Index: lib/DebugInfo/CMakeLists.txt =================================================================== --- lib/DebugInfo/CMakeLists.txt +++ lib/DebugInfo/CMakeLists.txt @@ -12,6 +12,7 @@ DWARFDebugLine.cpp DWARFDebugLoc.cpp DWARFDebugRangeList.cpp + DWARFExpression.cpp DWARFFormValue.cpp DWARFTypeUnit.cpp DWARFUnit.cpp Index: lib/DebugInfo/DWARFContext.h =================================================================== --- lib/DebugInfo/DWARFContext.h +++ lib/DebugInfo/DWARFContext.h @@ -131,13 +131,13 @@ /// Get the compile unit at the specified index for this compile unit. DWARFCompileUnit *getCompileUnitAtIndex(unsigned index) { parseCompileUnits(); - return CUs[index].get(); + return CUs.empty() ? nullptr : CUs[index].get(); } /// Get the compile unit at the specified index for the DWO compile units. DWARFCompileUnit *getDWOCompileUnitAtIndex(unsigned index) { parseDWOCompileUnits(); - return DWOCUs[index].get(); + return DWOCUs.empty() ? nullptr : DWOCUs[index].get(); } /// Get a pointer to the parsed DebugAbbrev object. Index: lib/DebugInfo/DWARFContext.cpp =================================================================== --- lib/DebugInfo/DWARFContext.cpp +++ lib/DebugInfo/DWARFContext.cpp @@ -117,12 +117,18 @@ if (DumpType == DIDT_All || DumpType == DIDT_Loc) { OS << "\n.debug_loc contents:\n"; - getDebugLoc()->dump(OS); + // The compile unit is wrong, but the same dirty trick is used in + // getDebugLoc(). + if (getNumCompileUnits()) + getDebugLoc()->dump(OS, getCompileUnitAtIndex(0)); } if (DumpType == DIDT_All || DumpType == DIDT_LocDwo) { OS << "\n.debug_loc.dwo contents:\n"; - getDebugLocDWO()->dump(OS); + // The compile unit is wrong, but the same dirty trick is used in + // getDebugLoc(). + if (getNumCompileUnits()) + getDebugLocDWO()->dump(OS, getCompileUnitAtIndex(0)); } if (DumpType == DIDT_All || DumpType == DIDT_Frames) { Index: lib/DebugInfo/DWARFDebugInfoEntry.cpp =================================================================== --- lib/DebugInfo/DWARFDebugInfoEntry.cpp +++ lib/DebugInfo/DWARFDebugInfoEntry.cpp @@ -11,6 +11,8 @@ #include "DWARFCompileUnit.h" #include "DWARFContext.h" #include "DWARFDebugAbbrev.h" +#include "DWARFDebugLoc.h" +#include "DWARFExpression.h" #include "llvm/DebugInfo/DWARFFormValue.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/Debug.h" @@ -104,6 +106,38 @@ } } +static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue, + DWARFUnit *U, unsigned Indent) { + if (FormValue.isFormClass(DWARFFormValue::FC_Block) + || FormValue.isFormClass(DWARFFormValue::FC_Exprloc)) { + ArrayRef Expr = *FormValue.getAsBlock(); + DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()), + U->getContext().isLittleEndian(), 0); + PrettyPrintDWARFExpression(OS, U, Data, 0, Expr.size(), false); + return; + } + + FormValue.dump(OS, U); + if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) { + const DWARFSection &LocSection = U->getContext().getLocSection(); + const DWARFSection &LocDWOSection = U->getContext().getLocDWOSection(); + uint32_t Offset = *FormValue.getAsSectionOffset(); + + if (LocSection.Data.size()) { + DWARFDebugLoc DebugLoc(LocSection.Relocs); + DataExtractor Data(LocSection.Data, U->getContext().isLittleEndian(), 0); + DWARFDebugLoc::LocationList LL; + DebugLoc.parseOneLocationList(Data, U->getAddressByteSize(), &Offset, LL); + LL.dump(OS, U, Indent); + } else if (LocDWOSection.Data.size()) { + DataExtractor Data(LocDWOSection.Data, U->getContext().isLittleEndian(), 0); + DWARFDebugLocDWO::LocationList LL; + DWARFDebugLocDWO::parseOneLocationList(Data, &Offset, LL); + LL.dump(OS, U, Indent); + } + } +} + void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS, DWARFUnit *u, uint32_t *offset_ptr, @@ -124,8 +158,8 @@ OS << format(" [DW_FORM_Unknown_%x]", form); DWARFFormValue formValue(form); - - if (!formValue.extractValue(u->getDebugInfoExtractor(), offset_ptr, u)) + DataExtractor Data = u->getDebugInfoExtractor(); + if (!formValue.extractValue(Data, offset_ptr, u)) return; OS << "\t("; @@ -148,6 +182,9 @@ OS << Name; } else if (attr == DW_AT_decl_line || attr == DW_AT_call_line) { OS << *formValue.getAsUnsignedConstant(); + } else if (attr == DW_AT_location || attr == DW_AT_frame_base || + attr == DW_AT_data_member_location) { + dumpLocation(OS, formValue, u, sizeof(BaseIndent)+indent+4); } else { formValue.dump(OS, u); } Index: lib/DebugInfo/DWARFDebugLoc.h =================================================================== --- lib/DebugInfo/DWARFDebugLoc.h +++ lib/DebugInfo/DWARFDebugLoc.h @@ -17,8 +17,10 @@ namespace llvm { class raw_ostream; +class DWARFUnit; class DWARFDebugLoc { +public: /// A single location within a location list. struct Entry { /// The beginning address of the instruction range. @@ -36,8 +38,11 @@ unsigned Offset; /// All the locations in which the variable is stored. SmallVector Entries; + /// + void dump(raw_ostream &OS, const DWARFUnit* Unit, unsigned Indent = 12) const; }; +private: typedef SmallVector LocationLists; /// A list of all the variables in the debug_loc section, each one describing @@ -50,13 +55,17 @@ public: DWARFDebugLoc(const RelocAddrMap &LocRelocMap) : RelocMap(LocRelocMap) {} /// Print the location lists found within the debug_loc section. - void dump(raw_ostream &OS) const; + void dump(raw_ostream &OS, const DWARFUnit *Unit) const; /// Parse the debug_loc section accessible via the 'data' parameter using the /// specified address size to interpret the address ranges. void parse(DataExtractor data, unsigned AddressSize); + + void parseOneLocationList(DataExtractor Data, unsigned AddressSize, + uint32_t *Offset, LocationList &LL); }; class DWARFDebugLocDWO { +public: struct Entry { uint64_t Start; uint32_t Length; @@ -66,15 +75,20 @@ struct LocationList { unsigned Offset; SmallVector Entries; + void dump(raw_ostream &OS, const DWARFUnit *Unit, + unsigned Indent = 12) const; }; +private: typedef SmallVector LocationLists; - LocationLists Locations; public: void parse(DataExtractor data); - void dump(raw_ostream &OS) const; + void dump(raw_ostream &OS, const DWARFUnit *Unit) const; + + static bool parseOneLocationList(DataExtractor Data, uint32_t *Offset, + LocationList &LL); }; } Index: lib/DebugInfo/DWARFDebugLoc.cpp =================================================================== --- lib/DebugInfo/DWARFDebugLoc.cpp +++ lib/DebugInfo/DWARFDebugLoc.cpp @@ -8,30 +8,74 @@ //===----------------------------------------------------------------------===// #include "DWARFDebugLoc.h" +#include "DWARFExpression.h" +#include "DWARFUnit.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Dwarf.h" +#include using namespace llvm; -void DWARFDebugLoc::dump(raw_ostream &OS) const { +void DWARFDebugLoc::LocationList::dump(raw_ostream& OS, const DWARFUnit *Unit, + unsigned Indent) const +{ + for (const Entry &E : Entries) { + OS << '\n'; + OS.indent(Indent); + //FIXME: Use address size + OS << format("0x%016" PRIx64, E.Begin+Unit->getBaseAddress()) << " - " + << format("0x%016" PRIx64, E.End+Unit->getBaseAddress()) << ": "; + + DataExtractor Data(StringRef((const char*)E.Loc.data(), E.Loc.size()), + Unit->getDebugInfoExtractor().isLittleEndian(), + Unit->getAddressByteSize()); + PrettyPrintDWARFExpression(OS, Unit, Data, 0, E.Loc.size(), false); + } +} + +void DWARFDebugLoc::dump(raw_ostream &OS, const DWARFUnit *Unit) const { for (const LocationList &L : Locations) { OS << format("0x%8.8x: ", L.Offset); - const unsigned Indent = 12; - for (const Entry &E : L.Entries) { - if (&E != L.Entries.begin()) - OS.indent(Indent); - OS << "Beginning address offset: " << format("0x%016" PRIx64, E.Begin) - << '\n'; - OS.indent(Indent) << " Ending address offset: " - << format("0x%016" PRIx64, E.End) << '\n'; - OS.indent(Indent) << " Location description: "; - for (unsigned char Loc : E.Loc) { - OS << format("%2.2x ", Loc); - } - OS << "\n\n"; - } + L.dump(OS, Unit); + OS << "\n\n"; + } +} + +void DWARFDebugLoc::parseOneLocationList(DataExtractor Data, unsigned AddressSize, + unsigned *Offset, LocationList &LL) { + LL.Offset = *Offset; + + // 2.6.2 Location Lists + // A location list entry consists of: + while (true) { + Entry E; + RelocAddrMap::const_iterator AI = RelocMap.find(*Offset); + // 1. A beginning address offset. ... + E.Begin = Data.getUnsigned(Offset, AddressSize); + if (AI != RelocMap.end()) + E.Begin += AI->second.second; + + AI = RelocMap.find(*Offset); + // 2. An ending address offset. ... + E.End = Data.getUnsigned(Offset, AddressSize); + if (AI != RelocMap.end()) + E.End += AI->second.second; + + // The end of any given location list is marked by an end of list entry, + // which consists of a 0 for the beginning address offset and a 0 for the + // ending address offset. + if (E.Begin == 0 && E.End == 0) + return; + + unsigned Bytes = Data.getU16(Offset); + // A single location description describing the location of the object... + StringRef str = Data.getData().substr(*Offset, Bytes); + *Offset += Bytes; + E.Loc.reserve(str.size()); + std::copy(str.begin(), str.end(), std::back_inserter(E.Loc)); + LL.Entries.push_back(std::move(E)); } } @@ -39,90 +83,67 @@ uint32_t Offset = 0; while (data.isValidOffset(Offset+AddressSize-1)) { Locations.resize(Locations.size() + 1); - LocationList &Loc = Locations.back(); - Loc.Offset = Offset; - // 2.6.2 Location Lists - // A location list entry consists of: - while (true) { - Entry E; - RelocAddrMap::const_iterator AI = RelocMap.find(Offset); - // 1. A beginning address offset. ... - E.Begin = data.getUnsigned(&Offset, AddressSize); - if (AI != RelocMap.end()) - E.Begin += AI->second.second; - - AI = RelocMap.find(Offset); - // 2. An ending address offset. ... - E.End = data.getUnsigned(&Offset, AddressSize); - if (AI != RelocMap.end()) - E.End += AI->second.second; - - // The end of any given location list is marked by an end of list entry, - // which consists of a 0 for the beginning address offset and a 0 for the - // ending address offset. - if (E.Begin == 0 && E.End == 0) - break; - - unsigned Bytes = data.getU16(&Offset); - // A single location description describing the location of the object... - StringRef str = data.getData().substr(Offset, Bytes); - Offset += Bytes; - E.Loc.reserve(str.size()); - std::copy(str.begin(), str.end(), std::back_inserter(E.Loc)); - Loc.Entries.push_back(std::move(E)); - } + parseOneLocationList(data, AddressSize, &Offset, Locations.back()); } if (data.isValidOffset(Offset)) llvm::errs() << "error: failed to consume entire .debug_loc section\n"; } +bool DWARFDebugLocDWO::parseOneLocationList(DataExtractor Data, unsigned *Offset, + LocationList &LL) { + LL.Offset = *Offset; + + // dwarf::DW_LLE_end_of_list_entry is 0 and indicates the end of the list. + while (auto Kind = static_cast(Data.getU8(Offset))) { + if (Kind != dwarf::DW_LLE_start_length_entry) { + llvm::errs() << "error: dumping support for LLE of kind " << (int)Kind + << " not implemented\n"; + return false; + } + + Entry E; + E.Start = Data.getULEB128(Offset); + E.Length = Data.getU32(Offset); + + unsigned Bytes = Data.getU16(Offset); + // A single location description describing the location of the object... + StringRef str = Data.getData().substr(*Offset, Bytes); + *Offset += Bytes; + E.Loc.resize(str.size()); + std::copy(str.begin(), str.end(), E.Loc.begin()); + + LL.Entries.push_back(std::move(E)); + } + return true; +} + void DWARFDebugLocDWO::parse(DataExtractor data) { uint32_t Offset = 0; while (data.isValidOffset(Offset)) { Locations.resize(Locations.size() + 1); - LocationList &Loc = Locations.back(); - Loc.Offset = Offset; - dwarf::LocationListEntry Kind; - while ((Kind = static_cast( - data.getU8(&Offset))) != dwarf::DW_LLE_end_of_list_entry) { - - if (Kind != dwarf::DW_LLE_start_length_entry) { - llvm::errs() << "error: dumping support for LLE of kind " << (int)Kind - << " not implemented\n"; - return; - } - - Entry E; - - E.Start = data.getULEB128(&Offset); - E.Length = data.getU32(&Offset); - - unsigned Bytes = data.getU16(&Offset); - // A single location description describing the location of the object... - StringRef str = data.getData().substr(Offset, Bytes); - Offset += Bytes; - E.Loc.resize(str.size()); - std::copy(str.begin(), str.end(), E.Loc.begin()); - - Loc.Entries.push_back(std::move(E)); - } + if (!parseOneLocationList(data, &Offset, Locations.back())) + return; + } +} + +void DWARFDebugLocDWO::LocationList::dump(raw_ostream &OS, const DWARFUnit *Unit, + unsigned Indent) const { + for (const Entry &E : Entries) { + OS << '\n'; + OS.indent(Indent); + OS << "Addr idx " << E.Start << " (w/ length " << E.Length << "): "; + DataExtractor Data(StringRef((const char*)E.Loc.data(), E.Loc.size()), + Unit->getDebugInfoExtractor().isLittleEndian(), + Unit->getAddressByteSize()); + PrettyPrintDWARFExpression(OS, Unit, Data, 0, E.Loc.size(), false); } } -void DWARFDebugLocDWO::dump(raw_ostream &OS) const { +void DWARFDebugLocDWO::dump(raw_ostream &OS, const DWARFUnit *Unit) const { for (const LocationList &L : Locations) { OS << format("0x%8.8x: ", L.Offset); - const unsigned Indent = 12; - for (const Entry &E : L.Entries) { - if (&E != L.Entries.begin()) - OS.indent(Indent); - OS << "Beginning address index: " << E.Start << '\n'; - OS.indent(Indent) << " Length: " << E.Length << '\n'; - OS.indent(Indent) << " Location description: "; - for (unsigned char Loc : E.Loc) - OS << format("%2.2x ", Loc); - OS << "\n\n"; - } + L.dump(OS, Unit); + OS << "\n\n"; } } Index: lib/DebugInfo/DWARFExpression.h =================================================================== --- /dev/null +++ lib/DebugInfo/DWARFExpression.h @@ -0,0 +1,27 @@ +//===--- DWARFExpression.h - DWARF Expression handling ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_DWARFEXPRESSION_H +#define LLVM_DEBUGINFO_DWARFEXPRESSION_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/DataExtractor.h" + +namespace llvm { + +class DWARFUnit; +class raw_ostream; + +void PrettyPrintDWARFExpression(raw_ostream& OS, const DWARFUnit *U, + DataExtractor Data, uint64_t Offset, uint64_t Size, + bool isEH); + +} + +#endif Index: lib/DebugInfo/DWARFExpression.cpp =================================================================== --- /dev/null +++ lib/DebugInfo/DWARFExpression.cpp @@ -0,0 +1,320 @@ +//===-- DWARFExpression.cpp -----------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DWARFExpression.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/Format.h" +#include "DWARFCompileUnit.h" +#include "DWARFContext.h" +#include +#include +#include + +using namespace llvm; +using namespace dwarf; + +namespace llvm { +namespace { + +class Op { +public: + /// \brief Size and signedness of expression operands. + /// Size1...Size8 must be encoded as 0...3 as some logic bellow + /// depends on it. + enum Encoding : uint8_t { + Size1 = 0, + Size2 = 1, + Size4 = 2, + Size8 = 3, + SizeLEB = 4, + SizeAddr = 5, + SizeRefAddr = 6, + SizeBlock = 7, ///< Preceding operand contains block size + SignBit = 0x8, + SignedSize1 = SignBit | Size1, + SignedSize2 = SignBit | Size2, + SignedSize4 = SignBit | Size4, + SignedSize8 = SignBit | Size8, + SignedSizeLEB = SignBit | SizeLEB, + SizeNA = 0xFF ///< Unused operands get this encoding. + }; + + enum DwarfVersion : uint8_t { + DwarfNA, ///< Serves as a marker for unused entries + Dwarf2 = 2, + Dwarf3, + Dwarf4 + }; + + /// \brief A description struct contains the information about how + /// to decode an expression Op. + struct Description { + DwarfVersion Version; + Encoding Op1; + Encoding Op2; + + Description() : Version(DwarfNA), Op1(SizeNA), Op2(SizeNA) {} + + Description(DwarfVersion Version, Encoding Op1, Encoding Op2) + : Version(Version), Op1(Op1), Op2(Op2) {} + }; + + class DescriptionArray { + std::vector Descriptions; + + void addOp(uint16_t LocationAtom, DwarfVersion Version, + Encoding Op1 = SizeNA, Encoding Op2 = SizeNA) { + if (LocationAtom >= Descriptions.size()) + Descriptions.resize(LocationAtom + 1); + Descriptions[LocationAtom] = Description(Version, Op1, Op2); + } + + public: + DescriptionArray(); + + Description operator[](uint8_t Opcode) const { + if (Opcode >= Descriptions.size()) + return Op::Description(); + + return Descriptions[Opcode]; + } + }; +}; + +Op::DescriptionArray::DescriptionArray() { + addOp(DW_OP_addr, Dwarf2, SizeAddr); + addOp(DW_OP_deref, Dwarf2); + addOp(DW_OP_const1u, Dwarf2, Size1); + addOp(DW_OP_const1s, Dwarf2, SignedSize1); + addOp(DW_OP_const2u, Dwarf2, Size2); + addOp(DW_OP_const2s, Dwarf2, SignedSize2); + addOp(DW_OP_const4u, Dwarf2, Size4); + addOp(DW_OP_const4s, Dwarf2, SignedSize4); + addOp(DW_OP_const8u, Dwarf2, Size8); + addOp(DW_OP_const8s, Dwarf2, SignedSize8); + addOp(DW_OP_constu, Dwarf2, SizeLEB); + addOp(DW_OP_consts, Dwarf2, SignedSizeLEB); + addOp(DW_OP_dup, Dwarf2); + addOp(DW_OP_drop, Dwarf2); + addOp(DW_OP_over, Dwarf2); + addOp(DW_OP_pick, Dwarf2, Size1); + addOp(DW_OP_swap, Dwarf2); + addOp(DW_OP_rot, Dwarf2); + addOp(DW_OP_xderef, Dwarf2); + addOp(DW_OP_abs, Dwarf2); + addOp(DW_OP_and, Dwarf2); + addOp(DW_OP_div, Dwarf2); + addOp(DW_OP_minus, Dwarf2); + addOp(DW_OP_mod, Dwarf2); + addOp(DW_OP_mul, Dwarf2); + addOp(DW_OP_neg, Dwarf2); + addOp(DW_OP_not, Dwarf2); + addOp(DW_OP_or, Dwarf2); + addOp(DW_OP_plus, Dwarf2); + addOp(DW_OP_plus_uconst, Dwarf2, SizeLEB); + addOp(DW_OP_shl, Dwarf2); + addOp(DW_OP_shr, Dwarf2); + addOp(DW_OP_shra, Dwarf2); + addOp(DW_OP_xor, Dwarf2); + addOp(DW_OP_skip, Dwarf2, SignedSize2); + addOp(DW_OP_bra, Dwarf2, SignedSize2); + addOp(DW_OP_eq, Dwarf2); + addOp(DW_OP_ge, Dwarf2); + addOp(DW_OP_gt, Dwarf2); + addOp(DW_OP_le, Dwarf2); + addOp(DW_OP_lt, Dwarf2); + addOp(DW_OP_ne, Dwarf2); + for (uint16_t LA = DW_OP_lit0; LA <= DW_OP_lit31; ++LA) + addOp(LA, Dwarf2); + for (uint16_t LA = DW_OP_reg0; LA <= DW_OP_reg31; ++LA) + addOp(LA, Dwarf2); + for (uint16_t LA = DW_OP_breg0; LA <= DW_OP_breg31; ++LA) + addOp(LA, Dwarf2, SignedSizeLEB); + addOp(DW_OP_regx, Dwarf2, SizeLEB); + addOp(DW_OP_fbreg, Dwarf2, SignedSizeLEB); + addOp(DW_OP_bregx, Dwarf2, SizeLEB, SignedSizeLEB); + addOp(DW_OP_piece, Dwarf2, SizeLEB); + addOp(DW_OP_deref_size, Dwarf2, Size1); + addOp(DW_OP_xderef_size, Dwarf2, Size1); + addOp(DW_OP_nop, Dwarf2); + addOp(DW_OP_push_object_address, Dwarf3); + addOp(DW_OP_call2, Dwarf3, Size2); + addOp(DW_OP_call4, Dwarf3, Size4); + addOp(DW_OP_call_ref, Dwarf3, SizeRefAddr); + addOp(DW_OP_form_tls_address, Dwarf3); + addOp(DW_OP_call_frame_cfa, Dwarf3); + addOp(DW_OP_bit_piece, Dwarf3, SizeLEB, SizeLEB); + addOp(DW_OP_implicit_value, Dwarf3, SizeLEB, SizeBlock); + addOp(DW_OP_stack_value, Dwarf3); + addOp(DW_OP_GNU_push_tls_address, Dwarf3); + addOp(DW_OP_GNU_addr_index, Dwarf4, SizeLEB); + addOp(DW_OP_GNU_const_index, Dwarf4, SizeLEB); +} +} + +static const Op::DescriptionArray ExpressionOps; + +static uint8_t getRefAddrSize(uint8_t AddrSize, uint16_t Version) { + return (Version == 2) ? AddrSize : 4; +} + +static bool prettyPrintOp(raw_ostream &OS, DataExtractor Data, uint32_t *Offset, + const DWARFUnit &Unit, bool isEH); + +void PrettyPrintDWARFExpression(raw_ostream &OS, const DWARFUnit *Unit, + DataExtractor Data, uint64_t Where, + uint64_t Size, bool isEH) { + uint32_t Offset = Where; + + if (Size) + if (prettyPrintOp(OS, Data, &Offset, *Unit, isEH)) + while (Offset < Where + Size) { + OS << ", "; + if (!prettyPrintOp(OS, Data, &Offset, *Unit, isEH)) + break; + } + + if (Offset < Where + Size) { + OS << " decoding failed: "; + while (Offset < Where + Size) + OS << format("%02x ", Data.getU8(&Offset)); + } else if (Offset > Where + Size) + OS << " storage overflow!"; +} + +static bool prettyPrintRegisterExpression(raw_ostream &OS, uint8_t Opcode, + uint32_t *Offset, DataExtractor Data, + const MCRegisterInfo *MRI, bool isEH) { + uint64_t DwarfRegNum; + uint32_t StartOffset = *Offset; + + OS << OperationEncodingString(Opcode) + 3 << ' '; + + if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx) + DwarfRegNum = Data.getULEB128(Offset); + else if (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx) + DwarfRegNum = Opcode - DW_OP_breg0; + else + DwarfRegNum = Opcode - DW_OP_reg0; + + int LLVMRegNum = MRI->tryGetLLVMRegNum(DwarfRegNum, isEH); + if (LLVMRegNum >= 0) + if (const char *RegName = MRI->getName(LLVMRegNum)) { + if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) || + Opcode == DW_OP_bregx) + OS << format("%s%+" PRId64, RegName, Data.getSLEB128(Offset)); + else + OS << RegName; + return true; + } + + *Offset = StartOffset; + return false; +} + +static bool prettyPrintOp(raw_ostream &OS, DataExtractor Data, uint32_t *Offset, + const DWARFUnit &Unit, bool isEH) { + uint8_t Opcode = Data.getU8(Offset); + const DWARFContext &DC = Unit.getContext(); + + if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) || + (Opcode >= DW_OP_reg0 && Opcode <= DW_OP_reg31) || + Opcode == DW_OP_bregx || Opcode == DW_OP_regx) + if (const MCRegisterInfo *MRI = DC.getTargetRegisterInfo()) + if (prettyPrintRegisterExpression(OS, Opcode, Offset, Data, MRI, isEH)) + return true; + + Op::Description OpDesc = ExpressionOps[Opcode]; + + // This indicates an uninitialized entry in the Op table. + if (OpDesc.Version == Op::DwarfNA) { + OS << format("OP_unknown_<%02x>", Opcode); + return false; + } + + const char *Name = OperationEncodingString(Opcode); + assert(Name && "DW_OP has no name!"); + OS << Name + 3; + + // Declare Val out of the loop so that it lives inbetween iteration + // for block support. + uint64_t Val; + for (unsigned Operand = 0; Operand < 2; ++Operand) { + unsigned Size = Operand ? OpDesc.Op2 : OpDesc.Op1; + unsigned Signed = Size & Op::SignBit; + + if (Size == Op::SizeNA) + break; + + switch (Size & ~Op::SignBit) { + case Op::Size1: + Val = (int8_t)Data.getU8(Offset); + break; + case Op::Size2: + Val = (int16_t)Data.getU16(Offset); + break; + case Op::Size4: + Val = (int32_t)Data.getU32(Offset); + break; + case Op::Size8: + Val = Data.getU64(Offset); + break; + case Op::SizeAddr: + if (Unit.getAddressByteSize() == 8) { + Val = Data.getU64(Offset); + Size = Op::Size8; + } else { + assert(Unit.getAddressByteSize() == 4); + Val = Data.getU32(Offset); + Size = Op::Size4; + } + break; + case Op::SizeRefAddr: + if (getRefAddrSize(Unit.getAddressByteSize(), Unit.getVersion()) == 8) { + Val = Data.getU64(Offset); + Size = Op::Size8; + } else { + assert(getRefAddrSize(Unit.getAddressByteSize(), Unit.getVersion()) == 4); + Val = Data.getU32(Offset); + Size = Op::Size4; + } + break; + case Op::SizeLEB: + if (Signed) + Val = Data.getSLEB128(Offset); + else { + Val = Data.getULEB128(Offset); + Size = (Val <= UINT32_MAX) ? Op::Size4 : Op::Size8; + } + break; + case Op::SizeBlock: + assert(Operand > 0 && "Op::SizeBlock is not possible as first operand."); + break; + default: + assert(0 && "Unknown DWARFExpression Op size"); + } + + if (Size == Op::SizeBlock) + for (unsigned i = 0; i < Val; ++i) + OS << format(" 0x%02x", Data.getU8(Offset)); + else { + const uint64_t Mask[] = {0xFF, 0xFFFF, 0xFFFFFFFF, 0xFFFFFFFFFFFFFFFFULL}; + if (Signed) + OS << format(" %+" PRId64, (int64_t)Val); + else { + assert(Size < array_lengthof(Mask) && "Invalid Op size."); + OS << format(" 0x%0*" PRIx64, (1 << Size) * 2, Val & Mask[Size]); + } + } + } + + return true; +} + +} // namespace llvm Index: test/CodeGen/ARM/2011-01-19-MergedGlobalDbg.ll =================================================================== --- test/CodeGen/ARM/2011-01-19-MergedGlobalDbg.ll +++ test/CodeGen/ARM/2011-01-19-MergedGlobalDbg.ll @@ -21,12 +21,12 @@ ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name {{.*}} "x1" ; CHECK-NOT: {{DW_TAG|NULL}} -; CHECK: DW_AT_location [DW_FORM_exprloc] (<0x8> 03 [[ADDR:.. .. .. ..]] 10 00 22 ) +; CHECK: DW_AT_location [DW_FORM_exprloc] (OP_addr [[ADDR:0x[0-9a-f]*]], OP_constu 0x00000000, OP_plus) ; CHECK: DW_TAG_variable ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name {{.*}} "x2" ; CHECK-NOT: {{DW_TAG|NULL}} -; CHECK: DW_AT_location [DW_FORM_exprloc] (<0x8> 03 [[ADDR]] 10 01 22 ) +; CHECK: DW_AT_location [DW_FORM_exprloc] (OP_addr [[ADDR]], OP_constu 0x00000001, OP_plus) define zeroext i8 @get1(i8 zeroext %a) nounwind optsize { entry: Index: test/CodeGen/ARM/2011-08-02-MergedGlobalDbg.ll =================================================================== --- test/CodeGen/ARM/2011-08-02-MergedGlobalDbg.ll +++ test/CodeGen/ARM/2011-08-02-MergedGlobalDbg.ll @@ -12,12 +12,13 @@ ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name {{.*}} "x1" ; CHECK-NOT: {{DW_TAG|NULL}} -; CHECK: DW_AT_location [DW_FORM_exprloc] (<0x8> 03 [[ADDR:.. .. .. ..]] 10 00 22 ) +; (OP_reg0 R0) +; CHECK: DW_AT_location [DW_FORM_exprloc] (OP_addr [[ADDR:0x[0-9a-f]*]], OP_constu 0x00000000, OP_plus) ; CHECK: DW_TAG_variable ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name {{.*}} "x2" ; CHECK-NOT: {{DW_TAG|NULL}} -; CHECK: DW_AT_location [DW_FORM_exprloc] (<0x8> 03 [[ADDR]] 10 04 22 ) +; CHECK: DW_AT_location [DW_FORM_exprloc] (OP_addr [[ADDR]], OP_constu 0x00000004, OP_plus) target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32" target triple = "thumbv7-apple-macosx10.7.0" Index: test/CodeGen/ARM/debug-info-sreg2.ll =================================================================== --- test/CodeGen/ARM/debug-info-sreg2.ll +++ test/CodeGen/ARM/debug-info-sreg2.ll @@ -5,12 +5,10 @@ ; Just making sure the first part of the location isn't a repetition ; of the size of the location description. -; -; 0x90 DW_OP_regx of super-register -; CHECK: 0x00000000: Beginning address offset: -; CHECK-NEXT: Ending address offset: -; CHECK-NEXT: Location description: 90 {{.. .. .. .. $}} +; CHECK: 0x00000000: +; CHECK-NEXT: 0x{{[0-9]*[a-f]*}} - 0x{{[0-9]*[a-f]*}}: OP_regx D8 + define void @_Z3foov() optsize ssp { entry: Index: test/CodeGen/X86/2011-01-24-DbgValue-Before-Use.ll =================================================================== --- test/CodeGen/X86/2011-01-24-DbgValue-Before-Use.ll +++ test/CodeGen/X86/2011-01-24-DbgValue-Before-Use.ll @@ -9,7 +9,8 @@ ; CHECK: DW_TAG_variable ; CHECK: DW_TAG_variable ; CHECK-NEXT: DW_AT_location -; CHECK-NEXT: DW_AT_name {{.*}} "z_s" +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "z_s" ; CHECK-NEXT: DW_AT_decl_file ; CHECK-NEXT: DW_AT_decl_line ; CHECK-NEXT: DW_AT_type{{.*}}{[[TYPE:.*]]} Index: test/DebugInfo/AArch64/coalescing.ll =================================================================== --- test/DebugInfo/AArch64/coalescing.ll +++ test/DebugInfo/AArch64/coalescing.ll @@ -23,9 +23,8 @@ ; CHECK: .debug_info contents: ; CHECK: DW_TAG_variable ; CHECK-NEXT: DW_AT_location + ; CHECK-NEXT: OP_breg0 W0+0) ; CHECK-NEXT: DW_AT_name {{.*}}"size" - ; CHECK: .debug_loc contents: - ; CHECK: Location description: 70 00 ret void, !dbg !18 } Index: test/DebugInfo/ARM/s-super-register.ll =================================================================== --- test/DebugInfo/ARM/s-super-register.ll +++ test/DebugInfo/ARM/s-super-register.ll @@ -7,7 +7,7 @@ ; 0x90 DW_OP_regx of super-register ; 0x93 DW_OP_piece ; 0x9d DW_OP_bit_piece -; CHECK: Location description: 90 {{.. .. ((93 ..)|(9d .. ..)) $}} +; CHECK: OP_regx D8, OP{{_bit_|_}}piece define void @_Z3foov() optsize ssp { entry: Index: test/DebugInfo/SystemZ/variable-loc.ll =================================================================== --- test/DebugInfo/SystemZ/variable-loc.ll +++ test/DebugInfo/SystemZ/variable-loc.ll @@ -14,9 +14,8 @@ ; CHECK: brasl %r14, populate_array@PLT ; DEBUG: DW_TAG_variable -; Rather hard-coded, but 0x91 => DW_OP_fbreg and 0xa401 is SLEB128 encoded 164. ; DEBUG-NOT: DW_TAG -; DEBUG: DW_AT_location {{.*}}(<0x3> 91 a4 01 ) +; DEBUG: DW_AT_location {{.*}}(OP_fbreg +164) ; DEBUG-NOT: DW_TAG ; DEBUG: DW_AT_name {{.*}} "main_arr" Index: test/DebugInfo/X86/DW_AT_location-reference.ll =================================================================== --- test/DebugInfo/X86/DW_AT_location-reference.ll +++ test/DebugInfo/X86/DW_AT_location-reference.ll @@ -31,22 +31,18 @@ ; // The 'x' variable and its symbol reference location ; CHECK: .debug_info contents: ; CHECK: DW_TAG_variable -; CHECK-NEXT: DW_AT_location [DW_FORM_sec_offset] (0x00000000) +; CHECK-NEXT: DW_AT_location [DW_FORM_sec_offset] (0x00000000 +; Check that the location contains only 4 ranges - this verifies that the 4th +; and 5th ranges were successfully merged into a single range. +; CHECK-NEXT: 0x{{[0-9a-f]*}} - 0x{{[0-9a-f]*}}: +; CHECK-NEXT: 0x{{[0-9a-f]*}} - 0x{{[0-9a-f]*}}: +; CHECK-NEXT: 0x{{[0-9a-f]*}} - 0x{{[0-9a-f]*}}: +; CHECK-NEXT: 0x{{[0-9a-f]*}} - 0x{{[0-9a-f]*}}: {{.*}}) ; CHECK-NEXT: DW_AT_name {{.*}} "x" ; CHECK-NEXT: DW_AT_decl_file ; CHECK-NEXT: DW_AT_decl_line ; CHECK-NEXT: DW_AT_type -; Check that the location contains only 4 ranges - this verifies that the 4th -; and 5th ranges were successfully merged into a single range. -; CHECK: .debug_loc contents: -; CHECK: 0x00000000: -; CHECK: Beginning address offset: -; CHECK: Beginning address offset: -; CHECK: Beginning address offset: -; CHECK: Beginning address offset: -; CHECK-NOT: Beginning address offset: - ; Check that we have no relocations in Darwin's output. ; DARWIN-NOT: X86_64_RELOC{{.*}} __debug_loc Index: test/DebugInfo/X86/block-capture.ll =================================================================== --- test/DebugInfo/X86/block-capture.ll +++ test/DebugInfo/X86/block-capture.ll @@ -4,8 +4,7 @@ ; Checks that we emit debug info for the block variable declare. ; CHECK: DW_TAG_subprogram ; CHECK: DW_TAG_variable -; fbreg +8, deref, +32 -; CHECK-NEXT: DW_AT_location [DW_FORM_block1] (<0x05> 91 08 06 23 20 ) +; CHECK-NEXT: DW_AT_location [DW_FORM_block1] (OP_fbreg +8, OP_deref, OP_plus_uconst 0x00000020) ; CHECK-NEXT: DW_AT_name {{.*}} "block" ; Extracted from the clang output for: Index: test/DebugInfo/X86/data_member_location.ll =================================================================== --- test/DebugInfo/X86/data_member_location.ll +++ test/DebugInfo/X86/data_member_location.ll @@ -20,11 +20,11 @@ ; DWARF2: DW_AT_name {{.*}} "c" ; DWARF2-NOT: DW_TAG -; DWARF2: DW_AT_data_member_location {{.*}} (<0x02> 23 00 ) +; DWARF2: DW_AT_data_member_location {{.*}} (OP_plus_uconst 0x00000000) ; DWARF2: DW_AT_name {{.*}} "i" ; DWARF2-NOT: DW_TAG -; DWARF2: DW_AT_data_member_location {{.*}} (<0x02> 23 04 ) +; DWARF2: DW_AT_data_member_location {{.*}} (OP_plus_uconst 0x00000004) %struct.foo = type { i8, i32 } Index: test/DebugInfo/X86/dbg-merge-loc-entry.ll =================================================================== --- test/DebugInfo/X86/dbg-merge-loc-entry.ll +++ test/DebugInfo/X86/dbg-merge-loc-entry.ll @@ -6,7 +6,7 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" target triple = "x86_64-apple-darwin8" -;CHECK: DW_AT_location{{.*}}(<0x1> 55 ) +;CHECK: DW_AT_location{{.*}}(OP_reg5 RDI) %0 = type { i64, i1 } Index: test/DebugInfo/X86/dbg-value-const-byref.ll =================================================================== --- test/DebugInfo/X86/dbg-value-const-byref.ll +++ test/DebugInfo/X86/dbg-value-const-byref.ll @@ -21,28 +21,14 @@ ; CHECK: .debug_info contents: ; CHECK: DW_TAG_variable ; CHECK-NOT: DW_TAG -; CHECK: DW_AT_location [DW_FORM_data4] ([[LOC:.*]]) +; CHECK: DW_AT_location [DW_FORM_data4] ( +; CHECK-NEXT: 0x0000000000000001 - 0x000000000000000b: OP_consts +3 +; CHECK-NEXT: 0x000000000000000b - 0x0000000000000012: OP_consts +7 +; CHECK-NEXT: 0x0000000000000012 - 0x000000000000001b: OP_reg0 RAX, OP_piece 0x00000004 +; CHECK-NEXT: 0x000000000000001b - 0x0000000000000024: OP_breg5 RDI+0) ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name{{.*}}"i" -; CHECK: .debug_loc contents: -; CHECK: [[LOC]]: -; consts 0x00000003 -; CHECK: Beginning address offset: 0x0000000000000{{.*}} -; CHECK: Ending address offset: [[C1:.*]] -; CHECK: Location description: 11 03 -; consts 0x00000007 -; CHECK: Beginning address offset: [[C1]] -; CHECK: Ending address offset: [[C2:.*]] -; CHECK: Location description: 11 07 -; rax, piece 0x00000004 -; CHECK: Beginning address offset: [[C2]] -; CHECK: Ending address offset: [[R1:.*]] -; CHECK: Location description: 50 93 04 -; rdi+0 -; CHECK: Beginning address offset: [[R1]] -; CHECK: Ending address offset: [[R2:.*]] -; CHECK: Location description: 75 00 -; + target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.9.0" Index: test/DebugInfo/X86/debug-info-blocks.ll =================================================================== --- test/DebugInfo/X86/debug-info-blocks.ll +++ test/DebugInfo/X86/debug-info-blocks.ll @@ -27,10 +27,7 @@ ; CHECK-NOT: {{DW_TAG|NULL}} ; CHECK: DW_TAG_variable ; CHECK-NOT: DW_TAG -; 0x06 = DW_OP_deref -; 0x23 = DW_OP_uconst -; 0x91 = DW_OP_fbreg -; CHECK: DW_AT_location{{.*}}91 {{[0-9]+}} 06 23 {{[0-9]+}} ) +; CHECK: DW_AT_location{{.*}}(OP_fbreg -24, OP_deref, OP_plus_uconst 0x00000020) ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name{{.*}}"self" ; CHECK-NOT: DW_TAG Index: test/DebugInfo/X86/debug-loc-offset.ll =================================================================== --- test/DebugInfo/X86/debug-loc-offset.ll +++ test/DebugInfo/X86/debug-loc-offset.ll @@ -45,7 +45,9 @@ ; CHECK-NOT: {{DW_TAG|NULL}} ; CHECK: DW_TAG_formal_parameter ; CHECK-NOT: DW_TAG -; CHECK: DW_AT_location [DW_FORM_sec_offset] (0x00000000) +; CHECK: DW_AT_location [DW_FORM_sec_offset] (0x00000000 +; do not check the location stored here, as it will be offseted by the +; compile unit's low_pc. The real check is below in the debug_loc section. ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name [DW_FORM_strp]{{.*}}"a" @@ -54,8 +56,8 @@ ; CHECK-NOT: DW_AT_location ; CHECK: .debug_loc contents: -; CHECK: 0x00000000: Beginning address offset: 0x0000000000000000 -; CHECK: Ending address offset: 0x000000000000001a +; CHECK: 0x00000000: +; CHECK-NEXT: 0x0000000000000000 - 0x000000000000001a %struct.A = type { i32 (...)**, i32 } Index: test/DebugInfo/X86/fission-cu.ll =================================================================== --- test/DebugInfo/X86/fission-cu.ll +++ test/DebugInfo/X86/fission-cu.ll @@ -77,7 +77,7 @@ ; CHECK: DW_AT_external [DW_FORM_flag_present] (true) ; CHECK: DW_AT_decl_file [DW_FORM_data1] (0x01) ; CHECK: DW_AT_decl_line [DW_FORM_data1] (1) -; CHECK: DW_AT_location [DW_FORM_exprloc] (<0x2> fb 00 ) +; CHECK: DW_AT_location [DW_FORM_exprloc] (OP_GNU_addr_index 0x00000000) ; CHECK: [[TYPE]]: DW_TAG_base_type ; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000003) string = "int") Index: test/DebugInfo/X86/fission-ranges.ll =================================================================== --- test/DebugInfo/X86/fission-ranges.ll +++ test/DebugInfo/X86/fission-ranges.ll @@ -10,37 +10,23 @@ ; CHECK-NEXT: DW_AT_GNU_dwo_id ; CHECK-NEXT: DW_AT_GNU_addr_base [DW_FORM_sec_offset] (0x00000000) - +; Don't assume these locations are entirely correct - feel free to update them +; if they've changed due to a bugfix, change in register allocation, etc. ; CHECK: .debug_info.dwo contents: -; CHECK: DW_AT_location [DW_FORM_sec_offset] ([[A:0x[0-9a-z]*]]) -; CHECK: DW_AT_location [DW_FORM_sec_offset] ([[E:0x[0-9a-z]*]]) -; CHECK: DW_AT_location [DW_FORM_sec_offset] ([[B:0x[0-9a-z]*]]) -; CHECK: DW_AT_location [DW_FORM_sec_offset] ([[D:0x[0-9a-z]*]]) +; CHECK: DW_AT_location [DW_FORM_sec_offset] ([[A:0x[0-9a-z]*]] +; CHECK-NEXT: Addr idx 2 (w/ length 190): OP_consts +0, OP_stack_value +; CHECK-NEXT: Addr idx 3 (w/ length 23): OP_reg0 RAX, OP_piece 0x00000004) +; CHECK: DW_AT_location [DW_FORM_sec_offset] ([[E:0x[0-9a-z]*]] +; CHECK-NEXT: Addr idx 4 (w/ length 21): OP_reg0 RAX, OP_piece 0x00000004) +; CHECK: DW_AT_location [DW_FORM_sec_offset] ([[B:0x[0-9a-z]*]] +; CHECK-NEXT: Addr idx 5 (w/ length 19): OP_reg0 RAX, OP_piece 0x00000004) +; CHECK: DW_AT_location [DW_FORM_sec_offset] ([[D:0x[0-9a-z]*]] +; CHECK-NEXT: Addr idx 6 (w/ length 23): OP_reg0 RAX, OP_piece 0x00000004) ; CHECK: DW_AT_ranges [DW_FORM_sec_offset] (0x00000000 ; CHECK: .debug_loc contents: ; CHECK-NOT: Beginning address offset ; CHECK: .debug_loc.dwo contents: -; Don't assume these locations are entirely correct - feel free to update them -; if they've changed due to a bugfix, change in register allocation, etc. - -; CHECK: [[A]]: Beginning address index: 2 -; CHECK-NEXT: Length: 190 -; CHECK-NEXT: Location description: 11 00 -; CHECK-NEXT: {{^$}} -; CHECK-NEXT: Beginning address index: 3 -; CHECK-NEXT: Length: 23 -; CHECK-NEXT: Location description: 50 93 04 -; CHECK: [[E]]: Beginning address index: 4 -; CHECK-NEXT: Length: 21 -; CHECK-NEXT: Location description: 50 93 04 -; CHECK: [[B]]: Beginning address index: 5 -; CHECK-NEXT: Length: 19 -; CHECK-NEXT: Location description: 50 93 04 -; CHECK: [[D]]: Beginning address index: 6 -; CHECK-NEXT: Length: 23 -; CHECK-NEXT: Location description: 50 93 04 - ; Make sure we don't produce any relocations in any .dwo section (though in particular, debug_info.dwo) ; HDR-NOT: .rela.{{.*}}.dwo Index: test/DebugInfo/X86/op_deref.ll =================================================================== --- test/DebugInfo/X86/op_deref.ll +++ test/DebugInfo/X86/op_deref.ll @@ -7,22 +7,16 @@ ; FIXME: The location here needs to be fixed, but llvm-dwarfdump doesn't handle ; DW_AT_location lists yet. -; DWARF4: DW_AT_location [DW_FORM_sec_offset] (0x00000000) +; DWARF4: DW_AT_location [DW_FORM_sec_offset] (0x00000000 ; FIXME: The location here needs to be fixed, but llvm-dwarfdump doesn't handle ; DW_AT_location lists yet. -; DWARF3: DW_AT_location [DW_FORM_data4] (0x00000000) +; DWARF3: DW_AT_location [DW_FORM_data4] (0x00000000 +; CHECK-NEXT: OP_breg2 RCX+0 ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000067] = "vla") -; Unfortunately llvm-dwarfdump can't unparse a list of DW_AT_locations -; right now, so we check the asm output: -; RUN: llc -O0 -mtriple=x86_64-apple-darwin %s -o - -filetype=asm | FileCheck %s -check-prefix=ASM-CHECK -; vla should have a register-indirect address at one point. -; ASM-CHECK: DEBUG_VALUE: vla <- RCX -; ASM-CHECK: DW_OP_breg2 - ; RUN: llvm-as %s -o - | llvm-dis - | FileCheck %s --check-prefix=PRETTY-PRINT ; PRETTY-PRINT: [ DW_TAG_expression ] [DW_OP_deref] Index: test/DebugInfo/X86/parameters.ll =================================================================== --- test/DebugInfo/X86/parameters.ll +++ test/DebugInfo/X86/parameters.ll @@ -23,19 +23,16 @@ ; } ; CHECK: debug_info contents -; 0x74 is DW_OP_breg4, showing that the parameter is accessed indirectly +; DW_OP_breg4 shows that the parameter is accessed indirectly ; (with a zero offset) from the register parameter -; CHECK: DW_AT_location{{.*}}(<0x0{{.}}> 74 00 +; CHECK: DW_AT_location{{.*}}(OP_breg4 RSI+0) ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name{{.*}} = "f" -; CHECK: DW_AT_location{{.*}}([[G_LOC:0x[0-9]*]]) +; CHECK: DW_AT_location{{.*}}(0x00000000 +; CHECK-NEXT: OP_breg4 RSI+0 ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name{{.*}} = "g" -; CHECK: debug_loc contents -; CHECK-NEXT: [[G_LOC]]: Beginning -; CHECK-NEXT: Ending -; CHECK-NEXT: Location description: 74 00 %"struct.pr14763::foo" = type { i8 } Index: test/DebugInfo/X86/pieces-1.ll =================================================================== --- test/DebugInfo/X86/pieces-1.ll +++ test/DebugInfo/X86/pieces-1.ll @@ -17,14 +17,9 @@ ; CHECK: .debug_loc contents: ; -; 0x0000000000000000 - 0x0000000000000006: rdi, piece 0x00000008, rsi, piece 0x00000004 -; CHECK: Beginning address offset: 0x0000000000000000 -; CHECK: Ending address offset: [[LTMP3:.*]] -; CHECK: Location description: 55 93 08 54 93 04 +; CHECK: 0x0000000000000000 - [[LTMP3:.*]]: OP_reg5 RDI, OP_piece 0x00000008, OP_reg4 RSI, OP_piece 0x00000004 ; 0x0000000000000006 - 0x0000000000000008: rbp-8, piece 0x00000008, rax, piece 0x00000004 ) -; CHECK: Beginning address offset: [[LTMP3]] -; CHECK: Ending address offset: [[END:.*]] -; CHECK: Location description: 76 78 93 08 54 93 04 +; CHECK: [[LTMP3]] - {{.*}}: OP_breg6 RBP-8, OP_piece 0x00000008, OP_reg4 RSI, OP_piece 0x00000004 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.9.0" Index: test/DebugInfo/X86/pieces-2.ll =================================================================== --- test/DebugInfo/X86/pieces-2.ll +++ test/DebugInfo/X86/pieces-2.ll @@ -17,8 +17,7 @@ ; ; ; CHECK: DW_TAG_variable [4] -; rax, piece 0x00000004 -; CHECK-NEXT: DW_AT_location [DW_FORM_block1]{{.*}}50 93 04 +; CHECK-NEXT: DW_AT_location [DW_FORM_block1]{{.*}} (OP_reg0 RAX, OP_piece 0x00000004 ; CHECK-NEXT: DW_AT_name {{.*}}"i1" ; ; ModuleID = '/Volumes/Data/llvm/test/DebugInfo/X86/sroasplit-1.ll' Index: test/DebugInfo/X86/pieces-3.ll =================================================================== --- test/DebugInfo/X86/pieces-3.ll +++ test/DebugInfo/X86/pieces-3.ll @@ -16,20 +16,14 @@ ; } ; ; CHECK: DW_TAG_formal_parameter [3] -; CHECK-NEXT: DW_AT_location [DW_FORM_data4] ([[LOC:.*]]) +; CHECK-NEXT: DW_AT_location [DW_FORM_data4] ( +; CHECK-NEXT: 0x0000000000000000 - 0x0000000000000004: OP_reg5 RDI, OP_piece 0x00000008, OP_piece 0x00000004, OP_reg4 RSI, OP_piece 0x00000004 +; CHECK-NEXT: 0x0000000000000004 - 0x0000000000000008: OP_reg5 RDI, OP_piece 0x00000008, OP_piece 0x00000004, OP_reg4 RSI, OP_piece 0x00000004) ; CHECK-NEXT: DW_AT_name {{.*}}"outer" ; CHECK: DW_TAG_variable -; rsi, piece 0x00000004 -; CHECK-NEXT: DW_AT_location [DW_FORM_block1] {{.*}} 54 93 04 +; CHECK-NEXT: DW_AT_location [DW_FORM_block1]{{.*}}(OP_reg4 RSI, OP_piece 0x00000004 ; CHECK-NEXT: "i1" ; -; CHECK: .debug_loc -; CHECK: [[LOC]]: -; CHECK: Beginning address offset: 0x0000000000000000 -; CHECK: Ending address offset: 0x0000000000000004 -; rdi, piece 0x00000008, piece 0x00000004, rsi, piece 0x00000004 -; CHECK: Location description: 55 93 08 93 04 54 93 04 -; ; ModuleID = '/Volumes/Data/llvm/test/DebugInfo/X86/sroasplit-2.ll' target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.9.0" Index: test/DebugInfo/X86/subregisters.ll =================================================================== --- test/DebugInfo/X86/subregisters.ll +++ test/DebugInfo/X86/subregisters.ll @@ -6,7 +6,7 @@ ; ; rdar://problem/16015314 ; -; CHECK: DW_AT_location [DW_FORM_block1] (<0x03> 54 93 04 ) +; CHECK: DW_AT_location [DW_FORM_block1] (OP_reg4 RSI, OP_piece 0x00000004) ; CHECK: DW_AT_name [DW_FORM_strp]{{.*}} "a" ; ; struct bar { Index: test/DebugInfo/X86/template.ll =================================================================== --- test/DebugInfo/X86/template.ll +++ test/DebugInfo/X86/template.ll @@ -29,7 +29,7 @@ ; The address of the global 'glbl', followed by DW_OP_stack_value (9f), to use ; the value immediately, rather than indirecting through the address. -; CHECK-NEXT: DW_AT_location [DW_FORM_exprloc]{{ *}}(<0xa> 03 00 00 00 00 00 00 00 00 9f ) +; CHECK-NEXT: DW_AT_location [DW_FORM_exprloc]{{ *}}(OP_addr 0x0000000000000000, OP_stack_value) ; CHECK-NOT: NULL ; CHECK: DW_TAG_GNU_template_template_param Index: test/DebugInfo/dwarfdump-debug-loc-simple.test =================================================================== --- test/DebugInfo/dwarfdump-debug-loc-simple.test +++ test/DebugInfo/dwarfdump-debug-loc-simple.test @@ -3,24 +3,20 @@ CHECK: .debug_info CHECK: DW_AT_name{{.*}}"f" -CHECK: DW_AT_location{{.*}}([[F_LOC:0x[0-9a-f]*]]) +CHECK: DW_AT_location{{.*}}([[F_LOC:0x[0-9a-f]*]] +CHECK-NEXT: 0x0000000000000000 - 0x0000000000000023: OP_reg1 ECX +CHECK-NEXT: 0x0000000000000023 - 0x000000000000005d: OP_breg5 EBP-16) CHECK: DW_AT_name{{.*}}"g" -CHECK: DW_AT_location{{.*}}([[G_LOC:0x[0-9a-f]*]]) +CHECK: DW_AT_location{{.*}}([[G_LOC:0x[0-9a-f]*]] +CHECK-NEXT: 0x0000000000000000 - 0x0000000000000020: OP_reg0 EAX +CHECK-NEXT: 0x0000000000000020 - 0x000000000000005d: OP_breg5 EBP-12) + CHECK: .debug_loc contents: -CHECK-NEXT: [[F_LOC]]: Beginning address offset: 0x0000000000000000 -CHECK-NEXT: Ending address offset: 0x0000000000000023 +CHECK-NEXT: [[F_LOC]]: this is actually the wrong location due to PR14763, but that doesn't matter for the purposes of testing dwarfdump -CHECK-NEXT: Location description: 51 -CHECK-NEXT: {{^$}} -CHECK-NEXT: Beginning address offset: 0x0000000000000023 -CHECK-NEXT: Ending address offset: 0x000000000000005d -CHECK-NEXT: Location description: 75 70 -CHECK-NEXT: {{^$}} -CHECK-NEXT: [[G_LOC]]: Beginning address offset: 0x0000000000000000 -CHECK-NEXT: Ending address offset: 0x0000000000000020 -CHECK-NEXT: Location description: 50 -CHECK-NEXT: {{^$}} -CHECK-NEXT: Beginning address offset: 0x0000000000000020 -CHECK-NEXT: Ending address offset: 0x000000000000005d -CHECK-NEXT: Location description: 75 74 +CHECK-NEXT: 0x0000000000000000 - 0x0000000000000023: OP_reg1 ECX +CHECK-NEXT: 0x0000000000000023 - 0x000000000000005d: OP_breg5 EBP-16 +CHECK: [[G_LOC]]: +CHECK-NEXT: 0x0000000000000000 - 0x0000000000000020: OP_reg0 EAX +CHECK-NEXT: 0x0000000000000020 - 0x000000000000005d: OP_breg5 EBP-12 Index: test/DebugInfo/incorrect-variable-debugloc1.ll =================================================================== --- test/DebugInfo/incorrect-variable-debugloc1.ll +++ test/DebugInfo/incorrect-variable-debugloc1.ll @@ -23,8 +23,11 @@ ; return c; ; } -; DWARF23: Location description: 10 0d {{$}} -; DWARF4: Location description: 10 0d 9f +; CHECK: DW_TAG_variable +; CHECK: DW_AT_location +; CHECK-NOT: DW_AT +; DWARF23: OP_constu 0x0000000d{{$}} +; DWARF4: OP_constu 0x0000000d, OP_stack_value{{$}} ; Function Attrs: uwtable define i32 @main() #0 {