diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2016-04-22 05:25:25 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2016-04-22 05:25:25 -0700 |
commit | 4cbe42ea236bce32da4262f6f12328b58bac8f0f (patch) | |
tree | 53953e5797a50d9218a795544eca4f93d1f82746 | |
parent | 6645479e9dc9470d22393d5bc4ef2ef2d391e848 (diff) | |
download | gdb-users/hjl/dynobj.zip gdb-users/hjl/dynobj.tar.gz gdb-users/hjl/dynobj.tar.bz2 |
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.c | 33 | ||||
-rw-r--r-- | ld/emultempl/aarch64elf.em | 2 | ||||
-rw-r--r-- | ld/emultempl/armelf.em | 2 | ||||
-rw-r--r-- | ld/emultempl/avrelf.em | 1 | ||||
-rw-r--r-- | ld/emultempl/elf32.em | 45 | ||||
-rw-r--r-- | ld/emultempl/hppaelf.em | 2 | ||||
-rw-r--r-- | ld/emultempl/m68hc1xelf.em | 2 | ||||
-rw-r--r-- | ld/emultempl/m68kelf.em | 2 | ||||
-rw-r--r-- | ld/emultempl/metagelf.em | 2 | ||||
-rw-r--r-- | ld/emultempl/mipself.em | 2 | ||||
-rw-r--r-- | ld/emultempl/nds32elf.em | 2 | ||||
-rw-r--r-- | ld/emultempl/nios2elf.em | 2 | ||||
-rw-r--r-- | ld/emultempl/ppc32elf.em | 2 | ||||
-rw-r--r-- | ld/emultempl/ppc64elf.em | 2 | ||||
-rw-r--r-- | 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, ¶ms); + + 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, ¶ms)) 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 |