Skip to content

Commit fceb1b5

Browse files
author
Yonghong Song
committed
Preserve compilation time failure for __builtin_trap()
Without this patch, the code having __builtin_trap() will survive compilation and the error will be reported in kernel bpf verification. $ cat test_trap.c int buz(int p) { __builtin_trap(); return 0; } $ clang --target=bpf -O2 -g -c test_trap.c $ One way to resolve the issue is to utilize the clang option '-ftrap-function=[name]' ([1]) to trigger compile time failure. For example, $ cat test_trap.c int buz(int p) { __builtin_trap(); return 0; } $ clang --target=bpf -O2 -ftrap-function=__undefined_trap -g -c test_trap.c test_trap.c:1:18: error: A call to built-in function '__undefined_trap' is not supported. 1 | int buz(int p) { __builtin_trap(); return 0; } | ^ 1 error generated. $ Basically, a user provided option can enable compilation failure. But compiler can automate this. If user does not have '-ftrap-funciton=[name]' option, compiler can provide a default unimplemented trap function and that will trigger the compilation failure. So with this patch, for the same above source code, we have $ clang --target=bpf -O2 -g -c test_trap.c test_trap.c:1:18: error: A call to built-in function '__bpf_unimpl_trap_func' is not supported. 1 | int buz(int p) { __builtin_trap(); return 0; } | ^ 1 error generated. $ [1] https://clang.llvm.org/docs/UsersManual.html
1 parent 7318685 commit fceb1b5

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

llvm/lib/Target/BPF/BPFCheckAndAdjustIR.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "llvm/IR/IRBuilder.h"
2727
#include "llvm/IR/Instruction.h"
2828
#include "llvm/IR/Instructions.h"
29+
#include "llvm/IR/IntrinsicInst.h"
2930
#include "llvm/IR/IntrinsicsBPF.h"
3031
#include "llvm/IR/Module.h"
3132
#include "llvm/IR/Type.h"
@@ -55,6 +56,7 @@ class BPFCheckAndAdjustIR final : public ModulePass {
5556
bool sinkMinMax(Module &M);
5657
bool removeGEPBuiltins(Module &M);
5758
bool insertASpaceCasts(Module &M);
59+
bool adjustTrapFunc(Module &M);
5860
};
5961
} // End anonymous namespace
6062

@@ -527,12 +529,43 @@ bool BPFCheckAndAdjustIR::insertASpaceCasts(Module &M) {
527529
return Changed;
528530
}
529531

532+
static const char *BPF_UNIMPL_TRAP_FUNC = "__bpf_unimpl_trap_func";
533+
534+
bool BPFCheckAndAdjustIR::adjustTrapFunc(Module &M) {
535+
bool Changed = false;
536+
for (Function &F : M) {
537+
for (BasicBlock &BB : F) {
538+
for (Instruction &I : BB) {
539+
auto *II = dyn_cast<IntrinsicInst>(&I);
540+
if (!II)
541+
continue;
542+
if (II->getIntrinsicID() != Intrinsic::trap)
543+
continue;
544+
AttributeList Attrs = II->getAttributes();
545+
StringRef TrapFuncName =
546+
Attrs.getFnAttr("trap-func-name").getValueAsString();
547+
if (TrapFuncName.empty()) {
548+
AttributeList NewAttrs =
549+
Attrs.removeFnAttribute(F.getContext(), "trap-func-name");
550+
NewAttrs = NewAttrs.addFnAttribute(F.getContext(), "trap-func-name",
551+
BPF_UNIMPL_TRAP_FUNC);
552+
II->setAttributes(NewAttrs);
553+
Changed = true;
554+
}
555+
}
556+
}
557+
}
558+
559+
return Changed;
560+
}
561+
530562
bool BPFCheckAndAdjustIR::adjustIR(Module &M) {
531563
bool Changed = removePassThroughBuiltin(M);
532564
Changed = removeCompareBuiltin(M) || Changed;
533565
Changed = sinkMinMax(M) || Changed;
534566
Changed = removeGEPBuiltins(M) || Changed;
535567
Changed = insertASpaceCasts(M) || Changed;
568+
Changed = adjustTrapFunc(M) || Changed;
536569
return Changed;
537570
}
538571

0 commit comments

Comments
 (0)