X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Felfread.c;h=a80b8f0854823879289c3818a5c94b54e0a2a1eb;hb=c3ea6048f0746b494cc53483e3d1e0422bcda9e0;hp=068d412b6e517539ce9eec3153ff8faa1e68101f;hpb=b6af0555b58f4a5996fd3590f2cb40d3664136f7;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/elfread.c b/gdb/elfread.c index 068d412b6e..a80b8f0854 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -1,7 +1,8 @@ /* Read ELF (Executable and Linking Format) object files for GDB. - Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001 - Free Software Foundation, Inc. + + Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + Written by Fred Fish at Cygnus Support. This file is part of GDB. @@ -18,8 +19,8 @@ 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. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ #include "defs.h" #include "bfd.h" @@ -43,52 +44,12 @@ extern void _initialize_elfread (void); struct elfinfo { - file_ptr dboffset; /* Offset to dwarf debug section */ - unsigned int dbsize; /* Size of dwarf debug section */ - file_ptr lnoffset; /* Offset to dwarf line number section */ - unsigned int lnsize; /* Size of dwarf line number section */ asection *stabsect; /* Section pointer for .stab section */ asection *stabindexsect; /* Section pointer for .stab.index section */ asection *mdebugsect; /* Section pointer for .mdebug section */ }; -/* Various things we might complain about... */ - -struct complaint section_info_complaint = -{"elf/stab section information %s without a preceding file symbol", 0, 0}; - -struct complaint section_info_dup_complaint = -{"duplicated elf/stab section information for %s", 0, 0}; - -struct complaint stab_info_mismatch_complaint = -{"elf/stab section information missing for %s", 0, 0}; - -struct complaint stab_info_questionable_complaint = -{"elf/stab section information questionable for %s", 0, 0}; - -static void elf_symfile_init (struct objfile *); - -static void elf_new_init (struct objfile *); - -static void elf_symfile_read (struct objfile *, int); - -static void elf_symfile_finish (struct objfile *); - -static void elf_symtab_read (struct objfile *, int); - -static void free_elfinfo (PTR); - -static struct minimal_symbol *record_minimal_symbol_and_info (char *, - CORE_ADDR, - enum - minimal_symbol_type, - char *, - asection * - bfd_section, - struct objfile - *); - -static void elf_locate_sections (bfd *, asection *, PTR); +static void free_elfinfo (void *); /* We are called once per section from elf_symfile_read. We need to examine each section we are passed, check to see @@ -110,76 +71,35 @@ static void elf_locate_sections (bfd *, asection *, PTR); -kingdon). */ static void -elf_locate_sections (bfd *ignore_abfd, asection *sectp, PTR eip) +elf_locate_sections (bfd *ignore_abfd, asection *sectp, void *eip) { - register struct elfinfo *ei; + struct elfinfo *ei; ei = (struct elfinfo *) eip; - if (STREQ (sectp->name, ".debug")) - { - ei->dboffset = sectp->filepos; - ei->dbsize = bfd_get_section_size_before_reloc (sectp); - } - else if (STREQ (sectp->name, ".line")) - { - ei->lnoffset = sectp->filepos; - ei->lnsize = bfd_get_section_size_before_reloc (sectp); - } - else if (STREQ (sectp->name, ".stab")) + if (strcmp (sectp->name, ".stab") == 0) { ei->stabsect = sectp; } - else if (STREQ (sectp->name, ".stab.index")) + else if (strcmp (sectp->name, ".stab.index") == 0) { ei->stabindexsect = sectp; } - else if (STREQ (sectp->name, ".mdebug")) + else if (strcmp (sectp->name, ".mdebug") == 0) { ei->mdebugsect = sectp; } } -#if 0 /* Currently unused */ - -char * -elf_interpreter (bfd *abfd) -{ - sec_ptr interp_sec; - unsigned size; - char *interp = NULL; - - interp_sec = bfd_get_section_by_name (abfd, ".interp"); - if (interp_sec) - { - size = bfd_section_size (abfd, interp_sec); - interp = alloca (size); - if (bfd_get_section_contents (abfd, interp_sec, interp, (file_ptr) 0, - size)) - { - interp = savestring (interp, size - 1); - } - else - { - interp = NULL; - } - } - return (interp); -} - -#endif - static struct minimal_symbol * -record_minimal_symbol_and_info (char *name, CORE_ADDR address, - enum minimal_symbol_type ms_type, char *info, /* FIXME, is this really char *? */ - asection *bfd_section, struct objfile *objfile) +record_minimal_symbol (char *name, CORE_ADDR address, + enum minimal_symbol_type ms_type, + asection *bfd_section, struct objfile *objfile) { -#ifdef SMASH_TEXT_ADDRESS if (ms_type == mst_text || ms_type == mst_file_text) - SMASH_TEXT_ADDRESS (address); -#endif + address = SMASH_TEXT_ADDRESS (address); return prim_record_minimal_symbol_and_info - (name, address, ms_type, info, bfd_section->index, bfd_section, objfile); + (name, address, ms_type, NULL, bfd_section->index, bfd_section, objfile); } /* @@ -190,13 +110,14 @@ record_minimal_symbol_and_info (char *name, CORE_ADDR address, SYNOPSIS - void elf_symtab_read (struct objfile *objfile, int dynamic) + void elf_symtab_read (struct objfile *objfile, int dynamic, + long number_of_symbols, asymbol **symbol_table) DESCRIPTION - Given an objfile and a flag that specifies whether or not the objfile - is for an executable or not (may be shared library for example), add - all the global function and data symbols to the minimal symbol table. + Given an objfile, a symbol table, and a flag indicating whether the + symbol table contains dynamic symbols, add all the global function + and data symbols to the minimal symbol table. In stabs-in-ELF, as implemented by Sun, there are some local symbols defined in the ELF symbol table, which can be used to locate @@ -207,15 +128,12 @@ record_minimal_symbol_and_info (char *name, CORE_ADDR address, */ static void -elf_symtab_read (struct objfile *objfile, int dynamic) +elf_symtab_read (struct objfile *objfile, int dynamic, + long number_of_symbols, asymbol **symbol_table) { long storage_needed; asymbol *sym; - asymbol **symbol_table; - long number_of_symbols; long i; - int index; - struct cleanup *back_to; CORE_ADDR symaddr; CORE_ADDR offset; enum minimal_symbol_type ms_type; @@ -226,304 +144,274 @@ elf_symtab_read (struct objfile *objfile, int dynamic) seen any section info for it yet. */ asymbol *filesym = 0; #ifdef SOFUN_ADDRESS_MAYBE_MISSING - /* Name of filesym, as saved on the symbol_obstack. */ - char *filesymname = obsavestring ("", 0, &objfile->symbol_obstack); + /* Name of filesym, as saved on the objfile_obstack. */ + char *filesymname = obsavestring ("", 0, &objfile->objfile_obstack); #endif - struct dbx_symfile_info *dbx = objfile->sym_stab_info; - unsigned long size; + struct dbx_symfile_info *dbx = objfile->deprecated_sym_stab_info; int stripped = (bfd_get_symcount (objfile->obfd) == 0); - if (dynamic) + for (i = 0; i < number_of_symbols; i++) { - storage_needed = bfd_get_dynamic_symtab_upper_bound (objfile->obfd); + sym = symbol_table[i]; + if (sym->name == NULL || *sym->name == '\0') + { + /* Skip names that don't exist (shouldn't happen), or names + that are null strings (may happen). */ + continue; + } - /* Nothing to be done if there is no dynamic symtab. */ - if (storage_needed < 0) - return; - } - else - { - storage_needed = bfd_get_symtab_upper_bound (objfile->obfd); - if (storage_needed < 0) - error ("Can't read symbols from %s: %s", bfd_get_filename (objfile->obfd), - bfd_errmsg (bfd_get_error ())); - } - if (storage_needed > 0) - { - symbol_table = (asymbol **) xmalloc (storage_needed); - back_to = make_cleanup (xfree, symbol_table); - if (dynamic) - number_of_symbols = bfd_canonicalize_dynamic_symtab (objfile->obfd, - symbol_table); - else - number_of_symbols = bfd_canonicalize_symtab (objfile->obfd, symbol_table); - if (number_of_symbols < 0) - error ("Can't read symbols from %s: %s", bfd_get_filename (objfile->obfd), - bfd_errmsg (bfd_get_error ())); + /* Skip "special" symbols, e.g. ARM mapping symbols. These are + symbols which do not correspond to objects in the symbol table, + but have some other target-specific meaning. */ + if (bfd_is_target_special_symbol (objfile->obfd, sym)) + continue; - for (i = 0; i < number_of_symbols; i++) + offset = ANOFFSET (objfile->section_offsets, sym->section->index); + if (dynamic + && sym->section == &bfd_und_section + && (sym->flags & BSF_FUNCTION)) { - sym = symbol_table[i]; - if (sym->name == NULL || *sym->name == '\0') - { - /* Skip names that don't exist (shouldn't happen), or names - that are null strings (may happen). */ - continue; - } + struct minimal_symbol *msym; + + /* Symbol is a reference to a function defined in + a shared library. + If its value is non zero then it is usually the address + of the corresponding entry in the procedure linkage table, + plus the desired section offset. + If its value is zero then the dynamic linker has to resolve + the symbol. We are unable to find any meaningful address + for this symbol in the executable file, so we skip it. */ + symaddr = sym->value; + if (symaddr == 0) + continue; + symaddr += offset; + msym = record_minimal_symbol + ((char *) sym->name, symaddr, + mst_solib_trampoline, sym->section, objfile); +#ifdef SOFUN_ADDRESS_MAYBE_MISSING + if (msym != NULL) + msym->filename = filesymname; +#endif + continue; + } - offset = ANOFFSET (objfile->section_offsets, sym->section->index); - if (dynamic - && sym->section == &bfd_und_section - && (sym->flags & BSF_FUNCTION)) + /* If it is a nonstripped executable, do not enter dynamic + symbols, as the dynamic symbol table is usually a subset + of the main symbol table. */ + if (dynamic && !stripped) + continue; + if (sym->flags & BSF_FILE) + { + /* STT_FILE debugging symbol that helps stabs-in-elf debugging. + Chain any old one onto the objfile; remember new sym. */ + if (sectinfo != NULL) { - struct minimal_symbol *msym; - - /* Symbol is a reference to a function defined in - a shared library. - If its value is non zero then it is usually the address - of the corresponding entry in the procedure linkage table, - plus the desired section offset. - If its value is zero then the dynamic linker has to resolve - the symbol. We are unable to find any meaningful address - for this symbol in the executable file, so we skip it. */ - symaddr = sym->value; - if (symaddr == 0) - continue; - symaddr += offset; - msym = record_minimal_symbol_and_info - ((char *) sym->name, symaddr, - mst_solib_trampoline, NULL, sym->section, objfile); + sectinfo->next = dbx->stab_section_info; + dbx->stab_section_info = sectinfo; + sectinfo = NULL; + } + filesym = sym; #ifdef SOFUN_ADDRESS_MAYBE_MISSING - if (msym != NULL) - msym->filename = filesymname; + filesymname = + obsavestring ((char *) filesym->name, strlen (filesym->name), + &objfile->objfile_obstack); #endif - continue; + } + else if (sym->flags & BSF_SECTION_SYM) + continue; + else if (sym->flags & (BSF_GLOBAL | BSF_LOCAL | BSF_WEAK)) + { + struct minimal_symbol *msym; + + /* Select global/local/weak symbols. Note that bfd puts abs + symbols in their own section, so all symbols we are + interested in will have a section. */ + /* Bfd symbols are section relative. */ + symaddr = sym->value + sym->section->vma; + /* Relocate all non-absolute symbols by the section offset. */ + if (sym->section != &bfd_abs_section) + { + symaddr += offset; } - - /* If it is a nonstripped executable, do not enter dynamic - symbols, as the dynamic symbol table is usually a subset - of the main symbol table. */ - if (dynamic && !stripped) - continue; - if (sym->flags & BSF_FILE) + /* For non-absolute symbols, use the type of the section + they are relative to, to intuit text/data. Bfd provides + no way of figuring this out for absolute symbols. */ + if (sym->section == &bfd_abs_section) { - /* STT_FILE debugging symbol that helps stabs-in-elf debugging. - Chain any old one onto the objfile; remember new sym. */ - if (sectinfo != NULL) + /* This is a hack to get the minimal symbol type + right for Irix 5, which has absolute addresses + with special section indices for dynamic symbols. */ + unsigned short shndx = + ((elf_symbol_type *) sym)->internal_elf_sym.st_shndx; + + switch (shndx) { - sectinfo->next = dbx->stab_section_info; - dbx->stab_section_info = sectinfo; - sectinfo = NULL; + case SHN_MIPS_TEXT: + ms_type = mst_text; + break; + case SHN_MIPS_DATA: + ms_type = mst_data; + break; + case SHN_MIPS_ACOMMON: + ms_type = mst_bss; + break; + default: + ms_type = mst_abs; + } + + /* If it is an Irix dynamic symbol, skip section name + symbols, relocate all others by section offset. */ + if (ms_type != mst_abs) + { + if (sym->name[0] == '.') + continue; + symaddr += offset; } - filesym = sym; -#ifdef SOFUN_ADDRESS_MAYBE_MISSING - filesymname = - obsavestring ((char *) filesym->name, strlen (filesym->name), - &objfile->symbol_obstack); -#endif } - else if (sym->flags & (BSF_GLOBAL | BSF_LOCAL | BSF_WEAK)) + else if (sym->section->flags & SEC_CODE) { - struct minimal_symbol *msym; - - /* Select global/local/weak symbols. Note that bfd puts abs - symbols in their own section, so all symbols we are - interested in will have a section. */ - /* Bfd symbols are section relative. */ - symaddr = sym->value + sym->section->vma; - /* Relocate all non-absolute symbols by the section offset. */ - if (sym->section != &bfd_abs_section) + if (sym->flags & (BSF_GLOBAL | BSF_WEAK)) { - symaddr += offset; + ms_type = mst_text; } - /* For non-absolute symbols, use the type of the section - they are relative to, to intuit text/data. Bfd provides - no way of figuring this out for absolute symbols. */ - if (sym->section == &bfd_abs_section) + else if ((sym->name[0] == '.' && sym->name[1] == 'L') + || ((sym->flags & BSF_LOCAL) + && sym->name[0] == '$' + && sym->name[1] == 'L')) + /* Looks like a compiler-generated label. Skip + it. The assembler should be skipping these (to + keep executables small), but apparently with + gcc on the (deleted) delta m88k SVR4, it loses. + So to have us check too should be harmless (but + I encourage people to fix this in the assembler + instead of adding checks here). */ + continue; + else { - /* This is a hack to get the minimal symbol type - right for Irix 5, which has absolute addresses - with special section indices for dynamic symbols. */ - unsigned short shndx = - ((elf_symbol_type *) sym)->internal_elf_sym.st_shndx; - - switch (shndx) - { - case SHN_MIPS_TEXT: - ms_type = mst_text; - break; - case SHN_MIPS_DATA: - ms_type = mst_data; - break; - case SHN_MIPS_ACOMMON: - ms_type = mst_bss; - break; - default: - ms_type = mst_abs; - } - - /* If it is an Irix dynamic symbol, skip section name - symbols, relocate all others by section offset. */ - if (ms_type != mst_abs) - { - if (sym->name[0] == '.') - continue; - symaddr += offset; - } + ms_type = mst_file_text; } - else if (sym->section->flags & SEC_CODE) + } + else if (sym->section->flags & SEC_ALLOC) + { + if (sym->flags & (BSF_GLOBAL | BSF_WEAK)) { - if (sym->flags & BSF_GLOBAL) + if (sym->section->flags & SEC_LOAD) { - ms_type = mst_text; - } - else if ((sym->name[0] == '.' && sym->name[1] == 'L') - || ((sym->flags & BSF_LOCAL) - && sym->name[0] == '$' - && sym->name[1] == 'L')) - /* Looks like a compiler-generated label. Skip it. - The assembler should be skipping these (to keep - executables small), but apparently with gcc on the - delta m88k SVR4, it loses. So to have us check too - should be harmless (but I encourage people to fix this - in the assembler instead of adding checks here). */ - continue; -#ifdef HARRIS_TARGET - else if (sym->name[0] == '.' && sym->name[1] == '.') - { - /* Looks like a Harris compiler generated label for the - purpose of marking instructions that are relevant to - DWARF dies. The assembler can't get rid of these - because they are relocatable addresses that the - linker needs to resolve. */ - continue; + ms_type = mst_data; } -#endif else { - ms_type = mst_file_text; + ms_type = mst_bss; } } - else if (sym->section->flags & SEC_ALLOC) + else if (sym->flags & BSF_LOCAL) { - if (sym->flags & (BSF_GLOBAL | BSF_WEAK)) - { - if (sym->section->flags & SEC_LOAD) - { - ms_type = mst_data; - } - else - { - ms_type = mst_bss; - } - } - else if (sym->flags & BSF_LOCAL) + /* Named Local variable in a Data section. + Check its name for stabs-in-elf. */ + int special_local_sect; + if (strcmp ("Bbss.bss", sym->name) == 0) + special_local_sect = SECT_OFF_BSS (objfile); + else if (strcmp ("Ddata.data", sym->name) == 0) + special_local_sect = SECT_OFF_DATA (objfile); + else if (strcmp ("Drodata.rodata", sym->name) == 0) + special_local_sect = SECT_OFF_RODATA (objfile); + else + special_local_sect = -1; + if (special_local_sect >= 0) { - /* Named Local variable in a Data section. Check its - name for stabs-in-elf. The STREQ macro checks the - first character inline, so we only actually do a - strcmp function call on names that start with 'B' - or 'D' */ - index = SECT_OFF_MAX; - if (STREQ ("Bbss.bss", sym->name)) - { - index = SECT_OFF_BSS (objfile); - } - else if (STREQ ("Ddata.data", sym->name)) - { - index = SECT_OFF_DATA (objfile); - } - else if (STREQ ("Drodata.rodata", sym->name)) + /* Found a special local symbol. Allocate a + sectinfo, if needed, and fill it in. */ + if (sectinfo == NULL) { - index = SECT_OFF_RODATA (objfile); - } - if (index != SECT_OFF_MAX) - { - /* Found a special local symbol. Allocate a - sectinfo, if needed, and fill it in. */ - if (sectinfo == NULL) + int max_index; + size_t size; + + max_index + = max (SECT_OFF_BSS (objfile), + max (SECT_OFF_DATA (objfile), + SECT_OFF_RODATA (objfile))); + + /* max_index is the largest index we'll + use into this array, so we must + allocate max_index+1 elements for it. + However, 'struct stab_section_info' + already includes one element, so we + need to allocate max_index aadditional + elements. */ + size = (sizeof (struct stab_section_info) + + (sizeof (CORE_ADDR) + * max_index)); + sectinfo = (struct stab_section_info *) + xmalloc (size); + memset (sectinfo, 0, size); + sectinfo->num_sections = max_index; + if (filesym == NULL) { - sectinfo = (struct stab_section_info *) - xmmalloc (objfile->md, sizeof (*sectinfo)); - memset ((PTR) sectinfo, 0, sizeof (*sectinfo)); - if (filesym == NULL) - { - complain (§ion_info_complaint, - sym->name); - } - else - { - sectinfo->filename = - (char *) filesym->name; - } - } - if (index != -1) - { - if (sectinfo->sections[index] != 0) - { - complain (§ion_info_dup_complaint, - sectinfo->filename); - } + complaint (&symfile_complaints, + _("elf/stab section information %s without a preceding file symbol"), + sym->name); } else - internal_error (__FILE__, __LINE__, - "Section index uninitialized."); - /* Bfd symbols are section relative. */ - symaddr = sym->value + sym->section->vma; - /* Relocate non-absolute symbols by the section offset. */ - if (sym->section != &bfd_abs_section) { - symaddr += offset; + sectinfo->filename = + (char *) filesym->name; } - if (index != -1) - sectinfo->sections[index] = symaddr; - else - internal_error (__FILE__, __LINE__, - "Section index uninitialized."); - /* The special local symbols don't go in the - minimal symbol table, so ignore this one. */ - continue; - } - /* Not a special stabs-in-elf symbol, do regular - symbol processing. */ - if (sym->section->flags & SEC_LOAD) - { - ms_type = mst_file_data; - } - else - { - ms_type = mst_file_bss; } + if (sectinfo->sections[special_local_sect] != 0) + complaint (&symfile_complaints, + _("duplicated elf/stab section information for %s"), + sectinfo->filename); + /* BFD symbols are section relative. */ + symaddr = sym->value + sym->section->vma; + /* Relocate non-absolute symbols by the + section offset. */ + if (sym->section != &bfd_abs_section) + symaddr += offset; + sectinfo->sections[special_local_sect] = symaddr; + /* The special local symbols don't go in the + minimal symbol table, so ignore this one. */ + continue; + } + /* Not a special stabs-in-elf symbol, do regular + symbol processing. */ + if (sym->section->flags & SEC_LOAD) + { + ms_type = mst_file_data; } else { - ms_type = mst_unknown; + ms_type = mst_file_bss; } } else { - /* FIXME: Solaris2 shared libraries include lots of - odd "absolute" and "undefined" symbols, that play - hob with actions like finding what function the PC - is in. Ignore them if they aren't text, data, or bss. */ - /* ms_type = mst_unknown; */ - continue; /* Skip this symbol. */ + ms_type = mst_unknown; } + } + else + { + /* FIXME: Solaris2 shared libraries include lots of + odd "absolute" and "undefined" symbols, that play + hob with actions like finding what function the PC + is in. Ignore them if they aren't text, data, or bss. */ + /* ms_type = mst_unknown; */ + continue; /* Skip this symbol. */ + } + msym = record_minimal_symbol + ((char *) sym->name, symaddr, + ms_type, sym->section, objfile); + if (msym) + { /* Pass symbol size field in via BFD. FIXME!!! */ - size = ((elf_symbol_type *) sym)->internal_elf_sym.st_size; - msym = record_minimal_symbol_and_info - ((char *) sym->name, symaddr, - ms_type, (PTR) size, sym->section, objfile); + unsigned long size = ((elf_symbol_type *) sym)->internal_elf_sym.st_size; + MSYMBOL_SIZE(msym) = size; + } #ifdef SOFUN_ADDRESS_MAYBE_MISSING - if (msym != NULL) - msym->filename = filesymname; + if (msym != NULL) + msym->filename = filesymname; #endif -#ifdef ELF_MAKE_MSYMBOL_SPECIAL - ELF_MAKE_MSYMBOL_SPECIAL (sym, msym); -#endif - } + ELF_MAKE_MSYMBOL_SPECIAL (sym, msym); } - do_cleanups (back_to); } } @@ -549,7 +437,6 @@ elf_symtab_read (struct objfile *objfile, int dynamic) We look for sections with specific names, to tell us what debug format to look for: FIXME!!! - dwarf_build_psymtabs() builds psymtabs for DWARF symbols; elfstab_build_psymtabs() handles STABS symbols; mdebug_build_psymtabs() handles ECOFF debugging information. @@ -566,6 +453,9 @@ elf_symfile_read (struct objfile *objfile, int mainline) struct elfinfo ei; struct cleanup *back_to; CORE_ADDR offset; + long symcount = 0, dynsymcount = 0, synthcount, storage_needed; + asymbol **symbol_table = NULL, **dyn_symbol_table = NULL; + asymbol *synthsyms; init_minimal_symbol_collection (); back_to = make_cleanup_discard_minimal_symbols (); @@ -573,20 +463,77 @@ elf_symfile_read (struct objfile *objfile, int mainline) memset ((char *) &ei, 0, sizeof (ei)); /* Allocate struct to keep track of the symfile */ - objfile->sym_stab_info = (struct dbx_symfile_info *) - xmmalloc (objfile->md, sizeof (struct dbx_symfile_info)); - memset ((char *) objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info)); - make_cleanup (free_elfinfo, (PTR) objfile); + objfile->deprecated_sym_stab_info = (struct dbx_symfile_info *) + xmalloc (sizeof (struct dbx_symfile_info)); + memset ((char *) objfile->deprecated_sym_stab_info, 0, sizeof (struct dbx_symfile_info)); + make_cleanup (free_elfinfo, (void *) objfile); /* Process the normal ELF symbol table first. This may write some - chain of info into the dbx_symfile_info in objfile->sym_stab_info, + chain of info into the dbx_symfile_info in objfile->deprecated_sym_stab_info, which can later be used by elfstab_offset_sections. */ - elf_symtab_read (objfile, 0); + storage_needed = bfd_get_symtab_upper_bound (objfile->obfd); + if (storage_needed < 0) + error (_("Can't read symbols from %s: %s"), bfd_get_filename (objfile->obfd), + bfd_errmsg (bfd_get_error ())); + + if (storage_needed > 0) + { + symbol_table = (asymbol **) xmalloc (storage_needed); + make_cleanup (xfree, symbol_table); + symcount = bfd_canonicalize_symtab (objfile->obfd, symbol_table); + + if (symcount < 0) + error (_("Can't read symbols from %s: %s"), bfd_get_filename (objfile->obfd), + bfd_errmsg (bfd_get_error ())); + + elf_symtab_read (objfile, 0, symcount, symbol_table); + } /* Add the dynamic symbols. */ - elf_symtab_read (objfile, 1); + storage_needed = bfd_get_dynamic_symtab_upper_bound (objfile->obfd); + + if (storage_needed > 0) + { + dyn_symbol_table = (asymbol **) xmalloc (storage_needed); + make_cleanup (xfree, dyn_symbol_table); + dynsymcount = bfd_canonicalize_dynamic_symtab (objfile->obfd, + dyn_symbol_table); + + if (dynsymcount < 0) + error (_("Can't read symbols from %s: %s"), bfd_get_filename (objfile->obfd), + bfd_errmsg (bfd_get_error ())); + + elf_symtab_read (objfile, 1, dynsymcount, dyn_symbol_table); + } + + /* Add synthetic symbols - for instance, names for any PLT entries. */ + + synthcount = bfd_get_synthetic_symtab (abfd, symcount, symbol_table, + dynsymcount, dyn_symbol_table, + &synthsyms); + if (synthcount > 0) + { + asymbol **synth_symbol_table; + long i; + + make_cleanup (xfree, synthsyms); + synth_symbol_table = xmalloc (sizeof (asymbol *) * synthcount); + for (i = 0; i < synthcount; i++) + synth_symbol_table[i] = synthsyms + i; + make_cleanup (xfree, synth_symbol_table); + elf_symtab_read (objfile, 0, synthcount, synth_symbol_table); + } + + /* Install any minimal symbols that have been collected as the current + minimal symbols for this objfile. The debug readers below this point + should not generate new minimal symbols; if they do it's their + responsibility to install them. "mdebug" appears to be the only one + which will do this. */ + + install_minimal_symbols (objfile); + do_cleanups (back_to); /* Now process debugging information, which is contained in special ELF sections. */ @@ -601,7 +548,7 @@ elf_symfile_read (struct objfile *objfile, int mainline) } /* We first have to find them... */ - bfd_map_over_sections (abfd, elf_locate_sections, (PTR) & ei); + bfd_map_over_sections (abfd, elf_locate_sections, (void *) & ei); /* ELF debugging information is inserted into the psymtab in the order of least informative first - most informative last. Since @@ -637,51 +584,37 @@ elf_symfile_read (struct objfile *objfile, int mainline) if (str_sect) elfstab_build_psymtabs (objfile, mainline, - ei.stabsect->filepos, - bfd_section_size (abfd, ei.stabsect), + ei.stabsect, str_sect->filepos, bfd_section_size (abfd, str_sect)); } - if (dwarf2_has_info (abfd)) + if (dwarf2_has_info (objfile)) { /* DWARF 2 sections */ dwarf2_build_psymtabs (objfile, mainline); } - else if (ei.dboffset && ei.lnoffset) - { - /* DWARF sections */ - dwarf_build_psymtabs (objfile, - mainline, - ei.dboffset, ei.dbsize, - ei.lnoffset, ei.lnsize); - } - if (DWARF2_BUILD_FRAME_INFO_P ()) - DWARF2_BUILD_FRAME_INFO(objfile); - - /* Install any minimal symbols that have been collected as the current - minimal symbols for this objfile. */ - - install_minimal_symbols (objfile); - - do_cleanups (back_to); + /* FIXME: kettenis/20030504: This still needs to be integrated with + dwarf2read.c in a better way. */ + dwarf2_build_frame_info (objfile); } -/* This cleans up the objfile's sym_stab_info pointer, and the chain of - stab_section_info's, that might be dangling from it. */ +/* This cleans up the objfile's deprecated_sym_stab_info pointer, and + the chain of stab_section_info's, that might be dangling from + it. */ static void -free_elfinfo (PTR objp) +free_elfinfo (void *objp) { struct objfile *objfile = (struct objfile *) objp; - struct dbx_symfile_info *dbxinfo = objfile->sym_stab_info; + struct dbx_symfile_info *dbxinfo = objfile->deprecated_sym_stab_info; struct stab_section_info *ssi, *nssi; ssi = dbxinfo->stab_section_info; while (ssi) { nssi = ssi->next; - xmfree (objfile->md, ssi); + xfree (ssi); ssi = nssi; } @@ -710,9 +643,9 @@ elf_new_init (struct objfile *ignore) static void elf_symfile_finish (struct objfile *objfile) { - if (objfile->sym_stab_info != NULL) + if (objfile->deprecated_sym_stab_info != NULL) { - xmfree (objfile->md, objfile->sym_stab_info); + xfree (objfile->deprecated_sym_stab_info); } } @@ -746,7 +679,7 @@ void elfstab_offset_sections (struct objfile *objfile, struct partial_symtab *pst) { char *filename = pst->filename; - struct dbx_symfile_info *dbx = objfile->sym_stab_info; + struct dbx_symfile_info *dbx = objfile->deprecated_sym_stab_info; struct stab_section_info *maybe = dbx->stab_section_info; struct stab_section_info *questionable = 0; int i; @@ -763,7 +696,7 @@ elfstab_offset_sections (struct objfile *objfile, struct partial_symtab *pst) for (; maybe; maybe = maybe->next) { if (filename[0] == maybe->filename[0] - && STREQ (filename, maybe->filename)) + && strcmp (filename, maybe->filename) == 0) { /* We found a match. But there might be several source files (from different directories) with the same name. */ @@ -775,7 +708,8 @@ elfstab_offset_sections (struct objfile *objfile, struct partial_symtab *pst) if (maybe == 0 && questionable != 0) { - complain (&stab_info_questionable_complaint, filename); + complaint (&symfile_complaints, + _("elf/stab section information questionable for %s"), filename); maybe = questionable; } @@ -784,15 +718,17 @@ elfstab_offset_sections (struct objfile *objfile, struct partial_symtab *pst) /* Found it! Allocate a new psymtab struct, and fill it in. */ maybe->found++; pst->section_offsets = (struct section_offsets *) - obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS); - for (i = 0; i < SECT_OFF_MAX; i++) + obstack_alloc (&objfile->objfile_obstack, + SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)); + for (i = 0; i < maybe->num_sections; i++) (pst->section_offsets)->offsets[i] = maybe->sections[i]; return; } /* We were unable to find any offsets for this file. Complain. */ if (dbx->stab_section_info) /* If there *is* any info, */ - complain (&stab_info_mismatch_complaint, filename); + complaint (&symfile_complaints, + _("elf/stab section information missing for %s"), filename); } /* Register that we are able to handle ELF object file formats. */