1 |
/* Support for the generic parts of COFF, for BFD. |
/* Support for the generic parts of COFF, for BFD. |
2 |
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, |
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, |
3 |
2000, 2001, 2002 |
2000, 2001, 2002, 2003, 2004, 2005 |
4 |
Free Software Foundation, Inc. |
Free Software Foundation, Inc. |
5 |
Written by Cygnus Support. |
Written by Cygnus Support. |
6 |
|
|
46 |
static void coff_fix_symbol_name |
static void coff_fix_symbol_name |
47 |
PARAMS ((bfd *, asymbol *, combined_entry_type *, bfd_size_type *, |
PARAMS ((bfd *, asymbol *, combined_entry_type *, bfd_size_type *, |
48 |
asection **, bfd_size_type *)); |
asection **, bfd_size_type *)); |
49 |
static boolean coff_write_symbol |
static bfd_boolean coff_write_symbol |
50 |
PARAMS ((bfd *, asymbol *, combined_entry_type *, bfd_vma *, |
PARAMS ((bfd *, asymbol *, combined_entry_type *, bfd_vma *, |
51 |
bfd_size_type *, asection **, bfd_size_type *)); |
bfd_size_type *, asection **, bfd_size_type *)); |
52 |
static boolean coff_write_alien_symbol |
static bfd_boolean coff_write_alien_symbol |
53 |
PARAMS ((bfd *, asymbol *, bfd_vma *, bfd_size_type *, |
PARAMS ((bfd *, asymbol *, bfd_vma *, bfd_size_type *, |
54 |
asection **, bfd_size_type *)); |
asection **, bfd_size_type *)); |
55 |
static boolean coff_write_native_symbol |
static bfd_boolean coff_write_native_symbol |
56 |
PARAMS ((bfd *, coff_symbol_type *, bfd_vma *, bfd_size_type *, |
PARAMS ((bfd *, coff_symbol_type *, bfd_vma *, bfd_size_type *, |
57 |
asection **, bfd_size_type *)); |
asection **, bfd_size_type *)); |
58 |
static void coff_pointerize_aux |
static void coff_pointerize_aux |
59 |
PARAMS ((bfd *, combined_entry_type *, combined_entry_type *, |
PARAMS ((bfd *, combined_entry_type *, combined_entry_type *, |
60 |
unsigned int, combined_entry_type *)); |
unsigned int, combined_entry_type *)); |
61 |
static boolean make_a_section_from_file |
static bfd_boolean make_a_section_from_file |
62 |
PARAMS ((bfd *, struct internal_scnhdr *, unsigned int)); |
PARAMS ((bfd *, struct internal_scnhdr *, unsigned int)); |
63 |
static const bfd_target *coff_real_object_p |
static const bfd_target *coff_real_object_p |
64 |
PARAMS ((bfd *, unsigned, struct internal_filehdr *, |
PARAMS ((bfd *, unsigned, struct internal_filehdr *, |
74 |
|
|
75 |
/* Take a section header read from a coff file (in HOST byte order), |
/* Take a section header read from a coff file (in HOST byte order), |
76 |
and make a BFD "section" out of it. This is used by ECOFF. */ |
and make a BFD "section" out of it. This is used by ECOFF. */ |
77 |
static boolean |
static bfd_boolean |
78 |
make_a_section_from_file (abfd, hdr, target_index) |
make_a_section_from_file (abfd, hdr, target_index) |
79 |
bfd *abfd; |
bfd *abfd; |
80 |
struct internal_scnhdr *hdr; |
struct internal_scnhdr *hdr; |
82 |
{ |
{ |
83 |
asection *return_section; |
asection *return_section; |
84 |
char *name; |
char *name; |
85 |
boolean result = true; |
bfd_boolean result = TRUE; |
86 |
flagword flags; |
flagword flags; |
87 |
|
|
88 |
name = NULL; |
name = NULL; |
103 |
{ |
{ |
104 |
strings = _bfd_coff_read_string_table (abfd); |
strings = _bfd_coff_read_string_table (abfd); |
105 |
if (strings == NULL) |
if (strings == NULL) |
106 |
return false; |
return FALSE; |
107 |
/* FIXME: For extra safety, we should make sure that |
/* FIXME: For extra safety, we should make sure that |
108 |
strindex does not run us past the end, but right now we |
strindex does not run us past the end, but right now we |
109 |
don't know the length of the string table. */ |
don't know the length of the string table. */ |
110 |
strings += strindex; |
strings += strindex; |
111 |
name = bfd_alloc (abfd, (bfd_size_type) strlen (strings) + 1); |
name = bfd_alloc (abfd, (bfd_size_type) strlen (strings) + 1); |
112 |
if (name == NULL) |
if (name == NULL) |
113 |
return false; |
return FALSE; |
114 |
strcpy (name, strings); |
strcpy (name, strings); |
115 |
} |
} |
116 |
} |
} |
120 |
/* Assorted wastage to null-terminate the name, thanks AT&T! */ |
/* Assorted wastage to null-terminate the name, thanks AT&T! */ |
121 |
name = bfd_alloc (abfd, (bfd_size_type) sizeof (hdr->s_name) + 1); |
name = bfd_alloc (abfd, (bfd_size_type) sizeof (hdr->s_name) + 1); |
122 |
if (name == NULL) |
if (name == NULL) |
123 |
return false; |
return FALSE; |
124 |
strncpy (name, (char *) &hdr->s_name[0], sizeof (hdr->s_name)); |
strncpy (name, (char *) &hdr->s_name[0], sizeof (hdr->s_name)); |
125 |
name[sizeof (hdr->s_name)] = 0; |
name[sizeof (hdr->s_name)] = 0; |
126 |
} |
} |
127 |
|
|
128 |
return_section = bfd_make_section_anyway (abfd, name); |
return_section = bfd_make_section_anyway (abfd, name); |
129 |
if (return_section == NULL) |
if (return_section == NULL) |
130 |
return false; |
return FALSE; |
131 |
|
|
132 |
return_section->vma = hdr->s_vaddr; |
return_section->vma = hdr->s_vaddr; |
133 |
return_section->lma = hdr->s_paddr; |
return_section->lma = hdr->s_paddr; |
134 |
return_section->_raw_size = hdr->s_size; |
return_section->size = hdr->s_size; |
135 |
return_section->filepos = hdr->s_scnptr; |
return_section->filepos = hdr->s_scnptr; |
136 |
return_section->rel_filepos = hdr->s_relptr; |
return_section->rel_filepos = hdr->s_relptr; |
137 |
return_section->reloc_count = hdr->s_nreloc; |
return_section->reloc_count = hdr->s_nreloc; |
147 |
|
|
148 |
if (! bfd_coff_styp_to_sec_flags_hook (abfd, hdr, name, return_section, |
if (! bfd_coff_styp_to_sec_flags_hook (abfd, hdr, name, return_section, |
149 |
& flags)) |
& flags)) |
150 |
result = false; |
result = FALSE; |
151 |
|
|
152 |
return_section->flags = flags; |
return_section->flags = flags; |
153 |
|
|
178 |
flagword oflags = abfd->flags; |
flagword oflags = abfd->flags; |
179 |
bfd_vma ostart = bfd_get_start_address (abfd); |
bfd_vma ostart = bfd_get_start_address (abfd); |
180 |
PTR tdata; |
PTR tdata; |
181 |
|
PTR tdata_save; |
182 |
bfd_size_type readsize; /* length of file_info */ |
bfd_size_type readsize; /* length of file_info */ |
183 |
unsigned int scnhsz; |
unsigned int scnhsz; |
184 |
char *external_sections; |
char *external_sections; |
207 |
|
|
208 |
/* Set up the tdata area. ECOFF uses its own routine, and overrides |
/* Set up the tdata area. ECOFF uses its own routine, and overrides |
209 |
abfd->flags. */ |
abfd->flags. */ |
210 |
|
tdata_save = abfd->tdata.any; |
211 |
tdata = bfd_coff_mkobject_hook (abfd, (PTR) internal_f, (PTR) internal_a); |
tdata = bfd_coff_mkobject_hook (abfd, (PTR) internal_f, (PTR) internal_a); |
212 |
if (tdata == NULL) |
if (tdata == NULL) |
213 |
return 0; |
goto fail2; |
214 |
|
|
215 |
scnhsz = bfd_coff_scnhsz (abfd); |
scnhsz = bfd_coff_scnhsz (abfd); |
216 |
readsize = (bfd_size_type) nscns * scnhsz; |
readsize = (bfd_size_type) nscns * scnhsz; |
226 |
if (! bfd_coff_set_arch_mach_hook (abfd, (PTR) internal_f)) |
if (! bfd_coff_set_arch_mach_hook (abfd, (PTR) internal_f)) |
227 |
goto fail; |
goto fail; |
228 |
|
|
229 |
/* Now copy data as required; construct all asections etc */ |
/* Now copy data as required; construct all asections etc. */ |
230 |
if (nscns != 0) |
if (nscns != 0) |
231 |
{ |
{ |
232 |
unsigned int i; |
unsigned int i; |
241 |
} |
} |
242 |
} |
} |
243 |
|
|
|
/* make_abs_section (abfd); */ |
|
|
|
|
244 |
return abfd->xvec; |
return abfd->xvec; |
245 |
|
|
246 |
fail: |
fail: |
247 |
bfd_release (abfd, tdata); |
bfd_release (abfd, tdata); |
248 |
|
fail2: |
249 |
|
abfd->tdata.any = tdata_save; |
250 |
abfd->flags = oflags; |
abfd->flags = oflags; |
251 |
bfd_get_start_address (abfd) = ostart; |
bfd_get_start_address (abfd) = ostart; |
252 |
return (const bfd_target *) NULL; |
return (const bfd_target *) NULL; |
272 |
|
|
273 |
filehdr = bfd_alloc (abfd, filhsz); |
filehdr = bfd_alloc (abfd, filhsz); |
274 |
if (filehdr == NULL) |
if (filehdr == NULL) |
275 |
return 0; |
return NULL; |
276 |
if (bfd_bread (filehdr, filhsz, abfd) != filhsz) |
if (bfd_bread (filehdr, filhsz, abfd) != filhsz) |
277 |
{ |
{ |
278 |
if (bfd_get_error () != bfd_error_system_call) |
if (bfd_get_error () != bfd_error_system_call) |
279 |
bfd_set_error (bfd_error_wrong_format); |
bfd_set_error (bfd_error_wrong_format); |
280 |
return 0; |
bfd_release (abfd, filehdr); |
281 |
|
return NULL; |
282 |
} |
} |
283 |
bfd_coff_swap_filehdr_in (abfd, filehdr, &internal_f); |
bfd_coff_swap_filehdr_in (abfd, filehdr, &internal_f); |
284 |
bfd_release (abfd, filehdr); |
bfd_release (abfd, filehdr); |
295 |
|| internal_f.f_opthdr > aoutsz) |
|| internal_f.f_opthdr > aoutsz) |
296 |
{ |
{ |
297 |
bfd_set_error (bfd_error_wrong_format); |
bfd_set_error (bfd_error_wrong_format); |
298 |
return 0; |
return NULL; |
299 |
} |
} |
300 |
nscns = internal_f.f_nscns; |
nscns = internal_f.f_nscns; |
301 |
|
|
305 |
|
|
306 |
opthdr = bfd_alloc (abfd, aoutsz); |
opthdr = bfd_alloc (abfd, aoutsz); |
307 |
if (opthdr == NULL) |
if (opthdr == NULL) |
308 |
return 0; |
return NULL; |
309 |
if (bfd_bread (opthdr, (bfd_size_type) internal_f.f_opthdr, abfd) |
if (bfd_bread (opthdr, (bfd_size_type) internal_f.f_opthdr, abfd) |
310 |
!= internal_f.f_opthdr) |
!= internal_f.f_opthdr) |
311 |
{ |
{ |
312 |
return 0; |
bfd_release (abfd, opthdr); |
313 |
|
return NULL; |
314 |
} |
} |
315 |
bfd_coff_swap_aouthdr_in (abfd, opthdr, (PTR) &internal_a); |
bfd_coff_swap_aouthdr_in (abfd, opthdr, (PTR) &internal_a); |
316 |
|
bfd_release (abfd, opthdr); |
317 |
} |
} |
318 |
|
|
319 |
return coff_real_object_p (abfd, nscns, &internal_f, |
return coff_real_object_p (abfd, nscns, &internal_f, |
329 |
bfd *abfd; |
bfd *abfd; |
330 |
int index; |
int index; |
331 |
{ |
{ |
332 |
struct sec *answer = abfd->sections; |
struct bfd_section *answer = abfd->sections; |
333 |
|
|
334 |
if (index == N_ABS) |
if (index == N_ABS) |
335 |
return bfd_abs_section_ptr; |
return bfd_abs_section_ptr; |
365 |
/* Canonicalize a COFF symbol table. */ |
/* Canonicalize a COFF symbol table. */ |
366 |
|
|
367 |
long |
long |
368 |
coff_get_symtab (abfd, alocation) |
coff_canonicalize_symtab (abfd, alocation) |
369 |
bfd *abfd; |
bfd *abfd; |
370 |
asymbol **alocation; |
asymbol **alocation; |
371 |
{ |
{ |
421 |
} |
} |
422 |
|
|
423 |
/* Read in and swap the relocs. This returns a buffer holding the |
/* Read in and swap the relocs. This returns a buffer holding the |
424 |
relocs for section SEC in file ABFD. If CACHE is true and |
relocs for section SEC in file ABFD. If CACHE is TRUE and |
425 |
INTERNAL_RELOCS is NULL, the relocs read in will be saved in case |
INTERNAL_RELOCS is NULL, the relocs read in will be saved in case |
426 |
the function is called again. If EXTERNAL_RELOCS is not NULL, it |
the function is called again. If EXTERNAL_RELOCS is not NULL, it |
427 |
is a buffer large enough to hold the unswapped relocs. If |
is a buffer large enough to hold the unswapped relocs. If |
428 |
INTERNAL_RELOCS is not NULL, it is a buffer large enough to hold |
INTERNAL_RELOCS is not NULL, it is a buffer large enough to hold |
429 |
the swapped relocs. If REQUIRE_INTERNAL is true, then the return |
the swapped relocs. If REQUIRE_INTERNAL is TRUE, then the return |
430 |
value must be INTERNAL_RELOCS. The function returns NULL on error. */ |
value must be INTERNAL_RELOCS. The function returns NULL on error. */ |
431 |
|
|
432 |
struct internal_reloc * |
struct internal_reloc * |
434 |
require_internal, internal_relocs) |
require_internal, internal_relocs) |
435 |
bfd *abfd; |
bfd *abfd; |
436 |
asection *sec; |
asection *sec; |
437 |
boolean cache; |
bfd_boolean cache; |
438 |
bfd_byte *external_relocs; |
bfd_byte *external_relocs; |
439 |
boolean require_internal; |
bfd_boolean require_internal; |
440 |
struct internal_reloc *internal_relocs; |
struct internal_reloc *internal_relocs; |
441 |
{ |
{ |
442 |
bfd_size_type relsz; |
bfd_size_type relsz; |
563 |
do |
do |
564 |
{ |
{ |
565 |
asection * sec = q->symbol.section->output_section; |
asection * sec = q->symbol.section->output_section; |
566 |
|
|
567 |
/* Do not try to update fields in read-only sections. */ |
/* Do not try to update fields in read-only sections. */ |
568 |
if (! bfd_is_const_section (sec)) |
if (! bfd_is_const_section (sec)) |
569 |
sec->lineno_count ++; |
sec->lineno_count ++; |
654 |
chain, and that the last one points to the first external symbol. We |
chain, and that the last one points to the first external symbol. We |
655 |
do that here too. */ |
do that here too. */ |
656 |
|
|
657 |
boolean |
bfd_boolean |
658 |
coff_renumber_symbols (bfd_ptr, first_undef) |
coff_renumber_symbols (bfd_ptr, first_undef) |
659 |
bfd *bfd_ptr; |
bfd *bfd_ptr; |
660 |
int *first_undef; |
int *first_undef; |
683 |
amt = sizeof (asymbol *) * ((bfd_size_type) symbol_count + 1); |
amt = sizeof (asymbol *) * ((bfd_size_type) symbol_count + 1); |
684 |
newsyms = (asymbol **) bfd_alloc (bfd_ptr, amt); |
newsyms = (asymbol **) bfd_alloc (bfd_ptr, amt); |
685 |
if (!newsyms) |
if (!newsyms) |
686 |
return false; |
return FALSE; |
687 |
bfd_ptr->outsymbols = newsyms; |
bfd_ptr->outsymbols = newsyms; |
688 |
for (i = 0; i < symbol_count; i++) |
for (i = 0; i < symbol_count; i++) |
689 |
if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) != 0 |
if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) != 0 |
746 |
} |
} |
747 |
obj_conv_table_size (bfd_ptr) = native_index; |
obj_conv_table_size (bfd_ptr) = native_index; |
748 |
|
|
749 |
return true; |
return TRUE; |
750 |
} |
} |
751 |
|
|
752 |
/* Run thorough the symbol table again, and fix it so that all |
/* Run thorough the symbol table again, and fix it so that all |
941 |
|
|
942 |
/* Write a symbol out to a COFF file. */ |
/* Write a symbol out to a COFF file. */ |
943 |
|
|
944 |
static boolean |
static bfd_boolean |
945 |
coff_write_symbol (abfd, symbol, native, written, string_size_p, |
coff_write_symbol (abfd, symbol, native, written, string_size_p, |
946 |
debug_string_section_p, debug_string_size_p) |
debug_string_section_p, debug_string_size_p) |
947 |
bfd *abfd; |
bfd *abfd; |
986 |
symesz = bfd_coff_symesz (abfd); |
symesz = bfd_coff_symesz (abfd); |
987 |
buf = bfd_alloc (abfd, symesz); |
buf = bfd_alloc (abfd, symesz); |
988 |
if (!buf) |
if (!buf) |
989 |
return false; |
return FALSE; |
990 |
bfd_coff_swap_sym_out (abfd, &native->u.syment, buf); |
bfd_coff_swap_sym_out (abfd, &native->u.syment, buf); |
991 |
if (bfd_bwrite (buf, symesz, abfd) != symesz) |
if (bfd_bwrite (buf, symesz, abfd) != symesz) |
992 |
return false; |
return FALSE; |
993 |
bfd_release (abfd, buf); |
bfd_release (abfd, buf); |
994 |
|
|
995 |
if (native->u.syment.n_numaux > 0) |
if (native->u.syment.n_numaux > 0) |
1000 |
auxesz = bfd_coff_auxesz (abfd); |
auxesz = bfd_coff_auxesz (abfd); |
1001 |
buf = bfd_alloc (abfd, auxesz); |
buf = bfd_alloc (abfd, auxesz); |
1002 |
if (!buf) |
if (!buf) |
1003 |
return false; |
return FALSE; |
1004 |
for (j = 0; j < native->u.syment.n_numaux; j++) |
for (j = 0; j < native->u.syment.n_numaux; j++) |
1005 |
{ |
{ |
1006 |
bfd_coff_swap_aux_out (abfd, |
bfd_coff_swap_aux_out (abfd, |
1011 |
native->u.syment.n_numaux, |
native->u.syment.n_numaux, |
1012 |
buf); |
buf); |
1013 |
if (bfd_bwrite (buf, auxesz, abfd) != auxesz) |
if (bfd_bwrite (buf, auxesz, abfd) != auxesz) |
1014 |
return false; |
return FALSE; |
1015 |
} |
} |
1016 |
bfd_release (abfd, buf); |
bfd_release (abfd, buf); |
1017 |
} |
} |
1020 |
set_index (symbol, *written); |
set_index (symbol, *written); |
1021 |
|
|
1022 |
*written += numaux + 1; |
*written += numaux + 1; |
1023 |
return true; |
return TRUE; |
1024 |
} |
} |
1025 |
|
|
1026 |
/* Write out a symbol to a COFF file that does not come from a COFF |
/* Write out a symbol to a COFF file that does not come from a COFF |
1027 |
file originally. This symbol may have been created by the linker, |
file originally. This symbol may have been created by the linker, |
1028 |
or we may be linking a non COFF file to a COFF file. */ |
or we may be linking a non COFF file to a COFF file. */ |
1029 |
|
|
1030 |
static boolean |
static bfd_boolean |
1031 |
coff_write_alien_symbol (abfd, symbol, written, string_size_p, |
coff_write_alien_symbol (abfd, symbol, written, string_size_p, |
1032 |
debug_string_section_p, debug_string_size_p) |
debug_string_section_p, debug_string_size_p) |
1033 |
bfd *abfd; |
bfd *abfd; |
1060 |
format. So, we just ignore them. We must clobber the symbol |
format. So, we just ignore them. We must clobber the symbol |
1061 |
name to keep it from being put in the string table. */ |
name to keep it from being put in the string table. */ |
1062 |
symbol->name = ""; |
symbol->name = ""; |
1063 |
return true; |
return TRUE; |
1064 |
} |
} |
1065 |
else |
else |
1066 |
{ |
{ |
1095 |
|
|
1096 |
/* Write a native symbol to a COFF file. */ |
/* Write a native symbol to a COFF file. */ |
1097 |
|
|
1098 |
static boolean |
static bfd_boolean |
1099 |
coff_write_native_symbol (abfd, symbol, written, string_size_p, |
coff_write_native_symbol (abfd, symbol, written, string_size_p, |
1100 |
debug_string_section_p, debug_string_size_p) |
debug_string_section_p, debug_string_size_p) |
1101 |
bfd *abfd; |
bfd *abfd; |
1127 |
count++; |
count++; |
1128 |
while (lineno[count].line_number != 0) |
while (lineno[count].line_number != 0) |
1129 |
{ |
{ |
|
#if 0 |
|
|
/* 13 april 92. sac |
|
|
I've been told this, but still need proof: |
|
|
> The second bug is also in `bfd/coffcode.h'. This bug |
|
|
> causes the linker to screw up the pc-relocations for |
|
|
> all the line numbers in COFF code. This bug isn't only |
|
|
> specific to A29K implementations, but affects all |
|
|
> systems using COFF format binaries. Note that in COFF |
|
|
> object files, the line number core offsets output by |
|
|
> the assembler are relative to the start of each |
|
|
> procedure, not to the start of the .text section. This |
|
|
> patch relocates the line numbers relative to the |
|
|
> `native->u.syment.n_value' instead of the section |
|
|
> virtual address. |
|
|
> modular!olson@cs.arizona.edu (Jon Olson) |
|
|
*/ |
|
|
lineno[count].u.offset += native->u.syment.n_value; |
|
|
#else |
|
1130 |
lineno[count].u.offset += |
lineno[count].u.offset += |
1131 |
(symbol->symbol.section->output_section->vma |
(symbol->symbol.section->output_section->vma |
1132 |
+ symbol->symbol.section->output_offset); |
+ symbol->symbol.section->output_offset); |
|
#endif |
|
1133 |
count++; |
count++; |
1134 |
} |
} |
1135 |
symbol->done_lineno = true; |
symbol->done_lineno = TRUE; |
1136 |
|
|
1137 |
if (! bfd_is_const_section (symbol->symbol.section->output_section)) |
if (! bfd_is_const_section (symbol->symbol.section->output_section)) |
1138 |
symbol->symbol.section->output_section->moving_line_filepos += |
symbol->symbol.section->output_section->moving_line_filepos += |
1146 |
|
|
1147 |
/* Write out the COFF symbols. */ |
/* Write out the COFF symbols. */ |
1148 |
|
|
1149 |
boolean |
bfd_boolean |
1150 |
coff_write_symbols (abfd) |
coff_write_symbols (abfd) |
1151 |
bfd *abfd; |
bfd *abfd; |
1152 |
{ |
{ |
1155 |
bfd_size_type debug_string_size; |
bfd_size_type debug_string_size; |
1156 |
unsigned int i; |
unsigned int i; |
1157 |
unsigned int limit = bfd_get_symcount (abfd); |
unsigned int limit = bfd_get_symcount (abfd); |
1158 |
bfd_signed_vma written = 0; |
bfd_vma written = 0; |
1159 |
asymbol **p; |
asymbol **p; |
1160 |
|
|
1161 |
string_size = 0; |
string_size = 0; |
1182 |
|
|
1183 |
/* Seek to the right place */ |
/* Seek to the right place */ |
1184 |
if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0) |
if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0) |
1185 |
return false; |
return FALSE; |
1186 |
|
|
1187 |
/* Output all the symbols we have */ |
/* Output all the symbols we have */ |
1188 |
|
|
1198 |
if (!coff_write_alien_symbol (abfd, symbol, &written, &string_size, |
if (!coff_write_alien_symbol (abfd, symbol, &written, &string_size, |
1199 |
&debug_string_section, |
&debug_string_section, |
1200 |
&debug_string_size)) |
&debug_string_size)) |
1201 |
return false; |
return FALSE; |
1202 |
} |
} |
1203 |
else |
else |
1204 |
{ |
{ |
1205 |
if (!coff_write_native_symbol (abfd, c_symbol, &written, |
if (!coff_write_native_symbol (abfd, c_symbol, &written, |
1206 |
&string_size, &debug_string_section, |
&string_size, &debug_string_section, |
1207 |
&debug_string_size)) |
&debug_string_size)) |
1208 |
return false; |
return FALSE; |
1209 |
} |
} |
1210 |
} |
} |
1211 |
|
|
1225 |
#endif |
#endif |
1226 |
if (bfd_bwrite ((PTR) buffer, (bfd_size_type) sizeof (buffer), abfd) |
if (bfd_bwrite ((PTR) buffer, (bfd_size_type) sizeof (buffer), abfd) |
1227 |
!= sizeof (buffer)) |
!= sizeof (buffer)) |
1228 |
return false; |
return FALSE; |
1229 |
|
|
1230 |
/* Handle long section names. This code must handle section |
/* Handle long section names. This code must handle section |
1231 |
names just as they are handled in coff_write_object_contents. */ |
names just as they are handled in coff_write_object_contents. */ |
1242 |
{ |
{ |
1243 |
if (bfd_bwrite (o->name, (bfd_size_type) (len + 1), abfd) |
if (bfd_bwrite (o->name, (bfd_size_type) (len + 1), abfd) |
1244 |
!= len + 1) |
!= len + 1) |
1245 |
return false; |
return FALSE; |
1246 |
} |
} |
1247 |
} |
} |
1248 |
} |
} |
1283 |
if (bfd_coff_force_symnames_in_strings (abfd)) |
if (bfd_coff_force_symnames_in_strings (abfd)) |
1284 |
{ |
{ |
1285 |
if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6) |
if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6) |
1286 |
return false; |
return FALSE; |
1287 |
} |
} |
1288 |
maxlen = bfd_coff_filnmlen (abfd); |
maxlen = bfd_coff_filnmlen (abfd); |
1289 |
} |
} |
1294 |
{ |
{ |
1295 |
if (bfd_bwrite ((PTR) (q->name), (bfd_size_type) name_length + 1, |
if (bfd_bwrite ((PTR) (q->name), (bfd_size_type) name_length + 1, |
1296 |
abfd) != name_length + 1) |
abfd) != name_length + 1) |
1297 |
return false; |
return FALSE; |
1298 |
} |
} |
1299 |
} |
} |
1300 |
} |
} |
1313 |
#endif |
#endif |
1314 |
if (bfd_bwrite ((PTR) buffer, (bfd_size_type) STRING_SIZE_SIZE, abfd) |
if (bfd_bwrite ((PTR) buffer, (bfd_size_type) STRING_SIZE_SIZE, abfd) |
1315 |
!= STRING_SIZE_SIZE) |
!= STRING_SIZE_SIZE) |
1316 |
return false; |
return FALSE; |
1317 |
} |
} |
1318 |
|
|
1319 |
/* Make sure the .debug section was created to be the correct size. |
/* Make sure the .debug section was created to be the correct size. |
1325 |
|| (debug_string_section != (asection *) NULL |
|| (debug_string_section != (asection *) NULL |
1326 |
&& (BFD_ALIGN (debug_string_size, |
&& (BFD_ALIGN (debug_string_size, |
1327 |
1 << debug_string_section->alignment_power) |
1 << debug_string_section->alignment_power) |
1328 |
== bfd_section_size (abfd, debug_string_section)))); |
== debug_string_section->size))); |
1329 |
|
|
1330 |
return true; |
return TRUE; |
1331 |
} |
} |
1332 |
|
|
1333 |
boolean |
bfd_boolean |
1334 |
coff_write_linenumbers (abfd) |
coff_write_linenumbers (abfd) |
1335 |
bfd *abfd; |
bfd *abfd; |
1336 |
{ |
{ |
1341 |
linesz = bfd_coff_linesz (abfd); |
linesz = bfd_coff_linesz (abfd); |
1342 |
buff = bfd_alloc (abfd, linesz); |
buff = bfd_alloc (abfd, linesz); |
1343 |
if (!buff) |
if (!buff) |
1344 |
return false; |
return FALSE; |
1345 |
for (s = abfd->sections; s != (asection *) NULL; s = s->next) |
for (s = abfd->sections; s != (asection *) NULL; s = s->next) |
1346 |
{ |
{ |
1347 |
if (s->lineno_count) |
if (s->lineno_count) |
1348 |
{ |
{ |
1349 |
asymbol **q = abfd->outsymbols; |
asymbol **q = abfd->outsymbols; |
1350 |
if (bfd_seek (abfd, s->line_filepos, SEEK_SET) != 0) |
if (bfd_seek (abfd, s->line_filepos, SEEK_SET) != 0) |
1351 |
return false; |
return FALSE; |
1352 |
/* Find all the linenumbers in this section */ |
/* Find all the linenumbers in this section */ |
1353 |
while (*q) |
while (*q) |
1354 |
{ |
{ |
1368 |
bfd_coff_swap_lineno_out (abfd, &out, buff); |
bfd_coff_swap_lineno_out (abfd, &out, buff); |
1369 |
if (bfd_bwrite (buff, (bfd_size_type) linesz, abfd) |
if (bfd_bwrite (buff, (bfd_size_type) linesz, abfd) |
1370 |
!= linesz) |
!= linesz) |
1371 |
return false; |
return FALSE; |
1372 |
l++; |
l++; |
1373 |
while (l->line_number) |
while (l->line_number) |
1374 |
{ |
{ |
1377 |
bfd_coff_swap_lineno_out (abfd, &out, buff); |
bfd_coff_swap_lineno_out (abfd, &out, buff); |
1378 |
if (bfd_bwrite (buff, (bfd_size_type) linesz, abfd) |
if (bfd_bwrite (buff, (bfd_size_type) linesz, abfd) |
1379 |
!= linesz) |
!= linesz) |
1380 |
return false; |
return FALSE; |
1381 |
l++; |
l++; |
1382 |
} |
} |
1383 |
} |
} |
1387 |
} |
} |
1388 |
} |
} |
1389 |
bfd_release (abfd, buff); |
bfd_release (abfd, buff); |
1390 |
return true; |
return TRUE; |
1391 |
} |
} |
1392 |
|
|
1393 |
alent * |
alent * |
1398 |
return coffsymbol (symbol)->lineno; |
return coffsymbol (symbol)->lineno; |
1399 |
} |
} |
1400 |
|
|
|
#if 0 |
|
|
|
|
|
/* This is only called from coff_add_missing_symbols, which has been |
|
|
disabled. */ |
|
|
|
|
|
asymbol * |
|
|
coff_section_symbol (abfd, name) |
|
|
bfd *abfd; |
|
|
char *name; |
|
|
{ |
|
|
asection *sec = bfd_make_section_old_way (abfd, name); |
|
|
asymbol *sym; |
|
|
combined_entry_type *csym; |
|
|
|
|
|
sym = sec->symbol; |
|
|
csym = coff_symbol_from (abfd, sym)->native; |
|
|
/* Make sure back-end COFF stuff is there. */ |
|
|
if (csym == 0) |
|
|
{ |
|
|
struct foo |
|
|
{ |
|
|
coff_symbol_type sym; |
|
|
/* @@FIXME This shouldn't use a fixed size!! */ |
|
|
combined_entry_type e[10]; |
|
|
}; |
|
|
struct foo *f; |
|
|
|
|
|
f = (struct foo *) bfd_zalloc (abfd, (bfd_size_type) sizeof (*f)); |
|
|
if (!f) |
|
|
{ |
|
|
bfd_set_error (bfd_error_no_error); |
|
|
return NULL; |
|
|
} |
|
|
coff_symbol_from (abfd, sym)->native = csym = f->e; |
|
|
} |
|
|
csym[0].u.syment.n_sclass = C_STAT; |
|
|
csym[0].u.syment.n_numaux = 1; |
|
|
/* SF_SET_STATICS (sym); @@ ??? */ |
|
|
csym[1].u.auxent.x_scn.x_scnlen = sec->_raw_size; |
|
|
csym[1].u.auxent.x_scn.x_nreloc = sec->reloc_count; |
|
|
csym[1].u.auxent.x_scn.x_nlinno = sec->lineno_count; |
|
|
|
|
|
if (sec->output_section == NULL) |
|
|
{ |
|
|
sec->output_section = sec; |
|
|
sec->output_offset = 0; |
|
|
} |
|
|
|
|
|
return sym; |
|
|
} |
|
|
|
|
|
#endif /* 0 */ |
|
|
|
|
1401 |
/* This function transforms the offsets into the symbol table into |
/* This function transforms the offsets into the symbol table into |
1402 |
pointers to syments. */ |
pointers to syments. */ |
1403 |
|
|
1465 |
return NULL; |
return NULL; |
1466 |
} |
} |
1467 |
|
|
1468 |
sec_size = bfd_get_section_size_before_reloc (sect); |
sec_size = sect->size; |
1469 |
debug_section = (PTR) bfd_alloc (abfd, sec_size); |
debug_section = (PTR) bfd_alloc (abfd, sec_size); |
1470 |
if (debug_section == NULL) |
if (debug_section == NULL) |
1471 |
return NULL; |
return NULL; |
1511 |
|
|
1512 |
/* Read in the external symbols. */ |
/* Read in the external symbols. */ |
1513 |
|
|
1514 |
boolean |
bfd_boolean |
1515 |
_bfd_coff_get_external_symbols (abfd) |
_bfd_coff_get_external_symbols (abfd) |
1516 |
bfd *abfd; |
bfd *abfd; |
1517 |
{ |
{ |
1520 |
PTR syms; |
PTR syms; |
1521 |
|
|
1522 |
if (obj_coff_external_syms (abfd) != NULL) |
if (obj_coff_external_syms (abfd) != NULL) |
1523 |
return true; |
return TRUE; |
1524 |
|
|
1525 |
symesz = bfd_coff_symesz (abfd); |
symesz = bfd_coff_symesz (abfd); |
1526 |
|
|
1528 |
|
|
1529 |
syms = (PTR) bfd_malloc (size); |
syms = (PTR) bfd_malloc (size); |
1530 |
if (syms == NULL && size != 0) |
if (syms == NULL && size != 0) |
1531 |
return false; |
return FALSE; |
1532 |
|
|
1533 |
if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0 |
if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0 |
1534 |
|| bfd_bread (syms, size, abfd) != size) |
|| bfd_bread (syms, size, abfd) != size) |
1535 |
{ |
{ |
1536 |
if (syms != NULL) |
if (syms != NULL) |
1537 |
free (syms); |
free (syms); |
1538 |
return false; |
return FALSE; |
1539 |
} |
} |
1540 |
|
|
1541 |
obj_coff_external_syms (abfd) = syms; |
obj_coff_external_syms (abfd) = syms; |
1542 |
|
|
1543 |
return true; |
return TRUE; |
1544 |
} |
} |
1545 |
|
|
1546 |
/* Read in the external strings. The strings are not loaded until |
/* Read in the external strings. The strings are not loaded until |
1591 |
if (strsize < STRING_SIZE_SIZE) |
if (strsize < STRING_SIZE_SIZE) |
1592 |
{ |
{ |
1593 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
1594 |
(_("%s: bad string table size %lu"), bfd_archive_filename (abfd), |
(_("%B: bad string table size %lu"), abfd, (unsigned long) strsize); |
|
(unsigned long) strsize); |
|
1595 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
1596 |
return NULL; |
return NULL; |
1597 |
} |
} |
1614 |
|
|
1615 |
/* Free up the external symbols and strings read from a COFF file. */ |
/* Free up the external symbols and strings read from a COFF file. */ |
1616 |
|
|
1617 |
boolean |
bfd_boolean |
1618 |
_bfd_coff_free_symbols (abfd) |
_bfd_coff_free_symbols (abfd) |
1619 |
bfd *abfd; |
bfd *abfd; |
1620 |
{ |
{ |
1630 |
free (obj_coff_strings (abfd)); |
free (obj_coff_strings (abfd)); |
1631 |
obj_coff_strings (abfd) = NULL; |
obj_coff_strings (abfd) = NULL; |
1632 |
} |
} |
1633 |
return true; |
return TRUE; |
1634 |
} |
} |
1635 |
|
|
1636 |
/* Read a symbol table into freshly bfd_allocated memory, swap it, and |
/* Read a symbol table into freshly bfd_allocated memory, swap it, and |
1702 |
} |
} |
1703 |
|
|
1704 |
/* Free the raw symbols, but not the strings (if we have them). */ |
/* Free the raw symbols, but not the strings (if we have them). */ |
1705 |
obj_coff_keep_strings (abfd) = true; |
obj_coff_keep_strings (abfd) = TRUE; |
1706 |
if (! _bfd_coff_free_symbols (abfd)) |
if (! _bfd_coff_free_symbols (abfd)) |
1707 |
return NULL; |
return NULL; |
1708 |
|
|
1834 |
new->symbol.section = 0; |
new->symbol.section = 0; |
1835 |
new->native = 0; |
new->native = 0; |
1836 |
new->lineno = (alent *) NULL; |
new->lineno = (alent *) NULL; |
1837 |
new->done_lineno = false; |
new->done_lineno = FALSE; |
1838 |
new->symbol.the_bfd = abfd; |
new->symbol.the_bfd = abfd; |
1839 |
return &new->symbol; |
return &new->symbol; |
1840 |
} |
} |
1860 |
new->symbol.section = bfd_abs_section_ptr; |
new->symbol.section = bfd_abs_section_ptr; |
1861 |
new->symbol.flags = BSF_DEBUGGING; |
new->symbol.flags = BSF_DEBUGGING; |
1862 |
new->lineno = (alent *) NULL; |
new->lineno = (alent *) NULL; |
1863 |
new->done_lineno = false; |
new->done_lineno = FALSE; |
1864 |
new->symbol.the_bfd = abfd; |
new->symbol.the_bfd = abfd; |
1865 |
return &new->symbol; |
return &new->symbol; |
1866 |
} |
} |
1882 |
|
|
1883 |
/* Return the COFF syment for a symbol. */ |
/* Return the COFF syment for a symbol. */ |
1884 |
|
|
1885 |
boolean |
bfd_boolean |
1886 |
bfd_coff_get_syment (abfd, symbol, psyment) |
bfd_coff_get_syment (abfd, symbol, psyment) |
1887 |
bfd *abfd; |
bfd *abfd; |
1888 |
asymbol *symbol; |
asymbol *symbol; |
1894 |
if (csym == NULL || csym->native == NULL) |
if (csym == NULL || csym->native == NULL) |
1895 |
{ |
{ |
1896 |
bfd_set_error (bfd_error_invalid_operation); |
bfd_set_error (bfd_error_invalid_operation); |
1897 |
return false; |
return FALSE; |
1898 |
} |
} |
1899 |
|
|
1900 |
*psyment = csym->native->u.syment; |
*psyment = csym->native->u.syment; |
1905 |
|
|
1906 |
/* FIXME: We should handle fix_line here. */ |
/* FIXME: We should handle fix_line here. */ |
1907 |
|
|
1908 |
return true; |
return TRUE; |
1909 |
} |
} |
1910 |
|
|
1911 |
/* Return the COFF auxent for a symbol. */ |
/* Return the COFF auxent for a symbol. */ |
1912 |
|
|
1913 |
boolean |
bfd_boolean |
1914 |
bfd_coff_get_auxent (abfd, symbol, indx, pauxent) |
bfd_coff_get_auxent (abfd, symbol, indx, pauxent) |
1915 |
bfd *abfd; |
bfd *abfd; |
1916 |
asymbol *symbol; |
asymbol *symbol; |
1927 |
|| indx >= csym->native->u.syment.n_numaux) |
|| indx >= csym->native->u.syment.n_numaux) |
1928 |
{ |
{ |
1929 |
bfd_set_error (bfd_error_invalid_operation); |
bfd_set_error (bfd_error_invalid_operation); |
1930 |
return false; |
return FALSE; |
1931 |
} |
} |
1932 |
|
|
1933 |
ent = csym->native + indx + 1; |
ent = csym->native + indx + 1; |
1949 |
((combined_entry_type *) pauxent->x_csect.x_scnlen.p |
((combined_entry_type *) pauxent->x_csect.x_scnlen.p |
1950 |
- obj_raw_syments (abfd)); |
- obj_raw_syments (abfd)); |
1951 |
|
|
1952 |
return true; |
return TRUE; |
1953 |
} |
} |
1954 |
|
|
1955 |
/* Print out information about COFF symbol. */ |
/* Print out information about COFF symbol. */ |
2116 |
function for the is_local_label_name entry point, but some may |
function for the is_local_label_name entry point, but some may |
2117 |
override it. */ |
override it. */ |
2118 |
|
|
2119 |
boolean |
bfd_boolean |
2120 |
_bfd_coff_is_local_label_name (abfd, name) |
_bfd_coff_is_local_label_name (abfd, name) |
2121 |
bfd *abfd ATTRIBUTE_UNUSED; |
bfd *abfd ATTRIBUTE_UNUSED; |
2122 |
const char *name; |
const char *name; |
2128 |
section, calculate and return the name of the source file and the line |
section, calculate and return the name of the source file and the line |
2129 |
nearest to the wanted location. */ |
nearest to the wanted location. */ |
2130 |
|
|
2131 |
boolean |
bfd_boolean |
2132 |
coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr, |
coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr, |
2133 |
functionname_ptr, line_ptr) |
functionname_ptr, line_ptr) |
2134 |
bfd *abfd; |
bfd *abfd; |
2139 |
const char **functionname_ptr; |
const char **functionname_ptr; |
2140 |
unsigned int *line_ptr; |
unsigned int *line_ptr; |
2141 |
{ |
{ |
2142 |
boolean found; |
bfd_boolean found; |
2143 |
unsigned int i; |
unsigned int i; |
2144 |
unsigned int line_base; |
unsigned int line_base; |
2145 |
coff_data_type *cof = coff_data (abfd); |
coff_data_type *cof = coff_data (abfd); |
2156 |
&found, filename_ptr, |
&found, filename_ptr, |
2157 |
functionname_ptr, line_ptr, |
functionname_ptr, line_ptr, |
2158 |
&coff_data(abfd)->line_info)) |
&coff_data(abfd)->line_info)) |
2159 |
return false; |
return FALSE; |
2160 |
|
|
2161 |
if (found) |
if (found) |
2162 |
return true; |
return TRUE; |
2163 |
|
|
2164 |
/* Also try examining DWARF2 debugging information. */ |
/* Also try examining DWARF2 debugging information. */ |
2165 |
if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset, |
if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset, |
2166 |
filename_ptr, functionname_ptr, |
filename_ptr, functionname_ptr, |
2167 |
line_ptr, 0, |
line_ptr, 0, |
2168 |
&coff_data(abfd)->dwarf2_find_line_info)) |
&coff_data(abfd)->dwarf2_find_line_info)) |
2169 |
return true; |
return TRUE; |
2170 |
|
|
2171 |
*filename_ptr = 0; |
*filename_ptr = 0; |
2172 |
*functionname_ptr = 0; |
*functionname_ptr = 0; |
2174 |
|
|
2175 |
/* Don't try and find line numbers in a non coff file */ |
/* Don't try and find line numbers in a non coff file */ |
2176 |
if (!bfd_family_coff (abfd)) |
if (!bfd_family_coff (abfd)) |
2177 |
return false; |
return FALSE; |
2178 |
|
|
2179 |
if (cof == NULL) |
if (cof == NULL) |
2180 |
return false; |
return FALSE; |
2181 |
|
|
2182 |
/* Find the first C_FILE symbol. */ |
/* Find the first C_FILE symbol. */ |
2183 |
p = cof->raw_syments; |
p = cof->raw_syments; |
2184 |
if (!p) |
if (!p) |
2185 |
return false; |
return FALSE; |
2186 |
|
|
2187 |
pend = p + cof->raw_syment_count; |
pend = p + cof->raw_syment_count; |
2188 |
while (p < pend) |
while (p < pend) |
2335 |
sec_data->line_base = line_base; |
sec_data->line_base = line_base; |
2336 |
} |
} |
2337 |
|
|
2338 |
return true; |
return TRUE; |
2339 |
} |
} |
2340 |
|
|
2341 |
int |
int |
2342 |
coff_sizeof_headers (abfd, reloc) |
coff_sizeof_headers (abfd, reloc) |
2343 |
bfd *abfd; |
bfd *abfd; |
2344 |
boolean reloc; |
bfd_boolean reloc; |
2345 |
{ |
{ |
2346 |
size_t size; |
size_t size; |
2347 |
|
|
2359 |
} |
} |
2360 |
|
|
2361 |
/* Change the class of a coff symbol held by BFD. */ |
/* Change the class of a coff symbol held by BFD. */ |
2362 |
boolean |
bfd_boolean |
2363 |
bfd_coff_set_symbol_class (abfd, symbol, class) |
bfd_coff_set_symbol_class (abfd, symbol, class) |
2364 |
bfd * abfd; |
bfd * abfd; |
2365 |
asymbol * symbol; |
asymbol * symbol; |
2371 |
if (csym == NULL) |
if (csym == NULL) |
2372 |
{ |
{ |
2373 |
bfd_set_error (bfd_error_invalid_operation); |
bfd_set_error (bfd_error_invalid_operation); |
2374 |
return false; |
return FALSE; |
2375 |
} |
} |
2376 |
else if (csym->native == NULL) |
else if (csym->native == NULL) |
2377 |
{ |
{ |
2385 |
|
|
2386 |
native = (combined_entry_type *) bfd_zalloc (abfd, amt); |
native = (combined_entry_type *) bfd_zalloc (abfd, amt); |
2387 |
if (native == NULL) |
if (native == NULL) |
2388 |
return false; |
return FALSE; |
2389 |
|
|
2390 |
native->u.syment.n_type = T_NULL; |
native->u.syment.n_type = T_NULL; |
2391 |
native->u.syment.n_sclass = class; |
native->u.syment.n_sclass = class; |
2421 |
csym->native->u.syment.n_sclass = class; |
csym->native->u.syment.n_sclass = class; |
2422 |
} |
} |
2423 |
|
|
2424 |
return true; |
return TRUE; |
2425 |
|
} |
2426 |
|
|
2427 |
|
struct coff_comdat_info * |
2428 |
|
bfd_coff_get_comdat_section (bfd *abfd, struct bfd_section *sec) |
2429 |
|
{ |
2430 |
|
if (bfd_get_flavour (abfd) == bfd_target_coff_flavour |
2431 |
|
&& coff_section_data (abfd, sec) != NULL) |
2432 |
|
return coff_section_data (abfd, sec)->comdat; |
2433 |
|
else |
2434 |
|
return NULL; |
2435 |
} |
} |