Index: ELF/OutputSections.h =================================================================== --- ELF/OutputSections.h +++ ELF/OutputSections.h @@ -117,6 +117,23 @@ }; template +class GotPltSection final : public OutputSectionBase { + typedef OutputSectionBase Base; + typedef typename Base::uintX_t uintX_t; + +public: + GotPltSection(); + void finalize() override; + void writeTo(uint8_t *Buf) override; + void addEntry(SymbolBody *Sym); + bool empty() const; + uintX_t getEntryAddr(const SymbolBody &B) const; + +private: + std::vector Entries; +}; + +template class PltSection final : public OutputSectionBase { typedef OutputSectionBase Base; typedef typename Base::uintX_t uintX_t; @@ -172,7 +189,7 @@ typedef typename llvm::object::ELFFile::uintX_t uintX_t; public: - RelocationSection(bool IsRela); + RelocationSection(StringRef Name, bool IsRela); void addReloc(const DynamicReloc &Reloc) { Relocs.push_back(Reloc); } void finalize() override; void writeTo(uint8_t *Buf) override; @@ -285,11 +302,13 @@ template struct Out { static DynamicSection *Dynamic; static GotSection *Got; + static GotPltSection *GotPlt; static HashTableSection *HashTab; static InterpSection *Interp; static OutputSection *Bss; static PltSection *Plt; static RelocationSection *RelaDyn; + static RelocationSection *RelaPlt; static StringTableSection *DynStrTab; static StringTableSection *StrTab; static SymbolTableSection *DynSymTab; @@ -298,11 +317,13 @@ template DynamicSection *Out::Dynamic; template GotSection *Out::Got; +template GotPltSection *Out::GotPlt; template HashTableSection *Out::HashTab; template InterpSection *Out::Interp; template OutputSection *Out::Bss; template PltSection *Out::Plt; template RelocationSection *Out::RelaDyn; +template RelocationSection *Out::RelaPlt; template StringTableSection *Out::DynStrTab; template StringTableSection *Out::StrTab; template SymbolTableSection *Out::DynSymTab; Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -30,6 +30,48 @@ } template +GotPltSection::GotPltSection() + : OutputSectionBase(".got.plt", llvm::ELF::SHT_PROGBITS, + llvm::ELF::SHF_ALLOC | + llvm::ELF::SHF_WRITE) { + this->Header.sh_addralign = this->getAddrSize(); + // .got.plt has 3 reserved entry + Entries.push_back(nullptr); + Entries.push_back(nullptr); + Entries.push_back(nullptr); +} + +template void GotPltSection::addEntry(SymbolBody *Sym) { + Sym->GotIndex = Entries.size(); + Entries.push_back(Sym); +} + +template bool GotPltSection::empty() const { + return Entries.size() == 3; +} + +template +typename GotPltSection::uintX_t +GotPltSection::getEntryAddr(const SymbolBody &B) const { + return this->getVA() + B.GotIndex * this->getAddrSize(); +} + +template void GotPltSection::finalize() { + this->Header.sh_size = Entries.size() * this->getAddrSize(); +} + +template void GotPltSection::writeTo(uint8_t *Buf) { + for (const SymbolBody *B : Entries) { + uint8_t *Entry = Buf; + Buf += sizeof(uintX_t); + if (B) { + uint64_t Plt = Out::Plt->getEntryAddr(*B); + Target->writeGotPltEntry(Entry, Plt); + } + } +} + +template GotSection::GotSection() : OutputSectionBase(".got", llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | @@ -69,10 +111,15 @@ template void PltSection::writeTo(uint8_t *Buf) { uint8_t *Start = Buf; + + // first write PLT[0] entry which is special + Target->writePltBaseEntry(Buf, Out::GotPlt->getVA(), this->getVA()); + Buf += Target->getPltBaseSize(); + for (const SymbolBody *E : Entries) { - uint64_t Got = Out::Got->getEntryAddr(*E); + uint64_t Got = Out::GotPlt->getEntryAddr(*E); uint64_t Plt = Buf - Start + this->getVA(); - Target->writePltEntry(Buf, Got, Plt); + Target->writePltEntry(Buf, Got, Plt, E->PltIndex); Buf += Target->getPltEntrySize(); } } @@ -85,19 +132,20 @@ template typename PltSection::uintX_t PltSection::getEntryAddr(const SymbolBody &B) const { - return this->getVA() + B.PltIndex * Target->getPltEntrySize(); + return this->getVA() + Target->getPltBaseSize() + + B.PltIndex * Target->getPltEntrySize(); } template void PltSection::finalize() { - this->Header.sh_size = Entries.size() * Target->getPltEntrySize(); + this->Header.sh_size = + Target->getPltBaseSize() + Entries.size() * Target->getPltEntrySize(); } template -RelocationSection::RelocationSection(bool IsRela) - : OutputSectionBase(IsRela ? ".rela.dyn" : ".rel.dyn", - IsRela ? llvm::ELF::SHT_RELA - : llvm::ELF::SHT_REL, +RelocationSection::RelocationSection(StringRef Name, bool IsRela) + : OutputSectionBase(Name, IsRela ? llvm::ELF::SHT_RELA + : llvm::ELF::SHT_REL, llvm::ELF::SHF_ALLOC), IsRela(IsRela) { this->Header.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); @@ -137,10 +185,16 @@ } if (Body && Target->relocNeedsGot(Type, *Body)) { - P->r_offset = Out::Got->getEntryAddr(*Body); + bool NeedsPlt = Target->relocNeedsPlt(Type, *Body); + if (NeedsPlt) + P->r_offset = Out::GotPlt->getEntryAddr(*Body); + else + P->r_offset = Out::Got->getEntryAddr(*Body); if (CanBePreempted) P->setSymbolAndType(Body->getDynamicSymbolTableIndex(), - Target->getGotReloc(), IsMips64EL); + NeedsPlt ? Target->getPltReloc() + : Target->getGotReloc(), + IsMips64EL); } else { if (IsRela) Addend += static_cast(RI).r_addend; @@ -257,6 +311,12 @@ ++NumEntries; // DT_RELASZ / DT_RELSZ ++NumEntries; // DT_RELAENT / DT_RELENT } + if (Out::RelaPlt->hasRelocs()) { + ++NumEntries; // DT_JMPREL + ++NumEntries; // DT_PLTRELSZ + ++NumEntries; // DT_PLTGOT + ++NumEntries; // DT_PLTREL + } ++NumEntries; // DT_SYMTAB ++NumEntries; // DT_SYMENT ++NumEntries; // DT_STRTAB @@ -325,7 +385,12 @@ WriteVal(IsRela ? DT_RELAENT : DT_RELENT, IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel)); } - + if (Out::RelaPlt->hasRelocs()) { + WritePtr(DT_JMPREL, Out::RelaPlt->getVA()); + WriteVal(DT_PLTRELSZ, Out::RelaPlt->getSize()); + WritePtr(DT_PLTGOT, Out::Got->getVA()); + WriteVal(DT_PLTREL, Out::RelaPlt->isRela() ? DT_RELA : DT_REL); + } WritePtr(DT_SYMTAB, Out::DynSymTab->getVA()); WritePtr(DT_SYMENT, sizeof(Elf_Sym)); WritePtr(DT_STRTAB, Out::DynStrTab->getVA()); @@ -694,6 +759,11 @@ template class GotSection; template class GotSection; +template class GotPltSection; +template class GotPltSection; +template class GotPltSection; +template class GotPltSection; + template class PltSection; template class PltSection; template class PltSection; Index: ELF/Target.h =================================================================== --- ELF/Target.h +++ ELF/Target.h @@ -25,11 +25,16 @@ uint64_t getVAStart() const { return VAStart; } unsigned getPCRelReloc() const { return PCRelReloc; } unsigned getGotReloc() const { return GotReloc; } + unsigned getPltReloc() const { return PltReloc; } unsigned getGotRefReloc() const { return GotRefReloc; } unsigned getRelativeReloc() const { return RelativeReloc; } + unsigned getPltBaseSize() const { return PltBaseSize; } unsigned getPltEntrySize() const { return PltEntrySize; } + virtual void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const = 0; + virtual void writePltBaseEntry(uint8_t *Buf, uint64_t GotEntryAddr, + uint64_t PltEntryAddr) const = 0; virtual void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const = 0; + uint64_t PltEntryAddr, int32_t Index) const = 0; virtual bool isRelRelative(uint32_t Type) const; virtual bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const = 0; virtual bool relocPointsToGot(uint32_t Type) const; @@ -45,16 +50,21 @@ unsigned PCRelReloc; unsigned GotRefReloc; unsigned GotReloc; + unsigned PltReloc; unsigned RelativeReloc; unsigned PltEntrySize = 8; + unsigned PltBaseSize = 16; llvm::StringRef DefaultEntry = "_start"; }; class X86TargetInfo final : public TargetInfo { public: X86TargetInfo(); + void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override; + void writePltBaseEntry(uint8_t *Buf, uint64_t GotEntryAddr, + uint64_t PltEntryAddr) const override; void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const override; + uint64_t PltEntryAddr, int32_t Index) const override; bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; bool relocPointsToGot(uint32_t Type) const override; bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; @@ -65,8 +75,11 @@ class X86_64TargetInfo final : public TargetInfo { public: X86_64TargetInfo(); + void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override; + void writePltBaseEntry(uint8_t *Buf, uint64_t GotEntryAddr, + uint64_t PltEntryAddr) const override; void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const override; + uint64_t PltEntryAddr, int32_t Index) const override; bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; void relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type, @@ -77,8 +90,11 @@ class PPC64TargetInfo final : public TargetInfo { public: PPC64TargetInfo(); + void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override; + void writePltBaseEntry(uint8_t *Buf, uint64_t GotEntryAddr, + uint64_t PltEntryAddr) const override; void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const override; + uint64_t PltEntryAddr, int32_t Index) const override; bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; void relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type, @@ -88,8 +104,11 @@ class PPCTargetInfo final : public TargetInfo { public: PPCTargetInfo(); + void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override; + void writePltBaseEntry(uint8_t *Buf, uint64_t GotEntryAddr, + uint64_t PltEntryAddr) const override; void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const override; + uint64_t PltEntryAddr, int32_t Index) const override; bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; void relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type, @@ -99,8 +118,11 @@ class ARMTargetInfo final : public TargetInfo { public: ARMTargetInfo(); + void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override; + void writePltBaseEntry(uint8_t *Buf, uint64_t GotEntryAddr, + uint64_t PltEntryAddr) const override; void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const override; + uint64_t PltEntryAddr, int32_t Index) const override; bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; void relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type, @@ -110,8 +132,11 @@ class AArch64TargetInfo final : public TargetInfo { public: AArch64TargetInfo(); + void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override; + void writePltBaseEntry(uint8_t *Buf, uint64_t GotEntryAddr, + uint64_t PltEntryAddr) const override; void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const override; + uint64_t PltEntryAddr, int32_t Index) const override; bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; void relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type, @@ -121,8 +146,11 @@ class MipsTargetInfo final : public TargetInfo { public: MipsTargetInfo(); + void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override; + void writePltBaseEntry(uint8_t *Buf, uint64_t GotEntryAddr, + uint64_t PltEntryAddr) const override; void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const override; + uint64_t PltEntryAddr, int32_t Index) const override; bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; void relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type, Index: ELF/Target.cpp =================================================================== --- ELF/Target.cpp +++ ELF/Target.cpp @@ -37,11 +37,17 @@ PCRelReloc = R_386_PC32; GotReloc = R_386_GLOB_DAT; GotRefReloc = R_386_GOT32; + PltReloc = R_386_JUMP_SLOT; VAStart = 0x10000; } +void X86TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {} + +void X86TargetInfo::writePltBaseEntry(uint8_t *Buf, uint64_t GotEntryAddr, + uint64_t PltEntryAddr) const {}; + void X86TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const { + uint64_t PltEntryAddr, int32_t Index) const { // jmpl *val; nop; nop const uint8_t Inst[] = {0xff, 0x25, 0, 0, 0, 0, 0x90, 0x90}; memcpy(Buf, Inst, sizeof(Inst)); @@ -91,7 +97,9 @@ PCRelReloc = R_X86_64_PC32; GotReloc = R_X86_64_GLOB_DAT; GotRefReloc = R_X86_64_PC32; + PltReloc = R_X86_64_JUMP_SLOT; RelativeReloc = R_X86_64_RELATIVE; + PltEntrySize = 16; // On freebsd x86_64 the first page cannot be mmaped. // On linux that is controled by vm.mmap_min_addr. At least on some x86_64 @@ -102,16 +110,55 @@ VAStart = 0x10000; } +void X86_64TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const { + // Skip 6 bytes of "jmpq *got(%rip)" + write32le(Buf, Plt + 6); +} + +void X86_64TargetInfo::writePltBaseEntry(uint8_t *Buf, uint64_t GotEntryAddr, + uint64_t PltEntryAddr) const { + const uint8_t PltData[] = { + 0xff, 0x35, 0x00, 0x00, 0x00, 0x00, // pushq GOT+8(%rip) + 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *GOT+16(%rip) + 0x0f, 0x1f, 0x40, 0x00 // nopl 0x0(rax) + }; + memcpy(Buf, PltData, sizeof(PltData)); + + uint64_t NextPC = PltEntryAddr + 6; + int64_t Delta = GotEntryAddr - NextPC + 8; //GOT + 8 + assert(isInt<32>(Delta)); + write32le(Buf + 2, Delta); + Buf += 6; + + NextPC += 6; + Delta = GotEntryAddr - NextPC + 16; //GOT + 16 + write32le(Buf + 2, Delta); + Buf += 6; +} + void X86_64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const { - // jmpq *val(%rip); nop; nop - const uint8_t Inst[] = {0xff, 0x25, 0, 0, 0, 0, 0x90, 0x90}; + uint64_t PltEntryAddr, int32_t Index) const { + const uint8_t Inst[] = { + 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmpq *got(%rip) + 0x68, 0x00, 0x00, 0x00, 0x00, // pushq reloc-index + 0xe9, 0x00, 0x00, 0x00, 0x00 // jmpq plt[0] + }; memcpy(Buf, Inst, sizeof(Inst)); uint64_t NextPC = PltEntryAddr + 6; int64_t Delta = GotEntryAddr - NextPC; assert(isInt<32>(Delta)); write32le(Buf + 2, Delta); + Buf += 6; + + NextPC += 5; + write32le(Buf + 1, Index); + Buf += 5; + + NextPC += 5; + Delta = PltEntryAddr - Index * PltEntrySize - PltBaseSize - NextPC; + assert(isInt<32>(Delta)); + write32le(Buf + 1, Delta); } bool X86_64TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const { @@ -201,12 +248,17 @@ PPC64TargetInfo::PPC64TargetInfo() { // PCRelReloc = FIXME // GotReloc = FIXME + // PltReloc = FIXME PltEntrySize = 32; PageSize = 65536; VAStart = 0x10000000; } + +void PPC64TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {} +void PPC64TargetInfo::writePltBaseEntry(uint8_t *Buf, uint64_t GotEntryAddr, + uint64_t PltEntryAddr) const {}; void PPC64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const {} + uint64_t PltEntryAddr, int32_t Index) const {} bool PPC64TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const { return false; } @@ -236,11 +288,16 @@ PPCTargetInfo::PPCTargetInfo() { // PCRelReloc = FIXME // GotReloc = FIXME + // PltReloc = FIXME PageSize = 65536; VAStart = 0x10000000; } + +void PPCTargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {} +void PPCTargetInfo::writePltBaseEntry(uint8_t *Buf, uint64_t GotEntryAddr, + uint64_t PltEntryAddr) const {}; void PPCTargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const {} + uint64_t PltEntryAddr, int32_t Index) const {} bool PPCTargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const { return false; } @@ -253,10 +310,15 @@ ARMTargetInfo::ARMTargetInfo() { // PCRelReloc = FIXME // GotReloc = FIXME + // PltReloc = FIXME VAStart = 0x8000; } + +void ARMTargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {} +void ARMTargetInfo::writePltBaseEntry(uint8_t *Buf, uint64_t GotEntryAddr, + uint64_t PltEntryAddr) const {}; void ARMTargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const {} + uint64_t PltEntryAddr, int32_t Index) const {} bool ARMTargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const { return false; } @@ -269,10 +331,16 @@ AArch64TargetInfo::AArch64TargetInfo() { // PCRelReloc = FIXME // GotReloc = FIXME + // PltReloc = FIXME VAStart = 0x400000; } + +void AArch64TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {} +void AArch64TargetInfo::writePltBaseEntry(uint8_t *Buf, uint64_t GotEntryAddr, + uint64_t PltEntryAddr) const {}; void AArch64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const {} + uint64_t PltEntryAddr, + int32_t Index) const {} bool AArch64TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const { return false; @@ -348,13 +416,20 @@ MipsTargetInfo::MipsTargetInfo() { // PCRelReloc = FIXME // GotReloc = FIXME + // PltReloc = FIXME DefaultEntry = "__start"; PageSize = 65536; VAStart = 0x400000; } +void MipsTargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {} + +void MipsTargetInfo::writePltBaseEntry(uint8_t *Buf, uint64_t GotEntryAddr, + uint64_t PltEntryAddr) const {} + void MipsTargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, - uint64_t PltEntryAddr) const {} + uint64_t PltEntryAddr, int32_t Index) const { +} bool MipsTargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const { return false; Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -98,6 +98,8 @@ Out::Bss = &Bss; GotSection Got; Out::Got = &Got; + GotPltSection GotPlt; + Out::GotPlt = &GotPlt; PltSection Plt; Out::Plt = &Plt; SymbolTableSection SymTab(*Symtab, *Out::StrTab); @@ -106,8 +108,11 @@ Out::DynSymTab = &DynSymTab; HashTableSection HashTab; Out::HashTab = &HashTab; - RelocationSection RelaDyn(Symtab->shouldUseRela()); + bool IsRela = Symtab->shouldUseRela(); + RelocationSection RelaDyn(IsRela ? ".rela.dyn" : ".rel.dyn", IsRela); Out::RelaDyn = &RelaDyn; + RelocationSection RelaPlt(IsRela ? ".rela.plt" : ".rel.plt", IsRela); + Out::RelaPlt = &RelaPlt; DynamicSection Dynamic(*Symtab); Out::Dynamic = &Dynamic; @@ -187,8 +192,8 @@ if (Body->isInPlt()) continue; Out::Plt->addEntry(Body); - } - if (Target->relocNeedsGot(Type, *Body)) { + Out::GotPlt->addEntry(Body); + } else if (Target->relocNeedsGot(Type, *Body)) { if (Body->isInGot()) continue; Out::Got->addEntry(Body); @@ -200,7 +205,10 @@ continue; if (CBP) Body->setUsedInDynamicReloc(); - Out::RelaDyn->addReloc({C, RI}); + if (Body && Target->relocNeedsPlt(Type, *Body)) + Out::RelaPlt->addReloc({ C, RI }); + else + Out::RelaDyn->addReloc({ C, RI }); } } @@ -428,9 +436,13 @@ OutputSections.push_back(Out::DynStrTab); if (Out::RelaDyn->hasRelocs()) OutputSections.push_back(Out::RelaDyn); + if (Out::RelaPlt->hasRelocs()) + OutputSections.push_back(Out::RelaPlt); } if (!Out::Got->empty()) OutputSections.push_back(Out::Got); + if (!Out::GotPlt->empty()) + OutputSections.push_back(Out::GotPlt); if (!Out::Plt->empty()) OutputSections.push_back(Out::Plt); Index: test/elf2/plt-i686.s =================================================================== --- test/elf2/plt-i686.s +++ test/elf2/plt-i686.s @@ -14,42 +14,51 @@ // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x11010 // CHECK-NEXT: Offset: -// CHECK-NEXT: Size: 16 +// CHECK-NEXT: Size: 32 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 16 // CHECK: Relocations [ -// CHECK-NEXT: Section ({{.*}}) .rel.dyn { -// CHECK-NEXT: 0x12050 R_386_GLOB_DAT bar 0x0 -// CHECK-NEXT: 0x12054 R_386_GLOB_DAT zed 0x0 +// CHECK-NEXT: Section ({{.*}}) .rel.plt { +// CHECK-NEXT: 0x12064 R_386_JUMP_SLOT bar 0x0 +// CHECK-NEXT: 0x12068 R_386_JUMP_SLOT zed 0x0 // CHECK-NEXT: } // CHECK-NEXT: ] // Unfortunately FileCheck can't do math, so we have to check for explicit // values: -// 0x11010 - (0x11000 + 1) - 4 = 11 -// 0x11010 - (0x11005 + 1) - 4 = 2 -// 0x11018 - (0x1100a + 1) - 4 = 9 +// 16 is the size of PLT[0] +// (0x11010 + 16) - (0x11000 + 1) - 4 = 11 +// (0x11010 + 16) - (0x11005 + 1) - 4 = 22 +// (0x11018 + 16) - (0x1100a + 1) - 4 = 25 // DISASM: _start: -// DISASM-NEXT: 11000: e9 0b 00 00 00 jmp 11 -// DISASM-NEXT: 11005: e9 06 00 00 00 jmp 6 -// DISASM-NEXT: 1100a: e9 09 00 00 00 jmp 9 +// DISASM-NEXT: 11000: e9 1b 00 00 00 jmp 27 +// DISASM-NEXT: 11005: e9 16 00 00 00 jmp 22 +// DISASM-NEXT: 1100a: e9 19 00 00 00 jmp 25 -// 0x12050 = 73808 -// 0x12054 = 73812 +// 0x12064 = 73828 +// 0x12068 = 73832 // DISASM: Disassembly of section .plt: // DISASM-NEXT: .plt: -// DISASM-NEXT: 11010: ff 25 {{.*}} jmpl *73808 -// DISASM-NEXT: 11016: 90 nop -// DISASM-NEXT: 11017: 90 nop -// DISASM-NEXT: 11018: ff 25 {{.*}} jmpl *73812 -// DISASM-NEXT: 1101e: 90 nop -// DISASM-NEXT: 1101f: 90 nop - +// DISASM-NEXT: 11010: 00 00 addb %al, (%eax) +// DISASM-NEXT: 11012: 00 00 addb %al, (%eax) +// DISASM-NEXT: 11014: 00 00 addb %al, (%eax) +// DISASM-NEXT: 11016: 00 00 addb %al, (%eax) +// DISASM-NEXT: 11018: 00 00 addb %al, (%eax) +// DISASM-NEXT: 1101a: 00 00 addb %al, (%eax) +// DISASM-NEXT: 1101c: 00 00 addb %al, (%eax) +// DISASM-NEXT: 1101e: 00 00 addb %al, (%eax) +// DISASM-NEXT: 11020: ff 25 64 20 01 00 jmpl *73828 +// DISASM-NEXT: 11026: 90 nop +// DISASM-NEXT: 11027: 90 nop +// DISASM-NEXT: 11028: ff 25 68 20 01 00 jmpl *73832 +// DISASM-NEXT: 1102e: 90 nop +// DISASM-NEXT: 1102f: 90 nop + .global _start _start: jmp bar@PLT Index: test/elf2/plt.s =================================================================== --- test/elf2/plt.s +++ test/elf2/plt.s @@ -14,42 +14,49 @@ // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x1020 // CHECK-NEXT: Offset: -// CHECK-NEXT: Size: 24 +// CHECK-NEXT: Size: 64 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 16 // CHECK: Relocations [ -// CHECK-NEXT: Section ({{.*}}) .rela.dyn { -// CHECK-NEXT: 0x20A0 R_X86_64_GLOB_DAT bar 0x0 -// CHECK-NEXT: 0x20A8 R_X86_64_GLOB_DAT zed 0x0 -// CHECK-NEXT: 0x20B0 R_X86_64_GLOB_DAT _start 0x0 +// CHECK-NEXT: Section ({{.*}}) .rela.plt { +// CHECK-NEXT: 0x20C8 R_X86_64_JUMP_SLOT bar 0x0 +// CHECK-NEXT: 0x20D0 R_X86_64_JUMP_SLOT zed 0x0 +// CHECK-NEXT: 0x20D8 R_X86_64_JUMP_SLOT _start 0x0 // CHECK-NEXT: } // CHECK-NEXT: ] // Unfortunately FileCheck can't do math, so we have to check for explicit // values: -// 0x11020 - (0x11000 + 1) - 4 = 27 -// 0x11020 - (0x11005 + 1) - 4 = 22 -// 0x11028 - (0x1100a + 1) - 4 = 25 +// 0x1030 - (0x1000 + 5) = 43 +// 0x1030 - (0x1005 + 5) = 38 +// 0x1040 - (0x100a + 5) = 49 // DISASM: _start: -// DISASM-NEXT: 1000: e9 {{.*}} jmp 27 -// DISASM-NEXT: 1005: e9 {{.*}} jmp 22 -// DISASM-NEXT: 100a: e9 {{.*}} jmp 25 +// DISASM-NEXT: 1000: e9 {{.*}} jmp 43 +// DISASM-NEXT: 1005: e9 {{.*}} jmp 38 +// DISASM-NEXT: 100a: e9 {{.*}} jmp 49 -// 0x120A0 - 0x11026 = 4218 -// 0x120A8 - 0x1102e = 4218 +// 0x20C8 - 0x1036 = 4242 +// 0x20D0 - 0x1046 = 4234 // DISASM: Disassembly of section .plt: // DISASM-NEXT: .plt: -// DISASM-NEXT: 1020: ff 25 {{.*}} jmpq *4218(%rip) -// DISASM-NEXT: 1026: 90 nop -// DISASM-NEXT: 1027: 90 nop -// DISASM-NEXT: 1028: ff 25 {{.*}} jmpq *4218(%rip) -// DISASM-NEXT: 102e: 90 nop -// DISASM-NEXT: 102f: 90 nop +// DISASM-NEXT: 1020: ff 35 92 10 00 00 pushq 4242(%rip) +// DISASM-NEXT: 1026: ff 25 94 10 00 00 jmpq *4244(%rip) +// DISASM-NEXT: 102c: 0f 1f 40 00 nopl (%rax) +// DISASM-NEXT: 1030: ff 25 92 10 00 00 jmpq *4242(%rip) +// DISASM-NEXT: 1036: 68 00 00 00 00 pushq $0 +// DISASM-NEXT: 103b: e9 e0 ff ff ff jmp -32 +// DISASM-NEXT: 1040: ff 25 8a 10 00 00 jmpq *4234(%rip) +// DISASM-NEXT: 1046: 68 01 00 00 00 pushq $1 +// DISASM-NEXT: 104b: e9 d0 ff ff ff jmp -48 +// DISASM-NEXT: 1050: ff 25 82 10 00 00 jmpq *4226(%rip) +// DISASM-NEXT: 1056: 68 02 00 00 00 pushq $2 +// DISASM-NEXT: 105b: e9 c0 ff ff ff jmp -64 + .global _start _start: Index: test/elf2/relocation-i686.s =================================================================== --- test/elf2/relocation-i686.s +++ test/elf2/relocation-i686.s @@ -47,7 +47,7 @@ // ADDR-NEXT: ] // ADDR-NEXT: Address: 0x11030 // ADDR-NEXT: Offset: 0x1030 -// ADDR-NEXT: Size: 8 +// ADDR-NEXT: Size: 24 // ADDR: Name: .got // ADDR-NEXT: Type: SHT_PROGBITS @@ -55,24 +55,24 @@ // ADDR-NEXT: SHF_ALLOC // ADDR-NEXT: SHF_WRITE // ADDR-NEXT: ] -// ADDR-NEXT: Address: 0x12050 +// ADDR-NEXT: Address: 0x12070 .section .R_386_GOTPC,"ax",@progbits R_386_GOTPC: movl $_GLOBAL_OFFSET_TABLE_, %eax -// 0x12050 - 0x11014 = 4156 +// 0x12070 - 0x11014 = 4188 // CHECK: Disassembly of section .R_386_GOTPC: // CHECK-NEXT: R_386_GOTPC: -// CHECK-NEXT: 11014: {{.*}} movl $4156, %eax +// CHECK-NEXT: 11014: {{.*}} movl $4188, %eax .section .dynamic_reloc, "ax",@progbits call bar -// 0x11030 - (0x11019 + 5) = 18 +// (0x11030 + 16) - (0x11019 + 5) = 34 // CHECK: Disassembly of section .dynamic_reloc: // CHECK-NEXT: .dynamic_reloc: -// CHECK-NEXT: 11019: e8 12 00 00 00 calll 18 +// CHECK-NEXT: 11019: e8 22 00 00 00 calll 34 .section .R_386_GOT32,"ax",@progbits .global R_386_GOT32 Index: test/elf2/relocation.s =================================================================== --- test/elf2/relocation.s +++ test/elf2/relocation.s @@ -14,23 +14,39 @@ // SEC-NEXT: ] // SEC-NEXT: Address: 0x11020 // SEC-NEXT: Offset: 0x1020 -// SEC-NEXT: Size: 8 +// SEC-NEXT: Size: 32 -// SEC: Name: .got +// SEC: Name: .got // SEC-NEXT: Type: SHT_PROGBITS // SEC-NEXT: Flags [ // SEC-NEXT: SHF_ALLOC // SEC-NEXT: SHF_WRITE // SEC-NEXT: ] -// SEC-NEXT: Address: 0x120A0 +// SEC-NEXT: Address: 0x120E0 // SEC-NEXT: Offset: -// SEC-NEXT: Size: 16 +// SEC-NEXT: Size: 8 // SEC-NEXT: Link: 0 // SEC-NEXT: Info: 0 // SEC-NEXT: AddressAlignment: 8 // SEC-NEXT: EntrySize: 0 // SEC-NEXT: } +// SEC: Name: .got.plt +// SEC-NEXT: Type: SHT_PROGBITS +// SEC-NEXT: Flags [ +// SEC-NEXT: SHF_ALLOC +// SEC-NEXT: SHF_WRITE +// SEC-NEXT: ] +// SEC-NEXT: Address: 0x120E8 +// SEC-NEXT: Offset: 0x20E8 +// SEC-NEXT: Size: 32 +// SEC-NEXT: Link: 0 +// SEC-NEXT: Info: 0 +// SEC-NEXT: AddressAlignment: 8 +// SEC-NEXT: EntrySize: 0 +// SEC-NEXT: } + + .section .text,"ax",@progbits,unique,1 .global _start _start: @@ -75,10 +91,11 @@ .global R_X86_64_PC32 R_X86_64_PC32: call bar -// 0x11020 - (0x11017 + 5) = 4 +// (0x11020 + 16) - (0x11017 + 5) = 20 +// 16 - is a size of PLT[0] // CHECK: Disassembly of section .R_X86_64_PC32: // CHECK-NEXT: R_X86_64_PC32: -// CHECK-NEXT: 11017: e8 04 00 00 00 callq 4 +// CHECK-NEXT: 11017: e8 14 00 00 00 callq 20 .section .R_X86_64_64,"a",@progbits .global R_X86_64_64 @@ -93,7 +110,7 @@ R_X86_64_GOTPCREL: .long zed@gotpcrel -// 0x120A8 - 0x10160 = 8008 -// 8008 = 0x481f0000 in little endian +// 0x120E0 - 0x10160 = 8064 +// 8064 = 0x801f0000 in little endian // CHECK: Contents of section .R_X86_64_GOTPCREL -// CHECK-NEXT: 10160 481f0000 +// CHECK-NEXT: 10160 801f0000