Locale changes from Bruno Haible <haible@clisp.cons.org>.
[deliverable/binutils-gdb.git] / ld / emultempl / elf32.em
index c0d52b1020553fb111f86083c83feba25243440c..f2011cece4b355814363b6d220e8e36da69d44aa 100644 (file)
@@ -3,6 +3,11 @@
 # This file is now misnamed, because it supports both 32 bit and 64 bit
 # ELF emulations.
 test -z "${ELFSIZE}" && ELFSIZE=32
+if [ -z "$MACHINE" ]; then
+  OUTPUT_ARCH=${ARCH}
+else
+  OUTPUT_ARCH=${ARCH}:${MACHINE}
+fi
 cat >e${EMULATION_NAME}.c <<EOF
 /* This file is is generated by a shell script.  DO NOT EDIT! */
 
@@ -33,8 +38,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "bfd.h"
 #include "sysdep.h"
 #include "libiberty.h"
-
-#include <ctype.h>
+#include "safe-ctype.h"
 
 #include "bfdlink.h"
 
@@ -48,27 +52,36 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "ldgram.h"
 #include "elf/common.h"
 
-static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
+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}_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}_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 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 ((void));
+static lang_output_section_statement_type *output_rel_find
+  PARAMS ((void));
+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 char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
+static char *gld${EMULATION_NAME}_get_script
+  PARAMS ((int *isfile));
 
 EOF
 
@@ -90,7 +103,15 @@ cat >>e${EMULATION_NAME}.c <<EOF
 static void
 gld${EMULATION_NAME}_before_parse ()
 {
-  ldfile_output_architecture = bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`;
+  const bfd_arch_info_type *arch = bfd_scan_arch ("${OUTPUT_ARCH}");
+  if (arch)
+    {
+      ldfile_output_architecture = arch->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`;
 }
@@ -226,8 +247,7 @@ gld${EMULATION_NAME}_stat_needed (s)
   if (soname == NULL)
     soname = basename (s->filename);
 
-  if (strncmp (soname, global_needed->name,
-              suffix - global_needed->name) == 0)
+  if (strncmp (soname, global_needed->name, suffix - global_needed->name) == 0)
     einfo ("%P: warning: %s, needed by %B, may conflict with %s\n",
           global_needed->name, global_needed->by, soname);
 }
@@ -250,12 +270,12 @@ gld${EMULATION_NAME}_try_needed (name, force)
     return false;
   if (! bfd_check_format (abfd, bfd_object))
     {
-      (void) bfd_close (abfd);
+      bfd_close (abfd);
       return false;
     }
   if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
     {
-      (void) bfd_close (abfd);
+      bfd_close (abfd);
       return false;
     }
 
@@ -278,7 +298,7 @@ gld${EMULATION_NAME}_try_needed (name, force)
          lang_for_each_input_file (gld${EMULATION_NAME}_vercheck);
          if (global_vercheck_failed)
            {
-             (void) bfd_close (abfd);
+             bfd_close (abfd);
              /* Return false to force the caller to move on to try
                  another file on the search path.  */
              return false;
@@ -303,7 +323,7 @@ case ${target} in
                break;
            if (l == NULL)
              {
-               (void) bfd_close (abfd);
+               bfd_close (abfd);
                return false;
              }
          }
@@ -347,6 +367,9 @@ cat >>e${EMULATION_NAME}.c <<EOF
      DT_NEEDED entry for this file.  */
   bfd_elf_set_dt_needed_name (abfd, "");
 
+  /* Previos basename call was clobbered in lang_for_each_input_file.  */
+  soname = basename (abfd->filename);
+
   /* Tell the ELF backend that the output file needs a DT_NEEDED
      entry for this file if it is used to resolve the reference in
      a regular object.  */
@@ -789,6 +812,18 @@ gld${EMULATION_NAME}_find_statement_assignment (s)
 EOF
 
 if test x"$LDEMUL_BEFORE_ALLOCATION" != xgld"$EMULATION_NAME"_before_allocation; then
