//===-- 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/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/MemoryRegionInfo.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->MemoryMapFileContentsIfLocal(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->MemoryMapFileContentsIfLocal(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);
                spec.SetObjectSize(length);

                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->GetAddressRef().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;

            // LC_ENCRYPTION_INFO and LC_ENCRYPTION_INFO_64 have the same sizes for
            // the 3 fields we care about, so treat them the same.
            if (encryption_cmd.cmd == LC_ENCRYPTION_INFO || encryption_cmd.cmd == LC_ENCRYPTION_INFO_64)
            {
                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));
    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_$_");

    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)
            {
                addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target);
                if (linkedit_load_addr == LLDB_INVALID_ADDRESS)
                {
                    // We might be trying to access the symbol table before the __LINKEDIT's load
                    // address has been set in the target. We can't fail to read the symbol table,
                    // so calculate the right address manually
                    linkedit_load_addr = CalculateSectionLoadAddressForMemoryImage(m_memory_addr, GetMachHeaderSection(), linkedit_section_sp.get());
                }

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

        typedef std::set<ConstString> IndirectSymbols;
        IndirectSymbols indirect_symbol_names;

#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.MemoryMapFileContentsIfLocal(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.MemoryMapFileContentsIfLocal(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.MemoryMapFileContentsIfLocal(localSymbolsOffset, localSymbolsSize))
                        {
                            DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp, byte_order, addr_byte_size);

                            offset = 0;

                            typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
                            typedef std::map<uint32_t, ConstString> SymbolIndexToName;
                            UndefinedNameToDescMap undefined_name_to_desc;
                            SymbolIndexToName reexport_shlib_needs_fixup;


                            // 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;
                                            bool set_value = true;

                                            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.

                                                        is_gsym = true;
                                                        sym[sym_idx].SetExternal(true);

                                                        if (symbol_name && symbol_name[0] == '_' && symbol_name[1] ==  'O')
                                                        {
                                                            llvm::StringRef symbol_name_ref(symbol_name);
                                                            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 (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:
                                                        {
                                                            const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
                                                            if (reexport_name_cstr && reexport_name_cstr[0])
                                                            {
                                                                type = eSymbolTypeReExported;
                                                                ConstString reexport_name(reexport_name_cstr + ((reexport_name_cstr[0] == '_') ? 1 : 0));
                                                                sym[sym_idx].SetReExportedSymbolName(reexport_name);
                                                                set_value = false;
                                                                reexport_shlib_needs_fixup[sym_idx] = reexport_name;
                                                                indirect_symbol_names.insert(ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
                                                            }
                                                            else
                                                                type = eSymbolTypeUndefined;
                                                        }
                                                        break;
                                                        
                                                    case N_UNDF:
                                                        if (symbol_name && symbol_name[0])
                                                        {
                                                            ConstString undefined_name(symbol_name + ((symbol_name[0] == '_') ? 1 : 0));
                                                            undefined_name_to_desc[undefined_name] = nlist.n_desc;
                                                        }
                                                        // Fall through
                                                    case N_PBUD:
                                                        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);
                                                                                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)
                                                        {
                                                            const char *gsym_name = sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString();
                                                            if (gsym_name)
                                                                N_GSYM_name_to_sym_idx[gsym_name] = 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          ||
                                                             type == eSymbolTypeObjCClass     ||
                                                             type == eSymbolTypeObjCMetaClass ||
                                                             type == eSymbolTypeObjCIVar      )
                                                    {
                                                        // 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
                                                        {
                                                            const char *gsym_name = sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString();
                                                            if (gsym_name)
                                                            {
                                                                // Combine N_GSYM stab entries with the non stab symbol
                                                                ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(gsym_name);
                                                                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].GetAddressRef().SetSection (symbol_section);
                                                                    sym[GSYM_sym_idx].GetAddressRef().SetOffset (symbol_value);
                                                                    // We just need the flags from the linker symbol, so put these flags
                                                                    // into the N_GSYM 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);
                                                if (set_value)
                                                {
                                                    sym[sym_idx].GetAddressRef().SetSection (symbol_section);
                                                    sym[sym_idx].GetAddressRef().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
                                }
                            }

                            for (const auto &pos :reexport_shlib_needs_fixup)
                            {
                                const auto undef_pos = undefined_name_to_desc.find(pos.second);
                                if (undef_pos != undefined_name_to_desc.end())
                                {
                                    const uint8_t dylib_ordinal = llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
                                    if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
                                        sym[pos.first].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(dylib_ordinal-1));
                                }
                            }
                        }
                    }
                }
            }
        }

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

            typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap;
            typedef std::map<uint32_t, ConstString> SymbolIndexToName;
            UndefinedNameToDescMap undefined_name_to_desc;
            SymbolIndexToName reexport_shlib_needs_fixup;
            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;
                bool set_value = true;
                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.
                        is_gsym = true;
                        sym[sym_idx].SetExternal(true);

                        if (symbol_name && symbol_name[0] == '_' && symbol_name[1] ==  'O')
                        {
                            llvm::StringRef symbol_name_ref(symbol_name);
                            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 (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(lldb::eLanguageTypeUnknown).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:
                        {
                            const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value);
                            if (reexport_name_cstr && reexport_name_cstr[0])
                            {
                                type = eSymbolTypeReExported;
                                ConstString reexport_name(reexport_name_cstr + ((reexport_name_cstr[0] == '_') ? 1 : 0));
                                sym[sym_idx].SetReExportedSymbolName(reexport_name);
                                set_value = false;
                                reexport_shlib_needs_fixup[sym_idx] = reexport_name;
                                indirect_symbol_names.insert(ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)));
                            }
                            else
                                type = eSymbolTypeUndefined;
                        }
                        break;

                    case N_UNDF:
                        if (symbol_name && symbol_name[0])
                        {
                            ConstString undefined_name(symbol_name + ((symbol_name[0] == '_') ? 1 : 0));
                            undefined_name_to_desc[undefined_name] = nlist.n_desc;
                        }
                        // Fall through
                    case N_PBUD:
                        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);
                                                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)
                    {
                        const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString();
                        if (gsym_name)
                            N_GSYM_name_to_sym_idx[gsym_name] = 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(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(lldb::eLanguageTypeUnknown, 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          ||
                                 type == eSymbolTypeObjCClass     ||
                                 type == eSymbolTypeObjCMetaClass ||
                                 type == eSymbolTypeObjCIVar      )
                        {
                            // 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(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(lldb::eLanguageTypeUnknown, 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
                                const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString();
                                if (gsym_name)
                                {
                                    ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(gsym_name);
                                    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].GetAddressRef().SetSection (symbol_section);
                                        sym[GSYM_sym_idx].GetAddressRef().SetOffset (symbol_value);
                                        // We just need the flags from the linker symbol, so put these flags
                                        // into the N_GSYM 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);
                    if (set_value)
                    {
                        sym[sym_idx].GetAddressRef().SetSection (symbol_section);
                        sym[sym_idx].GetAddressRef().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();
                }
            }

            for (const auto &pos :reexport_shlib_needs_fixup)
            {
                const auto undef_pos = undefined_name_to_desc.find(pos.second);
                if (undef_pos != undefined_name_to_desc.end())
                {
                    const uint8_t dylib_ordinal = llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
                    if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
                        sym[pos.first].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(dylib_ordinal-1));
                }
            }

        }

        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].GetAddressRef() = 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->GetAddressRef() = 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].GetAddressRef() = 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)
                {
                    // Only add indirect symbols from the Trie entries if we
                    // didn't have a N_INDR nlist entry for this already
                    if (indirect_symbol_names.find(e.entry.name) == indirect_symbol_names.end())
                    {
                        // 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);
        std::vector<std::string> rpath_paths;
        std::vector<std::string> rpath_relative_paths;
        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_RPATH:
            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);
                    if (path)
                    {
                        if (load_cmd.cmd == LC_RPATH)
                            rpath_paths.push_back(path);
                        else
                        {
                            if (path[0] == '@')
                            {
                                if (strncmp(path, "@rpath", strlen("@rpath")) == 0)
                                    rpath_relative_paths.push_back(path + strlen("@rpath"));
                            }
                            else
                            {
                                FileSpec file_spec(path, resolve_path);
                                if (files.AppendIfUnique(file_spec))
                                    count++;
                            }
                        }
                    }
                }
                break;

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

        if (!rpath_paths.empty())
        {
            // Fixup all LC_RPATH values to be absolute paths
            FileSpec this_file_spec(m_file);
            this_file_spec.ResolvePath();
            std::string loader_path("@loader_path");
            std::string executable_path("@executable_path");
            for (auto &rpath : rpath_paths)
            {
                if (rpath.find(loader_path) == 0)
                {
                    rpath.erase(0, loader_path.size());
                    rpath.insert(0, this_file_spec.GetDirectory().GetCString());
                }
                else if (rpath.find(executable_path) == 0)
                {
                    rpath.erase(0, executable_path.size());
                    rpath.insert(0, this_file_spec.GetDirectory().GetCString());
                }
            }

            for (const auto &rpath_relative_path : rpath_relative_paths)
            {
                for (const auto &rpath : rpath_paths)
                {
                    std::string path = rpath;
                    path += rpath_relative_path;
                    // It is OK to resolve this path because we must find a file on
                    // disk for us to accept it anyway if it is rpath relative.
                    FileSpec file_spec(path, true);
                    // Remove any redundant parts of the path (like "../foo") since
                    // LC_RPATH values often contain "..".
                    file_spec.NormalizePath ();
                    if (file_spec.Exists() && files.AppendIfUnique(file_spec))
                    {
                        count++;
                        break;
                    }
                }
            }
        }
    }
    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);
                        m_min_os_versions.push_back(yy);
                        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);
                        m_sdk_versions.push_back(yy);
                        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);
}


