Exemplo n.º 1
0
bool ThreadSpec::TIDMatches(Thread &thread) const {
  if (m_tid == LLDB_INVALID_THREAD_ID)
    return true;

  lldb::tid_t thread_id = thread.GetID();
  return TIDMatches(thread_id);
}
Exemplo n.º 2
0
SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
                                ThreadPlan *new_plan) {
  SBError sb_error;

  Process *process = exe_ctx.GetProcessPtr();
  if (!process) {
    sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
    return sb_error;
  }

  Thread *thread = exe_ctx.GetThreadPtr();
  if (!thread) {
    sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
    return sb_error;
  }

  // User level plans should be Master Plans so they can be interrupted, other
  // plans executed, and
  // then a "continue" will resume the plan.
  if (new_plan != NULL) {
    new_plan->SetIsMasterPlan(true);
    new_plan->SetOkayToDiscard(false);
  }

  // Why do we need to set the current thread by ID here???
  process->GetThreadList().SetSelectedThreadByID(thread->GetID());

  if (process->GetTarget().GetDebugger().GetAsyncExecution())
    sb_error.ref() = process->Resume();
  else
    sb_error.ref() = process->ResumeSynchronous(NULL);

  return sb_error;
}
Exemplo n.º 3
0
void SBThread::StepOutOfFrame(lldb::SBFrame &sb_frame) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));

  std::unique_lock<std::recursive_mutex> lock;
  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);

  if (!sb_frame.IsValid()) {
    if (log)
      log->Printf(
          "SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.",
          static_cast<void *>(exe_ctx.GetThreadPtr()));
    return;
  }

  StackFrameSP frame_sp(sb_frame.GetFrameSP());
  if (log) {
    SBStream frame_desc_strm;
    sb_frame.GetDescription(frame_desc_strm);
    log->Printf("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)",
                static_cast<void *>(exe_ctx.GetThreadPtr()),
                static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
  }

  if (exe_ctx.HasThreadScope()) {
    bool abort_other_plans = false;
    bool stop_other_threads = false;
    Thread *thread = exe_ctx.GetThreadPtr();
    if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
      log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another "
                  "thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.",
                  static_cast<void *>(exe_ctx.GetThreadPtr()),
                  sb_frame.GetThread().GetThreadID(), thread->GetID());
    }

    ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
        abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
        eVoteNoOpinion, frame_sp->GetFrameIndex()));

    // This returns an error, we should use it!
    ResumeNewPlan(exe_ctx, new_plan_sp.get());
  }
}
Exemplo n.º 4
0
bool
ABISysV_mips::PrepareTrivialCall (Thread &thread,
                                  addr_t sp,
                                  addr_t func_addr,
                                  addr_t return_addr,
                                  llvm::ArrayRef<addr_t> args) const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    if (log)
    {
        StreamString s;
        s.Printf("ABISysV_mips::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
                    thread.GetID(),
                    (uint64_t)sp,
                    (uint64_t)func_addr,
                    (uint64_t)return_addr);

        for (size_t i = 0; i < args.size(); ++i)
            s.Printf (", arg%zd = 0x%" PRIx64, i + 1, args[i]);
        s.PutCString (")");
        log->PutCString(s.GetString().c_str());
    }

    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    if (!reg_ctx)
        return false;

    const RegisterInfo *reg_info = NULL;

    RegisterValue reg_value;

    // Argument registers
    const char *reg_names[] = { "r4", "r5", "r6", "r7" };

    llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();

    // Write arguments to registers
    for (size_t i = 0; i < llvm::array_lengthof(reg_names); ++i)
    {
        if (ai == ae)
            break;

        reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
        if (log)
            log->Printf("About to write arg%zd (0x%" PRIx64 ") into %s", i + 1, args[i], reg_info->name);

        if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
            return false;

        ++ai;
    }

    // If we have more than 4 arguments --Spill onto the stack
    if (ai != ae)
    {
        // No of arguments to go on stack 
        size_t num_stack_regs = args.size();

        // Allocate needed space for args on the stack
        sp -= (num_stack_regs * 4);

        // Keep the stack 8 byte aligned
        sp &= ~(8ull-1ull);

        // just using arg1 to get the right size
        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
        
        addr_t arg_pos = sp+16;
        
        size_t i = 4;
        for (; ai != ae; ++ai)
        {
            reg_value.SetUInt32(*ai);
            if (log)
                log->Printf("About to write arg%zd (0x%" PRIx64 ") at  0x%" PRIx64 "", i+1, args[i], arg_pos);
            
            if (reg_ctx->WriteRegisterValueToMemory(reg_info, arg_pos, reg_info->byte_size, reg_value).Fail())
                return false;
            arg_pos += reg_info->byte_size;
            i++;
        }
    }

    Error error;
    const RegisterInfo *pc_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
    const RegisterInfo *sp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
    const RegisterInfo *ra_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);

    if (log)
    log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);

    // Set "sp" to the requested value
    if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_info, sp))
        return false;

    if (log)
    log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);

    // Set "ra" to the return address
    if (!reg_ctx->WriteRegisterFromUnsigned (ra_reg_info, return_addr))
        return false;

    if (log)
        log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr);

    // Set pc to the address of the called function.
    if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_info, func_addr))
        return false;

    return true;
}
Exemplo n.º 5
0
bool ABISysV_ppc64::PrepareTrivialCall(Thread &thread, addr_t sp,
                                       addr_t func_addr, addr_t return_addr,
                                       llvm::ArrayRef<addr_t> args) const {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

  if (log) {
    StreamString s;
    s.Printf("ABISysV_ppc64::PrepareTrivialCall (tid = 0x%" PRIx64
             ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
             ", return_addr = 0x%" PRIx64,
             thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
             (uint64_t)return_addr);

    for (size_t i = 0; i < args.size(); ++i)
      s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),
               args[i]);
    s.PutCString(")");
    log->PutString(s.GetString());
  }

  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
  if (!reg_ctx)
    return false;

  const RegisterInfo *reg_info = nullptr;

  if (args.size() > 8) // TODO handle more than 8 arguments
    return false;

  for (size_t i = 0; i < args.size(); ++i) {
    reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
                                        LLDB_REGNUM_GENERIC_ARG1 + i);
    if (log)
      log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
                  static_cast<uint64_t>(i + 1), args[i], reg_info->name);
    if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
      return false;
  }

  // First, align the SP

  if (log)
    log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
                (uint64_t)sp, (uint64_t)(sp & ~0xfull));

  sp &= ~(0xfull); // 16-byte alignment

  sp -= 8;

  Status error;
  const RegisterInfo *pc_reg_info =
      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
  const RegisterInfo *sp_reg_info =
      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
  ProcessSP process_sp(thread.GetProcess());

  RegisterValue reg_value;

  if (log)
    log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
                ": 0x%" PRIx64,
                (uint64_t)sp, (uint64_t)return_addr);

  // Save return address onto the stack
  if (!process_sp->WritePointerToMemory(sp, return_addr, error))
    return false;

  // %r1 is set to the actual stack value.

  if (log)
    log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);

  if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
    return false;

  // %pc is set to the address of the called function.

  if (log)
    log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);

  if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
    return false;

  return true;
}
Exemplo n.º 6
0
bool
ABISysV_ppc::PrepareTrivialCall (Thread &thread,
                                    addr_t sp,
                                    addr_t func_addr,
                                    addr_t return_addr,
                                    llvm::ArrayRef<addr_t> args) const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    if (log)
    {
        StreamString s;
        s.Printf("ABISysV_ppc::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
                    thread.GetID(),
                    (uint64_t)sp,
                    (uint64_t)func_addr,
                    (uint64_t)return_addr);

        for (size_t i = 0; i < args.size(); ++i)
            s.Printf (", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1), args[i]);
        s.PutCString (")");
        log->PutCString(s.GetString().c_str());
    }

    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    if (!reg_ctx)
        return false;

    const RegisterInfo *reg_info = NULL;

    if (args.size() > 8) // TODO handle more than 8 arguments
        return false;

    for (size_t i = 0; i < args.size(); ++i)
    {
        reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
        if (log)
            log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", static_cast<uint64_t>(i + 1), args[i], reg_info->name);
        if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
            return false;
    }

    // First, align the SP

    if (log)
        log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, (uint64_t)sp, (uint64_t)(sp & ~0xfull));

    sp &= ~(0xfull); // 16-byte alignment

    sp -= 8;

    Error error;
    const RegisterInfo *pc_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
    const RegisterInfo *sp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
    ProcessSP process_sp (thread.GetProcess());

    RegisterValue reg_value;

