This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Set dynobj to a normal input file if possible


On Fri, Apr 22, 2016 at 1:55 AM, Alan Modra <amodra@gmail.com> wrote:
> On Thu, Apr 21, 2016 at 09:49:50PM -0700, H.J. Lu wrote:
>> On Thu, Apr 21, 2016 at 8:39 PM, Hans-Peter Nilsson
>> <hans-peter.nilsson@axis.com> wrote:
>> >> Date: Wed, 20 Apr 2016 20:31:50 -0700
>> >> From: "H.J. Lu" <hongjiu.lu@intel.com>
>> >
>> >>       * elflink.c (_bfd_elf_link_create_dynstrtab): Set dynobj to a
>> >>       normal input file if possible.
>> >
>> > Looks like this caused, for a cross -m32 build to arm-unknown-eabi:
>> >
>> > Running /tmp/hpautotest-binutils/bsrc/src/ld/testsuite/ld-arm/arm-elf.exp ...
>> > FAIL: Indirect cross-library function reference
>> > FAIL: TLS dynamic application
>> > FAIL: GOT relocations in executables
>> > FAIL: Thumb and -gc-sections
>> > FAIL: Simple dynamic application
>> > FAIL: Simple dynamic application without .rel.plt in linker script
>> > FAIL: Non-pcrel function reference
>> > FAIL: Mixed ARM/Thumb dynamic application
>> > FAIL: Mixed ARM/Thumb arch5 dynamic application
>> > FAIL: Using Thumb lib by another lib
>> > FAIL: MOVW/MOVT against shared libraries
>> > FAIL: Mixed ARM/Thumb dynamic application with farcalls
>> > FAIL: Mixed ARM/Thumb arch5 dynamic application with farcalls
>> > FAIL: TLS long plt
>> > FAIL: IFUNC test 7
>> > FAIL: IFUNC test 8
>> > FAIL: IFUNC test 9
>> > FAIL: IFUNC test 10
>> > FAIL: IFUNC test 13
>> > FAIL: IFUNC test 14
>> > FAIL: IFUNC test 15
>> > FAIL: IFUNC test 16
>> > FAIL: Preempt Thumb symbol
>> > FAIL: ld-arm/unresolved-1-dyn
>
> Sounds like something should be fixed in the arm backend.  Powerpc64
> deliberately sets dynobj to the linker created "stub bfd", so there
> isn't some underlying generic problem with attaching the linker
> sections to a linker created bfd.  In fact, it's a good idea.
>
> Hmm.
> ld-new: linker stubs: file class ELFCLASSNONE incompatible with ELFCLASS32
> ld-new: final link failed: File in wrong format
>
> Yes, looks like there needs to be a small tweak.  See bfd/elf64-ppc.c
> ppc64_elf_init_stub_bfd

They need something like

elf_elfheader (fake_bfd)->e_ident[EI_CLASS]
   = (get_elf_backend_data (link_info.output_bfd)->s->arch_size == 64
       ? ELFCLASS64 : ELFCLASS32);

Currently, we hold linker created dynamic sections in an input shared
object, which has its own dynamic sections, when the first input file
from linker is a shared object.  It may lead to conflicts between
linker created dynamic sections and shared object's dynamic sections.
We can use a a fake bfd to hold linker created dynamic sections.
Unfortunately, it doesn't work due to BFD_LINKER_CREATED.  Dynamic
sections in bfd with BFD_LINKER_CREATED may be ignored.

-- 
H.J.
From 4cbe42ea236bce32da4262f6f12328b58bac8f0f Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Fri, 22 Apr 2016 05:25:25 -0700
Subject: [PATCH] Add a fake bfd to hold linker created dynamic sections

Currently, we hold linker created dynamic sections in an input shared
object, which has its own dynamic sections, when the first input file
from linker is a shared object.  It may lead to conflicts between
linker created dynamic sections and shared object's dynamic sections.
We can use a a fake bfd to hold linker created dynamic sections.
Unfortunately, it doesn't work due to BFD_LINKER_CREATED.  Dynamic
sections in bfd with BFD_LINKER_CREATED may be ignored.
---
 bfd/elflink.c              | 33 ++++++---------------------------
 ld/emultempl/aarch64elf.em |  2 ++
 ld/emultempl/armelf.em     |  2 ++
 ld/emultempl/avrelf.em     |  1 +
 ld/emultempl/elf32.em      | 45 ++++++++++++++++++++++++++++++++++++++++++++-
 ld/emultempl/hppaelf.em    |  2 ++
 ld/emultempl/m68hc1xelf.em |  2 ++
 ld/emultempl/m68kelf.em    |  2 ++
 ld/emultempl/metagelf.em   |  2 ++
 ld/emultempl/mipself.em    |  2 ++
 ld/emultempl/nds32elf.em   |  2 ++
 ld/emultempl/nios2elf.em   |  2 ++
 ld/emultempl/ppc32elf.em   |  2 ++
 ld/emultempl/ppc64elf.em   |  2 ++
 ld/emultempl/rxelf.em      |  2 ++
 15 files changed, 75 insertions(+), 28 deletions(-)

