//===-- ObjectFile.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 "lldb/Symbol/ObjectFile.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Symbol/CallFrameInfo.h"
#include "lldb/Symbol/ObjectContainer.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Timer.h"
#include "lldb/lldb-private.h"

#include "llvm/Support/DJB.h"

using namespace lldb;
using namespace lldb_private;

char ObjectFile::ID;
size_t ObjectFile::g_initial_bytes_to_read = 512;

static ObjectFileSP
CreateObjectFromContainer(const lldb::ModuleSP &module_sp, const FileSpec *file,
                          lldb::offset_t file_offset, lldb::offset_t file_size,
                          DataBufferSP data_sp, lldb::offset_t &data_offset) {
  for (auto &cbs : PluginManager::GetObjectContainerCallbacks()) {
    std::unique_ptr<ObjectContainer> object_container_up(cbs.create_callback(
        module_sp, data_sp, data_offset, file, file_offset, file_size));
    if (object_container_up)
      return object_container_up->GetObjectFile(file);
  }
  return {};
}

ObjectFileSP ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp,
                                    const FileSpec *file,
                                    lldb::offset_t file_offset,
                                    lldb::offset_t file_size,
                                    DataExtractorSP extractor_sp,
                                    lldb::offset_t &data_offset) {
  LLDB_SCOPED_TIMERF(
      "ObjectFile::FindPlugin (module = %s, file = %p, file_offset = "
      "0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")",
      module_sp->GetFileSpec().GetPath().c_str(),
      static_cast<const void *>(file), static_cast<uint64_t>(file_offset),
      static_cast<uint64_t>(file_size));

  if (!module_sp)
    return {};

  if (!file)
    return {};

  if (!extractor_sp || !extractor_sp->HasData()) {
    const bool file_exists = FileSystem::Instance().Exists(*file);
    // We have an object name which most likely means we have a .o file in
    // a static archive (.a file). Try and see if we have a cached archive
    // first without reading any data first
    if (file_exists && module_sp->GetObjectName()) {
      ObjectFileSP object_file_sp = CreateObjectFromContainer(
          module_sp, file, file_offset, file_size, DataBufferSP(), data_offset);
      if (object_file_sp)
        return object_file_sp;
    }
    // Ok, we didn't find any containers that have a named object, now lets
    // read the first 512 bytes from the file so the object file and object
    // container plug-ins can use these bytes to see if they can parse this
    // file.
    if (file_size > 0) {
      // Check that we made a data buffer. For instance, a directory node is
      // not 0 size, but we can't make a data buffer for it.
      if (DataBufferSP buffer_sp = FileSystem::Instance().CreateDataBuffer(
              file->GetPath(), g_initial_bytes_to_read, file_offset)) {
        extractor_sp = std::make_shared<DataExtractor>(buffer_sp);
        data_offset = 0;
      }
    }
  }

  if (!extractor_sp || !extractor_sp->HasData()) {
    // Check for archive file with format "/path/to/archive.a(object.o)"
    llvm::SmallString<256> path_with_object;
    module_sp->GetFileSpec().GetPath(path_with_object);

    FileSpec archive_file;
    llvm::StringRef archive_object;
    const bool must_exist = true;
    if (ObjectFile::SplitArchivePathWithObject(path_with_object, archive_file,
                                               archive_object, must_exist)) {
      file_size = FileSystem::Instance().GetByteSize(archive_file);
      if (file_size > 0) {
        file = &archive_file;
        module_sp->SetFileSpecAndObjectName(archive_file,
                                            ConstString(archive_object));
        // Check if this is a object container by iterating through all
        // object container plugin instances and then trying to get an
        // object file from the container plugins since we had a name.
        // Also, don't read
        // ANY data in case there is data cached in the container plug-ins
        // (like BSD archives caching the contained objects within an
        // file).
        ObjectFileSP object_file_sp =
            CreateObjectFromContainer(module_sp, file, file_offset, file_size,
                                      DataBufferSP(), data_offset);
        if (object_file_sp)
          return object_file_sp;
        // We failed to find any cached object files in the container plug-
        // ins, so lets read the first 512 bytes and try again below...
        DataBufferSP buffer_sp = FileSystem::Instance().CreateDataBuffer(
            archive_file.GetPath(), g_initial_bytes_to_read, file_offset);
        extractor_sp = std::make_shared<DataExtractor>(buffer_sp);
      }
    }
  }

  if (extractor_sp && extractor_sp->HasData()) {
    // Check if this is a normal object file by iterating through all
    // object file plugin instances.
    for (auto &cbs : PluginManager::GetObjectFileCallbacks()) {
      // Make a copy of the extractor in case any plugin modifies it while
      // processing.
      DataExtractorSP extractor_copy_sp = extractor_sp->Clone();
      ObjectFileSP object_file_sp(
          cbs.create_callback(module_sp, extractor_copy_sp, data_offset, file,
                              file_offset, file_size));
      if (object_file_sp.get())
        return object_file_sp;
    }

    // Check if this is a object container by iterating through all object
    // container plugin instances and then trying to get an object file
    // from the container.
    DataBufferSP buffer_sp = extractor_sp->GetSharedDataBuffer();
    ObjectFileSP object_file_sp = CreateObjectFromContainer(
        module_sp, file, file_offset, file_size, buffer_sp, data_offset);
    if (object_file_sp)
      return object_file_sp;
  }

  // We didn't find it, so clear our shared pointer in case it contains
  // anything and return an empty shared pointer
  return {};
}

