1+ // #include "X86.h"
2+ // #include "llvm/CodeGen/MachineFunctionPass.h"
3+ // #include "llvm/CodeGen/MachineInstr.h"
4+ // #include "llvm/CodeGen/MachineRegisterInfo.h"
5+ // #include "llvm/Support/Debug.h"
6+ // #include "llvm/Support/raw_ostream.h"
7+ // #include "X86MatchJumptablePass.h"
8+ // #include "llvm/CodeGen/MachineJumpTableInfo.h"
9+
10+ // #define DEBUG_TYPE "match-jump-table"
11+
12+ // using namespace llvm;
13+
14+ // namespace {
15+ // class X86MatchJumptablePass : public MachineFunctionPass {
16+ // public:
17+ // static char ID;
18+
19+ // X86MatchJumptablePass() : MachineFunctionPass(ID) {}
20+
21+ // bool runOnMachineFunction(MachineFunction &MF) override {
22+ // LLVM_DEBUG(dbgs() << "Analyzing jump tables in function: " << MF.getName() << "\n");
23+
24+ // // Get jump table information
25+ // MachineJumpTableInfo *JumpTableInfo = MF.getJumpTableInfo();
26+ // if (!JumpTableInfo) {
27+ // LLVM_DEBUG(dbgs() << "No jump tables in this function.\n");
28+ // return false;
29+ // }
30+ // // Assuming JumpTableInfo is available
31+ // for (unsigned JTIndex = 0; JTIndex < JumpTableInfo->getJumpTables().size(); ++JTIndex) {
32+ // const MachineJumpTableEntry &JTEntry = JumpTableInfo->getJumpTables()[JTIndex];
33+
34+ // LLVM_DEBUG(dbgs() << "Jump Table #" << JTIndex << " Base Address: " << JTEntry.BaseAddress << "\n");
35+
36+ // // Iterate through the entries (target basic blocks) in this jump table
37+ // for (auto *MBB : JTEntry.MBBs) {
38+ // LLVM_DEBUG(dbgs() << " Target BasicBlock: " << MBB->getName() << " Address: " << MBB->getAddress() << "\n");
39+ // }
40+
41+
42+ // // Trace potential indirect jumps related to this jump table
43+ // traceIndirectJumps(MF, JTIndex, JumpTableInfo);
44+ // }
45+ // return false;
46+
47+ // }
48+
49+ // void traceIndirectJumps(MachineFunction &MF, unsigned JTIndex, MachineJumpTableInfo *JumpTableInfo) {
50+ // const MachineJumpTableEntry &JTEntry = JumpTableInfo->getJumpTables()[JTIndex];
51+
52+ // for (auto &MBB : MF) {
53+ // for (auto &MI : MBB) {
54+ // if (MI.isIndirectBranch()) {
55+ // LLVM_DEBUG(dbgs() << "Found indirect jump: " << MI << "\n");
56+
57+ // // Analyze data flow to check if this jump is related to the jump table
58+ // if (isJumpTableRelated(MI, JTEntry, MF)) {
59+ // LLVM_DEBUG(dbgs() << "This indirect jump is related to Jump Table #" << JTIndex << "\n");
60+ // }
61+ // }
62+ // }
63+ // }
64+ // }
65+
66+ // bool isJumpTableRelated(MachineInstr &MI, const MachineJumpTableEntry &JTEntry, MachineFunction &MF) {
67+ // for (unsigned OpIdx = 0; OpIdx < MI.getNumOperands(); ++OpIdx) {
68+ // const MachineOperand &Op = MI.getOperand(OpIdx);
69+
70+ // if (Op.isReg()) {
71+ // Register Reg = Op.getReg();
72+ // MachineRegisterInfo &MRI = MF.getRegInfo();
73+ // // Check if any of the definitions of the register are related to a jump table load
74+ // for (MachineInstr &DefMI : MRI.def_instructions(Reg)) {
75+ // if (isJumpTableLoad(DefMI, JTEntry)) {
76+ // return true;
77+ // }
78+ // }
79+ // } else if (Op.isImm()) {
80+ // // Check if the immediate operand might be an offset/index into the jump table
81+ // int64_t ImmValue = Op.getImm();
82+
83+ // // For example, if the jump table has 10 entries, check if the immediate is between 0 and 9
84+ // if (ImmValue >= 0 && ImmValue < JTEntry.MBBs.size()) {
85+ // // This immediate value could be an index into the jump table
86+ // LLVM_DEBUG(dbgs() << "Immediate operand is a possible jump table index: " << ImmValue << "\n");
87+ // return true;
88+ // }
89+ // }
90+ // }
91+ // return false;
92+ // }
93+
94+ // bool isJumpTableLoad(MachineInstr &MI, const MachineJumpTableEntry &JTEntry) {
95+ // if (MI.mayLoad()) {
96+ // for (unsigned i = 0; i < MI.getNumOperands(); ++i) {
97+ // const MachineOperand &Op = MI.getOperand(i);
98+ // if (Op.isGlobal() && Op.getGlobal() == JTEntry.BaseAddress) {
99+ // return true;
100+ // }
101+ // }
102+ // }
103+ // return false;
104+ // }
105+
106+ // StringRef getPassName() const override {
107+ // return "Match Jump Table Pass";
108+ // }
109+
110+ // // StringRef getPassName() const override {
111+ // // return "X86 My Backend Pass";
112+ // // }
113+ // };
114+ // }
115+
116+ // char X86MatchJumptablePass::ID = 0;
117+
118+ // // Ensure the function is in the llvm namespace
119+ // namespace llvm {
120+
121+ // // Define the pass
122+ // FunctionPass *createX86MatchJumptablePass() {
123+ // return new X86MatchJumptablePass();
124+ // }
125+
126+ // } // end llvm namespace
127+
128+ // static RegisterPass<X86MatchJumptablePass> X("match-jump-table", "Match Jump Table Pass", false, false);
129+
130+
1131#include " X86.h"
2132#include " llvm/CodeGen/MachineFunctionPass.h"
3133#include " llvm/CodeGen/MachineInstr.h"
4134#include " llvm/CodeGen/MachineRegisterInfo.h"
5135#include " llvm/Support/Debug.h"
6136#include " llvm/Support/raw_ostream.h"
7- #include " X86MatchJumptablePass .h"
137+ #include " llvm/CodeGen/MachineJumpTableInfo .h"
8138
9139#define DEBUG_TYPE " match-jump-table"
10140
11141using namespace llvm ;
12142
13143namespace {
14- class X86MatchJumptablePass : public MachineFunctionPass {
15- public:
16- static char ID;
144+ class X86MatchJumptablePass : public MachineFunctionPass {
145+ public:
146+ static char ID;
17147
18- X86MatchJumptablePass () : MachineFunctionPass(ID) {}
148+ X86MatchJumptablePass () : MachineFunctionPass(ID) {}
19149
20- bool runOnMachineFunction (MachineFunction &MF) override {
150+ bool runOnMachineFunction (MachineFunction &MF) override {
21151 LLVM_DEBUG (dbgs () << " Analyzing jump tables in function: " << MF.getName () << " \n " );
22152
23153 // Get jump table information
@@ -26,104 +156,135 @@ namespace {
26156 LLVM_DEBUG (dbgs () << " No jump tables in this function.\n " );
27157 return false ;
28158 }
29- // Assuming JumpTableInfo is available
159+
30160 for (unsigned JTIndex = 0 ; JTIndex < JumpTableInfo->getJumpTables ().size (); ++JTIndex) {
31- const MachineJumpTableEntry &JTEntry = JumpTableInfo->getJumpTables ()[JTIndex];
32-
33- LLVM_DEBUG (dbgs () << " Jump Table #" << JTIndex << " Base Address: " << JTEntry.BaseAddress << " \n " );
161+ const MachineJumpTableEntry &JTEntry = JumpTableInfo->getJumpTables ()[JTIndex];
34162
35- // Iterate through the entries (target basic blocks) in this jump table
36- for (auto *MBB : JTEntry.MBBs ) {
37- LLVM_DEBUG (dbgs () << " Target BasicBlock: " << MBB->getName () << " Address: " << MBB->getAddress () << " \n " );
38- }
39-
163+ LLVM_DEBUG (dbgs () << " Jump Table #" << JTIndex << " contains " << JTEntry.MBBs .size ()
164+ << " entries.\n " );
165+
166+ // Iterate through the entries (target basic blocks) in this jump table
167+ for (auto *MBB : JTEntry.MBBs ) {
168+ if (MBB) {
169+ LLVM_DEBUG (dbgs () << " Target BasicBlock: " << MBB->getName () << " \n " );
170+ }
171+ }
40172
41- // Trace potential indirect jumps related to this jump table
42- traceIndirectJumps (MF, JTIndex, JumpTableInfo);
173+ // Assuming you have access to MF, JTIndex, and JumpTableInfo
174+ MachineInstr* indirectJumpInstr = traceIndirectJumps (MF, JTIndex, JumpTableInfo);
175+
176+ if (indirectJumpInstr) {
177+ // Handle the found indirect jump instruction
178+ dbgs () << " Indirect jump found at address: " << indirectJumpInstr << " \n " ;
179+ for (auto &MBB : JTEntry.MBBs ) {
180+ LLVM_DEBUG (dbgs () << " Address of MBB: " << &MBB << " \n " ); // Print the address of the MBB
181+ // Optionally print the name and instructions inside the MBB
182+ // LLVM_DEBUG(dbgs() << "MBB: " << MBB.getName() << "\n");
183+ // for (auto &MI : MBB) {
184+ // LLVM_DEBUG(dbgs() << " Instruction: " << MI << "\n");
185+ // }
186+ }
187+ }
43188 }
189+
44190 return false ;
191+ }
45192
46- }
193+ // void traceIndirectJumps(MachineFunction &MF, unsigned JTIndex, MachineJumpTableInfo *JumpTableInfo) {
194+ // const MachineJumpTableEntry &JTEntry = JumpTableInfo->getJumpTables()[JTIndex];
195+
196+ // for (auto &MBB : MF) {
197+ // for (auto &MI : MBB) {
198+ // if (MI.isIndirectBranch()) {
199+ // LLVM_DEBUG(dbgs() << "Found indirect jump: " << MI << "\n");
47200
48- void traceIndirectJumps (MachineFunction &MF, unsigned JTIndex, MachineJumpTableInfo *JumpTableInfo) {
201+ // // Analyze data flow to check if this jump is related to the jump table
202+ // if (isJumpTableRelated(MI, JTEntry, MF)) {
203+ // LLVM_DEBUG(dbgs() << "This indirect jump is related to Jump Table #" << JTIndex << "\n");
204+ // }
205+ // }
206+ // }
207+ // }
208+ // }
209+ MachineInstr* traceIndirectJumps (MachineFunction &MF, unsigned JTIndex, MachineJumpTableInfo *JumpTableInfo) {
49210 const MachineJumpTableEntry &JTEntry = JumpTableInfo->getJumpTables ()[JTIndex];
50211
51212 for (auto &MBB : MF) {
52- for (auto &MI : MBB) {
53- if (MI.isIndirectBranch ()) {
54- LLVM_DEBUG (dbgs () << " Found indirect jump: " << MI << " \n " );
213+ for (auto &MI : MBB) {
214+ if (MI.isIndirectBranch ()) {
215+ LLVM_DEBUG (dbgs () << " Found indirect jump: " << MI << " \n " );
55216
56- // Analyze data flow to check if this jump is related to the jump table
57- if (isJumpTableRelated (MI, JTEntry, MF)) {
58- LLVM_DEBUG (dbgs () << " This indirect jump is related to Jump Table #" << JTIndex << " \n " );
59- }
217+ // Analyze data flow to check if this jump is related to the jump table
218+ if (isJumpTableRelated (MI, JTEntry, MF)) {
219+ LLVM_DEBUG (dbgs () << " This indirect jump is related to Jump Table #" << JTIndex << " \n " );
220+
221+ // Return the address of the indirect jump (MI)
222+ return &MI;
223+ }
224+ }
60225 }
61- }
62226 }
63- }
227+
228+ // Return nullptr if no indirect jump is found
229+ return nullptr ;
230+ }
64231
65232 bool isJumpTableRelated (MachineInstr &MI, const MachineJumpTableEntry &JTEntry, MachineFunction &MF) {
66- for (unsigned OpIdx = 0 ; OpIdx < MI.getNumOperands (); ++OpIdx) {
67- const MachineOperand &Op = MI.getOperand (OpIdx);
68-
69- if (Op.isReg ()) {
70- Register Reg = Op.getReg ();
71- MachineRegisterInfo &MRI = MF.getRegInfo ();
72- // Check if any of the definitions of the register are related to a jump table load
73- for (MachineInstr &DefMI : MRI.def_instructions (Reg)) {
74- if (isJumpTableLoad (DefMI, JTEntry)) {
233+ for (unsigned OpIdx = 0 ; OpIdx < MI.getNumOperands (); ++OpIdx) {
234+ const MachineOperand &Op = MI.getOperand (OpIdx);
235+
236+ if (Op.isReg ()) {
237+ Register Reg = Op.getReg ();
238+ MachineRegisterInfo &MRI = MF.getRegInfo ();
239+ // Check if any of the definitions of the register are related to a jump table load
240+ for (MachineInstr &DefMI : MRI.def_instructions (Reg)) {
241+ if (isJumpTableLoad (DefMI, JTEntry)) {
242+ return true ;
243+ }
244+ }
245+ } else if (Op.isImm ()) {
246+ // Check if the immediate operand might be an offset/index into the jump table
247+ int64_t ImmValue = Op.getImm ();
248+ if (ImmValue >= 0 && ImmValue < JTEntry.MBBs .size ()) {
249+ // This immediate value could be an index into the jump table
250+ LLVM_DEBUG (dbgs () << " Immediate operand is a possible jump table index: " << ImmValue
251+ << " \n " );
75252 return true ;
76253 }
77254 }
78- } else if (Op.isImm ()) {
79- // Check if the immediate operand might be an offset/index into the jump table
80- int64_t ImmValue = Op.getImm ();
81-
82- // For example, if the jump table has 10 entries, check if the immediate is between 0 and 9
83- if (ImmValue >= 0 && ImmValue < JTEntry.MBBs .size ()) {
84- // This immediate value could be an index into the jump table
85- LLVM_DEBUG (dbgs () << " Immediate operand is a possible jump table index: " << ImmValue << " \n " );
86- return true ;
87- }
88255 }
256+ return false ;
89257 }
90- return false ;
91- }
92258
93- bool isJumpTableLoad (MachineInstr &MI, const MachineJumpTableEntry &JTEntry) {
259+ bool isJumpTableLoad (MachineInstr &MI, const MachineJumpTableEntry &JTEntry) {
94260 if (MI.mayLoad ()) {
95- for (unsigned i = 0 ; i < MI.getNumOperands (); ++i) {
96- const MachineOperand &Op = MI.getOperand (i);
97- if (Op.isGlobal () && Op.getGlobal () == JTEntry.BaseAddress ) {
98- return true ;
99- }
261+ for (unsigned i = 0 ; i < MI.getNumOperands (); ++i) {
262+ const MachineOperand &Op = MI.getOperand (i);
263+ if (Op.getType () == MachineOperand::MO_JumpTableIndex) {
264+ unsigned JTIndex = Op.getIndex ();
265+ if (JTIndex < JTEntry.MBBs .size ()) {
266+ LLVM_DEBUG (dbgs () << " Instruction loads from Jump Table index: " << JTIndex << " \n " );
267+ return true ;
268+ }
100269 }
270+ }
101271 }
102272 return false ;
103- }
104-
105- StringRef getPassName () const override {
106- return " Match Jump Table Pass" ;
107273 }
108274
109- // StringRef getPassName() const override {
110- // return "X86 My Backend Pass";
111- // }
112- };
113- }
275+ StringRef getPassName () const override { return " Match Jump Table Pass" ; }
276+ };
277+
278+ } // namespace
114279
115280char X86MatchJumptablePass::ID = 0 ;
116281
117- // Ensure the function is in the llvm namespace
118282namespace llvm {
119-
120- // Define the pass
121- FunctionPass *createX86MatchJumptablePass () {
122- return new X86MatchJumptablePass ();
123- }
124-
125- } // end llvm namespace
126283
127- static RegisterPass<X86MatchJumptablePass> X (" match-jump-table" , " Match Jump Table Pass" , false , false );
284+ // Define the pass
285+ FunctionPass *createX86MatchJumptablePass () { return new X86MatchJumptablePass (); }
128286
287+ } // namespace llvm
129288
289+ static RegisterPass<X86MatchJumptablePass> X (" match-jump-table" , " Match Jump Table Pass" , false ,
290+ false );
0 commit comments