+  if test x"${ELF_INTERPRETER_NAME+set}" = xset; then
+    ELF_INTERPRETER_SET_DEFAULT="
+  if (sinterp != NULL)
+    {
+      sinterp->contents = ${ELF_INTERPRETER_NAME};
+      sinterp->_raw_size = strlen (sinterp->contents) + 1;
+    }
+
+"
+  else
+    ELF_INTERPRETER_SET_DEFAULT=
+  fi
 cat >>e${EMULATION_NAME}.c <<EOF
 
 /* This is called after the sections have been attached to output
@@ -812,11 +847,11 @@ gld${EMULATION_NAME}_before_allocation ()
     rpath = (const char *) getenv ("LD_RUN_PATH");
   if (! (bfd_elf${ELFSIZE}_size_dynamic_sections
          (output_bfd, command_line.soname, rpath,
-         command_line.export_dynamic, command_line.filter_shlib,
+         command_line.filter_shlib,
          (const char * const *) command_line.auxiliary_filters,
          &link_info, &sinterp, lang_elf_version_info)))
     einfo ("%P%F: failed to set dynamic section sizes: %E\n");
-
+${ELF_INTERPRETER_SET_DEFAULT}
   /* Let the user override the dynamic linker we are using.  */
   if (command_line.interpreter != NULL
       && sinterp != NULL)
@@ -948,6 +983,8 @@ gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry)
 
 EOF
 fi
+
+if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then
 cat >>e${EMULATION_NAME}.c <<EOF
 
 /* A variant of lang_output_section_find.  Used by place_orphan.  */
@@ -973,10 +1010,31 @@ output_rel_find ()
   return (lang_output_section_statement_type *) NULL;
 }
 
-EOF
+/* Find the last output section before given output statement.
+   Used by place_orphan.  */
 
-if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then
-cat >>e${EMULATION_NAME}.c <<EOF
+static asection *
+output_prev_sec_find (os)
+     lang_output_section_statement_type *os;
+{
+  asection *s = (asection *) NULL;
+  lang_statement_union_type *u;
+  lang_output_section_statement_type *lookup;
+
+  for (u = lang_output_section_statement.head;
+       u != (lang_statement_union_type *) NULL;
+       u = lookup->next)
+    {
+      lookup = &u->output_section_statement;
+      if (lookup == os)
+       return s;
+
+      if (lookup->bfd_section != NULL && lookup->bfd_section->owner != NULL)
+       s = lookup->bfd_section;
+    }
+
+  return NULL;
+}
 
 /* Place an orphan section.  We use this to put random SHF_ALLOC
    sections in the right segment.  */
