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

#include "ObjectFileELF.h"

#include <algorithm>
#include <cassert>
#include <unordered_map>

#include "lldb/Core/FileSpecList.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/SwiftLanguageRuntime.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/Timer.h"

#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/Decompressor.h"
#include "llvm/Support/ARMBuildAttributes.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MipsABIFlags.h"

#define CASE_AND_STREAM(s, def, width)                                         \
  case def:                                                                    \
    s->Printf("%-*s", width, #def);                                            \
    break;

using namespace lldb;
using namespace lldb_private;
using namespace elf;
using namespace llvm::ELF;

namespace {

// ELF note owner definitions
const char *const LLDB_NT_OWNER_FREEBSD = "FreeBSD";
const char *const LLDB_NT_OWNER_GNU = "GNU";
const char *const LLDB_NT_OWNER_NETBSD = "NetBSD";
const char *const LLDB_NT_OWNER_OPENBSD = "OpenBSD";
const char *const LLDB_NT_OWNER_CSR = "csr";
const char *const LLDB_NT_OWNER_ANDROID = "Android";
const char *const LLDB_NT_OWNER_CORE = "CORE";
const char *const LLDB_NT_OWNER_LINUX = "LINUX";

// ELF note type definitions
const elf_word LLDB_NT_FREEBSD_ABI_TAG = 0x01;
const elf_word LLDB_NT_FREEBSD_ABI_SIZE = 4;

const elf_word LLDB_NT_GNU_ABI_TAG = 0x01;
const elf_word LLDB_NT_GNU_ABI_SIZE = 16;

const elf_word LLDB_NT_GNU_BUILD_ID_TAG = 0x03;

const elf_word LLDB_NT_NETBSD_ABI_TAG = 0x01;
const elf_word LLDB_NT_NETBSD_ABI_SIZE = 4;

// GNU ABI note OS constants
const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00;
const elf_word LLDB_NT_GNU_ABI_OS_HURD = 0x01;
const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02;

// LLDB_NT_OWNER_CORE and LLDB_NT_OWNER_LINUX note contants
#define NT_PRSTATUS 1
#define NT_PRFPREG 2
#define NT_PRPSINFO 3
#define NT_TASKSTRUCT 4
#define NT_AUXV 6
#define NT_SIGINFO 0x53494749
#define NT_FILE 0x46494c45
#define NT_PRXFPREG 0x46e62b7f
#define NT_PPC_VMX 0x100
#define NT_PPC_SPE 0x101
#define NT_PPC_VSX 0x102
#define NT_386_TLS 0x200
#define NT_386_IOPERM 0x201
#define NT_X86_XSTATE 0x202
#define NT_S390_HIGH_GPRS 0x300
#define NT_S390_TIMER 0x301
#define NT_S390_TODCMP 0x302
#define NT_S390_TODPREG 0x303
#define NT_S390_CTRS 0x304
#define NT_S390_PREFIX 0x305
#define NT_S390_LAST_BREAK 0x306
#define NT_S390_SYSTEM_CALL 0x307
#define NT_S390_TDB 0x308
#define NT_S390_VXRS_LOW 0x309
#define NT_S390_VXRS_HIGH 0x30a
#define NT_ARM_VFP 0x400
#define NT_ARM_TLS 0x401
#define NT_ARM_HW_BREAK 0x402
#define NT_ARM_HW_WATCH 0x403
#define NT_ARM_SYSTEM_CALL 0x404
#define NT_METAG_CBUF 0x500
#define NT_METAG_RPIPE 0x501
#define NT_METAG_TLS 0x502

//===----------------------------------------------------------------------===//
/// @class ELFRelocation
/// @brief Generic wrapper for ELFRel and ELFRela.
///
/// This helper class allows us to parse both ELFRel and ELFRela relocation
/// entries in a generic manner.
class ELFRelocation {
public:
  /// Constructs an ELFRelocation entry with a personality as given by @p
  /// type.
  ///
  /// @param type Either DT_REL or DT_RELA.  Any other value is invalid.
  ELFRelocation(unsigned type);

  ~ELFRelocation();

  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);

  static unsigned RelocType32(const ELFRelocation &rel);

  static unsigned RelocType64(const ELFRelocation &rel);

  static unsigned RelocSymbol32(const ELFRelocation &rel);

  static unsigned RelocSymbol64(const ELFRelocation &rel);

  static unsigned RelocOffset32(const ELFRelocation &rel);

  static unsigned RelocOffset64(const ELFRelocation &rel);

  static unsigned RelocAddend32(const ELFRelocation &rel);

  static unsigned RelocAddend64(const ELFRelocation &rel);

private:
  typedef llvm::PointerUnion<ELFRel *, ELFRela *> RelocUnion;

  RelocUnion reloc;
};

ELFRelocation::ELFRelocation(unsigned type) {
  if (type == DT_REL || type == SHT_REL)
    reloc = new ELFRel();
  else if (type == DT_RELA || type == SHT_RELA)
    reloc = new ELFRela();
  else {
    assert(false && "unexpected relocation type");
    reloc = static_cast<ELFRel *>(NULL);
  }
}

ELFRelocation::~ELFRelocation() {
  if (reloc.is<ELFRel *>())
    delete reloc.get<ELFRel *>();
  else
    delete reloc.get<ELFRela *>();
}

bool ELFRelocation::Parse(const lldb_private::DataExtractor &data,
                          lldb::offset_t *offset) {
  if (reloc.is<ELFRel *>())
    return reloc.get<ELFRel *>()->Parse(data, offset);
  else
    return reloc.get<ELFRela *>()->Parse(data, offset);
}

unsigned ELFRelocation::RelocType32(const ELFRelocation &rel) {
  if (rel.reloc.is<ELFRel *>())
    return ELFRel::RelocType32(*rel.reloc.get<ELFRel *>());
  else
    return ELFRela::RelocType32(*rel.reloc.get<ELFRela *>());
}

unsigned ELFRelocation::RelocType64(const ELFRelocation &rel) {
  if (rel.reloc.is<ELFRel *>())
    return ELFRel::RelocType64(*rel.reloc.get<ELFRel *>());
  else
    return ELFRela::RelocType64(*rel.reloc.get<ELFRela *>());
}

unsigned ELFRelocation::RelocSymbol32(const ELFRelocation &rel) {
  if (rel.reloc.is<ELFRel *>())
    return ELFRel::RelocSymbol32(*rel.reloc.get<ELFRel *>());
  else
    return ELFRela::RelocSymbol32(*rel.reloc.get<ELFRela *>());
}

unsigned ELFRelocation::RelocSymbol64(const ELFRelocation &rel) {
  if (rel.reloc.is<ELFRel *>())
    return ELFRel::RelocSymbol64(*rel.reloc.get<ELFRel *>());
  else
    return ELFRela::RelocSymbol64(*rel.reloc.get<ELFRela *>());
}

unsigned ELFRelocation::RelocOffset32(const ELFRelocation &rel) {
  if (rel.reloc.is<ELFRel *>())
    return rel.reloc.get<ELFRel *>()->r_offset;
  else
    return rel.reloc.get<ELFRela *>()->r_offset;
}

unsigned ELFRelocation::RelocOffset64(const ELFRelocation &rel) {
  if (rel.reloc.is<ELFRel *>())
    return rel.reloc.get<ELFRel *>()->r_offset;
  else
    return rel.reloc.get<ELFRela *>()->r_offset;
}

unsigned ELFRelocation::RelocAddend32(const ELFRelocation &rel) {
  if (rel.reloc.is<ELFRel *>())
    return 0;
  else
    return rel.reloc.get<ELFRela *>()->r_addend;
}

unsigned ELFRelocation::RelocAddend64(const ELFRelocation &rel) {
  if (rel.reloc.is<ELFRel *>())
    return 0;
  else
    return rel.reloc.get<ELFRela *>()->r_addend;
}

} // end anonymous namespace

bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) {
  // Read all fields.
  if (data.GetU32(offset, &n_namesz, 3) == NULL)
    return false;

  // The name field is required to be nul-terminated, and n_namesz
  // includes the terminating nul in observed implementations (contrary
  // to the ELF-64 spec).  A special case is needed for cores generated
  // by some older Linux versions, which write a note named "CORE"
  // without a nul terminator and n_namesz = 4.
  if (n_namesz == 4) {
    char buf[4];
    if (data.ExtractBytes(*offset, 4, data.GetByteOrder(), buf) != 4)
      return false;
    if (strncmp(buf, "CORE", 4) == 0) {
      n_name = "CORE";
      *offset += 4;
      return true;
    }
  }

  const char *cstr = data.GetCStr(offset, llvm::alignTo(n_namesz, 4));
  if (cstr == NULL) {
    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));
    if (log)
      log->Printf("Failed to parse note name lacking nul terminator");

    return false;
  }
  n_name = cstr;
  return true;
}

static uint32_t kalimbaVariantFromElfFlags(const elf::elf_word e_flags) {
  const uint32_t dsp_rev = e_flags & 0xFF;
  uint32_t kal_arch_variant = LLDB_INVALID_CPUTYPE;
  switch (dsp_rev) {
  // TODO(mg11) Support more variants
  case 10:
    kal_arch_variant = llvm::Triple::KalimbaSubArch_v3;
    break;
  case 14:
    kal_arch_variant = llvm::Triple::KalimbaSubArch_v4;
    break;
  case 17:
  case 20:
    kal_arch_variant = llvm::Triple::KalimbaSubArch_v5;
    break;
  default:
    break;
  }
  return kal_arch_variant;
}

static uint32_t mipsVariantFromElfFlags (const elf::ELFHeader &header) {
  const uint32_t mips_arch = header.e_flags & llvm::ELF::EF_MIPS_ARCH;
  uint32_t endian = header.e_ident[EI_DATA];
  uint32_t arch_variant = ArchSpec::eMIPSSubType_unknown;
  uint32_t fileclass = header.e_ident[EI_CLASS];

  // If there aren't any elf flags available (e.g core elf file) then return default 
  // 32 or 64 bit arch (without any architecture revision) based on object file's class.
  if (header.e_type == ET_CORE) {
    switch (fileclass) {
    case llvm::ELF::ELFCLASS32:
      return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32el
                                     : ArchSpec::eMIPSSubType_mips32;
    case llvm::ELF::ELFCLASS64:
      return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64el
                                     : ArchSpec::eMIPSSubType_mips64;
    default:
      return arch_variant;
    }
  }

  switch (mips_arch) {
  case llvm::ELF::EF_MIPS_ARCH_1:
  case llvm::ELF::EF_MIPS_ARCH_2:
  case llvm::ELF::EF_MIPS_ARCH_32:
    return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32el
                                   : ArchSpec::eMIPSSubType_mips32;
  case llvm::ELF::EF_MIPS_ARCH_32R2:
    return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32r2el
                                   : ArchSpec::eMIPSSubType_mips32r2;
  case llvm::ELF::EF_MIPS_ARCH_32R6:
    return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32r6el
                                   : ArchSpec::eMIPSSubType_mips32r6;
  case llvm::ELF::EF_MIPS_ARCH_3:
  case llvm::ELF::EF_MIPS_ARCH_4:
  case llvm::ELF::EF_MIPS_ARCH_5:
  case llvm::ELF::EF_MIPS_ARCH_64:
    return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64el
                                   : ArchSpec::eMIPSSubType_mips64;
  case llvm::ELF::EF_MIPS_ARCH_64R2:
    return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64r2el
                                   : ArchSpec::eMIPSSubType_mips64r2;
  case llvm::ELF::EF_MIPS_ARCH_64R6:
    return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64r6el
                                   : ArchSpec::eMIPSSubType_mips64r6;
  default:
    break;
  }

  return arch_variant;
}

static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) {
  if (header.e_machine == llvm::ELF::EM_MIPS)
    return mipsVariantFromElfFlags(header);

  return llvm::ELF::EM_CSR_KALIMBA == header.e_machine
             ? kalimbaVariantFromElfFlags(header.e_flags)
             : LLDB_INVALID_CPUTYPE;
}

//! The kalimba toolchain identifies a code section as being
//! one with the SHT_PROGBITS set in the section sh_type and the top
//! bit in the 32-bit address field set.
static lldb::SectionType
kalimbaSectionType(const elf::ELFHeader &header,
                   const elf::ELFSectionHeader &sect_hdr) {
  if (llvm::ELF::EM_CSR_KALIMBA != header.e_machine) {
    return eSectionTypeOther;
  }

  if (llvm::ELF::SHT_NOBITS == sect_hdr.sh_type) {
    return eSectionTypeZeroFill;
  }

  if (llvm::ELF::SHT_PROGBITS == sect_hdr.sh_type) {
    const lldb::addr_t KAL_CODE_BIT = 1 << 31;
    return KAL_CODE_BIT & sect_hdr.sh_addr ? eSectionTypeCode
                                           : eSectionTypeData;
  }

  return eSectionTypeOther;
}

// Arbitrary constant used as UUID prefix for core files.
const uint32_t ObjectFileELF::g_core_uuid_magic(0xE210C);

//------------------------------------------------------------------
// Static methods.
//------------------------------------------------------------------
void ObjectFileELF::Initialize() {
  PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                GetPluginDescriptionStatic(), CreateInstance,
                                CreateMemoryInstance, GetModuleSpecifications);
}

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

lldb_private::ConstString ObjectFileELF::GetPluginNameStatic() {
  static ConstString g_name("elf");
  return g_name;
}

const char *ObjectFileELF::GetPluginDescriptionStatic() {
  return "ELF object file reader.";
}

ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp,
                                          DataBufferSP &data_sp,
                                          lldb::offset_t data_offset,
                                          const lldb_private::FileSpec *file,
                                          lldb::offset_t file_offset,
                                          lldb::offset_t length) {
  if (!data_sp) {
    data_sp = MapFileData(*file, length, file_offset);
    if (!data_sp)
      return nullptr;
    data_offset = 0;
  }

  assert(data_sp);

  if (data_sp->GetByteSize() <= (llvm::ELF::EI_NIDENT + data_offset))
    return nullptr;

  const uint8_t *magic = data_sp->GetBytes() + data_offset;
  if (!ELFHeader::MagicBytesMatch(magic))
    return nullptr;

  // Update the data to contain the entire file if it doesn't already
  if (data_sp->GetByteSize() < length) {
    data_sp = MapFileData(*file, length, file_offset);
    if (!data_sp)
      return nullptr;
    data_offset = 0;
    magic = data_sp->GetBytes();
  }

  unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
  if (address_size == 4 || address_size == 8) {
    std::unique_ptr<ObjectFileELF> objfile_ap(new ObjectFileELF(
        module_sp, data_sp, data_offset, file, file_offset, length));
    ArchSpec spec;
    if (objfile_ap->GetArchitecture(spec) &&
        objfile_ap->SetModulesArchitecture(spec))
      return objfile_ap.release();
  }

  return NULL;
}

ObjectFile *ObjectFileELF::CreateMemoryInstance(
    const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
    const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) {
  if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT)) {
    const uint8_t *magic = data_sp->GetBytes();
    if (ELFHeader::MagicBytesMatch(magic)) {
      unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
      if (address_size == 4 || address_size == 8) {
        std::unique_ptr<ObjectFileELF> objfile_ap(
            new ObjectFileELF(module_sp, data_sp, process_sp, header_addr));
        ArchSpec spec;
        if (objfile_ap->GetArchitecture(spec) &&
            objfile_ap->SetModulesArchitecture(spec))
          return objfile_ap.release();
      }
    }
  }
  return NULL;
}

bool ObjectFileELF::MagicBytesMatch(DataBufferSP &data_sp,
                                    lldb::addr_t data_offset,
                                    lldb::addr_t data_length) {
  if (data_sp &&
      data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset)) {
    const uint8_t *magic = data_sp->GetBytes() + data_offset;
    return ELFHeader::MagicBytesMatch(magic);
  }
  return false;
}

