[PATCH 1/2] kbuild: add CONFIG_LD_IS_LLD

2 views
Skip to first unread message

Nathan Chancellor

unread,
Apr 19, 2020, 2:04:58 PM4/19/20
to Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek, Nathan Chancellor
From: Sami Tolvanen <samito...@google.com>

Similarly to the CC_IS_CLANG config, add LD_IS_LLD to avoid GNU ld
specific logic such as ld-version or ld-ifversion and gain the
ability to select potential features that depend on the linker at
configuration time such as LTO.

Signed-off-by: Sami Tolvanen <samito...@google.com>
[nc: Reword commit message]
Signed-off-by: Nathan Chancellor <natecha...@gmail.com>
---

Sami, please scream if you are unhappy with how I worded this commit.

init/Kconfig | 3 +++
1 file changed, 3 insertions(+)

diff --git a/init/Kconfig b/init/Kconfig
index 9e22ee8fbd75..c15ee42b8272 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -23,6 +23,9 @@ config LD_VERSION
config CC_IS_CLANG
def_bool $(success,$(CC) --version | head -n 1 | grep -q clang)

+config LD_IS_LLD
+ def_bool $(success,$(LD) -v | head -n 1 | grep -q LLD)
+
config CLANG_VERSION
int
default $(shell,$(srctree)/scripts/clang-version.sh $(CC))

base-commit: 50cc09c18985eacbbd666acfd7be2391394733f5
--
2.26.1

Nathan Chancellor

unread,
Apr 19, 2020, 2:05:01 PM4/19/20
to Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek, Nathan Chancellor
Currently, when linking with ld.lld, this warning pops up:

arch/mips/vdso/Makefile:70: MIPS VDSO requires binutils >= 2.25

