Index: llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h =================================================================== --- llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h +++ llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h @@ -87,8 +87,7 @@ uint64_t getRawOperand(unsigned Idx) { return Operands[Idx]; } uint64_t getOperandEndOffset(unsigned Idx) { return OperandEndOffsets[Idx]; } uint64_t getEndOffset() { return EndOffset; } - bool extract(DataExtractor Data, uint16_t Version, uint8_t AddressSize, - uint64_t Offset); + bool extract(DataExtractor Data, uint8_t AddressSize, uint64_t Offset); bool isError() { return Error; } bool print(raw_ostream &OS, const DWARFExpression *Expr, const MCRegisterInfo *RegInfo, DWARFUnit *U, bool isEH); @@ -107,7 +106,7 @@ : Expr(Expr), Offset(Offset) { Op.Error = Offset >= Expr->Data.getData().size() || - !Op.extract(Expr->Data, Expr->Version, Expr->AddressSize, Offset); + !Op.extract(Expr->Data, Expr->AddressSize, Offset); } public: @@ -115,7 +114,7 @@ Offset = Op.isError() ? Expr->Data.getData().size() : Op.EndOffset; Op.Error = Offset >= Expr->Data.getData().size() || - !Op.extract(Expr->Data, Expr->Version, Expr->AddressSize, Offset); + !Op.extract(Expr->Data, Expr->AddressSize, Offset); return Op; } @@ -127,8 +126,8 @@ friend bool operator==(const iterator &, const iterator &); }; - DWARFExpression(DataExtractor Data, uint16_t Version, uint8_t AddressSize) - : Data(Data), Version(Version), AddressSize(AddressSize) { + DWARFExpression(DataExtractor Data, uint8_t AddressSize) + : Data(Data), AddressSize(AddressSize) { assert(AddressSize == 8 || AddressSize == 4 || AddressSize == 2); } @@ -142,7 +141,6 @@ private: DataExtractor Data; - uint16_t Version; uint8_t AddressSize; }; Index: llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -2191,7 +2191,7 @@ DWARFDataExtractor Data(StringRef(DebugLocs.getBytes(Entry).data(), DebugLocs.getBytes(Entry).size()), Asm->getDataLayout().isLittleEndian(), PtrSize); - DWARFExpression Expr(Data, getDwarfVersion(), PtrSize); + DWARFExpression Expr(Data, PtrSize); using Encoding = DWARFExpression::Operation::Encoding; uint64_t Offset = 0; Index: llvm/lib/DWARFLinker/DWARFLinker.cpp =================================================================== --- llvm/lib/DWARFLinker/DWARFLinker.cpp +++ llvm/lib/DWARFLinker/DWARFLinker.cpp @@ -953,8 +953,7 @@ DWARFUnit &OrigUnit = Unit.getOrigUnit(); DataExtractor Data(StringRef((const char *)Bytes.data(), Bytes.size()), IsLittleEndian, OrigUnit.getAddressByteSize()); - DWARFExpression Expr(Data, OrigUnit.getVersion(), - OrigUnit.getAddressByteSize()); + DWARFExpression Expr(Data, OrigUnit.getAddressByteSize()); cloneExpression(Data, Expr, OF, Unit, Buffer); Bytes = Buffer; } @@ -2059,8 +2058,7 @@ DataExtractor Data(Bytes, IsLittleEndian, OrigUnit.getAddressByteSize()); cloneExpression(Data, - DWARFExpression(Data, OrigUnit.getVersion(), - OrigUnit.getAddressByteSize()), + DWARFExpression(Data, OrigUnit.getAddressByteSize()), OF, *CurrentUnit, Buffer); }; Emitter->emitLocationsForUnit(*CurrentUnit, DwarfContext, ProcessExpr); Index: llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp @@ -130,8 +130,8 @@ DataExtractor Extractor( Data.getData().slice(*Offset, *Offset + ExprLength), Data.isLittleEndian(), Data.getAddressSize()); - Instructions.back().Expression = DWARFExpression( - Extractor, Data.getAddressSize(), dwarf::DWARF_VERSION); + Instructions.back().Expression = + DWARFExpression(Extractor, Data.getAddressSize()); *Offset += ExprLength; break; } @@ -143,8 +143,8 @@ DataExtractor Extractor( Data.getData().slice(*Offset, *Offset + BlockLength), Data.isLittleEndian(), Data.getAddressSize()); - Instructions.back().Expression = DWARFExpression( - Extractor, Data.getAddressSize(), dwarf::DWARF_VERSION); + Instructions.back().Expression = + DWARFExpression(Extractor, Data.getAddressSize()); *Offset += BlockLength; break; } Index: llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp @@ -106,16 +106,11 @@ } } -// When directly dumping the .debug_loc without a compile unit, we have to guess -// at the DWARF version. This only affects DW_OP_call_ref, which is a rare -// expression that LLVM doesn't produce. Guessing the wrong version means we -// won't be able to pretty print expressions in DWARF2 binaries produced by -// non-LLVM tools. static void dumpExpression(raw_ostream &OS, ArrayRef Data, bool IsLittleEndian, unsigned AddressSize, const MCRegisterInfo *MRI, DWARFUnit *U) { DWARFDataExtractor Extractor(toStringRef(Data), IsLittleEndian, AddressSize); - DWARFExpression(Extractor, dwarf::DWARF_VERSION, AddressSize).print(OS, MRI, U); + DWARFExpression(Extractor, AddressSize).print(OS, MRI, U); } bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS, Index: llvm/lib/DebugInfo/DWARF/DWARFDie.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFDie.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -79,8 +79,7 @@ ArrayRef Expr = *FormValue.getAsBlock(); DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()), Ctx.isLittleEndian(), 0); - DWARFExpression(Data, U->getVersion(), U->getAddressByteSize()) - .print(OS, MRI, U); + DWARFExpression(Data, U->getAddressByteSize()).print(OS, MRI, U); return; } Index: llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp @@ -116,11 +116,7 @@ return Descriptions[OpCode]; } -static uint8_t getRefAddrSize(uint8_t AddrSize, uint16_t Version) { - return (Version == 2) ? AddrSize : 4; -} - -bool DWARFExpression::Operation::extract(DataExtractor Data, uint16_t Version, +bool DWARFExpression::Operation::extract(DataExtractor Data, uint8_t AddressSize, uint64_t Offset) { Opcode = Data.getU8(&Offset); @@ -160,14 +156,8 @@ Operands[Operand] = Data.getUnsigned(&Offset, AddressSize); break; case Operation::SizeRefAddr: - if (getRefAddrSize(AddressSize, Version) == 8) { - Operands[Operand] = Data.getU64(&Offset); - } else if (getRefAddrSize(AddressSize, Version) == 4) { - Operands[Operand] = Data.getU32(&Offset); - } else { - assert(getRefAddrSize(AddressSize, Version) == 2); - Operands[Operand] = Data.getU16(&Offset); - } + // TODO: Add support for 64-bit DWARF format. + Operands[Operand] = Data.getU32(&Offset); break; case Operation::SizeLEB: if (Signed) Index: llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp @@ -481,8 +481,7 @@ DWARFUnit *U = Die.getDwarfUnit(); for (const auto &Entry : *Loc) { DataExtractor Data(toStringRef(Entry.Expr), DCtx.isLittleEndian(), 0); - DWARFExpression Expression(Data, U->getVersion(), - U->getAddressByteSize()); + DWARFExpression Expression(Data, U->getAddressByteSize()); bool Error = any_of(Expression, [](DWARFExpression::Operation &Op) { return Op.isError(); }); @@ -1290,7 +1289,7 @@ for (const auto &Entry : *Loc) { DataExtractor Data(toStringRef(Entry.Expr), DCtx.isLittleEndian(), U->getAddressByteSize()); - DWARFExpression Expression(Data, U->getVersion(), U->getAddressByteSize()); + DWARFExpression Expression(Data, U->getAddressByteSize()); bool IsInteresting = any_of(Expression, [](DWARFExpression::Operation &Op) { return !Op.isError() && (Op.getCode() == DW_OP_addr || Op.getCode() == DW_OP_form_tls_address || Index: llvm/test/DebugInfo/X86/DW_OP_call_ref_ver2.s =================================================================== --- /dev/null +++ llvm/test/DebugInfo/X86/DW_OP_call_ref_ver2.s @@ -0,0 +1,42 @@ +# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj | \ +# RUN: llvm-dwarfdump - | \ +# RUN: FileCheck %s + +# This checks that the operand of DW_OP_call_ref is always parsed corresponding +# to the DWARF format of CU. Our code used to have an exception for verson == 2, +# where it treated the operand like it had the size of address, but since +# DW_OP_call_ref was introduced only in DWARF3, the code could be simplified. + +# CHECK: DW_TAG_variable +# CHECK-NEXT: DW_AT_location (DW_OP_call_ref 0x11223344) + + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 10 # DW_FORM_block1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + + .section .debug_info,"",@progbits + .long .Lcu_end-.Lcu_start # Length of Unit +.Lcu_start: + .short 2 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] DW_TAG_compile_unit + .byte 5 # Abbrev [5] DW_TAG_variable + .byte .Lloc_end-.Lloc_begin # DW_AT_location +.Lloc_begin: + .byte 154 # DW_OP_call_ref + .long 0x11223344 # Offset +.Lloc_end: + .byte 0 # End Of Children Mark +.Lcu_end: Index: llvm/tools/llvm-dwarfdump/Statistics.cpp =================================================================== --- llvm/tools/llvm-dwarfdump/Statistics.cpp +++ llvm/tools/llvm-dwarfdump/Statistics.cpp @@ -206,7 +206,7 @@ DWARFUnit *U = Die.getDwarfUnit(); DataExtractor Data(toStringRef(D), Die.getDwarfUnit()->getContext().isLittleEndian(), 0); - DWARFExpression Expression(Data, U->getVersion(), U->getAddressByteSize()); + DWARFExpression Expression(Data, U->getAddressByteSize()); // Consider the expression containing the DW_OP_entry_value as // an entry value. return llvm::any_of(Expression, [](DWARFExpression::Operation &Op) {