/*
 * crc function from http://svnweb.freebsd.org/base/head/sys/libkern/crc32.c
 *
 *   COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
 *   code or tables extracted from it, as desired without restriction.
 */
static uint32_t calc_crc32(uint32_t crc, const void *buf, size_t size) {
  static const uint32_t g_crc32_tab[] = {
      0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
      0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
      0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
      0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
      0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
      0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
      0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
      0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
      0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
      0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
      0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
      0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
      0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
      0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
      0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
      0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
      0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
      0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
      0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
      0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
      0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
      0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
      0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
      0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
      0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
      0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
      0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
      0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
      0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
      0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
      0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
      0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
      0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
      0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
      0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
      0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
      0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
      0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
      0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
      0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
      0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
      0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
      0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
  const uint8_t *p = (const uint8_t *)buf;

  crc = crc ^ ~0U;
  while (size--)
    crc = g_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
  return crc ^ ~0U;
}

static uint32_t calc_gnu_debuglink_crc32(const void *buf, size_t size) {
  return calc_crc32(0U, buf, size);
}

uint32_t ObjectFileELF::CalculateELFNotesSegmentsCRC32(
    const ProgramHeaderColl &program_headers, DataExtractor &object_data) {
  typedef ProgramHeaderCollConstIter Iter;

  uint32_t core_notes_crc = 0;

  for (Iter I = program_headers.begin(); I != program_headers.end(); ++I) {
    if (I->p_type == llvm::ELF::PT_NOTE) {
      const elf_off ph_offset = I->p_offset;
      const size_t ph_size = I->p_filesz;

      DataExtractor segment_data;
      if (segment_data.SetData(object_data, ph_offset, ph_size) != ph_size) {
        // The ELF program header contained incorrect data,
        // probably corefile is incomplete or corrupted.
        break;
      }

      core_notes_crc = calc_crc32(core_notes_crc, segment_data.GetDataStart(),
                                  segment_data.GetByteSize());
    }
  }

  return core_notes_crc;
}

static const char *OSABIAsCString(unsigned char osabi_byte) {
#define _MAKE_OSABI_CASE(x)                                                    \
  case x:                                                                      \
    return #x
  switch (osabi_byte) {
    _MAKE_OSABI_CASE(ELFOSABI_NONE);
    _MAKE_OSABI_CASE(ELFOSABI_HPUX);
    _MAKE_OSABI_CASE(ELFOSABI_NETBSD);
    _MAKE_OSABI_CASE(ELFOSABI_GNU);
    _MAKE_OSABI_CASE(ELFOSABI_HURD);
    _MAKE_OSABI_CASE(ELFOSABI_SOLARIS);
    _MAKE_OSABI_CASE(ELFOSABI_AIX);
    _MAKE_OSABI_CASE(ELFOSABI_IRIX);
    _MAKE_OSABI_CASE(ELFOSABI_FREEBSD);
    _MAKE_OSABI_CASE(ELFOSABI_TRU64);
    _MAKE_OSABI_CASE(ELFOSABI_MODESTO);
    _MAKE_OSABI_CASE(ELFOSABI_OPENBSD);
    _MAKE_OSABI_CASE(ELFOSABI_OPENVMS);
    _MAKE_OSABI_CASE(ELFOSABI_NSK);
    _MAKE_OSABI_CASE(ELFOSABI_AROS);
    _MAKE_OSABI_CASE(ELFOSABI_FENIXOS);
    _MAKE_OSABI_CASE(ELFOSABI_C6000_ELFABI);
    _MAKE_OSABI_CASE(ELFOSABI_C6000_LINUX);
    _MAKE_OSABI_CASE(ELFOSABI_ARM);
    _MAKE_OSABI_CASE(ELFOSABI_STANDALONE);
  default:
    return "<unknown-osabi>";
  }
#undef _MAKE_OSABI_CASE
}

//
// WARNING : This function is being deprecated
// It's functionality has moved to ArchSpec::SetArchitecture
// This function is only being kept to validate the move.
//
// TODO : Remove this function
static bool GetOsFromOSABI(unsigned char osabi_byte,
                           llvm::Triple::OSType &ostype) {
  switch (osabi_byte) {
  case ELFOSABI_AIX:
    ostype = llvm::Triple::OSType::AIX;
    break;
  case ELFOSABI_FREEBSD:
    ostype = llvm::Triple::OSType::FreeBSD;
    break;
  case ELFOSABI_GNU:
    ostype = llvm::Triple::OSType::Linux;
    break;
  case ELFOSABI_NETBSD:
    ostype = llvm::Triple::OSType::NetBSD;
    break;
  case ELFOSABI_OPENBSD:
    ostype = llvm::Triple::OSType::OpenBSD;
    break;
  case ELFOSABI_SOLARIS:
    ostype = llvm::Triple::OSType::Solaris;
    break;
  default:
    ostype = llvm::Triple::OSType::UnknownOS;
  }
  return ostype != llvm::Triple::OSType::UnknownOS;
}

size_t ObjectFileELF::GetModuleSpecifications(
    const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
    lldb::offset_t data_offset, lldb::offset_t file_offset,
    lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES));

  const size_t initial_count = specs.GetSize();

  if (ObjectFileELF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {
    DataExtractor data;
    data.SetData(data_sp);
    elf::ELFHeader header;
    lldb::offset_t header_offset = data_offset;
    if (header.Parse(data, &header_offset)) {
      if (data_sp) {
        ModuleSpec spec(file);

        const uint32_t sub_type = subTypeFromElfHeader(header);
        spec.GetArchitecture().SetArchitecture(
            eArchTypeELF, header.e_machine, sub_type, header.e_ident[EI_OSABI]);

        if (spec.GetArchitecture().IsValid()) {
          llvm::Triple::OSType ostype;
          llvm::Triple::VendorType vendor;
          llvm::Triple::OSType spec_ostype =
              spec.GetArchitecture().GetTriple().getOS();

          if (log)
            log->Printf("ObjectFileELF::%s file '%s' module OSABI: %s",
                        __FUNCTION__, file.GetPath().c_str(),
                        OSABIAsCString(header.e_ident[EI_OSABI]));

          // SetArchitecture should have set the vendor to unknown
          vendor = spec.GetArchitecture().GetTriple().getVendor();
          assert(vendor == llvm::Triple::UnknownVendor);
          UNUSED_IF_ASSERT_DISABLED(vendor);

          //
          // Validate it is ok to remove GetOsFromOSABI
          GetOsFromOSABI(header.e_ident[EI_OSABI], ostype);
          assert(spec_ostype == ostype);
          if (spec_ostype != llvm::Triple::OSType::UnknownOS) {
            if (log)
              log->Printf("ObjectFileELF::%s file '%s' set ELF module OS type "
                          "from ELF header OSABI.",
                          __FUNCTION__, file.GetPath().c_str());
          }

          // In case there is header extension in the section #0, the header
          // we parsed above could have sentinel values for e_phnum, e_shnum,
          // and e_shstrndx.  In this case we need to reparse the header
          // with a bigger data source to get the actual values.
          size_t section_header_end = header.e_shoff + header.e_shentsize;
          if (header.HasHeaderExtension() &&
            section_header_end > data_sp->GetByteSize()) {
            data_sp = MapFileData(file, section_header_end, file_offset);
            if (data_sp) {
              data.SetData(data_sp);
              lldb::offset_t header_offset = data_offset;
              header.Parse(data, &header_offset);
            }
          }

          // Try to get the UUID from the section list. Usually that's at the
          // end, so map the file in if we don't have it already.
          section_header_end =
              header.e_shoff + header.e_shnum * header.e_shentsize;
          if (section_header_end > data_sp->GetByteSize()) {
            data_sp = MapFileData(file, section_header_end, file_offset);
            if (data_sp)
              data.SetData(data_sp);
          }

          uint32_t gnu_debuglink_crc = 0;
          std::string gnu_debuglink_file;
          SectionHeaderColl section_headers;
          lldb_private::UUID &uuid = spec.GetUUID();

          GetSectionHeaderInfo(section_headers, data, header, uuid,
                               gnu_debuglink_file, gnu_debuglink_crc,
                               spec.GetArchitecture());

          llvm::Triple &spec_triple = spec.GetArchitecture().GetTriple();

          if (log)
            log->Printf("ObjectFileELF::%s file '%s' module set to triple: %s "
                        "(architecture %s)",
                        __FUNCTION__, file.GetPath().c_str(),
                        spec_triple.getTriple().c_str(),
                        spec.GetArchitecture().GetArchitectureName());

          if (!uuid.IsValid()) {
            uint32_t core_notes_crc = 0;

            if (!gnu_debuglink_crc) {
              static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
              lldb_private::Timer scoped_timer(
                  func_cat,
                  "Calculating module crc32 %s with size %" PRIu64 " KiB",
                  file.GetLastPathComponent().AsCString(),
                  (file.GetByteSize() - file_offset) / 1024);

              // For core files - which usually don't happen to have a
              // gnu_debuglink, and are pretty bulky - calculating whole
              // contents crc32 would be too much of luxury.  Thus we will need
              // to fallback to something simpler.
              if (header.e_type == llvm::ELF::ET_CORE) {
                size_t program_headers_end =
                    header.e_phoff + header.e_phnum * header.e_phentsize;
                if (program_headers_end > data_sp->GetByteSize()) {
                  data_sp = MapFileData(file, program_headers_end, file_offset);
                  if (data_sp)
                    data.SetData(data_sp);
                }
                ProgramHeaderColl program_headers;
                GetProgramHeaderInfo(program_headers, data, header);

                size_t segment_data_end = 0;
                for (ProgramHeaderCollConstIter I = program_headers.begin();
                     I != program_headers.end(); ++I) {
                  segment_data_end = std::max<unsigned long long>(
                      I->p_offset + I->p_filesz, segment_data_end);
                }

                if (segment_data_end > data_sp->GetByteSize()) {
                  data_sp = MapFileData(file, segment_data_end, file_offset);
                  if (data_sp)
                    data.SetData(data_sp);
                }

                core_notes_crc =
                    CalculateELFNotesSegmentsCRC32(program_headers, data);
              } else {
                // Need to map entire file into memory to calculate the crc.
                data_sp = MapFileData(file, -1, file_offset);
                if (data_sp) {
                  data.SetData(data_sp);
                  gnu_debuglink_crc = calc_gnu_debuglink_crc32(
                      data.GetDataStart(), data.GetByteSize());
                }
              }
            }
            if (gnu_debuglink_crc) {
              // Use 4 bytes of crc from the .gnu_debuglink section.
              uint32_t uuidt[4] = {gnu_debuglink_crc, 0, 0, 0};
              uuid.SetBytes(uuidt, sizeof(uuidt));
            } else if (core_notes_crc) {
              // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make
              // it look different form
              // .gnu_debuglink crc followed by 4 bytes of note segments crc.
              uint32_t uuidt[4] = {g_core_uuid_magic, core_notes_crc, 0, 0};
              uuid.SetBytes(uuidt, sizeof(uuidt));
            }
          }

          specs.Append(spec);
        }
      }
    }
  }

  return specs.GetSize() - initial_count;
}

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

uint32_t ObjectFileELF::GetPluginVersion() { return m_plugin_version; }
//------------------------------------------------------------------
// ObjectFile protocol
//------------------------------------------------------------------

ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
                             DataBufferSP &data_sp, lldb::offset_t data_offset,
                             const FileSpec *file, lldb::offset_t file_offset,
                             lldb::offset_t length)
    : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
      m_header(), m_uuid(), m_gnu_debuglink_file(), m_gnu_debuglink_crc(0),
      m_program_headers(), m_section_headers(), m_dynamic_symbols(),
      m_filespec_ap(), m_entry_point_address(), m_arch_spec() {
  if (file)
    m_file = *file;
  ::memset(&m_header, 0, sizeof(m_header));
}

ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
                             DataBufferSP &header_data_sp,
                             const lldb::ProcessSP &process_sp,
                             addr_t header_addr)
    : ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
      m_header(), m_uuid(), m_gnu_debuglink_file(), m_gnu_debuglink_crc(0),
      m_program_headers(), m_section_headers(), m_dynamic_symbols(),
      m_filespec_ap(), m_entry_point_address(), m_arch_spec() {
  ::memset(&m_header, 0, sizeof(m_header));
}

ObjectFileELF::~ObjectFileELF() {}

bool ObjectFileELF::IsExecutable() const {
  return ((m_header.e_type & ET_EXEC) != 0) || (m_header.e_entry != 0);
}

bool ObjectFileELF::SetLoadAddress(Target &target, lldb::addr_t value,
                                   bool value_is_offset) {
  ModuleSP module_sp = GetModule();
  if (module_sp) {
    size_t num_loaded_sections = 0;
    SectionList *section_list = GetSectionList();
    if (section_list) {
      if (!value_is_offset) {
        bool found_offset = false;
        for (size_t i = 1, count = GetProgramHeaderCount(); i <= count; ++i) {
          const elf::ELFProgramHeader *header = GetProgramHeaderByIndex(i);
          if (header == nullptr)
            continue;

          if (header->p_type != PT_LOAD || header->p_offset != 0)
            continue;

          value = value - header->p_vaddr;
          found_offset = true;
          break;
        }
        if (!found_offset)
          return false;
      }

      const size_t num_sections = section_list->GetSize();
      size_t sect_idx = 0;

      for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
        // Iterate through the object file sections to find all
        // of the sections that have SHF_ALLOC in their flag bits.
        SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
        if (section_sp && section_sp->Test(SHF_ALLOC)) {
          lldb::addr_t load_addr = section_sp->GetFileAddress();
          // We don't want to update the load address of a section with type
          // eSectionTypeAbsoluteAddress as they already have the absolute load
          // address
          // already specified
          if (section_sp->GetType() != eSectionTypeAbsoluteAddress)
            load_addr += value;

          // On 32-bit systems the load address have to fit into 4 bytes. The
          // rest of
          // the bytes are the overflow from the addition.
          if (GetAddressByteSize() == 4)
            load_addr &= 0xFFFFFFFF;

          if (target.GetSectionLoadList().SetSectionLoadAddress(section_sp,
                                                                load_addr))
            ++num_loaded_sections;
        }
      }
      return num_loaded_sections > 0;
    }
  }
  return false;
}

ByteOrder ObjectFileELF::GetByteOrder() const {
  if (m_header.e_ident[EI_DATA] == ELFDATA2MSB)
    return eByteOrderBig;
  if (m_header.e_ident[EI_DATA] == ELFDATA2LSB)
    return eByteOrderLittle;
  return eByteOrderInvalid;
}

uint32_t ObjectFileELF::GetAddressByteSize() const {
  return m_data.GetAddressByteSize();
}

AddressClass ObjectFileELF::GetAddressClass(addr_t file_addr) {
  Symtab *symtab = GetSymtab();
  if (!symtab)
    return eAddressClassUnknown;

  // The address class is determined based on the symtab. Ask it from the object
  // file what
  // contains the symtab information.
  ObjectFile *symtab_objfile = symtab->GetObjectFile();
  if (symtab_objfile != nullptr && symtab_objfile != this)
    return symtab_objfile->GetAddressClass(file_addr);

  auto res = ObjectFile::GetAddressClass(file_addr);
  if (res != eAddressClassCode)
    return res;

  auto ub = m_address_class_map.upper_bound(file_addr);
  if (ub == m_address_class_map.begin()) {
    // No entry in the address class map before the address. Return
    // default address class for an address in a code section.
    return eAddressClassCode;
  }

  // Move iterator to the address class entry preceding address
  --ub;

  return ub->second;
}

size_t ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I) {
  return std::distance(m_section_headers.begin(), I) + 1u;
}

size_t ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const {
  return std::distance(m_section_headers.begin(), I) + 1u;
}

bool ObjectFileELF::ParseHeader() {
  lldb::offset_t offset = 0;
  return m_header.Parse(m_data, &offset);
}

bool ObjectFileELF::GetUUID(lldb_private::UUID *uuid) {
  // Need to parse the section list to get the UUIDs, so make sure that's been
  // done.
  if (!ParseSectionHeaders() && GetType() != ObjectFile::eTypeCoreFile)
    return false;

  if (m_uuid.IsValid()) {
    // We have the full build id uuid.
    *uuid = m_uuid;
    return true;
  } else if (GetType() == ObjectFile::eTypeCoreFile) {
    uint32_t core_notes_crc = 0;

    if (!ParseProgramHeaders())
      return false;

    core_notes_crc = CalculateELFNotesSegmentsCRC32(m_program_headers, m_data);

    if (core_notes_crc) {
      // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make it
      // look different form .gnu_debuglink crc - followed by 4 bytes of note
      // segments crc.
      uint32_t uuidt[4] = {g_core_uuid_magic, core_notes_crc, 0, 0};
      m_uuid.SetBytes(uuidt, sizeof(uuidt));
    }
  } else {
    if (!m_gnu_debuglink_crc)
      m_gnu_debuglink_crc =
          calc_gnu_debuglink_crc32(m_data.GetDataStart(), m_data.GetByteSize());
    if (m_gnu_debuglink_crc) {
      // Use 4 bytes of crc from the .gnu_debuglink section.
      uint32_t uuidt[4] = {m_gnu_debuglink_crc, 0, 0, 0};
      m_uuid.SetBytes(uuidt, sizeof(uuidt));
    }
  }

  if (m_uuid.IsValid()) {
    *uuid = m_uuid;
    return true;
  }

  return false;
}

lldb_private::FileSpecList ObjectFileELF::GetDebugSymbolFilePaths() {
  FileSpecList file_spec_list;

  if (!m_gnu_debuglink_file.empty()) {
    FileSpec file_spec(m_gnu_debuglink_file, false);
    file_spec_list.Append(file_spec);
  }
  return file_spec_list;
}

uint32_t ObjectFileELF::GetDependentModules(FileSpecList &files) {
  size_t num_modules = ParseDependentModules();
  uint32_t num_specs = 0;

  for (unsigned i = 0; i < num_modules; ++i) {
    if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i)))
      num_specs++;
  }

  return num_specs;
}

Address ObjectFileELF::GetImageInfoAddress(Target *target) {
  if (!ParseDynamicSymbols())
    return Address();

  SectionList *section_list = GetSectionList();
  if (!section_list)
    return Address();

  // Find the SHT_DYNAMIC (.dynamic) section.
  SectionSP dynsym_section_sp(
      section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true));
  if (!dynsym_section_sp)
    return Address();
  assert(dynsym_section_sp->GetObjectFile() == this);

  user_id_t dynsym_id = dynsym_section_sp->GetID();
  const ELFSectionHeaderInfo *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id);
  if (!dynsym_hdr)
    return Address();

  for (size_t i = 0; i < m_dynamic_symbols.size(); ++i) {
    ELFDynamic &symbol = m_dynamic_symbols[i];

    if (symbol.d_tag == DT_DEBUG) {
      // Compute the offset as the number of previous entries plus the
      // size of d_tag.
      addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
      return Address(dynsym_section_sp, offset);
    }
    // MIPS executables uses DT_MIPS_RLD_MAP_REL to support PIE. DT_MIPS_RLD_MAP
    // exists in non-PIE.
    else if ((symbol.d_tag == DT_MIPS_RLD_MAP ||
              symbol.d_tag == DT_MIPS_RLD_MAP_REL) &&
             target) {
      addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
      addr_t dyn_base = dynsym_section_sp->GetLoadBaseAddress(target);
      if (dyn_base == LLDB_INVALID_ADDRESS)
        return Address();

      Status error;
      if (symbol.d_tag == DT_MIPS_RLD_MAP) {
        // DT_MIPS_RLD_MAP tag stores an absolute address of the debug pointer.
        Address addr;
        if (target->ReadPointerFromMemory(dyn_base + offset, false, error,
                                          addr))
          return addr;
      }
      if (symbol.d_tag == DT_MIPS_RLD_MAP_REL) {
        // DT_MIPS_RLD_MAP_REL tag stores the offset to the debug pointer,
        // relative to the address of the tag.
        uint64_t rel_offset;
        rel_offset = target->ReadUnsignedIntegerFromMemory(
            dyn_base + offset, false, GetAddressByteSize(), UINT64_MAX, error);
        if (error.Success() && rel_offset != UINT64_MAX) {
          Address addr;
          addr_t debug_ptr_address =
              dyn_base + (offset - GetAddressByteSize()) + rel_offset;
          addr.SetOffset(debug_ptr_address);
          return addr;
        }
      }
    }
  }

  return Address();
}

lldb_private::Address ObjectFileELF::GetEntryPointAddress() {
  if (m_entry_point_address.IsValid())
    return m_entry_point_address;

  if (!ParseHeader() || !IsExecutable())
    return m_entry_point_address;

  SectionList *section_list = GetSectionList();
  addr_t offset = m_header.e_entry;

  if (!section_list)
    m_entry_point_address.SetOffset(offset);
  else
    m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list);
  return m_entry_point_address;
}

//----------------------------------------------------------------------
// ParseDependentModules
//----------------------------------------------------------------------
size_t ObjectFileELF::ParseDependentModules() {
  if (m_filespec_ap.get())
    return m_filespec_ap->GetSize();

  m_filespec_ap.reset(new FileSpecList());

  if (!ParseSectionHeaders())
    return 0;

  SectionList *section_list = GetSectionList();
  if (!section_list)
    return 0;

  // Find the SHT_DYNAMIC section.
  Section *dynsym =
      section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true)
          .get();
  if (!dynsym)
    return 0;
  assert(dynsym->GetObjectFile() == this);

  const ELFSectionHeaderInfo *header = GetSectionHeaderByIndex(dynsym->GetID());
  if (!header)
    return 0;
  // sh_link: section header index of string table used by entries in the
  // section.
  Section *dynstr = section_list->FindSectionByID(header->sh_link + 1).get();
  if (!dynstr)
    return 0;

  DataExtractor dynsym_data;
  DataExtractor dynstr_data;
  if (ReadSectionData(dynsym, dynsym_data) &&
      ReadSectionData(dynstr, dynstr_data)) {
    ELFDynamic symbol;
    const lldb::offset_t section_size = dynsym_data.GetByteSize();
    lldb::offset_t offset = 0;

    // The only type of entries we are concerned with are tagged DT_NEEDED,
    // yielding the name of a required library.
    while (offset < section_size) {
      if (!symbol.Parse(dynsym_data, &offset))
        break;

      if (symbol.d_tag != DT_NEEDED)
        continue;

      uint32_t str_index = static_cast<uint32_t>(symbol.d_val);
      const char *lib_name = dynstr_data.PeekCStr(str_index);
      m_filespec_ap->Append(FileSpec(lib_name, true));
    }
  }

  return m_filespec_ap->GetSize();
}

//----------------------------------------------------------------------
// GetProgramHeaderInfo
//----------------------------------------------------------------------
size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
                                           DataExtractor &object_data,
                                           const ELFHeader &header) {
  // We have already parsed the program headers
  if (!program_headers.empty())
    return program_headers.size();

  // If there are no program headers to read we are done.
  if (header.e_phnum == 0)
    return 0;

  program_headers.resize(header.e_phnum);
  if (program_headers.size() != header.e_phnum)
    return 0;

  const size_t ph_size = header.e_phnum * header.e_phentsize;
  const elf_off ph_offset = header.e_phoff;
  DataExtractor data;
  if (data.SetData(object_data, ph_offset, ph_size) != ph_size)
    return 0;

  uint32_t idx;
  lldb::offset_t offset;
  for (idx = 0, offset = 0; idx < header.e_phnum; ++idx) {
    if (program_headers[idx].Parse(data, &offset) == false)
      break;
  }

  if (idx < program_headers.size())
    program_headers.resize(idx);

  return program_headers.size();
}

//----------------------------------------------------------------------
// ParseProgramHeaders
//----------------------------------------------------------------------
size_t ObjectFileELF::ParseProgramHeaders() {
  return GetProgramHeaderInfo(m_program_headers, m_data, m_header);
}

lldb_private::Status
ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
                                           lldb_private::ArchSpec &arch_spec,
                                           lldb_private::UUID &uuid) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES));
  Status error;

  lldb::offset_t offset = 0;

  while (true) {
    // Parse the note header.  If this fails, bail out.
    const lldb::offset_t note_offset = offset;
    ELFNote note = ELFNote();
    if (!note.Parse(data, &offset)) {
      // We're done.
      return error;
    }

    if (log)
      log->Printf("ObjectFileELF::%s parsing note name='%s', type=%" PRIu32,
                  __FUNCTION__, note.n_name.c_str(), note.n_type);

    // Process FreeBSD ELF notes.
    if ((note.n_name == LLDB_NT_OWNER_FREEBSD) &&
        (note.n_type == LLDB_NT_FREEBSD_ABI_TAG) &&
        (note.n_descsz == LLDB_NT_FREEBSD_ABI_SIZE)) {
      // Pull out the min version info.
      uint32_t version_info;
      if (data.GetU32(&offset, &version_info, 1) == nullptr) {
        error.SetErrorString("failed to read FreeBSD ABI note payload");
        return error;
      }

      // Convert the version info into a major/minor number.
      const uint32_t version_major = version_info / 100000;
      const uint32_t version_minor = (version_info / 1000) % 100;

      char os_name[32];
      snprintf(os_name, sizeof(os_name), "freebsd%" PRIu32 ".%" PRIu32,
               version_major, version_minor);

      // Set the elf OS version to FreeBSD.  Also clear the vendor.
      arch_spec.GetTriple().setOSName(os_name);
      arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);

      if (log)
        log->Printf("ObjectFileELF::%s detected FreeBSD %" PRIu32 ".%" PRIu32
                    ".%" PRIu32,
                    __FUNCTION__, version_major, version_minor,
                    static_cast<uint32_t>(version_info % 1000));
    }
    // Process GNU ELF notes.
    else if (note.n_name == LLDB_NT_OWNER_GNU) {
      switch (note.n_type) {
      case LLDB_NT_GNU_ABI_TAG:
        if (note.n_descsz == LLDB_NT_GNU_ABI_SIZE) {
          // Pull out the min OS version supporting the ABI.
          uint32_t version_info[4];
          if (data.GetU32(&offset, &version_info[0], note.n_descsz / 4) ==
              nullptr) {
            error.SetErrorString("failed to read GNU ABI note payload");
            return error;
          }

          // Set the OS per the OS field.
          switch (version_info[0]) {
          case LLDB_NT_GNU_ABI_OS_LINUX:
            arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
            arch_spec.GetTriple().setVendor(
                llvm::Triple::VendorType::UnknownVendor);
            if (log)
              log->Printf(
                  "ObjectFileELF::%s detected Linux, min version %" PRIu32
                  ".%" PRIu32 ".%" PRIu32,
                  __FUNCTION__, version_info[1], version_info[2],
                  version_info[3]);
            // FIXME we have the minimal version number, we could be propagating
            // that.  version_info[1] = OS Major, version_info[2] = OS Minor,
            // version_info[3] = Revision.
            break;
          case LLDB_NT_GNU_ABI_OS_HURD:
            arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS);
            arch_spec.GetTriple().setVendor(
                llvm::Triple::VendorType::UnknownVendor);
            if (log)
              log->Printf("ObjectFileELF::%s detected Hurd (unsupported), min "
                          "version %" PRIu32 ".%" PRIu32 ".%" PRIu32,
                          __FUNCTION__, version_info[1], version_info[2],
                          version_info[3]);
            break;
          case LLDB_NT_GNU_ABI_OS_SOLARIS:
            arch_spec.GetTriple().setOS(llvm::Triple::OSType::Solaris);
            arch_spec.GetTriple().setVendor(
                llvm::Triple::VendorType::UnknownVendor);
            if (log)
              log->Printf(
                  "ObjectFileELF::%s detected Solaris, min version %" PRIu32
                  ".%" PRIu32 ".%" PRIu32,
                  __FUNCTION__, version_info[1], version_info[2],
                  version_info[3]);
            break;
          default:
            if (log)
              log->Printf(
                  "ObjectFileELF::%s unrecognized OS in note, id %" PRIu32
                  ", min version %" PRIu32 ".%" PRIu32 ".%" PRIu32,
                  __FUNCTION__, version_info[0], version_info[1],
                  version_info[2], version_info[3]);
            break;
          }
        }
        break;

      case LLDB_NT_GNU_BUILD_ID_TAG:
        // Only bother processing this if we don't already have the uuid set.
        if (!uuid.IsValid()) {
          // 16 bytes is UUID|MD5, 20 bytes is SHA1. Other linkers may produce a
          // build-id of a different
          // length. Accept it as long as it's at least 4 bytes as it will be
          // better than our own crc32.
          if (note.n_descsz >= 4 && note.n_descsz <= 20) {
            uint8_t uuidbuf[20];
            if (data.GetU8(&offset, &uuidbuf, note.n_descsz) == nullptr) {
              error.SetErrorString("failed to read GNU_BUILD_ID note payload");
              return error;
            }

            // Save the build id as the UUID for the module.
            uuid.SetBytes(uuidbuf, note.n_descsz);
          }
        }
        break;
      }
      if (arch_spec.IsMIPS() &&
          arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS)
        // The note.n_name == LLDB_NT_OWNER_GNU is valid for Linux platform
        arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
    }
    // Process NetBSD ELF notes.
    else if ((note.n_name == LLDB_NT_OWNER_NETBSD) &&
             (note.n_type == LLDB_NT_NETBSD_ABI_TAG) &&
             (note.n_descsz == LLDB_NT_NETBSD_ABI_SIZE)) {
      // Pull out the min version info.
      uint32_t version_info;
      if (data.GetU32(&offset, &version_info, 1) == nullptr) {
        error.SetErrorString("failed to read NetBSD ABI note payload");
        return error;
      }

      // Set the elf OS version to NetBSD.  Also clear the vendor.
      arch_spec.GetTriple().setOS(llvm::Triple::OSType::NetBSD);
      arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);

      if (log)
        log->Printf(
            "ObjectFileELF::%s detected NetBSD, min version constant %" PRIu32,
            __FUNCTION__, version_info);
    }
    // Process OpenBSD ELF notes.
    else if (note.n_name == LLDB_NT_OWNER_OPENBSD) {
      // Set the elf OS version to OpenBSD.  Also clear the vendor.
      arch_spec.GetTriple().setOS(llvm::Triple::OSType::OpenBSD);
      arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
    }
    // Process CSR kalimba notes
    else if ((note.n_type == LLDB_NT_GNU_ABI_TAG) &&
             (note.n_name == LLDB_NT_OWNER_CSR)) {
      arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS);
      arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::CSR);

      // TODO At some point the description string could be processed.
      // It could provide a steer towards the kalimba variant which
      // this ELF targets.
      if (note.n_descsz) {
        const char *cstr =
            data.GetCStr(&offset, llvm::alignTo(note.n_descsz, 4));
        (void)cstr;
      }
    } else if (note.n_name == LLDB_NT_OWNER_ANDROID) {
      arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
      arch_spec.GetTriple().setEnvironment(
          llvm::Triple::EnvironmentType::Android);
    } else if (note.n_name == LLDB_NT_OWNER_LINUX) {
      // This is sometimes found in core files and usually contains extended
      // register info
      arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
    } else if (note.n_name == LLDB_NT_OWNER_CORE) {
      // Parse the NT_FILE to look for stuff in paths to shared libraries
      // As the contents look like this in a 64 bit ELF core file:
      // count     = 0x000000000000000a (10)
      // page_size = 0x0000000000001000 (4096)
      // Index start              end                file_ofs           path
      // ===== ------------------ ------------------ ------------------
      // -------------------------------------
      // [  0] 0x0000000000400000 0x0000000000401000 0x0000000000000000
      // /tmp/a.out
      // [  1] 0x0000000000600000 0x0000000000601000 0x0000000000000000
      // /tmp/a.out
      // [  2] 0x0000000000601000 0x0000000000602000 0x0000000000000001
      // /tmp/a.out
      // [  3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000
      // /lib/x86_64-linux-gnu/libc-2.19.so
      // [  4] 0x00007fa79cba8000 0x00007fa79cda7000 0x00000000000001bb
      // /lib/x86_64-linux-gnu/libc-2.19.so
      // [  5] 0x00007fa79cda7000 0x00007fa79cdab000 0x00000000000001ba
      // /lib/x86_64-linux-gnu/libc-2.19.so
      // [  6] 0x00007fa79cdab000 0x00007fa79cdad000 0x00000000000001be
      // /lib/x86_64-linux-gnu/libc-2.19.so
      // [  7] 0x00007fa79cdb2000 0x00007fa79cdd5000 0x0000000000000000
      // /lib/x86_64-linux-gnu/ld-2.19.so
      // [  8] 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022
      // /lib/x86_64-linux-gnu/ld-2.19.so
      // [  9] 0x00007fa79cfd5000 0x00007fa79cfd6000 0x0000000000000023
      // /lib/x86_64-linux-gnu/ld-2.19.so
      // In the 32 bit ELFs the count, page_size, start, end, file_ofs are
      // uint32_t
      // For reference: see readelf source code (in binutils).
      if (note.n_type == NT_FILE) {
        uint64_t count = data.GetAddress(&offset);
        const char *cstr;
        data.GetAddress(&offset); // Skip page size
        offset += count * 3 *
                  data.GetAddressByteSize(); // Skip all start/end/file_ofs
        for (size_t i = 0; i < count; ++i) {
          cstr = data.GetCStr(&offset);
          if (cstr == nullptr) {
            error.SetErrorStringWithFormat("ObjectFileELF::%s trying to read "
                                           "at an offset after the end "
                                           "(GetCStr returned nullptr)",
                                           __FUNCTION__);
            return error;
          }
          llvm::StringRef path(cstr);
          if (path.contains("/lib/x86_64-linux-gnu") || path.contains("/lib/i386-linux-gnu")) {
            arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
            break;
          }
        }
        if (arch_spec.IsMIPS() &&
            arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS)
          // In case of MIPSR6, the LLDB_NT_OWNER_GNU note is missing
          // for some cases (e.g. compile with -nostdlib)
          // Hence set OS to Linux
          arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); 
      }
    }

    // Calculate the offset of the next note just in case "offset" has been used
    // to poke at the contents of the note data
    offset = note_offset + note.GetByteSize();
  }

  return error;
}

void ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length,
                                       ArchSpec &arch_spec) {
  lldb::offset_t Offset = 0;

  uint8_t FormatVersion = data.GetU8(&Offset);
  if (FormatVersion != llvm::ARMBuildAttrs::Format_Version)
    return;

  Offset = Offset + sizeof(uint32_t); // Section Length
  llvm::StringRef VendorName = data.GetCStr(&Offset);

  if (VendorName != "aeabi")
    return;

  if (arch_spec.GetTriple().getEnvironment() ==
      llvm::Triple::UnknownEnvironment)
    arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI);

  while (Offset < length) {
    uint8_t Tag = data.GetU8(&Offset);
    uint32_t Size = data.GetU32(&Offset);

    if (Tag != llvm::ARMBuildAttrs::File || Size == 0)
      continue;

    while (Offset < length) {
      uint64_t Tag = data.GetULEB128(&Offset);
      switch (Tag) {
      default:
        if (Tag < 32)
          data.GetULEB128(&Offset);
        else if (Tag % 2 == 0)
          data.GetULEB128(&Offset);
        else
          data.GetCStr(&Offset);

        break;

      case llvm::ARMBuildAttrs::CPU_raw_name:
      case llvm::ARMBuildAttrs::CPU_name:
        data.GetCStr(&Offset);

        break;

      case llvm::ARMBuildAttrs::ABI_VFP_args: {
        uint64_t VFPArgs = data.GetULEB128(&Offset);

        if (VFPArgs == llvm::ARMBuildAttrs::BaseAAPCS) {
          if (arch_spec.GetTriple().getEnvironment() ==
                  llvm::Triple::UnknownEnvironment ||
              arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABIHF)
            arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI);

          arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float);
        } else if (VFPArgs == llvm::ARMBuildAttrs::HardFPAAPCS) {
          if (arch_spec.GetTriple().getEnvironment() ==
                  llvm::Triple::UnknownEnvironment ||
              arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABI)
            arch_spec.GetTriple().setEnvironment(llvm::Triple::EABIHF);

          arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float);
        }

        break;
      }
      }
    }
  }
}

//----------------------------------------------------------------------
// GetSectionHeaderInfo
//----------------------------------------------------------------------
size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
                                           DataExtractor &object_data,
                                           const elf::ELFHeader &header,
                                           lldb_private::UUID &uuid,
                                           std::string &gnu_debuglink_file,
                                           uint32_t &gnu_debuglink_crc,
                                           ArchSpec &arch_spec) {
  // Don't reparse the section headers if we already did that.
  if (!section_headers.empty())
    return section_headers.size();

  // Only initialize the arch_spec to okay defaults if they're not already set.
  // We'll refine this with note data as we parse the notes.
  if (arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS) {
    llvm::Triple::OSType ostype;
    llvm::Triple::OSType spec_ostype;
    const uint32_t sub_type = subTypeFromElfHeader(header);
    arch_spec.SetArchitecture(eArchTypeELF, header.e_machine, sub_type,
                              header.e_ident[EI_OSABI]);
    
    // Validate if it is ok to remove GetOsFromOSABI.
    // Note, that now the OS is determined based on EI_OSABI flag and
    // the info extracted from ELF notes (see RefineModuleDetailsFromNote).
    // However in some cases that still might be not enough: for example
    // a shared library might not have any notes at all
    // and have EI_OSABI flag set to System V,
    // as result the OS will be set to UnknownOS.
    GetOsFromOSABI(header.e_ident[EI_OSABI], ostype);
    spec_ostype = arch_spec.GetTriple().getOS();
    assert(spec_ostype == ostype);
    UNUSED_IF_ASSERT_DISABLED(spec_ostype);
  }

  if (arch_spec.GetMachine() == llvm::Triple::mips ||
      arch_spec.GetMachine() == llvm::Triple::mipsel ||
      arch_spec.GetMachine() == llvm::Triple::mips64 ||
      arch_spec.GetMachine() == llvm::Triple::mips64el) {
    switch (header.e_flags & llvm::ELF::EF_MIPS_ARCH_ASE) {
    case llvm::ELF::EF_MIPS_MICROMIPS:
      arch_spec.SetFlags(ArchSpec::eMIPSAse_micromips);
      break;
    case llvm::ELF::EF_MIPS_ARCH_ASE_M16:
      arch_spec.SetFlags(ArchSpec::eMIPSAse_mips16);
      break;
    case llvm::ELF::EF_MIPS_ARCH_ASE_MDMX:
      arch_spec.SetFlags(ArchSpec::eMIPSAse_mdmx);
      break;
    default:
      break;
    }
  }

  if (arch_spec.GetMachine() == llvm::Triple::arm ||
      arch_spec.GetMachine() == llvm::Triple::thumb) {
    if (header.e_flags & llvm::ELF::EF_ARM_SOFT_FLOAT)
      arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float);
    else if (header.e_flags & llvm::ELF::EF_ARM_VFP_FLOAT)
      arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float);
  }

  // If there are no section headers we are done.
  if (header.e_shnum == 0)
    return 0;

  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES));

  section_headers.resize(header.e_shnum);
  if (section_headers.size() != header.e_shnum)
    return 0;

  const size_t sh_size = header.e_shnum * header.e_shentsize;
  const elf_off sh_offset = header.e_shoff;
  DataExtractor sh_data;
  if (sh_data.SetData(object_data, sh_offset, sh_size) != sh_size)
    return 0;

  uint32_t idx;
  lldb::offset_t offset;
  for (idx = 0, offset = 0; idx < header.e_shnum; ++idx) {
    if (section_headers[idx].Parse(sh_data, &offset) == false)
      break;
  }
  if (idx < section_headers.size())
    section_headers.resize(idx);

  const unsigned strtab_idx = header.e_shstrndx;
  if (strtab_idx && strtab_idx < section_headers.size()) {
    const ELFSectionHeaderInfo &sheader = section_headers[strtab_idx];
    const size_t byte_size = sheader.sh_size;
    const Elf64_Off offset = sheader.sh_offset;
    lldb_private::DataExtractor shstr_data;

    if (shstr_data.SetData(object_data, offset, byte_size) == byte_size) {
      for (SectionHeaderCollIter I = section_headers.begin();
           I != section_headers.end(); ++I) {
        static ConstString g_sect_name_gnu_debuglink(".gnu_debuglink");
        const ELFSectionHeaderInfo &sheader = *I;
        const uint64_t section_size =
            sheader.sh_type == SHT_NOBITS ? 0 : sheader.sh_size;
        ConstString name(shstr_data.PeekCStr(I->sh_name));

        I->section_name = name;

        if (arch_spec.IsMIPS()) {
          uint32_t arch_flags = arch_spec.GetFlags();
          DataExtractor data;
          if (sheader.sh_type == SHT_MIPS_ABIFLAGS) {

            if (section_size && (data.SetData(object_data, sheader.sh_offset,
                                              section_size) == section_size)) {
              // MIPS ASE Mask is at offset 12 in MIPS.abiflags section
              lldb::offset_t offset = 12; // MIPS ABI Flags Version: 0
              arch_flags |= data.GetU32(&offset);

              // The floating point ABI is at offset 7
              offset = 7;
              switch (data.GetU8(&offset)) {
              case llvm::Mips::Val_GNU_MIPS_ABI_FP_ANY:
                arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_ANY;
                break;
              case llvm::Mips::Val_GNU_MIPS_ABI_FP_DOUBLE:
                arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_DOUBLE;
                break;
              case llvm::Mips::Val_GNU_MIPS_ABI_FP_SINGLE:
                arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SINGLE;
                break;
              case llvm::Mips::Val_GNU_MIPS_ABI_FP_SOFT:
                arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT;
                break;
              case llvm::Mips::Val_GNU_MIPS_ABI_FP_OLD_64:
                arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_OLD_64;
                break;
              case llvm::Mips::Val_GNU_MIPS_ABI_FP_XX:
                arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_XX;
                break;
              case llvm::Mips::Val_GNU_MIPS_ABI_FP_64:
                arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64;
                break;
              case llvm::Mips::Val_GNU_MIPS_ABI_FP_64A:
                arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64A;
                break;
              }
            }
          }
          // Settings appropriate ArchSpec ABI Flags
          switch (header.e_flags & llvm::ELF::EF_MIPS_ABI) {
          case llvm::ELF::EF_MIPS_ABI_O32:
            arch_flags |= lldb_private::ArchSpec::eMIPSABI_O32;
            break;
          case EF_MIPS_ABI_O64:
            arch_flags |= lldb_private::ArchSpec::eMIPSABI_O64;
            break;
          case EF_MIPS_ABI_EABI32:
            arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI32;
            break;
          case EF_MIPS_ABI_EABI64:
            arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI64;
            break;
          default:
            // ABI Mask doesn't cover N32 and N64 ABI.
            if (header.e_ident[EI_CLASS] == llvm::ELF::ELFCLASS64)
              arch_flags |= lldb_private::ArchSpec::eMIPSABI_N64;
            else if (header.e_flags & llvm::ELF::EF_MIPS_ABI2)
              arch_flags |= lldb_private::ArchSpec::eMIPSABI_N32;
            break;
          }
          arch_spec.SetFlags(arch_flags);
        }

        if (arch_spec.GetMachine() == llvm::Triple::arm ||
            arch_spec.GetMachine() == llvm::Triple::thumb) {
          DataExtractor data;

          if (sheader.sh_type == SHT_ARM_ATTRIBUTES && section_size != 0 &&
              data.SetData(object_data, sheader.sh_offset, section_size) == section_size)
            ParseARMAttributes(data, section_size, arch_spec);
        }

        if (name == g_sect_name_gnu_debuglink) {
          DataExtractor data;
          if (section_size && (data.SetData(object_data, sheader.sh_offset,
                                            section_size) == section_size)) {
            lldb::offset_t gnu_debuglink_offset = 0;
            gnu_debuglink_file = data.GetCStr(&gnu_debuglink_offset);
            gnu_debuglink_offset = llvm::alignTo(gnu_debuglink_offset, 4);
            data.GetU32(&gnu_debuglink_offset, &gnu_debuglink_crc, 1);
          }
        }

        // Process ELF note section entries.
        bool is_note_header = (sheader.sh_type == SHT_NOTE);

        // The section header ".note.android.ident" is stored as a
        // PROGBITS type header but it is actually a note header.
        static ConstString g_sect_name_android_ident(".note.android.ident");
        if (!is_note_header && name == g_sect_name_android_ident)
          is_note_header = true;

        if (is_note_header) {
          // Allow notes to refine module info.
          DataExtractor data;
          if (section_size && (data.SetData(object_data, sheader.sh_offset,
                                            section_size) == section_size)) {
            Status error = RefineModuleDetailsFromNote(data, arch_spec, uuid);
            if (error.Fail()) {
              if (log)
                log->Printf("ObjectFileELF::%s ELF note processing failed: %s",
                            __FUNCTION__, error.AsCString());
            }
          }
        }
      }

      // Make any unknown triple components to be unspecified unknowns.
      if (arch_spec.GetTriple().getVendor() == llvm::Triple::UnknownVendor)
        arch_spec.GetTriple().setVendorName(llvm::StringRef());
      if (arch_spec.GetTriple().getOS() == llvm::Triple::UnknownOS)
        arch_spec.GetTriple().setOSName(llvm::StringRef());

      return section_headers.size();
    }
  }

  section_headers.clear();
  return 0;
}

size_t ObjectFileELF::GetProgramHeaderCount() { return ParseProgramHeaders(); }

const elf::ELFProgramHeader *
ObjectFileELF::GetProgramHeaderByIndex(lldb::user_id_t id) {
  if (!id || !ParseProgramHeaders())
    return NULL;

  if (--id < m_program_headers.size())
    return &m_program_headers[id];

  return NULL;
}

DataExtractor ObjectFileELF::GetSegmentDataByIndex(lldb::user_id_t id) {
  const elf::ELFProgramHeader *segment_header = GetProgramHeaderByIndex(id);
  if (segment_header == NULL)
    return DataExtractor();
  return DataExtractor(m_data, segment_header->p_offset,
                       segment_header->p_filesz);
}

llvm::StringRef
ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const {
  size_t pos = symbol_name.find('@');
  return symbol_name.substr(0, pos);
}

//----------------------------------------------------------------------
// ParseSectionHeaders
//----------------------------------------------------------------------
size_t ObjectFileELF::ParseSectionHeaders() {
  return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid,
                              m_gnu_debuglink_file, m_gnu_debuglink_crc,
                              m_arch_spec);
}

const ObjectFileELF::ELFSectionHeaderInfo *
ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id) {
  if (!id || !ParseSectionHeaders())
    return NULL;

  if (--id < m_section_headers.size())
    return &m_section_headers[id];

  return NULL;
}

lldb::user_id_t ObjectFileELF::GetSectionIndexByName(const char *name) {
  if (!name || !name[0] || !ParseSectionHeaders())
    return 0;
  for (size_t i = 1; i < m_section_headers.size(); ++i)
    if (m_section_headers[i].section_name == ConstString(name))
      return i;
  return 0;
}

void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
  if (!m_sections_ap.get() && ParseSectionHeaders()) {
    m_sections_ap.reset(new SectionList());

    // Object files frequently have 0 for every section address, meaning we
    // need to compute synthetic addresses in order for "file addresses" from
    // different sections to not overlap
    bool synthaddrs = (CalculateType() == ObjectFile::Type::eTypeObjectFile);
    uint64_t nextaddr = 0;

    for (SectionHeaderCollIter I = m_section_headers.begin();
         I != m_section_headers.end(); ++I) {
      const ELFSectionHeaderInfo &header = *I;

      ConstString &name = I->section_name;
      const uint64_t file_size =
          header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
      const uint64_t vm_size = header.sh_flags & SHF_ALLOC ? header.sh_size : 0;

      static ConstString g_sect_name_text(".text");
      static ConstString g_sect_name_data(".data");
      static ConstString g_sect_name_bss(".bss");
      static ConstString g_sect_name_tdata(".tdata");
      static ConstString g_sect_name_tbss(".tbss");
      static ConstString g_sect_name_dwarf_debug_abbrev(".debug_abbrev");
      static ConstString g_sect_name_dwarf_debug_addr(".debug_addr");
      static ConstString g_sect_name_dwarf_debug_aranges(".debug_aranges");
      static ConstString g_sect_name_dwarf_debug_cu_index(".debug_cu_index");
      static ConstString g_sect_name_dwarf_debug_frame(".debug_frame");
      static ConstString g_sect_name_dwarf_debug_info(".debug_info");
      static ConstString g_sect_name_dwarf_debug_line(".debug_line");
      static ConstString g_sect_name_dwarf_debug_loc(".debug_loc");
      static ConstString g_sect_name_dwarf_debug_macinfo(".debug_macinfo");
      static ConstString g_sect_name_dwarf_debug_macro(".debug_macro");
      static ConstString g_sect_name_dwarf_debug_pubnames(".debug_pubnames");
      static ConstString g_sect_name_dwarf_debug_pubtypes(".debug_pubtypes");
      static ConstString g_sect_name_dwarf_debug_ranges(".debug_ranges");
      static ConstString g_sect_name_dwarf_debug_str(".debug_str");
      static ConstString g_sect_name_dwarf_debug_str_offsets(
          ".debug_str_offsets");
      static ConstString g_sect_name_dwarf_debug_abbrev_dwo(
          ".debug_abbrev.dwo");
      static ConstString g_sect_name_dwarf_debug_info_dwo(".debug_info.dwo");
      static ConstString g_sect_name_dwarf_debug_line_dwo(".debug_line.dwo");
      static ConstString g_sect_name_dwarf_debug_macro_dwo(".debug_macro.dwo");
      static ConstString g_sect_name_dwarf_debug_loc_dwo(".debug_loc.dwo");
      static ConstString g_sect_name_dwarf_debug_str_dwo(".debug_str.dwo");
      static ConstString g_sect_name_dwarf_debug_str_offsets_dwo(
          ".debug_str_offsets.dwo");
      static ConstString g_sect_name_eh_frame(".eh_frame");
      static ConstString g_sect_name_swift_ast(".swift_ast");
      static ConstString g_sect_name_arm_exidx(".ARM.exidx");
      static ConstString g_sect_name_arm_extab(".ARM.extab");
      static ConstString g_sect_name_go_symtab(".gosymtab");

      SectionType sect_type = eSectionTypeOther;

      bool is_thread_specific = false;

      if (name == g_sect_name_text)
        sect_type = eSectionTypeCode;
      else if (name == g_sect_name_data)
        sect_type = eSectionTypeData;
      else if (name == g_sect_name_bss)
        sect_type = eSectionTypeZeroFill;
      else if (name == g_sect_name_tdata) {
        sect_type = eSectionTypeData;
        is_thread_specific = true;
      } else if (name == g_sect_name_tbss) {
        sect_type = eSectionTypeZeroFill;
        is_thread_specific = true;
      }
      // .debug_abbrev – Abbreviations used in the .debug_info section
      // .debug_aranges – Lookup table for mapping addresses to compilation
      // units
      // .debug_frame – Call frame information
      // .debug_info – The core DWARF information section
      // .debug_line – Line number information
      // .debug_loc – Location lists used in DW_AT_location attributes
      // .debug_macinfo – Macro information
      // .debug_pubnames – Lookup table for mapping object and function names to
      // compilation units
      // .debug_pubtypes – Lookup table for mapping type names to compilation
      // units
      // .debug_ranges – Address ranges used in DW_AT_ranges attributes
      // .debug_str – String table used in .debug_info
      // MISSING? .gnu_debugdata - "mini debuginfo / MiniDebugInfo" section,
      // http://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html
      // MISSING? .debug-index -
      // http://src.chromium.org/viewvc/chrome/trunk/src/build/gdb-add-index?pathrev=144644
      // MISSING? .debug_types - Type descriptions from DWARF 4? See
      // http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo
      else if (name == g_sect_name_dwarf_debug_abbrev)
        sect_type = eSectionTypeDWARFDebugAbbrev;
      else if (name == g_sect_name_dwarf_debug_addr)
        sect_type = eSectionTypeDWARFDebugAddr;
      else if (name == g_sect_name_dwarf_debug_aranges)
        sect_type = eSectionTypeDWARFDebugAranges;
      else if (name == g_sect_name_dwarf_debug_cu_index)
        sect_type = eSectionTypeDWARFDebugCuIndex;
      else if (name == g_sect_name_dwarf_debug_frame)
        sect_type = eSectionTypeDWARFDebugFrame;
      else if (name == g_sect_name_dwarf_debug_info)
        sect_type = eSectionTypeDWARFDebugInfo;
      else if (name == g_sect_name_dwarf_debug_line)
        sect_type = eSectionTypeDWARFDebugLine;
      else if (name == g_sect_name_dwarf_debug_loc)
        sect_type = eSectionTypeDWARFDebugLoc;
      else if (name == g_sect_name_dwarf_debug_macinfo)
        sect_type = eSectionTypeDWARFDebugMacInfo;
      else if (name == g_sect_name_dwarf_debug_macro)
        sect_type = eSectionTypeDWARFDebugMacro;
      else if (name == g_sect_name_dwarf_debug_pubnames)
        sect_type = eSectionTypeDWARFDebugPubNames;
      else if (name == g_sect_name_dwarf_debug_pubtypes)
        sect_type = eSectionTypeDWARFDebugPubTypes;
      else if (name == g_sect_name_dwarf_debug_ranges)
        sect_type = eSectionTypeDWARFDebugRanges;
      else if (name == g_sect_name_dwarf_debug_str)
        sect_type = eSectionTypeDWARFDebugStr;
      else if (name == g_sect_name_dwarf_debug_str_offsets)
        sect_type = eSectionTypeDWARFDebugStrOffsets;
      else if (name == g_sect_name_dwarf_debug_abbrev_dwo)
        sect_type = eSectionTypeDWARFDebugAbbrev;
      else if (name == g_sect_name_dwarf_debug_info_dwo)
        sect_type = eSectionTypeDWARFDebugInfo;
      else if (name == g_sect_name_dwarf_debug_line_dwo)
        sect_type = eSectionTypeDWARFDebugLine;
      else if (name == g_sect_name_dwarf_debug_macro_dwo)
        sect_type = eSectionTypeDWARFDebugMacro;
      else if (name == g_sect_name_dwarf_debug_loc_dwo)
        sect_type = eSectionTypeDWARFDebugLoc;
      else if (name == g_sect_name_dwarf_debug_str_dwo)
        sect_type = eSectionTypeDWARFDebugStr;
      else if (name == g_sect_name_dwarf_debug_str_offsets_dwo)
        sect_type = eSectionTypeDWARFDebugStrOffsets;
      else if (name == g_sect_name_eh_frame)
        sect_type = eSectionTypeEHFrame;
      else if (name == g_sect_name_swift_ast)
        sect_type = eSectionTypeSwiftModules;
      else if (name == g_sect_name_arm_exidx)
        sect_type = eSectionTypeARMexidx;
      else if (name == g_sect_name_arm_extab)
        sect_type = eSectionTypeARMextab;
      else if (name == g_sect_name_go_symtab)
        sect_type = eSectionTypeGoSymtab;

      const uint32_t permissions =
          ((header.sh_flags & SHF_ALLOC) ? ePermissionsReadable : 0u) |
          ((header.sh_flags & SHF_WRITE) ? ePermissionsWritable : 0u) |
          ((header.sh_flags & SHF_EXECINSTR) ? ePermissionsExecutable : 0u);
      switch (header.sh_type) {
      case SHT_SYMTAB:
        assert(sect_type == eSectionTypeOther);
        sect_type = eSectionTypeELFSymbolTable;
        break;
      case SHT_DYNSYM:
        assert(sect_type == eSectionTypeOther);
        sect_type = eSectionTypeELFDynamicSymbols;
        break;
      case SHT_RELA:
      case SHT_REL:
        assert(sect_type == eSectionTypeOther);
        sect_type = eSectionTypeELFRelocationEntries;
        break;
      case SHT_DYNAMIC:
        assert(sect_type == eSectionTypeOther);
        sect_type = eSectionTypeELFDynamicLinkInfo;
        break;
      }

      if (eSectionTypeOther == sect_type) {
        // the kalimba toolchain assumes that ELF section names are free-form.
        // It does
        // support linkscripts which (can) give rise to various arbitrarily
        // named
        // sections being "Code" or "Data".
        sect_type = kalimbaSectionType(m_header, header);
      }

      const uint32_t target_bytes_size =
          (eSectionTypeData == sect_type || eSectionTypeZeroFill == sect_type)
              ? m_arch_spec.GetDataByteSize()
              : eSectionTypeCode == sect_type ? m_arch_spec.GetCodeByteSize()
                                              : 1;
      elf::elf_xword log2align =
          (header.sh_addralign == 0) ? 0 : llvm::Log2_64(header.sh_addralign);

      uint64_t addr = header.sh_addr;

      if ((header.sh_flags & SHF_ALLOC) && synthaddrs) {
          nextaddr =
              (nextaddr + header.sh_addralign - 1) & ~(header.sh_addralign - 1);
          addr = nextaddr;
          nextaddr += vm_size;
      }

      SectionSP section_sp(new Section(
          GetModule(), // Module to which this section belongs.
          this, // ObjectFile to which this section belongs and should read
                // section data from.
          SectionIndex(I),     // Section ID.
          name,                // Section name.
          sect_type,           // Section type.
          addr,                // VM address.
          vm_size,             // VM size in bytes of this section.
          header.sh_offset,    // Offset of this section in the file.
          file_size,           // Size of the section as found in the file.
          log2align,           // Alignment of the section
          header.sh_flags,     // Flags for this section.
          target_bytes_size)); // Number of host bytes per target byte

      section_sp->SetPermissions(permissions);
      if (is_thread_specific)
        section_sp->SetIsThreadSpecific(is_thread_specific);
      m_sections_ap->AddSection(section_sp);
    }
  }

  if (m_sections_ap.get()) {
    if (GetType() == eTypeDebugInfo) {
      static const SectionType g_sections[] = {
          eSectionTypeDWARFDebugAbbrev,   eSectionTypeDWARFDebugAddr,
          eSectionTypeDWARFDebugAranges,  eSectionTypeDWARFDebugCuIndex,
          eSectionTypeDWARFDebugFrame,    eSectionTypeDWARFDebugInfo,
          eSectionTypeDWARFDebugLine,     eSectionTypeDWARFDebugLoc,
          eSectionTypeDWARFDebugMacInfo,  eSectionTypeDWARFDebugPubNames,
          eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges,
          eSectionTypeDWARFDebugStr,      eSectionTypeDWARFDebugStrOffsets,
          eSectionTypeELFSymbolTable,
      };
      SectionList *elf_section_list = m_sections_ap.get();
      for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]);
           ++idx) {
        SectionType section_type = g_sections[idx];
        SectionSP section_sp(
            elf_section_list->FindSectionByType(section_type, true));
        if (section_sp) {
          SectionSP module_section_sp(
              unified_section_list.FindSectionByType(section_type, true));
          if (module_section_sp)
            unified_section_list.ReplaceSection(module_section_sp->GetID(),
                                                section_sp);
          else
            unified_section_list.AddSection(section_sp);
        }
      }
    } else {
      unified_section_list = *m_sections_ap;
    }
  }
}

// Find the arm/aarch64 mapping symbol character in the given symbol name.
// Mapping symbols have the
// form of "$<char>[.<any>]*". Additionally we recognize cases when the mapping
// symbol prefixed by
// an arbitrary string because if a symbol prefix added to each symbol in the
// object file with
// objcopy then the mapping symbols are also prefixed.
static char FindArmAarch64MappingSymbol(const char *symbol_name) {
  if (!symbol_name)
    return '\0';

  const char *dollar_pos = ::strchr(symbol_name, '$');
  if (!dollar_pos || dollar_pos[1] == '\0')
    return '\0';

  if (dollar_pos[2] == '\0' || dollar_pos[2] == '.')
    return dollar_pos[1];
  return '\0';
}

#define STO_MIPS_ISA (3 << 6)
#define STO_MICROMIPS (2 << 6)
#define IS_MICROMIPS(ST_OTHER) (((ST_OTHER)&STO_MIPS_ISA) == STO_MICROMIPS)

// private
unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
                                     SectionList *section_list,
                                     const size_t num_symbols,
                                     const DataExtractor &symtab_data,
                                     const DataExtractor &strtab_data) {
  ELFSymbol symbol;
  lldb::offset_t offset = 0;

  static ConstString text_section_name(".text");
  static ConstString init_section_name(".init");
  static ConstString fini_section_name(".fini");
  static ConstString ctors_section_name(".ctors");
  static ConstString dtors_section_name(".dtors");

  static ConstString data_section_name(".data");
  static ConstString rodata_section_name(".rodata");
  static ConstString rodata1_section_name(".rodata1");
  static ConstString data2_section_name(".data1");
  static ConstString bss_section_name(".bss");
  static ConstString opd_section_name(".opd"); // For ppc64

  // On Android the oatdata and the oatexec symbols in the oat and odex files
  // covers the full
  // .text section what causes issues with displaying unusable symbol name to
  // the user and very
  // slow unwinding speed because the instruction emulation based unwind plans
  // try to emulate all
  // instructions in these symbols. Don't add these symbols to the symbol list
  // as they have no
  // use for the debugger and they are causing a lot of trouble.
  // Filtering can't be restricted to Android because this special object file
  // don't contain the
  // note section specifying the environment to Android but the custom extension
  // and file name
  // makes it highly unlikely that this will collide with anything else.
  ConstString file_extension = m_file.GetFileNameExtension();
  bool skip_oatdata_oatexec = file_extension == ConstString("oat") ||
                              file_extension == ConstString("odex");

  ArchSpec arch;
  GetArchitecture(arch);
  ModuleSP module_sp(GetModule());
  SectionList *module_section_list =
      module_sp ? module_sp->GetSectionList() : nullptr;

  // Local cache to avoid doing a FindSectionByName for each symbol. The "const
  // char*" key must
  // came from a ConstString object so they can be compared by pointer
  std::unordered_map<const char *, lldb::SectionSP> section_name_to_section;

  unsigned i;
  for (i = 0; i < num_symbols; ++i) {
    if (symbol.Parse(symtab_data, &offset) == false)
      break;

    const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
    if (!symbol_name)
      symbol_name = "";

    // No need to add non-section symbols that have no names
    if (symbol.getType() != STT_SECTION &&
        (symbol_name == nullptr || symbol_name[0] == '\0'))
      continue;

    // Skipping oatdata and oatexec sections if it is requested. See details
    // above the
    // definition of skip_oatdata_oatexec for the reasons.
    if (skip_oatdata_oatexec && (::strcmp(symbol_name, "oatdata") == 0 ||
                                 ::strcmp(symbol_name, "oatexec") == 0))
      continue;

    SectionSP symbol_section_sp;
    SymbolType symbol_type = eSymbolTypeInvalid;
    Elf64_Half section_idx = symbol.st_shndx;

    switch (section_idx) {
    case SHN_ABS:
      symbol_type = eSymbolTypeAbsolute;
      break;
    case SHN_UNDEF:
      symbol_type = eSymbolTypeUndefined;
      break;
    default:
      symbol_section_sp = section_list->GetSectionAtIndex(section_idx);
      break;
    }

    // If a symbol is undefined do not process it further even if it has a STT
    // type
    if (symbol_type != eSymbolTypeUndefined) {
      switch (symbol.getType()) {
      default:
      case STT_NOTYPE:
        // The symbol's type is not specified.
        break;

      case STT_OBJECT:
        // The symbol is associated with a data object, such as a variable,
        // an array, etc.
        symbol_type = eSymbolTypeData;
        break;

      case STT_FUNC:
        // The symbol is associated with a function or other executable code.
        symbol_type = eSymbolTypeCode;
        break;

      case STT_SECTION:
        // The symbol is associated with a section. Symbol table entries of
        // this type exist primarily for relocation and normally have
        // STB_LOCAL binding.
        break;

      case STT_FILE:
        // Conventionally, the symbol's name gives the name of the source
        // file associated with the object file. A file symbol has STB_LOCAL
        // binding, its section index is SHN_ABS, and it precedes the other
        // STB_LOCAL symbols for the file, if it is present.
        symbol_type = eSymbolTypeSourceFile;
        break;

      case STT_GNU_IFUNC:
        // The symbol is associated with an indirect function. The actual
        // function will be resolved if it is referenced.
        symbol_type = eSymbolTypeResolver;
        break;
      }
    }

    if (symbol_type == eSymbolTypeInvalid && symbol.getType() != STT_SECTION) {
      if (symbol_section_sp) {
        const ConstString &sect_name = symbol_section_sp->GetName();
        if (sect_name == text_section_name || sect_name == init_section_name ||
            sect_name == fini_section_name || sect_name == ctors_section_name ||
            sect_name == dtors_section_name) {
          symbol_type = eSymbolTypeCode;
        } else if (sect_name == data_section_name ||
                   sect_name == data2_section_name ||
                   sect_name == rodata_section_name ||
                   sect_name == rodata1_section_name ||
                   sect_name == bss_section_name) {
          symbol_type = eSymbolTypeData;
        }
      }
    }

    int64_t symbol_value_offset = 0;
    uint32_t additional_flags = 0;

    if (arch.IsValid()) {
      if (arch.GetMachine() == llvm::Triple::arm) {
        if (symbol.getBinding() == STB_LOCAL) {
          char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name);
          if (symbol_type == eSymbolTypeCode) {
            switch (mapping_symbol) {
            case 'a':
              // $a[.<any>]* - marks an ARM instruction sequence
              m_address_class_map[symbol.st_value] = eAddressClassCode;
              break;
            case 'b':
            case 't':
              // $b[.<any>]* - marks a THUMB BL instruction sequence
              // $t[.<any>]* - marks a THUMB instruction sequence
              m_address_class_map[symbol.st_value] =
                  eAddressClassCodeAlternateISA;
              break;
            case 'd':
              // $d[.<any>]* - marks a data item sequence (e.g. lit pool)
              m_address_class_map[symbol.st_value] = eAddressClassData;
              break;
            }
          }
          if (mapping_symbol)
            continue;
        }
      } else if (arch.GetMachine() == llvm::Triple::aarch64) {
        if (symbol.getBinding() == STB_LOCAL) {
          char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name);
          if (symbol_type == eSymbolTypeCode) {
            switch (mapping_symbol) {
            case 'x':
              // $x[.<any>]* - marks an A64 instruction sequence
              m_address_class_map[symbol.st_value] = eAddressClassCode;
              break;
            case 'd':
              // $d[.<any>]* - marks a data item sequence (e.g. lit pool)
              m_address_class_map[symbol.st_value] = eAddressClassData;
              break;
            }
          }
          if (mapping_symbol)
            continue;
        }
      }

      if (arch.GetMachine() == llvm::Triple::arm) {
        if (symbol_type == eSymbolTypeCode) {
          if (symbol.st_value & 1) {
            // Subtracting 1 from the address effectively unsets
            // the low order bit, which results in the address
            // actually pointing to the beginning of the symbol.
            // This delta will be used below in conjunction with
            // symbol.st_value to produce the final symbol_value
            // that we store in the symtab.
            symbol_value_offset = -1;
            m_address_class_map[symbol.st_value ^ 1] =
                eAddressClassCodeAlternateISA;
          } else {
            // This address is ARM
            m_address_class_map[symbol.st_value] = eAddressClassCode;
          }
        }
      }

      /*
       * MIPS:
       * The bit #0 of an address is used for ISA mode (1 for microMIPS, 0 for
       * MIPS).
       * This allows processor to switch between microMIPS and MIPS without any
       * need
       * for special mode-control register. However, apart from .debug_line,
       * none of
       * the ELF/DWARF sections set the ISA bit (for symbol or section). Use
       * st_other
       * flag to check whether the symbol is microMIPS and then set the address
       * class
       * accordingly.
      */
      const llvm::Triple::ArchType llvm_arch = arch.GetMachine();
      if (llvm_arch == llvm::Triple::mips ||
          llvm_arch == llvm::Triple::mipsel ||
          llvm_arch == llvm::Triple::mips64 ||
          llvm_arch == llvm::Triple::mips64el) {
        if (IS_MICROMIPS(symbol.st_other))
          m_address_class_map[symbol.st_value] = eAddressClassCodeAlternateISA;
        else if ((symbol.st_value & 1) && (symbol_type == eSymbolTypeCode)) {
          symbol.st_value = symbol.st_value & (~1ull);
          m_address_class_map[symbol.st_value] = eAddressClassCodeAlternateISA;
        } else {
          if (symbol_type == eSymbolTypeCode)
            m_address_class_map[symbol.st_value] = eAddressClassCode;
          else if (symbol_type == eSymbolTypeData)
            m_address_class_map[symbol.st_value] = eAddressClassData;
          else
            m_address_class_map[symbol.st_value] = eAddressClassUnknown;
        }
      }
    }

    // symbol_value_offset may contain 0 for ARM symbols or -1 for THUMB
    // symbols. See above for
    // more details.
    uint64_t symbol_value = symbol.st_value + symbol_value_offset;

    if (symbol_section_sp == nullptr && section_idx == SHN_ABS &&
        symbol.st_size != 0) {
      // We don't have a section for a symbol with non-zero size. Create a new
      // section for it
      // so the address range covered by the symbol is also covered by the
      // module (represented
      // through the section list). It is needed so module lookup for the
      // addresses covered
      // by this symbol will be successfull. This case happens for absolute
      // symbols.
      ConstString fake_section_name(std::string(".absolute.") + symbol_name);
      symbol_section_sp =
          std::make_shared<Section>(module_sp, this, SHN_ABS, fake_section_name,
                                    eSectionTypeAbsoluteAddress, symbol_value,
                                    symbol.st_size, 0, 0, 0, SHF_ALLOC);

      module_section_list->AddSection(symbol_section_sp);
      section_list->AddSection(symbol_section_sp);
    }

    if (symbol_section_sp &&
        CalculateType() != ObjectFile::Type::eTypeObjectFile)
      symbol_value -= symbol_section_sp->GetFileAddress();

    if (symbol_section_sp && module_section_list &&
        module_section_list != section_list) {
      const ConstString &sect_name = symbol_section_sp->GetName();
      auto section_it = section_name_to_section.find(sect_name.GetCString());
      if (section_it == section_name_to_section.end())
        section_it =
            section_name_to_section
                .emplace(sect_name.GetCString(),
                         module_section_list->FindSectionByName(sect_name))
                .first;
      if (section_it->second)
        symbol_section_sp = section_it->second;
    }

    bool is_global = symbol.getBinding() == STB_GLOBAL;
    uint32_t flags = symbol.st_other << 8 | symbol.st_info | additional_flags;
    bool is_mangled =
        (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'Z');

    llvm::StringRef symbol_ref(symbol_name);

    // Symbol names may contain @VERSION suffixes. Find those and strip them
    // temporarily.
    size_t version_pos = symbol_ref.find('@');
    bool has_suffix = version_pos != llvm::StringRef::npos;
    llvm::StringRef symbol_bare = symbol_ref.substr(0, version_pos);

    Mangled guess_the_language(ConstString(symbol_bare), true);
    if (guess_the_language.GuessLanguage() != lldb::eLanguageTypeUnknown) {
      is_mangled = true;
    }

    Mangled mangled(ConstString(symbol_bare), is_mangled);

    // Now append the suffix back to mangled and unmangled names. Only do it if
    // the
    // demangling was successful (string is not empty).
    if (has_suffix) {
      llvm::StringRef suffix = symbol_ref.substr(version_pos);

      llvm::StringRef mangled_name = mangled.GetMangledName().GetStringRef();
      if (!mangled_name.empty())
        mangled.SetMangledName(ConstString((mangled_name + suffix).str()));

      ConstString demangled =
          mangled.GetDemangledName(lldb::eLanguageTypeUnknown);
      llvm::StringRef demangled_name = demangled.GetStringRef();
      if (!demangled_name.empty())
        mangled.SetDemangledName(ConstString((demangled_name + suffix).str()));
    }

    // In ELF all symbol should have a valid size but it is not true for some
    // function symbols
    // coming from hand written assembly. As none of the function symbol should
    // have 0 size we
    // try to calculate the size for these symbols in the symtab with saying
    // that their original
    // size is not valid.
    bool symbol_size_valid =
        symbol.st_size != 0 || symbol.getType() != STT_FUNC;

    Symbol dc_symbol(
        i + start_id, // ID is the original symbol table index.
        mangled,
        symbol_type,                    // Type of this symbol
        is_global,                      // Is this globally visible?
        false,                          // Is this symbol debug info?
        false,                          // Is this symbol a trampoline?
        false,                          // Is this symbol artificial?
        AddressRange(symbol_section_sp, // Section in which this symbol is
                                        // defined or null.
                     symbol_value,      // Offset in section or symbol value.
                     symbol.st_size),   // Size in bytes of this symbol.
        symbol_size_valid,              // Symbol size is valid
        has_suffix,                     // Contains linker annotations?
        flags);                         // Symbol flags.
    symtab->AddSymbol(dc_symbol);
  }
  return i;
}

unsigned ObjectFileELF::ParseSymbolTable(Symtab *symbol_table,
                                         user_id_t start_id,
                                         lldb_private::Section *symtab) {
  if (symtab->GetObjectFile() != this) {
    // If the symbol table section is owned by a different object file, have it
    // do the
    // parsing.
    ObjectFileELF *obj_file_elf =
        static_cast<ObjectFileELF *>(symtab->GetObjectFile());
    return obj_file_elf->ParseSymbolTable(symbol_table, start_id, symtab);
  }

  // Get section list for this object file.
  SectionList *section_list = m_sections_ap.get();
  if (!section_list)
    return 0;

  user_id_t symtab_id = symtab->GetID();
  const ELFSectionHeaderInfo *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
  assert(symtab_hdr->sh_type == SHT_SYMTAB ||
         symtab_hdr->sh_type == SHT_DYNSYM);

  // sh_link: section header index of associated string table.
  // Section ID's are ones based.
  user_id_t strtab_id = symtab_hdr->sh_link + 1;
  Section *strtab = section_list->FindSectionByID(strtab_id).get();

  if (symtab && strtab) {
    assert(symtab->GetObjectFile() == this);
    assert(strtab->GetObjectFile() == this);

    DataExtractor symtab_data;
    DataExtractor strtab_data;
    if (ReadSectionData(symtab, symtab_data) &&
        ReadSectionData(strtab, strtab_data)) {
      size_t num_symbols = symtab_data.GetByteSize() / symtab_hdr->sh_entsize;

      return ParseSymbols(symbol_table, start_id, section_list, num_symbols,
                          symtab_data, strtab_data);
    }
  }

  return 0;
}

size_t ObjectFileELF::ParseDynamicSymbols() {
  if (m_dynamic_symbols.size())
    return m_dynamic_symbols.size();

  SectionList *section_list = GetSectionList();
  if (!section_list)
    return 0;

  // Find the SHT_DYNAMIC section.
  Section *dynsym =
      section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true)
          .get();
  if (!dynsym)
    return 0;
  assert(dynsym->GetObjectFile() == this);

  ELFDynamic symbol;
  DataExtractor dynsym_data;
  if (ReadSectionData(dynsym, dynsym_data)) {
    const lldb::offset_t section_size = dynsym_data.GetByteSize();
    lldb::offset_t cursor = 0;

    while (cursor < section_size) {
      if (!symbol.Parse(dynsym_data, &cursor))
        break;

      m_dynamic_symbols.push_back(symbol);
    }
  }

  return m_dynamic_symbols.size();
}

const ELFDynamic *ObjectFileELF::FindDynamicSymbol(unsigned tag) {
  if (!ParseDynamicSymbols())
    return NULL;

  DynamicSymbolCollIter I = m_dynamic_symbols.begin();
  DynamicSymbolCollIter E = m_dynamic_symbols.end();
  for (; I != E; ++I) {
    ELFDynamic *symbol = &*I;

    if (symbol->d_tag == tag)
      return symbol;
  }

  return NULL;
}

unsigned ObjectFileELF::PLTRelocationType() {
  // DT_PLTREL
  //  This member specifies the type of relocation entry to which the
  //  procedure linkage table refers. The d_val member holds DT_REL or
  //  DT_RELA, as appropriate. All relocations in a procedure linkage table
  //  must use the same relocation.
  const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL);

  if (symbol)
    return symbol->d_val;

  return 0;
}

// Returns the size of the normal plt entries and the offset of the first normal
// plt entry. The
// 0th entry in the plt table is usually a resolution entry which have different
// size in some
// architectures then the rest of the plt entries.
static std::pair<uint64_t, uint64_t>
GetPltEntrySizeAndOffset(const ELFSectionHeader *rel_hdr,
                         const ELFSectionHeader *plt_hdr) {
  const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;

  // Clang 3.3 sets entsize to 4 for 32-bit binaries, but the plt entries are 16
  // bytes.
  // So round the entsize up by the alignment if addralign is set.
  elf_xword plt_entsize =
      plt_hdr->sh_addralign
          ? llvm::alignTo(plt_hdr->sh_entsize, plt_hdr->sh_addralign)
          : plt_hdr->sh_entsize;

  // Some linkers e.g ld for arm, fill plt_hdr->sh_entsize field incorrectly.
  // PLT entries relocation code in general requires multiple instruction and
  // should be greater than 4 bytes in most cases. Try to guess correct size
  // just in case.
  if (plt_entsize <= 4) {
    // The linker haven't set the plt_hdr->sh_entsize field. Try to guess the
    // size of the plt
    // entries based on the number of entries and the size of the plt section
    // with the
    // assumption that the size of the 0th entry is at least as big as the size
    // of the normal
    // entries and it isn't much bigger then that.
    if (plt_hdr->sh_addralign)
      plt_entsize = plt_hdr->sh_size / plt_hdr->sh_addralign /
                    (num_relocations + 1) * plt_hdr->sh_addralign;
    else
      plt_entsize = plt_hdr->sh_size / (num_relocations + 1);
  }

  elf_xword plt_offset = plt_hdr->sh_size - num_relocations * plt_entsize;

  return std::make_pair(plt_entsize, plt_offset);
}

static unsigned ParsePLTRelocations(
    Symtab *symbol_table, user_id_t start_id, unsigned rel_type,
    const ELFHeader *hdr, const ELFSectionHeader *rel_hdr,
    const ELFSectionHeader *plt_hdr, const ELFSectionHeader *sym_hdr,
    const lldb::SectionSP &plt_section_sp, DataExtractor &rel_data,
    DataExtractor &symtab_data, DataExtractor &strtab_data) {
  ELFRelocation rel(rel_type);
  ELFSymbol symbol;
  lldb::offset_t offset = 0;

  uint64_t plt_offset, plt_entsize;
  std::tie(plt_entsize, plt_offset) =
      GetPltEntrySizeAndOffset(rel_hdr, plt_hdr);
  const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;

  typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
  reloc_info_fn reloc_type;
  reloc_info_fn reloc_symbol;

  if (hdr->Is32Bit()) {
    reloc_type = ELFRelocation::RelocType32;
    reloc_symbol = ELFRelocation::RelocSymbol32;
  } else {
    reloc_type = ELFRelocation::RelocType64;
    reloc_symbol = ELFRelocation::RelocSymbol64;
  }

  unsigned slot_type = hdr->GetRelocationJumpSlotType();
  unsigned i;
  for (i = 0; i < num_relocations; ++i) {
    if (rel.Parse(rel_data, &offset) == false)
      break;

    if (reloc_type(rel) != slot_type)
      continue;

    lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
    if (!symbol.Parse(symtab_data, &symbol_offset))
      break;

    const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
    bool is_mangled =
        symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
    uint64_t plt_index = plt_offset + i * plt_entsize;

    Symbol jump_symbol(
        i + start_id,          // Symbol table index
        symbol_name,           // symbol name.
        is_mangled,            // is the symbol name mangled?
        eSymbolTypeTrampoline, // Type of this symbol
        false,                 // Is this globally visible?
        false,                 // Is this symbol debug info?
        true,                  // Is this symbol a trampoline?
        true,                  // Is this symbol artificial?
        plt_section_sp, // Section in which this symbol is defined or null.
        plt_index,      // Offset in section or symbol value.
        plt_entsize,    // Size in bytes of this symbol.
        true,           // Size is valid
        false,          // Contains linker annotations?
        0);             // Symbol flags.

    symbol_table->AddSymbol(jump_symbol);
  }

  return i;
}

unsigned
ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, user_id_t start_id,
                                      const ELFSectionHeaderInfo *rel_hdr,
                                      user_id_t rel_id) {
  assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);

  // The link field points to the associated symbol table.
  user_id_t symtab_id = rel_hdr->sh_link;

  // If the link field doesn't point to the appropriate symbol name table then
  // try to find it by name as some compiler don't fill in the link fields.
  if (!symtab_id)
    symtab_id = GetSectionIndexByName(".dynsym");

  // Get PLT section.  We cannot use rel_hdr->sh_info, since current linkers
  // point that to the .got.plt or .got section instead of .plt.
  user_id_t plt_id = GetSectionIndexByName(".plt");

  if (!symtab_id || !plt_id)
    return 0;

  // Section ID's are ones based;
  symtab_id++;
  plt_id++;

  const ELFSectionHeaderInfo *plt_hdr = GetSectionHeaderByIndex(plt_id);
  if (!plt_hdr)
    return 0;

  const ELFSectionHeaderInfo *sym_hdr = GetSectionHeaderByIndex(symtab_id);
  if (!sym_hdr)
    return 0;

  SectionList *section_list = m_sections_ap.get();
  if (!section_list)
    return 0;

  Section *rel_section = section_list->FindSectionByID(rel_id).get();
  if (!rel_section)
    return 0;

  SectionSP plt_section_sp(section_list->FindSectionByID(plt_id));
  if (!plt_section_sp)
    return 0;

  Section *symtab = section_list->FindSectionByID(symtab_id).get();
  if (!symtab)
    return 0;

  // sh_link points to associated string table.
  Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get();
  if (!strtab)
    return 0;

  DataExtractor rel_data;
  if (!ReadSectionData(rel_section, rel_data))
    return 0;

  DataExtractor symtab_data;
  if (!ReadSectionData(symtab, symtab_data))
    return 0;

  DataExtractor strtab_data;
  if (!ReadSectionData(strtab, strtab_data))
    return 0;

  unsigned rel_type = PLTRelocationType();
  if (!rel_type)
    return 0;

  return ParsePLTRelocations(symbol_table, start_id, rel_type, &m_header,
                             rel_hdr, plt_hdr, sym_hdr, plt_section_sp,
                             rel_data, symtab_data, strtab_data);
}

unsigned ObjectFileELF::ApplyRelocations(
    Symtab *symtab, const ELFHeader *hdr, const ELFSectionHeader *rel_hdr,
    const ELFSectionHeader *symtab_hdr, const ELFSectionHeader *debug_hdr,
    DataExtractor &rel_data, DataExtractor &symtab_data,
    DataExtractor &debug_data, Section *rel_section) {
  ELFRelocation rel(rel_hdr->sh_type);
  lldb::addr_t offset = 0;
  const unsigned num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
  typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
  reloc_info_fn reloc_type;
  reloc_info_fn reloc_symbol;

  if (hdr->Is32Bit()) {
    reloc_type = ELFRelocation::RelocType32;
    reloc_symbol = ELFRelocation::RelocSymbol32;
  } else {
    reloc_type = ELFRelocation::RelocType64;
    reloc_symbol = ELFRelocation::RelocSymbol64;
  }

  for (unsigned i = 0; i < num_relocations; ++i) {
    if (rel.Parse(rel_data, &offset) == false)
      break;

    Symbol *symbol = NULL;

    if (hdr->Is32Bit()) {
      switch (reloc_type(rel)) {
      case R_386_32:
      case R_386_PC32:
      default:
        // FIXME: This asserts with this input:
        //
        // foo.cpp
        // int main(int argc, char **argv) { return 0; }
        //
        // clang++.exe --target=i686-unknown-linux-gnu -g -c foo.cpp -o foo.o
        //
        // and running this on the foo.o module.
        assert(false && "unexpected relocation type");
      }
    } else {
      switch (reloc_type(rel)) {
      case R_X86_64_64: {
        symbol = symtab->FindSymbolByID(reloc_symbol(rel));
        if (symbol) {
          addr_t value = symbol->GetAddressRef().GetFileAddress();
          DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
          uint64_t *dst = reinterpret_cast<uint64_t *>(
              data_buffer_sp->GetBytes() + rel_section->GetFileOffset() +
              ELFRelocation::RelocOffset64(rel));
          *dst = value + ELFRelocation::RelocAddend64(rel);
        }
        break;
      }
      case R_X86_64_32:
      case R_X86_64_32S: {
        symbol = symtab->FindSymbolByID(reloc_symbol(rel));
        if (symbol) {
          addr_t value = symbol->GetAddressRef().GetFileAddress();
          value += ELFRelocation::RelocAddend32(rel);
          assert(
              (reloc_type(rel) == R_X86_64_32 && (value <= UINT32_MAX)) ||
              (reloc_type(rel) == R_X86_64_32S &&
               ((int64_t)value <= INT32_MAX && (int64_t)value >= INT32_MIN)));
          uint32_t truncated_addr = (value & 0xFFFFFFFF);
          DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
          uint32_t *dst = reinterpret_cast<uint32_t *>(
              data_buffer_sp->GetBytes() + rel_section->GetFileOffset() +
              ELFRelocation::RelocOffset32(rel));
          *dst = truncated_addr;
        }
        break;
      }
      case R_X86_64_PC32:
      default:
        assert(false && "unexpected relocation type");
      }
    }
  }

  return 0;
}

unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr,
                                              user_id_t rel_id,
                                              lldb_private::Symtab *thetab) {
  assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);

  // Parse in the section list if needed.
  SectionList *section_list = GetSectionList();
  if (!section_list)
    return 0;

  // Section ID's are ones based.
  user_id_t symtab_id = rel_hdr->sh_link + 1;
  user_id_t debug_id = rel_hdr->sh_info + 1;

  const ELFSectionHeader *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
  if (!symtab_hdr)
    return 0;

  const ELFSectionHeader *debug_hdr = GetSectionHeaderByIndex(debug_id);
  if (!debug_hdr)
    return 0;

  Section *rel = section_list->FindSectionByID(rel_id).get();
  if (!rel)
    return 0;

  Section *symtab = section_list->FindSectionByID(symtab_id).get();
  if (!symtab)
    return 0;

  Section *debug = section_list->FindSectionByID(debug_id).get();
  if (!debug)
    return 0;

  DataExtractor rel_data;
  DataExtractor symtab_data;
  DataExtractor debug_data;

  if (GetData(rel->GetFileOffset(), rel->GetFileSize(), rel_data) &&
      GetData(symtab->GetFileOffset(), symtab->GetFileSize(), symtab_data) &&
      GetData(debug->GetFileOffset(), debug->GetFileSize(), debug_data)) {
    ApplyRelocations(thetab, &m_header, rel_hdr, symtab_hdr, debug_hdr,
                     rel_data, symtab_data, debug_data, debug);
  }

  return 0;
}

Symtab *ObjectFileELF::GetSymtab() {
  ModuleSP module_sp(GetModule());
  if (!module_sp)
    return NULL;

  // We always want to use the main object file so we (hopefully) only have one
  // cached copy
  // of our symtab, dynamic sections, etc.
  ObjectFile *module_obj_file = module_sp->GetObjectFile();
  if (module_obj_file && module_obj_file != this)
    return module_obj_file->GetSymtab();

  if (m_symtab_ap.get() == NULL) {
    SectionList *section_list = module_sp->GetSectionList();
    if (!section_list)
      return NULL;

    uint64_t symbol_id = 0;
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());

    // Sharable objects and dynamic executables usually have 2 distinct symbol
    // tables, one named ".symtab", and the other ".dynsym". The dynsym is a
    // smaller
    // version of the symtab that only contains global symbols. The information
    // found
    // in the dynsym is therefore also found in the symtab, while the reverse is
    // not
    // necessarily true.
    Section *symtab =
        section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
    if (!symtab) {
      // The symtab section is non-allocable and can be stripped, so if it
      // doesn't exist
      // then use the dynsym section which should always be there.
      symtab =
          section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
              .get();
    }
    if (symtab) {
      m_symtab_ap.reset(new Symtab(symtab->GetObjectFile()));
      symbol_id += ParseSymbolTable(m_symtab_ap.get(), symbol_id, symtab);
    }

    // DT_JMPREL
    //      If present, this entry's d_ptr member holds the address of
    //      relocation
    //      entries associated solely with the procedure linkage table.
    //      Separating
    //      these relocation entries lets the dynamic linker ignore them during
    //      process initialization, if lazy binding is enabled. If this entry is
    //      present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
    //      also be present.
    const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
    if (symbol) {
      // Synthesize trampoline symbols to help navigate the PLT.
      addr_t addr = symbol->d_ptr;
      Section *reloc_section =
          section_list->FindSectionContainingFileAddress(addr).get();
      if (reloc_section) {
        user_id_t reloc_id = reloc_section->GetID();
        const ELFSectionHeaderInfo *reloc_header =
            GetSectionHeaderByIndex(reloc_id);
        assert(reloc_header);

        if (m_symtab_ap == nullptr)
          m_symtab_ap.reset(new Symtab(reloc_section->GetObjectFile()));

        ParseTrampolineSymbols(m_symtab_ap.get(), symbol_id, reloc_header,
                               reloc_id);
      }
    }

    DWARFCallFrameInfo *eh_frame = GetUnwindTable().GetEHFrameInfo();
    if (eh_frame) {
      if (m_symtab_ap == nullptr)
        m_symtab_ap.reset(new Symtab(this));
      ParseUnwindSymbols(m_symtab_ap.get(), eh_frame);
    }

    // If we still don't have any symtab then create an empty instance to avoid
    // do the section
    // lookup next time.
    if (m_symtab_ap == nullptr)
      m_symtab_ap.reset(new Symtab(this));

    m_symtab_ap->CalculateSymbolSizes();
  }

  return m_symtab_ap.get();
}

void ObjectFileELF::RelocateSection(lldb_private::Section *section)
{
  static const char *debug_prefix = ".debug";

  // Set relocated bit so we stop getting called, regardless of
  // whether we actually relocate.
  section->SetIsRelocated(true);

  // We only relocate in ELF relocatable files
  if (CalculateType() != eTypeObjectFile)
    return;

  const char *section_name = section->GetName().GetCString();
  // Can't relocate that which can't be named
  if (section_name == nullptr)
    return;

  // We don't relocate non-debug sections at the moment
  if (strncmp(section_name, debug_prefix, strlen(debug_prefix)))
    return;

  // Relocation section names to look for
  std::string needle = std::string(".rel") + section_name;
  std::string needlea = std::string(".rela") + section_name;

  for (SectionHeaderCollIter I = m_section_headers.begin();
       I != m_section_headers.end(); ++I) {
    if (I->sh_type == SHT_RELA || I->sh_type == SHT_REL) {
      const char *hay_name = I->section_name.GetCString();
      if (hay_name == nullptr)
        continue;
      if (needle == hay_name || needlea == hay_name) {
        const ELFSectionHeader &reloc_header = *I;
        user_id_t reloc_id = SectionIndex(I);
        RelocateDebugSections(&reloc_header, reloc_id, GetSymtab());
        break;
      }
    }
  }
}

void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table,
                                       DWARFCallFrameInfo *eh_frame) {
  SectionList *section_list = GetSectionList();
  if (!section_list)
    return;

  // First we save the new symbols into a separate list and add them to the
  // symbol table after
  // we colleced all symbols we want to add. This is neccessary because adding a
  // new symbol
  // invalidates the internal index of the symtab what causing the next lookup
  // to be slow because
  // it have to recalculate the index first.
  std::vector<Symbol> new_symbols;

  eh_frame->ForEachFDEEntries([this, symbol_table, section_list, &new_symbols](
      lldb::addr_t file_addr, uint32_t size, dw_offset_t) {
    Symbol *symbol = symbol_table->FindSymbolAtFileAddress(file_addr);
    if (symbol) {
      if (!symbol->GetByteSizeIsValid()) {
        symbol->SetByteSize(size);
        symbol->SetSizeIsSynthesized(true);
      }
    } else {
      SectionSP section_sp =
          section_list->FindSectionContainingFileAddress(file_addr);
      if (section_sp) {
        addr_t offset = file_addr - section_sp->GetFileAddress();
        const char *symbol_name = GetNextSyntheticSymbolName().GetCString();
        uint64_t symbol_id = symbol_table->GetNumSymbols();
        Symbol eh_symbol(
            symbol_id,       // Symbol table index.
            symbol_name,     // Symbol name.
            false,           // Is the symbol name mangled?
            eSymbolTypeCode, // Type of this symbol.
            true,            // Is this globally visible?
            false,           // Is this symbol debug info?
            false,           // Is this symbol a trampoline?
            true,            // Is this symbol artificial?
            section_sp,      // Section in which this symbol is defined or null.
            offset,          // Offset in section or symbol value.
            0,     // Size:          Don't specify the size as an FDE can
            false, // Size is valid: cover multiple symbols.
            false, // Contains linker annotations?
            0);    // Symbol flags.
        new_symbols.push_back(eh_symbol);
      }
    }
    return true;
  });

  for (const Symbol &s : new_symbols)
    symbol_table->AddSymbol(s);
}

bool ObjectFileELF::IsStripped() {
  // TODO: determine this for ELF
  return false;
}