bool
ObjectFileMachO::GetIsDynamicLinkEditor()
{
    return m_header.filetype == llvm::MachO::MH_DYLINKER;
}

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

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


Section *
ObjectFileMachO::GetMachHeaderSection()
{
    // Find the first address of the mach header which is the first non-zero
    // file sized section whose file offset is zero. This is the base file address
    // of the mach-o file which can be subtracted from the vmaddr of the other
    // segments found in memory and added to the load address
    ModuleSP module_sp = GetModule();
    if (module_sp)
    {
        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();

            for (size_t sect_idx = 0;
                 sect_idx < num_sections && mach_base_file_addr == LLDB_INVALID_ADDRESS;
                 ++sect_idx)
            {
                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())
                {
                    return section;
                }
            }
        }
    }
    return nullptr;
}

lldb::addr_t
ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage(lldb::addr_t mach_header_load_address, const Section *mach_header_section, const Section *section)
{
    ModuleSP module_sp = GetModule();
    if (module_sp && mach_header_section && section && mach_header_load_address != LLDB_INVALID_ADDRESS)
    {
        lldb::addr_t mach_header_file_addr = mach_header_section->GetFileAddress();
        if (mach_header_file_addr != LLDB_INVALID_ADDRESS)
        {
            if (section &&
                section->GetFileSize() > 0 &&
                section->IsThreadSpecific() == false &&
                module_sp.get() == section->GetModule().get())
            {
                // Ignore __LINKEDIT and __DWARF segments
                if (section->GetName() == GetSegmentNameLINKEDIT())
                {
                    // Only map __LINKEDIT if we have an in memory image and this isn't
                    // a kernel binary like a kext or mach_kernel.
                    const bool is_memory_image = (bool)m_process_wp.lock();
                    const Strata strata = GetStrata();
                    if (is_memory_image == false || strata == eStrataKernel)
                        return LLDB_INVALID_ADDRESS;
                }
                return section->GetFileAddress() - mach_header_file_addr + mach_header_load_address;
            }
        }
    }
    return LLDB_INVALID_ADDRESS;
}

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)
        {
            const size_t num_sections = section_list->GetSize();

            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() == GetSegmentNameLINKEDIT())
                        {
                            // Only map __LINKEDIT if we have an in memory image and this isn't
                            // a kernel binary like a kext or mach_kernel.
                            const bool is_memory_image = (bool)m_process_wp.lock();
                            const Strata strata = GetStrata();
                            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

                Section *mach_header_section = GetMachHeaderSection();
                if (mach_header_section)
                {
                    for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
                    {
                        SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));

                        lldb::addr_t section_load_addr = CalculateSectionLoadAddressForMemoryImage(value, mach_header_section, section_sp.get());
                        if (section_load_addr != LLDB_INVALID_ADDRESS)
                        {
                            if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_load_addr))
                                ++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())
            {
                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;
}

