13c397c90SCarlos Alberto Enciso //===-- LVLocation.cpp ----------------------------------------------------===// 23c397c90SCarlos Alberto Enciso // 33c397c90SCarlos Alberto Enciso // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 43c397c90SCarlos Alberto Enciso // See https://llvm.org/LICENSE.txt for license information. 53c397c90SCarlos Alberto Enciso // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 63c397c90SCarlos Alberto Enciso // 73c397c90SCarlos Alberto Enciso //===----------------------------------------------------------------------===// 83c397c90SCarlos Alberto Enciso // 93c397c90SCarlos Alberto Enciso // This implements the LVOperation and LVLocation classes. 103c397c90SCarlos Alberto Enciso // 113c397c90SCarlos Alberto Enciso //===----------------------------------------------------------------------===// 123c397c90SCarlos Alberto Enciso 133c397c90SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVLocation.h" 143c397c90SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVReader.h" 153c397c90SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVScope.h" 163c397c90SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" 173c397c90SCarlos Alberto Enciso 183c397c90SCarlos Alberto Enciso using namespace llvm; 193c397c90SCarlos Alberto Enciso using namespace llvm::logicalview; 203c397c90SCarlos Alberto Enciso 213c397c90SCarlos Alberto Enciso #define DEBUG_TYPE "Location" 223c397c90SCarlos Alberto Enciso 233c397c90SCarlos Alberto Enciso void LVOperation::print(raw_ostream &OS, bool Full) const {} 243c397c90SCarlos Alberto Enciso 253c397c90SCarlos Alberto Enciso // Identify the most common type of operations and print them using a high 263c397c90SCarlos Alberto Enciso // level format, trying to isolate the DWARF complexity. 273c397c90SCarlos Alberto Enciso std::string LVOperation::getOperandsDWARFInfo() { 283c397c90SCarlos Alberto Enciso std::string String; 293c397c90SCarlos Alberto Enciso raw_string_ostream Stream(String); 303c397c90SCarlos Alberto Enciso 313c397c90SCarlos Alberto Enciso auto PrintRegisterInfo = [&](LVSmall Code) { 323c397c90SCarlos Alberto Enciso //----------------------------------------------------------------------- 333c397c90SCarlos Alberto Enciso // 2.5.1.1 Literal encodings. 343c397c90SCarlos Alberto Enciso //----------------------------------------------------------------------- 353c397c90SCarlos Alberto Enciso if (dwarf::DW_OP_lit0 <= Code && Code <= dwarf::DW_OP_lit31) { 363c397c90SCarlos Alberto Enciso Stream << format("lit%d", Code - dwarf::DW_OP_lit0); 373c397c90SCarlos Alberto Enciso return; 383c397c90SCarlos Alberto Enciso } 393c397c90SCarlos Alberto Enciso 403c397c90SCarlos Alberto Enciso //----------------------------------------------------------------------- 413c397c90SCarlos Alberto Enciso // 2.5.1.2 Register values. 423c397c90SCarlos Alberto Enciso //----------------------------------------------------------------------- 433c397c90SCarlos Alberto Enciso if (dwarf::DW_OP_breg0 <= Code && Code <= dwarf::DW_OP_breg31) { 443c397c90SCarlos Alberto Enciso std::string RegisterName(getReader().getRegisterName(Code, Operands)); 453c397c90SCarlos Alberto Enciso Stream << format("breg%d+%d%s", Code - dwarf::DW_OP_breg0, Operands[0], 463c397c90SCarlos Alberto Enciso RegisterName.c_str()); 473c397c90SCarlos Alberto Enciso return; 483c397c90SCarlos Alberto Enciso } 493c397c90SCarlos Alberto Enciso 503c397c90SCarlos Alberto Enciso //----------------------------------------------------------------------- 513c397c90SCarlos Alberto Enciso // 2.6.1.1.3 Register location descriptions. 523c397c90SCarlos Alberto Enciso //----------------------------------------------------------------------- 533c397c90SCarlos Alberto Enciso if (dwarf::DW_OP_reg0 <= Code && Code <= dwarf::DW_OP_reg31) { 543c397c90SCarlos Alberto Enciso std::string RegisterName(getReader().getRegisterName(Code, Operands)); 553c397c90SCarlos Alberto Enciso Stream << format("reg%d%s", Code - dwarf::DW_OP_reg0, 563c397c90SCarlos Alberto Enciso RegisterName.c_str()); 573c397c90SCarlos Alberto Enciso return; 583c397c90SCarlos Alberto Enciso } 593c397c90SCarlos Alberto Enciso 603c397c90SCarlos Alberto Enciso Stream << format("#0x%02x ", Code) << hexString(Operands[0]) << " " 613c397c90SCarlos Alberto Enciso << hexString(Operands[1]) << "#"; 623c397c90SCarlos Alberto Enciso }; 633c397c90SCarlos Alberto Enciso 643c397c90SCarlos Alberto Enciso switch (Opcode) { 653c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 663c397c90SCarlos Alberto Enciso // 2.5.1.1 Literal encodings. 673c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 683c397c90SCarlos Alberto Enciso case dwarf::DW_OP_addr: 693c397c90SCarlos Alberto Enciso Stream << "addr " << hexString(Operands[0]); 703c397c90SCarlos Alberto Enciso break; 713c397c90SCarlos Alberto Enciso case dwarf::DW_OP_constu: 723c397c90SCarlos Alberto Enciso case dwarf::DW_OP_const1u: 733c397c90SCarlos Alberto Enciso case dwarf::DW_OP_const2u: 743c397c90SCarlos Alberto Enciso case dwarf::DW_OP_const4u: 753c397c90SCarlos Alberto Enciso case dwarf::DW_OP_const8u: 763c397c90SCarlos Alberto Enciso Stream << "const_u " << unsigned(Operands[0]); 773c397c90SCarlos Alberto Enciso break; 783c397c90SCarlos Alberto Enciso case dwarf::DW_OP_consts: 793c397c90SCarlos Alberto Enciso case dwarf::DW_OP_const1s: 803c397c90SCarlos Alberto Enciso case dwarf::DW_OP_const2s: 813c397c90SCarlos Alberto Enciso case dwarf::DW_OP_const4s: 823c397c90SCarlos Alberto Enciso case dwarf::DW_OP_const8s: 833c397c90SCarlos Alberto Enciso Stream << "const_s " << int(Operands[0]); 843c397c90SCarlos Alberto Enciso break; 853c397c90SCarlos Alberto Enciso case dwarf::DW_OP_addrx: 863c397c90SCarlos Alberto Enciso Stream << "addrx " << unsigned(Operands[0]); 873c397c90SCarlos Alberto Enciso break; 883c397c90SCarlos Alberto Enciso case dwarf::DW_OP_constx: 893c397c90SCarlos Alberto Enciso Stream << "constx " << unsigned(Operands[0]); 903c397c90SCarlos Alberto Enciso break; 913c397c90SCarlos Alberto Enciso case dwarf::DW_OP_const_type: 923c397c90SCarlos Alberto Enciso Stream << "TODO: DW_OP_const_type"; 933c397c90SCarlos Alberto Enciso break; 943c397c90SCarlos Alberto Enciso 953c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 963c397c90SCarlos Alberto Enciso // 2.5.1.2 Register values. 973c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 983c397c90SCarlos Alberto Enciso case dwarf::DW_OP_fbreg: 993c397c90SCarlos Alberto Enciso Stream << "fbreg " << int(Operands[0]); 1003c397c90SCarlos Alberto Enciso break; 1013c397c90SCarlos Alberto Enciso case dwarf::DW_OP_bregx: { 1023c397c90SCarlos Alberto Enciso std::string RegisterName(getReader().getRegisterName(Opcode, Operands)); 1033c397c90SCarlos Alberto Enciso Stream << format("bregx %d%s+%d", Operands[0], RegisterName.c_str(), 1043c397c90SCarlos Alberto Enciso unsigned(Operands[1])); 1053c397c90SCarlos Alberto Enciso break; 1063c397c90SCarlos Alberto Enciso } 1073c397c90SCarlos Alberto Enciso case dwarf::DW_OP_regval_type: { 1083c397c90SCarlos Alberto Enciso std::string RegisterName(getReader().getRegisterName(Opcode, Operands)); 1093c397c90SCarlos Alberto Enciso Stream << format("regval_type %d%s+%d", Operands[0], RegisterName.c_str(), 1103c397c90SCarlos Alberto Enciso unsigned(Operands[1])); 1113c397c90SCarlos Alberto Enciso break; 1123c397c90SCarlos Alberto Enciso } 1133c397c90SCarlos Alberto Enciso 1143c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 1153c397c90SCarlos Alberto Enciso // 2.5.1.3 Stack operations. 1163c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 1173c397c90SCarlos Alberto Enciso case dwarf::DW_OP_dup: 1183c397c90SCarlos Alberto Enciso Stream << "dup"; 1193c397c90SCarlos Alberto Enciso break; 1203c397c90SCarlos Alberto Enciso case dwarf::DW_OP_drop: 1213c397c90SCarlos Alberto Enciso Stream << "drop"; 1223c397c90SCarlos Alberto Enciso break; 1233c397c90SCarlos Alberto Enciso case dwarf::DW_OP_pick: 1243c397c90SCarlos Alberto Enciso Stream << "pick " << unsigned(Operands[0]); 1253c397c90SCarlos Alberto Enciso break; 1263c397c90SCarlos Alberto Enciso case dwarf::DW_OP_over: 1273c397c90SCarlos Alberto Enciso Stream << "over"; 1283c397c90SCarlos Alberto Enciso break; 1293c397c90SCarlos Alberto Enciso case dwarf::DW_OP_swap: 1303c397c90SCarlos Alberto Enciso Stream << "swap"; 1313c397c90SCarlos Alberto Enciso break; 1323c397c90SCarlos Alberto Enciso case dwarf::DW_OP_rot: 1333c397c90SCarlos Alberto Enciso Stream << "rot"; 1343c397c90SCarlos Alberto Enciso break; 1353c397c90SCarlos Alberto Enciso case dwarf::DW_OP_deref: 1363c397c90SCarlos Alberto Enciso Stream << "deref"; 1373c397c90SCarlos Alberto Enciso break; 1383c397c90SCarlos Alberto Enciso case dwarf::DW_OP_deref_size: 1393c397c90SCarlos Alberto Enciso Stream << "deref_size " << unsigned(Operands[0]); 1403c397c90SCarlos Alberto Enciso break; 1413c397c90SCarlos Alberto Enciso case dwarf::DW_OP_deref_type: 1423c397c90SCarlos Alberto Enciso Stream << "deref_type " << unsigned(Operands[0]) << " DIE offset " 1433c397c90SCarlos Alberto Enciso << hexString(Operands[1]); 1443c397c90SCarlos Alberto Enciso break; 1453c397c90SCarlos Alberto Enciso case dwarf::DW_OP_xderef: 1463c397c90SCarlos Alberto Enciso Stream << "xderef"; 1473c397c90SCarlos Alberto Enciso break; 1483c397c90SCarlos Alberto Enciso case dwarf::DW_OP_xderef_size: 1493c397c90SCarlos Alberto Enciso Stream << "xderef_size " << unsigned(Operands[0]); 1503c397c90SCarlos Alberto Enciso break; 1513c397c90SCarlos Alberto Enciso case dwarf::DW_OP_xderef_type: 1523c397c90SCarlos Alberto Enciso Stream << "xderef_type " << unsigned(Operands[0]) << " DIE offset " 1533c397c90SCarlos Alberto Enciso << hexString(Operands[1]); 1543c397c90SCarlos Alberto Enciso break; 1553c397c90SCarlos Alberto Enciso case dwarf::DW_OP_push_object_address: 1563c397c90SCarlos Alberto Enciso Stream << "push_object_address"; 1573c397c90SCarlos Alberto Enciso break; 1583c397c90SCarlos Alberto Enciso case dwarf::DW_OP_form_tls_address: 159*a912c81fSCarlos Alberto Enciso Stream << "form_tls_address"; 1603c397c90SCarlos Alberto Enciso break; 1613c397c90SCarlos Alberto Enciso case dwarf::DW_OP_call_frame_cfa: 1623c397c90SCarlos Alberto Enciso Stream << "call_frame_cfa"; 1633c397c90SCarlos Alberto Enciso break; 1643c397c90SCarlos Alberto Enciso 1653c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 1663c397c90SCarlos Alberto Enciso // 2.5.1.4 Arithmetic and Logical Operations. 1673c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 1683c397c90SCarlos Alberto Enciso case dwarf::DW_OP_abs: 1693c397c90SCarlos Alberto Enciso Stream << "abs"; 1703c397c90SCarlos Alberto Enciso break; 1713c397c90SCarlos Alberto Enciso case dwarf::DW_OP_and: 1723c397c90SCarlos Alberto Enciso Stream << "and"; 1733c397c90SCarlos Alberto Enciso break; 1743c397c90SCarlos Alberto Enciso case dwarf::DW_OP_div: 1753c397c90SCarlos Alberto Enciso Stream << "div"; 1763c397c90SCarlos Alberto Enciso break; 1773c397c90SCarlos Alberto Enciso case dwarf::DW_OP_minus: 1783c397c90SCarlos Alberto Enciso Stream << "minus"; 1793c397c90SCarlos Alberto Enciso break; 1803c397c90SCarlos Alberto Enciso case dwarf::DW_OP_mod: 1813c397c90SCarlos Alberto Enciso Stream << "mod"; 1823c397c90SCarlos Alberto Enciso break; 1833c397c90SCarlos Alberto Enciso case dwarf::DW_OP_mul: 1843c397c90SCarlos Alberto Enciso Stream << "mul"; 1853c397c90SCarlos Alberto Enciso break; 1863c397c90SCarlos Alberto Enciso case dwarf::DW_OP_neg: 1873c397c90SCarlos Alberto Enciso Stream << "neg"; 1883c397c90SCarlos Alberto Enciso break; 1893c397c90SCarlos Alberto Enciso case dwarf::DW_OP_not: 1903c397c90SCarlos Alberto Enciso Stream << "not"; 1913c397c90SCarlos Alberto Enciso break; 1923c397c90SCarlos Alberto Enciso case dwarf::DW_OP_or: 1933c397c90SCarlos Alberto Enciso Stream << "or"; 1943c397c90SCarlos Alberto Enciso break; 1953c397c90SCarlos Alberto Enciso case dwarf::DW_OP_plus: 1963c397c90SCarlos Alberto Enciso Stream << "plus"; 1973c397c90SCarlos Alberto Enciso break; 1983c397c90SCarlos Alberto Enciso case dwarf::DW_OP_plus_uconst: 1993c397c90SCarlos Alberto Enciso Stream << "plus_uconst " << unsigned(Operands[0]); 2003c397c90SCarlos Alberto Enciso break; 2013c397c90SCarlos Alberto Enciso case dwarf::DW_OP_shl: 2023c397c90SCarlos Alberto Enciso Stream << "shl"; 2033c397c90SCarlos Alberto Enciso break; 2043c397c90SCarlos Alberto Enciso case dwarf::DW_OP_shr: 2053c397c90SCarlos Alberto Enciso Stream << "shr"; 2063c397c90SCarlos Alberto Enciso break; 2073c397c90SCarlos Alberto Enciso case dwarf::DW_OP_shra: 2083c397c90SCarlos Alberto Enciso Stream << "shra"; 2093c397c90SCarlos Alberto Enciso break; 2103c397c90SCarlos Alberto Enciso case dwarf::DW_OP_xor: 2113c397c90SCarlos Alberto Enciso Stream << "xor"; 2123c397c90SCarlos Alberto Enciso break; 2133c397c90SCarlos Alberto Enciso 2143c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 2153c397c90SCarlos Alberto Enciso // 2.5.1.5 Control Flow Operations. 2163c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 2173c397c90SCarlos Alberto Enciso case dwarf::DW_OP_le: 2183c397c90SCarlos Alberto Enciso Stream << "le"; 2193c397c90SCarlos Alberto Enciso break; 2203c397c90SCarlos Alberto Enciso case dwarf::DW_OP_ge: 2213c397c90SCarlos Alberto Enciso Stream << "ge"; 2223c397c90SCarlos Alberto Enciso break; 2233c397c90SCarlos Alberto Enciso case dwarf::DW_OP_eq: 2243c397c90SCarlos Alberto Enciso Stream << "eq"; 2253c397c90SCarlos Alberto Enciso break; 2263c397c90SCarlos Alberto Enciso case dwarf::DW_OP_lt: 2273c397c90SCarlos Alberto Enciso Stream << "lt"; 2283c397c90SCarlos Alberto Enciso break; 2293c397c90SCarlos Alberto Enciso case dwarf::DW_OP_gt: 2303c397c90SCarlos Alberto Enciso Stream << "gt"; 2313c397c90SCarlos Alberto Enciso break; 2323c397c90SCarlos Alberto Enciso case dwarf::DW_OP_ne: 2333c397c90SCarlos Alberto Enciso Stream << "ne"; 2343c397c90SCarlos Alberto Enciso break; 2353c397c90SCarlos Alberto Enciso case dwarf::DW_OP_skip: 2363c397c90SCarlos Alberto Enciso Stream << "skip " << signed(Operands[0]); 2373c397c90SCarlos Alberto Enciso break; 2383c397c90SCarlos Alberto Enciso case dwarf::DW_OP_bra: 2393c397c90SCarlos Alberto Enciso Stream << "bra " << signed(Operands[0]); 2403c397c90SCarlos Alberto Enciso break; 2413c397c90SCarlos Alberto Enciso case dwarf::DW_OP_call2: 2423c397c90SCarlos Alberto Enciso Stream << "call2 DIE offset " << hexString(Operands[0]); 2433c397c90SCarlos Alberto Enciso break; 2443c397c90SCarlos Alberto Enciso case dwarf::DW_OP_call4: 2453c397c90SCarlos Alberto Enciso Stream << "call4 DIE offset " << hexString(Operands[0]); 2463c397c90SCarlos Alberto Enciso break; 2473c397c90SCarlos Alberto Enciso case dwarf::DW_OP_call_ref: 2483c397c90SCarlos Alberto Enciso Stream << "call_ref DIE offset " << hexString(Operands[0]); 2493c397c90SCarlos Alberto Enciso break; 2503c397c90SCarlos Alberto Enciso 2513c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 2523c397c90SCarlos Alberto Enciso // 2.5.1.6 Type Conversions. 2533c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 2543c397c90SCarlos Alberto Enciso case dwarf::DW_OP_convert: 2553c397c90SCarlos Alberto Enciso Stream << "convert DIE offset " << hexString(Operands[0]); 2563c397c90SCarlos Alberto Enciso break; 2573c397c90SCarlos Alberto Enciso case dwarf::DW_OP_reinterpret: 2583c397c90SCarlos Alberto Enciso Stream << "reinterpret DIE offset " << hexString(Operands[0]); 2593c397c90SCarlos Alberto Enciso break; 2603c397c90SCarlos Alberto Enciso 2613c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 2623c397c90SCarlos Alberto Enciso // 2.5.1.7 Special Operations. 2633c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 2643c397c90SCarlos Alberto Enciso case dwarf::DW_OP_nop: 2653c397c90SCarlos Alberto Enciso Stream << "nop"; 2663c397c90SCarlos Alberto Enciso break; 2673c397c90SCarlos Alberto Enciso case dwarf::DW_OP_entry_value: 2683c397c90SCarlos Alberto Enciso Stream << "TODO: DW_OP_entry_value"; 2693c397c90SCarlos Alberto Enciso break; 2703c397c90SCarlos Alberto Enciso 2713c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 2723c397c90SCarlos Alberto Enciso // 2.6.1.1.3 Register location descriptions. 2733c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 2743c397c90SCarlos Alberto Enciso case dwarf::DW_OP_regx: 2753c397c90SCarlos Alberto Enciso Stream << "regx" << getReader().getRegisterName(Opcode, Operands); 2763c397c90SCarlos Alberto Enciso break; 2773c397c90SCarlos Alberto Enciso 2783c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 2793c397c90SCarlos Alberto Enciso // 2.6.1.1.4 Implicit location descriptions. 2803c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 2813c397c90SCarlos Alberto Enciso case dwarf::DW_OP_stack_value: 2823c397c90SCarlos Alberto Enciso Stream << "stack_value"; 2833c397c90SCarlos Alberto Enciso break; 2843c397c90SCarlos Alberto Enciso case dwarf::DW_OP_implicit_value: 2853c397c90SCarlos Alberto Enciso Stream << "TODO: DW_OP_implicit_value"; 2863c397c90SCarlos Alberto Enciso break; 2873c397c90SCarlos Alberto Enciso case dwarf::DW_OP_implicit_pointer: 2883c397c90SCarlos Alberto Enciso Stream << "implicit_pointer DIE offset " << hexString(Operands[0]) << " " 2893c397c90SCarlos Alberto Enciso << int(Operands[1]); 2903c397c90SCarlos Alberto Enciso break; 2913c397c90SCarlos Alberto Enciso 2923c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 2933c397c90SCarlos Alberto Enciso // 2.6.1.2 Composite location descriptions. 2943c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 2953c397c90SCarlos Alberto Enciso case dwarf::DW_OP_piece: 2963c397c90SCarlos Alberto Enciso Stream << "piece " << int(Operands[0]); 2973c397c90SCarlos Alberto Enciso break; 2983c397c90SCarlos Alberto Enciso case dwarf::DW_OP_bit_piece: 2993c397c90SCarlos Alberto Enciso Stream << "bit_piece " << int(Operands[0]) << " offset " 3003c397c90SCarlos Alberto Enciso << int(Operands[1]); 3013c397c90SCarlos Alberto Enciso break; 3023c397c90SCarlos Alberto Enciso 3033c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 3043c397c90SCarlos Alberto Enciso // GNU extensions. 3053c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 3063c397c90SCarlos Alberto Enciso case dwarf::DW_OP_GNU_entry_value: 3073c397c90SCarlos Alberto Enciso Stream << "gnu_entry_value "; 3083c397c90SCarlos Alberto Enciso PrintRegisterInfo(dwarf::DW_OP_reg0); 3093c397c90SCarlos Alberto Enciso break; 3103c397c90SCarlos Alberto Enciso case dwarf::DW_OP_GNU_push_tls_address: 311*a912c81fSCarlos Alberto Enciso Stream << "gnu_push_tls_address"; 3123c397c90SCarlos Alberto Enciso break; 3133c397c90SCarlos Alberto Enciso case dwarf::DW_OP_GNU_addr_index: 3143c397c90SCarlos Alberto Enciso Stream << "gnu_addr_index " << unsigned(Operands[0]); 3153c397c90SCarlos Alberto Enciso break; 3163c397c90SCarlos Alberto Enciso case dwarf::DW_OP_GNU_const_index: 3173c397c90SCarlos Alberto Enciso Stream << "gnu_const_index " << unsigned(Operands[0]); 3183c397c90SCarlos Alberto Enciso break; 3193c397c90SCarlos Alberto Enciso 3203c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 3213c397c90SCarlos Alberto Enciso // Member location. 3223c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 3233c397c90SCarlos Alberto Enciso case LVLocationMemberOffset: 3243c397c90SCarlos Alberto Enciso Stream << "offset " << int(Operands[0]); 3253c397c90SCarlos Alberto Enciso break; 3263c397c90SCarlos Alberto Enciso 3273c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 3283c397c90SCarlos Alberto Enciso // Missing location. 3293c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 3303c397c90SCarlos Alberto Enciso case dwarf::DW_OP_hi_user: 3313c397c90SCarlos Alberto Enciso Stream << "missing"; 3323c397c90SCarlos Alberto Enciso break; 3333c397c90SCarlos Alberto Enciso 3343c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 3353c397c90SCarlos Alberto Enciso // Register values. 3363c397c90SCarlos Alberto Enciso //------------------------------------------------------------------------- 3373c397c90SCarlos Alberto Enciso default: 3383c397c90SCarlos Alberto Enciso PrintRegisterInfo(Opcode); 3393c397c90SCarlos Alberto Enciso break; 3403c397c90SCarlos Alberto Enciso } 3413c397c90SCarlos Alberto Enciso 3423c397c90SCarlos Alberto Enciso return String; 3433c397c90SCarlos Alberto Enciso } 3443c397c90SCarlos Alberto Enciso 3453c397c90SCarlos Alberto Enciso // Identify the most common type of operations and print them using a high 3463c397c90SCarlos Alberto Enciso // level format, trying to isolate the CodeView complexity. 3473c397c90SCarlos Alberto Enciso std::string LVOperation::getOperandsCodeViewInfo() { 3483c397c90SCarlos Alberto Enciso std::string String; 3493c397c90SCarlos Alberto Enciso raw_string_ostream Stream(String); 3503c397c90SCarlos Alberto Enciso 3513c397c90SCarlos Alberto Enciso // Get original CodeView operation code. 3523c397c90SCarlos Alberto Enciso uint16_t OperationCode = getCodeViewOperationCode(Opcode); 3533c397c90SCarlos Alberto Enciso 3543c397c90SCarlos Alberto Enciso switch (OperationCode) { 3552e6bb8c9SScott Linder // Operands: [Offset]. 3563c397c90SCarlos Alberto Enciso case codeview::SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL: 3573c397c90SCarlos Alberto Enciso Stream << "frame_pointer_rel " << int(Operands[0]); 3583c397c90SCarlos Alberto Enciso break; 3593c397c90SCarlos Alberto Enciso case codeview::SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE: 3603c397c90SCarlos Alberto Enciso Stream << "frame_pointer_rel_full_scope " << int(Operands[0]); 3613c397c90SCarlos Alberto Enciso break; 3623c397c90SCarlos Alberto Enciso 3632e6bb8c9SScott Linder // Operands: [Register]. 3643c397c90SCarlos Alberto Enciso case codeview::SymbolKind::S_DEFRANGE_REGISTER: 3653c397c90SCarlos Alberto Enciso Stream << "register " << getReader().getRegisterName(Opcode, Operands); 3663c397c90SCarlos Alberto Enciso break; 3673c397c90SCarlos Alberto Enciso case codeview::SymbolKind::S_DEFRANGE_SUBFIELD_REGISTER: 3683c397c90SCarlos Alberto Enciso Stream << "subfield_register " 3693c397c90SCarlos Alberto Enciso << getReader().getRegisterName(Opcode, Operands); 3703c397c90SCarlos Alberto Enciso break; 3713c397c90SCarlos Alberto Enciso 3723c397c90SCarlos Alberto Enciso // Operands: [Register, Offset]. 3733c397c90SCarlos Alberto Enciso case codeview::SymbolKind::S_DEFRANGE_REGISTER_REL: 3743c397c90SCarlos Alberto Enciso Stream << "register_rel " << getReader().getRegisterName(Opcode, Operands) 3753c397c90SCarlos Alberto Enciso << " offset " << int(Operands[1]); 3763c397c90SCarlos Alberto Enciso break; 3773c397c90SCarlos Alberto Enciso 3782e6bb8c9SScott Linder // Operands: [Program]. 3793c397c90SCarlos Alberto Enciso case codeview::SymbolKind::S_DEFRANGE: 3803c397c90SCarlos Alberto Enciso Stream << "frame " << int(Operands[0]); 3813c397c90SCarlos Alberto Enciso break; 3823c397c90SCarlos Alberto Enciso case codeview::SymbolKind::S_DEFRANGE_SUBFIELD: 3833c397c90SCarlos Alberto Enciso Stream << "subfield " << int(Operands[0]); 3843c397c90SCarlos Alberto Enciso break; 3853c397c90SCarlos Alberto Enciso 3863c397c90SCarlos Alberto Enciso default: 3873c397c90SCarlos Alberto Enciso Stream << format("#0x%02x: ", Opcode) << hexString(Operands[0]) << " " 3883c397c90SCarlos Alberto Enciso << hexString(Operands[1]) << "#"; 3893c397c90SCarlos Alberto Enciso break; 3903c397c90SCarlos Alberto Enciso } 3913c397c90SCarlos Alberto Enciso 3923c397c90SCarlos Alberto Enciso return String; 3933c397c90SCarlos Alberto Enciso } 3943c397c90SCarlos Alberto Enciso 3953c397c90SCarlos Alberto Enciso namespace { 3963c397c90SCarlos Alberto Enciso const char *const KindBaseClassOffset = "BaseClassOffset"; 3973c397c90SCarlos Alberto Enciso const char *const KindBaseClassStep = "BaseClassStep"; 3983c397c90SCarlos Alberto Enciso const char *const KindClassOffset = "ClassOffset"; 3993c397c90SCarlos Alberto Enciso const char *const KindFixedAddress = "FixedAddress"; 4003c397c90SCarlos Alberto Enciso const char *const KindMissingInfo = "Missing"; 4013c397c90SCarlos Alberto Enciso const char *const KindOperation = "Operation"; 4023c397c90SCarlos Alberto Enciso const char *const KindOperationList = "OperationList"; 4033c397c90SCarlos Alberto Enciso const char *const KindRegister = "Register"; 4043c397c90SCarlos Alberto Enciso const char *const KindUndefined = "Undefined"; 4053c397c90SCarlos Alberto Enciso } // end anonymous namespace 4063c397c90SCarlos Alberto Enciso 4073c397c90SCarlos Alberto Enciso //===----------------------------------------------------------------------===// 4083c397c90SCarlos Alberto Enciso // DWARF location information. 4093c397c90SCarlos Alberto Enciso //===----------------------------------------------------------------------===// 4103c397c90SCarlos Alberto Enciso const char *LVLocation::kind() const { 4113c397c90SCarlos Alberto Enciso const char *Kind = KindUndefined; 4123c397c90SCarlos Alberto Enciso if (getIsBaseClassOffset()) 4133c397c90SCarlos Alberto Enciso Kind = KindBaseClassOffset; 4143c397c90SCarlos Alberto Enciso else if (getIsBaseClassStep()) 4153c397c90SCarlos Alberto Enciso Kind = KindBaseClassStep; 4163c397c90SCarlos Alberto Enciso else if (getIsClassOffset()) 4173c397c90SCarlos Alberto Enciso Kind = KindClassOffset; 4183c397c90SCarlos Alberto Enciso else if (getIsFixedAddress()) 4193c397c90SCarlos Alberto Enciso Kind = KindFixedAddress; 4203c397c90SCarlos Alberto Enciso else if (getIsGapEntry()) 4213c397c90SCarlos Alberto Enciso Kind = KindMissingInfo; 4223c397c90SCarlos Alberto Enciso else if (getIsOperation()) 4233c397c90SCarlos Alberto Enciso Kind = KindOperation; 4243c397c90SCarlos Alberto Enciso else if (getIsOperationList()) 4253c397c90SCarlos Alberto Enciso Kind = KindOperationList; 4263c397c90SCarlos Alberto Enciso else if (getIsRegister()) 4273c397c90SCarlos Alberto Enciso Kind = KindRegister; 4283c397c90SCarlos Alberto Enciso return Kind; 4293c397c90SCarlos Alberto Enciso } 4303c397c90SCarlos Alberto Enciso 4313c397c90SCarlos Alberto Enciso std::string LVLocation::getIntervalInfo() const { 4323c397c90SCarlos Alberto Enciso static const char *const Question = "?"; 4333c397c90SCarlos Alberto Enciso std::string String; 4343c397c90SCarlos Alberto Enciso raw_string_ostream Stream(String); 4353c397c90SCarlos Alberto Enciso if (getIsAddressRange()) 4363c397c90SCarlos Alberto Enciso Stream << "{Range}"; 4373c397c90SCarlos Alberto Enciso 4383c397c90SCarlos Alberto Enciso auto PrintLine = [&](const LVLine *Line) { 4393c397c90SCarlos Alberto Enciso if (Line) { 4403c397c90SCarlos Alberto Enciso std::string TheLine; 4413c397c90SCarlos Alberto Enciso TheLine = Line->lineNumberAsStringStripped(); 4423c397c90SCarlos Alberto Enciso Stream << TheLine.c_str(); 4433c397c90SCarlos Alberto Enciso } else { 4443c397c90SCarlos Alberto Enciso Stream << Question; 4453c397c90SCarlos Alberto Enciso } 4463c397c90SCarlos Alberto Enciso }; 4473c397c90SCarlos Alberto Enciso 4483c397c90SCarlos Alberto Enciso Stream << " Lines "; 4493c397c90SCarlos Alberto Enciso PrintLine(getLowerLine()); 4503c397c90SCarlos Alberto Enciso Stream << ":"; 4513c397c90SCarlos Alberto Enciso PrintLine(getUpperLine()); 4523c397c90SCarlos Alberto Enciso 4533c397c90SCarlos Alberto Enciso if (options().getAttributeOffset()) 4543c397c90SCarlos Alberto Enciso // Print the active range (low pc and high pc). 4553c397c90SCarlos Alberto Enciso Stream << " [" << hexString(getLowerAddress()) << ":" 4563c397c90SCarlos Alberto Enciso << hexString(getUpperAddress()) << "]"; 4573c397c90SCarlos Alberto Enciso 4583c397c90SCarlos Alberto Enciso return String; 4593c397c90SCarlos Alberto Enciso } 4603c397c90SCarlos Alberto Enciso 4613c397c90SCarlos Alberto Enciso // Validate the ranges associated with the location. 4623c397c90SCarlos Alberto Enciso bool LVLocation::validateRanges() { 4633c397c90SCarlos Alberto Enciso // Traverse the locations and validate them against the address to line 4643c397c90SCarlos Alberto Enciso // mapping in the current compile unit. Record those invalid ranges. 4653c397c90SCarlos Alberto Enciso // A valid range must meet the following conditions: 4663c397c90SCarlos Alberto Enciso // a) line(lopc) <= line(hipc) 4673c397c90SCarlos Alberto Enciso // b) line(lopc) and line(hipc) are valid. 4683c397c90SCarlos Alberto Enciso 4693c397c90SCarlos Alberto Enciso if (!hasAssociatedRange()) 4703c397c90SCarlos Alberto Enciso return true; 4713c397c90SCarlos Alberto Enciso 4724f06d46fSCarlos Alberto Enciso LVLineRange Range = getReaderCompileUnit()->lineRange(this); 4734f06d46fSCarlos Alberto Enciso LVLine *LowLine = Range.first; 4744f06d46fSCarlos Alberto Enciso LVLine *HighLine = Range.second; 4753c397c90SCarlos Alberto Enciso if (LowLine) 4763c397c90SCarlos Alberto Enciso setLowerLine(LowLine); 4773c397c90SCarlos Alberto Enciso else { 4783c397c90SCarlos Alberto Enciso setIsInvalidLower(); 4793c397c90SCarlos Alberto Enciso return false; 4803c397c90SCarlos Alberto Enciso } 4813c397c90SCarlos Alberto Enciso if (HighLine) 4823c397c90SCarlos Alberto Enciso setUpperLine(HighLine); 4833c397c90SCarlos Alberto Enciso else { 4843c397c90SCarlos Alberto Enciso setIsInvalidUpper(); 4853c397c90SCarlos Alberto Enciso return false; 4863c397c90SCarlos Alberto Enciso } 4873c397c90SCarlos Alberto Enciso // Check for a valid interval. 4883c397c90SCarlos Alberto Enciso if (LowLine->getLineNumber() > HighLine->getLineNumber()) { 4893c397c90SCarlos Alberto Enciso setIsInvalidRange(); 4903c397c90SCarlos Alberto Enciso return false; 4913c397c90SCarlos Alberto Enciso } 4923c397c90SCarlos Alberto Enciso 4933c397c90SCarlos Alberto Enciso return true; 4943c397c90SCarlos Alberto Enciso } 4953c397c90SCarlos Alberto Enciso 4963c397c90SCarlos Alberto Enciso bool LVLocation::calculateCoverage(LVLocations *Locations, unsigned &Factor, 4973c397c90SCarlos Alberto Enciso float &Percentage) { 4983c397c90SCarlos Alberto Enciso if (!options().getAttributeCoverage() && !Locations) 4993c397c90SCarlos Alberto Enciso return false; 5003c397c90SCarlos Alberto Enciso 5013c397c90SCarlos Alberto Enciso // Calculate the coverage depending on the kind of location. We have 5023c397c90SCarlos Alberto Enciso // the simple and composed locations. 5033c397c90SCarlos Alberto Enciso if (Locations->size() == 1) { 5043c397c90SCarlos Alberto Enciso // Simple: fixed address, class offset, stack offset. 5053c397c90SCarlos Alberto Enciso LVLocation *Location = Locations->front(); 5063c397c90SCarlos Alberto Enciso // Some types of locations do not have specific kind. Now is the time 5073c397c90SCarlos Alberto Enciso // to set those types, depending on the operation type. 5083c397c90SCarlos Alberto Enciso Location->updateKind(); 5093c397c90SCarlos Alberto Enciso if (Location->getIsLocationSimple()) { 5103c397c90SCarlos Alberto Enciso Factor = 100; 5113c397c90SCarlos Alberto Enciso Percentage = 100; 5123c397c90SCarlos Alberto Enciso return true; 5133c397c90SCarlos Alberto Enciso } 5143c397c90SCarlos Alberto Enciso } 5153c397c90SCarlos Alberto Enciso 5163c397c90SCarlos Alberto Enciso // Composed locations. 5173c397c90SCarlos Alberto Enciso LVAddress LowerAddress = 0; 5183c397c90SCarlos Alberto Enciso LVAddress UpperAddress = 0; 5193c397c90SCarlos Alberto Enciso for (const LVLocation *Location : *Locations) 5203c397c90SCarlos Alberto Enciso // Do not include locations representing a gap. 5213c397c90SCarlos Alberto Enciso if (!Location->getIsGapEntry()) { 5223c397c90SCarlos Alberto Enciso LowerAddress = Location->getLowerAddress(); 5233c397c90SCarlos Alberto Enciso UpperAddress = Location->getUpperAddress(); 5243c397c90SCarlos Alberto Enciso Factor += (UpperAddress > LowerAddress) ? UpperAddress - LowerAddress 5253c397c90SCarlos Alberto Enciso : LowerAddress - UpperAddress; 5263c397c90SCarlos Alberto Enciso } 5273c397c90SCarlos Alberto Enciso 5283c397c90SCarlos Alberto Enciso Percentage = 0; 5293c397c90SCarlos Alberto Enciso return false; 5303c397c90SCarlos Alberto Enciso } 5313c397c90SCarlos Alberto Enciso 5323c397c90SCarlos Alberto Enciso void LVLocation::printRaw(raw_ostream &OS, bool Full) const { 5333c397c90SCarlos Alberto Enciso // Print the active range (low pc and high pc). 5343c397c90SCarlos Alberto Enciso OS << " [" << hexString(getLowerAddress()) << ":" 5353c397c90SCarlos Alberto Enciso << hexString(getUpperAddress()) << "]\n"; 5363c397c90SCarlos Alberto Enciso // Print any DWARF operations. 5373c397c90SCarlos Alberto Enciso printRawExtra(OS, Full); 5383c397c90SCarlos Alberto Enciso } 5393c397c90SCarlos Alberto Enciso 5403c397c90SCarlos Alberto Enciso void LVLocation::printInterval(raw_ostream &OS, bool Full) const { 5413c397c90SCarlos Alberto Enciso if (hasAssociatedRange()) 5423c397c90SCarlos Alberto Enciso OS << getIntervalInfo(); 5433c397c90SCarlos Alberto Enciso } 5443c397c90SCarlos Alberto Enciso 5453c397c90SCarlos Alberto Enciso void LVLocation::print(raw_ostream &OS, bool Full) const { 5463c397c90SCarlos Alberto Enciso if (getReader().doPrintLocation(this)) { 5473c397c90SCarlos Alberto Enciso LVObject::print(OS, Full); 5483c397c90SCarlos Alberto Enciso printExtra(OS, Full); 5493c397c90SCarlos Alberto Enciso } 5503c397c90SCarlos Alberto Enciso } 5513c397c90SCarlos Alberto Enciso 5523c397c90SCarlos Alberto Enciso void LVLocation::printExtra(raw_ostream &OS, bool Full) const { 5533c397c90SCarlos Alberto Enciso printInterval(OS, Full); 5543c397c90SCarlos Alberto Enciso OS << "\n"; 5553c397c90SCarlos Alberto Enciso } 5563c397c90SCarlos Alberto Enciso 5573c397c90SCarlos Alberto Enciso //===----------------------------------------------------------------------===// 5583c397c90SCarlos Alberto Enciso // DWARF location for a symbol. 5593c397c90SCarlos Alberto Enciso //===----------------------------------------------------------------------===// 5603c397c90SCarlos Alberto Enciso // Add a Location Entry. 5613c397c90SCarlos Alberto Enciso void LVLocationSymbol::addObject(LVAddress LowPC, LVAddress HighPC, 5623c397c90SCarlos Alberto Enciso LVUnsigned SectionOffset, 5633c397c90SCarlos Alberto Enciso uint64_t LocDescOffset) { 5643c397c90SCarlos Alberto Enciso setLowerAddress(LowPC); 5653c397c90SCarlos Alberto Enciso setUpperAddress(HighPC); 5663c397c90SCarlos Alberto Enciso 5673c397c90SCarlos Alberto Enciso // Record the offset where the location information begins. 5683c397c90SCarlos Alberto Enciso setOffset(LocDescOffset ? LocDescOffset : SectionOffset); 5693c397c90SCarlos Alberto Enciso 5703c397c90SCarlos Alberto Enciso // A -1 HighPC value, indicates no range. 5713c397c90SCarlos Alberto Enciso if (HighPC == LVAddress(UINT64_MAX)) 5723c397c90SCarlos Alberto Enciso setIsDiscardedRange(); 5733c397c90SCarlos Alberto Enciso 5743c397c90SCarlos Alberto Enciso // Update the location kind, using the DWARF attribute. 5753c397c90SCarlos Alberto Enciso setKind(); 5763c397c90SCarlos Alberto Enciso } 5773c397c90SCarlos Alberto Enciso 5783c397c90SCarlos Alberto Enciso // Add a Location Record. 5792e6bb8c9SScott Linder void LVLocationSymbol::addObject(LVSmall Opcode, 5802e6bb8c9SScott Linder ArrayRef<LVUnsigned> Operands) { 5813c397c90SCarlos Alberto Enciso if (!Entries) 5827fbcc244SCarlos Alberto Enciso Entries = std::make_unique<LVOperations>(); 5832e6bb8c9SScott Linder Entries->push_back(getReader().createOperation(Opcode, Operands)); 5843c397c90SCarlos Alberto Enciso } 5853c397c90SCarlos Alberto Enciso 5863c397c90SCarlos Alberto Enciso // Based on the DWARF attribute, define the location kind. 5873c397c90SCarlos Alberto Enciso void LVLocation::setKind() { 5883c397c90SCarlos Alberto Enciso switch (getAttr()) { 5893c397c90SCarlos Alberto Enciso case dwarf::DW_AT_data_member_location: 5903c397c90SCarlos Alberto Enciso setIsClassOffset(); 5913c397c90SCarlos Alberto Enciso break; 5923c397c90SCarlos Alberto Enciso case dwarf::DW_AT_location: 5933c397c90SCarlos Alberto Enciso // Depending on the operand, we have a fixed address. 5943c397c90SCarlos Alberto Enciso setIsFixedAddress(); 5953c397c90SCarlos Alberto Enciso break; 5963c397c90SCarlos Alberto Enciso default: 5973c397c90SCarlos Alberto Enciso break; 5983c397c90SCarlos Alberto Enciso } 5993c397c90SCarlos Alberto Enciso // For those symbols with absolute location information, ignore any 6003c397c90SCarlos Alberto Enciso // gaps in their location description; that is the case with absolute 6013c397c90SCarlos Alberto Enciso // memory addresses and members located at specific offsets. 6023c397c90SCarlos Alberto Enciso if (hasAssociatedRange()) 6033c397c90SCarlos Alberto Enciso getParentSymbol()->setFillGaps(); 6043c397c90SCarlos Alberto Enciso } 6053c397c90SCarlos Alberto Enciso 6063c397c90SCarlos Alberto Enciso void LVLocationSymbol::updateKind() { 6073c397c90SCarlos Alberto Enciso // Update the location type for simple ones. 6083c397c90SCarlos Alberto Enciso if (Entries && Entries->size() == 1) { 6097fbcc244SCarlos Alberto Enciso if (dwarf::DW_OP_fbreg == Entries->front()->getOpcode()) 6103c397c90SCarlos Alberto Enciso setIsStackOffset(); 6113c397c90SCarlos Alberto Enciso } 6123c397c90SCarlos Alberto Enciso } 6133c397c90SCarlos Alberto Enciso 6143c397c90SCarlos Alberto Enciso void LVLocationSymbol::printRawExtra(raw_ostream &OS, bool Full) const { 6153c397c90SCarlos Alberto Enciso if (Entries) 6163c397c90SCarlos Alberto Enciso for (const LVOperation *Operation : *Entries) 6173c397c90SCarlos Alberto Enciso Operation->print(OS, Full); 6183c397c90SCarlos Alberto Enciso } 6193c397c90SCarlos Alberto Enciso 6203c397c90SCarlos Alberto Enciso // Print location (formatted version). 6213c397c90SCarlos Alberto Enciso void LVLocation::print(LVLocations *Locations, raw_ostream &OS, bool Full) { 6223c397c90SCarlos Alberto Enciso if (!Locations || Locations->empty()) 6233c397c90SCarlos Alberto Enciso return; 6243c397c90SCarlos Alberto Enciso 6253c397c90SCarlos Alberto Enciso // Print the symbol coverage. 6263c397c90SCarlos Alberto Enciso if (options().getAttributeCoverage()) { 6273c397c90SCarlos Alberto Enciso // The location entries are contained within a symbol. Get a location, 6283c397c90SCarlos Alberto Enciso // to access basic information about indentation, parent, etc. 6293c397c90SCarlos Alberto Enciso LVLocation *Location = Locations->front(); 6303c397c90SCarlos Alberto Enciso LVSymbol *Symbol = Location->getParentSymbol(); 6313c397c90SCarlos Alberto Enciso float Percentage = Symbol->getCoveragePercentage(); 6323c397c90SCarlos Alberto Enciso 6333c397c90SCarlos Alberto Enciso // The coverage is dependent on the kind of location. 6343c397c90SCarlos Alberto Enciso std::string String; 6353c397c90SCarlos Alberto Enciso raw_string_ostream Stream(String); 6363c397c90SCarlos Alberto Enciso Stream << format("%.2f%%", Percentage); 6373c397c90SCarlos Alberto Enciso if (!Location->getIsLocationSimple()) 6383c397c90SCarlos Alberto Enciso Stream << format(" (%d/%d)", Symbol->getCoverageFactor(), 6393c397c90SCarlos Alberto Enciso Symbol->getParentScope()->getCoverageFactor()); 6403c397c90SCarlos Alberto Enciso Symbol->printAttributes(OS, Full, "{Coverage} ", Symbol, StringRef(String), 6413c397c90SCarlos Alberto Enciso /*UseQuotes=*/false, 6423c397c90SCarlos Alberto Enciso /*PrintRef=*/false); 6433c397c90SCarlos Alberto Enciso } 6443c397c90SCarlos Alberto Enciso 6453c397c90SCarlos Alberto Enciso // Print the symbol location, including the missing entries. 6463c397c90SCarlos Alberto Enciso if (getReader().doPrintLocation(/*Location=*/nullptr)) 6473c397c90SCarlos Alberto Enciso for (const LVLocation *Location : *Locations) 6483c397c90SCarlos Alberto Enciso Location->print(OS, Full); 6493c397c90SCarlos Alberto Enciso } 6503c397c90SCarlos Alberto Enciso 6513c397c90SCarlos Alberto Enciso void LVLocationSymbol::printExtra(raw_ostream &OS, bool Full) const { 6523c397c90SCarlos Alberto Enciso OS << "{Location}"; 6533c397c90SCarlos Alberto Enciso if (getIsCallSite()) 6543c397c90SCarlos Alberto Enciso OS << " -> CallSite"; 6553c397c90SCarlos Alberto Enciso printInterval(OS, Full); 6563c397c90SCarlos Alberto Enciso OS << "\n"; 6573c397c90SCarlos Alberto Enciso 6583c397c90SCarlos Alberto Enciso // Print location entries. 6593c397c90SCarlos Alberto Enciso if (Full && Entries) { 6603c397c90SCarlos Alberto Enciso bool CodeViewLocation = getParentSymbol()->getHasCodeViewLocation(); 6613c397c90SCarlos Alberto Enciso std::stringstream Stream; 662282d114cSKazu Hirata std::string Leading; 6633c397c90SCarlos Alberto Enciso for (LVOperation *Operation : *Entries) { 6643c397c90SCarlos Alberto Enciso Stream << Leading 6653c397c90SCarlos Alberto Enciso << (CodeViewLocation ? Operation->getOperandsCodeViewInfo() 6663c397c90SCarlos Alberto Enciso : Operation->getOperandsDWARFInfo()); 6673c397c90SCarlos Alberto Enciso Leading = ", "; 6683c397c90SCarlos Alberto Enciso } 6693c397c90SCarlos Alberto Enciso printAttributes(OS, Full, "{Entry} ", const_cast<LVLocationSymbol *>(this), 6703c397c90SCarlos Alberto Enciso StringRef(Stream.str()), 6713c397c90SCarlos Alberto Enciso /*UseQuotes=*/false, 6723c397c90SCarlos Alberto Enciso /*PrintRef=*/false); 6733c397c90SCarlos Alberto Enciso } 6743c397c90SCarlos Alberto Enciso } 675