Skip to content

Commit f23540f

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

File tree

3 files changed

+49
-6
lines changed

3 files changed

+49
-6
lines changed

llvm/tools/llvm-objdump/COFFDump.cpp

Lines changed: 22 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,30 @@ 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].getOpInfo() << 8) |
308+
static_cast<uint32_t>(UCs[0].u.CodeOffset);
309+
if (Offset == 0) {
310+
outs() << " padding";
311+
} else {
312+
outs() << " offset=" << format("0x%X", Offset);
313+
}
314+
} else {
315+
SeenFirstEpilog = true;
316+
bool AtEnd = (UCs[0].getOpInfo() & 0x1) != 0;
317+
uint32_t Length = UCs[0].u.CodeOffset;
318+
outs() << " atend=" << (AtEnd ? "yes" : "no")
319+
<< ", length=" << format("0x%X", Length);
320+
}
321+
break;
304322
}
305323
outs() << "\n";
306324
}
307325

308326
static void printAllUnwindCodes(ArrayRef<UnwindCode> UCs) {
327+
bool SeenFirstEpilog = false;
309328
for (const UnwindCode *I = UCs.begin(), *E = UCs.end(); I < E; ) {
310329
unsigned UsedSlots = getNumUsedSlots(*I);
311330
if (UsedSlots > UCs.size()) {
@@ -316,7 +335,7 @@ static void printAllUnwindCodes(ArrayRef<UnwindCode> UCs) {
316335
<< " remaining in buffer";
317336
return ;
318337
}
319-
printUnwindCode(ArrayRef(I, E));
338+
printUnwindCode(ArrayRef(I, E), SeenFirstEpilog);
320339
I += UsedSlots;
321340
}
322341
}

llvm/tools/llvm-readobj/Win64EHDumper.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ static StringRef getUnwindCodeTypeName(uint8_t Code) {
6565
case UOP_SaveXMM128: return "SAVE_XMM128";
6666
case UOP_SaveXMM128Big: return "SAVE_XMM128_FAR";
6767
case UOP_PushMachFrame: return "PUSH_MACHFRAME";
68+
case UOP_Epilog:
69+
return "EPILOG";
6870
}
6971
}
7072

@@ -99,6 +101,7 @@ static unsigned getNumUsedSlots(const UnwindCode &UnwindCode) {
99101
case UOP_AllocSmall:
100102
case UOP_SetFPReg:
101103
case UOP_PushMachFrame:
104+
case UOP_Epilog:
102105
return 1;
103106
case UOP_SaveNonVol:
104107
case UOP_SaveXMM128:
@@ -254,7 +257,8 @@ void Dumper::printRuntimeFunctionEntry(const Context &Ctx,
254257
// Prints one unwind code. Because an unwind code can occupy up to 3 slots in
255258
// the unwind codes array, this function requires that the correct number of
256259
// slots is provided.
257-
void Dumper::printUnwindCode(const UnwindInfo& UI, ArrayRef<UnwindCode> UC) {
260+
void Dumper::printUnwindCode(const UnwindInfo &UI, ArrayRef<UnwindCode> UC,
261+
bool &SeenFirstEpilog) {
258262
assert(UC.size() >= getNumUsedSlots(UC[0]));
259263

260264
SW.startLine() << format("0x%02X: ", unsigned(UC[0].u.CodeOffset))
@@ -306,6 +310,24 @@ void Dumper::printUnwindCode(const UnwindInfo& UI, ArrayRef<UnwindCode> UC) {
306310
case UOP_PushMachFrame:
307311
OS << " errcode=" << (UC[0].getOpInfo() == 0 ? "no" : "yes");
308312
break;
313+
314+
case UOP_Epilog:
315+
if (SeenFirstEpilog) {
316+
uint32_t Offset =
317+
(UC[0].getOpInfo() << 8) | static_cast<uint32_t>(UC[0].u.CodeOffset);
318+
if (Offset == 0) {
319+
OS << " padding";
320+
} else {
321+
OS << " offset=" << format("0x%X", Offset);
322+
}
323+
} else {
324+
SeenFirstEpilog = true;
325+
bool AtEnd = (UC[0].getOpInfo() & 0x1) != 0;
326+
uint32_t Length = UC[0].u.CodeOffset;
327+
OS << " atend=" << (AtEnd ? "yes" : "no")
328+
<< ", length=" << format("0x%X", Length);
329+
}
330+
break;
309331
}
310332

311333
OS << "\n";
@@ -330,14 +352,15 @@ void Dumper::printUnwindInfo(const Context &Ctx, const coff_section *Section,
330352
{
331353
ListScope UCS(SW, "UnwindCodes");
332354
ArrayRef<UnwindCode> UC(&UI.UnwindCodes[0], UI.NumCodes);
355+
bool SeenFirstEpilog = false;
333356
for (const UnwindCode *UCI = UC.begin(), *UCE = UC.end(); UCI < UCE; ++UCI) {
334357
unsigned UsedSlots = getNumUsedSlots(*UCI);
335358
if (UsedSlots > UC.size()) {
336359
errs() << "corrupt unwind data";
337360
return;
338361
}
339362

340-
printUnwindCode(UI, ArrayRef(UCI, UCE));
363+
printUnwindCode(UI, ArrayRef(UCI, UCE), SeenFirstEpilog);
341364
UCI = UCI + UsedSlots - 1;
342365
}
343366
}

llvm/tools/llvm-readobj/Win64EHDumper.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ class Dumper {
4444
const object::coff_section *Section,
4545
uint64_t SectionOffset,
4646
const RuntimeFunction &RF);
47-
void printUnwindCode(const UnwindInfo& UI, ArrayRef<UnwindCode> UC);
47+
void printUnwindCode(const UnwindInfo &UI, ArrayRef<UnwindCode> UC,
48+
bool &SeenFirstEpilog);
4849
void printUnwindInfo(const Context &Ctx, const object::coff_section *Section,
4950
off_t Offset, const UnwindInfo &UI);
5051
void printRuntimeFunction(const Context &Ctx,

0 commit comments

Comments
 (0)