summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Object/COFF.h17
-rw-r--r--llvm/test/tools/llvm-objdump/Inputs/tls.exe.coff-x86_64bin0 -> 1024 bytes
-rw-r--r--llvm/test/tools/llvm-objdump/coff-private-headers.test12
-rw-r--r--llvm/tools/llvm-objdump/COFFDump.cpp51
4 files changed, 80 insertions, 0 deletions
diff --git a/llvm/include/llvm/Object/COFF.h b/llvm/include/llvm/Object/COFF.h
index 3e69c3e6e5d..87b7ae2c3d2 100644
--- a/llvm/include/llvm/Object/COFF.h
+++ b/llvm/include/llvm/Object/COFF.h
@@ -485,6 +485,23 @@ struct coff_import_directory_table_entry {
support::ulittle32_t ImportAddressTableRVA;
};
+template <typename IntTy>
+struct coff_tls_directory {
+ IntTy StartAddressOfRawData;
+ IntTy EndAddressOfRawData;
+ IntTy AddressOfIndex;
+ IntTy AddressOfCallBacks;
+ support::ulittle32_t SizeOfZeroFill;
+ support::ulittle32_t Characteristics;
+ uint32_t getAlignment() const {
+ uint32_t AlignBit = (Characteristics & 0x00F00000) >> 20;
+ return AlignBit ? 1 << (AlignBit - 1) : 0;
+ }
+};
+
+typedef coff_tls_directory<support::little32_t> coff_tls_directory32;
+typedef coff_tls_directory<support::little64_t> coff_tls_directory64;
+
struct coff_load_configuration32 {
support::ulittle32_t Characteristics;
support::ulittle32_t TimeDateStamp;
diff --git a/llvm/test/tools/llvm-objdump/Inputs/tls.exe.coff-x86_64 b/llvm/test/tools/llvm-objdump/Inputs/tls.exe.coff-x86_64
new file mode 100644
index 00000000000..f2fe798d028
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/Inputs/tls.exe.coff-x86_64
Binary files differ
diff --git a/llvm/test/tools/llvm-objdump/coff-private-headers.test b/llvm/test/tools/llvm-objdump/coff-private-headers.test
index 51bf4435389..e6006dfff61 100644
--- a/llvm/test/tools/llvm-objdump/coff-private-headers.test
+++ b/llvm/test/tools/llvm-objdump/coff-private-headers.test
@@ -43,6 +43,18 @@ EXPORT-NEXT: Ordinal RVA Name
EXPORT-NEXT: 5 0x2008
EXPORT-NEXT: 6 0x2010 exportfn2
+// RUN: llvm-objdump -p %p/Inputs/tls.exe.coff-x86_64 | \
+// RUN: FileCheck -check-prefix=TLS %s
+
+TLS: TLS directory:
+TLS-NEXT: StartAddressOfRawData: 0x00000000000000
+TLS-NEXT: EndAddressOfRawData: 0x00000000000000
+TLS-NEXT: AddressOfIndex: 0x00000000000000
+TLS-NEXT: AddressOfCallBacks: 0x00000000000000
+TLS-NEXT: SizeOfZeroFill: 0
+TLS-NEXT: Characteristics: 0
+TLS-NEXT: Alignment: 0
+
// RUN: llvm-objdump -p %p/Inputs/nop.exe.coff-i386 | \
// RUN: FileCheck -check-prefix=LOADCFG %s
diff --git a/llvm/tools/llvm-objdump/COFFDump.cpp b/llvm/tools/llvm-objdump/COFFDump.cpp
index 5d21b3320e7..aee771e42a2 100644
--- a/llvm/tools/llvm-objdump/COFFDump.cpp
+++ b/llvm/tools/llvm-objdump/COFFDump.cpp
@@ -252,6 +252,56 @@ printSEHTable(const COFFObjectFile *Obj, uint32_t TableVA, int Count) {
outs() << "\n\n";
}
+template <typename T>
+static void printTLSDirectoryT(const coff_tls_directory<T> *TLSDir) {
+ size_t FormatWidth = sizeof(T) * 2;
+ outs() << "TLS directory:"
+ << "\n StartAddressOfRawData: "
+ << format_hex(TLSDir->StartAddressOfRawData, FormatWidth)
+ << "\n EndAddressOfRawData: "
+ << format_hex(TLSDir->EndAddressOfRawData, FormatWidth)
+ << "\n AddressOfIndex: "
+ << format_hex(TLSDir->AddressOfIndex, FormatWidth)
+ << "\n AddressOfCallBacks: "
+ << format_hex(TLSDir->AddressOfCallBacks, FormatWidth)
+ << "\n SizeOfZeroFill: "
+ << TLSDir->SizeOfZeroFill
+ << "\n Characteristics: "
+ << TLSDir->Characteristics
+ << "\n Alignment: "
+ << TLSDir->getAlignment()
+ << "\n\n";
+}
+
+static void printTLSDirectory(const COFFObjectFile *Obj) {
+ const pe32_header *PE32Header;
+ error(Obj->getPE32Header(PE32Header));
+
+ const pe32plus_header *PE32PlusHeader;
+ error(Obj->getPE32PlusHeader(PE32PlusHeader));
+
+ // Skip if it's not executable.
+ if (!PE32Header && !PE32PlusHeader)
+ return;
+
+ const data_directory *DataDir;
+ error(Obj->getDataDirectory(COFF::TLS_TABLE, DataDir));
+ uintptr_t IntPtr = 0;
+ if (DataDir->RelativeVirtualAddress == 0)
+ return;
+ error(Obj->getRvaPtr(DataDir->RelativeVirtualAddress, IntPtr));
+
+ if (PE32Header) {
+ auto *TLSDir = reinterpret_cast<const coff_tls_directory32 *>(IntPtr);
+ printTLSDirectoryT(TLSDir);
+ } else {
+ auto *TLSDir = reinterpret_cast<const coff_tls_directory64 *>(IntPtr);
+ printTLSDirectoryT(TLSDir);
+ }
+
+ outs() << "\n";
+}
+
static void printLoadConfiguration(const COFFObjectFile *Obj) {
// Skip if it's not executable.
const pe32_header *PE32Header;
@@ -555,6 +605,7 @@ void llvm::printCOFFUnwindInfo(const COFFObjectFile *Obj) {
void llvm::printCOFFFileHeader(const object::ObjectFile *Obj) {
const COFFObjectFile *file = dyn_cast<const COFFObjectFile>(Obj);
+ printTLSDirectory(file);
printLoadConfiguration(file);
printImportTables(file);
printExportTable(file);
OpenPOWER on IntegriCloud