diff --git a/bfd/elflink.c b/bfd/elflink.c
index 6f67266..5656ca0 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -198,31 +198,11 @@ _bfd_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
 
 /* Create a strtab to hold the dynamic symbol names.  */
 static bfd_boolean
-_bfd_elf_link_create_dynstrtab (bfd *abfd, struct bfd_link_info *info)
+_bfd_elf_link_create_dynstrtab (struct bfd_link_info *info)
 {
   struct elf_link_hash_table *hash_table;
 
   hash_table = elf_hash_table (info);
-  if (hash_table->dynobj == NULL)
-    {
-      /* We may not set dynobj, an input file holding linker created
-	 dynamic sections to abfd, which may be a dynamic object with
-	 its own dynamic sections.  We need to find a normal input file
-	 to hold linker created sections if possible.  */
-      if ((abfd->flags & (DYNAMIC | BFD_PLUGIN)) != 0)
-	{
-	  bfd *ibfd;
-	  for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link.next)
-	    if ((ibfd->flags
-		 & (DYNAMIC | BFD_LINKER_CREATED | BFD_PLUGIN)) == 0)
-	      {
-		abfd = ibfd;
-		break;
-	      }
-	}
-      hash_table->dynobj = abfd;
-    }
-
   if (hash_table->dynstr == NULL)
     {
       hash_table->dynstr = _bfd_elf_strtab_init ();
@@ -253,7 +233,7 @@ _bfd_elf_link_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
   if (elf_hash_table (info)->dynamic_sections_created)
     return TRUE;
 
-  if (!_bfd_elf_link_create_dynstrtab (abfd, info))
+  if (!_bfd_elf_link_create_dynstrtab (info))
     return FALSE;
 
   abfd = elf_hash_table (info)->dynobj;
@@ -3206,15 +3186,14 @@ _bfd_elf_add_dynamic_entry (struct bfd_link_info *info,
    1 if a DT_NEEDED tag already exists, and 0 on success.  */
 
 static int
-elf_add_dt_needed_tag (bfd *abfd,
-		       struct bfd_link_info *info,
+elf_add_dt_needed_tag (struct bfd_link_info *info,
 		       const char *soname,
 		       bfd_boolean do_it)
 {
   struct elf_link_hash_table *hash_table;
   bfd_size_type strindex;
 
-  if (!_bfd_elf_link_create_dynstrtab (abfd, info))
+  if (!_bfd_elf_link_create_dynstrtab (info))
     return -1;
 
   hash_table = elf_hash_table (info);
@@ -3908,7 +3887,7 @@ error_free_dyn:
 	 will need to know it.  */
       elf_dt_name (abfd) = soname;
 
-      ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed);
+      ret = elf_add_dt_needed_tag (info, soname, add_needed);
       if (ret < 0)
 	goto error_return;
 
@@ -4717,7 +4696,7 @@ error_free_dyn:
 		(elf_dyn_lib_class (abfd) & ~DYN_AS_NEEDED);
 
 	      add_needed = TRUE;
-	      ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed);
+	      ret = elf_add_dt_needed_tag (info, soname, add_needed);
 	      if (ret < 0)
 		goto error_free_vers;
 
diff --git a/ld/emultempl/aarch64elf.em b/ld/emultempl/aarch64elf.em
index 9923be3..c961b9e 100644
--- a/ld/emultempl/aarch64elf.em
+++ b/ld/emultempl/aarch64elf.em
@@ -322,6 +322,8 @@ aarch64_elf_create_output_section_statements (void)
 
   stub_file->the_bfd->flags |= BFD_LINKER_CREATED;
   ldlang_add_file (stub_file);
+
+  gld${EMULATION_NAME}_create_output_section_statements ();
 }
 
 /* Avoid processing the fake stub_file in vercheck, stat_needed and
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
index 2e43172..b7b9463 100644
--- a/ld/emultempl/armelf.em
+++ b/ld/emultempl/armelf.em
@@ -514,6 +514,8 @@ arm_elf_create_output_section_statements (void)
   /* Also use the stub file for stubs placed in a single output section.  */
   bfd_elf32_arm_add_glue_sections_to_bfd (stub_file->the_bfd, &link_info);
   bfd_elf32_arm_get_bfd_for_interworking (stub_file->the_bfd, &link_info);
+
+  gld${EMULATION_NAME}_create_output_section_statements ();
 }
 
 /* Avoid processing the fake stub_file in vercheck, stat_needed and
diff --git a/ld/emultempl/avrelf.em b/ld/emultempl/avrelf.em
index 4710b6e..80526ac 100644
--- a/ld/emultempl/avrelf.em
+++ b/ld/emultempl/avrelf.em
@@ -136,6 +136,7 @@ avr_elf_create_output_section_statements (void)
 
   ldlang_add_file (stub_file);
 
+  gld${EMULATION_NAME}_create_output_section_statements ();
   return;
 
   err_ret:
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 4f5d1a4..e90af48 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -64,6 +64,7 @@ static void gld${EMULATION_NAME}_after_parse (void);
 static void gld${EMULATION_NAME}_after_open (void);
 static void gld${EMULATION_NAME}_before_allocation (void);
 static void gld${EMULATION_NAME}_after_allocation (void);
+static void gld${EMULATION_NAME}_create_output_section_statements (void);
 static lang_output_section_statement_type *gld${EMULATION_NAME}_place_orphan
   (asection *, const char *, int);
 EOF
@@ -263,6 +264,8 @@ gld${EMULATION_NAME}_stat_needed (lang_input_statement_type *s)
     return;
   if (s->the_bfd == NULL)
     return;
+  if ((s->the_bfd->flags & BFD_LINKER_CREATED) != 0)
+    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.  */
@@ -1400,6 +1403,46 @@ gld${EMULATION_NAME}_find_statement_assignment (lang_statement_union_type *s)
 
 EOF
 