ObjectFileSP ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp,
                                    const ProcessSP &process_sp,
                                    lldb::addr_t header_addr,
                                    WritableDataBufferSP data_sp) {
  ObjectFileSP object_file_sp;

  if (module_sp) {
    LLDB_SCOPED_TIMERF("ObjectFile::FindPlugin (module = "
                       "%s, process = %p, header_addr = "
                       "0x%" PRIx64 ")",
                       module_sp->GetFileSpec().GetPath().c_str(),
                       static_cast<void *>(process_sp.get()), header_addr);

    // Check if this is a normal object file by iterating through all object
    // file plugin instances.
    for (auto &cbs : PluginManager::GetObjectFileCallbacks()) {
      if (!cbs.create_memory_callback)
        continue;
      object_file_sp.reset(cbs.create_memory_callback(module_sp, data_sp,
                                                      process_sp, header_addr));
      if (object_file_sp.get())
        return object_file_sp;
    }
  }

  // We didn't find it, so clear our shared pointer in case it contains
  // anything and return an empty shared pointer
  object_file_sp.reset();
  return object_file_sp;
}

bool ObjectFile::IsObjectFile(lldb_private::FileSpec file_spec) {
  DataExtractorSP extractor_sp;
  offset_t data_offset = 0;
  ModuleSP module_sp = std::make_shared<Module>(file_spec);
  return static_cast<bool>(ObjectFile::FindPlugin(
      module_sp, &file_spec, 0, FileSystem::Instance().GetByteSize(file_spec),
      extractor_sp, data_offset));
}

ModuleSpecList ObjectFile::GetModuleSpecifications(
    const FileSpec &file, lldb::offset_t file_offset, lldb::offset_t file_size,
    DataExtractorSP extractor_sp) {
  if (!extractor_sp)
    extractor_sp = std::make_shared<DataExtractor>();
  if (!extractor_sp->HasData()) {
    if (DataBufferSP file_data_sp = FileSystem::Instance().CreateDataBuffer(
            file.GetPath(), g_initial_bytes_to_read, file_offset))
      extractor_sp->SetData(file_data_sp);
  }
  if (extractor_sp->HasData()) {
    if (file_size == 0) {
      const lldb::offset_t actual_file_size =
          FileSystem::Instance().GetByteSize(file);
      if (actual_file_size > file_offset)
        file_size = actual_file_size - file_offset;
    }
    return ObjectFile::GetModuleSpecifications(file, extractor_sp, file_offset,
                                               file_size);
  }
  return {};
}

