//===-- DynamicLoaderMacOSXDYLD.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "DynamicLoaderMacOSXDYLD.h"
#include "DynamicLoaderDarwin.h"
#include "DynamicLoaderMacOS.h"
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/ABI.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 "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/State.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

#ifndef __APPLE__
#include "Utility/UuidCompatibility.h"
#else
#include <uuid/uuid.h>
#endif

using namespace lldb;
using namespace lldb_private;

LLDB_PLUGIN_DEFINE(DynamicLoaderMacOSXDYLD)

// 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 *DynamicLoaderMacOSXDYLD::CreateInstance(Process *process,
                                                       bool force) {
  bool create = force;
  if (!create) {
    create = true;
    Module *exe_module = process->GetTarget().GetExecutableModulePointer();
    if (exe_module) {
      ObjectFile *object_file = exe_module->GetObjectFile();
      if (object_file) {
        create = (object_file->GetStrata() == ObjectFile::eStrataUser);
      }
    }

    if (create) {
      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:
      case llvm::Triple::TvOS:
      case llvm::Triple::WatchOS:
      // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
        create = triple_ref.getVendor() == llvm::Triple::Apple;
        break;
      default:
        create = false;
        break;
      }
    }
  }

  if (UseDYLDSPI(process)) {
    create = false;
  }

  if (create)
    return new DynamicLoaderMacOSXDYLD(process);
  return nullptr;
}

// Constructor
DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD(Process *process)
    : DynamicLoaderDarwin(process),
      m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS),
      m_dyld_all_image_infos(), m_dyld_all_image_infos_stop_id(UINT32_MAX),
      m_break_id(LLDB_INVALID_BREAK_ID), m_mutex(),
      m_process_image_addr_is_all_images_infos(false) {}

// Destructor
DynamicLoaderMacOSXDYLD::~DynamicLoaderMacOSXDYLD() {
  if (LLDB_BREAK_ID_IS_VALID(m_break_id))
    m_process->GetTarget().RemoveBreakpointByID(m_break_id);
}

bool DynamicLoaderMacOSXDYLD::ProcessDidExec() {
  std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
  bool did_exec = false;
  if (m_process) {
    // If we are stopped after an exec, we will have only one thread...
    if (m_process->GetThreadList().GetSize() == 1) {
      // We know if a process has exec'ed if our "m_dyld_all_image_infos_addr"
      // value differs from the Process' image info address. When a process
      // execs itself it might cause a change if ASLR is enabled.
      const addr_t shlib_addr = m_process->GetImageInfoAddress();
      if (m_process_image_addr_is_all_images_infos &&
          shlib_addr != m_dyld_all_image_infos_addr) {
        // The image info address from the process is the
        // 'dyld_all_image_infos' address and it has changed.
        did_exec = true;
      } else if (!m_process_image_addr_is_all_images_infos &&
                 shlib_addr == m_dyld.address) {
        // The image info address from the process is the mach_header address
        // for dyld and it has changed.
        did_exec = true;
      } else {
        // ASLR might be disabled and dyld could have ended up in the same
        // location. We should try and detect if we are stopped at
        // '_dyld_start'
        ThreadSP thread_sp(m_process->GetThreadList().GetThreadAtIndex(0));
        if (thread_sp) {
          lldb::StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
          if (frame_sp) {
            const Symbol *symbol =
                frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
            if (symbol) {
              if (symbol->GetName() == "_dyld_start")
                did_exec = true;
            }
          }
        }
      }

      if (did_exec) {
        m_libpthread_module_wp.reset();
        m_pthread_getspecific_addr.Clear();
      }
    }
  }
  return did_exec;
}

// Clear out the state of this class.
void DynamicLoaderMacOSXDYLD::DoClear() {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  if (LLDB_BREAK_ID_IS_VALID(m_break_id))
    m_process->GetTarget().RemoveBreakpointByID(m_break_id);

  m_dyld_all_image_infos_addr = LLDB_INVALID_ADDRESS;
  m_dyld_all_image_infos.Clear();
  m_break_id = LLDB_INVALID_BREAK_ID;
}

// Check if we have found DYLD yet
bool DynamicLoaderMacOSXDYLD::DidSetNotificationBreakpoint() {
  return LLDB_BREAK_ID_IS_VALID(m_break_id);
}

void DynamicLoaderMacOSXDYLD::ClearNotificationBreakpoint() {
  if (LLDB_BREAK_ID_IS_VALID(m_break_id)) {
    m_process->GetTarget().RemoveBreakpointByID(m_break_id);
  }
}

