예제 #1
0
// Minidump string
llvm::Optional<std::string>
lldb_private::minidump::parseMinidumpString(llvm::ArrayRef<uint8_t> &data) {
  std::string result;

  const uint32_t *source_length;
  Status error = consumeObject(data, source_length);
  if (error.Fail() || *source_length > data.size() || *source_length % 2 != 0)
    return llvm::None;

  auto source_start = reinterpret_cast<const llvm::UTF16 *>(data.data());
  // source_length is the length of the string in bytes
  // we need the length of the string in UTF-16 characters/code points (16 bits
  // per char)
  // that's why it's divided by 2
  const auto source_end = source_start + (*source_length) / 2;
  // resize to worst case length
  result.resize(UNI_MAX_UTF8_BYTES_PER_CODE_POINT * (*source_length) / 2);
  auto result_start = reinterpret_cast<llvm::UTF8 *>(&result[0]);
  const auto result_end = result_start + result.size();
  llvm::ConvertUTF16toUTF8(&source_start, source_end, &result_start, result_end,
                           llvm::strictConversion);
  const auto result_size =
      std::distance(reinterpret_cast<llvm::UTF8 *>(&result[0]), result_start);
  result.resize(result_size); // shrink to actual length

  return result;
}
예제 #2
0
void
PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes)
{
    const char *data = reinterpret_cast<const char *>(bytes.data());
    PyObject *py_bytes = PyBytes_FromStringAndSize(data, bytes.size());
    PythonObject::Reset(PyRefType::Owned, py_bytes);
}
예제 #3
0
llvm::ArrayRef<MinidumpThread>
MinidumpThread::ParseThreadList(llvm::ArrayRef<uint8_t> &data) {
  const llvm::support::ulittle32_t *thread_count;
  Status error = consumeObject(data, thread_count);
  if (error.Fail() || *thread_count * sizeof(MinidumpThread) > data.size())
    return {};

  return llvm::ArrayRef<MinidumpThread>(
      reinterpret_cast<const MinidumpThread *>(data.data()), *thread_count);
}
예제 #4
0
llvm::ArrayRef<MinidumpModule>
MinidumpModule::ParseModuleList(llvm::ArrayRef<uint8_t> &data) {

  const llvm::support::ulittle32_t *modules_count;
  Status error = consumeObject(data, modules_count);
  if (error.Fail() || *modules_count * sizeof(MinidumpModule) > data.size())
    return {};

  return llvm::ArrayRef<MinidumpModule>(
      reinterpret_cast<const MinidumpModule *>(data.data()), *modules_count);
}
예제 #5
0
static void DumpDWARFExpr(Stream &s, llvm::ArrayRef<uint8_t> expr, Thread *thread) {
  if (auto order_and_width = GetByteOrderAndAddrSize(thread)) {
    DataExtractor extractor(expr.data(), expr.size(), order_and_width->first,
                            order_and_width->second);
    if (!DWARFExpression::PrintDWARFExpression(s, extractor,
                                               order_and_width->second,
                                               /*dwarf_ref_size*/ 4,
                                               /*location_expression*/ false))
      s.PutCString("invalid-dwarf-expr");
  } else
    s.PutCString("dwarf-expr");
}
예제 #6
0
llvm::ArrayRef<MinidumpMemoryDescriptor>
MinidumpMemoryDescriptor::ParseMemoryList(llvm::ArrayRef<uint8_t> &data) {
  const llvm::support::ulittle32_t *mem_ranges_count;
  Status error = consumeObject(data, mem_ranges_count);
  if (error.Fail() ||
      *mem_ranges_count * sizeof(MinidumpMemoryDescriptor) > data.size())
    return {};

  return llvm::makeArrayRef(
      reinterpret_cast<const MinidumpMemoryDescriptor *>(data.data()),
      *mem_ranges_count);
}
예제 #7
0
  /// \brief Write a block of data, and get the offset that it starts at.
  /// \param Bytes the array of bytes to be written.
  /// \return the offset that this block was written at.
  ///
  offset_uint write(llvm::ArrayRef<char> Bytes) {
    // If the stream doesn't exist, silently ignore the write request.
    if (!Out)
      return noOffset();
    
    auto const Size = Bytes.size();
    Out->write(Bytes.data(), Size);

    // Update the current offset and return the original value.
    auto const WrittenAt = Offset;
    Offset += Size;
    return WrittenAt;
  }
예제 #8
0
std::pair<llvm::ArrayRef<MinidumpMemoryDescriptor64>, uint64_t>
MinidumpMemoryDescriptor64::ParseMemory64List(llvm::ArrayRef<uint8_t> &data) {
  const llvm::support::ulittle64_t *mem_ranges_count;
  Status error = consumeObject(data, mem_ranges_count);
  if (error.Fail() ||
      *mem_ranges_count * sizeof(MinidumpMemoryDescriptor64) > data.size())
    return {};

  const llvm::support::ulittle64_t *base_rva;
  error = consumeObject(data, base_rva);
  if (error.Fail())
    return {};

  return std::make_pair(
      llvm::makeArrayRef(
          reinterpret_cast<const MinidumpMemoryDescriptor64 *>(data.data()),
          *mem_ranges_count),
      *base_rva);
}
예제 #9
0
// Linux Proc Status
// it's stored as an ascii string in the file
llvm::Optional<LinuxProcStatus>
LinuxProcStatus::Parse(llvm::ArrayRef<uint8_t> &data) {
  LinuxProcStatus result;
  result.proc_status =
      llvm::StringRef(reinterpret_cast<const char *>(data.data()), data.size());
  data = data.drop_front(data.size());

  llvm::SmallVector<llvm::StringRef, 0> lines;
  result.proc_status.split(lines, '\n', 42);
  // /proc/$pid/status has 41 lines, but why not use 42?
  for (auto line : lines) {
    if (line.consume_front("Pid:")) {
      line = line.trim();
      if (!line.getAsInteger(10, result.pid))
        return result;
    }
  }

  return llvm::None;
}
예제 #10
0
std::vector<const MinidumpMemoryInfo *>
MinidumpMemoryInfo::ParseMemoryInfoList(llvm::ArrayRef<uint8_t> &data) {
  const MinidumpMemoryInfoListHeader *header;
  Status error = consumeObject(data, header);
  if (error.Fail() ||
      header->size_of_header < sizeof(MinidumpMemoryInfoListHeader) ||
      header->size_of_entry < sizeof(MinidumpMemoryInfo))
    return {};

  data = data.drop_front(header->size_of_header -
                         sizeof(MinidumpMemoryInfoListHeader));

  if (header->size_of_entry * header->num_of_entries > data.size())
    return {};

  std::vector<const MinidumpMemoryInfo *> result;
  for (uint64_t i = 0; i < header->num_of_entries; ++i) {
    result.push_back(reinterpret_cast<const MinidumpMemoryInfo *>(
        data.data() + i * header->size_of_entry));
  }

  return result;
}
예제 #11
0
PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes)
    : PythonByteArray(bytes.data(), bytes.size()) {}