void process::cont_from_bp(uintptr_t pc) { // known BP? sinsn_t orig_insn; try { orig_insn = pelf_->get_byte_at(pc); } catch(...) { tracer_.cont(); return; } // PLT tweaking if (pelf_->is_PLT_enter(pc) && (! pelf_->is_cxa_throw_addr(pc))) { uintptr_t GOT_addr = get_GOT_addr(pc, tracer_); uintptr_t GOT_value = tracer_.get_word(GOT_addr); if (GOT_value != pc + HT_PLT_INSN_SIZE) { // NOT first PLT call. uintptr_t sp = tracer_.get_sp(); uintptr_t ret_addr = tracer_.get_word(sp); plt_call_stack_.push(ret_addr); // rewrite return address tracer_.set_word(sp, pc + HT_PLT_INSN_SIZE); } } else if (pelf_->is_PLT_leave(pc)) { uintptr_t GOT_addr = get_GOT_addr(pc - HT_PLT_INSN_SIZE, tracer_); uintptr_t GOT_value = tracer_.get_word(GOT_addr); if (GOT_value != pc) { // NOT first PLT call. assert(! plt_call_stack_.empty()); uintptr_t ret_addr = plt_call_stack_.top(); plt_call_stack_.pop(); tracer_.set_pc(ret_addr); tracer_.cont(); return; // no single-step. just cont. } } // recover original insn, then single step. tracer_.set_byte(pc, orig_insn); tracer_.offset_pc(-1 * BREAKPOINT_INSN_LEN); tracer_.single_step(); again: if (::waitpid(get_pid(), NULL, __WALL) == -1) { if (errno == EINTR) { goto again; } THROW_ERRNO("waitpid"); } // put breakpoint again. tracer_.break_at(pc); tracer_.cont(); return; }
void Interpreter::loadModuleRecursive (const string &moduleName) { debug ("Interpreter::loadModuleRecursive " "(moduleName = " << moduleName << ")"); if (moduleIsLoadedInternal (moduleName)) { debug ("\talready loaded"); return; } // // Using the module search path, locate the file that contains the // source code for the module. Open the file. // string fileName = findModule (moduleName); ifstream file (fileName.c_str()); if (!file) { THROW_ERRNO ("Cannot load CTL module \"" << moduleName << "\". " "Opening file \"" << fileName << "\" for reading " "failed (%T)."); } debug ("\tloading from file \"" << fileName << "\""); Module *module = 0; LContext *lcontext = 0; try { // // Create a Module, an Lcontext and a Parser // module = newModule (moduleName, fileName); _data->moduleSet.addModule (module); lcontext = newLContext (file, module, _data->symtab); Parser parser (*lcontext, *this); // // Parse the source code and generate executable code // for the module // debug ("\tparsing input"); SyntaxNodePtr syntaxTree = parser.parseInput (); if (syntaxTree && lcontext->numErrors() == 0) { debug ("\tgenerating code"); syntaxTree->generateCode (*lcontext); } if (lcontext->numErrors() > 0) { lcontext->printDeclaredErrors(); THROW (LoadModuleExc, "Failed to load CTL module \"" << moduleName << "\"."); } // // Run the module's initialization code // debug ("\trunning module initialization code"); module->runInitCode(); // // Cleanup: the LContext and the module's local symbols // are no longer needed, but we keep the global symbols. // debug ("\tcleanup"); delete lcontext; _data->symtab.deleteAllLocalSymbols (module); } catch (...) { // // Something went wrong while loading the module, clean up // delete lcontext; _data->symtab.deleteAllSymbols (module); _data->moduleSet.removeModule (moduleName); throw; } }