Skip to content

Commit c2c81bb

Browse files
RISC-V: Fix the VDSO symbol generaton for binutils-2.35+
We were relying on GNU ld's ability to re-link executable files in order to extract our VDSO symbols. This behavior was deemed a bug as of binutils-2.35 (specifically the binutils-gdb commit a87e1817a4 ("Have the linker fail if any attempt to link in an executable is made."), but as that has been backported to at least Debian's binutils-2.34 in may manifest in other places. The previous version of this was a bit of a mess: we were linking a static executable version of the VDSO, containing only a subset of the input symbols, which we then linked into the kernel. This worked, but certainly wasn't a supported path through the toolchain. Instead this new version parses the textual output of nm to produce a symbol table. Both rely on near-zero addresses being linkable, but as we rely on weak undefined symbols being linkable elsewhere I don't view this as a major issue. Fixes: e2c0cdf ("RISC-V: User-facing API") Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
1 parent 1074dd4 commit c2c81bb

3 files changed

Lines changed: 16 additions & 9 deletions

File tree

arch/riscv/kernel/vdso/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# SPDX-License-Identifier: GPL-2.0-only
22
vdso.lds
33
*.tmp
4+
vdso-syms.S

arch/riscv/kernel/vdso/Makefile

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,14 @@ $(obj)/vdso.o: $(obj)/vdso.so
4343
SYSCFLAGS_vdso.so.dbg = $(c_flags)
4444
$(obj)/vdso.so.dbg: $(src)/vdso.lds $(obj-vdso) FORCE
4545
$(call if_changed,vdsold)
46+
SYSCFLAGS_vdso.so.dbg = -shared -s -Wl,-soname=linux-vdso.so.1 \
47+
-Wl,--build-id -Wl,--hash-style=both
4648

4749
# We also create a special relocatable object that should mirror the symbol
4850
# table and layout of the linked DSO. With ld --just-symbols we can then
4951
# refer to these symbols in the kernel code rather than hand-coded addresses.
50-
51-
SYSCFLAGS_vdso.so.dbg = -shared -s -Wl,-soname=linux-vdso.so.1 \
52-
-Wl,--build-id=sha1 -Wl,--hash-style=both
53-
$(obj)/vdso-dummy.o: $(src)/vdso.lds $(obj)/rt_sigreturn.o FORCE
54-
$(call if_changed,vdsold)
55-
56-
LDFLAGS_vdso-syms.o := -r --just-symbols
57-
$(obj)/vdso-syms.o: $(obj)/vdso-dummy.o FORCE
58-
$(call if_changed,ld)
52+
$(obj)/vdso-syms.S: $(obj)/vdso.so FORCE
53+
$(call if_changed,so2s)
5954

6055
# strip rule for the .so file
6156
$(obj)/%.so: OBJCOPYFLAGS := -S
@@ -73,6 +68,11 @@ quiet_cmd_vdsold = VDSOLD $@
7368
$(patsubst %, -G __vdso_%, $(vdso-syms)) $@.tmp $@ && \
7469
rm $@.tmp
7570

71+
# Extracts symbol offsets from the VDSO, converting them into an assembly file
72+
# that contains the same symbols at the same offsets.
73+
quiet_cmd_so2s = SO2S $@
74+
cmd_so2s = $(NM) -D $< | $(srctree)/$(src)/so2s.sh > $@
75+
7676
# install commands for the unstripped file
7777
quiet_cmd_vdso_install = INSTALL $@
7878
cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@

arch/riscv/kernel/vdso/so2s.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/sh
2+
# SPDX-License-Identifier: GPL-2.0+
3+
# Copyright 2020 Palmer Dabbelt <palmerdabbelt@google.com>
4+
5+
sed 's!\([0-9a-f]*\) T \([a-z0-9_]*\)\(@@LINUX_4.15\)*!.global \2\n.set \2,0x\1!' \
6+
| grep '^\.'

0 commit comments

Comments
 (0)