// Try and figure out where dyld is by first asking the Process if it knows
// (which currently calls down in the lldb::Process to get the DYLD info
// (available on SnowLeopard only). If that fails, then check in the default
// addresses.
void DynamicLoaderMacOSXDYLD::DoInitialImageFetch() {
  if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS) {
    // Check the image info addr as it might point to the mach header for dyld,
    // or it might point to the dyld_all_image_infos struct
    const addr_t shlib_addr = m_process->GetImageInfoAddress();
    if (shlib_addr != LLDB_INVALID_ADDRESS) {
      ByteOrder byte_order =
          m_process->GetTarget().GetArchitecture().GetByteOrder();
      uint8_t buf[4];
      DataExtractor data(buf, sizeof(buf), byte_order, 4);
      Status error;
      if (m_process->ReadMemory(shlib_addr, buf, 4, error) == 4) {
        lldb::offset_t offset = 0;
        uint32_t magic = data.GetU32(&offset);
        switch (magic) {
        case llvm::MachO::MH_MAGIC:
        case llvm::MachO::MH_MAGIC_64:
        case llvm::MachO::MH_CIGAM:
        case llvm::MachO::MH_CIGAM_64:
          m_process_image_addr_is_all_images_infos = false;
          ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr);
          return;

        default:
          break;
        }
      }
      // Maybe it points to the all image infos?
      m_dyld_all_image_infos_addr = shlib_addr;
      m_process_image_addr_is_all_images_infos = true;
    }
  }

  if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) {
    if (ReadAllImageInfosStructure()) {
      if (m_dyld_all_image_infos.dyldImageLoadAddress != LLDB_INVALID_ADDRESS)
        ReadDYLDInfoFromMemoryAndSetNotificationCallback(
            m_dyld_all_image_infos.dyldImageLoadAddress);
      else
        ReadDYLDInfoFromMemoryAndSetNotificationCallback(
            m_dyld_all_image_infos_addr & 0xfffffffffff00000ull);
      return;
    }
  }

  // Check some default values
  Module *executable = m_process->GetTarget().GetExecutableModulePointer();

  if (executable) {
    const ArchSpec &exe_arch = executable->GetArchitecture();
    if (exe_arch.GetAddressByteSize() == 8) {
      ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x7fff5fc00000ull);
    } else if (exe_arch.GetMachine() == llvm::Triple::arm ||
               exe_arch.GetMachine() == llvm::Triple::thumb ||
               exe_arch.GetMachine() == llvm::Triple::aarch64 ||
               exe_arch.GetMachine() == llvm::Triple::aarch64_32) {
      ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x2fe00000);
    } else {
      ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x8fe00000);
    }
  }
  return;
}

// Assume that dyld is in memory at ADDR and try to parse it's load commands
bool DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(
    lldb::addr_t addr) {
  std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
  DataExtractor data; // Load command data
  static ConstString g_dyld_all_image_infos("dyld_all_image_infos");
  if (ReadMachHeader(addr, &m_dyld.header, &data)) {
    if (m_dyld.header.filetype == llvm::MachO::MH_DYLINKER) {
      m_dyld.address = addr;
      ModuleSP dyld_module_sp;
      if (ParseLoadCommands(data, m_dyld, &m_dyld.file_spec)) {
        if (m_dyld.file_spec) {
          UpdateDYLDImageInfoFromNewImageInfo(m_dyld);
        }
      }
      dyld_module_sp = GetDYLDModule();

      Target &target = m_process->GetTarget();

      if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS &&
          dyld_module_sp.get()) {
        const Symbol *symbol = dyld_module_sp->FindFirstSymbolWithNameAndType(
            g_dyld_all_image_infos, eSymbolTypeData);
        if (symbol)
          m_dyld_all_image_infos_addr = symbol->GetLoadAddress(&target);
      }

      // Update all image infos
      InitializeFromAllImageInfos();

      // If we didn't have an executable before, but now we do, then the dyld
      // module shared pointer might be unique and we may need to add it again
      // (since Target::SetExecutableModule() will clear the images). So append
      // the dyld module back to the list if it is
      /// unique!
      if (dyld_module_sp) {
        target.GetImages().AppendIfNeeded(dyld_module_sp);

        // At this point we should have read in dyld's module, and so we should
        // set breakpoints in it:
        ModuleList modules;
        modules.Append(dyld_module_sp);
        target.ModulesDidLoad(modules);
        SetDYLDModule(dyld_module_sp);
      }

      return true;
    }
  }
  return false;
}

bool DynamicLoaderMacOSXDYLD::NeedToDoInitialImageFetch() {
  return m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS;
}

