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

#include "lldb/lldb-python.h"

#include "lldb/Utility/SafeMachO.h"

#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
#include "Plugins/Platform/MacOSX/PlatformDarwinKernel.h"

#include "DynamicLoaderDarwinKernel.h"

//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
#ifdef ENABLE_DEBUG_PRINTF
#include <stdio.h>
#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
#else
#define DEBUG_PRINTF(fmt, ...)
#endif

using namespace lldb;
using namespace lldb_private;

// Progressively greater amounts of scanning we will allow
// For some targets very early in startup, we can't do any random reads of memory or we can crash the device
// so a setting is needed that can completely disable the KASLR scans.

enum KASLRScanType
{
    eKASLRScanNone = 0,         // No reading into the inferior at all
    eKASLRScanLowgloAddresses,  // Check one word of memory for a possible kernel addr, then see if a kernel is there
    eKASLRScanNearPC,           // Scan backwards from the current $pc looking for kernel; checking at 96 locations total
    eKASLRScanExhaustiveScan    // Scan through the entire possible kernel address range looking for a kernel
};

OptionEnumValueElement
g_kaslr_kernel_scan_enum_values[] =
{
    { eKASLRScanNone,            "none",            "Do not read memory looking for a Darwin kernel when attaching." },
    { eKASLRScanLowgloAddresses, "basic",           "Check for the Darwin kernel's load addr in the lowglo page (boot-args=debug) only." },
    { eKASLRScanNearPC,          "fast-scan",       "Scan near the pc value on attach to find the Darwin kernel's load address."},
    { eKASLRScanExhaustiveScan,  "exhaustive-scan", "Scan through the entire potential address range of Darwin kernel (only on 32-bit targets)."},
    { 0, NULL, NULL }
};

static PropertyDefinition
g_properties[] =
{
    { "load-kexts" , OptionValue::eTypeBoolean, true, true, NULL, NULL, "Automatically loads kext images when attaching to a kernel." },
    { "scan-type",   OptionValue::eTypeEnum,    true, eKASLRScanNearPC, NULL, g_kaslr_kernel_scan_enum_values, "Control how many reads lldb will make while searching for a Darwin kernel on attach." },
    {  NULL        , OptionValue::eTypeInvalid, false, 0  , NULL, NULL, NULL  }
};

enum {
    ePropertyLoadKexts,
    ePropertyScanType
};

class DynamicLoaderDarwinKernelProperties : public Properties
{
public:
    
    static ConstString &
    GetSettingName ()
    {
        static ConstString g_setting_name("darwin-kernel");
        return g_setting_name;
    }

    DynamicLoaderDarwinKernelProperties() :
        Properties ()
    {
        m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
        m_collection_sp->Initialize(g_properties);
    }

    virtual
    ~DynamicLoaderDarwinKernelProperties()
    {
    }

    bool
    GetLoadKexts() const
    {
        const uint32_t idx = ePropertyLoadKexts;
        return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
    }

    KASLRScanType
    GetScanType() const
    {
        const uint32_t idx = ePropertyScanType;
        return (KASLRScanType) m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
    }


};

typedef std::shared_ptr<DynamicLoaderDarwinKernelProperties> DynamicLoaderDarwinKernelPropertiesSP;

static const DynamicLoaderDarwinKernelPropertiesSP &
GetGlobalProperties()
{
    static DynamicLoaderDarwinKernelPropertiesSP g_settings_sp;
    if (!g_settings_sp)
        g_settings_sp.reset (new DynamicLoaderDarwinKernelProperties ());
    return g_settings_sp;
}

//----------------------------------------------------------------------
// Create an instance of this class. This function is filled into
// the plugin info class that gets handed out by the plugin factory and
// allows the lldb to instantiate an instance of this class.
//----------------------------------------------------------------------
DynamicLoader *
DynamicLoaderDarwinKernel::CreateInstance (Process* process, bool force)
{
    if (!force)
    {
        // If the user provided an executable binary and it is not a kernel,
        // this plugin should not create an instance.
        Module* exe_module = process->GetTarget().GetExecutableModulePointer();
        if (exe_module)
        {
            ObjectFile *object_file = exe_module->GetObjectFile();
            if (object_file)
            {
                if (object_file->GetStrata() != ObjectFile::eStrataKernel)
                {
                    return NULL;
                }
            }
        }

        // If the target's architecture does not look like an Apple environment,
        // this plugin should not create an instance.
        const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
        switch (triple_ref.getOS())
        {
            case llvm::Triple::Darwin:
            case llvm::Triple::MacOSX:
            case llvm::Triple::IOS:
                if (triple_ref.getVendor() != llvm::Triple::Apple)
                {
                   return NULL;
                }
                break;
            // If we have triple like armv7-unknown-unknown, we should try looking for a Darwin kernel.
            case llvm::Triple::UnknownOS:
                break;
            default:
                return NULL;
                break;
        }
    }

    // At this point if there is an ExecutableModule, it is a kernel and the Target is some variant of an Apple system.  
    // If the Process hasn't provided the kernel load address, we need to look around in memory to find it.

    addr_t kernel_load_address = SearchForDarwinKernel (process);
    if (kernel_load_address != LLDB_INVALID_ADDRESS)
    {
        process->SetCanJIT(false);
        return new DynamicLoaderDarwinKernel (process, kernel_load_address);
    }
    return NULL;
}

lldb::addr_t
DynamicLoaderDarwinKernel::SearchForDarwinKernel (Process *process)
{
    addr_t kernel_load_address = process->GetImageInfoAddress();
    if (kernel_load_address == LLDB_INVALID_ADDRESS)
    {
        kernel_load_address = SearchForKernelAtSameLoadAddr (process);
        if (kernel_load_address == LLDB_INVALID_ADDRESS)
        {
            kernel_load_address = SearchForKernelWithDebugHints (process);
            if (kernel_load_address == LLDB_INVALID_ADDRESS)
            {
                kernel_load_address = SearchForKernelNearPC (process);
                if (kernel_load_address == LLDB_INVALID_ADDRESS)
                {
                    kernel_load_address = SearchForKernelViaExhaustiveSearch (process);
                }
            }
        }
    }
    return kernel_load_address;
}

