Skip to content

Commit a26a805

Browse files
author
Yonghong Song
committed
[BPF] Use visible symbols and dedicated jump tables for computed goto
For computed goto, the llvm won't generate JumpTableInfo. Note that JumpTableInfo is generated for switch statements. See previous example 2 and 3. Example 2 does not have jump table. Example 3 has jump table, but the symbols are not visible in symbol table. The section is '.rodata' and this makes it hard to inspect binary for jump tables. This patch addressed the issue for example 2/3. The final jump table is similar to the example 1. For the previous example 2, Compile: clang --target=bpf -mcpu=v4 -O2 -S test1.c Asm code: ... # %bb.0: # %entry r2 = BPF.JT.0.0 ll if w1 == 0 goto LBB0_2 # %bb.1: # %entry r2 = BPF.JT.0.1 ll LBB0_2: # %entry *(u64 *)(r10 - 8) = r2 r1 = *(u64 *)(r10 - 8) gotox r1 ... .section .jumptables,"",@progbits BPF.JT.0.0: .long LBB0_4 .size BPF.JT.0.0, 4 BPF.JT.0.1: .long LBB0_3 .size BPF.JT.0.1, 4 The binary: clang --target=bpf -mcpu=v4 -O2 -c test1.c 0: 18 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r2 = 0x0 ll 0000000000000000: R_BPF_64_64 BPF.JT.0.0 2: 16 01 02 00 00 00 00 00 if w1 == 0x0 goto +0x2 <bar+0x28> 3: 18 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r2 = 0x0 ll 0000000000000018: R_BPF_64_64 BPF.JT.0.1 5: 7b 2a f8 ff 00 00 00 00 *(u64 *)(r10 - 0x8) = r2 6: 79 a1 f8 ff 00 00 00 00 r1 = *(u64 *)(r10 - 0x8) 7: 0d 01 00 00 00 00 00 00 gotox r1 4: 0000000000000000 4 OBJECT GLOBAL DEFAULT 4 BPF.JT.0.0 5: 0000000000000004 4 OBJECT GLOBAL DEFAULT 4 BPF.JT.0.1 [ 4] .jumptables PROGBITS 0000000000000000 0000a0 000008 00 0 0 1 For the previous example 3, Compile: clang --target=bpf -mcpu=v4 -O2 -S test.c Asm code: ... r3 = (s32)r2 r3 <<= 3 r2 = BPF.JT.0.0 ll r2 += r3 r1 = (s32)r1 r1 <<= 3 r3 = BPF.JT.0.1 ll r3 += r1 w0 = 0 r1 = *(u64 *)(r3 + 0) gotox r1 .Ltmp0: # Block address taken LBB0_1: # %l1 # =>This Inner Loop Header: Depth=1 w0 += 1 ... .section .jumptables,"",@progbits BPF.JT.0.0: .long LBB0_3 .long LBB0_4 .size BPF.JT.0.0, 8 BPF.JT.0.1: .long LBB0_1 .long LBB0_2 .size BPF.JT.0.1, 8 The binary: clang --target=bpf -mcpu=v4 -O2 -c test2.c 12: bf 23 20 00 00 00 00 00 r3 = (s32)r2 13: 67 03 00 00 03 00 00 00 r3 <<= 0x3 14: 18 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r2 = 0x0 ll 0000000000000070: R_BPF_64_64 BPF.JT.0.0 16: 0f 32 00 00 00 00 00 00 r2 += r3 17: bf 11 20 00 00 00 00 00 r1 = (s32)r1 18: 67 01 00 00 03 00 00 00 r1 <<= 0x3 19: 18 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r3 = 0x0 ll 0000000000000098: R_BPF_64_64 BPF.JT.0.1 21: 0f 13 00 00 00 00 00 00 r3 += r1 4: 0000000000000000 8 OBJECT GLOBAL DEFAULT 4 BPF.JT.0.0 5: 0000000000000008 8 OBJECT GLOBAL DEFAULT 4 BPF.JT.0.1 [ 4] .jumptables PROGBITS 0000000000000000 000160 000010 00 0 0 1
1 parent 296234e commit a26a805

File tree

3 files changed

+73
-2
lines changed

3 files changed

+73
-2
lines changed