// 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 DynamicLoaderMacOSXDYLD::NotifyBreakpointHit(
    void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id,
    lldb::user_id_t break_loc_id) {
  // Let the event know that the images have changed
  // DYLD passes three arguments to the notification breakpoint.
  // Arg1: enum dyld_image_mode mode - 0 = adding, 1 = removing Arg2: uint32_t
  // infoCount        - Number of shared libraries added Arg3: dyld_image_info
  // info[]    - Array of structs of the form:
  //                                     const struct mach_header
  //                                     *imageLoadAddress
  //                                     const char               *imageFilePath
  //                                     uintptr_t imageFileModDate (a time_t)

  DynamicLoaderMacOSXDYLD *dyld_instance = (DynamicLoaderMacOSXDYLD *)baton;

  // First step is to see if we've already initialized the all image infos.  If
  // we haven't then this function will do so and return true.  In the course
  // of initializing the all_image_infos it will read the complete current
  // state, so we don't need to figure out what has changed from the data
  // passed in to us.

  ExecutionContext exe_ctx(context->exe_ctx_ref);
  Process *process = exe_ctx.GetProcessPtr();

  // This is a sanity check just in case this dyld_instance is an old dyld
  // plugin's breakpoint still lying around.
  if (process != dyld_instance->m_process)
    return false;

  if (dyld_instance->InitializeFromAllImageInfos())
    return dyld_instance->GetStopWhenImagesChange();

  const lldb::ABISP &abi = process->GetABI();
  if (abi) {
    // Build up the value array to store the three arguments given above, then
    // get the values from the ABI:

    TypeSystemClang *clang_ast_context =
        ScratchTypeSystemClang::GetForTarget(process->GetTarget());
    if (!clang_ast_context)
      return false;

    ValueList argument_values;
    Value input_value;

    CompilerType clang_void_ptr_type =
        clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
    CompilerType clang_uint32_type =
        clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
            lldb::eEncodingUint, 32);
    input_value.SetValueType(Value::ValueType::Scalar);
    input_value.SetCompilerType(clang_uint32_type);
    //        input_value.SetContext (Value::eContextTypeClangType,
    //        clang_uint32_type);
    argument_values.PushValue(input_value);
    argument_values.PushValue(input_value);
    input_value.SetCompilerType(clang_void_ptr_type);
    //        input_value.SetContext (Value::eContextTypeClangType,
    //        clang_void_ptr_type);
    argument_values.PushValue(input_value);

    if (abi->GetArgumentValues(exe_ctx.GetThreadRef(), argument_values)) {
      uint32_t dyld_mode =
          argument_values.GetValueAtIndex(0)->GetScalar().UInt(-1);
      if (dyld_mode != static_cast<uint32_t>(-1)) {
        // Okay the mode was right, now get the number of elements, and the
        // array of new elements...
        uint32_t image_infos_count =
            argument_values.GetValueAtIndex(1)->GetScalar().UInt(-1);
        if (image_infos_count != static_cast<uint32_t>(-1)) {
          // Got the number added, now go through the array of added elements,
          // putting out the mach header address, and adding the image. Note,
          // I'm not putting in logging here, since the AddModules &
          // RemoveModules functions do all the logging internally.

          lldb::addr_t image_infos_addr =
              argument_values.GetValueAtIndex(2)->GetScalar().ULongLong();
          if (dyld_mode == 0) {
            // This is add:
            dyld_instance->AddModulesUsingImageInfosAddress(image_infos_addr,
                                                            image_infos_count);
          } else {
            // This is remove:
            dyld_instance->RemoveModulesUsingImageInfosAddress(
                image_infos_addr, image_infos_count);
          }
        }
      }
    }
  } else {
    process->GetTarget().GetDebugger().GetAsyncErrorStream()->Printf(
        "No ABI plugin located for triple %s -- shared libraries will not be "
        "registered!\n",
        process->GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
  }

  // Return true to stop the target, false to just let the target run
  return dyld_instance->GetStopWhenImagesChange();
}

