aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Object/COFFObjectFile.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-06-13 19:31:46 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-06-13 19:37:19 +0000
commite8d8bef961a50d4dc22501cde4fb9fb0be1b2532 (patch)
tree94f04805f47bb7c59ae29690d8952b6074fff602 /contrib/llvm-project/llvm/lib/Object/COFFObjectFile.cpp
parentbb130ff39747b94592cb26d71b7cb097b9a4ea6b (diff)
parentb60736ec1405bb0a8dd40989f67ef4c93da068ab (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Object/COFFObjectFile.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Object/COFFObjectFile.cpp74
1 files changed, 57 insertions, 17 deletions
diff --git a/contrib/llvm-project/llvm/lib/Object/COFFObjectFile.cpp b/contrib/llvm-project/llvm/lib/Object/COFFObjectFile.cpp
index c26d7721b3fe..6e9a8eb35dcf 100644
--- a/contrib/llvm-project/llvm/lib/Object/COFFObjectFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/COFFObjectFile.cpp
@@ -28,8 +28,8 @@
#include "llvm/Support/MemoryBuffer.h"
#include <algorithm>
#include <cassert>
+#include <cinttypes>
#include <cstddef>
-#include <cstdint>
#include <cstring>
#include <limits>
#include <memory>
@@ -57,7 +57,7 @@ static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size) {
template <typename T>
static Error getObject(const T *&Obj, MemoryBufferRef M, const void *Ptr,
const uint64_t Size = sizeof(T)) {
- uintptr_t Addr = uintptr_t(Ptr);
+ uintptr_t Addr = reinterpret_cast<uintptr_t>(Ptr);
if (Error E = Binary::checkOffset(M, Addr, Size))
return E;
Obj = reinterpret_cast<const T *>(Addr);
@@ -103,10 +103,11 @@ const coff_symbol_type *COFFObjectFile::toSymb(DataRefImpl Ref) const {
const coff_symbol_type *Addr =
reinterpret_cast<const coff_symbol_type *>(Ref.p);
- assert(!checkOffset(Data, uintptr_t(Addr), sizeof(*Addr)));
+ assert(!checkOffset(Data, reinterpret_cast<uintptr_t>(Addr), sizeof(*Addr)));
#ifndef NDEBUG
// Verify that the symbol points to a valid entry in the symbol table.
- uintptr_t Offset = uintptr_t(Addr) - uintptr_t(base());
+ uintptr_t Offset =
+ reinterpret_cast<uintptr_t>(Addr) - reinterpret_cast<uintptr_t>(base());
assert((Offset - getPointerToSymbolTable()) % sizeof(coff_symbol_type) == 0 &&
"Symbol did not point to the beginning of a symbol");
@@ -123,7 +124,8 @@ const coff_section *COFFObjectFile::toSec(DataRefImpl Ref) const {
if (Addr < SectionTable || Addr >= (SectionTable + getNumberOfSections()))
report_fatal_error("Section was outside of section table.");
- uintptr_t Offset = uintptr_t(Addr) - uintptr_t(SectionTable);
+ uintptr_t Offset = reinterpret_cast<uintptr_t>(Addr) -
+ reinterpret_cast<uintptr_t>(SectionTable);
assert(Offset % sizeof(coff_section) == 0 &&
"Section did not point to the beginning of a section");
#endif
@@ -332,7 +334,7 @@ bool COFFObjectFile::isDebugSection(StringRef SectionName) const {
unsigned COFFObjectFile::getSectionID(SectionRef Sec) const {
uintptr_t Offset =
- uintptr_t(Sec.getRawDataRefImpl().p) - uintptr_t(SectionTable);
+ Sec.getRawDataRefImpl().p - reinterpret_cast<uintptr_t>(SectionTable);
assert((Offset % sizeof(coff_section)) == 0);
return (Offset / sizeof(coff_section)) + 1;
}
@@ -376,7 +378,7 @@ getFirstReloc(const coff_section *Sec, MemoryBufferRef M, const uint8_t *Base) {
// relocations.
begin++;
}
- if (auto E = Binary::checkOffset(M, uintptr_t(begin),
+ if (auto E = Binary::checkOffset(M, reinterpret_cast<uintptr_t>(begin),
sizeof(coff_relocation) * NumRelocs)) {
consumeError(std::move(E));
return nullptr;
@@ -467,7 +469,8 @@ Error COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const {
uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize;
if (SectionStart <= Addr && Addr < SectionEnd) {
uint32_t Offset = Addr - SectionStart;
- Res = uintptr_t(base()) + Section->PointerToRawData + Offset;
+ Res = reinterpret_cast<uintptr_t>(base()) + Section->PointerToRawData +
+ Offset;
return Error::success();
}
}
@@ -484,8 +487,8 @@ Error COFFObjectFile::getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
uint32_t OffsetIntoSection = RVA - SectionStart;
if (SectionStart <= RVA && OffsetIntoSection < Section->VirtualSize &&
Size <= Section->VirtualSize - OffsetIntoSection) {
- uintptr_t Begin =
- uintptr_t(base()) + Section->PointerToRawData + OffsetIntoSection;
+ uintptr_t Begin = reinterpret_cast<uintptr_t>(base()) +
+ Section->PointerToRawData + OffsetIntoSection;
Contents =
ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Begin), Size);
return Error::success();
@@ -649,6 +652,38 @@ Error COFFObjectFile::initDebugDirectoryPtr() {
return Error::success();
}
+Error COFFObjectFile::initTLSDirectoryPtr() {
+ // Get the RVA of the TLS directory. Do nothing if it does not exist.
+ const data_directory *DataEntry = getDataDirectory(COFF::TLS_TABLE);
+ if (!DataEntry)
+ return Error::success();
+
+ // Do nothing if the RVA is NULL.
+ if (DataEntry->RelativeVirtualAddress == 0)
+ return Error::success();
+
+ uint64_t DirSize =
+ is64() ? sizeof(coff_tls_directory64) : sizeof(coff_tls_directory32);
+
+ // Check that the size is correct.
+ if (DataEntry->Size != DirSize)
+ return createStringError(
+ object_error::parse_failed,
+ "TLS Directory size (%u) is not the expected size (%" PRIu64 ").",
+ static_cast<uint32_t>(DataEntry->Size), DirSize);
+
+ uintptr_t IntPtr = 0;
+ if (Error E = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
+ return E;
+
+ if (is64())
+ TLSDirectory64 = reinterpret_cast<const coff_tls_directory64 *>(IntPtr);
+ else
+ TLSDirectory32 = reinterpret_cast<const coff_tls_directory32 *>(IntPtr);
+
+ return Error::success();
+}
+
Error COFFObjectFile::initLoadConfigPtr() {
// Get the RVA of the debug directory. Do nothing if it does not exist.
const data_directory *DataEntry = getDataDirectory(COFF::LOAD_CONFIG_TABLE);
@@ -682,7 +717,8 @@ COFFObjectFile::COFFObjectFile(MemoryBufferRef Object)
ImportDirectory(nullptr), DelayImportDirectory(nullptr),
NumberOfDelayImportDirectory(0), ExportDirectory(nullptr),
BaseRelocHeader(nullptr), BaseRelocEnd(nullptr),
- DebugDirectoryBegin(nullptr), DebugDirectoryEnd(nullptr) {}
+ DebugDirectoryBegin(nullptr), DebugDirectoryEnd(nullptr),
+ TLSDirectory32(nullptr), TLSDirectory64(nullptr) {}
Error COFFObjectFile::initialize() {
// Check that we at least have enough room for a header.
@@ -809,10 +845,14 @@ Error COFFObjectFile::initialize() {
if (Error E = initBaseRelocPtr())
return E;
- // Initialize the pointer to the export table.
+ // Initialize the pointer to the debug directory.
if (Error E = initDebugDirectoryPtr())
return E;
+ // Initialize the pointer to the TLS directory.
+ if (Error E = initTLSDirectoryPtr())
+ return E;
+
if (Error E = initLoadConfigPtr())
return E;
@@ -1090,7 +1130,8 @@ Error COFFObjectFile::getSectionContents(const coff_section *Sec,
// The only thing that we need to verify is that the contents is contained
// within the file bounds. We don't need to make sure it doesn't cover other
// data, as there's nothing that says that is not allowed.
- uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData;
+ uintptr_t ConStart =
+ reinterpret_cast<uintptr_t>(base()) + Sec->PointerToRawData;
uint32_t SectionSize = getSectionSize(Sec);
if (Error E = checkOffset(Data, ConStart, SectionSize))
return E;
@@ -1750,10 +1791,9 @@ Error ResourceSectionRef::load(const COFFObjectFile *O, const SectionRef &S) {
Relocs.reserve(OrigRelocs.size());
for (const coff_relocation &R : OrigRelocs)
Relocs.push_back(&R);
- std::sort(Relocs.begin(), Relocs.end(),
- [](const coff_relocation *A, const coff_relocation *B) {
- return A->VirtualAddress < B->VirtualAddress;
- });
+ llvm::sort(Relocs, [](const coff_relocation *A, const coff_relocation *B) {
+ return A->VirtualAddress < B->VirtualAddress;
+ });
return Error::success();
}