Skip to content

Commit f6d628f

Browse files
committed
[llvm] Win x64 Unwind V2 2/n: Support dumping UOP_Epilog
1 parent 305b25c commit f6d628f

File tree

6 files changed

+273
-31
lines changed

6 files changed

+273
-31
lines changed

llvm/include/llvm/Support/Win64EH.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ union UnwindCode {
124124
uint8_t getOpInfo() const {
125125
return (u.UnwindOpAndOpInfo >> 4) & 0x0F;
126126
}
127+
/// Gets the offset for an UOP_Epilog unwind code.
128+
uint32_t getEpilogOffset() const {
129+
assert(getUnwindOp() == UOP_Epilog);
130+
return (getOpInfo() << 8) | static_cast<uint32_t>(u.CodeOffset);
131+
}
127132
};
128133

129134
enum {
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# RUN: yaml2obj %s -o %t.exe
2+
# RUN: llvm-objdump --unwind-info %t.exe | FileCheck %s
3+
4+
# CHECK-LABEL: Unwind info:
5+
# CHECK-EMPTY:
6+
# CHECK-NEXT: Function Table:
7+
# CHECK-NEXT: Start Address: 0x1010
8+
# CHECK-NEXT: End Address: 0x1017
9+
# CHECK-NEXT: Unwind Info Address: 0x2000
10+
# CHECK-NEXT: Version: 2
11+
# CHECK-NEXT: Flags: 0
12+
# CHECK-NEXT: Size of prolog: 4
13+
# CHECK-NEXT: Number of Codes: 3
14+
# CHECK-NEXT: No frame pointer used
15+
# CHECK-NEXT: Unwind Codes:
16+
# CHECK-NEXT: 0x01: UOP_Epilog atend=yes, length=0x1
17+
# CHECK-NEXT: 0x0b: UOP_Epilog offset=0xB
18+
# CHECK-NEXT: 0x04: UOP_AllocSmall 72
19+
# CHECK-EMPTY:
20+
# CHECK-NEXT: Function Table:
21+
# CHECK-NEXT: Start Address: 0x1020
22+
# CHECK-NEXT: End Address: 0x105c
23+
# CHECK-NEXT: Unwind Info Address: 0x200c
24+
# CHECK-NEXT: Version: 1
25+
# CHECK-NEXT: Flags: 3 UNW_ExceptionHandler UNW_TerminateHandler
26+
# CHECK-NEXT: Size of prolog: 4
27+
# CHECK-NEXT: Number of Codes: 1
28+
# CHECK-NEXT: No frame pointer used
29+
# CHECK-NEXT: Unwind Codes:
30+
# CHECK-NEXT: 0x04: UOP_AllocSmall 56
31+
32+
--- !COFF
33+
OptionalHeader:
34+
AddressOfEntryPoint: 4128
35+
ImageBase: 5368709120
36+
SectionAlignment: 4096
37+
FileAlignment: 512
38+
MajorOperatingSystemVersion: 6
39+
MinorOperatingSystemVersion: 0
40+
MajorImageVersion: 0
41+
MinorImageVersion: 0
42+
MajorSubsystemVersion: 6
43+
MinorSubsystemVersion: 0
44+
Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
45+
DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE ]
46+
SizeOfStackReserve: 1048576
47+
SizeOfStackCommit: 4096
48+
SizeOfHeapReserve: 1048576
49+
SizeOfHeapCommit: 4096
50+
ExportTable:
51+
RelativeVirtualAddress: 0
52+
Size: 0
53+
ImportTable:
54+
RelativeVirtualAddress: 0
55+
Size: 0
56+
ResourceTable:
57+
RelativeVirtualAddress: 0
58+
Size: 0
59+
ExceptionTable:
60+
RelativeVirtualAddress: 12288
61+
Size: 24
62+
CertificateTable:
63+
RelativeVirtualAddress: 0
64+
Size: 0
65+
BaseRelocationTable:
66+
RelativeVirtualAddress: 0
67+
Size: 0
68+
Debug:
69+
RelativeVirtualAddress: 0
70+
Size: 0
71+
Architecture:
72+
RelativeVirtualAddress: 0
73+
Size: 0
74+
GlobalPtr:
75+
RelativeVirtualAddress: 0
76+
Size: 0
77+
TlsTable:
78+
RelativeVirtualAddress: 0
79+
Size: 0
80+
LoadConfigTable:
81+
RelativeVirtualAddress: 0
82+
Size: 0
83+
BoundImport:
84+
RelativeVirtualAddress: 0
85+
Size: 0
86+
IAT:
87+
RelativeVirtualAddress: 0
88+
Size: 0
89+
DelayImportDescriptor:
90+
RelativeVirtualAddress: 0
91+
Size: 0
92+
ClrRuntimeHeader:
93+
RelativeVirtualAddress: 0
94+
Size: 0
95+
header:
96+
Machine: IMAGE_FILE_MACHINE_AMD64
97+
Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE ]
98+
sections:
99+
- Name: .text
100+
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
101+
VirtualAddress: 4096
102+
VirtualSize: 8
103+
SectionData: 00000000
104+
- Name: .xdata
105+
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
106+
VirtualAddress: 8192
107+
VirtualSize: 40
108+
SectionData: 0204030001160B0604820000190401000462000070100000FFFF010804051E0009330000
109+
- Name: .pdata
110+
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
111+
VirtualAddress: 12288
112+
VirtualSize: 24
113+
SectionData: 101000001710000000200000201000005C1000000C200000
114+
symbols:
115+
- Name: .text
116+
Value: 0
117+
SectionNumber: 1
118+
SimpleType: IMAGE_SYM_TYPE_NULL
119+
ComplexType: IMAGE_SYM_DTYPE_NULL
120+
StorageClass: IMAGE_SYM_CLASS_STATIC
121+
- Name: .xdata
122+
Value: 0
123+
SectionNumber: 2
124+
SimpleType: IMAGE_SYM_TYPE_NULL
125+
ComplexType: IMAGE_SYM_DTYPE_NULL
126+
StorageClass: IMAGE_SYM_CLASS_STATIC
127+
- Name: .pdata
128+
Value: 0
129+
SectionNumber: 3
130+
SimpleType: IMAGE_SYM_TYPE_NULL
131+
ComplexType: IMAGE_SYM_DTYPE_NULL
132+
StorageClass: IMAGE_SYM_CLASS_STATIC
133+
- Name: other
134+
Value: 0
135+
SectionNumber: 1
136+
SimpleType: IMAGE_SYM_TYPE_NULL
137+
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
138+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
139+
- Name: _ZN4RAIID2Ev
140+
Value: 16
141+
SectionNumber: 1
142+
SimpleType: IMAGE_SYM_TYPE_NULL
143+
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
144+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
145+
- Name: entry
146+
Value: 32
147+
SectionNumber: 1
148+
SimpleType: IMAGE_SYM_TYPE_NULL
149+
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
150+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
151+
- Name: _ZN4RAIID1Ev
152+
Value: 16
153+
SectionNumber: 1
154+
SimpleType: IMAGE_SYM_TYPE_NULL
155+
ComplexType: IMAGE_SYM_DTYPE_NULL
156+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
157+
- Name: _Unwind_Resume
158+
Value: 96
159+
SectionNumber: 1
160+
SimpleType: IMAGE_SYM_TYPE_NULL
161+
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
162+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
163+
- Name: __gxx_personality_seh0
164+
Value: 112
165+
SectionNumber: 1
166+
SimpleType: IMAGE_SYM_TYPE_NULL
167+
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
168+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
169+
- Name: GCC_except_table2
170+
Value: 20
171+
SectionNumber: 2
172+
SimpleType: IMAGE_SYM_TYPE_NULL
173+
ComplexType: IMAGE_SYM_DTYPE_NULL
174+
StorageClass: IMAGE_SYM_CLASS_STATIC
175+
...