ModuleSpecList ObjectFile::GetModuleSpecifications(
    const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp,
    lldb::offset_t file_offset, lldb::offset_t file_size) {
  ModuleSpecList specs;

  // A container can be embedded in an otherwise valid object file. Preserve
  // the object file's specifications and also query the container plug-ins.

  // Try the ObjectFile plug-ins
  for (auto &cbs : PluginManager::GetObjectFileCallbacks()) {
    ModuleSpecList object_specs = cbs.get_module_specifications(
        file, extractor_sp, file_offset, file_size);
    if (object_specs.GetSize() > 0) {
      specs.Append(object_specs);
      break;
    }
  }

  // Try the ObjectContainer plug-ins
  for (auto &cbs : PluginManager::GetObjectContainerCallbacks()) {
    ModuleSpecList container_specs = cbs.get_module_specifications(
        file, extractor_sp, file_offset, file_size);
    if (container_specs.GetSize() > 0)
      specs.Append(container_specs);
  }
  return specs;
}

ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp,
                       const FileSpec *file_spec_ptr,
                       lldb::offset_t file_offset, lldb::offset_t length,
                       lldb::DataExtractorSP extractor_sp,
                       lldb::offset_t data_offset)
    : ModuleChild(module_sp),
      m_file(), // This file could be different from the original module's file
      m_type(eTypeInvalid), m_strata(eStrataInvalid),
      m_file_offset(file_offset), m_length(length),
      m_data_nsp(std::make_shared<DataExtractor>()), m_process_wp(),
      m_memory_addr(LLDB_INVALID_ADDRESS), m_sections_up(), m_symtab_up(),
      m_symtab_once_up(new llvm::once_flag()) {
  if (file_spec_ptr)
    m_file = *file_spec_ptr;
  if (extractor_sp && extractor_sp->HasData()) {
    m_data_nsp = extractor_sp;
    // The offset & length fields may be specifying a subset of the
    // total data buffer.
    m_data_nsp->SetData(extractor_sp->GetSharedDataBuffer(), data_offset,
                        length);
  }
  Log *log = GetLog(LLDBLog::Object);
  LLDB_LOGF(log,
            "%p ObjectFile::ObjectFile() module = %p (%s), file = %s, "
            "file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64,
            static_cast<void *>(this), static_cast<void *>(module_sp.get()),
            module_sp->GetSpecificationDescription().c_str(),
            m_file ? m_file.GetPath().c_str() : "<NULL>", m_file_offset,
            m_length);
}

ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp,
                       const ProcessSP &process_sp, lldb::addr_t header_addr,
                       DataExtractorSP header_extractor_sp)
    : ModuleChild(module_sp), m_file(), m_type(eTypeInvalid),
      m_strata(eStrataInvalid), m_file_offset(0), m_length(0),
      m_data_nsp(std::make_shared<DataExtractor>()), m_process_wp(process_sp),
      m_memory_addr(header_addr), m_sections_up(), m_symtab_up(),
      m_symtab_once_up(new llvm::once_flag()) {
  if (header_extractor_sp && header_extractor_sp->HasData())
    m_data_nsp = header_extractor_sp;
  Log *log = GetLog(LLDBLog::Object);
  LLDB_LOGF(log,
            "%p ObjectFile::ObjectFile() module = %p (%s), process = %p, "
            "header_addr = 0x%" PRIx64,
            static_cast<void *>(this), static_cast<void *>(module_sp.get()),
            module_sp->GetSpecificationDescription().c_str(),
            static_cast<void *>(process_sp.get()), m_memory_addr);
}

ObjectFile::~ObjectFile() {
  Log *log = GetLog(LLDBLog::Object);
  LLDB_LOGF(log, "%p ObjectFile::~ObjectFile ()\n", static_cast<void *>(this));
}

bool ObjectFile::SetModulesArchitecture(const ArchSpec &new_arch) {
  ModuleSP module_sp(GetModule());
  if (module_sp)
    return module_sp->SetArchitecture(new_arch);
  return false;
}

