//===-- ObjectFileMachO.cpp -------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/StringRef.h" 

#include "lldb/lldb-private-log.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/FileSpecList.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RangeMap.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
#include "lldb/Core/UUID.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Symbol/ClangNamespaceDecl.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadList.h"
#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h"
#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"

#include "lldb/Utility/SafeMachO.h"

#include "ObjectFileMachO.h"

#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
// GetLLDBSharedCacheUUID() needs to call dlsym()
#include <dlfcn.h>
#endif

#ifndef __APPLE__
#include "Utility/UuidCompatibility.h"
#endif

using namespace lldb;
using namespace lldb_private;
using namespace llvm::MachO;

class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64
{
public:
    RegisterContextDarwin_x86_64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
        RegisterContextDarwin_x86_64 (thread, 0)
    {
        SetRegisterDataFrom_LC_THREAD (data);
    }

    virtual void
    InvalidateAllRegisters ()
    {
        // Do nothing... registers are always valid...
    }

    void
    SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
    {
        lldb::offset_t offset = 0;
        SetError (GPRRegSet, Read, -1);
        SetError (FPURegSet, Read, -1);
        SetError (EXCRegSet, Read, -1);
        bool done = false;

        while (!done)
        {
            int flavor = data.GetU32 (&offset);
            if (flavor == 0)
                done = true;
            else
            {
                uint32_t i;
                uint32_t count = data.GetU32 (&offset);
                switch (flavor)
                {
                    case GPRRegSet:
                        for (i=0; i<count; ++i)
                            (&gpr.rax)[i] = data.GetU64(&offset);
                        SetError (GPRRegSet, Read, 0);
                        done = true;

                        break;
                    case FPURegSet:
                        // TODO: fill in FPU regs....
                        //SetError (FPURegSet, Read, -1);
                        done = true;

                        break;
                    case EXCRegSet:
                        exc.trapno = data.GetU32(&offset);
                        exc.err = data.GetU32(&offset);
                        exc.faultvaddr = data.GetU64(&offset);
                        SetError (EXCRegSet, Read, 0);
                        done = true;
                        break;
                    case 7:
                    case 8:
                    case 9:
                        // fancy flavors that encapsulate of the above
                        // flavors...
                        break;

                    default:
                        done = true;
                        break;
                }
            }
        }
    }
    

    static size_t
    WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
    {
        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
        if (reg_info == NULL)
            reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
        if (reg_info)
        {
            lldb_private::RegisterValue reg_value;
            if (reg_ctx->ReadRegister(reg_info, reg_value))
            {
                if (reg_info->byte_size >= reg_byte_size)
                    data.Write(reg_value.GetBytes(), reg_byte_size);
                else
                {
                    data.Write(reg_value.GetBytes(), reg_info->byte_size);
                    for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
                        data.PutChar(0);
                }
                return reg_byte_size;
            }
        }
        // Just write zeros if all else fails
        for (size_t i=0; i<reg_byte_size; ++ i)
            data.PutChar(0);
        return reg_byte_size;
    }

    static bool
    Create_LC_THREAD (Thread *thread, Stream &data)
    {
        RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
        if (reg_ctx_sp)
        {
            RegisterContext *reg_ctx = reg_ctx_sp.get();

            data.PutHex32 (GPRRegSet);  // Flavor
            data.PutHex32 (GPRWordCount);
            WriteRegister (reg_ctx, "rax", NULL, 8, data);
            WriteRegister (reg_ctx, "rbx", NULL, 8, data);
            WriteRegister (reg_ctx, "rcx", NULL, 8, data);
            WriteRegister (reg_ctx, "rdx", NULL, 8, data);
            WriteRegister (reg_ctx, "rdi", NULL, 8, data);
            WriteRegister (reg_ctx, "rsi", NULL, 8, data);
            WriteRegister (reg_ctx, "rbp", NULL, 8, data);
            WriteRegister (reg_ctx, "rsp", NULL, 8, data);
            WriteRegister (reg_ctx, "r8", NULL, 8, data);
            WriteRegister (reg_ctx, "r9", NULL, 8, data);
            WriteRegister (reg_ctx, "r10", NULL, 8, data);
            WriteRegister (reg_ctx, "r11", NULL, 8, data);
            WriteRegister (reg_ctx, "r12", NULL, 8, data);
            WriteRegister (reg_ctx, "r13", NULL, 8, data);
            WriteRegister (reg_ctx, "r14", NULL, 8, data);
            WriteRegister (reg_ctx, "r15", NULL, 8, data);
            WriteRegister (reg_ctx, "rip", NULL, 8, data);
            WriteRegister (reg_ctx, "rflags", NULL, 8, data);
            WriteRegister (reg_ctx, "cs", NULL, 8, data);
            WriteRegister (reg_ctx, "fs", NULL, 8, data);
            WriteRegister (reg_ctx, "gs", NULL, 8, data);

//            // Write out the FPU registers
//            const size_t fpu_byte_size = sizeof(FPU);
//            size_t bytes_written = 0;
//            data.PutHex32 (FPURegSet);
//            data.PutHex32 (fpu_byte_size/sizeof(uint64_t));
//            bytes_written += data.PutHex32(0);                                   // uint32_t pad[0]
//            bytes_written += data.PutHex32(0);                                   // uint32_t pad[1]
//            bytes_written += WriteRegister (reg_ctx, "fcw", "fctrl", 2, data);   // uint16_t    fcw;    // "fctrl"
//            bytes_written += WriteRegister (reg_ctx, "fsw" , "fstat", 2, data);  // uint16_t    fsw;    // "fstat"
//            bytes_written += WriteRegister (reg_ctx, "ftw" , "ftag", 1, data);   // uint8_t     ftw;    // "ftag"
//            bytes_written += data.PutHex8  (0);                                  // uint8_t pad1;
//            bytes_written += WriteRegister (reg_ctx, "fop" , NULL, 2, data);     // uint16_t    fop;    // "fop"
//            bytes_written += WriteRegister (reg_ctx, "fioff", "ip", 4, data);    // uint32_t    ip;     // "fioff"
//            bytes_written += WriteRegister (reg_ctx, "fiseg", NULL, 2, data);    // uint16_t    cs;     // "fiseg"
//            bytes_written += data.PutHex16 (0);                                  // uint16_t    pad2;
//            bytes_written += WriteRegister (reg_ctx, "dp", "fooff" , 4, data);   // uint32_t    dp;     // "fooff"
//            bytes_written += WriteRegister (reg_ctx, "foseg", NULL, 2, data);    // uint16_t    ds;     // "foseg"
//            bytes_written += data.PutHex16 (0);                                  // uint16_t    pad3;
//            bytes_written += WriteRegister (reg_ctx, "mxcsr", NULL, 4, data);    // uint32_t    mxcsr;
//            bytes_written += WriteRegister (reg_ctx, "mxcsrmask", NULL, 4, data);// uint32_t    mxcsrmask;
//            bytes_written += WriteRegister (reg_ctx, "stmm0", NULL, sizeof(MMSReg), data);
//            bytes_written += WriteRegister (reg_ctx, "stmm1", NULL, sizeof(MMSReg), data);
//            bytes_written += WriteRegister (reg_ctx, "stmm2", NULL, sizeof(MMSReg), data);
//            bytes_written += WriteRegister (reg_ctx, "stmm3", NULL, sizeof(MMSReg), data);
//            bytes_written += WriteRegister (reg_ctx, "stmm4", NULL, sizeof(MMSReg), data);
//            bytes_written += WriteRegister (reg_ctx, "stmm5", NULL, sizeof(MMSReg), data);
//            bytes_written += WriteRegister (reg_ctx, "stmm6", NULL, sizeof(MMSReg), data);
//            bytes_written += WriteRegister (reg_ctx, "stmm7", NULL, sizeof(MMSReg), data);
//            bytes_written += WriteRegister (reg_ctx, "xmm0" , NULL, sizeof(XMMReg), data);
//            bytes_written += WriteRegister (reg_ctx, "xmm1" , NULL, sizeof(XMMReg), data);
//            bytes_written += WriteRegister (reg_ctx, "xmm2" , NULL, sizeof(XMMReg), data);
//            bytes_written += WriteRegister (reg_ctx, "xmm3" , NULL, sizeof(XMMReg), data);
//            bytes_written += WriteRegister (reg_ctx, "xmm4" , NULL, sizeof(XMMReg), data);
//            bytes_written += WriteRegister (reg_ctx, "xmm5" , NULL, sizeof(XMMReg), data);
//            bytes_written += WriteRegister (reg_ctx, "xmm6" , NULL, sizeof(XMMReg), data);
//            bytes_written += WriteRegister (reg_ctx, "xmm7" , NULL, sizeof(XMMReg), data);
//            bytes_written += WriteRegister (reg_ctx, "xmm8" , NULL, sizeof(XMMReg), data);
//            bytes_written += WriteRegister (reg_ctx, "xmm9" , NULL, sizeof(XMMReg), data);
//            bytes_written += WriteRegister (reg_ctx, "xmm10", NULL, sizeof(XMMReg), data);
//            bytes_written += WriteRegister (reg_ctx, "xmm11", NULL, sizeof(XMMReg), data);
//            bytes_written += WriteRegister (reg_ctx, "xmm12", NULL, sizeof(XMMReg), data);
//            bytes_written += WriteRegister (reg_ctx, "xmm13", NULL, sizeof(XMMReg), data);
//            bytes_written += WriteRegister (reg_ctx, "xmm14", NULL, sizeof(XMMReg), data);
//            bytes_written += WriteRegister (reg_ctx, "xmm15", NULL, sizeof(XMMReg), data);
//            
//            // Fill rest with zeros
//            for (size_t i=0, n = fpu_byte_size - bytes_written; i<n; ++ i)
//                data.PutChar(0);
            
            // Write out the EXC registers
            data.PutHex32 (EXCRegSet);
            data.PutHex32 (EXCWordCount);
            WriteRegister (reg_ctx, "trapno", NULL, 4, data);
            WriteRegister (reg_ctx, "err", NULL, 4, data);
            WriteRegister (reg_ctx, "faultvaddr", NULL, 8, data);
            return true;
        }
        return false;
    }

protected:
    virtual int
    DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
    {
        return 0;
    }

    virtual int
    DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
    {
        return 0;
    }

    virtual int
    DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
    {
        return 0;
    }

    virtual int
    DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
    {
        return 0;
    }

    virtual int
    DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
    {
        return 0;
    }

    virtual int
    DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
    {
        return 0;
    }
};


class RegisterContextDarwin_i386_Mach : public RegisterContextDarwin_i386
{
public:
    RegisterContextDarwin_i386_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
    RegisterContextDarwin_i386 (thread, 0)
    {
        SetRegisterDataFrom_LC_THREAD (data);
    }

    virtual void
    InvalidateAllRegisters ()
    {
        // Do nothing... registers are always valid...
    }

    void
    SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
    {
        lldb::offset_t offset = 0;
        SetError (GPRRegSet, Read, -1);
        SetError (FPURegSet, Read, -1);
        SetError (EXCRegSet, Read, -1);
        bool done = false;

        while (!done)
        {
            int flavor = data.GetU32 (&offset);
            if (flavor == 0)
                done = true;
            else
            {
                uint32_t i;
                uint32_t count = data.GetU32 (&offset);
                switch (flavor)
                {
                    case GPRRegSet:
                        for (i=0; i<count; ++i)
                            (&gpr.eax)[i] = data.GetU32(&offset);
                        SetError (GPRRegSet, Read, 0);
                        done = true;

                        break;
                    case FPURegSet:
                        // TODO: fill in FPU regs....
                        //SetError (FPURegSet, Read, -1);
                        done = true;

                        break;
                    case EXCRegSet:
                        exc.trapno = data.GetU32(&offset);
                        exc.err = data.GetU32(&offset);
                        exc.faultvaddr = data.GetU32(&offset);
                        SetError (EXCRegSet, Read, 0);
                        done = true;
                        break;
                    case 7:
                    case 8:
                    case 9:
                        // fancy flavors that encapsulate of the above
                        // flavors...
                        break;

                    default:
                        done = true;
                        break;
                }
            }
        }
    }

    static size_t
    WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
    {
        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
        if (reg_info == NULL)
            reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
        if (reg_info)
        {
            lldb_private::RegisterValue reg_value;
            if (reg_ctx->ReadRegister(reg_info, reg_value))
            {
                if (reg_info->byte_size >= reg_byte_size)
                    data.Write(reg_value.GetBytes(), reg_byte_size);
                else
                {
                    data.Write(reg_value.GetBytes(), reg_info->byte_size);
                    for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
                        data.PutChar(0);
                }
                return reg_byte_size;
            }
        }
        // Just write zeros if all else fails
        for (size_t i=0; i<reg_byte_size; ++ i)
            data.PutChar(0);
        return reg_byte_size;
    }

    static bool
    Create_LC_THREAD (Thread *thread, Stream &data)
    {
        RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
        if (reg_ctx_sp)
        {
            RegisterContext *reg_ctx = reg_ctx_sp.get();

            data.PutHex32 (GPRRegSet);  // Flavor
            data.PutHex32 (GPRWordCount);
            WriteRegister (reg_ctx, "eax", NULL, 4, data);
            WriteRegister (reg_ctx, "ebx", NULL, 4, data);
            WriteRegister (reg_ctx, "ecx", NULL, 4, data);
            WriteRegister (reg_ctx, "edx", NULL, 4, data);
            WriteRegister (reg_ctx, "edi", NULL, 4, data);
            WriteRegister (reg_ctx, "esi", NULL, 4, data);
            WriteRegister (reg_ctx, "ebp", NULL, 4, data);
            WriteRegister (reg_ctx, "esp", NULL, 4, data);
            WriteRegister (reg_ctx, "ss", NULL, 4, data);
            WriteRegister (reg_ctx, "eflags", NULL, 4, data);
            WriteRegister (reg_ctx, "eip", NULL, 4, data);
            WriteRegister (reg_ctx, "cs", NULL, 4, data);
            WriteRegister (reg_ctx, "ds", NULL, 4, data);
            WriteRegister (reg_ctx, "es", NULL, 4, data);
            WriteRegister (reg_ctx, "fs", NULL, 4, data);
            WriteRegister (reg_ctx, "gs", NULL, 4, data);

            // Write out the EXC registers
            data.PutHex32 (EXCRegSet);
            data.PutHex32 (EXCWordCount);
            WriteRegister (reg_ctx, "trapno", NULL, 4, data);
            WriteRegister (reg_ctx, "err", NULL, 4, data);
            WriteRegister (reg_ctx, "faultvaddr", NULL, 4, data);
            return true;
        }
        return false;
    }

protected:
    virtual int
    DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
    {
        return 0;
    }

    virtual int
    DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
    {
        return 0;
    }

    virtual int
    DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
    {
        return 0;
    }

    virtual int
    DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
    {
        return 0;
    }

    virtual int
    DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
    {
        return 0;
    }

    virtual int
    DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
    {
        return 0;
    }
};

class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm
{
public:
    RegisterContextDarwin_arm_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
        RegisterContextDarwin_arm (thread, 0)
    {
        SetRegisterDataFrom_LC_THREAD (data);
    }

    virtual void
    InvalidateAllRegisters ()
    {
        // Do nothing... registers are always valid...
    }

    void
    SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
    {
        lldb::offset_t offset = 0;
        SetError (GPRRegSet, Read, -1);
        SetError (FPURegSet, Read, -1);
        SetError (EXCRegSet, Read, -1);
        bool done = false;

        while (!done)
        {
            int flavor = data.GetU32 (&offset);
            uint32_t count = data.GetU32 (&offset);
            lldb::offset_t next_thread_state = offset + (count * 4);
            switch (flavor)
            {
                case GPRRegSet:
                    for (uint32_t i=0; i<count; ++i)
                    {
                        gpr.r[i] = data.GetU32(&offset);
                    }

                    // Note that gpr.cpsr is also copied by the above loop; this loop technically extends 
                    // one element past the end of the gpr.r[] array.

                    SetError (GPRRegSet, Read, 0);
                    offset = next_thread_state;
                    break;

                case FPURegSet:
                    {
                        uint8_t  *fpu_reg_buf = (uint8_t*) &fpu.floats.s[0];
                        const int fpu_reg_buf_size = sizeof (fpu.floats);
                        if (data.ExtractBytes (offset, fpu_reg_buf_size, eByteOrderLittle, fpu_reg_buf) == fpu_reg_buf_size)
                        {
                            offset += fpu_reg_buf_size;
                            fpu.fpscr = data.GetU32(&offset);
                            SetError (FPURegSet, Read, 0);
                        }
                        else
                        {
                            done = true;
                        }
                    }
                    offset = next_thread_state;
                    break;

                case EXCRegSet:
                    if (count == 3)
                    {
                        exc.exception = data.GetU32(&offset);
                        exc.fsr = data.GetU32(&offset);
                        exc.far = data.GetU32(&offset);
                        SetError (EXCRegSet, Read, 0);
                    }
                    done = true;
                    offset = next_thread_state;
                    break;

                // Unknown register set flavor, stop trying to parse.
                default:
                    done = true;
            }
        }
    }

    static size_t
    WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
    {
        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
        if (reg_info == NULL)
            reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
        if (reg_info)
        {
            lldb_private::RegisterValue reg_value;
            if (reg_ctx->ReadRegister(reg_info, reg_value))
            {
                if (reg_info->byte_size >= reg_byte_size)
                    data.Write(reg_value.GetBytes(), reg_byte_size);
                else
                {
                    data.Write(reg_value.GetBytes(), reg_info->byte_size);
                    for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
                        data.PutChar(0);
                }
                return reg_byte_size;
            }
        }
        // Just write zeros if all else fails
        for (size_t i=0; i<reg_byte_size; ++ i)
            data.PutChar(0);
        return reg_byte_size;
    }

    static bool
    Create_LC_THREAD (Thread *thread, Stream &data)
    {
        RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
        if (reg_ctx_sp)
        {
            RegisterContext *reg_ctx = reg_ctx_sp.get();

            data.PutHex32 (GPRRegSet);  // Flavor
            data.PutHex32 (GPRWordCount);
            WriteRegister (reg_ctx, "r0", NULL, 4, data);
            WriteRegister (reg_ctx, "r1", NULL, 4, data);
            WriteRegister (reg_ctx, "r2", NULL, 4, data);
            WriteRegister (reg_ctx, "r3", NULL, 4, data);
            WriteRegister (reg_ctx, "r4", NULL, 4, data);
            WriteRegister (reg_ctx, "r5", NULL, 4, data);
            WriteRegister (reg_ctx, "r6", NULL, 4, data);
            WriteRegister (reg_ctx, "r7", NULL, 4, data);
            WriteRegister (reg_ctx, "r8", NULL, 4, data);
            WriteRegister (reg_ctx, "r9", NULL, 4, data);
            WriteRegister (reg_ctx, "r10", NULL, 4, data);
            WriteRegister (reg_ctx, "r11", NULL, 4, data);
            WriteRegister (reg_ctx, "r12", NULL, 4, data);
            WriteRegister (reg_ctx, "sp", NULL, 4, data);
            WriteRegister (reg_ctx, "lr", NULL, 4, data);
            WriteRegister (reg_ctx, "pc", NULL, 4, data);
            WriteRegister (reg_ctx, "cpsr", NULL, 4, data);

            // Write out the EXC registers
//            data.PutHex32 (EXCRegSet);
//            data.PutHex32 (EXCWordCount);
//            WriteRegister (reg_ctx, "exception", NULL, 4, data);
//            WriteRegister (reg_ctx, "fsr", NULL, 4, data);
//            WriteRegister (reg_ctx, "far", NULL, 4, data);
            return true;
        }
        return false;
    }

protected:
    virtual int
    DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
    {
        return -1;
    }

    virtual int
    DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
    {
        return -1;
    }

    virtual int
    DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
    {
        return -1;
    }

    virtual int
    DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
    {
        return -1;
    }

    virtual int
    DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
    {
        return 0;
    }

    virtual int
    DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
    {
        return 0;
    }

    virtual int
    DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
    {
        return 0;
    }

    virtual int
    DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
    {
        return -1;
    }
};

class RegisterContextDarwin_arm64_Mach : public RegisterContextDarwin_arm64
{
public:
    RegisterContextDarwin_arm64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
        RegisterContextDarwin_arm64 (thread, 0)
    {
        SetRegisterDataFrom_LC_THREAD (data);
    }
    
    virtual void
    InvalidateAllRegisters ()
    {
        // Do nothing... registers are always valid...
    }
    
    void
    SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
    {
        lldb::offset_t offset = 0;
        SetError (GPRRegSet, Read, -1);
        SetError (FPURegSet, Read, -1);
        SetError (EXCRegSet, Read, -1);
        bool done = false;
        while (!done)
        {
            int flavor = data.GetU32 (&offset);
            uint32_t count = data.GetU32 (&offset);
            lldb::offset_t next_thread_state = offset + (count * 4);
            switch (flavor)
            {
                case GPRRegSet:
                    // x0-x29 + fp + lr + sp + pc (== 33 64-bit registers) plus cpsr (1 32-bit register)
                    if (count >= (33 * 2) + 1)
                    {
                        for (uint32_t i=0; i<33; ++i)
                            gpr.x[i] = data.GetU64(&offset);
                        gpr.cpsr = data.GetU32(&offset);
                        SetError (GPRRegSet, Read, 0);
                    }
                    offset = next_thread_state;
                    break;
                case FPURegSet:
                    {
                        uint8_t *fpu_reg_buf = (uint8_t*) &fpu.v[0];
                        const int fpu_reg_buf_size = sizeof (fpu);
                        if (fpu_reg_buf_size == count
                            && data.ExtractBytes (offset, fpu_reg_buf_size, eByteOrderLittle, fpu_reg_buf) == fpu_reg_buf_size)
                        {
                            SetError (FPURegSet, Read, 0);
                        }
                        else
                        {
                            done = true;
                        }
                    }
                    offset = next_thread_state;
                    break;
                case EXCRegSet:
                    if (count == 4)
                    {
                        exc.far = data.GetU64(&offset);
                        exc.esr = data.GetU32(&offset);
                        exc.exception = data.GetU32(&offset);
                        SetError (EXCRegSet, Read, 0);
                    }
                    offset = next_thread_state;
                    break;
                default:
                    done = true;
                    break;
            }
        }
    }

