diff --git a/llvm/include/llvm/DebugInfo/DIContext.h b/llvm/include/llvm/DebugInfo/DIContext.h --- a/llvm/include/llvm/DebugInfo/DIContext.h +++ b/llvm/include/llvm/DebugInfo/DIContext.h @@ -114,6 +114,8 @@ std::string Name; uint64_t Start = 0; uint64_t Size = 0; + std::string DeclFile; + uint64_t DeclLine = 0; DIGlobal() : Name(DILineInfo::BadString) {} }; diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include @@ -240,6 +242,11 @@ /// std::map::upper_bound for address range lookup. std::map> AddrDieMap; + /// Map from the location (interpreted DW_AT_location) of a DW_TAG_variable, + /// to the DIE. + std::unordered_map VariableDieMap; + std::unordered_set RootsParsedForVariables; + using die_iterator_range = iterator_range::iterator>; @@ -322,6 +329,9 @@ /// Recursively update address to Die map. void updateAddressDieMap(DWARFDie Die); + /// Recursively update address to variable Die map. + void updateVariableDieMap(DWARFDie Die); + void setRangesSection(const DWARFSection *RS, uint64_t Base) { RangeSection = RS; RangeSectionBase = Base; @@ -436,6 +446,10 @@ /// cleared. DWARFDie getSubroutineForAddress(uint64_t Address); + /// Returns variable DIE for the address provided. The pointer is alive as + /// long as parsed compile unit DIEs are not cleared. + DWARFDie getVariableForAddress(uint64_t Address); + /// getInlinedChainForAddress - fetches inlined chain for a given address. /// Returns empty chain if there is no subprogram containing address. The /// chain is valid as long as parsed compile unit DIEs are not cleared. diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -1264,8 +1264,17 @@ DILineInfo Result; DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address); - if (!CU) + if (!CU) { + // Fallback to walking the .debug_info, looking for DW_TAG_variables. + for (const auto &CU : normal_units()) { + DWARFDie Die = CU->getVariableForAddress(Address.Address); + if (Die.isValid()) { + Result.FileName = Die.getDeclFile(FileLineInfoKind::AbsoluteFilePath); + Result.Line = Die.getDeclLine(); + } + } return Result; + } getFunctionNameAndStartLineForAddress( CU, Address.Address, Spec.FNKind, Spec.FLIKind, Result.FunctionName, diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -23,6 +23,7 @@ #include "llvm/DebugInfo/DWARF/DWARFObject.h" #include "llvm/DebugInfo/DWARF/DWARFSection.h" #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h" +#include "llvm/Object/ObjectFile.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/Errc.h" #include "llvm/Support/Path.h" @@ -739,6 +740,52 @@ return R->second.second; } +void DWARFUnit::updateVariableDieMap(DWARFDie Die) { + for (DWARFDie Child = Die.getFirstChild(); Child; Child = Child.getSibling()) + updateVariableDieMap(Child); + + if (Die.getTag() != DW_TAG_variable) + return; + + Expected Locations = + Die.getLocations(DW_AT_location); + if (!Locations) + return; + + for (const DWARFLocationExpression &Location : *Locations) { + DataExtractor Data(Location.Expr, /*IsLittleEndian=*/true, 8); + uint64_t DataOffset = 0; + uint8_t Operation = Data.getU8(&DataOffset); + if (Operation == dwarf::DW_OP_addr) { + uint64_t Pointer = Data.getAddress(&DataOffset); + VariableDieMap[Pointer] = Die; + return; + } + if (Operation == dwarf::DW_OP_addrx) { + uint64_t DebugAddrOffset = Data.getULEB128(&DataOffset); + Optional Pointer = + getAddrOffsetSectionItem(DebugAddrOffset); + if (Pointer) + VariableDieMap[Pointer->Address] = Die; + } + } +} + +DWARFDie DWARFUnit::getVariableForAddress(uint64_t Address) { + extractDIEsIfNeeded(false); + + auto RootDie = getUnitDIE(); + + if (RootsParsedForVariables.count(RootDie.getOffset()) == 0) { + updateVariableDieMap(RootDie); + RootsParsedForVariables.insert(RootDie.getOffset()); + } + + if (!VariableDieMap.count(Address)) + return DWARFDie(); + return VariableDieMap[Address]; +} + void DWARFUnit::getInlinedChainForAddress(uint64_t Address, SmallVectorImpl &InlinedChain) { diff --git a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp --- a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp +++ b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp @@ -206,6 +206,10 @@ Name = DILineInfo::Addr2LineBadString; OS << Name << "\n"; OS << Global.Start << " " << Global.Size << "\n"; + if (Global.DeclFile.empty()) + OS << "??:?\n"; + else + OS << Global.DeclFile << ":" << Global.DeclLine << "\n"; printFooter(); } diff --git a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp --- a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp +++ b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp @@ -327,6 +327,14 @@ std::string FileName; getNameFromSymbolTable(ModuleOffset.Address, Res.Name, Res.Start, Res.Size, FileName); + Res.DeclFile = FileName; + + // Try and get a better filename:lineno pair from the debuginfo, if present. + DILineInfo DL = DebugInfoContext->getLineInfoForAddress(ModuleOffset); + if (DL.Line != 0) { + Res.DeclFile = DL.FileName; + Res.DeclLine = DL.Line; + } return Res; } diff --git a/llvm/test/DebugInfo/Symbolize/ELF/data-command-symtab.yaml b/llvm/test/DebugInfo/Symbolize/ELF/data-command-symtab.yaml --- a/llvm/test/DebugInfo/Symbolize/ELF/data-command-symtab.yaml +++ b/llvm/test/DebugInfo/Symbolize/ELF/data-command-symtab.yaml @@ -7,12 +7,15 @@ # CHECK: func # CHECK-NEXT: 4096 1 +# CHECK-NEXT: ??:? # CHECK-EMPTY: # CHECK-NEXT: data # CHECK-NEXT: 8192 2 +# CHECK-NEXT: ??:? # CHECK-EMPTY: # CHECK-NEXT: notype # CHECK-NEXT: 8194 3 +# CHECK-NEXT: ??:? # CHECK-EMPTY: --- !ELF diff --git a/llvm/test/tools/llvm-symbolizer/data-location.s b/llvm/test/tools/llvm-symbolizer/data-location.s new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-symbolizer/data-location.s @@ -0,0 +1,467 @@ +## Show that when "DATA" is used with an address, it forces the found location +## to be symbolized as data, including the source information. +# RUN: yaml2obj %s -o %t.so +# RUN: llvm-symbolizer "DATA 0x3888" "DATA 0x388c" --obj=%t.so | FileCheck %s + +# CHECK: x +# CHECK-NEXT: 14472 4 +# CHECK-NEXT: /tmp/file.c:1 +# CHECK-EMPTY: +# CHECK-NEXT: y +# CHECK-NEXT: 14476 4 +# CHECK-NEXT: /tmp/file.c:3 +# CHECK-EMPTY: + +################################################################################ +## File below was generated using: +## $ clang -g -fuse-ld=lld -shared /tmp/file.c -o out.so && obj2yaml out.so +## ... with /tmp/file.c: +## 1: int x; +## 2: +## 3: int y; +## 4: void f() {} +## 5: +################################################################################ + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +ProgramHeaders: + - Type: PT_PHDR + Flags: [ PF_R ] + VAddr: 0x40 + Align: 0x8 + - Type: PT_LOAD + Flags: [ PF_R ] + FirstSec: .dynsym + LastSec: .eh_frame + Align: 0x1000 + - Type: PT_LOAD + Flags: [ PF_X, PF_R ] + FirstSec: .text + LastSec: .plt + VAddr: 0x1500 + Align: 0x1000 + - Type: PT_LOAD + Flags: [ PF_W, PF_R ] + FirstSec: .ctors + LastSec: .got + VAddr: 0x26C0 + Align: 0x1000 + - Type: PT_LOAD + Flags: [ PF_W, PF_R ] + FirstSec: .data + LastSec: .bss + VAddr: 0x3850 + Align: 0x1000 + - Type: PT_DYNAMIC + Flags: [ PF_W, PF_R ] + FirstSec: .dynamic + LastSec: .dynamic + VAddr: 0x26E0 + Align: 0x8 + - Type: PT_GNU_RELRO + Flags: [ PF_R ] + FirstSec: .ctors + LastSec: .got + VAddr: 0x26C0 + - Type: PT_GNU_EH_FRAME + Flags: [ PF_R ] + FirstSec: .eh_frame_hdr + LastSec: .eh_frame_hdr + VAddr: 0x4A0 + Align: 0x4 + - Type: PT_GNU_STACK + Flags: [ PF_W, PF_R ] + Align: 0x0 +Sections: + - Name: .dynsym + Type: SHT_DYNSYM + Flags: [ SHF_ALLOC ] + Address: 0x238 + Link: .dynstr + AddressAlign: 0x8 + - Name: .gnu.version + Type: SHT_GNU_versym + Flags: [ SHF_ALLOC ] + Address: 0x2F8 + Link: .dynsym + AddressAlign: 0x2 + Entries: [ 0, 1, 1, 1, 2, 1, 1, 1 ] + - Name: .gnu.version_r + Type: SHT_GNU_verneed + Flags: [ SHF_ALLOC ] + Address: 0x308 + Link: .dynstr + AddressAlign: 0x4 + Dependencies: + - Version: 1 + File: libc.so.6 + Entries: + - Name: GLIBC_2.2.5 + Hash: 157882997 + Flags: 0 + Other: 2 + - Name: .gnu.hash + Type: SHT_GNU_HASH + Flags: [ SHF_ALLOC ] + Address: 0x328 + Link: .dynsym + AddressAlign: 0x8 + Header: + SymNdx: 0x5 + Shift2: 0x1A + BloomFilter: [ 0x60000801 ] + HashBuckets: [ 0x5 ] + HashValues: [ 0x2B60A, 0x2B61C, 0x2B61F ] + - Name: .hash + Type: SHT_HASH + Flags: [ SHF_ALLOC ] + Address: 0x350 + Link: .dynsym + AddressAlign: 0x4 + Bucket: [ 6, 7, 0, 0, 0, 4, 5, 1 ] + Chain: [ 0, 0, 0, 2, 3, 0, 0, 0 ] + - Name: .dynstr + Type: SHT_STRTAB + Flags: [ SHF_ALLOC ] + Address: 0x398 + AddressAlign: 0x1 + - Name: .rela.dyn + Type: SHT_RELA + Flags: [ SHF_ALLOC ] + Address: 0x410 + Link: .dynsym + AddressAlign: 0x8 + Relocations: + - Offset: 0x3850 + Type: R_X86_64_RELATIVE + Addend: 14416 + - Offset: 0x2830 + Symbol: __gmon_start__ + Type: R_X86_64_GLOB_DAT + - Offset: 0x2838 + Symbol: _ITM_deregisterTMCloneTable + Type: R_X86_64_GLOB_DAT + - Offset: 0x2840 + Symbol: _ITM_registerTMCloneTable + Type: R_X86_64_GLOB_DAT + - Offset: 0x2848 + Symbol: __cxa_finalize + Type: R_X86_64_GLOB_DAT + - Name: .rela.plt + Type: SHT_RELA + Flags: [ SHF_ALLOC, SHF_INFO_LINK ] + Address: 0x488 + Link: .dynsym + AddressAlign: 0x8 + Info: .got.plt + Relocations: + - Offset: 0x3870 + Symbol: __cxa_finalize + Type: R_X86_64_JUMP_SLOT + - Name: .eh_frame_hdr + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x4A0 + AddressAlign: 0x4 + Content: 011B033B14000000010000007011000030000000 + - Name: .eh_frame + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x4B8 + AddressAlign: 0x8 + Content: 1400000000000000017A5200017810011B0C0708900100001C0000001C000000381100000600000000410E108602430D06410C070800000000000000 + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1500 + AddressAlign: 0x10 + Content: 488D3D51230000488D054A2300004839F87415488B051E1300004885C07409FFE00F1F8000000000C30F1F8000000000488D3D21230000488D351A2300004829FE4889F048C1EE3F48C1F8034801C648D1FE7414488B05E51200004885C07408FFE0660F1F440000C30F1F8000000000F30F1EFA803DFD22000000757B5548833DC2120000004889E5415453740C488B3DBB220000E816010000488D052F110000488D1D301100004829C34989C4488B05CB22000048C1FB034883EB014839D87321660F1F4400004883C001488905AD22000041FF14C4488B05A22200004839D872E5E818FFFFFF5B415CC60586220000015DC30F1F4000C30F1F8000000000F30F1EFAE927FFFFFFCCCCCCCCCCCCCC554889E55DC3CCCCCCCCCCCCCCCCCCCCF30F1EFA488B05951000004883F8FF742F554889E553488D1D831000004883EC080F1F8000000000FFD0488B43F84883EB084883F8FF75F0488B5DF8C9C36690C3 + - Name: .init + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1664 + AddressAlign: 0x4 + Content: 4883EC08488B05C11100004885C07402FFD0E885FFFFFFE8A0FFFFFF4883C408C3 + - Name: .fini + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1688 + AddressAlign: 0x4 + Content: 4883EC08E8DFFEFFFF4883C408C3 + - Name: .plt + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x16A0 + AddressAlign: 0x10 + Content: FF35BA210000FF25BC2100000F1F4000FF25BA2100006800000000E9E0FFFFFF + - Name: .ctors + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x26C0 + AddressAlign: 0x8 + Content: FFFFFFFFFFFFFFFF0000000000000000 + - Name: .dtors + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x26D0 + AddressAlign: 0x8 + Content: FFFFFFFFFFFFFFFF0000000000000000 + - Name: .dynamic + Type: SHT_DYNAMIC + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x26E0 + Link: .dynstr + AddressAlign: 0x8 + Entries: + - Tag: DT_NEEDED + Value: 0x5B + - Tag: DT_RELA + Value: 0x410 + - Tag: DT_RELASZ + Value: 0x78 + - Tag: DT_RELAENT + Value: 0x18 + - Tag: DT_RELACOUNT + Value: 0x1 + - Tag: DT_JMPREL + Value: 0x488 + - Tag: DT_PLTRELSZ + Value: 0x18 + - Tag: DT_PLTGOT + Value: 0x3858 + - Tag: DT_PLTREL + Value: 0x7 + - Tag: DT_SYMTAB + Value: 0x238 + - Tag: DT_SYMENT + Value: 0x18 + - Tag: DT_STRTAB + Value: 0x398 + - Tag: DT_STRSZ + Value: 0x71 + - Tag: DT_GNU_HASH + Value: 0x328 + - Tag: DT_HASH + Value: 0x350 + - Tag: DT_INIT + Value: 0x1664 + - Tag: DT_FINI + Value: 0x1688 + - Tag: DT_VERSYM + Value: 0x2F8 + - Tag: DT_VERNEED + Value: 0x308 + - Tag: DT_VERNEEDNUM + Value: 0x1 + - Tag: DT_NULL + Value: 0x0 + - Name: .got + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x2830 + AddressAlign: 0x8 + Content: '0000000000000000000000000000000000000000000000000000000000000000' + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3850 + AddressAlign: 0x8 + Content: '0000000000000000' + - Name: .tm_clone_table + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3858 + AddressAlign: 0x8 + - Name: .got.plt + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3858 + AddressAlign: 0x8 + Content: E02600000000000000000000000000000000000000000000B616000000000000 + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x3878 + AddressAlign: 0x8 + Size: 0x18 + - Name: .comment + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x1 + EntSize: 0x1 + Content: 4C696E6B65723A204C4C442031342E302E30004743433A202844656269616E2031312E322E302D3136292031312E322E300000636C616E672076657273696F6E2031342E302E30202868747470733A2F2F6769746875622E636F6D2F6C6C766D2F6C6C766D2D70726F6A6563742E67697420353335376139386338323361353236323831346532363964623236356235643865316632633466322900 + - Name: .debug_abbrev + Type: SHT_PROGBITS + AddressAlign: 0x1 + Content: 011101250E1305030E10171B0E110112060000023400030E49133F193A0B3B0B02180000032400030E3E0B0B0B0000042E00110112064018030E3A0B3B0B3F19000000 + - Name: .debug_info + Type: SHT_PROGBITS + AddressAlign: 0x1 + Content: 6D00000004000000000008011B0000000C0002000000000000001600000010160000000000000600000002140000003F00000001010903883800000000000003100000000504020E0000003F000000010309038C3800000000000004101600000000000006000000015600000000010400 + - Name: .debug_line + Type: SHT_PROGBITS + AddressAlign: 0x1 + Content: 3900000004001E000000010101FB0E0D0001010101000000010000010066696C652E630000000000000902101600000000000015050B0A4A0202000101 +Symbols: + - Name: crtstuff.c + Type: STT_FILE + Index: SHN_ABS + - Name: __CTOR_LIST__ + Type: STT_OBJECT + Section: .ctors + Value: 0x26C0 + - Name: __DTOR_LIST__ + Type: STT_OBJECT + Section: .dtors + Value: 0x26D0 + - Name: __TMC_LIST__ + Type: STT_OBJECT + Section: .tm_clone_table + Value: 0x3858 + - Name: deregister_tm_clones + Type: STT_FUNC + Section: .text + Value: 0x1500 + - Name: register_tm_clones + Type: STT_FUNC + Section: .text + Value: 0x1530 + - Name: __do_global_dtors_aux + Type: STT_FUNC + Section: .text + Value: 0x1570 + - Name: completed.1 + Type: STT_OBJECT + Section: .bss + Value: 0x3878 + Size: 0x1 + - Name: dtor_idx.0 + Type: STT_OBJECT + Section: .bss + Value: 0x3880 + Size: 0x8 + - Name: frame_dummy + Type: STT_FUNC + Section: .text + Value: 0x1600 + - Name: __dso_handle + Type: STT_OBJECT + Section: .data + Value: 0x3850 + Other: [ STV_HIDDEN ] + - Name: file.c + Type: STT_FILE + Index: SHN_ABS + - Name: 'crtstuff.c (1)' + Type: STT_FILE + Index: SHN_ABS + - Name: __CTOR_END__ + Type: STT_OBJECT + Section: .ctors + Value: 0x26C8 + - Name: __FRAME_END__ + Type: STT_OBJECT + Section: .eh_frame + Value: 0x4B8 + - Name: __do_global_ctors_aux + Type: STT_FUNC + Section: .text + Value: 0x1620 + - Name: __TMC_END__ + Type: STT_OBJECT + Section: .tm_clone_table + Value: 0x3858 + Other: [ STV_HIDDEN ] + - Name: __DTOR_END__ + Type: STT_OBJECT + Section: .dtors + Value: 0x26D8 + Other: [ STV_HIDDEN ] + - Name: _init + Type: STT_FUNC + Section: .init + Value: 0x1664 + Other: [ STV_HIDDEN ] + - Name: _fini + Type: STT_FUNC + Section: .fini + Value: 0x1688 + Other: [ STV_HIDDEN ] + - Name: _GLOBAL_OFFSET_TABLE_ + Section: .got.plt + Value: 0x3858 + Other: [ STV_HIDDEN ] + - Name: _DYNAMIC + Section: .dynamic + Value: 0x26E0 + Other: [ STV_HIDDEN ] + - Name: __gmon_start__ + Binding: STB_WEAK + - Name: _ITM_deregisterTMCloneTable + Binding: STB_WEAK + - Name: _ITM_registerTMCloneTable + Binding: STB_WEAK + - Name: __cxa_finalize + Type: STT_FUNC + Binding: STB_WEAK + - Name: f + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Value: 0x1610 + Size: 0x6 + - Name: x + Type: STT_OBJECT + Section: .bss + Binding: STB_GLOBAL + Value: 0x3888 + Size: 0x4 + - Name: y + Type: STT_OBJECT + Section: .bss + Binding: STB_GLOBAL + Value: 0x388C + Size: 0x4 +DynamicSymbols: + - Name: __gmon_start__ + Binding: STB_WEAK + - Name: _ITM_deregisterTMCloneTable + Binding: STB_WEAK + - Name: _ITM_registerTMCloneTable + Binding: STB_WEAK + - Name: __cxa_finalize + Type: STT_FUNC + Binding: STB_WEAK + - Name: f + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Value: 0x1610 + Size: 0x6 + - Name: x + Type: STT_OBJECT + Section: .bss + Binding: STB_GLOBAL + Value: 0x3888 + Size: 0x4 + - Name: y + Type: STT_OBJECT + Section: .bss + Binding: STB_GLOBAL + Value: 0x388C + Size: 0x4 +DWARF: + debug_str: + - f + - '/tmp/file.c' + - y + - int + - x + - '/tmp' + - 'clang version 14.0.0 (https://github.com/llvm/llvm-project.git 5357a98c823a5262814e269db265b5d8e1f2c4f2)' +... diff --git a/llvm/test/tools/llvm-symbolizer/data.s b/llvm/test/tools/llvm-symbolizer/data.s --- a/llvm/test/tools/llvm-symbolizer/data.s +++ b/llvm/test/tools/llvm-symbolizer/data.s @@ -7,9 +7,12 @@ # CHECK: d1 # CHECK-NEXT: 0 8 +# CHECK-NEXT: ??:? # CHECK-EMPTY: # CHECK-NEXT: d2 # CHECK-NEXT: 8 4 +# CHECK-NEXT: ??:? +# CHECK-EMPTY: d1: .quad 0x1122334455667788