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

// C Includes
// C++ Includes
// Other libraries and framework includes
#include "llvm/ADT/StringRef.h" 

// Project includes
#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/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

#define THUMB_ADDRESS_BIT_MASK 0xfffffffffffffffeull
using namespace lldb;
using namespace lldb_private;
using namespace llvm::MachO;

// Some structure definitions needed for parsing the dyld shared cache files
// found on iOS devices.

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


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

    void
    InvalidateAllRegisters() override
    {
        // 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:
    int
    DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
    {
        return 0;
    }

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

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

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

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

    int
    DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
    {
        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);
    }

    void
    InvalidateAllRegisters() override
    {
        // 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:
    int
    DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
    {
        return 0;
    }

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

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

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

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

    int
    DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
    {
        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);
    }

    void
    InvalidateAllRegisters() override
    {
        // 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:
    int
    DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
    {
        return -1;
    }

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

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

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

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

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

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

    int
    DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override
    {
        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);
    }
    
    void
    InvalidateAllRegisters() override
    {
        // 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:
    int
    DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override
    {
        return -1;
    }
    
    int
    DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override
    {
        return -1;
    }
    
    int
    DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override
    {
        return -1;
    }

    int
    DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override
    {
        return -1;
    }
    
    int
    DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override
    {
        return 0;
    }
    
    int
    DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override
    {
        return 0;
    }
    
    int
    DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override
    {
        return 0;
    }
    
    int
    DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override
    {
        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::GetSegmentNameDATA_DIRTY()
{
    static ConstString g_segment_name ("__DATA_DIRTY");
    return g_segment_name;
}

const ConstString &
ObjectFileMachO::GetSegmentNameDATA_CONST()
{
    static ConstString g_segment_name ("__DATA_CONST");
    return g_segment_name;
}

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

bool
ObjectFileMachO::ParseHeader (DataExtractor &data,
                              lldb::offset_t *data_offset_ptr,
                              llvm::MachO::mach_header &header)
{
    data.SetByteOrder (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 (endian::InlHostByteOrder());
            data.SetAddressByteSize(4);
            can_parse = true;
            break;
            
        case MH_MAGIC_64:
            data.SetByteOrder (endian::InlHostByteOrder());
            data.SetAddressByteSize(8);
            can_parse = true;
            is_64_bit = true;
            break;
            
        case MH_CIGAM:
            data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig);
            data.SetAddressByteSize(4);
            can_parse = true;
            break;
            
        case MH_CIGAM_64:
            data.SetByteOrder(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 (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 (endian::InlHostByteOrder());
            m_data.SetAddressByteSize(4);
            can_parse = true;
            break;

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

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

        case MH_CIGAM_64:
            m_data.SetByteOrder(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:
                    case eSectionTypeGoSymtab:
                        return eAddressClassData;

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

                    case eSectionTypeEHFrame:
                    case eSectionTypeARMexidx:
                    case eSectionTypeARMextab:
                    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");
                                    static ConstString g_sect_name_go_symtab ("__gosymtab");

                                    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_go_symtab)
                                        sect_type = eSectionTypeGoSymtab;
                                    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 bool
ParseTrieEntries (DataExtractor &data,
                  lldb::offset_t offset,
                  const bool is_arm,
                  std::vector<llvm::StringRef> &nameSlices,
                  std::set<lldb::addr_t> &resolver_addresses,
                  std::vector<TrieEntryWithOffset>& output)
{
	if (!data.ValidOffset(offset))
        return true;

	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 )
            {
				e.entry.other = data.GetULEB128(&offset);
                uint64_t resolver_addr = e.entry.other;
                if (is_arm)
                    resolver_addr &= THUMB_ADDRESS_BIT_MASK;
                resolver_addresses.insert(resolver_addr);
            }
			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) {
        const char *cstr = data.GetCStr(&children_offset);
        if (cstr)
            nameSlices.push_back(llvm::StringRef(cstr));
        else
            return false; // Corrupt data
        lldb::offset_t childNodeOffset = data.GetULEB128(&children_offset);
		if (childNodeOffset)
        {
            if (!ParseTrieEntries(data,
                                 childNodeOffset,
                                 is_arm,
                                 nameSlices,
                                 resolver_addresses,
                                 output))
            {
                return false;
            }
        }
        nameSlices.pop_back();
	}
    return true;
}

// Read the UUID out of a dyld_shared_cache file on-disk.
UUID
ObjectFileMachO::GetSharedCacheUUID (FileSpec dyld_shared_cache, const ByteOrder byte_order, const uint32_t addr_byte_size)
{
    UUID dsc_uuid;
    DataBufferSP dsc_data_sp = dyld_shared_cache.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[7];
        lldb::offset_t offset = 0;
        memcpy (version_str, dsc_header_data.GetData (&offset, 6), 6);
        version_str[6] = '\0';
        if (strcmp (version_str, "dyld_v") == 0)
        {
            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);
        }
    }
    return dsc_uuid;
}

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_DATA_DIRTY = GetSegmentNameDATA_DIRTY();
        const ConstString &g_segment_name_DATA_CONST = GetSegmentNameDATA_CONST();
        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 data_dirty_section_sp(section_list->FindSectionByName(g_segment_name_DATA_DIRTY));
        SectionSP data_const_section_sp(section_list->FindSectionByName(g_segment_name_DATA_CONST));
        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, eRegisterKindEHFrame, 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,
                              is_arm,
                              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];
            char dsc_path_development[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());

            snprintf(dsc_path_development, sizeof(dsc_path), "%s%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(),
                     ".development");

            FileSpec dsc_nondevelopment_filespec(dsc_path, false);
            FileSpec dsc_development_filespec(dsc_path_development, false);
            FileSpec dsc_filespec;

            UUID dsc_uuid;
            UUID process_shared_cache_uuid;

            if (process)
            {
                process_shared_cache_uuid = GetProcessSharedCacheUUID(process);
            }

            // First see if we can find an exact match for the inferior process shared cache UUID in
            // the development or non-development shared caches on disk.
            if (process_shared_cache_uuid.IsValid())
            {
                if (dsc_development_filespec.Exists())
                {
                    UUID dsc_development_uuid = GetSharedCacheUUID (dsc_development_filespec, byte_order, addr_byte_size);
                    if (dsc_development_uuid.IsValid() && dsc_development_uuid == process_shared_cache_uuid)
                    {
                        dsc_filespec = dsc_development_filespec;
                        dsc_uuid = dsc_development_uuid;
                    }
                }
                if (!dsc_uuid.IsValid() && dsc_nondevelopment_filespec.Exists())
                {
                    UUID dsc_nondevelopment_uuid = GetSharedCacheUUID (dsc_nondevelopment_filespec, byte_order, addr_byte_size);
                    if (dsc_nondevelopment_uuid.IsValid() && dsc_nondevelopment_uuid == process_shared_cache_uuid)
                    {
                        dsc_filespec = dsc_nondevelopment_filespec;
                        dsc_uuid = dsc_nondevelopment_uuid;
                    }
                }
            }

            // Failing a UUID match, prefer the development dyld_shared cache if both are present.
            if (!dsc_filespec.Exists())
            {
                if (dsc_development_filespec.Exists())
                {
                    dsc_filespec = dsc_development_filespec;
                }
                else
                {
                    dsc_filespec = dsc_nondevelopment_filespec;
                }
            }

            /* 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 dyld shared cache header to find the unmapped symbols

            DataBufferSP dsc_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(0, sizeof(struct lldb_copy_dyld_cache_header_v1));
            if (!dsc_uuid.IsValid())
            {
                dsc_uuid = GetSharedCacheUUID (dsc_filespec, byte_order, addr_byte_size);
            }
            if (dsc_data_sp)
            {
                DataExtractor dsc_header_data (dsc_data_sp, byte_order, addr_byte_size);

                bool uuid_match = true;
                if (dsc_uuid.IsValid() && process)
                {
                    if (process_shared_cache_uuid.IsValid() && dsc_uuid != process_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_v1))
                {

                    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);
                                                        if (symbol_name && symbol_name[0])
                                                        {
                                                            type = ObjectFile::GetSymbolTypeFromName(symbol_name+1, 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()) ||
                                                                             symbol_section->IsDescendant(data_dirty_section_sp.get()) ||
                                                                             symbol_section->IsDescendant(data_const_section_sp.get()))
                                                                    {
                                                                        if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
                                                                        {
                                                                            type = eSymbolTypeRuntime;
                                                                            
                                                                            if (symbol_name)
                                                                            {
                                                                                llvm::StringRef symbol_name_ref(symbol_name);
                                                                                if (symbol_name_ref.startswith("_OBJC_"))
                                                                                {
                                                                                    static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_");
                                                                                    static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_");
                                                                                    static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_");
                                                                                    if (symbol_name_ref.startswith(g_objc_v2_prefix_class))
                                                                                    {
                                                                                        symbol_name_non_abi_mangled = symbol_name + 1;
                                                                                        symbol_name = symbol_name + g_objc_v2_prefix_class.size();
                                                                                        type = eSymbolTypeObjCClass;
                                                                                        demangled_is_synthesized = true;
                                                                                    }
                                                                                    else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
                                                                                    {
                                                                                        symbol_name_non_abi_mangled = symbol_name + 1;
                                                                                        symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
                                                                                        type = eSymbolTypeObjCMetaClass;
                                                                                        demangled_is_synthesized = true;
                                                                                    }
                                                                                    else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
                                                                                    {
                                                                                        symbol_name_non_abi_mangled = symbol_name + 1;
                                                                                        symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
                                                                                        type = eSymbolTypeObjCIVar;
                                                                                        demangled_is_synthesized = true;
                                                                                    }
                                                                                }
                                                                            }
                                                                        }
                                                                        else if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
                                                                        {
                                                                            type = eSymbolTypeException;
                                                                        }
                                                                        else
                                                                        {
                                                                            type = eSymbolTypeData;
                                                                        }
                                                                    }
                                                                    else if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
                                                                    {
                                                                        type = eSymbolTypeTrampoline;
                                                                    }
                                                                    else if (symbol_section->IsDescendant(objc_section_sp.get()))
                                                                    {
                                                                        type = eSymbolTypeRuntime;
                                                                        if (symbol_name && symbol_name[0] == '.')
                                                                        {
                                                                            llvm::StringRef symbol_name_ref(symbol_name);
                                                                            static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
                                                                            if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
                                                                            {
                                                                                symbol_name_non_abi_mangled = symbol_name;
                                                                                symbol_name = symbol_name + g_objc_v1_prefix_class.size();
                                                                                type = eSymbolTypeObjCClass;
                                                                                demangled_is_synthesized = true;
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                        break;
                                                }
                                            }

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

                                                    if (symbol_name)
                                                    {
                                                        ConstString const_symbol_name(symbol_name);
                                                        sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
                                                        if (is_gsym && is_debug)
                                                        {
                                                            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 &= THUMB_ADDRESS_BIT_MASK;
                                                            }

                                                            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 &= THUMB_ADDRESS_BIT_MASK;
                                                                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);
                        if (symbol_name && symbol_name[0])
                        {
                            type = ObjectFile::GetSymbolTypeFromName(symbol_name+1, 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()) ||
                                        symbol_section->IsDescendant(data_dirty_section_sp.get()) ||
                                        symbol_section->IsDescendant(data_const_section_sp.get()))
                                    {
                                        if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
                                        {
                                            type = eSymbolTypeRuntime;

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

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

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

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

                        if (symbol_name)
                        {
                            ConstString const_symbol_name(symbol_name);
                            sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled);
                        }
                    }

                    if (is_gsym)
                    {
                        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 &= THUMB_ADDRESS_BIT_MASK;

                                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 &= THUMB_ADDRESS_BIT_MASK;
                                    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 &= THUMB_ADDRESS_BIT_MASK;
                        }
                        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 &= THUMB_ADDRESS_BIT_MASK;
                                    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();

        // Set OS to an unspecified unknown or a "*" so it can match any OS
        triple.setOS(llvm::Triple::UnknownOS);
        triple.setOSName(llvm::StringRef());

        if (header.filetype == MH_PRELOAD)
        {
            // Set vendor to an unspecified unknown or a "*" so it can match any vendor
            triple.setVendor(llvm::Triple::UnknownVendor);
            triple.setVendorName(llvm::StringRef());
            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 llvm::MachO::LC_VERSION_MIN_IPHONEOS:
                        triple.setOS (llvm::Triple::IOS);
                        return true;
                        
                    case llvm::MachO::LC_VERSION_MIN_MACOSX:
                        triple.setOS (llvm::Triple::MacOSX);
                        return true;

                    case llvm::MachO::LC_VERSION_MIN_TVOS:
                        triple.setOS (llvm::Triple::TvOS);
                        return true;
                        
                    case llvm::MachO::LC_VERSION_MIN_WATCHOS:
                        triple.setOS (llvm::Triple::WatchOS);
                        return true;

                    default:
                        break;
                }

                offset = cmd_offset + load_cmd.cmdsize;
            }
            
            if (header.filetype != MH_KEXT_BUNDLE)
            {
                // We didn't find a LC_VERSION_MIN load command and this isn't a KEXT
                // so lets not say our Vendor is Apple, leave it as an unspecified unknown
                triple.setVendor(llvm::Triple::UnknownVendor);
                triple.setVendorName(llvm::StringRef());
            }
        }
    }
    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 == llvm::MachO::LC_VERSION_MIN_MACOSX 
                 || lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS 
                 || lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS 
                 || lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS)
            {
                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 == llvm::MachO::LC_VERSION_MIN_MACOSX 
                || lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS
                || lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS
                || lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS)
            {
                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
             || target_triple.getOS() == llvm::Triple::WatchOS
             || target_triple.getOS() == llvm::Triple::TvOS))
        {
            bool make_core = false;
            switch (target_arch.GetMachine())
            {
                case llvm::Triple::aarch64:
                case llvm::Triple::arm:
                case llvm::Triple::thumb:
                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;
}
