ld: Add "-z separate-code" option to ELF linker
[deliverable/binutils-gdb.git] / ld / emultempl / elf32.em
index 0ee02bd0ac0e4b86df2d049610c1d94b1743b218..8ff19bf8833f93313b7eecdc3453c7b9bb164688 100644 (file)
@@ -12,7 +12,7 @@ fragment <<EOF
 /* This file is is generated by a shell script.  DO NOT EDIT! */
 
 /* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME}
-   Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   Copyright (C) 1991-2018 Free Software Foundation, Inc.
    Written by Steve Chamberlain <sac@cygnus.com>
    ELF support by Ian Lance Taylor <ian@cygnus.com>
 
@@ -104,7 +104,7 @@ gld${EMULATION_NAME}_before_parse (void)
   config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`;
   config.separate_code = `if test "x${SEPARATE_CODE}" = xyes ; then echo TRUE ; else echo FALSE ; fi`;
   `if test -n "$CALL_NOP_BYTE" ; then echo link_info.call_nop_byte = $CALL_NOP_BYTE; fi`;
-  link_info.check_relocs_after_open_input = `if test "x${CHECK_RELOCS_AFTER_OPEN_INPUT}" = xyes ; then echo TRUE ; else echo FALSE ; fi`;
+  link_info.check_relocs_after_open_input = TRUE;
   link_info.relro = DEFAULT_LD_Z_RELRO;
 }
 
@@ -120,6 +120,13 @@ gld${EMULATION_NAME}_after_parse (void)
   if (bfd_link_pie (&link_info))
     link_info.flags_1 |= (bfd_vma) DF_1_PIE;
 
+  if (bfd_link_executable (&link_info)
+      && link_info.nointerp)
+    {
+      if (link_info.dynamic_undefined_weak > 0)
+       einfo (_("%P: warning: -z dynamic-undefined-weak ignored\n"));
+      link_info.dynamic_undefined_weak = 0;
+    }
   after_parse_default ();
 }
 
@@ -527,7 +534,7 @@ gld${EMULATION_NAME}_search_needed (const char *path,
 
       /* PR 20535: Support the same pseudo-environment variables that
         are supported by ld.so.  Namely, $ORIGIN, $LIB and $PLATFORM.
-         Since there can be more than one occurrence of these tokens in
+        Since there can be more than one occurrence of these tokens in
         the path we loop until no more are found.  Since we might not
         be able to substitute some of the tokens we maintain an offset
         into the filename for where we should begin our scan.  */
@@ -664,8 +671,8 @@ gld${EMULATION_NAME}_search_needed (const char *path,
                /* Restore the path separator.  */
                * end = '/';
 
-             /* PR 20784: Make sure that we resume the scan
-                *after* the token that we could not replace.  */
+             /* PR 20784: Make sure that we resume the scan *after*
+                the token that we could not replace.  */
              offset = (var + 1) - filename;
            }
 
@@ -1701,34 +1708,36 @@ gld${EMULATION_NAME}_before_allocation (void)
       /* 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;
-           }
-       }
+       {
+         struct elf_link_hash_table *htab = elf_hash_table (&link_info);
+         struct elf_link_hash_entry *h
+           = elf_link_hash_lookup (htab, "__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))
+           {
+             const struct elf_backend_data *bed;
+             bed = get_elf_backend_data (link_info.output_bfd);
+             (*bed->elf_backend_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
@@ -1931,7 +1940,7 @@ gld${EMULATION_NAME}_open_dynamic_archive
         filename we recorded earlier.  */
 
       if (!entry->flags.full_name_provided)
-        filename = lbasename (entry->filename);
+       filename = lbasename (entry->filename);
       bfd_elf_set_dt_needed_name (entry->the_bfd, filename);
     }
 
@@ -2358,35 +2367,71 @@ if test -n "$GENERATE_PIE_SCRIPT" ; then
 if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
 echo '  ; else if (bfd_link_pie (&link_info)'          >> e${EMULATION_NAME}.c
 echo '             && link_info.combreloc'             >> e${EMULATION_NAME}.c
