Check that COFF .obj files have sections with zero virtual address spaces.
authorRafael Espindola <rafael.espindola@gmail.com>
Mon, 6 Jul 2015 14:26:07 +0000 (14:26 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Mon, 6 Jul 2015 14:26:07 +0000 (14:26 +0000)
When talking about the virtual address of sections the coff spec says:
  ... for simplicity, compilers should set this to zero. Otherwise, it is an
  arbitrary value that is subtracted from offsets during relocation.

We don't currently subtract it, so check that it is zero.

If some producer does create such files, we can change getRelocationOffset
instead.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241447 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Object/COFFObjectFile.cpp
test/Object/Inputs/invalid-bad-section-address.coff [new file with mode: 0644]
test/Object/coff-invalid.test [new file with mode: 0644]
tools/llvm-readobj/COFFDumper.cpp

index 19b53d8028d3eb3b02916b05387aa7f6c7cbb862..fcdd7d2c13b0452b3b2fdf4a0d94874ab4488c49 100644 (file)
@@ -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());
 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<uintptr_t>(begin);
   return relocation_iterator(RelocationRef(Ret, this));
   DataRefImpl Ret;
   Ret.p = reinterpret_cast<uintptr_t>(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 (file)
index 0000000..8d96e01
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 (file)
index 0000000..b85543d
--- /dev/null
@@ -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
index f5effe2924419b515c09ed608c030384df8cd627..91a4435d848772ef65ff65b7f69cf94636d9329f 100644 (file)
@@ -48,7 +48,6 @@ public:
   COFFDumper(const llvm::object::COFFObjectFile *Obj, StreamWriter& Writer)
     : ObjDumper(Writer)
     , Obj(Obj) {
   COFFDumper(const llvm::object::COFFObjectFile *Obj, StreamWriter& Writer)
     : ObjDumper(Writer)
     , Obj(Obj) {
-    cacheRelocations();
   }
 
   void printFileHeaders() override;
   }
 
   void printFileHeaders() override;
@@ -92,6 +91,7 @@ private:
   typedef DenseMap<const coff_section*, std::vector<RelocationRef> > RelocMapTy;
 
   const llvm::object::COFFObjectFile *Obj;
   typedef DenseMap<const coff_section*, std::vector<RelocationRef> > RelocMapTy;
 
   const llvm::object::COFFObjectFile *Obj;
+  bool RelocCached = false;
   RelocMapTy RelocMap;
   StringRef CVFileIndexToStringOffsetTable;
   StringRef CVStringTable;
   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) {
 // 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();
   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() {
 }
 
 void COFFDumper::cacheRelocations() {
+  if (RelocCached)
+    return;
+  RelocCached = true;
+
   for (const SectionRef &S : Obj->sections()) {
     const coff_section *Section = Obj->getCOFFSection(S);
 
   for (const SectionRef &S : Obj->sections()) {
     const coff_section *Section = Obj->getCOFFSection(S);