Beispiel #1
0
lldb::DisassemblerSP 
Disassembler::DisassembleBytes (const ArchSpec &arch,
                                const char *plugin_name,
                                const char *flavor,
                                const Address &start,
                                const void *src,
                                size_t src_len,
                                uint32_t num_instructions,
                                bool data_from_file)
{
    lldb::DisassemblerSP disasm_sp;
    
    if (src)
    {
        disasm_sp = Disassembler::FindPlugin(arch, flavor, plugin_name);
        
        if (disasm_sp)
        {
            DataExtractor data(src, src_len, arch.GetByteOrder(), arch.GetAddressByteSize());
            
            (void)disasm_sp->DecodeInstructions (start,
                                                 data,
                                                 0,
                                                 num_instructions,
                                                 false,
                                                 data_from_file);
        }
    }
    
    return disasm_sp;
}
Beispiel #2
0
lldb::DisassemblerSP 
Disassembler::DisassembleBytes 
(
    const ArchSpec &arch,
    const char *plugin_name,
    const Address &start,
    const void *bytes,
    size_t length,
    uint32_t num_instructions
)
{
    lldb::DisassemblerSP disasm_sp;
    
    if (bytes)
    {
        disasm_sp.reset(Disassembler::FindPlugin(arch, plugin_name));
        
        if (disasm_sp)
        {
            DataExtractor data(bytes, length, arch.GetByteOrder(), arch.GetAddressByteSize());
            
            (void)disasm_sp->DecodeInstructions (start,
                                                 data,
                                                 0,
                                                 num_instructions,
                                                 false);
        }
    }
    
    return disasm_sp;
}
Beispiel #3
0
static llvm::Optional<std::pair<lldb::ByteOrder, uint32_t>>
GetByteOrderAndAddrSize(Thread *thread) {
  if (!thread)
    return llvm::None;
  ProcessSP process_sp = thread->GetProcess();
  if (!process_sp)
    return llvm::None;
  ArchSpec arch = process_sp->GetTarget().GetArchitecture();
  return std::make_pair(arch.GetByteOrder(), arch.GetAddressByteSize());
}
Beispiel #4
0
bool
ArchSpec::Compare (const ArchSpec& rhs, bool exact_match) const
{
    if (GetByteOrder() != rhs.GetByteOrder())
        return false;
        
    const ArchSpec::Core lhs_core = GetCore ();
    const ArchSpec::Core rhs_core = rhs.GetCore ();

    const bool core_match = cores_match (lhs_core, rhs_core, true, exact_match);

    if (core_match)
    {
        const llvm::Triple &lhs_triple = GetTriple();
        const llvm::Triple &rhs_triple = rhs.GetTriple();

        const llvm::Triple::VendorType lhs_triple_vendor = lhs_triple.getVendor();
        const llvm::Triple::VendorType rhs_triple_vendor = rhs_triple.getVendor();
        if (lhs_triple_vendor != rhs_triple_vendor)
        {
            const bool rhs_vendor_specified = rhs.TripleVendorWasSpecified();
            const bool lhs_vendor_specified = TripleVendorWasSpecified();
            // Both architectures had the vendor specified, so if they aren't
            // equal then we return false
            if (rhs_vendor_specified && lhs_vendor_specified)
                return false;
            
            // Only fail if both vendor types are not unknown
            if (lhs_triple_vendor != llvm::Triple::UnknownVendor &&
                rhs_triple_vendor != llvm::Triple::UnknownVendor)
                return false;
        }
        
        const llvm::Triple::OSType lhs_triple_os = lhs_triple.getOS();
        const llvm::Triple::OSType rhs_triple_os = rhs_triple.getOS();
        if (lhs_triple_os != rhs_triple_os)
        {
            const bool rhs_os_specified = rhs.TripleOSWasSpecified();
            const bool lhs_os_specified = TripleOSWasSpecified();
            // Both architectures had the OS specified, so if they aren't
            // equal then we return false
            if (rhs_os_specified && lhs_os_specified)
                return false;
            // Only fail if both os types are not unknown
            if (lhs_triple_os != llvm::Triple::UnknownOS &&
                rhs_triple_os != llvm::Triple::UnknownOS)
                return false;
        }

        const llvm::Triple::EnvironmentType lhs_triple_env = lhs_triple.getEnvironment();
        const llvm::Triple::EnvironmentType rhs_triple_env = rhs_triple.getEnvironment();
            
        if (lhs_triple_env != rhs_triple_env)
        {
            // Only fail if both environment types are not unknown
            if (lhs_triple_env != llvm::Triple::UnknownEnvironment &&
                rhs_triple_env != llvm::Triple::UnknownEnvironment)
                return false;
        }
        return true;
    }
    return false;
}
size_t
DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
                                     const ArchSpec &arch) {
  assert(!m_finalized);
  StructuredData::Array *sets = nullptr;
  if (dict.GetValueForKeyAsArray("sets", sets)) {
    const uint32_t num_sets = sets->GetSize();
    for (uint32_t i = 0; i < num_sets; ++i) {
      std::string set_name_str;
      ConstString set_name;
      if (sets->GetItemAtIndexAsString(i, set_name_str))
        set_name.SetCString(set_name_str.c_str());
      if (set_name) {
        RegisterSet new_set = {set_name.AsCString(), NULL, 0, NULL};
        m_sets.push_back(new_set);
      } else {
        Clear();
        printf("error: register sets must have valid names\n");
        return 0;
      }
    }
    m_set_reg_nums.resize(m_sets.size());
  }
  StructuredData::Array *regs = nullptr;
  if (!dict.GetValueForKeyAsArray("registers", regs))
    return 0;

  const uint32_t num_regs = regs->GetSize();
  //        typedef std::map<std::string, std::vector<std::string> >
  //        InvalidateNameMap;
  //        InvalidateNameMap invalidate_map;
  for (uint32_t i = 0; i < num_regs; ++i) {
    StructuredData::Dictionary *reg_info_dict = nullptr;
    if (!regs->GetItemAtIndexAsDictionary(i, reg_info_dict)) {
      Clear();
      printf("error: items in the 'registers' array must be dictionaries\n");
      regs->DumpToStdout();
      return 0;
    }

    // { 'name':'rcx'       , 'bitsize' :  64, 'offset' :  16, 'encoding':'uint'
    // , 'format':'hex'         , 'set': 0, 'ehframe' : 2,
    // 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },
    RegisterInfo reg_info;
    std::vector<uint32_t> value_regs;
    std::vector<uint32_t> invalidate_regs;
    memset(&reg_info, 0, sizeof(reg_info));

    ConstString name_val;
    ConstString alt_name_val;
    if (!reg_info_dict->GetValueForKeyAsString("name", name_val, nullptr)) {
      Clear();
      printf("error: registers must have valid names and offsets\n");
      reg_info_dict->DumpToStdout();
      return 0;
    }
    reg_info.name = name_val.GetCString();
    reg_info_dict->GetValueForKeyAsString("alt-name", alt_name_val, nullptr);
    reg_info.alt_name = alt_name_val.GetCString();

    reg_info_dict->GetValueForKeyAsInteger("offset", reg_info.byte_offset,
                                           UINT32_MAX);

    const ByteOrder byte_order = arch.GetByteOrder();

    if (reg_info.byte_offset == UINT32_MAX) {
      // No offset for this register, see if the register has a value expression
      // which indicates this register is part of another register. Value
      // expressions
      // are things like "rax[31:0]" which state that the current register's
      // value
      // is in a concrete register "rax" in bits 31:0. If there is a value
      // expression
      // we can calculate the offset
      bool success = false;
      std::string slice_str;
      if (reg_info_dict->GetValueForKeyAsString("slice", slice_str, nullptr)) {
        // Slices use the following format:
        //  REGNAME[MSBIT:LSBIT]
        // REGNAME - name of the register to grab a slice of
        // MSBIT - the most significant bit at which the current register value
        // starts at
        // LSBIT - the least significant bit at which the current register value
        // ends at
        static RegularExpression g_bitfield_regex(
            llvm::StringRef("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]"));
        RegularExpression::Match regex_match(3);
        if (g_bitfield_regex.Execute(slice_str, &regex_match)) {
          llvm::StringRef reg_name_str;
          std::string msbit_str;
          std::string lsbit_str;
          if (regex_match.GetMatchAtIndex(slice_str.c_str(), 1, reg_name_str) &&
              regex_match.GetMatchAtIndex(slice_str.c_str(), 2, msbit_str) &&
              regex_match.GetMatchAtIndex(slice_str.c_str(), 3, lsbit_str)) {
            const uint32_t msbit =
                StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX);
            const uint32_t lsbit =
                StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX);
            if (msbit != UINT32_MAX && lsbit != UINT32_MAX) {
              if (msbit > lsbit) {
                const uint32_t msbyte = msbit / 8;
                const uint32_t lsbyte = lsbit / 8;

                ConstString containing_reg_name(reg_name_str);

                RegisterInfo *containing_reg_info =
                    GetRegisterInfo(containing_reg_name);
                if (containing_reg_info) {
                  const uint32_t max_bit = containing_reg_info->byte_size * 8;
                  if (msbit < max_bit && lsbit < max_bit) {
                    m_invalidate_regs_map[containing_reg_info
                                              ->kinds[eRegisterKindLLDB]]
                        .push_back(i);
                    m_value_regs_map[i].push_back(
                        containing_reg_info->kinds[eRegisterKindLLDB]);
                    m_invalidate_regs_map[i].push_back(
                        containing_reg_info->kinds[eRegisterKindLLDB]);

                    if (byte_order == eByteOrderLittle) {
                      success = true;
                      reg_info.byte_offset =
                          containing_reg_info->byte_offset + lsbyte;
                    } else if (byte_order == eByteOrderBig) {
                      success = true;
                      reg_info.byte_offset =
                          containing_reg_info->byte_offset + msbyte;
                    } else {
                      llvm_unreachable("Invalid byte order");
                    }
                  } else {
                    if (msbit > max_bit)
                      printf("error: msbit (%u) must be less than the bitsize "
                             "of the register (%u)\n",
                             msbit, max_bit);
                    else
                      printf("error: lsbit (%u) must be less than the bitsize "
                             "of the register (%u)\n",
                             lsbit, max_bit);
                  }
                } else {
                  printf("error: invalid concrete register \"%s\"\n",
                         containing_reg_name.GetCString());
                }
              } else {
                printf("error: msbit (%u) must be greater than lsbit (%u)\n",
                       msbit, lsbit);
              }
            } else {
              printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit,
                     lsbit);
            }
          } else {
            // TODO: print error invalid slice string that doesn't follow the
            // format
            printf("error: failed to extract regex matches for parsing the "
                   "register bitfield regex\n");
          }
        } else {
          // TODO: print error invalid slice string that doesn't follow the
          // format
          printf("error: failed to match against register bitfield regex\n");
        }
      } else {
        StructuredData::Array *composite_reg_list = nullptr;
        if (reg_info_dict->GetValueForKeyAsArray("composite",
                                                 composite_reg_list)) {
          const size_t num_composite_regs = composite_reg_list->GetSize();
          if (num_composite_regs > 0) {
            uint32_t composite_offset = UINT32_MAX;
            for (uint32_t composite_idx = 0; composite_idx < num_composite_regs;
                 ++composite_idx) {
              ConstString composite_reg_name;
              if (composite_reg_list->GetItemAtIndexAsString(
                      composite_idx, composite_reg_name, nullptr)) {
                RegisterInfo *composite_reg_info =
                    GetRegisterInfo(composite_reg_name);
                if (composite_reg_info) {
                  composite_offset = std::min(composite_offset,
                                              composite_reg_info->byte_offset);
                  m_value_regs_map[i].push_back(
                      composite_reg_info->kinds[eRegisterKindLLDB]);
                  m_invalidate_regs_map[composite_reg_info
                                            ->kinds[eRegisterKindLLDB]]
                      .push_back(i);
                  m_invalidate_regs_map[i].push_back(
                      composite_reg_info->kinds[eRegisterKindLLDB]);
                } else {
                  // TODO: print error invalid slice string that doesn't follow
                  // the format
                  printf("error: failed to find composite register by name: "
                         "\"%s\"\n",
                         composite_reg_name.GetCString());
                }
              } else {
                printf(
                    "error: 'composite' list value wasn't a python string\n");
              }
            }
            if (composite_offset != UINT32_MAX) {
              reg_info.byte_offset = composite_offset;
              success = m_value_regs_map.find(i) != m_value_regs_map.end();
            } else {
              printf("error: 'composite' registers must specify at least one "
                     "real register\n");
            }
          } else {
            printf("error: 'composite' list was empty\n");
          }
        }
      }

      if (!success) {
        Clear();
        reg_info_dict->DumpToStdout();
        return 0;
      }
    }

    int64_t bitsize = 0;
    if (!reg_info_dict->GetValueForKeyAsInteger("bitsize", bitsize)) {
      Clear();
      printf("error: invalid or missing 'bitsize' key/value pair in register "
             "dictionary\n");
      reg_info_dict->DumpToStdout();
      return 0;
    }

    reg_info.byte_size = bitsize / 8;

    std::string dwarf_opcode_string;
    if (reg_info_dict->GetValueForKeyAsString("dynamic_size_dwarf_expr_bytes",
                                              dwarf_opcode_string)) {
      reg_info.dynamic_size_dwarf_len = dwarf_opcode_string.length() / 2;
      assert(reg_info.dynamic_size_dwarf_len > 0);

      std::vector<uint8_t> dwarf_opcode_bytes(reg_info.dynamic_size_dwarf_len);
      uint32_t j;
      StringExtractor opcode_extractor;
      // Swap "dwarf_opcode_string" over into "opcode_extractor"
      opcode_extractor.GetStringRef().swap(dwarf_opcode_string);
      uint32_t ret_val = opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes);
      assert(ret_val == reg_info.dynamic_size_dwarf_len);

      for (j = 0; j < reg_info.dynamic_size_dwarf_len; ++j)
        m_dynamic_reg_size_map[i].push_back(dwarf_opcode_bytes[j]);

      reg_info.dynamic_size_dwarf_expr_bytes = m_dynamic_reg_size_map[i].data();
    }

    std::string format_str;
    if (reg_info_dict->GetValueForKeyAsString("format", format_str, nullptr)) {
      if (Args::StringToFormat(format_str.c_str(), reg_info.format, NULL)
              .Fail()) {
        Clear();
        printf("error: invalid 'format' value in register dictionary\n");
        reg_info_dict->DumpToStdout();
        return 0;
      }
    } else {
      reg_info_dict->GetValueForKeyAsInteger("format", reg_info.format,
                                             eFormatHex);
    }

    std::string encoding_str;
    if (reg_info_dict->GetValueForKeyAsString("encoding", encoding_str))
      reg_info.encoding = Args::StringToEncoding(encoding_str, eEncodingUint);
    else
      reg_info_dict->GetValueForKeyAsInteger("encoding", reg_info.encoding,
                                             eEncodingUint);

    size_t set = 0;
    if (!reg_info_dict->GetValueForKeyAsInteger<size_t>("set", set, -1) ||
        set >= m_sets.size()) {
      Clear();
      printf("error: invalid 'set' value in register dictionary, valid values "
             "are 0 - %i\n",
             (int)set);
      reg_info_dict->DumpToStdout();
      return 0;
    }

    // Fill in the register numbers
    reg_info.kinds[lldb::eRegisterKindLLDB] = i;
    reg_info.kinds[lldb::eRegisterKindProcessPlugin] = i;
    uint32_t eh_frame_regno = LLDB_INVALID_REGNUM;
    reg_info_dict->GetValueForKeyAsInteger("gcc", eh_frame_regno,
                                           LLDB_INVALID_REGNUM);
    if (eh_frame_regno == LLDB_INVALID_REGNUM)
      reg_info_dict->GetValueForKeyAsInteger("ehframe", eh_frame_regno,
                                             LLDB_INVALID_REGNUM);
    reg_info.kinds[lldb::eRegisterKindEHFrame] = eh_frame_regno;
    reg_info_dict->GetValueForKeyAsInteger(
        "dwarf", reg_info.kinds[lldb::eRegisterKindDWARF], LLDB_INVALID_REGNUM);
    std::string generic_str;
    if (reg_info_dict->GetValueForKeyAsString("generic", generic_str))
      reg_info.kinds[lldb::eRegisterKindGeneric] =
          Args::StringToGenericRegister(generic_str);
    else
      reg_info_dict->GetValueForKeyAsInteger(
          "generic", reg_info.kinds[lldb::eRegisterKindGeneric],
          LLDB_INVALID_REGNUM);

    // Check if this register invalidates any other register values when it is
    // modified
    StructuredData::Array *invalidate_reg_list = nullptr;
    if (reg_info_dict->GetValueForKeyAsArray("invalidate-regs",
                                             invalidate_reg_list)) {
      const size_t num_regs = invalidate_reg_list->GetSize();
      if (num_regs > 0) {
        for (uint32_t idx = 0; idx < num_regs; ++idx) {
          ConstString invalidate_reg_name;
          uint64_t invalidate_reg_num;
          if (invalidate_reg_list->GetItemAtIndexAsString(
                  idx, invalidate_reg_name)) {
            RegisterInfo *invalidate_reg_info =
                GetRegisterInfo(invalidate_reg_name);
            if (invalidate_reg_info) {
              m_invalidate_regs_map[i].push_back(
                  invalidate_reg_info->kinds[eRegisterKindLLDB]);
            } else {
              // TODO: print error invalid slice string that doesn't follow the
              // format
              printf("error: failed to find a 'invalidate-regs' register for "
                     "\"%s\" while parsing register \"%s\"\n",
                     invalidate_reg_name.GetCString(), reg_info.name);
            }
          } else if (invalidate_reg_list->GetItemAtIndexAsInteger(
                         idx, invalidate_reg_num)) {
            if (invalidate_reg_num != UINT64_MAX)
              m_invalidate_regs_map[i].push_back(invalidate_reg_num);
            else
              printf("error: 'invalidate-regs' list value wasn't a valid "
                     "integer\n");
          } else {
            printf("error: 'invalidate-regs' list value wasn't a python string "
                   "or integer\n");
          }
        }
      } else {
        printf("error: 'invalidate-regs' contained an empty list\n");
      }
    }

    // Calculate the register offset
    const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
    if (m_reg_data_byte_size < end_reg_offset)
      m_reg_data_byte_size = end_reg_offset;

    m_regs.push_back(reg_info);
    m_set_reg_nums[set].push_back(i);
  }
  Finalize(arch);
  return m_regs.size();
}