+echo '             && link_info.separate_code'         >> e${EMULATION_NAME}.c
+echo '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xdwe               >> e${EMULATION_NAME}.c
+echo '  ; else if (bfd_link_pie (&link_info)'          >> e${EMULATION_NAME}.c
+echo '             && link_info.combreloc'             >> e${EMULATION_NAME}.c
 echo '             && link_info.relro'                 >> e${EMULATION_NAME}.c
 echo '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
 sed $sc ldscripts/${EMULATION_NAME}.xdw                        >> e${EMULATION_NAME}.c
 echo '  ; else if (bfd_link_pie (&link_info)'          >> e${EMULATION_NAME}.c
+echo '             && link_info.separate_code'         >> e${EMULATION_NAME}.c
+echo '             && link_info.combreloc) return'     >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xdce               >> e${EMULATION_NAME}.c
+echo '  ; else if (bfd_link_pie (&link_info)'          >> e${EMULATION_NAME}.c
 echo '             && link_info.combreloc) return'     >> e${EMULATION_NAME}.c
 sed $sc ldscripts/${EMULATION_NAME}.xdc                        >> e${EMULATION_NAME}.c
 fi
+echo '  ; else if (bfd_link_pie (&link_info)'          >> e${EMULATION_NAME}.c
+echo '             && link_info.separate_code) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xde                        >> e${EMULATION_NAME}.c
 echo '  ; else if (bfd_link_pie (&link_info)) 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 (bfd_link_dll (&link_info) && link_info.combreloc' >> e${EMULATION_NAME}.c
-echo '             && link_info.relro' >> e${EMULATION_NAME}.c
+echo '  ; else if (bfd_link_dll (&link_info)'          >> e${EMULATION_NAME}.c
+echo '             && link_info.combreloc'             >> e${EMULATION_NAME}.c
+echo '             && link_info.separate_code'         >> e${EMULATION_NAME}.c
+echo '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xswe               >> e${EMULATION_NAME}.c
+echo '  ; else if (bfd_link_dll (&link_info)'          >> e${EMULATION_NAME}.c
+echo '             && link_info.combreloc'             >> e${EMULATION_NAME}.c
+echo '             && link_info.relro'                 >> e${EMULATION_NAME}.c
 echo '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
 sed $sc ldscripts/${EMULATION_NAME}.xsw                        >> e${EMULATION_NAME}.c
-echo '  ; else if (bfd_link_dll (&link_info) && link_info.combreloc) return' >> e${EMULATION_NAME}.c
+echo '  ; else if (bfd_link_dll (&link_info)'          >> e${EMULATION_NAME}.c
+echo '             && link_info.combreloc'             >> e${EMULATION_NAME}.c
+echo '             && link_info.separate_code) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xsce                       >> e${EMULATION_NAME}.c
+echo '  ; else if (bfd_link_dll (&link_info)'          >> e${EMULATION_NAME}.c
+echo '             && link_info.combreloc) return'     >> e${EMULATION_NAME}.c
 sed $sc ldscripts/${EMULATION_NAME}.xsc                        >> e${EMULATION_NAME}.c
 fi
+echo '  ; else if (bfd_link_dll (&link_info)'          >> e${EMULATION_NAME}.c
+echo '             && link_info.separate_code) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xse                        >> e${EMULATION_NAME}.c
 echo '  ; else if (bfd_link_dll (&link_info)) 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 '  ; else if (link_info.combreloc'                        >> e${EMULATION_NAME}.c
+echo '             && link_info.separate_code'         >> e${EMULATION_NAME}.c
+echo '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xwe                        >> e${EMULATION_NAME}.c
+echo '  ; else if (link_info.combreloc'                        >> e${EMULATION_NAME}.c
+echo '             && link_info.relro'                 >> e${EMULATION_NAME}.c
 echo '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
 sed $sc ldscripts/${EMULATION_NAME}.xw                 >> e${EMULATION_NAME}.c
+echo '  ; else if (link_info.combreloc'                        >> e${EMULATION_NAME}.c
+echo '             && link_info.separate_code) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xce                        >> 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 if (link_info.separate_code) return'            >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xe                 >> 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
@@ -2419,15 +2464,30 @@ fragment <<EOF
           && link_info.combreloc
           && link_info.relro
           && (link_info.flags & DF_BIND_NOW))
-    return "ldscripts/${EMULATION_NAME}.xdw";
+    {
+      if (link_info.separate_code)
+       return "ldscripts/${EMULATION_NAME}.xdwe";
+      else
+       return "ldscripts/${EMULATION_NAME}.xdw";
+    }
   else if (bfd_link_pie (&link_info)
           && link_info.combreloc)
