aboutsummaryrefslogtreecommitdiff
path: root/bfd/elfcode.h
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1997-03-13 02:41:44 +0000
committerIan Lance Taylor <ian@airs.com>1997-03-13 02:41:44 +0000
commite549b1d2a3c79f49a487a26aa806b4241f329ee2 (patch)
tree636946c75df633b2cabf12c80aeccfa4fbb953ef /bfd/elfcode.h
parent7d996a75d2ee20dba23c3e1e7a1df6e6beaaddda (diff)
downloadgdb-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.h90
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;