//===-- ObjectFile.cpp ------------------------------------------*- C++ -*-===//
//
// 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/Log.h"
#include "lldb/Utility/Timer.h"
#include "lldb/lldb-private.h"

using namespace lldb;
using namespace lldb_private;

char ObjectFile::ID;

ObjectFileSP
ObjectFile::FindPlugin(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) {
  ObjectFileSP object_file_sp;

  if (module_sp) {
    static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
    Timer scoped_timer(
        func_cat,
        "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 (file) {
      FileSpec archive_file;
      ObjectContainerCreateInstance create_object_container_callback;

      const bool file_exists = FileSystem::Instance().Exists(*file);
      if (!data_sp) {
        // 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()) {
          for (uint32_t idx = 0;
               (create_object_container_callback =
                    PluginManager::GetObjectContainerCreateCallbackAtIndex(
                        idx)) != nullptr;
               ++idx) {
            std::unique_ptr<ObjectContainer> object_container_up(
                create_object_container_callback(module_sp, data_sp,
                                                 data_offset, file, file_offset,
                                                 file_size));

            if (object_container_up)
              object_file_sp = object_container_up->GetObjectFile(file);

            if (object_file_sp.get())
              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) {
          data_sp = FileSystem::Instance().CreateDataBuffer(file->GetPath(),
                                                            512, file_offset);
          data_offset = 0;
        }
      }

      if (!data_sp || data_sp->GetByteSize() == 0) {
        // 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);

        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).
            for (uint32_t idx = 0;
                 (create_object_container_callback =
                      PluginManager::GetObjectContainerCreateCallbackAtIndex(
                          idx)) != nullptr;
                 ++idx) {
              std::unique_ptr<ObjectContainer> object_container_up(
                  create_object_container_callback(module_sp, data_sp,
                                                   data_offset, file,
                                                   file_offset, file_size));

              if (object_container_up)
                object_file_sp = object_container_up->GetObjectFile(file);

              if (object_file_sp.get())
                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...
            data_sp = FileSystem::Instance().CreateDataBuffer(
                archive_file.GetPath(), 512, file_offset);
          }
        }
      }

      if (data_sp && data_sp->GetByteSize() > 0) {
        // Check if this is a normal object file by iterating through all
        // object file plugin instances.
        ObjectFileCreateInstance create_object_file_callback;
        for (uint32_t idx = 0;
             (create_object_file_callback =
                  PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) !=
             nullptr;
             ++idx) {
          object_file_sp.reset(create_object_file_callback(
              module_sp, data_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.
        for (uint32_t idx = 0;
             (create_object_container_callback =
                  PluginManager::GetObjectContainerCreateCallbackAtIndex(
                      idx)) != nullptr;
             ++idx) {
          std::unique_ptr<ObjectContainer> object_container_up(
              create_object_container_callback(module_sp, data_sp, data_offset,
                                               file, file_offset, file_size));

          if (object_container_up)
            object_file_sp = object_container_up->GetObjectFile(file);

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

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

  if (module_sp) {
    static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
    Timer scoped_timer(func_cat,
                       "ObjectFile::FindPlugin (module = "
                       "%s, process = %p, header_addr = "
                       "0x%" PRIx64 ")",
                       module_sp->GetFileSpec().GetPath().c_str(),
                       static_cast<void *>(process_sp.get()), header_addr);
    uint32_t idx;

    // Check if this is a normal object file by iterating through all object
    // file plugin instances.
    ObjectFileCreateMemoryInstance create_callback;
    for (idx = 0;
         (create_callback =
              PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(idx)) !=
         nullptr;
         ++idx) {
      object_file_sp.reset(
          create_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;
}

size_t ObjectFile::GetModuleSpecifications(const FileSpec &file,
                                           lldb::offset_t file_offset,
                                           lldb::offset_t file_size,
                                           ModuleSpecList &specs) {
  DataBufferSP data_sp =
      FileSystem::Instance().CreateDataBuffer(file.GetPath(), 512, file_offset);
  if (data_sp) {
    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,        // file spec
                                               data_sp,     // data bytes
                                               0,           // data offset
                                               file_offset, // file offset
                                               file_size,   // file length
                                               specs);
  }
  return 0;
}

size_t ObjectFile::GetModuleSpecifications(
    const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
    lldb::offset_t data_offset, lldb::offset_t file_offset,
    lldb::offset_t file_size, lldb_private::ModuleSpecList &specs) {
  const size_t initial_count = specs.GetSize();
  ObjectFileGetModuleSpecifications callback;
  uint32_t i;
  // Try the ObjectFile plug-ins
  for (i = 0;
       (callback =
            PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
                i)) != nullptr;
       ++i) {
    if (callback(file, data_sp, data_offset, file_offset, file_size, specs) > 0)
      return specs.GetSize() - initial_count;
  }

  // Try the ObjectContainer plug-ins
  for (i = 0;
       (callback = PluginManager::
            GetObjectContainerGetModuleSpecificationsCallbackAtIndex(i)) !=
       nullptr;
       ++i) {
    if (callback(file, data_sp, data_offset, file_offset, file_size, specs) > 0)
      return specs.GetSize() - initial_count;
  }
  return 0;
}

ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp,
                       const FileSpec *file_spec_ptr,
                       lldb::offset_t file_offset, lldb::offset_t length,
                       const lldb::DataBufferSP &data_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(), m_process_wp(),
      m_memory_addr(LLDB_INVALID_ADDRESS), m_sections_up(), m_symtab_up(),
      m_synthetic_symbol_idx(0) {
  if (file_spec_ptr)
    m_file = *file_spec_ptr;
  if (data_sp)
    m_data.SetData(data_sp, data_offset, length);
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_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,
                       DataBufferSP &header_data_sp)
    : ModuleChild(module_sp), m_file(), m_type(eTypeInvalid),
      m_strata(eStrataInvalid), m_file_offset(0), m_length(0), m_data(),
      m_process_wp(process_sp), m_memory_addr(header_addr), m_sections_up(),
      m_symtab_up(), m_synthetic_symbol_idx(0) {
  if (header_data_sp)
    m_data.SetData(header_data_sp, 0, header_data_sp->GetByteSize());
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_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(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_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) {
    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 eSectionTypeDWARFDebugTypes:
          case eSectionTypeDWARFDebugTypesDwo:
          case eSectionTypeDWARFAppleNames:
          case eSectionTypeDWARFAppleTypes:
          case eSectionTypeDWARFAppleNamespaces:
          case eSectionTypeDWARFAppleObjC:
          case eSectionTypeDWARFGNUDebugAltLink:
            return AddressClass::eDebug;
          case eSectionTypeEHFrame:
          case eSectionTypeARMexidx:
          case eSectionTypeARMextab:
          case eSectionTypeCompactUnwind:
            return AddressClass::eRuntime;
          case eSectionTypeELFSymbolTable:
          case eSectionTypeELFDynamicSymbols:
          case eSectionTypeELFRelocationEntries:
          case eSectionTypeELFDynamicLinkInfo:
          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;
}

DataBufferSP ObjectFile::ReadMemory(const ProcessSP &process_sp,
                                    lldb::addr_t addr, size_t byte_size) {
  DataBufferSP 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,
                           DataExtractor &data) const {
  // The entire file has already been mmap'ed into m_data, so just copy from
  // there as the back mmap buffer will be shared with shared pointers.
  return data.SetData(m_data, offset, length);
}

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, so just copy from
  // there Note that the data remains in target byte order.
  return m_data.CopyData(offset, length, dst);
}

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

  // 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 (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 {
    if (!section->IsRelocated())
      RelocateSection(section);

    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 (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();
        }
      }
    }
    return GetData(section->GetFileOffset(), section->GetFileSize(),
                   section_data);
  } else {
    // The object file now contains a full mmap'ed copy of the object file
    // data, so just use this
    if (!section->IsRelocated())
      RelocateSection(section);

    return GetData(section->GetFileOffset(), section->GetFileSize(),
                   section_data);
  }
}

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) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
    LLDB_LOGF(log, "%p ObjectFile::ClearSymtab () symtab = %p",
              static_cast<void *>(this),
              static_cast<void *>(m_symtab_up.get()));
    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.startswith("_OBJC_")) {
      // ObjC
      if (name.startswith("_OBJC_CLASS_$_"))
        return lldb::eSymbolTypeObjCClass;
      if (name.startswith("_OBJC_METACLASS_$_"))
        return lldb::eSymbolTypeObjCMetaClass;
      if (name.startswith("_OBJC_IVAR_$_"))
        return lldb::eSymbolTypeObjCIVar;
    } else if (name.startswith(".objc_class_name_")) {
      // ObjC v1
      return lldb::eSymbolTypeObjCClass;
    }
  }
  return symbol_type_hint;
}

ConstString ObjectFile::GetNextSyntheticSymbolName() {
  StreamString ss;
  ConstString file_name = GetModule()->GetFileSpec().GetFilename();
  ss.Printf("___lldb_unnamed_symbol%u$$%s", ++m_synthetic_symbol_idx,
            file_name.GetCString());
  return ConstString(ss.GetString());
}

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.GetSectionLoadList().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 = llvm::ArrayRef<uint8_t>(section_data.GetDataStart(),
                                                section_data.GetByteSize());
    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;
  }
}
