Skip to content

Commit 9923565

Browse files
authored
Add CodeView S_LABEL32 symbols for jump table targets (for Windows debugging) (#146121)
This PR provides more information to debuggers and analysis tools on Windows. It adds `S_LABEL32` symbols for each target BB of each jump table. This allows debuggers to insert symbolic labels when disassembling code. `S_LABEL32` symbol records indicate that a location is definitely code, and can optionally associate a string label with the code location. BBs generated for jump tables may or may not have string labels, so it is acceptable for the "name" field within `S_LABEL32` symbols to be an empty string. More importantly, this PR allows Windows analysis tools, such as those that generate hot-patches for the Windows kernel, to use these labels to distinguish code basic blocks from data blocks. Microsoft's analysis tools (similar to Bolt) rely on being able to identify all code blocks, so that the tools can traverse all instructions and verify that important requirements for hot-patching are met. This PR has no effect on code generation. It only affects the CodeView symbols that are emitted into OBJ files, which the linker then repackages into PDB files.
1 parent 5110ac4 commit 9923565

File tree

3 files changed

+34
-5
lines changed

3 files changed

+34
-5
lines changed

llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3566,15 +3566,34 @@ void CodeViewDebug::collectDebugInfoForJumpTables(const MachineFunction *MF,
35663566
break;
35673567
}
35683568

3569-
CurFn->JumpTables.push_back(
3570-
{EntrySize, Base, BaseOffset, Branch,
3571-
MF->getJTISymbol(JumpTableIndex, MMI->getContext()),
3572-
JTI.getJumpTables()[JumpTableIndex].MBBs.size()});
3569+
const MachineJumpTableEntry &JTE = JTI.getJumpTables()[JumpTableIndex];
3570+
JumpTableInfo CVJTI{EntrySize,
3571+
Base,
3572+
BaseOffset,
3573+
Branch,
3574+
MF->getJTISymbol(JumpTableIndex, MMI->getContext()),
3575+
JTE.MBBs.size()};
3576+
for (const auto &MBB : JTE.MBBs)
3577+
CVJTI.Cases.push_back(MBB->getSymbol());
3578+
CurFn->JumpTables.push_back(std::move(CVJTI));
35733579
});
35743580
}
35753581

35763582
void CodeViewDebug::emitDebugInfoForJumpTables(const FunctionInfo &FI) {
3577-
for (auto JumpTable : FI.JumpTables) {
3583+
// Emit S_LABEL32 records for each jump target
3584+
for (const auto &JumpTable : FI.JumpTables) {
3585+
for (const auto &CaseSym : JumpTable.Cases) {
3586+
MCSymbol *LabelEnd = beginSymbolRecord(SymbolKind::S_LABEL32);
3587+
OS.AddComment("Offset and segment");
3588+
OS.emitCOFFSecRel32(CaseSym, 0);
3589+
OS.AddComment("Flags");
3590+
OS.emitInt8(0);
3591+
emitNullTerminatedSymbolName(OS, CaseSym->getName());
3592+
endSymbolRecord(LabelEnd);
3593+
}
3594+
}
3595+
3596+
for (const auto &JumpTable : FI.JumpTables) {
35783597
MCSymbol *JumpTableEnd = beginSymbolRecord(SymbolKind::S_ARMSWITCHTABLE);
35793598
if (JumpTable.Base) {
35803599
OS.AddComment("Base offset");

llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
146146
const MCSymbol *Branch;
147147
const MCSymbol *Table;
148148
size_t TableSize;
149+
std::vector<const MCSymbol *> Cases;
149150
};
150151

151152
// For each function, store a vector of labels to its instructions, as well as

llvm/test/DebugInfo/COFF/jump-table.ll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,15 @@
118118
; CV: GlobalProcIdSym {
119119
; CV: DisplayName: func
120120
; CV-NOT: GlobalProcIdSym
121+
; CV: LabelSym {
122+
; CV-NEXT: Kind: S_LABEL32 (0x1105)
123+
; CV-NEXT: CodeOffset: 0xC0
124+
; CV-NEXT: Segment: 0x0
125+
; CV-NEXT: Flags: 0x0
126+
; CV-NEXT: Flags [ (0x0)
127+
; CV-NEXT: ]
128+
; CV-NEXT: DisplayName:
129+
; CV-NEXT: }
121130
; CV: JumpTableSym {
122131
; CV-NEXT: Kind: S_ARMSWITCHTABLE (0x1159)
123132
; CV-NEXT: BaseOffset: 0x0

0 commit comments

Comments
 (0)