bool DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure() {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  // the all image infos is already valid for this process stop ID
  if (m_process->GetStopID() == m_dyld_all_image_infos_stop_id)
    return true;

  m_dyld_all_image_infos.Clear();
  if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) {
    ByteOrder byte_order =
        m_process->GetTarget().GetArchitecture().GetByteOrder();
    uint32_t addr_size =
        m_process->GetTarget().GetArchitecture().GetAddressByteSize();

    uint8_t buf[256];
    DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
    lldb::offset_t offset = 0;

    const size_t count_v2 = sizeof(uint32_t) + // version
                            sizeof(uint32_t) + // infoArrayCount
                            addr_size +        // infoArray
                            addr_size +        // notification
                            addr_size + // processDetachedFromSharedRegion +
                                        // libSystemInitialized + pad
                            addr_size;  // dyldImageLoadAddress
    const size_t count_v11 = count_v2 + addr_size +  // jitInfo
                             addr_size +             // dyldVersion
                             addr_size +             // errorMessage
                             addr_size +             // terminationFlags
                             addr_size +             // coreSymbolicationShmPage
                             addr_size +             // systemOrderFlag
                             addr_size +             // uuidArrayCount
                             addr_size +             // uuidArray
                             addr_size +             // dyldAllImageInfosAddress
                             addr_size +             // initialImageCount
                             addr_size +             // errorKind
                             addr_size +             // errorClientOfDylibPath
                             addr_size +             // errorTargetDylibPath
                             addr_size;              // errorSymbol
    const size_t count_v13 = count_v11 + addr_size + // sharedCacheSlide
                             sizeof(uuid_t);         // sharedCacheUUID
    UNUSED_IF_ASSERT_DISABLED(count_v13);
    assert(sizeof(buf) >= count_v13);

    Status error;
    if (m_process->ReadMemory(m_dyld_all_image_infos_addr, buf, 4, error) ==
        4) {
      m_dyld_all_image_infos.version = data.GetU32(&offset);
      // If anything in the high byte is set, we probably got the byte order
      // incorrect (the process might not have it set correctly yet due to
      // attaching to a program without a specified file).
      if (m_dyld_all_image_infos.version & 0xff000000) {
        // We have guessed the wrong byte order. Swap it and try reading the
        // version again.
        if (byte_order == eByteOrderLittle)
          byte_order = eByteOrderBig;
        else
          byte_order = eByteOrderLittle;

        data.SetByteOrder(byte_order);
        offset = 0;
        m_dyld_all_image_infos.version = data.GetU32(&offset);
      }
    } else {
      return false;
    }

    const size_t count =
        (m_dyld_all_image_infos.version >= 11) ? count_v11 : count_v2;

    const size_t bytes_read =
        m_process->ReadMemory(m_dyld_all_image_infos_addr, buf, count, error);
    if (bytes_read == count) {
      offset = 0;
      m_dyld_all_image_infos.version = data.GetU32(&offset);
      m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset);
      m_dyld_all_image_infos.dylib_info_addr = data.GetAddress(&offset);
      m_dyld_all_image_infos.notification = data.GetAddress(&offset);
      m_dyld_all_image_infos.processDetachedFromSharedRegion =
          data.GetU8(&offset);
      m_dyld_all_image_infos.libSystemInitialized = data.GetU8(&offset);
      // Adjust for padding.
      offset += addr_size - 2;
      m_dyld_all_image_infos.dyldImageLoadAddress = data.GetAddress(&offset);
      if (m_dyld_all_image_infos.version >= 11) {
        offset += addr_size * 8;
        uint64_t dyld_all_image_infos_addr = data.GetAddress(&offset);

        // When we started, we were given the actual address of the
        // all_image_infos struct (probably via TASK_DYLD_INFO) in memory -
        // this address is stored in m_dyld_all_image_infos_addr and is the
        // most accurate address we have.

        // We read the dyld_all_image_infos struct from memory; it contains its
        // own address. If the address in the struct does not match the actual
        // address, the dyld we're looking at has been loaded at a different
        // location (slid) from where it intended to load.  The addresses in
        // the dyld_all_image_infos struct are the original, non-slid
        // addresses, and need to be adjusted.  Most importantly the address of
        // dyld and the notification address need to be adjusted.

        if (dyld_all_image_infos_addr != m_dyld_all_image_infos_addr) {
          uint64_t image_infos_offset =
              dyld_all_image_infos_addr -
              m_dyld_all_image_infos.dyldImageLoadAddress;
          uint64_t notification_offset =
              m_dyld_all_image_infos.notification -
              m_dyld_all_image_infos.dyldImageLoadAddress;
          m_dyld_all_image_infos.dyldImageLoadAddress =
              m_dyld_all_image_infos_addr - image_infos_offset;
          m_dyld_all_image_infos.notification =
              m_dyld_all_image_infos.dyldImageLoadAddress + notification_offset;
        }
      }
      m_dyld_all_image_infos_stop_id = m_process->GetStopID();
      return true;
    }
  }
  return false;
}

bool DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress(
    lldb::addr_t image_infos_addr, uint32_t image_infos_count) {
  ImageInfo::collection image_infos;
  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
  LLDB_LOGF(log, "Adding %d modules.\n", image_infos_count);

  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
  if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
    return true;

  StructuredData::ObjectSP image_infos_json_sp =
      m_process->GetLoadedDynamicLibrariesInfos(image_infos_addr,
                                                image_infos_count);
  if (image_infos_json_sp.get() && image_infos_json_sp->GetAsDictionary() &&
      image_infos_json_sp->GetAsDictionary()->HasKey("images") &&
      image_infos_json_sp->GetAsDictionary()
          ->GetValueForKey("images")
          ->GetAsArray() &&
      image_infos_json_sp->GetAsDictionary()
              ->GetValueForKey("images")
              ->GetAsArray()
              ->GetSize() == image_infos_count) {
    bool return_value = false;
    if (JSONImageInformationIntoImageInfo(image_infos_json_sp, image_infos)) {
      UpdateSpecialBinariesFromNewImageInfos(image_infos);
      return_value = AddModulesUsingImageInfos(image_infos);
    }
    m_dyld_image_infos_stop_id = m_process->GetStopID();
    return return_value;
  }

  if (!ReadImageInfos(image_infos_addr, image_infos_count, image_infos))
    return false;

  UpdateImageInfosHeaderAndLoadCommands(image_infos, image_infos_count, false);
  bool return_value = AddModulesUsingImageInfos(image_infos);
  m_dyld_image_infos_stop_id = m_process->GetStopID();
  return return_value;
}

