X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=ld%2Femultempl%2Felf32.em;h=89c5d5d0e55a83abfb8d309f3e5d9f0869ab12c7;hb=e49f502242bc5fc72547397cd344aea5b9f53a14;hp=4fee5fb85569a5f6484b98d97bcb4074e46e6aa6;hpb=a8927cfd1ab2dac807c4d22428f3dbfd3c9d8713;p=deliverable%2Fbinutils-gdb.git diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index 4fee5fb855..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 @@ -39,6 +39,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sysdep.h" #include "libiberty.h" #include "safe-ctype.h" +#include "getopt.h" #include "bfdlink.h" @@ -49,41 +50,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "ldlang.h" #include "ldfile.h" #include "ldemul.h" -#include "ldgram.h" +#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 boolean gld${EMULATION_NAME}_try_needed - PARAMS ((const char *, int)); -static 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 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 *)); -static 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)); +/* 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 + (lang_input_statement_type *file, asection *s); +static void gld${EMULATION_NAME}_finish (void); EOF @@ -103,24 +79,38 @@ 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/:.*//'`; - config.dynamic_link = ${DYNAMIC_LINK-true}; - config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo true ; else echo false ; fi`; + 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`; } 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 <>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. */ - global_vercheck_failed = true; + 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; } } @@ -204,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; @@ -225,7 +213,7 @@ gld${EMULATION_NAME}_stat_needed (s) if (st.st_dev == global_stat.st_dev && st.st_ino == global_stat.st_ino) { - global_found = true; + global_found = TRUE; return; } @@ -259,33 +247,31 @@ gld${EMULATION_NAME}_stat_needed (s) named by a DT_NEEDED entry. The FORCE parameter indicates whether to skip the check for a conflicting version. */ -static boolean -gld${EMULATION_NAME}_try_needed (name, force) - const char *name; - int force; +static bfd_boolean +gld${EMULATION_NAME}_try_needed (const char *name, int force) { bfd *abfd; const char *soname; abfd = bfd_openr (name, bfd_get_target (output_bfd)); if (abfd == NULL) - return false; + return FALSE; if (! bfd_check_format (abfd, bfd_object)) { bfd_close (abfd); - return false; + return FALSE; } if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0) { bfd_close (abfd); - return false; + return FALSE; } /* For DT_NEEDED, they have to match. */ if (abfd->xvec != output_bfd->xvec) { bfd_close (abfd); - return false; + return FALSE; } /* Check whether this object would include any conflicting library @@ -303,22 +289,22 @@ gld${EMULATION_NAME}_try_needed (name, force) if (needed != NULL) { global_vercheck_needed = needed; - global_vercheck_failed = false; + global_vercheck_failed = FALSE; lang_for_each_input_file (gld${EMULATION_NAME}_vercheck); if (global_vercheck_failed) { bfd_close (abfd); - /* Return false to force the caller to move on to try - another file on the search path. */ - return false; + /* Return FALSE to force the caller to move on to try + 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 @@ -333,7 +319,7 @@ case ${target} in if (l == NULL) { bfd_close (abfd); - return false; + return FALSE; } } @@ -363,39 +349,35 @@ 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 <filename, global_needed->name) == 0) { - global_found = true; + global_found = TRUE; return; } @@ -560,7 +582,7 @@ gld${EMULATION_NAME}_check_needed (s) if (f != NULL && strcmp (f + 1, global_needed->name) == 0) { - global_found = true; + global_found = TRUE; return; } } @@ -574,7 +596,7 @@ gld${EMULATION_NAME}_check_needed (s) if (soname != NULL && strcmp (soname, global_needed->name) == 0) { - global_found = true; + global_found = TRUE; return; } } @@ -588,12 +610,12 @@ cat >>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <name, force)) break; EOF -if [ "x${host}" = "x${target}" ] ; then - case " ${EMULATION_LIBPATH} " in - *" ${EMULATION_NAME} "*) +if [ "x${USE_LIBPATH}" = xyes ] ; then cat >>e${EMULATION_NAME}.c <name, force)) break; +EOF +fi +if [ "x${NATIVE}" = xyes ] ; then +cat >>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <name, force)) break; - +EOF +fi +if [ "x${USE_LIBPATH}" = xyes ] ; then +cat >>e${EMULATION_NAME}.c <next) { + char *tmpname = gld${EMULATION_NAME}_add_sysroot (rp->name); found = (rp->by == l->by - && gld${EMULATION_NAME}_search_needed (rp->name, + && gld${EMULATION_NAME}_search_needed (tmpname, l->name, force)); + free (tmpname); } if (found) break; EOF - ;; - esac fi cat >>e${EMULATION_NAME}.c <name); @@ -713,19 +736,15 @@ cat >>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <name, force)) break; EOF - # Linux - ;; - esac - ;; + # Linux + ;; esac fi cat >>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <assign.dst, - false, false, false); + FALSE, FALSE, FALSE); if (h == NULL) break; @@ -772,9 +790,9 @@ gld${EMULATION_NAME}_find_exp_assignment (exp) case etree_assign: if (strcmp (exp->assign.dst, ".") != 0) { - if (! (bfd_elf${ELFSIZE}_record_link_assignment + if (! (bfd_elf_record_link_assignment (output_bfd, &link_info, exp->assign.dst, - exp->type.node_class == etree_provide ? true : false))) + exp->type.node_class == etree_provide ? TRUE : FALSE))) einfo ("%P%F: failed to record assignment to %s: %E\n", exp->assign.dst); } @@ -808,8 +826,7 @@ gld${EMULATION_NAME}_find_exp_assignment (exp) symbols which are referred to by dynamic objects. */ static void -gld${EMULATION_NAME}_find_statement_assignment (s) - lang_statement_union_type *s; +gld${EMULATION_NAME}_find_statement_assignment (lang_statement_union_type *s) { if (s->header.type == lang_assignment_statement_enum) gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp); @@ -836,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. */ @@ -851,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))) @@ -876,8 +896,10 @@ ${ELF_INTERPRETER_SET_DEFAULT} { asection *s; bfd_size_type sz; + bfd_size_type prefix_len; char *msg; - boolean ret; + bfd_boolean ret; + const char * gnu_warning_prefix = _("warning: "); if (is->just_syms_flag) continue; @@ -887,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, @@ -916,17 +941,15 @@ cat >>e${EMULATION_NAME}.c <is_archive) - return false; + return FALSE; filename = entry->filename; @@ -954,7 +977,7 @@ gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry) if (! ldfile_try_open_bfd (string, entry)) { free (string); - return false; + return FALSE; } entry->filename = string; @@ -984,7 +1007,7 @@ gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry) bfd_elf_set_dt_needed_name (entry->the_bfd, filename); } - return true; + return TRUE; } EOF @@ -996,12 +1019,12 @@ cat >>e${EMULATION_NAME}.c <name[4] == 'a'; @@ -1009,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) @@ -1035,6 +1067,9 @@ output_rel_find (sec) if (last_rel) return last_rel; + if (last_alloc) + return last_alloc; + return last; } @@ -1042,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; @@ -1071,12 +1105,11 @@ struct orphan_save { lang_output_section_statement_type *os; asection **section; lang_statement_union_type **stmt; + lang_statement_union_type **os_tail; }; -static boolean -gld${EMULATION_NAME}_place_orphan (file, s) - lang_input_statement_type *file; - asection *s; +static bfd_boolean +gld${EMULATION_NAME}_place_orphan (lang_input_statement_type *file, asection *s) { static struct orphan_save hold_text; static struct orphan_save hold_rodata; @@ -1093,10 +1126,12 @@ gld${EMULATION_NAME}_place_orphan (file, s) const char *secname; const char *ps = NULL; lang_output_section_statement_type *os; + lang_statement_union_type **os_tail; + etree_type *load_base; 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) @@ -1108,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); @@ -1121,7 +1156,7 @@ gld${EMULATION_NAME}_place_orphan (file, s) /* We already have an output section statement with this name, and its bfd section, if any, has compatible flags. */ lang_add_section (&os->children, s, os, file); - return true; + return TRUE; } } @@ -1130,13 +1165,13 @@ 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.shared - && ! link_info.relocateable + if (link_info.executable + && ! link_info.relocatable && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0 && hold_text.os != NULL) { lang_add_section (&hold_text.os->children, s, hold_text.os, file); - return true; + return TRUE; } /* Decide which segment the section should go in based on the @@ -1147,11 +1182,13 @@ 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; - return true; + return TRUE; } place = NULL; @@ -1173,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")) @@ -1227,16 +1264,25 @@ gld${EMULATION_NAME}_place_orphan (file, s) } } - if (link_info.relocateable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0) + address = NULL; + if (link_info.relocatable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0) address = exp_intop ((bfd_vma) 0); - else - address = NULL; + load_base = NULL; + if (place != NULL && place->os->load_base != NULL) + { + etree_type *lma_from_vma; + lma_from_vma = exp_binop ('-', place->os->load_base, + exp_nameop (ADDR, place->os->name)); + load_base = exp_binop ('+', lma_from_vma, + exp_nameop (ADDR, secname)); + } + + 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, - (etree_type *) NULL); + load_base, 0); lang_add_section (&os->children, s, os, file); @@ -1311,11 +1357,15 @@ gld${EMULATION_NAME}_place_orphan (file, s) read/write section before or amongst the read-only ones. */ if (add.head != NULL) { + lang_statement_union_type *newly_added_os; + if (place->stmt == NULL) { /* Put the new statement list right at the head. */ *add.tail = place->os->header.next; place->os->header.next = add.head; + + place->os_tail = &place->os->next; } else { @@ -1331,10 +1381,25 @@ gld${EMULATION_NAME}_place_orphan (file, s) /* Save the end of this list. */ place->stmt = add.tail; + + /* Do the same for the list of output section statements. */ + newly_added_os = *os_tail; + *os_tail = NULL; + newly_added_os->output_section_statement.next = *place->os_tail; + *place->os_tail = newly_added_os; + place->os_tail = &newly_added_os->output_section_statement.next; + + /* Fixing the global list pointer here is a little different. + We added to the list in lang_enter_output_section_statement, + trimmed off the new output_section_statment above when + assigning *os_tail = NULL, but possibly added it back in + the same place when assigning *place->os_tail. */ + if (*os_tail == NULL) + lang_output_section_statement.tail = os_tail; } } - return true; + return TRUE; } EOF fi @@ -1343,15 +1408,15 @@ if test x"$LDEMUL_FINISH" != xgld"$EMULATION_NAME"_finish; then cat >>e${EMULATION_NAME}.c <head, abs_output_section, - &stat_ptr->head, 0, (bfd_vma) 0, NULL); + &stat_ptr->head, 0, (bfd_vma) 0, NULL, TRUE); /* Redo special stuff. */ ldemul_after_allocation (); @@ -1368,8 +1433,7 @@ if test x"$LDEMUL_GET_SCRIPT" != xgld"$EMULATION_NAME"_get_script; then cat >>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <> e${EMULATION_NAME}.c -echo ' ; else if (link_info.relocateable == true) 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 +sed $sc ldscripts/${EMULATION_NAME}.xu >> 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 if cmp -s ldscripts/${EMULATION_NAME}.x ldscripts/${EMULATION_NAME}.xn; then : ; else -echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c +echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c +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 +echo ' ; else if (link_info.pie) return' >> e${EMULATION_NAME}.c +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 +sed $sc ldscripts/${EMULATION_NAME}.xsc >> e${EMULATION_NAME}.c fi -echo ' ; else if (link_info.shared) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xs >> e${EMULATION_NAME}.c +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) return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.xc >> e${EMULATION_NAME}.c +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 -echo ' ; else return' >> e${EMULATION_NAME}.c -sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c -echo '; }' >> e${EMULATION_NAME}.c +echo ' ; else return' >> e${EMULATION_NAME}.c +sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c +echo '; }' >> e${EMULATION_NAME}.c else # Scripts read from the filesystem. @@ -1418,16 +1501,60 @@ 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 <>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 <