[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