summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/tools/llvm-objdump/Inputs/win64-unwind.exe.coff-x86_64.exebin0 -> 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)bin698 -> 698 bytes
-rw-r--r--test/tools/llvm-objdump/win64-unwind-data.test155
-rw-r--r--tools/llvm-objdump/COFFDump.cpp37
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
new file mode 100644
index 0000000000..c701c24fb8
--- /dev/null
+++ b/test/tools/llvm-objdump/Inputs/win64-unwind.exe.coff-x86_64.exe
Binary files differ
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
index 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
Binary files differ
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);
}
}