bool DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress(
    lldb::addr_t image_infos_addr, uint32_t image_infos_count) {
  ImageInfo::collection image_infos;
  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));

  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
  if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
    return true;

  // First read in the image_infos for the removed modules, and their headers &
  // load commands.
  if (!ReadImageInfos(image_infos_addr, image_infos_count, image_infos)) {
    if (log)
      log->PutCString("Failed reading image infos array.");
    return false;
  }

  LLDB_LOGF(log, "Removing %d modules.", image_infos_count);

  ModuleList unloaded_module_list;
  for (uint32_t idx = 0; idx < image_infos.size(); ++idx) {
    if (log) {
      LLDB_LOGF(log, "Removing module at address=0x%16.16" PRIx64 ".",
                image_infos[idx].address);
      image_infos[idx].PutToLog(log);
    }

    // Remove this image_infos from the m_all_image_infos.  We do the
    // comparison by address rather than by file spec because we can have many
    // modules with the same "file spec" in the case that they are modules
    // loaded from memory.
    //
    // Also copy over the uuid from the old entry to the removed entry so we
    // can use it to lookup the module in the module list.

    ImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
    for (pos = m_dyld_image_infos.begin(); pos != end; pos++) {
      if (image_infos[idx].address == (*pos).address) {
        image_infos[idx].uuid = (*pos).uuid;

        // Add the module from this image_info to the "unloaded_module_list".
        // We'll remove them all at one go later on.

        ModuleSP unload_image_module_sp(
            FindTargetModuleForImageInfo(image_infos[idx], false, nullptr));
        if (unload_image_module_sp.get()) {
          // When we unload, be sure to use the image info from the old list,
          // since that has sections correctly filled in.
          UnloadModuleSections(unload_image_module_sp.get(), *pos);
          unloaded_module_list.AppendIfNeeded(unload_image_module_sp);
        } else {
          if (log) {
            LLDB_LOGF(log, "Could not find module for unloading info entry:");
            image_infos[idx].PutToLog(log);
          }
        }

        // Then remove it from the m_dyld_image_infos:

        m_dyld_image_infos.erase(pos);
        break;
      }
    }

    if (pos == end) {
      if (log) {
        LLDB_LOGF(log, "Could not find image_info entry for unloading image:");
        image_infos[idx].PutToLog(log);
      }
    }
  }
  if (unloaded_module_list.GetSize() > 0) {
    if (log) {
      log->PutCString("Unloaded:");
      unloaded_module_list.LogUUIDAndPaths(
          log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload");
    }
    m_process->GetTarget().GetImages().Remove(unloaded_module_list);
  }
  m_dyld_image_infos_stop_id = m_process->GetStopID();
  return true;
}

bool DynamicLoaderMacOSXDYLD::ReadImageInfos(
    lldb::addr_t image_infos_addr, uint32_t image_infos_count,
    ImageInfo::collection &image_infos) {
  std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
  const ByteOrder endian = GetByteOrderFromMagic(m_dyld.header.magic);
  const uint32_t addr_size = m_dyld.GetAddressByteSize();

  image_infos.resize(image_infos_count);
  const size_t count = image_infos.size() * 3 * addr_size;
  DataBufferHeap info_data(count, 0);
  Status error;
  const size_t bytes_read = m_process->ReadMemory(
      image_infos_addr, info_data.GetBytes(), info_data.GetByteSize(), error);
  if (bytes_read == count) {
    lldb::offset_t info_data_offset = 0;
    DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(),
                                endian, addr_size);
    for (size_t i = 0;
         i < image_infos.size() && info_data_ref.ValidOffset(info_data_offset);
         i++) {
      image_infos[i].address = info_data_ref.GetAddress(&info_data_offset);
      lldb::addr_t path_addr = info_data_ref.GetAddress(&info_data_offset);
      image_infos[i].mod_date = info_data_ref.GetAddress(&info_data_offset);

      char raw_path[PATH_MAX];
      m_process->ReadCStringFromMemory(path_addr, raw_path, sizeof(raw_path),
                                       error);
      // don't resolve the path
      if (error.Success()) {
        image_infos[i].file_spec.SetFile(raw_path, FileSpec::Style::native);
      }
    }
    return true;
  } else {
    return false;
  }
}

// If we have found where the "_dyld_all_image_infos" lives in memory, read the
// current info from it, and then update all image load addresses (or lack
// thereof).  Only do this if this is the first time we're reading the dyld
// infos.  Return true if we actually read anything, and false otherwise.
bool DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos() {
  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));

  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
  if (m_process->GetStopID() == m_dyld_image_infos_stop_id ||
      m_dyld_image_infos.size() != 0)
    return false;

  if (ReadAllImageInfosStructure()) {
    // Nothing to load or unload?
    if (m_dyld_all_image_infos.dylib_info_count == 0)
      return true;

    if (m_dyld_all_image_infos.dylib_info_addr == 0) {
      // DYLD is updating the images now.  So we should say we have no images,
      // and then we'll
      // figure it out when we hit the added breakpoint.
      return false;
    } else {
      if (!AddModulesUsingImageInfosAddress(
              m_dyld_all_image_infos.dylib_info_addr,
              m_dyld_all_image_infos.dylib_info_count)) {
        DEBUG_PRINTF("%s", "unable to read all data for all_dylib_infos.");
        m_dyld_image_infos.clear();
      }
    }

    // Now we have one more bit of business.  If there is a library left in the
    // images for our target that doesn't have a load address, then it must be
    // something that we were expecting to load (for instance we read a load
    // command for it) but it didn't in fact load - probably because
    // DYLD_*_PATH pointed to an equivalent version.  We don't want it to stay
    // in the target's module list or it will confuse us, so unload it here.
    Target &target = m_process->GetTarget();
    ModuleList not_loaded_modules;
    for (ModuleSP module_sp : target.GetImages().Modules()) {
      if (!module_sp->IsLoadedInTarget(&target)) {
        if (log) {
          StreamString s;
          module_sp->GetDescription(s.AsRawOstream());
          LLDB_LOGF(log, "Unloading pre-run module: %s.", s.GetData());
        }
        not_loaded_modules.Append(module_sp);
      }
    }

    if (not_loaded_modules.GetSize() != 0) {
      target.GetImages().Remove(not_loaded_modules);
    }

    return true;
  } else
    return false;
}

