diff options
Diffstat (limited to 'source/Plugins/ObjectFile')
| -rw-r--r-- | source/Plugins/ObjectFile/ELF/ELFHeader.cpp | 607 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/ELF/ELFHeader.h | 645 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 5918 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/ELF/ObjectFileELF.h | 766 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp | 429 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/JIT/ObjectFileJIT.h | 201 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp | 11217 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h | 396 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp | 1748 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h | 540 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp | 63 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.h | 9 | 
12 files changed, 10951 insertions, 11588 deletions
diff --git a/source/Plugins/ObjectFile/ELF/ELFHeader.cpp b/source/Plugins/ObjectFile/ELF/ELFHeader.cpp index 625cce3c10627..a3e82390d262e 100644 --- a/source/Plugins/ObjectFile/ELF/ELFHeader.cpp +++ b/source/Plugins/ObjectFile/ELF/ELFHeader.cpp @@ -24,240 +24,201 @@ using namespace llvm::ELF;  //  // GetMaxU64 and GetMaxS64 wrap the similarly named methods from DataExtractor  // with error handling code and provide for parsing a sequence of values. -static bool -GetMaxU64(const lldb_private::DataExtractor &data, -          lldb::offset_t *offset, -          uint64_t *value, -          uint32_t byte_size) -{ -    const lldb::offset_t saved_offset = *offset; -    *value = data.GetMaxU64(offset, byte_size); -    return *offset != saved_offset; +static bool GetMaxU64(const lldb_private::DataExtractor &data, +                      lldb::offset_t *offset, uint64_t *value, +                      uint32_t byte_size) { +  const lldb::offset_t saved_offset = *offset; +  *value = data.GetMaxU64(offset, byte_size); +  return *offset != saved_offset;  } -static bool -GetMaxU64(const lldb_private::DataExtractor &data,  -          lldb::offset_t *offset, -          uint64_t *value, -          uint32_t byte_size, -          uint32_t count)  -{ -    lldb::offset_t saved_offset = *offset; - -    for (uint32_t i = 0; i < count; ++i, ++value) -    { -        if (GetMaxU64(data, offset, value, byte_size) == false)  -        { -            *offset = saved_offset; -            return false; -        } +static bool GetMaxU64(const lldb_private::DataExtractor &data, +                      lldb::offset_t *offset, uint64_t *value, +                      uint32_t byte_size, uint32_t count) { +  lldb::offset_t saved_offset = *offset; + +  for (uint32_t i = 0; i < count; ++i, ++value) { +    if (GetMaxU64(data, offset, value, byte_size) == false) { +      *offset = saved_offset; +      return false;      } -    return true; +  } +  return true;  } -static bool -GetMaxS64(const lldb_private::DataExtractor &data,  -          lldb::offset_t *offset, -          int64_t *value, -          uint32_t byte_size) -{ -    const lldb::offset_t saved_offset = *offset; -    *value = data.GetMaxS64(offset, byte_size); -    return *offset != saved_offset; +static bool GetMaxS64(const lldb_private::DataExtractor &data, +                      lldb::offset_t *offset, int64_t *value, +                      uint32_t byte_size) { +  const lldb::offset_t saved_offset = *offset; +  *value = data.GetMaxS64(offset, byte_size); +  return *offset != saved_offset;  } -static bool -GetMaxS64(const lldb_private::DataExtractor &data,  -          lldb::offset_t *offset, -          int64_t *value, -          uint32_t byte_size, -          uint32_t count)  -{ -    lldb::offset_t saved_offset = *offset; - -    for (uint32_t i = 0; i < count; ++i, ++value) -    { -        if (GetMaxS64(data, offset, value, byte_size) == false)  -        { -            *offset = saved_offset; -            return false; -        } +static bool GetMaxS64(const lldb_private::DataExtractor &data, +                      lldb::offset_t *offset, int64_t *value, +                      uint32_t byte_size, uint32_t count) { +  lldb::offset_t saved_offset = *offset; + +  for (uint32_t i = 0; i < count; ++i, ++value) { +    if (GetMaxS64(data, offset, value, byte_size) == false) { +      *offset = saved_offset; +      return false;      } -    return true; +  } +  return true;  }  //------------------------------------------------------------------------------  // ELFHeader -ELFHeader::ELFHeader() -{ -    memset(this, 0, sizeof(ELFHeader));  -} +ELFHeader::ELFHeader() { memset(this, 0, sizeof(ELFHeader)); } -ByteOrder -ELFHeader::GetByteOrder() const  -{ -    if (e_ident[EI_DATA] == ELFDATA2MSB) -        return eByteOrderBig; -    if (e_ident[EI_DATA] == ELFDATA2LSB) -        return eByteOrderLittle; -    return eByteOrderInvalid; +ByteOrder ELFHeader::GetByteOrder() const { +  if (e_ident[EI_DATA] == ELFDATA2MSB) +    return eByteOrderBig; +  if (e_ident[EI_DATA] == ELFDATA2LSB) +    return eByteOrderLittle; +  return eByteOrderInvalid;  } -bool -ELFHeader::Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset)  -{ -    // Read e_ident.  This provides byte order and address size info. -    if (data.GetU8(offset, &e_ident, EI_NIDENT) == NULL) -        return false; +bool ELFHeader::Parse(lldb_private::DataExtractor &data, +                      lldb::offset_t *offset) { +  // Read e_ident.  This provides byte order and address size info. +  if (data.GetU8(offset, &e_ident, EI_NIDENT) == NULL) +    return false; -    const unsigned byte_size = Is32Bit() ? 4 : 8; -    data.SetByteOrder(GetByteOrder()); -    data.SetAddressByteSize(byte_size); +  const unsigned byte_size = Is32Bit() ? 4 : 8; +  data.SetByteOrder(GetByteOrder()); +  data.SetAddressByteSize(byte_size); -    // Read e_type and e_machine. -    if (data.GetU16(offset, &e_type, 2) == NULL) -        return false; +  // Read e_type and e_machine. +  if (data.GetU16(offset, &e_type, 2) == NULL) +    return false; -    // Read e_version. -    if (data.GetU32(offset, &e_version, 1) == NULL) -        return false; +  // Read e_version. +  if (data.GetU32(offset, &e_version, 1) == NULL) +    return false; -    // Read e_entry, e_phoff and e_shoff. -    if (GetMaxU64(data, offset, &e_entry, byte_size, 3) == false) -        return false; +  // Read e_entry, e_phoff and e_shoff. +  if (GetMaxU64(data, offset, &e_entry, byte_size, 3) == false) +    return false; -    // Read e_flags. -    if (data.GetU32(offset, &e_flags, 1) == NULL) -        return false; +  // Read e_flags. +  if (data.GetU32(offset, &e_flags, 1) == NULL) +    return false; -    // Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum and -    // e_shstrndx. -    if (data.GetU16(offset, &e_ehsize, 6) == NULL) -        return false; +  // Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum and +  // e_shstrndx. +  if (data.GetU16(offset, &e_ehsize, 6) == NULL) +    return false; -    return true; +  return true;  } -bool -ELFHeader::MagicBytesMatch(const uint8_t *magic) -{ -    return memcmp(magic, ElfMagic, strlen(ElfMagic)) == 0; +bool ELFHeader::MagicBytesMatch(const uint8_t *magic) { +  return memcmp(magic, ElfMagic, strlen(ElfMagic)) == 0;  } -unsigned -ELFHeader::AddressSizeInBytes(const uint8_t *magic) -{ -    unsigned address_size = 0; - -    switch (magic[EI_CLASS])  -    { -    case ELFCLASS32: -        address_size = 4; -        break; -             -    case ELFCLASS64: -        address_size = 8; -        break; -    } -    return address_size; -} +unsigned ELFHeader::AddressSizeInBytes(const uint8_t *magic) { +  unsigned address_size = 0; -unsigned -ELFHeader::GetRelocationJumpSlotType() const -{ -    unsigned slot = 0; - -    switch (e_machine) -    { -    default: -        assert(false && "architecture not supported"); -        break; -    case EM_PPC: -        slot = R_PPC_JMP_SLOT; -        break; -    case EM_PPC64: -        slot = R_PPC64_JMP_SLOT; -        break; -    case EM_386: -    case EM_IAMCU: // FIXME: is this correct? -        slot = R_386_JUMP_SLOT; -        break; -    case EM_X86_64: -        slot = R_X86_64_JUMP_SLOT; -        break; -    case EM_ARM: -        slot = R_ARM_JUMP_SLOT; -        break; -    case EM_HEXAGON: -        slot = R_HEX_JMP_SLOT; -        break; -    case EM_AARCH64: -        slot = R_AARCH64_JUMP_SLOT; -        break; -    case EM_MIPS: -        slot = R_MIPS_JUMP_SLOT; -        break; -    case EM_S390: -        slot = R_390_JMP_SLOT; -        break; -    } +  switch (magic[EI_CLASS]) { +  case ELFCLASS32: +    address_size = 4; +    break; -    return slot; +  case ELFCLASS64: +    address_size = 8; +    break; +  } +  return address_size; +} + +unsigned ELFHeader::GetRelocationJumpSlotType() const { +  unsigned slot = 0; + +  switch (e_machine) { +  default: +    assert(false && "architecture not supported"); +    break; +  case EM_PPC: +    slot = R_PPC_JMP_SLOT; +    break; +  case EM_PPC64: +    slot = R_PPC64_JMP_SLOT; +    break; +  case EM_386: +  case EM_IAMCU: // FIXME: is this correct? +    slot = R_386_JUMP_SLOT; +    break; +  case EM_X86_64: +    slot = R_X86_64_JUMP_SLOT; +    break; +  case EM_ARM: +    slot = R_ARM_JUMP_SLOT; +    break; +  case EM_HEXAGON: +    slot = R_HEX_JMP_SLOT; +    break; +  case EM_AARCH64: +    slot = R_AARCH64_JUMP_SLOT; +    break; +  case EM_MIPS: +    slot = R_MIPS_JUMP_SLOT; +    break; +  case EM_S390: +    slot = R_390_JMP_SLOT; +    break; +  } + +  return slot;  }  //------------------------------------------------------------------------------  // ELFSectionHeader -ELFSectionHeader::ELFSectionHeader()  -{ -    memset(this, 0, sizeof(ELFSectionHeader)); +ELFSectionHeader::ELFSectionHeader() { +  memset(this, 0, sizeof(ELFSectionHeader));  } -bool -ELFSectionHeader::Parse(const lldb_private::DataExtractor &data, -                        lldb::offset_t *offset) -{ -    const unsigned byte_size = data.GetAddressByteSize(); +bool ELFSectionHeader::Parse(const lldb_private::DataExtractor &data, +                             lldb::offset_t *offset) { +  const unsigned byte_size = data.GetAddressByteSize(); -    // Read sh_name and sh_type. -    if (data.GetU32(offset, &sh_name, 2) == NULL) -        return false; +  // Read sh_name and sh_type. +  if (data.GetU32(offset, &sh_name, 2) == NULL) +    return false; -    // Read sh_flags. -    if (GetMaxU64(data, offset, &sh_flags, byte_size) == false) -        return false; +  // Read sh_flags. +  if (GetMaxU64(data, offset, &sh_flags, byte_size) == false) +    return false; -    // Read sh_addr, sh_off and sh_size. -    if (GetMaxU64(data, offset, &sh_addr, byte_size, 3) == false) -        return false; +  // Read sh_addr, sh_off and sh_size. +  if (GetMaxU64(data, offset, &sh_addr, byte_size, 3) == false) +    return false; -    // Read sh_link and sh_info. -    if (data.GetU32(offset, &sh_link, 2) == NULL) -        return false; +  // Read sh_link and sh_info. +  if (data.GetU32(offset, &sh_link, 2) == NULL) +    return false; -    // Read sh_addralign and sh_entsize. -    if (GetMaxU64(data, offset, &sh_addralign, byte_size, 2) == false) -        return false; +  // Read sh_addralign and sh_entsize. +  if (GetMaxU64(data, offset, &sh_addralign, byte_size, 2) == false) +    return false; -    return true; +  return true;  }  //------------------------------------------------------------------------------  // ELFSymbol -ELFSymbol::ELFSymbol()  -{ -    memset(this, 0, sizeof(ELFSymbol)); -} +ELFSymbol::ELFSymbol() { memset(this, 0, sizeof(ELFSymbol)); } -#define ENUM_TO_CSTR(e) case e: return #e +#define ENUM_TO_CSTR(e)                                                        \ +  case e:                                                                      \ +    return #e -const char * -ELFSymbol::bindingToCString(unsigned char binding) -{ -    switch (binding) -    { +const char *ELFSymbol::bindingToCString(unsigned char binding) { +  switch (binding) {      ENUM_TO_CSTR(STB_LOCAL);      ENUM_TO_CSTR(STB_GLOBAL);      ENUM_TO_CSTR(STB_WEAK); @@ -265,15 +226,12 @@ ELFSymbol::bindingToCString(unsigned char binding)      ENUM_TO_CSTR(STB_HIOS);      ENUM_TO_CSTR(STB_LOPROC);      ENUM_TO_CSTR(STB_HIPROC); -    } -    return ""; +  } +  return "";  } -const char * -ELFSymbol::typeToCString(unsigned char type) -{ -    switch (type) -    { +const char *ELFSymbol::typeToCString(unsigned char type) { +  switch (type) {      ENUM_TO_CSTR(STT_NOTYPE);      ENUM_TO_CSTR(STT_OBJECT);      ENUM_TO_CSTR(STT_FUNC); @@ -285,16 +243,13 @@ ELFSymbol::typeToCString(unsigned char type)      ENUM_TO_CSTR(STT_HIOS);      ENUM_TO_CSTR(STT_LOPROC);      ENUM_TO_CSTR(STT_HIPROC); -    } -    return ""; +  } +  return "";  } -const char * -ELFSymbol::sectionIndexToCString (elf_half shndx, -                                  const lldb_private::SectionList *section_list) -{ -    switch (shndx) -    { +const char *ELFSymbol::sectionIndexToCString( +    elf_half shndx, const lldb_private::SectionList *section_list) { +  switch (shndx) {      ENUM_TO_CSTR(SHN_UNDEF);      ENUM_TO_CSTR(SHN_LOPROC);      ENUM_TO_CSTR(SHN_HIPROC); @@ -303,180 +258,148 @@ ELFSymbol::sectionIndexToCString (elf_half shndx,      ENUM_TO_CSTR(SHN_ABS);      ENUM_TO_CSTR(SHN_COMMON);      ENUM_TO_CSTR(SHN_XINDEX); -    default: -        { -            const lldb_private::Section *section = section_list->GetSectionAtIndex(shndx).get(); -            if (section) -                return section->GetName().AsCString(""); -        } -        break; -    } -    return ""; +  default: { +    const lldb_private::Section *section = +        section_list->GetSectionAtIndex(shndx).get(); +    if (section) +      return section->GetName().AsCString(""); +  } break; +  } +  return "";  } -void -ELFSymbol::Dump (lldb_private::Stream *s, -                 uint32_t idx, -                 const lldb_private::DataExtractor *strtab_data, -                 const lldb_private::SectionList *section_list) -{ -    s->Printf("[%3u] 0x%16.16" PRIx64 " 0x%16.16" PRIx64 " 0x%8.8x 0x%2.2x (%-10s %-13s) 0x%2.2x 0x%4.4x (%-10s) %s\n", -              idx, -              st_value, -              st_size, -              st_name, -              st_info, -              bindingToCString (getBinding()), -              typeToCString (getType()), -              st_other, -              st_shndx, -              sectionIndexToCString (st_shndx, section_list), -              strtab_data ? strtab_data->PeekCStr(st_name) : ""); +void ELFSymbol::Dump(lldb_private::Stream *s, uint32_t idx, +                     const lldb_private::DataExtractor *strtab_data, +                     const lldb_private::SectionList *section_list) { +  s->Printf("[%3u] 0x%16.16" PRIx64 " 0x%16.16" PRIx64 +            " 0x%8.8x 0x%2.2x (%-10s %-13s) 0x%2.2x 0x%4.4x (%-10s) %s\n", +            idx, st_value, st_size, st_name, st_info, +            bindingToCString(getBinding()), typeToCString(getType()), st_other, +            st_shndx, sectionIndexToCString(st_shndx, section_list), +            strtab_data ? strtab_data->PeekCStr(st_name) : "");  } -bool -ELFSymbol::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) -{ -    const unsigned byte_size = data.GetAddressByteSize(); -    const bool parsing_32 = byte_size == 4; - -    // Read st_name. -    if (data.GetU32(offset, &st_name, 1) == NULL) -        return false; - -    if (parsing_32)  -    { -        // Read st_value and st_size. -        if (GetMaxU64(data, offset, &st_value, byte_size, 2) == false) -            return false; - -        // Read st_info and st_other. -        if (data.GetU8(offset, &st_info, 2) == NULL) -            return false; -             -        // Read st_shndx. -        if (data.GetU16(offset, &st_shndx, 1) == NULL) -            return false; -    } -    else  -    { -        // Read st_info and st_other. -        if (data.GetU8(offset, &st_info, 2) == NULL) -            return false; -             -        // Read st_shndx. -        if (data.GetU16(offset, &st_shndx, 1) == NULL) -            return false; - -        // Read st_value and st_size. -        if (data.GetU64(offset, &st_value, 2) == NULL) -            return false; -    } -    return true; +bool ELFSymbol::Parse(const lldb_private::DataExtractor &data, +                      lldb::offset_t *offset) { +  const unsigned byte_size = data.GetAddressByteSize(); +  const bool parsing_32 = byte_size == 4; + +  // Read st_name. +  if (data.GetU32(offset, &st_name, 1) == NULL) +    return false; + +  if (parsing_32) { +    // Read st_value and st_size. +    if (GetMaxU64(data, offset, &st_value, byte_size, 2) == false) +      return false; + +    // Read st_info and st_other. +    if (data.GetU8(offset, &st_info, 2) == NULL) +      return false; + +    // Read st_shndx. +    if (data.GetU16(offset, &st_shndx, 1) == NULL) +      return false; +  } else { +    // Read st_info and st_other. +    if (data.GetU8(offset, &st_info, 2) == NULL) +      return false; + +    // Read st_shndx. +    if (data.GetU16(offset, &st_shndx, 1) == NULL) +      return false; + +    // Read st_value and st_size. +    if (data.GetU64(offset, &st_value, 2) == NULL) +      return false; +  } +  return true;  }  //------------------------------------------------------------------------------  // ELFProgramHeader -ELFProgramHeader::ELFProgramHeader()  -{ -    memset(this, 0, sizeof(ELFProgramHeader)); +ELFProgramHeader::ELFProgramHeader() { +  memset(this, 0, sizeof(ELFProgramHeader));  } -bool -ELFProgramHeader::Parse(const lldb_private::DataExtractor &data,  -                        lldb::offset_t *offset) -{ -    const uint32_t byte_size = data.GetAddressByteSize(); -    const bool parsing_32 = byte_size == 4; - -    // Read p_type; -    if (data.GetU32(offset, &p_type, 1) == NULL) -        return false; - -    if (parsing_32) { -        // Read p_offset, p_vaddr, p_paddr, p_filesz and p_memsz. -        if (GetMaxU64(data, offset, &p_offset, byte_size, 5) == false) -            return false; - -        // Read p_flags. -        if (data.GetU32(offset, &p_flags, 1) == NULL) -            return false; - -        // Read p_align. -        if (GetMaxU64(data, offset, &p_align, byte_size) == false) -            return false; -    } -    else { -        // Read p_flags. -        if (data.GetU32(offset, &p_flags, 1) == NULL) -            return false; - -        // Read p_offset, p_vaddr, p_paddr, p_filesz, p_memsz and p_align. -        if (GetMaxU64(data, offset, &p_offset, byte_size, 6) == false) -            return false; -    } - -    return true; +bool ELFProgramHeader::Parse(const lldb_private::DataExtractor &data, +                             lldb::offset_t *offset) { +  const uint32_t byte_size = data.GetAddressByteSize(); +  const bool parsing_32 = byte_size == 4; + +  // Read p_type; +  if (data.GetU32(offset, &p_type, 1) == NULL) +    return false; + +  if (parsing_32) { +    // Read p_offset, p_vaddr, p_paddr, p_filesz and p_memsz. +    if (GetMaxU64(data, offset, &p_offset, byte_size, 5) == false) +      return false; + +    // Read p_flags. +    if (data.GetU32(offset, &p_flags, 1) == NULL) +      return false; + +    // Read p_align. +    if (GetMaxU64(data, offset, &p_align, byte_size) == false) +      return false; +  } else { +    // Read p_flags. +    if (data.GetU32(offset, &p_flags, 1) == NULL) +      return false; + +    // Read p_offset, p_vaddr, p_paddr, p_filesz, p_memsz and p_align. +    if (GetMaxU64(data, offset, &p_offset, byte_size, 6) == false) +      return false; +  } + +  return true;  }  //------------------------------------------------------------------------------  // ELFDynamic -ELFDynamic::ELFDynamic()  -{  -    memset(this, 0, sizeof(ELFDynamic));  -} +ELFDynamic::ELFDynamic() { memset(this, 0, sizeof(ELFDynamic)); } -bool -ELFDynamic::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) -{ -    const unsigned byte_size = data.GetAddressByteSize(); -    return GetMaxS64(data, offset, &d_tag, byte_size, 2); +bool ELFDynamic::Parse(const lldb_private::DataExtractor &data, +                       lldb::offset_t *offset) { +  const unsigned byte_size = data.GetAddressByteSize(); +  return GetMaxS64(data, offset, &d_tag, byte_size, 2);  }  //------------------------------------------------------------------------------  // ELFRel -ELFRel::ELFRel() -{ -    memset(this, 0, sizeof(ELFRel)); -} +ELFRel::ELFRel() { memset(this, 0, sizeof(ELFRel)); } -bool -ELFRel::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) -{ -    const unsigned byte_size = data.GetAddressByteSize(); +bool ELFRel::Parse(const lldb_private::DataExtractor &data, +                   lldb::offset_t *offset) { +  const unsigned byte_size = data.GetAddressByteSize(); -    // Read r_offset and r_info. -    if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false) -        return false; +  // Read r_offset and r_info. +  if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false) +    return false; -    return true; +  return true;  }  //------------------------------------------------------------------------------  // ELFRela -ELFRela::ELFRela() -{ -    memset(this, 0, sizeof(ELFRela)); -} +ELFRela::ELFRela() { memset(this, 0, sizeof(ELFRela)); } -bool -ELFRela::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) -{ -    const unsigned byte_size = data.GetAddressByteSize(); +bool ELFRela::Parse(const lldb_private::DataExtractor &data, +                    lldb::offset_t *offset) { +  const unsigned byte_size = data.GetAddressByteSize(); -    // Read r_offset and r_info. -    if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false) -        return false; +  // Read r_offset and r_info. +  if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false) +    return false; -    // Read r_addend; -    if (GetMaxS64(data, offset, &r_addend, byte_size) == false) -        return false; +  // Read r_addend; +  if (GetMaxS64(data, offset, &r_addend, byte_size) == false) +    return false; -    return true; +  return true;  } - - diff --git a/source/Plugins/ObjectFile/ELF/ELFHeader.h b/source/Plugins/ObjectFile/ELF/ELFHeader.h index 4ea22b51baf70..71b200f1c16b6 100644 --- a/source/Plugins/ObjectFile/ELF/ELFHeader.h +++ b/source/Plugins/ObjectFile/ELF/ELFHeader.h @@ -25,13 +25,11 @@  #include "lldb/lldb-enumerations.h" -namespace lldb_private -{ +namespace lldb_private {  class DataExtractor;  } // End namespace lldb_private. -namespace elf  -{ +namespace elf {  //------------------------------------------------------------------------------  /// @name ELF type definitions. @@ -44,10 +42,10 @@ typedef uint64_t elf_addr;  typedef uint64_t elf_off;  typedef uint16_t elf_half;  typedef uint32_t elf_word; -typedef int32_t  elf_sword; +typedef int32_t elf_sword;  typedef uint64_t elf_size;  typedef uint64_t elf_xword; -typedef int64_t  elf_sxword; +typedef int64_t elf_sxword;  //@}  //------------------------------------------------------------------------------ @@ -56,376 +54,331 @@ typedef int64_t  elf_sxword;  ///  /// This object is used to identify the general attributes on an ELF file and to  /// locate additional sections within the file. -struct ELFHeader  -{ -    unsigned char e_ident[llvm::ELF::EI_NIDENT]; ///< ELF file identification. -    elf_addr      e_entry;            ///< Virtual address program entry point. -    elf_off       e_phoff;            ///< File offset of program header table. -    elf_off       e_shoff;            ///< File offset of section header table. -    elf_word      e_flags;            ///< Processor specific flags. -    elf_word      e_version;          ///< Version of object file (always 1). -    elf_half      e_type;             ///< Object file type. -    elf_half      e_machine;          ///< Target architecture. -    elf_half      e_ehsize;           ///< Byte size of the ELF header. -    elf_half      e_phentsize;        ///< Size of a program header table entry. -    elf_half      e_phnum;            ///< Number of program header entries. -    elf_half      e_shentsize;        ///< Size of a section header table entry. -    elf_half      e_shnum;            ///< Number of section header entries. -    elf_half      e_shstrndx;         ///< String table section index. - -    ELFHeader(); - -    //-------------------------------------------------------------------------- -    /// Returns true if this is a 32 bit ELF file header. -    /// -    /// @return -    ///    True if this is a 32 bit ELF file header. -    bool Is32Bit() const {  -        return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32;  -    } - -    //-------------------------------------------------------------------------- -    /// Returns true if this is a 64 bit ELF file header. -    /// -    /// @return -    ///   True if this is a 64 bit ELF file header. -    bool Is64Bit() const {  -        return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64;  -    } - -    //-------------------------------------------------------------------------- -    /// The byte order of this ELF file header. -    /// -    /// @return -    ///    The byte order of this ELF file as described by the header. -    lldb::ByteOrder -    GetByteOrder() const; - -    //-------------------------------------------------------------------------- -    /// The jump slot relocation type of this ELF. -    unsigned -    GetRelocationJumpSlotType() const; - -    //-------------------------------------------------------------------------- -    /// Parse an ELFHeader entry starting at position \p offset and -    /// update the data extractor with the address size and byte order -    /// attributes as defined by the header. -    /// -    /// @param[in,out] data -    ///    The DataExtractor to read from.  Updated with the address size and -    ///    byte order attributes appropriate to this header. -    /// -    /// @param[in,out] offset -    ///    Pointer to an offset in the data.  On return the offset will be -    ///    advanced by the number of bytes read. -    /// -    /// @return -    ///    True if the ELFHeader was successfully read and false -    ///    otherwise. -    bool -    Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset); - -    //-------------------------------------------------------------------------- -    /// Examines at most EI_NIDENT bytes starting from the given pointer and -    /// determines if the magic ELF identification exists. -    /// -    /// @return -    ///    True if the given sequence of bytes identifies an ELF file. -    static bool -    MagicBytesMatch(const uint8_t *magic); - -    //-------------------------------------------------------------------------- -    /// Examines at most EI_NIDENT bytes starting from the given address and -    /// determines the address size of the underlying ELF file.  This function -    /// should only be called on an pointer for which MagicBytesMatch returns -    /// true. -    /// -    /// @return -    ///    The number of bytes forming an address in the ELF file (either 4 or -    ///    8), else zero if the address size could not be determined. -    static unsigned -    AddressSizeInBytes(const uint8_t *magic); +struct ELFHeader { +  unsigned char e_ident[llvm::ELF::EI_NIDENT]; ///< ELF file identification. +  elf_addr e_entry;     ///< Virtual address program entry point. +  elf_off e_phoff;      ///< File offset of program header table. +  elf_off e_shoff;      ///< File offset of section header table. +  elf_word e_flags;     ///< Processor specific flags. +  elf_word e_version;   ///< Version of object file (always 1). +  elf_half e_type;      ///< Object file type. +  elf_half e_machine;   ///< Target architecture. +  elf_half e_ehsize;    ///< Byte size of the ELF header. +  elf_half e_phentsize; ///< Size of a program header table entry. +  elf_half e_phnum;     ///< Number of program header entries. +  elf_half e_shentsize; ///< Size of a section header table entry. +  elf_half e_shnum;     ///< Number of section header entries. +  elf_half e_shstrndx;  ///< String table section index. + +  ELFHeader(); + +  //-------------------------------------------------------------------------- +  /// Returns true if this is a 32 bit ELF file header. +  /// +  /// @return +  ///    True if this is a 32 bit ELF file header. +  bool Is32Bit() const { +    return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32; +  } + +  //-------------------------------------------------------------------------- +  /// Returns true if this is a 64 bit ELF file header. +  /// +  /// @return +  ///   True if this is a 64 bit ELF file header. +  bool Is64Bit() const { +    return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64; +  } + +  //-------------------------------------------------------------------------- +  /// The byte order of this ELF file header. +  /// +  /// @return +  ///    The byte order of this ELF file as described by the header. +  lldb::ByteOrder GetByteOrder() const; + +  //-------------------------------------------------------------------------- +  /// The jump slot relocation type of this ELF. +  unsigned GetRelocationJumpSlotType() const; + +  //-------------------------------------------------------------------------- +  /// Parse an ELFHeader entry starting at position \p offset and +  /// update the data extractor with the address size and byte order +  /// attributes as defined by the header. +  /// +  /// @param[in,out] data +  ///    The DataExtractor to read from.  Updated with the address size and +  ///    byte order attributes appropriate to this header. +  /// +  /// @param[in,out] offset +  ///    Pointer to an offset in the data.  On return the offset will be +  ///    advanced by the number of bytes read. +  /// +  /// @return +  ///    True if the ELFHeader was successfully read and false +  ///    otherwise. +  bool Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset); + +  //-------------------------------------------------------------------------- +  /// Examines at most EI_NIDENT bytes starting from the given pointer and +  /// determines if the magic ELF identification exists. +  /// +  /// @return +  ///    True if the given sequence of bytes identifies an ELF file. +  static bool MagicBytesMatch(const uint8_t *magic); + +  //-------------------------------------------------------------------------- +  /// Examines at most EI_NIDENT bytes starting from the given address and +  /// determines the address size of the underlying ELF file.  This function +  /// should only be called on an pointer for which MagicBytesMatch returns +  /// true. +  /// +  /// @return +  ///    The number of bytes forming an address in the ELF file (either 4 or +  ///    8), else zero if the address size could not be determined. +  static unsigned AddressSizeInBytes(const uint8_t *magic);  };  //------------------------------------------------------------------------------  /// @class ELFSectionHeader  /// @brief Generic representation of an ELF section header. -struct ELFSectionHeader  -{ -    elf_word  sh_name;          ///< Section name string index. -    elf_word  sh_type;          ///< Section type. -    elf_xword sh_flags;         ///< Section attributes.  -    elf_addr  sh_addr;          ///< Virtual address of the section in memory. -    elf_off   sh_offset;        ///< Start of section from beginning of file. -    elf_xword sh_size;          ///< Number of bytes occupied in the file. -    elf_word  sh_link;          ///< Index of associated section. -    elf_word  sh_info;          ///< Extra section info (overloaded). -    elf_xword sh_addralign;     ///< Power of two alignment constraint. -    elf_xword sh_entsize;       ///< Byte size of each section entry. - -    ELFSectionHeader(); - -    //-------------------------------------------------------------------------- -    /// Parse an ELFSectionHeader entry from the given DataExtracter starting at -    /// position \p offset. -    /// -    /// @param[in] data -    ///    The DataExtractor to read from.  The address size of the extractor -    ///    determines if a 32 or 64 bit object should be read. -    /// -    /// @param[in,out] offset -    ///    Pointer to an offset in the data.  On return the offset will be -    ///    advanced by the number of bytes read. -    /// -    /// @return -    ///    True if the ELFSectionHeader was successfully read and false -    ///    otherwise. -    bool -    Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); +struct ELFSectionHeader { +  elf_word sh_name;       ///< Section name string index. +  elf_word sh_type;       ///< Section type. +  elf_xword sh_flags;     ///< Section attributes. +  elf_addr sh_addr;       ///< Virtual address of the section in memory. +  elf_off sh_offset;      ///< Start of section from beginning of file. +  elf_xword sh_size;      ///< Number of bytes occupied in the file. +  elf_word sh_link;       ///< Index of associated section. +  elf_word sh_info;       ///< Extra section info (overloaded). +  elf_xword sh_addralign; ///< Power of two alignment constraint. +  elf_xword sh_entsize;   ///< Byte size of each section entry. + +  ELFSectionHeader(); + +  //-------------------------------------------------------------------------- +  /// Parse an ELFSectionHeader entry from the given DataExtracter starting at +  /// position \p offset. +  /// +  /// @param[in] data +  ///    The DataExtractor to read from.  The address size of the extractor +  ///    determines if a 32 or 64 bit object should be read. +  /// +  /// @param[in,out] offset +  ///    Pointer to an offset in the data.  On return the offset will be +  ///    advanced by the number of bytes read. +  /// +  /// @return +  ///    True if the ELFSectionHeader was successfully read and false +  ///    otherwise. +  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);  };  //------------------------------------------------------------------------------  /// @class ELFProgramHeader  /// @brief Generic representation of an ELF program header. -struct ELFProgramHeader -{ -    elf_word  p_type;           ///< Type of program segment. -    elf_word  p_flags;          ///< Segment attributes. -    elf_off   p_offset;         ///< Start of segment from beginning of file. -    elf_addr  p_vaddr;          ///< Virtual address of segment in memory. -    elf_addr  p_paddr;          ///< Physical address (for non-VM systems).  -    elf_xword p_filesz;         ///< Byte size of the segment in file. -    elf_xword p_memsz;          ///< Byte size of the segment in memory. -    elf_xword p_align;          ///< Segment alignment constraint. - -    ELFProgramHeader(); - -    /// Parse an ELFProgramHeader entry from the given DataExtractor starting at -    /// position \p offset.  The address size of the DataExtractor determines if -    /// a 32 or 64 bit object is to be parsed. -    /// -    /// @param[in] data -    ///    The DataExtractor to read from.  The address size of the extractor -    ///    determines if a 32 or 64 bit object should be read. -    /// -    /// @param[in,out] offset -    ///    Pointer to an offset in the data.  On return the offset will be -    ///    advanced by the number of bytes read. -    /// -    /// @return -    ///    True if the ELFProgramHeader was successfully read and false -    ///    otherwise. -    bool -    Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); +struct ELFProgramHeader { +  elf_word p_type;    ///< Type of program segment. +  elf_word p_flags;   ///< Segment attributes. +  elf_off p_offset;   ///< Start of segment from beginning of file. +  elf_addr p_vaddr;   ///< Virtual address of segment in memory. +  elf_addr p_paddr;   ///< Physical address (for non-VM systems). +  elf_xword p_filesz; ///< Byte size of the segment in file. +  elf_xword p_memsz;  ///< Byte size of the segment in memory. +  elf_xword p_align;  ///< Segment alignment constraint. + +  ELFProgramHeader(); + +  /// Parse an ELFProgramHeader entry from the given DataExtractor starting at +  /// position \p offset.  The address size of the DataExtractor determines if +  /// a 32 or 64 bit object is to be parsed. +  /// +  /// @param[in] data +  ///    The DataExtractor to read from.  The address size of the extractor +  ///    determines if a 32 or 64 bit object should be read. +  /// +  /// @param[in,out] offset +  ///    Pointer to an offset in the data.  On return the offset will be +  ///    advanced by the number of bytes read. +  /// +  /// @return +  ///    True if the ELFProgramHeader was successfully read and false +  ///    otherwise. +  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);  };  //------------------------------------------------------------------------------  /// @class ELFSymbol  /// @brief Represents a symbol within an ELF symbol table. -struct ELFSymbol -{ -    elf_addr      st_value;     ///< Absolute or relocatable address. -    elf_xword     st_size;      ///< Size of the symbol or zero. -    elf_word      st_name;      ///< Symbol name string index. -    unsigned char st_info;      ///< Symbol type and binding attributes. -    unsigned char st_other;     ///< Reserved for future use. -    elf_half      st_shndx;     ///< Section to which this symbol applies. - -    ELFSymbol(); - -    /// Returns the binding attribute of the st_info member. -    unsigned char getBinding() const { return st_info >> 4; } - -    /// Returns the type attribute of the st_info member. -    unsigned char getType() const { return st_info & 0x0F; } - -    /// Sets the binding and type of the st_info member. -    void setBindingAndType(unsigned char binding, unsigned char type) { -        st_info = (binding << 4) + (type & 0x0F); -    } - -    static const char * -    bindingToCString(unsigned char binding); - -    static const char * -    typeToCString(unsigned char type); - -    static const char * -    sectionIndexToCString(elf_half shndx, -                          const lldb_private::SectionList *section_list); - -    /// Parse an ELFSymbol entry from the given DataExtractor starting at -    /// position \p offset.  The address size of the DataExtractor determines if -    /// a 32 or 64 bit object is to be parsed. -    /// -    /// @param[in] data -    ///    The DataExtractor to read from.  The address size of the extractor -    ///    determines if a 32 or 64 bit object should be read. -    /// -    /// @param[in,out] offset -    ///    Pointer to an offset in the data.  On return the offset will be -    ///    advanced by the number of bytes read. -    /// -    /// @return -    ///    True if the ELFSymbol was successfully read and false otherwise. -    bool -    Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); -     -    void -    Dump (lldb_private::Stream *s, -          uint32_t idx, -          const lldb_private::DataExtractor *strtab_data, -          const lldb_private::SectionList *section_list); +struct ELFSymbol { +  elf_addr st_value;      ///< Absolute or relocatable address. +  elf_xword st_size;      ///< Size of the symbol or zero. +  elf_word st_name;       ///< Symbol name string index. +  unsigned char st_info;  ///< Symbol type and binding attributes. +  unsigned char st_other; ///< Reserved for future use. +  elf_half st_shndx;      ///< Section to which this symbol applies. + +  ELFSymbol(); + +  /// Returns the binding attribute of the st_info member. +  unsigned char getBinding() const { return st_info >> 4; } + +  /// Returns the type attribute of the st_info member. +  unsigned char getType() const { return st_info & 0x0F; } + +  /// Sets the binding and type of the st_info member. +  void setBindingAndType(unsigned char binding, unsigned char type) { +    st_info = (binding << 4) + (type & 0x0F); +  } + +  static const char *bindingToCString(unsigned char binding); + +  static const char *typeToCString(unsigned char type); + +  static const char * +  sectionIndexToCString(elf_half shndx, +                        const lldb_private::SectionList *section_list); + +  /// Parse an ELFSymbol entry from the given DataExtractor starting at +  /// position \p offset.  The address size of the DataExtractor determines if +  /// a 32 or 64 bit object is to be parsed. +  /// +  /// @param[in] data +  ///    The DataExtractor to read from.  The address size of the extractor +  ///    determines if a 32 or 64 bit object should be read. +  /// +  /// @param[in,out] offset +  ///    Pointer to an offset in the data.  On return the offset will be +  ///    advanced by the number of bytes read. +  /// +  /// @return +  ///    True if the ELFSymbol was successfully read and false otherwise. +  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); + +  void Dump(lldb_private::Stream *s, uint32_t idx, +            const lldb_private::DataExtractor *strtab_data, +            const lldb_private::SectionList *section_list);  };  //------------------------------------------------------------------------------  /// @class ELFDynamic  /// @brief Represents an entry in an ELF dynamic table. -struct ELFDynamic -{ -    elf_sxword d_tag;           ///< Type of dynamic table entry. -    union -    { -        elf_xword d_val;        ///< Integer value of the table entry. -        elf_addr  d_ptr;        ///< Pointer value of the table entry. -    }; - -    ELFDynamic(); - -    /// Parse an ELFDynamic entry from the given DataExtractor starting at -    /// position \p offset.  The address size of the DataExtractor determines if -    /// a 32 or 64 bit object is to be parsed. -    /// -    /// @param[in] data -    ///    The DataExtractor to read from.  The address size of the extractor -    ///    determines if a 32 or 64 bit object should be read. -    /// -    /// @param[in,out] offset -    ///    Pointer to an offset in the data.  On return the offset will be -    ///    advanced by the number of bytes read. -    /// -    /// @return -    ///    True if the ELFDynamic entry was successfully read and false -    ///    otherwise. -    bool -    Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); +struct ELFDynamic { +  elf_sxword d_tag; ///< Type of dynamic table entry. +  union { +    elf_xword d_val; ///< Integer value of the table entry. +    elf_addr d_ptr;  ///< Pointer value of the table entry. +  }; + +  ELFDynamic(); + +  /// Parse an ELFDynamic entry from the given DataExtractor starting at +  /// position \p offset.  The address size of the DataExtractor determines if +  /// a 32 or 64 bit object is to be parsed. +  /// +  /// @param[in] data +  ///    The DataExtractor to read from.  The address size of the extractor +  ///    determines if a 32 or 64 bit object should be read. +  /// +  /// @param[in,out] offset +  ///    Pointer to an offset in the data.  On return the offset will be +  ///    advanced by the number of bytes read. +  /// +  /// @return +  ///    True if the ELFDynamic entry was successfully read and false +  ///    otherwise. +  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);  };  //------------------------------------------------------------------------------  /// @class ELFRel  /// @brief Represents a relocation entry with an implicit addend. -struct ELFRel -{ -    elf_addr  r_offset;         ///< Address of reference. -    elf_xword r_info;           ///< symbol index and type of relocation. - -    ELFRel(); - -    /// Parse an ELFRel entry from the given DataExtractor starting at position -    /// \p offset.  The address size of the DataExtractor determines if a 32 or -    /// 64 bit object is to be parsed. -    /// -    /// @param[in] data -    ///    The DataExtractor to read from.  The address size of the extractor -    ///    determines if a 32 or 64 bit object should be read. -    /// -    /// @param[in,out] offset -    ///    Pointer to an offset in the data.  On return the offset will be -    ///    advanced by the number of bytes read. -    /// -    /// @return -    ///    True if the ELFRel entry was successfully read and false otherwise. -    bool -    Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); - -    /// Returns the type when the given entry represents a 32-bit relocation. -    static unsigned -    RelocType32(const ELFRel &rel) -    { -        return rel.r_info & 0x0ff; -    } - -    /// Returns the type when the given entry represents a 64-bit relocation. -    static unsigned -    RelocType64(const ELFRel &rel) -    { -        return rel.r_info & 0xffffffff; -    } - -    /// Returns the symbol index when the given entry represents a 32-bit -    /// relocation. -    static unsigned -    RelocSymbol32(const ELFRel &rel) -    { -        return rel.r_info >> 8; -    } - -    /// Returns the symbol index when the given entry represents a 64-bit -    /// relocation. -    static unsigned -    RelocSymbol64(const ELFRel &rel) -    { -        return rel.r_info >> 32; -    } +struct ELFRel { +  elf_addr r_offset; ///< Address of reference. +  elf_xword r_info;  ///< symbol index and type of relocation. + +  ELFRel(); + +  /// Parse an ELFRel entry from the given DataExtractor starting at position +  /// \p offset.  The address size of the DataExtractor determines if a 32 or +  /// 64 bit object is to be parsed. +  /// +  /// @param[in] data +  ///    The DataExtractor to read from.  The address size of the extractor +  ///    determines if a 32 or 64 bit object should be read. +  /// +  /// @param[in,out] offset +  ///    Pointer to an offset in the data.  On return the offset will be +  ///    advanced by the number of bytes read. +  /// +  /// @return +  ///    True if the ELFRel entry was successfully read and false otherwise. +  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); + +  /// Returns the type when the given entry represents a 32-bit relocation. +  static unsigned RelocType32(const ELFRel &rel) { return rel.r_info & 0x0ff; } + +  /// Returns the type when the given entry represents a 64-bit relocation. +  static unsigned RelocType64(const ELFRel &rel) { +    return rel.r_info & 0xffffffff; +  } + +  /// Returns the symbol index when the given entry represents a 32-bit +  /// relocation. +  static unsigned RelocSymbol32(const ELFRel &rel) { return rel.r_info >> 8; } + +  /// Returns the symbol index when the given entry represents a 64-bit +  /// relocation. +  static unsigned RelocSymbol64(const ELFRel &rel) { return rel.r_info >> 32; }  };  //------------------------------------------------------------------------------  /// @class ELFRela  /// @brief Represents a relocation entry with an explicit addend. -struct ELFRela -{ -    elf_addr   r_offset;        ///< Address of reference. -    elf_xword  r_info;          ///< Symbol index and type of relocation. -    elf_sxword r_addend;        ///< Constant part of expression. - -    ELFRela(); - -    /// Parse an ELFRela entry from the given DataExtractor starting at position -    /// \p offset.  The address size of the DataExtractor determines if a 32 or -    /// 64 bit object is to be parsed. -    /// -    /// @param[in] data -    ///    The DataExtractor to read from.  The address size of the extractor -    ///    determines if a 32 or 64 bit object should be read. -    /// -    /// @param[in,out] offset -    ///    Pointer to an offset in the data.  On return the offset will be -    ///    advanced by the number of bytes read. -    /// -    /// @return -    ///    True if the ELFRela entry was successfully read and false otherwise. -    bool -    Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); - -    /// Returns the type when the given entry represents a 32-bit relocation. -    static unsigned -    RelocType32(const ELFRela &rela) -    { -        return rela.r_info & 0x0ff; -    } - -    /// Returns the type when the given entry represents a 64-bit relocation. -    static unsigned -    RelocType64(const ELFRela &rela) -    { -        return rela.r_info & 0xffffffff; -    } - -    /// Returns the symbol index when the given entry represents a 32-bit -    /// relocation. -    static unsigned -    RelocSymbol32(const ELFRela &rela) -    { -        return rela.r_info >> 8; -    } - -    /// Returns the symbol index when the given entry represents a 64-bit -    /// relocation. -    static unsigned -    RelocSymbol64(const ELFRela &rela) -    { -        return rela.r_info >> 32; -    } +struct ELFRela { +  elf_addr r_offset;   ///< Address of reference. +  elf_xword r_info;    ///< Symbol index and type of relocation. +  elf_sxword r_addend; ///< Constant part of expression. + +  ELFRela(); + +  /// Parse an ELFRela entry from the given DataExtractor starting at position +  /// \p offset.  The address size of the DataExtractor determines if a 32 or +  /// 64 bit object is to be parsed. +  /// +  /// @param[in] data +  ///    The DataExtractor to read from.  The address size of the extractor +  ///    determines if a 32 or 64 bit object should be read. +  /// +  /// @param[in,out] offset +  ///    Pointer to an offset in the data.  On return the offset will be +  ///    advanced by the number of bytes read. +  /// +  /// @return +  ///    True if the ELFRela entry was successfully read and false otherwise. +  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); + +  /// Returns the type when the given entry represents a 32-bit relocation. +  static unsigned RelocType32(const ELFRela &rela) { +    return rela.r_info & 0x0ff; +  } + +  /// Returns the type when the given entry represents a 64-bit relocation. +  static unsigned RelocType64(const ELFRela &rela) { +    return rela.r_info & 0xffffffff; +  } + +  /// Returns the symbol index when the given entry represents a 32-bit +  /// relocation. +  static unsigned RelocSymbol32(const ELFRela &rela) { +    return rela.r_info >> 8; +  } + +  /// Returns the symbol index when the given entry represents a 64-bit +  /// relocation. +  static unsigned RelocSymbol64(const ELFRela &rela) { +    return rela.r_info >> 32; +  }  };  } // End namespace elf. diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 68e4e50a96e55..eb983154618bb 100644 --- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -9,8 +9,8 @@  #include "ObjectFileELF.h" -#include <cassert>  #include <algorithm> +#include <cassert>  #include <unordered_map>  #include "lldb/Core/ArchSpec.h" @@ -35,8 +35,10 @@  #include "llvm/Support/MathExtras.h"  #include "llvm/Support/MipsABIFlags.h" -#define CASE_AND_STREAM(s, def, width)                  \ -    case def: s->Printf("%-*s", width, #def); break; +#define CASE_AND_STREAM(s, def, width)                                         \ +  case def:                                                                    \ +    s->Printf("%-*s", width, #def);                                            \ +    break;  using namespace lldb;  using namespace lldb_private; @@ -47,64 +49,64 @@ 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_CSR     = "csr"; +const char *const LLDB_NT_OWNER_GNU = "GNU"; +const char *const LLDB_NT_OWNER_NETBSD = "NetBSD"; +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"; +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_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_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; +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_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 +#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 @@ -112,401 +114,335 @@ const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02;  ///  /// This helper class allows us to parse both ELFRel and ELFRela relocation  /// entries in a generic manner. -class ELFRelocation -{ +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); -    /// 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(); +  ~ELFRelocation(); -    bool -    Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); +  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); -    static unsigned -    RelocType32(const ELFRelocation &rel); +  static unsigned RelocType32(const ELFRelocation &rel); -    static unsigned -    RelocType64(const ELFRelocation &rel); +  static unsigned RelocType64(const ELFRelocation &rel); -    static unsigned -    RelocSymbol32(const ELFRelocation &rel); +  static unsigned RelocSymbol32(const ELFRelocation &rel); -    static unsigned -    RelocSymbol64(const ELFRelocation &rel); +  static unsigned RelocSymbol64(const ELFRelocation &rel); -    static unsigned -    RelocOffset32(const ELFRelocation &rel); +  static unsigned RelocOffset32(const ELFRelocation &rel); -    static unsigned -    RelocOffset64(const ELFRelocation &rel); +  static unsigned RelocOffset64(const ELFRelocation &rel); -    static unsigned -    RelocAddend32(const ELFRelocation &rel); +  static unsigned RelocAddend32(const ELFRelocation &rel); -    static unsigned -    RelocAddend64(const ELFRelocation &rel); +  static unsigned RelocAddend64(const ELFRelocation &rel);  private: -    typedef llvm::PointerUnion<ELFRel*, ELFRela*> RelocUnion; +  typedef llvm::PointerUnion<ELFRel *, ELFRela *> RelocUnion; -    RelocUnion reloc; +  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(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*>(); +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); +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::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::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::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::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::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::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::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; +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::elf_word e_flags, uint32_t endian) -{ -    const uint32_t mips_arch = e_flags & llvm::ELF::EF_MIPS_ARCH; -    uint32_t arch_variant = ArchSpec::eMIPSSubType_unknown; - -    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; -} +bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) { +  // Read all fields. +  if (data.GetU32(offset, &n_namesz, 3) == NULL) +    return false; -static uint32_t -subTypeFromElfHeader(const elf::ELFHeader& header) -{ -    if (header.e_machine == llvm::ELF::EM_MIPS) -        return mipsVariantFromElfFlags (header.e_flags, -            header.e_ident[EI_DATA]); +  // 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 -        llvm::ELF::EM_CSR_KALIMBA == header.e_machine ? -        kalimbaVariantFromElfFlags(header.e_flags) : -        LLDB_INVALID_CPUTYPE; +    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::elf_word e_flags, +                                        uint32_t endian) { +  const uint32_t mips_arch = e_flags & llvm::ELF::EF_MIPS_ARCH; +  uint32_t arch_variant = ArchSpec::eMIPSSubType_unknown; + +  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.e_flags, header.e_ident[EI_DATA]); + +  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; -    } +kalimbaSectionType(const elf::ELFHeader &header, +                   const elf::ELFSectionHeader §_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_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; -    } +  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; +  return eSectionTypeOther;  }  // Arbitrary constant used as UUID prefix for core files. -const uint32_t -ObjectFileELF::g_core_uuid_magic(0xE210C); +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 = file->MemoryMapFileContentsIfLocal(file_offset, length); -        data_offset = 0; -    } +void ObjectFileELF::Initialize() { +  PluginManager::RegisterPlugin(GetPluginNameStatic(), +                                GetPluginDescriptionStatic(), CreateInstance, +                                CreateMemoryInstance, GetModuleSpecifications); +} -    if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset)) -    { -        const uint8_t *magic = data_sp->GetBytes() + data_offset; -        if (ELFHeader::MagicBytesMatch(magic)) -        { -            // Update the data to contain the entire file if it doesn't already -            if (data_sp->GetByteSize() < length) { -                data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length); -                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; +void ObjectFileELF::Terminate() { +  PluginManager::UnregisterPlugin(CreateInstance);  } +lldb_private::ConstString ObjectFileELF::GetPluginNameStatic() { +  static ConstString g_name("elf"); +  return g_name; +} -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::auto_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; +const char *ObjectFileELF::GetPluginDescriptionStatic() { +  return "ELF object file reader.";  } -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; +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 = file->MemoryMapFileContentsIfLocal(file_offset, length); +    data_offset = 0; +  } + +  if (data_sp && +      data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset)) { +    const uint8_t *magic = data_sp->GetBytes() + data_offset; +    if (ELFHeader::MagicBytesMatch(magic)) { +      // Update the data to contain the entire file if it doesn't already +      if (data_sp->GetByteSize() < length) { +        data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length); +        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::auto_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;  }  /* @@ -515,130 +451,117 @@ ObjectFileELF::MagicBytesMatch (DataBufferSP& data_sp,   *   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>"; -    } +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  } @@ -648,2480 +571,2427 @@ OSABIAsCString (unsigned char osabi_byte)  // 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; -        if (header.Parse(data, &data_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); - -                    // -                    // 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 ()); -                    } - -                    // 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. -                    size_t section_header_end = header.e_shoff + header.e_shnum * header.e_shentsize; -                    if (section_header_end > data_sp->GetByteSize()) -                    { -                        data_sp = file.MemoryMapFileContentsIfLocal (file_offset, section_header_end); -                        data.SetData(data_sp); -                    } - -                    uint32_t gnu_debuglink_crc = 0; -                    std::string gnu_debuglink_file; -                    SectionHeaderColl section_headers; -                    lldb_private::UUID &uuid = spec.GetUUID(); - -                    using namespace std::placeholders; -                    const SetDataFunction set_data = std::bind(&ObjectFileELF::SetData, std::cref(data), _1, _2, _3); -                    GetSectionHeaderInfo(section_headers, set_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) -                        { -                            lldb_private::Timer scoped_timer (__PRETTY_FUNCTION__, -                                                              "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 = file.MemoryMapFileContentsIfLocal(file_offset, program_headers_end); -                                    data.SetData(data_sp); -                                } -                                ProgramHeaderColl program_headers; -                                GetProgramHeaderInfo(program_headers, set_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 = file.MemoryMapFileContentsIfLocal(file_offset, segment_data_end); -                                    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 = file.MemoryMapFileContentsIfLocal (file_offset, SIZE_MAX); -                                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); +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; +    if (header.Parse(data, &data_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); + +          // +          // 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()); +          } + +          // 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. +          size_t section_header_end = +              header.e_shoff + header.e_shnum * header.e_shentsize; +          if (section_header_end > data_sp->GetByteSize()) { +            data_sp = file.MemoryMapFileContentsIfLocal(file_offset, +                                                        section_header_end); +            data.SetData(data_sp); +          } + +          uint32_t gnu_debuglink_crc = 0; +          std::string gnu_debuglink_file; +          SectionHeaderColl section_headers; +          lldb_private::UUID &uuid = spec.GetUUID(); + +          using namespace std::placeholders; +          const SetDataFunction set_data = +              std::bind(&ObjectFileELF::SetData, std::cref(data), _1, _2, _3); +          GetSectionHeaderInfo(section_headers, set_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) { +              lldb_private::Timer scoped_timer( +                  LLVM_PRETTY_FUNCTION, +                  "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 = file.MemoryMapFileContentsIfLocal( +                      file_offset, program_headers_end); +                  data.SetData(data_sp); +                } +                ProgramHeaderColl program_headers; +                GetProgramHeaderInfo(program_headers, set_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 = file.MemoryMapFileContentsIfLocal(file_offset, +                                                              segment_data_end); +                  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 = +                    file.MemoryMapFileContentsIfLocal(file_offset, SIZE_MAX); +                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; +  return specs.GetSize() - initial_count;  }  //------------------------------------------------------------------  // PluginInterface protocol  //------------------------------------------------------------------ -lldb_private::ConstString -ObjectFileELF::GetPluginName() -{ -    return GetPluginNameStatic(); +lldb_private::ConstString ObjectFileELF::GetPluginName() { +  return GetPluginNameStatic();  } -uint32_t -ObjectFileELF::GetPluginVersion() -{ -    return m_plugin_version; -} +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 = 0, 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; -            } +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 = 0, count = GetProgramHeaderCount(); i < count; ++i) { +          const elf::ELFProgramHeader *header = GetProgramHeaderByIndex(i); +          if (header == nullptr) +            continue; -            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; +          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; +  } +  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; -    } +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; +  // Move iterator to the address class entry preceding address +  --ub; -    return ub->second; +  return ub->second;  } -size_t -ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I) -{ -    return std::distance(m_section_headers.begin(), I) + 1u; +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; +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; -    if (!m_header.Parse(m_data, &offset)) -        return false; - -    if (!IsInMemory()) -        return true; - -    // For in memory object files m_data might not contain the full object file. Try to load it -    // until the end of the "Section header table" what is at the end of the ELF file. -    addr_t file_size = m_header.e_shoff + m_header.e_shnum * m_header.e_shentsize; -    if (m_data.GetByteSize() < file_size) -    { -        ProcessSP process_sp (m_process_wp.lock()); -        if (!process_sp) -            return false; - -        DataBufferSP data_sp = ReadMemory(process_sp, m_memory_addr, file_size); -        if (!data_sp) -            return false; -        m_data.SetData(data_sp, 0, file_size); -    } +bool ObjectFileELF::ParseHeader() { +  lldb::offset_t offset = 0; +  if (!m_header.Parse(m_data, &offset)) +    return false; +  if (!IsInMemory())      return true; + +  // For in memory object files m_data might not contain the full object file. +  // Try to load it +  // until the end of the "Section header table" what is at the end of the ELF +  // file. +  addr_t file_size = m_header.e_shoff + m_header.e_shnum * m_header.e_shentsize; +  if (m_data.GetByteSize() < file_size) { +    ProcessSP process_sp(m_process_wp.lock()); +    if (!process_sp) +      return false; + +    DataBufferSP data_sp = ReadMemory(process_sp, m_memory_addr, file_size); +    if (!data_sp) +      return false; +    m_data.SetData(data_sp, 0, file_size); +  } + +  return true;  } -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; +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()) { +    // We have the full build id uuid. +    *uuid = m_uuid; +    return true; +  } else if (GetType() == ObjectFile::eTypeCoreFile) { +    uint32_t core_notes_crc = 0; -    if (m_uuid.IsValid()) -    { -        *uuid = m_uuid; -        return true; -    } +    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; +  return false;  } -lldb_private::FileSpecList -ObjectFileELF::GetDebugSymbolFilePaths() -{ -    FileSpecList file_spec_list; +lldb_private::FileSpecList ObjectFileELF::GetDebugSymbolFilePaths() { +  FileSpecList file_spec_list; -    if (!m_gnu_debuglink_file.empty()) -    { -        FileSpec file_spec (m_gnu_debuglink_file.c_str(), false); -        file_spec_list.Append (file_spec); -    } -    return 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; +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++; -    } +  for (unsigned i = 0; i < num_modules; ++i) { +    if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i))) +      num_specs++; +  } -    return num_specs; +  return num_specs;  } -Address -ObjectFileELF::GetImageInfoAddress(Target *target) -{ -    if (!ParseDynamicSymbols()) -        return Address(); +Address ObjectFileELF::GetImageInfoAddress(Target *target) { +  if (!ParseDynamicSymbols()) +    return Address(); -    SectionList *section_list = GetSectionList(); -    if (!section_list) -        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); +  // 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(); +  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]; +  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(); -        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(); - -            Error 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; -                } -            } +      Error 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(); +  return Address();  } -lldb_private::Address -ObjectFileELF::GetEntryPointAddress () -{ -    if (m_entry_point_address.IsValid()) -        return m_entry_point_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; +  if (!ParseHeader() || !IsExecutable()) +    return m_entry_point_address; -    SectionList *section_list = GetSectionList(); -    addr_t offset = m_header.e_entry; +  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; +  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(); +size_t ObjectFileELF::ParseDependentModules() { +  if (m_filespec_ap.get()) +    return m_filespec_ap->GetSize(); -    m_filespec_ap.reset(new FileSpecList()); +  m_filespec_ap.reset(new FileSpecList()); -    if (!ParseSectionHeaders()) -        return 0; +  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; +  SectionList *section_list = GetSectionList(); +  if (!section_list) +    return 0; -            if (symbol.d_tag != DT_NEEDED) -                continue; +  // Find the SHT_DYNAMIC section. +  Section *dynsym = +      section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true) +          .get(); +  if (!dynsym) +    return 0; +  assert(dynsym->GetObjectFile() == this); -            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)); -        } +  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(); +  return m_filespec_ap->GetSize();  }  //----------------------------------------------------------------------  // GetProgramHeaderInfo  //---------------------------------------------------------------------- -size_t -ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers, -                                    const SetDataFunction &set_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 (set_data(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; -    } +size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers, +                                           const SetDataFunction &set_data, +                                           const ELFHeader &header) { +  // We have already parsed the program headers +  if (!program_headers.empty()) +    return program_headers.size(); -    if (idx < program_headers.size()) -        program_headers.resize(idx); +  // If there are no program headers to read we are done. +  if (header.e_phnum == 0) +    return 0; -    return program_headers.size(); +  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 (set_data(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() -{ -    using namespace std::placeholders; -    return GetProgramHeaderInfo(m_program_headers, -                                std::bind(&ObjectFileELF::SetDataWithReadMemoryFallback, this, _1, _2, _3), -                                m_header); +size_t ObjectFileELF::ParseProgramHeaders() { +  using namespace std::placeholders; +  return GetProgramHeaderInfo( +      m_program_headers, +      std::bind(&ObjectFileELF::SetDataWithReadMemoryFallback, this, _1, _2, +                _3), +      m_header);  }  lldb_private::Error -ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch_spec, lldb_private::UUID &uuid) -{ -    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MODULES)); -    Error error; +ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, +                                           lldb_private::ArchSpec &arch_spec, +                                           lldb_private::UUID &uuid) { +  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES)); +  Error 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; +          } -    lldb::offset_t offset = 0; +          // 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; +            } -    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. +            // Save the build id as the UUID for the module. +            uuid.SetBytes(uuidbuf, note.n_descsz); +          } +        } +        break; +      } +    } +    // 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 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 (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; -            } +    // 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(); +  } -            // 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; +  return error; +} -            char os_name[32]; -            snprintf (os_name, sizeof (os_name), "freebsd%" PRIu32 ".%" PRIu32, version_major, version_minor); +void ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length, +                                       ArchSpec &arch_spec) { +  lldb::offset_t Offset = 0; -            // 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); +  uint8_t FormatVersion = data.GetU8(&Offset); +  if (FormatVersion != llvm::ARMBuildAttrs::Format_Version) +    return; -            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; -            } -        } -        // 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; -            } +  Offset = Offset + sizeof(uint32_t); // Section Length +  llvm::StringRef VendorName = data.GetCStr(&Offset); -            // 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 (VendorName != "aeabi") +    return; -            if (log) -                log->Printf ("ObjectFileELF::%s detected NetBSD, min version constant %" PRIu32, __FUNCTION__, version_info); -        } -        // 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: -            // 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 -            if (note.n_type == NT_FILE) -            { -                uint64_t count = data.GetU64(&offset); -                offset += 8 + 3*8*count; // Skip page size and all start/end/file_ofs -                for (size_t i=0; i<count; ++i) -                { -                    llvm::StringRef path(data.GetCStr(&offset)); -                    if (path.startswith("/lib/x86_64-linux-gnu")) -                    { -                        arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); -                        break; -                    } -                } -            } -        } +  if (arch_spec.GetTriple().getEnvironment() == +      llvm::Triple::UnknownEnvironment) +    arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI); -        // 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(); -    } +  while (Offset < length) { +    uint8_t Tag = data.GetU8(&Offset); +    uint32_t Size = data.GetU32(&Offset); -    return error; -} +    if (Tag != llvm::ARMBuildAttrs::File || Size == 0) +      continue; -void -ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length, ArchSpec &arch_spec) -{ -    lldb::offset_t Offset = 0; +    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); -    uint8_t FormatVersion = data.GetU8(&Offset); -    if (FormatVersion != llvm::ARMBuildAttrs::Format_Version) -      return; +        break; -    Offset = Offset + sizeof(uint32_t); // Section Length -    llvm::StringRef VendorName = data.GetCStr(&Offset); +      case llvm::ARMBuildAttrs::CPU_raw_name: +      case llvm::ARMBuildAttrs::CPU_name: +        data.GetCStr(&Offset); -    if (VendorName != "aeabi") -      return; +        break; -    if (arch_spec.GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment) -        arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI); +      case llvm::ARMBuildAttrs::ABI_VFP_args: { +        uint64_t VFPArgs = data.GetULEB128(&Offset); -    while (Offset < length) -    { -        uint8_t Tag = data.GetU8(&Offset); -        uint32_t Size = data.GetU32(&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); -        if (Tag != llvm::ARMBuildAttrs::File || Size == 0) -            continue; +          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); -        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; -                } -            } +          arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float);          } + +        break; +      } +      }      } +  }  }  //----------------------------------------------------------------------  // GetSectionHeaderInfo  //---------------------------------------------------------------------- -size_t -ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, -                                    const SetDataFunction &set_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 -        GetOsFromOSABI (header.e_ident[EI_OSABI], ostype); -        spec_ostype = arch_spec.GetTriple ().getOS (); -        assert(spec_ostype == 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; -        } +size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, +                                           const SetDataFunction &set_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); +  } + +  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 (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; +  // If there are no section headers we are done. +  if (header.e_shnum == 0) +    return 0; -    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MODULES)); +  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES)); -    section_headers.resize(header.e_shnum); -    if (section_headers.size() != header.e_shnum) -        return 0; +  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 (set_data (sh_data, sh_offset, sh_size) != sh_size) -        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 (set_data(sh_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) +  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 (set_data(shstr_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 && (set_data(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; -    } -    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 (set_data (shstr_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 && (set_data (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); -                } +          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 (arch_spec.GetMachine() == llvm::Triple::arm || +            arch_spec.GetMachine() == llvm::Triple::thumb) { +          DataExtractor data; -                    if (sheader.sh_type == SHT_ARM_ATTRIBUTES && section_size != 0 &&  -                        set_data(data, sheader.sh_offset, section_size) == section_size) -                        ParseARMAttributes(data, section_size, arch_spec); -                } +          if (sheader.sh_type == SHT_ARM_ATTRIBUTES && section_size != 0 && +              set_data(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 && (set_data (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); -                    } -                } +        if (name == g_sect_name_gnu_debuglink) { +          DataExtractor data; +          if (section_size && (set_data(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 && (set_data (data, sheader.sh_offset, section_size) == section_size)) -                    { -                        Error error = RefineModuleDetailsFromNote (data, arch_spec, uuid); -                        if (error.Fail ()) -                        { -                            if (log) -                                log->Printf ("ObjectFileELF::%s ELF note processing failed: %s", __FUNCTION__, error.AsCString ()); -                        } -                    } -                } +        // 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 && (set_data(data, sheader.sh_offset, +                                        section_size) == section_size)) { +            Error 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()); +      // 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(); -        } +      return section_headers.size();      } +  } -    section_headers.clear(); -    return 0; +  section_headers.clear(); +  return 0;  } -size_t -ObjectFileELF::GetProgramHeaderCount() -{ -    return ParseProgramHeaders(); -} +size_t ObjectFileELF::GetProgramHeaderCount() { return ParseProgramHeaders(); }  const elf::ELFProgramHeader * -ObjectFileELF::GetProgramHeaderByIndex(lldb::user_id_t id) -{ -    if (!id || !ParseProgramHeaders()) -        return NULL; +ObjectFileELF::GetProgramHeaderByIndex(lldb::user_id_t id) { +  if (!id || !ParseProgramHeaders()) +    return NULL; -    if (--id < m_program_headers.size()) -        return &m_program_headers[id]; +  if (--id < m_program_headers.size()) +    return &m_program_headers[id]; -    return NULL; +  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); +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);  }  std::string -ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const -{ -    size_t pos = symbol_name.find('@'); -    return symbol_name.substr(0, pos).str(); +ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const { +  size_t pos = symbol_name.find('@'); +  return symbol_name.substr(0, pos).str();  }  //----------------------------------------------------------------------  // ParseSectionHeaders  //---------------------------------------------------------------------- -size_t -ObjectFileELF::ParseSectionHeaders() -{ -    using namespace std::placeholders; +size_t ObjectFileELF::ParseSectionHeaders() { +  using namespace std::placeholders; -    return GetSectionHeaderInfo(m_section_headers, -                                std::bind(&ObjectFileELF::SetDataWithReadMemoryFallback, this, _1, _2, _3), -                                m_header, -                                m_uuid, -                                m_gnu_debuglink_file, -                                m_gnu_debuglink_crc, -                                m_arch_spec); +  return GetSectionHeaderInfo( +      m_section_headers, +      std::bind(&ObjectFileELF::SetDataWithReadMemoryFallback, this, _1, _2, +                _3), +      m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc, m_arch_spec);  } -lldb::offset_t -ObjectFileELF::SetData(const lldb_private::DataExtractor &src, lldb_private::DataExtractor &dst, lldb::offset_t offset, lldb::offset_t length) -{ -    return dst.SetData(src, offset, length); +lldb::offset_t ObjectFileELF::SetData(const lldb_private::DataExtractor &src, +                                      lldb_private::DataExtractor &dst, +                                      lldb::offset_t offset, +                                      lldb::offset_t length) { +  return dst.SetData(src, offset, length);  }  lldb::offset_t -ObjectFileELF::SetDataWithReadMemoryFallback(lldb_private::DataExtractor &dst, lldb::offset_t offset, lldb::offset_t length) -{ -    if (offset + length <= m_data.GetByteSize()) -        return dst.SetData(m_data, offset, length); - -    const auto process_sp = m_process_wp.lock(); -    if (process_sp != nullptr) -    { -        addr_t file_size = offset + length; - -        DataBufferSP data_sp = ReadMemory(process_sp, m_memory_addr, file_size); -        if (!data_sp) -            return false; -        m_data.SetData(data_sp, 0, file_size); -    } - +ObjectFileELF::SetDataWithReadMemoryFallback(lldb_private::DataExtractor &dst, +                                             lldb::offset_t offset, +                                             lldb::offset_t length) { +  if (offset + length <= m_data.GetByteSize())      return dst.SetData(m_data, offset, length); + +  const auto process_sp = m_process_wp.lock(); +  if (process_sp != nullptr) { +    addr_t file_size = offset + length; + +    DataBufferSP data_sp = ReadMemory(process_sp, m_memory_addr, file_size); +    if (!data_sp) +      return false; +    m_data.SetData(data_sp, 0, file_size); +  } + +  return dst.SetData(m_data, offset, length);  }  const ObjectFileELF::ELFSectionHeaderInfo * -ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id) -{ -    if (!id || !ParseSectionHeaders()) -        return NULL; +ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id) { +  if (!id || !ParseSectionHeaders()) +    return NULL; -    if (--id < m_section_headers.size()) -        return &m_section_headers[id]; +  if (--id < m_section_headers.size()) +    return &m_section_headers[id]; -    return NULL; +  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; +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()); - -        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_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_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_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_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 : 0) | -                                         ((header.sh_flags & SHF_WRITE) ? ePermissionsWritable : 0) | -                                         ((header.sh_flags & SHF_EXECINSTR) ? ePermissionsExecutable : 0); -            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); -            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. -                                              header.sh_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); -        } -    } +void ObjectFileELF::CreateSections(SectionList &unified_section_list) { +  if (!m_sections_ap.get() && ParseSectionHeaders()) { +    m_sections_ap.reset(new SectionList()); -    if (m_sections_ap.get()) -    { -        if (GetType() == eTypeDebugInfo) -        { -            static const SectionType g_sections[] = -            { -                eSectionTypeDWARFDebugAbbrev, -                eSectionTypeDWARFDebugAddr, -                eSectionTypeDWARFDebugAranges, -                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; +    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_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_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_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_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); +      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. +          header.sh_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,    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 +// 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'; +static char FindArmAarch64MappingSymbol(const char *symbol_name) { +  if (!symbol_name) +    return '\0'; -    if (dollar_pos[2] == '\0' || dollar_pos[2] == '.') -        return dollar_pos[1]; +  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) +#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; +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; +    } -    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; +    // 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; -        const char *symbol_name = strtab_data.PeekCStr(symbol.st_name); +      case STT_OBJECT: +        // The symbol is associated with a data object, such as a variable, +        // an array, etc. +        symbol_type = eSymbolTypeData; +        break; -        // No need to add non-section symbols that have no names -        if (symbol.getType() != STT_SECTION && -            (symbol_name == NULL || symbol_name[0] == '\0')) -            continue; +      case STT_FUNC: +        // The symbol is associated with a function or other executable code. +        symbol_type = eSymbolTypeCode; +        break; -        // 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; +      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; -        SectionSP symbol_section_sp; -        SymbolType symbol_type = eSymbolTypeInvalid; -        Elf64_Half section_idx = symbol.st_shndx; +      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; -        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; +      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 §_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;          } - -        // 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 §_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;          } - -        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 processer 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; -                } +      } 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;          } - -        // 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 (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; +          }          } - -        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 §_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 && section_it->second->GetFileSize()) -                symbol_section_sp = section_it->second; +      } + +      /* +       * 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 §_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 && section_it->second->GetFileSize()) +        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[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 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; -        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') : false; - -        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 mangled(ConstString(symbol_bare), is_mangled); +  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); -        // 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); +  // 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(); -            llvm::StringRef mangled_name = mangled.GetMangledName().GetStringRef(); -            if (! mangled_name.empty()) -                mangled.SetMangledName( ConstString((mangled_name + suffix).str()) ); +  if (symtab && strtab) { +    assert(symtab->GetObjectFile() == this); +    assert(strtab->GetObjectFile() == this); -            ConstString demangled = mangled.GetDemangledName(lldb::eLanguageTypeUnknown); -            llvm::StringRef demangled_name = demangled.GetStringRef(); -            if (!demangled_name.empty()) -                mangled.SetDemangledName( ConstString((demangled_name + suffix).str()) ); -        } +    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; -        // 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 ParseSymbols(symbol_table, start_id, section_list, num_symbols, +                          symtab_data, strtab_data);      } -    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); -    } +  return 0; +} -    // 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); -        } -    } +size_t ObjectFileELF::ParseDynamicSymbols() { +  if (m_dynamic_symbols.size()) +    return m_dynamic_symbols.size(); +  SectionList *section_list = GetSectionList(); +  if (!section_list)      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); -    // 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; -    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; +    while (cursor < section_size) { +      if (!symbol.Parse(dynsym_data, &cursor)) +        break; -            m_dynamic_symbols.push_back(symbol); -        } +      m_dynamic_symbols.push_back(symbol);      } +  } -    return m_dynamic_symbols.size(); +  return m_dynamic_symbols.size();  } -const ELFDynamic * -ObjectFileELF::FindDynamicSymbol(unsigned tag) -{ -    if (!ParseDynamicSymbols()) -        return NULL; +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; +  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; -    } +    if (symbol->d_tag == tag) +      return symbol; +  } -    return NULL; +  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; +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); -    return 0; +  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 +// 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; -    } +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 -    { -        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; +      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, +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"); +                                      user_id_t rel_id) { +  assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL); -    // 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"); +  // The link field points to the associated symbol table. +  user_id_t symtab_id = rel_hdr->sh_link; -    if (!symtab_id || !plt_id) -        return 0; +  // 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"); -    // Section ID's are ones based; -    symtab_id++; -    plt_id++; +  // 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"); -    const ELFSectionHeaderInfo *plt_hdr = GetSectionHeaderByIndex(plt_id); -    if (!plt_hdr) -        return 0; +  if (!symtab_id || !plt_id) +    return 0; -    const ELFSectionHeaderInfo *sym_hdr = GetSectionHeaderByIndex(symtab_id); -    if (!sym_hdr) -        return 0; +  // Section ID's are ones based; +  symtab_id++; +  plt_id++; -    SectionList *section_list = m_sections_ap.get(); -    if (!section_list) -        return 0; +  const ELFSectionHeaderInfo *plt_hdr = GetSectionHeaderByIndex(plt_id); +  if (!plt_hdr) +    return 0; -    Section *rel_section = section_list->FindSectionByID(rel_id).get(); -    if (!rel_section) -        return 0; +  const ELFSectionHeaderInfo *sym_hdr = GetSectionHeaderByIndex(symtab_id); +  if (!sym_hdr) +    return 0; -    SectionSP plt_section_sp (section_list->FindSectionByID(plt_id)); -    if (!plt_section_sp) -        return 0; +  SectionList *section_list = m_sections_ap.get(); +  if (!section_list) +    return 0; -    Section *symtab = section_list->FindSectionByID(symtab_id).get(); -    if (!symtab) -        return 0; +  Section *rel_section = section_list->FindSectionByID(rel_id).get(); +  if (!rel_section) +    return 0; -    // sh_link points to associated string table. -    Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get(); -    if (!strtab) -        return 0; +  SectionSP plt_section_sp(section_list->FindSectionByID(plt_id)); +  if (!plt_section_sp) +    return 0; -    DataExtractor rel_data; -    if (!ReadSectionData(rel_section, rel_data)) -        return 0; +  Section *symtab = section_list->FindSectionByID(symtab_id).get(); +  if (!symtab) +    return 0; -    DataExtractor symtab_data; -    if (!ReadSectionData(symtab, symtab_data)) -        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 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); -} +  DataExtractor rel_data; +  if (!ReadSectionData(rel_section, rel_data)) +    return 0; -unsigned -ObjectFileELF::RelocateSection(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; -    } +  DataExtractor symtab_data; +  if (!ReadSectionData(symtab, symtab_data)) +    return 0; -    for (unsigned i = 0; i < num_relocations; ++i) -    { -        if (rel.Parse(rel_data, &offset) == false) -            break; +  DataExtractor strtab_data; +  if (!ReadSectionData(strtab, strtab_data)) +    return 0; -        Symbol* symbol = NULL; +  unsigned rel_type = PLTRelocationType(); +  if (!rel_type) +    return 0; -        if (hdr->Is32Bit()) -        { -            switch (reloc_type(rel)) { -            case R_386_32: -            case R_386_PC32: -            default: -                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 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::RelocateSection( +    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: +        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; +  return 0;  } -unsigned -ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr, user_id_t rel_id) -{ -    assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL); +unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr, +                                              user_id_t rel_id) { +  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; +  // 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; +  // 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 *symtab_hdr = GetSectionHeaderByIndex(symtab_id); +  if (!symtab_hdr) +    return 0; -    const ELFSectionHeader *debug_hdr = GetSectionHeaderByIndex(debug_id); -    if (!debug_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 *rel = section_list->FindSectionByID(rel_id).get(); +  if (!rel) +    return 0; -    Section *symtab = section_list->FindSectionByID(symtab_id).get(); -    if (!symtab) -        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; +  Section *debug = section_list->FindSectionByID(debug_id).get(); +  if (!debug) +    return 0; -    DataExtractor rel_data; -    DataExtractor symtab_data; -    DataExtractor debug_data; - -    if (ReadSectionData(rel, rel_data) && -        ReadSectionData(symtab, symtab_data) && -        ReadSectionData(debug, debug_data)) -    { -        RelocateSection(m_symtab_ap.get(), &m_header, rel_hdr, symtab_hdr, debug_hdr, -                        rel_data, symtab_data, debug_data, debug); -    } +  DataExtractor rel_data; +  DataExtractor symtab_data; +  DataExtractor debug_data; -    return 0; +  if (ReadSectionData(rel, rel_data) && ReadSectionData(symtab, symtab_data) && +      ReadSectionData(debug, debug_data)) { +    RelocateSection(m_symtab_ap.get(), &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); -        } +Symtab *ObjectFileELF::GetSymtab() { +  ModuleSP module_sp(GetModule()); +  if (!module_sp) +    return NULL; -        // 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); -            } -        } +  // 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(); -        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 (m_symtab_ap.get() == NULL) { +    SectionList *section_list = module_sp->GetSectionList(); +    if (!section_list) +      return NULL; -        // 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)); +    uint64_t symbol_id = 0; +    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); -        m_symtab_ap->CalculateSymbolSizes(); -    } +    // 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); -    for (SectionHeaderCollIter I = m_section_headers.begin(); -         I != m_section_headers.end(); ++I) -    { -        if (I->sh_type == SHT_RELA || I->sh_type == SHT_REL) -        { -            if (CalculateType() == eTypeObjectFile) -            { -                const char *section_name = I->section_name.AsCString(""); -                if (strstr(section_name, ".rela.debug") || -                    strstr(section_name, ".rel.debug")) -                { -                    const ELFSectionHeader &reloc_header = *I; -                    user_id_t reloc_id = SectionIndex(I); -                    RelocateDebugSections(&reloc_header, reloc_id); -                } -            } +        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(); +  } + +  for (SectionHeaderCollIter I = m_section_headers.begin(); +       I != m_section_headers.end(); ++I) { +    if (I->sh_type == SHT_RELA || I->sh_type == SHT_REL) { +      if (CalculateType() == eTypeObjectFile) { +        const char *section_name = I->section_name.AsCString(""); +        if (strstr(section_name, ".rela.debug") || +            strstr(section_name, ".rel.debug")) { +          const ELFSectionHeader &reloc_header = *I; +          user_id_t reloc_id = SectionIndex(I); +          RelocateDebugSections(&reloc_header, reloc_id);          } +      } +    } +  } +  return m_symtab_ap.get(); +} + +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 m_symtab_ap.get(); -} - -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; -    }); +    return true; +  }); -    for (const Symbol& s : new_symbols) -        symbol_table->AddSymbol(s); +  for (const Symbol &s : new_symbols) +    symbol_table->AddSymbol(s);  } -bool -ObjectFileELF::IsStripped () -{ -    // TODO: determine this for ELF -    return false; +bool ObjectFileELF::IsStripped() { +  // TODO: determine this for ELF +  return false;  }  //===----------------------------------------------------------------------===// @@ -3130,40 +3000,38 @@ ObjectFileELF::IsStripped ()  // 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(); +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();  }  //---------------------------------------------------------------------- @@ -3171,38 +3039,36 @@ ObjectFileELF::Dump(Stream *s)  //  // 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%4.4x\n", header.e_phnum); -    s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize); -    s->Printf("e_shnum     = 0x%4.4x\n", header.e_shnum); -    s->Printf("e_shstrndx  = 0x%4.4x\n", header.e_shstrndx); +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%4.4x\n", header.e_phnum); +  s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize); +  s->Printf("e_shnum     = 0x%4.4x\n", header.e_shnum); +  s->Printf("e_shstrndx  = 0x%4.4x\n", header.e_shstrndx);  }  //---------------------------------------------------------------------- @@ -3210,19 +3076,26 @@ ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header)  //  // 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; -    } +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; +  }  }  //---------------------------------------------------------------------- @@ -3230,34 +3103,38 @@ ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type)  //  // 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; -    } +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); +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_flags(s, ph.p_flags); +  s->Printf(") %8.8" PRIx64, ph.p_align);  }  //---------------------------------------------------------------------- @@ -3266,41 +3143,35 @@ ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph)  // 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); +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; -    } +  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" : "    "); +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" : "    ");  }  //---------------------------------------------------------------------- @@ -3308,26 +3179,23 @@ ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags)  //  // 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(); -    } +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(); +  }  }  //---------------------------------------------------------------------- @@ -3335,16 +3203,16 @@ ObjectFileELF::DumpELFProgramHeaders(Stream *s)  //  // 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); +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);  }  //---------------------------------------------------------------------- @@ -3353,32 +3221,29 @@ ObjectFileELF::DumpELFSectionHeader(Stream *s, const ELFSectionHeaderInfo &sh)  // 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; -    } +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; +  }  }  //---------------------------------------------------------------------- @@ -3386,14 +3251,13 @@ ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type)  //  // 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" : "         "); +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" : "         ");  }  //---------------------------------------------------------------------- @@ -3401,153 +3265,135 @@ ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_xword sh_flags)  //  // 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(); +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 (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()); +  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 = 0, 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;  } -bool -ObjectFileELF::GetArchitecture (ArchSpec &arch) -{ -    if (!ParseHeader()) -        return false; +ObjectFile::Type ObjectFileELF::CalculateType() { +  switch (m_header.e_type) { +  case llvm::ELF::ET_NONE: +    // 0 - No file type +    return eTypeUnknown; -    if (m_section_headers.empty()) -    { -        // Allow elf notes to be parsed which may affect the detected architecture. -        ParseSectionHeaders(); -    } +  case llvm::ELF::ET_REL: +    // 1 - Relocatable file +    return eTypeObjectFile; -    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 = 0, 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; -} +  case llvm::ELF::ET_EXEC: +    // 2 - Executable file +    return eTypeExecutable; -ObjectFile::Type -ObjectFileELF::CalculateType() -{ -    switch (m_header.e_type) -    { -        case llvm::ELF::ET_NONE: -            // 0 - No file type -            return eTypeUnknown; +  case llvm::ELF::ET_DYN: +    // 3 - Shared object file +    return eTypeSharedLibrary; -        case llvm::ELF::ET_REL: -            // 1 - Relocatable file -            return eTypeObjectFile; +  case ET_CORE: +    // 4 - Core file +    return eTypeCoreFile; -        case llvm::ELF::ET_EXEC: -            // 2 - Executable file -            return eTypeExecutable; +  default: +    break; +  } +  return eTypeUnknown; +} -        case llvm::ELF::ET_DYN: -            // 3 - Shared object file -            return eTypeSharedLibrary; +ObjectFile::Strata ObjectFileELF::CalculateStrata() { +  switch (m_header.e_type) { +  case llvm::ELF::ET_NONE: +    // 0 - No file type +    return eStrataUnknown; -        case ET_CORE: -            // 4 - Core file -            return eTypeCoreFile; +  case llvm::ELF::ET_REL: +    // 1 - Relocatable file +    return eStrataUnknown; -        default: -            break; -    } -    return eTypeUnknown; -} +  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; -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; -    } +  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; +} diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h index e2f73f53ec63e..4ce5648cfed55 100644 --- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -19,46 +19,40 @@  // Other libraries and framework includes  // Project includes -#include "lldb/lldb-private.h" +#include "lldb/Core/ArchSpec.h" +#include "lldb/Core/UUID.h"  #include "lldb/Host/FileSpec.h"  #include "lldb/Symbol/ObjectFile.h" -#include "lldb/Core/UUID.h" -#include "lldb/Core/ArchSpec.h" +#include "lldb/lldb-private.h"  #include "ELFHeader.h" -struct ELFNote -{ -    elf::elf_word n_namesz; -    elf::elf_word n_descsz; -    elf::elf_word n_type; - -    std::string n_name; - -    ELFNote() : n_namesz(0), n_descsz(0), n_type(0) -    { -    } - -    /// Parse an ELFNote entry from the given DataExtractor starting at position -    /// \p offset. -    /// -    /// @param[in] data -    ///    The DataExtractor to read from. -    /// -    /// @param[in,out] offset -    ///    Pointer to an offset in the data.  On return the offset will be -    ///    advanced by the number of bytes read. -    /// -    /// @return -    ///    True if the ELFRel entry was successfully read and false otherwise. -    bool -    Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); - -    size_t -    GetByteSize() const -    { -        return 12 + llvm::alignTo (n_namesz, 4) + llvm::alignTo (n_descsz, 4); -    } +struct ELFNote { +  elf::elf_word n_namesz; +  elf::elf_word n_descsz; +  elf::elf_word n_type; + +  std::string n_name; + +  ELFNote() : n_namesz(0), n_descsz(0), n_type(0) {} + +  /// Parse an ELFNote entry from the given DataExtractor starting at position +  /// \p offset. +  /// +  /// @param[in] data +  ///    The DataExtractor to read from. +  /// +  /// @param[in,out] offset +  ///    Pointer to an offset in the data.  On return the offset will be +  ///    advanced by the number of bytes read. +  /// +  /// @return +  ///    True if the ELFRel entry was successfully read and false otherwise. +  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); + +  size_t GetByteSize() const { +    return 12 + llvm::alignTo(n_namesz, 4) + llvm::alignTo(n_descsz, 4); +  }  };  //------------------------------------------------------------------------------ @@ -67,390 +61,332 @@ struct ELFNote  ///  /// This class provides a generic ELF (32/64 bit) reader plugin implementing the  /// ObjectFile protocol. -class ObjectFileELF : -    public lldb_private::ObjectFile -{ +class ObjectFileELF : public lldb_private::ObjectFile {  public: -    ~ObjectFileELF() override; +  ~ObjectFileELF() override; + +  //------------------------------------------------------------------ +  // Static Functions +  //------------------------------------------------------------------ +  static void Initialize(); + +  static void Terminate(); + +  static lldb_private::ConstString GetPluginNameStatic(); + +  static const char *GetPluginDescriptionStatic(); + +  static lldb_private::ObjectFile * +  CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, +                 lldb::offset_t data_offset, const lldb_private::FileSpec *file, +                 lldb::offset_t file_offset, lldb::offset_t length); + +  static lldb_private::ObjectFile *CreateMemoryInstance( +      const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, +      const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); + +  static size_t 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); + +  static bool MagicBytesMatch(lldb::DataBufferSP &data_sp, lldb::addr_t offset, +                              lldb::addr_t length); + +  //------------------------------------------------------------------ +  // PluginInterface protocol +  //------------------------------------------------------------------ +  lldb_private::ConstString GetPluginName() override; + +  uint32_t GetPluginVersion() override; + +  //------------------------------------------------------------------ +  // ObjectFile Protocol. +  //------------------------------------------------------------------ +  bool ParseHeader() override; + +  bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, +                      bool value_is_offset) override; + +  lldb::ByteOrder GetByteOrder() const override; + +  bool IsExecutable() const override; + +  uint32_t GetAddressByteSize() const override; + +  lldb::AddressClass GetAddressClass(lldb::addr_t file_addr) override; + +  lldb_private::Symtab *GetSymtab() override; + +  bool IsStripped() override; + +  void CreateSections(lldb_private::SectionList &unified_section_list) override; + +  void Dump(lldb_private::Stream *s) override; + +  bool GetArchitecture(lldb_private::ArchSpec &arch) override; + +  bool GetUUID(lldb_private::UUID *uuid) override; + +  lldb_private::FileSpecList GetDebugSymbolFilePaths() override; + +  uint32_t GetDependentModules(lldb_private::FileSpecList &files) override; + +  lldb_private::Address +  GetImageInfoAddress(lldb_private::Target *target) override; + +  lldb_private::Address GetEntryPointAddress() override; + +  ObjectFile::Type CalculateType() override; + +  ObjectFile::Strata CalculateStrata() override; + +  // Returns number of program headers found in the ELF file. +  size_t GetProgramHeaderCount(); + +  // Returns the program header with the given index. +  const elf::ELFProgramHeader *GetProgramHeaderByIndex(lldb::user_id_t id); + +  // Returns segment data for the given index. +  lldb_private::DataExtractor GetSegmentDataByIndex(lldb::user_id_t id); -    //------------------------------------------------------------------ -    // Static Functions -    //------------------------------------------------------------------ -    static void -    Initialize(); - -    static void -    Terminate(); - -    static lldb_private::ConstString -    GetPluginNameStatic(); - -    static const char * -    GetPluginDescriptionStatic(); - -    static lldb_private::ObjectFile * -    CreateInstance(const lldb::ModuleSP &module_sp, -                   lldb::DataBufferSP& data_sp, -                   lldb::offset_t data_offset, -                   const lldb_private::FileSpec* file, -                   lldb::offset_t file_offset, -                   lldb::offset_t length); - -    static lldb_private::ObjectFile * -    CreateMemoryInstance (const lldb::ModuleSP &module_sp,  -                          lldb::DataBufferSP& data_sp,  -                          const lldb::ProcessSP &process_sp,  -                          lldb::addr_t header_addr); - -    static size_t -    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); - -    static bool -    MagicBytesMatch (lldb::DataBufferSP& data_sp, -                     lldb::addr_t offset,  -                     lldb::addr_t length); - -    //------------------------------------------------------------------ -    // PluginInterface protocol -    //------------------------------------------------------------------ -    lldb_private::ConstString -    GetPluginName() override; - -    uint32_t -    GetPluginVersion() override; - -    //------------------------------------------------------------------ -    // ObjectFile Protocol. -    //------------------------------------------------------------------ -    bool -    ParseHeader() override; - -    bool -    SetLoadAddress (lldb_private::Target &target, -                    lldb::addr_t value, -                    bool value_is_offset) override; - -    lldb::ByteOrder -    GetByteOrder() const override; - -    bool -    IsExecutable () const override; - -    uint32_t -    GetAddressByteSize() const override; - -    lldb::AddressClass -    GetAddressClass (lldb::addr_t file_addr) override; - -    lldb_private::Symtab * -    GetSymtab() override; - -    bool -    IsStripped () override; - -    void -    CreateSections (lldb_private::SectionList &unified_section_list) override; - -    void -    Dump(lldb_private::Stream *s) override; - -    bool -    GetArchitecture (lldb_private::ArchSpec &arch) override; - -    bool -    GetUUID(lldb_private::UUID* uuid) override; - -    lldb_private::FileSpecList -    GetDebugSymbolFilePaths() override; - -    uint32_t -    GetDependentModules(lldb_private::FileSpecList& files) override; - -    lldb_private::Address -    GetImageInfoAddress(lldb_private::Target *target) override; -     -    lldb_private::Address -    GetEntryPointAddress () override; -     -    ObjectFile::Type -    CalculateType() override; -     -    ObjectFile::Strata -    CalculateStrata() override; - -    // Returns number of program headers found in the ELF file. -    size_t -    GetProgramHeaderCount(); - -    // Returns the program header with the given index. -    const elf::ELFProgramHeader * -    GetProgramHeaderByIndex(lldb::user_id_t id); - -    // Returns segment data for the given index. -    lldb_private::DataExtractor -    GetSegmentDataByIndex(lldb::user_id_t id); - -    std::string -    StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const override; +  std::string +  StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const override;  private: -    ObjectFileELF(const lldb::ModuleSP &module_sp, -                  lldb::DataBufferSP& data_sp, -                  lldb::offset_t data_offset, -                  const lldb_private::FileSpec* file, -                  lldb::offset_t offset, -                  lldb::offset_t length); - -    ObjectFileELF (const lldb::ModuleSP &module_sp, -                   lldb::DataBufferSP& header_data_sp, -                   const lldb::ProcessSP &process_sp, -                   lldb::addr_t header_addr); - -    typedef std::vector<elf::ELFProgramHeader>  ProgramHeaderColl; -    typedef ProgramHeaderColl::iterator         ProgramHeaderCollIter; -    typedef ProgramHeaderColl::const_iterator   ProgramHeaderCollConstIter; - -    struct ELFSectionHeaderInfo : public elf::ELFSectionHeader -    { -        lldb_private::ConstString section_name; -    }; - -    typedef std::vector<ELFSectionHeaderInfo>   SectionHeaderColl; -    typedef SectionHeaderColl::iterator         SectionHeaderCollIter; -    typedef SectionHeaderColl::const_iterator   SectionHeaderCollConstIter; - -    typedef std::vector<elf::ELFDynamic>        DynamicSymbolColl; -    typedef DynamicSymbolColl::iterator         DynamicSymbolCollIter; -    typedef DynamicSymbolColl::const_iterator   DynamicSymbolCollConstIter; - -    typedef std::map<lldb::addr_t, lldb::AddressClass> FileAddressToAddressClassMap; -    typedef std::function<lldb::offset_t (lldb_private::DataExtractor &, lldb::offset_t, lldb::offset_t)> SetDataFunction; - -    /// Version of this reader common to all plugins based on this class. -    static const uint32_t m_plugin_version = 1; -    static const uint32_t g_core_uuid_magic; - -    /// ELF file header. -    elf::ELFHeader m_header; - -    /// ELF build ID. -    lldb_private::UUID m_uuid; - -    /// ELF .gnu_debuglink file and crc data if available. -    std::string m_gnu_debuglink_file; -    uint32_t m_gnu_debuglink_crc; - -    /// Collection of program headers. -    ProgramHeaderColl m_program_headers; - -    /// Collection of section headers. -    SectionHeaderColl m_section_headers; - -    /// Collection of symbols from the dynamic table. -    DynamicSymbolColl m_dynamic_symbols; - -    /// List of file specifications corresponding to the modules (shared -    /// libraries) on which this object file depends. -    mutable std::unique_ptr<lldb_private::FileSpecList> m_filespec_ap; - -    /// Cached value of the entry point for this module. -    lldb_private::Address  m_entry_point_address; - -    /// The architecture detected from parsing elf file contents. -    lldb_private::ArchSpec m_arch_spec; - -    /// The address class for each symbol in the elf file -    FileAddressToAddressClassMap m_address_class_map; - -    /// Returns a 1 based index of the given section header. -    size_t -    SectionIndex(const SectionHeaderCollIter &I); - -    /// Returns a 1 based index of the given section header. -    size_t -    SectionIndex(const SectionHeaderCollConstIter &I) const; - -    // Parses the ELF program headers. -    static size_t -    GetProgramHeaderInfo(ProgramHeaderColl &program_headers, -                         const SetDataFunction &set_data, -                         const elf::ELFHeader &header); - -    // Finds PT_NOTE segments and calculates their crc sum. -    static uint32_t -    CalculateELFNotesSegmentsCRC32(const ProgramHeaderColl& program_headers, -                                   lldb_private::DataExtractor &data); - -    /// Parses all section headers present in this object file and populates -    /// m_program_headers.  This method will compute the header list only once. -    /// Returns the number of headers parsed. -    size_t -    ParseProgramHeaders(); - -    /// Parses all section headers present in this object file and populates -    /// m_section_headers.  This method will compute the header list only once. -    /// Returns the number of headers parsed. -    size_t -    ParseSectionHeaders(); - -    static void -    ParseARMAttributes(lldb_private::DataExtractor &data, uint64_t length, -                       lldb_private::ArchSpec &arch_spec); - -    /// Parses the elf section headers and returns the uuid, debug link name, crc, archspec. -    static size_t -    GetSectionHeaderInfo(SectionHeaderColl §ion_headers, -                         const SetDataFunction &set_data, -                         const elf::ELFHeader &header, -                         lldb_private::UUID &uuid, -                         std::string &gnu_debuglink_file, -                         uint32_t &gnu_debuglink_crc, -                         lldb_private::ArchSpec &arch_spec); - -    /// Scans the dynamic section and locates all dependent modules (shared -    /// libraries) populating m_filespec_ap.  This method will compute the -    /// dependent module list only once.  Returns the number of dependent -    /// modules parsed. -    size_t -    ParseDependentModules(); - -    /// Parses the dynamic symbol table and populates m_dynamic_symbols.  The -    /// vector retains the order as found in the object file.  Returns the -    /// number of dynamic symbols parsed. -    size_t -    ParseDynamicSymbols(); - -    /// Populates m_symtab_ap will all non-dynamic linker symbols.  This method -    /// will parse the symbols only once.  Returns the number of symbols parsed. -    unsigned -    ParseSymbolTable(lldb_private::Symtab *symbol_table, -                     lldb::user_id_t start_id, -                     lldb_private::Section *symtab); - -    /// Helper routine for ParseSymbolTable(). -    unsigned -    ParseSymbols(lldb_private::Symtab *symbol_table,  -                 lldb::user_id_t start_id, -                 lldb_private::SectionList *section_list, -                 const size_t num_symbols, -                 const lldb_private::DataExtractor &symtab_data, -                 const lldb_private::DataExtractor &strtab_data); - -    /// Scans the relocation entries and adds a set of artificial symbols to the -    /// given symbol table for each PLT slot.  Returns the number of symbols -    /// added. -    unsigned -    ParseTrampolineSymbols(lldb_private::Symtab *symbol_table,  -                           lldb::user_id_t start_id, -                           const ELFSectionHeaderInfo *rela_hdr, -                           lldb::user_id_t section_id); - -    void -    ParseUnwindSymbols(lldb_private::Symtab *symbol_table, -                       lldb_private::DWARFCallFrameInfo* eh_frame); - -    /// Relocates debug sections -    unsigned -    RelocateDebugSections(const elf::ELFSectionHeader *rel_hdr, lldb::user_id_t rel_id); - -    unsigned -    RelocateSection(lldb_private::Symtab* symtab, const elf::ELFHeader *hdr, const elf::ELFSectionHeader *rel_hdr, -                    const elf::ELFSectionHeader *symtab_hdr, const elf::ELFSectionHeader *debug_hdr, -                    lldb_private::DataExtractor &rel_data, lldb_private::DataExtractor &symtab_data, -                    lldb_private::DataExtractor &debug_data, lldb_private::Section* rel_section); - -    /// Loads the section name string table into m_shstr_data.  Returns the -    /// number of bytes constituting the table. -    size_t -    GetSectionHeaderStringTable(); - -    /// Utility method for looking up a section given its name.  Returns the -    /// index of the corresponding section or zero if no section with the given -    /// name can be found (note that section indices are always 1 based, and so -    /// section index 0 is never valid). -    lldb::user_id_t -    GetSectionIndexByName(const char *name); - -    // Returns the ID of the first section that has the given type. -    lldb::user_id_t -    GetSectionIndexByType(unsigned type); - -    /// Returns the section header with the given id or NULL. -    const ELFSectionHeaderInfo * -    GetSectionHeaderByIndex(lldb::user_id_t id); - -    /// @name  ELF header dump routines -    //@{ -    static void -    DumpELFHeader(lldb_private::Stream *s, const elf::ELFHeader& header); - -    static void -    DumpELFHeader_e_ident_EI_DATA(lldb_private::Stream *s, -                                  unsigned char ei_data); - -    static void -    DumpELFHeader_e_type(lldb_private::Stream *s, elf::elf_half e_type); -    //@} - -    /// @name ELF program header dump routines -    //@{ -    void -    DumpELFProgramHeaders(lldb_private::Stream *s); - -    static void -    DumpELFProgramHeader(lldb_private::Stream *s,  -                         const elf::ELFProgramHeader &ph); - -    static void -    DumpELFProgramHeader_p_type(lldb_private::Stream *s, elf::elf_word p_type); - -    static void -    DumpELFProgramHeader_p_flags(lldb_private::Stream *s,  -                                 elf::elf_word p_flags); -    //@} - -    /// @name ELF section header dump routines -    //@{ -    void -    DumpELFSectionHeaders(lldb_private::Stream *s); - -    static void -    DumpELFSectionHeader(lldb_private::Stream *s,  -                         const ELFSectionHeaderInfo& sh); - -    static void -    DumpELFSectionHeader_sh_type(lldb_private::Stream *s,  -                                 elf::elf_word sh_type); - -    static void -    DumpELFSectionHeader_sh_flags(lldb_private::Stream *s,  -                                  elf::elf_xword sh_flags); -    //@} - -    /// ELF dependent module dump routine. -    void -    DumpDependentModules(lldb_private::Stream *s); - -    const elf::ELFDynamic * -    FindDynamicSymbol(unsigned tag); -         -    unsigned -    PLTRelocationType(); - -    static lldb_private::Error -    RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch_spec, lldb_private::UUID &uuid); - - -    static lldb::offset_t -    SetData(const lldb_private::DataExtractor &src, lldb_private::DataExtractor &dst, lldb::offset_t offset, lldb::offset_t length); - -    lldb::offset_t -    SetDataWithReadMemoryFallback(lldb_private::DataExtractor &dst, lldb::offset_t offset, lldb::offset_t length); +  ObjectFileELF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, +                lldb::offset_t data_offset, const lldb_private::FileSpec *file, +                lldb::offset_t offset, lldb::offset_t length); + +  ObjectFileELF(const lldb::ModuleSP &module_sp, +                lldb::DataBufferSP &header_data_sp, +                const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); + +  typedef std::vector<elf::ELFProgramHeader> ProgramHeaderColl; +  typedef ProgramHeaderColl::iterator ProgramHeaderCollIter; +  typedef ProgramHeaderColl::const_iterator ProgramHeaderCollConstIter; + +  struct ELFSectionHeaderInfo : public elf::ELFSectionHeader { +    lldb_private::ConstString section_name; +  }; + +  typedef std::vector<ELFSectionHeaderInfo> SectionHeaderColl; +  typedef SectionHeaderColl::iterator SectionHeaderCollIter; +  typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter; + +  typedef std::vector<elf::ELFDynamic> DynamicSymbolColl; +  typedef DynamicSymbolColl::iterator DynamicSymbolCollIter; +  typedef DynamicSymbolColl::const_iterator DynamicSymbolCollConstIter; + +  typedef std::map<lldb::addr_t, lldb::AddressClass> +      FileAddressToAddressClassMap; +  typedef std::function<lldb::offset_t(lldb_private::DataExtractor &, +                                       lldb::offset_t, lldb::offset_t)> +      SetDataFunction; + +  /// Version of this reader common to all plugins based on this class. +  static const uint32_t m_plugin_version = 1; +  static const uint32_t g_core_uuid_magic; + +  /// ELF file header. +  elf::ELFHeader m_header; + +  /// ELF build ID. +  lldb_private::UUID m_uuid; + +  /// ELF .gnu_debuglink file and crc data if available. +  std::string m_gnu_debuglink_file; +  uint32_t m_gnu_debuglink_crc; + +  /// Collection of program headers. +  ProgramHeaderColl m_program_headers; + +  /// Collection of section headers. +  SectionHeaderColl m_section_headers; + +  /// Collection of symbols from the dynamic table. +  DynamicSymbolColl m_dynamic_symbols; + +  /// List of file specifications corresponding to the modules (shared +  /// libraries) on which this object file depends. +  mutable std::unique_ptr<lldb_private::FileSpecList> m_filespec_ap; + +  /// Cached value of the entry point for this module. +  lldb_private::Address m_entry_point_address; + +  /// The architecture detected from parsing elf file contents. +  lldb_private::ArchSpec m_arch_spec; + +  /// The address class for each symbol in the elf file +  FileAddressToAddressClassMap m_address_class_map; + +  /// Returns a 1 based index of the given section header. +  size_t SectionIndex(const SectionHeaderCollIter &I); + +  /// Returns a 1 based index of the given section header. +  size_t SectionIndex(const SectionHeaderCollConstIter &I) const; + +  // Parses the ELF program headers. +  static size_t GetProgramHeaderInfo(ProgramHeaderColl &program_headers, +                                     const SetDataFunction &set_data, +                                     const elf::ELFHeader &header); + +  // Finds PT_NOTE segments and calculates their crc sum. +  static uint32_t +  CalculateELFNotesSegmentsCRC32(const ProgramHeaderColl &program_headers, +                                 lldb_private::DataExtractor &data); + +  /// Parses all section headers present in this object file and populates +  /// m_program_headers.  This method will compute the header list only once. +  /// Returns the number of headers parsed. +  size_t ParseProgramHeaders(); + +  /// Parses all section headers present in this object file and populates +  /// m_section_headers.  This method will compute the header list only once. +  /// Returns the number of headers parsed. +  size_t ParseSectionHeaders(); + +  static void ParseARMAttributes(lldb_private::DataExtractor &data, +                                 uint64_t length, +                                 lldb_private::ArchSpec &arch_spec); + +  /// Parses the elf section headers and returns the uuid, debug link name, crc, +  /// archspec. +  static size_t GetSectionHeaderInfo(SectionHeaderColl §ion_headers, +                                     const SetDataFunction &set_data, +                                     const elf::ELFHeader &header, +                                     lldb_private::UUID &uuid, +                                     std::string &gnu_debuglink_file, +                                     uint32_t &gnu_debuglink_crc, +                                     lldb_private::ArchSpec &arch_spec); + +  /// Scans the dynamic section and locates all dependent modules (shared +  /// libraries) populating m_filespec_ap.  This method will compute the +  /// dependent module list only once.  Returns the number of dependent +  /// modules parsed. +  size_t ParseDependentModules(); + +  /// Parses the dynamic symbol table and populates m_dynamic_symbols.  The +  /// vector retains the order as found in the object file.  Returns the +  /// number of dynamic symbols parsed. +  size_t ParseDynamicSymbols(); + +  /// Populates m_symtab_ap will all non-dynamic linker symbols.  This method +  /// will parse the symbols only once.  Returns the number of symbols parsed. +  unsigned ParseSymbolTable(lldb_private::Symtab *symbol_table, +                            lldb::user_id_t start_id, +                            lldb_private::Section *symtab); + +  /// Helper routine for ParseSymbolTable(). +  unsigned ParseSymbols(lldb_private::Symtab *symbol_table, +                        lldb::user_id_t start_id, +                        lldb_private::SectionList *section_list, +                        const size_t num_symbols, +                        const lldb_private::DataExtractor &symtab_data, +                        const lldb_private::DataExtractor &strtab_data); + +  /// Scans the relocation entries and adds a set of artificial symbols to the +  /// given symbol table for each PLT slot.  Returns the number of symbols +  /// added. +  unsigned ParseTrampolineSymbols(lldb_private::Symtab *symbol_table, +                                  lldb::user_id_t start_id, +                                  const ELFSectionHeaderInfo *rela_hdr, +                                  lldb::user_id_t section_id); + +  void ParseUnwindSymbols(lldb_private::Symtab *symbol_table, +                          lldb_private::DWARFCallFrameInfo *eh_frame); + +  /// Relocates debug sections +  unsigned RelocateDebugSections(const elf::ELFSectionHeader *rel_hdr, +                                 lldb::user_id_t rel_id); + +  unsigned RelocateSection(lldb_private::Symtab *symtab, +                           const elf::ELFHeader *hdr, +                           const elf::ELFSectionHeader *rel_hdr, +                           const elf::ELFSectionHeader *symtab_hdr, +                           const elf::ELFSectionHeader *debug_hdr, +                           lldb_private::DataExtractor &rel_data, +                           lldb_private::DataExtractor &symtab_data, +                           lldb_private::DataExtractor &debug_data, +                           lldb_private::Section *rel_section); + +  /// Loads the section name string table into m_shstr_data.  Returns the +  /// number of bytes constituting the table. +  size_t GetSectionHeaderStringTable(); + +  /// Utility method for looking up a section given its name.  Returns the +  /// index of the corresponding section or zero if no section with the given +  /// name can be found (note that section indices are always 1 based, and so +  /// section index 0 is never valid). +  lldb::user_id_t GetSectionIndexByName(const char *name); + +  // Returns the ID of the first section that has the given type. +  lldb::user_id_t GetSectionIndexByType(unsigned type); + +  /// Returns the section header with the given id or NULL. +  const ELFSectionHeaderInfo *GetSectionHeaderByIndex(lldb::user_id_t id); + +  /// @name  ELF header dump routines +  //@{ +  static void DumpELFHeader(lldb_private::Stream *s, +                            const elf::ELFHeader &header); + +  static void DumpELFHeader_e_ident_EI_DATA(lldb_private::Stream *s, +                                            unsigned char ei_data); + +  static void DumpELFHeader_e_type(lldb_private::Stream *s, +                                   elf::elf_half e_type); +  //@} + +  /// @name ELF program header dump routines +  //@{ +  void DumpELFProgramHeaders(lldb_private::Stream *s); + +  static void DumpELFProgramHeader(lldb_private::Stream *s, +                                   const elf::ELFProgramHeader &ph); + +  static void DumpELFProgramHeader_p_type(lldb_private::Stream *s, +                                          elf::elf_word p_type); + +  static void DumpELFProgramHeader_p_flags(lldb_private::Stream *s, +                                           elf::elf_word p_flags); +  //@} + +  /// @name ELF section header dump routines +  //@{ +  void DumpELFSectionHeaders(lldb_private::Stream *s); + +  static void DumpELFSectionHeader(lldb_private::Stream *s, +                                   const ELFSectionHeaderInfo &sh); + +  static void DumpELFSectionHeader_sh_type(lldb_private::Stream *s, +                                           elf::elf_word sh_type); + +  static void DumpELFSectionHeader_sh_flags(lldb_private::Stream *s, +                                            elf::elf_xword sh_flags); +  //@} + +  /// ELF dependent module dump routine. +  void DumpDependentModules(lldb_private::Stream *s); + +  const elf::ELFDynamic *FindDynamicSymbol(unsigned tag); + +  unsigned PLTRelocationType(); + +  static lldb_private::Error +  RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, +                              lldb_private::ArchSpec &arch_spec, +                              lldb_private::UUID &uuid); + +  static lldb::offset_t SetData(const lldb_private::DataExtractor &src, +                                lldb_private::DataExtractor &dst, +                                lldb::offset_t offset, lldb::offset_t length); + +  lldb::offset_t SetDataWithReadMemoryFallback(lldb_private::DataExtractor &dst, +                                               lldb::offset_t offset, +                                               lldb::offset_t length);  };  #endif // liblldb_ObjectFileELF_h_ diff --git a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp index e3d8383337119..b5b5e38e1f6f3 100644 --- a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp +++ b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp @@ -26,8 +26,8 @@  #include "lldb/Core/StreamString.h"  #include "lldb/Core/Timer.h"  #include "lldb/Core/UUID.h" -#include "lldb/Host/Host.h"  #include "lldb/Host/FileSpec.h" +#include "lldb/Host/Host.h"  #include "lldb/Symbol/ObjectFile.h"  #include "lldb/Target/Platform.h"  #include "lldb/Target/Process.h" @@ -41,322 +41,227 @@  using namespace lldb;  using namespace lldb_private; - -void -ObjectFileJIT::Initialize() -{ -    PluginManager::RegisterPlugin (GetPluginNameStatic(), -                                   GetPluginDescriptionStatic(), -                                   CreateInstance, -                                   CreateMemoryInstance, -                                   GetModuleSpecifications); +void ObjectFileJIT::Initialize() { +  PluginManager::RegisterPlugin(GetPluginNameStatic(), +                                GetPluginDescriptionStatic(), CreateInstance, +                                CreateMemoryInstance, GetModuleSpecifications);  } -void -ObjectFileJIT::Terminate() -{ -    PluginManager::UnregisterPlugin (CreateInstance); -} - - -lldb_private::ConstString -ObjectFileJIT::GetPluginNameStatic() -{ -    static ConstString g_name("jit"); -    return g_name; +void ObjectFileJIT::Terminate() { +  PluginManager::UnregisterPlugin(CreateInstance);  } -const char * -ObjectFileJIT::GetPluginDescriptionStatic() -{ -    return "JIT code object file"; +lldb_private::ConstString ObjectFileJIT::GetPluginNameStatic() { +  static ConstString g_name("jit"); +  return g_name;  } -ObjectFile * -ObjectFileJIT::CreateInstance (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) -{ -    // JIT'ed object file is backed by the ObjectFileJITDelegate, never -    // read from a file -    return NULL; +const char *ObjectFileJIT::GetPluginDescriptionStatic() { +  return "JIT code object file";  } -ObjectFile * -ObjectFileJIT::CreateMemoryInstance (const lldb::ModuleSP &module_sp, -                                     DataBufferSP& data_sp, -                                     const ProcessSP &process_sp, -                                     lldb::addr_t header_addr) -{ -    // JIT'ed object file is backed by the ObjectFileJITDelegate, never -    // read from memory -    return NULL; +ObjectFile *ObjectFileJIT::CreateInstance(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) { +  // JIT'ed object file is backed by the ObjectFileJITDelegate, never +  // read from a file +  return NULL;  } -size_t -ObjectFileJIT::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) -{ -    // JIT'ed object file can't be read from a file on disk -    return 0; +ObjectFile *ObjectFileJIT::CreateMemoryInstance(const lldb::ModuleSP &module_sp, +                                                DataBufferSP &data_sp, +                                                const ProcessSP &process_sp, +                                                lldb::addr_t header_addr) { +  // JIT'ed object file is backed by the ObjectFileJITDelegate, never +  // read from memory +  return NULL;  } -ObjectFileJIT::ObjectFileJIT (const lldb::ModuleSP &module_sp, -                              const ObjectFileJITDelegateSP &delegate_sp) : -    ObjectFile(module_sp, NULL, 0, 0, DataBufferSP(), 0), -    m_delegate_wp () -{ -    if (delegate_sp) -    { -        m_delegate_wp = delegate_sp; -        m_data.SetByteOrder(delegate_sp->GetByteOrder()); -        m_data.SetAddressByteSize(delegate_sp->GetAddressByteSize()); -    } +size_t ObjectFileJIT::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) { +  // JIT'ed object file can't be read from a file on disk +  return 0;  } -ObjectFileJIT::~ObjectFileJIT() -{ +ObjectFileJIT::ObjectFileJIT(const lldb::ModuleSP &module_sp, +                             const ObjectFileJITDelegateSP &delegate_sp) +    : ObjectFile(module_sp, NULL, 0, 0, DataBufferSP(), 0), m_delegate_wp() { +  if (delegate_sp) { +    m_delegate_wp = delegate_sp; +    m_data.SetByteOrder(delegate_sp->GetByteOrder()); +    m_data.SetAddressByteSize(delegate_sp->GetAddressByteSize()); +  }  } +ObjectFileJIT::~ObjectFileJIT() {} -bool -ObjectFileJIT::ParseHeader () -{ -    // JIT code is never in a file, nor is it required to have any header -    return false; +bool ObjectFileJIT::ParseHeader() { +  // JIT code is never in a file, nor is it required to have any header +  return false;  } -ByteOrder -ObjectFileJIT::GetByteOrder () const -{ -    return m_data.GetByteOrder(); -} +ByteOrder ObjectFileJIT::GetByteOrder() const { return m_data.GetByteOrder(); } -bool -ObjectFileJIT::IsExecutable() const -{ -    return false; -} +bool ObjectFileJIT::IsExecutable() const { return false; } -uint32_t -ObjectFileJIT::GetAddressByteSize () const -{ -    return m_data.GetAddressByteSize(); +uint32_t ObjectFileJIT::GetAddressByteSize() const { +  return m_data.GetAddressByteSize();  } - -Symtab * -ObjectFileJIT::GetSymtab() -{ -    ModuleSP module_sp(GetModule()); -    if (module_sp) -    { -        std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); -        if (m_symtab_ap.get() == NULL) -        { -            m_symtab_ap.reset(new Symtab(this)); -            std::lock_guard<std::recursive_mutex> symtab_guard(m_symtab_ap->GetMutex()); -            ObjectFileJITDelegateSP delegate_sp (m_delegate_wp.lock()); -            if (delegate_sp) -                delegate_sp->PopulateSymtab(this, *m_symtab_ap); -            // TODO: get symbols from delegate -            m_symtab_ap->Finalize (); -        } +Symtab *ObjectFileJIT::GetSymtab() { +  ModuleSP module_sp(GetModule()); +  if (module_sp) { +    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); +    if (m_symtab_ap.get() == NULL) { +      m_symtab_ap.reset(new Symtab(this)); +      std::lock_guard<std::recursive_mutex> symtab_guard( +          m_symtab_ap->GetMutex()); +      ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock()); +      if (delegate_sp) +        delegate_sp->PopulateSymtab(this, *m_symtab_ap); +      // TODO: get symbols from delegate +      m_symtab_ap->Finalize();      } -    return m_symtab_ap.get(); +  } +  return m_symtab_ap.get();  } -bool -ObjectFileJIT::IsStripped () -{ -    return false; // JIT code that is in a module is never stripped +bool ObjectFileJIT::IsStripped() { +  return false; // JIT code that is in a module is never stripped  } -void -ObjectFileJIT::CreateSections (SectionList &unified_section_list) -{ -    if (!m_sections_ap.get()) -    { -        m_sections_ap.reset(new SectionList()); -        ObjectFileJITDelegateSP delegate_sp (m_delegate_wp.lock()); -        if (delegate_sp) -        { -            delegate_sp->PopulateSectionList(this, *m_sections_ap); -            unified_section_list = *m_sections_ap; -        } +void ObjectFileJIT::CreateSections(SectionList &unified_section_list) { +  if (!m_sections_ap.get()) { +    m_sections_ap.reset(new SectionList()); +    ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock()); +    if (delegate_sp) { +      delegate_sp->PopulateSectionList(this, *m_sections_ap); +      unified_section_list = *m_sections_ap;      } +  }  } -void -ObjectFileJIT::Dump (Stream *s) -{ -    ModuleSP module_sp(GetModule()); -    if (module_sp) -    { -        std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); -        s->Printf("%p: ", static_cast<void*>(this)); -        s->Indent(); -        s->PutCString("ObjectFileJIT"); - -        ArchSpec arch; -        if (GetArchitecture(arch)) -            *s << ", arch = " << arch.GetArchitectureName(); - -        s->EOL(); - -        SectionList *sections = GetSectionList(); -        if (sections) -            sections->Dump(s, NULL, true, UINT32_MAX); - -        if (m_symtab_ap.get()) -            m_symtab_ap->Dump(s, NULL, eSortOrderNone); -    } -} +void ObjectFileJIT::Dump(Stream *s) { +  ModuleSP module_sp(GetModule()); +  if (module_sp) { +    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); +    s->Printf("%p: ", static_cast<void *>(this)); +    s->Indent(); +    s->PutCString("ObjectFileJIT"); -bool -ObjectFileJIT::GetUUID (lldb_private::UUID* uuid) -{ -    // TODO: maybe get from delegate, not needed for first pass -    return false; -} +    ArchSpec arch; +    if (GetArchitecture(arch)) +      *s << ", arch = " << arch.GetArchitectureName(); +    s->EOL(); -uint32_t -ObjectFileJIT::GetDependentModules (FileSpecList& files) -{ -    // JIT modules don't have dependencies, but they could -    // if external functions are called and we know where they are -    files.Clear(); -    return 0; -} +    SectionList *sections = GetSectionList(); +    if (sections) +      sections->Dump(s, NULL, true, UINT32_MAX); -lldb_private::Address -ObjectFileJIT::GetEntryPointAddress () -{ -    return Address(); +    if (m_symtab_ap.get()) +      m_symtab_ap->Dump(s, NULL, eSortOrderNone); +  }  } -lldb_private::Address -ObjectFileJIT::GetHeaderAddress () -{ -    return Address(); +bool ObjectFileJIT::GetUUID(lldb_private::UUID *uuid) { +  // TODO: maybe get from delegate, not needed for first pass +  return false;  } - - -ObjectFile::Type -ObjectFileJIT::CalculateType() -{ -    return eTypeJIT; +uint32_t ObjectFileJIT::GetDependentModules(FileSpecList &files) { +  // JIT modules don't have dependencies, but they could +  // if external functions are called and we know where they are +  files.Clear(); +  return 0;  } -ObjectFile::Strata -ObjectFileJIT::CalculateStrata() -{ -    return eStrataJIT; +lldb_private::Address ObjectFileJIT::GetEntryPointAddress() { +  return Address();  } +lldb_private::Address ObjectFileJIT::GetHeaderAddress() { return Address(); } + +ObjectFile::Type ObjectFileJIT::CalculateType() { return eTypeJIT; } + +ObjectFile::Strata ObjectFileJIT::CalculateStrata() { return eStrataJIT; } -bool -ObjectFileJIT::GetArchitecture (ArchSpec &arch) -{ -    ObjectFileJITDelegateSP delegate_sp (m_delegate_wp.lock()); -    if (delegate_sp) -        return delegate_sp->GetArchitecture(arch); -    return false; +bool ObjectFileJIT::GetArchitecture(ArchSpec &arch) { +  ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock()); +  if (delegate_sp) +    return delegate_sp->GetArchitecture(arch); +  return false;  }  //------------------------------------------------------------------  // PluginInterface protocol  //------------------------------------------------------------------ -lldb_private::ConstString -ObjectFileJIT::GetPluginName() -{ -    return GetPluginNameStatic(); +lldb_private::ConstString ObjectFileJIT::GetPluginName() { +  return GetPluginNameStatic();  } -uint32_t -ObjectFileJIT::GetPluginVersion() -{ -    return 1; -} - - -bool -ObjectFileJIT::SetLoadAddress (Target &target, -                               lldb::addr_t value, -                               bool value_is_offset) -{ -    size_t num_loaded_sections = 0; -    SectionList *section_list = GetSectionList (); -    if (section_list) -    { -        const size_t num_sections = section_list->GetSize(); -        // "value" is an offset to apply to each top level segment -        for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) -        { -            // Iterate through the object file sections to find all -            // of the sections that size on disk (to avoid __PAGEZERO) -            // and load them -            SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx)); -            if (section_sp && -                section_sp->GetFileSize() > 0 && -                section_sp->IsThreadSpecific() == false) -            { -                if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + value)) -                    ++num_loaded_sections; -            } -        } +uint32_t ObjectFileJIT::GetPluginVersion() { return 1; } + +bool ObjectFileJIT::SetLoadAddress(Target &target, lldb::addr_t value, +                                   bool value_is_offset) { +  size_t num_loaded_sections = 0; +  SectionList *section_list = GetSectionList(); +  if (section_list) { +    const size_t num_sections = section_list->GetSize(); +    // "value" is an offset to apply to each top level segment +    for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) { +      // Iterate through the object file sections to find all +      // of the sections that size on disk (to avoid __PAGEZERO) +      // and load them +      SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx)); +      if (section_sp && section_sp->GetFileSize() > 0 && +          section_sp->IsThreadSpecific() == false) { +        if (target.GetSectionLoadList().SetSectionLoadAddress( +                section_sp, section_sp->GetFileAddress() + value)) +          ++num_loaded_sections; +      }      } -    return num_loaded_sections > 0; +  } +  return num_loaded_sections > 0;  } -     -size_t -ObjectFileJIT::ReadSectionData (const lldb_private::Section *section, -                                lldb::offset_t section_offset, -                                void *dst, -                                size_t dst_len) const -{ -    lldb::offset_t file_size = section->GetFileSize(); -    if (section_offset < file_size) -    { -        size_t src_len = file_size - section_offset; -        if (src_len > dst_len) -            src_len = dst_len; -        const uint8_t *src = ((uint8_t *)(uintptr_t)section->GetFileOffset()) + section_offset; -         -        memcpy (dst, src, src_len); -        return src_len; -    } -    return 0; +size_t ObjectFileJIT::ReadSectionData(const lldb_private::Section *section, +                                      lldb::offset_t section_offset, void *dst, +                                      size_t dst_len) const { +  lldb::offset_t file_size = section->GetFileSize(); +  if (section_offset < file_size) { +    size_t src_len = file_size - section_offset; +    if (src_len > dst_len) +      src_len = dst_len; +    const uint8_t *src = +        ((uint8_t *)(uintptr_t)section->GetFileOffset()) + section_offset; + +    memcpy(dst, src, src_len); +    return src_len; +  } +  return 0;  } -size_t -ObjectFileJIT::ReadSectionData (const lldb_private::Section *section, -                                lldb_private::DataExtractor& section_data) const -{ -    if (section->GetFileSize()) -    { -        const void *src = (void *)(uintptr_t)section->GetFileOffset(); -     -        DataBufferSP data_sp (new lldb_private::DataBufferHeap(src, section->GetFileSize())); -        if (data_sp) -        { -            section_data.SetData (data_sp, 0, data_sp->GetByteSize()); -            section_data.SetByteOrder (GetByteOrder()); -            section_data.SetAddressByteSize (GetAddressByteSize()); -            return section_data.GetByteSize(); -        } +size_t ObjectFileJIT::ReadSectionData( +    const lldb_private::Section *section, +    lldb_private::DataExtractor §ion_data) const { +  if (section->GetFileSize()) { +    const void *src = (void *)(uintptr_t)section->GetFileOffset(); + +    DataBufferSP data_sp( +        new lldb_private::DataBufferHeap(src, section->GetFileSize())); +    if (data_sp) { +      section_data.SetData(data_sp, 0, data_sp->GetByteSize()); +      section_data.SetByteOrder(GetByteOrder()); +      section_data.SetAddressByteSize(GetAddressByteSize()); +      return section_data.GetByteSize();      } -    section_data.Clear(); -    return 0; +  } +  section_data.Clear(); +  return 0;  } - diff --git a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h index 39dbb3fb047b4..a211645d5d8b3 100644 --- a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h +++ b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h @@ -21,126 +21,93 @@  // This class needs to be hidden as eventually belongs in a plugin that  // will export the ObjectFile protocol  //---------------------------------------------------------------------- -class ObjectFileJIT : -    public lldb_private::ObjectFile -{ +class ObjectFileJIT : public lldb_private::ObjectFile {  public: -    ObjectFileJIT(const lldb::ModuleSP &module_sp, -                  const lldb::ObjectFileJITDelegateSP &delegate_sp); - -    ~ObjectFileJIT() override; - -    //------------------------------------------------------------------ -    // Static Functions -    //------------------------------------------------------------------ -    static void -    Initialize(); - -    static void -    Terminate(); - -    static lldb_private::ConstString -    GetPluginNameStatic(); - -    static const char * -    GetPluginDescriptionStatic(); - -    static lldb_private::ObjectFile * -    CreateInstance (const lldb::ModuleSP &module_sp, -                    lldb::DataBufferSP& data_sp, -                    lldb::offset_t data_offset, -                    const lldb_private::FileSpec* file, -                    lldb::offset_t file_offset, -                    lldb::offset_t length); - -    static lldb_private::ObjectFile * -    CreateMemoryInstance (const lldb::ModuleSP &module_sp,  -                          lldb::DataBufferSP& data_sp,  -                          const lldb::ProcessSP &process_sp,  -                          lldb::addr_t header_addr); - -    static size_t -    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); -     -    //------------------------------------------------------------------ -    // Member Functions -    //------------------------------------------------------------------ -    bool -    ParseHeader() override; - -    bool -    SetLoadAddress(lldb_private::Target &target, -                   lldb::addr_t value, -                   bool value_is_offset) override; -     -    lldb::ByteOrder -    GetByteOrder() const override; -     -    bool -    IsExecutable() const override; - -    uint32_t -    GetAddressByteSize() const override; - -    lldb_private::Symtab * -    GetSymtab() override; - -    bool -    IsStripped() override; -     -    void -    CreateSections(lldb_private::SectionList &unified_section_list) override; - -    void -    Dump(lldb_private::Stream *s) override; - -    bool -    GetArchitecture(lldb_private::ArchSpec &arch) override; - -    bool -    GetUUID(lldb_private::UUID* uuid) override; - -    uint32_t -    GetDependentModules(lldb_private::FileSpecList& files) override; -     -    size_t -    ReadSectionData(const lldb_private::Section *section, -                    lldb::offset_t section_offset, -                    void *dst, -                    size_t dst_len) const override; - -    size_t -    ReadSectionData(const lldb_private::Section *section, -                    lldb_private::DataExtractor& section_data) const override; -     -    lldb_private::Address -    GetEntryPointAddress() override; -     -    lldb_private::Address -    GetHeaderAddress() override; -     -    ObjectFile::Type -    CalculateType() override; -     -    ObjectFile::Strata -    CalculateStrata() override; - -    //------------------------------------------------------------------ -    // PluginInterface protocol -    //------------------------------------------------------------------ -    lldb_private::ConstString -    GetPluginName() override; - -    uint32_t -    GetPluginVersion() override; +  ObjectFileJIT(const lldb::ModuleSP &module_sp, +                const lldb::ObjectFileJITDelegateSP &delegate_sp); + +  ~ObjectFileJIT() override; + +  //------------------------------------------------------------------ +  // Static Functions +  //------------------------------------------------------------------ +  static void Initialize(); + +  static void Terminate(); + +  static lldb_private::ConstString GetPluginNameStatic(); + +  static const char *GetPluginDescriptionStatic(); + +  static lldb_private::ObjectFile * +  CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, +                 lldb::offset_t data_offset, const lldb_private::FileSpec *file, +                 lldb::offset_t file_offset, lldb::offset_t length); + +  static lldb_private::ObjectFile *CreateMemoryInstance( +      const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, +      const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); + +  static size_t 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); + +  //------------------------------------------------------------------ +  // Member Functions +  //------------------------------------------------------------------ +  bool ParseHeader() override; + +  bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, +                      bool value_is_offset) override; + +  lldb::ByteOrder GetByteOrder() const override; + +  bool IsExecutable() const override; + +  uint32_t GetAddressByteSize() const override; + +  lldb_private::Symtab *GetSymtab() override; + +  bool IsStripped() override; + +  void CreateSections(lldb_private::SectionList &unified_section_list) override; + +  void Dump(lldb_private::Stream *s) override; + +  bool GetArchitecture(lldb_private::ArchSpec &arch) override; + +  bool GetUUID(lldb_private::UUID *uuid) override; + +  uint32_t GetDependentModules(lldb_private::FileSpecList &files) override; + +  size_t ReadSectionData(const lldb_private::Section *section, +                         lldb::offset_t section_offset, void *dst, +                         size_t dst_len) const override; + +  size_t +  ReadSectionData(const lldb_private::Section *section, +                  lldb_private::DataExtractor §ion_data) const override; + +  lldb_private::Address GetEntryPointAddress() override; + +  lldb_private::Address GetHeaderAddress() override; + +  ObjectFile::Type CalculateType() override; + +  ObjectFile::Strata CalculateStrata() override; + +  //------------------------------------------------------------------ +  // PluginInterface protocol +  //------------------------------------------------------------------ +  lldb_private::ConstString GetPluginName() override; + +  uint32_t GetPluginVersion() override;  protected: -    lldb::ObjectFileJITDelegateWP m_delegate_wp; +  lldb::ObjectFileJITDelegateWP m_delegate_wp;  };  #endif // liblldb_ObjectFileJIT_h_ diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index 5f8242211b7f6..9ef4e9c3c9b19 100644 --- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -10,9 +10,13 @@  // C Includes  // C++ Includes  // Other libraries and framework includes -#include "llvm/ADT/StringRef.h"  +#include "llvm/ADT/StringRef.h"  // Project includes +#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h" +#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h" +#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h" +#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"  #include "lldb/Core/ArchSpec.h"  #include "lldb/Core/DataBuffer.h"  #include "lldb/Core/Debugger.h" @@ -28,10 +32,11 @@  #include "lldb/Core/StreamString.h"  #include "lldb/Core/Timer.h"  #include "lldb/Core/UUID.h" -#include "lldb/Host/Host.h"  #include "lldb/Host/FileSpec.h" +#include "lldb/Host/Host.h"  #include "lldb/Symbol/DWARFCallFrameInfo.h"  #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Target/DynamicLoader.h"  #include "lldb/Target/MemoryRegionInfo.h"  #include "lldb/Target/Platform.h"  #include "lldb/Target/Process.h" @@ -39,16 +44,13 @@  #include "lldb/Target/Target.h"  #include "lldb/Target/Thread.h"  #include "lldb/Target/ThreadList.h" -#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h" -#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h" -#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h" -#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"  #include "lldb/Utility/SafeMachO.h"  #include "ObjectFileMachO.h" -#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__)) +#if defined(__APPLE__) &&                                                      \ +    (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))  // GetLLDBSharedCacheUUID() needs to call dlsym()  #include <dlfcn.h>  #endif @@ -65,3870 +67,2966 @@ using namespace llvm::MachO;  // Some structure definitions needed for parsing the dyld shared cache files  // found on iOS devices. -struct lldb_copy_dyld_cache_header_v1 -{ -    char        magic[16];            // e.g. "dyld_v0    i386", "dyld_v1   armv7", etc. -    uint32_t    mappingOffset;        // file offset to first dyld_cache_mapping_info -    uint32_t    mappingCount;         // number of dyld_cache_mapping_info entries -    uint32_t    imagesOffset; -    uint32_t    imagesCount; -    uint64_t    dyldBaseAddress; -    uint64_t    codeSignatureOffset; -    uint64_t    codeSignatureSize; -    uint64_t    slideInfoOffset; -    uint64_t    slideInfoSize; -    uint64_t    localSymbolsOffset; -    uint64_t    localSymbolsSize; -    uint8_t     uuid[16];             // v1 and above, also recorded in dyld_all_image_infos v13 and later +struct lldb_copy_dyld_cache_header_v1 { +  char magic[16];         // e.g. "dyld_v0    i386", "dyld_v1   armv7", etc. +  uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info +  uint32_t mappingCount;  // number of dyld_cache_mapping_info entries +  uint32_t imagesOffset; +  uint32_t imagesCount; +  uint64_t dyldBaseAddress; +  uint64_t codeSignatureOffset; +  uint64_t codeSignatureSize; +  uint64_t slideInfoOffset; +  uint64_t slideInfoSize; +  uint64_t localSymbolsOffset; +  uint64_t localSymbolsSize; +  uint8_t uuid[16]; // v1 and above, also recorded in dyld_all_image_infos v13 +                    // and later  }; -struct lldb_copy_dyld_cache_mapping_info -{ -    uint64_t        address; -    uint64_t        size; -    uint64_t        fileOffset; -    uint32_t        maxProt; -    uint32_t        initProt; +struct lldb_copy_dyld_cache_mapping_info { +  uint64_t address; +  uint64_t size; +  uint64_t fileOffset; +  uint32_t maxProt; +  uint32_t initProt;  }; -struct lldb_copy_dyld_cache_local_symbols_info -{ -    uint32_t        nlistOffset; -    uint32_t        nlistCount; -    uint32_t        stringsOffset; -    uint32_t        stringsSize; -    uint32_t        entriesOffset; -    uint32_t        entriesCount; +struct lldb_copy_dyld_cache_local_symbols_info { +  uint32_t nlistOffset; +  uint32_t nlistCount; +  uint32_t stringsOffset; +  uint32_t stringsSize; +  uint32_t entriesOffset; +  uint32_t entriesCount;  }; -struct lldb_copy_dyld_cache_local_symbols_entry -{ -    uint32_t        dylibOffset; -    uint32_t        nlistStartIndex; -    uint32_t        nlistCount; +struct lldb_copy_dyld_cache_local_symbols_entry { +  uint32_t dylibOffset; +  uint32_t nlistStartIndex; +  uint32_t nlistCount;  }; - -class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64 -{ +class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64 {  public: -    RegisterContextDarwin_x86_64_Mach (lldb_private::Thread &thread, const DataExtractor &data) : -        RegisterContextDarwin_x86_64 (thread, 0) -    { -        SetRegisterDataFrom_LC_THREAD (data); -    } +  RegisterContextDarwin_x86_64_Mach(lldb_private::Thread &thread, +                                    const DataExtractor &data) +      : RegisterContextDarwin_x86_64(thread, 0) { +    SetRegisterDataFrom_LC_THREAD(data); +  } -    void -    InvalidateAllRegisters() override -    { -        // Do nothing... registers are always valid... -    } - -    void -    SetRegisterDataFrom_LC_THREAD (const DataExtractor &data) -    { -        lldb::offset_t offset = 0; -        SetError (GPRRegSet, Read, -1); -        SetError (FPURegSet, Read, -1); -        SetError (EXCRegSet, Read, -1); -        bool done = false; - -        while (!done) -        { -            int flavor = data.GetU32 (&offset); -            if (flavor == 0) -                done = true; -            else -            { -                uint32_t i; -                uint32_t count = data.GetU32 (&offset); -                switch (flavor) -                { -                    case GPRRegSet: -                        for (i=0; i<count; ++i) -                            (&gpr.rax)[i] = data.GetU64(&offset); -                        SetError (GPRRegSet, Read, 0); -                        done = true; +  void InvalidateAllRegisters() override { +    // Do nothing... registers are always valid... +  } -                        break; -                    case FPURegSet: -                        // TODO: fill in FPU regs.... -                        //SetError (FPURegSet, Read, -1); -                        done = true; - -                        break; -                    case EXCRegSet: -                        exc.trapno = data.GetU32(&offset); -                        exc.err = data.GetU32(&offset); -                        exc.faultvaddr = data.GetU64(&offset); -                        SetError (EXCRegSet, Read, 0); -                        done = true; -                        break; -                    case 7: -                    case 8: -                    case 9: -                        // fancy flavors that encapsulate of the above -                        // flavors... -                        break; +  void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) { +    lldb::offset_t offset = 0; +    SetError(GPRRegSet, Read, -1); +    SetError(FPURegSet, Read, -1); +    SetError(EXCRegSet, Read, -1); +    bool done = false; + +    while (!done) { +      int flavor = data.GetU32(&offset); +      if (flavor == 0) +        done = true; +      else { +        uint32_t i; +        uint32_t count = data.GetU32(&offset); +        switch (flavor) { +        case GPRRegSet: +          for (i = 0; i < count; ++i) +            (&gpr.rax)[i] = data.GetU64(&offset); +          SetError(GPRRegSet, Read, 0); +          done = true; + +          break; +        case FPURegSet: +          // TODO: fill in FPU regs.... +          // SetError (FPURegSet, Read, -1); +          done = true; + +          break; +        case EXCRegSet: +          exc.trapno = data.GetU32(&offset); +          exc.err = data.GetU32(&offset); +          exc.faultvaddr = data.GetU64(&offset); +          SetError(EXCRegSet, Read, 0); +          done = true; +          break; +        case 7: +        case 8: +        case 9: +          // fancy flavors that encapsulate of the above +          // flavors... +          break; -                    default: -                        done = true; -                        break; -                } -            } +        default: +          done = true; +          break;          } +      }      } - -    static size_t -    WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data) -    { -        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name); -        if (reg_info == NULL) -            reg_info = reg_ctx->GetRegisterInfoByName(alt_name); -        if (reg_info) -        { -            lldb_private::RegisterValue reg_value; -            if (reg_ctx->ReadRegister(reg_info, reg_value)) -            { -                if (reg_info->byte_size >= reg_byte_size) -                    data.Write(reg_value.GetBytes(), reg_byte_size); -                else -                { -                    data.Write(reg_value.GetBytes(), reg_info->byte_size); -                    for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i) -                        data.PutChar(0); -                } -                return reg_byte_size; -            } -        } -        // Just write zeros if all else fails -        for (size_t i=0; i<reg_byte_size; ++ i) +  } + +  static size_t WriteRegister(RegisterContext *reg_ctx, const char *name, +                              const char *alt_name, size_t reg_byte_size, +                              Stream &data) { +    const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name); +    if (reg_info == NULL) +      reg_info = reg_ctx->GetRegisterInfoByName(alt_name); +    if (reg_info) { +      lldb_private::RegisterValue reg_value; +      if (reg_ctx->ReadRegister(reg_info, reg_value)) { +        if (reg_info->byte_size >= reg_byte_size) +          data.Write(reg_value.GetBytes(), reg_byte_size); +        else { +          data.Write(reg_value.GetBytes(), reg_info->byte_size); +          for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n; +               ++i)              data.PutChar(0); +        }          return reg_byte_size; +      }      } - -    static bool -    Create_LC_THREAD (Thread *thread, Stream &data) -    { -        RegisterContextSP reg_ctx_sp (thread->GetRegisterContext()); -        if (reg_ctx_sp) -        { -            RegisterContext *reg_ctx = reg_ctx_sp.get(); - -            data.PutHex32 (GPRRegSet);  // Flavor -            data.PutHex32 (GPRWordCount); -            WriteRegister (reg_ctx, "rax", NULL, 8, data); -            WriteRegister (reg_ctx, "rbx", NULL, 8, data); -            WriteRegister (reg_ctx, "rcx", NULL, 8, data); -            WriteRegister (reg_ctx, "rdx", NULL, 8, data); -            WriteRegister (reg_ctx, "rdi", NULL, 8, data); -            WriteRegister (reg_ctx, "rsi", NULL, 8, data); -            WriteRegister (reg_ctx, "rbp", NULL, 8, data); -            WriteRegister (reg_ctx, "rsp", NULL, 8, data); -            WriteRegister (reg_ctx, "r8", NULL, 8, data); -            WriteRegister (reg_ctx, "r9", NULL, 8, data); -            WriteRegister (reg_ctx, "r10", NULL, 8, data); -            WriteRegister (reg_ctx, "r11", NULL, 8, data); -            WriteRegister (reg_ctx, "r12", NULL, 8, data); -            WriteRegister (reg_ctx, "r13", NULL, 8, data); -            WriteRegister (reg_ctx, "r14", NULL, 8, data); -            WriteRegister (reg_ctx, "r15", NULL, 8, data); -            WriteRegister (reg_ctx, "rip", NULL, 8, data); -            WriteRegister (reg_ctx, "rflags", NULL, 8, data); -            WriteRegister (reg_ctx, "cs", NULL, 8, data); -            WriteRegister (reg_ctx, "fs", NULL, 8, data); -            WriteRegister (reg_ctx, "gs", NULL, 8, data); - -//            // Write out the FPU registers -//            const size_t fpu_byte_size = sizeof(FPU); -//            size_t bytes_written = 0; -//            data.PutHex32 (FPURegSet); -//            data.PutHex32 (fpu_byte_size/sizeof(uint64_t)); -//            bytes_written += data.PutHex32(0);                                   // uint32_t pad[0] -//            bytes_written += data.PutHex32(0);                                   // uint32_t pad[1] -//            bytes_written += WriteRegister (reg_ctx, "fcw", "fctrl", 2, data);   // uint16_t    fcw;    // "fctrl" -//            bytes_written += WriteRegister (reg_ctx, "fsw" , "fstat", 2, data);  // uint16_t    fsw;    // "fstat" -//            bytes_written += WriteRegister (reg_ctx, "ftw" , "ftag", 1, data);   // uint8_t     ftw;    // "ftag" -//            bytes_written += data.PutHex8  (0);                                  // uint8_t pad1; -//            bytes_written += WriteRegister (reg_ctx, "fop" , NULL, 2, data);     // uint16_t    fop;    // "fop" -//            bytes_written += WriteRegister (reg_ctx, "fioff", "ip", 4, data);    // uint32_t    ip;     // "fioff" -//            bytes_written += WriteRegister (reg_ctx, "fiseg", NULL, 2, data);    // uint16_t    cs;     // "fiseg" -//            bytes_written += data.PutHex16 (0);                                  // uint16_t    pad2; -//            bytes_written += WriteRegister (reg_ctx, "dp", "fooff" , 4, data);   // uint32_t    dp;     // "fooff" -//            bytes_written += WriteRegister (reg_ctx, "foseg", NULL, 2, data);    // uint16_t    ds;     // "foseg" -//            bytes_written += data.PutHex16 (0);                                  // uint16_t    pad3; -//            bytes_written += WriteRegister (reg_ctx, "mxcsr", NULL, 4, data);    // uint32_t    mxcsr; -//            bytes_written += WriteRegister (reg_ctx, "mxcsrmask", NULL, 4, data);// uint32_t    mxcsrmask; -//            bytes_written += WriteRegister (reg_ctx, "stmm0", NULL, sizeof(MMSReg), data); -//            bytes_written += WriteRegister (reg_ctx, "stmm1", NULL, sizeof(MMSReg), data); -//            bytes_written += WriteRegister (reg_ctx, "stmm2", NULL, sizeof(MMSReg), data); -//            bytes_written += WriteRegister (reg_ctx, "stmm3", NULL, sizeof(MMSReg), data); -//            bytes_written += WriteRegister (reg_ctx, "stmm4", NULL, sizeof(MMSReg), data); -//            bytes_written += WriteRegister (reg_ctx, "stmm5", NULL, sizeof(MMSReg), data); -//            bytes_written += WriteRegister (reg_ctx, "stmm6", NULL, sizeof(MMSReg), data); -//            bytes_written += WriteRegister (reg_ctx, "stmm7", NULL, sizeof(MMSReg), data); -//            bytes_written += WriteRegister (reg_ctx, "xmm0" , NULL, sizeof(XMMReg), data); -//            bytes_written += WriteRegister (reg_ctx, "xmm1" , NULL, sizeof(XMMReg), data); -//            bytes_written += WriteRegister (reg_ctx, "xmm2" , NULL, sizeof(XMMReg), data); -//            bytes_written += WriteRegister (reg_ctx, "xmm3" , NULL, sizeof(XMMReg), data); -//            bytes_written += WriteRegister (reg_ctx, "xmm4" , NULL, sizeof(XMMReg), data); -//            bytes_written += WriteRegister (reg_ctx, "xmm5" , NULL, sizeof(XMMReg), data); -//            bytes_written += WriteRegister (reg_ctx, "xmm6" , NULL, sizeof(XMMReg), data); -//            bytes_written += WriteRegister (reg_ctx, "xmm7" , NULL, sizeof(XMMReg), data); -//            bytes_written += WriteRegister (reg_ctx, "xmm8" , NULL, sizeof(XMMReg), data); -//            bytes_written += WriteRegister (reg_ctx, "xmm9" , NULL, sizeof(XMMReg), data); -//            bytes_written += WriteRegister (reg_ctx, "xmm10", NULL, sizeof(XMMReg), data); -//            bytes_written += WriteRegister (reg_ctx, "xmm11", NULL, sizeof(XMMReg), data); -//            bytes_written += WriteRegister (reg_ctx, "xmm12", NULL, sizeof(XMMReg), data); -//            bytes_written += WriteRegister (reg_ctx, "xmm13", NULL, sizeof(XMMReg), data); -//            bytes_written += WriteRegister (reg_ctx, "xmm14", NULL, sizeof(XMMReg), data); -//            bytes_written += WriteRegister (reg_ctx, "xmm15", NULL, sizeof(XMMReg), data); -//             -//            // Fill rest with zeros -//            for (size_t i=0, n = fpu_byte_size - bytes_written; i<n; ++ i) -//                data.PutChar(0); -             -            // Write out the EXC registers -            data.PutHex32 (EXCRegSet); -            data.PutHex32 (EXCWordCount); -            WriteRegister (reg_ctx, "trapno", NULL, 4, data); -            WriteRegister (reg_ctx, "err", NULL, 4, data); -            WriteRegister (reg_ctx, "faultvaddr", NULL, 8, data); -            return true; -        } -        return false; +    // Just write zeros if all else fails +    for (size_t i = 0; i < reg_byte_size; ++i) +      data.PutChar(0); +    return reg_byte_size; +  } + +  static bool Create_LC_THREAD(Thread *thread, Stream &data) { +    RegisterContextSP reg_ctx_sp(thread->GetRegisterContext()); +    if (reg_ctx_sp) { +      RegisterContext *reg_ctx = reg_ctx_sp.get(); + +      data.PutHex32(GPRRegSet); // Flavor +      data.PutHex32(GPRWordCount); +      WriteRegister(reg_ctx, "rax", NULL, 8, data); +      WriteRegister(reg_ctx, "rbx", NULL, 8, data); +      WriteRegister(reg_ctx, "rcx", NULL, 8, data); +      WriteRegister(reg_ctx, "rdx", NULL, 8, data); +      WriteRegister(reg_ctx, "rdi", NULL, 8, data); +      WriteRegister(reg_ctx, "rsi", NULL, 8, data); +      WriteRegister(reg_ctx, "rbp", NULL, 8, data); +      WriteRegister(reg_ctx, "rsp", NULL, 8, data); +      WriteRegister(reg_ctx, "r8", NULL, 8, data); +      WriteRegister(reg_ctx, "r9", NULL, 8, data); +      WriteRegister(reg_ctx, "r10", NULL, 8, data); +      WriteRegister(reg_ctx, "r11", NULL, 8, data); +      WriteRegister(reg_ctx, "r12", NULL, 8, data); +      WriteRegister(reg_ctx, "r13", NULL, 8, data); +      WriteRegister(reg_ctx, "r14", NULL, 8, data); +      WriteRegister(reg_ctx, "r15", NULL, 8, data); +      WriteRegister(reg_ctx, "rip", NULL, 8, data); +      WriteRegister(reg_ctx, "rflags", NULL, 8, data); +      WriteRegister(reg_ctx, "cs", NULL, 8, data); +      WriteRegister(reg_ctx, "fs", NULL, 8, data); +      WriteRegister(reg_ctx, "gs", NULL, 8, data); + +      //            // Write out the FPU registers +      //            const size_t fpu_byte_size = sizeof(FPU); +      //            size_t bytes_written = 0; +      //            data.PutHex32 (FPURegSet); +      //            data.PutHex32 (fpu_byte_size/sizeof(uint64_t)); +      //            bytes_written += data.PutHex32(0); // uint32_t pad[0] +      //            bytes_written += data.PutHex32(0); // uint32_t pad[1] +      //            bytes_written += WriteRegister (reg_ctx, "fcw", "fctrl", 2, +      //            data);   // uint16_t    fcw;    // "fctrl" +      //            bytes_written += WriteRegister (reg_ctx, "fsw" , "fstat", 2, +      //            data);  // uint16_t    fsw;    // "fstat" +      //            bytes_written += WriteRegister (reg_ctx, "ftw" , "ftag", 1, +      //            data);   // uint8_t     ftw;    // "ftag" +      //            bytes_written += data.PutHex8  (0); // uint8_t pad1; +      //            bytes_written += WriteRegister (reg_ctx, "fop" , NULL, 2, +      //            data);     // uint16_t    fop;    // "fop" +      //            bytes_written += WriteRegister (reg_ctx, "fioff", "ip", 4, +      //            data);    // uint32_t    ip;     // "fioff" +      //            bytes_written += WriteRegister (reg_ctx, "fiseg", NULL, 2, +      //            data);    // uint16_t    cs;     // "fiseg" +      //            bytes_written += data.PutHex16 (0); // uint16_t    pad2; +      //            bytes_written += WriteRegister (reg_ctx, "dp", "fooff" , 4, +      //            data);   // uint32_t    dp;     // "fooff" +      //            bytes_written += WriteRegister (reg_ctx, "foseg", NULL, 2, +      //            data);    // uint16_t    ds;     // "foseg" +      //            bytes_written += data.PutHex16 (0); // uint16_t    pad3; +      //            bytes_written += WriteRegister (reg_ctx, "mxcsr", NULL, 4, +      //            data);    // uint32_t    mxcsr; +      //            bytes_written += WriteRegister (reg_ctx, "mxcsrmask", NULL, +      //            4, data);// uint32_t    mxcsrmask; +      //            bytes_written += WriteRegister (reg_ctx, "stmm0", NULL, +      //            sizeof(MMSReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "stmm1", NULL, +      //            sizeof(MMSReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "stmm2", NULL, +      //            sizeof(MMSReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "stmm3", NULL, +      //            sizeof(MMSReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "stmm4", NULL, +      //            sizeof(MMSReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "stmm5", NULL, +      //            sizeof(MMSReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "stmm6", NULL, +      //            sizeof(MMSReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "stmm7", NULL, +      //            sizeof(MMSReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "xmm0" , NULL, +      //            sizeof(XMMReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "xmm1" , NULL, +      //            sizeof(XMMReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "xmm2" , NULL, +      //            sizeof(XMMReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "xmm3" , NULL, +      //            sizeof(XMMReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "xmm4" , NULL, +      //            sizeof(XMMReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "xmm5" , NULL, +      //            sizeof(XMMReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "xmm6" , NULL, +      //            sizeof(XMMReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "xmm7" , NULL, +      //            sizeof(XMMReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "xmm8" , NULL, +      //            sizeof(XMMReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "xmm9" , NULL, +      //            sizeof(XMMReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "xmm10", NULL, +      //            sizeof(XMMReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "xmm11", NULL, +      //            sizeof(XMMReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "xmm12", NULL, +      //            sizeof(XMMReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "xmm13", NULL, +      //            sizeof(XMMReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "xmm14", NULL, +      //            sizeof(XMMReg), data); +      //            bytes_written += WriteRegister (reg_ctx, "xmm15", NULL, +      //            sizeof(XMMReg), data); +      // +      //            // Fill rest with zeros +      //            for (size_t i=0, n = fpu_byte_size - bytes_written; i<n; ++ +      //            i) +      //                data.PutChar(0); + +      // Write out the EXC registers +      data.PutHex32(EXCRegSet); +      data.PutHex32(EXCWordCount); +      WriteRegister(reg_ctx, "trapno", NULL, 4, data); +      WriteRegister(reg_ctx, "err", NULL, 4, data); +      WriteRegister(reg_ctx, "faultvaddr", NULL, 8, data); +      return true;      } +    return false; +  }  protected: -    int -    DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override -    { -        return 0; -    } +  int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return 0; } -    int -    DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override -    { -        return 0; -    } +  int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return 0; } -    int -    DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override -    { -        return 0; -    } +  int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return 0; } -    int -    DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override -    { -        return 0; -    } +  int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override { +    return 0; +  } -    int -    DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override -    { -        return 0; -    } +  int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override { +    return 0; +  } -    int -    DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override -    { -        return 0; -    } +  int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override { +    return 0; +  }  }; -class RegisterContextDarwin_i386_Mach : public RegisterContextDarwin_i386 -{ +class RegisterContextDarwin_i386_Mach : public RegisterContextDarwin_i386 {  public: -    RegisterContextDarwin_i386_Mach (lldb_private::Thread &thread, const DataExtractor &data) : -    RegisterContextDarwin_i386 (thread, 0) -    { -        SetRegisterDataFrom_LC_THREAD (data); -    } - -    void -    InvalidateAllRegisters() override -    { -        // Do nothing... registers are always valid... -    } +  RegisterContextDarwin_i386_Mach(lldb_private::Thread &thread, +                                  const DataExtractor &data) +      : RegisterContextDarwin_i386(thread, 0) { +    SetRegisterDataFrom_LC_THREAD(data); +  } -    void -    SetRegisterDataFrom_LC_THREAD (const DataExtractor &data) -    { -        lldb::offset_t offset = 0; -        SetError (GPRRegSet, Read, -1); -        SetError (FPURegSet, Read, -1); -        SetError (EXCRegSet, Read, -1); -        bool done = false; - -        while (!done) -        { -            int flavor = data.GetU32 (&offset); -            if (flavor == 0) -                done = true; -            else -            { -                uint32_t i; -                uint32_t count = data.GetU32 (&offset); -                switch (flavor) -                { -                    case GPRRegSet: -                        for (i=0; i<count; ++i) -                            (&gpr.eax)[i] = data.GetU32(&offset); -                        SetError (GPRRegSet, Read, 0); -                        done = true; +  void InvalidateAllRegisters() override { +    // Do nothing... registers are always valid... +  } -                        break; -                    case FPURegSet: -                        // TODO: fill in FPU regs.... -                        //SetError (FPURegSet, Read, -1); -                        done = true; - -                        break; -                    case EXCRegSet: -                        exc.trapno = data.GetU32(&offset); -                        exc.err = data.GetU32(&offset); -                        exc.faultvaddr = data.GetU32(&offset); -                        SetError (EXCRegSet, Read, 0); -                        done = true; -                        break; -                    case 7: -                    case 8: -                    case 9: -                        // fancy flavors that encapsulate of the above -                        // flavors... -                        break; +  void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) { +    lldb::offset_t offset = 0; +    SetError(GPRRegSet, Read, -1); +    SetError(FPURegSet, Read, -1); +    SetError(EXCRegSet, Read, -1); +    bool done = false; + +    while (!done) { +      int flavor = data.GetU32(&offset); +      if (flavor == 0) +        done = true; +      else { +        uint32_t i; +        uint32_t count = data.GetU32(&offset); +        switch (flavor) { +        case GPRRegSet: +          for (i = 0; i < count; ++i) +            (&gpr.eax)[i] = data.GetU32(&offset); +          SetError(GPRRegSet, Read, 0); +          done = true; + +          break; +        case FPURegSet: +          // TODO: fill in FPU regs.... +          // SetError (FPURegSet, Read, -1); +          done = true; + +          break; +        case EXCRegSet: +          exc.trapno = data.GetU32(&offset); +          exc.err = data.GetU32(&offset); +          exc.faultvaddr = data.GetU32(&offset); +          SetError(EXCRegSet, Read, 0); +          done = true; +          break; +        case 7: +        case 8: +        case 9: +          // fancy flavors that encapsulate of the above +          // flavors... +          break; -                    default: -                        done = true; -                        break; -                } -            } +        default: +          done = true; +          break;          } +      }      } - -    static size_t -    WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data) -    { -        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name); -        if (reg_info == NULL) -            reg_info = reg_ctx->GetRegisterInfoByName(alt_name); -        if (reg_info) -        { -            lldb_private::RegisterValue reg_value; -            if (reg_ctx->ReadRegister(reg_info, reg_value)) -            { -                if (reg_info->byte_size >= reg_byte_size) -                    data.Write(reg_value.GetBytes(), reg_byte_size); -                else -                { -                    data.Write(reg_value.GetBytes(), reg_info->byte_size); -                    for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i) -                        data.PutChar(0); -                } -                return reg_byte_size; -            } -        } -        // Just write zeros if all else fails -        for (size_t i=0; i<reg_byte_size; ++ i) +  } + +  static size_t WriteRegister(RegisterContext *reg_ctx, const char *name, +                              const char *alt_name, size_t reg_byte_size, +                              Stream &data) { +    const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name); +    if (reg_info == NULL) +      reg_info = reg_ctx->GetRegisterInfoByName(alt_name); +    if (reg_info) { +      lldb_private::RegisterValue reg_value; +      if (reg_ctx->ReadRegister(reg_info, reg_value)) { +        if (reg_info->byte_size >= reg_byte_size) +          data.Write(reg_value.GetBytes(), reg_byte_size); +        else { +          data.Write(reg_value.GetBytes(), reg_info->byte_size); +          for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n; +               ++i)              data.PutChar(0); +        }          return reg_byte_size; +      }      } - -    static bool -    Create_LC_THREAD (Thread *thread, Stream &data) -    { -        RegisterContextSP reg_ctx_sp (thread->GetRegisterContext()); -        if (reg_ctx_sp) -        { -            RegisterContext *reg_ctx = reg_ctx_sp.get(); - -            data.PutHex32 (GPRRegSet);  // Flavor -            data.PutHex32 (GPRWordCount); -            WriteRegister (reg_ctx, "eax", NULL, 4, data); -            WriteRegister (reg_ctx, "ebx", NULL, 4, data); -            WriteRegister (reg_ctx, "ecx", NULL, 4, data); -            WriteRegister (reg_ctx, "edx", NULL, 4, data); -            WriteRegister (reg_ctx, "edi", NULL, 4, data); -            WriteRegister (reg_ctx, "esi", NULL, 4, data); -            WriteRegister (reg_ctx, "ebp", NULL, 4, data); -            WriteRegister (reg_ctx, "esp", NULL, 4, data); -            WriteRegister (reg_ctx, "ss", NULL, 4, data); -            WriteRegister (reg_ctx, "eflags", NULL, 4, data); -            WriteRegister (reg_ctx, "eip", NULL, 4, data); -            WriteRegister (reg_ctx, "cs", NULL, 4, data); -            WriteRegister (reg_ctx, "ds", NULL, 4, data); -            WriteRegister (reg_ctx, "es", NULL, 4, data); -            WriteRegister (reg_ctx, "fs", NULL, 4, data); -            WriteRegister (reg_ctx, "gs", NULL, 4, data); - -            // Write out the EXC registers -            data.PutHex32 (EXCRegSet); -            data.PutHex32 (EXCWordCount); -            WriteRegister (reg_ctx, "trapno", NULL, 4, data); -            WriteRegister (reg_ctx, "err", NULL, 4, data); -            WriteRegister (reg_ctx, "faultvaddr", NULL, 4, data); -            return true; -        } -        return false; +    // Just write zeros if all else fails +    for (size_t i = 0; i < reg_byte_size; ++i) +      data.PutChar(0); +    return reg_byte_size; +  } + +  static bool Create_LC_THREAD(Thread *thread, Stream &data) { +    RegisterContextSP reg_ctx_sp(thread->GetRegisterContext()); +    if (reg_ctx_sp) { +      RegisterContext *reg_ctx = reg_ctx_sp.get(); + +      data.PutHex32(GPRRegSet); // Flavor +      data.PutHex32(GPRWordCount); +      WriteRegister(reg_ctx, "eax", NULL, 4, data); +      WriteRegister(reg_ctx, "ebx", NULL, 4, data); +      WriteRegister(reg_ctx, "ecx", NULL, 4, data); +      WriteRegister(reg_ctx, "edx", NULL, 4, data); +      WriteRegister(reg_ctx, "edi", NULL, 4, data); +      WriteRegister(reg_ctx, "esi", NULL, 4, data); +      WriteRegister(reg_ctx, "ebp", NULL, 4, data); +      WriteRegister(reg_ctx, "esp", NULL, 4, data); +      WriteRegister(reg_ctx, "ss", NULL, 4, data); +      WriteRegister(reg_ctx, "eflags", NULL, 4, data); +      WriteRegister(reg_ctx, "eip", NULL, 4, data); +      WriteRegister(reg_ctx, "cs", NULL, 4, data); +      WriteRegister(reg_ctx, "ds", NULL, 4, data); +      WriteRegister(reg_ctx, "es", NULL, 4, data); +      WriteRegister(reg_ctx, "fs", NULL, 4, data); +      WriteRegister(reg_ctx, "gs", NULL, 4, data); + +      // Write out the EXC registers +      data.PutHex32(EXCRegSet); +      data.PutHex32(EXCWordCount); +      WriteRegister(reg_ctx, "trapno", NULL, 4, data); +      WriteRegister(reg_ctx, "err", NULL, 4, data); +      WriteRegister(reg_ctx, "faultvaddr", NULL, 4, data); +      return true;      } +    return false; +  }  protected: -    int -    DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override -    { -        return 0; -    } +  int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return 0; } -    int -    DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override -    { -        return 0; -    } +  int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return 0; } -    int -    DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override -    { -        return 0; -    } +  int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return 0; } -    int -    DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override -    { -        return 0; -    } +  int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override { +    return 0; +  } -    int -    DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override -    { -        return 0; -    } +  int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override { +    return 0; +  } -    int -    DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override -    { -        return 0; -    } +  int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override { +    return 0; +  }  }; -class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm -{ +class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm {  public: -    RegisterContextDarwin_arm_Mach (lldb_private::Thread &thread, const DataExtractor &data) : -        RegisterContextDarwin_arm (thread, 0) -    { -        SetRegisterDataFrom_LC_THREAD (data); -    } - -    void -    InvalidateAllRegisters() override -    { -        // Do nothing... registers are always valid... -    } - -    void -    SetRegisterDataFrom_LC_THREAD (const DataExtractor &data) -    { -        lldb::offset_t offset = 0; -        SetError (GPRRegSet, Read, -1); -        SetError (FPURegSet, Read, -1); -        SetError (EXCRegSet, Read, -1); -        bool done = false; - -        while (!done) -        { -            int flavor = data.GetU32 (&offset); -            uint32_t count = data.GetU32 (&offset); -            lldb::offset_t next_thread_state = offset + (count * 4); -            switch (flavor) -            { -                case GPRAltRegSet: -                case GPRRegSet: -                    for (uint32_t i=0; i<count; ++i) -                    { -                        gpr.r[i] = data.GetU32(&offset); -                    } - -                    // Note that gpr.cpsr is also copied by the above loop; this loop technically extends  -                    // one element past the end of the gpr.r[] array. - -                    SetError (GPRRegSet, Read, 0); -                    offset = next_thread_state; -                    break; +  RegisterContextDarwin_arm_Mach(lldb_private::Thread &thread, +                                 const DataExtractor &data) +      : RegisterContextDarwin_arm(thread, 0) { +    SetRegisterDataFrom_LC_THREAD(data); +  } -                case FPURegSet: -                    { -                        uint8_t  *fpu_reg_buf = (uint8_t*) &fpu.floats.s[0]; -                        const int fpu_reg_buf_size = sizeof (fpu.floats); -                        if (data.ExtractBytes (offset, fpu_reg_buf_size, eByteOrderLittle, fpu_reg_buf) == fpu_reg_buf_size) -                        { -                            offset += fpu_reg_buf_size; -                            fpu.fpscr = data.GetU32(&offset); -                            SetError (FPURegSet, Read, 0); -                        } -                        else -                        { -                            done = true; -                        } -                    } -                    offset = next_thread_state; -                    break; +  void InvalidateAllRegisters() override { +    // Do nothing... registers are always valid... +  } -                case EXCRegSet: -                    if (count == 3) -                    { -                        exc.exception = data.GetU32(&offset); -                        exc.fsr = data.GetU32(&offset); -                        exc.far = data.GetU32(&offset); -                        SetError (EXCRegSet, Read, 0); -                    } -                    done = true; -                    offset = next_thread_state; -                    break; - -                // Unknown register set flavor, stop trying to parse. -                default: -                    done = true; -            } +  void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) { +    lldb::offset_t offset = 0; +    SetError(GPRRegSet, Read, -1); +    SetError(FPURegSet, Read, -1); +    SetError(EXCRegSet, Read, -1); +    bool done = false; + +    while (!done) { +      int flavor = data.GetU32(&offset); +      uint32_t count = data.GetU32(&offset); +      lldb::offset_t next_thread_state = offset + (count * 4); +      switch (flavor) { +      case GPRAltRegSet: +      case GPRRegSet: +        for (uint32_t i = 0; i < count; ++i) { +          gpr.r[i] = data.GetU32(&offset);          } -    } -    static size_t -    WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data) -    { -        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name); -        if (reg_info == NULL) -            reg_info = reg_ctx->GetRegisterInfoByName(alt_name); -        if (reg_info) -        { -            lldb_private::RegisterValue reg_value; -            if (reg_ctx->ReadRegister(reg_info, reg_value)) -            { -                if (reg_info->byte_size >= reg_byte_size) -                    data.Write(reg_value.GetBytes(), reg_byte_size); -                else -                { -                    data.Write(reg_value.GetBytes(), reg_info->byte_size); -                    for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i) -                        data.PutChar(0); -                } -                return reg_byte_size; -            } +        // Note that gpr.cpsr is also copied by the above loop; this loop +        // technically extends +        // one element past the end of the gpr.r[] array. + +        SetError(GPRRegSet, Read, 0); +        offset = next_thread_state; +        break; + +      case FPURegSet: { +        uint8_t *fpu_reg_buf = (uint8_t *)&fpu.floats.s[0]; +        const int fpu_reg_buf_size = sizeof(fpu.floats); +        if (data.ExtractBytes(offset, fpu_reg_buf_size, eByteOrderLittle, +                              fpu_reg_buf) == fpu_reg_buf_size) { +          offset += fpu_reg_buf_size; +          fpu.fpscr = data.GetU32(&offset); +          SetError(FPURegSet, Read, 0); +        } else { +          done = true; +        } +      } +        offset = next_thread_state; +        break; + +      case EXCRegSet: +        if (count == 3) { +          exc.exception = data.GetU32(&offset); +          exc.fsr = data.GetU32(&offset); +          exc.far = data.GetU32(&offset); +          SetError(EXCRegSet, Read, 0);          } -        // Just write zeros if all else fails -        for (size_t i=0; i<reg_byte_size; ++ i) +        done = true; +        offset = next_thread_state; +        break; + +      // Unknown register set flavor, stop trying to parse. +      default: +        done = true; +      } +    } +  } + +  static size_t WriteRegister(RegisterContext *reg_ctx, const char *name, +                              const char *alt_name, size_t reg_byte_size, +                              Stream &data) { +    const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name); +    if (reg_info == NULL) +      reg_info = reg_ctx->GetRegisterInfoByName(alt_name); +    if (reg_info) { +      lldb_private::RegisterValue reg_value; +      if (reg_ctx->ReadRegister(reg_info, reg_value)) { +        if (reg_info->byte_size >= reg_byte_size) +          data.Write(reg_value.GetBytes(), reg_byte_size); +        else { +          data.Write(reg_value.GetBytes(), reg_info->byte_size); +          for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n; +               ++i)              data.PutChar(0); +        }          return reg_byte_size; +      }      } - -    static bool -    Create_LC_THREAD (Thread *thread, Stream &data) -    { -        RegisterContextSP reg_ctx_sp (thread->GetRegisterContext()); -        if (reg_ctx_sp) -        { -            RegisterContext *reg_ctx = reg_ctx_sp.get(); - -            data.PutHex32 (GPRRegSet);  // Flavor -            data.PutHex32 (GPRWordCount); -            WriteRegister (reg_ctx, "r0", NULL, 4, data); -            WriteRegister (reg_ctx, "r1", NULL, 4, data); -            WriteRegister (reg_ctx, "r2", NULL, 4, data); -            WriteRegister (reg_ctx, "r3", NULL, 4, data); -            WriteRegister (reg_ctx, "r4", NULL, 4, data); -            WriteRegister (reg_ctx, "r5", NULL, 4, data); -            WriteRegister (reg_ctx, "r6", NULL, 4, data); -            WriteRegister (reg_ctx, "r7", NULL, 4, data); -            WriteRegister (reg_ctx, "r8", NULL, 4, data); -            WriteRegister (reg_ctx, "r9", NULL, 4, data); -            WriteRegister (reg_ctx, "r10", NULL, 4, data); -            WriteRegister (reg_ctx, "r11", NULL, 4, data); -            WriteRegister (reg_ctx, "r12", NULL, 4, data); -            WriteRegister (reg_ctx, "sp", NULL, 4, data); -            WriteRegister (reg_ctx, "lr", NULL, 4, data); -            WriteRegister (reg_ctx, "pc", NULL, 4, data); -            WriteRegister (reg_ctx, "cpsr", NULL, 4, data); - -            // Write out the EXC registers -//            data.PutHex32 (EXCRegSet); -//            data.PutHex32 (EXCWordCount); -//            WriteRegister (reg_ctx, "exception", NULL, 4, data); -//            WriteRegister (reg_ctx, "fsr", NULL, 4, data); -//            WriteRegister (reg_ctx, "far", NULL, 4, data); -            return true; -        } -        return false; +    // Just write zeros if all else fails +    for (size_t i = 0; i < reg_byte_size; ++i) +      data.PutChar(0); +    return reg_byte_size; +  } + +  static bool Create_LC_THREAD(Thread *thread, Stream &data) { +    RegisterContextSP reg_ctx_sp(thread->GetRegisterContext()); +    if (reg_ctx_sp) { +      RegisterContext *reg_ctx = reg_ctx_sp.get(); + +      data.PutHex32(GPRRegSet); // Flavor +      data.PutHex32(GPRWordCount); +      WriteRegister(reg_ctx, "r0", NULL, 4, data); +      WriteRegister(reg_ctx, "r1", NULL, 4, data); +      WriteRegister(reg_ctx, "r2", NULL, 4, data); +      WriteRegister(reg_ctx, "r3", NULL, 4, data); +      WriteRegister(reg_ctx, "r4", NULL, 4, data); +      WriteRegister(reg_ctx, "r5", NULL, 4, data); +      WriteRegister(reg_ctx, "r6", NULL, 4, data); +      WriteRegister(reg_ctx, "r7", NULL, 4, data); +      WriteRegister(reg_ctx, "r8", NULL, 4, data); +      WriteRegister(reg_ctx, "r9", NULL, 4, data); +      WriteRegister(reg_ctx, "r10", NULL, 4, data); +      WriteRegister(reg_ctx, "r11", NULL, 4, data); +      WriteRegister(reg_ctx, "r12", NULL, 4, data); +      WriteRegister(reg_ctx, "sp", NULL, 4, data); +      WriteRegister(reg_ctx, "lr", NULL, 4, data); +      WriteRegister(reg_ctx, "pc", NULL, 4, data); +      WriteRegister(reg_ctx, "cpsr", NULL, 4, data); + +      // Write out the EXC registers +      //            data.PutHex32 (EXCRegSet); +      //            data.PutHex32 (EXCWordCount); +      //            WriteRegister (reg_ctx, "exception", NULL, 4, data); +      //            WriteRegister (reg_ctx, "fsr", NULL, 4, data); +      //            WriteRegister (reg_ctx, "far", NULL, 4, data); +      return true;      } +    return false; +  }  protected: -    int -    DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override -    { -        return -1; -    } +  int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; } -    int -    DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override -    { -        return -1; -    } +  int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; } -    int -    DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override -    { -        return -1; -    } +  int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; } -    int -    DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override -    { -        return -1; -    } +  int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override { return -1; } -    int -    DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override -    { -        return 0; -    } +  int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override { +    return 0; +  } -    int -    DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override -    { -        return 0; -    } +  int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override { +    return 0; +  } -    int -    DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override -    { -        return 0; -    } +  int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override { +    return 0; +  } -    int -    DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override -    { -        return -1; -    } +  int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override { +    return -1; +  }  }; -class RegisterContextDarwin_arm64_Mach : public RegisterContextDarwin_arm64 -{ +class RegisterContextDarwin_arm64_Mach : public RegisterContextDarwin_arm64 {  public: -    RegisterContextDarwin_arm64_Mach (lldb_private::Thread &thread, const DataExtractor &data) : -        RegisterContextDarwin_arm64 (thread, 0) -    { -        SetRegisterDataFrom_LC_THREAD (data); -    } -     -    void -    InvalidateAllRegisters() override -    { -        // Do nothing... registers are always valid... -    } -     -    void -    SetRegisterDataFrom_LC_THREAD (const DataExtractor &data) -    { -        lldb::offset_t offset = 0; -        SetError (GPRRegSet, Read, -1); -        SetError (FPURegSet, Read, -1); -        SetError (EXCRegSet, Read, -1); -        bool done = false; -        while (!done) -        { -            int flavor = data.GetU32 (&offset); -            uint32_t count = data.GetU32 (&offset); -            lldb::offset_t next_thread_state = offset + (count * 4); -            switch (flavor) -            { -                case GPRRegSet: -                    // x0-x29 + fp + lr + sp + pc (== 33 64-bit registers) plus cpsr (1 32-bit register) -                    if (count >= (33 * 2) + 1) -                    { -                        for (uint32_t i=0; i<33; ++i) -                            gpr.x[i] = data.GetU64(&offset); -                        gpr.cpsr = data.GetU32(&offset); -                        SetError (GPRRegSet, Read, 0); -                    } -                    offset = next_thread_state; -                    break; -                case FPURegSet: -                    { -                        uint8_t *fpu_reg_buf = (uint8_t*) &fpu.v[0]; -                        const int fpu_reg_buf_size = sizeof (fpu); -                        if (fpu_reg_buf_size == count -                            && data.ExtractBytes (offset, fpu_reg_buf_size, eByteOrderLittle, fpu_reg_buf) == fpu_reg_buf_size) -                        { -                            SetError (FPURegSet, Read, 0); -                        } -                        else -                        { -                            done = true; -                        } -                    } -                    offset = next_thread_state; -                    break; -                case EXCRegSet: -                    if (count == 4) -                    { -                        exc.far = data.GetU64(&offset); -                        exc.esr = data.GetU32(&offset); -                        exc.exception = data.GetU32(&offset); -                        SetError (EXCRegSet, Read, 0); -                    } -                    offset = next_thread_state; -                    break; -                default: -                    done = true; -                    break; -            } -        } -    } +  RegisterContextDarwin_arm64_Mach(lldb_private::Thread &thread, +                                   const DataExtractor &data) +      : RegisterContextDarwin_arm64(thread, 0) { +    SetRegisterDataFrom_LC_THREAD(data); +  } -    static size_t -    WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data) -    { -        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name); -        if (reg_info == NULL) -            reg_info = reg_ctx->GetRegisterInfoByName(alt_name); -        if (reg_info) -        { -            lldb_private::RegisterValue reg_value; -            if (reg_ctx->ReadRegister(reg_info, reg_value)) -            { -                if (reg_info->byte_size >= reg_byte_size) -                    data.Write(reg_value.GetBytes(), reg_byte_size); -                else -                { -                    data.Write(reg_value.GetBytes(), reg_info->byte_size); -                    for (size_t i=0, n = reg_byte_size - reg_info->byte_size; i<n; ++ i) -                        data.PutChar(0); -                } -                return reg_byte_size; -            } +  void InvalidateAllRegisters() override { +    // Do nothing... registers are always valid... +  } + +  void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) { +    lldb::offset_t offset = 0; +    SetError(GPRRegSet, Read, -1); +    SetError(FPURegSet, Read, -1); +    SetError(EXCRegSet, Read, -1); +    bool done = false; +    while (!done) { +      int flavor = data.GetU32(&offset); +      uint32_t count = data.GetU32(&offset); +      lldb::offset_t next_thread_state = offset + (count * 4); +      switch (flavor) { +      case GPRRegSet: +        // x0-x29 + fp + lr + sp + pc (== 33 64-bit registers) plus cpsr (1 +        // 32-bit register) +        if (count >= (33 * 2) + 1) { +          for (uint32_t i = 0; i < 29; ++i) +            gpr.x[i] = data.GetU64(&offset); +          gpr.fp = data.GetU64(&offset); +          gpr.lr = data.GetU64(&offset); +          gpr.sp = data.GetU64(&offset); +          gpr.pc = data.GetU64(&offset); +          gpr.cpsr = data.GetU32(&offset); +          SetError(GPRRegSet, Read, 0); +        } +        offset = next_thread_state; +        break; +      case FPURegSet: { +        uint8_t *fpu_reg_buf = (uint8_t *)&fpu.v[0]; +        const int fpu_reg_buf_size = sizeof(fpu); +        if (fpu_reg_buf_size == count && +            data.ExtractBytes(offset, fpu_reg_buf_size, eByteOrderLittle, +                              fpu_reg_buf) == fpu_reg_buf_size) { +          SetError(FPURegSet, Read, 0); +        } else { +          done = true; +        } +      } +        offset = next_thread_state; +        break; +      case EXCRegSet: +        if (count == 4) { +          exc.far = data.GetU64(&offset); +          exc.esr = data.GetU32(&offset); +          exc.exception = data.GetU32(&offset); +          SetError(EXCRegSet, Read, 0);          } -        // Just write zeros if all else fails -        for (size_t i=0; i<reg_byte_size; ++ i) +        offset = next_thread_state; +        break; +      default: +        done = true; +        break; +      } +    } +  } + +  static size_t WriteRegister(RegisterContext *reg_ctx, const char *name, +                              const char *alt_name, size_t reg_byte_size, +                              Stream &data) { +    const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name); +    if (reg_info == NULL) +      reg_info = reg_ctx->GetRegisterInfoByName(alt_name); +    if (reg_info) { +      lldb_private::RegisterValue reg_value; +      if (reg_ctx->ReadRegister(reg_info, reg_value)) { +        if (reg_info->byte_size >= reg_byte_size) +          data.Write(reg_value.GetBytes(), reg_byte_size); +        else { +          data.Write(reg_value.GetBytes(), reg_info->byte_size); +          for (size_t i = 0, n = reg_byte_size - reg_info->byte_size; i < n; +               ++i)              data.PutChar(0); +        }          return reg_byte_size; +      }      } - -    static bool -    Create_LC_THREAD (Thread *thread, Stream &data) -    { -        RegisterContextSP reg_ctx_sp (thread->GetRegisterContext()); -        if (reg_ctx_sp) -        { -            RegisterContext *reg_ctx = reg_ctx_sp.get(); - -            data.PutHex32 (GPRRegSet);  // Flavor -            data.PutHex32 (GPRWordCount); -            WriteRegister (reg_ctx, "x0", NULL, 8, data); -            WriteRegister (reg_ctx, "x1", NULL, 8, data); -            WriteRegister (reg_ctx, "x2", NULL, 8, data); -            WriteRegister (reg_ctx, "x3", NULL, 8, data); -            WriteRegister (reg_ctx, "x4", NULL, 8, data); -            WriteRegister (reg_ctx, "x5", NULL, 8, data); -            WriteRegister (reg_ctx, "x6", NULL, 8, data); -            WriteRegister (reg_ctx, "x7", NULL, 8, data); -            WriteRegister (reg_ctx, "x8", NULL, 8, data); -            WriteRegister (reg_ctx, "x9", NULL, 8, data); -            WriteRegister (reg_ctx, "x10", NULL, 8, data); -            WriteRegister (reg_ctx, "x11", NULL, 8, data); -            WriteRegister (reg_ctx, "x12", NULL, 8, data); -            WriteRegister (reg_ctx, "x13", NULL, 8, data); -            WriteRegister (reg_ctx, "x14", NULL, 8, data); -            WriteRegister (reg_ctx, "x15", NULL, 8, data); -            WriteRegister (reg_ctx, "x16", NULL, 8, data); -            WriteRegister (reg_ctx, "x17", NULL, 8, data); -            WriteRegister (reg_ctx, "x18", NULL, 8, data); -            WriteRegister (reg_ctx, "x19", NULL, 8, data); -            WriteRegister (reg_ctx, "x20", NULL, 8, data); -            WriteRegister (reg_ctx, "x21", NULL, 8, data); -            WriteRegister (reg_ctx, "x22", NULL, 8, data); -            WriteRegister (reg_ctx, "x23", NULL, 8, data); -            WriteRegister (reg_ctx, "x24", NULL, 8, data); -            WriteRegister (reg_ctx, "x25", NULL, 8, data); -            WriteRegister (reg_ctx, "x26", NULL, 8, data); -            WriteRegister (reg_ctx, "x27", NULL, 8, data); -            WriteRegister (reg_ctx, "x28", NULL, 8, data); -            WriteRegister (reg_ctx, "fp", NULL, 8, data); -            WriteRegister (reg_ctx, "lr", NULL, 8, data); -            WriteRegister (reg_ctx, "sp", NULL, 8, data); -            WriteRegister (reg_ctx, "pc", NULL, 8, data); -            WriteRegister (reg_ctx, "cpsr", NULL, 4, data); - -            // Write out the EXC registers -//            data.PutHex32 (EXCRegSet); -//            data.PutHex32 (EXCWordCount); -//            WriteRegister (reg_ctx, "far", NULL, 8, data); -//            WriteRegister (reg_ctx, "esr", NULL, 4, data); -//            WriteRegister (reg_ctx, "exception", NULL, 4, data); -            return true; -        } -        return false; +    // Just write zeros if all else fails +    for (size_t i = 0; i < reg_byte_size; ++i) +      data.PutChar(0); +    return reg_byte_size; +  } + +  static bool Create_LC_THREAD(Thread *thread, Stream &data) { +    RegisterContextSP reg_ctx_sp(thread->GetRegisterContext()); +    if (reg_ctx_sp) { +      RegisterContext *reg_ctx = reg_ctx_sp.get(); + +      data.PutHex32(GPRRegSet); // Flavor +      data.PutHex32(GPRWordCount); +      WriteRegister(reg_ctx, "x0", NULL, 8, data); +      WriteRegister(reg_ctx, "x1", NULL, 8, data); +      WriteRegister(reg_ctx, "x2", NULL, 8, data); +      WriteRegister(reg_ctx, "x3", NULL, 8, data); +      WriteRegister(reg_ctx, "x4", NULL, 8, data); +      WriteRegister(reg_ctx, "x5", NULL, 8, data); +      WriteRegister(reg_ctx, "x6", NULL, 8, data); +      WriteRegister(reg_ctx, "x7", NULL, 8, data); +      WriteRegister(reg_ctx, "x8", NULL, 8, data); +      WriteRegister(reg_ctx, "x9", NULL, 8, data); +      WriteRegister(reg_ctx, "x10", NULL, 8, data); +      WriteRegister(reg_ctx, "x11", NULL, 8, data); +      WriteRegister(reg_ctx, "x12", NULL, 8, data); +      WriteRegister(reg_ctx, "x13", NULL, 8, data); +      WriteRegister(reg_ctx, "x14", NULL, 8, data); +      WriteRegister(reg_ctx, "x15", NULL, 8, data); +      WriteRegister(reg_ctx, "x16", NULL, 8, data); +      WriteRegister(reg_ctx, "x17", NULL, 8, data); +      WriteRegister(reg_ctx, "x18", NULL, 8, data); +      WriteRegister(reg_ctx, "x19", NULL, 8, data); +      WriteRegister(reg_ctx, "x20", NULL, 8, data); +      WriteRegister(reg_ctx, "x21", NULL, 8, data); +      WriteRegister(reg_ctx, "x22", NULL, 8, data); +      WriteRegister(reg_ctx, "x23", NULL, 8, data); +      WriteRegister(reg_ctx, "x24", NULL, 8, data); +      WriteRegister(reg_ctx, "x25", NULL, 8, data); +      WriteRegister(reg_ctx, "x26", NULL, 8, data); +      WriteRegister(reg_ctx, "x27", NULL, 8, data); +      WriteRegister(reg_ctx, "x28", NULL, 8, data); +      WriteRegister(reg_ctx, "fp", NULL, 8, data); +      WriteRegister(reg_ctx, "lr", NULL, 8, data); +      WriteRegister(reg_ctx, "sp", NULL, 8, data); +      WriteRegister(reg_ctx, "pc", NULL, 8, data); +      WriteRegister(reg_ctx, "cpsr", NULL, 4, data); + +      // Write out the EXC registers +      //            data.PutHex32 (EXCRegSet); +      //            data.PutHex32 (EXCWordCount); +      //            WriteRegister (reg_ctx, "far", NULL, 8, data); +      //            WriteRegister (reg_ctx, "esr", NULL, 4, data); +      //            WriteRegister (reg_ctx, "exception", NULL, 4, data); +      return true;      } +    return false; +  }  protected: -    int -    DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override -    { -        return -1; -    } -     -    int -    DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override -    { -        return -1; -    } -     -    int -    DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override -    { -        return -1; -    } +  int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; } -    int -    DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override -    { -        return -1; -    } -     -    int -    DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override -    { -        return 0; -    } -     -    int -    DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override -    { -        return 0; -    } -     -    int -    DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override -    { -        return 0; -    } -     -    int -    DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override -    { -        return -1; -    } -}; +  int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; } -static uint32_t -MachHeaderSizeFromMagic(uint32_t magic) -{ -    switch (magic) -    { -        case MH_MAGIC: -        case MH_CIGAM: -            return sizeof(struct mach_header); -             -        case MH_MAGIC_64: -        case MH_CIGAM_64: -            return sizeof(struct mach_header_64); -            break; -             -        default: -            break; -    } +  int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; } + +  int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override { return -1; } + +  int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override { +    return 0; +  } + +  int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override { +    return 0; +  } + +  int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override {      return 0; +  } + +  int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override { +    return -1; +  } +}; + +static uint32_t MachHeaderSizeFromMagic(uint32_t magic) { +  switch (magic) { +  case MH_MAGIC: +  case MH_CIGAM: +    return sizeof(struct mach_header); + +  case MH_MAGIC_64: +  case MH_CIGAM_64: +    return sizeof(struct mach_header_64); +    break; + +  default: +    break; +  } +  return 0;  }  #define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008 -void -ObjectFileMachO::Initialize() -{ -    PluginManager::RegisterPlugin (GetPluginNameStatic(), -                                   GetPluginDescriptionStatic(), -                                   CreateInstance, -                                   CreateMemoryInstance, -                                   GetModuleSpecifications, -                                   SaveCore); +void ObjectFileMachO::Initialize() { +  PluginManager::RegisterPlugin( +      GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, +      CreateMemoryInstance, GetModuleSpecifications, SaveCore);  } -void -ObjectFileMachO::Terminate() -{ -    PluginManager::UnregisterPlugin (CreateInstance); +void ObjectFileMachO::Terminate() { +  PluginManager::UnregisterPlugin(CreateInstance);  } -lldb_private::ConstString -ObjectFileMachO::GetPluginNameStatic() -{ -    static ConstString g_name("mach-o"); -    return g_name; +lldb_private::ConstString ObjectFileMachO::GetPluginNameStatic() { +  static ConstString g_name("mach-o"); +  return g_name;  } -const char * -ObjectFileMachO::GetPluginDescriptionStatic() -{ -    return "Mach-o object file reader (32 and 64 bit)"; +const char *ObjectFileMachO::GetPluginDescriptionStatic() { +  return "Mach-o object file reader (32 and 64 bit)";  } -ObjectFile * -ObjectFileMachO::CreateInstance (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) -{ -    if (!data_sp) -    { -        data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length); -        data_offset = 0; -    } - -    if (ObjectFileMachO::MagicBytesMatch(data_sp, data_offset, length)) -    { -        // Update the data to contain the entire file if it doesn't already -        if (data_sp->GetByteSize() < length) -        { -            data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length); -            data_offset = 0; -        } -        std::unique_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, data_offset, file, file_offset, length)); -        if (objfile_ap.get() && objfile_ap->ParseHeader()) -            return objfile_ap.release(); +ObjectFile *ObjectFileMachO::CreateInstance(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) { +  if (!data_sp) { +    data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length); +    data_offset = 0; +  } + +  if (ObjectFileMachO::MagicBytesMatch(data_sp, data_offset, length)) { +    // Update the data to contain the entire file if it doesn't already +    if (data_sp->GetByteSize() < length) { +      data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length); +      data_offset = 0;      } -    return NULL; +    std::unique_ptr<ObjectFile> objfile_ap(new ObjectFileMachO( +        module_sp, data_sp, data_offset, file, file_offset, length)); +    if (objfile_ap.get() && objfile_ap->ParseHeader()) +      return objfile_ap.release(); +  } +  return NULL;  } -ObjectFile * -ObjectFileMachO::CreateMemoryInstance (const lldb::ModuleSP &module_sp, -                                       DataBufferSP& data_sp, -                                       const ProcessSP &process_sp, -                                       lldb::addr_t header_addr) -{ -    if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) -    { -        std::unique_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, process_sp, header_addr)); -        if (objfile_ap.get() && objfile_ap->ParseHeader()) -            return objfile_ap.release(); -    } -    return NULL; +ObjectFile *ObjectFileMachO::CreateMemoryInstance( +    const lldb::ModuleSP &module_sp, DataBufferSP &data_sp, +    const ProcessSP &process_sp, lldb::addr_t header_addr) { +  if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) { +    std::unique_ptr<ObjectFile> objfile_ap( +        new ObjectFileMachO(module_sp, data_sp, process_sp, header_addr)); +    if (objfile_ap.get() && objfile_ap->ParseHeader()) +      return objfile_ap.release(); +  } +  return NULL;  } -size_t -ObjectFileMachO::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) -{ -    const size_t initial_count = specs.GetSize(); -     -    if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) -    { -        DataExtractor data; +size_t ObjectFileMachO::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) { +  const size_t initial_count = specs.GetSize(); + +  if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) { +    DataExtractor data; +    data.SetData(data_sp); +    llvm::MachO::mach_header header; +    if (ParseHeader(data, &data_offset, header)) { +      size_t header_and_load_cmds = +          header.sizeofcmds + MachHeaderSizeFromMagic(header.magic); +      if (header_and_load_cmds >= data_sp->GetByteSize()) { +        data_sp = file.ReadFileContents(file_offset, header_and_load_cmds);          data.SetData(data_sp); -        llvm::MachO::mach_header header; -        if (ParseHeader (data, &data_offset, header)) -        { -            size_t header_and_load_cmds = header.sizeofcmds + MachHeaderSizeFromMagic(header.magic); -            if (header_and_load_cmds >= data_sp->GetByteSize()) -            { -                data_sp = file.ReadFileContents(file_offset, header_and_load_cmds); -                data.SetData(data_sp); -                data_offset = MachHeaderSizeFromMagic(header.magic); -            } -            if (data_sp) -            { -                ModuleSpec spec; -                spec.GetFileSpec() = file; -                spec.SetObjectOffset(file_offset); -                spec.SetObjectSize(length); - -                if (GetArchitecture (header, data, data_offset, spec.GetArchitecture())) -                { -                    if (spec.GetArchitecture().IsValid()) -                    { -                        GetUUID (header, data, data_offset, spec.GetUUID()); -                        specs.Append(spec); -                    } -                } -            } +        data_offset = MachHeaderSizeFromMagic(header.magic); +      } +      if (data_sp) { +        ModuleSpec spec; +        spec.GetFileSpec() = file; +        spec.SetObjectOffset(file_offset); +        spec.SetObjectSize(length); + +        if (GetArchitecture(header, data, data_offset, +                            spec.GetArchitecture())) { +          if (spec.GetArchitecture().IsValid()) { +            GetUUID(header, data, data_offset, spec.GetUUID()); +            specs.Append(spec); +          }          } +      }      } -    return specs.GetSize() - initial_count; +  } +  return specs.GetSize() - initial_count;  } -const ConstString & -ObjectFileMachO::GetSegmentNameTEXT() -{ -    static ConstString g_segment_name_TEXT ("__TEXT"); -    return g_segment_name_TEXT; +const ConstString &ObjectFileMachO::GetSegmentNameTEXT() { +  static ConstString g_segment_name_TEXT("__TEXT"); +  return g_segment_name_TEXT;  } -const ConstString & -ObjectFileMachO::GetSegmentNameDATA() -{ -    static ConstString g_segment_name_DATA ("__DATA"); -    return g_segment_name_DATA; +const ConstString &ObjectFileMachO::GetSegmentNameDATA() { +  static ConstString g_segment_name_DATA("__DATA"); +  return g_segment_name_DATA;  } -const ConstString & -ObjectFileMachO::GetSegmentNameDATA_DIRTY() -{ -    static ConstString g_segment_name ("__DATA_DIRTY"); -    return g_segment_name; +const ConstString &ObjectFileMachO::GetSegmentNameDATA_DIRTY() { +  static ConstString g_segment_name("__DATA_DIRTY"); +  return g_segment_name;  } -const ConstString & -ObjectFileMachO::GetSegmentNameDATA_CONST() -{ -    static ConstString g_segment_name ("__DATA_CONST"); -    return g_segment_name; +const ConstString &ObjectFileMachO::GetSegmentNameDATA_CONST() { +  static ConstString g_segment_name("__DATA_CONST"); +  return g_segment_name;  } -const ConstString & -ObjectFileMachO::GetSegmentNameOBJC() -{ -    static ConstString g_segment_name_OBJC ("__OBJC"); -    return g_segment_name_OBJC; +const ConstString &ObjectFileMachO::GetSegmentNameOBJC() { +  static ConstString g_segment_name_OBJC("__OBJC"); +  return g_segment_name_OBJC;  } -const ConstString & -ObjectFileMachO::GetSegmentNameLINKEDIT() -{ -    static ConstString g_section_name_LINKEDIT ("__LINKEDIT"); -    return g_section_name_LINKEDIT; +const ConstString &ObjectFileMachO::GetSegmentNameLINKEDIT() { +  static ConstString g_section_name_LINKEDIT("__LINKEDIT"); +  return g_section_name_LINKEDIT;  } -const ConstString & -ObjectFileMachO::GetSectionNameEHFrame() -{ -    static ConstString g_section_name_eh_frame ("__eh_frame"); -    return g_section_name_eh_frame; +const ConstString &ObjectFileMachO::GetSectionNameEHFrame() { +  static ConstString g_section_name_eh_frame("__eh_frame"); +  return g_section_name_eh_frame;  } -bool -ObjectFileMachO::MagicBytesMatch (DataBufferSP& data_sp, -                                  lldb::addr_t data_offset, -                                  lldb::addr_t data_length) -{ -    DataExtractor data; -    data.SetData (data_sp, data_offset, data_length); -    lldb::offset_t offset = 0; -    uint32_t magic = data.GetU32(&offset); -    return MachHeaderSizeFromMagic(magic) != 0; +bool ObjectFileMachO::MagicBytesMatch(DataBufferSP &data_sp, +                                      lldb::addr_t data_offset, +                                      lldb::addr_t data_length) { +  DataExtractor data; +  data.SetData(data_sp, data_offset, data_length); +  lldb::offset_t offset = 0; +  uint32_t magic = data.GetU32(&offset); +  return MachHeaderSizeFromMagic(magic) != 0;  }  ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp, -                                 DataBufferSP& data_sp, +                                 DataBufferSP &data_sp,                                   lldb::offset_t data_offset, -                                 const FileSpec* file, +                                 const FileSpec *file,                                   lldb::offset_t file_offset, -                                 lldb::offset_t length) : -    ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset), -    m_mach_segments(), -    m_mach_sections(), -    m_entry_point_address(), -    m_thread_context_offsets(), -    m_thread_context_offsets_valid(false), -    m_reexported_dylibs (), -    m_allow_assembly_emulation_unwind_plans (true) -{ -    ::memset (&m_header, 0, sizeof(m_header)); -    ::memset (&m_dysymtab, 0, sizeof(m_dysymtab)); +                                 lldb::offset_t length) +    : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset), +      m_mach_segments(), m_mach_sections(), m_entry_point_address(), +      m_thread_context_offsets(), m_thread_context_offsets_valid(false), +      m_reexported_dylibs(), m_allow_assembly_emulation_unwind_plans(true) { +  ::memset(&m_header, 0, sizeof(m_header)); +  ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));  } -ObjectFileMachO::ObjectFileMachO (const lldb::ModuleSP &module_sp, -                                  lldb::DataBufferSP& header_data_sp, -                                  const lldb::ProcessSP &process_sp, -                                  lldb::addr_t header_addr) : -    ObjectFile(module_sp, process_sp, header_addr, header_data_sp), -    m_mach_segments(), -    m_mach_sections(), -    m_entry_point_address(), -    m_thread_context_offsets(), -    m_thread_context_offsets_valid(false), -    m_reexported_dylibs (), -    m_allow_assembly_emulation_unwind_plans (true) -{ -    ::memset (&m_header, 0, sizeof(m_header)); -    ::memset (&m_dysymtab, 0, sizeof(m_dysymtab)); +ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp, +                                 lldb::DataBufferSP &header_data_sp, +                                 const lldb::ProcessSP &process_sp, +                                 lldb::addr_t header_addr) +    : ObjectFile(module_sp, process_sp, header_addr, header_data_sp), +      m_mach_segments(), m_mach_sections(), m_entry_point_address(), +      m_thread_context_offsets(), m_thread_context_offsets_valid(false), +      m_reexported_dylibs(), m_allow_assembly_emulation_unwind_plans(true) { +  ::memset(&m_header, 0, sizeof(m_header)); +  ::memset(&m_dysymtab, 0, sizeof(m_dysymtab));  } -bool -ObjectFileMachO::ParseHeader (DataExtractor &data, -                              lldb::offset_t *data_offset_ptr, -                              llvm::MachO::mach_header &header) -{ -    data.SetByteOrder (endian::InlHostByteOrder()); -    // Leave magic in the original byte order -    header.magic = data.GetU32(data_offset_ptr); -    bool can_parse = false; -    bool is_64_bit = false; -    switch (header.magic) -    { -        case MH_MAGIC: -            data.SetByteOrder (endian::InlHostByteOrder()); -            data.SetAddressByteSize(4); -            can_parse = true; -            break; -             -        case MH_MAGIC_64: -            data.SetByteOrder (endian::InlHostByteOrder()); -            data.SetAddressByteSize(8); -            can_parse = true; -            is_64_bit = true; -            break; -             -        case MH_CIGAM: -            data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig); -            data.SetAddressByteSize(4); -            can_parse = true; -            break; -             -        case MH_CIGAM_64: -            data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig); -            data.SetAddressByteSize(8); -            is_64_bit = true; -            can_parse = true; -            break; -             -        default: -            break; -    } -     -    if (can_parse) -    { -        data.GetU32(data_offset_ptr, &header.cputype, 6); -        if (is_64_bit) -            *data_offset_ptr += 4; -        return true; -    } -    else -    { -        memset(&header, 0, sizeof(header)); -    } -    return false; +bool ObjectFileMachO::ParseHeader(DataExtractor &data, +                                  lldb::offset_t *data_offset_ptr, +                                  llvm::MachO::mach_header &header) { +  data.SetByteOrder(endian::InlHostByteOrder()); +  // Leave magic in the original byte order +  header.magic = data.GetU32(data_offset_ptr); +  bool can_parse = false; +  bool is_64_bit = false; +  switch (header.magic) { +  case MH_MAGIC: +    data.SetByteOrder(endian::InlHostByteOrder()); +    data.SetAddressByteSize(4); +    can_parse = true; +    break; + +  case MH_MAGIC_64: +    data.SetByteOrder(endian::InlHostByteOrder()); +    data.SetAddressByteSize(8); +    can_parse = true; +    is_64_bit = true; +    break; + +  case MH_CIGAM: +    data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig +                          ? eByteOrderLittle +                          : eByteOrderBig); +    data.SetAddressByteSize(4); +    can_parse = true; +    break; + +  case MH_CIGAM_64: +    data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig +                          ? eByteOrderLittle +                          : eByteOrderBig); +    data.SetAddressByteSize(8); +    is_64_bit = true; +    can_parse = true; +    break; + +  default: +    break; +  } + +  if (can_parse) { +    data.GetU32(data_offset_ptr, &header.cputype, 6); +    if (is_64_bit) +      *data_offset_ptr += 4; +    return true; +  } else { +    memset(&header, 0, sizeof(header)); +  } +  return false;  } -bool -ObjectFileMachO::ParseHeader () -{ -    ModuleSP module_sp(GetModule()); -    if (module_sp) -    { -        std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); -        bool can_parse = false; -        lldb::offset_t offset = 0; -        m_data.SetByteOrder (endian::InlHostByteOrder()); -        // Leave magic in the original byte order -        m_header.magic = m_data.GetU32(&offset); -        switch (m_header.magic) -        { -        case MH_MAGIC: -            m_data.SetByteOrder (endian::InlHostByteOrder()); -            m_data.SetAddressByteSize(4); -            can_parse = true; -            break; - -        case MH_MAGIC_64: -            m_data.SetByteOrder (endian::InlHostByteOrder()); -            m_data.SetAddressByteSize(8); -            can_parse = true; -            break; - -        case MH_CIGAM: -            m_data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig); -            m_data.SetAddressByteSize(4); -            can_parse = true; -            break; - -        case MH_CIGAM_64: -            m_data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig ? eByteOrderLittle : eByteOrderBig); -            m_data.SetAddressByteSize(8); -            can_parse = true; -            break; - -        default: -            break; -        } - -        if (can_parse) -        { -            m_data.GetU32(&offset, &m_header.cputype, 6); +bool ObjectFileMachO::ParseHeader() { +  ModuleSP module_sp(GetModule()); +  if (module_sp) { +    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); +    bool can_parse = false; +    lldb::offset_t offset = 0; +    m_data.SetByteOrder(endian::InlHostByteOrder()); +    // Leave magic in the original byte order +    m_header.magic = m_data.GetU32(&offset); +    switch (m_header.magic) { +    case MH_MAGIC: +      m_data.SetByteOrder(endian::InlHostByteOrder()); +      m_data.SetAddressByteSize(4); +      can_parse = true; +      break; + +    case MH_MAGIC_64: +      m_data.SetByteOrder(endian::InlHostByteOrder()); +      m_data.SetAddressByteSize(8); +      can_parse = true; +      break; + +    case MH_CIGAM: +      m_data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig +                              ? eByteOrderLittle +                              : eByteOrderBig); +      m_data.SetAddressByteSize(4); +      can_parse = true; +      break; + +    case MH_CIGAM_64: +      m_data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig +                              ? eByteOrderLittle +                              : eByteOrderBig); +      m_data.SetAddressByteSize(8); +      can_parse = true; +      break; + +    default: +      break; +    } -             -            ArchSpec mach_arch; -             -            if (GetArchitecture (mach_arch)) -            { -                // Check if the module has a required architecture -                const ArchSpec &module_arch = module_sp->GetArchitecture(); -                if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch)) -                    return false; - -                if (SetModulesArchitecture (mach_arch)) -                { -                    const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic); -                    if (m_data.GetByteSize() < header_and_lc_size) -                    { -                        DataBufferSP data_sp; -                        ProcessSP process_sp (m_process_wp.lock()); -                        if (process_sp) -                        { -                            data_sp = ReadMemory (process_sp, m_memory_addr, header_and_lc_size); -                        } -                        else -                        { -                            // Read in all only the load command data from the file on disk -                            data_sp = m_file.ReadFileContents(m_file_offset, header_and_lc_size); -                            if (data_sp->GetByteSize() != header_and_lc_size) -                                return false; -                        } -                        if (data_sp) -                            m_data.SetData (data_sp); -                    } -                } -                return true; +    if (can_parse) { +      m_data.GetU32(&offset, &m_header.cputype, 6); + +      ArchSpec mach_arch; + +      if (GetArchitecture(mach_arch)) { +        // Check if the module has a required architecture +        const ArchSpec &module_arch = module_sp->GetArchitecture(); +        if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch)) +          return false; + +        if (SetModulesArchitecture(mach_arch)) { +          const size_t header_and_lc_size = +              m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic); +          if (m_data.GetByteSize() < header_and_lc_size) { +            DataBufferSP data_sp; +            ProcessSP process_sp(m_process_wp.lock()); +            if (process_sp) { +              data_sp = +                  ReadMemory(process_sp, m_memory_addr, header_and_lc_size); +            } else { +              // Read in all only the load command data from the file on disk +              data_sp = +                  m_file.ReadFileContents(m_file_offset, header_and_lc_size); +              if (data_sp->GetByteSize() != header_and_lc_size) +                return false;              } +            if (data_sp) +              m_data.SetData(data_sp); +          }          } -        else -        { -            memset(&m_header, 0, sizeof(struct mach_header)); -        } +        return true; +      } +    } else { +      memset(&m_header, 0, sizeof(struct mach_header));      } -    return false; +  } +  return false;  } -ByteOrder -ObjectFileMachO::GetByteOrder () const -{ -    return m_data.GetByteOrder (); +ByteOrder ObjectFileMachO::GetByteOrder() const { +  return m_data.GetByteOrder();  } -bool -ObjectFileMachO::IsExecutable() const -{ -    return m_header.filetype == MH_EXECUTE; +bool ObjectFileMachO::IsExecutable() const { +  return m_header.filetype == MH_EXECUTE;  } -uint32_t -ObjectFileMachO::GetAddressByteSize () const -{ -    return m_data.GetAddressByteSize (); +uint32_t ObjectFileMachO::GetAddressByteSize() const { +  return m_data.GetAddressByteSize();  } -AddressClass -ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr) -{ -    Symtab *symtab = GetSymtab(); -    if (symtab) -    { -        Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr); -        if (symbol) -        { -            if (symbol->ValueIsAddress()) -            { -                SectionSP section_sp (symbol->GetAddressRef().GetSection()); -                if (section_sp) -                { -                    const lldb::SectionType section_type = section_sp->GetType(); -                    switch (section_type) -                    { -                    case eSectionTypeInvalid: -                        return eAddressClassUnknown; - -                    case eSectionTypeCode: -                        if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM) -                        { -                            // For ARM we have a bit in the n_desc field of the symbol -                            // that tells us ARM/Thumb which is bit 0x0008. -                            if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB) -                                return eAddressClassCodeAlternateISA; -                        } -                        return eAddressClassCode; - -                    case eSectionTypeContainer: -                        return eAddressClassUnknown; - -                    case eSectionTypeData: -                    case eSectionTypeDataCString: -                    case eSectionTypeDataCStringPointers: -                    case eSectionTypeDataSymbolAddress: -                    case eSectionTypeData4: -                    case eSectionTypeData8: -                    case eSectionTypeData16: -                    case eSectionTypeDataPointers: -                    case eSectionTypeZeroFill: -                    case eSectionTypeDataObjCMessageRefs: -                    case eSectionTypeDataObjCCFStrings: -                    case eSectionTypeGoSymtab: -                        return eAddressClassData; - -                    case eSectionTypeDebug: -                    case eSectionTypeDWARFDebugAbbrev: -                    case eSectionTypeDWARFDebugAddr: -                    case eSectionTypeDWARFDebugAranges: -                    case eSectionTypeDWARFDebugFrame: -                    case eSectionTypeDWARFDebugInfo: -                    case eSectionTypeDWARFDebugLine: -                    case eSectionTypeDWARFDebugLoc: -                    case eSectionTypeDWARFDebugMacInfo: -                    case eSectionTypeDWARFDebugMacro: -                    case eSectionTypeDWARFDebugPubNames: -                    case eSectionTypeDWARFDebugPubTypes: -                    case eSectionTypeDWARFDebugRanges: -                    case eSectionTypeDWARFDebugStr: -                    case eSectionTypeDWARFDebugStrOffsets: -                    case eSectionTypeDWARFAppleNames: -                    case eSectionTypeDWARFAppleTypes: -                    case eSectionTypeDWARFAppleNamespaces: -                    case eSectionTypeDWARFAppleObjC: -                        return eAddressClassDebug; - -                    case eSectionTypeEHFrame: -                    case eSectionTypeARMexidx: -                    case eSectionTypeARMextab: -                    case eSectionTypeCompactUnwind: -                        return eAddressClassRuntime; - -                    case eSectionTypeAbsoluteAddress: -                    case eSectionTypeELFSymbolTable: -                    case eSectionTypeELFDynamicSymbols: -                    case eSectionTypeELFRelocationEntries: -                    case eSectionTypeELFDynamicLinkInfo: -                    case eSectionTypeOther: -                        return eAddressClassUnknown; -                    } -                } -            } - -            const SymbolType symbol_type = symbol->GetType(); -            switch (symbol_type) -            { -            case eSymbolTypeAny:            return eAddressClassUnknown; -            case eSymbolTypeAbsolute:       return eAddressClassUnknown; - -            case eSymbolTypeCode: -            case eSymbolTypeTrampoline: -            case eSymbolTypeResolver: -                if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM) -                { -                    // For ARM we have a bit in the n_desc field of the symbol -                    // that tells us ARM/Thumb which is bit 0x0008. -                    if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB) -                        return eAddressClassCodeAlternateISA; -                } -                return eAddressClassCode; - -            case eSymbolTypeData:           return eAddressClassData; -            case eSymbolTypeRuntime:        return eAddressClassRuntime; -            case eSymbolTypeException:      return eAddressClassRuntime; -            case eSymbolTypeSourceFile:     return eAddressClassDebug; -            case eSymbolTypeHeaderFile:     return eAddressClassDebug; -            case eSymbolTypeObjectFile:     return eAddressClassDebug; -            case eSymbolTypeCommonBlock:    return eAddressClassDebug; -            case eSymbolTypeBlock:          return eAddressClassDebug; -            case eSymbolTypeLocal:          return eAddressClassData; -            case eSymbolTypeParam:          return eAddressClassData; -            case eSymbolTypeVariable:       return eAddressClassData; -            case eSymbolTypeVariableType:   return eAddressClassDebug; -            case eSymbolTypeLineEntry:      return eAddressClassDebug; -            case eSymbolTypeLineHeader:     return eAddressClassDebug; -            case eSymbolTypeScopeBegin:     return eAddressClassDebug; -            case eSymbolTypeScopeEnd:       return eAddressClassDebug; -            case eSymbolTypeAdditional:     return eAddressClassUnknown; -            case eSymbolTypeCompiler:       return eAddressClassDebug; -            case eSymbolTypeInstrumentation:return eAddressClassDebug; -            case eSymbolTypeUndefined:      return eAddressClassUnknown; -            case eSymbolTypeObjCClass:      return eAddressClassRuntime; -            case eSymbolTypeObjCMetaClass:  return eAddressClassRuntime; -            case eSymbolTypeObjCIVar:       return eAddressClassRuntime; -            case eSymbolTypeReExported:     return eAddressClassRuntime; +AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) { +  Symtab *symtab = GetSymtab(); +  if (symtab) { +    Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr); +    if (symbol) { +      if (symbol->ValueIsAddress()) { +        SectionSP section_sp(symbol->GetAddressRef().GetSection()); +        if (section_sp) { +          const lldb::SectionType section_type = section_sp->GetType(); +          switch (section_type) { +          case eSectionTypeInvalid: +            return eAddressClassUnknown; + +          case eSectionTypeCode: +            if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM) { +              // For ARM we have a bit in the n_desc field of the symbol +              // that tells us ARM/Thumb which is bit 0x0008. +              if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB) +                return eAddressClassCodeAlternateISA;              } +            return eAddressClassCode; + +          case eSectionTypeContainer: +            return eAddressClassUnknown; + +          case eSectionTypeData: +          case eSectionTypeDataCString: +          case eSectionTypeDataCStringPointers: +          case eSectionTypeDataSymbolAddress: +          case eSectionTypeData4: +          case eSectionTypeData8: +          case eSectionTypeData16: +          case eSectionTypeDataPointers: +          case eSectionTypeZeroFill: +          case eSectionTypeDataObjCMessageRefs: +          case eSectionTypeDataObjCCFStrings: +          case eSectionTypeGoSymtab: +            return eAddressClassData; + +          case eSectionTypeDebug: +          case eSectionTypeDWARFDebugAbbrev: +          case eSectionTypeDWARFDebugAddr: +          case eSectionTypeDWARFDebugAranges: +          case eSectionTypeDWARFDebugFrame: +          case eSectionTypeDWARFDebugInfo: +          case eSectionTypeDWARFDebugLine: +          case eSectionTypeDWARFDebugLoc: +          case eSectionTypeDWARFDebugMacInfo: +          case eSectionTypeDWARFDebugMacro: +          case eSectionTypeDWARFDebugPubNames: +          case eSectionTypeDWARFDebugPubTypes: +          case eSectionTypeDWARFDebugRanges: +          case eSectionTypeDWARFDebugStr: +          case eSectionTypeDWARFDebugStrOffsets: +          case eSectionTypeDWARFAppleNames: +          case eSectionTypeDWARFAppleTypes: +          case eSectionTypeDWARFAppleNamespaces: +          case eSectionTypeDWARFAppleObjC: +            return eAddressClassDebug; + +          case eSectionTypeEHFrame: +          case eSectionTypeARMexidx: +          case eSectionTypeARMextab: +          case eSectionTypeCompactUnwind: +            return eAddressClassRuntime; + +          case eSectionTypeAbsoluteAddress: +          case eSectionTypeELFSymbolTable: +          case eSectionTypeELFDynamicSymbols: +          case eSectionTypeELFRelocationEntries: +          case eSectionTypeELFDynamicLinkInfo: +          case eSectionTypeOther: +            return eAddressClassUnknown; +          }          } +      } + +      const SymbolType symbol_type = symbol->GetType(); +      switch (symbol_type) { +      case eSymbolTypeAny: +        return eAddressClassUnknown; +      case eSymbolTypeAbsolute: +        return eAddressClassUnknown; + +      case eSymbolTypeCode: +      case eSymbolTypeTrampoline: +      case eSymbolTypeResolver: +        if (m_header.cputype == llvm::MachO::CPU_TYPE_ARM) { +          // For ARM we have a bit in the n_desc field of the symbol +          // that tells us ARM/Thumb which is bit 0x0008. +          if (symbol->GetFlags() & MACHO_NLIST_ARM_SYMBOL_IS_THUMB) +            return eAddressClassCodeAlternateISA; +        } +        return eAddressClassCode; + +      case eSymbolTypeData: +        return eAddressClassData; +      case eSymbolTypeRuntime: +        return eAddressClassRuntime; +      case eSymbolTypeException: +        return eAddressClassRuntime; +      case eSymbolTypeSourceFile: +        return eAddressClassDebug; +      case eSymbolTypeHeaderFile: +        return eAddressClassDebug; +      case eSymbolTypeObjectFile: +        return eAddressClassDebug; +      case eSymbolTypeCommonBlock: +        return eAddressClassDebug; +      case eSymbolTypeBlock: +        return eAddressClassDebug; +      case eSymbolTypeLocal: +        return eAddressClassData; +      case eSymbolTypeParam: +        return eAddressClassData; +      case eSymbolTypeVariable: +        return eAddressClassData; +      case eSymbolTypeVariableType: +        return eAddressClassDebug; +      case eSymbolTypeLineEntry: +        return eAddressClassDebug; +      case eSymbolTypeLineHeader: +        return eAddressClassDebug; +      case eSymbolTypeScopeBegin: +        return eAddressClassDebug; +      case eSymbolTypeScopeEnd: +        return eAddressClassDebug; +      case eSymbolTypeAdditional: +        return eAddressClassUnknown; +      case eSymbolTypeCompiler: +        return eAddressClassDebug; +      case eSymbolTypeInstrumentation: +        return eAddressClassDebug; +      case eSymbolTypeUndefined: +        return eAddressClassUnknown; +      case eSymbolTypeObjCClass: +        return eAddressClassRuntime; +      case eSymbolTypeObjCMetaClass: +        return eAddressClassRuntime; +      case eSymbolTypeObjCIVar: +        return eAddressClassRuntime; +      case eSymbolTypeReExported: +        return eAddressClassRuntime; +      } +    } +  } +  return eAddressClassUnknown; +} + +Symtab *ObjectFileMachO::GetSymtab() { +  ModuleSP module_sp(GetModule()); +  if (module_sp) { +    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); +    if (m_symtab_ap.get() == NULL) { +      m_symtab_ap.reset(new Symtab(this)); +      std::lock_guard<std::recursive_mutex> symtab_guard( +          m_symtab_ap->GetMutex()); +      ParseSymtab(); +      m_symtab_ap->Finalize();      } -    return eAddressClassUnknown; +  } +  return m_symtab_ap.get();  } -Symtab * -ObjectFileMachO::GetSymtab() -{ +bool ObjectFileMachO::IsStripped() { +  if (m_dysymtab.cmd == 0) {      ModuleSP module_sp(GetModule()); -    if (module_sp) -    { -        std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); -        if (m_symtab_ap.get() == NULL) -        { -            m_symtab_ap.reset(new Symtab(this)); -            std::lock_guard<std::recursive_mutex> symtab_guard(m_symtab_ap->GetMutex()); -            ParseSymtab (); -            m_symtab_ap->Finalize (); +    if (module_sp) { +      lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); +      for (uint32_t i = 0; i < m_header.ncmds; ++i) { +        const lldb::offset_t load_cmd_offset = offset; + +        load_command lc; +        if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL) +          break; +        if (lc.cmd == LC_DYSYMTAB) { +          m_dysymtab.cmd = lc.cmd; +          m_dysymtab.cmdsize = lc.cmdsize; +          if (m_data.GetU32(&offset, &m_dysymtab.ilocalsym, +                            (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2) == +              NULL) { +            // Clear m_dysymtab if we were unable to read all items from the +            // load command +            ::memset(&m_dysymtab, 0, sizeof(m_dysymtab)); +          }          } +        offset = load_cmd_offset + lc.cmdsize; +      }      } -    return m_symtab_ap.get(); +  } +  if (m_dysymtab.cmd) +    return m_dysymtab.nlocalsym <= 1; +  return false;  } -bool -ObjectFileMachO::IsStripped () -{ -    if (m_dysymtab.cmd == 0) -    { -        ModuleSP module_sp(GetModule()); -        if (module_sp) -        { -            lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); -            for (uint32_t i=0; i<m_header.ncmds; ++i) -            { -                const lldb::offset_t load_cmd_offset = offset; -                 -                load_command lc; -                if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL) -                    break; -                if (lc.cmd == LC_DYSYMTAB) -                { -                    m_dysymtab.cmd = lc.cmd; -                    m_dysymtab.cmdsize = lc.cmdsize; -                    if (m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2) == NULL) -                    { -                        // Clear m_dysymtab if we were unable to read all items from the load command -                        ::memset (&m_dysymtab, 0, sizeof(m_dysymtab)); -                    } -                } -                offset = load_cmd_offset + lc.cmdsize; -            } +void ObjectFileMachO::CreateSections(SectionList &unified_section_list) { +  if (!m_sections_ap.get()) { +    m_sections_ap.reset(new SectionList()); + +    const bool is_dsym = (m_header.filetype == MH_DSYM); +    lldb::user_id_t segID = 0; +    lldb::user_id_t sectID = 0; +    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); +    uint32_t i; +    const bool is_core = GetType() == eTypeCoreFile; +    // bool dump_sections = false; +    ModuleSP module_sp(GetModule()); +    // First look up any LC_ENCRYPTION_INFO load commands +    typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges; +    EncryptedFileRanges encrypted_file_ranges; +    encryption_info_command encryption_cmd; +    for (i = 0; i < m_header.ncmds; ++i) { +      const lldb::offset_t load_cmd_offset = offset; +      if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL) +        break; + +      // LC_ENCRYPTION_INFO and LC_ENCRYPTION_INFO_64 have the same sizes for +      // the 3 fields we care about, so treat them the same. +      if (encryption_cmd.cmd == LC_ENCRYPTION_INFO || +          encryption_cmd.cmd == LC_ENCRYPTION_INFO_64) { +        if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3)) { +          if (encryption_cmd.cryptid != 0) { +            EncryptedFileRanges::Entry entry; +            entry.SetRangeBase(encryption_cmd.cryptoff); +            entry.SetByteSize(encryption_cmd.cryptsize); +            encrypted_file_ranges.Append(entry); +          }          } +      } +      offset = load_cmd_offset + encryption_cmd.cmdsize;      } -    if (m_dysymtab.cmd) -        return m_dysymtab.nlocalsym <= 1; -    return false; -} -void -ObjectFileMachO::CreateSections (SectionList &unified_section_list) -{ -    if (!m_sections_ap.get()) -    { -        m_sections_ap.reset(new SectionList()); -         -        const bool is_dsym = (m_header.filetype == MH_DSYM); -        lldb::user_id_t segID = 0; -        lldb::user_id_t sectID = 0; -        lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); -        uint32_t i; -        const bool is_core = GetType() == eTypeCoreFile; -        //bool dump_sections = false; -        ModuleSP module_sp (GetModule()); -        // First look up any LC_ENCRYPTION_INFO load commands -        typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges; -        EncryptedFileRanges encrypted_file_ranges; -        encryption_info_command encryption_cmd; -        for (i=0; i<m_header.ncmds; ++i) -        { -            const lldb::offset_t load_cmd_offset = offset; -            if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL) -                break; +    bool section_file_addresses_changed = false; + +    offset = MachHeaderSizeFromMagic(m_header.magic); + +    struct segment_command_64 load_cmd; +    for (i = 0; i < m_header.ncmds; ++i) { +      const lldb::offset_t load_cmd_offset = offset; +      if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) +        break; + +      if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64) { +        if (m_data.GetU8(&offset, (uint8_t *)load_cmd.segname, 16)) { +          bool add_section = true; +          bool add_to_unified = true; +          ConstString const_segname(load_cmd.segname, +                                    std::min<size_t>(strlen(load_cmd.segname), +                                                     sizeof(load_cmd.segname))); + +          SectionSP unified_section_sp( +              unified_section_list.FindSectionByName(const_segname)); +          if (is_dsym && unified_section_sp) { +            if (const_segname == GetSegmentNameLINKEDIT()) { +              // We need to keep the __LINKEDIT segment private to this object +              // file only +              add_to_unified = false; +            } else { +              // This is the dSYM file and this section has already been created +              // by +              // the object file, no need to create it. +              add_section = false; +            } +          } +          load_cmd.vmaddr = m_data.GetAddress(&offset); +          load_cmd.vmsize = m_data.GetAddress(&offset); +          load_cmd.fileoff = m_data.GetAddress(&offset); +          load_cmd.filesize = m_data.GetAddress(&offset); +          if (m_length != 0 && load_cmd.filesize != 0) { +            if (load_cmd.fileoff > m_length) { +              // We have a load command that says it extends past the end of the +              // file.  This is likely +              // a corrupt file.  We don't have any way to return an error +              // condition here (this method +              // was likely invoked from something like +              // ObjectFile::GetSectionList()) -- all we can do +              // is null out the SectionList vector and if a process has been +              // set up, dump a message +              // to stdout.  The most common case here is core file debugging +              // with a truncated file. +              const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 +                                                ? "LC_SEGMENT_64" +                                                : "LC_SEGMENT"; +              module_sp->ReportWarning( +                  "load command %u %s has a fileoff (0x%" PRIx64 +                  ") that extends beyond the end of the file (0x%" PRIx64 +                  "), ignoring this section", +                  i, lc_segment_name, load_cmd.fileoff, m_length); + +              load_cmd.fileoff = 0; +              load_cmd.filesize = 0; +            } -            // LC_ENCRYPTION_INFO and LC_ENCRYPTION_INFO_64 have the same sizes for -            // the 3 fields we care about, so treat them the same. -            if (encryption_cmd.cmd == LC_ENCRYPTION_INFO || encryption_cmd.cmd == LC_ENCRYPTION_INFO_64) -            { -                if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3)) -                { -                    if (encryption_cmd.cryptid != 0) -                    { -                        EncryptedFileRanges::Entry entry; -                        entry.SetRangeBase(encryption_cmd.cryptoff); -                        entry.SetByteSize(encryption_cmd.cryptsize); -                        encrypted_file_ranges.Append(entry); -                    } +            if (load_cmd.fileoff + load_cmd.filesize > m_length) { +              // We have a load command that says it extends past the end of the +              // file.  This is likely +              // a corrupt file.  We don't have any way to return an error +              // condition here (this method +              // was likely invoked from something like +              // ObjectFile::GetSectionList()) -- all we can do +              // is null out the SectionList vector and if a process has been +              // set up, dump a message +              // to stdout.  The most common case here is core file debugging +              // with a truncated file. +              const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 +                                                ? "LC_SEGMENT_64" +                                                : "LC_SEGMENT"; +              GetModule()->ReportWarning( +                  "load command %u %s has a fileoff + filesize (0x%" PRIx64 +                  ") that extends beyond the end of the file (0x%" PRIx64 +                  "), the segment will be truncated to match", +                  i, lc_segment_name, load_cmd.fileoff + load_cmd.filesize, +                  m_length); + +              // Tuncase the length +              load_cmd.filesize = m_length - load_cmd.fileoff; +            } +          } +          if (m_data.GetU32(&offset, &load_cmd.maxprot, 4)) { +            uint32_t segment_permissions = 0; +            if (load_cmd.initprot & VM_PROT_READ) +              segment_permissions |= ePermissionsReadable; +            if (load_cmd.initprot & VM_PROT_WRITE) +              segment_permissions |= ePermissionsWritable; +            if (load_cmd.initprot & VM_PROT_EXECUTE) +              segment_permissions |= ePermissionsExecutable; + +            const bool segment_is_encrypted = +                (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0; + +            // Keep a list of mach segments around in case we need to +            // get at data that isn't stored in the abstracted Sections. +            m_mach_segments.push_back(load_cmd); + +            // Use a segment ID of the segment index shifted left by 8 so they +            // never conflict with any of the sections. +            SectionSP segment_sp; +            if (add_section && (const_segname || is_core)) { +              segment_sp.reset(new Section( +                  module_sp,     // Module to which this section belongs +                  this,          // Object file to which this sections belongs +                  ++segID << 8,  // Section ID is the 1 based segment index +                                 // shifted right by 8 bits as not to collide +                                 // with any of the 256 section IDs that are +                                 // possible +                  const_segname, // Name of this section +                  eSectionTypeContainer, // This section is a container of other +                                         // sections. +                  load_cmd.vmaddr,   // File VM address == addresses as they are +                                     // found in the object file +                  load_cmd.vmsize,   // VM size in bytes of this section +                  load_cmd.fileoff,  // Offset to the data for this section in +                                     // the file +                  load_cmd.filesize, // Size in bytes of this section as found +                                     // in the file +                  0,                 // Segments have no alignment information +                  load_cmd.flags));  // Flags for this section + +              segment_sp->SetIsEncrypted(segment_is_encrypted); +              m_sections_ap->AddSection(segment_sp); +              segment_sp->SetPermissions(segment_permissions); +              if (add_to_unified) +                unified_section_list.AddSection(segment_sp); +            } else if (unified_section_sp) { +              if (is_dsym && +                  unified_section_sp->GetFileAddress() != load_cmd.vmaddr) { +                // Check to see if the module was read from memory? +                if (module_sp->GetObjectFile()->GetHeaderAddress().IsValid()) { +                  // We have a module that is in memory and needs to have its +                  // file address adjusted. We need to do this because when we +                  // load a file from memory, its addresses will be slid +                  // already, +                  // yet the addresses in the new symbol file will still be +                  // unslid. +                  // Since everything is stored as section offset, this +                  // shouldn't +                  // cause any problems. + +                  // Make sure we've parsed the symbol table from the +                  // ObjectFile before we go around changing its Sections. +                  module_sp->GetObjectFile()->GetSymtab(); +                  // eh_frame would present the same problems but we parse that +                  // on +                  // a per-function basis as-needed so it's more difficult to +                  // remove its use of the Sections.  Realistically, the +                  // environments +                  // where this code path will be taken will not have eh_frame +                  // sections. + +                  unified_section_sp->SetFileAddress(load_cmd.vmaddr); + +                  // Notify the module that the section addresses have been +                  // changed once +                  // we're done so any file-address caches can be updated. +                  section_file_addresses_changed = true;                  } +              } +              m_sections_ap->AddSection(unified_section_sp);              } -            offset = load_cmd_offset + encryption_cmd.cmdsize; -        } -        bool section_file_addresses_changed = false; - -        offset = MachHeaderSizeFromMagic(m_header.magic); +            struct section_64 sect64; +            ::memset(§64, 0, sizeof(sect64)); +            // Push a section into our mach sections for the section at +            // index zero (NO_SECT) if we don't have any mach sections yet... +            if (m_mach_sections.empty()) +              m_mach_sections.push_back(sect64); +            uint32_t segment_sect_idx; +            const lldb::user_id_t first_segment_sectID = sectID + 1; + +            const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8; +            for (segment_sect_idx = 0; segment_sect_idx < load_cmd.nsects; +                 ++segment_sect_idx) { +              if (m_data.GetU8(&offset, (uint8_t *)sect64.sectname, +                               sizeof(sect64.sectname)) == NULL) +                break; +              if (m_data.GetU8(&offset, (uint8_t *)sect64.segname, +                               sizeof(sect64.segname)) == NULL) +                break; +              sect64.addr = m_data.GetAddress(&offset); +              sect64.size = m_data.GetAddress(&offset); -        struct segment_command_64 load_cmd; -        for (i=0; i<m_header.ncmds; ++i) -        { -            const lldb::offset_t load_cmd_offset = offset; -            if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) +              if (m_data.GetU32(&offset, §64.offset, num_u32s) == NULL)                  break; -            if (load_cmd.cmd == LC_SEGMENT || load_cmd.cmd == LC_SEGMENT_64) -            { -                if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16)) -                { -                    bool add_section = true; -                    bool add_to_unified = true; -                    ConstString const_segname (load_cmd.segname, std::min<size_t>(strlen(load_cmd.segname), sizeof(load_cmd.segname))); - -                    SectionSP unified_section_sp(unified_section_list.FindSectionByName(const_segname)); -                    if (is_dsym && unified_section_sp) -                    { -                        if (const_segname == GetSegmentNameLINKEDIT()) -                        { -                            // We need to keep the __LINKEDIT segment private to this object file only -                            add_to_unified = false; -                        } -                        else -                        { -                            // This is the dSYM file and this section has already been created by -                            // the object file, no need to create it. -                            add_section = false; -                        } +              // Keep a list of mach sections around in case we need to +              // get at data that isn't stored in the abstracted Sections. +              m_mach_sections.push_back(sect64); + +              if (add_section) { +                ConstString section_name( +                    sect64.sectname, std::min<size_t>(strlen(sect64.sectname), +                                                      sizeof(sect64.sectname))); +                if (!const_segname) { +                  // We have a segment with no name so we need to conjure up +                  // segments that correspond to the section's segname if there +                  // isn't already such a section. If there is such a section, +                  // we resize the section so that it spans all sections. +                  // We also mark these sections as fake so address matches +                  // don't +                  // hit if they land in the gaps between the child sections. +                  const_segname.SetTrimmedCStringWithLength( +                      sect64.segname, sizeof(sect64.segname)); +                  segment_sp = +                      unified_section_list.FindSectionByName(const_segname); +                  if (segment_sp.get()) { +                    Section *segment = segment_sp.get(); +                    // Grow the section size as needed. +                    const lldb::addr_t sect64_min_addr = sect64.addr; +                    const lldb::addr_t sect64_max_addr = +                        sect64_min_addr + sect64.size; +                    const lldb::addr_t curr_seg_byte_size = +                        segment->GetByteSize(); +                    const lldb::addr_t curr_seg_min_addr = +                        segment->GetFileAddress(); +                    const lldb::addr_t curr_seg_max_addr = +                        curr_seg_min_addr + curr_seg_byte_size; +                    if (sect64_min_addr >= curr_seg_min_addr) { +                      const lldb::addr_t new_seg_byte_size = +                          sect64_max_addr - curr_seg_min_addr; +                      // Only grow the section size if needed +                      if (new_seg_byte_size > curr_seg_byte_size) +                        segment->SetByteSize(new_seg_byte_size); +                    } else { +                      // We need to change the base address of the segment and +                      // adjust the child section offsets for all existing +                      // children. +                      const lldb::addr_t slide_amount = +                          sect64_min_addr - curr_seg_min_addr; +                      segment->Slide(slide_amount, false); +                      segment->GetChildren().Slide(-slide_amount, false); +                      segment->SetByteSize(curr_seg_max_addr - sect64_min_addr);                      } -                    load_cmd.vmaddr = m_data.GetAddress(&offset); -                    load_cmd.vmsize = m_data.GetAddress(&offset); -                    load_cmd.fileoff = m_data.GetAddress(&offset); -                    load_cmd.filesize = m_data.GetAddress(&offset); -                    if (m_length != 0 && load_cmd.filesize != 0) -                    { -                        if (load_cmd.fileoff > m_length) -                        { -                            // We have a load command that says it extends past the end of the file.  This is likely -                            // a corrupt file.  We don't have any way to return an error condition here (this method -                            // was likely invoked from something like ObjectFile::GetSectionList()) -- all we can do -                            // is null out the SectionList vector and if a process has been set up, dump a message -                            // to stdout.  The most common case here is core file debugging with a truncated file. -                            const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT"; -                            module_sp->ReportWarning("load command %u %s has a fileoff (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 "), ignoring this section", -                                                   i, -                                                   lc_segment_name, -                                                   load_cmd.fileoff, -                                                   m_length); -                             -                            load_cmd.fileoff = 0; -                            load_cmd.filesize = 0; -                        } -                         -                        if (load_cmd.fileoff + load_cmd.filesize > m_length) -                        { -                            // We have a load command that says it extends past the end of the file.  This is likely -                            // a corrupt file.  We don't have any way to return an error condition here (this method -                            // was likely invoked from something like ObjectFile::GetSectionList()) -- all we can do -                            // is null out the SectionList vector and if a process has been set up, dump a message -                            // to stdout.  The most common case here is core file debugging with a truncated file. -                            const char *lc_segment_name = load_cmd.cmd == LC_SEGMENT_64 ? "LC_SEGMENT_64" : "LC_SEGMENT"; -                            GetModule()->ReportWarning("load command %u %s has a fileoff + filesize (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 "), the segment will be truncated to match", -                                                     i, -                                                     lc_segment_name, -                                                     load_cmd.fileoff + load_cmd.filesize, -                                                     m_length); -                             -                            // Tuncase the length -                            load_cmd.filesize = m_length - load_cmd.fileoff; -                        } -                    } -                    if (m_data.GetU32(&offset, &load_cmd.maxprot, 4)) -                    { -                        const uint32_t segment_permissions = -                            ((load_cmd.initprot & VM_PROT_READ) ? ePermissionsReadable : 0) | -                            ((load_cmd.initprot & VM_PROT_WRITE) ? ePermissionsWritable : 0) | -                            ((load_cmd.initprot & VM_PROT_EXECUTE) ? ePermissionsExecutable : 0); - -                        const bool segment_is_encrypted = (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0; - -                        // Keep a list of mach segments around in case we need to -                        // get at data that isn't stored in the abstracted Sections. -                        m_mach_segments.push_back (load_cmd); - -                        // Use a segment ID of the segment index shifted left by 8 so they -                        // never conflict with any of the sections. -                        SectionSP segment_sp; -                        if (add_section && (const_segname || is_core)) -                        { -                            segment_sp.reset(new Section (module_sp,              // Module to which this section belongs -                                                          this,                   // Object file to which this sections belongs -                                                          ++segID << 8,           // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible -                                                          const_segname,          // Name of this section -                                                          eSectionTypeContainer,  // This section is a container of other sections. -                                                          load_cmd.vmaddr,        // File VM address == addresses as they are found in the object file -                                                          load_cmd.vmsize,        // VM size in bytes of this section -                                                          load_cmd.fileoff,       // Offset to the data for this section in the file -                                                          load_cmd.filesize,      // Size in bytes of this section as found in the file -                                                          0,                      // Segments have no alignment information -                                                          load_cmd.flags));       // Flags for this section - -                            segment_sp->SetIsEncrypted (segment_is_encrypted); -                            m_sections_ap->AddSection(segment_sp); -                            segment_sp->SetPermissions(segment_permissions); -                            if (add_to_unified) -                                unified_section_list.AddSection(segment_sp); -                        } -                        else if (unified_section_sp) -                        { -                            if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr) -                            { -                                // Check to see if the module was read from memory? -                                if (module_sp->GetObjectFile()->GetHeaderAddress().IsValid()) -                                { -                                    // We have a module that is in memory and needs to have its -                                    // file address adjusted. We need to do this because when we -                                    // load a file from memory, its addresses will be slid already, -                                    // yet the addresses in the new symbol file will still be unslid. -                                    // Since everything is stored as section offset, this shouldn't -                                    // cause any problems. - -                                    // Make sure we've parsed the symbol table from the  -                                    // ObjectFile before we go around changing its Sections. -                                    module_sp->GetObjectFile()->GetSymtab(); -                                    // eh_frame would present the same problems but we parse that on -                                    // a per-function basis as-needed so it's more difficult to -                                    // remove its use of the Sections.  Realistically, the environments -                                    // where this code path will be taken will not have eh_frame sections. - -                                    unified_section_sp->SetFileAddress(load_cmd.vmaddr); - -                                    // Notify the module that the section addresses have been changed once -                                    // we're done so any file-address caches can be updated. -                                    section_file_addresses_changed = true; -                                } -                            } -                            m_sections_ap->AddSection(unified_section_sp); -                        } - -                        struct section_64 sect64; -                        ::memset (§64, 0, sizeof(sect64)); -                        // Push a section into our mach sections for the section at -                        // index zero (NO_SECT) if we don't have any mach sections yet... -                        if (m_mach_sections.empty()) -                            m_mach_sections.push_back(sect64); -                        uint32_t segment_sect_idx; -                        const lldb::user_id_t first_segment_sectID = sectID + 1; - - -                        const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8; -                        for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx) -                        { -                            if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL) -                                break; -                            if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL) -                                break; -                            sect64.addr = m_data.GetAddress(&offset); -                            sect64.size = m_data.GetAddress(&offset); - -                            if (m_data.GetU32(&offset, §64.offset, num_u32s) == NULL) -                                break; - -                            // Keep a list of mach sections around in case we need to -                            // get at data that isn't stored in the abstracted Sections. -                            m_mach_sections.push_back (sect64); - -                            if (add_section) -                            { -                                ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname))); -                                if (!const_segname) -                                { -                                    // We have a segment with no name so we need to conjure up -                                    // segments that correspond to the section's segname if there -                                    // isn't already such a section. If there is such a section, -                                    // we resize the section so that it spans all sections. -                                    // We also mark these sections as fake so address matches don't -                                    // hit if they land in the gaps between the child sections. -                                    const_segname.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname)); -                                    segment_sp = unified_section_list.FindSectionByName (const_segname); -                                    if (segment_sp.get()) -                                    { -                                        Section *segment = segment_sp.get(); -                                        // Grow the section size as needed. -                                        const lldb::addr_t sect64_min_addr = sect64.addr; -                                        const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size; -                                        const lldb::addr_t curr_seg_byte_size = segment->GetByteSize(); -                                        const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress(); -                                        const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size; -                                        if (sect64_min_addr >= curr_seg_min_addr) -                                        { -                                            const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr; -                                            // Only grow the section size if needed -                                            if (new_seg_byte_size > curr_seg_byte_size) -                                                segment->SetByteSize (new_seg_byte_size); -                                        } -                                        else -                                        { -                                            // We need to change the base address of the segment and -                                            // adjust the child section offsets for all existing children. -                                            const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr; -                                            segment->Slide(slide_amount, false); -                                            segment->GetChildren().Slide(-slide_amount, false); -                                            segment->SetByteSize (curr_seg_max_addr - sect64_min_addr); -                                        } - -                                        // Grow the section size as needed. -                                        if (sect64.offset) -                                        { -                                            const lldb::addr_t segment_min_file_offset = segment->GetFileOffset(); -                                            const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize(); - -                                            const lldb::addr_t section_min_file_offset = sect64.offset; -                                            const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size; -                                            const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset); -                                            const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset; -                                            segment->SetFileOffset (new_file_offset); -                                            segment->SetFileSize (new_file_size); -                                        } -                                    } -                                    else -                                    { -                                        // Create a fake section for the section's named segment -                                        segment_sp.reset(new Section (segment_sp,            // Parent section -                                                                      module_sp,             // Module to which this section belongs -                                                                      this,                  // Object file to which this section belongs -                                                                      ++segID << 8,          // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible -                                                                      const_segname,         // Name of this section -                                                                      eSectionTypeContainer, // This section is a container of other sections. -                                                                      sect64.addr,           // File VM address == addresses as they are found in the object file -                                                                      sect64.size,           // VM size in bytes of this section -                                                                      sect64.offset,         // Offset to the data for this section in the file -                                                                      sect64.offset ? sect64.size : 0,        // Size in bytes of this section as found in the file -                                                                      sect64.align, -                                                                      load_cmd.flags));      // Flags for this section -                                        segment_sp->SetIsFake(true); -                                        segment_sp->SetPermissions(segment_permissions); -                                        m_sections_ap->AddSection(segment_sp); -                                        if (add_to_unified) -                                            unified_section_list.AddSection(segment_sp); -                                        segment_sp->SetIsEncrypted (segment_is_encrypted); -                                    } -                                } -                                assert (segment_sp.get()); - -                                lldb::SectionType sect_type = eSectionTypeOther; - -                                if (sect64.flags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS)) -                                    sect_type = eSectionTypeCode; -                                else -                                { -                                    uint32_t mach_sect_type = sect64.flags & SECTION_TYPE; -                                    static ConstString g_sect_name_objc_data ("__objc_data"); -                                    static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs"); -                                    static ConstString g_sect_name_objc_selrefs ("__objc_selrefs"); -                                    static ConstString g_sect_name_objc_classrefs ("__objc_classrefs"); -                                    static ConstString g_sect_name_objc_superrefs ("__objc_superrefs"); -                                    static ConstString g_sect_name_objc_const ("__objc_const"); -                                    static ConstString g_sect_name_objc_classlist ("__objc_classlist"); -                                    static ConstString g_sect_name_cfstring ("__cfstring"); - -                                    static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev"); -                                    static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges"); -                                    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_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_apple_names ("__apple_names"); -                                    static ConstString g_sect_name_dwarf_apple_types ("__apple_types"); -                                    static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac"); -                                    static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc"); -                                    static ConstString g_sect_name_eh_frame ("__eh_frame"); -                                    static ConstString g_sect_name_compact_unwind ("__unwind_info"); -                                    static ConstString g_sect_name_text ("__text"); -                                    static ConstString g_sect_name_data ("__data"); -                                    static ConstString g_sect_name_go_symtab ("__gosymtab"); - -                                    if (section_name == g_sect_name_dwarf_debug_abbrev) -                                        sect_type = eSectionTypeDWARFDebugAbbrev; -                                    else if (section_name == g_sect_name_dwarf_debug_aranges) -                                        sect_type = eSectionTypeDWARFDebugAranges; -                                    else if (section_name == g_sect_name_dwarf_debug_frame) -                                        sect_type = eSectionTypeDWARFDebugFrame; -                                    else if (section_name == g_sect_name_dwarf_debug_info) -                                        sect_type = eSectionTypeDWARFDebugInfo; -                                    else if (section_name == g_sect_name_dwarf_debug_line) -                                        sect_type = eSectionTypeDWARFDebugLine; -                                    else if (section_name == g_sect_name_dwarf_debug_loc) -                                        sect_type = eSectionTypeDWARFDebugLoc; -                                    else if (section_name == g_sect_name_dwarf_debug_macinfo) -                                        sect_type = eSectionTypeDWARFDebugMacInfo; -                                    else if (section_name == g_sect_name_dwarf_debug_pubnames) -                                        sect_type = eSectionTypeDWARFDebugPubNames; -                                    else if (section_name == g_sect_name_dwarf_debug_pubtypes) -                                        sect_type = eSectionTypeDWARFDebugPubTypes; -                                    else if (section_name == g_sect_name_dwarf_debug_ranges) -                                        sect_type = eSectionTypeDWARFDebugRanges; -                                    else if (section_name == g_sect_name_dwarf_debug_str) -                                        sect_type = eSectionTypeDWARFDebugStr; -                                    else if (section_name == g_sect_name_dwarf_apple_names) -                                        sect_type = eSectionTypeDWARFAppleNames; -                                    else if (section_name == g_sect_name_dwarf_apple_types) -                                        sect_type = eSectionTypeDWARFAppleTypes; -                                    else if (section_name == g_sect_name_dwarf_apple_namespaces) -                                        sect_type = eSectionTypeDWARFAppleNamespaces; -                                    else if (section_name == g_sect_name_dwarf_apple_objc) -                                        sect_type = eSectionTypeDWARFAppleObjC; -                                    else if (section_name == g_sect_name_objc_selrefs) -                                        sect_type = eSectionTypeDataCStringPointers; -                                    else if (section_name == g_sect_name_objc_msgrefs) -                                        sect_type = eSectionTypeDataObjCMessageRefs; -                                    else if (section_name == g_sect_name_eh_frame) -                                        sect_type = eSectionTypeEHFrame; -                                    else if (section_name == g_sect_name_compact_unwind) -                                        sect_type = eSectionTypeCompactUnwind; -                                    else if (section_name == g_sect_name_cfstring) -                                        sect_type = eSectionTypeDataObjCCFStrings; -                                    else if (section_name == g_sect_name_go_symtab) -                                        sect_type = eSectionTypeGoSymtab; -                                    else if (section_name == g_sect_name_objc_data || -                                             section_name == g_sect_name_objc_classrefs || -                                             section_name == g_sect_name_objc_superrefs || -                                             section_name == g_sect_name_objc_const || -                                             section_name == g_sect_name_objc_classlist) -                                    { -                                        sect_type = eSectionTypeDataPointers; -                                    } - -                                    if (sect_type == eSectionTypeOther) -                                    { -                                        switch (mach_sect_type) -                                        { -                                        // TODO: categorize sections by other flags for regular sections -                                        case S_REGULAR: -                                            if (section_name == g_sect_name_text) -                                                sect_type = eSectionTypeCode; -                                            else if (section_name == g_sect_name_data) -                                                sect_type = eSectionTypeData; -                                            else -                                                sect_type = eSectionTypeOther; -                                            break; -                                        case S_ZEROFILL:                   sect_type = eSectionTypeZeroFill; break; -                                        case S_CSTRING_LITERALS:           sect_type = eSectionTypeDataCString;    break; // section with only literal C strings -                                        case S_4BYTE_LITERALS:             sect_type = eSectionTypeData4;    break; // section with only 4 byte literals -                                        case S_8BYTE_LITERALS:             sect_type = eSectionTypeData8;    break; // section with only 8 byte literals -                                        case S_LITERAL_POINTERS:           sect_type = eSectionTypeDataPointers;  break; // section with only pointers to literals -                                        case S_NON_LAZY_SYMBOL_POINTERS:   sect_type = eSectionTypeDataPointers;  break; // section with only non-lazy symbol pointers -                                        case S_LAZY_SYMBOL_POINTERS:       sect_type = eSectionTypeDataPointers;  break; // section with only lazy symbol pointers -                                        case S_SYMBOL_STUBS:               sect_type = eSectionTypeCode;  break; // section with only symbol stubs, byte size of stub in the reserved2 field -                                        case S_MOD_INIT_FUNC_POINTERS:     sect_type = eSectionTypeDataPointers;    break; // section with only function pointers for initialization -                                        case S_MOD_TERM_FUNC_POINTERS:     sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination -                                        case S_COALESCED:                  sect_type = eSectionTypeOther; break; -                                        case S_GB_ZEROFILL:                sect_type = eSectionTypeZeroFill; break; -                                        case S_INTERPOSING:                sect_type = eSectionTypeCode;  break; // section with only pairs of function pointers for interposing -                                        case S_16BYTE_LITERALS:            sect_type = eSectionTypeData16; break; // section with only 16 byte literals -                                        case S_DTRACE_DOF:                 sect_type = eSectionTypeDebug; break; -                                        case S_LAZY_DYLIB_SYMBOL_POINTERS: sect_type = eSectionTypeDataPointers;  break; -                                        default: break; -                                        } -                                    } -                                } -                                SectionSP section_sp(new Section (segment_sp, -                                                                  module_sp, -                                                                  this, -                                                                  ++sectID, -                                                                  section_name, -                                                                  sect_type, -                                                                  sect64.addr - segment_sp->GetFileAddress(), -                                                                  sect64.size, -                                                                  sect64.offset, -                                                                  sect64.offset == 0 ? 0 : sect64.size, -                                                                  sect64.align, -                                                                  sect64.flags)); -                                // Set the section to be encrypted to match the segment - -                                bool section_is_encrypted = false; -                                if (!segment_is_encrypted && load_cmd.filesize != 0) -                                    section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL; - -                                section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted); -                                section_sp->SetPermissions(segment_permissions); -                                segment_sp->GetChildren().AddSection(section_sp); - -                                if (segment_sp->IsFake()) -                                { -                                    segment_sp.reset(); -                                    const_segname.Clear(); -                                } -                            } -                        } -                        if (segment_sp && is_dsym) -                        { -                            if (first_segment_sectID <= sectID) -                            { -                                lldb::user_id_t sect_uid; -                                for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid) -                                { -                                    SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid)); -                                    SectionSP next_section_sp; -                                    if (sect_uid + 1 <= sectID) -                                        next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1); - -                                    if (curr_section_sp.get()) -                                    { -                                        if (curr_section_sp->GetByteSize() == 0) -                                        { -                                            if (next_section_sp.get() != NULL) -                                                curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() ); -                                            else -                                                curr_section_sp->SetByteSize ( load_cmd.vmsize ); -                                        } -                                    } -                                } -                            } -                        } +                    // Grow the section size as needed. +                    if (sect64.offset) { +                      const lldb::addr_t segment_min_file_offset = +                          segment->GetFileOffset(); +                      const lldb::addr_t segment_max_file_offset = +                          segment_min_file_offset + segment->GetFileSize(); + +                      const lldb::addr_t section_min_file_offset = +                          sect64.offset; +                      const lldb::addr_t section_max_file_offset = +                          section_min_file_offset + sect64.size; +                      const lldb::addr_t new_file_offset = std::min( +                          section_min_file_offset, segment_min_file_offset); +                      const lldb::addr_t new_file_size = +                          std::max(section_max_file_offset, +                                   segment_max_file_offset) - +                          new_file_offset; +                      segment->SetFileOffset(new_file_offset); +                      segment->SetFileSize(new_file_size); +                    } +                  } else { +                    // Create a fake section for the section's named segment +                    segment_sp.reset(new Section( +                        segment_sp, // Parent section +                        module_sp,  // Module to which this section belongs +                        this,       // Object file to which this section belongs +                        ++segID << 8, // Section ID is the 1 based segment index +                                      // shifted right by 8 bits as not to +                                      // collide with any of the 256 section IDs +                                      // that are possible +                        const_segname,         // Name of this section +                        eSectionTypeContainer, // This section is a container of +                                               // other sections. +                        sect64.addr, // File VM address == addresses as they are +                                     // found in the object file +                        sect64.size, // VM size in bytes of this section +                        sect64.offset, // Offset to the data for this section in +                                       // the file +                        sect64.offset ? sect64.size : 0, // Size in bytes of +                                                         // this section as +                                                         // found in the file +                        sect64.align, +                        load_cmd.flags)); // Flags for this section +                    segment_sp->SetIsFake(true); +                    segment_sp->SetPermissions(segment_permissions); +                    m_sections_ap->AddSection(segment_sp); +                    if (add_to_unified) +                      unified_section_list.AddSection(segment_sp); +                    segment_sp->SetIsEncrypted(segment_is_encrypted); +                  } +                } +                assert(segment_sp.get()); + +                lldb::SectionType sect_type = eSectionTypeOther; + +                if (sect64.flags & +                    (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS)) +                  sect_type = eSectionTypeCode; +                else { +                  uint32_t mach_sect_type = sect64.flags & SECTION_TYPE; +                  static ConstString g_sect_name_objc_data("__objc_data"); +                  static ConstString g_sect_name_objc_msgrefs("__objc_msgrefs"); +                  static ConstString g_sect_name_objc_selrefs("__objc_selrefs"); +                  static ConstString g_sect_name_objc_classrefs( +                      "__objc_classrefs"); +                  static ConstString g_sect_name_objc_superrefs( +                      "__objc_superrefs"); +                  static ConstString g_sect_name_objc_const("__objc_const"); +                  static ConstString g_sect_name_objc_classlist( +                      "__objc_classlist"); +                  static ConstString g_sect_name_cfstring("__cfstring"); + +                  static ConstString g_sect_name_dwarf_debug_abbrev( +                      "__debug_abbrev"); +                  static ConstString g_sect_name_dwarf_debug_aranges( +                      "__debug_aranges"); +                  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_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_apple_names( +                      "__apple_names"); +                  static ConstString g_sect_name_dwarf_apple_types( +                      "__apple_types"); +                  static ConstString g_sect_name_dwarf_apple_namespaces( +                      "__apple_namespac"); +                  static ConstString g_sect_name_dwarf_apple_objc( +                      "__apple_objc"); +                  static ConstString g_sect_name_eh_frame("__eh_frame"); +                  static ConstString g_sect_name_compact_unwind( +                      "__unwind_info"); +                  static ConstString g_sect_name_text("__text"); +                  static ConstString g_sect_name_data("__data"); +                  static ConstString g_sect_name_go_symtab("__gosymtab"); + +                  if (section_name == g_sect_name_dwarf_debug_abbrev) +                    sect_type = eSectionTypeDWARFDebugAbbrev; +                  else if (section_name == g_sect_name_dwarf_debug_aranges) +                    sect_type = eSectionTypeDWARFDebugAranges; +                  else if (section_name == g_sect_name_dwarf_debug_frame) +                    sect_type = eSectionTypeDWARFDebugFrame; +                  else if (section_name == g_sect_name_dwarf_debug_info) +                    sect_type = eSectionTypeDWARFDebugInfo; +                  else if (section_name == g_sect_name_dwarf_debug_line) +                    sect_type = eSectionTypeDWARFDebugLine; +                  else if (section_name == g_sect_name_dwarf_debug_loc) +                    sect_type = eSectionTypeDWARFDebugLoc; +                  else if (section_name == g_sect_name_dwarf_debug_macinfo) +                    sect_type = eSectionTypeDWARFDebugMacInfo; +                  else if (section_name == g_sect_name_dwarf_debug_pubnames) +                    sect_type = eSectionTypeDWARFDebugPubNames; +                  else if (section_name == g_sect_name_dwarf_debug_pubtypes) +                    sect_type = eSectionTypeDWARFDebugPubTypes; +                  else if (section_name == g_sect_name_dwarf_debug_ranges) +                    sect_type = eSectionTypeDWARFDebugRanges; +                  else if (section_name == g_sect_name_dwarf_debug_str) +                    sect_type = eSectionTypeDWARFDebugStr; +                  else if (section_name == g_sect_name_dwarf_apple_names) +                    sect_type = eSectionTypeDWARFAppleNames; +                  else if (section_name == g_sect_name_dwarf_apple_types) +                    sect_type = eSectionTypeDWARFAppleTypes; +                  else if (section_name == g_sect_name_dwarf_apple_namespaces) +                    sect_type = eSectionTypeDWARFAppleNamespaces; +                  else if (section_name == g_sect_name_dwarf_apple_objc) +                    sect_type = eSectionTypeDWARFAppleObjC; +                  else if (section_name == g_sect_name_objc_selrefs) +                    sect_type = eSectionTypeDataCStringPointers; +                  else if (section_name == g_sect_name_objc_msgrefs) +                    sect_type = eSectionTypeDataObjCMessageRefs; +                  else if (section_name == g_sect_name_eh_frame) +                    sect_type = eSectionTypeEHFrame; +                  else if (section_name == g_sect_name_compact_unwind) +                    sect_type = eSectionTypeCompactUnwind; +                  else if (section_name == g_sect_name_cfstring) +                    sect_type = eSectionTypeDataObjCCFStrings; +                  else if (section_name == g_sect_name_go_symtab) +                    sect_type = eSectionTypeGoSymtab; +                  else if (section_name == g_sect_name_objc_data || +                           section_name == g_sect_name_objc_classrefs || +                           section_name == g_sect_name_objc_superrefs || +                           section_name == g_sect_name_objc_const || +                           section_name == g_sect_name_objc_classlist) { +                    sect_type = eSectionTypeDataPointers; +                  } + +                  if (sect_type == eSectionTypeOther) { +                    switch (mach_sect_type) { +                    // TODO: categorize sections by other flags for regular +                    // sections +                    case S_REGULAR: +                      if (section_name == g_sect_name_text) +                        sect_type = eSectionTypeCode; +                      else if (section_name == g_sect_name_data) +                        sect_type = eSectionTypeData; +                      else +                        sect_type = eSectionTypeOther; +                      break; +                    case S_ZEROFILL: +                      sect_type = eSectionTypeZeroFill; +                      break; +                    case S_CSTRING_LITERALS: +                      sect_type = eSectionTypeDataCString; +                      break; // section with only literal C strings +                    case S_4BYTE_LITERALS: +                      sect_type = eSectionTypeData4; +                      break; // section with only 4 byte literals +                    case S_8BYTE_LITERALS: +                      sect_type = eSectionTypeData8; +                      break; // section with only 8 byte literals +                    case S_LITERAL_POINTERS: +                      sect_type = eSectionTypeDataPointers; +                      break; // section with only pointers to literals +                    case S_NON_LAZY_SYMBOL_POINTERS: +                      sect_type = eSectionTypeDataPointers; +                      break; // section with only non-lazy symbol pointers +                    case S_LAZY_SYMBOL_POINTERS: +                      sect_type = eSectionTypeDataPointers; +                      break; // section with only lazy symbol pointers +                    case S_SYMBOL_STUBS: +                      sect_type = eSectionTypeCode; +                      break; // section with only symbol stubs, byte size of +                             // stub in the reserved2 field +                    case S_MOD_INIT_FUNC_POINTERS: +                      sect_type = eSectionTypeDataPointers; +                      break; // section with only function pointers for +                             // initialization +                    case S_MOD_TERM_FUNC_POINTERS: +                      sect_type = eSectionTypeDataPointers; +                      break; // section with only function pointers for +                             // termination +                    case S_COALESCED: +                      sect_type = eSectionTypeOther; +                      break; +                    case S_GB_ZEROFILL: +                      sect_type = eSectionTypeZeroFill; +                      break; +                    case S_INTERPOSING: +                      sect_type = eSectionTypeCode; +                      break; // section with only pairs of function pointers for +                             // interposing +                    case S_16BYTE_LITERALS: +                      sect_type = eSectionTypeData16; +                      break; // section with only 16 byte literals +                    case S_DTRACE_DOF: +                      sect_type = eSectionTypeDebug; +                      break; +                    case S_LAZY_DYLIB_SYMBOL_POINTERS: +                      sect_type = eSectionTypeDataPointers; +                      break; +                    default: +                      break;                      } +                  }                  } + +                SectionSP section_sp(new Section( +                    segment_sp, module_sp, this, ++sectID, section_name, +                    sect_type, sect64.addr - segment_sp->GetFileAddress(), +                    sect64.size, sect64.offset, +                    sect64.offset == 0 ? 0 : sect64.size, sect64.align, +                    sect64.flags)); +                // Set the section to be encrypted to match the segment + +                bool section_is_encrypted = false; +                if (!segment_is_encrypted && load_cmd.filesize != 0) +                  section_is_encrypted = +                      encrypted_file_ranges.FindEntryThatContains( +                          sect64.offset) != NULL; + +                section_sp->SetIsEncrypted(segment_is_encrypted || +                                           section_is_encrypted); +                section_sp->SetPermissions(segment_permissions); +                segment_sp->GetChildren().AddSection(section_sp); + +                if (segment_sp->IsFake()) { +                  segment_sp.reset(); +                  const_segname.Clear(); +                } +              }              } -            else if (load_cmd.cmd == LC_DYSYMTAB) -            { -                m_dysymtab.cmd = load_cmd.cmd; -                m_dysymtab.cmdsize = load_cmd.cmdsize; -                m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2); +            if (segment_sp && is_dsym) { +              if (first_segment_sectID <= sectID) { +                lldb::user_id_t sect_uid; +                for (sect_uid = first_segment_sectID; sect_uid <= sectID; +                     ++sect_uid) { +                  SectionSP curr_section_sp( +                      segment_sp->GetChildren().FindSectionByID(sect_uid)); +                  SectionSP next_section_sp; +                  if (sect_uid + 1 <= sectID) +                    next_section_sp = +                        segment_sp->GetChildren().FindSectionByID(sect_uid + 1); + +                  if (curr_section_sp.get()) { +                    if (curr_section_sp->GetByteSize() == 0) { +                      if (next_section_sp.get() != NULL) +                        curr_section_sp->SetByteSize( +                            next_section_sp->GetFileAddress() - +                            curr_section_sp->GetFileAddress()); +                      else +                        curr_section_sp->SetByteSize(load_cmd.vmsize); +                    } +                  } +                } +              }              } - -            offset = load_cmd_offset + load_cmd.cmdsize; +          }          } +      } else if (load_cmd.cmd == LC_DYSYMTAB) { +        m_dysymtab.cmd = load_cmd.cmd; +        m_dysymtab.cmdsize = load_cmd.cmdsize; +        m_data.GetU32(&offset, &m_dysymtab.ilocalsym, +                      (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2); +      } + +      offset = load_cmd_offset + load_cmd.cmdsize; +    } - -        if (section_file_addresses_changed && module_sp.get()) -        { -            module_sp->SectionFileAddressesChanged(); -        } +    if (section_file_addresses_changed && module_sp.get()) { +      module_sp->SectionFileAddressesChanged();      } +  }  } -class MachSymtabSectionInfo -{ +class MachSymtabSectionInfo {  public: -    MachSymtabSectionInfo (SectionList *section_list) : -        m_section_list (section_list), -        m_section_infos() -    { -        // Get the number of sections down to a depth of 1 to include -        // all segments and their sections, but no other sections that -        // may be added for debug map or -        m_section_infos.resize(section_list->GetNumSections(1)); -    } - -    SectionSP -    GetSection (uint8_t n_sect, addr_t file_addr) -    { -        if (n_sect == 0) -            return SectionSP(); -        if (n_sect < m_section_infos.size()) -        { -            if (!m_section_infos[n_sect].section_sp) -            { -                SectionSP section_sp (m_section_list->FindSectionByID (n_sect)); -                m_section_infos[n_sect].section_sp = section_sp; -                if (section_sp) -                { -                    m_section_infos[n_sect].vm_range.SetBaseAddress (section_sp->GetFileAddress()); -                    m_section_infos[n_sect].vm_range.SetByteSize (section_sp->GetByteSize()); -                } -                else -                { -                    Host::SystemLog (Host::eSystemLogError, "error: unable to find section for section %u\n", n_sect); -                } -            } -            if (m_section_infos[n_sect].vm_range.Contains(file_addr)) -            { -                // Symbol is in section. -                return m_section_infos[n_sect].section_sp; -            } -            else if (m_section_infos[n_sect].vm_range.GetByteSize () == 0 && -                     m_section_infos[n_sect].vm_range.GetBaseAddress() == file_addr) -            { -                // Symbol is in section with zero size, but has the same start -                // address as the section. This can happen with linker symbols -                // (symbols that start with the letter 'l' or 'L'. -                return m_section_infos[n_sect].section_sp; -            } +  MachSymtabSectionInfo(SectionList *section_list) +      : m_section_list(section_list), m_section_infos() { +    // Get the number of sections down to a depth of 1 to include +    // all segments and their sections, but no other sections that +    // may be added for debug map or +    m_section_infos.resize(section_list->GetNumSections(1)); +  } + +  SectionSP GetSection(uint8_t n_sect, addr_t file_addr) { +    if (n_sect == 0) +      return SectionSP(); +    if (n_sect < m_section_infos.size()) { +      if (!m_section_infos[n_sect].section_sp) { +        SectionSP section_sp(m_section_list->FindSectionByID(n_sect)); +        m_section_infos[n_sect].section_sp = section_sp; +        if (section_sp) { +          m_section_infos[n_sect].vm_range.SetBaseAddress( +              section_sp->GetFileAddress()); +          m_section_infos[n_sect].vm_range.SetByteSize( +              section_sp->GetByteSize()); +        } else { +          Host::SystemLog(Host::eSystemLogError, +                          "error: unable to find section for section %u\n", +                          n_sect);          } -        return m_section_list->FindSectionContainingFileAddress(file_addr); +      } +      if (m_section_infos[n_sect].vm_range.Contains(file_addr)) { +        // Symbol is in section. +        return m_section_infos[n_sect].section_sp; +      } else if (m_section_infos[n_sect].vm_range.GetByteSize() == 0 && +                 m_section_infos[n_sect].vm_range.GetBaseAddress() == +                     file_addr) { +        // Symbol is in section with zero size, but has the same start +        // address as the section. This can happen with linker symbols +        // (symbols that start with the letter 'l' or 'L'. +        return m_section_infos[n_sect].section_sp; +      }      } +    return m_section_list->FindSectionContainingFileAddress(file_addr); +  }  protected: -    struct SectionInfo -    { -        SectionInfo () : -            vm_range(), -            section_sp () -        { -        } - -        VMRange vm_range; -        SectionSP section_sp; -    }; -    SectionList *m_section_list; -    std::vector<SectionInfo> m_section_infos; +  struct SectionInfo { +    SectionInfo() : vm_range(), section_sp() {} + +    VMRange vm_range; +    SectionSP section_sp; +  }; +  SectionList *m_section_list; +  std::vector<SectionInfo> m_section_infos;  }; -struct TrieEntry -{ -    TrieEntry () : -        name(), -        address(LLDB_INVALID_ADDRESS), -        flags (0), -        other(0), -        import_name() -    { -    } -     -    void -    Clear () -    { -        name.Clear(); -        address = LLDB_INVALID_ADDRESS; -        flags = 0; -        other = 0; -        import_name.Clear(); -    } -     -    void -    Dump () const -    { -        printf ("0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"", -                static_cast<unsigned long long>(address), -                static_cast<unsigned long long>(flags), -                static_cast<unsigned long long>(other), name.GetCString()); -        if (import_name) -            printf (" -> \"%s\"\n", import_name.GetCString()); -        else -            printf ("\n"); -    } -    ConstString		name; -    uint64_t		address; -    uint64_t		flags; -    uint64_t		other; -    ConstString		import_name; +struct TrieEntry { +  TrieEntry() +      : name(), address(LLDB_INVALID_ADDRESS), flags(0), other(0), +        import_name() {} + +  void Clear() { +    name.Clear(); +    address = LLDB_INVALID_ADDRESS; +    flags = 0; +    other = 0; +    import_name.Clear(); +  } + +  void Dump() const { +    printf("0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"", +           static_cast<unsigned long long>(address), +           static_cast<unsigned long long>(flags), +           static_cast<unsigned long long>(other), name.GetCString()); +    if (import_name) +      printf(" -> \"%s\"\n", import_name.GetCString()); +    else +      printf("\n"); +  } +  ConstString name; +  uint64_t address; +  uint64_t flags; +  uint64_t other; +  ConstString import_name;  }; -struct TrieEntryWithOffset -{ -	lldb::offset_t nodeOffset; -	TrieEntry entry; +struct TrieEntryWithOffset { +  lldb::offset_t nodeOffset; +  TrieEntry entry; -    TrieEntryWithOffset (lldb::offset_t offset) : -        nodeOffset (offset), -        entry() -    { -    } +  TrieEntryWithOffset(lldb::offset_t offset) : nodeOffset(offset), entry() {} -    void -    Dump (uint32_t idx) const -    { -        printf ("[%3u] 0x%16.16llx: ", idx, -                static_cast<unsigned long long>(nodeOffset)); -        entry.Dump(); -    } +  void Dump(uint32_t idx) const { +    printf("[%3u] 0x%16.16llx: ", idx, +           static_cast<unsigned long long>(nodeOffset)); +    entry.Dump(); +  } -	bool -    operator<(const TrieEntryWithOffset& other) const -    { -        return ( nodeOffset < other.nodeOffset ); -    } +  bool operator<(const TrieEntryWithOffset &other) const { +    return (nodeOffset < other.nodeOffset); +  }  }; -static bool -ParseTrieEntries (DataExtractor &data, -                  lldb::offset_t offset, -                  const bool is_arm, -                  std::vector<llvm::StringRef> &nameSlices, -                  std::set<lldb::addr_t> &resolver_addresses, -                  std::vector<TrieEntryWithOffset>& output) -{ -	if (!data.ValidOffset(offset)) -        return true; - -	const uint64_t terminalSize = data.GetULEB128(&offset); -	lldb::offset_t children_offset = offset + terminalSize; -	if ( terminalSize != 0 ) { -		TrieEntryWithOffset e (offset); -		e.entry.flags = data.GetULEB128(&offset); -        const char *import_name = NULL; -		if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT ) { -			e.entry.address = 0; -			e.entry.other = data.GetULEB128(&offset); // dylib ordinal -            import_name = data.GetCStr(&offset); -		} -		else { -			e.entry.address = data.GetULEB128(&offset); -			if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER ) -            { -				e.entry.other = data.GetULEB128(&offset); -                uint64_t resolver_addr = e.entry.other; -                if (is_arm) -                    resolver_addr &= THUMB_ADDRESS_BIT_MASK; -                resolver_addresses.insert(resolver_addr); -            } -			else -				e.entry.other = 0; -		} -        // Only add symbols that are reexport symbols with a valid import name -        if (EXPORT_SYMBOL_FLAGS_REEXPORT & e.entry.flags && import_name && import_name[0]) -        { -            std::string name; -            if (!nameSlices.empty()) -            { -                for (auto name_slice: nameSlices) -                    name.append(name_slice.data(), name_slice.size()); -            } -            if (name.size() > 1) -            { -                // Skip the leading '_' -                e.entry.name.SetCStringWithLength(name.c_str() + 1,name.size() - 1); -            } -            if (import_name) -            { -                // Skip the leading '_' -                e.entry.import_name.SetCString(import_name+1);                 -            } -            output.push_back(e); -        } -	} -     -	const uint8_t childrenCount = data.GetU8(&children_offset); -	for (uint8_t i=0; i < childrenCount; ++i) { -        const char *cstr = data.GetCStr(&children_offset); -        if (cstr) -            nameSlices.push_back(llvm::StringRef(cstr)); -        else -            return false; // Corrupt data -        lldb::offset_t childNodeOffset = data.GetULEB128(&children_offset); -		if (childNodeOffset) -        { -            if (!ParseTrieEntries(data, -                                 childNodeOffset, -                                 is_arm, -                                 nameSlices, -                                 resolver_addresses, -                                 output)) -            { -                return false; -            } -        } -        nameSlices.pop_back(); -	} +static bool ParseTrieEntries(DataExtractor &data, lldb::offset_t offset, +                             const bool is_arm, +                             std::vector<llvm::StringRef> &nameSlices, +                             std::set<lldb::addr_t> &resolver_addresses, +                             std::vector<TrieEntryWithOffset> &output) { +  if (!data.ValidOffset(offset))      return true; + +  const uint64_t terminalSize = data.GetULEB128(&offset); +  lldb::offset_t children_offset = offset + terminalSize; +  if (terminalSize != 0) { +    TrieEntryWithOffset e(offset); +    e.entry.flags = data.GetULEB128(&offset); +    const char *import_name = NULL; +    if (e.entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT) { +      e.entry.address = 0; +      e.entry.other = data.GetULEB128(&offset); // dylib ordinal +      import_name = data.GetCStr(&offset); +    } else { +      e.entry.address = data.GetULEB128(&offset); +      if (e.entry.flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) { +        e.entry.other = data.GetULEB128(&offset); +        uint64_t resolver_addr = e.entry.other; +        if (is_arm) +          resolver_addr &= THUMB_ADDRESS_BIT_MASK; +        resolver_addresses.insert(resolver_addr); +      } else +        e.entry.other = 0; +    } +    // Only add symbols that are reexport symbols with a valid import name +    if (EXPORT_SYMBOL_FLAGS_REEXPORT & e.entry.flags && import_name && +        import_name[0]) { +      std::string name; +      if (!nameSlices.empty()) { +        for (auto name_slice : nameSlices) +          name.append(name_slice.data(), name_slice.size()); +      } +      if (name.size() > 1) { +        // Skip the leading '_' +        e.entry.name.SetCStringWithLength(name.c_str() + 1, name.size() - 1); +      } +      if (import_name) { +        // Skip the leading '_' +        e.entry.import_name.SetCString(import_name + 1); +      } +      output.push_back(e); +    } +  } + +  const uint8_t childrenCount = data.GetU8(&children_offset); +  for (uint8_t i = 0; i < childrenCount; ++i) { +    const char *cstr = data.GetCStr(&children_offset); +    if (cstr) +      nameSlices.push_back(llvm::StringRef(cstr)); +    else +      return false; // Corrupt data +    lldb::offset_t childNodeOffset = data.GetULEB128(&children_offset); +    if (childNodeOffset) { +      if (!ParseTrieEntries(data, childNodeOffset, is_arm, nameSlices, +                            resolver_addresses, output)) { +        return false; +      } +    } +    nameSlices.pop_back(); +  } +  return true;  }  // Read the UUID out of a dyld_shared_cache file on-disk. -UUID -ObjectFileMachO::GetSharedCacheUUID (FileSpec dyld_shared_cache, const ByteOrder byte_order, const uint32_t addr_byte_size) -{ -    UUID dsc_uuid; -    DataBufferSP dsc_data_sp = dyld_shared_cache.MemoryMapFileContentsIfLocal(0, sizeof(struct lldb_copy_dyld_cache_header_v1)); -    if (dsc_data_sp) -    { -        DataExtractor dsc_header_data (dsc_data_sp, byte_order, addr_byte_size); - -        char version_str[7]; -        lldb::offset_t offset = 0; -        memcpy (version_str, dsc_header_data.GetData (&offset, 6), 6); -        version_str[6] = '\0'; -        if (strcmp (version_str, "dyld_v") == 0) -        { -            offset = offsetof (struct lldb_copy_dyld_cache_header_v1, uuid); -            uint8_t uuid_bytes[sizeof (uuid_t)]; -            memcpy (uuid_bytes, dsc_header_data.GetData (&offset, sizeof (uuid_t)), sizeof (uuid_t)); -            dsc_uuid.SetBytes (uuid_bytes); -        } +UUID ObjectFileMachO::GetSharedCacheUUID(FileSpec dyld_shared_cache, +                                         const ByteOrder byte_order, +                                         const uint32_t addr_byte_size) { +  UUID dsc_uuid; +  DataBufferSP dsc_data_sp = dyld_shared_cache.MemoryMapFileContentsIfLocal( +      0, sizeof(struct lldb_copy_dyld_cache_header_v1)); +  if (dsc_data_sp) { +    DataExtractor dsc_header_data(dsc_data_sp, byte_order, addr_byte_size); + +    char version_str[7]; +    lldb::offset_t offset = 0; +    memcpy(version_str, dsc_header_data.GetData(&offset, 6), 6); +    version_str[6] = '\0'; +    if (strcmp(version_str, "dyld_v") == 0) { +      offset = offsetof(struct lldb_copy_dyld_cache_header_v1, uuid); +      uint8_t uuid_bytes[sizeof(uuid_t)]; +      memcpy(uuid_bytes, dsc_header_data.GetData(&offset, sizeof(uuid_t)), +             sizeof(uuid_t)); +      dsc_uuid.SetBytes(uuid_bytes);      } -    return dsc_uuid; +  } +  return dsc_uuid;  } -size_t -ObjectFileMachO::ParseSymtab () -{ -    Timer scoped_timer(__PRETTY_FUNCTION__, -                       "ObjectFileMachO::ParseSymtab () module = %s", -                       m_file.GetFilename().AsCString("")); -    ModuleSP module_sp (GetModule()); -    if (!module_sp) -        return 0; - -    struct symtab_command symtab_load_command = { 0, 0, 0, 0, 0, 0 }; -    struct linkedit_data_command function_starts_load_command = { 0, 0, 0, 0 }; -    struct dyld_info_command dyld_info = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -    typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts; -    FunctionStarts function_starts; -    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); -    uint32_t i; -    FileSpecList dylib_files; -    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS)); -    static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_"); -    static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_"); -    static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_"); - -    for (i=0; i<m_header.ncmds; ++i) -    { -        const lldb::offset_t cmd_offset = offset; -        // Read in the load command and load command size -        struct load_command lc; -        if (m_data.GetU32(&offset, &lc, 2) == NULL) -            break; -        // Watch for the symbol table load command -        switch (lc.cmd) -        { -        case LC_SYMTAB: -            symtab_load_command.cmd = lc.cmd; -            symtab_load_command.cmdsize = lc.cmdsize; -            // Read in the rest of the symtab load command -            if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) == 0) // fill in symoff, nsyms, stroff, strsize fields -                return 0; -            if (symtab_load_command.symoff == 0) -            { -                if (log) -                    module_sp->LogMessage(log, "LC_SYMTAB.symoff == 0"); -                return 0; -            } - -            if (symtab_load_command.stroff == 0) -            { -                if (log) -                    module_sp->LogMessage(log, "LC_SYMTAB.stroff == 0"); -                return 0; -            } - -            if (symtab_load_command.nsyms == 0) -            { -                if (log) -                    module_sp->LogMessage(log, "LC_SYMTAB.nsyms == 0"); -                return 0; -            } - -            if (symtab_load_command.strsize == 0) -            { -                if (log) -                    module_sp->LogMessage(log, "LC_SYMTAB.strsize == 0"); -                return 0; -            } -            break; - -        case LC_DYLD_INFO: -        case LC_DYLD_INFO_ONLY: -            if (m_data.GetU32(&offset, &dyld_info.rebase_off, 10)) -            { -                dyld_info.cmd = lc.cmd; -                dyld_info.cmdsize = lc.cmdsize; -            } -            else -            { -                memset (&dyld_info, 0, sizeof(dyld_info)); -            } -            break; +size_t ObjectFileMachO::ParseSymtab() { +  Timer scoped_timer(LLVM_PRETTY_FUNCTION, +                     "ObjectFileMachO::ParseSymtab () module = %s", +                     m_file.GetFilename().AsCString("")); +  ModuleSP module_sp(GetModule()); +  if (!module_sp) +    return 0; -        case LC_LOAD_DYLIB: -        case LC_LOAD_WEAK_DYLIB: -        case LC_REEXPORT_DYLIB: -        case LC_LOADFVMLIB: -        case LC_LOAD_UPWARD_DYLIB: -            { -                uint32_t name_offset = cmd_offset + m_data.GetU32(&offset); -                const char *path = m_data.PeekCStr(name_offset); -                if (path) -                { -                    FileSpec file_spec(path, false); -                    // Strip the path if there is @rpath, @executable, etc so we just use the basename -                    if (path[0] == '@') -                        file_spec.GetDirectory().Clear(); -                     -                    if (lc.cmd == LC_REEXPORT_DYLIB) -                    { -                        m_reexported_dylibs.AppendIfUnique(file_spec); -                    } +  struct symtab_command symtab_load_command = {0, 0, 0, 0, 0, 0}; +  struct linkedit_data_command function_starts_load_command = {0, 0, 0, 0}; +  struct dyld_info_command dyld_info = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +  typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts; +  FunctionStarts function_starts; +  lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); +  uint32_t i; +  FileSpecList dylib_files; +  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS)); +  static const llvm::StringRef g_objc_v2_prefix_class("_OBJC_CLASS_$_"); +  static const llvm::StringRef g_objc_v2_prefix_metaclass("_OBJC_METACLASS_$_"); +  static const llvm::StringRef g_objc_v2_prefix_ivar("_OBJC_IVAR_$_"); + +  for (i = 0; i < m_header.ncmds; ++i) { +    const lldb::offset_t cmd_offset = offset; +    // Read in the load command and load command size +    struct load_command lc; +    if (m_data.GetU32(&offset, &lc, 2) == NULL) +      break; +    // Watch for the symbol table load command +    switch (lc.cmd) { +    case LC_SYMTAB: +      symtab_load_command.cmd = lc.cmd; +      symtab_load_command.cmdsize = lc.cmdsize; +      // Read in the rest of the symtab load command +      if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) == +          0) // fill in symoff, nsyms, stroff, strsize fields +        return 0; +      if (symtab_load_command.symoff == 0) { +        if (log) +          module_sp->LogMessage(log, "LC_SYMTAB.symoff == 0"); +        return 0; +      } -                    dylib_files.Append(file_spec); -                } -            } -            break; +      if (symtab_load_command.stroff == 0) { +        if (log) +          module_sp->LogMessage(log, "LC_SYMTAB.stroff == 0"); +        return 0; +      } -        case LC_FUNCTION_STARTS: -            function_starts_load_command.cmd = lc.cmd; -            function_starts_load_command.cmdsize = lc.cmdsize; -            if (m_data.GetU32(&offset, &function_starts_load_command.dataoff, 2) == NULL) // fill in symoff, nsyms, stroff, strsize fields -                memset (&function_starts_load_command, 0, sizeof(function_starts_load_command)); -            break; +      if (symtab_load_command.nsyms == 0) { +        if (log) +          module_sp->LogMessage(log, "LC_SYMTAB.nsyms == 0"); +        return 0; +      } -        default: -            break; +      if (symtab_load_command.strsize == 0) { +        if (log) +          module_sp->LogMessage(log, "LC_SYMTAB.strsize == 0"); +        return 0; +      } +      break; + +    case LC_DYLD_INFO: +    case LC_DYLD_INFO_ONLY: +      if (m_data.GetU32(&offset, &dyld_info.rebase_off, 10)) { +        dyld_info.cmd = lc.cmd; +        dyld_info.cmdsize = lc.cmdsize; +      } else { +        memset(&dyld_info, 0, sizeof(dyld_info)); +      } +      break; + +    case LC_LOAD_DYLIB: +    case LC_LOAD_WEAK_DYLIB: +    case LC_REEXPORT_DYLIB: +    case LC_LOADFVMLIB: +    case LC_LOAD_UPWARD_DYLIB: { +      uint32_t name_offset = cmd_offset + m_data.GetU32(&offset); +      const char *path = m_data.PeekCStr(name_offset); +      if (path) { +        FileSpec file_spec(path, false); +        // Strip the path if there is @rpath, @executable, etc so we just use +        // the basename +        if (path[0] == '@') +          file_spec.GetDirectory().Clear(); + +        if (lc.cmd == LC_REEXPORT_DYLIB) { +          m_reexported_dylibs.AppendIfUnique(file_spec);          } -        offset = cmd_offset + lc.cmdsize; -    } - -    if (symtab_load_command.cmd) -    { -        Symtab *symtab = m_symtab_ap.get(); -        SectionList *section_list = GetSectionList(); -        if (section_list == NULL) -            return 0; - -        const uint32_t addr_byte_size = m_data.GetAddressByteSize(); -        const ByteOrder byte_order = m_data.GetByteOrder(); -        bool bit_width_32 = addr_byte_size == 4; -        const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64); - -        DataExtractor nlist_data (NULL, 0, byte_order, addr_byte_size); -        DataExtractor strtab_data (NULL, 0, byte_order, addr_byte_size); -        DataExtractor function_starts_data (NULL, 0, byte_order, addr_byte_size); -        DataExtractor indirect_symbol_index_data (NULL, 0, byte_order, addr_byte_size); -        DataExtractor dyld_trie_data (NULL, 0, byte_order, addr_byte_size); - -        const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size; -        const addr_t strtab_data_byte_size = symtab_load_command.strsize; -        addr_t strtab_addr = LLDB_INVALID_ADDRESS; - -        ProcessSP process_sp (m_process_wp.lock()); -        Process *process = process_sp.get(); -         -        uint32_t memory_module_load_level = eMemoryModuleLoadLevelComplete; - -        if (process && m_header.filetype != llvm::MachO::MH_OBJECT) -        { -            Target &target = process->GetTarget(); -             -            memory_module_load_level = target.GetMemoryModuleLoadLevel(); - -            SectionSP linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT())); -            // Reading mach file from memory in a process or core file... - -            if (linkedit_section_sp) -            { -                addr_t linkedit_load_addr = linkedit_section_sp->GetLoadBaseAddress(&target); -                if (linkedit_load_addr == LLDB_INVALID_ADDRESS) -                { -                    // We might be trying to access the symbol table before the __LINKEDIT's load -                    // address has been set in the target. We can't fail to read the symbol table, -                    // so calculate the right address manually -                    linkedit_load_addr = CalculateSectionLoadAddressForMemoryImage(m_memory_addr, GetMachHeaderSection(), linkedit_section_sp.get()); -                } - -                const addr_t linkedit_file_offset = linkedit_section_sp->GetFileOffset(); -                const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset; -                strtab_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset; - -                bool data_was_read = false; - -#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__)) -                if (m_header.flags & 0x80000000u && process->GetAddressByteSize() == sizeof (void*)) -                { -                    // This mach-o memory file is in the dyld shared cache. If this -                    // program is not remote and this is iOS, then this process will -                    // share the same shared cache as the process we are debugging and -                    // we can read the entire __LINKEDIT from the address space in this -                    // process. This is a needed optimization that is used for local iOS -                    // debugging only since all shared libraries in the shared cache do -                    // not have corresponding files that exist in the file system of the -                    // device. They have been combined into a single file. This means we -                    // always have to load these files from memory. All of the symbol and -                    // string tables from all of the __LINKEDIT sections from the shared -                    // libraries in the shared cache have been merged into a single large -                    // symbol and string table. Reading all of this symbol and string table -                    // data across can slow down debug launch times, so we optimize this by -                    // reading the memory for the __LINKEDIT section from this process. - -                    UUID lldb_shared_cache(GetLLDBSharedCacheUUID()); -                    UUID process_shared_cache(GetProcessSharedCacheUUID(process)); -                    bool use_lldb_cache = true; -                    if (lldb_shared_cache.IsValid() && process_shared_cache.IsValid() && lldb_shared_cache != process_shared_cache) -                    { -                            use_lldb_cache = false; -                            ModuleSP module_sp (GetModule()); -                            if (module_sp) -                                module_sp->ReportWarning ("shared cache in process does not match lldb's own shared cache, startup will be slow."); -                    } - -                    PlatformSP platform_sp (target.GetPlatform()); -                    if (platform_sp && platform_sp->IsHost() && use_lldb_cache) -                    { -                        data_was_read = true; -                        nlist_data.SetData((void *)symoff_addr, nlist_data_byte_size, eByteOrderLittle); -                        strtab_data.SetData((void *)strtab_addr, strtab_data_byte_size, eByteOrderLittle); -                        if (function_starts_load_command.cmd) -                        { -                            const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset; -                            function_starts_data.SetData ((void *)func_start_addr, function_starts_load_command.datasize, eByteOrderLittle); -                        } -                    } -                } -#endif +        dylib_files.Append(file_spec); +      } +    } break; + +    case LC_FUNCTION_STARTS: +      function_starts_load_command.cmd = lc.cmd; +      function_starts_load_command.cmdsize = lc.cmdsize; +      if (m_data.GetU32(&offset, &function_starts_load_command.dataoff, 2) == +          NULL) // fill in symoff, nsyms, stroff, strsize fields +        memset(&function_starts_load_command, 0, +               sizeof(function_starts_load_command)); +      break; + +    default: +      break; +    } +    offset = cmd_offset + lc.cmdsize; +  } -                if (!data_was_read) -                { -                    if (memory_module_load_level == eMemoryModuleLoadLevelComplete) -                    { -                        DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size)); -                        if (nlist_data_sp) -                            nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize()); -                        // Load strings individually from memory when loading from memory since shared cache -                        // string tables contain strings for all symbols from all shared cached libraries -                        //DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr, strtab_data_byte_size)); -                        //if (strtab_data_sp) -                        //    strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize()); -                        if (m_dysymtab.nindirectsyms != 0) -                        { -                            const addr_t indirect_syms_addr = linkedit_load_addr + m_dysymtab.indirectsymoff - linkedit_file_offset; -                            DataBufferSP indirect_syms_data_sp (ReadMemory (process_sp, indirect_syms_addr, m_dysymtab.nindirectsyms * 4)); -                            if (indirect_syms_data_sp) -                                indirect_symbol_index_data.SetData (indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize()); -                        } -                    } -                     -                    if (memory_module_load_level >= eMemoryModuleLoadLevelPartial) -                    { -                        if (function_starts_load_command.cmd) -                        { -                            const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset; -                            DataBufferSP func_start_data_sp (ReadMemory (process_sp, func_start_addr, function_starts_load_command.datasize)); -                            if (func_start_data_sp) -                                function_starts_data.SetData (func_start_data_sp, 0, func_start_data_sp->GetByteSize()); -                        } -                    } -                } -            } +  if (symtab_load_command.cmd) { +    Symtab *symtab = m_symtab_ap.get(); +    SectionList *section_list = GetSectionList(); +    if (section_list == NULL) +      return 0; + +    const uint32_t addr_byte_size = m_data.GetAddressByteSize(); +    const ByteOrder byte_order = m_data.GetByteOrder(); +    bool bit_width_32 = addr_byte_size == 4; +    const size_t nlist_byte_size = +        bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64); + +    DataExtractor nlist_data(NULL, 0, byte_order, addr_byte_size); +    DataExtractor strtab_data(NULL, 0, byte_order, addr_byte_size); +    DataExtractor function_starts_data(NULL, 0, byte_order, addr_byte_size); +    DataExtractor indirect_symbol_index_data(NULL, 0, byte_order, +                                             addr_byte_size); +    DataExtractor dyld_trie_data(NULL, 0, byte_order, addr_byte_size); + +    const addr_t nlist_data_byte_size = +        symtab_load_command.nsyms * nlist_byte_size; +    const addr_t strtab_data_byte_size = symtab_load_command.strsize; +    addr_t strtab_addr = LLDB_INVALID_ADDRESS; + +    ProcessSP process_sp(m_process_wp.lock()); +    Process *process = process_sp.get(); + +    uint32_t memory_module_load_level = eMemoryModuleLoadLevelComplete; + +    if (process && m_header.filetype != llvm::MachO::MH_OBJECT) { +      Target &target = process->GetTarget(); + +      memory_module_load_level = target.GetMemoryModuleLoadLevel(); + +      SectionSP linkedit_section_sp( +          section_list->FindSectionByName(GetSegmentNameLINKEDIT())); +      // Reading mach file from memory in a process or core file... + +      if (linkedit_section_sp) { +        addr_t linkedit_load_addr = +            linkedit_section_sp->GetLoadBaseAddress(&target); +        if (linkedit_load_addr == LLDB_INVALID_ADDRESS) { +          // We might be trying to access the symbol table before the +          // __LINKEDIT's load +          // address has been set in the target. We can't fail to read the +          // symbol table, +          // so calculate the right address manually +          linkedit_load_addr = CalculateSectionLoadAddressForMemoryImage( +              m_memory_addr, GetMachHeaderSection(), linkedit_section_sp.get());          } -        else -        { -            nlist_data.SetData (m_data, -                                symtab_load_command.symoff, -                                nlist_data_byte_size); -            strtab_data.SetData (m_data, -                                 symtab_load_command.stroff, -                                 strtab_data_byte_size); -             -            if (dyld_info.export_size > 0) -            { -                dyld_trie_data.SetData (m_data, -                                        dyld_info.export_off, -                                        dyld_info.export_size); -            } -            if (m_dysymtab.nindirectsyms != 0) -            { -                indirect_symbol_index_data.SetData (m_data, -                                                    m_dysymtab.indirectsymoff, -                                                    m_dysymtab.nindirectsyms * 4); -            } -            if (function_starts_load_command.cmd) -            { -                function_starts_data.SetData (m_data, -                                              function_starts_load_command.dataoff, -                                              function_starts_load_command.datasize); +        const addr_t linkedit_file_offset = +            linkedit_section_sp->GetFileOffset(); +        const addr_t symoff_addr = linkedit_load_addr + +                                   symtab_load_command.symoff - +                                   linkedit_file_offset; +        strtab_addr = linkedit_load_addr + symtab_load_command.stroff - +                      linkedit_file_offset; + +        bool data_was_read = false; + +#if defined(__APPLE__) &&                                                      \ +    (defined(__arm__) || defined(__arm64__) || defined(__aarch64__)) +        if (m_header.flags & 0x80000000u && +            process->GetAddressByteSize() == sizeof(void *)) { +          // This mach-o memory file is in the dyld shared cache. If this +          // program is not remote and this is iOS, then this process will +          // share the same shared cache as the process we are debugging and +          // we can read the entire __LINKEDIT from the address space in this +          // process. This is a needed optimization that is used for local iOS +          // debugging only since all shared libraries in the shared cache do +          // not have corresponding files that exist in the file system of the +          // device. They have been combined into a single file. This means we +          // always have to load these files from memory. All of the symbol and +          // string tables from all of the __LINKEDIT sections from the shared +          // libraries in the shared cache have been merged into a single large +          // symbol and string table. Reading all of this symbol and string +          // table +          // data across can slow down debug launch times, so we optimize this +          // by +          // reading the memory for the __LINKEDIT section from this process. + +          UUID lldb_shared_cache(GetLLDBSharedCacheUUID()); +          UUID process_shared_cache(GetProcessSharedCacheUUID(process)); +          bool use_lldb_cache = true; +          if (lldb_shared_cache.IsValid() && process_shared_cache.IsValid() && +              lldb_shared_cache != process_shared_cache) { +            use_lldb_cache = false; +            ModuleSP module_sp(GetModule()); +            if (module_sp) +              module_sp->ReportWarning("shared cache in process does not match " +                                       "lldb's own shared cache, startup will " +                                       "be slow."); +          } + +          PlatformSP platform_sp(target.GetPlatform()); +          if (platform_sp && platform_sp->IsHost() && use_lldb_cache) { +            data_was_read = true; +            nlist_data.SetData((void *)symoff_addr, nlist_data_byte_size, +                               eByteOrderLittle); +            strtab_data.SetData((void *)strtab_addr, strtab_data_byte_size, +                                eByteOrderLittle); +            if (function_starts_load_command.cmd) { +              const addr_t func_start_addr = +                  linkedit_load_addr + function_starts_load_command.dataoff - +                  linkedit_file_offset; +              function_starts_data.SetData( +                  (void *)func_start_addr, +                  function_starts_load_command.datasize, eByteOrderLittle);              } +          }          } +#endif -        if (nlist_data.GetByteSize() == 0 && memory_module_load_level == eMemoryModuleLoadLevelComplete) -        { -            if (log) -                module_sp->LogMessage(log, "failed to read nlist data"); -            return 0; -        } - -        const bool have_strtab_data = strtab_data.GetByteSize() > 0; -        if (!have_strtab_data) -        { -            if (process) -            { -                if (strtab_addr == LLDB_INVALID_ADDRESS) -                { -                    if (log) -                        module_sp->LogMessage(log, "failed to locate the strtab in memory"); -                    return 0; -                } +        if (!data_was_read) { +          // Always load dyld - the dynamic linker - from memory if we didn't +          // find a binary anywhere else. +          // lldb will not register dylib/framework/bundle loads/unloads if we +          // don't have the dyld symbols, +          // we force dyld to load from memory despite the user's +          // target.memory-module-load-level setting. +          if (memory_module_load_level == eMemoryModuleLoadLevelComplete || +              m_header.filetype == llvm::MachO::MH_DYLINKER) { +            DataBufferSP nlist_data_sp( +                ReadMemory(process_sp, symoff_addr, nlist_data_byte_size)); +            if (nlist_data_sp) +              nlist_data.SetData(nlist_data_sp, 0, +                                 nlist_data_sp->GetByteSize()); +            // Load strings individually from memory when loading from memory +            // since shared cache +            // string tables contain strings for all symbols from all shared +            // cached libraries +            // DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr, +            // strtab_data_byte_size)); +            // if (strtab_data_sp) +            //    strtab_data.SetData (strtab_data_sp, 0, +            //    strtab_data_sp->GetByteSize()); +            if (m_dysymtab.nindirectsyms != 0) { +              const addr_t indirect_syms_addr = linkedit_load_addr + +                                                m_dysymtab.indirectsymoff - +                                                linkedit_file_offset; +              DataBufferSP indirect_syms_data_sp( +                  ReadMemory(process_sp, indirect_syms_addr, +                             m_dysymtab.nindirectsyms * 4)); +              if (indirect_syms_data_sp) +                indirect_symbol_index_data.SetData( +                    indirect_syms_data_sp, 0, +                    indirect_syms_data_sp->GetByteSize());              } -            else -            { -                if (log) -                    module_sp->LogMessage(log, "failed to read strtab data"); -                return 0; +          } else if (memory_module_load_level >= +                     eMemoryModuleLoadLevelPartial) { +            if (function_starts_load_command.cmd) { +              const addr_t func_start_addr = +                  linkedit_load_addr + function_starts_load_command.dataoff - +                  linkedit_file_offset; +              DataBufferSP func_start_data_sp( +                  ReadMemory(process_sp, func_start_addr, +                             function_starts_load_command.datasize)); +              if (func_start_data_sp) +                function_starts_data.SetData(func_start_data_sp, 0, +                                             func_start_data_sp->GetByteSize());              } +          }          } +      } +    } else { +      nlist_data.SetData(m_data, symtab_load_command.symoff, +                         nlist_data_byte_size); +      strtab_data.SetData(m_data, symtab_load_command.stroff, +                          strtab_data_byte_size); + +      if (dyld_info.export_size > 0) { +        dyld_trie_data.SetData(m_data, dyld_info.export_off, +                               dyld_info.export_size); +      } + +      if (m_dysymtab.nindirectsyms != 0) { +        indirect_symbol_index_data.SetData(m_data, m_dysymtab.indirectsymoff, +                                           m_dysymtab.nindirectsyms * 4); +      } +      if (function_starts_load_command.cmd) { +        function_starts_data.SetData(m_data, +                                     function_starts_load_command.dataoff, +                                     function_starts_load_command.datasize); +      } +    } -        const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT(); -        const ConstString &g_segment_name_DATA = GetSegmentNameDATA(); -        const ConstString &g_segment_name_DATA_DIRTY = GetSegmentNameDATA_DIRTY(); -        const ConstString &g_segment_name_DATA_CONST = GetSegmentNameDATA_CONST(); -        const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC(); -        const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame(); -        SectionSP text_section_sp(section_list->FindSectionByName(g_segment_name_TEXT)); -        SectionSP data_section_sp(section_list->FindSectionByName(g_segment_name_DATA)); -        SectionSP data_dirty_section_sp(section_list->FindSectionByName(g_segment_name_DATA_DIRTY)); -        SectionSP data_const_section_sp(section_list->FindSectionByName(g_segment_name_DATA_CONST)); -        SectionSP objc_section_sp(section_list->FindSectionByName(g_segment_name_OBJC)); -        SectionSP eh_frame_section_sp; -        if (text_section_sp.get()) -            eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName (g_section_name_eh_frame); -        else -            eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame); - -        const bool is_arm = (m_header.cputype == llvm::MachO::CPU_TYPE_ARM); - -        // lldb works best if it knows the start address of all functions in a module. -        // Linker symbols or debug info are normally the best source of information for start addr / size but -        // they may be stripped in a released binary. -        // Two additional sources of information exist in Mach-O binaries: -        //    LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each function's start address in the -        //                         binary, relative to the text section. -        //    eh_frame           - the eh_frame FDEs have the start addr & size of each function -        //  LC_FUNCTION_STARTS is the fastest source to read in, and is present on all modern binaries. -        //  Binaries built to run on older releases may need to use eh_frame information. - -        if (text_section_sp && function_starts_data.GetByteSize()) -        { -            FunctionStarts::Entry function_start_entry; -            function_start_entry.data = false; -            lldb::offset_t function_start_offset = 0; -            function_start_entry.addr = text_section_sp->GetFileAddress(); -            uint64_t delta; -            while ((delta = function_starts_data.GetULEB128(&function_start_offset)) > 0) -            { -                // Now append the current entry -                function_start_entry.addr += delta; -                function_starts.Append(function_start_entry); -            } -        } -        else -        { -            // If m_type is eTypeDebugInfo, then this is a dSYM - it will have the load command claiming an eh_frame -            // but it doesn't actually have the eh_frame content.  And if we have a dSYM, we don't need to do any -            // of this fill-in-the-missing-symbols works anyway - the debug info should give us all the functions in -            // the module. -            if (text_section_sp.get() && eh_frame_section_sp.get() && m_type != eTypeDebugInfo) -            { -                DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp, eRegisterKindEHFrame, true); -                DWARFCallFrameInfo::FunctionAddressAndSizeVector functions; -                eh_frame.GetFunctionAddressAndSizeVector (functions); -                addr_t text_base_addr = text_section_sp->GetFileAddress(); -                size_t count = functions.GetSize(); -                for (size_t i = 0; i < count; ++i) -                { -                    const DWARFCallFrameInfo::FunctionAddressAndSizeVector::Entry *func = functions.GetEntryAtIndex (i); -                    if (func) -                    { -                        FunctionStarts::Entry function_start_entry; -                        function_start_entry.addr = func->base - text_base_addr; -                        function_starts.Append(function_start_entry); -                    } -                } -            } -        } +    if (nlist_data.GetByteSize() == 0 && +        memory_module_load_level == eMemoryModuleLoadLevelComplete) { +      if (log) +        module_sp->LogMessage(log, "failed to read nlist data"); +      return 0; +    } -        const size_t function_starts_count = function_starts.GetSize(); - -        // For user process binaries (executables, dylibs, frameworks, bundles), if we don't have -        // LC_FUNCTION_STARTS/eh_frame section in this binary, we're going to assume the binary -        // has been stripped.  Don't allow assembly language instruction emulation because we don't -        // know proper function start boundaries. -        // -        // For all other types of binaries (kernels, stand-alone bare board binaries, kexts), they -        // may not have LC_FUNCTION_STARTS / eh_frame sections - we should not make any assumptions -        // about them based on that. -        if (function_starts_count == 0 && CalculateStrata() == eStrataUser) -        { -            m_allow_assembly_emulation_unwind_plans = false; -            Log *unwind_or_symbol_log (lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_SYMBOLS | LIBLLDB_LOG_UNWIND)); - -            if (unwind_or_symbol_log) -                module_sp->LogMessage(unwind_or_symbol_log, "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds"); +    const bool have_strtab_data = strtab_data.GetByteSize() > 0; +    if (!have_strtab_data) { +      if (process) { +        if (strtab_addr == LLDB_INVALID_ADDRESS) { +          if (log) +            module_sp->LogMessage(log, "failed to locate the strtab in memory"); +          return 0;          } +      } else { +        if (log) +          module_sp->LogMessage(log, "failed to read strtab data"); +        return 0; +      } +    } -        const user_id_t TEXT_eh_frame_sectID = -            eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() -                                      : static_cast<user_id_t>(NO_SECT); - -        lldb::offset_t nlist_data_offset = 0; - -        uint32_t N_SO_index = UINT32_MAX; - -        MachSymtabSectionInfo section_info (section_list); -        std::vector<uint32_t> N_FUN_indexes; -        std::vector<uint32_t> N_NSYM_indexes; -        std::vector<uint32_t> N_INCL_indexes; -        std::vector<uint32_t> N_BRAC_indexes; -        std::vector<uint32_t> N_COMM_indexes; -        typedef std::multimap <uint64_t, uint32_t> ValueToSymbolIndexMap; -        typedef std::map <uint32_t, uint32_t> NListIndexToSymbolIndexMap; -        typedef std::map <const char *, uint32_t> ConstNameToSymbolIndexMap; -        ValueToSymbolIndexMap N_FUN_addr_to_sym_idx; -        ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx; -        ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx; -        // Any symbols that get merged into another will get an entry -        // in this map so we know -        NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx; -        uint32_t nlist_idx = 0; -        Symbol *symbol_ptr = NULL; - -        uint32_t sym_idx = 0; -        Symbol *sym = NULL; -        size_t num_syms = 0; -        std::string memory_symbol_name; -        uint32_t unmapped_local_symbols_found = 0; - -        std::vector<TrieEntryWithOffset> trie_entries; -        std::set<lldb::addr_t> resolver_addresses; - -        if (dyld_trie_data.GetByteSize() > 0) -        { -            std::vector<llvm::StringRef> nameSlices; -            ParseTrieEntries (dyld_trie_data, -                              0, -                              is_arm, -                              nameSlices, -                              resolver_addresses, -                              trie_entries); -             -            ConstString text_segment_name ("__TEXT"); -            SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name); -            if (text_segment_sp) -            { -                const lldb::addr_t text_segment_file_addr = text_segment_sp->GetFileAddress(); -                if (text_segment_file_addr != LLDB_INVALID_ADDRESS) -                { -                    for (auto &e : trie_entries) -                        e.entry.address += text_segment_file_addr; -                } -            } +    const ConstString &g_segment_name_TEXT = GetSegmentNameTEXT(); +    const ConstString &g_segment_name_DATA = GetSegmentNameDATA(); +    const ConstString &g_segment_name_DATA_DIRTY = GetSegmentNameDATA_DIRTY(); +    const ConstString &g_segment_name_DATA_CONST = GetSegmentNameDATA_CONST(); +    const ConstString &g_segment_name_OBJC = GetSegmentNameOBJC(); +    const ConstString &g_section_name_eh_frame = GetSectionNameEHFrame(); +    SectionSP text_section_sp( +        section_list->FindSectionByName(g_segment_name_TEXT)); +    SectionSP data_section_sp( +        section_list->FindSectionByName(g_segment_name_DATA)); +    SectionSP data_dirty_section_sp( +        section_list->FindSectionByName(g_segment_name_DATA_DIRTY)); +    SectionSP data_const_section_sp( +        section_list->FindSectionByName(g_segment_name_DATA_CONST)); +    SectionSP objc_section_sp( +        section_list->FindSectionByName(g_segment_name_OBJC)); +    SectionSP eh_frame_section_sp; +    if (text_section_sp.get()) +      eh_frame_section_sp = text_section_sp->GetChildren().FindSectionByName( +          g_section_name_eh_frame); +    else +      eh_frame_section_sp = +          section_list->FindSectionByName(g_section_name_eh_frame); + +    const bool is_arm = (m_header.cputype == llvm::MachO::CPU_TYPE_ARM); + +    // lldb works best if it knows the start address of all functions in a +    // module. +    // Linker symbols or debug info are normally the best source of information +    // for start addr / size but +    // they may be stripped in a released binary. +    // Two additional sources of information exist in Mach-O binaries: +    //    LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each +    //    function's start address in the +    //                         binary, relative to the text section. +    //    eh_frame           - the eh_frame FDEs have the start addr & size of +    //    each function +    //  LC_FUNCTION_STARTS is the fastest source to read in, and is present on +    //  all modern binaries. +    //  Binaries built to run on older releases may need to use eh_frame +    //  information. + +    if (text_section_sp && function_starts_data.GetByteSize()) { +      FunctionStarts::Entry function_start_entry; +      function_start_entry.data = false; +      lldb::offset_t function_start_offset = 0; +      function_start_entry.addr = text_section_sp->GetFileAddress(); +      uint64_t delta; +      while ((delta = function_starts_data.GetULEB128(&function_start_offset)) > +             0) { +        // Now append the current entry +        function_start_entry.addr += delta; +        function_starts.Append(function_start_entry); +      } +    } else { +      // If m_type is eTypeDebugInfo, then this is a dSYM - it will have the +      // load command claiming an eh_frame +      // but it doesn't actually have the eh_frame content.  And if we have a +      // dSYM, we don't need to do any +      // of this fill-in-the-missing-symbols works anyway - the debug info +      // should give us all the functions in +      // the module. +      if (text_section_sp.get() && eh_frame_section_sp.get() && +          m_type != eTypeDebugInfo) { +        DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp, +                                    eRegisterKindEHFrame, true); +        DWARFCallFrameInfo::FunctionAddressAndSizeVector functions; +        eh_frame.GetFunctionAddressAndSizeVector(functions); +        addr_t text_base_addr = text_section_sp->GetFileAddress(); +        size_t count = functions.GetSize(); +        for (size_t i = 0; i < count; ++i) { +          const DWARFCallFrameInfo::FunctionAddressAndSizeVector::Entry *func = +              functions.GetEntryAtIndex(i); +          if (func) { +            FunctionStarts::Entry function_start_entry; +            function_start_entry.addr = func->base - text_base_addr; +            function_starts.Append(function_start_entry); +          }          } +      } +    } -        typedef std::set<ConstString> IndirectSymbols; -        IndirectSymbols indirect_symbol_names; - -#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__)) - -        // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been optimized by moving LOCAL -        // symbols out of the memory mapped portion of the DSC. The symbol information has all been retained, -        // but it isn't available in the normal nlist data. However, there *are* duplicate entries of *some* -        // LOCAL symbols in the normal nlist data. To handle this situation correctly, we must first attempt -        // to parse any DSC unmapped symbol information. If we find any, we set a flag that tells the normal -        // nlist parser to ignore all LOCAL symbols. - -        if (m_header.flags & 0x80000000u) -        { -            // Before we can start mapping the DSC, we need to make certain the target process is actually -            // using the cache we can find. - -            // Next we need to determine the correct path for the dyld shared cache. - -            ArchSpec header_arch; -            GetArchitecture(header_arch); -            char dsc_path[PATH_MAX]; -            char dsc_path_development[PATH_MAX]; - -            snprintf(dsc_path, sizeof(dsc_path), "%s%s%s", -                     "/System/Library/Caches/com.apple.dyld/",  /* IPHONE_DYLD_SHARED_CACHE_DIR */ -                     "dyld_shared_cache_",          /* DYLD_SHARED_CACHE_BASE_NAME */ -                     header_arch.GetArchitectureName()); - -            snprintf(dsc_path_development, sizeof(dsc_path), "%s%s%s%s", -                     "/System/Library/Caches/com.apple.dyld/",  /* IPHONE_DYLD_SHARED_CACHE_DIR */ -                     "dyld_shared_cache_",          /* DYLD_SHARED_CACHE_BASE_NAME */ -                     header_arch.GetArchitectureName(), -                     ".development"); - -            FileSpec dsc_nondevelopment_filespec(dsc_path, false); -            FileSpec dsc_development_filespec(dsc_path_development, false); -            FileSpec dsc_filespec; - -            UUID dsc_uuid; -            UUID process_shared_cache_uuid; - -            if (process) -            { -                process_shared_cache_uuid = GetProcessSharedCacheUUID(process); -            } - -            // First see if we can find an exact match for the inferior process shared cache UUID in -            // the development or non-development shared caches on disk. -            if (process_shared_cache_uuid.IsValid()) -            { -                if (dsc_development_filespec.Exists()) -                { -                    UUID dsc_development_uuid = GetSharedCacheUUID (dsc_development_filespec, byte_order, addr_byte_size); -                    if (dsc_development_uuid.IsValid() && dsc_development_uuid == process_shared_cache_uuid) -                    { -                        dsc_filespec = dsc_development_filespec; -                        dsc_uuid = dsc_development_uuid; -                    } -                } -                if (!dsc_uuid.IsValid() && dsc_nondevelopment_filespec.Exists()) -                { -                    UUID dsc_nondevelopment_uuid = GetSharedCacheUUID (dsc_nondevelopment_filespec, byte_order, addr_byte_size); -                    if (dsc_nondevelopment_uuid.IsValid() && dsc_nondevelopment_uuid == process_shared_cache_uuid) -                    { -                        dsc_filespec = dsc_nondevelopment_filespec; -                        dsc_uuid = dsc_nondevelopment_uuid; -                    } -                } -            } - -            // Failing a UUID match, prefer the development dyld_shared cache if both are present. -            if (!dsc_filespec.Exists()) -            { -                if (dsc_development_filespec.Exists()) -                { -                    dsc_filespec = dsc_development_filespec; -                } -                else -                { -                    dsc_filespec = dsc_nondevelopment_filespec; -                } -            } - -            /* The dyld_cache_header has a pointer to the dyld_cache_local_symbols_info structure (localSymbolsOffset). -               The dyld_cache_local_symbols_info structure gives us three things: -                 1. The start and count of the nlist records in the dyld_shared_cache file -                 2. The start and size of the strings for these nlist records -                 3. The start and count of dyld_cache_local_symbols_entry entries - -               There is one dyld_cache_local_symbols_entry per dylib/framework in the dyld shared cache. -               The "dylibOffset" field is the Mach-O header of this dylib/framework in the dyld shared cache. -               The dyld_cache_local_symbols_entry also lists the start of this dylib/framework's nlist records -               and the count of how many nlist records there are for this dylib/framework. -            */ - -            // Process the dyld shared cache header to find the unmapped symbols - -            DataBufferSP dsc_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(0, sizeof(struct lldb_copy_dyld_cache_header_v1)); -            if (!dsc_uuid.IsValid()) -            { -                dsc_uuid = GetSharedCacheUUID (dsc_filespec, byte_order, addr_byte_size); -            } -            if (dsc_data_sp) -            { -                DataExtractor dsc_header_data (dsc_data_sp, byte_order, addr_byte_size); - -                bool uuid_match = true; -                if (dsc_uuid.IsValid() && process) -                { -                    if (process_shared_cache_uuid.IsValid() && dsc_uuid != process_shared_cache_uuid) -                    { -                        // The on-disk dyld_shared_cache file is not the same as the one in this -                        // process' memory, don't use it. -                        uuid_match = false; -                        ModuleSP module_sp (GetModule()); -                        if (module_sp) -                            module_sp->ReportWarning ("process shared cache does not match on-disk dyld_shared_cache file, some symbol names will be missing."); -                    } -                } - -                offset = offsetof (struct lldb_copy_dyld_cache_header_v1, mappingOffset); - -                uint32_t mappingOffset = dsc_header_data.GetU32(&offset); - -                // If the mappingOffset points to a location inside the header, we've -                // opened an old dyld shared cache, and should not proceed further. -                if (uuid_match && mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v1)) -                { - -                    DataBufferSP dsc_mapping_info_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(mappingOffset, sizeof (struct lldb_copy_dyld_cache_mapping_info)); -                    DataExtractor dsc_mapping_info_data(dsc_mapping_info_data_sp, byte_order, addr_byte_size); -                    offset = 0; - -                    // The File addresses (from the in-memory Mach-O load commands) for the shared libraries -                    // in the shared library cache need to be adjusted by an offset to match up with the -                    // dylibOffset identifying field in the dyld_cache_local_symbol_entry's.  This offset is -                    // recorded in mapping_offset_value. -                    const uint64_t mapping_offset_value = dsc_mapping_info_data.GetU64(&offset); - -                    offset = offsetof (struct lldb_copy_dyld_cache_header_v1, localSymbolsOffset); -                    uint64_t localSymbolsOffset = dsc_header_data.GetU64(&offset); -                    uint64_t localSymbolsSize = dsc_header_data.GetU64(&offset); +    const size_t function_starts_count = function_starts.GetSize(); -                    if (localSymbolsOffset && localSymbolsSize) -                    { -                        // Map the local symbols -                        if (DataBufferSP dsc_local_symbols_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal(localSymbolsOffset, localSymbolsSize)) -                        { -                            DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp, byte_order, addr_byte_size); - -                            offset = 0; - -                            typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap; -                            typedef std::map<uint32_t, ConstString> SymbolIndexToName; -                            UndefinedNameToDescMap undefined_name_to_desc; -                            SymbolIndexToName reexport_shlib_needs_fixup; - - -                            // Read the local_symbols_infos struct in one shot -                            struct lldb_copy_dyld_cache_local_symbols_info local_symbols_info; -                            dsc_local_symbols_data.GetU32(&offset, &local_symbols_info.nlistOffset, 6); - -                            SectionSP text_section_sp(section_list->FindSectionByName(GetSegmentNameTEXT())); - -                            uint32_t header_file_offset = (text_section_sp->GetFileAddress() - mapping_offset_value); - -                            offset = local_symbols_info.entriesOffset; -                            for (uint32_t entry_index = 0; entry_index < local_symbols_info.entriesCount; entry_index++) -                            { -                                struct lldb_copy_dyld_cache_local_symbols_entry local_symbols_entry; -                                local_symbols_entry.dylibOffset = dsc_local_symbols_data.GetU32(&offset); -                                local_symbols_entry.nlistStartIndex = dsc_local_symbols_data.GetU32(&offset); -                                local_symbols_entry.nlistCount = dsc_local_symbols_data.GetU32(&offset); - -                                if (header_file_offset == local_symbols_entry.dylibOffset) -                                { -                                    unmapped_local_symbols_found = local_symbols_entry.nlistCount; - -                                    // The normal nlist code cannot correctly size the Symbols array, we need to allocate it here. -                                    sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms + unmapped_local_symbols_found - m_dysymtab.nlocalsym); -                                    num_syms = symtab->GetNumSymbols(); - -                                    nlist_data_offset = local_symbols_info.nlistOffset + (nlist_byte_size * local_symbols_entry.nlistStartIndex); -                                    uint32_t string_table_offset = local_symbols_info.stringsOffset; - -                                    for (uint32_t nlist_index = 0; nlist_index < local_symbols_entry.nlistCount; nlist_index++) -                                    { -                                        ///////////////////////////// -                                        { -                                            struct nlist_64 nlist; -                                            if (!dsc_local_symbols_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size)) -                                                break; - -                                            nlist.n_strx  = dsc_local_symbols_data.GetU32_unchecked(&nlist_data_offset); -                                            nlist.n_type  = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset); -                                            nlist.n_sect  = dsc_local_symbols_data.GetU8_unchecked (&nlist_data_offset); -                                            nlist.n_desc  = dsc_local_symbols_data.GetU16_unchecked (&nlist_data_offset); -                                            nlist.n_value = dsc_local_symbols_data.GetAddress_unchecked (&nlist_data_offset); - -                                            SymbolType type = eSymbolTypeInvalid; -                                            const char *symbol_name = dsc_local_symbols_data.PeekCStr(string_table_offset + nlist.n_strx); - -                                            if (symbol_name == NULL) -                                            { -                                                // No symbol should be NULL, even the symbols with no -                                                // string values should have an offset zero which points -                                                // to an empty C-string -                                                Host::SystemLog (Host::eSystemLogError, -                                                                 "error: DSC unmapped local symbol[%u] has invalid string table offset 0x%x in %s, ignoring symbol\n", -                                                                 entry_index, -                                                                 nlist.n_strx, -                                                                 module_sp->GetFileSpec().GetPath().c_str()); -                                                continue; -                                            } -                                            if (symbol_name[0] == '\0') -                                                symbol_name = NULL; - -                                            const char *symbol_name_non_abi_mangled = NULL; - -                                            SectionSP symbol_section; -                                            uint32_t symbol_byte_size = 0; -                                            bool add_nlist = true; -                                            bool is_debug = ((nlist.n_type & N_STAB) != 0); -                                            bool demangled_is_synthesized = false; -                                            bool is_gsym = false; -                                            bool set_value = true; - -                                            assert (sym_idx < num_syms); - -                                            sym[sym_idx].SetDebug (is_debug); - -                                            if (is_debug) -                                            { -                                                switch (nlist.n_type) -                                                { -                                                    case N_GSYM: -                                                        // global symbol: name,,NO_SECT,type,0 -                                                        // Sometimes the N_GSYM value contains the address. - -                                                        // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data.  They -                                                        // have the same address, but we want to ensure that we always find only the real symbol, -                                                        // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass -                                                        // symbol type.  This is a temporary hack to make sure the ObjectiveC symbols get treated -                                                        // correctly.  To do this right, we should coalesce all the GSYM & global symbols that have the -                                                        // same address. - -                                                        is_gsym = true; -                                                        sym[sym_idx].SetExternal(true); - -                                                        if (symbol_name && symbol_name[0] == '_' && symbol_name[1] ==  'O') -                                                        { -                                                            llvm::StringRef symbol_name_ref(symbol_name); -                                                            if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) -                                                            { -                                                                symbol_name_non_abi_mangled = symbol_name + 1; -                                                                symbol_name = symbol_name + g_objc_v2_prefix_class.size(); -                                                                type = eSymbolTypeObjCClass; -                                                                demangled_is_synthesized = true; - -                                                            } -                                                            else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass)) -                                                            { -                                                                symbol_name_non_abi_mangled = symbol_name + 1; -                                                                symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size(); -                                                                type = eSymbolTypeObjCMetaClass; -                                                                demangled_is_synthesized = true; -                                                            } -                                                            else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar)) -                                                            { -                                                                symbol_name_non_abi_mangled = symbol_name + 1; -                                                                symbol_name = symbol_name + g_objc_v2_prefix_ivar.size(); -                                                                type = eSymbolTypeObjCIVar; -                                                                demangled_is_synthesized = true; -                                                            } -                                                        } -                                                        else -                                                        { -                                                            if (nlist.n_value != 0) -                                                                symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); -                                                            type = eSymbolTypeData; -                                                        } -                                                        break; - -                                                    case N_FNAME: -                                                        // procedure name (f77 kludge): name,,NO_SECT,0,0 -                                                        type = eSymbolTypeCompiler; -                                                        break; - -                                                    case N_FUN: -                                                        // procedure: name,,n_sect,linenumber,address -                                                        if (symbol_name) -                                                        { -                                                            type = eSymbolTypeCode; -                                                            symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); - -                                                            N_FUN_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx)); -                                                            // We use the current number of symbols in the symbol table in lieu of -                                                            // using nlist_idx in case we ever start trimming entries out -                                                            N_FUN_indexes.push_back(sym_idx); -                                                        } -                                                        else -                                                        { -                                                            type = eSymbolTypeCompiler; - -                                                            if ( !N_FUN_indexes.empty() ) -                                                            { -                                                                // Copy the size of the function into the original STAB entry so we don't have -                                                                // to hunt for it later -                                                                symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value); -                                                                N_FUN_indexes.pop_back(); -                                                                // We don't really need the end function STAB as it contains the size which -                                                                // we already placed with the original symbol, so don't add it if we want a -                                                                // minimal symbol table -                                                                add_nlist = false; -                                                            } -                                                        } -                                                        break; - -                                                    case N_STSYM: -                                                        // static symbol: name,,n_sect,type,address -                                                        N_STSYM_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx)); -                                                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); -                                                        if (symbol_name && symbol_name[0]) -                                                        { -                                                            type = ObjectFile::GetSymbolTypeFromName(symbol_name+1, eSymbolTypeData); -                                                        } -                                                        break; - -                                                    case N_LCSYM: -                                                        // .lcomm symbol: name,,n_sect,type,address -                                                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); -                                                        type = eSymbolTypeCommonBlock; -                                                        break; - -                                                    case N_BNSYM: -                                                        // We use the current number of symbols in the symbol table in lieu of -                                                        // using nlist_idx in case we ever start trimming entries out -                                                        // Skip these if we want minimal symbol tables -                                                        add_nlist = false; -                                                        break; - -                                                    case N_ENSYM: -                                                        // Set the size of the N_BNSYM to the terminating index of this N_ENSYM -                                                        // so that we can always skip the entire symbol if we need to navigate -                                                        // more quickly at the source level when parsing STABS -                                                        // Skip these if we want minimal symbol tables -                                                        add_nlist = false; -                                                        break; - -                                                    case N_OPT: -                                                        // emitted with gcc2_compiled and in gcc source -                                                        type = eSymbolTypeCompiler; -                                                        break; - -                                                    case N_RSYM: -                                                        // register sym: name,,NO_SECT,type,register -                                                        type = eSymbolTypeVariable; -                                                        break; - -                                                    case N_SLINE: -                                                        // src line: 0,,n_sect,linenumber,address -                                                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); -                                                        type = eSymbolTypeLineEntry; -                                                        break; - -                                                    case N_SSYM: -                                                        // structure elt: name,,NO_SECT,type,struct_offset -                                                        type = eSymbolTypeVariableType; -                                                        break; - -                                                    case N_SO: -                                                        // source file name -                                                        type = eSymbolTypeSourceFile; -                                                        if (symbol_name == NULL) -                                                        { -                                                            add_nlist = false; -                                                            if (N_SO_index != UINT32_MAX) -                                                            { -                                                                // Set the size of the N_SO to the terminating index of this N_SO -                                                                // so that we can always skip the entire N_SO if we need to navigate -                                                                // more quickly at the source level when parsing STABS -                                                                symbol_ptr = symtab->SymbolAtIndex(N_SO_index); -                                                                symbol_ptr->SetByteSize(sym_idx); -                                                                symbol_ptr->SetSizeIsSibling(true); -                                                            } -                                                            N_NSYM_indexes.clear(); -                                                            N_INCL_indexes.clear(); -                                                            N_BRAC_indexes.clear(); -                                                            N_COMM_indexes.clear(); -                                                            N_FUN_indexes.clear(); -                                                            N_SO_index = UINT32_MAX; -                                                        } -                                                        else -                                                        { -                                                            // We use the current number of symbols in the symbol table in lieu of -                                                            // using nlist_idx in case we ever start trimming entries out -                                                            const bool N_SO_has_full_path = symbol_name[0] == '/'; -                                                            if (N_SO_has_full_path) -                                                            { -                                                                if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) -                                                                { -                                                                    // We have two consecutive N_SO entries where the first contains a directory -                                                                    // and the second contains a full path. -                                                                    sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false); -                                                                    m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1; -                                                                    add_nlist = false; -                                                                } -                                                                else -                                                                { -                                                                    // This is the first entry in a N_SO that contains a directory or -                                                                    // a full path to the source file -                                                                    N_SO_index = sym_idx; -                                                                } -                                                            } -                                                            else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) -                                                            { -                                                                // This is usually the second N_SO entry that contains just the filename, -                                                                // so here we combine it with the first one if we are minimizing the symbol table -                                                                const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName(lldb::eLanguageTypeUnknown).AsCString(); -                                                                if (so_path && so_path[0]) -                                                                { -                                                                    std::string full_so_path (so_path); -                                                                    const size_t double_slash_pos = full_so_path.find("//"); -                                                                    if (double_slash_pos != std::string::npos) -                                                                    { -                                                                        // The linker has been generating bad N_SO entries with doubled up paths -                                                                        // in the format "%s%s" where the first string in the DW_AT_comp_dir, -                                                                        // and the second is the directory for the source file so you end up with -                                                                        // a path that looks like "/tmp/src//tmp/src/" -                                                                        FileSpec so_dir(so_path, false); -                                                                        if (!so_dir.Exists()) -                                                                        { -                                                                            so_dir.SetFile(&full_so_path[double_slash_pos + 1], false); -                                                                            if (so_dir.Exists()) -                                                                            { -                                                                                // Trim off the incorrect path -                                                                                full_so_path.erase(0, double_slash_pos + 1); -                                                                            } -                                                                        } -                                                                    } -                                                                    if (*full_so_path.rbegin() != '/') -                                                                        full_so_path += '/'; -                                                                    full_so_path += symbol_name; -                                                                    sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false); -                                                                    add_nlist = false; -                                                                    m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1; -                                                                } -                                                            } -                                                            else -                                                            { -                                                                // This could be a relative path to a N_SO -                                                                N_SO_index = sym_idx; -                                                            } -                                                        } -                                                        break; - -                                                    case N_OSO: -                                                        // object file name: name,,0,0,st_mtime -                                                        type = eSymbolTypeObjectFile; -                                                        break; - -                                                    case N_LSYM: -                                                        // local sym: name,,NO_SECT,type,offset -                                                        type = eSymbolTypeLocal; -                                                        break; - -                                                        //---------------------------------------------------------------------- -                                                        // INCL scopes -                                                        //---------------------------------------------------------------------- -                                                    case N_BINCL: -                                                        // include file beginning: name,,NO_SECT,0,sum -                                                        // We use the current number of symbols in the symbol table in lieu of -                                                        // using nlist_idx in case we ever start trimming entries out -                                                        N_INCL_indexes.push_back(sym_idx); -                                                        type = eSymbolTypeScopeBegin; -                                                        break; - -                                                    case N_EINCL: -                                                        // include file end: name,,NO_SECT,0,0 -                                                        // Set the size of the N_BINCL to the terminating index of this N_EINCL -                                                        // so that we can always skip the entire symbol if we need to navigate -                                                        // more quickly at the source level when parsing STABS -                                                        if ( !N_INCL_indexes.empty() ) -                                                        { -                                                            symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back()); -                                                            symbol_ptr->SetByteSize(sym_idx + 1); -                                                            symbol_ptr->SetSizeIsSibling(true); -                                                            N_INCL_indexes.pop_back(); -                                                        } -                                                        type = eSymbolTypeScopeEnd; -                                                        break; - -                                                    case N_SOL: -                                                        // #included file name: name,,n_sect,0,address -                                                        type = eSymbolTypeHeaderFile; - -                                                        // We currently don't use the header files on darwin -                                                        add_nlist = false; -                                                        break; - -                                                    case N_PARAMS: -                                                        // compiler parameters: name,,NO_SECT,0,0 -                                                        type = eSymbolTypeCompiler; -                                                        break; - -                                                    case N_VERSION: -                                                        // compiler version: name,,NO_SECT,0,0 -                                                        type = eSymbolTypeCompiler; -                                                        break; - -                                                    case N_OLEVEL: -                                                        // compiler -O level: name,,NO_SECT,0,0 -                                                        type = eSymbolTypeCompiler; -                                                        break; - -                                                    case N_PSYM: -                                                        // parameter: name,,NO_SECT,type,offset -                                                        type = eSymbolTypeVariable; -                                                        break; - -                                                    case N_ENTRY: -                                                        // alternate entry: name,,n_sect,linenumber,address -                                                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); -                                                        type = eSymbolTypeLineEntry; -                                                        break; - -                                                        //---------------------------------------------------------------------- -                                                        // Left and Right Braces -                                                        //---------------------------------------------------------------------- -                                                    case N_LBRAC: -                                                        // left bracket: 0,,NO_SECT,nesting level,address -                                                        // We use the current number of symbols in the symbol table in lieu of -                                                        // using nlist_idx in case we ever start trimming entries out -                                                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); -                                                        N_BRAC_indexes.push_back(sym_idx); -                                                        type = eSymbolTypeScopeBegin; -                                                        break; - -                                                    case N_RBRAC: -                                                        // right bracket: 0,,NO_SECT,nesting level,address -                                                        // Set the size of the N_LBRAC to the terminating index of this N_RBRAC -                                                        // so that we can always skip the entire symbol if we need to navigate -                                                        // more quickly at the source level when parsing STABS -                                                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); -                                                        if ( !N_BRAC_indexes.empty() ) -                                                        { -                                                            symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back()); -                                                            symbol_ptr->SetByteSize(sym_idx + 1); -                                                            symbol_ptr->SetSizeIsSibling(true); -                                                            N_BRAC_indexes.pop_back(); -                                                        } -                                                        type = eSymbolTypeScopeEnd; -                                                        break; - -                                                    case N_EXCL: -                                                        // deleted include file: name,,NO_SECT,0,sum -                                                        type = eSymbolTypeHeaderFile; -                                                        break; - -                                                        //---------------------------------------------------------------------- -                                                        // COMM scopes -                                                        //---------------------------------------------------------------------- -                                                    case N_BCOMM: -                                                        // begin common: name,,NO_SECT,0,0 -                                                        // We use the current number of symbols in the symbol table in lieu of -                                                        // using nlist_idx in case we ever start trimming entries out -                                                        type = eSymbolTypeScopeBegin; -                                                        N_COMM_indexes.push_back(sym_idx); -                                                        break; - -                                                    case N_ECOML: -                                                        // end common (local name): 0,,n_sect,0,address -                                                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); -                                                        // Fall through - -                                                    case N_ECOMM: -                                                        // end common: name,,n_sect,0,0 -                                                        // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML -                                                        // so that we can always skip the entire symbol if we need to navigate -                                                        // more quickly at the source level when parsing STABS -                                                        if ( !N_COMM_indexes.empty() ) -                                                        { -                                                            symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back()); -                                                            symbol_ptr->SetByteSize(sym_idx + 1); -                                                            symbol_ptr->SetSizeIsSibling(true); -                                                            N_COMM_indexes.pop_back(); -                                                        } -                                                        type = eSymbolTypeScopeEnd; -                                                        break; - -                                                    case N_LENG: -                                                        // second stab entry with length information -                                                        type = eSymbolTypeAdditional; -                                                        break; - -                                                    default: break; -                                                } -                                            } -                                            else -                                            { -                                                //uint8_t n_pext    = N_PEXT & nlist.n_type; -                                                uint8_t n_type  = N_TYPE & nlist.n_type; -                                                sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0); - -                                                switch (n_type) -                                                { -                                                    case N_INDR: -                                                        { -                                                            const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value); -                                                            if (reexport_name_cstr && reexport_name_cstr[0]) -                                                            { -                                                                type = eSymbolTypeReExported; -                                                                ConstString reexport_name(reexport_name_cstr + ((reexport_name_cstr[0] == '_') ? 1 : 0)); -                                                                sym[sym_idx].SetReExportedSymbolName(reexport_name); -                                                                set_value = false; -                                                                reexport_shlib_needs_fixup[sym_idx] = reexport_name; -                                                                indirect_symbol_names.insert(ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0))); -                                                            } -                                                            else -                                                                type = eSymbolTypeUndefined; -                                                        } -                                                        break; -                                                         -                                                    case N_UNDF: -                                                        if (symbol_name && symbol_name[0]) -                                                        { -                                                            ConstString undefined_name(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)); -                                                            undefined_name_to_desc[undefined_name] = nlist.n_desc; -                                                        } -                                                        // Fall through -                                                    case N_PBUD: -                                                        type = eSymbolTypeUndefined; -                                                        break; - -                                                    case N_ABS: -                                                        type = eSymbolTypeAbsolute; -                                                        break; - -                                                    case N_SECT: -                                                        { -                                                            symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); - -                                                            if (symbol_section == NULL) -                                                            { -                                                                // TODO: warn about this? -                                                                add_nlist = false; -                                                                break; -                                                            } - -                                                            if (TEXT_eh_frame_sectID == nlist.n_sect) -                                                            { -                                                                type = eSymbolTypeException; -                                                            } -                                                            else -                                                            { -                                                                uint32_t section_type = symbol_section->Get() & SECTION_TYPE; - -                                                                switch (section_type) -                                                                { -                                                                    case S_CSTRING_LITERALS:           type = eSymbolTypeData;    break; // section with only literal C strings -                                                                    case S_4BYTE_LITERALS:             type = eSymbolTypeData;    break; // section with only 4 byte literals -                                                                    case S_8BYTE_LITERALS:             type = eSymbolTypeData;    break; // section with only 8 byte literals -                                                                    case S_LITERAL_POINTERS:           type = eSymbolTypeTrampoline; break; // section with only pointers to literals -                                                                    case S_NON_LAZY_SYMBOL_POINTERS:   type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers -                                                                    case S_LAZY_SYMBOL_POINTERS:       type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers -                                                                    case S_SYMBOL_STUBS:               type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field -                                                                    case S_MOD_INIT_FUNC_POINTERS:     type = eSymbolTypeCode;    break; // section with only function pointers for initialization -                                                                    case S_MOD_TERM_FUNC_POINTERS:     type = eSymbolTypeCode;    break; // section with only function pointers for termination -                                                                    case S_INTERPOSING:                type = eSymbolTypeTrampoline;  break; // section with only pairs of function pointers for interposing -                                                                    case S_16BYTE_LITERALS:            type = eSymbolTypeData;    break; // section with only 16 byte literals -                                                                    case S_DTRACE_DOF:                 type = eSymbolTypeInstrumentation; break; -                                                                    case S_LAZY_DYLIB_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; -                                                                    default: -                                                                        switch (symbol_section->GetType()) -                                                                        { -                                                                            case lldb::eSectionTypeCode: -                                                                                type = eSymbolTypeCode; -                                                                                break; -                                                                            case eSectionTypeData: -                                                                            case eSectionTypeDataCString:            // Inlined C string data -                                                                            case eSectionTypeDataCStringPointers:    // Pointers to C string data -                                                                            case eSectionTypeDataSymbolAddress:      // Address of a symbol in the symbol table -                                                                            case eSectionTypeData4: -                                                                            case eSectionTypeData8: -                                                                            case eSectionTypeData16: -                                                                                type = eSymbolTypeData; -                                                                                break; -                                                                            default: -                                                                                break; -                                                                        } -                                                                        break; -                                                                } - -                                                                if (type == eSymbolTypeInvalid) -                                                                { -                                                                    const char *symbol_sect_name = symbol_section->GetName().AsCString(); -                                                                    if (symbol_section->IsDescendant (text_section_sp.get())) -                                                                    { -                                                                        if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS | -                                                                                                    S_ATTR_SELF_MODIFYING_CODE | -                                                                                                    S_ATTR_SOME_INSTRUCTIONS)) -                                                                            type = eSymbolTypeData; -                                                                        else -                                                                            type = eSymbolTypeCode; -                                                                    } -                                                                    else if (symbol_section->IsDescendant(data_section_sp.get()) || -                                                                             symbol_section->IsDescendant(data_dirty_section_sp.get()) || -                                                                             symbol_section->IsDescendant(data_const_section_sp.get())) -                                                                    { -                                                                        if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name) -                                                                        { -                                                                            type = eSymbolTypeRuntime; -                                                                             -                                                                            if (symbol_name) -                                                                            { -                                                                                llvm::StringRef symbol_name_ref(symbol_name); -                                                                                if (symbol_name_ref.startswith("_OBJC_")) -                                                                                { -                                                                                    static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_"); -                                                                                    static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_"); -                                                                                    static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_"); -                                                                                    if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) -                                                                                    { -                                                                                        symbol_name_non_abi_mangled = symbol_name + 1; -                                                                                        symbol_name = symbol_name + g_objc_v2_prefix_class.size(); -                                                                                        type = eSymbolTypeObjCClass; -                                                                                        demangled_is_synthesized = true; -                                                                                    } -                                                                                    else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass)) -                                                                                    { -                                                                                        symbol_name_non_abi_mangled = symbol_name + 1; -                                                                                        symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size(); -                                                                                        type = eSymbolTypeObjCMetaClass; -                                                                                        demangled_is_synthesized = true; -                                                                                    } -                                                                                    else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar)) -                                                                                    { -                                                                                        symbol_name_non_abi_mangled = symbol_name + 1; -                                                                                        symbol_name = symbol_name + g_objc_v2_prefix_ivar.size(); -                                                                                        type = eSymbolTypeObjCIVar; -                                                                                        demangled_is_synthesized = true; -                                                                                    } -                                                                                } -                                                                            } -                                                                        } -                                                                        else if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name) -                                                                        { -                                                                            type = eSymbolTypeException; -                                                                        } -                                                                        else -                                                                        { -                                                                            type = eSymbolTypeData; -                                                                        } -                                                                    } -                                                                    else if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name) -                                                                    { -                                                                        type = eSymbolTypeTrampoline; -                                                                    } -                                                                    else if (symbol_section->IsDescendant(objc_section_sp.get())) -                                                                    { -                                                                        type = eSymbolTypeRuntime; -                                                                        if (symbol_name && symbol_name[0] == '.') -                                                                        { -                                                                            llvm::StringRef symbol_name_ref(symbol_name); -                                                                            static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_"); -                                                                            if (symbol_name_ref.startswith(g_objc_v1_prefix_class)) -                                                                            { -                                                                                symbol_name_non_abi_mangled = symbol_name; -                                                                                symbol_name = symbol_name + g_objc_v1_prefix_class.size(); -                                                                                type = eSymbolTypeObjCClass; -                                                                                demangled_is_synthesized = true; -                                                                            } -                                                                        } -                                                                    } -                                                                } -                                                            } -                                                        } -                                                        break; -                                                } -                                            } - -                                            if (add_nlist) -                                            { -                                                uint64_t symbol_value = nlist.n_value; -                                                if (symbol_name_non_abi_mangled) -                                                { -                                                    sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled)); -                                                    sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name)); -                                                } -                                                else -                                                { -                                                    bool symbol_name_is_mangled = false; -                                                     -                                                    if (symbol_name && symbol_name[0] == '_') -                                                    { -                                                        symbol_name_is_mangled = symbol_name[1] == '_'; -                                                        symbol_name++;  // Skip the leading underscore -                                                    } - -                                                    if (symbol_name) -                                                    { -                                                        ConstString const_symbol_name(symbol_name); -                                                        sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled); -                                                        if (is_gsym && is_debug) -                                                        { -                                                            const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString(); -                                                            if (gsym_name) -                                                                N_GSYM_name_to_sym_idx[gsym_name] = sym_idx; -                                                        } -                                                    } -                                                } -                                                if (symbol_section) -                                                { -                                                    const addr_t section_file_addr = symbol_section->GetFileAddress(); -                                                    if (symbol_byte_size == 0 && function_starts_count > 0) -                                                    { -                                                        addr_t symbol_lookup_file_addr = nlist.n_value; -                                                        // Do an exact address match for non-ARM addresses, else get the closest since -                                                        // the symbol might be a thumb symbol which has an address with bit zero set -                                                        FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm); -                                                        if (is_arm && func_start_entry) -                                                        { -                                                            // Verify that the function start address is the symbol address (ARM) -                                                            // or the symbol address + 1 (thumb) -                                                            if (func_start_entry->addr != symbol_lookup_file_addr && -                                                                func_start_entry->addr != (symbol_lookup_file_addr + 1)) -                                                            { -                                                                // Not the right entry, NULL it out... -                                                                func_start_entry = NULL; -                                                            } -                                                        } -                                                        if (func_start_entry) -                                                        { -                                                            func_start_entry->data = true; - -                                                            addr_t symbol_file_addr = func_start_entry->addr; -                                                            uint32_t symbol_flags = 0; -                                                            if (is_arm) -                                                            { -                                                                if (symbol_file_addr & 1) -                                                                    symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB; -                                                                symbol_file_addr &= THUMB_ADDRESS_BIT_MASK; -                                                            } - -                                                            const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry); -                                                            const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize(); -                                                            if (next_func_start_entry) -                                                            { -                                                                addr_t next_symbol_file_addr = next_func_start_entry->addr; -                                                                // Be sure the clear the Thumb address bit when we calculate the size -                                                                // from the current and next address -                                                                if (is_arm) -                                                                    next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK; -                                                                symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr); -                                                            } -                                                            else -                                                            { -                                                                symbol_byte_size = section_end_file_addr - symbol_file_addr; -                                                            } -                                                        } -                                                    } -                                                    symbol_value -= section_file_addr; -                                                } - -                                                if (is_debug == false) -                                                { -                                                    if (type == eSymbolTypeCode) -                                                    { -                                                        // See if we can find a N_FUN entry for any code symbols. -                                                        // If we do find a match, and the name matches, then we -                                                        // can merge the two into just the function symbol to avoid -                                                        // duplicate entries in the symbol table -                                                        std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range; -                                                        range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value); -                                                        if (range.first != range.second) -                                                        { -                                                            bool found_it = false; -                                                            for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos) -                                                            { -                                                                if (sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled)) -                                                                { -                                                                    m_nlist_idx_to_sym_idx[nlist_idx] = pos->second; -                                                                    // We just need the flags from the linker symbol, so put these flags -                                                                    // into the N_FUN flags to avoid duplicate symbols in the symbol table -                                                                    sym[pos->second].SetExternal(sym[sym_idx].IsExternal()); -                                                                    sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc); -                                                                    if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end()) -                                                                        sym[pos->second].SetType (eSymbolTypeResolver); -                                                                    sym[sym_idx].Clear(); -                                                                    found_it = true; -                                                                    break; -                                                                } -                                                            } -                                                            if (found_it) -                                                                continue; -                                                        } -                                                        else -                                                        { -                                                            if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end()) -                                                                type = eSymbolTypeResolver; -                                                        } -                                                    } -                                                    else if (type == eSymbolTypeData          || -                                                             type == eSymbolTypeObjCClass     || -                                                             type == eSymbolTypeObjCMetaClass || -                                                             type == eSymbolTypeObjCIVar      ) -                                                    { -                                                        // See if we can find a N_STSYM entry for any data symbols. -                                                        // If we do find a match, and the name matches, then we -                                                        // can merge the two into just the Static symbol to avoid -                                                        // duplicate entries in the symbol table -                                                        std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range; -                                                        range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value); -                                                        if (range.first != range.second) -                                                        { -                                                            bool found_it = false; -                                                            for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos) -                                                            { -                                                                if (sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled)) -                                                                { -                                                                    m_nlist_idx_to_sym_idx[nlist_idx] = pos->second; -                                                                    // We just need the flags from the linker symbol, so put these flags -                                                                    // into the N_STSYM flags to avoid duplicate symbols in the symbol table -                                                                    sym[pos->second].SetExternal(sym[sym_idx].IsExternal()); -                                                                    sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc); -                                                                    sym[sym_idx].Clear(); -                                                                    found_it = true; -                                                                    break; -                                                                } -                                                            } -                                                            if (found_it) -                                                                continue; -                                                        } -                                                        else -                                                        { -                                                            const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString(); -                                                            if (gsym_name) -                                                            { -                                                                // Combine N_GSYM stab entries with the non stab symbol -                                                                ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(gsym_name); -                                                                if (pos != N_GSYM_name_to_sym_idx.end()) -                                                                { -                                                                    const uint32_t GSYM_sym_idx = pos->second; -                                                                    m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx; -                                                                    // Copy the address, because often the N_GSYM address has an invalid address of zero -                                                                    // when the global is a common symbol -                                                                    sym[GSYM_sym_idx].GetAddressRef().SetSection (symbol_section); -                                                                    sym[GSYM_sym_idx].GetAddressRef().SetOffset (symbol_value); -                                                                    // We just need the flags from the linker symbol, so put these flags -                                                                    // into the N_GSYM flags to avoid duplicate symbols in the symbol table -                                                                    sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc); -                                                                    sym[sym_idx].Clear(); -                                                                    continue; -                                                                } -                                                            } -                                                        } -                                                    } -                                                } - -                                                sym[sym_idx].SetID (nlist_idx); -                                                sym[sym_idx].SetType (type); -                                                if (set_value) -                                                { -                                                    sym[sym_idx].GetAddressRef().SetSection (symbol_section); -                                                    sym[sym_idx].GetAddressRef().SetOffset (symbol_value); -                                                } -                                                sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc); - -                                                if (symbol_byte_size > 0) -                                                    sym[sym_idx].SetByteSize(symbol_byte_size); - -                                                if (demangled_is_synthesized) -                                                    sym[sym_idx].SetDemangledNameIsSynthesized(true); -                                                ++sym_idx; -                                            } -                                            else -                                            { -                                                sym[sym_idx].Clear(); -                                            } - -                                        } -                                        ///////////////////////////// -                                    } -                                    break; // No more entries to consider -                                } -                            } +    // For user process binaries (executables, dylibs, frameworks, bundles), if +    // we don't have +    // LC_FUNCTION_STARTS/eh_frame section in this binary, we're going to assume +    // the binary +    // has been stripped.  Don't allow assembly language instruction emulation +    // because we don't +    // know proper function start boundaries. +    // +    // For all other types of binaries (kernels, stand-alone bare board +    // binaries, kexts), they +    // may not have LC_FUNCTION_STARTS / eh_frame sections - we should not make +    // any assumptions +    // about them based on that. +    if (function_starts_count == 0 && CalculateStrata() == eStrataUser) { +      m_allow_assembly_emulation_unwind_plans = false; +      Log *unwind_or_symbol_log(lldb_private::GetLogIfAnyCategoriesSet( +          LIBLLDB_LOG_SYMBOLS | LIBLLDB_LOG_UNWIND)); + +      if (unwind_or_symbol_log) +        module_sp->LogMessage( +            unwind_or_symbol_log, +            "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds"); +    } -                            for (const auto &pos :reexport_shlib_needs_fixup) -                            { -                                const auto undef_pos = undefined_name_to_desc.find(pos.second); -                                if (undef_pos != undefined_name_to_desc.end()) -                                { -                                    const uint8_t dylib_ordinal = llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second); -                                    if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize()) -                                        sym[pos.first].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(dylib_ordinal-1)); -                                } -                            } -                        } -                    } -                } -            } +    const user_id_t TEXT_eh_frame_sectID = +        eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() +                                  : static_cast<user_id_t>(NO_SECT); + +    lldb::offset_t nlist_data_offset = 0; + +    uint32_t N_SO_index = UINT32_MAX; + +    MachSymtabSectionInfo section_info(section_list); +    std::vector<uint32_t> N_FUN_indexes; +    std::vector<uint32_t> N_NSYM_indexes; +    std::vector<uint32_t> N_INCL_indexes; +    std::vector<uint32_t> N_BRAC_indexes; +    std::vector<uint32_t> N_COMM_indexes; +    typedef std::multimap<uint64_t, uint32_t> ValueToSymbolIndexMap; +    typedef std::map<uint32_t, uint32_t> NListIndexToSymbolIndexMap; +    typedef std::map<const char *, uint32_t> ConstNameToSymbolIndexMap; +    ValueToSymbolIndexMap N_FUN_addr_to_sym_idx; +    ValueToSymbolIndexMap N_STSYM_addr_to_sym_idx; +    ConstNameToSymbolIndexMap N_GSYM_name_to_sym_idx; +    // Any symbols that get merged into another will get an entry +    // in this map so we know +    NListIndexToSymbolIndexMap m_nlist_idx_to_sym_idx; +    uint32_t nlist_idx = 0; +    Symbol *symbol_ptr = NULL; + +    uint32_t sym_idx = 0; +    Symbol *sym = NULL; +    size_t num_syms = 0; +    std::string memory_symbol_name; +    uint32_t unmapped_local_symbols_found = 0; + +    std::vector<TrieEntryWithOffset> trie_entries; +    std::set<lldb::addr_t> resolver_addresses; + +    if (dyld_trie_data.GetByteSize() > 0) { +      std::vector<llvm::StringRef> nameSlices; +      ParseTrieEntries(dyld_trie_data, 0, is_arm, nameSlices, +                       resolver_addresses, trie_entries); + +      ConstString text_segment_name("__TEXT"); +      SectionSP text_segment_sp = +          GetSectionList()->FindSectionByName(text_segment_name); +      if (text_segment_sp) { +        const lldb::addr_t text_segment_file_addr = +            text_segment_sp->GetFileAddress(); +        if (text_segment_file_addr != LLDB_INVALID_ADDRESS) { +          for (auto &e : trie_entries) +            e.entry.address += text_segment_file_addr;          } +      } +    } -        // Must reset this in case it was mutated above! -        nlist_data_offset = 0; -#endif - -        if (nlist_data.GetByteSize() > 0) -        { - -            // If the sym array was not created while parsing the DSC unmapped -            // symbols, create it now. -            if (sym == NULL) -            { -                sym = symtab->Resize (symtab_load_command.nsyms + m_dysymtab.nindirectsyms); -                num_syms = symtab->GetNumSymbols(); -            } - -            if (unmapped_local_symbols_found) -            { -                assert(m_dysymtab.ilocalsym == 0); -                nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size); -                nlist_idx = m_dysymtab.nlocalsym; -            } -            else -            { -                nlist_idx = 0; -            } - -            typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap; -            typedef std::map<uint32_t, ConstString> SymbolIndexToName; -            UndefinedNameToDescMap undefined_name_to_desc; -            SymbolIndexToName reexport_shlib_needs_fixup; -            for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) -            { -                struct nlist_64 nlist; -                if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, nlist_byte_size)) -                    break; - -                nlist.n_strx  = nlist_data.GetU32_unchecked(&nlist_data_offset); -                nlist.n_type  = nlist_data.GetU8_unchecked (&nlist_data_offset); -                nlist.n_sect  = nlist_data.GetU8_unchecked (&nlist_data_offset); -                nlist.n_desc  = nlist_data.GetU16_unchecked (&nlist_data_offset); -                nlist.n_value = nlist_data.GetAddress_unchecked (&nlist_data_offset); - -                SymbolType type = eSymbolTypeInvalid; -                const char *symbol_name = NULL; - -                if (have_strtab_data) -                { -                    symbol_name = strtab_data.PeekCStr(nlist.n_strx); +    typedef std::set<ConstString> IndirectSymbols; +    IndirectSymbols indirect_symbol_names; + +#if defined(__APPLE__) &&                                                      \ +    (defined(__arm__) || defined(__arm64__) || defined(__aarch64__)) + +    // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been +    // optimized by moving LOCAL +    // symbols out of the memory mapped portion of the DSC. The symbol +    // information has all been retained, +    // but it isn't available in the normal nlist data. However, there *are* +    // duplicate entries of *some* +    // LOCAL symbols in the normal nlist data. To handle this situation +    // correctly, we must first attempt +    // to parse any DSC unmapped symbol information. If we find any, we set a +    // flag that tells the normal +    // nlist parser to ignore all LOCAL symbols. + +    if (m_header.flags & 0x80000000u) { +      // Before we can start mapping the DSC, we need to make certain the target +      // process is actually +      // using the cache we can find. + +      // Next we need to determine the correct path for the dyld shared cache. + +      ArchSpec header_arch; +      GetArchitecture(header_arch); +      char dsc_path[PATH_MAX]; +      char dsc_path_development[PATH_MAX]; + +      snprintf( +          dsc_path, sizeof(dsc_path), "%s%s%s", +          "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR +                                                       */ +          "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */ +          header_arch.GetArchitectureName()); + +      snprintf( +          dsc_path_development, sizeof(dsc_path), "%s%s%s%s", +          "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR +                                                       */ +          "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */ +          header_arch.GetArchitectureName(), ".development"); + +      FileSpec dsc_nondevelopment_filespec(dsc_path, false); +      FileSpec dsc_development_filespec(dsc_path_development, false); +      FileSpec dsc_filespec; + +      UUID dsc_uuid; +      UUID process_shared_cache_uuid; + +      if (process) { +        process_shared_cache_uuid = GetProcessSharedCacheUUID(process); +      } + +      // First see if we can find an exact match for the inferior process shared +      // cache UUID in +      // the development or non-development shared caches on disk. +      if (process_shared_cache_uuid.IsValid()) { +        if (dsc_development_filespec.Exists()) { +          UUID dsc_development_uuid = GetSharedCacheUUID( +              dsc_development_filespec, byte_order, addr_byte_size); +          if (dsc_development_uuid.IsValid() && +              dsc_development_uuid == process_shared_cache_uuid) { +            dsc_filespec = dsc_development_filespec; +            dsc_uuid = dsc_development_uuid; +          } +        } +        if (!dsc_uuid.IsValid() && dsc_nondevelopment_filespec.Exists()) { +          UUID dsc_nondevelopment_uuid = GetSharedCacheUUID( +              dsc_nondevelopment_filespec, byte_order, addr_byte_size); +          if (dsc_nondevelopment_uuid.IsValid() && +              dsc_nondevelopment_uuid == process_shared_cache_uuid) { +            dsc_filespec = dsc_nondevelopment_filespec; +            dsc_uuid = dsc_nondevelopment_uuid; +          } +        } +      } + +      // Failing a UUID match, prefer the development dyld_shared cache if both +      // are present. +      if (!dsc_filespec.Exists()) { +        if (dsc_development_filespec.Exists()) { +          dsc_filespec = dsc_development_filespec; +        } else { +          dsc_filespec = dsc_nondevelopment_filespec; +        } +      } + +      /* The dyld_cache_header has a pointer to the +         dyld_cache_local_symbols_info structure (localSymbolsOffset). +         The dyld_cache_local_symbols_info structure gives us three things: +           1. The start and count of the nlist records in the dyld_shared_cache +         file +           2. The start and size of the strings for these nlist records +           3. The start and count of dyld_cache_local_symbols_entry entries + +         There is one dyld_cache_local_symbols_entry per dylib/framework in the +         dyld shared cache. +         The "dylibOffset" field is the Mach-O header of this dylib/framework in +         the dyld shared cache. +         The dyld_cache_local_symbols_entry also lists the start of this +         dylib/framework's nlist records +         and the count of how many nlist records there are for this +         dylib/framework. +      */ + +      // Process the dyld shared cache header to find the unmapped symbols + +      DataBufferSP dsc_data_sp = dsc_filespec.MemoryMapFileContentsIfLocal( +          0, sizeof(struct lldb_copy_dyld_cache_header_v1)); +      if (!dsc_uuid.IsValid()) { +        dsc_uuid = GetSharedCacheUUID(dsc_filespec, byte_order, addr_byte_size); +      } +      if (dsc_data_sp) { +        DataExtractor dsc_header_data(dsc_data_sp, byte_order, addr_byte_size); + +        bool uuid_match = true; +        if (dsc_uuid.IsValid() && process) { +          if (process_shared_cache_uuid.IsValid() && +              dsc_uuid != process_shared_cache_uuid) { +            // The on-disk dyld_shared_cache file is not the same as the one in +            // this +            // process' memory, don't use it. +            uuid_match = false; +            ModuleSP module_sp(GetModule()); +            if (module_sp) +              module_sp->ReportWarning("process shared cache does not match " +                                       "on-disk dyld_shared_cache file, some " +                                       "symbol names will be missing."); +          } +        } -                    if (symbol_name == NULL) +        offset = offsetof(struct lldb_copy_dyld_cache_header_v1, mappingOffset); + +        uint32_t mappingOffset = dsc_header_data.GetU32(&offset); + +        // If the mappingOffset points to a location inside the header, we've +        // opened an old dyld shared cache, and should not proceed further. +        if (uuid_match && +            mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v1)) { + +          DataBufferSP dsc_mapping_info_data_sp = +              dsc_filespec.MemoryMapFileContentsIfLocal( +                  mappingOffset, +                  sizeof(struct lldb_copy_dyld_cache_mapping_info)); +          DataExtractor dsc_mapping_info_data(dsc_mapping_info_data_sp, +                                              byte_order, addr_byte_size); +          offset = 0; + +          // The File addresses (from the in-memory Mach-O load commands) for +          // the shared libraries +          // in the shared library cache need to be adjusted by an offset to +          // match up with the +          // dylibOffset identifying field in the +          // dyld_cache_local_symbol_entry's.  This offset is +          // recorded in mapping_offset_value. +          const uint64_t mapping_offset_value = +              dsc_mapping_info_data.GetU64(&offset); + +          offset = offsetof(struct lldb_copy_dyld_cache_header_v1, +                            localSymbolsOffset); +          uint64_t localSymbolsOffset = dsc_header_data.GetU64(&offset); +          uint64_t localSymbolsSize = dsc_header_data.GetU64(&offset); + +          if (localSymbolsOffset && localSymbolsSize) { +            // Map the local symbols +            if (DataBufferSP dsc_local_symbols_data_sp = +                    dsc_filespec.MemoryMapFileContentsIfLocal( +                        localSymbolsOffset, localSymbolsSize)) { +              DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp, +                                                   byte_order, addr_byte_size); + +              offset = 0; + +              typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap; +              typedef std::map<uint32_t, ConstString> SymbolIndexToName; +              UndefinedNameToDescMap undefined_name_to_desc; +              SymbolIndexToName reexport_shlib_needs_fixup; + +              // Read the local_symbols_infos struct in one shot +              struct lldb_copy_dyld_cache_local_symbols_info local_symbols_info; +              dsc_local_symbols_data.GetU32(&offset, +                                            &local_symbols_info.nlistOffset, 6); + +              SectionSP text_section_sp( +                  section_list->FindSectionByName(GetSegmentNameTEXT())); + +              uint32_t header_file_offset = +                  (text_section_sp->GetFileAddress() - mapping_offset_value); + +              offset = local_symbols_info.entriesOffset; +              for (uint32_t entry_index = 0; +                   entry_index < local_symbols_info.entriesCount; +                   entry_index++) { +                struct lldb_copy_dyld_cache_local_symbols_entry +                    local_symbols_entry; +                local_symbols_entry.dylibOffset = +                    dsc_local_symbols_data.GetU32(&offset); +                local_symbols_entry.nlistStartIndex = +                    dsc_local_symbols_data.GetU32(&offset); +                local_symbols_entry.nlistCount = +                    dsc_local_symbols_data.GetU32(&offset); + +                if (header_file_offset == local_symbols_entry.dylibOffset) { +                  unmapped_local_symbols_found = local_symbols_entry.nlistCount; + +                  // The normal nlist code cannot correctly size the Symbols +                  // array, we need to allocate it here. +                  sym = symtab->Resize( +                      symtab_load_command.nsyms + m_dysymtab.nindirectsyms + +                      unmapped_local_symbols_found - m_dysymtab.nlocalsym); +                  num_syms = symtab->GetNumSymbols(); + +                  nlist_data_offset = +                      local_symbols_info.nlistOffset + +                      (nlist_byte_size * local_symbols_entry.nlistStartIndex); +                  uint32_t string_table_offset = +                      local_symbols_info.stringsOffset; + +                  for (uint32_t nlist_index = 0; +                       nlist_index < local_symbols_entry.nlistCount; +                       nlist_index++) { +                    /////////////////////////////                      { +                      struct nlist_64 nlist; +                      if (!dsc_local_symbols_data.ValidOffsetForDataOfSize( +                              nlist_data_offset, nlist_byte_size)) +                        break; + +                      nlist.n_strx = dsc_local_symbols_data.GetU32_unchecked( +                          &nlist_data_offset); +                      nlist.n_type = dsc_local_symbols_data.GetU8_unchecked( +                          &nlist_data_offset); +                      nlist.n_sect = dsc_local_symbols_data.GetU8_unchecked( +                          &nlist_data_offset); +                      nlist.n_desc = dsc_local_symbols_data.GetU16_unchecked( +                          &nlist_data_offset); +                      nlist.n_value = +                          dsc_local_symbols_data.GetAddress_unchecked( +                              &nlist_data_offset); + +                      SymbolType type = eSymbolTypeInvalid; +                      const char *symbol_name = dsc_local_symbols_data.PeekCStr( +                          string_table_offset + nlist.n_strx); + +                      if (symbol_name == NULL) {                          // No symbol should be NULL, even the symbols with no                          // string values should have an offset zero which points                          // to an empty C-string -                        Host::SystemLog (Host::eSystemLogError, -                                         "error: symbol[%u] has invalid string table offset 0x%x in %s, ignoring symbol\n", -                                         nlist_idx, -                                         nlist.n_strx, -                                         module_sp->GetFileSpec().GetPath().c_str()); +                        Host::SystemLog( +                            Host::eSystemLogError, +                            "error: DSC unmapped local symbol[%u] has invalid " +                            "string table offset 0x%x in %s, ignoring symbol\n", +                            entry_index, nlist.n_strx, +                            module_sp->GetFileSpec().GetPath().c_str());                          continue; -                    } -                    if (symbol_name[0] == '\0') +                      } +                      if (symbol_name[0] == '\0')                          symbol_name = NULL; -                } -                else -                { -                    const addr_t str_addr = strtab_addr + nlist.n_strx; -                    Error str_error; -                    if (process->ReadCStringFromMemory(str_addr, memory_symbol_name, str_error)) -                        symbol_name = memory_symbol_name.c_str(); -                } -                const char *symbol_name_non_abi_mangled = NULL; - -                SectionSP symbol_section; -                lldb::addr_t symbol_byte_size = 0; -                bool add_nlist = true; -                bool is_gsym = false; -                bool is_debug = ((nlist.n_type & N_STAB) != 0); -                bool demangled_is_synthesized = false; -                bool set_value = true; -                assert (sym_idx < num_syms); - -                sym[sym_idx].SetDebug (is_debug); - -                if (is_debug) -                { -                    switch (nlist.n_type) -                    { -                    case N_GSYM: -                        // global symbol: name,,NO_SECT,type,0 -                        // Sometimes the N_GSYM value contains the address. - -                        // FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data.  They -                        // have the same address, but we want to ensure that we always find only the real symbol, -                        // 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass -                        // symbol type.  This is a temporary hack to make sure the ObjectiveC symbols get treated -                        // correctly.  To do this right, we should coalesce all the GSYM & global symbols that have the -                        // same address. -                        is_gsym = true; -                        sym[sym_idx].SetExternal(true); - -                        if (symbol_name && symbol_name[0] == '_' && symbol_name[1] ==  'O') -                        { + +                      const char *symbol_name_non_abi_mangled = NULL; + +                      SectionSP symbol_section; +                      uint32_t symbol_byte_size = 0; +                      bool add_nlist = true; +                      bool is_debug = ((nlist.n_type & N_STAB) != 0); +                      bool demangled_is_synthesized = false; +                      bool is_gsym = false; +                      bool set_value = true; + +                      assert(sym_idx < num_syms); + +                      sym[sym_idx].SetDebug(is_debug); + +                      if (is_debug) { +                        switch (nlist.n_type) { +                        case N_GSYM: +                          // global symbol: name,,NO_SECT,type,0 +                          // Sometimes the N_GSYM value contains the address. + +                          // FIXME: In the .o files, we have a GSYM and a debug +                          // symbol for all the ObjC data.  They +                          // have the same address, but we want to ensure that +                          // we always find only the real symbol, +                          // 'cause we don't currently correctly attribute the +                          // GSYM one to the ObjCClass/Ivar/MetaClass +                          // symbol type.  This is a temporary hack to make sure +                          // the ObjectiveC symbols get treated +                          // correctly.  To do this right, we should coalesce +                          // all the GSYM & global symbols that have the +                          // same address. + +                          is_gsym = true; +                          sym[sym_idx].SetExternal(true); + +                          if (symbol_name && symbol_name[0] == '_' && +                              symbol_name[1] == 'O') {                              llvm::StringRef symbol_name_ref(symbol_name); -                            if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) -                            { -                                symbol_name_non_abi_mangled = symbol_name + 1; -                                symbol_name = symbol_name + g_objc_v2_prefix_class.size(); -                                type = eSymbolTypeObjCClass; -                                demangled_is_synthesized = true; -                                 -                            } -                            else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass)) -                            { -                                symbol_name_non_abi_mangled = symbol_name + 1; -                                symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size(); -                                type = eSymbolTypeObjCMetaClass; -                                demangled_is_synthesized = true; +                            if (symbol_name_ref.startswith( +                                    g_objc_v2_prefix_class)) { +                              symbol_name_non_abi_mangled = symbol_name + 1; +                              symbol_name = +                                  symbol_name + g_objc_v2_prefix_class.size(); +                              type = eSymbolTypeObjCClass; +                              demangled_is_synthesized = true; + +                            } else if (symbol_name_ref.startswith( +                                           g_objc_v2_prefix_metaclass)) { +                              symbol_name_non_abi_mangled = symbol_name + 1; +                              symbol_name = symbol_name + +                                            g_objc_v2_prefix_metaclass.size(); +                              type = eSymbolTypeObjCMetaClass; +                              demangled_is_synthesized = true; +                            } else if (symbol_name_ref.startswith( +                                           g_objc_v2_prefix_ivar)) { +                              symbol_name_non_abi_mangled = symbol_name + 1; +                              symbol_name = +                                  symbol_name + g_objc_v2_prefix_ivar.size(); +                              type = eSymbolTypeObjCIVar; +                              demangled_is_synthesized = true;                              } -                            else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar)) -                            { -                                symbol_name_non_abi_mangled = symbol_name + 1; -                                symbol_name = symbol_name + g_objc_v2_prefix_ivar.size(); -                                type = eSymbolTypeObjCIVar; -                                demangled_is_synthesized = true; -                            } -                        } -                        else -                        { +                          } else {                              if (nlist.n_value != 0) -                                symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); +                              symbol_section = section_info.GetSection( +                                  nlist.n_sect, nlist.n_value);                              type = eSymbolTypeData; -                        } -                        break; +                          } +                          break; -                    case N_FNAME: -                        // procedure name (f77 kludge): name,,NO_SECT,0,0 -                        type = eSymbolTypeCompiler; -                        break; +                        case N_FNAME: +                          // procedure name (f77 kludge): name,,NO_SECT,0,0 +                          type = eSymbolTypeCompiler; +                          break; -                    case N_FUN: -                        // procedure: name,,n_sect,linenumber,address -                        if (symbol_name) -                        { +                        case N_FUN: +                          // procedure: name,,n_sect,linenumber,address +                          if (symbol_name) {                              type = eSymbolTypeCode; -                            symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); - -                            N_FUN_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx)); -                            // We use the current number of symbols in the symbol table in lieu of -                            // using nlist_idx in case we ever start trimming entries out +                            symbol_section = section_info.GetSection( +                                nlist.n_sect, nlist.n_value); + +                            N_FUN_addr_to_sym_idx.insert( +                                std::make_pair(nlist.n_value, sym_idx)); +                            // We use the current number of symbols in the +                            // symbol table in lieu of +                            // using nlist_idx in case we ever start trimming +                            // entries out                              N_FUN_indexes.push_back(sym_idx); -                        } -                        else -                        { +                          } else {                              type = eSymbolTypeCompiler; -                            if ( !N_FUN_indexes.empty() ) -                            { -                                // Copy the size of the function into the original STAB entry so we don't have -                                // to hunt for it later -                                symtab->SymbolAtIndex(N_FUN_indexes.back())->SetByteSize(nlist.n_value); -                                N_FUN_indexes.pop_back(); -                                // We don't really need the end function STAB as it contains the size which -                                // we already placed with the original symbol, so don't add it if we want a -                                // minimal symbol table -                                add_nlist = false; +                            if (!N_FUN_indexes.empty()) { +                              // Copy the size of the function into the original +                              // STAB entry so we don't have +                              // to hunt for it later +                              symtab->SymbolAtIndex(N_FUN_indexes.back()) +                                  ->SetByteSize(nlist.n_value); +                              N_FUN_indexes.pop_back(); +                              // We don't really need the end function STAB as +                              // it contains the size which +                              // we already placed with the original symbol, so +                              // don't add it if we want a +                              // minimal symbol table +                              add_nlist = false;                              } -                        } -                        break; - -                    case N_STSYM: -                        // static symbol: name,,n_sect,type,address -                        N_STSYM_addr_to_sym_idx.insert(std::make_pair(nlist.n_value, sym_idx)); -                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); -                        if (symbol_name && symbol_name[0]) -                        { -                            type = ObjectFile::GetSymbolTypeFromName(symbol_name+1, eSymbolTypeData); -                        } -                        break; - -                    case N_LCSYM: -                        // .lcomm symbol: name,,n_sect,type,address -                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); -                        type = eSymbolTypeCommonBlock; -                        break; - -                    case N_BNSYM: -                        // We use the current number of symbols in the symbol table in lieu of -                        // using nlist_idx in case we ever start trimming entries out -                        // Skip these if we want minimal symbol tables -                        add_nlist = false; -                        break; - -                    case N_ENSYM: -                        // Set the size of the N_BNSYM to the terminating index of this N_ENSYM -                        // so that we can always skip the entire symbol if we need to navigate -                        // more quickly at the source level when parsing STABS -                        // Skip these if we want minimal symbol tables -                        add_nlist = false; -                        break; - - -                    case N_OPT: -                        // emitted with gcc2_compiled and in gcc source -                        type = eSymbolTypeCompiler; -                        break; - -                    case N_RSYM: -                        // register sym: name,,NO_SECT,type,register -                        type = eSymbolTypeVariable; -                        break; - -                    case N_SLINE: -                        // src line: 0,,n_sect,linenumber,address -                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); -                        type = eSymbolTypeLineEntry; -                        break; - -                    case N_SSYM: -                        // structure elt: name,,NO_SECT,type,struct_offset -                        type = eSymbolTypeVariableType; -                        break; - -                    case N_SO: -                        // source file name -                        type = eSymbolTypeSourceFile; -                        if (symbol_name == NULL) -                        { +                          } +                          break; + +                        case N_STSYM: +                          // static symbol: name,,n_sect,type,address +                          N_STSYM_addr_to_sym_idx.insert( +                              std::make_pair(nlist.n_value, sym_idx)); +                          symbol_section = section_info.GetSection( +                              nlist.n_sect, nlist.n_value); +                          if (symbol_name && symbol_name[0]) { +                            type = ObjectFile::GetSymbolTypeFromName( +                                symbol_name + 1, eSymbolTypeData); +                          } +                          break; + +                        case N_LCSYM: +                          // .lcomm symbol: name,,n_sect,type,address +                          symbol_section = section_info.GetSection( +                              nlist.n_sect, nlist.n_value); +                          type = eSymbolTypeCommonBlock; +                          break; + +                        case N_BNSYM: +                          // We use the current number of symbols in the symbol +                          // table in lieu of +                          // using nlist_idx in case we ever start trimming +                          // entries out +                          // Skip these if we want minimal symbol tables +                          add_nlist = false; +                          break; + +                        case N_ENSYM: +                          // Set the size of the N_BNSYM to the terminating +                          // index of this N_ENSYM +                          // so that we can always skip the entire symbol if we +                          // need to navigate +                          // more quickly at the source level when parsing STABS +                          // Skip these if we want minimal symbol tables +                          add_nlist = false; +                          break; + +                        case N_OPT: +                          // emitted with gcc2_compiled and in gcc source +                          type = eSymbolTypeCompiler; +                          break; + +                        case N_RSYM: +                          // register sym: name,,NO_SECT,type,register +                          type = eSymbolTypeVariable; +                          break; + +                        case N_SLINE: +                          // src line: 0,,n_sect,linenumber,address +                          symbol_section = section_info.GetSection( +                              nlist.n_sect, nlist.n_value); +                          type = eSymbolTypeLineEntry; +                          break; + +                        case N_SSYM: +                          // structure elt: name,,NO_SECT,type,struct_offset +                          type = eSymbolTypeVariableType; +                          break; + +                        case N_SO: +                          // source file name +                          type = eSymbolTypeSourceFile; +                          if (symbol_name == NULL) {                              add_nlist = false; -                            if (N_SO_index != UINT32_MAX) -                            { -                                // Set the size of the N_SO to the terminating index of this N_SO -                                // so that we can always skip the entire N_SO if we need to navigate -                                // more quickly at the source level when parsing STABS -                                symbol_ptr = symtab->SymbolAtIndex(N_SO_index); -                                symbol_ptr->SetByteSize(sym_idx); -                                symbol_ptr->SetSizeIsSibling(true); +                            if (N_SO_index != UINT32_MAX) { +                              // Set the size of the N_SO to the terminating +                              // index of this N_SO +                              // so that we can always skip the entire N_SO if +                              // we need to navigate +                              // more quickly at the source level when parsing +                              // STABS +                              symbol_ptr = symtab->SymbolAtIndex(N_SO_index); +                              symbol_ptr->SetByteSize(sym_idx); +                              symbol_ptr->SetSizeIsSibling(true);                              }                              N_NSYM_indexes.clear();                              N_INCL_indexes.clear(); @@ -3936,2204 +3034,3061 @@ ObjectFileMachO::ParseSymtab ()                              N_COMM_indexes.clear();                              N_FUN_indexes.clear();                              N_SO_index = UINT32_MAX; -                        } -                        else -                        { -                            // We use the current number of symbols in the symbol table in lieu of -                            // using nlist_idx in case we ever start trimming entries out -                            const bool N_SO_has_full_path = symbol_name[0] == '/'; -                            if (N_SO_has_full_path) -                            { -                                if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) -                                { -                                    // We have two consecutive N_SO entries where the first contains a directory -                                    // and the second contains a full path. -                                    sym[sym_idx - 1].GetMangled().SetValue(ConstString(symbol_name), false); -                                    m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1; -                                    add_nlist = false; -                                } -                                else -                                { -                                    // This is the first entry in a N_SO that contains a directory or -                                    // a full path to the source file -                                    N_SO_index = sym_idx; -                                } -                            } -                            else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) -                            { -                                // This is usually the second N_SO entry that contains just the filename, -                                // so here we combine it with the first one if we are minimizing the symbol table -                                const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName(lldb::eLanguageTypeUnknown).AsCString(); -                                if (so_path && so_path[0]) -                                { -                                    std::string full_so_path (so_path); -                                    const size_t double_slash_pos = full_so_path.find("//"); -                                    if (double_slash_pos != std::string::npos) -                                    { -                                        // The linker has been generating bad N_SO entries with doubled up paths -                                        // in the format "%s%s" where the first string in the DW_AT_comp_dir, -                                        // and the second is the directory for the source file so you end up with -                                        // a path that looks like "/tmp/src//tmp/src/" -                                        FileSpec so_dir(so_path, false); -                                        if (!so_dir.Exists()) -                                        { -                                            so_dir.SetFile(&full_so_path[double_slash_pos + 1], false); -                                            if (so_dir.Exists()) -                                            { -                                                // Trim off the incorrect path -                                                full_so_path.erase(0, double_slash_pos + 1); -                                            } -                                        } +                          } else { +                            // We use the current number of symbols in the +                            // symbol table in lieu of +                            // using nlist_idx in case we ever start trimming +                            // entries out +                            const bool N_SO_has_full_path = +                                symbol_name[0] == '/'; +                            if (N_SO_has_full_path) { +                              if ((N_SO_index == sym_idx - 1) && +                                  ((sym_idx - 1) < num_syms)) { +                                // We have two consecutive N_SO entries where +                                // the first contains a directory +                                // and the second contains a full path. +                                sym[sym_idx - 1].GetMangled().SetValue( +                                    ConstString(symbol_name), false); +                                m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1; +                                add_nlist = false; +                              } else { +                                // This is the first entry in a N_SO that +                                // contains a directory or +                                // a full path to the source file +                                N_SO_index = sym_idx; +                              } +                            } else if ((N_SO_index == sym_idx - 1) && +                                       ((sym_idx - 1) < num_syms)) { +                              // This is usually the second N_SO entry that +                              // contains just the filename, +                              // so here we combine it with the first one if we +                              // are minimizing the symbol table +                              const char *so_path = +                                  sym[sym_idx - 1] +                                      .GetMangled() +                                      .GetDemangledName( +                                          lldb::eLanguageTypeUnknown) +                                      .AsCString(); +                              if (so_path && so_path[0]) { +                                std::string full_so_path(so_path); +                                const size_t double_slash_pos = +                                    full_so_path.find("//"); +                                if (double_slash_pos != std::string::npos) { +                                  // The linker has been generating bad N_SO +                                  // entries with doubled up paths +                                  // in the format "%s%s" where the first string +                                  // in the DW_AT_comp_dir, +                                  // and the second is the directory for the +                                  // source file so you end up with +                                  // a path that looks like "/tmp/src//tmp/src/" +                                  FileSpec so_dir(so_path, false); +                                  if (!so_dir.Exists()) { +                                    so_dir.SetFile( +                                        &full_so_path[double_slash_pos + 1], +                                        false); +                                    if (so_dir.Exists()) { +                                      // Trim off the incorrect path +                                      full_so_path.erase(0, +                                                         double_slash_pos + 1);                                      } -                                    if (*full_so_path.rbegin() != '/') -                                        full_so_path += '/'; -                                    full_so_path += symbol_name; -                                    sym[sym_idx - 1].GetMangled().SetValue(ConstString(full_so_path.c_str()), false); -                                    add_nlist = false; -                                    m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1; +                                  }                                  } +                                if (*full_so_path.rbegin() != '/') +                                  full_so_path += '/'; +                                full_so_path += symbol_name; +                                sym[sym_idx - 1].GetMangled().SetValue( +                                    ConstString(full_so_path.c_str()), false); +                                add_nlist = false; +                                m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1; +                              } +                            } else { +                              // This could be a relative path to a N_SO +                              N_SO_index = sym_idx;                              } -                            else -                            { -                                // This could be a relative path to a N_SO -                                N_SO_index = sym_idx; -                            } -                        } -                        break; - -                    case N_OSO: -                        // object file name: name,,0,0,st_mtime -                        type = eSymbolTypeObjectFile; -                        break; - -                    case N_LSYM: -                        // local sym: name,,NO_SECT,type,offset -                        type = eSymbolTypeLocal; -                        break; - -                    //---------------------------------------------------------------------- -                    // INCL scopes -                    //---------------------------------------------------------------------- -                    case N_BINCL: -                        // include file beginning: name,,NO_SECT,0,sum -                        // We use the current number of symbols in the symbol table in lieu of -                        // using nlist_idx in case we ever start trimming entries out -                        N_INCL_indexes.push_back(sym_idx); -                        type = eSymbolTypeScopeBegin; -                        break; - -                    case N_EINCL: -                        // include file end: name,,NO_SECT,0,0 -                        // Set the size of the N_BINCL to the terminating index of this N_EINCL -                        // so that we can always skip the entire symbol if we need to navigate -                        // more quickly at the source level when parsing STABS -                        if ( !N_INCL_indexes.empty() ) -                        { -                            symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back()); +                          } +                          break; + +                        case N_OSO: +                          // object file name: name,,0,0,st_mtime +                          type = eSymbolTypeObjectFile; +                          break; + +                        case N_LSYM: +                          // local sym: name,,NO_SECT,type,offset +                          type = eSymbolTypeLocal; +                          break; + +                        //---------------------------------------------------------------------- +                        // INCL scopes +                        //---------------------------------------------------------------------- +                        case N_BINCL: +                          // include file beginning: name,,NO_SECT,0,sum +                          // We use the current number of symbols in the symbol +                          // table in lieu of +                          // using nlist_idx in case we ever start trimming +                          // entries out +                          N_INCL_indexes.push_back(sym_idx); +                          type = eSymbolTypeScopeBegin; +                          break; + +                        case N_EINCL: +                          // include file end: name,,NO_SECT,0,0 +                          // Set the size of the N_BINCL to the terminating +                          // index of this N_EINCL +                          // so that we can always skip the entire symbol if we +                          // need to navigate +                          // more quickly at the source level when parsing STABS +                          if (!N_INCL_indexes.empty()) { +                            symbol_ptr = +                                symtab->SymbolAtIndex(N_INCL_indexes.back());                              symbol_ptr->SetByteSize(sym_idx + 1);                              symbol_ptr->SetSizeIsSibling(true);                              N_INCL_indexes.pop_back(); -                        } -                        type = eSymbolTypeScopeEnd; -                        break; - -                    case N_SOL: -                        // #included file name: name,,n_sect,0,address -                        type = eSymbolTypeHeaderFile; - -                        // We currently don't use the header files on darwin -                        add_nlist = false; -                        break; - -                    case N_PARAMS: -                        // compiler parameters: name,,NO_SECT,0,0 -                        type = eSymbolTypeCompiler; -                        break; - -                    case N_VERSION: -                        // compiler version: name,,NO_SECT,0,0 -                        type = eSymbolTypeCompiler; -                        break; - -                    case N_OLEVEL: -                        // compiler -O level: name,,NO_SECT,0,0 -                        type = eSymbolTypeCompiler; -                        break; - -                    case N_PSYM: -                        // parameter: name,,NO_SECT,type,offset -                        type = eSymbolTypeVariable; -                        break; - -                    case N_ENTRY: -                        // alternate entry: name,,n_sect,linenumber,address -                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); -                        type = eSymbolTypeLineEntry; -                        break; - -                    //---------------------------------------------------------------------- -                    // Left and Right Braces -                    //---------------------------------------------------------------------- -                    case N_LBRAC: -                        // left bracket: 0,,NO_SECT,nesting level,address -                        // We use the current number of symbols in the symbol table in lieu of -                        // using nlist_idx in case we ever start trimming entries out -                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); -                        N_BRAC_indexes.push_back(sym_idx); -                        type = eSymbolTypeScopeBegin; -                        break; - -                    case N_RBRAC: -                        // right bracket: 0,,NO_SECT,nesting level,address -                        // Set the size of the N_LBRAC to the terminating index of this N_RBRAC -                        // so that we can always skip the entire symbol if we need to navigate -                        // more quickly at the source level when parsing STABS -                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); -                        if ( !N_BRAC_indexes.empty() ) -                        { -                            symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back()); +                          } +                          type = eSymbolTypeScopeEnd; +                          break; + +                        case N_SOL: +                          // #included file name: name,,n_sect,0,address +                          type = eSymbolTypeHeaderFile; + +                          // We currently don't use the header files on darwin +                          add_nlist = false; +                          break; + +                        case N_PARAMS: +                          // compiler parameters: name,,NO_SECT,0,0 +                          type = eSymbolTypeCompiler; +                          break; + +                        case N_VERSION: +                          // compiler version: name,,NO_SECT,0,0 +                          type = eSymbolTypeCompiler; +                          break; + +                        case N_OLEVEL: +                          // compiler -O level: name,,NO_SECT,0,0 +                          type = eSymbolTypeCompiler; +                          break; + +                        case N_PSYM: +                          // parameter: name,,NO_SECT,type,offset +                          type = eSymbolTypeVariable; +                          break; + +                        case N_ENTRY: +                          // alternate entry: name,,n_sect,linenumber,address +                          symbol_section = section_info.GetSection( +                              nlist.n_sect, nlist.n_value); +                          type = eSymbolTypeLineEntry; +                          break; + +                        //---------------------------------------------------------------------- +                        // Left and Right Braces +                        //---------------------------------------------------------------------- +                        case N_LBRAC: +                          // left bracket: 0,,NO_SECT,nesting level,address +                          // We use the current number of symbols in the symbol +                          // table in lieu of +                          // using nlist_idx in case we ever start trimming +                          // entries out +                          symbol_section = section_info.GetSection( +                              nlist.n_sect, nlist.n_value); +                          N_BRAC_indexes.push_back(sym_idx); +                          type = eSymbolTypeScopeBegin; +                          break; + +                        case N_RBRAC: +                          // right bracket: 0,,NO_SECT,nesting level,address +                          // Set the size of the N_LBRAC to the terminating +                          // index of this N_RBRAC +                          // so that we can always skip the entire symbol if we +                          // need to navigate +                          // more quickly at the source level when parsing STABS +                          symbol_section = section_info.GetSection( +                              nlist.n_sect, nlist.n_value); +                          if (!N_BRAC_indexes.empty()) { +                            symbol_ptr = +                                symtab->SymbolAtIndex(N_BRAC_indexes.back());                              symbol_ptr->SetByteSize(sym_idx + 1);                              symbol_ptr->SetSizeIsSibling(true);                              N_BRAC_indexes.pop_back(); -                        } -                        type = eSymbolTypeScopeEnd; -                        break; - -                    case N_EXCL: -                        // deleted include file: name,,NO_SECT,0,sum -                        type = eSymbolTypeHeaderFile; -                        break; - -                    //---------------------------------------------------------------------- -                    // COMM scopes -                    //---------------------------------------------------------------------- -                    case N_BCOMM: -                        // begin common: name,,NO_SECT,0,0 -                        // We use the current number of symbols in the symbol table in lieu of -                        // using nlist_idx in case we ever start trimming entries out -                        type = eSymbolTypeScopeBegin; -                        N_COMM_indexes.push_back(sym_idx); -                        break; - -                    case N_ECOML: -                        // end common (local name): 0,,n_sect,0,address -                        symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); -                        LLVM_FALLTHROUGH; - -                    case N_ECOMM: -                        // end common: name,,n_sect,0,0 -                        // Set the size of the N_BCOMM to the terminating index of this N_ECOMM/N_ECOML -                        // so that we can always skip the entire symbol if we need to navigate -                        // more quickly at the source level when parsing STABS -                        if ( !N_COMM_indexes.empty() ) -                        { -                            symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back()); +                          } +                          type = eSymbolTypeScopeEnd; +                          break; + +                        case N_EXCL: +                          // deleted include file: name,,NO_SECT,0,sum +                          type = eSymbolTypeHeaderFile; +                          break; + +                        //---------------------------------------------------------------------- +                        // COMM scopes +                        //---------------------------------------------------------------------- +                        case N_BCOMM: +                          // begin common: name,,NO_SECT,0,0 +                          // We use the current number of symbols in the symbol +                          // table in lieu of +                          // using nlist_idx in case we ever start trimming +                          // entries out +                          type = eSymbolTypeScopeBegin; +                          N_COMM_indexes.push_back(sym_idx); +                          break; + +                        case N_ECOML: +                          // end common (local name): 0,,n_sect,0,address +                          symbol_section = section_info.GetSection( +                              nlist.n_sect, nlist.n_value); +                        // Fall through + +                        case N_ECOMM: +                          // end common: name,,n_sect,0,0 +                          // Set the size of the N_BCOMM to the terminating +                          // index of this N_ECOMM/N_ECOML +                          // so that we can always skip the entire symbol if we +                          // need to navigate +                          // more quickly at the source level when parsing STABS +                          if (!N_COMM_indexes.empty()) { +                            symbol_ptr = +                                symtab->SymbolAtIndex(N_COMM_indexes.back());                              symbol_ptr->SetByteSize(sym_idx + 1);                              symbol_ptr->SetSizeIsSibling(true);                              N_COMM_indexes.pop_back(); -                        } -                        type = eSymbolTypeScopeEnd; -                        break; - -                    case N_LENG: -                        // second stab entry with length information -                        type = eSymbolTypeAdditional; -                        break; +                          } +                          type = eSymbolTypeScopeEnd; +                          break; -                    default: break; -                    } -                } -                else -                { -                    //uint8_t n_pext    = N_PEXT & nlist.n_type; -                    uint8_t n_type  = N_TYPE & nlist.n_type; -                    sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0); +                        case N_LENG: +                          // second stab entry with length information +                          type = eSymbolTypeAdditional; +                          break; -                    switch (n_type) -                    { -                    case N_INDR: -                        { -                            const char *reexport_name_cstr = strtab_data.PeekCStr(nlist.n_value); -                            if (reexport_name_cstr && reexport_name_cstr[0]) -                            { -                                type = eSymbolTypeReExported; -                                ConstString reexport_name(reexport_name_cstr + ((reexport_name_cstr[0] == '_') ? 1 : 0)); -                                sym[sym_idx].SetReExportedSymbolName(reexport_name); -                                set_value = false; -                                reexport_shlib_needs_fixup[sym_idx] = reexport_name; -                                indirect_symbol_names.insert(ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0))); -                            } -                            else -                                type = eSymbolTypeUndefined; -                        } -                        break; - -                    case N_UNDF: -                        if (symbol_name && symbol_name[0]) -                        { -                            ConstString undefined_name(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)); -                            undefined_name_to_desc[undefined_name] = nlist.n_desc; +                        default: +                          break;                          } -                        LLVM_FALLTHROUGH; - -                    case N_PBUD: -                        type = eSymbolTypeUndefined; -                        break; - -                    case N_ABS: -                        type = eSymbolTypeAbsolute; -                        break; - -                    case N_SECT: -                        { -                            symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); - -                            if (!symbol_section) -                            { -                                // TODO: warn about this? -                                add_nlist = false; +                      } else { +                        // uint8_t n_pext    = N_PEXT & nlist.n_type; +                        uint8_t n_type = N_TYPE & nlist.n_type; +                        sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0); + +                        switch (n_type) { +                        case N_INDR: { +                          const char *reexport_name_cstr = +                              strtab_data.PeekCStr(nlist.n_value); +                          if (reexport_name_cstr && reexport_name_cstr[0]) { +                            type = eSymbolTypeReExported; +                            ConstString reexport_name( +                                reexport_name_cstr + +                                ((reexport_name_cstr[0] == '_') ? 1 : 0)); +                            sym[sym_idx].SetReExportedSymbolName(reexport_name); +                            set_value = false; +                            reexport_shlib_needs_fixup[sym_idx] = reexport_name; +                            indirect_symbol_names.insert( +                                ConstString(symbol_name + +                                            ((symbol_name[0] == '_') ? 1 : 0))); +                          } else +                            type = eSymbolTypeUndefined; +                        } break; + +                        case N_UNDF: +                          if (symbol_name && symbol_name[0]) { +                            ConstString undefined_name( +                                symbol_name + +                                ((symbol_name[0] == '_') ? 1 : 0)); +                            undefined_name_to_desc[undefined_name] = +                                nlist.n_desc; +                          } +                        // Fall through +                        case N_PBUD: +                          type = eSymbolTypeUndefined; +                          break; + +                        case N_ABS: +                          type = eSymbolTypeAbsolute; +                          break; + +                        case N_SECT: { +                          symbol_section = section_info.GetSection( +                              nlist.n_sect, nlist.n_value); + +                          if (symbol_section == NULL) { +                            // TODO: warn about this? +                            add_nlist = false; +                            break; +                          } + +                          if (TEXT_eh_frame_sectID == nlist.n_sect) { +                            type = eSymbolTypeException; +                          } else { +                            uint32_t section_type = +                                symbol_section->Get() & SECTION_TYPE; + +                            switch (section_type) { +                            case S_CSTRING_LITERALS: +                              type = eSymbolTypeData; +                              break; // section with only literal C strings +                            case S_4BYTE_LITERALS: +                              type = eSymbolTypeData; +                              break; // section with only 4 byte literals +                            case S_8BYTE_LITERALS: +                              type = eSymbolTypeData; +                              break; // section with only 8 byte literals +                            case S_LITERAL_POINTERS: +                              type = eSymbolTypeTrampoline; +                              break; // section with only pointers to literals +                            case S_NON_LAZY_SYMBOL_POINTERS: +                              type = eSymbolTypeTrampoline; +                              break; // section with only non-lazy symbol +                                     // pointers +                            case S_LAZY_SYMBOL_POINTERS: +                              type = eSymbolTypeTrampoline; +                              break; // section with only lazy symbol pointers +                            case S_SYMBOL_STUBS: +                              type = eSymbolTypeTrampoline; +                              break; // section with only symbol stubs, byte +                                     // size of stub in the reserved2 field +                            case S_MOD_INIT_FUNC_POINTERS: +                              type = eSymbolTypeCode; +                              break; // section with only function pointers for +                                     // initialization +                            case S_MOD_TERM_FUNC_POINTERS: +                              type = eSymbolTypeCode; +                              break; // section with only function pointers for +                                     // termination +                            case S_INTERPOSING: +                              type = eSymbolTypeTrampoline; +                              break; // section with only pairs of function +                                     // pointers for interposing +                            case S_16BYTE_LITERALS: +                              type = eSymbolTypeData; +                              break; // section with only 16 byte literals +                            case S_DTRACE_DOF: +                              type = eSymbolTypeInstrumentation; +                              break; +                            case S_LAZY_DYLIB_SYMBOL_POINTERS: +                              type = eSymbolTypeTrampoline; +                              break; +                            default: +                              switch (symbol_section->GetType()) { +                              case lldb::eSectionTypeCode: +                                type = eSymbolTypeCode; +                                break; +                              case eSectionTypeData: +                              case eSectionTypeDataCString: // Inlined C string +                                                            // data +                              case eSectionTypeDataCStringPointers: // Pointers +                                                                    // to C +                                                                    // string +                                                                    // data +                              case eSectionTypeDataSymbolAddress: // Address of +                                                                  // a symbol in +                                                                  // the symbol +                                                                  // table +                              case eSectionTypeData4: +                              case eSectionTypeData8: +                              case eSectionTypeData16: +                                type = eSymbolTypeData; +                                break; +                              default:                                  break; +                              } +                              break;                              } -                            if (TEXT_eh_frame_sectID == nlist.n_sect) -                            { -                                type = eSymbolTypeException; -                            } -                            else -                            { -                                uint32_t section_type = symbol_section->Get() & SECTION_TYPE; - -                                switch (section_type) -                                { -                                case S_CSTRING_LITERALS:           type = eSymbolTypeData;    break; // section with only literal C strings -                                case S_4BYTE_LITERALS:             type = eSymbolTypeData;    break; // section with only 4 byte literals -                                case S_8BYTE_LITERALS:             type = eSymbolTypeData;    break; // section with only 8 byte literals -                                case S_LITERAL_POINTERS:           type = eSymbolTypeTrampoline; break; // section with only pointers to literals -                                case S_NON_LAZY_SYMBOL_POINTERS:   type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers -                                case S_LAZY_SYMBOL_POINTERS:       type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers -                                case S_SYMBOL_STUBS:               type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field -                                case S_MOD_INIT_FUNC_POINTERS:     type = eSymbolTypeCode;    break; // section with only function pointers for initialization -                                case S_MOD_TERM_FUNC_POINTERS:     type = eSymbolTypeCode;    break; // section with only function pointers for termination -                                case S_INTERPOSING:                type = eSymbolTypeTrampoline;  break; // section with only pairs of function pointers for interposing -                                case S_16BYTE_LITERALS:            type = eSymbolTypeData;    break; // section with only 16 byte literals -                                case S_DTRACE_DOF:                 type = eSymbolTypeInstrumentation; break; -                                case S_LAZY_DYLIB_SYMBOL_POINTERS: type = eSymbolTypeTrampoline; break; -                                default: -                                    switch (symbol_section->GetType()) -                                    { -                                        case lldb::eSectionTypeCode: -                                            type = eSymbolTypeCode; -                                            break; -                                        case eSectionTypeData: -                                        case eSectionTypeDataCString:            // Inlined C string data -                                        case eSectionTypeDataCStringPointers:    // Pointers to C string data -                                        case eSectionTypeDataSymbolAddress:      // Address of a symbol in the symbol table -                                        case eSectionTypeData4: -                                        case eSectionTypeData8: -                                        case eSectionTypeData16: -                                            type = eSymbolTypeData; -                                            break; -                                        default: -                                            break; +                            if (type == eSymbolTypeInvalid) { +                              const char *symbol_sect_name = +                                  symbol_section->GetName().AsCString(); +                              if (symbol_section->IsDescendant( +                                      text_section_sp.get())) { +                                if (symbol_section->IsClear( +                                        S_ATTR_PURE_INSTRUCTIONS | +                                        S_ATTR_SELF_MODIFYING_CODE | +                                        S_ATTR_SOME_INSTRUCTIONS)) +                                  type = eSymbolTypeData; +                                else +                                  type = eSymbolTypeCode; +                              } else if (symbol_section->IsDescendant( +                                             data_section_sp.get()) || +                                         symbol_section->IsDescendant( +                                             data_dirty_section_sp.get()) || +                                         symbol_section->IsDescendant( +                                             data_const_section_sp.get())) { +                                if (symbol_sect_name && +                                    ::strstr(symbol_sect_name, "__objc") == +                                        symbol_sect_name) { +                                  type = eSymbolTypeRuntime; + +                                  if (symbol_name) { +                                    llvm::StringRef symbol_name_ref( +                                        symbol_name); +                                    if (symbol_name_ref.startswith("_OBJC_")) { +                                      static const llvm::StringRef +                                          g_objc_v2_prefix_class( +                                              "_OBJC_CLASS_$_"); +                                      static const llvm::StringRef +                                          g_objc_v2_prefix_metaclass( +                                              "_OBJC_METACLASS_$_"); +                                      static const llvm::StringRef +                                          g_objc_v2_prefix_ivar( +                                              "_OBJC_IVAR_$_"); +                                      if (symbol_name_ref.startswith( +                                              g_objc_v2_prefix_class)) { +                                        symbol_name_non_abi_mangled = +                                            symbol_name + 1; +                                        symbol_name = +                                            symbol_name + +                                            g_objc_v2_prefix_class.size(); +                                        type = eSymbolTypeObjCClass; +                                        demangled_is_synthesized = true; +                                      } else if ( +                                          symbol_name_ref.startswith( +                                              g_objc_v2_prefix_metaclass)) { +                                        symbol_name_non_abi_mangled = +                                            symbol_name + 1; +                                        symbol_name = +                                            symbol_name + +                                            g_objc_v2_prefix_metaclass.size(); +                                        type = eSymbolTypeObjCMetaClass; +                                        demangled_is_synthesized = true; +                                      } else if (symbol_name_ref.startswith( +                                                     g_objc_v2_prefix_ivar)) { +                                        symbol_name_non_abi_mangled = +                                            symbol_name + 1; +                                        symbol_name = +                                            symbol_name + +                                            g_objc_v2_prefix_ivar.size(); +                                        type = eSymbolTypeObjCIVar; +                                        demangled_is_synthesized = true; +                                      }                                      } -                                    break; +                                  } +                                } else if (symbol_sect_name && +                                           ::strstr(symbol_sect_name, +                                                    "__gcc_except_tab") == +                                               symbol_sect_name) { +                                  type = eSymbolTypeException; +                                } else { +                                  type = eSymbolTypeData;                                  } - -                                if (type == eSymbolTypeInvalid) -                                { -                                    const char *symbol_sect_name = symbol_section->GetName().AsCString(); -                                    if (symbol_section->IsDescendant (text_section_sp.get())) -                                    { -                                        if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS | -                                                                    S_ATTR_SELF_MODIFYING_CODE | -                                                                    S_ATTR_SOME_INSTRUCTIONS)) -                                            type = eSymbolTypeData; -                                        else -                                            type = eSymbolTypeCode; -                                    } -                                    else -                                    if (symbol_section->IsDescendant(data_section_sp.get()) || -                                        symbol_section->IsDescendant(data_dirty_section_sp.get()) || -                                        symbol_section->IsDescendant(data_const_section_sp.get())) -                                    { -                                        if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name) -                                        { -                                            type = eSymbolTypeRuntime; - -                                            if (symbol_name) -                                            { -                                                llvm::StringRef symbol_name_ref(symbol_name); -                                                if (symbol_name_ref.startswith("_OBJC_")) -                                                { -                                                    static const llvm::StringRef g_objc_v2_prefix_class ("_OBJC_CLASS_$_"); -                                                    static const llvm::StringRef g_objc_v2_prefix_metaclass ("_OBJC_METACLASS_$_"); -                                                    static const llvm::StringRef g_objc_v2_prefix_ivar ("_OBJC_IVAR_$_"); -                                                    if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) -                                                    { -                                                        symbol_name_non_abi_mangled = symbol_name + 1; -                                                        symbol_name = symbol_name + g_objc_v2_prefix_class.size(); -                                                        type = eSymbolTypeObjCClass; -                                                        demangled_is_synthesized = true; -                                                    } -                                                    else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass)) -                                                    { -                                                        symbol_name_non_abi_mangled = symbol_name + 1; -                                                        symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size(); -                                                        type = eSymbolTypeObjCMetaClass; -                                                        demangled_is_synthesized = true; -                                                    } -                                                    else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar)) -                                                    { -                                                        symbol_name_non_abi_mangled = symbol_name + 1; -                                                        symbol_name = symbol_name + g_objc_v2_prefix_ivar.size(); -                                                        type = eSymbolTypeObjCIVar; -                                                        demangled_is_synthesized = true; -                                                    } -                                                } -                                            } -                                        } -                                        else -                                        if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name) -                                        { -                                            type = eSymbolTypeException; -                                        } -                                        else -                                        { -                                            type = eSymbolTypeData; -                                        } -                                    } -                                    else -                                    if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name) -                                    { -                                        type = eSymbolTypeTrampoline; -                                    } -                                    else -                                    if (symbol_section->IsDescendant(objc_section_sp.get())) -                                    { -                                        type = eSymbolTypeRuntime; -                                        if (symbol_name && symbol_name[0] == '.') -                                        { -                                            llvm::StringRef symbol_name_ref(symbol_name); -                                            static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_"); -                                            if (symbol_name_ref.startswith(g_objc_v1_prefix_class)) -                                            { -                                                symbol_name_non_abi_mangled = symbol_name; -                                                symbol_name = symbol_name + g_objc_v1_prefix_class.size(); -                                                type = eSymbolTypeObjCClass; -                                                demangled_is_synthesized = true; -                                            } -                                        } -                                    } +                              } else if (symbol_sect_name && +                                         ::strstr(symbol_sect_name, +                                                  "__IMPORT") == +                                             symbol_sect_name) { +                                type = eSymbolTypeTrampoline; +                              } else if (symbol_section->IsDescendant( +                                             objc_section_sp.get())) { +                                type = eSymbolTypeRuntime; +                                if (symbol_name && symbol_name[0] == '.') { +                                  llvm::StringRef symbol_name_ref(symbol_name); +                                  static const llvm::StringRef +                                      g_objc_v1_prefix_class( +                                          ".objc_class_name_"); +                                  if (symbol_name_ref.startswith( +                                          g_objc_v1_prefix_class)) { +                                    symbol_name_non_abi_mangled = symbol_name; +                                    symbol_name = symbol_name + +                                                  g_objc_v1_prefix_class.size(); +                                    type = eSymbolTypeObjCClass; +                                    demangled_is_synthesized = true; +                                  }                                  } +                              }                              } +                          } +                        } break;                          } -                        break; -                    } -                } - -                if (add_nlist) -                { -                    uint64_t symbol_value = nlist.n_value; - -                    if (symbol_name_non_abi_mangled) -                    { -                        sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled)); -                        sym[sym_idx].GetMangled().SetDemangledName (ConstString(symbol_name)); -                    } -                    else -                    { -                        bool symbol_name_is_mangled = false; - -                        if (symbol_name && symbol_name[0] == '_') -                        { +                      } + +                      if (add_nlist) { +                        uint64_t symbol_value = nlist.n_value; +                        if (symbol_name_non_abi_mangled) { +                          sym[sym_idx].GetMangled().SetMangledName( +                              ConstString(symbol_name_non_abi_mangled)); +                          sym[sym_idx].GetMangled().SetDemangledName( +                              ConstString(symbol_name)); +                        } else { +                          bool symbol_name_is_mangled = false; + +                          if (symbol_name && symbol_name[0] == '_') {                              symbol_name_is_mangled = symbol_name[1] == '_'; -                            symbol_name++;  // Skip the leading underscore -                        } +                            symbol_name++; // Skip the leading underscore +                          } -                        if (symbol_name) -                        { +                          if (symbol_name) {                              ConstString const_symbol_name(symbol_name); -                            sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled); +                            sym[sym_idx].GetMangled().SetValue( +                                const_symbol_name, symbol_name_is_mangled); +                            if (is_gsym && is_debug) { +                              const char *gsym_name = +                                  sym[sym_idx] +                                      .GetMangled() +                                      .GetName(lldb::eLanguageTypeUnknown, +                                               Mangled::ePreferMangled) +                                      .GetCString(); +                              if (gsym_name) +                                N_GSYM_name_to_sym_idx[gsym_name] = sym_idx; +                            } +                          }                          } -                    } - -                    if (is_gsym) -                    { -                        const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString(); -                        if (gsym_name) -                            N_GSYM_name_to_sym_idx[gsym_name] = sym_idx; -                    } - -                    if (symbol_section) -                    { -                        const addr_t section_file_addr = symbol_section->GetFileAddress(); -                        if (symbol_byte_size == 0 && function_starts_count > 0) -                        { +                        if (symbol_section) { +                          const addr_t section_file_addr = +                              symbol_section->GetFileAddress(); +                          if (symbol_byte_size == 0 && +                              function_starts_count > 0) {                              addr_t symbol_lookup_file_addr = nlist.n_value; -                            // Do an exact address match for non-ARM addresses, else get the closest since -                            // the symbol might be a thumb symbol which has an address with bit zero set -                            FunctionStarts::Entry *func_start_entry = function_starts.FindEntry (symbol_lookup_file_addr, !is_arm); -                            if (is_arm && func_start_entry) -                            { -                                // Verify that the function start address is the symbol address (ARM) -                                // or the symbol address + 1 (thumb) -                                if (func_start_entry->addr != symbol_lookup_file_addr && -                                    func_start_entry->addr != (symbol_lookup_file_addr + 1)) -                                { -                                    // Not the right entry, NULL it out... -                                    func_start_entry = NULL; -                                } +                            // Do an exact address match for non-ARM addresses, +                            // else get the closest since +                            // the symbol might be a thumb symbol which has an +                            // address with bit zero set +                            FunctionStarts::Entry *func_start_entry = +                                function_starts.FindEntry( +                                    symbol_lookup_file_addr, !is_arm); +                            if (is_arm && func_start_entry) { +                              // Verify that the function start address is the +                              // symbol address (ARM) +                              // or the symbol address + 1 (thumb) +                              if (func_start_entry->addr != +                                      symbol_lookup_file_addr && +                                  func_start_entry->addr != +                                      (symbol_lookup_file_addr + 1)) { +                                // Not the right entry, NULL it out... +                                func_start_entry = NULL; +                              }                              } -                            if (func_start_entry) -                            { -                                func_start_entry->data = true; - -                                addr_t symbol_file_addr = func_start_entry->addr; +                            if (func_start_entry) { +                              func_start_entry->data = true; + +                              addr_t symbol_file_addr = func_start_entry->addr; +                              uint32_t symbol_flags = 0; +                              if (is_arm) { +                                if (symbol_file_addr & 1) +                                  symbol_flags = +                                      MACHO_NLIST_ARM_SYMBOL_IS_THUMB; +                                symbol_file_addr &= THUMB_ADDRESS_BIT_MASK; +                              } + +                              const FunctionStarts::Entry +                                  *next_func_start_entry = +                                      function_starts.FindNextEntry( +                                          func_start_entry); +                              const addr_t section_end_file_addr = +                                  section_file_addr + +                                  symbol_section->GetByteSize(); +                              if (next_func_start_entry) { +                                addr_t next_symbol_file_addr = +                                    next_func_start_entry->addr; +                                // Be sure the clear the Thumb address bit when +                                // we calculate the size +                                // from the current and next address                                  if (is_arm) -                                    symbol_file_addr &= THUMB_ADDRESS_BIT_MASK; - -                                const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry); -                                const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize(); -                                if (next_func_start_entry) -                                { -                                    addr_t next_symbol_file_addr = next_func_start_entry->addr; -                                    // Be sure the clear the Thumb address bit when we calculate the size -                                    // from the current and next address -                                    if (is_arm) -                                        next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK; -                                    symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr); -                                } -                                else -                                { -                                    symbol_byte_size = section_end_file_addr - symbol_file_addr; -                                } +                                  next_symbol_file_addr &= +                                      THUMB_ADDRESS_BIT_MASK; +                                symbol_byte_size = std::min<lldb::addr_t>( +                                    next_symbol_file_addr - symbol_file_addr, +                                    section_end_file_addr - symbol_file_addr); +                              } else { +                                symbol_byte_size = +                                    section_end_file_addr - symbol_file_addr; +                              }                              } +                          } +                          symbol_value -= section_file_addr;                          } -                        symbol_value -= section_file_addr; -                    } -                    if (is_debug == false) -                    { -                        if (type == eSymbolTypeCode) -                        { -                            // See if we can find a N_FUN entry for any code symbols. -                            // If we do find a match, and the name matches, then we -                            // can merge the two into just the function symbol to avoid +                        if (is_debug == false) { +                          if (type == eSymbolTypeCode) { +                            // See if we can find a N_FUN entry for any code +                            // symbols. +                            // If we do find a match, and the name matches, then +                            // we +                            // can merge the two into just the function symbol +                            // to avoid                              // duplicate entries in the symbol table -                            std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range; -                            range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value); -                            if (range.first != range.second) -                            { -                                bool found_it = false; -                                for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos) -                                { -                                    if (sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled)) -                                    { -                                        m_nlist_idx_to_sym_idx[nlist_idx] = pos->second; -                                        // We just need the flags from the linker symbol, so put these flags -                                        // into the N_FUN flags to avoid duplicate symbols in the symbol table -                                        sym[pos->second].SetExternal(sym[sym_idx].IsExternal()); -                                        sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc); -                                        if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end()) -                                            sym[pos->second].SetType (eSymbolTypeResolver); -                                        sym[sym_idx].Clear(); -                                        found_it = true; -                                        break; -                                    } +                            std::pair<ValueToSymbolIndexMap::const_iterator, +                                      ValueToSymbolIndexMap::const_iterator> +                                range; +                            range = N_FUN_addr_to_sym_idx.equal_range( +                                nlist.n_value); +                            if (range.first != range.second) { +                              bool found_it = false; +                              for (ValueToSymbolIndexMap::const_iterator pos = +                                       range.first; +                                   pos != range.second; ++pos) { +                                if (sym[sym_idx].GetMangled().GetName( +                                        lldb::eLanguageTypeUnknown, +                                        Mangled::ePreferMangled) == +                                    sym[pos->second].GetMangled().GetName( +                                        lldb::eLanguageTypeUnknown, +                                        Mangled::ePreferMangled)) { +                                  m_nlist_idx_to_sym_idx[nlist_idx] = +                                      pos->second; +                                  // We just need the flags from the linker +                                  // symbol, so put these flags +                                  // into the N_FUN flags to avoid duplicate +                                  // symbols in the symbol table +                                  sym[pos->second].SetExternal( +                                      sym[sym_idx].IsExternal()); +                                  sym[pos->second].SetFlags(nlist.n_type << 16 | +                                                            nlist.n_desc); +                                  if (resolver_addresses.find(nlist.n_value) != +                                      resolver_addresses.end()) +                                    sym[pos->second].SetType( +                                        eSymbolTypeResolver); +                                  sym[sym_idx].Clear(); +                                  found_it = true; +                                  break;                                  } -                                if (found_it) -                                    continue; -                            } -                            else -                            { -                                if (resolver_addresses.find(nlist.n_value) != resolver_addresses.end()) -                                    type = eSymbolTypeResolver; +                              } +                              if (found_it) +                                continue; +                            } else { +                              if (resolver_addresses.find(nlist.n_value) != +                                  resolver_addresses.end()) +                                type = eSymbolTypeResolver;                              } -                        } -                        else if (type == eSymbolTypeData          || -                                 type == eSymbolTypeObjCClass     || -                                 type == eSymbolTypeObjCMetaClass || -                                 type == eSymbolTypeObjCIVar      ) -                        { -                            // See if we can find a N_STSYM entry for any data symbols. -                            // If we do find a match, and the name matches, then we -                            // can merge the two into just the Static symbol to avoid +                          } else if (type == eSymbolTypeData || +                                     type == eSymbolTypeObjCClass || +                                     type == eSymbolTypeObjCMetaClass || +                                     type == eSymbolTypeObjCIVar) { +                            // See if we can find a N_STSYM entry for any data +                            // symbols. +                            // If we do find a match, and the name matches, then +                            // we +                            // can merge the two into just the Static symbol to +                            // avoid                              // duplicate entries in the symbol table -                            std::pair<ValueToSymbolIndexMap::const_iterator, ValueToSymbolIndexMap::const_iterator> range; -                            range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value); -                            if (range.first != range.second) -                            { -                                bool found_it = false; -                                for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos) -                                { -                                    if (sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled)) -                                    { -                                        m_nlist_idx_to_sym_idx[nlist_idx] = pos->second; -                                        // We just need the flags from the linker symbol, so put these flags -                                        // into the N_STSYM flags to avoid duplicate symbols in the symbol table -                                        sym[pos->second].SetExternal(sym[sym_idx].IsExternal()); -                                        sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc); -                                        sym[sym_idx].Clear(); -                                        found_it = true; -                                        break; -                                    } +                            std::pair<ValueToSymbolIndexMap::const_iterator, +                                      ValueToSymbolIndexMap::const_iterator> +                                range; +                            range = N_STSYM_addr_to_sym_idx.equal_range( +                                nlist.n_value); +                            if (range.first != range.second) { +                              bool found_it = false; +                              for (ValueToSymbolIndexMap::const_iterator pos = +                                       range.first; +                                   pos != range.second; ++pos) { +                                if (sym[sym_idx].GetMangled().GetName( +                                        lldb::eLanguageTypeUnknown, +                                        Mangled::ePreferMangled) == +                                    sym[pos->second].GetMangled().GetName( +                                        lldb::eLanguageTypeUnknown, +                                        Mangled::ePreferMangled)) { +                                  m_nlist_idx_to_sym_idx[nlist_idx] = +                                      pos->second; +                                  // We just need the flags from the linker +                                  // symbol, so put these flags +                                  // into the N_STSYM flags to avoid duplicate +                                  // symbols in the symbol table +                                  sym[pos->second].SetExternal( +                                      sym[sym_idx].IsExternal()); +                                  sym[pos->second].SetFlags(nlist.n_type << 16 | +                                                            nlist.n_desc); +                                  sym[sym_idx].Clear(); +                                  found_it = true; +                                  break;                                  } -                                if (found_it) -                                    continue; -                            } -                            else -                            { -                                // Combine N_GSYM stab entries with the non stab symbol -                                const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString(); -                                if (gsym_name) -                                { -                                    ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(gsym_name); -                                    if (pos != N_GSYM_name_to_sym_idx.end()) -                                    { -                                        const uint32_t GSYM_sym_idx = pos->second; -                                        m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx; -                                        // Copy the address, because often the N_GSYM address has an invalid address of zero -                                        // when the global is a common symbol -                                        sym[GSYM_sym_idx].GetAddressRef().SetSection (symbol_section); -                                        sym[GSYM_sym_idx].GetAddressRef().SetOffset (symbol_value); -                                        // We just need the flags from the linker symbol, so put these flags -                                        // into the N_GSYM flags to avoid duplicate symbols in the symbol table -                                        sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc); -                                        sym[sym_idx].Clear(); -                                        continue; -                                    } +                              } +                              if (found_it) +                                continue; +                            } else { +                              const char *gsym_name = +                                  sym[sym_idx] +                                      .GetMangled() +                                      .GetName(lldb::eLanguageTypeUnknown, +                                               Mangled::ePreferMangled) +                                      .GetCString(); +                              if (gsym_name) { +                                // Combine N_GSYM stab entries with the non stab +                                // symbol +                                ConstNameToSymbolIndexMap::const_iterator pos = +                                    N_GSYM_name_to_sym_idx.find(gsym_name); +                                if (pos != N_GSYM_name_to_sym_idx.end()) { +                                  const uint32_t GSYM_sym_idx = pos->second; +                                  m_nlist_idx_to_sym_idx[nlist_idx] = +                                      GSYM_sym_idx; +                                  // Copy the address, because often the N_GSYM +                                  // address has an invalid address of zero +                                  // when the global is a common symbol +                                  sym[GSYM_sym_idx].GetAddressRef().SetSection( +                                      symbol_section); +                                  sym[GSYM_sym_idx].GetAddressRef().SetOffset( +                                      symbol_value); +                                  // We just need the flags from the linker +                                  // symbol, so put these flags +                                  // into the N_GSYM flags to avoid duplicate +                                  // symbols in the symbol table +                                  sym[GSYM_sym_idx].SetFlags( +                                      nlist.n_type << 16 | nlist.n_desc); +                                  sym[sym_idx].Clear(); +                                  continue;                                  } +                              }                              } +                          }                          } -                    } - -                    sym[sym_idx].SetID (nlist_idx); -                    sym[sym_idx].SetType (type); -                    if (set_value) -                    { -                        sym[sym_idx].GetAddressRef().SetSection (symbol_section); -                        sym[sym_idx].GetAddressRef().SetOffset (symbol_value); -                    } -                    sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc); -                    if (symbol_byte_size > 0) -                        sym[sym_idx].SetByteSize(symbol_byte_size); +                        sym[sym_idx].SetID(nlist_idx); +                        sym[sym_idx].SetType(type); +                        if (set_value) { +                          sym[sym_idx].GetAddressRef().SetSection( +                              symbol_section); +                          sym[sym_idx].GetAddressRef().SetOffset(symbol_value); +                        } +                        sym[sym_idx].SetFlags(nlist.n_type << 16 | +                                              nlist.n_desc); -                    if (demangled_is_synthesized) -                        sym[sym_idx].SetDemangledNameIsSynthesized(true); +                        if (symbol_byte_size > 0) +                          sym[sym_idx].SetByteSize(symbol_byte_size); -                    ++sym_idx; -                } -                else -                { -                    sym[sym_idx].Clear(); +                        if (demangled_is_synthesized) +                          sym[sym_idx].SetDemangledNameIsSynthesized(true); +                        ++sym_idx; +                      } else { +                        sym[sym_idx].Clear(); +                      } +                    } +                    ///////////////////////////// +                  } +                  break; // No more entries to consider                  } -            } +              } -            for (const auto &pos :reexport_shlib_needs_fixup) -            { +              for (const auto &pos : reexport_shlib_needs_fixup) {                  const auto undef_pos = undefined_name_to_desc.find(pos.second); -                if (undef_pos != undefined_name_to_desc.end()) -                { -                    const uint8_t dylib_ordinal = llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second); -                    if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize()) -                        sym[pos.first].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(dylib_ordinal-1)); +                if (undef_pos != undefined_name_to_desc.end()) { +                  const uint8_t dylib_ordinal = +                      llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second); +                  if (dylib_ordinal > 0 && +                      dylib_ordinal < dylib_files.GetSize()) +                    sym[pos.first].SetReExportedSymbolSharedLibrary( +                        dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));                  } +              }              } +          }          } +      } +    } -        uint32_t synthetic_sym_id = symtab_load_command.nsyms; +    // Must reset this in case it was mutated above! +    nlist_data_offset = 0; +#endif -        if (function_starts_count > 0) -        { -            uint32_t num_synthetic_function_symbols = 0; -            for (i=0; i<function_starts_count; ++i) -            { -                if (function_starts.GetEntryRef (i).data == false) -                    ++num_synthetic_function_symbols; +    if (nlist_data.GetByteSize() > 0) { + +      // If the sym array was not created while parsing the DSC unmapped +      // symbols, create it now. +      if (sym == NULL) { +        sym = symtab->Resize(symtab_load_command.nsyms + +                             m_dysymtab.nindirectsyms); +        num_syms = symtab->GetNumSymbols(); +      } + +      if (unmapped_local_symbols_found) { +        assert(m_dysymtab.ilocalsym == 0); +        nlist_data_offset += (m_dysymtab.nlocalsym * nlist_byte_size); +        nlist_idx = m_dysymtab.nlocalsym; +      } else { +        nlist_idx = 0; +      } + +      typedef std::map<ConstString, uint16_t> UndefinedNameToDescMap; +      typedef std::map<uint32_t, ConstString> SymbolIndexToName; +      UndefinedNameToDescMap undefined_name_to_desc; +      SymbolIndexToName reexport_shlib_needs_fixup; +      for (; nlist_idx < symtab_load_command.nsyms; ++nlist_idx) { +        struct nlist_64 nlist; +        if (!nlist_data.ValidOffsetForDataOfSize(nlist_data_offset, +                                                 nlist_byte_size)) +          break; + +        nlist.n_strx = nlist_data.GetU32_unchecked(&nlist_data_offset); +        nlist.n_type = nlist_data.GetU8_unchecked(&nlist_data_offset); +        nlist.n_sect = nlist_data.GetU8_unchecked(&nlist_data_offset); +        nlist.n_desc = nlist_data.GetU16_unchecked(&nlist_data_offset); +        nlist.n_value = nlist_data.GetAddress_unchecked(&nlist_data_offset); + +        SymbolType type = eSymbolTypeInvalid; +        const char *symbol_name = NULL; + +        if (have_strtab_data) { +          symbol_name = strtab_data.PeekCStr(nlist.n_strx); + +          if (symbol_name == NULL) { +            // No symbol should be NULL, even the symbols with no +            // string values should have an offset zero which points +            // to an empty C-string +            Host::SystemLog(Host::eSystemLogError, +                            "error: symbol[%u] has invalid string table offset " +                            "0x%x in %s, ignoring symbol\n", +                            nlist_idx, nlist.n_strx, +                            module_sp->GetFileSpec().GetPath().c_str()); +            continue; +          } +          if (symbol_name[0] == '\0') +            symbol_name = NULL; +        } else { +          const addr_t str_addr = strtab_addr + nlist.n_strx; +          Error str_error; +          if (process->ReadCStringFromMemory(str_addr, memory_symbol_name, +                                             str_error)) +            symbol_name = memory_symbol_name.c_str(); +        } +        const char *symbol_name_non_abi_mangled = NULL; + +        SectionSP symbol_section; +        lldb::addr_t symbol_byte_size = 0; +        bool add_nlist = true; +        bool is_gsym = false; +        bool is_debug = ((nlist.n_type & N_STAB) != 0); +        bool demangled_is_synthesized = false; +        bool set_value = true; +        assert(sym_idx < num_syms); + +        sym[sym_idx].SetDebug(is_debug); + +        if (is_debug) { +          switch (nlist.n_type) { +          case N_GSYM: +            // global symbol: name,,NO_SECT,type,0 +            // Sometimes the N_GSYM value contains the address. + +            // FIXME: In the .o files, we have a GSYM and a debug symbol for all +            // the ObjC data.  They +            // have the same address, but we want to ensure that we always find +            // only the real symbol, +            // 'cause we don't currently correctly attribute the GSYM one to the +            // ObjCClass/Ivar/MetaClass +            // symbol type.  This is a temporary hack to make sure the +            // ObjectiveC symbols get treated +            // correctly.  To do this right, we should coalesce all the GSYM & +            // global symbols that have the +            // same address. +            is_gsym = true; +            sym[sym_idx].SetExternal(true); + +            if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O') { +              llvm::StringRef symbol_name_ref(symbol_name); +              if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) { +                symbol_name_non_abi_mangled = symbol_name + 1; +                symbol_name = symbol_name + g_objc_v2_prefix_class.size(); +                type = eSymbolTypeObjCClass; +                demangled_is_synthesized = true; + +              } else if (symbol_name_ref.startswith( +                             g_objc_v2_prefix_metaclass)) { +                symbol_name_non_abi_mangled = symbol_name + 1; +                symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size(); +                type = eSymbolTypeObjCMetaClass; +                demangled_is_synthesized = true; +              } else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar)) { +                symbol_name_non_abi_mangled = symbol_name + 1; +                symbol_name = symbol_name + g_objc_v2_prefix_ivar.size(); +                type = eSymbolTypeObjCIVar; +                demangled_is_synthesized = true; +              } +            } else { +              if (nlist.n_value != 0) +                symbol_section = +                    section_info.GetSection(nlist.n_sect, nlist.n_value); +              type = eSymbolTypeData;              } +            break; -            if (num_synthetic_function_symbols > 0) -            { -                if (num_syms < sym_idx + num_synthetic_function_symbols) -                { -                    num_syms = sym_idx + num_synthetic_function_symbols; -                    sym = symtab->Resize (num_syms); -                } -                for (i=0; i<function_starts_count; ++i) -                { -                    const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex (i); -                    if (func_start_entry->data == false) -                    { -                        addr_t symbol_file_addr = func_start_entry->addr; -                        uint32_t symbol_flags = 0; -                        if (is_arm) -                        { -                            if (symbol_file_addr & 1) -                                symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB; -                            symbol_file_addr &= THUMB_ADDRESS_BIT_MASK; -                        } -                        Address symbol_addr; -                        if (module_sp->ResolveFileAddress (symbol_file_addr, symbol_addr)) -                        { -                            SectionSP symbol_section (symbol_addr.GetSection()); -                            uint32_t symbol_byte_size = 0; -                            if (symbol_section) -                            { -                                const addr_t section_file_addr = symbol_section->GetFileAddress(); -                                const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry); -                                const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize(); -                                if (next_func_start_entry) -                                { -                                    addr_t next_symbol_file_addr = next_func_start_entry->addr; -                                    if (is_arm) -                                        next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK; -                                    symbol_byte_size = std::min<lldb::addr_t>(next_symbol_file_addr - symbol_file_addr, section_end_file_addr - symbol_file_addr); -                                } -                                else -                                { -                                    symbol_byte_size = section_end_file_addr - symbol_file_addr; -                                } -                                sym[sym_idx].SetID (synthetic_sym_id++); -                                sym[sym_idx].GetMangled().SetDemangledName(GetNextSyntheticSymbolName()); -                                sym[sym_idx].SetType (eSymbolTypeCode); -                                sym[sym_idx].SetIsSynthetic (true); -                                sym[sym_idx].GetAddressRef() = symbol_addr; -                                if (symbol_flags) -                                    sym[sym_idx].SetFlags (symbol_flags); -                                if (symbol_byte_size) -                                    sym[sym_idx].SetByteSize (symbol_byte_size); -                                ++sym_idx; -                            } -                        } -                    } -                } +          case N_FNAME: +            // procedure name (f77 kludge): name,,NO_SECT,0,0 +            type = eSymbolTypeCompiler; +            break; + +          case N_FUN: +            // procedure: name,,n_sect,linenumber,address +            if (symbol_name) { +              type = eSymbolTypeCode; +              symbol_section = +                  section_info.GetSection(nlist.n_sect, nlist.n_value); + +              N_FUN_addr_to_sym_idx.insert( +                  std::make_pair(nlist.n_value, sym_idx)); +              // We use the current number of symbols in the symbol table in +              // lieu of +              // using nlist_idx in case we ever start trimming entries out +              N_FUN_indexes.push_back(sym_idx); +            } else { +              type = eSymbolTypeCompiler; + +              if (!N_FUN_indexes.empty()) { +                // Copy the size of the function into the original STAB entry so +                // we don't have +                // to hunt for it later +                symtab->SymbolAtIndex(N_FUN_indexes.back()) +                    ->SetByteSize(nlist.n_value); +                N_FUN_indexes.pop_back(); +                // We don't really need the end function STAB as it contains the +                // size which +                // we already placed with the original symbol, so don't add it +                // if we want a +                // minimal symbol table +                add_nlist = false; +              }              } -        } +            break; -        // Trim our symbols down to just what we ended up with after -        // removing any symbols. -        if (sym_idx < num_syms) -        { -            num_syms = sym_idx; -            sym = symtab->Resize (num_syms); -        } +          case N_STSYM: +            // static symbol: name,,n_sect,type,address +            N_STSYM_addr_to_sym_idx.insert( +                std::make_pair(nlist.n_value, sym_idx)); +            symbol_section = +                section_info.GetSection(nlist.n_sect, nlist.n_value); +            if (symbol_name && symbol_name[0]) { +              type = ObjectFile::GetSymbolTypeFromName(symbol_name + 1, +                                                       eSymbolTypeData); +            } +            break; -        // Now synthesize indirect symbols -        if (m_dysymtab.nindirectsyms != 0) -        { -            if (indirect_symbol_index_data.GetByteSize()) -            { -                NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end(); +          case N_LCSYM: +            // .lcomm symbol: name,,n_sect,type,address +            symbol_section = +                section_info.GetSection(nlist.n_sect, nlist.n_value); +            type = eSymbolTypeCommonBlock; +            break; -                for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); ++sect_idx) -                { -                    if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) == S_SYMBOL_STUBS) -                    { -                        uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2; -                        if (symbol_stub_byte_size == 0) -                            continue; - -                        const uint32_t num_symbol_stubs = m_mach_sections[sect_idx].size / symbol_stub_byte_size; - -                        if (num_symbol_stubs == 0) -                            continue; - -                        const uint32_t symbol_stub_index_offset = m_mach_sections[sect_idx].reserved1; -                        for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) -                        { -                            const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx; -                            const lldb::addr_t symbol_stub_addr = m_mach_sections[sect_idx].addr + (stub_idx * symbol_stub_byte_size); -                            lldb::offset_t symbol_stub_offset = symbol_stub_index * 4; -                            if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4)) -                            { -                                const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset); -                                if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL)) -                                    continue; - -                                NListIndexToSymbolIndexMap::const_iterator index_pos = m_nlist_idx_to_sym_idx.find (stub_sym_id); -                                Symbol *stub_symbol = NULL; -                                if (index_pos != end_index_pos) -                                { -                                    // We have a remapping from the original nlist index to -                                    // a current symbol index, so just look this up by index -                                    stub_symbol = symtab->SymbolAtIndex (index_pos->second); -                                } -                                else -                                { -                                    // We need to lookup a symbol using the original nlist -                                    // symbol index since this index is coming from the -                                    // S_SYMBOL_STUBS -                                    stub_symbol = symtab->FindSymbolByID (stub_sym_id); -                                } +          case N_BNSYM: +            // We use the current number of symbols in the symbol table in lieu +            // of +            // using nlist_idx in case we ever start trimming entries out +            // Skip these if we want minimal symbol tables +            add_nlist = false; +            break; -                                if (stub_symbol) -                                { -                                    Address so_addr(symbol_stub_addr, section_list); - -                                    if (stub_symbol->GetType() == eSymbolTypeUndefined) -                                    { -                                        // Change the external symbol into a trampoline that makes sense -                                        // These symbols were N_UNDF N_EXT, and are useless to us, so we -                                        // can re-use them so we don't have to make up a synthetic symbol -                                        // for no good reason. -                                        if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end()) -                                            stub_symbol->SetType (eSymbolTypeTrampoline); -                                        else -                                            stub_symbol->SetType (eSymbolTypeResolver); -                                        stub_symbol->SetExternal (false); -                                        stub_symbol->GetAddressRef() = so_addr; -                                        stub_symbol->SetByteSize (symbol_stub_byte_size); -                                    } -                                    else -                                    { -                                        // Make a synthetic symbol to describe the trampoline stub -                                        Mangled stub_symbol_mangled_name(stub_symbol->GetMangled()); -                                        if (sym_idx >= num_syms) -                                        { -                                            sym = symtab->Resize (++num_syms); -                                            stub_symbol = NULL;  // this pointer no longer valid -                                        } -                                        sym[sym_idx].SetID (synthetic_sym_id++); -                                        sym[sym_idx].GetMangled() = stub_symbol_mangled_name; -                                        if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end()) -                                            sym[sym_idx].SetType (eSymbolTypeTrampoline); -                                        else -                                            sym[sym_idx].SetType (eSymbolTypeResolver); -                                        sym[sym_idx].SetIsSynthetic (true); -                                        sym[sym_idx].GetAddressRef() = so_addr; -                                        sym[sym_idx].SetByteSize (symbol_stub_byte_size); -                                        ++sym_idx; -                                    } -                                } -                                else -                                { -                                    if (log) -                                        log->Warning ("symbol stub referencing symbol table symbol %u that isn't in our minimal symbol table, fix this!!!", stub_sym_id); -                                } -                            } -                        } -                    } -                } -            } -        } +          case N_ENSYM: +            // Set the size of the N_BNSYM to the terminating index of this +            // N_ENSYM +            // so that we can always skip the entire symbol if we need to +            // navigate +            // more quickly at the source level when parsing STABS +            // Skip these if we want minimal symbol tables +            add_nlist = false; +            break; -        if (!trie_entries.empty()) -        { -            for (const auto &e : trie_entries) -            { -                if (e.entry.import_name) -                { -                    // Only add indirect symbols from the Trie entries if we -                    // didn't have a N_INDR nlist entry for this already -                    if (indirect_symbol_names.find(e.entry.name) == indirect_symbol_names.end()) -                    { -                        // Make a synthetic symbol to describe re-exported symbol. -                        if (sym_idx >= num_syms) -                            sym = symtab->Resize (++num_syms); -                        sym[sym_idx].SetID (synthetic_sym_id++); -                        sym[sym_idx].GetMangled() = Mangled(e.entry.name); -                        sym[sym_idx].SetType (eSymbolTypeReExported); -                        sym[sym_idx].SetIsSynthetic (true); -                        sym[sym_idx].SetReExportedSymbolName(e.entry.import_name); -                        if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize()) -                        { -                            sym[sym_idx].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(e.entry.other-1)); -                        } -                        ++sym_idx; +          case N_OPT: +            // emitted with gcc2_compiled and in gcc source +            type = eSymbolTypeCompiler; +            break; + +          case N_RSYM: +            // register sym: name,,NO_SECT,type,register +            type = eSymbolTypeVariable; +            break; + +          case N_SLINE: +            // src line: 0,,n_sect,linenumber,address +            symbol_section = +                section_info.GetSection(nlist.n_sect, nlist.n_value); +            type = eSymbolTypeLineEntry; +            break; + +          case N_SSYM: +            // structure elt: name,,NO_SECT,type,struct_offset +            type = eSymbolTypeVariableType; +            break; + +          case N_SO: +            // source file name +            type = eSymbolTypeSourceFile; +            if (symbol_name == NULL) { +              add_nlist = false; +              if (N_SO_index != UINT32_MAX) { +                // Set the size of the N_SO to the terminating index of this +                // N_SO +                // so that we can always skip the entire N_SO if we need to +                // navigate +                // more quickly at the source level when parsing STABS +                symbol_ptr = symtab->SymbolAtIndex(N_SO_index); +                symbol_ptr->SetByteSize(sym_idx); +                symbol_ptr->SetSizeIsSibling(true); +              } +              N_NSYM_indexes.clear(); +              N_INCL_indexes.clear(); +              N_BRAC_indexes.clear(); +              N_COMM_indexes.clear(); +              N_FUN_indexes.clear(); +              N_SO_index = UINT32_MAX; +            } else { +              // We use the current number of symbols in the symbol table in +              // lieu of +              // using nlist_idx in case we ever start trimming entries out +              const bool N_SO_has_full_path = symbol_name[0] == '/'; +              if (N_SO_has_full_path) { +                if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) { +                  // We have two consecutive N_SO entries where the first +                  // contains a directory +                  // and the second contains a full path. +                  sym[sym_idx - 1].GetMangled().SetValue( +                      ConstString(symbol_name), false); +                  m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1; +                  add_nlist = false; +                } else { +                  // This is the first entry in a N_SO that contains a directory +                  // or +                  // a full path to the source file +                  N_SO_index = sym_idx; +                } +              } else if ((N_SO_index == sym_idx - 1) && +                         ((sym_idx - 1) < num_syms)) { +                // This is usually the second N_SO entry that contains just the +                // filename, +                // so here we combine it with the first one if we are minimizing +                // the symbol table +                const char *so_path = +                    sym[sym_idx - 1] +                        .GetMangled() +                        .GetDemangledName(lldb::eLanguageTypeUnknown) +                        .AsCString(); +                if (so_path && so_path[0]) { +                  std::string full_so_path(so_path); +                  const size_t double_slash_pos = full_so_path.find("//"); +                  if (double_slash_pos != std::string::npos) { +                    // The linker has been generating bad N_SO entries with +                    // doubled up paths +                    // in the format "%s%s" where the first string in the +                    // DW_AT_comp_dir, +                    // and the second is the directory for the source file so +                    // you end up with +                    // a path that looks like "/tmp/src//tmp/src/" +                    FileSpec so_dir(so_path, false); +                    if (!so_dir.Exists()) { +                      so_dir.SetFile(&full_so_path[double_slash_pos + 1], +                                     false); +                      if (so_dir.Exists()) { +                        // Trim off the incorrect path +                        full_so_path.erase(0, double_slash_pos + 1); +                      }                      } +                  } +                  if (*full_so_path.rbegin() != '/') +                    full_so_path += '/'; +                  full_so_path += symbol_name; +                  sym[sym_idx - 1].GetMangled().SetValue( +                      ConstString(full_so_path.c_str()), false); +                  add_nlist = false; +                  m_nlist_idx_to_sym_idx[nlist_idx] = sym_idx - 1;                  } +              } else { +                // This could be a relative path to a N_SO +                N_SO_index = sym_idx; +              }              } -        } -        -//        StreamFile s(stdout, false); -//        s.Printf ("Symbol table before CalculateSymbolSizes():\n"); -//        symtab->Dump(&s, NULL, eSortOrderNone); -        // Set symbol byte sizes correctly since mach-o nlist entries don't have sizes -        symtab->CalculateSymbolSizes(); +            break; -//        s.Printf ("Symbol table after CalculateSymbolSizes():\n"); -//        symtab->Dump(&s, NULL, eSortOrderNone); +          case N_OSO: +            // object file name: name,,0,0,st_mtime +            type = eSymbolTypeObjectFile; +            break; -        return symtab->GetNumSymbols(); -    } -    return 0; -} +          case N_LSYM: +            // local sym: name,,NO_SECT,type,offset +            type = eSymbolTypeLocal; +            break; -void -ObjectFileMachO::Dump (Stream *s) -{ -    ModuleSP module_sp(GetModule()); -    if (module_sp) -    { -        std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); -        s->Printf("%p: ", static_cast<void*>(this)); -        s->Indent(); -        if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64) -            s->PutCString("ObjectFileMachO64"); -        else -            s->PutCString("ObjectFileMachO32"); +          //---------------------------------------------------------------------- +          // INCL scopes +          //---------------------------------------------------------------------- +          case N_BINCL: +            // include file beginning: name,,NO_SECT,0,sum +            // We use the current number of symbols in the symbol table in lieu +            // of +            // using nlist_idx in case we ever start trimming entries out +            N_INCL_indexes.push_back(sym_idx); +            type = eSymbolTypeScopeBegin; +            break; -        ArchSpec header_arch; -        GetArchitecture(header_arch); +          case N_EINCL: +            // include file end: name,,NO_SECT,0,0 +            // Set the size of the N_BINCL to the terminating index of this +            // N_EINCL +            // so that we can always skip the entire symbol if we need to +            // navigate +            // more quickly at the source level when parsing STABS +            if (!N_INCL_indexes.empty()) { +              symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back()); +              symbol_ptr->SetByteSize(sym_idx + 1); +              symbol_ptr->SetSizeIsSibling(true); +              N_INCL_indexes.pop_back(); +            } +            type = eSymbolTypeScopeEnd; +            break; -        *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n"; +          case N_SOL: +            // #included file name: name,,n_sect,0,address +            type = eSymbolTypeHeaderFile; -        SectionList *sections = GetSectionList(); -        if (sections) -            sections->Dump(s, NULL, true, UINT32_MAX); +            // We currently don't use the header files on darwin +            add_nlist = false; +            break; -        if (m_symtab_ap.get()) -            m_symtab_ap->Dump(s, NULL, eSortOrderNone); -    } -} +          case N_PARAMS: +            // compiler parameters: name,,NO_SECT,0,0 +            type = eSymbolTypeCompiler; +            break; -bool -ObjectFileMachO::GetUUID (const llvm::MachO::mach_header &header, -                          const lldb_private::DataExtractor &data, -                          lldb::offset_t lc_offset, -                          lldb_private::UUID& uuid) -{ -    uint32_t i; -    struct uuid_command load_cmd; +          case N_VERSION: +            // compiler version: name,,NO_SECT,0,0 +            type = eSymbolTypeCompiler; +            break; -    lldb::offset_t offset = lc_offset; -    for (i=0; i<header.ncmds; ++i) -    { -        const lldb::offset_t cmd_offset = offset; -        if (data.GetU32(&offset, &load_cmd, 2) == NULL) +          case N_OLEVEL: +            // compiler -O level: name,,NO_SECT,0,0 +            type = eSymbolTypeCompiler;              break; -         -        if (load_cmd.cmd == LC_UUID) -        { -            const uint8_t *uuid_bytes = data.PeekData(offset, 16); -             -            if (uuid_bytes) -            { -                // OpenCL on Mac OS X uses the same UUID for each of its object files. -                // We pretend these object files have no UUID to prevent crashing. -                 -                const uint8_t opencl_uuid[] = { 0x8c, 0x8e, 0xb3, 0x9b, -                    0x3b, 0xa8, -                    0x4b, 0x16, -                    0xb6, 0xa4, -                    0x27, 0x63, 0xbb, 0x14, 0xf0, 0x0d }; -                 -                if (!memcmp(uuid_bytes, opencl_uuid, 16)) -                    return false; -                 -                uuid.SetBytes (uuid_bytes); -                return true; -            } -            return false; -        } -        offset = cmd_offset + load_cmd.cmdsize; -    } -    return false; -} -bool -ObjectFileMachO::GetArchitecture (const llvm::MachO::mach_header &header, -                                  const lldb_private::DataExtractor &data, -                                  lldb::offset_t lc_offset, -                                  ArchSpec &arch) -{ -    arch.SetArchitecture (eArchTypeMachO, header.cputype, header.cpusubtype); - -    if (arch.IsValid()) -    { -        llvm::Triple &triple = arch.GetTriple(); - -        // Set OS to an unspecified unknown or a "*" so it can match any OS -        triple.setOS(llvm::Triple::UnknownOS); -        triple.setOSName(llvm::StringRef()); - -        if (header.filetype == MH_PRELOAD) -        { -            if (header.cputype == CPU_TYPE_ARM) -            { -                // If this is a 32-bit arm binary, and it's a standalone binary, -                // force the Vendor to Apple so we don't accidentally pick up  -                // the generic armv7 ABI at runtime.  Apple's armv7 ABI always uses -                // r7 for the frame pointer register; most other armv7 ABIs use a -                // combination of r7 and r11. -                triple.setVendor(llvm::Triple::Apple); -            } -            else -            { -                // Set vendor to an unspecified unknown or a "*" so it can match any vendor -                // This is required for correct behavior of EFI debugging on x86_64 -                triple.setVendor(llvm::Triple::UnknownVendor); -                triple.setVendorName(llvm::StringRef()); +          case N_PSYM: +            // parameter: name,,NO_SECT,type,offset +            type = eSymbolTypeVariable; +            break; + +          case N_ENTRY: +            // alternate entry: name,,n_sect,linenumber,address +            symbol_section = +                section_info.GetSection(nlist.n_sect, nlist.n_value); +            type = eSymbolTypeLineEntry; +            break; + +          //---------------------------------------------------------------------- +          // Left and Right Braces +          //---------------------------------------------------------------------- +          case N_LBRAC: +            // left bracket: 0,,NO_SECT,nesting level,address +            // We use the current number of symbols in the symbol table in lieu +            // of +            // using nlist_idx in case we ever start trimming entries out +            symbol_section = +                section_info.GetSection(nlist.n_sect, nlist.n_value); +            N_BRAC_indexes.push_back(sym_idx); +            type = eSymbolTypeScopeBegin; +            break; + +          case N_RBRAC: +            // right bracket: 0,,NO_SECT,nesting level,address +            // Set the size of the N_LBRAC to the terminating index of this +            // N_RBRAC +            // so that we can always skip the entire symbol if we need to +            // navigate +            // more quickly at the source level when parsing STABS +            symbol_section = +                section_info.GetSection(nlist.n_sect, nlist.n_value); +            if (!N_BRAC_indexes.empty()) { +              symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back()); +              symbol_ptr->SetByteSize(sym_idx + 1); +              symbol_ptr->SetSizeIsSibling(true); +              N_BRAC_indexes.pop_back();              } -            return true; -        } -        else -        { -            struct load_command load_cmd; +            type = eSymbolTypeScopeEnd; +            break; -            lldb::offset_t offset = lc_offset; -            for (uint32_t i=0; i<header.ncmds; ++i) -            { -                const lldb::offset_t cmd_offset = offset; -                if (data.GetU32(&offset, &load_cmd, 2) == NULL) -                    break; -                 -                switch (load_cmd.cmd) -                { -                    case llvm::MachO::LC_VERSION_MIN_IPHONEOS: -                        triple.setOS (llvm::Triple::IOS); -                        return true; -                         -                    case llvm::MachO::LC_VERSION_MIN_MACOSX: -                        triple.setOS (llvm::Triple::MacOSX); -                        return true; - -                    case llvm::MachO::LC_VERSION_MIN_TVOS: -                        triple.setOS (llvm::Triple::TvOS); -                        return true; -                         -                    case llvm::MachO::LC_VERSION_MIN_WATCHOS: -                        triple.setOS (llvm::Triple::WatchOS); -                        return true; +          case N_EXCL: +            // deleted include file: name,,NO_SECT,0,sum +            type = eSymbolTypeHeaderFile; +            break; -                    default: -                        break; -                } +          //---------------------------------------------------------------------- +          // COMM scopes +          //---------------------------------------------------------------------- +          case N_BCOMM: +            // begin common: name,,NO_SECT,0,0 +            // We use the current number of symbols in the symbol table in lieu +            // of +            // using nlist_idx in case we ever start trimming entries out +            type = eSymbolTypeScopeBegin; +            N_COMM_indexes.push_back(sym_idx); +            break; -                offset = cmd_offset + load_cmd.cmdsize; +          case N_ECOML: +            // end common (local name): 0,,n_sect,0,address +            symbol_section = +                section_info.GetSection(nlist.n_sect, nlist.n_value); +            LLVM_FALLTHROUGH; + +          case N_ECOMM: +            // end common: name,,n_sect,0,0 +            // Set the size of the N_BCOMM to the terminating index of this +            // N_ECOMM/N_ECOML +            // so that we can always skip the entire symbol if we need to +            // navigate +            // more quickly at the source level when parsing STABS +            if (!N_COMM_indexes.empty()) { +              symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back()); +              symbol_ptr->SetByteSize(sym_idx + 1); +              symbol_ptr->SetSizeIsSibling(true); +              N_COMM_indexes.pop_back();              } -             -            if (header.filetype != MH_KEXT_BUNDLE) -            { -                // We didn't find a LC_VERSION_MIN load command and this isn't a KEXT -                // so lets not say our Vendor is Apple, leave it as an unspecified unknown -                triple.setVendor(llvm::Triple::UnknownVendor); -                triple.setVendorName(llvm::StringRef()); +            type = eSymbolTypeScopeEnd; +            break; + +          case N_LENG: +            // second stab entry with length information +            type = eSymbolTypeAdditional; +            break; + +          default: +            break; +          } +        } else { +          // uint8_t n_pext    = N_PEXT & nlist.n_type; +          uint8_t n_type = N_TYPE & nlist.n_type; +          sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0); + +          switch (n_type) { +          case N_INDR: { +            const char *reexport_name_cstr = +                strtab_data.PeekCStr(nlist.n_value); +            if (reexport_name_cstr && reexport_name_cstr[0]) { +              type = eSymbolTypeReExported; +              ConstString reexport_name( +                  reexport_name_cstr + +                  ((reexport_name_cstr[0] == '_') ? 1 : 0)); +              sym[sym_idx].SetReExportedSymbolName(reexport_name); +              set_value = false; +              reexport_shlib_needs_fixup[sym_idx] = reexport_name; +              indirect_symbol_names.insert( +                  ConstString(symbol_name + ((symbol_name[0] == '_') ? 1 : 0))); +            } else +              type = eSymbolTypeUndefined; +          } break; + +          case N_UNDF: +            if (symbol_name && symbol_name[0]) { +              ConstString undefined_name(symbol_name + +                                         ((symbol_name[0] == '_') ? 1 : 0)); +              undefined_name_to_desc[undefined_name] = nlist.n_desc;              } -        } -    } -    return arch.IsValid(); -} +            LLVM_FALLTHROUGH; -bool -ObjectFileMachO::GetUUID (lldb_private::UUID* uuid) -{ -    ModuleSP module_sp(GetModule()); -    if (module_sp) -    { -        std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); -        lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); -        return GetUUID (m_header, m_data, offset, *uuid); -    } -    return false; -} +          case N_PBUD: +            type = eSymbolTypeUndefined; +            break; -uint32_t -ObjectFileMachO::GetDependentModules (FileSpecList& files) -{ -    uint32_t count = 0; -    ModuleSP module_sp(GetModule()); -    if (module_sp) -    { -        std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); -        struct load_command load_cmd; -        lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); -        std::vector<std::string> rpath_paths; -        std::vector<std::string> rpath_relative_paths; -        const bool resolve_path = false; // Don't resolve the dependent file paths since they may not reside on this system -        uint32_t i; -        for (i=0; i<m_header.ncmds; ++i) -        { -            const uint32_t cmd_offset = offset; -            if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) -                break; +          case N_ABS: +            type = eSymbolTypeAbsolute; +            break; -            switch (load_cmd.cmd) -            { -            case LC_RPATH: -            case LC_LOAD_DYLIB: -            case LC_LOAD_WEAK_DYLIB: -            case LC_REEXPORT_DYLIB: -            case LC_LOAD_DYLINKER: -            case LC_LOADFVMLIB: -            case LC_LOAD_UPWARD_DYLIB: -                { -                    uint32_t name_offset = cmd_offset + m_data.GetU32(&offset); -                    const char *path = m_data.PeekCStr(name_offset); -                    if (path) -                    { -                        if (load_cmd.cmd == LC_RPATH) -                            rpath_paths.push_back(path); -                        else -                        { -                            if (path[0] == '@') -                            { -                                if (strncmp(path, "@rpath", strlen("@rpath")) == 0) -                                    rpath_relative_paths.push_back(path + strlen("@rpath")); -                            } -                            else -                            { -                                FileSpec file_spec(path, resolve_path); -                                if (files.AppendIfUnique(file_spec)) -                                    count++; -                            } +          case N_SECT: { +            symbol_section = +                section_info.GetSection(nlist.n_sect, nlist.n_value); + +            if (!symbol_section) { +              // TODO: warn about this? +              add_nlist = false; +              break; +            } + +            if (TEXT_eh_frame_sectID == nlist.n_sect) { +              type = eSymbolTypeException; +            } else { +              uint32_t section_type = symbol_section->Get() & SECTION_TYPE; + +              switch (section_type) { +              case S_CSTRING_LITERALS: +                type = eSymbolTypeData; +                break; // section with only literal C strings +              case S_4BYTE_LITERALS: +                type = eSymbolTypeData; +                break; // section with only 4 byte literals +              case S_8BYTE_LITERALS: +                type = eSymbolTypeData; +                break; // section with only 8 byte literals +              case S_LITERAL_POINTERS: +                type = eSymbolTypeTrampoline; +                break; // section with only pointers to literals +              case S_NON_LAZY_SYMBOL_POINTERS: +                type = eSymbolTypeTrampoline; +                break; // section with only non-lazy symbol pointers +              case S_LAZY_SYMBOL_POINTERS: +                type = eSymbolTypeTrampoline; +                break; // section with only lazy symbol pointers +              case S_SYMBOL_STUBS: +                type = eSymbolTypeTrampoline; +                break; // section with only symbol stubs, byte size of stub in +                       // the reserved2 field +              case S_MOD_INIT_FUNC_POINTERS: +                type = eSymbolTypeCode; +                break; // section with only function pointers for initialization +              case S_MOD_TERM_FUNC_POINTERS: +                type = eSymbolTypeCode; +                break; // section with only function pointers for termination +              case S_INTERPOSING: +                type = eSymbolTypeTrampoline; +                break; // section with only pairs of function pointers for +                       // interposing +              case S_16BYTE_LITERALS: +                type = eSymbolTypeData; +                break; // section with only 16 byte literals +              case S_DTRACE_DOF: +                type = eSymbolTypeInstrumentation; +                break; +              case S_LAZY_DYLIB_SYMBOL_POINTERS: +                type = eSymbolTypeTrampoline; +                break; +              default: +                switch (symbol_section->GetType()) { +                case lldb::eSectionTypeCode: +                  type = eSymbolTypeCode; +                  break; +                case eSectionTypeData: +                case eSectionTypeDataCString:         // Inlined C string data +                case eSectionTypeDataCStringPointers: // Pointers to C string +                                                      // data +                case eSectionTypeDataSymbolAddress:   // Address of a symbol in +                                                      // the symbol table +                case eSectionTypeData4: +                case eSectionTypeData8: +                case eSectionTypeData16: +                  type = eSymbolTypeData; +                  break; +                default: +                  break; +                } +                break; +              } + +              if (type == eSymbolTypeInvalid) { +                const char *symbol_sect_name = +                    symbol_section->GetName().AsCString(); +                if (symbol_section->IsDescendant(text_section_sp.get())) { +                  if (symbol_section->IsClear(S_ATTR_PURE_INSTRUCTIONS | +                                              S_ATTR_SELF_MODIFYING_CODE | +                                              S_ATTR_SOME_INSTRUCTIONS)) +                    type = eSymbolTypeData; +                  else +                    type = eSymbolTypeCode; +                } else if (symbol_section->IsDescendant( +                               data_section_sp.get()) || +                           symbol_section->IsDescendant( +                               data_dirty_section_sp.get()) || +                           symbol_section->IsDescendant( +                               data_const_section_sp.get())) { +                  if (symbol_sect_name && +                      ::strstr(symbol_sect_name, "__objc") == +                          symbol_sect_name) { +                    type = eSymbolTypeRuntime; + +                    if (symbol_name) { +                      llvm::StringRef symbol_name_ref(symbol_name); +                      if (symbol_name_ref.startswith("_OBJC_")) { +                        static const llvm::StringRef g_objc_v2_prefix_class( +                            "_OBJC_CLASS_$_"); +                        static const llvm::StringRef g_objc_v2_prefix_metaclass( +                            "_OBJC_METACLASS_$_"); +                        static const llvm::StringRef g_objc_v2_prefix_ivar( +                            "_OBJC_IVAR_$_"); +                        if (symbol_name_ref.startswith( +                                g_objc_v2_prefix_class)) { +                          symbol_name_non_abi_mangled = symbol_name + 1; +                          symbol_name = +                              symbol_name + g_objc_v2_prefix_class.size(); +                          type = eSymbolTypeObjCClass; +                          demangled_is_synthesized = true; +                        } else if (symbol_name_ref.startswith( +                                       g_objc_v2_prefix_metaclass)) { +                          symbol_name_non_abi_mangled = symbol_name + 1; +                          symbol_name = +                              symbol_name + g_objc_v2_prefix_metaclass.size(); +                          type = eSymbolTypeObjCMetaClass; +                          demangled_is_synthesized = true; +                        } else if (symbol_name_ref.startswith( +                                       g_objc_v2_prefix_ivar)) { +                          symbol_name_non_abi_mangled = symbol_name + 1; +                          symbol_name = +                              symbol_name + g_objc_v2_prefix_ivar.size(); +                          type = eSymbolTypeObjCIVar; +                          demangled_is_synthesized = true;                          } +                      } +                    } +                  } else if (symbol_sect_name && +                             ::strstr(symbol_sect_name, "__gcc_except_tab") == +                                 symbol_sect_name) { +                    type = eSymbolTypeException; +                  } else { +                    type = eSymbolTypeData; +                  } +                } else if (symbol_sect_name && +                           ::strstr(symbol_sect_name, "__IMPORT") == +                               symbol_sect_name) { +                  type = eSymbolTypeTrampoline; +                } else if (symbol_section->IsDescendant( +                               objc_section_sp.get())) { +                  type = eSymbolTypeRuntime; +                  if (symbol_name && symbol_name[0] == '.') { +                    llvm::StringRef symbol_name_ref(symbol_name); +                    static const llvm::StringRef g_objc_v1_prefix_class( +                        ".objc_class_name_"); +                    if (symbol_name_ref.startswith(g_objc_v1_prefix_class)) { +                      symbol_name_non_abi_mangled = symbol_name; +                      symbol_name = symbol_name + g_objc_v1_prefix_class.size(); +                      type = eSymbolTypeObjCClass; +                      demangled_is_synthesized = true;                      } +                  }                  } -                break; - -            default: -                break; +              }              } -            offset = cmd_offset + load_cmd.cmdsize; +          } break; +          }          } -        if (!rpath_paths.empty()) -        { -            // Fixup all LC_RPATH values to be absolute paths -            FileSpec this_file_spec(m_file); -            this_file_spec.ResolvePath(); -            std::string loader_path("@loader_path"); -            std::string executable_path("@executable_path"); -            for (auto &rpath : rpath_paths) -            { -                if (rpath.find(loader_path) == 0) -                { -                    rpath.erase(0, loader_path.size()); -                    rpath.insert(0, this_file_spec.GetDirectory().GetCString()); +        if (add_nlist) { +          uint64_t symbol_value = nlist.n_value; + +          if (symbol_name_non_abi_mangled) { +            sym[sym_idx].GetMangled().SetMangledName( +                ConstString(symbol_name_non_abi_mangled)); +            sym[sym_idx].GetMangled().SetDemangledName( +                ConstString(symbol_name)); +          } else { +            bool symbol_name_is_mangled = false; + +            if (symbol_name && symbol_name[0] == '_') { +              symbol_name_is_mangled = symbol_name[1] == '_'; +              symbol_name++; // Skip the leading underscore +            } + +            if (symbol_name) { +              ConstString const_symbol_name(symbol_name); +              sym[sym_idx].GetMangled().SetValue(const_symbol_name, +                                                 symbol_name_is_mangled); +            } +          } + +          if (is_gsym) { +            const char *gsym_name = sym[sym_idx] +                                        .GetMangled() +                                        .GetName(lldb::eLanguageTypeUnknown, +                                                 Mangled::ePreferMangled) +                                        .GetCString(); +            if (gsym_name) +              N_GSYM_name_to_sym_idx[gsym_name] = sym_idx; +          } + +          if (symbol_section) { +            const addr_t section_file_addr = symbol_section->GetFileAddress(); +            if (symbol_byte_size == 0 && function_starts_count > 0) { +              addr_t symbol_lookup_file_addr = nlist.n_value; +              // Do an exact address match for non-ARM addresses, else get the +              // closest since +              // the symbol might be a thumb symbol which has an address with +              // bit zero set +              FunctionStarts::Entry *func_start_entry = +                  function_starts.FindEntry(symbol_lookup_file_addr, !is_arm); +              if (is_arm && func_start_entry) { +                // Verify that the function start address is the symbol address +                // (ARM) +                // or the symbol address + 1 (thumb) +                if (func_start_entry->addr != symbol_lookup_file_addr && +                    func_start_entry->addr != (symbol_lookup_file_addr + 1)) { +                  // Not the right entry, NULL it out... +                  func_start_entry = NULL;                  } -                else if (rpath.find(executable_path) == 0) -                { -                    rpath.erase(0, executable_path.size()); -                    rpath.insert(0, this_file_spec.GetDirectory().GetCString()); +              } +              if (func_start_entry) { +                func_start_entry->data = true; + +                addr_t symbol_file_addr = func_start_entry->addr; +                if (is_arm) +                  symbol_file_addr &= THUMB_ADDRESS_BIT_MASK; + +                const FunctionStarts::Entry *next_func_start_entry = +                    function_starts.FindNextEntry(func_start_entry); +                const addr_t section_end_file_addr = +                    section_file_addr + symbol_section->GetByteSize(); +                if (next_func_start_entry) { +                  addr_t next_symbol_file_addr = next_func_start_entry->addr; +                  // Be sure the clear the Thumb address bit when we calculate +                  // the size +                  // from the current and next address +                  if (is_arm) +                    next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK; +                  symbol_byte_size = std::min<lldb::addr_t>( +                      next_symbol_file_addr - symbol_file_addr, +                      section_end_file_addr - symbol_file_addr); +                } else { +                  symbol_byte_size = section_end_file_addr - symbol_file_addr;                  } +              }              } - -            for (const auto &rpath_relative_path : rpath_relative_paths) -            { -                for (const auto &rpath : rpath_paths) -                { -                    std::string path = rpath; -                    path += rpath_relative_path; -                    // It is OK to resolve this path because we must find a file on -                    // disk for us to accept it anyway if it is rpath relative. -                    FileSpec file_spec(path, true); -                    // Remove any redundant parts of the path (like "../foo") since -                    // LC_RPATH values often contain "..". -                    file_spec.NormalizePath (); -                    if (file_spec.Exists() && files.AppendIfUnique(file_spec)) -                    { -                        count++; -                        break; -                    } +            symbol_value -= section_file_addr; +          } + +          if (is_debug == false) { +            if (type == eSymbolTypeCode) { +              // See if we can find a N_FUN entry for any code symbols. +              // If we do find a match, and the name matches, then we +              // can merge the two into just the function symbol to avoid +              // duplicate entries in the symbol table +              std::pair<ValueToSymbolIndexMap::const_iterator, +                        ValueToSymbolIndexMap::const_iterator> +                  range; +              range = N_FUN_addr_to_sym_idx.equal_range(nlist.n_value); +              if (range.first != range.second) { +                bool found_it = false; +                for (ValueToSymbolIndexMap::const_iterator pos = range.first; +                     pos != range.second; ++pos) { +                  if (sym[sym_idx].GetMangled().GetName( +                          lldb::eLanguageTypeUnknown, +                          Mangled::ePreferMangled) == +                      sym[pos->second].GetMangled().GetName( +                          lldb::eLanguageTypeUnknown, +                          Mangled::ePreferMangled)) { +                    m_nlist_idx_to_sym_idx[nlist_idx] = pos->second; +                    // We just need the flags from the linker symbol, so put +                    // these flags +                    // into the N_FUN flags to avoid duplicate symbols in the +                    // symbol table +                    sym[pos->second].SetExternal(sym[sym_idx].IsExternal()); +                    sym[pos->second].SetFlags(nlist.n_type << 16 | +                                              nlist.n_desc); +                    if (resolver_addresses.find(nlist.n_value) != +                        resolver_addresses.end()) +                      sym[pos->second].SetType(eSymbolTypeResolver); +                    sym[sym_idx].Clear(); +                    found_it = true; +                    break; +                  } +                } +                if (found_it) +                  continue; +              } else { +                if (resolver_addresses.find(nlist.n_value) != +                    resolver_addresses.end()) +                  type = eSymbolTypeResolver; +              } +            } else if (type == eSymbolTypeData || +                       type == eSymbolTypeObjCClass || +                       type == eSymbolTypeObjCMetaClass || +                       type == eSymbolTypeObjCIVar) { +              // See if we can find a N_STSYM entry for any data symbols. +              // If we do find a match, and the name matches, then we +              // can merge the two into just the Static symbol to avoid +              // duplicate entries in the symbol table +              std::pair<ValueToSymbolIndexMap::const_iterator, +                        ValueToSymbolIndexMap::const_iterator> +                  range; +              range = N_STSYM_addr_to_sym_idx.equal_range(nlist.n_value); +              if (range.first != range.second) { +                bool found_it = false; +                for (ValueToSymbolIndexMap::const_iterator pos = range.first; +                     pos != range.second; ++pos) { +                  if (sym[sym_idx].GetMangled().GetName( +                          lldb::eLanguageTypeUnknown, +                          Mangled::ePreferMangled) == +                      sym[pos->second].GetMangled().GetName( +                          lldb::eLanguageTypeUnknown, +                          Mangled::ePreferMangled)) { +                    m_nlist_idx_to_sym_idx[nlist_idx] = pos->second; +                    // We just need the flags from the linker symbol, so put +                    // these flags +                    // into the N_STSYM flags to avoid duplicate symbols in the +                    // symbol table +                    sym[pos->second].SetExternal(sym[sym_idx].IsExternal()); +                    sym[pos->second].SetFlags(nlist.n_type << 16 | +                                              nlist.n_desc); +                    sym[sym_idx].Clear(); +                    found_it = true; +                    break; +                  } +                } +                if (found_it) +                  continue; +              } else { +                // Combine N_GSYM stab entries with the non stab symbol +                const char *gsym_name = sym[sym_idx] +                                            .GetMangled() +                                            .GetName(lldb::eLanguageTypeUnknown, +                                                     Mangled::ePreferMangled) +                                            .GetCString(); +                if (gsym_name) { +                  ConstNameToSymbolIndexMap::const_iterator pos = +                      N_GSYM_name_to_sym_idx.find(gsym_name); +                  if (pos != N_GSYM_name_to_sym_idx.end()) { +                    const uint32_t GSYM_sym_idx = pos->second; +                    m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx; +                    // Copy the address, because often the N_GSYM address has an +                    // invalid address of zero +                    // when the global is a common symbol +                    sym[GSYM_sym_idx].GetAddressRef().SetSection( +                        symbol_section); +                    sym[GSYM_sym_idx].GetAddressRef().SetOffset(symbol_value); +                    // We just need the flags from the linker symbol, so put +                    // these flags +                    // into the N_GSYM flags to avoid duplicate symbols in the +                    // symbol table +                    sym[GSYM_sym_idx].SetFlags(nlist.n_type << 16 | +                                               nlist.n_desc); +                    sym[sym_idx].Clear(); +                    continue; +                  }                  } +              }              } -        } -    } -    return count; -} +          } -lldb_private::Address -ObjectFileMachO::GetEntryPointAddress () -{ -    // If the object file is not an executable it can't hold the entry point.  m_entry_point_address -    // is initialized to an invalid address, so we can just return that. -    // If m_entry_point_address is valid it means we've found it already, so return the cached value. +          sym[sym_idx].SetID(nlist_idx); +          sym[sym_idx].SetType(type); +          if (set_value) { +            sym[sym_idx].GetAddressRef().SetSection(symbol_section); +            sym[sym_idx].GetAddressRef().SetOffset(symbol_value); +          } +          sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc); -    if (!IsExecutable() || m_entry_point_address.IsValid()) -        return m_entry_point_address; +          if (symbol_byte_size > 0) +            sym[sym_idx].SetByteSize(symbol_byte_size); -    // Otherwise, look for the UnixThread or Thread command.  The data for the Thread command is given in -    // /usr/include/mach-o.h, but it is basically: -    // -    //  uint32_t flavor  - this is the flavor argument you would pass to thread_get_state -    //  uint32_t count   - this is the count of longs in the thread state data -    //  struct XXX_thread_state state - this is the structure from <machine/thread_status.h> corresponding to the flavor. -    //  <repeat this trio> -    // -    // So we just keep reading the various register flavors till we find the GPR one, then read the PC out of there. -    // FIXME: We will need to have a "RegisterContext data provider" class at some point that can get all the registers -    // out of data in this form & attach them to a given thread.  That should underlie the MacOS X User process plugin, -    // and we'll also need it for the MacOS X Core File process plugin.  When we have that we can also use it here. -    // -    // For now we hard-code the offsets and flavors we need: -    // -    // +          if (demangled_is_synthesized) +            sym[sym_idx].SetDemangledNameIsSynthesized(true); -    ModuleSP module_sp(GetModule()); -    if (module_sp) -    { -        std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); -        struct load_command load_cmd; -        lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); -        uint32_t i; -        lldb::addr_t start_address = LLDB_INVALID_ADDRESS; -        bool done = false; +          ++sym_idx; +        } else { +          sym[sym_idx].Clear(); +        } +      } + +      for (const auto &pos : reexport_shlib_needs_fixup) { +        const auto undef_pos = undefined_name_to_desc.find(pos.second); +        if (undef_pos != undefined_name_to_desc.end()) { +          const uint8_t dylib_ordinal = +              llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second); +          if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize()) +            sym[pos.first].SetReExportedSymbolSharedLibrary( +                dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1)); +        } +      } +    } -        for (i=0; i<m_header.ncmds; ++i) -        { -            const lldb::offset_t cmd_offset = offset; -            if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) -                break; +    uint32_t synthetic_sym_id = symtab_load_command.nsyms; -            switch (load_cmd.cmd) -            { -            case LC_UNIXTHREAD: -            case LC_THREAD: -                { -                    while (offset < cmd_offset + load_cmd.cmdsize) -                    { -                        uint32_t flavor = m_data.GetU32(&offset); -                        uint32_t count = m_data.GetU32(&offset); -                        if (count == 0) -                        { -                            // We've gotten off somehow, log and exit; -                            return m_entry_point_address; -                        } +    if (function_starts_count > 0) { +      uint32_t num_synthetic_function_symbols = 0; +      for (i = 0; i < function_starts_count; ++i) { +        if (function_starts.GetEntryRef(i).data == false) +          ++num_synthetic_function_symbols; +      } -                        switch (m_header.cputype) -                        { -                        case llvm::MachO::CPU_TYPE_ARM: -                           if (flavor == 1 || flavor == 9) // ARM_THREAD_STATE/ARM_THREAD_STATE32 from mach/arm/thread_status.h -                           { -                               offset += 60;  // This is the offset of pc in the GPR thread state data structure. -                               start_address = m_data.GetU32(&offset); -                               done = true; -                            } -                        break; -                        case llvm::MachO::CPU_TYPE_ARM64: -                           if (flavor == 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h -                           { -                               offset += 256;  // This is the offset of pc in the GPR thread state data structure. -                               start_address = m_data.GetU64(&offset); -                               done = true; -                            } -                        break; -                        case llvm::MachO::CPU_TYPE_I386: -                           if (flavor == 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h -                           { -                               offset += 40;  // This is the offset of eip in the GPR thread state data structure. -                               start_address = m_data.GetU32(&offset); -                               done = true; -                            } -                        break; -                        case llvm::MachO::CPU_TYPE_X86_64: -                           if (flavor == 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h -                           { -                               offset += 16 * 8;  // This is the offset of rip in the GPR thread state data structure. -                               start_address = m_data.GetU64(&offset); -                               done = true; -                            } -                        break; -                        default: -                            return m_entry_point_address; -                        } -                        // Haven't found the GPR flavor yet, skip over the data for this flavor: -                        if (done) -                            break; -                        offset += count * 4; -                    } -                } -                break; -            case LC_MAIN: -                { -                    ConstString text_segment_name ("__TEXT"); -                    uint64_t entryoffset = m_data.GetU64(&offset); -                    SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name); -                    if (text_segment_sp) -                    { -                        done = true; -                        start_address = text_segment_sp->GetFileAddress() + entryoffset; -                    } +      if (num_synthetic_function_symbols > 0) { +        if (num_syms < sym_idx + num_synthetic_function_symbols) { +          num_syms = sym_idx + num_synthetic_function_symbols; +          sym = symtab->Resize(num_syms); +        } +        for (i = 0; i < function_starts_count; ++i) { +          const FunctionStarts::Entry *func_start_entry = +              function_starts.GetEntryAtIndex(i); +          if (func_start_entry->data == false) { +            addr_t symbol_file_addr = func_start_entry->addr; +            uint32_t symbol_flags = 0; +            if (is_arm) { +              if (symbol_file_addr & 1) +                symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB; +              symbol_file_addr &= THUMB_ADDRESS_BIT_MASK; +            } +            Address symbol_addr; +            if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) { +              SectionSP symbol_section(symbol_addr.GetSection()); +              uint32_t symbol_byte_size = 0; +              if (symbol_section) { +                const addr_t section_file_addr = +                    symbol_section->GetFileAddress(); +                const FunctionStarts::Entry *next_func_start_entry = +                    function_starts.FindNextEntry(func_start_entry); +                const addr_t section_end_file_addr = +                    section_file_addr + symbol_section->GetByteSize(); +                if (next_func_start_entry) { +                  addr_t next_symbol_file_addr = next_func_start_entry->addr; +                  if (is_arm) +                    next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK; +                  symbol_byte_size = std::min<lldb::addr_t>( +                      next_symbol_file_addr - symbol_file_addr, +                      section_end_file_addr - symbol_file_addr); +                } else { +                  symbol_byte_size = section_end_file_addr - symbol_file_addr;                  } -                break; - -            default: -                break; +                sym[sym_idx].SetID(synthetic_sym_id++); +                sym[sym_idx].GetMangled().SetDemangledName( +                    GetNextSyntheticSymbolName()); +                sym[sym_idx].SetType(eSymbolTypeCode); +                sym[sym_idx].SetIsSynthetic(true); +                sym[sym_idx].GetAddressRef() = symbol_addr; +                if (symbol_flags) +                  sym[sym_idx].SetFlags(symbol_flags); +                if (symbol_byte_size) +                  sym[sym_idx].SetByteSize(symbol_byte_size); +                ++sym_idx; +              }              } -            if (done) -                break; - -            // Go to the next load command: -            offset = cmd_offset + load_cmd.cmdsize; +          }          } +      } +    } -        if (start_address != LLDB_INVALID_ADDRESS) -        { -            // We got the start address from the load commands, so now resolve that address in the sections -            // of this ObjectFile: -            if (!m_entry_point_address.ResolveAddressUsingFileSections (start_address, GetSectionList())) -            { -                m_entry_point_address.Clear(); -            } -        } -        else -        { -            // We couldn't read the UnixThread load command - maybe it wasn't there.  As a fallback look for the -            // "start" symbol in the main executable. +    // Trim our symbols down to just what we ended up with after +    // removing any symbols. +    if (sym_idx < num_syms) { +      num_syms = sym_idx; +      sym = symtab->Resize(num_syms); +    } -            ModuleSP module_sp (GetModule()); +    // Now synthesize indirect symbols +    if (m_dysymtab.nindirectsyms != 0) { +      if (indirect_symbol_index_data.GetByteSize()) { +        NListIndexToSymbolIndexMap::const_iterator end_index_pos = +            m_nlist_idx_to_sym_idx.end(); + +        for (uint32_t sect_idx = 1; sect_idx < m_mach_sections.size(); +             ++sect_idx) { +          if ((m_mach_sections[sect_idx].flags & SECTION_TYPE) == +              S_SYMBOL_STUBS) { +            uint32_t symbol_stub_byte_size = +                m_mach_sections[sect_idx].reserved2; +            if (symbol_stub_byte_size == 0) +              continue; + +            const uint32_t num_symbol_stubs = +                m_mach_sections[sect_idx].size / symbol_stub_byte_size; + +            if (num_symbol_stubs == 0) +              continue; + +            const uint32_t symbol_stub_index_offset = +                m_mach_sections[sect_idx].reserved1; +            for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; +                 ++stub_idx) { +              const uint32_t symbol_stub_index = +                  symbol_stub_index_offset + stub_idx; +              const lldb::addr_t symbol_stub_addr = +                  m_mach_sections[sect_idx].addr + +                  (stub_idx * symbol_stub_byte_size); +              lldb::offset_t symbol_stub_offset = symbol_stub_index * 4; +              if (indirect_symbol_index_data.ValidOffsetForDataOfSize( +                      symbol_stub_offset, 4)) { +                const uint32_t stub_sym_id = +                    indirect_symbol_index_data.GetU32(&symbol_stub_offset); +                if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL)) +                  continue; + +                NListIndexToSymbolIndexMap::const_iterator index_pos = +                    m_nlist_idx_to_sym_idx.find(stub_sym_id); +                Symbol *stub_symbol = NULL; +                if (index_pos != end_index_pos) { +                  // We have a remapping from the original nlist index to +                  // a current symbol index, so just look this up by index +                  stub_symbol = symtab->SymbolAtIndex(index_pos->second); +                } else { +                  // We need to lookup a symbol using the original nlist +                  // symbol index since this index is coming from the +                  // S_SYMBOL_STUBS +                  stub_symbol = symtab->FindSymbolByID(stub_sym_id); +                } -            if (module_sp) -            { -                SymbolContextList contexts; -                SymbolContext context; -                if (module_sp->FindSymbolsWithNameAndType(ConstString ("start"), eSymbolTypeCode, contexts)) -                { -                    if (contexts.GetContextAtIndex(0, context)) -                        m_entry_point_address = context.symbol->GetAddress(); +                if (stub_symbol) { +                  Address so_addr(symbol_stub_addr, section_list); + +                  if (stub_symbol->GetType() == eSymbolTypeUndefined) { +                    // Change the external symbol into a trampoline that makes +                    // sense +                    // These symbols were N_UNDF N_EXT, and are useless to us, +                    // so we +                    // can re-use them so we don't have to make up a synthetic +                    // symbol +                    // for no good reason. +                    if (resolver_addresses.find(symbol_stub_addr) == +                        resolver_addresses.end()) +                      stub_symbol->SetType(eSymbolTypeTrampoline); +                    else +                      stub_symbol->SetType(eSymbolTypeResolver); +                    stub_symbol->SetExternal(false); +                    stub_symbol->GetAddressRef() = so_addr; +                    stub_symbol->SetByteSize(symbol_stub_byte_size); +                  } else { +                    // Make a synthetic symbol to describe the trampoline stub +                    Mangled stub_symbol_mangled_name(stub_symbol->GetMangled()); +                    if (sym_idx >= num_syms) { +                      sym = symtab->Resize(++num_syms); +                      stub_symbol = NULL; // this pointer no longer valid +                    } +                    sym[sym_idx].SetID(synthetic_sym_id++); +                    sym[sym_idx].GetMangled() = stub_symbol_mangled_name; +                    if (resolver_addresses.find(symbol_stub_addr) == +                        resolver_addresses.end()) +                      sym[sym_idx].SetType(eSymbolTypeTrampoline); +                    else +                      sym[sym_idx].SetType(eSymbolTypeResolver); +                    sym[sym_idx].SetIsSynthetic(true); +                    sym[sym_idx].GetAddressRef() = so_addr; +                    sym[sym_idx].SetByteSize(symbol_stub_byte_size); +                    ++sym_idx; +                  } +                } else { +                  if (log) +                    log->Warning("symbol stub referencing symbol table symbol " +                                 "%u that isn't in our minimal symbol table, " +                                 "fix this!!!", +                                 stub_sym_id);                  } +              }              } +          }          } +      }      } -    return m_entry_point_address; -} - -lldb_private::Address -ObjectFileMachO::GetHeaderAddress () -{ -    lldb_private::Address header_addr; -    SectionList *section_list = GetSectionList(); -    if (section_list) -    { -        SectionSP text_segment_sp (section_list->FindSectionByName (GetSegmentNameTEXT())); -        if (text_segment_sp) -        { -            header_addr.SetSection (text_segment_sp); -            header_addr.SetOffset (0); +    if (!trie_entries.empty()) { +      for (const auto &e : trie_entries) { +        if (e.entry.import_name) { +          // Only add indirect symbols from the Trie entries if we +          // didn't have a N_INDR nlist entry for this already +          if (indirect_symbol_names.find(e.entry.name) == +              indirect_symbol_names.end()) { +            // Make a synthetic symbol to describe re-exported symbol. +            if (sym_idx >= num_syms) +              sym = symtab->Resize(++num_syms); +            sym[sym_idx].SetID(synthetic_sym_id++); +            sym[sym_idx].GetMangled() = Mangled(e.entry.name); +            sym[sym_idx].SetType(eSymbolTypeReExported); +            sym[sym_idx].SetIsSynthetic(true); +            sym[sym_idx].SetReExportedSymbolName(e.entry.import_name); +            if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize()) { +              sym[sym_idx].SetReExportedSymbolSharedLibrary( +                  dylib_files.GetFileSpecAtIndex(e.entry.other - 1)); +            } +            ++sym_idx; +          }          } +      }      } -    return header_addr; + +    //        StreamFile s(stdout, false); +    //        s.Printf ("Symbol table before CalculateSymbolSizes():\n"); +    //        symtab->Dump(&s, NULL, eSortOrderNone); +    // Set symbol byte sizes correctly since mach-o nlist entries don't have +    // sizes +    symtab->CalculateSymbolSizes(); + +    //        s.Printf ("Symbol table after CalculateSymbolSizes():\n"); +    //        symtab->Dump(&s, NULL, eSortOrderNone); + +    return symtab->GetNumSymbols(); +  } +  return 0;  } -uint32_t -ObjectFileMachO::GetNumThreadContexts () -{ -    ModuleSP module_sp(GetModule()); -    if (module_sp) -    { -        std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); -        if (!m_thread_context_offsets_valid) -        { -            m_thread_context_offsets_valid = true; -            lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); -            FileRangeArray::Entry file_range; -            thread_command thread_cmd; -            for (uint32_t i=0; i<m_header.ncmds; ++i) -            { -                const uint32_t cmd_offset = offset; -                if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL) -                    break; +void ObjectFileMachO::Dump(Stream *s) { +  ModuleSP module_sp(GetModule()); +  if (module_sp) { +    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); +    s->Printf("%p: ", static_cast<void *>(this)); +    s->Indent(); +    if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64) +      s->PutCString("ObjectFileMachO64"); +    else +      s->PutCString("ObjectFileMachO32"); -                if (thread_cmd.cmd == LC_THREAD) -                { -                    file_range.SetRangeBase (offset); -                    file_range.SetByteSize (thread_cmd.cmdsize - 8); -                    m_thread_context_offsets.Append (file_range); -                } -                offset = cmd_offset + thread_cmd.cmdsize; -            } -        } -    } -    return m_thread_context_offsets.GetSize(); +    ArchSpec header_arch; +    GetArchitecture(header_arch); + +    *s << ", file = '" << m_file +       << "', arch = " << header_arch.GetArchitectureName() << "\n"; + +    SectionList *sections = GetSectionList(); +    if (sections) +      sections->Dump(s, NULL, true, UINT32_MAX); + +    if (m_symtab_ap.get()) +      m_symtab_ap->Dump(s, NULL, eSortOrderNone); +  }  } -lldb::RegisterContextSP -ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread) -{ -    lldb::RegisterContextSP reg_ctx_sp; +bool ObjectFileMachO::GetUUID(const llvm::MachO::mach_header &header, +                              const lldb_private::DataExtractor &data, +                              lldb::offset_t lc_offset, +                              lldb_private::UUID &uuid) { +  uint32_t i; +  struct uuid_command load_cmd; -    ModuleSP module_sp(GetModule()); -    if (module_sp) -    { -        std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); -        if (!m_thread_context_offsets_valid) -            GetNumThreadContexts (); +  lldb::offset_t offset = lc_offset; +  for (i = 0; i < header.ncmds; ++i) { +    const lldb::offset_t cmd_offset = offset; +    if (data.GetU32(&offset, &load_cmd, 2) == NULL) +      break; -        const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx); -        if (thread_context_file_range) -        { +    if (load_cmd.cmd == LC_UUID) { +      const uint8_t *uuid_bytes = data.PeekData(offset, 16); -            DataExtractor data (m_data, -                                thread_context_file_range->GetRangeBase(), -                                thread_context_file_range->GetByteSize()); +      if (uuid_bytes) { +        // OpenCL on Mac OS X uses the same UUID for each of its object files. +        // We pretend these object files have no UUID to prevent crashing. -            switch (m_header.cputype) -            { -                case llvm::MachO::CPU_TYPE_ARM64: -                    reg_ctx_sp.reset (new RegisterContextDarwin_arm64_Mach (thread, data)); -                    break; -                     -                case llvm::MachO::CPU_TYPE_ARM: -                    reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data)); -                    break; +        const uint8_t opencl_uuid[] = {0x8c, 0x8e, 0xb3, 0x9b, 0x3b, 0xa8, +                                       0x4b, 0x16, 0xb6, 0xa4, 0x27, 0x63, +                                       0xbb, 0x14, 0xf0, 0x0d}; -                case llvm::MachO::CPU_TYPE_I386: -                    reg_ctx_sp.reset (new RegisterContextDarwin_i386_Mach (thread, data)); -                    break; +        if (!memcmp(uuid_bytes, opencl_uuid, 16)) +          return false; -                case llvm::MachO::CPU_TYPE_X86_64: -                    reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data)); -                    break; -            } +        uuid.SetBytes(uuid_bytes); +        return true; +      } +      return false; +    } +    offset = cmd_offset + load_cmd.cmdsize; +  } +  return false; +} + +bool ObjectFileMachO::GetArchitecture(const llvm::MachO::mach_header &header, +                                      const lldb_private::DataExtractor &data, +                                      lldb::offset_t lc_offset, +                                      ArchSpec &arch) { +  arch.SetArchitecture(eArchTypeMachO, header.cputype, header.cpusubtype); + +  if (arch.IsValid()) { +    llvm::Triple &triple = arch.GetTriple(); + +    // Set OS to an unspecified unknown or a "*" so it can match any OS +    triple.setOS(llvm::Triple::UnknownOS); +    triple.setOSName(llvm::StringRef()); + +    if (header.filetype == MH_PRELOAD) { +      if (header.cputype == CPU_TYPE_ARM) { +        // If this is a 32-bit arm binary, and it's a standalone binary, +        // force the Vendor to Apple so we don't accidentally pick up +        // the generic armv7 ABI at runtime.  Apple's armv7 ABI always uses +        // r7 for the frame pointer register; most other armv7 ABIs use a +        // combination of r7 and r11. +        triple.setVendor(llvm::Triple::Apple); +      } else { +        // Set vendor to an unspecified unknown or a "*" so it can match any +        // vendor +        // This is required for correct behavior of EFI debugging on x86_64 +        triple.setVendor(llvm::Triple::UnknownVendor); +        triple.setVendorName(llvm::StringRef()); +      } +      return true; +    } else { +      struct load_command load_cmd; + +      lldb::offset_t offset = lc_offset; +      for (uint32_t i = 0; i < header.ncmds; ++i) { +        const lldb::offset_t cmd_offset = offset; +        if (data.GetU32(&offset, &load_cmd, 2) == NULL) +          break; + +        switch (load_cmd.cmd) { +        case llvm::MachO::LC_VERSION_MIN_IPHONEOS: +          triple.setOS(llvm::Triple::IOS); +          return true; + +        case llvm::MachO::LC_VERSION_MIN_MACOSX: +          triple.setOS(llvm::Triple::MacOSX); +          return true; + +        case llvm::MachO::LC_VERSION_MIN_TVOS: +          triple.setOS(llvm::Triple::TvOS); +          return true; + +        case llvm::MachO::LC_VERSION_MIN_WATCHOS: +          triple.setOS(llvm::Triple::WatchOS); +          return true; + +        default: +          break;          } + +        offset = cmd_offset + load_cmd.cmdsize; +      } + +      if (header.filetype != MH_KEXT_BUNDLE) { +        // We didn't find a LC_VERSION_MIN load command and this isn't a KEXT +        // so lets not say our Vendor is Apple, leave it as an unspecified +        // unknown +        triple.setVendor(llvm::Triple::UnknownVendor); +        triple.setVendorName(llvm::StringRef()); +      }      } -    return reg_ctx_sp; +  } +  return arch.IsValid();  } -ObjectFile::Type -ObjectFileMachO::CalculateType() -{ -    switch (m_header.filetype) -    { -        case MH_OBJECT:                                         // 0x1u -            if (GetAddressByteSize () == 4) -            { -                // 32 bit kexts are just object files, but they do have a valid -                // UUID load command. -                UUID uuid; -                if (GetUUID(&uuid)) -                { -                    // this checking for the UUID load command is not enough -                    // we could eventually look for the symbol named -                    // "OSKextGetCurrentIdentifier" as this is required of kexts -                    if (m_strata == eStrataInvalid) -                        m_strata = eStrataKernel; -                    return eTypeSharedLibrary; -                } +bool ObjectFileMachO::GetUUID(lldb_private::UUID *uuid) { +  ModuleSP module_sp(GetModule()); +  if (module_sp) { +    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); +    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); +    return GetUUID(m_header, m_data, offset, *uuid); +  } +  return false; +} + +uint32_t ObjectFileMachO::GetDependentModules(FileSpecList &files) { +  uint32_t count = 0; +  ModuleSP module_sp(GetModule()); +  if (module_sp) { +    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); +    struct load_command load_cmd; +    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); +    std::vector<std::string> rpath_paths; +    std::vector<std::string> rpath_relative_paths; +    const bool resolve_path = false; // Don't resolve the dependent file paths +                                     // since they may not reside on this system +    uint32_t i; +    for (i = 0; i < m_header.ncmds; ++i) { +      const uint32_t cmd_offset = offset; +      if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) +        break; + +      switch (load_cmd.cmd) { +      case LC_RPATH: +      case LC_LOAD_DYLIB: +      case LC_LOAD_WEAK_DYLIB: +      case LC_REEXPORT_DYLIB: +      case LC_LOAD_DYLINKER: +      case LC_LOADFVMLIB: +      case LC_LOAD_UPWARD_DYLIB: { +        uint32_t name_offset = cmd_offset + m_data.GetU32(&offset); +        const char *path = m_data.PeekCStr(name_offset); +        if (path) { +          if (load_cmd.cmd == LC_RPATH) +            rpath_paths.push_back(path); +          else { +            if (path[0] == '@') { +              if (strncmp(path, "@rpath", strlen("@rpath")) == 0) +                rpath_relative_paths.push_back(path + strlen("@rpath")); +            } else { +              FileSpec file_spec(path, resolve_path); +              if (files.AppendIfUnique(file_spec)) +                count++;              } -            return eTypeObjectFile; - -        case MH_EXECUTE:            return eTypeExecutable;     // 0x2u -        case MH_FVMLIB:             return eTypeSharedLibrary;  // 0x3u -        case MH_CORE:               return eTypeCoreFile;       // 0x4u -        case MH_PRELOAD:            return eTypeSharedLibrary;  // 0x5u -        case MH_DYLIB:              return eTypeSharedLibrary;  // 0x6u -        case MH_DYLINKER:           return eTypeDynamicLinker;  // 0x7u -        case MH_BUNDLE:             return eTypeSharedLibrary;  // 0x8u -        case MH_DYLIB_STUB:         return eTypeStubLibrary;    // 0x9u -        case MH_DSYM:               return eTypeDebugInfo;      // 0xAu -        case MH_KEXT_BUNDLE:        return eTypeSharedLibrary;  // 0xBu -        default: +          } +        } +      } break; + +      default: +        break; +      } +      offset = cmd_offset + load_cmd.cmdsize; +    } + +    if (!rpath_paths.empty()) { +      // Fixup all LC_RPATH values to be absolute paths +      FileSpec this_file_spec(m_file); +      this_file_spec.ResolvePath(); +      std::string loader_path("@loader_path"); +      std::string executable_path("@executable_path"); +      for (auto &rpath : rpath_paths) { +        if (rpath.find(loader_path) == 0) { +          rpath.erase(0, loader_path.size()); +          rpath.insert(0, this_file_spec.GetDirectory().GetCString()); +        } else if (rpath.find(executable_path) == 0) { +          rpath.erase(0, executable_path.size()); +          rpath.insert(0, this_file_spec.GetDirectory().GetCString()); +        } +      } + +      for (const auto &rpath_relative_path : rpath_relative_paths) { +        for (const auto &rpath : rpath_paths) { +          std::string path = rpath; +          path += rpath_relative_path; +          // It is OK to resolve this path because we must find a file on +          // disk for us to accept it anyway if it is rpath relative. +          FileSpec file_spec(path, true); +          // Remove any redundant parts of the path (like "../foo") since +          // LC_RPATH values often contain "..". +          file_spec = file_spec.GetNormalizedPath(); +          if (file_spec.Exists() && files.AppendIfUnique(file_spec)) { +            count++;              break; +          } +        } +      }      } -    return eTypeUnknown; +  } +  return count;  } -ObjectFile::Strata -ObjectFileMachO::CalculateStrata() -{ -    switch (m_header.filetype) -    { -        case MH_OBJECT:                                  // 0x1u +lldb_private::Address ObjectFileMachO::GetEntryPointAddress() { +  // If the object file is not an executable it can't hold the entry point. +  // m_entry_point_address +  // is initialized to an invalid address, so we can just return that. +  // If m_entry_point_address is valid it means we've found it already, so +  // return the cached value. + +  if (!IsExecutable() || m_entry_point_address.IsValid()) +    return m_entry_point_address; + +  // Otherwise, look for the UnixThread or Thread command.  The data for the +  // Thread command is given in +  // /usr/include/mach-o.h, but it is basically: +  // +  //  uint32_t flavor  - this is the flavor argument you would pass to +  //  thread_get_state +  //  uint32_t count   - this is the count of longs in the thread state data +  //  struct XXX_thread_state state - this is the structure from +  //  <machine/thread_status.h> corresponding to the flavor. +  //  <repeat this trio> +  // +  // So we just keep reading the various register flavors till we find the GPR +  // one, then read the PC out of there. +  // FIXME: We will need to have a "RegisterContext data provider" class at some +  // point that can get all the registers +  // out of data in this form & attach them to a given thread.  That should +  // underlie the MacOS X User process plugin, +  // and we'll also need it for the MacOS X Core File process plugin.  When we +  // have that we can also use it here. +  // +  // For now we hard-code the offsets and flavors we need: +  // +  // + +  ModuleSP module_sp(GetModule()); +  if (module_sp) { +    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); +    struct load_command load_cmd; +    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); +    uint32_t i; +    lldb::addr_t start_address = LLDB_INVALID_ADDRESS; +    bool done = false; + +    for (i = 0; i < m_header.ncmds; ++i) { +      const lldb::offset_t cmd_offset = offset; +      if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) +        break; + +      switch (load_cmd.cmd) { +      case LC_UNIXTHREAD: +      case LC_THREAD: { +        while (offset < cmd_offset + load_cmd.cmdsize) { +          uint32_t flavor = m_data.GetU32(&offset); +          uint32_t count = m_data.GetU32(&offset); +          if (count == 0) { +            // We've gotten off somehow, log and exit; +            return m_entry_point_address; +          } + +          switch (m_header.cputype) { +          case llvm::MachO::CPU_TYPE_ARM: +            if (flavor == 1 || +                flavor == 9) // ARM_THREAD_STATE/ARM_THREAD_STATE32 from +                             // mach/arm/thread_status.h              { -                // 32 bit kexts are just object files, but they do have a valid -                // UUID load command. -                UUID uuid; -                if (GetUUID(&uuid)) -                { -                    // this checking for the UUID load command is not enough -                    // we could eventually look for the symbol named -                    // "OSKextGetCurrentIdentifier" as this is required of kexts -                    if (m_type == eTypeInvalid) -                        m_type = eTypeSharedLibrary; - -                    return eStrataKernel; -                } +              offset += 60; // This is the offset of pc in the GPR thread state +                            // data structure. +              start_address = m_data.GetU32(&offset); +              done = true;              } -            return eStrataUnknown; - -        case MH_EXECUTE:                                 // 0x2u -            // Check for the MH_DYLDLINK bit in the flags -            if (m_header.flags & MH_DYLDLINK) +            break; +          case llvm::MachO::CPU_TYPE_ARM64: +            if (flavor == 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h              { -                return eStrataUser; +              offset += 256; // This is the offset of pc in the GPR thread state +                             // data structure. +              start_address = m_data.GetU64(&offset); +              done = true;              } -            else +            break; +          case llvm::MachO::CPU_TYPE_I386: +            if (flavor == +                1) // x86_THREAD_STATE32 from mach/i386/thread_status.h              { -                SectionList *section_list = GetSectionList(); -                if (section_list) -                { -                    static ConstString g_kld_section_name ("__KLD"); -                    if (section_list->FindSectionByName(g_kld_section_name)) -                        return eStrataKernel; -                } +              offset += 40; // This is the offset of eip in the GPR thread state +                            // data structure. +              start_address = m_data.GetU32(&offset); +              done = true;              } -            return eStrataRawImage; - -        case MH_FVMLIB:      return eStrataUser;         // 0x3u -        case MH_CORE:        return eStrataUnknown;      // 0x4u -        case MH_PRELOAD:     return eStrataRawImage;     // 0x5u -        case MH_DYLIB:       return eStrataUser;         // 0x6u -        case MH_DYLINKER:    return eStrataUser;         // 0x7u -        case MH_BUNDLE:      return eStrataUser;         // 0x8u -        case MH_DYLIB_STUB:  return eStrataUser;         // 0x9u -        case MH_DSYM:        return eStrataUnknown;      // 0xAu -        case MH_KEXT_BUNDLE: return eStrataKernel;       // 0xBu -        default:              break; +          case llvm::MachO::CPU_TYPE_X86_64: +            if (flavor == +                4) // x86_THREAD_STATE64 from mach/i386/thread_status.h +            { +              offset += 16 * 8; // This is the offset of rip in the GPR thread +                                // state data structure. +              start_address = m_data.GetU64(&offset); +              done = true; +            } +            break; +          default: +            return m_entry_point_address; +          } +          // Haven't found the GPR flavor yet, skip over the data for this +          // flavor: +          if (done) +            break; +          offset += count * 4; +        } +      } break; +      case LC_MAIN: { +        ConstString text_segment_name("__TEXT"); +        uint64_t entryoffset = m_data.GetU64(&offset); +        SectionSP text_segment_sp = +            GetSectionList()->FindSectionByName(text_segment_name); +        if (text_segment_sp) { +          done = true; +          start_address = text_segment_sp->GetFileAddress() + entryoffset; +        } +      } break; + +      default: +        break; +      } +      if (done) +        break; + +      // Go to the next load command: +      offset = cmd_offset + load_cmd.cmdsize;      } -    return eStrataUnknown; + +    if (start_address != LLDB_INVALID_ADDRESS) { +      // We got the start address from the load commands, so now resolve that +      // address in the sections +      // of this ObjectFile: +      if (!m_entry_point_address.ResolveAddressUsingFileSections( +              start_address, GetSectionList())) { +        m_entry_point_address.Clear(); +      } +    } else { +      // We couldn't read the UnixThread load command - maybe it wasn't there. +      // As a fallback look for the +      // "start" symbol in the main executable. + +      ModuleSP module_sp(GetModule()); + +      if (module_sp) { +        SymbolContextList contexts; +        SymbolContext context; +        if (module_sp->FindSymbolsWithNameAndType(ConstString("start"), +                                                  eSymbolTypeCode, contexts)) { +          if (contexts.GetContextAtIndex(0, context)) +            m_entry_point_address = context.symbol->GetAddress(); +        } +      } +    } +  } + +  return m_entry_point_address;  } -uint32_t -ObjectFileMachO::GetVersion (uint32_t *versions, uint32_t num_versions) -{ -    ModuleSP module_sp(GetModule()); -    if (module_sp) -    { -        std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); -        struct dylib_command load_cmd; -        lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); -        uint32_t version_cmd = 0; -        uint64_t version = 0; -        uint32_t i; -        for (i=0; i<m_header.ncmds; ++i) -        { -            const lldb::offset_t cmd_offset = offset; -            if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) -                break; +lldb_private::Address ObjectFileMachO::GetHeaderAddress() { +  lldb_private::Address header_addr; +  SectionList *section_list = GetSectionList(); +  if (section_list) { +    SectionSP text_segment_sp( +        section_list->FindSectionByName(GetSegmentNameTEXT())); +    if (text_segment_sp) { +      header_addr.SetSection(text_segment_sp); +      header_addr.SetOffset(0); +    } +  } +  return header_addr; +} -            if (load_cmd.cmd == LC_ID_DYLIB) -            { -                if (version_cmd == 0) -                { -                    version_cmd = load_cmd.cmd; -                    if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL) -                        break; -                    version = load_cmd.dylib.current_version; -                } -                break; // Break for now unless there is another more complete version -                       // number load command in the future. -            } -            offset = cmd_offset + load_cmd.cmdsize; +uint32_t ObjectFileMachO::GetNumThreadContexts() { +  ModuleSP module_sp(GetModule()); +  if (module_sp) { +    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); +    if (!m_thread_context_offsets_valid) { +      m_thread_context_offsets_valid = true; +      lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); +      FileRangeArray::Entry file_range; +      thread_command thread_cmd; +      for (uint32_t i = 0; i < m_header.ncmds; ++i) { +        const uint32_t cmd_offset = offset; +        if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL) +          break; + +        if (thread_cmd.cmd == LC_THREAD) { +          file_range.SetRangeBase(offset); +          file_range.SetByteSize(thread_cmd.cmdsize - 8); +          m_thread_context_offsets.Append(file_range);          } +        offset = cmd_offset + thread_cmd.cmdsize; +      } +    } +  } +  return m_thread_context_offsets.GetSize(); +} -        if (version_cmd == LC_ID_DYLIB) -        { -            if (versions != NULL && num_versions > 0) -            { -                if (num_versions > 0) -                    versions[0] = (version & 0xFFFF0000ull) >> 16; -                if (num_versions > 1) -                    versions[1] = (version & 0x0000FF00ull) >> 8; -                if (num_versions > 2) -                    versions[2] = (version & 0x000000FFull); -                // Fill in an remaining version numbers with invalid values -                for (i=3; i<num_versions; ++i) -                    versions[i] = UINT32_MAX; -            } -            // The LC_ID_DYLIB load command has a version with 3 version numbers -            // in it, so always return 3 -            return 3; -        } +lldb::RegisterContextSP +ObjectFileMachO::GetThreadContextAtIndex(uint32_t idx, +                                         lldb_private::Thread &thread) { +  lldb::RegisterContextSP reg_ctx_sp; + +  ModuleSP module_sp(GetModule()); +  if (module_sp) { +    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); +    if (!m_thread_context_offsets_valid) +      GetNumThreadContexts(); + +    const FileRangeArray::Entry *thread_context_file_range = +        m_thread_context_offsets.GetEntryAtIndex(idx); +    if (thread_context_file_range) { + +      DataExtractor data(m_data, thread_context_file_range->GetRangeBase(), +                         thread_context_file_range->GetByteSize()); + +      switch (m_header.cputype) { +      case llvm::MachO::CPU_TYPE_ARM64: +        reg_ctx_sp.reset(new RegisterContextDarwin_arm64_Mach(thread, data)); +        break; + +      case llvm::MachO::CPU_TYPE_ARM: +        reg_ctx_sp.reset(new RegisterContextDarwin_arm_Mach(thread, data)); +        break; + +      case llvm::MachO::CPU_TYPE_I386: +        reg_ctx_sp.reset(new RegisterContextDarwin_i386_Mach(thread, data)); +        break; + +      case llvm::MachO::CPU_TYPE_X86_64: +        reg_ctx_sp.reset(new RegisterContextDarwin_x86_64_Mach(thread, data)); +        break; +      }      } -    return false; +  } +  return reg_ctx_sp;  } -bool -ObjectFileMachO::GetArchitecture (ArchSpec &arch) -{ -    ModuleSP module_sp(GetModule()); -    if (module_sp) -    { -        std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); -        return GetArchitecture (m_header, m_data, MachHeaderSizeFromMagic(m_header.magic), arch); +ObjectFile::Type ObjectFileMachO::CalculateType() { +  switch (m_header.filetype) { +  case MH_OBJECT: // 0x1u +    if (GetAddressByteSize() == 4) { +      // 32 bit kexts are just object files, but they do have a valid +      // UUID load command. +      UUID uuid; +      if (GetUUID(&uuid)) { +        // this checking for the UUID load command is not enough +        // we could eventually look for the symbol named +        // "OSKextGetCurrentIdentifier" as this is required of kexts +        if (m_strata == eStrataInvalid) +          m_strata = eStrataKernel; +        return eTypeSharedLibrary; +      }      } -    return false; +    return eTypeObjectFile; + +  case MH_EXECUTE: +    return eTypeExecutable; // 0x2u +  case MH_FVMLIB: +    return eTypeSharedLibrary; // 0x3u +  case MH_CORE: +    return eTypeCoreFile; // 0x4u +  case MH_PRELOAD: +    return eTypeSharedLibrary; // 0x5u +  case MH_DYLIB: +    return eTypeSharedLibrary; // 0x6u +  case MH_DYLINKER: +    return eTypeDynamicLinker; // 0x7u +  case MH_BUNDLE: +    return eTypeSharedLibrary; // 0x8u +  case MH_DYLIB_STUB: +    return eTypeStubLibrary; // 0x9u +  case MH_DSYM: +    return eTypeDebugInfo; // 0xAu +  case MH_KEXT_BUNDLE: +    return eTypeSharedLibrary; // 0xBu +  default: +    break; +  } +  return eTypeUnknown;  } -UUID -ObjectFileMachO::GetProcessSharedCacheUUID (Process *process) -{ +ObjectFile::Strata ObjectFileMachO::CalculateStrata() { +  switch (m_header.filetype) { +  case MH_OBJECT: // 0x1u +  { +    // 32 bit kexts are just object files, but they do have a valid +    // UUID load command.      UUID uuid; -    if (process) -    { -        addr_t all_image_infos = process->GetImageInfoAddress(); - -        // The address returned by GetImageInfoAddress may be the address of dyld (don't want) -        // or it may be the address of the dyld_all_image_infos structure (want).  The first four -        // bytes will be either the version field (all_image_infos) or a Mach-O file magic constant. -        // Version 13 and higher of dyld_all_image_infos is required to get the sharedCacheUUID field. - -        Error err; -        uint32_t version_or_magic = process->ReadUnsignedIntegerFromMemory (all_image_infos, 4, -1, err); -        if (version_or_magic != static_cast<uint32_t>(-1) -            && version_or_magic != MH_MAGIC -            && version_or_magic != MH_CIGAM -            && version_or_magic != MH_MAGIC_64 -            && version_or_magic != MH_CIGAM_64 -            && version_or_magic >= 13) -        { -            addr_t sharedCacheUUID_address = LLDB_INVALID_ADDRESS; -            int wordsize = process->GetAddressByteSize(); -            if (wordsize == 8) -            { -                sharedCacheUUID_address = all_image_infos + 160;  // sharedCacheUUID <mach-o/dyld_images.h> -            } -            if (wordsize == 4) -            { -                sharedCacheUUID_address = all_image_infos + 84;   // sharedCacheUUID <mach-o/dyld_images.h> -            } -            if (sharedCacheUUID_address != LLDB_INVALID_ADDRESS) -            { -                uuid_t shared_cache_uuid; -                if (process->ReadMemory (sharedCacheUUID_address, shared_cache_uuid, sizeof (uuid_t), err) == sizeof (uuid_t)) -                { -                    uuid.SetBytes (shared_cache_uuid); -                } -            } +    if (GetUUID(&uuid)) { +      // this checking for the UUID load command is not enough +      // we could eventually look for the symbol named +      // "OSKextGetCurrentIdentifier" as this is required of kexts +      if (m_type == eTypeInvalid) +        m_type = eTypeSharedLibrary; + +      return eStrataKernel; +    } +  } +    return eStrataUnknown; + +  case MH_EXECUTE: // 0x2u +    // Check for the MH_DYLDLINK bit in the flags +    if (m_header.flags & MH_DYLDLINK) { +      return eStrataUser; +    } else { +      SectionList *section_list = GetSectionList(); +      if (section_list) { +        static ConstString g_kld_section_name("__KLD"); +        if (section_list->FindSectionByName(g_kld_section_name)) +          return eStrataKernel; +      } +    } +    return eStrataRawImage; + +  case MH_FVMLIB: +    return eStrataUser; // 0x3u +  case MH_CORE: +    return eStrataUnknown; // 0x4u +  case MH_PRELOAD: +    return eStrataRawImage; // 0x5u +  case MH_DYLIB: +    return eStrataUser; // 0x6u +  case MH_DYLINKER: +    return eStrataUser; // 0x7u +  case MH_BUNDLE: +    return eStrataUser; // 0x8u +  case MH_DYLIB_STUB: +    return eStrataUser; // 0x9u +  case MH_DSYM: +    return eStrataUnknown; // 0xAu +  case MH_KEXT_BUNDLE: +    return eStrataKernel; // 0xBu +  default: +    break; +  } +  return eStrataUnknown; +} + +uint32_t ObjectFileMachO::GetVersion(uint32_t *versions, +                                     uint32_t num_versions) { +  ModuleSP module_sp(GetModule()); +  if (module_sp) { +    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); +    struct dylib_command load_cmd; +    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); +    uint32_t version_cmd = 0; +    uint64_t version = 0; +    uint32_t i; +    for (i = 0; i < m_header.ncmds; ++i) { +      const lldb::offset_t cmd_offset = offset; +      if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) +        break; + +      if (load_cmd.cmd == LC_ID_DYLIB) { +        if (version_cmd == 0) { +          version_cmd = load_cmd.cmd; +          if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == NULL) +            break; +          version = load_cmd.dylib.current_version;          } +        break; // Break for now unless there is another more complete version +               // number load command in the future. +      } +      offset = cmd_offset + load_cmd.cmdsize; +    } + +    if (version_cmd == LC_ID_DYLIB) { +      if (versions != NULL && num_versions > 0) { +        if (num_versions > 0) +          versions[0] = (version & 0xFFFF0000ull) >> 16; +        if (num_versions > 1) +          versions[1] = (version & 0x0000FF00ull) >> 8; +        if (num_versions > 2) +          versions[2] = (version & 0x000000FFull); +        // Fill in an remaining version numbers with invalid values +        for (i = 3; i < num_versions; ++i) +          versions[i] = UINT32_MAX; +      } +      // The LC_ID_DYLIB load command has a version with 3 version numbers +      // in it, so always return 3 +      return 3;      } -    return uuid; +  } +  return false;  } -UUID -ObjectFileMachO::GetLLDBSharedCacheUUID () -{ -    UUID uuid; -#if defined (__APPLE__) && (defined (__arm__) || defined (__arm64__) || defined (__aarch64__)) -    uint8_t *(*dyld_get_all_image_infos)(void); -    dyld_get_all_image_infos = (uint8_t*(*)()) dlsym (RTLD_DEFAULT, "_dyld_get_all_image_infos"); -    if (dyld_get_all_image_infos) -    { -        uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos(); -        if (dyld_all_image_infos_address) -        { -            uint32_t *version = (uint32_t*) dyld_all_image_infos_address;              // version <mach-o/dyld_images.h> -            if (*version >= 13) -            { -                uuid_t *sharedCacheUUID_address = 0; -                int wordsize = sizeof (uint8_t *); -                if (wordsize == 8) -                { -                    sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 160); // sharedCacheUUID <mach-o/dyld_images.h> -                } -                else -                { -                    sharedCacheUUID_address = (uuid_t*) ((uint8_t*) dyld_all_image_infos_address + 84);  // sharedCacheUUID <mach-o/dyld_images.h> -                } -                uuid.SetBytes (sharedCacheUUID_address); -            } +bool ObjectFileMachO::GetArchitecture(ArchSpec &arch) { +  ModuleSP module_sp(GetModule()); +  if (module_sp) { +    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); +    return GetArchitecture(m_header, m_data, +                           MachHeaderSizeFromMagic(m_header.magic), arch); +  } +  return false; +} + +UUID ObjectFileMachO::GetProcessSharedCacheUUID(Process *process) { +  UUID uuid; +  if (process && process->GetDynamicLoader()) { +    DynamicLoader *dl = process->GetDynamicLoader(); +    addr_t load_address; +    LazyBool using_shared_cache; +    LazyBool private_shared_cache; +    dl->GetSharedCacheInformation(load_address, uuid, using_shared_cache, +                                  private_shared_cache); +  } +  return uuid; +} + +UUID ObjectFileMachO::GetLLDBSharedCacheUUID() { +  UUID uuid; +#if defined(__APPLE__) &&                                                      \ +    (defined(__arm__) || defined(__arm64__) || defined(__aarch64__)) +  uint8_t *(*dyld_get_all_image_infos)(void); +  dyld_get_all_image_infos = +      (uint8_t * (*)())dlsym(RTLD_DEFAULT, "_dyld_get_all_image_infos"); +  if (dyld_get_all_image_infos) { +    uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos(); +    if (dyld_all_image_infos_address) { +      uint32_t *version = (uint32_t *) +          dyld_all_image_infos_address; // version <mach-o/dyld_images.h> +      if (*version >= 13) { +        uuid_t *sharedCacheUUID_address = 0; +        int wordsize = sizeof(uint8_t *); +        if (wordsize == 8) { +          sharedCacheUUID_address = +              (uuid_t *)((uint8_t *)dyld_all_image_infos_address + +                         160); // sharedCacheUUID <mach-o/dyld_images.h> +        } else { +          sharedCacheUUID_address = +              (uuid_t *)((uint8_t *)dyld_all_image_infos_address + +                         84); // sharedCacheUUID <mach-o/dyld_images.h>          } +        uuid.SetBytes(sharedCacheUUID_address); +      }      } +  }  #endif -    return uuid; +  return uuid;  } -uint32_t -ObjectFileMachO::GetMinimumOSVersion (uint32_t *versions, uint32_t num_versions) -{ -    if (m_min_os_versions.empty()) -    { -        lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); -        bool success = false; -        for (uint32_t i=0; success == false && i < m_header.ncmds; ++i) -        { -            const lldb::offset_t load_cmd_offset = offset; -             -            version_min_command lc; -            if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL) -                break; -            if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX  -                 || lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS  -                 || lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS  -                 || lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) -            { -                if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2)) -                { -                    const uint32_t xxxx = lc.version >> 16; -                    const uint32_t yy = (lc.version >> 8) & 0xffu; -                    const uint32_t zz = lc.version  & 0xffu; -                    if (xxxx) -                    { -                        m_min_os_versions.push_back(xxxx); -                        m_min_os_versions.push_back(yy); -                        m_min_os_versions.push_back(zz); -                    } -                    success = true; -                } -            } -            offset = load_cmd_offset + lc.cmdsize; -        } -         -        if (success == false) -        { -            // Push an invalid value so we don't keep trying to -            m_min_os_versions.push_back(UINT32_MAX); +uint32_t ObjectFileMachO::GetMinimumOSVersion(uint32_t *versions, +                                              uint32_t num_versions) { +  if (m_min_os_versions.empty()) { +    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); +    bool success = false; +    for (uint32_t i = 0; success == false && i < m_header.ncmds; ++i) { +      const lldb::offset_t load_cmd_offset = offset; + +      version_min_command lc; +      if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL) +        break; +      if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX || +          lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS || +          lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS || +          lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) { +        if (m_data.GetU32(&offset, &lc.version, +                          (sizeof(lc) / sizeof(uint32_t)) - 2)) { +          const uint32_t xxxx = lc.version >> 16; +          const uint32_t yy = (lc.version >> 8) & 0xffu; +          const uint32_t zz = lc.version & 0xffu; +          if (xxxx) { +            m_min_os_versions.push_back(xxxx); +            m_min_os_versions.push_back(yy); +            m_min_os_versions.push_back(zz); +          } +          success = true;          } +      } +      offset = load_cmd_offset + lc.cmdsize;      } -     -    if (m_min_os_versions.size() > 1 || m_min_os_versions[0] != UINT32_MAX) -    { -        if (versions != NULL && num_versions > 0) -        { -            for (size_t i=0; i<num_versions; ++i) -            { -                if (i < m_min_os_versions.size()) -                    versions[i] = m_min_os_versions[i]; -                else -                    versions[i] = 0; -            } -        } -        return m_min_os_versions.size(); + +    if (success == false) { +      // Push an invalid value so we don't keep trying to +      m_min_os_versions.push_back(UINT32_MAX); +    } +  } + +  if (m_min_os_versions.size() > 1 || m_min_os_versions[0] != UINT32_MAX) { +    if (versions != NULL && num_versions > 0) { +      for (size_t i = 0; i < num_versions; ++i) { +        if (i < m_min_os_versions.size()) +          versions[i] = m_min_os_versions[i]; +        else +          versions[i] = 0; +      }      } -    // Call the superclasses version that will empty out the data -    return ObjectFile::GetMinimumOSVersion (versions, num_versions); +    return m_min_os_versions.size(); +  } +  // Call the superclasses version that will empty out the data +  return ObjectFile::GetMinimumOSVersion(versions, num_versions);  } -uint32_t -ObjectFileMachO::GetSDKVersion(uint32_t *versions, uint32_t num_versions) -{ -    if (m_sdk_versions.empty()) -    { -        lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); -        bool success = false; -        for (uint32_t i=0; success == false && i < m_header.ncmds; ++i) -        { -            const lldb::offset_t load_cmd_offset = offset; -             -            version_min_command lc; -            if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL) -                break; -            if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX  -                || lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS -                || lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS -                || lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) -            { -                if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2)) -                { -                    const uint32_t xxxx = lc.sdk >> 16; -                    const uint32_t yy = (lc.sdk >> 8) & 0xffu; -                    const uint32_t zz = lc.sdk & 0xffu; -                    if (xxxx) -                    { -                        m_sdk_versions.push_back(xxxx); -                        m_sdk_versions.push_back(yy); -                        m_sdk_versions.push_back(zz); -                    } -                    success = true; -                } -            } -            offset = load_cmd_offset + lc.cmdsize; -        } -         -        if (success == false) -        { -            // Push an invalid value so we don't keep trying to -            m_sdk_versions.push_back(UINT32_MAX); +uint32_t ObjectFileMachO::GetSDKVersion(uint32_t *versions, +                                        uint32_t num_versions) { +  if (m_sdk_versions.empty()) { +    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); +    bool success = false; +    for (uint32_t i = 0; success == false && i < m_header.ncmds; ++i) { +      const lldb::offset_t load_cmd_offset = offset; + +      version_min_command lc; +      if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL) +        break; +      if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX || +          lc.cmd == llvm::MachO::LC_VERSION_MIN_IPHONEOS || +          lc.cmd == llvm::MachO::LC_VERSION_MIN_TVOS || +          lc.cmd == llvm::MachO::LC_VERSION_MIN_WATCHOS) { +        if (m_data.GetU32(&offset, &lc.version, +                          (sizeof(lc) / sizeof(uint32_t)) - 2)) { +          const uint32_t xxxx = lc.sdk >> 16; +          const uint32_t yy = (lc.sdk >> 8) & 0xffu; +          const uint32_t zz = lc.sdk & 0xffu; +          if (xxxx) { +            m_sdk_versions.push_back(xxxx); +            m_sdk_versions.push_back(yy); +            m_sdk_versions.push_back(zz); +          } +          success = true;          } +      } +      offset = load_cmd_offset + lc.cmdsize;      } -     -    if (m_sdk_versions.size() > 1 || m_sdk_versions[0] != UINT32_MAX) -    { -        if (versions != NULL && num_versions > 0) -        { -            for (size_t i=0; i<num_versions; ++i) -            { -                if (i < m_sdk_versions.size()) -                    versions[i] = m_sdk_versions[i]; -                else -                    versions[i] = 0; -            } -        } -        return m_sdk_versions.size(); + +    if (success == false) { +      // Push an invalid value so we don't keep trying to +      m_sdk_versions.push_back(UINT32_MAX);      } -    // Call the superclasses version that will empty out the data -    return ObjectFile::GetSDKVersion (versions, num_versions); +  } + +  if (m_sdk_versions.size() > 1 || m_sdk_versions[0] != UINT32_MAX) { +    if (versions != NULL && num_versions > 0) { +      for (size_t i = 0; i < num_versions; ++i) { +        if (i < m_sdk_versions.size()) +          versions[i] = m_sdk_versions[i]; +        else +          versions[i] = 0; +      } +    } +    return m_sdk_versions.size(); +  } +  // Call the superclasses version that will empty out the data +  return ObjectFile::GetSDKVersion(versions, num_versions);  } -bool -ObjectFileMachO::GetIsDynamicLinkEditor() -{ -    return m_header.filetype == llvm::MachO::MH_DYLINKER; +bool ObjectFileMachO::GetIsDynamicLinkEditor() { +  return m_header.filetype == llvm::MachO::MH_DYLINKER;  } -bool -ObjectFileMachO::AllowAssemblyEmulationUnwindPlans () -{ -    return m_allow_assembly_emulation_unwind_plans; +bool ObjectFileMachO::AllowAssemblyEmulationUnwindPlans() { +  return m_allow_assembly_emulation_unwind_plans;  }  //------------------------------------------------------------------  // PluginInterface protocol  //------------------------------------------------------------------ -lldb_private::ConstString -ObjectFileMachO::GetPluginName() -{ -    return GetPluginNameStatic(); +lldb_private::ConstString ObjectFileMachO::GetPluginName() { +  return GetPluginNameStatic();  } -uint32_t -ObjectFileMachO::GetPluginVersion() -{ -    return 1; -} +uint32_t ObjectFileMachO::GetPluginVersion() { return 1; } -Section * -ObjectFileMachO::GetMachHeaderSection() -{ -    // Find the first address of the mach header which is the first non-zero -    // file sized section whose file offset is zero. This is the base file address -    // of the mach-o file which can be subtracted from the vmaddr of the other -    // segments found in memory and added to the load address -    ModuleSP module_sp = GetModule(); -    if (module_sp) -    { -        SectionList *section_list = GetSectionList (); -        if (section_list) -        { -            lldb::addr_t mach_base_file_addr = LLDB_INVALID_ADDRESS; -            const size_t num_sections = section_list->GetSize(); - -            for (size_t sect_idx = 0; -                 sect_idx < num_sections && mach_base_file_addr == LLDB_INVALID_ADDRESS; -                 ++sect_idx) -            { -                Section *section = section_list->GetSectionAtIndex (sect_idx).get(); -                if (section && -                    section->GetFileSize() > 0 && -                    section->GetFileOffset() == 0 && -                    section->IsThreadSpecific() == false && -                    module_sp.get() == section->GetModule().get()) -                { -                    return section; -                } -            } +Section *ObjectFileMachO::GetMachHeaderSection() { +  // Find the first address of the mach header which is the first non-zero +  // file sized section whose file offset is zero. This is the base file address +  // of the mach-o file which can be subtracted from the vmaddr of the other +  // segments found in memory and added to the load address +  ModuleSP module_sp = GetModule(); +  if (module_sp) { +    SectionList *section_list = GetSectionList(); +    if (section_list) { +      lldb::addr_t mach_base_file_addr = LLDB_INVALID_ADDRESS; +      const size_t num_sections = section_list->GetSize(); + +      for (size_t sect_idx = 0; sect_idx < num_sections && +                                mach_base_file_addr == LLDB_INVALID_ADDRESS; +           ++sect_idx) { +        Section *section = section_list->GetSectionAtIndex(sect_idx).get(); +        if (section && section->GetFileSize() > 0 && +            section->GetFileOffset() == 0 && +            section->IsThreadSpecific() == false && +            module_sp.get() == section->GetModule().get()) { +          return section;          } +      }      } -    return nullptr; +  } +  return nullptr;  } -lldb::addr_t -ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage(lldb::addr_t mach_header_load_address, const Section *mach_header_section, const Section *section) -{ -    ModuleSP module_sp = GetModule(); -    if (module_sp && mach_header_section && section && mach_header_load_address != LLDB_INVALID_ADDRESS) -    { -        lldb::addr_t mach_header_file_addr = mach_header_section->GetFileAddress(); -        if (mach_header_file_addr != LLDB_INVALID_ADDRESS) -        { -            if (section && -                section->GetFileSize() > 0 && -                section->IsThreadSpecific() == false && -                module_sp.get() == section->GetModule().get()) -            { -                // Ignore __LINKEDIT and __DWARF segments -                if (section->GetName() == GetSegmentNameLINKEDIT()) -                { -                    // Only map __LINKEDIT if we have an in memory image and this isn't -                    // a kernel binary like a kext or mach_kernel. -                    const bool is_memory_image = (bool)m_process_wp.lock(); -                    const Strata strata = GetStrata(); -                    if (is_memory_image == false || strata == eStrataKernel) -                        return LLDB_INVALID_ADDRESS; -                } -                return section->GetFileAddress() - mach_header_file_addr + mach_header_load_address; -            } +lldb::addr_t ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage( +    lldb::addr_t mach_header_load_address, const Section *mach_header_section, +    const Section *section) { +  ModuleSP module_sp = GetModule(); +  if (module_sp && mach_header_section && section && +      mach_header_load_address != LLDB_INVALID_ADDRESS) { +    lldb::addr_t mach_header_file_addr = mach_header_section->GetFileAddress(); +    if (mach_header_file_addr != LLDB_INVALID_ADDRESS) { +      if (section && section->GetFileSize() > 0 && +          section->IsThreadSpecific() == false && +          module_sp.get() == section->GetModule().get()) { +        // Ignore __LINKEDIT and __DWARF segments +        if (section->GetName() == GetSegmentNameLINKEDIT()) { +          // Only map __LINKEDIT if we have an in memory image and this isn't +          // a kernel binary like a kext or mach_kernel. +          const bool is_memory_image = (bool)m_process_wp.lock(); +          const Strata strata = GetStrata(); +          if (is_memory_image == false || strata == eStrataKernel) +            return LLDB_INVALID_ADDRESS;          } +        return section->GetFileAddress() - mach_header_file_addr + +               mach_header_load_address; +      }      } -    return LLDB_INVALID_ADDRESS; +  } +  return LLDB_INVALID_ADDRESS;  } -bool -ObjectFileMachO::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) -        { -            const size_t num_sections = section_list->GetSize(); - -            if (value_is_offset) -            { -                // "value" is an offset to apply to each top level segment -                for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) -                { -                    // Iterate through the object file sections to find all -                    // of the sections that size on disk (to avoid __PAGEZERO) -                    // and load them -                    SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx)); -                    if (section_sp && -                        section_sp->GetFileSize() > 0 && -                        section_sp->IsThreadSpecific() == false && -                        module_sp.get() == section_sp->GetModule().get()) -                    { -                        // Ignore __LINKEDIT and __DWARF segments -                        if (section_sp->GetName() == GetSegmentNameLINKEDIT()) -                        { -                            // Only map __LINKEDIT if we have an in memory image and this isn't -                            // a kernel binary like a kext or mach_kernel. -                            const bool is_memory_image = (bool)m_process_wp.lock(); -                            const Strata strata = GetStrata(); -                            if (is_memory_image == false || strata == eStrataKernel) -                                continue; -                        } -                        if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + value)) -                            ++num_loaded_sections; -                    } -                } +bool ObjectFileMachO::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) { +      const size_t num_sections = section_list->GetSize(); + +      if (value_is_offset) { +        // "value" is an offset to apply to each top level segment +        for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) { +          // Iterate through the object file sections to find all +          // of the sections that size on disk (to avoid __PAGEZERO) +          // and load them +          SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx)); +          if (section_sp && section_sp->GetFileSize() > 0 && +              section_sp->IsThreadSpecific() == false && +              module_sp.get() == section_sp->GetModule().get()) { +            // Ignore __LINKEDIT and __DWARF segments +            if (section_sp->GetName() == GetSegmentNameLINKEDIT()) { +              // Only map __LINKEDIT if we have an in memory image and this +              // isn't +              // a kernel binary like a kext or mach_kernel. +              const bool is_memory_image = (bool)m_process_wp.lock(); +              const Strata strata = GetStrata(); +              if (is_memory_image == false || strata == eStrataKernel) +                continue;              } -            else -            { -                // "value" is the new base address of the mach_header, adjust each -                // section accordingly - -                Section *mach_header_section = GetMachHeaderSection(); -                if (mach_header_section) -                { -                    for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) -                    { -                        SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx)); - -                        lldb::addr_t section_load_addr = CalculateSectionLoadAddressForMemoryImage(value, mach_header_section, section_sp.get()); -                        if (section_load_addr != LLDB_INVALID_ADDRESS) -                        { -                            if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_load_addr)) -                                ++num_loaded_sections; -                        } -                    } -                } +            if (target.GetSectionLoadList().SetSectionLoadAddress( +                    section_sp, section_sp->GetFileAddress() + value)) +              ++num_loaded_sections; +          } +        } +      } else { +        // "value" is the new base address of the mach_header, adjust each +        // section accordingly + +        Section *mach_header_section = GetMachHeaderSection(); +        if (mach_header_section) { +          for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) { +            SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx)); + +            lldb::addr_t section_load_addr = +                CalculateSectionLoadAddressForMemoryImage( +                    value, mach_header_section, section_sp.get()); +            if (section_load_addr != LLDB_INVALID_ADDRESS) { +              if (target.GetSectionLoadList().SetSectionLoadAddress( +                      section_sp, section_load_addr)) +                ++num_loaded_sections;              } +          }          } -        return num_loaded_sections > 0; +      }      } -    return false; +    return num_loaded_sections > 0; +  } +  return false;  } -bool -ObjectFileMachO::SaveCore (const lldb::ProcessSP &process_sp, -                           const FileSpec &outfile, -                           Error &error) -{ -    if (process_sp) -    { -        Target &target = process_sp->GetTarget(); -        const ArchSpec target_arch = target.GetArchitecture(); -        const llvm::Triple &target_triple = target_arch.GetTriple(); -        if (target_triple.getVendor() == llvm::Triple::Apple && -            (target_triple.getOS() == llvm::Triple::MacOSX  -             || target_triple.getOS() == llvm::Triple::IOS -             || target_triple.getOS() == llvm::Triple::WatchOS -             || target_triple.getOS() == llvm::Triple::TvOS)) -        { -            bool make_core = false; -            switch (target_arch.GetMachine()) -            { -                case llvm::Triple::aarch64: -                case llvm::Triple::arm: -                case llvm::Triple::thumb: -                case llvm::Triple::x86: -                case llvm::Triple::x86_64: -                    make_core = true; -                    break; -                default: -                    error.SetErrorStringWithFormat ("unsupported core architecture: %s", target_triple.str().c_str()); -                    break; +bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp, +                               const FileSpec &outfile, Error &error) { +  if (process_sp) { +    Target &target = process_sp->GetTarget(); +    const ArchSpec target_arch = target.GetArchitecture(); +    const llvm::Triple &target_triple = target_arch.GetTriple(); +    if (target_triple.getVendor() == llvm::Triple::Apple && +        (target_triple.getOS() == llvm::Triple::MacOSX || +         target_triple.getOS() == llvm::Triple::IOS || +         target_triple.getOS() == llvm::Triple::WatchOS || +         target_triple.getOS() == llvm::Triple::TvOS)) { +      bool make_core = false; +      switch (target_arch.GetMachine()) { +      case llvm::Triple::aarch64: +      case llvm::Triple::arm: +      case llvm::Triple::thumb: +      case llvm::Triple::x86: +      case llvm::Triple::x86_64: +        make_core = true; +        break; +      default: +        error.SetErrorStringWithFormat("unsupported core architecture: %s", +                                       target_triple.str().c_str()); +        break; +      } + +      if (make_core) { +        std::vector<segment_command_64> segment_load_commands; +        //                uint32_t range_info_idx = 0; +        MemoryRegionInfo range_info; +        Error range_error = process_sp->GetMemoryRegionInfo(0, range_info); +        const uint32_t addr_byte_size = target_arch.GetAddressByteSize(); +        const ByteOrder byte_order = target_arch.GetByteOrder(); +        if (range_error.Success()) { +          while (range_info.GetRange().GetRangeBase() != LLDB_INVALID_ADDRESS) { +            const addr_t addr = range_info.GetRange().GetRangeBase(); +            const addr_t size = range_info.GetRange().GetByteSize(); + +            if (size == 0) +              break; + +            // Calculate correct protections +            uint32_t prot = 0; +            if (range_info.GetReadable() == MemoryRegionInfo::eYes) +              prot |= VM_PROT_READ; +            if (range_info.GetWritable() == MemoryRegionInfo::eYes) +              prot |= VM_PROT_WRITE; +            if (range_info.GetExecutable() == MemoryRegionInfo::eYes) +              prot |= VM_PROT_EXECUTE; + +            //                        printf ("[%3u] [0x%16.16" PRIx64 " - +            //                        0x%16.16" PRIx64 ") %c%c%c\n", +            //                                range_info_idx, +            //                                addr, +            //                                size, +            //                                (prot & VM_PROT_READ   ) ? 'r' : +            //                                '-', +            //                                (prot & VM_PROT_WRITE  ) ? 'w' : +            //                                '-', +            //                                (prot & VM_PROT_EXECUTE) ? 'x' : +            //                                '-'); + +            if (prot != 0) { +              uint32_t cmd_type = LC_SEGMENT_64; +              uint32_t segment_size = sizeof(segment_command_64); +              if (addr_byte_size == 4) { +                cmd_type = LC_SEGMENT; +                segment_size = sizeof(segment_command); +              } +              segment_command_64 segment = { +                  cmd_type,     // uint32_t cmd; +                  segment_size, // uint32_t cmdsize; +                  {0},          // char segname[16]; +                  addr, // uint64_t vmaddr;    // uint32_t for 32-bit Mach-O +                  size, // uint64_t vmsize;    // uint32_t for 32-bit Mach-O +                  0,    // uint64_t fileoff;   // uint32_t for 32-bit Mach-O +                  size, // uint64_t filesize;  // uint32_t for 32-bit Mach-O +                  prot, // uint32_t maxprot; +                  prot, // uint32_t initprot; +                  0,    // uint32_t nsects; +                  0};   // uint32_t flags; +              segment_load_commands.push_back(segment); +            } else { +              // No protections and a size of 1 used to be returned from old +              // debugservers when we asked about a region that was past the +              // last memory region and it indicates the end... +              if (size == 1) +                break;              } -             -            if (make_core) -            { -                std::vector<segment_command_64> segment_load_commands; -//                uint32_t range_info_idx = 0; -                MemoryRegionInfo range_info; -                Error range_error = process_sp->GetMemoryRegionInfo(0, range_info); -                const uint32_t addr_byte_size = target_arch.GetAddressByteSize(); -                const ByteOrder byte_order = target_arch.GetByteOrder(); -                if (range_error.Success()) -                { -                    while (range_info.GetRange().GetRangeBase() != LLDB_INVALID_ADDRESS) -                    { -                        const addr_t addr = range_info.GetRange().GetRangeBase(); -                        const addr_t size = range_info.GetRange().GetByteSize(); -                        if (size == 0) -                            break; - -                        // Calculate correct protections -                        uint32_t prot = 0; -                        if (range_info.GetReadable() == MemoryRegionInfo::eYes) -                            prot |= VM_PROT_READ; -                        if (range_info.GetWritable() == MemoryRegionInfo::eYes) -                            prot |= VM_PROT_WRITE; -                        if (range_info.GetExecutable() == MemoryRegionInfo::eYes) -                            prot |= VM_PROT_EXECUTE; - -//                        printf ("[%3u] [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") %c%c%c\n", -//                                range_info_idx, -//                                addr, -//                                size, -//                                (prot & VM_PROT_READ   ) ? 'r' : '-', -//                                (prot & VM_PROT_WRITE  ) ? 'w' : '-', -//                                (prot & VM_PROT_EXECUTE) ? 'x' : '-'); - -                        if (prot != 0) -                        { -                            uint32_t cmd_type = LC_SEGMENT_64; -                            uint32_t segment_size = sizeof (segment_command_64); -                            if (addr_byte_size == 4) -                            { -                                cmd_type = LC_SEGMENT; -                                segment_size = sizeof (segment_command); -                            } -                            segment_command_64 segment = { -                                cmd_type,           // uint32_t cmd; -                                segment_size,       // uint32_t cmdsize; -                                {0},                // char segname[16]; -                                addr,               // uint64_t vmaddr;    // uint32_t for 32-bit Mach-O -                                size,               // uint64_t vmsize;    // uint32_t for 32-bit Mach-O -                                0,                  // uint64_t fileoff;   // uint32_t for 32-bit Mach-O -                                size,               // uint64_t filesize;  // uint32_t for 32-bit Mach-O -                                prot,               // uint32_t maxprot; -                                prot,               // uint32_t initprot; -                                0,                  // uint32_t nsects; -                                0 };                // uint32_t flags; -                            segment_load_commands.push_back(segment); -                        } -                        else -                        { -                            // No protections and a size of 1 used to be returned from old -                            // debugservers when we asked about a region that was past the -                            // last memory region and it indicates the end... -                            if (size == 1) -                                break; -                        } -                         -                        range_error = process_sp->GetMemoryRegionInfo(range_info.GetRange().GetRangeEnd(), range_info); -                        if (range_error.Fail()) -                            break; -                    } -                     -                    StreamString buffer (Stream::eBinary, -                                         addr_byte_size, -                                         byte_order); +            range_error = process_sp->GetMemoryRegionInfo( +                range_info.GetRange().GetRangeEnd(), range_info); +            if (range_error.Fail()) +              break; +          } + +          StreamString buffer(Stream::eBinary, addr_byte_size, byte_order); + +          mach_header_64 mach_header; +          if (addr_byte_size == 8) { +            mach_header.magic = MH_MAGIC_64; +          } else { +            mach_header.magic = MH_MAGIC; +          } +          mach_header.cputype = target_arch.GetMachOCPUType(); +          mach_header.cpusubtype = target_arch.GetMachOCPUSubType(); +          mach_header.filetype = MH_CORE; +          mach_header.ncmds = segment_load_commands.size(); +          mach_header.flags = 0; +          mach_header.reserved = 0; +          ThreadList &thread_list = process_sp->GetThreadList(); +          const uint32_t num_threads = thread_list.GetSize(); + +          // Make an array of LC_THREAD data items. Each one contains +          // the contents of the LC_THREAD load command. The data doesn't +          // contain the load command + load command size, we will +          // add the load command and load command size as we emit the data. +          std::vector<StreamString> LC_THREAD_datas(num_threads); +          for (auto &LC_THREAD_data : LC_THREAD_datas) { +            LC_THREAD_data.GetFlags().Set(Stream::eBinary); +            LC_THREAD_data.SetAddressByteSize(addr_byte_size); +            LC_THREAD_data.SetByteOrder(byte_order); +          } +          for (uint32_t thread_idx = 0; thread_idx < num_threads; +               ++thread_idx) { +            ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx)); +            if (thread_sp) { +              switch (mach_header.cputype) { +              case llvm::MachO::CPU_TYPE_ARM64: +                RegisterContextDarwin_arm64_Mach::Create_LC_THREAD( +                    thread_sp.get(), LC_THREAD_datas[thread_idx]); +                break; -                    mach_header_64 mach_header; -                    if (addr_byte_size == 8) -                    { -                        mach_header.magic = MH_MAGIC_64; -                    } -                    else -                    { -                        mach_header.magic = MH_MAGIC; -                    } -                    mach_header.cputype = target_arch.GetMachOCPUType(); -                    mach_header.cpusubtype = target_arch.GetMachOCPUSubType(); -                    mach_header.filetype = MH_CORE; -                    mach_header.ncmds = segment_load_commands.size(); -                    mach_header.flags = 0; -                    mach_header.reserved = 0; -                    ThreadList &thread_list = process_sp->GetThreadList(); -                    const uint32_t num_threads = thread_list.GetSize(); - -                    // Make an array of LC_THREAD data items. Each one contains -                    // the contents of the LC_THREAD load command. The data doesn't -                    // contain the load command + load command size, we will -                    // add the load command and load command size as we emit the data. -                    std::vector<StreamString> LC_THREAD_datas(num_threads); -                    for (auto &LC_THREAD_data : LC_THREAD_datas) -                    { -                        LC_THREAD_data.GetFlags().Set(Stream::eBinary); -                        LC_THREAD_data.SetAddressByteSize(addr_byte_size); -                        LC_THREAD_data.SetByteOrder(byte_order); -                    } -                    for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) -                    { -                        ThreadSP thread_sp (thread_list.GetThreadAtIndex(thread_idx)); -                        if (thread_sp) -                        { -                            switch (mach_header.cputype) -                            { -                                case llvm::MachO::CPU_TYPE_ARM64: -                                    RegisterContextDarwin_arm64_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]); -                                    break; - -                                case llvm::MachO::CPU_TYPE_ARM: -                                    RegisterContextDarwin_arm_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]); -                                    break; - -                                case llvm::MachO::CPU_TYPE_I386: -                                    RegisterContextDarwin_i386_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]); -                                    break; -                                     -                                case llvm::MachO::CPU_TYPE_X86_64: -                                    RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]); -                                    break; -                            } -                             -                        } -                    } -                     -                    // The size of the load command is the size of the segments... -                    if (addr_byte_size == 8) -                    { -                        mach_header.sizeofcmds = segment_load_commands.size() * sizeof (struct segment_command_64); -                    } -                    else -                    { -                        mach_header.sizeofcmds = segment_load_commands.size() * sizeof (struct segment_command); -                    } -                     -                    // and the size of all LC_THREAD load command -                    for (const auto &LC_THREAD_data : LC_THREAD_datas) -                    { -                        ++mach_header.ncmds; -                        mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize(); -                    } +              case llvm::MachO::CPU_TYPE_ARM: +                RegisterContextDarwin_arm_Mach::Create_LC_THREAD( +                    thread_sp.get(), LC_THREAD_datas[thread_idx]); +                break; -                    printf ("mach_header: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n", -                            mach_header.magic, -                            mach_header.cputype, -                            mach_header.cpusubtype, -                            mach_header.filetype, -                            mach_header.ncmds, -                            mach_header.sizeofcmds, -                            mach_header.flags, -                            mach_header.reserved); - -                    // Write the mach header -                    buffer.PutHex32(mach_header.magic); -                    buffer.PutHex32(mach_header.cputype); -                    buffer.PutHex32(mach_header.cpusubtype); -                    buffer.PutHex32(mach_header.filetype); -                    buffer.PutHex32(mach_header.ncmds); -                    buffer.PutHex32(mach_header.sizeofcmds); -                    buffer.PutHex32(mach_header.flags); -                    if (addr_byte_size == 8) -                    { -                        buffer.PutHex32(mach_header.reserved); -                    } -                     -                    // Skip the mach header and all load commands and align to the next -                    // 0x1000 byte boundary -                    addr_t file_offset = buffer.GetSize() + mach_header.sizeofcmds; -                    if (file_offset & 0x00000fff) -                    { -                        file_offset += 0x00001000ull; -                        file_offset &= (~0x00001000ull + 1); -                    } -                     -                    for (auto &segment : segment_load_commands) -                    { -                        segment.fileoff = file_offset; -                        file_offset += segment.filesize; -                    } -                     -                    // Write out all of the LC_THREAD load commands -                    for (const auto &LC_THREAD_data : LC_THREAD_datas) -                    { -                        const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize(); -                        buffer.PutHex32(LC_THREAD); -                        buffer.PutHex32(8 + LC_THREAD_data_size); // cmd + cmdsize + data -                        buffer.Write(LC_THREAD_data.GetData(), LC_THREAD_data_size); -                    } +              case llvm::MachO::CPU_TYPE_I386: +                RegisterContextDarwin_i386_Mach::Create_LC_THREAD( +                    thread_sp.get(), LC_THREAD_datas[thread_idx]); +                break; -                    // Write out all of the segment load commands -                    for (const auto &segment : segment_load_commands) -                    { -                        printf ("0x%8.8x 0x%8.8x [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") [0x%16.16" PRIx64 " 0x%16.16" PRIx64 ") 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x]\n", -                                segment.cmd, -                                segment.cmdsize, -                                segment.vmaddr, -                                segment.vmaddr + segment.vmsize, -                                segment.fileoff, -                                segment.filesize, -                                segment.maxprot, -                                segment.initprot, -                                segment.nsects, -                                segment.flags); -                         -                        buffer.PutHex32(segment.cmd); -                        buffer.PutHex32(segment.cmdsize); -                        buffer.PutRawBytes(segment.segname, sizeof(segment.segname)); -                        if (addr_byte_size == 8) -                        { -                            buffer.PutHex64(segment.vmaddr); -                            buffer.PutHex64(segment.vmsize); -                            buffer.PutHex64(segment.fileoff); -                            buffer.PutHex64(segment.filesize); -                        } -                        else -                        { -                            buffer.PutHex32(static_cast<uint32_t>(segment.vmaddr)); -                            buffer.PutHex32(static_cast<uint32_t>(segment.vmsize)); -                            buffer.PutHex32(static_cast<uint32_t>(segment.fileoff)); -                            buffer.PutHex32(static_cast<uint32_t>(segment.filesize)); -                        } -                        buffer.PutHex32(segment.maxprot); -                        buffer.PutHex32(segment.initprot); -                        buffer.PutHex32(segment.nsects); -                        buffer.PutHex32(segment.flags); -                    } -                     -                    File core_file; -                    std::string core_file_path(outfile.GetPath()); -                    error = core_file.Open(core_file_path.c_str(), -                                           File::eOpenOptionWrite    | -                                           File::eOpenOptionTruncate | -                                           File::eOpenOptionCanCreate); -                    if (error.Success()) -                    { -                        // Read 1 page at a time -                        uint8_t bytes[0x1000]; -                        // Write the mach header and load commands out to the core file -                        size_t bytes_written = buffer.GetString().size(); -                        error = core_file.Write(buffer.GetString().data(), bytes_written); -                        if (error.Success()) -                        { -                            // Now write the file data for all memory segments in the process -                            for (const auto &segment : segment_load_commands) -                            { -                                if (core_file.SeekFromStart(segment.fileoff) == -1) -                                { -                                    error.SetErrorStringWithFormat("unable to seek to offset 0x%" PRIx64 " in '%s'", segment.fileoff, core_file_path.c_str()); -                                    break; -                                } -                                 -                                printf ("Saving %" PRId64 " bytes of data for memory region at 0x%" PRIx64 "\n", segment.vmsize, segment.vmaddr); -                                addr_t bytes_left = segment.vmsize; -                                addr_t addr = segment.vmaddr; -                                Error memory_read_error; -                                while (bytes_left > 0 && error.Success()) -                                { -                                    const size_t bytes_to_read = bytes_left > sizeof(bytes) ? sizeof(bytes) : bytes_left; -                                    const size_t bytes_read = process_sp->ReadMemory(addr, bytes, bytes_to_read, memory_read_error); -                                    if (bytes_read == bytes_to_read) -                                    { -                                        size_t bytes_written = bytes_read; -                                        error = core_file.Write(bytes, bytes_written); -                                        bytes_left -= bytes_read; -                                        addr += bytes_read; -                                    } -                                    else -                                    { -                                        // Some pages within regions are not readable, those -                                        // should be zero filled -                                        memset (bytes, 0, bytes_to_read); -                                        size_t bytes_written = bytes_to_read; -                                        error = core_file.Write(bytes, bytes_written); -                                        bytes_left -= bytes_to_read; -                                        addr += bytes_to_read; -                                    } -                                } -                            } -                        } -                    } +              case llvm::MachO::CPU_TYPE_X86_64: +                RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD( +                    thread_sp.get(), LC_THREAD_datas[thread_idx]); +                break; +              } +            } +          } + +          // The size of the load command is the size of the segments... +          if (addr_byte_size == 8) { +            mach_header.sizeofcmds = segment_load_commands.size() * +                                     sizeof(struct segment_command_64); +          } else { +            mach_header.sizeofcmds = +                segment_load_commands.size() * sizeof(struct segment_command); +          } + +          // and the size of all LC_THREAD load command +          for (const auto &LC_THREAD_data : LC_THREAD_datas) { +            ++mach_header.ncmds; +            mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize(); +          } + +          printf("mach_header: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x " +                 "0x%8.8x 0x%8.8x\n", +                 mach_header.magic, mach_header.cputype, mach_header.cpusubtype, +                 mach_header.filetype, mach_header.ncmds, +                 mach_header.sizeofcmds, mach_header.flags, +                 mach_header.reserved); + +          // Write the mach header +          buffer.PutHex32(mach_header.magic); +          buffer.PutHex32(mach_header.cputype); +          buffer.PutHex32(mach_header.cpusubtype); +          buffer.PutHex32(mach_header.filetype); +          buffer.PutHex32(mach_header.ncmds); +          buffer.PutHex32(mach_header.sizeofcmds); +          buffer.PutHex32(mach_header.flags); +          if (addr_byte_size == 8) { +            buffer.PutHex32(mach_header.reserved); +          } + +          // Skip the mach header and all load commands and align to the next +          // 0x1000 byte boundary +          addr_t file_offset = buffer.GetSize() + mach_header.sizeofcmds; +          if (file_offset & 0x00000fff) { +            file_offset += 0x00001000ull; +            file_offset &= (~0x00001000ull + 1); +          } + +          for (auto &segment : segment_load_commands) { +            segment.fileoff = file_offset; +            file_offset += segment.filesize; +          } + +          // Write out all of the LC_THREAD load commands +          for (const auto &LC_THREAD_data : LC_THREAD_datas) { +            const size_t LC_THREAD_data_size = LC_THREAD_data.GetSize(); +            buffer.PutHex32(LC_THREAD); +            buffer.PutHex32(8 + LC_THREAD_data_size); // cmd + cmdsize + data +            buffer.Write(LC_THREAD_data.GetString().data(), +                         LC_THREAD_data_size); +          } + +          // Write out all of the segment load commands +          for (const auto &segment : segment_load_commands) { +            printf("0x%8.8x 0x%8.8x [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 +                   ") [0x%16.16" PRIx64 " 0x%16.16" PRIx64 +                   ") 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x]\n", +                   segment.cmd, segment.cmdsize, segment.vmaddr, +                   segment.vmaddr + segment.vmsize, segment.fileoff, +                   segment.filesize, segment.maxprot, segment.initprot, +                   segment.nsects, segment.flags); + +            buffer.PutHex32(segment.cmd); +            buffer.PutHex32(segment.cmdsize); +            buffer.PutRawBytes(segment.segname, sizeof(segment.segname)); +            if (addr_byte_size == 8) { +              buffer.PutHex64(segment.vmaddr); +              buffer.PutHex64(segment.vmsize); +              buffer.PutHex64(segment.fileoff); +              buffer.PutHex64(segment.filesize); +            } else { +              buffer.PutHex32(static_cast<uint32_t>(segment.vmaddr)); +              buffer.PutHex32(static_cast<uint32_t>(segment.vmsize)); +              buffer.PutHex32(static_cast<uint32_t>(segment.fileoff)); +              buffer.PutHex32(static_cast<uint32_t>(segment.filesize)); +            } +            buffer.PutHex32(segment.maxprot); +            buffer.PutHex32(segment.initprot); +            buffer.PutHex32(segment.nsects); +            buffer.PutHex32(segment.flags); +          } + +          File core_file; +          std::string core_file_path(outfile.GetPath()); +          error = core_file.Open(core_file_path.c_str(), +                                 File::eOpenOptionWrite | +                                     File::eOpenOptionTruncate | +                                     File::eOpenOptionCanCreate); +          if (error.Success()) { +            // Read 1 page at a time +            uint8_t bytes[0x1000]; +            // Write the mach header and load commands out to the core file +            size_t bytes_written = buffer.GetString().size(); +            error = core_file.Write(buffer.GetString().data(), bytes_written); +            if (error.Success()) { +              // Now write the file data for all memory segments in the process +              for (const auto &segment : segment_load_commands) { +                if (core_file.SeekFromStart(segment.fileoff) == -1) { +                  error.SetErrorStringWithFormat( +                      "unable to seek to offset 0x%" PRIx64 " in '%s'", +                      segment.fileoff, core_file_path.c_str()); +                  break;                  } -                else -                { -                    error.SetErrorString("process doesn't support getting memory region info"); + +                printf("Saving %" PRId64 +                       " bytes of data for memory region at 0x%" PRIx64 "\n", +                       segment.vmsize, segment.vmaddr); +                addr_t bytes_left = segment.vmsize; +                addr_t addr = segment.vmaddr; +                Error memory_read_error; +                while (bytes_left > 0 && error.Success()) { +                  const size_t bytes_to_read = +                      bytes_left > sizeof(bytes) ? sizeof(bytes) : bytes_left; +                  const size_t bytes_read = process_sp->ReadMemory( +                      addr, bytes, bytes_to_read, memory_read_error); +                  if (bytes_read == bytes_to_read) { +                    size_t bytes_written = bytes_read; +                    error = core_file.Write(bytes, bytes_written); +                    bytes_left -= bytes_read; +                    addr += bytes_read; +                  } else { +                    // Some pages within regions are not readable, those +                    // should be zero filled +                    memset(bytes, 0, bytes_to_read); +                    size_t bytes_written = bytes_to_read; +                    error = core_file.Write(bytes, bytes_written); +                    bytes_left -= bytes_to_read; +                    addr += bytes_to_read; +                  }                  } +              }              } -            return true; // This is the right plug to handle saving core files for this process +          } +        } else { +          error.SetErrorString( +              "process doesn't support getting memory region info");          } +      } +      return true; // This is the right plug to handle saving core files for +                   // this process      } -    return false; +  } +  return false;  } diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h index 251a0865e7823..cac176fe2ca67 100644 --- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h +++ b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h @@ -14,242 +14,192 @@  // C++ Includes  // Other libraries and framework includes  // Project includes -#include "lldb/Utility/SafeMachO.h"  #include "lldb/Core/Address.h"  #include "lldb/Core/FileSpecList.h"  #include "lldb/Core/RangeMap.h"  #include "lldb/Host/FileSpec.h"  #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Utility/SafeMachO.h"  //----------------------------------------------------------------------  // This class needs to be hidden as eventually belongs in a plugin that  // will export the ObjectFile protocol  //---------------------------------------------------------------------- -class ObjectFileMachO : -    public lldb_private::ObjectFile -{ +class ObjectFileMachO : public lldb_private::ObjectFile {  public: -    ObjectFileMachO(const lldb::ModuleSP &module_sp, -                    lldb::DataBufferSP& data_sp, -                    lldb::offset_t data_offset, -                    const lldb_private::FileSpec* file, -                    lldb::offset_t offset, -                    lldb::offset_t length); - -    ObjectFileMachO(const lldb::ModuleSP &module_sp, -                    lldb::DataBufferSP& data_sp, -                    const lldb::ProcessSP &process_sp, -                    lldb::addr_t header_addr); - -    ~ObjectFileMachO() override = default; - -    //------------------------------------------------------------------ -    // Static Functions -    //------------------------------------------------------------------ -    static void -    Initialize(); - -    static void -    Terminate(); - -    static lldb_private::ConstString -    GetPluginNameStatic(); - -    static const char * -    GetPluginDescriptionStatic(); - -    static lldb_private::ObjectFile * -    CreateInstance (const lldb::ModuleSP &module_sp, -                    lldb::DataBufferSP& data_sp, -                    lldb::offset_t data_offset, -                    const lldb_private::FileSpec* file, -                    lldb::offset_t file_offset, -                    lldb::offset_t length); - -    static lldb_private::ObjectFile * -    CreateMemoryInstance (const lldb::ModuleSP &module_sp,  -                          lldb::DataBufferSP& data_sp,  -                          const lldb::ProcessSP &process_sp,  -                          lldb::addr_t header_addr); - -    static size_t -    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); - -    static bool -    SaveCore (const lldb::ProcessSP &process_sp, -              const lldb_private::FileSpec &outfile, -              lldb_private::Error &error); - -    static bool -    MagicBytesMatch (lldb::DataBufferSP& data_sp, -                     lldb::addr_t offset,  -                     lldb::addr_t length); - -    //------------------------------------------------------------------ -    // Member Functions -    //------------------------------------------------------------------ -    bool -    ParseHeader() override; - -    bool -    SetLoadAddress(lldb_private::Target &target, -                   lldb::addr_t value, -                   bool value_is_offset) override; -     -    lldb::ByteOrder -    GetByteOrder() const override; -     -    bool -    IsExecutable() const override; - -    uint32_t -    GetAddressByteSize() const override; - -    lldb::AddressClass -    GetAddressClass(lldb::addr_t file_addr) override; - -    lldb_private::Symtab * -    GetSymtab() override; - -    bool -    IsStripped() override; -     -    void -    CreateSections(lldb_private::SectionList &unified_section_list) override; - -    void -    Dump(lldb_private::Stream *s) override; - -    bool -    GetArchitecture(lldb_private::ArchSpec &arch) override; - -    bool -    GetUUID(lldb_private::UUID* uuid) override; - -    uint32_t -    GetDependentModules(lldb_private::FileSpecList& files) override; - -    lldb_private::FileSpecList -    GetReExportedLibraries() override -    { -        return m_reexported_dylibs; -    } - -    lldb_private::Address -    GetEntryPointAddress() override; -     -    lldb_private::Address -    GetHeaderAddress() override; -     -    uint32_t -    GetNumThreadContexts() override; -     -    lldb::RegisterContextSP -    GetThreadContextAtIndex(uint32_t idx, lldb_private::Thread &thread) override; - -    ObjectFile::Type -    CalculateType() override; -     -    ObjectFile::Strata -    CalculateStrata() override; - -    uint32_t -    GetVersion(uint32_t *versions, uint32_t num_versions) override; - -    uint32_t -    GetMinimumOSVersion(uint32_t *versions, uint32_t num_versions) override; -     -    uint32_t -    GetSDKVersion(uint32_t *versions, uint32_t num_versions) override; - -    bool -    GetIsDynamicLinkEditor() override; - -    static bool -    ParseHeader (lldb_private::DataExtractor &data, -                 lldb::offset_t *data_offset_ptr, -                 llvm::MachO::mach_header &header); -     -    bool -    AllowAssemblyEmulationUnwindPlans () override; - -    //------------------------------------------------------------------ -    // PluginInterface protocol -    //------------------------------------------------------------------ -    lldb_private::ConstString -    GetPluginName() override; - -    uint32_t -    GetPluginVersion() override; +  ObjectFileMachO(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, +                  lldb::offset_t data_offset, +                  const lldb_private::FileSpec *file, lldb::offset_t offset, +                  lldb::offset_t length); + +  ObjectFileMachO(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, +                  const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); + +  ~ObjectFileMachO() override = default; + +  //------------------------------------------------------------------ +  // Static Functions +  //------------------------------------------------------------------ +  static void Initialize(); + +  static void Terminate(); + +  static lldb_private::ConstString GetPluginNameStatic(); + +  static const char *GetPluginDescriptionStatic(); + +  static lldb_private::ObjectFile * +  CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, +                 lldb::offset_t data_offset, const lldb_private::FileSpec *file, +                 lldb::offset_t file_offset, lldb::offset_t length); + +  static lldb_private::ObjectFile *CreateMemoryInstance( +      const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, +      const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); + +  static size_t 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); + +  static bool SaveCore(const lldb::ProcessSP &process_sp, +                       const lldb_private::FileSpec &outfile, +                       lldb_private::Error &error); + +  static bool MagicBytesMatch(lldb::DataBufferSP &data_sp, lldb::addr_t offset, +                              lldb::addr_t length); + +  //------------------------------------------------------------------ +  // Member Functions +  //------------------------------------------------------------------ +  bool ParseHeader() override; + +  bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, +                      bool value_is_offset) override; + +  lldb::ByteOrder GetByteOrder() const override; + +  bool IsExecutable() const override; + +  uint32_t GetAddressByteSize() const override; + +  lldb::AddressClass GetAddressClass(lldb::addr_t file_addr) override; + +  lldb_private::Symtab *GetSymtab() override; + +  bool IsStripped() override; + +  void CreateSections(lldb_private::SectionList &unified_section_list) override; + +  void Dump(lldb_private::Stream *s) override; + +  bool GetArchitecture(lldb_private::ArchSpec &arch) override; + +  bool GetUUID(lldb_private::UUID *uuid) override; + +  uint32_t GetDependentModules(lldb_private::FileSpecList &files) override; + +  lldb_private::FileSpecList GetReExportedLibraries() override { +    return m_reexported_dylibs; +  } + +  lldb_private::Address GetEntryPointAddress() override; + +  lldb_private::Address GetHeaderAddress() override; + +  uint32_t GetNumThreadContexts() override; + +  lldb::RegisterContextSP +  GetThreadContextAtIndex(uint32_t idx, lldb_private::Thread &thread) override; + +  ObjectFile::Type CalculateType() override; + +  ObjectFile::Strata CalculateStrata() override; + +  uint32_t GetVersion(uint32_t *versions, uint32_t num_versions) override; + +  uint32_t GetMinimumOSVersion(uint32_t *versions, +                               uint32_t num_versions) override; + +  uint32_t GetSDKVersion(uint32_t *versions, uint32_t num_versions) override; + +  bool GetIsDynamicLinkEditor() override; + +  static bool ParseHeader(lldb_private::DataExtractor &data, +                          lldb::offset_t *data_offset_ptr, +                          llvm::MachO::mach_header &header); + +  bool AllowAssemblyEmulationUnwindPlans() override; + +  //------------------------------------------------------------------ +  // PluginInterface protocol +  //------------------------------------------------------------------ +  lldb_private::ConstString GetPluginName() override; + +  uint32_t GetPluginVersion() override;  protected: -    static bool -    GetUUID (const llvm::MachO::mach_header &header, -             const lldb_private::DataExtractor &data, -             lldb::offset_t lc_offset, // Offset to the first load command -             lldb_private::UUID& uuid); -     -    static bool -    GetArchitecture (const llvm::MachO::mach_header &header, -                     const lldb_private::DataExtractor &data, -                     lldb::offset_t lc_offset, -                     lldb_private::ArchSpec &arch); - -    // Intended for same-host arm device debugging where lldb needs to -    // detect libraries in the shared cache and augment the nlist entries -    // with an on-disk dyld_shared_cache file.  The process will record -    // the shared cache UUID so the on-disk cache can be matched or rejected -    // correctly. -    lldb_private::UUID -    GetProcessSharedCacheUUID (lldb_private::Process *); - -    // Intended for same-host arm device debugging where lldb will read -    // shared cache libraries out of its own memory instead of the remote -    // process' memory as an optimization.  If lldb's shared cache UUID  -    // does not match the process' shared cache UUID, this optimization -    // should not be used. -    lldb_private::UUID -    GetLLDBSharedCacheUUID (); - -    lldb_private::Section * -    GetMachHeaderSection(); - -    lldb::addr_t -    CalculateSectionLoadAddressForMemoryImage(lldb::addr_t mach_header_load_address, -                                              const lldb_private::Section *mach_header_section, -                                              const lldb_private::Section *section); - -    lldb_private::UUID -    GetSharedCacheUUID (lldb_private::FileSpec dyld_shared_cache, const lldb::ByteOrder byte_order, const uint32_t addr_byte_size); - -    size_t -    ParseSymtab(); - -    llvm::MachO::mach_header m_header; -    static const lldb_private::ConstString &GetSegmentNameTEXT(); -    static const lldb_private::ConstString &GetSegmentNameDATA(); -    static const lldb_private::ConstString &GetSegmentNameDATA_DIRTY(); -    static const lldb_private::ConstString &GetSegmentNameDATA_CONST(); -    static const lldb_private::ConstString &GetSegmentNameOBJC(); -    static const lldb_private::ConstString &GetSegmentNameLINKEDIT(); -    static const lldb_private::ConstString &GetSectionNameEHFrame(); - -    llvm::MachO::dysymtab_command m_dysymtab; -    std::vector<llvm::MachO::segment_command_64> m_mach_segments; -    std::vector<llvm::MachO::section_64> m_mach_sections; -    std::vector<uint32_t> m_min_os_versions; -    std::vector<uint32_t> m_sdk_versions; -    typedef lldb_private::RangeVector<uint32_t, uint32_t> FileRangeArray; -    lldb_private::Address  m_entry_point_address; -    FileRangeArray m_thread_context_offsets; -    bool m_thread_context_offsets_valid; -    lldb_private::FileSpecList m_reexported_dylibs; -    bool m_allow_assembly_emulation_unwind_plans; +  static bool +  GetUUID(const llvm::MachO::mach_header &header, +          const lldb_private::DataExtractor &data, +          lldb::offset_t lc_offset, // Offset to the first load command +          lldb_private::UUID &uuid); + +  static bool GetArchitecture(const llvm::MachO::mach_header &header, +                              const lldb_private::DataExtractor &data, +                              lldb::offset_t lc_offset, +                              lldb_private::ArchSpec &arch); + +  // Intended for same-host arm device debugging where lldb needs to +  // detect libraries in the shared cache and augment the nlist entries +  // with an on-disk dyld_shared_cache file.  The process will record +  // the shared cache UUID so the on-disk cache can be matched or rejected +  // correctly. +  lldb_private::UUID GetProcessSharedCacheUUID(lldb_private::Process *); + +  // Intended for same-host arm device debugging where lldb will read +  // shared cache libraries out of its own memory instead of the remote +  // process' memory as an optimization.  If lldb's shared cache UUID +  // does not match the process' shared cache UUID, this optimization +  // should not be used. +  lldb_private::UUID GetLLDBSharedCacheUUID(); + +  lldb_private::Section *GetMachHeaderSection(); + +  lldb::addr_t CalculateSectionLoadAddressForMemoryImage( +      lldb::addr_t mach_header_load_address, +      const lldb_private::Section *mach_header_section, +      const lldb_private::Section *section); + +  lldb_private::UUID +  GetSharedCacheUUID(lldb_private::FileSpec dyld_shared_cache, +                     const lldb::ByteOrder byte_order, +                     const uint32_t addr_byte_size); + +  size_t ParseSymtab(); + +  llvm::MachO::mach_header m_header; +  static const lldb_private::ConstString &GetSegmentNameTEXT(); +  static const lldb_private::ConstString &GetSegmentNameDATA(); +  static const lldb_private::ConstString &GetSegmentNameDATA_DIRTY(); +  static const lldb_private::ConstString &GetSegmentNameDATA_CONST(); +  static const lldb_private::ConstString &GetSegmentNameOBJC(); +  static const lldb_private::ConstString &GetSegmentNameLINKEDIT(); +  static const lldb_private::ConstString &GetSectionNameEHFrame(); + +  llvm::MachO::dysymtab_command m_dysymtab; +  std::vector<llvm::MachO::segment_command_64> m_mach_segments; +  std::vector<llvm::MachO::section_64> m_mach_sections; +  std::vector<uint32_t> m_min_os_versions; +  std::vector<uint32_t> m_sdk_versions; +  typedef lldb_private::RangeVector<uint32_t, uint32_t> FileRangeArray; +  lldb_private::Address m_entry_point_address; +  FileRangeArray m_thread_context_offsets; +  bool m_thread_context_offsets_valid; +  lldb_private::FileSpecList m_reexported_dylibs; +  bool m_allow_assembly_emulation_unwind_plans;  };  #endif // liblldb_ObjectFileMachO_h_ diff --git a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp index 5f5a0ab07ad69..f0647e02158be 100644 --- a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp +++ b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp @@ -14,7 +14,7 @@  #include "lldb/Core/ArchSpec.h"  #include "lldb/Core/DataBuffer.h" -#include "lldb/Host/FileSpec.h" +#include "lldb/Core/DataBufferHeap.h"  #include "lldb/Core/FileSpecList.h"  #include "lldb/Core/Module.h"  #include "lldb/Core/ModuleSpec.h" @@ -24,858 +24,818 @@  #include "lldb/Core/StreamString.h"  #include "lldb/Core/Timer.h"  #include "lldb/Core/UUID.h" +#include "lldb/Host/FileSpec.h"  #include "lldb/Symbol/ObjectFile.h"  #include "lldb/Target/Process.h"  #include "lldb/Target/SectionLoadList.h"  #include "lldb/Target/Target.h" -#define IMAGE_DOS_SIGNATURE             0x5A4D      // MZ -#define IMAGE_NT_SIGNATURE              0x00004550  // PE00 -#define OPT_HEADER_MAGIC_PE32           0x010b -#define OPT_HEADER_MAGIC_PE32_PLUS      0x020b +#define IMAGE_DOS_SIGNATURE 0x5A4D    // MZ +#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 +#define OPT_HEADER_MAGIC_PE32 0x010b +#define OPT_HEADER_MAGIC_PE32_PLUS 0x020b  using namespace lldb;  using namespace lldb_private; -void -ObjectFilePECOFF::Initialize() -{ -    PluginManager::RegisterPlugin (GetPluginNameStatic(), -                                   GetPluginDescriptionStatic(), -                                   CreateInstance, -                                   CreateMemoryInstance, -                                   GetModuleSpecifications, -                                   SaveCore); +void ObjectFilePECOFF::Initialize() { +  PluginManager::RegisterPlugin( +      GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, +      CreateMemoryInstance, GetModuleSpecifications, SaveCore);  } -void -ObjectFilePECOFF::Terminate() -{ -    PluginManager::UnregisterPlugin (CreateInstance); +void ObjectFilePECOFF::Terminate() { +  PluginManager::UnregisterPlugin(CreateInstance);  } +lldb_private::ConstString ObjectFilePECOFF::GetPluginNameStatic() { +  static ConstString g_name("pe-coff"); +  return g_name; +} -lldb_private::ConstString -ObjectFilePECOFF::GetPluginNameStatic() -{ -    static ConstString g_name("pe-coff"); -    return g_name; +const char *ObjectFilePECOFF::GetPluginDescriptionStatic() { +  return "Portable Executable and Common Object File Format object file reader " +         "(32 and 64 bit)";  } -const char * -ObjectFilePECOFF::GetPluginDescriptionStatic() -{ -    return "Portable Executable and Common Object File Format object file reader (32 and 64 bit)"; +ObjectFile *ObjectFilePECOFF::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 = file->MemoryMapFileContentsIfLocal(file_offset, length); +    data_offset = 0; +  } + +  if (ObjectFilePECOFF::MagicBytesMatch(data_sp)) { +    // Update the data to contain the entire file if it doesn't already +    if (data_sp->GetByteSize() < length) +      data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length); +    std::unique_ptr<ObjectFile> objfile_ap(new ObjectFilePECOFF( +        module_sp, data_sp, data_offset, file, file_offset, length)); +    if (objfile_ap.get() && objfile_ap->ParseHeader()) +      return objfile_ap.release(); +  } +  return NULL;  } +ObjectFile *ObjectFilePECOFF::CreateMemoryInstance( +    const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, +    const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) { +  if (!data_sp || !ObjectFilePECOFF::MagicBytesMatch(data_sp)) +    return nullptr; +  auto objfile_ap = llvm::make_unique<ObjectFilePECOFF>( +      module_sp, data_sp, process_sp, header_addr); +  if (objfile_ap.get() && objfile_ap->ParseHeader()) { +    return objfile_ap.release(); +  } +  return nullptr; +} -ObjectFile * -ObjectFilePECOFF::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 = file->MemoryMapFileContentsIfLocal(file_offset, length); -        data_offset = 0; -    } +size_t ObjectFilePECOFF::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) { +  const size_t initial_count = specs.GetSize(); -    if (ObjectFilePECOFF::MagicBytesMatch(data_sp)) -    { -        // Update the data to contain the entire file if it doesn't already -        if (data_sp->GetByteSize() < length) -            data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length); -        std::unique_ptr<ObjectFile> objfile_ap(new ObjectFilePECOFF (module_sp, data_sp, data_offset, file, file_offset, length)); -        if (objfile_ap.get() && objfile_ap->ParseHeader()) -            return objfile_ap.release(); -    } -    return NULL; -} +  if (ObjectFilePECOFF::MagicBytesMatch(data_sp)) { +    DataExtractor data; +    data.SetData(data_sp, data_offset, length); +    data.SetByteOrder(eByteOrderLittle); -ObjectFile * -ObjectFilePECOFF::CreateMemoryInstance (const lldb::ModuleSP &module_sp,  -                                        lldb::DataBufferSP& data_sp,  -                                        const lldb::ProcessSP &process_sp,  -                                        lldb::addr_t header_addr) -{ -    return NULL; -} +    dos_header_t dos_header; +    coff_header_t coff_header; -size_t -ObjectFilePECOFF::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) -{ -    const size_t initial_count = specs.GetSize(); - -    if (ObjectFilePECOFF::MagicBytesMatch(data_sp)) -    { -        DataExtractor data; -        data.SetData(data_sp, data_offset, length); -        data.SetByteOrder(eByteOrderLittle); - -        dos_header_t dos_header; -        coff_header_t coff_header; - -        if (ParseDOSHeader(data, dos_header)) -        { -            lldb::offset_t offset = dos_header.e_lfanew; -            uint32_t pe_signature = data.GetU32(&offset); -            if (pe_signature != IMAGE_NT_SIGNATURE) -                return false; -            if (ParseCOFFHeader(data, &offset, coff_header)) -            { -                ArchSpec spec; -                if (coff_header.machine == MachineAmd64) -                { -                    spec.SetTriple("x86_64-pc-windows"); -                    specs.Append(ModuleSpec(file, spec)); -                } -                else if (coff_header.machine == MachineX86) -                { -                    spec.SetTriple("i386-pc-windows"); -                    specs.Append(ModuleSpec(file, spec)); -                    spec.SetTriple("i686-pc-windows"); -                    specs.Append(ModuleSpec(file, spec)); -                } -            } +    if (ParseDOSHeader(data, dos_header)) { +      lldb::offset_t offset = dos_header.e_lfanew; +      uint32_t pe_signature = data.GetU32(&offset); +      if (pe_signature != IMAGE_NT_SIGNATURE) +        return false; +      if (ParseCOFFHeader(data, &offset, coff_header)) { +        ArchSpec spec; +        if (coff_header.machine == MachineAmd64) { +          spec.SetTriple("x86_64-pc-windows"); +          specs.Append(ModuleSpec(file, spec)); +        } else if (coff_header.machine == MachineX86) { +          spec.SetTriple("i386-pc-windows"); +          specs.Append(ModuleSpec(file, spec)); +          spec.SetTriple("i686-pc-windows"); +          specs.Append(ModuleSpec(file, spec));          } +      }      } +  } -    return specs.GetSize() - initial_count; +  return specs.GetSize() - initial_count;  } -bool -ObjectFilePECOFF::SaveCore(const lldb::ProcessSP &process_sp, -                           const lldb_private::FileSpec &outfile, -                           lldb_private::Error &error) -{ -    return SaveMiniDump(process_sp, outfile, error); +bool ObjectFilePECOFF::SaveCore(const lldb::ProcessSP &process_sp, +                                const lldb_private::FileSpec &outfile, +                                lldb_private::Error &error) { +  return SaveMiniDump(process_sp, outfile, error);  } - -bool -ObjectFilePECOFF::MagicBytesMatch (DataBufferSP& data_sp) -{ -    DataExtractor data(data_sp, eByteOrderLittle, 4); -    lldb::offset_t offset = 0; -    uint16_t magic = data.GetU16 (&offset); -    return magic == IMAGE_DOS_SIGNATURE; +bool ObjectFilePECOFF::MagicBytesMatch(DataBufferSP &data_sp) { +  DataExtractor data(data_sp, eByteOrderLittle, 4); +  lldb::offset_t offset = 0; +  uint16_t magic = data.GetU16(&offset); +  return magic == IMAGE_DOS_SIGNATURE;  } -lldb::SymbolType -ObjectFilePECOFF::MapSymbolType(uint16_t coff_symbol_type) -{ -    // TODO:  We need to complete this mapping of COFF symbol types to LLDB ones. -    // For now, here's a hack to make sure our function have types. -    const auto complex_type = coff_symbol_type >> llvm::COFF::SCT_COMPLEX_TYPE_SHIFT; -    if (complex_type == llvm::COFF::IMAGE_SYM_DTYPE_FUNCTION) -    { -        return lldb::eSymbolTypeCode; -    } -    return lldb::eSymbolTypeInvalid; +lldb::SymbolType ObjectFilePECOFF::MapSymbolType(uint16_t coff_symbol_type) { +  // TODO:  We need to complete this mapping of COFF symbol types to LLDB ones. +  // For now, here's a hack to make sure our function have types. +  const auto complex_type = +      coff_symbol_type >> llvm::COFF::SCT_COMPLEX_TYPE_SHIFT; +  if (complex_type == llvm::COFF::IMAGE_SYM_DTYPE_FUNCTION) { +    return lldb::eSymbolTypeCode; +  } +  return lldb::eSymbolTypeInvalid;  } -ObjectFilePECOFF::ObjectFilePECOFF (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_dos_header (), -    m_coff_header (), -    m_coff_header_opt (), -    m_sect_headers (), -    m_entry_point_address () -{ -    ::memset (&m_dos_header, 0, sizeof(m_dos_header)); -    ::memset (&m_coff_header, 0, sizeof(m_coff_header)); -    ::memset (&m_coff_header_opt, 0, sizeof(m_coff_header_opt)); +ObjectFilePECOFF::ObjectFilePECOFF(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_dos_header(), m_coff_header(), m_coff_header_opt(), m_sect_headers(), +      m_entry_point_address() { +  ::memset(&m_dos_header, 0, sizeof(m_dos_header)); +  ::memset(&m_coff_header, 0, sizeof(m_coff_header)); +  ::memset(&m_coff_header_opt, 0, sizeof(m_coff_header_opt));  } - -ObjectFilePECOFF::~ObjectFilePECOFF() -{ +ObjectFilePECOFF::ObjectFilePECOFF(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_dos_header(), m_coff_header(), m_coff_header_opt(), m_sect_headers(), +      m_entry_point_address() { +  ::memset(&m_dos_header, 0, sizeof(m_dos_header)); +  ::memset(&m_coff_header, 0, sizeof(m_coff_header)); +  ::memset(&m_coff_header_opt, 0, sizeof(m_coff_header_opt));  } +ObjectFilePECOFF::~ObjectFilePECOFF() {} -bool -ObjectFilePECOFF::ParseHeader () -{ -    ModuleSP module_sp(GetModule()); -    if (module_sp) -    { -        std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); -        m_sect_headers.clear(); -        m_data.SetByteOrder (eByteOrderLittle); -        lldb::offset_t offset = 0; -         -        if (ParseDOSHeader(m_data, m_dos_header)) -        { -            offset = m_dos_header.e_lfanew; -            uint32_t pe_signature = m_data.GetU32 (&offset); -            if (pe_signature != IMAGE_NT_SIGNATURE) -                return false; -            if (ParseCOFFHeader(m_data, &offset, m_coff_header)) -            { -                if (m_coff_header.hdrsize > 0) -                    ParseCOFFOptionalHeader(&offset); -                ParseSectionHeaders (offset); -            } -            return true; -        } +bool ObjectFilePECOFF::ParseHeader() { +  ModuleSP module_sp(GetModule()); +  if (module_sp) { +    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); +    m_sect_headers.clear(); +    m_data.SetByteOrder(eByteOrderLittle); +    lldb::offset_t offset = 0; + +    if (ParseDOSHeader(m_data, m_dos_header)) { +      offset = m_dos_header.e_lfanew; +      uint32_t pe_signature = m_data.GetU32(&offset); +      if (pe_signature != IMAGE_NT_SIGNATURE) +        return false; +      if (ParseCOFFHeader(m_data, &offset, m_coff_header)) { +        if (m_coff_header.hdrsize > 0) +          ParseCOFFOptionalHeader(&offset); +        ParseSectionHeaders(offset); +      } +      return true;      } -    return false; +  } +  return false;  } -bool -ObjectFilePECOFF::SetLoadAddress(Target &target, addr_t value, bool value_is_offset) -{ -    bool changed = false; -    ModuleSP module_sp = GetModule(); -    if (module_sp) -    { -        size_t num_loaded_sections = 0; -        SectionList *section_list = GetSectionList (); -        if (section_list) -        { -            if (!value_is_offset) -            { -                value -= m_image_base; -            } - -            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->IsThreadSpecific()) -                { -                    if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + value)) -                        ++num_loaded_sections; -                } -            } -            changed = num_loaded_sections > 0; +bool ObjectFilePECOFF::SetLoadAddress(Target &target, addr_t value, +                                      bool value_is_offset) { +  bool changed = false; +  ModuleSP module_sp = GetModule(); +  if (module_sp) { +    size_t num_loaded_sections = 0; +    SectionList *section_list = GetSectionList(); +    if (section_list) { +      if (!value_is_offset) { +        value -= m_image_base; +      } + +      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->IsThreadSpecific()) { +          if (target.GetSectionLoadList().SetSectionLoadAddress( +                  section_sp, section_sp->GetFileAddress() + value)) +            ++num_loaded_sections;          } +      } +      changed = num_loaded_sections > 0;      } -    return changed; +  } +  return changed;  } +ByteOrder ObjectFilePECOFF::GetByteOrder() const { return eByteOrderLittle; } -ByteOrder -ObjectFilePECOFF::GetByteOrder () const -{ -    return eByteOrderLittle; -} - -bool -ObjectFilePECOFF::IsExecutable() const -{ -    return (m_coff_header.flags & llvm::COFF::IMAGE_FILE_DLL) == 0; +bool ObjectFilePECOFF::IsExecutable() const { +  return (m_coff_header.flags & llvm::COFF::IMAGE_FILE_DLL) == 0;  } -uint32_t -ObjectFilePECOFF::GetAddressByteSize () const -{ -    if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32_PLUS) -        return 8; -    else if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32) -        return 4; +uint32_t ObjectFilePECOFF::GetAddressByteSize() const { +  if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32_PLUS) +    return 8; +  else if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32)      return 4; +  return 4;  }  //----------------------------------------------------------------------  // NeedsEndianSwap  // -// Return true if an endian swap needs to occur when extracting data  +// Return true if an endian swap needs to occur when extracting data  // from this file.  //---------------------------------------------------------------------- -bool  -ObjectFilePECOFF::NeedsEndianSwap() const -{ +bool ObjectFilePECOFF::NeedsEndianSwap() const {  #if defined(__LITTLE_ENDIAN__) -    return false; +  return false;  #else -    return true; +  return true;  #endif  }  //----------------------------------------------------------------------  // ParseDOSHeader  //---------------------------------------------------------------------- -bool -ObjectFilePECOFF::ParseDOSHeader (DataExtractor &data, dos_header_t &dos_header) -{ -    bool success = false; -    lldb::offset_t offset = 0; -    success = data.ValidOffsetForDataOfSize(0, sizeof(dos_header)); -     -    if (success) -    { -        dos_header.e_magic = data.GetU16(&offset); // Magic number -        success = dos_header.e_magic == IMAGE_DOS_SIGNATURE; -         -        if (success) -        { -            dos_header.e_cblp     = data.GetU16(&offset); // Bytes on last page of file -            dos_header.e_cp       = data.GetU16(&offset); // Pages in file -            dos_header.e_crlc     = data.GetU16(&offset); // Relocations -            dos_header.e_cparhdr  = data.GetU16(&offset); // Size of header in paragraphs -            dos_header.e_minalloc = data.GetU16(&offset); // Minimum extra paragraphs needed -            dos_header.e_maxalloc = data.GetU16(&offset); // Maximum extra paragraphs needed -            dos_header.e_ss       = data.GetU16(&offset); // Initial (relative) SS value -            dos_header.e_sp       = data.GetU16(&offset); // Initial SP value -            dos_header.e_csum     = data.GetU16(&offset); // Checksum -            dos_header.e_ip       = data.GetU16(&offset); // Initial IP value -            dos_header.e_cs       = data.GetU16(&offset); // Initial (relative) CS value -            dos_header.e_lfarlc   = data.GetU16(&offset); // File address of relocation table -            dos_header.e_ovno     = data.GetU16(&offset); // Overlay number -             -            dos_header.e_res[0]   = data.GetU16(&offset); // Reserved words -            dos_header.e_res[1]   = data.GetU16(&offset); // Reserved words -            dos_header.e_res[2]   = data.GetU16(&offset); // Reserved words -            dos_header.e_res[3]   = data.GetU16(&offset); // Reserved words -             -            dos_header.e_oemid    = data.GetU16(&offset); // OEM identifier (for e_oeminfo) -            dos_header.e_oeminfo  = data.GetU16(&offset); // OEM information; e_oemid specific -            dos_header.e_res2[0]  = data.GetU16(&offset); // Reserved words -            dos_header.e_res2[1]  = data.GetU16(&offset); // Reserved words -            dos_header.e_res2[2]  = data.GetU16(&offset); // Reserved words -            dos_header.e_res2[3]  = data.GetU16(&offset); // Reserved words -            dos_header.e_res2[4]  = data.GetU16(&offset); // Reserved words -            dos_header.e_res2[5]  = data.GetU16(&offset); // Reserved words -            dos_header.e_res2[6]  = data.GetU16(&offset); // Reserved words -            dos_header.e_res2[7]  = data.GetU16(&offset); // Reserved words -            dos_header.e_res2[8]  = data.GetU16(&offset); // Reserved words -            dos_header.e_res2[9]  = data.GetU16(&offset); // Reserved words -             -            dos_header.e_lfanew   = data.GetU32(&offset); // File address of new exe header -        } +bool ObjectFilePECOFF::ParseDOSHeader(DataExtractor &data, +                                      dos_header_t &dos_header) { +  bool success = false; +  lldb::offset_t offset = 0; +  success = data.ValidOffsetForDataOfSize(0, sizeof(dos_header)); + +  if (success) { +    dos_header.e_magic = data.GetU16(&offset); // Magic number +    success = dos_header.e_magic == IMAGE_DOS_SIGNATURE; + +    if (success) { +      dos_header.e_cblp = data.GetU16(&offset); // Bytes on last page of file +      dos_header.e_cp = data.GetU16(&offset);   // Pages in file +      dos_header.e_crlc = data.GetU16(&offset); // Relocations +      dos_header.e_cparhdr = +          data.GetU16(&offset); // Size of header in paragraphs +      dos_header.e_minalloc = +          data.GetU16(&offset); // Minimum extra paragraphs needed +      dos_header.e_maxalloc = +          data.GetU16(&offset);               // Maximum extra paragraphs needed +      dos_header.e_ss = data.GetU16(&offset); // Initial (relative) SS value +      dos_header.e_sp = data.GetU16(&offset); // Initial SP value +      dos_header.e_csum = data.GetU16(&offset); // Checksum +      dos_header.e_ip = data.GetU16(&offset);   // Initial IP value +      dos_header.e_cs = data.GetU16(&offset);   // Initial (relative) CS value +      dos_header.e_lfarlc = +          data.GetU16(&offset); // File address of relocation table +      dos_header.e_ovno = data.GetU16(&offset); // Overlay number + +      dos_header.e_res[0] = data.GetU16(&offset); // Reserved words +      dos_header.e_res[1] = data.GetU16(&offset); // Reserved words +      dos_header.e_res[2] = data.GetU16(&offset); // Reserved words +      dos_header.e_res[3] = data.GetU16(&offset); // Reserved words + +      dos_header.e_oemid = +          data.GetU16(&offset); // OEM identifier (for e_oeminfo) +      dos_header.e_oeminfo = +          data.GetU16(&offset); // OEM information; e_oemid specific +      dos_header.e_res2[0] = data.GetU16(&offset); // Reserved words +      dos_header.e_res2[1] = data.GetU16(&offset); // Reserved words +      dos_header.e_res2[2] = data.GetU16(&offset); // Reserved words +      dos_header.e_res2[3] = data.GetU16(&offset); // Reserved words +      dos_header.e_res2[4] = data.GetU16(&offset); // Reserved words +      dos_header.e_res2[5] = data.GetU16(&offset); // Reserved words +      dos_header.e_res2[6] = data.GetU16(&offset); // Reserved words +      dos_header.e_res2[7] = data.GetU16(&offset); // Reserved words +      dos_header.e_res2[8] = data.GetU16(&offset); // Reserved words +      dos_header.e_res2[9] = data.GetU16(&offset); // Reserved words + +      dos_header.e_lfanew = +          data.GetU32(&offset); // File address of new exe header      } -    if (!success) -        memset(&dos_header, 0, sizeof(dos_header)); -    return success; +  } +  if (!success) +    memset(&dos_header, 0, sizeof(dos_header)); +  return success;  } -  //----------------------------------------------------------------------  // ParserCOFFHeader  //---------------------------------------------------------------------- -bool -ObjectFilePECOFF::ParseCOFFHeader(DataExtractor &data, lldb::offset_t *offset_ptr, coff_header_t &coff_header) -{ -    bool success = data.ValidOffsetForDataOfSize (*offset_ptr, sizeof(coff_header)); -    if (success) -    { -        coff_header.machine   = data.GetU16(offset_ptr); -        coff_header.nsects    = data.GetU16(offset_ptr); -        coff_header.modtime   = data.GetU32(offset_ptr); -        coff_header.symoff    = data.GetU32(offset_ptr); -        coff_header.nsyms     = data.GetU32(offset_ptr); -        coff_header.hdrsize   = data.GetU16(offset_ptr); -        coff_header.flags     = data.GetU16(offset_ptr); -    } -    if (!success) -        memset(&coff_header, 0, sizeof(coff_header)); -    return success; +bool ObjectFilePECOFF::ParseCOFFHeader(DataExtractor &data, +                                       lldb::offset_t *offset_ptr, +                                       coff_header_t &coff_header) { +  bool success = +      data.ValidOffsetForDataOfSize(*offset_ptr, sizeof(coff_header)); +  if (success) { +    coff_header.machine = data.GetU16(offset_ptr); +    coff_header.nsects = data.GetU16(offset_ptr); +    coff_header.modtime = data.GetU32(offset_ptr); +    coff_header.symoff = data.GetU32(offset_ptr); +    coff_header.nsyms = data.GetU32(offset_ptr); +    coff_header.hdrsize = data.GetU16(offset_ptr); +    coff_header.flags = data.GetU16(offset_ptr); +  } +  if (!success) +    memset(&coff_header, 0, sizeof(coff_header)); +  return success;  } -bool -ObjectFilePECOFF::ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr) -{ -    bool success = false; -    const lldb::offset_t end_offset = *offset_ptr + m_coff_header.hdrsize; -    if (*offset_ptr < end_offset) -    { -        success = true; -        m_coff_header_opt.magic                         = m_data.GetU16(offset_ptr);  -        m_coff_header_opt.major_linker_version          = m_data.GetU8 (offset_ptr); -        m_coff_header_opt.minor_linker_version          = m_data.GetU8 (offset_ptr);      -        m_coff_header_opt.code_size                     = m_data.GetU32(offset_ptr);  -        m_coff_header_opt.data_size                     = m_data.GetU32(offset_ptr);  -        m_coff_header_opt.bss_size                      = m_data.GetU32(offset_ptr);  -        m_coff_header_opt.entry                         = m_data.GetU32(offset_ptr);  -        m_coff_header_opt.code_offset                   = m_data.GetU32(offset_ptr);  - -        const uint32_t addr_byte_size = GetAddressByteSize (); - -        if (*offset_ptr < end_offset) -        { -            if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32) -            { -                // PE32 only -                m_coff_header_opt.data_offset               = m_data.GetU32(offset_ptr);                              -            } -            else -                m_coff_header_opt.data_offset = 0; -         -            if (*offset_ptr < end_offset) -            { -                m_coff_header_opt.image_base                    = m_data.GetMaxU64 (offset_ptr, addr_byte_size);  -                m_coff_header_opt.sect_alignment                = m_data.GetU32(offset_ptr);  -                m_coff_header_opt.file_alignment                = m_data.GetU32(offset_ptr);  -                m_coff_header_opt.major_os_system_version       = m_data.GetU16(offset_ptr);  -                m_coff_header_opt.minor_os_system_version       = m_data.GetU16(offset_ptr);  -                m_coff_header_opt.major_image_version           = m_data.GetU16(offset_ptr);  -                m_coff_header_opt.minor_image_version           = m_data.GetU16(offset_ptr);  -                m_coff_header_opt.major_subsystem_version       = m_data.GetU16(offset_ptr);  -                m_coff_header_opt.minor_subsystem_version       = m_data.GetU16(offset_ptr);  -                m_coff_header_opt.reserved1                     = m_data.GetU32(offset_ptr);  -                m_coff_header_opt.image_size                    = m_data.GetU32(offset_ptr);  -                m_coff_header_opt.header_size                   = m_data.GetU32(offset_ptr);  -                m_coff_header_opt.checksum                      = m_data.GetU32(offset_ptr);  -                m_coff_header_opt.subsystem                     = m_data.GetU16(offset_ptr);  -                m_coff_header_opt.dll_flags                     = m_data.GetU16(offset_ptr);  -                m_coff_header_opt.stack_reserve_size            = m_data.GetMaxU64 (offset_ptr, addr_byte_size); -                m_coff_header_opt.stack_commit_size             = m_data.GetMaxU64 (offset_ptr, addr_byte_size); -                m_coff_header_opt.heap_reserve_size             = m_data.GetMaxU64 (offset_ptr, addr_byte_size); -                m_coff_header_opt.heap_commit_size              = m_data.GetMaxU64 (offset_ptr, addr_byte_size); -                m_coff_header_opt.loader_flags                  = m_data.GetU32(offset_ptr);  -                uint32_t num_data_dir_entries = m_data.GetU32(offset_ptr); -                m_coff_header_opt.data_dirs.clear(); -                m_coff_header_opt.data_dirs.resize(num_data_dir_entries); -                uint32_t i; -                for (i=0; i<num_data_dir_entries; i++) -                { -                    m_coff_header_opt.data_dirs[i].vmaddr = m_data.GetU32(offset_ptr); -                    m_coff_header_opt.data_dirs[i].vmsize = m_data.GetU32(offset_ptr); -                } - -                m_file_offset = m_coff_header_opt.image_base; -                m_image_base = m_coff_header_opt.image_base; -            } +bool ObjectFilePECOFF::ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr) { +  bool success = false; +  const lldb::offset_t end_offset = *offset_ptr + m_coff_header.hdrsize; +  if (*offset_ptr < end_offset) { +    success = true; +    m_coff_header_opt.magic = m_data.GetU16(offset_ptr); +    m_coff_header_opt.major_linker_version = m_data.GetU8(offset_ptr); +    m_coff_header_opt.minor_linker_version = m_data.GetU8(offset_ptr); +    m_coff_header_opt.code_size = m_data.GetU32(offset_ptr); +    m_coff_header_opt.data_size = m_data.GetU32(offset_ptr); +    m_coff_header_opt.bss_size = m_data.GetU32(offset_ptr); +    m_coff_header_opt.entry = m_data.GetU32(offset_ptr); +    m_coff_header_opt.code_offset = m_data.GetU32(offset_ptr); + +    const uint32_t addr_byte_size = GetAddressByteSize(); + +    if (*offset_ptr < end_offset) { +      if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32) { +        // PE32 only +        m_coff_header_opt.data_offset = m_data.GetU32(offset_ptr); +      } else +        m_coff_header_opt.data_offset = 0; + +      if (*offset_ptr < end_offset) { +        m_coff_header_opt.image_base = +            m_data.GetMaxU64(offset_ptr, addr_byte_size); +        m_coff_header_opt.sect_alignment = m_data.GetU32(offset_ptr); +        m_coff_header_opt.file_alignment = m_data.GetU32(offset_ptr); +        m_coff_header_opt.major_os_system_version = m_data.GetU16(offset_ptr); +        m_coff_header_opt.minor_os_system_version = m_data.GetU16(offset_ptr); +        m_coff_header_opt.major_image_version = m_data.GetU16(offset_ptr); +        m_coff_header_opt.minor_image_version = m_data.GetU16(offset_ptr); +        m_coff_header_opt.major_subsystem_version = m_data.GetU16(offset_ptr); +        m_coff_header_opt.minor_subsystem_version = m_data.GetU16(offset_ptr); +        m_coff_header_opt.reserved1 = m_data.GetU32(offset_ptr); +        m_coff_header_opt.image_size = m_data.GetU32(offset_ptr); +        m_coff_header_opt.header_size = m_data.GetU32(offset_ptr); +        m_coff_header_opt.checksum = m_data.GetU32(offset_ptr); +        m_coff_header_opt.subsystem = m_data.GetU16(offset_ptr); +        m_coff_header_opt.dll_flags = m_data.GetU16(offset_ptr); +        m_coff_header_opt.stack_reserve_size = +            m_data.GetMaxU64(offset_ptr, addr_byte_size); +        m_coff_header_opt.stack_commit_size = +            m_data.GetMaxU64(offset_ptr, addr_byte_size); +        m_coff_header_opt.heap_reserve_size = +            m_data.GetMaxU64(offset_ptr, addr_byte_size); +        m_coff_header_opt.heap_commit_size = +            m_data.GetMaxU64(offset_ptr, addr_byte_size); +        m_coff_header_opt.loader_flags = m_data.GetU32(offset_ptr); +        uint32_t num_data_dir_entries = m_data.GetU32(offset_ptr); +        m_coff_header_opt.data_dirs.clear(); +        m_coff_header_opt.data_dirs.resize(num_data_dir_entries); +        uint32_t i; +        for (i = 0; i < num_data_dir_entries; i++) { +          m_coff_header_opt.data_dirs[i].vmaddr = m_data.GetU32(offset_ptr); +          m_coff_header_opt.data_dirs[i].vmsize = m_data.GetU32(offset_ptr);          } + +        m_file_offset = m_coff_header_opt.image_base; +        m_image_base = m_coff_header_opt.image_base; +      }      } -    // Make sure we are on track for section data which follows -    *offset_ptr = end_offset; -    return success; +  } +  // Make sure we are on track for section data which follows +  *offset_ptr = end_offset; +  return success;  } +DataExtractor ObjectFilePECOFF::ReadImageData(uint32_t offset, size_t size) { +  if (m_file) { +    DataBufferSP buffer_sp(m_file.ReadFileContents(offset, size)); +    return DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize()); +  } +  ProcessSP process_sp(m_process_wp.lock()); +  DataExtractor data; +  if (process_sp) { +    auto data_ap = llvm::make_unique<DataBufferHeap>(size, 0); +    Error readmem_error; +    size_t bytes_read = +        process_sp->ReadMemory(m_image_base + offset, data_ap->GetBytes(), +                               data_ap->GetByteSize(), readmem_error); +    if (bytes_read == size) { +      DataBufferSP buffer_sp(data_ap.release()); +      data.SetData(buffer_sp, 0, buffer_sp->GetByteSize()); +    } +  } +  return data; +}  //----------------------------------------------------------------------  // ParseSectionHeaders  //---------------------------------------------------------------------- -bool -ObjectFilePECOFF::ParseSectionHeaders (uint32_t section_header_data_offset) -{ -    const uint32_t nsects = m_coff_header.nsects; -    m_sect_headers.clear(); -     -    if (nsects > 0) -    { -        const uint32_t addr_byte_size = GetAddressByteSize (); -        const size_t section_header_byte_size = nsects * sizeof(section_header_t); -        DataBufferSP section_header_data_sp(m_file.ReadFileContents (section_header_data_offset, section_header_byte_size)); -        DataExtractor section_header_data (section_header_data_sp, GetByteOrder(), addr_byte_size); +bool ObjectFilePECOFF::ParseSectionHeaders( +    uint32_t section_header_data_offset) { +  const uint32_t nsects = m_coff_header.nsects; +  m_sect_headers.clear(); -        lldb::offset_t offset = 0; -        if (section_header_data.ValidOffsetForDataOfSize (offset, section_header_byte_size)) -        { -            m_sect_headers.resize(nsects); -             -            for (uint32_t idx = 0; idx<nsects; ++idx) -            { -                const void *name_data = section_header_data.GetData(&offset, 8); -                if (name_data) -                { -                    memcpy(m_sect_headers[idx].name, name_data, 8); -                    m_sect_headers[idx].vmsize  = section_header_data.GetU32(&offset); -                    m_sect_headers[idx].vmaddr  = section_header_data.GetU32(&offset); -                    m_sect_headers[idx].size    = section_header_data.GetU32(&offset); -                    m_sect_headers[idx].offset  = section_header_data.GetU32(&offset); -                    m_sect_headers[idx].reloff  = section_header_data.GetU32(&offset); -                    m_sect_headers[idx].lineoff = section_header_data.GetU32(&offset); -                    m_sect_headers[idx].nreloc  = section_header_data.GetU16(&offset); -                    m_sect_headers[idx].nline   = section_header_data.GetU16(&offset); -                    m_sect_headers[idx].flags   = section_header_data.GetU32(&offset); -                } -            } +  if (nsects > 0) { +    const size_t section_header_byte_size = nsects * sizeof(section_header_t); +    DataExtractor section_header_data = +        ReadImageData(section_header_data_offset, section_header_byte_size); + +    lldb::offset_t offset = 0; +    if (section_header_data.ValidOffsetForDataOfSize( +            offset, section_header_byte_size)) { +      m_sect_headers.resize(nsects); + +      for (uint32_t idx = 0; idx < nsects; ++idx) { +        const void *name_data = section_header_data.GetData(&offset, 8); +        if (name_data) { +          memcpy(m_sect_headers[idx].name, name_data, 8); +          m_sect_headers[idx].vmsize = section_header_data.GetU32(&offset); +          m_sect_headers[idx].vmaddr = section_header_data.GetU32(&offset); +          m_sect_headers[idx].size = section_header_data.GetU32(&offset); +          m_sect_headers[idx].offset = section_header_data.GetU32(&offset); +          m_sect_headers[idx].reloff = section_header_data.GetU32(&offset); +          m_sect_headers[idx].lineoff = section_header_data.GetU32(&offset); +          m_sect_headers[idx].nreloc = section_header_data.GetU16(&offset); +          m_sect_headers[idx].nline = section_header_data.GetU16(&offset); +          m_sect_headers[idx].flags = section_header_data.GetU32(&offset);          } +      }      } -     -    return m_sect_headers.empty() == false; +  } + +  return m_sect_headers.empty() == false;  } -bool -ObjectFilePECOFF::GetSectionName(std::string& sect_name, const section_header_t& sect) -{ -    if (sect.name[0] == '/') -    { -        lldb::offset_t stroff = strtoul(§.name[1], NULL, 10); -        lldb::offset_t string_file_offset = m_coff_header.symoff + (m_coff_header.nsyms * 18) + stroff; -        const char *name = m_data.GetCStr (&string_file_offset); -        if (name) -        { -            sect_name = name; -            return true; -        } -         -        return false; +bool ObjectFilePECOFF::GetSectionName(std::string §_name, +                                      const section_header_t §) { +  if (sect.name[0] == '/') { +    lldb::offset_t stroff = strtoul(§.name[1], NULL, 10); +    lldb::offset_t string_file_offset = +        m_coff_header.symoff + (m_coff_header.nsyms * 18) + stroff; +    const char *name = m_data.GetCStr(&string_file_offset); +    if (name) { +      sect_name = name; +      return true;      } -    sect_name = sect.name; -    return true; -}        + +    return false; +  } +  sect_name = sect.name; +  return true; +}  //----------------------------------------------------------------------  // GetNListSymtab  //---------------------------------------------------------------------- -Symtab * -ObjectFilePECOFF::GetSymtab() -{ -    ModuleSP module_sp(GetModule()); -    if (module_sp) -    { -        std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); -        if (m_symtab_ap.get() == NULL) -        { -            SectionList *sect_list = GetSectionList(); -            m_symtab_ap.reset(new Symtab(this)); -            std::lock_guard<std::recursive_mutex> guard(m_symtab_ap->GetMutex()); - -            const uint32_t num_syms = m_coff_header.nsyms; - -            if (num_syms > 0 && m_coff_header.symoff > 0) -            { -                const uint32_t symbol_size = 18; -                const uint32_t addr_byte_size = GetAddressByteSize (); -                const size_t symbol_data_size = num_syms * symbol_size; -                // Include the 4-byte string table size at the end of the symbols -                DataBufferSP symtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff, symbol_data_size + 4)); -                DataExtractor symtab_data (symtab_data_sp, GetByteOrder(), addr_byte_size); -                lldb::offset_t offset = symbol_data_size; -                const uint32_t strtab_size = symtab_data.GetU32 (&offset); -                DataBufferSP strtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff + symbol_data_size, strtab_size)); -                DataExtractor strtab_data (strtab_data_sp, GetByteOrder(), addr_byte_size); - -                // First 4 bytes should be zeroed after strtab_size has been read, -                // because it is used as offset 0 to encode a NULL string. -                uint32_t* strtab_data_start = (uint32_t*)strtab_data_sp->GetBytes(); -                strtab_data_start[0] = 0; - -                offset = 0; -                std::string symbol_name; -                Symbol *symbols = m_symtab_ap->Resize (num_syms); -                for (uint32_t i=0; i<num_syms; ++i) -                { -                    coff_symbol_t symbol; -                    const uint32_t symbol_offset = offset; -                    const char *symbol_name_cstr = NULL; -                    // If the first 4 bytes of the symbol string are zero, then they -                    // are followed by a 4-byte string table offset. Else these -                    // 8 bytes contain the symbol name -                    if (symtab_data.GetU32 (&offset) == 0) -                    { -                        // Long string that doesn't fit into the symbol table name, -                        // so now we must read the 4 byte string table offset -                        uint32_t strtab_offset = symtab_data.GetU32 (&offset); -                        symbol_name_cstr = strtab_data.PeekCStr (strtab_offset); -                        symbol_name.assign (symbol_name_cstr); -                    } -                    else -                    { -                        // Short string that fits into the symbol table name which is 8 bytes -                        offset += sizeof(symbol.name) - 4; // Skip remaining  -                        symbol_name_cstr = symtab_data.PeekCStr (symbol_offset); -                        if (symbol_name_cstr == NULL) -                            break; -                        symbol_name.assign (symbol_name_cstr, sizeof(symbol.name)); -                    } -                    symbol.value    = symtab_data.GetU32 (&offset); -                    symbol.sect     = symtab_data.GetU16 (&offset); -                    symbol.type     = symtab_data.GetU16 (&offset); -                    symbol.storage  = symtab_data.GetU8  (&offset); -                    symbol.naux     = symtab_data.GetU8  (&offset);		 -                    symbols[i].GetMangled ().SetValue (ConstString(symbol_name.c_str())); -                    if ((int16_t)symbol.sect >= 1) -                    { -                        Address symbol_addr(sect_list->GetSectionAtIndex(symbol.sect-1), symbol.value); -                        symbols[i].GetAddressRef() = symbol_addr; -                        symbols[i].SetType(MapSymbolType(symbol.type)); -                    } - -                    if (symbol.naux > 0) -                    { -                        i += symbol.naux; -                        offset += symbol_size; -                    } -                } -                 +Symtab *ObjectFilePECOFF::GetSymtab() { +  ModuleSP module_sp(GetModule()); +  if (module_sp) { +    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); +    if (m_symtab_ap.get() == NULL) { +      SectionList *sect_list = GetSectionList(); +      m_symtab_ap.reset(new Symtab(this)); +      std::lock_guard<std::recursive_mutex> guard(m_symtab_ap->GetMutex()); + +      const uint32_t num_syms = m_coff_header.nsyms; + +      if (m_file && num_syms > 0 && m_coff_header.symoff > 0) { +        const uint32_t symbol_size = 18; +        const size_t symbol_data_size = num_syms * symbol_size; +        // Include the 4-byte string table size at the end of the symbols +        DataExtractor symtab_data = +            ReadImageData(m_coff_header.symoff, symbol_data_size + 4); +        lldb::offset_t offset = symbol_data_size; +        const uint32_t strtab_size = symtab_data.GetU32(&offset); +        if (strtab_size > 0) { +          DataExtractor strtab_data = ReadImageData( +              m_coff_header.symoff + symbol_data_size, strtab_size); + +          // First 4 bytes should be zeroed after strtab_size has been read, +          // because it is used as offset 0 to encode a NULL string. +          uint32_t *strtab_data_start = (uint32_t *)strtab_data.GetDataStart(); +          strtab_data_start[0] = 0; + +          offset = 0; +          std::string symbol_name; +          Symbol *symbols = m_symtab_ap->Resize(num_syms); +          for (uint32_t i = 0; i < num_syms; ++i) { +            coff_symbol_t symbol; +            const uint32_t symbol_offset = offset; +            const char *symbol_name_cstr = NULL; +            // If the first 4 bytes of the symbol string are zero, then they +            // are followed by a 4-byte string table offset. Else these +            // 8 bytes contain the symbol name +            if (symtab_data.GetU32(&offset) == 0) { +              // Long string that doesn't fit into the symbol table name, +              // so now we must read the 4 byte string table offset +              uint32_t strtab_offset = symtab_data.GetU32(&offset); +              symbol_name_cstr = strtab_data.PeekCStr(strtab_offset); +              symbol_name.assign(symbol_name_cstr); +            } else { +              // Short string that fits into the symbol table name which is 8 +              // bytes +              offset += sizeof(symbol.name) - 4; // Skip remaining +              symbol_name_cstr = symtab_data.PeekCStr(symbol_offset); +              if (symbol_name_cstr == NULL) +                break; +              symbol_name.assign(symbol_name_cstr, sizeof(symbol.name)); +            } +            symbol.value = symtab_data.GetU32(&offset); +            symbol.sect = symtab_data.GetU16(&offset); +            symbol.type = symtab_data.GetU16(&offset); +            symbol.storage = symtab_data.GetU8(&offset); +            symbol.naux = symtab_data.GetU8(&offset); +            symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str())); +            if ((int16_t)symbol.sect >= 1) { +              Address symbol_addr(sect_list->GetSectionAtIndex(symbol.sect - 1), +                                  symbol.value); +              symbols[i].GetAddressRef() = symbol_addr; +              symbols[i].SetType(MapSymbolType(symbol.type));              } -            // Read export header -            if (coff_data_dir_export_table < m_coff_header_opt.data_dirs.size() -                && m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmsize > 0 && m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr > 0) -            { -                export_directory_entry export_table; -                uint32_t data_start = m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr; -                Address address(m_coff_header_opt.image_base + data_start, sect_list); -                DataBufferSP symtab_data_sp(m_file.ReadFileContents(address.GetSection()->GetFileOffset() + address.GetOffset(), m_coff_header_opt.data_dirs[0].vmsize)); -                DataExtractor symtab_data (symtab_data_sp, GetByteOrder(), GetAddressByteSize()); -                lldb::offset_t offset = 0; - -                // Read export_table header -                export_table.characteristics = symtab_data.GetU32(&offset); -                export_table.time_date_stamp = symtab_data.GetU32(&offset); -                export_table.major_version = symtab_data.GetU16(&offset); -                export_table.minor_version = symtab_data.GetU16(&offset); -                export_table.name = symtab_data.GetU32(&offset); -                export_table.base = symtab_data.GetU32(&offset); -                export_table.number_of_functions = symtab_data.GetU32(&offset); -                export_table.number_of_names = symtab_data.GetU32(&offset); -                export_table.address_of_functions = symtab_data.GetU32(&offset); -                export_table.address_of_names = symtab_data.GetU32(&offset); -                export_table.address_of_name_ordinals = symtab_data.GetU32(&offset); - -                bool has_ordinal = export_table.address_of_name_ordinals != 0; - -                lldb::offset_t name_offset = export_table.address_of_names - data_start; -                lldb::offset_t name_ordinal_offset = export_table.address_of_name_ordinals - data_start; - -                Symbol *symbols = m_symtab_ap->Resize(export_table.number_of_names); - -                std::string symbol_name; - -                // Read each export table entry -                for (size_t i = 0; i < export_table.number_of_names; ++i) -                { -                    uint32_t name_ordinal = has_ordinal ? symtab_data.GetU16(&name_ordinal_offset) : i; -                    uint32_t name_address = symtab_data.GetU32(&name_offset); - -                    const char* symbol_name_cstr = symtab_data.PeekCStr(name_address - data_start); -                    symbol_name.assign(symbol_name_cstr); - -                    lldb::offset_t function_offset = export_table.address_of_functions - data_start + sizeof(uint32_t) * name_ordinal; -                    uint32_t function_rva = symtab_data.GetU32(&function_offset); - -                    Address symbol_addr(m_coff_header_opt.image_base + function_rva, sect_list); -                    symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str())); -                    symbols[i].GetAddressRef() = symbol_addr; -                    symbols[i].SetType(lldb::eSymbolTypeCode); -                    symbols[i].SetDebug(true); -                } +            if (symbol.naux > 0) { +              i += symbol.naux; +              offset += symbol_size;              } -            m_symtab_ap->CalculateSymbolSizes(); +          }          } -    } -    return m_symtab_ap.get(); +      } + +      // Read export header +      if (coff_data_dir_export_table < m_coff_header_opt.data_dirs.size() && +          m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmsize > 0 && +          m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr > 0) { +        export_directory_entry export_table; +        uint32_t data_start = +            m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr; + +        uint32_t address_rva = data_start; +        if (m_file) { +          Address address(m_coff_header_opt.image_base + data_start, sect_list); +          address_rva = +              address.GetSection()->GetFileOffset() + address.GetOffset(); +        } +        DataExtractor symtab_data = +            ReadImageData(address_rva, m_coff_header_opt.data_dirs[0].vmsize); +        lldb::offset_t offset = 0; +        // Read export_table header +        export_table.characteristics = symtab_data.GetU32(&offset); +        export_table.time_date_stamp = symtab_data.GetU32(&offset); +        export_table.major_version = symtab_data.GetU16(&offset); +        export_table.minor_version = symtab_data.GetU16(&offset); +        export_table.name = symtab_data.GetU32(&offset); +        export_table.base = symtab_data.GetU32(&offset); +        export_table.number_of_functions = symtab_data.GetU32(&offset); +        export_table.number_of_names = symtab_data.GetU32(&offset); +        export_table.address_of_functions = symtab_data.GetU32(&offset); +        export_table.address_of_names = symtab_data.GetU32(&offset); +        export_table.address_of_name_ordinals = symtab_data.GetU32(&offset); + +        bool has_ordinal = export_table.address_of_name_ordinals != 0; + +        lldb::offset_t name_offset = export_table.address_of_names - data_start; +        lldb::offset_t name_ordinal_offset = +            export_table.address_of_name_ordinals - data_start; + +        Symbol *symbols = m_symtab_ap->Resize(export_table.number_of_names); + +        std::string symbol_name; + +        // Read each export table entry +        for (size_t i = 0; i < export_table.number_of_names; ++i) { +          uint32_t name_ordinal = +              has_ordinal ? symtab_data.GetU16(&name_ordinal_offset) : i; +          uint32_t name_address = symtab_data.GetU32(&name_offset); + +          const char *symbol_name_cstr = +              symtab_data.PeekCStr(name_address - data_start); +          symbol_name.assign(symbol_name_cstr); + +          lldb::offset_t function_offset = export_table.address_of_functions - +                                           data_start + +                                           sizeof(uint32_t) * name_ordinal; +          uint32_t function_rva = symtab_data.GetU32(&function_offset); + +          Address symbol_addr(m_coff_header_opt.image_base + function_rva, +                              sect_list); +          symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str())); +          symbols[i].GetAddressRef() = symbol_addr; +          symbols[i].SetType(lldb::eSymbolTypeCode); +          symbols[i].SetDebug(true); +        } +      } +      m_symtab_ap->CalculateSymbolSizes(); +    } +  } +  return m_symtab_ap.get();  } -bool -ObjectFilePECOFF::IsStripped () -{ -    // TODO: determine this for COFF -    return false; +bool ObjectFilePECOFF::IsStripped() { +  // TODO: determine this for COFF +  return false;  } +void ObjectFilePECOFF::CreateSections(SectionList &unified_section_list) { +  if (!m_sections_ap.get()) { +    m_sections_ap.reset(new SectionList()); - -void -ObjectFilePECOFF::CreateSections (SectionList &unified_section_list) -{ -    if (!m_sections_ap.get()) -    { -        m_sections_ap.reset(new SectionList()); - -        ModuleSP module_sp(GetModule()); -        if (module_sp) -        { -            std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); -            const uint32_t nsects = m_sect_headers.size(); -            ModuleSP module_sp (GetModule()); -            for (uint32_t idx = 0; idx<nsects; ++idx) -            { -                std::string sect_name; -                GetSectionName (sect_name, m_sect_headers[idx]); -                ConstString const_sect_name (sect_name.c_str()); -                static ConstString g_code_sect_name (".code"); -                static ConstString g_CODE_sect_name ("CODE"); -                static ConstString g_data_sect_name (".data"); -                static ConstString g_DATA_sect_name ("DATA"); -                static ConstString g_bss_sect_name (".bss"); -                static ConstString g_BSS_sect_name ("BSS"); -                static ConstString g_debug_sect_name (".debug"); -                static ConstString g_reloc_sect_name (".reloc"); -                static ConstString g_stab_sect_name (".stab"); -                static ConstString g_stabstr_sect_name (".stabstr"); -                static ConstString g_sect_name_dwarf_debug_abbrev (".debug_abbrev"); -                static ConstString g_sect_name_dwarf_debug_aranges (".debug_aranges"); -                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_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_eh_frame (".eh_frame"); -                static ConstString g_sect_name_go_symtab (".gosymtab"); -                SectionType section_type = eSectionTypeOther; -                if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_CODE && -                    ((const_sect_name == g_code_sect_name) || (const_sect_name == g_CODE_sect_name))) -                { -                    section_type = eSectionTypeCode; -                } -                else if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA && -                         ((const_sect_name == g_data_sect_name) || (const_sect_name == g_DATA_sect_name))) -                { -                    section_type = eSectionTypeData; -                } -                else if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA && -                         ((const_sect_name == g_bss_sect_name) || (const_sect_name == g_BSS_sect_name))) -                { -                    if (m_sect_headers[idx].size == 0) -                        section_type = eSectionTypeZeroFill; -                    else -                        section_type = eSectionTypeData; -                } -                else if (const_sect_name == g_debug_sect_name) -                { -                    section_type = eSectionTypeDebug; -                } -                else if (const_sect_name == g_stabstr_sect_name) -                { -                    section_type = eSectionTypeDataCString; -                } -                else if (const_sect_name == g_reloc_sect_name) -                { -                    section_type = eSectionTypeOther; -                } -                else if (const_sect_name == g_sect_name_dwarf_debug_abbrev)    section_type = eSectionTypeDWARFDebugAbbrev; -                else if (const_sect_name == g_sect_name_dwarf_debug_aranges)   section_type = eSectionTypeDWARFDebugAranges; -                else if (const_sect_name == g_sect_name_dwarf_debug_frame)     section_type = eSectionTypeDWARFDebugFrame; -                else if (const_sect_name == g_sect_name_dwarf_debug_info)      section_type = eSectionTypeDWARFDebugInfo; -                else if (const_sect_name == g_sect_name_dwarf_debug_line)      section_type = eSectionTypeDWARFDebugLine; -                else if (const_sect_name == g_sect_name_dwarf_debug_loc)       section_type = eSectionTypeDWARFDebugLoc; -                else if (const_sect_name == g_sect_name_dwarf_debug_macinfo)   section_type = eSectionTypeDWARFDebugMacInfo; -                else if (const_sect_name == g_sect_name_dwarf_debug_pubnames)  section_type = eSectionTypeDWARFDebugPubNames; -                else if (const_sect_name == g_sect_name_dwarf_debug_pubtypes)  section_type = eSectionTypeDWARFDebugPubTypes; -                else if (const_sect_name == g_sect_name_dwarf_debug_ranges)    section_type = eSectionTypeDWARFDebugRanges; -                else if (const_sect_name == g_sect_name_dwarf_debug_str)       section_type = eSectionTypeDWARFDebugStr; -                else if (const_sect_name == g_sect_name_eh_frame)              section_type = eSectionTypeEHFrame; -                else if (const_sect_name == g_sect_name_go_symtab)             section_type = eSectionTypeGoSymtab; -                else if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_CODE) -                { -                    section_type = eSectionTypeCode; -                } -                else if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) -                { -                    section_type = eSectionTypeData; -                } -                else if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) -                { -                    if (m_sect_headers[idx].size == 0) -                        section_type = eSectionTypeZeroFill; -                    else -                        section_type = eSectionTypeData; -                } - -                // Use a segment ID of the segment index shifted left by 8 so they -                // never conflict with any of the sections. -                SectionSP section_sp (new Section (module_sp,                    // Module to which this section belongs -                                                   this,                         // Object file to which this section belongs -                                                   idx + 1,                      // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible -                                                   const_sect_name,              // Name of this section -                                                   section_type,                 // This section is a container of other sections. -                                                   m_coff_header_opt.image_base + m_sect_headers[idx].vmaddr,   // File VM address == addresses as they are found in the object file -                                                   m_sect_headers[idx].vmsize,   // VM size in bytes of this section -                                                   m_sect_headers[idx].offset,   // Offset to the data for this section in the file -                                                   m_sect_headers[idx].size,     // Size in bytes of this section as found in the file -                                                   m_coff_header_opt.sect_alignment, // Section alignment -                                                   m_sect_headers[idx].flags));  // Flags for this section - -                //section_sp->SetIsEncrypted (segment_is_encrypted); - -                unified_section_list.AddSection(section_sp); -                m_sections_ap->AddSection (section_sp); -            } +    ModuleSP module_sp(GetModule()); +    if (module_sp) { +      std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); +      const uint32_t nsects = m_sect_headers.size(); +      ModuleSP module_sp(GetModule()); +      for (uint32_t idx = 0; idx < nsects; ++idx) { +        std::string sect_name; +        GetSectionName(sect_name, m_sect_headers[idx]); +        ConstString const_sect_name(sect_name.c_str()); +        static ConstString g_code_sect_name(".code"); +        static ConstString g_CODE_sect_name("CODE"); +        static ConstString g_data_sect_name(".data"); +        static ConstString g_DATA_sect_name("DATA"); +        static ConstString g_bss_sect_name(".bss"); +        static ConstString g_BSS_sect_name("BSS"); +        static ConstString g_debug_sect_name(".debug"); +        static ConstString g_reloc_sect_name(".reloc"); +        static ConstString g_stab_sect_name(".stab"); +        static ConstString g_stabstr_sect_name(".stabstr"); +        static ConstString g_sect_name_dwarf_debug_abbrev(".debug_abbrev"); +        static ConstString g_sect_name_dwarf_debug_aranges(".debug_aranges"); +        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_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_eh_frame(".eh_frame"); +        static ConstString g_sect_name_go_symtab(".gosymtab"); +        SectionType section_type = eSectionTypeOther; +        if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_CODE && +            ((const_sect_name == g_code_sect_name) || +             (const_sect_name == g_CODE_sect_name))) { +          section_type = eSectionTypeCode; +        } else if (m_sect_headers[idx].flags & +                       llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA && +                   ((const_sect_name == g_data_sect_name) || +                    (const_sect_name == g_DATA_sect_name))) { +          section_type = eSectionTypeData; +        } else if (m_sect_headers[idx].flags & +                       llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA && +                   ((const_sect_name == g_bss_sect_name) || +                    (const_sect_name == g_BSS_sect_name))) { +          if (m_sect_headers[idx].size == 0) +            section_type = eSectionTypeZeroFill; +          else +            section_type = eSectionTypeData; +        } else if (const_sect_name == g_debug_sect_name) { +          section_type = eSectionTypeDebug; +        } else if (const_sect_name == g_stabstr_sect_name) { +          section_type = eSectionTypeDataCString; +        } else if (const_sect_name == g_reloc_sect_name) { +          section_type = eSectionTypeOther; +        } else if (const_sect_name == g_sect_name_dwarf_debug_abbrev) +          section_type = eSectionTypeDWARFDebugAbbrev; +        else if (const_sect_name == g_sect_name_dwarf_debug_aranges) +          section_type = eSectionTypeDWARFDebugAranges; +        else if (const_sect_name == g_sect_name_dwarf_debug_frame) +          section_type = eSectionTypeDWARFDebugFrame; +        else if (const_sect_name == g_sect_name_dwarf_debug_info) +          section_type = eSectionTypeDWARFDebugInfo; +        else if (const_sect_name == g_sect_name_dwarf_debug_line) +          section_type = eSectionTypeDWARFDebugLine; +        else if (const_sect_name == g_sect_name_dwarf_debug_loc) +          section_type = eSectionTypeDWARFDebugLoc; +        else if (const_sect_name == g_sect_name_dwarf_debug_macinfo) +          section_type = eSectionTypeDWARFDebugMacInfo; +        else if (const_sect_name == g_sect_name_dwarf_debug_pubnames) +          section_type = eSectionTypeDWARFDebugPubNames; +        else if (const_sect_name == g_sect_name_dwarf_debug_pubtypes) +          section_type = eSectionTypeDWARFDebugPubTypes; +        else if (const_sect_name == g_sect_name_dwarf_debug_ranges) +          section_type = eSectionTypeDWARFDebugRanges; +        else if (const_sect_name == g_sect_name_dwarf_debug_str) +          section_type = eSectionTypeDWARFDebugStr; +        else if (const_sect_name == g_sect_name_eh_frame) +          section_type = eSectionTypeEHFrame; +        else if (const_sect_name == g_sect_name_go_symtab) +          section_type = eSectionTypeGoSymtab; +        else if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_CODE) { +          section_type = eSectionTypeCode; +        } else if (m_sect_headers[idx].flags & +                   llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) { +          section_type = eSectionTypeData; +        } else if (m_sect_headers[idx].flags & +                   llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) { +          if (m_sect_headers[idx].size == 0) +            section_type = eSectionTypeZeroFill; +          else +            section_type = eSectionTypeData;          } + +        // Use a segment ID of the segment index shifted left by 8 so they +        // never conflict with any of the sections. +        SectionSP section_sp(new Section( +            module_sp, // Module to which this section belongs +            this,      // Object file to which this section belongs +            idx + 1, // Section ID is the 1 based segment index shifted right by +                     // 8 bits as not to collide with any of the 256 section IDs +                     // that are possible +            const_sect_name, // Name of this section +            section_type,    // This section is a container of other sections. +            m_coff_header_opt.image_base + +                m_sect_headers[idx].vmaddr, // File VM address == addresses as +                                            // they are found in the object file +            m_sect_headers[idx].vmsize,     // VM size in bytes of this section +            m_sect_headers[idx] +                .offset, // Offset to the data for this section in the file +            m_sect_headers[idx] +                .size, // Size in bytes of this section as found in the file +            m_coff_header_opt.sect_alignment, // Section alignment +            m_sect_headers[idx].flags));      // Flags for this section + +        // section_sp->SetIsEncrypted (segment_is_encrypted); + +        unified_section_list.AddSection(section_sp); +        m_sections_ap->AddSection(section_sp); +      }      } +  }  } -bool -ObjectFilePECOFF::GetUUID (UUID* uuid) -{ -    return false; -} +bool ObjectFilePECOFF::GetUUID(UUID *uuid) { return false; } -uint32_t -ObjectFilePECOFF::GetDependentModules (FileSpecList& files) -{ -    return 0; +uint32_t ObjectFilePECOFF::GetDependentModules(FileSpecList &files) { +  return 0;  } -lldb_private::Address -ObjectFilePECOFF::GetEntryPointAddress () -{ -    if (m_entry_point_address.IsValid()) -        return m_entry_point_address; +lldb_private::Address ObjectFilePECOFF::GetEntryPointAddress() { +  if (m_entry_point_address.IsValid()) +    return m_entry_point_address; -    if (!ParseHeader() || !IsExecutable()) -        return m_entry_point_address; +  if (!ParseHeader() || !IsExecutable()) +    return m_entry_point_address; -    SectionList *section_list = GetSectionList(); -    addr_t offset = m_coff_header_opt.entry; +  SectionList *section_list = GetSectionList(); +  addr_t offset = m_coff_header_opt.entry; -    if (!section_list) -        m_entry_point_address.SetOffset(offset); -    else -        m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list); -    return m_entry_point_address; +  if (!section_list) +    m_entry_point_address.SetOffset(offset); +  else +    m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list); +  return m_entry_point_address;  } -  //----------------------------------------------------------------------  // Dump  //  // Dump the specifics of the runtime file container (such as any headers  // segments, sections, etc).  //---------------------------------------------------------------------- -void  -ObjectFilePECOFF::Dump(Stream *s) -{ -    ModuleSP module_sp(GetModule()); -    if (module_sp) -    { -        std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); -        s->Printf("%p: ", static_cast<void*>(this)); -        s->Indent(); -        s->PutCString("ObjectFilePECOFF"); - -        ArchSpec header_arch; -        GetArchitecture (header_arch); - -        *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n"; - -        SectionList *sections = GetSectionList(); -        if (sections) -            sections->Dump(s, NULL, true, UINT32_MAX); - -        if (m_symtab_ap.get()) -            m_symtab_ap->Dump(s, NULL, eSortOrderNone); - -        if (m_dos_header.e_magic) -            DumpDOSHeader (s, m_dos_header); -        if (m_coff_header.machine) -        { -            DumpCOFFHeader (s, m_coff_header); -            if (m_coff_header.hdrsize) -                DumpOptCOFFHeader (s, m_coff_header_opt); -        } -        s->EOL(); -        DumpSectionHeaders(s); -        s->EOL(); +void ObjectFilePECOFF::Dump(Stream *s) { +  ModuleSP module_sp(GetModule()); +  if (module_sp) { +    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); +    s->Printf("%p: ", static_cast<void *>(this)); +    s->Indent(); +    s->PutCString("ObjectFilePECOFF"); + +    ArchSpec header_arch; +    GetArchitecture(header_arch); + +    *s << ", file = '" << m_file +       << "', arch = " << header_arch.GetArchitectureName() << "\n"; + +    SectionList *sections = GetSectionList(); +    if (sections) +      sections->Dump(s, NULL, true, UINT32_MAX); + +    if (m_symtab_ap.get()) +      m_symtab_ap->Dump(s, NULL, eSortOrderNone); + +    if (m_dos_header.e_magic) +      DumpDOSHeader(s, m_dos_header); +    if (m_coff_header.machine) { +      DumpCOFFHeader(s, m_coff_header); +      if (m_coff_header.hdrsize) +        DumpOptCOFFHeader(s, m_coff_header_opt);      } +    s->EOL(); +    DumpSectionHeaders(s); +    s->EOL(); +  }  }  //---------------------------------------------------------------------- @@ -883,43 +843,33 @@ ObjectFilePECOFF::Dump(Stream *s)  //  // Dump the MS-DOS header to the specified output stream  //---------------------------------------------------------------------- -void -ObjectFilePECOFF::DumpDOSHeader(Stream *s, const dos_header_t& header) -{ -    s->PutCString ("MSDOS Header\n"); -    s->Printf ("  e_magic    = 0x%4.4x\n", header.e_magic); -    s->Printf ("  e_cblp     = 0x%4.4x\n", header.e_cblp); -    s->Printf ("  e_cp       = 0x%4.4x\n", header.e_cp); -    s->Printf ("  e_crlc     = 0x%4.4x\n", header.e_crlc); -    s->Printf ("  e_cparhdr  = 0x%4.4x\n", header.e_cparhdr); -    s->Printf ("  e_minalloc = 0x%4.4x\n", header.e_minalloc); -    s->Printf ("  e_maxalloc = 0x%4.4x\n", header.e_maxalloc); -    s->Printf ("  e_ss       = 0x%4.4x\n", header.e_ss); -    s->Printf ("  e_sp       = 0x%4.4x\n", header.e_sp); -    s->Printf ("  e_csum     = 0x%4.4x\n", header.e_csum); -    s->Printf ("  e_ip       = 0x%4.4x\n", header.e_ip); -    s->Printf ("  e_cs       = 0x%4.4x\n", header.e_cs); -    s->Printf ("  e_lfarlc   = 0x%4.4x\n", header.e_lfarlc); -    s->Printf ("  e_ovno     = 0x%4.4x\n", header.e_ovno); -    s->Printf ("  e_res[4]   = { 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x }\n", -               header.e_res[0], -               header.e_res[1], -               header.e_res[2], -               header.e_res[3]); -    s->Printf ("  e_oemid    = 0x%4.4x\n", header.e_oemid); -    s->Printf ("  e_oeminfo  = 0x%4.4x\n", header.e_oeminfo); -    s->Printf ("  e_res2[10] = { 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x }\n", -               header.e_res2[0], -               header.e_res2[1], -               header.e_res2[2], -               header.e_res2[3], -               header.e_res2[4], -               header.e_res2[5], -               header.e_res2[6], -               header.e_res2[7], -               header.e_res2[8], -               header.e_res2[9]); -    s->Printf ("  e_lfanew   = 0x%8.8x\n", header.e_lfanew); +void ObjectFilePECOFF::DumpDOSHeader(Stream *s, const dos_header_t &header) { +  s->PutCString("MSDOS Header\n"); +  s->Printf("  e_magic    = 0x%4.4x\n", header.e_magic); +  s->Printf("  e_cblp     = 0x%4.4x\n", header.e_cblp); +  s->Printf("  e_cp       = 0x%4.4x\n", header.e_cp); +  s->Printf("  e_crlc     = 0x%4.4x\n", header.e_crlc); +  s->Printf("  e_cparhdr  = 0x%4.4x\n", header.e_cparhdr); +  s->Printf("  e_minalloc = 0x%4.4x\n", header.e_minalloc); +  s->Printf("  e_maxalloc = 0x%4.4x\n", header.e_maxalloc); +  s->Printf("  e_ss       = 0x%4.4x\n", header.e_ss); +  s->Printf("  e_sp       = 0x%4.4x\n", header.e_sp); +  s->Printf("  e_csum     = 0x%4.4x\n", header.e_csum); +  s->Printf("  e_ip       = 0x%4.4x\n", header.e_ip); +  s->Printf("  e_cs       = 0x%4.4x\n", header.e_cs); +  s->Printf("  e_lfarlc   = 0x%4.4x\n", header.e_lfarlc); +  s->Printf("  e_ovno     = 0x%4.4x\n", header.e_ovno); +  s->Printf("  e_res[4]   = { 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x }\n", +            header.e_res[0], header.e_res[1], header.e_res[2], header.e_res[3]); +  s->Printf("  e_oemid    = 0x%4.4x\n", header.e_oemid); +  s->Printf("  e_oeminfo  = 0x%4.4x\n", header.e_oeminfo); +  s->Printf("  e_res2[10] = { 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, " +            "0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x }\n", +            header.e_res2[0], header.e_res2[1], header.e_res2[2], +            header.e_res2[3], header.e_res2[4], header.e_res2[5], +            header.e_res2[6], header.e_res2[7], header.e_res2[8], +            header.e_res2[9]); +  s->Printf("  e_lfanew   = 0x%8.8x\n", header.e_lfanew);  }  //---------------------------------------------------------------------- @@ -927,16 +877,14 @@ ObjectFilePECOFF::DumpDOSHeader(Stream *s, const dos_header_t& header)  //  // Dump the COFF header to the specified output stream  //---------------------------------------------------------------------- -void -ObjectFilePECOFF::DumpCOFFHeader(Stream *s, const coff_header_t& header) -{ -    s->PutCString ("COFF Header\n"); -    s->Printf ("  machine = 0x%4.4x\n", header.machine); -    s->Printf ("  nsects  = 0x%4.4x\n", header.nsects); -    s->Printf ("  modtime = 0x%8.8x\n", header.modtime); -    s->Printf ("  symoff  = 0x%8.8x\n", header.symoff); -    s->Printf ("  nsyms   = 0x%8.8x\n", header.nsyms); -    s->Printf ("  hdrsize = 0x%4.4x\n", header.hdrsize); +void ObjectFilePECOFF::DumpCOFFHeader(Stream *s, const coff_header_t &header) { +  s->PutCString("COFF Header\n"); +  s->Printf("  machine = 0x%4.4x\n", header.machine); +  s->Printf("  nsects  = 0x%4.4x\n", header.nsects); +  s->Printf("  modtime = 0x%8.8x\n", header.modtime); +  s->Printf("  symoff  = 0x%8.8x\n", header.symoff); +  s->Printf("  nsyms   = 0x%8.8x\n", header.nsyms); +  s->Printf("  hdrsize = 0x%4.4x\n", header.hdrsize);  }  //---------------------------------------------------------------------- @@ -944,147 +892,145 @@ ObjectFilePECOFF::DumpCOFFHeader(Stream *s, const coff_header_t& header)  //  // Dump the optional COFF header to the specified output stream  //---------------------------------------------------------------------- -void -ObjectFilePECOFF::DumpOptCOFFHeader(Stream *s, const coff_opt_header_t& header) -{ -    s->PutCString ("Optional COFF Header\n"); -    s->Printf ("  magic                   = 0x%4.4x\n", header.magic); -    s->Printf ("  major_linker_version    = 0x%2.2x\n", header.major_linker_version); -    s->Printf ("  minor_linker_version    = 0x%2.2x\n", header.minor_linker_version); -    s->Printf ("  code_size               = 0x%8.8x\n", header.code_size); -    s->Printf ("  data_size               = 0x%8.8x\n", header.data_size); -    s->Printf ("  bss_size                = 0x%8.8x\n", header.bss_size); -    s->Printf ("  entry                   = 0x%8.8x\n", header.entry); -    s->Printf ("  code_offset             = 0x%8.8x\n", header.code_offset); -    s->Printf ("  data_offset             = 0x%8.8x\n", header.data_offset); -    s->Printf ("  image_base              = 0x%16.16" PRIx64 "\n", header.image_base); -    s->Printf ("  sect_alignment          = 0x%8.8x\n", header.sect_alignment); -    s->Printf ("  file_alignment          = 0x%8.8x\n", header.file_alignment); -    s->Printf ("  major_os_system_version = 0x%4.4x\n", header.major_os_system_version); -    s->Printf ("  minor_os_system_version = 0x%4.4x\n", header.minor_os_system_version); -    s->Printf ("  major_image_version     = 0x%4.4x\n", header.major_image_version); -    s->Printf ("  minor_image_version     = 0x%4.4x\n", header.minor_image_version); -    s->Printf ("  major_subsystem_version = 0x%4.4x\n", header.major_subsystem_version); -    s->Printf ("  minor_subsystem_version = 0x%4.4x\n", header.minor_subsystem_version); -    s->Printf ("  reserved1               = 0x%8.8x\n", header.reserved1); -    s->Printf ("  image_size              = 0x%8.8x\n", header.image_size); -    s->Printf ("  header_size             = 0x%8.8x\n", header.header_size); -    s->Printf ("  checksum                = 0x%8.8x\n", header.checksum); -    s->Printf ("  subsystem               = 0x%4.4x\n", header.subsystem); -    s->Printf ("  dll_flags               = 0x%4.4x\n", header.dll_flags); -    s->Printf ("  stack_reserve_size      = 0x%16.16" PRIx64 "\n", header.stack_reserve_size); -    s->Printf ("  stack_commit_size       = 0x%16.16" PRIx64 "\n", header.stack_commit_size); -    s->Printf ("  heap_reserve_size       = 0x%16.16" PRIx64 "\n", header.heap_reserve_size); -    s->Printf ("  heap_commit_size        = 0x%16.16" PRIx64 "\n", header.heap_commit_size); -    s->Printf ("  loader_flags            = 0x%8.8x\n", header.loader_flags); -    s->Printf ("  num_data_dir_entries    = 0x%8.8x\n", (uint32_t)header.data_dirs.size()); -    uint32_t i; -    for (i=0; i<header.data_dirs.size(); i++) -    { -        s->Printf ("  data_dirs[%2u] vmaddr = 0x%8.8x, vmsize = 0x%8.8x\n",  -                   i, -                   header.data_dirs[i].vmaddr, -                   header.data_dirs[i].vmsize); -    } +void ObjectFilePECOFF::DumpOptCOFFHeader(Stream *s, +                                         const coff_opt_header_t &header) { +  s->PutCString("Optional COFF Header\n"); +  s->Printf("  magic                   = 0x%4.4x\n", header.magic); +  s->Printf("  major_linker_version    = 0x%2.2x\n", +            header.major_linker_version); +  s->Printf("  minor_linker_version    = 0x%2.2x\n", +            header.minor_linker_version); +  s->Printf("  code_size               = 0x%8.8x\n", header.code_size); +  s->Printf("  data_size               = 0x%8.8x\n", header.data_size); +  s->Printf("  bss_size                = 0x%8.8x\n", header.bss_size); +  s->Printf("  entry                   = 0x%8.8x\n", header.entry); +  s->Printf("  code_offset             = 0x%8.8x\n", header.code_offset); +  s->Printf("  data_offset             = 0x%8.8x\n", header.data_offset); +  s->Printf("  image_base              = 0x%16.16" PRIx64 "\n", +            header.image_base); +  s->Printf("  sect_alignment          = 0x%8.8x\n", header.sect_alignment); +  s->Printf("  file_alignment          = 0x%8.8x\n", header.file_alignment); +  s->Printf("  major_os_system_version = 0x%4.4x\n", +            header.major_os_system_version); +  s->Printf("  minor_os_system_version = 0x%4.4x\n", +            header.minor_os_system_version); +  s->Printf("  major_image_version     = 0x%4.4x\n", +            header.major_image_version); +  s->Printf("  minor_image_version     = 0x%4.4x\n", +            header.minor_image_version); +  s->Printf("  major_subsystem_version = 0x%4.4x\n", +            header.major_subsystem_version); +  s->Printf("  minor_subsystem_version = 0x%4.4x\n", +            header.minor_subsystem_version); +  s->Printf("  reserved1               = 0x%8.8x\n", header.reserved1); +  s->Printf("  image_size              = 0x%8.8x\n", header.image_size); +  s->Printf("  header_size             = 0x%8.8x\n", header.header_size); +  s->Printf("  checksum                = 0x%8.8x\n", header.checksum); +  s->Printf("  subsystem               = 0x%4.4x\n", header.subsystem); +  s->Printf("  dll_flags               = 0x%4.4x\n", header.dll_flags); +  s->Printf("  stack_reserve_size      = 0x%16.16" PRIx64 "\n", +            header.stack_reserve_size); +  s->Printf("  stack_commit_size       = 0x%16.16" PRIx64 "\n", +            header.stack_commit_size); +  s->Printf("  heap_reserve_size       = 0x%16.16" PRIx64 "\n", +            header.heap_reserve_size); +  s->Printf("  heap_commit_size        = 0x%16.16" PRIx64 "\n", +            header.heap_commit_size); +  s->Printf("  loader_flags            = 0x%8.8x\n", header.loader_flags); +  s->Printf("  num_data_dir_entries    = 0x%8.8x\n", +            (uint32_t)header.data_dirs.size()); +  uint32_t i; +  for (i = 0; i < header.data_dirs.size(); i++) { +    s->Printf("  data_dirs[%2u] vmaddr = 0x%8.8x, vmsize = 0x%8.8x\n", i, +              header.data_dirs[i].vmaddr, header.data_dirs[i].vmsize); +  }  }  //----------------------------------------------------------------------  // DumpSectionHeader  //  // Dump a single ELF section header to the specified output stream  //---------------------------------------------------------------------- -void -ObjectFilePECOFF::DumpSectionHeader(Stream *s, const section_header_t& sh) -{ -    std::string name; -    GetSectionName(name, sh); -    s->Printf ("%-16s 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%4.4x 0x%4.4x 0x%8.8x\n", -               name.c_str(), -               sh.vmaddr, -               sh.vmsize, -               sh.offset, -               sh.size, -               sh.reloff, -               sh.lineoff, -               sh.nreloc, -               sh.nline, -               sh.flags); +void ObjectFilePECOFF::DumpSectionHeader(Stream *s, +                                         const section_header_t &sh) { +  std::string name; +  GetSectionName(name, sh); +  s->Printf("%-16s 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%4.4x " +            "0x%4.4x 0x%8.8x\n", +            name.c_str(), sh.vmaddr, sh.vmsize, sh.offset, sh.size, sh.reloff, +            sh.lineoff, sh.nreloc, sh.nline, sh.flags);  } -  //----------------------------------------------------------------------  // DumpSectionHeaders  //  // Dump all of the ELF section header to the specified output stream  //---------------------------------------------------------------------- -void -ObjectFilePECOFF::DumpSectionHeaders(Stream *s) -{ -     -    s->PutCString ("Section Headers\n"); -    s->PutCString ("IDX  name             vm addr    vm size    file off   file size  reloc off  line off   nreloc nline  flags\n"); -    s->PutCString ("==== ---------------- ---------- ---------- ---------- ---------- ---------- ---------- ------ ------ ----------\n"); -     -    uint32_t idx = 0; -    SectionHeaderCollIter pos, end = m_sect_headers.end(); -     -    for (pos = m_sect_headers.begin(); pos != end; ++pos, ++idx) -    { -        s->Printf ("[%2u] ", idx); -        ObjectFilePECOFF::DumpSectionHeader(s, *pos); -    } +void ObjectFilePECOFF::DumpSectionHeaders(Stream *s) { + +  s->PutCString("Section Headers\n"); +  s->PutCString("IDX  name             vm addr    vm size    file off   file " +                "size  reloc off  line off   nreloc nline  flags\n"); +  s->PutCString("==== ---------------- ---------- ---------- ---------- " +                "---------- ---------- ---------- ------ ------ ----------\n"); + +  uint32_t idx = 0; +  SectionHeaderCollIter pos, end = m_sect_headers.end(); + +  for (pos = m_sect_headers.begin(); pos != end; ++pos, ++idx) { +    s->Printf("[%2u] ", idx); +    ObjectFilePECOFF::DumpSectionHeader(s, *pos); +  }  } -bool -ObjectFilePECOFF::GetArchitecture (ArchSpec &arch) -{ -    uint16_t machine = m_coff_header.machine; -    switch (machine) -    { -        case llvm::COFF::IMAGE_FILE_MACHINE_AMD64: -        case llvm::COFF::IMAGE_FILE_MACHINE_I386: -        case llvm::COFF::IMAGE_FILE_MACHINE_POWERPC: -        case llvm::COFF::IMAGE_FILE_MACHINE_POWERPCFP: -        case llvm::COFF::IMAGE_FILE_MACHINE_ARM: -        case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT: -        case llvm::COFF::IMAGE_FILE_MACHINE_THUMB: -            arch.SetArchitecture (eArchTypeCOFF, machine, LLDB_INVALID_CPUTYPE); -            return true; -        default: -            break; -    } +bool ObjectFilePECOFF::IsWindowsSubsystem() { +  switch (m_coff_header_opt.subsystem) { +  case llvm::COFF::IMAGE_SUBSYSTEM_NATIVE: +  case llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI: +  case llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI: +  case llvm::COFF::IMAGE_SUBSYSTEM_NATIVE_WINDOWS: +  case llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CE_GUI: +  case llvm::COFF::IMAGE_SUBSYSTEM_XBOX: +  case llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION: +    return true; +  default:      return false; +  }  } -ObjectFile::Type -ObjectFilePECOFF::CalculateType() -{ -    if (m_coff_header.machine != 0) -    { -        if ((m_coff_header.flags & llvm::COFF::IMAGE_FILE_DLL) == 0) -            return eTypeExecutable; -        else -            return eTypeSharedLibrary; -    } -    return eTypeExecutable; +bool ObjectFilePECOFF::GetArchitecture(ArchSpec &arch) { +  uint16_t machine = m_coff_header.machine; +  switch (machine) { +  case llvm::COFF::IMAGE_FILE_MACHINE_AMD64: +  case llvm::COFF::IMAGE_FILE_MACHINE_I386: +  case llvm::COFF::IMAGE_FILE_MACHINE_POWERPC: +  case llvm::COFF::IMAGE_FILE_MACHINE_POWERPCFP: +  case llvm::COFF::IMAGE_FILE_MACHINE_ARM: +  case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT: +  case llvm::COFF::IMAGE_FILE_MACHINE_THUMB: +    arch.SetArchitecture(eArchTypeCOFF, machine, LLDB_INVALID_CPUTYPE, +                         IsWindowsSubsystem() ? llvm::Triple::Win32 +                                              : llvm::Triple::UnknownOS); +    return true; +  default: +    break; +  } +  return false;  } -ObjectFile::Strata -ObjectFilePECOFF::CalculateStrata() -{ -    return eStrataUser; +ObjectFile::Type ObjectFilePECOFF::CalculateType() { +  if (m_coff_header.machine != 0) { +    if ((m_coff_header.flags & llvm::COFF::IMAGE_FILE_DLL) == 0) +      return eTypeExecutable; +    else +      return eTypeSharedLibrary; +  } +  return eTypeExecutable;  } + +ObjectFile::Strata ObjectFilePECOFF::CalculateStrata() { return eStrataUser; }  //------------------------------------------------------------------  // PluginInterface protocol  //------------------------------------------------------------------ -ConstString -ObjectFilePECOFF::GetPluginName() -{ -    return GetPluginNameStatic(); -} - -uint32_t -ObjectFilePECOFF::GetPluginVersion() -{ -    return 1; -} +ConstString ObjectFilePECOFF::GetPluginName() { return GetPluginNameStatic(); } +uint32_t ObjectFilePECOFF::GetPluginVersion() { return 1; } diff --git a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h index 6c1cdbf56c6b8..2313047735e0c 100644 --- a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h +++ b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h @@ -18,290 +18,270 @@  // Project includes  #include "lldb/Symbol/ObjectFile.h" -class ObjectFilePECOFF :  -    public lldb_private::ObjectFile -{ +class ObjectFilePECOFF : public lldb_private::ObjectFile {  public: -    typedef enum MachineType -    { -        MachineUnknown = 0x0, -        MachineAm33 = 0x1d3, -        MachineAmd64 = 0x8664, -        MachineArm = 0x1c0, -        MachineArmNt = 0x1c4, -        MachineArm64 = 0xaa64, -        MachineEbc = 0xebc, -        MachineX86 = 0x14c, -        MachineIA64 = 0x200, -        MachineM32R = 0x9041, -        MachineMips16 = 0x266, -        MachineMipsFpu = 0x366, -        MachineMipsFpu16 = 0x466, -        MachinePowerPc = 0x1f0, -        MachinePowerPcfp = 0x1f1, -        MachineR4000 = 0x166, -        MachineSh3 = 0x1a2, -        MachineSh3dsp = 0x1a3, -        MachineSh4 = 0x1a6, -        MachineSh5 = 0x1a8, -        MachineThumb = 0x1c2, -        MachineWcemIpsv2 = 0x169 -    } MachineType; -     -    ObjectFilePECOFF(const lldb::ModuleSP &module_sp, -                     lldb::DataBufferSP& data_sp, -                     lldb::offset_t data_offset, -                     const lldb_private::FileSpec* file, -                     lldb::offset_t file_offset, -                     lldb::offset_t length); - -    ~ObjectFilePECOFF() override; - -    //------------------------------------------------------------------ -    // Static Functions -    //------------------------------------------------------------------ -    static void -    Initialize(); -     -    static void -    Terminate(); -     -    static lldb_private::ConstString -    GetPluginNameStatic(); -     -    static const char * -    GetPluginDescriptionStatic(); -     -    static ObjectFile * -    CreateInstance (const lldb::ModuleSP &module_sp, -                    lldb::DataBufferSP& data_sp, -                    lldb::offset_t data_offset, -                    const lldb_private::FileSpec* file, -                    lldb::offset_t offset, -                    lldb::offset_t length); -     -    static lldb_private::ObjectFile * -    CreateMemoryInstance (const lldb::ModuleSP &module_sp,  -                          lldb::DataBufferSP& data_sp,  -                          const lldb::ProcessSP &process_sp,  -                          lldb::addr_t header_addr); -     -    static size_t -    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); - -    static bool -    SaveCore (const lldb::ProcessSP &process_sp, -              const lldb_private::FileSpec &outfile, -              lldb_private::Error &error); - -    static bool -    MagicBytesMatch (lldb::DataBufferSP& data_sp); - -    static lldb::SymbolType -    MapSymbolType(uint16_t coff_symbol_type); - -    bool -    ParseHeader() override; -     -    bool -    SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, bool value_is_offset) override; - -    lldb::ByteOrder -    GetByteOrder() const override; -     -    bool -    IsExecutable() const override; -     -    uint32_t -    GetAddressByteSize() const override; - -//    virtual lldb_private::AddressClass -//    GetAddressClass (lldb::addr_t file_addr); - -    lldb_private::Symtab * -    GetSymtab() override; -     -    bool -    IsStripped() override; - -    void -    CreateSections(lldb_private::SectionList &unified_section_list) override; -     -    void -    Dump(lldb_private::Stream *s) override; -     -    bool -    GetArchitecture(lldb_private::ArchSpec &arch) override; -     -    bool -    GetUUID(lldb_private::UUID* uuid) override; -     -    uint32_t -    GetDependentModules(lldb_private::FileSpecList& files) override; -     -    virtual lldb_private::Address -    GetEntryPointAddress () override; -     -    ObjectFile::Type -    CalculateType() override; -     -    ObjectFile::Strata -    CalculateStrata() override; -     -    //------------------------------------------------------------------ -    // PluginInterface protocol -    //------------------------------------------------------------------ -    lldb_private::ConstString -    GetPluginName() override; -     -    uint32_t -    GetPluginVersion() override; +  typedef enum MachineType { +    MachineUnknown = 0x0, +    MachineAm33 = 0x1d3, +    MachineAmd64 = 0x8664, +    MachineArm = 0x1c0, +    MachineArmNt = 0x1c4, +    MachineArm64 = 0xaa64, +    MachineEbc = 0xebc, +    MachineX86 = 0x14c, +    MachineIA64 = 0x200, +    MachineM32R = 0x9041, +    MachineMips16 = 0x266, +    MachineMipsFpu = 0x366, +    MachineMipsFpu16 = 0x466, +    MachinePowerPc = 0x1f0, +    MachinePowerPcfp = 0x1f1, +    MachineR4000 = 0x166, +    MachineSh3 = 0x1a2, +    MachineSh3dsp = 0x1a3, +    MachineSh4 = 0x1a6, +    MachineSh5 = 0x1a8, +    MachineThumb = 0x1c2, +    MachineWcemIpsv2 = 0x169 +  } MachineType; + +  ObjectFilePECOFF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, +                   lldb::offset_t data_offset, +                   const lldb_private::FileSpec *file, +                   lldb::offset_t file_offset, lldb::offset_t length); + +  ObjectFilePECOFF(const lldb::ModuleSP &module_sp, +                   lldb::DataBufferSP &header_data_sp, +                   const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); + +  ~ObjectFilePECOFF() override; + +  //------------------------------------------------------------------ +  // Static Functions +  //------------------------------------------------------------------ +  static void Initialize(); + +  static void Terminate(); + +  static lldb_private::ConstString GetPluginNameStatic(); + +  static const char *GetPluginDescriptionStatic(); + +  static ObjectFile * +  CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, +                 lldb::offset_t data_offset, const lldb_private::FileSpec *file, +                 lldb::offset_t offset, lldb::offset_t length); + +  static lldb_private::ObjectFile *CreateMemoryInstance( +      const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, +      const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); + +  static size_t 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); + +  static bool SaveCore(const lldb::ProcessSP &process_sp, +                       const lldb_private::FileSpec &outfile, +                       lldb_private::Error &error); + +  static bool MagicBytesMatch(lldb::DataBufferSP &data_sp); + +  static lldb::SymbolType MapSymbolType(uint16_t coff_symbol_type); + +  bool ParseHeader() override; + +  bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, +                      bool value_is_offset) override; + +  lldb::ByteOrder GetByteOrder() const override; + +  bool IsExecutable() const override; + +  uint32_t GetAddressByteSize() const override; + +  //    virtual lldb_private::AddressClass +  //    GetAddressClass (lldb::addr_t file_addr); + +  lldb_private::Symtab *GetSymtab() override; + +  bool IsStripped() override; + +  void CreateSections(lldb_private::SectionList &unified_section_list) override; + +  void Dump(lldb_private::Stream *s) override; + +  bool GetArchitecture(lldb_private::ArchSpec &arch) override; + +  bool GetUUID(lldb_private::UUID *uuid) override; + +  uint32_t GetDependentModules(lldb_private::FileSpecList &files) override; + +  virtual lldb_private::Address GetEntryPointAddress() override; + +  ObjectFile::Type CalculateType() override; + +  ObjectFile::Strata CalculateStrata() override; + +  //------------------------------------------------------------------ +  // PluginInterface protocol +  //------------------------------------------------------------------ +  lldb_private::ConstString GetPluginName() override; + +  uint32_t GetPluginVersion() override; + +  bool IsWindowsSubsystem(); + +  lldb_private::DataExtractor ReadImageData(uint32_t offset, size_t size);  protected: -	bool NeedsEndianSwap() const;     -     -	typedef struct dos_header  {  // DOS .EXE header -		uint16_t e_magic;         // Magic number -		uint16_t e_cblp;          // Bytes on last page of file -		uint16_t e_cp;            // Pages in file -		uint16_t e_crlc;          // Relocations -		uint16_t e_cparhdr;       // Size of header in paragraphs -		uint16_t e_minalloc;      // Minimum extra paragraphs needed -		uint16_t e_maxalloc;      // Maximum extra paragraphs needed -		uint16_t e_ss;            // Initial (relative) SS value -		uint16_t e_sp;            // Initial SP value -		uint16_t e_csum;          // Checksum -		uint16_t e_ip;            // Initial IP value -		uint16_t e_cs;            // Initial (relative) CS value -		uint16_t e_lfarlc;        // File address of relocation table -		uint16_t e_ovno;          // Overlay number -		uint16_t e_res[4];        // Reserved words -		uint16_t e_oemid;         // OEM identifier (for e_oeminfo) -		uint16_t e_oeminfo;       // OEM information; e_oemid specific -		uint16_t e_res2[10];      // Reserved words -		uint32_t e_lfanew;        // File address of new exe header -    } dos_header_t; -     -	typedef struct coff_header { -		uint16_t machine; -		uint16_t nsects; -		uint32_t modtime; -		uint32_t symoff; -		uint32_t nsyms; -		uint16_t hdrsize; -		uint16_t flags; -	} coff_header_t; -     -	typedef struct data_directory { -		uint32_t vmaddr; -		uint32_t vmsize; -	} data_directory_t; -     -	typedef struct coff_opt_header  -	{ -		uint16_t	magic; -		uint8_t		major_linker_version; -		uint8_t		minor_linker_version; -		uint32_t	code_size; -		uint32_t	data_size; -		uint32_t	bss_size; -		uint32_t	entry; -		uint32_t	code_offset; -		uint32_t	data_offset; -         -		uint64_t	image_base; -		uint32_t	sect_alignment; -		uint32_t	file_alignment; -		uint16_t	major_os_system_version; -		uint16_t	minor_os_system_version; -		uint16_t	major_image_version; -		uint16_t	minor_image_version; -		uint16_t	major_subsystem_version; -		uint16_t	minor_subsystem_version; -		uint32_t	reserved1; -		uint32_t	image_size; -		uint32_t	header_size; -		uint32_t	checksum; -		uint16_t	subsystem; -		uint16_t	dll_flags; -		uint64_t	stack_reserve_size; -		uint64_t	stack_commit_size; -		uint64_t	heap_reserve_size; -		uint64_t	heap_commit_size; -		uint32_t	loader_flags; -        //    uint32_t	num_data_dir_entries; -		std::vector<data_directory> data_dirs;	// will contain num_data_dir_entries entries -	} coff_opt_header_t; - -    typedef enum coff_data_dir_type -    { -        coff_data_dir_export_table = 0, -        coff_data_dir_import_table = 1, -    } coff_data_dir_type; -     -	typedef struct section_header { -		char		name[8]; -		uint32_t	vmsize;	// Virtual Size -		uint32_t	vmaddr;	// Virtual Addr -		uint32_t	size;	// File size -		uint32_t	offset;	// File offset -		uint32_t	reloff;	// Offset to relocations -		uint32_t	lineoff;// Offset to line table entries -		uint16_t	nreloc;	// Number of relocation entries -		uint16_t	nline;	// Number of line table entries -		uint32_t	flags; -	} section_header_t; -     -	typedef struct coff_symbol { -		char		name[8]; -		uint32_t	value; -		uint16_t	sect; -		uint16_t	type; -		uint8_t		storage; -		uint8_t		naux;		 -	} coff_symbol_t; - -    typedef struct export_directory_entry { -        uint32_t   characteristics; -        uint32_t   time_date_stamp; -        uint16_t   major_version; -        uint16_t   minor_version; -        uint32_t   name; -        uint32_t   base; -        uint32_t   number_of_functions; -        uint32_t   number_of_names; -        uint32_t   address_of_functions; -        uint32_t   address_of_names; -        uint32_t   address_of_name_ordinals; -    } export_directory_entry; -     -	static bool ParseDOSHeader (lldb_private::DataExtractor &data, dos_header_t &dos_header); -	static bool ParseCOFFHeader (lldb_private::DataExtractor &data, lldb::offset_t *offset_ptr, coff_header_t &coff_header); -	bool ParseCOFFOptionalHeader (lldb::offset_t *offset_ptr); -	bool ParseSectionHeaders (uint32_t offset); -	 -	static	void DumpDOSHeader(lldb_private::Stream *s, const dos_header_t& header); -	static	void DumpCOFFHeader(lldb_private::Stream *s, const coff_header_t& header); -	static	void DumpOptCOFFHeader(lldb_private::Stream *s, const coff_opt_header_t& header); -    void DumpSectionHeaders(lldb_private::Stream *s); -    void DumpSectionHeader(lldb_private::Stream *s, const section_header_t& sh); -    bool GetSectionName(std::string& sect_name, const section_header_t& sect); -     -	typedef std::vector<section_header_t>		SectionHeaderColl; -	typedef SectionHeaderColl::iterator			SectionHeaderCollIter; -	typedef SectionHeaderColl::const_iterator	SectionHeaderCollConstIter; +  bool NeedsEndianSwap() const; + +  typedef struct dos_header { // DOS .EXE header +    uint16_t e_magic;         // Magic number +    uint16_t e_cblp;          // Bytes on last page of file +    uint16_t e_cp;            // Pages in file +    uint16_t e_crlc;          // Relocations +    uint16_t e_cparhdr;       // Size of header in paragraphs +    uint16_t e_minalloc;      // Minimum extra paragraphs needed +    uint16_t e_maxalloc;      // Maximum extra paragraphs needed +    uint16_t e_ss;            // Initial (relative) SS value +    uint16_t e_sp;            // Initial SP value +    uint16_t e_csum;          // Checksum +    uint16_t e_ip;            // Initial IP value +    uint16_t e_cs;            // Initial (relative) CS value +    uint16_t e_lfarlc;        // File address of relocation table +    uint16_t e_ovno;          // Overlay number +    uint16_t e_res[4];        // Reserved words +    uint16_t e_oemid;         // OEM identifier (for e_oeminfo) +    uint16_t e_oeminfo;       // OEM information; e_oemid specific +    uint16_t e_res2[10];      // Reserved words +    uint32_t e_lfanew;        // File address of new exe header +  } dos_header_t; + +  typedef struct coff_header { +    uint16_t machine; +    uint16_t nsects; +    uint32_t modtime; +    uint32_t symoff; +    uint32_t nsyms; +    uint16_t hdrsize; +    uint16_t flags; +  } coff_header_t; + +  typedef struct data_directory { +    uint32_t vmaddr; +    uint32_t vmsize; +  } data_directory_t; + +  typedef struct coff_opt_header { +    uint16_t magic; +    uint8_t major_linker_version; +    uint8_t minor_linker_version; +    uint32_t code_size; +    uint32_t data_size; +    uint32_t bss_size; +    uint32_t entry; +    uint32_t code_offset; +    uint32_t data_offset; + +    uint64_t image_base; +    uint32_t sect_alignment; +    uint32_t file_alignment; +    uint16_t major_os_system_version; +    uint16_t minor_os_system_version; +    uint16_t major_image_version; +    uint16_t minor_image_version; +    uint16_t major_subsystem_version; +    uint16_t minor_subsystem_version; +    uint32_t reserved1; +    uint32_t image_size; +    uint32_t header_size; +    uint32_t checksum; +    uint16_t subsystem; +    uint16_t dll_flags; +    uint64_t stack_reserve_size; +    uint64_t stack_commit_size; +    uint64_t heap_reserve_size; +    uint64_t heap_commit_size; +    uint32_t loader_flags; +    //    uint32_t	num_data_dir_entries; +    std::vector<data_directory> +        data_dirs; // will contain num_data_dir_entries entries +  } coff_opt_header_t; + +  typedef enum coff_data_dir_type { +    coff_data_dir_export_table = 0, +    coff_data_dir_import_table = 1, +  } coff_data_dir_type; + +  typedef struct section_header { +    char name[8]; +    uint32_t vmsize;  // Virtual Size +    uint32_t vmaddr;  // Virtual Addr +    uint32_t size;    // File size +    uint32_t offset;  // File offset +    uint32_t reloff;  // Offset to relocations +    uint32_t lineoff; // Offset to line table entries +    uint16_t nreloc;  // Number of relocation entries +    uint16_t nline;   // Number of line table entries +    uint32_t flags; +  } section_header_t; + +  typedef struct coff_symbol { +    char name[8]; +    uint32_t value; +    uint16_t sect; +    uint16_t type; +    uint8_t storage; +    uint8_t naux; +  } coff_symbol_t; + +  typedef struct export_directory_entry { +    uint32_t characteristics; +    uint32_t time_date_stamp; +    uint16_t major_version; +    uint16_t minor_version; +    uint32_t name; +    uint32_t base; +    uint32_t number_of_functions; +    uint32_t number_of_names; +    uint32_t address_of_functions; +    uint32_t address_of_names; +    uint32_t address_of_name_ordinals; +  } export_directory_entry; + +  static bool ParseDOSHeader(lldb_private::DataExtractor &data, +                             dos_header_t &dos_header); +  static bool ParseCOFFHeader(lldb_private::DataExtractor &data, +                              lldb::offset_t *offset_ptr, +                              coff_header_t &coff_header); +  bool ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr); +  bool ParseSectionHeaders(uint32_t offset); + +  static void DumpDOSHeader(lldb_private::Stream *s, +                            const dos_header_t &header); +  static void DumpCOFFHeader(lldb_private::Stream *s, +                             const coff_header_t &header); +  static void DumpOptCOFFHeader(lldb_private::Stream *s, +                                const coff_opt_header_t &header); +  void DumpSectionHeaders(lldb_private::Stream *s); +  void DumpSectionHeader(lldb_private::Stream *s, const section_header_t &sh); +  bool GetSectionName(std::string §_name, const section_header_t §); + +  typedef std::vector<section_header_t> SectionHeaderColl; +  typedef SectionHeaderColl::iterator SectionHeaderCollIter; +  typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter; +  private: -	dos_header_t		m_dos_header; -	coff_header_t		m_coff_header; -	coff_opt_header_t	m_coff_header_opt; -	SectionHeaderColl	m_sect_headers; -    lldb::addr_t		m_image_base; -    lldb_private::Address	m_entry_point_address; +  dos_header_t m_dos_header; +  coff_header_t m_coff_header; +  coff_opt_header_t m_coff_header_opt; +  SectionHeaderColl m_sect_headers; +  lldb::addr_t m_image_base; +  lldb_private::Address m_entry_point_address;  };  #endif // liblldb_ObjectFilePECOFF_h_ diff --git a/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp b/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp index 14c73eff2388a..3fd6cdc5c9a76 100644 --- a/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp +++ b/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp @@ -16,41 +16,44 @@  #ifdef _WIN32  #include "lldb/Host/windows/windows.h" -#include <DbgHelp.h>  // for MiniDumpWriteDump +#include <dbghelp.h> // for MiniDumpWriteDump  #endif  namespace lldb_private { -bool -SaveMiniDump(const lldb::ProcessSP &process_sp, -             const lldb_private::FileSpec &outfile, -             lldb_private::Error &error) -{ -    if (!process_sp) return false; +bool SaveMiniDump(const lldb::ProcessSP &process_sp, +                  const lldb_private::FileSpec &outfile, +                  lldb_private::Error &error) { +  if (!process_sp) +    return false;  #ifdef _WIN32 -    HANDLE process_handle = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, process_sp->GetID()); -    const std::string file_name = outfile.GetCString(); -    std::wstring wide_name; -    wide_name.resize(file_name.size() + 1); -    char * result_ptr = reinterpret_cast<char *>(&wide_name[0]); -    const UTF8 *error_ptr = nullptr; -    if (!llvm::ConvertUTF8toWide(sizeof(wchar_t), file_name, result_ptr, error_ptr)) { -        error.SetErrorString("cannot convert file name"); -        return false; -    } -    HANDLE file_handle = ::CreateFileW(wide_name.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); -    const auto result = ::MiniDumpWriteDump(process_handle, process_sp->GetID(), file_handle, -                                            MiniDumpWithFullMemoryInfo, NULL, NULL, NULL); -    ::CloseHandle(file_handle); -    ::CloseHandle(process_handle); -    if (!result) -    { -        error.SetError(::GetLastError(), lldb::eErrorTypeWin32); -        return false; -    } -    return true; -#endif +  HANDLE process_handle = ::OpenProcess( +      PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, process_sp->GetID()); +  const std::string file_name = outfile.GetCString(); +  std::wstring wide_name; +  wide_name.resize(file_name.size() + 1); +  char *result_ptr = reinterpret_cast<char *>(&wide_name[0]); +  const llvm::UTF8 *error_ptr = nullptr; +  if (!llvm::ConvertUTF8toWide(sizeof(wchar_t), file_name, result_ptr, +                               error_ptr)) { +    error.SetErrorString("cannot convert file name");      return false; +  } +  HANDLE file_handle = +      ::CreateFileW(wide_name.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, +                    CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); +  const auto result = +      ::MiniDumpWriteDump(process_handle, process_sp->GetID(), file_handle, +                          MiniDumpWithFullMemoryInfo, NULL, NULL, NULL); +  ::CloseHandle(file_handle); +  ::CloseHandle(process_handle); +  if (!result) { +    error.SetError(::GetLastError(), lldb::eErrorTypeWin32); +    return false; +  } +  return true; +#endif +  return false;  } -}  // namesapce lldb_private +} // namesapce lldb_private diff --git a/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.h b/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.h index cbea88af1fb0a..3f741dc04f514 100644 --- a/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.h +++ b/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.h @@ -14,11 +14,10 @@  namespace lldb_private { -bool -SaveMiniDump(const lldb::ProcessSP &process_sp, -             const lldb_private::FileSpec &outfile, -             lldb_private::Error &error); +bool SaveMiniDump(const lldb::ProcessSP &process_sp, +                  const lldb_private::FileSpec &outfile, +                  lldb_private::Error &error); -}  // namespace lldb_private +} // namespace lldb_private  #endif  | 
