Skip to contentSkip to conversation

Add support for GNU gold

PATCH Superseded Sami Tolvanen 4 participants 28 messages Nov 29, 2017 – Dec 1, 2017

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover Add support for GNU gold

These patches add macros for detecting the linker name and version, and apply fixes and workarounds needed to link the arm64 kernel with GNU gold.

Sami Tolvanen (7):
kbuild: add ld-name macro and support for GNU gold
kbuild: add ld-if-name-version and linker-specific macros
kbuild: fix LD_DEAD_CODE_DATA_ELIMINATION with GNU gold
arm64: fix -m for GNU gold
arm64: keep .altinstructions and .altinstr_replacement
arm64: explicitly pass --no-fix-cortex-a53-843419 to GNU gold
arm64: add a workaround for GNU gold with ARM64_MODULE_PLTS

 Makefile                          |  5 +++++
 arch/arm64/Makefile               | 17 +++++++++++++++++
 arch/arm64/kernel/module.lds      |  4 ++--
 arch/arm64/kernel/vmlinux.lds.S   |  4 ++--
 include/asm-generic/vmlinux.lds.h |  8 ++++----
 scripts/Kbuild.include            | 16 ++++++++++++++++
 6 files changed, 46 insertions(+), 8 deletions(-)
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog
#1 lore raw

PATCH 1/7 kbuild: add ld-name macro and support for GNU gold

GNU gold may require different flags than GNU ld. Add a macro for detecting the linker and conditionally add gold specific flags from LDFLAGS_GOLD.

---
 Makefile               | 5 +++++
 scripts/Kbuild.include | 4 ++++
 2 files changed, 9 insertions(+)
Makefile +5 -0
index f761bf475ba5..a16c98d6e3ba 100644
@@ -814,6 +814,11 @@ include scripts/Makefile.kasan
 include scripts/Makefile.extrawarn
 include scripts/Makefile.ubsan
 
+# Add any flags specific to ld.gold
+ifeq ($(ld-name),gold)
+LDFLAGS		+= $(LDFLAGS_GOLD)
+endif
+
 # Add any arch overrides and user supplied CPPFLAGS, AFLAGS and CFLAGS as the
 # last assignments
 KBUILD_CPPFLAGS += $(ARCH_CPPFLAGS) $(KCPPFLAGS)