// Read a mach_header at ADDR into HEADER, and also fill in the load command
// data into LOAD_COMMAND_DATA if it is non-NULL.
//
// Returns true if we succeed, false if we fail for any reason.
bool DynamicLoaderMacOSXDYLD::ReadMachHeader(lldb::addr_t addr,
                                             llvm::MachO::mach_header *header,
                                             DataExtractor *load_command_data) {
  DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0);
  Status error;
  size_t bytes_read = m_process->ReadMemory(addr, header_bytes.GetBytes(),
                                            header_bytes.GetByteSize(), error);
  if (bytes_read == sizeof(llvm::MachO::mach_header)) {
    lldb::offset_t offset = 0;
    ::memset(header, 0, sizeof(llvm::MachO::mach_header));

    // Get the magic byte unswapped so we can figure out what we are dealing
    // with
    DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(),
                       endian::InlHostByteOrder(), 4);
    header->magic = data.GetU32(&offset);
    lldb::addr_t load_cmd_addr = addr;
    data.SetByteOrder(
        DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header->magic));
    switch (header->magic) {
    case llvm::MachO::MH_MAGIC:
    case llvm::MachO::MH_CIGAM:
      data.SetAddressByteSize(4);
      load_cmd_addr += sizeof(llvm::MachO::mach_header);
      break;

    case llvm::MachO::MH_MAGIC_64:
    case llvm::MachO::MH_CIGAM_64:
      data.SetAddressByteSize(8);
      load_cmd_addr += sizeof(llvm::MachO::mach_header_64);
      break;

    default:
      return false;
    }

    // Read the rest of dyld's mach header
    if (data.GetU32(&offset, &header->cputype,
                    (sizeof(llvm::MachO::mach_header) / sizeof(uint32_t)) -
                        1)) {
      if (load_command_data == nullptr)
        return true; // We were able to read the mach_header and weren't asked
                     // to read the load command bytes

      DataBufferSP load_cmd_data_sp(new DataBufferHeap(header->sizeofcmds, 0));

      size_t load_cmd_bytes_read =
          m_process->ReadMemory(load_cmd_addr, load_cmd_data_sp->GetBytes(),
                                load_cmd_data_sp->GetByteSize(), error);

      if (load_cmd_bytes_read == header->sizeofcmds) {
        // Set the load command data and also set the correct endian swap
        // settings and the correct address size
        load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds);
        load_command_data->SetByteOrder(data.GetByteOrder());
        load_command_data->SetAddressByteSize(data.GetAddressByteSize());
        return true; // We successfully read the mach_header and the load
                     // command data
      }

      return false; // We weren't able to read the load command data
    }
  }
  return false; // We failed the read the mach_header
}