//----------------------------------------------------------------------
// Check if the kernel binary is loaded in memory without a slide.
// First verify that the ExecutableModule is a kernel before we proceed.
// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
//----------------------------------------------------------------------
lldb::addr_t
DynamicLoaderDarwinKernel::SearchForKernelAtSameLoadAddr (Process *process)
{
    Module *exe_module = process->GetTarget().GetExecutableModulePointer();
    if (exe_module == NULL)
        return LLDB_INVALID_ADDRESS;

    ObjectFile *exe_objfile = exe_module->GetObjectFile();
    if (exe_objfile == NULL)
        return LLDB_INVALID_ADDRESS;

    if (exe_objfile->GetType() != ObjectFile::eTypeExecutable || exe_objfile->GetStrata() != ObjectFile::eStrataKernel)
        return LLDB_INVALID_ADDRESS;

    if (!exe_objfile->GetHeaderAddress().IsValid())
        return LLDB_INVALID_ADDRESS;

    if (CheckForKernelImageAtAddress (exe_objfile->GetHeaderAddress().GetFileAddress(), process) == exe_module->GetUUID())
        return exe_objfile->GetHeaderAddress().GetFileAddress();

    return LLDB_INVALID_ADDRESS;
}

//----------------------------------------------------------------------
// If the debug flag is included in the boot-args nvram setting, the kernel's load address
// will be noted in the lowglo page at a fixed address
// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
//----------------------------------------------------------------------
lldb::addr_t
DynamicLoaderDarwinKernel::SearchForKernelWithDebugHints (Process *process)
{
    if (GetGlobalProperties()->GetScanType() == eKASLRScanNone)
        return LLDB_INVALID_ADDRESS;

    Error read_err;
    addr_t addr = LLDB_INVALID_ADDRESS;
    if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
    {
        addr = process->ReadUnsignedIntegerFromMemory (0xffffff8000002010ULL, 8, LLDB_INVALID_ADDRESS, read_err);
        if (CheckForKernelImageAtAddress (addr, process).IsValid())
        {
            return addr;
        }
        addr = process->ReadUnsignedIntegerFromMemory (0xffffff8000004010ULL, 8, LLDB_INVALID_ADDRESS, read_err);
        if (CheckForKernelImageAtAddress (addr, process).IsValid())
        {
            return addr;
        }
    }
    else
    {
        addr = process->ReadUnsignedIntegerFromMemory (0xffff0110, 4, LLDB_INVALID_ADDRESS, read_err);
        if (CheckForKernelImageAtAddress (addr, process).IsValid())
        {
            return addr;
        }
    }
    return LLDB_INVALID_ADDRESS;
}

//----------------------------------------------------------------------
// If the kernel is currently executing when lldb attaches, and we don't have
// a better way of finding the kernel's load address, try searching backwards
// from the current pc value looking for the kernel's Mach header in memory.
// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
//----------------------------------------------------------------------
lldb::addr_t
DynamicLoaderDarwinKernel::SearchForKernelNearPC (Process *process)
{
    if (GetGlobalProperties()->GetScanType() == eKASLRScanNone 
        || GetGlobalProperties()->GetScanType() == eKASLRScanLowgloAddresses)
    {
        return LLDB_INVALID_ADDRESS;
    }

    ThreadSP thread = process->GetThreadList().GetSelectedThread ();
    if (thread.get() == NULL)
        return LLDB_INVALID_ADDRESS;
    addr_t pc = thread->GetRegisterContext ()->GetPC(LLDB_INVALID_ADDRESS);

    if (pc == LLDB_INVALID_ADDRESS)
        return LLDB_INVALID_ADDRESS;

    addr_t kernel_range_low;
    if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
    {
        kernel_range_low = 1ULL << 63;
    }
    else
    {
        kernel_range_low = 1ULL << 31;
    }

    // Outside the normal kernel address range, this is probably userland code running right now
    if (pc < kernel_range_low)
        return LLDB_INVALID_ADDRESS;

    // The kernel will load at at one megabyte boundary (0x100000), or at that boundary plus 
    // an offset of one page (0x1000) or two, depending on the device.

    // Round the current pc down to the nearest one megabyte boundary - the place where we will start searching.
    addr_t addr = pc & ~0xfffff;

    int i = 0;
    while (i < 32 && pc >= kernel_range_low)
    {
        if (CheckForKernelImageAtAddress (addr, process).IsValid())
            return addr;
        if (CheckForKernelImageAtAddress (addr + 0x1000, process).IsValid())
            return addr + 0x1000;
        if (CheckForKernelImageAtAddress (addr + 0x2000, process).IsValid())
            return addr + 0x2000;
        if (CheckForKernelImageAtAddress (addr + 0x4000, process).IsValid())
            return addr + 0x4000;
        i++;
        addr -= 0x100000;
    }

    return LLDB_INVALID_ADDRESS;
}

//----------------------------------------------------------------------
// Scan through the valid address range for a kernel binary.
// This is uselessly slow in 64-bit environments so we don't even try it.
// This scan is not enabled by default even for 32-bit targets.
// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
//----------------------------------------------------------------------
lldb::addr_t
DynamicLoaderDarwinKernel::SearchForKernelViaExhaustiveSearch (Process *process)
{
    if (GetGlobalProperties()->GetScanType() != eKASLRScanExhaustiveScan)
    {
        return LLDB_INVALID_ADDRESS;
    }

    addr_t kernel_range_low, kernel_range_high;
    if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
    {
        kernel_range_low = 1ULL << 63;
        kernel_range_high = UINT64_MAX;
    }
    else
    {
        kernel_range_low = 1ULL << 31;
        kernel_range_high = UINT32_MAX;
    }

    // Stepping through memory at one-megabyte resolution looking for a kernel
    // rarely works (fast enough) with a 64-bit address space -- for now, let's
    // not even bother.  We may be attaching to something which *isn't* a kernel
    // and we don't want to spin for minutes on-end looking for a kernel.
    if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
        return LLDB_INVALID_ADDRESS;

    addr_t addr = kernel_range_low;

    while (addr >= kernel_range_low && addr < kernel_range_high)
    {
        if (CheckForKernelImageAtAddress (addr, process).IsValid())
            return addr;
        if (CheckForKernelImageAtAddress (addr + 0x1000, process).IsValid())
            return addr + 0x1000;
        if (CheckForKernelImageAtAddress (addr + 0x2000, process).IsValid())
            return addr + 0x2000;
        if (CheckForKernelImageAtAddress (addr + 0x4000, process).IsValid())
            return addr + 0x4000;
        addr += 0x100000;
    }
    return LLDB_INVALID_ADDRESS;
}

