PR ld/22909 amendment; don't xfail ld-elf/pr19539.d for cris*-*-*.
[deliverable/binutils-gdb.git] / ld / ldelf.c
index 3b0f3ada8c2b9518d6689f5c103c5aff85374bee..efb4b77382e483cb19d1d6a03074698a32615cd4 100644 (file)
@@ -1,5 +1,5 @@
 /* ELF emulation code for targets using elf.em.
-   Copyright (C) 1991-2019 Free Software Foundation, Inc.
+   Copyright (C) 1991-2020 Free Software Foundation, Inc.
 
    This file is part of the GNU Binutils.
 
@@ -23,6 +23,8 @@
 #include "libiberty.h"
 #include "filenames.h"
 #include "safe-ctype.h"
+#include "bfdlink.h"
+#include "ctf-api.h"
 #include "ld.h"
 #include "ldmain.h"
 #include "ldmisc.h"
@@ -373,6 +375,9 @@ ldelf_try_needed (struct dt_needed *needed, int force, int is_linux)
 
   bfd_elf_set_dyn_lib_class (abfd, (enum dynamic_lib_link_class) link_class);
 
+  *link_info.input_bfds_tail = abfd;
+  link_info.input_bfds_tail = &abfd->link.next;
+
   /* Add this file into the symbol table.  */
   if (! bfd_link_add_symbols (abfd, &link_info))
     einfo (_("%F%P: %pB: error adding symbols: %E\n"), abfd);
@@ -778,8 +783,7 @@ ldelf_parse_ld_so_conf_include (struct ldelf_ld_so_conf *info,
   ldelf_parse_ld_so_conf (info, pattern);
 #endif
 
-  if (newp)
-    free (newp);
+  free (newp);
 }
 
 static bfd_boolean