    static size_t
    WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data)
    {
        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name);
        if (reg_info == NULL)
            reg_info = reg_ctx->GetRegisterInfoByName(alt_name);
        if (reg_info)
        {
            lldb_private::RegisterValue reg_value;
            if (reg_ctx->ReadRegister(reg_info, reg_value))
            {
                if (reg_info->byte_size >= reg_byte_size)
                    data.Write(reg_value.GetBytes(), reg_byte_size);
                else
                {
                    data.Write(reg_value.GetBytes(), reg_info->byte_size);
                    for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i)
                        data.PutChar(0);
                }
                return reg_byte_size;
            }
        }
        // Just write zeros if all else fails
        for (size_t i=0; i<reg_byte_size; ++ i)
            data.PutChar(0);
        return reg_byte_size;
    }

    static bool
    Create_LC_THREAD (Thread *thread, Stream &data)
    {
        RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
        if (reg_ctx_sp)
        {
            RegisterContext *reg_ctx = reg_ctx_sp.get();

            data.PutHex32 (GPRRegSet);  // Flavor
            data.PutHex32 (GPRWordCount);
            WriteRegister (reg_ctx, "x0", NULL, 8, data);
            WriteRegister (reg_ctx, "x1", NULL, 8, data);
            WriteRegister (reg_ctx, "x2", NULL, 8, data);
            WriteRegister (reg_ctx, "x3", NULL, 8, data);
            WriteRegister (reg_ctx, "x4", NULL, 8, data);
            WriteRegister (reg_ctx, "x5", NULL, 8, data);
            WriteRegister (reg_ctx, "x6", NULL, 8, data);
            WriteRegister (reg_ctx, "x7", NULL, 8, data);
            WriteRegister (reg_ctx, "x8", NULL, 8, data);
            WriteRegister (reg_ctx, "x9", NULL, 8, data);
            WriteRegister (reg_ctx, "x10", NULL, 8, data);
            WriteRegister (reg_ctx, "x11", NULL, 8, data);
            WriteRegister (reg_ctx, "x12", NULL, 8, data);
            WriteRegister (reg_ctx, "x13", NULL, 8, data);
            WriteRegister (reg_ctx, "x14", NULL, 8, data);
            WriteRegister (reg_ctx, "x15", NULL, 8, data);
            WriteRegister (reg_ctx, "x16", NULL, 8, data);
            WriteRegister (reg_ctx, "x17", NULL, 8, data);
            WriteRegister (reg_ctx, "x18", NULL, 8, data);
            WriteRegister (reg_ctx, "x19", NULL, 8, data);
            WriteRegister (reg_ctx, "x20", NULL, 8, data);
            WriteRegister (reg_ctx, "x21", NULL, 8, data);
            WriteRegister (reg_ctx, "x22", NULL, 8, data);
            WriteRegister (reg_ctx, "x23", NULL, 8, data);
            WriteRegister (reg_ctx, "x24", NULL, 8, data);
            WriteRegister (reg_ctx, "x25", NULL, 8, data);
            WriteRegister (reg_ctx, "x26", NULL, 8, data);
            WriteRegister (reg_ctx, "x27", NULL, 8, data);
            WriteRegister (reg_ctx, "x28", NULL, 8, data);
            WriteRegister (reg_ctx, "fp", NULL, 8, data);
            WriteRegister (reg_ctx, "lr", NULL, 8, data);
            WriteRegister (reg_ctx, "sp", NULL, 8, data);
            WriteRegister (reg_ctx, "pc", NULL, 8, data);
            WriteRegister (reg_ctx, "cpsr", NULL, 4, data);

            // Write out the EXC registers
//            data.PutHex32 (EXCRegSet);
//            data.PutHex32 (EXCWordCount);
//            WriteRegister (reg_ctx, "far", NULL, 8, data);
//            WriteRegister (reg_ctx, "esr", NULL, 4, data);
//            WriteRegister (reg_ctx, "exception", NULL, 4, data);
            return true;
        }
        return false;
    }

protected:
    virtual int
    DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
    {
        return -1;
    }
    
    virtual int
    DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
    {
        return -1;
    }
    
    virtual int
    DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
    {
        return -1;
    }

    virtual int
    DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
    {
        return -1;
    }
    
    virtual int
    DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
    {
        return 0;
    }
    
    virtual int
    DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
    {
        return 0;
    }
    
    virtual int
    DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
    {
        return 0;
    }
    
    virtual int
    DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
    {
        return -1;
    }
};

static uint32_t
MachHeaderSizeFromMagic(uint32_t magic)
{
    switch (magic)
    {
        case MH_MAGIC:
        case MH_CIGAM:
            return sizeof(struct mach_header);
            
        case MH_MAGIC_64:
        case MH_CIGAM_64:
            return sizeof(struct mach_header_64);
            break;
            
        default:
            break;
    }
    return 0;
}

#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008

void
ObjectFileMachO::Initialize()
{
    PluginManager::RegisterPlugin (GetPluginNameStatic(),
                                   GetPluginDescriptionStatic(),
                                   CreateInstance,
                                   CreateMemoryInstance,
                                   GetModuleSpecifications,
                                   SaveCore);
}

void
ObjectFileMachO::Terminate()
{
    PluginManager::UnregisterPlugin (CreateInstance);
}


lldb_private::ConstString
ObjectFileMachO::GetPluginNameStatic()
{
    static ConstString g_name("mach-o");
    return g_name;
}

const char *
ObjectFileMachO::GetPluginDescriptionStatic()
{
    return "Mach-o object file reader (32 and 64 bit)";
}

ObjectFile *
ObjectFileMachO::CreateInstance (const lldb::ModuleSP &module_sp,
                                 DataBufferSP& data_sp,
                                 lldb::offset_t data_offset,
                                 const FileSpec* file,
                                 lldb::offset_t file_offset,
                                 lldb::offset_t length)
{
    if (!data_sp)
    {
        data_sp = file->MemoryMapFileContents(file_offset, length);
        data_offset = 0;
    }

    if (ObjectFileMachO::MagicBytesMatch(data_sp, data_offset, length))
    {
        // Update the data to contain the entire file if it doesn't already
        if (data_sp->GetByteSize() < length)
        {
            data_sp = file->MemoryMapFileContents(file_offset, length);
            data_offset = 0;
        }
        std::unique_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, data_offset, file, file_offset, length));
        if (objfile_ap.get() && objfile_ap->ParseHeader())
            return objfile_ap.release();
    }
    return NULL;
}

ObjectFile *
ObjectFileMachO::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
                                       DataBufferSP& data_sp,
                                       const ProcessSP &process_sp,
                                       lldb::addr_t header_addr)
{
    if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
    {
        std::unique_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, process_sp, header_addr));
        if (objfile_ap.get() && objfile_ap->ParseHeader())
            return objfile_ap.release();
    }
    return NULL;
}

size_t
ObjectFileMachO::GetModuleSpecifications (const lldb_private::FileSpec& file,
                                          lldb::DataBufferSP& data_sp,
                                          lldb::offset_t data_offset,
                                          lldb::offset_t file_offset,
                                          lldb::offset_t length,
                                          lldb_private::ModuleSpecList &specs)
{
    const size_t initial_count = specs.GetSize();
    
    if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
    {
        DataExtractor data;
        data.SetData(data_sp);
        llvm::MachO::mach_header header;
        if (ParseHeader (data, &data_offset, header))
        {
            size_t header_and_load_cmds = header.sizeofcmds + MachHeaderSizeFromMagic(header.magic);
            if (header_and_load_cmds >= data_sp->GetByteSize())
            {
                data_sp = file.ReadFileContents(file_offset, header_and_load_cmds);
                data.SetData(data_sp);
                data_offset = MachHeaderSizeFromMagic(header.magic);
            }
            if (data_sp)
            {
                ModuleSpec spec;
                spec.GetFileSpec() = file;
                spec.SetObjectOffset(file_offset);
                
                if (GetArchitecture (header, data, data_offset, spec.GetArchitecture()))
                {
                    if (spec.GetArchitecture().IsValid())
                    {
                        GetUUID (header, data, data_offset, spec.GetUUID());
                        specs.Append(spec);
                    }
                }
            }
        }
    }
    return specs.GetSize() - initial_count;
}



const ConstString &
ObjectFileMachO::GetSegmentNameTEXT()
{
    static ConstString g_segment_name_TEXT ("__TEXT");
    return g_segment_name_TEXT;
}

const ConstString &
ObjectFileMachO::GetSegmentNameDATA()
{
    static ConstString g_segment_name_DATA ("__DATA");
    return g_segment_name_DATA;
}

const ConstString &
ObjectFileMachO::GetSegmentNameOBJC()
{
    static ConstString g_segment_name_OBJC ("__OBJC");
    return g_segment_name_OBJC;
}

const ConstString &
ObjectFileMachO::GetSegmentNameLINKEDIT()
{
    static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
    return g_section_name_LINKEDIT;
}

const ConstString &
ObjectFileMachO::GetSectionNameEHFrame()
{
    static ConstString g_section_name_eh_frame ("__eh_frame");
    return g_section_name_eh_frame;
}

bool
ObjectFileMachO::MagicBytesMatch (DataBufferSP& data_sp,
                                  lldb::addr_t data_offset,
                                  lldb::addr_t data_length)
{
    DataExtractor data;
    data.SetData (data_sp, data_offset, data_length);
    lldb::offset_t offset = 0;
    uint32_t magic = data.GetU32(&offset);
    return MachHeaderSizeFromMagic(magic) != 0;
}


ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
                                 DataBufferSP& data_sp,
                                 lldb::offset_t data_offset,
                                 const FileSpec* file,
                                 lldb::offset_t file_offset,
                                 lldb::offset_t length) :
    ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
    m_mach_segments(),
    m_mach_sections(),
    m_entry_point_address(),
    m_thread_context_offsets(),
    m_thread_context_offsets_valid(false)
{
    ::memset (&m_header, 0, sizeof(m_header));
    ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
}

ObjectFileMachO::ObjectFileMachO (const lldb::ModuleSP &module_sp,
                                  lldb::DataBufferSP& header_data_sp,
                                  const lldb::ProcessSP &process_sp,
                                  lldb::addr_t header_addr) :
    ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
    m_mach_segments(),
    m_mach_sections(),
    m_entry_point_address(),
    m_thread_context_offsets(),
    m_thread_context_offsets_valid(false)
{
    ::memset (&m_header, 0, sizeof(m_header));
    ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
}

ObjectFileMachO::~ObjectFileMachO()
{
}

bool
ObjectFileMachO::ParseHeader (DataExtractor &data,
                              lldb::offset_t *data_offset_ptr,
                              llvm::MachO::mach_header &header)
{
    data.SetByteOrder (lldb::endian::InlHostByteOrder());
    // Leave magic in the original byte order
    header.magic = data.GetU32(data_offset_ptr);
    bool can_parse = false;
    bool is_64_bit = false;
    switch (header.magic)
    {
        case MH_MAGIC:
            data.SetByteOrder (lldb::endian::InlHostByteOrder());
            data.SetAddressByteSize(4);
            can_parse = true;
            break;
            
        case MH_MAGIC_64:
            data.SetByteOrder (lldb::endian::InlHostByteOrder());
            data.SetAddressByteSize(8);
            can_parse = true;
            is_64_bit = true;
            break;
            
        case MH_CIGAM:
            data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
            data.SetAddressByteSize(4);
            can_parse = true;
            break;
            
        case MH_CIGAM_64:
            data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
            data.SetAddressByteSize(8);
            is_64_bit = true;
            can_parse = true;
            break;
            
        default:
            break;
    }
    
    if (can_parse)
    {
        data.GetU32(data_offset_ptr, &header.cputype, 6);
        if (is_64_bit)
            *data_offset_ptr += 4;
        return true;
    }
    else
    {
        memset(&header, 0, sizeof(header));
    }
    return false;
}

bool
ObjectFileMachO::ParseHeader ()
{
    ModuleSP module_sp(GetModule());
    if (module_sp)
    {
        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
        bool can_parse = false;
        lldb::offset_t offset = 0;
        m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
        // Leave magic in the original byte order
        m_header.magic = m_data.GetU32(&offset);
        switch (m_header.magic)
        {
        case MH_MAGIC:
            m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
            m_data.SetAddressByteSize(4);
            can_parse = true;
            break;

        case MH_MAGIC_64:
            m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
            m_data.SetAddressByteSize(8);
            can_parse = true;
            break;

        case MH_CIGAM:
            m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
            m_data.SetAddressByteSize(4);
            can_parse = true;
            break;

        case MH_CIGAM_64:
            m_data.SetByteOrder(lldb::endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
            m_data.SetAddressByteSize(8);
            can_parse = true;
            break;

        default:
            break;
        }

        if (can_parse)
        {
            m_data.GetU32(&offset, &m_header.cputype, 6);

            
            ArchSpec mach_arch;
            
            if (GetArchitecture (mach_arch))
            {
                // Check if the module has a required architecture
                const ArchSpec &module_arch = module_sp->GetArchitecture();
                if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch))
                    return false;

                if (SetModulesArchitecture (mach_arch))
                {
                    const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
                    if (m_data.GetByteSize() < header_and_lc_size)
                    {
                        DataBufferSP data_sp;
                        ProcessSP process_sp (m_process_wp.lock());
                        if (process_sp)
                        {
                            data_sp = ReadMemory (process_sp, m_memory_addr, header_and_lc_size);
                        }
                        else
                        {
                            // Read in all only the load command data from the file on disk
                            data_sp = m_file.ReadFileContents(m_file_offset, header_and_lc_size);
                            if (data_sp->GetByteSize() != header_and_lc_size)
                                return false;
                        }
                        if (data_sp)
                            m_data.SetData (data_sp);
                    }
                }
                return true;
            }
        }
        else
        {
            memset(&m_header, 0, sizeof(struct mach_header));
        }
    }
    return false;
}


ByteOrder
ObjectFileMachO::GetByteOrder () const
{
    return m_data.GetByteOrder ();
}

bool
ObjectFileMachO::IsExecutable() const
{
    return m_header.filetype == MH_EXECUTE;
}

uint32_t
ObjectFileMachO::GetAddressByteSize () const
{
    return m_data.GetAddressByteSize ();
}

AddressClass
ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr)
{
    Symtab *symtab = GetSymtab();
    if (symtab)
    {
        Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
        if (symbol)
        {
            if (symbol->ValueIsAddress())
            {
                SectionSP section_sp (symbol->GetAddress().GetSection());
                if (section_sp)
                {
                    const lldb::SectionType section_type = section_sp->GetType();
                    switch (section_type)
                    {
                    case eSectionTypeInvalid:
                        return eAddressClassUnknown;

                    case eSectionTypeCode:
                        if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM)
                        {
                            // For ARM we have a bit in the n_desc field of the symbol
                            // that tells us ARM/Thumb which is bit 0x0008.
                            if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
                                return eAddressClassCodeAlternateISA;
                        }
                        return eAddressClassCode;

                    case eSectionTypeContainer:
                        return eAddressClassUnknown;

                    case eSectionTypeData:
                    case eSectionTypeDataCString:
                    case eSectionTypeDataCStringPointers:
                    case eSectionTypeDataSymbolAddress:
                    case eSectionTypeData4:
                    case eSectionTypeData8:
                    case eSectionTypeData16:
                    case eSectionTypeDataPointers:
                    case eSectionTypeZeroFill:
                    case eSectionTypeDataObjCMessageRefs:
                    case eSectionTypeDataObjCCFStrings:
                        return eAddressClassData;

                    case eSectionTypeDebug:
                    case eSectionTypeDWARFDebugAbbrev:
                    case eSectionTypeDWARFDebugAranges:
                    case eSectionTypeDWARFDebugFrame:
                    case eSectionTypeDWARFDebugInfo:
                    case eSectionTypeDWARFDebugLine:
                    case eSectionTypeDWARFDebugLoc:
                    case eSectionTypeDWARFDebugMacInfo:
                    case eSectionTypeDWARFDebugPubNames:
                    case eSectionTypeDWARFDebugPubTypes:
                    case eSectionTypeDWARFDebugRanges:
                    case eSectionTypeDWARFDebugStr:
                    case eSectionTypeDWARFAppleNames:
                    case eSectionTypeDWARFAppleTypes:
                    case eSectionTypeDWARFAppleNamespaces:
                    case eSectionTypeDWARFAppleObjC:
                        return eAddressClassDebug;

                    case eSectionTypeEHFrame:
                    case eSectionTypeCompactUnwind:
                        return eAddressClassRuntime;

                    case eSectionTypeELFSymbolTable:
                    case eSectionTypeELFDynamicSymbols:
                    case eSectionTypeELFRelocationEntries:
                    case eSectionTypeELFDynamicLinkInfo:
                    case eSectionTypeOther:
                        return eAddressClassUnknown;
                    }
                }
            }

            const SymbolType symbol_type = symbol->GetType();
            switch (symbol_type)
            {
            case eSymbolTypeAny:            return eAddressClassUnknown;
            case eSymbolTypeAbsolute:       return eAddressClassUnknown;

            case eSymbolTypeCode:
            case eSymbolTypeTrampoline:
            case eSymbolTypeResolver:
                if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM)
                {
                    // For ARM we have a bit in the n_desc field of the symbol
                    // that tells us ARM/Thumb which is bit 0x0008.
                    if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB)
                        return eAddressClassCodeAlternateISA;
                }
                return eAddressClassCode;

            case eSymbolTypeData:           return eAddressClassData;
            case eSymbolTypeRuntime:        return eAddressClassRuntime;
            case eSymbolTypeException:      return eAddressClassRuntime;
            case eSymbolTypeSourceFile:     return eAddressClassDebug;
            case eSymbolTypeHeaderFile:     return eAddressClassDebug;
            case eSymbolTypeObjectFile:     return eAddressClassDebug;
            case eSymbolTypeCommonBlock:    return eAddressClassDebug;
            case eSymbolTypeBlock:          return eAddressClassDebug;
            case eSymbolTypeLocal:          return eAddressClassData;
            case eSymbolTypeParam:          return eAddressClassData;
            case eSymbolTypeVariable:       return eAddressClassData;
            case eSymbolTypeVariableType:   return eAddressClassDebug;
            case eSymbolTypeLineEntry:      return eAddressClassDebug;
            case eSymbolTypeLineHeader:     return eAddressClassDebug;
            case eSymbolTypeScopeBegin:     return eAddressClassDebug;
            case eSymbolTypeScopeEnd:       return eAddressClassDebug;
            case eSymbolTypeAdditional:     return eAddressClassUnknown;
            case eSymbolTypeCompiler:       return eAddressClassDebug;
            case eSymbolTypeInstrumentation:return eAddressClassDebug;
            case eSymbolTypeUndefined:      return eAddressClassUnknown;
            case eSymbolTypeObjCClass:      return eAddressClassRuntime;
            case eSymbolTypeObjCMetaClass:  return eAddressClassRuntime;
            case eSymbolTypeObjCIVar:       return eAddressClassRuntime;
            case eSymbolTypeReExported:     return eAddressClassRuntime;
            }
        }
    }
    return eAddressClassUnknown;
}

Symtab *
ObjectFileMachO::GetSymtab()
{
    ModuleSP module_sp(GetModule());
    if (module_sp)
    {
        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
        if (m_symtab_ap.get() == NULL)
        {
            m_symtab_ap.reset(new Symtab(this));
            Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
            ParseSymtab ();
            m_symtab_ap->Finalize ();
        }
    }
    return m_symtab_ap.get();
}

bool
ObjectFileMachO::IsStripped ()
{
    if (m_dysymtab.cmd == 0)
    {
        ModuleSP module_sp(GetModule());
        if (module_sp)
        {
            lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
            for (uint32_t i=0; i<m_header.ncmds; ++i)
            {
                const lldb::offset_t load_cmd_offset = offset;
                
                load_command lc;
                if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
                    break;
                if (lc.cmd == LC_DYSYMTAB)
                {
                    m_dysymtab.cmd = lc.cmd;
                    m_dysymtab.cmdsize = lc.cmdsize;
                    if (m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2) == NULL)
                    {
                        // Clear m_dysymtab if we were unable to read all items from the load command
                        ::memset (&m_dysymtab, 0, sizeof(m_dysymtab));
                    }
                }
                offset = load_cmd_offset + lc.cmdsize;
            }
        }
    }
    if (m_dysymtab.cmd)
        return m_dysymtab.nlocalsym <= 1;
    return false;
}