//----------------------------------------------------------------------
// Given an address in memory, look to see if there is a kernel image at that
// address.  
// Returns a UUID; if a kernel was not found at that address, UUID.IsValid() will be false.
//----------------------------------------------------------------------
lldb_private::UUID
DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress (lldb::addr_t addr, Process *process)
{
    if (addr == LLDB_INVALID_ADDRESS)
        return UUID();

    // First try a quick test -- read the first 4 bytes and see if there is a valid Mach-O magic field there
    // (the first field of the mach_header/mach_header_64 struct).

    Error read_error;
    uint64_t result = process->ReadUnsignedIntegerFromMemory (addr, 4, LLDB_INVALID_ADDRESS, read_error);
    if (result != llvm::MachO::MH_MAGIC_64
        && result != llvm::MachO::MH_MAGIC
        && result != llvm::MachO::MH_CIGAM
        && result != llvm::MachO::MH_CIGAM_64)
    {
        return UUID();
    }

    // Read the mach header and see whether it looks like a kernel
    llvm::MachO::mach_header header;
    if (process->DoReadMemory (addr, &header, sizeof(header), read_error) != sizeof(header))
        return UUID();

    if (header.magic == llvm::MachO::MH_CIGAM ||
        header.magic == llvm::MachO::MH_CIGAM_64)
    {
        header.magic        = llvm::ByteSwap_32(header.magic);
        header.cputype      = llvm::ByteSwap_32(header.cputype);
        header.cpusubtype   = llvm::ByteSwap_32(header.cpusubtype);
        header.filetype     = llvm::ByteSwap_32(header.filetype);
        header.ncmds        = llvm::ByteSwap_32(header.ncmds);
        header.sizeofcmds   = llvm::ByteSwap_32(header.sizeofcmds);
        header.flags        = llvm::ByteSwap_32(header.flags);
    }

    // A kernel is an executable which does not have the dynamic link object flag set.
    if (header.filetype == llvm::MachO::MH_EXECUTE
        && (header.flags & llvm::MachO::MH_DYLDLINK) == 0)
    {
        // Create a full module to get the UUID
        ModuleSP memory_module_sp = process->ReadModuleFromMemory (FileSpec ("temp_mach_kernel", false), addr);
        if (!memory_module_sp.get())
            return UUID();

        ObjectFile *exe_objfile = memory_module_sp->GetObjectFile();
        if (exe_objfile == NULL)
            return UUID();

        if (exe_objfile->GetType() == ObjectFile::eTypeExecutable && exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
        {
            ArchSpec kernel_arch (eArchTypeMachO, header.cputype, header.cpusubtype);
            if (!process->GetTarget().GetArchitecture().IsCompatibleMatch(kernel_arch))
            {
                process->GetTarget().SetArchitecture (kernel_arch);
            }
            return memory_module_sp->GetUUID();
        }
    }

    return UUID();
}

//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel (Process* process, lldb::addr_t kernel_addr) :
    DynamicLoader(process),
    m_kernel_load_address (kernel_addr),
    m_kernel(),
    m_kext_summary_header_ptr_addr (),
    m_kext_summary_header_addr (),
    m_kext_summary_header (),
    m_known_kexts (),
    m_mutex(Mutex::eMutexTypeRecursive),
    m_break_id (LLDB_INVALID_BREAK_ID)
{
    Error error;
    PlatformSP platform_sp(Platform::Create(PlatformDarwinKernel::GetPluginNameStatic(), error));
    // Only select the darwin-kernel Platform if we've been asked to load kexts.
    // It can take some time to scan over all of the kext info.plists and that
    // shouldn't be done if kext loading is explicitly disabled.
    if (platform_sp.get() && GetGlobalProperties()->GetLoadKexts())
    {
        process->GetTarget().SetPlatform (platform_sp);
    }
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
DynamicLoaderDarwinKernel::~DynamicLoaderDarwinKernel()
{
    Clear(true);
}

void
DynamicLoaderDarwinKernel::UpdateIfNeeded()
{
    LoadKernelModuleIfNeeded();
    SetNotificationBreakpointIfNeeded ();
}
//------------------------------------------------------------------
/// Called after attaching a process.
///
/// Allow DynamicLoader plug-ins to execute some code after
/// attaching to a process.
//------------------------------------------------------------------
void
DynamicLoaderDarwinKernel::DidAttach ()
{
    PrivateInitialize(m_process);
    UpdateIfNeeded();
}

//------------------------------------------------------------------
/// Called after attaching a process.
///
/// Allow DynamicLoader plug-ins to execute some code after
/// attaching to a process.
//------------------------------------------------------------------
void
DynamicLoaderDarwinKernel::DidLaunch ()
{
    PrivateInitialize(m_process);
    UpdateIfNeeded();
}


//----------------------------------------------------------------------
// Clear out the state of this class.
//----------------------------------------------------------------------
void
DynamicLoaderDarwinKernel::Clear (bool clear_process)
{
    Mutex::Locker locker(m_mutex);

    if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
        m_process->ClearBreakpointSiteByID(m_break_id);

    if (clear_process)
        m_process = NULL;
    m_kernel.Clear();
    m_known_kexts.clear();
    m_kext_summary_header_ptr_addr.Clear();
    m_kext_summary_header_addr.Clear();
    m_break_id = LLDB_INVALID_BREAK_ID;
}


bool
DynamicLoaderDarwinKernel::KextImageInfo::LoadImageAtFileAddress (Process *process)
{
    if (IsLoaded())
        return true;

    if (m_module_sp)
    {
        bool changed = false;
        if (m_module_sp->SetLoadAddress (process->GetTarget(), 0, true, changed))
            m_load_process_stop_id = process->GetStopID();
    }
    return false;
}

void
DynamicLoaderDarwinKernel::KextImageInfo::SetModule (ModuleSP module_sp)
{
    m_module_sp = module_sp;
    if (module_sp.get() && module_sp->GetObjectFile())
    {
        if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable
            && module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel)
        {
            m_kernel_image = true;
        }
        else
        {
            m_kernel_image = false;
        }
    }
}

ModuleSP
DynamicLoaderDarwinKernel::KextImageInfo::GetModule ()
{
    return m_module_sp;
}

void
DynamicLoaderDarwinKernel::KextImageInfo::SetLoadAddress (addr_t load_addr)
{ 
    m_load_address = load_addr;
}

addr_t
DynamicLoaderDarwinKernel::KextImageInfo::GetLoadAddress () const
{ 
    return m_load_address;
}

uint64_t 
DynamicLoaderDarwinKernel::KextImageInfo::GetSize () const
{
    return m_size;
}

void
DynamicLoaderDarwinKernel::KextImageInfo::SetSize (uint64_t size)
{
    m_size = size;
}

uint32_t
DynamicLoaderDarwinKernel::KextImageInfo::GetProcessStopId () const
{
    return m_load_process_stop_id;
}

void
DynamicLoaderDarwinKernel::KextImageInfo::SetProcessStopId (uint32_t stop_id)
{
    m_load_process_stop_id = stop_id;
}

bool
DynamicLoaderDarwinKernel::KextImageInfo::operator== (const KextImageInfo &rhs)
{
    if (m_uuid.IsValid() || rhs.GetUUID().IsValid())
    {
        if (m_uuid == rhs.GetUUID())
        {
            return true;
        }
        return false;
    }

    if (m_name == rhs.GetName() && m_load_address == rhs.GetLoadAddress())
        return true;

    return false;
}

void
DynamicLoaderDarwinKernel::KextImageInfo::SetName (const char *name)
{
    m_name = name;
}

std::string
DynamicLoaderDarwinKernel::KextImageInfo::GetName () const
{
    return m_name;
}

void
DynamicLoaderDarwinKernel::KextImageInfo::SetUUID (const UUID &uuid)
{
    m_uuid = uuid;
}

UUID
DynamicLoaderDarwinKernel::KextImageInfo::GetUUID () const
{
    return m_uuid;
}

// Given the m_load_address from the kext summaries, and a UUID, try to create an in-memory
// Module at that address.  Require that the MemoryModule have a matching UUID and detect
// if this MemoryModule is a kernel or a kext.
//
// Returns true if m_memory_module_sp is now set to a valid Module.  

bool
DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule (Process *process)
{
    if (m_memory_module_sp.get() != NULL)
        return true;
    if (m_load_address == LLDB_INVALID_ADDRESS)
        return false;

    FileSpec file_spec;
    file_spec.SetFile (m_name.c_str(), false);

    ModuleSP memory_module_sp = process->ReadModuleFromMemory (file_spec, m_load_address);

    if (memory_module_sp.get() == NULL)
        return false;

    bool is_kernel = false;
    if (memory_module_sp->GetObjectFile())
    {
        if (memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable
            && memory_module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel)
        {
            is_kernel = true;
        }
        else if (memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeSharedLibrary)
        {
            is_kernel = false;
        }
    }

    // If this is a kext, and the kernel specified what UUID we should find at this 
    // load address, require that the memory module have a matching UUID or something 
    // has gone wrong and we should discard it.
    if (m_uuid.IsValid())
    {
        if (m_uuid != memory_module_sp->GetUUID())
        {
            return false;
        }
    }

    // If the in-memory Module has a UUID, let's use that.
    if (!m_uuid.IsValid() && memory_module_sp->GetUUID().IsValid())
    {
        m_uuid = memory_module_sp->GetUUID();
    }

    m_memory_module_sp = memory_module_sp;
    m_kernel_image = is_kernel;
    if (is_kernel)
    {
        if (memory_module_sp->GetArchitecture().IsValid())
        {
            process->GetTarget().SetArchitecture(memory_module_sp->GetArchitecture());
        }
        if (m_uuid.IsValid())
        {
            Module* exe_module = process->GetTarget().GetExecutableModulePointer();
            if (exe_module && exe_module->GetUUID().IsValid())
            {
                if (m_uuid != exe_module->GetUUID())
                {
                    Stream *s = process->GetTarget().GetDebugger().GetOutputFile().get();
                    if (s)
                    {
                        s->Printf ("warning: Host-side kernel file has Mach-O UUID of %s but remote kernel has a UUID of %s -- a mismatched kernel file will result in a poor debugger experience.\n", 
                                   exe_module->GetUUID().GetAsString().c_str(),
                                   m_uuid.GetAsString().c_str());
                        s->Flush ();
                    }
                }
            }
        }
    }

    return true;
}

bool
DynamicLoaderDarwinKernel::KextImageInfo::IsKernel () const
{
    return m_kernel_image == true;
}

void
DynamicLoaderDarwinKernel::KextImageInfo::SetIsKernel (bool is_kernel) 
{
    m_kernel_image = is_kernel;
}

bool
DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule (Process *process)
{
    if (IsLoaded())
        return true;


    Target &target = process->GetTarget();

    // If we don't have / can't create a memory module for this kext, don't try to load it - we won't
    // have the correct segment load addresses.
    if (!ReadMemoryModule (process))
    {
        return false;
    }

    bool uuid_is_valid = m_uuid.IsValid();

    if (IsKernel() && uuid_is_valid && m_memory_module_sp.get())
    {
        Stream *s = target.GetDebugger().GetOutputFile().get();
        if (s)
        {
            s->Printf ("Kernel UUID: %s\n", m_memory_module_sp->GetUUID().GetAsString().c_str());
            s->Printf ("Load Address: 0x%" PRIx64 "\n", m_load_address);
        }
    }

    if (!m_module_sp)
    {
        // See if the kext has already been loaded into the target, probably by the user doing target modules add.
        const ModuleList &target_images = target.GetImages();
        m_module_sp = target_images.FindModule(m_uuid);

        // Search for the kext on the local filesystem via the UUID
        if (!m_module_sp && uuid_is_valid)
        {
            ModuleSpec module_spec;
            module_spec.GetUUID() = m_uuid;
            module_spec.GetArchitecture() = target.GetArchitecture();

            // For the kernel, we really do need an on-disk file copy of the binary to do anything useful.
            // This will force a clal to 
            if (IsKernel())
            {
                if (Symbols::DownloadObjectAndSymbolFile (module_spec, true))
                {
                    if (module_spec.GetFileSpec().Exists())
                    {
                        m_module_sp.reset(new Module (module_spec.GetFileSpec(), target.GetArchitecture()));
                        if (m_module_sp.get() && m_module_sp->MatchesModuleSpec (module_spec))
                        {
                            ModuleList loaded_module_list;
                            loaded_module_list.Append (m_module_sp);
                            target.ModulesDidLoad (loaded_module_list);
                        }
                    }
                }
            }

            // If the current platform is PlatformDarwinKernel, create a ModuleSpec with the filename set 
            // to be the bundle ID for this kext, e.g. "com.apple.filesystems.msdosfs", and ask the platform
            // to find it.
            PlatformSP platform_sp (target.GetPlatform());
            if (!m_module_sp && platform_sp)
            {
                ConstString platform_name (platform_sp->GetPluginName());
                static ConstString g_platform_name (PlatformDarwinKernel::GetPluginNameStatic());
                if (platform_name == g_platform_name)
                {
                    ModuleSpec kext_bundle_module_spec(module_spec);
                    FileSpec kext_filespec(m_name.c_str(), false);
                    kext_bundle_module_spec.GetFileSpec() = kext_filespec;
                    platform_sp->GetSharedModule (kext_bundle_module_spec, m_module_sp, &target.GetExecutableSearchPaths(), NULL, NULL);
                }
            }

            // Ask the Target to find this file on the local system, if possible.
            // This will search in the list of currently-loaded files, look in the 
            // standard search paths on the system, and on a Mac it will try calling
            // the DebugSymbols framework with the UUID to find the binary via its
            // search methods.
            if (!m_module_sp)
            {
                m_module_sp = target.GetSharedModule (module_spec);
            }

            if (IsKernel() && !m_module_sp)
            {
                Stream *s = target.GetDebugger().GetOutputFile().get();
                if (s)
                {
                    s->Printf ("WARNING: Unable to locate kernel binary on the debugger system.\n");
                }
            }
        }

        // If we managed to find a module, append it to the target's list of images.
        // If we also have a memory module, require that they have matching UUIDs
        if (m_module_sp)
        {
            bool uuid_match_ok = true;
            if (m_memory_module_sp)
            {
                if (m_module_sp->GetUUID() != m_memory_module_sp->GetUUID())
                {
                    uuid_match_ok = false;
                }
            }
            if (uuid_match_ok)
            {
                target.GetImages().AppendIfNeeded(m_module_sp);
                if (IsKernel() && target.GetExecutableModulePointer() != m_module_sp.get())
                {
                    target.SetExecutableModule (m_module_sp, false);
                }
            }
        }
    }
    
    if (!m_module_sp && !IsKernel() && m_uuid.IsValid() && !m_name.empty())
    {
        Stream *s = target.GetDebugger().GetOutputFile().get();
        if (s)
        {
            s->Printf ("warning: Can't find binary/dSYM for %s (%s)\n", 
                       m_name.c_str(), m_uuid.GetAsString().c_str());
        }
    }

    static ConstString g_section_name_LINKEDIT ("__LINKEDIT");

    if (m_memory_module_sp && m_module_sp)
    {
        if (m_module_sp->GetUUID() == m_memory_module_sp->GetUUID())
        {
            ObjectFile *ondisk_object_file = m_module_sp->GetObjectFile();
            ObjectFile *memory_object_file = m_memory_module_sp->GetObjectFile();
            
            if (memory_object_file && ondisk_object_file)
            {
                // The memory_module for kexts may have an invalid __LINKEDIT seg; skip it.
                const bool ignore_linkedit = !IsKernel ();
                
                SectionList *ondisk_section_list = ondisk_object_file->GetSectionList ();
                SectionList *memory_section_list = memory_object_file->GetSectionList ();
                if (memory_section_list && ondisk_section_list)
                {
                    const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();
                    // There may be CTF sections in the memory image so we can't
                    // always just compare the number of sections (which are actually
                    // segments in mach-o parlance)
                    uint32_t sect_idx = 0;
                    
                    // Use the memory_module's addresses for each section to set the 
                    // file module's load address as appropriate.  We don't want to use
                    // a single slide value for the entire kext - different segments may
                    // be slid different amounts by the kext loader.

                    uint32_t num_sections_loaded = 0;
                    for (sect_idx=0; sect_idx<num_ondisk_sections; ++sect_idx)
                    {
                        SectionSP ondisk_section_sp(ondisk_section_list->GetSectionAtIndex(sect_idx));
                        if (ondisk_section_sp)
                        {
                            // Don't ever load __LINKEDIT as it may or may not be actually
                            // mapped into memory and there is no current way to tell.
                            // I filed rdar://problem/12851706 to track being able to tell
                            // if the __LINKEDIT is actually mapped, but until then, we need
                            // to not load the __LINKEDIT
                            if (ignore_linkedit && ondisk_section_sp->GetName() == g_section_name_LINKEDIT)
                                continue;

                            const Section *memory_section = memory_section_list->FindSectionByName(ondisk_section_sp->GetName()).get();
                            if (memory_section)
                            {
                                target.SetSectionLoadAddress (ondisk_section_sp, memory_section->GetFileAddress());
                                ++num_sections_loaded;
                            }
                        }
                    }
                    if (num_sections_loaded > 0)
                        m_load_process_stop_id = process->GetStopID();
                    else
                        m_module_sp.reset(); // No sections were loaded
                }
                else
                    m_module_sp.reset(); // One or both section lists
            }
            else
                m_module_sp.reset(); // One or both object files missing
        }
        else
            m_module_sp.reset(); // UUID mismatch
    }

    bool is_loaded = IsLoaded();
    
    if (is_loaded && m_module_sp && IsKernel())
    {
        Stream *s = target.GetDebugger().GetOutputFile().get();
        if (s)
        {
            ObjectFile *kernel_object_file = m_module_sp->GetObjectFile();
            if (kernel_object_file)
            {
                addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress();
                if (m_load_address != LLDB_INVALID_ADDRESS && file_address != LLDB_INVALID_ADDRESS)
                {
                    s->Printf ("Kernel slid 0x%" PRIx64 " in memory.\n", m_load_address - file_address);
                }
            }
            {
                s->Printf ("Loaded kernel file %s\n",
                           m_module_sp->GetFileSpec().GetPath().c_str());
            }
            s->Flush ();
        }
    }
    return is_loaded;
}

uint32_t
DynamicLoaderDarwinKernel::KextImageInfo::GetAddressByteSize ()
{
    if (m_memory_module_sp)
        return m_memory_module_sp->GetArchitecture().GetAddressByteSize();
    if (m_module_sp)
        return m_module_sp->GetArchitecture().GetAddressByteSize();
    return 0;
}

lldb::ByteOrder
DynamicLoaderDarwinKernel::KextImageInfo::GetByteOrder()
{
    if (m_memory_module_sp)
        return m_memory_module_sp->GetArchitecture().GetByteOrder();
    if (m_module_sp)
        return m_module_sp->GetArchitecture().GetByteOrder();
    return lldb::endian::InlHostByteOrder();
}

lldb_private::ArchSpec
DynamicLoaderDarwinKernel::KextImageInfo::GetArchitecture () const
{
    if (m_memory_module_sp)
        return m_memory_module_sp->GetArchitecture();
    if (m_module_sp)
        return m_module_sp->GetArchitecture();
    return lldb_private::ArchSpec ();
}


//----------------------------------------------------------------------
// Load the kernel module and initialize the "m_kernel" member. Return
// true _only_ if the kernel is loaded the first time through (subsequent
// calls to this function should return false after the kernel has been
// already loaded).
//----------------------------------------------------------------------
void
DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded()
{
    if (!m_kext_summary_header_ptr_addr.IsValid())
    {
        m_kernel.Clear();
        m_kernel.SetModule (m_process->GetTarget().GetExecutableModule());
        m_kernel.SetIsKernel(true);

        ConstString kernel_name("mach_kernel");
        if (m_kernel.GetModule().get()
            && m_kernel.GetModule()->GetObjectFile()
            && !m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty())
        {
            kernel_name = m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename();
        }
        m_kernel.SetName (kernel_name.AsCString());

        if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS)
        {
            m_kernel.SetLoadAddress(m_kernel_load_address);
            if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS && m_kernel.GetModule())
            {
                // We didn't get a hint from the process, so we will
                // try the kernel at the address that it exists at in
                // the file if we have one
                ObjectFile *kernel_object_file = m_kernel.GetModule()->GetObjectFile();
                if (kernel_object_file)
                {
                    addr_t load_address = kernel_object_file->GetHeaderAddress().GetLoadAddress(&m_process->GetTarget());
                    addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress();
                    if (load_address != LLDB_INVALID_ADDRESS && load_address != 0)
                    {
                        m_kernel.SetLoadAddress (load_address);
                        if (load_address != file_address)
                        {
                            // Don't accidentally relocate the kernel to the File address -- 
                            // the Load address has already been set to its actual in-memory address.  
                            // Mark it as IsLoaded.
                            m_kernel.SetProcessStopId (m_process->GetStopID());
                        }
                    }
                    else
                    {
                        m_kernel.SetLoadAddress(file_address);
                    }
                }
            }
        }
        
        if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS)
        {
            if (!m_kernel.LoadImageUsingMemoryModule (m_process))
            {
                m_kernel.LoadImageAtFileAddress (m_process);
            }
        }

        if (m_kernel.IsLoaded() && m_kernel.GetModule())
        {
            static ConstString kext_summary_symbol ("gLoadedKextSummaries");
            const Symbol *symbol = m_kernel.GetModule()->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData);
            if (symbol)
            {
                m_kext_summary_header_ptr_addr = symbol->GetAddress();
                // Update all image infos
                ReadAllKextSummaries ();
            }
        }
        else
        {
            m_kernel.Clear();
        }
    }
}