ld-ifversion calls ld-version, which calls scripts/ld-version.sh, which
is specific to GNU ld. ld.lld has a completely different versioning
scheme (as it follows LLVM's versioning) and it does not have the issue
mentioned in the comment above this block so it should not be subjected
to this check.

With this patch, the VDSO successfully links and shows P_MIPS_PC32 in
vgettimeofday.o.

$ llvm-objdump -Dr arch/mips/vdso/vgettimeofday.o | grep R_MIPS_PC32
00000024: R_MIPS_PC32 _start
000000b0: R_MIPS_PC32 _start
000002bc: R_MIPS_PC32 _start
0000036c: R_MIPS_PC32 _start
00000468: R_MIPS_PC32 _start

Link: https://github.com/ClangBuiltLinux/linux/issues/785
Link: https://github.com/llvm/llvm-project/commit/e364e2e9ce50c12eb2bf093560e1a1a8544d455a
Reported-by: Dmitry Golovin <di...@golovin.in>
Signed-off-by: Nathan Chancellor <natecha...@gmail.com>
---
arch/mips/vdso/Makefile | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
index d7fe8408603e..f99e583d14a1 100644
--- a/arch/mips/vdso/Makefile
+++ b/arch/mips/vdso/Makefile
@@ -65,9 +65,11 @@ DISABLE_VDSO := n
# the comments on that file.
#
ifndef CONFIG_CPU_MIPSR6
- ifeq ($(call ld-ifversion, -lt, 225000000, y),y)
- $(warning MIPS VDSO requires binutils >= 2.25)
- DISABLE_VDSO := y
+ ifndef CONFIG_LD_IS_LLD
+ ifeq ($(call ld-ifversion, -lt, 225000000, y),y)
+ $(warning MIPS VDSO requires binutils >= 2.25)
+ DISABLE_VDSO := y
+ endif
endif
endif

--
2.26.1

Nathan Chancellor

unread,
Apr 19, 2020, 2:17:18 PM4/19/20
to Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek
Hmmm, I still see this warning when first runing make <config>... I
assume because this Makefile gets parsed before Kconfig runs.

Perhaps it would be better to check if ld-version is 0 (since that means
we are not using GNU ld):

ifneq ($(call ld-ifversion, -eq, 0, y),y)

I am open to suggestions though.

Cheers,
Nathan

Masahiro Yamada

unread,
Apr 19, 2020, 3:33:11 PM4/19/20
to Nathan Chancellor, Thomas Bogendoerfer, linux...@vger.kernel.org, Linux Kernel Mailing List, clang-built-linux, Linux Kbuild mailing list, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek
I do not see the warning for 'make <config>'.

Could you tell me how to reproduce it?


For cleaning, indeed, i see the warning.


$ make ARCH=mips LLVM=1 clean
arch/mips/vdso/Makefile:70: MIPS VDSO requires binutils >= 2.25








>
> Perhaps it would be better to check if ld-version is 0 (since that means
> we are not using GNU ld):
>
> ifneq ($(call ld-ifversion, -eq, 0, y),y)
>
> I am open to suggestions though.
>
> Cheers,
> Nathan
>
> --
> You received this message because you are subscribed to the Google Groups "Clang Built Linux" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to clang-built-li...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/clang-built-linux/20200419181715.GA36234%40ubuntu-s3-xlarge-x86.



--
Best Regards
Masahiro Yamada

Nathan Chancellor

unread,
Apr 19, 2020, 4:06:01 PM4/19/20
to Masahiro Yamada, Thomas Bogendoerfer, linux...@vger.kernel.org, Linux Kernel Mailing List, clang-built-linux, Linux Kbuild mailing list, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek
Hi Masahiro,
This is enough. I think I figured out how to avoid it, I'll be sending
out v2 shortly, I'd appreciate any comments that you have.

> >
> > Perhaps it would be better to check if ld-version is 0 (since that means
> > we are not using GNU ld):
> >
> > ifneq ($(call ld-ifversion, -eq, 0, y),y)
> >
> > I am open to suggestions though.
> >
> > Cheers,
> > Nathan
> >
> > --
> > You received this message because you are subscribed to the Google Groups "Clang Built Linux" group.
> > To unsubscribe from this group and stop receiving emails from it, send an email to clang-built-li...@googlegroups.com.
> > To view this discussion on the web visit https://groups.google.com/d/msgid/clang-built-linux/20200419181715.GA36234%40ubuntu-s3-xlarge-x86.
>
>
>
> --
> Best Regards
> Masahiro Yamada
>

Cheers,
Nathan

Nathan Chancellor

unread,
Apr 19, 2020, 4:21:43 PM4/19/20
to Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek, Nathan Chancellor
From: Sami Tolvanen <samito...@google.com>

Similarly to the CC_IS_CLANG config, add LD_IS_LLD to avoid GNU ld
specific logic such as ld-version or ld-ifversion and gain the
ability to select potential features that depend on the linker at
configuration time such as LTO.

Signed-off-by: Sami Tolvanen <samito...@google.com>
[nc: Reword commit message]
Signed-off-by: Nathan Chancellor <natecha...@gmail.com>
---

v1 -> v2:

* No changes.

Nathan Chancellor

unread,
Apr 19, 2020, 4:21:52 PM4/19/20
to Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek, Nathan Chancellor
After commit 9553d16fa671 ("init/kconfig: Add LD_VERSION Kconfig"), we
have access to GNU ld's version at configuration time. As a result, we
can make it clearer under what configuration circumstances the MIPS VDSO
needs to be disabled.

This is a prerequisite for getting rid of the MIPS VDSO binutils
warning and linking the VDSO when LD is ld.lld. Wrapping the call to
ld-ifversion with CONFIG_LD_IS_LLD does not work because the config
values are wiped away during 'make clean'.

Signed-off-by: Nathan Chancellor <natecha...@gmail.com>
---

v1 -> v2:

* New patch.

arch/mips/Kconfig | 2 ++
arch/mips/vdso/Kconfig | 18 ++++++++++++++++++
arch/mips/vdso/Makefile | 30 ++----------------------------
arch/mips/vdso/vdso.lds.S | 2 +-
4 files changed, 23 insertions(+), 29 deletions(-)
create mode 100644 arch/mips/vdso/Kconfig

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 690718b3701a..45220e4b8a65 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -3275,3 +3275,5 @@ endmenu
source "drivers/firmware/Kconfig"

source "arch/mips/kvm/Kconfig"
+
+source "arch/mips/vdso/Kconfig"
diff --git a/arch/mips/vdso/Kconfig b/arch/mips/vdso/Kconfig
new file mode 100644
index 000000000000..36a52158d849
--- /dev/null
+++ b/arch/mips/vdso/Kconfig
@@ -0,0 +1,18 @@
+# For the pre-R6 code in arch/mips/vdso/vdso.h for locating
+# the base address of VDSO, the linker will emit a R_MIPS_PC32
+# relocation in binutils > 2.25 but it will fail with older versions
+# because that relocation is not supported for that symbol. As a result
+# of which we are forced to disable the VDSO symbols when building
+# with < 2.25 binutils on pre-R6 kernels. For more references on why we
+# can't use other methods to get the base address of VDSO please refer to
+# the comments on that file.
+#
+# GCC (at least up to version 9.2) appears to emit function calls that make use
+# of the GOT when targeting microMIPS, which we can't use in the VDSO due to
+# the lack of relocations. As such, we disable the VDSO for microMIPS builds.
+
+config MIPS_LD_CAN_LINK_VDSO
+ def_bool LD_VERSION >= 225000000
+
+config MIPS_DISABLE_VDSO
+ def_bool CPU_MICROMIPS || (!CPU_MIPSR6 && !MIPS_LD_CAN_LINK_VDSO)
diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
index d7fe8408603e..92b53d1df42c 100644
--- a/arch/mips/vdso/Makefile
+++ b/arch/mips/vdso/Makefile
@@ -52,37 +52,11 @@ endif

CFLAGS_REMOVE_vgettimeofday.o = -pg

-DISABLE_VDSO := n
-
-#
-# For the pre-R6 code in arch/mips/vdso/vdso.h for locating
-# the base address of VDSO, the linker will emit a R_MIPS_PC32
-# relocation in binutils > 2.25 but it will fail with older versions
-# because that relocation is not supported for that symbol. As a result
-# of which we are forced to disable the VDSO symbols when building
-# with < 2.25 binutils on pre-R6 kernels. For more references on why we
-# can't use other methods to get the base address of VDSO please refer to
-# the comments on that file.
-#
-ifndef CONFIG_CPU_MIPSR6
- ifeq ($(call ld-ifversion, -lt, 225000000, y),y)
+ifdef CONFIG_MIPS_DISABLE_VDSO
+ ifndef CONFIG_MIPS_LD_CAN_LINK_VDSO
$(warning MIPS VDSO requires binutils >= 2.25)
- DISABLE_VDSO := y
endif
-endif
-
-#
-# GCC (at least up to version 9.2) appears to emit function calls that make use
-# of the GOT when targeting microMIPS, which we can't use in the VDSO due to
-# the lack of relocations. As such, we disable the VDSO for microMIPS builds.
-#
-ifdef CONFIG_CPU_MICROMIPS
- DISABLE_VDSO := y
-endif
-
-ifeq ($(DISABLE_VDSO),y)
obj-vdso-y := $(filter-out vgettimeofday.o, $(obj-vdso-y))
- ccflags-vdso += -DDISABLE_MIPS_VDSO
endif

# VDSO linker flags.
diff --git a/arch/mips/vdso/vdso.lds.S b/arch/mips/vdso/vdso.lds.S
index da4627430aba..ffcb5fc12708 100644
--- a/arch/mips/vdso/vdso.lds.S
+++ b/arch/mips/vdso/vdso.lds.S
@@ -91,7 +91,7 @@ PHDRS
VERSION
{
LINUX_2.6 {
-#ifndef DISABLE_MIPS_VDSO
+#ifndef CONFIG_DISABLE_MIPS_VDSO
global:
__vdso_clock_gettime;
__vdso_gettimeofday;
--
2.26.1

Nathan Chancellor

unread,
Apr 19, 2020, 4:21:53 PM4/19/20
to Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek, Nathan Chancellor
Currently, when linking with ld.lld, this warning pops up:

arch/mips/vdso/Makefile:70: MIPS VDSO requires binutils >= 2.25

CONFIG_LD_VERSION is set with scripts/ld-version.sh, which is specific
to GNU ld. It returns 0 for ld.lld so CONFIG_MIPS_LD_CAN_LINK_VDSO does
not set.

ld.lld has a completely different versioning scheme (as it follows
LLVM's versioning) and it does not have the issue mentioned in the
comment block so it should be allowed to link the VDSO.

With this patch, the VDSO successfully links and shows P_MIPS_PC32 in
vgettimeofday.o.

$ llvm-objdump -Dr arch/mips/vdso/vgettimeofday.o | grep R_MIPS_PC32
00000024: R_MIPS_PC32 _start
000000b0: R_MIPS_PC32 _start
000002bc: R_MIPS_PC32 _start
0000036c: R_MIPS_PC32 _start
00000468: R_MIPS_PC32 _start

Link: https://github.com/ClangBuiltLinux/linux/issues/785
Link: https://github.com/llvm/llvm-project/commit/e364e2e9ce50c12eb2bf093560e1a1a8544d455a
Reported-by: Dmitry Golovin <di...@golovin.in>
Signed-off-by: Nathan Chancellor <natecha...@gmail.com>
---

v1 -> v2:

* Move into Kconfig so that the warning does not happen.

arch/mips/vdso/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/vdso/Kconfig b/arch/mips/vdso/Kconfig
index 36a52158d849..7aec721398d5 100644
--- a/arch/mips/vdso/Kconfig
+++ b/arch/mips/vdso/Kconfig
@@ -12,7 +12,7 @@
# the lack of relocations. As such, we disable the VDSO for microMIPS builds.

config MIPS_LD_CAN_LINK_VDSO
- def_bool LD_VERSION >= 225000000
+ def_bool LD_VERSION >= 225000000 || LD_IS_LLD

config MIPS_DISABLE_VDSO
def_bool CPU_MICROMIPS || (!CPU_MIPSR6 && !MIPS_LD_CAN_LINK_VDSO)
--
2.26.1

Sedat Dilek

unread,
Apr 20, 2020, 5:54:08 AM4/20/20
to Nathan Chancellor, Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, Clang-Built-Linux ML, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin
...
> --- /dev/null
> +++ b/arch/mips/vdso/Kconfig
...
> +config MIPS_DISABLE_VDSO
> + def_bool CPU_MICROMIPS || (!CPU_MIPSR6 && !MIPS_LD_CAN_LINK_VDSO)
...
> diff --git a/arch/mips/vdso/vdso.lds.S b/arch/mips/vdso/vdso.lds.S
...
> --- a/arch/mips/vdso/vdso.lds.S
> +++ b/arch/mips/vdso/vdso.lds.S
...
> -#ifndef DISABLE_MIPS_VDSO
> +#ifndef CONFIG_DISABLE_MIPS_VDSO

Should be s/CONFIG_DISABLE_MIPS_VDSO/CONFIG_MIPS_DISABLE_VDSO ?

- Sedat -

Nathan Chancellor

unread,
Apr 20, 2020, 10:42:59 PM4/20/20
to Sedat Dilek, Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, Clang-Built-Linux ML, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin
Ugh yes, thank you much for pointing it out.

I'll send a v3 once I get further feedback on the series.

Cheers!
Nathan

Masahiro Yamada

unread,
Apr 23, 2020, 10:39:30 AM4/23/20
to Nathan Chancellor, Thomas Bogendoerfer, linux...@vger.kernel.org, Linux Kernel Mailing List, clang-built-linux, Linux Kbuild mailing list, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek
On Mon, Apr 20, 2020 at 5:21 AM Nathan Chancellor
<natecha...@gmail.com> wrote:
>
> From: Sami Tolvanen <samito...@google.com>
>
> Similarly to the CC_IS_CLANG config, add LD_IS_LLD to avoid GNU ld
> specific logic such as ld-version or ld-ifversion and gain the
> ability to select potential features that depend on the linker at
> configuration time such as LTO.
>
> Signed-off-by: Sami Tolvanen <samito...@google.com>
> [nc: Reword commit message]
> Signed-off-by: Nathan Chancellor <natecha...@gmail.com>
> ---


Acked-by: Masahiro Yamada <masa...@kernel.org>

Masahiro Yamada

unread,
Apr 23, 2020, 10:42:58 AM4/23/20
to Nathan Chancellor, Sedat Dilek, Thomas Bogendoerfer, linux...@vger.kernel.org, Linux Kernel Mailing List, Clang-Built-Linux ML, Linux Kbuild mailing list, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin
I just wondered if we could raise the minimal binutils
version from 2.23 to 2.25, but it might be too aggressive...
I do not know.

Other than what Sedat pointed out, this looks good me.

Nathan Chancellor

unread,
Apr 23, 2020, 1:18:27 PM4/23/20
to Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek, Nathan Chancellor
From: Sami Tolvanen <samito...@google.com>

Similarly to the CC_IS_CLANG config, add LD_IS_LLD to avoid GNU ld
specific logic such as ld-version or ld-ifversion and gain the
ability to select potential features that depend on the linker at
configuration time such as LTO.

Signed-off-by: Sami Tolvanen <samito...@google.com>
Acked-by: Masahiro Yamada <masa...@kernel.org>
[nc: Reword commit message]
Signed-off-by: Nathan Chancellor <natecha...@gmail.com>
---

v2 -> v3:

* Add Masahiro's ack.

v1 -> v2:

* No changes.

Sami, please scream if you are unhappy with how I worded this commit.

init/Kconfig | 3 +++
1 file changed, 3 insertions(+)

diff --git a/init/Kconfig b/init/Kconfig
index 9e22ee8fbd75e..c15ee42b82726 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -23,6 +23,9 @@ config LD_VERSION
config CC_IS_CLANG
def_bool $(success,$(CC) --version | head -n 1 | grep -q clang)

+config LD_IS_LLD
+ def_bool $(success,$(LD) -v | head -n 1 | grep -q LLD)
+
config CLANG_VERSION
int
default $(shell,$(srctree)/scripts/clang-version.sh $(CC))

base-commit: ae83d0b416db002fe95601e7f97f64b59514d936
--
2.26.2

Nathan Chancellor

unread,
Apr 23, 2020, 1:18:31 PM4/23/20
to Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek, Nathan Chancellor
After commit 9553d16fa671 ("init/kconfig: Add LD_VERSION Kconfig"), we
have access to GNU ld's version at configuration time. As a result, we
can make it clearer under what configuration circumstances the MIPS VDSO
needs to be disabled.

This is a prerequisite for getting rid of the MIPS VDSO binutils
warning and linking the VDSO when LD is ld.lld. Wrapping the call to
ld-ifversion with CONFIG_LD_IS_LLD does not work because the config
values are wiped away during 'make clean'.

Signed-off-by: Nathan Chancellor <natecha...@gmail.com>
---

v2 -> v3:

* Fix CONFIG macro in arch/mips/vdso/vdso.lds.S, thanks to Sedat for
catching it.

v1 -> v2:

* New patch.

arch/mips/Kconfig | 2 ++
arch/mips/vdso/Kconfig | 18 ++++++++++++++++++
arch/mips/vdso/Makefile | 30 ++----------------------------
arch/mips/vdso/vdso.lds.S | 2 +-
4 files changed, 23 insertions(+), 29 deletions(-)
create mode 100644 arch/mips/vdso/Kconfig

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 690718b3701af..45220e4b8a653 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -3275,3 +3275,5 @@ endmenu
source "drivers/firmware/Kconfig"

source "arch/mips/kvm/Kconfig"
+
+source "arch/mips/vdso/Kconfig"
diff --git a/arch/mips/vdso/Kconfig b/arch/mips/vdso/Kconfig
new file mode 100644
index 0000000000000..36a52158d849b
--- /dev/null
+++ b/arch/mips/vdso/Kconfig
@@ -0,0 +1,18 @@
+# For the pre-R6 code in arch/mips/vdso/vdso.h for locating
+# the base address of VDSO, the linker will emit a R_MIPS_PC32
+# relocation in binutils > 2.25 but it will fail with older versions
+# because that relocation is not supported for that symbol. As a result
+# of which we are forced to disable the VDSO symbols when building
+# with < 2.25 binutils on pre-R6 kernels. For more references on why we
+# can't use other methods to get the base address of VDSO please refer to
+# the comments on that file.
+#
+# GCC (at least up to version 9.2) appears to emit function calls that make use
+# of the GOT when targeting microMIPS, which we can't use in the VDSO due to
+# the lack of relocations. As such, we disable the VDSO for microMIPS builds.
+
+config MIPS_LD_CAN_LINK_VDSO
+ def_bool LD_VERSION >= 225000000
+
+config MIPS_DISABLE_VDSO
+ def_bool CPU_MICROMIPS || (!CPU_MIPSR6 && !MIPS_LD_CAN_LINK_VDSO)
diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
index d7fe8408603e8..92b53d1df42c3 100644
index da4627430aba4..d90b65724d78e 100644
--- a/arch/mips/vdso/vdso.lds.S
+++ b/arch/mips/vdso/vdso.lds.S
@@ -91,7 +91,7 @@ PHDRS
VERSION
{
LINUX_2.6 {
-#ifndef DISABLE_MIPS_VDSO
+#ifndef CONFIG_MIPS_DISABLE_VDSO
global:
__vdso_clock_gettime;
__vdso_gettimeofday;
--
2.26.2

Nathan Chancellor

unread,
Apr 23, 2020, 1:18:35 PM4/23/20
to Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek, Nathan Chancellor
Currently, the VDSO is being linked through $(CC). This does not match
how the rest of the kernel links objects, which is through the $(LD)
variable.

When clang is built in a default configuration, it first attempts to use
the target triple's default linker then the system's default linker,
unless told otherwise through -fuse-ld=... We do not use -fuse-ld=
because it can be brittle and we have support for invoking $(LD)
directly. See commit fe00e50b2db8c ("ARM: 8858/1: vdso: use $(LD)
instead of $(CC) to link VDSO") and commit 691efbedc60d2 ("arm64: vdso:
use $(LD) instead of $(CC) to link VDSO") for examples of doing this in
the VDSO.

Do the same thing here. Replace the custom linking logic with $(cmd_ld)
and ldflags-y so that $(LD) is respected.

Before this patch, LD=ld.lld did nothing:

$ llvm-readelf -p.comment arch/mips/vdso/vdso.so.dbg | sed 's/(.*//'
String dump of section '.comment':
[ 0] ClangBuiltLinux clang version 11.0.0

After this patch, it does:

$ llvm-readelf -p.comment arch/mips/vdso/vdso.so.dbg | sed 's/(.*//'
String dump of section '.comment':
[ 0] Linker: LLD 11.0.0
[ 62] ClangBuiltLinux clang version 11.0.0

Signed-off-by: Nathan Chancellor <natecha...@gmail.com>
---

v2 -> v3:

* New patch.

arch/mips/vdso/Makefile | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
index 92b53d1df42c3..da5db947072d5 100644
--- a/arch/mips/vdso/Makefile
+++ b/arch/mips/vdso/Makefile
@@ -60,10 +60,9 @@ ifdef CONFIG_MIPS_DISABLE_VDSO
endif

# VDSO linker flags.
-VDSO_LDFLAGS := \
- -Wl,-Bsymbolic -Wl,--no-undefined -Wl,-soname=linux-vdso.so.1 \
- $(addprefix -Wl$(comma),$(filter -E%,$(KBUILD_CFLAGS))) \
- -nostdlib -shared -Wl,--hash-style=sysv -Wl,--build-id
+ldflags-y := -Bsymbolic --no-undefined -soname=linux-vdso.so.1 \
+ $(filter -E%,$(KBUILD_CFLAGS)) -nostdlib -shared \
+ --hash-style=sysv --build-id -T

CFLAGS_REMOVE_vdso.o = -pg

@@ -82,11 +81,7 @@ quiet_cmd_vdso_mips_check = VDSOCHK $@
#

quiet_cmd_vdsold_and_vdso_check = LD $@
- cmd_vdsold_and_vdso_check = $(cmd_vdsold); $(cmd_vdso_check); $(cmd_vdso_mips_check)
-
-quiet_cmd_vdsold = VDSO $@
- cmd_vdsold = $(CC) $(c_flags) $(VDSO_LDFLAGS) \
- -Wl,-T $(filter %.lds,$^) $(filter %.o,$^) -o $@
+ cmd_vdsold_and_vdso_check = $(cmd_ld); $(cmd_vdso_check); $(cmd_vdso_mips_check)

quiet_cmd_vdsoas_o_S = AS $@
cmd_vdsoas_o_S = $(CC) $(a_flags) -c -o $@ $<
--
2.26.2

Nathan Chancellor

unread,
Apr 23, 2020, 1:18:36 PM4/23/20
to Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek, Nathan Chancellor
Currently, when linking with ld.lld, this warning pops up:

arch/mips/vdso/Makefile:70: MIPS VDSO requires binutils >= 2.25

CONFIG_LD_VERSION is set with scripts/ld-version.sh, which is specific
to GNU ld. It returns 0 for ld.lld so CONFIG_MIPS_LD_CAN_LINK_VDSO does
not set.

ld.lld has a completely different versioning scheme (as it follows
LLVM's versioning) and it does not have the issue mentioned in the
comment block so it should be allowed to link the VDSO.

With this patch, the VDSO successfully links and shows P_MIPS_PC32 in
vgettimeofday.o.

$ llvm-objdump -Dr arch/mips/vdso/vgettimeofday.o | grep R_MIPS_PC32
00000024: R_MIPS_PC32 _start
000000b0: R_MIPS_PC32 _start
000002bc: R_MIPS_PC32 _start
0000036c: R_MIPS_PC32 _start
00000468: R_MIPS_PC32 _start

---

v2 -> v3:

* No changes.

v1 -> v2:

* Move into Kconfig so that the warning does not happen.

arch/mips/vdso/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/vdso/Kconfig b/arch/mips/vdso/Kconfig
index 36a52158d849b..7aec721398d59 100644
--- a/arch/mips/vdso/Kconfig
+++ b/arch/mips/vdso/Kconfig
@@ -12,7 +12,7 @@
# the lack of relocations. As such, we disable the VDSO for microMIPS builds.

config MIPS_LD_CAN_LINK_VDSO
- def_bool LD_VERSION >= 225000000
+ def_bool LD_VERSION >= 225000000 || LD_IS_LLD

config MIPS_DISABLE_VDSO
def_bool CPU_MICROMIPS || (!CPU_MIPSR6 && !MIPS_LD_CAN_LINK_VDSO)
--
2.26.2

Thomas Bogendoerfer

unread,
Apr 26, 2020, 12:39:39 PM4/26/20
to Nathan Chancellor, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek
On Thu, Apr 23, 2020 at 10:18:06AM -0700, Nathan Chancellor wrote:
> Currently, the VDSO is being linked through $(CC). This does not match
> how the rest of the kernel links objects, which is through the $(LD)
> variable.

this causes build errors for me when (cross) compiling a big endian target:

target is little endian
mips64-linux-gnu-ld: arch/mips/vdso/elf.o: endianness incompatible with that of the selected emulation
mips64-linux-gnu-ld: failed to merge target specific data of file arch/mips/vdso/elf.o

Thomas.

--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]

Nathan Chancellor

unread,
Apr 26, 2020, 10:08:35 PM4/26/20
to Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek
On Sun, Apr 26, 2020 at 06:27:37PM +0200, Thomas Bogendoerfer wrote:
> On Thu, Apr 23, 2020 at 10:18:06AM -0700, Nathan Chancellor wrote:
> > Currently, the VDSO is being linked through $(CC). This does not match
> > how the rest of the kernel links objects, which is through the $(LD)
> > variable.
>
> this causes build errors for me when (cross) compiling a big endian target:
>
> target is little endian
> mips64-linux-gnu-ld: arch/mips/vdso/elf.o: endianness incompatible with that of the selected emulation
> mips64-linux-gnu-ld: failed to merge target specific data of file arch/mips/vdso/elf.o

Thanks for the report. I will look into it tomorrow and hopefully have a
v4 by then.

Cheers,
Nathan

Maciej W. Rozycki

unread,
Apr 27, 2020, 12:22:57 PM4/27/20
to Nathan Chancellor, Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek
On Sun, 26 Apr 2020, Nathan Chancellor wrote:

> > this causes build errors for me when (cross) compiling a big endian target:
> >
> > target is little endian
> > mips64-linux-gnu-ld: arch/mips/vdso/elf.o: endianness incompatible with that of the selected emulation
> > mips64-linux-gnu-ld: failed to merge target specific data of file arch/mips/vdso/elf.o
>
> Thanks for the report. I will look into it tomorrow and hopefully have a
> v4 by then.

Can you actually record in the change description what the difference in
the relevant link command is, as shown where `V=1' has been used with
`make' invocation?

Actually running `diff -bu' on the whole `V=1' build log obtained without
and with your proposed change applied and ensuring there are no unwanted
changes elsewhere will be a good measure of the correctness of your patch.
You may have to prepare to be patient and run with `-j1' to make sure any
`make' parallelism does not interfere with the order of commands printed.

Maciej

Nathan Chancellor

unread,
Apr 27, 2020, 7:24:09 PM4/27/20
to Maciej W. Rozycki, Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek
On Mon, Apr 27, 2020 at 05:22:53PM +0100, Maciej W. Rozycki wrote:
> On Sun, 26 Apr 2020, Nathan Chancellor wrote:
>
> > > this causes build errors for me when (cross) compiling a big endian target:
> > >
> > > target is little endian
> > > mips64-linux-gnu-ld: arch/mips/vdso/elf.o: endianness incompatible with that of the selected emulation
> > > mips64-linux-gnu-ld: failed to merge target specific data of file arch/mips/vdso/elf.o
> >
> > Thanks for the report. I will look into it tomorrow and hopefully have a
> > v4 by then.
>
> Can you actually record in the change description what the difference in
> the relevant link command is, as shown where `V=1' has been used with
> `make' invocation?

That will be rather unweildy to put in the commit message since
currently, $(CC) + $(KBUILD_CFLAGS) is being used but I can if it is
really desired. Otherwise, I can just put it where I put the changelog.

> Actually running `diff -bu' on the whole `V=1' build log obtained without
> and with your proposed change applied and ensuring there are no unwanted
> changes elsewhere will be a good measure of the correctness of your patch.
> You may have to prepare to be patient and run with `-j1' to make sure any
> `make' parallelism does not interfere with the order of commands printed.
>
> Maciej
>

Thanks for the input, I will take a look.

Cheers,
Nathan

Nathan Chancellor

unread,
Apr 27, 2020, 10:17:40 PM4/27/20
to Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek
On Sun, Apr 26, 2020 at 06:27:37PM +0200, Thomas Bogendoerfer wrote:
> On Thu, Apr 23, 2020 at 10:18:06AM -0700, Nathan Chancellor wrote:
> > Currently, the VDSO is being linked through $(CC). This does not match
> > how the rest of the kernel links objects, which is through the $(LD)
> > variable.
>
> this causes build errors for me when (cross) compiling a big endian target:
>
> target is little endian
> mips64-linux-gnu-ld: arch/mips/vdso/elf.o: endianness incompatible with that of the selected emulation
> mips64-linux-gnu-ld: failed to merge target specific data of file arch/mips/vdso/elf.o
>
> Thomas.
>

Thanks for reporting this, I figured it out. This is the solution that I
came up with, I'll send out a v4 tomorrow once I do some more testing.

Cheers,
Nathan

From 256e3b6c8fff7a66aa29961ebefc0fe653ec34b6 Mon Sep 17 00:00:00 2001
From: Nathan Chancellor <natecha...@gmail.com>
Date: Mon, 27 Apr 2020 17:02:55 -0700
Subject: [PATCH] MIPS: Unconditionally specify '-EL' or '-EB'

This was all done to work around a GCC bug that has been fixed after
4.2. The kernel requires GCC 4.6 or newer so remove all of these hacks
and just use the traditional flags.

$ mips64-linux-gcc --version | head -n1
mips64-linux-gcc (GCC) 4.6.3

$ mips64-linux-gcc -EB -dM -E -C -x c /dev/null | grep MIPSE
#define MIPSEB 1
#define __MIPSEB__ 1
#define _MIPSEB 1
#define __MIPSEB 1

$ mips64-linux-gcc -EL -dM -E -C -x c /dev/null | grep MIPSE
#define __MIPSEL__ 1
#define MIPSEL 1
#define _MIPSEL 1
#define __MIPSEL 1

This is necessary when converting the MIPS VDSO to use $(LD) instead of
$(CC) to link because the OUTPUT_FORMAT is defaulted to little endian
and only flips to big endian when -EB is set on the command line, which
is inherited from KBUILD_CFLAGS. Without this, we will see the following
error when compiling for big endian (64r2_defconfig):

$ make -j$(nproc) ARCH=mips CROSS_COMPILE=mips64-linux- \
64r2el_defconfig arch/mips/vdso/
...
mips64-linux-ld: arch/mips/vdso/elf.o: compiled for a big endian system
and target is little endian
mips64-linux-ld: arch/mips/vdso/elf.o: endianness incompatible with that
of the selected emulation
mips64-linux-ld: failed to merge target specific data of file
arch/mips/vdso/elf.o
...

Reported-by: Thomas Bogendoerfer <tsbo...@alpha.franken.de>
Signed-off-by: Nathan Chancellor <natecha...@gmail.com>
---
arch/mips/Makefile | 25 -------------------------
1 file changed, 25 deletions(-)

diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index e1c44aed81565..301efb90b51ed 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -116,33 +116,8 @@ endif

cflags-y += -ffreestanding

-#
-# We explicitly add the endianness specifier if needed, this allows
-# to compile kernels with a toolchain for the other endianness. We
-# carefully avoid to add it redundantly because gcc 3.3/3.4 complains
-# when fed the toolchain default!
-#
-# Certain gcc versions up to gcc 4.1.1 (probably 4.2-subversion as of
-# 2006-10-10 don't properly change the predefined symbols if -EB / -EL
-# are used, so we kludge that here. A bug has been filed at
-# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29413.
-#
-# clang doesn't suffer from these issues and our checks against -dumpmachine
-# don't work so well when cross compiling, since without providing --target
-# clang's output will be based upon the build machine. So for clang we simply
-# unconditionally specify -EB or -EL as appropriate.
-#
-ifdef CONFIG_CC_IS_CLANG
cflags-$(CONFIG_CPU_BIG_ENDIAN) += -EB
cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -EL
-else
-undef-all += -UMIPSEB -U_MIPSEB -U__MIPSEB -U__MIPSEB__
-undef-all += -UMIPSEL -U_MIPSEL -U__MIPSEL -U__MIPSEL__
-predef-be += -DMIPSEB -D_MIPSEB -D__MIPSEB -D__MIPSEB__
-predef-le += -DMIPSEL -D_MIPSEL -D__MIPSEL -D__MIPSEL__
-cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' && echo -EB $(undef-all) $(predef-be))
-cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL $(undef-all) $(predef-le))
-endif

cflags-$(CONFIG_SB1XXX_CORELIS) += $(call cc-option,-mno-sched-prolog) \
-fno-omit-frame-pointer
--
2.26.2

Nathan Chancellor

unread,
Apr 28, 2020, 6:14:40 PM4/28/20
to Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Fangrui Song, Sami Tolvanen, Dmitry Golovin, Sedat Dilek
Hi all,

This series allows ld.lld to properly and completely link the MIPS vDSO.

Patch 1 adds ld.lld support to Kconfig so that we can avoid certain
ld.bfd checks.

Patch 2 moves disabling of the VDSO to Kconfig. This allows us to avoid
a warning with LD=ld.lld during the clean phase, when we do not have
access to CONFIG_LD_IS_LLD.

Patch 3 prepares for the shift from $(CC) to $(LD) and is probably a
worthwhile change aside from this series because GCC 4.6 is the minimum
version allowed to build the kernel.

Patch 4 does the actual shift from $(CC) to $(LD) to link the VDSO.

Patch 5 allows LD=ld.lld to build the VDSO fully through Kconfig.

I have build tested 32r2_defconfig, 32r2el_defconfig, 64r2_defconfig,
and 64r2el_defconfig with GCC and 32r2el_defconfig and
malta_kvm_guest_defconfig with clang. There is a separate issue with the
64-bit configs (https://github.com/ClangBuiltLinux/linux/issues/884) and
ld.lld does not support the triple OUTPUT_FORMAT linker script macro so
32r2_defconfig errors out in a manner similar to GCC without patch 3:
https://github.com/llvm/llvm-project/blob/46a75436f811d0e6a2c76c669140a7e9471cd2a3/lld/ELF/ScriptParser.cpp#L430
TODO: File an LLVM bug upstream

Please let me know if there are any issues!

Cheers,
Nathan


Nathan Chancellor

unread,
Apr 28, 2020, 6:14:42 PM4/28/20
to Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Fangrui Song, Sami Tolvanen, Dmitry Golovin, Sedat Dilek, Nathan Chancellor
From: Sami Tolvanen <samito...@google.com>

Similarly to the CC_IS_CLANG config, add LD_IS_LLD to avoid GNU ld
specific logic such as ld-version or ld-ifversion and gain the
ability to select potential features that depend on the linker at
configuration time such as LTO.

Signed-off-by: Sami Tolvanen <samito...@google.com>
Acked-by: Masahiro Yamada <masa...@kernel.org>
[nc: Reword commit message]
Signed-off-by: Nathan Chancellor <natecha...@gmail.com>
---

v3 -> v4:

* No changes.

v2 -> v3:

* Add Masahiro's ack.

v1 -> v2:

* No changes.

Sami, please scream if you are unhappy with how I worded this commit.

init/Kconfig | 3 +++
1 file changed, 3 insertions(+)

diff --git a/init/Kconfig b/init/Kconfig
index 9e22ee8fbd75e..c15ee42b82726 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -23,6 +23,9 @@ config LD_VERSION
config CC_IS_CLANG
def_bool $(success,$(CC) --version | head -n 1 | grep -q clang)

+config LD_IS_LLD
+ def_bool $(success,$(LD) -v | head -n 1 | grep -q LLD)
+
config CLANG_VERSION
int
default $(shell,$(srctree)/scripts/clang-version.sh $(CC))

base-commit: 96c9a7802af7d500a582d89a8b864584fe878c1b
--
2.26.2

Nathan Chancellor

unread,
Apr 28, 2020, 6:14:43 PM4/28/20
to Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Fangrui Song, Sami Tolvanen, Dmitry Golovin, Sedat Dilek, Nathan Chancellor
After commit 9553d16fa671 ("init/kconfig: Add LD_VERSION Kconfig"), we
have access to GNU ld's version at configuration time. As a result, we
can make it clearer under what configuration circumstances the MIPS VDSO
needs to be disabled.

This is a prerequisite for getting rid of the MIPS VDSO binutils
warning and linking the VDSO when LD is ld.lld. Wrapping the call to
ld-ifversion with CONFIG_LD_IS_LLD does not work because the config
values are wiped away during 'make clean'.

Signed-off-by: Nathan Chancellor <natecha...@gmail.com>
---

v3 -> v4:

* No changes.

v2 -> v3:

+# the lack of relocations. As such, we disable the VDSO for microMIPS builds.
+
+config MIPS_LD_CAN_LINK_VDSO
+ def_bool LD_VERSION >= 225000000
+
+config MIPS_DISABLE_VDSO
+ def_bool CPU_MICROMIPS || (!CPU_MIPSR6 && !MIPS_LD_CAN_LINK_VDSO)
diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
index d7fe8408603e8..92b53d1df42c3 100644
--- a/arch/mips/vdso/Makefile
+++ b/arch/mips/vdso/Makefile
endif

# VDSO linker flags.

Nathan Chancellor

unread,
Apr 28, 2020, 6:14:46 PM4/28/20
to Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Fangrui Song, Sami Tolvanen, Dmitry Golovin, Sedat Dilek, Nathan Chancellor
This was all done to work around a GCC bug that has been fixed after
4.2. The kernel requires GCC 4.6 or newer so remove all of these hacks
and just use the traditional flags.

$ mips64-linux-gcc --version | head -n1
mips64-linux-gcc (GCC) 4.6.3

$ mips64-linux-gcc -EB -dM -E -C -x c /dev/null | grep MIPSE
#define MIPSEB 1
#define __MIPSEB__ 1
#define _MIPSEB 1
#define __MIPSEB 1

$ mips64-linux-gcc -EL -dM -E -C -x c /dev/null | grep MIPSE
#define __MIPSEL__ 1
#define MIPSEL 1
#define _MIPSEL 1
#define __MIPSEL 1

This is necessary when converting the MIPS VDSO to use $(LD) instead of
$(CC) to link because the OUTPUT_FORMAT is defaulted to little endian
and only flips to big endian when '-EB' is set on the command line.
There is no issue currently because the compiler explicitly passes
'-EB' or '-EL' to the linker regardless of whether or not it was
provided by the user. Passing '-v' to VDSO_LDFLAGS shows:

<gcc_prefix>/libexec/gcc/mips64-linux/9.3.0/collect2 ... -EB ...

even though '-EB' is nowhere to be found in KBUILD_CFLAGS. The VDSO
Makefile already supports getting '-EB' or '-EL' from KBUILD_CFLAGS
through a filter directive but '-EB' or '-EL' is not always present.

If we do not do this, we will see the following error when compiling
for big endian:

$ make -j$(nproc) ARCH=mips CROSS_COMPILE=mips64-linux- \
64r2el_defconfig arch/mips/vdso/
...
mips64-linux-ld: arch/mips/vdso/elf.o: compiled for a big endian system
and target is little endian
mips64-linux-ld: arch/mips/vdso/elf.o: endianness incompatible with that
of the selected emulation
mips64-linux-ld: failed to merge target specific data of file
arch/mips/vdso/elf.o
...

Remove this legacy hack and just use '-EB' and '-EL' unconditionally.

Reported-by: Thomas Bogendoerfer <tsbo...@alpha.franken.de>
Signed-off-by: Nathan Chancellor <natecha...@gmail.com>
---

v3 -> v4:

* New patch.

Nathan Chancellor

unread,
Apr 28, 2020, 6:14:47 PM4/28/20
to Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Fangrui Song, Sami Tolvanen, Dmitry Golovin, Sedat Dilek, Nathan Chancellor
Currently, the VDSO is being linked through $(CC). This does not match
how the rest of the kernel links objects, which is through the $(LD)
variable.

When clang is built in a default configuration, it first attempts to use
the target triple's default linker then the system's default linker,
unless told otherwise through -fuse-ld=... We do not use -fuse-ld=
because it can be brittle and we have support for invoking $(LD)
directly. See commit fe00e50b2db8c ("ARM: 8858/1: vdso: use $(LD)
instead of $(CC) to link VDSO") and commit 691efbedc60d2 ("arm64: vdso:
use $(LD) instead of $(CC) to link VDSO") for examples of doing this in
the VDSO.

Do the same thing here. Replace the custom linking logic with $(cmd_ld)
and ldflags-y so that $(LD) is respected. We need to explicitly add two
flags to the linker that were implicitly passed by the compiler:
-G 0 (which comes from ccflags-vdso) and --eh-frame-hdr.

Before this patch (generated by adding '-v' to VDSO_LDFLAGS):

<gcc_prefix>/libexec/gcc/mips64-linux/9.3.0/collect2 \
-plugin <gcc_prefix>/libexec/gcc/mips64-linux/9.3.0/liblto_plugin.so \
-plugin-opt=<gcc_prefix>/libexec/gcc/mips64-linux/9.3.0/lto-wrapper \
-plugin-opt=-fresolution=/tmp/ccGEi5Ka.res \
--eh-frame-hdr \
-G 0 \
-EB \
-mips64r2 \
-shared \
-melf64btsmip \
-o arch/mips/vdso/vdso.so.dbg.raw \
-L<gcc_prefix>/lib/gcc/mips64-linux/9.3.0/64 \
-L<gcc_prefix>/lib/gcc/mips64-linux/9.3.0 \
-L<gcc_prefix>/lib/gcc/mips64-linux/9.3.0/../../../../mips64-linux/lib \
-Bsymbolic \
--no-undefined \
-soname=linux-vdso.so.1 \
-EB \
--hash-style=sysv \
--build-id \
-T arch/mips/vdso/vdso.lds \
arch/mips/vdso/elf.o \
arch/mips/vdso/vgettimeofday.o \
arch/mips/vdso/sigreturn.o

After this patch:

<gcc_prefix>/bin/mips64-linux-ld \
-m elf64btsmip \
-Bsymbolic \
--no-undefined \
-soname=linux-vdso.so.1 \
-EB \
-nostdlib \
-shared \
-G 0 \
--eh-frame-hdr \
--hash-style=sysv \
--build-id \
-T arch/mips/vdso/vdso.lds \
arch/mips/vdso/elf.o \
arch/mips/vdso/vgettimeofday.o
arch/mips/vdso/sigreturn.o \
-o arch/mips/vdso/vdso.so.dbg.raw

Note that we leave behind -mips64r2. Turns out that ld ignores it (see
get_emulation in ld/ldmain.c). This is true of current trunk and 2.23,
which is the minimum supported version for the kernel:

https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=ld/ldmain.c;hb=aa4209e7b679afd74a3860ce25659e71cc4847d5#l593
https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=ld/ldmain.c;hb=a55e30b51bc6227d8d41f707654d0a5620978dcf#l641

Before this patch, LD=ld.lld did nothing:

$ llvm-readelf -p.comment arch/mips/vdso/vdso.so.dbg | sed 's/(.*//'
String dump of section '.comment':
[ 0] ClangBuiltLinux clang version 11.0.0

After this patch, it does:

$ llvm-readelf -p.comment arch/mips/vdso/vdso.so.dbg | sed 's/(.*//'
String dump of section '.comment':
[ 0] Linker: LLD 11.0.0
[ 62] ClangBuiltLinux clang version 11.0.0

Link: https://github.com/ClangBuiltLinux/linux/issues/785
Signed-off-by: Nathan Chancellor <natecha...@gmail.com>
---

v3 -> v4:

* Improve commit message to show that ld command is effectively the
same as the one generated by GCC.

* Add '-G 0' and '--eh-frame-hdr' because they were added by GCC.

v2 -> v3:

* New patch.

arch/mips/vdso/Makefile | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
index 92b53d1df42c3..2e64c7600eead 100644
--- a/arch/mips/vdso/Makefile
+++ b/arch/mips/vdso/Makefile
@@ -60,10 +60,9 @@ ifdef CONFIG_MIPS_DISABLE_VDSO
endif

# VDSO linker flags.
-VDSO_LDFLAGS := \
- -Wl,-Bsymbolic -Wl,--no-undefined -Wl,-soname=linux-vdso.so.1 \
- $(addprefix -Wl$(comma),$(filter -E%,$(KBUILD_CFLAGS))) \
- -nostdlib -shared -Wl,--hash-style=sysv -Wl,--build-id
+ldflags-y := -Bsymbolic --no-undefined -soname=linux-vdso.so.1 \
+ $(filter -E%,$(KBUILD_CFLAGS)) -nostdlib -shared \
+ -G 0 --eh-frame-hdr --hash-style=sysv --build-id -T

Nathan Chancellor

unread,
Apr 28, 2020, 6:14:48 PM4/28/20
to Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Fangrui Song, Sami Tolvanen, Dmitry Golovin, Sedat Dilek, Nathan Chancellor
Currently, when linking with ld.lld, this warning pops up:

arch/mips/vdso/Makefile:70: MIPS VDSO requires binutils >= 2.25

CONFIG_LD_VERSION is set with scripts/ld-version.sh, which is specific
to GNU ld. It returns 0 for ld.lld so CONFIG_MIPS_LD_CAN_LINK_VDSO does
not set.

ld.lld has a completely different versioning scheme (as it follows
LLVM's versioning) and it does not have the issue mentioned in the
comment block so it should be allowed to link the VDSO.

With this patch, the VDSO successfully links and shows P_MIPS_PC32 in
vgettimeofday.o.

$ llvm-objdump -Dr arch/mips/vdso/vgettimeofday.o | grep R_MIPS_PC32
00000024: R_MIPS_PC32 _start
000000b0: R_MIPS_PC32 _start
000002bc: R_MIPS_PC32 _start
0000036c: R_MIPS_PC32 _start
00000468: R_MIPS_PC32 _start

Reported-by: Dmitry Golovin <di...@golovin.in>
Signed-off-by: Nathan Chancellor <natecha...@gmail.com>
Link: https://github.com/ClangBuiltLinux/linux/issues/785
Link: https://github.com/llvm/llvm-project/commit/e364e2e9ce50c12eb2bf093560e1a1a8544d455a
---

v3 -> v4:

* No changes.

v2 -> v3:

* No changes.

v1 -> v2:

* Move into Kconfig so that the warning does not happen.

arch/mips/vdso/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/vdso/Kconfig b/arch/mips/vdso/Kconfig
index 36a52158d849b..7aec721398d59 100644
--- a/arch/mips/vdso/Kconfig
+++ b/arch/mips/vdso/Kconfig
@@ -12,7 +12,7 @@
# the lack of relocations. As such, we disable the VDSO for microMIPS builds.

config MIPS_LD_CAN_LINK_VDSO
- def_bool LD_VERSION >= 225000000
+ def_bool LD_VERSION >= 225000000 || LD_IS_LLD

config MIPS_DISABLE_VDSO
def_bool CPU_MICROMIPS || (!CPU_MIPSR6 && !MIPS_LD_CAN_LINK_VDSO)
--
2.26.2

Fangrui Song

unread,
Apr 28, 2020, 6:54:05 PM4/28/20
to Nathan Chancellor, Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek
My understanding is that we start to use more -fasynchronous-unwind-tables to eliminate .eh_frame in object files.
Without .eh_frame, LD --eh-frame-hdr is really not useful.


Sigh... -G 0. This is an option ignored by LLD. GCC devs probably should
have used the long option --gpsize rather than take the short option -G.
Even better, -z gpsize= or similar if this option is specific to ELF.

Nathan Chancellor

unread,
Apr 28, 2020, 8:44:28 PM4/28/20
to Fangrui Song, Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek
Ah, I was not paying attention; I figured that this was necessary
because the x86 VDSO broke without it:

cd01544a268ad ("x86/vdso: Pass --eh-frame-hdr to the linker")

However, they explicitly add -fasynchronous-unwind-tables so it seems
like this indeed can be removed. Kind of odd that GCC passes it along
even with -fno-asynchronous-unwind-tables. I will do that in v5 once I
get some feedback on whether or not anything else breaks.

Cheers,
Nathan

Sedat Dilek

unread,
Apr 29, 2020, 3:04:55 AM4/29/20
to Nathan Chancellor, Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, Clang-Built-Linux ML, linux-...@vger.kernel.org, Nick Desaulniers, Fangrui Song, Sami Tolvanen, Dmitry Golovin
On Wed, Apr 29, 2020 at 12:14 AM Nathan Chancellor
<natecha...@gmail.com> wrote:

> Patch 1 adds ld.lld support to Kconfig so that we can avoid certain
> ld.bfd checks.
>

Is it possible to introduce and add LD_IS_BFD Kconfig for ld.bfd in this series?
Most people agreed on this name AFAICS.
What do people think?

- Sedat -

Sedat Dilek

unread,
Apr 29, 2020, 3:13:52 AM4/29/20
to Nathan Chancellor, Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, Clang-Built-Linux ML, linux-...@vger.kernel.org, Nick Desaulniers, Fangrui Song, Sami Tolvanen, Dmitry Golovin
On Wed, Apr 29, 2020 at 12:14 AM Nathan Chancellor
<natecha...@gmail.com> wrote:
>
> From: Sami Tolvanen <samito...@google.com>
>
> Similarly to the CC_IS_CLANG config, add LD_IS_LLD to avoid GNU ld
> specific logic such as ld-version or ld-ifversion and gain the
> ability to select potential features that depend on the linker at
> configuration time such as LTO.
>
> Signed-off-by: Sami Tolvanen <samito...@google.com>
> Acked-by: Masahiro Yamada <masa...@kernel.org>
> [nc: Reword commit message]
> Signed-off-by: Nathan Chancellor <natecha...@gmail.com>

Tested-by: Sedat Dilek <sedat...@gmail.com>
Reviewed-by: Sedat Dilek <sedat...@gmail.com>

Testing on Debian/testing AMD64 (since Linux v5.3):
#1: LLVM/Clang/LLD version 9.0 and 10.0
#2: Debian's GCC 9.3 with ld.lld-9 and ld.lld-10

I am linking my Linux-kernels with ld.lld despite there are issues -
then check with ld.bfd.

- Sedat -

Maciej W. Rozycki

unread,
Apr 29, 2020, 1:46:39 PM4/29/20
to Nathan Chancellor, Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek
On Mon, 27 Apr 2020, Nathan Chancellor wrote:

> > Can you actually record in the change description what the difference in
> > the relevant link command is, as shown where `V=1' has been used with
> > `make' invocation?
>
> That will be rather unweildy to put in the commit message since
> currently, $(CC) + $(KBUILD_CFLAGS) is being used but I can if it is
> really desired. Otherwise, I can just put it where I put the changelog.

Umm, is the difference so huge? I think a note along the lines of:

"[...] This change adds/removes[*]:

<part of the command affected>

from the invocation of [...], which is required for [...]"

-- only quoting what's actually changed will be sufficient. Reword as
required. Otherwise it's hard to guess now what the change actually does,
and it will be even harder for someone who comes across it and tries to
understand it the future, when the context might be hard to reproduce.

[*] Delete as appropriate.

Maciej

Nathan Chancellor

unread,
Apr 29, 2020, 11:05:52 PM4/29/20
to Sedat Dilek, Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, Clang-Built-Linux ML, linux-...@vger.kernel.org, Nick Desaulniers, Fangrui Song, Sami Tolvanen, Dmitry Golovin
On Wed, Apr 29, 2020 at 09:13:40AM +0200, Sedat Dilek wrote:
> On Wed, Apr 29, 2020 at 12:14 AM Nathan Chancellor
> <natecha...@gmail.com> wrote:
> >
> > From: Sami Tolvanen <samito...@google.com>
> >
> > Similarly to the CC_IS_CLANG config, add LD_IS_LLD to avoid GNU ld
> > specific logic such as ld-version or ld-ifversion and gain the
> > ability to select potential features that depend on the linker at
> > configuration time such as LTO.
> >
> > Signed-off-by: Sami Tolvanen <samito...@google.com>
> > Acked-by: Masahiro Yamada <masa...@kernel.org>
> > [nc: Reword commit message]
> > Signed-off-by: Nathan Chancellor <natecha...@gmail.com>
>
> Tested-by: Sedat Dilek <sedat...@gmail.com>
> Reviewed-by: Sedat Dilek <sedat...@gmail.com>
>
> Testing on Debian/testing AMD64 (since Linux v5.3):
> #1: LLVM/Clang/LLD version 9.0 and 10.0
> #2: Debian's GCC 9.3 with ld.lld-9 and ld.lld-10
>
> I am linking my Linux-kernels with ld.lld despite there are issues -
> then check with ld.bfd.

What issues are these? Have they been reported?

Cheers,
Nathan

Nathan Chancellor

unread,
Apr 29, 2020, 11:06:34 PM4/29/20
to Sedat Dilek, Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, Clang-Built-Linux ML, linux-...@vger.kernel.org, Nick Desaulniers, Fangrui Song, Sami Tolvanen, Dmitry Golovin
What is the use case for LD_IS_BFD right now? I am not sure I see a
reason to add a CONFIG value that won't see any immediate use.

Cheers,
Nathan

Nathan Chancellor

unread,
Apr 29, 2020, 11:14:06 PM4/29/20
to Maciej W. Rozycki, Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek
I ended up figuring out a way to get the difference proper into the
commit message in v4. Please take a look.

Cheers,
Nathan

Maciej W. Rozycki

unread,
May 2, 2020, 9:34:09 AM5/2/20
to Fangrui Song, Nathan Chancellor, Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Sami Tolvanen, Dmitry Golovin, Sedat Dilek
On Tue, 28 Apr 2020, Fangrui Song wrote:

> Sigh... -G 0. This is an option ignored by LLD. GCC devs probably should
> have used the long option --gpsize rather than take the short option -G.
> Even better, -z gpsize= or similar if this option is specific to ELF.

Well, the `-G' option is some 30 years old and comes from RISC-OS where
the vendor linker had it; it was already present with the initial MIPS
port of GCC:

commit fe3ec4f798ceea52e1b542b481670b83c12347fd
Author: Michael Meissner <meis...@gcc.gnu.org>
Date: Sun Dec 1 05:02:56 1991 +0000

Initial revision

From-SVN: r88

specifically:

+#define LINK_SPEC "%{G*} \

there, so I don't know of what GCC developers' choice you are talking
about.

Much of GCC legacy comes from various vendors' compilation systems; in
this case it was the MIPS Computer Systems (aka MIPSCO) compiler. There
may not have been a GNU linker port to RISC-OS at that point (or ever),
and the assembler and linker invocation interfaces were kept compatible as
ports were added to individual GNU development tools, for obvious reasons.
I still remember using GCC with vendor's assembler and linker on DEC
Ultrix/MIPS myself many years ago, to overcome some vendor compiler's
limitations.

And FTR this was still a few years before ELF was even invented; MIPS OSs
used the COFF binary format back then.

Sorry. I think it's LLVM/LLD that ignores compatibility, not the other
way round.

Maciej

Maciej W. Rozycki

unread,
May 2, 2020, 9:50:37 AM5/2/20
to Nathan Chancellor, Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Fangrui Song, Sami Tolvanen, Dmitry Golovin, Sedat Dilek
On Tue, 28 Apr 2020, Nathan Chancellor wrote:

> Before this patch, LD=ld.lld did nothing:
>
> $ llvm-readelf -p.comment arch/mips/vdso/vdso.so.dbg | sed 's/(.*//'
> String dump of section '.comment':
> [ 0] ClangBuiltLinux clang version 11.0.0

What does it mean "did nothing", is `arch/mips/vdso/vdso.so.dbg.raw' not
produced? Where does `arch/mips/vdso/vdso.so.dbg' come from then?

Maciej

Nathan Chancellor

unread,
May 2, 2020, 11:49:49 AM5/2/20
to Maciej W. Rozycki, Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Fangrui Song, Sami Tolvanen, Dmitry Golovin, Sedat Dilek
A better wording might be "Before this patch, specifying a linker like
ld.lld via the LD variable was not respected by the MIPS VDSO". I should
also probably expand on the second paragraph, maybe something like:

When clang is built in a default configuration, it first attempts to use
the target triple's default linker then the system's default linker,
which is almost always ld.bfd. To use ld.lld, '-fuse-ld=lld' must be
passed to clang. However, we do not use -fuse-ld=lld because it can be
brittle and we have support for invoking $(LD) directly because we have
separate compilation and link steps. See commit fe00e50b2db8c ("ARM:

Thomas Bogendoerfer

unread,
May 12, 2020, 4:05:21 AM5/12/20
to Nathan Chancellor, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Fangrui Song, Sami Tolvanen, Dmitry Golovin, Sedat Dilek
On Tue, Apr 28, 2020 at 03:14:14PM -0700, Nathan Chancellor wrote:
> [..]
> Please let me know if there are any issues!

I found no issues in my tests. Is this the final state ? If yes, I'm
going to apply it to mips-next.

Nathan Chancellor

unread,
May 12, 2020, 4:28:46 AM5/12/20
to Thomas Bogendoerfer, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Fangrui Song, Sami Tolvanen, Dmitry Golovin, Sedat Dilek
Maciej seemed to have some issue with the way I worded the commit
message of patch 4 but I have not heard anything back about my
suggestion and Fangrui commented that --eh-frame-hdr might not be
necessary but if everything works fine for you with this version, I
am not inclined to touch it.

If you feel this is good to go, I am happy to let it go in. Thanks for
accepting it!

Cheers,
Nathan

Thomas Bogendoerfer

unread,
May 13, 2020, 7:21:20 AM5/13/20
to Nathan Chancellor, Masahiro Yamada, linux...@vger.kernel.org, linux-...@vger.kernel.org, clang-bu...@googlegroups.com, linux-...@vger.kernel.org, Nick Desaulniers, Fangrui Song, Sami Tolvanen, Dmitry Golovin, Sedat Dilek
applied to mips-next.
Reply all
Reply to author
Forward
0 new messages