void
ObjectFileMachO::CreateSections (SectionList &unified_section_list)
{
    if (!m_sections_ap.get())
    {
        m_sections_ap.reset(new SectionList());
        
        const bool is_dsym = (m_header.filetype == MH_DSYM);
        lldb::user_id_t segID = 0;
        lldb::user_id_t sectID = 0;
        lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
        uint32_t i;
        const bool is_core = GetType() == eTypeCoreFile;
        //bool dump_sections = false;
        ModuleSP module_sp (GetModule());
        // First look up any LC_ENCRYPTION_INFO load commands
        typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges;
        EncryptedFileRanges encrypted_file_ranges;
        encryption_info_command encryption_cmd;
        for (i=0; i<m_header.ncmds; ++i)
        {
            const lldb::offset_t load_cmd_offset = offset;
            if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
                break;

            if (encryption_cmd.cmd == LC_ENCRYPTION_INFO)
            {
                if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3))
                {
                    if (encryption_cmd.cryptid != 0)
                    {
                        EncryptedFileRanges::Entry entry;
                        entry.SetRangeBase(encryption_cmd.cryptoff);
                        entry.SetByteSize(encryption_cmd.cryptsize);
                        encrypted_file_ranges.Append(entry);
                    }
                }
            }
            offset = load_cmd_offset + encryption_cmd.cmdsize;
        }

        bool section_file_addresses_changed = false;

        offset = MachHeaderSizeFromMagic(m_header.magic);

        struct segment_command_64 load_cmd;
        for (i=0; i<m_header.ncmds; ++i)
        {
            const lldb::offset_t load_cmd_offset = offset;
            if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
                break;

            if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64)
            {
                if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16))
                {
                    bool add_section = true;
                    bool add_to_unified = true;
                    ConstString const_segname (load_cmd.segname, std::min<size_t>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));

                    SectionSP unified_section_sp(unified_section_list.FindSectionByName(const_segname));
                    if (is_dsym && unified_section_sp)
                    {
                        if (const_segname == GetSegmentNameLINKEDIT())
                        {
                            // We need to keep the __LINKEDIT segment private to this object file only
                            add_to_unified = false;
                        }
                        else
                        {
                            // This is the dSYM file and this section has already been created by
                            // the object file, no need to create it.
                            add_section = false;
                        }
                    }
                    load_cmd.vmaddr = m_data.GetAddress(&offset);
                    load_cmd.vmsize = m_data.GetAddress(&offset);
                    load_cmd.fileoff = m_data.GetAddress(&offset);
                    load_cmd.filesize = m_data.GetAddress(&offset);
                    if (m_length != 0 && load_cmd.filesize != 0)
                    {
                        if (load_cmd.fileoff > m_length)
                        {
                            // We have a load command that says it extends past the end of the file.  This is likely
                            // a corrupt file.  We don't have any way to return an error condition here (this method
                            // was likely invoked from something like ObjectFile::GetSectionList()) -- all we can do
                            // is null out the SectionList vector and if a process has been set up, dump a message
                            // to stdout.  The most common case here is core file debugging with a truncated file.
                            const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
                            module_sp->ReportWarning("load command %u %s has a fileoff (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 "), ignoring this section",
                                                   i,
                                                   lc_segment_name,
                                                   load_cmd.fileoff,
                                                   m_length);
                            
                            load_cmd.fileoff = 0;
                            load_cmd.filesize = 0;
                        }
                        
                        if (load_cmd.fileoff + load_cmd.filesize > m_length)
                        {
                            // We have a load command that says it extends past the end of the file.  This is likely
                            // a corrupt file.  We don't have any way to return an error condition here (this method
                            // was likely invoked from something like ObjectFile::GetSectionList()) -- all we can do
                            // is null out the SectionList vector and if a process has been set up, dump a message
                            // to stdout.  The most common case here is core file debugging with a truncated file.
                            const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT";
                            GetModule()->ReportWarning("load command %u %s has a fileoff + filesize (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 "), the segment will be truncated to match",
                                                     i,
                                                     lc_segment_name,
                                                     load_cmd.fileoff + load_cmd.filesize,
                                                     m_length);
                            
                            // Tuncase the length
                            load_cmd.filesize = m_length - load_cmd.fileoff;
                        }
                    }
                    if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
                    {

                        const bool segment_is_encrypted = (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;

                        // Keep a list of mach segments around in case we need to
                        // get at data that isn't stored in the abstracted Sections.
                        m_mach_segments.push_back (load_cmd);

                        // Use a segment ID of the segment index shifted left by 8 so they
                        // never conflict with any of the sections.
                        SectionSP segment_sp;
                        if (add_section && (const_segname || is_core))
                        {
                            segment_sp.reset(new Section (module_sp,              // Module to which this section belongs
                                                          this,                   // Object file to which this sections belongs
                                                          ++segID << 8,           // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible
                                                          const_segname,          // Name of this section
                                                          eSectionTypeContainer,  // This section is a container of other sections.
                                                          load_cmd.vmaddr,        // File VM address == addresses as they are found in the object file
                                                          load_cmd.vmsize,        // VM size in bytes of this section
                                                          load_cmd.fileoff,       // Offset to the data for this section in the file
                                                          load_cmd.filesize,      // Size in bytes of this section as found in the file
                                                          0,                      // Segments have no alignment information
                                                          load_cmd.flags));       // Flags for this section

                            segment_sp->SetIsEncrypted (segment_is_encrypted);
                            m_sections_ap->AddSection(segment_sp);
                            if (add_to_unified)
                                unified_section_list.AddSection(segment_sp);
                        }
                        else if (unified_section_sp)
                        {
                            if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr)
                            {
                                // Check to see if the module was read from memory?
                                if (module_sp->GetObjectFile()->GetHeaderAddress().IsValid())
                                {
                                    // We have a module that is in memory and needs to have its
                                    // file address adjusted. We need to do this because when we
                                    // load a file from memory, its addresses will be slid already,
                                    // yet the addresses in the new symbol file will still be unslid.
                                    // Since everything is stored as section offset, this shouldn't
                                    // cause any problems.

                                    // Make sure we've parsed the symbol table from the 
                                    // ObjectFile before we go around changing its Sections.
                                    module_sp->GetObjectFile()->GetSymtab();
                                    // eh_frame would present the same problems but we parse that on
                                    // a per-function basis as-needed so it's more difficult to
                                    // remove its use of the Sections.  Realistically, the environments
                                    // where this code path will be taken will not have eh_frame sections.

                                    unified_section_sp->SetFileAddress(load_cmd.vmaddr);

                                    // Notify the module that the section addresses have been changed once
                                    // we're done so any file-address caches can be updated.
                                    section_file_addresses_changed = true;
                                }
                            }
                            m_sections_ap->AddSection(unified_section_sp);
                        }

                        struct section_64 sect64;
                        ::memset (&sect64, 0, sizeof(sect64));
                        // Push a section into our mach sections for the section at
                        // index zero (NO_SECT) if we don't have any mach sections yet...
                        if (m_mach_sections.empty())
                            m_mach_sections.push_back(sect64);
                        uint32_t segment_sect_idx;
                        const lldb::user_id_t first_segment_sectID = sectID + 1;


                        const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
                        for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx)
                        {
                            if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL)
                                break;
                            if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL)
                                break;
                            sect64.addr = m_data.GetAddress(&offset);
                            sect64.size = m_data.GetAddress(&offset);

                            if (m_data.GetU32(&offset, &sect64.offset, num_u32s) == NULL)
                                break;

                            // Keep a list of mach sections around in case we need to
                            // get at data that isn't stored in the abstracted Sections.
                            m_mach_sections.push_back (sect64);

                            if (add_section)
                            {
                                ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname)));
                                if (!const_segname)
                                {
                                    // We have a segment with no name so we need to conjure up
                                    // segments that correspond to the section's segname if there
                                    // isn't already such a section. If there is such a section,
                                    // we resize the section so that it spans all sections.
                                    // We also mark these sections as fake so address matches don't
                                    // hit if they land in the gaps between the child sections.
                                    const_segname.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname));
                                    segment_sp = unified_section_list.FindSectionByName (const_segname);
                                    if (segment_sp.get())
                                    {
                                        Section *segment = segment_sp.get();
                                        // Grow the section size as needed.
                                        const lldb::addr_t sect64_min_addr = sect64.addr;
                                        const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size;
                                        const lldb::addr_t curr_seg_byte_size = segment->GetByteSize();
                                        const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress();
                                        const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size;
                                        if (sect64_min_addr >= curr_seg_min_addr)
                                        {
                                            const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr;
                                            // Only grow the section size if needed
                                            if (new_seg_byte_size > curr_seg_byte_size)
                                                segment->SetByteSize (new_seg_byte_size);
                                        }
                                        else
                                        {
                                            // We need to change the base address of the segment and
                                            // adjust the child section offsets for all existing children.
                                            const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
                                            segment->Slide(slide_amount, false);
                                            segment->GetChildren().Slide(-slide_amount, false);
                                            segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
                                        }

                                        // Grow the section size as needed.
                                        if (sect64.offset)
                                        {
                                            const lldb::addr_t segment_min_file_offset = segment->GetFileOffset();
                                            const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize();

                                            const lldb::addr_t section_min_file_offset = sect64.offset;
                                            const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size;
                                            const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset);
                                            const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset;
                                            segment->SetFileOffset (new_file_offset);
                                            segment->SetFileSize (new_file_size);
                                        }
                                    }
                                    else
                                    {
                                        // Create a fake section for the section's named segment
                                        segment_sp.reset(new Section (segment_sp,            // Parent section
                                                                      module_sp,             // Module to which this section belongs
                                                                      this,                  // Object file to which this section belongs
                                                                      ++segID << 8,          // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible
                                                                      const_segname,         // Name of this section
                                                                      eSectionTypeContainer, // This section is a container of other sections.
                                                                      sect64.addr,           // File VM address == addresses as they are found in the object file
                                                                      sect64.size,           // VM size in bytes of this section
                                                                      sect64.offset,         // Offset to the data for this section in the file
                                                                      sect64.offset ? sect64.size : 0,        // Size in bytes of this section as found in the file
                                                                      sect64.align,
                                                                      load_cmd.flags));      // Flags for this section
                                        segment_sp->SetIsFake(true);
                                        
                                        m_sections_ap->AddSection(segment_sp);
                                        if (add_to_unified)
                                            unified_section_list.AddSection(segment_sp);
                                        segment_sp->SetIsEncrypted (segment_is_encrypted);
                                    }
                                }
                                assert (segment_sp.get());

                                lldb::SectionType sect_type = eSectionTypeOther;

                                if (sect64.flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS))
                                    sect_type = eSectionTypeCode;
                                else
                                {
                                    uint32_t mach_sect_type = sect64.flags & SECTION_TYPE;
                                    static ConstString g_sect_name_objc_data ("__objc_data");
                                    static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs");
                                    static ConstString g_sect_name_objc_selrefs ("__objc_selrefs");
                                    static ConstString g_sect_name_objc_classrefs ("__objc_classrefs");
                                    static ConstString g_sect_name_objc_superrefs ("__objc_superrefs");
                                    static ConstString g_sect_name_objc_const ("__objc_const");
                                    static ConstString g_sect_name_objc_classlist ("__objc_classlist");
                                    static ConstString g_sect_name_cfstring ("__cfstring");

                                    static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev");
                                    static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges");
                                    static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame");
                                    static ConstString g_sect_name_dwarf_debug_info ("__debug_info");
                                    static ConstString g_sect_name_dwarf_debug_line ("__debug_line");
                                    static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc");
                                    static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo");
                                    static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames");
                                    static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes");
                                    static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges");
                                    static ConstString g_sect_name_dwarf_debug_str ("__debug_str");
                                    static ConstString g_sect_name_dwarf_apple_names ("__apple_names");
                                    static ConstString g_sect_name_dwarf_apple_types ("__apple_types");
                                    static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac");
                                    static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc");
                                    static ConstString g_sect_name_eh_frame ("__eh_frame");
                                    static ConstString g_sect_name_compact_unwind ("__unwind_info");
                                    static ConstString g_sect_name_text ("__text");
                                    static ConstString g_sect_name_data ("__data");


                                    if (section_name == g_sect_name_dwarf_debug_abbrev)
                                        sect_type = eSectionTypeDWARFDebugAbbrev;
                                    else if (section_name == g_sect_name_dwarf_debug_aranges)
                                        sect_type = eSectionTypeDWARFDebugAranges;
                                    else if (section_name == g_sect_name_dwarf_debug_frame)
                                        sect_type = eSectionTypeDWARFDebugFrame;
                                    else if (section_name == g_sect_name_dwarf_debug_info)
                                        sect_type = eSectionTypeDWARFDebugInfo;
                                    else if (section_name == g_sect_name_dwarf_debug_line)
                                        sect_type = eSectionTypeDWARFDebugLine;
                                    else if (section_name == g_sect_name_dwarf_debug_loc)
                                        sect_type = eSectionTypeDWARFDebugLoc;
                                    else if (section_name == g_sect_name_dwarf_debug_macinfo)
                                        sect_type = eSectionTypeDWARFDebugMacInfo;
                                    else if (section_name == g_sect_name_dwarf_debug_pubnames)
                                        sect_type = eSectionTypeDWARFDebugPubNames;
                                    else if (section_name == g_sect_name_dwarf_debug_pubtypes)
                                        sect_type = eSectionTypeDWARFDebugPubTypes;
                                    else if (section_name == g_sect_name_dwarf_debug_ranges)
                                        sect_type = eSectionTypeDWARFDebugRanges;
                                    else if (section_name == g_sect_name_dwarf_debug_str)
                                        sect_type = eSectionTypeDWARFDebugStr;
                                    else if (section_name == g_sect_name_dwarf_apple_names)
                                        sect_type = eSectionTypeDWARFAppleNames;
                                    else if (section_name == g_sect_name_dwarf_apple_types)
                                        sect_type = eSectionTypeDWARFAppleTypes;
                                    else if (section_name == g_sect_name_dwarf_apple_namespaces)
                                        sect_type = eSectionTypeDWARFAppleNamespaces;
                                    else if (section_name == g_sect_name_dwarf_apple_objc)
                                        sect_type = eSectionTypeDWARFAppleObjC;
                                    else if (section_name == g_sect_name_objc_selrefs)
                                        sect_type = eSectionTypeDataCStringPointers;
                                    else if (section_name == g_sect_name_objc_msgrefs)
                                        sect_type = eSectionTypeDataObjCMessageRefs;
                                    else if (section_name == g_sect_name_eh_frame)
                                        sect_type = eSectionTypeEHFrame;
                                    else if (section_name == g_sect_name_compact_unwind)
                                        sect_type = eSectionTypeCompactUnwind;
                                    else if (section_name == g_sect_name_cfstring)
                                        sect_type = eSectionTypeDataObjCCFStrings;
                                    else if (section_name == g_sect_name_objc_data ||
                                             section_name == g_sect_name_objc_classrefs ||
                                             section_name == g_sect_name_objc_superrefs ||
                                             section_name == g_sect_name_objc_const ||
                                             section_name == g_sect_name_objc_classlist)
                                    {
                                        sect_type = eSectionTypeDataPointers;
                                    }

                                    if (sect_type == eSectionTypeOther)
                                    {
                                        switch (mach_sect_type)
                                        {
                                        // TODO: categorize sections by other flags for regular sections
                                        case S_REGULAR:
                                            if (section_name == g_sect_name_text)
                                                sect_type = eSectionTypeCode;
                                            else if (section_name == g_sect_name_data)
                                                sect_type = eSectionTypeData;
                                            else
                                                sect_type = eSectionTypeOther;
                                            break;
                                        case S_ZEROFILL:                   sect_type = eSectionTypeZeroFill; break;
                                        case S_CSTRING_LITERALS:           sect_type = eSectionTypeDataCString;    break; // section with only literal C strings
                                        case S_4BYTE_LITERALS:             sect_type = eSectionTypeData4;    break; // section with only 4 byte literals
                                        case S_8BYTE_LITERALS:             sect_type = eSectionTypeData8;    break; // section with only 8 byte literals
                                        case S_LITERAL_POINTERS:           sect_type = eSectionTypeDataPointers;  break; // section with only pointers to literals
                                        case S_NON_LAZY_SYMBOL_POINTERS:   sect_type = eSectionTypeDataPointers;  break; // section with only non-lazy symbol pointers
                                        case S_LAZY_SYMBOL_POINTERS:       sect_type = eSectionTypeDataPointers;  break; // section with only lazy symbol pointers
                                        case S_SYMBOL_STUBS:               sect_type = eSectionTypeCode;  break; // section with only symbol stubs, byte size of stub in the reserved2 field
                                        case S_MOD_INIT_FUNC_POINTERS:     sect_type = eSectionTypeDataPointers;    break; // section with only function pointers for initialization
                                        case S_MOD_TERM_FUNC_POINTERS:     sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination
                                        case S_COALESCED:                  sect_type = eSectionTypeOther; break;
                                        case S_GB_ZEROFILL:                sect_type = eSectionTypeZeroFill; break;
                                        case S_INTERPOSING:                sect_type = eSectionTypeCode;  break; // section with only pairs of function pointers for interposing
                                        case S_16BYTE_LITERALS:            sect_type = eSectionTypeData16; break; // section with only 16 byte literals
                                        case S_DTRACE_DOF:                 sect_type = eSectionTypeDebug; break;
                                        case S_LAZY_DYLIB_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers;  break;
                                        default: break;
                                        }
                                    }
                                }

                                SectionSP section_sp(new Section (segment_sp,
                                                                  module_sp,
                                                                  this,
                                                                  ++sectID,
                                                                  section_name,
                                                                  sect_type,
                                                                  sect64.addr - segment_sp->GetFileAddress(),
                                                                  sect64.size,
                                                                  sect64.offset,
                                                                  sect64.offset == 0 ? 0 : sect64.size,
                                                                  sect64.align,
                                                                  sect64.flags));
                                // Set the section to be encrypted to match the segment

                                bool section_is_encrypted = false;
                                if (!segment_is_encrypted && load_cmd.filesize != 0)
                                    section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL;

                                section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted);
                                segment_sp->GetChildren().AddSection(section_sp);

                                if (segment_sp->IsFake())
                                {
                                    segment_sp.reset();
                                    const_segname.Clear();
                                }
                            }
                        }
                        if (segment_sp && is_dsym)
                        {
                            if (first_segment_sectID <= sectID)
                            {
                                lldb::user_id_t sect_uid;
                                for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid)
                                {
                                    SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid));
                                    SectionSP next_section_sp;
                                    if (sect_uid + 1 <= sectID)
                                        next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1);

                                    if (curr_section_sp.get())
                                    {
                                        if (curr_section_sp->GetByteSize() == 0)
                                        {
                                            if (next_section_sp.get() != NULL)
                                                curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() );
                                            else
                                                curr_section_sp->SetByteSize ( load_cmd.vmsize );
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else if (load_cmd.cmd == LC_DYSYMTAB)
            {
                m_dysymtab.cmd = load_cmd.cmd;
                m_dysymtab.cmdsize = load_cmd.cmdsize;
                m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2);
            }

            offset = load_cmd_offset + load_cmd.cmdsize;
        }


        if (section_file_addresses_changed && module_sp.get())
        {
            module_sp->SectionFileAddressesChanged();
        }
    }
}

class MachSymtabSectionInfo
{
public:

    MachSymtabSectionInfo (SectionList *section_list) :
        m_section_list (section_list),
        m_section_infos()
    {
        // Get the number of sections down to a depth of 1 to include
        // all segments and their sections, but no other sections that
        // may be added for debug map or
        m_section_infos.resize(section_list->GetNumSections(1));
    }


    SectionSP
    GetSection (uint8_t n_sect, addr_t file_addr)
    {
        if (n_sect == 0)
            return SectionSP();
        if (n_sect < m_section_infos.size())
        {
            if (!m_section_infos[n_sect].section_sp)
            {
                SectionSP section_sp (m_section_list->FindSectionByID (n_sect));
                m_section_infos[n_sect].section_sp = section_sp;
                if (section_sp)
                {
                    m_section_infos[n_sect].vm_range.SetBaseAddress (section_sp->GetFileAddress());
                    m_section_infos[n_sect].vm_range.SetByteSize (section_sp->GetByteSize());
                }
                else
                {
                    Host::SystemLog (Host::eSystemLogError, "error: unable to find section for section %u\n", n_sect);
                }
            }
            if (m_section_infos[n_sect].vm_range.Contains(file_addr))
            {
                // Symbol is in section.
                return m_section_infos[n_sect].section_sp;
            }
            else if (m_section_infos[n_sect].vm_range.GetByteSize () == 0 &&
                     m_section_infos[n_sect].vm_range.GetBaseAddress() == file_addr)
            {
                // Symbol is in section with zero size, but has the same start
                // address as the section. This can happen with linker symbols
                // (symbols that start with the letter 'l' or 'L'.
                return m_section_infos[n_sect].section_sp;
            }
        }
        return m_section_list->FindSectionContainingFileAddress(file_addr);
    }

protected:
    struct SectionInfo
    {
        SectionInfo () :
            vm_range(),
            section_sp ()
        {
        }

        VMRange vm_range;
        SectionSP section_sp;
    };
    SectionList *m_section_list;
    std::vector<SectionInfo> m_section_infos;
};

struct TrieEntry
{
    TrieEntry () :
        name(),
        address(LLDB_INVALID_ADDRESS),
        flags (0),
        other(0),
        import_name()
    {
    }
    
    void
    Clear ()
    {
        name.Clear();
        address = LLDB_INVALID_ADDRESS;
        flags = 0;
        other = 0;
        import_name.Clear();
    }
    
    void
    Dump () const
    {
        printf ("0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"",
                static_cast<unsigned long long>(address),
                static_cast<unsigned long long>(flags),
                static_cast<unsigned long long>(other), name.GetCString());
        if (import_name)
            printf (" -> \"%s\"\n", import_name.GetCString());
        else
            printf ("\n");
    }
    ConstString		name;
    uint64_t		address;
    uint64_t		flags;
    uint64_t		other;
    ConstString		import_name;
};

struct TrieEntryWithOffset
{
	lldb::offset_t nodeOffset;
	TrieEntry entry;

    TrieEntryWithOffset (lldb::offset_t offset) :
        nodeOffset (offset),
        entry()
    {
    }

    void
    Dump (uint32_t idx) const
    {
        printf ("[%3u] 0x%16.16llx: ", idx,
                static_cast<unsigned long long>(nodeOffset));
        entry.Dump();
    }

	bool
    operator<(const TrieEntryWithOffset& other) const
    {
        return ( nodeOffset < other.nodeOffset );
    }
};

static void
ParseTrieEntries (DataExtractor &data,
                  lldb::offset_t offset,
                  std::vector<llvm::StringRef> &nameSlices,
                  std::set<lldb::addr_t> &resolver_addresses,
                  std::vector<TrieEntryWithOffset>& output)
{
	if (!data.ValidOffset(offset))
        return;

	const uint64_t terminalSize = data.GetULEB128(&offset);
	lldb::offset_t children_offset = offset + terminalSize;
	if ( terminalSize != 0 ) {
		TrieEntryWithOffset e (offset);
		e.entry.flags = data.GetULEB128(&offset);
        const char *import_name = NULL;
		if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT ) {
			e.entry.address = 0;
			e.entry.other = data.GetULEB128(&offset); // dylib ordinal
            import_name = data.GetCStr(&offset);
		}
		else {
			e.entry.address = data.GetULEB128(&offset);
			if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER )
            {
                //resolver_addresses.insert(e.entry.address);
				e.entry.other = data.GetULEB128(&offset);
                resolver_addresses.insert(e.entry.other);
            }
			else
				e.entry.other = 0;
		}
        // Only add symbols that are reexport symbols with a valid import name
        if (EXPORT_SYMBOL_FLAGS_REEXPORT & e.entry.flags && import_name && import_name[0])
        {
            std::string name;
            if (!nameSlices.empty())
            {
                for (auto name_slice: nameSlices)
                    name.append(name_slice.data(), name_slice.size());
            }
            if (name.size() > 1)
            {
                // Skip the leading '_'
                e.entry.name.SetCStringWithLength(name.c_str() + 1,name.size() - 1);
            }
            if (import_name)
            {
                // Skip the leading '_'
                e.entry.import_name.SetCString(import_name+1);                
            }
            output.push_back(e);
        }
	}
    
	const uint8_t childrenCount = data.GetU8(&children_offset);
	for (uint8_t i=0; i < childrenCount; ++i) {
        nameSlices.push_back(data.GetCStr(&children_offset));
        lldb::offset_t childNodeOffset = data.GetULEB128(&children_offset);
		if (childNodeOffset)
        {
            ParseTrieEntries(data,
                             childNodeOffset,
                             nameSlices,
                             resolver_addresses,
                             output);
        }
        nameSlices.pop_back();
	}
}