//----------------------------------------------------------------------
// Static callback function that gets called when our DYLD notification
// breakpoint gets hit. We update all of our image infos and then
// let our super class DynamicLoader class decide if we should stop
// or not (based on global preference).
//----------------------------------------------------------------------
bool
DynamicLoaderDarwinKernel::BreakpointHitCallback (void *baton, 
                                                  StoppointCallbackContext *context, 
                                                  user_id_t break_id, 
                                                  user_id_t break_loc_id)
{    
    return static_cast<DynamicLoaderDarwinKernel*>(baton)->BreakpointHit (context, break_id, break_loc_id);    
}

bool
DynamicLoaderDarwinKernel::BreakpointHit (StoppointCallbackContext *context, 
                                          user_id_t break_id, 
                                          user_id_t break_loc_id)
{    
    Log *log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
    if (log)
        log->Printf ("DynamicLoaderDarwinKernel::BreakpointHit (...)\n");

    ReadAllKextSummaries ();
    
    if (log)
        PutToLog(log);

    return GetStopWhenImagesChange();
}


bool
DynamicLoaderDarwinKernel::ReadKextSummaryHeader ()
{
    Mutex::Locker locker(m_mutex);

    // the all image infos is already valid for this process stop ID

    if (m_kext_summary_header_ptr_addr.IsValid())
    {
        const uint32_t addr_size = m_kernel.GetAddressByteSize ();
        const ByteOrder byte_order = m_kernel.GetByteOrder();
        Error error;
        // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure
        // which is currently 4 uint32_t and a pointer.
        uint8_t buf[24];
        DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
        const size_t count = 4 * sizeof(uint32_t) + addr_size;
        const bool prefer_file_cache = false;
        if (m_process->GetTarget().ReadPointerFromMemory (m_kext_summary_header_ptr_addr, 
                                                          prefer_file_cache,
                                                          error,
                                                          m_kext_summary_header_addr))
        {
            // We got a valid address for our kext summary header and make sure it isn't NULL
            if (m_kext_summary_header_addr.IsValid() && 
                m_kext_summary_header_addr.GetFileAddress() != 0)
            {
                const size_t bytes_read = m_process->GetTarget().ReadMemory (m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
                if (bytes_read == count)
                {
                    lldb::offset_t offset = 0;
                    m_kext_summary_header.version = data.GetU32(&offset);
                    if (m_kext_summary_header.version > 128)
                    {
                        Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
                        s->Printf ("WARNING: Unable to read kext summary header, got improbable version number %u\n", m_kext_summary_header.version);
                        // If we get an improbably large version number, we're probably getting bad memory.
                        m_kext_summary_header_addr.Clear();
                        return false;
                    }
                    if (m_kext_summary_header.version >= 2)
                    {
                        m_kext_summary_header.entry_size = data.GetU32(&offset);
                        if (m_kext_summary_header.entry_size > 4096)
                        {
                            // If we get an improbably large entry_size, we're probably getting bad memory.
                            Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
                            s->Printf ("WARNING: Unable to read kext summary header, got improbable entry_size %u\n", m_kext_summary_header.entry_size);
                            m_kext_summary_header_addr.Clear();
                            return false;
                        }
                    }
                    else
                    {
                        // Versions less than 2 didn't have an entry size, it was hard coded
                        m_kext_summary_header.entry_size = KERNEL_MODULE_ENTRY_SIZE_VERSION_1;
                    }
                    m_kext_summary_header.entry_count = data.GetU32(&offset);
                    if (m_kext_summary_header.entry_count > 10000)
                    {
                        // If we get an improbably large number of kexts, we're probably getting bad memory.
                        Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
                        s->Printf ("WARNING: Unable to read kext summary header, got improbable number of kexts %u\n", m_kext_summary_header.entry_count);
                        m_kext_summary_header_addr.Clear();
                        return false;
                    }
                    return true;
                }
            }
        }
    }
    m_kext_summary_header_addr.Clear();
    return false;
}

// We've either (a) just attached to a new kernel, or (b) the kexts-changed breakpoint was hit
// and we need to figure out what kexts have been added or removed.
// Read the kext summaries from the inferior kernel memory, compare them against the
// m_known_kexts vector and update the m_known_kexts vector as needed to keep in sync with the
// inferior.

bool
DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr, uint32_t count)
{
    KextImageInfo::collection kext_summaries;
    Log *log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
    if (log)
        log->Printf ("Kexts-changed breakpoint hit, there are %d kexts currently.\n", count);
        
    Mutex::Locker locker(m_mutex);

    if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries))
        return false;

    // read the plugin.dynamic-loader.darwin-kernel.load-kexts setting -- if the user requested no 
    // kext loading, don't print any messages about kexts & don't try to read them.
    const bool load_kexts = GetGlobalProperties()->GetLoadKexts();

    // By default, all kexts we've loaded in the past are marked as "remove" and all of the kexts
    // we just found out about from ReadKextSummaries are marked as "add".
    std::vector<bool> to_be_removed(m_known_kexts.size(), true);
    std::vector<bool> to_be_added(count, true);

    int number_of_new_kexts_being_added = 0;
    int number_of_old_kexts_being_removed = m_known_kexts.size();

    const uint32_t new_kexts_size = kext_summaries.size();
    const uint32_t old_kexts_size = m_known_kexts.size();

    // The m_known_kexts vector may have entries that have been Cleared,
    // or are a kernel.  
    for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++)
    {
        bool ignore = false;
        KextImageInfo &image_info = m_known_kexts[old_kext];
        if (image_info.IsKernel())
        {
            ignore = true;
        }
        else if (image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS && !image_info.GetModule())
        {
            ignore = true;
        }

        if (ignore)
        {
            number_of_old_kexts_being_removed--;
            to_be_removed[old_kext] = false;
        }
    }

    // Scan over the list of kexts we just read from the kernel, note those that
    // need to be added and those already loaded.
    for (uint32_t new_kext = 0; new_kext < new_kexts_size; new_kext++)
    {
        bool add_this_one = true;
        for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++)
        {
            if (m_known_kexts[old_kext] == kext_summaries[new_kext])
            {
                // We already have this kext, don't re-load it.
                to_be_added[new_kext] = false;
                // This kext is still present, do not remove it.
                to_be_removed[old_kext] = false;

                number_of_old_kexts_being_removed--;
                add_this_one = false;
                break;
            }
        }
        if (add_this_one)
        {
            number_of_new_kexts_being_added++;
        }
    }

    if (number_of_new_kexts_being_added == 0 && number_of_old_kexts_being_removed == 0)
        return true;

    Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
    if (s && load_kexts)
    {
        if (number_of_new_kexts_being_added > 0 && number_of_old_kexts_being_removed > 0)
        {
            s->Printf ("Loading %d kext modules and unloading %d kext modules ", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
        }
        else if (number_of_new_kexts_being_added > 0)
        {
            s->Printf ("Loading %d kext modules ", number_of_new_kexts_being_added);
        }
        else if (number_of_old_kexts_being_removed > 0)
        {
            s->Printf ("Unloading %d kext modules ", number_of_old_kexts_being_removed);
        }
    }

    if (log)
    {
        if (load_kexts)
        {
            log->Printf ("DynamicLoaderDarwinKernel::ParseKextSummaries: %d kexts added, %d kexts removed", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
        }
        else
        {
            log->Printf ("DynamicLoaderDarwinKernel::ParseKextSummaries kext loading is disabled, else would have %d kexts added, %d kexts removed", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
        }
    }


    if (number_of_new_kexts_being_added > 0)
    {
        ModuleList loaded_module_list;

        const uint32_t num_of_new_kexts = kext_summaries.size();
        for (uint32_t new_kext = 0; new_kext < num_of_new_kexts; new_kext++)
        {
            if (to_be_added[new_kext] == true)
            {
                KextImageInfo &image_info = kext_summaries[new_kext];
                if (load_kexts)
                {
                    if (!image_info.LoadImageUsingMemoryModule (m_process))
                    {
                        image_info.LoadImageAtFileAddress (m_process);
                    }
                }

                m_known_kexts.push_back(image_info);

                if (image_info.GetModule() && m_process->GetStopID() == image_info.GetProcessStopId())
                    loaded_module_list.AppendIfNeeded (image_info.GetModule());

                if (s && load_kexts)
                    s->Printf (".");

                if (log)
                    kext_summaries[new_kext].PutToLog (log);
            }
        }
        m_process->GetTarget().ModulesDidLoad (loaded_module_list);
    }

    if (number_of_old_kexts_being_removed > 0)
    {
        ModuleList loaded_module_list;
        const uint32_t num_of_old_kexts = m_known_kexts.size();
        for (uint32_t old_kext = 0; old_kext < num_of_old_kexts; old_kext++)
        {
            ModuleList unloaded_module_list;
            if (to_be_removed[old_kext])
            {
                KextImageInfo &image_info = m_known_kexts[old_kext];
                // You can't unload the kernel.
                if (!image_info.IsKernel())
                {
                    if (image_info.GetModule())
                    {
                        unloaded_module_list.AppendIfNeeded (image_info.GetModule());
                    }
                    if (s)
                        s->Printf (".");
                    image_info.Clear();
                    // should pull it out of the KextImageInfos vector but that would mutate the list and invalidate
                    // the to_be_removed bool vector; leaving it in place once Cleared() is relatively harmless.
                }
            }
            m_process->GetTarget().ModulesDidUnload (unloaded_module_list, false);
        }
    }

    if (s && load_kexts)
    {
        s->Printf (" done.\n");
        s->Flush ();
    }

    return true;
}

uint32_t
DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr,
                                              uint32_t image_infos_count, 
                                              KextImageInfo::collection &image_infos)
{
    const ByteOrder endian = m_kernel.GetByteOrder();
    const uint32_t addr_size = m_kernel.GetAddressByteSize();

    image_infos.resize(image_infos_count);
    const size_t count = image_infos.size() * m_kext_summary_header.entry_size;
    DataBufferHeap data(count, 0);
    Error error;
    
    const bool prefer_file_cache = false;
    const size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary_addr, 
                                                                 prefer_file_cache,
                                                                 data.GetBytes(), 
                                                                 data.GetByteSize(),
                                                                 error);
    if (bytes_read == count)
    {
        
        DataExtractor extractor (data.GetBytes(), data.GetByteSize(), endian, addr_size);
        uint32_t i=0;
        for (uint32_t kext_summary_offset = 0;
             i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size); 
             ++i, kext_summary_offset += m_kext_summary_header.entry_size)
        {
            lldb::offset_t offset = kext_summary_offset;
            const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
            if (name_data == NULL)
                break;
            image_infos[i].SetName ((const char *) name_data);
            UUID uuid (extractor.GetData (&offset, 16), 16);
            image_infos[i].SetUUID (uuid);
            image_infos[i].SetLoadAddress (extractor.GetU64(&offset));
            image_infos[i].SetSize (extractor.GetU64(&offset));
        }
        if (i < image_infos.size())
            image_infos.resize(i);
    }
    else
    {
        image_infos.clear();
    }
    return image_infos.size();
}

