]> Git Repo - binutils.git/blobdiff - ld/emultempl/elf32.em
* emultempl/elf32.em (output_rel_find): Prefer .rel script sections
[binutils.git] / ld / emultempl / elf32.em
index c62727d7e0cb1de6ab1de841a646c13ad6a7a4ee..62c39f442afb70b9396996b44ce75eaca927c42a 100644 (file)
@@ -75,7 +75,7 @@ static void gld${EMULATION_NAME}_before_allocation
 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));
+  PARAMS ((asection *));
 static asection *output_prev_sec_find
   PARAMS ((lang_output_section_statement_type *));
 static boolean gld${EMULATION_NAME}_place_orphan
@@ -165,7 +165,7 @@ gld${EMULATION_NAME}_vercheck (s)
 
   soname = bfd_elf_get_dt_soname (s->the_bfd);
   if (soname == NULL)
-    soname = basename (bfd_get_filename (s->the_bfd));
+    soname = lbasename (bfd_get_filename (s->the_bfd));
 
   for (l = global_vercheck_needed; l != NULL; l = l->next)
     {
@@ -247,7 +247,7 @@ gld${EMULATION_NAME}_stat_needed (s)
 
   soname = bfd_elf_get_dt_soname (s->the_bfd);
   if (soname == NULL)
-    soname = basename (s->filename);
+    soname = lbasename (s->filename);
 
   if (strncmp (soname, global_needed->name, suffix - global_needed->name) == 0)
     einfo ("%P: warning: %s, needed by %B, may conflict with %s\n",
@@ -281,6 +281,13 @@ gld${EMULATION_NAME}_try_needed (name, force)
       return false;
     }
 
+  /* For DT_NEEDED, they have to match.  */
+  if (abfd->xvec != output_bfd->xvec)
+    {
+      bfd_close (abfd);
+      return false;
+    }
+
   /* Check whether this object would include any conflicting library
      versions.  If FORCE is set, then we skip this check; we use this
      the second time around, if we couldn't find any compatible
@@ -351,7 +358,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 = basename (abfd->filename);
+  soname = lbasename (abfd->filename);
 
   if (trace_file_tries)
     info_msg (_("found %s at %s\n"), soname, name);
@@ -369,9 +376,6 @@ 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.  */
@@ -976,7 +980,7 @@ gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry)
       /* Rather than duplicating the logic above.  Just use the
         filename we recorded earlier.  */
 
-      filename = xstrdup (basename (entry->filename));
+      filename = lbasename (entry->filename);
       bfd_elf_set_dt_needed_name (entry->the_bfd, filename);
     }
 
@@ -992,24 +996,46 @@ cat >>e${EMULATION_NAME}.c <<EOF
 /* A variant of lang_output_section_find.  Used by place_orphan.  */
 
 static lang_output_section_statement_type *
