//===-- 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;
    ConstString 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, 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,
            extractor_sp->GetSharedDataBuffer(), 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) {
  // Try the ObjectFile plug-ins
  for (auto &cbs : PluginManager::GetObjectFileCallbacks()) {
    ModuleSpecList specs = cbs.get_module_specifications(
        file, extractor_sp, file_offset, file_size);
    if (specs.GetSize() > 0)
      return specs;
  }

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

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 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,
                                            ConstString &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.SetString(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) {
  if (m_sections_up == nullptr) {
    if (update_module_section_list) {
      ModuleSP module_sp(GetModule());
      if (module_sp) {
        std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
        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().GetString(),
                           object_name.GetString())
          .str();
  return GetFileSpec().GetFilename().GetString();
}

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