bool
DynamicLoaderDarwinKernel::ReadAllKextSummaries ()
{
    Mutex::Locker locker(m_mutex);
    
    if (ReadKextSummaryHeader ())
    {
        if (m_kext_summary_header.entry_count > 0 && m_kext_summary_header_addr.IsValid())
        {
            Address summary_addr (m_kext_summary_header_addr);
            summary_addr.Slide(m_kext_summary_header.GetSize());
            if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count))
            {
                m_known_kexts.clear();
            }
            return true;
        }
    }
    return false;
}

//----------------------------------------------------------------------
// Dump an image info structure to the file handle provided.
//----------------------------------------------------------------------
void
DynamicLoaderDarwinKernel::KextImageInfo::PutToLog (Log *log) const
{
    if (log == NULL)
        return;
    const uint8_t *u = (uint8_t *) m_uuid.GetBytes();

    if (m_load_address == LLDB_INVALID_ADDRESS)
    {
        if (u)
        {
            log->Printf("\tuuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\" (UNLOADED)",
                        u[ 0], u[ 1], u[ 2], u[ 3],
                        u[ 4], u[ 5], u[ 6], u[ 7],
                        u[ 8], u[ 9], u[10], u[11],
                        u[12], u[13], u[14], u[15],
                        m_name.c_str());
        }
        else
            log->Printf("\tname=\"%s\" (UNLOADED)", m_name.c_str());
    }
    else
    {
        if (u)
        {
            log->Printf("\taddr=0x%16.16" PRIx64 " size=0x%16.16" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\"",
                        m_load_address, m_size, 
                        u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
                        u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15],
                        m_name.c_str());
        }
        else
        {
            log->Printf("\t[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") name=\"%s\"",
                        m_load_address, m_load_address+m_size, m_name.c_str());
        }
    }
}