+if test x"$LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS" != xgld"$EMULATION_NAME"create_output_section_statements; then
+fragment <<EOF
+
+/* Fake input file for dynamic sections.  */
+static lang_input_statement_type *dynobj;
+
+/* This is called before the input files are opened.  We create a new
+   fake input file to hold the dynamic sections.  */
+
+static void
+gld${EMULATION_NAME}_create_output_section_statements (void)
+{
+  if (bfd_get_flavour (link_info.output_bfd) != bfd_target_elf_flavour)
+    return;
+
+  dynobj = lang_add_input_file (" dynobj ",
+				lang_input_file_is_fake_enum,
+				NULL);
+  dynobj->the_bfd = bfd_create (" dynobj ", link_info.output_bfd);
+  if (dynobj->the_bfd == NULL
+      || !bfd_set_arch_mach (dynobj->the_bfd,
+			     bfd_get_arch (link_info.output_bfd),
+			     bfd_get_mach (link_info.output_bfd)))
+    {
+      einfo ("%F%P: can not create BFD to hold dynamic sections: %E\n");
+      return;
+    }
+
+  dynobj->the_bfd->flags |= BFD_LINKER_CREATED;
+  elf_elfheader (dynobj->the_bfd)->e_ident[EI_CLASS]
+    = (get_elf_backend_data (link_info.output_bfd)->s->arch_size == 64
+       ? ELFCLASS64 : ELFCLASS32);
+  elf_hash_table (&link_info)->dynobj = dynobj->the_bfd;
+
+  ldlang_add_file (dynobj);
+}
+
+EOF
+fi
+
 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="
@@ -2515,7 +2558,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
   "${EMULATION_NAME}",
   "${OUTPUT_FORMAT}",
   ${LDEMUL_FINISH-finish_default},
-  ${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL},
+  ${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-gld${EMULATION_NAME}_create_output_section_statements},
   ${LDEMUL_OPEN_DYNAMIC_ARCHIVE-gld${EMULATION_NAME}_open_dynamic_archive},
   ${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan},
   ${LDEMUL_SET_SYMBOLS-NULL},
diff --git a/ld/emultempl/hppaelf.em b/ld/emultempl/hppaelf.em
index a1d2e80..5965e9b 100644
--- a/ld/emultempl/hppaelf.em
+++ b/ld/emultempl/hppaelf.em
@@ -88,6 +88,8 @@ hppaelf_create_output_section_statements (void)
 
   stub_file->the_bfd->flags |= BFD_LINKER_CREATED;
   ldlang_add_file (stub_file);
+
+  gld${EMULATION_NAME}_create_output_section_statements ();
 }
 
 
diff --git a/ld/emultempl/m68hc1xelf.em b/ld/emultempl/m68hc1xelf.em
index 739479d..b2e8fa1 100644
--- a/ld/emultempl/m68hc1xelf.em
+++ b/ld/emultempl/m68hc1xelf.em
@@ -155,6 +155,8 @@ m68hc11elf_create_output_section_statements (void)
     }
 
   ldlang_add_file (stub_file);