llvm/test/tools/llvm-readobj/COFF/unwind-x86_64-image.yaml

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,47 @@
11
# RUN: yaml2obj %s -o %t.exe
22
# RUN: llvm-readobj --unwind %t.exe | FileCheck %s
33

4-
# CHECK: RuntimeFunction {
5-
# CHECK: StartAddress: entry (0x140001020)
6-
# CHECK-NEXT: EndAddress: (0x14000105C)
7-
# CHECK-NEXT: UnwindInfoAddress: (0x140002008)
8-
# CHECK-NEXT: UnwindInfo {
9-
# CHECK-NEXT: Version: 1
10-
# CHECK-NEXT: Flags [ (0x3)
11-
# CHECK-NEXT: ExceptionHandler (0x1)
12-
# CHECK-NEXT: TerminateHandler (0x2)
13-
# CHECK-NEXT: ]
14-
# CHECK-NEXT: PrologSize: 4
15-
# CHECK-NEXT: FrameRegister: -
16-
# CHECK-NEXT: FrameOffset: -
17-
# CHECK-NEXT: UnwindCodeCount: 1
18-
# CHECK-NEXT: UnwindCodes [
19-
# CHECK-NEXT: 0x04: ALLOC_SMALL size=56
20-
# CHECK-NEXT: ]
21-
# CHECK-NEXT: Handler: __gxx_personality_seh0 (0x140001070)
4+
# CHECK-LABEL: UnwindInformation [
5+
# CHECK-NEXT: RuntimeFunction {
6+
# CHECK-NEXT: StartAddress: _ZN4RAIID2Ev (0x140001010)
7+
# CHECK-NEXT: EndAddress: (0x140001017)
8+
# CHECK-NEXT: UnwindInfoAddress: .xdata (0x140002000)
9+
# CHECK-NEXT: UnwindInfo {
10+
# CHECK-NEXT: Version: 2
11+
# CHECK-NEXT: Flags [ (0x0)
12+
# CHECK-NEXT: ]
13+
# CHECK-NEXT: PrologSize: 4
14+
# CHECK-NEXT: FrameRegister: -
15+
# CHECK-NEXT: FrameOffset: -
16+
# CHECK-NEXT: UnwindCodeCount: 3
17+
# CHECK-NEXT: UnwindCodes [
18+
# CHECK-NEXT: 0x01: EPILOG atend=yes, length=0x1
19+
# CHECK-NEXT: 0x0B: EPILOG offset=0xB
20+
# CHECK-NEXT: 0x04: ALLOC_SMALL size=72
21+
# CHECK-NEXT: ]
22+
# CHECK-NEXT: }
2223
# CHECK-NEXT: }
23-
# CHECK-NEXT: }
24+
# CHECK-NEXT: RuntimeFunction {
25+
# CHECK-NEXT: StartAddress: entry (0x140001020)
26+
# CHECK-NEXT: EndAddress: (0x14000105C)
27+
# CHECK-NEXT: UnwindInfoAddress: (0x14000200C)
28+
# CHECK-NEXT: UnwindInfo {
29+
# CHECK-NEXT: Version: 1
30+
# CHECK-NEXT: Flags [ (0x3)
31+
# CHECK-NEXT: ExceptionHandler (0x1)
32+
# CHECK-NEXT: TerminateHandler (0x2)
33+
# CHECK-NEXT: ]
34+
# CHECK-NEXT: PrologSize: 4
35+
# CHECK-NEXT: FrameRegister: -
36+
# CHECK-NEXT: FrameOffset: -
37+
# CHECK-NEXT: UnwindCodeCount: 1
38+
# CHECK-NEXT: UnwindCodes [
39+
# CHECK-NEXT: 0x04: ALLOC_SMALL size=56
40+
# CHECK-NEXT: ]
41+
# CHECK-NEXT: Handler: __gxx_personality_seh0 (0x140001070)
42+
# CHECK-NEXT: }
43+
# CHECK-NEXT: }
44+
# CHECK-NEXT: ]
2445

