Index: test/tools/llvm-readobj/mips-got-overlapped.test =================================================================== --- /dev/null +++ test/tools/llvm-readobj/mips-got-overlapped.test @@ -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: } Index: tools/llvm-readobj/ELFDumper.cpp =================================================================== --- tools/llvm-readobj/ELFDumper.cpp +++ tools/llvm-readobj/ELFDumper.cpp @@ -497,10 +497,10 @@ } template -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 @@ return; } - const Elf_Shdr *GOTShdr = findSectionByAddress(Obj, *DtPltGot); - if (!GOTShdr) { - W.startLine() << "There is no .got section in the file.\n"; - return; - } - - ErrorOr> 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 StrTable = Obj->getStringTableForSymtab(*DynSymSec); error(StrTable.getError()); @@ -1896,8 +1879,22 @@ std::size_t GlobalGotNum = DynSymTotal - *DtGotSym; + if (*DtLocalGotNum + GlobalGotNum == 0) { + W.startLine() << "GOT is empty.\n"; + return; + } + + const Elf_Shdr *GOTShdr = findNotEmptySectionByAddress(Obj, *DtPltGot); + if (!GOTShdr) { + W.startLine() << "There is no not empty GOT section at " + << format("0x%" PRIX64, *DtPltGot) << ".\n "; + return; + } + + ErrorOr> GOT = Obj->getSectionContents(GOTShdr); + if (*DtLocalGotNum + GlobalGotNum > getGOTTotal(*GOT)) { - W.startLine() << "Number of global GOT entries exceeds the size of GOT.\n"; + W.startLine() << "Number of GOT entries exceeds the size of GOT section.\n"; return; } @@ -1957,20 +1954,18 @@ return; } - const Elf_Shdr *PLTShdr = findSectionByAddress(Obj, *DtMipsPltGot); + const Elf_Shdr *PLTShdr = findNotEmptySectionByAddress(Obj, *DtMipsPltGot); if (!PLTShdr) { - W.startLine() << "There is no .got.plt section in the file.\n"; + W.startLine() << "There is no not empty PLTGOT section at " + << format("0x%" PRIX64, *DtMipsPltGot) << ".\n"; return; } ErrorOr> 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"; + const Elf_Shdr *PLTRelShdr = findNotEmptySectionByAddress(Obj, *DtJmpRel); + if (!PLTRelShdr) { + W.startLine() << "There is no not empty RELPLT section at " + << format("0x%" PRIX64, *DtJmpRel) << ".\n"; return; } ErrorOr SymTableOrErr =