linking PE images with referenced absolute symbols

Message ID c0f28437-a463-6bbf-7603-43c5874079dc@suse.com
State New
Headers show
Series
  • linking PE images with referenced absolute symbols
Related show

Commit Message

Alan Modra via Binutils Feb. 18, 2021, 4:50 p.m.
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:


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

Patch

--- 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;