2546
--- !COFF
2647
OptionalHeader:
@@ -92,18 +113,18 @@ sections:
92113
- Name: .text
93114
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
94115
VirtualAddress: 4096
95-
VirtualSize: 113
96-
SectionData: C3662E0F1F8400000000000F1F4400005048890C2458C3660F1F8400000000004883EC38E8D7FFFFFFE900000000488D4C2430E8D8FFFFFF904883C438C3488944242889542424488D4C2430E8BFFFFFFF488B4C2428E805000000CC0F1F4000C3662E0F1F8400000000000F1F440000C3
97-
- Name: .rdata
116+
VirtualSize: 8
117+
SectionData: 00000000
118+
- Name: .xdata
98119
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
99120
VirtualAddress: 8192
100-
VirtualSize: 32
101-
SectionData: 0101010001020000190401000462000070100000FFFF010804051E0009330000
121+
VirtualSize: 40
122+
SectionData: 0204030001160B0604820000190401000462000070100000FFFF010804051E0009330000
102123
- Name: .pdata
103124
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
104125
VirtualAddress: 12288
105126
VirtualSize: 24
106-
SectionData: 101000001710000000200000201000005C10000008200000
127+
SectionData: 101000001710000000200000201000005C1000000C200000
107128
symbols:
108129
- Name: .text
109130
Value: 0

