linking PE images with referenced absolute symbols

Jan Beulich jbeulich@suse.com
Thu Feb 18 16:50:04 GMT 2021


Hello,

in the course of investigating whether in the Xen Project we
could make use of the relatively new option of having ld
populate the .reloc section of such executables (EFI app in
our case, but the problem looks to affect e.g. Cygwin as well)
I've noticed (besides a few other quirks) that the linker
would emit relocations also for absolute symbols (I'm in
particular after making use of .sizeof.() / .startof.(), where
the former would be affected). Excluding absolute symbols
looks to be doable, on the surface:

--- 2.36/ld/pe-dll.c
+++ 2.36/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,13 @@ generate_reloc (bfd *abfd, struct bfd_li
 		      if (!strcmp (s->name, ".eh_frame"))
 			continue;
 		    }
+		  /* Nor for absolute symbols.  */
+		  else if (blhe && blhe->type == bfd_link_hash_defined
+			   && blhe->u.def.section == bfd_abs_section_ptr
+			   && (!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;

It became apparent pretty quickly though that some relocations
get wrongly squashed this way. This is because the function is
called down the call tree from ldemul_finish(), while only the
later invoked ldexp_finalize_syms() will take care of converting
script specified symbols living outside of sections from
absolute to section relative (_start and _end in particular). It
might be feasible to mimic here what set_sym_sections() does,
but I wasn't able to spot a way to get at the information that
it uses for doing its job.

Could anyone suggest an approach to resolve this problem, please?

Jan


More information about the Binutils mailing list