diff options
author | Ian Lance Taylor <ian@airs.com> | 1997-03-13 02:41:44 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1997-03-13 02:41:44 +0000 |
commit | e549b1d2a3c79f49a487a26aa806b4241f329ee2 (patch) | |
tree | 636946c75df633b2cabf12c80aeccfa4fbb953ef /bfd/elfcode.h | |
parent | 7d996a75d2ee20dba23c3e1e7a1df6e6beaaddda (diff) | |
download | gdb-e549b1d2a3c79f49a487a26aa806b4241f329ee2.zip gdb-e549b1d2a3c79f49a487a26aa806b4241f329ee2.tar.gz gdb-e549b1d2a3c79f49a487a26aa806b4241f329ee2.tar.bz2 |
* elflink.h (elf_link_add_object_symbols): Use extsymoff when
setting ever. Sanity check the version number. Sort out copying
flags and other information when adding an indirect symbol.
(NAME(bfd_elf,size_dynamic_sections)): Preserve any dynamic
symbols added by the backend. Clear the entire contents of the
versym section.
(elf_export_symbol): Ignore indirect symbols.
(elf_link_output_extsym): Accept a section without an owner in an
assert.
* elfcode.h (elf_slurp_symbol_table): Add a sanity check on the
version count. Correct the allocation of x_versymp.
Diffstat (limited to 'bfd/elfcode.h')
-rw-r--r-- | bfd/elfcode.h | 90 |
1 files changed, 86 insertions, 4 deletions
diff --git a/bfd/elfcode.h b/bfd/elfcode.h index 87e02f2..1320601 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -1,5 +1,5 @@ /* ELF executable support for BFD. - Copyright 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. + Copyright 1991, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. Written by Fred Fish @ Cygnus Support, from information published in "UNIX System V Release 4, Programmers Guide: ANSI C and @@ -68,6 +68,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bfdlink.h" #include "libbfd.h" #include "elf-bfd.h" +#include "fnmatch.h" /* Renaming structures, typedefs, macros and functions to be size-specific. */ #define Elf_External_Ehdr NAME(Elf,External_Ehdr) @@ -455,6 +456,7 @@ elf_object_p (abfd) struct elf_backend_data *ebd; struct elf_obj_tdata *preserved_tdata = elf_tdata (abfd); struct elf_obj_tdata *new_tdata = NULL; + asection *s; /* Read in the ELF header in external format. */ @@ -658,6 +660,25 @@ elf_object_p (abfd) goto got_wrong_format_error; } + /* If we have created any reloc sections that are associated with + debugging sections, mark the reloc sections as debugging as well. */ + for (s = abfd->sections; s != NULL; s = s->next) + { + if ((elf_section_data (s)->this_hdr.sh_type == SHT_REL + || elf_section_data (s)->this_hdr.sh_type == SHT_RELA) + && elf_section_data (s)->this_hdr.sh_info > 0) + { + unsigned long targ_index; + asection *targ_sec; + + targ_index = elf_section_data (s)->this_hdr.sh_info; + targ_sec = bfd_section_from_elf_index (abfd, targ_index); + if (targ_sec != NULL + && (targ_sec->flags & SEC_DEBUGGING) != 0) + s->flags |= SEC_DEBUGGING; + } + } + return (abfd->xvec); got_wrong_format_error: @@ -902,11 +923,13 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic) boolean dynamic; { Elf_Internal_Shdr *hdr; + Elf_Internal_Shdr *verhdr; long symcount; /* Number of external ELF symbols */ elf_symbol_type *sym; /* Pointer to current bfd symbol */ elf_symbol_type *symbase; /* Buffer for generated bfd symbols */ Elf_Internal_Sym i_sym; Elf_External_Sym *x_symp = NULL; + Elf_External_Versym *x_versymp = NULL; /* Read each raw ELF symbol, converting from external ELF form to internal ELF form, and then using the information to create a @@ -918,10 +941,25 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic) space left over at the end. When we have all the symbols, we build the caller's pointer vector. */ - if (dynamic) - hdr = &elf_tdata (abfd)->dynsymtab_hdr; + if (! dynamic) + { + hdr = &elf_tdata (abfd)->symtab_hdr; + verhdr = NULL; + } else - hdr = &elf_tdata (abfd)->symtab_hdr; + { + hdr = &elf_tdata (abfd)->dynsymtab_hdr; + verhdr = &elf_tdata (abfd)->dynversym_hdr; + if ((elf_tdata (abfd)->dynverdef_section != 0 + && elf_tdata (abfd)->verdef == NULL) + || (elf_tdata (abfd)->dynverref_section != 0 + && elf_tdata (abfd)->verref == NULL)) + { + if (! _bfd_elf_slurp_version_tables (abfd)) + return -1; + } + } + if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1) return -1; @@ -951,6 +989,38 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic) if (bfd_read ((PTR) x_symp, sizeof (Elf_External_Sym), symcount, abfd) != symcount * sizeof (Elf_External_Sym)) goto error_return; + + /* Read the raw ELF version symbol information. */ + + if (elf_dynversym (abfd) != 0 + && verhdr != NULL + && verhdr->sh_size / sizeof (Elf_External_Versym) != symcount) + { + (*_bfd_error_handler) + ("%s: version count (%ld) does not match symbol count (%ld)", + abfd->filename, + (long) (verhdr->sh_size / sizeof (Elf_External_Versym)), + symcount); + + /* Slurp in the symbols without the version information, + since that is more helpful than just quitting. */ + verhdr = NULL; + } + + if (verhdr != NULL) + { + if (bfd_seek (abfd, verhdr->sh_offset, SEEK_SET) != 0) + goto error_return; + + x_versymp = (Elf_External_Versym *) bfd_malloc (verhdr->sh_size); + if (x_versymp == NULL && symcount != 0) + goto error_return; + + if (bfd_read ((PTR) x_versymp, 1, verhdr->sh_size, abfd) + != verhdr->sh_size) + goto error_return; + } + /* Skip first symbol, which is a null dummy. */ for (i = 1; i < symcount; i++) { @@ -1035,6 +1105,14 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic) if (dynamic) sym->symbol.flags |= BSF_DYNAMIC; + if (x_versymp != NULL) + { + Elf_Internal_Versym iversym; + + _bfd_elf_swap_versym_in (abfd, x_versymp + i, &iversym); + sym->version = iversym.vs_vers; + } + /* Do some backend-specific processing on this symbol. */ { struct elf_backend_data *ebd = get_elf_backend_data (abfd); @@ -1071,10 +1149,14 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic) *symptrs = 0; /* Final null pointer */ } + if (x_versymp != NULL) + free (x_versymp); if (x_symp != NULL) free (x_symp); return symcount; error_return: + if (x_versymp != NULL) + free (x_versymp); if (x_symp != NULL) free (x_symp); return -1; |