| 3089 | } |
| 3090 | |
| 3091 | bool UCSanVisitor::visitWrappedCallBase(Function *F, CallBase &CB) { |
| 3092 | IRBuilder<> IRB(&CB); |
| 3093 | Value *Shadow = nullptr; |
| 3094 | const DataLayout &DL = getDataLayout(); |
| 3095 | FunctionType *FT = F->getFunctionType(); |
| 3096 | switch (UF.UC.getWrapperKind(F)) { |
| 3097 | case UCSan::WK_None: |
| 3098 | // No wrapper needed, fall through to default behavior |
| 3099 | llvm_unreachable("WK_None should not be handled here"); |
| 3100 | return false; |
| 3101 | case UCSan::WK_ShimTarget: |
| 3102 | llvm_unreachable("WK_ShimTarget should not be in UnwrappedFnMap"); |
| 3103 | return false; |
| 3104 | case UCSan::WK_ShimOrig: |
| 3105 | { |
| 3106 | // Redirect call to __shim_ function, let normal TLS path handle shadows |
| 3107 | std::string ShimName = "__shim_" + F->getName().str(); |
| 3108 | FunctionCallee ShimF = UF.UC.Mod->getOrInsertFunction(ShimName, F->getFunctionType()); |
| 3109 | CB.setCalledFunction(ShimF); |
| 3110 | return false; // let caller handle arg/retval TLS |
| 3111 | } |
| 3112 | case UCSan::WK_AutoCustom: |
| 3113 | // invoke the custom function |
| 3114 | { |
| 3115 | // Only store shadows for fixed parameters, varargs are not tracked in TLS |
| 3116 | // FIXME: add vararg shadow tracking support |
| 3117 | unsigned NumFixedParams = FT->getNumParams(); |
| 3118 | unsigned ArgOffset = 0; |
| 3119 | |
| 3120 | for (unsigned I = 0; I < NumFixedParams; ++I) { |
| 3121 | unsigned Size = |
| 3122 | DL.getTypeAllocSize(UF.UC.getShadowTy(FT->getParamType(I))); |
| 3123 | // Stop storing if arguments' size overflows. Inside a function, |
| 3124 | // arguments after overflow have zero shadow values. |
| 3125 | if (ArgOffset + Size > ArgTLSSize) |
| 3126 | report_fatal_error("Argument size overflow in custom function"); |
| 3127 | StoreInst *SI = IRB.CreateAlignedStore( |
| 3128 | UF.getShadow(CB.getArgOperand(I)), |
| 3129 | UF.getArgTLS(FT->getParamType(I), ArgOffset, IRB), |
| 3130 | ShadowTLSAlignment); |
| 3131 | UF.UC.markNosanitize(SI); |
| 3132 | ArgOffset += alignTo(Size, ShadowTLSAlignment); |
| 3133 | } |
| 3134 | |
| 3135 | // For taint ref_names, the wrapper just forwards to the ref function |
| 3136 | // and TaintPass will handle the __dfsw_ wrapping via its own dfsan TLS. |
| 3137 | // Skip reading retval TLS in that case |
| 3138 | auto It = UF.UC.Scope.custom.find(F->getName().str()); |
| 3139 | bool IsTaintRef = (It != UF.UC.Scope.custom.end()) && |
| 3140 | UF.UC.ABIList.isIn(It->second.ref_name, "taint"); |
| 3141 | |
| 3142 | CB.setCalledFunction(UF.UC.getCustomFunction(F)); |
| 3143 | if (!FT->getReturnType()->isVoidTy()) { |
| 3144 | if (IsTaintRef) { |
| 3145 | // No ucsan return shadow from the wrapper; set zero. |
| 3146 | UF.setShadow(&CB, UF.UC.getZeroShadow(&CB)); |
| 3147 | } else { |
| 3148 | IRB.SetInsertPoint(CB.getNextNode()); |
nothing calls this directly
no test coverage detected