#if 0
    // This code adds an extra frame so that we don't lose the function that we came from
    // by pushing the PC and the FP and then writing the current FP to point to the FP value
    // we just pushed. It is disabled for now until the stack backtracing code can be debugged.

    // Save current PC
    const RegisterInfo *fp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
    if (reg_ctx->ReadRegister(pc_reg_info, reg_value))
    {
        if (log)
            log->Printf("Pushing the current PC onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, reg_value.GetAsUInt64());

        if (!process_sp->WritePointerToMemory(sp, reg_value.GetAsUInt64(), error))
            return false;

        sp -= 8;

        // Save current FP
        if (reg_ctx->ReadRegister(fp_reg_info, reg_value))
        {
            if (log)
                log->Printf("Pushing the current FP onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, reg_value.GetAsUInt64());

            if (!process_sp->WritePointerToMemory(sp, reg_value.GetAsUInt64(), error))
                return false;
        }
        // Setup FP backchain
        reg_value.SetUInt64 (sp);

        if (log)
            log->Printf("Writing FP:  0x%" PRIx64 " (for FP backchain)", reg_value.GetAsUInt64());

        if (!reg_ctx->WriteRegister(fp_reg_info, reg_value))
        {
            return false;
        }

        sp -= 8;
    }
#endif

    if (log)
        log->Printf("Pushing the return address onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, (uint64_t)return_addr);

    // Save return address onto the stack
    if (!process_sp->WritePointerToMemory(sp, return_addr, error))
        return false;

    // %r1 is set to the actual stack value.

    if (log)
        log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);

    if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_info, sp))
        return false;

    // %pc is set to the address of the called function.

    if (log)
        log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);

    if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_info, func_addr))
        return false;

    return true;
}
Exemplo n.º 7
0
bool ABISysV_s390x::PrepareTrivialCall(Thread &thread, addr_t sp,
                                       addr_t func_addr, addr_t return_addr,
                                       llvm::ArrayRef<addr_t> args) const {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));

  if (log) {
    StreamString s;
    s.Printf("ABISysV_s390x::PrepareTrivialCall (tid = 0x%" PRIx64
             ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
             ", return_addr = 0x%" PRIx64,
             thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
             (uint64_t)return_addr);

    for (size_t i = 0; i < args.size(); ++i)
      s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),
               args[i]);
    s.PutCString(")");
    log->PutString(s.GetString());
  }

  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
  if (!reg_ctx)
    return false;

  const RegisterInfo *pc_reg_info =
      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
  const RegisterInfo *sp_reg_info =
      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
  const RegisterInfo *ra_reg_info = reg_ctx->GetRegisterInfoByName("r14", 0);
  ProcessSP process_sp(thread.GetProcess());

  // Allocate a new stack frame and space for stack arguments if necessary

  addr_t arg_pos = 0;
  if (args.size() > 5) {
    sp -= 8 * (args.size() - 5);
    arg_pos = sp;
  }

  sp -= 160;

  // Process arguments

  for (size_t i = 0; i < args.size(); ++i) {
    if (i < 5) {
      const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
          eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
      if (log)
        log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
                    static_cast<uint64_t>(i + 1), args[i], reg_info->name);
      if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
        return false;
    } else {
      Status error;
      if (log)
        log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") onto stack",
                    static_cast<uint64_t>(i + 1), args[i]);
      if (!process_sp->WritePointerToMemory(arg_pos, args[i], error))
        return false;
      arg_pos += 8;
    }
  }

  // %r14 is set to the return address

  if (log)
    log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);

  if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
    return false;

  // %r15 is set to the actual stack value.

  if (log)
    log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);

  if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
    return false;

  // %pc is set to the address of the called function.

  if (log)
    log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr);

  if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
    return false;

  return true;
}
Exemplo n.º 8
0
bool
ABISysV_mips64::PrepareTrivialCall (Thread &thread,
                                  addr_t sp,
                                  addr_t func_addr,
                                  addr_t return_addr,
                                  llvm::ArrayRef<addr_t> args) const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    if (log)
    {
        StreamString s;
        s.Printf("ABISysV_mips64::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
                    thread.GetID(),
                    (uint64_t)sp,
                    (uint64_t)func_addr,
                    (uint64_t)return_addr);

        for (size_t i = 0; i < args.size(); ++i)
            s.Printf (", arg%zd = 0x%" PRIx64, i + 1, args[i]);
        s.PutCString (")");
        log->PutCString(s.GetString().c_str());
    }

    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    if (!reg_ctx)
        return false;

    const RegisterInfo *reg_info = NULL;

    if (args.size() > 8) // TODO handle more than 8 arguments
        return false;

    for (size_t i = 0; i < args.size(); ++i)
    {
        reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
        if (log)
            log->Printf("About to write arg%zd (0x%" PRIx64 ") into %s", i + 1, args[i], reg_info->name);
        if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
            return false;
    }

    // First, align the SP

    if (log)
        log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, (uint64_t)sp, (uint64_t)(sp & ~0xfull));

    sp &= ~(0xfull); // 16-byte alignment

    Error error;
    const RegisterInfo *pc_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
    const RegisterInfo *sp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
    const RegisterInfo *ra_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);

    if (log)
    log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);

    // Set "sp" to the requested value
    if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_info, sp))
        return false;

    if (log)
    log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);

    // Set "ra" to the return address
    if (!reg_ctx->WriteRegisterFromUnsigned (ra_reg_info, return_addr))
        return false;

    if (log)
        log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr);

    // Set pc to the address of the called function.
    if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_info, func_addr))
        return false;

    return true;
}