Esempio n. 1
0
  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;
  }
Esempio n. 2
0
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;
    }
}