diff options
-rw-r--r-- | test/tools/llvm-objdump/Inputs/win64-unwind.exe.coff-x86_64.exe | bin | 0 -> 2560 bytes | |||
-rw-r--r-- | test/tools/llvm-objdump/Inputs/win64-unwind.exe.coff-x86_64.obj (renamed from test/tools/llvm-objdump/Inputs/win64-unwind.exe.coff-x86_64) | bin | 698 -> 698 bytes | |||
-rw-r--r-- | test/tools/llvm-objdump/win64-unwind-data.test | 155 | ||||
-rw-r--r-- | tools/llvm-objdump/COFFDump.cpp | 37 |
4 files changed, 138 insertions, 54 deletions
diff --git a/test/tools/llvm-objdump/Inputs/win64-unwind.exe.coff-x86_64.exe b/test/tools/llvm-objdump/Inputs/win64-unwind.exe.coff-x86_64.exe Binary files differnew file mode 100644 index 0000000000..c701c24fb8 --- /dev/null +++ b/test/tools/llvm-objdump/Inputs/win64-unwind.exe.coff-x86_64.exe diff --git a/test/tools/llvm-objdump/Inputs/win64-unwind.exe.coff-x86_64 b/test/tools/llvm-objdump/Inputs/win64-unwind.exe.coff-x86_64.obj Binary files differindex 63460e7826..63460e7826 100644 --- a/test/tools/llvm-objdump/Inputs/win64-unwind.exe.coff-x86_64 +++ b/test/tools/llvm-objdump/Inputs/win64-unwind.exe.coff-x86_64.obj diff --git a/test/tools/llvm-objdump/win64-unwind-data.test b/test/tools/llvm-objdump/win64-unwind-data.test index 00ad469079..104d959a2a 100644 --- a/test/tools/llvm-objdump/win64-unwind-data.test +++ b/test/tools/llvm-objdump/win64-unwind-data.test @@ -1,52 +1,107 @@ // This test checks that the unwind data is dumped by llvm-objdump. -// RUN: llvm-objdump -u %p/Inputs/win64-unwind.exe.coff-x86_64 | FileCheck %s +// RUN: llvm-objdump -u %p/Inputs/win64-unwind.exe.coff-x86_64.obj \ +// RUN: | FileCheck -check-prefix=OBJ %s +// RUN: llvm-objdump -u %p/Inputs/win64-unwind.exe.coff-x86_64.exe \ +// RUN: | FileCheck -check-prefix=EXE %s -CHECK: Unwind info: -CHECK: Function Table: -CHECK-NEXT: Start Address: func -CHECK-NEXT: End Address: func + 0x001b -CHECK-NEXT: Unwind Info Address: .xdata -CHECK-NEXT: Version: 1 -CHECK-NEXT: Flags: 1 UNW_ExceptionHandler -CHECK-NEXT: Size of prolog: 18 -CHECK-NEXT: Number of Codes: 8 -CHECK-NEXT: Frame register: RBX -CHECK-NEXT: Frame offset: 0 -CHECK-NEXT: Unwind Codes: -CHECK-NEXT: 0x12: UOP_SetFPReg -CHECK-NEXT: 0x0f: UOP_PushNonVol RBX -CHECK-NEXT: 0x0e: UOP_SaveXMM128 XMM8 [0x0000] -CHECK-NEXT: 0x09: UOP_SaveNonVol RSI [0x0010] -CHECK-NEXT: 0x04: UOP_AllocSmall 24 -CHECK-NEXT: 0x00: UOP_PushMachFrame w/o error code -CHECK: Function Table: -CHECK-NEXT: Start Address: func + 0x0012 -CHECK-NEXT: End Address: func + 0x0012 -CHECK-NEXT: Unwind Info Address: .xdata + 0x001c -CHECK-NEXT: Version: 1 -CHECK-NEXT: Flags: 4 UNW_ChainInfo -CHECK-NEXT: Size of prolog: 0 -CHECK-NEXT: Number of Codes: 0 -CHECK-NEXT: No frame pointer used -CHECK: Function Table: -CHECK-NEXT: Start Address: smallFunc -CHECK-NEXT: End Address: smallFunc + 0x0001 -CHECK-NEXT: Unwind Info Address: .xdata + 0x002c -CHECK-NEXT: Version: 1 -CHECK-NEXT: Flags: 0 -CHECK-NEXT: Size of prolog: 0 -CHECK-NEXT: Number of Codes: 0 -CHECK-NEXT: No frame pointer used -CHECK: Function Table: -CHECK-NEXT: Start Address: allocFunc -CHECK-NEXT: End Address: allocFunc + 0x001d -CHECK-NEXT: Unwind Info Address: .xdata + 0x0034 -CHECK-NEXT: Version: 1 -CHECK-NEXT: Flags: 0 -CHECK-NEXT: Size of prolog: 14 -CHECK-NEXT: Number of Codes: 6 -CHECK-NEXT: No frame pointer used -CHECK-NEXT: Unwind Codes: -CHECK-NEXT: 0x0e: UOP_AllocLarge 8454128 -CHECK-NEXT: 0x07: UOP_AllocLarge 8190 -CHECK-NEXT: 0x00: UOP_PushMachFrame w/o error code +OBJ: Unwind info: +OBJ: Function Table: +OBJ-NEXT: Start Address: func +OBJ-NEXT: End Address: func + 0x001b +OBJ-NEXT: Unwind Info Address: .xdata +OBJ-NEXT: Version: 1 +OBJ-NEXT: Flags: 1 UNW_ExceptionHandler +OBJ-NEXT: Size of prolog: 18 +OBJ-NEXT: Number of Codes: 8 +OBJ-NEXT: Frame register: RBX +OBJ-NEXT: Frame offset: 0 +OBJ-NEXT: Unwind Codes: +OBJ-NEXT: 0x12: UOP_SetFPReg +OBJ-NEXT: 0x0f: UOP_PushNonVol RBX +OBJ-NEXT: 0x0e: UOP_SaveXMM128 XMM8 [0x0000] +OBJ-NEXT: 0x09: UOP_SaveNonVol RSI [0x0010] +OBJ-NEXT: 0x04: UOP_AllocSmall 24 +OBJ-NEXT: 0x00: UOP_PushMachFrame w/o error code +OBJ: Function Table: +OBJ-NEXT: Start Address: func + 0x0012 +OBJ-NEXT: End Address: func + 0x0012 +OBJ-NEXT: Unwind Info Address: .xdata + 0x001c +OBJ-NEXT: Version: 1 +OBJ-NEXT: Flags: 4 UNW_ChainInfo +OBJ-NEXT: Size of prolog: 0 +OBJ-NEXT: Number of Codes: 0 +OBJ-NEXT: No frame pointer used +OBJ: Function Table: +OBJ-NEXT: Start Address: smallFunc +OBJ-NEXT: End Address: smallFunc + 0x0001 +OBJ-NEXT: Unwind Info Address: .xdata + 0x002c +OBJ-NEXT: Version: 1 +OBJ-NEXT: Flags: 0 +OBJ-NEXT: Size of prolog: 0 +OBJ-NEXT: Number of Codes: 0 +OBJ-NEXT: No frame pointer used +OBJ: Function Table: +OBJ-NEXT: Start Address: allocFunc +OBJ-NEXT: End Address: allocFunc + 0x001d +OBJ-NEXT: Unwind Info Address: .xdata + 0x0034 +OBJ-NEXT: Version: 1 +OBJ-NEXT: Flags: 0 +OBJ-NEXT: Size of prolog: 14 +OBJ-NEXT: Number of Codes: 6 +OBJ-NEXT: No frame pointer used +OBJ-NEXT: Unwind Codes: +OBJ-NEXT: 0x0e: UOP_AllocLarge 8454128 +OBJ-NEXT: 0x07: UOP_AllocLarge 8190 +OBJ-NEXT: 0x00: UOP_PushMachFrame w/o error code + +EXE: Function Table: +EXE: Start Address: 0x1000 +EXE: End Address: 0x101b +EXE: Unwind Info Address: : 0x2000 +EXE: Version: 1 +EXE: Flags: 1 UNW_ExceptionHandler +EXE: Size of prolog: 18 +EXE: Number of Codes: 8 +EXE: Frame register: RBX +EXE: Frame offset: 0 +EXE: Unwind Codes: +EXE: 0x12: UOP_SetFPReg +EXE: 0x0f: UOP_PushNonVol RBX +EXE: 0x0e: UOP_SaveXMM128 XMM8 [0x0000] +EXE: 0x09: UOP_SaveNonVol RSI [0x0010] +EXE: 0x04: UOP_AllocSmall 24 +EXE: 0x00: UOP_PushMachFrame w/o error code + +EXE: Function Table: +EXE: Start Address: 0x1012 +EXE: End Address: 0x1012 +EXE: Unwind Info Address: : 0x201c +EXE: Version: 1 +EXE: Flags: 4 UNW_ChainInfo +EXE: Size of prolog: 0 +EXE: Number of Codes: 0 +EXE: No frame pointer used + +EXE: Function Table: +EXE: Start Address: 0x101b +EXE: End Address: 0x101c +EXE: Unwind Info Address: : 0x202c +EXE: Version: 1 +EXE: Flags: 0 +EXE: Size of prolog: 0 +EXE: Number of Codes: 0 +EXE: No frame pointer used + +EXE: Function Table: +EXE: Start Address: 0x101c +EXE: End Address: 0x1039 +EXE: Unwind Info Address: : 0x2034 +EXE: Version: 1 +EXE: Flags: 0 +EXE: Size of prolog: 14 +EXE: Number of Codes: 6 +EXE: No frame pointer used +EXE: Unwind Codes: +EXE: 0x0e: UOP_AllocLarge 8454128 +EXE: 0x07: UOP_AllocLarge 8190 +EXE: 0x00: UOP_PushMachFrame w/o error code diff --git a/tools/llvm-objdump/COFFDump.cpp b/tools/llvm-objdump/COFFDump.cpp index ba5de46b9f..53cedbbdbd 100644 --- a/tools/llvm-objdump/COFFDump.cpp +++ b/tools/llvm-objdump/COFFDump.cpp @@ -453,10 +453,32 @@ static void printWin64EHUnwindInfo(const Win64EH::UnwindInfo *UI) { outs().flush(); } +/// Prints out the given RuntumeFunction struct for x64, assuming that Obj is +/// pointing to an executable file. static void printRuntimeFunction(const COFFObjectFile *Obj, - const RuntimeFunction &RF, - uint64_t SectionOffset, - const std::vector<RelocationRef> &Rels) { + const RuntimeFunction &RF) { + if (!RF.StartAddress) + return; + outs() << "Function Table:\n" + << format(" Start Address: 0x%04x\n", RF.StartAddress) + << format(" End Address: 0x%04x\n", RF.EndAddress) + << format(" Unwind Info Address: : 0x%04x\n\n", RF.UnwindInfoOffset); + uintptr_t addr; + if (Obj->getRvaPtr(RF.UnwindInfoOffset, addr)) + return; + printWin64EHUnwindInfo(reinterpret_cast<const Win64EH::UnwindInfo *>(addr)); +} + +/// Prints out the given RuntumeFunction struct for x64, assuming that Obj is +/// pointing to an object file. Unlike executable, fields in RuntumeFunction +/// struct are filled with zeros, but instead there are relocations pointing to +/// them so that the linker will fill targets' RVAs to the fields at link +/// time. This function interprets the relocations to find the data to be used +/// in the resulting executable. +static void printRuntimeFunctionRels(const COFFObjectFile *Obj, + const RuntimeFunction &RF, + uint64_t SectionOffset, + const std::vector<RelocationRef> &Rels) { outs() << "Function Table:\n"; outs() << " Start Address: "; printCOFFSymbolAddress(outs(), Rels, @@ -516,10 +538,17 @@ void llvm::printCOFFUnwindInfo(const COFFObjectFile *Obj) { return; ArrayRef<RuntimeFunction> RFs(RFStart, NumRFs); + bool IsExecutable = Rels.empty(); + if (IsExecutable) { + for (const RuntimeFunction &RF : RFs) + printRuntimeFunction(Obj, RF); + return; + } + for (const RuntimeFunction &RF : RFs) { uint64_t SectionOffset = std::distance(RFs.begin(), &RF) * sizeof(RuntimeFunction); - printRuntimeFunction(Obj, RF, SectionOffset, Rels); + printRuntimeFunctionRels(Obj, RF, SectionOffset, Rels); } } |