diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index 19b53d8028d..fcdd7d2c13b 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -361,6 +361,8 @@ getFirstReloc(const coff_section *Sec, MemoryBufferRef M, const uint8_t *Base) { relocation_iterator COFFObjectFile::section_rel_begin(DataRefImpl Ref) const { const coff_section *Sec = toSec(Ref); const coff_relocation *begin = getFirstReloc(Sec, Data, base()); + if (begin && Sec->VirtualAddress != 0) + report_fatal_error("Sections with relocations should have an address of 0"); DataRefImpl Ret; Ret.p = reinterpret_cast(begin); return relocation_iterator(RelocationRef(Ret, this)); diff --git a/test/Object/Inputs/invalid-bad-section-address.coff b/test/Object/Inputs/invalid-bad-section-address.coff new file mode 100644 index 00000000000..8d96e013751 Binary files /dev/null and b/test/Object/Inputs/invalid-bad-section-address.coff differ diff --git a/test/Object/coff-invalid.test b/test/Object/coff-invalid.test new file mode 100644 index 00000000000..b85543dcfe8 --- /dev/null +++ b/test/Object/coff-invalid.test @@ -0,0 +1,13 @@ +RUN: llvm-readobj -s %p/Inputs/invalid-bad-section-address.coff 2>&1 | \ +RUN: FileCheck --check-prefix=SECTIONS %s + +SECTIONS: Section { +SECTIONS-NEXT: Number: 1 +SECTIONS-NEXT: Name: .text (2E 74 65 78 74 00 00 00) +SECTIONS-NEXT: VirtualSize: 0x0 +SECTIONS-NEXT: VirtualAddress: 0x1000000 + +RUN: not llvm-readobj -r %p/Inputs/invalid-bad-section-address.coff 2>&1 | \ +RUN: FileCheck %s + +CHECK: Sections with relocations should have an address of 0 diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp index f5effe29244..91a4435d848 100644 --- a/tools/llvm-readobj/COFFDumper.cpp +++ b/tools/llvm-readobj/COFFDumper.cpp @@ -48,7 +48,6 @@ public: COFFDumper(const llvm::object::COFFObjectFile *Obj, StreamWriter& Writer) : ObjDumper(Writer) , Obj(Obj) { - cacheRelocations(); } void printFileHeaders() override; @@ -92,6 +91,7 @@ private: typedef DenseMap > RelocMapTy; const llvm::object::COFFObjectFile *Obj; + bool RelocCached = false; RelocMapTy RelocMap; StringRef CVFileIndexToStringOffsetTable; StringRef CVStringTable; @@ -119,6 +119,7 @@ std::error_code createCOFFDumper(const object::ObjectFile *Obj, // symbol used for the relocation at the offset. std::error_code COFFDumper::resolveSymbol(const coff_section *Section, uint64_t Offset, SymbolRef &Sym) { + cacheRelocations(); const auto &Relocations = RelocMap[Section]; for (const auto &Relocation : Relocations) { uint64_t RelocationOffset = Relocation.getOffset(); @@ -339,6 +340,10 @@ static std::error_code getSymbolAuxData(const COFFObjectFile *Obj, } void COFFDumper::cacheRelocations() { + if (RelocCached) + return; + RelocCached = true; + for (const SectionRef &S : Obj->sections()) { const coff_section *Section = Obj->getCOFFSection(S);