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