X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=ld%2Femultempl%2Felf32.em;h=89c5d5d0e55a83abfb8d309f3e5d9f0869ab12c7;hb=e49f502242bc5fc72547397cd344aea5b9f53a14;hp=11668fdb9b6d3e465884f73637dab09cde152de2;hpb=36af4a4e51338a12cdd06009ae335ad776b496ff;p=deliverable%2Fbinutils-gdb.git diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index 11668fdb9b..89c5d5d0e5 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -13,7 +13,7 @@ cat >e${EMULATION_NAME}.c < ELF support by Ian Lance Taylor @@ -53,38 +53,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "elf/common.h" -static void gld${EMULATION_NAME}_before_parse - PARAMS ((void)); -static void gld${EMULATION_NAME}_vercheck - PARAMS ((lang_input_statement_type *)); -static void gld${EMULATION_NAME}_stat_needed - PARAMS ((lang_input_statement_type *)); -static bfd_boolean gld${EMULATION_NAME}_try_needed - PARAMS ((const char *, int)); -static bfd_boolean gld${EMULATION_NAME}_search_needed - PARAMS ((const char *, const char *, int)); -static void gld${EMULATION_NAME}_check_needed - PARAMS ((lang_input_statement_type *)); -static void gld${EMULATION_NAME}_after_open - PARAMS ((void)); -static void gld${EMULATION_NAME}_find_exp_assignment - PARAMS ((etree_type *)); -static void gld${EMULATION_NAME}_find_statement_assignment - PARAMS ((lang_statement_union_type *)); -static void gld${EMULATION_NAME}_before_allocation - PARAMS ((void)); -static bfd_boolean gld${EMULATION_NAME}_open_dynamic_archive - PARAMS ((const char *, search_dirs_type *, lang_input_statement_type *)); -static lang_output_section_statement_type *output_rel_find - PARAMS ((asection *)); -static asection *output_prev_sec_find - PARAMS ((lang_output_section_statement_type *)); +/* Declare functions used by various EXTRA_EM_FILEs. */ +static void gld${EMULATION_NAME}_before_parse (void); +static void gld${EMULATION_NAME}_after_open (void); +static void gld${EMULATION_NAME}_before_allocation (void); static bfd_boolean gld${EMULATION_NAME}_place_orphan - PARAMS ((lang_input_statement_type *, asection *)); -static void gld${EMULATION_NAME}_finish - PARAMS ((void)); -static char *gld${EMULATION_NAME}_get_script - PARAMS ((int *isfile)); + (lang_input_statement_type *file, asection *s); +static void gld${EMULATION_NAME}_finish (void); EOF @@ -104,17 +79,9 @@ if test x"$LDEMUL_BEFORE_PARSE" != xgld"$EMULATION_NAME"_before_parse; then cat >>e${EMULATION_NAME}.c <arch; - ldfile_output_machine = arch->mach; - ldfile_output_machine_name = arch->printable_name; - } - else - ldfile_output_architecture = bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`; + ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`); config.dynamic_link = ${DYNAMIC_LINK-TRUE}; config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`; } @@ -122,6 +89,28 @@ gld${EMULATION_NAME}_before_parse () EOF fi +if test x"$LDEMUL_RECOGNIZED_FILE" != xgld"${EMULATION_NAME}"_load_symbols; then +cat >>e${EMULATION_NAME}.c <as_needed + || (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) == 0) + return FALSE; + + /* Tell the ELF linker that we don't want the output file to have a + DT_NEEDED entry for this file, unless it is used to resolve + references in a regular object. */ + bfd_elf_set_dyn_lib_class (entry->the_bfd, DYN_AS_NEEDED); + + /* Continue on with normal load_symbols processing. */ + return FALSE; +} +EOF +fi + cat >>e${EMULATION_NAME}.c <name, suffix - l->name) == 0) { /* Here we know that S is a dynamic object FOO.SO.VER1, and - the object we are considering needs a dynamic object - FOO.SO.VER2, and VER1 and VER2 are different. This - appears to be a version mismatch, so we tell the caller - to try a different version of this library. */ + the object we are considering needs a dynamic object + FOO.SO.VER2, and VER1 and VER2 are different. This + appears to be a version mismatch, so we tell the caller + to try a different version of this library. */ global_vercheck_failed = TRUE; return; } @@ -205,8 +193,7 @@ gld${EMULATION_NAME}_vercheck (s) the file. */ static void -gld${EMULATION_NAME}_stat_needed (s) - lang_input_statement_type *s; +gld${EMULATION_NAME}_stat_needed (lang_input_statement_type *s) { struct stat st; const char *suffix; @@ -261,9 +248,7 @@ gld${EMULATION_NAME}_stat_needed (s) to skip the check for a conflicting version. */ static bfd_boolean -gld${EMULATION_NAME}_try_needed (name, force) - const char *name; - int force; +gld${EMULATION_NAME}_try_needed (const char *name, int force) { bfd *abfd; const char *soname; @@ -310,16 +295,16 @@ gld${EMULATION_NAME}_try_needed (name, force) { bfd_close (abfd); /* Return FALSE to force the caller to move on to try - another file on the search path. */ + another file on the search path. */ return FALSE; } /* But wait! It gets much worse. On Linux, if a shared - library does not use libc at all, we are supposed to skip - it the first time around in case we encounter a shared - library later on with the same name which does use the - version of libc that we want. This is much too horrible - to use on any system other than Linux. */ + library does not use libc at all, we are supposed to skip + it the first time around in case we encounter a shared + library later on with the same name which does use the + version of libc that we want. This is much too horrible + to use on any system other than Linux. */ EOF case ${target} in @@ -369,18 +354,17 @@ cat >>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <header.type == lang_assignment_statement_enum) gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp); @@ -883,11 +853,14 @@ cat >>e${EMULATION_NAME}.c <type == bfd_link_elf_hash_table) + _bfd_elf_tls_setup (output_bfd, &link_info); + /* 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. */ @@ -898,8 +871,8 @@ gld${EMULATION_NAME}_before_allocation () rpath = command_line.rpath; if (rpath == NULL) rpath = (const char *) getenv ("LD_RUN_PATH"); - if (! (bfd_elf${ELFSIZE}_size_dynamic_sections - (output_bfd, command_line.soname, rpath, + if (! (bfd_elf_size_dynamic_sections + (output_bfd, command_line.soname, rpath, command_line.filter_shlib, (const char * const *) command_line.auxiliary_filters, &link_info, &sinterp, lang_elf_version_info))) @@ -923,8 +896,10 @@ ${ELF_INTERPRETER_SET_DEFAULT} { asection *s; bfd_size_type sz; + bfd_size_type prefix_len; char *msg; bfd_boolean ret; + const char * gnu_warning_prefix = _("warning: "); if (is->just_syms_flag) continue; @@ -934,11 +909,14 @@ ${ELF_INTERPRETER_SET_DEFAULT} continue; sz = bfd_section_size (is->the_bfd, s); - msg = xmalloc ((size_t) sz + 1); - if (! bfd_get_section_contents (is->the_bfd, s, msg, (file_ptr) 0, sz)) + prefix_len = strlen (gnu_warning_prefix); + msg = xmalloc ((size_t) (prefix_len + sz + 1)); + strcpy (msg, gnu_warning_prefix); + if (! bfd_get_section_contents (is->the_bfd, s, msg + prefix_len, + (file_ptr) 0, sz)) einfo ("%F%B: Can't read contents of section .gnu.warning: %E\n", is->the_bfd); - msg[sz] = '\0'; + msg[prefix_len + sz] = '\0'; ret = link_info.callbacks->warning (&link_info, msg, (const char *) NULL, is->the_bfd, (asection *) NULL, @@ -964,10 +942,8 @@ cat >>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <name[4] == 'a'; @@ -1056,24 +1032,33 @@ output_rel_find (sec) for (u = lang_output_section_statement.head; u; u = lookup->next) { lookup = &u->output_section_statement; - if (strncmp (".rel", lookup->name, 4) == 0) + if (lookup->constraint != -1 + && strncmp (".rel", lookup->name, 4) == 0) { - /* Don't place after .rel.plt as doing so results in wrong - dynamic tags. Also, place allocated reloc sections before - non-allocated. */ int lookrela = lookup->name[4] == 'a'; - if (strcmp (".plt", lookup->name + 4 + lookrela) == 0 - || (lookup->bfd_section != NULL - && (lookup->bfd_section->flags & SEC_ALLOC) == 0)) + /* .rel.dyn must come before all other reloc sections, to suit + GNU ld.so. */ + if (isdyn) + break; + + /* Don't place after .rel.plt as doing so results in wrong + dynamic tags. */ + if (strcmp (".plt", lookup->name + 4 + lookrela) == 0) break; - last = lookup; - if (rela == lookrela) + + if (rela == lookrela || last_rel == NULL) last_rel = lookup; - if (lookup->bfd_section != NULL + if ((rela == lookrela || last_rel_alloc == NULL) + && lookup->bfd_section != NULL && (lookup->bfd_section->flags & SEC_ALLOC) != 0) last_rel_alloc = lookup; } + + last = lookup; + if (lookup->bfd_section != NULL + && (lookup->bfd_section->flags & SEC_ALLOC) != 0) + last_alloc = lookup; } if (last_rel_alloc) @@ -1082,6 +1067,9 @@ output_rel_find (sec) if (last_rel) return last_rel; + if (last_alloc) + return last_alloc; + return last; } @@ -1089,8 +1077,7 @@ output_rel_find (sec) Used by place_orphan. */ static asection * -output_prev_sec_find (os) - lang_output_section_statement_type *os; +output_prev_sec_find (lang_output_section_statement_type *os) { asection *s = (asection *) NULL; lang_statement_union_type *u; @@ -1122,9 +1109,7 @@ struct orphan_save { }; static bfd_boolean -gld${EMULATION_NAME}_place_orphan (file, s) - lang_input_statement_type *file; - asection *s; +gld${EMULATION_NAME}_place_orphan (lang_input_statement_type *file, asection *s) { static struct orphan_save hold_text; static struct orphan_save hold_rodata; @@ -1146,7 +1131,7 @@ gld${EMULATION_NAME}_place_orphan (file, s) int isdyn = 0; secname = bfd_get_section_name (s->owner, s); - if (! link_info.relocateable + if (! link_info.relocatable && link_info.combreloc && (s->flags & SEC_ALLOC) && strncmp (secname, ".rel", 4) == 0) @@ -1158,7 +1143,7 @@ gld${EMULATION_NAME}_place_orphan (file, s) isdyn = 1; } - if (isdyn || (!config.unique_orphan_sections && !unique_section_p (secname))) + if (isdyn || (!config.unique_orphan_sections && !unique_section_p (s))) { /* Look through the script to see where to place this section. */ os = lang_output_section_find (secname); @@ -1181,7 +1166,7 @@ gld${EMULATION_NAME}_place_orphan (file, s) /* If this is a final link, then always put .gnu.warning.SYMBOL sections into the .text section to get them out of the way. */ if (link_info.executable - && ! link_info.relocateable + && ! link_info.relocatable && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0 && hold_text.os != NULL) { @@ -1197,7 +1182,9 @@ gld${EMULATION_NAME}_place_orphan (file, s) #define HAVE_SECTION(hold, name) \ (hold.os != NULL || (hold.os = lang_output_section_find (name)) != NULL) - if ((s->flags & SEC_EXCLUDE) != 0 && !link_info.relocateable) + if (((s->flags & (SEC_EXCLUDE | SEC_GROUP)) != 0 && !link_info.relocatable) + || ((s->flags & (SEC_EXCLUDE | SEC_DEBUGGING)) + == (SEC_EXCLUDE | SEC_DEBUGGING))) { if (s->output_section == NULL) s->output_section = bfd_abs_section_ptr; @@ -1223,7 +1210,7 @@ gld${EMULATION_NAME}_place_orphan (file, s) else if (strncmp (secname, ".rel", 4) == 0 && (s->flags & SEC_LOAD) != 0 && (hold_rel.os != NULL - || (hold_rel.os = output_rel_find (s)) != NULL)) + || (hold_rel.os = output_rel_find (s, isdyn)) != NULL)) place = &hold_rel; else if ((s->flags & (SEC_CODE | SEC_READONLY)) == SEC_READONLY && HAVE_SECTION (hold_rodata, ".rodata")) @@ -1278,7 +1265,7 @@ gld${EMULATION_NAME}_place_orphan (file, s) } address = NULL; - if (link_info.relocateable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0) + if (link_info.relocatable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0) address = exp_intop ((bfd_vma) 0); load_base = NULL; @@ -1293,10 +1280,9 @@ gld${EMULATION_NAME}_place_orphan (file, s) os_tail = lang_output_section_statement.tail; os = lang_enter_output_section_statement (secname, address, 0, - (bfd_vma) 0, (etree_type *) NULL, (etree_type *) NULL, - load_base); + load_base, 0); lang_add_section (&os->children, s, os, file); @@ -1422,9 +1408,9 @@ if test x"$LDEMUL_FINISH" != xgld"$EMULATION_NAME"_finish; then cat >>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <> e${EMULATION_NAME}.c -echo ' ; else if (link_info.relocateable) return' >> e${EMULATION_NAME}.c +echo ' ; else if (link_info.relocatable) return' >> e${EMULATION_NAME}.c sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c @@ -1476,6 +1461,10 @@ sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c fi if test -n "$GENERATE_PIE_SCRIPT" ; then if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then +echo ' ; else if (link_info.pie && link_info.combreloc' >> e${EMULATION_NAME}.c +echo ' && link_info.relro' >> e${EMULATION_NAME}.c +echo ' && (link_info.flags & DT_BIND_NOW)) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xdw >> e${EMULATION_NAME}.c echo ' ; else if (link_info.pie && link_info.combreloc) return' >> e${EMULATION_NAME}.c sed $sc ldscripts/${EMULATION_NAME}.xdc >> e${EMULATION_NAME}.c fi @@ -1484,6 +1473,10 @@ sed $sc ldscripts/${EMULATION_NAME}.xd >> e${EMULATION_NAME}.c fi if test -n "$GENERATE_SHLIB_SCRIPT" ; then if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then +echo ' ; else if (link_info.shared && link_info.combreloc' >> e${EMULATION_NAME}.c +echo ' && link_info.relro' >> e${EMULATION_NAME}.c +echo ' && (link_info.flags & DT_BIND_NOW)) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xsw >> e${EMULATION_NAME}.c echo ' ; else if (link_info.shared && link_info.combreloc) return' >> e${EMULATION_NAME}.c sed $sc ldscripts/${EMULATION_NAME}.xsc >> e${EMULATION_NAME}.c fi @@ -1491,6 +1484,9 @@ echo ' ; else if (link_info.shared) return' >> e${EMULATION_NAME}.c sed $sc ldscripts/${EMULATION_NAME}.xs >> e${EMULATION_NAME}.c fi if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then +echo ' ; else if (link_info.combreloc && link_info.relro' >> e${EMULATION_NAME}.c +echo ' && (link_info.flags & DT_BIND_NOW)) return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.xw >> e${EMULATION_NAME}.c echo ' ; else if (link_info.combreloc) return' >> e${EMULATION_NAME}.c sed $sc ldscripts/${EMULATION_NAME}.xc >> e${EMULATION_NAME}.c fi @@ -1505,9 +1501,9 @@ cat >>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <