summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Object
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-11-13 07:42:07 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-11-13 07:42:07 +0000
commit58323a9763a5a291f2db96312b7eb7a345cdf12e (patch)
treecaeac332e18b4ba6c70787f8de56361f71516c56 /llvm/lib/Object
parent8ded0179c6aff189cb95cc95690b4693e97a113e (diff)
downloadbcm5719-llvm-58323a9763a5a291f2db96312b7eb7a345cdf12e.tar.gz
bcm5719-llvm-58323a9763a5a291f2db96312b7eb7a345cdf12e.zip
Object, COFF: Fix some theoretical bugs
getObject didn't consider the case where a pointer came before the start of the object file. No test is included, trying to come up with something reasonable. llvm-svn: 221868
Diffstat (limited to 'llvm/lib/Object')
-rw-r--r--llvm/lib/Object/COFFObjectFile.cpp17
1 files changed, 14 insertions, 3 deletions
diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp
index dadad1f2603..1fdeae6342f 100644
--- a/llvm/lib/Object/COFFObjectFile.cpp
+++ b/llvm/lib/Object/COFFObjectFile.cpp
@@ -43,11 +43,12 @@ static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size) {
// Returns unexpected_eof if error.
template <typename T>
static std::error_code getObject(const T *&Obj, MemoryBufferRef M,
- const uint8_t *Ptr,
+ const void *Ptr,
const size_t Size = sizeof(T)) {
uintptr_t Addr = uintptr_t(Ptr);
if (Addr + Size < Addr || Addr + Size < Size ||
- Addr + Size > uintptr_t(M.getBufferEnd())) {
+ Addr + Size > uintptr_t(M.getBufferEnd()) ||
+ Addr < uintptr_t(M.getBufferStart())) {
return object_error::unexpected_eof;
}
Obj = reinterpret_cast<const T *>(Addr);
@@ -424,6 +425,11 @@ relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const {
} else {
auto begin = reinterpret_cast<const coff_relocation*>(
base() + Sec->PointerToRelocations);
+ if (Sec->hasExtendedRelocations()) {
+ // Skip the first relocation entry repurposed to store the number of
+ // relocations.
+ begin++;
+ }
uint32_t NumReloc = getNumberOfRelocations(Sec, base());
Ret.p = reinterpret_cast<uintptr_t>(begin + NumReloc);
}
@@ -973,7 +979,12 @@ std::error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel,
std::error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel,
uint64_t &Res) const {
- Res = toRel(Rel)->VirtualAddress;
+ const coff_relocation *R = toRel(Rel);
+ const support::ulittle32_t *VirtualAddressPtr;
+ if (std::error_code EC =
+ getObject(VirtualAddressPtr, Data, &R->VirtualAddress))
+ return EC;
+ Res = *VirtualAddressPtr;
return object_error::success;
}
OpenPOWER on IntegriCloud