Skip to content

Commit e0de14e

Browse files
author
Yonghong Song
committed
[BPF] Use visible symbols and dedicated jump tables for switch statements
For jumptables from switch statements, generate 'llvm-readelf -s' visible symbols and put jumptables into a dedicated section. Most work from Eduard. For the previous example 1, Compile: clang --target=bpf -O2 -S test.c Asm code: # %bb.1: # %entry r1 <<= 3 r2 = BPF.JT.0.0 ll r2 += r1 r1 = *(u64 *)(r2 + 0) gotox r1 LBB0_2: w1 = 18 goto LBB0_9 ... # %bb.10: # %sw.epilog r1 <<= 3 r2 = BPF.JT.0.1 ll r2 += r1 r1 = *(u64 *)(r2 + 0) gotox r1 LBB0_11: w1 = 8 goto LBB0_16 ... .section .jumptables,"",@progbits BPF.JT.0.0: .quad LBB0_2 .quad LBB0_8 ... .quad LBB0_7 .size BPF.JT.0.0, 240 BPF.JT.0.1: .quad LBB0_11 .quad LBB0_13 ... .quad LBB0_12 .size BPF.JT.0.1, 256 And symbols BPF.JT.0.{0,1} will be in symbol table. The final binary: 4: 67 01 00 00 03 00 00 00 r1 <<= 0x3 5: 18 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r2 = 0x0 ll 0000000000000028: R_BPF_64_64 BPF.JT.0.0 7: 0f 12 00 00 00 00 00 00 r2 += r1 ... 29: 67 01 00 00 03 00 00 00 r1 <<= 0x3 30: 18 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r2 = 0x0 ll 00000000000000f0: R_BPF_64_64 BPF.JT.0.1 32: 0f 12 00 00 00 00 00 00 r2 += r1 ... Symbol table: 4: 0000000000000000 240 OBJECT GLOBAL DEFAULT 4 BPF.JT.0.0 5: 0000000000000000 4 OBJECT GLOBAL DEFAULT 6 ret_user 6: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND bar 7: 00000000000000f0 256 OBJECT GLOBAL DEFAULT 4 BPF.JT.0.1 and [ 4] .jumptables PROGBITS 0000000000000000 0001c8 0001f0 00 0 0 1 This will make things easier when inspecting the binary about jump table.
1 parent e13937c commit e0de14e

File tree

8 files changed

+147
-29
lines changed

8 files changed

+147
-29
lines changed

llvm/lib/Target/BPF/BPFAsmPrinter.cpp

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,52 +11,35 @@
1111
//
1212
//===----------------------------------------------------------------------===//
1313

14+
#include "BPFAsmPrinter.h"
1415
#include "BPF.h"
1516
#include "BPFInstrInfo.h"
1617
#include "BPFMCInstLower.h"
1718
#include "BTFDebug.h"
1819
#include "MCTargetDesc/BPFInstPrinter.h"
1920
#include "TargetInfo/BPFTargetInfo.h"
21+
#include "llvm/BinaryFormat/ELF.h"
2022
#include "llvm/CodeGen/AsmPrinter.h"
2123
#include "llvm/CodeGen/MachineConstantPool.h"
2224
#include "llvm/CodeGen/MachineInstr.h"
25+
#include "llvm/CodeGen/MachineJumpTableInfo.h"
2326
#include "llvm/CodeGen/MachineModuleInfo.h"
27+
#include "llvm/CodeGen/TargetLowering.h"
2428
#include "llvm/IR/Module.h"
2529
#include "llvm/MC/MCAsmInfo.h"
30+
#include "llvm/MC/MCExpr.h"
2631
#include "llvm/MC/MCInst.h"
2732
#include "llvm/MC/MCStreamer.h"
2833
#include "llvm/MC/MCSymbol.h"
34+
#include "llvm/MC/MCSymbolELF.h"
2935
#include "llvm/MC/TargetRegistry.h"
3036
#include "llvm/Support/Compiler.h"
3137
#include "llvm/Support/raw_ostream.h"
38+
#include "llvm/Target/TargetLoweringObjectFile.h"
3239
using namespace llvm;
3340

3441
#define DEBUG_TYPE "asm-printer"
3542

