From dc9bd8c92af67947db44b3cb428c050259b15cd0 Mon Sep 17 00:00:00 2001 From: Hannes Domani Date: Fri, 3 Jan 2020 12:55:12 +0000 Subject: [PATCH] For PE format files, the base relocation table is necessary if the image is loaded at a different image base than specified in the PE header. This patch provides a new option --enable-reloc-section to force the generation of this section. * emultempl/pe.em: Add new option --enable-reloc-section. * emultempl/pep.em: Likewise. * ld.texi: Document --enable-reloc-section. * pe-dll.c (pe_dll_build_sections): Use pe_dll_enable_reloc_section. (pe_dll_fill_sections): Simplify by calling pe_exe_fill_sections. * pe-dll.h: Add extern declaration of option flag. * pep-dll.c (pe_dll_enable_reloc_section): Add alias define for pep_dll_enable_reloc_section. * pep-dll.h: Add extern declaration of option flag. --- ld/ChangeLog | 12 ++++++++++++ ld/emultempl/pe.em | 7 +++++++ ld/emultempl/pep.em | 11 +++++++++-- ld/ld.texi | 8 ++++++++ ld/pe-dll.c | 35 +++++++++++++---------------------- ld/pe-dll.h | 1 + ld/pep-dll.c | 1 + ld/pep-dll.h | 1 + 8 files changed, 52 insertions(+), 24 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index e0aa3ea44ed..476e6cb894c 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,15 @@ +2020-01-03 Hannes Domani + + * emultempl/pe.em: Add new option --enable-reloc-section. + * emultempl/pep.em: Likewise. + * ld.texi: Document --enable-reloc-section. + * pe-dll.c (pe_dll_build_sections): Use pe_dll_enable_reloc_section. + (pe_dll_fill_sections): Simplify by calling pe_exe_fill_sections. + * pe-dll.h: Add extern declaration of option flag. + * pep-dll.c (pe_dll_enable_reloc_section): + Add alias define for pep_dll_enable_reloc_section. + * pep-dll.h: Add extern declaration of option flag. + 2020-01-02 Sergey Belyashov * Makefile.am: Add new target z80-elf diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index 2b2f9e2acb9..97fb1468aac 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -270,6 +270,7 @@ fragment <num_exports != 0) #endif diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em index 2fef25e81d6..e8f5ca503fb 100644 --- a/ld/emultempl/pep.em +++ b/ld/emultempl/pep.em @@ -247,7 +247,8 @@ enum options OPTION_INSERT_TIMESTAMP, OPTION_NO_INSERT_TIMESTAMP, OPTION_TERMINAL_SERVER_AWARE, - OPTION_BUILD_ID + OPTION_BUILD_ID, + OPTION_ENABLE_RELOC_SECTION }; static void @@ -325,6 +326,7 @@ gld${EMULATION_NAME}_add_options {"insert-timestamp", no_argument, NULL, OPTION_INSERT_TIMESTAMP}, {"no-insert-timestamp", no_argument, NULL, OPTION_NO_INSERT_TIMESTAMP}, {"build-id", optional_argument, NULL, OPTION_BUILD_ID}, + {"enable-reloc-section", no_argument, NULL, OPTION_ENABLE_RELOC_SECTION}, {NULL, no_argument, NULL, 0} }; @@ -448,6 +450,7 @@ gld_${EMULATION_NAME}_list_options (FILE *file) layout randomization (ASLR)\n")); fprintf (file, _(" --dynamicbase Image base address may be relocated using\n\ address space layout randomization (ASLR)\n")); + fprintf (file, _(" --enable-reloc-section Create the base relocation table\n")); fprintf (file, _(" --forceinteg Code integrity checks are enforced\n")); fprintf (file, _(" --nxcompat Image is compatible with data execution prevention\n")); fprintf (file, _(" --no-isolation Image understands isolation but do not isolate the image\n")); @@ -799,9 +802,12 @@ gld${EMULATION_NAME}_handle_option (int optc) /* Get DLLCharacteristics bits */ case OPTION_HIGH_ENTROPY_VA: pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA; - break; + /* fall through */ case OPTION_DYNAMIC_BASE: pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE; + /* fall through */ + case OPTION_ENABLE_RELOC_SECTION: + pep_dll_enable_reloc_section = 1; break; case OPTION_FORCE_INTEGRITY: pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY; @@ -1755,6 +1761,7 @@ gld_${EMULATION_NAME}_finish (void) #ifdef DLL_SUPPORT if (bfd_link_pic (&link_info) + || pep_dll_enable_reloc_section || (!bfd_link_relocatable (&link_info) && pep_def_file->num_exports != 0)) { diff --git a/ld/ld.texi b/ld/ld.texi index c7016f18452..eb7bcb99338 100644 --- a/ld/ld.texi +++ b/ld/ld.texi @@ -2995,12 +2995,15 @@ of the PE file header: @item --high-entropy-va Image is compatible with 64-bit address space layout randomization (ASLR). +This option also implies @option{--dynamicbase} and +@option{--enable-reloc-section}. @kindex --dynamicbase @item --dynamicbase The image base address may be relocated using address space layout randomization (ASLR). This feature was introduced with MS Windows Vista for i386 PE targets. +This option also implies @option{--enable-reloc-section}. @kindex --forceinteg @item --forceinteg @@ -3043,6 +3046,11 @@ same sources are linked. The option @option{--no-insert-timestamp} can be used to insert a zero value for the timestamp, this ensuring that binaries produced from identical sources will compare identically. + +@kindex --enable-reloc-section +@item --enable-reloc-section +Create the base relocation table, which is necessary if the image +is loaded at a different image base than specified in the PE header. @end table @c man end diff --git a/ld/pe-dll.c b/ld/pe-dll.c index 4e26c0b9086..397af8780e4 100644 --- a/ld/pe-dll.c +++ b/ld/pe-dll.c @@ -160,6 +160,7 @@ int pe_dll_extra_pe_debug = 0; int pe_use_nul_prefixed_import_tables = 0; int pe_use_coff_long_section_names = -1; int pe_leading_underscore = -1; +int pe_dll_enable_reloc_section = 0; /* Static variables and types. */ @@ -3554,7 +3555,14 @@ pe_dll_build_sections (bfd *abfd, struct bfd_link_info *info) process_def_file_and_drectve (abfd, info); if (pe_def_file->num_exports == 0 && !bfd_link_pic (info)) - return; + { + if (pe_dll_enable_reloc_section) + { + build_filler_bfd (0); + pe_output_file_set_long_section_names (filler_bfd); + } + return; + } generate_edata (abfd, info); build_filler_bfd (1); @@ -3573,33 +3581,16 @@ pe_exe_build_sections (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED) void pe_dll_fill_sections (bfd *abfd, struct bfd_link_info *info) { - pe_dll_id_target (bfd_get_target (abfd)); - pe_output_file_set_long_section_names (abfd); - image_base = pe_data (abfd)->pe_opthdr.ImageBase; + pe_exe_fill_sections (abfd, info); - generate_reloc (abfd, info); - if (reloc_sz > 0) + if (edata_s) { - bfd_set_section_size (reloc_s, reloc_sz); - - /* Resize the sections. */ - lang_reset_memory_regions (); - lang_size_sections (NULL, TRUE); - - /* Redo special stuff. */ - ldemul_after_allocation (); - - /* Do the assignments again. */ - lang_do_assignments (lang_final_phase_enum); + fill_edata (abfd, info); + edata_s->contents = edata_d; } - fill_edata (abfd, info); - if (bfd_link_dll (info)) pe_data (abfd)->dll = 1; - - edata_s->contents = edata_d; - reloc_s->contents = reloc_d; } void diff --git a/ld/pe-dll.h b/ld/pe-dll.h index 1ad3e43d806..2dbd0fb9867 100644 --- a/ld/pe-dll.h +++ b/ld/pe-dll.h @@ -38,6 +38,7 @@ extern int pe_dll_extra_pe_debug; extern int pe_use_nul_prefixed_import_tables; extern int pe_use_coff_long_section_names; extern int pe_leading_underscore; +extern int pe_dll_enable_reloc_section; typedef enum { EXCLUDESYMS, EXCLUDELIBS, EXCLUDEFORIMPLIB } exclude_type; diff --git a/ld/pep-dll.c b/ld/pep-dll.c index 172b9705d9d..16140d322b0 100644 --- a/ld/pep-dll.c +++ b/ld/pep-dll.c @@ -39,6 +39,7 @@ #define pe_use_coff_long_section_names \ pep_use_coff_long_section_names #define pe_leading_underscore pep_leading_underscore +#define pe_dll_enable_reloc_section pep_dll_enable_reloc_section /* Unique global name for functions to avoid double defined symbols. */ #define pe_find_data_imports pep_find_data_imports diff --git a/ld/pep-dll.h b/ld/pep-dll.h index 0b6676792cf..d05598f064d 100644 --- a/ld/pep-dll.h +++ b/ld/pep-dll.h @@ -39,6 +39,7 @@ extern int pep_dll_extra_pe_debug; extern int pep_use_nul_prefixed_import_tables; extern int pep_use_coff_long_section_names; extern int pep_leading_underscore; +extern int pep_dll_enable_reloc_section; typedef enum { EXCLUDESYMS, EXCLUDELIBS, EXCLUDEFORIMPLIB } exclude_type; -- 2.30.2