summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2016-03-15 06:14:01 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2016-03-15 06:14:01 +0000
commit0ab61bfb377c7cffef8ad91afea012c6bd6ff812 (patch)
tree80f735f5515a6d5743fd841aff26d324a64bc71a
parent6436a4abd7a2f3a60b230453295dba199d8a59c3 (diff)
downloadbcm5719-llvm-0ab61bfb377c7cffef8ad91afea012c6bd6ff812.tar.gz
bcm5719-llvm-0ab61bfb377c7cffef8ad91afea012c6bd6ff812.zip
[llvm-objdump] Add support for dumping the PE TLS directory
The PE TLS directory contains information about where the TLS data resides in the image, what functions should be executed when threads are created, etc. llvm-svn: 263537
-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