llvm/lib/Target/BPF/BPFAsmPrinter.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,71 @@ MCSymbol *BPFAsmPrinter::getJTPublicSymbol(unsigned JTI) {
145145
return S;
146146
}
147147

148+
MCSymbol *BPFAsmPrinter::getJTPublicSymbol(const BlockAddress *BA) {
149+
BasicBlock *BB = BA->getBasicBlock();
150+
151+
MachineBasicBlock *MBB = nullptr;
152+
for (MachineBasicBlock &MB : *MF) {
153+
if (MB.getBasicBlock() == BB) {
154+
MBB = &MB;
155+
break;
156+
}
157+
}
158+
assert(MBB);
159+
160+
std::vector<MachineBasicBlock *> Targets;
161+
Targets.push_back(MBB);
162+
163+
unsigned JTI =
164+
MF->getOrCreateJumpTableInfo(MachineJumpTableInfo::EK_LabelDifference32)
165+
->createJumpTableIndex(Targets);
166+
return getJTPublicSymbol(JTI);
167+
}
168+
169+
MCSymbol *BPFAsmPrinter::getJTPublicSymbol(const GlobalValue *GVal) {
170+
auto *GV = dyn_cast<GlobalVariable>(GVal);
171+
if (!GV)
172+
return NULL;
173+
if (GV->getLinkage() != GlobalValue::PrivateLinkage)
174+
return NULL;
175+
if (!GV->isConstant() || !GV->hasInitializer())
176+
return NULL;
177+
178+
const Constant *CV = dyn_cast<Constant>(GV->getInitializer());
179+
if (!CV)
180+
return NULL;
181+
const ConstantArray *CA = dyn_cast<ConstantArray>(CV);
182+
if (!CA)
183+
return NULL;
184+
185+
for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) {
186+
if (!dyn_cast<BlockAddress>(CA->getOperand(i)))
187+
return NULL;
188+
}
189+
190+
std::vector<MachineBasicBlock *> Targets;
191+
for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) {
192+
BlockAddress *BA = dyn_cast<BlockAddress>(CA->getOperand(i));
193+
BasicBlock *BB = BA->getBasicBlock();
194+
195+
MachineBasicBlock *MBB = nullptr;
196+
for (MachineBasicBlock &MB : *MF) {
197+
if (MB.getBasicBlock() == BB) {
198+
MBB = &MB;
199+
break;
200+
}
201+
}
202+
203+
Targets.push_back(MBB);
204+
}
205+
assert(Targets.size());
206+
207+
unsigned JTI =
208+
MF->getOrCreateJumpTableInfo(MachineJumpTableInfo::EK_LabelDifference32)
209+
->createJumpTableIndex(Targets);
210+
return getJTPublicSymbol(JTI);
211+
}
212+
148213
void BPFAsmPrinter::emitJumpTableInfo() {
149214
const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
150215
if (!MJTI)

llvm/lib/Target/BPF/BPFAsmPrinter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ class BPFAsmPrinter : public AsmPrinter {
3030

3131
void emitInstruction(const MachineInstr *MI) override;
3232
MCSymbol *getJTPublicSymbol(unsigned JTI);
33+
MCSymbol *getJTPublicSymbol(const BlockAddress *BA);
34+
MCSymbol *getJTPublicSymbol(const GlobalValue *GVal);
3335
virtual void emitJumpTableInfo() override;
3436

3537
static char ID;

llvm/lib/Target/BPF/BPFMCInstLower.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ using namespace llvm;
2828

2929
MCSymbol *
3030
BPFMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
31-
return Printer.getSymbol(MO.getGlobal());
31+
const GlobalValue *GVal = MO.getGlobal();
32+
MCSymbol *Sym = Printer.getJTPublicSymbol(GVal);
33+
if (!Sym)
34+
Sym = Printer.getSymbol(GVal);
35+
return Sym;
3236
}
3337

3438
MCSymbol *
@@ -85,7 +89,7 @@ void BPFMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
8589
break;
8690
case MachineOperand::MO_BlockAddress:
8791
MCOp = LowerSymbolOperand(
88-
MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress()));
92+
MO, Printer.getJTPublicSymbol(MO.getBlockAddress()));
8993
break;
9094
}
9195

0 commit comments

Comments
 (0)