-output_rel_find ()
+output_rel_find (sec)
+     asection *sec;
 {
   lang_statement_union_type *u;
   lang_output_section_statement_type *lookup;
+  lang_output_section_statement_type *last = NULL;
+  lang_output_section_statement_type *last_rel = NULL;
+  lang_output_section_statement_type *last_rel_alloc = NULL;
+  int rela = sec->name[4] == 'a';
 
-  for (u = lang_output_section_statement.head;
-       u != (lang_statement_union_type *) NULL;
-       u = lookup->next)
+  for (u = lang_output_section_statement.head; u; u = lookup->next)
     {
       lookup = &u->output_section_statement;
-      if (strncmp (".rel", lookup->name, 4) == 0
-         && lookup->bfd_section != NULL
-         && (lookup->bfd_section->flags & SEC_ALLOC) != 0)
+      if (strncmp (".rel", lookup->name, 4) == 0)
        {
-         return lookup;
+         /* 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))
+           break;
+         last = lookup;
+         if (rela == lookrela)
+           last_rel = lookup;
+         if (lookup->bfd_section != NULL
+             && (lookup->bfd_section->flags & SEC_ALLOC) != 0)
+           last_rel_alloc = lookup;
        }
     }
-  return (lang_output_section_statement_type *) NULL;
+
+  if (last_rel_alloc)
+    return last_rel_alloc;
+
+  if (last_rel)
+    return last_rel;
+
+  return last;
 }
 
 /* Find the last output section before given output statement.
@@ -1065,13 +1091,23 @@ gld${EMULATION_NAME}_place_orphan (file, s)
   lang_statement_list_type add;
   etree_type *address;
   const char *secname;
-  const char *outsecname;
   const char *ps = NULL;
   lang_output_section_statement_type *os;
+  int isdyn = 0;
 
   secname = bfd_get_section_name (s->owner, s);
+  if (! link_info.relocateable
+      && link_info.combreloc
+      && strncmp (secname, ".rel", 4) == 0)
+    {
+      if (secname[4] == 'a')
+       secname = ".rela.dyn";
+      else
+       secname = ".rel.dyn";
+      isdyn = 1;
+    }
 
-  if (! config.unique_orphan_sections && ! unique_section_p (secname))
+  if (isdyn || (!config.unique_orphan_sections && !unique_section_p (secname)))
     {
       /* Look through the script to see where to place this section.  */
       os = lang_output_section_find (secname);
@@ -1110,7 +1146,7 @@ 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)
+  if ((s->flags & SEC_EXCLUDE) != 0 && !link_info.relocateable)
     {
       if (s->output_section == NULL)
        s->output_section = bfd_abs_section_ptr;
@@ -1134,27 +1170,10 @@ gld${EMULATION_NAME}_place_orphan (file, s)
           && HAVE_SECTION (hold_data, ".data"))
     place = &hold_data;
   else if (strncmp (secname, ".rel", 4) == 0
+          && (s->flags & SEC_LOAD) != 0
           && (hold_rel.os != NULL
-              || (hold_rel.os = output_rel_find ()) != NULL))
-    {
-      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;
-    }
+              || (hold_rel.os = output_rel_find (s)) != NULL))
+    place = &hold_rel;
   else if ((s->flags & (SEC_CODE | SEC_READONLY)) == SEC_READONLY
           && HAVE_SECTION (hold_rodata, ".rodata"))
     place = &hold_rodata;
@@ -1167,13 +1186,10 @@ gld${EMULATION_NAME}_place_orphan (file, s)
   /* Choose a unique name for the section.  This will be needed if the
      same section name appears in the input file with different
      loadable or allocatable characteristics.  */
-  outsecname = secname;
-  if (bfd_get_section_by_name (output_bfd, outsecname) != NULL)
+  if (bfd_get_section_by_name (output_bfd, secname) != NULL)
     {
-      outsecname = bfd_get_unique_section_name (output_bfd,
-                                               outsecname,
-                                               &count);
-      if (outsecname == NULL)
+      secname = bfd_get_unique_section_name (output_bfd, secname, &count);
+      if (secname == NULL)
        einfo ("%F%P: place_orphan failed: %E\n");
     }
 
@@ -1194,7 +1210,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++)
+      for (ps = secname; *ps != '\0'; ps++)
        if (! ISALNUM (*ps) && *ps != '_')
          break;
       if (*ps == '\0')
@@ -1202,8 +1218,8 @@ gld${EMULATION_NAME}_place_orphan (file, s)
          char *symname;
          etree_type *e_align;
 
-         symname = (char *) xmalloc (ps - outsecname + sizeof "__start_");
-         sprintf (symname, "__start_%s", outsecname);
+         symname = (char *) xmalloc (ps - secname + sizeof "__start_");
+         sprintf (symname, "__start_%s", secname);
          e_align = exp_unop (ALIGN_K,
                              exp_intop ((bfd_vma) 1 << s->alignment_power));
          lang_add_assignment (exp_assop ('=', symname, e_align));
