[lld] r199516 - [Mips] Implement .plt and .got.plt section creation.
Rui Ueyama
ruiu at google.com
Fri Jan 17 13:31:48 PST 2014
On Fri, Jan 17, 2014 at 1:18 PM, Simon Atanasyan <simon at atanasyan.com>wrote:
> Author: atanasyan
> Date: Fri Jan 17 15:18:37 2014
> New Revision: 199516
>
> URL: http://llvm.org/viewvc/llvm-project?rev=199516&view=rev
> Log:
> [Mips] Implement .plt and .got.plt section creation.
>
> Added:
> lld/trunk/test/elf/Mips/plt-header.test
> Modified:
> lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
> lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
> lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
> lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
> lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
> lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
> lld/trunk/test/elf/Mips/r26.test
>
> Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp?rev=199516&r1=199515&r2=199516&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp (original)
> +++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp Fri Jan 17
> 15:18:37 2014
> @@ -56,3 +56,16 @@ void MipsLinkingContext::addPasses(PassM
> pm.add(std::move(pass));
> ELFLinkingContext::addPasses(pm);
> }
> +
> +bool MipsLinkingContext::isPLTRelocation(const DefinedAtom &,
> + const Reference &r) const {
> + if (r.kindNamespace() != Reference::KindNamespace::ELF)
> + return false;
> + assert(r.kindArch() == Reference::KindArch::Mips);
> + switch (r.kindValue()) {
> + case llvm::ELF::R_MIPS_JUMP_SLOT:
> + return true;
> + default:
> + return false;
> + }
> +}
>
> Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h?rev=199516&r1=199515&r2=199516&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h (original)
> +++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h Fri Jan 17
> 15:18:37 2014
> @@ -21,7 +21,11 @@ enum {
> /// \brief The same as R_MIPS_GOT16 but for global symbols.
> LLD_R_MIPS_GLOBAL_GOT16 = 1025,
> /// \brief The same as R_MIPS_26 but for global symbols.
> - LLD_R_MIPS_GLOBAL_26 = 1026
> + LLD_R_MIPS_GLOBAL_26 = 1026,
> + /// \brief Setup hi 16 bits using the symbol this reference refers to.
> + LLD_R_MIPS_HI16 = 1027,
> + /// \brief Setup low 16 bits using the symbol this reference refers to.
> + LLD_R_MIPS_LO16 = 1028
> };
>
> typedef llvm::object::ELFType<llvm::support::little, 2, false>
> Mips32ElELFType;
> @@ -41,6 +45,7 @@ public:
> virtual StringRef entrySymbolName() const;
> virtual StringRef getDefaultInterpreter() const;
> virtual void addPasses(PassManager &pm);
> + virtual bool isPLTRelocation(const DefinedAtom &, const Reference &r)
> const;
> };
>
> } // elf
>
> Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp?rev=199516&r1=199515&r2=199516&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
> (original)
> +++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp Fri Jan
> 17 15:18:37 2014
> @@ -105,6 +105,18 @@ void relocCall16(uint8_t *location, uint
> applyReloc(location, result);
> }
>
> +/// \brief LLD_R_MIPS_HI16
> +void relocLldHi16(uint8_t *location, uint64_t S) {
> + int32_t result = lld::scatterBits<uint32_t>((S + 0x8000) >> 16, 0xffff);
>
If my understanding of scatterBits() is correct, this expression is
equivalent to a more plain one: ((S + 0x8000) >> 16) & 0xffff.
+ applyReloc(location, result);
> +}
> +
> +/// \brief LLD_R_MIPS_LO16
> +void relocLldLo16(uint8_t *location, uint64_t S) {
> + int32_t result = lld::scatterBits<uint32_t>(S, 0xffff);
>
Ditto.
> + applyReloc(location, result);
> +}
> +
> } // end anon namespace
>
> MipsTargetRelocationHandler::MipsTargetRelocationHandler(
> @@ -200,6 +212,9 @@ error_code MipsTargetRelocationHandler::
> case R_MIPS_JALR:
> // We do not do JALR optimization now.
> break;
> + case R_MIPS_JUMP_SLOT:
> + // Ignore runtime relocations.
> + break;
> case LLD_R_MIPS_GLOBAL_GOT:
> // Do nothing.
> break;
> @@ -210,6 +225,12 @@ error_code MipsTargetRelocationHandler::
> case LLD_R_MIPS_GLOBAL_26:
> reloc26(location, relocVAddress, targetVAddress, false);
> break;
> + case LLD_R_MIPS_HI16:
> + relocLldHi16(location, targetVAddress);
> + break;
> + case LLD_R_MIPS_LO16:
> + relocLldLo16(location, targetVAddress);
> + break;
> default: {
> std::string str;
> llvm::raw_string_ostream s(str);
>
> Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp?rev=199516&r1=199515&r2=199516&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp (original)
> +++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp Fri Jan 17
> 15:18:37 2014
> @@ -24,6 +24,26 @@ const uint8_t mipsGot0AtomContent[] = {
> // Module pointer
> const uint8_t mipsGotModulePointerAtomContent[] = { 0x00, 0x00, 0x00,
> 0x80 };
>
> +// PLT0 entry
> +const uint8_t mipsPlt0AtomContent[] = {
> + 0x00, 0x00, 0x1c, 0x3c, // lui $28, %hi(&GOTPLT[0])
> + 0x00, 0x00, 0x99, 0x8f, // lw $25, %lo(&GOTPLT[0])($28)
> + 0x00, 0x00, 0x9c, 0x27, // addiu $28, $28, %lo(&GOTPLT[0])
> + 0x23, 0xc0, 0x1c, 0x03, // subu $24, $24, $28
> + 0x21, 0x78, 0xe0, 0x03, // move $15, $31
> + 0x82, 0xc0, 0x18, 0x00, // srl $24, $24, 2
> + 0x09, 0xf8, 0x20, 0x03, // jalr $25
> + 0xfe, 0xff, 0x18, 0x27 // subu $24, $24, 2
> +};
> +
> +// Regular PLT entry
> +const uint8_t mipsPltAAtomContent[] = {
> + 0x00, 0x00, 0x0f, 0x3c, // lui $15, %hi(.got.plt entry)
> + 0x00, 0x00, 0xf9, 0x8d, // l[wd] $25, %lo(.got.plt entry)($15)
> + 0x08, 0x00, 0x20, 0x03, // jr $25
> + 0x00, 0x00, 0xf8, 0x25 // addiu $24, $15, %lo(.got.plt entry)
> +};
> +
> /// \brief Abstract base class represent MIPS GOT entries.
> class MipsGOTAtom : public GOTAtom {
> public:
> @@ -52,6 +72,36 @@ public:
> }
> };
>
> +class PLT0Atom : public PLTAtom {
> +public:
> + PLT0Atom(const File &f) : PLTAtom(f, ".plt") {}
> +
> + virtual ArrayRef<uint8_t> rawContent() const {
> + return llvm::makeArrayRef(mipsPlt0AtomContent);
> + }
> +};
> +
> +class PLTAAtom : public PLTAtom {
> +public:
> + PLTAAtom(const File &f) : PLTAtom(f, ".plt") {}
> +
> + virtual ArrayRef<uint8_t> rawContent() const {
> + return llvm::makeArrayRef(mipsPltAAtomContent);
> + }
> +};
> +
> +/// \brief MIPS GOT PLT entry
> +class GOTPLTAtom : public GOTAtom {
> +public:
> + GOTPLTAtom(const File &f) : GOTAtom(f, ".got.plt") {}
> +
> + virtual Alignment alignment() const { return Alignment(2); }
> +
> + virtual ArrayRef<uint8_t> rawContent() const {
> + return llvm::makeArrayRef(mipsGot0AtomContent);
> + }
> +};
> +
> class RelocationPassFile : public SimpleFile {
> public:
> RelocationPassFile(const ELFLinkingContext &ctx)
> @@ -90,6 +140,20 @@ public:
> got->setOrdinal(ordinal++);
> mf->addAtom(*got);
> }
> +
> + for (auto &plt : _pltVector) {
> + DEBUG_WITH_TYPE("MipsGOT", llvm::dbgs() << "[ PLT ] Adding "
> + << plt->name() << "\n");
> + plt->setOrdinal(ordinal++);
> + mf->addAtom(*plt);
> + }
> +
> + for (auto &gotplt : _gotpltVector) {
> + DEBUG_WITH_TYPE("MipsGOT", llvm::dbgs() << "[ GOTPLT ] Adding "
> + << gotplt->name() << "\n");
> + gotplt->setOrdinal(ordinal++);
> + mf->addAtom(*gotplt);
> + }
> }
>
> private:
> @@ -105,6 +169,15 @@ private:
> /// \brief the list of global GOT atoms.
> std::vector<GOTAtom *> _globalGotVector;
>
> + /// \brief Map Atoms to their PLT entries.
> + llvm::DenseMap<const Atom *, PLTAtom *> _pltMap;
> +
> + /// \brief the list of PLT atoms.
> + std::vector<PLTAtom *> _pltVector;
> +
> + /// \brief the list of GOTPLT atoms.
> + std::vector<GOTAtom *> _gotpltVector;
> +
> /// \brief Handle a specific reference.
> void handleReference(const DefinedAtom &atom, const Reference &ref) {
> if (ref.kindNamespace() != lld::Reference::KindNamespace::ELF)
> @@ -131,7 +204,8 @@ private:
> if (ref.kindValue() == R_MIPS_26 && !isLocal(ref.target()))
> const_cast<Reference &>(ref).setKindValue(LLD_R_MIPS_GLOBAL_26);
>
> - // FIXME (simon): Create PLT entry.
> + if (isa<SharedLibraryAtom>(ref.target()))
> + const_cast<Reference &>(ref).setTarget(getPLTEntry(ref.target()));
> }
>
> void handleGOT(const Reference &ref) {
> @@ -187,6 +261,69 @@ private:
>
> return ga;
> }
> +
> + void createPLTHeader() {
> + assert(_pltVector.empty() && _gotpltVector.empty());
> +
> + auto pa = new (_file._alloc) PLT0Atom(_file);
> + _pltVector.push_back(pa);
> +
> + auto ga0 = new (_file._alloc) GOTPLTAtom(_file);
> + _gotpltVector.push_back(ga0);
> + auto ga1 = new (_file._alloc) GOTPLTAtom(_file);
> + _gotpltVector.push_back(ga1);
> +
> + // Setup reference to fixup the PLT0 entry.
> + pa->addReferenceELF_Mips(LLD_R_MIPS_HI16, 0, ga0, 0);
> + pa->addReferenceELF_Mips(LLD_R_MIPS_LO16, 4, ga0, 0);
> + pa->addReferenceELF_Mips(LLD_R_MIPS_LO16, 8, ga0, 0);
> +
> + DEBUG_WITH_TYPE("MipsGOT", {
> + pa->_name = "__plt0";
> + llvm::dbgs() << "[ PLT ] Create PLT0\n";
> + ga0->_name = "__gotplt0";
> + llvm::dbgs() << "[ GOTPLT ] Create GOTPLT0\n";
> + ga1->_name = "__gotplt1";
> + llvm::dbgs() << "[ GOTPLT ] Create GOTPLT1\n";
> + });
> + }
> +
> + const PLTAtom *getPLTEntry(const Atom *a) {
> + auto plt = _pltMap.find(a);
> + if (plt != _pltMap.end())
> + return plt->second;
> +
> + if (_pltVector.empty())
> + createPLTHeader();
> +
> + auto pa = new (_file._alloc) PLTAAtom(_file);
> + _pltMap[a] = pa;
> + _pltVector.push_back(pa);
> +
> + auto ga = new (_file._alloc) GOTPLTAtom(_file);
> + _gotpltVector.push_back(ga);
> +
> + // Setup reference to fixup the PLT entry.
> + pa->addReferenceELF_Mips(LLD_R_MIPS_HI16, 0, ga, 0);
> + pa->addReferenceELF_Mips(LLD_R_MIPS_LO16, 4, ga, 0);
> + pa->addReferenceELF_Mips(LLD_R_MIPS_LO16, 12, ga, 0);
> +
> + // Setup reference to assign initial value to the .got.plt entry.
> + ga->addReferenceELF_Mips(R_MIPS_32, 0, _pltVector.front(), 0);
> + // Create dynamic relocation to adjust the .got.plt entry at runtime.
> + ga->addReferenceELF_Mips(R_MIPS_JUMP_SLOT, 0, a, 0);
> +
> + DEBUG_WITH_TYPE("MipsGOT", {
> + pa->_name = "__plt_";
> + pa->_name += a->name();
> + llvm::dbgs() << "[ PLT ] Create " << a->name() << "\n";
> + ga->_name = "__got_plt_";
> + ga->_name += a->name();
> + llvm::dbgs() << "[ GOTPLT ] Create " << a->name() << "\n";
> + });
> +
> + return pa;
> + }
> };
>
> } // end anon namespace
>
> Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp?rev=199516&r1=199515&r2=199516&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp (original)
> +++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp Fri Jan 17
> 15:18:37 2014
> @@ -201,8 +201,11 @@ const Registry::KindStrings MipsTargetHa
> LLD_KIND_STRING_ENTRY(R_MIPS_GOT16),
> LLD_KIND_STRING_ENTRY(R_MIPS_CALL16),
> LLD_KIND_STRING_ENTRY(R_MIPS_JALR),
> + LLD_KIND_STRING_ENTRY(R_MIPS_JUMP_SLOT),
> LLD_KIND_STRING_ENTRY(LLD_R_MIPS_GLOBAL_GOT),
> LLD_KIND_STRING_ENTRY(LLD_R_MIPS_GLOBAL_GOT16),
> LLD_KIND_STRING_ENTRY(LLD_R_MIPS_GLOBAL_26),
> + LLD_KIND_STRING_ENTRY(LLD_R_MIPS_HI16),
> + LLD_KIND_STRING_ENTRY(LLD_R_MIPS_LO16),
> LLD_KIND_STRING_END
> };
>
> Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h?rev=199516&r1=199515&r2=199516&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h (original)
> +++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h Fri Jan 17
> 15:18:37 2014
> @@ -35,7 +35,7 @@ public:
> createSection(StringRef name, int32_t type,
> DefinedAtom::ContentPermissions permissions,
> Layout::SectionOrder order) {
> - if (type == DefinedAtom::typeGOT)
> + if (type == DefinedAtom::typeGOT && name == ".got")
> return _gotSection;
> return DefaultLayout<ELFType>::createSection(name, type, permissions,
> order);
>
> Added: lld/trunk/test/elf/Mips/plt-header.test
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/plt-header.test?rev=199516&view=auto
>
> ==============================================================================
> --- lld/trunk/test/elf/Mips/plt-header.test (added)
> +++ lld/trunk/test/elf/Mips/plt-header.test Fri Jan 17 15:18:37 2014
> @@ -0,0 +1,40 @@
> +# Check initialization of .plt header entries.
> +
> +# Build shared library
> +# RUN: llvm-mc -triple=mipsel -filetype=obj -relocation-model=pic \
> +# RUN: -o=%t1 %p/Inputs/ext.s
> +# RUN: lld -flavor gnu -target mipsel -shared -o %t2 %t1
> +
> +# Build executable
> +# RUN: llvm-mc -triple=mipsel -filetype=obj -o=%t3 %s
> +# RUN: lld -flavor gnu -target mipsel -e glob -o %t4 %t3 %t2
> +# RUN: llvm-objdump -section-headers -disassemble %t4 | \
> +# RUN: FileCheck -check-prefix=EXE %s
> +
> +# EXE: Disassembly of section .plt:
> +# EXE: .plt:
> +# PLT0 entry. Points to the .got.plt[0]
> +# EXE: 400170: 40 00 1c 3c lui $gp, 64
> +# EXE: 400174: 00 20 99 8f lw $25, 8192($gp)
> +# EXE: 400178: 00 20 9c 27 addiu $gp, $gp, 8192
> +# EXE: 40017c: 23 c0 1c 03 subu $24, $24, $gp
> +# EXE: 400180: 21 78 e0 03 move $15, $ra
> +# EXE: 400184: 82 c0 18 00 srl $24, $24, 2
> +# EXE: 400188: 09 f8 20 03 jalr $25
> +# EXE: 40018c: fe ff 18 27 addiu $24, $24, -2
> +
> +# EXE: Sections:
> +# EXE: Idx Name Size Address Type
> +# EXE: 6 .plt 00000030 0000000000400170 TEXT DATA
> +# EXE: 10 .got.plt 0000000c 0000000000402000 DATA
> +
> + .abicalls
> + .global glob
> + .ent glob
> +glob:
> + jal $t9
> + jal loc
> +loc:
> + jal glob
> + jal ext1
> + .end glob
>
> Modified: lld/trunk/test/elf/Mips/r26.test
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/r26.test?rev=199516&r1=199515&r2=199516&view=diff
>
> ==============================================================================
> --- lld/trunk/test/elf/Mips/r26.test (original)
> +++ lld/trunk/test/elf/Mips/r26.test Fri Jan 17 15:18:37 2014
> @@ -7,33 +7,58 @@
>
> # Build executable
> # RUN: llvm-mc -triple=mipsel -filetype=obj -o=%t3 %s
> -# RUN: llvm-objdump -r %t3 | FileCheck -check-prefix=REL %s
> +# RUN: llvm-readobj -relocations %t3 | FileCheck -check-prefix=OBJ-REL %s
> # RUN: lld -flavor gnu -target mipsel -e glob -o %t4 %t3 %t2
> -# RUN: llvm-objdump -disassemble %t4 | FileCheck -check-prefix=EXE %s
> +# RUN: llvm-objdump -section-headers -disassemble %t4 | \
> +# RUN: FileCheck -check-prefix=EXE %s
> +# RUN: llvm-readobj -relocations %t4 | FileCheck -check-prefix=EXE-REL %s
>
> # Object file has three R_MIPS_26 relocations
> -# REL: RELOCATION RECORDS FOR [.rel.text]:
> -# REL: 8 R_MIPS_26 Unknown
> -# REL: 16 R_MIPS_26 Unknown
> -# REL: 24 R_MIPS_26 Unknown
> +# OBJ-REL: Relocations [
> +# OBJ-REL: Section (2) .rel.text {
> +# OBJ-REL: 0x8 R_MIPS_26 .text 0x0
> +# OBJ-REL: 0x10 R_MIPS_26 glob 0x0
> +# OBJ-REL: 0x18 R_MIPS_26 ext1 0x0
> +# OBJ-REL: }
> +# OBJ-REL: ]
> +
> +# Executable file has the only relocation for external symbol
> +# EXE-REL: Relocations [
> +# EXE-REL: Section (5) .rela.plt {
> +# EXE-REL: 0x402008 R_MIPS_JUMP_SLOT ext1 0x0
> +# EXE-REL: }
> +# EXE-REL: ]
> +
> +# EXE: Disassembly of section .plt:
> +# EXE: .plt:
> +# PLTA entry. Points to the .got.plt[1]
> +# EXE: 400190: 40 00 0f 3c lui $15, 64
> +# EXE: 400194: 08 20 f9 8d lw $25, 8200($15)
> +# EXE: 400198: 08 00 20 03 jr $25
> +# EXE: 40019c: 08 20 f8 25 addiu $24, $15, 8200
>
> # EXE: Disassembly of section .text:
> # EXE: glob:
> -# EXE: 40014c: 09 f8 20 03 jalr $25
> -# EXE: 400150: 00 00 00 00 nop
> +# EXE: 4001a0: 09 f8 20 03 jalr $25
> +# EXE: 4001a4: 00 00 00 00 nop
> #
> # Jump to 'loc' label address
> -# EXE: 400154: 57 00 10 0c jal 4194652
> -# EXE: 400158: 00 00 00 00 nop
> +# EXE: 4001a8: 6c 00 10 0c jal 4194736
> +# EXE: 4001ac: 00 00 00 00 nop
> #
> # EXE: loc:
> # Jump to 'glob' label address
> -# EXE: 40015c: 53 00 10 0c jal 4194636
> -# EXE: 400160: 00 00 00 00 nop
> +# EXE: 4001b0: 68 00 10 0c jal 4194720
> +# EXE: 4001b4: 00 00 00 00 nop
> #
> # Jump to the first PLT entry (.plt + 32) for ext1 entry
> -# EXE: 400164: 00 00 00 0c jal 0
> -# EXE: 400168: 00 00 00 00 nop
> +# EXE: 4001b8: 64 00 10 0c jal 4194704
> +# EXE: 4001bc: 00 00 00 00 nop
> +
> +# EXE: Sections:
> +# EXE: Idx Name Size Address Type
> +# EXE: 6 .plt 00000030 0000000000400170 TEXT DATA
> +# EXE: 10 .got.plt 0000000c 0000000000402000 DATA
>
> .abicalls
> .global glob
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140117/dfc4826d/attachment.html>
More information about the llvm-commits
mailing list