size_t
ObjectFileMachO::ParseSymtab ()
{
    Timer scoped_timer(__PRETTY_FUNCTION__,
                       "ObjectFileMachO::ParseSymtab () module = %s",
                       m_file.GetFilename().AsCString(""));
    ModuleSP module_sp (GetModule());
    if (!module_sp)
        return 0;

    struct symtab_command symtab_load_command = { 0, 0, 0, 0, 0, 0 };
    struct linkedit_data_command function_starts_load_command = { 0, 0, 0, 0 };
    struct dyld_info_command dyld_info = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
    FunctionStarts function_starts;
    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
    uint32_t i;
    FileSpecList dylib_files;
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));

    for (i=0; i<m_header.ncmds; ++i)
    {
        const lldb::offset_t cmd_offset = offset;
        // Read in the load command and load command size
        struct load_command lc;
        if (m_data.GetU32(&offset, &lc, 2) == NULL)
            break;
        // Watch for the symbol table load command
        switch (lc.cmd)
        {
        case LC_SYMTAB:
            symtab_load_command.cmd = lc.cmd;
            symtab_load_command.cmdsize = lc.cmdsize;
            // Read in the rest of the symtab load command
            if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) == 0) // fill in symoff, nsyms, stroff, strsize fields
                return 0;
            if (symtab_load_command.symoff == 0)
            {
                if (log)
                    module_sp->LogMessage(log, "LC_SYMTAB.symoff == 0");
                return 0;
            }

            if (symtab_load_command.stroff == 0)
            {
                if (log)
                    module_sp->LogMessage(log, "LC_SYMTAB.stroff == 0");
                return 0;
            }

            if (symtab_load_command.nsyms == 0)
            {
                if (log)
                    module_sp->LogMessage(log, "LC_SYMTAB.nsyms == 0");
                return 0;
            }

            if (symtab_load_command.strsize == 0)
            {
                if (log)
                    module_sp->LogMessage(log, "LC_SYMTAB.strsize == 0");
                return 0;
            }
            break;

        case LC_DYLD_INFO:
        case LC_DYLD_INFO_ONLY:
            if (m_data.GetU32(&offset, &dyld_info.rebase_off, 10))
            {
                dyld_info.cmd = lc.cmd;
                dyld_info.cmdsize = lc.cmdsize;
            }
            else
            {
                memset (&dyld_info, 0, sizeof(dyld_info));
            }
            break;

        case LC_LOAD_DYLIB:
        case LC_LOAD_WEAK_DYLIB:
        case LC_REEXPORT_DYLIB:
        case LC_LOADFVMLIB:
        case LC_LOAD_UPWARD_DYLIB:
            {
                uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
                const char *path = m_data.PeekCStr(name_offset);
                if (path)
                {
                    FileSpec file_spec(path, false);
                    // Strip the path if there is @rpath, @executable, etc so we just use the basename
                    if (path[0] == '@')
                        file_spec.GetDirectory().Clear();
                    
                    if (lc.cmd == LC_REEXPORT_DYLIB)
                    {
                        m_reexported_dylibs.AppendIfUnique(file_spec);
                    }

                    dylib_files.Append(file_spec);
                }
            }
            break;

        case LC_FUNCTION_STARTS:
            function_starts_load_command.cmd = lc.cmd;
            function_starts_load_command.cmdsize = lc.cmdsize;
            if (m_data.GetU32(&offset, &function_starts_load_command.dataoff, 2) == NULL) // fill in symoff, nsyms, stroff, strsize fields
                memset (&function_starts_load_command, 0, sizeof(function_starts_load_command));
            break;

        default:
            break;
        }
        offset = cmd_offset + lc.cmdsize;
    }

    if (symtab_load_command.cmd)
    {
        Symtab *symtab = m_symtab_ap.get();
        SectionList *section_list = GetSectionList();
        if (section_list == NULL)
            return 0;

        const uint32_t addr_byte_size = m_data.GetAddressByteSize();
        const ByteOrder byte_order = m_data.GetByteOrder();
        bool bit_width_32 = addr_byte_size == 4;
        const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);

        DataExtractor nlist_data (NULL, 0, byte_order, addr_byte_size);
        DataExtractor strtab_data (NULL, 0, byte_order, addr_byte_size);
        DataExtractor function_starts_data (NULL, 0, byte_order, addr_byte_size);
        DataExtractor indirect_symbol_index_data (NULL, 0, byte_order, addr_byte_size);
        DataExtractor dyld_trie_data (NULL, 0, byte_order, addr_byte_size);

        const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
        const addr_t strtab_data_byte_size = symtab_load_command.strsize;
        addr_t strtab_addr = LLDB_INVALID_ADDRESS;

        ProcessSP process_sp (m_process_wp.lock());
        Process *process = process_sp.get();
        
        uint32_t memory_module_load_level = eMemoryModuleLoadLevelComplete;

        if (process && m_header.filetype != llvm::MachO::MH_OBJECT)
        {
            Target &target = process->GetTarget();
            
            memory_module_load_level = target.GetMemoryModuleLoadLevel();

            SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
            // Reading mach file from memory in a process or core file...

            if (linkedit_section_sp)
            {
                const addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
                const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset();
                const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset;
                strtab_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;

                bool data_was_read = false;

#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
                if (m_header.flags & 0x80000000u && process->GetAddressByteSize() == sizeof (void*))
                {
                    // This mach-o memory file is in the dyld shared cache. If this
                    // program is not remote and this is iOS, then this process will
                    // share the same shared cache as the process we are debugging and
                    // we can read the entire __LINKEDIT from the address space in this
                    // process. This is a needed optimization that is used for local iOS
                    // debugging only since all shared libraries in the shared cache do
                    // not have corresponding files that exist in the file system of the
                    // device. They have been combined into a single file. This means we
                    // always have to load these files from memory. All of the symbol and
                    // string tables from all of the __LINKEDIT sections from the shared
                    // libraries in the shared cache have been merged into a single large
                    // symbol and string table. Reading all of this symbol and string table
                    // data across can slow down debug launch times, so we optimize this by
                    // reading the memory for the __LINKEDIT section from this process.

                    UUID lldb_shared_cache(GetLLDBSharedCacheUUID());
                    UUID process_shared_cache(GetProcessSharedCacheUUID(process));
                    bool use_lldb_cache = true;
                    if (lldb_shared_cache.IsValid() && process_shared_cache.IsValid() && lldb_shared_cache != process_shared_cache)
                    {
                            use_lldb_cache = false;
                            ModuleSP module_sp (GetModule());
                            if (module_sp)
                                module_sp->ReportWarning ("shared cache in process does not match lldb's own shared cache, startup will be slow.");

                    }

                    PlatformSP platform_sp (target.GetPlatform());
                    if (platform_sp && platform_sp->IsHost() && use_lldb_cache)
                    {
                        data_was_read = true;
                        nlist_data.SetData((void *)symoff_addr, nlist_data_byte_size, eByteOrderLittle);
                        strtab_data.SetData((void *)strtab_addr, strtab_data_byte_size, eByteOrderLittle);
                        if (function_starts_load_command.cmd)
                        {
                            const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
                            function_starts_data.SetData ((void *)func_start_addr, function_starts_load_command.datasize, eByteOrderLittle);
                        }
                    }
                }
#endif

                if (!data_was_read)
                {
                    if (memory_module_load_level == eMemoryModuleLoadLevelComplete)
                    {
                        DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size));
                        if (nlist_data_sp)
                            nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize());
                        // Load strings individually from memory when loading from memory since shared cache
                        // string tables contain strings for all symbols from all shared cached libraries
                        //DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr, strtab_data_byte_size));
                        //if (strtab_data_sp)
                        //    strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
                        if (m_dysymtab.nindirectsyms != 0)
                        {
                            const addr_t indirect_syms_addr = linkedit_load_addr + m_dysymtab.indirectsymoff - linkedit_file_offset;
                            DataBufferSP indirect_syms_data_sp (ReadMemory (process_sp, indirect_syms_addr, m_dysymtab.nindirectsyms * 4));
                            if (indirect_syms_data_sp)
                                indirect_symbol_index_data.SetData (indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
                        }
                    }
                    
                    if (memory_module_load_level >= eMemoryModuleLoadLevelPartial)
                    {
                        if (function_starts_load_command.cmd)
                        {
                            const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
                            DataBufferSP func_start_data_sp (ReadMemory (process_sp, func_start_addr, function_starts_load_command.datasize));
                            if (func_start_data_sp)
                                function_starts_data.SetData (func_start_data_sp, 0, func_start_data_sp->GetByteSize());
                        }
                    }
                }
            }
        }
        else
        {
            nlist_data.SetData (m_data,
                                symtab_load_command.symoff,
                                nlist_data_byte_size);
            strtab_data.SetData (m_data,
                                 symtab_load_command.stroff,
                                 strtab_data_byte_size);
            
            if (dyld_info.export_size > 0)
            {
                dyld_trie_data.SetData (m_data,
                                        dyld_info.export_off,
                                        dyld_info.export_size);
            }

            if (m_dysymtab.nindirectsyms != 0)
            {
                indirect_symbol_index_data.SetData (m_data,
                                                    m_dysymtab.indirectsymoff,
                                                    m_dysymtab.nindirectsyms * 4);
            }
            if (function_starts_load_command.cmd)
            {
                function_starts_data.SetData (m_data,
                                              function_starts_load_command.dataoff,
                                              function_starts_load_command.datasize);
            }
        }

        if (nlist_data.GetByteSize() == 0 && memory_module_load_level == eMemoryModuleLoadLevelComplete)
        {
            if (log)
                module_sp->LogMessage(log, "failed to read nlist data");
            return 0;
        }


        const bool have_strtab_data = strtab_data.GetByteSize() > 0;
        if (!have_strtab_data)
        {
            if (process)
            {
                if (strtab_addr == LLDB_INVALID_ADDRESS)
                {
                    if (log)
                        module_sp->LogMessage(log, "failed to locate the strtab in memory");
                    return 0;
                }
            }
            else
            {
                if (log)
                    module_sp->LogMessage(log, "failed to read strtab data");
                return 0;
            }
        }

        const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT();
        const ConstString &g_segment_name_DATA = GetSegmentNameDATA();
        const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC();
        const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame();
        SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT));
        SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA));
        SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC));
        SectionSP eh_frame_section_sp;
        if (text_section_sp.get())
            eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame);
        else
            eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);

        const bool is_arm = (m_header.cputype == llvm::MachO::CPU_TYPE_ARM);

        // lldb works best if it knows the start address of all functions in a module.
        // Linker symbols or debug info are normally the best source of information for start addr / size but
        // they may be stripped in a released binary.
        // Two additional sources of information exist in Mach-O binaries:
        //    LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each function's start address in the
        //                         binary, relative to the text section.
        //    eh_frame           - the eh_frame FDEs have the start addr & size of each function
        //  LC_FUNCTION_STARTS is the fastest source to read in, and is present on all modern binaries.
        //  Binaries built to run on older releases may need to use eh_frame information.

        if (text_section_sp && function_starts_data.GetByteSize())
        {
            FunctionStarts::Entry function_start_entry;
            function_start_entry.data = false;
            lldb::offset_t function_start_offset = 0;
            function_start_entry.addr = text_section_sp->GetFileAddress();
            uint64_t delta;
            while ((delta = function_starts_data.GetULEB128(&function_start_offset)) > 0)
            {
                // Now append the current entry
                function_start_entry.addr += delta;
                function_starts.Append(function_start_entry);
            }
        }
        else
        {
            // If m_type is eTypeDebugInfo, then this is a dSYM - it will have the load command claiming an eh_frame
            // but it doesn't actually have the eh_frame content.  And if we have a dSYM, we don't need to do any
            // of this fill-in-the-missing-symbols works anyway - the debug info should give us all the functions in
            // the module.
            if (text_section_sp.get() && eh_frame_section_sp.get() && m_type != eTypeDebugInfo)
            {
                DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp, eRegisterKindGCC, true);
                DWARFCallFrameInfo::FunctionAddressAndSizeVector functions;
                eh_frame.GetFunctionAddressAndSizeVector (functions);
                addr_t text_base_addr = text_section_sp->GetFileAddress();
                size_t count = functions.GetSize();
                for (size_t i = 0; i < count; ++i)
                {
                    const DWARFCallFrameInfo::FunctionAddressAndSizeVector::Entry *func = functions.GetEntryAtIndex (i);
                    if (func)
                    {
                        FunctionStarts::Entry function_start_entry;
                        function_start_entry.addr = func->base - text_base_addr;
                        function_starts.Append(function_start_entry);
                    }
                }
            }
        }

        const size_t function_starts_count = function_starts.GetSize();

        const user_id_t TEXT_eh_frame_sectID =
            eh_frame_section_sp.get() ? eh_frame_section_sp->GetID()
                                      : static_cast<user_id_t>(NO_SECT);

        lldb::offset_t nlist_data_offset = 0;

        uint32_t N_SO_index = UINT32_MAX;

        MachSymtabSectionInfo section_info (section_list);
        std::vector<uint32_t> N_FUN_indexes;
        std::vector<uint32_t> N_NSYM_indexes;
        std::vector<uint32_t> N_INCL_indexes;
        std::vector<uint32_t> N_BRAC_indexes;
        std::vector<uint32_t> N_COMM_indexes;
        typedef std::multimap <uint64_t, uint32_t> ValueToSymbolIndexMap;
        typedef std::map <uint32_t, uint32_t> NListIndexToSymbolIndexMap;
        typedef std::map <const char *, uint32_t> ConstNameToSymbolIndexMap;
        ValueToSymbolIndexMap N_FUN_addr_to_sym_idx;
        ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx;
        ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx;
        // Any symbols that get merged into another will get an entry
        // in this map so we know
        NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx;
        uint32_t nlist_idx = 0;
        Symbol *symbol_ptr = NULL;

        uint32_t sym_idx = 0;
        Symbol *sym = NULL;
        size_t num_syms = 0;
        std::string memory_symbol_name;
        uint32_t unmapped_local_symbols_found = 0;

        std::vector<TrieEntryWithOffset> trie_entries;
        std::set<lldb::addr_t> resolver_addresses;

        if (dyld_trie_data.GetByteSize() > 0)
        {
            std::vector<llvm::StringRef> nameSlices;
            ParseTrieEntries (dyld_trie_data,
                              0,
                              nameSlices,
                              resolver_addresses,
                              trie_entries);
            
            ConstString text_segment_name ("__TEXT");
            SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
            if (text_segment_sp)
            {
                const lldb::addr_t text_segment_file_addr = text_segment_sp->GetFileAddress();
                if (text_segment_file_addr != LLDB_INVALID_ADDRESS)
                {
                    for (auto &e : trie_entries)
                        e.entry.address += text_segment_file_addr;
                }
            }
        }

