addr_t DynamicLoaderPOSIXDYLD::ComputeLoadOffset() { addr_t virt_entry; if (m_load_offset != LLDB_INVALID_ADDRESS) return m_load_offset; if ((virt_entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS) return LLDB_INVALID_ADDRESS; ModuleSP module = m_process->GetTarget().GetExecutableModule(); if (!module) return LLDB_INVALID_ADDRESS; ObjectFile *exe = module->GetObjectFile(); if (!exe) return LLDB_INVALID_ADDRESS; Address file_entry = exe->GetEntryPointAddress(); if (!file_entry.IsValid()) return LLDB_INVALID_ADDRESS; m_load_offset = virt_entry - file_entry.GetFileAddress(); return m_load_offset; }
//---------------------------------------------------------------------- // ThreadPlanCallFunction: Plan to call a single function //---------------------------------------------------------------------- bool ThreadPlanCallFunction::ConstructorSetup (Thread &thread, ABI *& abi, lldb::addr_t &start_load_addr, lldb::addr_t &function_load_addr) { SetIsMasterPlan (true); SetOkayToDiscard (false); SetPrivate (true); ProcessSP process_sp (thread.GetProcess()); if (!process_sp) return false; abi = process_sp->GetABI().get(); if (!abi) return false; Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); SetBreakpoints(); m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize(); // If we can't read memory at the point of the process where we are planning to put our function, we're // not going to get any further... Error error; process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error); if (!error.Success()) { m_constructor_errors.Printf ("Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".", m_function_sp); if (log) log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); return false; } Module *exe_module = GetTarget().GetExecutableModulePointer(); if (exe_module == NULL) { m_constructor_errors.Printf ("Can't execute code without an executable module."); if (log) log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); return false; } else { ObjectFile *objectFile = exe_module->GetObjectFile(); if (!objectFile) { m_constructor_errors.Printf ("Could not find object file for module \"%s\".", exe_module->GetFileSpec().GetFilename().AsCString()); if (log) log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); return false; } m_start_addr = objectFile->GetEntryPointAddress(); if (!m_start_addr.IsValid()) { m_constructor_errors.Printf ("Could not find entry point address for executable module \"%s\".", exe_module->GetFileSpec().GetFilename().AsCString()); if (log) log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); return false; } } start_load_addr = m_start_addr.GetLoadAddress (&GetTarget()); // Checkpoint the thread state so we can restore it later. if (log && log->GetVerbose()) ReportRegisterState ("About to checkpoint thread before function call. Original register state was:"); if (!thread.CheckpointThreadState (m_stored_thread_state)) { m_constructor_errors.Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state."); if (log) log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData()); return false; } function_load_addr = m_function_addr.GetLoadAddress (&GetTarget()); return true; }