summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Object/COFFObjectFile.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-11-13 08:46:37 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-11-13 08:46:37 +0000
commite830c60d89f65202b729d962693055a1cac2b7fd (patch)
treeb6fa5d33ccd59e69b95d16fffc2683c65bb4d9f7 /llvm/lib/Object/COFFObjectFile.cpp
parente0eb086dd426cc1d2e708653f0b48edae40aa600 (diff)
downloadbcm5719-llvm-e830c60d89f65202b729d962693055a1cac2b7fd.tar.gz
bcm5719-llvm-e830c60d89f65202b729d962693055a1cac2b7fd.zip
Object, COFF: Increase code reuse
Split getObject's smarts into checkOffset, use this to replace the handwritten check in getSectionContents. Similarly, replace checks in section_rel_begin/section_rel_end with getNumberOfRelocations. No functionality change intended. llvm-svn: 221873
Diffstat (limited to 'llvm/lib/Object/COFFObjectFile.cpp')
-rw-r--r--llvm/lib/Object/COFFObjectFile.cpp56
1 files changed, 32 insertions, 24 deletions
diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp
index 8312fed734c..b8e7d5e9e35 100644
--- a/llvm/lib/Object/COFFObjectFile.cpp
+++ b/llvm/lib/Object/COFFObjectFile.cpp
@@ -39,6 +39,16 @@ static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size) {
return true;
}
+static std::error_code checkOffset(MemoryBufferRef M, uintptr_t Addr,
+ const size_t Size) {
+ if (Addr + Size < Addr || Addr + Size < Size ||
+ Addr + Size > uintptr_t(M.getBufferEnd()) ||
+ Addr < uintptr_t(M.getBufferStart())) {
+ return object_error::unexpected_eof;
+ }
+ return object_error::success;
+}
+
// Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
// Returns unexpected_eof if error.
template <typename T>
@@ -46,11 +56,8 @@ static std::error_code getObject(const T *&Obj, MemoryBufferRef M,
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 < uintptr_t(M.getBufferStart())) {
- return object_error::unexpected_eof;
- }
+ if (std::error_code EC = checkOffset(M, Addr, Size))
+ return EC;
Obj = reinterpret_cast<const T *>(Addr);
return object_error::success;
}
@@ -385,10 +392,26 @@ bool COFFObjectFile::sectionContainsSymbol(DataRefImpl SecRef,
return SecNumber == Symb.getSectionNumber();
}
+static uint32_t getNumberOfRelocations(const coff_section *Sec,
+ MemoryBufferRef M, const uint8_t *base) {
+ // The field for the number of relocations in COFF section table is only
+ // 16-bit wide. If a section has more than 65535 relocations, 0xFFFF is set to
+ // NumberOfRelocations field, and the actual relocation count is stored in the
+ // VirtualAddress field in the first relocation entry.
+ if (Sec->hasExtendedRelocations()) {
+ const coff_relocation *FirstReloc;
+ if (getObject(FirstReloc, M, reinterpret_cast<const coff_relocation*>(
+ base + Sec->PointerToRelocations)))
+ return 0;
+ return FirstReloc->VirtualAddress;
+ }
+ return Sec->NumberOfRelocations;
+}
+
relocation_iterator COFFObjectFile::section_rel_begin(DataRefImpl Ref) const {
const coff_section *Sec = toSec(Ref);
DataRefImpl Ret;
- if (Sec->NumberOfRelocations == 0) {
+ if (getNumberOfRelocations(Sec, Data, base()) == 0) {
Ret.p = 0;
} else {
auto begin = reinterpret_cast<const coff_relocation*>(
@@ -403,24 +426,10 @@ relocation_iterator COFFObjectFile::section_rel_begin(DataRefImpl Ref) const {
return relocation_iterator(RelocationRef(Ret, this));
}
-static uint32_t getNumberOfRelocations(const coff_section *Sec,
- const uint8_t *base) {
- // The field for the number of relocations in COFF section table is only
- // 16-bit wide. If a section has more than 65535 relocations, 0xFFFF is set to
- // NumberOfRelocations field, and the actual relocation count is stored in the
- // VirtualAddress field in the first relocation entry.
- if (Sec->hasExtendedRelocations()) {
- auto *FirstReloc = reinterpret_cast<const coff_relocation*>(
- base + Sec->PointerToRelocations);
- return FirstReloc->VirtualAddress;
- }
- return Sec->NumberOfRelocations;
-}
-
relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const {
const coff_section *Sec = toSec(Ref);
DataRefImpl Ret;
- if (Sec->NumberOfRelocations == 0) {
+ if (getNumberOfRelocations(Sec, Data, base()) == 0) {
Ret.p = 0;
} else {
auto begin = reinterpret_cast<const coff_relocation*>(
@@ -430,7 +439,7 @@ relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const {
// relocations.
begin++;
}
- uint32_t NumReloc = getNumberOfRelocations(Sec, base());
+ uint32_t NumReloc = getNumberOfRelocations(Sec, Data, base());
Ret.p = reinterpret_cast<uintptr_t>(begin + NumReloc);
}
return relocation_iterator(RelocationRef(Ret, this));
@@ -956,8 +965,7 @@ COFFObjectFile::getSectionContents(const coff_section *Sec,
// data, as there's nothing that says that is not allowed.
uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData;
uint32_t SectionSize = getSectionSize(Sec);
- uintptr_t ConEnd = ConStart + SectionSize;
- if (ConEnd > uintptr_t(Data.getBufferEnd()))
+ if (checkOffset(Data, ConStart, SectionSize))
return object_error::parse_failed;
Res = makeArrayRef(reinterpret_cast<const uint8_t *>(ConStart), SectionSize);
return object_error::success;
OpenPOWER on IntegriCloud