#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))

        // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been optimized by moving LOCAL
        // symbols out of the memory mapped portion of the DSC. The symbol information has all been retained,
        // but it isn't available in the normal nlist data. However, there *are* duplicate entries of *some*
        // LOCAL symbols in the normal nlist data. To handle this situation correctly, we must first attempt
        // to parse any DSC unmapped symbol information. If we find any, we set a flag that tells the normal
        // nlist parser to ignore all LOCAL symbols.

        if (m_header.flags & 0x80000000u)
        {
            // Before we can start mapping the DSC, we need to make certain the target process is actually
            // using the cache we can find.

            // Next we need to determine the correct path for the dyld shared cache.

            ArchSpec header_arch;
            GetArchitecture(header_arch);
            char dsc_path[PATH_MAX];

            snprintf(dsc_path, sizeof(dsc_path), "%s%s%s",
                     "/System/Library/Caches/com.apple.dyld/",  /* IPHONE_DYLD_SHARED_CACHE_DIR */
                     "dyld_shared_cache_",          /* DYLD_SHARED_CACHE_BASE_NAME */
                     header_arch.GetArchitectureName());

            FileSpec dsc_filespec(dsc_path, false);

            // We need definitions of two structures in the on-disk DSC, copy them here manually
            struct lldb_copy_dyld_cache_header_v0
            {
                char        magic[16];            // e.g. "dyld_v0    i386", "dyld_v1   armv7", etc.
                uint32_t    mappingOffset;        // file offset to first dyld_cache_mapping_info
                uint32_t    mappingCount;         // number of dyld_cache_mapping_info entries
                uint32_t    imagesOffset;
                uint32_t    imagesCount;
                uint64_t    dyldBaseAddress;
                uint64_t    codeSignatureOffset;
                uint64_t    codeSignatureSize;
                uint64_t    slideInfoOffset;
                uint64_t    slideInfoSize;
                uint64_t    localSymbolsOffset;   // file offset of where local symbols are stored
                uint64_t    localSymbolsSize;     // size of local symbols information
            };
            struct lldb_copy_dyld_cache_header_v1
            {
                char        magic[16];            // e.g. "dyld_v0    i386", "dyld_v1   armv7", etc.
                uint32_t    mappingOffset;        // file offset to first dyld_cache_mapping_info
                uint32_t    mappingCount;         // number of dyld_cache_mapping_info entries
                uint32_t    imagesOffset;
                uint32_t    imagesCount;
                uint64_t    dyldBaseAddress;
                uint64_t    codeSignatureOffset;
                uint64_t    codeSignatureSize;
                uint64_t    slideInfoOffset;
                uint64_t    slideInfoSize;
                uint64_t    localSymbolsOffset;
                uint64_t    localSymbolsSize;
                uint8_t     uuid[16];             // v1 and above, also recorded in dyld_all_image_infos v13 and later
            };

            struct lldb_copy_dyld_cache_mapping_info
            {
                uint64_t        address;
                uint64_t        size;
                uint64_t        fileOffset;
                uint32_t        maxProt;
                uint32_t        initProt;
            };

            struct lldb_copy_dyld_cache_local_symbols_info
            {
                uint32_t        nlistOffset;
                uint32_t        nlistCount;
                uint32_t        stringsOffset;
                uint32_t        stringsSize;
                uint32_t        entriesOffset;
                uint32_t        entriesCount;
            };
            struct lldb_copy_dyld_cache_local_symbols_entry
            {
                uint32_t        dylibOffset;
                uint32_t        nlistStartIndex;
                uint32_t        nlistCount;
            };

            /* The dyld_cache_header has a pointer to the dyld_cache_local_symbols_info structure (localSymbolsOffset).
               The dyld_cache_local_symbols_info structure gives us three things:
                 1. The start and count of the nlist records in the dyld_shared_cache file
                 2. The start and size of the strings for these nlist records
                 3. The start and count of dyld_cache_local_symbols_entry entries

               There is one dyld_cache_local_symbols_entry per dylib/framework in the dyld shared cache.
               The "dylibOffset" field is the Mach-O header of this dylib/framework in the dyld shared cache.
               The dyld_cache_local_symbols_entry also lists the start of this dylib/framework's nlist records
               and the count of how many nlist records there are for this dylib/framework.
            */

            // Process the dsc header to find the unmapped symbols
            //
            // Save some VM space, do not map the entire cache in one shot.

            DataBufferSP dsc_data_sp;
            dsc_data_sp = dsc_filespec.MemoryMapFileContents(0, sizeof(struct lldb_copy_dyld_cache_header_v1));

            if (dsc_data_sp)
            {
                DataExtractor dsc_header_data(dsc_data_sp, byte_order, addr_byte_size);

                char version_str[17];
                int version = -1;
                lldb::offset_t offset = 0;
                memcpy (version_str, dsc_header_data.GetData (&offset, 16), 16);
                version_str[16] = '\0';
                if (strncmp (version_str, "dyld_v", 6) == 0 && isdigit (version_str[6]))
                {
                    int v;
                    if (::sscanf (version_str + 6, "%d", &v) == 1)
                    {
                        version = v;
                    }
                }

                UUID dsc_uuid;
                if (version >= 1)
                {
                    offset = offsetof (struct lldb_copy_dyld_cache_header_v1, uuid);
                    uint8_t uuid_bytes[sizeof (uuid_t)];
                    memcpy (uuid_bytes, dsc_header_data.GetData (&offset, sizeof (uuid_t)), sizeof (uuid_t));
                    dsc_uuid.SetBytes (uuid_bytes);
                }

                bool uuid_match = true;
                if (dsc_uuid.IsValid() && process)
                {
                    UUID shared_cache_uuid(GetProcessSharedCacheUUID(process));

                    if (shared_cache_uuid.IsValid() && dsc_uuid != shared_cache_uuid)
                    {
                        // The on-disk dyld_shared_cache file is not the same as the one in this
                        // process' memory, don't use it.
                        uuid_match = false;
                        ModuleSP module_sp (GetModule());
                        if (module_sp)
                            module_sp->ReportWarning ("process shared cache does not match on-disk dyld_shared_cache file, some symbol names will be missing.");
                    }
                }

                offset = offsetof (struct lldb_copy_dyld_cache_header_v1, mappingOffset);

                uint32_t mappingOffset = dsc_header_data.GetU32(&offset);

                // If the mappingOffset points to a location inside the header, we've
                // opened an old dyld shared cache, and should not proceed further.
                if (uuid_match && mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v0))
                {

                    DataBufferSP dsc_mapping_info_data_sp = dsc_filespec.MemoryMapFileContents(mappingOffset, sizeof (struct lldb_copy_dyld_cache_mapping_info));
                    DataExtractor dsc_mapping_info_data(dsc_mapping_info_data_sp, byte_order, addr_byte_size);
                    offset = 0;

                    // The File addresses (from the in-memory Mach-O load commands) for the shared libraries
                    // in the shared library cache need to be adjusted by an offset to match up with the
                    // dylibOffset identifying field in the dyld_cache_local_symbol_entry's.  This offset is
                    // recorded in mapping_offset_value.
                    const uint64_t mapping_offset_value = dsc_mapping_info_data.GetU64(&offset);

                    offset = offsetof (struct lldb_copy_dyld_cache_header_v1, localSymbolsOffset);
                    uint64_t localSymbolsOffset = dsc_header_data.GetU64(&offset);
                    uint64_t localSymbolsSize = dsc_header_data.GetU64(&offset);

                    if (localSymbolsOffset && localSymbolsSize)
                    {
                        // Map the local symbols
                        if (DataBufferSP dsc_local_symbols_data_sp = dsc_filespec.MemoryMapFileContents(localSymbolsOffset, localSymbolsSize))
                        {
                            DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp, byte_order, addr_byte_size);

                            offset = 0;

                            // Read the local_symbols_infos struct in one shot
                            struct lldb_copy_dyld_cache_local_symbols_info local_symbols_info;
                            dsc_local_symbols_data.GetU32(&offset, &local_symbols_info.nlistOffset, 6);

                            SectionSP text_section_sp(section_list->FindSectionByName(GetSegmentNameTEXT()));

                            uint32_t header_file_offset = (text_section_sp->GetFileAddress() - mapping_offset_value);

                            offset = local_symbols_info.entriesOffset;
                            for (uint32_t entry_index = 0; entry_index < local_symbols_info.entriesCount; entry_index++)
                            {
                                struct lldb_copy_dyld_cache_local_symbols_entry local_symbols_entry;
                                local_symbols_entry.dylibOffset = dsc_local_symbols_data.GetU32(&offset);
                                local_symbols_entry.nlistStartIndex = dsc_local_symbols_data.GetU32(&offset);
                                local_symbols_entry.nlistCount = dsc_local_symbols_data.GetU32(&offset);

                                if (header_file_offset == local_symbols_entry.dylibOffset)
                                {
                                    unmapped_local_symbols_found = local_symbols_entry.nlistCount;

                                    // The normal nlist code cannot correctly size the Symbols array, we need to allocate it here.
                                    sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms + unmapped_local_symbols_found - m_dysymtab.nlocalsym);
                                    num_syms = symtab->GetNumSymbols();

                                    nlist_data_offset = local_symbols_info.nlistOffset + (nlist_byte_size * local_symbols_entry.nlistStartIndex);
                                    uint32_t string_table_offset = local_symbols_info.stringsOffset;

                                    for (uint32_t nlist_index = 0; nlist_index < local_symbols_entry.nlistCount; nlist_index++)
                                    {
                                        /////////////////////////////
                                        {
                                            struct nlist_64 nlist;
                                            if (!dsc_local_symbols_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
                                                break;

                                            nlist.n_strx  = dsc_local_symbols_data.GetU32_unchecked(&nlist_data_offset);
                                            nlist.n_type  = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset);
                                            nlist.n_sect  = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset);
                                            nlist.n_desc  = dsc_local_symbols_data.GetU16_unchecked (&nlist_data_offset);
                                            nlist.n_value = dsc_local_symbols_data.GetAddress_unchecked (&nlist_data_offset);

                                            SymbolType type = eSymbolTypeInvalid;
                                            const char *symbol_name = dsc_local_symbols_data.PeekCStr(string_table_offset + nlist.n_strx);

                                            if (symbol_name == NULL)
                                            {
                                                // No symbol should be NULL, even the symbols with no
                                                // string values should have an offset zero which points
                                                // to an empty C-string
                                                Host::SystemLog (Host::eSystemLogError,
                                                                 "error: DSC unmapped local symbol[%u] has invalid string table offset 0x%x in %s, ignoring symbol\n",
                                                                 entry_index,
                                                                 nlist.n_strx,
                                                                 module_sp->GetFileSpec().GetPath().c_str());
                                                continue;
                                            }
                                            if (symbol_name[0] == '\0')
                                                symbol_name = NULL;

                                            const char *symbol_name_non_abi_mangled = NULL;

                                            SectionSP symbol_section;
                                            uint32_t symbol_byte_size = 0;
                                            bool add_nlist = true;
                                            bool is_debug = ((nlist.n_type & N_STAB) != 0);
                                            bool demangled_is_synthesized = false;
                                            bool is_gsym = false;

                                            assert (sym_idx < num_syms);

                                            sym[sym_idx].SetDebug (is_debug);

                                            if (is_debug)
                                            {
                                                switch (nlist.n_type)
                                                {
                                                    case N_GSYM:
                                                        // global symbol: name,,NO_SECT,type,0
                                                        // Sometimes the N_GSYM value contains the address.

                                                        // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data.  They
                                                        // have the same address, but we want to ensure that we always find only the real symbol,
                                                        // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
                                                        // symbol type.  This is a temporary hack to make sure the ObjectiveC symbols get treated
                                                        // correctly.  To do this right, we should coalesce all the GSYM & global symbols that have the
                                                        // same address.

                                                        if (symbol_name && symbol_name[0] == '_' && symbol_name[1] ==  'O'
                                                            && (strncmp (symbol_name, "_OBJC_IVAR_$_", strlen ("_OBJC_IVAR_$_")) == 0
                                                                || strncmp (symbol_name, "_OBJC_CLASS_$_", strlen ("_OBJC_CLASS_$_")) == 0
                                                                || strncmp (symbol_name, "_OBJC_METACLASS_$_", strlen ("_OBJC_METACLASS_$_")) == 0))
                                                            add_nlist = false;
                                                        else
                                                        {
                                                            is_gsym = true;
                                                            sym[sym_idx].SetExternal(true);
                                                            if (nlist.n_value != 0)
                                                                symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
                                                            type = eSymbolTypeData;
                                                        }
                                                        break;

                                                    case N_FNAME:
                                                        // procedure name (f77 kludge): name,,NO_SECT,0,0
                                                        type = eSymbolTypeCompiler;
                                                        break;

                                                    case N_FUN:
                                                        // procedure: name,,n_sect,linenumber,address
                                                        if (symbol_name)
                                                        {
                                                            type = eSymbolTypeCode;
                                                            symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);

                                                            N_FUN_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
                                                            // We use the current number of symbols in the symbol table in lieu of
                                                            // using nlist_idx in case we ever start trimming entries out
                                                            N_FUN_indexes.push_back(sym_idx);
                                                        }
                                                        else
                                                        {
                                                            type = eSymbolTypeCompiler;

                                                            if ( !N_FUN_indexes.empty() )
                                                            {
                                                                // Copy the size of the function into the original STAB entry so we don't have
                                                                // to hunt for it later
                                                                symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
                                                                N_FUN_indexes.pop_back();
                                                                // We don't really need the end function STAB as it contains the size which
                                                                // we already placed with the original symbol, so don't add it if we want a
                                                                // minimal symbol table
                                                                add_nlist = false;
                                                            }
                                                        }
                                                        break;

                                                    case N_STSYM:
                                                        // static symbol: name,,n_sect,type,address
                                                        N_STSYM_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
                                                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
                                                        type = eSymbolTypeData;
                                                        break;

                                                    case N_LCSYM:
                                                        // .lcomm symbol: name,,n_sect,type,address
                                                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
                                                        type = eSymbolTypeCommonBlock;
                                                        break;

                                                    case N_BNSYM:
                                                        // We use the current number of symbols in the symbol table in lieu of
                                                        // using nlist_idx in case we ever start trimming entries out
                                                        // Skip these if we want minimal symbol tables
                                                        add_nlist = false;
                                                        break;

                                                    case N_ENSYM:
                                                        // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
                                                        // so that we can always skip the entire symbol if we need to navigate
                                                        // more quickly at the source level when parsing STABS
                                                        // Skip these if we want minimal symbol tables
                                                        add_nlist = false;
                                                        break;


                                                    case N_OPT:
                                                        // emitted with gcc2_compiled and in gcc source
                                                        type = eSymbolTypeCompiler;
                                                        break;

                                                    case N_RSYM:
                                                        // register sym: name,,NO_SECT,type,register
                                                        type = eSymbolTypeVariable;
                                                        break;

                                                    case N_SLINE:
                                                        // src line: 0,,n_sect,linenumber,address
                                                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
                                                        type = eSymbolTypeLineEntry;
                                                        break;

                                                    case N_SSYM:
                                                        // structure elt: name,,NO_SECT,type,struct_offset
                                                        type = eSymbolTypeVariableType;
                                                        break;

                                                    case N_SO:
                                                        // source file name
                                                        type = eSymbolTypeSourceFile;
                                                        if (symbol_name == NULL)
                                                        {
                                                            add_nlist = false;
                                                            if (N_SO_index != UINT32_MAX)
                                                            {
                                                                // Set the size of the N_SO to the terminating index of this N_SO
                                                                // so that we can always skip the entire N_SO if we need to navigate
                                                                // more quickly at the source level when parsing STABS
                                                                symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
                                                                symbol_ptr->SetByteSize(sym_idx);
                                                                symbol_ptr->SetSizeIsSibling(true);
                                                            }
                                                            N_NSYM_indexes.clear();
                                                            N_INCL_indexes.clear();
                                                            N_BRAC_indexes.clear();
                                                            N_COMM_indexes.clear();
                                                            N_FUN_indexes.clear();
                                                            N_SO_index = UINT32_MAX;
                                                        }
                                                        else
                                                        {
                                                            // We use the current number of symbols in the symbol table in lieu of
                                                            // using nlist_idx in case we ever start trimming entries out
                                                            const bool N_SO_has_full_path = symbol_name[0] == '/';
                                                            if (N_SO_has_full_path)
                                                            {
                                                                if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
                                                                {
                                                                    // We have two consecutive N_SO entries where the first contains a directory
                                                                    // and the second contains a full path.
                                                                    sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
                                                                    m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
                                                                    add_nlist = false;
                                                                }
                                                                else
                                                                {
                                                                    // This is the first entry in a N_SO that contains a directory or
                                                                    // a full path to the source file
                                                                    N_SO_index = sym_idx;
                                                                }
                                                            }
                                                            else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
                                                            {
                                                                // This is usually the second N_SO entry that contains just the filename,
                                                                // so here we combine it with the first one if we are minimizing the symbol table
                                                                const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
                                                                if (so_path && so_path[0])
                                                                {
                                                                    std::string full_so_path (so_path);
                                                                    const size_t double_slash_pos = full_so_path.find("//");
                                                                    if (double_slash_pos != std::string::npos)
                                                                    {
                                                                        // The linker has been generating bad N_SO entries with doubled up paths
                                                                        // in the format "%s%s" where the first string in the DW_AT_comp_dir,
                                                                        // and the second is the directory for the source file so you end up with
                                                                        // a path that looks like "/tmp/src//tmp/src/"
                                                                        FileSpec so_dir(so_path, false);
                                                                        if (!so_dir.Exists())
                                                                        {
                                                                            so_dir.SetFile(&full_so_path[double_slash_pos + 1], false);
                                                                            if (so_dir.Exists())
                                                                            {
                                                                                // Trim off the incorrect path
                                                                                full_so_path.erase(0, double_slash_pos + 1);
                                                                            }
                                                                        }
                                                                    }
                                                                    if (*full_so_path.rbegin() != '/')
                                                                        full_so_path += '/';
                                                                    full_so_path += symbol_name;
                                                                    sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
                                                                    add_nlist = false;
                                                                    m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
                                                                }
                                                            }
                                                            else
                                                            {
                                                                // This could be a relative path to a N_SO
                                                                N_SO_index = sym_idx;
                                                            }
                                                        }
                                                        break;

                                                    case N_OSO:
                                                        // object file name: name,,0,0,st_mtime
                                                        type = eSymbolTypeObjectFile;
                                                        break;

                                                    case N_LSYM:
                                                        // local sym: name,,NO_SECT,type,offset
                                                        type = eSymbolTypeLocal;
                                                        break;

                                                        //----------------------------------------------------------------------
                                                        // INCL scopes
                                                        //----------------------------------------------------------------------
                                                    case N_BINCL:
                                                        // include file beginning: name,,NO_SECT,0,sum
                                                        // We use the current number of symbols in the symbol table in lieu of
                                                        // using nlist_idx in case we ever start trimming entries out
                                                        N_INCL_indexes.push_back(sym_idx);
                                                        type = eSymbolTypeScopeBegin;
                                                        break;

                                                    case N_EINCL:
                                                        // include file end: name,,NO_SECT,0,0
                                                        // Set the size of the N_BINCL to the terminating index of this N_EINCL
                                                        // so that we can always skip the entire symbol if we need to navigate
                                                        // more quickly at the source level when parsing STABS
                                                        if ( !N_INCL_indexes.empty() )
                                                        {
                                                            symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
                                                            symbol_ptr->SetByteSize(sym_idx + 1);
                                                            symbol_ptr->SetSizeIsSibling(true);
                                                            N_INCL_indexes.pop_back();
                                                        }
                                                        type = eSymbolTypeScopeEnd;
                                                        break;

                                                    case N_SOL:
                                                        // #included file name: name,,n_sect,0,address
                                                        type = eSymbolTypeHeaderFile;

                                                        // We currently don't use the header files on darwin
                                                        add_nlist = false;
                                                        break;

                                                    case N_PARAMS:
                                                        // compiler parameters: name,,NO_SECT,0,0
                                                        type = eSymbolTypeCompiler;
                                                        break;

                                                    case N_VERSION:
                                                        // compiler version: name,,NO_SECT,0,0
                                                        type = eSymbolTypeCompiler;
                                                        break;

                                                    case N_OLEVEL:
                                                        // compiler -O level: name,,NO_SECT,0,0
                                                        type = eSymbolTypeCompiler;
                                                        break;

                                                    case N_PSYM:
                                                        // parameter: name,,NO_SECT,type,offset
                                                        type = eSymbolTypeVariable;
                                                        break;

                                                    case N_ENTRY:
                                                        // alternate entry: name,,n_sect,linenumber,address
                                                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
                                                        type = eSymbolTypeLineEntry;
                                                        break;

                                                        //----------------------------------------------------------------------
                                                        // Left and Right Braces
                                                        //----------------------------------------------------------------------
                                                    case N_LBRAC:
                                                        // left bracket: 0,,NO_SECT,nesting level,address
                                                        // We use the current number of symbols in the symbol table in lieu of
                                                        // using nlist_idx in case we ever start trimming entries out
                                                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
                                                        N_BRAC_indexes.push_back(sym_idx);
                                                        type = eSymbolTypeScopeBegin;
                                                        break;

                                                    case N_RBRAC:
                                                        // right bracket: 0,,NO_SECT,nesting level,address
                                                        // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
                                                        // so that we can always skip the entire symbol if we need to navigate
                                                        // more quickly at the source level when parsing STABS
                                                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
                                                        if ( !N_BRAC_indexes.empty() )
                                                        {
                                                            symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
                                                            symbol_ptr->SetByteSize(sym_idx + 1);
                                                            symbol_ptr->SetSizeIsSibling(true);
                                                            N_BRAC_indexes.pop_back();
                                                        }
                                                        type = eSymbolTypeScopeEnd;
                                                        break;

                                                    case N_EXCL:
                                                        // deleted include file: name,,NO_SECT,0,sum
                                                        type = eSymbolTypeHeaderFile;
                                                        break;

                                                        //----------------------------------------------------------------------
                                                        // COMM scopes
                                                        //----------------------------------------------------------------------
                                                    case N_BCOMM:
                                                        // begin common: name,,NO_SECT,0,0
                                                        // We use the current number of symbols in the symbol table in lieu of
                                                        // using nlist_idx in case we ever start trimming entries out
                                                        type = eSymbolTypeScopeBegin;
                                                        N_COMM_indexes.push_back(sym_idx);
                                                        break;

                                                    case N_ECOML:
                                                        // end common (local name): 0,,n_sect,0,address
                                                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
                                                        // Fall through

                                                    case N_ECOMM:
                                                        // end common: name,,n_sect,0,0
                                                        // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
                                                        // so that we can always skip the entire symbol if we need to navigate
                                                        // more quickly at the source level when parsing STABS
                                                        if ( !N_COMM_indexes.empty() )
                                                        {
                                                            symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
                                                            symbol_ptr->SetByteSize(sym_idx + 1);
                                                            symbol_ptr->SetSizeIsSibling(true);
                                                            N_COMM_indexes.pop_back();
                                                        }
                                                        type = eSymbolTypeScopeEnd;
                                                        break;

                                                    case N_LENG:
                                                        // second stab entry with length information
                                                        type = eSymbolTypeAdditional;
                                                        break;

                                                    default: break;
                                                }
                                            }
                                            else
                                            {
                                                //uint8_t n_pext    = N_PEXT & nlist.n_type;
                                                uint8_t n_type  = N_TYPE & nlist.n_type;
                                                sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);

                                                switch (n_type)
                                                {
                                                    case N_INDR: // Fall through
                                                    case N_PBUD: // Fall through
                                                    case N_UNDF:
                                                        type = eSymbolTypeUndefined;
                                                        break;

                                                    case N_ABS:
                                                        type = eSymbolTypeAbsolute;
                                                        break;

                                                    case N_SECT:
                                                        {
                                                            symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);

                                                            if (symbol_section == NULL)
                                                            {
                                                                // TODO: warn about this?
                                                                add_nlist = false;
                                                                break;
                                                            }

                                                            if (TEXT_eh_frame_sectID == nlist.n_sect)
                                                            {
                                                                type = eSymbolTypeException;
                                                            }
                                                            else
                                                            {
                                                                uint32_t section_type = symbol_section->Get() & SECTION_TYPE;

                                                                switch (section_type)
                                                                {
                                                                    case S_CSTRING_LITERALS:           type = eSymbolTypeData;    break; // section with only literal C strings
                                                                    case S_4BYTE_LITERALS:             type = eSymbolTypeData;    break; // section with only 4 byte literals
                                                                    case S_8BYTE_LITERALS:             type = eSymbolTypeData;    break; // section with only 8 byte literals
                                                                    case S_LITERAL_POINTERS:           type = eSymbolTypeTrampoline; break; // section with only pointers to literals
                                                                    case S_NON_LAZY_SYMBOL_POINTERS:   type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
                                                                    case S_LAZY_SYMBOL_POINTERS:       type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
                                                                    case S_SYMBOL_STUBS:               type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
                                                                    case S_MOD_INIT_FUNC_POINTERS:     type = eSymbolTypeCode;    break; // section with only function pointers for initialization
                                                                    case S_MOD_TERM_FUNC_POINTERS:     type = eSymbolTypeCode;    break; // section with only function pointers for termination
                                                                    case S_INTERPOSING:                type = eSymbolTypeTrampoline;  break; // section with only pairs of function pointers for interposing
                                                                    case S_16BYTE_LITERALS:            type = eSymbolTypeData;    break; // section with only 16 byte literals
                                                                    case S_DTRACE_DOF:                 type = eSymbolTypeInstrumentation; break;
                                                                    case S_LAZY_DYLIB_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break;
                                                                    default:
                                                                        switch (symbol_section->GetType())
                                                                        {
                                                                            case lldb::eSectionTypeCode:
                                                                                type = eSymbolTypeCode;
                                                                                break;
                                                                            case eSectionTypeData:
                                                                            case eSectionTypeDataCString:            // Inlined C string data
                                                                            case eSectionTypeDataCStringPointers:    // Pointers to C string data
                                                                            case eSectionTypeDataSymbolAddress:      // Address of a symbol in the symbol table
                                                                            case eSectionTypeData4:
                                                                            case eSectionTypeData8:
                                                                            case eSectionTypeData16:
                                                                                type = eSymbolTypeData;
                                                                                break;
                                                                            default:
                                                                                break;
                                                                        }
                                                                        break;
                                                                }

                                                                if (type == eSymbolTypeInvalid)
                                                                {
                                                                    const char *symbol_sect_name = symbol_section->GetName().AsCString();
                                                                    if (symbol_section->IsDescendant (text_section_sp.get()))
                                                                    {
                                                                        if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
                                                                                                    S_ATTR_SELF_MODIFYING_CODE |
                                                                                                    S_ATTR_SOME_INSTRUCTIONS))
                                                                            type = eSymbolTypeData;
                                                                        else
                                                                            type = eSymbolTypeCode;
                                                                    }
                                                                    else if (symbol_section->IsDescendant(data_section_sp.get()))
                                                                    {
                                                                        if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
                                                                        {
                                                                            type = eSymbolTypeRuntime;

                                                                            if (symbol_name &&
                                                                                symbol_name[0] == '_' &&
                                                                                symbol_name[1] == 'O' &&
                                                                                symbol_name[2] == 'B')
                                                                            {
                                                                                llvm::StringRef symbol_name_ref(symbol_name);
                                                                                static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
                                                                                static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
                                                                                static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
                                                                                if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
                                                                                {
                                                                                    symbol_name_non_abi_mangled = symbol_name + 1;
                                                                                    symbol_name = symbol_name + g_objc_v2_prefix_class.size();
                                                                                    type = eSymbolTypeObjCClass;
                                                                                    demangled_is_synthesized = true;
                                                                                }
                                                                                else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
                                                                                {
                                                                                    symbol_name_non_abi_mangled = symbol_name + 1;
                                                                                    symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
                                                                                    type = eSymbolTypeObjCMetaClass;
                                                                                    demangled_is_synthesized = true;
                                                                                }
                                                                                else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
                                                                                {
                                                                                    symbol_name_non_abi_mangled = symbol_name + 1;
                                                                                    symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
                                                                                    type = eSymbolTypeObjCIVar;
                                                                                    demangled_is_synthesized = true;
                                                                                }
                                                                            }
                                                                        }
                                                                        else if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
                                                                        {
                                                                            type = eSymbolTypeException;
                                                                        }
                                                                        else
                                                                        {
                                                                            type = eSymbolTypeData;
                                                                        }
                                                                    }
                                                                    else if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
                                                                    {
                                                                        type = eSymbolTypeTrampoline;
                                                                    }
                                                                    else if (symbol_section->IsDescendant(objc_section_sp.get()))
                                                                    {
                                                                        type = eSymbolTypeRuntime;
                                                                        if (symbol_name && symbol_name[0] == '.')
                                                                        {
                                                                            llvm::StringRef symbol_name_ref(symbol_name);
                                                                            static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
                                                                            if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
                                                                            {
                                                                                symbol_name_non_abi_mangled = symbol_name;
                                                                                symbol_name = symbol_name + g_objc_v1_prefix_class.size();
                                                                                type = eSymbolTypeObjCClass;
                                                                                demangled_is_synthesized = true;
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                        break;
                                                }
                                            }

                                            if (add_nlist)
                                            {
                                                uint64_t symbol_value = nlist.n_value;
                                                if (symbol_name_non_abi_mangled)
                                                {
                                                    sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
                                                    sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
                                                }
                                                else
                                                {
                                                    bool symbol_name_is_mangled = false;
                                                    
                                                    if (symbol_name && symbol_name[0] == '_')
                                                    {
                                                        symbol_name_is_mangled = symbol_name[1] == '_';
                                                        symbol_name++;  // Skip the leading underscore
                                                    }

                                                    if (symbol_name)
                                                    {
                                                        ConstString const_symbol_name(symbol_name);
                                                        sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
                                                        if (is_gsym && is_debug)
                                                            N_GSYM_name_to_sym_idx[sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString()] = sym_idx;
                                                    }
                                                }
                                                if (symbol_section)
                                                {
                                                    const addr_t section_file_addr = symbol_section->GetFileAddress();
                                                    if (symbol_byte_size == 0 && function_starts_count > 0)
                                                    {
                                                        addr_t symbol_lookup_file_addr = nlist.n_value;
                                                        // Do an exact address match for non-ARM addresses, else get the closest since
                                                        // the symbol might be a thumb symbol which has an address with bit zero set
                                                        FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
                                                        if (is_arm && func_start_entry)
                                                        {
                                                            // Verify that the function start address is the symbol address (ARM)
                                                            // or the symbol address + 1 (thumb)
                                                            if (func_start_entry->addr != symbol_lookup_file_addr &&
                                                                func_start_entry->addr != (symbol_lookup_file_addr + 1))
                                                            {
                                                                // Not the right entry, NULL it out...
                                                                func_start_entry = NULL;
                                                            }
                                                        }
                                                        if (func_start_entry)
                                                        {
                                                            func_start_entry->data = true;

                                                            addr_t symbol_file_addr = func_start_entry->addr;
                                                            uint32_t symbol_flags = 0;
                                                            if (is_arm)
                                                            {
                                                                if (symbol_file_addr & 1)
                                                                    symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
                                                                symbol_file_addr &= 0xfffffffffffffffeull;
                                                            }

                                                            const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
                                                            const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
                                                            if (next_func_start_entry)
                                                            {
                                                                addr_t next_symbol_file_addr = next_func_start_entry->addr;
                                                                // Be sure the clear the Thumb address bit when we calculate the size
                                                                // from the current and next address
                                                                if (is_arm)
                                                                    next_symbol_file_addr &= 0xfffffffffffffffeull;
                                                                symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
                                                            }
                                                            else
                                                            {
                                                                symbol_byte_size = section_end_file_addr - symbol_file_addr;
                                                            }
                                                        }
                                                    }
                                                    symbol_value -= section_file_addr;
                                                }

                                                if (is_debug == false)
                                                {
                                                    if (type == eSymbolTypeCode)
                                                    {
                                                        // See if we can find a N_FUN entry for any code symbols.
                                                        // If we do find a match, and the name matches, then we
                                                        // can merge the two into just the function symbol to avoid
                                                        // duplicate entries in the symbol table
                                                        std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
                                                        range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
                                                        if (range.first != range.second)
                                                        {
                                                            bool found_it = false;
                                                            for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
                                                            {
                                                                if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
                                                                {
                                                                    m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
                                                                    // We just need the flags from the linker symbol, so put these flags
                                                                    // into the N_FUN flags to avoid duplicate symbols in the symbol table
                                                                    sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
                                                                    sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
                                                                    if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
                                                                        sym[pos->second].SetType (eSymbolTypeResolver);
                                                                    sym[sym_idx].Clear();
                                                                    found_it = true;
                                                                    break;
                                                                }
                                                            }
                                                            if (found_it)
                                                                continue;
                                                        }
                                                        else
                                                        {
                                                            if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
                                                                type = eSymbolTypeResolver;
                                                        }
                                                    }
                                                    else if (type == eSymbolTypeData)
                                                    {
                                                        // See if we can find a N_STSYM entry for any data symbols.
                                                        // If we do find a match, and the name matches, then we
                                                        // can merge the two into just the Static symbol to avoid
                                                        // duplicate entries in the symbol table
                                                        std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
                                                        range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
                                                        if (range.first != range.second)
                                                        {
                                                            bool found_it = false;
                                                            for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
                                                            {
                                                                if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
                                                                {
                                                                    m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
                                                                    // We just need the flags from the linker symbol, so put these flags
                                                                    // into the N_STSYM flags to avoid duplicate symbols in the symbol table
                                                                    sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
                                                                    sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
                                                                    sym[sym_idx].Clear();
                                                                    found_it = true;
                                                                    break;
                                                                }
                                                            }
                                                            if (found_it)
                                                                continue;
                                                        }
                                                        else
                                                        {
                                                            // Combine N_GSYM stab entries with the non stab symbol
                                                            ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString());
                                                            if (pos != N_GSYM_name_to_sym_idx.end())
                                                            {
                                                                const uint32_t GSYM_sym_idx = pos->second;
                                                                m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
                                                                // Copy the address, because often the N_GSYM address has an invalid address of zero
                                                                // when the global is a common symbol
                                                                sym[GSYM_sym_idx].GetAddress().SetSection (symbol_section);
                                                                sym[GSYM_sym_idx].GetAddress().SetOffset (symbol_value);
                                                                // We just need the flags from the linker symbol, so put these flags
                                                                // into the N_STSYM flags to avoid duplicate symbols in the symbol table
                                                                sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
                                                                sym[sym_idx].Clear();
                                                                continue;
                                                            }
                                                        }
                                                    }
                                                }

                                                sym[sym_idx].SetID (nlist_idx);
                                                sym[sym_idx].SetType (type);
                                                sym[sym_idx].GetAddress().SetSection (symbol_section);
                                                sym[sym_idx].GetAddress().SetOffset (symbol_value);
                                                sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);

                                                if (symbol_byte_size > 0)
                                                    sym[sym_idx].SetByteSize(symbol_byte_size);

                                                if (demangled_is_synthesized)
                                                    sym[sym_idx].SetDemangledNameIsSynthesized(true);
                                                ++sym_idx;
                                            }
                                            else
                                            {
                                                sym[sym_idx].Clear();
                                            }

                                        }
                                        /////////////////////////////
                                    }
                                    break; // No more entries to consider
                                }
                            }
                        }
                    }
                }
            }
        }

        // Must reset this in case it was mutated above!
        nlist_data_offset = 0;
