diff options
author | Leonard Chan <leonardchan@google.com> | 2020-04-01 15:25:04 -0700 |
---|---|---|
committer | Leonard Chan <leonardchan@google.com> | 2020-11-19 10:26:17 -0800 |
commit | a97f62837f59620a60b3ed9f29568440c7d0553a (patch) | |
tree | 360eb006af37d0abe1f40757db6f4da7b5246984 /llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | |
parent | 2f3adc54b57356cd207ded2ec2d7f4e1273da0ff (diff) | |
download | llvm-a97f62837f59620a60b3ed9f29568440c7d0553a.zip llvm-a97f62837f59620a60b3ed9f29568440c7d0553a.tar.gz llvm-a97f62837f59620a60b3ed9f29568440c7d0553a.tar.bz2 |
[llvm][IR] Add dso_local_equivalent Constant
The `dso_local_equivalent` constant is a wrapper for functions that represents a
value which is functionally equivalent to the global passed to this. That is, if
this accepts a function, calling this constant should have the same effects as
calling the function directly. This could be a direct reference to the function,
the `@plt` modifier on X86/AArch64, a thunk, or anything that's equivalent to the
resolved function as a call target.
When lowered, the returned address must have a constant offset at link time from
some other symbol defined within the same binary. The address of this value is
also insignificant. The name is leveraged from `dso_local` where use of a function
or variable is resolved to a symbol in the same linkage unit.
In this patch:
- Addition of `dso_local_equivalent` and handling it
- Update Constant::needsRelocation() to strip constant inbound GEPs and take
advantage of `dso_local_equivalent` for relative references
This is useful for the [Relative VTables C++ ABI](https://reviews.llvm.org/D72959)
which makes vtables readonly. This works by replacing the dynamic relocations for
function pointers in them with static relocations that represent the offset between
the vtable and virtual functions. If a function is externally defined,
`dso_local_equivalent` can be used as a generic wrapper for the function to still
allow for this static offset calculation to be done.
See [RFC](http://lists.llvm.org/pipermail/llvm-dev/2020-August/144469.html) for more details.
Differential Revision: https://reviews.llvm.org/D77248
Diffstat (limited to 'llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp')
-rw-r--r-- | llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 6f9268f..a6c5a26 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -105,6 +105,11 @@ static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags, // ELF //===----------------------------------------------------------------------===// +TargetLoweringObjectFileELF::TargetLoweringObjectFileELF() + : TargetLoweringObjectFile() { + SupportDSOLocalEquivalentLowering = true; +} + void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx, const TargetMachine &TgtM) { TargetLoweringObjectFile::Initialize(Ctx, TgtM); @@ -1007,6 +1012,20 @@ const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference( MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); } +const MCExpr *TargetLoweringObjectFileELF::lowerDSOLocalEquivalent( + const DSOLocalEquivalent *Equiv, const TargetMachine &TM) const { + assert(supportDSOLocalEquivalentLowering()); + + const auto *GV = Equiv->getGlobalValue(); + + // A PLT entry is not needed for dso_local globals. + if (GV->isDSOLocal() || GV->isImplicitDSOLocal()) + return MCSymbolRefExpr::create(TM.getSymbol(GV), getContext()); + + return MCSymbolRefExpr::create(TM.getSymbol(GV), PLTRelativeVariantKind, + getContext()); +} + MCSection *TargetLoweringObjectFileELF::getSectionForCommandLines() const { // Use ".GCC.command.line" since this feature is to support clang's // -frecord-gcc-switches which in turn attempts to mimic GCC's switch of the |