AddressClass ObjectFile::GetAddressClass(addr_t file_addr) {
  Symtab *symtab = GetSymtab();
  if (symtab) {
    const Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
    if (symbol) {
      if (symbol->ValueIsAddress()) {
        const SectionSP section_sp(symbol->GetAddressRef().GetSection());
        if (section_sp) {
          const SectionType section_type = section_sp->GetType();
          switch (section_type) {
          case eSectionTypeInvalid:
            return AddressClass::eUnknown;
          case eSectionTypeCode:
            return AddressClass::eCode;
          case eSectionTypeContainer:
            return AddressClass::eUnknown;
          case eSectionTypeData:
          case eSectionTypeDataCString:
          case eSectionTypeDataCStringPointers:
          case eSectionTypeDataSymbolAddress:
          case eSectionTypeData4:
          case eSectionTypeData8:
          case eSectionTypeData16:
          case eSectionTypeDataPointers:
          case eSectionTypeZeroFill:
          case eSectionTypeDataObjCMessageRefs:
          case eSectionTypeDataObjCCFStrings:
          case eSectionTypeGoSymtab:
            return AddressClass::eData;
          case eSectionTypeDebug:
          case eSectionTypeDWARFDebugAbbrev:
          case eSectionTypeDWARFDebugAbbrevDwo:
          case eSectionTypeDWARFDebugAddr:
          case eSectionTypeDWARFDebugAranges:
          case eSectionTypeDWARFDebugCuIndex:
          case eSectionTypeDWARFDebugFrame:
          case eSectionTypeDWARFDebugInfo:
          case eSectionTypeDWARFDebugInfoDwo:
          case eSectionTypeDWARFDebugLine:
          case eSectionTypeDWARFDebugLineStr:
          case eSectionTypeDWARFDebugLoc:
          case eSectionTypeDWARFDebugLocDwo:
          case eSectionTypeDWARFDebugLocLists:
          case eSectionTypeDWARFDebugLocListsDwo:
          case eSectionTypeDWARFDebugMacInfo:
          case eSectionTypeDWARFDebugMacro:
          case eSectionTypeDWARFDebugNames:
          case eSectionTypeDWARFDebugPubNames:
          case eSectionTypeDWARFDebugPubTypes:
          case eSectionTypeDWARFDebugRanges:
          case eSectionTypeDWARFDebugRngLists:
          case eSectionTypeDWARFDebugRngListsDwo:
          case eSectionTypeDWARFDebugStr:
          case eSectionTypeDWARFDebugStrDwo:
          case eSectionTypeDWARFDebugStrOffsets:
          case eSectionTypeDWARFDebugStrOffsetsDwo:
          case eSectionTypeDWARFDebugTuIndex:
          case eSectionTypeDWARFDebugTypes:
          case eSectionTypeDWARFDebugTypesDwo:
          case eSectionTypeDWARFAppleNames:
          case eSectionTypeDWARFAppleTypes:
          case eSectionTypeDWARFAppleNamespaces:
          case eSectionTypeDWARFAppleObjC:
          case eSectionTypeDWARFGNUDebugAltLink:
          case eSectionTypeCTF:
          case eSectionTypeLLDBFormatters:
          case eSectionTypeLLDBTypeSummaries:
          case eSectionTypeSwiftModules:
            return AddressClass::eDebug;
          case eSectionTypeEHFrame:
          case eSectionTypeARMexidx:
          case eSectionTypeARMextab:
          case eSectionTypeCompactUnwind:
            return AddressClass::eRuntime;
          case eSectionTypeELFSymbolTable:
          case eSectionTypeELFDynamicSymbols:
          case eSectionTypeELFRelocationEntries:
          case eSectionTypeELFDynamicLinkInfo:
          case eSectionTypeWasmName:
          case eSectionTypeWasmGlobal:
          case eSectionTypeOther:
            return AddressClass::eUnknown;
          case eSectionTypeAbsoluteAddress:
            // In case of absolute sections decide the address class based on
            // the symbol type because the section type isn't specify if it is
            // a code or a data section.
            break;
          }
        }
      }

      const SymbolType symbol_type = symbol->GetType();
      switch (symbol_type) {
      case eSymbolTypeAny:
        return AddressClass::eUnknown;
      case eSymbolTypeAbsolute:
        return AddressClass::eUnknown;
      case eSymbolTypeCode:
        return AddressClass::eCode;
      case eSymbolTypeTrampoline:
        return AddressClass::eCode;
      case eSymbolTypeResolver:
        return AddressClass::eCode;
      case eSymbolTypeData:
        return AddressClass::eData;
      case eSymbolTypeRuntime:
        return AddressClass::eRuntime;
      case eSymbolTypeException:
        return AddressClass::eRuntime;
      case eSymbolTypeSourceFile:
        return AddressClass::eDebug;
      case eSymbolTypeHeaderFile:
        return AddressClass::eDebug;
      case eSymbolTypeObjectFile:
        return AddressClass::eDebug;
      case eSymbolTypeCommonBlock:
        return AddressClass::eDebug;
      case eSymbolTypeBlock:
        return AddressClass::eDebug;
      case eSymbolTypeLocal:
        return AddressClass::eData;
      case eSymbolTypeParam:
        return AddressClass::eData;
      case eSymbolTypeVariable:
        return AddressClass::eData;
      case eSymbolTypeVariableType:
        return AddressClass::eDebug;
      case eSymbolTypeLineEntry:
        return AddressClass::eDebug;
      case eSymbolTypeLineHeader:
        return AddressClass::eDebug;
      case eSymbolTypeScopeBegin:
        return AddressClass::eDebug;
      case eSymbolTypeScopeEnd:
        return AddressClass::eDebug;
      case eSymbolTypeAdditional:
        return AddressClass::eUnknown;
      case eSymbolTypeCompiler:
        return AddressClass::eDebug;
      case eSymbolTypeInstrumentation:
        return AddressClass::eDebug;
      case eSymbolTypeUndefined:
        return AddressClass::eUnknown;
      case eSymbolTypeObjCClass:
        return AddressClass::eRuntime;
      case eSymbolTypeObjCMetaClass:
        return AddressClass::eRuntime;
      case eSymbolTypeObjCIVar:
        return AddressClass::eRuntime;
      case eSymbolTypeReExported:
        return AddressClass::eRuntime;
      }
    }
  }
  return AddressClass::eUnknown;
}