llvm/tools/llvm-objdump/COFFDump.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,10 @@ static unsigned getNumUsedSlots(const UnwindCode &UnwindCode) {
240240
case UOP_AllocSmall:
241241
case UOP_SetFPReg:
242242
case UOP_PushMachFrame:
243+
case UOP_Epilog:
243244
return 1;
244245
case UOP_SaveNonVol:
245246
case UOP_SaveXMM128:
246-
case UOP_Epilog:
247247
return 2;
248248
case UOP_SaveNonVolBig:
249249
case UOP_SaveXMM128Big:
@@ -257,7 +257,7 @@ static unsigned getNumUsedSlots(const UnwindCode &UnwindCode) {
257257
// Prints one unwind code. Because an unwind code can occupy up to 3 slots in
258258
// the unwind codes array, this function requires that the correct number of
259259
// slots is provided.
260-
static void printUnwindCode(ArrayRef<UnwindCode> UCs) {
260+
static void printUnwindCode(ArrayRef<UnwindCode> UCs, bool &SeenFirstEpilog) {
261261
assert(UCs.size() >= getNumUsedSlots(UCs[0]));
262262
outs() << format(" 0x%02x: ", unsigned(UCs[0].u.CodeOffset))
263263
<< getUnwindCodeTypeName(UCs[0].getUnwindOp());
@@ -301,11 +301,29 @@ static void printUnwindCode(ArrayRef<UnwindCode> UCs) {
301301
outs() << " " << (UCs[0].getOpInfo() ? "w/o" : "w")
302302
<< " error code";
303303
break;
304+
305+
case UOP_Epilog:
306+
if (SeenFirstEpilog) {
307+
uint32_t Offset = UCs[0].getEpilogOffset();
308+
if (Offset == 0) {
309+
outs() << " padding";
310+
} else {
311+
outs() << " offset=" << format("0x%X", Offset);
312+
}
313+
} else {
314+
SeenFirstEpilog = true;
315+
bool AtEnd = (UCs[0].getOpInfo() & 0x1) != 0;
316+
uint32_t Length = UCs[0].u.CodeOffset;
317+
outs() << " atend=" << (AtEnd ? "yes" : "no")
318+
<< ", length=" << format("0x%X", Length);
319+
}
320+
break;
304321
}
305322
outs() << "\n";
306323
}
307324

308325
static void printAllUnwindCodes(ArrayRef<UnwindCode> UCs) {
326+
bool SeenFirstEpilog = false;
309327
for (const UnwindCode *I = UCs.begin(), *E = UCs.end(); I < E; ) {
310328
unsigned UsedSlots = getNumUsedSlots(*I);
311329
if (UsedSlots > UCs.size()) {
@@ -316,7 +334,7 @@ static void printAllUnwindCodes(ArrayRef<UnwindCode> UCs) {
316334
<< " remaining in buffer";
317335
return ;
318336
}
319-
printUnwindCode(ArrayRef(I, E));
337+
printUnwindCode(ArrayRef(I, E), SeenFirstEpilog);
320338
I += UsedSlots;
321339
}
322340
}

0 commit comments

Comments
 (0)