11
11
//
12
12
// ===----------------------------------------------------------------------===//
13
13
14
+ #include " BPFAsmPrinter.h"
14
15
#include " BPF.h"
15
16
#include " BPFInstrInfo.h"
16
17
#include " BPFMCInstLower.h"
17
18
#include " BTFDebug.h"
18
19
#include " MCTargetDesc/BPFInstPrinter.h"
19
20
#include " TargetInfo/BPFTargetInfo.h"
21
+ #include " llvm/BinaryFormat/ELF.h"
20
22
#include " llvm/CodeGen/AsmPrinter.h"
21
23
#include " llvm/CodeGen/MachineConstantPool.h"
22
24
#include " llvm/CodeGen/MachineInstr.h"
25
+ #include " llvm/CodeGen/MachineJumpTableInfo.h"
23
26
#include " llvm/CodeGen/MachineModuleInfo.h"
27
+ #include " llvm/CodeGen/TargetLowering.h"
24
28
#include " llvm/IR/Module.h"
25
29
#include " llvm/MC/MCAsmInfo.h"
30
+ #include " llvm/MC/MCExpr.h"
26
31
#include " llvm/MC/MCInst.h"
27
32
#include " llvm/MC/MCStreamer.h"
28
33
#include " llvm/MC/MCSymbol.h"
34
+ #include " llvm/MC/MCSymbolELF.h"
29
35
#include " llvm/MC/TargetRegistry.h"
30
36
#include " llvm/Support/Compiler.h"
31
37
#include " llvm/Support/raw_ostream.h"
38
+ #include " llvm/Target/TargetLoweringObjectFile.h"
32
39
using namespace llvm ;
33
40
34
41
#define DEBUG_TYPE " asm-printer"
35
42
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
-
60
43
bool BPFAsmPrinter::doInitialization (Module &M) {
61
44
AsmPrinter::doInitialization (M);
62
45
@@ -69,6 +52,45 @@ bool BPFAsmPrinter::doInitialization(Module &M) {
69
52
return false ;
70
53
}
71
54
55
+ const BPFTargetMachine &BPFAsmPrinter::getBTM () const {
56
+ return static_cast <const BPFTargetMachine &>(TM);
57
+ }
58
+
59
+ bool BPFAsmPrinter::doFinalization (Module &M) {
60
+ // Remove unused globals which are previously used for jump table.
61
+ const BPFSubtarget *Subtarget = getBTM ().getSubtargetImpl ();
62
+ if (Subtarget->hasGotox ()) {
63
+ std::vector<GlobalVariable *> Targets;
64
+ for (GlobalVariable &Global : M.globals ()) {
65
+ if (Global.getLinkage () != GlobalValue::PrivateLinkage)
66
+ continue ;
67
+ if (!Global.isConstant () || !Global.hasInitializer ())
68
+ continue ;
69
+
70
+ Constant *CV = dyn_cast<Constant>(Global.getInitializer ());
71
+ if (!CV)
72
+ continue ;
73
+ ConstantArray *CA = dyn_cast<ConstantArray>(CV);
74
+ if (!CA)
75
+ continue ;
76
+
77
+ for (unsigned i = 1 , e = CA->getNumOperands (); i != e; ++i) {
78
+ if (!dyn_cast<BlockAddress>(CA->getOperand (i)))
79
+ continue ;
80
+ }
81
+ Targets.push_back (&Global);
82
+ }
83
+
84
+ for (GlobalVariable *GV : Targets) {
85
+ GV->replaceAllUsesWith (PoisonValue::get (GV->getType ()));
86
+ GV->dropAllReferences ();
87
+ GV->eraseFromParent ();
88
+ }
89
+ }
90
+
91
+ return AsmPrinter::doFinalization (M);
92
+ }
93
+
72
94
void BPFAsmPrinter::printOperand (const MachineInstr *MI, int OpNum,
73
95
raw_ostream &O) {
74
96
const MachineOperand &MO = MI->getOperand (OpNum);
@@ -150,6 +172,50 @@ void BPFAsmPrinter::emitInstruction(const MachineInstr *MI) {
150
172
EmitToStreamer (*OutStreamer, TmpInst);
151
173
}
152
174
175
+ MCSymbol *BPFAsmPrinter::getJTPublicSymbol (unsigned JTI) {
176
+ SmallString<60 > Name;
177
+ raw_svector_ostream (Name)
178
+ << " BPF.JT." << MF->getFunctionNumber () << ' .' << JTI;
179
+ MCSymbol *S = OutContext.getOrCreateSymbol (Name);
180
+ if (auto *ES = static_cast <MCSymbolELF *>(S)) {
181
+ ES->setBinding (ELF::STB_GLOBAL);
182
+ ES->setType (ELF::STT_OBJECT);
183
+ }
184
+ return S;
185
+ }
186
+
187
+ void BPFAsmPrinter::emitJumpTableInfo () {
188
+ const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo ();
189
+ if (!MJTI)
190
+ return ;
191
+
192
+ const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables ();
193
+ if (JT.empty ())
194
+ return ;
195
+
196
+ const TargetLoweringObjectFile &TLOF = getObjFileLowering ();
197
+ const Function &F = MF->getFunction ();
198
+ MCSection *JTS = TLOF.getSectionForJumpTable (F, TM);
199
+ assert (MJTI->getEntryKind () == MachineJumpTableInfo::EK_BlockAddress);
200
+ unsigned EntrySize = MJTI->getEntrySize (getDataLayout ());
201
+ OutStreamer->switchSection (JTS);
202
+ for (unsigned JTI = 0 ; JTI < JT.size (); JTI++) {
203
+ ArrayRef<MachineBasicBlock *> JTBBs = JT[JTI].MBBs ;
204
+ if (JTBBs.empty ())
205
+ continue ;
206
+
207
+ MCSymbol *JTStart = getJTPublicSymbol (JTI);
208
+ OutStreamer->emitLabel (JTStart);
209
+ for (const MachineBasicBlock *MBB : JTBBs) {
210
+ const MCExpr *LHS = MCSymbolRefExpr::create (MBB->getSymbol (), OutContext);
211
+ OutStreamer->emitValue (LHS, EntrySize);
212
+ }
213
+ const MCExpr *JTSize =
214
+ MCConstantExpr::create (JTBBs.size () * EntrySize, OutContext);
215
+ OutStreamer->emitELFSize (JTStart, JTSize);
216
+ }
217
+ }
218
+
153
219
char BPFAsmPrinter::ID = 0 ;
154
220
155
221
INITIALIZE_PASS (BPFAsmPrinter, " bpf-asm-printer" , " BPF Assembly Printer" , false ,
0 commit comments