|
21 | 21 | #include "llvm/CodeGen/MachineRegisterInfo.h"
|
22 | 22 | #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
|
23 | 23 | #include "llvm/CodeGen/ValueTypes.h"
|
| 24 | +#include "llvm/IR/DIBuilder.h" |
24 | 25 | #include "llvm/IR/DiagnosticInfo.h"
|
25 | 26 | #include "llvm/IR/DiagnosticPrinter.h"
|
| 27 | +#include "llvm/IR/Module.h" |
26 | 28 | #include "llvm/Support/Debug.h"
|
27 | 29 | #include "llvm/Support/ErrorHandling.h"
|
28 | 30 | #include "llvm/Support/MathExtras.h"
|
@@ -68,6 +70,8 @@ BPFTargetLowering::BPFTargetLowering(const TargetMachine &TM,
|
68 | 70 | setOperationAction(ISD::BRIND, MVT::Other, Expand);
|
69 | 71 | setOperationAction(ISD::BRCOND, MVT::Other, Expand);
|
70 | 72 |
|
| 73 | + setOperationAction(ISD::TRAP, MVT::Other, Custom); |
| 74 | + |
71 | 75 | setOperationAction({ISD::GlobalAddress, ISD::ConstantPool}, MVT::i64, Custom);
|
72 | 76 |
|
73 | 77 | setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Custom);
|
@@ -326,6 +330,8 @@ SDValue BPFTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
|
326 | 330 | case ISD::ATOMIC_LOAD:
|
327 | 331 | case ISD::ATOMIC_STORE:
|
328 | 332 | return LowerATOMIC_LOAD_STORE(Op, DAG);
|
| 333 | + case ISD::TRAP: |
| 334 | + return LowerTRAP(Op, DAG); |
329 | 335 | }
|
330 | 336 | }
|
331 | 337 |
|
@@ -521,10 +527,12 @@ SDValue BPFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
521 | 527 | Callee = DAG.getTargetGlobalAddress(G->getGlobal(), CLI.DL, PtrVT,
|
522 | 528 | G->getOffset(), 0);
|
523 | 529 | } else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
|
524 |
| - Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, 0); |
525 |
| - fail(CLI.DL, DAG, |
526 |
| - Twine("A call to built-in function '" + StringRef(E->getSymbol()) + |
527 |
| - "' is not supported.")); |
| 530 | + if (StringRef(E->getSymbol()) != BPF_TRAP) { |
| 531 | + Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, 0); |
| 532 | + fail(CLI.DL, DAG, |
| 533 | + Twine("A call to built-in function '" + StringRef(E->getSymbol()) + |
| 534 | + "' is not supported.")); |
| 535 | + } |
528 | 536 | }
|
529 | 537 |
|
530 | 538 | // Returns a chain & a flag for retval copy to use.
|
@@ -726,6 +734,52 @@ SDValue BPFTargetLowering::LowerATOMIC_LOAD_STORE(SDValue Op,
|
726 | 734 | return Op;
|
727 | 735 | }
|
728 | 736 |
|
| 737 | +static Function *createBPFUnreachable(Module *M) { |
| 738 | + if (auto *Fn = M->getFunction(BPF_TRAP)) |
| 739 | + return Fn; |
| 740 | + |
| 741 | + FunctionType *FT = FunctionType::get(Type::getVoidTy(M->getContext()), false); |
| 742 | + Function *NewF = |
| 743 | + Function::Create(FT, GlobalValue::ExternalWeakLinkage, BPF_TRAP, M); |
| 744 | + NewF->setDSOLocal(true); |
| 745 | + NewF->setCallingConv(CallingConv::C); |
| 746 | + NewF->setSection(".ksyms"); |
| 747 | + |
| 748 | + if (M->debug_compile_units().empty()) |
| 749 | + return NewF; |
| 750 | + |
| 751 | + DIBuilder DBuilder(*M); |
| 752 | + DITypeRefArray ParamTypes = |
| 753 | + DBuilder.getOrCreateTypeArray({nullptr /*void return*/}); |
| 754 | + DISubroutineType *FuncType = DBuilder.createSubroutineType(ParamTypes); |
| 755 | + DICompileUnit *CU = *M->debug_compile_units_begin(); |
| 756 | + DISubprogram *SP = |
| 757 | + DBuilder.createFunction(CU, BPF_TRAP, BPF_TRAP, nullptr, 0, FuncType, 0, |
| 758 | + DINode::FlagZero, DISubprogram::SPFlagZero); |
| 759 | + NewF->setSubprogram(SP); |
| 760 | + return NewF; |
| 761 | +} |
| 762 | + |
| 763 | +SDValue BPFTargetLowering::LowerTRAP(SDValue Op, SelectionDAG &DAG) const { |
| 764 | + MachineFunction &MF = DAG.getMachineFunction(); |
| 765 | + TargetLowering::CallLoweringInfo CLI(DAG); |
| 766 | + SmallVector<SDValue> InVals; |
| 767 | + SDNode *N = Op.getNode(); |
| 768 | + SDLoc DL(N); |
| 769 | + |
| 770 | + Function *Fn = createBPFUnreachable(MF.getFunction().getParent()); |
| 771 | + auto PtrVT = getPointerTy(MF.getDataLayout()); |
| 772 | + CLI.Callee = DAG.getTargetGlobalAddress(Fn, DL, PtrVT); |
| 773 | + CLI.Chain = N->getOperand(0); |
| 774 | + CLI.IsTailCall = false; |
| 775 | + CLI.CallConv = CallingConv::C; |
| 776 | + CLI.IsVarArg = false; |
| 777 | + CLI.DL = DL; |
| 778 | + CLI.NoMerge = false; |
| 779 | + CLI.DoesNotReturn = true; |
| 780 | + return LowerCall(CLI, InVals); |
| 781 | +} |
| 782 | + |
729 | 783 | const char *BPFTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
730 | 784 | switch ((BPFISD::NodeType)Opcode) {
|
731 | 785 | case BPFISD::FIRST_NUMBER:
|
|
0 commit comments