[PATCH v3 0/2] RISC-V: Support GNU indirect functions
Nelson Chu
nelson.chu@sifive.com
Wed Oct 7 03:48:21 GMT 2020
Hi binutils,
I have arranged the ifunc patches recently, and also pass elf/linux
toolchain regressions. Compared to the v2 patches, the second patch
- RISC-V: Fix that IRELATIVE relocs may be inserted to the wrong place,
fix the ifunc overwrite issue when generating the static executable.
Otherwise, the v3 patches just fix some minor conflicts, and almost the
same the the v2 patches.
As for the different ifunc behaviors between ld and lld, I have tested
the x86 ifunc behaviors both for ld and lld, and they are also different.
Our ld ifunc behavior is the same as the x86 ld, and the riscv lld is
the same as the x86 lld. Consider the following tests,
* x86 test file
nelson@LAPTOP-QFSGI1F2:~/test/ifunc/x86$ cat x86.s
.text
.type foo_resolver, @function
foo_resolver:
ret
.size foo_resolver, .-foo_resolver
.globl foo
.type foo, %gnu_indirect_function
.set foo, foo_resolver
.globl main
.type main, @function
main:
# GOT ifunc
movq foo@GOTPCREL(%rip), %rax
# PCREL ifunc
movq foo(%rip), %rax
# Data xxx
movl xxx(%rip), %eax
# PLT ifunc
call foo@PLT
ret
.size main, .-main
# Data ifunc
.data
xxx:
.quad foo
* x86 GNU ld ifunc behavior
nelson@LAPTOP-QFSGI1F2:~/test/ifunc/x86$ build-binutils-x86/build-install/bin/as x86.s -o x86.o
nelson@LAPTOP-QFSGI1F2:~/test/ifunc/x86$ build-binutils-x86/build-install/bin/readelf -Wr x86.o
Relocation section '.rela.text' at offset 0x1c0 contains 4 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000004 000000070000002a R_X86_64_REX_GOTPCRELX foo() foo - 4
000000000000000b 0000000700000002 R_X86_64_PC32 foo() foo - 4
0000000000000011 0000000200000002 R_X86_64_PC32 0000000000000000 .data - 4
0000000000000016 0000000700000004 R_X86_64_PLT32 foo() foo - 4
Relocation section '.rela.data' at offset 0x220 contains 1 entry:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000000 0000000700000001 R_X86_64_64 foo() foo + 0
nelson@LAPTOP-QFSGI1F2:~/test/ifunc/x86$ build-binutils-x86/build-install/bin/ld -pie x86.o -o x86.pie.ld
nelson@LAPTOP-QFSGI1F2:~/test/ifunc/x86$ build-binutils-x86/build-install/bin/readelf -Wr x86.pie.ld
Relocation section '.rela.dyn' at offset 0x300 contains 1 entry:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000003020 0000000000000025 R_X86_64_IRELATIVE 1020
Relocation section '.rela.plt' at offset 0x318 contains 1 entry:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000003018 0000000000000025 R_X86_64_IRELATIVE 1020
nelson@LAPTOP-QFSGI1F2:~/test/ifunc/x86$ build-binutils-x86/build-install/bin/objdump -d x86.pie.ld
x86.pie: file format elf64-x86-64
Disassembly of section .plt:
0000000000001000 <.plt>:
1000: ff 35 02 20 00 00 push 0x2002(%rip) #3008 <_GLOBAL_OFFSET_TABLE_+0x8>
1006: ff 25 04 20 00 00 jmp *0x2004(%rip) #3010 <_GLOBAL_OFFSET_TABLE_+0x10>
100c: 0f 1f 40 00 nopl 0x0(%rax)
1010: ff 25 02 20 00 00 jmp *0x2002(%rip) #3018 <_GLOBAL_OFFSET_TABLE_+0x18>
1016: 68 00 00 00 00 push $0x0
101b: e9 e0 ff ff ff jmp 1000 <.plt>
Disassembly of section .text:
0000000000001020 <foo_resolver>:
1020: c3 ret
0000000000001021 <main>:
1021: 48 8b 05 f0 1f 00 00 mov 0x1ff0(%rip),%rax # 3018 <_GLOBAL_OFFSET_TABLE_+0x18>
1028: 48 8b 05 e1 ff ff ff mov -0x1f(%rip),%rax # 1010 <.plt+0x10>
102f: 8b 05 eb 1f 00 00 mov 0x1feb(%rip),%eax # 3020 <xxx>
1035: e8 d6 ff ff ff call 1010 <.plt+0x10>
103a: c3 ret
1. The first mov is GOT reference, 0x3018 is a got entry, and ld have
inserted a dynamic R_X86_64_IRELATIVE for it.
2. The second mov is PCREL reloc, it refers to the .plt entry 0x1010.
3. The fourth instruction call is the PLT reference (0x1010). The PLT
and GOT share the same .got entry (0x3018).
4. The third mov refers to the data xxx (0x3020). GNU ld inserts a
dynamic R_X86_64_IRELATIVE for the data section.
* x86 lld ifunc behavior (v12.0.0)
nelson@LAPTOP-QFSGI1F2:~/test/ifunc/x86$ build-binutils-x86/build-install/bin/readelf -Wr x86.pie.lld
Relocation section '.rela.dyn' at offset 0x248 contains 3 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
00000000000023d0 0000000000000008 R_X86_64_RELATIVE 12b0
00000000000033d8 0000000000000008 R_X86_64_RELATIVE 12b0
00000000000033f8 0000000000000025 R_X86_64_IRELATIVE 1290
nelson@LAPTOP-QFSGI1F2:~/test/ifunc/x86$ build-binutils-x86/build-install/bin/objdump -d x86.pie.lld
x86.pie.lld: file format elf64-x86-64
Disassembly of section .text:
0000000000001290 <foo_resolver>:
1290: c3 ret
0000000000001291 <main>:
1291: 48 8b 05 38 11 00 00 mov 0x1138(%rip),%rax # 23d0 <_DYNAMIC+0x110>
1298: 48 8b 05 11 00 00 00 mov 0x11(%rip),%rax # 12b0 <foo>
129f: 8b 05 33 21 00 00 mov 0x2133(%rip),%eax # 33d8 <xxx>
12a5: e8 06 00 00 00 call 12b0 <foo>
12aa: c3 ret
Disassembly of section .iplt:
00000000000012b0 <foo>:
12b0: ff 25 42 21 00 00 jmp *0x2142(%rip) #33f8 <_GLOBAL_OFFSET_TABLE_+0x18>
12b6: 68 00 00 00 00 push $0x0
12bb: e9 40 ed ff ff jmp 0 <foo_resolver-0x1290>
1. The first mov is GOT reference, 0x23d0 is a got entry. lld insert
a dynamic R_X86_64_RELATIVE for it rather than the R_X86_64_IRELATIVE,
so we will get the .plt ifunc entry in the GOT, rather than the
resolved ifunc foo address.
2. The second mov is PCREL reloc, it refers to the .plt entry 0x12b0.
3. The fourth instruction call is the PLT reference (0x12b0). The PLT
will refer to the .got.plt entry 0x33f8, and ld should insert a
dynamic R_X86_64_IRELATIVE for it.
4. The third mov refers to the data xxx (0x33d8). lld inserts a
dynamic R_X86_64_RELATIVE for the data section, it refers to the
corresponding .plt entry rather than the resolved ifunc foo address.
Please feel free to correct me if I'm wrong or miss anything.
Thanks
Nelson
More information about the Binutils
mailing list