diff options
| author | Denis Protivensky <dprotivensky@accesssoftek.com> | 2015-04-07 07:04:42 +0000 |
|---|---|---|
| committer | Denis Protivensky <dprotivensky@accesssoftek.com> | 2015-04-07 07:04:42 +0000 |
| commit | 6c50e88c0deacca04f345bb08266c101b85da7b6 (patch) | |
| tree | afa35d6f8382b9ef7d24915fbced2bfe91b1fcd6 /lld/lib | |
| parent | 9dedc775d7b436e5f8f961413c3fd867ea8be53e (diff) | |
| download | bcm5719-llvm-6c50e88c0deacca04f345bb08266c101b85da7b6.tar.gz bcm5719-llvm-6c50e88c0deacca04f345bb08266c101b85da7b6.zip | |
[ARM] Add mapping symbols to PLT entries
Make PLT entry atoms represent mapping symbols in the Release mode,
while in the Debug mode they are still function-like symbols
with regular names.
It's legal that mapping symbols denote unnamed parts of code,
and PLT entries are not required to have function-like names.
Differential Revision: http://reviews.llvm.org/D8819
llvm-svn: 234301
Diffstat (limited to 'lld/lib')
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp | 92 |
1 files changed, 73 insertions, 19 deletions
diff --git a/lld/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp b/lld/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp index 713d4dfd79f..987f13f54ae 100644 --- a/lld/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp +++ b/lld/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp @@ -62,6 +62,21 @@ static const uint8_t ARMPltVeneerAtomContent[4] = { 0x00, 0x00 // nop }; +// Determine proper names for mapping symbols. +static std::string getMappingAtomName(DefinedAtom::CodeModel model, + const std::string &part) { + switch (model) { + case DefinedAtom::codeARM_a: + return part.empty() ? "$a" : "$a." + part; + case DefinedAtom::codeARM_d: + return part.empty() ? "$d" : "$d." + part; + case DefinedAtom::codeARM_t: + return part.empty() ? "$t" : "$t." + part; + default: + llvm_unreachable("Wrong code model of mapping atom"); + } +} + /// \brief Atoms that hold veneer code. class VeneerAtom : public SimpleELFDefinedAtom { StringRef _section; @@ -141,23 +156,62 @@ public: ARMGOTPLTAtom(const File &f) : ARMGOTAtom(f, ".got.plt") {} }; +/// \brief PLT entry atom. +/// Serves as a mapping symbol in the release mode. class ARMPLTAtom : public PLTAtom { public: - ARMPLTAtom(const File &f) : PLTAtom(f, ".plt") {} + ARMPLTAtom(const File &f, const std::string &name) + : PLTAtom(f, ".plt") { +#ifndef NDEBUG + _name = name; +#else + // Don't move the code to any base classes since + // virtual codeModel method would return wrong value. + _name = getMappingAtomName(codeModel(), name); +#endif + } + + DefinedAtom::CodeModel codeModel() const override { +#ifndef NDEBUG + return DefinedAtom::codeNA; +#else + return DefinedAtom::codeARM_a; +#endif + } ArrayRef<uint8_t> rawContent() const override { return llvm::makeArrayRef(ARMPltAtomContent); } Alignment alignment() const override { return 4; } + + StringRef name() const override { return _name; } + +private: + std::string _name; }; +/// \brief Veneer atom for PLT entry. +/// Serves as a mapping symbol in the release mode. class ARMPLTVeneerAtom : public PLTAtom { public: - ARMPLTVeneerAtom(const File &f) : PLTAtom(f, ".plt") {} + ARMPLTVeneerAtom(const File &f, const std::string &name) + : PLTAtom(f, ".plt") { +#ifndef NDEBUG + _name = name; +#else + // Don't move the code to any base classes since + // virtual codeModel method would return wrong value. + _name = getMappingAtomName(codeModel(), name); +#endif + } DefinedAtom::CodeModel codeModel() const override { +#ifndef NDEBUG return DefinedAtom::codeARMThumb; +#else + return DefinedAtom::codeARM_t; +#endif } ArrayRef<uint8_t> rawContent() const override { @@ -165,6 +219,11 @@ public: } Alignment alignment() const override { return 4; } + + StringRef name() const override { return _name; } + +private: + std::string _name; }; class ELFPassFile : public SimpleFile { @@ -295,14 +354,14 @@ protected: /// \brief get a veneer for a PLT entry. const PLTAtom *getPLTVeneer(const DefinedAtom *da, PLTAtom *pa, StringRef source) { - auto va = new (_file._alloc) ARMPLTVeneerAtom(_file); + std::string name = "__plt_from_thumb"; + name += source; + name += da->name(); + // Create veneer for PLT entry. + auto va = new (_file._alloc) ARMPLTVeneerAtom(_file, name); // Fake reference to show connection between veneer and PLT entry. va->addReferenceELF_ARM(R_ARM_NONE, 0, pa, 0); -#ifndef NDEBUG - va->_name = "__plt_from_thumb"; - va->_name += source; - va->_name += da->name(); -#endif + _pltAtoms[da] = PLTWithVeneer(pa, va); return va; } @@ -335,16 +394,15 @@ protected: assert(ga->customSectionName() == ".got.plt" && "GOT entry should be in a special section"); + std::string name = "__plt"; + name += source; + name += da->name(); // Create PLT entry for the GOT entry. - auto pa = new (_file._alloc) ARMPLTAtom(_file); + auto pa = new (_file._alloc) ARMPLTAtom(_file, name); pa->addReferenceELF_ARM(R_ARM_ALU_PC_G0_NC, 0, ga, -8); pa->addReferenceELF_ARM(R_ARM_ALU_PC_G1_NC, 4, ga, -4); pa->addReferenceELF_ARM(R_ARM_LDR_PC_G2, 8, ga, 0); -#ifndef NDEBUG - pa->_name = "__plt"; - pa->_name += source; - pa->_name += da->name(); -#endif + // Since all PLT entries are in ARM code, Thumb to ARM // switching should be added if the relocated place contais Thumb code. if (fromThumb) @@ -371,11 +429,7 @@ protected: /// \brief get the PLT entry for a given IFUNC Atom. const PLTAtom *getIFUNCPLTEntry(const DefinedAtom *da, bool fromThumb) { - StringRef source; -#ifndef NDEBUG - source = "_ifunc_"; -#endif - return getPLTEntry(da, fromThumb, &Derived::createIFUNCGOTEntry, source); + return getPLTEntry(da, fromThumb, &Derived::createIFUNCGOTEntry, "_ifunc_"); } /// \brief Redirect the call to the PLT stub for the target IFUNC. |

