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;
}