summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2015-07-06 14:26:07 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2015-07-06 14:26:07 +0000
commit76d650e8d77f19b9ee0ae708fff38109ff79e360 (patch)
tree1321f8e2cea2f151c47ec2e7059a0f7b21a4cca0
parent5c235c09665d7b30529a8e88f66b353026cbf8ff (diff)
downloadbcm5719-llvm-76d650e8d77f19b9ee0ae708fff38109ff79e360.tar.gz
bcm5719-llvm-76d650e8d77f19b9ee0ae708fff38109ff79e360.zip
Check that COFF .obj files have sections with zero virtual address spaces.
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. llvm-svn: 241447
-rw-r--r--llvm/lib/Object/COFFObjectFile.cpp2
-rw-r--r--llvm/test/Object/Inputs/invalid-bad-section-address.coffbin0 -> 304 bytes
-rw-r--r--llvm/test/Object/coff-invalid.test13
-rw-r--r--llvm/tools/llvm-readobj/COFFDumper.cpp7
4 files changed, 21 insertions, 1 deletions
diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp
index 19b53d8028d..fcdd7d2c13b 100644
--- a/llvm/lib/Object/COFFObjectFile.cpp
+++ b/llvm/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<uintptr_t>(begin);
return relocation_iterator(RelocationRef(Ret, this));
diff --git a/llvm/test/Object/Inputs/invalid-bad-section-address.coff b/llvm/test/Object/Inputs/invalid-bad-section-address.coff
new file mode 100644
index 00000000000..8d96e013751
--- /dev/null
+++ b/llvm/test/Object/Inputs/invalid-bad-section-address.coff
Binary files differ
diff --git a/llvm/test/Object/coff-invalid.test b/llvm/test/Object/coff-invalid.test
new file mode 100644
index 00000000000..b85543dcfe8
--- /dev/null
+++ b/llvm/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/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp
index f5effe29244..91a4435d848 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/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<const coff_section*, std::vector<RelocationRef> > 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);
OpenPOWER on IntegriCloud