1 //===-- LVLocation.cpp ----------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This implements the LVOperation and LVLocation classes.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/DebugInfo/LogicalView/Core/LVLocation.h"
14 #include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
15 #include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
16 #include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
19 using namespace llvm::logicalview
;
21 #define DEBUG_TYPE "Location"
23 void LVOperation::print(raw_ostream
&OS
, bool Full
) const {}
25 // Identify the most common type of operations and print them using a high
26 // level format, trying to isolate the DWARF complexity.
27 std::string
LVOperation::getOperandsDWARFInfo() {
29 raw_string_ostream
Stream(String
);
31 auto PrintRegisterInfo
= [&](LVSmall Code
) {
32 //-----------------------------------------------------------------------
33 // 2.5.1.1 Literal encodings.
34 //-----------------------------------------------------------------------
35 if (dwarf::DW_OP_lit0
<= Code
&& Code
<= dwarf::DW_OP_lit31
) {
36 Stream
<< format("lit%d", Code
- dwarf::DW_OP_lit0
);
40 //-----------------------------------------------------------------------
41 // 2.5.1.2 Register values.
42 //-----------------------------------------------------------------------
43 if (dwarf::DW_OP_breg0
<= Code
&& Code
<= dwarf::DW_OP_breg31
) {
44 std::string
RegisterName(getReader().getRegisterName(Code
, Operands
));
45 Stream
<< format("breg%d+%d%s", Code
- dwarf::DW_OP_breg0
, Operands
[0],
46 RegisterName
.c_str());
50 //-----------------------------------------------------------------------
51 // 2.6.1.1.3 Register location descriptions.
52 //-----------------------------------------------------------------------
53 if (dwarf::DW_OP_reg0
<= Code
&& Code
<= dwarf::DW_OP_reg31
) {
54 std::string
RegisterName(getReader().getRegisterName(Code
, Operands
));
55 Stream
<< format("reg%d%s", Code
- dwarf::DW_OP_reg0
,
56 RegisterName
.c_str());
60 Stream
<< format("#0x%02x ", Code
) << hexString(Operands
[0]) << " "
61 << hexString(Operands
[1]) << "#";
65 //-------------------------------------------------------------------------
66 // 2.5.1.1 Literal encodings.
67 //-------------------------------------------------------------------------
68 case dwarf::DW_OP_addr
:
69 Stream
<< "addr " << hexString(Operands
[0]);
71 case dwarf::DW_OP_constu
:
72 case dwarf::DW_OP_const1u
:
73 case dwarf::DW_OP_const2u
:
74 case dwarf::DW_OP_const4u
:
75 case dwarf::DW_OP_const8u
:
76 Stream
<< "const_u " << unsigned(Operands
[0]);
78 case dwarf::DW_OP_consts
:
79 case dwarf::DW_OP_const1s
:
80 case dwarf::DW_OP_const2s
:
81 case dwarf::DW_OP_const4s
:
82 case dwarf::DW_OP_const8s
:
83 Stream
<< "const_s " << int(Operands
[0]);
85 case dwarf::DW_OP_addrx
:
86 Stream
<< "addrx " << unsigned(Operands
[0]);
88 case dwarf::DW_OP_constx
:
89 Stream
<< "constx " << unsigned(Operands
[0]);
91 case dwarf::DW_OP_const_type
:
92 Stream
<< "TODO: DW_OP_const_type";
95 //-------------------------------------------------------------------------
96 // 2.5.1.2 Register values.
97 //-------------------------------------------------------------------------
98 case dwarf::DW_OP_fbreg
:
99 Stream
<< "fbreg " << int(Operands
[0]);
101 case dwarf::DW_OP_bregx
: {
102 std::string
RegisterName(getReader().getRegisterName(Opcode
, Operands
));
103 Stream
<< format("bregx %d%s+%d", Operands
[0], RegisterName
.c_str(),
104 unsigned(Operands
[1]));
107 case dwarf::DW_OP_regval_type
: {
108 std::string
RegisterName(getReader().getRegisterName(Opcode
, Operands
));
109 Stream
<< format("regval_type %d%s+%d", Operands
[0], RegisterName
.c_str(),
110 unsigned(Operands
[1]));
114 //-------------------------------------------------------------------------
115 // 2.5.1.3 Stack operations.
116 //-------------------------------------------------------------------------
117 case dwarf::DW_OP_dup
:
120 case dwarf::DW_OP_drop
:
123 case dwarf::DW_OP_pick
:
124 Stream
<< "pick " << unsigned(Operands
[0]);
126 case dwarf::DW_OP_over
:
129 case dwarf::DW_OP_swap
:
132 case dwarf::DW_OP_rot
:
135 case dwarf::DW_OP_deref
:
138 case dwarf::DW_OP_deref_size
:
139 Stream
<< "deref_size " << unsigned(Operands
[0]);
141 case dwarf::DW_OP_deref_type
:
142 Stream
<< "deref_type " << unsigned(Operands
[0]) << " DIE offset "
143 << hexString(Operands
[1]);
145 case dwarf::DW_OP_xderef
:
148 case dwarf::DW_OP_xderef_size
:
149 Stream
<< "xderef_size " << unsigned(Operands
[0]);
151 case dwarf::DW_OP_xderef_type
:
152 Stream
<< "xderef_type " << unsigned(Operands
[0]) << " DIE offset "
153 << hexString(Operands
[1]);
155 case dwarf::DW_OP_push_object_address
:
156 Stream
<< "push_object_address";
158 case dwarf::DW_OP_form_tls_address
:
159 Stream
<< "form_tls_address " << hexString(Operands
[0]);
161 case dwarf::DW_OP_call_frame_cfa
:
162 Stream
<< "call_frame_cfa";
165 //-------------------------------------------------------------------------
166 // 2.5.1.4 Arithmetic and Logical Operations.
167 //-------------------------------------------------------------------------
168 case dwarf::DW_OP_abs
:
171 case dwarf::DW_OP_and
:
174 case dwarf::DW_OP_div
:
177 case dwarf::DW_OP_minus
:
180 case dwarf::DW_OP_mod
:
183 case dwarf::DW_OP_mul
:
186 case dwarf::DW_OP_neg
:
189 case dwarf::DW_OP_not
:
192 case dwarf::DW_OP_or
:
195 case dwarf::DW_OP_plus
:
198 case dwarf::DW_OP_plus_uconst
:
199 Stream
<< "plus_uconst " << unsigned(Operands
[0]);
201 case dwarf::DW_OP_shl
:
204 case dwarf::DW_OP_shr
:
207 case dwarf::DW_OP_shra
:
210 case dwarf::DW_OP_xor
:
214 //-------------------------------------------------------------------------
215 // 2.5.1.5 Control Flow Operations.
216 //-------------------------------------------------------------------------
217 case dwarf::DW_OP_le
:
220 case dwarf::DW_OP_ge
:
223 case dwarf::DW_OP_eq
:
226 case dwarf::DW_OP_lt
:
229 case dwarf::DW_OP_gt
:
232 case dwarf::DW_OP_ne
:
235 case dwarf::DW_OP_skip
:
236 Stream
<< "skip " << signed(Operands
[0]);
238 case dwarf::DW_OP_bra
:
239 Stream
<< "bra " << signed(Operands
[0]);
241 case dwarf::DW_OP_call2
:
242 Stream
<< "call2 DIE offset " << hexString(Operands
[0]);
244 case dwarf::DW_OP_call4
:
245 Stream
<< "call4 DIE offset " << hexString(Operands
[0]);
247 case dwarf::DW_OP_call_ref
:
248 Stream
<< "call_ref DIE offset " << hexString(Operands
[0]);
251 //-------------------------------------------------------------------------
252 // 2.5.1.6 Type Conversions.
253 //-------------------------------------------------------------------------
254 case dwarf::DW_OP_convert
:
255 Stream
<< "convert DIE offset " << hexString(Operands
[0]);
257 case dwarf::DW_OP_reinterpret
:
258 Stream
<< "reinterpret DIE offset " << hexString(Operands
[0]);
261 //-------------------------------------------------------------------------
262 // 2.5.1.7 Special Operations.
263 //-------------------------------------------------------------------------
264 case dwarf::DW_OP_nop
:
267 case dwarf::DW_OP_entry_value
:
268 Stream
<< "TODO: DW_OP_entry_value";
271 //-------------------------------------------------------------------------
272 // 2.6.1.1.3 Register location descriptions.
273 //-------------------------------------------------------------------------
274 case dwarf::DW_OP_regx
:
275 Stream
<< "regx" << getReader().getRegisterName(Opcode
, Operands
);
278 //-------------------------------------------------------------------------
279 // 2.6.1.1.4 Implicit location descriptions.
280 //-------------------------------------------------------------------------
281 case dwarf::DW_OP_stack_value
:
282 Stream
<< "stack_value";
284 case dwarf::DW_OP_implicit_value
:
285 Stream
<< "TODO: DW_OP_implicit_value";
287 case dwarf::DW_OP_implicit_pointer
:
288 Stream
<< "implicit_pointer DIE offset " << hexString(Operands
[0]) << " "
292 //-------------------------------------------------------------------------
293 // 2.6.1.2 Composite location descriptions.
294 //-------------------------------------------------------------------------
295 case dwarf::DW_OP_piece
:
296 Stream
<< "piece " << int(Operands
[0]);
298 case dwarf::DW_OP_bit_piece
:
299 Stream
<< "bit_piece " << int(Operands
[0]) << " offset "
303 //-------------------------------------------------------------------------
305 //-------------------------------------------------------------------------
306 case dwarf::DW_OP_GNU_entry_value
:
307 Stream
<< "gnu_entry_value ";
308 PrintRegisterInfo(dwarf::DW_OP_reg0
);
310 case dwarf::DW_OP_GNU_push_tls_address
:
311 Stream
<< "gnu_push_tls_address " << hexString(Operands
[0]);
313 case dwarf::DW_OP_GNU_addr_index
:
314 Stream
<< "gnu_addr_index " << unsigned(Operands
[0]);
316 case dwarf::DW_OP_GNU_const_index
:
317 Stream
<< "gnu_const_index " << unsigned(Operands
[0]);
320 //-------------------------------------------------------------------------
322 //-------------------------------------------------------------------------
323 case LVLocationMemberOffset
:
324 Stream
<< "offset " << int(Operands
[0]);
327 //-------------------------------------------------------------------------
329 //-------------------------------------------------------------------------
330 case dwarf::DW_OP_hi_user
:
334 //-------------------------------------------------------------------------
336 //-------------------------------------------------------------------------
338 PrintRegisterInfo(Opcode
);
345 // Identify the most common type of operations and print them using a high
346 // level format, trying to isolate the CodeView complexity.
347 std::string
LVOperation::getOperandsCodeViewInfo() {
349 raw_string_ostream
Stream(String
);
351 // Get original CodeView operation code.
352 uint16_t OperationCode
= getCodeViewOperationCode(Opcode
);
354 switch (OperationCode
) {
355 // Operands: [Offset].
356 case codeview::SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL
:
357 Stream
<< "frame_pointer_rel " << int(Operands
[0]);
359 case codeview::SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE
:
360 Stream
<< "frame_pointer_rel_full_scope " << int(Operands
[0]);
363 // Operands: [Register].
364 case codeview::SymbolKind::S_DEFRANGE_REGISTER
:
365 Stream
<< "register " << getReader().getRegisterName(Opcode
, Operands
);
367 case codeview::SymbolKind::S_DEFRANGE_SUBFIELD_REGISTER
:
368 Stream
<< "subfield_register "
369 << getReader().getRegisterName(Opcode
, Operands
);
372 // Operands: [Register, Offset].
373 case codeview::SymbolKind::S_DEFRANGE_REGISTER_REL
:
374 Stream
<< "register_rel " << getReader().getRegisterName(Opcode
, Operands
)
375 << " offset " << int(Operands
[1]);
378 // Operands: [Program].
379 case codeview::SymbolKind::S_DEFRANGE
:
380 Stream
<< "frame " << int(Operands
[0]);
382 case codeview::SymbolKind::S_DEFRANGE_SUBFIELD
:
383 Stream
<< "subfield " << int(Operands
[0]);
387 Stream
<< format("#0x%02x: ", Opcode
) << hexString(Operands
[0]) << " "
388 << hexString(Operands
[1]) << "#";
396 const char *const KindBaseClassOffset
= "BaseClassOffset";
397 const char *const KindBaseClassStep
= "BaseClassStep";
398 const char *const KindClassOffset
= "ClassOffset";
399 const char *const KindFixedAddress
= "FixedAddress";
400 const char *const KindMissingInfo
= "Missing";
401 const char *const KindOperation
= "Operation";
402 const char *const KindOperationList
= "OperationList";
403 const char *const KindRegister
= "Register";
404 const char *const KindUndefined
= "Undefined";
405 } // end anonymous namespace
407 //===----------------------------------------------------------------------===//
408 // DWARF location information.
409 //===----------------------------------------------------------------------===//
410 const char *LVLocation::kind() const {
411 const char *Kind
= KindUndefined
;
412 if (getIsBaseClassOffset())
413 Kind
= KindBaseClassOffset
;
414 else if (getIsBaseClassStep())
415 Kind
= KindBaseClassStep
;
416 else if (getIsClassOffset())
417 Kind
= KindClassOffset
;
418 else if (getIsFixedAddress())
419 Kind
= KindFixedAddress
;
420 else if (getIsGapEntry())
421 Kind
= KindMissingInfo
;
422 else if (getIsOperation())
423 Kind
= KindOperation
;
424 else if (getIsOperationList())
425 Kind
= KindOperationList
;
426 else if (getIsRegister())
431 std::string
LVLocation::getIntervalInfo() const {
432 static const char *const Question
= "?";
434 raw_string_ostream
Stream(String
);
435 if (getIsAddressRange())
438 auto PrintLine
= [&](const LVLine
*Line
) {
441 TheLine
= Line
->lineNumberAsStringStripped();
442 Stream
<< TheLine
.c_str();
449 PrintLine(getLowerLine());
451 PrintLine(getUpperLine());
453 if (options().getAttributeOffset())
454 // Print the active range (low pc and high pc).
455 Stream
<< " [" << hexString(getLowerAddress()) << ":"
456 << hexString(getUpperAddress()) << "]";
461 // Validate the ranges associated with the location.
462 bool LVLocation::validateRanges() {
463 // Traverse the locations and validate them against the address to line
464 // mapping in the current compile unit. Record those invalid ranges.
465 // A valid range must meet the following conditions:
466 // a) line(lopc) <= line(hipc)
467 // b) line(lopc) and line(hipc) are valid.
469 if (!hasAssociatedRange())
472 LVLineRange Range
= getReaderCompileUnit()->lineRange(this);
473 LVLine
*LowLine
= Range
.first
;
474 LVLine
*HighLine
= Range
.second
;
476 setLowerLine(LowLine
);
482 setUpperLine(HighLine
);
487 // Check for a valid interval.
488 if (LowLine
->getLineNumber() > HighLine
->getLineNumber()) {
496 bool LVLocation::calculateCoverage(LVLocations
*Locations
, unsigned &Factor
,
498 if (!options().getAttributeCoverage() && !Locations
)
501 // Calculate the coverage depending on the kind of location. We have
502 // the simple and composed locations.
503 if (Locations
->size() == 1) {
504 // Simple: fixed address, class offset, stack offset.
505 LVLocation
*Location
= Locations
->front();
506 // Some types of locations do not have specific kind. Now is the time
507 // to set those types, depending on the operation type.
508 Location
->updateKind();
509 if (Location
->getIsLocationSimple()) {
516 // Composed locations.
517 LVAddress LowerAddress
= 0;
518 LVAddress UpperAddress
= 0;
519 for (const LVLocation
*Location
: *Locations
)
520 // Do not include locations representing a gap.
521 if (!Location
->getIsGapEntry()) {
522 LowerAddress
= Location
->getLowerAddress();
523 UpperAddress
= Location
->getUpperAddress();
524 Factor
+= (UpperAddress
> LowerAddress
) ? UpperAddress
- LowerAddress
525 : LowerAddress
- UpperAddress
;
532 void LVLocation::printRaw(raw_ostream
&OS
, bool Full
) const {
533 // Print the active range (low pc and high pc).
534 OS
<< " [" << hexString(getLowerAddress()) << ":"
535 << hexString(getUpperAddress()) << "]\n";
536 // Print any DWARF operations.
537 printRawExtra(OS
, Full
);
540 void LVLocation::printInterval(raw_ostream
&OS
, bool Full
) const {
541 if (hasAssociatedRange())
542 OS
<< getIntervalInfo();
545 void LVLocation::print(raw_ostream
&OS
, bool Full
) const {
546 if (getReader().doPrintLocation(this)) {
547 LVObject::print(OS
, Full
);
548 printExtra(OS
, Full
);
552 void LVLocation::printExtra(raw_ostream
&OS
, bool Full
) const {
553 printInterval(OS
, Full
);
557 //===----------------------------------------------------------------------===//
558 // DWARF location for a symbol.
559 //===----------------------------------------------------------------------===//
560 // Add a Location Entry.
561 void LVLocationSymbol::addObject(LVAddress LowPC
, LVAddress HighPC
,
562 LVUnsigned SectionOffset
,
563 uint64_t LocDescOffset
) {
564 setLowerAddress(LowPC
);
565 setUpperAddress(HighPC
);
567 // Record the offset where the location information begins.
568 setOffset(LocDescOffset
? LocDescOffset
: SectionOffset
);
570 // A -1 HighPC value, indicates no range.
571 if (HighPC
== LVAddress(UINT64_MAX
))
572 setIsDiscardedRange();
574 // Update the location kind, using the DWARF attribute.
578 // Add a Location Record.
579 void LVLocationSymbol::addObject(LVSmall Opcode
,
580 ArrayRef
<LVUnsigned
> Operands
) {
582 Entries
= std::make_unique
<LVOperations
>();
583 Entries
->push_back(getReader().createOperation(Opcode
, Operands
));
586 // Based on the DWARF attribute, define the location kind.
587 void LVLocation::setKind() {
589 case dwarf::DW_AT_data_member_location
:
592 case dwarf::DW_AT_location
:
593 // Depending on the operand, we have a fixed address.
599 // For those symbols with absolute location information, ignore any
600 // gaps in their location description; that is the case with absolute
601 // memory addresses and members located at specific offsets.
602 if (hasAssociatedRange())
603 getParentSymbol()->setFillGaps();
606 void LVLocationSymbol::updateKind() {
607 // Update the location type for simple ones.
608 if (Entries
&& Entries
->size() == 1) {
609 if (dwarf::DW_OP_fbreg
== Entries
->front()->getOpcode())
614 void LVLocationSymbol::printRawExtra(raw_ostream
&OS
, bool Full
) const {
616 for (const LVOperation
*Operation
: *Entries
)
617 Operation
->print(OS
, Full
);
620 // Print location (formatted version).
621 void LVLocation::print(LVLocations
*Locations
, raw_ostream
&OS
, bool Full
) {
622 if (!Locations
|| Locations
->empty())
625 // Print the symbol coverage.
626 if (options().getAttributeCoverage()) {
627 // The location entries are contained within a symbol. Get a location,
628 // to access basic information about indentation, parent, etc.
629 LVLocation
*Location
= Locations
->front();
630 LVSymbol
*Symbol
= Location
->getParentSymbol();
631 float Percentage
= Symbol
->getCoveragePercentage();
633 // The coverage is dependent on the kind of location.
635 raw_string_ostream
Stream(String
);
636 Stream
<< format("%.2f%%", Percentage
);
637 if (!Location
->getIsLocationSimple())
638 Stream
<< format(" (%d/%d)", Symbol
->getCoverageFactor(),
639 Symbol
->getParentScope()->getCoverageFactor());
640 Symbol
->printAttributes(OS
, Full
, "{Coverage} ", Symbol
, StringRef(String
),
645 // Print the symbol location, including the missing entries.
646 if (getReader().doPrintLocation(/*Location=*/nullptr))
647 for (const LVLocation
*Location
: *Locations
)
648 Location
->print(OS
, Full
);
651 void LVLocationSymbol::printExtra(raw_ostream
&OS
, bool Full
) const {
654 OS
<< " -> CallSite";
655 printInterval(OS
, Full
);
658 // Print location entries.
659 if (Full
&& Entries
) {
660 bool CodeViewLocation
= getParentSymbol()->getHasCodeViewLocation();
661 std::stringstream Stream
;
663 for (LVOperation
*Operation
: *Entries
) {
665 << (CodeViewLocation
? Operation
->getOperandsCodeViewInfo()
666 : Operation
->getOperandsDWARFInfo());
669 printAttributes(OS
, Full
, "{Entry} ", const_cast<LVLocationSymbol
*>(this),
670 StringRef(Stream
.str()),