//----------------------------------------------------------------------
// Dump the _dyld_all_image_infos members and all current image infos
// that we have parsed to the file handle provided.
//----------------------------------------------------------------------
void
DynamicLoaderDarwinKernel::PutToLog(Log *log) const
{
    if (log == NULL)
        return;

    Mutex::Locker locker(m_mutex);
    log->Printf("gLoadedKextSummaries = 0x%16.16" PRIx64 " { version=%u, entry_size=%u, entry_count=%u }",
                m_kext_summary_header_addr.GetFileAddress(),
                m_kext_summary_header.version,
                m_kext_summary_header.entry_size,
                m_kext_summary_header.entry_count);

    size_t i;
    const size_t count = m_known_kexts.size();
    if (count > 0)
    {
        log->PutCString("Loaded:");
        for (i = 0; i<count; i++)
            m_known_kexts[i].PutToLog(log);
    }
}

void
DynamicLoaderDarwinKernel::PrivateInitialize(Process *process)
{
    DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
    Clear(true);
    m_process = process;
}

void
DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded ()
{
    if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.GetModule())
    {
        DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));

        
        const bool internal_bp = true;
        const bool hardware = false;
        const LazyBool skip_prologue = eLazyBoolNo;
        FileSpecList module_spec_list;
        module_spec_list.Append (m_kernel.GetModule()->GetFileSpec());
        Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&module_spec_list,
                                                                  NULL,
                                                                  "OSKextLoadedKextSummariesUpdated",
                                                                  eFunctionNameTypeFull,
                                                                  skip_prologue,
                                                                  internal_bp,
                                                                  hardware).get();

        bp->SetCallback (DynamicLoaderDarwinKernel::BreakpointHitCallback, this, true);
        m_break_id = bp->GetID();
    }
}

