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