[PATCH 1/6] ld: don't generate base relocations in PE output for absolute symbols

Jan Beulich jbeulich@suse.com
Tue Mar 2 09:47:03 GMT 2021


It is the very nature of absolute symbols that they don't change even
if the loader decides to put the image at other than its link-time base
address. Of the linker-defined (and PE-specific) symbols __image_base__
(and its alias) needs special casing, as it'll still appear to be
absolute at this point.

A new inquiry function in ldexp.c is needed because PE base relocations
get generated before ldexp_finalize_syms() runs, yet whether a
relocation is needed depends on the ultimate property of a symbol.

ld/
2021-02-XX  Jan Beulich  <jbeulich@suse.com>

	* ldexp.c (ldexp_is_final_sym_absolute): New.
	* ldexp.h (ldexp_is_final_sym_absolute): Declare.
	* pe-dll.c (generate_reloc): Skip absolute symbols.

--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -1696,6 +1696,28 @@ ldexp_finalize_syms (void)
   bfd_hash_traverse (&definedness_table, set_sym_sections, NULL);
 }
 
+/* Determine whether a symbol is going to remain absolute even after
+   ldexp_finalize_syms() has run.  */
+
+bfd_boolean
+ldexp_is_final_sym_absolute (const struct bfd_link_hash_entry *h)
+{
+  if (h->type == bfd_link_hash_defined
+      && h->u.def.section == bfd_abs_section_ptr)
+    {
+      const struct definedness_hash_entry *def;
+
+      if (!h->ldscript_def)
+	return TRUE;
+
+      def = symbol_defined (h->root.string);
+      if (def != NULL)
+	return def->final_sec == bfd_abs_section_ptr;
+    }
+
+  return FALSE;
+}
+
 void
 ldexp_finish (void)
 {
--- a/ld/ldexp.h
+++ b/ld/ldexp.h
@@ -239,6 +239,7 @@ bfd_vma exp_get_abs_int
   (etree_type *, int, char *);
 void ldexp_init (void);
 void ldexp_finalize_syms (void);
+bfd_boolean ldexp_is_final_sym_absolute (const struct bfd_link_hash_entry *);
 void ldexp_finish (void);
 
 #endif
--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -1579,13 +1579,13 @@ generate_reloc (bfd *abfd, struct bfd_li
 		  && relocs[i]->howto->type != pe_details->imagebase_reloc)
 		{
 		  struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr;
+		  const struct bfd_link_hash_entry *blhe
+		    = bfd_wrapped_link_hash_lookup (abfd, info, sym->name,
+						    FALSE, FALSE, FALSE);
 
 		  /* Don't create relocs for undefined weak symbols.  */
 		  if (sym->flags == BSF_WEAK)
 		    {
-		      struct bfd_link_hash_entry *blhe
-			= bfd_wrapped_link_hash_lookup (abfd, info, sym->name,
-						FALSE, FALSE, FALSE);
 		      if (blhe && blhe->type == bfd_link_hash_undefweak)
 			{
 			  /* Check aux sym and see if it is defined or not. */
@@ -1617,6 +1617,12 @@ generate_reloc (bfd *abfd, struct bfd_li
 		      if (!strcmp (s->name, ".eh_frame"))
 			continue;
 		    }
+		  /* Nor for absolute symbols.  */
+		  else if (blhe && ldexp_is_final_sym_absolute (blhe)
+			   && (!blhe->linker_def
+			       || (strcmp(sym->name, "__image_base__")
+				   && strcmp(sym->name, U ("__ImageBase")))))
+		    continue;
 
 		  reloc_data[total_relocs].vma = sec_vma + relocs[i]->address;
 		  reloc_data[total_relocs].idx = total_relocs;



More information about the Binutils mailing list