18#include "llvm/BinaryFormat/Dwarf.h"
19#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
20#include "llvm/DebugInfo/CodeView/TypeIndex.h"
21#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
22#include "llvm/Support/Endian.h"
36 if (register_id == llvm::codeview::RegisterId::VFRAME)
43 llvm::codeview::RegisterId register_id,
56 case SimpleTypeKind::Int128:
57 case SimpleTypeKind::Int64:
58 case SimpleTypeKind::Int64Quad:
59 case SimpleTypeKind::Int32:
60 case SimpleTypeKind::Int32Long:
61 case SimpleTypeKind::Int16:
62 case SimpleTypeKind::Int16Short:
63 case SimpleTypeKind::Float128:
64 case SimpleTypeKind::Float80:
65 case SimpleTypeKind::Float64:
66 case SimpleTypeKind::Float32:
67 case SimpleTypeKind::Float16:
68 case SimpleTypeKind::NarrowCharacter:
69 case SimpleTypeKind::SignedCharacter:
70 case SimpleTypeKind::SByte:
77static llvm::Expected<std::pair<size_t, bool>>
80 SimpleTypeKind stk = ti.getSimpleKind();
85 CVType cvt = tpi.getType(ti);
89 if (
auto err = TypeDeserializer::deserializeAs<ModifierRecord>(cvt, mfr))
90 return std::move(err);
95 if (
auto err = TypeDeserializer::deserializeAs<PointerRecord>(cvt, pr))
96 return std::move(err);
97 return std::make_pair(pr.getSize(),
false);
101 if (
auto err = TypeDeserializer::deserializeAs<EnumRecord>(cvt, er))
102 return std::move(err);
106 return llvm::make_error<llvm::StringError>(
"Type is not integral",
107 llvm::inconvertibleErrorCode());
111template <
typename StreamWriter>
113 StreamWriter &&writer) {
114 const ArchSpec &architecture =
module->GetArchitecture();
123 if (!writer(stream, register_kind))
127 std::make_shared<DataBufferHeap>(stream.
GetData(), stream.
GetSize());
144 llvm::dwarf::LocationAtom base =
145 relative_offset ? llvm::dwarf::DW_OP_bregx : llvm::dwarf::DW_OP_regx;
149 llvm::dwarf::LocationAtom base =
150 relative_offset ? llvm::dwarf::DW_OP_breg0 : llvm::dwarf::DW_OP_reg0;
151 stream.
PutHex8(base + reg_num);
165 indir_offset, module))
168 stream.
PutHex8(llvm::dwarf::DW_OP_deref);
169 stream.
PutHex8(llvm::dwarf::DW_OP_plus_uconst);
176 llvm::codeview::RegisterId reg, std::optional<int32_t> relative_offset,
181 stream, reg, register_kind, relative_offset, module);
191 llvm::codeview::RegisterId reg, int32_t offset,
lldb::ModuleSP module) {
196 llvm::codeview::RegisterId reg, int32_t offset, int32_t offset_in_udt,
201 stream, reg, register_kind, offset, offset_in_udt, module);
206 llvm::StringRef program, llvm::Triple::ArchType arch_type,
Stream &stream) {
213 llvm::StringRef fpo_program, int32_t offset,
lldb::ModuleSP module) {
216 const ArchSpec &architecture =
module->GetArchitecture();
222 stream.
PutHex8(llvm::dwarf::DW_OP_consts);
224 stream.
PutHex8(llvm::dwarf::DW_OP_plus);
233 uint16_t section, uint32_t offset,
ModuleSP module) {
239 stream.
PutHex8(llvm::dwarf::DW_OP_addr);
241 SectionList *section_list =
module->GetSectionList();
242 assert(section_list);
248 stream.
PutMaxHex64(section_ptr->GetFileAddress() + offset,
255llvm::Expected<DWARFExpression>
258 const llvm::APSInt &constant,
260 const ArchSpec &architecture =
module->GetArchitecture();
265 return type_info.takeError();
266 auto [size, is_signed] = *type_info;
269 llvm::support::little64_t I;
270 llvm::support::ulittle64_t U;
273 std::shared_ptr<DataBufferHeap> buffer = std::make_shared<DataBufferHeap>();
274 buffer->SetByteSize(size);
276 llvm::ArrayRef<uint8_t> bytes;
278 Value.I = constant.getSExtValue();
280 Value.U = constant.getZExtValue();
283 bytes = llvm::ArrayRef(
reinterpret_cast<const uint8_t *
>(&
Value), 8)
285 buffer->CopyData(bytes.data(), size);
293 const std::map<uint64_t, MemberValLocation> &offset_to_location,
294 std::map<uint64_t, size_t> &offset_to_size,
size_t total_size,
298 size_t cur_offset = 0;
299 bool is_simple_type = offset_to_size.empty();
302 for (
const auto &offset_loc : offset_to_location) {
303 if (cur_offset < offset_loc.first) {
304 stream.
PutHex8(llvm::dwarf::DW_OP_piece);
305 stream.
PutULEB128(offset_loc.first - cur_offset);
306 cur_offset = offset_loc.first;
309 std::optional<int32_t> offset =
313 stream, (RegisterId)loc.
reg_id, register_kind, offset,
316 if (!is_simple_type) {
317 stream.
PutHex8(llvm::dwarf::DW_OP_piece);
318 stream.
PutULEB128(offset_to_size[offset_loc.first]);
319 cur_offset = offset_loc.first + offset_to_size[offset_loc.first];
325 if (total_size > cur_offset) {
326 stream.
PutHex8(llvm::dwarf::DW_OP_piece);
static bool EmitVFrameEvaluationDWARFExpression(llvm::StringRef program, llvm::Triple::ArchType arch_type, Stream &stream)
uint32_t GetGenericRegisterNumber(llvm::codeview::RegisterId register_id)
static bool MakeRegisterBasedLocationExpressionInternal(Stream &stream, llvm::codeview::RegisterId reg, RegisterKind ®ister_kind, std::optional< int32_t > relative_offset, lldb::ModuleSP module)
static llvm::Expected< std::pair< size_t, bool > > GetIntegralTypeInfo(TypeIndex ti, TpiStream &tpi)
static uint32_t GetRegisterNumber(llvm::Triple::ArchType arch_type, llvm::codeview::RegisterId register_id, RegisterKind ®ister_kind)
static bool IsSimpleTypeSignedInteger(SimpleTypeKind kind)
static bool MakeRegisterBasedIndirectLocationExpressionInternal(Stream &stream, llvm::codeview::RegisterId reg, RegisterKind ®ister_kind, int32_t indir_offset, int32_t offset, lldb::ModuleSP module)
*(reg + indir_offset) + offset
static DWARFExpression MakeLocationExpressionInternal(lldb::ModuleSP module, StreamWriter &&writer)
An architecture specification class.
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
"lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location expression and interprets it.
void SetRegisterKind(lldb::RegisterKind reg_kind)
Set the call-frame-info style register kind.
lldb::SectionSP FindSectionByID(lldb::user_id_t sect_id) const
const char * GetData() const
A stream class that can stream formatted output to a file.
lldb::ByteOrder GetByteOrder() const
uint32_t GetAddressByteSize() const
Get the address size in bytes.
size_t size_t PutHex8(uint8_t uvalue)
Append an uint8_t value in the hexadecimal format to the stream.
@ eBinary
Get and put data as binary instead of as the default string mode.
size_t PutULEB128(uint64_t uval)
Output a ULEB128 number to the stream.
size_t PutSLEB128(int64_t uval)
Output a SLEB128 number to the stream.
size_t PutMaxHex64(uint64_t uvalue, size_t byte_size, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
#define LLDB_INVALID_REGNUM
#define LLDB_REGNUM_GENERIC_FP
DWARFExpression MakeRegRelIndirLocationExpression(llvm::codeview::RegisterId reg, int32_t offset, int32_t offset_in_udt, lldb::ModuleSP module)
DWARFExpression MakeRegRelLocationExpression(llvm::codeview::RegisterId reg, int32_t offset, lldb::ModuleSP module)
size_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind)
DWARFExpression MakeVFrameRelLocationExpression(llvm::StringRef fpo_program, int32_t offset, lldb::ModuleSP module)
llvm::Expected< DWARFExpression > MakeConstantLocationExpression(llvm::codeview::TypeIndex underlying_ti, llvm::pdb::TpiStream &tpi, const llvm::APSInt &constant, lldb::ModuleSP module)
bool TranslateFPOProgramToDWARFExpression(llvm::StringRef program, llvm::StringRef register_name, llvm::Triple::ArchType arch_type, lldb_private::Stream &stream)
DWARFExpression MakeGlobalLocationExpression(uint16_t section, uint32_t offset, lldb::ModuleSP module)
DWARFExpression MakeEnregisteredLocationExpressionForComposite(const std::map< uint64_t, MemberValLocation > &offset_to_location, std::map< uint64_t, size_t > &offset_to_size, size_t total_size, lldb::ModuleSP module)
DWARFExpression MakeEnregisteredLocationExpression(llvm::codeview::RegisterId reg, lldb::ModuleSP module)
uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type, llvm::codeview::RegisterId register_id)
A class that represents a running process on the host machine.
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::Module > ModuleSP
RegisterKind
Register numbering types.
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
@ eRegisterKindLLDB
lldb's internal register numbers
@ eRegisterKindDWARF
the register numbers seen DWARF