36-
namespace {
37-
class BPFAsmPrinter : public AsmPrinter {
38-
public:
39-
explicit BPFAsmPrinter(TargetMachine &TM,
40-
std::unique_ptr<MCStreamer> Streamer)
41-
: AsmPrinter(TM, std::move(Streamer), ID), BTF(nullptr) {}
42-
43-
StringRef getPassName() const override { return "BPF Assembly Printer"; }
44-
bool doInitialization(Module &M) override;
45-
void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
46-
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
47-
const char *ExtraCode, raw_ostream &O) override;
48-
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
49-
const char *ExtraCode, raw_ostream &O) override;
50-
51-
void emitInstruction(const MachineInstr *MI) override;
52-
53-
static char ID;
54-
55-
private:
56-
BTFDebug *BTF;
57-
};
58-
} // namespace
59-
6043
bool BPFAsmPrinter::doInitialization(Module &M) {
6144
AsmPrinter::doInitialization(M);
6245

@@ -150,6 +133,49 @@ void BPFAsmPrinter::emitInstruction(const MachineInstr *MI) {
150133
EmitToStreamer(*OutStreamer, TmpInst);
151134
}
152135

136+
MCSymbol *BPFAsmPrinter::getJTPublicSymbol(unsigned JTI) {
137+
SmallString<60> Name;
138+
raw_svector_ostream(Name)
139+
<< "BPF.JT." << MF->getFunctionNumber() << '.' << JTI;
140+
MCSymbol *S = OutContext.getOrCreateSymbol(Name);
141+
if (auto *ES = dyn_cast<MCSymbolELF>(S)) {
142+
ES->setBinding(ELF::STB_GLOBAL);
143+
ES->setType(ELF::STT_OBJECT);
144+
}
145+
return S;
146+
}
147+
148+
void BPFAsmPrinter::emitJumpTableInfo() {
149+
const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
150+
if (!MJTI)
151+
return;
152+
153+
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
154+
if (JT.empty())
155+
return;
156+
157+
const TargetLoweringObjectFile &TLOF = getObjFileLowering();
158+
const Function &F = MF->getFunction();
159+
MCSection *JTS = TLOF.getSectionForJumpTable(F, TM);
160+
assert(MJTI->getEntryKind() == MachineJumpTableInfo::EK_BlockAddress);
161+
unsigned EntrySize = MJTI->getEntrySize(getDataLayout());
162+
OutStreamer->switchSection(JTS);
163+
for (unsigned JTI = 0; JTI < JT.size(); JTI++) {
164+
ArrayRef<MachineBasicBlock *> JTBBs = JT[JTI].MBBs;
165+
if (JTBBs.empty())
166+
continue;
167+
168+
MCSymbol *JTStart = getJTPublicSymbol(JTI);
169+
OutStreamer->emitLabel(JTStart);
170+
for (const MachineBasicBlock *MBB : JTBBs) {
171+
const MCExpr *LHS = MCSymbolRefExpr::create(MBB->getSymbol(), OutContext);
172+
OutStreamer->emitValue(LHS, EntrySize);
173+
}
174+
const MCExpr *JTSize = MCConstantExpr::create(JTBBs.size() * 8, OutContext);
175+
OutStreamer->emitELFSize(JTStart, JTSize);
176+
}
177+
}
178+
153179
char BPFAsmPrinter::ID = 0;
154180

155181
INITIALIZE_PASS(BPFAsmPrinter, "bpf-asm-printer", "BPF Assembly Printer", false,
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//===-- BPFFrameLowering.h - Define frame lowering for BPF -----*- C++ -*--===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIB_TARGET_BPF_BPFASMPRINTER_H
10+
#define LLVM_LIB_TARGET_BPF_BPFASMPRINTER_H
11+
12+
#include "BTFDebug.h"
13+
#include "llvm/CodeGen/AsmPrinter.h"
14+
15+
namespace llvm {
16+
17+
class BPFAsmPrinter : public AsmPrinter {
18+
public:
19+
explicit BPFAsmPrinter(TargetMachine &TM,
20+
std::unique_ptr<MCStreamer> Streamer)
21+
: AsmPrinter(TM, std::move(Streamer), ID), BTF(nullptr) {}
22+
23+
StringRef getPassName() const override { return "BPF Assembly Printer"; }
24+
bool doInitialization(Module &M) override;
25+
void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
26+
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
27+
const char *ExtraCode, raw_ostream &O) override;
28+
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
29+
const char *ExtraCode, raw_ostream &O) override;
30+
31+
void emitInstruction(const MachineInstr *MI) override;
32+
MCSymbol *getJTPublicSymbol(unsigned JTI);
33+
virtual void emitJumpTableInfo() override;
34+
35+
static char ID;
36+
37+
private:
38+
BTFDebug *BTF;
39+
};
40+
41+
} // namespace llvm
42+
43+
#endif /* LLVM_LIB_TARGET_BPF_BPFASMPRINTER_H */

llvm/lib/Target/BPF/BPFMCInstLower.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@
1212
//===----------------------------------------------------------------------===//
1313

