Commit | Line | Data |
---|---|---|
9ce0058c SC |
1 | /* ELF support for BFD. |
2 | Copyright (C) 1991 Free Software Foundation, Inc. | |
3 | ||
4 | Written by Fred Fish @ Cygnus Support, from information published | |
5 | in "UNIX System V Release 4, Programmers Guide: ANSI C and | |
6 | Programming Support Tools". | |
7 | ||
8 | This file is part of BFD, the Binary File Descriptor library. | |
9 | ||
10 | This program is free software; you can redistribute it and/or modify | |
11 | it under the terms of the GNU General Public License as published by | |
12 | the Free Software Foundation; either version 2 of the License, or | |
13 | (at your option) any later version. | |
14 | ||
15 | This program is distributed in the hope that it will be useful, | |
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | GNU General Public License for more details. | |
19 | ||
20 | You should have received a copy of the GNU General Public License | |
21 | along with this program; if not, write to the Free Software | |
22 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
23 | ||
24 | ||
25 | /**************************************** | |
26 | ||
27 | WARNING | |
28 | ||
29 | This is only a partial ELF implementation, | |
30 | incorporating only those parts that are | |
31 | required to get gdb up and running. It is | |
32 | expected that it will be expanded to a full | |
33 | ELF implementation at some future date. | |
34 | ||
35 | Unimplemented stubs call abort() to ensure | |
36 | that they get proper attention if they are | |
37 | ever called. The stubs are here since | |
38 | this version was hacked from the COFF | |
39 | version, and thus they will probably | |
40 | go away or get expanded appropriately in a | |
41 | future version. | |
42 | ||
43 | fnf@cygnus.com | |
44 | ||
45 | *****************************************/ | |
46 | ||
47 | ||
48 | /* Problems and other issues to resolve. | |
49 | ||
50 | (1) BFD expects there to be some fixed number of "sections" in | |
51 | the object file. I.E. there is a "section_count" variable in the | |
52 | bfd structure which contains the number of sections. However, ELF | |
53 | supports multiple "views" of a file. In particular, with current | |
54 | implementations, executable files typically have two tables, a | |
55 | program header table and a section header table, both of which | |
56 | partition the executable. | |
57 | ||
58 | In ELF-speak, the "linking view" of the file uses the section header | |
59 | table to access "sections" within the file, and the "execution view" | |
60 | uses the program header table to access "segments" within the file. | |
61 | "Segments" typically may contain all the data from one or more | |
62 | "sections". | |
63 | ||
64 | Note that the section header table is optional in ELF executables, | |
65 | but it is this information that is most useful to gdb. If the | |
66 | section header table is missing, then gdb should probably try | |
67 | to make do with the program header table. (FIXME) | |
68 | ||
69 | */ | |
70 | ||
9ce0058c | 71 | #include "bfd.h" |
e0796d22 | 72 | #include "sysdep.h" |
9ce0058c SC |
73 | #include "libbfd.h" |
74 | #include "obstack.h" | |
75 | #include "elf-common.h" | |
76 | #include "elf-internal.h" | |
77 | #include "elf-external.h" | |
78 | ||
79 | /* Forward data declarations */ | |
80 | extern bfd_target elf_little_vec, elf_big_vec; | |
81 | ||
82 | /* Translate an ELF header in external format into an ELF header in internal | |
83 | format. */ | |
84 | ||
85 | static void | |
86 | DEFUN(bfd_swap_ehdr_in,(abfd, src, dst), | |
87 | bfd *abfd AND | |
88 | Elf_External_Ehdr *src AND | |
89 | Elf_Internal_Ehdr *dst) | |
90 | { | |
91 | bcopy (src -> e_ident, dst -> e_ident, EI_NIDENT); | |
92 | dst -> e_type = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_type); | |
93 | dst -> e_machine = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_machine); | |
94 | dst -> e_version = bfd_h_get_32 (abfd, (bfd_byte *) src -> e_version); | |
95 | dst -> e_entry = bfd_h_get_32 (abfd, (bfd_byte *) src -> e_entry); | |
96 | dst -> e_phoff = bfd_h_get_32 (abfd, (bfd_byte *) src -> e_phoff); | |
97 | dst -> e_shoff = bfd_h_get_32 (abfd, (bfd_byte *) src -> e_shoff); | |
98 | dst -> e_flags = bfd_h_get_32 (abfd, (bfd_byte *) src -> e_flags); | |
99 | dst -> e_ehsize = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_ehsize); | |
100 | dst -> e_phentsize = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_phentsize); | |
101 | dst -> e_phnum = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_phnum); | |
102 | dst -> e_shentsize = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_shentsize); | |
103 | dst -> e_shnum = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_shnum); | |
104 | dst -> e_shstrndx = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_shstrndx); | |
105 | } | |
106 | ||
107 | ||
108 | /* Translate an ELF section header table entry in external format into an | |
109 | ELF section header table entry in internal format. */ | |
110 | ||
111 | static void | |
112 | DEFUN(bfd_swap_shdr_in,(abfd, src, dst), | |
113 | bfd *abfd AND | |
114 | Elf_External_Shdr *src AND | |
115 | Elf_Internal_Shdr *dst) | |
116 | { | |
117 | dst -> sh_name = bfd_h_get_32 (abfd, (bfd_byte *) src -> sh_name); | |
118 | dst -> sh_type = bfd_h_get_32 (abfd, (bfd_byte *) src -> sh_type); | |
119 | dst -> sh_flags = bfd_h_get_32 (abfd, (bfd_byte *) src -> sh_flags); | |
120 | dst -> sh_addr = bfd_h_get_32 (abfd, (bfd_byte *) src -> sh_addr); | |
121 | dst -> sh_offset = bfd_h_get_32 (abfd, (bfd_byte *) src -> sh_offset); | |
122 | dst -> sh_size = bfd_h_get_32 (abfd, (bfd_byte *) src -> sh_size); | |
123 | dst -> sh_link = bfd_h_get_32 (abfd, (bfd_byte *) src -> sh_link); | |
124 | dst -> sh_info = bfd_h_get_32 (abfd, (bfd_byte *) src -> sh_info); | |
125 | dst -> sh_addralign = bfd_h_get_32 (abfd, (bfd_byte *) src -> sh_addralign); | |
126 | dst -> sh_entsize = bfd_h_get_32 (abfd, (bfd_byte *) src -> sh_entsize); | |
127 | } | |
128 | ||
129 | ||
e0796d22 FF |
130 | /* Translate an ELF program header table entry in external format into an |
131 | ELF program header table entry in internal format. */ | |
132 | ||
133 | static void | |
134 | DEFUN(bfd_swap_phdr_in,(abfd, src, dst), | |
135 | bfd *abfd AND | |
136 | Elf_External_Phdr *src AND | |
137 | Elf_Internal_Phdr *dst) | |
138 | { | |
139 | dst -> p_type = bfd_h_get_32 (abfd, (bfd_byte *) src -> p_type); | |
140 | dst -> p_offset = bfd_h_get_32 (abfd, (bfd_byte *) src -> p_offset); | |
141 | dst -> p_vaddr = bfd_h_get_32 (abfd, (bfd_byte *) src -> p_vaddr); | |
142 | dst -> p_paddr = bfd_h_get_32 (abfd, (bfd_byte *) src -> p_paddr); | |
143 | dst -> p_filesz = bfd_h_get_32 (abfd, (bfd_byte *) src -> p_filesz); | |
144 | dst -> p_memsz = bfd_h_get_32 (abfd, (bfd_byte *) src -> p_memsz); | |
145 | dst -> p_flags = bfd_h_get_32 (abfd, (bfd_byte *) src -> p_flags); | |
146 | dst -> p_align = bfd_h_get_32 (abfd, (bfd_byte *) src -> p_align); | |
147 | } | |
148 | ||
149 | ||
9ce0058c SC |
150 | /* Create a new bfd section from an ELF section header. */ |
151 | ||
152 | static boolean | |
153 | DEFUN(bfd_section_from_shdr, (abfd, hdr, shstrtab), | |
154 | bfd *abfd AND | |
155 | Elf_Internal_Shdr *hdr AND | |
156 | char *shstrtab) | |
157 | { | |
158 | asection *newsect; | |
159 | char *name; | |
160 | ||
161 | name = hdr -> sh_name ? shstrtab + hdr -> sh_name : "unnamed"; | |
162 | newsect = bfd_make_section (abfd, name); | |
163 | newsect -> vma = hdr -> sh_addr; | |
164 | newsect -> size = hdr -> sh_size; | |
165 | if (!(hdr -> sh_type == SHT_NOBITS)) | |
166 | { | |
167 | newsect -> filepos = hdr -> sh_offset; | |
168 | newsect -> flags |= SEC_HAS_CONTENTS; | |
169 | } | |
170 | if (hdr -> sh_flags & SHF_ALLOC) | |
171 | { | |
172 | newsect -> flags |= SEC_ALLOC; | |
173 | if (hdr -> sh_type != SHT_NOBITS) | |
174 | { | |
175 | newsect -> flags |= SEC_LOAD; | |
176 | } | |
177 | } | |
178 | if (!(hdr -> sh_flags & SHF_WRITE)) | |
179 | { | |
180 | newsect -> flags |= SEC_READONLY; | |
181 | } | |
182 | if (hdr -> sh_flags & SHF_EXECINSTR) | |
183 | { | |
184 | newsect -> flags |= SEC_CODE; /* FIXME: may only contain SOME code */ | |
185 | } | |
186 | if (hdr -> sh_type == SHT_SYMTAB) | |
187 | { | |
188 | abfd -> flags |= HAS_SYMS; | |
189 | } | |
190 | ||
191 | return (true); | |
192 | } | |
193 | ||
e0796d22 FF |
194 | /* Create a new bfd section from an ELF program header. |
195 | ||
196 | Since program segments have no names, we generate a synthetic name | |
197 | of the form segment<NUM>, where NUM is generally the index in the | |
198 | program header table. For segments that are split (see below) we | |
199 | generate the names segment<NUM>a and segment<NUM>b. | |
200 | ||
201 | Note that some program segments may have a file size that is different than | |
202 | (less than) the memory size. All this means is that at execution the | |
203 | system must allocate the amount of memory specified by the memory size, | |
204 | but only initialize it with the first "file size" bytes read from the | |
205 | file. This would occur for example, with program segments consisting | |
206 | of combined data+bss. | |
207 | ||
208 | To handle the above situation, this routine generates TWO bfd sections | |
209 | for the single program segment. The first has the length specified by | |
210 | the file size of the segment, and the second has the length specified | |
211 | by the difference between the two sizes. In effect, the segment is split | |
212 | into it's initialized and uninitialized parts. | |
213 | ||
214 | */ | |
215 | ||
216 | static boolean | |
217 | DEFUN(bfd_section_from_phdr, (abfd, hdr, index), | |
218 | bfd *abfd AND | |
219 | Elf_Internal_Phdr *hdr AND | |
220 | int index) | |
221 | { | |
222 | asection *newsect; | |
223 | char *name; | |
224 | char namebuf[64]; | |
225 | int split; | |
226 | ||
227 | split = ((hdr -> p_memsz > 0) && | |
228 | (hdr -> p_filesz > 0) && | |
229 | (hdr -> p_memsz > hdr -> p_filesz)); | |
230 | sprintf (namebuf, split ? "segment%da" : "segment%d", index); | |
231 | name = bfd_alloc (abfd, strlen (namebuf) + 1); | |
232 | (void) strcpy (name, namebuf); | |
233 | newsect = bfd_make_section (abfd, name); | |
234 | newsect -> vma = hdr -> p_vaddr; | |
235 | newsect -> size = hdr -> p_filesz; | |
236 | newsect -> filepos = hdr -> p_offset; | |
237 | newsect -> flags |= SEC_HAS_CONTENTS; | |
238 | if (hdr -> p_type == PT_LOAD) | |
239 | { | |
240 | newsect -> flags |= SEC_ALLOC; | |
241 | newsect -> flags |= SEC_LOAD; | |
242 | if (hdr -> p_flags & PF_X) | |
243 | { | |
244 | /* FIXME: all we known is that it has execute PERMISSION, | |
245 | may be data. */ | |
246 | newsect -> flags |= SEC_CODE; | |
247 | } | |
248 | } | |
249 | if (!(hdr -> p_flags & PF_W)) | |
250 | { | |
251 | newsect -> flags |= SEC_READONLY; | |
252 | } | |
253 | ||
254 | if (split) | |
255 | { | |
256 | sprintf (namebuf, "segment%db", index); | |
257 | name = bfd_alloc (abfd, strlen (namebuf) + 1); | |
258 | (void) strcpy (name, namebuf); | |
259 | newsect = bfd_make_section (abfd, name); | |
260 | newsect -> vma = hdr -> p_vaddr + hdr -> p_filesz; | |
261 | newsect -> size = hdr -> p_memsz - hdr -> p_filesz; | |
262 | if (hdr -> p_type == PT_LOAD) | |
263 | { | |
264 | newsect -> flags |= SEC_ALLOC; | |
265 | if (hdr -> p_flags & PF_X) | |
266 | { | |
267 | newsect -> flags |= SEC_CODE; | |
268 | } | |
269 | } | |
270 | if (!(hdr -> p_flags & PF_W)) | |
271 | { | |
272 | newsect -> flags |= SEC_READONLY; | |
273 | } | |
274 | } | |
275 | ||
276 | return (true); | |
277 | } | |
278 | ||
9ce0058c SC |
279 | /* Begin processing a given object. |
280 | ||
281 | First we validate the file by reading in the ELF header and checking | |
282 | the magic number. | |
283 | ||
284 | */ | |
285 | ||
286 | static bfd_target * | |
287 | DEFUN (elf_object_p, (abfd), bfd *abfd) | |
288 | { | |
289 | Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ | |
290 | Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */ | |
291 | Elf_External_Shdr *x_shdr; /* Section header table, external form */ | |
292 | Elf_Internal_Shdr *i_shdr; /* Section header table, internal form */ | |
293 | int shindex; | |
294 | char *shstrtab; /* Internal copy of section header stringtab */ | |
295 | int shstrtabsize; /* Size of section header string table */ | |
296 | ||
297 | /* Read in the ELF header in external format. */ | |
298 | ||
299 | if (bfd_read ((PTR) &x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr)) | |
300 | { | |
301 | bfd_error = system_call_error; | |
302 | return (NULL); | |
303 | } | |
304 | ||
305 | /* Now check to see if we have a valid ELF file, and one that BFD can | |
306 | make use of. The magic number must match, the address size ('class') | |
307 | and byte-swapping must match our XVEC entry, and it must have a | |
308 | section header table (FIXME: See comments re sections at top of this | |
309 | file). */ | |
310 | ||
311 | if (x_ehdr.e_ident[EI_MAG0] != ELFMAG0 || | |
312 | x_ehdr.e_ident[EI_MAG1] != ELFMAG1 || | |
313 | x_ehdr.e_ident[EI_MAG2] != ELFMAG2 || | |
314 | x_ehdr.e_ident[EI_MAG3] != ELFMAG3) | |
315 | { | |
316 | wrong: | |
317 | bfd_error = wrong_format; | |
318 | return (NULL); | |
319 | } | |
320 | ||
321 | /* FIXME, Check EI_VERSION here ! */ | |
322 | ||
323 | switch (x_ehdr.e_ident[EI_CLASS]) { | |
324 | case ELFCLASSNONE: /* address size not specified */ | |
325 | goto wrong; /* No support if can't tell address size */ | |
326 | case ELFCLASS32: /* 32-bit addresses */ | |
327 | break; | |
328 | case ELFCLASS64: /* 64-bit addresses */ | |
329 | goto wrong; /* FIXME: 64 bits not yet supported */ | |
330 | default: | |
331 | goto wrong; /* No support if unknown address class */ | |
332 | } | |
333 | ||
334 | /* Switch xvec to match the specified byte order. */ | |
335 | switch (x_ehdr.e_ident[EI_DATA]) { | |
336 | case ELFDATA2MSB: /* Big-endian */ | |
337 | abfd->xvec = &elf_big_vec; | |
338 | break; | |
339 | case ELFDATA2LSB: /* Little-endian */ | |
340 | abfd->xvec = &elf_little_vec; | |
341 | case ELFDATANONE: /* No data encoding specified */ | |
342 | default: /* Unknown data encoding specified */ | |
343 | goto wrong; | |
344 | } | |
345 | ||
346 | /* Now that we know the byte order, swap in the rest of the header */ | |
347 | bfd_swap_ehdr_in (abfd, &x_ehdr, &i_ehdr); | |
e0796d22 FF |
348 | |
349 | /* If there is no section header table, we're hosed. */ | |
350 | if (i_ehdr.e_shoff == 0) | |
9ce0058c SC |
351 | goto wrong; |
352 | ||
353 | if (i_ehdr.e_type == ET_EXEC || i_ehdr.e_type == ET_DYN) | |
354 | { | |
355 | abfd -> flags |= EXEC_P; | |
356 | } | |
357 | ||
358 | /* Allocate space for copies of the section header table in external | |
359 | and internal form, seek to the section header table in the file, | |
360 | read it in, and convert it to internal form. As a simple sanity | |
361 | check, verify that the what BFD thinks is the size of each section | |
362 | header table entry actually matches the size recorded in the file. */ | |
363 | ||
364 | if (i_ehdr.e_shentsize != sizeof (*x_shdr)) | |
365 | goto wrong; | |
366 | if ((x_shdr = (Elf_External_Shdr *) | |
367 | bfd_alloc (abfd, sizeof (*x_shdr) * i_ehdr.e_shnum)) == NULL) | |
368 | { | |
369 | bfd_error = no_memory; | |
370 | return (NULL); | |
371 | } | |
372 | if ((i_shdr = (Elf_Internal_Shdr *) | |
373 | bfd_alloc (abfd, sizeof (*i_shdr) * i_ehdr.e_shnum)) == NULL) | |
374 | { | |
375 | bfd_error = no_memory; | |
376 | return (NULL); | |
377 | } | |
378 | if (bfd_seek (abfd, i_ehdr.e_shoff, SEEK_SET) == -1) | |
379 | { | |
380 | bfd_error = system_call_error; | |
381 | return (NULL); | |
382 | } | |
383 | for (shindex = 0; shindex < i_ehdr.e_shnum; shindex++) | |
384 | { | |
385 | if (bfd_read ((PTR) (x_shdr + shindex), sizeof (*x_shdr), 1, abfd) | |
386 | != sizeof (*x_shdr)) | |
387 | { | |
388 | bfd_error = system_call_error; | |
389 | return (NULL); | |
390 | } | |
391 | bfd_swap_shdr_in (abfd, x_shdr + shindex, i_shdr + shindex); | |
392 | } | |
393 | ||
394 | /* Read in the string table containing the names of the sections. We | |
395 | will need the base pointer to this table later. */ | |
396 | ||
397 | shstrtabsize = i_shdr[i_ehdr.e_shstrndx].sh_size; | |
398 | if ((shstrtab = bfd_alloc (abfd, shstrtabsize)) == NULL) | |
399 | { | |
400 | bfd_error = no_memory; | |
401 | return (NULL); | |
402 | } | |
403 | if (bfd_seek (abfd, i_shdr[i_ehdr.e_shstrndx].sh_offset, SEEK_SET) == -1) | |
404 | { | |
405 | bfd_error = system_call_error; | |
406 | return (NULL); | |
407 | } | |
408 | if (bfd_read ((PTR) shstrtab, shstrtabsize, 1, abfd) != shstrtabsize) | |
409 | { | |
410 | bfd_error = system_call_error; | |
411 | return (NULL); | |
412 | } | |
413 | ||
414 | /* Once all of the section headers have been read and converted, we | |
a6c1d731 FF |
415 | can start processing them. Note that the first section header is |
416 | a dummy placeholder entry, so we ignore it. */ | |
9ce0058c | 417 | |
a6c1d731 | 418 | for (shindex = 1; shindex < i_ehdr.e_shnum; shindex++) |
9ce0058c SC |
419 | { |
420 | bfd_section_from_shdr (abfd, i_shdr + shindex, shstrtab); | |
421 | } | |
422 | ||
423 | return (abfd->xvec); | |
424 | } | |
425 | ||
e0796d22 FF |
426 | /* Core files are simply standard ELF formatted files that partition |
427 | the file using the execution view of the file (program header table) | |
428 | rather than the linking view. In fact, there is no section header | |
429 | table in a core file. | |
430 | */ | |
431 | ||
432 | static bfd_target * | |
433 | DEFUN (elf_core_file_p, (abfd), bfd *abfd) | |
434 | { | |
435 | Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ | |
436 | Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */ | |
437 | Elf_External_Phdr *x_phdr; /* Program header table, external form */ | |
438 | Elf_Internal_Phdr *i_phdr; /* Program header table, internal form */ | |
439 | int phindex; | |
440 | ||
441 | /* Read in the ELF header in external format. */ | |
442 | ||
443 | if (bfd_read ((PTR) &x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr)) | |
444 | { | |
445 | bfd_error = system_call_error; | |
446 | return (NULL); | |
447 | } | |
448 | ||
449 | /* Now check to see if we have a valid ELF file, and one that BFD can | |
450 | make use of. The magic number must match, the address size ('class') | |
451 | and byte-swapping must match our XVEC entry, and it must have a | |
452 | program header table (FIXME: See comments re segments at top of this | |
453 | file). */ | |
454 | ||
455 | if (x_ehdr.e_ident[EI_MAG0] != ELFMAG0 || | |
456 | x_ehdr.e_ident[EI_MAG1] != ELFMAG1 || | |
457 | x_ehdr.e_ident[EI_MAG2] != ELFMAG2 || | |
458 | x_ehdr.e_ident[EI_MAG3] != ELFMAG3) | |
459 | { | |
460 | wrong: | |
461 | bfd_error = wrong_format; | |
462 | return (NULL); | |
463 | } | |
464 | ||
465 | /* FIXME, Check EI_VERSION here ! */ | |
466 | ||
467 | switch (x_ehdr.e_ident[EI_CLASS]) { | |
468 | case ELFCLASSNONE: /* address size not specified */ | |
469 | goto wrong; /* No support if can't tell address size */ | |
470 | case ELFCLASS32: /* 32-bit addresses */ | |
471 | break; | |
472 | case ELFCLASS64: /* 64-bit addresses */ | |
473 | goto wrong; /* FIXME: 64 bits not yet supported */ | |
474 | default: | |
475 | goto wrong; /* No support if unknown address class */ | |
476 | } | |
477 | ||
478 | /* Switch xvec to match the specified byte order. */ | |
479 | switch (x_ehdr.e_ident[EI_DATA]) { | |
480 | case ELFDATA2MSB: /* Big-endian */ | |
481 | abfd->xvec = &elf_big_vec; | |
482 | break; | |
483 | case ELFDATA2LSB: /* Little-endian */ | |
484 | abfd->xvec = &elf_little_vec; | |
485 | case ELFDATANONE: /* No data encoding specified */ | |
486 | default: /* Unknown data encoding specified */ | |
487 | goto wrong; | |
488 | } | |
489 | ||
490 | /* Now that we know the byte order, swap in the rest of the header */ | |
491 | bfd_swap_ehdr_in (abfd, &x_ehdr, &i_ehdr); | |
492 | ||
493 | /* If there is no program header, or the type is not a core file, then | |
494 | we are hosed. */ | |
495 | if (i_ehdr.e_phoff == 0 || i_ehdr.e_type != ET_CORE) | |
496 | goto wrong; | |
497 | ||
498 | /* Allocate space for copies of the program header table in external | |
499 | and internal form, seek to the program header table in the file, | |
500 | read it in, and convert it to internal form. As a simple sanity | |
501 | check, verify that the what BFD thinks is the size of each program | |
502 | header table entry actually matches the size recorded in the file. */ | |
503 | ||
504 | if (i_ehdr.e_phentsize != sizeof (*x_phdr)) | |
505 | goto wrong; | |
506 | if ((x_phdr = (Elf_External_Phdr *) | |
507 | bfd_alloc (abfd, sizeof (*x_phdr) * i_ehdr.e_phnum)) == NULL) | |
508 | { | |
509 | bfd_error = no_memory; | |
510 | return (NULL); | |
511 | } | |
512 | if ((i_phdr = (Elf_Internal_Phdr *) | |
513 | bfd_alloc (abfd, sizeof (*i_phdr) * i_ehdr.e_phnum)) == NULL) | |
514 | { | |
515 | bfd_error = no_memory; | |
516 | return (NULL); | |
517 | } | |
518 | if (bfd_seek (abfd, i_ehdr.e_phoff, SEEK_SET) == -1) | |
519 | { | |
520 | bfd_error = system_call_error; | |
521 | return (NULL); | |
522 | } | |
523 | for (phindex = 0; phindex < i_ehdr.e_phnum; phindex++) | |
524 | { | |
525 | if (bfd_read ((PTR) (x_phdr + phindex), sizeof (*x_phdr), 1, abfd) | |
526 | != sizeof (*x_phdr)) | |
527 | { | |
528 | bfd_error = system_call_error; | |
529 | return (NULL); | |
530 | } | |
531 | bfd_swap_phdr_in (abfd, x_phdr + phindex, i_phdr + phindex); | |
532 | } | |
533 | ||
534 | /* Once all of the program headers have been read and converted, we | |
535 | can start processing them. */ | |
536 | ||
537 | for (phindex = 0; phindex < i_ehdr.e_phnum; phindex++) | |
538 | { | |
539 | bfd_section_from_phdr (abfd, i_phdr + phindex, phindex); | |
540 | } | |
541 | ||
542 | return (abfd->xvec); | |
543 | } | |
544 | ||
9ce0058c SC |
545 | static boolean |
546 | DEFUN (elf_mkobject, (abfd), bfd *abfd) | |
547 | { | |
548 | fprintf (stderr, "elf_mkobject unimplemented\n"); | |
549 | fflush (stderr); | |
550 | abort (); | |
551 | return (false); | |
552 | } | |
553 | ||
554 | static boolean | |
555 | DEFUN (elf_write_object_contents, (abfd), bfd *abfd) | |
556 | { | |
557 | fprintf (stderr, "elf_write_object_contents unimplemented\n"); | |
558 | fflush (stderr); | |
559 | abort (); | |
560 | return (false); | |
561 | } | |
562 | ||
9ce0058c SC |
563 | static unsigned int |
564 | elf_get_symtab_upper_bound(abfd) | |
565 | bfd *abfd; | |
566 | { | |
567 | fprintf (stderr, "elf_get_symtab_upper_bound unimplemented\n"); | |
568 | fflush (stderr); | |
569 | abort (); | |
570 | return (0); | |
571 | } | |
572 | ||
573 | static unsigned int | |
574 | elf_get_reloc_upper_bound (abfd, asect) | |
575 | bfd *abfd; | |
576 | sec_ptr asect; | |
577 | { | |
578 | fprintf (stderr, "elf_get_reloc_upper_bound unimplemented\n"); | |
579 | fflush (stderr); | |
580 | abort (); | |
581 | return (0); | |
582 | } | |
583 | ||
584 | static unsigned int | |
585 | elf_canonicalize_reloc (abfd, section, relptr, symbols) | |
586 | bfd *abfd; | |
587 | sec_ptr section; | |
588 | arelent **relptr; | |
589 | asymbol **symbols; | |
590 | { | |
591 | fprintf (stderr, "elf_canonicalize_reloc unimplemented\n"); | |
592 | fflush (stderr); | |
593 | abort (); | |
594 | return (0); | |
595 | } | |
596 | ||
597 | static unsigned int | |
598 | elf_get_symtab (abfd, alocation) | |
599 | bfd *abfd; | |
600 | asymbol **alocation; | |
601 | { | |
602 | fprintf (stderr, "elf_get_symtab unimplemented\n"); | |
603 | fflush (stderr); | |
604 | abort (); | |
605 | return (0); | |
606 | } | |
607 | ||
608 | static asymbol * | |
609 | elf_make_empty_symbol(abfd) | |
610 | bfd *abfd; | |
611 | { | |
612 | fprintf (stderr, "elf_make_empty_symbol unimplemented\n"); | |
613 | fflush (stderr); | |
614 | abort (); | |
615 | return (NULL); | |
616 | } | |
617 | ||
618 | static void | |
619 | DEFUN (elf_print_symbol,(ignore_abfd, filep, symbol, how), | |
620 | bfd *ignore_abfd AND | |
621 | PTR filep AND | |
622 | asymbol *symbol AND | |
e0796d22 | 623 | bfd_print_symbol_type how) |
9ce0058c SC |
624 | { |
625 | fprintf (stderr, "elf_print_symbol unimplemented\n"); | |
626 | fflush (stderr); | |
627 | abort (); | |
628 | } | |
629 | ||
630 | static alent * | |
631 | DEFUN (elf_get_lineno,(ignore_abfd, symbol), | |
632 | bfd *ignore_abfd AND | |
633 | asymbol *symbol) | |
634 | { | |
635 | fprintf (stderr, "elf_get_lineno unimplemented\n"); | |
636 | fflush (stderr); | |
637 | abort (); | |
638 | return (NULL); | |
639 | } | |
640 | ||
641 | static boolean | |
642 | DEFUN (elf_set_arch_mach,(abfd, arch, machine), | |
643 | bfd *abfd AND | |
644 | enum bfd_architecture arch AND | |
645 | unsigned long machine) | |
646 | { | |
647 | fprintf (stderr, "elf_set_arch_mach unimplemented\n"); | |
648 | fflush (stderr); | |
649 | /* Allow any architecture to be supported by the elf backend */ | |
650 | return bfd_default_set_arch_mach(abfd, arch, machine); | |
651 | } | |
652 | ||
653 | static boolean | |
654 | DEFUN (elf_find_nearest_line,(abfd, | |
655 | section, | |
656 | symbols, | |
657 | offset, | |
658 | filename_ptr, | |
659 | functionname_ptr, | |
660 | line_ptr), | |
661 | bfd *abfd AND | |
662 | asection *section AND | |
663 | asymbol **symbols AND | |
664 | bfd_vma offset AND | |
665 | CONST char **filename_ptr AND | |
666 | CONST char **functionname_ptr AND | |
667 | unsigned int *line_ptr) | |
668 | { | |
669 | fprintf (stderr, "elf_find_nearest_line unimplemented\n"); | |
670 | fflush (stderr); | |
671 | abort (); | |
672 | return (false); | |
673 | } | |
674 | ||
675 | static int | |
676 | DEFUN (elf_sizeof_headers, (abfd, reloc), | |
677 | bfd *abfd AND | |
678 | boolean reloc) | |
679 | { | |
680 | fprintf (stderr, "elf_sizeof_headers unimplemented\n"); | |
681 | fflush (stderr); | |
682 | abort (); | |
683 | return (0); | |
684 | } | |
e0796d22 | 685 | \f |
9ce0058c SC |
686 | /* This structure contains everything that BFD knows about a target. |
687 | It includes things like its byte order, name, what routines to call | |
688 | to do various operations, etc. Every BFD points to a target structure | |
689 | with its "xvec" member. | |
690 | ||
691 | There are two such structures here: one for big-endian machines and | |
692 | one for little-endian machines. */ | |
693 | ||
e0796d22 FF |
694 | #define elf_core_file_failing_command _bfd_dummy_core_file_failing_command |
695 | #define elf_core_file_failing_signal _bfd_dummy_core_file_failing_signal | |
696 | #define elf_core_file_matches_executable_p _bfd_dummy_core_file_matches_executable_p | |
697 | ||
698 | /* Archives are generic or unimplemented. */ | |
699 | #define elf_slurp_armap bfd_false | |
700 | #define elf_slurp_extended_name_table _bfd_slurp_extended_name_table | |
701 | #define elf_truncate_arname bfd_dont_truncate_arname | |
702 | #define elf_openr_next_archived_file bfd_generic_openr_next_archived_file | |
703 | #define elf_generic_stat_arch_elt bfd_generic_stat_arch_elt | |
704 | #define elf_write_armap (PROTO (boolean, (*), \ | |
a6c1d731 | 705 | (bfd *arch, unsigned int elength, struct orl *map, unsigned int orl_count, \ |
e0796d22 FF |
706 | int stridx))) bfd_false |
707 | ||
708 | /* Ordinary section reading and writing */ | |
709 | #define elf_new_section_hook _bfd_dummy_new_section_hook | |
710 | #define elf_get_section_contents bfd_generic_get_section_contents | |
711 | #define elf_set_section_contents bfd_generic_set_section_contents | |
712 | #define elf_close_and_cleanup bfd_generic_close_and_cleanup | |
713 | ||
714 | #define elf_bfd_debug_info_start bfd_void | |
715 | #define elf_bfd_debug_info_end bfd_void | |
716 | #define elf_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void | |
717 | ||
9ce0058c SC |
718 | bfd_target elf_big_vec = |
719 | { | |
720 | /* name: identify kind of target */ | |
721 | "elf-big", | |
722 | ||
723 | /* flavour: general indication about file */ | |
e0796d22 | 724 | bfd_target_elf_flavour, |
9ce0058c SC |
725 | |
726 | /* byteorder_big_p: data is big endian */ | |
727 | true, | |
728 | ||
729 | /* header_byteorder_big_p: header is also big endian */ | |
730 | true, | |
731 | ||
732 | /* object_flags: mask of all file flags */ | |
733 | (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS | | |
734 | DYNAMIC | WP_TEXT), | |
735 | ||
736 | /* section_flags: mask of all section flags */ | |
737 | (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | | |
738 | SEC_DATA), | |
739 | ||
740 | /* ar_pad_char: pad character for filenames within an archive header | |
741 | FIXME: this really has nothing to do with ELF, this is a characteristic | |
742 | of the archiver and/or os and should be independently tunable */ | |
743 | '/', | |
744 | ||
745 | /* ar_max_namelen: maximum number of characters in an archive header | |
746 | FIXME: this really has nothing to do with ELF, this is a characteristic | |
747 | of the archiver and should be independently tunable. This value is | |
748 | a WAG (wild a** guess) */ | |
749 | 15, | |
750 | ||
751 | /* align_power_min: minimum alignment restriction for any section | |
752 | FIXME: this value may be target machine dependent */ | |
753 | 3, | |
754 | ||
755 | /* Routines to byte-swap various sized integers from the data sections */ | |
756 | _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, | |
757 | ||
758 | /* Routines to byte-swap various sized integers from the file headers */ | |
759 | _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, | |
760 | ||
761 | /* bfd_check_format: check the format of a file being read */ | |
e0796d22 FF |
762 | { _bfd_dummy_target, /* unknown format */ |
763 | elf_object_p, /* assembler/linker output (object file) */ | |
764 | bfd_generic_archive_p, /* an archive */ | |
765 | elf_core_file_p /* a core file */ | |
9ce0058c SC |
766 | }, |
767 | ||
768 | /* bfd_set_format: set the format of a file being written */ | |
769 | { bfd_false, | |
770 | elf_mkobject, | |
771 | _bfd_generic_mkarchive, | |
772 | bfd_false | |
773 | }, | |
774 | ||
775 | /* bfd_write_contents: write cached information into a file being written */ | |
776 | { bfd_false, | |
777 | elf_write_object_contents, | |
778 | _bfd_write_archive_contents, | |
779 | bfd_false | |
780 | }, | |
781 | ||
782 | /* Initialize a jump table with the standard macro. All names start | |
783 | with "elf" */ | |
784 | JUMP_TABLE(elf), | |
785 | ||
786 | /* SWAP_TABLE */ | |
787 | NULL, NULL, NULL | |
788 | }; | |
789 | ||
790 | bfd_target elf_little_vec = | |
791 | { | |
792 | /* name: identify kind of target */ | |
793 | "elf-little", | |
794 | ||
795 | /* flavour: general indication about file */ | |
e0796d22 | 796 | bfd_target_elf_flavour, |
9ce0058c SC |
797 | |
798 | /* byteorder_big_p: data is big endian */ | |
799 | false, /* Nope -- this one's little endian */ | |
800 | ||
801 | /* header_byteorder_big_p: header is also big endian */ | |
802 | false, /* Nope -- this one's little endian */ | |
803 | ||
804 | /* object_flags: mask of all file flags */ | |
805 | (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS | | |
806 | DYNAMIC | WP_TEXT), | |
807 | ||
808 | /* section_flags: mask of all section flags */ | |
809 | (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | | |
810 | SEC_DATA), | |
811 | ||
812 | /* ar_pad_char: pad character for filenames within an archive header | |
813 | FIXME: this really has nothing to do with ELF, this is a characteristic | |
814 | of the archiver and/or os and should be independently tunable */ | |
815 | '/', | |
816 | ||
817 | /* ar_max_namelen: maximum number of characters in an archive header | |
818 | FIXME: this really has nothing to do with ELF, this is a characteristic | |
819 | of the archiver and should be independently tunable. This value is | |
820 | a WAG (wild a** guess) */ | |
821 | 15, | |
822 | ||
823 | /* align_power_min: minimum alignment restriction for any section | |
824 | FIXME: this value may be target machine dependent */ | |
825 | 3, | |
826 | ||
827 | /* Routines to byte-swap various sized integers from the data sections */ | |
828 | _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, | |
829 | ||
830 | /* Routines to byte-swap various sized integers from the file headers */ | |
831 | _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, | |
832 | ||
833 | /* bfd_check_format: check the format of a file being read */ | |
e0796d22 FF |
834 | { _bfd_dummy_target, /* unknown format */ |
835 | elf_object_p, /* assembler/linker output (object file) */ | |
836 | bfd_generic_archive_p, /* an archive */ | |
837 | elf_core_file_p /* a core file */ | |
9ce0058c SC |
838 | }, |
839 | ||
840 | /* bfd_set_format: set the format of a file being written */ | |
841 | { bfd_false, | |
842 | elf_mkobject, | |
843 | _bfd_generic_mkarchive, | |
844 | bfd_false | |
845 | }, | |
846 | ||
847 | /* bfd_write_contents: write cached information into a file being written */ | |
848 | { bfd_false, | |
849 | elf_write_object_contents, | |
850 | _bfd_write_archive_contents, | |
851 | bfd_false | |
852 | }, | |
853 | ||
854 | /* Initialize a jump table with the standard macro. All names start | |
855 | with "elf" */ | |
856 | JUMP_TABLE(elf), | |
857 | ||
858 | /* SWAP_TABLE */ | |
859 | NULL, NULL, NULL | |
860 | }; |