Ed Maste via llvm-dev
2018-Aug-22 14:11 UTC
[llvm-dev] [lld] avoid emitting PLT entries for ifuncs
On 22 August 2018 at 04:27, Rui Ueyama via llvm-dev <llvm-dev at lists.llvm.org> wrote:> > However, if you pass the -emit-relocs option to the linker, lld keeps all > relocations that have already been resolved in an output executable. By > analyzing a relocation table in a resulting executable, you could find all > locations where the ifunc PLT is called. Then, you can construct a new table > for your linker, embed it to the executable using objcopy or something like > that, and then let the kernel loader interpret it. > > Have you considered that?I've thought about alternative ways to achieve the same thing, including something like the above. My concern with that approach is that it's rather cumbersome and can be error-prone, and introduces a requirement for awkward multi-stage linking. In comparison Mark's patch is a relatively tiny tweak in lld. Despite the disadvantages I much prefer the proposed approach. On 22 August 2018 at 09:20, Joerg Sonnenberger via llvm-dev <llvm-dev at lists.llvm.org> wrote:> > On the linker side, it is a custom hack for > something that is generally considered very bad nowadays: text > relocations.True, although the argument against .text relocations doesn't hold for our kernel use case.
Mark Johnston via llvm-dev
2018-Aug-22 16:33 UTC
[llvm-dev] [lld] avoid emitting PLT entries for ifuncs
On Wed, Aug 22, 2018 at 10:11:00AM -0400, Ed Maste wrote:> On 22 August 2018 at 04:27, Rui Ueyama via llvm-dev > <llvm-dev at lists.llvm.org> wrote: > > > > However, if you pass the -emit-relocs option to the linker, lld keeps all > > relocations that have already been resolved in an output executable. By > > analyzing a relocation table in a resulting executable, you could find all > > locations where the ifunc PLT is called. Then, you can construct a new table > > for your linker, embed it to the executable using objcopy or something like > > that, and then let the kernel loader interpret it. > > > > Have you considered that? > > I've thought about alternative ways to achieve the same thing, > including something like the above. My concern with that approach is > that it's rather cumbersome and can be error-prone, and introduces a > requirement for awkward multi-stage linking.A couple of years ago I did something very much like this to experiment with hot-patched static DTrace probes in the kernel. My conclusion at the time was that even this kind of functionality (selective filtering of relocations as a post-processing step) was quite awkward and is much more easily implemented in the static linker.[*] In this case, we need to modify the loadable segment descriptions, and we need to do some unwinding of the static linker's work when processing non-RELA relocations in the kernel. It is all doable, but requires a significant amount of both userland and kernel code and a custom, FreeBSD-kernel-specific post-link step. [*] dtrace -G basically does this already. See dt_link.c in libdtrace: it's 2000 LOC of complicated ELF handling, and it's required numerous tweaks over the years to deal with changing behavioural quirks of GNU ld and lld. r313262 is an example of this: https://svnweb.freebsd.org/changeset/base/313262 The integration of dtrace(1) into the build systems of projects that wish to provide static probes is painful and often creates race conditions with incremental rebuilds. Rafael and I discussed this several times and his general sentiment was that the functionality provided by dtrace -G can be implemented much more sanely in lld.> On 22 August 2018 at 09:20, Joerg Sonnenberger via llvm-dev > <llvm-dev at lists.llvm.org> wrote: > > > > On the linker side, it is a custom hack for > > something that is generally considered very bad nowadays: text > > relocations. > > True, although the argument against .text relocations doesn't hold for > our kernel use case.Moreover, while being a hack, it is IMHO simply the right place to implement this logic from an architectural standpoint. The static linker is pessimizing ifunc calls in a freestanding environment and it has all the information required to avoid doing this, and in a robust manner. The small size of the required lld patch supports this view. Addressing the problem any other way involves adding much larger and more fragile hacks elsewhere.
Rui Ueyama via llvm-dev
2018-Aug-23 06:14 UTC
[llvm-dev] [lld] avoid emitting PLT entries for ifuncs
In the context of support not only IFunc but DTrace, what kind of features do you want to add to lld, if you have a chance to implement it in the linker instead of a post-processing tool? I wonder if we can solve both of your problems. On Thu, Aug 23, 2018 at 1:33 AM Mark Johnston <markj at freebsd.org> wrote:> On Wed, Aug 22, 2018 at 10:11:00AM -0400, Ed Maste wrote: > > On 22 August 2018 at 04:27, Rui Ueyama via llvm-dev > > <llvm-dev at lists.llvm.org> wrote: > > > > > > However, if you pass the -emit-relocs option to the linker, lld keeps > all > > > relocations that have already been resolved in an output executable. By > > > analyzing a relocation table in a resulting executable, you could find > all > > > locations where the ifunc PLT is called. Then, you can construct a new > table > > > for your linker, embed it to the executable using objcopy or something > like > > > that, and then let the kernel loader interpret it. > > > > > > Have you considered that? > > > > I've thought about alternative ways to achieve the same thing, > > including something like the above. My concern with that approach is > > that it's rather cumbersome and can be error-prone, and introduces a > > requirement for awkward multi-stage linking. > > A couple of years ago I did something very much like this to experiment > with hot-patched static DTrace probes in the kernel. My conclusion at > the time was that even this kind of functionality (selective filtering > of relocations as a post-processing step) was quite awkward and is much > more easily implemented in the static linker.[*] In this case, we need to > modify the loadable segment descriptions, and we need to do some > unwinding of the static linker's work when processing non-RELA > relocations in the kernel. It is all doable, but requires a significant > amount of both userland and kernel code and a custom, > FreeBSD-kernel-specific post-link step. > > [*] dtrace -G basically does this already. See dt_link.c in libdtrace: > it's 2000 LOC of complicated ELF handling, and it's required numerous > tweaks over the years to deal with changing behavioural quirks of GNU > ld and lld. r313262 is an example of this: > https://svnweb.freebsd.org/changeset/base/313262 > The integration of dtrace(1) into the build systems of projects that > wish to provide static probes is painful and often creates race > conditions with incremental rebuilds. Rafael and I discussed this > several times and his general sentiment was that the functionality > provided by dtrace -G can be implemented much more sanely in lld. > > > On 22 August 2018 at 09:20, Joerg Sonnenberger via llvm-dev > > <llvm-dev at lists.llvm.org> wrote: > > > > > > On the linker side, it is a custom hack for > > > something that is generally considered very bad nowadays: text > > > relocations. > > > > True, although the argument against .text relocations doesn't hold for > > our kernel use case. > > Moreover, while being a hack, it is IMHO simply the right place to > implement this logic from an architectural standpoint. The static > linker is pessimizing ifunc calls in a freestanding environment and it > has all the information required to avoid doing this, and in a robust > manner. The small size of the required lld patch supports this view. > Addressing the problem any other way involves adding much larger and > more fragile hacks elsewhere. >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180823/bf7ae5d0/attachment.html>
Possibly Parallel Threads
- [lld] avoid emitting PLT entries for ifuncs
- [lld] avoid emitting PLT entries for ifuncs
- [RFC][LLVM] New Constant type for representing function PLT entries
- RFC: __attribute__((ifunc("resolver")) representation in LLVM IR
- RFC: __attribute__((ifunc("resolver")) representation in LLVM IR