From 465237b45342386c6f41f052e47ff820173e734e Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Thu, 13 Nov 2014 07:42:07 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221868 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/COFFObjectFile.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index dadad1f2603..1fdeae6342f 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/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 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(Addr); @@ -424,6 +425,11 @@ relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const { } else { auto begin = reinterpret_cast( 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(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; } -- 2.11.0