From c514a8041fa9e3f73963efe20369d76f5f490ec4 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Wed, 19 Feb 2014 03:53:11 +0000 Subject: [PATCH] llvm-objdump/COFF: Print load configuration table. Load Configuration Table may contain a pointer to SEH table. This patch is to print the offset to the table. Printing SEH table contents is a TODO. The layout of Layout Configuration Table is described in Microsoft PE/COFF Object File Format Spec, but the table's offset/size descriptions seems to be totally wrong, at least in revision 8.3 of the spec. I believe the table in this patch is the correct one. llvm-svn: 201638 --- llvm/include/llvm/Object/COFF.h | 23 +++++++ .../llvm-objdump/Inputs/nop.exe.coff-i386 | Bin 7680 -> 6144 bytes .../llvm-objdump/coff-private-headers.test | 56 ++++++++++++++++-- llvm/tools/llvm-objdump/COFFDump.cpp | 41 +++++++++++++ 4 files changed, 116 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/Object/COFF.h b/llvm/include/llvm/Object/COFF.h index 264a851e8538..6ce549060688 100644 --- a/llvm/include/llvm/Object/COFF.h +++ b/llvm/include/llvm/Object/COFF.h @@ -244,6 +244,29 @@ struct coff_aux_section_definition { char Unused[3]; }; +struct coff_load_configuration32 { + support::ulittle32_t Characteristics; + support::ulittle32_t TimeDateStamp; + support::ulittle16_t MajorVersion; + support::ulittle16_t MinorVersion; + support::ulittle32_t GlobalFlagsClear; + support::ulittle32_t GlobalFlagsSet; + support::ulittle32_t CriticalSectionDefaultTimeout; + support::ulittle32_t DeCommitFreeBlockThreshold; + support::ulittle32_t DeCommitTotalFreeThreshold; + support::ulittle32_t LockPrefixTable; + support::ulittle32_t MaximumAllocationSize; + support::ulittle32_t VirtualMemoryThreshold; + support::ulittle32_t ProcessAffinityMask; + support::ulittle32_t ProcessHeapFlags; + support::ulittle16_t CSDVersion; + char Reserved[4]; + support::ulittle32_t EditList; + support::ulittle32_t SecurityCookie; + support::ulittle32_t SEHandlerTable; + support::ulittle32_t SEHandlerCount; +}; + class COFFObjectFile : public ObjectFile { private: friend class ImportDirectoryEntryRef; diff --git a/llvm/test/tools/llvm-objdump/Inputs/nop.exe.coff-i386 b/llvm/test/tools/llvm-objdump/Inputs/nop.exe.coff-i386 index 68c9d3db0f8f93f1b9c3772d059e4b483d49ab53..2cda30ff3d2b325355d6c23e1e06fa662cbc76cc 100644 GIT binary patch literal 6144 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 F@C*71LD>KR diff --git a/llvm/test/tools/llvm-objdump/coff-private-headers.test b/llvm/test/tools/llvm-objdump/coff-private-headers.test index de3de9001db1..24d1b96cfc77 100644 --- a/llvm/test/tools/llvm-objdump/coff-private-headers.test +++ b/llvm/test/tools/llvm-objdump/coff-private-headers.test @@ -1,11 +1,37 @@ // RUN: llvm-objdump -p %p/Inputs/nop.exe.coff-i386 | \ // RUN: FileCheck -check-prefix=IMPORT %s -IMPORT: The Import Tables: -IMPORT-NEXT: lookup 00005028 time 00000000 fwd 00000000 name 00005096 addr 00005058 -IMPORT: DLL Name: KERNEL32.dll +IMPORT: The Import Tables: +IMPORT: lookup 000021e4 time 00000000 fwd 00000000 name 0000234a addr 00002024 +IMPORT: DLL Name: MSVCR110.dll IMPORT-NEXT: Hint/Ord Name -IMPORT-NEXT: 365 ExitProcess +IMPORT-NEXT: 767 _initterm_e +IMPORT-NEXT: 766 _initterm +IMPORT-NEXT: 437 __initenv +IMPORT-NEXT: 660 _fmode +IMPORT-NEXT: 571 _commode +IMPORT-NEXT: 315 ?terminate@@YAXXZ +IMPORT-NEXT: 424 __crtSetUnhandledExceptionFilter +IMPORT-NEXT: 892 _lock +IMPORT-NEXT: 1254 _unlock +IMPORT-NEXT: 498 __setusermatherr +IMPORT-NEXT: 428 __dllonexit +IMPORT-NEXT: 1058 _onexit +IMPORT-NEXT: 774 _invoke_watson +IMPORT-NEXT: 575 _controlfp_s +IMPORT-NEXT: 624 _except_handler4_common +IMPORT-NEXT: 587 _crt_debugger_hook +IMPORT-NEXT: 426 __crtUnhandledException +IMPORT-NEXT: 425 __crtTerminateProcess +IMPORT-NEXT: 572 _configthreadlocale +IMPORT-NEXT: 556 _cexit +IMPORT-NEXT: 633 _exit +IMPORT-NEXT: 1484 exit +IMPORT-NEXT: 496 __set_app_type +IMPORT-NEXT: 436 __getmainargs +IMPORT-NEXT: 533 _amsg_exit +IMPORT-NEXT: 555 _calloc_crt +IMPORT-NEXT: 367 _XcptFilter // RUN: llvm-objdump -p %p/Inputs/export.dll.coff-i386 | \ // RUN: FileCheck -check-prefix=EXPORT %s @@ -16,3 +42,25 @@ EXPORT-NEXT: Ordinal base: 5 EXPORT-NEXT: Ordinal RVA Name EXPORT-NEXT: 5 0x2008 EXPORT-NEXT: 6 0x2010 exportfn2 + +// RUN: llvm-objdump -p %p/Inputs/nop.exe.coff-i386 | \ +// RUN: FileCheck -check-prefix=LOADCFG %s + +LOADCFG: Load configuration: +LOADCFG-NEXT: Timestamp: 0 +LOADCFG-NEXT: Major Version: 0 +LOADCFG-NEXT: Minor Version: 0 +LOADCFG-NEXT: GlobalFlags Clear: 0 +LOADCFG-NEXT: GlobalFlags Set: 0 +LOADCFG-NEXT: Critical Section Default Timeout: 0 +LOADCFG-NEXT: Decommit Free Block Threshold: 0 +LOADCFG-NEXT: Decommit Total Free Threshold: 0 +LOADCFG-NEXT: Lock Prefix Table: 0 +LOADCFG-NEXT: Maximum Allocation Size: 0 +LOADCFG-NEXT: Virtual Memory Threshold: 0 +LOADCFG-NEXT: Process Affinity Mask: 0 +LOADCFG-NEXT: Process Heap Flags: 0 +LOADCFG-NEXT: CSD Version: 0 +LOADCFG-NEXT: Security Cookie: 554696768 +LOADCFG-NEXT: SEH Table: 65600 +LOADCFG-NEXT: SEH Count: 0 diff --git a/llvm/tools/llvm-objdump/COFFDump.cpp b/llvm/tools/llvm-objdump/COFFDump.cpp index f6f0f15197b9..883786d4f664 100644 --- a/llvm/tools/llvm-objdump/COFFDump.cpp +++ b/llvm/tools/llvm-objdump/COFFDump.cpp @@ -233,6 +233,46 @@ static void printCOFFSymbolAddress(llvm::raw_ostream &Out, Out << format(" + 0x%04x", Disp); } +static void printLoadConfiguration(const COFFObjectFile *Obj) { + const coff_file_header *Header; + if (error(Obj->getCOFFHeader(Header))) + return; + // Currently only x86 is supported + if (Header->Machine != COFF::IMAGE_FILE_MACHINE_I386) + return; + + const data_directory *DataDir; + if (error(Obj->getDataDirectory(COFF::LOAD_CONFIG_TABLE, DataDir))) + return; + uintptr_t IntPtr = 0; + if (DataDir->RelativeVirtualAddress == 0) + return; + if (error(Obj->getRvaPtr(DataDir->RelativeVirtualAddress, IntPtr))) + return; + const coff_load_configuration32 *LoadConf = + reinterpret_cast(IntPtr); + + outs() << "Load configuration:" + << "\n Timestamp: " << LoadConf->TimeDateStamp + << "\n Major Version: " << LoadConf->MajorVersion + << "\n Minor Version: " << LoadConf->MinorVersion + << "\n GlobalFlags Clear: " << LoadConf->GlobalFlagsClear + << "\n GlobalFlags Set: " << LoadConf->GlobalFlagsSet + << "\n Critical Section Default Timeout: " << LoadConf->CriticalSectionDefaultTimeout + << "\n Decommit Free Block Threshold: " << LoadConf->DeCommitFreeBlockThreshold + << "\n Decommit Total Free Threshold: " << LoadConf->DeCommitTotalFreeThreshold + << "\n Lock Prefix Table: " << LoadConf->LockPrefixTable + << "\n Maximum Allocation Size: " << LoadConf->MaximumAllocationSize + << "\n Virtual Memory Threshold: " << LoadConf->VirtualMemoryThreshold + << "\n Process Affinity Mask: " << LoadConf->ProcessAffinityMask + << "\n Process Heap Flags: " << LoadConf->ProcessHeapFlags + << "\n CSD Version: " << LoadConf->CSDVersion + << "\n Security Cookie: " << LoadConf->SecurityCookie + << "\n SEH Table: " << LoadConf->SEHandlerTable + << "\n SEH Count: " << LoadConf->SEHandlerCount + << "\n\n"; +} + // Prints import tables. The import table is a table containing the list of // DLL name and symbol names which will be linked by the loader. static void printImportTables(const COFFObjectFile *Obj) { @@ -431,6 +471,7 @@ void llvm::printCOFFUnwindInfo(const COFFObjectFile *Obj) { void llvm::printCOFFFileHeader(const object::ObjectFile *Obj) { const COFFObjectFile *file = dyn_cast(Obj); + printLoadConfiguration(file); printImportTables(file); printExportTable(file); }