-    return "ldscripts/${EMULATION_NAME}.xdc";
+    {
+      if (link_info.separate_code)
+       return "ldscripts/${EMULATION_NAME}.xdce";
+      else
+       return "ldscripts/${EMULATION_NAME}.xdc";
+    }
 EOF
 fi
 fragment <<EOF
   else if (bfd_link_pie (&link_info))
-    return "ldscripts/${EMULATION_NAME}.xd";
+    {
+      if (link_info.separate_code)
+       return "ldscripts/${EMULATION_NAME}.xde";
+      else
+       return "ldscripts/${EMULATION_NAME}.xd";
+    }
 EOF
 fi
 if test -n "$GENERATE_SHLIB_SCRIPT" ; then
@@ -2435,28 +2495,58 @@ if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
 fragment <<EOF
   else if (bfd_link_dll (&link_info) && link_info.combreloc
           && link_info.relro && (link_info.flags & DF_BIND_NOW))
-    return "ldscripts/${EMULATION_NAME}.xsw";
+    {
+      if (link_info.separate_code)
+       return "ldscripts/${EMULATION_NAME}.xswe";
+      else
+       return "ldscripts/${EMULATION_NAME}.xsw";
+    }
   else if (bfd_link_dll (&link_info) && link_info.combreloc)
-    return "ldscripts/${EMULATION_NAME}.xsc";
+    {
+      if (link_info.separate_code)
+       return "ldscripts/${EMULATION_NAME}.xsce";
+      else
+       return "ldscripts/${EMULATION_NAME}.xsc";
+    }
 EOF
 fi
 fragment <<EOF
   else if (bfd_link_dll (&link_info))
-    return "ldscripts/${EMULATION_NAME}.xs";
+    {
+      if (link_info.separate_code)
+       return "ldscripts/${EMULATION_NAME}.xse";
+      else
+       return "ldscripts/${EMULATION_NAME}.xs";
+    }
 EOF
 fi
 if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
 fragment <<EOF
   else if (link_info.combreloc && link_info.relro
           && (link_info.flags & DF_BIND_NOW))
-    return "ldscripts/${EMULATION_NAME}.xw";
+    {
+      if (link_info.separate_code)
+       return "ldscripts/${EMULATION_NAME}.xwe";
+      else
+       return "ldscripts/${EMULATION_NAME}.xw";
+    }
   else if (link_info.combreloc)
-    return "ldscripts/${EMULATION_NAME}.xc";
+    {
+      if (link_info.separate_code)
+       return "ldscripts/${EMULATION_NAME}.xce";
+      else
+       return "ldscripts/${EMULATION_NAME}.xc";
+    }
 EOF
 fi
 fragment <<EOF
   else
-    return "ldscripts/${EMULATION_NAME}.x";
+    {
+      if (link_info.separate_code)
+       return "ldscripts/${EMULATION_NAME}.xe";
+      else
+       return "ldscripts/${EMULATION_NAME}.x";
+    }
 }
 
 EOF
@@ -2726,6 +2816,10 @@ fragment <<EOF
        link_info.relro = TRUE;
       else if (strcmp (optarg, "norelro") == 0)
        link_info.relro = FALSE;
+      else if (strcmp (optarg, "separate-code") == 0)
+       link_info.separate_code = TRUE;
+      else if (strcmp (optarg, "noseparate-code") == 0)
+       link_info.separate_code = FALSE;
       else if (strcmp (optarg, "common") == 0)
        link_info.elf_stt_common = elf_stt_common;
       else if (strcmp (optarg, "nocommon") == 0)
@@ -2804,6 +2898,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
   ${LDEMUL_HLL-hll_default},
   ${LDEMUL_AFTER_PARSE-gld${EMULATION_NAME}_after_parse},
   ${LDEMUL_AFTER_OPEN-gld${EMULATION_NAME}_after_open},
+  ${LDEMUL_AFTER_CHECK_RELOCS-after_check_relocs_default},
   ${LDEMUL_AFTER_ALLOCATION-gld${EMULATION_NAME}_after_allocation},
   ${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default},
   ${LDEMUL_CHOOSE_TARGET-ldemul_default_target},
This page took 0.030166 seconds and 4 git commands to generate.