]>
Commit | Line | Data |
---|---|---|
37ac3b76 ME |
1 | /* ELF executable support for BFD. |
2 | Copyright (C) 1991, 1992 Free Software Foundation, Inc. | |
9ce0058c SC |
3 | |
4 | Written by Fred Fish @ Cygnus Support, from information published | |
5 | in "UNIX System V Release 4, Programmers Guide: ANSI C and | |
3dfa6cfb | 6 | Programming Support Tools". Sufficient support for gdb. |
37ac3b76 ME |
7 | |
8 | Rewritten by Mark Eichin @ Cygnus Support, from information | |
9 | published in "System V Application Binary Interface", chapters 4 | |
10 | and 5, as well as the various "Processor Supplement" documents | |
11 | derived from it. Added support for assembler and other object file | |
12 | utilities. | |
13 | ||
9ce0058c SC |
14 | This file is part of BFD, the Binary File Descriptor library. |
15 | ||
16 | This program is free software; you can redistribute it and/or modify | |
17 | it under the terms of the GNU General Public License as published by | |
18 | the Free Software Foundation; either version 2 of the License, or | |
19 | (at your option) any later version. | |
20 | ||
21 | This program is distributed in the hope that it will be useful, | |
22 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24 | GNU General Public License for more details. | |
25 | ||
26 | You should have received a copy of the GNU General Public License | |
27 | along with this program; if not, write to the Free Software | |
28 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
29 | ||
30 | ||
31 | /**************************************** | |
32 | ||
33 | WARNING | |
34 | ||
35 | This is only a partial ELF implementation, | |
36 | incorporating only those parts that are | |
37 | required to get gdb up and running. It is | |
38 | expected that it will be expanded to a full | |
39 | ELF implementation at some future date. | |
40 | ||
41 | Unimplemented stubs call abort() to ensure | |
42 | that they get proper attention if they are | |
43 | ever called. The stubs are here since | |
44 | this version was hacked from the COFF | |
45 | version, and thus they will probably | |
46 | go away or get expanded appropriately in a | |
47 | future version. | |
48 | ||
49 | [email protected] | |
50 | ||
51 | *****************************************/ | |
52 | ||
53 | ||
54 | /* Problems and other issues to resolve. | |
55 | ||
56 | (1) BFD expects there to be some fixed number of "sections" in | |
57 | the object file. I.E. there is a "section_count" variable in the | |
58 | bfd structure which contains the number of sections. However, ELF | |
59 | supports multiple "views" of a file. In particular, with current | |
60 | implementations, executable files typically have two tables, a | |
61 | program header table and a section header table, both of which | |
62 | partition the executable. | |
63 | ||
64 | In ELF-speak, the "linking view" of the file uses the section header | |
65 | table to access "sections" within the file, and the "execution view" | |
66 | uses the program header table to access "segments" within the file. | |
67 | "Segments" typically may contain all the data from one or more | |
68 | "sections". | |
69 | ||
70 | Note that the section header table is optional in ELF executables, | |
71 | but it is this information that is most useful to gdb. If the | |
72 | section header table is missing, then gdb should probably try | |
73 | to make do with the program header table. (FIXME) | |
74 | ||
75 | */ | |
76 | ||
9ce0058c | 77 | #include "bfd.h" |
e0796d22 | 78 | #include "sysdep.h" |
9ce0058c SC |
79 | #include "libbfd.h" |
80 | #include "obstack.h" | |
c3eb25fc SC |
81 | #include "elf/common.h" |
82 | #include "elf/internal.h" | |
83 | #include "elf/external.h" | |
9ce0058c | 84 | |
8c4a1ace JG |
85 | #ifdef HAVE_PROCFS /* Some core file support requires host /proc files */ |
86 | #include <sys/procfs.h> | |
87 | #else | |
88 | #define bfd_prstatus(abfd, descdata, descsz, filepos) /* Define away */ | |
89 | #define bfd_fpregset(abfd, descdata, descsz, filepos) /* Define away */ | |
90 | #define bfd_prpsinfo(abfd, descdata, descsz, filepos) /* Define away */ | |
91 | #endif | |
92 | ||
9ce0058c | 93 | /* Forward data declarations */ |
8c4a1ace | 94 | |
9ce0058c SC |
95 | extern bfd_target elf_little_vec, elf_big_vec; |
96 | ||
8c4a1ace JG |
97 | /* Currently the elf_symbol_type struct just contains the generic bfd |
98 | symbol structure. */ | |
99 | ||
100 | typedef struct | |
101 | { | |
102 | asymbol symbol; | |
103 | } elf_symbol_type; | |
104 | ||
105 | /* Some private data is stashed away for future use using the tdata pointer | |
80bdcb77 | 106 | in the bfd structure. */ |
8c4a1ace | 107 | |
80bdcb77 | 108 | struct elf_obj_tdata |
8c4a1ace | 109 | { |
80bdcb77 | 110 | Elf_Internal_Ehdr elf_header[1]; /* Actual data, but ref like ptr */ |
37ac3b76 ME |
111 | Elf_Internal_Shdr *elf_sect_ptr; |
112 | struct strtab *strtab_ptr; | |
113 | int symtab_section; | |
80bdcb77 JG |
114 | void *prstatus; /* The raw /proc prstatus structure */ |
115 | void *prpsinfo; /* The raw /proc prpsinfo structure */ | |
116 | }; | |
8c4a1ace | 117 | |
e98e6ec1 | 118 | #define elf_tdata(bfd) ((bfd) -> tdata.elf_obj_data) |
37ac3b76 ME |
119 | #define elf_elfheader(bfd) (elf_tdata(bfd) -> elf_header) |
120 | #define elf_elfsections(bfd) (elf_tdata(bfd) -> elf_sect_ptr) | |
121 | #define elf_shstrtab(bfd) (elf_tdata(bfd) -> strtab_ptr) | |
122 | #define elf_onesymtab(bfd) (elf_tdata(bfd) -> symtab_section) | |
80bdcb77 JG |
123 | #define core_prpsinfo(bfd) (elf_tdata(bfd) -> prpsinfo) |
124 | #define core_prstatus(bfd) (elf_tdata(bfd) -> prstatus) | |
8c4a1ace JG |
125 | |
126 | /* Translate an ELF symbol in external format into an ELF symbol in internal | |
127 | format. */ | |
128 | ||
129 | static void | |
130 | DEFUN(elf_swap_symbol_in,(abfd, src, dst), | |
131 | bfd *abfd AND | |
132 | Elf_External_Sym *src AND | |
133 | Elf_Internal_Sym *dst) | |
134 | { | |
135 | dst -> st_name = bfd_h_get_32 (abfd, (bfd_byte *) src -> st_name); | |
136 | dst -> st_value = bfd_h_get_32 (abfd, (bfd_byte *) src -> st_value); | |
137 | dst -> st_size = bfd_h_get_32 (abfd, (bfd_byte *) src -> st_size); | |
138 | dst -> st_info = bfd_h_get_8 (abfd, (bfd_byte *) src -> st_info); | |
139 | dst -> st_other = bfd_h_get_8 (abfd, (bfd_byte *) src -> st_other); | |
140 | dst -> st_shndx = bfd_h_get_16 (abfd, (bfd_byte *) src -> st_shndx); | |
141 | } | |
142 | ||
37ac3b76 ME |
143 | /* Translate an ELF symbol in internal format into an ELF symbol in external |
144 | format. */ | |
145 | ||
146 | static void | |
147 | DEFUN(elf_swap_symbol_out,(abfd, src, dst), | |
148 | bfd *abfd AND | |
149 | Elf_Internal_Sym *src AND | |
150 | Elf_External_Sym *dst) | |
151 | { | |
152 | bfd_h_put_32 (abfd, src->st_name, dst->st_name); | |
153 | bfd_h_put_32 (abfd, src->st_value, dst->st_value); | |
154 | bfd_h_put_32 (abfd, src->st_size, dst->st_size); | |
155 | bfd_h_put_8 (abfd, src->st_info, dst->st_info); | |
156 | bfd_h_put_8 (abfd, src->st_other, dst->st_other); | |
157 | bfd_h_put_16 (abfd, src->st_shndx, dst->st_shndx); | |
158 | } | |
159 | ||
8c4a1ace | 160 | |
e83f3040 FF |
161 | /* Translate an ELF file header in external format into an ELF file header in |
162 | internal format. */ | |
9ce0058c SC |
163 | |
164 | static void | |
8c4a1ace | 165 | DEFUN(elf_swap_ehdr_in,(abfd, src, dst), |
9ce0058c SC |
166 | bfd *abfd AND |
167 | Elf_External_Ehdr *src AND | |
168 | Elf_Internal_Ehdr *dst) | |
169 | { | |
e98e6ec1 | 170 | memcpy (dst -> e_ident, src -> e_ident, EI_NIDENT); |
9ce0058c SC |
171 | dst -> e_type = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_type); |
172 | dst -> e_machine = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_machine); | |
173 | dst -> e_version = bfd_h_get_32 (abfd, (bfd_byte *) src -> e_version); | |
174 | dst -> e_entry = bfd_h_get_32 (abfd, (bfd_byte *) src -> e_entry); | |
175 | dst -> e_phoff = bfd_h_get_32 (abfd, (bfd_byte *) src -> e_phoff); | |
176 | dst -> e_shoff = bfd_h_get_32 (abfd, (bfd_byte *) src -> e_shoff); | |
177 | dst -> e_flags = bfd_h_get_32 (abfd, (bfd_byte *) src -> e_flags); | |
178 | dst -> e_ehsize = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_ehsize); | |
179 | dst -> e_phentsize = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_phentsize); | |
180 | dst -> e_phnum = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_phnum); | |
181 | dst -> e_shentsize = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_shentsize); | |
182 | dst -> e_shnum = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_shnum); | |
183 | dst -> e_shstrndx = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_shstrndx); | |
184 | } | |
185 | ||
37ac3b76 ME |
186 | /* Translate an ELF file header in internal format into an ELF file header in |
187 | external format. */ | |
188 | ||
189 | static void | |
190 | DEFUN(elf_swap_ehdr_out,(abfd, src, dst), | |
191 | bfd *abfd AND | |
192 | Elf_Internal_Ehdr *src AND | |
193 | Elf_External_Ehdr *dst) | |
194 | { | |
195 | memcpy (dst -> e_ident, src -> e_ident, EI_NIDENT); | |
196 | /* note that all elements of dst are *arrays of unsigned char* already... */ | |
197 | bfd_h_put_16 (abfd, src->e_type, dst->e_type); | |
198 | bfd_h_put_16 (abfd, src->e_machine, dst->e_machine); | |
199 | bfd_h_put_32 (abfd, src->e_version, dst->e_version); | |
200 | bfd_h_put_32 (abfd, src->e_entry, dst->e_entry); | |
201 | bfd_h_put_32 (abfd, src->e_phoff, dst->e_phoff); | |
202 | bfd_h_put_32 (abfd, src->e_shoff, dst->e_shoff); | |
203 | bfd_h_put_32 (abfd, src->e_flags, dst->e_flags); | |
204 | bfd_h_put_16 (abfd, src->e_ehsize, dst->e_ehsize); | |
205 | bfd_h_put_16 (abfd, src->e_phentsize, dst->e_phentsize); | |
206 | bfd_h_put_16 (abfd, src->e_phnum, dst->e_phnum); | |
207 | bfd_h_put_16 (abfd, src->e_shentsize, dst->e_shentsize); | |
208 | bfd_h_put_16 (abfd, src->e_shnum, dst->e_shnum); | |
209 | bfd_h_put_16 (abfd, src->e_shstrndx, dst->e_shstrndx); | |
210 | } | |
211 | ||
9ce0058c SC |
212 | |
213 | /* Translate an ELF section header table entry in external format into an | |
214 | ELF section header table entry in internal format. */ | |
215 | ||
216 | static void | |
8c4a1ace | 217 | DEFUN(elf_swap_shdr_in,(abfd, src, dst), |
9ce0058c SC |
218 | bfd *abfd AND |
219 | Elf_External_Shdr *src AND | |
220 | Elf_Internal_Shdr *dst) | |
221 | { | |
37ac3b76 ME |
222 | dst->sh_name = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_name); |
223 | dst->sh_type = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_type); | |
224 | dst->sh_flags = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_flags); | |
225 | dst->sh_addr = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_addr); | |
226 | dst->sh_offset = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_offset); | |
227 | dst->sh_size = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_size); | |
228 | dst->sh_link = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_link); | |
229 | dst->sh_info = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_info); | |
230 | dst->sh_addralign = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_addralign); | |
231 | dst->sh_entsize = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_entsize); | |
232 | /* we haven't done any processing on it yet, so... */ | |
233 | dst->rawdata = (void*)0; | |
234 | } | |
235 | ||
236 | /* Translate an ELF section header table entry in internal format into an | |
237 | ELF section header table entry in external format. */ | |
238 | ||
239 | static void | |
240 | DEFUN(elf_swap_shdr_out,(abfd, src, dst), | |
241 | bfd *abfd AND | |
242 | Elf_Internal_Shdr *src AND | |
243 | Elf_External_Shdr *dst) | |
244 | { | |
245 | /* note that all elements of dst are *arrays of unsigned char* already... */ | |
246 | bfd_h_put_32 (abfd, src->sh_name, dst->sh_name); | |
247 | bfd_h_put_32 (abfd, src->sh_type, dst->sh_type); | |
248 | bfd_h_put_32 (abfd, src->sh_flags, dst->sh_flags); | |
249 | bfd_h_put_32 (abfd, src->sh_addr, dst->sh_addr); | |
250 | bfd_h_put_32 (abfd, src->sh_offset, dst->sh_offset); | |
251 | bfd_h_put_32 (abfd, src->sh_size, dst->sh_size); | |
252 | bfd_h_put_32 (abfd, src->sh_link, dst->sh_link); | |
253 | bfd_h_put_32 (abfd, src->sh_info, dst->sh_info); | |
254 | bfd_h_put_32 (abfd, src->sh_addralign, dst->sh_addralign); | |
255 | bfd_h_put_32 (abfd, src->sh_entsize, dst->sh_entsize); | |
9ce0058c SC |
256 | } |
257 | ||
258 | ||
e0796d22 FF |
259 | /* Translate an ELF program header table entry in external format into an |
260 | ELF program header table entry in internal format. */ | |
261 | ||
262 | static void | |
8c4a1ace | 263 | DEFUN(elf_swap_phdr_in,(abfd, src, dst), |
e0796d22 FF |
264 | bfd *abfd AND |
265 | Elf_External_Phdr *src AND | |
266 | Elf_Internal_Phdr *dst) | |
267 | { | |
37ac3b76 ME |
268 | dst->p_type = bfd_h_get_32 (abfd, (bfd_byte *) src->p_type); |
269 | dst->p_offset = bfd_h_get_32 (abfd, (bfd_byte *) src->p_offset); | |
270 | dst->p_vaddr = bfd_h_get_32 (abfd, (bfd_byte *) src->p_vaddr); | |
271 | dst->p_paddr = bfd_h_get_32 (abfd, (bfd_byte *) src->p_paddr); | |
272 | dst->p_filesz = bfd_h_get_32 (abfd, (bfd_byte *) src->p_filesz); | |
273 | dst->p_memsz = bfd_h_get_32 (abfd, (bfd_byte *) src->p_memsz); | |
274 | dst->p_flags = bfd_h_get_32 (abfd, (bfd_byte *) src->p_flags); | |
275 | dst->p_align = bfd_h_get_32 (abfd, (bfd_byte *) src->p_align); | |
e0796d22 FF |
276 | } |
277 | ||
278 | ||
37ac3b76 ME |
279 | /* Translate an ELF reloc from external format to internal format. */ |
280 | static void | |
281 | DEFUN(elf_swap_reloc_in,(abfd, src, dst), | |
282 | bfd *abfd AND | |
283 | Elf_External_Rel *src AND | |
284 | Elf_Internal_Rel *dst) | |
285 | { | |
286 | dst->r_offset = bfd_h_get_32 (abfd, (bfd_byte *) src->r_offset); | |
287 | dst->r_info = bfd_h_get_32 (abfd, (bfd_byte *) src->r_info); | |
288 | } | |
9ce0058c | 289 | |
37ac3b76 ME |
290 | static void |
291 | DEFUN(elf_swap_reloca_in,(abfd, src, dst), | |
292 | bfd *abfd AND | |
293 | Elf_External_Rela *src AND | |
294 | Elf_Internal_Rela *dst) | |
9ce0058c | 295 | { |
37ac3b76 ME |
296 | dst->r_offset = bfd_h_get_32 (abfd, (bfd_byte *) src->r_offset); |
297 | dst->r_info = bfd_h_get_32 (abfd, (bfd_byte *) src->r_info); | |
298 | dst->r_addend = bfd_h_get_32 (abfd, (bfd_byte *) src->r_addend); | |
299 | } | |
9ce0058c | 300 | |
37ac3b76 ME |
301 | /* Translate an ELF reloc from internal format to external format. */ |
302 | static void | |
303 | DEFUN(elf_swap_reloc_out,(abfd, src, dst), | |
304 | bfd *abfd AND | |
305 | Elf_Internal_Rel *src AND | |
306 | Elf_External_Rel *dst) | |
307 | { | |
308 | bfd_h_put_32 (abfd, src->r_offset, dst->r_offset); | |
309 | bfd_h_put_32 (abfd, src->r_info, dst->r_info); | |
310 | } | |
311 | ||
312 | static void | |
313 | DEFUN(elf_swap_reloca_out,(abfd, src, dst), | |
314 | bfd *abfd AND | |
315 | Elf_Internal_Rela *src AND | |
316 | Elf_External_Rela *dst) | |
317 | { | |
318 | bfd_h_put_32 (abfd, src->r_offset, dst->r_offset); | |
319 | bfd_h_put_32 (abfd, src->r_info, dst->r_info); | |
320 | bfd_h_put_32 (abfd, src->r_addend, dst->r_addend); | |
321 | } | |
322 | ||
323 | static char *EXFUN(elf_read, (bfd *, long, int)); | |
324 | static struct sec * EXFUN(section_from_elf_index, (bfd *, int)); | |
325 | static int EXFUN(elf_section_from_bfd_section, (bfd *, struct sec *)); | |
3dfa6cfb | 326 | static boolean EXFUN(elf_slurp_symbol_table, (bfd *, asymbol **)); |
37ac3b76 | 327 | static void EXFUN(elf_info_to_howto, (bfd *, arelent *, Elf_Internal_Rela *)); |
80bdcb77 | 328 | static char *EXFUN(elf_get_str_section, (bfd *, unsigned int)); |
37ac3b76 | 329 | |
796aae47 JG |
330 | /* |
331 | INTERNAL_FUNCTION | |
332 | bfd_elf_find_section | |
333 | ||
334 | SYNOPSIS | |
335 | struct elf_internal_shdr *bfd_elf_find_section (bfd *abfd, char *name); | |
336 | ||
337 | DESCRIPTION | |
338 | Helper functions for GDB to locate the string tables. | |
339 | Since BFD hides string tables from callers, GDB needs to use an | |
340 | internal hook to find them. Sun's .stabstr, in particular, | |
341 | isn't even pointed to by the .stab section, so ordinary | |
342 | mechanisms wouldn't work to find it, even if we had some. | |
343 | */ | |
80bdcb77 | 344 | |
796aae47 JG |
345 | struct elf_internal_shdr * |
346 | DEFUN(bfd_elf_find_section, (abfd, name), | |
80bdcb77 JG |
347 | bfd *abfd AND |
348 | char *name) | |
349 | { | |
350 | Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd); | |
351 | char *shstrtab = elf_get_str_section (abfd, elf_elfheader (abfd)->e_shstrndx); | |
352 | unsigned int max = elf_elfheader (abfd)->e_shnum; | |
353 | unsigned int i; | |
354 | ||
355 | for (i = 1; i < max; i++) | |
356 | if (!strcmp (&shstrtab[i_shdrp[i].sh_name], name)) | |
357 | return &i_shdrp[i]; | |
358 | return 0; | |
359 | } | |
360 | ||
361 | /* End of GDB support. */ | |
37ac3b76 ME |
362 | |
363 | static char * | |
364 | DEFUN(elf_get_str_section, (abfd, shindex), | |
365 | bfd *abfd AND | |
366 | unsigned int shindex) | |
367 | { | |
368 | Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd); | |
369 | unsigned int shstrtabsize = i_shdrp[shindex].sh_size; | |
370 | unsigned int offset = i_shdrp[shindex].sh_offset; | |
80bdcb77 JG |
371 | char *shstrtab = i_shdrp[shindex].rawdata; |
372 | ||
373 | if (shstrtab) | |
374 | return shstrtab; | |
375 | ||
37ac3b76 | 376 | if ((shstrtab = elf_read (abfd, offset, shstrtabsize)) == NULL) |
9ce0058c | 377 | { |
37ac3b76 | 378 | return (NULL); |
9ce0058c | 379 | } |
37ac3b76 | 380 | i_shdrp[shindex].rawdata = (void*)shstrtab; |
80bdcb77 | 381 | return shstrtab; |
37ac3b76 | 382 | } |
80bdcb77 | 383 | |
37ac3b76 ME |
384 | static char * |
385 | DEFUN(elf_string_from_elf_section, (abfd, shindex, strindex), | |
386 | bfd *abfd AND | |
387 | unsigned int shindex AND | |
388 | unsigned int strindex) | |
389 | { | |
390 | Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd); | |
391 | Elf_Internal_Shdr *hdr = i_shdrp + shindex; | |
80bdcb77 | 392 | |
37ac3b76 | 393 | if (! hdr->rawdata) |
9ce0058c | 394 | { |
37ac3b76 | 395 | if (elf_get_str_section (abfd, shindex) == NULL) |
9ce0058c | 396 | { |
37ac3b76 | 397 | return NULL; |
9ce0058c SC |
398 | } |
399 | } | |
37ac3b76 ME |
400 | return ((char*)hdr->rawdata)+strindex; |
401 | } | |
402 | ||
403 | #define elf_string_from_elf_strtab(abfd, strindex) \ | |
404 | elf_string_from_elf_section (abfd, elf_elfheader(abfd)->e_shstrndx, strindex) | |
405 | ||
406 | /* Create a new bfd section from an ELF section header. */ | |
407 | ||
408 | static boolean | |
409 | DEFUN(bfd_section_from_shdr, (abfd, shindex), | |
410 | bfd *abfd AND | |
411 | unsigned int shindex) | |
412 | { | |
413 | Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd); | |
414 | Elf_Internal_Shdr *hdr = i_shdrp + shindex; | |
415 | asection *newsect; | |
416 | char *name; | |
417 | ||
418 | name = hdr->sh_name ? | |
419 | elf_string_from_elf_strtab (abfd, hdr->sh_name) : "unnamed"; | |
420 | ||
421 | switch(hdr->sh_type) { | |
3dfa6cfb | 422 | |
37ac3b76 ME |
423 | case SHT_NULL: |
424 | /* inactive section. Throw it away. */ | |
425 | return true; | |
3dfa6cfb | 426 | |
37ac3b76 ME |
427 | case SHT_PROGBITS: |
428 | case SHT_NOBITS: | |
429 | /* Bits that get saved. This one is real. */ | |
430 | if (! hdr->rawdata ) | |
431 | { | |
432 | newsect = bfd_make_section (abfd, name); | |
433 | newsect->vma = hdr->sh_addr; | |
434 | newsect->_raw_size = hdr->sh_size; | |
435 | newsect->filepos = hdr->sh_offset; /* so we can read back the bits */ | |
436 | newsect->flags |= SEC_HAS_CONTENTS; | |
437 | ||
438 | if (hdr->sh_flags & SHF_ALLOC) | |
439 | { | |
440 | newsect->flags |= SEC_ALLOC; | |
441 | if (hdr->sh_type != SHT_NOBITS) | |
442 | newsect->flags |= SEC_LOAD; | |
443 | } | |
444 | ||
445 | if (!(hdr->sh_flags & SHF_WRITE)) | |
446 | newsect->flags |= SEC_READONLY; | |
447 | ||
448 | if (hdr->sh_flags & SHF_EXECINSTR) | |
449 | newsect->flags |= SEC_CODE; /* FIXME: may only contain SOME code */ | |
450 | else | |
451 | newsect->flags |= SEC_DATA; | |
452 | ||
453 | hdr->rawdata = (void*)newsect; | |
454 | } | |
455 | return true; | |
456 | break; | |
3dfa6cfb FF |
457 | |
458 | case SHT_SYMTAB: /* A symbol table */ | |
459 | BFD_ASSERT (hdr->sh_entsize == sizeof (Elf_External_Sym)); | |
460 | elf_onesymtab (abfd) = shindex; | |
461 | abfd->flags |= HAS_SYMS; | |
37ac3b76 | 462 | return true; |
3dfa6cfb FF |
463 | |
464 | case SHT_STRTAB: /* A string table */ | |
37ac3b76 | 465 | return true; |
3dfa6cfb | 466 | |
37ac3b76 ME |
467 | case SHT_REL: |
468 | case SHT_RELA: | |
469 | /* *these* do a lot of work -- but build no sections! */ | |
470 | /* the spec says there can be multiple strtabs, but only one symtab */ | |
471 | /* but there can be lots of REL* sections. */ | |
91f781ff FF |
472 | /* FIXME: The above statement is wrong! There are typically at least |
473 | two symbol tables in a dynamically linked executable, ".dynsym" | |
474 | which is the dynamic linkage symbol table and ".symtab", which is | |
475 | the "traditional" symbol table. -fnf */ | |
476 | ||
9ce0058c | 477 | { |
37ac3b76 | 478 | asection *target_sect; |
37ac3b76 ME |
479 | |
480 | bfd_section_from_shdr (abfd, hdr->sh_link); /* symbol table */ | |
481 | bfd_section_from_shdr (abfd, hdr->sh_info); /* target */ | |
482 | target_sect = section_from_elf_index (abfd, hdr->sh_info); | |
3dfa6cfb FF |
483 | if (target_sect == NULL) |
484 | return false; | |
485 | ||
91f781ff FF |
486 | #if 0 |
487 | /* FIXME: We are only prepared to read one symbol table, so | |
488 | do NOT read the dynamic symbol table since it is only a | |
489 | subset of the full symbol table. Also see comment above. -fnf */ | |
37ac3b76 ME |
490 | if (!elf_slurp_symbol_table(abfd, i_shdrp + hdr->sh_link)) |
491 | return false; | |
91f781ff | 492 | #endif |
37ac3b76 ME |
493 | |
494 | target_sect->reloc_count = hdr->sh_size / hdr->sh_entsize; | |
495 | target_sect->flags |= SEC_RELOC; | |
496 | target_sect->relocation = 0; | |
497 | target_sect->rel_filepos = hdr->sh_offset; | |
37ac3b76 | 498 | return true; |
9ce0058c | 499 | } |
37ac3b76 | 500 | break; |
3dfa6cfb | 501 | |
37ac3b76 ME |
502 | case SHT_HASH: |
503 | case SHT_DYNAMIC: | |
504 | case SHT_DYNSYM: /* could treat this like symtab... */ | |
80bdcb77 | 505 | #if 0 |
37ac3b76 ME |
506 | fprintf(stderr, "Dynamic Linking sections not yet supported.\n"); |
507 | abort (); | |
80bdcb77 | 508 | #endif |
37ac3b76 | 509 | break; |
3dfa6cfb | 510 | |
37ac3b76 | 511 | case SHT_NOTE: |
80bdcb77 | 512 | #if 0 |
37ac3b76 ME |
513 | fprintf(stderr, "Note Sections not yet supported.\n"); |
514 | abort (); | |
80bdcb77 | 515 | #endif |
37ac3b76 | 516 | break; |
3dfa6cfb | 517 | |
37ac3b76 | 518 | case SHT_SHLIB: |
80bdcb77 | 519 | #if 0 |
37ac3b76 | 520 | fprintf(stderr, "SHLIB Sections not supported (and non conforming.)\n"); |
80bdcb77 | 521 | #endif |
37ac3b76 | 522 | return true; |
80bdcb77 | 523 | |
37ac3b76 ME |
524 | default: |
525 | break; | |
526 | } | |
527 | ||
528 | return (true); | |
529 | } | |
530 | ||
3dfa6cfb | 531 | |
37ac3b76 ME |
532 | |
533 | ||
534 | struct strtab { | |
535 | char *tab; | |
536 | int nentries; | |
537 | int length; | |
538 | }; | |
539 | ||
540 | ||
541 | static struct strtab * | |
542 | DEFUN(bfd_new_strtab, (abfd), | |
543 | bfd *abfd) | |
544 | { | |
545 | struct strtab *ss; | |
546 | ||
547 | ss = (struct strtab *)malloc(sizeof(struct strtab)); | |
548 | ss->tab = malloc(1); | |
549 | BFD_ASSERT(ss->tab != 0); | |
550 | *ss->tab = 0; | |
551 | ss->nentries = 0; | |
552 | ss->length = 1; | |
553 | ||
554 | return ss; | |
555 | } | |
556 | ||
557 | static int | |
558 | DEFUN(bfd_add_to_strtab, (abfd, ss, str), | |
559 | bfd *abfd AND | |
560 | struct strtab *ss AND | |
808dfd5a | 561 | CONST char *str) |
37ac3b76 ME |
562 | { |
563 | /* should search first, but for now: */ | |
564 | /* include the trailing NUL */ | |
565 | int ln = strlen(str)+1; | |
566 | ||
567 | /* should this be using obstacks? */ | |
568 | ss->tab = realloc(ss->tab, ss->length + ln); | |
569 | ||
570 | BFD_ASSERT(ss->tab != 0); | |
571 | strcpy(ss->tab + ss->length, str); | |
572 | ss->nentries++; | |
573 | ss->length += ln; | |
574 | ||
575 | return ss->length - ln; | |
576 | } | |
577 | ||
578 | static int | |
579 | DEFUN(bfd_add_2_to_strtab, (abfd, ss, str, str2), | |
580 | bfd *abfd AND | |
581 | struct strtab *ss AND | |
582 | char *str AND | |
808dfd5a | 583 | CONST char *str2) |
37ac3b76 ME |
584 | { |
585 | /* should search first, but for now: */ | |
586 | /* include the trailing NUL */ | |
587 | int ln = strlen(str)+strlen(str2)+1; | |
588 | ||
589 | /* should this be using obstacks? */ | |
590 | if (ss->length) | |
591 | ss->tab = realloc(ss->tab, ss->length + ln); | |
592 | else | |
593 | ss->tab = malloc(ln); | |
594 | ||
595 | BFD_ASSERT(ss->tab != 0); | |
596 | strcpy(ss->tab + ss->length, str); | |
597 | strcpy(ss->tab + ss->length + strlen(str), str2); | |
598 | ss->nentries++; | |
599 | ss->length += ln; | |
600 | ||
601 | return ss->length - ln; | |
602 | } | |
603 | ||
604 | /* Create a new ELF section from a bfd section. */ | |
605 | ||
606 | static boolean | |
607 | DEFUN(bfd_shdr_from_section, (abfd, hdr, shstrtab, indx), | |
608 | bfd *abfd AND | |
609 | Elf_Internal_Shdr *hdr AND | |
610 | struct strtab *shstrtab AND | |
611 | int indx) | |
612 | { | |
613 | asection *sect; | |
614 | int ndx; | |
615 | ||
616 | /* figure out out to write the section name from the bfd section name. MWE */ | |
617 | ||
618 | sect = abfd->sections; | |
619 | for (ndx = indx; --ndx; ) | |
9ce0058c | 620 | { |
37ac3b76 | 621 | sect = sect->next; |
9ce0058c | 622 | } |
37ac3b76 ME |
623 | hdr[indx].sh_name = bfd_add_to_strtab(abfd, shstrtab, |
624 | bfd_section_name(abfd, sect)); | |
625 | hdr[indx].sh_addr = sect->vma; | |
626 | hdr[indx].sh_size = sect->_raw_size; | |
627 | hdr[indx].sh_flags = 0; | |
628 | /* these need to be preserved on */ | |
629 | hdr[indx].sh_link = 0; | |
630 | hdr[indx].sh_info = 0; | |
631 | hdr[indx].sh_addralign = 0; | |
632 | hdr[indx].sh_entsize = 0; | |
633 | ||
634 | hdr[indx].sh_type = 0; | |
635 | if (sect->flags & SEC_RELOC) { | |
636 | hdr[indx].sh_type = SHT_RELA; /* FIXME -- sparc specific */ | |
637 | } | |
638 | ||
639 | if (sect->flags & SEC_HAS_CONTENTS) | |
e83f3040 | 640 | { |
37ac3b76 ME |
641 | hdr[indx].sh_offset = sect->filepos; |
642 | hdr[indx].sh_size = sect->_raw_size; | |
e83f3040 | 643 | } |
37ac3b76 | 644 | if (sect->flags & SEC_ALLOC) |
9ce0058c | 645 | { |
37ac3b76 ME |
646 | hdr[indx].sh_flags |= SHF_ALLOC; |
647 | if (sect->flags & SEC_LOAD) | |
648 | { | |
649 | /* do something with sh_type ? */ | |
650 | } | |
9ce0058c | 651 | } |
37ac3b76 ME |
652 | if (!(sect->flags & SEC_READONLY)) |
653 | hdr[indx].sh_flags |= SHF_WRITE; | |
654 | ||
655 | if (sect->flags & SEC_CODE) | |
656 | hdr[indx].sh_flags |= SHF_EXECINSTR; | |
9ce0058c SC |
657 | |
658 | return (true); | |
659 | } | |
660 | ||
e0796d22 FF |
661 | /* Create a new bfd section from an ELF program header. |
662 | ||
663 | Since program segments have no names, we generate a synthetic name | |
664 | of the form segment<NUM>, where NUM is generally the index in the | |
665 | program header table. For segments that are split (see below) we | |
666 | generate the names segment<NUM>a and segment<NUM>b. | |
667 | ||
668 | Note that some program segments may have a file size that is different than | |
669 | (less than) the memory size. All this means is that at execution the | |
670 | system must allocate the amount of memory specified by the memory size, | |
671 | but only initialize it with the first "file size" bytes read from the | |
672 | file. This would occur for example, with program segments consisting | |
673 | of combined data+bss. | |
674 | ||
675 | To handle the above situation, this routine generates TWO bfd sections | |
676 | for the single program segment. The first has the length specified by | |
677 | the file size of the segment, and the second has the length specified | |
678 | by the difference between the two sizes. In effect, the segment is split | |
679 | into it's initialized and uninitialized parts. | |
680 | ||
681 | */ | |
682 | ||
683 | static boolean | |
684 | DEFUN(bfd_section_from_phdr, (abfd, hdr, index), | |
685 | bfd *abfd AND | |
686 | Elf_Internal_Phdr *hdr AND | |
687 | int index) | |
688 | { | |
689 | asection *newsect; | |
690 | char *name; | |
691 | char namebuf[64]; | |
692 | int split; | |
693 | ||
694 | split = ((hdr -> p_memsz > 0) && | |
695 | (hdr -> p_filesz > 0) && | |
696 | (hdr -> p_memsz > hdr -> p_filesz)); | |
697 | sprintf (namebuf, split ? "segment%da" : "segment%d", index); | |
698 | name = bfd_alloc (abfd, strlen (namebuf) + 1); | |
97225e37 | 699 | strcpy (name, namebuf); |
e0796d22 FF |
700 | newsect = bfd_make_section (abfd, name); |
701 | newsect -> vma = hdr -> p_vaddr; | |
e98e6ec1 | 702 | newsect -> _raw_size = hdr -> p_filesz; |
e0796d22 FF |
703 | newsect -> filepos = hdr -> p_offset; |
704 | newsect -> flags |= SEC_HAS_CONTENTS; | |
705 | if (hdr -> p_type == PT_LOAD) | |
706 | { | |
707 | newsect -> flags |= SEC_ALLOC; | |
708 | newsect -> flags |= SEC_LOAD; | |
709 | if (hdr -> p_flags & PF_X) | |
710 | { | |
711 | /* FIXME: all we known is that it has execute PERMISSION, | |
712 | may be data. */ | |
713 | newsect -> flags |= SEC_CODE; | |
714 | } | |
715 | } | |
716 | if (!(hdr -> p_flags & PF_W)) | |
717 | { | |
718 | newsect -> flags |= SEC_READONLY; | |
719 | } | |
720 | ||
721 | if (split) | |
722 | { | |
723 | sprintf (namebuf, "segment%db", index); | |
724 | name = bfd_alloc (abfd, strlen (namebuf) + 1); | |
97225e37 | 725 | strcpy (name, namebuf); |
e0796d22 FF |
726 | newsect = bfd_make_section (abfd, name); |
727 | newsect -> vma = hdr -> p_vaddr + hdr -> p_filesz; | |
e98e6ec1 | 728 | newsect -> _raw_size = hdr -> p_memsz - hdr -> p_filesz; |
e0796d22 FF |
729 | if (hdr -> p_type == PT_LOAD) |
730 | { | |
731 | newsect -> flags |= SEC_ALLOC; | |
732 | if (hdr -> p_flags & PF_X) | |
37ac3b76 | 733 | newsect -> flags |= SEC_CODE; |
e0796d22 FF |
734 | } |
735 | if (!(hdr -> p_flags & PF_W)) | |
37ac3b76 | 736 | newsect -> flags |= SEC_READONLY; |
e0796d22 FF |
737 | } |
738 | ||
739 | return (true); | |
740 | } | |
741 | ||
8c4a1ace JG |
742 | #ifdef HAVE_PROCFS |
743 | ||
744 | static void | |
745 | DEFUN(bfd_prstatus,(abfd, descdata, descsz, filepos), | |
746 | bfd *abfd AND | |
747 | char *descdata AND | |
748 | int descsz AND | |
749 | long filepos) | |
750 | { | |
751 | asection *newsect; | |
37ac3b76 | 752 | prstatus_t *status = (prstatus_t *)0; |
8c4a1ace JG |
753 | |
754 | if (descsz == sizeof (prstatus_t)) | |
755 | { | |
756 | newsect = bfd_make_section (abfd, ".reg"); | |
37ac3b76 ME |
757 | newsect -> _raw_size = sizeof (status->pr_reg); |
758 | newsect -> filepos = filepos + (long) &status->pr_reg; | |
8c4a1ace JG |
759 | newsect -> flags = SEC_ALLOC | SEC_HAS_CONTENTS; |
760 | newsect -> alignment_power = 2; | |
761 | if ((core_prstatus (abfd) = bfd_alloc (abfd, descsz)) != NULL) | |
762 | { | |
e98e6ec1 | 763 | memcpy (core_prstatus (abfd), descdata, descsz); |
8c4a1ace JG |
764 | } |
765 | } | |
766 | } | |
767 | ||
768 | /* Stash a copy of the prpsinfo structure away for future use. */ | |
769 | ||
770 | static void | |
771 | DEFUN(bfd_prpsinfo,(abfd, descdata, descsz, filepos), | |
772 | bfd *abfd AND | |
773 | char *descdata AND | |
774 | int descsz AND | |
775 | long filepos) | |
776 | { | |
777 | asection *newsect; | |
778 | ||
779 | if (descsz == sizeof (prpsinfo_t)) | |
780 | { | |
781 | if ((core_prpsinfo (abfd) = bfd_alloc (abfd, descsz)) != NULL) | |
782 | { | |
294eaca4 | 783 | memcpy (core_prpsinfo (abfd), descdata, descsz); |
8c4a1ace JG |
784 | } |
785 | } | |
786 | } | |
787 | ||
788 | static void | |
789 | DEFUN(bfd_fpregset,(abfd, descdata, descsz, filepos), | |
790 | bfd *abfd AND | |
791 | char *descdata AND | |
792 | int descsz AND | |
793 | long filepos) | |
794 | { | |
795 | asection *newsect; | |
796 | ||
37ac3b76 ME |
797 | newsect = bfd_make_section (abfd, ".reg2"); |
798 | newsect -> _raw_size = descsz; | |
799 | newsect -> filepos = filepos; | |
800 | newsect -> flags = SEC_ALLOC | SEC_HAS_CONTENTS; | |
801 | newsect -> alignment_power = 2; | |
8c4a1ace JG |
802 | } |
803 | ||
804 | #endif /* HAVE_PROCFS */ | |
805 | ||
806 | /* Return a pointer to the args (including the command name) that were | |
807 | seen by the program that generated the core dump. Note that for | |
808 | some reason, a spurious space is tacked onto the end of the args | |
809 | in some (at least one anyway) implementations, so strip it off if | |
810 | it exists. */ | |
811 | ||
812 | char * | |
813 | DEFUN(elf_core_file_failing_command, (abfd), | |
814 | bfd *abfd) | |
815 | { | |
e98e6ec1 | 816 | #ifdef HAVE_PROCFS |
8c4a1ace JG |
817 | if (core_prpsinfo (abfd)) |
818 | { | |
819 | prpsinfo_t *p = core_prpsinfo (abfd); | |
820 | char *scan = p -> pr_psargs; | |
821 | while (*scan++) {;} | |
822 | scan -= 2; | |
823 | if ((scan > p -> pr_psargs) && (*scan == ' ')) | |
824 | { | |
825 | *scan = '\000'; | |
826 | } | |
827 | return (p -> pr_psargs); | |
828 | } | |
829 | #endif | |
830 | return (NULL); | |
831 | } | |
832 | ||
833 | /* Return the number of the signal that caused the core dump. Presumably, | |
834 | since we have a core file, we got a signal of some kind, so don't bother | |
835 | checking the other process status fields, just return the signal number. | |
836 | */ | |
837 | ||
838 | static int | |
839 | DEFUN(elf_core_file_failing_signal, (abfd), | |
840 | bfd *abfd) | |
841 | { | |
e98e6ec1 | 842 | #ifdef HAVE_PROCFS |
8c4a1ace JG |
843 | if (core_prstatus (abfd)) |
844 | { | |
845 | return (((prstatus_t *)(core_prstatus (abfd))) -> pr_cursig); | |
846 | } | |
847 | #endif | |
848 | return (-1); | |
849 | } | |
850 | ||
851 | /* Check to see if the core file could reasonably be expected to have | |
852 | come for the current executable file. Note that by default we return | |
853 | true unless we find something that indicates that there might be a | |
854 | problem. | |
855 | */ | |
856 | ||
857 | static boolean | |
858 | DEFUN(elf_core_file_matches_executable_p, (core_bfd, exec_bfd), | |
859 | bfd *core_bfd AND | |
860 | bfd *exec_bfd) | |
861 | { | |
e98e6ec1 | 862 | #ifdef HAVE_PROCFS |
8c4a1ace JG |
863 | char *corename; |
864 | char *execname; | |
e83f3040 | 865 | #endif |
8c4a1ace JG |
866 | |
867 | /* First, xvecs must match since both are ELF files for the same target. */ | |
868 | ||
869 | if (core_bfd->xvec != exec_bfd->xvec) | |
870 | { | |
871 | bfd_error = system_call_error; | |
872 | return (false); | |
873 | } | |
874 | ||
e98e6ec1 | 875 | #ifdef HAVE_PROCFS |
8c4a1ace JG |
876 | |
877 | /* If no prpsinfo, just return true. Otherwise, grab the last component | |
878 | of the exec'd pathname from the prpsinfo. */ | |
879 | ||
880 | if (core_prpsinfo (core_bfd)) | |
881 | { | |
882 | corename = (((struct prpsinfo *) core_prpsinfo (core_bfd)) -> pr_fname); | |
883 | } | |
884 | else | |
885 | { | |
886 | return (true); | |
887 | } | |
888 | ||
889 | /* Find the last component of the executable pathname. */ | |
890 | ||
891 | if ((execname = strrchr (exec_bfd -> filename, '/')) != NULL) | |
892 | { | |
893 | execname++; | |
894 | } | |
895 | else | |
896 | { | |
897 | execname = (char *) exec_bfd -> filename; | |
898 | } | |
899 | ||
900 | /* See if they match */ | |
901 | ||
902 | return (strcmp (execname, corename) ? false : true); | |
903 | ||
904 | #else | |
905 | ||
906 | return (true); | |
907 | ||
908 | #endif /* HAVE_PROCFS */ | |
909 | } | |
910 | ||
911 | /* ELF core files contain a segment of type PT_NOTE, that holds much of | |
912 | the information that would normally be available from the /proc interface | |
913 | for the process, at the time the process dumped core. Currently this | |
914 | includes copies of the prstatus, prpsinfo, and fpregset structures. | |
915 | ||
916 | Since these structures are potentially machine dependent in size and | |
917 | ordering, bfd provides two levels of support for them. The first level, | |
918 | available on all machines since it does not require that the host | |
919 | have /proc support or the relevant include files, is to create a bfd | |
920 | section for each of the prstatus, prpsinfo, and fpregset structures, | |
921 | without any interpretation of their contents. With just this support, | |
922 | the bfd client will have to interpret the structures itself. Even with | |
923 | /proc support, it might want these full structures for it's own reasons. | |
924 | ||
925 | In the second level of support, where HAVE_PROCFS is defined, bfd will | |
926 | pick apart the structures to gather some additional information that | |
927 | clients may want, such as the general register set, the name of the | |
928 | exec'ed file and its arguments, the signal (if any) that caused the | |
929 | core dump, etc. | |
930 | ||
931 | */ | |
932 | ||
933 | static boolean | |
934 | DEFUN(elf_corefile_note, (abfd, hdr), | |
935 | bfd *abfd AND | |
936 | Elf_Internal_Phdr *hdr) | |
937 | { | |
938 | Elf_External_Note *x_note_p; /* Elf note, external form */ | |
939 | Elf_Internal_Note i_note; /* Elf note, internal form */ | |
940 | char *buf = NULL; /* Entire note segment contents */ | |
941 | char *namedata; /* Name portion of the note */ | |
942 | char *descdata; /* Descriptor portion of the note */ | |
943 | char *sectname; /* Name to use for new section */ | |
944 | long filepos; /* File offset to descriptor data */ | |
945 | asection *newsect; | |
946 | ||
947 | if (hdr -> p_filesz > 0 | |
d4acec2c | 948 | && (buf = (char *) bfd_xmalloc (hdr -> p_filesz)) != NULL |
f8e01940 | 949 | && bfd_seek (abfd, hdr -> p_offset, SEEK_SET) != -1 |
8c4a1ace JG |
950 | && bfd_read ((PTR) buf, hdr -> p_filesz, 1, abfd) == hdr -> p_filesz) |
951 | { | |
952 | x_note_p = (Elf_External_Note *) buf; | |
953 | while ((char *) x_note_p < (buf + hdr -> p_filesz)) | |
954 | { | |
955 | i_note.namesz = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p -> namesz); | |
956 | i_note.descsz = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p -> descsz); | |
957 | i_note.type = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p -> type); | |
958 | namedata = x_note_p -> name; | |
959 | descdata = namedata + BFD_ALIGN (i_note.namesz, 4); | |
960 | filepos = hdr -> p_offset + (descdata - buf); | |
961 | switch (i_note.type) { | |
962 | case NT_PRSTATUS: | |
963 | /* process descdata as prstatus info */ | |
964 | bfd_prstatus (abfd, descdata, i_note.descsz, filepos); | |
965 | sectname = ".prstatus"; | |
966 | break; | |
967 | case NT_FPREGSET: | |
968 | /* process descdata as fpregset info */ | |
969 | bfd_fpregset (abfd, descdata, i_note.descsz, filepos); | |
970 | sectname = ".fpregset"; | |
971 | break; | |
972 | case NT_PRPSINFO: | |
973 | /* process descdata as prpsinfo */ | |
974 | bfd_prpsinfo (abfd, descdata, i_note.descsz, filepos); | |
975 | sectname = ".prpsinfo"; | |
976 | break; | |
977 | default: | |
978 | /* Unknown descriptor, just ignore it. */ | |
979 | sectname = NULL; | |
980 | break; | |
981 | } | |
982 | if (sectname != NULL) | |
983 | { | |
984 | newsect = bfd_make_section (abfd, sectname); | |
e98e6ec1 | 985 | newsect -> _raw_size = i_note.descsz; |
8c4a1ace JG |
986 | newsect -> filepos = filepos; |
987 | newsect -> flags = SEC_ALLOC | SEC_HAS_CONTENTS; | |
988 | newsect -> alignment_power = 2; | |
989 | } | |
990 | x_note_p = (Elf_External_Note *) | |
991 | (descdata + BFD_ALIGN (i_note.descsz, 4)); | |
992 | } | |
993 | } | |
994 | if (buf != NULL) | |
995 | { | |
996 | free (buf); | |
997 | } | |
e83f3040 FF |
998 | return true; |
999 | ||
8c4a1ace JG |
1000 | } |
1001 | ||
1002 | ||
e83f3040 FF |
1003 | /* Read a specified number of bytes at a specified offset in an ELF |
1004 | file, into a newly allocated buffer, and return a pointer to the | |
1005 | buffer. */ | |
1006 | ||
1007 | static char * | |
1008 | DEFUN(elf_read, (abfd, offset, size), | |
1009 | bfd *abfd AND | |
1010 | long offset AND | |
1011 | int size) | |
1012 | { | |
1013 | char *buf; | |
1014 | ||
1015 | if ((buf = bfd_alloc (abfd, size)) == NULL) | |
1016 | { | |
1017 | bfd_error = no_memory; | |
1018 | return (NULL); | |
1019 | } | |
1020 | if (bfd_seek (abfd, offset, SEEK_SET) == -1) | |
1021 | { | |
1022 | bfd_error = system_call_error; | |
1023 | return (NULL); | |
1024 | } | |
1025 | if (bfd_read ((PTR) buf, size, 1, abfd) != size) | |
1026 | { | |
1027 | bfd_error = system_call_error; | |
1028 | return (NULL); | |
1029 | } | |
1030 | return (buf); | |
1031 | } | |
1032 | ||
9ce0058c SC |
1033 | /* Begin processing a given object. |
1034 | ||
1035 | First we validate the file by reading in the ELF header and checking | |
1036 | the magic number. | |
1037 | ||
1038 | */ | |
1039 | ||
1040 | static bfd_target * | |
1041 | DEFUN (elf_object_p, (abfd), bfd *abfd) | |
1042 | { | |
1043 | Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ | |
80bdcb77 | 1044 | Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ |
d4acec2c FF |
1045 | Elf_External_Shdr x_shdr; /* Section header table entry, external form */ |
1046 | Elf_Internal_Shdr *i_shdrp; /* Section header table, internal form */ | |
9ce0058c SC |
1047 | int shindex; |
1048 | char *shstrtab; /* Internal copy of section header stringtab */ | |
9ce0058c SC |
1049 | |
1050 | /* Read in the ELF header in external format. */ | |
1051 | ||
1052 | if (bfd_read ((PTR) &x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr)) | |
1053 | { | |
1054 | bfd_error = system_call_error; | |
1055 | return (NULL); | |
1056 | } | |
1057 | ||
1058 | /* Now check to see if we have a valid ELF file, and one that BFD can | |
1059 | make use of. The magic number must match, the address size ('class') | |
1060 | and byte-swapping must match our XVEC entry, and it must have a | |
1061 | section header table (FIXME: See comments re sections at top of this | |
1062 | file). */ | |
1063 | ||
1064 | if (x_ehdr.e_ident[EI_MAG0] != ELFMAG0 || | |
1065 | x_ehdr.e_ident[EI_MAG1] != ELFMAG1 || | |
1066 | x_ehdr.e_ident[EI_MAG2] != ELFMAG2 || | |
1067 | x_ehdr.e_ident[EI_MAG3] != ELFMAG3) | |
1068 | { | |
1069 | wrong: | |
1070 | bfd_error = wrong_format; | |
1071 | return (NULL); | |
1072 | } | |
1073 | ||
1074 | /* FIXME, Check EI_VERSION here ! */ | |
1075 | ||
37ac3b76 ME |
1076 | switch (x_ehdr.e_ident[EI_CLASS]) |
1077 | { | |
1078 | case ELFCLASSNONE: /* address size not specified */ | |
1079 | goto wrong; /* No support if can't tell address size */ | |
1080 | case ELFCLASS32: /* 32-bit addresses */ | |
1081 | break; | |
1082 | case ELFCLASS64: /* 64-bit addresses */ | |
1083 | goto wrong; /* FIXME: 64 bits not yet supported */ | |
1084 | default: | |
1085 | goto wrong; /* No support if unknown address class */ | |
1086 | } | |
9ce0058c SC |
1087 | |
1088 | /* Switch xvec to match the specified byte order. */ | |
37ac3b76 ME |
1089 | switch (x_ehdr.e_ident[EI_DATA]) |
1090 | { | |
1091 | case ELFDATA2MSB: /* Big-endian */ | |
1092 | if (!abfd->xvec->header_byteorder_big_p) | |
1093 | goto wrong; | |
1094 | break; | |
1095 | case ELFDATA2LSB: /* Little-endian */ | |
1096 | if (abfd->xvec->header_byteorder_big_p) | |
1097 | goto wrong; | |
1098 | break; | |
1099 | case ELFDATANONE: /* No data encoding specified */ | |
1100 | default: /* Unknown data encoding specified */ | |
d4acec2c | 1101 | goto wrong; |
37ac3b76 | 1102 | } |
9ce0058c | 1103 | |
8c4a1ace JG |
1104 | /* Allocate an instance of the elf_obj_tdata structure and hook it up to |
1105 | the tdata pointer in the bfd. */ | |
1106 | ||
80bdcb77 JG |
1107 | if (NULL == (elf_tdata (abfd) = (struct elf_obj_tdata *) |
1108 | bfd_zalloc (abfd, sizeof (struct elf_obj_tdata)))) | |
8c4a1ace JG |
1109 | { |
1110 | bfd_error = no_memory; | |
1111 | return (NULL); | |
1112 | } | |
1113 | ||
80bdcb77 JG |
1114 | /* FIXME: Any `wrong' exits below here will leak memory (tdata). */ |
1115 | ||
9ce0058c | 1116 | /* Now that we know the byte order, swap in the rest of the header */ |
80bdcb77 JG |
1117 | i_ehdrp = elf_elfheader (abfd); |
1118 | elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp); | |
37ac3b76 | 1119 | |
e0796d22 | 1120 | /* If there is no section header table, we're hosed. */ |
80bdcb77 | 1121 | if (i_ehdrp->e_shoff == 0) |
9ce0058c SC |
1122 | goto wrong; |
1123 | ||
80bdcb77 | 1124 | if (i_ehdrp->e_type == ET_EXEC || i_ehdrp->e_type == ET_DYN) |
37ac3b76 ME |
1125 | abfd -> flags |= EXEC_P; |
1126 | ||
80bdcb77 | 1127 | switch (i_ehdrp->e_machine) |
9ce0058c | 1128 | { |
37ac3b76 ME |
1129 | case EM_NONE: |
1130 | case EM_M32: /* or should this be bfd_arch_obscure? */ | |
1131 | bfd_default_set_arch_mach(abfd, bfd_arch_unknown, 0); | |
1132 | break; | |
1133 | case EM_SPARC: | |
1134 | bfd_default_set_arch_mach(abfd, bfd_arch_sparc, 0); | |
1135 | break; | |
1136 | case EM_386: | |
1137 | bfd_default_set_arch_mach(abfd, bfd_arch_i386, 0); | |
1138 | break; | |
1139 | case EM_68K: | |
1140 | bfd_default_set_arch_mach(abfd, bfd_arch_m68k, 0); | |
1141 | break; | |
1142 | case EM_88K: | |
1143 | bfd_default_set_arch_mach(abfd, bfd_arch_m88k, 0); | |
1144 | break; | |
1145 | case EM_860: | |
1146 | bfd_default_set_arch_mach(abfd, bfd_arch_i860, 0); | |
1147 | break; | |
1148 | case EM_MIPS: | |
1149 | bfd_default_set_arch_mach(abfd, bfd_arch_mips, 0); | |
1150 | break; | |
1151 | default: | |
1152 | goto wrong; | |
9ce0058c | 1153 | } |
37ac3b76 ME |
1154 | |
1155 | /* Allocate space for a copy of the section header table in | |
1156 | internal form, seek to the section header table in the file, | |
9ce0058c SC |
1157 | read it in, and convert it to internal form. As a simple sanity |
1158 | check, verify that the what BFD thinks is the size of each section | |
1159 | header table entry actually matches the size recorded in the file. */ | |
1160 | ||
80bdcb77 | 1161 | if (i_ehdrp->e_shentsize != sizeof (x_shdr)) |
9ce0058c | 1162 | goto wrong; |
37ac3b76 | 1163 | i_shdrp = (Elf_Internal_Shdr *) |
80bdcb77 | 1164 | bfd_alloc (abfd, sizeof (*i_shdrp) * i_ehdrp->e_shnum); |
37ac3b76 | 1165 | if (! i_shdrp) |
9ce0058c SC |
1166 | { |
1167 | bfd_error = no_memory; | |
1168 | return (NULL); | |
1169 | } | |
80bdcb77 | 1170 | if (bfd_seek (abfd, i_ehdrp->e_shoff, SEEK_SET) == -1) |
9ce0058c SC |
1171 | { |
1172 | bfd_error = system_call_error; | |
1173 | return (NULL); | |
1174 | } | |
80bdcb77 | 1175 | for (shindex = 0; shindex < i_ehdrp->e_shnum; shindex++) |
9ce0058c | 1176 | { |
37ac3b76 | 1177 | if (bfd_read ((PTR) &x_shdr, sizeof x_shdr, 1, abfd) |
d4acec2c | 1178 | != sizeof (x_shdr)) |
9ce0058c SC |
1179 | { |
1180 | bfd_error = system_call_error; | |
1181 | return (NULL); | |
1182 | } | |
d4acec2c | 1183 | elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex); |
9ce0058c SC |
1184 | } |
1185 | ||
37ac3b76 ME |
1186 | elf_elfsections (abfd) = i_shdrp; |
1187 | ||
9ce0058c SC |
1188 | /* Read in the string table containing the names of the sections. We |
1189 | will need the base pointer to this table later. */ | |
37ac3b76 ME |
1190 | /* We read this inline now, so that we don't have to go through |
1191 | bfd_section_from_shdr with it (since this particular strtab is | |
1192 | used to find all of the ELF section names.) */ | |
9ce0058c | 1193 | |
80bdcb77 | 1194 | shstrtab = elf_get_str_section (abfd, i_ehdrp->e_shstrndx); |
37ac3b76 ME |
1195 | if (! shstrtab) |
1196 | return (NULL); | |
1197 | ||
9ce0058c | 1198 | /* Once all of the section headers have been read and converted, we |
a6c1d731 | 1199 | can start processing them. Note that the first section header is |
8c4a1ace JG |
1200 | a dummy placeholder entry, so we ignore it. |
1201 | ||
1202 | We also watch for the symbol table section and remember the file | |
1203 | offset and section size for both the symbol table section and the | |
1204 | associated string table section. */ | |
9ce0058c | 1205 | |
80bdcb77 | 1206 | for (shindex = 1; shindex < i_ehdrp->e_shnum; shindex++) |
9ce0058c | 1207 | { |
37ac3b76 | 1208 | bfd_section_from_shdr (abfd, shindex); |
9ce0058c SC |
1209 | } |
1210 | ||
e83f3040 FF |
1211 | /* Remember the entry point specified in the ELF file header. */ |
1212 | ||
80bdcb77 | 1213 | bfd_get_start_address (abfd) = i_ehdrp->e_entry; |
e83f3040 | 1214 | |
9ce0058c SC |
1215 | return (abfd->xvec); |
1216 | } | |
1217 | ||
e0796d22 FF |
1218 | /* Core files are simply standard ELF formatted files that partition |
1219 | the file using the execution view of the file (program header table) | |
1220 | rather than the linking view. In fact, there is no section header | |
1221 | table in a core file. | |
8c4a1ace JG |
1222 | |
1223 | The process status information (including the contents of the general | |
1224 | register set) and the floating point register set are stored in a | |
1225 | segment of type PT_NOTE. We handcraft a couple of extra bfd sections | |
1226 | that allow standard bfd access to the general registers (.reg) and the | |
1227 | floating point registers (.reg2). | |
1228 | ||
e0796d22 FF |
1229 | */ |
1230 | ||
1231 | static bfd_target * | |
1232 | DEFUN (elf_core_file_p, (abfd), bfd *abfd) | |
1233 | { | |
1234 | Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ | |
80bdcb77 | 1235 | Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ |
d4acec2c FF |
1236 | Elf_External_Phdr x_phdr; /* Program header table entry, external form */ |
1237 | Elf_Internal_Phdr *i_phdrp; /* Program header table, internal form */ | |
37ac3b76 | 1238 | unsigned int phindex; |
e0796d22 FF |
1239 | |
1240 | /* Read in the ELF header in external format. */ | |
1241 | ||
1242 | if (bfd_read ((PTR) &x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr)) | |
1243 | { | |
1244 | bfd_error = system_call_error; | |
1245 | return (NULL); | |
1246 | } | |
1247 | ||
1248 | /* Now check to see if we have a valid ELF file, and one that BFD can | |
1249 | make use of. The magic number must match, the address size ('class') | |
1250 | and byte-swapping must match our XVEC entry, and it must have a | |
1251 | program header table (FIXME: See comments re segments at top of this | |
1252 | file). */ | |
1253 | ||
1254 | if (x_ehdr.e_ident[EI_MAG0] != ELFMAG0 || | |
1255 | x_ehdr.e_ident[EI_MAG1] != ELFMAG1 || | |
1256 | x_ehdr.e_ident[EI_MAG2] != ELFMAG2 || | |
1257 | x_ehdr.e_ident[EI_MAG3] != ELFMAG3) | |
1258 | { | |
1259 | wrong: | |
1260 | bfd_error = wrong_format; | |
1261 | return (NULL); | |
1262 | } | |
1263 | ||
1264 | /* FIXME, Check EI_VERSION here ! */ | |
1265 | ||
37ac3b76 ME |
1266 | switch (x_ehdr.e_ident[EI_CLASS]) |
1267 | { | |
1268 | case ELFCLASSNONE: /* address size not specified */ | |
1269 | goto wrong; /* No support if can't tell address size */ | |
1270 | case ELFCLASS32: /* 32-bit addresses */ | |
1271 | break; | |
1272 | case ELFCLASS64: /* 64-bit addresses */ | |
1273 | goto wrong; /* FIXME: 64 bits not yet supported */ | |
1274 | default: | |
1275 | goto wrong; /* No support if unknown address class */ | |
1276 | } | |
e0796d22 FF |
1277 | |
1278 | /* Switch xvec to match the specified byte order. */ | |
37ac3b76 ME |
1279 | switch (x_ehdr.e_ident[EI_DATA]) |
1280 | { | |
1281 | case ELFDATA2MSB: /* Big-endian */ | |
1282 | abfd->xvec = &elf_big_vec; | |
1283 | break; | |
1284 | case ELFDATA2LSB: /* Little-endian */ | |
1285 | abfd->xvec = &elf_little_vec; | |
1286 | break; | |
1287 | case ELFDATANONE: /* No data encoding specified */ | |
1288 | default: /* Unknown data encoding specified */ | |
1289 | goto wrong; | |
1290 | } | |
e0796d22 | 1291 | |
80bdcb77 | 1292 | /* Allocate an instance of the elf_obj_tdata structure and hook it up to |
8c4a1ace JG |
1293 | the tdata pointer in the bfd. */ |
1294 | ||
80bdcb77 JG |
1295 | elf_tdata (abfd) = |
1296 | (struct elf_obj_tdata *) bfd_zalloc (abfd, sizeof (struct elf_obj_tdata)); | |
1297 | if (elf_tdata (abfd) == NULL) | |
8c4a1ace JG |
1298 | { |
1299 | bfd_error = no_memory; | |
1300 | return (NULL); | |
1301 | } | |
1302 | ||
80bdcb77 JG |
1303 | /* FIXME, `wrong' returns from this point onward, leak memory. */ |
1304 | ||
1305 | /* Now that we know the byte order, swap in the rest of the header */ | |
1306 | i_ehdrp = elf_elfheader (abfd); | |
1307 | elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp); | |
1308 | ||
1309 | /* If there is no program header, or the type is not a core file, then | |
1310 | we are hosed. */ | |
1311 | if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE) | |
1312 | goto wrong; | |
1313 | ||
37ac3b76 | 1314 | /* Allocate space for a copy of the program header table in |
80bdcb77 | 1315 | internal form, seek to the program header table in the file, |
e0796d22 FF |
1316 | read it in, and convert it to internal form. As a simple sanity |
1317 | check, verify that the what BFD thinks is the size of each program | |
1318 | header table entry actually matches the size recorded in the file. */ | |
1319 | ||
80bdcb77 | 1320 | if (i_ehdrp->e_phentsize != sizeof (x_phdr)) |
e0796d22 | 1321 | goto wrong; |
37ac3b76 | 1322 | i_phdrp = (Elf_Internal_Phdr *) |
80bdcb77 | 1323 | bfd_alloc (abfd, sizeof (*i_phdrp) * i_ehdrp->e_phnum); |
37ac3b76 | 1324 | if (! i_phdrp) |
e0796d22 FF |
1325 | { |
1326 | bfd_error = no_memory; | |
1327 | return (NULL); | |
1328 | } | |
80bdcb77 | 1329 | if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) == -1) |
e0796d22 FF |
1330 | { |
1331 | bfd_error = system_call_error; | |
1332 | return (NULL); | |
1333 | } | |
80bdcb77 | 1334 | for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++) |
e0796d22 | 1335 | { |
d4acec2c FF |
1336 | if (bfd_read ((PTR) &x_phdr, sizeof (x_phdr), 1, abfd) |
1337 | != sizeof (x_phdr)) | |
e0796d22 FF |
1338 | { |
1339 | bfd_error = system_call_error; | |
1340 | return (NULL); | |
1341 | } | |
d4acec2c | 1342 | elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex); |
e0796d22 FF |
1343 | } |
1344 | ||
1345 | /* Once all of the program headers have been read and converted, we | |
1346 | can start processing them. */ | |
1347 | ||
80bdcb77 | 1348 | for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++) |
e0796d22 | 1349 | { |
d4acec2c FF |
1350 | bfd_section_from_phdr (abfd, i_phdrp + phindex, phindex); |
1351 | if ((i_phdrp + phindex) -> p_type == PT_NOTE) | |
8c4a1ace | 1352 | { |
d4acec2c | 1353 | elf_corefile_note (abfd, i_phdrp + phindex); |
8c4a1ace | 1354 | } |
e0796d22 FF |
1355 | } |
1356 | ||
e83f3040 FF |
1357 | /* Remember the entry point specified in the ELF file header. */ |
1358 | ||
80bdcb77 | 1359 | bfd_get_start_address (abfd) = i_ehdrp->e_entry; |
e83f3040 | 1360 | |
e0796d22 FF |
1361 | return (abfd->xvec); |
1362 | } | |
1363 | ||
9ce0058c SC |
1364 | static boolean |
1365 | DEFUN (elf_mkobject, (abfd), bfd *abfd) | |
1366 | { | |
37ac3b76 ME |
1367 | /* this just does initialization */ |
1368 | /* coff_mkobject zalloc's space for tdata.coff_obj_data ... */ | |
80bdcb77 JG |
1369 | elf_tdata(abfd) = (struct elf_obj_tdata *) |
1370 | bfd_zalloc (abfd, sizeof(struct elf_obj_tdata)); | |
37ac3b76 ME |
1371 | if (elf_tdata(abfd) == 0) { |
1372 | bfd_error = no_memory; | |
1373 | return false; | |
1374 | } | |
1375 | /* since everything is done at close time, do we need any | |
1376 | initialization? */ | |
1377 | ||
1378 | return (true); | |
1379 | } | |
1380 | ||
1381 | /* | |
1382 | Create ELF output from BFD sections. | |
1383 | ||
1384 | Essentially, just create the section header and forget about the program | |
1385 | header for now. | |
1386 | ||
1387 | */ | |
1388 | ||
1389 | /* lacking nested functions and nested types, set up for mapping over | |
1390 | BFD sections to produce ELF sections */ | |
1391 | ||
1392 | typedef struct { | |
1393 | Elf_Internal_Ehdr *i_ehdr; | |
1394 | Elf_Internal_Shdr *i_shdrp; | |
1395 | struct strtab *shstrtab; | |
1396 | int symtab_section; | |
1397 | } elf_sect_thunk; | |
1398 | ||
1399 | ||
1400 | ||
1401 | static void | |
1402 | DEFUN (elf_make_sections, (abfd, asect, obj), | |
1403 | bfd *abfd AND | |
1404 | asection *asect AND | |
1405 | PTR obj) | |
1406 | { | |
1407 | elf_sect_thunk *thunk = (elf_sect_thunk*)obj; | |
1408 | /* most of what is in bfd_shdr_from_section goes in here... */ | |
1409 | /* and all of these sections generate at *least* one ELF section. */ | |
1410 | int this_section; | |
1411 | int idx; | |
1412 | ||
1413 | /* check if we're making a PROGBITS section... */ | |
1414 | /* if ((asect->flags & SEC_ALLOC) && (asect->flags & SEC_LOAD)) */ | |
1415 | /* this was too strict... what *do* we want to check here? */ | |
1416 | if(1) | |
1417 | { | |
1418 | Elf_Internal_Shdr *this_hdr; | |
1419 | this_section = elf_section_from_bfd_section (abfd, asect); | |
1420 | this_hdr = &thunk->i_shdrp[this_section]; | |
1421 | ||
1422 | this_hdr->sh_addr = asect->vma; | |
1423 | this_hdr->sh_size = asect->_raw_size; | |
1424 | /* contents already set by elf_set_section_contents */ | |
1425 | ||
1426 | if (asect->flags & SEC_RELOC) | |
1427 | { | |
1428 | /* emit a reloc section, and thus strtab and symtab... */ | |
1429 | Elf_Internal_Shdr *rela_hdr; | |
1430 | Elf_Internal_Shdr *symtab_hdr; | |
1431 | Elf_Internal_Shdr *symstrtab_hdr; | |
1432 | Elf_External_Rela *outbound_relocs; | |
1433 | Elf_External_Sym *outbound_syms; | |
1434 | int rela_section; | |
1435 | int symstrtab_section; | |
1436 | ||
1437 | symtab_hdr = &thunk->i_shdrp[thunk->symtab_section]; | |
1438 | ||
1439 | if (thunk->symtab_section == this_section + 1) | |
1440 | rela_section = thunk->symtab_section + 2; /* symtab + symstrtab */ | |
1441 | else | |
1442 | rela_section = this_section + 1; | |
1443 | rela_hdr = &thunk->i_shdrp[rela_section]; | |
1444 | rela_hdr->sh_type = SHT_RELA; | |
1445 | rela_hdr->sh_link = thunk->symtab_section; | |
1446 | rela_hdr->sh_info = this_section; | |
1447 | rela_hdr->sh_entsize = sizeof (Elf_External_Rela); | |
1448 | /* orelocation has the data, reloc_count has the count... */ | |
1449 | rela_hdr->sh_size = rela_hdr->sh_entsize * asect->reloc_count; | |
37ac3b76 ME |
1450 | outbound_relocs = (Elf_External_Rela *) |
1451 | bfd_alloc(abfd, asect->reloc_count * sizeof(Elf_External_Rela)); | |
1452 | for (idx = 0; idx < asect->reloc_count; idx++) | |
1453 | { | |
1454 | Elf_Internal_Rela dst; | |
1455 | arelent *ptr; | |
1456 | Elf_External_Rela *src; | |
1457 | ||
1458 | ptr = asect->orelocation[idx]; | |
1459 | src = outbound_relocs + idx; | |
1460 | if (asect->flags & SEC_RELOC) | |
1461 | dst.r_offset = ptr->address - asect->vma; | |
1462 | else | |
1463 | dst.r_offset = ptr->address; | |
1464 | ||
1465 | dst.r_info = ELF_R_INFO(1 /*ptr->sym_ptr_ptr*/, /* needs index into symtab (FIXME) */ | |
1466 | ptr->howto->type); | |
1467 | ||
1468 | dst.r_addend = ptr->addend; | |
1469 | elf_swap_reloca_out(abfd, &dst, src); | |
1470 | } | |
1471 | rela_hdr->contents = (void*)outbound_relocs; | |
1472 | } | |
1473 | } | |
1474 | } | |
1475 | ||
1476 | static void | |
1477 | DEFUN (elf_fake_sections, (abfd, asect, obj), | |
1478 | bfd *abfd AND | |
1479 | asection *asect AND | |
1480 | PTR obj) | |
1481 | { | |
1482 | elf_sect_thunk *thunk = (elf_sect_thunk*)obj; | |
1483 | /* most of what is in bfd_shdr_from_section goes in here... */ | |
1484 | /* and all of these sections generate at *least* one ELF section. */ | |
1485 | int this_section; | |
1486 | int idx; | |
1487 | ||
1488 | /* check if we're making a PROGBITS section... */ | |
1489 | /* if ((asect->flags & SEC_ALLOC) && (asect->flags & SEC_LOAD)) */ | |
1490 | /* this was too strict... what *do* we want to check here? */ | |
1491 | if(1) | |
1492 | { | |
1493 | Elf_Internal_Shdr *this_hdr; | |
1494 | this_section = thunk->i_ehdr->e_shnum++; | |
1495 | this_hdr = &thunk->i_shdrp[this_section]; | |
1496 | this_hdr->sh_name = | |
1497 | bfd_add_to_strtab (abfd, thunk->shstrtab, asect->name); | |
1498 | /* we need to log the type *now* so that elf_section_from_bfd_section | |
1499 | can find us... have to set rawdata too. */ | |
1500 | this_hdr->rawdata = (void*)asect; | |
1501 | if ((asect->flags & SEC_ALLOC) && (asect->flags & SEC_LOAD)) | |
1502 | this_hdr->sh_type = SHT_PROGBITS; | |
1503 | else | |
1504 | /* what *do* we put here? */ | |
1505 | this_hdr->sh_type = SHT_PROGBITS; | |
1506 | ||
1507 | ||
1508 | if (asect->flags & SEC_RELOC) | |
1509 | { | |
1510 | /* emit a reloc section, and thus strtab and symtab... */ | |
1511 | Elf_Internal_Shdr *rela_hdr; | |
1512 | Elf_Internal_Shdr *symtab_hdr; | |
1513 | Elf_Internal_Shdr *symstrtab_hdr; | |
1514 | Elf_External_Rela *outbound_relocs; | |
1515 | Elf_External_Sym *outbound_syms; | |
1516 | int rela_section; | |
1517 | int symstrtab_section; | |
1518 | ||
1519 | /* note that only one symtab is used, so just remember it | |
1520 | for now */ | |
1521 | if (! thunk->symtab_section) | |
1522 | { | |
1523 | thunk->symtab_section = thunk->i_ehdr->e_shnum++; | |
1524 | symtab_hdr = &thunk->i_shdrp[thunk->symtab_section]; | |
1525 | symtab_hdr->sh_name = | |
1526 | bfd_add_to_strtab (abfd, thunk->shstrtab, ".symtab"); | |
1527 | symtab_hdr->sh_type = SHT_SYMTAB; | |
1528 | symtab_hdr->sh_entsize = sizeof (Elf_External_Sym); | |
1529 | ||
1530 | symstrtab_section = thunk->i_ehdr->e_shnum++; | |
1531 | BFD_ASSERT(symstrtab_section == thunk->symtab_section+1); | |
1532 | symstrtab_hdr = &thunk->i_shdrp[symstrtab_section]; | |
1533 | symtab_hdr->sh_link = symstrtab_section; | |
1534 | symstrtab_hdr->sh_name = | |
1535 | bfd_add_to_strtab (abfd, thunk->shstrtab, ".strtab"); | |
1536 | symstrtab_hdr->sh_type = SHT_STRTAB; | |
1537 | ||
1538 | symtab_hdr->contents = 0; | |
1539 | symstrtab_hdr->contents = 0; | |
1540 | symstrtab_hdr->sh_size = 0; | |
1541 | } | |
1542 | else | |
1543 | symtab_hdr = &thunk->i_shdrp[thunk->symtab_section]; | |
1544 | ||
1545 | rela_section = thunk->i_ehdr->e_shnum++; | |
1546 | rela_hdr = &thunk->i_shdrp[rela_section]; | |
1547 | rela_hdr->sh_name = | |
1548 | bfd_add_2_to_strtab (abfd, thunk->shstrtab, ".rela", asect->name); | |
1549 | rela_hdr->sh_type = SHT_RELA; | |
1550 | rela_hdr->sh_link = thunk->symtab_section; | |
1551 | rela_hdr->sh_info = this_section; | |
1552 | rela_hdr->sh_entsize = sizeof (Elf_External_Rela); | |
1553 | } | |
1554 | } | |
1555 | } | |
1556 | ||
1557 | ||
1558 | static boolean | |
1559 | DEFUN (elf_compute_section_file_positions, (abfd), bfd *abfd) | |
1560 | { | |
1561 | Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ | |
1562 | Elf_Internal_Shdr *i_shdrp; /* Section header table, internal form */ | |
1563 | struct strtab *shstrtab; | |
1564 | int count, maxsections; | |
1565 | int outbase; | |
1566 | elf_sect_thunk est; | |
1567 | ||
1568 | if (! elf_shstrtab (abfd)) { | |
80bdcb77 JG |
1569 | i_ehdrp = elf_elfheader (abfd); /* build new header in tdata memory */ |
1570 | shstrtab = bfd_new_strtab(abfd); | |
37ac3b76 | 1571 | |
80bdcb77 JG |
1572 | i_ehdrp->e_ident[EI_MAG0] = ELFMAG0; |
1573 | i_ehdrp->e_ident[EI_MAG1] = ELFMAG1; | |
1574 | i_ehdrp->e_ident[EI_MAG2] = ELFMAG2; | |
1575 | i_ehdrp->e_ident[EI_MAG3] = ELFMAG3; | |
1576 | ||
1577 | i_ehdrp->e_ident[EI_CLASS] = ELFCLASS32; /* FIXME: find out from bfd */ | |
1578 | i_ehdrp->e_ident[EI_DATA] = | |
1579 | abfd->xvec->byteorder_big_p ? ELFDATA2MSB : ELFDATA2LSB; | |
1580 | i_ehdrp->e_ident[EI_VERSION] = EV_CURRENT; | |
1581 | ||
1582 | for(count = EI_PAD; count < EI_NIDENT; count ++) | |
1583 | i_ehdrp->e_ident[count] = 0; | |
1584 | ||
1585 | i_ehdrp->e_type = (abfd->flags & EXEC_P)? ET_EXEC : ET_REL; | |
1586 | switch(bfd_get_arch(abfd)) | |
1587 | { | |
1588 | case bfd_arch_unknown: | |
1589 | i_ehdrp->e_machine = EM_NONE; | |
1590 | break; | |
1591 | case bfd_arch_sparc: | |
1592 | i_ehdrp->e_machine = EM_SPARC; | |
1593 | break; | |
1594 | case bfd_arch_i386: | |
1595 | i_ehdrp->e_machine = EM_386; | |
1596 | break; | |
1597 | case bfd_arch_m68k: | |
1598 | i_ehdrp->e_machine = EM_68K; | |
1599 | break; | |
1600 | case bfd_arch_m88k: | |
1601 | i_ehdrp->e_machine = EM_88K; | |
1602 | break; | |
1603 | case bfd_arch_i860: | |
1604 | i_ehdrp->e_machine = EM_860; | |
1605 | break; | |
1606 | case bfd_arch_mips: /* MIPS Rxxxx */ | |
1607 | i_ehdrp->e_machine = EM_MIPS; /* only MIPS R3000 */ | |
1608 | break; | |
1609 | /* also note that EM_M32, AT&T WE32100 is unknown to bfd */ | |
1610 | default: | |
1611 | i_ehdrp->e_machine = EM_NONE; | |
1612 | } | |
1613 | i_ehdrp->e_version = EV_CURRENT; | |
1614 | i_ehdrp->e_ehsize = sizeof(Elf_External_Ehdr); | |
1615 | ||
1616 | /* no program header, for now. */ | |
1617 | i_ehdrp->e_phoff = 0; | |
1618 | i_ehdrp->e_phentsize = 0; | |
1619 | i_ehdrp->e_phnum = 0; | |
37ac3b76 | 1620 | |
80bdcb77 JG |
1621 | /* each bfd section is section header entry */ |
1622 | i_ehdrp->e_entry = bfd_get_start_address (abfd); | |
1623 | i_ehdrp->e_shentsize = sizeof (Elf_External_Shdr); | |
37ac3b76 | 1624 | |
80bdcb77 JG |
1625 | /* figure at most each section can have a rel, strtab, symtab */ |
1626 | maxsections = 4*bfd_count_sections(abfd)+2; | |
37ac3b76 | 1627 | |
80bdcb77 | 1628 | i_ehdrp->e_shoff = i_ehdrp->e_ehsize; |
37ac3b76 | 1629 | |
80bdcb77 JG |
1630 | /* and we'll just have to fix up the offsets later. */ |
1631 | /* outbase += i_ehdr.e_shentsize * i_ehdr.e_shnum; */ | |
1632 | ||
1633 | i_shdrp = (Elf_Internal_Shdr *) | |
1634 | bfd_alloc (abfd, sizeof (*i_shdrp) * maxsections); | |
1635 | if (! i_shdrp) | |
1636 | { | |
1637 | bfd_error = no_memory; | |
1638 | return (false); | |
1639 | } | |
1640 | for (count=0; count < maxsections; count++) | |
1641 | { | |
1642 | i_shdrp[count].rawdata = 0; | |
1643 | i_shdrp[count].contents = 0; | |
1644 | } | |
1645 | ||
1646 | ||
1647 | i_shdrp[0].sh_name = 0; | |
1648 | i_shdrp[0].sh_type = SHT_NULL; | |
1649 | i_shdrp[0].sh_flags = 0; | |
1650 | i_shdrp[0].sh_addr = 0; | |
1651 | i_shdrp[0].sh_offset = 0; | |
1652 | i_shdrp[0].sh_size = 0; | |
1653 | i_shdrp[0].sh_link = SHN_UNDEF; | |
1654 | i_shdrp[0].sh_info = 0; | |
1655 | i_shdrp[0].sh_addralign = 0; | |
1656 | i_shdrp[0].sh_entsize = 0; | |
1657 | ||
1658 | i_ehdrp->e_shnum = 1; | |
1659 | ||
1660 | elf_elfsections (abfd) = i_shdrp; | |
1661 | elf_shstrtab (abfd) = shstrtab; | |
37ac3b76 ME |
1662 | } |
1663 | est.i_ehdr = elf_elfheader(abfd); | |
1664 | est.i_shdrp = elf_elfsections(abfd); | |
1665 | est.shstrtab = elf_shstrtab(abfd); | |
1666 | est.symtab_section = 0; /* elf_fake_sections fils it in */ | |
1667 | ||
1668 | bfd_map_over_sections(abfd, elf_fake_sections, &est); | |
1669 | elf_onesymtab (abfd) = est.symtab_section; | |
808dfd5a | 1670 | return (true); |
9ce0058c SC |
1671 | } |
1672 | ||
1673 | static boolean | |
1674 | DEFUN (elf_write_object_contents, (abfd), bfd *abfd) | |
1675 | { | |
37ac3b76 ME |
1676 | Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ |
1677 | Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ | |
1678 | Elf_External_Phdr *x_phdrp; /* Program header table, external form */ | |
1679 | Elf_Internal_Phdr *i_phdrp; /* Program header table, internal form */ | |
1680 | Elf_External_Shdr *x_shdrp; /* Section header table, external form */ | |
1681 | Elf_Internal_Shdr *i_shdrp; /* Section header table, internal form */ | |
1682 | asection *nsect; | |
1683 | int maxsections; | |
1684 | elf_sect_thunk est; | |
1685 | ||
1686 | int outbase = 0; | |
1687 | int count; | |
1688 | struct strtab *shstrtab; | |
1689 | ||
1690 | if(abfd->output_has_begun == false) | |
1691 | elf_compute_section_file_positions(abfd); | |
1692 | ||
1693 | i_ehdrp = elf_elfheader (abfd); | |
1694 | i_shdrp = elf_elfsections (abfd); | |
1695 | shstrtab = elf_shstrtab (abfd); | |
1696 | ||
1697 | est.i_ehdr = i_ehdrp; | |
1698 | est.i_shdrp = i_shdrp; | |
1699 | est.shstrtab = shstrtab; | |
1700 | est.symtab_section = elf_onesymtab (abfd); /* filled in by elf_fake */ | |
1701 | ||
1702 | bfd_map_over_sections(abfd, elf_make_sections, &est); | |
1703 | ||
1704 | /* dump out the one symtab */ | |
1705 | { | |
1706 | int symcount = bfd_get_symcount (abfd); | |
1707 | asymbol ** syms = bfd_get_outsymbols (abfd); | |
1708 | struct strtab * stt = bfd_new_strtab (abfd); | |
1709 | Elf_Internal_Shdr *symtab_hdr; | |
1710 | Elf_Internal_Shdr *symstrtab_hdr; | |
1711 | int symstrtab_section; | |
1712 | Elf_External_Sym *outbound_syms; | |
1713 | int idx; | |
1714 | ||
1715 | symtab_hdr = &i_shdrp[est.symtab_section]; | |
1716 | symtab_hdr->sh_type = SHT_SYMTAB; | |
1717 | symtab_hdr->sh_entsize = sizeof (Elf_External_Sym); | |
1718 | symtab_hdr->sh_size = symtab_hdr->sh_entsize * symcount; | |
1719 | ||
1720 | /* see assert in elf_fake_sections that supports this: */ | |
1721 | symstrtab_section = est.symtab_section+1; | |
1722 | symstrtab_hdr = &i_shdrp[symstrtab_section]; | |
1723 | symtab_hdr->sh_link = symstrtab_section; | |
1724 | symstrtab_hdr->sh_type = SHT_STRTAB; | |
1725 | ||
37ac3b76 ME |
1726 | outbound_syms = (Elf_External_Sym*) |
1727 | bfd_alloc(abfd, (1+symcount) * sizeof(Elf_External_Sym)); | |
1728 | /* now generate the data (for "contents") */ | |
1729 | for (idx = 0; idx < symcount; idx++) | |
1730 | { | |
1731 | Elf_Internal_Sym sym; | |
1732 | sym.st_name = bfd_add_to_strtab (abfd, stt, syms[idx]->name); | |
1733 | sym.st_value = syms[idx]->value; | |
1734 | sym.st_size = 0; /* we should recover this (FIXME) */ | |
1735 | if (syms[idx]->flags & BSF_WEAK) | |
1736 | sym.st_info = ELF_ST_INFO(STB_WEAK, STT_OBJECT); | |
1737 | else if (syms[idx]->flags & BSF_LOCAL) | |
1738 | sym.st_info = ELF_ST_INFO(STB_LOCAL, STT_OBJECT); | |
1739 | else if (syms[idx]->flags & BSF_GLOBAL) | |
1740 | sym.st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT); | |
3dfa6cfb FF |
1741 | else if (syms[idx]->flags & BSF_SECTION_SYM) |
1742 | sym.st_info = ELF_ST_INFO(STB_LOCAL, STT_SECTION); | |
1743 | else if (syms[idx]->flags & BSF_FILE) | |
1744 | sym.st_info = ELF_ST_INFO(STB_LOCAL, STT_FILE); | |
37ac3b76 ME |
1745 | |
1746 | sym.st_other = 0; | |
1747 | if (syms[idx]->section) | |
1748 | sym.st_shndx = | |
1749 | elf_section_from_bfd_section(abfd, | |
1750 | syms[idx]->section->output_section); | |
1751 | else | |
1752 | sym.st_shndx = SHN_UNDEF; | |
1753 | ||
1754 | elf_swap_symbol_out (abfd, &sym, outbound_syms+idx+1); | |
1755 | } | |
1756 | { | |
1757 | /* fill in 0th symbol */ | |
1758 | Elf_Internal_Sym sym; | |
1759 | sym.st_name = 0; | |
1760 | sym.st_value = 0; | |
1761 | sym.st_size = 0; | |
1762 | sym.st_info = 0; | |
1763 | sym.st_other = 0; | |
1764 | sym.st_shndx = SHN_UNDEF; | |
1765 | elf_swap_symbol_out (abfd, &sym, outbound_syms); | |
1766 | } | |
1767 | symtab_hdr->contents = (void*)outbound_syms; | |
1768 | symstrtab_hdr->contents = (void*)stt->tab; | |
1769 | symstrtab_hdr->sh_size = stt->length; | |
1770 | } | |
1771 | ||
1772 | /* put the strtab out too... */ | |
1773 | { | |
1774 | Elf_Internal_Shdr *this_hdr; | |
1775 | int this_section; | |
1776 | ||
1777 | this_section = i_ehdrp->e_shnum++; | |
1778 | i_ehdrp->e_shstrndx = this_section; | |
1779 | this_hdr = &i_shdrp[this_section]; | |
1780 | this_hdr->sh_name = bfd_add_to_strtab (abfd, shstrtab, ".shstrtab"); | |
1781 | this_hdr->sh_size = shstrtab->length; | |
1782 | this_hdr->contents = (void*)shstrtab->tab; | |
1783 | } | |
1784 | ||
1785 | outbase = i_ehdrp->e_ehsize; | |
1786 | ||
1787 | /* swap the header before spitting it out... */ | |
1788 | elf_swap_ehdr_out (abfd, i_ehdrp, &x_ehdr); | |
f8e01940 | 1789 | bfd_seek (abfd, (file_ptr) 0, SEEK_SET); |
37ac3b76 ME |
1790 | bfd_write ((PTR) &x_ehdr, sizeof(x_ehdr), 1, abfd); |
1791 | ||
1792 | outbase += i_ehdrp->e_shentsize * i_ehdrp->e_shnum; | |
1793 | ||
1794 | /* now we fix up the offsets... */ | |
1795 | for (count = 0; count < i_ehdrp->e_shnum; count ++) | |
1796 | { | |
1797 | i_shdrp[count].sh_offset = outbase; | |
1798 | outbase += i_shdrp[count].sh_size; | |
1799 | } | |
1800 | ||
1801 | /* at this point we've concocted all the ELF sections... */ | |
1802 | x_shdrp = (Elf_External_Shdr *) | |
1803 | bfd_alloc (abfd, sizeof (*x_shdrp) * (i_ehdrp->e_shnum)); | |
1804 | if (! x_shdrp) | |
1805 | { | |
1806 | bfd_error = no_memory; | |
808dfd5a | 1807 | return (false); |
37ac3b76 ME |
1808 | } |
1809 | ||
37ac3b76 ME |
1810 | for (count = 0; count < i_ehdrp->e_shnum; count ++) |
1811 | { | |
1812 | elf_swap_shdr_out (abfd, i_shdrp+count, x_shdrp+count); | |
1813 | } | |
1814 | bfd_write ((PTR) x_shdrp, sizeof(*x_shdrp), i_ehdrp->e_shnum, abfd); | |
1815 | /* need to dump the string table too... */ | |
1816 | ||
1817 | /* after writing the headers, we need to write the sections too... */ | |
1818 | nsect = abfd->sections; | |
1819 | for (count = 0; count < i_ehdrp->e_shnum; count ++) | |
1820 | { | |
1821 | if(i_shdrp[count].contents) | |
1822 | { | |
37ac3b76 ME |
1823 | bfd_seek (abfd, i_shdrp[count].sh_offset, SEEK_SET); |
1824 | bfd_write (i_shdrp[count].contents, i_shdrp[count].sh_size, 1, abfd); | |
1825 | } | |
1826 | } | |
1827 | ||
1828 | /* sample use of bfd: | |
f8e01940 | 1829 | * bfd_seek (abfd, (file_ptr) 0, SEEK_SET); |
37ac3b76 ME |
1830 | * bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd); |
1831 | * if (bfd_seek(abfd, scn_base, SEEK_SET) != 0) | |
1832 | * return false; | |
1833 | * old = bfd_tell(abfd); | |
1834 | */ | |
1835 | ||
1836 | return true; | |
1837 | ||
9ce0058c SC |
1838 | } |
1839 | ||
8c4a1ace JG |
1840 | /* Given an index of a section, retrieve a pointer to it. Note |
1841 | that for our purposes, sections are indexed by {1, 2, ...} with | |
1842 | 0 being an illegal index. */ | |
1843 | ||
37ac3b76 ME |
1844 | /* In the original, each ELF section went into exactly one BFD |
1845 | section. This doesn't really make sense, so we need a real mapping. | |
1846 | The mapping has to hide in the Elf_Internal_Shdr since asection | |
1847 | doesn't have anything like a tdata field... */ | |
1848 | ||
8c4a1ace | 1849 | static struct sec * |
37ac3b76 | 1850 | DEFUN (section_from_elf_index, (abfd, index), |
8c4a1ace JG |
1851 | bfd *abfd AND |
1852 | int index) | |
1853 | { | |
37ac3b76 ME |
1854 | Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd); |
1855 | Elf_Internal_Shdr *hdr = i_shdrp + index; | |
1856 | ||
1857 | switch (hdr->sh_type) | |
8c4a1ace | 1858 | { |
37ac3b76 ME |
1859 | /* ELF sections that map to BFD sections */ |
1860 | case SHT_PROGBITS: | |
1861 | case SHT_NOBITS: | |
1862 | if (! hdr->rawdata) | |
1863 | bfd_section_from_shdr (abfd, index); | |
1864 | return (struct sec *)hdr->rawdata; | |
1865 | break; | |
1866 | default: | |
13ff1343 | 1867 | return (struct sec *)&bfd_abs_section; |
8c4a1ace | 1868 | } |
37ac3b76 ME |
1869 | } |
1870 | ||
1871 | /* given a section, search the header to find them... */ | |
1872 | static int | |
1873 | DEFUN (elf_section_from_bfd_section, (abfd, asect), | |
1874 | bfd *abfd AND | |
1875 | struct sec *asect) | |
1876 | { | |
1877 | Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd); | |
1878 | int index; | |
1879 | Elf_Internal_Shdr *hdr; | |
1880 | int maxindex = elf_elfheader (abfd)->e_shnum; | |
1881 | ||
1882 | for(index = 0; index < maxindex; index++) { | |
1883 | hdr = &i_shdrp[index]; | |
1884 | switch (hdr->sh_type) | |
1885 | { | |
1886 | /* ELF sections that map to BFD sections */ | |
1887 | case SHT_PROGBITS: | |
1888 | case SHT_NOBITS: | |
1889 | if (hdr->rawdata) | |
1890 | { | |
1891 | if (((struct sec *)(hdr->rawdata)) == asect) | |
1892 | return index; | |
1893 | } | |
1894 | break; | |
1895 | default: | |
1896 | break; | |
1897 | } | |
1898 | } | |
1899 | return 0; | |
8c4a1ace JG |
1900 | } |
1901 | ||
1902 | static boolean | |
3dfa6cfb | 1903 | DEFUN (elf_slurp_symbol_table, (abfd, symptrs), |
37ac3b76 | 1904 | bfd *abfd AND |
3dfa6cfb | 1905 | asymbol **symptrs) /* Buffer for generated bfd symbols */ |
8c4a1ace | 1906 | { |
3dfa6cfb FF |
1907 | Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd); |
1908 | Elf_Internal_Shdr *hdr = i_shdrp + elf_onesymtab (abfd); | |
8c4a1ace | 1909 | int symcount; /* Number of external ELF symbols */ |
3dfa6cfb | 1910 | int i; |
8c4a1ace JG |
1911 | asymbol *sym; /* Pointer to current bfd symbol */ |
1912 | asymbol *symbase; /* Buffer for generated bfd symbols */ | |
8c4a1ace | 1913 | Elf_Internal_Sym i_sym; |
37ac3b76 | 1914 | Elf_External_Sym *x_symp; |
8c4a1ace | 1915 | |
37ac3b76 | 1916 | /* this is only valid because there is only one symtab... */ |
91f781ff FF |
1917 | /* FIXME: This is incorrect, there may also be a dynamic symbol |
1918 | table which is a subset of the full symbol table. We either need | |
1919 | to be prepared to read both (and merge them) or ensure that we | |
1920 | only read the full symbol table. Currently we only get called to | |
1921 | read the full symbol table. -fnf */ | |
8c4a1ace JG |
1922 | if (bfd_get_outsymbols (abfd) != NULL) |
1923 | { | |
1924 | return (true); | |
1925 | } | |
1926 | ||
8c4a1ace JG |
1927 | /* Read each raw ELF symbol, converting from external ELF form to |
1928 | internal ELF form, and then using the information to create a | |
1929 | canonical bfd symbol table entry. | |
1930 | ||
37ac3b76 | 1931 | Note that we allocate the initial bfd canonical symbol buffer |
8c4a1ace | 1932 | based on a one-to-one mapping of the ELF symbols to canonical |
3dfa6cfb FF |
1933 | symbols. We actually use all the ELF symbols, so there will be no |
1934 | space left over at the end. When we have all the symbols, we | |
1935 | build the caller's pointer vector. */ | |
8c4a1ace | 1936 | |
37ac3b76 | 1937 | if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1) |
8c4a1ace JG |
1938 | { |
1939 | bfd_error = system_call_error; | |
1940 | return (false); | |
1941 | } | |
1942 | ||
37ac3b76 | 1943 | symcount = hdr->sh_size / sizeof (Elf_External_Sym); |
3dfa6cfb FF |
1944 | symbase = (asymbol *) bfd_zalloc (abfd, symcount * sizeof (asymbol)); |
1945 | sym = symbase; | |
1946 | ||
1947 | /* Temporarily allocate room for the raw ELF symbols. */ | |
1948 | x_symp = (Elf_External_Sym *) malloc (symcount * sizeof (Elf_External_Sym)); | |
8c4a1ace | 1949 | |
37ac3b76 ME |
1950 | if (bfd_read ((PTR) x_symp, sizeof (Elf_External_Sym), symcount, abfd) |
1951 | != symcount * sizeof (Elf_External_Sym)) | |
1952 | { | |
3dfa6cfb | 1953 | free ((PTR)x_symp); |
37ac3b76 ME |
1954 | bfd_error = system_call_error; |
1955 | return (false); | |
1956 | } | |
3dfa6cfb FF |
1957 | /* Skip first symbol, which is a null dummy. */ |
1958 | for (i = 1; i < symcount; i++) | |
8c4a1ace | 1959 | { |
3dfa6cfb FF |
1960 | elf_swap_symbol_in (abfd, x_symp + i, &i_sym); |
1961 | sym -> the_bfd = abfd; | |
37ac3b76 | 1962 | if (i_sym.st_name > 0) |
3dfa6cfb FF |
1963 | sym -> name = elf_string_from_elf_section(abfd, hdr->sh_link, |
1964 | i_sym.st_name); | |
1965 | else | |
1966 | sym -> name = "unnamed"; /* perhaps should include the number? */ | |
1967 | sym -> value = i_sym.st_value; | |
80bdcb77 | 1968 | /* FIXME -- this is almost certainly bogus. It's from Pace Willisson's |
3dfa6cfb FF |
1969 | hasty Solaris support, to pass the sizes of object files or functions |
1970 | down into GDB via the back door, to circumvent some other kludge in | |
1971 | how Sun hacked stabs. -- [email protected] */ | |
1972 | sym -> udata = (PTR)i_sym.st_size; | |
80bdcb77 | 1973 | /* FIXME -- end of bogosity. */ |
3dfa6cfb FF |
1974 | if (i_sym.st_shndx > 0 && i_sym.st_shndx < SHN_LORESERV) |
1975 | { | |
1976 | sym -> section = section_from_elf_index (abfd, i_sym.st_shndx); | |
8c4a1ace | 1977 | } |
3dfa6cfb | 1978 | else if (i_sym.st_shndx == SHN_ABS) |
8c4a1ace | 1979 | { |
3dfa6cfb FF |
1980 | sym -> section = &bfd_abs_section; |
1981 | } | |
1982 | else if (i_sym.st_shndx == SHN_COMMON) | |
1983 | { | |
1984 | sym -> section = &bfd_com_section; | |
1985 | } | |
1986 | else if (i_sym.st_shndx == SHN_UNDEF) | |
1987 | { | |
1988 | sym -> section = &bfd_und_section; | |
1989 | } | |
13ff1343 BK |
1990 | else |
1991 | sym -> section = &bfd_abs_section; | |
3dfa6cfb FF |
1992 | |
1993 | switch (ELF_ST_BIND (i_sym.st_info)) | |
1994 | { | |
1995 | case STB_LOCAL: | |
1996 | sym -> flags |= BSF_LOCAL; | |
1997 | break; | |
1998 | case STB_GLOBAL: | |
1999 | sym -> flags |= (BSF_GLOBAL | BSF_EXPORT); | |
2000 | break; | |
2001 | case STB_WEAK: | |
2002 | sym -> flags |= BSF_WEAK; | |
2003 | break; | |
2004 | } | |
37ac3b76 | 2005 | |
3dfa6cfb FF |
2006 | switch (ELF_ST_TYPE (i_sym.st_info)) |
2007 | { | |
2008 | case STT_SECTION: | |
2009 | sym->flags |= BSF_SECTION_SYM | BSF_DEBUGGING; | |
2010 | break; | |
2011 | case STT_FILE: | |
2012 | sym->flags |= BSF_FILE | BSF_DEBUGGING; | |
2013 | break; | |
8c4a1ace | 2014 | } |
3dfa6cfb | 2015 | sym++; |
8c4a1ace JG |
2016 | } |
2017 | ||
3dfa6cfb FF |
2018 | /* We rely on the zalloc to clear out the final symbol entry. */ |
2019 | ||
2020 | /* We're now done with the raw symbols. */ | |
2021 | free ((PTR)x_symp); | |
8c4a1ace | 2022 | |
3dfa6cfb FF |
2023 | bfd_get_symcount(abfd) = symcount = sym - symbase; |
2024 | ||
2025 | /* Fill in the user's symbol pointer vector if needed. */ | |
2026 | if (symptrs) | |
8c4a1ace | 2027 | { |
3dfa6cfb FF |
2028 | sym = symbase; |
2029 | while (symcount-- > 0) | |
2030 | { | |
2031 | *symptrs++ = sym++; | |
2032 | } | |
2033 | *symptrs = 0; /* Final null pointer */ | |
8c4a1ace JG |
2034 | } |
2035 | ||
2036 | return (true); | |
2037 | } | |
2038 | ||
2039 | /* Return the number of bytes required to hold the symtab vector. | |
2040 | ||
2041 | Note that we base it on the count plus 1, since we will null terminate | |
3dfa6cfb FF |
2042 | the vector allocated based on this size. However, the ELF symbol table |
2043 | always has a dummy entry as symbol #0, so it ends up even. */ | |
8c4a1ace | 2044 | |
9ce0058c | 2045 | static unsigned int |
8c4a1ace | 2046 | DEFUN (elf_get_symtab_upper_bound, (abfd), bfd *abfd) |
9ce0058c | 2047 | { |
3dfa6cfb FF |
2048 | unsigned int symcount; |
2049 | unsigned int symtab_size; | |
2050 | Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd); | |
2051 | Elf_Internal_Shdr *hdr = i_shdrp + elf_onesymtab (abfd); | |
8c4a1ace | 2052 | |
3dfa6cfb FF |
2053 | symcount = hdr->sh_size / sizeof (Elf_External_Sym); |
2054 | symtab_size = (symcount - 1 + 1) * (sizeof (asymbol)); | |
8c4a1ace | 2055 | return (symtab_size); |
9ce0058c SC |
2056 | } |
2057 | ||
37ac3b76 ME |
2058 | /* |
2059 | This function return the number of bytes required to store the | |
2060 | relocation information associated with section <<sect>> | |
2061 | attached to bfd <<abfd>> | |
2062 | ||
2063 | */ | |
9ce0058c SC |
2064 | static unsigned int |
2065 | elf_get_reloc_upper_bound (abfd, asect) | |
2066 | bfd *abfd; | |
2067 | sec_ptr asect; | |
2068 | { | |
37ac3b76 ME |
2069 | if (asect->flags & SEC_RELOC) |
2070 | { | |
2071 | /* either rel or rela */ | |
2072 | return asect->_raw_size; | |
2073 | } | |
2074 | else | |
2075 | return (0); | |
2076 | } | |
2077 | ||
2078 | /* FIXME!!! sparc howto should go into elf-32-sparc.c */ | |
2079 | #ifdef sparc | |
2080 | enum reloc_type | |
2081 | { | |
2082 | R_SPARC_NONE = 0, | |
2083 | R_SPARC_8, R_SPARC_16, R_SPARC_32, | |
2084 | R_SPARC_DISP8, R_SPARC_DISP16, R_SPARC_DISP32, | |
2085 | R_SPARC_WDISP30, R_SPARC_WDISP22, | |
2086 | R_SPARC_HI22, R_SPARC_22, | |
2087 | R_SPARC_13, R_SPARC_LO10, | |
2088 | R_SPARC_GOT10, R_SPARC_GOT13, R_SPARC_GOT22, | |
2089 | R_SPARC_PC10, R_SPARC_PC22, | |
2090 | R_SPARC_WPLT30, | |
2091 | R_SPARC_COPY, | |
2092 | R_SPARC_GLOB_DAT, R_SPARC_JMP_SLOT, | |
2093 | R_SPARC_RELATIVE, | |
2094 | R_SPARC_UA32, | |
2095 | }; | |
2096 | ||
2097 | #define RELOC_TYPE_NAMES \ | |
2098 | "R_SPARC_NONE", \ | |
2099 | "R_SPARC_8", "R_SPARC_16", "R_SPARC_32", \ | |
2100 | "R_SPARC_DISP8", "R_SPARC_DISP16", "R_SPARC_DISP32", \ | |
2101 | "R_SPARC_WDISP30", "R_SPARC_WDISP22", \ | |
2102 | "R_SPARC_HI22", "R_SPARC_22", \ | |
2103 | "R_SPARC_13", "R_SPARC_LO10", \ | |
2104 | "R_SPARC_GOT10", "R_SPARC_GOT13", "R_SPARC_GOT22", \ | |
2105 | "R_SPARC_PC10", "R_SPARC_PC22", \ | |
2106 | "R_SPARC_WPLT30", \ | |
2107 | "R_SPARC_COPY", \ | |
2108 | "R_SPARC_GLOB_DAT", "R_SPARC_JMP_SLOT", \ | |
2109 | "R_SPARC_RELATIVE", \ | |
2110 | "R_SPARC_UA32" | |
2111 | ||
2112 | static reloc_howto_type elf_howto_table[] = | |
2113 | { | |
2114 | HOWTO(R_SPARC_NONE, 0,0, 0,false,0,false,false, 0,"R_SPARC_NONE", false,0,0x00000000,false), | |
2115 | HOWTO(R_SPARC_8, 0,0, 8,false,0,true, true, 0,"R_SPARC_8", false,0,0x000000ff,false), | |
2116 | HOWTO(R_SPARC_16, 0,1,16,false,0,true, true, 0,"R_SPARC_16", false,0,0x0000ffff,false), | |
2117 | HOWTO(R_SPARC_32, 0,2,32,false,0,true, true, 0,"R_SPARC_32", false,0,0xffffffff,false), | |
2118 | HOWTO(R_SPARC_DISP8, 0,0, 8,true, 0,false, true, 0,"R_SPARC_DISP8", false,0,0x000000ff,false), | |
2119 | HOWTO(R_SPARC_DISP16, 0,1,16,true, 0,false, true, 0,"R_SPARC_DISP16", false,0,0x0000ffff,false), | |
2120 | HOWTO(R_SPARC_DISP32, 0,2,32,true, 0,false, true, 0,"R_SPARC_DISP32", false,0,0x00ffffff,false), | |
2121 | HOWTO(R_SPARC_WDISP30,2,2,30,true, 0,false, true, 0,"R_SPARC_WDISP30",false,0,0x3fffffff,false), | |
2122 | HOWTO(R_SPARC_WDISP22,2,2,22,true, 0,false, true, 0,"R_SPARC_WDISP22",false,0,0x003fffff,false), | |
2123 | HOWTO(R_SPARC_HI22, 10,2,22,false,0,true, false, 0,"R_SPARC_HI22", false,0,0x003fffff,false), | |
2124 | HOWTO(R_SPARC_22, 0,2,22,false,0,true, true, 0,"R_SPARC_22", false,0,0x003fffff,false), | |
2125 | HOWTO(R_SPARC_13, 0,1,13,false,0,true, true, 0,"R_SPARC_13", false,0,0x00001fff,false), | |
2126 | HOWTO(R_SPARC_LO10, 0,1,10,false,0,true, false, 0,"R_SPARC_LO10", false,0,0x000003ff,false), | |
2127 | HOWTO(R_SPARC_GOT10, 0,1,10,false,0,false, true, 0,"R_SPARC_GOT10", false,0,0x000003ff,false), | |
2128 | HOWTO(R_SPARC_GOT13, 0,1,13,false,0,false, true, 0,"R_SPARC_GOT13", false,0,0x00001fff,false), | |
2129 | HOWTO(R_SPARC_GOT22, 10,2,22,false,0,false, true, 0,"R_SPARC_GOT22", false,0,0x003fffff,false), | |
2130 | HOWTO(R_SPARC_PC10, 0,1,10,false,0,true, true, 0,"R_SPARC_PC10", false,0,0x000003ff,false), | |
2131 | HOWTO(R_SPARC_PC22, 0,2,22,false,0,true, true, 0,"R_SPARC_PC22", false,0,0x003fffff,false), | |
2132 | HOWTO(R_SPARC_WPLT30, 0,0,00,false,0,false,false, 0,"R_SPARC_WPLT30", false,0,0x00000000,false), | |
2133 | HOWTO(R_SPARC_COPY, 0,0,00,false,0,false,false, 0,"R_SPARC_COPY", false,0,0x00000000,false), | |
2134 | HOWTO(R_SPARC_GLOB_DAT,0,0,00,false,0,false,false,0,"R_SPARC_GLOB_DAT",false,0,0x00000000,false), | |
2135 | HOWTO(R_SPARC_JMP_SLOT,0,0,00,false,0,false,false,0,"R_SPARC_JMP_SLOT",false,0,0x00000000,false), | |
2136 | HOWTO(R_SPARC_RELATIVE,0,0,00,false,0,false,false,0,"R_SPARC_RELATIVE",false,0,0x00000000,false), | |
2137 | HOWTO(R_SPARC_UA32, 0,0,00,false,0,false,false,0,"R_SPARC_UA32", false,0,0x00000000,false), | |
2138 | }; | |
2139 | #endif | |
2140 | ||
2141 | static void | |
2142 | DEFUN(elf_info_to_howto, (abfd, cache_ptr, dst), | |
2143 | bfd *abfd AND | |
2144 | arelent *cache_ptr AND | |
2145 | Elf_Internal_Rela *dst) | |
2146 | { | |
2147 | /* FIXME!!! just doing sparc for now... */ | |
2148 | #ifdef sparc | |
2149 | BFD_ASSERT (ELF_R_TYPE(dst->r_info) < 24); | |
2150 | ||
2151 | cache_ptr->howto = &elf_howto_table[ELF_R_TYPE(dst->r_info)]; | |
2152 | #else | |
2153 | fprintf (stderr, "elf_info_to_howto not implemented\n"); | |
9ce0058c | 2154 | abort (); |
37ac3b76 ME |
2155 | #endif |
2156 | } | |
2157 | ||
2158 | static boolean | |
2159 | DEFUN(elf_slurp_reloca_table,(abfd, asect, symbols), | |
2160 | bfd *abfd AND | |
2161 | sec_ptr asect AND | |
2162 | asymbol **symbols) | |
2163 | { | |
2164 | Elf_External_Rela *native_relocs; | |
2165 | arelent *reloc_cache; | |
2166 | arelent *cache_ptr; | |
2167 | ||
2168 | unsigned int idx; | |
2169 | ||
2170 | if (asect->relocation) | |
2171 | return true; | |
2172 | if (asect->reloc_count == 0) | |
2173 | return true; | |
2174 | if (asect->flags & SEC_CONSTRUCTOR) | |
2175 | return true; | |
37ac3b76 ME |
2176 | |
2177 | bfd_seek (abfd, asect->rel_filepos, SEEK_SET); | |
2178 | native_relocs = (Elf_External_Rela *) | |
2179 | bfd_alloc(abfd, asect->reloc_count * sizeof(Elf_External_Rela)); | |
37ac3b76 ME |
2180 | bfd_read ((PTR) native_relocs, |
2181 | sizeof(Elf_External_Rela), asect->reloc_count, abfd); | |
2182 | ||
2183 | reloc_cache = (arelent *) | |
2184 | bfd_alloc(abfd, (size_t) (asect->reloc_count * sizeof(arelent))); | |
2185 | ||
2186 | if (! reloc_cache) { | |
2187 | bfd_error = no_memory; | |
2188 | return false; | |
2189 | } | |
2190 | ||
2191 | for (idx = 0; idx < asect->reloc_count; idx ++) | |
2192 | { | |
2193 | #ifdef RELOC_PROCESSING | |
2194 | /* sparc, 68k, 88k, 860 use rela only. */ | |
2195 | /* 386 and we32000 use rel only... fix it for them later. */ | |
2196 | Elf_Internal_Rela dst; | |
2197 | Elf_External_Rela *src; | |
2198 | ||
2199 | cache_ptr = reloc_cache + idx; | |
2200 | src = native_relocs + idx; | |
2201 | elf_swap_reloca_in(abfd, src, &dst); | |
2202 | ||
2203 | RELOC_PROCESSING(cache_ptr, &dst, symbols, abfd, asect); | |
2204 | #else | |
2205 | Elf_Internal_Rela dst; | |
37ac3b76 ME |
2206 | Elf_External_Rela *src; |
2207 | ||
2208 | cache_ptr = reloc_cache + idx; | |
2209 | src = native_relocs + idx; | |
2210 | ||
2211 | elf_swap_reloca_in(abfd, src, &dst); | |
2212 | ||
2213 | if(asect->flags & SEC_RELOC) | |
2214 | { | |
2215 | /* relocatable, so the offset is off of the section */ | |
2216 | cache_ptr->address = dst.r_offset + asect->vma; | |
2217 | } | |
2218 | else | |
2219 | { | |
2220 | /* non-relocatable, so the offset a virtual address */ | |
2221 | cache_ptr->address = dst.r_offset; | |
2222 | } | |
2223 | /* ELF_R_SYM(dst.r_info) is the symbol table offset... */ | |
2224 | cache_ptr->sym_ptr_ptr = symbols + ELF_R_SYM(dst.r_info); | |
2225 | cache_ptr->addend = dst.r_addend; | |
37ac3b76 ME |
2226 | |
2227 | /* Fill in the cache_ptr->howto field from dst.r_type */ | |
2228 | elf_info_to_howto(abfd, cache_ptr, &dst); | |
2229 | #endif | |
2230 | } | |
2231 | ||
2232 | asect->relocation = reloc_cache; | |
2233 | return true; | |
9ce0058c SC |
2234 | } |
2235 | ||
37ac3b76 | 2236 | |
9ce0058c SC |
2237 | static unsigned int |
2238 | elf_canonicalize_reloc (abfd, section, relptr, symbols) | |
2239 | bfd *abfd; | |
2240 | sec_ptr section; | |
2241 | arelent **relptr; | |
2242 | asymbol **symbols; | |
2243 | { | |
37ac3b76 ME |
2244 | arelent *tblptr = section->relocation; |
2245 | unsigned int count = 0; | |
2246 | ||
2247 | /* snarfed from coffcode.h */ | |
2248 | /* FIXME: this could be reloc... */ | |
2249 | elf_slurp_reloca_table(abfd, section, symbols); | |
2250 | ||
2251 | tblptr = section->relocation; | |
2252 | if (!tblptr) | |
2253 | return 0; | |
2254 | ||
2255 | for (; count++ < section->reloc_count;) | |
2256 | *relptr++ = tblptr++; | |
2257 | ||
2258 | *relptr = 0; | |
2259 | return section->reloc_count; | |
9ce0058c SC |
2260 | } |
2261 | ||
2262 | static unsigned int | |
8c4a1ace JG |
2263 | DEFUN (elf_get_symtab, (abfd, alocation), |
2264 | bfd *abfd AND | |
2265 | asymbol **alocation) | |
9ce0058c | 2266 | { |
8c4a1ace | 2267 | |
3dfa6cfb | 2268 | if (!elf_slurp_symbol_table (abfd, alocation)) |
37ac3b76 | 2269 | return (0); |
3dfa6cfb FF |
2270 | else |
2271 | return (bfd_get_symcount (abfd)); | |
9ce0058c SC |
2272 | } |
2273 | ||
2274 | static asymbol * | |
d01cd8fc FF |
2275 | DEFUN (elf_make_empty_symbol, (abfd), |
2276 | bfd *abfd) | |
9ce0058c | 2277 | { |
37ac3b76 | 2278 | elf_symbol_type *newsym; |
d01cd8fc | 2279 | |
37ac3b76 ME |
2280 | newsym = (elf_symbol_type *) bfd_zalloc (abfd, sizeof (elf_symbol_type)); |
2281 | if (! newsym) | |
d01cd8fc FF |
2282 | { |
2283 | bfd_error = no_memory; | |
2284 | return (NULL); | |
2285 | } | |
2286 | else | |
2287 | { | |
37ac3b76 ME |
2288 | newsym -> symbol.the_bfd = abfd; |
2289 | return (&newsym -> symbol); | |
d01cd8fc | 2290 | } |
9ce0058c SC |
2291 | } |
2292 | ||
2293 | static void | |
2294 | DEFUN (elf_print_symbol,(ignore_abfd, filep, symbol, how), | |
2295 | bfd *ignore_abfd AND | |
2296 | PTR filep AND | |
2297 | asymbol *symbol AND | |
e0796d22 | 2298 | bfd_print_symbol_type how) |
9ce0058c | 2299 | { |
37ac3b76 ME |
2300 | FILE *file = (FILE *)filep; |
2301 | switch (how) | |
2302 | { | |
2303 | case bfd_print_symbol_name: | |
2304 | fprintf(file, "%s", symbol->name); | |
2305 | break; | |
2306 | case bfd_print_symbol_more: | |
2307 | fprintf(file, "elf %lx %lx", | |
2308 | symbol->value, | |
2309 | symbol->flags); | |
2310 | break; | |
2311 | case bfd_print_symbol_nm: | |
2312 | case bfd_print_symbol_all: | |
2313 | { | |
ec6b2951 | 2314 | CONST char *section_name; |
37ac3b76 ME |
2315 | section_name = symbol->section? symbol->section->name : "(*none*)"; |
2316 | bfd_print_symbol_vandf((PTR) file, symbol); | |
3dfa6cfb | 2317 | fprintf(file, " %s\t%s", |
37ac3b76 | 2318 | section_name, |
37ac3b76 ME |
2319 | symbol->name); |
2320 | } | |
2321 | break; | |
2322 | } | |
2323 | ||
9ce0058c SC |
2324 | } |
2325 | ||
2326 | static alent * | |
2327 | DEFUN (elf_get_lineno,(ignore_abfd, symbol), | |
2328 | bfd *ignore_abfd AND | |
2329 | asymbol *symbol) | |
2330 | { | |
2331 | fprintf (stderr, "elf_get_lineno unimplemented\n"); | |
2332 | fflush (stderr); | |
2333 | abort (); | |
2334 | return (NULL); | |
2335 | } | |
2336 | ||
2337 | static boolean | |
2338 | DEFUN (elf_set_arch_mach,(abfd, arch, machine), | |
2339 | bfd *abfd AND | |
2340 | enum bfd_architecture arch AND | |
2341 | unsigned long machine) | |
2342 | { | |
9ce0058c | 2343 | /* Allow any architecture to be supported by the elf backend */ |
37ac3b76 ME |
2344 | switch(arch) |
2345 | { | |
2346 | case bfd_arch_unknown: /* EM_NONE */ | |
2347 | case bfd_arch_sparc: /* EM_SPARC */ | |
2348 | case bfd_arch_i386: /* EM_386 */ | |
2349 | case bfd_arch_m68k: /* EM_68K */ | |
2350 | case bfd_arch_m88k: /* EM_88K */ | |
2351 | case bfd_arch_i860: /* EM_860 */ | |
2352 | case bfd_arch_mips: /* EM_MIPS (MIPS R3000) */ | |
2353 | return bfd_default_set_arch_mach(abfd, arch, machine); | |
2354 | default: | |
2355 | return false; | |
2356 | } | |
9ce0058c SC |
2357 | } |
2358 | ||
2359 | static boolean | |
2360 | DEFUN (elf_find_nearest_line,(abfd, | |
2361 | section, | |
2362 | symbols, | |
2363 | offset, | |
2364 | filename_ptr, | |
2365 | functionname_ptr, | |
2366 | line_ptr), | |
2367 | bfd *abfd AND | |
2368 | asection *section AND | |
2369 | asymbol **symbols AND | |
2370 | bfd_vma offset AND | |
2371 | CONST char **filename_ptr AND | |
2372 | CONST char **functionname_ptr AND | |
2373 | unsigned int *line_ptr) | |
2374 | { | |
2375 | fprintf (stderr, "elf_find_nearest_line unimplemented\n"); | |
2376 | fflush (stderr); | |
2377 | abort (); | |
2378 | return (false); | |
2379 | } | |
2380 | ||
2381 | static int | |
2382 | DEFUN (elf_sizeof_headers, (abfd, reloc), | |
2383 | bfd *abfd AND | |
2384 | boolean reloc) | |
2385 | { | |
2386 | fprintf (stderr, "elf_sizeof_headers unimplemented\n"); | |
2387 | fflush (stderr); | |
2388 | abort (); | |
2389 | return (0); | |
2390 | } | |
37ac3b76 ME |
2391 | |
2392 | boolean | |
2393 | DEFUN(elf_set_section_contents, (abfd, section, location, offset, count), | |
2394 | bfd *abfd AND | |
2395 | sec_ptr section AND | |
2396 | PTR location AND | |
2397 | file_ptr offset AND | |
2398 | bfd_size_type count) | |
2399 | { | |
2400 | int dest_sect; | |
2401 | void *contents; | |
2402 | if (abfd->output_has_begun == false) /* set by bfd.c handler? */ | |
2403 | { | |
2404 | /* do setup calculations (FIXME) */ | |
2405 | elf_compute_section_file_positions(abfd); | |
2406 | } | |
2407 | #if 0 | |
2408 | if(bfd_seek (abfd, (file_ptr)section->filepos + offset, SEEK_SET) == -1) | |
2409 | return false; | |
2410 | if(bfd_write (location, (bfd_size_type)1, count, abfd) != count) | |
2411 | return false; | |
2412 | #endif | |
2413 | /* we really just need to save the contents away... */ | |
2414 | dest_sect = elf_section_from_bfd_section(abfd, section); | |
2415 | if(!dest_sect) | |
2416 | return false; | |
2417 | ||
2418 | /* FIXME: allocate in set_section_size, then copy in here... */ | |
2419 | contents = (void*)bfd_alloc(abfd, count); | |
2420 | BFD_ASSERT(contents); | |
2421 | memcpy(contents, location, count); | |
2422 | elf_elfsections (abfd)[dest_sect].contents = contents; | |
2423 | ||
2424 | return true; | |
2425 | } | |
2426 | ||
e0796d22 | 2427 | \f |
9ce0058c SC |
2428 | /* This structure contains everything that BFD knows about a target. |
2429 | It includes things like its byte order, name, what routines to call | |
2430 | to do various operations, etc. Every BFD points to a target structure | |
2431 | with its "xvec" member. | |
2432 | ||
2433 | There are two such structures here: one for big-endian machines and | |
2434 | one for little-endian machines. */ | |
2435 | ||
e0796d22 FF |
2436 | /* Archives are generic or unimplemented. */ |
2437 | #define elf_slurp_armap bfd_false | |
2438 | #define elf_slurp_extended_name_table _bfd_slurp_extended_name_table | |
2439 | #define elf_truncate_arname bfd_dont_truncate_arname | |
2440 | #define elf_openr_next_archived_file bfd_generic_openr_next_archived_file | |
2441 | #define elf_generic_stat_arch_elt bfd_generic_stat_arch_elt | |
2442 | #define elf_write_armap (PROTO (boolean, (*), \ | |
a6c1d731 | 2443 | (bfd *arch, unsigned int elength, struct orl *map, unsigned int orl_count, \ |
e0796d22 FF |
2444 | int stridx))) bfd_false |
2445 | ||
2446 | /* Ordinary section reading and writing */ | |
2447 | #define elf_new_section_hook _bfd_dummy_new_section_hook | |
37ac3b76 ME |
2448 | #define elf_get_section_contents bfd_generic_get_section_contents |
2449 | /* #define elf_set_section_contents bfd_generic_set_section_contents */ | |
e0796d22 FF |
2450 | #define elf_close_and_cleanup bfd_generic_close_and_cleanup |
2451 | ||
2452 | #define elf_bfd_debug_info_start bfd_void | |
2453 | #define elf_bfd_debug_info_end bfd_void | |
2454 | #define elf_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void | |
e98e6ec1 SC |
2455 | #define elf_bfd_get_relocated_section_contents \ |
2456 | bfd_generic_get_relocated_section_contents | |
d01cd8fc | 2457 | #define elf_bfd_relax_section bfd_generic_relax_section |
9ce0058c SC |
2458 | bfd_target elf_big_vec = |
2459 | { | |
2460 | /* name: identify kind of target */ | |
2461 | "elf-big", | |
2462 | ||
2463 | /* flavour: general indication about file */ | |
e0796d22 | 2464 | bfd_target_elf_flavour, |
9ce0058c SC |
2465 | |
2466 | /* byteorder_big_p: data is big endian */ | |
2467 | true, | |
2468 | ||
2469 | /* header_byteorder_big_p: header is also big endian */ | |
2470 | true, | |
2471 | ||
2472 | /* object_flags: mask of all file flags */ | |
2473 | (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS | | |
2474 | DYNAMIC | WP_TEXT), | |
2475 | ||
2476 | /* section_flags: mask of all section flags */ | |
2477 | (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | | |
37ac3b76 | 2478 | SEC_CODE | SEC_DATA), |
9ce0058c | 2479 | |
294eaca4 SC |
2480 | |
2481 | /* leading_symbol_char: is the first char of a user symbol | |
2482 | predictable, and if so what is it */ | |
2483 | 0, | |
2484 | ||
9ce0058c SC |
2485 | /* ar_pad_char: pad character for filenames within an archive header |
2486 | FIXME: this really has nothing to do with ELF, this is a characteristic | |
2487 | of the archiver and/or os and should be independently tunable */ | |
2488 | '/', | |
2489 | ||
2490 | /* ar_max_namelen: maximum number of characters in an archive header | |
2491 | FIXME: this really has nothing to do with ELF, this is a characteristic | |
2492 | of the archiver and should be independently tunable. This value is | |
2493 | a WAG (wild a** guess) */ | |
2494 | 15, | |
2495 | ||
2496 | /* align_power_min: minimum alignment restriction for any section | |
2497 | FIXME: this value may be target machine dependent */ | |
2498 | 3, | |
2499 | ||
2500 | /* Routines to byte-swap various sized integers from the data sections */ | |
2501 | _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, | |
2502 | ||
2503 | /* Routines to byte-swap various sized integers from the file headers */ | |
2504 | _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, | |
2505 | ||
2506 | /* bfd_check_format: check the format of a file being read */ | |
e0796d22 FF |
2507 | { _bfd_dummy_target, /* unknown format */ |
2508 | elf_object_p, /* assembler/linker output (object file) */ | |
2509 | bfd_generic_archive_p, /* an archive */ | |
2510 | elf_core_file_p /* a core file */ | |
9ce0058c SC |
2511 | }, |
2512 | ||
2513 | /* bfd_set_format: set the format of a file being written */ | |
2514 | { bfd_false, | |
2515 | elf_mkobject, | |
2516 | _bfd_generic_mkarchive, | |
2517 | bfd_false | |
2518 | }, | |
2519 | ||
2520 | /* bfd_write_contents: write cached information into a file being written */ | |
2521 | { bfd_false, | |
2522 | elf_write_object_contents, | |
2523 | _bfd_write_archive_contents, | |
2524 | bfd_false | |
2525 | }, | |
2526 | ||
2527 | /* Initialize a jump table with the standard macro. All names start | |
2528 | with "elf" */ | |
2529 | JUMP_TABLE(elf), | |
2530 | ||
2531 | /* SWAP_TABLE */ | |
2532 | NULL, NULL, NULL | |
2533 | }; | |
2534 | ||
2535 | bfd_target elf_little_vec = | |
2536 | { | |
2537 | /* name: identify kind of target */ | |
2538 | "elf-little", | |
2539 | ||
2540 | /* flavour: general indication about file */ | |
e0796d22 | 2541 | bfd_target_elf_flavour, |
9ce0058c SC |
2542 | |
2543 | /* byteorder_big_p: data is big endian */ | |
2544 | false, /* Nope -- this one's little endian */ | |
2545 | ||
2546 | /* header_byteorder_big_p: header is also big endian */ | |
2547 | false, /* Nope -- this one's little endian */ | |
2548 | ||
2549 | /* object_flags: mask of all file flags */ | |
2550 | (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS | | |
2551 | DYNAMIC | WP_TEXT), | |
2552 | ||
2553 | /* section_flags: mask of all section flags */ | |
2554 | (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | | |
2555 | SEC_DATA), | |
2556 | ||
294eaca4 SC |
2557 | /* leading_symbol_char: is the first char of a user symbol |
2558 | predictable, and if so what is it */ | |
2559 | 0, | |
2560 | ||
9ce0058c SC |
2561 | /* ar_pad_char: pad character for filenames within an archive header |
2562 | FIXME: this really has nothing to do with ELF, this is a characteristic | |
2563 | of the archiver and/or os and should be independently tunable */ | |
2564 | '/', | |
2565 | ||
2566 | /* ar_max_namelen: maximum number of characters in an archive header | |
2567 | FIXME: this really has nothing to do with ELF, this is a characteristic | |
2568 | of the archiver and should be independently tunable. This value is | |
2569 | a WAG (wild a** guess) */ | |
2570 | 15, | |
2571 | ||
2572 | /* align_power_min: minimum alignment restriction for any section | |
2573 | FIXME: this value may be target machine dependent */ | |
2574 | 3, | |
2575 | ||
2576 | /* Routines to byte-swap various sized integers from the data sections */ | |
2577 | _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, | |
2578 | ||
2579 | /* Routines to byte-swap various sized integers from the file headers */ | |
2580 | _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, | |
2581 | ||
2582 | /* bfd_check_format: check the format of a file being read */ | |
e0796d22 FF |
2583 | { _bfd_dummy_target, /* unknown format */ |
2584 | elf_object_p, /* assembler/linker output (object file) */ | |
2585 | bfd_generic_archive_p, /* an archive */ | |
2586 | elf_core_file_p /* a core file */ | |
9ce0058c SC |
2587 | }, |
2588 | ||
2589 | /* bfd_set_format: set the format of a file being written */ | |
2590 | { bfd_false, | |
2591 | elf_mkobject, | |
2592 | _bfd_generic_mkarchive, | |
2593 | bfd_false | |
2594 | }, | |
2595 | ||
2596 | /* bfd_write_contents: write cached information into a file being written */ | |
2597 | { bfd_false, | |
2598 | elf_write_object_contents, | |
2599 | _bfd_write_archive_contents, | |
2600 | bfd_false | |
2601 | }, | |
2602 | ||
2603 | /* Initialize a jump table with the standard macro. All names start | |
2604 | with "elf" */ | |
2605 | JUMP_TABLE(elf), | |
2606 | ||
2607 | /* SWAP_TABLE */ | |
2608 | NULL, NULL, NULL | |
2609 | }; |