xref: /minix/minix/llvm/passes/magic/MagicPass.cpp (revision bdb56518)
13e457fe3SDavid van Moolenbroek #include <magic/MagicPass.h>
23e457fe3SDavid van Moolenbroek 
33e457fe3SDavid van Moolenbroek using namespace llvm;
43e457fe3SDavid van Moolenbroek 
53e457fe3SDavid van Moolenbroek PASS_COMMON_INIT_ONCE();
63e457fe3SDavid van Moolenbroek 
73e457fe3SDavid van Moolenbroek // command-line arguments
83e457fe3SDavid van Moolenbroek static cl::opt<std::string>
93e457fe3SDavid van Moolenbroek DLLFName("magic-dll-function",
103e457fe3SDavid van Moolenbroek     cl::desc("Specify the name of the deepest long-lived function whose stack "
113e457fe3SDavid van Moolenbroek         "needs to be instrumented"),
123e457fe3SDavid van Moolenbroek     cl::init(MAGIC_ENTRY_POINT), cl::NotHidden, cl::ValueRequired);
133e457fe3SDavid van Moolenbroek 
143e457fe3SDavid van Moolenbroek static cl::opt<std::string>
153e457fe3SDavid van Moolenbroek LibPathRegex("magic-lib-path-regex",
163e457fe3SDavid van Moolenbroek     cl::desc("Specify all the colon-separated path regexes that identify directories containing "
173e457fe3SDavid van Moolenbroek         "libraries. Deprecated. Use -magic-ext-lib-sections instead."),
183e457fe3SDavid van Moolenbroek     cl::init(""), cl::NotHidden, cl::ValueRequired);
193e457fe3SDavid van Moolenbroek 
203e457fe3SDavid van Moolenbroek static cl::opt<std::string>
213e457fe3SDavid van Moolenbroek VoidTypeAlias("magic-void-alias",
223e457fe3SDavid van Moolenbroek     cl::desc("Specify all the colon-separated type names that are to be treated as void, typically "
233e457fe3SDavid van Moolenbroek         "used in custom memory management implementations"),
243e457fe3SDavid van Moolenbroek     cl::init(""), cl::NotHidden, cl::ValueRequired);
253e457fe3SDavid van Moolenbroek 
263e457fe3SDavid van Moolenbroek static cl::opt<std::string>
273e457fe3SDavid van Moolenbroek MMFuncPrefix("magic-mmfunc-prefix",
283e457fe3SDavid van Moolenbroek     cl::desc("Specify all the colon-separated prefixes that are to be used when extracting "
293e457fe3SDavid van Moolenbroek         "memory management functions used in custom memory management implementations"),
303e457fe3SDavid van Moolenbroek     cl::init(""), cl::NotHidden, cl::ValueRequired);
313e457fe3SDavid van Moolenbroek 
323e457fe3SDavid van Moolenbroek static cl::opt<std::string>
333e457fe3SDavid van Moolenbroek MMFuncPair("magic-mmfunc-pair",
343e457fe3SDavid van Moolenbroek     cl::desc("Specify all the colon-separated pairs of malloc/free style memory management functions "
353e457fe3SDavid van Moolenbroek         "used in custom memory management implementations. Each function is to be listed together "
363e457fe3SDavid van Moolenbroek 	"with a number indicating which of the input parameters is the one corresponding to its "
373e457fe3SDavid van Moolenbroek 	"malloc(size)/free(pointer) counterpart. Example: "
383e457fe3SDavid van Moolenbroek 	"\"my_smart_alloc/3;my_smart_free/3:my_custom_alloc/2;my_custom_free/1\". "
393e457fe3SDavid van Moolenbroek 	"The counter for arguments starts from 1."),
403e457fe3SDavid van Moolenbroek     cl::init(""), cl::NotHidden, cl::ValueRequired);
413e457fe3SDavid van Moolenbroek 
423e457fe3SDavid van Moolenbroek static cl::opt<std::string>
433e457fe3SDavid van Moolenbroek MMPoolFunc("magic-mm-poolfunc",
443e457fe3SDavid van Moolenbroek     cl::desc("Specify a pool memory management set of functions for creating pools, destroying pools, "
453e457fe3SDavid van Moolenbroek 		"managing the pool buffers, reseting (reusing) pools and allocating memory blocks from the pool. "
463e457fe3SDavid van Moolenbroek 		"All the functions are to be listed together with a number indicating which of the input parameters"
473e457fe3SDavid van Moolenbroek 		"(numbering starts at 1) corresponds to the pool object. For the creation function, the pool object "
483e457fe3SDavid van Moolenbroek 		"can be the return value (specify 0 for return value). The block allocation function additionally "
493e457fe3SDavid van Moolenbroek 		"requires the number of the parameter denoting the size. Separate sets of functions using ':' and "
503e457fe3SDavid van Moolenbroek 		"separate multiple functions of the same type using ';'. "
513e457fe3SDavid van Moolenbroek 		"Example: \"my_pool_block_alloc/1/2:my_pool_create/0:my_pool_destroy/1:my_pool_alloc/1;"
523e457fe3SDavid van Moolenbroek 		"another_pool_alloc/1;my_pool_free/1:my_pool_reset/1\"."
533e457fe3SDavid van Moolenbroek 		"If there are no additional management functions, skip them. "
543e457fe3SDavid van Moolenbroek 		"Example: \"pool_block_alloc/1/2:pool_create:pool_destroy/1\"."),
553e457fe3SDavid van Moolenbroek     cl::init(""), cl::NotHidden, cl::ValueRequired);
563e457fe3SDavid van Moolenbroek 
573e457fe3SDavid van Moolenbroek static cl::opt<bool>
583e457fe3SDavid van Moolenbroek EnablePoolMemReuse("magic-mpool-enable-reuse",
593e457fe3SDavid van Moolenbroek     cl::desc("Enable memory reuse across pools."),
603e457fe3SDavid van Moolenbroek     cl::init(false), cl::NotHidden);
613e457fe3SDavid van Moolenbroek 
623e457fe3SDavid van Moolenbroek static cl::opt<std::string>
633e457fe3SDavid van Moolenbroek MMAPCtlFunction("magic-mmap-ctlfunc",
643e457fe3SDavid van Moolenbroek     cl::desc("Specify all the colon-separated mmap control functions that change low-level properties"
653e457fe3SDavid van Moolenbroek         "of memory-mapped memory regions taking the start address as an argument"),
663e457fe3SDavid van Moolenbroek     cl::init(""), cl::NotHidden, cl::ValueRequired);
673e457fe3SDavid van Moolenbroek 
683e457fe3SDavid van Moolenbroek static cl::opt<std::string>
693e457fe3SDavid van Moolenbroek MagicDataSections("magic-data-sections",
703e457fe3SDavid van Moolenbroek     cl::desc("Specify all the colon-separated magic data section regexes not to instrument"),
7176b68f9fSDavid van Moolenbroek     cl::init("^" MAGIC_STATIC_VARS_SECTION_PREFIX ".*$:^" UNBL_SECTION_PREFIX ".*$"), cl::NotHidden, cl::ValueRequired);
723e457fe3SDavid van Moolenbroek 
733e457fe3SDavid van Moolenbroek static cl::opt<std::string>
743e457fe3SDavid van Moolenbroek MagicFunctionSections("magic-function-sections",
753e457fe3SDavid van Moolenbroek     cl::desc("Specify all the colon-separated magic function section regexes not to instrument"),
763e457fe3SDavid van Moolenbroek     cl::init("^" MAGIC_STATIC_FUNCTIONS_SECTION ".*$:^" UNBL_SECTION_PREFIX ".*$"), cl::NotHidden, cl::ValueRequired);
773e457fe3SDavid van Moolenbroek 
783e457fe3SDavid van Moolenbroek static cl::opt<std::string>
793e457fe3SDavid van Moolenbroek ExtLibSections("magic-ext-lib-sections",
803e457fe3SDavid van Moolenbroek     cl::desc("Specify all the colon-separated external lib section regexes"),
813e457fe3SDavid van Moolenbroek     cl::init(MAGIC_DEFAULT_EXT_LIB_SECTION_REGEX), cl::NotHidden, cl::ValueRequired);
823e457fe3SDavid van Moolenbroek 
833e457fe3SDavid van Moolenbroek static cl::opt<std::string>
843e457fe3SDavid van Moolenbroek baseBuildDir("magic-base-build-dir",
853e457fe3SDavid van Moolenbroek     cl::desc("Specify the base build directory from which the pass derives relative directories for debug symbols"),
863e457fe3SDavid van Moolenbroek     cl::init(""), cl::NotHidden, cl::ValueRequired);
873e457fe3SDavid van Moolenbroek 
883e457fe3SDavid van Moolenbroek static cl::opt<bool>
893e457fe3SDavid van Moolenbroek EnableShadowing("magic-enable-shadowing",
903e457fe3SDavid van Moolenbroek     cl::desc("Enable state shadowing"),
913e457fe3SDavid van Moolenbroek     cl::init(false), cl::NotHidden);
923e457fe3SDavid van Moolenbroek 
933e457fe3SDavid van Moolenbroek static cl::opt<bool>
9476b68f9fSDavid van Moolenbroek DisableMemFunctions("magic-disable-mem-functions",
9576b68f9fSDavid van Moolenbroek     cl::desc("Disable hooking of memory functions"),
9676b68f9fSDavid van Moolenbroek     cl::init(false), cl::NotHidden);
9776b68f9fSDavid van Moolenbroek 
9876b68f9fSDavid van Moolenbroek static cl::opt<bool>
9976b68f9fSDavid van Moolenbroek DisableMallocSkip("magic-disable-malloc-skip",
10076b68f9fSDavid van Moolenbroek     cl::desc("Disable ignoring malloc data variables"),
10176b68f9fSDavid van Moolenbroek     cl::init(false), cl::NotHidden);
10276b68f9fSDavid van Moolenbroek 
10376b68f9fSDavid van Moolenbroek static cl::opt<bool>
1043e457fe3SDavid van Moolenbroek SkipAll("magic-skip-all",
1053e457fe3SDavid van Moolenbroek     cl::desc("Exit immediately"),
1063e457fe3SDavid van Moolenbroek     cl::init(false), cl::NotHidden);
1073e457fe3SDavid van Moolenbroek 
1083e457fe3SDavid van Moolenbroek #if MAGIC_USE_QPROF_INSTRUMENTATION
1093e457fe3SDavid van Moolenbroek QPROF_DECLARE_ALL_OPTS(magic,
1103e457fe3SDavid van Moolenbroek     magicLLSitestacks,
1113e457fe3SDavid van Moolenbroek     magicDeepestLLLoops,
1123e457fe3SDavid van Moolenbroek     magicDeepestLLLibs,
1133e457fe3SDavid van Moolenbroek     magicTaskClasses
1143e457fe3SDavid van Moolenbroek );
1153e457fe3SDavid van Moolenbroek #endif
1163e457fe3SDavid van Moolenbroek 
1173e457fe3SDavid van Moolenbroek #define DEBUG_TYPE_INFOS            0
1183e457fe3SDavid van Moolenbroek #define DEBUG_FILL_TYPE_INFOS       0
1193e457fe3SDavid van Moolenbroek #define DEBUG_FILL_EXT_TYPE_INFOS   0
1203e457fe3SDavid van Moolenbroek #define DEBUG_ALLOC_LEVEL           0
1213e457fe3SDavid van Moolenbroek #define DEBUG_ALLOC_BAD_TYPES       0
1223e457fe3SDavid van Moolenbroek #define DEBUG_CASTS                 0
1233e457fe3SDavid van Moolenbroek #define DEBUG_DUPLICATED_TYPE_INFOS 0
1243e457fe3SDavid van Moolenbroek #define DEBUG_VALUE_SET             0
1253e457fe3SDavid van Moolenbroek #define DEBUG_QPROF                 0
1263e457fe3SDavid van Moolenbroek 
1273e457fe3SDavid van Moolenbroek namespace llvm {
1283e457fe3SDavid van Moolenbroek 
1293e457fe3SDavid van Moolenbroek //===----------------------------------------------------------------------===//
1303e457fe3SDavid van Moolenbroek // Constructors, destructor, and operators
1313e457fe3SDavid van Moolenbroek //===----------------------------------------------------------------------===//
1323e457fe3SDavid van Moolenbroek 
MagicPass()1333e457fe3SDavid van Moolenbroek MagicPass::MagicPass() : ModulePass(ID) {}
1343e457fe3SDavid van Moolenbroek 
1353e457fe3SDavid van Moolenbroek unsigned TypeInfo::maxNameLength = 0;
1363e457fe3SDavid van Moolenbroek unsigned TypeInfo::maxTypeStringLength = 0;
1373e457fe3SDavid van Moolenbroek std::map<TYPECONST Type*, std::set<int> > TypeInfo::intCastTypes;
1383e457fe3SDavid van Moolenbroek std::map<TYPECONST Type*, std::set<TYPECONST Type*> > TypeInfo::bitCastTypes;
1393e457fe3SDavid van Moolenbroek std::map<TYPECONST Type*, std::set<TypeInfo*> > TypeInfo::typeMap;
1403e457fe3SDavid van Moolenbroek 
1413e457fe3SDavid van Moolenbroek bool SmartType::forceRawUnions = MAGIC_FORCE_RAW_UNIONS;
1423e457fe3SDavid van Moolenbroek bool SmartType::forceRawBitfields = MAGIC_FORCE_RAW_BITFIELDS;
1433e457fe3SDavid van Moolenbroek 
1443e457fe3SDavid van Moolenbroek Function *MagicMemFunction::lastAllocWrapper = NULL;
1453e457fe3SDavid van Moolenbroek std::map<std::string, Function*> MagicMemFunction::allocWrapperCache;
1463e457fe3SDavid van Moolenbroek std::set<Function*> MagicMemFunction::customWrapperSet;
1473e457fe3SDavid van Moolenbroek 
1483e457fe3SDavid van Moolenbroek //===----------------------------------------------------------------------===//
1493e457fe3SDavid van Moolenbroek // Public methods
1503e457fe3SDavid van Moolenbroek //===----------------------------------------------------------------------===//
1513e457fe3SDavid van Moolenbroek 
runOnModule(Module & M)1523e457fe3SDavid van Moolenbroek bool MagicPass::runOnModule(Module &M) {
1533e457fe3SDavid van Moolenbroek     unsigned i;
1543e457fe3SDavid van Moolenbroek 
1553e457fe3SDavid van Moolenbroek     if (SkipAll) {
1563e457fe3SDavid van Moolenbroek 	return false;
1573e457fe3SDavid van Moolenbroek     }
1583e457fe3SDavid van Moolenbroek 
1593e457fe3SDavid van Moolenbroek     magicPassLog("Running...");
1603e457fe3SDavid van Moolenbroek     EDIType::setModule(&M);
1613e457fe3SDavid van Moolenbroek     PassUtil::setModule(&M);
1623e457fe3SDavid van Moolenbroek 
1633e457fe3SDavid van Moolenbroek     // initialize qprof instrumentation
1643e457fe3SDavid van Moolenbroek     qprofInstrumentationInit(M);
1653e457fe3SDavid van Moolenbroek 
1663e457fe3SDavid van Moolenbroek     //look up magic entry point function
1673e457fe3SDavid van Moolenbroek     Function *magicEntryPointFunc = M.getFunction(MAGIC_ENTRY_POINT);
1683e457fe3SDavid van Moolenbroek     if( !magicEntryPointFunc ){
1693e457fe3SDavid van Moolenbroek         //if no valid entry point, we are not compiling a valid program, skip pass
1703e457fe3SDavid van Moolenbroek         magicPassLog("Error: no " << MAGIC_ENTRY_POINT << "() found");
1713e457fe3SDavid van Moolenbroek         return false;
1723e457fe3SDavid van Moolenbroek     }
1733e457fe3SDavid van Moolenbroek 
1743e457fe3SDavid van Moolenbroek     //look up magic enabled variable
1753e457fe3SDavid van Moolenbroek     GlobalVariable* magicEnabled = M.getNamedGlobal(MAGIC_ENABLED);
1763e457fe3SDavid van Moolenbroek     if(!magicEnabled) {
1773e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_ENABLED << " variable found");
1783e457fe3SDavid van Moolenbroek         exit(1);
1793e457fe3SDavid van Moolenbroek     }
1803e457fe3SDavid van Moolenbroek 
1813e457fe3SDavid van Moolenbroek     //look up magic root variable
1823e457fe3SDavid van Moolenbroek     GlobalVariable* magicRootVar = M.getNamedGlobal(MAGIC_ROOT_VAR_NAME);
1833e457fe3SDavid van Moolenbroek     if(!magicRootVar) {
1843e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_ROOT_VAR_NAME << " variable found");
1853e457fe3SDavid van Moolenbroek         exit(1);
1863e457fe3SDavid van Moolenbroek     }
1873e457fe3SDavid van Moolenbroek 
1883e457fe3SDavid van Moolenbroek     //look up magic data init function and get the last instruction to add stuff in it
1893e457fe3SDavid van Moolenbroek     Function *magicDataInitFunc = M.getFunction(MAGIC_DATA_INIT_FUNC_NAME);
1903e457fe3SDavid van Moolenbroek     if(!magicDataInitFunc){
1913e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_DATA_INIT_FUNC_NAME << "() found");
1923e457fe3SDavid van Moolenbroek         exit(1);
1933e457fe3SDavid van Moolenbroek     }
1943e457fe3SDavid van Moolenbroek     Instruction *magicArrayBuildFuncInst = magicDataInitFunc->back().getTerminator();
1953e457fe3SDavid van Moolenbroek 
196c07c198bSDavid van Moolenbroek     //look up pointer to magic memory instrumentation flag
197c07c198bSDavid van Moolenbroek     Value* magicNoMemInst = MagicUtil::getMagicRStructFieldPtr(M, magicArrayBuildFuncInst, magicRootVar, MAGIC_RSTRUCT_FIELD_NO_MEM_INST);
198c07c198bSDavid van Moolenbroek     if(!magicNoMemInst) {
199c07c198bSDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_RSTRUCT_FIELD_NO_MEM_INST << " field found");
200c07c198bSDavid van Moolenbroek         exit(1);
201c07c198bSDavid van Moolenbroek     }
202c07c198bSDavid van Moolenbroek 
2033e457fe3SDavid van Moolenbroek     //look up pointer to magic array and magic struct type
2043e457fe3SDavid van Moolenbroek     Value* magicArrayPtr = MagicUtil::getMagicRStructFieldPtr(M, magicArrayBuildFuncInst, magicRootVar, MAGIC_RSTRUCT_FIELD_SENTRIES);
2053e457fe3SDavid van Moolenbroek     if(!magicArrayPtr) {
2063e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_RSTRUCT_FIELD_SENTRIES << " field found");
2073e457fe3SDavid van Moolenbroek         exit(1);
2083e457fe3SDavid van Moolenbroek     }
2093e457fe3SDavid van Moolenbroek     TYPECONST StructType* magicStructType = (TYPECONST StructType*) ((TYPECONST PointerType*)((TYPECONST PointerType*)magicArrayPtr->getType())->getElementType())->getElementType();
2103e457fe3SDavid van Moolenbroek 
2113e457fe3SDavid van Moolenbroek     //look up pointer to magic array size
2123e457fe3SDavid van Moolenbroek     Value *magicArraySize = MagicUtil::getMagicRStructFieldPtr(M, magicArrayBuildFuncInst, magicRootVar, MAGIC_RSTRUCT_FIELD_SENTRIES_NUM);
2133e457fe3SDavid van Moolenbroek     if(!magicArraySize) {
2143e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_RSTRUCT_FIELD_SENTRIES_NUM << " field found");
2153e457fe3SDavid van Moolenbroek         exit(1);
2163e457fe3SDavid van Moolenbroek     }
2173e457fe3SDavid van Moolenbroek 
2183e457fe3SDavid van Moolenbroek     //look up pointer to magic array string size
2193e457fe3SDavid van Moolenbroek     Value *magicArrayStrSize = MagicUtil::getMagicRStructFieldPtr(M, magicArrayBuildFuncInst, magicRootVar, MAGIC_RSTRUCT_FIELD_SENTRIES_STR_NUM);
2203e457fe3SDavid van Moolenbroek     if(!magicArrayStrSize) {
2213e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_RSTRUCT_FIELD_SENTRIES_STR_NUM << " field found");
2223e457fe3SDavid van Moolenbroek         exit(1);
2233e457fe3SDavid van Moolenbroek     }
2243e457fe3SDavid van Moolenbroek 
2253e457fe3SDavid van Moolenbroek     //look up pointer to magic next id
2263e457fe3SDavid van Moolenbroek     Value *magicNextId = MagicUtil::getMagicRStructFieldPtr(M, magicArrayBuildFuncInst, magicRootVar, MAGIC_RSTRUCT_FIELD_SENTRIES_NEXT_ID);
2273e457fe3SDavid van Moolenbroek     if(!magicNextId) {
2283e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_RSTRUCT_FIELD_SENTRIES_NEXT_ID << " field found");
2293e457fe3SDavid van Moolenbroek         exit(1);
2303e457fe3SDavid van Moolenbroek     }
2313e457fe3SDavid van Moolenbroek 
2323e457fe3SDavid van Moolenbroek     //look up pointer to magic dsindex array and magic dsindex struct type
2333e457fe3SDavid van Moolenbroek     Value* magicDsindexArrayPtr = MagicUtil::getMagicRStructFieldPtr(M, magicArrayBuildFuncInst, magicRootVar, MAGIC_RSTRUCT_FIELD_DSINDEXES);
2343e457fe3SDavid van Moolenbroek     if(!magicDsindexArrayPtr) {
2353e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_RSTRUCT_FIELD_DSINDEXES << " field found");
2363e457fe3SDavid van Moolenbroek         exit(1);
2373e457fe3SDavid van Moolenbroek     }
2383e457fe3SDavid van Moolenbroek     TYPECONST StructType* magicDsindexStructType = (TYPECONST StructType*) ((TYPECONST PointerType*)((TYPECONST PointerType*)magicDsindexArrayPtr->getType())->getElementType())->getElementType();
2393e457fe3SDavid van Moolenbroek 
2403e457fe3SDavid van Moolenbroek     //look up pointer to magic dsindex array size
2413e457fe3SDavid van Moolenbroek     Value *magicDsindexArraySize = MagicUtil::getMagicRStructFieldPtr(M, magicArrayBuildFuncInst, magicRootVar, MAGIC_RSTRUCT_FIELD_DSINDEXES_NUM);
2423e457fe3SDavid van Moolenbroek     if(!magicDsindexArraySize) {
2433e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_RSTRUCT_FIELD_DSINDEXES_NUM << " field found");
2443e457fe3SDavid van Moolenbroek         exit(1);
2453e457fe3SDavid van Moolenbroek     }
2463e457fe3SDavid van Moolenbroek 
2473e457fe3SDavid van Moolenbroek     //look up pointer to magic type array and magic type struct type
2483e457fe3SDavid van Moolenbroek     Value *magicTypeArrayPtr = MagicUtil::getMagicRStructFieldPtr(M, magicArrayBuildFuncInst, magicRootVar, MAGIC_RSTRUCT_FIELD_TYPES);
2493e457fe3SDavid van Moolenbroek     if(!magicTypeArrayPtr) {
2503e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_RSTRUCT_FIELD_TYPES << " field found");
2513e457fe3SDavid van Moolenbroek         exit(1);
2523e457fe3SDavid van Moolenbroek     }
2533e457fe3SDavid van Moolenbroek     TYPECONST StructType* magicTypeStructType = (TYPECONST StructType*) ((TYPECONST PointerType*)((TYPECONST PointerType*)magicTypeArrayPtr->getType())->getElementType())->getElementType();
2543e457fe3SDavid van Moolenbroek 
2553e457fe3SDavid van Moolenbroek     //look up pointer to magic type array size
2563e457fe3SDavid van Moolenbroek     Value *magicTypeArraySize = MagicUtil::getMagicRStructFieldPtr(M, magicArrayBuildFuncInst, magicRootVar, MAGIC_RSTRUCT_FIELD_TYPES_NUM);
2573e457fe3SDavid van Moolenbroek     if(!magicTypeArraySize) {
2583e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_RSTRUCT_FIELD_TYPES_NUM << " field found");
2593e457fe3SDavid van Moolenbroek         exit(1);
2603e457fe3SDavid van Moolenbroek     }
2613e457fe3SDavid van Moolenbroek 
2623e457fe3SDavid van Moolenbroek     //look up pointer to magic type next id
2633e457fe3SDavid van Moolenbroek     Value *magicTypeNextId = MagicUtil::getMagicRStructFieldPtr(M, magicArrayBuildFuncInst, magicRootVar, MAGIC_RSTRUCT_FIELD_TYPES_NEXT_ID);
2643e457fe3SDavid van Moolenbroek     if(!magicTypeNextId) {
2653e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_RSTRUCT_FIELD_TYPES_NEXT_ID << " field found");
2663e457fe3SDavid van Moolenbroek         exit(1);
2673e457fe3SDavid van Moolenbroek     }
2683e457fe3SDavid van Moolenbroek 
2693e457fe3SDavid van Moolenbroek     //look up pointer to magic function array and magic function struct type
2703e457fe3SDavid van Moolenbroek     Value *magicFunctionArrayPtr = MagicUtil::getMagicRStructFieldPtr(M, magicArrayBuildFuncInst, magicRootVar, MAGIC_RSTRUCT_FIELD_FUNCTIONS);
2713e457fe3SDavid van Moolenbroek     if(!magicFunctionArrayPtr) {
2723e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_RSTRUCT_FIELD_FUNCTIONS << " field found");
2733e457fe3SDavid van Moolenbroek         exit(1);
2743e457fe3SDavid van Moolenbroek     }
2753e457fe3SDavid van Moolenbroek     TYPECONST StructType* magicFunctionStructType = (TYPECONST StructType*) ((TYPECONST PointerType*)((TYPECONST PointerType*)magicFunctionArrayPtr->getType())->getElementType())->getElementType();
2763e457fe3SDavid van Moolenbroek 
2773e457fe3SDavid van Moolenbroek     //look up pointer to magic function array size
2783e457fe3SDavid van Moolenbroek     Value *magicFunctionArraySize = MagicUtil::getMagicRStructFieldPtr(M, magicArrayBuildFuncInst, magicRootVar, MAGIC_RSTRUCT_FIELD_FUNCTIONS_NUM);
2793e457fe3SDavid van Moolenbroek     if(!magicFunctionArraySize) {
2803e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_RSTRUCT_FIELD_FUNCTIONS_NUM << " field found");
2813e457fe3SDavid van Moolenbroek         exit(1);
2823e457fe3SDavid van Moolenbroek     }
2833e457fe3SDavid van Moolenbroek 
2843e457fe3SDavid van Moolenbroek     //look up pointer to magic function next id
2853e457fe3SDavid van Moolenbroek     Value *magicFunctionNextId = MagicUtil::getMagicRStructFieldPtr(M, magicArrayBuildFuncInst, magicRootVar, MAGIC_RSTRUCT_FIELD_FUNCTIONS_NEXT_ID);
2863e457fe3SDavid van Moolenbroek     if(!magicFunctionNextId) {
2873e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_RSTRUCT_FIELD_FUNCTIONS_NEXT_ID << " field found");
2883e457fe3SDavid van Moolenbroek         exit(1);
2893e457fe3SDavid van Moolenbroek     }
2903e457fe3SDavid van Moolenbroek 
2913e457fe3SDavid van Moolenbroek     //look up magic dsentry struct type
2923e457fe3SDavid van Moolenbroek     Value *magicFirstDsentyPtr = MagicUtil::getMagicRStructFieldPtr(M, magicArrayBuildFuncInst, magicRootVar, MAGIC_RSTRUCT_FIELD_FIRST_DSENTRY);
2933e457fe3SDavid van Moolenbroek     if(!magicFirstDsentyPtr) {
2943e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_RSTRUCT_FIELD_FIRST_DSENTRY << " field found");
2953e457fe3SDavid van Moolenbroek         exit(1);
2963e457fe3SDavid van Moolenbroek     }
2973e457fe3SDavid van Moolenbroek     TYPECONST StructType* magicDsentryStructType = (TYPECONST StructType*) ((TYPECONST PointerType*)((TYPECONST PointerType*)magicFirstDsentyPtr->getType())->getElementType())->getElementType();
2983e457fe3SDavid van Moolenbroek 
2993e457fe3SDavid van Moolenbroek     //look up magic init function
3003e457fe3SDavid van Moolenbroek     Function *magicInitFunc = M.getFunction(MAGIC_INIT_FUNC_NAME);
3013e457fe3SDavid van Moolenbroek     if( !magicInitFunc ){
3023e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_INIT_FUNC_NAME << "() found");
3033e457fe3SDavid van Moolenbroek         exit(1);
3043e457fe3SDavid van Moolenbroek     }
3053e457fe3SDavid van Moolenbroek 
3063e457fe3SDavid van Moolenbroek     //look up magic dsentry stack functions
3073e457fe3SDavid van Moolenbroek     Function *magicStackDsentryCreateFunc = M.getFunction(MAGIC_STACK_DSENTRIES_CREATE_FUNC_NAME);
3083e457fe3SDavid van Moolenbroek     if (!magicStackDsentryCreateFunc) {
3093e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_STACK_DSENTRIES_CREATE_FUNC_NAME << "() found");
3103e457fe3SDavid van Moolenbroek         exit(1);
3113e457fe3SDavid van Moolenbroek     }
3123e457fe3SDavid van Moolenbroek     Function *magicStackDsentryDestroyFunc = M.getFunction(MAGIC_STACK_DSENTRIES_DESTROY_FUNC_NAME);
3133e457fe3SDavid van Moolenbroek     if (!magicStackDsentryDestroyFunc) {
3143e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_STACK_DSENTRIES_DESTROY_FUNC_NAME << "() found");
3153e457fe3SDavid van Moolenbroek         exit(1);
3163e457fe3SDavid van Moolenbroek     }
3173e457fe3SDavid van Moolenbroek 
3183e457fe3SDavid van Moolenbroek     //look up deepest long-lived function
3193e457fe3SDavid van Moolenbroek     Function *deepestLLFunction = M.getFunction(DLLFName);
3203e457fe3SDavid van Moolenbroek     if (!deepestLLFunction) {
3213e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << DLLFName << "() found");
3223e457fe3SDavid van Moolenbroek         exit(1);
3233e457fe3SDavid van Moolenbroek     }
3243e457fe3SDavid van Moolenbroek 
3253e457fe3SDavid van Moolenbroek     //lookup magic get page size function
3263e457fe3SDavid van Moolenbroek     Function *magicGetPageSizeFunc = M.getFunction(MAGIC_GET_PAGE_SIZE_FUNC_NAME);
3273e457fe3SDavid van Moolenbroek     if(!magicGetPageSizeFunc){
3283e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_GET_PAGE_SIZE_FUNC_NAME << "() found");
3293e457fe3SDavid van Moolenbroek         exit(1);
3303e457fe3SDavid van Moolenbroek     }
3313e457fe3SDavid van Moolenbroek 
3323e457fe3SDavid van Moolenbroek     //look up magic void pointer
3333e457fe3SDavid van Moolenbroek     GlobalVariable *magicVoidPtr = M.getNamedGlobal(MAGIC_VOID_PTR_NAME);
3343e457fe3SDavid van Moolenbroek     if(!magicVoidPtr) {
3353e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_VOID_PTR_NAME << "variable found");
3363e457fe3SDavid van Moolenbroek         exit(1);
3373e457fe3SDavid van Moolenbroek     }
3383e457fe3SDavid van Moolenbroek     assert(!isMagicGV(M, magicVoidPtr));
3393e457fe3SDavid van Moolenbroek 
3403e457fe3SDavid van Moolenbroek     //look up magic void array
3413e457fe3SDavid van Moolenbroek     GlobalVariable *magicVoidArr = M.getNamedGlobal(MAGIC_VOID_ARRAY_NAME);
3423e457fe3SDavid van Moolenbroek     if(!magicVoidArr) {
3433e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_VOID_ARRAY_NAME << "variable found");
3443e457fe3SDavid van Moolenbroek         exit(1);
3453e457fe3SDavid van Moolenbroek     }
3463e457fe3SDavid van Moolenbroek     assert(!isMagicGV(M, magicVoidArr));
3473e457fe3SDavid van Moolenbroek 
3483e457fe3SDavid van Moolenbroek     //look up magic void * type pointer
3493e457fe3SDavid van Moolenbroek     GlobalVariable *magicVoidPtrTypePtr = M.getNamedGlobal(MAGIC_VOID_PTR_TYPE_PTR_NAME);
3503e457fe3SDavid van Moolenbroek     if(!magicVoidPtrTypePtr) {
3513e457fe3SDavid van Moolenbroek         magicPassErr("Error: no " << MAGIC_VOID_PTR_TYPE_PTR_NAME << "variable found");
3523e457fe3SDavid van Moolenbroek         exit(1);
3533e457fe3SDavid van Moolenbroek     }
3543e457fe3SDavid van Moolenbroek 
3553e457fe3SDavid van Moolenbroek     //determine lib path regexes
3563e457fe3SDavid van Moolenbroek     PassUtil::parseStringListOpt(libPathRegexes, LibPathRegex);
3573e457fe3SDavid van Moolenbroek 
3583e457fe3SDavid van Moolenbroek     //determine void type aliases
3593e457fe3SDavid van Moolenbroek     PassUtil::parseStringListOpt(voidTypeAliases, VoidTypeAlias);
3603e457fe3SDavid van Moolenbroek     std::copy( voidTypeAliases.begin(), voidTypeAliases.end(), std::inserter( voidTypeAliasesSet, voidTypeAliasesSet.end() ) );
3613e457fe3SDavid van Moolenbroek 
3623e457fe3SDavid van Moolenbroek     //determine mm function prefixes
3633e457fe3SDavid van Moolenbroek     PassUtil::parseStringListOpt(mmFuncPrefixes, MMFuncPrefix);
3643e457fe3SDavid van Moolenbroek 
3653e457fe3SDavid van Moolenbroek     //determine custom malloc/free style custom mm functions
3663e457fe3SDavid van Moolenbroek     PassUtil::parseStringPairListOpt(mmFuncPairs, MMFuncPair);
3673e457fe3SDavid van Moolenbroek 
3683e457fe3SDavid van Moolenbroek     //determine the pool management sets of functions
3693e457fe3SDavid van Moolenbroek     PassUtil::parseStringListOpt(mmPoolFunctions, MMPoolFunc);
3703e457fe3SDavid van Moolenbroek 
3713e457fe3SDavid van Moolenbroek     //determine mmap ctl functions
3723e457fe3SDavid van Moolenbroek     PassUtil::parseStringListOpt(mmapCtlFunctions, MMAPCtlFunction);
3733e457fe3SDavid van Moolenbroek 
3743e457fe3SDavid van Moolenbroek     //determine magic data section regexes
37576b68f9fSDavid van Moolenbroek     std::string DataSections = MagicDataSections;
37676b68f9fSDavid van Moolenbroek     if (!DisableMallocSkip)
37776b68f9fSDavid van Moolenbroek         DataSections += ":^" MAGIC_MALLOC_VARS_SECTION_PREFIX ".*$";
37876b68f9fSDavid van Moolenbroek     PassUtil::parseRegexListOpt(magicDataSectionRegexes, DataSections);
3793e457fe3SDavid van Moolenbroek 
3803e457fe3SDavid van Moolenbroek     //determine magic function section regexes
3813e457fe3SDavid van Moolenbroek     PassUtil::parseRegexListOpt(magicFunctionSectionRegexes, MagicFunctionSections);
3823e457fe3SDavid van Moolenbroek 
3833e457fe3SDavid van Moolenbroek     //determine magic ext lib section regexes
3843e457fe3SDavid van Moolenbroek     PassUtil::parseRegexListOpt(extLibSectionRegexes, ExtLibSections);
3853e457fe3SDavid van Moolenbroek 
3863e457fe3SDavid van Moolenbroek     //look up inttoptr type casts
3873e457fe3SDavid van Moolenbroek     Module::GlobalListType &globalList = M.getGlobalList();
3883e457fe3SDavid van Moolenbroek     Module::FunctionListType &functionList = M.getFunctionList();
3893e457fe3SDavid van Moolenbroek     std::vector<TYPECONST Type*> intCastTypes;
3903e457fe3SDavid van Moolenbroek     std::vector<int> intCastValues;
3913e457fe3SDavid van Moolenbroek     std::map<TYPECONST Type*, std::set<TYPECONST Type*> > bitCastMap;
3923e457fe3SDavid van Moolenbroek     for (Module::iterator it = functionList.begin(); it != functionList.end(); ++it) {
3933e457fe3SDavid van Moolenbroek         Function *F = it;
3943e457fe3SDavid van Moolenbroek         if(isMagicFunction(M, F)) {
3953e457fe3SDavid van Moolenbroek             continue;
3963e457fe3SDavid van Moolenbroek         }
3973e457fe3SDavid van Moolenbroek         for (inst_iterator I2 = inst_begin(F), E2 = inst_end(F); I2 != E2; ++I2) {
3983e457fe3SDavid van Moolenbroek             indexCasts(M, &(*I2), intCastTypes, intCastValues, bitCastMap);
3993e457fe3SDavid van Moolenbroek         }
4003e457fe3SDavid van Moolenbroek     }
4013e457fe3SDavid van Moolenbroek     for (Module::global_iterator it = globalList.begin(); it != globalList.end(); ++it) {
4023e457fe3SDavid van Moolenbroek         GlobalVariable *GV = it;
4033e457fe3SDavid van Moolenbroek         StringRef GVName = GV->getName();
4043e457fe3SDavid van Moolenbroek         if(isMagicGV(M, GV) || GVName.startswith(".str") || GVName.startswith(".arr") || GVName.startswith("C.")) {
4053e457fe3SDavid van Moolenbroek             continue;
4063e457fe3SDavid van Moolenbroek         }
4073e457fe3SDavid van Moolenbroek         if(GV->hasInitializer()) {
4083e457fe3SDavid van Moolenbroek             indexCasts(M, GV->getInitializer(), intCastTypes, intCastValues, bitCastMap);
4093e457fe3SDavid van Moolenbroek         }
4103e457fe3SDavid van Moolenbroek     }
4113e457fe3SDavid van Moolenbroek 
4123e457fe3SDavid van Moolenbroek     //index and set cast maps
4133e457fe3SDavid van Moolenbroek     std::map<TYPECONST Type*, std::set<int> > intCastMap;
4143e457fe3SDavid van Moolenbroek     std::map<TYPECONST Type*, std::set<int> >::iterator intCastMapIt;
4153e457fe3SDavid van Moolenbroek     for(i=0;i<intCastTypes.size();i++) {
4163e457fe3SDavid van Moolenbroek         TYPECONST Type* type = intCastTypes[i];
4173e457fe3SDavid van Moolenbroek         int value = intCastValues[i];
4183e457fe3SDavid van Moolenbroek         intCastMapIt = intCastMap.find(type);
4193e457fe3SDavid van Moolenbroek         if(intCastMapIt == intCastMap.end()) {
4203e457fe3SDavid van Moolenbroek             std::set<int> valueSet;
4213e457fe3SDavid van Moolenbroek             intCastMap.insert(std::pair<TYPECONST Type*, std::set<int> >(type, valueSet));
4223e457fe3SDavid van Moolenbroek             intCastMapIt = intCastMap.find(type);
4233e457fe3SDavid van Moolenbroek         }
4243e457fe3SDavid van Moolenbroek         assert(intCastMapIt != intCastMap.end());
4253e457fe3SDavid van Moolenbroek         std::set<int> *setPtr = &(intCastMapIt->second);
4263e457fe3SDavid van Moolenbroek         if(setPtr->size() == 1 && *(setPtr->begin()) == 0) {
4273e457fe3SDavid van Moolenbroek             continue;
4283e457fe3SDavid van Moolenbroek         }
4293e457fe3SDavid van Moolenbroek         if(value == 0) {
4303e457fe3SDavid van Moolenbroek             setPtr->clear();
4313e457fe3SDavid van Moolenbroek         }
4323e457fe3SDavid van Moolenbroek         setPtr->insert(value);
4333e457fe3SDavid van Moolenbroek     }
4343e457fe3SDavid van Moolenbroek     TypeInfo::setIntCastTypes(intCastMap);
4353e457fe3SDavid van Moolenbroek     TypeInfo::setBitCastTypes(bitCastMap);
4363e457fe3SDavid van Moolenbroek 
4373e457fe3SDavid van Moolenbroek #if MAGIC_INSTRUMENT_MEM_FUNCS
43876b68f9fSDavid van Moolenbroek     std::vector<MagicMemFunction> magicMemFunctions;
43976b68f9fSDavid van Moolenbroek     std::set<Function*> originalMagicMemFunctions;
44076b68f9fSDavid van Moolenbroek     std::vector<MagicDebugFunction> magicDebugFunctions;
44176b68f9fSDavid van Moolenbroek     std::vector<MagicMmapCtlFunction> magicMmapCtlFunctions;
44276b68f9fSDavid van Moolenbroek     if (!DisableMemFunctions) {
4433e457fe3SDavid van Moolenbroek         //look up magic memory functions and corresponding wrappers
4443e457fe3SDavid van Moolenbroek         #define __X(P) #P
4453e457fe3SDavid van Moolenbroek         std::string magicMemFuncNames[] = { MAGIC_MEM_FUNC_NAMES };
4463e457fe3SDavid van Moolenbroek         std::string magicMemDeallocFuncNames[] = { MAGIC_MEMD_FUNC_NAMES };
447b7725c85SDavid van Moolenbroek         std::string magicMemNestedFuncNames[] = { MAGIC_MEMN_FUNC_NAMES };
4483e457fe3SDavid van Moolenbroek         #undef __X
4493e457fe3SDavid van Moolenbroek         int magicMemFuncAllocFlags[] = { MAGIC_MEM_FUNC_ALLOC_FLAGS };
4503e457fe3SDavid van Moolenbroek         std::string magicMemPrefixes[] = { MAGIC_MEM_PREFIX_STRS };
4513e457fe3SDavid van Moolenbroek         std::vector<std::string> llvmCallPrefixes;
4523e457fe3SDavid van Moolenbroek         for (std::vector<std::string>::iterator it = mmFuncPrefixes.begin(); it != mmFuncPrefixes.end(); ++it) {
4533e457fe3SDavid van Moolenbroek             llvmCallPrefixes.push_back(*it);
4543e457fe3SDavid van Moolenbroek         }
4553e457fe3SDavid van Moolenbroek         llvmCallPrefixes.push_back("");
4563e457fe3SDavid van Moolenbroek         llvmCallPrefixes.push_back("\01"); //llvm uses odd prefixes for some functions, sometimes (e.g. mmap64)
4573e457fe3SDavid van Moolenbroek         for(i=0;magicMemFuncNames[i].compare("");i++) {
4583e457fe3SDavid van Moolenbroek             int allocFlags = magicMemFuncAllocFlags[i];
4593e457fe3SDavid van Moolenbroek             for(unsigned j=0;j<llvmCallPrefixes.size();j++) {
460b7725c85SDavid van Moolenbroek                 std::string fName = magicMemFuncNames[i];
461b7725c85SDavid van Moolenbroek                 Function *f = M.getFunction(llvmCallPrefixes[j] + fName);
4623e457fe3SDavid van Moolenbroek                 if(!f) {
4633e457fe3SDavid van Moolenbroek                     continue;
4643e457fe3SDavid van Moolenbroek                 }
4653e457fe3SDavid van Moolenbroek                 TYPECONST FunctionType *fType = f->getFunctionType();
4663e457fe3SDavid van Moolenbroek                 if(fType->getNumParams() == 0 && fType->isVarArg()) {
4673e457fe3SDavid van Moolenbroek                     //missing function prototype, i.e. no realistic caller. Skip.
4683e457fe3SDavid van Moolenbroek                     continue;
4693e457fe3SDavid van Moolenbroek                 }
470b7725c85SDavid van Moolenbroek                 if(!fName.compare("brk")) {
4713e457fe3SDavid van Moolenbroek                     brkFunctions.insert(f);
4723e457fe3SDavid van Moolenbroek                 }
473b7725c85SDavid van Moolenbroek                 if(!fName.compare("sbrk")) {
4743e457fe3SDavid van Moolenbroek                     sbrkFunctions.insert(f);
4753e457fe3SDavid van Moolenbroek                 }
4763e457fe3SDavid van Moolenbroek                 bool isDeallocFunction = false;
477b7725c85SDavid van Moolenbroek                 for(unsigned k=0;magicMemDeallocFuncNames[k].compare("");k++) {
478b7725c85SDavid van Moolenbroek                     if(!magicMemDeallocFuncNames[k].compare(fName)) {
4793e457fe3SDavid van Moolenbroek                         isDeallocFunction = true;
4803e457fe3SDavid van Moolenbroek                         break;
4813e457fe3SDavid van Moolenbroek                     }
4823e457fe3SDavid van Moolenbroek                 }
483b7725c85SDavid van Moolenbroek                 bool makeNestedFunction = false;
484b7725c85SDavid van Moolenbroek                 for(unsigned k=0;magicMemNestedFuncNames[k].compare("");k++) {
485b7725c85SDavid van Moolenbroek                     if (!magicMemNestedFuncNames[k].compare(fName)) {
486b7725c85SDavid van Moolenbroek                         makeNestedFunction = true;
487b7725c85SDavid van Moolenbroek                         break;
488b7725c85SDavid van Moolenbroek                     }
489b7725c85SDavid van Moolenbroek                 }
490b7725c85SDavid van Moolenbroek 
491b7725c85SDavid van Moolenbroek                 Function* w = findWrapper(M, magicMemPrefixes, f, fName);
492b7725c85SDavid van Moolenbroek                 MagicMemFunction memFunction(M, f, w, isDeallocFunction, false, allocFlags);
4933e457fe3SDavid van Moolenbroek                 magicMemFunctions.push_back(memFunction);
494b7725c85SDavid van Moolenbroek                 if (makeNestedFunction) {
495b7725c85SDavid van Moolenbroek                     w = findWrapper(M, magicMemPrefixes, f, MAGIC_NESTED_PREFIX_STR + fName);
496b7725c85SDavid van Moolenbroek                     MagicMemFunction memFunction(M, f, w, isDeallocFunction, true, allocFlags);
497b7725c85SDavid van Moolenbroek                     magicMemFunctions.push_back(memFunction);
498b7725c85SDavid van Moolenbroek                 }
4993e457fe3SDavid van Moolenbroek                 originalMagicMemFunctions.insert(f);
5003e457fe3SDavid van Moolenbroek 
5013e457fe3SDavid van Moolenbroek #if DEBUG_ALLOC_LEVEL >= 1
5023e457fe3SDavid van Moolenbroek                 magicPassErr("Memory management function/wrapper found: " << f->getName() << "()/" << w->getName() << "()");
5033e457fe3SDavid van Moolenbroek #endif
5043e457fe3SDavid van Moolenbroek             }
5053e457fe3SDavid van Moolenbroek         }
5063e457fe3SDavid van Moolenbroek 
5073e457fe3SDavid van Moolenbroek         //look up custom memory management functions and build the corresponding wrappers
5083e457fe3SDavid van Moolenbroek         int stdAllocFlags = 0;
5093e457fe3SDavid van Moolenbroek         Function *stdAllocFunc, *stdAllocWrapperFunc;
5103e457fe3SDavid van Moolenbroek         stdAllocFunc = M.getFunction(MAGIC_MALLOC_FUNC_NAME);
5113e457fe3SDavid van Moolenbroek         assert(stdAllocFunc && "Could not find the standard allocation function.");
5123e457fe3SDavid van Moolenbroek         for(i=0;magicMemFuncNames[i].compare("");i++) {
5133e457fe3SDavid van Moolenbroek             if (!magicMemFuncNames[i].compare(MAGIC_MALLOC_FUNC_NAME)) {
5143e457fe3SDavid van Moolenbroek                 stdAllocFlags = magicMemFuncAllocFlags[i];
5153e457fe3SDavid van Moolenbroek                 break;
5163e457fe3SDavid van Moolenbroek             }
5173e457fe3SDavid van Moolenbroek         }
5183e457fe3SDavid van Moolenbroek         assert(magicMemFuncNames[i].compare("") && "Could not find the flags for the standard allocation function.");
5193e457fe3SDavid van Moolenbroek         std::string wName;
5203e457fe3SDavid van Moolenbroek         for(i=0;magicMemPrefixes[i].compare("");i++) {
5213e457fe3SDavid van Moolenbroek             wName = magicMemPrefixes[i] + MAGIC_MALLOC_FUNC_NAME;
5223e457fe3SDavid van Moolenbroek             stdAllocWrapperFunc = M.getFunction(wName);
5233e457fe3SDavid van Moolenbroek             if (stdAllocWrapperFunc) {
5243e457fe3SDavid van Moolenbroek                 break;
5253e457fe3SDavid van Moolenbroek             }
5263e457fe3SDavid van Moolenbroek         }
5273e457fe3SDavid van Moolenbroek         assert(stdAllocWrapperFunc && "Could not find a wrapper for the standard allocation function.");
5283e457fe3SDavid van Moolenbroek         for (std::set<std::pair<std::string, std::string> >::iterator it = mmFuncPairs.begin(); it != mmFuncPairs.end(); ++it) {
5293e457fe3SDavid van Moolenbroek 	    std::vector<std::string> allocTokens;
5303e457fe3SDavid van Moolenbroek 	    PassUtil::parseStringListOpt(allocTokens, (*it).first, "/");
5313e457fe3SDavid van Moolenbroek 		    assert((allocTokens.size() == stdAllocFunc->getFunctionType()->getNumParams() + 1) && "Bad option format, format is: customFuncName/stdFuncArg1Mapping/.../stdFuncArgNMapping");
5323e457fe3SDavid van Moolenbroek 
5333e457fe3SDavid van Moolenbroek 		    // build custom wrapper for the allocation function
5343e457fe3SDavid van Moolenbroek 		    Function *allocFunction = MagicUtil::getFunction(M, allocTokens[0]);
5353e457fe3SDavid van Moolenbroek 		    if (!allocFunction) {
5363e457fe3SDavid van Moolenbroek 			    continue;
5373e457fe3SDavid van Moolenbroek 		    }
5383e457fe3SDavid van Moolenbroek 		    std::vector<unsigned> allocArgMapping;
5393e457fe3SDavid van Moolenbroek 		    int param;
5403e457fe3SDavid van Moolenbroek 		    for (unsigned i = 0; i < stdAllocFunc->getFunctionType()->getNumParams(); i++) {
5413e457fe3SDavid van Moolenbroek 			    int ret = StringRef(allocTokens[i + 1]).getAsInteger(10, param);
5423e457fe3SDavid van Moolenbroek 			    assert(!ret && "Bad option format, format is: customFuncName/stdFuncArg1Mapping/.../stdFuncArgNMapping");
5433e457fe3SDavid van Moolenbroek 			    assert(param > 0 && "The numbering of function parameters starts from 1.");
5443e457fe3SDavid van Moolenbroek 			    allocArgMapping.push_back(param);
5453e457fe3SDavid van Moolenbroek 		    }
5463e457fe3SDavid van Moolenbroek 		    FunctionType *allocFuncType = getFunctionType(allocFunction->getFunctionType(), allocArgMapping);
5473e457fe3SDavid van Moolenbroek 		    if(!isCompatibleMagicMemFuncType(allocFuncType, stdAllocWrapperFunc->getFunctionType())) {
5483e457fe3SDavid van Moolenbroek 			    magicPassErr("Error: standard wrapper function " << stdAllocWrapperFunc->getName() << " has incompatible type.");
5493e457fe3SDavid van Moolenbroek 			    magicPassErr(TypeUtil::getDescription(allocFuncType, MAGIC_TYPE_STR_PRINT_MAX, MAGIC_TYPE_STR_PRINT_MAX_LEVEL) << " != " << TypeUtil::getDescription(stdAllocWrapperFunc->getFunctionType(), MAGIC_TYPE_STR_PRINT_MAX, MAGIC_TYPE_STR_PRINT_MAX_LEVEL));
5503e457fe3SDavid van Moolenbroek 			    exit(1);
5513e457fe3SDavid van Moolenbroek 		    }
5523e457fe3SDavid van Moolenbroek 		    Function *allocWrapper = MagicMemFunction::getCustomWrapper(allocFunction, stdAllocFunc, stdAllocWrapperFunc, allocArgMapping, false);
5533e457fe3SDavid van Moolenbroek 
5543e457fe3SDavid van Moolenbroek 		    // register the wrapper
555b7725c85SDavid van Moolenbroek 		    MagicMemFunction memFunctionAlloc(M, allocFunction, allocWrapper, false, false, stdAllocFlags);
5563e457fe3SDavid van Moolenbroek 		    magicMemFunctions.push_back(memFunctionAlloc);
5573e457fe3SDavid van Moolenbroek 		    originalMagicMemFunctions.insert(allocFunction);
5583e457fe3SDavid van Moolenbroek #if DEBUG_ALLOC_LEVEL >= 1
5593e457fe3SDavid van Moolenbroek             magicPassErr("Allocation function/custom wrapper added: " << allocFunction->getName() << "()/" << allocWrapper->getName() << "()");
5603e457fe3SDavid van Moolenbroek #endif
5613e457fe3SDavid van Moolenbroek         }
5623e457fe3SDavid van Moolenbroek 
5633e457fe3SDavid van Moolenbroek         //lookup memory pool management functions and add the corresponding wrapper calls
5643e457fe3SDavid van Moolenbroek         int mempoolAllocFlags = MAGIC_STATE_HEAP;
5653e457fe3SDavid van Moolenbroek 	    Function *mempoolBlockAllocTemplate, *mempoolBlockAllocTemplateWrapper;
5663e457fe3SDavid van Moolenbroek 	    mempoolBlockAllocTemplate = MagicUtil::getFunction(M,  MAGIC_MEMPOOL_BLOCK_ALLOC_TEMPLATE_FUNC_NAME);
5673e457fe3SDavid van Moolenbroek 	    assert(mempoolBlockAllocTemplate && "Could not find the pool block allocation template function.");
5683e457fe3SDavid van Moolenbroek 	    for(i = 0; magicMemPrefixes[i].compare(""); i++) {
5693e457fe3SDavid van Moolenbroek 		    wName = magicMemPrefixes[i] + MAGIC_MEMPOOL_BLOCK_ALLOC_TEMPLATE_FUNC_NAME;
5703e457fe3SDavid van Moolenbroek 		    mempoolBlockAllocTemplateWrapper = MagicUtil::getFunction(M, wName);
5713e457fe3SDavid van Moolenbroek 		    if (mempoolBlockAllocTemplateWrapper) {
5723e457fe3SDavid van Moolenbroek 			    break;
5733e457fe3SDavid van Moolenbroek 		    }
5743e457fe3SDavid van Moolenbroek 	    }
5753e457fe3SDavid van Moolenbroek 	    assert(mempoolBlockAllocTemplateWrapper && "Could not find a wrapper for the pool block allocation template function.");
5763e457fe3SDavid van Moolenbroek #define __X(P) #P
5773e457fe3SDavid van Moolenbroek         // C++11 Initializer Lists are not yet supported as of Clang 3.0 ...
5783e457fe3SDavid van Moolenbroek         std::pair<std::string, std::string> magicMempoolFuncNames[] = {
5793e457fe3SDavid van Moolenbroek 		    std::pair<std::string, std::string>(MAGIC_MEMPOOL_CREATE_FUNCS),
5803e457fe3SDavid van Moolenbroek 		    std::pair<std::string, std::string>(MAGIC_MEMPOOL_DESTROY_FUNCS),
5813e457fe3SDavid van Moolenbroek 		    std::pair<std::string, std::string>(MAGIC_MEMPOOL_MGMT_FUNCS),
5823e457fe3SDavid van Moolenbroek 		    std::pair<std::string, std::string>(MAGIC_MEMPOOL_RESET_FUNCS)
5833e457fe3SDavid van Moolenbroek         };
5843e457fe3SDavid van Moolenbroek #undef __X
5853e457fe3SDavid van Moolenbroek         int magicMempoolFuncFlags[] = { MAGIC_MEMPOOL_FUNC_FLAGS };
5863e457fe3SDavid van Moolenbroek         unsigned numMagicMempoolFuncPairs = sizeof(magicMempoolFuncNames) / sizeof(magicMempoolFuncNames[0]);
5873e457fe3SDavid van Moolenbroek         std::vector<std::pair<Function*, Function*> > magicMempoolFuncs(numMagicMempoolFuncPairs, std::pair<Function*, Function*>());
5883e457fe3SDavid van Moolenbroek         for (i = 0; i < numMagicMempoolFuncPairs; i++) {
5893e457fe3SDavid van Moolenbroek 	    magicMempoolFuncs[i].first = MagicUtil::getFunction(M, magicMempoolFuncNames[i].first);
5903e457fe3SDavid van Moolenbroek 	    if (!magicMempoolFuncs[i].first) {
5913e457fe3SDavid van Moolenbroek 			    magicPassErr("Could not find one of the memory pool wrapper functions: " + magicMempoolFuncNames[i].first);
5923e457fe3SDavid van Moolenbroek 			    exit(1);
5933e457fe3SDavid van Moolenbroek 		    }
5943e457fe3SDavid van Moolenbroek 	    magicMempoolFuncs[i].second = MagicUtil::getFunction(M, magicMempoolFuncNames[i].second);
5953e457fe3SDavid van Moolenbroek 	    if (!magicMempoolFuncs[i].second) {
5963e457fe3SDavid van Moolenbroek 			    magicPassErr("Could not find one of the memory pool wrapper functions: " + magicMempoolFuncNames[i].second);
5973e457fe3SDavid van Moolenbroek 			    exit(1);
5983e457fe3SDavid van Moolenbroek 		    }
5993e457fe3SDavid van Moolenbroek         }
6003e457fe3SDavid van Moolenbroek 
6013e457fe3SDavid van Moolenbroek         if (mmPoolFunctions.size()) {
6023e457fe3SDavid van Moolenbroek 		    assert(mmPoolFunctions.size() >= 3 && mmPoolFunctions.size() <= 5 &&
6033e457fe3SDavid van Moolenbroek 						    "Specify at least 3 and at most 5 of the pool management types of functions: block alloc,pool create,pool destroy,pool management functions,pool reset functions.");
6043e457fe3SDavid van Moolenbroek 		    std::vector<std::string>::iterator mmPoolFuncsIt = mmPoolFunctions.begin();
6053e457fe3SDavid van Moolenbroek 		    std::vector<MagicMemFunction> mempoolMagicMemFunctions;
6063e457fe3SDavid van Moolenbroek 
6073e457fe3SDavid van Moolenbroek 		    // memory pool block allocation functions
6083e457fe3SDavid van Moolenbroek 		    std::vector<std::string> mempoolBlockAllocFuncs;
6093e457fe3SDavid van Moolenbroek 		    PassUtil::parseStringListOpt(mempoolBlockAllocFuncs, *(mmPoolFuncsIt++), ";");
6103e457fe3SDavid van Moolenbroek 
6113e457fe3SDavid van Moolenbroek 		    for (std::vector<std::string>::iterator funcIt = mempoolBlockAllocFuncs.begin(); funcIt != mempoolBlockAllocFuncs.end(); ++funcIt) {
6123e457fe3SDavid van Moolenbroek 			    std::vector<std::string> funcTokens;
6133e457fe3SDavid van Moolenbroek 			    PassUtil::parseStringListOpt(funcTokens, *funcIt, "/");
6143e457fe3SDavid van Moolenbroek 			    assert(funcTokens.size() == 3 && "Bad option format, format is: block_alloc_func/pool_ptr_arg_number/size_arg_number");
6153e457fe3SDavid van Moolenbroek 			    Function* blockAllocFunc = MagicUtil::getFunction(M, funcTokens[0]);
6163e457fe3SDavid van Moolenbroek 			    if (!blockAllocFunc) {
6173e457fe3SDavid van Moolenbroek 			        magicPassErr("Memory pool block allocation function not found - " + funcTokens[0] + ". Skipping instrumentation!");
6183e457fe3SDavid van Moolenbroek 			        mempoolMagicMemFunctions.clear();
6193e457fe3SDavid van Moolenbroek 			        break;
6203e457fe3SDavid van Moolenbroek 			    }
6213e457fe3SDavid van Moolenbroek 			    std::vector<unsigned> argMapping;
6223e457fe3SDavid van Moolenbroek 			    unsigned param;
6233e457fe3SDavid van Moolenbroek 			    for (unsigned i = 1; i < funcTokens.size(); i++) {
6243e457fe3SDavid van Moolenbroek 				    assert(!StringRef(funcTokens[i]).getAsInteger(10, param) && "Bad option format, format is: block_alloc_func/pool_ptr_arg_number/size_arg_number");
6253e457fe3SDavid van Moolenbroek 				    assert(param > 0 && param <= blockAllocFunc->getFunctionType()->getNumParams()
6263e457fe3SDavid van Moolenbroek 						    && "Bad option format. The function parameter number is not valid.");
6273e457fe3SDavid van Moolenbroek 				    argMapping.push_back(param);
6283e457fe3SDavid van Moolenbroek 			    }
6293e457fe3SDavid van Moolenbroek 			    FunctionType *blockAllocFuncType = getFunctionType(mempoolBlockAllocTemplate->getFunctionType(), argMapping);
6303e457fe3SDavid van Moolenbroek 			    if(!isCompatibleMagicMemFuncType(blockAllocFuncType, mempoolBlockAllocTemplateWrapper->getFunctionType())) {
6313e457fe3SDavid van Moolenbroek 				    magicPassErr("Error: standard wrapper function " << mempoolBlockAllocTemplateWrapper->getName() << " has incompatible type.");
6323e457fe3SDavid van Moolenbroek 				    magicPassErr(TypeUtil::getDescription(blockAllocFuncType, MAGIC_TYPE_STR_PRINT_MAX, MAGIC_TYPE_STR_PRINT_MAX_LEVEL) << " != " << TypeUtil::getDescription(mempoolBlockAllocTemplateWrapper->getFunctionType(), MAGIC_TYPE_STR_PRINT_MAX, MAGIC_TYPE_STR_PRINT_MAX_LEVEL));
6333e457fe3SDavid van Moolenbroek 				    exit(1);
6343e457fe3SDavid van Moolenbroek 			    }
6353e457fe3SDavid van Moolenbroek 			    Function *blockAllocWrapper = MagicMemFunction::getCustomWrapper(blockAllocFunc, mempoolBlockAllocTemplate, mempoolBlockAllocTemplateWrapper, argMapping, false);
636b7725c85SDavid van Moolenbroek 			    MagicMemFunction memFunctionBlockAlloc(M, blockAllocFunc, blockAllocWrapper, false, false, mempoolAllocFlags);
6373e457fe3SDavid van Moolenbroek 			    mempoolMagicMemFunctions.push_back(memFunctionBlockAlloc);
6383e457fe3SDavid van Moolenbroek 		    }
6393e457fe3SDavid van Moolenbroek 		    if (!mempoolMagicMemFunctions.empty()) { // only if the block allocation functions have been successfully processed
6403e457fe3SDavid van Moolenbroek 			    // continue with the rest of the memory pool management functions, which do not require a magic wrapper
6413e457fe3SDavid van Moolenbroek 			    std::vector<std::vector<Function*> >::iterator magicMempoolFuncIt;
6423e457fe3SDavid van Moolenbroek 			    std::vector<std::vector<int> >::iterator magicMempoolFuncFlagsIt;
6433e457fe3SDavid van Moolenbroek 			    for (unsigned magicMempoolFuncIndex = 1; mmPoolFuncsIt != mmPoolFunctions.end(); ++mmPoolFuncsIt, ++magicMempoolFuncIndex) {
6443e457fe3SDavid van Moolenbroek 				    std::vector<std::string> mempoolMgmtFuncs;
6453e457fe3SDavid van Moolenbroek 				    PassUtil::parseStringListOpt(mempoolMgmtFuncs, *mmPoolFuncsIt, ";");
6463e457fe3SDavid van Moolenbroek 				    for (std::vector<std::string>::iterator funcIt = mempoolMgmtFuncs.begin(); funcIt != mempoolMgmtFuncs.end(); ++funcIt) {
6473e457fe3SDavid van Moolenbroek 					    std::vector<std::string> funcTokens;
6483e457fe3SDavid van Moolenbroek 					    PassUtil::parseStringListOpt(funcTokens, *funcIt, "/");
6493e457fe3SDavid van Moolenbroek 					    assert(funcTokens.size() == 2 && "Bad option format, format is: mempool_mgmt_func/pool_ptr_arg_number");
6503e457fe3SDavid van Moolenbroek 					    Function* mempoolMgmtFunc = MagicUtil::getFunction(M, funcTokens[0]);
6513e457fe3SDavid van Moolenbroek 					    assert(mempoolMgmtFunc && "Bad memory pool configuration, instrumentation aborted!");
6523e457fe3SDavid van Moolenbroek 					    std::vector<unsigned> argMapping;
6533e457fe3SDavid van Moolenbroek 					    unsigned param;
6543e457fe3SDavid van Moolenbroek 					    for (unsigned i = 1; i < funcTokens.size(); i++) {
6553e457fe3SDavid van Moolenbroek 						    assert(!StringRef(funcTokens[i]).getAsInteger(10, param) && "Bad option format, format is: mempool_mgmt_func/pool_ptr_arg_number");
6563e457fe3SDavid van Moolenbroek 						    assert(param <= mempoolMgmtFunc->getFunctionType()->getNumParams() &&
6573e457fe3SDavid van Moolenbroek 								    "Bad option format. The function parameter number is not valid.");
6583e457fe3SDavid van Moolenbroek 						    argMapping.push_back(param);
6593e457fe3SDavid van Moolenbroek 					    }
6603e457fe3SDavid van Moolenbroek 					    std::vector<Value*> trailingArgs;
6613e457fe3SDavid van Moolenbroek 					    if (magicMempoolFuncIndex == 1) { // pool create funcs
6623e457fe3SDavid van Moolenbroek 						    TYPECONST Type* poolType = mempoolMgmtFunc->getFunctionType()->getContainedType(argMapping[0]);
6633e457fe3SDavid van Moolenbroek 						    int level = MagicUtil::getPointerIndirectionLevel(poolType);
6643e457fe3SDavid van Moolenbroek 						    trailingArgs.push_back(ConstantInt::get(Type::getInt32Ty(M.getContext()), (level > 1)));
6653e457fe3SDavid van Moolenbroek 					    } else if (magicMempoolFuncIndex == 2) { // pool destroy funcs
6663e457fe3SDavid van Moolenbroek 						    trailingArgs.push_back(ConstantInt::get(Type::getInt32Ty(M.getContext()), (EnablePoolMemReuse ? 1 : 0)));
6673e457fe3SDavid van Moolenbroek 					    }
6683e457fe3SDavid van Moolenbroek 					    if (magicMempoolFuncFlags[magicMempoolFuncIndex - 1] & MAGIC_HOOK_DEBUG_MASK) {
6693e457fe3SDavid van Moolenbroek 						    MagicDebugFunction magicDebugFunction(mempoolMgmtFunc);
6703e457fe3SDavid van Moolenbroek 						    magicDebugFunction.addHooks(magicMempoolFuncs[magicMempoolFuncIndex - 1], magicMempoolFuncFlags[magicMempoolFuncIndex - 1], argMapping, trailingArgs);
6713e457fe3SDavid van Moolenbroek 						    magicDebugFunctions.push_back(magicDebugFunction);
6723e457fe3SDavid van Moolenbroek 					    } else {
6733e457fe3SDavid van Moolenbroek 						    bool ret = MagicDebugFunction::inlineHookCalls(mempoolMgmtFunc,
6743e457fe3SDavid van Moolenbroek 								    magicMempoolFuncs[magicMempoolFuncIndex - 1], magicMempoolFuncFlags[magicMempoolFuncIndex - 1], argMapping, trailingArgs);
6753e457fe3SDavid van Moolenbroek 						    if (!ret) {
6763e457fe3SDavid van Moolenbroek 							    magicPassErr("Unable to inline wrapper function calls for " + funcTokens[0]);
6773e457fe3SDavid van Moolenbroek 							    exit(1);
6783e457fe3SDavid van Moolenbroek 						    }
6793e457fe3SDavid van Moolenbroek 					    }
6803e457fe3SDavid van Moolenbroek 				    }
6813e457fe3SDavid van Moolenbroek 			    }
6823e457fe3SDavid van Moolenbroek 			    for (std::vector<MagicMemFunction>::iterator magicIt = mempoolMagicMemFunctions.begin(); magicIt != mempoolMagicMemFunctions.end(); ++magicIt) {
6833e457fe3SDavid van Moolenbroek 				    magicMemFunctions.push_back(*magicIt);
6843e457fe3SDavid van Moolenbroek 				    originalMagicMemFunctions.insert(magicIt->getFunction());
6853e457fe3SDavid van Moolenbroek 			    }
6863e457fe3SDavid van Moolenbroek 		    }
6873e457fe3SDavid van Moolenbroek         }
6883e457fe3SDavid van Moolenbroek 
6893e457fe3SDavid van Moolenbroek         //lookup mmap ctl functions whose call arguments need to be fixed
6903e457fe3SDavid van Moolenbroek         for (std::vector<std::string>::iterator it = mmapCtlFunctions.begin(); it != mmapCtlFunctions.end(); ++it) {
6913e457fe3SDavid van Moolenbroek             std::vector<std::string> tokens;
6923e457fe3SDavid van Moolenbroek             tokens.clear();
6933e457fe3SDavid van Moolenbroek             PassUtil::parseStringListOpt(tokens, *it, "/");
6943e457fe3SDavid van Moolenbroek             assert(tokens.size() == 3 && "Bad option format, format is: function/[ptr_arg_name]/[len_arg_name]");
6953e457fe3SDavid van Moolenbroek 
6963e457fe3SDavid van Moolenbroek             Function *function = M.getFunction(tokens[0]);
6973e457fe3SDavid van Moolenbroek             if(!function) {
6983e457fe3SDavid van Moolenbroek                 continue;
6993e457fe3SDavid van Moolenbroek             }
7003e457fe3SDavid van Moolenbroek             std::string &ptrArgName = tokens[1];
7013e457fe3SDavid van Moolenbroek             std::string &lenArgName = tokens[2];
7023e457fe3SDavid van Moolenbroek             MagicMmapCtlFunction magicMmapCtlFunction(function, PointerType::get(IntegerType::get(M.getContext(), 8), 0), ptrArgName, lenArgName);
7033e457fe3SDavid van Moolenbroek             magicMmapCtlFunctions.push_back(magicMmapCtlFunction);
7043e457fe3SDavid van Moolenbroek         }
70576b68f9fSDavid van Moolenbroek     }
70676b68f9fSDavid van Moolenbroek #endif /*MAGIC_INSTRUMENT_MEM_FUNCS*/
7073e457fe3SDavid van Moolenbroek 
7083e457fe3SDavid van Moolenbroek     //everything as expected, set magic enabled variable to TRUE
7093e457fe3SDavid van Moolenbroek     magicEnabled->setInitializer(ConstantInt::get(M.getContext(), APInt(32, 1)));
7103e457fe3SDavid van Moolenbroek 
7113e457fe3SDavid van Moolenbroek     //scan the list of global variables
7123e457fe3SDavid van Moolenbroek     unsigned strGlobalVariables = 0;
7133e457fe3SDavid van Moolenbroek     unsigned constGlobalVariables = 0;
7143e457fe3SDavid van Moolenbroek     for (Module::global_iterator it = globalList.begin(); it != globalList.end(); ++it) {
7153e457fe3SDavid van Moolenbroek         GlobalVariable *GV = it;
7163e457fe3SDavid van Moolenbroek         StringRef GVName = GV->getName();
7173e457fe3SDavid van Moolenbroek         TYPECONST Type *GVType = GV->getType()->getElementType();
7183e457fe3SDavid van Moolenbroek         bool isPrimitiveOrPointerType = !GVType->isAggregateType();
7193e457fe3SDavid van Moolenbroek         DATA_LAYOUT_TY DL = DATA_LAYOUT_TY(&M);
7203e457fe3SDavid van Moolenbroek         bool isExternal = GV->hasExternalLinkage() || GV->hasExternalWeakLinkage();
7213e457fe3SDavid van Moolenbroek         int typeSize = isExternal ? 0 : DL.getTypeSizeInBits(GVType)/8;
7223e457fe3SDavid van Moolenbroek         int align = MAGIC_FORCE_ALIGN;
7233e457fe3SDavid van Moolenbroek 
7243e457fe3SDavid van Moolenbroek         if(isMagicGV(M, GV)) {
7253e457fe3SDavid van Moolenbroek             magicPassLog("Skipping magic variable: " << GVName);
7263e457fe3SDavid van Moolenbroek             continue;
7273e457fe3SDavid van Moolenbroek         }
7283e457fe3SDavid van Moolenbroek         assert(!MAGIC_STRINGREF_HAS_MAGIC_HIDDEN_PREFIX(GVName));
7293e457fe3SDavid van Moolenbroek         if(GVName.startswith("C.")) {
7303e457fe3SDavid van Moolenbroek             //LLVM code we are not interested in
7313e457fe3SDavid van Moolenbroek             continue;
7323e457fe3SDavid van Moolenbroek         }
7333e457fe3SDavid van Moolenbroek         if(MagicUtil::isLocalConstant(M, GV)) {
7343e457fe3SDavid van Moolenbroek             //Local constants we are not interested in
7353e457fe3SDavid van Moolenbroek             continue;
7363e457fe3SDavid van Moolenbroek         }
7373e457fe3SDavid van Moolenbroek #if GLOBAL_VARS_IN_SECTION
7383e457fe3SDavid van Moolenbroek         MagicUtil::setGlobalVariableSection(GV, GV->isConstant() ? GLOBAL_VARS_SECTION_RO : GLOBAL_VARS_SECTION_DATA);
7393e457fe3SDavid van Moolenbroek #endif
7403e457fe3SDavid van Moolenbroek         if(GVName.startswith(".str")) {
7413e457fe3SDavid van Moolenbroek             assert(GV->hasInitializer());
7423e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 31
7433e457fe3SDavid van Moolenbroek             /* XXX Check. */
7443e457fe3SDavid van Moolenbroek             ConstantDataArray *initializer = dyn_cast<ConstantDataArray>(GV->getInitializer());
7453e457fe3SDavid van Moolenbroek #else
7463e457fe3SDavid van Moolenbroek             ConstantArray *initializer = dyn_cast<ConstantArray>(GV->getInitializer());
7473e457fe3SDavid van Moolenbroek #endif
7483e457fe3SDavid van Moolenbroek             if(initializer) {
7493e457fe3SDavid van Moolenbroek                 assert(initializer->isString());
7503e457fe3SDavid van Moolenbroek                 MagicUtil::putStringRefCache(M, initializer->getAsString(), GV);
7513e457fe3SDavid van Moolenbroek             }
7523e457fe3SDavid van Moolenbroek             else {
7533e457fe3SDavid van Moolenbroek                 MagicUtil::putStringRefCache(M, "", GV);
7543e457fe3SDavid van Moolenbroek             }
7553e457fe3SDavid van Moolenbroek 
7563e457fe3SDavid van Moolenbroek             strGlobalVariables++;
7573e457fe3SDavid van Moolenbroek             Value *stringOwner = MagicUtil::getStringOwner(GV);
7583e457fe3SDavid van Moolenbroek             if(stringOwner) {
7593e457fe3SDavid van Moolenbroek                 GlobalVariable *GVOwner = dyn_cast<GlobalVariable>(stringOwner);
7603e457fe3SDavid van Moolenbroek                 AllocaInst *AIOwner = dyn_cast<AllocaInst>(stringOwner);
7613e457fe3SDavid van Moolenbroek                 assert(GVOwner || AIOwner);
7623e457fe3SDavid van Moolenbroek                 bool stringOwnerFound = false;
7633e457fe3SDavid van Moolenbroek                 std::string ownerName;
7643e457fe3SDavid van Moolenbroek                 raw_string_ostream ostream(ownerName);
7653e457fe3SDavid van Moolenbroek                 if(GVOwner && !isMagicGV(M, GVOwner)) {
7663e457fe3SDavid van Moolenbroek                     ostream << "#" << MagicUtil::getGVSourceName(M, GVOwner, NULL, baseBuildDir);
7673e457fe3SDavid van Moolenbroek                     stringOwnerFound = true;
7683e457fe3SDavid van Moolenbroek                 }
7693e457fe3SDavid van Moolenbroek                 else if(AIOwner && !isMagicFunction(M, AIOwner->getParent()->getParent())) {
7703e457fe3SDavid van Moolenbroek                     ostream << MagicUtil::getFunctionSourceName(M, AIOwner->getParent()->getParent(), NULL, baseBuildDir) << "#" << MagicUtil::getLVSourceName(M, AIOwner);
7713e457fe3SDavid van Moolenbroek                     stringOwnerFound = true;
7723e457fe3SDavid van Moolenbroek                 }
7733e457fe3SDavid van Moolenbroek                 if(stringOwnerFound) {
7743e457fe3SDavid van Moolenbroek                     ostream.flush();
7753e457fe3SDavid van Moolenbroek                     stringOwnerMapIt = stringOwnerMap.find(ownerName);
7763e457fe3SDavid van Moolenbroek                     if(stringOwnerMapIt == stringOwnerMap.end()) {
7773e457fe3SDavid van Moolenbroek                         stringOwnerMap.insert(std::pair<std::string, GlobalVariable*>(ownerName, GV));
7783e457fe3SDavid van Moolenbroek                         stringOwnerInvertedMap.insert(std::pair<GlobalVariable*, std::string>(GV, ownerName));
7793e457fe3SDavid van Moolenbroek                     }
7803e457fe3SDavid van Moolenbroek                     else {
7813e457fe3SDavid van Moolenbroek                         stringOwnerInvertedMapIt = stringOwnerInvertedMap.find(stringOwnerMapIt->second);
7823e457fe3SDavid van Moolenbroek                         if(stringOwnerInvertedMapIt != stringOwnerInvertedMap.end()) {
7833e457fe3SDavid van Moolenbroek                             stringOwnerInvertedMap.erase(stringOwnerInvertedMapIt);
7843e457fe3SDavid van Moolenbroek                         }
7853e457fe3SDavid van Moolenbroek                     }
7863e457fe3SDavid van Moolenbroek                 }
7873e457fe3SDavid van Moolenbroek             }
7883e457fe3SDavid van Moolenbroek         }
7893e457fe3SDavid van Moolenbroek         else if(GV->isConstant()) {
7903e457fe3SDavid van Moolenbroek             constGlobalVariables++;
7913e457fe3SDavid van Moolenbroek         }
7923e457fe3SDavid van Moolenbroek         if(!isPrimitiveOrPointerType && align) {
7933e457fe3SDavid van Moolenbroek             GV->setAlignment(align);
7943e457fe3SDavid van Moolenbroek             if(typeSize % align) {
7953e457fe3SDavid van Moolenbroek                 typeSize = typeSize - (typeSize % align) + align;
7963e457fe3SDavid van Moolenbroek             }
7973e457fe3SDavid van Moolenbroek         }
7983e457fe3SDavid van Moolenbroek         else if(MAGIC_OFF_BY_N_PROTECTION_N && GVType->isArrayTy() && typeSize>0) {
7993e457fe3SDavid van Moolenbroek             unsigned alignment = typeSize + (DL.getTypeSizeInBits(GVType->getContainedType(0))/8) * MAGIC_OFF_BY_N_PROTECTION_N;
8003e457fe3SDavid van Moolenbroek             unsigned a = 2;
8013e457fe3SDavid van Moolenbroek             while(a < alignment) a = a << 1;
8023e457fe3SDavid van Moolenbroek             GV->setAlignment(a);
8033e457fe3SDavid van Moolenbroek         }
8043e457fe3SDavid van Moolenbroek         globalVariableSizes.push_back(typeSize);
8053e457fe3SDavid van Moolenbroek         globalVariables.push_back(GV);
8063e457fe3SDavid van Moolenbroek         if(MagicUtil::hasAddressTaken(GV)) {
8073e457fe3SDavid van Moolenbroek             globalVariablesWithAddressTaken.insert(GV);
8083e457fe3SDavid van Moolenbroek         }
8093e457fe3SDavid van Moolenbroek     }
8103e457fe3SDavid van Moolenbroek     magicPassLog(">>>> Number of global variables found: " << globalVariables.size() << " of which " << strGlobalVariables << " .str variables, " << constGlobalVariables << " constants, and " << globalVariables.size()-strGlobalVariables-constGlobalVariables << " regular variables");
8113e457fe3SDavid van Moolenbroek 
8123e457fe3SDavid van Moolenbroek     //build the list of functions having their address taken (include the last function no matter what to get the function ranges right)
8133e457fe3SDavid van Moolenbroek     std::vector<const SmartType *> functionTypes;
8143e457fe3SDavid van Moolenbroek     std::vector<GlobalValue *> functionTypeParents;
8153e457fe3SDavid van Moolenbroek     std::vector<TYPECONST FunctionType *> externalFunctionTypes;
8163e457fe3SDavid van Moolenbroek     std::vector<GlobalValue *> externalFunctionTypeParents;
8173e457fe3SDavid van Moolenbroek     for (Module::iterator it = functionList.begin(); it != functionList.end(); ++it) {
8183e457fe3SDavid van Moolenbroek         Function *F = it;
8193e457fe3SDavid van Moolenbroek         if(F->hasAddressTaken() || it == --functionList.end() || F->getName().startswith(MAGIC_EVAL_FUNC_PREFIX)) {
8203e457fe3SDavid van Moolenbroek             if(isMagicFunction(M, F)) {
8213e457fe3SDavid van Moolenbroek                 continue;
8223e457fe3SDavid van Moolenbroek             }
8233e457fe3SDavid van Moolenbroek             functions.push_back(F);
8243e457fe3SDavid van Moolenbroek             const SmartType *FSmartType = SmartType::getSmartTypeFromFunction(M, F);
8253e457fe3SDavid van Moolenbroek             if(FSmartType && !FSmartType->isTypeConsistent()) {
8263e457fe3SDavid van Moolenbroek                 delete FSmartType;
8273e457fe3SDavid van Moolenbroek                 //pretend the function is external if an invalid type has been found.
8283e457fe3SDavid van Moolenbroek                 FSmartType = NULL;
8293e457fe3SDavid van Moolenbroek             }
8303e457fe3SDavid van Moolenbroek             if(!FSmartType) {
8313e457fe3SDavid van Moolenbroek                 externalFunctionTypes.push_back(F->getFunctionType());
8323e457fe3SDavid van Moolenbroek                 externalFunctionTypeParents.push_back(F);
8333e457fe3SDavid van Moolenbroek             }
8343e457fe3SDavid van Moolenbroek             else {
8353e457fe3SDavid van Moolenbroek                 functionTypes.push_back(FSmartType);
8363e457fe3SDavid van Moolenbroek                 functionTypeParents.push_back(F);
8373e457fe3SDavid van Moolenbroek             }
8383e457fe3SDavid van Moolenbroek         }
8393e457fe3SDavid van Moolenbroek     }
8403e457fe3SDavid van Moolenbroek     magicPassLog(">>>> Number of functions with address taken found: " << functions.size() << ", of which " << functionTypes.size() << " internal and " << externalFunctionTypes.size() << " external...");
8413e457fe3SDavid van Moolenbroek 
8423e457fe3SDavid van Moolenbroek     //build the list of global types
8433e457fe3SDavid van Moolenbroek     std::vector<const SmartType *> smartTypes;
8443e457fe3SDavid van Moolenbroek     std::vector<GlobalValue *> smartTypeParents;
8453e457fe3SDavid van Moolenbroek     std::vector<TYPECONST Type *> externalTypes;
8463e457fe3SDavid van Moolenbroek     std::vector<GlobalValue *> externalTypeParents;
8473e457fe3SDavid van Moolenbroek     for(i=0;i<globalVariables.size();i++) {
8483e457fe3SDavid van Moolenbroek         GlobalVariable *GV = globalVariables[i];
8493e457fe3SDavid van Moolenbroek         TYPECONST Type* GVType = GV->getType()->getElementType();
8503e457fe3SDavid van Moolenbroek 
8513e457fe3SDavid van Moolenbroek         const SmartType *GVSmartType = SmartType::getSmartTypeFromGV(M, GV);
8523e457fe3SDavid van Moolenbroek 
8533e457fe3SDavid van Moolenbroek         if(!GV->hasAppendingLinkage()){
8543e457fe3SDavid van Moolenbroek             // llvm.global_ctors and llvm.global_dtors have appending linkage, don't have compile unit debug info, and therefore cannot be linked to GV debug info, and so are skipped.
8553e457fe3SDavid van Moolenbroek             if(!GVSmartType) {
8563e457fe3SDavid van Moolenbroek 		bool isExternal = GV->hasExternalLinkage() || GV->hasExternalWeakLinkage();
8573e457fe3SDavid van Moolenbroek                 if (!isExternal && !GV->isConstant()) {
8583e457fe3SDavid van Moolenbroek                     magicPassErr("var is: " << GV->getName());
8593e457fe3SDavid van Moolenbroek                     magicPassErr("type is: " << TypeUtil::getDescription(GV->getType()->getElementType(), MAGIC_TYPE_STR_PRINT_MAX, MAGIC_TYPE_STR_PRINT_MAX_LEVEL));
8603e457fe3SDavid van Moolenbroek             	}
8613e457fe3SDavid van Moolenbroek                 assert(isExternal || GV->isConstant());
8623e457fe3SDavid van Moolenbroek                 externalTypes.push_back(GVType);
8633e457fe3SDavid van Moolenbroek                 externalTypeParents.push_back(GV);
8643e457fe3SDavid van Moolenbroek             }
8653e457fe3SDavid van Moolenbroek             else {
8663e457fe3SDavid van Moolenbroek                 smartTypes.push_back(GVSmartType);
8673e457fe3SDavid van Moolenbroek                 smartTypeParents.push_back(GV);
8683e457fe3SDavid van Moolenbroek             }
8693e457fe3SDavid van Moolenbroek         }
8703e457fe3SDavid van Moolenbroek     }
8713e457fe3SDavid van Moolenbroek     magicPassLog(">>>> Number of global types found: " << globalVariables.size() << ", of which " << smartTypes.size() << " internal and " << externalTypes.size() << " external...");
8723e457fe3SDavid van Moolenbroek 
8733e457fe3SDavid van Moolenbroek     //build type infos
8743e457fe3SDavid van Moolenbroek     TypeInfo* magicVoidPtrTypeInfo = NULL;
8753e457fe3SDavid van Moolenbroek     TypeInfo* magicVoidArrTypeInfo = NULL;
8763e457fe3SDavid van Moolenbroek     TypeInfo* magicVoidTypeInfo = NULL;
8773e457fe3SDavid van Moolenbroek     for(i=0;i<smartTypes.size();i++) {
8783e457fe3SDavid van Moolenbroek         TypeInfo sourceTypeInfo(smartTypes[i]);
8793e457fe3SDavid van Moolenbroek         sourceTypeInfo.addParent(smartTypeParents[i]);
8803e457fe3SDavid van Moolenbroek         TypeInfo *aTypeInfo = fillTypeInfos(sourceTypeInfo, globalTypeInfos);
8813e457fe3SDavid van Moolenbroek         if(smartTypeParents[i] == magicVoidPtr) {
8823e457fe3SDavid van Moolenbroek             //get a pointer to void and void* types
8833e457fe3SDavid van Moolenbroek             magicVoidPtrTypeInfo = aTypeInfo;
8843e457fe3SDavid van Moolenbroek             assert(magicVoidPtrTypeInfo->getTypeID() == MAGIC_TYPE_POINTER);
8853e457fe3SDavid van Moolenbroek             magicVoidTypeInfo = magicVoidPtrTypeInfo->getContainedType(0);
8863e457fe3SDavid van Moolenbroek             assert(magicVoidTypeInfo->getTypeID() == MAGIC_TYPE_VOID);
8873e457fe3SDavid van Moolenbroek         }
8883e457fe3SDavid van Moolenbroek         else if(smartTypeParents[i] == magicVoidArr) {
8893e457fe3SDavid van Moolenbroek             //get a pointer to void array types
8903e457fe3SDavid van Moolenbroek             magicVoidArrTypeInfo = aTypeInfo;
8913e457fe3SDavid van Moolenbroek             assert(magicVoidArrTypeInfo->getTypeID() == MAGIC_TYPE_ARRAY);
8923e457fe3SDavid van Moolenbroek         }
8933e457fe3SDavid van Moolenbroek     }
8943e457fe3SDavid van Moolenbroek     assert(magicVoidPtrTypeInfo && magicVoidTypeInfo && magicVoidArrTypeInfo);
8953e457fe3SDavid van Moolenbroek     std::vector<TypeInfo*> magicVoidTypeInfoArr;
8963e457fe3SDavid van Moolenbroek     magicVoidTypeInfoArr.push_back(magicVoidTypeInfo);
8973e457fe3SDavid van Moolenbroek     magicVoidArrTypeInfo->setContainedTypes(magicVoidTypeInfoArr);
8983e457fe3SDavid van Moolenbroek     magicPassLog(">>>> Number of types found: " << globalTypeInfos.size());
8993e457fe3SDavid van Moolenbroek     for(i=0;i<functionTypes.size();i++) {
9003e457fe3SDavid van Moolenbroek         TypeInfo sourceTypeInfo(functionTypes[i]);
9013e457fe3SDavid van Moolenbroek         sourceTypeInfo.addParent(functionTypeParents[i]);
9023e457fe3SDavid van Moolenbroek         fillTypeInfos(sourceTypeInfo, globalTypeInfos);
9033e457fe3SDavid van Moolenbroek     }
9043e457fe3SDavid van Moolenbroek     magicPassLog(">>>> Number of types + function types found: " << globalTypeInfos.size());
9053e457fe3SDavid van Moolenbroek 
9063e457fe3SDavid van Moolenbroek     //add external function types
9073e457fe3SDavid van Moolenbroek     for(i=0;i<externalFunctionTypes.size();i++) {
9083e457fe3SDavid van Moolenbroek         TypeInfo sourceTypeInfo(externalFunctionTypes[i]);
9093e457fe3SDavid van Moolenbroek         sourceTypeInfo.addParent(externalFunctionTypeParents[i]);
9103e457fe3SDavid van Moolenbroek         fillTypeInfos(sourceTypeInfo, globalTypeInfos);
9113e457fe3SDavid van Moolenbroek     }
9123e457fe3SDavid van Moolenbroek     magicPassLog(">>>> Number of types + function types + external function types found: " << globalTypeInfos.size());
9133e457fe3SDavid van Moolenbroek 
9143e457fe3SDavid van Moolenbroek     //add external variable types
9153e457fe3SDavid van Moolenbroek     for(i=0;i<externalTypes.size();i++) {
9163e457fe3SDavid van Moolenbroek         TypeInfo* aTypeInfo = fillExternalTypeInfos(externalTypes[i], externalTypeParents[i], globalTypeInfos);
9173e457fe3SDavid van Moolenbroek         if(aTypeInfo == NULL) {
9183e457fe3SDavid van Moolenbroek             magicPassErr("var is: " << externalTypeParents[i]->getName());
9193e457fe3SDavid van Moolenbroek             magicPassErr("type is: " << TypeUtil::getDescription(externalTypes[i], MAGIC_TYPE_STR_PRINT_MAX, MAGIC_TYPE_STR_PRINT_MAX_LEVEL));
9203e457fe3SDavid van Moolenbroek         }
9213e457fe3SDavid van Moolenbroek         assert(aTypeInfo != NULL && "External type not supported!");
9223e457fe3SDavid van Moolenbroek     }
9233e457fe3SDavid van Moolenbroek     magicPassLog(">>>> Number of types + external types + function types + external function types found: " << globalTypeInfos.size());
9243e457fe3SDavid van Moolenbroek 
9253e457fe3SDavid van Moolenbroek     //process types, split them when some parent has a valid value set
9263e457fe3SDavid van Moolenbroek     std::vector<TypeInfo*> splitTypeInfos;
9273e457fe3SDavid van Moolenbroek     for(i=0;i<globalTypeInfos.size();i++) {
9283e457fe3SDavid van Moolenbroek         bool isTypeInfoSplit = globalTypeInfos[i]->splitByParentValueSet(splitTypeInfos, globalVariablesWithAddressTaken);
9293e457fe3SDavid van Moolenbroek         if(isTypeInfoSplit) {
9303e457fe3SDavid van Moolenbroek #if DEBUG_VALUE_SET
9313e457fe3SDavid van Moolenbroek             unsigned splitTypeInfosSize = splitTypeInfos.size();
9323e457fe3SDavid van Moolenbroek             errs() << "MagicPass: Found type info split with different parents and value sets: original type is: " << globalTypeInfos[i]->getDescription() << ", type splits are:\n";
9333e457fe3SDavid van Moolenbroek             for(unsigned j=splitTypeInfosSize;j<splitTypeInfos.size();j++) {
9343e457fe3SDavid van Moolenbroek                 errs() << " - value set is: [ ";
9353e457fe3SDavid van Moolenbroek                 std::vector<int> valueSet = splitTypeInfos[j]->getValueSet();
9363e457fe3SDavid van Moolenbroek                 for(unsigned k=1;k<valueSet.size();k++) {
9373e457fe3SDavid van Moolenbroek                     errs() << (k==1 ? "" : ", ") << valueSet[k];
9383e457fe3SDavid van Moolenbroek                 }
9393e457fe3SDavid van Moolenbroek                 errs() << " ], parents are: [ ";
9403e457fe3SDavid van Moolenbroek                 std::vector<GlobalValue*> parents = splitTypeInfos[j]->getParents();
9413e457fe3SDavid van Moolenbroek                 for(unsigned k=0;k<parents.size();k++) {
9423e457fe3SDavid van Moolenbroek                     errs() << (k==0 ? "" : ", ") << parents[k]->getName();
9433e457fe3SDavid van Moolenbroek                 }
9443e457fe3SDavid van Moolenbroek                 errs() << " ]\n";
9453e457fe3SDavid van Moolenbroek             }
9463e457fe3SDavid van Moolenbroek #endif
9473e457fe3SDavid van Moolenbroek         }
9483e457fe3SDavid van Moolenbroek     }
9493e457fe3SDavid van Moolenbroek 
9503e457fe3SDavid van Moolenbroek     //index type parents
9513e457fe3SDavid van Moolenbroek     globalTypeInfos.clear();
9523e457fe3SDavid van Moolenbroek     for(i=0;i<splitTypeInfos.size();i++) {
9533e457fe3SDavid van Moolenbroek         TypeInfo *aTypeInfo = splitTypeInfos[i];
9543e457fe3SDavid van Moolenbroek         std::vector<GlobalValue*> parents = aTypeInfo->getParents();
9553e457fe3SDavid van Moolenbroek         for(unsigned j=0;j<parents.size();j++) {
9563e457fe3SDavid van Moolenbroek             parentMapIt = globalParentMap.find(parents[j]);
9573e457fe3SDavid van Moolenbroek             assert(parentMapIt == globalParentMap.end());
9583e457fe3SDavid van Moolenbroek             globalParentMap.insert(std::pair<GlobalValue*, TypeInfo*>(parents[j], aTypeInfo));
9593e457fe3SDavid van Moolenbroek         }
9603e457fe3SDavid van Moolenbroek         globalTypeInfos.push_back(aTypeInfo);
9613e457fe3SDavid van Moolenbroek     }
9623e457fe3SDavid van Moolenbroek 
9633e457fe3SDavid van Moolenbroek     std::vector< TypeInfo* > magicDsindexTypeInfoList;
9643e457fe3SDavid van Moolenbroek     std::vector< std::pair<std::string,std::string> > magicDsindexNamesList;
9653e457fe3SDavid van Moolenbroek     std::vector<int> magicDsindexFlagsList;
9663e457fe3SDavid van Moolenbroek 
9673e457fe3SDavid van Moolenbroek #if MAGIC_INSTRUMENT_MEM_FUNCS
9683e457fe3SDavid van Moolenbroek     std::vector<MagicMemFunction> magicMemFunctionCalls;
96976b68f9fSDavid van Moolenbroek     if (!DisableMemFunctions) {
97076b68f9fSDavid van Moolenbroek         //gather magic memory function calls to replace and figure out the type (adding more (local) types if needed)
9713e457fe3SDavid van Moolenbroek         std::map< std::pair<std::string,std::string>, int> namesMap;
9723e457fe3SDavid van Moolenbroek         int allocFlags;
9733e457fe3SDavid van Moolenbroek         std::set<Function*> extendedMagicMemFunctions;
9743e457fe3SDavid van Moolenbroek         for (std::set<Function*>::iterator it = originalMagicMemFunctions.begin(); it != originalMagicMemFunctions.end(); ++it) {
9753e457fe3SDavid van Moolenbroek             PassUtil::getFunctionsInDirectBUCallgraph(*it, extendedMagicMemFunctions);
9763e457fe3SDavid van Moolenbroek         }
9773e457fe3SDavid van Moolenbroek         while(!magicMemFunctions.empty()) {
9783e457fe3SDavid van Moolenbroek             MagicMemFunction magicMemFunction = magicMemFunctions.front();
9793e457fe3SDavid van Moolenbroek             magicMemFunctions.erase(magicMemFunctions.begin());
980*bdb56518SDavid van Moolenbroek             std::vector<User*> Users(magicMemFunction.getFunction()->user_begin(), magicMemFunction.getFunction()->user_end());
9813e457fe3SDavid van Moolenbroek             std::vector<Value*> EqPointers;
9823e457fe3SDavid van Moolenbroek             while (!Users.empty()) {
9833e457fe3SDavid van Moolenbroek               int annotation;
9843e457fe3SDavid van Moolenbroek               User *U = Users.back();
9853e457fe3SDavid van Moolenbroek               Users.pop_back();
9863e457fe3SDavid van Moolenbroek 
9873e457fe3SDavid van Moolenbroek               if (Instruction *I = dyn_cast<Instruction>(U)) {
9883e457fe3SDavid van Moolenbroek                 Function *parent = I->getParent()->getParent();
9893e457fe3SDavid van Moolenbroek                 if (isMagicFunction(M, parent) || MagicMemFunction::isCustomWrapper(parent)) {
9903e457fe3SDavid van Moolenbroek                     continue;
9913e457fe3SDavid van Moolenbroek                 }
9923e457fe3SDavid van Moolenbroek                 CallSite CS = MagicUtil::getCallSiteFromInstruction(I);
9933e457fe3SDavid van Moolenbroek                 if (CS.getInstruction() &&
9943e457fe3SDavid van Moolenbroek                     (!CS.arg_empty() || magicMemFunction.getWrapper() == NULL) &&
9953e457fe3SDavid van Moolenbroek                     (MagicUtil::getCalledFunctionFromCS(CS) == magicMemFunction.getFunction() ||
9963e457fe3SDavid van Moolenbroek                      std::find(EqPointers.begin(), EqPointers.end(),
9973e457fe3SDavid van Moolenbroek                                CS.getCalledValue()) != EqPointers.end())) {
9983e457fe3SDavid van Moolenbroek                   bool isDeallocFunction = magicMemFunction.isDeallocFunction();
9993e457fe3SDavid van Moolenbroek                   bool wrapParent = false;
1000b7725c85SDavid van Moolenbroek                   bool isNested = false;
10013e457fe3SDavid van Moolenbroek                   TypeInfo *typeInfo = magicVoidTypeInfo;
10023e457fe3SDavid van Moolenbroek                   std::string allocName = "";
10033e457fe3SDavid van Moolenbroek                   std::string allocParentName = "";
10043e457fe3SDavid van Moolenbroek                   //check if we have to skip
1005b7725c85SDavid van Moolenbroek                   //if this call site is only called from some predefined mem function, it is nested
1006b7725c85SDavid van Moolenbroek                   //some function wrappers are for such nested calls, some are not. this must match.
1007b7725c85SDavid van Moolenbroek                   isNested = (extendedMagicMemFunctions.find(CS.getInstruction()->getParent()->getParent()) != extendedMagicMemFunctions.end());
1008b7725c85SDavid van Moolenbroek                   if (isNested != magicMemFunction.isNestedFunction()) {
10093e457fe3SDavid van Moolenbroek                       continue;
10103e457fe3SDavid van Moolenbroek                   }
10113e457fe3SDavid van Moolenbroek                   if(sbrkFunctions.find(MagicUtil::getCalledFunctionFromCS(CS)) != sbrkFunctions.end()) {
10123e457fe3SDavid van Moolenbroek                       ConstantInt *arg = dyn_cast<ConstantInt>(CS.getArgument(0));
10133e457fe3SDavid van Moolenbroek                       if(arg && arg->getZExtValue() == 0) {
10143e457fe3SDavid van Moolenbroek                           //ignore sbrk(0) calls. This does not skip calls with a variable argument (when arg == NULL)
10153e457fe3SDavid van Moolenbroek #if DEBUG_ALLOC_LEVEL >= 1
10163e457fe3SDavid van Moolenbroek                           magicPassErr("Skipping instrumentation of sbrk(0) MM call found in " << parent->getName() << "():");
10173e457fe3SDavid van Moolenbroek                           I->print(errs());
10183e457fe3SDavid van Moolenbroek                           errs() << "\n";
10193e457fe3SDavid van Moolenbroek #endif
10203e457fe3SDavid van Moolenbroek                           continue;
10213e457fe3SDavid van Moolenbroek                       }
10223e457fe3SDavid van Moolenbroek                   }
10233e457fe3SDavid van Moolenbroek                   else if(MagicUtil::getCallAnnotation(M, CS, &annotation)
10243e457fe3SDavid van Moolenbroek                       && annotation == MAGIC_CALL_MEM_SKIP_INSTRUMENTATION) {
10253e457fe3SDavid van Moolenbroek                       //ignore calls we are supposed to skip
10263e457fe3SDavid van Moolenbroek #if DEBUG_ALLOC_LEVEL >= 1
10273e457fe3SDavid van Moolenbroek                       magicPassErr("Skipping instrumentation of annotated MM call found in " << parent->getName() << "():");
10283e457fe3SDavid van Moolenbroek                       I->print(errs());
10293e457fe3SDavid van Moolenbroek                       errs() << "\n";
10303e457fe3SDavid van Moolenbroek #endif
10313e457fe3SDavid van Moolenbroek                       continue;
10323e457fe3SDavid van Moolenbroek                   }
10333e457fe3SDavid van Moolenbroek                   //figure out the type and the names
1034b7725c85SDavid van Moolenbroek                   if(!isDeallocFunction && !isNested) {
10353e457fe3SDavid van Moolenbroek                       int allocCounter = 1;
10363e457fe3SDavid van Moolenbroek                       int ret;
10373e457fe3SDavid van Moolenbroek                       std::map< std::pair<std::string,std::string>, int>::iterator namesMapIt;
10383e457fe3SDavid van Moolenbroek                       //get alloc types and names
10393e457fe3SDavid van Moolenbroek                       TypeInfo *allocTypeInfo = getAllocTypeInfo(M, magicVoidPtrTypeInfo, CS, allocName, allocParentName);
10403e457fe3SDavid van Moolenbroek #if !MAGIC_INSTRUMENT_MEM_CUSTOM_WRAPPERS
10413e457fe3SDavid van Moolenbroek                       if(!allocTypeInfo) {
10423e457fe3SDavid van Moolenbroek                           allocTypeInfo = voidTypeInfo;
10433e457fe3SDavid van Moolenbroek                       }
10443e457fe3SDavid van Moolenbroek #endif
10453e457fe3SDavid van Moolenbroek                       if(allocTypeInfo) {
10463e457fe3SDavid van Moolenbroek                           typeInfo = allocTypeInfo;
10473e457fe3SDavid van Moolenbroek                       }
10483e457fe3SDavid van Moolenbroek                       else {
10493e457fe3SDavid van Moolenbroek                           int pointerParam = MagicMemFunction::getMemFunctionPointerParam(I->getParent()->getParent(), brkFunctions, magicVoidPtrTypeInfo);
10503e457fe3SDavid van Moolenbroek                           if(pointerParam >= 0 /* && !I->getParent()->getParent()->hasAddressTaken() */) {
10513e457fe3SDavid van Moolenbroek                               //the parent is a valid magic mem function to wrap
10523e457fe3SDavid van Moolenbroek                               wrapParent = true;
10533e457fe3SDavid van Moolenbroek                           }
10543e457fe3SDavid van Moolenbroek                       }
10553e457fe3SDavid van Moolenbroek                       if(!wrapParent) {
10563e457fe3SDavid van Moolenbroek                           assert(allocParentName.compare("") && "Empty parent name!");
10573e457fe3SDavid van Moolenbroek                           if(!allocName.compare("")) {
10583e457fe3SDavid van Moolenbroek                              allocName = MAGIC_ALLOC_NONAME;
10593e457fe3SDavid van Moolenbroek                           }
10603e457fe3SDavid van Moolenbroek 
10613e457fe3SDavid van Moolenbroek #if (MAGIC_NAMED_ALLOC_USE_DBG_INFO || (MAGIC_MEM_USAGE_OUTPUT_CTL == 1))
10623e457fe3SDavid van Moolenbroek                           //extend names with debug information when requested
10633e457fe3SDavid van Moolenbroek                           if (MDNode *N = I->getMetadata("dbg")) {
10643e457fe3SDavid van Moolenbroek                              DILocation Loc(N);
10653e457fe3SDavid van Moolenbroek                              std::string string;
10663e457fe3SDavid van Moolenbroek                              raw_string_ostream ostream(string);
10673e457fe3SDavid van Moolenbroek                              ostream << allocName << MAGIC_ALLOC_NAME_SEP << Loc.getFilename() << MAGIC_ALLOC_NAME_SEP << Loc.getLineNumber();
10683e457fe3SDavid van Moolenbroek                              ostream.flush();
10693e457fe3SDavid van Moolenbroek                              allocName = string;
10703e457fe3SDavid van Moolenbroek                           }
10713e457fe3SDavid van Moolenbroek #endif
10723e457fe3SDavid van Moolenbroek 
10733e457fe3SDavid van Moolenbroek #if MAGIC_FORCE_ALLOC_EXT_NAMES
10743e457fe3SDavid van Moolenbroek                           if (isExtLibrary(parent, NULL)) {
10753e457fe3SDavid van Moolenbroek                              allocName = MAGIC_ALLOC_EXT_NAME;
10763e457fe3SDavid van Moolenbroek                              allocName = MAGIC_ALLOC_EXT_PARENT_NAME;
10773e457fe3SDavid van Moolenbroek                           }
10783e457fe3SDavid van Moolenbroek     #endif
10793e457fe3SDavid van Moolenbroek 
10803e457fe3SDavid van Moolenbroek                           //avoid duplicates
10813e457fe3SDavid van Moolenbroek                           namesMapIt = namesMap.find(std::pair<std::string, std::string>(allocParentName, allocName));
10823e457fe3SDavid van Moolenbroek                           if(namesMapIt != namesMap.end()) {
10833e457fe3SDavid van Moolenbroek                              allocCounter = namesMapIt->second + 1;
10843e457fe3SDavid van Moolenbroek                              ret = namesMap.erase(std::pair<std::string, std::string>(allocParentName, allocName));
10853e457fe3SDavid van Moolenbroek                              assert(ret == 1);
10863e457fe3SDavid van Moolenbroek                              namesMap.insert(std::pair<std::pair<std::string, std::string>, int>(std::pair<std::string, std::string>(allocParentName, allocName), allocCounter));
10873e457fe3SDavid van Moolenbroek                              std::string string;
10883e457fe3SDavid van Moolenbroek                              raw_string_ostream ostream(string);
10893e457fe3SDavid van Moolenbroek                              ostream << allocName << MAGIC_ALLOC_NAME_SUFFIX << allocCounter;
10903e457fe3SDavid van Moolenbroek                              ostream.flush();
10913e457fe3SDavid van Moolenbroek                              allocName = string;
10923e457fe3SDavid van Moolenbroek                           }
10933e457fe3SDavid van Moolenbroek                           else {
10943e457fe3SDavid van Moolenbroek                              namesMap.insert(std::pair<std::pair<std::string, std::string>, int>(std::pair<std::string, std::string>(allocParentName, allocName), allocCounter));
10953e457fe3SDavid van Moolenbroek                              allocName += MAGIC_ALLOC_NAME_SUFFIX;
10963e457fe3SDavid van Moolenbroek                           }
10973e457fe3SDavid van Moolenbroek                           magicMemFunction.setInstructionTypeInfo(typeInfo, allocName, allocParentName);
10983e457fe3SDavid van Moolenbroek                           //add dsindex entries
10993e457fe3SDavid van Moolenbroek                           magicDsindexTypeInfoList.push_back(typeInfo);
11003e457fe3SDavid van Moolenbroek                           magicDsindexNamesList.push_back(std::pair<std::string, std::string>(allocParentName, allocName));
11013e457fe3SDavid van Moolenbroek                           allocFlags = magicMemFunction.getAllocFlags();
11023e457fe3SDavid van Moolenbroek                           assert(allocFlags);
11033e457fe3SDavid van Moolenbroek                           magicDsindexFlagsList.push_back(allocFlags);
11043e457fe3SDavid van Moolenbroek                       }
11053e457fe3SDavid van Moolenbroek                   }
11063e457fe3SDavid van Moolenbroek                   magicMemFunction.setInstruction(I);
11073e457fe3SDavid van Moolenbroek                   Function *instructionParent = I->getParent()->getParent();
11083e457fe3SDavid van Moolenbroek                   //see if we can find the parent in our lists
11093e457fe3SDavid van Moolenbroek                   MagicMemFunction *magicMemParent = NULL;
11103e457fe3SDavid van Moolenbroek                   for(unsigned k=0;k<magicMemFunctions.size();k++) {
11113e457fe3SDavid van Moolenbroek                       if(magicMemFunctions[k].getFunction() == instructionParent) {
11123e457fe3SDavid van Moolenbroek                           magicMemParent = &magicMemFunctions[k];
11133e457fe3SDavid van Moolenbroek                           break;
11143e457fe3SDavid van Moolenbroek                       }
11153e457fe3SDavid van Moolenbroek                   }
11163e457fe3SDavid van Moolenbroek                   if(!magicMemParent) {
11173e457fe3SDavid van Moolenbroek                       for(unsigned k=0;k<magicMemFunctionCalls.size();k++) {
11183e457fe3SDavid van Moolenbroek                           if(magicMemFunctionCalls[k].getFunction() == instructionParent) {
11193e457fe3SDavid van Moolenbroek                               magicMemParent = &magicMemFunctionCalls[k];
11203e457fe3SDavid van Moolenbroek                               break;
11213e457fe3SDavid van Moolenbroek                           }
11223e457fe3SDavid van Moolenbroek                       }
11233e457fe3SDavid van Moolenbroek                   }
11243e457fe3SDavid van Moolenbroek                   if(!magicMemParent && wrapParent) {
11253e457fe3SDavid van Moolenbroek                       //if there is no existing parent but we have to wrap the parent, create a parent now and add it to the function queue
1126b7725c85SDavid van Moolenbroek                       assert(!isNested);
1127b7725c85SDavid van Moolenbroek                       MagicMemFunction newMagicMemFunction(M, instructionParent, NULL, false, false, 0);
11283e457fe3SDavid van Moolenbroek                       magicMemFunctions.push_back(newMagicMemFunction);
11293e457fe3SDavid van Moolenbroek                       magicMemParent = &magicMemFunctions[magicMemFunctions.size()-1];
11303e457fe3SDavid van Moolenbroek                   }
11313e457fe3SDavid van Moolenbroek                   if(magicMemParent) {
11323e457fe3SDavid van Moolenbroek                       //if we have a parent, add a dependency
11333e457fe3SDavid van Moolenbroek                       magicMemParent->addInstructionDep(magicMemFunction);
11343e457fe3SDavid van Moolenbroek                       assert(magicMemParent->getAllocFlags());
11353e457fe3SDavid van Moolenbroek                   }
11363e457fe3SDavid van Moolenbroek                   else {
11373e457fe3SDavid van Moolenbroek                       //if there is no parent, add it to the call queue
11383e457fe3SDavid van Moolenbroek                       magicMemFunctionCalls.push_back(magicMemFunction);
11393e457fe3SDavid van Moolenbroek                   }
11403e457fe3SDavid van Moolenbroek                 }
11413e457fe3SDavid van Moolenbroek               } else if (GlobalValue *GV = dyn_cast<GlobalValue>(U)) {
1142*bdb56518SDavid van Moolenbroek                 Users.insert(Users.end(), GV->user_begin(), GV->user_end());
11433e457fe3SDavid van Moolenbroek                 EqPointers.push_back(GV);
11443e457fe3SDavid van Moolenbroek               } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) {
11453e457fe3SDavid van Moolenbroek                 if (CE->isCast()) {
1146*bdb56518SDavid van Moolenbroek                   Users.insert(Users.end(), CE->user_begin(), CE->user_end());
11473e457fe3SDavid van Moolenbroek                   EqPointers.push_back(CE);
11483e457fe3SDavid van Moolenbroek                 }
11493e457fe3SDavid van Moolenbroek               }
11503e457fe3SDavid van Moolenbroek             }
11513e457fe3SDavid van Moolenbroek         }
115276b68f9fSDavid van Moolenbroek     }
115376b68f9fSDavid van Moolenbroek #endif /*MAGIC_INSTRUMENT_MEM_FUNCS*/
11543e457fe3SDavid van Moolenbroek 
11553e457fe3SDavid van Moolenbroek #if MAGIC_INSTRUMENT_STACK
11563e457fe3SDavid van Moolenbroek     std::vector<std::map<AllocaInst*, std::pair<TypeInfo*, std::string> > > localTypeInfoMaps;
11573e457fe3SDavid van Moolenbroek     std::map<AllocaInst*, std::pair<TypeInfo*, std::string> > localTypeInfoMap;
11583e457fe3SDavid van Moolenbroek     std::vector<Function*> stackIntrumentedFuncs;
11593e457fe3SDavid van Moolenbroek     fillStackInstrumentedFunctions(stackIntrumentedFuncs, deepestLLFunction);
11603e457fe3SDavid van Moolenbroek     std::string stackIntrumentedFuncsStr;
11613e457fe3SDavid van Moolenbroek     for(i=0;i<stackIntrumentedFuncs.size();i++) {
11623e457fe3SDavid van Moolenbroek         localTypeInfoMap.clear();
11633e457fe3SDavid van Moolenbroek         indexLocalTypeInfos(M, stackIntrumentedFuncs[i], localTypeInfoMap);
11643e457fe3SDavid van Moolenbroek         localTypeInfoMaps.push_back(localTypeInfoMap);
11653e457fe3SDavid van Moolenbroek         stackIntrumentedFuncsStr += (i==0 ? "" : ", ") + stackIntrumentedFuncs[i]->getName().str() + "()";
11663e457fe3SDavid van Moolenbroek     }
11673e457fe3SDavid van Moolenbroek     magicPassLog(">>>> Set of stack-instrumented functions expanded from function " << deepestLLFunction->getName() << "(): " << stackIntrumentedFuncsStr);
11683e457fe3SDavid van Moolenbroek     magicPassLog(">>>> Number of types + external types + function types + external function types + local types found: " << globalTypeInfos.size());
11693e457fe3SDavid van Moolenbroek #endif
11703e457fe3SDavid van Moolenbroek 
11713e457fe3SDavid van Moolenbroek     //add raw types
11723e457fe3SDavid van Moolenbroek     std::vector<TypeInfo*> rawTypeInfos;
11733e457fe3SDavid van Moolenbroek     for(i=0;i<globalTypeInfos.size();i++) {
11743e457fe3SDavid van Moolenbroek         TypeInfo* aTypeInfo = globalTypeInfos[i];
11753e457fe3SDavid van Moolenbroek         if(!aTypeInfo->hasRawTypeRepresentation()) {
11763e457fe3SDavid van Moolenbroek             continue;
11773e457fe3SDavid van Moolenbroek         }
11783e457fe3SDavid van Moolenbroek         assert(aTypeInfo->getNumContainedTypes() == 0);
11793e457fe3SDavid van Moolenbroek         TypeInfo* aRawTypeInfo = new TypeInfo(*magicVoidArrTypeInfo);
11803e457fe3SDavid van Moolenbroek         aRawTypeInfo->setPersistent();
11813e457fe3SDavid van Moolenbroek         aRawTypeInfo->removeAllParents();
11823e457fe3SDavid van Moolenbroek         rawTypeInfos.push_back(aRawTypeInfo);
11833e457fe3SDavid van Moolenbroek         std::vector<TypeInfo*> aTypeInfoContainedTypes;
11843e457fe3SDavid van Moolenbroek         aTypeInfoContainedTypes.push_back(aRawTypeInfo);
11853e457fe3SDavid van Moolenbroek         aTypeInfo->setContainedTypes(aTypeInfoContainedTypes);
11863e457fe3SDavid van Moolenbroek         assert(aTypeInfo->getContainedType(0)->getContainedType(0) == magicVoidTypeInfo);
11873e457fe3SDavid van Moolenbroek     }
11883e457fe3SDavid van Moolenbroek     for(i=0;i<rawTypeInfos.size();i++) {
11893e457fe3SDavid van Moolenbroek         globalTypeInfos.push_back(rawTypeInfos[i]);
11903e457fe3SDavid van Moolenbroek         assert(rawTypeInfos[i]->getNumContainedTypes() == 1);
11913e457fe3SDavid van Moolenbroek     }
11923e457fe3SDavid van Moolenbroek     magicPassLog(">>>> Number of types + external types + function types + external function types + local types found + raw types: " << globalTypeInfos.size());
11933e457fe3SDavid van Moolenbroek 
11943e457fe3SDavid van Moolenbroek     //find max recursive sequence length
11953e457fe3SDavid van Moolenbroek     unsigned length, maxRecursiveSequenceLength = 0;
11963e457fe3SDavid van Moolenbroek     for(i=0;i<globalTypeInfos.size();i++) {
11973e457fe3SDavid van Moolenbroek         if(globalTypeInfos[i]->getParents().size() > 0) {
11983e457fe3SDavid van Moolenbroek             length = getMaxRecursiveSequenceLength(globalTypeInfos[i]);
11993e457fe3SDavid van Moolenbroek             if(length > maxRecursiveSequenceLength) {
12003e457fe3SDavid van Moolenbroek                 maxRecursiveSequenceLength = length;
12013e457fe3SDavid van Moolenbroek             }
12023e457fe3SDavid van Moolenbroek         }
12033e457fe3SDavid van Moolenbroek     }
12043e457fe3SDavid van Moolenbroek     magicPassLog(">>>> Max recursive sequence length: " << maxRecursiveSequenceLength);
12053e457fe3SDavid van Moolenbroek 
12063e457fe3SDavid van Moolenbroek     //debug type infos when needed
12073e457fe3SDavid van Moolenbroek #if DEBUG_TYPE_INFOS
12083e457fe3SDavid van Moolenbroek         for(i=0;i<globalTypeInfos.size();i++) {
12093e457fe3SDavid van Moolenbroek             std::vector<GlobalValue*> parents = globalTypeInfos[i]->getParents();
12103e457fe3SDavid van Moolenbroek             if(parents.size() > 0) {
12113e457fe3SDavid van Moolenbroek                 std::string parentString, typeString;
12123e457fe3SDavid van Moolenbroek                 for(unsigned j=0;j<parents.size();j++) {
12133e457fe3SDavid van Moolenbroek                     parentString.append((j>0 ? ", " : "") + parents[j]->getName().str());
12143e457fe3SDavid van Moolenbroek                 }
12153e457fe3SDavid van Moolenbroek                 typeString = globalTypeInfos[i]->getDescription();
12163e457fe3SDavid van Moolenbroek                 magicPassErr("     Global type group found, parents=( " << parentString << "), type=" << typeString << ", name=" << globalTypeInfos[i]->getName() << ", names_string=" << globalTypeInfos[i]->getNamesString());
12173e457fe3SDavid van Moolenbroek                 if(DEBUG_TYPE_INFOS >= 2) {
12183e457fe3SDavid van Moolenbroek                     printInterestingTypes(globalTypeInfos[i]);
12193e457fe3SDavid van Moolenbroek                 }
12203e457fe3SDavid van Moolenbroek             }
12213e457fe3SDavid van Moolenbroek         }
12223e457fe3SDavid van Moolenbroek         for(i=0;i<globalTypeInfos.size();i++) {
12233e457fe3SDavid van Moolenbroek             std::string name = globalTypeInfos[i]->getName();
12243e457fe3SDavid van Moolenbroek             if(name.compare("")) {
12253e457fe3SDavid van Moolenbroek                 magicPassErr("     Named type found: " << name << " (names string: " << globalTypeInfos[i]->getNamesString() << ", id: " << i << ")");
12263e457fe3SDavid van Moolenbroek             }
12273e457fe3SDavid van Moolenbroek         }
12283e457fe3SDavid van Moolenbroek #endif
12293e457fe3SDavid van Moolenbroek 
12303e457fe3SDavid van Moolenbroek #if DEBUG_DUPLICATED_TYPE_INFOS
12313e457fe3SDavid van Moolenbroek     std::map<std::string, TypeInfo*> duplicatedTypeInfoMap;
12323e457fe3SDavid van Moolenbroek     std::map<std::string, TypeInfo*>::iterator duplicatedTypeInfoMapIt;
12333e457fe3SDavid van Moolenbroek     for(i=0;i<globalTypeInfos.size();i++) {
12343e457fe3SDavid van Moolenbroek         if(globalTypeInfos[i]->getType()->isStructTy()) {
12353e457fe3SDavid van Moolenbroek             std::string name = globalTypeInfos[i]->getName();
12363e457fe3SDavid van Moolenbroek             if(!name.compare("")) {
12373e457fe3SDavid van Moolenbroek                 continue;
12383e457fe3SDavid van Moolenbroek             }
12393e457fe3SDavid van Moolenbroek             duplicatedTypeInfoMapIt = duplicatedTypeInfoMap.find(name);
12403e457fe3SDavid van Moolenbroek             if(duplicatedTypeInfoMapIt != duplicatedTypeInfoMap.end()) {
12413e457fe3SDavid van Moolenbroek                 magicPassErr("Duplicated struct name found: " << name << ": " << globalTypeInfos[i]->getVerboseDescription() << " != " << (duplicatedTypeInfoMapIt->second)->getVerboseDescription());
12423e457fe3SDavid van Moolenbroek             }
12433e457fe3SDavid van Moolenbroek             else {
12443e457fe3SDavid van Moolenbroek                 duplicatedTypeInfoMap.insert(std::pair<std::string, TypeInfo*>(name, globalTypeInfos[i]));
12453e457fe3SDavid van Moolenbroek             }
12463e457fe3SDavid van Moolenbroek         }
12473e457fe3SDavid van Moolenbroek     }
12483e457fe3SDavid van Moolenbroek #endif
12493e457fe3SDavid van Moolenbroek 
12503e457fe3SDavid van Moolenbroek     //allocate magic type array
12513e457fe3SDavid van Moolenbroek     ArrayType* magicTypeArrayType = ArrayType::get(magicTypeStructType, globalTypeInfos.size());
12523e457fe3SDavid van Moolenbroek     magicTypeArray = new GlobalVariable(M, magicTypeArrayType, false, GlobalValue::InternalLinkage, ConstantAggregateZero::get(magicTypeArrayType), MAGIC_TYPE_ARRAY_NAME);
12533e457fe3SDavid van Moolenbroek     MagicUtil::setGlobalVariableSection(magicTypeArray, MAGIC_STATIC_VARS_SECTION_DATA);
12543e457fe3SDavid van Moolenbroek 
12553e457fe3SDavid van Moolenbroek     //allocate magic array
12563e457fe3SDavid van Moolenbroek     ArrayType* magicArrayType = ArrayType::get(magicStructType, globalVariables.size());
12573e457fe3SDavid van Moolenbroek     magicArray = new GlobalVariable(M, magicArrayType, false, GlobalValue::InternalLinkage, ConstantAggregateZero::get(magicArrayType), MAGIC_ARRAY_NAME);
12583e457fe3SDavid van Moolenbroek     MagicUtil::setGlobalVariableSection(magicArray, MAGIC_STATIC_VARS_SECTION_DATA);
12593e457fe3SDavid van Moolenbroek 
12603e457fe3SDavid van Moolenbroek     //allocate magic function array
12613e457fe3SDavid van Moolenbroek     ArrayType* magicFunctionArrayType = ArrayType::get(magicFunctionStructType, functions.size());
12623e457fe3SDavid van Moolenbroek     magicFunctionArray = new GlobalVariable(M, magicFunctionArrayType, false, GlobalValue::InternalLinkage, ConstantAggregateZero::get(magicFunctionArrayType), MAGIC_FUNC_ARRAY_NAME);
12633e457fe3SDavid van Moolenbroek     MagicUtil::setGlobalVariableSection(magicFunctionArray, MAGIC_STATIC_VARS_SECTION_DATA);
12643e457fe3SDavid van Moolenbroek 
12653e457fe3SDavid van Moolenbroek     //build magic type array in build function
12663e457fe3SDavid van Moolenbroek     i=0;
12673e457fe3SDavid van Moolenbroek     std::map<TypeInfo*, Constant*> magicArrayTypePtrMap;
12683e457fe3SDavid van Moolenbroek     std::map<TypeInfo*, Constant*>::iterator magicArrayTypePtrMapIt;
12693e457fe3SDavid van Moolenbroek     std::map<TypeInfo*, unsigned> magicArrayTypeIndexMap;
12703e457fe3SDavid van Moolenbroek     std::map<TypeInfo*, unsigned>::iterator magicArrayTypeIndexMapIt;
12713e457fe3SDavid van Moolenbroek     std::vector<Value*> arrayIndexes;
12723e457fe3SDavid van Moolenbroek     for(;i<globalTypeInfos.size();i++) {
12733e457fe3SDavid van Moolenbroek         TypeInfo* aTypeInfo = globalTypeInfos[i];
12743e457fe3SDavid van Moolenbroek         TYPECONST Type *aType = aTypeInfo->getType();
12753e457fe3SDavid van Moolenbroek         arrayIndexes.clear();
12763e457fe3SDavid van Moolenbroek         arrayIndexes.push_back(ConstantInt::get(M.getContext(), APInt(64, 0, 10)));     //pointer to A[]
12773e457fe3SDavid van Moolenbroek         arrayIndexes.push_back(ConstantInt::get(M.getContext(), APInt(64, i, 10))); //pointer to A[index]
12783e457fe3SDavid van Moolenbroek         Constant* magicTypeArrayPtr = MagicUtil::getGetElementPtrConstant(magicTypeArray, arrayIndexes);
12793e457fe3SDavid van Moolenbroek         magicArrayTypePtrMap.insert(std::pair<TypeInfo*, Constant*>(aTypeInfo, magicTypeArrayPtr));
12803e457fe3SDavid van Moolenbroek         magicArrayTypeIndexMap.insert(std::pair<TypeInfo*, unsigned>(aTypeInfo, i));
12813e457fe3SDavid van Moolenbroek 
12823e457fe3SDavid van Moolenbroek         //storing id field
12833e457fe3SDavid van Moolenbroek         Value* structIdField = MagicUtil::getMagicTStructFieldPtr(M, magicArrayBuildFuncInst, magicTypeArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_TSTRUCT_FIELD_ID);
12843e457fe3SDavid van Moolenbroek         Constant* idValue = ConstantInt::get(M.getContext(), APInt(32, i+1, 10));
12853e457fe3SDavid van Moolenbroek         new StoreInst(idValue, structIdField, false, magicArrayBuildFuncInst);
12863e457fe3SDavid van Moolenbroek 
12873e457fe3SDavid van Moolenbroek         //storing name field
12883e457fe3SDavid van Moolenbroek         Value* structNameField = MagicUtil::getMagicTStructFieldPtr(M, magicArrayBuildFuncInst, magicTypeArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_TSTRUCT_FIELD_NAME);
12893e457fe3SDavid van Moolenbroek         Constant* nameValue = MagicUtil::getArrayPtr(M, MagicUtil::getStringRef(M, aTypeInfo->getName()));
12903e457fe3SDavid van Moolenbroek         new StoreInst(nameValue, structNameField, false, magicArrayBuildFuncInst);
12913e457fe3SDavid van Moolenbroek 
12923e457fe3SDavid van Moolenbroek         //storing names field
12933e457fe3SDavid van Moolenbroek         std::vector<std::string> names = aTypeInfo->getNames();
12943e457fe3SDavid van Moolenbroek         Value* structNamesField = MagicUtil::getMagicTStructFieldPtr(M, magicArrayBuildFuncInst, magicTypeArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_TSTRUCT_FIELD_NAMES);
12953e457fe3SDavid van Moolenbroek         Constant* namesValue;
12963e457fe3SDavid van Moolenbroek         if(names.size() > 0) {
12973e457fe3SDavid van Moolenbroek             namesValue = MagicUtil::getArrayPtr(M, MagicUtil::getStringArrayRef(M, names.size(), &names));
12983e457fe3SDavid van Moolenbroek         }
12993e457fe3SDavid van Moolenbroek         else {
13003e457fe3SDavid van Moolenbroek             namesValue = ConstantPointerNull::get((TYPECONST PointerType*) ((TYPECONST PointerType*)structNamesField->getType())->getElementType());
13013e457fe3SDavid van Moolenbroek         }
13023e457fe3SDavid van Moolenbroek         new StoreInst(namesValue, structNamesField, false, magicArrayBuildFuncInst);
13033e457fe3SDavid van Moolenbroek 
13043e457fe3SDavid van Moolenbroek         //storing num_names field
13053e457fe3SDavid van Moolenbroek         Value* structNumNamesField = MagicUtil::getMagicTStructFieldPtr(M, magicArrayBuildFuncInst, magicTypeArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_TSTRUCT_FIELD_NUM_NAMES);
13063e457fe3SDavid van Moolenbroek         Constant* numNamesValue = ConstantInt::get(M.getContext(), APInt(32, names.size(), 10));
13073e457fe3SDavid van Moolenbroek         new StoreInst(numNamesValue, structNumNamesField, false, magicArrayBuildFuncInst);
13083e457fe3SDavid van Moolenbroek 
13093e457fe3SDavid van Moolenbroek         //storing type_str field
13103e457fe3SDavid van Moolenbroek         Value* structTypeStrField = MagicUtil::getMagicTStructFieldPtr(M, magicArrayBuildFuncInst, magicTypeArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_TSTRUCT_FIELD_TYPE_STR);
13113e457fe3SDavid van Moolenbroek         Constant* typeStrValue = MagicUtil::getArrayPtr(M, MagicUtil::getStringRef(M, aTypeInfo->getTypeString()));
13123e457fe3SDavid van Moolenbroek         new StoreInst(typeStrValue, structTypeStrField, false, magicArrayBuildFuncInst);
13133e457fe3SDavid van Moolenbroek 
13143e457fe3SDavid van Moolenbroek         //filling size field
13153e457fe3SDavid van Moolenbroek         Value* structSizeField = MagicUtil::getMagicTStructFieldPtr(M, magicArrayBuildFuncInst, magicTypeArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_TSTRUCT_FIELD_SIZE);
13163e457fe3SDavid van Moolenbroek         Value* typeSizeValue;
13173e457fe3SDavid van Moolenbroek         if(aType->isFunctionTy() || TypeUtil::isOpaqueTy(aType) || aType->isVoidTy()) {
13183e457fe3SDavid van Moolenbroek             typeSizeValue = ConstantInt::get(M.getContext(), APInt(32, 1, 10));
13193e457fe3SDavid van Moolenbroek         }
13203e457fe3SDavid van Moolenbroek         else {
13213e457fe3SDavid van Moolenbroek             assert(aType->isSized());
13223e457fe3SDavid van Moolenbroek             typeSizeValue = ConstantExpr::getIntegerCast(ConstantExpr::getSizeOf(aType), (TYPECONST IntegerType*)((TYPECONST PointerType*)structSizeField->getType())->getElementType(), true);
13233e457fe3SDavid van Moolenbroek         }
13243e457fe3SDavid van Moolenbroek         new StoreInst(typeSizeValue, structSizeField, false, magicArrayBuildFuncInst);
13253e457fe3SDavid van Moolenbroek 
13263e457fe3SDavid van Moolenbroek         //storing num_child_types field
13273e457fe3SDavid van Moolenbroek         Value* structNumChildTypesField = MagicUtil::getMagicTStructFieldPtr(M, magicArrayBuildFuncInst, magicTypeArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_TSTRUCT_FIELD_NUM_CHILD_TYPES);
13283e457fe3SDavid van Moolenbroek         Constant* numChildTypesValue = ConstantInt::get(M.getContext(), APInt(32, aTypeInfo->getNumChildTypes(), 10));
13293e457fe3SDavid van Moolenbroek         new StoreInst(numChildTypesValue, structNumChildTypesField, false, magicArrayBuildFuncInst);
13303e457fe3SDavid van Moolenbroek 
13313e457fe3SDavid van Moolenbroek         //storing member_names field
13323e457fe3SDavid van Moolenbroek         std::vector<std::string> memberNames = aTypeInfo->getMemberNames();
13333e457fe3SDavid van Moolenbroek         Value* structMemberNamesField = MagicUtil::getMagicTStructFieldPtr(M, magicArrayBuildFuncInst, magicTypeArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_TSTRUCT_FIELD_MEMBER_NAMES);
13343e457fe3SDavid van Moolenbroek         Constant* memberNamesValue;
13353e457fe3SDavid van Moolenbroek         if(memberNames.size() > 0) {
13363e457fe3SDavid van Moolenbroek             assert(aType->isStructTy());
13373e457fe3SDavid van Moolenbroek             assert(aTypeInfo->getNumContainedTypes() == memberNames.size());
13383e457fe3SDavid van Moolenbroek             memberNamesValue = MagicUtil::getArrayPtr(M, MagicUtil::getStringArrayRef(M, memberNames.size(), &memberNames));
13393e457fe3SDavid van Moolenbroek         }
13403e457fe3SDavid van Moolenbroek         else {
13413e457fe3SDavid van Moolenbroek             memberNamesValue = ConstantPointerNull::get((TYPECONST PointerType*) ((TYPECONST PointerType*)structMemberNamesField->getType())->getElementType());
13423e457fe3SDavid van Moolenbroek         }
13433e457fe3SDavid van Moolenbroek         new StoreInst(memberNamesValue, structMemberNamesField, false, magicArrayBuildFuncInst);
13443e457fe3SDavid van Moolenbroek 
13453e457fe3SDavid van Moolenbroek         //storing member_offsets field
13463e457fe3SDavid van Moolenbroek         Value* structMemberOffsetsField = MagicUtil::getMagicTStructFieldPtr(M, magicArrayBuildFuncInst, magicTypeArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_TSTRUCT_FIELD_MEMBER_OFFSETS);
13473e457fe3SDavid van Moolenbroek         Constant* memberOffsetsValue;
13483e457fe3SDavid van Moolenbroek         if(memberNames.size() > 0) {
13493e457fe3SDavid van Moolenbroek             assert(aType->isStructTy());
13503e457fe3SDavid van Moolenbroek             assert(aTypeInfo->getNumContainedTypes() == aTypeInfo->getNumChildTypes());
13513e457fe3SDavid van Moolenbroek             bool isConstant = false;
13523e457fe3SDavid van Moolenbroek             GlobalVariable *memberOffsetArray = MagicUtil::getIntArrayRef(M, aTypeInfo->getNumChildTypes(), NULL, isConstant);
13533e457fe3SDavid van Moolenbroek             for(unsigned j=0;j<aTypeInfo->getNumChildTypes();j++) {
13543e457fe3SDavid van Moolenbroek                 std::vector<Value*> arrayIndexes;
13553e457fe3SDavid van Moolenbroek                 arrayIndexes.clear();
13563e457fe3SDavid van Moolenbroek                 arrayIndexes.push_back(ConstantInt::get(M.getContext(), APInt(64, 0, 10))); //pointer to A[]
13573e457fe3SDavid van Moolenbroek                 arrayIndexes.push_back(ConstantInt::get(M.getContext(), APInt(64, j, 10))); //pointer to A[j]
13583e457fe3SDavid van Moolenbroek                 Constant* memberOffsetArrayPtr = MagicUtil::getGetElementPtrConstant(memberOffsetArray, arrayIndexes);
13593e457fe3SDavid van Moolenbroek 
13603e457fe3SDavid van Moolenbroek                 Value* memberOffsetValue = ConstantExpr::getIntegerCast(ConstantExpr::getOffsetOf((TYPECONST StructType*) aTypeInfo->getType(), j), (TYPECONST IntegerType*)((TYPECONST PointerType*)memberOffsetArrayPtr->getType())->getElementType(), true);
13613e457fe3SDavid van Moolenbroek                 new StoreInst(memberOffsetValue, memberOffsetArrayPtr, false, magicArrayBuildFuncInst);
13623e457fe3SDavid van Moolenbroek             }
13633e457fe3SDavid van Moolenbroek             memberOffsetsValue = MagicUtil::getArrayPtr(M, memberOffsetArray);
13643e457fe3SDavid van Moolenbroek         }
13653e457fe3SDavid van Moolenbroek         else {
13663e457fe3SDavid van Moolenbroek             memberOffsetsValue = ConstantPointerNull::get((TYPECONST PointerType*) ((TYPECONST PointerType*)structMemberOffsetsField->getType())->getElementType());
13673e457fe3SDavid van Moolenbroek         }
13683e457fe3SDavid van Moolenbroek         new StoreInst(memberOffsetsValue, structMemberOffsetsField, false, magicArrayBuildFuncInst);
13693e457fe3SDavid van Moolenbroek 
13703e457fe3SDavid van Moolenbroek         //storing value set field (for enum values and value set analysis)
13713e457fe3SDavid van Moolenbroek         std::vector<int> valueSet = aTypeInfo->getValueSet();
13723e457fe3SDavid van Moolenbroek         Value* structValueSetField = MagicUtil::getMagicTStructFieldPtr(M, magicArrayBuildFuncInst, magicTypeArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_TSTRUCT_FIELD_VALUE_SET);
13733e457fe3SDavid van Moolenbroek         Constant* valueSetValue;
13743e457fe3SDavid van Moolenbroek         if(valueSet.size() > 0) {
13753e457fe3SDavid van Moolenbroek             valueSetValue = ConstantExpr::getCast(Instruction::BitCast, MagicUtil::getArrayPtr(M, MagicUtil::getIntArrayRef(M, valueSet.size(), &valueSet)), magicVoidPtrTypeInfo->getType());
13763e457fe3SDavid van Moolenbroek         }
13773e457fe3SDavid van Moolenbroek         else {
13783e457fe3SDavid van Moolenbroek             valueSetValue = ConstantPointerNull::get((TYPECONST PointerType*)magicVoidPtrTypeInfo->getType());
13793e457fe3SDavid van Moolenbroek         }
13803e457fe3SDavid van Moolenbroek         new StoreInst(valueSetValue, structValueSetField, false, magicArrayBuildFuncInst);
13813e457fe3SDavid van Moolenbroek 
13823e457fe3SDavid van Moolenbroek         //storing type_id field
13833e457fe3SDavid van Moolenbroek         Value* structTypeIDField = MagicUtil::getMagicTStructFieldPtr(M, magicArrayBuildFuncInst, magicTypeArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_TSTRUCT_FIELD_TYPE_ID);
13843e457fe3SDavid van Moolenbroek         Constant* typeIDValue = ConstantInt::get(M.getContext(), APInt(32, aTypeInfo->getTypeID(), 10));
13853e457fe3SDavid van Moolenbroek         new StoreInst(typeIDValue, structTypeIDField, false, magicArrayBuildFuncInst);
13863e457fe3SDavid van Moolenbroek 
13873e457fe3SDavid van Moolenbroek         //storing flags field
13883e457fe3SDavid van Moolenbroek         Value* structFlagsField = MagicUtil::getMagicTStructFieldPtr(M, magicArrayBuildFuncInst, magicTypeArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_TSTRUCT_FIELD_FLAGS);
13893e457fe3SDavid van Moolenbroek         Constant* flagsValue = ConstantInt::get(M.getContext(), APInt(32, aTypeInfo->getFlags(), 10));
13903e457fe3SDavid van Moolenbroek         new StoreInst(flagsValue, structFlagsField, false, magicArrayBuildFuncInst);
13913e457fe3SDavid van Moolenbroek 
13923e457fe3SDavid van Moolenbroek         //storing bit_width field
13933e457fe3SDavid van Moolenbroek         Value* structBitWidthField = MagicUtil::getMagicTStructFieldPtr(M, magicArrayBuildFuncInst, magicTypeArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_TSTRUCT_FIELD_BIT_WIDTH);
13943e457fe3SDavid van Moolenbroek         Constant* bitWidthValue = ConstantInt::get(M.getContext(), APInt(32, aTypeInfo->getBitWidth(), 10));
13953e457fe3SDavid van Moolenbroek         new StoreInst(bitWidthValue, structBitWidthField, false, magicArrayBuildFuncInst);
13963e457fe3SDavid van Moolenbroek     }
13973e457fe3SDavid van Moolenbroek 
13983e457fe3SDavid van Moolenbroek     i=0;
13993e457fe3SDavid van Moolenbroek     //build contained types pointers
14003e457fe3SDavid van Moolenbroek     unsigned dstIndex, voidTypeIndex;
14013e457fe3SDavid van Moolenbroek     magicArrayTypeIndexMapIt = magicArrayTypeIndexMap.find(magicVoidTypeInfo);
14023e457fe3SDavid van Moolenbroek     assert(magicArrayTypeIndexMapIt != magicArrayTypeIndexMap.end());
14033e457fe3SDavid van Moolenbroek     voidTypeIndex = magicArrayTypeIndexMapIt->second;
14043e457fe3SDavid van Moolenbroek     for(;i<globalTypeInfos.size();i++) {
14053e457fe3SDavid van Moolenbroek         TypeInfo* aTypeInfo = globalTypeInfos[i];
14063e457fe3SDavid van Moolenbroek         std::vector<Constant*> containedTypePtrs;
14073e457fe3SDavid van Moolenbroek         for(unsigned j=0;j<aTypeInfo->getNumContainedTypes();j++) {
14083e457fe3SDavid van Moolenbroek             TypeInfo* containedType = aTypeInfo->getContainedType(j);
14093e457fe3SDavid van Moolenbroek             magicArrayTypePtrMapIt = magicArrayTypePtrMap.find(containedType);
14103e457fe3SDavid van Moolenbroek             assert(magicArrayTypePtrMapIt != magicArrayTypePtrMap.end());
14113e457fe3SDavid van Moolenbroek 
14123e457fe3SDavid van Moolenbroek             containedTypePtrs.push_back(magicArrayTypePtrMapIt->second);
14133e457fe3SDavid van Moolenbroek         }
14143e457fe3SDavid van Moolenbroek         Value* structContainedTypesField = MagicUtil::getMagicTStructFieldPtr(M, magicArrayBuildFuncInst, magicTypeArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_TSTRUCT_FIELD_CONTAINED_TYPES);
14153e457fe3SDavid van Moolenbroek         Constant *containedTypesValue;
14163e457fe3SDavid van Moolenbroek         if(containedTypePtrs.size() > 0) {
14173e457fe3SDavid van Moolenbroek             containedTypesValue = MagicUtil::getArrayPtr(M, MagicUtil::getGenericArrayRef(M, containedTypePtrs));
14183e457fe3SDavid van Moolenbroek         }
14193e457fe3SDavid van Moolenbroek         else {
14203e457fe3SDavid van Moolenbroek             containedTypesValue = ConstantPointerNull::get((TYPECONST PointerType*) ((TYPECONST PointerType*)structContainedTypesField->getType())->getElementType());
14213e457fe3SDavid van Moolenbroek         }
14223e457fe3SDavid van Moolenbroek         new StoreInst(containedTypesValue, structContainedTypesField, false, magicArrayBuildFuncInst);
14233e457fe3SDavid van Moolenbroek         if(!aTypeInfo->hasRawTypeRepresentation()) {
14243e457fe3SDavid van Moolenbroek             continue;
14253e457fe3SDavid van Moolenbroek         }
14263e457fe3SDavid van Moolenbroek 
14273e457fe3SDavid van Moolenbroek         //handle raw array types
14283e457fe3SDavid van Moolenbroek         assert(aTypeInfo->getNumContainedTypes() == 1 && aTypeInfo->getContainedType(0)->getType()->isArrayTy());
14293e457fe3SDavid van Moolenbroek         magicArrayTypeIndexMapIt = magicArrayTypeIndexMap.find(aTypeInfo->getContainedType(0));
14303e457fe3SDavid van Moolenbroek         assert(magicArrayTypeIndexMapIt != magicArrayTypeIndexMap.end());
14313e457fe3SDavid van Moolenbroek         dstIndex = magicArrayTypeIndexMapIt->second;
14323e457fe3SDavid van Moolenbroek 
14333e457fe3SDavid van Moolenbroek         //fix size field (inherited by parent type)
14343e457fe3SDavid van Moolenbroek         Value* srcStructSizeField = MagicUtil::getMagicTStructFieldPtr(M, magicArrayBuildFuncInst, magicTypeArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_TSTRUCT_FIELD_SIZE);
14353e457fe3SDavid van Moolenbroek         Value* dstStructSizeField = MagicUtil::getMagicTStructFieldPtr(M, magicArrayBuildFuncInst, magicTypeArray, ConstantInt::get(M.getContext(), APInt(64, dstIndex, 10)), MAGIC_TSTRUCT_FIELD_SIZE);
14363e457fe3SDavid van Moolenbroek         Value* srcStructSizeValue = new LoadInst(srcStructSizeField, "", false, magicArrayBuildFuncInst);
14373e457fe3SDavid van Moolenbroek         new StoreInst(srcStructSizeValue, dstStructSizeField, false, magicArrayBuildFuncInst);
14383e457fe3SDavid van Moolenbroek 
14393e457fe3SDavid van Moolenbroek         //fix num_child_types field
14403e457fe3SDavid van Moolenbroek         Value* dstStructNumChildTypesField = MagicUtil::getMagicTStructFieldPtr(M, magicArrayBuildFuncInst, magicTypeArray, ConstantInt::get(M.getContext(), APInt(64, dstIndex, 10)), MAGIC_TSTRUCT_FIELD_NUM_CHILD_TYPES);
14413e457fe3SDavid van Moolenbroek         Value* voidStructSizeField = MagicUtil::getMagicTStructFieldPtr(M, magicArrayBuildFuncInst, magicTypeArray, ConstantInt::get(M.getContext(), APInt(64, voidTypeIndex, 10)), MAGIC_TSTRUCT_FIELD_SIZE);
14423e457fe3SDavid van Moolenbroek         Value* voidStructSizeValue = new LoadInst(voidStructSizeField, "", false, magicArrayBuildFuncInst);
14433e457fe3SDavid van Moolenbroek         BinaryOperator* numChildTypesValue = BinaryOperator::Create(Instruction::SDiv, srcStructSizeValue, voidStructSizeValue, "", magicArrayBuildFuncInst);
14443e457fe3SDavid van Moolenbroek         new StoreInst(numChildTypesValue, dstStructNumChildTypesField, false, magicArrayBuildFuncInst);
14453e457fe3SDavid van Moolenbroek     }
14463e457fe3SDavid van Moolenbroek 
14473e457fe3SDavid van Moolenbroek     i=0;
14483e457fe3SDavid van Moolenbroek     //build cast types pointers
14493e457fe3SDavid van Moolenbroek     for(;i<globalTypeInfos.size();i++) {
14503e457fe3SDavid van Moolenbroek         TypeInfo* aTypeInfo = globalTypeInfos[i];
14513e457fe3SDavid van Moolenbroek         std::vector<Constant*> castTypePtrs;
14523e457fe3SDavid van Moolenbroek         std::vector<TypeInfo*> castTypes = aTypeInfo->getCastTypes();
14533e457fe3SDavid van Moolenbroek 
14543e457fe3SDavid van Moolenbroek         Value* structCompatibleTypesField = MagicUtil::getMagicTStructFieldPtr(M, magicArrayBuildFuncInst, magicTypeArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_TSTRUCT_FIELD_COMPATIBLE_TYPES);
14553e457fe3SDavid van Moolenbroek         TYPECONST PointerType* nullArrayType = (TYPECONST PointerType*) ((TYPECONST PointerType*)structCompatibleTypesField->getType())->getElementType();
14563e457fe3SDavid van Moolenbroek         for(unsigned j=0;j<castTypes.size();j++) {
14573e457fe3SDavid van Moolenbroek             TypeInfo* castType = castTypes[j];
14583e457fe3SDavid van Moolenbroek             if(castType == NULL) {
14593e457fe3SDavid van Moolenbroek                 castTypePtrs.push_back(ConstantPointerNull::get((TYPECONST PointerType*) nullArrayType->getContainedType(0)));
14603e457fe3SDavid van Moolenbroek             }
14613e457fe3SDavid van Moolenbroek             else {
14623e457fe3SDavid van Moolenbroek                 magicArrayTypePtrMapIt = magicArrayTypePtrMap.find(castType);
14633e457fe3SDavid van Moolenbroek                 assert(magicArrayTypePtrMapIt != magicArrayTypePtrMap.end());
14643e457fe3SDavid van Moolenbroek 
14653e457fe3SDavid van Moolenbroek                 castTypePtrs.push_back(magicArrayTypePtrMapIt->second);
14663e457fe3SDavid van Moolenbroek             }
14673e457fe3SDavid van Moolenbroek         }
14683e457fe3SDavid van Moolenbroek 
14693e457fe3SDavid van Moolenbroek         Constant *compatibleTypesValue;
14703e457fe3SDavid van Moolenbroek         if(castTypePtrs.size() > 0) {
14713e457fe3SDavid van Moolenbroek             compatibleTypesValue = MagicUtil::getArrayPtr(M, MagicUtil::getGenericArrayRef(M, castTypePtrs));
14723e457fe3SDavid van Moolenbroek         }
14733e457fe3SDavid van Moolenbroek         else {
14743e457fe3SDavid van Moolenbroek             compatibleTypesValue = ConstantPointerNull::get(nullArrayType);
14753e457fe3SDavid van Moolenbroek         }
14763e457fe3SDavid van Moolenbroek         new StoreInst(compatibleTypesValue, structCompatibleTypesField, false, magicArrayBuildFuncInst);
14773e457fe3SDavid van Moolenbroek     }
14783e457fe3SDavid van Moolenbroek 
14793e457fe3SDavid van Moolenbroek     //build magic array in build function
14803e457fe3SDavid van Moolenbroek     i=0;
14813e457fe3SDavid van Moolenbroek     strGlobalVariables = 0;
14823e457fe3SDavid van Moolenbroek     PointerType* voidPointerType = PointerType::get(IntegerType::get(M.getContext(), 8), 0);
14833e457fe3SDavid van Moolenbroek     for(;i<globalVariables.size();i++) {
14843e457fe3SDavid van Moolenbroek         GlobalVariable *GV = globalVariables[i];
14853e457fe3SDavid van Moolenbroek         DIGlobalVariable *DIGV = NULL;
14863e457fe3SDavid van Moolenbroek         StringRef GVName;
14873e457fe3SDavid van Moolenbroek         bool isFromLibrary, hasAddressTaken, isString, isNamedString;
14883e457fe3SDavid van Moolenbroek         isString = GV->getName().startswith(".str");
14893e457fe3SDavid van Moolenbroek         isNamedString = false;
14903e457fe3SDavid van Moolenbroek         if(isString) {
14913e457fe3SDavid van Moolenbroek             stringOwnerInvertedMapIt = stringOwnerInvertedMap.find(GV);
14923e457fe3SDavid van Moolenbroek             if(stringOwnerInvertedMapIt != stringOwnerInvertedMap.end()) {
14933e457fe3SDavid van Moolenbroek                 isNamedString = true;
14943e457fe3SDavid van Moolenbroek                 DIGV = NULL;
14953e457fe3SDavid van Moolenbroek                 GVName = ".str#" + stringOwnerInvertedMapIt->second;
14963e457fe3SDavid van Moolenbroek             }
14973e457fe3SDavid van Moolenbroek         }
14983e457fe3SDavid van Moolenbroek         if(!isNamedString) {
14993e457fe3SDavid van Moolenbroek             GVName = MagicUtil::getGVSourceName(M, GV, &DIGV, baseBuildDir);
15003e457fe3SDavid van Moolenbroek         }
15013e457fe3SDavid van Moolenbroek         isFromLibrary = isExtLibrary(GV, DIGV);
15023e457fe3SDavid van Moolenbroek         hasAddressTaken = globalVariablesWithAddressTaken.find(GV) != globalVariablesWithAddressTaken.end();
15033e457fe3SDavid van Moolenbroek         std::string GVNameStr(GVName.str());
15043e457fe3SDavid van Moolenbroek 
15053e457fe3SDavid van Moolenbroek         //storing id field
15063e457fe3SDavid van Moolenbroek         Value* structIdField = MagicUtil::getMagicSStructFieldPtr(M, magicArrayBuildFuncInst, magicArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_SSTRUCT_FIELD_ID);
15073e457fe3SDavid van Moolenbroek         Constant* idValue = ConstantInt::get(M.getContext(), APInt(32, i+1, 10));
15083e457fe3SDavid van Moolenbroek         new StoreInst(idValue, structIdField, false, magicArrayBuildFuncInst);
15093e457fe3SDavid van Moolenbroek 
15103e457fe3SDavid van Moolenbroek         //storing name field
15113e457fe3SDavid van Moolenbroek         Value* structNameField = MagicUtil::getMagicSStructFieldPtr(M, magicArrayBuildFuncInst, magicArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_SSTRUCT_FIELD_NAME);
15123e457fe3SDavid van Moolenbroek         Constant* nameValue = MagicUtil::getArrayPtr(M, MagicUtil::getStringRef(M, GVNameStr));
15133e457fe3SDavid van Moolenbroek         new StoreInst(nameValue, structNameField, false, magicArrayBuildFuncInst);
15143e457fe3SDavid van Moolenbroek 
15153e457fe3SDavid van Moolenbroek         //storing type field
15163e457fe3SDavid van Moolenbroek         parentMapIt = globalParentMap.find(GV);
15173e457fe3SDavid van Moolenbroek         if(parentMapIt == globalParentMap.end()) {
15183e457fe3SDavid van Moolenbroek             continue;
15193e457fe3SDavid van Moolenbroek         }
15203e457fe3SDavid van Moolenbroek         assert(parentMapIt != globalParentMap.end());
15213e457fe3SDavid van Moolenbroek         TypeInfo* aTypeInfo = parentMapIt->second;
15223e457fe3SDavid van Moolenbroek         magicArrayTypePtrMapIt = magicArrayTypePtrMap.find(aTypeInfo);
15233e457fe3SDavid van Moolenbroek         assert(magicArrayTypePtrMapIt != magicArrayTypePtrMap.end());
15243e457fe3SDavid van Moolenbroek         Value* structTypeField = MagicUtil::getMagicSStructFieldPtr(M, magicArrayBuildFuncInst, magicArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_SSTRUCT_FIELD_TYPE);
15253e457fe3SDavid van Moolenbroek         Constant* typeValue = magicArrayTypePtrMapIt->second;
15263e457fe3SDavid van Moolenbroek         new StoreInst(typeValue, structTypeField, false, magicArrayBuildFuncInst);
15273e457fe3SDavid van Moolenbroek 
15283e457fe3SDavid van Moolenbroek         //filling flags field
15293e457fe3SDavid van Moolenbroek         int annotation, flags = MAGIC_STATE_DATA;
15303e457fe3SDavid van Moolenbroek         if(GV->hasExternalLinkage() || GV->hasExternalWeakLinkage()) {
15313e457fe3SDavid van Moolenbroek             flags |= MAGIC_STATE_EXTERNAL;
15323e457fe3SDavid van Moolenbroek         }
15333e457fe3SDavid van Moolenbroek         if(GV->isConstant()) {
15343e457fe3SDavid van Moolenbroek             flags |= MAGIC_STATE_CONSTANT;
15353e457fe3SDavid van Moolenbroek         }
15363e457fe3SDavid van Moolenbroek         if(GV->isThreadLocal()) {
15373e457fe3SDavid van Moolenbroek             flags |= MAGIC_STATE_THREAD_LOCAL;
15383e457fe3SDavid van Moolenbroek         }
15393e457fe3SDavid van Moolenbroek         if(isFromLibrary) {
15403e457fe3SDavid van Moolenbroek             flags |= MAGIC_STATE_LIB;
15413e457fe3SDavid van Moolenbroek         }
15423e457fe3SDavid van Moolenbroek         if(!hasAddressTaken) {
15433e457fe3SDavid van Moolenbroek             flags |= MAGIC_STATE_ADDR_NOT_TAKEN;
15443e457fe3SDavid van Moolenbroek         }
15453e457fe3SDavid van Moolenbroek         if(isString) {
15463e457fe3SDavid van Moolenbroek             flags |= MAGIC_STATE_STRING;
15473e457fe3SDavid van Moolenbroek             if(isNamedString) {
15483e457fe3SDavid van Moolenbroek                 flags |= MAGIC_STATE_NAMED_STRING;
15493e457fe3SDavid van Moolenbroek             }
15503e457fe3SDavid van Moolenbroek             strGlobalVariables++;
15513e457fe3SDavid van Moolenbroek         }
15523e457fe3SDavid van Moolenbroek         if(MagicUtil::getVarAnnotation(M, GV, &annotation)) {
15533e457fe3SDavid van Moolenbroek             magicPassLog("Magic annotation found for global variable: " << GV->getName());
15543e457fe3SDavid van Moolenbroek             flags |= (annotation & MAGIC_STATE_ANNOTATION_MASK);
15553e457fe3SDavid van Moolenbroek         }
15563e457fe3SDavid van Moolenbroek         Value* structFlagsField = MagicUtil::getMagicSStructFieldPtr(M, magicArrayBuildFuncInst, magicArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_SSTRUCT_FIELD_FLAGS);
15573e457fe3SDavid van Moolenbroek         Constant* flagsValue = ConstantInt::get(M.getContext(), APInt(32, flags, 10));
15583e457fe3SDavid van Moolenbroek         new StoreInst(flagsValue, structFlagsField, false, magicArrayBuildFuncInst);
15593e457fe3SDavid van Moolenbroek 
15603e457fe3SDavid van Moolenbroek         //filling address field
15613e457fe3SDavid van Moolenbroek         Value* structAddressField = MagicUtil::getMagicSStructFieldPtr(M, magicArrayBuildFuncInst, magicArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_SSTRUCT_FIELD_ADDRESS);
15623e457fe3SDavid van Moolenbroek         Constant* varAddressValue = ConstantExpr::getCast(Instruction::BitCast, GV, voidPointerType);
15633e457fe3SDavid van Moolenbroek         new StoreInst(varAddressValue, structAddressField, false, magicArrayBuildFuncInst);
15643e457fe3SDavid van Moolenbroek 
15653e457fe3SDavid van Moolenbroek         //filling shadow address field
15663e457fe3SDavid van Moolenbroek         Value* structShadowAddressField = MagicUtil::getMagicSStructFieldPtr(M, magicArrayBuildFuncInst, magicArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_SSTRUCT_FIELD_SHADOW_ADDRESS);
15673e457fe3SDavid van Moolenbroek         Constant* varShadowAddressValue;
15683e457fe3SDavid van Moolenbroek         if(EnableShadowing && !GV->isConstant()) {
15693e457fe3SDavid van Moolenbroek             GlobalVariable* varShadow = MagicUtil::getShadowRef(M, GV);
15703e457fe3SDavid van Moolenbroek             shadowGlobalVariables.push_back(varShadow);
15713e457fe3SDavid van Moolenbroek             varShadowAddressValue = ConstantExpr::getCast(Instruction::BitCast, varShadow, voidPointerType);
15723e457fe3SDavid van Moolenbroek         }
15733e457fe3SDavid van Moolenbroek         else {
15743e457fe3SDavid van Moolenbroek             varShadowAddressValue = ConstantPointerNull::get((TYPECONST PointerType*) ((TYPECONST PointerType*)structShadowAddressField->getType())->getElementType());
15753e457fe3SDavid van Moolenbroek         }
15763e457fe3SDavid van Moolenbroek         new StoreInst(varShadowAddressValue, structShadowAddressField, false, magicArrayBuildFuncInst);
15773e457fe3SDavid van Moolenbroek     }
15783e457fe3SDavid van Moolenbroek 
15793e457fe3SDavid van Moolenbroek     //build magic function array in build function
15803e457fe3SDavid van Moolenbroek     i=0;
15813e457fe3SDavid van Moolenbroek     for(;i<functions.size();i++) {
15823e457fe3SDavid van Moolenbroek         Function *F = functions[i];
15833e457fe3SDavid van Moolenbroek         DISubprogram *DIS = NULL;
15843e457fe3SDavid van Moolenbroek         StringRef FName = MagicUtil::getFunctionSourceName(M, F, &DIS, baseBuildDir);
15853e457fe3SDavid van Moolenbroek         std::string FNameStr(FName.str());
15863e457fe3SDavid van Moolenbroek         bool isFromLibrary = isExtLibrary(F, DIS);
15873e457fe3SDavid van Moolenbroek 
15883e457fe3SDavid van Moolenbroek         //storing id field
15893e457fe3SDavid van Moolenbroek         Value* structIdField = MagicUtil::getMagicFStructFieldPtr(M, magicArrayBuildFuncInst, magicFunctionArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_FSTRUCT_FIELD_ID);
15903e457fe3SDavid van Moolenbroek         Constant* idValue = ConstantInt::get(M.getContext(), APInt(32, i+1, 10));
15913e457fe3SDavid van Moolenbroek         new StoreInst(idValue, structIdField, false, magicArrayBuildFuncInst);
15923e457fe3SDavid van Moolenbroek 
15933e457fe3SDavid van Moolenbroek         //storing name field
15943e457fe3SDavid van Moolenbroek         Value* structNameField = MagicUtil::getMagicFStructFieldPtr(M, magicArrayBuildFuncInst, magicFunctionArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_FSTRUCT_FIELD_NAME);
15953e457fe3SDavid van Moolenbroek         Constant* nameValue = MagicUtil::getArrayPtr(M, MagicUtil::getStringRef(M, FNameStr));
15963e457fe3SDavid van Moolenbroek         new StoreInst(nameValue, structNameField, false, magicArrayBuildFuncInst);
15973e457fe3SDavid van Moolenbroek 
15983e457fe3SDavid van Moolenbroek         //storing type field
15993e457fe3SDavid van Moolenbroek         parentMapIt = globalParentMap.find(F);
16003e457fe3SDavid van Moolenbroek         assert(parentMapIt != globalParentMap.end());
16013e457fe3SDavid van Moolenbroek         TypeInfo* aTypeInfo = parentMapIt->second;
16023e457fe3SDavid van Moolenbroek         magicArrayTypePtrMapIt = magicArrayTypePtrMap.find(aTypeInfo);
16033e457fe3SDavid van Moolenbroek         assert(magicArrayTypePtrMapIt != magicArrayTypePtrMap.end());
16043e457fe3SDavid van Moolenbroek         Value* structTypeField = MagicUtil::getMagicFStructFieldPtr(M, magicArrayBuildFuncInst, magicFunctionArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_FSTRUCT_FIELD_TYPE);
16053e457fe3SDavid van Moolenbroek         Constant* typeValue = magicArrayTypePtrMapIt->second;
16063e457fe3SDavid van Moolenbroek         new StoreInst(typeValue, structTypeField, false, magicArrayBuildFuncInst);
16073e457fe3SDavid van Moolenbroek 
16083e457fe3SDavid van Moolenbroek         //filling flags field
16093e457fe3SDavid van Moolenbroek         int flags = MAGIC_STATE_TEXT|MAGIC_STATE_CONSTANT;
16103e457fe3SDavid van Moolenbroek         if(isFromLibrary) {
16113e457fe3SDavid van Moolenbroek             flags |= MAGIC_STATE_LIB;
16123e457fe3SDavid van Moolenbroek         }
16133e457fe3SDavid van Moolenbroek         if(!F->hasAddressTaken()) {
16143e457fe3SDavid van Moolenbroek             flags |= MAGIC_STATE_ADDR_NOT_TAKEN;
16153e457fe3SDavid van Moolenbroek         }
16163e457fe3SDavid van Moolenbroek         Value* structFlagsField = MagicUtil::getMagicFStructFieldPtr(M, magicArrayBuildFuncInst, magicFunctionArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_FSTRUCT_FIELD_FLAGS);
16173e457fe3SDavid van Moolenbroek         Constant* flagsValue = ConstantInt::get(M.getContext(), APInt(32, flags, 10));
16183e457fe3SDavid van Moolenbroek         new StoreInst(flagsValue, structFlagsField, false, magicArrayBuildFuncInst);
16193e457fe3SDavid van Moolenbroek 
16203e457fe3SDavid van Moolenbroek         //filling address field
16213e457fe3SDavid van Moolenbroek         Value* structAddressField = MagicUtil::getMagicFStructFieldPtr(M, magicArrayBuildFuncInst, magicFunctionArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_FSTRUCT_FIELD_ADDRESS);
16223e457fe3SDavid van Moolenbroek         Constant* varAddressValue = ConstantExpr::getCast(Instruction::BitCast, F, voidPointerType);
16233e457fe3SDavid van Moolenbroek         new StoreInst(varAddressValue, structAddressField, false, magicArrayBuildFuncInst);
16243e457fe3SDavid van Moolenbroek     }
16253e457fe3SDavid van Moolenbroek 
16263e457fe3SDavid van Moolenbroek #if MAGIC_INSTRUMENT_MEM_FUNCS
162776b68f9fSDavid van Moolenbroek     if (!DisableMemFunctions) {
16283e457fe3SDavid van Moolenbroek         //replace magic memory function calls with their wrappers
16293e457fe3SDavid van Moolenbroek         for(i=0;i<magicMemFunctionCalls.size();i++) {
16303e457fe3SDavid van Moolenbroek             MagicMemFunction *magicMemFunctionCall = &magicMemFunctionCalls[i];
16313e457fe3SDavid van Moolenbroek             magicMemFunctionCall->replaceInstruction(magicArrayTypePtrMap, magicVoidPtrTypeInfo);
16323e457fe3SDavid van Moolenbroek         }
16333e457fe3SDavid van Moolenbroek 
16343e457fe3SDavid van Moolenbroek         //fix debug function calls and their arguments
16353e457fe3SDavid van Moolenbroek         for (i=0;i<magicDebugFunctions.size();i++) {
16363e457fe3SDavid van Moolenbroek             MagicDebugFunction *magicDebugFunction = &magicDebugFunctions[i];
16373e457fe3SDavid van Moolenbroek             magicDebugFunction->fixCalls(M, baseBuildDir);
16383e457fe3SDavid van Moolenbroek         }
16393e457fe3SDavid van Moolenbroek 
16403e457fe3SDavid van Moolenbroek         //fix mmap ctl function calls and their arguments
16413e457fe3SDavid van Moolenbroek         for (i=0;i<magicMmapCtlFunctions.size();i++) {
16423e457fe3SDavid van Moolenbroek             MagicMmapCtlFunction *magicMmapCtlFunction = &magicMmapCtlFunctions[i];
16433e457fe3SDavid van Moolenbroek             magicMmapCtlFunction->fixCalls(M, magicGetPageSizeFunc);
16443e457fe3SDavid van Moolenbroek         }
164576b68f9fSDavid van Moolenbroek     }
164676b68f9fSDavid van Moolenbroek #endif /*MAGIC_INSTRUMENT_MEM_FUNCS*/
16473e457fe3SDavid van Moolenbroek 
16483e457fe3SDavid van Moolenbroek #if MAGIC_INSTRUMENT_STACK
16493e457fe3SDavid van Moolenbroek     //instrument the stack for the relevant set of functions and add dsindex entries
16503e457fe3SDavid van Moolenbroek     for(i=0;i<stackIntrumentedFuncs.size();i++) {
16513e457fe3SDavid van Moolenbroek         addMagicStackDsentryFuncCalls(M, stackIntrumentedFuncs[i], stackIntrumentedFuncs[i], magicStackDsentryCreateFunc, magicStackDsentryDestroyFunc,
16523e457fe3SDavid van Moolenbroek             magicDsentryStructType, localTypeInfoMaps[i], magicArrayTypePtrMap, magicVoidPtrTypeInfo, magicDsindexTypeInfoList, magicDsindexNamesList, magicDsindexFlagsList);
16533e457fe3SDavid van Moolenbroek     }
16543e457fe3SDavid van Moolenbroek #endif
16553e457fe3SDavid van Moolenbroek 
16563e457fe3SDavid van Moolenbroek     //allocate magic dsindex array
16573e457fe3SDavid van Moolenbroek     ArrayType* magicDsindexArrayType = ArrayType::get(magicDsindexStructType, magicDsindexTypeInfoList.size());
16583e457fe3SDavid van Moolenbroek     magicDsindexArray = new GlobalVariable(M, magicDsindexArrayType, false, GlobalValue::InternalLinkage, ConstantAggregateZero::get(magicDsindexArrayType), MAGIC_DSINDEX_ARRAY_NAME);
16593e457fe3SDavid van Moolenbroek     MagicUtil::setGlobalVariableSection(magicDsindexArray, MAGIC_STATIC_VARS_SECTION_DATA);
16603e457fe3SDavid van Moolenbroek 
16613e457fe3SDavid van Moolenbroek     //build magic dsindex array in build function
16623e457fe3SDavid van Moolenbroek     i=0;
16633e457fe3SDavid van Moolenbroek     for(;i<magicDsindexTypeInfoList.size();i++) {
16643e457fe3SDavid van Moolenbroek         //storing type field
16653e457fe3SDavid van Moolenbroek         TypeInfo* aTypeInfo = magicDsindexTypeInfoList[i];
16663e457fe3SDavid van Moolenbroek         magicArrayTypePtrMapIt = magicArrayTypePtrMap.find(aTypeInfo);
16673e457fe3SDavid van Moolenbroek         assert(magicArrayTypePtrMapIt != magicArrayTypePtrMap.end());
16683e457fe3SDavid van Moolenbroek         Value* structTypeField = MagicUtil::getMagicDStructFieldPtr(M, magicArrayBuildFuncInst, magicDsindexArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_DSTRUCT_FIELD_TYPE);
16693e457fe3SDavid van Moolenbroek         Constant* typeValue = magicArrayTypePtrMapIt->second;
16703e457fe3SDavid van Moolenbroek         new StoreInst(typeValue, structTypeField, false, magicArrayBuildFuncInst);
16713e457fe3SDavid van Moolenbroek 
16723e457fe3SDavid van Moolenbroek         //storing name field
16733e457fe3SDavid van Moolenbroek         Value* structNameField = MagicUtil::getMagicDStructFieldPtr(M, magicArrayBuildFuncInst, magicDsindexArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_DSTRUCT_FIELD_NAME);
16743e457fe3SDavid van Moolenbroek         Constant* nameValue = MagicUtil::getArrayPtr(M, MagicUtil::getStringRef(M, magicDsindexNamesList[i].second));
16753e457fe3SDavid van Moolenbroek         new StoreInst(nameValue, structNameField, false, magicArrayBuildFuncInst);
16763e457fe3SDavid van Moolenbroek 
16773e457fe3SDavid van Moolenbroek         //storing parent name field
16783e457fe3SDavid van Moolenbroek         Value* structParentNameField = MagicUtil::getMagicDStructFieldPtr(M, magicArrayBuildFuncInst, magicDsindexArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_DSTRUCT_FIELD_PARENT_NAME);
16793e457fe3SDavid van Moolenbroek         Constant* parentNameValue = MagicUtil::getArrayPtr(M, MagicUtil::getStringRef(M, magicDsindexNamesList[i].first));
16803e457fe3SDavid van Moolenbroek         new StoreInst(parentNameValue, structParentNameField, false, magicArrayBuildFuncInst);
16813e457fe3SDavid van Moolenbroek 
16823e457fe3SDavid van Moolenbroek         //storing flags field
16833e457fe3SDavid van Moolenbroek         Value* structFlagsField = MagicUtil::getMagicDStructFieldPtr(M, magicArrayBuildFuncInst, magicDsindexArray, ConstantInt::get(M.getContext(), APInt(64, i, 10)), MAGIC_DSTRUCT_FIELD_FLAGS);
16843e457fe3SDavid van Moolenbroek         Constant* flagsValue = ConstantInt::get(M.getContext(), APInt(32, magicDsindexFlagsList[i], 10));
16853e457fe3SDavid van Moolenbroek         new StoreInst(flagsValue, structFlagsField, false, magicArrayBuildFuncInst);
16863e457fe3SDavid van Moolenbroek     }
16873e457fe3SDavid van Moolenbroek 
16883e457fe3SDavid van Moolenbroek     // apply qprof instrumentation
16893e457fe3SDavid van Moolenbroek     qprofInstrumentationApply(M);
16903e457fe3SDavid van Moolenbroek 
16913e457fe3SDavid van Moolenbroek     //set pointer to magic type array in build function
16923e457fe3SDavid van Moolenbroek     new StoreInst(MagicUtil::getArrayPtr(M, magicTypeArray), magicTypeArrayPtr, false, magicArrayBuildFuncInst);
16933e457fe3SDavid van Moolenbroek 
1694c07c198bSDavid van Moolenbroek     // set runtime flags
1695c07c198bSDavid van Moolenbroek     new StoreInst(ConstantInt::get(M.getContext(), APInt(32, DisableMemFunctions ? 1 : 0)), magicNoMemInst, false, magicArrayBuildFuncInst);
1696c07c198bSDavid van Moolenbroek 
16973e457fe3SDavid van Moolenbroek     //set magic type array size in build function
16983e457fe3SDavid van Moolenbroek     new StoreInst(ConstantInt::get(M.getContext(), APInt(32, globalTypeInfos.size())), magicTypeArraySize, false, magicArrayBuildFuncInst);
16993e457fe3SDavid van Moolenbroek 
17003e457fe3SDavid van Moolenbroek     //set magic type next id in build function
17013e457fe3SDavid van Moolenbroek     new StoreInst(ConstantInt::get(M.getContext(), APInt(32, globalTypeInfos.size()+1)), magicTypeNextId, false, magicArrayBuildFuncInst);
17023e457fe3SDavid van Moolenbroek 
17033e457fe3SDavid van Moolenbroek     //set pointer to magic array in build function
17043e457fe3SDavid van Moolenbroek     new StoreInst(MagicUtil::getArrayPtr(M, magicArray), magicArrayPtr, false, magicArrayBuildFuncInst);
17053e457fe3SDavid van Moolenbroek 
17063e457fe3SDavid van Moolenbroek     //set magic array size in build function
17073e457fe3SDavid van Moolenbroek     new StoreInst(ConstantInt::get(M.getContext(), APInt(32, globalVariables.size())), magicArraySize, false, magicArrayBuildFuncInst);
17083e457fe3SDavid van Moolenbroek 
17093e457fe3SDavid van Moolenbroek     //set magic array string size in build function
17103e457fe3SDavid van Moolenbroek     new StoreInst(ConstantInt::get(M.getContext(), APInt(32, strGlobalVariables)), magicArrayStrSize, false, magicArrayBuildFuncInst);
17113e457fe3SDavid van Moolenbroek 
17123e457fe3SDavid van Moolenbroek     //set magic next id in build function
17133e457fe3SDavid van Moolenbroek     new StoreInst(ConstantInt::get(M.getContext(), APInt(32, globalVariables.size()+1)), magicNextId, false, magicArrayBuildFuncInst);
17143e457fe3SDavid van Moolenbroek 
17153e457fe3SDavid van Moolenbroek     //set pointer to magic function array in build function
17163e457fe3SDavid van Moolenbroek     new StoreInst(MagicUtil::getArrayPtr(M, magicFunctionArray), magicFunctionArrayPtr, false, magicArrayBuildFuncInst);
17173e457fe3SDavid van Moolenbroek 
17183e457fe3SDavid van Moolenbroek     //set magic function array size in build function
17193e457fe3SDavid van Moolenbroek     new StoreInst(ConstantInt::get(M.getContext(), APInt(32, functions.size())), magicFunctionArraySize, false, magicArrayBuildFuncInst);
17203e457fe3SDavid van Moolenbroek 
17213e457fe3SDavid van Moolenbroek     //set magic function next id in build function
17223e457fe3SDavid van Moolenbroek     new StoreInst(ConstantInt::get(M.getContext(), APInt(32, functions.size()+1)), magicFunctionNextId, false, magicArrayBuildFuncInst);
17233e457fe3SDavid van Moolenbroek 
17243e457fe3SDavid van Moolenbroek     //set pointer to magic dsindex array in build function
17253e457fe3SDavid van Moolenbroek     new StoreInst(MagicUtil::getArrayPtr(M, magicDsindexArray), magicDsindexArrayPtr, false, magicArrayBuildFuncInst);
17263e457fe3SDavid van Moolenbroek 
17273e457fe3SDavid van Moolenbroek     //set magic dsindex array size in build function
17283e457fe3SDavid van Moolenbroek     new StoreInst(ConstantInt::get(M.getContext(), APInt(32, magicDsindexTypeInfoList.size())), magicDsindexArraySize, false, magicArrayBuildFuncInst);
17293e457fe3SDavid van Moolenbroek 
17303e457fe3SDavid van Moolenbroek     //set magic void type pointer in build function
17313e457fe3SDavid van Moolenbroek     magicArrayTypePtrMapIt = magicArrayTypePtrMap.find(magicVoidPtrTypeInfo);
17323e457fe3SDavid van Moolenbroek     assert(magicArrayTypePtrMapIt != magicArrayTypePtrMap.end());
17333e457fe3SDavid van Moolenbroek     Constant* magicVoidPtrTypeValue = magicArrayTypePtrMapIt->second;
17343e457fe3SDavid van Moolenbroek     new StoreInst(magicVoidPtrTypeValue, magicVoidPtrTypePtr, false, magicArrayBuildFuncInst);
17353e457fe3SDavid van Moolenbroek 
17363e457fe3SDavid van Moolenbroek     //inject magic init call at the beginning of magic entry point function
17373e457fe3SDavid van Moolenbroek     std::vector<Value*> args;
17383e457fe3SDavid van Moolenbroek     MagicUtil::createCallInstruction(magicInitFunc, args, "", magicEntryPointFunc->getBasicBlockList().begin()->begin());
17393e457fe3SDavid van Moolenbroek 
17403e457fe3SDavid van Moolenbroek     //check invariants
17413e457fe3SDavid van Moolenbroek #if MAGIC_CHECK_INVARIANTS
17423e457fe3SDavid van Moolenbroek     if(maxRecursiveSequenceLength > MAGIC_MAX_RECURSIVE_TYPES) {
17433e457fe3SDavid van Moolenbroek         magicPassErr("Max recursive sequence length is: " << maxRecursiveSequenceLength);
17443e457fe3SDavid van Moolenbroek     }
17453e457fe3SDavid van Moolenbroek     assert(maxRecursiveSequenceLength <= MAGIC_MAX_RECURSIVE_TYPES && "MAGIC_MAX_RECURSIVE_TYPES is too small!");
17463e457fe3SDavid van Moolenbroek     if(TypeInfo::getMaxNameLength() > MAGIC_MAX_NAME_LEN) {
17473e457fe3SDavid van Moolenbroek         magicPassErr("Max name length is: " << TypeInfo::getMaxNameLength());
17483e457fe3SDavid van Moolenbroek     }
17493e457fe3SDavid van Moolenbroek     assert(TypeInfo::getMaxNameLength() <= MAGIC_MAX_NAME_LEN && "MAGIC_MAX_NAME_LEN is too small!");
17503e457fe3SDavid van Moolenbroek     if(TypeInfo::getMaxTypeStringLength() > MAGIC_MAX_TYPE_STR_LEN) {
17513e457fe3SDavid van Moolenbroek         magicPassErr("Max type string length is: " << TypeInfo::getMaxTypeStringLength());
17523e457fe3SDavid van Moolenbroek     }
17533e457fe3SDavid van Moolenbroek     assert(TypeInfo::getMaxTypeStringLength() <= MAGIC_MAX_TYPE_STR_LEN && "MAGIC_MAX_TYPE_STR_LEN is too small!");
17543e457fe3SDavid van Moolenbroek #endif
17553e457fe3SDavid van Moolenbroek 
17563e457fe3SDavid van Moolenbroek     return true;
17573e457fe3SDavid van Moolenbroek }
17583e457fe3SDavid van Moolenbroek 
17593e457fe3SDavid van Moolenbroek //===----------------------------------------------------------------------===//
17603e457fe3SDavid van Moolenbroek // Private methods
17613e457fe3SDavid van Moolenbroek //===----------------------------------------------------------------------===//
17623e457fe3SDavid van Moolenbroek 
17633e457fe3SDavid van Moolenbroek static std::vector<int> currPtrVarIndexes;
17643e457fe3SDavid van Moolenbroek static std::set< std::pair<Value*,std::vector<int> > > visitedValues;
17653e457fe3SDavid van Moolenbroek 
checkPointerVariableIndexes(TYPECONST Type * type,std::vector<int> & ptrVarIndexes,unsigned offset)17663e457fe3SDavid van Moolenbroek bool MagicPass::checkPointerVariableIndexes(TYPECONST Type *type, std::vector<int> &ptrVarIndexes, unsigned offset)
17673e457fe3SDavid van Moolenbroek {
17683e457fe3SDavid van Moolenbroek     if(offset >= ptrVarIndexes.size()) {
17693e457fe3SDavid van Moolenbroek         return true;
17703e457fe3SDavid van Moolenbroek     }
17713e457fe3SDavid van Moolenbroek     unsigned ptrVarIndex = (unsigned) ptrVarIndexes[ptrVarIndexes.size()-1 - offset];
17723e457fe3SDavid van Moolenbroek     if(ptrVarIndex >= type->getNumContainedTypes()) {
17733e457fe3SDavid van Moolenbroek         return false;
17743e457fe3SDavid van Moolenbroek     }
17753e457fe3SDavid van Moolenbroek     return checkPointerVariableIndexes(type->getContainedType(ptrVarIndex), ptrVarIndexes, offset+1);
17763e457fe3SDavid van Moolenbroek }
17773e457fe3SDavid van Moolenbroek 
findPointerVariables(Function * function,Value * value,std::vector<Value * > & ptrVars,std::vector<std::vector<int>> & ptrVarIndexes,Value * parent,bool isUser)17783e457fe3SDavid van Moolenbroek void MagicPass::findPointerVariables(Function* function, Value *value, std::vector<Value*> &ptrVars, std::vector<std::vector<int> > &ptrVarIndexes, Value *parent, bool isUser)
17793e457fe3SDavid van Moolenbroek {
17803e457fe3SDavid van Moolenbroek 
17813e457fe3SDavid van Moolenbroek #define RETURN_IF(X) do{ if(X){ return; } } while(0)
17823e457fe3SDavid van Moolenbroek #define DEBUG_VALUE(M, V) do{ if(DEBUG_ALLOC_LEVEL >= 2) { errs() << M; V->print(errs()); errs() << "\n"; } } while(0)
17833e457fe3SDavid van Moolenbroek #define DEBUG_INDEXES() do{ if(DEBUG_ALLOC_LEVEL >= 3) { errs() << ">>> Indexes: "; for(unsigned i=0;i<currPtrVarIndexes.size();i++) errs() << currPtrVarIndexes[i] << " "; errs() << "\n"; } } while(0)
17843e457fe3SDavid van Moolenbroek 
17853e457fe3SDavid van Moolenbroek     std::pair<Value*,std::vector<int> > visitedPair(value, currPtrVarIndexes);
17863e457fe3SDavid van Moolenbroek     if(visitedValues.find(visitedPair) != visitedValues.end()) {
17873e457fe3SDavid van Moolenbroek         return;
17883e457fe3SDavid van Moolenbroek     }
17893e457fe3SDavid van Moolenbroek 
17903e457fe3SDavid van Moolenbroek     DEBUG_VALUE(" >>>> findPointerVariables: Value is: ", value);
17913e457fe3SDavid van Moolenbroek     DEBUG_VALUE(" >>>> findPointerVariables: Parent value is: ", parent);
17923e457fe3SDavid van Moolenbroek     DEBUG_INDEXES();
17933e457fe3SDavid van Moolenbroek     std::vector<int> savedPtrVarIndexes;
17943e457fe3SDavid van Moolenbroek     visitedValues.insert(visitedPair);
17953e457fe3SDavid van Moolenbroek     ConstantExpr *constantExpr = dyn_cast<ConstantExpr>(value);
17963e457fe3SDavid van Moolenbroek     if(currPtrVarIndexes.size() == 0) {
17973e457fe3SDavid van Moolenbroek         if(DEBUG_ALLOC_LEVEL >= 2) {
17983e457fe3SDavid van Moolenbroek             magicPassErr("Empty indexes, skipping search path!");
17993e457fe3SDavid van Moolenbroek         }
18003e457fe3SDavid van Moolenbroek         RETURN_IF(true);
18013e457fe3SDavid van Moolenbroek     }
18023e457fe3SDavid van Moolenbroek     else if(GlobalVariable *GV = dyn_cast<GlobalVariable>(value)) {
18033e457fe3SDavid van Moolenbroek         if(DEBUG_ALLOC_LEVEL >= 2) {
18043e457fe3SDavid van Moolenbroek             magicPassErr("Found global variable!");
18053e457fe3SDavid van Moolenbroek         }
18063e457fe3SDavid van Moolenbroek         ptrVars.push_back(GV);
18073e457fe3SDavid van Moolenbroek         ptrVarIndexes.push_back(currPtrVarIndexes);
18083e457fe3SDavid van Moolenbroek         assert(!isUser);
18093e457fe3SDavid van Moolenbroek         if(GV->getType()->getElementType() != PointerType::get(IntegerType::get(function->getParent()->getContext(), 8), 0)) {
18103e457fe3SDavid van Moolenbroek             RETURN_IF(true);
18113e457fe3SDavid van Moolenbroek         }
18123e457fe3SDavid van Moolenbroek     }
18133e457fe3SDavid van Moolenbroek     else if(AllocaInst *AI = dyn_cast<AllocaInst>(value)) {
18143e457fe3SDavid van Moolenbroek         if(DEBUG_ALLOC_LEVEL >= 2) {
18153e457fe3SDavid van Moolenbroek             magicPassErr("Found local variable!");
18163e457fe3SDavid van Moolenbroek         }
18173e457fe3SDavid van Moolenbroek         ptrVars.push_back(AI);
18183e457fe3SDavid van Moolenbroek         ptrVarIndexes.push_back(currPtrVarIndexes);
18193e457fe3SDavid van Moolenbroek         assert(!isUser);
18203e457fe3SDavid van Moolenbroek         if(AI->getAllocatedType() != PointerType::get(IntegerType::get(function->getParent()->getContext(), 8), 0)) {
18213e457fe3SDavid van Moolenbroek             RETURN_IF(true);
18223e457fe3SDavid van Moolenbroek         }
18233e457fe3SDavid van Moolenbroek     }
18243e457fe3SDavid van Moolenbroek     else if(dyn_cast<ReturnInst>(value)) {
18253e457fe3SDavid van Moolenbroek         if(DEBUG_ALLOC_LEVEL >= 2) {
18263e457fe3SDavid van Moolenbroek             magicPassErr("Found return variable!");
18273e457fe3SDavid van Moolenbroek         }
18283e457fe3SDavid van Moolenbroek         assert(isUser);
18293e457fe3SDavid van Moolenbroek         RETURN_IF(true);
18303e457fe3SDavid van Moolenbroek     }
18313e457fe3SDavid van Moolenbroek     else if(StoreInst *SI = dyn_cast<StoreInst>(value)) {
18323e457fe3SDavid van Moolenbroek         DEBUG_VALUE(" >>>> findPointerVariables: Digging store instruction: ", value);
18333e457fe3SDavid van Moolenbroek         assert(isUser);
18343e457fe3SDavid van Moolenbroek         if(parent == SI->getOperand(1)) {
18353e457fe3SDavid van Moolenbroek             assert(currPtrVarIndexes.size() > 0 && currPtrVarIndexes[currPtrVarIndexes.size()-1] == 0);
18363e457fe3SDavid van Moolenbroek             currPtrVarIndexes.pop_back();
18373e457fe3SDavid van Moolenbroek             findPointerVariables(function, SI->getOperand(0), ptrVars, ptrVarIndexes, value);
18383e457fe3SDavid van Moolenbroek             currPtrVarIndexes.push_back(0);
18393e457fe3SDavid van Moolenbroek         }
18403e457fe3SDavid van Moolenbroek         else {
18413e457fe3SDavid van Moolenbroek             currPtrVarIndexes.push_back(0);
18423e457fe3SDavid van Moolenbroek             findPointerVariables(function, SI->getOperand(1), ptrVars, ptrVarIndexes, value);
18433e457fe3SDavid van Moolenbroek             currPtrVarIndexes.pop_back();
18443e457fe3SDavid van Moolenbroek         }
18453e457fe3SDavid van Moolenbroek     }
18463e457fe3SDavid van Moolenbroek     else if(LoadInst *LI = dyn_cast<LoadInst>(value)) {
18473e457fe3SDavid van Moolenbroek         DEBUG_VALUE(" >>>> findPointerVariables: Digging load instruction: ", value);
18483e457fe3SDavid van Moolenbroek         if(isUser) {
18493e457fe3SDavid van Moolenbroek             assert(currPtrVarIndexes.size() > 0 && currPtrVarIndexes[currPtrVarIndexes.size()-1] == 0);
18503e457fe3SDavid van Moolenbroek             savedPtrVarIndexes.push_back(currPtrVarIndexes.back());
18513e457fe3SDavid van Moolenbroek             currPtrVarIndexes.pop_back();
18523e457fe3SDavid van Moolenbroek         }
18533e457fe3SDavid van Moolenbroek         else {
18543e457fe3SDavid van Moolenbroek             currPtrVarIndexes.push_back(0);
18553e457fe3SDavid van Moolenbroek             findPointerVariables(function, LI->getOperand(0), ptrVars, ptrVarIndexes, value);
18563e457fe3SDavid van Moolenbroek             currPtrVarIndexes.pop_back();
18573e457fe3SDavid van Moolenbroek         }
18583e457fe3SDavid van Moolenbroek     }
18593e457fe3SDavid van Moolenbroek     else if(GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(value)) {
18603e457fe3SDavid van Moolenbroek         if(GEPI->getNumIndices() == 1) {
18613e457fe3SDavid van Moolenbroek             DEBUG_VALUE(" >>>> findPointerVariables: Digging GEP instruction: ", value);
18623e457fe3SDavid van Moolenbroek             findPointerVariables(function, GEPI->getOperand(0), ptrVars, ptrVarIndexes, value);
18633e457fe3SDavid van Moolenbroek         }
18643e457fe3SDavid van Moolenbroek         else {
18653e457fe3SDavid van Moolenbroek             RETURN_IF(isUser);
18663e457fe3SDavid van Moolenbroek             DEBUG_VALUE(" >>>> findPointerVariables: Digging GEP instruction: ", value);
18673e457fe3SDavid van Moolenbroek             unsigned k = 0;
18683e457fe3SDavid van Moolenbroek             int index;
18693e457fe3SDavid van Moolenbroek             assert(currPtrVarIndexes.size() > 0 && currPtrVarIndexes[currPtrVarIndexes.size()-1] == 0);
18703e457fe3SDavid van Moolenbroek             currPtrVarIndexes.pop_back(); //pop 0
18713e457fe3SDavid van Moolenbroek             for(GetElementPtrInst::const_op_iterator i=GEPI->idx_end()-1, b=GEPI->idx_begin();i>b;i--,k++) {
18723e457fe3SDavid van Moolenbroek                 index = 0;
18733e457fe3SDavid van Moolenbroek                 if(ConstantInt *CI = dyn_cast<ConstantInt>(*i)) {
18743e457fe3SDavid van Moolenbroek                     index = CI->getSExtValue();
18753e457fe3SDavid van Moolenbroek                 }
18763e457fe3SDavid van Moolenbroek                 currPtrVarIndexes.push_back(index);
18773e457fe3SDavid van Moolenbroek             }
18783e457fe3SDavid van Moolenbroek             currPtrVarIndexes.push_back(0); //push 0
18793e457fe3SDavid van Moolenbroek             findPointerVariables(function, GEPI->getOperand(0), ptrVars, ptrVarIndexes, value);
18803e457fe3SDavid van Moolenbroek             currPtrVarIndexes.pop_back();   //pop 0
18813e457fe3SDavid van Moolenbroek             while(k-->0) {
18823e457fe3SDavid van Moolenbroek                 currPtrVarIndexes.pop_back();
18833e457fe3SDavid van Moolenbroek             }
18843e457fe3SDavid van Moolenbroek             currPtrVarIndexes.push_back(0); //push 0
18853e457fe3SDavid van Moolenbroek         }
18863e457fe3SDavid van Moolenbroek     }
18873e457fe3SDavid van Moolenbroek     else if(constantExpr && constantExpr->getOpcode() == Instruction::GetElementPtr) {
18883e457fe3SDavid van Moolenbroek         assert(constantExpr->getNumOperands() >= 2);
18893e457fe3SDavid van Moolenbroek         if(constantExpr->getNumOperands() == 2) {
18903e457fe3SDavid van Moolenbroek             DEBUG_VALUE(" >>>> findPointerVariables: Digging GEP expression: ", value);
18913e457fe3SDavid van Moolenbroek             findPointerVariables(function, constantExpr->getOperand(0), ptrVars, ptrVarIndexes, value);
18923e457fe3SDavid van Moolenbroek         }
18933e457fe3SDavid van Moolenbroek         else {
18943e457fe3SDavid van Moolenbroek             RETURN_IF(isUser);
18953e457fe3SDavid van Moolenbroek             DEBUG_VALUE(" >>>> findPointerVariables: Digging GEP expression: ", value);
18963e457fe3SDavid van Moolenbroek             unsigned k = 0;
18973e457fe3SDavid van Moolenbroek             int index;
18983e457fe3SDavid van Moolenbroek             assert(currPtrVarIndexes.size() > 0 && currPtrVarIndexes[currPtrVarIndexes.size()-1] == 0);
18993e457fe3SDavid van Moolenbroek             currPtrVarIndexes.pop_back(); //pop 0
19003e457fe3SDavid van Moolenbroek             for(unsigned i=constantExpr->getNumOperands()-1;i>1;i--,k++) {
19013e457fe3SDavid van Moolenbroek                 index = 0;
19023e457fe3SDavid van Moolenbroek                 if(ConstantInt *CI = dyn_cast<ConstantInt>(constantExpr->getOperand(i))) {
19033e457fe3SDavid van Moolenbroek                     index = CI->getSExtValue();
19043e457fe3SDavid van Moolenbroek                 }
19053e457fe3SDavid van Moolenbroek                 currPtrVarIndexes.push_back(index);
19063e457fe3SDavid van Moolenbroek             }
19073e457fe3SDavid van Moolenbroek             currPtrVarIndexes.push_back(0); //push 0
19083e457fe3SDavid van Moolenbroek             findPointerVariables(function, constantExpr->getOperand(0), ptrVars, ptrVarIndexes, value);
19093e457fe3SDavid van Moolenbroek             currPtrVarIndexes.pop_back();   //pop 0
19103e457fe3SDavid van Moolenbroek             while(k-->0) {
19113e457fe3SDavid van Moolenbroek                 currPtrVarIndexes.pop_back();
19123e457fe3SDavid van Moolenbroek             }
19133e457fe3SDavid van Moolenbroek             currPtrVarIndexes.push_back(0); //push 0
19143e457fe3SDavid van Moolenbroek         }
19153e457fe3SDavid van Moolenbroek     }
19163e457fe3SDavid van Moolenbroek     else if(BitCastInst *CI = dyn_cast<BitCastInst>(value)) {
19173e457fe3SDavid van Moolenbroek         if((isUser && !checkPointerVariableIndexes(CI->getType(), currPtrVarIndexes))
19183e457fe3SDavid van Moolenbroek             || (!isUser && !checkPointerVariableIndexes(CI->getOperand(0)->getType(), currPtrVarIndexes))) {
19193e457fe3SDavid van Moolenbroek             DEBUG_VALUE(" >>>> findPointerVariables: Skipping unsafe cast instruction: ", value);
19203e457fe3SDavid van Moolenbroek             RETURN_IF(true);
19213e457fe3SDavid van Moolenbroek         }
19223e457fe3SDavid van Moolenbroek         DEBUG_VALUE(" >>>> findPointerVariables: Digging cast instruction: ", value);
19233e457fe3SDavid van Moolenbroek         findPointerVariables(function, CI->getOperand(0), ptrVars, ptrVarIndexes, value);
19243e457fe3SDavid van Moolenbroek     }
19253e457fe3SDavid van Moolenbroek     else if(dyn_cast<CallInst>(value) || dyn_cast<InvokeInst>(value)) {
19263e457fe3SDavid van Moolenbroek         RETURN_IF(isUser);
19273e457fe3SDavid van Moolenbroek         DEBUG_VALUE(" >>>> findPointerVariables: found call instruction: ", value);
19283e457fe3SDavid van Moolenbroek     }
19293e457fe3SDavid van Moolenbroek     else if(CmpInst *CI = dyn_cast<CmpInst>(value)) {
19303e457fe3SDavid van Moolenbroek         assert(isUser);
19313e457fe3SDavid van Moolenbroek         DEBUG_VALUE(" >>>> findPointerVariables: Digging cmp instruction: ", value);
19323e457fe3SDavid van Moolenbroek         findPointerVariables(function, CI->getOperand(0), ptrVars, ptrVarIndexes, value);
19333e457fe3SDavid van Moolenbroek         findPointerVariables(function, CI->getOperand(1), ptrVars, ptrVarIndexes, value);
19343e457fe3SDavid van Moolenbroek         RETURN_IF(true);
19353e457fe3SDavid van Moolenbroek     }
19363e457fe3SDavid van Moolenbroek     else if(SelectInst *SI = dyn_cast<SelectInst>(value)) {
19373e457fe3SDavid van Moolenbroek         DEBUG_VALUE(" >>>> findPointerVariables: Digging select instruction: ", value);
19383e457fe3SDavid van Moolenbroek         findPointerVariables(function, SI->getOperand(1), ptrVars, ptrVarIndexes, value);
19393e457fe3SDavid van Moolenbroek         findPointerVariables(function, SI->getOperand(2), ptrVars, ptrVarIndexes, value);
19403e457fe3SDavid van Moolenbroek     }
19413e457fe3SDavid van Moolenbroek     else if(constantExpr && constantExpr->getOpcode() == Instruction::Select) {
19423e457fe3SDavid van Moolenbroek         DEBUG_VALUE(" >>>> findPointerVariables: Digging select expression: ", value);
19433e457fe3SDavid van Moolenbroek         findPointerVariables(function, constantExpr->getOperand(1), ptrVars, ptrVarIndexes, value);
19443e457fe3SDavid van Moolenbroek         findPointerVariables(function, constantExpr->getOperand(2), ptrVars, ptrVarIndexes, value);
19453e457fe3SDavid van Moolenbroek     }
19463e457fe3SDavid van Moolenbroek     else if(PHINode *PN = dyn_cast<PHINode>(value)) {
19473e457fe3SDavid van Moolenbroek         DEBUG_VALUE(" >>>> findPointerVariables: Digging PHI instruction: ", value);
19483e457fe3SDavid van Moolenbroek         for(unsigned i=0;i<PN->getNumIncomingValues();i++) {
19493e457fe3SDavid van Moolenbroek             findPointerVariables(function, PN->getIncomingValue(i), ptrVars, ptrVarIndexes, value);
19503e457fe3SDavid van Moolenbroek         }
19513e457fe3SDavid van Moolenbroek     }
19523e457fe3SDavid van Moolenbroek     else if(Argument *ARG = dyn_cast<Argument>(value)) {
19533e457fe3SDavid van Moolenbroek         DEBUG_VALUE(" >>>> findPointerVariables: Digging Argument: ", value);
19543e457fe3SDavid van Moolenbroek         AllocaInst *AI = MagicUtil::getAllocaInstFromArgument(ARG);
19553e457fe3SDavid van Moolenbroek         assert(AI);
19563e457fe3SDavid van Moolenbroek         currPtrVarIndexes.push_back(0);
19573e457fe3SDavid van Moolenbroek         findPointerVariables(function, AI, ptrVars, ptrVarIndexes, value);
19583e457fe3SDavid van Moolenbroek         currPtrVarIndexes.pop_back();
19593e457fe3SDavid van Moolenbroek         RETURN_IF(true);
19603e457fe3SDavid van Moolenbroek     }
19613e457fe3SDavid van Moolenbroek     else {
19623e457fe3SDavid van Moolenbroek         DEBUG_VALUE(" ************************************************************ findPointerVariables: Unknown value: ", value);
19633e457fe3SDavid van Moolenbroek         RETURN_IF(true);
19643e457fe3SDavid van Moolenbroek     }
1965*bdb56518SDavid van Moolenbroek     for (Value::user_iterator i = value->user_begin(), e = value->user_end(); i != e; ++i) {
19663e457fe3SDavid van Moolenbroek         User *user = *i;
19673e457fe3SDavid van Moolenbroek         Instruction *instruction = dyn_cast<Instruction>(user);
19683e457fe3SDavid van Moolenbroek         if(!instruction || instruction->getParent()->getParent() != function) {
19693e457fe3SDavid van Moolenbroek             continue;
19703e457fe3SDavid van Moolenbroek         }
19713e457fe3SDavid van Moolenbroek         DEBUG_VALUE(" >>>> findPointerVariables: Found user: ", user);
19723e457fe3SDavid van Moolenbroek         findPointerVariables(function, user, ptrVars, ptrVarIndexes, value, true);
19733e457fe3SDavid van Moolenbroek     }
19743e457fe3SDavid van Moolenbroek     while(savedPtrVarIndexes.size() > 0) {
19753e457fe3SDavid van Moolenbroek         currPtrVarIndexes.push_back(savedPtrVarIndexes.back());
19763e457fe3SDavid van Moolenbroek         savedPtrVarIndexes.pop_back();
19773e457fe3SDavid van Moolenbroek     }
19783e457fe3SDavid van Moolenbroek }
19793e457fe3SDavid van Moolenbroek 
typeInfoFromPointerVariables(Module & M,TypeInfo * voidPtrTypeInfo,std::vector<Value * > & ptrVars,std::vector<std::vector<int>> & ptrVarIndexes,std::string & allocName)19803e457fe3SDavid van Moolenbroek TypeInfo* MagicPass::typeInfoFromPointerVariables(Module &M, TypeInfo *voidPtrTypeInfo, std::vector<Value*> &ptrVars, std::vector<std::vector<int> > &ptrVarIndexes, std::string &allocName)
19813e457fe3SDavid van Moolenbroek {
19823e457fe3SDavid van Moolenbroek     std::vector<TypeInfo*> validTypeInfos;
19833e457fe3SDavid van Moolenbroek     std::set<TypeInfo*> validTypeInfoSet;
19843e457fe3SDavid van Moolenbroek     std::vector<unsigned> validTypeTags;
19853e457fe3SDavid van Moolenbroek     std::vector<unsigned> voidTypeTags;
19863e457fe3SDavid van Moolenbroek     std::vector<int> indexes;
19873e457fe3SDavid van Moolenbroek     TypeInfo *aTypeInfo = NULL;
19883e457fe3SDavid van Moolenbroek     TypeInfo *voidTypeInfo = voidPtrTypeInfo->getContainedType(0);
19893e457fe3SDavid van Moolenbroek     allocName = "";
19903e457fe3SDavid van Moolenbroek     if(ptrVars.size()==0) {
19913e457fe3SDavid van Moolenbroek         return voidTypeInfo;
19923e457fe3SDavid van Moolenbroek     }
19933e457fe3SDavid van Moolenbroek 
19943e457fe3SDavid van Moolenbroek     for(unsigned i=0;i<ptrVars.size();i++) {
19953e457fe3SDavid van Moolenbroek         DIVariable DIV;
19963e457fe3SDavid van Moolenbroek         unsigned tag = 0;
19973e457fe3SDavid van Moolenbroek         std::string varName = "";
19983e457fe3SDavid van Moolenbroek         if(GlobalVariable *GV = dyn_cast<GlobalVariable>(ptrVars[i])) {
19993e457fe3SDavid van Moolenbroek             parentMapIt = globalParentMap.find(GV);
20003e457fe3SDavid van Moolenbroek             assert(parentMapIt != globalParentMap.end());
20013e457fe3SDavid van Moolenbroek             aTypeInfo = parentMapIt->second;
20023e457fe3SDavid van Moolenbroek             tag = dwarf::DW_TAG_variable;
20033e457fe3SDavid van Moolenbroek             varName = MagicUtil::getGVSourceName(M, GV, NULL, baseBuildDir);
20043e457fe3SDavid van Moolenbroek         }
20053e457fe3SDavid van Moolenbroek         else {
20063e457fe3SDavid van Moolenbroek             AllocaInst *AI = dyn_cast<AllocaInst>(ptrVars[i]);
20073e457fe3SDavid van Moolenbroek             assert(AI);
20083e457fe3SDavid van Moolenbroek             if(DEBUG_ALLOC_LEVEL >= 4) {
20093e457fe3SDavid van Moolenbroek             	AI->print(errs()); errs() << "\n";
20103e457fe3SDavid van Moolenbroek             }
20113e457fe3SDavid van Moolenbroek             const SmartType *aSmartType = SmartType::getSmartTypeFromLV(M, AI, &DIV);
20123e457fe3SDavid van Moolenbroek             if(aSmartType == (const SmartType *)-1) {
20133e457fe3SDavid van Moolenbroek                 //a temporary variable
20143e457fe3SDavid van Moolenbroek                 if(DEBUG_ALLOC_LEVEL >= 4) {
20153e457fe3SDavid van Moolenbroek                     magicPassErr("typeInfoFromPointerVariables: Skipping temporary variable");
20163e457fe3SDavid van Moolenbroek                 }
20173e457fe3SDavid van Moolenbroek                 continue;
20183e457fe3SDavid van Moolenbroek             }
20193e457fe3SDavid van Moolenbroek             else if(!aSmartType) {
20203e457fe3SDavid van Moolenbroek                 //a return variable
20213e457fe3SDavid van Moolenbroek                 if(DEBUG_ALLOC_LEVEL >= 4) {
20223e457fe3SDavid van Moolenbroek                     magicPassErr("typeInfoFromPointerVariables: Processing return variable");
20233e457fe3SDavid van Moolenbroek                 }
20243e457fe3SDavid van Moolenbroek                 if(AI->getAllocatedType() == voidPtrTypeInfo->getType()) {
20253e457fe3SDavid van Moolenbroek                     aTypeInfo = voidPtrTypeInfo;
20263e457fe3SDavid van Moolenbroek                 }
20273e457fe3SDavid van Moolenbroek                 else {
20283e457fe3SDavid van Moolenbroek                     aTypeInfo = fillExternalTypeInfos(AI->getAllocatedType(), NULL, globalTypeInfos);
20293e457fe3SDavid van Moolenbroek                     if(aTypeInfo == NULL) {
20303e457fe3SDavid van Moolenbroek                         magicPassErr("typeInfoFromPointerVariables: type is: " << TypeUtil::getDescription(AI->getAllocatedType(), MAGIC_TYPE_STR_PRINT_MAX, MAGIC_TYPE_STR_PRINT_MAX_LEVEL));
20313e457fe3SDavid van Moolenbroek                         if(!MAGIC_ABORT_ON_UNSUPPORTED_LOCAL_EXTERNAL_TYPE) {
20323e457fe3SDavid van Moolenbroek                             magicPassErr("typeInfoFromPointerVariables: Warning: Local external type not supported, resorting to void* type...");
20333e457fe3SDavid van Moolenbroek                             aTypeInfo = voidPtrTypeInfo;
20343e457fe3SDavid van Moolenbroek                         }
20353e457fe3SDavid van Moolenbroek                         else {
20363e457fe3SDavid van Moolenbroek                             assert(aTypeInfo != NULL && "Local external type not supported!");
20373e457fe3SDavid van Moolenbroek                         }
20383e457fe3SDavid van Moolenbroek                     }
20393e457fe3SDavid van Moolenbroek                 }
20403e457fe3SDavid van Moolenbroek                 tag = dwarf::DW_TAG_unspecified_type;
20413e457fe3SDavid van Moolenbroek             }
20423e457fe3SDavid van Moolenbroek             else {
20433e457fe3SDavid van Moolenbroek                 //a regular variable (potentially returning a value to the caller)
20443e457fe3SDavid van Moolenbroek                 if(DEBUG_ALLOC_LEVEL >= 4) {
20453e457fe3SDavid van Moolenbroek                     magicPassErr("typeInfoFromPointerVariables: Processing regular variable");
20463e457fe3SDavid van Moolenbroek                 }
20473e457fe3SDavid van Moolenbroek                 TypeInfo newTypeInfo(aSmartType);
20483e457fe3SDavid van Moolenbroek                 aTypeInfo = fillTypeInfos(newTypeInfo, globalTypeInfos);
20493e457fe3SDavid van Moolenbroek                 if(aTypeInfo->getSmartType() != aSmartType) {
20503e457fe3SDavid van Moolenbroek                     delete aSmartType;
20513e457fe3SDavid van Moolenbroek                 }
20523e457fe3SDavid van Moolenbroek                 if (PassUtil::isReturnedValue(AI->getParent()->getParent(), AI)) {
20533e457fe3SDavid van Moolenbroek                     // treat this variable as a return variable
20543e457fe3SDavid van Moolenbroek                     tag = dwarf::DW_TAG_unspecified_type;
20553e457fe3SDavid van Moolenbroek                 }
20563e457fe3SDavid van Moolenbroek                 else {
20573e457fe3SDavid van Moolenbroek                     tag = DIV.getTag();
20583e457fe3SDavid van Moolenbroek                 }
20593e457fe3SDavid van Moolenbroek             }
20603e457fe3SDavid van Moolenbroek             varName = DIV.getName();
20613e457fe3SDavid van Moolenbroek         }
20623e457fe3SDavid van Moolenbroek         //see if the target type is an alias for void*
20633e457fe3SDavid van Moolenbroek         assert(aTypeInfo);
20643e457fe3SDavid van Moolenbroek         if(aTypeInfo->getType()->isPointerTy()) {
20653e457fe3SDavid van Moolenbroek             stringSetIt = voidTypeAliasesSet.find(aTypeInfo->getContainedType(0)->getName());
20663e457fe3SDavid van Moolenbroek             if(stringSetIt != voidTypeAliasesSet.end()) {
20673e457fe3SDavid van Moolenbroek                 aTypeInfo = voidPtrTypeInfo;
20683e457fe3SDavid van Moolenbroek             }
20693e457fe3SDavid van Moolenbroek         }
20703e457fe3SDavid van Moolenbroek         //fix tag if needed
20713e457fe3SDavid van Moolenbroek         if(tag == dwarf::DW_TAG_unspecified_type) {
20723e457fe3SDavid van Moolenbroek             TYPECONST Type *type = aTypeInfo->getType();
20733e457fe3SDavid van Moolenbroek             if(!type->isPointerTy() || type->getContainedType(0)->isPointerTy()) {
20743e457fe3SDavid van Moolenbroek                 //not a good return type, switch to a regular variable
20753e457fe3SDavid van Moolenbroek                 tag = dwarf::DW_TAG_auto_variable;
20763e457fe3SDavid van Moolenbroek             }
20773e457fe3SDavid van Moolenbroek         }
20783e457fe3SDavid van Moolenbroek         if(tag == dwarf::DW_TAG_arg_variable) {
20793e457fe3SDavid van Moolenbroek             TYPECONST Type *type = aTypeInfo->getType();
20803e457fe3SDavid van Moolenbroek             if(!type->isPointerTy() || !type->getContainedType(0)->isPointerTy() || type->getContainedType(0)->getContainedType(0)->isPointerTy()) {
20813e457fe3SDavid van Moolenbroek                 //not a good arg type, switch to a regular variable
20823e457fe3SDavid van Moolenbroek                 tag = dwarf::DW_TAG_auto_variable;
20833e457fe3SDavid van Moolenbroek             }
20843e457fe3SDavid van Moolenbroek         }
20853e457fe3SDavid van Moolenbroek         if(DEBUG_ALLOC_LEVEL >= 3) {
20863e457fe3SDavid van Moolenbroek             switch(tag) {
20873e457fe3SDavid van Moolenbroek                 case dwarf::DW_TAG_unspecified_type:
20883e457fe3SDavid van Moolenbroek                     magicPassErr("typeInfoFromPointerVariables: Found return variable: " << varName);
20893e457fe3SDavid van Moolenbroek                 break;
20903e457fe3SDavid van Moolenbroek                 case dwarf::DW_TAG_variable:
20913e457fe3SDavid van Moolenbroek                     magicPassErr("typeInfoFromPointerVariables: Found global variable:" << varName);
20923e457fe3SDavid van Moolenbroek                 break;
20933e457fe3SDavid van Moolenbroek                 case dwarf::DW_TAG_auto_variable:
20943e457fe3SDavid van Moolenbroek                     magicPassErr("typeInfoFromPointerVariables: Found local variable:" << varName);
20953e457fe3SDavid van Moolenbroek                 break;
20963e457fe3SDavid van Moolenbroek                 case dwarf::DW_TAG_arg_variable:
20973e457fe3SDavid van Moolenbroek                     magicPassErr("typeInfoFromPointerVariables: Found argument variable:" << varName);
20983e457fe3SDavid van Moolenbroek                 break;
20993e457fe3SDavid van Moolenbroek                 default:
21003e457fe3SDavid van Moolenbroek                     assert(0 && "Should never get here!");
21013e457fe3SDavid van Moolenbroek                 break;
21023e457fe3SDavid van Moolenbroek             }
21033e457fe3SDavid van Moolenbroek         }
21043e457fe3SDavid van Moolenbroek         indexes = ptrVarIndexes[i];
21053e457fe3SDavid van Moolenbroek         assert(indexes.back() == 0);
21063e457fe3SDavid van Moolenbroek         indexes.pop_back();
21073e457fe3SDavid van Moolenbroek         if(DEBUG_ALLOC_LEVEL >= 4) {
21083e457fe3SDavid van Moolenbroek             magicPassErr("typeInfoFromPointerVariables: " << indexes.size() << " indexes to process.");
21093e457fe3SDavid van Moolenbroek         }
21103e457fe3SDavid van Moolenbroek         while(!indexes.empty()) {
21113e457fe3SDavid van Moolenbroek             int index = indexes.back();
21123e457fe3SDavid van Moolenbroek             if(aTypeInfo->hasRawTypeRepresentation()) {
21133e457fe3SDavid van Moolenbroek                 if(DEBUG_ALLOC_LEVEL >= 4) {
21143e457fe3SDavid van Moolenbroek                     magicPassErr("typeInfoFromPointerVariables: Skipping index (raw type representation): " << index << ", type is: " << aTypeInfo->getVerboseDescription());
21153e457fe3SDavid van Moolenbroek                 }
21163e457fe3SDavid van Moolenbroek                 aTypeInfo = voidTypeInfo;
21173e457fe3SDavid van Moolenbroek                 break;
21183e457fe3SDavid van Moolenbroek             }
21193e457fe3SDavid van Moolenbroek             if(!aTypeInfo->getType()->isStructTy()) {
21203e457fe3SDavid van Moolenbroek                 index = 0;
21213e457fe3SDavid van Moolenbroek             }
21223e457fe3SDavid van Moolenbroek             aTypeInfo = aTypeInfo->getContainedType(index);
21233e457fe3SDavid van Moolenbroek             if(DEBUG_ALLOC_LEVEL >= 4) {
21243e457fe3SDavid van Moolenbroek                 magicPassErr("typeInfoFromPointerVariables: Processing index: " << index << ", type is: " << aTypeInfo->getVerboseDescription());
21253e457fe3SDavid van Moolenbroek             }
21263e457fe3SDavid van Moolenbroek             indexes.pop_back();
21273e457fe3SDavid van Moolenbroek         }
21283e457fe3SDavid van Moolenbroek         if(aTypeInfo == voidTypeInfo) {
21293e457fe3SDavid van Moolenbroek             voidTypeTags.push_back(tag);
21303e457fe3SDavid van Moolenbroek         }
21313e457fe3SDavid van Moolenbroek         else {
21323e457fe3SDavid van Moolenbroek             validTypeInfos.push_back(aTypeInfo);
21333e457fe3SDavid van Moolenbroek             validTypeInfoSet.insert(aTypeInfo);
21343e457fe3SDavid van Moolenbroek             validTypeTags.push_back(tag);
21353e457fe3SDavid van Moolenbroek         }
21363e457fe3SDavid van Moolenbroek         if(!allocName.compare("")) {
21373e457fe3SDavid van Moolenbroek             allocName = varName;
21383e457fe3SDavid van Moolenbroek         }
21393e457fe3SDavid van Moolenbroek     }
21403e457fe3SDavid van Moolenbroek     //see if we have a valid void return type
21413e457fe3SDavid van Moolenbroek     bool hasValidVoidReturnType = false;
21423e457fe3SDavid van Moolenbroek     for(unsigned i=0;i<voidTypeTags.size();i++) {
21433e457fe3SDavid van Moolenbroek         if(voidTypeTags[i] == dwarf::DW_TAG_unspecified_type || voidTypeTags[i] == dwarf::DW_TAG_arg_variable) {
21443e457fe3SDavid van Moolenbroek             hasValidVoidReturnType = true;
21453e457fe3SDavid van Moolenbroek             break;
21463e457fe3SDavid van Moolenbroek         }
21473e457fe3SDavid van Moolenbroek     }
21483e457fe3SDavid van Moolenbroek 
21493e457fe3SDavid van Moolenbroek     //count the number of weak local types
21503e457fe3SDavid van Moolenbroek     unsigned numWeakLocalTypes = 0;
21513e457fe3SDavid van Moolenbroek     unsigned nonWeakTypeIndex = 0;
21523e457fe3SDavid van Moolenbroek     unsigned index = 0;
21533e457fe3SDavid van Moolenbroek     for (std::set<TypeInfo*>::iterator it=validTypeInfoSet.begin() ; it != validTypeInfoSet.end(); it++ ) {
21543e457fe3SDavid van Moolenbroek         if((*it)->getType() == voidTypeInfo->getType()) {
21553e457fe3SDavid van Moolenbroek             numWeakLocalTypes++;
21563e457fe3SDavid van Moolenbroek         } else {
21573e457fe3SDavid van Moolenbroek             nonWeakTypeIndex = index;
21583e457fe3SDavid van Moolenbroek         }
21593e457fe3SDavid van Moolenbroek         index++;
21603e457fe3SDavid van Moolenbroek     }
21613e457fe3SDavid van Moolenbroek     bool hasOnlyWeakLocalTypes = (numWeakLocalTypes == validTypeInfoSet.size());
21623e457fe3SDavid van Moolenbroek     bool hasOnlyOneNonWeakLocalType = (validTypeInfoSet.size() - numWeakLocalTypes == 1);
21633e457fe3SDavid van Moolenbroek 
21643e457fe3SDavid van Moolenbroek     if(DEBUG_ALLOC_LEVEL >= 3) {
21653e457fe3SDavid van Moolenbroek         magicPassErr("typeInfoFromPointerVariables: Status: voidTypeTagsSize=" << voidTypeTags.size() << ", hasValidVoidReturnType=" << hasValidVoidReturnType << ", hasOnlyWeakLocalTypes=" << hasOnlyWeakLocalTypes << ", hasOnlyOneNonWeakLocalType=" << hasOnlyOneNonWeakLocalType);
21663e457fe3SDavid van Moolenbroek     }
21673e457fe3SDavid van Moolenbroek 
21683e457fe3SDavid van Moolenbroek     //return NULL (treat the function as a wrapper) if we have a valid return type and only weak local types
21693e457fe3SDavid van Moolenbroek     if(hasValidVoidReturnType && hasOnlyWeakLocalTypes) {
21703e457fe3SDavid van Moolenbroek         if(DEBUG_ALLOC_LEVEL >= 3) {
21713e457fe3SDavid van Moolenbroek             magicPassErr("typeInfoFromPointerVariables: Returning no type at all: treat the function as a wrapper");
21723e457fe3SDavid van Moolenbroek         }
21733e457fe3SDavid van Moolenbroek         return NULL;
21743e457fe3SDavid van Moolenbroek     }
21753e457fe3SDavid van Moolenbroek 
21763e457fe3SDavid van Moolenbroek     //a single valid type has been found, return it
21773e457fe3SDavid van Moolenbroek     if(hasOnlyOneNonWeakLocalType || (hasOnlyWeakLocalTypes && validTypeInfoSet.size() > 0)) {
21783e457fe3SDavid van Moolenbroek         if(validTypeTags[nonWeakTypeIndex] == dwarf::DW_TAG_unspecified_type) {
21793e457fe3SDavid van Moolenbroek             if(DEBUG_ALLOC_BAD_TYPES) {
21803e457fe3SDavid van Moolenbroek                 magicPassErr("typeInfoFromPointerVariables: warning: non-void return type");
21813e457fe3SDavid van Moolenbroek             }
21823e457fe3SDavid van Moolenbroek         }
21833e457fe3SDavid van Moolenbroek         if(validTypeTags[nonWeakTypeIndex] == dwarf::DW_TAG_arg_variable) {
21843e457fe3SDavid van Moolenbroek             if(DEBUG_ALLOC_BAD_TYPES) {
21853e457fe3SDavid van Moolenbroek                 magicPassErr("typeInfoFromPointerVariables: warning: non-void arg type");
21863e457fe3SDavid van Moolenbroek             }
21873e457fe3SDavid van Moolenbroek         }
21883e457fe3SDavid van Moolenbroek         if(DEBUG_ALLOC_LEVEL >= 3) {
21893e457fe3SDavid van Moolenbroek             magicPassErr("typeInfoFromPointerVariables: Returning single valid type");
21903e457fe3SDavid van Moolenbroek         }
21913e457fe3SDavid van Moolenbroek         return validTypeInfos[nonWeakTypeIndex];
21923e457fe3SDavid van Moolenbroek     }
21933e457fe3SDavid van Moolenbroek     //multiple valid types found, print warning and resort to void
21943e457fe3SDavid van Moolenbroek     else if(validTypeInfoSet.size() > 1 && DEBUG_ALLOC_BAD_TYPES) {
21953e457fe3SDavid van Moolenbroek         magicPassErr("typeInfoFromPointerVariables: warning: multiple valid types found:");
21963e457fe3SDavid van Moolenbroek         for (std::set<TypeInfo*>::iterator it=validTypeInfoSet.begin() ; it != validTypeInfoSet.end(); it++ ) {
21973e457fe3SDavid van Moolenbroek             magicPassErr(" - " << (*it)->getVerboseDescription());
21983e457fe3SDavid van Moolenbroek         }
21993e457fe3SDavid van Moolenbroek         if(DEBUG_ALLOC_LEVEL >= 3) {
22003e457fe3SDavid van Moolenbroek             magicPassErr("typeInfoFromPointerVariables: Multiple valid types found");
22013e457fe3SDavid van Moolenbroek         }
22023e457fe3SDavid van Moolenbroek     }
22033e457fe3SDavid van Moolenbroek 
22043e457fe3SDavid van Moolenbroek     if(DEBUG_ALLOC_LEVEL >= 3) {
22053e457fe3SDavid van Moolenbroek         magicPassErr("typeInfoFromPointerVariables: Returning default void type");
22063e457fe3SDavid van Moolenbroek     }
22073e457fe3SDavid van Moolenbroek     return voidTypeInfo;
22083e457fe3SDavid van Moolenbroek }
22093e457fe3SDavid van Moolenbroek 
getAllocTypeInfo(Module & M,TypeInfo * voidPtrTypeInfo,const CallSite & CS,std::string & allocName,std::string & allocParentName)22103e457fe3SDavid van Moolenbroek TypeInfo* MagicPass::getAllocTypeInfo(Module &M, TypeInfo *voidPtrTypeInfo, const CallSite &CS, std::string &allocName, std::string &allocParentName)
22113e457fe3SDavid van Moolenbroek {
22123e457fe3SDavid van Moolenbroek     Value *allocPointer = NULL;
22133e457fe3SDavid van Moolenbroek     Function *function = MagicUtil::getCalledFunctionFromCS(CS);
22143e457fe3SDavid van Moolenbroek     Function *parentFunction = CS.getInstruction()->getParent()->getParent();
22153e457fe3SDavid van Moolenbroek     if(DEBUG_ALLOC_LEVEL >= 1) {
22163e457fe3SDavid van Moolenbroek         magicPassErr("Function is: " << function->getName());
22173e457fe3SDavid van Moolenbroek         magicPassErr("Parent is: " << parentFunction->getName());
22183e457fe3SDavid van Moolenbroek     }
22193e457fe3SDavid van Moolenbroek     std::vector<Value*> ptrVars;
22203e457fe3SDavid van Moolenbroek     std::vector<std::vector<int> > ptrVarIndexes;
22213e457fe3SDavid van Moolenbroek     currPtrVarIndexes.clear();
22223e457fe3SDavid van Moolenbroek     visitedValues.clear();
22233e457fe3SDavid van Moolenbroek     int pointerParam = MagicMemFunction::getMemFunctionPointerParam(function, brkFunctions, voidPtrTypeInfo);
22243e457fe3SDavid van Moolenbroek     assert(pointerParam >= 0 && "Invalid wrapper function!");
22253e457fe3SDavid van Moolenbroek     if(pointerParam == 0) {
22263e457fe3SDavid van Moolenbroek         allocPointer = CS.getInstruction();
22273e457fe3SDavid van Moolenbroek         currPtrVarIndexes.push_back(0);
22283e457fe3SDavid van Moolenbroek     }
22293e457fe3SDavid van Moolenbroek     else {
22303e457fe3SDavid van Moolenbroek         allocPointer = CS.getArgument(pointerParam-1);
22313e457fe3SDavid van Moolenbroek         currPtrVarIndexes.push_back(0);
22323e457fe3SDavid van Moolenbroek         //brk is a special case and takes the pointer by value
22333e457fe3SDavid van Moolenbroek         if(brkFunctions.find(function) == brkFunctions.end()) {
22343e457fe3SDavid van Moolenbroek             currPtrVarIndexes.push_back(0);
22353e457fe3SDavid van Moolenbroek         }
22363e457fe3SDavid van Moolenbroek     }
22373e457fe3SDavid van Moolenbroek     findPointerVariables(parentFunction, allocPointer, ptrVars, ptrVarIndexes);
22383e457fe3SDavid van Moolenbroek     TypeInfo* aTypeInfo = typeInfoFromPointerVariables(M, voidPtrTypeInfo, ptrVars, ptrVarIndexes, allocName);
22393e457fe3SDavid van Moolenbroek     allocParentName = MagicUtil::getFunctionSourceName(M, parentFunction, NULL, baseBuildDir);
22403e457fe3SDavid van Moolenbroek     if(DEBUG_ALLOC_LEVEL >= 1) {
22413e457fe3SDavid van Moolenbroek         magicPassErr("**************** type found: " << (aTypeInfo ? aTypeInfo->getType()->isStructTy() ? "struct " + aTypeInfo->getName() : aTypeInfo->getVerboseDescription() : "NULL"));
22423e457fe3SDavid van Moolenbroek     }
22433e457fe3SDavid van Moolenbroek     return aTypeInfo;
22443e457fe3SDavid van Moolenbroek }
22453e457fe3SDavid van Moolenbroek 
fillTypeInfos(TypeInfo & sourceTypeInfo,std::vector<TypeInfo * > & typeInfos)22463e457fe3SDavid van Moolenbroek TypeInfo* MagicPass::fillTypeInfos(TypeInfo &sourceTypeInfo, std::vector<TypeInfo*> &typeInfos) {
22473e457fe3SDavid van Moolenbroek     static std::vector<TypeInfo*> nestedTypes;
22483e457fe3SDavid van Moolenbroek     static unsigned level = 0;
22493e457fe3SDavid van Moolenbroek     if(DEBUG_FILL_TYPE_INFOS) {
22503e457fe3SDavid van Moolenbroek         magicPassErr("Entering level: " << level << ", Examining type: " << sourceTypeInfo.getDescription() << ", types so far: " << typeInfos.size());
22513e457fe3SDavid van Moolenbroek     }
22523e457fe3SDavid van Moolenbroek 
22533e457fe3SDavid van Moolenbroek     if(sourceTypeInfo.getType()) {
22543e457fe3SDavid van Moolenbroek         TYPECONST Type* type = sourceTypeInfo.getType();
22553e457fe3SDavid van Moolenbroek         for(unsigned i=0;i<nestedTypes.size();i++) {
22563e457fe3SDavid van Moolenbroek             if(type == nestedTypes[i]->getType()) {
22573e457fe3SDavid van Moolenbroek                 const SmartType *nestedSType = nestedTypes[i]->getSmartType();
22583e457fe3SDavid van Moolenbroek                 const SmartType *sourceSType = sourceTypeInfo.getSmartType();
22593e457fe3SDavid van Moolenbroek                 if((!nestedSType && !sourceSType) || (nestedSType && sourceSType && nestedSType->getEDIType()->equals(sourceSType->getEDIType()))) {
22603e457fe3SDavid van Moolenbroek                     nestedTypes[i]->addParents(sourceTypeInfo.getParents());
22613e457fe3SDavid van Moolenbroek                     return nestedTypes[i];
22623e457fe3SDavid van Moolenbroek                 }
22633e457fe3SDavid van Moolenbroek             }
22643e457fe3SDavid van Moolenbroek         }
22653e457fe3SDavid van Moolenbroek     }
22663e457fe3SDavid van Moolenbroek     assert(sourceTypeInfo.getParents().size() <= 1);
22673e457fe3SDavid van Moolenbroek     for(unsigned i=0;i<typeInfos.size();i++) {
22683e457fe3SDavid van Moolenbroek         if(typeInfos[i]->equals(&sourceTypeInfo)) {
22693e457fe3SDavid van Moolenbroek             typeInfos[i]->addParents(sourceTypeInfo.getParents());
22703e457fe3SDavid van Moolenbroek             return typeInfos[i];
22713e457fe3SDavid van Moolenbroek         }
22723e457fe3SDavid van Moolenbroek     }
22733e457fe3SDavid van Moolenbroek     TypeInfo *aTypeInfo = new TypeInfo(sourceTypeInfo);
22743e457fe3SDavid van Moolenbroek     aTypeInfo->setPersistent();
22753e457fe3SDavid van Moolenbroek     const SmartType *aSmartType = aTypeInfo->getSmartType();
22763e457fe3SDavid van Moolenbroek     unsigned numContainedTypes = aSmartType ? aSmartType->getNumContainedTypes() : 0;
22773e457fe3SDavid van Moolenbroek     const SmartType* containedSmartType = NULL;
22783e457fe3SDavid van Moolenbroek     TypeInfo* addedTypeInfo = NULL;
22793e457fe3SDavid van Moolenbroek     std::vector<TypeInfo*> aTypeInfoContainedTypes;
22803e457fe3SDavid van Moolenbroek     nestedTypes.push_back(aTypeInfo);
22813e457fe3SDavid van Moolenbroek     level++;
22823e457fe3SDavid van Moolenbroek     for(unsigned i=0;i<numContainedTypes;i++) {
22833e457fe3SDavid van Moolenbroek         containedSmartType = aSmartType->getContainedType(i);
22843e457fe3SDavid van Moolenbroek         if(!containedSmartType->isFunctionTy() || containedSmartType->isTypeConsistent()) {
22853e457fe3SDavid van Moolenbroek             TypeInfo containedTypeInfo(containedSmartType);
22863e457fe3SDavid van Moolenbroek             addedTypeInfo = fillTypeInfos(containedTypeInfo, typeInfos);
22873e457fe3SDavid van Moolenbroek         }
22883e457fe3SDavid van Moolenbroek         else {
22893e457fe3SDavid van Moolenbroek             TYPECONST FunctionType* type = (TYPECONST FunctionType*) containedSmartType->getType();
22903e457fe3SDavid van Moolenbroek             TypeInfo containedTypeInfo(type);
22913e457fe3SDavid van Moolenbroek             addedTypeInfo = fillTypeInfos(containedTypeInfo, typeInfos);
22923e457fe3SDavid van Moolenbroek         }
22933e457fe3SDavid van Moolenbroek         if(addedTypeInfo->getSmartType() != containedSmartType) {
22943e457fe3SDavid van Moolenbroek             delete containedSmartType;
22953e457fe3SDavid van Moolenbroek         }
22963e457fe3SDavid van Moolenbroek         aTypeInfoContainedTypes.push_back(addedTypeInfo);
22973e457fe3SDavid van Moolenbroek     }
22983e457fe3SDavid van Moolenbroek     level--;
22993e457fe3SDavid van Moolenbroek     nestedTypes.pop_back();
23003e457fe3SDavid van Moolenbroek     aTypeInfo->setContainedTypes(aTypeInfoContainedTypes);
23013e457fe3SDavid van Moolenbroek     typeInfos.push_back(aTypeInfo);
23023e457fe3SDavid van Moolenbroek     if(DEBUG_FILL_TYPE_INFOS) {
23033e457fe3SDavid van Moolenbroek         magicPassErr("Exiting level: " << level << ", types so far: " << typeInfos.size());
23043e457fe3SDavid van Moolenbroek     }
23053e457fe3SDavid van Moolenbroek     return aTypeInfo;
23063e457fe3SDavid van Moolenbroek }
23073e457fe3SDavid van Moolenbroek 
fillExternalTypeInfos(TYPECONST Type * sourceType,GlobalValue * parent,std::vector<TypeInfo * > & typeInfos)23083e457fe3SDavid van Moolenbroek TypeInfo* MagicPass::fillExternalTypeInfos(TYPECONST Type *sourceType, GlobalValue* parent, std::vector<TypeInfo*> &typeInfos) {
23093e457fe3SDavid van Moolenbroek     static std::map<TYPECONST Type *, TypeInfo*> externalTypeInfoCache;
23103e457fe3SDavid van Moolenbroek     std::map<TYPECONST Type*, TypeInfo*>::iterator externalTypeInfoCacheIt;
23113e457fe3SDavid van Moolenbroek     TypeInfo* aTypeInfo = NULL;
23123e457fe3SDavid van Moolenbroek     std::vector<TypeInfo*> compatibleTypeInfos;
23133e457fe3SDavid van Moolenbroek     //see if we already have the type in the cache first
23143e457fe3SDavid van Moolenbroek     externalTypeInfoCacheIt = externalTypeInfoCache.find(sourceType);
23153e457fe3SDavid van Moolenbroek     if(externalTypeInfoCacheIt != externalTypeInfoCache.end()) {
23163e457fe3SDavid van Moolenbroek         aTypeInfo = externalTypeInfoCacheIt->second;
23173e457fe3SDavid van Moolenbroek         if(parent) {
23183e457fe3SDavid van Moolenbroek             aTypeInfo->addParent(parent);
23193e457fe3SDavid van Moolenbroek         }
23203e457fe3SDavid van Moolenbroek         return aTypeInfo;
23213e457fe3SDavid van Moolenbroek     }
23223e457fe3SDavid van Moolenbroek 
23233e457fe3SDavid van Moolenbroek     for(unsigned i=0;i<typeInfos.size();i++) {
23243e457fe3SDavid van Moolenbroek         if(typeInfos[i]->getSmartType() && typeInfos[i]->getSmartType()->getType() == sourceType && (!sourceType->isArrayTy() || typeInfos[i]->getTypeID() == MAGIC_TYPE_ARRAY)) {
23253e457fe3SDavid van Moolenbroek             compatibleTypeInfos.push_back(typeInfos[i]);
23263e457fe3SDavid van Moolenbroek         }
23273e457fe3SDavid van Moolenbroek     }
23283e457fe3SDavid van Moolenbroek     if(compatibleTypeInfos.size() > 0) {
23293e457fe3SDavid van Moolenbroek         unsigned minStringTypeInfo = 0;
23303e457fe3SDavid van Moolenbroek         if(compatibleTypeInfos.size() > 1) {
23313e457fe3SDavid van Moolenbroek             /* Select the first type in alphabetical order to ensure deterministic behavior. */
23323e457fe3SDavid van Moolenbroek             for(unsigned i=1;i<compatibleTypeInfos.size();i++) {
23333e457fe3SDavid van Moolenbroek                 if(compatibleTypeInfos[i]->getSmartType()->getEDIType()->getDescription().compare(compatibleTypeInfos[minStringTypeInfo]->getSmartType()->getEDIType()->getDescription()) < 0) {
23343e457fe3SDavid van Moolenbroek                     minStringTypeInfo = i;
23353e457fe3SDavid van Moolenbroek                 }
23363e457fe3SDavid van Moolenbroek             }
23373e457fe3SDavid van Moolenbroek         }
23383e457fe3SDavid van Moolenbroek         aTypeInfo = compatibleTypeInfos[minStringTypeInfo];
23393e457fe3SDavid van Moolenbroek     }
23403e457fe3SDavid van Moolenbroek     if(DEBUG_FILL_EXT_TYPE_INFOS && compatibleTypeInfos.size() > 1) {
23413e457fe3SDavid van Moolenbroek         std::string typeString;
23423e457fe3SDavid van Moolenbroek         for(unsigned i=0;i<compatibleTypeInfos.size();i++) {
23433e457fe3SDavid van Moolenbroek             assert(compatibleTypeInfos[i]->getSmartType());
23443e457fe3SDavid van Moolenbroek             typeString += (i==0 ? "" : ", ") + compatibleTypeInfos[i]->getSmartType()->getEDIType()->getDescription();
23453e457fe3SDavid van Moolenbroek         }
23463e457fe3SDavid van Moolenbroek         magicPassErr("Multiple compatible types found for external type " << TypeUtil::getDescription(sourceType, MAGIC_TYPE_STR_PRINT_MAX, MAGIC_TYPE_STR_PRINT_MAX_LEVEL) << ": " << typeString << "; selecting the first type in alphabetical order: " << aTypeInfo->getSmartType()->getEDIType()->getDescription());
23473e457fe3SDavid van Moolenbroek     }
23483e457fe3SDavid van Moolenbroek     if(aTypeInfo == NULL) {
23493e457fe3SDavid van Moolenbroek         TypeInfo *targetTypeInfo = NULL;
23503e457fe3SDavid van Moolenbroek         if(TypeUtil::isOpaqueTy(sourceType)) {
23513e457fe3SDavid van Moolenbroek             aTypeInfo = new TypeInfo((TYPECONST StructType*) sourceType, TYPEINFO_PERSISTENT);
23523e457fe3SDavid van Moolenbroek             typeInfos.push_back(aTypeInfo);
23533e457fe3SDavid van Moolenbroek         }
23543e457fe3SDavid van Moolenbroek         else if(sourceType->isPointerTy()) {
23553e457fe3SDavid van Moolenbroek             TYPECONST Type *targetType = sourceType->getContainedType(0);
23563e457fe3SDavid van Moolenbroek             targetTypeInfo = fillExternalTypeInfos(targetType, NULL, typeInfos);
23573e457fe3SDavid van Moolenbroek             if(targetTypeInfo == NULL) {
23583e457fe3SDavid van Moolenbroek                 return NULL;
23593e457fe3SDavid van Moolenbroek             }
23603e457fe3SDavid van Moolenbroek             aTypeInfo = new TypeInfo((TYPECONST PointerType*) sourceType, TYPEINFO_PERSISTENT);
23613e457fe3SDavid van Moolenbroek         }
23623e457fe3SDavid van Moolenbroek         else if(sourceType->isArrayTy()) {
23633e457fe3SDavid van Moolenbroek             TYPECONST Type *targetType = sourceType->getContainedType(0);
23643e457fe3SDavid van Moolenbroek             targetTypeInfo = fillExternalTypeInfos(targetType, NULL, typeInfos);
23653e457fe3SDavid van Moolenbroek             if(targetTypeInfo == NULL) {
23663e457fe3SDavid van Moolenbroek                 return NULL;
23673e457fe3SDavid van Moolenbroek             }
23683e457fe3SDavid van Moolenbroek             aTypeInfo = new TypeInfo((TYPECONST ArrayType*) sourceType, TYPEINFO_PERSISTENT);
23693e457fe3SDavid van Moolenbroek         }
23703e457fe3SDavid van Moolenbroek         else if(sourceType->isIntegerTy()) {
23713e457fe3SDavid van Moolenbroek             aTypeInfo = new TypeInfo((TYPECONST IntegerType*) sourceType, TYPEINFO_PERSISTENT);
23723e457fe3SDavid van Moolenbroek             typeInfos.push_back(aTypeInfo);
23733e457fe3SDavid van Moolenbroek         }
23743e457fe3SDavid van Moolenbroek         else if(sourceType->isFunctionTy()) {
23753e457fe3SDavid van Moolenbroek             aTypeInfo = new TypeInfo((TYPECONST FunctionType*) sourceType, TYPEINFO_PERSISTENT);
23763e457fe3SDavid van Moolenbroek             typeInfos.push_back(aTypeInfo);
23773e457fe3SDavid van Moolenbroek         }
23783e457fe3SDavid van Moolenbroek         if(targetTypeInfo != NULL) {
23793e457fe3SDavid van Moolenbroek             std::vector<TypeInfo*> containedTypes;
23803e457fe3SDavid van Moolenbroek             containedTypes.push_back(targetTypeInfo);
23813e457fe3SDavid van Moolenbroek             aTypeInfo->setContainedTypes(containedTypes);
23823e457fe3SDavid van Moolenbroek             typeInfos.push_back(aTypeInfo);
23833e457fe3SDavid van Moolenbroek         }
23843e457fe3SDavid van Moolenbroek     }
23853e457fe3SDavid van Moolenbroek     if(aTypeInfo && parent) {
23863e457fe3SDavid van Moolenbroek         aTypeInfo->addParent(parent);
23873e457fe3SDavid van Moolenbroek     }
23883e457fe3SDavid van Moolenbroek     externalTypeInfoCache.insert(std::pair<TYPECONST Type*, TypeInfo*>(sourceType, aTypeInfo));
23893e457fe3SDavid van Moolenbroek     return aTypeInfo;
23903e457fe3SDavid van Moolenbroek }
23913e457fe3SDavid van Moolenbroek 
printInterestingTypes(TYPECONST TypeInfo * aTypeInfo)23923e457fe3SDavid van Moolenbroek void MagicPass::printInterestingTypes(TYPECONST TypeInfo *aTypeInfo) {
23933e457fe3SDavid van Moolenbroek     static std::vector<TYPECONST TypeInfo*> nestedTypes;
23943e457fe3SDavid van Moolenbroek     static std::vector<unsigned> nestedIndexes;
23953e457fe3SDavid van Moolenbroek     static std::vector<TYPECONST TypeInfo*> interestingTypesSoFar;
23963e457fe3SDavid van Moolenbroek     static std::string typeName;
23973e457fe3SDavid van Moolenbroek     static unsigned level = 0;
23983e457fe3SDavid van Moolenbroek     for(unsigned i=0;i<nestedTypes.size();i++) {
23993e457fe3SDavid van Moolenbroek         if(aTypeInfo == nestedTypes[i]) {
24003e457fe3SDavid van Moolenbroek             return;
24013e457fe3SDavid van Moolenbroek         }
24023e457fe3SDavid van Moolenbroek     }
24033e457fe3SDavid van Moolenbroek 
24043e457fe3SDavid van Moolenbroek     bool isInterestingType = false;
24053e457fe3SDavid van Moolenbroek     const SmartType *aSmartType = aTypeInfo->getSmartType();
24063e457fe3SDavid van Moolenbroek     if(aSmartType) {
24073e457fe3SDavid van Moolenbroek         if(aSmartType->isStructTy() && !aTypeInfo->getName().compare("")) {
24083e457fe3SDavid van Moolenbroek             isInterestingType = true;
24093e457fe3SDavid van Moolenbroek             typeName = "Anonymous";
24103e457fe3SDavid van Moolenbroek         }
24113e457fe3SDavid van Moolenbroek         if(aSmartType->getEDIType()->isEnumTy()) {
24123e457fe3SDavid van Moolenbroek             isInterestingType = true;
24133e457fe3SDavid van Moolenbroek             typeName = "Enum";
24143e457fe3SDavid van Moolenbroek         }
24153e457fe3SDavid van Moolenbroek         if(aSmartType->isOpaqueTy()) {
24163e457fe3SDavid van Moolenbroek             isInterestingType = true;
24173e457fe3SDavid van Moolenbroek             typeName = "Opaque";
24183e457fe3SDavid van Moolenbroek         }
24193e457fe3SDavid van Moolenbroek     }
24203e457fe3SDavid van Moolenbroek     if(isInterestingType) {
24213e457fe3SDavid van Moolenbroek         bool isNewInterestingType = true;
24223e457fe3SDavid van Moolenbroek         for(unsigned i=0;i<interestingTypesSoFar.size();i++) {
24233e457fe3SDavid van Moolenbroek             if(aTypeInfo == interestingTypesSoFar[i]) {
24243e457fe3SDavid van Moolenbroek                 isNewInterestingType = false;
24253e457fe3SDavid van Moolenbroek                 break;
24263e457fe3SDavid van Moolenbroek             }
24273e457fe3SDavid van Moolenbroek         }
24283e457fe3SDavid van Moolenbroek         if(isNewInterestingType) {
24293e457fe3SDavid van Moolenbroek             interestingTypesSoFar.push_back(aTypeInfo);
24303e457fe3SDavid van Moolenbroek             if(nestedTypes.size() == 0) {
24313e457fe3SDavid van Moolenbroek                 dbgs() << "**** " << typeName << " top type found, printing it: \n";
24323e457fe3SDavid van Moolenbroek                 dbgs() << aSmartType->getDescription();
24333e457fe3SDavid van Moolenbroek                 aSmartType->getEDIType()->getDIType()->print(dbgs());
24343e457fe3SDavid van Moolenbroek             }
24353e457fe3SDavid van Moolenbroek             else {
24363e457fe3SDavid van Moolenbroek                 dbgs() << "**** " << typeName << " type found, printing path: \n";
24373e457fe3SDavid van Moolenbroek                 dbgs() << "**************** LEVEL 0\n";
24383e457fe3SDavid van Moolenbroek                 dbgs() << "**************** NAME: " << nestedTypes[0]->getName() << "\n";
24393e457fe3SDavid van Moolenbroek                 dbgs() << nestedTypes[0]->getSmartType()->getDescription();
24403e457fe3SDavid van Moolenbroek                 unsigned i;
24413e457fe3SDavid van Moolenbroek                 for(i=1;i<nestedTypes.size();i++) {
24423e457fe3SDavid van Moolenbroek                     dbgs() << "**************** LEVEL " << i << "\n";
24433e457fe3SDavid van Moolenbroek                     dbgs() << "**************** NAME: " << nestedTypes[i]->getName() << "\n";
24443e457fe3SDavid van Moolenbroek                     dbgs() << "**************** PARENT INDEX " << nestedIndexes[i-1] << "\n";
24453e457fe3SDavid van Moolenbroek                     dbgs() << nestedTypes[i]->getSmartType()->getDescription();
24463e457fe3SDavid van Moolenbroek                 }
24473e457fe3SDavid van Moolenbroek                 dbgs() << "**************** LAST LEVEL " << i << "\n";
24483e457fe3SDavid van Moolenbroek                 dbgs() << "**************** PARENT INDEX " << nestedIndexes[i-1] << "\n";
24493e457fe3SDavid van Moolenbroek                 dbgs() << aSmartType->getDescription();
24503e457fe3SDavid van Moolenbroek                 aSmartType->getEDIType()->getDIType()->print(dbgs());
24513e457fe3SDavid van Moolenbroek                 dbgs() << "*****************************************\n";
24523e457fe3SDavid van Moolenbroek             }
24533e457fe3SDavid van Moolenbroek         }
24543e457fe3SDavid van Moolenbroek     }
24553e457fe3SDavid van Moolenbroek 
24563e457fe3SDavid van Moolenbroek     unsigned numContainedTypes = aTypeInfo->getNumContainedTypes();
24573e457fe3SDavid van Moolenbroek     nestedTypes.push_back(aTypeInfo);
24583e457fe3SDavid van Moolenbroek     level++;
24593e457fe3SDavid van Moolenbroek     for(unsigned i=0;i<numContainedTypes;i++) {
24603e457fe3SDavid van Moolenbroek         nestedIndexes.push_back(i);
24613e457fe3SDavid van Moolenbroek         printInterestingTypes(aTypeInfo->getContainedType(i));
24623e457fe3SDavid van Moolenbroek         nestedIndexes.pop_back();
24633e457fe3SDavid van Moolenbroek     }
24643e457fe3SDavid van Moolenbroek     level--;
24653e457fe3SDavid van Moolenbroek     nestedTypes.pop_back();
24663e457fe3SDavid van Moolenbroek }
24673e457fe3SDavid van Moolenbroek 
getMaxRecursiveSequenceLength(TYPECONST TypeInfo * aTypeInfo)24683e457fe3SDavid van Moolenbroek unsigned MagicPass::getMaxRecursiveSequenceLength(TYPECONST TypeInfo *aTypeInfo) {
24693e457fe3SDavid van Moolenbroek     static std::vector<TYPECONST TypeInfo*> nestedTypes;
24703e457fe3SDavid van Moolenbroek     static unsigned level = 0;
24713e457fe3SDavid van Moolenbroek     for(unsigned i=0;i<nestedTypes.size();i++) {
24723e457fe3SDavid van Moolenbroek         if(aTypeInfo == nestedTypes[i]) {
24733e457fe3SDavid van Moolenbroek             return nestedTypes.size()+1;
24743e457fe3SDavid van Moolenbroek         }
24753e457fe3SDavid van Moolenbroek     }
24763e457fe3SDavid van Moolenbroek 
24773e457fe3SDavid van Moolenbroek     unsigned numContainedTypes = aTypeInfo->getNumContainedTypes();
24783e457fe3SDavid van Moolenbroek     unsigned length, maxLength = 0;
24793e457fe3SDavid van Moolenbroek     nestedTypes.push_back(aTypeInfo);
24803e457fe3SDavid van Moolenbroek     level++;
24813e457fe3SDavid van Moolenbroek     for(unsigned i=0;i<numContainedTypes;i++) {
24823e457fe3SDavid van Moolenbroek         length = getMaxRecursiveSequenceLength(aTypeInfo->getContainedType(i));
24833e457fe3SDavid van Moolenbroek         if(length > maxLength) {
24843e457fe3SDavid van Moolenbroek             maxLength = length;
24853e457fe3SDavid van Moolenbroek         }
24863e457fe3SDavid van Moolenbroek     }
24873e457fe3SDavid van Moolenbroek     level--;
24883e457fe3SDavid van Moolenbroek     nestedTypes.pop_back();
24893e457fe3SDavid van Moolenbroek     return maxLength;
24903e457fe3SDavid van Moolenbroek }
24913e457fe3SDavid van Moolenbroek 
getFunctionType(TYPECONST FunctionType * baseType,std::vector<unsigned> selectedArgs)24923e457fe3SDavid van Moolenbroek FunctionType* MagicPass::getFunctionType(TYPECONST FunctionType *baseType, std::vector<unsigned> selectedArgs) {
24933e457fe3SDavid van Moolenbroek 	std::vector<TYPECONST Type*> ArgTypes;
24943e457fe3SDavid van Moolenbroek 	for (unsigned i = 0; i < selectedArgs.size(); i++) {
24953e457fe3SDavid van Moolenbroek 		ArgTypes.push_back(baseType->getParamType(selectedArgs[i] - 1));
24963e457fe3SDavid van Moolenbroek 	}
24973e457fe3SDavid van Moolenbroek 	// Create a new function type...
24983e457fe3SDavid van Moolenbroek 	FunctionType *FTy = FunctionType::get(baseType->getReturnType(), ArgTypes, baseType->isVarArg());
24993e457fe3SDavid van Moolenbroek 	return FTy;
25003e457fe3SDavid van Moolenbroek }
25013e457fe3SDavid van Moolenbroek 
isCompatibleMagicMemFuncType(TYPECONST FunctionType * type,TYPECONST FunctionType * magicType)25023e457fe3SDavid van Moolenbroek bool MagicPass::isCompatibleMagicMemFuncType(TYPECONST FunctionType *type, TYPECONST FunctionType* magicType) {
25033e457fe3SDavid van Moolenbroek     if(type->getReturnType() != magicType->getReturnType()) {
25043e457fe3SDavid van Moolenbroek         return false;
25053e457fe3SDavid van Moolenbroek     }
25063e457fe3SDavid van Moolenbroek     unsigned numContainedTypes = type->getNumContainedTypes();
25073e457fe3SDavid van Moolenbroek     unsigned numContainedMagicTypes = magicType->getNumContainedTypes();
25083e457fe3SDavid van Moolenbroek     if(numContainedTypes > numContainedMagicTypes) {
25093e457fe3SDavid van Moolenbroek         return false;
25103e457fe3SDavid van Moolenbroek     }
25113e457fe3SDavid van Moolenbroek     for(unsigned i=0;i<numContainedTypes-1;i++) {
25123e457fe3SDavid van Moolenbroek         TYPECONST Type* cType = type->getContainedType(numContainedTypes-1-i);
25133e457fe3SDavid van Moolenbroek         TYPECONST Type* cMagicType = magicType->getContainedType(numContainedMagicTypes-1-i);
25143e457fe3SDavid van Moolenbroek         if (!MagicUtil::isCompatibleType(cType, cMagicType)) {
25153e457fe3SDavid van Moolenbroek         	return false;
25163e457fe3SDavid van Moolenbroek         }
25173e457fe3SDavid van Moolenbroek     }
25183e457fe3SDavid van Moolenbroek     return true;
25193e457fe3SDavid van Moolenbroek }
25203e457fe3SDavid van Moolenbroek 
findWrapper(Module & M,std::string * magicMemPrefixes,Function * f,std::string fName)2521b7725c85SDavid van Moolenbroek Function* MagicPass::findWrapper(Module &M, std::string *magicMemPrefixes, Function *f, std::string fName)
2522b7725c85SDavid van Moolenbroek {
2523b7725c85SDavid van Moolenbroek     std::string wName, wName2;
2524b7725c85SDavid van Moolenbroek     Function *w = NULL, *w2 = NULL;
2525b7725c85SDavid van Moolenbroek     for(unsigned k=0;magicMemPrefixes[k].compare("");k++) {
2526b7725c85SDavid van Moolenbroek         wName = magicMemPrefixes[k] + fName;
2527b7725c85SDavid van Moolenbroek         w = M.getFunction(wName);
2528b7725c85SDavid van Moolenbroek         if(w) {
2529b7725c85SDavid van Moolenbroek             wName2 = wName + "_";
2530b7725c85SDavid van Moolenbroek             break;
2531b7725c85SDavid van Moolenbroek         }
2532b7725c85SDavid van Moolenbroek     }
2533b7725c85SDavid van Moolenbroek     if(!w) {
2534b7725c85SDavid van Moolenbroek         magicPassErr("Error: no wrapper function found for " << fName << "()");
2535b7725c85SDavid van Moolenbroek         exit(1);
2536b7725c85SDavid van Moolenbroek     }
2537b7725c85SDavid van Moolenbroek     while(!isCompatibleMagicMemFuncType(f->getFunctionType(), w->getFunctionType()) && (w2 = M.getFunction(wName2))) {
2538b7725c85SDavid van Moolenbroek         w = w2;
2539b7725c85SDavid van Moolenbroek         wName2.append("_");
2540b7725c85SDavid van Moolenbroek     }
2541b7725c85SDavid van Moolenbroek     if(!isCompatibleMagicMemFuncType(f->getFunctionType(), w->getFunctionType())) {
2542b7725c85SDavid van Moolenbroek         magicPassErr("Error: wrapper function with incompatible type " << wName << "() found");
2543b7725c85SDavid van Moolenbroek         magicPassErr(TypeUtil::getDescription(f->getFunctionType(), MAGIC_TYPE_STR_PRINT_MAX, MAGIC_TYPE_STR_PRINT_MAX_LEVEL) << " != " << TypeUtil::getDescription(w->getFunctionType(), MAGIC_TYPE_STR_PRINT_MAX, MAGIC_TYPE_STR_PRINT_MAX_LEVEL));
2544b7725c85SDavid van Moolenbroek         exit(1);
2545b7725c85SDavid van Moolenbroek     }
2546b7725c85SDavid van Moolenbroek     return w;
2547b7725c85SDavid van Moolenbroek }
2548b7725c85SDavid van Moolenbroek 
25493a3478dcSDavid van Moolenbroek #if MAGIC_INDEX_BIT_CAST
25503a3478dcSDavid van Moolenbroek static void processBitCast(Module &M, std::map<TYPECONST Type*, std::set<TYPECONST Type*> > &bitCastMap, TYPECONST Type* srcType, TYPECONST Type* dstType);
25513a3478dcSDavid van Moolenbroek 
processFunctionBitCast(Module & M,std::map<TYPECONST Type *,std::set<TYPECONST Type * >> & bitCastMap,TYPECONST Type * srcType,TYPECONST Type * dstType)25523a3478dcSDavid van Moolenbroek static void processFunctionBitCast(Module &M, std::map<TYPECONST Type*, std::set<TYPECONST Type*> > &bitCastMap, TYPECONST Type* srcType, TYPECONST Type* dstType) {
25533a3478dcSDavid van Moolenbroek     // The rough intuition: we are casting one function to another, so we expect these functions to be
25543a3478dcSDavid van Moolenbroek     // compatible, so their respective parameters must also be compatible, if they are different at all.
25553a3478dcSDavid van Moolenbroek     // We limit ourselves to pointer parameters because we are only interested in pointer compatibility.
25563a3478dcSDavid van Moolenbroek     // This routine basically aims to mark two structure pointers as compatible when one structure has
25573a3478dcSDavid van Moolenbroek     // an opaque pointer and the other one does not.
25583a3478dcSDavid van Moolenbroek     TYPECONST FunctionType* srcF = dyn_cast<TYPECONST FunctionType>(srcType);
25593a3478dcSDavid van Moolenbroek     TYPECONST FunctionType* dstF = dyn_cast<TYPECONST FunctionType>(dstType);
25603a3478dcSDavid van Moolenbroek 
25613a3478dcSDavid van Moolenbroek     // Both functions must have the same number of parameters.
25623a3478dcSDavid van Moolenbroek     unsigned int numParams = srcF->getNumParams();
25633a3478dcSDavid van Moolenbroek 
25643a3478dcSDavid van Moolenbroek     if (numParams != dstF->getNumParams()) return;
25653a3478dcSDavid van Moolenbroek 
25663a3478dcSDavid van Moolenbroek     TYPECONST Type* voidPtrType = PointerType::get(IntegerType::get(M.getContext(), 8), 0);
25673a3478dcSDavid van Moolenbroek 
25683a3478dcSDavid van Moolenbroek     // If any of the parameters are pointers for different types, these types must be compatible.
25693a3478dcSDavid van Moolenbroek     for (unsigned int i = 0; i < numParams; i++) {
25703a3478dcSDavid van Moolenbroek         TYPECONST Type* spType = srcF->getParamType(i);
25713a3478dcSDavid van Moolenbroek         TYPECONST Type* dpType = dstF->getParamType(i);
25723a3478dcSDavid van Moolenbroek 
25733a3478dcSDavid van Moolenbroek         // The parameters must have different types, but they must both be pointers.
25743a3478dcSDavid van Moolenbroek         if (spType == dpType) continue;
25753a3478dcSDavid van Moolenbroek 
25763a3478dcSDavid van Moolenbroek         if (!spType->isPointerTy() || !dpType->isPointerTy()) continue;
25773a3478dcSDavid van Moolenbroek 
25783a3478dcSDavid van Moolenbroek         // We ignore certain types, depending on our configuration.
25793a3478dcSDavid van Moolenbroek         TYPECONST Type* dpElType = TypeUtil::getRecursiveElementType(dpType);
25803a3478dcSDavid van Moolenbroek 
25813a3478dcSDavid van Moolenbroek         if (!((MAGIC_INDEX_FUN_PTR_BIT_CAST && dpElType->isFunctionTy()) ||
25823a3478dcSDavid van Moolenbroek             (MAGIC_INDEX_STR_PTR_BIT_CAST && dpElType->isStructTy()) ||
25833a3478dcSDavid van Moolenbroek             MAGIC_INDEX_OTH_PTR_BIT_CAST)) continue;
25843a3478dcSDavid van Moolenbroek 
25853a3478dcSDavid van Moolenbroek         // TODO: this needs configuration testing as well.
25863a3478dcSDavid van Moolenbroek         if (spType == voidPtrType || dpType == voidPtrType) continue;
25873a3478dcSDavid van Moolenbroek 
25883a3478dcSDavid van Moolenbroek #if DEBUG_CASTS
25893a3478dcSDavid van Moolenbroek         errs() << "Compatible function parameter " << i << ": " << TypeUtil::getDescription(spType) <<
25903a3478dcSDavid van Moolenbroek             " -> " << TypeUtil::getDescription(dpType) << "\n";
25913a3478dcSDavid van Moolenbroek #endif
25923a3478dcSDavid van Moolenbroek 
25933a3478dcSDavid van Moolenbroek         // The two pointers should be compatible, so mark them as such.
25943a3478dcSDavid van Moolenbroek         // TODO: prevent infinite recursion
25953a3478dcSDavid van Moolenbroek 	processBitCast(M, bitCastMap, spType, dpType);
25963a3478dcSDavid van Moolenbroek     }
25973a3478dcSDavid van Moolenbroek }
25983a3478dcSDavid van Moolenbroek 
25993a3478dcSDavid van Moolenbroek #if 0
26003a3478dcSDavid van Moolenbroek static void processStructBitCast(Module &M, std::map<TYPECONST Type*, std::set<TYPECONST Type*> > &bitCastMap, TYPECONST Type* srcType, TYPECONST Type* dstType) {
26013a3478dcSDavid van Moolenbroek     // The rough intuition: the given structure types are subject to pointer casting. This does not
26023a3478dcSDavid van Moolenbroek     // mean they are compatible by itself (struct sockaddr..). HOWEVER, if they differ only by
26033a3478dcSDavid van Moolenbroek     // elements which are different only (recursively) by opaque pointers in one of them, and
26043a3478dcSDavid van Moolenbroek     // non-opaque pointer in the other, then those pointers are highly likely to be compatible.
26053a3478dcSDavid van Moolenbroek     TYPECONST StructType* srcS = dyn_cast<TYPECONST StructType>(srcType);
26063a3478dcSDavid van Moolenbroek     TYPECONST StructType* dstS = dyn_cast<TYPECONST StructType>(dstType);
26073a3478dcSDavid van Moolenbroek 
26083a3478dcSDavid van Moolenbroek     // The structures must be similar..
26093a3478dcSDavid van Moolenbroek     if (srcS->isPacked() != dstS->isPacked()) return false;
26103a3478dcSDavid van Moolenbroek 
26113a3478dcSDavid van Moolenbroek     unsigned int numElements = srcS->getNumElements();
26123a3478dcSDavid van Moolenbroek 
26133a3478dcSDavid van Moolenbroek     if (numElements != dstS->getNumElements()) return false;
26143a3478dcSDavid van Moolenbroek 
26153a3478dcSDavid van Moolenbroek     // ..but not the same.
26163a3478dcSDavid van Moolenbroek     if (srcS->isLayoutIdentical(dstS)) return false;
26173a3478dcSDavid van Moolenbroek 
26183a3478dcSDavid van Moolenbroek     // Pass 1: see if the structures differ only by opaque (sub)elements.
26193a3478dcSDavid van Moolenbroek     for (unsigned int i = 0; i < numElements; i++) {
26203a3478dcSDavid van Moolenbroek         TYPECONST Type* seType = srcS->getElementType(i);
26213a3478dcSDavid van Moolenbroek         TYPECONST Type* deType = dstS->getElementType(i);
26223a3478dcSDavid van Moolenbroek 
26233a3478dcSDavid van Moolenbroek         if (seType != deType) {
26243a3478dcSDavid van Moolenbroek             if (seType->isPointerTy() && deType->isPointerTy()) {
26253a3478dcSDavid van Moolenbroek                 TYPECONST PointerType* sePtrType = dyn_cast<PointerType>(seType);
26263a3478dcSDavid van Moolenbroek                 TYPECONST PointerType* dePtrType = dyn_cast<PointerType>(deType);
26273a3478dcSDavid van Moolenbroek 
26283a3478dcSDavid van Moolenbroek                 // ..TODO..
26293a3478dcSDavid van Moolenbroek                 // this may involve recursive testing!
26303a3478dcSDavid van Moolenbroek             }
26313a3478dcSDavid van Moolenbroek 
26323a3478dcSDavid van Moolenbroek             // ..TODO..
26333a3478dcSDavid van Moolenbroek         }
26343a3478dcSDavid van Moolenbroek     }
26353a3478dcSDavid van Moolenbroek 
26363a3478dcSDavid van Moolenbroek     // Pass 2: register all pointers to compatible elements.
26373a3478dcSDavid van Moolenbroek     // ..TODO..
26383a3478dcSDavid van Moolenbroek     // this may involve recursive registration!
26393a3478dcSDavid van Moolenbroek }
26403a3478dcSDavid van Moolenbroek #endif
26413a3478dcSDavid van Moolenbroek 
processBitCast(Module & M,std::map<TYPECONST Type *,std::set<TYPECONST Type * >> & bitCastMap,TYPECONST Type * srcType,TYPECONST Type * dstType)26423a3478dcSDavid van Moolenbroek static void processBitCast(Module &M, std::map<TYPECONST Type*, std::set<TYPECONST Type*> > &bitCastMap, TYPECONST Type* srcType, TYPECONST Type* dstType) {
26433a3478dcSDavid van Moolenbroek     std::map<TYPECONST Type*, std::set<TYPECONST Type*> >::iterator bitCastMapIt;
26443a3478dcSDavid van Moolenbroek     unsigned int dstDepth, srcDepth;
26453a3478dcSDavid van Moolenbroek     TYPECONST PointerType* ptrType;
26463a3478dcSDavid van Moolenbroek 
26473a3478dcSDavid van Moolenbroek     // The pointers are compatible, so add them to the bitcast map.
26483a3478dcSDavid van Moolenbroek     bitCastMapIt = bitCastMap.find(dstType);
26493a3478dcSDavid van Moolenbroek     if(bitCastMapIt == bitCastMap.end()) {
26503a3478dcSDavid van Moolenbroek         std::set<TYPECONST Type*> typeSet;
26513a3478dcSDavid van Moolenbroek         typeSet.insert(srcType);
26523a3478dcSDavid van Moolenbroek         bitCastMap.insert(std::pair<TYPECONST Type*, std::set<TYPECONST Type*> >(dstType, typeSet));
26533a3478dcSDavid van Moolenbroek     }
26543a3478dcSDavid van Moolenbroek     else {
26553a3478dcSDavid van Moolenbroek         std::set<TYPECONST Type*> *typeSet = &(bitCastMapIt->second);
26563a3478dcSDavid van Moolenbroek         typeSet->insert(srcType);
26573a3478dcSDavid van Moolenbroek     }
26583a3478dcSDavid van Moolenbroek 
26593a3478dcSDavid van Moolenbroek     // Unfortunately, this is not the whole story. The compiler may pull crazy stunts like storing
26603a3478dcSDavid van Moolenbroek     // a well-defined pointer in a structure, and then bitcast that structure to an almost-equivalent
26613a3478dcSDavid van Moolenbroek     // structure which has the pointer marked as opaque. Worse yet, it may bitcast between functions
26623a3478dcSDavid van Moolenbroek     // with such structures as parameters.  In those case, we never see a cast of the actual pointer,
26633a3478dcSDavid van Moolenbroek     // even though they are compatible. Failing to mark them as such could cause runtime failures.
26643a3478dcSDavid van Moolenbroek     // The code below is a first attempt to deal with a subset of cases that we have actually run
26653a3478dcSDavid van Moolenbroek     // into in practice. A better approach would be a separate pass that eliminates opaque pointers
26663a3478dcSDavid van Moolenbroek     // whenever possible altogether, but that would be even more work. TODO! Note that in general,
26673a3478dcSDavid van Moolenbroek     // it seems that there is no way to get to know which pointers the linker decided are equivalent,
26683a3478dcSDavid van Moolenbroek     // so this procedure is inherently going to involve guessing, with false positives and negatives.
26693a3478dcSDavid van Moolenbroek 
26703a3478dcSDavid van Moolenbroek     // Follow the pointers to see what they actually point to.
26713a3478dcSDavid van Moolenbroek     // The caller may already have done so, but without getting the depth.
26723a3478dcSDavid van Moolenbroek     for (dstDepth = 0; (ptrType = dyn_cast<PointerType>(dstType)); dstDepth++)
26733a3478dcSDavid van Moolenbroek         dstType = ptrType->getElementType();
26743a3478dcSDavid van Moolenbroek 
26753a3478dcSDavid van Moolenbroek     for (srcDepth = 0; (ptrType = dyn_cast<PointerType>(srcType)); srcDepth++)
26763a3478dcSDavid van Moolenbroek         srcType = ptrType->getElementType();
26773a3478dcSDavid van Moolenbroek 
26783a3478dcSDavid van Moolenbroek     // The pointers' indirection levels must be the same.
26793a3478dcSDavid van Moolenbroek     if (srcDepth != dstDepth) return;
26803a3478dcSDavid van Moolenbroek 
26813a3478dcSDavid van Moolenbroek     // Do more processing for certain types.
26823a3478dcSDavid van Moolenbroek     if (dstType->isFunctionTy() && srcType->isFunctionTy())
26833a3478dcSDavid van Moolenbroek         processFunctionBitCast(M, bitCastMap, srcType, dstType);
26843a3478dcSDavid van Moolenbroek     // TODO: add support for structures and their elements
26853a3478dcSDavid van Moolenbroek #if 0
26863a3478dcSDavid van Moolenbroek     else if (dstType->isStructTy() && srcType->isStructTy())
26873a3478dcSDavid van Moolenbroek         processStructBitCast(M, bitCastMap, srcType, dstType);
26883a3478dcSDavid van Moolenbroek #endif
26893a3478dcSDavid van Moolenbroek }
26903a3478dcSDavid van Moolenbroek #endif /* MAGIC_INDEX_BIT_CAST */
26913a3478dcSDavid van Moolenbroek 
indexCasts(Module & M,User * U,std::vector<TYPECONST Type * > & intCastTypes,std::vector<int> & intCastValues,std::map<TYPECONST Type *,std::set<TYPECONST Type * >> & bitCastMap)26923e457fe3SDavid van Moolenbroek void MagicPass::indexCasts(Module &M, User *U, std::vector<TYPECONST Type*> &intCastTypes, std::vector<int> &intCastValues, std::map<TYPECONST Type*, std::set<TYPECONST Type*> > &bitCastMap) {
26933e457fe3SDavid van Moolenbroek     unsigned i;
26943e457fe3SDavid van Moolenbroek     TYPECONST Type* voidPtrType = PointerType::get(IntegerType::get(M.getContext(), 8), 0);
26953e457fe3SDavid van Moolenbroek 
26963e457fe3SDavid van Moolenbroek     //look at instructions first
26973e457fe3SDavid van Moolenbroek #if MAGIC_INDEX_INT_CAST
26983e457fe3SDavid van Moolenbroek     if(CastInst* CI = dyn_cast<IntToPtrInst>(U)) {
26993e457fe3SDavid van Moolenbroek         TYPECONST Type* type = TypeUtil::getArrayFreePointerType(CI->getDestTy());
27003e457fe3SDavid van Moolenbroek         TYPECONST Type* elType = TypeUtil::getRecursiveElementType(type);
27013e457fe3SDavid van Moolenbroek         if((MAGIC_INDEX_FUN_PTR_INT_CAST && elType->isFunctionTy()) || (MAGIC_INDEX_STR_PTR_INT_CAST && elType->isStructTy()) || MAGIC_INDEX_OTH_PTR_INT_CAST) {
27023e457fe3SDavid van Moolenbroek             if(MAGIC_INDEX_VOID_PTR_INT_CAST || type != voidPtrType) {
27033e457fe3SDavid van Moolenbroek                 intCastTypes.push_back(type);
27043e457fe3SDavid van Moolenbroek                 ConstantInt *value = dyn_cast<ConstantInt>(CI->getOperand(0));
27053e457fe3SDavid van Moolenbroek                 intCastValues.push_back(value ? value->getSExtValue() : 0);
27063e457fe3SDavid van Moolenbroek #if DEBUG_CASTS
27073e457fe3SDavid van Moolenbroek                 CI->print(errs()); errs() << "\n";
27083e457fe3SDavid van Moolenbroek #endif
27093e457fe3SDavid van Moolenbroek             }
27103e457fe3SDavid van Moolenbroek         }
27113e457fe3SDavid van Moolenbroek     }
27123e457fe3SDavid van Moolenbroek #endif
27133e457fe3SDavid van Moolenbroek 
27143e457fe3SDavid van Moolenbroek #if MAGIC_INDEX_BIT_CAST
27153e457fe3SDavid van Moolenbroek     if(BitCastInst* CI = dyn_cast<BitCastInst>(U)) {
27163e457fe3SDavid van Moolenbroek         TYPECONST Type* type = TypeUtil::getArrayFreePointerType(CI->getDestTy());
27173e457fe3SDavid van Moolenbroek         TYPECONST Type* elType = TypeUtil::getRecursiveElementType(type);
27183e457fe3SDavid van Moolenbroek         if((MAGIC_INDEX_FUN_PTR_BIT_CAST && elType->isFunctionTy()) || (MAGIC_INDEX_STR_PTR_BIT_CAST && elType->isStructTy()) || MAGIC_INDEX_OTH_PTR_BIT_CAST) {
27193e457fe3SDavid van Moolenbroek             if(MAGIC_INDEX_VOID_PTR_BIT_CAST || type != voidPtrType) {
27203e457fe3SDavid van Moolenbroek                 TYPECONST Type* srcType = TypeUtil::getArrayFreePointerType(CI->getSrcTy());
27213e457fe3SDavid van Moolenbroek                 if(srcType != type && (!MAGIC_SKIP_TOVOID_PTR_BIT_CAST || srcType != voidPtrType)) {
27223e457fe3SDavid van Moolenbroek #if DEBUG_CASTS
27233e457fe3SDavid van Moolenbroek                     CI->print(errs()); errs() << "\n";
27243e457fe3SDavid van Moolenbroek #endif
27253a3478dcSDavid van Moolenbroek                     processBitCast(M, bitCastMap, srcType, type);
27263e457fe3SDavid van Moolenbroek                 }
27273e457fe3SDavid van Moolenbroek             }
27283e457fe3SDavid van Moolenbroek         }
27293e457fe3SDavid van Moolenbroek     }
27303e457fe3SDavid van Moolenbroek #endif
27313e457fe3SDavid van Moolenbroek 
27323e457fe3SDavid van Moolenbroek     //now dig looking for constant expressions
27333e457fe3SDavid van Moolenbroek     std::vector<User*> users;
27343e457fe3SDavid van Moolenbroek     users.push_back(U);
27353e457fe3SDavid van Moolenbroek     while(!users.empty()) {
27363e457fe3SDavid van Moolenbroek         User *user = users.front();
27373e457fe3SDavid van Moolenbroek         users.erase(users.begin());
27383e457fe3SDavid van Moolenbroek         ConstantExpr *CE = dyn_cast<ConstantExpr>(user);
27393e457fe3SDavid van Moolenbroek 
27403e457fe3SDavid van Moolenbroek #if MAGIC_INDEX_INT_CAST
27413e457fe3SDavid van Moolenbroek         if(CE && CE->getOpcode() == Instruction::IntToPtr) {
27423e457fe3SDavid van Moolenbroek             TYPECONST Type* type = TypeUtil::getArrayFreePointerType(CE->getType());
27433e457fe3SDavid van Moolenbroek             TYPECONST Type* elType = TypeUtil::getRecursiveElementType(type);
27443e457fe3SDavid van Moolenbroek             if((MAGIC_INDEX_FUN_PTR_INT_CAST && elType->isFunctionTy()) || (MAGIC_INDEX_STR_PTR_INT_CAST && elType->isStructTy()) || MAGIC_INDEX_OTH_PTR_INT_CAST) {
27453e457fe3SDavid van Moolenbroek                 if(MAGIC_INDEX_VOID_PTR_INT_CAST || type != voidPtrType) {
27463e457fe3SDavid van Moolenbroek #if DEBUG_CASTS
27473e457fe3SDavid van Moolenbroek                     CE->print(errs()); errs() << "\n";
27483e457fe3SDavid van Moolenbroek #endif
27493e457fe3SDavid van Moolenbroek                     intCastTypes.push_back(type);
27503e457fe3SDavid van Moolenbroek                     ConstantInt *value = dyn_cast<ConstantInt>(CE->getOperand(0));
27513e457fe3SDavid van Moolenbroek                     intCastValues.push_back(value ? value->getSExtValue() : 0);
27523e457fe3SDavid van Moolenbroek                 }
27533e457fe3SDavid van Moolenbroek             }
27543e457fe3SDavid van Moolenbroek         }
27553e457fe3SDavid van Moolenbroek #endif
27563e457fe3SDavid van Moolenbroek 
27573e457fe3SDavid van Moolenbroek #if MAGIC_INDEX_BIT_CAST
27583e457fe3SDavid van Moolenbroek         if(CE && CE->getOpcode() == Instruction::BitCast) {
27593e457fe3SDavid van Moolenbroek             TYPECONST Type* type = TypeUtil::getArrayFreePointerType(CE->getType());
27603e457fe3SDavid van Moolenbroek             TYPECONST Type* elType = TypeUtil::getRecursiveElementType(type);
27613e457fe3SDavid van Moolenbroek             if((MAGIC_INDEX_FUN_PTR_BIT_CAST && elType->isFunctionTy()) || (MAGIC_INDEX_STR_PTR_BIT_CAST && elType->isStructTy()) || MAGIC_INDEX_OTH_PTR_BIT_CAST) {
27623e457fe3SDavid van Moolenbroek                 if(MAGIC_INDEX_VOID_PTR_BIT_CAST || type != voidPtrType) {
27633e457fe3SDavid van Moolenbroek                     TYPECONST Type* srcType = TypeUtil::getArrayFreePointerType(CE->getOperand(0)->getType());
27643e457fe3SDavid van Moolenbroek                     if(srcType != type && (!MAGIC_SKIP_TOVOID_PTR_BIT_CAST || srcType != voidPtrType)) {
27653e457fe3SDavid van Moolenbroek #if DEBUG_CASTS
27663e457fe3SDavid van Moolenbroek                         CE->print(errs()); errs() << "\n";
27673e457fe3SDavid van Moolenbroek #endif
27683a3478dcSDavid van Moolenbroek                         processBitCast(M, bitCastMap, srcType, type);
27693e457fe3SDavid van Moolenbroek                     }
27703e457fe3SDavid van Moolenbroek                 }
27713e457fe3SDavid van Moolenbroek             }
27723e457fe3SDavid van Moolenbroek         }
27733e457fe3SDavid van Moolenbroek #endif
27743e457fe3SDavid van Moolenbroek 
27753e457fe3SDavid van Moolenbroek         for(i=0;i<user->getNumOperands();i++) {
27763e457fe3SDavid van Moolenbroek             User *operand = dyn_cast<User>(user->getOperand(i));
27773e457fe3SDavid van Moolenbroek             if(operand && !isa<Instruction>(operand) && !isa<GlobalVariable>(operand)) {
27783e457fe3SDavid van Moolenbroek                 users.push_back(operand);
27793e457fe3SDavid van Moolenbroek             }
27803e457fe3SDavid van Moolenbroek         }
27813e457fe3SDavid van Moolenbroek     }
27823e457fe3SDavid van Moolenbroek }
27833e457fe3SDavid van Moolenbroek 
fillStackInstrumentedFunctions(std::vector<Function * > & stackIntrumentedFuncs,Function * deepestLLFunction)27843e457fe3SDavid van Moolenbroek void MagicPass::fillStackInstrumentedFunctions(std::vector<Function*> &stackIntrumentedFuncs, Function *deepestLLFunction) {
27853e457fe3SDavid van Moolenbroek     assert(!deepestLLFunction->hasAddressTaken() && "Indirect calls not supported for detection of long-lived functions");
27863e457fe3SDavid van Moolenbroek     for(unsigned i=0;i<stackIntrumentedFuncs.size();i++) {
27873e457fe3SDavid van Moolenbroek         if(stackIntrumentedFuncs[i] == deepestLLFunction) {
27883e457fe3SDavid van Moolenbroek             return;
27893e457fe3SDavid van Moolenbroek         }
27903e457fe3SDavid van Moolenbroek     }
27913e457fe3SDavid van Moolenbroek     stackIntrumentedFuncs.push_back(deepestLLFunction);
2792*bdb56518SDavid van Moolenbroek     for (Value::user_iterator i = deepestLLFunction->user_begin(), e = deepestLLFunction->user_end(); i != e; ++i) {
27933e457fe3SDavid van Moolenbroek         User *user = *i;
27943e457fe3SDavid van Moolenbroek         if(Instruction *I = dyn_cast<Instruction>(user)) {
27953e457fe3SDavid van Moolenbroek             fillStackInstrumentedFunctions(stackIntrumentedFuncs, I->getParent()->getParent());
27963e457fe3SDavid van Moolenbroek         }
27973e457fe3SDavid van Moolenbroek     }
27983e457fe3SDavid van Moolenbroek }
27993e457fe3SDavid van Moolenbroek 
indexLocalTypeInfos(Module & M,Function * F,std::map<AllocaInst *,std::pair<TypeInfo *,std::string>> & localMap)28003e457fe3SDavid van Moolenbroek void MagicPass::indexLocalTypeInfos(Module &M, Function *F, std::map<AllocaInst*, std::pair<TypeInfo*, std::string> > &localMap) {
28013e457fe3SDavid van Moolenbroek   DIVariable DIV;
28023e457fe3SDavid van Moolenbroek   for (inst_iterator it = inst_begin(F), et = inst_end(F); it != et; ++it) {
28033e457fe3SDavid van Moolenbroek       AllocaInst *AI = dyn_cast<AllocaInst>(&(*it));
28043e457fe3SDavid van Moolenbroek       if(!AI) {
28053e457fe3SDavid van Moolenbroek           break;
28063e457fe3SDavid van Moolenbroek       }
28073e457fe3SDavid van Moolenbroek       const SmartType *aSmartType = SmartType::getSmartTypeFromLV(M, AI, &DIV);
28083e457fe3SDavid van Moolenbroek       if(!aSmartType || aSmartType == (const SmartType *)-1) {
28093e457fe3SDavid van Moolenbroek           // skip return and temporary variables
28103e457fe3SDavid van Moolenbroek           continue;
28113e457fe3SDavid van Moolenbroek       }
28123e457fe3SDavid van Moolenbroek       TypeInfo newTypeInfo(aSmartType);
28133e457fe3SDavid van Moolenbroek       TypeInfo *aTypeInfo = fillTypeInfos(newTypeInfo, globalTypeInfos);
28143e457fe3SDavid van Moolenbroek       if(aTypeInfo->getSmartType() != aSmartType) {
28153e457fe3SDavid van Moolenbroek           delete aSmartType;
28163e457fe3SDavid van Moolenbroek       }
28173e457fe3SDavid van Moolenbroek       std::string name = MagicUtil::getLVSourceName(M, AI).data();
28183e457fe3SDavid van Moolenbroek       std::pair<TypeInfo*, std::string> infoNamePair(aTypeInfo, name);
28193e457fe3SDavid van Moolenbroek       localMap.insert(std::pair<AllocaInst*, std::pair<TypeInfo*, std::string> >(AI, infoNamePair));
28203e457fe3SDavid van Moolenbroek   }
28213e457fe3SDavid van Moolenbroek }
28223e457fe3SDavid van Moolenbroek 
addMagicStackDsentryFuncCalls(Module & M,Function * insertCallsInFunc,Function * localsFromFunc,Function * dsentryCreateFunc,Function * dsentryDestroyFunc,TYPECONST StructType * dsentryStructType,std::map<AllocaInst *,std::pair<TypeInfo *,std::string>> localTypeInfoMap,std::map<TypeInfo *,Constant * > & magicArrayTypePtrMap,TypeInfo * voidPtrTypeInfo,std::vector<TypeInfo * > & typeInfoList,std::vector<std::pair<std::string,std::string>> & namesList,std::vector<int> & flagsList)28233e457fe3SDavid van Moolenbroek void MagicPass::addMagicStackDsentryFuncCalls(Module &M, Function *insertCallsInFunc, Function *localsFromFunc, Function *dsentryCreateFunc, Function *dsentryDestroyFunc, TYPECONST StructType *dsentryStructType, std::map<AllocaInst*, std::pair<TypeInfo*, std::string> > localTypeInfoMap, std::map<TypeInfo*, Constant*> &magicArrayTypePtrMap, TypeInfo *voidPtrTypeInfo, std::vector<TypeInfo*> &typeInfoList, std::vector<std::pair<std::string, std::string> > &namesList, std::vector<int> &flagsList) {
28243e457fe3SDavid van Moolenbroek   std::vector<Value*> locals;
28253e457fe3SDavid van Moolenbroek   std::map<AllocaInst*, std::pair<TypeInfo*, std::string> >::iterator localTypeInfoMapIt;
28263e457fe3SDavid van Moolenbroek   std::map<TypeInfo*, Constant*>::iterator magicArrayTypePtrMapIt;
28273e457fe3SDavid van Moolenbroek   std::vector<TypeInfo*> localTypeInfos;
28283e457fe3SDavid van Moolenbroek   std::vector<Value*> localTypeInfoValues;
28293e457fe3SDavid van Moolenbroek   std::vector<Value*> localDsentryValues;
28303e457fe3SDavid van Moolenbroek   std::string allocName, allocParentName;
28313e457fe3SDavid van Moolenbroek   Instruction *allocaI = NULL, *dsentryCreateI = NULL, *dsentryDestroyI = NULL;
28323e457fe3SDavid van Moolenbroek   // find local variables and types
28333e457fe3SDavid van Moolenbroek   for (inst_iterator it = inst_begin(localsFromFunc), et = inst_end(localsFromFunc); it != et; ++it) {
28343e457fe3SDavid van Moolenbroek       AllocaInst *AI = dyn_cast<AllocaInst>(&(*it));
28353e457fe3SDavid van Moolenbroek       if(!AI) {
28363e457fe3SDavid van Moolenbroek           break;
28373e457fe3SDavid van Moolenbroek       }
28383e457fe3SDavid van Moolenbroek       localTypeInfoMapIt = localTypeInfoMap.find(AI);
28393e457fe3SDavid van Moolenbroek       if(localTypeInfoMapIt != localTypeInfoMap.end()) {
28403e457fe3SDavid van Moolenbroek           assert(AI->hasName());
28413e457fe3SDavid van Moolenbroek           TypeInfo *aTypeInfo = localTypeInfoMapIt->second.first;
28423e457fe3SDavid van Moolenbroek           magicArrayTypePtrMapIt = magicArrayTypePtrMap.find(aTypeInfo);
28433e457fe3SDavid van Moolenbroek           assert(magicArrayTypePtrMapIt != magicArrayTypePtrMap.end());
28443e457fe3SDavid van Moolenbroek           Constant *aTypeInfoValue = magicArrayTypePtrMapIt->second;
28453e457fe3SDavid van Moolenbroek           localTypeInfos.push_back(aTypeInfo);
28463e457fe3SDavid van Moolenbroek           localTypeInfoValues.push_back(aTypeInfoValue);
28473e457fe3SDavid van Moolenbroek           locals.push_back(AI);
28483e457fe3SDavid van Moolenbroek       }
28493e457fe3SDavid van Moolenbroek   }
28503e457fe3SDavid van Moolenbroek   // find the first and the last valid instruction to place a call and the alloca point
28513e457fe3SDavid van Moolenbroek   dsentryCreateI = MagicUtil::getFirstNonAllocaInst(insertCallsInFunc);
28523e457fe3SDavid van Moolenbroek   dsentryDestroyI = insertCallsInFunc->back().getTerminator();
28533e457fe3SDavid van Moolenbroek   allocaI = MagicUtil::getFirstNonAllocaInst(insertCallsInFunc, false);
28543e457fe3SDavid van Moolenbroek 
28553e457fe3SDavid van Moolenbroek   // create one dsentry for each local variable
28563e457fe3SDavid van Moolenbroek   for(unsigned i=0;i<locals.size();i++) {
28573e457fe3SDavid van Moolenbroek       AllocaInst *AI = new AllocaInst(dsentryStructType, "dsentry_" + (locals[i]->hasName() ? locals[i]->getName() : "anon"), allocaI);
28583e457fe3SDavid van Moolenbroek       localDsentryValues.push_back(AI);
28593e457fe3SDavid van Moolenbroek   }
28603e457fe3SDavid van Moolenbroek   assert(localTypeInfoValues.size() == localDsentryValues.size());
28613e457fe3SDavid van Moolenbroek 
28623e457fe3SDavid van Moolenbroek   // create one dsentry and value set array for the return address
28633e457fe3SDavid van Moolenbroek   localTypeInfos.push_back(voidPtrTypeInfo);
28643e457fe3SDavid van Moolenbroek   localTypeInfoValues.push_back(new AllocaInst(ArrayType::get(IntegerType::get(M.getContext(), 32), 2), "dsentry_ret_addr_value_set", allocaI)); //pass the value set pointer as though it were a type pointer
28653e457fe3SDavid van Moolenbroek   localDsentryValues.push_back(new AllocaInst(dsentryStructType, "dsentry_ret_addr", allocaI));
28663e457fe3SDavid van Moolenbroek 
28673e457fe3SDavid van Moolenbroek   // create one dsentry pointer to remember the last stack dsentry
28683e457fe3SDavid van Moolenbroek   AllocaInst *prevLastStackDsentry = new AllocaInst(PointerType::get(dsentryStructType, 0), "prev_last_stack_dsentry", allocaI);
28693e457fe3SDavid van Moolenbroek 
28703e457fe3SDavid van Moolenbroek   // get the frame address of the function and pass the value as though it were a data pointer
28713e457fe3SDavid van Moolenbroek   Function *frameAddrIntrinsic = MagicUtil::getIntrinsicFunction(M, Intrinsic::frameaddress);
28723e457fe3SDavid van Moolenbroek   std::vector<Value*> frameAddrArgs;
28733e457fe3SDavid van Moolenbroek   frameAddrArgs.push_back(ConstantInt::get(M.getContext(), APInt(32, 0)));
28743e457fe3SDavid van Moolenbroek   CallInst *callInst = MagicUtil::createCallInstruction(frameAddrIntrinsic, frameAddrArgs, "", dsentryCreateI);
28753e457fe3SDavid van Moolenbroek   locals.push_back(callInst);
28763e457fe3SDavid van Moolenbroek 
28773e457fe3SDavid van Moolenbroek   // place calls
28783e457fe3SDavid van Moolenbroek   std::vector<Value*> dsentryCreateArgs;
28793e457fe3SDavid van Moolenbroek   std::vector<Value*> dsentryDestroyArgs;
28803e457fe3SDavid van Moolenbroek   dsentryCreateArgs.push_back(prevLastStackDsentry);
28813e457fe3SDavid van Moolenbroek   dsentryDestroyArgs.push_back(prevLastStackDsentry);
28823e457fe3SDavid van Moolenbroek   dsentryCreateArgs.push_back(ConstantInt::get(M.getContext(), APInt(32, locals.size())));
28833e457fe3SDavid van Moolenbroek   dsentryDestroyArgs.push_back(ConstantInt::get(M.getContext(), APInt(32, locals.size())));
28843e457fe3SDavid van Moolenbroek   allocParentName = MagicUtil::getFunctionSourceName(M, insertCallsInFunc, NULL, baseBuildDir);
28853e457fe3SDavid van Moolenbroek   int allocFlags = MAGIC_STATE_STACK;
28863e457fe3SDavid van Moolenbroek   for(unsigned i=0;i<locals.size();i++) {
28873e457fe3SDavid van Moolenbroek       //get name
28883e457fe3SDavid van Moolenbroek       if(AllocaInst *AI = dyn_cast<AllocaInst>(locals[i])) {
28893e457fe3SDavid van Moolenbroek           // local variable
28903e457fe3SDavid van Moolenbroek           localTypeInfoMapIt = localTypeInfoMap.find(AI);
28913e457fe3SDavid van Moolenbroek           assert(localTypeInfoMapIt != localTypeInfoMap.end());
28923e457fe3SDavid van Moolenbroek           allocName = localTypeInfoMapIt->second.second;
28933e457fe3SDavid van Moolenbroek       }
28943e457fe3SDavid van Moolenbroek       else {
28953e457fe3SDavid van Moolenbroek           // return address
28963e457fe3SDavid van Moolenbroek           allocName = MAGIC_ALLOC_RET_ADDR_NAME;
28973e457fe3SDavid van Moolenbroek       }
28983e457fe3SDavid van Moolenbroek       //add args
28993e457fe3SDavid van Moolenbroek       dsentryCreateArgs.push_back(localDsentryValues[i]);
29003e457fe3SDavid van Moolenbroek       dsentryCreateArgs.push_back(localTypeInfoValues[i]);
29013e457fe3SDavid van Moolenbroek       dsentryCreateArgs.push_back(locals[i]);
29023e457fe3SDavid van Moolenbroek       dsentryCreateArgs.push_back(MagicUtil::getStringRef(M, allocParentName));
29033e457fe3SDavid van Moolenbroek       dsentryCreateArgs.push_back(MagicUtil::getStringRef(M, allocName));
29043e457fe3SDavid van Moolenbroek       dsentryDestroyArgs.push_back(localDsentryValues[i]);
29053e457fe3SDavid van Moolenbroek       //add elements to type and names lists
29063e457fe3SDavid van Moolenbroek       typeInfoList.push_back(localTypeInfos[i]);
29073e457fe3SDavid van Moolenbroek       namesList.push_back(std::pair<std::string, std::string>(allocParentName, allocName));
29083e457fe3SDavid van Moolenbroek       flagsList.push_back(allocFlags);
29093e457fe3SDavid van Moolenbroek   }
29103e457fe3SDavid van Moolenbroek   MagicUtil::createCallInstruction(dsentryCreateFunc, dsentryCreateArgs, "", dsentryCreateI);
29113e457fe3SDavid van Moolenbroek   if(isa<ReturnInst>(dsentryDestroyI)) {
29123e457fe3SDavid van Moolenbroek       MagicUtil::createCallInstruction(dsentryDestroyFunc, dsentryDestroyArgs, "", dsentryDestroyI);
29133e457fe3SDavid van Moolenbroek   }
29143e457fe3SDavid van Moolenbroek }
29153e457fe3SDavid van Moolenbroek 
isExtLibrary(GlobalValue * GV,DIDescriptor * DID)29163e457fe3SDavid van Moolenbroek bool MagicPass::isExtLibrary(GlobalValue *GV, DIDescriptor *DID)
29173e457fe3SDavid van Moolenbroek {
29183e457fe3SDavid van Moolenbroek     static bool regexesInitialized = false;
29193e457fe3SDavid van Moolenbroek     static std::vector<Regex*> regexes;
29203e457fe3SDavid van Moolenbroek     if(!regexesInitialized) {
29213e457fe3SDavid van Moolenbroek         std::vector<std::string>::iterator it;
29223e457fe3SDavid van Moolenbroek         for (it = libPathRegexes.begin(); it != libPathRegexes.end(); ++it) {
29233e457fe3SDavid van Moolenbroek             Regex* regex = new Regex(*it, 0);
29243e457fe3SDavid van Moolenbroek             std::string error;
29253e457fe3SDavid van Moolenbroek             assert(regex->isValid(error));
29263e457fe3SDavid van Moolenbroek             regexes.push_back(regex);
29273e457fe3SDavid van Moolenbroek         }
29283e457fe3SDavid van Moolenbroek         regexesInitialized = true;
29293e457fe3SDavid van Moolenbroek     }
29303e457fe3SDavid van Moolenbroek     if (DID) {
29313e457fe3SDavid van Moolenbroek 	std::string relPath;
29323e457fe3SDavid van Moolenbroek 	PassUtil::getDbgLocationInfo(*DID, baseBuildDir, NULL, NULL, &relPath);
29333e457fe3SDavid van Moolenbroek         for(unsigned i=0;i<regexes.size();i++) {
29343e457fe3SDavid van Moolenbroek             if(regexes[i]->match(relPath, NULL)) {
29353e457fe3SDavid van Moolenbroek                 return true;
29363e457fe3SDavid van Moolenbroek             }
29373e457fe3SDavid van Moolenbroek         }
29383e457fe3SDavid van Moolenbroek     }
29393e457fe3SDavid van Moolenbroek     return PassUtil::matchRegexes(GV->getSection(), extLibSectionRegexes);
29403e457fe3SDavid van Moolenbroek }
29413e457fe3SDavid van Moolenbroek 
isMagicGV(Module & M,GlobalVariable * GV)29423e457fe3SDavid van Moolenbroek bool MagicPass::isMagicGV(Module &M, GlobalVariable *GV)
29433e457fe3SDavid van Moolenbroek {
29443e457fe3SDavid van Moolenbroek     if (GV->isThreadLocal() && (GV->getName().startswith(MAGIC_PREFIX_STR) || GV->getName().startswith("rcu"))) {
29453e457fe3SDavid van Moolenbroek         return true;
29463e457fe3SDavid van Moolenbroek     }
2947*bdb56518SDavid van Moolenbroek     if (!StringRef(GV->getSection()).compare(MAGIC_LLVM_METADATA_SECTION)) {
29483e457fe3SDavid van Moolenbroek 	return true;
29493e457fe3SDavid van Moolenbroek     }
29503e457fe3SDavid van Moolenbroek     if (GV->getName().startswith("__start") || GV->getName().startswith("__stop") || GV->getName().startswith("llvm.")) {
29513e457fe3SDavid van Moolenbroek         return true;
29523e457fe3SDavid van Moolenbroek     }
29533e457fe3SDavid van Moolenbroek     return PassUtil::matchRegexes(GV->getSection(), magicDataSectionRegexes);
29543e457fe3SDavid van Moolenbroek }
29553e457fe3SDavid van Moolenbroek 
isMagicFunction(Module & M,Function * F)29563e457fe3SDavid van Moolenbroek bool MagicPass::isMagicFunction(Module &M, Function *F)
29573e457fe3SDavid van Moolenbroek {
29583e457fe3SDavid van Moolenbroek 	if (F->getName().startswith("llvm.")) return true;
29593e457fe3SDavid van Moolenbroek     return PassUtil::matchRegexes(F->getSection(), magicFunctionSectionRegexes);
29603e457fe3SDavid van Moolenbroek }
29613e457fe3SDavid van Moolenbroek 
29623e457fe3SDavid van Moolenbroek #if MAGIC_USE_QPROF_INSTRUMENTATION
29633e457fe3SDavid van Moolenbroek 
qprofInstrumentationInit(Module & M)29643e457fe3SDavid van Moolenbroek void MagicPass::qprofInstrumentationInit(Module &M)
29653e457fe3SDavid van Moolenbroek {
29663e457fe3SDavid van Moolenbroek     // look up qprof configuration
29673e457fe3SDavid van Moolenbroek     qprofConf = QProfConf::get(M, &magicLLSitestacks,
29683e457fe3SDavid van Moolenbroek         &magicDeepestLLLoops,
29693e457fe3SDavid van Moolenbroek         &magicDeepestLLLibs,
29703e457fe3SDavid van Moolenbroek         &magicTaskClasses);
29713e457fe3SDavid van Moolenbroek     qprofConf->mergeAllTaskClassesWithSameDeepestLLLoops();
29723e457fe3SDavid van Moolenbroek 
29733e457fe3SDavid van Moolenbroek #if DEBUG_QPROF
29743e457fe3SDavid van Moolenbroek     qprofConf->print(errs());
29753e457fe3SDavid van Moolenbroek #endif
29763e457fe3SDavid van Moolenbroek }
29773e457fe3SDavid van Moolenbroek 
qprofInstrumentationApply(Module & M)29783e457fe3SDavid van Moolenbroek void MagicPass::qprofInstrumentationApply(Module &M)
29793e457fe3SDavid van Moolenbroek {
29803e457fe3SDavid van Moolenbroek     Function *hook;
29813e457fe3SDavid van Moolenbroek     std::vector<Value*> hookParams;
29823e457fe3SDavid van Moolenbroek     QProfSite* site;
29833e457fe3SDavid van Moolenbroek     std::vector<TYPECONST Type*>functionTyArgs;
29843e457fe3SDavid van Moolenbroek     FunctionType *hookFunctionTy;
29853e457fe3SDavid van Moolenbroek 
29863e457fe3SDavid van Moolenbroek     /*
29873e457fe3SDavid van Moolenbroek      * Instrument deepest long-lived loops. This creates a function
29883e457fe3SDavid van Moolenbroek      * pointer of the form void (*MAGIC_DEEPEST_LL_LOOP_HOOK_NAME)(char*, int)
29893e457fe3SDavid van Moolenbroek      * called (if set by instrumentation libraries) at the top of every loop.
29903e457fe3SDavid van Moolenbroek      */
29913e457fe3SDavid van Moolenbroek     functionTyArgs.push_back(PointerType::get(IntegerType::get(M.getContext(), 8), 0));
29923e457fe3SDavid van Moolenbroek     functionTyArgs.push_back(IntegerType::get(M.getContext(), 32));
29933e457fe3SDavid van Moolenbroek     hookFunctionTy = PassUtil::getFunctionType(Type::getVoidTy(M.getContext()), functionTyArgs, false);
29943e457fe3SDavid van Moolenbroek     std::vector<QProfSite*> deepestLLLoops = qprofConf->getDeepestLLLoops();
29953e457fe3SDavid van Moolenbroek     hook = PassUtil::getOrInsertFunction(M, MAGIC_DEEPEST_LL_LOOP_HOOK_NAME, hookFunctionTy,
29963e457fe3SDavid van Moolenbroek         PASS_UTIL_LINKAGE_WEAK_POINTER, PASS_UTIL_FLAG(PASS_UTIL_PROP_PRESERVE));
29973e457fe3SDavid van Moolenbroek     assert(hook);
29983e457fe3SDavid van Moolenbroek     for (unsigned i=0;i<deepestLLLoops.size();i++) {
29993e457fe3SDavid van Moolenbroek         site = deepestLLLoops[i];
30003e457fe3SDavid van Moolenbroek         hookParams.clear();
30013e457fe3SDavid van Moolenbroek         Constant* siteString = MagicUtil::getArrayPtr(M, MagicUtil::getStringRef(M, site->toString()));
30023e457fe3SDavid van Moolenbroek         hookParams.push_back(siteString);
30033e457fe3SDavid van Moolenbroek         hookParams.push_back(ConstantInt::get(M.getContext(), APInt(32, site->taskClassID, 10)));
30043e457fe3SDavid van Moolenbroek         PassUtil::createCallInstruction(hook, hookParams, "", site->siteInstruction);
30053e457fe3SDavid van Moolenbroek     }
30063e457fe3SDavid van Moolenbroek 
30073e457fe3SDavid van Moolenbroek     /*
30083e457fe3SDavid van Moolenbroek      * Instrument deepest long-lived library calls. This creates a function
30093e457fe3SDavid van Moolenbroek      * pointer of the form void (*MAGIC_DEEPEST_LL_LIB_HOOK_NAME)(char*, int, int, int)
30103e457fe3SDavid van Moolenbroek      * called (if set by instrumentation libraries) before every library call.
30113e457fe3SDavid van Moolenbroek      */
30123e457fe3SDavid van Moolenbroek     functionTyArgs.clear();
30133e457fe3SDavid van Moolenbroek     functionTyArgs.push_back(PointerType::get(IntegerType::get(M.getContext(), 8), 0));
30143e457fe3SDavid van Moolenbroek     functionTyArgs.push_back(IntegerType::get(M.getContext(), 32));
30153e457fe3SDavid van Moolenbroek     functionTyArgs.push_back(IntegerType::get(M.getContext(), 32));
30163e457fe3SDavid van Moolenbroek     functionTyArgs.push_back(IntegerType::get(M.getContext(), 32));
30173e457fe3SDavid van Moolenbroek     hookFunctionTy = PassUtil::getFunctionType(Type::getVoidTy(M.getContext()), functionTyArgs, false);
30183e457fe3SDavid van Moolenbroek     std::vector<QProfSite*> deepestLLLibs = qprofConf->getDeepestLLLibs();
30193e457fe3SDavid van Moolenbroek     hook = PassUtil::getOrInsertFunction(M, MAGIC_DEEPEST_LL_LIB_HOOK_NAME, hookFunctionTy,
30203e457fe3SDavid van Moolenbroek         PASS_UTIL_LINKAGE_WEAK_POINTER, PASS_UTIL_FLAG(PASS_UTIL_PROP_PRESERVE));
30213e457fe3SDavid van Moolenbroek     assert(hook);
30223e457fe3SDavid van Moolenbroek     for (unsigned i=0;i<deepestLLLibs.size();i++) {
30233e457fe3SDavid van Moolenbroek         site = deepestLLLibs[i];
30243e457fe3SDavid van Moolenbroek         hookParams.clear();
30253e457fe3SDavid van Moolenbroek         Constant* siteString = MagicUtil::getArrayPtr(M, MagicUtil::getStringRef(M, site->toString()));
30263e457fe3SDavid van Moolenbroek         hookParams.push_back(siteString);
30273e457fe3SDavid van Moolenbroek         hookParams.push_back(ConstantInt::get(M.getContext(), APInt(32, site->taskClassID, 10)));
30283e457fe3SDavid van Moolenbroek         hookParams.push_back(ConstantInt::get(M.getContext(), APInt(32, site->taskSiteID, 10)));
30293e457fe3SDavid van Moolenbroek         hookParams.push_back(ConstantInt::get(M.getContext(), APInt(32, site->libFlags, 10)));
30303e457fe3SDavid van Moolenbroek         PassUtil::createCallInstruction(hook, hookParams, "", site->siteInstruction);
30313e457fe3SDavid van Moolenbroek     }
30323e457fe3SDavid van Moolenbroek 
30333e457fe3SDavid van Moolenbroek     /*
30343e457fe3SDavid van Moolenbroek      * Create relevant exported variables in use by the libraries.
30353e457fe3SDavid van Moolenbroek      */
30363e457fe3SDavid van Moolenbroek     MagicUtil::getExportedIntGlobalVar(M, MAGIC_NUM_LL_TASK_CLASSES_NAME, qprofConf->getNumLLTaskClasses());
30373e457fe3SDavid van Moolenbroek     MagicUtil::getExportedIntGlobalVar(M, MAGIC_NUM_LL_BLOCK_EXT_TASK_CLASSES_NAME, qprofConf->getNumLLBlockExtTaskClasses());
30383e457fe3SDavid van Moolenbroek     MagicUtil::getExportedIntGlobalVar(M, MAGIC_NUM_LL_BLOCK_INT_TASK_CLASSES_NAME, qprofConf->getNumLLBlockIntTaskClasses());
30393e457fe3SDavid van Moolenbroek     MagicUtil::getExportedIntGlobalVar(M, MAGIC_NUM_LL_BLOCK_EXT_LIBS_NAME, qprofConf->getNumLLBlockExtLibs());
30403e457fe3SDavid van Moolenbroek     MagicUtil::getExportedIntGlobalVar(M, MAGIC_NUM_LL_BLOCK_INT_LIBS_NAME, qprofConf->getNumLLBlockIntLibs());
30413e457fe3SDavid van Moolenbroek }
30423e457fe3SDavid van Moolenbroek 
30433e457fe3SDavid van Moolenbroek #else
30443e457fe3SDavid van Moolenbroek 
qprofInstrumentationInit(Module & M)30453e457fe3SDavid van Moolenbroek void MagicPass::qprofInstrumentationInit(Module &M) {}
qprofInstrumentationApply(Module & M)30463e457fe3SDavid van Moolenbroek void MagicPass::qprofInstrumentationApply(Module &M) {}
30473e457fe3SDavid van Moolenbroek 
30483e457fe3SDavid van Moolenbroek #endif
30493e457fe3SDavid van Moolenbroek 
30503e457fe3SDavid van Moolenbroek } // end namespace
30513e457fe3SDavid van Moolenbroek 
30523e457fe3SDavid van Moolenbroek char MagicPass::ID = 0;
30533e457fe3SDavid van Moolenbroek RegisterPass<MagicPass> MP("magic", "Magic Pass to Build a Table of Global Variables");
30543e457fe3SDavid van Moolenbroek 
3055