@@ -892,7 +896,7 @@ ldelf_parse_ld_so_conf (struct ldelf_ld_so_conf *info, const char *filename)
 
 static bfd_boolean
 ldelf_check_ld_so_conf (const struct bfd_link_needed_list *l, int force,
-                       int elfsize)
+                       int elfsize, const char *prefix)
 {
   static bfd_boolean initialized;
   static const char *ld_so_conf;
@@ -905,7 +909,7 @@ ldelf_check_ld_so_conf (const struct bfd_link_needed_list *l, int force,
 
       info.path = NULL;
       info.len = info.alloc = 0;
-      tmppath = concat (ld_sysroot, "${prefix}/etc/ld.so.conf",
+      tmppath = concat (ld_sysroot, prefix, "/etc/ld.so.conf",
                        (const char *) NULL);
       if (!ldelf_parse_ld_so_conf (&info, tmppath))
        {
@@ -984,12 +988,13 @@ ldelf_check_needed (lang_input_statement_type *s)
 
 void
 ldelf_after_open (int use_libpath, int native, int is_linux, int is_freebsd,
-                 int elfsize)
+                 int elfsize, const char *prefix)
 {
   struct bfd_link_needed_list *needed, *l;
   struct elf_link_hash_table *htab;
   asection *s;
   bfd *abfd;
+  bfd **save_input_bfd_tail;
 
   after_open_default ();
 
@@ -1018,7 +1023,7 @@ ldelf_after_open (int use_libpath, int native, int is_linux, int is_freebsd,
           abfd != (bfd *) NULL; abfd = abfd->link.next)
        if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
            && bfd_count_sections (abfd) != 0
-           && !((lang_input_statement_type *) abfd->usrdata)->flags.just_syms)
+           && !bfd_input_just_syms (abfd))
          break;
 
       /* PR 10555: If there are no ELF input files do not try to
@@ -1060,12 +1065,12 @@ ldelf_after_open (int use_libpath, int native, int is_linux, int is_freebsd,
        {
          int type = 0;
 
-         if (((lang_input_statement_type *) abfd->usrdata)->flags.just_syms)
+         if (bfd_input_just_syms (abfd))
            continue;
 
          for (s = abfd->sections; s && type < COMPACT_EH_HDR; s = s->next)
            {
-             const char *name = bfd_get_section_name (abfd, s);
+             const char *name = bfd_section_name (s);
 
              if (bfd_is_abs_section (s->output_section))
                continue;
@@ -1112,7 +1117,7 @@ ldelf_after_open (int use_libpath, int native, int is_linux, int is_freebsd,
                                           bed->dynamic_sec_flags
                                           | SEC_READONLY);
          if (s != NULL
-             && bfd_set_section_alignment (elfbfd, s, 2))
+             && bfd_set_section_alignment (s, 2))
            {
              htab->eh_info.hdr_sec = s;
              warn_eh_frame = FALSE;
@@ -1132,6 +1137,7 @@ ldelf_after_open (int use_libpath, int native, int is_linux, int is_freebsd,
      special action by the person doing the link.  Note that the
      needed list can actually grow while we are stepping through this
      loop.  */
+  save_input_bfd_tail = link_info.input_bfds_tail;
   needed = bfd_elf_get_needed_list (link_info.output_bfd, &link_info);
   for (l = needed; l != NULL; l = l->next)
     {
@@ -1258,7 +1264,7 @@ ldelf_after_open (int use_libpath, int native, int is_linux, int is_freebsd,
                break;
 
              if (is_linux
-                 && ldelf_check_ld_so_conf (l, force, elfsize))
+                 && ldelf_check_ld_so_conf (l, force, elfsize, prefix))
                break;
            }
 
@@ -1288,6 +1294,20 @@ ldelf_after_open (int use_libpath, int native, int is_linux, int is_freebsd,
             l->name, l->by);
     }
 
+  for (abfd = link_info.input_bfds; abfd; abfd = abfd->link.next)
+    if (bfd_get_format (abfd) == bfd_object
+       && ((abfd->flags) & DYNAMIC) != 0
+       && bfd_get_flavour (abfd) == bfd_target_elf_flavour
+       && (elf_dyn_lib_class (abfd) & (DYN_AS_NEEDED | DYN_NO_NEEDED)) == 0
+       && elf_dt_name (abfd) != NULL)
+      {
+       if (bfd_elf_add_dt_needed_tag (abfd, &link_info) < 0)
+         einfo (_("%F%P: failed to add DT_NEEDED dynamic tag\n"));
+      }
+
+  link_info.input_bfds_tail = save_input_bfd_tail;
+  *save_input_bfd_tail = NULL;
+
   if (link_info.eh_frame_hdr_type == COMPACT_EH_HDR)
     if (!bfd_elf_parse_eh_frame_entries (NULL, &link_info))
       einfo (_("%F%P: failed to parse EH frame entries\n"));
@@ -1382,7 +1402,7 @@ ldelf_setup_build_id (bfd *ibfd)
   flags = (SEC_ALLOC | SEC_LOAD | SEC_IN_MEMORY
           | SEC_LINKER_CREATED | SEC_READONLY | SEC_DATA);
   s = bfd_make_section_with_flags (ibfd, ".note.gnu.build-id", flags);
-  if (s != NULL && bfd_set_section_alignment (ibfd, s, 2))
+  if (s != NULL && bfd_set_section_alignment (s, 2))
     {
       struct elf_obj_tdata *t = elf_tdata (link_info.output_bfd);
       t->o->build_id.after_write_object_contents = &write_build_id;
@@ -1778,7 +1798,7 @@ output_rel_find (int isdyn, int rela)
   lang_output_section_statement_type *last_rel = NULL;
   lang_output_section_statement_type *last_rel_alloc = NULL;
 
-  for (lookup = &lang_os_list.head->output_section_statement;
+  for (lookup = (void *) lang_os_list.head;
        lookup != NULL;
        lookup = lookup->next)
     {
@@ -1844,13 +1864,13 @@ elf_orphan_compatible (asection *in, asection *out)
   if (elf_section_data (out)->this_hdr.sh_info
       != elf_section_data (in)->this_hdr.sh_info)
     return FALSE;
-  /* We can't merge with member of output section group nor merge two
-     sections with differing SHF_EXCLUDE when doing a relocatable link.
-   */
+  /* We can't merge with a member of an output section group or merge
+     two sections with differing SHF_EXCLUDE or other processor and OS
+     specific flags when doing a relocatable link.  */
   if (bfd_link_relocatable (&link_info)
       && (elf_next_in_group (out) != NULL
          || ((elf_section_flags (out) ^ elf_section_flags (in))
-             & SHF_EXCLUDE) != 0))
+             & (SHF_MASKPROC | SHF_MASKOS)) != 0))
     return FALSE;
   return _bfd_elf_match_sections_by_type (link_info.output_bfd, out,
                                          in->owner, in);
@@ -1950,7 +1970,7 @@ ldelf_place_orphan (asection *s, const char *secname, int constraint)
     {
       /* Find the output mbind section with the same type, attributes
         and sh_info field.  */
-      for (os = &lang_os_list.head->output_section_statement;
+      for (os = (void *) lang_os_list.head;
           os != NULL;
           os = os->next)
        if (os->bfd_section != NULL
@@ -2065,9 +2085,7 @@ ldelf_place_orphan (asection *s, const char *secname, int constraint)
            && (nexts->flags & SEC_EXCLUDE) == 0
            && ((nexts->flags ^ flags) & (SEC_LOAD | SEC_ALLOC)) == 0
            && (nexts->owner->flags & DYNAMIC) == 0
-           && nexts->owner->usrdata != NULL
-           && !(((lang_input_statement_type *) nexts->owner->usrdata)
-                ->flags.just_syms)
+           && !bfd_input_just_syms (nexts->owner)
            && _bfd_elf_match_sections_by_type (nexts->owner, nexts,
                                                s->owner, s))
          flags = (((flags ^ SEC_READONLY)
@@ -2129,8 +2147,37 @@ ldelf_place_orphan (asection *s, const char *secname, int constraint)
                                               _bfd_elf_match_sections_by_type);
       if (after == NULL)
        /* *ABS* is always the first output section statement.  */
-       after = &lang_os_list.head->output_section_statement;
+       after = (void *) lang_os_list.head;
     }
 
   return lang_insert_orphan (s, secname, constraint, after, place, NULL, NULL);
 }
+
+void
+ldelf_before_place_orphans (void)
+{
+  bfd *abfd;
+
+  for (abfd = link_info.input_bfds;
+       abfd != (bfd *) NULL; abfd = abfd->link.next)
+    if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
+       && bfd_count_sections (abfd) != 0
+       && !bfd_input_just_syms (abfd))
+      {
+       asection *isec;
+       for (isec = abfd->sections; isec != NULL; isec = isec->next)
+         {
+           /* Discard a section if any of its linked-to section has
+              been discarded.  */
+           asection *linked_to_sec;
+           for (linked_to_sec = elf_linked_to_section (isec);
+                linked_to_sec != NULL;
+                linked_to_sec = elf_linked_to_section (linked_to_sec))
+             if (discarded_section (linked_to_sec))
+               {
+                 isec->output_section = bfd_abs_section_ptr;
+                 break;
+               }
+         }
+      }
+}
This page took 0.036606 seconds and 4 git commands to generate.