bfd/
[deliverable/binutils-gdb.git] / ld / emultempl / elf32.em
index ca5eafdff93d2675d5c5a81d59628d1920b84cf7..e43c8c5a8305bda13b3958c486ece65e1a46204c 100644 (file)
@@ -31,10 +31,11 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
 
 #define TARGET_IS_${EMULATION_NAME}
 
+#include "config.h"
 #include "bfd.h"
 #include "sysdep.h"
 #include "libiberty.h"
@@ -56,16 +57,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 /* 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}_provide_init_fini_syms (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);
+static void gld${EMULATION_NAME}_layout_sections_again (void);
+static void gld${EMULATION_NAME}_finish (void) ATTRIBUTE_UNUSED;
 
 EOF
 
 if [ "x${USE_LIBPATH}" = xyes ] ; then
   case ${target} in
-    *-*-linux-*)
+    *-*-linux-* | *-*-k*bsd*-*)
   cat >>e${EMULATION_NAME}.c <<EOF
 #ifdef HAVE_GLOB
 #include <glob.h>
@@ -226,6 +229,9 @@ gld${EMULATION_NAME}_stat_needed (lang_input_statement_type *s)
     return;
   if (s->the_bfd == NULL)
     return;
+  if (s->as_needed
+      && (bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0)
+    return;
 
   if (bfd_stat (s->the_bfd, &st) != 0)
     {
@@ -347,7 +353,7 @@ gld${EMULATION_NAME}_try_needed (struct dt_needed *needed,
 
 EOF
 case ${target} in
-  *-*-linux-*)
+  *-*-linux-* | *-*-k*bsd*-*)
     cat >>e${EMULATION_NAME}.c <<EOF
          {
            struct bfd_link_needed_list *l;
@@ -519,7 +525,7 @@ gld${EMULATION_NAME}_add_sysroot (const char *path)
 
 EOF
   case ${target} in
-    *-*-linux-*)
+    *-*-linux-* | *-*-k*bsd*-*)
       cat >>e${EMULATION_NAME}.c <<EOF
 /* For a native linker, check the file /etc/ld.so.conf for directories
    in which we may find shared libraries.  /etc/ld.so.conf is really
@@ -733,6 +739,13 @@ gld${EMULATION_NAME}_check_needed (lang_input_statement_type *s)
   if (global_found)
     return;
 
+  /* If this input file was an as-needed entry, and wasn't found to be
+     needed at the stage it was linked, then don't say we have loaded it.  */
+  if (s->as_needed
+      && (s->the_bfd == NULL
+         || (bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0))
+    return;
+
   if (s->filename != NULL)
     {
       const char *f;
@@ -922,7 +935,7 @@ cat >>e${EMULATION_NAME}.c <<EOF
 EOF
 if [ "x${USE_LIBPATH}" = xyes ] ; then
   case ${target} in
-    *-*-linux-*)
+    *-*-linux-* | *-*-k*bsd*-*)
       cat >>e${EMULATION_NAME}.c <<EOF
          if (gld${EMULATION_NAME}_check_ld_so_conf (l->name, force))
            break;
@@ -969,8 +982,8 @@ gld${EMULATION_NAME}_find_exp_assignment (etree_type *exp)
         will do no harm.  */
       if (strcmp (exp->assign.dst, ".") != 0)
        {
-         if (!bfd_elf_record_link_assignment (output_bfd, &link_info,
-                                              exp->assign.dst, provide))
+         if (!bfd_elf_record_link_assignment (&link_info, exp->assign.dst,
+                                              provide))
            einfo ("%P%F: failed to record assignment to %s: %E\n",
                   exp->assign.dst);
        }
@@ -1027,6 +1040,47 @@ if test x"$LDEMUL_BEFORE_ALLOCATION" != xgld"$EMULATION_NAME"_before_allocation;
   fi
 cat >>e${EMULATION_NAME}.c <<EOF
 
+static void
+gld${EMULATION_NAME}_provide_bound_symbols (const char *sec,
+                                           const char *start,
+                                           const char *end)
+{
+  asection *s = bfd_get_section_by_name (output_bfd, sec);
+  _bfd_elf_provide_section_bound_symbols (&link_info, s, start, end);
+}
+
+/* If not building a shared library, provide
+
+   __preinit_array_start
+   __preinit_array_end
+   __init_array_start
+   __init_array_end
+   __fini_array_start
+   __fini_array_end
+
+   They are set here rather than via PROVIDE in the linker
+   script, because using PROVIDE inside an output section
+   statement results in unnecessary output sections.  Using
+   PROVIDE outside an output section statement runs the risk of
+   section alignment affecting where the section starts.  */
+
+static void
+gld${EMULATION_NAME}_provide_init_fini_syms (void)
+{
+  if (!link_info.relocatable && link_info.executable)
+    {
+      gld${EMULATION_NAME}_provide_bound_symbols (".preinit_array",
+                                                 "__preinit_array_start",
+                                                 "__preinit_array_end");
+      gld${EMULATION_NAME}_provide_bound_symbols (".init_array",
+                                                 "__init_array_start",
+                                                 "__init_array_end");
+      gld${EMULATION_NAME}_provide_bound_symbols (".fini_array",
+                                                 "__fini_array_start",
+                                                 "__fini_array_end");
+    }
+}
+
 /* This is called after the sections have been attached to output
    sections, but before any sizes or addresses have been set.  */
 