#endif

        if (nlist_data.GetByteSize() > 0)
        {

            // If the sym array was not created while parsing the DSC unmapped
            // symbols, create it now.
            if (sym == NULL)
            {
                sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
                num_syms = symtab->GetNumSymbols();
            }

            if (unmapped_local_symbols_found)
            {
                assert(m_dysymtab.ilocalsym == 0);
                nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size);
                nlist_idx = m_dysymtab.nlocalsym;
            }
            else
            {
                nlist_idx = 0;
            }

            for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx)
            {
                struct nlist_64 nlist;
                if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size))
                    break;

                nlist.n_strx  = nlist_data.GetU32_unchecked(&nlist_data_offset);
                nlist.n_type  = nlist_data.GetU8_unchecked (&nlist_data_offset);
                nlist.n_sect  = nlist_data.GetU8_unchecked (&nlist_data_offset);
                nlist.n_desc  = nlist_data.GetU16_unchecked (&nlist_data_offset);
                nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset);

                SymbolType type = eSymbolTypeInvalid;
                const char *symbol_name = NULL;

                if (have_strtab_data)
                {
                    symbol_name = strtab_data.PeekCStr(nlist.n_strx);

                    if (symbol_name == NULL)
                    {
                        // No symbol should be NULL, even the symbols with no
                        // string values should have an offset zero which points
                        // to an empty C-string
                        Host::SystemLog (Host::eSystemLogError,
                                         "error: symbol[%u] has invalid string table offset 0x%x in %s, ignoring symbol\n",
                                         nlist_idx,
                                         nlist.n_strx,
                                         module_sp->GetFileSpec().GetPath().c_str());
                        continue;
                    }
                    if (symbol_name[0] == '\0')
                        symbol_name = NULL;
                }
                else
                {
                    const addr_t str_addr = strtab_addr + nlist.n_strx;
                    Error str_error;
                    if (process->ReadCStringFromMemory(str_addr, memory_symbol_name, str_error))
                        symbol_name = memory_symbol_name.c_str();
                }
                const char *symbol_name_non_abi_mangled = NULL;

                SectionSP symbol_section;
                lldb::addr_t symbol_byte_size = 0;
                bool add_nlist = true;
                bool is_gsym = false;
                bool is_debug = ((nlist.n_type & N_STAB) != 0);
                bool demangled_is_synthesized = false;

                assert (sym_idx < num_syms);

                sym[sym_idx].SetDebug (is_debug);

                if (is_debug)
                {
                    switch (nlist.n_type)
                    {
                    case N_GSYM:
                        // global symbol: name,,NO_SECT,type,0
                        // Sometimes the N_GSYM value contains the address.

                        // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data.  They
                        // have the same address, but we want to ensure that we always find only the real symbol,
                        // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
                        // symbol type.  This is a temporary hack to make sure the ObjectiveC symbols get treated
                        // correctly.  To do this right, we should coalesce all the GSYM & global symbols that have the
                        // same address.

                        if (symbol_name && symbol_name[0] == '_' && symbol_name[1] ==  'O'
                            && (strncmp (symbol_name, "_OBJC_IVAR_$_", strlen ("_OBJC_IVAR_$_")) == 0
                                || strncmp (symbol_name, "_OBJC_CLASS_$_", strlen ("_OBJC_CLASS_$_")) == 0
                                || strncmp (symbol_name, "_OBJC_METACLASS_$_", strlen ("_OBJC_METACLASS_$_")) == 0))
                            add_nlist = false;
                        else
                        {
                            is_gsym = true;
                            sym[sym_idx].SetExternal(true);
                            if (nlist.n_value != 0)
                                symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
                            type = eSymbolTypeData;
                        }
                        break;

                    case N_FNAME:
                        // procedure name (f77 kludge): name,,NO_SECT,0,0
                        type = eSymbolTypeCompiler;
                        break;

                    case N_FUN:
                        // procedure: name,,n_sect,linenumber,address
                        if (symbol_name)
                        {
                            type = eSymbolTypeCode;
                            symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);

                            N_FUN_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
                            // We use the current number of symbols in the symbol table in lieu of
                            // using nlist_idx in case we ever start trimming entries out
                            N_FUN_indexes.push_back(sym_idx);
                        }
                        else
                        {
                            type = eSymbolTypeCompiler;

                            if ( !N_FUN_indexes.empty() )
                            {
                                // Copy the size of the function into the original STAB entry so we don't have
                                // to hunt for it later
                                symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value);
                                N_FUN_indexes.pop_back();
                                // We don't really need the end function STAB as it contains the size which
                                // we already placed with the original symbol, so don't add it if we want a
                                // minimal symbol table
                                add_nlist = false;
                            }
                        }
                        break;

                    case N_STSYM:
                        // static symbol: name,,n_sect,type,address
                        N_STSYM_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx));
                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
                        type = eSymbolTypeData;
                        break;

                    case N_LCSYM:
                        // .lcomm symbol: name,,n_sect,type,address
                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
                        type = eSymbolTypeCommonBlock;
                        break;

                    case N_BNSYM:
                        // We use the current number of symbols in the symbol table in lieu of
                        // using nlist_idx in case we ever start trimming entries out
                        // Skip these if we want minimal symbol tables
                        add_nlist = false;
                        break;

                    case N_ENSYM:
                        // Set the size of the N_BNSYM to the terminating index of this N_ENSYM
                        // so that we can always skip the entire symbol if we need to navigate
                        // more quickly at the source level when parsing STABS
                        // Skip these if we want minimal symbol tables
                        add_nlist = false;
                        break;


                    case N_OPT:
                        // emitted with gcc2_compiled and in gcc source
                        type = eSymbolTypeCompiler;
                        break;

                    case N_RSYM:
                        // register sym: name,,NO_SECT,type,register
                        type = eSymbolTypeVariable;
                        break;

                    case N_SLINE:
                        // src line: 0,,n_sect,linenumber,address
                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
                        type = eSymbolTypeLineEntry;
                        break;

                    case N_SSYM:
                        // structure elt: name,,NO_SECT,type,struct_offset
                        type = eSymbolTypeVariableType;
                        break;

                    case N_SO:
                        // source file name
                        type = eSymbolTypeSourceFile;
                        if (symbol_name == NULL)
                        {
                            add_nlist = false;
                            if (N_SO_index != UINT32_MAX)
                            {
                                // Set the size of the N_SO to the terminating index of this N_SO
                                // so that we can always skip the entire N_SO if we need to navigate
                                // more quickly at the source level when parsing STABS
                                symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
                                symbol_ptr->SetByteSize(sym_idx);
                                symbol_ptr->SetSizeIsSibling(true);
                            }
                            N_NSYM_indexes.clear();
                            N_INCL_indexes.clear();
                            N_BRAC_indexes.clear();
                            N_COMM_indexes.clear();
                            N_FUN_indexes.clear();
                            N_SO_index = UINT32_MAX;
                        }
                        else
                        {
                            // We use the current number of symbols in the symbol table in lieu of
                            // using nlist_idx in case we ever start trimming entries out
                            const bool N_SO_has_full_path = symbol_name[0] == '/';
                            if (N_SO_has_full_path)
                            {
                                if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
                                {
                                    // We have two consecutive N_SO entries where the first contains a directory
                                    // and the second contains a full path.
                                    sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false);
                                    m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
                                    add_nlist = false;
                                }
                                else
                                {
                                    // This is the first entry in a N_SO that contains a directory or
                                    // a full path to the source file
                                    N_SO_index = sym_idx;
                                }
                            }
                            else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms))
                            {
                                // This is usually the second N_SO entry that contains just the filename,
                                // so here we combine it with the first one if we are minimizing the symbol table
                                const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString();
                                if (so_path && so_path[0])
                                {
                                    std::string full_so_path (so_path);
                                    const size_t double_slash_pos = full_so_path.find("//");
                                    if (double_slash_pos != std::string::npos)
                                    {
                                        // The linker has been generating bad N_SO entries with doubled up paths
                                        // in the format "%s%s" where the first string in the DW_AT_comp_dir,
                                        // and the second is the directory for the source file so you end up with
                                        // a path that looks like "/tmp/src//tmp/src/"
                                        FileSpec so_dir(so_path, false);
                                        if (!so_dir.Exists())
                                        {
                                            so_dir.SetFile(&full_so_path[double_slash_pos + 1], false);
                                            if (so_dir.Exists())
                                            {
                                                // Trim off the incorrect path
                                                full_so_path.erase(0, double_slash_pos + 1);
                                            }
                                        }
                                    }
                                    if (*full_so_path.rbegin() != '/')
                                        full_so_path += '/';
                                    full_so_path += symbol_name;
                                    sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false);
                                    add_nlist = false;
                                    m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;
                                }
                            }
                            else
                            {
                                // This could be a relative path to a N_SO
                                N_SO_index = sym_idx;
                            }
                        }

                        break;

                    case N_OSO:
                        // object file name: name,,0,0,st_mtime
                        type = eSymbolTypeObjectFile;
                        break;

                    case N_LSYM:
                        // local sym: name,,NO_SECT,type,offset
                        type = eSymbolTypeLocal;
                        break;

                    //----------------------------------------------------------------------
                    // INCL scopes
                    //----------------------------------------------------------------------
                    case N_BINCL:
                        // include file beginning: name,,NO_SECT,0,sum
                        // We use the current number of symbols in the symbol table in lieu of
                        // using nlist_idx in case we ever start trimming entries out
                        N_INCL_indexes.push_back(sym_idx);
                        type = eSymbolTypeScopeBegin;
                        break;

                    case N_EINCL:
                        // include file end: name,,NO_SECT,0,0
                        // Set the size of the N_BINCL to the terminating index of this N_EINCL
                        // so that we can always skip the entire symbol if we need to navigate
                        // more quickly at the source level when parsing STABS
                        if ( !N_INCL_indexes.empty() )
                        {
                            symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
                            symbol_ptr->SetByteSize(sym_idx + 1);
                            symbol_ptr->SetSizeIsSibling(true);
                            N_INCL_indexes.pop_back();
                        }
                        type = eSymbolTypeScopeEnd;
                        break;

                    case N_SOL:
                        // #included file name: name,,n_sect,0,address
                        type = eSymbolTypeHeaderFile;

                        // We currently don't use the header files on darwin
                        add_nlist = false;
                        break;

                    case N_PARAMS:
                        // compiler parameters: name,,NO_SECT,0,0
                        type = eSymbolTypeCompiler;
                        break;

                    case N_VERSION:
                        // compiler version: name,,NO_SECT,0,0
                        type = eSymbolTypeCompiler;
                        break;

                    case N_OLEVEL:
                        // compiler -O level: name,,NO_SECT,0,0
                        type = eSymbolTypeCompiler;
                        break;

                    case N_PSYM:
                        // parameter: name,,NO_SECT,type,offset
                        type = eSymbolTypeVariable;
                        break;

                    case N_ENTRY:
                        // alternate entry: name,,n_sect,linenumber,address
                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
                        type = eSymbolTypeLineEntry;
                        break;

                    //----------------------------------------------------------------------
                    // Left and Right Braces
                    //----------------------------------------------------------------------
                    case N_LBRAC:
                        // left bracket: 0,,NO_SECT,nesting level,address
                        // We use the current number of symbols in the symbol table in lieu of
                        // using nlist_idx in case we ever start trimming entries out
                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
                        N_BRAC_indexes.push_back(sym_idx);
                        type = eSymbolTypeScopeBegin;
                        break;

                    case N_RBRAC:
                        // right bracket: 0,,NO_SECT,nesting level,address
                        // Set the size of the N_LBRAC to the terminating index of this N_RBRAC
                        // so that we can always skip the entire symbol if we need to navigate
                        // more quickly at the source level when parsing STABS
                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
                        if ( !N_BRAC_indexes.empty() )
                        {
                            symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
                            symbol_ptr->SetByteSize(sym_idx + 1);
                            symbol_ptr->SetSizeIsSibling(true);
                            N_BRAC_indexes.pop_back();
                        }
                        type = eSymbolTypeScopeEnd;
                        break;

                    case N_EXCL:
                        // deleted include file: name,,NO_SECT,0,sum
                        type = eSymbolTypeHeaderFile;
                        break;

                    //----------------------------------------------------------------------
                    // COMM scopes
                    //----------------------------------------------------------------------
                    case N_BCOMM:
                        // begin common: name,,NO_SECT,0,0
                        // We use the current number of symbols in the symbol table in lieu of
                        // using nlist_idx in case we ever start trimming entries out
                        type = eSymbolTypeScopeBegin;
                        N_COMM_indexes.push_back(sym_idx);
                        break;

                    case N_ECOML:
                        // end common (local name): 0,,n_sect,0,address
                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
                        // Fall through

                    case N_ECOMM:
                        // end common: name,,n_sect,0,0
                        // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML
                        // so that we can always skip the entire symbol if we need to navigate
                        // more quickly at the source level when parsing STABS
                        if ( !N_COMM_indexes.empty() )
                        {
                            symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
                            symbol_ptr->SetByteSize(sym_idx + 1);
                            symbol_ptr->SetSizeIsSibling(true);
                            N_COMM_indexes.pop_back();
                        }
                        type = eSymbolTypeScopeEnd;
                        break;

                    case N_LENG:
                        // second stab entry with length information
                        type = eSymbolTypeAdditional;
                        break;

                    default: break;
                    }
                }
                else
                {
                    //uint8_t n_pext    = N_PEXT & nlist.n_type;
                    uint8_t n_type  = N_TYPE & nlist.n_type;
                    sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);

                    switch (n_type)
                    {
                    case N_INDR:// Fall through
                    case N_PBUD:// Fall through
                    case N_UNDF:
                        type = eSymbolTypeUndefined;
                        break;

                    case N_ABS:
                        type = eSymbolTypeAbsolute;
                        break;

                    case N_SECT:
                        {
                            symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);

                            if (!symbol_section)
                            {
                                // TODO: warn about this?
                                add_nlist = false;
                                break;
                            }

                            if (TEXT_eh_frame_sectID == nlist.n_sect)
                            {
                                type = eSymbolTypeException;
                            }
                            else
                            {
                                uint32_t section_type = symbol_section->Get() & SECTION_TYPE;

                                switch (section_type)
                                {
                                case S_CSTRING_LITERALS:           type = eSymbolTypeData;    break; // section with only literal C strings
                                case S_4BYTE_LITERALS:             type = eSymbolTypeData;    break; // section with only 4 byte literals
                                case S_8BYTE_LITERALS:             type = eSymbolTypeData;    break; // section with only 8 byte literals
                                case S_LITERAL_POINTERS:           type = eSymbolTypeTrampoline; break; // section with only pointers to literals
                                case S_NON_LAZY_SYMBOL_POINTERS:   type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
                                case S_LAZY_SYMBOL_POINTERS:       type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
                                case S_SYMBOL_STUBS:               type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
                                case S_MOD_INIT_FUNC_POINTERS:     type = eSymbolTypeCode;    break; // section with only function pointers for initialization
                                case S_MOD_TERM_FUNC_POINTERS:     type = eSymbolTypeCode;    break; // section with only function pointers for termination
                                case S_INTERPOSING:                type = eSymbolTypeTrampoline;  break; // section with only pairs of function pointers for interposing
                                case S_16BYTE_LITERALS:            type = eSymbolTypeData;    break; // section with only 16 byte literals
                                case S_DTRACE_DOF:                 type = eSymbolTypeInstrumentation; break;
                                case S_LAZY_DYLIB_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break;
                                default:
                                    switch (symbol_section->GetType())
                                    {
                                        case lldb::eSectionTypeCode:
                                            type = eSymbolTypeCode;
                                            break;
                                        case eSectionTypeData:
                                        case eSectionTypeDataCString:            // Inlined C string data
                                        case eSectionTypeDataCStringPointers:    // Pointers to C string data
                                        case eSectionTypeDataSymbolAddress:      // Address of a symbol in the symbol table
                                        case eSectionTypeData4:
                                        case eSectionTypeData8:
                                        case eSectionTypeData16:
                                            type = eSymbolTypeData;
                                            break;
                                        default:
                                            break;
                                    }
                                    break;
                                }

                                if (type == eSymbolTypeInvalid)
                                {
                                    const char *symbol_sect_name = symbol_section->GetName().AsCString();
                                    if (symbol_section->IsDescendant (text_section_sp.get()))
                                    {
                                        if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS |
                                                                    S_ATTR_SELF_MODIFYING_CODE |
                                                                    S_ATTR_SOME_INSTRUCTIONS))
                                            type = eSymbolTypeData;
                                        else
                                            type = eSymbolTypeCode;
                                    }
                                    else
                                    if (symbol_section->IsDescendant(data_section_sp.get()))
                                    {
                                        if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
                                        {
                                            type = eSymbolTypeRuntime;

                                            if (symbol_name &&
                                                symbol_name[0] == '_' &&
                                                symbol_name[1] == 'O' &&
                                                symbol_name[2] == 'B')
                                            {
                                                llvm::StringRef symbol_name_ref(symbol_name);
                                                static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
                                                static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
                                                static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
                                                if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
                                                {
                                                    symbol_name_non_abi_mangled = symbol_name + 1;
                                                    symbol_name = symbol_name + g_objc_v2_prefix_class.size();
                                                    type = eSymbolTypeObjCClass;
                                                    demangled_is_synthesized = true;
                                                }
                                                else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
                                                {
                                                    symbol_name_non_abi_mangled = symbol_name + 1;
                                                    symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
                                                    type = eSymbolTypeObjCMetaClass;
                                                    demangled_is_synthesized = true;
                                                }
                                                else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
                                                {
                                                    symbol_name_non_abi_mangled = symbol_name + 1;
                                                    symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
                                                    type = eSymbolTypeObjCIVar;
                                                    demangled_is_synthesized = true;
                                                }
                                            }
                                        }
                                        else
                                        if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
                                        {
                                            type = eSymbolTypeException;
                                        }
                                        else
                                        {
                                            type = eSymbolTypeData;
                                        }
                                    }
                                    else
                                    if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
                                    {
                                        type = eSymbolTypeTrampoline;
                                    }
                                    else
                                    if (symbol_section->IsDescendant(objc_section_sp.get()))
                                    {
                                        type = eSymbolTypeRuntime;
                                        if (symbol_name && symbol_name[0] == '.')
                                        {
                                            llvm::StringRef symbol_name_ref(symbol_name);
                                            static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
                                            if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
                                            {
                                                symbol_name_non_abi_mangled = symbol_name;
                                                symbol_name = symbol_name + g_objc_v1_prefix_class.size();
                                                type = eSymbolTypeObjCClass;
                                                demangled_is_synthesized = true;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        break;
                    }
                }

                if (add_nlist)
                {
                    uint64_t symbol_value = nlist.n_value;

                    if (symbol_name_non_abi_mangled)
                    {
                        sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
                        sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name));
                    }
                    else
                    {
                        bool symbol_name_is_mangled = false;

                        if (symbol_name && symbol_name[0] == '_')
                        {
                            symbol_name_is_mangled = symbol_name[1] == '_';
                            symbol_name++;  // Skip the leading underscore
                        }

                        if (symbol_name)
                        {
                            ConstString const_symbol_name(symbol_name);
                            sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
                            if (is_gsym && is_debug)
                            {
                                N_GSYM_name_to_sym_idx[sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString()] = sym_idx;
                            }
                        }
                    }
                    if (symbol_section)
                    {
                        const addr_t section_file_addr = symbol_section->GetFileAddress();
                        if (symbol_byte_size == 0 && function_starts_count > 0)
                        {
                            addr_t symbol_lookup_file_addr = nlist.n_value;
                            // Do an exact address match for non-ARM addresses, else get the closest since
                            // the symbol might be a thumb symbol which has an address with bit zero set
                            FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm);
                            if (is_arm && func_start_entry)
                            {
                                // Verify that the function start address is the symbol address (ARM)
                                // or the symbol address + 1 (thumb)
                                if (func_start_entry->addr != symbol_lookup_file_addr &&
                                    func_start_entry->addr != (symbol_lookup_file_addr + 1))
                                {
                                    // Not the right entry, NULL it out...
                                    func_start_entry = NULL;
                                }
                            }
                            if (func_start_entry)
                            {
                                func_start_entry->data = true;

                                addr_t symbol_file_addr = func_start_entry->addr;
                                if (is_arm)
                                    symbol_file_addr &= 0xfffffffffffffffeull;

                                const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
                                const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
                                if (next_func_start_entry)
                                {
                                    addr_t next_symbol_file_addr = next_func_start_entry->addr;
                                    // Be sure the clear the Thumb address bit when we calculate the size
                                    // from the current and next address
                                    if (is_arm)
                                        next_symbol_file_addr &= 0xfffffffffffffffeull;
                                    symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
                                }
                                else
                                {
                                    symbol_byte_size = section_end_file_addr - symbol_file_addr;
                                }
                            }
                        }
                        symbol_value -= section_file_addr;
                    }

                    if (is_debug == false)
                    {
                        if (type == eSymbolTypeCode)
                        {
                            // See if we can find a N_FUN entry for any code symbols.
                            // If we do find a match, and the name matches, then we
                            // can merge the two into just the function symbol to avoid
                            // duplicate entries in the symbol table
                            std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
                            range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value);
                            if (range.first != range.second)
                            {
                                bool found_it = false;
                                for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
                                {
                                    if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
                                    {
                                        m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
                                        // We just need the flags from the linker symbol, so put these flags
                                        // into the N_FUN flags to avoid duplicate symbols in the symbol table
                                        sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
                                        sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
                                        if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
                                            sym[pos->second].SetType (eSymbolTypeResolver);
                                        sym[sym_idx].Clear();
                                        found_it = true;
                                        break;
                                    }
                                }
                                if (found_it)
                                    continue;
                            }
                            else
                            {
                                if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end())
                                    type = eSymbolTypeResolver;
                            }
                        }
                        else if (type == eSymbolTypeData)
                        {
                            // See if we can find a N_STSYM entry for any data symbols.
                            // If we do find a match, and the name matches, then we
                            // can merge the two into just the Static symbol to avoid
                            // duplicate entries in the symbol table
                            std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range;
                            range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value);
                            if (range.first != range.second)
                            {
                                bool found_it = false;
                                for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos)
                                {
                                    if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled))
                                    {
                                        m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
                                        // We just need the flags from the linker symbol, so put these flags
                                        // into the N_STSYM flags to avoid duplicate symbols in the symbol table
                                        sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
                                        sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
                                        sym[sym_idx].Clear();
                                        found_it = true;
                                        break;
                                    }
                                }
                                if (found_it)
                                    continue;
                            }
                            else
                            {
                                // Combine N_GSYM stab entries with the non stab symbol
                                ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString());
                                if (pos != N_GSYM_name_to_sym_idx.end())
                                {
                                    const uint32_t GSYM_sym_idx = pos->second;
                                    m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
                                    // Copy the address, because often the N_GSYM address has an invalid address of zero
                                    // when the global is a common symbol
                                    sym[GSYM_sym_idx].GetAddress().SetSection (symbol_section);
                                    sym[GSYM_sym_idx].GetAddress().SetOffset (symbol_value);
                                    // We just need the flags from the linker symbol, so put these flags
                                    // into the N_STSYM flags to avoid duplicate symbols in the symbol table
                                    sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
                                    sym[sym_idx].Clear();
                                    continue;
                                }
                            }
                        }
                    }

                    sym[sym_idx].SetID (nlist_idx);
                    sym[sym_idx].SetType (type);
                    sym[sym_idx].GetAddress().SetSection (symbol_section);
                    sym[sym_idx].GetAddress().SetOffset (symbol_value);
                    sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);

                    if (symbol_byte_size > 0)
                        sym[sym_idx].SetByteSize(symbol_byte_size);

                    if (demangled_is_synthesized)
                        sym[sym_idx].SetDemangledNameIsSynthesized(true);

                    ++sym_idx;
                }
                else
                {
                    sym[sym_idx].Clear();
                }
            }
        }

        uint32_t synthetic_sym_id = symtab_load_command.nsyms;

        if (function_starts_count > 0)
        {
            char synthetic_function_symbol[PATH_MAX];
            uint32_t num_synthetic_function_symbols = 0;
            for (i=0; i<function_starts_count; ++i)
            {
                if (function_starts.GetEntryRef (i).data == false)
                    ++num_synthetic_function_symbols;
            }

            if (num_synthetic_function_symbols > 0)
            {
                if (num_syms < sym_idx + num_synthetic_function_symbols)
                {
                    num_syms = sym_idx + num_synthetic_function_symbols;
                    sym = symtab->Resize (num_syms);
                }
                uint32_t synthetic_function_symbol_idx = 0;
                for (i=0; i<function_starts_count; ++i)
                {
                    const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex (i);
                    if (func_start_entry->data == false)
                    {
                        addr_t symbol_file_addr = func_start_entry->addr;
                        uint32_t symbol_flags = 0;
                        if (is_arm)
                        {
                            if (symbol_file_addr & 1)
                                symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
                            symbol_file_addr &= 0xfffffffffffffffeull;
                        }
                        Address symbol_addr;
                        if (module_sp->ResolveFileAddress (symbol_file_addr, symbol_addr))
                        {
                            SectionSP symbol_section (symbol_addr.GetSection());
                            uint32_t symbol_byte_size = 0;
                            if (symbol_section)
                            {
                                const addr_t section_file_addr = symbol_section->GetFileAddress();
                                const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
                                const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
                                if (next_func_start_entry)
                                {
                                    addr_t next_symbol_file_addr = next_func_start_entry->addr;
                                    if (is_arm)
                                        next_symbol_file_addr &= 0xfffffffffffffffeull;
                                    symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr);
                                }
                                else
                                {
                                    symbol_byte_size = section_end_file_addr - symbol_file_addr;
                                }
                                snprintf (synthetic_function_symbol,
                                          sizeof(synthetic_function_symbol),
                                          "___lldb_unnamed_function%u$$%s",
                                          ++synthetic_function_symbol_idx,
                                          module_sp->GetFileSpec().GetFilename().GetCString());
                                sym[sym_idx].SetID (synthetic_sym_id++);
                                sym[sym_idx].GetMangled().SetDemangledName(ConstString(synthetic_function_symbol));
                                sym[sym_idx].SetType (eSymbolTypeCode);
                                sym[sym_idx].SetIsSynthetic (true);
                                sym[sym_idx].GetAddress() = symbol_addr;
                                if (symbol_flags)
                                    sym[sym_idx].SetFlags (symbol_flags);
                                if (symbol_byte_size)
                                    sym[sym_idx].SetByteSize (symbol_byte_size);
                                ++sym_idx;
                            }
                        }
                    }
                }
            }
        }

        // Trim our symbols down to just what we ended up with after
        // removing any symbols.
        if (sym_idx < num_syms)
        {
            num_syms = sym_idx;
            sym = symtab->Resize (num_syms);
        }

        // Now synthesize indirect symbols
        if (m_dysymtab.nindirectsyms != 0)
        {
            if (indirect_symbol_index_data.GetByteSize())
            {
                NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();

                for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx)
                {
                    if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) == S_SYMBOL_STUBS)
                    {
                        uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
                        if (symbol_stub_byte_size == 0)
                            continue;

                        const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size;

                        if (num_symbol_stubs == 0)
                            continue;

                        const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1;
                        for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx)
                        {
                            const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
                            const lldb::addr_t symbol_stub_addr = m_mach_sections[sect_idx].addr + (stub_idx * symbol_stub_byte_size);
                            lldb::offset_t symbol_stub_offset = symbol_stub_index * 4;
                            if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
                            {
                                const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
                                if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
                                    continue;

                                NListIndexToSymbolIndexMap::const_iterator index_pos = m_nlist_idx_to_sym_idx.find (stub_sym_id);
                                Symbol *stub_symbol = NULL;
                                if (index_pos != end_index_pos)
                                {
                                    // We have a remapping from the original nlist index to
                                    // a current symbol index, so just look this up by index
                                    stub_symbol = symtab->SymbolAtIndex (index_pos->second);
                                }
                                else
                                {
                                    // We need to lookup a symbol using the original nlist
                                    // symbol index since this index is coming from the
                                    // S_SYMBOL_STUBS
                                    stub_symbol = symtab->FindSymbolByID (stub_sym_id);
                                }

                                if (stub_symbol)
                                {
                                    Address so_addr(symbol_stub_addr, section_list);

                                    if (stub_symbol->GetType() == eSymbolTypeUndefined)
                                    {
                                        // Change the external symbol into a trampoline that makes sense
                                        // These symbols were N_UNDF N_EXT, and are useless to us, so we
                                        // can re-use them so we don't have to make up a synthetic symbol
                                        // for no good reason.
                                        if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end())
                                            stub_symbol->SetType (eSymbolTypeTrampoline);
                                        else
                                            stub_symbol->SetType (eSymbolTypeResolver);
                                        stub_symbol->SetExternal (false);
                                        stub_symbol->GetAddress() = so_addr;
                                        stub_symbol->SetByteSize (symbol_stub_byte_size);
                                    }
                                    else
                                    {
                                        // Make a synthetic symbol to describe the trampoline stub
                                        Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
                                        if (sym_idx >= num_syms)
                                        {
                                            sym = symtab->Resize (++num_syms);
                                            stub_symbol = NULL;  // this pointer no longer valid
                                        }
                                        sym[sym_idx].SetID (synthetic_sym_id++);
                                        sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
                                        if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end())
                                            sym[sym_idx].SetType (eSymbolTypeTrampoline);
                                        else
                                            sym[sym_idx].SetType (eSymbolTypeResolver);
                                        sym[sym_idx].SetIsSynthetic (true);
                                        sym[sym_idx].GetAddress() = so_addr;
                                        sym[sym_idx].SetByteSize (symbol_stub_byte_size);
                                        ++sym_idx;
                                    }
                                }
                                else
                                {
                                    if (log)
                                        log->Warning ("symbol stub referencing symbol table symbol %u that isn't in our minimal symbol table, fix this!!!", stub_sym_id);
                                }
                            }
                        }
                    }
                }
            }
        }

        
        if (!trie_entries.empty())
        {
            for (const auto &e : trie_entries)
            {
                if (e.entry.import_name)
                {
                    // Make a synthetic symbol to describe re-exported symbol.
                    if (sym_idx >= num_syms)
                        sym = symtab->Resize (++num_syms);
                    sym[sym_idx].SetID (synthetic_sym_id++);
                    sym[sym_idx].GetMangled() = Mangled(e.entry.name);
                    sym[sym_idx].SetType (eSymbolTypeReExported);
                    sym[sym_idx].SetIsSynthetic (true);
                    sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
                    if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize())
                    {
                        sym[sym_idx].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(e.entry.other-1));
                    }
                    ++sym_idx;
                }
            }
        }


        