+
+  gld${EMULATION_NAME}_create_output_section_statements ();
 }
 
 
diff --git a/ld/emultempl/m68kelf.em b/ld/emultempl/m68kelf.em
index c1a514c..17150ac 100644
--- a/ld/emultempl/m68kelf.em
+++ b/ld/emultempl/m68kelf.em
@@ -208,6 +208,8 @@ static void
 elf_m68k_create_output_section_statements (void)
 {
   bfd_elf_m68k_set_target_options (&link_info, got_handling);
+
+  gld${EMULATION_NAME}_create_output_section_statements ();
 }
 
 EOF
diff --git a/ld/emultempl/metagelf.em b/ld/emultempl/metagelf.em
index 5626eca..95900d7 100644
--- a/ld/emultempl/metagelf.em
+++ b/ld/emultempl/metagelf.em
@@ -65,6 +65,8 @@ metagelf_create_output_section_statements (void)
 
   stub_file->the_bfd->flags |= BFD_LINKER_CREATED;
   ldlang_add_file (stub_file);
+
+  gld${EMULATION_NAME}_create_output_section_statements ();
 }
 
 
diff --git a/ld/emultempl/mipself.em b/ld/emultempl/mipself.em
index dbff36b..d64ca0d 100644
--- a/ld/emultempl/mipself.em
+++ b/ld/emultempl/mipself.em
@@ -206,6 +206,8 @@ mips_create_output_section_statements (void)
 
   if (is_mips_elf (link_info.output_bfd))
     _bfd_mips_elf_init_stubs (&link_info, mips_add_stub_section);
+
+  gld${EMULATION_NAME}_create_output_section_statements ();
 }
 
 /* This is called after we have merged the private data of the input bfds.  */
diff --git a/ld/emultempl/nds32elf.em b/ld/emultempl/nds32elf.em
index 08da695..eee5087 100644
--- a/ld/emultempl/nds32elf.em
+++ b/ld/emultempl/nds32elf.em
@@ -65,6 +65,8 @@ nds32_elf_create_output_section_statements (void)
 				     ex9_export_file, ex9_import_file,
 				     update_ex9_table, ex9_limit,
 				     ex9_loop_aware, ifc_loop_aware);
+
+  gld${EMULATION_NAME}_create_output_section_statements ();
 }
 
 static void
diff --git a/ld/emultempl/nios2elf.em b/ld/emultempl/nios2elf.em
index da4bea0..3b1275c 100644
--- a/ld/emultempl/nios2elf.em
+++ b/ld/emultempl/nios2elf.em
@@ -70,6 +70,8 @@ nios2elf_create_output_section_statements (void)
 
   stub_file->the_bfd->flags |= BFD_LINKER_CREATED;
   ldlang_add_file (stub_file);
+
+  gld${EMULATION_NAME}_create_output_section_statements ();
 }
 
 
diff --git a/ld/emultempl/ppc32elf.em b/ld/emultempl/ppc32elf.em
index a0255cd..37dcc95 100644
--- a/ld/emultempl/ppc32elf.em
+++ b/ld/emultempl/ppc32elf.em
@@ -53,6 +53,8 @@ ppc_after_open_output (void)
     pagesize = config.commonpagesize;
   params.pagesize_p2 = bfd_log2 (pagesize);
   ppc_elf_link_params (&link_info, &params);
+
+  gld${EMULATION_NAME}_create_output_section_statements ();
 }
 
 EOF
diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em
index d7c0686..1f48ab1 100644
--- a/ld/emultempl/ppc64elf.em
+++ b/ld/emultempl/ppc64elf.em
@@ -98,6 +98,8 @@ ppc_create_output_section_statements (void)
     params.save_restore_funcs = !bfd_link_relocatable (&link_info);
   if (!ppc64_elf_init_stub_bfd (&link_info, &params))
     einfo ("%F%P: can not init BFD: %E\n");
+
+  gld${EMULATION_NAME}_create_output_section_statements ();
 }
 
 /* Called after opening files but before mapping sections.  */
diff --git a/ld/emultempl/rxelf.em b/ld/emultempl/rxelf.em
index 36be1ba..d1fc9fa 100644
--- a/ld/emultempl/rxelf.em
+++ b/ld/emultempl/rxelf.em
@@ -38,6 +38,8 @@ rx_elf_create_output_section_statements (void)
   extern void bfd_elf32_rx_set_target_flags (bfd_boolean, bfd_boolean);
 
   bfd_elf32_rx_set_target_flags (no_flag_mismatch_warnings, ignore_lma);
+
+  gld${EMULATION_NAME}_create_output_section_statements ();
 }
 
 EOF
-- 
2.5.5


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]