// Parse the load commands for an image
uint32_t DynamicLoaderMacOSXDYLD::ParseLoadCommands(const DataExtractor &data,
                                                    ImageInfo &dylib_info,
                                                    FileSpec *lc_id_dylinker) {
  lldb::offset_t offset = 0;
  uint32_t cmd_idx;
  Segment segment;
  dylib_info.Clear(true);

  for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++) {
    // Clear out any load command specific data from DYLIB_INFO since we are
    // about to read it.

    if (data.ValidOffsetForDataOfSize(offset,
                                      sizeof(llvm::MachO::load_command))) {
      llvm::MachO::load_command load_cmd;
      lldb::offset_t load_cmd_offset = offset;
      load_cmd.cmd = data.GetU32(&offset);
      load_cmd.cmdsize = data.GetU32(&offset);
      switch (load_cmd.cmd) {
      case llvm::MachO::LC_SEGMENT: {
        segment.name.SetTrimmedCStringWithLength(
            (const char *)data.GetData(&offset, 16), 16);
        // We are putting 4 uint32_t values 4 uint64_t values so we have to use
        // multiple 32 bit gets below.
        segment.vmaddr = data.GetU32(&offset);
        segment.vmsize = data.GetU32(&offset);
        segment.fileoff = data.GetU32(&offset);
        segment.filesize = data.GetU32(&offset);
        // Extract maxprot, initprot, nsects and flags all at once
        data.GetU32(&offset, &segment.maxprot, 4);
        dylib_info.segments.push_back(segment);
      } break;

      case llvm::MachO::LC_SEGMENT_64: {
        segment.name.SetTrimmedCStringWithLength(
            (const char *)data.GetData(&offset, 16), 16);
        // Extract vmaddr, vmsize, fileoff, and filesize all at once
        data.GetU64(&offset, &segment.vmaddr, 4);
        // Extract maxprot, initprot, nsects and flags all at once
        data.GetU32(&offset, &segment.maxprot, 4);
        dylib_info.segments.push_back(segment);
      } break;

      case llvm::MachO::LC_ID_DYLINKER:
        if (lc_id_dylinker) {
          const lldb::offset_t name_offset =
              load_cmd_offset + data.GetU32(&offset);
          const char *path = data.PeekCStr(name_offset);
          lc_id_dylinker->SetFile(path, FileSpec::Style::native);
          FileSystem::Instance().Resolve(*lc_id_dylinker);
        }
        break;

      case llvm::MachO::LC_UUID:
        dylib_info.uuid = UUID::fromOptionalData(data.GetData(&offset, 16), 16);
        break;

      default:
        break;
      }
      // Set offset to be the beginning of the next load command.
      offset = load_cmd_offset + load_cmd.cmdsize;
    }
  }

  // All sections listed in the dyld image info structure will all either be
  // fixed up already, or they will all be off by a single slide amount that is
  // determined by finding the first segment that is at file offset zero which
  // also has bytes (a file size that is greater than zero) in the object file.

  // Determine the slide amount (if any)
  const size_t num_sections = dylib_info.segments.size();
  for (size_t i = 0; i < num_sections; ++i) {
    // Iterate through the object file sections to find the first section that
    // starts of file offset zero and that has bytes in the file...
    if ((dylib_info.segments[i].fileoff == 0 &&
         dylib_info.segments[i].filesize > 0) ||
        (dylib_info.segments[i].name == "__TEXT")) {
      dylib_info.slide = dylib_info.address - dylib_info.segments[i].vmaddr;
      // We have found the slide amount, so we can exit this for loop.
      break;
    }
  }
  return cmd_idx;
}

// Read the mach_header and load commands for each image that the
// _dyld_all_image_infos structure points to and cache the results.

void DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(
    ImageInfo::collection &image_infos, uint32_t infos_count,
    bool update_executable) {
  uint32_t exe_idx = UINT32_MAX;
  // Read any UUID values that we can get
  for (uint32_t i = 0; i < infos_count; i++) {
    if (!image_infos[i].UUIDValid()) {
      DataExtractor data; // Load command data
      if (!ReadMachHeader(image_infos[i].address, &image_infos[i].header,
                          &data))
        continue;

      ParseLoadCommands(data, image_infos[i], nullptr);

      if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE)
        exe_idx = i;
    }
  }

  Target &target = m_process->GetTarget();

  if (exe_idx < image_infos.size()) {
    const bool can_create = true;
    ModuleSP exe_module_sp(FindTargetModuleForImageInfo(image_infos[exe_idx],
                                                        can_create, nullptr));

    if (exe_module_sp) {
      UpdateImageLoadAddress(exe_module_sp.get(), image_infos[exe_idx]);

      if (exe_module_sp.get() != target.GetExecutableModulePointer()) {
        // Don't load dependent images since we are in dyld where we will know
        // and find out about all images that are loaded. Also when setting the
        // executable module, it will clear the targets module list, and if we
        // have an in memory dyld module, it will get removed from the list so
        // we will need to add it back after setting the executable module, so
        // we first try and see if we already have a weak pointer to the dyld
        // module, make it into a shared pointer, then add the executable, then
        // re-add it back to make sure it is always in the list.
        ModuleSP dyld_module_sp(GetDYLDModule());

        m_process->GetTarget().SetExecutableModule(exe_module_sp,
                                                   eLoadDependentsNo);

        if (dyld_module_sp) {
          if (target.GetImages().AppendIfNeeded(dyld_module_sp)) {
            std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());

            // Also add it to the section list.
            UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
          }
        }
      }
    }
  }
}

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

  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
  LLDB_LOGF(log,
            "dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8" PRIx64
            ", notify=0x%8.8" PRIx64 " }",
            m_dyld_all_image_infos.version,
            m_dyld_all_image_infos.dylib_info_count,
            (uint64_t)m_dyld_all_image_infos.dylib_info_addr,
            (uint64_t)m_dyld_all_image_infos.notification);
  size_t i;
  const size_t count = m_dyld_image_infos.size();
  if (count > 0) {
    log->PutCString("Loaded:");
    for (i = 0; i < count; i++)
      m_dyld_image_infos[i].PutToLog(log);
  }
}

bool DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint() {
  DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n",
               __FUNCTION__, StateAsCString(m_process->GetState()));
  if (m_break_id == LLDB_INVALID_BREAK_ID) {
    if (m_dyld_all_image_infos.notification != LLDB_INVALID_ADDRESS) {
      Address so_addr;
      // Set the notification breakpoint and install a breakpoint callback
      // function that will get called each time the breakpoint gets hit. We
      // will use this to track when shared libraries get loaded/unloaded.
      bool resolved = m_process->GetTarget().ResolveLoadAddress(
          m_dyld_all_image_infos.notification, so_addr);
      if (!resolved) {
        ModuleSP dyld_module_sp = GetDYLDModule();
        if (dyld_module_sp) {
          std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());

          UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
          resolved = m_process->GetTarget().ResolveLoadAddress(
              m_dyld_all_image_infos.notification, so_addr);
        }
      }

      if (resolved) {
        Breakpoint *dyld_break =
            m_process->GetTarget().CreateBreakpoint(so_addr, true, false).get();
        dyld_break->SetCallback(DynamicLoaderMacOSXDYLD::NotifyBreakpointHit,
                                this, true);
        dyld_break->SetBreakpointKind("shared-library-event");
        m_break_id = dyld_break->GetID();
      }
    }
  }
  return m_break_id != LLDB_INVALID_BREAK_ID;
}