@@ -1215,7 +1231,7 @@ gld${EMULATION_NAME}_place_orphan (file, s)
   else
     address = NULL;
 
-  os = lang_enter_output_section_statement (outsecname, address, 0,
+  os = lang_enter_output_section_statement (secname, address, 0,
                                            (bfd_vma) 0,
                                            (etree_type *) NULL,
                                            (etree_type *) NULL,
@@ -1225,7 +1241,7 @@ gld${EMULATION_NAME}_place_orphan (file, s)
 
   lang_leave_output_section_statement
     ((bfd_vma) 0, "*default*",
-     (struct lang_output_section_phdr_list *) NULL, "*default*");
+     (struct lang_output_section_phdr_list *) NULL, NULL);
 
   if (config.build_constructors && *ps == '\0')
     {
@@ -1236,8 +1252,8 @@ gld${EMULATION_NAME}_place_orphan (file, s)
       if (place != NULL)
        stat_ptr = &add;
 
-      symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_");
-      sprintf (symname, "__stop_%s", outsecname);
+      symname = (char *) xmalloc (ps - secname + sizeof "__stop_");
+      sprintf (symname, "__stop_%s", secname);
       lang_add_assignment (exp_assop ('=', symname,
                                      exp_nameop (NAME, ".")));
     }
@@ -1245,7 +1261,7 @@ gld${EMULATION_NAME}_place_orphan (file, s)
   /* Restore the global list pointer.  */
   stat_ptr = old;
 
-  if (place != NULL)
+  if (place != NULL && os->bfd_section != NULL)
     {
       asection *snew, **pps;
 
@@ -1341,7 +1357,7 @@ gld${EMULATION_NAME}_finish ()
 
       /* Do the assignments again.  */
       lang_do_assignments (stat_ptr->head, abs_output_section,
-                          (fill_type) 0, (bfd_vma) 0);
+                          (fill_type *) 0, (bfd_vma) 0);
     }
 }
 EOF
@@ -1379,13 +1395,17 @@ echo '  ; else if (!config.magic_demand_paged) return'     >> e${EMULATION_NAME}
 sed $sc ldscripts/${EMULATION_NAME}.xn                     >> 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) return' >> 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
 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
+fi
 echo '  ; else return'                                     >> e${EMULATION_NAME}.c
 sed $sc ldscripts/${EMULATION_NAME}.x                      >> e${EMULATION_NAME}.c
 echo '; }'                                                 >> e${EMULATION_NAME}.c
@@ -1544,6 +1564,8 @@ cat >>e${EMULATION_NAME}.c <<EOF
        }
       else if (strcmp (optarg, "defs") == 0)
        link_info.no_undefined = true;
+      else if (strcmp (optarg, "muldefs") == 0)
+       link_info.allow_multiple_definition = true;
       else if (strcmp (optarg, "combreloc") == 0)
        link_info.combreloc = true;
       else if (strcmp (optarg, "nocombreloc") == 0)
@@ -1592,6 +1614,7 @@ cat >>e${EMULATION_NAME}.c <<EOF
   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"));
+  fprintf (file, _("  -z muldefs\t\tAllow multiple definitions\n"));
   fprintf (file, _("  -z nocombreloc\tDon't merge dynamic relocs into one section\n"));
   fprintf (file, _("  -z nocopyreloc\tDon't create copy relocs\n"));
   fprintf (file, _("  -z nodefaultlib\tMark object not to use default search paths\n"));
@@ -1659,5 +1682,6 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
   ${LDEMUL_LIST_OPTIONS-gld${EMULATION_NAME}_list_options},
   ${LDEMUL_RECOGNIZED_FILE-NULL},
   ${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL},
+  ${LDEMUL_NEW_VERS_PATTERN-NULL}
 };
 EOF
This page took 0.035723 seconds and 4 git commands to generate.