LLDB  mainline
PDBLocationToDWARFExpression.cpp
Go to the documentation of this file.
1 //===-- PDBLocationToDWARFExpression.cpp ----------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 
11 #include "lldb/Core/Section.h"
12 #include "lldb/Core/StreamBuffer.h"
13 #include "lldb/Core/dwarf.h"
15 #include "lldb/Symbol/Variable.h"
17 
18 #include "llvm/DebugInfo/CodeView/CodeView.h"
19 #include "llvm/DebugInfo/PDB/IPDBSession.h"
20 #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
21 
24 
25 using namespace lldb;
26 using namespace lldb_private;
27 using namespace lldb_private::npdb;
28 using namespace lldb_private::dwarf;
29 using namespace llvm::pdb;
30 
31 static std::unique_ptr<IPDBFrameData>
32 GetCorrespondingFrameData(const IPDBSession &session,
33  const Variable::RangeList &ranges) {
34  auto enumFrameData = session.getFrameData();
35  if (!enumFrameData)
36  return nullptr;
37 
38  std::unique_ptr<IPDBFrameData> found;
39  while (auto fd = enumFrameData->getNext()) {
40  Range<lldb::addr_t, lldb::addr_t> fdRange(fd->getVirtualAddress(),
41  fd->getLengthBlock());
42 
43  for (size_t i = 0; i < ranges.GetSize(); i++) {
44  auto range = ranges.GetEntryAtIndex(i);
45  if (!range)
46  continue;
47 
48  if (!range->DoesIntersect(fdRange))
49  continue;
50 
51  found = std::move(fd);
52 
53  break;
54  }
55  }
56 
57  return found;
58 }
59 
61  llvm::StringRef program, llvm::Triple::ArchType arch_type, Stream &stream) {
62  // VFrame value always stored in $TO pseudo-register
63  return TranslateFPOProgramToDWARFExpression(program, "$T0", arch_type,
64  stream);
65 }
66 
68  ModuleSP module, const PDBSymbolData &symbol,
69  const Variable::RangeList &ranges, bool &is_constant) {
70  is_constant = true;
71 
72  if (!module)
73  return DWARFExpression();
74 
75  const ArchSpec &architecture = module->GetArchitecture();
76  llvm::Triple::ArchType arch_type = architecture.GetMachine();
77  ByteOrder byte_order = architecture.GetByteOrder();
78  uint32_t address_size = architecture.GetAddressByteSize();
79  uint32_t byte_size = architecture.GetDataByteSize();
80  if (byte_order == eByteOrderInvalid || address_size == 0)
81  return DWARFExpression();
82 
83  RegisterKind register_kind = eRegisterKindDWARF;
84  StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order);
85  switch (symbol.getLocationType()) {
86  case PDB_LocType::Static:
87  case PDB_LocType::TLS: {
88  stream.PutHex8(DW_OP_addr);
89 
90  SectionList *section_list = module->GetSectionList();
91  if (!section_list)
92  return DWARFExpression();
93 
94  uint32_t section_id = symbol.getAddressSection();
95 
96  auto section = section_list->FindSectionByID(section_id);
97  if (!section)
98  return DWARFExpression();
99 
100  uint32_t offset = symbol.getAddressOffset();
101  stream.PutMaxHex64(section->GetFileAddress() + offset, address_size,
102  byte_order);
103 
104  is_constant = false;
105 
106  break;
107  }
108  case PDB_LocType::RegRel: {
109  uint32_t reg_num;
110  auto reg_id = symbol.getRegisterId();
111  if (reg_id == llvm::codeview::RegisterId::VFRAME) {
112  if (auto fd = GetCorrespondingFrameData(symbol.getSession(), ranges)) {
113  if (EmitVFrameEvaluationDWARFExpression(fd->getProgram(), arch_type,
114  stream)) {
115  int32_t offset = symbol.getOffset();
116  stream.PutHex8(DW_OP_consts);
117  stream.PutSLEB128(offset);
118  stream.PutHex8(DW_OP_plus);
119 
120  register_kind = eRegisterKindLLDB;
121 
122  is_constant = false;
123  break;
124  }
125  }
126 
127  register_kind = eRegisterKindGeneric;
128  reg_num = LLDB_REGNUM_GENERIC_FP;
129  } else {
130  register_kind = eRegisterKindLLDB;
131  reg_num = GetLLDBRegisterNumber(arch_type, reg_id);
132  if (reg_num == LLDB_INVALID_REGNUM)
133  return DWARFExpression();
134  }
135 
136  if (reg_num > 31) {
137  stream.PutHex8(DW_OP_bregx);
138  stream.PutULEB128(reg_num);
139  } else
140  stream.PutHex8(DW_OP_breg0 + reg_num);
141 
142  int32_t offset = symbol.getOffset();
143  stream.PutSLEB128(offset);
144 
145  is_constant = false;
146 
147  break;
148  }
149  case PDB_LocType::Enregistered: {
150  register_kind = eRegisterKindLLDB;
151  uint32_t reg_num = GetLLDBRegisterNumber(arch_type, symbol.getRegisterId());
152  if (reg_num == LLDB_INVALID_REGNUM)
153  return DWARFExpression();
154 
155  if (reg_num > 31) {
156  stream.PutHex8(DW_OP_regx);
157  stream.PutULEB128(reg_num);
158  } else
159  stream.PutHex8(DW_OP_reg0 + reg_num);
160 
161  is_constant = false;
162 
163  break;
164  }
165  case PDB_LocType::Constant: {
166  Variant value = symbol.getValue();
167  stream.PutRawBytes(&value.Value, sizeof(value.Value),
169  break;
170  }
171  default:
172  return DWARFExpression();
173  }
174 
175  DataBufferSP buffer =
176  std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
177  DataExtractor extractor(buffer, byte_order, address_size, byte_size);
178  DWARFExpression result(module, extractor, nullptr);
179  result.SetRegisterKind(register_kind);
180 
181  return result;
182 }
lldb_private::Stream::PutMaxHex64
size_t PutMaxHex64(uint64_t uvalue, size_t byte_size, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
Definition: Stream.cpp:288
lldb_private::npdb::TranslateFPOProgramToDWARFExpression
bool TranslateFPOProgramToDWARFExpression(llvm::StringRef program, llvm::StringRef register_name, llvm::Triple::ArchType arch_type, lldb_private::Stream &stream)
Definition: PdbFPOProgramToDWARFExpression.cpp:92
GetCorrespondingFrameData
static std::unique_ptr< IPDBFrameData > GetCorrespondingFrameData(const IPDBSession &session, const Variable::RangeList &ranges)
Definition: PDBLocationToDWARFExpression.cpp:32
lldb_private::ArchSpec::GetByteOrder
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition: ArchSpec.cpp:731
EmitVFrameEvaluationDWARFExpression
static bool EmitVFrameEvaluationDWARFExpression(llvm::StringRef program, llvm::Triple::ArchType arch_type, Stream &stream)
Definition: PDBLocationToDWARFExpression.cpp:60
lldb_private::ArchSpec
Definition: ArchSpec.h:33
LLDB_INVALID_REGNUM
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:79
lldb_private::ArchSpec::GetMachine
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition: ArchSpec.cpp:668
lldb::eRegisterKindDWARF
@ eRegisterKindDWARF
the register numbers seen DWARF
Definition: lldb-enumerations.h:229
lldb::eRegisterKindGeneric
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
Definition: lldb-enumerations.h:230
lldb_private::npdb
Definition: CodeViewRegisterMapping.h:16
lldb_private::SectionList
Definition: Section.h:34
lldb_private::Stream
Definition: Stream.h:28
Section.h
StreamBuffer.h
lldb_private::DWARFExpression::SetRegisterKind
void SetRegisterKind(lldb::RegisterKind reg_kind)
Set the call-frame-info style register kind.
Definition: DWARFExpression.cpp:104
lldb::eRegisterKindLLDB
@ eRegisterKindLLDB
lldb's internal register numbers
Definition: lldb-enumerations.h:234
lldb_private::DataExtractor
Definition: DataExtractor.h:48
PDBLocationToDWARFExpression.h
ConvertPDBLocationToDWARFExpression
DWARFExpression ConvertPDBLocationToDWARFExpression(ModuleSP module, const PDBSymbolData &symbol, const Variable::RangeList &ranges, bool &is_constant)
Definition: PDBLocationToDWARFExpression.cpp:67
lldb_private::DWARFExpression
Definition: DWARFExpression.h:36
llvm::pdb
Definition: DWARFLocationExpression.h:23
lldb_private::npdb::GetLLDBRegisterNumber
uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type, llvm::codeview::RegisterId register_id)
Definition: CodeViewRegisterMapping.cpp:424
lldb_private::Range< lldb::addr_t, lldb::addr_t >
lldb_private::StreamBuffer::GetSize
size_t GetSize() const
Definition: StreamBuffer.h:40
lldb_private::RangeVector< lldb::addr_t, lldb::addr_t >
lldb_private::ArchSpec::GetAddressByteSize
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition: ArchSpec.cpp:684
lldb::RegisterKind
RegisterKind
Register numbering types.
Definition: lldb-enumerations.h:227
dwarf.h
lldb::eByteOrderInvalid
@ eByteOrderInvalid
Definition: lldb-enumerations.h:139
uint32_t
lldb_private::StreamBuffer::GetData
const char * GetData() const
Definition: StreamBuffer.h:38
lldb_private::endian::InlHostByteOrder
lldb::ByteOrder InlHostByteOrder()
Definition: Endian.h:25
lldb_private::Stream::PutRawBytes
size_t PutRawBytes(const void *s, size_t src_len, lldb::ByteOrder src_byte_order=lldb::eByteOrderInvalid, lldb::ByteOrder dst_byte_order=lldb::eByteOrderInvalid)
Definition: Stream.cpp:329
PdbFPOProgramToDWARFExpression.h
lldb_private::ArchSpec::GetDataByteSize
uint32_t GetDataByteSize() const
Architecture data byte width accessor.
Definition: ArchSpec.cpp:660
DWARFExpression.h
lldb_private::StreamBuffer
Definition: StreamBuffer.h:19
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
LLDB_REGNUM_GENERIC_FP
#define LLDB_REGNUM_GENERIC_FP
Definition: lldb-defines.h:53
Variable.h
lldb
Definition: SBAddress.h:15
lldb_private::Stream::PutHex8
size_t size_t PutHex8(uint8_t uvalue)
Append an uint8_t value in the hexadecimal format to the stream.
Definition: Stream.cpp:234
CodeViewRegisterMapping.h
lldb_private::Stream::PutULEB128
size_t PutULEB128(uint64_t uval)
Output a ULEB128 number to the stream.
Definition: Stream.cpp:55
lldb_private::dwarf
Definition: dwarf.h:19
DataBufferHeap.h
lldb_private::SectionList::FindSectionByID
lldb::SectionSP FindSectionByID(lldb::user_id_t sect_id) const
Definition: Section.cpp:568
lldb_private::RangeVector::GetEntryAtIndex
const Entry * GetEntryAtIndex(size_t i) const
Definition: RangeMap.h:292
lldb::ByteOrder
ByteOrder
Byte ordering definitions.
Definition: lldb-enumerations.h:138
lldb_private::Stream::PutSLEB128
size_t PutSLEB128(int64_t uval)
Output a SLEB128 number to the stream.
Definition: Stream.cpp:47
lldb_private::RangeVector::GetSize
size_t GetSize() const
Definition: RangeMap.h:290