summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2016-04-22 05:25:25 -0700
committerH.J. Lu <hjl.tools@gmail.com>2016-04-22 05:25:25 -0700
commit4cbe42ea236bce32da4262f6f12328b58bac8f0f (patch)
tree53953e5797a50d9218a795544eca4f93d1f82746
parent6645479e9dc9470d22393d5bc4ef2ef2d391e848 (diff)
downloadbinutils-gdb-users/hjl/dynobj.tar.gz
Add a fake bfd to hold linker created dynamic sectionsusers/hjl/dynobj
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.
-rw-r--r--bfd/elflink.c33
-rw-r--r--ld/emultempl/aarch64elf.em2
-rw-r--r--ld/emultempl/armelf.em2
-rw-r--r--ld/emultempl/avrelf.em1
-rw-r--r--ld/emultempl/elf32.em45
-rw-r--r--ld/emultempl/hppaelf.em2
-rw-r--r--ld/emultempl/m68hc1xelf.em2
-rw-r--r--ld/emultempl/m68kelf.em2
-rw-r--r--ld/emultempl/metagelf.em2
-rw-r--r--ld/emultempl/mipself.em2
-rw-r--r--ld/emultempl/nds32elf.em2
-rw-r--r--ld/emultempl/nios2elf.em2
-rw-r--r--ld/emultempl/ppc32elf.em2
-rw-r--r--ld/emultempl/ppc64elf.em2
-rw-r--r--ld/emultempl/rxelf.em2
15 files changed, 75 insertions, 28 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 6f6726648fd..5656ca0ccb6 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 9923be3a6b6..c961b9e79bf 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 2e431720842..b7b94633738 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 4710b6e0e82..80526aca4c0 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 4f5d1a4d2c0..e90af48455b 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 a1d2e80d2a8..5965e9b1cfd 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 739479d7e51..b2e8fa1b7c7 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 c1a514c5a8f..17150acb51d 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 5626ecad830..95900d70829 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 dbff36bb8d1..d64ca0db71b 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 08da695bac0..eee5087c503 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 da4bea05d96..3b1275c70f6 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 a0255cd5323..37dcc953f90 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 d7c0686d681..1f48ab1f930 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 36be1ba6cc0..d1fc9fa0831 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