diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 21 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 4 | ||||
-rw-r--r-- | bfd/elf-bfd.h | 2 | ||||
-rw-r--r-- | bfd/elf.c | 2 | ||||
-rw-r--r-- | bfd/elfcode.h | 5 | ||||
-rw-r--r-- | bfd/elflink.c | 32 | ||||
-rw-r--r-- | bfd/syms.c | 9 |
7 files changed, 64 insertions, 11 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7987bbc..42dd8e3 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,24 @@ +2009-07-23 Ulrich Drepper <drepper@redhat.com> + + * elf-bfd.h (struct elf_link_hash_entry): Add unique_global field. + * elf.c (swap_out_syms): Set binding to STB_GNU_UNIQUE for symbols + with the BSF_GNU_UNIQUE flag bit set. + * elfcode.h (elf_slurp_symbol_table): Set the BSF_GNU_UNIQUE flag + for symbols with STB_GNU_UNIQUE binding. + * elflink.c (_bfd_elf_merge_symbol): Set unique_global for symbols + with the STB_GNU_UNIQUE binding. + (elf_link_add_object_symbols): Set the BSF_GNU_UNIQUE flag for + symbols with STB_GNU_UNIQUE binding. Set STB_GNU_UNIQUE for + symbols with the unique_global field set. + (elf_link_output_extsym): Set unique_global field for symbols with + the STB_GNU_UNIQUE binding. + * syms.c (struct bfd_symbol): Define BSF_GNU_UNIQUE flag bit. + (bfd_print_symbol_vandf): Print a 'u' character for BSF_GNU_UNIQUE + symbols. + (bfd_decode_symclass): Return a 'u' character for BSF_GNU_UNIQUE + symbols. + * bfd-in2.h: Regenerate. + 2009-07-22 H.J. Lu <hongjiu.lu@intel.com> * elflink.c (elf_link_output_extsym): Revert the last change. diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 5244b9a..562f833 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -4639,6 +4639,10 @@ typedef struct bfd_symbol calling the function that it points to. BSF_FUNCTION must also be also set. */ #define BSF_GNU_INDIRECT_FUNCTION (1 << 22) + /* This symbol is a globally unique data object. The dynamic linker + will make sure that in the entire process there is just one symbol + with this name and type in use. BSF_OBJECT must also be set. */ +#define BSF_GNU_UNIQUE (1 << 23) flagword flags; diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 1690def..8f70d79 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -178,6 +178,8 @@ struct elf_link_hash_entry /* Symbol is referenced with a relocation where C/C++ pointer equality matters. */ unsigned int pointer_equality_needed : 1; + /* Symbol is a unique global symbol. */ + unsigned int unique_global : 1; /* String table index in .dynstr if this is a dynamic symbol. */ unsigned long dynstr_index; @@ -6446,6 +6446,8 @@ Unable to find equivalent output section for symbol '%s' from section '%s'"), if (flags & BSF_LOCAL) bind = STB_LOCAL; + else if (flags & BSF_GNU_UNIQUE) + bind = STB_GNU_UNIQUE; else if (flags & BSF_WEAK) bind = STB_WEAK; else if (flags & BSF_GLOBAL) diff --git a/bfd/elfcode.h b/bfd/elfcode.h index 024ead4..10aa131 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -1,6 +1,6 @@ /* ELF executable support for BFD. Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Written by Fred Fish @ Cygnus Support, from information published @@ -1282,6 +1282,9 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic) case STB_WEAK: sym->symbol.flags |= BSF_WEAK; break; + case STB_GNU_UNIQUE: + sym->symbol.flags |= BSF_GNU_UNIQUE; + break; } switch (ELF_ST_TYPE (isym->st_info)) diff --git a/bfd/elflink.c b/bfd/elflink.c index f9b577c..a117063 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -1248,6 +1248,9 @@ _bfd_elf_merge_symbol (bfd *abfd, oldweak = (h->root.type == bfd_link_hash_defweak || h->root.type == bfd_link_hash_undefweak); + if (bind == STB_GNU_UNIQUE) + h->unique_global = 1; + /* If a new weak symbol definition comes from a regular file and the old symbol comes from a dynamic library, we treat the new one as strong. Similarly, an old weak symbol definition from a regular @@ -3871,24 +3874,31 @@ error_free_dyn: common = bed->common_definition (isym); bind = ELF_ST_BIND (isym->st_info); - if (bind == STB_LOCAL) + switch (bind) { + case STB_LOCAL: /* This should be impossible, since ELF requires that all global symbols follow all local symbols, and that sh_info point to the first global symbol. Unfortunately, Irix 5 screws this up. */ continue; - } - else if (bind == STB_GLOBAL) - { + + case STB_GLOBAL: if (isym->st_shndx != SHN_UNDEF && !common) flags = BSF_GLOBAL; - } - else if (bind == STB_WEAK) - flags = BSF_WEAK; - else - { + break; + + case STB_WEAK: + flags = BSF_WEAK; + break; + + case STB_GNU_UNIQUE: + flags = BSF_GNU_UNIQUE; + break; + + default: /* Leave it up to the processor backend. */ + break; } if (isym->st_shndx == SHN_UNDEF) @@ -4140,7 +4150,9 @@ error_free_dyn: while (h->root.type == bfd_link_hash_indirect || h->root.type == bfd_link_hash_warning) h = (struct elf_link_hash_entry *) h->root.u.i.link; + *sym_hash = h; + h->unique_global = (flags & BSF_GNU_UNIQUE) != 0; new_weakdef = FALSE; if (dynamic @@ -8571,6 +8583,8 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data) sym.st_other = h->other; if (h->forced_local) sym.st_info = ELF_ST_INFO (STB_LOCAL, h->type); + else if (h->unique_global) + sym.st_info = ELF_ST_INFO (STB_GNU_UNIQUE, h->type); else if (h->root.type == bfd_link_hash_undefweak || h->root.type == bfd_link_hash_defweak) sym.st_info = ELF_ST_INFO (STB_WEAK, h->type); @@ -302,6 +302,10 @@ CODE_FRAGMENT . calling the function that it points to. BSF_FUNCTION must . also be also set. *} .#define BSF_GNU_INDIRECT_FUNCTION (1 << 22) +. {* This symbol is a globally unique data object. The dynamic linker +. will make sure that in the entire process there is just one symbol +. with this name and type in use. BSF_OBJECT must also be set. *} +.#define BSF_GNU_UNIQUE (1 << 23) . . flagword flags; . @@ -485,7 +489,8 @@ bfd_print_symbol_vandf (bfd *abfd, void *arg, asymbol *symbol) fprintf (file, " %c%c%c%c%c%c%c", ((type & BSF_LOCAL) ? (type & BSF_GLOBAL) ? '!' : 'l' - : (type & BSF_GLOBAL) ? 'g' : ' '), + : (type & BSF_GLOBAL) ? 'g' + : (type & BSF_GNU_UNIQUE) ? 'u' : ' '), (type & BSF_WEAK) ? 'w' : ' ', (type & BSF_CONSTRUCTOR) ? 'C' : ' ', (type & BSF_WARNING) ? 'W' : ' ', @@ -686,6 +691,8 @@ bfd_decode_symclass (asymbol *symbol) else return 'W'; } + if (symbol->flags & BSF_GNU_UNIQUE) + return 'u'; if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL))) return '?'; |