void DICFG::parse_all(void) { BPatch_addressSpace *handle = cfg_handle; SymtabCodeSource *sts = cfg_sts; CodeObject *co = cfg_co; // Parse the binary co->parse(); /* Parse the functions found by the BPatch API */ BPatch_image *image = handle->getImage(); std::vector<BPatch_module *> *mods = image->getModules(); std::vector<BPatch_module *>::iterator mods_iter; for (mods_iter = mods->begin(); mods_iter != mods->end(); mods_iter++) { address_t mod_start = (address_t)(*mods_iter)->getBaseAddr(); address_t mod_end = (address_t)(*mods_iter)->getBaseAddr() + (*mods_iter)->getSize(); if((get_start_addr() == 0) || (mod_start < get_start_addr())) { set_start_addr(mod_start); } if((get_end_addr() == 0) || (mod_end > get_end_addr())) { set_end_addr(mod_end); } std::vector<BPatch_function *> *funcs = (*mods_iter)->getProcedures(false); std::vector<BPatch_function *>::iterator funcs_iter = funcs->begin(); for(; funcs_iter != funcs->end(); funcs_iter++) { co->parse((Address)(*funcs_iter)->getBaseAddr(), true); } } /* Parse PLT entries */ Symtab *symtab = Symtab::findOpenSymtab(string((char *) this->get_module_name().c_str())); vector<SymtabAPI::relocationEntry> fbt; vector<SymtabAPI::relocationEntry>::iterator fbt_iter; symtab->getFuncBindingTable(fbt); for (fbt_iter = fbt.begin(); fbt_iter != fbt.end(); fbt_iter++) { co->parse((Address)((*fbt_iter).target_addr()), true); } const CodeObject::funclist& funcs = co->funcs(); insert_functions_and_bbs(funcs); for (fbt_iter = fbt.begin(); fbt_iter != fbt.end(); fbt_iter++) { address_t plt_fun_addr = (address_t)(*fbt_iter).target_addr(); if((get_start_addr() == 0) || (plt_fun_addr < get_start_addr())) { set_start_addr(plt_fun_addr); } if((get_end_addr() == 0) || (plt_fun_addr > get_end_addr())) { set_end_addr(plt_fun_addr); } mark_function_as_plt(plt_fun_addr); } }
BPatch_point *BPatch_addressSpace::createBPPointCB(AddressSpace *a, Dyninst::PatchAPI::PatchFunction *pf, Dyninst::PatchAPI::Point *p, int type) { func_instance *fi = static_cast<func_instance *>(pf); instPoint *ip = static_cast<instPoint *>(p); BPatch_addressSpace *aS = (BPatch_addressSpace *)a->up_ptr(); assert(aS); BPatch_module *bpmod = aS->getImage()->findOrCreateModule(fi->mod()); assert(bpmod); BPatch_function *func = aS->findOrCreateBPFunc(fi, bpmod); assert(func); return aS->findOrCreateBPPoint(func, ip, (BPatch_procedureLocation) type); }
BPatch_function *BPatch_addressSpace::createBPFuncCB(AddressSpace *a, Dyninst::PatchAPI::PatchFunction *f) { BPatch_addressSpace *aS = (BPatch_addressSpace *)a->up_ptr(); assert(aS); return aS->findOrCreateBPFunc(f, NULL); }
int main (int argc, char *argv[]) { set<string> UserFunctions; set<string> ParallelFunctions; map<string, vector<string> > LoopLevels; char *env_var; int index; if (getenv("EXTRAE_HOME") == NULL) { cerr << PACKAGE_NAME << ": Environment variable EXTRAE_HOME is undefined" << endl; exit (-1); } if ((env_var = getenv ("DYNINSTAPI_RT_LIB")) == NULL) { env_var = (char*) malloc ((1+strlen("DYNINSTAPI_RT_LIB=")+strlen(DYNINST_RT_LIB))*sizeof(char)); if (env_var == NULL) { cerr << PACKAGE_NAME << ": Cannot allocate memory to define DYNINSTAPI_RT_LIB!" << endl; exit (-1); } sprintf (env_var, "DYNINSTAPI_RT_LIB=%s", DYNINST_RT_LIB); putenv (env_var); } else cout << PACKAGE_NAME << ": Warning, DYNINSTAPI_RT_LIB already set and pointing to " << env_var << endl; /* Parse the params */ index = processParams (argc, argv); char * envvar_dyn = (char *) malloc ((strlen("EXTRAE_DYNINST_RUN=yes")+1)*sizeof (char)); if (NULL == envvar_dyn) { cerr << PACKAGE_NAME << ": Error! Unable to allocate memory for EXTRAE_DYNINST_RUN environment variable" << endl; exit (-1); } sprintf (envvar_dyn, "EXTRAE_DYNINST_RUN=yes"); putenv (envvar_dyn); if (!ListFunctions) { if (configXML != NULL) { char * envvar = (char *) malloc ((strlen(configXML)+strlen("EXTRAE_CONFIG_FILE=")+1)*sizeof (char)); if (NULL == envvar) { cerr << PACKAGE_NAME << ": Error! Unable to allocate memory for EXTRAE_CONFIG_FILE environment variable" << endl; exit (-1); } sprintf (envvar, "EXTRAE_CONFIG_FILE=%s", configXML); putenv (envvar); } else { if (getenv ("EXTRAE_CONFIG_FILE") == NULL) { cerr << PACKAGE_NAME << ": Error! You have to provide a configuration file using the -config parameter or set the EXTRAE_CONFIG_FILE" << endl; exit (-1); } configXML = getenv ("EXTRAE_CONFIG_FILE"); } if (!file_exists(configXML)) { cerr << PACKAGE_NAME << ": Error! Unable to locate " << configXML << endl; exit (-1); } ::Parse_XML_File (0, 0, configXML); } /* Does the binary exists? */ if (!file_exists(argv[index])) { cout << PACKAGE_NAME << ": Executable " << argv[index] << " cannot be found!" << endl; exit (-1); } /* Create an instance of the BPatch library */ bpatch = new BPatch; /* Register a callback function that prints any error messages */ bpatch->registerErrorCallback (errorFunc); /* Don't check recursion in snippets */ bpatch->setTrampRecursive (true); cout << "Welcome to " << PACKAGE_STRING << " launcher using DynInst " << DYNINST_MAJOR << "." << DYNINST_MINOR << "." << DYNINST_SUBMINOR << endl; int i = 1; while (argv[index+i] != NULL) { cout << PACKAGE_NAME << ": Argument " << i << " - " << argv[index+i] << endl; i++; } BPatch_process *appProcess = NULL; BPatch_binaryEdit *appBin = NULL; BPatch_addressSpace *appAddrSpace = NULL; if (!BinaryRewrite) { cout << PACKAGE_NAME << ": Creating process for image binary " << argv[index]; cout.flush (); appProcess = bpatch->processCreate ((const char*) argv[index], (const char**) &argv[index], (const char**) environ); if (appProcess == NULL) { cerr << endl << PACKAGE_NAME << ": Error creating the target application process" << endl; exit (-1); } cout << " PID(" << appProcess->getPid() << ")" << endl; /* Stop the execution in order to load the instrumentation library */ cout << PACKAGE_NAME << ": Stopping mutatee execution" << endl; if (!appProcess->stopExecution()) { cerr << PACKAGE_NAME << ": Cannot stop execution of the target application" << endl; exit (-1); } appAddrSpace = appProcess; } else { cout << PACKAGE_NAME << ": Rewriting binary " << argv[index] << endl; appBin = bpatch->openBinary ((const char*) argv[index], false); /* passed true to instrument libraries before !? */ if (appBin == NULL) { cerr << PACKAGE_NAME << ": Error opening binary for rewriting" << endl; exit (-1); } appAddrSpace = appBin; } BPatch_image *appImage = appAddrSpace->getImage(); if (appImage == NULL) { cerr << PACKAGE_NAME << ": Error while acquiring application image" << endl; exit (-1); } /* The user asks for the list of functions, simply show it */ if (ListFunctions) { ShowFunctions (appImage); if (!BinaryRewrite) appProcess->terminateExecution(); exit (-1); } /* Read files */ if (::XML_have_UFlist()) { if (VerboseLevel) cout << PACKAGE_NAME << ": Reading instrumented user functions from " << ::XML_UFlist() << endl; ReadFileIntoList (::XML_UFlist(), UserFunctions); discoverInstrumentationLevel(UserFunctions, LoopLevels); } if (DecodeBasicBlock) { std::set<string>::iterator f_begin = UserFunctions.begin(); std::set<string>::iterator f_end = UserFunctions.end(); while (f_begin != f_end) { BPatch_function *f = getRoutine ((*f_begin).c_str(), appImage); if (f == NULL) { cerr << PACKAGE_NAME << ": Unable to find " << *f_begin << " function!" << endl; } else { cout<<decodeBasicBlocks(f, *f_begin); } f_begin++; } if (!BinaryRewrite) { appProcess->terminateExecution(); } exit(-1); } if (::XML_CheckTraceEnabled()) { ApplicationType *appType = new ApplicationType (); extrae_detecting_application_type = true; cout << PACKAGE_NAME << ": Detecting application type " << endl; appType->detectApplicationType (appImage); appType->dumpApplicationType (); cout << PACKAGE_NAME << ": Detecting whether the application has been already linked with Extrae : "; BPatch_function *extrae_init = getRoutine ("Extrae_init", appImage, false); BinaryLinkedWithInstrumentation = extrae_init != NULL; cout << (BinaryLinkedWithInstrumentation?"yes":"no") << endl; extrae_detecting_application_type = false; /* If the application has not been linked with instrumentation library, load the appropriate module */ if (!BinaryLinkedWithInstrumentation) { char buffer[1024]; /* will hold the library to load */ /* Check for the correct library to be loaded */ if (appType->get_isMPI()) { if (appType->get_isOpenMP()) { if (appType->get_MPI_type() == ApplicationType::MPI_C) sprintf (buffer, "%s/lib/lib_dyn_ompitracec-%s.so", getenv("EXTRAE_HOME"), PACKAGE_VERSION); else sprintf (buffer, "%s/lib/lib_dyn_ompitracef-%s.so", getenv("EXTRAE_HOME"), PACKAGE_VERSION); } else if (appType->get_isCUDA()) { if (appType->get_MPI_type() == ApplicationType::MPI_C) sprintf (buffer, "%s/lib/lib_dyn_cudampitracec-%s.so", getenv("EXTRAE_HOME"), PACKAGE_VERSION); else sprintf (buffer, "%s/lib/lib_dyn_cudampitracef-%s.so", getenv("EXTRAE_HOME"), PACKAGE_VERSION); } else { if (appType->get_MPI_type() == ApplicationType::MPI_C) sprintf (buffer, "%s/lib/lib_dyn_mpitracec-%s.so", getenv("EXTRAE_HOME"), PACKAGE_VERSION); else sprintf (buffer, "%s/lib/lib_dyn_mpitracef-%s.so", getenv("EXTRAE_HOME"), PACKAGE_VERSION); } } else { if (appType->get_isOpenMP()) { sprintf (buffer, "%s/lib/libomptrace-%s.so", getenv("EXTRAE_HOME"), PACKAGE_VERSION); } else { if (appType->get_isCUDA()) sprintf (buffer, "%s/lib/libcudatrace-%s.so", getenv("EXTRAE_HOME"), PACKAGE_VERSION); else sprintf (buffer, "%s/lib/libseqtrace-%s.so", getenv("EXTRAE_HOME"), PACKAGE_VERSION); } } loadedModule = buffer; /* Load the module into the mutattee */ cout << PACKAGE_NAME << ": Loading " << loadedModule << " into the target application" << endl; if (!file_exists (buffer)) { /* If the library does not exist, terminate the mutatee and exit */ cerr << PACKAGE_NAME << ": Cannot find the module. It must be under $EXTRAE_HOME/lib" << endl; appProcess->terminateExecution(); exit (-1); } if (!appAddrSpace->loadLibrary (loadedModule.c_str())) { /* If the library cannot be loaded, terminate the mutatee and exit */ cerr << PACKAGE_NAME << ": Cannot load library! Retry using -v to gather more information on this error!" << endl; appProcess->terminateExecution(); exit (-1); } } /* ! BinaryLinkedWithInstrumentation */ else cout << PACKAGE_NAME << ": The application seems to be linked with Extrae libraries. Won't load additional libraries..." << endl; /* Load instrumentation API patches */ loadAPIPatches (appImage); if (appType->get_isMPI() && ::XML_GetTraceMPI()) loadMPIPatches (appImage); /* Instrument fork, wait, waitpid and exec calls */ InstrumentForks (appImage); /* Apply instrumentation of runtimes only if not linked with Extrae */ if (!BinaryLinkedWithInstrumentation && appType->get_isOpenMP()) { if (appType->get_OpenMP_rte() == ApplicationType::Intel_v11) { cout << PACKAGE_NAME << ": Gathering information for Intel v11 OpenMP runtime" << endl; # warning "Aixo nomes es per !BinaryRewriting!" InstrumentOMPruntime_Intel (appImage, appProcess); } cout << PACKAGE_NAME << ": Instrumenting OpenMP runtime" << endl; InstrumentOMPruntime (::XML_GetTraceOMP_locks(), appType, appImage); } /* Apply instrumentation of runtimes only if not linked with Extrae */ if (!BinaryLinkedWithInstrumentation && appType->get_isCUDA()) { cout << PACKAGE_NAME << ": Instrumenting CUDA runtime" << endl; InstrumentCUDAruntime (appType, appImage); } /* If the application is NOT MPI, instrument the MAIN symbol in order to initialize and finalize the instrumentation */ /* Apply instrumentation of runtimes only if not linked with Extrae */ if (!appType->get_isMPI()) { /* Typical main entry & exit */ wrapRoutine (appImage, "main", "Extrae_init", "Extrae_fini"); } else { /* Cover those cases that MPI apps do not call MPI_Finalize */ wrapRoutine (appImage, "main", "", "Extrae_fini_last_chance_Wrapper"); } { /* Special cases (e.g., fortran stop call) */ string exit_calls[] = { "exit", /* C */ "_xlfExit", /* Fortran IBM XL */ "_gfortran_stop_numeric", /* Fortran GNU */ "for_stop_core", /* Fortran Intel */ "" }; /* bypass error messages given if these routines are not found */ int i = 0; extrae_detecting_application_type = true; while (exit_calls[i].length() > 0) { BPatch_function *special_exit = getRoutine (exit_calls[i].c_str(), appImage, false); if (NULL != special_exit) wrapRoutine (appImage, exit_calls[i], "Extrae_fini_last_chance_Wrapper", ""); i++; } extrae_detecting_application_type = false; } InstrumentCalls (appImage, appAddrSpace, appType, ParallelFunctions, UserFunctions, LoopLevels, ::XML_GetTraceMPI(), ::XML_GetTraceOMP(), true); GenerateSymFile (ParallelFunctions, UserFunctions, appImage, appAddrSpace); } // bpatch->registerExecCallback(ExecCallback); if (!BinaryRewrite) { cout << PACKAGE_NAME << ": Starting program execution" << endl; if (!appProcess->continueExecution()) { /* If the application cannot continue, terminate the mutatee and exit */ cerr << PACKAGE_NAME << ": Cannot continue execution of the target application" << endl; appProcess->terminateExecution(); exit (-1); } while (!appProcess->isTerminated()) bpatch->waitForStatusChange(); if (appProcess->terminationStatus() == ExitedNormally) appProcess->getExitCode(); else if(appProcess->terminationStatus() == ExitedViaSignal) appProcess->getExitSignal(); delete appProcess; } else { string newfile = string(argv[index])+".extrae"; cout << PACKAGE_NAME << ": Generating the instrumented binary" << endl; if (appBin->writeFile (newfile.c_str())) cout << PACKAGE_NAME << ": Congratulations " << newfile << " has been generated" << endl; else cout << PACKAGE_NAME << ": Error! Could not generate " << newfile << endl; delete appBin; } return 0; }