diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:55:28 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:55:28 +0000 | 
| commit | e81d9d49145e432d917eea3a70d2ae74dcad1d89 (patch) | |
| tree | 9ed5e1a91f242e2cb5911577356e487a55c01b78 /source/Plugins/ObjectFile | |
| parent | 85d8ef8f1f0e0e063a8571944302be2d2026f823 (diff) | |
Notes
Diffstat (limited to 'source/Plugins/ObjectFile')
| -rw-r--r-- | source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 508 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/ELF/ObjectFileELF.h | 19 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/JIT/ObjectFileJIT.h | 114 | 
3 files changed, 445 insertions, 196 deletions
| diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 789fd4913301..44fe6615a361 100644 --- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -11,6 +11,7 @@  #include <cassert>  #include <algorithm> +#include <unordered_map>  #include "lldb/Core/ArchSpec.h"  #include "lldb/Core/DataBuffer.h" @@ -48,6 +49,8 @@ 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";  // ELF note type definitions  const elf_word LLDB_NT_FREEBSD_ABI_TAG  = 0x01; @@ -66,6 +69,41 @@ const elf_word LLDB_NT_GNU_ABI_OS_LINUX   = 0x00;  const elf_word LLDB_NT_GNU_ABI_OS_HURD    = 0x01;  const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02; +// LLDB_NT_OWNER_CORE and LLDB_NT_OWNER_LINUX note contants +#define NT_PRSTATUS             1 +#define NT_PRFPREG              2 +#define NT_PRPSINFO             3 +#define NT_TASKSTRUCT           4 +#define NT_AUXV                 6 +#define NT_SIGINFO              0x53494749 +#define NT_FILE                 0x46494c45 +#define NT_PRXFPREG             0x46e62b7f +#define NT_PPC_VMX              0x100 +#define NT_PPC_SPE              0x101 +#define NT_PPC_VSX              0x102 +#define NT_386_TLS              0x200 +#define NT_386_IOPERM           0x201 +#define NT_X86_XSTATE           0x202 +#define NT_S390_HIGH_GPRS       0x300 +#define NT_S390_TIMER           0x301 +#define NT_S390_TODCMP          0x302 +#define NT_S390_TODPREG         0x303 +#define NT_S390_CTRS            0x304 +#define NT_S390_PREFIX          0x305 +#define NT_S390_LAST_BREAK      0x306 +#define NT_S390_SYSTEM_CALL     0x307 +#define NT_S390_TDB             0x308 +#define NT_S390_VXRS_LOW        0x309 +#define NT_S390_VXRS_HIGH       0x30a +#define NT_ARM_VFP              0x400 +#define NT_ARM_TLS              0x401 +#define NT_ARM_HW_BREAK         0x402 +#define NT_ARM_HW_WATCH         0x403 +#define NT_ARM_SYSTEM_CALL      0x404 +#define NT_METAG_CBUF           0x500 +#define NT_METAG_RPIPE          0x501 +#define NT_METAG_TLS            0x502 +  //===----------------------------------------------------------------------===//  /// @class ELFRelocation  /// @brief Generic wrapper for ELFRel and ELFRela. @@ -290,6 +328,11 @@ mipsVariantFromElfFlags(const elf::elf_word e_flags, uint32_t endian)      switch (mips_arch)      { +        case llvm::ELF::EF_MIPS_ARCH_1: +        case llvm::ELF::EF_MIPS_ARCH_2: +        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_32:              return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32el : ArchSpec::eMIPSSubType_mips32;          case llvm::ELF::EF_MIPS_ARCH_32R2: @@ -847,40 +890,52 @@ ObjectFileELF::SetLoadAddress (Target &target,          SectionList *section_list = GetSectionList ();          if (section_list)          { -            if (value_is_offset) +            if (!value_is_offset)              { -                const size_t num_sections = section_list->GetSize(); -                size_t sect_idx = 0; - -                for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) +                bool found_offset = false; +                for (size_t i = 0, count = GetProgramHeaderCount(); i < count; ++i)                  { -                    // 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 (section_sp && section_sp->Test(SHF_ALLOC)) -                    { -                        lldb::addr_t load_addr = section_sp->GetFileAddress() + 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; -                    } +                    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;                  } -                return num_loaded_sections > 0; +                if (!found_offset) +                    return false;              } -            else + +            const size_t num_sections = section_list->GetSize(); +            size_t sect_idx = 0; + +            for (sect_idx = 0; sect_idx < num_sections; ++sect_idx)              { -                // Not sure how to slide an ELF file given the base address -                // of the ELF file in memory +                // 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 (section_sp && section_sp->Test(SHF_ALLOC)) +                { +                    lldb::addr_t load_addr = section_sp->GetFileAddress() + 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; // If it changed +    return false;  }  ByteOrder @@ -905,8 +960,17 @@ ObjectFileELF::GetAddressByteSize() const  AddressClass  ObjectFileELF::GetAddressClass (addr_t file_addr)  { -    auto res = ObjectFile::GetAddressClass (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; @@ -1076,16 +1140,35 @@ ObjectFileELF::GetImageInfoAddress(Target *target)              addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();              return Address(dynsym_section_sp, offset);          } -        else if (symbol.d_tag == DT_MIPS_RLD_MAP && target) +        // 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(); -            Address addr; +              Error error; -            if (target->ReadPointerFromMemory(dyn_base + offset, false, error, addr)) -                return addr; +            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; +                } +            }          }      } @@ -1232,6 +1315,7 @@ ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, l      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))          { @@ -1239,11 +1323,6 @@ ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, l              return error;          } -        // If a tag processor handles the tag, it should set processed to true, and -        // the loop will assume the tag processing has moved entirely past the note's payload. -        // Otherwise, leave it false and the end of the loop will handle the offset properly. -        bool processed = false; -          if (log)              log->Printf ("ObjectFileELF::%s parsing note name='%s', type=%" PRIu32, __FUNCTION__, note.n_name.c_str (), note.n_type); @@ -1252,9 +1331,6 @@ ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, l              (note.n_type == LLDB_NT_FREEBSD_ABI_TAG) &&              (note.n_descsz == LLDB_NT_FREEBSD_ABI_SIZE))          { -            // We'll consume the payload below. -            processed = true; -              // Pull out the min version info.              uint32_t version_info;              if (data.GetU32 (&offset, &version_info, 1) == nullptr) @@ -1285,9 +1361,6 @@ ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, l                  case LLDB_NT_GNU_ABI_TAG:                      if (note.n_descsz == LLDB_NT_GNU_ABI_SIZE)                      { -                        // We'll consume the payload below. -                        processed = true; -                          // 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) @@ -1330,9 +1403,6 @@ ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, l                      // Only bother processing this if we don't already have the uuid set.                      if (!uuid.IsValid())                      { -                        // We'll consume the payload below. -                        processed = true; -                          // 16 bytes is UUID|MD5, 20 bytes is SHA1                          if ((note.n_descsz == 16 || note.n_descsz == 20))                          { @@ -1355,10 +1425,6 @@ ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, l                   (note.n_type == LLDB_NT_NETBSD_ABI_TAG) &&                   (note.n_descsz == LLDB_NT_NETBSD_ABI_SIZE))          { - -            // We'll consume the payload below. -            processed = true; -              // Pull out the min version info.              uint32_t version_info;              if (data.GetU32 (&offset, &version_info, 1) == nullptr) @@ -1378,8 +1444,6 @@ ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, l          else if ((note.n_type == LLDB_NT_GNU_ABI_TAG) &&                  (note.n_name == LLDB_NT_OWNER_CSR))          { -            // We'll consume the payload below. -            processed = true;              arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS);              arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::CSR); @@ -1397,9 +1461,48 @@ ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, l              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 (!processed) -            offset += llvm::RoundUpToAlignment(note.n_descsz, 4); +        // Calculate the offset of the next note just in case "offset" has been used +        // to poke at the contents of the note data +        offset = note_offset + note.GetByteSize();      }      return error; @@ -1496,8 +1599,8 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers,                   I != section_headers.end(); ++I)              {                  static ConstString g_sect_name_gnu_debuglink (".gnu_debuglink"); -                const ELFSectionHeaderInfo &header = *I; -                const uint64_t section_size = header.sh_type == SHT_NOBITS ? 0 : header.sh_size; +                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; @@ -1505,23 +1608,33 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers,                  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)                  { -                    if (header.sh_type == SHT_MIPS_ABIFLAGS) +                    uint32_t arch_flags = arch_spec.GetFlags (); +                    DataExtractor data; +                    if (sheader.sh_type == SHT_MIPS_ABIFLAGS)                      { -                        DataExtractor data; -                        if (section_size && (data.SetData (object_data, header.sh_offset, section_size) == section_size)) +                         +                        if (section_size && (data.SetData (object_data, sheader.sh_offset, section_size) == section_size))                          {                              lldb::offset_t ase_offset = 12; // MIPS ABI Flags Version: 0 -                            uint32_t arch_flags = arch_spec.GetFlags ();                              arch_flags |= data.GetU32 (&ase_offset); -                            arch_spec.SetFlags (arch_flags);                          }                      } +                    // Settings appropriate ArchSpec ABI Flags +                    if (header.e_flags & llvm::ELF::EF_MIPS_ABI2) +                    {    +                        arch_flags |= lldb_private::ArchSpec::eMIPSABI_N32; +                    } +                    else if (header.e_flags & llvm::ELF::EF_MIPS_ABI_O32) +                    { +                         arch_flags |= lldb_private::ArchSpec::eMIPSABI_O32;        +                    } +                    arch_spec.SetFlags (arch_flags);                  }                  if (name == g_sect_name_gnu_debuglink)                  {                      DataExtractor data; -                    if (section_size && (data.SetData (object_data, header.sh_offset, section_size) == section_size)) +                    if (section_size && (data.SetData (object_data, sheader.sh_offset, section_size) == section_size))                      {                          lldb::offset_t gnu_debuglink_offset = 0;                          gnu_debuglink_file = data.GetCStr (&gnu_debuglink_offset); @@ -1531,7 +1644,7 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers,                  }                  // Process ELF note section entries. -                bool is_note_header = (header.sh_type == SHT_NOTE); +                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. @@ -1543,7 +1656,7 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers,                  {                      // Allow notes to refine module info.                      DataExtractor data; -                    if (section_size && (data.SetData (object_data, header.sh_offset, section_size) == section_size)) +                    if (section_size && (data.SetData (object_data, sheader.sh_offset, section_size) == section_size))                      {                          Error error = RefineModuleDetailsFromNote (data, arch_spec, uuid);                          if (error.Fail ()) @@ -1555,6 +1668,12 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers,                  }              } +            // 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();          }      } @@ -1651,17 +1770,30 @@ ObjectFileELF::CreateSections(SectionList &unified_section_list)              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; @@ -1694,18 +1826,31 @@ ObjectFileELF::CreateSections(SectionList &unified_section_list)              // 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_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_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_eh_frame)              sect_type = eSectionTypeEHFrame; +            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;              switch (header.sh_type)              { @@ -1731,7 +1876,7 @@ ObjectFileELF::CreateSections(SectionList &unified_section_list)              if (eSectionTypeOther == sect_type)              {                  // the kalimba toolchain assumes that ELF section names are free-form. It does -                // supports linkscripts which (can) give rise to various arbitarily named +                // support linkscripts which (can) give rise to various arbitrarily named                  // sections being "Code" or "Data".                   sect_type = kalimbaSectionType(m_header, header);              } @@ -1770,17 +1915,19 @@ ObjectFileELF::CreateSections(SectionList &unified_section_list)          {              static const SectionType g_sections[] =              { -                eSectionTypeDWARFDebugAranges, -                eSectionTypeDWARFDebugInfo,                  eSectionTypeDWARFDebugAbbrev, +                eSectionTypeDWARFDebugAddr, +                eSectionTypeDWARFDebugAranges,                  eSectionTypeDWARFDebugFrame, +                eSectionTypeDWARFDebugInfo,                  eSectionTypeDWARFDebugLine, -                eSectionTypeDWARFDebugStr,                  eSectionTypeDWARFDebugLoc,                  eSectionTypeDWARFDebugMacInfo,                  eSectionTypeDWARFDebugPubNames,                  eSectionTypeDWARFDebugPubTypes,                  eSectionTypeDWARFDebugRanges, +                eSectionTypeDWARFDebugStr, +                eSectionTypeDWARFDebugStrOffsets,                  eSectionTypeELFSymbolTable,              };              SectionList *elf_section_list = m_sections_ap.get(); @@ -1805,6 +1952,29 @@ ObjectFileELF::CreateSections(SectionList &unified_section_list)      }  } +// Find the arm/aarch64 mapping symbol character in the given symbol name. Mapping symbols have the +// form of "$<char>[.<any>]*". Additionally we recognize cases when the mapping symbol prefixed by +// an arbitrary string because if a symbol prefix added to each symbol in the object file with +// objcopy then the mapping symbols are also prefixed. +static char +FindArmAarch64MappingSymbol(const char* symbol_name) +{ +    if (!symbol_name) +        return '\0'; + +    const char* dollar_pos = ::strchr(symbol_name, '$'); +    if (!dollar_pos || dollar_pos[1] == '\0') +        return '\0'; + +    if (dollar_pos[2] == '\0' || dollar_pos[2] == '.') +        return dollar_pos[1]; +    return '\0'; +} + +#define STO_MIPS_ISA            (3 << 6) +#define STO_MICROMIPS           (2 << 6) +#define IS_MICROMIPS(ST_OTHER)  (((ST_OTHER) & STO_MIPS_ISA) == STO_MICROMIPS) +  // private  unsigned  ObjectFileELF::ParseSymbols (Symtab *symtab, @@ -1840,6 +2010,13 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,      // makes it highly unlikely that this will collide with anything else.      bool skip_oatdata_oatexec = m_file.GetFilename() == ConstString("system@framework@boot.oat"); +    ArchSpec arch; +    GetArchitecture(arch); + +    // 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)      { @@ -1945,64 +2122,58 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,          int64_t symbol_value_offset = 0;          uint32_t additional_flags = 0; -        ArchSpec arch; -        if (GetArchitecture(arch)) +        if (arch.IsValid())          {              if (arch.GetMachine() == llvm::Triple::arm)              { -                if (symbol.getBinding() == STB_LOCAL && symbol_name && symbol_name[0] == '$') +                if (symbol.getBinding() == STB_LOCAL)                  { -                    // These are reserved for the specification (e.g.: mapping -                    // symbols). We don't want to add them to the symbol table. - +                    char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name);                      if (symbol_type == eSymbolTypeCode)                      { -                        llvm::StringRef symbol_name_ref(symbol_name); -                        if (symbol_name_ref == "$a" || symbol_name_ref.startswith("$a.")) -                        { -                            // $a[.<any>]* - marks an ARM instruction sequence -                            m_address_class_map[symbol.st_value] = eAddressClassCode; -                        } -                        else if (symbol_name_ref == "$b" || symbol_name_ref.startswith("$b.") || -                                 symbol_name_ref == "$t" || symbol_name_ref.startswith("$t.")) +                        switch (mapping_symbol)                          { -                            // $b[.<any>]* - marks a THUMB BL instruction sequence -                            // $t[.<any>]* - marks a THUMB instruction sequence -                            m_address_class_map[symbol.st_value] = eAddressClassCodeAlternateISA; -                        } -                        else if (symbol_name_ref == "$d" || symbol_name_ref.startswith("$d.")) -                        { -                            // $d[.<any>]* - marks a data item sequence (e.g. lit pool) -                            m_address_class_map[symbol.st_value] = eAddressClassData; +                            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;                          }                      } - -                    continue; +                    if (mapping_symbol) +                        continue;                  }              }              else if (arch.GetMachine() == llvm::Triple::aarch64)              { -                if (symbol.getBinding() == STB_LOCAL && symbol_name && symbol_name[0] == '$') +                if (symbol.getBinding() == STB_LOCAL)                  { -                    // These are reserved for the specification (e.g.: mapping -                    // symbols). We don't want to add them to the symbol table. - +                    char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name);                      if (symbol_type == eSymbolTypeCode)                      { -                        llvm::StringRef symbol_name_ref(symbol_name); -                        if (symbol_name_ref == "$x" || symbol_name_ref.startswith("$x.")) +                        switch (mapping_symbol)                          { -                            // $x[.<any>]* - marks an A64 instruction sequence -                            m_address_class_map[symbol.st_value] = eAddressClassCode; -                        } -                        else if (symbol_name_ref == "$d" || symbol_name_ref.startswith("$d.")) -                        { -                            // $d[.<any>]* - marks a data item sequence (e.g. lit pool) -                            m_address_class_map[symbol.st_value] = eAddressClassData; +                            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;                          }                      } - -                    continue; +                    if (mapping_symbol) +                        continue;                  }              } @@ -2029,11 +2200,46 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,                      }                  }              } + +            /* +             * 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; +                } +            }          } -        // If the symbol section we've found has no data (SHT_NOBITS), then check the module section -        // list. This can happen if we're parsing the debug file and it has no .text section, for example. -        if (symbol_section_sp && (symbol_section_sp->GetFileSize() == 0)) +        // 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 && CalculateType() != ObjectFile::Type::eTypeObjectFile) +            symbol_value -= symbol_section_sp->GetFileAddress(); + +        if (symbol_section_sp)          {              ModuleSP module_sp(GetModule());              if (module_sp) @@ -2042,20 +2248,17 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,                  if (module_section_list && module_section_list != section_list)                  {                      const ConstString §_name = symbol_section_sp->GetName(); -                    lldb::SectionSP section_sp (module_section_list->FindSectionByName (sect_name)); -                    if (section_sp && section_sp->GetFileSize()) -                    { -                        symbol_section_sp = section_sp; -                    } +                    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;                  }              }          } -        // 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 && CalculateType() != ObjectFile::Type::eTypeObjectFile) -            symbol_value -= symbol_section_sp->GetFileAddress();          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; @@ -2069,7 +2272,7 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,          Mangled mangled(ConstString(symbol_bare), is_mangled);          // Now append the suffix back to mangled and unmangled names. Only do it if the -        // demangling was sucessful (string is not empty). +        // demangling was successful (string is not empty).          if (has_suffix)          {              llvm::StringRef suffix = symbol_ref.substr(version_pos); @@ -2221,7 +2424,7 @@ ObjectFileELF::PLTRelocationType()  }  // 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 ususally a resolution entry which have different size in some +// 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) @@ -2237,8 +2440,8 @@ GetPltEntrySizeAndOffset(const ELFSectionHeader* rel_hdr, const ELFSectionHeader      {          // 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 -        // asumption that the size of the 0th entry is at least as big as the size of the normal -        // entries and it isn't mutch bigger then that. +        // 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 @@ -2563,8 +2766,6 @@ ObjectFileELF::GetSymtab()          uint64_t symbol_id = 0;          lldb_private::Mutex::Locker locker(module_sp->GetMutex()); -        m_symtab_ap.reset(new Symtab(this)); -          // 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 @@ -2578,7 +2779,10 @@ ObjectFileELF::GetSymtab()              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 @@ -2598,10 +2802,19 @@ ObjectFileELF::GetSymtab()                  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);              }          } +         +        // 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();      } @@ -3000,6 +3213,27 @@ ObjectFileELF::GetArchitecture (ArchSpec &arch)          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;  } diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h index 99088d166b12..4b97f92c6c5c 100644 --- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -10,9 +10,14 @@  #ifndef liblldb_ObjectFileELF_h_  #define liblldb_ObjectFileELF_h_ +// C Includes  #include <stdint.h> + +// C++ Includes  #include <vector> +// Other libraries and framework includes +// Project includes  #include "lldb/lldb-private.h"  #include "lldb/Host/FileSpec.h"  #include "lldb/Symbol/ObjectFile.h" @@ -47,6 +52,12 @@ struct ELFNote      ///    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::RoundUpToAlignment (n_namesz, 4) + llvm::RoundUpToAlignment (n_descsz, 4); +    }  };  //------------------------------------------------------------------------------ @@ -59,6 +70,8 @@ class ObjectFileELF :      public lldb_private::ObjectFile  {  public: +    ~ObjectFileELF() override; +      //------------------------------------------------------------------      // Static Functions      //------------------------------------------------------------------ @@ -113,9 +126,6 @@ public:      //------------------------------------------------------------------      // ObjectFile Protocol.      //------------------------------------------------------------------ -    virtual -    ~ObjectFileELF(); -      bool      ParseHeader() override; @@ -211,6 +221,7 @@ private:      {          lldb_private::ConstString section_name;      }; +      typedef std::vector<ELFSectionHeaderInfo>   SectionHeaderColl;      typedef SectionHeaderColl::iterator         SectionHeaderCollIter;      typedef SectionHeaderColl::const_iterator   SectionHeaderCollConstIter; @@ -428,4 +439,4 @@ private:      RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch_spec, lldb_private::UUID &uuid);  }; -#endif // #ifndef liblldb_ObjectFileELF_h_ +#endif // liblldb_ObjectFileELF_h_ diff --git a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h index 47140f5bcaff..39dbb3fb047b 100644 --- a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h +++ b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h @@ -10,10 +10,13 @@  #ifndef liblldb_ObjectFileJIT_h_  #define liblldb_ObjectFileJIT_h_ +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes  #include "lldb/Core/Address.h"  #include "lldb/Symbol/ObjectFile.h" -  //----------------------------------------------------------------------  // This class needs to be hidden as eventually belongs in a plugin that  // will export the ObjectFile protocol @@ -22,6 +25,11 @@ class ObjectFileJIT :      public lldb_private::ObjectFile  {  public: +    ObjectFileJIT(const lldb::ModuleSP &module_sp, +                  const lldb::ObjectFileJITDelegateSP &delegate_sp); + +    ~ObjectFileJIT() override; +      //------------------------------------------------------------------      // Static Functions      //------------------------------------------------------------------ @@ -62,81 +70,77 @@ public:      //------------------------------------------------------------------      // Member Functions      //------------------------------------------------------------------ -    ObjectFileJIT (const lldb::ModuleSP &module_sp, -                   const lldb::ObjectFileJITDelegateSP &delegate_sp); -     -    virtual -    ~ObjectFileJIT(); - -    virtual bool -    ParseHeader (); +    bool +    ParseHeader() override; -    virtual bool +    bool      SetLoadAddress(lldb_private::Target &target,                     lldb::addr_t value, -                   bool value_is_offset); +                   bool value_is_offset) override; -    virtual lldb::ByteOrder -    GetByteOrder () const; +    lldb::ByteOrder +    GetByteOrder() const override; -    virtual bool -    IsExecutable () const; +    bool +    IsExecutable() const override; -    virtual uint32_t -    GetAddressByteSize ()  const; +    uint32_t +    GetAddressByteSize() const override; -    virtual lldb_private::Symtab * -    GetSymtab(); +    lldb_private::Symtab * +    GetSymtab() override; -    virtual bool -    IsStripped (); +    bool +    IsStripped() override; -    virtual void -    CreateSections (lldb_private::SectionList &unified_section_list); +    void +    CreateSections(lldb_private::SectionList &unified_section_list) override; -    virtual void -    Dump (lldb_private::Stream *s); +    void +    Dump(lldb_private::Stream *s) override; -    virtual bool -    GetArchitecture (lldb_private::ArchSpec &arch); +    bool +    GetArchitecture(lldb_private::ArchSpec &arch) override; -    virtual bool -    GetUUID (lldb_private::UUID* uuid); +    bool +    GetUUID(lldb_private::UUID* uuid) override; -    virtual uint32_t -    GetDependentModules (lldb_private::FileSpecList& files); +    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; -    virtual size_t -    ReadSectionData (const lldb_private::Section *section, -                     lldb::offset_t section_offset, -                     void *dst, -                     size_t dst_len) const; -    virtual size_t -    ReadSectionData (const lldb_private::Section *section, -                     lldb_private::DataExtractor& section_data) const; +    lldb_private::Address +    GetEntryPointAddress() override; +    lldb_private::Address +    GetHeaderAddress() override; +     +    ObjectFile::Type +    CalculateType() override; +     +    ObjectFile::Strata +    CalculateStrata() override; +      //------------------------------------------------------------------      // PluginInterface protocol      //------------------------------------------------------------------ -    virtual lldb_private::ConstString -    GetPluginName(); +    lldb_private::ConstString +    GetPluginName() override; -    virtual uint32_t -    GetPluginVersion(); +    uint32_t +    GetPluginVersion() override; -    virtual lldb_private::Address -    GetEntryPointAddress (); -     -    virtual lldb_private::Address -    GetHeaderAddress (); -     -    virtual ObjectFile::Type -    CalculateType(); -     -    virtual ObjectFile::Strata -    CalculateStrata();  protected:      lldb::ObjectFileJITDelegateWP m_delegate_wp;  }; -#endif  // liblldb_ObjectFileJIT_h_ +#endif // liblldb_ObjectFileJIT_h_ | 