@@ -1044,6 +1098,8 @@ gld${EMULATION_NAME}_before_allocation (void)
      referred to by dynamic objects.  */
   lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment);
 
+  ldemul_do_assignments ();
+
   /* Let the ELF backend work out the sizes of any sections required
      by dynamic linking.  */
   rpath = command_line.rpath;
@@ -1055,6 +1111,7 @@ gld${EMULATION_NAME}_before_allocation (void)
          (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
@@ -1111,6 +1168,11 @@ ${ELF_INTERPRETER_SET_DEFAULT}
        s->flags |= SEC_EXCLUDE;
       }
   }
+
+  before_allocation_default ();
+
+  if (!bfd_elf_size_dynsym_hash_dynstr (output_bfd, &link_info))
+    einfo ("%P%F: failed to set dynamic section sizes: %E\n");
 }
 
 EOF
@@ -1428,102 +1490,27 @@ if test x"$LDEMUL_FINISH" != xgld"$EMULATION_NAME"_finish; then
 cat >>e${EMULATION_NAME}.c <<EOF
 
 static void
-gld${EMULATION_NAME}_provide_bound_symbols (const char *sec,
-                                           const char *start,
-                                           const char *end)
+gld${EMULATION_NAME}_layout_sections_again (void)
 {
-  asection *s;
-  bfd_vma start_val, end_val;
+  lang_reset_memory_regions ();
 
-  s = bfd_get_section_by_name (output_bfd, sec);
-  if (s != NULL)
-    {
-      start_val = s->vma;
-      end_val = start_val + s->size;
-    }
-  else
-    {
-      start_val = 0;
-      end_val = 0;
-    }
-  _bfd_elf_provide_symbol (&link_info, start, start_val);
-  _bfd_elf_provide_symbol (&link_info, end, end_val);
+  /* Resize the sections.  */
+  lang_size_sections (NULL, TRUE);
+
+  /* Redo special stuff.  */
+  ldemul_after_allocation ();
+
+  /* Do the assignments again.  */
+  lang_do_assignments ();
 }
 
 static void
 gld${EMULATION_NAME}_finish (void)
 {
   if (bfd_elf_discard_info (output_bfd, &link_info))
-    {
-      lang_reset_memory_regions ();
-
-      /* Resize the sections.  */
-      lang_size_sections (stat_ptr->head, abs_output_section,
-                         &stat_ptr->head, 0, (bfd_vma) 0, NULL, TRUE);
-
-      /* Redo special stuff.  */
-      ldemul_after_allocation ();
-
-      /* Do the assignments again.  */
-      lang_do_assignments (stat_ptr->head, abs_output_section,
-                          (fill_type *) 0, (bfd_vma) 0);
-    }
-
-  if (!link_info.relocatable)
-    {
-      lang_output_section_statement_type *os;
-
-      for (os = &lang_output_section_statement.head->output_section_statement;
-          os != NULL;
-          os = os->next)
-       {
-         asection *s;
-
-         if (os == abs_output_section || os->constraint == -1)
-           continue;
-         s = os->bfd_section;
-         if (s != NULL && s->size == 0 && (s->flags & SEC_KEEP) == 0)
-           {
-             asection **p;
-
-             for (p = &output_bfd->sections; *p; p = &(*p)->next)
-               if (*p == s)
-                 {
-                   bfd_section_list_remove (output_bfd, p);
-                   output_bfd->section_count--;
-                   break;
-                 }
-           }
-       }
+    gld${EMULATION_NAME}_layout_sections_again ();
 
-      /* If not building shared library, provide
-
-        __preinit_array_start
-        __preinit_array_end
-        __init_array_start
-        __init_array_end
-        __fini_array_start
-        __fini_array_end
-
-        They are set here rather than via PROVIDE in the linker
-        script, because using PROVIDE inside an output section
-        statement results in unnecessary output sections.  Using
-        PROVIDE outside an output section statement runs the risk of
-        section alignment affecting where the section starts.  */
-
-      if (!link_info.shared)
-       {
-         gld${EMULATION_NAME}_provide_bound_symbols
-           (".preinit_array", "__preinit_array_start",
-            "__preinit_array_end");
-         gld${EMULATION_NAME}_provide_bound_symbols
-           (".init_array", "__init_array_start",
-            "__init_array_end");
-         gld${EMULATION_NAME}_provide_bound_symbols
-           (".fini_array", "__fini_array_start",
-            "__fini_array_end");
-       }
-    }
+  finish_default ();
 }
 EOF
 fi
@@ -1894,6 +1881,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
   ${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default},
   ${LDEMUL_CHOOSE_TARGET-ldemul_default_target},
   ${LDEMUL_BEFORE_ALLOCATION-gld${EMULATION_NAME}_before_allocation},
+  ${LDEMUL_DO_ASSIGNMENTS-gld${EMULATION_NAME}_provide_init_fini_syms},
   ${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script},
   "${EMULATION_NAME}",
   "${OUTPUT_FORMAT}",
This page took 0.026909 seconds and 4 git commands to generate.