//        StreamFile s(stdout, false);
//        s.Printf ("Symbol table before CalculateSymbolSizes():\n");
//        symtab->Dump(&s, NULL, eSortOrderNone);
        // Set symbol byte sizes correctly since mach-o nlist entries don't have sizes
        symtab->CalculateSymbolSizes();

//        s.Printf ("Symbol table after CalculateSymbolSizes():\n");
//        symtab->Dump(&s, NULL, eSortOrderNone);

        return symtab->GetNumSymbols();
    }
    return 0;
}


void
ObjectFileMachO::Dump (Stream *s)
{
    ModuleSP module_sp(GetModule());
    if (module_sp)
    {
        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
        s->Printf("%p: ", static_cast<void*>(this));
        s->Indent();
        if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64)
            s->PutCString("ObjectFileMachO64");
        else
            s->PutCString("ObjectFileMachO32");

        ArchSpec header_arch;
        GetArchitecture(header_arch);

        *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";

        SectionList *sections = GetSectionList();
        if (sections)
            sections->Dump(s, NULL, true, UINT32_MAX);

        if (m_symtab_ap.get())
            m_symtab_ap->Dump(s, NULL, eSortOrderNone);
    }
}

bool
ObjectFileMachO::GetUUID (const llvm::MachO::mach_header &header,
                          const lldb_private::DataExtractor &data,
                          lldb::offset_t lc_offset,
                          lldb_private::UUID& uuid)
{
    uint32_t i;
    struct uuid_command load_cmd;

    lldb::offset_t offset = lc_offset;
    for (i=0; i<header.ncmds; ++i)
    {
        const lldb::offset_t cmd_offset = offset;
        if (data.GetU32(&offset, &load_cmd, 2) == NULL)
            break;
        
        if (load_cmd.cmd == LC_UUID)
        {
            const uint8_t *uuid_bytes = data.PeekData(offset, 16);
            
            if (uuid_bytes)
            {
                // OpenCL on Mac OS X uses the same UUID for each of its object files.
                // We pretend these object files have no UUID to prevent crashing.
                
                const uint8_t opencl_uuid[] = { 0x8c, 0x8e, 0xb3, 0x9b,
                    0x3b, 0xa8,
                    0x4b, 0x16,
                    0xb6, 0xa4,
                    0x27, 0x63, 0xbb, 0x14, 0xf0, 0x0d };
                
                if (!memcmp(uuid_bytes, opencl_uuid, 16))
                    return false;
                
                uuid.SetBytes (uuid_bytes);
                return true;
            }
            return false;
        }
        offset = cmd_offset + load_cmd.cmdsize;
    }
    return false;
}


bool
ObjectFileMachO::GetArchitecture (const llvm::MachO::mach_header &header,
                                  const lldb_private::DataExtractor &data,
                                  lldb::offset_t lc_offset,
                                  ArchSpec &arch)
{
    arch.SetArchitecture (eArchTypeMachO, header.cputype, header.cpusubtype);

    if (arch.IsValid())
    {
        llvm::Triple &triple = arch.GetTriple();
        if (header.filetype == MH_PRELOAD)
        {
            // Set OS to "unknown" - this is a standalone binary with no dyld et al
            triple.setOS(llvm::Triple::UnknownOS);
            return true;
        }
        else
        {
            struct load_command load_cmd;
            
            lldb::offset_t offset = lc_offset;
            for (uint32_t i=0; i<header.ncmds; ++i)
            {
                const lldb::offset_t cmd_offset = offset;
                if (data.GetU32(&offset, &load_cmd, 2) == NULL)
                    break;
                
                switch (load_cmd.cmd)
                {
                    case LC_VERSION_MIN_IPHONEOS:
                        triple.setOS (llvm::Triple::IOS);
                        return true;
                        
                    case LC_VERSION_MIN_MACOSX:
                        triple.setOS (llvm::Triple::MacOSX);
                        return true;
                        
                    default:
                        break;
                }

                offset = cmd_offset + load_cmd.cmdsize;
            }
            
            // Only set the OS to iOS for ARM, we don't want to set it for x86 and x86_64.
            // We do this because we now have MacOSX or iOS as the OS value for x86 and
            // x86_64 for normal desktop (MacOSX) and simulator (iOS) binaries. And if
            // we compare a "x86_64-apple-ios" to a "x86_64-apple-" triple, it will say
            // it is compatible (because the OS is unspecified in the second one and will
            // match anything in the first
            if (header.cputype == CPU_TYPE_ARM || header.cputype == CPU_TYPE_ARM64)
                triple.setOS (llvm::Triple::IOS);
        }
    }
    return arch.IsValid();
}

bool
ObjectFileMachO::GetUUID (lldb_private::UUID* uuid)
{
    ModuleSP module_sp(GetModule());
    if (module_sp)
    {
        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
        lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
        return GetUUID (m_header, m_data, offset, *uuid);
    }
    return false;
}


uint32_t
ObjectFileMachO::GetDependentModules (FileSpecList& files)
{
    uint32_t count = 0;
    ModuleSP module_sp(GetModule());
    if (module_sp)
    {
        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
        struct load_command load_cmd;
        lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
        const bool resolve_path = false; // Don't resolve the dependent file paths since they may not reside on this system
        uint32_t i;
        for (i=0; i<m_header.ncmds; ++i)
        {
            const uint32_t cmd_offset = offset;
            if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
                break;

            switch (load_cmd.cmd)
            {
            case LC_LOAD_DYLIB:
            case LC_LOAD_WEAK_DYLIB:
            case LC_REEXPORT_DYLIB:
            case LC_LOAD_DYLINKER:
            case LC_LOADFVMLIB:
            case LC_LOAD_UPWARD_DYLIB:
                {
                    uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
                    const char *path = m_data.PeekCStr(name_offset);
                    // Skip any path that starts with '@' since these are usually:
                    // @executable_path/.../file
                    // @rpath/.../file
                    if (path && path[0] != '@')
                    {
                        FileSpec file_spec(path, resolve_path);
                        if (files.AppendIfUnique(file_spec))
                            count++;
                    }
                }
                break;

            default:
                break;
            }
            offset = cmd_offset + load_cmd.cmdsize;
        }
    }
    return count;
}

lldb_private::Address
ObjectFileMachO::GetEntryPointAddress ()
{
    // If the object file is not an executable it can't hold the entry point.  m_entry_point_address
    // is initialized to an invalid address, so we can just return that.
    // If m_entry_point_address is valid it means we've found it already, so return the cached value.

    if (!IsExecutable() || m_entry_point_address.IsValid())
        return m_entry_point_address;

    // Otherwise, look for the UnixThread or Thread command.  The data for the Thread command is given in
    // /usr/include/mach-o.h, but it is basically:
    //
    //  uint32_t flavor  - this is the flavor argument you would pass to thread_get_state
    //  uint32_t count   - this is the count of longs in the thread state data
    //  struct XXX_thread_state state - this is the structure from <machine/thread_status.h> corresponding to the flavor.
    //  <repeat this trio>
    //
    // So we just keep reading the various register flavors till we find the GPR one, then read the PC out of there.
    // FIXME: We will need to have a "RegisterContext data provider" class at some point that can get all the registers
    // out of data in this form & attach them to a given thread.  That should underlie the MacOS X User process plugin,
    // and we'll also need it for the MacOS X Core File process plugin.  When we have that we can also use it here.
    //
    // For now we hard-code the offsets and flavors we need:
    //
    //

    ModuleSP module_sp(GetModule());
    if (module_sp)
    {
        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
        struct load_command load_cmd;
        lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
        uint32_t i;
        lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
        bool done = false;

        for (i=0; i<m_header.ncmds; ++i)
        {
            const lldb::offset_t cmd_offset = offset;
            if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
                break;

            switch (load_cmd.cmd)
            {
            case LC_UNIXTHREAD:
            case LC_THREAD:
                {
                    while (offset < cmd_offset + load_cmd.cmdsize)
                    {
                        uint32_t flavor = m_data.GetU32(&offset);
                        uint32_t count = m_data.GetU32(&offset);
                        if (count == 0)
                        {
                            // We've gotten off somehow, log and exit;
                            return m_entry_point_address;
                        }

                        switch (m_header.cputype)
                        {
                        case llvm::MachO::CPU_TYPE_ARM:
                           if (flavor == 1) // ARM_THREAD_STATE from mach/arm/thread_status.h
                           {
                               offset += 60;  // This is the offset of pc in the GPR thread state data structure.
                               start_address = m_data.GetU32(&offset);
                               done = true;
                            }
                        break;
                        case llvm::MachO::CPU_TYPE_ARM64:
                           if (flavor == 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h
                           {
                               offset += 256;  // This is the offset of pc in the GPR thread state data structure.
                               start_address = m_data.GetU64(&offset);
                               done = true;
                            }
                        break;
                        case llvm::MachO::CPU_TYPE_I386:
                           if (flavor == 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
                           {
                               offset += 40;  // This is the offset of eip in the GPR thread state data structure.
                               start_address = m_data.GetU32(&offset);
                               done = true;
                            }
                        break;
                        case llvm::MachO::CPU_TYPE_X86_64:
                           if (flavor == 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
                           {
                               offset += 16 * 8;  // This is the offset of rip in the GPR thread state data structure.
                               start_address = m_data.GetU64(&offset);
                               done = true;
                            }
                        break;
                        default:
                            return m_entry_point_address;
                        }
                        // Haven't found the GPR flavor yet, skip over the data for this flavor:
                        if (done)
                            break;
                        offset += count * 4;
                    }
                }
                break;
            case LC_MAIN:
                {
                    ConstString text_segment_name ("__TEXT");
                    uint64_t entryoffset = m_data.GetU64(&offset);
                    SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
                    if (text_segment_sp)
                    {
                        done = true;
                        start_address = text_segment_sp->GetFileAddress() + entryoffset;
                    }
                }

            default:
                break;
            }
            if (done)
                break;

            // Go to the next load command:
            offset = cmd_offset + load_cmd.cmdsize;
        }

        if (start_address != LLDB_INVALID_ADDRESS)
        {
            // We got the start address from the load commands, so now resolve that address in the sections
            // of this ObjectFile:
            if (!m_entry_point_address.ResolveAddressUsingFileSections (start_address, GetSectionList()))
            {
                m_entry_point_address.Clear();
            }
        }
        else
        {
            // We couldn't read the UnixThread load command - maybe it wasn't there.  As a fallback look for the
            // "start" symbol in the main executable.

            ModuleSP module_sp (GetModule());

            if (module_sp)
            {
                SymbolContextList contexts;
                SymbolContext context;
                if (module_sp->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts))
                {
                    if (contexts.GetContextAtIndex(0, context))
                        m_entry_point_address = context.symbol->GetAddress();
                }
            }
        }
    }

    return m_entry_point_address;

}

lldb_private::Address
ObjectFileMachO::GetHeaderAddress ()
{
    lldb_private::Address header_addr;
    SectionList *section_list = GetSectionList();
    if (section_list)
    {
        SectionSP text_segment_sp (section_list->FindSectionByName (GetSegmentNameTEXT()));
        if (text_segment_sp)
        {
            header_addr.SetSection (text_segment_sp);
            header_addr.SetOffset (0);
        }
    }
    return header_addr;
}

uint32_t
ObjectFileMachO::GetNumThreadContexts ()
{
    ModuleSP module_sp(GetModule());
    if (module_sp)
    {
        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
        if (!m_thread_context_offsets_valid)
        {
            m_thread_context_offsets_valid = true;
            lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
            FileRangeArray::Entry file_range;
            thread_command thread_cmd;
            for (uint32_t i=0; i<m_header.ncmds; ++i)
            {
                const uint32_t cmd_offset = offset;
                if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL)
                    break;

                if (thread_cmd.cmd == LC_THREAD)
                {
                    file_range.SetRangeBase (offset);
                    file_range.SetByteSize (thread_cmd.cmdsize - 8);
                    m_thread_context_offsets.Append (file_range);
                }
                offset = cmd_offset + thread_cmd.cmdsize;
            }
        }
    }
    return m_thread_context_offsets.GetSize();
}

lldb::RegisterContextSP
ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread)
{
    lldb::RegisterContextSP reg_ctx_sp;

    ModuleSP module_sp(GetModule());
    if (module_sp)
    {
        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
        if (!m_thread_context_offsets_valid)
            GetNumThreadContexts ();

        const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx);
        if (thread_context_file_range)
        {

            DataExtractor data (m_data,
                                thread_context_file_range->GetRangeBase(),
                                thread_context_file_range->GetByteSize());

            switch (m_header.cputype)
            {
                case llvm::MachO::CPU_TYPE_ARM64:
                    reg_ctx_sp.reset (new RegisterContextDarwin_arm64_Mach (thread, data));
                    break;
                    
                case llvm::MachO::CPU_TYPE_ARM:
                    reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data));
                    break;

                case llvm::MachO::CPU_TYPE_I386:
                    reg_ctx_sp.reset (new RegisterContextDarwin_i386_Mach (thread, data));
                    break;

                case llvm::MachO::CPU_TYPE_X86_64:
                    reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data));
                    break;
            }
        }
    }
    return reg_ctx_sp;
}


ObjectFile::Type
ObjectFileMachO::CalculateType()
{
    switch (m_header.filetype)
    {
        case MH_OBJECT:                                         // 0x1u
            if (GetAddressByteSize () == 4)
            {
                // 32 bit kexts are just object files, but they do have a valid
                // UUID load command.
                UUID uuid;
                if (GetUUID(&uuid))
                {
                    // this checking for the UUID load command is not enough
                    // we could eventually look for the symbol named
                    // "OSKextGetCurrentIdentifier" as this is required of kexts
                    if (m_strata == eStrataInvalid)
                        m_strata = eStrataKernel;
                    return eTypeSharedLibrary;
                }
            }
            return eTypeObjectFile;

        case MH_EXECUTE:            return eTypeExecutable;     // 0x2u
        case MH_FVMLIB:             return eTypeSharedLibrary;  // 0x3u
        case MH_CORE:               return eTypeCoreFile;       // 0x4u
        case MH_PRELOAD:            return eTypeSharedLibrary;  // 0x5u
        case MH_DYLIB:              return eTypeSharedLibrary;  // 0x6u
        case MH_DYLINKER:           return eTypeDynamicLinker;  // 0x7u
        case MH_BUNDLE:             return eTypeSharedLibrary;  // 0x8u
        case MH_DYLIB_STUB:         return eTypeStubLibrary;    // 0x9u
        case MH_DSYM:               return eTypeDebugInfo;      // 0xAu
        case MH_KEXT_BUNDLE:        return eTypeSharedLibrary;  // 0xBu
        default:
            break;
    }
    return eTypeUnknown;
}

ObjectFile::Strata
ObjectFileMachO::CalculateStrata()
{
    switch (m_header.filetype)
    {
        case MH_OBJECT:                                  // 0x1u
            {
                // 32 bit kexts are just object files, but they do have a valid
                // UUID load command.
                UUID uuid;
                if (GetUUID(&uuid))
                {
                    // this checking for the UUID load command is not enough
                    // we could eventually look for the symbol named
                    // "OSKextGetCurrentIdentifier" as this is required of kexts
                    if (m_type == eTypeInvalid)
                        m_type = eTypeSharedLibrary;

                    return eStrataKernel;
                }
            }
            return eStrataUnknown;

        case MH_EXECUTE:                                 // 0x2u
            // Check for the MH_DYLDLINK bit in the flags
            if (m_header.flags & MH_DYLDLINK)
            {
                return eStrataUser;
            }
            else
            {
                SectionList *section_list = GetSectionList();
                if (section_list)
                {
                    static ConstString g_kld_section_name ("__KLD");
                    if (section_list->FindSectionByName(g_kld_section_name))
                        return eStrataKernel;
                }
            }
            return eStrataRawImage;

        case MH_FVMLIB:      return eStrataUser;         // 0x3u
        case MH_CORE:        return eStrataUnknown;      // 0x4u
        case MH_PRELOAD:     return eStrataRawImage;     // 0x5u
        case MH_DYLIB:       return eStrataUser;         // 0x6u
        case MH_DYLINKER:    return eStrataUser;         // 0x7u
        case MH_BUNDLE:      return eStrataUser;         // 0x8u
        case MH_DYLIB_STUB:  return eStrataUser;         // 0x9u
        case MH_DSYM:        return eStrataUnknown;      // 0xAu
        case MH_KEXT_BUNDLE: return eStrataKernel;       // 0xBu
        default:
            break;
    }
    return eStrataUnknown;
}


