diff options
-rw-r--r-- | llvm/include/llvm/Object/COFF.h | 17 | ||||
-rw-r--r-- | llvm/test/tools/llvm-objdump/Inputs/tls.exe.coff-x86_64 | bin | 0 -> 1024 bytes | |||
-rw-r--r-- | llvm/test/tools/llvm-objdump/coff-private-headers.test | 12 | ||||
-rw-r--r-- | llvm/tools/llvm-objdump/COFFDump.cpp | 51 |
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 Binary files differnew file mode 100644 index 00000000000..f2fe798d028 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/Inputs/tls.exe.coff-x86_64 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); |