Status DynamicLoaderMacOSXDYLD::CanLoadImage() {
  Status error;
  // In order for us to tell if we can load a shared library we verify that the
  // dylib_info_addr isn't zero (which means no shared libraries have been set
  // yet, or dyld is currently mucking with the shared library list).
  if (ReadAllImageInfosStructure()) {
    // TODO: also check the _dyld_global_lock_held variable in
    // libSystem.B.dylib?
    // TODO: check the malloc lock?
    // TODO: check the objective C lock?
    if (m_dyld_all_image_infos.dylib_info_addr != 0)
      return error; // Success
  }

  error.SetErrorString("unsafe to load or unload shared libraries");
  return error;
}

bool DynamicLoaderMacOSXDYLD::GetSharedCacheInformation(
    lldb::addr_t &base_address, UUID &uuid, LazyBool &using_shared_cache,
    LazyBool &private_shared_cache) {
  base_address = LLDB_INVALID_ADDRESS;
  uuid.Clear();
  using_shared_cache = eLazyBoolCalculate;
  private_shared_cache = eLazyBoolCalculate;

  if (m_process) {
    addr_t all_image_infos = m_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.

    Status err;
    uint32_t version_or_magic =
        m_process->ReadUnsignedIntegerFromMemory(all_image_infos, 4, -1, err);
    if (version_or_magic != static_cast<uint32_t>(-1) &&
        version_or_magic != llvm::MachO::MH_MAGIC &&
        version_or_magic != llvm::MachO::MH_CIGAM &&
        version_or_magic != llvm::MachO::MH_MAGIC_64 &&
        version_or_magic != llvm::MachO::MH_CIGAM_64 &&
        version_or_magic >= 13) {
      addr_t sharedCacheUUID_address = LLDB_INVALID_ADDRESS;
      int wordsize = m_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 (m_process->ReadMemory(sharedCacheUUID_address, shared_cache_uuid,
                                  sizeof(uuid_t), err) == sizeof(uuid_t)) {
          uuid = UUID::fromOptionalData(shared_cache_uuid, 16);
          if (uuid.IsValid()) {
            using_shared_cache = eLazyBoolYes;
          }
        }

        if (version_or_magic >= 15) {
          // The sharedCacheBaseAddress field is the next one in the
          // dyld_all_image_infos struct.
          addr_t sharedCacheBaseAddr_address = sharedCacheUUID_address + 16;
          Status error;
          base_address = m_process->ReadUnsignedIntegerFromMemory(
              sharedCacheBaseAddr_address, wordsize, LLDB_INVALID_ADDRESS,
              error);
          if (error.Fail())
            base_address = LLDB_INVALID_ADDRESS;
        }

        return true;
      }

      //
      // add
      // NB: sharedCacheBaseAddress is the next field in dyld_all_image_infos
      // after
      // sharedCacheUUID -- that is, 16 bytes after it, if we wanted to fetch
      // it.
    }
  }
  return false;
}

void DynamicLoaderMacOSXDYLD::Initialize() {
  PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                GetPluginDescriptionStatic(), CreateInstance);
  DynamicLoaderMacOS::Initialize();
}

void DynamicLoaderMacOSXDYLD::Terminate() {
  DynamicLoaderMacOS::Terminate();
  PluginManager::UnregisterPlugin(CreateInstance);
}

lldb_private::ConstString DynamicLoaderMacOSXDYLD::GetPluginNameStatic() {
  static ConstString g_name("macosx-dyld");
  return g_name;
}

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

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

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

uint32_t DynamicLoaderMacOSXDYLD::AddrByteSize() {
  std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());

  switch (m_dyld.header.magic) {
  case llvm::MachO::MH_MAGIC:
  case llvm::MachO::MH_CIGAM:
    return 4;

  case llvm::MachO::MH_MAGIC_64:
  case llvm::MachO::MH_CIGAM_64:
    return 8;

  default:
    break;
  }
  return 0;
}

lldb::ByteOrder DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(uint32_t magic) {
  switch (magic) {
  case llvm::MachO::MH_MAGIC:
  case llvm::MachO::MH_MAGIC_64:
    return endian::InlHostByteOrder();

  case llvm::MachO::MH_CIGAM:
  case llvm::MachO::MH_CIGAM_64:
    if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
      return lldb::eByteOrderLittle;
    else
      return lldb::eByteOrderBig;

  default:
    break;
  }
  return lldb::eByteOrderInvalid;
}