WritableDataBufferSP ObjectFile::ReadMemory(const ProcessSP &process_sp,
                                            lldb::addr_t addr,
                                            size_t byte_size) {
  WritableDataBufferSP data_sp;
  if (process_sp) {
    std::unique_ptr<DataBufferHeap> data_up(new DataBufferHeap(byte_size, 0));
    Status error;
    const size_t bytes_read = process_sp->ReadMemory(
        addr, data_up->GetBytes(), data_up->GetByteSize(), error);
    if (bytes_read == byte_size)
      data_sp.reset(data_up.release());
  }
  return data_sp;
}

size_t ObjectFile::GetData(lldb::offset_t offset, size_t length,
                           DataExtractorSP &data_sp) const {
  // The entire file has already been mmap'ed into m_data_nsp, so just copy from
  // there as the back mmap buffer will be shared with shared pointers.
  data_sp = m_data_nsp->GetSubsetExtractorSP(offset, length);
  return data_sp->GetByteSize();
}

size_t ObjectFile::CopyData(lldb::offset_t offset, size_t length,
                            void *dst) const {
  // The entire file has already been mmap'ed into m_data_nsp, so just copy from
  // there Note that the data remains in target byte order.
  return m_data_nsp->CopyData(offset, length, dst);
}

size_t ObjectFile::ReadSectionData(Section *section,
                                   lldb::offset_t section_offset, void *dst,
                                   size_t dst_len) {
  assert(section);

  // If some other objectfile owns this data, pass this to them.
  if (section->GetObjectFile() != this)
    return section->GetObjectFile()->ReadSectionData(section, section_offset,
                                                     dst, dst_len);

  if (!section->IsRelocated())
    RelocateSection(section);

  if (IsInMemory()) {
    ProcessSP process_sp(m_process_wp.lock());
    if (process_sp) {
      Status error;
      const addr_t base_load_addr =
          section->GetLoadBaseAddress(&process_sp->GetTarget());
      if (base_load_addr != LLDB_INVALID_ADDRESS)
        return process_sp->ReadMemory(base_load_addr + section_offset, dst,
                                      dst_len, error);
    }
  } else {
    const lldb::offset_t section_file_size = section->GetFileSize();
    if (section_offset < section_file_size) {
      const size_t section_bytes_left = section_file_size - section_offset;
      size_t section_dst_len = dst_len;
      if (section_dst_len > section_bytes_left)
        section_dst_len = section_bytes_left;
      return CopyData(section->GetFileOffset() + section_offset,
                      section_dst_len, dst);
    } else {
      if (section->GetType() == eSectionTypeZeroFill) {
        const uint64_t section_size = section->GetByteSize();
        const uint64_t section_bytes_left = section_size - section_offset;
        uint64_t section_dst_len = dst_len;
        if (section_dst_len > section_bytes_left)
          section_dst_len = section_bytes_left;
        memset(dst, 0, section_dst_len);
        return section_dst_len;
      }
    }
  }
  return 0;
}

