Implement --enable-reloc-section

Message ID 20191229123839.5346-1-ssbssa@yahoo.de
State New
Headers show
Series
  • Implement --enable-reloc-section
Related show

Commit Message

Alan Modra via Binutils Dec. 29, 2019, 12:38 p.m.
The base relocation table is necessary if the image is loaded at
a different image base than specified in the PE header.

For that reason this option is also enabled if --dynamicbase is active.
And --high-entryopy-va enables --dynamicbase.

ld/ChangeLog:

2019-12-29  Hannes Domani  <ssbssa@yahoo.de>

	* 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/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 +
 7 files changed, 40 insertions(+), 24 deletions(-)

-- 
2.24.1

Comments

Nick Clifton Jan. 3, 2020, 12:58 p.m. | #1
Hi Hannes,

> The base relocation table is necessary if the image is loaded at

> a different image base than specified in the PE header.

> 

> For that reason this option is also enabled if --dynamicbase is active.

> And --high-entryopy-va enables --dynamicbase.

> 

> ld/ChangeLog:

> 

> 2019-12-29  Hannes Domani  <ssbssa@yahoo.de>

> 

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


Approved and applied.  Thanks very much for contributing this patch.

Cheers
  Nick

Patch

diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index 7e85ede3e2..47045a3ae9 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -270,6 +270,7 @@  fragment <<EOF
 #define OPTION_INSERT_TIMESTAMP		(OPTION_TERMINAL_SERVER_AWARE + 1)
 #define OPTION_NO_INSERT_TIMESTAMP	(OPTION_INSERT_TIMESTAMP + 1)
 #define OPTION_BUILD_ID			(OPTION_NO_INSERT_TIMESTAMP + 1)
+#define OPTION_ENABLE_RELOC_SECTION	(OPTION_BUILD_ID + 1)
 
 static void
 gld${EMULATION_NAME}_add_options
@@ -349,6 +350,7 @@  gld${EMULATION_NAME}_add_options
     {"wdmdriver", no_argument, NULL, OPTION_WDM_DRIVER},
     {"tsaware", no_argument, NULL, OPTION_TERMINAL_SERVER_AWARE},
     {"build-id", optional_argument, NULL, OPTION_BUILD_ID},
+    {"enable-reloc-section", no_argument, NULL, OPTION_ENABLE_RELOC_SECTION},
     {NULL, no_argument, NULL, 0}
   };
 
@@ -483,6 +485,7 @@  gld_${EMULATION_NAME}_list_options (FILE *file)
                                        in object files\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"));
@@ -855,6 +858,9 @@  gld${EMULATION_NAME}_handle_option (int optc)
 /*  Get DLLCharacteristics bits  */
     case OPTION_DYNAMIC_BASE:
       pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
+      /* fall through */
+    case OPTION_ENABLE_RELOC_SECTION:
+      pe_dll_enable_reloc_section = 1;
       break;
     case OPTION_FORCE_INTEGRITY:
       pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY;
@@ -1947,6 +1953,7 @@  gld_${EMULATION_NAME}_finish (void)
 #ifdef DLL_SUPPORT
   if (bfd_link_pic (&link_info)
 #if !defined(TARGET_IS_shpe)
+      || pe_dll_enable_reloc_section
       || (!bfd_link_relocatable (&link_info)
 	  && pe_def_file->num_exports != 0)
 #endif
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
index f9f6a8e98d..9f8e0c7aac 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 ed538fbfe2..96aba55c3d 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 7f45546aaf..76fd314200 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 ffbd25cc77..d502533523 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 c80f5d736f..1113a0743e 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 2d1878a78d..b091d1c6bb 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;