[PATCH] ld: Add -z start-stop-gc to let __start_/__stop_ not retain C identifier name sections

Alan Modra amodra@gmail.com
Mon Mar 1 03:59:52 GMT 2021


On Sat, Feb 27, 2021 at 09:03:19PM -0800, Fangrui Song wrote:
> Unfortunately if there is an undefined weak "__start_xx" and no xx is retained =>
> undefined symbol error due to ldlang.c:undef_start_stop .
> 
> I don't know how to distinguish undefined strong and undefined weak in undef_start_stop.

OK, so let's fix that first.

If a weak reference to a __start_foo or __stop_foo symbol ends up
having no definition due to all the foo sections being removed for
some reason, undef_start_stop currently makes the symbol strong
undefined.  That risks a linker undefined symbol error.  Fix that by
making the symbol undefweak and also undo some dynamic symbol state.

Note that saving the state of the symbol type at the time
lang_init_start_stop runs is not sufficient.  The linker may have
merged in a shared library reference by that point and made what was
an undefweak in regular objects, a strong undefined.  So it is
necessary to look at the ELF symbol flags to decide whether an
undefweak is the proper resolution.

Something probably should be done for COFF/PE too, but I'm unsure how
to do go about that.

	* ldlang.c (undef_start_stop): For ELF make undefined start/stop
	symbols undefweak if that was how they were referenced.  Undo
	dynamic state too.

diff --git a/ld/ldlang.c b/ld/ldlang.c
index 5ffc8444c7..a77e8fabef 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -6808,6 +6808,19 @@ undef_start_stop (struct bfd_link_hash_entry *h)
 	}
       h->type = bfd_link_hash_undefined;
       h->u.undef.abfd = NULL;
+      if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour)
+	{
+	  const struct elf_backend_data *bed;
+	  struct elf_link_hash_entry *eh = (struct elf_link_hash_entry *) h;
+	  unsigned int was_forced = eh->forced_local;
+
+	  bed = get_elf_backend_data (link_info.output_bfd);
+	  (*bed->elf_backend_hide_symbol) (&link_info, eh, TRUE);
+	  if (!eh->ref_regular_nonweak)
+	    h->type = bfd_link_hash_undefweak;
+	  eh->def_regular = 0;
+	  eh->forced_local = was_forced;
+	}
     }
 }
 

-- 
Alan Modra
Australia Development Lab, IBM


More information about the Binutils mailing list