X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=bfd%2Fcoffgen.c;h=0faaede68fd7a27c10433c04046f44bcc9a04f6d;hb=c7c7219d3a06a714e04e73ebd029811e6bd5bd37;hp=f2410d919d9a256c773abc5b8fd4fa870d07b53d;hpb=abd8680d6efd97e7ba848a6392ee3ad72be18cd0;p=binutils-gdb.git diff --git a/bfd/coffgen.c b/bfd/coffgen.c index f2410d919d9..0faaede68fd 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -1,23 +1,25 @@ /* Support for the generic parts of COFF, for BFD. - Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999, 2000 + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. Written by Cygnus Support. -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ /* Most of this hacked by Steve Chamberlain, sac@cygnus.com. Split out of coffcode.h by Ian Taylor, ian@cygnus.com. */ @@ -36,56 +38,34 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ Those functions may not use any COFF specific information, such as coff_data (abfd). */ -#include "bfd.h" #include "sysdep.h" +#include "bfd.h" #include "libbfd.h" #include "coff/internal.h" #include "libcoff.h" -static void coff_fix_symbol_name - PARAMS ((bfd *, asymbol *, combined_entry_type *, bfd_size_type *, - asection **, bfd_size_type *)); -static boolean coff_write_symbol - PARAMS ((bfd *, asymbol *, combined_entry_type *, unsigned int *, - bfd_size_type *, asection **, bfd_size_type *)); -static boolean coff_write_alien_symbol - PARAMS ((bfd *, asymbol *, unsigned int *, bfd_size_type *, - asection **, bfd_size_type *)); -static boolean coff_write_native_symbol - PARAMS ((bfd *, coff_symbol_type *, unsigned int *, bfd_size_type *, - asection **, bfd_size_type *)); -static void coff_pointerize_aux - PARAMS ((bfd *, combined_entry_type *, combined_entry_type *, - unsigned int, combined_entry_type *)); -static boolean make_a_section_from_file - PARAMS ((bfd *, struct internal_scnhdr *, unsigned int)); -static const bfd_target *coff_real_object_p - PARAMS ((bfd *, unsigned, struct internal_filehdr *, - struct internal_aouthdr *)); -static void fixup_symbol_value - PARAMS ((bfd *, coff_symbol_type *, struct internal_syment *)); -static char *build_debug_section - PARAMS ((bfd *)); -static char *copy_name - PARAMS ((bfd *, char *, int)); - -#define STRING_SIZE_SIZE (4) - /* Take a section header read from a coff file (in HOST byte order), and make a BFD "section" out of it. This is used by ECOFF. */ -static boolean -make_a_section_from_file (abfd, hdr, target_index) - bfd *abfd; - struct internal_scnhdr *hdr; - unsigned int target_index; + +static bfd_boolean +make_a_section_from_file (bfd *abfd, + struct internal_scnhdr *hdr, + unsigned int target_index) { asection *return_section; char *name; + bfd_boolean result = TRUE; + flagword flags; name = NULL; - /* Handle long section names as in PE. */ - if (bfd_coff_long_section_names (abfd) + /* Handle long section names as in PE. On reading, we want to + accept long names if the format permits them at all, regardless + of the current state of the flag that dictates if we would generate + them in outputs; this construct checks if that is the case by + attempting to set the flag, without changing its state; the call + will fail for formats that do not support long names at all. */ + if (bfd_coff_set_long_section_names (abfd, bfd_coff_long_section_names (abfd)) && hdr->s_name[0] == '/') { char buf[SCNNMLEN]; @@ -100,14 +80,14 @@ make_a_section_from_file (abfd, hdr, target_index) { strings = _bfd_coff_read_string_table (abfd); if (strings == NULL) - return false; + return FALSE; /* FIXME: For extra safety, we should make sure that strindex does not run us past the end, but right now we don't know the length of the string table. */ strings += strindex; - name = bfd_alloc (abfd, strlen (strings) + 1); + name = bfd_alloc (abfd, (bfd_size_type) strlen (strings) + 1); if (name == NULL) - return false; + return FALSE; strcpy (name, strings); } } @@ -115,20 +95,20 @@ make_a_section_from_file (abfd, hdr, target_index) if (name == NULL) { /* Assorted wastage to null-terminate the name, thanks AT&T! */ - name = bfd_alloc (abfd, sizeof (hdr->s_name) + 1); + name = bfd_alloc (abfd, (bfd_size_type) sizeof (hdr->s_name) + 1); if (name == NULL) - return false; + return FALSE; strncpy (name, (char *) &hdr->s_name[0], sizeof (hdr->s_name)); name[sizeof (hdr->s_name)] = 0; } return_section = bfd_make_section_anyway (abfd, name); if (return_section == NULL) - return false; + return FALSE; return_section->vma = hdr->s_vaddr; return_section->lma = hdr->s_paddr; - return_section->_raw_size = hdr->s_size; + return_section->size = hdr->s_size; return_section->filepos = hdr->s_scnptr; return_section->rel_filepos = hdr->s_relptr; return_section->reloc_count = hdr->s_nreloc; @@ -139,10 +119,14 @@ make_a_section_from_file (abfd, hdr, target_index) return_section->lineno_count = hdr->s_nlnno; return_section->userdata = NULL; - return_section->next = (asection *) NULL; + return_section->next = NULL; return_section->target_index = target_index; - return_section->flags = 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, + & flags)) + result = FALSE; + + return_section->flags = flags; /* At least on i386-coff, the line number count for a shared library section must be ignored. */ @@ -151,26 +135,27 @@ make_a_section_from_file (abfd, hdr, target_index) if (hdr->s_nreloc != 0) return_section->flags |= SEC_RELOC; - /* FIXME: should this check 'hdr->s_size > 0' */ + /* FIXME: should this check 'hdr->s_size > 0'. */ if (hdr->s_scnptr != 0) return_section->flags |= SEC_HAS_CONTENTS; - return true; + + return result; } /* Read in a COFF object and make it into a BFD. This is used by ECOFF as well. */ static const bfd_target * -coff_real_object_p (abfd, nscns, internal_f, internal_a) - bfd *abfd; - unsigned nscns; - struct internal_filehdr *internal_f; - struct internal_aouthdr *internal_a; +coff_real_object_p (bfd *abfd, + unsigned nscns, + struct internal_filehdr *internal_f, + struct internal_aouthdr *internal_a) { flagword oflags = abfd->flags; bfd_vma ostart = bfd_get_start_address (abfd); - PTR tdata; - size_t readsize; /* length of file_info */ + void * tdata; + void * tdata_save; + bfd_size_type readsize; /* Length of file_info. */ unsigned int scnhsz; char *external_sections; @@ -198,25 +183,26 @@ coff_real_object_p (abfd, nscns, internal_f, internal_a) /* Set up the tdata area. ECOFF uses its own routine, and overrides abfd->flags. */ - tdata = bfd_coff_mkobject_hook (abfd, (PTR) internal_f, (PTR) internal_a); + tdata_save = abfd->tdata.any; + tdata = bfd_coff_mkobject_hook (abfd, (void *) internal_f, (void *) internal_a); if (tdata == NULL) - return 0; + goto fail2; scnhsz = bfd_coff_scnhsz (abfd); - readsize = nscns * scnhsz; - external_sections = (char *) bfd_alloc (abfd, readsize); + readsize = (bfd_size_type) nscns * scnhsz; + external_sections = bfd_alloc (abfd, readsize); if (!external_sections) goto fail; - if (bfd_read ((PTR) external_sections, 1, readsize, abfd) != readsize) + if (bfd_bread ((void *) external_sections, readsize, abfd) != readsize) goto fail; /* Set the arch/mach *before* swapping in sections; section header swapping - may depend on arch/mach info. */ - if (bfd_coff_set_arch_mach_hook (abfd, (PTR) internal_f) == false) + may depend on arch/mach info. */ + if (! bfd_coff_set_arch_mach_hook (abfd, (void *) internal_f)) goto fail; - /* Now copy data as required; construct all asections etc */ + /* Now copy data as required; construct all asections etc. */ if (nscns != 0) { unsigned int i; @@ -224,19 +210,19 @@ coff_real_object_p (abfd, nscns, internal_f, internal_a) { struct internal_scnhdr tmp; bfd_coff_swap_scnhdr_in (abfd, - (PTR) (external_sections + i * scnhsz), - (PTR) & tmp); + (void *) (external_sections + i * scnhsz), + (void *) & tmp); if (! make_a_section_from_file (abfd, &tmp, i + 1)) goto fail; } } - /* make_abs_section (abfd); */ - return abfd->xvec; fail: bfd_release (abfd, tdata); + fail2: + abfd->tdata.any = tdata_save; abfd->flags = oflags; bfd_get_start_address (abfd) = ostart; return (const bfd_target *) NULL; @@ -246,52 +232,63 @@ coff_real_object_p (abfd, nscns, internal_f, internal_a) not a COFF file. This is also used by ECOFF. */ const bfd_target * -coff_object_p (abfd) - bfd *abfd; +coff_object_p (bfd *abfd) { - unsigned int filhsz; - unsigned int aoutsz; - int nscns; - PTR filehdr; + bfd_size_type filhsz; + bfd_size_type aoutsz; + unsigned int nscns; + void * filehdr; struct internal_filehdr internal_f; struct internal_aouthdr internal_a; - /* figure out how much to read */ + /* Figure out how much to read. */ filhsz = bfd_coff_filhsz (abfd); aoutsz = bfd_coff_aoutsz (abfd); filehdr = bfd_alloc (abfd, filhsz); if (filehdr == NULL) - return 0; - if (bfd_read (filehdr, 1, filhsz, abfd) != filhsz) + return NULL; + if (bfd_bread (filehdr, filhsz, abfd) != filhsz) { if (bfd_get_error () != bfd_error_system_call) bfd_set_error (bfd_error_wrong_format); - return 0; + bfd_release (abfd, filehdr); + return NULL; } bfd_coff_swap_filehdr_in (abfd, filehdr, &internal_f); bfd_release (abfd, filehdr); - if (bfd_coff_bad_format_hook (abfd, &internal_f) == false) + /* The XCOFF format has two sizes for the f_opthdr. SMALL_AOUTSZ + (less than aoutsz) used in object files and AOUTSZ (equal to + aoutsz) in executables. The bfd_coff_swap_aouthdr_in function + expects this header to be aoutsz bytes in length, so we use that + value in the call to bfd_alloc below. But we must be careful to + only read in f_opthdr bytes in the call to bfd_bread. We should + also attempt to catch corrupt or non-COFF binaries with a strange + value for f_opthdr. */ + if (! bfd_coff_bad_format_hook (abfd, &internal_f) + || internal_f.f_opthdr > aoutsz) { bfd_set_error (bfd_error_wrong_format); - return 0; + return NULL; } nscns = internal_f.f_nscns; if (internal_f.f_opthdr) { - PTR opthdr; + void * opthdr; opthdr = bfd_alloc (abfd, aoutsz); if (opthdr == NULL) - return 0;; - if (bfd_read (opthdr, 1, internal_f.f_opthdr, abfd) + return NULL; + if (bfd_bread (opthdr, (bfd_size_type) internal_f.f_opthdr, abfd) != internal_f.f_opthdr) { - return 0; + bfd_release (abfd, opthdr); + return NULL; } - bfd_coff_swap_aouthdr_in (abfd, opthdr, (PTR) &internal_a); + bfd_coff_swap_aouthdr_in (abfd, opthdr, (void *) &internal_a); + bfd_release (abfd, opthdr); } return coff_real_object_p (abfd, nscns, &internal_f, @@ -303,11 +300,9 @@ coff_object_p (abfd) /* Get the BFD section from a COFF symbol section number. */ asection * -coff_section_from_bfd_index (abfd, index) - bfd *abfd; - int index; +coff_section_from_bfd_index (bfd *abfd, int index) { - struct sec *answer = abfd->sections; + struct bfd_section *answer = abfd->sections; if (index == N_ABS) return bfd_abs_section_ptr; @@ -331,8 +326,7 @@ coff_section_from_bfd_index (abfd, index) /* Get the upper bound of a COFF symbol table. */ long -coff_get_symtab_upper_bound (abfd) - bfd *abfd; +coff_get_symtab_upper_bound (bfd *abfd) { if (!bfd_coff_slurp_symbol_table (abfd)) return -1; @@ -340,13 +334,10 @@ coff_get_symtab_upper_bound (abfd) return (bfd_get_symcount (abfd) + 1) * (sizeof (coff_symbol_type *)); } - /* Canonicalize a COFF symbol table. */ long -coff_get_symtab (abfd, alocation) - bfd *abfd; - asymbol **alocation; +coff_canonicalize_symtab (bfd *abfd, asymbol **alocation) { unsigned int counter; coff_symbol_type *symbase; @@ -369,10 +360,9 @@ coff_get_symtab (abfd, alocation) >= SYMNMLEN + 1. */ const char * -_bfd_coff_internal_syment_name (abfd, sym, buf) - bfd *abfd; - const struct internal_syment *sym; - char *buf; +_bfd_coff_internal_syment_name (bfd *abfd, + const struct internal_syment *sym, + char *buf) { /* FIXME: It's not clear this will work correctly if sizeof (_n_zeroes) != 4. */ @@ -400,23 +390,21 @@ _bfd_coff_internal_syment_name (abfd, sym, buf) } /* Read in and swap the relocs. This returns a buffer holding the - relocs for section SEC in file ABFD. If CACHE is true and + relocs for section SEC in file ABFD. If CACHE is TRUE and INTERNAL_RELOCS is NULL, the relocs read in will be saved in case the function is called again. If EXTERNAL_RELOCS is not NULL, it is a buffer large enough to hold the unswapped relocs. If INTERNAL_RELOCS is not NULL, it is a buffer large enough to hold - the swapped relocs. If REQUIRE_INTERNAL is true, then the return + the swapped relocs. If REQUIRE_INTERNAL is TRUE, then the return value must be INTERNAL_RELOCS. The function returns NULL on error. */ struct internal_reloc * -_bfd_coff_read_internal_relocs (abfd, sec, cache, external_relocs, - require_internal, internal_relocs) - bfd *abfd; - asection *sec; - boolean cache; - bfd_byte *external_relocs; - boolean require_internal; - struct internal_reloc *internal_relocs; +_bfd_coff_read_internal_relocs (bfd *abfd, + asection *sec, + bfd_boolean cache, + bfd_byte *external_relocs, + bfd_boolean require_internal, + struct internal_reloc *internal_relocs) { bfd_size_type relsz; bfd_byte *free_external = NULL; @@ -424,6 +412,10 @@ _bfd_coff_read_internal_relocs (abfd, sec, cache, external_relocs, bfd_byte *erel; bfd_byte *erel_end; struct internal_reloc *irel; + bfd_size_type amt; + + if (sec->reloc_count == 0) + return internal_relocs; /* Nothing to do. */ if (coff_section_data (abfd, sec) != NULL && coff_section_data (abfd, sec)->relocs != NULL) @@ -437,25 +429,25 @@ _bfd_coff_read_internal_relocs (abfd, sec, cache, external_relocs, relsz = bfd_coff_relsz (abfd); + amt = sec->reloc_count * relsz; if (external_relocs == NULL) { - free_external = (bfd_byte *) bfd_malloc (sec->reloc_count * relsz); - if (free_external == NULL && sec->reloc_count > 0) + free_external = bfd_malloc (amt); + if (free_external == NULL) goto error_return; external_relocs = free_external; } if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0 - || (bfd_read (external_relocs, relsz, sec->reloc_count, abfd) - != relsz * sec->reloc_count)) + || bfd_bread (external_relocs, amt, abfd) != amt) goto error_return; if (internal_relocs == NULL) { - free_internal = ((struct internal_reloc *) - bfd_malloc (sec->reloc_count - * sizeof (struct internal_reloc))); - if (free_internal == NULL && sec->reloc_count > 0) + amt = sec->reloc_count; + amt *= sizeof (struct internal_reloc); + free_internal = bfd_malloc (amt); + if (free_internal == NULL) goto error_return; internal_relocs = free_internal; } @@ -465,7 +457,7 @@ _bfd_coff_read_internal_relocs (abfd, sec, cache, external_relocs, erel_end = erel + relsz * sec->reloc_count; irel = internal_relocs; for (; erel < erel_end; erel += relsz, irel++) - bfd_coff_swap_reloc_in (abfd, (PTR) erel, (PTR) irel); + bfd_coff_swap_reloc_in (abfd, (void *) erel, (void *) irel); if (free_external != NULL) { @@ -477,9 +469,8 @@ _bfd_coff_read_internal_relocs (abfd, sec, cache, external_relocs, { if (coff_section_data (abfd, sec) == NULL) { - sec->used_by_bfd = - (PTR) bfd_zalloc (abfd, - sizeof (struct coff_section_tdata)); + amt = sizeof (struct coff_section_tdata); + sec->used_by_bfd = bfd_zalloc (abfd, amt); if (sec->used_by_bfd == NULL) goto error_return; coff_section_data (abfd, sec)->contents = NULL; @@ -500,8 +491,7 @@ _bfd_coff_read_internal_relocs (abfd, sec, cache, external_relocs, /* Set lineno_count for the output sections of a COFF file. */ int -coff_count_linenumbers (abfd) - bfd *abfd; +coff_count_linenumbers (bfd *abfd) { unsigned int limit = bfd_get_symcount (abfd); unsigned int i; @@ -525,7 +515,7 @@ coff_count_linenumbers (abfd) { asymbol *q_maybe = *p; - if (bfd_asymbol_flavour (q_maybe) == bfd_target_coff_flavour) + if (bfd_family_coff (bfd_asymbol_bfd (q_maybe))) { coff_symbol_type *q = coffsymbol (q_maybe); @@ -539,15 +529,18 @@ coff_count_linenumbers (abfd) section's linenumber count. */ alent *l = q->lineno; - ++q->symbol.section->output_section->lineno_count; - ++total; - ++l; - while (l->line_number != 0) + do { + asection * sec = q->symbol.section->output_section; + + /* Do not try to update fields in read-only sections. */ + if (! bfd_is_const_section (sec)) + sec->lineno_count ++; + ++total; - ++q->symbol.section->output_section->lineno_count; ++l; } + while (l->line_number != 0); } } } @@ -558,13 +551,11 @@ coff_count_linenumbers (abfd) /* Takes a bfd and a symbol, returns a pointer to the coff specific area of the symbol if there is one. */ -/*ARGSUSED*/ coff_symbol_type * -coff_symbol_from (ignore_abfd, symbol) - bfd *ignore_abfd ATTRIBUTE_UNUSED; - asymbol *symbol; +coff_symbol_from (bfd *ignore_abfd ATTRIBUTE_UNUSED, + asymbol *symbol) { - if (bfd_asymbol_flavour (symbol) != bfd_target_coff_flavour) + if (!bfd_family_coff (bfd_asymbol_bfd (symbol))) return (coff_symbol_type *) NULL; if (bfd_asymbol_bfd (symbol)->tdata.coff_obj_data == (coff_data_type *) NULL) @@ -574,16 +565,15 @@ coff_symbol_from (ignore_abfd, symbol) } static void -fixup_symbol_value (abfd, coff_symbol_ptr, syment) - bfd *abfd; - coff_symbol_type *coff_symbol_ptr; - struct internal_syment *syment; +fixup_symbol_value (bfd *abfd, + coff_symbol_type *coff_symbol_ptr, + struct internal_syment *syment) { - - /* Normalize the symbol flags */ - if (bfd_is_com_section (coff_symbol_ptr->symbol.section)) + /* Normalize the symbol flags. */ + if (coff_symbol_ptr->symbol.section + && bfd_is_com_section (coff_symbol_ptr->symbol.section)) { - /* a common symbol is undefined with a value */ + /* A common symbol is undefined with a value. */ syment->n_scnum = N_UNDEF; syment->n_value = coff_symbol_ptr->symbol.value; } @@ -608,8 +598,11 @@ fixup_symbol_value (abfd, coff_symbol_ptr, syment) syment->n_value = (coff_symbol_ptr->symbol.value + coff_symbol_ptr->symbol.section->output_offset); if (! obj_pe (abfd)) - syment->n_value += - coff_symbol_ptr->symbol.section->output_section->vma; + { + syment->n_value += (syment->n_sclass == C_STATLAB) + ? coff_symbol_ptr->symbol.section->output_section->lma + : coff_symbol_ptr->symbol.section->output_section->vma; + } } else { @@ -628,15 +621,13 @@ fixup_symbol_value (abfd, coff_symbol_ptr, syment) chain, and that the last one points to the first external symbol. We do that here too. */ -boolean -coff_renumber_symbols (bfd_ptr, first_undef) - bfd *bfd_ptr; - int *first_undef; +bfd_boolean +coff_renumber_symbols (bfd *bfd_ptr, int *first_undef) { unsigned int symbol_count = bfd_get_symcount (bfd_ptr); asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols; unsigned int native_index = 0; - struct internal_syment *last_file = (struct internal_syment *) NULL; + struct internal_syment *last_file = NULL; unsigned int symbol_index; /* COFF demands that undefined symbols come after all other symbols. @@ -652,11 +643,12 @@ coff_renumber_symbols (bfd_ptr, first_undef) { asymbol **newsyms; unsigned int i; + bfd_size_type amt; - newsyms = (asymbol **) bfd_alloc (bfd_ptr, - sizeof (asymbol *) * (symbol_count + 1)); + amt = sizeof (asymbol *) * ((bfd_size_type) symbol_count + 1); + newsyms = bfd_alloc (bfd_ptr, amt); if (!newsyms) - return false; + return FALSE; bfd_ptr->outsymbols = newsyms; for (i = 0; i < symbol_count; i++) if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) != 0 @@ -689,7 +681,7 @@ coff_renumber_symbols (bfd_ptr, first_undef) for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) { coff_symbol_type *coff_symbol_ptr = coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]); - symbol_ptr_ptr[symbol_index]->udata.i = symbol_index; + symbol_ptr_ptr[symbol_index]->udata.i = symbol_index; if (coff_symbol_ptr && coff_symbol_ptr->native) { combined_entry_type *s = coff_symbol_ptr->native; @@ -697,29 +689,25 @@ coff_renumber_symbols (bfd_ptr, first_undef) if (s->u.syment.n_sclass == C_FILE) { - if (last_file != (struct internal_syment *) NULL) + if (last_file != NULL) last_file->n_value = native_index; last_file = &(s->u.syment); } else - { - - /* Modify the symbol values according to their section and - type */ + /* Modify the symbol values according to their section and + type. */ + fixup_symbol_value (bfd_ptr, coff_symbol_ptr, &(s->u.syment)); - fixup_symbol_value (bfd_ptr, coff_symbol_ptr, &(s->u.syment)); - } for (i = 0; i < s->u.syment.n_numaux + 1; i++) s[i].offset = native_index++; } else - { - native_index++; - } + native_index++; } + obj_conv_table_size (bfd_ptr) = native_index; - return true; + return TRUE; } /* Run thorough the symbol table again, and fix it so that all @@ -727,8 +715,7 @@ coff_renumber_symbols (bfd_ptr, first_undef) symbol table. */ void -coff_mangle_symbols (bfd_ptr) - bfd *bfd_ptr; +coff_mangle_symbols (bfd *bfd_ptr) { unsigned int symbol_count = bfd_get_symcount (bfd_ptr); asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols; @@ -748,7 +735,8 @@ coff_mangle_symbols (bfd_ptr) { /* FIXME: We should use a union here. */ s->u.syment.n_value = - ((combined_entry_type *) s->u.syment.n_value)->offset; + (bfd_hostptr_t) ((combined_entry_type *) + ((bfd_hostptr_t) s->u.syment.n_value))->offset; s->fix_value = 0; } if (s->fix_line) @@ -790,22 +778,20 @@ coff_mangle_symbols (bfd_ptr) } static void -coff_fix_symbol_name (abfd, symbol, native, string_size_p, - debug_string_section_p, debug_string_size_p) - bfd *abfd; - asymbol *symbol; - combined_entry_type *native; - bfd_size_type *string_size_p; - asection **debug_string_section_p; - bfd_size_type *debug_string_size_p; +coff_fix_symbol_name (bfd *abfd, + asymbol *symbol, + combined_entry_type *native, + bfd_size_type *string_size_p, + asection **debug_string_section_p, + bfd_size_type *debug_string_size_p) { unsigned int name_length; union internal_auxent *auxent; char *name = (char *) (symbol->name); - if (name == (char *) NULL) + if (name == NULL) { - /* coff symbols always have names, so we'll make one up */ + /* COFF symbols always have names, so we'll make one up. */ symbol->name = "strange"; name = (char *) symbol->name; } @@ -816,7 +802,16 @@ coff_fix_symbol_name (abfd, symbol, native, string_size_p, { unsigned int filnmlen; - strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN); + if (bfd_coff_force_symnames_in_strings (abfd)) + { + native->u.syment._n._n_n._n_offset = + (*string_size_p + STRING_SIZE_SIZE); + native->u.syment._n._n_n._n_zeroes = 0; + *string_size_p += 6; /* strlen(".file") + 1 */ + } + else + strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN); + auxent = &(native + 1)->u.auxent; filnmlen = bfd_coff_filnmlen (abfd); @@ -824,9 +819,7 @@ coff_fix_symbol_name (abfd, symbol, native, string_size_p, if (bfd_coff_long_filenames (abfd)) { if (name_length <= filnmlen) - { - strncpy (auxent->x_file.x_fname, name, filnmlen); - } + strncpy (auxent->x_file.x_fname, name, filnmlen); else { auxent->x_file.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE; @@ -843,11 +836,10 @@ coff_fix_symbol_name (abfd, symbol, native, string_size_p, } else { - if (name_length <= SYMNMLEN) - { - /* This name will fit into the symbol neatly */ - strncpy (native->u.syment._n._n_name, symbol->name, SYMNMLEN); - } + if (name_length <= SYMNMLEN && !bfd_coff_force_symnames_in_strings (abfd)) + /* This name will fit into the symbol neatly. */ + strncpy (native->u.syment._n._n_name, symbol->name, SYMNMLEN); + else if (!bfd_coff_symname_in_debug (abfd, &native->u.syment)) { native->u.syment._n._n_n._n_offset = (*string_size_p @@ -857,8 +849,9 @@ coff_fix_symbol_name (abfd, symbol, native, string_size_p, } else { - long filepos; - bfd_byte buf[2]; + file_ptr filepos; + bfd_byte buf[4]; + int prefix_len = bfd_coff_debug_string_prefix_length (abfd); /* This name should be written into the .debug section. For some reason each name is preceded by a two byte length @@ -868,24 +861,29 @@ coff_fix_symbol_name (abfd, symbol, native, string_size_p, if (*debug_string_section_p == (asection *) NULL) *debug_string_section_p = bfd_get_section_by_name (abfd, ".debug"); filepos = bfd_tell (abfd); - bfd_put_16 (abfd, name_length + 1, buf); + if (prefix_len == 4) + bfd_put_32 (abfd, (bfd_vma) (name_length + 1), buf); + else + bfd_put_16 (abfd, (bfd_vma) (name_length + 1), buf); + if (!bfd_set_section_contents (abfd, *debug_string_section_p, - (PTR) buf, + (void *) buf, (file_ptr) *debug_string_size_p, - (bfd_size_type) 2) + (bfd_size_type) prefix_len) || !bfd_set_section_contents (abfd, *debug_string_section_p, - (PTR) symbol->name, - ((file_ptr) *debug_string_size_p - + 2), + (void *) symbol->name, + (file_ptr) (*debug_string_size_p + + prefix_len), (bfd_size_type) name_length + 1)) abort (); if (bfd_seek (abfd, filepos, SEEK_SET) != 0) abort (); - native->u.syment._n._n_n._n_offset = *debug_string_size_p + 2; + native->u.syment._n._n_n._n_offset = + *debug_string_size_p + prefix_len; native->u.syment._n._n_n._n_zeroes = 0; - *debug_string_size_p += name_length + 3; + *debug_string_size_p += name_length + 1 + prefix_len; } } } @@ -898,21 +896,19 @@ coff_fix_symbol_name (abfd, symbol, native, string_size_p, /* Write a symbol out to a COFF file. */ -static boolean -coff_write_symbol (abfd, symbol, native, written, string_size_p, - debug_string_section_p, debug_string_size_p) - bfd *abfd; - asymbol *symbol; - combined_entry_type *native; - unsigned int *written; - bfd_size_type *string_size_p; - asection **debug_string_section_p; - bfd_size_type *debug_string_size_p; +static bfd_boolean +coff_write_symbol (bfd *abfd, + asymbol *symbol, + combined_entry_type *native, + bfd_vma *written, + bfd_size_type *string_size_p, + asection **debug_string_section_p, + bfd_size_type *debug_string_size_p) { unsigned int numaux = native->u.syment.n_numaux; int type = native->u.syment.n_type; int class = native->u.syment.n_sclass; - PTR buf; + void * buf; bfd_size_type symesz; if (native->u.syment.n_sclass == C_FILE) @@ -920,22 +916,17 @@ coff_write_symbol (abfd, symbol, native, written, string_size_p, if (symbol->flags & BSF_DEBUGGING && bfd_is_abs_section (symbol->section)) - { - native->u.syment.n_scnum = N_DEBUG; - } + native->u.syment.n_scnum = N_DEBUG; + else if (bfd_is_abs_section (symbol->section)) - { - native->u.syment.n_scnum = N_ABS; - } + native->u.syment.n_scnum = N_ABS; + else if (bfd_is_und_section (symbol->section)) - { - native->u.syment.n_scnum = N_UNDEF; - } + native->u.syment.n_scnum = N_UNDEF; + else - { - native->u.syment.n_scnum = - symbol->section->output_section->target_index; - } + native->u.syment.n_scnum = + symbol->section->output_section->target_index; coff_fix_symbol_name (abfd, symbol, native, string_size_p, debug_string_section_p, debug_string_size_p); @@ -943,10 +934,10 @@ coff_write_symbol (abfd, symbol, native, written, string_size_p, symesz = bfd_coff_symesz (abfd); buf = bfd_alloc (abfd, symesz); if (!buf) - return false; + return FALSE; bfd_coff_swap_sym_out (abfd, &native->u.syment, buf); - if (bfd_write (buf, 1, symesz, abfd) != symesz) - return false; + if (bfd_bwrite (buf, symesz, abfd) != symesz) + return FALSE; bfd_release (abfd, buf); if (native->u.syment.n_numaux > 0) @@ -957,18 +948,16 @@ coff_write_symbol (abfd, symbol, native, written, string_size_p, auxesz = bfd_coff_auxesz (abfd); buf = bfd_alloc (abfd, auxesz); if (!buf) - return false; + return FALSE; for (j = 0; j < native->u.syment.n_numaux; j++) { bfd_coff_swap_aux_out (abfd, &((native + j + 1)->u.auxent), - type, - class, - j, + type, class, (int) j, native->u.syment.n_numaux, buf); - if (bfd_write (buf, 1, auxesz, abfd) != auxesz) - return false; + if (bfd_bwrite (buf, auxesz, abfd) != auxesz) + return FALSE; } bfd_release (abfd, buf); } @@ -977,22 +966,20 @@ coff_write_symbol (abfd, symbol, native, written, string_size_p, set_index (symbol, *written); *written += numaux + 1; - return true; + return TRUE; } /* Write out a symbol to a COFF file that does not come from a COFF file originally. This symbol may have been created by the linker, or we may be linking a non COFF file to a COFF file. */ -static boolean -coff_write_alien_symbol (abfd, symbol, written, string_size_p, - debug_string_section_p, debug_string_size_p) - bfd *abfd; - asymbol *symbol; - unsigned int *written; - bfd_size_type *string_size_p; - asection **debug_string_section_p; - bfd_size_type *debug_string_size_p; +static bfd_boolean +coff_write_alien_symbol (bfd *abfd, + asymbol *symbol, + bfd_vma *written, + bfd_size_type *string_size_p, + asection **debug_string_section_p, + bfd_size_type *debug_string_size_p) { combined_entry_type *native; combined_entry_type dummy; @@ -1017,7 +1004,7 @@ coff_write_alien_symbol (abfd, symbol, written, string_size_p, format. So, we just ignore them. We must clobber the symbol name to keep it from being put in the string table. */ symbol->name = ""; - return true; + return TRUE; } else { @@ -1028,7 +1015,7 @@ coff_write_alien_symbol (abfd, symbol, written, string_size_p, if (! obj_pe (abfd)) native->u.syment.n_value += symbol->section->output_section->vma; - /* Copy the any flags from the the file header into the symbol. + /* Copy the any flags from the file header into the symbol. FIXME: Why? */ { coff_symbol_type *c = coff_symbol_from (abfd, symbol); @@ -1052,15 +1039,13 @@ coff_write_alien_symbol (abfd, symbol, written, string_size_p, /* Write a native symbol to a COFF file. */ -static boolean -coff_write_native_symbol (abfd, symbol, written, string_size_p, - debug_string_section_p, debug_string_size_p) - bfd *abfd; - coff_symbol_type *symbol; - unsigned int *written; - bfd_size_type *string_size_p; - asection **debug_string_section_p; - bfd_size_type *debug_string_size_p; +static bfd_boolean +coff_write_native_symbol (bfd *abfd, + coff_symbol_type *symbol, + bfd_vma *written, + bfd_size_type *string_size_p, + asection **debug_string_section_p, + bfd_size_type *debug_string_size_p) { combined_entry_type *native = symbol->native; alent *lineno = symbol->lineno; @@ -1071,6 +1056,7 @@ coff_write_native_symbol (abfd, symbol, written, string_size_p, if (lineno && !symbol->done_lineno && symbol->symbol.section->owner != NULL) { unsigned int count = 0; + lineno[count].u.offset = *written; if (native->u.syment.n_numaux) { @@ -1084,34 +1070,16 @@ coff_write_native_symbol (abfd, symbol, written, string_size_p, count++; while (lineno[count].line_number != 0) { -#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 lineno[count].u.offset += (symbol->symbol.section->output_section->vma + symbol->symbol.section->output_offset); -#endif count++; } - symbol->done_lineno = true; + symbol->done_lineno = TRUE; - symbol->symbol.section->output_section->moving_line_filepos += - count * bfd_coff_linesz (abfd); + if (! bfd_is_const_section (symbol->symbol.section->output_section)) + symbol->symbol.section->output_section->moving_line_filepos += + count * bfd_coff_linesz (abfd); } return coff_write_symbol (abfd, &(symbol->symbol), native, written, @@ -1119,18 +1087,22 @@ coff_write_native_symbol (abfd, symbol, written, string_size_p, debug_string_size_p); } +static void +null_error_handler (const char * fmt ATTRIBUTE_UNUSED, ...) +{ +} + /* Write out the COFF symbols. */ -boolean -coff_write_symbols (abfd) - bfd *abfd; +bfd_boolean +coff_write_symbols (bfd *abfd) { bfd_size_type string_size; asection *debug_string_section; bfd_size_type debug_string_size; unsigned int i; unsigned int limit = bfd_get_symcount (abfd); - unsigned int written = 0; + bfd_vma written = 0; asymbol **p; string_size = 0; @@ -1155,12 +1127,11 @@ coff_write_symbols (abfd) } } - /* Seek to the right place */ + /* Seek to the right place. */ if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0) - return false; - - /* Output all the symbols we have */ + return FALSE; + /* Output all the symbols we have. */ written = 0; for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) { @@ -1173,33 +1144,69 @@ coff_write_symbols (abfd) if (!coff_write_alien_symbol (abfd, symbol, &written, &string_size, &debug_string_section, &debug_string_size)) - return false; + return FALSE; } else { + if (coff_backend_info (abfd)->_bfd_coff_classify_symbol != NULL) + { + bfd_error_handler_type current_error_handler; + enum coff_symbol_classification class; + unsigned char *n_sclass; + + /* Suppress error reporting by bfd_coff_classify_symbol. + Error messages can be generated when we are processing a local + symbol which has no associated section and we do not have to + worry about this, all we need to know is that it is local. */ + current_error_handler = bfd_set_error_handler (null_error_handler); + class = bfd_coff_classify_symbol (abfd, &c_symbol->native->u.syment); + (void) bfd_set_error_handler (current_error_handler); + + n_sclass = &c_symbol->native->u.syment.n_sclass; + + /* If the symbol class has been changed (eg objcopy/ld script/etc) + we cannot retain the existing sclass from the original symbol. + Weak symbols only have one valid sclass, so just set it always. + If it is not local class and should be, set it C_STAT. + If it is global and not classified as global, or if it is + weak (which is also classified as global), set it C_EXT. */ + + if (symbol->flags & BSF_WEAK) + *n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT; + else if (symbol->flags & BSF_LOCAL && class != COFF_SYMBOL_LOCAL) + *n_sclass = C_STAT; + else if (symbol->flags & BSF_GLOBAL + && (class != COFF_SYMBOL_GLOBAL +#ifdef COFF_WITH_PE + || *n_sclass == C_NT_WEAK +#endif + || *n_sclass == C_WEAKEXT)) + c_symbol->native->u.syment.n_sclass = C_EXT; + } + if (!coff_write_native_symbol (abfd, c_symbol, &written, &string_size, &debug_string_section, &debug_string_size)) - return false; + return FALSE; } } obj_raw_syment_count (abfd) = written; - /* Now write out strings */ - + /* Now write out strings. */ if (string_size != 0) { unsigned int size = string_size + STRING_SIZE_SIZE; bfd_byte buffer[STRING_SIZE_SIZE]; #if STRING_SIZE_SIZE == 4 - bfd_h_put_32 (abfd, size, buffer); + H_PUT_32 (abfd, size, buffer); #else - #error Change bfd_h_put_32 + #error Change H_PUT_32 #endif - if (bfd_write ((PTR) buffer, 1, sizeof (buffer), abfd) != sizeof (buffer)) - return false; + if (bfd_bwrite ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd) + != sizeof (buffer)) + return FALSE; /* Handle long section names. This code must handle section names just as they are handled in coff_write_object_contents. */ @@ -1214,8 +1221,9 @@ coff_write_symbols (abfd) len = strlen (o->name); if (len > SCNNMLEN) { - if (bfd_write (o->name, 1, len + 1, abfd) != len + 1) - return false; + if (bfd_bwrite (o->name, (bfd_size_type) (len + 1), abfd) + != len + 1) + return FALSE; } } } @@ -1238,29 +1246,34 @@ coff_write_symbols (abfd) if (c_symbol == NULL || c_symbol->native == NULL) - { - /* This is not a COFF symbol, so it certainly is not a - file name, nor does it go in the .debug section. */ - maxlen = SYMNMLEN; - } + /* This is not a COFF symbol, so it certainly is not a + file name, nor does it go in the .debug section. */ + maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN; + else if (bfd_coff_symname_in_debug (abfd, &c_symbol->native->u.syment)) - { - /* This symbol name is in the XCOFF .debug section. - Don't write it into the string table. */ - maxlen = name_length; - } + /* This symbol name is in the XCOFF .debug section. + Don't write it into the string table. */ + maxlen = name_length; + else if (c_symbol->native->u.syment.n_sclass == C_FILE && c_symbol->native->u.syment.n_numaux > 0) - maxlen = bfd_coff_filnmlen (abfd); + { + if (bfd_coff_force_symnames_in_strings (abfd)) + { + if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6) + return FALSE; + } + maxlen = bfd_coff_filnmlen (abfd); + } else - maxlen = SYMNMLEN; + maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN; if (name_length > maxlen) { - if (bfd_write ((PTR) (q->name), 1, name_length + 1, abfd) - != name_length + 1) - return false; + if (bfd_bwrite ((void *) (q->name), (bfd_size_type) name_length + 1, + abfd) != name_length + 1) + return FALSE; } } } @@ -1273,13 +1286,13 @@ coff_write_symbols (abfd) bfd_byte buffer[STRING_SIZE_SIZE]; #if STRING_SIZE_SIZE == 4 - bfd_h_put_32 (abfd, size, buffer); + H_PUT_32 (abfd, size, buffer); #else - #error Change bfd_h_put_32 + #error Change H_PUT_32 #endif - if (bfd_write ((PTR) buffer, 1, STRING_SIZE_SIZE, abfd) + if (bfd_bwrite ((void *) buffer, (bfd_size_type) STRING_SIZE_SIZE, abfd) != STRING_SIZE_SIZE) - return false; + return FALSE; } /* Make sure the .debug section was created to be the correct size. @@ -1291,31 +1304,30 @@ coff_write_symbols (abfd) || (debug_string_section != (asection *) NULL && (BFD_ALIGN (debug_string_size, 1 << debug_string_section->alignment_power) - == bfd_section_size (abfd, debug_string_section)))); + == debug_string_section->size))); - return true; + return TRUE; } -boolean -coff_write_linenumbers (abfd) - bfd *abfd; +bfd_boolean +coff_write_linenumbers (bfd *abfd) { asection *s; bfd_size_type linesz; - PTR buff; + void * buff; linesz = bfd_coff_linesz (abfd); buff = bfd_alloc (abfd, linesz); if (!buff) - return false; + return FALSE; for (s = abfd->sections; s != (asection *) NULL; s = s->next) { if (s->lineno_count) { asymbol **q = abfd->outsymbols; if (bfd_seek (abfd, s->line_filepos, SEEK_SET) != 0) - return false; - /* Find all the linenumbers in this section */ + return FALSE; + /* Find all the linenumbers in this section. */ while (*q) { asymbol *p = *q; @@ -1326,22 +1338,24 @@ coff_write_linenumbers (abfd) (bfd_asymbol_bfd (p), p)); if (l) { - /* Found a linenumber entry, output */ + /* Found a linenumber entry, output. */ struct internal_lineno out; - memset ((PTR) & out, 0, sizeof (out)); + memset ((void *) & out, 0, sizeof (out)); out.l_lnno = 0; out.l_addr.l_symndx = l->u.offset; bfd_coff_swap_lineno_out (abfd, &out, buff); - if (bfd_write (buff, 1, linesz, abfd) != linesz) - return false; + if (bfd_bwrite (buff, (bfd_size_type) linesz, abfd) + != linesz) + return FALSE; l++; while (l->line_number) { out.l_lnno = l->line_number; out.l_addr.l_symndx = l->u.offset; bfd_coff_swap_lineno_out (abfd, &out, buff); - if (bfd_write (buff, 1, linesz, abfd) != linesz) - return false; + if (bfd_bwrite (buff, (bfd_size_type) linesz, abfd) + != linesz) + return FALSE; l++; } } @@ -1351,81 +1365,24 @@ coff_write_linenumbers (abfd) } } bfd_release (abfd, buff); - return true; + return TRUE; } -/*ARGSUSED */ alent * -coff_get_lineno (ignore_abfd, symbol) - bfd *ignore_abfd ATTRIBUTE_UNUSED; - asymbol *symbol; +coff_get_lineno (bfd *ignore_abfd ATTRIBUTE_UNUSED, asymbol *symbol) { return coffsymbol (symbol)->lineno; } -#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_alloc (abfd, sizeof (*f)); - if (!f) - { - bfd_set_error (bfd_error_no_error); - return NULL; - } - memset ((char *) f, 0, sizeof (*f)); - 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 */ - /* This function transforms the offsets into the symbol table into pointers to syments. */ static void -coff_pointerize_aux (abfd, table_base, symbol, indaux, auxent) - bfd *abfd; - combined_entry_type *table_base; - combined_entry_type *symbol; - unsigned int indaux; - combined_entry_type *auxent; +coff_pointerize_aux (bfd *abfd, + combined_entry_type *table_base, + combined_entry_type *symbol, + unsigned int indaux, + combined_entry_type *auxent) { unsigned int type = symbol->u.syment.n_type; unsigned int class = symbol->u.syment.n_sclass; @@ -1437,15 +1394,16 @@ coff_pointerize_aux (abfd, table_base, symbol, indaux, auxent) return; } - /* Don't bother if this is a file or a section */ + /* Don't bother if this is a file or a section. */ if (class == C_STAT && type == T_NULL) return; if (class == C_FILE) return; - /* Otherwise patch up */ -#define N_TMASK coff_data (abfd)->local_n_tmask + /* Otherwise patch up. */ +#define N_TMASK coff_data (abfd)->local_n_tmask #define N_BTSHFT coff_data (abfd)->local_n_btshft + if ((ISFCN (type) || ISTAG (class) || class == C_BLOCK || class == C_FCN) && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l > 0) { @@ -1465,14 +1423,14 @@ coff_pointerize_aux (abfd, table_base, symbol, indaux, auxent) /* Allocate space for the ".debug" section, and read it. We did not read the debug section until now, because - we didn't want to go to the trouble until someone needed it. */ + we didn't want to go to the trouble until someone needed it. */ static char * -build_debug_section (abfd) - bfd *abfd; +build_debug_section (bfd *abfd) { char *debug_section; - long position; + file_ptr position; + bfd_size_type sec_size; asection *sect = bfd_get_section_by_name (abfd, ".debug"); @@ -1482,48 +1440,40 @@ build_debug_section (abfd) return NULL; } - debug_section = (PTR) bfd_alloc (abfd, - bfd_get_section_size_before_reloc (sect)); + sec_size = sect->size; + debug_section = bfd_alloc (abfd, sec_size); if (debug_section == NULL) return NULL; - /* Seek to the beginning of the `.debug' section and read it. + /* Seek to the beginning of the `.debug' section and read it. Save the current position first; it is needed by our caller. Then read debug section and reset the file pointer. */ position = bfd_tell (abfd); if (bfd_seek (abfd, sect->filepos, SEEK_SET) != 0 - || (bfd_read (debug_section, - bfd_get_section_size_before_reloc (sect), 1, abfd) - != bfd_get_section_size_before_reloc (sect)) + || bfd_bread (debug_section, sec_size, abfd) != sec_size || bfd_seek (abfd, position, SEEK_SET) != 0) return NULL; return debug_section; } - /* Return a pointer to a malloc'd copy of 'name'. 'name' may not be \0-terminated, but will not exceed 'maxlen' characters. The copy *will* be \0-terminated. */ + static char * -copy_name (abfd, name, maxlen) - bfd *abfd; - char *name; - int maxlen; +copy_name (bfd *abfd, char *name, size_t maxlen) { - int len; + size_t len; char *newname; for (len = 0; len < maxlen; ++len) - { - if (name[len] == '\0') - { - break; - } - } + if (name[len] == '\0') + break; + + if ((newname = bfd_alloc (abfd, (bfd_size_type) len + 1)) == NULL) + return NULL; - if ((newname = (PTR) bfd_alloc (abfd, len + 1)) == NULL) - return (NULL); strncpy (newname, name, len); newname[len] = '\0'; return newname; @@ -1531,36 +1481,37 @@ copy_name (abfd, name, maxlen) /* Read in the external symbols. */ -boolean -_bfd_coff_get_external_symbols (abfd) - bfd *abfd; +bfd_boolean +_bfd_coff_get_external_symbols (bfd *abfd) { bfd_size_type symesz; - size_t size; - PTR syms; + bfd_size_type size; + void * syms; if (obj_coff_external_syms (abfd) != NULL) - return true; + return TRUE; symesz = bfd_coff_symesz (abfd); size = obj_raw_syment_count (abfd) * symesz; + if (size == 0) + return TRUE; - syms = (PTR) bfd_malloc (size); - if (syms == NULL && size != 0) - return false; + syms = bfd_malloc (size); + if (syms == NULL) + return FALSE; if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0 - || bfd_read (syms, size, 1, abfd) != size) + || bfd_bread (syms, size, abfd) != size) { if (syms != NULL) free (syms); - return false; + return FALSE; } obj_coff_external_syms (abfd) = syms; - return true; + return TRUE; } /* Read in the external strings. The strings are not loaded until @@ -1568,12 +1519,12 @@ _bfd_coff_get_external_symbols (abfd) detecting a missing string table in an archive. */ const char * -_bfd_coff_read_string_table (abfd) - bfd *abfd; +_bfd_coff_read_string_table (bfd *abfd) { char extstrsize[STRING_SIZE_SIZE]; - size_t strsize; + bfd_size_type strsize; char *strings; + file_ptr pos; if (obj_coff_strings (abfd) != NULL) return obj_coff_strings (abfd); @@ -1584,13 +1535,13 @@ _bfd_coff_read_string_table (abfd) return NULL; } - if (bfd_seek (abfd, - (obj_sym_filepos (abfd) - + obj_raw_syment_count (abfd) * bfd_coff_symesz (abfd)), - SEEK_SET) != 0) + pos = obj_sym_filepos (abfd); + pos += obj_raw_syment_count (abfd) * bfd_coff_symesz (abfd); + if (bfd_seek (abfd, pos, SEEK_SET) != 0) return NULL; - - if (bfd_read (extstrsize, sizeof extstrsize, 1, abfd) != sizeof extstrsize) + + if (bfd_bread (extstrsize, (bfd_size_type) sizeof extstrsize, abfd) + != sizeof extstrsize) { if (bfd_get_error () != bfd_error_file_truncated) return NULL; @@ -1601,27 +1552,25 @@ _bfd_coff_read_string_table (abfd) else { #if STRING_SIZE_SIZE == 4 - strsize = bfd_h_get_32 (abfd, (bfd_byte *) extstrsize); + strsize = H_GET_32 (abfd, extstrsize); #else - #error Change bfd_h_get_32 + #error Change H_GET_32 #endif } if (strsize < STRING_SIZE_SIZE) { (*_bfd_error_handler) - (_("%s: bad string table size %lu"), bfd_get_filename (abfd), - (unsigned long) strsize); + (_("%B: bad string table size %lu"), abfd, (unsigned long) strsize); bfd_set_error (bfd_error_bad_value); return NULL; } - strings = (char *) bfd_malloc (strsize); + strings = bfd_malloc (strsize); if (strings == NULL) return NULL; - if (bfd_read (strings + STRING_SIZE_SIZE, - strsize - STRING_SIZE_SIZE, 1, abfd) + if (bfd_bread (strings + STRING_SIZE_SIZE, strsize - STRING_SIZE_SIZE, abfd) != strsize - STRING_SIZE_SIZE) { free (strings); @@ -1635,9 +1584,8 @@ _bfd_coff_read_string_table (abfd) /* Free up the external symbols and strings read from a COFF file. */ -boolean -_bfd_coff_free_symbols (abfd) - bfd *abfd; +bfd_boolean +_bfd_coff_free_symbols (bfd *abfd) { if (obj_coff_external_syms (abfd) != NULL && ! obj_coff_keep_syms (abfd)) @@ -1651,7 +1599,7 @@ _bfd_coff_free_symbols (abfd) free (obj_coff_strings (abfd)); obj_coff_strings (abfd) = NULL; } - return true; + return TRUE; } /* Read a symbol table into freshly bfd_allocated memory, swap it, and @@ -1660,25 +1608,24 @@ _bfd_coff_free_symbols (abfd) terminated string. */ combined_entry_type * -coff_get_normalized_symtab (abfd) - bfd *abfd; +coff_get_normalized_symtab (bfd *abfd) { combined_entry_type *internal; combined_entry_type *internal_ptr; combined_entry_type *symbol_ptr; combined_entry_type *internal_end; - bfd_size_type symesz; + size_t symesz; char *raw_src; char *raw_end; const char *string_table = NULL; char *debug_section = NULL; - unsigned long size; + bfd_size_type size; if (obj_raw_syments (abfd) != NULL) return obj_raw_syments (abfd); size = obj_raw_syment_count (abfd) * sizeof (combined_entry_type); - internal = (combined_entry_type *) bfd_zalloc (abfd, size); + internal = bfd_zalloc (abfd, size); if (internal == NULL && size != 0) return NULL; internal_end = internal + obj_raw_syment_count (abfd); @@ -1688,22 +1635,22 @@ coff_get_normalized_symtab (abfd) raw_src = (char *) obj_coff_external_syms (abfd); - /* mark the end of the symbols */ + /* Mark the end of the symbols. */ symesz = bfd_coff_symesz (abfd); raw_end = (char *) raw_src + obj_raw_syment_count (abfd) * symesz; /* FIXME SOMEDAY. A string table size of zero is very weird, but probably possible. If one shows up, it will probably kill us. */ - /* Swap all the raw entries */ + /* Swap all the raw entries. */ for (internal_ptr = internal; raw_src < raw_end; raw_src += symesz, internal_ptr++) { unsigned int i; - bfd_coff_swap_sym_in (abfd, (PTR) raw_src, - (PTR) & internal_ptr->u.syment); + bfd_coff_swap_sym_in (abfd, (void *) raw_src, + (void *) & internal_ptr->u.syment); symbol_ptr = internal_ptr; for (i = 0; @@ -1712,10 +1659,10 @@ coff_get_normalized_symtab (abfd) { internal_ptr++; raw_src += symesz; - bfd_coff_swap_aux_in (abfd, (PTR) raw_src, + bfd_coff_swap_aux_in (abfd, (void *) raw_src, symbol_ptr->u.syment.n_type, symbol_ptr->u.syment.n_sclass, - i, symbol_ptr->u.syment.n_numaux, + (int) i, symbol_ptr->u.syment.n_numaux, &(internal_ptr->u.auxent)); coff_pointerize_aux (abfd, internal, symbol_ptr, i, internal_ptr); @@ -1723,7 +1670,7 @@ coff_get_normalized_symtab (abfd) } /* Free the raw symbols, but not the strings (if we have them). */ - obj_coff_keep_strings (abfd) = true; + obj_coff_keep_strings (abfd) = TRUE; if (! _bfd_coff_free_symbols (abfd)) return NULL; @@ -1733,11 +1680,11 @@ coff_get_normalized_symtab (abfd) if (internal_ptr->u.syment.n_sclass == C_FILE && internal_ptr->u.syment.n_numaux > 0) { - /* make a file symbol point to the name in the auxent, since - the text ".file" is redundant */ + /* Make a file symbol point to the name in the auxent, since + the text ".file" is redundant. */ if ((internal_ptr + 1)->u.auxent.x_file.x_n.x_zeroes == 0) { - /* the filename is a long one, point into the string table */ + /* The filename is a long one, point into the string table. */ if (string_table == NULL) { string_table = _bfd_coff_read_string_table (abfd); @@ -1746,7 +1693,7 @@ coff_get_normalized_symtab (abfd) } internal_ptr->u.syment._n._n_n._n_offset = - ((long) + ((bfd_hostptr_t) (string_table + (internal_ptr + 1)->u.auxent.x_file.x_n.x_offset)); } @@ -1757,21 +1704,17 @@ coff_get_normalized_symtab (abfd) multiple AUX entries. */ if (internal_ptr->u.syment.n_numaux > 1 && coff_data (abfd)->pe) - { - internal_ptr->u.syment._n._n_n._n_offset = - ((long) - copy_name (abfd, - (internal_ptr + 1)->u.auxent.x_file.x_fname, - internal_ptr->u.syment.n_numaux * symesz)); - } + internal_ptr->u.syment._n._n_n._n_offset = + ((bfd_hostptr_t) + copy_name (abfd, + (internal_ptr + 1)->u.auxent.x_file.x_fname, + internal_ptr->u.syment.n_numaux * symesz)); else - { - internal_ptr->u.syment._n._n_n._n_offset = - ((long) - copy_name (abfd, - (internal_ptr + 1)->u.auxent.x_file.x_fname, - bfd_coff_filnmlen (abfd))); - } + internal_ptr->u.syment._n._n_n._n_offset = + ((bfd_hostptr_t) + copy_name (abfd, + (internal_ptr + 1)->u.auxent.x_file.x_fname, + (size_t) bfd_coff_filnmlen (abfd))); } } else @@ -1779,28 +1722,24 @@ coff_get_normalized_symtab (abfd) if (internal_ptr->u.syment._n._n_n._n_zeroes != 0) { /* This is a "short" name. Make it long. */ - unsigned long i = 0; - char *newstring = NULL; + size_t i; + char *newstring; - /* find the length of this string without walking into memory + /* Find the length of this string without walking into memory that isn't ours. */ for (i = 0; i < 8; ++i) - { - if (internal_ptr->u.syment._n._n_name[i] == '\0') - { - break; - } /* if end of string */ - } /* possible lengths of this string. */ - - if ((newstring = (PTR) bfd_alloc (abfd, ++i)) == NULL) - return (NULL); - memset (newstring, 0, i); - strncpy (newstring, internal_ptr->u.syment._n._n_name, i - 1); - internal_ptr->u.syment._n._n_n._n_offset = (long int) newstring; + if (internal_ptr->u.syment._n._n_name[i] == '\0') + break; + + newstring = bfd_zalloc (abfd, (bfd_size_type) (i + 1)); + if (newstring == NULL) + return NULL; + strncpy (newstring, internal_ptr->u.syment._n._n_name, i); + internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) newstring; internal_ptr->u.syment._n._n_n._n_zeroes = 0; } else if (internal_ptr->u.syment._n._n_n._n_offset == 0) - internal_ptr->u.syment._n._n_n._n_offset = (long int) ""; + internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) ""; else if (!bfd_coff_symname_in_debug (abfd, &internal_ptr->u.syment)) { /* Long name already. Point symbol at the string in the @@ -1812,7 +1751,7 @@ coff_get_normalized_symtab (abfd) return NULL; } internal_ptr->u.syment._n._n_n._n_offset = - ((long int) + ((bfd_hostptr_t) (string_table + internal_ptr->u.syment._n._n_n._n_offset)); } @@ -1821,7 +1760,7 @@ coff_get_normalized_symtab (abfd) /* Long name in debug section. Very similar. */ if (debug_section == NULL) debug_section = build_debug_section (abfd); - internal_ptr->u.syment._n._n_n._n_offset = (long int) + internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) (debug_section + internal_ptr->u.syment._n._n_n._n_offset); } } @@ -1832,13 +1771,11 @@ coff_get_normalized_symtab (abfd) BFD_ASSERT (obj_raw_syment_count (abfd) == (unsigned int) (internal_ptr - internal)); - return (internal); -} /* coff_get_normalized_symtab() */ + return internal; +} long -coff_get_reloc_upper_bound (abfd, asect) - bfd *abfd; - sec_ptr asect; +coff_get_reloc_upper_bound (bfd *abfd, sec_ptr asect) { if (bfd_get_format (abfd) != bfd_object) { @@ -1849,71 +1786,66 @@ coff_get_reloc_upper_bound (abfd, asect) } asymbol * -coff_make_empty_symbol (abfd) - bfd *abfd; +coff_make_empty_symbol (bfd *abfd) { - coff_symbol_type *new = (coff_symbol_type *) bfd_alloc (abfd, sizeof (coff_symbol_type)); + bfd_size_type amt = sizeof (coff_symbol_type); + coff_symbol_type *new = bfd_zalloc (abfd, amt); + if (new == NULL) - return (NULL); - memset (new, 0, sizeof *new); + return NULL; new->symbol.section = 0; new->native = 0; - new->lineno = (alent *) NULL; - new->done_lineno = false; + new->lineno = NULL; + new->done_lineno = FALSE; new->symbol.the_bfd = abfd; - return &new->symbol; + + return & new->symbol; } /* Make a debugging symbol. */ asymbol * -coff_bfd_make_debug_symbol (abfd, ptr, sz) - bfd *abfd; - PTR ptr ATTRIBUTE_UNUSED; - unsigned long sz ATTRIBUTE_UNUSED; +coff_bfd_make_debug_symbol (bfd *abfd, + void * ptr ATTRIBUTE_UNUSED, + unsigned long sz ATTRIBUTE_UNUSED) { - coff_symbol_type *new = (coff_symbol_type *) bfd_alloc (abfd, sizeof (coff_symbol_type)); + bfd_size_type amt = sizeof (coff_symbol_type); + coff_symbol_type *new = bfd_alloc (abfd, amt); + if (new == NULL) - return (NULL); + return NULL; /* @@ The 10 is a guess at a plausible maximum number of aux entries (but shouldn't be a constant). */ - new->native = (combined_entry_type *) bfd_zalloc (abfd, sizeof (combined_entry_type) * 10); + amt = sizeof (combined_entry_type) * 10; + new->native = bfd_zalloc (abfd, amt); if (!new->native) - return (NULL); + return NULL; new->symbol.section = bfd_abs_section_ptr; new->symbol.flags = BSF_DEBUGGING; - new->lineno = (alent *) NULL; - new->done_lineno = false; + new->lineno = NULL; + new->done_lineno = FALSE; new->symbol.the_bfd = abfd; - return &new->symbol; + + return & new->symbol; } -/*ARGSUSED */ void -coff_get_symbol_info (abfd, symbol, ret) - bfd *abfd; - asymbol *symbol; - symbol_info *ret; +coff_get_symbol_info (bfd *abfd, asymbol *symbol, symbol_info *ret) { bfd_symbol_info (symbol, ret); + if (coffsymbol (symbol)->native != NULL && coffsymbol (symbol)->native->fix_value) - { - combined_entry_type *psym; - - psym = ((combined_entry_type *) - coffsymbol (symbol)->native->u.syment.n_value); - ret->value = (bfd_vma) (psym - obj_raw_syments (abfd)); - } + ret->value = coffsymbol (symbol)->native->u.syment.n_value - + (bfd_hostptr_t) obj_raw_syments (abfd); } /* Return the COFF syment for a symbol. */ -boolean -bfd_coff_get_syment (abfd, symbol, psyment) - bfd *abfd; - asymbol *symbol; - struct internal_syment *psyment; +bfd_boolean +bfd_coff_get_syment (bfd *abfd, + asymbol *symbol, + struct internal_syment *psyment) { coff_symbol_type *csym; @@ -1921,28 +1853,27 @@ bfd_coff_get_syment (abfd, symbol, psyment) if (csym == NULL || csym->native == NULL) { bfd_set_error (bfd_error_invalid_operation); - return false; + return FALSE; } *psyment = csym->native->u.syment; if (csym->native->fix_value) - psyment->n_value = ((combined_entry_type *) psyment->n_value - - obj_raw_syments (abfd)); + psyment->n_value = psyment->n_value - + (bfd_hostptr_t) obj_raw_syments (abfd); /* FIXME: We should handle fix_line here. */ - return true; + return TRUE; } /* Return the COFF auxent for a symbol. */ -boolean -bfd_coff_get_auxent (abfd, symbol, indx, pauxent) - bfd *abfd; - asymbol *symbol; - int indx; - union internal_auxent *pauxent; +bfd_boolean +bfd_coff_get_auxent (bfd *abfd, + asymbol *symbol, + int indx, + union internal_auxent *pauxent) { coff_symbol_type *csym; combined_entry_type *ent; @@ -1954,7 +1885,7 @@ bfd_coff_get_auxent (abfd, symbol, indx, pauxent) || indx >= csym->native->u.syment.n_numaux) { bfd_set_error (bfd_error_invalid_operation); - return false; + return FALSE; } ent = csym->native + indx + 1; @@ -1976,19 +1907,18 @@ bfd_coff_get_auxent (abfd, symbol, indx, pauxent) ((combined_entry_type *) pauxent->x_csect.x_scnlen.p - obj_raw_syments (abfd)); - return true; + return TRUE; } /* Print out information about COFF symbol. */ void -coff_print_symbol (abfd, filep, symbol, how) - bfd *abfd; - PTR filep; - asymbol *symbol; - bfd_print_symbol_type how; +coff_print_symbol (bfd *abfd, + void * filep, + asymbol *symbol, + bfd_print_symbol_type how) { - FILE *file = (FILE *) filep; + FILE * file = (FILE *) filep; switch (how) { @@ -2005,7 +1935,7 @@ coff_print_symbol (abfd, filep, symbol, how) case bfd_print_symbol_all: if (coffsymbol (symbol)->native) { - unsigned long val; + bfd_vma val; unsigned int aux; combined_entry_type *combined = coffsymbol (symbol)->native; combined_entry_type *root = obj_raw_syments (abfd); @@ -2014,21 +1944,27 @@ coff_print_symbol (abfd, filep, symbol, how) fprintf (file, "[%3ld]", (long) (combined - root)); if (! combined->fix_value) - val = (unsigned long) combined->u.syment.n_value; + val = (bfd_vma) combined->u.syment.n_value; else - val = ((unsigned long) - ((combined_entry_type *) combined->u.syment.n_value - - root)); + val = combined->u.syment.n_value - (bfd_hostptr_t) root; - fprintf (file, - "(sec %2d)(fl 0x%02x)(ty %3x)(scl %3d) (nx %d) 0x%08lx %s", + fprintf (file, "(sec %2d)(fl 0x%02x)(ty %3x)(scl %3d) (nx %d) 0x", combined->u.syment.n_scnum, combined->u.syment.n_flags, combined->u.syment.n_type, combined->u.syment.n_sclass, - combined->u.syment.n_numaux, - val, - symbol->name); + combined->u.syment.n_numaux); +#ifdef BFD64 + /* fprintf_vma() on a 64-bit enabled host will always print a 64-bit + value, but really we want to display the address in the target's + address size. Since we do not have a field in the bfd structure + to tell us this, we take a guess, based on the target's name. */ + if (strstr (bfd_get_target (abfd), "64") == NULL) + fprintf (file, "%08lx", (unsigned long) (val & 0xffffffff)); + else +#endif + fprintf_vma (file, val); + fprintf (file, " %s", symbol->name); for (aux = 0; aux < combined->u.syment.n_numaux; aux++) { @@ -2053,10 +1989,10 @@ coff_print_symbol (abfd, filep, symbol, how) case C_STAT: if (combined->u.syment.n_type == T_NULL) - /* probably a section symbol? */ + /* Probably a section symbol ? */ { fprintf (file, "AUX scnlen 0x%lx nreloc %d nlnno %d", - (long) auxp->u.auxent.x_scn.x_scnlen, + (unsigned long) auxp->u.auxent.x_scn.x_scnlen, auxp->u.auxent.x_scn.x_nreloc, auxp->u.auxent.x_scn.x_nlinno); if (auxp->u.auxent.x_scn.x_checksum != 0 @@ -2068,23 +2004,27 @@ coff_print_symbol (abfd, filep, symbol, how) auxp->u.auxent.x_scn.x_comdat); break; } - /* else fall through */ + /* Otherwise fall through. */ case C_EXT: + case C_AIX_WEAKEXT: if (ISFCN (combined->u.syment.n_type)) { + long next, llnos; + + if (auxp->fix_end) + next = (auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p + - root); + else + next = auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l; + llnos = auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_lnnoptr; fprintf (file, - _("AUX tagndx %ld ttlsiz 0x%lx lnnos %ld next %ld"), + "AUX tagndx %ld ttlsiz 0x%lx lnnos %ld next %ld", tagndx, - auxp->u.auxent.x_sym.x_misc.x_fsize, - auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_lnnoptr, - (auxp->fix_end - ? ((long) - (auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p - - root)) - : auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l)); + (unsigned long) auxp->u.auxent.x_sym.x_misc.x_fsize, + llnos, next); break; } - /* else fall through */ + /* Otherwise fall through. */ default: fprintf (file, "AUX lnno %d size 0x%x tagndx %ld", auxp->u.auxent.x_sym.x_misc.x_lnsz.x_lnno, @@ -2105,17 +2045,15 @@ coff_print_symbol (abfd, filep, symbol, how) l++; while (l->line_number) { - fprintf (file, "\n%4d : 0x%lx", - l->line_number, - ((unsigned long) - (l->u.offset + symbol->section->vma))); + fprintf (file, "\n%4d : ", l->line_number); + fprintf_vma (file, l->u.offset + symbol->section->vma); l++; } } } else { - bfd_print_symbol_vandf ((PTR) file, symbol); + bfd_print_symbol_vandf (abfd, (void *) file, symbol); fprintf (file, " %-5s %s %s %s", symbol->section->name, coffsymbol (symbol)->native ? "n" : "g", @@ -2130,10 +2068,9 @@ coff_print_symbol (abfd, filep, symbol, how) function for the is_local_label_name entry point, but some may override it. */ -boolean -_bfd_coff_is_local_label_name (abfd, name) - bfd *abfd ATTRIBUTE_UNUSED; - const char *name; +bfd_boolean +_bfd_coff_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, + const char *name) { return name[0] == '.' && name[1] == 'L'; } @@ -2141,53 +2078,60 @@ _bfd_coff_is_local_label_name (abfd, name) /* Provided a BFD, a section and an offset (in bytes, not octets) into the section, calculate and return the name of the source file and the line nearest to the wanted location. */ -/*ARGSUSED*/ -boolean -coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr, - functionname_ptr, line_ptr) - bfd *abfd; - asection *section; - asymbol **symbols; - bfd_vma offset; - CONST char **filename_ptr; - CONST char **functionname_ptr; - unsigned int *line_ptr; + +bfd_boolean +coff_find_nearest_line (bfd *abfd, + asection *section, + asymbol **symbols, + bfd_vma offset, + const char **filename_ptr, + const char **functionname_ptr, + unsigned int *line_ptr) { - boolean found; + bfd_boolean found; unsigned int i; unsigned int line_base; coff_data_type *cof = coff_data (abfd); - /* Run through the raw syments if available */ + /* Run through the raw syments if available. */ combined_entry_type *p; combined_entry_type *pend; alent *l; struct coff_section_tdata *sec_data; + bfd_size_type amt; /* Before looking through the symbol table, try to use a .stab section to find the information. */ if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, &found, filename_ptr, functionname_ptr, line_ptr, - &coff_data (abfd)->line_info)) - return false; + &coff_data(abfd)->line_info)) + return FALSE; + if (found) - return true; + return TRUE; + + /* Also try examining DWARF2 debugging information. */ + if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset, + filename_ptr, functionname_ptr, + line_ptr, 0, + &coff_data(abfd)->dwarf2_find_line_info)) + return TRUE; *filename_ptr = 0; *functionname_ptr = 0; *line_ptr = 0; - /* Don't try and find line numbers in a non coff file */ - if (abfd->xvec->flavour != bfd_target_coff_flavour) - return false; + /* Don't try and find line numbers in a non coff file. */ + if (!bfd_family_coff (abfd)) + return FALSE; if (cof == NULL) - return false; + return FALSE; /* Find the first C_FILE symbol. */ p = cof->raw_syments; if (!p) - return false; + return FALSE; pend = p + cof->raw_syment_count; while (p < pend) @@ -2238,7 +2182,7 @@ coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr, /* Avoid endless loops on erroneous files by ensuring that we always move forward in the file. */ - if (p - cof->raw_syments >= p->u.syment.n_value) + if (p >= cof->raw_syments + p->u.syment.n_value) break; p = cof->raw_syments + p->u.syment.n_value; @@ -2247,7 +2191,7 @@ coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr, } } - /* Now wander though the raw linenumbers of the section */ + /* Now wander though the raw linenumbers of the section. */ /* If we have been called on this section before, and the offset we want is further down then we can prime the lookup loop. */ sec_data = coff_section_data (abfd, section); @@ -2275,7 +2219,7 @@ coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr, { if (l->line_number == 0) { - /* Get the symbol this line number points at */ + /* Get the symbol this line number points at. */ coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym); if (coff->symbol.value > offset) break; @@ -2328,48 +2272,55 @@ coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr, /* Cache the results for the next call. */ if (sec_data == NULL && section->owner == abfd) { - section->used_by_bfd = - ((PTR) bfd_zalloc (abfd, - sizeof (struct coff_section_tdata))); + amt = sizeof (struct coff_section_tdata); + section->used_by_bfd = bfd_zalloc (abfd, amt); sec_data = (struct coff_section_tdata *) section->used_by_bfd; } if (sec_data != NULL) { sec_data->offset = offset; - sec_data->i = i; + sec_data->i = i - 1; sec_data->function = *functionname_ptr; sec_data->line_base = line_base; } - return true; + return TRUE; +} + +bfd_boolean +coff_find_inliner_info (bfd *abfd, + const char **filename_ptr, + const char **functionname_ptr, + unsigned int *line_ptr) +{ + bfd_boolean found; + + found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr, + functionname_ptr, line_ptr, + &coff_data(abfd)->dwarf2_find_line_info); + return (found); } int -coff_sizeof_headers (abfd, reloc) - bfd *abfd; - boolean reloc; +coff_sizeof_headers (bfd *abfd, struct bfd_link_info *info) { size_t size; - if (reloc == false) - { - size = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd); - } + if (!info->relocatable) + size = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd); else - { - size = bfd_coff_filhsz (abfd); - } + size = bfd_coff_filhsz (abfd); size += abfd->section_count * bfd_coff_scnhsz (abfd); return size; } /* Change the class of a coff symbol held by BFD. */ -boolean -bfd_coff_set_symbol_class (abfd, symbol, class) - bfd * abfd; - asymbol * symbol; - unsigned int class; + +bfd_boolean +bfd_coff_set_symbol_class (bfd * abfd, + asymbol * symbol, + unsigned int class) { coff_symbol_type * csym; @@ -2377,7 +2328,7 @@ bfd_coff_set_symbol_class (abfd, symbol, class) if (csym == NULL) { bfd_set_error (bfd_error_invalid_operation); - return false; + return FALSE; } else if (csym->native == NULL) { @@ -2385,18 +2336,17 @@ bfd_coff_set_symbol_class (abfd, symbol, class) We cheat here by creating a fake native entry for it and then filling in the class. This code is based on that in coff_write_alien_symbol(). */ - + combined_entry_type * native; + bfd_size_type amt = sizeof (* native); - native = (combined_entry_type *) bfd_alloc (abfd, sizeof (* native)); + native = bfd_zalloc (abfd, amt); if (native == NULL) - return false; + return FALSE; - memset (native, 0, sizeof (* native)); - native->u.syment.n_type = T_NULL; native->u.syment.n_sclass = class; - + if (bfd_is_und_section (symbol->section)) { native->u.syment.n_scnum = N_UNDEF; @@ -2415,19 +2365,26 @@ bfd_coff_set_symbol_class (abfd, symbol, class) + symbol->section->output_offset); if (! obj_pe (abfd)) native->u.syment.n_value += symbol->section->output_section->vma; - - /* Copy the any flags from the the file header into the symbol. + + /* Copy the any flags from the file header into the symbol. FIXME: Why? */ native->u.syment.n_flags = bfd_asymbol_bfd (& csym->symbol)->flags; } - + csym->native = native; } else - { - csym->native->u.syment.n_sclass = class; - } - - return true; + csym->native->u.syment.n_sclass = class; + + return TRUE; } +struct coff_comdat_info * +bfd_coff_get_comdat_section (bfd *abfd, struct bfd_section *sec) +{ + if (bfd_get_flavour (abfd) == bfd_target_coff_flavour + && coff_section_data (abfd, sec) != NULL) + return coff_section_data (abfd, sec)->comdat; + else + return NULL; +}