// Get the section data the file on disk
size_t ObjectFile::ReadSectionData(Section *section,
                                   DataExtractor &section_data) {
  // If some other objectfile owns this data, pass this to them.
  if (section->GetObjectFile() != this)
    return section->GetObjectFile()->ReadSectionData(section, section_data);

  if (!section->IsRelocated())
    RelocateSection(section);

  if (IsInMemory()) {
    ProcessSP process_sp(m_process_wp.lock());
    if (process_sp) {
      const addr_t base_load_addr =
          section->GetLoadBaseAddress(&process_sp->GetTarget());
      if (base_load_addr != LLDB_INVALID_ADDRESS) {
        DataBufferSP data_sp(
            ReadMemory(process_sp, base_load_addr, section->GetByteSize()));
        if (data_sp) {
          section_data.SetData(data_sp, 0, data_sp->GetByteSize());
          section_data.SetByteOrder(process_sp->GetByteOrder());
          section_data.SetAddressByteSize(process_sp->GetAddressByteSize());
          return section_data.GetByteSize();
        }
      }
    }
  }

  // The object file now contains a full mmap'ed copy of the object file
  // data, so just use this
  DataExtractorSP extractor_sp;
  size_t ret_size = GetData(section->GetFileOffset(),
                            GetSectionDataSize(section), extractor_sp);
  section_data = *extractor_sp;
  return ret_size;
}

bool ObjectFile::SplitArchivePathWithObject(llvm::StringRef path_with_object,
                                            FileSpec &archive_file,
                                            llvm::StringRef &archive_object,
                                            bool must_exist) {
  size_t len = path_with_object.size();
  if (len < 2 || path_with_object.back() != ')')
    return false;
  llvm::StringRef archive =
      path_with_object.substr(0, path_with_object.rfind('('));
  if (archive.empty())
    return false;
  llvm::StringRef object =
      path_with_object.substr(archive.size() + 1).drop_back();
  archive_file.SetFile(archive, FileSpec::Style::native);
  if (must_exist && !FileSystem::Instance().Exists(archive_file))
    return false;
  archive_object = object;
  return true;
}

void ObjectFile::ClearSymtab() {
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    Log *log = GetLog(LLDBLog::Object);
    LLDB_LOGF(log, "%p ObjectFile::ClearSymtab () symtab = %p",
              static_cast<void *>(this),
              static_cast<void *>(m_symtab_up.get()));
    // Since we need to clear the symbol table, we need a new llvm::once_flag
    // instance so we can safely create another symbol table
    m_symtab_once_up.reset(new llvm::once_flag());
    m_symtab_up.reset();
  }
}

SectionList *ObjectFile::GetSectionList(bool update_module_section_list) {
  std::lock_guard<std::recursive_mutex> guard(m_sections_mutex);
  if (m_sections_up)
    return m_sections_up.get();
  if (update_module_section_list) {
    if (ModuleSP module_sp = GetModule()) {
      std::lock_guard<std::recursive_mutex> guard(module_sp->m_sections_mutex);
      CreateSections(*module_sp->GetUnifiedSectionList());
    }
  } else {
    SectionList unified_section_list;
    CreateSections(unified_section_list);
  }
  return m_sections_up.get();
}

lldb::SymbolType
ObjectFile::GetSymbolTypeFromName(llvm::StringRef name,
                                  lldb::SymbolType symbol_type_hint) {
  if (!name.empty()) {
    if (name.starts_with("_OBJC_")) {
      // ObjC
      if (name.starts_with("_OBJC_CLASS_$_"))
        return lldb::eSymbolTypeObjCClass;
      if (name.starts_with("_OBJC_METACLASS_$_"))
        return lldb::eSymbolTypeObjCMetaClass;
      if (name.starts_with("_OBJC_IVAR_$_"))
        return lldb::eSymbolTypeObjCIVar;
    } else if (name.starts_with(".objc_class_name_")) {
      // ObjC v1
      return lldb::eSymbolTypeObjCClass;
    }
  }
  return symbol_type_hint;
}

