mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-04 11:27:34 +00:00
[llvm-readobj][ELF] Show MIPS GOT content when there is another zero-sized section at the same address
It is possible to have .got section and one or more zero-sized section at the same address. This patch first checks that GOT (or GOT PLT) section should have non-zero size using corresponding dynamic tags. Then it looks up not empty section at the specified address. Differential Revision: http://reviews.llvm.org/D16968 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@260245 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
23b546ba0d
commit
30b32053a4
BIN
test/tools/llvm-readobj/Inputs/got-over.exe.elf-mips
Executable file
BIN
test/tools/llvm-readobj/Inputs/got-over.exe.elf-mips
Executable file
Binary file not shown.
45
test/tools/llvm-readobj/mips-got-overlapped.test
Normal file
45
test/tools/llvm-readobj/mips-got-overlapped.test
Normal file
@ -0,0 +1,45 @@
|
||||
# Check that llvm-readobj -mips-plt-got correctly shows .got section
|
||||
# content if there are some other zero-sized sections with the same
|
||||
# address as the .got. got-over.exe.elf-mips has zero-sized .data
|
||||
# section at the same offset .got section.
|
||||
|
||||
RUN: llvm-readobj -mips-plt-got %p/Inputs/got-over.exe.elf-mips | FileCheck %s
|
||||
|
||||
GOT-OBJ: Cannot find PLTGOT dynamic table tag.
|
||||
|
||||
CHECK: Primary GOT {
|
||||
CHECK-NEXT: Canonical gp value: 0x418270
|
||||
CHECK-NEXT: Reserved entries [
|
||||
CHECK-NEXT: Entry {
|
||||
CHECK-NEXT: Address: 0x410280
|
||||
CHECK-NEXT: Access: -32752
|
||||
CHECK-NEXT: Initial: 0x0
|
||||
CHECK-NEXT: Purpose: Lazy resolver
|
||||
CHECK-NEXT: }
|
||||
CHECK-NEXT: Entry {
|
||||
CHECK-NEXT: Address: 0x410284
|
||||
CHECK-NEXT: Access: -32748
|
||||
CHECK-NEXT: Initial: 0x80000000
|
||||
CHECK-NEXT: Purpose: Module pointer (GNU extension)
|
||||
CHECK-NEXT: }
|
||||
CHECK-NEXT: ]
|
||||
CHECK-NEXT: Local entries [
|
||||
CHECK-NEXT: Entry {
|
||||
CHECK-NEXT: Address: 0x410288
|
||||
CHECK-NEXT: Access: -32744
|
||||
CHECK-NEXT: Initial: 0x4001B8
|
||||
CHECK-NEXT: }
|
||||
CHECK-NEXT: ]
|
||||
CHECK-NEXT: Global entries [
|
||||
CHECK-NEXT: Entry {
|
||||
CHECK-NEXT: Address: 0x41028C
|
||||
CHECK-NEXT: Access: -32740
|
||||
CHECK-NEXT: Initial: 0x0
|
||||
CHECK-NEXT: Value: 0x0
|
||||
CHECK-NEXT: Type: None
|
||||
CHECK-NEXT: Section: Undefined
|
||||
CHECK-NEXT: Name: _foo
|
||||
CHECK-NEXT: }
|
||||
CHECK-NEXT: ]
|
||||
CHECK-NEXT: Number of TLS and multi-GOT entries: 0
|
||||
CHECK-NEXT: }
|
@ -497,10 +497,10 @@ getSectionNameIndex(const ELFO &Obj, const typename ELFO::Elf_Sym *Symbol,
|
||||
}
|
||||
|
||||
template <class ELFO>
|
||||
static const typename ELFO::Elf_Shdr *findSectionByAddress(const ELFO *Obj,
|
||||
uint64_t Addr) {
|
||||
static const typename ELFO::Elf_Shdr *
|
||||
findNotEmptySectionByAddress(const ELFO *Obj, uint64_t Addr) {
|
||||
for (const auto &Shdr : Obj->sections())
|
||||
if (Shdr.sh_addr == Addr)
|
||||
if (Shdr.sh_addr == Addr && Shdr.sh_size > 0)
|
||||
return &Shdr;
|
||||
return nullptr;
|
||||
}
|
||||
@ -1865,23 +1865,6 @@ template <class ELFT> void MipsGOTParser<ELFT>::parseGOT() {
|
||||
return;
|
||||
}
|
||||
|
||||
const Elf_Shdr *GOTShdr = findSectionByAddress(Obj, *DtPltGot);
|
||||
if (!GOTShdr) {
|
||||
W.startLine() << "There is no .got section in the file.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
ErrorOr<ArrayRef<uint8_t>> GOT = Obj->getSectionContents(GOTShdr);
|
||||
if (!GOT) {
|
||||
W.startLine() << "The .got section is empty.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if (*DtLocalGotNum > getGOTTotal(*GOT)) {
|
||||
W.startLine() << "MIPS_LOCAL_GOTNO exceeds a number of GOT entries.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
const Elf_Shdr *DynSymSec = Dumper->getDotDynSymSec();
|
||||
ErrorOr<StringRef> StrTable = Obj->getStringTableForSymtab(*DynSymSec);
|
||||
error(StrTable.getError());
|
||||
@ -1889,18 +1872,26 @@ template <class ELFT> void MipsGOTParser<ELFT>::parseGOT() {
|
||||
const Elf_Sym *DynSymEnd = Obj->symbol_end(DynSymSec);
|
||||
std::size_t DynSymTotal = std::size_t(std::distance(DynSymBegin, DynSymEnd));
|
||||
|
||||
if (*DtGotSym > DynSymTotal) {
|
||||
W.startLine() << "MIPS_GOTSYM exceeds a number of dynamic symbols.\n";
|
||||
return;
|
||||
}
|
||||
if (*DtGotSym > DynSymTotal)
|
||||
report_fatal_error("MIPS_GOTSYM exceeds a number of dynamic symbols");
|
||||
|
||||
std::size_t GlobalGotNum = DynSymTotal - *DtGotSym;
|
||||
|
||||
if (*DtLocalGotNum + GlobalGotNum > getGOTTotal(*GOT)) {
|
||||
W.startLine() << "Number of global GOT entries exceeds the size of GOT.\n";
|
||||
if (*DtLocalGotNum + GlobalGotNum == 0) {
|
||||
W.startLine() << "GOT is empty.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
const Elf_Shdr *GOTShdr = findNotEmptySectionByAddress(Obj, *DtPltGot);
|
||||
if (!GOTShdr)
|
||||
report_fatal_error("There is no not empty GOT section at 0x" +
|
||||
Twine::utohexstr(*DtPltGot));
|
||||
|
||||
ErrorOr<ArrayRef<uint8_t>> GOT = Obj->getSectionContents(GOTShdr);
|
||||
|
||||
if (*DtLocalGotNum + GlobalGotNum > getGOTTotal(*GOT))
|
||||
report_fatal_error("Number of GOT entries exceeds the size of GOT section");
|
||||
|
||||
const GOTEntry *GotBegin = makeGOTIter(*GOT, 0);
|
||||
const GOTEntry *GotLocalEnd = makeGOTIter(*GOT, *DtLocalGotNum);
|
||||
const GOTEntry *It = GotBegin;
|
||||
@ -1957,22 +1948,16 @@ template <class ELFT> void MipsGOTParser<ELFT>::parsePLT() {
|
||||
return;
|
||||
}
|
||||
|
||||
const Elf_Shdr *PLTShdr = findSectionByAddress(Obj, *DtMipsPltGot);
|
||||
if (!PLTShdr) {
|
||||
W.startLine() << "There is no .got.plt section in the file.\n";
|
||||
return;
|
||||
}
|
||||
const Elf_Shdr *PLTShdr = findNotEmptySectionByAddress(Obj, *DtMipsPltGot);
|
||||
if (!PLTShdr)
|
||||
report_fatal_error("There is no not empty PLTGOT section at 0x " +
|
||||
Twine::utohexstr(*DtMipsPltGot));
|
||||
ErrorOr<ArrayRef<uint8_t>> PLT = Obj->getSectionContents(PLTShdr);
|
||||
if (!PLT) {
|
||||
W.startLine() << "The .got.plt section is empty.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
const Elf_Shdr *PLTRelShdr = findSectionByAddress(Obj, *DtJmpRel);
|
||||
if (!PLTShdr) {
|
||||
W.startLine() << "There is no .rel.plt section in the file.\n";
|
||||
return;
|
||||
}
|
||||
const Elf_Shdr *PLTRelShdr = findNotEmptySectionByAddress(Obj, *DtJmpRel);
|
||||
if (!PLTRelShdr)
|
||||
report_fatal_error("There is no not empty RELPLT section at 0x" +
|
||||
Twine::utohexstr(*DtJmpRel));
|
||||
ErrorOr<const Elf_Shdr *> SymTableOrErr =
|
||||
Obj->getSection(PLTRelShdr->sh_link);
|
||||
error(SymTableOrErr.getError());
|
||||
|
Loading…
x
Reference in New Issue
Block a user