While LLVM's lld is supposed to be a drop-in replacement for GNU ld [1],
it appears to not understand quoted section names as operands to e.g.
ADDR(). Therefore the original workaround broke the build in
environments where ld is actually LLVM's, like on FreeBSD.

Fixes: 58ad654ebce7 ("x86: work around build issue with GNU ld 2.37")
Reported-by: Andrew Cooper <andrew.coop...@citrix.com>
Signed-off-by: Jan Beulich <jbeul...@suse.com>

[1] https://lld.llvm.org/
---
I haven't been able to find an environment where I could actually try
with lld (ld.lld); all testing was with GNU ld (ld.bfd).

--- a/.gitignore
+++ b/.gitignore
@@ -306,6 +306,7 @@
 xen/.config.old
 xen/.xen.elf32
 xen/System.map
+xen/arch/x86/.check.*
 xen/arch/x86/asm-macros.i
 xen/arch/x86/boot/mkelf32
 xen/arch/x86/boot/cmdline.S
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -92,10 +92,16 @@ efi-$(CONFIG_PV_SHIM_EXCLUSIVE) :=
 
 ifneq ($(build_id_linker),)
 notes_phdrs = --notes
+# Determine whether to engage a workaround for GNU ld 2.37.
+build-id-ld-good = $(shell echo 'void test(void) {}' \
+                           | $(CC) $(XEN_CFLAGS) -o .check.o -c -x c - 
2>.check.err \
+                           && $(LD) -T check.lds -o .check.elf .check.o 
2>>.check.err \
+                           && echo y)
 else
 ifeq ($(CONFIG_PVH_GUEST),y)
 notes_phdrs = --notes
 endif
+build-id-ld-good := y
 endif
 
 ifdef CONFIG_LIVEPATCH
@@ -291,6 +297,10 @@ $(BASEDIR)/include/asm-x86/asm-macros.h:
        $(call move-if-changed,$@.new,$@)
 
 efi.lds: AFLAGS-y += -DEFI
+xen.lds: Makefile
+ifneq ($(build-id-ld-good),y)
+xen.lds: CFLAGS-y += -DQUOTE_SECTION_NAMES
+endif
 xen.lds efi.lds: xen.lds.S
        $(CPP) -P $(call cpp_flags,$(a_flags)) -MQ $@ -o $@ $<
 
@@ -302,7 +312,7 @@ hweight.o: CFLAGS-y += $(foreach reg,cx
 
 .PHONY: clean
 clean::
-       rm -f *.lds *.new boot/*.o boot/*~ boot/core boot/mkelf32
+       rm -f ???.lds *.new .check.* boot/*.o boot/*~ boot/core boot/mkelf32
        rm -f asm-macros.i $(BASEDIR)/include/asm-x86/asm-macros.*
        rm -f $(BASEDIR)/.xen-syms.[0-9]* boot/.*.d $(BASEDIR)/.xen.elf32
        rm -f $(BASEDIR)/.xen.efi.[0-9]* efi/*.efi efi/mkreloc
--- /dev/null
+++ b/xen/arch/x86/check.lds
@@ -0,0 +1,11 @@
+/*
+ * Minimal linker script used to check whether the linker understands section
+ * names containing a dash (like in .note.gnu.build-id) inside ADDR() and alike
+ * without quoting them.
+ */
+OUTPUT_FORMAT("elf64-x86-64")
+OUTPUT_ARCH("i386:x86-64")
+SECTIONS
+{
+ .text-1 : AT(ADDR(.text-1)) { *(.text) }
+}
--- a/xen/arch/x86/xen.lds.S
+++ b/xen/arch/x86/xen.lds.S
@@ -18,7 +18,12 @@ ENTRY(efi_start)
 #else /* !EFI */
 
 #define FORMAT "elf64-x86-64"
+
+#if defined(QUOTE_SECTION_NAMES) /* GNU ld 2.37 workaround */
 #define DECL_SECTION(x) x : AT(ADDR(#x) - __XEN_VIRT_START)
+#else
+#define DECL_SECTION(x) x : AT(ADDR(x) - __XEN_VIRT_START)
+#endif
 
 ENTRY(start_pa)
 


Reply via email to