Skip to content

Commit 6a24ee6

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 3. Actually compiler has generated symbols and jump tables. But unfortunately for previous patch, the symbols are not visible in symbol table and the section is '.rodata' and this makes it is hard to inspect binary for jump tables. For computed goto, to make jump table symbol visible in symbol table, a pass is added in BPFMIPeephole.cpp such that it will - Change linkage from PrivateLinkage to InternalLinkage to avoid adding '.L' prefix. - Change section from '.rodata' to '.jumptables'. With the above, the following are some asm and objdump codes. Asm code: ... r2 <<= 3 r3 = __const.foo.jt2 ll r3 += r2 r1 <<= 32 r1 s>>= 32 r1 <<= 3 r2 = __const.foo.jt1 ll r2 += r1 w0 = 0 r1 = *(u64 *)(r2 + 0) gotox r1 goto LBB0_4 ... .type __const.foo.jt1,@object # @__const.foo.jt1 .section .jumptables,"a",@progbits .p2align 3, 0x0 __const.foo.jt1: .quad .Ltmp0 .quad .Ltmp1 .size __const.foo.jt1, 16 .type __const.foo.jt2,@object # @__const.foo.jt2 .p2align 3, 0x0 __const.foo.jt2: .quad .Ltmp2 .quad .Ltmp3 .size __const.foo.jt2, 16 objdump code: ... 14: 67 02 00 00 03 00 00 00 r2 <<= 0x3 15: 18 03 00 00 10 00 00 00 00 00 00 00 00 00 00 00 r3 = 0x10 ll 0000000000000078: R_BPF_64_64 .jumptables 17: 0f 23 00 00 00 00 00 00 r3 += r2 18: 67 01 00 00 20 00 00 00 r1 <<= 0x20 19: c7 01 00 00 20 00 00 00 r1 s>>= 0x20 20: 67 01 00 00 03 00 00 00 r1 <<= 0x3 21: 18 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r2 = 0x0 ll 00000000000000a8: R_BPF_64_64 .jumptables 23: 0f 12 00 00 00 00 00 00 r2 += r1 [ 4] .jumptables PROGBITS 0000000000000000 000170 000020 00 A 0 0 8 3: 0000000000000010 16 OBJECT LOCAL DEFAULT 4 __const.foo.jt2 4: 0000000000000000 16 OBJECT LOCAL DEFAULT 4 __const.foo.jt1 5: 0000000000000000 0 SECTION LOCAL DEFAULT 4 .jumptables
1 parent 667db88 commit 6a24ee6

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

llvm/lib/Target/BPF/BPFMIPeephole.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "llvm/CodeGen/MachineFunctionPass.h"
3131
#include "llvm/CodeGen/MachineInstrBuilder.h"
3232
#include "llvm/CodeGen/MachineRegisterInfo.h"
33+
#include "llvm/IR/Module.h"
3334
#include "llvm/Support/Debug.h"
3435
#include <set>
3536

@@ -308,6 +309,7 @@ struct BPFMIPreEmitPeephole : public MachineFunctionPass {
308309
const TargetRegisterInfo *TRI;
309310
const BPFInstrInfo *TII;
310311
bool SupportGotol;
312+
bool DoneConvertPrivGlobal;
311313

312314
BPFMIPreEmitPeephole() : MachineFunctionPass(ID) {}
313315

@@ -321,6 +323,7 @@ struct BPFMIPreEmitPeephole : public MachineFunctionPass {
321323
bool insertMissingCallerSavedSpills();
322324
bool removeMayGotoZero();
323325
bool addExitAfterUnreachable();
326+
bool convertPrivateGlobal();
324327

325328
public:
326329

@@ -338,6 +341,7 @@ struct BPFMIPreEmitPeephole : public MachineFunctionPass {
338341
Changed |= insertMissingCallerSavedSpills();
339342
Changed |= removeMayGotoZero();
340343
Changed |= addExitAfterUnreachable();
344+
Changed |= convertPrivateGlobal();
341345
return Changed;
342346
}
343347
};
@@ -348,6 +352,7 @@ void BPFMIPreEmitPeephole::initialize(MachineFunction &MFParm) {
348352
TII = MF->getSubtarget<BPFSubtarget>().getInstrInfo();
349353
TRI = MF->getSubtarget<BPFSubtarget>().getRegisterInfo();
350354
SupportGotol = MF->getSubtarget<BPFSubtarget>().hasGotol();
355+
DoneConvertPrivGlobal = false;
351356
LLVM_DEBUG(dbgs() << "*** BPF PreEmit peephole pass ***\n\n");
352357
}
353358

@@ -750,6 +755,48 @@ bool BPFMIPreEmitPeephole::addExitAfterUnreachable() {
750755
return true;
751756
}
752757

758+
bool BPFMIPreEmitPeephole::convertPrivateGlobal() {
759+
if (DoneConvertPrivGlobal)
760+
return false;
761+
DoneConvertPrivGlobal = true;
762+
763+
// A jump table associated with indirectbr looks like:
764+
// @__const.foo.jt1 = private unnamed_addr constant [2 x ptr]
765+
// [ptr blockaddress(@foo, %l1), ptr blockaddress(@foo, %l2)], align 8
766+
Module *M = MF->getFunction().getParent();
767+
for (GlobalVariable &Global : M->globals()) {
768+
if (Global.getLinkage() != GlobalValue::PrivateLinkage)
769+
continue;
770+
if (!Global.isConstant())
771+
continue;
772+
if (!Global.hasInitializer())
773+
continue;
774+
775+
Constant *CV = dyn_cast<Constant>(Global.getInitializer());
776+
if (!CV)
777+
continue;
778+
ConstantArray *CA = dyn_cast<ConstantArray>(CV);
779+
if (!CA)
780+
continue;
781+
782+
for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
783+
if (!dyn_cast<BlockAddress>(CA->getOperand(i)))
784+
continue;
785+
}
786+
787+
// All jump tables in the same .jumptables section.
788+
Global.setSection(".jumptables");
789+
790+
// The global symbol with PrivateLinkage (e.g. __const.foo.jt1) will add
791+
// a prefix like '.L' (e.g. .L__const.foo.jt1) which will prevent symbol
792+
// from appearing in the symbol table. Changing linkage type from
793+
// PrivateLinkage to InternalLinkage can preserve the symbol name and
794+
// keep the symbol in the symbol table.
795+
Global.setLinkage(GlobalValue::InternalLinkage);
796+
}
797+
return true;
798+
}
799+
753800
} // end default namespace
754801

755802
INITIALIZE_PASS(BPFMIPreEmitPeephole, "bpf-mi-pemit-peephole",

0 commit comments

Comments
 (0)