scripts/Kbuild.include +4 -0
index b6d7d347b203..a7c7843c2cf1 100644
@@ -277,6 +277,10 @@ ld-option = $(call try-run-cached,\
 # Important: no spaces around options
 ar-option = $(call try-run-cached, $(AR) rc$(1) "$$TMP",$(1),$(2))
 
+# ld-name
+# Expands to either bfd or gold
+ld-name = $(shell $(LD) -v 2>&1 | grep -q "GNU gold" && echo gold || echo bfd)
+
 # ld-version
 # Note this is mainly for HJ Lu's 3 number binutil versions
 ld-version = $(call shell-cached,$(LD) --version | $(srctree)/scripts/ld-version.sh)
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog
#2 lore raw

Re: [PATCH 1/7] kbuild: add ld-name macro and support for GNU gold

Quoted 3 lines · Sami Tolvanen

GNU gold may require different flags than GNU ld. Add a macro for detecting the linker and conditionally add gold specific flags from LDFLAGS_GOLD.

Right, but you're still only ever using one linker per build, correct?
Can we get away without 2 distinct flags?

Makefile include scripts/Makefile.kasan · line 821

Quoted 5 lines
Makefile +5 -0
+# Add any flags specific to ld.gold
+ifeq ($(ld-name),gold)
+LDFLAGS                += $(LDFLAGS_GOLD)
+endif
+

Patch 1 and 6 have this pattern of always assigning to LDFLAGS_GOLD, then that to LDFLAGS. Wouldn't it be better to check the ld-name and conditionally assign to LDFLAGS? Then LDFLAGS_GOLD is not necessary. For example, what I'm suggesting is what is done in patch 4.

scripts/Kbuild.include ld-option = $(call try-run-cached,\ · line 283

Quoted 4 lines
scripts/Kbuild.include +4 -0
+# ld-name
+# Expands to either bfd or gold
+ld-name = $(shell $(LD) -v 2>&1 | grep -q "GNU gold" && echo gold || echo bfd)
+

This part LGTM.

#3 lore raw

Re: [PATCH 1/7] kbuild: add ld-name macro and support for GNU gold

Quoted 1 line · Nick Desaulniers

Right, but you're still only ever using one linker per build, correct?

Correct. LDFLAGS_GOLD makes it move convenient to add gold specific flags without explicit $(ld-name) checks everywhere, but I'm fine with removing it in v2.

Sami

#4 lore raw

PATCH 2/7 kbuild: add ld-if-name-version and linker-specific macros

In reply to Sami Tolvanen

Add macros for testing both linker name and version.

---
 scripts/Kbuild.include | 12 ++++++++++++
 1 file changed, 12 insertions(+)
scripts/Kbuild.include +12 -0
index a7c7843c2cf1..5d286d69e8dc 100644
@@ -289,6 +289,18 @@ ld-version = $(call shell-cached,$(LD) --version | $(srctree)/scripts/ld-version
 # Usage:  $(call ld-ifversion, -ge, 22252, y)
 ld-ifversion = $(shell [ $(ld-version) $(1) $(2) ] && echo $(3) || echo $(4))
 
+# ld-if-name-version
+# Usage:  $(call ld-if-name-version, gold, -ge, 112000000, y)
+ld-if-name-version = $(shell [ $(ld-name) == $(1) ] && [ $(ld-version) $(2) $(3) ] && echo $(4) || echo $(5))
+
+# bfd-ifversion
+# Usage:  $(call bfd-ifversion, -ge, 227000000, y)
+bfd-ifversion = $(call ld-if-name-version, bfd, $(1), $(2), $(3), $(4))
+
+# gold-ifversion
+# Usage:  $(call gold-ifversion, -ge, 112000000, y)
+gold-ifversion = $(call ld-if-name-version, gold, $(1), $(2), $(3), $(4))
+
 ######
 
 ###
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog
#5 lore raw

PATCH 3/7 kbuild: fix LD_DEAD_CODE_DATA_ELIMINATION with GNU gold

In reply to Sami Tolvanen

Don't remove .head.text or .exitcall.exit when linking with --gc-sections, and include .init.text.* in .init.text and .init.rodata.* in .init.rodata.

---
 include/asm-generic/vmlinux.lds.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
include/asm-generic/vmlinux.lds.h +4 -4
index ee8b707d9fa9..eb4199c12bd2 100644
@@ -515,7 +515,7 @@
 		VMLINUX_SYMBOL(__softirqentry_text_end) = .;
 
 /* Section used for early init (in .S files) */
-#define HEAD_TEXT  *(.head.text)
+#define HEAD_TEXT  KEEP(*(.head.text))
 
 #define HEAD_TEXT_SECTION							\
 	.head.text : AT(ADDR(.head.text) - LOAD_OFFSET) {		\
@@ -560,7 +560,7 @@
 	MEM_DISCARD(init.data)						\
 	KERNEL_CTORS()							\
 	MCOUNT_REC()							\
-	*(.init.rodata)							\
+	*(.init.rodata .init.rodata.*)					\
 	FTRACE_EVENTS()							\
 	TRACE_SYSCALLS()						\
 	KPROBE_BLACKLIST()						\
@@ -579,7 +579,7 @@
 	EARLYCON_TABLE()
 
 #define INIT_TEXT							\
-	*(.init.text)							\
+	*(.init.text .init.text.*)					\
 	*(.text.startup)						\
 	MEM_DISCARD(init.text)
 
@@ -596,7 +596,7 @@
 	MEM_DISCARD(exit.text)
 
 #define EXIT_CALL							\
-	*(.exitcall.exit)
+	KEEP(*(.exitcall.exit))
 
 /*
  * bss (Block Started by Symbol) - uninitialized data
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog
Reviewed-by on v1 3/7
#6 lore raw

Re: [PATCH 3/7] kbuild: fix LD_DEAD_CODE_DATA_ELIMINATION with GNU gold

Quoted 4 lines · On Wed, 29 Nov 2017 15:44:38 -0800 Sami Tolvanen <[email protected]>…

Don't remove .head.text or .exitcall.exit when linking with --gc-sections, and include .init.text.* in .init.text and .init.rodata.* in .init.rodata.

Fine by me, if you consider my other comments.

#7 lore raw

PATCH 4/7 arm64: fix -m for GNU gold

In reply to Sami Tolvanen

GNU gold supports different emulations than bfd. Use aarch64_elf64_*_vec instead of aarch64linux.

---
 arch/arm64/Makefile | 8 ++++++++
 1 file changed, 8 insertions(+)
arch/arm64/Makefile +8 -0
index b35788c909f1..82a0df6e865e 100644
@@ -64,14 +64,22 @@ KBUILD_CPPFLAGS	+= -mbig-endian
 CHECKFLAGS	+= -D__AARCH64EB__
 AS		+= -EB
 LD		+= -EB
+ifeq ($(ld-name),gold)
+LDFLAGS		+= -maarch64_elf64_be_vec
+else
 LDFLAGS		+= -maarch64linuxb
+endif
 UTS_MACHINE	:= aarch64_be
 else
 KBUILD_CPPFLAGS	+= -mlittle-endian
 CHECKFLAGS	+= -D__AARCH64EL__
 AS		+= -EL
 LD		+= -EL
+ifeq ($(ld-name),gold)
+LDFLAGS		+= -maarch64_elf64_le_vec
+else
 LDFLAGS		+= -maarch64linux
+endif
 UTS_MACHINE	:= aarch64
 endif
 
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog
#8 lore raw

PATCH 5/7 arm64: keep .altinstructions and .altinstr_replacement

In reply to Sami Tolvanen

Make sure the linker doesn't remove .altinstructions or .altinstr_replacement when CONFIG_LD_DEAD_CODE_DATA_ELIMINATION is enabled.

---
 arch/arm64/kernel/vmlinux.lds.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/kernel/vmlinux.lds.S +2 -2
index 7da3e5c366a0..15479995869c 100644
@@ -138,11 +138,11 @@ SECTIONS
 	. = ALIGN(4);
 	.altinstructions : {
 		__alt_instructions = .;
-		*(.altinstructions)
+		KEEP(*(.altinstructions))
 		__alt_instructions_end = .;
 	}
 	.altinstr_replacement : {
-		*(.altinstr_replacement)
+		KEEP(*(.altinstr_replacement))
 	}
 
 	. = ALIGN(PAGE_SIZE);
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog
#9 lore raw

Re: [PATCH 5/7] arm64: keep .altinstructions and .altinstr_replacement

Quoted 3 lines · Sami Tolvanen

Make sure the linker doesn't remove .altinstructions or .altinstr_replacement when CONFIG_LD_DEAD_CODE_DATA_ELIMINATION is enabled.

This sounds like a bug in the original implementation of CONFIG_LD_DEAD_CODE_DATA_ELIMINATION? If so, this can likely get merged regardless of the rest of the patchset, ie. gold support.

#10 lore raw

Re: [PATCH 5/7] arm64: keep .altinstructions and .altinstr_replacement

Quoted 8 lines · On Wed, 29 Nov 2017 15:57:53 -0800 Nick Desaulniers <[email protected]>…
Quoted 3 lines · Sami Tolvanen

Make sure the linker doesn't remove .altinstructions or .altinstr_replacement when CONFIG_LD_DEAD_CODE_DATA_ELIMINATION is enabled.

This sounds like a bug in the original implementation of CONFIG_LD_DEAD_CODE_DATA_ELIMINATION? If so, this can likely get merged regardless of the rest of the patchset, ie. gold support.

Yes, also patch 3/7 probably (thanks for doing these, btw). The LD_DCDE option is actually been broken upstream thanks to lack of time (which is a known issue, this is why no arch enables it).

Basically it just needs a bit more effort to go through and ensure nothing is discarded incorrectly, and all new sections are placed into output sections, before each arch is enabled.

(Comparing readelf -S before/after is a way to spot bugs.)

So yes please if it's not too much trouble, could you remove the "gold" name from the generic patch and put it at the front of the series with this arm64 patch. Possibly then you could also do a 3rd patch to allow arm64 to select it if it's working with gcc?

Thanks,
Nick

#11 lore raw

Re: [PATCH 5/7] arm64: keep .altinstructions and .altinstr_replacement

Quoted 1 line · Nicholas Piggin

(Comparing readelf -S before/after is a way to spot bugs.)

Do you have a script that can be used to diff 2 readelf -S, look for missing references, and report an error? Might be easier to rerun that every so often and see what's missing.

#12 lore raw

Re: [PATCH 5/7] arm64: keep .altinstructions and .altinstr_replacement

Quoted 6 lines · On Thu, 30 Nov 2017 09:00:35 -0800 Nick Desaulniers <[email protected]>…
Quoted 1 line · Nicholas Piggin

(Comparing readelf -S before/after is a way to spot bugs.)

Do you have a script that can be used to diff 2 readelf -S, look for missing references, and report an error? Might be easier to rerun that every so often and see what's missing.

I don't, I was just doing it by hand.

Thanks,
Nick

#13 lore raw

Re: [PATCH 5/7] arm64: keep .altinstructions and .altinstr_replacement

In reply to Nicholas Piggin
Quoted 3 lines · Nicholas Piggin

So yes please if it's not too much trouble, could you remove the "gold" name from the generic patch and put it at the front of the series with this arm64 patch.

Sure, I'll do this in v2.

Quoted 2 lines

Possibly then you could also do a 3rd patch to allow arm64 to select it if it's working with gcc?

These patches only fix the issues I ran into with clang and gold when testing on a single device. I feel like more testing would be needed before enabling this by default for arm64.

Sami

#14 lore raw

PATCH 6/7 arm64: explicitly pass --no-fix-cortex-a53-843419 to GNU gold

In reply to Sami Tolvanen

Some versions of GNU gold are known to produce broken code with --fix-cortex-a53-843419 as explained in this bug:

https://sourceware.org/bugzilla/show_bug.cgi?id=21491

If ARM64_ERRATUM_843419 is disabled and we're using GNU gold, pass --no-fix-cortex-a53-843419 to the linker to ensure the erratum fix is not used even if the linker is configured to enable it by default.

This change also adds a warning if the erratum fix is enabled and gold version <1.14 is used.

---
 arch/arm64/Makefile | 9 +++++++++
 1 file changed, 9 insertions(+)
arch/arm64/Makefile +9 -0
index 82a0df6e865e..81a12713f7af 100644
@@ -26,10 +26,19 @@ ifeq ($(CONFIG_ARM64_ERRATUM_843419),y)
   ifeq ($(call ld-option, --fix-cortex-a53-843419),)
 $(warning ld does not support --fix-cortex-a53-843419; kernel may be susceptible to erratum)
   else
+    ifeq ($(call gold-ifversion, -lt, 114000000, y), y)
+$(warning This version of GNU gold may generate incorrect code with --fix-cortex-a53-843419;\
+	see https://sourceware.org/bugzilla/show_bug.cgi?id=21491)
+    endif
 LDFLAGS_vmlinux	+= --fix-cortex-a53-843419
   endif
 endif
 
+ifeq ($(CONFIG_ARM64_ERRATUM_843419),)
+# https://sourceware.org/bugzilla/show_bug.cgi?id=21491
+LDFLAGS_GOLD	+= --no-fix-cortex-a53-843419
+endif
+
 KBUILD_DEFCONFIG := defconfig
 
 # Check for binutils support for specific extensions
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog
#15 lore raw

Re: [PATCH 6/7] arm64: explicitly pass --no-fix-cortex-a53-843419 to GNU gold

Quoted 7 lines · Sami Tolvanen
arch/arm64/Makefile +3 -0
@@ -26,10 +26,19 @@ ifeq ($(CONFIG_ARM64_ERRATUM_843419),y)
   ifeq ($(call ld-option, --fix-cortex-a53-843419),)
 $(warning ld does not support --fix-cortex-a53-843419; kernel may be susceptible to erratum)
   else
+    ifeq ($(call gold-ifversion, -lt, 114000000, y), y)
+$(warning This version of GNU gold may generate incorrect code with --fix-cortex-a53-843419;\
+       see https://sourceware.org/bugzilla/show_bug.cgi?id=21491)

arch/arm64/Makefile ifeq ($(CONFIG_ARM64_ERRATUM_843419),y) · line 41

Quoted 10 lines
arch/arm64/Makefile +6 -0
+    endif
 LDFLAGS_vmlinux        += --fix-cortex-a53-843419
   endif
 endif
 
+ifeq ($(CONFIG_ARM64_ERRATUM_843419),)
+# https://sourceware.org/bugzilla/show_bug.cgi?id=21491
+LDFLAGS_GOLD   += --no-fix-cortex-a53-843419
+endif
+

Rather than:

if CONFIG_ARM64_ERRATUM_843419 == y:
...
if CONFIG_ARM64_ERRATUM_843419 == '':
...

could this be:

if CONFIG_ARM64_ERRATUM_843419 == y:
...
else
...

?

#16 lore raw

Re: [PATCH 6/7] arm64: explicitly pass --no-fix-cortex-a53-843419 to GNU gold

Quoted 7 lines · Nick Desaulniers

Rather than:

if CONFIG_ARM64_ERRATUM_843419 == y:
...
if CONFIG_ARM64_ERRATUM_843419 == '':
...

Quoted 8 lines

could this be:

if CONFIG_ARM64_ERRATUM_843419 == y:
...
else
...

?

Sure. I'll clean this up in v2.

Sami

#17 lore raw

PATCH 7/7 arm64: add a workaround for GNU gold with ARM64_MODULE_PLTS

In reply to Sami Tolvanen

All current versions of GNU gold crash when linking kernel modules with ARM64_MODULE_PLTS due to a known bug:

https://sourceware.org/bugzilla/show_bug.cgi?id=14592

To work around the problem, this change removes NOLOAD from .plt and .init.plt.

---
 arch/arm64/kernel/module.lds | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/kernel/module.lds +2 -2
index f7c9781a9d48..eacb5c67f61e 100644
@@ -1,4 +1,4 @@
 SECTIONS {
-	.plt (NOLOAD) : { BYTE(0) }
-	.init.plt (NOLOAD) : { BYTE(0) }
+	.plt : { BYTE(0) }
+	.init.plt : { BYTE(0) }
 }
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog
Acked-by on v1 7/7
#18 lore raw

Re: [PATCH 7/7] arm64: add a workaround for GNU gold with ARM64_MODULE_PLTS

Quoted 9 lines · Sami Tolvanen

All current versions of GNU gold crash when linking kernel modules with ARM64_MODULE_PLTS due to a known bug:

https://sourceware.org/bugzilla/show_bug.cgi?id=14592

To work around the problem, this change removes NOLOAD from .plt and .init.plt.

Quoted 18 lines
---
 arch/arm64/kernel/module.lds | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/kernel/module.lds +2 -3
index f7c9781a9d48..eacb5c67f61e 100644
@@ -1,4 +1,4 @@
 SECTIONS {
-       .plt (NOLOAD) : { BYTE(0) }
-       .init.plt (NOLOAD) : { BYTE(0) }
+       .plt : { BYTE(0) }
+       .init.plt : { BYTE(0) }
 }
--

2.15.0.531.g2ccb3012c9-goog

#19 lore raw

v2 cover Add support for GNU gold

In reply to Sami Tolvanen

These patches add macros for detecting the linker name and version, and apply fixes and workarounds needed to link the arm64 kernel with GNU gold.

Changes since v1:
- moved LD_DEAD_CODE_DATA_ELIMINATION fixes to the beginning of the patch set and removed mentions of gold
- renamed ld-if-name-version to __ld-ifversion for consistency
- cleaned up the erratum changes in arch/arm64/Makefile

Sami Tolvanen (7):
kbuild: fix LD_DEAD_CODE_DATA_ELIMINATION
arm64: keep .altinstructions and .altinstr_replacement
kbuild: add ld-name macro
kbuild: add __ld-ifversion and linker-specific macros
arm64: fix -m for GNU gold
arm64: explicitly pass --no-fix-cortex-a53-843419 to GNU gold
arm64: add a workaround for GNU gold with ARM64_MODULE_PLTS

 arch/arm64/Makefile               | 17 +++++++++++++++++
 arch/arm64/kernel/module.lds      |  4 ++--
 arch/arm64/kernel/vmlinux.lds.S   |  4 ++--
 include/asm-generic/vmlinux.lds.h |  8 ++++----
 scripts/Kbuild.include            | 16 ++++++++++++++++
 5 files changed, 41 insertions(+), 8 deletions(-)
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog
#20 lore raw

PATCH v2 1/7 kbuild: fix LD_DEAD_CODE_DATA_ELIMINATION

Don't remove .head.text or .exitcall.exit when linking with --gc-sections, and include .init.text.* in .init.text and .init.rodata.* in .init.rodata.

---
 include/asm-generic/vmlinux.lds.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
include/asm-generic/vmlinux.lds.h +4 -4
index ee8b707d9fa9..eb4199c12bd2 100644
@@ -515,7 +515,7 @@
 		VMLINUX_SYMBOL(__softirqentry_text_end) = .;
 
 /* Section used for early init (in .S files) */
-#define HEAD_TEXT  *(.head.text)
+#define HEAD_TEXT  KEEP(*(.head.text))
 
 #define HEAD_TEXT_SECTION							\
 	.head.text : AT(ADDR(.head.text) - LOAD_OFFSET) {		\
@@ -560,7 +560,7 @@
 	MEM_DISCARD(init.data)						\
 	KERNEL_CTORS()							\
 	MCOUNT_REC()							\
-	*(.init.rodata)							\
+	*(.init.rodata .init.rodata.*)					\
 	FTRACE_EVENTS()							\
 	TRACE_SYSCALLS()						\
 	KPROBE_BLACKLIST()						\
@@ -579,7 +579,7 @@
 	EARLYCON_TABLE()
 
 #define INIT_TEXT							\
-	*(.init.text)							\
+	*(.init.text .init.text.*)					\
 	*(.text.startup)						\
 	MEM_DISCARD(init.text)
 
@@ -596,7 +596,7 @@
 	MEM_DISCARD(exit.text)
 
 #define EXIT_CALL							\
-	*(.exitcall.exit)
+	KEEP(*(.exitcall.exit))
 
 /*
  * bss (Block Started by Symbol) - uninitialized data
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog
#21 lore raw

PATCH v2 2/7 arm64: keep .altinstructions and .altinstr_replacement

In reply to Sami Tolvanen

Make sure the linker doesn't remove .altinstructions or .altinstr_replacement when CONFIG_LD_DEAD_CODE_DATA_ELIMINATION is enabled.

---
 arch/arm64/kernel/vmlinux.lds.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/kernel/vmlinux.lds.S +2 -2
index 7da3e5c366a0..15479995869c 100644
@@ -138,11 +138,11 @@ SECTIONS
 	. = ALIGN(4);
 	.altinstructions : {
 		__alt_instructions = .;
-		*(.altinstructions)
+		KEEP(*(.altinstructions))
 		__alt_instructions_end = .;
 	}
 	.altinstr_replacement : {
-		*(.altinstr_replacement)
+		KEEP(*(.altinstr_replacement))
 	}
 
 	. = ALIGN(PAGE_SIZE);
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog
#22 lore raw

PATCH v2 3/7 kbuild: add ld-name macro

In reply to Sami Tolvanen

GNU gold may require different flags than GNU ld. Add a macro for detecting the linker.

---
 scripts/Kbuild.include | 4 ++++
 1 file changed, 4 insertions(+)
scripts/Kbuild.include +4 -0
index eb2cf2780f6e..899863e4cd05 100644
@@ -273,6 +273,10 @@ ld-option = $(call try-run-cached,\
 # Important: no spaces around options
 ar-option = $(call try-run-cached, $(AR) rc$(1) "$$TMP",$(1),$(2))
 
+# ld-name
+# Expands to either bfd or gold
+ld-name = $(shell $(LD) -v 2>&1 | grep -q "GNU gold" && echo gold || echo bfd)
+
 # ld-version
 # Note this is mainly for HJ Lu's 3 number binutil versions
 ld-version = $(call shell-cached,$(LD) --version | $(srctree)/scripts/ld-version.sh)
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog
#23 lore raw

PATCH v2 4/7 kbuild: add __ld-ifversion and linker-specific macros

In reply to Sami Tolvanen

Add macros for testing both linker name and version.

---
 scripts/Kbuild.include | 12 ++++++++++++
 1 file changed, 12 insertions(+)
scripts/Kbuild.include +12 -0
index 899863e4cd05..2991b463b4ce 100644
@@ -285,6 +285,18 @@ ld-version = $(call shell-cached,$(LD) --version | $(srctree)/scripts/ld-version
 # Usage:  $(call ld-ifversion, -ge, 22252, y)
 ld-ifversion = $(shell [ $(ld-version) $(1) $(2) ] && echo $(3) || echo $(4))
 
+# __ld-ifversion
+# Usage:  $(call __ld-ifversion, gold, -ge, 112000000, y)
+__ld-ifversion = $(shell [ $(ld-name) == $(1) ] && [ $(ld-version) $(2) $(3) ] && echo $(4) || echo $(5))
+
+# bfd-ifversion
+# Usage:  $(call bfd-ifversion, -ge, 227000000, y)
+bfd-ifversion = $(call __ld-ifversion, bfd, $(1), $(2), $(3), $(4))
+
+# gold-ifversion
+# Usage:  $(call gold-ifversion, -ge, 112000000, y)
+gold-ifversion = $(call __ld-ifversion, gold, $(1), $(2), $(3), $(4))
+
 ######
 
 ###
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog
#24 lore raw

PATCH v2 5/7 arm64: fix -m for GNU gold

In reply to Sami Tolvanen

GNU gold supports different emulations than bfd. Use aarch64_elf64_*_vec instead of aarch64linux.

---
 arch/arm64/Makefile | 8 ++++++++
 1 file changed, 8 insertions(+)
arch/arm64/Makefile +8 -0
index b35788c909f1..82a0df6e865e 100644
@@ -64,14 +64,22 @@ KBUILD_CPPFLAGS	+= -mbig-endian
 CHECKFLAGS	+= -D__AARCH64EB__
 AS		+= -EB
 LD		+= -EB
+ifeq ($(ld-name),gold)
+LDFLAGS		+= -maarch64_elf64_be_vec
+else
 LDFLAGS		+= -maarch64linuxb
+endif
 UTS_MACHINE	:= aarch64_be
 else
 KBUILD_CPPFLAGS	+= -mlittle-endian
 CHECKFLAGS	+= -D__AARCH64EL__
 AS		+= -EL
 LD		+= -EL
+ifeq ($(ld-name),gold)
+LDFLAGS		+= -maarch64_elf64_le_vec
+else
 LDFLAGS		+= -maarch64linux
+endif
 UTS_MACHINE	:= aarch64
 endif
 
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog
#25 lore raw

PATCH v2 6/7 arm64: explicitly pass --no-fix-cortex-a53-843419 to GNU gold

In reply to Sami Tolvanen

Some versions of GNU gold are known to produce broken code with --fix-cortex-a53-843419 as explained in this bug:

https://sourceware.org/bugzilla/show_bug.cgi?id=21491

If ARM64_ERRATUM_843419 is disabled and we're using GNU gold, pass --no-fix-cortex-a53-843419 to the linker to ensure the erratum fix is not used even if the linker is configured to enable it by default.

This change also adds a warning if the erratum fix is enabled and gold version <1.14 is used.

---
 arch/arm64/Makefile | 9 +++++++++
 1 file changed, 9 insertions(+)
arch/arm64/Makefile +9 -0
index 82a0df6e865e..68eed687e468 100644
@@ -26,8 +26,17 @@ ifeq ($(CONFIG_ARM64_ERRATUM_843419),y)
   ifeq ($(call ld-option, --fix-cortex-a53-843419),)
 $(warning ld does not support --fix-cortex-a53-843419; kernel may be susceptible to erratum)
   else
+    ifeq ($(call gold-ifversion, -lt, 114000000, y), y)
+$(warning This version of GNU gold may generate incorrect code with --fix-cortex-a53-843419;\
+	see https://sourceware.org/bugzilla/show_bug.cgi?id=21491)
+    endif
 LDFLAGS_vmlinux	+= --fix-cortex-a53-843419
   endif
+else
+  ifeq ($(ld-name),gold)
+# Pass --no-fix-cortex-a53-843419 to ensure the erratum fix is disabled
+LDFLAGS	+= --no-fix-cortex-a53-843419
+  endif
 endif
 
 KBUILD_DEFCONFIG := defconfig
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog
#27 lore raw

PATCH v2 7/7 arm64: add a workaround for GNU gold with ARM64_MODULE_PLTS

In reply to Sami Tolvanen

All current versions of GNU gold crash when linking kernel modules with ARM64_MODULE_PLTS due to a known bug:

https://sourceware.org/bugzilla/show_bug.cgi?id=14592

To work around the problem, this change removes NOLOAD from .plt and .init.plt.

---
 arch/arm64/kernel/module.lds | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/kernel/module.lds +2 -2
index f7c9781a9d48..eacb5c67f61e 100644
@@ -1,4 +1,4 @@
 SECTIONS {
-	.plt (NOLOAD) : { BYTE(0) }
-	.init.plt (NOLOAD) : { BYTE(0) }
+	.plt : { BYTE(0) }
+	.init.plt : { BYTE(0) }
 }
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog