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:
80 SimpleTypeKind stk = ti.getSimpleKind();
84 CVType cvt = tpi.getType(ti);
88 llvm::cantFail(TypeDeserializer::deserializeAs<ModifierRecord>(cvt, mfr));
93 llvm::cantFail(TypeDeserializer::deserializeAs<PointerRecord>(cvt, pr));
98 llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
102 assert(
false &&
"Type is not integral!");
107template <
typename StreamWriter>
109 StreamWriter &&writer) {
110 const ArchSpec &architecture = module->GetArchitecture();
120 if (!writer(stream, register_kind))
124 std::make_shared<DataBufferHeap>(stream.
GetData(), stream.
GetSize());
125 DataExtractor extractor(buffer, byte_order, address_size, byte_size);
141 llvm::dwarf::LocationAtom base =
142 relative_offset ? llvm::dwarf::DW_OP_bregx : llvm::dwarf::DW_OP_regx;
146 llvm::dwarf::LocationAtom base =
147 relative_offset ? llvm::dwarf::DW_OP_breg0 : llvm::dwarf::DW_OP_reg0;
148 stream.
PutHex8(base + reg_num);
158 llvm::codeview::RegisterId reg, std::optional<int32_t> relative_offset,
163 stream, reg, register_kind, relative_offset, module);
173 llvm::codeview::RegisterId reg, int32_t offset,
lldb::ModuleSP module) {
178 llvm::StringRef program, llvm::Triple::ArchType arch_type,
Stream &stream) {
185 llvm::StringRef fpo_program, int32_t offset,
lldb::ModuleSP module) {
188 const ArchSpec &architecture = module->GetArchitecture();
194 stream.
PutHex8(llvm::dwarf::DW_OP_consts);
196 stream.
PutHex8(llvm::dwarf::DW_OP_plus);
205 uint16_t section, uint32_t offset,
ModuleSP module) {
211 stream.
PutHex8(llvm::dwarf::DW_OP_addr);
213 SectionList *section_list = module->GetSectionList();
214 assert(section_list);
220 stream.
PutMaxHex64(section_ptr->GetFileAddress() + offset,
228 TypeIndex underlying_ti, TpiStream &tpi,
const llvm::APSInt &constant,
230 const ArchSpec &architecture = module->GetArchitecture();
234 bool is_signed =
false;
238 llvm::support::little64_t I;
239 llvm::support::ulittle64_t U;
242 std::shared_ptr<DataBufferHeap> buffer = std::make_shared<DataBufferHeap>();
243 buffer->SetByteSize(size);
245 llvm::ArrayRef<uint8_t> bytes;
247 Value.I = constant.getSExtValue();
249 Value.U = constant.getZExtValue();
252 bytes = llvm::ArrayRef(
reinterpret_cast<const uint8_t *
>(&
Value), 8)
254 buffer->CopyData(bytes.data(), size);
262 const std::map<uint64_t, MemberValLocation> &offset_to_location,
263 std::map<uint64_t, size_t> &offset_to_size,
size_t total_size,
267 size_t cur_offset = 0;
268 bool is_simple_type = offset_to_size.empty();
271 for (
const auto &offset_loc : offset_to_location) {
272 if (cur_offset < offset_loc.first) {
273 stream.PutHex8(llvm::dwarf::DW_OP_piece);
274 stream.PutULEB128(offset_loc.first - cur_offset);
275 cur_offset = offset_loc.first;
278 std::optional<int32_t> offset =
280 : std::optional<int32_t>(loc.reg_offset);
282 stream, (RegisterId)loc.reg_id, register_kind, offset,
285 if (!is_simple_type) {
286 stream.
PutHex8(llvm::dwarf::DW_OP_piece);
287 stream.
PutULEB128(offset_to_size[offset_loc.first]);
288 cur_offset = offset_loc.first + offset_to_size[offset_loc.first];
294 if (total_size > cur_offset) {
295 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 std::pair< size_t, bool > GetIntegralTypeInfo(TypeIndex ti, TpiStream &tpi)
static bool MakeRegisterBasedLocationExpressionInternal(Stream &stream, llvm::codeview::RegisterId reg, RegisterKind ®ister_kind, std::optional< int32_t > relative_offset, lldb::ModuleSP module)
static uint32_t GetRegisterNumber(llvm::Triple::ArchType arch_type, llvm::codeview::RegisterId register_id, RegisterKind ®ister_kind)
static bool IsSimpleTypeSignedInteger(SimpleTypeKind kind)
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.
uint32_t GetDataByteSize() const
Architecture data byte width accessor.
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.
@ eBinary
Get and put data as binary instead of as the default string mode.
size_t size_t PutHex8(uint8_t uvalue)
Append an uint8_t value in the hexadecimal format to the stream.
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 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)
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)
DWARFExpression MakeConstantLocationExpression(llvm::codeview::TypeIndex underlying_ti, llvm::pdb::TpiStream &tpi, const llvm::APSInt &constant, lldb::ModuleSP module)
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