diff options
Diffstat (limited to 'ld/emultempl/elf32.em')
-rw-r--r-- | ld/emultempl/elf32.em | 45 |
1 files changed, 44 insertions, 1 deletions
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}, |