//----------------------------------------------------------------------
// Member function that gets called when the process state changes.
//----------------------------------------------------------------------
void
DynamicLoaderDarwinKernel::PrivateProcessStateChanged (Process *process, StateType state)
{
    DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__, StateAsCString(state));
    switch (state)
    {
    case eStateConnected:
    case eStateAttaching:
    case eStateLaunching:
    case eStateInvalid:
    case eStateUnloaded:
    case eStateExited:
    case eStateDetached:
        Clear(false);
        break;

    case eStateStopped:
        UpdateIfNeeded();
        break;

    case eStateRunning:
    case eStateStepping:
    case eStateCrashed:
    case eStateSuspended:
        break;
    }
}

ThreadPlanSP
DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
{
    ThreadPlanSP thread_plan_sp;
    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
    if (log)
        log->Printf ("Could not find symbol for step through.");
    return thread_plan_sp;
}

Error
DynamicLoaderDarwinKernel::CanLoadImage ()
{
    Error error;
    error.SetErrorString("always unsafe to load or unload shared libraries in the darwin kernel");
    return error;
}

void
DynamicLoaderDarwinKernel::Initialize()
{
    PluginManager::RegisterPlugin (GetPluginNameStatic(),
                                   GetPluginDescriptionStatic(),
                                   CreateInstance,
                                   DebuggerInitialize);
}

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