@@ -1017,12 +1075,13 @@ gld${EMULATION_NAME}_place_orphan (file, s)
       os = lang_output_section_find (secname);
 
       if (os != NULL
-         && os->bfd_section != NULL
-         && ((s->flags ^ os->bfd_section->flags)
-             & (SEC_LOAD | SEC_ALLOC)) == 0)
+         && (os->bfd_section == NULL
+             || ((s->flags ^ os->bfd_section->flags)
+                 & (SEC_LOAD | SEC_ALLOC)) == 0))
        {
-         /* We have already placed a section with this name.  */
-         wild_doit (&os->children, s, os, file);
+         /* 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;
        }
     }
@@ -1037,7 +1096,7 @@ gld${EMULATION_NAME}_place_orphan (file, s)
       && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0
       && hold_text.os != NULL)
     {
-      wild_doit (&hold_text.os->children, s, hold_text.os, file);
+      lang_add_section (&hold_text.os->children, s, hold_text.os, file);
       return true;
     }
 
@@ -1050,7 +1109,11 @@ gld${EMULATION_NAME}_place_orphan (file, s)
 (hold.os != NULL || (hold.os = lang_output_section_find (name)) != NULL)
 
   if (s->flags & SEC_EXCLUDE)
-    return false;
+    {
+      if (s->output_section == NULL)
+       s->output_section = bfd_abs_section_ptr;
+      return true;
+    }
 
   place = NULL;
   if ((s->flags & SEC_ALLOC) == 0)
@@ -1071,7 +1134,25 @@ gld${EMULATION_NAME}_place_orphan (file, s)
   else if (strncmp (secname, ".rel", 4) == 0
           && (hold_rel.os != NULL
               || (hold_rel.os = output_rel_find ()) != NULL))
-    place = &hold_rel;
+    {
+      if (! link_info.relocateable && link_info.combreloc)
+       {
+         if (strncmp (secname, ".rela", 5) == 0)
+           os = lang_output_section_find (".rela.dyn");
+         else
+           os = lang_output_section_find (".rel.dyn");
+
+         if (os != NULL
+             && os->bfd_section != NULL
+             && ((s->flags ^ os->bfd_section->flags)
+                 & (SEC_LOAD | SEC_ALLOC)) == 0)
+           {
+             lang_add_section (&os->children, s, os, file);
+             return true;
+           }
+       }
+      place = &hold_rel;
+    }
   else if ((s->flags & (SEC_CODE | SEC_READONLY)) == SEC_READONLY
           && HAVE_SECTION (hold_rodata, ".rodata"))
     place = &hold_rodata;
@@ -1112,7 +1193,7 @@ gld${EMULATION_NAME}_place_orphan (file, s)
       /* If the name of the section is representable in C, then create
         symbols to mark the start and the end of the section.  */
       for (ps = outsecname; *ps != '\0'; ps++)
-       if (! isalnum ((unsigned char) *ps) && *ps != '_')
+       if (! ISALNUM (*ps) && *ps != '_')
          break;
       if (*ps == '\0')
        {
@@ -1138,7 +1219,7 @@ gld${EMULATION_NAME}_place_orphan (file, s)
                                            (etree_type *) NULL,
                                            (etree_type *) NULL);
 
-  wild_doit (&os->children, s, os, file);
+  lang_add_section (&os->children, s, os, file);
 
   lang_leave_output_section_statement
     ((bfd_vma) 0, "*default*",
@@ -1167,29 +1248,26 @@ gld${EMULATION_NAME}_place_orphan (file, s)
       asection *snew, **pps;
 
       snew = os->bfd_section;
-      if (place->section != NULL
-         || (place->os->bfd_section != NULL
-             && place->os->bfd_section != snew))
+
+      /* Shuffle the bfd section list to make the output file look
+        neater.  This is really only cosmetic.  */
+      if (place->section == NULL)
        {
-         /* Shuffle the section to make the output file look neater.
-            This is really only cosmetic.  */
-         if (place->section == NULL)
-           {
-#if 0
-             /* Finding the end of the list is a little tricky.  We
-                make a wild stab at it by comparing section flags.  */
-             flagword first_flags = place->os->bfd_section->flags;
-             for (pps = &place->os->bfd_section->next;
-                  *pps != NULL && (*pps)->flags == first_flags;
-                  pps = &(*pps)->next)
-               ;
-             place->section = pps;
-#else
-             /* Put orphans after the first section on the list.  */
-             place->section = &place->os->bfd_section->next;
-#endif
-           }
+         asection *bfd_section = place->os->bfd_section;
+
+         /* If the output statement hasn't been used to place
+            any input sections (and thus doesn't have an output
+            bfd_section), look for the closest prior output statement
+            having an output section.  */
+         if (bfd_section == NULL)
+           bfd_section = output_prev_sec_find (place->os);
 
+         if (bfd_section != NULL && bfd_section != snew)
+           place->section = &bfd_section->next;
+       }
+
+      if (place->section != NULL)
+       {
          /*  Unlink the section.  */
          for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
            ;
@@ -1199,13 +1277,22 @@ gld${EMULATION_NAME}_place_orphan (file, s)
          snew->next = *place->section;
          *place->section = snew;
        }
-      place->section = &snew->next;    /* Save the end of this list.  */
 
+      /* Save the end of this list.  Further ophans of this type will
+        follow the one we've just added.  */
+      place->section = &snew->next;
+
+      /* The following is non-cosmetic.  We try to put the output
+        statements in some sort of reasonable order here, because
+        they determine the final load addresses of the orphan
+        sections.  In addition, placing output statements in the
+        wrong order may require extra segments.  For instance,
+        given a typical situation of all read-only sections placed
+        in one segment and following that a segment containing all
+        the read-write sections, we wouldn't want to place an orphan
+        read/write section before or amongst the read-only ones.  */
       if (add.head != NULL)
        {
-         /* We try to put the output statements in some sort of
-            reasonable order here, because they determine the final
-            load addresses of the orphan sections.  */
          if (place->stmt == NULL)
            {
              /* Put the new statement list right at the head.  */
@@ -1262,14 +1349,18 @@ echo '  ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}
 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
 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_SHLIB_SCRIPT" ; then
+echo '  ; else if (link_info.shared && link_info.combreloc) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xsc                    >> 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
-
+echo '  ; else if (link_info.combreloc) return'            >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xc                     >> 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
@@ -1422,6 +1513,10 @@ cat >>e${EMULATION_NAME}.c <<EOF
        }
       else if (strcmp (optarg, "defs") == 0)
        link_info.no_undefined = true;
+      else if (strcmp (optarg, "combreloc") == 0)
+       link_info.combreloc = true;
+      else if (strcmp (optarg, "nocombreloc") == 0)
+       link_info.combreloc = false;
       /* What about the other Solaris -z options? FIXME.  */
       break;
 EOF
This page took 0.028416 seconds and 4 git commands to generate.