uint32_t
ObjectFileMachO::GetVersion (uint32_t *versions, uint32_t num_versions)
{
    ModuleSP module_sp(GetModule());
    if (module_sp)
    {
        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
        struct dylib_command load_cmd;
        lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
        uint32_t version_cmd = 0;
        uint64_t version = 0;
        uint32_t i;
        for (i=0; i<m_header.ncmds; ++i)
        {
            const lldb::offset_t cmd_offset = offset;
            if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
                break;

            if (load_cmd.cmd == LC_ID_DYLIB)
            {
                if (version_cmd == 0)
                {
                    version_cmd = load_cmd.cmd;
                    if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL)
                        break;
                    version = load_cmd.dylib.current_version;
                }
                break; // Break for now unless there is another more complete version
                       // number load command in the future.
            }
            offset = cmd_offset + load_cmd.cmdsize;
        }

        if (version_cmd == LC_ID_DYLIB)
        {
            if (versions != NULL && num_versions > 0)
            {
                if (num_versions > 0)
                    versions[0] = (version & 0xFFFF0000ull) >> 16;
                if (num_versions > 1)
                    versions[1] = (version & 0x0000FF00ull) >> 8;
                if (num_versions > 2)
                    versions[2] = (version & 0x000000FFull);
                // Fill in an remaining version numbers with invalid values
                for (i=3; i<num_versions; ++i)
                    versions[i] = UINT32_MAX;
            }
            // The LC_ID_DYLIB load command has a version with 3 version numbers
            // in it, so always return 3
            return 3;
        }
    }
    return false;
}

bool
ObjectFileMachO::GetArchitecture (ArchSpec &arch)
{
    ModuleSP module_sp(GetModule());
    if (module_sp)
    {
        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
        return GetArchitecture (m_header, m_data, MachHeaderSizeFromMagic(m_header.magic), arch);
    }
    return false;
}


UUID
ObjectFileMachO::GetProcessSharedCacheUUID (Process *process)
{
    UUID uuid;
    if (process)
    {
        addr_t all_image_infos = process->GetImageInfoAddress();

        // The address returned by GetImageInfoAddress may be the address of dyld (don't want)
        // or it may be the address of the dyld_all_image_infos structure (want).  The first four
        // bytes will be either the version field (all_image_infos) or a Mach-O file magic constant.
        // Version 13 and higher of dyld_all_image_infos is required to get the sharedCacheUUID field.

        Error err;
        uint32_t version_or_magic = process->ReadUnsignedIntegerFromMemory (all_image_infos, 4, -1, err);
        if (version_or_magic != static_cast<uint32_t>(-1)
            && version_or_magic != MH_MAGIC
            && version_or_magic != MH_CIGAM
            && version_or_magic != MH_MAGIC_64
            && version_or_magic != MH_CIGAM_64
            && version_or_magic >= 13)
        {
            addr_t sharedCacheUUID_address = LLDB_INVALID_ADDRESS;
            int wordsize = process->GetAddressByteSize();
            if (wordsize == 8)
            {
                sharedCacheUUID_address = all_image_infos + 160;  // sharedCacheUUID <mach-o/dyld_images.h>
            }
            if (wordsize == 4)
            {
                sharedCacheUUID_address = all_image_infos + 84;   // sharedCacheUUID <mach-o/dyld_images.h>
            }
            if (sharedCacheUUID_address != LLDB_INVALID_ADDRESS)
            {
                uuid_t shared_cache_uuid;
                if (process->ReadMemory (sharedCacheUUID_address, shared_cache_uuid, sizeof (uuid_t), err) == sizeof (uuid_t))
                {
                    uuid.SetBytes (shared_cache_uuid);
                }
            }
        }
    }
    return uuid;
}

UUID
ObjectFileMachO::GetLLDBSharedCacheUUID ()
{
    UUID uuid;
#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__))
    uint8_t *(*dyld_get_all_image_infos)(void);
    dyld_get_all_image_infos = (uint8_t*(*)()) dlsym (RTLD_DEFAULT, "_dyld_get_all_image_infos");
    if (dyld_get_all_image_infos)
    {
        uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos();
        if (dyld_all_image_infos_address)
        {
            uint32_t *version = (uint32_t*) dyld_all_image_infos_address;              // version <mach-o/dyld_images.h>
            if (*version >= 13)
            {
                uuid_t *sharedCacheUUID_address = 0;
                int wordsize = sizeof (uint8_t *);
                if (wordsize == 8)
                {
                    sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 160); // sharedCacheUUID <mach-o/dyld_images.h>
                }
                else
                {
                    sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 84);  // sharedCacheUUID <mach-o/dyld_images.h>
                }
                uuid.SetBytes (sharedCacheUUID_address);
            }
        }
    }
#endif
    return uuid;
}

uint32_t
ObjectFileMachO::GetMinimumOSVersion (uint32_t *versions, uint32_t num_versions)
{
    if (m_min_os_versions.empty())
    {
        lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
        bool success = false;
        for (uint32_t i=0; success == false && i < m_header.ncmds; ++i)
        {
            const lldb::offset_t load_cmd_offset = offset;
            
            version_min_command lc;
            if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
                break;
            if (lc.cmd == LC_VERSION_MIN_MACOSX || lc.cmd == LC_VERSION_MIN_IPHONEOS)
            {
                if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2))
                {
                    const uint32_t xxxx = lc.version >> 16;
                    const uint32_t yy = (lc.version >> 8) & 0xffu;
                    const uint32_t zz = lc.version  & 0xffu;
                    if (xxxx)
                    {
                        m_min_os_versions.push_back(xxxx);
                        if (yy)
                        {
                            m_min_os_versions.push_back(yy);
                            if (zz)
                                m_min_os_versions.push_back(zz);
                        }
                    }
                    success = true;
                }
            }
            offset = load_cmd_offset + lc.cmdsize;
        }
        
        if (success == false)
        {
            // Push an invalid value so we don't keep trying to
            m_min_os_versions.push_back(UINT32_MAX);
        }
    }
    
    if (m_min_os_versions.size() > 1 || m_min_os_versions[0] != UINT32_MAX)
    {
        if (versions != NULL && num_versions > 0)
        {
            for (size_t i=0; i<num_versions; ++i)
            {
                if (i < m_min_os_versions.size())
                    versions[i] = m_min_os_versions[i];
                else
                    versions[i] = 0;
            }
        }
        return m_min_os_versions.size();
    }
    // Call the superclasses version that will empty out the data
    return ObjectFile::GetMinimumOSVersion (versions, num_versions);
}

uint32_t
ObjectFileMachO::GetSDKVersion(uint32_t *versions, uint32_t num_versions)
{
    if (m_sdk_versions.empty())
    {
        lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
        bool success = false;
        for (uint32_t i=0; success == false && i < m_header.ncmds; ++i)
        {
            const lldb::offset_t load_cmd_offset = offset;
            
            version_min_command lc;
            if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
                break;
            if (lc.cmd == LC_VERSION_MIN_MACOSX || lc.cmd == LC_VERSION_MIN_IPHONEOS)
            {
                if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2))
                {
                    const uint32_t xxxx = lc.sdk >> 16;
                    const uint32_t yy = (lc.sdk >> 8) & 0xffu;
                    const uint32_t zz = lc.sdk & 0xffu;
                    if (xxxx)
                    {
                        m_sdk_versions.push_back(xxxx);
                        if (yy)
                        {
                            m_sdk_versions.push_back(yy);
                            if (zz)
                                m_sdk_versions.push_back(zz);
                        }
                    }
                    success = true;
                }
            }
            offset = load_cmd_offset + lc.cmdsize;
        }
        
        if (success == false)
        {
            // Push an invalid value so we don't keep trying to
            m_sdk_versions.push_back(UINT32_MAX);
        }
    }
    
    if (m_sdk_versions.size() > 1 || m_sdk_versions[0] != UINT32_MAX)
    {
        if (versions != NULL && num_versions > 0)
        {
            for (size_t i=0; i<num_versions; ++i)
            {
                if (i < m_sdk_versions.size())
                    versions[i] = m_sdk_versions[i];
                else
                    versions[i] = 0;
            }
        }
        return m_sdk_versions.size();
    }
    // Call the superclasses version that will empty out the data
    return ObjectFile::GetSDKVersion (versions, num_versions);
}


//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
lldb_private::ConstString
ObjectFileMachO::GetPluginName()
{
    return GetPluginNameStatic();
}

uint32_t
ObjectFileMachO::GetPluginVersion()
{
    return 1;
}


bool
ObjectFileMachO::SetLoadAddress (Target &target,
                                 lldb::addr_t value,
                                 bool value_is_offset)
{
    ModuleSP module_sp = GetModule();
    if (module_sp)
    {
        size_t num_loaded_sections = 0;
        SectionList *section_list = GetSectionList ();
        if (section_list)
        {
            lldb::addr_t mach_base_file_addr = LLDB_INVALID_ADDRESS;
            const size_t num_sections = section_list->GetSize();

            const bool is_memory_image = (bool)m_process_wp.lock();
            const Strata strata = GetStrata();
            static ConstString g_linkedit_segname ("__LINKEDIT");
            if (value_is_offset)
            {
                // "value" is an offset to apply to each top level segment
                for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
                {
                    // Iterate through the object file sections to find all
                    // of the sections that size on disk (to avoid __PAGEZERO)
                    // and load them
                    SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
                    if (section_sp &&
                        section_sp->GetFileSize() > 0 &&
                        section_sp->IsThreadSpecific() == false &&
                        module_sp.get() == section_sp->GetModule().get())
                    {
                        // Ignore __LINKEDIT and __DWARF segments
                        if (section_sp->GetName() == g_linkedit_segname)
                        {
                            // Only map __LINKEDIT if we have an in memory image and this isn't
                            // a kernel binary like a kext or mach_kernel.
                            if (is_memory_image == false || strata == eStrataKernel)
                                continue;
                        }
                        if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + value))
                            ++num_loaded_sections;
                    }
                }
            }
            else
            {
                // "value" is the new base address of the mach_header, adjust each
                // section accordingly

                // First find the address of the mach header which is the first non-zero
                // file sized section whose file offset is zero as this will be subtracted
                // from each other valid section's vmaddr and then get "base_addr" added to
                // it when loading the module in the target
                for (size_t sect_idx = 0;
                     sect_idx < num_sections && mach_base_file_addr == LLDB_INVALID_ADDRESS;
                     ++sect_idx)
                {
                    // Iterate through the object file sections to find all
                    // of the sections that size on disk (to avoid __PAGEZERO)
                    // and load them
                    Section *section = section_list->GetSectionAtIndex (sect_idx).get();
                    if (section &&
                        section->GetFileSize() > 0 &&
                        section->GetFileOffset() == 0 &&
                        section->IsThreadSpecific() == false &&
                        module_sp.get() == section->GetModule().get())
                    {
                        // Ignore __LINKEDIT and __DWARF segments
                        if (section->GetName() == g_linkedit_segname)
                        {
                            // Only map __LINKEDIT if we have an in memory image and this isn't
                            // a kernel binary like a kext or mach_kernel.
                            if (is_memory_image == false || strata == eStrataKernel)
                                continue;
                        }
                        mach_base_file_addr = section->GetFileAddress();
                    }
                }

                if (mach_base_file_addr != LLDB_INVALID_ADDRESS)
                {
                    for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
                    {
                        // Iterate through the object file sections to find all
                        // of the sections that size on disk (to avoid __PAGEZERO)
                        // and load them
                        SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
                        if (section_sp &&
                            section_sp->GetFileSize() > 0 &&
                            section_sp->IsThreadSpecific() == false &&
                            module_sp.get() == section_sp->GetModule().get())
                        {
                            // Ignore __LINKEDIT and __DWARF segments
                            if (section_sp->GetName() == g_linkedit_segname)
                            {
                                // Only map __LINKEDIT if we have an in memory image and this isn't
                                // a kernel binary like a kext or mach_kernel.
                                if (is_memory_image == false || strata == eStrataKernel)
                                    continue;
                            }
                            if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() - mach_base_file_addr + value))
                                ++num_loaded_sections;
                        }
                    }
                }
            }
        }
        return num_loaded_sections > 0;
    }
    return false;
}

bool
ObjectFileMachO::SaveCore (const lldb::ProcessSP &process_sp,
                           const FileSpec &outfile,
                           Error &error)
{
    if (process_sp)
    {
        Target &target = process_sp->GetTarget();
        const ArchSpec target_arch = target.GetArchitecture();
        const llvm::Triple &target_triple = target_arch.GetTriple();
        if (target_triple.getVendor() == llvm::Triple::Apple &&
            (target_triple.getOS() == llvm::Triple::MacOSX ||
             target_triple.getOS() == llvm::Triple::IOS))
        {
            bool make_core = false;
            switch (target_arch.GetMachine())
            {
                  // arm64 core file writing is having some problem with writing  down the 
                  // dyld shared images info struct and/or the main executable binary. May
                  // turn out to be a debugserver problem, not sure yet.
//                case llvm::Triple::aarch64:

                case llvm::Triple::arm:
                case llvm::Triple::x86:
                case llvm::Triple::x86_64:
                    make_core = true;
                    break;
                default:
                    error.SetErrorStringWithFormat ("unsupported core architecture: %s", target_triple.str().c_str());
                    break;
            }
            
            if (make_core)
            {
                std::vector<segment_command_64> segment_load_commands;
//                uint32_t range_info_idx = 0;
                MemoryRegionInfo range_info;
                Error range_error = process_sp->GetMemoryRegionInfo(0, range_info);
                const uint32_t addr_byte_size = target_arch.GetAddressByteSize();
                const ByteOrder byte_order = target_arch.GetByteOrder();
                if (range_error.Success())
                {
                    while (range_info.GetRange().GetRangeBase() != LLDB_INVALID_ADDRESS)
                    {
                        const addr_t addr = range_info.GetRange().GetRangeBase();
                        const addr_t size = range_info.GetRange().GetByteSize();

                        if (size == 0)
                            break;

                        // Calculate correct protections
                        uint32_t prot = 0;
                        if (range_info.GetReadable() == MemoryRegionInfo::eYes)
                            prot |= VM_PROT_READ;
                        if (range_info.GetWritable() == MemoryRegionInfo::eYes)
                            prot |= VM_PROT_WRITE;
                        if (range_info.GetExecutable() == MemoryRegionInfo::eYes)
                            prot |= VM_PROT_EXECUTE;

//                        printf ("[%3u] [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") %c%c%c\n",
//                                range_info_idx,
//                                addr,
//                                size,
//                                (prot & VM_PROT_READ   ) ? 'r' : '-',
//                                (prot & VM_PROT_WRITE  ) ? 'w' : '-',
//                                (prot & VM_PROT_EXECUTE) ? 'x' : '-');

                        if (prot != 0)
                        {
                            uint32_t cmd_type = LC_SEGMENT_64;
                            uint32_t segment_size = sizeof (segment_command_64);
                            if (addr_byte_size == 4)
                            {
                                cmd_type = LC_SEGMENT;
                                segment_size = sizeof (segment_command);
                            }
                            segment_command_64 segment = {
                                cmd_type,           // uint32_t cmd;
                                segment_size,       // uint32_t cmdsize;
                                {0},                // char segname[16];
                                addr,               // uint64_t vmaddr;    // uint32_t for 32-bit Mach-O
                                size,               // uint64_t vmsize;    // uint32_t for 32-bit Mach-O
                                0,                  // uint64_t fileoff;   // uint32_t for 32-bit Mach-O
                                size,               // uint64_t filesize;  // uint32_t for 32-bit Mach-O
                                prot,               // uint32_t maxprot;
                                prot,               // uint32_t initprot;
                                0,                  // uint32_t nsects;
                                0 };                // uint32_t flags;
                            segment_load_commands.push_back(segment);
                        }
                        else
                        {
                            // No protections and a size of 1 used to be returned from old
                            // debugservers when we asked about a region that was past the
                            // last memory region and it indicates the end...
                            if (size == 1)
                                break;
                        }
                        
                        range_error = process_sp->GetMemoryRegionInfo(range_info.GetRange().GetRangeEnd(), range_info);
                        if (range_error.Fail())
                            break;
                    }
                    
                    StreamString buffer (Stream::eBinary,
                                         addr_byte_size,
                                         byte_order);

                    mach_header_64 mach_header;
                    if (addr_byte_size == 8)
                    {
                        mach_header.magic = MH_MAGIC_64;
                    }
                    else
                    {
                        mach_header.magic = MH_MAGIC;
                    }
                    mach_header.cputype = target_arch.GetMachOCPUType();
                    mach_header.cpusubtype = target_arch.GetMachOCPUSubType();
                    mach_header.filetype = MH_CORE;
                    mach_header.ncmds = segment_load_commands.size();
                    mach_header.flags = 0;
                    mach_header.reserved = 0;
                    ThreadList &thread_list = process_sp->GetThreadList();
                    const uint32_t num_threads = thread_list.GetSize();

                    // Make an array of LC_THREAD data items. Each one contains
                    // the contents of the LC_THREAD load command. The data doesn't
                    // contain the load command + load command size, we will
                    // add the load command and load command size as we emit the data.
                    std::vector<StreamString> LC_THREAD_datas(num_threads);
                    for (auto &LC_THREAD_data : LC_THREAD_datas)
                    {
                        LC_THREAD_data.GetFlags().Set(Stream::eBinary);
                        LC_THREAD_data.SetAddressByteSize(addr_byte_size);
                        LC_THREAD_data.SetByteOrder(byte_order);
                    }
                    for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx)
                    {
                        ThreadSP thread_sp (thread_list.GetThreadAtIndex(thread_idx));
                        if (thread_sp)
                        {
                            switch (mach_header.cputype)
                            {
                                case llvm::MachO::CPU_TYPE_ARM64:
                                    RegisterContextDarwin_arm64_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
                                    break;

                                case llvm::MachO::CPU_TYPE_ARM:
                                    RegisterContextDarwin_arm_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
                                    break;

                                case llvm::MachO::CPU_TYPE_I386:
                                    RegisterContextDarwin_i386_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
                                    break;
                                    
                                case llvm::MachO::CPU_TYPE_X86_64:
                                    RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]);
                                    break;
                            }
                            
                        }
                    }
                    
                    // The size of the load command is the size of the segments...
                    if (addr_byte_size == 8)
                    {
                        mach_header.sizeofcmds = segment_load_commands.size() * sizeof (struct segment_command_64);
                    }
                    else
                    {
                        mach_header.sizeofcmds = segment_load_commands.size() * sizeof (struct segment_command);
                    }
                    
                    // and the size of all LC_THREAD load command
                    for (const auto &LC_THREAD_data : LC_THREAD_datas)
                    {
                        ++mach_header.ncmds;
                        mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
                    }

                    printf ("mach_header: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n",
                            mach_header.magic,
                            mach_header.cputype,
                            mach_header.cpusubtype,
                            mach_header.filetype,
                            mach_header.ncmds,
                            mach_header.sizeofcmds,
                            mach_header.flags,
                            mach_header.reserved);

                    // Write the mach header
                    buffer.PutHex32(mach_header.magic);
                    buffer.PutHex32(mach_header.cputype);
                    buffer.PutHex32(mach_header.cpusubtype);
                    buffer.PutHex32(mach_header.filetype);
                    buffer.PutHex32(mach_header.ncmds);
                    buffer.PutHex32(mach_header.sizeofcmds);
                    buffer.PutHex32(mach_header.flags);
                    if (addr_byte_size == 8)
                    {
                        buffer.PutHex32(mach_header.reserved);
                    }
                    
                    // Skip the mach header and all load commands and align to the next
                    // 0x1000 byte boundary
                    addr_t file_offset = buffer.GetSize() + mach_header.sizeofcmds;
                    if (file_offset & 0x00000fff)
                    {
                        file_offset += 0x00001000ull;
                        file_offset &= (~0x00001000ull + 1);
                    }
                    
                    for (auto &segment : segment_load_commands)
                    {
                        segment.fileoff = file_offset;
                        file_offset += segment.filesize;
                    }
                    
                    // Write out all of the LC_THREAD load commands
                    for (const auto &LC_THREAD_data : LC_THREAD_datas)
                    {
                        const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize();
                        buffer.PutHex32(LC_THREAD);
                        buffer.PutHex32(8 + LC_THREAD_data_size); // cmd + cmdsize + data
                        buffer.Write(LC_THREAD_data.GetData(), LC_THREAD_data_size);
                    }

                    // Write out all of the segment load commands
                    for (const auto &segment : segment_load_commands)
                    {
                        printf ("0x%8.8x 0x%8.8x [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") [0x%16.16" PRIx64 " 0x%16.16" PRIx64 ") 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x]\n",
                                segment.cmd,
                                segment.cmdsize,
                                segment.vmaddr,
                                segment.vmaddr + segment.vmsize,
                                segment.fileoff,
                                segment.filesize,
                                segment.maxprot,
                                segment.initprot,
                                segment.nsects,
                                segment.flags);
                        
                        buffer.PutHex32(segment.cmd);
                        buffer.PutHex32(segment.cmdsize);
                        buffer.PutRawBytes(segment.segname, sizeof(segment.segname));
                        if (addr_byte_size == 8)
                        {
                            buffer.PutHex64(segment.vmaddr);
                            buffer.PutHex64(segment.vmsize);
                            buffer.PutHex64(segment.fileoff);
                            buffer.PutHex64(segment.filesize);
                        }
                        else
                        {
                            buffer.PutHex32(static_cast<uint32_t>(segment.vmaddr));
                            buffer.PutHex32(static_cast<uint32_t>(segment.vmsize));
                            buffer.PutHex32(static_cast<uint32_t>(segment.fileoff));
                            buffer.PutHex32(static_cast<uint32_t>(segment.filesize));
                        }
                        buffer.PutHex32(segment.maxprot);
                        buffer.PutHex32(segment.initprot);
                        buffer.PutHex32(segment.nsects);
                        buffer.PutHex32(segment.flags);
                    }
                    
                    File core_file;
                    std::string core_file_path(outfile.GetPath());
                    error = core_file.Open(core_file_path.c_str(),
                                           File::eOpenOptionWrite    |
                                           File::eOpenOptionTruncate |
                                           File::eOpenOptionCanCreate);
                    if (error.Success())
                    {
                        // Read 1 page at a time
                        uint8_t bytes[0x1000];
                        // Write the mach header and load commands out to the core file
                        size_t bytes_written = buffer.GetString().size();
                        error = core_file.Write(buffer.GetString().data(), bytes_written);
                        if (error.Success())
                        {
                            // Now write the file data for all memory segments in the process
                            for (const auto &segment : segment_load_commands)
                            {
                                if (core_file.SeekFromStart(segment.fileoff) == -1)
                                {
                                    error.SetErrorStringWithFormat("unable to seek to offset 0x%" PRIx64 " in '%s'", segment.fileoff, core_file_path.c_str());
                                    break;
                                }
                                
                                printf ("Saving %" PRId64 " bytes of data for memory region at 0x%" PRIx64 "\n", segment.vmsize, segment.vmaddr);
                                addr_t bytes_left = segment.vmsize;
                                addr_t addr = segment.vmaddr;
                                Error memory_read_error;
                                while (bytes_left > 0 && error.Success())
                                {
                                    const size_t bytes_to_read = bytes_left > sizeof(bytes) ? sizeof(bytes) : bytes_left;
                                    const size_t bytes_read = process_sp->ReadMemory(addr, bytes, bytes_to_read, memory_read_error);
                                    if (bytes_read == bytes_to_read)
                                    {
                                        size_t bytes_written = bytes_read;
                                        error = core_file.Write(bytes, bytes_written);
                                        bytes_left -= bytes_read;
                                        addr += bytes_read;
                                    }
                                    else
                                    {
                                        // Some pages within regions are not readable, those
                                        // should be zero filled
                                        memset (bytes, 0, bytes_to_read);
                                        size_t bytes_written = bytes_to_read;
                                        error = core_file.Write(bytes, bytes_written);
                                        bytes_left -= bytes_to_read;
                                        addr += bytes_to_read;
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    error.SetErrorString("process doesn't support getting memory region info");
                }
            }
            return true; // This is the right plug to handle saving core files for this process
        }
    }
    return false;
}

