Commit | Line | Data |
---|---|---|
37ac3b76 | 1 | /* ELF executable support for BFD. |
0dc1bc8b | 2 | Copyright 1991, 1992, 1993 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 | ||
0dc1bc8b ILT |
579 | ss = (struct strtab *) bfd_xmalloc(sizeof(struct strtab)); |
580 | ss->tab = bfd_xmalloc(1); | |
37ac3b76 ME |
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 | |
0dc1bc8b | 625 | ss->tab = bfd_xmalloc(ln); |
37ac3b76 ME |
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; | |
37ac3b76 | 1463 | Elf_External_Rela *outbound_relocs; |
37ac3b76 | 1464 | int rela_section; |
37ac3b76 ME |
1465 | |
1466 | symtab_hdr = &thunk->i_shdrp[thunk->symtab_section]; | |
1467 | ||
1468 | if (thunk->symtab_section == this_section + 1) | |
1469 | rela_section = thunk->symtab_section + 2; /* symtab + symstrtab */ | |
1470 | else | |
1471 | rela_section = this_section + 1; | |
1472 | rela_hdr = &thunk->i_shdrp[rela_section]; | |
1473 | rela_hdr->sh_type = SHT_RELA; | |
1474 | rela_hdr->sh_link = thunk->symtab_section; | |
1475 | rela_hdr->sh_info = this_section; | |
1476 | rela_hdr->sh_entsize = sizeof (Elf_External_Rela); | |
1477 | /* orelocation has the data, reloc_count has the count... */ | |
1478 | rela_hdr->sh_size = rela_hdr->sh_entsize * asect->reloc_count; | |
37ac3b76 ME |
1479 | outbound_relocs = (Elf_External_Rela *) |
1480 | bfd_alloc(abfd, asect->reloc_count * sizeof(Elf_External_Rela)); | |
1481 | for (idx = 0; idx < asect->reloc_count; idx++) | |
1482 | { | |
1483 | Elf_Internal_Rela dst; | |
1484 | arelent *ptr; | |
1485 | Elf_External_Rela *src; | |
1486 | ||
1487 | ptr = asect->orelocation[idx]; | |
1488 | src = outbound_relocs + idx; | |
1489 | if (asect->flags & SEC_RELOC) | |
1490 | dst.r_offset = ptr->address - asect->vma; | |
1491 | else | |
1492 | dst.r_offset = ptr->address; | |
1493 | ||
1494 | dst.r_info = ELF_R_INFO(1 /*ptr->sym_ptr_ptr*/, /* needs index into symtab (FIXME) */ | |
1495 | ptr->howto->type); | |
1496 | ||
1497 | dst.r_addend = ptr->addend; | |
1498 | elf_swap_reloca_out(abfd, &dst, src); | |
1499 | } | |
1500 | rela_hdr->contents = (void*)outbound_relocs; | |
1501 | } | |
1502 | } | |
1503 | } | |
1504 | ||
1505 | static void | |
1506 | DEFUN (elf_fake_sections, (abfd, asect, obj), | |
1507 | bfd *abfd AND | |
1508 | asection *asect AND | |
1509 | PTR obj) | |
1510 | { | |
1511 | elf_sect_thunk *thunk = (elf_sect_thunk*)obj; | |
1512 | /* most of what is in bfd_shdr_from_section goes in here... */ | |
1513 | /* and all of these sections generate at *least* one ELF section. */ | |
1514 | int this_section; | |
37ac3b76 ME |
1515 | |
1516 | /* check if we're making a PROGBITS section... */ | |
1517 | /* if ((asect->flags & SEC_ALLOC) && (asect->flags & SEC_LOAD)) */ | |
1518 | /* this was too strict... what *do* we want to check here? */ | |
1519 | if(1) | |
1520 | { | |
1521 | Elf_Internal_Shdr *this_hdr; | |
1522 | this_section = thunk->i_ehdr->e_shnum++; | |
1523 | this_hdr = &thunk->i_shdrp[this_section]; | |
1524 | this_hdr->sh_name = | |
1525 | bfd_add_to_strtab (abfd, thunk->shstrtab, asect->name); | |
1526 | /* we need to log the type *now* so that elf_section_from_bfd_section | |
1527 | can find us... have to set rawdata too. */ | |
1528 | this_hdr->rawdata = (void*)asect; | |
1529 | if ((asect->flags & SEC_ALLOC) && (asect->flags & SEC_LOAD)) | |
1530 | this_hdr->sh_type = SHT_PROGBITS; | |
1531 | else | |
1532 | /* what *do* we put here? */ | |
1533 | this_hdr->sh_type = SHT_PROGBITS; | |
1534 | ||
1535 | ||
1536 | if (asect->flags & SEC_RELOC) | |
1537 | { | |
1538 | /* emit a reloc section, and thus strtab and symtab... */ | |
1539 | Elf_Internal_Shdr *rela_hdr; | |
1540 | Elf_Internal_Shdr *symtab_hdr; | |
1541 | Elf_Internal_Shdr *symstrtab_hdr; | |
37ac3b76 ME |
1542 | int rela_section; |
1543 | int symstrtab_section; | |
1544 | ||
1545 | /* note that only one symtab is used, so just remember it | |
1546 | for now */ | |
1547 | if (! thunk->symtab_section) | |
1548 | { | |
1549 | thunk->symtab_section = thunk->i_ehdr->e_shnum++; | |
1550 | symtab_hdr = &thunk->i_shdrp[thunk->symtab_section]; | |
1551 | symtab_hdr->sh_name = | |
1552 | bfd_add_to_strtab (abfd, thunk->shstrtab, ".symtab"); | |
1553 | symtab_hdr->sh_type = SHT_SYMTAB; | |
1554 | symtab_hdr->sh_entsize = sizeof (Elf_External_Sym); | |
1555 | ||
1556 | symstrtab_section = thunk->i_ehdr->e_shnum++; | |
1557 | BFD_ASSERT(symstrtab_section == thunk->symtab_section+1); | |
1558 | symstrtab_hdr = &thunk->i_shdrp[symstrtab_section]; | |
1559 | symtab_hdr->sh_link = symstrtab_section; | |
1560 | symstrtab_hdr->sh_name = | |
1561 | bfd_add_to_strtab (abfd, thunk->shstrtab, ".strtab"); | |
1562 | symstrtab_hdr->sh_type = SHT_STRTAB; | |
1563 | ||
1564 | symtab_hdr->contents = 0; | |
1565 | symstrtab_hdr->contents = 0; | |
1566 | symstrtab_hdr->sh_size = 0; | |
1567 | } | |
1568 | else | |
1569 | symtab_hdr = &thunk->i_shdrp[thunk->symtab_section]; | |
1570 | ||
1571 | rela_section = thunk->i_ehdr->e_shnum++; | |
1572 | rela_hdr = &thunk->i_shdrp[rela_section]; | |
1573 | rela_hdr->sh_name = | |
1574 | bfd_add_2_to_strtab (abfd, thunk->shstrtab, ".rela", asect->name); | |
1575 | rela_hdr->sh_type = SHT_RELA; | |
1576 | rela_hdr->sh_link = thunk->symtab_section; | |
1577 | rela_hdr->sh_info = this_section; | |
1578 | rela_hdr->sh_entsize = sizeof (Elf_External_Rela); | |
1579 | } | |
1580 | } | |
1581 | } | |
1582 | ||
1583 | ||
1584 | static boolean | |
1585 | DEFUN (elf_compute_section_file_positions, (abfd), bfd *abfd) | |
1586 | { | |
1587 | Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ | |
1588 | Elf_Internal_Shdr *i_shdrp; /* Section header table, internal form */ | |
1589 | struct strtab *shstrtab; | |
1590 | int count, maxsections; | |
37ac3b76 ME |
1591 | elf_sect_thunk est; |
1592 | ||
1593 | if (! elf_shstrtab (abfd)) { | |
80bdcb77 JG |
1594 | i_ehdrp = elf_elfheader (abfd); /* build new header in tdata memory */ |
1595 | shstrtab = bfd_new_strtab(abfd); | |
37ac3b76 | 1596 | |
80bdcb77 JG |
1597 | i_ehdrp->e_ident[EI_MAG0] = ELFMAG0; |
1598 | i_ehdrp->e_ident[EI_MAG1] = ELFMAG1; | |
1599 | i_ehdrp->e_ident[EI_MAG2] = ELFMAG2; | |
1600 | i_ehdrp->e_ident[EI_MAG3] = ELFMAG3; | |
1601 | ||
1602 | i_ehdrp->e_ident[EI_CLASS] = ELFCLASS32; /* FIXME: find out from bfd */ | |
1603 | i_ehdrp->e_ident[EI_DATA] = | |
1604 | abfd->xvec->byteorder_big_p ? ELFDATA2MSB : ELFDATA2LSB; | |
1605 | i_ehdrp->e_ident[EI_VERSION] = EV_CURRENT; | |
1606 | ||
1607 | for(count = EI_PAD; count < EI_NIDENT; count ++) | |
1608 | i_ehdrp->e_ident[count] = 0; | |
1609 | ||
1610 | i_ehdrp->e_type = (abfd->flags & EXEC_P)? ET_EXEC : ET_REL; | |
1611 | switch(bfd_get_arch(abfd)) | |
1612 | { | |
1613 | case bfd_arch_unknown: | |
1614 | i_ehdrp->e_machine = EM_NONE; | |
1615 | break; | |
1616 | case bfd_arch_sparc: | |
1617 | i_ehdrp->e_machine = EM_SPARC; | |
1618 | break; | |
1619 | case bfd_arch_i386: | |
1620 | i_ehdrp->e_machine = EM_386; | |
1621 | break; | |
1622 | case bfd_arch_m68k: | |
1623 | i_ehdrp->e_machine = EM_68K; | |
1624 | break; | |
1625 | case bfd_arch_m88k: | |
1626 | i_ehdrp->e_machine = EM_88K; | |
1627 | break; | |
1628 | case bfd_arch_i860: | |
1629 | i_ehdrp->e_machine = EM_860; | |
1630 | break; | |
1631 | case bfd_arch_mips: /* MIPS Rxxxx */ | |
1632 | i_ehdrp->e_machine = EM_MIPS; /* only MIPS R3000 */ | |
1633 | break; | |
1634 | /* also note that EM_M32, AT&T WE32100 is unknown to bfd */ | |
1635 | default: | |
1636 | i_ehdrp->e_machine = EM_NONE; | |
1637 | } | |
1638 | i_ehdrp->e_version = EV_CURRENT; | |
1639 | i_ehdrp->e_ehsize = sizeof(Elf_External_Ehdr); | |
1640 | ||
1641 | /* no program header, for now. */ | |
1642 | i_ehdrp->e_phoff = 0; | |
1643 | i_ehdrp->e_phentsize = 0; | |
1644 | i_ehdrp->e_phnum = 0; | |
37ac3b76 | 1645 | |
80bdcb77 JG |
1646 | /* each bfd section is section header entry */ |
1647 | i_ehdrp->e_entry = bfd_get_start_address (abfd); | |
1648 | i_ehdrp->e_shentsize = sizeof (Elf_External_Shdr); | |
37ac3b76 | 1649 | |
80bdcb77 JG |
1650 | /* figure at most each section can have a rel, strtab, symtab */ |
1651 | maxsections = 4*bfd_count_sections(abfd)+2; | |
37ac3b76 | 1652 | |
80bdcb77 | 1653 | i_ehdrp->e_shoff = i_ehdrp->e_ehsize; |
37ac3b76 | 1654 | |
80bdcb77 JG |
1655 | /* and we'll just have to fix up the offsets later. */ |
1656 | /* outbase += i_ehdr.e_shentsize * i_ehdr.e_shnum; */ | |
1657 | ||
1658 | i_shdrp = (Elf_Internal_Shdr *) | |
1659 | bfd_alloc (abfd, sizeof (*i_shdrp) * maxsections); | |
1660 | if (! i_shdrp) | |
1661 | { | |
1662 | bfd_error = no_memory; | |
1663 | return (false); | |
1664 | } | |
1665 | for (count=0; count < maxsections; count++) | |
1666 | { | |
1667 | i_shdrp[count].rawdata = 0; | |
1668 | i_shdrp[count].contents = 0; | |
1669 | } | |
1670 | ||
1671 | ||
1672 | i_shdrp[0].sh_name = 0; | |
1673 | i_shdrp[0].sh_type = SHT_NULL; | |
1674 | i_shdrp[0].sh_flags = 0; | |
1675 | i_shdrp[0].sh_addr = 0; | |
1676 | i_shdrp[0].sh_offset = 0; | |
1677 | i_shdrp[0].sh_size = 0; | |
1678 | i_shdrp[0].sh_link = SHN_UNDEF; | |
1679 | i_shdrp[0].sh_info = 0; | |
1680 | i_shdrp[0].sh_addralign = 0; | |
1681 | i_shdrp[0].sh_entsize = 0; | |
1682 | ||
1683 | i_ehdrp->e_shnum = 1; | |
1684 | ||
1685 | elf_elfsections (abfd) = i_shdrp; | |
1686 | elf_shstrtab (abfd) = shstrtab; | |
37ac3b76 ME |
1687 | } |
1688 | est.i_ehdr = elf_elfheader(abfd); | |
1689 | est.i_shdrp = elf_elfsections(abfd); | |
1690 | est.shstrtab = elf_shstrtab(abfd); | |
1691 | est.symtab_section = 0; /* elf_fake_sections fils it in */ | |
1692 | ||
1693 | bfd_map_over_sections(abfd, elf_fake_sections, &est); | |
1694 | elf_onesymtab (abfd) = est.symtab_section; | |
808dfd5a | 1695 | return (true); |
9ce0058c SC |
1696 | } |
1697 | ||
1698 | static boolean | |
1699 | DEFUN (elf_write_object_contents, (abfd), bfd *abfd) | |
1700 | { | |
37ac3b76 ME |
1701 | Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ |
1702 | Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ | |
37ac3b76 ME |
1703 | Elf_External_Shdr *x_shdrp; /* Section header table, external form */ |
1704 | Elf_Internal_Shdr *i_shdrp; /* Section header table, internal form */ | |
1705 | asection *nsect; | |
37ac3b76 ME |
1706 | elf_sect_thunk est; |
1707 | ||
1708 | int outbase = 0; | |
1709 | int count; | |
1710 | struct strtab *shstrtab; | |
1711 | ||
1712 | if(abfd->output_has_begun == false) | |
1713 | elf_compute_section_file_positions(abfd); | |
1714 | ||
1715 | i_ehdrp = elf_elfheader (abfd); | |
1716 | i_shdrp = elf_elfsections (abfd); | |
1717 | shstrtab = elf_shstrtab (abfd); | |
1718 | ||
1719 | est.i_ehdr = i_ehdrp; | |
1720 | est.i_shdrp = i_shdrp; | |
1721 | est.shstrtab = shstrtab; | |
1722 | est.symtab_section = elf_onesymtab (abfd); /* filled in by elf_fake */ | |
1723 | ||
1724 | bfd_map_over_sections(abfd, elf_make_sections, &est); | |
1725 | ||
1726 | /* dump out the one symtab */ | |
1727 | { | |
1728 | int symcount = bfd_get_symcount (abfd); | |
1729 | asymbol ** syms = bfd_get_outsymbols (abfd); | |
1730 | struct strtab * stt = bfd_new_strtab (abfd); | |
1731 | Elf_Internal_Shdr *symtab_hdr; | |
1732 | Elf_Internal_Shdr *symstrtab_hdr; | |
1733 | int symstrtab_section; | |
1734 | Elf_External_Sym *outbound_syms; | |
1735 | int idx; | |
1736 | ||
1737 | symtab_hdr = &i_shdrp[est.symtab_section]; | |
1738 | symtab_hdr->sh_type = SHT_SYMTAB; | |
1739 | symtab_hdr->sh_entsize = sizeof (Elf_External_Sym); | |
1740 | symtab_hdr->sh_size = symtab_hdr->sh_entsize * symcount; | |
1741 | ||
1742 | /* see assert in elf_fake_sections that supports this: */ | |
1743 | symstrtab_section = est.symtab_section+1; | |
1744 | symstrtab_hdr = &i_shdrp[symstrtab_section]; | |
1745 | symtab_hdr->sh_link = symstrtab_section; | |
1746 | symstrtab_hdr->sh_type = SHT_STRTAB; | |
1747 | ||
37ac3b76 ME |
1748 | outbound_syms = (Elf_External_Sym*) |
1749 | bfd_alloc(abfd, (1+symcount) * sizeof(Elf_External_Sym)); | |
1750 | /* now generate the data (for "contents") */ | |
1751 | for (idx = 0; idx < symcount; idx++) | |
1752 | { | |
1753 | Elf_Internal_Sym sym; | |
1754 | sym.st_name = bfd_add_to_strtab (abfd, stt, syms[idx]->name); | |
1755 | sym.st_value = syms[idx]->value; | |
1756 | sym.st_size = 0; /* we should recover this (FIXME) */ | |
1757 | if (syms[idx]->flags & BSF_WEAK) | |
1758 | sym.st_info = ELF_ST_INFO(STB_WEAK, STT_OBJECT); | |
1759 | else if (syms[idx]->flags & BSF_LOCAL) | |
1760 | sym.st_info = ELF_ST_INFO(STB_LOCAL, STT_OBJECT); | |
1761 | else if (syms[idx]->flags & BSF_GLOBAL) | |
1762 | sym.st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT); | |
3dfa6cfb FF |
1763 | else if (syms[idx]->flags & BSF_SECTION_SYM) |
1764 | sym.st_info = ELF_ST_INFO(STB_LOCAL, STT_SECTION); | |
1765 | else if (syms[idx]->flags & BSF_FILE) | |
1766 | sym.st_info = ELF_ST_INFO(STB_LOCAL, STT_FILE); | |
37ac3b76 ME |
1767 | |
1768 | sym.st_other = 0; | |
1769 | if (syms[idx]->section) | |
1770 | sym.st_shndx = | |
1771 | elf_section_from_bfd_section(abfd, | |
1772 | syms[idx]->section->output_section); | |
1773 | else | |
1774 | sym.st_shndx = SHN_UNDEF; | |
1775 | ||
1776 | elf_swap_symbol_out (abfd, &sym, outbound_syms+idx+1); | |
1777 | } | |
1778 | { | |
1779 | /* fill in 0th symbol */ | |
1780 | Elf_Internal_Sym sym; | |
1781 | sym.st_name = 0; | |
1782 | sym.st_value = 0; | |
1783 | sym.st_size = 0; | |
1784 | sym.st_info = 0; | |
1785 | sym.st_other = 0; | |
1786 | sym.st_shndx = SHN_UNDEF; | |
1787 | elf_swap_symbol_out (abfd, &sym, outbound_syms); | |
1788 | } | |
1789 | symtab_hdr->contents = (void*)outbound_syms; | |
1790 | symstrtab_hdr->contents = (void*)stt->tab; | |
1791 | symstrtab_hdr->sh_size = stt->length; | |
1792 | } | |
1793 | ||
1794 | /* put the strtab out too... */ | |
1795 | { | |
1796 | Elf_Internal_Shdr *this_hdr; | |
1797 | int this_section; | |
1798 | ||
1799 | this_section = i_ehdrp->e_shnum++; | |
1800 | i_ehdrp->e_shstrndx = this_section; | |
1801 | this_hdr = &i_shdrp[this_section]; | |
1802 | this_hdr->sh_name = bfd_add_to_strtab (abfd, shstrtab, ".shstrtab"); | |
1803 | this_hdr->sh_size = shstrtab->length; | |
1804 | this_hdr->contents = (void*)shstrtab->tab; | |
1805 | } | |
1806 | ||
1807 | outbase = i_ehdrp->e_ehsize; | |
1808 | ||
1809 | /* swap the header before spitting it out... */ | |
1810 | elf_swap_ehdr_out (abfd, i_ehdrp, &x_ehdr); | |
f8e01940 | 1811 | bfd_seek (abfd, (file_ptr) 0, SEEK_SET); |
37ac3b76 ME |
1812 | bfd_write ((PTR) &x_ehdr, sizeof(x_ehdr), 1, abfd); |
1813 | ||
1814 | outbase += i_ehdrp->e_shentsize * i_ehdrp->e_shnum; | |
1815 | ||
1816 | /* now we fix up the offsets... */ | |
1817 | for (count = 0; count < i_ehdrp->e_shnum; count ++) | |
1818 | { | |
1819 | i_shdrp[count].sh_offset = outbase; | |
1820 | outbase += i_shdrp[count].sh_size; | |
1821 | } | |
1822 | ||
1823 | /* at this point we've concocted all the ELF sections... */ | |
1824 | x_shdrp = (Elf_External_Shdr *) | |
1825 | bfd_alloc (abfd, sizeof (*x_shdrp) * (i_ehdrp->e_shnum)); | |
1826 | if (! x_shdrp) | |
1827 | { | |
1828 | bfd_error = no_memory; | |
808dfd5a | 1829 | return (false); |
37ac3b76 ME |
1830 | } |
1831 | ||
37ac3b76 ME |
1832 | for (count = 0; count < i_ehdrp->e_shnum; count ++) |
1833 | { | |
1834 | elf_swap_shdr_out (abfd, i_shdrp+count, x_shdrp+count); | |
1835 | } | |
1836 | bfd_write ((PTR) x_shdrp, sizeof(*x_shdrp), i_ehdrp->e_shnum, abfd); | |
1837 | /* need to dump the string table too... */ | |
1838 | ||
1839 | /* after writing the headers, we need to write the sections too... */ | |
1840 | nsect = abfd->sections; | |
1841 | for (count = 0; count < i_ehdrp->e_shnum; count ++) | |
1842 | { | |
1843 | if(i_shdrp[count].contents) | |
1844 | { | |
37ac3b76 ME |
1845 | bfd_seek (abfd, i_shdrp[count].sh_offset, SEEK_SET); |
1846 | bfd_write (i_shdrp[count].contents, i_shdrp[count].sh_size, 1, abfd); | |
1847 | } | |
1848 | } | |
1849 | ||
1850 | /* sample use of bfd: | |
f8e01940 | 1851 | * bfd_seek (abfd, (file_ptr) 0, SEEK_SET); |
37ac3b76 ME |
1852 | * bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd); |
1853 | * if (bfd_seek(abfd, scn_base, SEEK_SET) != 0) | |
1854 | * return false; | |
1855 | * old = bfd_tell(abfd); | |
1856 | */ | |
1857 | ||
1858 | return true; | |
1859 | ||
9ce0058c SC |
1860 | } |
1861 | ||
8c4a1ace JG |
1862 | /* Given an index of a section, retrieve a pointer to it. Note |
1863 | that for our purposes, sections are indexed by {1, 2, ...} with | |
1864 | 0 being an illegal index. */ | |
1865 | ||
37ac3b76 ME |
1866 | /* In the original, each ELF section went into exactly one BFD |
1867 | section. This doesn't really make sense, so we need a real mapping. | |
1868 | The mapping has to hide in the Elf_Internal_Shdr since asection | |
1869 | doesn't have anything like a tdata field... */ | |
1870 | ||
8c4a1ace | 1871 | static struct sec * |
37ac3b76 | 1872 | DEFUN (section_from_elf_index, (abfd, index), |
8c4a1ace JG |
1873 | bfd *abfd AND |
1874 | int index) | |
1875 | { | |
37ac3b76 ME |
1876 | Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd); |
1877 | Elf_Internal_Shdr *hdr = i_shdrp + index; | |
1878 | ||
1879 | switch (hdr->sh_type) | |
8c4a1ace | 1880 | { |
37ac3b76 ME |
1881 | /* ELF sections that map to BFD sections */ |
1882 | case SHT_PROGBITS: | |
1883 | case SHT_NOBITS: | |
1884 | if (! hdr->rawdata) | |
1885 | bfd_section_from_shdr (abfd, index); | |
1886 | return (struct sec *)hdr->rawdata; | |
1887 | break; | |
1888 | default: | |
13ff1343 | 1889 | return (struct sec *)&bfd_abs_section; |
8c4a1ace | 1890 | } |
37ac3b76 ME |
1891 | } |
1892 | ||
1893 | /* given a section, search the header to find them... */ | |
1894 | static int | |
1895 | DEFUN (elf_section_from_bfd_section, (abfd, asect), | |
1896 | bfd *abfd AND | |
1897 | struct sec *asect) | |
1898 | { | |
1899 | Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd); | |
1900 | int index; | |
1901 | Elf_Internal_Shdr *hdr; | |
1902 | int maxindex = elf_elfheader (abfd)->e_shnum; | |
1903 | ||
1904 | for(index = 0; index < maxindex; index++) { | |
1905 | hdr = &i_shdrp[index]; | |
1906 | switch (hdr->sh_type) | |
1907 | { | |
1908 | /* ELF sections that map to BFD sections */ | |
1909 | case SHT_PROGBITS: | |
1910 | case SHT_NOBITS: | |
1911 | if (hdr->rawdata) | |
1912 | { | |
1913 | if (((struct sec *)(hdr->rawdata)) == asect) | |
1914 | return index; | |
1915 | } | |
1916 | break; | |
1917 | default: | |
1918 | break; | |
1919 | } | |
1920 | } | |
1921 | return 0; | |
8c4a1ace JG |
1922 | } |
1923 | ||
1924 | static boolean | |
3dfa6cfb | 1925 | DEFUN (elf_slurp_symbol_table, (abfd, symptrs), |
37ac3b76 | 1926 | bfd *abfd AND |
3dfa6cfb | 1927 | asymbol **symptrs) /* Buffer for generated bfd symbols */ |
8c4a1ace | 1928 | { |
3dfa6cfb FF |
1929 | Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd); |
1930 | Elf_Internal_Shdr *hdr = i_shdrp + elf_onesymtab (abfd); | |
8c4a1ace | 1931 | int symcount; /* Number of external ELF symbols */ |
3dfa6cfb | 1932 | int i; |
8c4a1ace JG |
1933 | asymbol *sym; /* Pointer to current bfd symbol */ |
1934 | asymbol *symbase; /* Buffer for generated bfd symbols */ | |
8c4a1ace | 1935 | Elf_Internal_Sym i_sym; |
37ac3b76 | 1936 | Elf_External_Sym *x_symp; |
8c4a1ace | 1937 | |
37ac3b76 | 1938 | /* this is only valid because there is only one symtab... */ |
91f781ff FF |
1939 | /* FIXME: This is incorrect, there may also be a dynamic symbol |
1940 | table which is a subset of the full symbol table. We either need | |
1941 | to be prepared to read both (and merge them) or ensure that we | |
1942 | only read the full symbol table. Currently we only get called to | |
1943 | read the full symbol table. -fnf */ | |
8c4a1ace JG |
1944 | if (bfd_get_outsymbols (abfd) != NULL) |
1945 | { | |
1946 | return (true); | |
1947 | } | |
1948 | ||
8c4a1ace JG |
1949 | /* Read each raw ELF symbol, converting from external ELF form to |
1950 | internal ELF form, and then using the information to create a | |
1951 | canonical bfd symbol table entry. | |
1952 | ||
37ac3b76 | 1953 | Note that we allocate the initial bfd canonical symbol buffer |
8c4a1ace | 1954 | based on a one-to-one mapping of the ELF symbols to canonical |
3dfa6cfb FF |
1955 | symbols. We actually use all the ELF symbols, so there will be no |
1956 | space left over at the end. When we have all the symbols, we | |
1957 | build the caller's pointer vector. */ | |
8c4a1ace | 1958 | |
37ac3b76 | 1959 | if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1) |
8c4a1ace JG |
1960 | { |
1961 | bfd_error = system_call_error; | |
1962 | return (false); | |
1963 | } | |
1964 | ||
37ac3b76 | 1965 | symcount = hdr->sh_size / sizeof (Elf_External_Sym); |
3dfa6cfb FF |
1966 | symbase = (asymbol *) bfd_zalloc (abfd, symcount * sizeof (asymbol)); |
1967 | sym = symbase; | |
1968 | ||
1969 | /* Temporarily allocate room for the raw ELF symbols. */ | |
0dc1bc8b | 1970 | x_symp = (Elf_External_Sym *) bfd_xmalloc (symcount * sizeof (Elf_External_Sym)); |
8c4a1ace | 1971 | |
37ac3b76 ME |
1972 | if (bfd_read ((PTR) x_symp, sizeof (Elf_External_Sym), symcount, abfd) |
1973 | != symcount * sizeof (Elf_External_Sym)) | |
1974 | { | |
3dfa6cfb | 1975 | free ((PTR)x_symp); |
37ac3b76 ME |
1976 | bfd_error = system_call_error; |
1977 | return (false); | |
1978 | } | |
3dfa6cfb FF |
1979 | /* Skip first symbol, which is a null dummy. */ |
1980 | for (i = 1; i < symcount; i++) | |
8c4a1ace | 1981 | { |
3dfa6cfb FF |
1982 | elf_swap_symbol_in (abfd, x_symp + i, &i_sym); |
1983 | sym -> the_bfd = abfd; | |
37ac3b76 | 1984 | if (i_sym.st_name > 0) |
3dfa6cfb FF |
1985 | sym -> name = elf_string_from_elf_section(abfd, hdr->sh_link, |
1986 | i_sym.st_name); | |
1987 | else | |
1988 | sym -> name = "unnamed"; /* perhaps should include the number? */ | |
1989 | sym -> value = i_sym.st_value; | |
80bdcb77 | 1990 | /* FIXME -- this is almost certainly bogus. It's from Pace Willisson's |
3dfa6cfb FF |
1991 | hasty Solaris support, to pass the sizes of object files or functions |
1992 | down into GDB via the back door, to circumvent some other kludge in | |
1993 | how Sun hacked stabs. -- gnu@cygnus.com */ | |
1994 | sym -> udata = (PTR)i_sym.st_size; | |
80bdcb77 | 1995 | /* FIXME -- end of bogosity. */ |
3dfa6cfb FF |
1996 | if (i_sym.st_shndx > 0 && i_sym.st_shndx < SHN_LORESERV) |
1997 | { | |
1998 | sym -> section = section_from_elf_index (abfd, i_sym.st_shndx); | |
8c4a1ace | 1999 | } |
3dfa6cfb | 2000 | else if (i_sym.st_shndx == SHN_ABS) |
8c4a1ace | 2001 | { |
3dfa6cfb FF |
2002 | sym -> section = &bfd_abs_section; |
2003 | } | |
2004 | else if (i_sym.st_shndx == SHN_COMMON) | |
2005 | { | |
2006 | sym -> section = &bfd_com_section; | |
2007 | } | |
2008 | else if (i_sym.st_shndx == SHN_UNDEF) | |
2009 | { | |
2010 | sym -> section = &bfd_und_section; | |
2011 | } | |
13ff1343 BK |
2012 | else |
2013 | sym -> section = &bfd_abs_section; | |
3dfa6cfb FF |
2014 | |
2015 | switch (ELF_ST_BIND (i_sym.st_info)) | |
2016 | { | |
2017 | case STB_LOCAL: | |
2018 | sym -> flags |= BSF_LOCAL; | |
2019 | break; | |
2020 | case STB_GLOBAL: | |
2021 | sym -> flags |= (BSF_GLOBAL | BSF_EXPORT); | |
2022 | break; | |
2023 | case STB_WEAK: | |
2024 | sym -> flags |= BSF_WEAK; | |
2025 | break; | |
2026 | } | |
37ac3b76 | 2027 | |
3dfa6cfb FF |
2028 | switch (ELF_ST_TYPE (i_sym.st_info)) |
2029 | { | |
2030 | case STT_SECTION: | |
2031 | sym->flags |= BSF_SECTION_SYM | BSF_DEBUGGING; | |
2032 | break; | |
2033 | case STT_FILE: | |
2034 | sym->flags |= BSF_FILE | BSF_DEBUGGING; | |
2035 | break; | |
8c4a1ace | 2036 | } |
3dfa6cfb | 2037 | sym++; |
8c4a1ace JG |
2038 | } |
2039 | ||
3dfa6cfb FF |
2040 | /* We rely on the zalloc to clear out the final symbol entry. */ |
2041 | ||
2042 | /* We're now done with the raw symbols. */ | |
2043 | free ((PTR)x_symp); | |
8c4a1ace | 2044 | |
3dfa6cfb FF |
2045 | bfd_get_symcount(abfd) = symcount = sym - symbase; |
2046 | ||
2047 | /* Fill in the user's symbol pointer vector if needed. */ | |
2048 | if (symptrs) | |
8c4a1ace | 2049 | { |
3dfa6cfb FF |
2050 | sym = symbase; |
2051 | while (symcount-- > 0) | |
2052 | { | |
2053 | *symptrs++ = sym++; | |
2054 | } | |
2055 | *symptrs = 0; /* Final null pointer */ | |
8c4a1ace JG |
2056 | } |
2057 | ||
2058 | return (true); | |
2059 | } | |
2060 | ||
2061 | /* Return the number of bytes required to hold the symtab vector. | |
2062 | ||
2063 | Note that we base it on the count plus 1, since we will null terminate | |
3dfa6cfb FF |
2064 | the vector allocated based on this size. However, the ELF symbol table |
2065 | always has a dummy entry as symbol #0, so it ends up even. */ | |
8c4a1ace | 2066 | |
9ce0058c | 2067 | static unsigned int |
8c4a1ace | 2068 | DEFUN (elf_get_symtab_upper_bound, (abfd), bfd *abfd) |
9ce0058c | 2069 | { |
3dfa6cfb | 2070 | unsigned int symcount; |
e555d764 FF |
2071 | unsigned int symtab_size = 0; |
2072 | Elf_Internal_Shdr *i_shdrp; | |
2073 | Elf_Internal_Shdr *hdr; | |
8c4a1ace | 2074 | |
e555d764 FF |
2075 | i_shdrp = elf_elfsections (abfd); |
2076 | if (i_shdrp != NULL) | |
2077 | { | |
2078 | hdr = i_shdrp + elf_onesymtab (abfd); | |
2079 | symcount = hdr->sh_size / sizeof (Elf_External_Sym); | |
2080 | symtab_size = (symcount - 1 + 1) * (sizeof (asymbol)); | |
2081 | } | |
8c4a1ace | 2082 | return (symtab_size); |
9ce0058c SC |
2083 | } |
2084 | ||
37ac3b76 ME |
2085 | /* |
2086 | This function return the number of bytes required to store the | |
2087 | relocation information associated with section <<sect>> | |
2088 | attached to bfd <<abfd>> | |
2089 | ||
2090 | */ | |
9ce0058c SC |
2091 | static unsigned int |
2092 | elf_get_reloc_upper_bound (abfd, asect) | |
2093 | bfd *abfd; | |
2094 | sec_ptr asect; | |
2095 | { | |
37ac3b76 ME |
2096 | if (asect->flags & SEC_RELOC) |
2097 | { | |
2098 | /* either rel or rela */ | |
2099 | return asect->_raw_size; | |
2100 | } | |
2101 | else | |
2102 | return (0); | |
2103 | } | |
2104 | ||
37ac3b76 ME |
2105 | enum reloc_type |
2106 | { | |
0dc1bc8b | 2107 | R_SPARC_offset = 0, |
37ac3b76 ME |
2108 | R_SPARC_NONE = 0, |
2109 | R_SPARC_8, R_SPARC_16, R_SPARC_32, | |
2110 | R_SPARC_DISP8, R_SPARC_DISP16, R_SPARC_DISP32, | |
2111 | R_SPARC_WDISP30, R_SPARC_WDISP22, | |
2112 | R_SPARC_HI22, R_SPARC_22, | |
2113 | R_SPARC_13, R_SPARC_LO10, | |
2114 | R_SPARC_GOT10, R_SPARC_GOT13, R_SPARC_GOT22, | |
2115 | R_SPARC_PC10, R_SPARC_PC22, | |
2116 | R_SPARC_WPLT30, | |
2117 | R_SPARC_COPY, | |
2118 | R_SPARC_GLOB_DAT, R_SPARC_JMP_SLOT, | |
2119 | R_SPARC_RELATIVE, | |
2120 | R_SPARC_UA32, | |
0dc1bc8b ILT |
2121 | R_SPARC_max, |
2122 | ||
2123 | R_386_offset = R_SPARC_max, | |
2124 | R_386_NONE = 0, | |
2125 | R_386_32, R_386_PC32, | |
2126 | R_386_GOT32, R_386_PLT32, | |
2127 | R_386_COPY, | |
2128 | R_386_GLOB_DAT, R_386_JUMP_SLOT, | |
2129 | R_386_RELATIVE, | |
2130 | R_386_GOTOFF, R_386_GOTPC, | |
2131 | R_386_max, | |
37ac3b76 ME |
2132 | }; |
2133 | ||
0dc1bc8b | 2134 | #if 0 /* not used */ |
37ac3b76 ME |
2135 | #define RELOC_TYPE_NAMES \ |
2136 | "R_SPARC_NONE", \ | |
2137 | "R_SPARC_8", "R_SPARC_16", "R_SPARC_32", \ | |
2138 | "R_SPARC_DISP8", "R_SPARC_DISP16", "R_SPARC_DISP32", \ | |
2139 | "R_SPARC_WDISP30", "R_SPARC_WDISP22", \ | |
2140 | "R_SPARC_HI22", "R_SPARC_22", \ | |
2141 | "R_SPARC_13", "R_SPARC_LO10", \ | |
2142 | "R_SPARC_GOT10", "R_SPARC_GOT13", "R_SPARC_GOT22", \ | |
2143 | "R_SPARC_PC10", "R_SPARC_PC22", \ | |
2144 | "R_SPARC_WPLT30", \ | |
2145 | "R_SPARC_COPY", \ | |
2146 | "R_SPARC_GLOB_DAT", "R_SPARC_JMP_SLOT", \ | |
2147 | "R_SPARC_RELATIVE", \ | |
0dc1bc8b ILT |
2148 | "R_SPARC_UA32", \ |
2149 | "R_386_NONE", \ | |
2150 | "R_386_32", "R_386_PC32", \ | |
2151 | "R_386_GOT32", "R_386_PLT32", \ | |
2152 | "R_386_COPY", \ | |
2153 | "R_386_GLOB_DAT", "R_386_JUMP_SLOT", \ | |
2154 | "R_386_RELATIVE", \ | |
2155 | "R_386_GOTOFF", "R_386_GOTPC" | |
2156 | #endif | |
37ac3b76 | 2157 | |
0dc1bc8b | 2158 | static reloc_howto_type elf_sparc_howto_table[] = |
37ac3b76 ME |
2159 | { |
2160 | HOWTO(R_SPARC_NONE, 0,0, 0,false,0,false,false, 0,"R_SPARC_NONE", false,0,0x00000000,false), | |
2161 | HOWTO(R_SPARC_8, 0,0, 8,false,0,true, true, 0,"R_SPARC_8", false,0,0x000000ff,false), | |
2162 | HOWTO(R_SPARC_16, 0,1,16,false,0,true, true, 0,"R_SPARC_16", false,0,0x0000ffff,false), | |
2163 | HOWTO(R_SPARC_32, 0,2,32,false,0,true, true, 0,"R_SPARC_32", false,0,0xffffffff,false), | |
2164 | HOWTO(R_SPARC_DISP8, 0,0, 8,true, 0,false, true, 0,"R_SPARC_DISP8", false,0,0x000000ff,false), | |
2165 | HOWTO(R_SPARC_DISP16, 0,1,16,true, 0,false, true, 0,"R_SPARC_DISP16", false,0,0x0000ffff,false), | |
2166 | HOWTO(R_SPARC_DISP32, 0,2,32,true, 0,false, true, 0,"R_SPARC_DISP32", false,0,0x00ffffff,false), | |
2167 | HOWTO(R_SPARC_WDISP30,2,2,30,true, 0,false, true, 0,"R_SPARC_WDISP30",false,0,0x3fffffff,false), | |
2168 | HOWTO(R_SPARC_WDISP22,2,2,22,true, 0,false, true, 0,"R_SPARC_WDISP22",false,0,0x003fffff,false), | |
2169 | HOWTO(R_SPARC_HI22, 10,2,22,false,0,true, false, 0,"R_SPARC_HI22", false,0,0x003fffff,false), | |
2170 | HOWTO(R_SPARC_22, 0,2,22,false,0,true, true, 0,"R_SPARC_22", false,0,0x003fffff,false), | |
2171 | HOWTO(R_SPARC_13, 0,1,13,false,0,true, true, 0,"R_SPARC_13", false,0,0x00001fff,false), | |
2172 | HOWTO(R_SPARC_LO10, 0,1,10,false,0,true, false, 0,"R_SPARC_LO10", false,0,0x000003ff,false), | |
2173 | HOWTO(R_SPARC_GOT10, 0,1,10,false,0,false, true, 0,"R_SPARC_GOT10", false,0,0x000003ff,false), | |
2174 | HOWTO(R_SPARC_GOT13, 0,1,13,false,0,false, true, 0,"R_SPARC_GOT13", false,0,0x00001fff,false), | |
2175 | HOWTO(R_SPARC_GOT22, 10,2,22,false,0,false, true, 0,"R_SPARC_GOT22", false,0,0x003fffff,false), | |
2176 | HOWTO(R_SPARC_PC10, 0,1,10,false,0,true, true, 0,"R_SPARC_PC10", false,0,0x000003ff,false), | |
2177 | HOWTO(R_SPARC_PC22, 0,2,22,false,0,true, true, 0,"R_SPARC_PC22", false,0,0x003fffff,false), | |
2178 | HOWTO(R_SPARC_WPLT30, 0,0,00,false,0,false,false, 0,"R_SPARC_WPLT30", false,0,0x00000000,false), | |
2179 | HOWTO(R_SPARC_COPY, 0,0,00,false,0,false,false, 0,"R_SPARC_COPY", false,0,0x00000000,false), | |
2180 | HOWTO(R_SPARC_GLOB_DAT,0,0,00,false,0,false,false,0,"R_SPARC_GLOB_DAT",false,0,0x00000000,false), | |
2181 | HOWTO(R_SPARC_JMP_SLOT,0,0,00,false,0,false,false,0,"R_SPARC_JMP_SLOT",false,0,0x00000000,false), | |
2182 | HOWTO(R_SPARC_RELATIVE,0,0,00,false,0,false,false,0,"R_SPARC_RELATIVE",false,0,0x00000000,false), | |
2183 | HOWTO(R_SPARC_UA32, 0,0,00,false,0,false,false,0,"R_SPARC_UA32", false,0,0x00000000,false), | |
2184 | }; | |
0dc1bc8b ILT |
2185 | |
2186 | #if 0 | |
2187 | static const reloc_howto_type elf_386_howto_table[] = | |
2188 | { | |
2189 | HOWTO (R_386_NONE, 0, 0, 0, false, 0, | |
37ac3b76 ME |
2190 | #endif |
2191 | ||
2192 | static void | |
2193 | DEFUN(elf_info_to_howto, (abfd, cache_ptr, dst), | |
2194 | bfd *abfd AND | |
2195 | arelent *cache_ptr AND | |
2196 | Elf_Internal_Rela *dst) | |
2197 | { | |
2198 | /* FIXME!!! just doing sparc for now... */ | |
0dc1bc8b ILT |
2199 | switch (abfd->arch_info->arch) |
2200 | { | |
2201 | case bfd_arch_sparc: | |
8feff717 | 2202 | BFD_ASSERT (ELF_R_TYPE(dst->r_info) < (unsigned char) R_SPARC_max); |
0dc1bc8b ILT |
2203 | cache_ptr->howto = &elf_sparc_howto_table[ELF_R_TYPE(dst->r_info)]; |
2204 | break; | |
37ac3b76 | 2205 | |
0dc1bc8b ILT |
2206 | #if 0 |
2207 | case bfd_arch_i386: | |
2208 | BFD_ASSER (ELF_R_TYPE (dst->r_info) < R_386_max); | |
2209 | cache_ptr->howto = &elf_i386_howto_table[ELF_R_TYPE (dst->r_info)]; | |
2210 | break; | |
37ac3b76 | 2211 | #endif |
0dc1bc8b ILT |
2212 | |
2213 | default: | |
2214 | fprintf (stderr, "elf_info_to_howto not implemented\n"); | |
2215 | abort (); | |
2216 | } | |
37ac3b76 | 2217 | } |
0dc1bc8b | 2218 | |
37ac3b76 ME |
2219 | static boolean |
2220 | DEFUN(elf_slurp_reloca_table,(abfd, asect, symbols), | |
2221 | bfd *abfd AND | |
2222 | sec_ptr asect AND | |
2223 | asymbol **symbols) | |
2224 | { | |
2225 | Elf_External_Rela *native_relocs; | |
2226 | arelent *reloc_cache; | |
2227 | arelent *cache_ptr; | |
2228 | ||
2229 | unsigned int idx; | |
2230 | ||
2231 | if (asect->relocation) | |
2232 | return true; | |
2233 | if (asect->reloc_count == 0) | |
2234 | return true; | |
2235 | if (asect->flags & SEC_CONSTRUCTOR) | |
2236 | return true; | |
37ac3b76 ME |
2237 | |
2238 | bfd_seek (abfd, asect->rel_filepos, SEEK_SET); | |
2239 | native_relocs = (Elf_External_Rela *) | |
2240 | bfd_alloc(abfd, asect->reloc_count * sizeof(Elf_External_Rela)); | |
37ac3b76 ME |
2241 | bfd_read ((PTR) native_relocs, |
2242 | sizeof(Elf_External_Rela), asect->reloc_count, abfd); | |
2243 | ||
2244 | reloc_cache = (arelent *) | |
2245 | bfd_alloc(abfd, (size_t) (asect->reloc_count * sizeof(arelent))); | |
2246 | ||
2247 | if (! reloc_cache) { | |
2248 | bfd_error = no_memory; | |
2249 | return false; | |
2250 | } | |
2251 | ||
2252 | for (idx = 0; idx < asect->reloc_count; idx ++) | |
2253 | { | |
2254 | #ifdef RELOC_PROCESSING | |
2255 | /* sparc, 68k, 88k, 860 use rela only. */ | |
2256 | /* 386 and we32000 use rel only... fix it for them later. */ | |
2257 | Elf_Internal_Rela dst; | |
2258 | Elf_External_Rela *src; | |
2259 | ||
2260 | cache_ptr = reloc_cache + idx; | |
2261 | src = native_relocs + idx; | |
2262 | elf_swap_reloca_in(abfd, src, &dst); | |
2263 | ||
2264 | RELOC_PROCESSING(cache_ptr, &dst, symbols, abfd, asect); | |
2265 | #else | |
2266 | Elf_Internal_Rela dst; | |
37ac3b76 ME |
2267 | Elf_External_Rela *src; |
2268 | ||
2269 | cache_ptr = reloc_cache + idx; | |
2270 | src = native_relocs + idx; | |
2271 | ||
2272 | elf_swap_reloca_in(abfd, src, &dst); | |
2273 | ||
2274 | if(asect->flags & SEC_RELOC) | |
2275 | { | |
2276 | /* relocatable, so the offset is off of the section */ | |
2277 | cache_ptr->address = dst.r_offset + asect->vma; | |
2278 | } | |
2279 | else | |
2280 | { | |
2281 | /* non-relocatable, so the offset a virtual address */ | |
2282 | cache_ptr->address = dst.r_offset; | |
2283 | } | |
2284 | /* ELF_R_SYM(dst.r_info) is the symbol table offset... */ | |
2285 | cache_ptr->sym_ptr_ptr = symbols + ELF_R_SYM(dst.r_info); | |
2286 | cache_ptr->addend = dst.r_addend; | |
37ac3b76 ME |
2287 | |
2288 | /* Fill in the cache_ptr->howto field from dst.r_type */ | |
2289 | elf_info_to_howto(abfd, cache_ptr, &dst); | |
2290 | #endif | |
2291 | } | |
2292 | ||
2293 | asect->relocation = reloc_cache; | |
2294 | return true; | |
9ce0058c SC |
2295 | } |
2296 | ||
37ac3b76 | 2297 | |
9ce0058c SC |
2298 | static unsigned int |
2299 | elf_canonicalize_reloc (abfd, section, relptr, symbols) | |
2300 | bfd *abfd; | |
2301 | sec_ptr section; | |
2302 | arelent **relptr; | |
2303 | asymbol **symbols; | |
2304 | { | |
37ac3b76 ME |
2305 | arelent *tblptr = section->relocation; |
2306 | unsigned int count = 0; | |
2307 | ||
2308 | /* snarfed from coffcode.h */ | |
2309 | /* FIXME: this could be reloc... */ | |
2310 | elf_slurp_reloca_table(abfd, section, symbols); | |
2311 | ||
2312 | tblptr = section->relocation; | |
2313 | if (!tblptr) | |
2314 | return 0; | |
2315 | ||
2316 | for (; count++ < section->reloc_count;) | |
2317 | *relptr++ = tblptr++; | |
2318 | ||
2319 | *relptr = 0; | |
2320 | return section->reloc_count; | |
9ce0058c SC |
2321 | } |
2322 | ||
2323 | static unsigned int | |
8c4a1ace JG |
2324 | DEFUN (elf_get_symtab, (abfd, alocation), |
2325 | bfd *abfd AND | |
2326 | asymbol **alocation) | |
9ce0058c | 2327 | { |
8c4a1ace | 2328 | |
3dfa6cfb | 2329 | if (!elf_slurp_symbol_table (abfd, alocation)) |
37ac3b76 | 2330 | return (0); |
3dfa6cfb FF |
2331 | else |
2332 | return (bfd_get_symcount (abfd)); | |
9ce0058c SC |
2333 | } |
2334 | ||
2335 | static asymbol * | |
d01cd8fc FF |
2336 | DEFUN (elf_make_empty_symbol, (abfd), |
2337 | bfd *abfd) | |
9ce0058c | 2338 | { |
37ac3b76 | 2339 | elf_symbol_type *newsym; |
d01cd8fc | 2340 | |
37ac3b76 ME |
2341 | newsym = (elf_symbol_type *) bfd_zalloc (abfd, sizeof (elf_symbol_type)); |
2342 | if (! newsym) | |
d01cd8fc FF |
2343 | { |
2344 | bfd_error = no_memory; | |
2345 | return (NULL); | |
2346 | } | |
2347 | else | |
2348 | { | |
37ac3b76 ME |
2349 | newsym -> symbol.the_bfd = abfd; |
2350 | return (&newsym -> symbol); | |
d01cd8fc | 2351 | } |
9ce0058c SC |
2352 | } |
2353 | ||
2354 | static void | |
2355 | DEFUN (elf_print_symbol,(ignore_abfd, filep, symbol, how), | |
2356 | bfd *ignore_abfd AND | |
2357 | PTR filep AND | |
2358 | asymbol *symbol AND | |
e0796d22 | 2359 | bfd_print_symbol_type how) |
9ce0058c | 2360 | { |
37ac3b76 ME |
2361 | FILE *file = (FILE *)filep; |
2362 | switch (how) | |
2363 | { | |
2364 | case bfd_print_symbol_name: | |
2365 | fprintf(file, "%s", symbol->name); | |
2366 | break; | |
2367 | case bfd_print_symbol_more: | |
2368 | fprintf(file, "elf %lx %lx", | |
2369 | symbol->value, | |
2370 | symbol->flags); | |
2371 | break; | |
2372 | case bfd_print_symbol_nm: | |
2373 | case bfd_print_symbol_all: | |
2374 | { | |
ec6b2951 | 2375 | CONST char *section_name; |
37ac3b76 ME |
2376 | section_name = symbol->section? symbol->section->name : "(*none*)"; |
2377 | bfd_print_symbol_vandf((PTR) file, symbol); | |
3dfa6cfb | 2378 | fprintf(file, " %s\t%s", |
37ac3b76 | 2379 | section_name, |
37ac3b76 ME |
2380 | symbol->name); |
2381 | } | |
2382 | break; | |
2383 | } | |
2384 | ||
9ce0058c SC |
2385 | } |
2386 | ||
2387 | static alent * | |
2388 | DEFUN (elf_get_lineno,(ignore_abfd, symbol), | |
2389 | bfd *ignore_abfd AND | |
2390 | asymbol *symbol) | |
2391 | { | |
2392 | fprintf (stderr, "elf_get_lineno unimplemented\n"); | |
2393 | fflush (stderr); | |
2394 | abort (); | |
2395 | return (NULL); | |
2396 | } | |
2397 | ||
2398 | static boolean | |
2399 | DEFUN (elf_set_arch_mach,(abfd, arch, machine), | |
2400 | bfd *abfd AND | |
2401 | enum bfd_architecture arch AND | |
2402 | unsigned long machine) | |
2403 | { | |
9ce0058c | 2404 | /* Allow any architecture to be supported by the elf backend */ |
37ac3b76 ME |
2405 | switch(arch) |
2406 | { | |
2407 | case bfd_arch_unknown: /* EM_NONE */ | |
2408 | case bfd_arch_sparc: /* EM_SPARC */ | |
2409 | case bfd_arch_i386: /* EM_386 */ | |
2410 | case bfd_arch_m68k: /* EM_68K */ | |
2411 | case bfd_arch_m88k: /* EM_88K */ | |
2412 | case bfd_arch_i860: /* EM_860 */ | |
2413 | case bfd_arch_mips: /* EM_MIPS (MIPS R3000) */ | |
2414 | return bfd_default_set_arch_mach(abfd, arch, machine); | |
2415 | default: | |
2416 | return false; | |
2417 | } | |
9ce0058c SC |
2418 | } |
2419 | ||
2420 | static boolean | |
2421 | DEFUN (elf_find_nearest_line,(abfd, | |
2422 | section, | |
2423 | symbols, | |
2424 | offset, | |
2425 | filename_ptr, | |
2426 | functionname_ptr, | |
2427 | line_ptr), | |
2428 | bfd *abfd AND | |
2429 | asection *section AND | |
2430 | asymbol **symbols AND | |
2431 | bfd_vma offset AND | |
2432 | CONST char **filename_ptr AND | |
2433 | CONST char **functionname_ptr AND | |
2434 | unsigned int *line_ptr) | |
2435 | { | |
2436 | fprintf (stderr, "elf_find_nearest_line unimplemented\n"); | |
2437 | fflush (stderr); | |
2438 | abort (); | |
2439 | return (false); | |
2440 | } | |
2441 | ||
2442 | static int | |
2443 | DEFUN (elf_sizeof_headers, (abfd, reloc), | |
2444 | bfd *abfd AND | |
2445 | boolean reloc) | |
2446 | { | |
2447 | fprintf (stderr, "elf_sizeof_headers unimplemented\n"); | |
2448 | fflush (stderr); | |
2449 | abort (); | |
2450 | return (0); | |
2451 | } | |
37ac3b76 ME |
2452 | |
2453 | boolean | |
2454 | DEFUN(elf_set_section_contents, (abfd, section, location, offset, count), | |
2455 | bfd *abfd AND | |
2456 | sec_ptr section AND | |
2457 | PTR location AND | |
2458 | file_ptr offset AND | |
2459 | bfd_size_type count) | |
2460 | { | |
2461 | int dest_sect; | |
2462 | void *contents; | |
2463 | if (abfd->output_has_begun == false) /* set by bfd.c handler? */ | |
2464 | { | |
2465 | /* do setup calculations (FIXME) */ | |
2466 | elf_compute_section_file_positions(abfd); | |
2467 | } | |
2468 | #if 0 | |
2469 | if(bfd_seek (abfd, (file_ptr)section->filepos + offset, SEEK_SET) == -1) | |
2470 | return false; | |
2471 | if(bfd_write (location, (bfd_size_type)1, count, abfd) != count) | |
2472 | return false; | |
2473 | #endif | |
2474 | /* we really just need to save the contents away... */ | |
2475 | dest_sect = elf_section_from_bfd_section(abfd, section); | |
2476 | if(!dest_sect) | |
2477 | return false; | |
2478 | ||
2479 | /* FIXME: allocate in set_section_size, then copy in here... */ | |
2480 | contents = (void*)bfd_alloc(abfd, count); | |
2481 | BFD_ASSERT(contents); | |
2482 | memcpy(contents, location, count); | |
2483 | elf_elfsections (abfd)[dest_sect].contents = contents; | |
2484 | ||
2485 | return true; | |
2486 | } | |
2487 | ||
e0796d22 | 2488 | \f |
9ce0058c SC |
2489 | /* This structure contains everything that BFD knows about a target. |
2490 | It includes things like its byte order, name, what routines to call | |
2491 | to do various operations, etc. Every BFD points to a target structure | |
2492 | with its "xvec" member. | |
2493 | ||
2494 | There are two such structures here: one for big-endian machines and | |
2495 | one for little-endian machines. */ | |
2496 | ||
e0796d22 | 2497 | /* Archives are generic or unimplemented. */ |
287c221d | 2498 | #define elf_slurp_armap bfd_slurp_coff_armap |
e0796d22 FF |
2499 | #define elf_slurp_extended_name_table _bfd_slurp_extended_name_table |
2500 | #define elf_truncate_arname bfd_dont_truncate_arname | |
2501 | #define elf_openr_next_archived_file bfd_generic_openr_next_archived_file | |
2502 | #define elf_generic_stat_arch_elt bfd_generic_stat_arch_elt | |
287c221d | 2503 | #define elf_write_armap coff_write_armap |
e0796d22 FF |
2504 | |
2505 | /* Ordinary section reading and writing */ | |
2506 | #define elf_new_section_hook _bfd_dummy_new_section_hook | |
37ac3b76 ME |
2507 | #define elf_get_section_contents bfd_generic_get_section_contents |
2508 | /* #define elf_set_section_contents bfd_generic_set_section_contents */ | |
e0796d22 FF |
2509 | #define elf_close_and_cleanup bfd_generic_close_and_cleanup |
2510 | ||
2511 | #define elf_bfd_debug_info_start bfd_void | |
2512 | #define elf_bfd_debug_info_end bfd_void | |
2513 | #define elf_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void | |
e98e6ec1 SC |
2514 | #define elf_bfd_get_relocated_section_contents \ |
2515 | bfd_generic_get_relocated_section_contents | |
d01cd8fc | 2516 | #define elf_bfd_relax_section bfd_generic_relax_section |
0dc1bc8b | 2517 | #define elf_bfd_seclet_link bfd_generic_seclet_link |
8feff717 ILT |
2518 | #define elf_bfd_reloc_type_lookup \ |
2519 | ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr) | |
2520 | #define elf_bfd_make_debug_symbol \ | |
2521 | ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr) | |
0dc1bc8b | 2522 | |
9ce0058c SC |
2523 | bfd_target elf_big_vec = |
2524 | { | |
2525 | /* name: identify kind of target */ | |
2526 | "elf-big", | |
2527 | ||
2528 | /* flavour: general indication about file */ | |
e0796d22 | 2529 | bfd_target_elf_flavour, |
9ce0058c SC |
2530 | |
2531 | /* byteorder_big_p: data is big endian */ | |
2532 | true, | |
2533 | ||
2534 | /* header_byteorder_big_p: header is also big endian */ | |
2535 | true, | |
2536 | ||
2537 | /* object_flags: mask of all file flags */ | |
2538 | (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS | | |
2539 | DYNAMIC | WP_TEXT), | |
2540 | ||
2541 | /* section_flags: mask of all section flags */ | |
2542 | (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | | |
37ac3b76 | 2543 | SEC_CODE | SEC_DATA), |
9ce0058c | 2544 | |
294eaca4 SC |
2545 | /* leading_symbol_char: is the first char of a user symbol |
2546 | predictable, and if so what is it */ | |
2547 | 0, | |
2548 | ||
9ce0058c SC |
2549 | /* ar_pad_char: pad character for filenames within an archive header |
2550 | FIXME: this really has nothing to do with ELF, this is a characteristic | |
2551 | of the archiver and/or os and should be independently tunable */ | |
2552 | '/', | |
2553 | ||
2554 | /* ar_max_namelen: maximum number of characters in an archive header | |
2555 | FIXME: this really has nothing to do with ELF, this is a characteristic | |
2556 | of the archiver and should be independently tunable. This value is | |
2557 | a WAG (wild a** guess) */ | |
2558 | 15, | |
2559 | ||
2560 | /* align_power_min: minimum alignment restriction for any section | |
2561 | FIXME: this value may be target machine dependent */ | |
2562 | 3, | |
2563 | ||
2564 | /* Routines to byte-swap various sized integers from the data sections */ | |
2565 | _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, | |
2566 | ||
2567 | /* Routines to byte-swap various sized integers from the file headers */ | |
2568 | _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, | |
2569 | ||
2570 | /* bfd_check_format: check the format of a file being read */ | |
e0796d22 FF |
2571 | { _bfd_dummy_target, /* unknown format */ |
2572 | elf_object_p, /* assembler/linker output (object file) */ | |
2573 | bfd_generic_archive_p, /* an archive */ | |
2574 | elf_core_file_p /* a core file */ | |
9ce0058c SC |
2575 | }, |
2576 | ||
2577 | /* bfd_set_format: set the format of a file being written */ | |
2578 | { bfd_false, | |
2579 | elf_mkobject, | |
2580 | _bfd_generic_mkarchive, | |
2581 | bfd_false | |
2582 | }, | |
2583 | ||
2584 | /* bfd_write_contents: write cached information into a file being written */ | |
2585 | { bfd_false, | |
2586 | elf_write_object_contents, | |
2587 | _bfd_write_archive_contents, | |
2588 | bfd_false | |
2589 | }, | |
2590 | ||
e555d764 FF |
2591 | /* Initialize a jump table with the standard macro. All names start with |
2592 | "elf" */ | |
9ce0058c SC |
2593 | JUMP_TABLE(elf), |
2594 | ||
e555d764 FF |
2595 | /* backend_data: */ |
2596 | NULL | |
9ce0058c SC |
2597 | }; |
2598 | ||
2599 | bfd_target elf_little_vec = | |
2600 | { | |
2601 | /* name: identify kind of target */ | |
2602 | "elf-little", | |
2603 | ||
2604 | /* flavour: general indication about file */ | |
e0796d22 | 2605 | bfd_target_elf_flavour, |
9ce0058c SC |
2606 | |
2607 | /* byteorder_big_p: data is big endian */ | |
2608 | false, /* Nope -- this one's little endian */ | |
2609 | ||
2610 | /* header_byteorder_big_p: header is also big endian */ | |
2611 | false, /* Nope -- this one's little endian */ | |
2612 | ||
2613 | /* object_flags: mask of all file flags */ | |
2614 | (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS | | |
2615 | DYNAMIC | WP_TEXT), | |
2616 | ||
2617 | /* section_flags: mask of all section flags */ | |
2618 | (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | | |
2619 | SEC_DATA), | |
2620 | ||
294eaca4 SC |
2621 | /* leading_symbol_char: is the first char of a user symbol |
2622 | predictable, and if so what is it */ | |
2623 | 0, | |
2624 | ||
9ce0058c SC |
2625 | /* ar_pad_char: pad character for filenames within an archive header |
2626 | FIXME: this really has nothing to do with ELF, this is a characteristic | |
2627 | of the archiver and/or os and should be independently tunable */ | |
2628 | '/', | |
2629 | ||
2630 | /* ar_max_namelen: maximum number of characters in an archive header | |
2631 | FIXME: this really has nothing to do with ELF, this is a characteristic | |
2632 | of the archiver and should be independently tunable. This value is | |
2633 | a WAG (wild a** guess) */ | |
2634 | 15, | |
2635 | ||
2636 | /* align_power_min: minimum alignment restriction for any section | |
2637 | FIXME: this value may be target machine dependent */ | |
2638 | 3, | |
2639 | ||
2640 | /* Routines to byte-swap various sized integers from the data sections */ | |
2641 | _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, | |
2642 | ||
2643 | /* Routines to byte-swap various sized integers from the file headers */ | |
2644 | _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, | |
2645 | ||
2646 | /* bfd_check_format: check the format of a file being read */ | |
e0796d22 FF |
2647 | { _bfd_dummy_target, /* unknown format */ |
2648 | elf_object_p, /* assembler/linker output (object file) */ | |
2649 | bfd_generic_archive_p, /* an archive */ | |
2650 | elf_core_file_p /* a core file */ | |
9ce0058c SC |
2651 | }, |
2652 | ||
2653 | /* bfd_set_format: set the format of a file being written */ | |
2654 | { bfd_false, | |
2655 | elf_mkobject, | |
2656 | _bfd_generic_mkarchive, | |
2657 | bfd_false | |
2658 | }, | |
2659 | ||
2660 | /* bfd_write_contents: write cached information into a file being written */ | |
2661 | { bfd_false, | |
2662 | elf_write_object_contents, | |
2663 | _bfd_write_archive_contents, | |
2664 | bfd_false | |
2665 | }, | |
2666 | ||
e555d764 FF |
2667 | /* Initialize a jump table with the standard macro. All names start with |
2668 | "elf" */ | |
9ce0058c SC |
2669 | JUMP_TABLE(elf), |
2670 | ||
e555d764 FF |
2671 | /* backend_data: */ |
2672 | NULL | |
9ce0058c | 2673 | }; |