void
DynamicLoaderDarwinKernel::DebuggerInitialize (lldb_private::Debugger &debugger)
{
    if (!PluginManager::GetSettingForDynamicLoaderPlugin (debugger, DynamicLoaderDarwinKernelProperties::GetSettingName()))
    {
        const bool is_global_setting = true;
        PluginManager::CreateSettingForDynamicLoaderPlugin (debugger,
                                                            GetGlobalProperties()->GetValueProperties(),
                                                            ConstString ("Properties for the DynamicLoaderDarwinKernel plug-in."),
                                                            is_global_setting);
    }
}

lldb_private::ConstString
DynamicLoaderDarwinKernel::GetPluginNameStatic()
{
    static ConstString g_name("darwin-kernel");
    return g_name;
}

const char *
DynamicLoaderDarwinKernel::GetPluginDescriptionStatic()
{
    return "Dynamic loader plug-in that watches for shared library loads/unloads in the MacOSX kernel.";
}


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

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

lldb::ByteOrder
DynamicLoaderDarwinKernel::GetByteOrderFromMagic (uint32_t magic)
{
    switch (magic)
    {
        case llvm::MachO::MH_MAGIC:
        case llvm::MachO::MH_MAGIC_64:
            return lldb::endian::InlHostByteOrder();
            
        case llvm::MachO::MH_CIGAM:
        case llvm::MachO::MH_CIGAM_64:
            if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig)
                return lldb::eByteOrderLittle;
            else
                return lldb::eByteOrderBig;
            
        default:
            break;
    }
    return lldb::eByteOrderInvalid;
}

