| 1940 | } |
| 1941 | |
| 1942 | Function *UCSan::getCustomFunction(const Function *F) { |
| 1943 | // Handles auto-custom function wrapping based on YAML configuration |
| 1944 | // Maps arguments from one function signature to another |
| 1945 | |
| 1946 | auto Name = F->getName().str(); |
| 1947 | |
| 1948 | // Check if already built |
| 1949 | if (CustomFuncs.find(Name) != CustomFuncs.end()) { |
| 1950 | return CustomFuncs[Name]; |
| 1951 | } |
| 1952 | |
| 1953 | // Check if this is a custom function in metadata |
| 1954 | if (Scope.custom.find(Name) == Scope.custom.end()) { |
| 1955 | return nullptr; // Not a custom function |
| 1956 | } |
| 1957 | |
| 1958 | auto &CustomEntry = Scope.custom[Name]; |
| 1959 | |
| 1960 | // Verify referenced function type exists |
| 1961 | if (CustomFuncTypes.find(CustomEntry.ref_name) == CustomFuncTypes.end()) { |
| 1962 | errs() << "Error: Referenced function " << CustomEntry.ref_name << " not found\n"; |
| 1963 | return nullptr; |
| 1964 | } |
| 1965 | |
| 1966 | // Check if ref function is a taint type (handled by TaintPass). |
| 1967 | // For taint refs, generate a simple forwarding wrapper that calls the ref |
| 1968 | // function directly with remapped args. TaintPass will instrument the |
| 1969 | // wrapper body and convert the inner call to __dfsw_<ref>. |
| 1970 | bool IsTaintRef = ABIList.isIn(CustomEntry.ref_name, "taint"); |
| 1971 | |
| 1972 | // Create wrapper function |
| 1973 | auto Linkage = Function::InternalLinkage; |
| 1974 | auto WrappedName = "__auto_dfsw_" + Name; |
| 1975 | auto RefedName = IsTaintRef ? CustomEntry.ref_name |
| 1976 | : ("__dfsw_" + CustomEntry.ref_name); |
| 1977 | |
| 1978 | FunctionType *RefedFuncType = CustomFuncTypes[CustomEntry.ref_name]; |
| 1979 | FunctionType *WrapperType = FunctionType::get(F->getReturnType(), |
| 1980 | F->getFunctionType()->params(), |
| 1981 | F->isVarArg()); |
| 1982 | |
| 1983 | Function *WrapperFunc = Function::Create(WrapperType, Linkage, WrappedName, *Mod); |
| 1984 | // Keep wrapper/runtime call ABI robust even when module stack alignment is 8. |
| 1985 | WrapperFunc->addFnAttr(Attribute::getWithStackAlignment(*Ctx, Align(16))); |
| 1986 | WrapperFunc->addFnAttr("stackrealign"); |
| 1987 | // For ucsan custom refs, mark wrapper nosanitize so TaintPass skips its body. |
| 1988 | // For taint refs, leave the wrapper instrumentable so TaintPass wraps the |
| 1989 | // inner ref call with its proper taint-label handling. |
| 1990 | if (!IsTaintRef) |
| 1991 | markFunctionNosanitize(WrapperFunc); |
| 1992 | BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", WrapperFunc); |
| 1993 | IRBuilder<> IRB(BB); |
| 1994 | |
| 1995 | // Create UCSanFunction context for shadow memory access |
| 1996 | UCSanFunction UF(*this, WrapperFunc); |
| 1997 | |
| 1998 | // Build argument mapping |
| 1999 | std::map<unsigned int, unsigned int> ArgMap; |
no test coverage detected