lldb::SectionType
ObjectFile::GetDWARFSectionTypeFromName(llvm::StringRef name) {
  return llvm::StringSwitch<SectionType>(name)
      .Case("abbrev", eSectionTypeDWARFDebugAbbrev)
      .Case("abbrev.dwo", eSectionTypeDWARFDebugAbbrevDwo)
      .Case("addr", eSectionTypeDWARFDebugAddr)
      .Case("aranges", eSectionTypeDWARFDebugAranges)
      .Case("cu_index", eSectionTypeDWARFDebugCuIndex)
      .Case("frame", eSectionTypeDWARFDebugFrame)
      .Case("info", eSectionTypeDWARFDebugInfo)
      .Case("info.dwo", eSectionTypeDWARFDebugInfoDwo)
      .Cases({"line", "line.dwo"}, eSectionTypeDWARFDebugLine)
      .Cases({"line_str", "line_str.dwo"}, eSectionTypeDWARFDebugLineStr)
      .Case("loc", eSectionTypeDWARFDebugLoc)
      .Case("loc.dwo", eSectionTypeDWARFDebugLocDwo)
      .Case("loclists", eSectionTypeDWARFDebugLocLists)
      .Case("loclists.dwo", eSectionTypeDWARFDebugLocListsDwo)
      .Case("macinfo", eSectionTypeDWARFDebugMacInfo)
      .Cases({"macro", "macro.dwo"}, eSectionTypeDWARFDebugMacro)
      .Case("names", eSectionTypeDWARFDebugNames)
      .Case("pubnames", eSectionTypeDWARFDebugPubNames)
      .Case("pubtypes", eSectionTypeDWARFDebugPubTypes)
      .Case("ranges", eSectionTypeDWARFDebugRanges)
      .Case("rnglists", eSectionTypeDWARFDebugRngLists)
      .Case("rnglists.dwo", eSectionTypeDWARFDebugRngListsDwo)
      .Case("str", eSectionTypeDWARFDebugStr)
      .Case("str.dwo", eSectionTypeDWARFDebugStrDwo)
      .Cases({"str_offsets", "str_offs"}, eSectionTypeDWARFDebugStrOffsets)
      .Case("str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo)
      .Case("tu_index", eSectionTypeDWARFDebugTuIndex)
      .Case("types", eSectionTypeDWARFDebugTypes)
      .Case("types.dwo", eSectionTypeDWARFDebugTypesDwo)
      .Default(eSectionTypeOther);
}

std::vector<ObjectFile::LoadableData>
ObjectFile::GetLoadableData(Target &target) {
  std::vector<LoadableData> loadables;
  SectionList *section_list = GetSectionList();
  if (!section_list)
    return loadables;
  // Create a list of loadable data from loadable sections
  size_t section_count = section_list->GetNumSections(0);
  for (size_t i = 0; i < section_count; ++i) {
    LoadableData loadable;
    SectionSP section_sp = section_list->GetSectionAtIndex(i);
    loadable.Dest = target.GetSectionLoadAddress(section_sp);
    if (loadable.Dest == LLDB_INVALID_ADDRESS)
      continue;
    // We can skip sections like bss
    if (section_sp->GetFileSize() == 0)
      continue;
    DataExtractor section_data;
    section_sp->GetSectionData(section_data);
    loadable.Contents = section_data.GetData();
    loadables.push_back(loadable);
  }
  return loadables;
}

std::unique_ptr<CallFrameInfo> ObjectFile::CreateCallFrameInfo() {
  return {};
}

void ObjectFile::RelocateSection(lldb_private::Section *section)
{
}

DataBufferSP ObjectFile::MapFileData(const FileSpec &file, uint64_t Size,
                                     uint64_t Offset) {
  return FileSystem::Instance().CreateDataBuffer(file.GetPath(), Size, Offset);
}

void llvm::format_provider<ObjectFile::Type>::format(
    const ObjectFile::Type &type, raw_ostream &OS, StringRef Style) {
  switch (type) {
  case ObjectFile::eTypeInvalid:
    OS << "invalid";
    break;
  case ObjectFile::eTypeCoreFile:
    OS << "core file";
    break;
  case ObjectFile::eTypeExecutable:
    OS << "executable";
    break;
  case ObjectFile::eTypeDebugInfo:
    OS << "debug info";
    break;
  case ObjectFile::eTypeDynamicLinker:
    OS << "dynamic linker";
    break;
  case ObjectFile::eTypeObjectFile:
    OS << "object file";
    break;
  case ObjectFile::eTypeSharedLibrary:
    OS << "shared library";
    break;
  case ObjectFile::eTypeStubLibrary:
    OS << "stub library";
    break;
  case ObjectFile::eTypeJIT:
    OS << "jit";
    break;
  case ObjectFile::eTypeUnknown:
    OS << "unknown";
    break;
  }
}

void llvm::format_provider<ObjectFile::Strata>::format(
    const ObjectFile::Strata &strata, raw_ostream &OS, StringRef Style) {
  switch (strata) {
  case ObjectFile::eStrataInvalid:
    OS << "invalid";
    break;
  case ObjectFile::eStrataUnknown:
    OS << "unknown";
    break;
  case ObjectFile::eStrataUser:
    OS << "user";
    break;
  case ObjectFile::eStrataKernel:
    OS << "kernel";
    break;
  case ObjectFile::eStrataRawImage:
    OS << "raw image";
    break;
  case ObjectFile::eStrataJIT:
    OS << "jit";
    break;
  }
}

Symtab *ObjectFile::GetSymtab(bool can_create) {
  ModuleSP module_sp(GetModule());
  if (module_sp && can_create) {
    // We can't take the module lock in ObjectFile::GetSymtab() or we can
    // deadlock in DWARF indexing when any file asks for the symbol table from
    // an object file. This currently happens in the preloading of symbols in
    // SymbolFileDWARF::PreloadSymbols() because the main thread will take the
    // module lock, and then threads will be spun up to index the DWARF and
    // any of those threads might end up trying to relocate items in the DWARF
    // sections which causes ObjectFile::GetSectionData(...) to relocate section
    // data which requires the symbol table.
    //
    // So to work around this, we create the symbol table one time using
    // llvm::once_flag, lock it, and then set the unique pointer. Any other
    // thread that gets ahold of the symbol table before parsing is done, will
    // not be able to access the symbol table contents since all APIs in Symtab
    // are protected by a mutex in the Symtab object itself.
    llvm::call_once(*m_symtab_once_up, [&]() {
      Symtab *symtab = new Symtab(this);
      std::lock_guard<std::recursive_mutex> symtab_guard(symtab->GetMutex());
      m_symtab_up.reset(symtab);
      if (!m_symtab_up->LoadFromCache()) {
        ElapsedTime elapsed(module_sp->GetSymtabParseTime());
        ParseSymtab(*m_symtab_up);
        m_symtab_up->Finalize();
      }
    });
  }
  return m_symtab_up.get();
}

uint32_t ObjectFile::GetCacheHash() {
  if (m_cache_hash)
    return *m_cache_hash;
  StreamString strm;
  strm.Format("{0}-{1}-{2}", m_file, GetType(), GetStrata());
  m_cache_hash = llvm::djbHash(strm.GetString());
  return *m_cache_hash;
}

std::string ObjectFile::GetObjectName() const {
  if (ModuleSP module_sp = GetModule())
    if (ConstString object_name = module_sp->GetObjectName())
      return llvm::formatv("{0}({1})", GetFileSpec().GetFilename(),
                           object_name.GetString())
          .str();
  return GetFileSpec().GetFilename().str();
}

namespace llvm {
namespace json {

bool fromJSON(const llvm::json::Value &value,
              lldb_private::ObjectFile::Type &type, llvm::json::Path path) {
  if (auto str = value.getAsString()) {
    type = llvm::StringSwitch<ObjectFile::Type>(*str)
               .Case("corefile", ObjectFile::eTypeCoreFile)
               .Case("executable", ObjectFile::eTypeExecutable)
               .Case("debuginfo", ObjectFile::eTypeDebugInfo)
               .Case("dynamiclinker", ObjectFile::eTypeDynamicLinker)
               .Case("objectfile", ObjectFile::eTypeObjectFile)
               .Case("sharedlibrary", ObjectFile::eTypeSharedLibrary)
               .Case("stublibrary", ObjectFile::eTypeStubLibrary)
               .Case("jit", ObjectFile::eTypeJIT)
               .Case("unknown", ObjectFile::eTypeUnknown)
               .Default(ObjectFile::eTypeInvalid);

    if (type == ObjectFile::eTypeInvalid) {
      path.report("invalid object type");
      return false;
    }

    return true;
  }
  path.report("expected string");
  return false;
}
} // namespace json
} // namespace llvm
