[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug ld/28218] New: ld: ifunc resolver calls a lazy PLT. When does it wo
From: |
i at maskray dot me |
Subject: |
[Bug ld/28218] New: ld: ifunc resolver calls a lazy PLT. When does it work? |
Date: |
Tue, 10 Aug 2021 17:36:59 +0000 |
https://sourceware.org/bugzilla/show_bug.cgi?id=28218
Bug ID: 28218
Summary: ld: ifunc resolver calls a lazy PLT. When does it
work?
Product: binutils
Version: unspecified
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: ld
Assignee: unassigned at sourceware dot org
Reporter: i at maskray dot me
Target Milestone: ---
If an ifunc resolver calls a PLT with lazy JUMP_SLOT, should it work?
My impression is that this does not necessarily need to work.
That said, the R_X86_64_IRELATIVE in .rela.plt is special.
PR ld/13302 patched GNU ld to place R_X86_64_IRELATIVE in .rela.plt after
JUMP_SLOT.
This allows lazy PLT calls.
I think if this case is to be supported, ld.so is to be patched instead.
IRELATIVE relocations are eagerly resolved.
.rela.dyn is conceptually a better place, similar to the .plt.got GLOB_DAT
optimization.
IRELATIVE relocations are not PLT.
FreeBSD rtld resolves non-IRELATIVE relocations in all modules, then IRELATIVE
relocations in all modules.
This allows flexibility on what can be used in ifunc resolvers, and
linkers don't need to place IRELATIVE in special places.
cat > a.c <<eof
#include <stdio.h>
int a_impl() { return 42; }
void *a_resolver() {
puts("a_resolver");
return (void *)a_impl;
}
int a() __attribute__((ifunc("a_resolver")));
// .rela.dyn.rel => R_X86_64_64 referencing STT_GNU_IFUNC in .rela.dyn
int (*fptr_a)() = a;
int main() { printf("%d\n", a()); }
eof
cc -fpie -c a.c
cc -fuse-ld=bfd -pie a.o -o a
% ./a
[1] 170657 segmentation fault ./a
% readelf -Wr a
Relocation section '.rela.dyn' at offset 0x4b0 contains 9 entries:
Offset Info Type Symbol's Value
Symbol's Name + Addend
0000000000003de8 0000000000000008 R_X86_64_RELATIVE
1150
0000000000003df0 0000000000000008 R_X86_64_RELATIVE
1110
0000000000004038 0000000000000008 R_X86_64_RELATIVE
4038
0000000000003fd8 0000000100000006 R_X86_64_GLOB_DAT 0000000000000000
_ITM_deregisterTMCloneTable + 0
0000000000003fe0 0000000400000006 R_X86_64_GLOB_DAT 0000000000000000
__libc_start_main@GLIBC_2.2.5 + 0
0000000000003fe8 0000000500000006 R_X86_64_GLOB_DAT 0000000000000000
__gmon_start__ + 0
0000000000003ff0 0000000600000006 R_X86_64_GLOB_DAT 0000000000000000
_ITM_registerTMCloneTable + 0
0000000000003ff8 0000000700000006 R_X86_64_GLOB_DAT 0000000000000000
__cxa_finalize@GLIBC_2.2.5 + 0
0000000000004040 0000000000000025 R_X86_64_IRELATIVE
1160
Relocation section '.rela.plt' at offset 0x588 contains 3 entries:
Offset Info Type Symbol's Value
Symbol's Name + Addend
0000000000004018 0000000200000007 R_X86_64_JUMP_SLOT 0000000000000000
puts@GLIBC_2.2.5 + 0
0000000000004020 0000000300000007 R_X86_64_JUMP_SLOT 0000000000000000
printf@GLIBC_2.2.5 + 0
0000000000004028 0000000000000025 R_X86_64_IRELATIVE
1160
`int (*fptr_a)() = a;` leads to an R_X86_64_IRELATIVE in .rela.dyn .
If lazy binding is used, when the R_X86_64_IRELATIVE is resolved,
R_X86_64_JUMP_SLOT(puts) hasn't been resolved yet, and the program crashes.
R_X86_64_IRELATIVE can be seen as an optimization.
R_X86_64_64 referencing an STT_GNU_IFUNC symbol is a different representation.
---
cat > b.c <<eof
#include <stdio.h>
int b_impl() { return 42; }
void *b_resolver() {
puts("b resolver");
return (void *)b_impl;
}
int b() __attribute__((ifunc("b_resolver")));
int (*fptr_b)() = b;
eof
cc b.c -fpic -shared -o b.so
Make b.so a DT_NEEDED of the executable and see the crash again.
In this case, R_X86_64_64 is used instead of IRELATIVE.
(b is preemptible, so IRELATIVE cannot be used.)
https://sourceware.org/pipermail/libc-alpha/2021-August/129968.html says
"I don't believe this is the use case we want to support."
--
You are receiving this mail because:
You are on the CC list for the bug.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Bug ld/28218] New: ld: ifunc resolver calls a lazy PLT. When does it work?,
i at maskray dot me <=