* emultempl/elf32.em (output_prev_sec_find): New.
[binutils-gdb.git] / ld / emultempl / elf32.em
index e890c75e8960d492d96c998f131579a3ae550e9f..67e0d250b22a9f162155934c4bf017071451766d 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! */
 
@@ -32,6 +37,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>
 
@@ -89,7 +95,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`;
 }
@@ -130,7 +144,7 @@ static void
 gld${EMULATION_NAME}_vercheck (s)
      lang_input_statement_type *s;
 {
-  const char *soname, *f;
+  const char *soname;
   struct bfd_link_needed_list *l;
 
   if (global_vercheck_failed)
@@ -141,19 +155,13 @@ gld${EMULATION_NAME}_vercheck (s)
 
   soname = bfd_elf_get_dt_soname (s->the_bfd);
   if (soname == NULL)
-    soname = bfd_get_filename (s->the_bfd);
-
-  f = strrchr (soname, '/');
-  if (f != NULL)
-    ++f;
-  else
-    f = soname;
+    soname = basename (bfd_get_filename (s->the_bfd));
 
   for (l = global_vercheck_needed; l != NULL; l = l->next)
     {
       const char *suffix;
 
-      if (strcmp (f, l->name) == 0)
+      if (strcmp (soname, l->name) == 0)
        {
          /* Probably can't happen, but it's an easy check.  */
          continue;
@@ -168,7 +176,7 @@ gld${EMULATION_NAME}_vercheck (s)
 
       suffix += sizeof ".so." - 1;
 
-      if (strncmp (f, l->name, suffix - l->name) == 0)
+      if (strncmp (soname, l->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
@@ -192,7 +200,6 @@ gld${EMULATION_NAME}_stat_needed (s)
   struct stat st;
   const char *suffix;
   const char *soname;
-  const char *f;
 
   if (global_found)
     return;
@@ -230,17 +237,12 @@ gld${EMULATION_NAME}_stat_needed (s)
 
   soname = bfd_elf_get_dt_soname (s->the_bfd);
   if (soname == NULL)
-    soname = s->filename;
-
-  f = strrchr (soname, '/');
-  if (f != NULL)
-    ++f;
-  else
-    f = soname;
+    soname = basename (s->filename);
 
-  if (strncmp (f, 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, f);
+          global_needed->name, global_needed->by, soname);
 }
 
 
@@ -340,11 +342,7 @@ cat >>e${EMULATION_NAME}.c <<EOF
     einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd);
 
   /* First strip off everything before the last '/'.  */
-  soname = strrchr (abfd->filename, '/');
-  if (soname)
-    soname++;
-  else
-    soname = abfd->filename;
+  soname = basename (abfd->filename);
 
   if (trace_file_tries)
     info_msg (_("found %s at %s\n"), soname, name);
@@ -362,6 +360,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.  */
@@ -386,6 +387,9 @@ gld${EMULATION_NAME}_search_needed (path, name, force)
   const char *s;
   size_t len;
 
+  if (name[0] == '/')
+    return gld${EMULATION_NAME}_try_needed (name, force);
+
   if (path == NULL || *path == '\0')
     return false;
   len = strlen (name);
@@ -801,6 +805,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
@@ -824,11 +840,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)
@@ -946,20 +962,13 @@ gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry)
   if (bfd_check_format (entry->the_bfd, bfd_object)
       && (entry->the_bfd->flags & DYNAMIC) != 0)
     {
-      char *needed_name;
-
       ASSERT (entry->is_archive && entry->search_dirs_flag);
 
       /* Rather than duplicating the logic above.  Just use the
-        filename we recorded earlier.
-
-        First strip off everything before the last '/'.  */
-      filename = strrchr (entry->filename, '/');
-      filename++;
+        filename we recorded earlier.  */
 
-      needed_name = (char *) xmalloc (strlen (filename) + 1);
-      strcpy (needed_name, filename);
-      bfd_elf_set_dt_needed_name (entry->the_bfd, needed_name);
+      filename = xstrdup (basename (entry->filename));
+      bfd_elf_set_dt_needed_name (entry->the_bfd, filename);
     }
 
   return true;
@@ -997,6 +1006,35 @@ EOF
 if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then
 cat >>e${EMULATION_NAME}.c <<EOF
 
+/* Find the last output section before given output statement.
+   Used by place_orphan.  */
+
+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)
+       break;
+      if (lookup->bfd_section != NULL)
+       s = lookup->bfd_section;
+    }
+
+  if (u == NULL)
+    return NULL;
+
+  return s;
+}
+
+
 /* Place an orphan section.  We use this to put random SHF_ALLOC
    sections in the right segment.  */
 
@@ -1183,12 +1221,16 @@ gld${EMULATION_NAME}_place_orphan (file, s)
 
   if (place != NULL)
     {
-      asection *snew, **pps;
+      asection *snew, **pps, *bfd_section;
 
       snew = os->bfd_section;
+      bfd_section = place->os->bfd_section;
+      if (place->section == NULL && bfd_section == NULL)
+       bfd_section = output_prev_sec_find (place->os);
+
       if (place->section != NULL
-         || (place->os->bfd_section != NULL
-             && place->os->bfd_section != snew))
+         || (bfd_section != NULL
+             && bfd_section != snew))
        {
          /* Shuffle the section to make the output file look neater.
             This is really only cosmetic.  */
@@ -1197,15 +1239,15 @@ gld${EMULATION_NAME}_place_orphan (file, s)
 #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;
+             flagword first_flags = bfd_section->flags;
+             for (pps = &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;
+             place->section = &bfd_section->next;
 #endif
            }
 
@@ -1334,6 +1376,7 @@ cat >>e${EMULATION_NAME}.c <<EOF
 
 #define OPTION_DISABLE_NEW_DTAGS       (400)
 #define OPTION_ENABLE_NEW_DTAGS                (OPTION_DISABLE_NEW_DTAGS + 1)
+#define OPTION_GROUP                   (OPTION_ENABLE_NEW_DTAGS + 1)
 
 static struct option longopts[] =
 {
@@ -1347,6 +1390,8 @@ cat >>e${EMULATION_NAME}.c <<EOF
   {"disable-new-dtags", no_argument, NULL, OPTION_DISABLE_NEW_DTAGS},
   {"enable-new-dtags", no_argument, NULL, OPTION_ENABLE_NEW_DTAGS},
   {"enable-new-dtags", no_argument, NULL, OPTION_ENABLE_NEW_DTAGS},
+  {"Bgroup", no_argument, NULL, OPTION_GROUP},
+  {"Bgroup", no_argument, NULL, OPTION_GROUP},
 EOF
 fi
 
@@ -1405,6 +1450,12 @@ cat >>e${EMULATION_NAME}.c <<EOF
       link_info.new_dtags = true;
       break;
 
+    case OPTION_GROUP:
+      link_info.flags_1 |= (bfd_vma) DF_1_GROUP;
+      /* Groups must be self-contained.  */
+      link_info.no_undefined = true;
+      break;
+
     case 'z':
       if (strcmp (optarg, "initfirst") == 0)
        link_info.flags_1 |= (bfd_vma) DF_1_INITFIRST;
@@ -1430,6 +1481,8 @@ cat >>e${EMULATION_NAME}.c <<EOF
          link_info.flags |= (bfd_vma) DF_ORIGIN;
          link_info.flags_1 |= (bfd_vma) DF_1_ORIGIN;
        }
+      else if (strcmp (optarg, "defs") == 0)
+       link_info.no_undefined = true;
       /* What about the other Solaris -z options? FIXME.  */
       break;
 EOF
@@ -1463,8 +1516,10 @@ EOF
 
 if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
 cat >>e${EMULATION_NAME}.c <<EOF
+  fprintf (file, _("  -Bgroup\t\tSelects group name lookup rules for DSO\n"));
   fprintf (file, _("  --disable-new-dtags\tDisable new dynamic tags\n"));
   fprintf (file, _("  --enable-new-dtags\tEnable new dynamic tags\n"));
+  fprintf (file, _("  -z defs\t\tDisallows undefined symbols\n"));
   fprintf (file, _("  -z initfirst\t\tMark DSO to be initialized first at runtime\n"));
   fprintf (file, _("  -z interpose\t\tMark object to interpose all DSOs but executable\n"));
   fprintf (file, _("  -z loadfltr\t\tMark object requiring immediate process\n"));