21#define DEBUG_TYPE "Location"
35 if (dwarf::DW_OP_lit0 <=
Code &&
Code <= dwarf::DW_OP_lit31) {
36 Stream <<
formatv(
"lit{0}",
Code - dwarf::DW_OP_lit0);
43 if (dwarf::DW_OP_breg0 <=
Code &&
Code <= dwarf::DW_OP_breg31) {
45 Stream <<
formatv(
"breg{0}+{1}{2}",
Code - dwarf::DW_OP_breg0,
46 Operands[0], RegisterName);
53 if (dwarf::DW_OP_reg0 <=
Code &&
Code <= dwarf::DW_OP_reg31) {
55 Stream <<
formatv(
"reg{0}{1}",
Code - dwarf::DW_OP_reg0, RegisterName);
67 case dwarf::DW_OP_addr:
68 Stream <<
"addr " <<
hexString(Operands[0]);
70 case dwarf::DW_OP_constu:
71 case dwarf::DW_OP_const1u:
72 case dwarf::DW_OP_const2u:
73 case dwarf::DW_OP_const4u:
74 case dwarf::DW_OP_const8u:
75 Stream <<
"const_u " <<
unsigned(Operands[0]);
77 case dwarf::DW_OP_consts:
78 case dwarf::DW_OP_const1s:
79 case dwarf::DW_OP_const2s:
80 case dwarf::DW_OP_const4s:
81 case dwarf::DW_OP_const8s:
82 Stream <<
"const_s " << int(Operands[0]);
84 case dwarf::DW_OP_addrx:
85 Stream <<
"addrx " <<
unsigned(Operands[0]);
87 case dwarf::DW_OP_constx:
88 Stream <<
"constx " <<
unsigned(Operands[0]);
90 case dwarf::DW_OP_const_type:
91 Stream <<
"TODO: DW_OP_const_type";
97 case dwarf::DW_OP_fbreg:
98 Stream <<
"fbreg " << int(Operands[0]);
100 case dwarf::DW_OP_bregx: {
102 Stream <<
formatv(
"bregx {0}{1}+{2}", Operands[0], RegisterName,
103 unsigned(Operands[1]));
106 case dwarf::DW_OP_regval_type: {
108 Stream <<
formatv(
"regval_type {0}{1}+{2}", Operands[0], RegisterName,
109 unsigned(Operands[1]));
116 case dwarf::DW_OP_dup:
119 case dwarf::DW_OP_drop:
122 case dwarf::DW_OP_pick:
123 Stream <<
"pick " <<
unsigned(Operands[0]);
125 case dwarf::DW_OP_over:
128 case dwarf::DW_OP_swap:
131 case dwarf::DW_OP_rot:
134 case dwarf::DW_OP_deref:
137 case dwarf::DW_OP_deref_size:
138 Stream <<
"deref_size " <<
unsigned(Operands[0]);
140 case dwarf::DW_OP_deref_type:
141 Stream <<
"deref_type " <<
unsigned(Operands[0]) <<
" DIE offset "
144 case dwarf::DW_OP_xderef:
147 case dwarf::DW_OP_xderef_size:
148 Stream <<
"xderef_size " <<
unsigned(Operands[0]);
150 case dwarf::DW_OP_xderef_type:
151 Stream <<
"xderef_type " <<
unsigned(Operands[0]) <<
" DIE offset "
154 case dwarf::DW_OP_push_object_address:
155 Stream <<
"push_object_address";
157 case dwarf::DW_OP_form_tls_address:
158 Stream <<
"form_tls_address";
160 case dwarf::DW_OP_call_frame_cfa:
161 Stream <<
"call_frame_cfa";
167 case dwarf::DW_OP_abs:
170 case dwarf::DW_OP_and:
173 case dwarf::DW_OP_div:
176 case dwarf::DW_OP_minus:
179 case dwarf::DW_OP_mod:
182 case dwarf::DW_OP_mul:
185 case dwarf::DW_OP_neg:
188 case dwarf::DW_OP_not:
191 case dwarf::DW_OP_or:
194 case dwarf::DW_OP_plus:
197 case dwarf::DW_OP_plus_uconst:
198 Stream <<
"plus_uconst " <<
unsigned(Operands[0]);
200 case dwarf::DW_OP_shl:
203 case dwarf::DW_OP_shr:
206 case dwarf::DW_OP_shra:
209 case dwarf::DW_OP_xor:
216 case dwarf::DW_OP_le:
219 case dwarf::DW_OP_ge:
222 case dwarf::DW_OP_eq:
225 case dwarf::DW_OP_lt:
228 case dwarf::DW_OP_gt:
231 case dwarf::DW_OP_ne:
234 case dwarf::DW_OP_skip:
235 Stream <<
"skip " << signed(Operands[0]);
237 case dwarf::DW_OP_bra:
238 Stream <<
"bra " << signed(Operands[0]);
240 case dwarf::DW_OP_call2:
241 Stream <<
"call2 DIE offset " <<
hexString(Operands[0]);
243 case dwarf::DW_OP_call4:
244 Stream <<
"call4 DIE offset " <<
hexString(Operands[0]);
246 case dwarf::DW_OP_call_ref:
247 Stream <<
"call_ref DIE offset " <<
hexString(Operands[0]);
253 case dwarf::DW_OP_convert:
254 Stream <<
"convert DIE offset " <<
hexString(Operands[0]);
256 case dwarf::DW_OP_reinterpret:
257 Stream <<
"reinterpret DIE offset " <<
hexString(Operands[0]);
263 case dwarf::DW_OP_nop:
266 case dwarf::DW_OP_entry_value:
267 Stream <<
"TODO: DW_OP_entry_value";
273 case dwarf::DW_OP_regx:
280 case dwarf::DW_OP_stack_value:
281 Stream <<
"stack_value";
283 case dwarf::DW_OP_implicit_value:
284 Stream <<
"TODO: DW_OP_implicit_value";
286 case dwarf::DW_OP_implicit_pointer:
287 Stream <<
"implicit_pointer DIE offset " <<
hexString(Operands[0]) <<
" "
294 case dwarf::DW_OP_piece:
295 Stream <<
"piece " << int(Operands[0]);
297 case dwarf::DW_OP_bit_piece:
298 Stream <<
"bit_piece " << int(Operands[0]) <<
" offset "
305 case dwarf::DW_OP_GNU_entry_value:
306 Stream <<
"gnu_entry_value ";
307 PrintRegisterInfo(dwarf::DW_OP_reg0);
309 case dwarf::DW_OP_GNU_push_tls_address:
310 Stream <<
"gnu_push_tls_address";
312 case dwarf::DW_OP_GNU_addr_index:
313 Stream <<
"gnu_addr_index " <<
unsigned(Operands[0]);
315 case dwarf::DW_OP_GNU_const_index:
316 Stream <<
"gnu_const_index " <<
unsigned(Operands[0]);
323 Stream <<
"offset " << int(Operands[0]);
337 PrintRegisterInfo(Opcode);
353 switch (OperationCode) {
355 case codeview::SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL:
356 Stream <<
"frame_pointer_rel " << int(Operands[0]);
358 case codeview::SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:
359 Stream <<
"frame_pointer_rel_full_scope " << int(Operands[0]);
363 case codeview::SymbolKind::S_DEFRANGE_REGISTER:
366 case codeview::SymbolKind::S_DEFRANGE_SUBFIELD_REGISTER:
367 Stream <<
"subfield_register "
372 case codeview::SymbolKind::S_DEFRANGE_REGISTER_REL:
374 <<
" offset " << int(Operands[1]);
377 case codeview::SymbolKind::S_DEFRANGE_REGISTER_REL_INDIR:
378 Stream <<
"register_rel_indir "
380 << int(Operands[1]) <<
" offset_in_udt " << int(Operands[2]);
384 case codeview::SymbolKind::S_DEFRANGE:
385 Stream <<
"frame " << int(Operands[0]);
387 case codeview::SymbolKind::S_DEFRANGE_SUBFIELD:
388 Stream <<
"subfield " << int(Operands[0]);
401const char *
const KindBaseClassOffset =
"BaseClassOffset";
402const char *
const KindBaseClassStep =
"BaseClassStep";
403const char *
const KindClassOffset =
"ClassOffset";
404const char *
const KindFixedAddress =
"FixedAddress";
405const char *
const KindMissingInfo =
"Missing";
406const char *
const KindOperation =
"Operation";
407const char *
const KindOperationList =
"OperationList";
408const char *
const KindRegister =
"Register";
409const char *
const KindUndefined =
"Undefined";
416 const char *
Kind = KindUndefined;
417 if (getIsBaseClassOffset())
418 Kind = KindBaseClassOffset;
419 else if (getIsBaseClassStep())
420 Kind = KindBaseClassStep;
421 else if (getIsClassOffset())
422 Kind = KindClassOffset;
423 else if (getIsFixedAddress())
424 Kind = KindFixedAddress;
425 else if (getIsGapEntry())
426 Kind = KindMissingInfo;
427 else if (getIsOperation())
428 Kind = KindOperation;
429 else if (getIsOperationList())
430 Kind = KindOperationList;
431 else if (getIsRegister())
437 static const char *
const Question =
"?";
440 if (getIsAddressRange())
446 TheLine =
Line->lineNumberAsStringStripped();
447 Stream << TheLine.c_str();
458 if (
options().getAttributeOffset())
474 if (!hasAssociatedRange())
514 if (
Location->getIsLocationSimple()) {
527 LowerAddress =
Location->getLowerAddress();
528 UpperAddress =
Location->getUpperAddress();
529 Factor += (UpperAddress > LowerAddress) ? UpperAddress - LowerAddress
530 : LowerAddress - UpperAddress;
546 if (hasAssociatedRange())
573 setOffset(LocDescOffset ? LocDescOffset : SectionOffset);
577 setIsDiscardedRange();
587 Entries = std::make_unique<LVOperations>();
594 case dwarf::DW_AT_data_member_location:
597 case dwarf::DW_AT_location:
607 if (hasAssociatedRange())
613 if (Entries && Entries->size() == 1) {
614 if (dwarf::DW_OP_fbreg == Entries->front()->getOpcode())
631 if (
options().getAttributeCoverage()) {
636 float Percentage =
Symbol->getCoveragePercentage();
641 Stream <<
formatv(
"{0:f2}%", Percentage);
642 if (!
Location->getIsLocationSimple())
644 Symbol->getParentScope()->getCoverageFactor());
651 if (
getReader().doPrintLocation(
nullptr))
659 OS <<
" -> CallSite";
664 if (
Full && Entries) {
666 std::stringstream Stream;
670 << (CodeViewLocation ?
Operation->getOperandsCodeViewInfo()
static std::string getRegisterName(const TargetRegisterInfo *TRI, Register Reg)
PowerPC Reduce CR logical Operation
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
StringRef - Represent a constant reference to a string, i.e.
void printExtra(raw_ostream &OS, bool Full=true) const override
void printRawExtra(raw_ostream &OS, bool Full=true) const override
void addObject(LVAddress LowPC, LVAddress HighPC, LVUnsigned SectionOffset, uint64_t LocDescOffset) override
const char * kind() const override
static bool calculateCoverage(LVLocations *Locations, unsigned &Factor, float &Percentage)
void setUpperAddress(LVAddress Address) override
const LVLine * getLowerLine() const
void setUpperLine(LVLine *Line)
virtual void updateKind()
std::string getIntervalInfo() const
virtual void printRawExtra(raw_ostream &OS, bool Full=true) const
void printRaw(raw_ostream &OS, bool Full=true) const
LVAddress getLowerAddress() const override
const LVLine * getUpperLine() const
void printExtra(raw_ostream &OS, bool Full=true) const override
static void print(LVLocations *Locations, raw_ostream &OS, bool Full=true)
void setLowerLine(LVLine *Line)
LVAddress getUpperAddress() const override
void printInterval(raw_ostream &OS, bool Full=true) const
void setLowerAddress(LVAddress Address) override
virtual void print(raw_ostream &OS, bool Full=true) const
void printAttributes(raw_ostream &OS, bool Full=true) const
dwarf::Attribute getAttr() const
LVSymbol * getParentSymbol() const
uint32_t getLineNumber() const
void setOffset(LVOffset DieOffset)
LLVM_ABI void print(raw_ostream &OS, bool Full=true) const
LLVM_ABI std::string getOperandsDWARFInfo()
LLVM_ABI std::string getOperandsCodeViewInfo()
virtual std::string getRegisterName(LVSmall Opcode, ArrayRef< uint64_t > Operands)
LVLineRange lineRange(LVLocation *Location) const
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
std::string hexString(uint64_t Value, size_t Width=HEX_WIDTH)
uint16_t getCodeViewOperationCode(uint8_t Code)
LVScopeCompileUnit * getReaderCompileUnit()
std::pair< LVLine *, LVLine * > LVLineRange
const LVSmall LVLocationMemberOffset
SmallVector< LVLocation *, 8 > LVLocations
This is an optimization pass for GlobalISel generic memory operations.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)