[LLDB][NativePDB] Switch to use DWARFLocationList.
Before, NativePDB uses scoped range as a workaround for value range, that causes problems (e.g. a variable's value can only have one range, but usually a variable's value is located at different address ranges, each at different locations, in optimized build). This patch let NativePDB switch to DWARFLocationList so a variable's value can be described at multiple non-overlapped address ranges and each range maps to a location. Because overlapping ranges exists, here's peference when choosing ranges: 1. Always prefer whole value locations. Suppose a variable size is 8 bytes, one record is that for range [1, 5) first 4 bytes is at ecx, and another record is that for range [2, 8) the 8 bytes value is at rdx. This results: [1, 2) has first 4 bytes at ecx, [2, 8) has the whole value at rdx. 2. Always prefer the locations parsed later. Suppose first record is that for range [1, 5) value is at ecx, second record is that for range [2, 6) value is at eax. This results: [1, 2) -> ecx, [2, 6) -> eax. Differential Revision: https://reviews.llvm.org/D130796
This commit is contained in:
@@ -49,6 +49,11 @@ template <typename B, typename S> struct Range {
|
||||
|
||||
void Slide(BaseType slide) { base += slide; }
|
||||
|
||||
void ShrinkFront(S s) {
|
||||
base += s;
|
||||
size -= std::min(s, size);
|
||||
}
|
||||
|
||||
bool Union(const Range &rhs) {
|
||||
if (DoesAdjoinOrIntersect(rhs)) {
|
||||
auto new_end = std::max<BaseType>(GetRangeEnd(), rhs.GetRangeEnd());
|
||||
@@ -445,6 +450,13 @@ public:
|
||||
|
||||
void Append(const Entry &entry) { m_entries.emplace_back(entry); }
|
||||
|
||||
bool Erase(uint32_t start, uint32_t end) {
|
||||
if (start >= end || end > m_entries.size())
|
||||
return false;
|
||||
m_entries.erase(begin() + start, begin() + end);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Sort() {
|
||||
if (m_entries.size() > 1)
|
||||
std::stable_sort(m_entries.begin(), m_entries.end(),
|
||||
@@ -621,6 +633,17 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t FindEntryIndexThatContainsOrFollows(B addr) const {
|
||||
#ifdef ASSERT_RANGEMAP_ARE_SORTED
|
||||
assert(IsSorted());
|
||||
#endif
|
||||
const AugmentedEntry *entry = static_cast<const AugmentedEntry *>(
|
||||
FindEntryThatContainsOrFollows(addr));
|
||||
if (entry)
|
||||
return std::distance(m_entries.begin(), entry);
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
Entry *Back() { return (m_entries.empty() ? nullptr : &m_entries.back()); }
|
||||
|
||||
const Entry *Back() const {
|
||||
|
||||
@@ -649,3 +649,100 @@ uint32_t lldb_private::npdb::GetLLDBRegisterNumber(
|
||||
return LLDB_INVALID_REGNUM;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
lldb_private::npdb::GetRegisterSize(llvm::codeview::RegisterId register_id) {
|
||||
switch(register_id) {
|
||||
case llvm::codeview::RegisterId::AL:
|
||||
case llvm::codeview::RegisterId::BL:
|
||||
case llvm::codeview::RegisterId::CL:
|
||||
case llvm::codeview::RegisterId::DL:
|
||||
case llvm::codeview::RegisterId::AH:
|
||||
case llvm::codeview::RegisterId::BH:
|
||||
case llvm::codeview::RegisterId::CH:
|
||||
case llvm::codeview::RegisterId::DH:
|
||||
case llvm::codeview::RegisterId::SIL:
|
||||
case llvm::codeview::RegisterId::DIL:
|
||||
case llvm::codeview::RegisterId::BPL:
|
||||
case llvm::codeview::RegisterId::SPL:
|
||||
case llvm::codeview::RegisterId::R8B:
|
||||
case llvm::codeview::RegisterId::R9B:
|
||||
case llvm::codeview::RegisterId::R10B:
|
||||
case llvm::codeview::RegisterId::R11B:
|
||||
case llvm::codeview::RegisterId::R12B:
|
||||
case llvm::codeview::RegisterId::R13B:
|
||||
case llvm::codeview::RegisterId::R14B:
|
||||
case llvm::codeview::RegisterId::R15B:
|
||||
return 1;
|
||||
case llvm::codeview::RegisterId::AX:
|
||||
case llvm::codeview::RegisterId::BX:
|
||||
case llvm::codeview::RegisterId::CX:
|
||||
case llvm::codeview::RegisterId::DX:
|
||||
case llvm::codeview::RegisterId::SP:
|
||||
case llvm::codeview::RegisterId::BP:
|
||||
case llvm::codeview::RegisterId::SI:
|
||||
case llvm::codeview::RegisterId::DI:
|
||||
case llvm::codeview::RegisterId::R8W:
|
||||
case llvm::codeview::RegisterId::R9W:
|
||||
case llvm::codeview::RegisterId::R10W:
|
||||
case llvm::codeview::RegisterId::R11W:
|
||||
case llvm::codeview::RegisterId::R12W:
|
||||
case llvm::codeview::RegisterId::R13W:
|
||||
case llvm::codeview::RegisterId::R14W:
|
||||
case llvm::codeview::RegisterId::R15W:
|
||||
return 2;
|
||||
case llvm::codeview::RegisterId::EAX:
|
||||
case llvm::codeview::RegisterId::EBX:
|
||||
case llvm::codeview::RegisterId::ECX:
|
||||
case llvm::codeview::RegisterId::EDX:
|
||||
case llvm::codeview::RegisterId::ESP:
|
||||
case llvm::codeview::RegisterId::EBP:
|
||||
case llvm::codeview::RegisterId::ESI:
|
||||
case llvm::codeview::RegisterId::EDI:
|
||||
case llvm::codeview::RegisterId::R8D:
|
||||
case llvm::codeview::RegisterId::R9D:
|
||||
case llvm::codeview::RegisterId::R10D:
|
||||
case llvm::codeview::RegisterId::R11D:
|
||||
case llvm::codeview::RegisterId::R12D:
|
||||
case llvm::codeview::RegisterId::R13D:
|
||||
case llvm::codeview::RegisterId::R14D:
|
||||
case llvm::codeview::RegisterId::R15D:
|
||||
return 4;
|
||||
case llvm::codeview::RegisterId::RAX:
|
||||
case llvm::codeview::RegisterId::RBX:
|
||||
case llvm::codeview::RegisterId::RCX:
|
||||
case llvm::codeview::RegisterId::RDX:
|
||||
case llvm::codeview::RegisterId::RSI:
|
||||
case llvm::codeview::RegisterId::RDI:
|
||||
case llvm::codeview::RegisterId::RBP:
|
||||
case llvm::codeview::RegisterId::RSP:
|
||||
case llvm::codeview::RegisterId::R8:
|
||||
case llvm::codeview::RegisterId::R9:
|
||||
case llvm::codeview::RegisterId::R10:
|
||||
case llvm::codeview::RegisterId::R11:
|
||||
case llvm::codeview::RegisterId::R12:
|
||||
case llvm::codeview::RegisterId::R13:
|
||||
case llvm::codeview::RegisterId::R14:
|
||||
case llvm::codeview::RegisterId::R15:
|
||||
return 8;
|
||||
case llvm::codeview::RegisterId::XMM0:
|
||||
case llvm::codeview::RegisterId::XMM1:
|
||||
case llvm::codeview::RegisterId::XMM2:
|
||||
case llvm::codeview::RegisterId::XMM3:
|
||||
case llvm::codeview::RegisterId::XMM4:
|
||||
case llvm::codeview::RegisterId::XMM5:
|
||||
case llvm::codeview::RegisterId::XMM6:
|
||||
case llvm::codeview::RegisterId::XMM7:
|
||||
case llvm::codeview::RegisterId::XMM8:
|
||||
case llvm::codeview::RegisterId::XMM9:
|
||||
case llvm::codeview::RegisterId::XMM10:
|
||||
case llvm::codeview::RegisterId::XMM11:
|
||||
case llvm::codeview::RegisterId::XMM12:
|
||||
case llvm::codeview::RegisterId::XMM13:
|
||||
case llvm::codeview::RegisterId::XMM14:
|
||||
case llvm::codeview::RegisterId::XMM15:
|
||||
return 16;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ namespace npdb {
|
||||
|
||||
uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type,
|
||||
llvm::codeview::RegisterId register_id);
|
||||
uint32_t GetRegisterSize(llvm::codeview::RegisterId register_id);
|
||||
|
||||
} // namespace npdb
|
||||
} // namespace lldb_private
|
||||
|
||||
@@ -128,33 +128,38 @@ static DWARFExpression MakeLocationExpressionInternal(lldb::ModuleSP module,
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool MakeRegisterBasedLocationExpressionInternal(
|
||||
Stream &stream, llvm::codeview::RegisterId reg, RegisterKind register_kind,
|
||||
llvm::Optional<int32_t> relative_offset, lldb::ModuleSP module) {
|
||||
uint32_t reg_num = GetRegisterNumber(module->GetArchitecture().GetMachine(),
|
||||
reg, register_kind);
|
||||
if (reg_num == LLDB_INVALID_REGNUM)
|
||||
return false;
|
||||
|
||||
if (reg_num > 31) {
|
||||
llvm::dwarf::LocationAtom base =
|
||||
relative_offset ? llvm::dwarf::DW_OP_bregx : llvm::dwarf::DW_OP_regx;
|
||||
stream.PutHex8(base);
|
||||
stream.PutULEB128(reg_num);
|
||||
} else {
|
||||
llvm::dwarf::LocationAtom base =
|
||||
relative_offset ? llvm::dwarf::DW_OP_breg0 : llvm::dwarf::DW_OP_reg0;
|
||||
stream.PutHex8(base + reg_num);
|
||||
}
|
||||
|
||||
if (relative_offset)
|
||||
stream.PutSLEB128(*relative_offset);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static DWARFExpression MakeRegisterBasedLocationExpressionInternal(
|
||||
llvm::codeview::RegisterId reg, llvm::Optional<int32_t> relative_offset,
|
||||
lldb::ModuleSP module) {
|
||||
return MakeLocationExpressionInternal(
|
||||
module, [&](Stream &stream, RegisterKind ®ister_kind) -> bool {
|
||||
uint32_t reg_num = GetRegisterNumber(
|
||||
module->GetArchitecture().GetMachine(), reg, register_kind);
|
||||
if (reg_num == LLDB_INVALID_REGNUM)
|
||||
return false;
|
||||
|
||||
if (reg_num > 31) {
|
||||
llvm::dwarf::LocationAtom base = relative_offset
|
||||
? llvm::dwarf::DW_OP_bregx
|
||||
: llvm::dwarf::DW_OP_regx;
|
||||
stream.PutHex8(base);
|
||||
stream.PutULEB128(reg_num);
|
||||
} else {
|
||||
llvm::dwarf::LocationAtom base = relative_offset
|
||||
? llvm::dwarf::DW_OP_breg0
|
||||
: llvm::dwarf::DW_OP_reg0;
|
||||
stream.PutHex8(base + reg_num);
|
||||
}
|
||||
|
||||
if (relative_offset)
|
||||
stream.PutSLEB128(*relative_offset);
|
||||
|
||||
return true;
|
||||
return MakeRegisterBasedLocationExpressionInternal(
|
||||
stream, reg, register_kind, relative_offset, module);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -251,28 +256,43 @@ DWARFExpression lldb_private::npdb::MakeConstantLocationExpression(
|
||||
return result;
|
||||
}
|
||||
|
||||
DWARFExpression lldb_private::npdb::MakeEnregisteredLocationExpressionForClass(
|
||||
std::map<uint64_t, std::pair<RegisterId, uint32_t>> &members_info,
|
||||
DWARFExpression
|
||||
lldb_private::npdb::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) {
|
||||
return MakeLocationExpressionInternal(
|
||||
module, [&](Stream &stream, RegisterKind ®ister_kind) -> bool {
|
||||
for (auto pair : members_info) {
|
||||
std::pair<RegisterId, uint32_t> member_info = pair.second;
|
||||
if (member_info.first != llvm::codeview::RegisterId::NONE) {
|
||||
uint32_t reg_num =
|
||||
GetRegisterNumber(module->GetArchitecture().GetMachine(),
|
||||
member_info.first, register_kind);
|
||||
if (reg_num == LLDB_INVALID_REGNUM)
|
||||
return false;
|
||||
if (reg_num > 31) {
|
||||
stream.PutHex8(llvm::dwarf::DW_OP_regx);
|
||||
stream.PutULEB128(reg_num);
|
||||
} else {
|
||||
stream.PutHex8(llvm::dwarf::DW_OP_reg0 + reg_num);
|
||||
}
|
||||
size_t cur_offset = 0;
|
||||
bool is_simple_type = offset_to_size.empty();
|
||||
// Iterate through offset_to_location because offset_to_size might be
|
||||
// empty if the variable is a simple type.
|
||||
for (const auto &offset_loc : offset_to_location) {
|
||||
if (cur_offset < offset_loc.first) {
|
||||
stream.PutHex8(llvm::dwarf::DW_OP_piece);
|
||||
stream.PutULEB128(offset_loc.first - cur_offset);
|
||||
cur_offset = offset_loc.first;
|
||||
}
|
||||
MemberValLocation loc = offset_loc.second;
|
||||
llvm::Optional<int32_t> offset =
|
||||
loc.is_at_reg ? llvm::None
|
||||
: llvm::Optional<int32_t>(loc.reg_offset);
|
||||
if (!MakeRegisterBasedLocationExpressionInternal(
|
||||
stream, (RegisterId)loc.reg_id, register_kind, offset,
|
||||
module))
|
||||
return false;
|
||||
if (!is_simple_type) {
|
||||
stream.PutHex8(llvm::dwarf::DW_OP_piece);
|
||||
stream.PutULEB128(offset_to_size[offset_loc.first]);
|
||||
cur_offset = offset_loc.first + offset_to_size[offset_loc.first];
|
||||
}
|
||||
}
|
||||
// For simple type, it specifies the byte size of the value described by
|
||||
// the previous dwarf expr. For udt, it's the remaining byte size at end
|
||||
// of a struct.
|
||||
if (total_size > cur_offset) {
|
||||
stream.PutHex8(llvm::dwarf::DW_OP_piece);
|
||||
stream.PutULEB128(member_info.second);
|
||||
stream.PutULEB128(total_size - cur_offset);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -26,6 +26,12 @@ class TpiStream;
|
||||
} // namespace llvm
|
||||
namespace lldb_private {
|
||||
namespace npdb {
|
||||
struct MemberValLocation {
|
||||
uint16_t reg_id;
|
||||
uint16_t reg_offset;
|
||||
bool is_at_reg = true;
|
||||
};
|
||||
|
||||
DWARFExpression
|
||||
MakeEnregisteredLocationExpression(llvm::codeview::RegisterId reg,
|
||||
lldb::ModuleSP module);
|
||||
@@ -41,9 +47,9 @@ DWARFExpression MakeGlobalLocationExpression(uint16_t section, uint32_t offset,
|
||||
DWARFExpression MakeConstantLocationExpression(
|
||||
llvm::codeview::TypeIndex underlying_ti, llvm::pdb::TpiStream &tpi,
|
||||
const llvm::APSInt &constant, lldb::ModuleSP module);
|
||||
DWARFExpression MakeEnregisteredLocationExpressionForClass(
|
||||
std::map<uint64_t, std::pair<llvm::codeview::RegisterId, uint32_t>>
|
||||
&members_info,
|
||||
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);
|
||||
} // namespace npdb
|
||||
} // namespace lldb_private
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
|
||||
|
||||
#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
|
||||
#include "Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h"
|
||||
#include "lldb/Symbol/Block.h"
|
||||
#include "lldb/Utility/LLDBAssert.h"
|
||||
#include "lldb/Utility/LLDBLog.h"
|
||||
@@ -29,6 +30,8 @@ using namespace lldb_private::npdb;
|
||||
using namespace llvm::codeview;
|
||||
using namespace llvm::pdb;
|
||||
|
||||
// The returned range list is guaranteed to be sorted and no overlaps between
|
||||
// adjacent ranges because fields in LocalVariableAddrGap are unsigned integers.
|
||||
static Variable::RangeList
|
||||
MakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range,
|
||||
llvm::ArrayRef<LocalVariableAddrGap> gaps) {
|
||||
@@ -52,21 +55,144 @@ MakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range,
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct FindMembersSize : public TypeVisitorCallbacks {
|
||||
FindMembersSize(
|
||||
std::map<uint64_t, std::pair<RegisterId, uint32_t>> &members_info,
|
||||
TpiStream &tpi)
|
||||
: members_info(members_info), tpi(tpi) {}
|
||||
std::map<uint64_t, std::pair<RegisterId, uint32_t>> &members_info;
|
||||
TpiStream &tpi;
|
||||
llvm::Error visitKnownMember(CVMemberRecord &cvr,
|
||||
DataMemberRecord &member) override {
|
||||
members_info.insert(
|
||||
{member.getFieldOffset(),
|
||||
{llvm::codeview::RegisterId::NONE, GetSizeOfType(member.Type, tpi)}});
|
||||
return llvm::Error::success();
|
||||
struct MemberLocations {
|
||||
std::map<uint64_t, MemberValLocation> offset_to_location;
|
||||
DWARFExpression expr;
|
||||
bool is_dwarf = false;
|
||||
|
||||
MemberLocations() = default;
|
||||
MemberLocations(const DWARFExpression &expr) : expr(expr), is_dwarf(true) {}
|
||||
MemberLocations(uint64_t offset, const MemberValLocation &member_loc) {
|
||||
insert(offset, member_loc);
|
||||
}
|
||||
|
||||
void insert(uint64_t offset, const MemberValLocation &member_loc) {
|
||||
offset_to_location[offset] = member_loc;
|
||||
}
|
||||
|
||||
struct Comparator {
|
||||
public:
|
||||
bool operator()(const MemberLocations &, const MemberLocations &) const {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// A range map with address ranges to a map of pair of offset and locaitons.
|
||||
typedef RangeDataVector<lldb::addr_t, lldb::addr_t, MemberLocations, 0,
|
||||
MemberLocations::Comparator>
|
||||
RangeMap;
|
||||
|
||||
void AddMemberLocationRanges(RangeMap &location_map, uint64_t offset,
|
||||
MemberValLocation member_loc,
|
||||
const Variable::RangeList &ranges) {
|
||||
RangeMap new_location_map;
|
||||
auto add_overlap_region = [&](lldb::addr_t base, lldb::addr_t end,
|
||||
RangeMap::Entry *entry) {
|
||||
RangeMap::Entry overlap_region = {base, end - base, entry->data};
|
||||
overlap_region.data.insert(offset, member_loc);
|
||||
new_location_map.Append(overlap_region);
|
||||
};
|
||||
|
||||
for (const auto &range : ranges) {
|
||||
lldb::addr_t base = range.GetRangeBase();
|
||||
lldb::addr_t end = range.GetRangeEnd();
|
||||
uint32_t base_idx = location_map.FindEntryIndexThatContainsOrFollows(base);
|
||||
while (auto *entry = location_map.GetMutableEntryAtIndex(base_idx)) {
|
||||
if (base >= end || entry->base >= end)
|
||||
break;
|
||||
if (entry->data.is_dwarf)
|
||||
base = entry->GetRangeEnd();
|
||||
else {
|
||||
lldb::addr_t entry_end = entry->GetRangeEnd();
|
||||
if (base > entry->base) {
|
||||
if (end < entry_end)
|
||||
new_location_map.Append({end, entry_end - end, entry->data});
|
||||
add_overlap_region(base, end < entry_end ? end : entry_end, entry);
|
||||
entry->SetRangeEnd(base);
|
||||
} else if (base < entry->base) {
|
||||
new_location_map.Append(
|
||||
{base, entry->base - base, {offset, member_loc}});
|
||||
if (entry_end == end)
|
||||
entry->data.insert(offset, member_loc);
|
||||
else {
|
||||
add_overlap_region(entry->base, end, entry);
|
||||
entry->ShrinkFront(end - entry->base);
|
||||
}
|
||||
} else {
|
||||
if (end < entry_end) {
|
||||
new_location_map.Append({end, entry_end, entry->data});
|
||||
entry->SetRangeEnd(end);
|
||||
}
|
||||
entry->data.insert(offset, member_loc);
|
||||
}
|
||||
base = entry_end;
|
||||
}
|
||||
++base_idx;
|
||||
}
|
||||
if (base >= end)
|
||||
continue;
|
||||
new_location_map.Append({base, end - base, {offset, member_loc}});
|
||||
}
|
||||
for (const auto &entry : new_location_map)
|
||||
location_map.Append(entry);
|
||||
if (!new_location_map.IsEmpty())
|
||||
location_map.Sort();
|
||||
}
|
||||
|
||||
void AddDwarfRange(RangeMap &location_map, const DWARFExpression &expr,
|
||||
const Variable::RangeList &ranges) {
|
||||
if (!expr.IsValid())
|
||||
return;
|
||||
RangeMap new_location_map;
|
||||
for (const auto &range : ranges) {
|
||||
lldb::addr_t base = range.GetRangeBase();
|
||||
lldb::addr_t end = range.GetRangeEnd();
|
||||
uint32_t base_idx = location_map.FindEntryIndexThatContains(base);
|
||||
uint32_t end_idx = location_map.FindEntryIndexThatContains(end - 1);
|
||||
// range is within an entry.
|
||||
if (base_idx == end_idx && base_idx != UINT32_MAX) {
|
||||
auto *entry = location_map.GetMutableEntryAtIndex(base_idx);
|
||||
if (base > entry->base) {
|
||||
new_location_map.Append({entry->base, base - entry->base, entry->data});
|
||||
entry->ShrinkFront(base - entry->base);
|
||||
}
|
||||
if (end == entry->GetRangeEnd())
|
||||
entry->data = expr;
|
||||
else {
|
||||
entry->ShrinkFront(end - base);
|
||||
new_location_map.Append({base, end - base, expr});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
base_idx = location_map.FindEntryIndexThatContainsOrFollows(base);
|
||||
if (auto *entry = location_map.GetMutableEntryAtIndex(base_idx)) {
|
||||
if (entry->Contains(base) && entry->base != base) {
|
||||
entry->SetRangeEnd(base);
|
||||
++base_idx;
|
||||
}
|
||||
}
|
||||
end_idx = location_map.FindEntryIndexThatContainsOrFollows(end - 1);
|
||||
if (auto *entry = location_map.GetMutableEntryAtIndex(end_idx)) {
|
||||
if (entry->Contains(end - 1)) {
|
||||
if (entry->GetRangeEnd() == end)
|
||||
++end_idx;
|
||||
else
|
||||
entry->ShrinkFront(end - entry->base);
|
||||
}
|
||||
}
|
||||
|
||||
if (end_idx == UINT32_MAX)
|
||||
end_idx = location_map.GetSize();
|
||||
// Erase existing ranges covered by new range.
|
||||
location_map.Erase(base_idx, end_idx);
|
||||
new_location_map.Append({base, end - base, expr});
|
||||
}
|
||||
|
||||
for (const auto &entry : new_location_map)
|
||||
location_map.Append(entry);
|
||||
location_map.Sort();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
CVTagRecord CVTagRecord::create(CVType type) {
|
||||
@@ -612,207 +738,176 @@ VariableInfo lldb_private::npdb::GetVariableLocationInfo(
|
||||
if (sym.kind() == S_REGREL32) {
|
||||
RegRelativeSym reg(SymbolRecordKind::RegRelativeSym);
|
||||
cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg));
|
||||
result.location =
|
||||
MakeRegRelLocationExpression(reg.Register, reg.Offset, module);
|
||||
result.ranges.emplace();
|
||||
result.location = DWARFExpressionList(
|
||||
module, MakeRegRelLocationExpression(reg.Register, reg.Offset, module),
|
||||
nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (sym.kind() == S_REGISTER) {
|
||||
RegisterSym reg(SymbolRecordKind::RegisterSym);
|
||||
cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg));
|
||||
result.location = MakeEnregisteredLocationExpression(reg.Register, module);
|
||||
result.ranges.emplace();
|
||||
result.location = DWARFExpressionList(
|
||||
module, MakeEnregisteredLocationExpression(reg.Register, module),
|
||||
nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (sym.kind() == S_LOCAL) {
|
||||
LocalSym local(SymbolRecordKind::LocalSym);
|
||||
cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local));
|
||||
if (llvm::Error error =
|
||||
SymbolDeserializer::deserializeAs<LocalSym>(sym, local)) {
|
||||
llvm::consumeError(std::move(error));
|
||||
return result;
|
||||
}
|
||||
|
||||
PdbCompilandSymId loc_specifier_id(var_id.modi,
|
||||
var_id.offset + sym.RecordData.size());
|
||||
CVSymbol loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id);
|
||||
switch(loc_specifier_cvs.kind()) {
|
||||
case S_DEFRANGE_FRAMEPOINTER_REL: {
|
||||
DefRangeFramePointerRelSym loc(
|
||||
SymbolRecordKind::DefRangeFramePointerRelSym);
|
||||
cantFail(SymbolDeserializer::deserializeAs<DefRangeFramePointerRelSym>(
|
||||
loc_specifier_cvs, loc));
|
||||
CVSymbol loc_specifier_cvs;
|
||||
// Only used for S_DEFRANGE_FRAMEPOINTER_REL.
|
||||
RegisterId base_reg = RegisterId::NONE;
|
||||
size_t type_size = GetSizeOfType(result.type, index.tpi());
|
||||
// A map from offset of a field in parent to size of the field.
|
||||
std::map<uint64_t, size_t> offset_to_size;
|
||||
|
||||
Variable::RangeList ranges = MakeRangeList(index, loc.Range, loc.Gaps);
|
||||
// When overlaps happens, always prefer the one that doesn't split the value
|
||||
// into multiple locations and the location parsed first is perfered.
|
||||
RangeMap location_map;
|
||||
|
||||
PdbCompilandSymId func_scope_id =
|
||||
PdbSymUid(func_block.GetID()).asCompilandSym();
|
||||
CVSymbol func_block_cvs = index.ReadSymbolRecord(func_scope_id);
|
||||
lldbassert(func_block_cvs.kind() == S_GPROC32 ||
|
||||
func_block_cvs.kind() == S_LPROC32);
|
||||
|
||||
PdbCompilandSymId frame_proc_id(
|
||||
func_scope_id.modi, func_scope_id.offset + func_block_cvs.length());
|
||||
|
||||
RegisterId base_reg =
|
||||
GetBaseFrameRegister(index, frame_proc_id, result.is_param);
|
||||
if (base_reg == RegisterId::NONE)
|
||||
// Iterate through all location records after S_LOCAL. They describe the
|
||||
// value of this variable at different locations.
|
||||
bool finished = false;
|
||||
while (!finished) {
|
||||
loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id);
|
||||
switch (loc_specifier_cvs.kind()) {
|
||||
case S_DEFRANGE_FRAMEPOINTER_REL: {
|
||||
DefRangeFramePointerRelSym loc(
|
||||
SymbolRecordKind::DefRangeFramePointerRelSym);
|
||||
if (llvm::Error error =
|
||||
SymbolDeserializer::deserializeAs<DefRangeFramePointerRelSym>(
|
||||
loc_specifier_cvs, loc)) {
|
||||
llvm::consumeError(std::move(error));
|
||||
return result;
|
||||
}
|
||||
Variable::RangeList raw_ranges =
|
||||
MakeRangeList(index, loc.Range, loc.Gaps);
|
||||
if (base_reg == RegisterId::NONE) {
|
||||
PdbCompilandSymId func_scope_id =
|
||||
PdbSymUid(func_block.GetID()).asCompilandSym();
|
||||
CVSymbol func_block_cvs = index.ReadSymbolRecord(func_scope_id);
|
||||
lldbassert(func_block_cvs.kind() == S_GPROC32 ||
|
||||
func_block_cvs.kind() == S_LPROC32);
|
||||
PdbCompilandSymId frame_proc_id(func_scope_id.modi,
|
||||
func_scope_id.offset +
|
||||
func_block_cvs.length());
|
||||
base_reg =
|
||||
GetBaseFrameRegister(index, frame_proc_id, result.is_param);
|
||||
if (base_reg == RegisterId::NONE)
|
||||
break;
|
||||
}
|
||||
DWARFExpression expr;
|
||||
if (base_reg == RegisterId::VFRAME) {
|
||||
llvm::StringRef program;
|
||||
if (GetFrameDataProgram(index, raw_ranges, program))
|
||||
expr = MakeVFrameRelLocationExpression(program, loc.Hdr.Offset,
|
||||
module);
|
||||
else {
|
||||
// invalid variable
|
||||
}
|
||||
} else
|
||||
expr = MakeRegRelLocationExpression(base_reg, loc.Hdr.Offset, module);
|
||||
AddDwarfRange(location_map, expr, raw_ranges);
|
||||
break;
|
||||
if (base_reg == RegisterId::VFRAME) {
|
||||
llvm::StringRef program;
|
||||
if (GetFrameDataProgram(index, ranges, program)) {
|
||||
result.location =
|
||||
MakeVFrameRelLocationExpression(program, loc.Hdr.Offset, module);
|
||||
result.ranges = std::move(ranges);
|
||||
} else {
|
||||
// invalid variable
|
||||
}
|
||||
} else {
|
||||
result.location =
|
||||
MakeRegRelLocationExpression(base_reg, loc.Hdr.Offset, module);
|
||||
result.ranges = std::move(ranges);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case S_DEFRANGE_REGISTER_REL: {
|
||||
DefRangeRegisterRelSym loc(SymbolRecordKind::DefRangeRegisterRelSym);
|
||||
cantFail(SymbolDeserializer::deserializeAs<DefRangeRegisterRelSym>(
|
||||
loc_specifier_cvs, loc));
|
||||
|
||||
Variable::RangeList ranges = MakeRangeList(index, loc.Range, loc.Gaps);
|
||||
|
||||
RegisterId base_reg = (RegisterId)(uint16_t)loc.Hdr.Register;
|
||||
|
||||
if (base_reg == RegisterId::VFRAME) {
|
||||
llvm::StringRef program;
|
||||
if (GetFrameDataProgram(index, ranges, program)) {
|
||||
result.location = MakeVFrameRelLocationExpression(
|
||||
program, loc.Hdr.BasePointerOffset, module);
|
||||
result.ranges = std::move(ranges);
|
||||
} else {
|
||||
// invalid variable
|
||||
case S_DEFRANGE_REGISTER: {
|
||||
DefRangeRegisterSym loc(SymbolRecordKind::DefRangeRegisterSym);
|
||||
if (llvm::Error error =
|
||||
SymbolDeserializer::deserializeAs<DefRangeRegisterSym>(
|
||||
loc_specifier_cvs, loc)) {
|
||||
llvm::consumeError(std::move(error));
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
result.location = MakeRegRelLocationExpression(
|
||||
base_reg, loc.Hdr.BasePointerOffset, module);
|
||||
result.ranges = std::move(ranges);
|
||||
RegisterId reg_id = (RegisterId)(uint16_t)loc.Hdr.Register;
|
||||
Variable::RangeList raw_ranges =
|
||||
MakeRangeList(index, loc.Range, loc.Gaps);
|
||||
DWARFExpression expr =
|
||||
MakeEnregisteredLocationExpression(reg_id, module);
|
||||
AddDwarfRange(location_map, expr, raw_ranges);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case S_DEFRANGE_REGISTER: {
|
||||
DefRangeRegisterSym loc(SymbolRecordKind::DefRangeRegisterSym);
|
||||
cantFail(SymbolDeserializer::deserializeAs<DefRangeRegisterSym>(
|
||||
loc_specifier_cvs, loc));
|
||||
|
||||
RegisterId base_reg = (RegisterId)(uint16_t)loc.Hdr.Register;
|
||||
result.ranges = MakeRangeList(index, loc.Range, loc.Gaps);
|
||||
result.location = MakeEnregisteredLocationExpression(base_reg, module);
|
||||
break;
|
||||
}
|
||||
case S_DEFRANGE_SUBFIELD_REGISTER: {
|
||||
// A map from offset in parent to pair of register id and size. If the
|
||||
// variable is a simple type, then we don't know the number of subfields.
|
||||
// Otherwise, the size of the map should be greater than or equal to the
|
||||
// number of sub field record.
|
||||
std::map<uint64_t, std::pair<RegisterId, uint32_t>> members_info;
|
||||
bool is_simple_type = result.type.isSimple();
|
||||
if (!is_simple_type) {
|
||||
CVType class_cvt = index.tpi().getType(result.type);
|
||||
TypeIndex class_id = result.type;
|
||||
if (class_cvt.kind() == LF_MODIFIER)
|
||||
class_id = LookThroughModifierRecord(class_cvt);
|
||||
if (IsForwardRefUdt(class_id, index.tpi())) {
|
||||
auto expected_full_ti =
|
||||
index.tpi().findFullDeclForForwardRef(class_id);
|
||||
if (!expected_full_ti) {
|
||||
llvm::consumeError(expected_full_ti.takeError());
|
||||
break;
|
||||
}
|
||||
class_cvt = index.tpi().getType(*expected_full_ti);
|
||||
case S_DEFRANGE_REGISTER_REL: {
|
||||
DefRangeRegisterRelSym loc(SymbolRecordKind::DefRangeRegisterRelSym);
|
||||
if (llvm::Error error =
|
||||
SymbolDeserializer::deserializeAs<DefRangeRegisterRelSym>(
|
||||
loc_specifier_cvs, loc)) {
|
||||
llvm::consumeError(std::move(error));
|
||||
return result;
|
||||
}
|
||||
if (IsTagRecord(class_cvt)) {
|
||||
TagRecord tag_record = CVTagRecord::create(class_cvt).asTag();
|
||||
CVType field_list_cvt = index.tpi().getType(tag_record.FieldList);
|
||||
FieldListRecord field_list;
|
||||
if (llvm::Error error =
|
||||
TypeDeserializer::deserializeAs<FieldListRecord>(
|
||||
field_list_cvt, field_list))
|
||||
llvm::consumeError(std::move(error));
|
||||
FindMembersSize find_members_size(members_info, index.tpi());
|
||||
if (llvm::Error err = visitMemberRecordStream(field_list.Data,
|
||||
find_members_size)) {
|
||||
llvm::consumeError(std::move(err));
|
||||
break;
|
||||
Variable::RangeList raw_ranges =
|
||||
MakeRangeList(index, loc.Range, loc.Gaps);
|
||||
RegisterId reg_id = (RegisterId)(uint16_t)loc.Hdr.Register;
|
||||
DWARFExpression expr;
|
||||
if (reg_id == RegisterId::VFRAME) {
|
||||
llvm::StringRef program;
|
||||
if (GetFrameDataProgram(index, raw_ranges, program))
|
||||
expr = MakeVFrameRelLocationExpression(
|
||||
program, loc.Hdr.BasePointerOffset, module);
|
||||
else {
|
||||
// invalid variable
|
||||
}
|
||||
} else {
|
||||
// TODO: Handle poiner type.
|
||||
break;
|
||||
expr = MakeRegRelLocationExpression(reg_id, loc.Hdr.BasePointerOffset,
|
||||
module);
|
||||
}
|
||||
// FIXME: If it's UDT, we need to know the size of the value in byte.
|
||||
if (!loc.hasSpilledUDTMember())
|
||||
AddDwarfRange(location_map, expr, raw_ranges);
|
||||
break;
|
||||
}
|
||||
|
||||
size_t member_idx = 0;
|
||||
// Assuming S_DEFRANGE_SUBFIELD_REGISTER is followed only by
|
||||
// S_DEFRANGE_SUBFIELD_REGISTER, need to verify.
|
||||
while (loc_specifier_cvs.kind() == S_DEFRANGE_SUBFIELD_REGISTER) {
|
||||
if (!is_simple_type && member_idx >= members_info.size())
|
||||
break;
|
||||
|
||||
case S_DEFRANGE_SUBFIELD_REGISTER: {
|
||||
DefRangeSubfieldRegisterSym loc(
|
||||
SymbolRecordKind::DefRangeSubfieldRegisterSym);
|
||||
cantFail(SymbolDeserializer::deserializeAs<DefRangeSubfieldRegisterSym>(
|
||||
loc_specifier_cvs, loc));
|
||||
|
||||
if (result.ranges) {
|
||||
result.ranges = Variable::RangeList::GetOverlaps(
|
||||
*result.ranges, MakeRangeList(index, loc.Range, loc.Gaps));
|
||||
} else {
|
||||
result.ranges = MakeRangeList(index, loc.Range, loc.Gaps);
|
||||
result.ranges->Sort();
|
||||
if (llvm::Error error =
|
||||
SymbolDeserializer::deserializeAs<DefRangeSubfieldRegisterSym>(
|
||||
loc_specifier_cvs, loc)) {
|
||||
llvm::consumeError(std::move(error));
|
||||
return result;
|
||||
}
|
||||
|
||||
if (is_simple_type) {
|
||||
if (members_info.count(loc.Hdr.OffsetInParent)) {
|
||||
// Malformed record.
|
||||
result.ranges->Clear();
|
||||
return result;
|
||||
}
|
||||
members_info[loc.Hdr.OffsetInParent] = {
|
||||
(RegisterId)(uint16_t)loc.Hdr.Register, 0};
|
||||
} else {
|
||||
if (!members_info.count(loc.Hdr.OffsetInParent)) {
|
||||
// Malformed record.
|
||||
result.ranges->Clear();
|
||||
return result;
|
||||
}
|
||||
members_info[loc.Hdr.OffsetInParent].first =
|
||||
(RegisterId)(uint16_t)loc.Hdr.Register;
|
||||
}
|
||||
// Go to next S_DEFRANGE_SUBFIELD_REGISTER.
|
||||
loc_specifier_id = PdbCompilandSymId(
|
||||
loc_specifier_id.modi,
|
||||
loc_specifier_id.offset + loc_specifier_cvs.RecordData.size());
|
||||
loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id);
|
||||
Variable::RangeList ranges = MakeRangeList(index, loc.Range, loc.Gaps);
|
||||
uint32_t reg_size =
|
||||
GetRegisterSize((RegisterId)(uint16_t)loc.Hdr.Register);
|
||||
if (reg_size == 0)
|
||||
break;
|
||||
offset_to_size[loc.Hdr.OffsetInParent] = reg_size;
|
||||
AddMemberLocationRanges(location_map, loc.Hdr.OffsetInParent,
|
||||
{loc.Hdr.Register, 0, true}, ranges);
|
||||
break;
|
||||
}
|
||||
// Fix size for simple type.
|
||||
if (is_simple_type) {
|
||||
auto cur = members_info.begin();
|
||||
auto end = members_info.end();
|
||||
auto next = cur;
|
||||
++next;
|
||||
uint32_t size = 0;
|
||||
while (next != end) {
|
||||
cur->second.second = next->first - cur->first;
|
||||
size += cur->second.second;
|
||||
cur = next++;
|
||||
}
|
||||
cur->second.second =
|
||||
GetTypeSizeForSimpleKind(result.type.getSimpleKind()) - size;
|
||||
}
|
||||
result.location =
|
||||
MakeEnregisteredLocationExpressionForClass(members_info, module);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// FIXME: Handle other kinds. LLVM only generates the 4 types of records
|
||||
// above.
|
||||
break;
|
||||
// above. MSVC generates other location types.
|
||||
case S_DEFRANGE:
|
||||
case S_DEFRANGE_SUBFIELD:
|
||||
case S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:
|
||||
break;
|
||||
default:
|
||||
finished = true;
|
||||
break;
|
||||
}
|
||||
loc_specifier_id = PdbCompilandSymId(
|
||||
loc_specifier_id.modi,
|
||||
loc_specifier_id.offset + loc_specifier_cvs.RecordData.size());
|
||||
}
|
||||
result.location = DWARFExpressionList();
|
||||
for (const auto &entry : location_map) {
|
||||
DWARFExpression dwarf_expr =
|
||||
entry.data.is_dwarf ? entry.data.expr
|
||||
: MakeEnregisteredLocationExpressionForComposite(
|
||||
entry.data.offset_to_location,
|
||||
offset_to_size, type_size, module);
|
||||
|
||||
result.location->AddExpression(entry.GetRangeBase(), entry.GetRangeEnd(),
|
||||
dwarf_expr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -103,8 +103,7 @@ struct SegmentOffsetLength {
|
||||
struct VariableInfo {
|
||||
llvm::StringRef name;
|
||||
llvm::codeview::TypeIndex type;
|
||||
llvm::Optional<DWARFExpression> location;
|
||||
llvm::Optional<Variable::RangeList> ranges;
|
||||
llvm::Optional<DWARFExpressionList> location;
|
||||
bool is_param;
|
||||
};
|
||||
|
||||
|
||||
@@ -1712,9 +1712,13 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,
|
||||
func_block->GetStartAddress(addr);
|
||||
VariableInfo var_info =
|
||||
GetVariableLocationInfo(*m_index, var_id, *func_block, module);
|
||||
if (!var_info.location || !var_info.ranges)
|
||||
if (!var_info.location || var_info.location->GetSize() == 0)
|
||||
return nullptr;
|
||||
|
||||
Function *func = func_block->CalculateSymbolContextFunction();
|
||||
if (!func)
|
||||
return VariableSP();
|
||||
var_info.location->SetFuncFileAddress(
|
||||
func->GetAddressRange().GetBaseAddress().GetFileAddress());
|
||||
CompilandIndexItem *cii = m_index->compilands().GetCompiland(var_id.modi);
|
||||
CompUnitSP comp_unit_sp = GetOrCreateCompileUnit(*cii);
|
||||
TypeSP type_sp = GetOrCreateType(var_info.type);
|
||||
@@ -1732,11 +1736,10 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,
|
||||
bool artificial = false;
|
||||
bool location_is_constant_data = false;
|
||||
bool static_member = false;
|
||||
DWARFExpressionList locaiton_list = DWARFExpressionList(
|
||||
module, *var_info.location, nullptr);
|
||||
Variable::RangeList scope_ranges;
|
||||
VariableSP var_sp = std::make_shared<Variable>(
|
||||
toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope,
|
||||
&block, *var_info.ranges, &decl, locaiton_list, external, artificial,
|
||||
&block, scope_ranges, &decl, *var_info.location, external, artificial,
|
||||
location_is_constant_data, static_member);
|
||||
if (!is_param)
|
||||
m_ast->GetOrCreateVariableDecl(scope_id, var_id);
|
||||
|
||||
@@ -8,4 +8,28 @@ image lookup -a 0x140001019 -v
|
||||
image lookup -a 0x14000101e -v
|
||||
image lookup -a 0x14000102c -v
|
||||
|
||||
image lookup -a 0x140001031 -v
|
||||
image lookup -a 0x140001032 -v
|
||||
image lookup -a 0x140001033 -v
|
||||
image lookup -a 0x140001034 -v
|
||||
image lookup -a 0x140001035 -v
|
||||
image lookup -a 0x140001036 -v
|
||||
image lookup -a 0x140001037 -v
|
||||
image lookup -a 0x14000103b -v
|
||||
image lookup -a 0x14000103d -v
|
||||
image lookup -a 0x14000103f -v
|
||||
image lookup -a 0x140001041 -v
|
||||
image lookup -a 0x140001043 -v
|
||||
image lookup -a 0x140001045 -v
|
||||
image lookup -a 0x140001046 -v
|
||||
image lookup -a 0x140001047 -v
|
||||
image lookup -a 0x140001048 -v
|
||||
image lookup -a 0x140001049 -v
|
||||
image lookup -a 0x14000104a -v
|
||||
image lookup -a 0x14000104b -v
|
||||
image lookup -a 0x14000104c -v
|
||||
image lookup -a 0x14000104e -v
|
||||
image lookup -a 0x14000104f -v
|
||||
image lookup -a 0x140001050 -v
|
||||
image lookup -a 0x140001051 -v
|
||||
exit
|
||||
|
||||
@@ -52,13 +52,17 @@
|
||||
#CHECK: (lldb) b a.cpp:4
|
||||
#CHECK: Breakpoint 13: where = {{.*}}`main + 61 at a.cpp:4, address = 0x000000014000103d
|
||||
|
||||
# FIXME: The following variable location have wrong register numbers due to
|
||||
# https://github.com/llvm/llvm-project/issues/53575. Fix them after resolving
|
||||
# the issue.
|
||||
|
||||
# CEHCK-LABEL: (lldb) image lookup -a 0x140001003 -v
|
||||
# CHECK: Summary: {{.*}}`main + 3 at a.cpp:2
|
||||
# CHECK: Function: id = {{.*}}, name = "main", range = [0x0000000140001000-0x0000000140001046)
|
||||
# CHECK: Blocks: id = {{.*}}, range = [0x140001000-0x140001046)
|
||||
# CHECK: LineEntry: [0x0000000140001000-0x0000000140001004): /tmp/a.cpp:2
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = [0x0000000140001000-0x000000014000102d)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = [0x0000000140001000-0x0000000140001045)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = <block>, location = [0x0000000140001000, 0x000000014000102d) -> DW_OP_reg26 XMM9
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001045) -> DW_OP_reg3 RBX
|
||||
|
||||
# CEHCK-LABEL: (lldb) image lookup -a 0x140001004 -v
|
||||
# CHECK: Summary: {{.*}}`main + 4 [inlined] Namespace1::foo at a.h:5
|
||||
@@ -67,10 +71,10 @@
|
||||
# CHECK: Blocks: id = {{.*}}, range = [0x140001000-0x140001046)
|
||||
# CHECK-NEXT: id = {{.*}}, ranges = [0x140001004-0x140001039)[0x14000103f-0x140001046), name = "Namespace1::foo", decl = a.h:4
|
||||
# CHECK: LineEntry: [0x0000000140001004-0x000000014000100c): /tmp/a.h:5
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = [0x0000000140001004-0x0000000140001039)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = [0x0000000140001000-0x000000014000102d)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = [0x0000000140001000-0x0000000140001045)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = [0x0000000140001004-0x0000000140001046)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001039) -> DW_OP_breg7 RSP+44
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = <block>, location = [0x0000000140001000, 0x000000014000102d) -> DW_OP_reg26 XMM9
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001045) -> DW_OP_reg3 RBX
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001046) -> DW_OP_breg7 RSP+48
|
||||
|
||||
# CEHCK-LABEL: (lldb) image lookup -a 0x140001010 -v
|
||||
# CHECK: Summary: {{.*}}`main + 16 [inlined] Namespace1::foo + 12 at a.h:7
|
||||
@@ -79,10 +83,10 @@
|
||||
# CHECK: Blocks: id = {{.*}}, range = [0x140001000-0x140001046)
|
||||
# CHECK-NEXT: id = {{.*}}, ranges = [0x140001004-0x140001039)[0x14000103f-0x140001046), name = "Namespace1::foo", decl = a.h:4
|
||||
# CHECK: LineEntry: [0x0000000140001010-0x0000000140001018): /tmp/a.h:7
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = [0x0000000140001004-0x0000000140001039)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = [0x0000000140001000-0x000000014000102d)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = [0x0000000140001000-0x0000000140001045)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = [0x0000000140001004-0x0000000140001046)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001039) -> DW_OP_breg7 RSP+44
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = <block>, location = [0x0000000140001000, 0x000000014000102d) -> DW_OP_reg26 XMM9
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001045) -> DW_OP_reg3 RBX
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001046) -> DW_OP_breg7 RSP+48
|
||||
|
||||
# CEHCK-LABEL: (lldb) image lookup -a 0x14000101c -v
|
||||
# CHECK: Summary: {{.*}}`main + 28 [inlined] Class1::bar at b.h:5
|
||||
@@ -93,12 +97,12 @@
|
||||
# CHECK-NEXT: id = {{.*}}, ranges = [0x140001004-0x140001039)[0x14000103f-0x140001046), name = "Namespace1::foo", decl = a.h:4
|
||||
# CHECK-NEXT: id = {{.*}}, range = [0x14000101c-0x140001039), name = "Class1::bar", decl = b.h:4
|
||||
# CHECK: LineEntry: [0x000000014000101c-0x0000000140001022): /tmp/b.h:5
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "x", type = "int", valid ranges = [0x000000014000101c-0x000000014000101e)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "bar_local", type = "int", valid ranges = [0x000000014000101c-0x0000000140001039)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = [0x0000000140001004-0x0000000140001039)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = [0x0000000140001000-0x000000014000102d)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = [0x0000000140001000-0x0000000140001045)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = [0x0000000140001004-0x0000000140001046)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "x", type = "int", valid ranges = <block>, location = [0x000000014000101c, 0x000000014000101e) -> DW_OP_reg24 XMM7
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "bar_local", type = "int", valid ranges = <block>, location = [0x000000014000101c, 0x0000000140001039) -> DW_OP_breg7 RSP+52
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001039) -> DW_OP_breg7 RSP+44
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = <block>, location = [0x0000000140001000, 0x000000014000102d) -> DW_OP_reg26 XMM9
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001045) -> DW_OP_reg3 RBX
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001046) -> DW_OP_breg7 RSP+48
|
||||
|
||||
# CEHCK-LABEL: (lldb) image lookup -a 0x14000102a -v
|
||||
# CHECK: Summary: {{.*}}`main + 42 [inlined] Namespace2::Class2::func at c.h:5
|
||||
@@ -111,21 +115,21 @@
|
||||
# CHECK-NEXT: id = {{.*}}, range = [0x14000101c-0x140001039), name = "Class1::bar", decl = b.h:4
|
||||
# CHECK-NEXT: id = {{.*}}, range = [0x14000102a-0x140001039), name = "Namespace2::Class2::func", decl = c.h:4
|
||||
# CHECK: LineEntry: [0x000000014000102a-0x0000000140001031): /tmp/c.h:5
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "x", type = "int", valid ranges = [0x000000014000102a-0x0000000140001039)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "func_local", type = "int", valid ranges = [0x000000014000102a-0x0000000140001039)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "bar_local", type = "int", valid ranges = [0x000000014000101c-0x0000000140001039)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = [0x0000000140001004-0x0000000140001039)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = [0x0000000140001000-0x000000014000102d)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = [0x0000000140001000-0x0000000140001045)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = [0x0000000140001004-0x0000000140001046)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "x", type = "int", valid ranges = <block>, location = [0x000000014000102a, 0x0000000140001039) -> DW_OP_reg24 XMM7
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "func_local", type = "int", valid ranges = <block>, location = [0x000000014000102a, 0x0000000140001039) -> DW_OP_breg7 RSP+48
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "bar_local", type = "int", valid ranges = <block>, location = [0x000000014000101c, 0x0000000140001039) -> DW_OP_breg7 RSP+52
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001039) -> DW_OP_breg7 RSP+44
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = <block>, location = [0x0000000140001000, 0x000000014000102d) -> DW_OP_reg26 XMM9
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001045) -> DW_OP_reg3 RBX
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001046) -> DW_OP_breg7 RSP+48
|
||||
|
||||
# CEHCK-LABEL: (lldb) image lookup -a 0x140001039 -v
|
||||
# CHECK: Summary: {{.*}}`main + 57 at a.cpp:3
|
||||
# CHECK: Function: id = {{.*}}, name = "main", range = [0x0000000140001000-0x0000000140001046)
|
||||
# CHECK: Blocks: id = {{.*}}, range = [0x140001000-0x140001046)
|
||||
# CHECK: LineEntry: [0x0000000140001039-0x000000014000103d): /tmp/a.cpp:3
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = [0x0000000140001000-0x0000000140001045)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = [0x0000000140001004-0x0000000140001046)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001045) -> DW_OP_reg3 RBX
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001046) -> DW_OP_breg7 RSP+48
|
||||
|
||||
# CEHCK-LABEL: (lldb) image lookup -a 0x140001044 -v
|
||||
# CHECK: Summary: {{.*}}`main + 68 [inlined] Namespace1::foo + 5 at a.h:8
|
||||
@@ -134,10 +138,10 @@
|
||||
# CHECK: Blocks: id = {{.*}}, range = [0x140001000-0x140001046)
|
||||
# CHECK-NEXT: id = {{.*}}, ranges = [0x140001004-0x140001039)[0x14000103f-0x140001046), name = "Namespace1::foo", decl = a.h:4
|
||||
# CHECK: LineEntry: [0x0000000140001044-0x0000000140001046): /tmp/a.h:8
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = [0x0000000140001044-0x0000000140001046)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = [0x0000000140001044-0x0000000140001045)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = [0x0000000140001000-0x0000000140001045)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = [0x0000000140001004-0x0000000140001046)
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = <block>, location = [0x0000000140001044, 0x0000000140001046) -> DW_OP_breg7 RSP+44
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = <block>, location = [0x0000000140001044, 0x0000000140001045) -> DW_OP_reg26 XMM9
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001045) -> DW_OP_reg3 RBX
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001046) -> DW_OP_breg7 RSP+48
|
||||
|
||||
# CHECK-LABEL: (lldb) target modules dump ast
|
||||
# CHECK-NEXT: Dumping clang ast for 1 modules.
|
||||
|
||||
@@ -34,39 +34,38 @@
|
||||
|
||||
# CHECK: (lldb) image lookup -a 0x140001000 -v
|
||||
# CHECK: LineEntry: [0x0000000140001000-0x0000000140001003): C:\src\test\a.cpp:10
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "p1", type = "int", valid ranges = [0x0000000140001000-0x0000000140001003), location = DW_OP_reg26 XMM9
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "p2", type = "char", valid ranges = [0x0000000140001000-0x0000000140001006), location = DW_OP_regx 0x3f
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "p1", type = "int", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001003) -> DW_OP_reg26 XMM9
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "p2", type = "char", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001006) -> DW_OP_regx 0x3f
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x140001003 -v
|
||||
# CHECK: LineEntry: [0x0000000140001003-0x0000000140001006): C:\src\test\a.cpp:11
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "p2", type = "char", valid ranges = [0x0000000140001000-0x0000000140001006), location = DW_OP_regx 0x3f
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "p2", type = "char", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001006) -> DW_OP_regx 0x3f
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "s", type = "S", valid ranges = <block>, location = [0x0000000140001003, 0x0000000140001006) -> DW_OP_piece 0x4, DW_OP_regx 0x3f, DW_OP_piece 0x1, DW_OP_piece 0x3
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x140001006 -v
|
||||
# CHECK: LineEntry: [0x0000000140001006-0x0000000140001011): C:\src\test\a.cpp:12
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "s", type = "S", valid ranges = [0x0000000140001006-0x0000000140001011), location = DW_OP_reg26 XMM9, DW_OP_piece 0x4, DW_OP_regx 0x3f, DW_OP_piece 0x1
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "s", type = "S", valid ranges = <block>, location = [0x0000000140001006, 0x0000000140001011) -> DW_OP_reg26 XMM9, DW_OP_piece 0x4, DW_OP_regx 0x3f, DW_OP_piece 0x1, DW_OP_piece 0x3
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x140001011 -v
|
||||
# CHECK: LineEntry: [0x0000000140001011-0x0000000140001015): C:\src\test\a.cpp:15
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = [0x0000000140001011-0x0000000140001017), location = DW_OP_reg26 XMM9
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = [0x0000000140001011-0x0000000140001019), location = DW_OP_reg3 RBX
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = <block>, location = [0x0000000140001011, 0x0000000140001017) -> DW_OP_reg26 XMM9
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = <block>, location = [0x0000000140001011, 0x0000000140001019) -> DW_OP_reg3 RBX
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x140001017 -v
|
||||
# CHECK: LineEntry: [0x0000000140001017-0x000000014000101e): C:\src\test\a.cpp:17
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = [0x0000000140001011-0x0000000140001019), location = DW_OP_reg3 RBX
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "local", type = "int", valid ranges = [0x0000000140001017-0x000000014000101e), location = DW_OP_reg26 XMM9
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = <block>, location = [0x0000000140001011, 0x0000000140001019) -> DW_OP_reg3 RBX
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "local", type = "int", valid ranges = <block>, location = [0x0000000140001017, 0x000000014000101e) -> DW_OP_reg26 XMM9
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x140001019 -v
|
||||
# CHECK: LineEntry: [0x0000000140001017-0x000000014000101e): C:\src\test\a.cpp:17
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "local", type = "int", valid ranges = [0x0000000140001017-0x000000014000101e), location = DW_OP_reg26 XMM9
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "local", type = "int", valid ranges = <block>, location = [0x0000000140001017, 0x000000014000101e) -> DW_OP_reg26 XMM9
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x14000101e -v
|
||||
# CHECK: LineEntry: [0x000000014000101e-0x0000000140001031): C:\src\test\a.cpp:18
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "s", type = "S", valid ranges = [0x000000014000101e-0x000000014000102c), location = DW_OP_reg24 XMM7, DW_OP_piece 0x4, DW_OP_piece 0x1
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "s", type = "S", valid ranges = <block>, location = [0x000000014000101e, 0x000000014000102c) -> DW_OP_reg24 XMM7, DW_OP_piece 0x4, DW_OP_piece 0x4
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x14000102c -v
|
||||
# CHECK: LineEntry: [0x000000014000101e-0x0000000140001031): C:\src\test\a.cpp:18
|
||||
# CHECK-EMPTY:
|
||||
|
||||
|
||||
.text
|
||||
.def @feat.00;
|
||||
@@ -153,6 +152,75 @@ main: # @main
|
||||
.Ltmp7:
|
||||
add rsp, 40
|
||||
ret
|
||||
# Manually created for testing purpose.
|
||||
.L31:
|
||||
.cv_loc 1 1 1000 0 # a.cpp:1000:0
|
||||
ret
|
||||
.L32:
|
||||
ret
|
||||
.L33:
|
||||
ret
|
||||
.L34:
|
||||
.cv_loc 1 1 1001 0 # a.cpp:1001:0
|
||||
ret
|
||||
.L35:
|
||||
ret
|
||||
.L36:
|
||||
ret
|
||||
.L37:
|
||||
ret
|
||||
.L38:
|
||||
ret
|
||||
.L39:
|
||||
ret
|
||||
.L3a:
|
||||
ret
|
||||
.L3b:
|
||||
.cv_loc 1 1 1002 0 # a.cpp:1002:0
|
||||
ret
|
||||
.L3c:
|
||||
ret
|
||||
.L3d:
|
||||
ret
|
||||
.L3e:
|
||||
ret
|
||||
.L3f:
|
||||
ret
|
||||
.L40:
|
||||
ret
|
||||
.L41:
|
||||
ret
|
||||
.L42:
|
||||
ret
|
||||
.L43:
|
||||
ret
|
||||
.L44:
|
||||
ret
|
||||
.L45:
|
||||
.cv_loc 1 1 1003 0 # a.cpp:1003:0
|
||||
ret
|
||||
.L46:
|
||||
ret
|
||||
.L47:
|
||||
ret
|
||||
.L48:
|
||||
ret
|
||||
.L49:
|
||||
ret
|
||||
.L4a:
|
||||
ret
|
||||
.L4b:
|
||||
ret
|
||||
.L4c:
|
||||
ret
|
||||
.L4d:
|
||||
ret
|
||||
.L4e:
|
||||
.cv_loc 1 1 1004 0 # a.cpp:1004:0
|
||||
ret
|
||||
.L4f:
|
||||
ret
|
||||
.L50:
|
||||
.Ltmp8:
|
||||
.Lfunc_end1:
|
||||
.seh_endproc
|
||||
@@ -322,8 +390,172 @@ main: # @main
|
||||
.p2align 2
|
||||
.Ltmp38:
|
||||
.cv_def_range .Ltmp6 .Ltmp7, subfield_reg, 17, 0
|
||||
.short 2 # Record length
|
||||
.short .Ltmp101-.Ltmp100
|
||||
# Manually created debug info for testing purpose.
|
||||
# 1. Test non-overlapped ranges.
|
||||
.Ltmp100:
|
||||
.short 4414 # Record kind: S_LOCAL
|
||||
.long 4109 # TypeIndex
|
||||
.short 0 # Flags
|
||||
.asciz "non_overlapped_ranges"
|
||||
.p2align 2
|
||||
.Ltmp101:
|
||||
.cv_def_range .L31 .L32, reg, 331
|
||||
.cv_def_range .L32 .L33, reg, 330
|
||||
.cv_def_range .L33 .L34, reg, 336
|
||||
.short .Ltmp103-.Ltmp102
|
||||
# CHECK: (lldb) image lookup -a 0x140001031 -v
|
||||
# CHECK: LineEntry: [0x0000000140001031-0x0000000140001034): C:\src\test\a.cpp:1000
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "non_overlapped_ranges", type = "S1", valid ranges = <block>, location = [0x0000000140001031, 0x0000000140001032) -> DW_OP_reg3 RBX
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x140001032 -v
|
||||
# CHECK: LineEntry: [0x0000000140001031-0x0000000140001034): C:\src\test\a.cpp:1000
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "non_overlapped_ranges", type = "S1", valid ranges = <block>, location = [0x0000000140001032, 0x0000000140001033) -> DW_OP_reg2 RCX
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x140001033 -v
|
||||
# CHECK: LineEntry: [0x0000000140001031-0x0000000140001034): C:\src\test\a.cpp:1000
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "non_overlapped_ranges", type = "S1", valid ranges = <block>, location = [0x0000000140001033, 0x0000000140001034) -> DW_OP_reg8 R8
|
||||
# CHECK-EMPTY:
|
||||
|
||||
# 2. Test overlapped subfield ranges at different offsets.
|
||||
.Ltmp102:
|
||||
.short 4414 # Record kind: S_LOCAL
|
||||
.long 4109 # TypeIndex
|
||||
.short 0 # Flags
|
||||
.asciz "overlapped_subfield_ranges"
|
||||
.p2align 2
|
||||
.Ltmp103:
|
||||
.cv_def_range .L34 .L36, subfield_reg, 3, 0
|
||||
.cv_def_range .L35 .L37, subfield_reg, 17, 4
|
||||
.cv_def_range .L37 .L39, subfield_reg, 18, 4
|
||||
.short .Ltmp105-.Ltmp104
|
||||
# CHECK: (lldb) image lookup -a 0x140001034 -v
|
||||
# CHECK: LineEntry: [0x0000000140001034-0x000000014000103b): C:\src\test\a.cpp:1001
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "overlapped_subfield_ranges", type = "S1", valid ranges = <block>, location = [0x0000000140001034, 0x0000000140001035) -> DW_OP_regx 0x3f, DW_OP_piece 0x1, DW_OP_piece 0x7
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x140001035 -v
|
||||
# CHECK: LineEntry: [0x0000000140001034-0x000000014000103b): C:\src\test\a.cpp:1001
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "overlapped_subfield_ranges", type = "S1", valid ranges = <block>, location = [0x0000000140001035, 0x0000000140001036) -> DW_OP_regx 0x3f, DW_OP_piece 0x1, DW_OP_piece 0x3, DW_OP_reg24 XMM7, DW_OP_piece 0x4
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x140001036 -v
|
||||
# CHECK: LineEntry: [0x0000000140001034-0x000000014000103b): C:\src\test\a.cpp:1001
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "overlapped_subfield_ranges", type = "S1", valid ranges = <block>, location = [0x0000000140001036, 0x0000000140001037) -> DW_OP_piece 0x4, DW_OP_reg24 XMM7, DW_OP_piece 0x4
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x140001037 -v
|
||||
# CHECK: LineEntry: [0x0000000140001034-0x000000014000103b): C:\src\test\a.cpp:1001
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "overlapped_subfield_ranges", type = "S1", valid ranges = <block>, location = [0x0000000140001037, 0x0000000140001039) -> DW_OP_piece 0x4, DW_OP_reg26 XMM9, DW_OP_piece 0x4
|
||||
# CHECK-EMPTY:
|
||||
|
||||
# 3. Test overlapped ranges for the whole value.
|
||||
.Ltmp104:
|
||||
.short 4414 # Record kind: S_LOCAL
|
||||
.long 4109 # TypeIndex
|
||||
.short 0 # Flags
|
||||
.asciz "overlapped_ranges_2"
|
||||
.p2align 2
|
||||
.Ltmp105:
|
||||
.cv_def_range .L3b .L3d, reg, 331
|
||||
.cv_def_range .L3c .L3e, reg, 330
|
||||
.cv_def_range .L3f .L44, reg, 339
|
||||
.cv_def_range .L41 .L43, reg, 328
|
||||
.short .Ltmp107-.Ltmp106
|
||||
# CHECK: (lldb) image lookup -a 0x14000103b -v
|
||||
# CHECK: LineEntry: [0x000000014000103b-0x0000000140001045): C:\src\test\a.cpp:1002
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "overlapped_ranges_2", type = "S1", valid ranges = <block>, location = [0x000000014000103b, 0x000000014000103c) -> DW_OP_reg3 RBX
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x14000103d -v
|
||||
# CHECK: LineEntry: [0x000000014000103b-0x0000000140001045): C:\src\test\a.cpp:1002
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "overlapped_ranges_2", type = "S1", valid ranges = <block>, location = [0x000000014000103c, 0x000000014000103e) -> DW_OP_reg2 RCX
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x14000103f -v
|
||||
# CHECK: LineEntry: [0x000000014000103b-0x0000000140001045): C:\src\test\a.cpp:1002
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "overlapped_ranges_2", type = "S1", valid ranges = <block>, location = [0x000000014000103f, 0x0000000140001041) -> DW_OP_reg11 R11
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x140001041 -v
|
||||
# CHECK: LineEntry: [0x000000014000103b-0x0000000140001045): C:\src\test\a.cpp:1002
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "overlapped_ranges_2", type = "S1", valid ranges = <block>, location = [0x0000000140001041, 0x0000000140001043) -> DW_OP_reg0 RAX
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x140001043 -v
|
||||
# CHECK: LineEntry: [0x000000014000103b-0x0000000140001045): C:\src\test\a.cpp:1002
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "overlapped_ranges_2", type = "S1", valid ranges = <block>, location = [0x0000000140001043, 0x0000000140001044) -> DW_OP_reg11 R11
|
||||
# CHECK-EMPTY:
|
||||
|
||||
# 4. Test overlapped ranges for both subfield and whole value.
|
||||
.Ltmp106:
|
||||
.short 4414 # Record kind: S_LOCAL
|
||||
.long 4109 # TypeIndex
|
||||
.short 0 # Flags
|
||||
.asciz "overlapped_ranges_3"
|
||||
.p2align 2
|
||||
.Ltmp107:
|
||||
# The following two lines result:
|
||||
# [.L45, .L46) -> value at offset 0 is at reg 3.
|
||||
# [.L46, .L49) -> value at offset 0 is at reg 3 and value at offset 4 is at reg 17.
|
||||
# [.L49, .L4a) -> value at offset 4 is at reg 17.
|
||||
.cv_def_range .L46 .L4a, subfield_reg, 17, 4
|
||||
.cv_def_range .L45 .L49, subfield_reg, 3, 0
|
||||
# The following overwrites range [.L47, .L48) and [.L49 .L4a) because whole
|
||||
# value location is preferred over composited value locations.
|
||||
.cv_def_range .L47 .L48, reg, 331
|
||||
.cv_def_range .L49 .L4a, reg, 328
|
||||
# For the same reason, reg 330 wins in following example.
|
||||
.cv_def_range .L4b .L4e, reg, 330
|
||||
.cv_def_range .L4b .L4d, subfield_reg, 17, 4
|
||||
.cv_def_range .L4c .L4e, subfield_reg, 3, 0
|
||||
.short .Ltmp109-.Ltmp108
|
||||
# CHECK: (lldb) image lookup -a 0x140001045 -v
|
||||
# CHECK: LineEntry: [0x0000000140001045-0x000000014000104e): C:\src\test\a.cpp:1003
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "overlapped_ranges_3", type = "S1", valid ranges = <block>, location = [0x0000000140001045, 0x0000000140001046) -> DW_OP_regx 0x3f, DW_OP_piece 0x1, DW_OP_piece 0x7
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x140001046 -v
|
||||
# CHECK: LineEntry: [0x0000000140001045-0x000000014000104e): C:\src\test\a.cpp:1003
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "overlapped_ranges_3", type = "S1", valid ranges = <block>, location = [0x0000000140001046, 0x0000000140001047) -> DW_OP_regx 0x3f, DW_OP_piece 0x1, DW_OP_piece 0x3, DW_OP_reg24 XMM7, DW_OP_piece 0x4
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x140001047 -v
|
||||
# CHECK: LineEntry: [0x0000000140001045-0x000000014000104e): C:\src\test\a.cpp:1003
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "overlapped_ranges_3", type = "S1", valid ranges = <block>, location = [0x0000000140001047, 0x0000000140001048) -> DW_OP_reg3 RBX
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x140001048 -v
|
||||
# CHECK: LineEntry: [0x0000000140001045-0x000000014000104e): C:\src\test\a.cpp:1003
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "overlapped_ranges_3", type = "S1", valid ranges = <block>, location = [0x0000000140001048, 0x0000000140001049) -> DW_OP_regx 0x3f, DW_OP_piece 0x1, DW_OP_piece 0x3, DW_OP_reg24 XMM7, DW_OP_piece 0x4
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x140001049 -v
|
||||
# CHECK: LineEntry: [0x0000000140001045-0x000000014000104e): C:\src\test\a.cpp:1003
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "overlapped_ranges_3", type = "S1", valid ranges = <block>, location = [0x0000000140001049, 0x000000014000104a) -> DW_OP_reg0 RAX
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x14000104a -v
|
||||
# CHECK: LineEntry: [0x0000000140001045-0x000000014000104e): C:\src\test\a.cpp:1003
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x14000104b -v
|
||||
# CHECK: LineEntry: [0x0000000140001045-0x000000014000104e): C:\src\test\a.cpp:1003
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "overlapped_ranges_3", type = "S1", valid ranges = <block>, location = [0x000000014000104b, 0x000000014000104e) -> DW_OP_reg2 RCX
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x14000104c -v
|
||||
# CHECK: LineEntry: [0x0000000140001045-0x000000014000104e): C:\src\test\a.cpp:1003
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "overlapped_ranges_3", type = "S1", valid ranges = <block>, location = [0x000000014000104b, 0x000000014000104e) -> DW_OP_reg2 RCX
|
||||
# CHECK-EMPTY:
|
||||
|
||||
# 5. Simple type with subfield.
|
||||
.Ltmp108:
|
||||
.short 4414 # Record kind: S_LOCAL
|
||||
.long 19 # TypeIndex
|
||||
.short 0 # Flags
|
||||
.asciz "simple_type1"
|
||||
.p2align 2
|
||||
.Ltmp109:
|
||||
.cv_def_range .L4e .L4f, subfield_reg, 17, 4
|
||||
.cv_def_range .L4e .L50, subfield_reg, 18, 0
|
||||
.short 2
|
||||
.short 4431 # Record kind: S_PROC_ID_END
|
||||
# CHECK: (lldb) image lookup -a 0x14000104e -v
|
||||
# CHECK: LineEntry: [0x000000014000104e-0x0000000140001050): C:\src\test\a.cpp:1004
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "simple_type1", type = "int64_t", valid ranges = <block>, location = [0x000000014000104e, 0x000000014000104f) -> DW_OP_reg26 XMM9, DW_OP_piece 0x4, DW_OP_reg24 XMM7, DW_OP_piece 0x4
|
||||
# CHECK-EMPTY:
|
||||
# CHECK: (lldb) image lookup -a 0x14000104f -v
|
||||
# CHECK: LineEntry: [0x000000014000104e-0x0000000140001050): C:\src\test\a.cpp:1004
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "simple_type1", type = "int64_t", valid ranges = <block>, location = [0x000000014000104f, 0x0000000140001050) -> DW_OP_reg26 XMM9, DW_OP_piece 0x4, DW_OP_piece 0x4
|
||||
# CHECK-EMPTY:
|
||||
|
||||
.Ltmp26:
|
||||
.p2align 2
|
||||
.cv_linetable 1, main, .Lfunc_end1
|
||||
@@ -452,25 +684,38 @@ main: # @main
|
||||
.byte 243
|
||||
.byte 242
|
||||
.byte 241
|
||||
# StringId (0x100C)
|
||||
.short 0x12 # Record length
|
||||
.short 0x1605 # Record kind: LF_STRING_ID
|
||||
.long 0x0 # Id
|
||||
.asciz "C:\\src\\test" # StringData
|
||||
# StringId (0x100D)
|
||||
.short 0xe # Record length
|
||||
.short 0x1605 # Record kind: LF_STRING_ID
|
||||
.long 0x0 # Id
|
||||
.asciz "a.cpp" # StringData
|
||||
.byte 242
|
||||
.byte 241
|
||||
# Manually created debug info for testing purpose, FieldList (0x100C) and Struct (0x100D)
|
||||
# FieldList (0x100C)
|
||||
.short 0x1a # Record length
|
||||
.short 0x1203 # Record kind: LF_FIELDLIST
|
||||
.short 0x150d # Member kind: DataMember ( LF_MEMBER )
|
||||
.short 0x3 # Attrs: Public
|
||||
.long 0x70 # Type: char
|
||||
.short 0x0 # FieldOffset
|
||||
.asciz "c" # Name
|
||||
.short 0x150d # Member kind: DataMember ( LF_MEMBER )
|
||||
.short 0x3 # Attrs: Public
|
||||
.long 0x74 # Type: int
|
||||
.short 0x4 # FieldOffset
|
||||
.asciz "i" # Name
|
||||
# Struct (0x100D)
|
||||
.short 0x20 # Record length
|
||||
.short 0x1505 # Record kind: LF_STRUCTURE
|
||||
.short 0x2 # MemberCount
|
||||
.short 0x200 # Properties ( HasUniqueName (0x200) )
|
||||
.long 0x100c # FieldList: <field list>
|
||||
.long 0x0 # DerivedFrom
|
||||
.long 0x0 # VShape
|
||||
.short 0x8 # SizeOf
|
||||
.asciz "S1" # Name
|
||||
.asciz ".?AUS1@@" # LinkageName
|
||||
# BuildInfo (0x100E)
|
||||
.short 0x1a # Record length
|
||||
.short 0x1603 # Record kind: LF_BUILDINFO
|
||||
.short 0x5 # NumArgs
|
||||
.long 0x100c # Argument: C:\src\test
|
||||
.short 0x1 # NumArgs
|
||||
.long 0x0 # Argument
|
||||
.long 0x0 # Argument
|
||||
.long 0x0 # Argument
|
||||
.long 0x100d # Argument: a.cpp
|
||||
.long 0x0 # Argument
|
||||
.long 0x0 # Argument
|
||||
.byte 242
|
||||
|
||||
@@ -1,433 +0,0 @@
|
||||
# clang-format off
|
||||
# REQUIRES: lld, x86
|
||||
|
||||
# RUN: %clang_cl --target=i386-windows-msvc -c /Fo%t.obj -- %s
|
||||
# RUN: lld-link /debug:full /nodefaultlib /entry:main %t.obj /out:%t.exe /base:0x400000
|
||||
# RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -f %t.exe -s \
|
||||
# RUN: %p/Inputs/subfield_register_simple_type.lldbinit 2>&1 | FileCheck %s
|
||||
|
||||
# This file is compiled from following source file:
|
||||
# clang-cl --target=i386-windows-msvc /Z7 /O1 -c /Fa a.cpp
|
||||
# __int64 __attribute__((optnone)) bar(__int64 x) { return x; };
|
||||
# __int64 foo(__int64 x) {
|
||||
# return bar(x);
|
||||
# }
|
||||
#
|
||||
# int main(int argc, char** argv) {
|
||||
# foo(argc);
|
||||
# return 0;
|
||||
# }
|
||||
|
||||
# FIXME: The following variable location have wrong register numbers due to
|
||||
# https://github.com/llvm/llvm-project/issues/53575. Fix them after resolving
|
||||
# the issue.
|
||||
|
||||
# CHECK: (lldb) image lookup -a 0x40102f -v
|
||||
# CHECK: LineEntry: [0x00401026-0x00401039): C:\src\a.cpp:3
|
||||
# CHECK-NEXT: Variable: id = {{.*}}, name = "x", type = "int64_t", valid ranges = [0x0040102f-0x00401036), location = DW_OP_reg0 EAX, DW_OP_piece 0x4, DW_OP_reg2 EDX, DW_OP_piece 0x4, decl =
|
||||
|
||||
.text
|
||||
.def @feat.00;
|
||||
.scl 3;
|
||||
.type 0;
|
||||
.endef
|
||||
.globl @feat.00
|
||||
.set @feat.00, 1
|
||||
.intel_syntax noprefix
|
||||
.file "a.cpp"
|
||||
.def "?bar@@YA_J_J@Z";
|
||||
.scl 2;
|
||||
.type 32;
|
||||
.endef
|
||||
.section .text,"xr",one_only,"?bar@@YA_J_J@Z"
|
||||
.globl "?bar@@YA_J_J@Z" # -- Begin function ?bar@@YA_J_J@Z
|
||||
.p2align 4, 0x90
|
||||
"?bar@@YA_J_J@Z": # @"?bar@@YA_J_J@Z"
|
||||
Lfunc_begin0:
|
||||
.cv_func_id 0
|
||||
.cv_file 1 "C:\\src\\a.cpp" "CB99424BC3DD1AB059A2DBC6841147F2" 1
|
||||
.cv_loc 0 1 1 0 # a.cpp:1:0
|
||||
.cv_fpo_proc "?bar@@YA_J_J@Z" 8
|
||||
# %bb.0: # %entry
|
||||
push ebp
|
||||
.cv_fpo_pushreg ebp
|
||||
mov ebp, esp
|
||||
.cv_fpo_setframe ebp
|
||||
and esp, -8
|
||||
.cv_fpo_stackalign 8
|
||||
sub esp, 8
|
||||
.cv_fpo_stackalloc 8
|
||||
.cv_fpo_endprologue
|
||||
mov eax, dword ptr [ebp + 8]
|
||||
mov ecx, dword ptr [ebp + 12]
|
||||
mov dword ptr [esp], eax
|
||||
mov dword ptr [esp + 4], ecx
|
||||
Ltmp0:
|
||||
mov eax, dword ptr [esp]
|
||||
mov edx, dword ptr [esp + 4]
|
||||
mov esp, ebp
|
||||
pop ebp
|
||||
ret
|
||||
Ltmp1:
|
||||
.cv_fpo_endproc
|
||||
Lfunc_end0:
|
||||
# -- End function
|
||||
.def "?foo@@YA_J_J@Z";
|
||||
.scl 2;
|
||||
.type 32;
|
||||
.endef
|
||||
.section .text,"xr",one_only,"?foo@@YA_J_J@Z"
|
||||
.globl "?foo@@YA_J_J@Z" # -- Begin function ?foo@@YA_J_J@Z
|
||||
"?foo@@YA_J_J@Z": # @"?foo@@YA_J_J@Z"
|
||||
Lfunc_begin1:
|
||||
.cv_func_id 1
|
||||
.cv_fpo_proc "?foo@@YA_J_J@Z" 8
|
||||
# %bb.0: # %entry
|
||||
#DEBUG_VALUE: foo:x <- [DW_OP_plus_uconst 4] [$esp+0]
|
||||
.cv_loc 1 1 3 0 # a.cpp:3:0
|
||||
jmp "?bar@@YA_J_J@Z" # TAILCALL
|
||||
Ltmp2:
|
||||
.cv_fpo_endproc
|
||||
Lfunc_end1:
|
||||
# -- End function
|
||||
.def _main;
|
||||
.scl 2;
|
||||
.type 32;
|
||||
.endef
|
||||
.section .text,"xr",one_only,_main
|
||||
.globl _main # -- Begin function main
|
||||
_main: # @main
|
||||
Lfunc_begin2:
|
||||
.cv_func_id 2
|
||||
.cv_loc 2 1 6 0 # a.cpp:6:0
|
||||
.cv_fpo_proc _main 8
|
||||
# %bb.0: # %entry
|
||||
#DEBUG_VALUE: main:argv <- [DW_OP_plus_uconst 8] [$esp+0]
|
||||
#DEBUG_VALUE: main:argc <- [DW_OP_plus_uconst 4] [$esp+0]
|
||||
.cv_inline_site_id 3 within 2 inlined_at 1 7 0
|
||||
.cv_loc 3 1 3 0 # a.cpp:3:0
|
||||
mov eax, dword ptr [esp + 4]
|
||||
mov ecx, eax
|
||||
sar ecx, 31
|
||||
Ltmp3:
|
||||
#DEBUG_VALUE: foo:x <- [DW_OP_LLVM_fragment 0 32] $eax
|
||||
#DEBUG_VALUE: foo:x <- [DW_OP_LLVM_fragment 32 32] $ecx
|
||||
push ecx
|
||||
Ltmp4:
|
||||
push eax
|
||||
call "?bar@@YA_J_J@Z"
|
||||
Ltmp5:
|
||||
add esp, 8
|
||||
Ltmp6:
|
||||
.cv_loc 2 1 8 0 # a.cpp:8:0
|
||||
xor eax, eax
|
||||
ret
|
||||
Ltmp7:
|
||||
.cv_fpo_endproc
|
||||
Lfunc_end2:
|
||||
# -- End function
|
||||
.section .drectve,"yn"
|
||||
.ascii " /DEFAULTLIB:libcmt.lib"
|
||||
.ascii " /DEFAULTLIB:oldnames.lib"
|
||||
.section .debug$S,"dr"
|
||||
.p2align 2
|
||||
.long 4 # Debug section magic
|
||||
.long 241
|
||||
.long Ltmp9-Ltmp8 # Subsection size
|
||||
Ltmp8:
|
||||
.short Ltmp11-Ltmp10 # Record length
|
||||
Ltmp10:
|
||||
.short 4353 # Record kind: S_OBJNAME
|
||||
.long 0 # Signature
|
||||
.asciz "C:\\src\\a.obj" # Object name
|
||||
.p2align 2
|
||||
Ltmp11:
|
||||
.short Ltmp13-Ltmp12 # Record length
|
||||
Ltmp12:
|
||||
.short 4412 # Record kind: S_COMPILE3
|
||||
.long 1 # Flags and language
|
||||
.short 7 # CPUType
|
||||
.short 15 # Frontend version
|
||||
.short 0
|
||||
.short 0
|
||||
.short 0
|
||||
.short 15000 # Backend version
|
||||
.short 0
|
||||
.short 0
|
||||
.short 0
|
||||
.asciz "clang version 15.0.0" # Null-terminated compiler version string
|
||||
.p2align 2
|
||||
Ltmp13:
|
||||
Ltmp9:
|
||||
.p2align 2
|
||||
.long 246 # Inlinee lines subsection
|
||||
.long Ltmp15-Ltmp14 # Subsection size
|
||||
Ltmp14:
|
||||
.long 0 # Inlinee lines signature
|
||||
|
||||
# Inlined function foo starts at a.cpp:2
|
||||
.long 4098 # Type index of inlined function
|
||||
.cv_filechecksumoffset 1 # Offset into filechecksum table
|
||||
.long 2 # Starting line number
|
||||
Ltmp15:
|
||||
.p2align 2
|
||||
.section .debug$S,"dr",associative,"?bar@@YA_J_J@Z"
|
||||
.p2align 2
|
||||
.long 4 # Debug section magic
|
||||
.cv_fpo_data "?bar@@YA_J_J@Z"
|
||||
.long 241 # Symbol subsection for bar
|
||||
.long Ltmp17-Ltmp16 # Subsection size
|
||||
Ltmp16:
|
||||
.short Ltmp19-Ltmp18 # Record length
|
||||
Ltmp18:
|
||||
.short 4423 # Record kind: S_GPROC32_ID
|
||||
.long 0 # PtrParent
|
||||
.long 0 # PtrEnd
|
||||
.long 0 # PtrNext
|
||||
.long Lfunc_end0-"?bar@@YA_J_J@Z" # Code size
|
||||
.long 0 # Offset after prologue
|
||||
.long 0 # Offset before epilogue
|
||||
.long 4099 # Function type index
|
||||
.secrel32 "?bar@@YA_J_J@Z" # Function section relative address
|
||||
.secidx "?bar@@YA_J_J@Z" # Function section index
|
||||
.byte 0 # Flags
|
||||
.asciz "bar" # Function name
|
||||
.p2align 2
|
||||
Ltmp19:
|
||||
.short Ltmp21-Ltmp20 # Record length
|
||||
Ltmp20:
|
||||
.short 4114 # Record kind: S_FRAMEPROC
|
||||
.long 12 # FrameSize
|
||||
.long 0 # Padding
|
||||
.long 0 # Offset of padding
|
||||
.long 0 # Bytes of callee saved registers
|
||||
.long 0 # Exception handler offset
|
||||
.short 0 # Exception handler section
|
||||
.long 147456 # Flags (defines frame register)
|
||||
.p2align 2
|
||||
Ltmp21:
|
||||
.short Ltmp23-Ltmp22 # Record length
|
||||
Ltmp22:
|
||||
.short 4414 # Record kind: S_LOCAL
|
||||
.long 19 # TypeIndex
|
||||
.short 1 # Flags
|
||||
.asciz "x"
|
||||
.p2align 2
|
||||
Ltmp23:
|
||||
.cv_def_range Ltmp0 Ltmp1, reg_rel, 30006, 0, -8
|
||||
.short 2 # Record length
|
||||
.short 4431 # Record kind: S_PROC_ID_END
|
||||
Ltmp17:
|
||||
.p2align 2
|
||||
.cv_linetable 0, "?bar@@YA_J_J@Z", Lfunc_end0
|
||||
.section .debug$S,"dr",associative,"?foo@@YA_J_J@Z"
|
||||
.p2align 2
|
||||
.long 4 # Debug section magic
|
||||
.cv_fpo_data "?foo@@YA_J_J@Z"
|
||||
.long 241 # Symbol subsection for foo
|
||||
.long Ltmp25-Ltmp24 # Subsection size
|
||||
Ltmp24:
|
||||
.short Ltmp27-Ltmp26 # Record length
|
||||
Ltmp26:
|
||||
.short 4423 # Record kind: S_GPROC32_ID
|
||||
.long 0 # PtrParent
|
||||
.long 0 # PtrEnd
|
||||
.long 0 # PtrNext
|
||||
.long Lfunc_end1-"?foo@@YA_J_J@Z" # Code size
|
||||
.long 0 # Offset after prologue
|
||||
.long 0 # Offset before epilogue
|
||||
.long 4098 # Function type index
|
||||
.secrel32 "?foo@@YA_J_J@Z" # Function section relative address
|
||||
.secidx "?foo@@YA_J_J@Z" # Function section index
|
||||
.byte 0 # Flags
|
||||
.asciz "foo" # Function name
|
||||
.p2align 2
|
||||
Ltmp27:
|
||||
.short Ltmp29-Ltmp28 # Record length
|
||||
Ltmp28:
|
||||
.short 4114 # Record kind: S_FRAMEPROC
|
||||
.long 0 # FrameSize
|
||||
.long 0 # Padding
|
||||
.long 0 # Offset of padding
|
||||
.long 0 # Bytes of callee saved registers
|
||||
.long 0 # Exception handler offset
|
||||
.short 0 # Exception handler section
|
||||
.long 0 # Flags (defines frame register)
|
||||
.p2align 2
|
||||
Ltmp29:
|
||||
.short Ltmp31-Ltmp30 # Record length
|
||||
Ltmp30:
|
||||
.short 4414 # Record kind: S_LOCAL
|
||||
.long 19 # TypeIndex
|
||||
.short 1 # Flags
|
||||
.asciz "x"
|
||||
.p2align 2
|
||||
Ltmp31:
|
||||
.cv_def_range Lfunc_begin1 Lfunc_end1, reg_rel, 30006, 0, 4
|
||||
.short 2 # Record length
|
||||
.short 4431 # Record kind: S_PROC_ID_END
|
||||
Ltmp25:
|
||||
.p2align 2
|
||||
.cv_linetable 1, "?foo@@YA_J_J@Z", Lfunc_end1
|
||||
.section .debug$S,"dr",associative,_main
|
||||
.p2align 2
|
||||
.long 4 # Debug section magic
|
||||
.cv_fpo_data _main
|
||||
.long 241 # Symbol subsection for main
|
||||
.long Ltmp33-Ltmp32 # Subsection size
|
||||
Ltmp32:
|
||||
.short Ltmp35-Ltmp34 # Record length
|
||||
Ltmp34:
|
||||
.short 4423 # Record kind: S_GPROC32_ID
|
||||
.long 0 # PtrParent
|
||||
.long 0 # PtrEnd
|
||||
.long 0 # PtrNext
|
||||
.long Lfunc_end2-_main # Code size
|
||||
.long 0 # Offset after prologue
|
||||
.long 0 # Offset before epilogue
|
||||
.long 4103 # Function type index
|
||||
.secrel32 _main # Function section relative address
|
||||
.secidx _main # Function section index
|
||||
.byte 0 # Flags
|
||||
.asciz "main" # Function name
|
||||
.p2align 2
|
||||
Ltmp35:
|
||||
.short Ltmp37-Ltmp36 # Record length
|
||||
Ltmp36:
|
||||
.short 4114 # Record kind: S_FRAMEPROC
|
||||
.long 0 # FrameSize
|
||||
.long 0 # Padding
|
||||
.long 0 # Offset of padding
|
||||
.long 0 # Bytes of callee saved registers
|
||||
.long 0 # Exception handler offset
|
||||
.short 0 # Exception handler section
|
||||
.long 0 # Flags (defines frame register)
|
||||
.p2align 2
|
||||
Ltmp37:
|
||||
.short Ltmp39-Ltmp38 # Record length
|
||||
Ltmp38:
|
||||
.short 4414 # Record kind: S_LOCAL
|
||||
.long 116 # TypeIndex
|
||||
.short 1 # Flags
|
||||
.asciz "argc"
|
||||
.p2align 2
|
||||
Ltmp39:
|
||||
.cv_def_range Lfunc_begin2 Ltmp4, reg_rel, 30006, 0, 4
|
||||
.short Ltmp41-Ltmp40 # Record length
|
||||
Ltmp40:
|
||||
.short 4414 # Record kind: S_LOCAL
|
||||
.long 4100 # TypeIndex
|
||||
.short 1 # Flags
|
||||
.asciz "argv"
|
||||
.p2align 2
|
||||
Ltmp41:
|
||||
.cv_def_range Lfunc_begin2 Ltmp4, reg_rel, 30006, 0, 8
|
||||
.short Ltmp43-Ltmp42 # Record length
|
||||
Ltmp42:
|
||||
.short 4429 # Record kind: S_INLINESITE
|
||||
.long 0 # PtrParent
|
||||
.long 0 # PtrEnd
|
||||
.long 4098 # Inlinee type index
|
||||
.cv_inline_linetable 3 1 2 Lfunc_begin2 Lfunc_end2
|
||||
.p2align 2
|
||||
Ltmp43:
|
||||
.short Ltmp45-Ltmp44 # Record length
|
||||
Ltmp44:
|
||||
.short 4414 # Record kind: S_LOCAL
|
||||
.long 19 # TypeIndex
|
||||
.short 1 # Flags
|
||||
.asciz "x"
|
||||
.p2align 2
|
||||
Ltmp45:
|
||||
.cv_def_range Ltmp3 Ltmp5, subfield_reg, 17, 0
|
||||
.cv_def_range Ltmp3 Ltmp5, subfield_reg, 18, 4
|
||||
.short 2 # Record length
|
||||
.short 4430 # Record kind: S_INLINESITE_END
|
||||
.short 2 # Record length
|
||||
.short 4431 # Record kind: S_PROC_ID_END
|
||||
Ltmp33:
|
||||
.p2align 2
|
||||
.cv_linetable 2, _main, Lfunc_end2
|
||||
.section .debug$S,"dr"
|
||||
.cv_filechecksums # File index to string table offset subsection
|
||||
.cv_stringtable # String table
|
||||
.long 241
|
||||
.long Ltmp47-Ltmp46 # Subsection size
|
||||
Ltmp46:
|
||||
.short Ltmp49-Ltmp48 # Record length
|
||||
Ltmp48:
|
||||
.short 4428 # Record kind: S_BUILDINFO
|
||||
.long 4109 # LF_BUILDINFO index
|
||||
.p2align 2
|
||||
Ltmp49:
|
||||
Ltmp47:
|
||||
.p2align 2
|
||||
.section .debug$T,"dr"
|
||||
.p2align 2
|
||||
.long 4 # Debug section magic
|
||||
# ArgList (0x1000)
|
||||
.short 0xa # Record length
|
||||
.short 0x1201 # Record kind: LF_ARGLIST
|
||||
.long 0x1 # NumArgs
|
||||
.long 0x13 # Argument: __int64
|
||||
# Procedure (0x1001)
|
||||
.short 0xe # Record length
|
||||
.short 0x1008 # Record kind: LF_PROCEDURE
|
||||
.long 0x13 # ReturnType: __int64
|
||||
.byte 0x0 # CallingConvention: NearC
|
||||
.byte 0x0 # FunctionOptions
|
||||
.short 0x1 # NumParameters
|
||||
.long 0x1000 # ArgListType: (__int64)
|
||||
# FuncId (0x1002)
|
||||
.short 0xe # Record length
|
||||
.short 0x1601 # Record kind: LF_FUNC_ID
|
||||
.long 0x0 # ParentScope
|
||||
.long 0x1001 # FunctionType: __int64 (__int64)
|
||||
.asciz "foo" # Name
|
||||
# FuncId (0x1003)
|
||||
.short 0xe # Record length
|
||||
.short 0x1601 # Record kind: LF_FUNC_ID
|
||||
.long 0x0 # ParentScope
|
||||
.long 0x1001 # FunctionType: __int64 (__int64)
|
||||
.asciz "bar" # Name
|
||||
# Pointer (0x1004)
|
||||
.short 0xa # Record length
|
||||
.short 0x1002 # Record kind: LF_POINTER
|
||||
.long 0x470 # PointeeType: char*
|
||||
.long 0x800a # Attrs: [ Type: Near32, Mode: Pointer, SizeOf: 4 ]
|
||||
# ArgList (0x1005)
|
||||
.short 0xe # Record length
|
||||
.short 0x1201 # Record kind: LF_ARGLIST
|
||||
.long 0x2 # NumArgs
|
||||
.long 0x74 # Argument: int
|
||||
.long 0x1004 # Argument: char**
|
||||
# Procedure (0x1006)
|
||||
.short 0xe # Record length
|
||||
.short 0x1008 # Record kind: LF_PROCEDURE
|
||||
.long 0x74 # ReturnType: int
|
||||
.byte 0x0 # CallingConvention: NearC
|
||||
.byte 0x0 # FunctionOptions
|
||||
.short 0x2 # NumParameters
|
||||
.long 0x1005 # ArgListType: (int, char**)
|
||||
# FuncId (0x1007)
|
||||
.short 0x12 # Record length
|
||||
.short 0x1601 # Record kind: LF_FUNC_ID
|
||||
.long 0x0 # ParentScope
|
||||
.long 0x1006 # FunctionType: int (int, char**)
|
||||
.asciz "main" # Name
|
||||
.byte 243
|
||||
.byte 242
|
||||
.byte 241
|
||||
# StringId (0x1008)
|
||||
.short 0xe # Record length
|
||||
.short 0x1605 # Record kind: LF_STRING_ID
|
||||
.long 0x0 # Id
|
||||
.asciz "C:\\src" # StringData
|
||||
.byte 241
|
||||
# StringId (0x1009)
|
||||
.short 0xe # Record length
|
||||
.short 0x1605 # Record kind: LF_STRING_ID
|
||||
.long 0x0 # Id
|
||||
.asciz "a.cpp" # StringData
|
||||
.byte 242
|
||||
.byte 241
|
||||
Reference in New Issue
Block a user