51#define DEBUG_TYPE "bpf-func-table"
66 return !
F.isDeclaration() && !
F.hasSection();
72 const User *Usr = U.getUser();
78 return isCallbackUse(U, Seen);
82 if (!CB || CB->isCallee(&U))
84 const Value *Callee = CB->getCalledOperand()->stripPointerCasts();
91 const User *Usr = U.getUser();
116 C->handleOperandChange(&
F, Index);
131 GV->eraseFromParent();
133 GV->eraseFromParent();
140 if (!
F.hasLocalLinkage())
142 F,
"BPF func-table cannot take the address of a function that is "
144 Types[
F.getFunctionType()].Funcs.push_back(&
F);
149 if (CB && !CB->isInlineAsm() && !
isa<Constant>(CB->getCalledOperand()))
155 for (
auto &[FTy, R] : Types) {
156 R.First =
Table.size();
159 ConstantInt::get(I64,
Table.size()), Ptr));
166 if (Calls.
empty() && Types.empty())
173 const FuncRange &R = Types.lookup(CB->getFunctionType());
180 IRBuilder<>(CB).CreateIntrinsic(Intrinsic::trap, {});
185 CB->setCalledOperand(R.Funcs[0]);
194 Value *Idx =
B.CreatePtrToInt(CB->getCalledOperand(), I64);
195 Idx =
B.CreateSub(Idx, ConstantInt::get(I64, R.First));
196 Idx =
B.CreateBinaryIntrinsic(Intrinsic::umin, Idx,
197 ConstantInt::get(I64, Cnt - 1));
199 GV, ConstantInt::get(I64, R.First *
DL.getPointerSize()));
200 Value *Slot =
B.CreateInBoundsGEP(Ptr,
First, Idx);
201 CB->setCalledOperand(
B.CreateLoad(Ptr, Slot));
208struct BPFFuncTableLegacy :
public ModulePass {
210 BPFFuncTableLegacy() : ModulePass(ID) {}
211 StringRef getPassName()
const override {
return "BPF Function Table"; }
217char BPFFuncTableLegacy::ID = 0;
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
static bool isInText(const Function &F)
The address of a function in another section is the address of a program, e.g.
static bool runFuncTable(Module &M)
static bool isCallbackUse(const Use &U, SmallPtrSetImpl< const User * > &Seen)
A callback: bpf_loop(), bpf_timer_set_callback() and co.
static void replaceAddress(Function &F, Constant *Index)
static bool isAddressUse(const Use &U)
The use is the address of the function as a value.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
This file implements a map that provides insertion order iteration.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file implements a set that has insertion order iteration characteristics.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_SUPPRESS_DEPRECATED_DECLARATIONS_POP Constant * getInBoundsPtrAdd(Constant *Ptr, Constant *Offset)
Create a getelementptr inbounds i8, ptr, offset constant expression.
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
Diagnostic information for unsupported feature in backend.
@ InternalLinkage
Rename collisions when linking (static functions).
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
This is an important class for using LLVM in a threaded context.
This class implements a map that also provides access to all stored values in a deterministic order.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
A Module instance is used to store all the information related to an LLVM module.
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
iterator_range< use_iterator > uses()
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
ModulePass * createBPFFuncTablePass()
LLVM_ABI void appendToUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.used list.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
LLVM_ABI GlobalVariable * collectUsedGlobalVariables(const Module &M, SmallVectorImpl< GlobalValue * > &Vec, bool CompilerUsed)
Given "llvm.used" or "llvm.compiler.used" as a global name, collect the initializer elements of that ...