//===----------------------------------------------------------------------===//
// Dump
//
// Dump the specifics of the runtime file container (such as any headers
// segments, sections, etc).
//----------------------------------------------------------------------
void ObjectFileELF::Dump(Stream *s) {
  ModuleSP module_sp(GetModule());
  if (!module_sp) {
    return;
  }

  std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
  s->Printf("%p: ", static_cast<void *>(this));
  s->Indent();
  s->PutCString("ObjectFileELF");

  ArchSpec header_arch;
  GetArchitecture(header_arch);

  *s << ", file = '" << m_file
     << "', arch = " << header_arch.GetArchitectureName() << "\n";

  DumpELFHeader(s, m_header);
  s->EOL();
  DumpELFProgramHeaders(s);
  s->EOL();
  DumpELFSectionHeaders(s);
  s->EOL();
  SectionList *section_list = GetSectionList();
  if (section_list)
    section_list->Dump(s, NULL, true, UINT32_MAX);
  Symtab *symtab = GetSymtab();
  if (symtab)
    symtab->Dump(s, NULL, eSortOrderNone);
  s->EOL();
  DumpDependentModules(s);
  s->EOL();
}

//----------------------------------------------------------------------
// DumpELFHeader
//
// Dump the ELF header to the specified output stream
//----------------------------------------------------------------------
void ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header) {
  s->PutCString("ELF Header\n");
  s->Printf("e_ident[EI_MAG0   ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
  s->Printf("e_ident[EI_MAG1   ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG1],
            header.e_ident[EI_MAG1]);
  s->Printf("e_ident[EI_MAG2   ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG2],
            header.e_ident[EI_MAG2]);
  s->Printf("e_ident[EI_MAG3   ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG3],
            header.e_ident[EI_MAG3]);

  s->Printf("e_ident[EI_CLASS  ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
  s->Printf("e_ident[EI_DATA   ] = 0x%2.2x ", header.e_ident[EI_DATA]);
  DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
  s->Printf("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
  s->Printf("e_ident[EI_PAD    ] = 0x%2.2x\n", header.e_ident[EI_PAD]);

  s->Printf("e_type      = 0x%4.4x ", header.e_type);
  DumpELFHeader_e_type(s, header.e_type);
  s->Printf("\ne_machine   = 0x%4.4x\n", header.e_machine);
  s->Printf("e_version   = 0x%8.8x\n", header.e_version);
  s->Printf("e_entry     = 0x%8.8" PRIx64 "\n", header.e_entry);
  s->Printf("e_phoff     = 0x%8.8" PRIx64 "\n", header.e_phoff);
  s->Printf("e_shoff     = 0x%8.8" PRIx64 "\n", header.e_shoff);
  s->Printf("e_flags     = 0x%8.8x\n", header.e_flags);
  s->Printf("e_ehsize    = 0x%4.4x\n", header.e_ehsize);
  s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
  s->Printf("e_phnum     = 0x%8.8x\n", header.e_phnum);
  s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
  s->Printf("e_shnum     = 0x%8.8x\n", header.e_shnum);
  s->Printf("e_shstrndx  = 0x%8.8x\n", header.e_shstrndx);
}

//----------------------------------------------------------------------
// DumpELFHeader_e_type
//
// Dump an token value for the ELF header member e_type
//----------------------------------------------------------------------
void ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type) {
  switch (e_type) {
  case ET_NONE:
    *s << "ET_NONE";
    break;
  case ET_REL:
    *s << "ET_REL";
    break;
  case ET_EXEC:
    *s << "ET_EXEC";
    break;
  case ET_DYN:
    *s << "ET_DYN";
    break;
  case ET_CORE:
    *s << "ET_CORE";
    break;
  default:
    break;
  }
}

//----------------------------------------------------------------------
// DumpELFHeader_e_ident_EI_DATA
//
// Dump an token value for the ELF header member e_ident[EI_DATA]
//----------------------------------------------------------------------
void ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s,
                                                  unsigned char ei_data) {
  switch (ei_data) {
  case ELFDATANONE:
    *s << "ELFDATANONE";
    break;
  case ELFDATA2LSB:
    *s << "ELFDATA2LSB - Little Endian";
    break;
  case ELFDATA2MSB:
    *s << "ELFDATA2MSB - Big Endian";
    break;
  default:
    break;
  }
}

//----------------------------------------------------------------------
// DumpELFProgramHeader
//
// Dump a single ELF program header to the specified output stream
//----------------------------------------------------------------------
void ObjectFileELF::DumpELFProgramHeader(Stream *s,
                                         const ELFProgramHeader &ph) {
  DumpELFProgramHeader_p_type(s, ph.p_type);
  s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset,
            ph.p_vaddr, ph.p_paddr);
  s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8x (", ph.p_filesz, ph.p_memsz,
            ph.p_flags);

  DumpELFProgramHeader_p_flags(s, ph.p_flags);
  s->Printf(") %8.8" PRIx64, ph.p_align);
}

//----------------------------------------------------------------------
// DumpELFProgramHeader_p_type
//
// Dump an token value for the ELF program header member p_type which
// describes the type of the program header
// ----------------------------------------------------------------------
void ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type) {
  const int kStrWidth = 15;
  switch (p_type) {
    CASE_AND_STREAM(s, PT_NULL, kStrWidth);
    CASE_AND_STREAM(s, PT_LOAD, kStrWidth);
    CASE_AND_STREAM(s, PT_DYNAMIC, kStrWidth);
    CASE_AND_STREAM(s, PT_INTERP, kStrWidth);
    CASE_AND_STREAM(s, PT_NOTE, kStrWidth);
    CASE_AND_STREAM(s, PT_SHLIB, kStrWidth);
    CASE_AND_STREAM(s, PT_PHDR, kStrWidth);
    CASE_AND_STREAM(s, PT_TLS, kStrWidth);
    CASE_AND_STREAM(s, PT_GNU_EH_FRAME, kStrWidth);
  default:
    s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
    break;
  }
}

//----------------------------------------------------------------------
// DumpELFProgramHeader_p_flags
//
// Dump an token value for the ELF program header member p_flags
//----------------------------------------------------------------------
void ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags) {
  *s << ((p_flags & PF_X) ? "PF_X" : "    ")
     << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
     << ((p_flags & PF_W) ? "PF_W" : "    ")
     << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
     << ((p_flags & PF_R) ? "PF_R" : "    ");
}

//----------------------------------------------------------------------
// DumpELFProgramHeaders
//
// Dump all of the ELF program header to the specified output stream
//----------------------------------------------------------------------
void ObjectFileELF::DumpELFProgramHeaders(Stream *s) {
  if (!ParseProgramHeaders())
    return;

  s->PutCString("Program Headers\n");
  s->PutCString("IDX  p_type          p_offset p_vaddr  p_paddr  "
                "p_filesz p_memsz  p_flags                   p_align\n");
  s->PutCString("==== --------------- -------- -------- -------- "
                "-------- -------- ------------------------- --------\n");

  uint32_t idx = 0;
  for (ProgramHeaderCollConstIter I = m_program_headers.begin();
       I != m_program_headers.end(); ++I, ++idx) {
    s->Printf("[%2u] ", idx);
    ObjectFileELF::DumpELFProgramHeader(s, *I);
    s->EOL();
  }
}

//----------------------------------------------------------------------
// DumpELFSectionHeader
//
// Dump a single ELF section header to the specified output stream
//----------------------------------------------------------------------
void ObjectFileELF::DumpELFSectionHeader(Stream *s,
                                         const ELFSectionHeaderInfo &sh) {
  s->Printf("%8.8x ", sh.sh_name);
  DumpELFSectionHeader_sh_type(s, sh.sh_type);
  s->Printf(" %8.8" PRIx64 " (", sh.sh_flags);
  DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
  s->Printf(") %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addr,
            sh.sh_offset, sh.sh_size);
  s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
  s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize);
}

//----------------------------------------------------------------------
// DumpELFSectionHeader_sh_type
//
// Dump an token value for the ELF section header member sh_type which
// describes the type of the section
//----------------------------------------------------------------------
void ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type) {
  const int kStrWidth = 12;
  switch (sh_type) {
    CASE_AND_STREAM(s, SHT_NULL, kStrWidth);
    CASE_AND_STREAM(s, SHT_PROGBITS, kStrWidth);
    CASE_AND_STREAM(s, SHT_SYMTAB, kStrWidth);
    CASE_AND_STREAM(s, SHT_STRTAB, kStrWidth);
    CASE_AND_STREAM(s, SHT_RELA, kStrWidth);
    CASE_AND_STREAM(s, SHT_HASH, kStrWidth);
    CASE_AND_STREAM(s, SHT_DYNAMIC, kStrWidth);
    CASE_AND_STREAM(s, SHT_NOTE, kStrWidth);
    CASE_AND_STREAM(s, SHT_NOBITS, kStrWidth);
    CASE_AND_STREAM(s, SHT_REL, kStrWidth);
    CASE_AND_STREAM(s, SHT_SHLIB, kStrWidth);
    CASE_AND_STREAM(s, SHT_DYNSYM, kStrWidth);
    CASE_AND_STREAM(s, SHT_LOPROC, kStrWidth);
    CASE_AND_STREAM(s, SHT_HIPROC, kStrWidth);
    CASE_AND_STREAM(s, SHT_LOUSER, kStrWidth);
    CASE_AND_STREAM(s, SHT_HIUSER, kStrWidth);
  default:
    s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
    break;
  }
}

//----------------------------------------------------------------------
// DumpELFSectionHeader_sh_flags
//
// Dump an token value for the ELF section header member sh_flags
//----------------------------------------------------------------------
void ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s,
                                                  elf_xword sh_flags) {
  *s << ((sh_flags & SHF_WRITE) ? "WRITE" : "     ")
     << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
     << ((sh_flags & SHF_ALLOC) ? "ALLOC" : "     ")
     << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
     << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : "         ");
}

//----------------------------------------------------------------------
// DumpELFSectionHeaders
//
// Dump all of the ELF section header to the specified output stream
//----------------------------------------------------------------------
void ObjectFileELF::DumpELFSectionHeaders(Stream *s) {
  if (!ParseSectionHeaders())
    return;

  s->PutCString("Section Headers\n");
  s->PutCString("IDX  name     type         flags                            "
                "addr     offset   size     link     info     addralgn "
                "entsize  Name\n");
  s->PutCString("==== -------- ------------ -------------------------------- "
                "-------- -------- -------- -------- -------- -------- "
                "-------- ====================\n");

  uint32_t idx = 0;
  for (SectionHeaderCollConstIter I = m_section_headers.begin();
       I != m_section_headers.end(); ++I, ++idx) {
    s->Printf("[%2u] ", idx);
    ObjectFileELF::DumpELFSectionHeader(s, *I);
    const char *section_name = I->section_name.AsCString("");
    if (section_name)
      *s << ' ' << section_name << "\n";
  }
}

void ObjectFileELF::DumpDependentModules(lldb_private::Stream *s) {
  size_t num_modules = ParseDependentModules();

  if (num_modules > 0) {
    s->PutCString("Dependent Modules:\n");
    for (unsigned i = 0; i < num_modules; ++i) {
      const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i);
      s->Printf("   %s\n", spec.GetFilename().GetCString());
    }
  }
}

bool ObjectFileELF::GetArchitecture(ArchSpec &arch) {
  if (!ParseHeader())
    return false;

  if (m_section_headers.empty()) {
    // Allow elf notes to be parsed which may affect the detected architecture.
    ParseSectionHeaders();
  }

  if (CalculateType() == eTypeCoreFile &&
      m_arch_spec.TripleOSIsUnspecifiedUnknown()) {
    // Core files don't have section headers yet they have PT_NOTE program
    // headers
    // that might shed more light on the architecture
    if (ParseProgramHeaders()) {
      for (size_t i = 1, count = GetProgramHeaderCount(); i <= count; ++i) {
        const elf::ELFProgramHeader *header = GetProgramHeaderByIndex(i);
        if (header && header->p_type == PT_NOTE && header->p_offset != 0 &&
            header->p_filesz > 0) {
          DataExtractor data;
          if (data.SetData(m_data, header->p_offset, header->p_filesz) ==
              header->p_filesz) {
            lldb_private::UUID uuid;
            RefineModuleDetailsFromNote(data, m_arch_spec, uuid);
          }
        }
      }
    }
  }
  arch = m_arch_spec;
  return true;
}

ObjectFile::Type ObjectFileELF::CalculateType() {
  switch (m_header.e_type) {
  case llvm::ELF::ET_NONE:
    // 0 - No file type
    return eTypeUnknown;

  case llvm::ELF::ET_REL:
    // 1 - Relocatable file
    return eTypeObjectFile;

  case llvm::ELF::ET_EXEC:
    // 2 - Executable file
    return eTypeExecutable;

  case llvm::ELF::ET_DYN:
    // 3 - Shared object file
    return eTypeSharedLibrary;

  case ET_CORE:
    // 4 - Core file
    return eTypeCoreFile;

  default:
    break;
  }
  return eTypeUnknown;
}

ObjectFile::Strata ObjectFileELF::CalculateStrata() {
  switch (m_header.e_type) {
  case llvm::ELF::ET_NONE:
    // 0 - No file type
    return eStrataUnknown;

  case llvm::ELF::ET_REL:
    // 1 - Relocatable file
    return eStrataUnknown;

  case llvm::ELF::ET_EXEC:
    // 2 - Executable file
    // TODO: is there any way to detect that an executable is a kernel
    // related executable by inspecting the program headers, section
    // headers, symbols, or any other flag bits???
    return eStrataUser;

  case llvm::ELF::ET_DYN:
    // 3 - Shared object file
    // TODO: is there any way to detect that an shared library is a kernel
    // related executable by inspecting the program headers, section
    // headers, symbols, or any other flag bits???
    return eStrataUnknown;

  case ET_CORE:
    // 4 - Core file
    // TODO: is there any way to detect that an core file is a kernel
    // related executable by inspecting the program headers, section
    // headers, symbols, or any other flag bits???
    return eStrataUnknown;

  default:
    break;
  }
  return eStrataUnknown;
}

size_t ObjectFileELF::ReadSectionData(Section *section,
                       lldb::offset_t section_offset, void *dst,
                       size_t dst_len) {
  // 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->Test(SHF_COMPRESSED))
    return ObjectFile::ReadSectionData(section, section_offset, dst, dst_len);

  // For compressed sections we need to read to full data to be able to
  // decompress.
  DataExtractor data;
  ReadSectionData(section, data);
  return data.CopyData(section_offset, dst_len, dst);
}

size_t ObjectFileELF::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);

  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES);

  size_t result = ObjectFile::ReadSectionData(section, section_data);
  if (result == 0 || !section->Test(SHF_COMPRESSED))
    return result;

  auto Decompressor = llvm::object::Decompressor::create(
      section->GetName().GetStringRef(),
      {reinterpret_cast<const char *>(section_data.GetDataStart()),
       size_t(section_data.GetByteSize())},
      GetByteOrder() == eByteOrderLittle, GetAddressByteSize() == 8);
  if (!Decompressor) {
    LLDB_LOG(log, "Unable to initialize decompressor for section {0}: {1}",
             section->GetName(), llvm::toString(Decompressor.takeError()));
    return result;
  }
  auto buffer_sp =
      std::make_shared<DataBufferHeap>(Decompressor->getDecompressedSize(), 0);
  if (auto Error = Decompressor->decompress(
          {reinterpret_cast<char *>(buffer_sp->GetBytes()),
           size_t(buffer_sp->GetByteSize())})) {
    LLDB_LOG(log, "Decompression of section {0} failed: {1}",
             section->GetName(), llvm::toString(std::move(Error)));
    return result;
  }
  section_data.SetData(buffer_sp);
  return buffer_sp->GetByteSize();
}