1414
#include "BPFMCInstLower.h"
15+
#include "BPFAsmPrinter.h"
16+
#include "BPFISelLowering.h"
1517
#include "llvm/CodeGen/AsmPrinter.h"
1618
#include "llvm/CodeGen/MachineBasicBlock.h"
1719
#include "llvm/CodeGen/MachineInstr.h"
1820
#include "llvm/MC/MCAsmInfo.h"
1921
#include "llvm/MC/MCContext.h"
2022
#include "llvm/MC/MCExpr.h"
2123
#include "llvm/MC/MCInst.h"
24+
#include "llvm/MC/MCStreamer.h"
2225
#include "llvm/Support/ErrorHandling.h"
2326
#include "llvm/Support/raw_ostream.h"
2427
using namespace llvm;
@@ -78,7 +81,7 @@ void BPFMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
7881
MCOp = LowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex()));
7982
break;
8083
case MachineOperand::MO_JumpTableIndex:
81-
MCOp = LowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex()));
84+
MCOp = LowerSymbolOperand(MO, Printer.getJTPublicSymbol(MO.getIndex()));
8285
break;
8386
case MachineOperand::MO_BlockAddress:
8487
MCOp = LowerSymbolOperand(

llvm/lib/Target/BPF/BPFMCInstLower.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#include "llvm/Support/Compiler.h"
1313

1414
namespace llvm {
15-
class AsmPrinter;
15+
class BPFAsmPrinter;
1616
class MCContext;
1717
class MCInst;
1818
class MCOperand;
@@ -24,10 +24,10 @@ class MachineOperand;
2424
class LLVM_LIBRARY_VISIBILITY BPFMCInstLower {
2525
MCContext &Ctx;
2626

27-
AsmPrinter &Printer;
27+
BPFAsmPrinter &Printer;
2828

2929
public:
30-
BPFMCInstLower(MCContext &ctx, AsmPrinter &printer)
30+
BPFMCInstLower(MCContext &ctx, BPFAsmPrinter &printer)
3131
: Ctx(ctx), Printer(printer) {}
3232
void Lower(const MachineInstr *MI, MCInst &OutMI) const;
3333

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//===------------------ BPFTargetLoweringObjectFile.cpp -------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "BPFTargetLoweringObjectFile.h"
10+
#include "llvm/MC/MCContext.h"
11+
#include "llvm/MC/MCSectionELF.h"
12+
13+
using namespace llvm;
14+
15+
MCSection *BPFTargetLoweringObjectFileELF::getSectionForJumpTable(
16+
const Function &F, const TargetMachine &TM,
17+
const MachineJumpTableEntry *JTE) const {
18+
return getContext().getELFSection(".jumptables", ELF::SHT_PROGBITS, 0);
19+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//===============- BPFTargetLoweringObjectFile.h -*- C++ -*-================//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIB_TARGET_BPF_BPFTARGETLOWERINGOBJECTFILE
10+
#define LLVM_LIB_TARGET_BPF_BPFTARGETLOWERINGOBJECTFILE
11+
12+
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
13+
#include "llvm/Target/TargetLoweringObjectFile.h"
14+
15+
namespace llvm {
16+
class BPFTargetLoweringObjectFileELF : public TargetLoweringObjectFileELF {
17+
18+
public:
19+
virtual MCSection *
20+
getSectionForJumpTable(const Function &F, const TargetMachine &TM,
21+
const MachineJumpTableEntry *JTE) const override;
22+
};
23+
} // namespace llvm
24+
25+
#endif // LLVM_LIB_TARGET_BPF_BPFTARGETLOWERINGOBJECTFILE

llvm/lib/Target/BPF/BPFTargetMachine.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "BPFTargetMachine.h"
1414
#include "BPF.h"
15+
#include "BPFTargetLoweringObjectFile.h"
1516
#include "BPFTargetTransformInfo.h"
1617
#include "MCTargetDesc/BPFMCAsmInfo.h"
1718
#include "TargetInfo/BPFTargetInfo.h"
@@ -80,7 +81,7 @@ BPFTargetMachine::BPFTargetMachine(const Target &T, const Triple &TT,
8081
: CodeGenTargetMachineImpl(T, computeDataLayout(TT), TT, CPU, FS, Options,
8182
getEffectiveRelocModel(RM),
8283
getEffectiveCodeModel(CM, CodeModel::Small), OL),
83-
TLOF(std::make_unique<TargetLoweringObjectFileELF>()),
84+
TLOF(std::make_unique<BPFTargetLoweringObjectFileELF>()),
8485
Subtarget(TT, std::string(CPU), std::string(FS), *this) {
8586
if (!DisableCheckUnreachable) {
8687
this->Options.TrapUnreachable = true;

llvm/lib/Target/BPF/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ add_llvm_target(BPFCodeGen
3737
BPFRegisterInfo.cpp
3838
BPFSelectionDAGInfo.cpp
3939
BPFSubtarget.cpp
40+
BPFTargetLoweringObjectFile.cpp
4041
BPFTargetMachine.cpp
4142
BPFMIPeephole.cpp
4243
BPFMIChecking.cpp

0 commit comments

Comments
 (0)