forked from OSchip/llvm-project
[ELF][PPC32] Fix canonical PLTs when the order does not match the PLT order
Reviewed By: Bdragon28 Differential Revision: https://reviews.llvm.org/D75394
This commit is contained in:
parent
718cbd394a
commit
00925aadb3
|
|
@ -76,12 +76,11 @@ void writePPC32GlinkSection(uint8_t *buf, size_t numEntries) {
|
|||
// non-GOT-non-PLT relocations referencing external functions for -fpie/-fPIE.
|
||||
uint32_t glink = in.plt->getVA(); // VA of .glink
|
||||
if (!config->isPic) {
|
||||
for (const Symbol *sym : in.plt->entries)
|
||||
if (sym->needsPltAddr) {
|
||||
writePPC32PltCallStub(buf, sym->getGotPltVA(), nullptr, 0);
|
||||
buf += 16;
|
||||
glink += 16;
|
||||
}
|
||||
for (const Symbol *sym : cast<PPC32GlinkSection>(in.plt)->canonical_plts) {
|
||||
writePPC32PltCallStub(buf, sym->getGotPltVA(), nullptr, 0);
|
||||
buf += 16;
|
||||
glink += 16;
|
||||
}
|
||||
}
|
||||
|
||||
// On PPC Secure PLT ABI, bl foo@plt jumps to a call stub, which loads an
|
||||
|
|
|
|||
|
|
@ -1226,6 +1226,7 @@ static void processRelocAux(InputSectionBase &sec, RelExpr expr, RelType type,
|
|||
// PPC32 canonical PLT entries are at the beginning of .glink
|
||||
cast<Defined>(sym).value = in.plt->headerSize;
|
||||
in.plt->headerSize += 16;
|
||||
cast<PPC32GlinkSection>(in.plt)->canonical_plts.push_back(&sym);
|
||||
}
|
||||
}
|
||||
sym.needsPltAddr = true;
|
||||
|
|
|
|||
|
|
@ -2447,12 +2447,9 @@ PltSection::PltSection()
|
|||
: SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16, ".plt"),
|
||||
headerSize(target->pltHeaderSize) {
|
||||
// On PowerPC, this section contains lazy symbol resolvers.
|
||||
if (config->emachine == EM_PPC || config->emachine == EM_PPC64) {
|
||||
if (config->emachine == EM_PPC64) {
|
||||
name = ".glink";
|
||||
alignment = 4;
|
||||
// PLTresolve is at the end.
|
||||
if (config->emachine == EM_PPC)
|
||||
footerSize = 64;
|
||||
}
|
||||
|
||||
// On x86 when IBT is enabled, this section contains the second PLT (lazy
|
||||
|
|
@ -2468,11 +2465,6 @@ PltSection::PltSection()
|
|||
}
|
||||
|
||||
void PltSection::writeTo(uint8_t *buf) {
|
||||
if (config->emachine == EM_PPC) {
|
||||
writePPC32GlinkSection(buf, entries.size());
|
||||
return;
|
||||
}
|
||||
|
||||
// At beginning of PLT, we have code to call the dynamic
|
||||
// linker to resolve dynsyms at runtime. Write such code.
|
||||
target->writePltHeader(buf);
|
||||
|
|
@ -2490,7 +2482,7 @@ void PltSection::addEntry(Symbol &sym) {
|
|||
}
|
||||
|
||||
size_t PltSection::getSize() const {
|
||||
return headerSize + entries.size() * target->pltEntrySize + footerSize;
|
||||
return headerSize + entries.size() * target->pltEntrySize;
|
||||
}
|
||||
|
||||
bool PltSection::isNeeded() const {
|
||||
|
|
@ -2544,6 +2536,19 @@ void IpltSection::addSymbols() {
|
|||
}
|
||||
}
|
||||
|
||||
PPC32GlinkSection::PPC32GlinkSection() {
|
||||
name = ".glink";
|
||||
alignment = 4;
|
||||
}
|
||||
|
||||
void PPC32GlinkSection::writeTo(uint8_t *buf) {
|
||||
writePPC32GlinkSection(buf, entries.size());
|
||||
}
|
||||
|
||||
size_t PPC32GlinkSection::getSize() const {
|
||||
return headerSize + entries.size() * target->pltEntrySize + footerSize;
|
||||
}
|
||||
|
||||
// This is an x86-only extra PLT section and used only when a security
|
||||
// enhancement feature called CET is enabled. In this comment, I'll explain what
|
||||
// the feature is and why we have two PLT sections if CET is enabled.
|
||||
|
|
|
|||
|
|
@ -684,7 +684,6 @@ public:
|
|||
size_t getNumEntries() const { return entries.size(); }
|
||||
|
||||
size_t headerSize;
|
||||
size_t footerSize = 0;
|
||||
|
||||
std::vector<const Symbol *> entries;
|
||||
};
|
||||
|
|
@ -705,6 +704,16 @@ public:
|
|||
void addEntry(Symbol &sym);
|
||||
};
|
||||
|
||||
class PPC32GlinkSection : public PltSection {
|
||||
public:
|
||||
PPC32GlinkSection();
|
||||
void writeTo(uint8_t *buf) override;
|
||||
size_t getSize() const override;
|
||||
|
||||
std::vector<const Symbol *> canonical_plts;
|
||||
static constexpr size_t footerSize = 64;
|
||||
};
|
||||
|
||||
// This is x86-only.
|
||||
class IBTPltSection : public SyntheticSection {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -525,7 +525,8 @@ template <class ELFT> void createSyntheticSections() {
|
|||
add(in.ibtPlt);
|
||||
}
|
||||
|
||||
in.plt = make<PltSection>();
|
||||
in.plt = config->emachine == EM_PPC ? make<PPC32GlinkSection>()
|
||||
: make<PltSection>();
|
||||
add(in.plt);
|
||||
in.iplt = make<IpltSection>();
|
||||
add(in.iplt);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
.globl func, ifunc
|
||||
.globl func, func2, ifunc
|
||||
.type func, @function
|
||||
.type func2, @function
|
||||
.type ifunc, @gnu_indirect_function
|
||||
func:
|
||||
func2:
|
||||
ifunc:
|
||||
|
|
|
|||
|
|
@ -14,49 +14,59 @@
|
|||
|
||||
# REL: Relocations [
|
||||
# REL-NEXT: .rela.plt {
|
||||
# REL-NEXT: R_PPC_JMP_SLOT func 0x0
|
||||
# REL-NEXT: R_PPC_JMP_SLOT ifunc 0x0
|
||||
# REL-NEXT: 0x10030318 R_PPC_JMP_SLOT func 0x0
|
||||
# REL-NEXT: 0x1003031C R_PPC_JMP_SLOT func2 0x0
|
||||
# REL-NEXT: 0x10030320 R_PPC_JMP_SLOT ifunc 0x0
|
||||
# REL-NEXT: }
|
||||
# REL-NEXT: ]
|
||||
|
||||
# SYM: .glink PROGBITS 100101dc
|
||||
# SYM: .glink PROGBITS 1001022c
|
||||
|
||||
## st_value points to the canonical PLT entry in .glink
|
||||
# SYM: Symbol table '.dynsym'
|
||||
# SYM: 100101dc 0 FUNC GLOBAL DEFAULT UND func
|
||||
# SYM: 100101ec 0 FUNC GLOBAL DEFAULT UND ifunc
|
||||
# SYM: 1001023c 0 FUNC GLOBAL DEFAULT UND func
|
||||
# SYM: 1001022c 0 FUNC GLOBAL DEFAULT UND func2
|
||||
# SYM: 1001024c 0 FUNC GLOBAL DEFAULT UND ifunc
|
||||
# SYM: Symbol table '.symtab'
|
||||
# SYM: 100101dc 0 FUNC GLOBAL DEFAULT UND func
|
||||
# SYM: 100101ec 0 FUNC GLOBAL DEFAULT UND ifunc
|
||||
# SYM: 1001023c 0 FUNC GLOBAL DEFAULT UND func
|
||||
# SYM: 1001022c 0 FUNC GLOBAL DEFAULT UND func2
|
||||
# SYM: 1001024c 0 FUNC GLOBAL DEFAULT UND ifunc
|
||||
|
||||
# HEX: 0x100302b4 100101fc 10010200
|
||||
# HEX: 0x10030318 1001025c 10010260 10010264
|
||||
|
||||
## Canonical PLT entry of func2.
|
||||
## 0x1003031C = 65536*4099+796
|
||||
# CHECK: 1001022c .glink:
|
||||
# CHECK-NEXT: lis 11, 4099
|
||||
# CHECK-NEXT: lwz 11, 796(11)
|
||||
# CHECK-NEXT: mtctr 11
|
||||
# CHECK-NEXT: bctr
|
||||
|
||||
## Canonical PLT entry of func.
|
||||
## 0x100101dc + 4*2 + 64 = 0x10010224
|
||||
## 0x1001021c = 65536*4099+692
|
||||
# CHECK: 100101dc .glink:
|
||||
# CHECK-NEXT: lis 11, 4099
|
||||
# CHECK-NEXT: lwz 11, 692(11)
|
||||
## 0x10030318 = 65536*4099+792
|
||||
# CHECK-NEXT: 1001023c: lis 11, 4099
|
||||
# CHECK-NEXT: lwz 11, 792(11)
|
||||
# CHECK-NEXT: mtctr 11
|
||||
# CHECK-NEXT: bctr
|
||||
|
||||
## Canonical PLT entry of ifunc.
|
||||
## 0x10010220 = 65536*4099+696
|
||||
# CHECK-NEXT: 100101ec: lis 11, 4099
|
||||
# CHECK-NEXT: lwz 11, 696(11)
|
||||
## 0x10030320 = 65536*4099+800
|
||||
# CHECK-NEXT: 1001024c: lis 11, 4099
|
||||
# CHECK-NEXT: lwz 11, 800(11)
|
||||
# CHECK-NEXT: mtctr 11
|
||||
# CHECK-NEXT: bctr
|
||||
|
||||
## The 2 b instructions are referenced by .plt entries.
|
||||
# CHECK-NEXT: 100101fc: b .+8
|
||||
## The 3 b instructions are referenced by .plt entries.
|
||||
# CHECK-NEXT: 1001025c: b .+12
|
||||
# CHECK-NEXT: b .+8
|
||||
# CHECK-NEXT: b .+4
|
||||
|
||||
## PLTresolve of 64 bytes is at the end.
|
||||
## Operands of addis & addi: -0x100101fc = 65536*-4097-508
|
||||
## Operands of addis & addi: -0x1001025c = 65536*-4097-604
|
||||
# CHECK-NEXT: lis 12, 0
|
||||
# CHECK-NEXT: addis 11, 11, -4097
|
||||
# CHECK-NEXT: lwz 0, 4(12)
|
||||
# CHECK-NEXT: addi 11, 11, -508
|
||||
# CHECK-NEXT: addi 11, 11, -604
|
||||
# CHECK-NEXT: mtctr 0
|
||||
# CHECK-NEXT: add 0, 11, 11
|
||||
# CHECK-NEXT: lwz 12, 8(12)
|
||||
|
|
@ -66,6 +76,9 @@
|
|||
|
||||
.globl _start
|
||||
_start:
|
||||
b func
|
||||
lis 3, func2@ha
|
||||
la 3, func2@l(3)
|
||||
lis 3, func@ha
|
||||
la 3, func@l(3)
|
||||
lis 4, ifunc@ha
|
||||
|
|
|
|||
Loading…
Reference in New Issue