forked from OSchip/llvm-project
Add a ProcessStructReader utility class to LLDB
The purpose of a ProcessStructReader is to allow intelligent reading of data from the underlying process Traditionally, the way this has been handled is to have a load_address and shuffle it around, and use Process::ReadMemory()-kind APIs With a ProcessStructReader one can define a clang type that matches exactly the definition of the thing they are trying to ingest from the inferior process, and then just point LLDB at where the data is Since this work is done in terms of clang types, one can honor packed/aligned attributes, sizes of types on the inferior architecture, and similar tricky caveats without having to hardcode them llvm-svn: 217644
This commit is contained in:
parent
6f8525d8a6
commit
13460a59fd
|
@ -0,0 +1,98 @@
|
|||
//===---------------------ProcessStructReader.h ------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef utility_ProcessStructReader_h_
|
||||
#define utility_ProcessStructReader_h_
|
||||
|
||||
#include "lldb/lldb-defines.h"
|
||||
#include "lldb/lldb-types.h"
|
||||
|
||||
#include "lldb/Core/ConstString.h"
|
||||
#include "lldb/Core/DataExtractor.h"
|
||||
#include "lldb/Core/Error.h"
|
||||
#include "lldb/Symbol/ClangASTType.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
|
||||
#include <initializer_list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace lldb_private {
|
||||
class ProcessStructReader
|
||||
{
|
||||
protected:
|
||||
struct FieldImpl
|
||||
{
|
||||
ClangASTType type;
|
||||
size_t offset;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
std::map<ConstString, FieldImpl> m_fields;
|
||||
DataExtractor m_data;
|
||||
lldb::ByteOrder m_byte_order;
|
||||
size_t m_addr_byte_size;
|
||||
|
||||
public:
|
||||
ProcessStructReader (Process *process, lldb::addr_t base_addr, ClangASTType struct_type)
|
||||
{
|
||||
if (!process)
|
||||
return;
|
||||
if (base_addr == 0 || base_addr == LLDB_INVALID_ADDRESS)
|
||||
return;
|
||||
m_byte_order = process->GetByteOrder();
|
||||
m_addr_byte_size = process->GetAddressByteSize();
|
||||
|
||||
for (size_t idx = 0; idx < struct_type.GetNumFields(); idx++)
|
||||
{
|
||||
std::string name;
|
||||
uint64_t bit_offset;
|
||||
uint32_t bitfield_bit_size;
|
||||
bool is_bitfield;
|
||||
ClangASTType field_type = struct_type.GetFieldAtIndex(idx,name,&bit_offset,&bitfield_bit_size,&is_bitfield);
|
||||
// no support for bitfields in here (yet)
|
||||
if (is_bitfield)
|
||||
return;
|
||||
auto size = field_type.GetByteSize();
|
||||
// no support for things larger than a uint64_t (yet)
|
||||
if (size > 8)
|
||||
return;
|
||||
m_fields[ConstString(name.c_str())] = FieldImpl{field_type,bit_offset/8,size};
|
||||
}
|
||||
size_t total_size = struct_type.GetByteSize();
|
||||
lldb::DataBufferSP buffer_sp(new DataBufferHeap(total_size,0));
|
||||
Error error;
|
||||
process->ReadMemoryFromInferior(base_addr,
|
||||
buffer_sp->GetBytes(),
|
||||
total_size,
|
||||
error);
|
||||
if (error.Fail())
|
||||
return;
|
||||
m_data = DataExtractor(buffer_sp,m_byte_order,m_addr_byte_size);
|
||||
}
|
||||
|
||||
template<typename RetType>
|
||||
RetType
|
||||
GetField (ConstString name, RetType fail_value = RetType())
|
||||
{
|
||||
auto iter = m_fields.find(name), end = m_fields.end();
|
||||
if (iter == end)
|
||||
return fail_value;
|
||||
auto size = iter->second.size;
|
||||
if (sizeof(RetType) < size)
|
||||
return fail_value;
|
||||
lldb::offset_t offset = iter->second.offset;
|
||||
if (offset + size > m_data.GetByteSize())
|
||||
return fail_value;
|
||||
return (RetType)(m_data.GetMaxU64(&offset, size));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // utility_ProcessStructReader_h_
|
|
@ -2047,6 +2047,7 @@
|
|||
94EA27CD17DE91750070F505 /* LibCxxUnorderedMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxUnorderedMap.cpp; path = source/DataFormatters/LibCxxUnorderedMap.cpp; sourceTree = "<group>"; };
|
||||
94EBAC8313D9EE26009BA64E /* PythonPointer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PythonPointer.h; path = include/lldb/Utility/PythonPointer.h; sourceTree = "<group>"; };
|
||||
94EE33F218643C6900CD703B /* FormattersContainer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FormattersContainer.h; path = include/lldb/DataFormatters/FormattersContainer.h; sourceTree = "<group>"; };
|
||||
94F6C4D119C264C70049D089 /* ProcessStructReader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ProcessStructReader.h; path = include/lldb/Utility/ProcessStructReader.h; sourceTree = "<group>"; };
|
||||
94FA3DDD1405D4E500833217 /* ValueObjectConstResultChild.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ValueObjectConstResultChild.h; path = include/lldb/Core/ValueObjectConstResultChild.h; sourceTree = "<group>"; };
|
||||
94FA3DDF1405D50300833217 /* ValueObjectConstResultChild.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectConstResultChild.cpp; path = source/Core/ValueObjectConstResultChild.cpp; sourceTree = "<group>"; };
|
||||
94FE476613FC1DA8001F8475 /* finish-swig-Python-LLDB.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "finish-swig-Python-LLDB.sh"; sourceTree = "<group>"; };
|
||||
|
@ -2960,6 +2961,7 @@
|
|||
26D1804416CEE12500EDFB5B /* KQueue.h */,
|
||||
26D1803C16CEBFD300EDFB5B /* KQueue.cpp */,
|
||||
94031A9F13CF5B3D00DCFF3C /* PriorityPointerPair.h */,
|
||||
94F6C4D119C264C70049D089 /* ProcessStructReader.h */,
|
||||
2682F16B115EDA0D00CCFF99 /* PseudoTerminal.h */,
|
||||
2682F16A115EDA0D00CCFF99 /* PseudoTerminal.cpp */,
|
||||
4CAB257C18EC9DB800BAD33E /* SafeMachO.h */,
|
||||
|
|
Loading…
Reference in New Issue