Compare commits

...

1 Commits

Author SHA1 Message Date
H.J. Lu
4cbe42ea23 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.
2016-04-22 05:25:25 -07:00
15 changed files with 75 additions and 28 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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},

View File

@@ -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 ();
}

View File

@@ -155,6 +155,8 @@ m68hc11elf_create_output_section_statements (void)
}
ldlang_add_file (stub_file);
gld${EMULATION_NAME}_create_output_section_statements ();
}

View File

@@ -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

View File

@@ -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 ();
}

View File

@@ -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. */

View File

@@ -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

View File

@@ -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 ();
}

View File

@@ -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

View File

@@ -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. */

View File

@@ -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