From: H.J. Lu Date: Thu, 28 Apr 2016 12:25:17 +0000 (-0700) Subject: Add record_link_assignments to ldemul X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=316b611580f1dd4242863f0fcded588980fe9e07;p=thirdparty%2Fbinutils-gdb.git Add record_link_assignments to ldemul --- diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index 4f5d1a4d2c0..cc2f056602c 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -64,6 +64,7 @@ static void gld${EMULATION_NAME}_after_parse (void); static void gld${EMULATION_NAME}_after_open (void); static void gld${EMULATION_NAME}_before_allocation (void); static void gld${EMULATION_NAME}_after_allocation (void); +static void gld${EMULATION_NAME}_restore_ehdr_start (void); static lang_output_section_statement_type *gld${EMULATION_NAME}_place_orphan (asection *, const char *, int); EOF @@ -1330,6 +1331,7 @@ fragment <assignment_statement.exp); } +static struct elf_link_hash_entry *ehdr_start; +static struct bfd_link_hash_entry ehdr_start_save; + +static void +gld${EMULATION_NAME}_record_link_assignments (lang_phase_type phase) +{ + if (phase == lang_mark_phase_enum + && is_elf_hash_table (link_info.hash)) + { + /* Make __ehdr_start hidden if it has been referenced, to + prevent the symbol from being dynamic. */ + if (!bfd_link_relocatable (&link_info)) + { + struct elf_link_hash_entry *h + = elf_link_hash_lookup (elf_hash_table (&link_info), + "__ehdr_start", FALSE, FALSE, TRUE); + + /* Only adjust the export class if the symbol was referenced + and not defined, otherwise leave it alone. */ + if (h != NULL + && (h->root.type == bfd_link_hash_new + || h->root.type == bfd_link_hash_undefined + || h->root.type == bfd_link_hash_undefweak + || h->root.type == bfd_link_hash_common)) + { + _bfd_elf_link_hash_hide_symbol (&link_info, h, TRUE); + if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL) + h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN; + /* Don't leave the symbol undefined. Undefined hidden + symbols typically won't have dynamic relocations, but + we most likely will need dynamic relocations for + __ehdr_start if we are building a PIE or shared + library. */ + ehdr_start = h; + ehdr_start_save = h->root; + h->root.type = bfd_link_hash_defined; + h->root.u.def.section = bfd_abs_section_ptr; + h->root.u.def.value = 0; + } + } + + /* If we are going to make any variable assignments, we need to + let the ELF backend know about them in case the variables are + referred to by dynamic objects. */ + lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment); + } +} + +static void +gld${EMULATION_NAME}_restore_ehdr_start (void) +{ + if (ehdr_start != NULL) + { + /* If we twiddled __ehdr_start to defined earlier, put it back + as it was. */ + ehdr_start->root.type = ehdr_start_save.type; + ehdr_start->root.u = ehdr_start_save.u; + } +} + EOF +else +fragment <