hctim updated this revision to Diff 426172.
hctim marked an inline comment as done.
hctim added a comment.
Herald added subscribers: rupprecht, MaskRay, emaste.
Herald added a reviewer: jhenderson.
Update test, rebase off of string debuginfo.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D123534/new/
https://reviews.llvm.org/D123534
Files:
llvm/include/llvm/DebugInfo/DIContext.h
llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
llvm/include/llvm/DebugInfo/PDB/PDBContext.h
llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
llvm/lib/DebugInfo/PDB/PDBContext.cpp
llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
llvm/test/DebugInfo/Symbolize/ELF/data-command-symtab.yaml
llvm/test/tools/llvm-symbolizer/data-location.yaml
llvm/test/tools/llvm-symbolizer/data.s
Index: llvm/test/tools/llvm-symbolizer/data.s
===================================================================
--- llvm/test/tools/llvm-symbolizer/data.s
+++ 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
Index: llvm/test/tools/llvm-symbolizer/data-location.yaml
===================================================================
--- /dev/null
+++ llvm/test/tools/llvm-symbolizer/data-location.yaml
@@ -0,0 +1,503 @@
+## 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 0x38a4" "DATA 0x3868" "DATA 0x38a0" \
+# RUN: --obj=%t.so | FileCheck %s
+
+# CHECK: bss_global
+# CHECK-NEXT: {{[0-9]+}} 4
+# CHECK-NEXT: /tmp/file.c:1
+# CHECK-EMPTY:
+# CHECK-NEXT: data_global
+# CHECK-NEXT: {{[0-9]+}} 4
+# CHECK-NEXT: /tmp/file.c:2
+# CHECK-EMPTY:
+# CHECK-NEXT: f.function_global
+# CHECK-NEXT: {{[0-9]+}} 4
+# CHECK-NEXT: /tmp/file.c:4
+# 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 bss_global;
+## 2: int data_global = 2;
+## 3: void f() {
+## 4: static int function_global;
+## 5: }
+## 6:
+## ... then, one can get the offsets using `nm`, like:
+## $ nm out.so | grep bss_global
+## 00000000000038fc B bss_global
+##
+## Ideally, this would be tested by invoking clang directly on a C source file,
+## but unfortunately there's no way to do that for LLVM tests. The other option
+## is to compile IR to an objfile, but llvm-symbolizer doesn't understand that
+## two symbols can have the same address in different sections. In the code
+## above, for example, we'd have bss_global at .bss+0x0, and data_global at
+## .data+0x0, and so the symbolizer would only print one of them. Hence, we have
+## the ugly dso-to-yaml blob below.
+##
+## For now, constant strings don't have a debuginfo entry, and so can't be
+## symbolized correctly. In future (if D123534 gets merged), this can be updated
+## to include a check that llvm-symbolize can also symbolize constant strings,
+## like `const char* string = "123456"` (and &"123456" should be symbolizable)
+## to the specific line. Then, you can find the address of the constant string
+## from the relocation:
+## $ nm out.so | grep string
+## 00000000000038c0 D string
+## $ llvm-objdump -R out.so | grep 38c0
+## 00000000000038c0 R_X86_64_RELATIVE *ABS*+0x4f8 # <-- 0x4f8
+################################################################################
+
+--- !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: 0x1510
+ Align: 0x1000
+ - Type: PT_LOAD
+ Flags: [ PF_W, PF_R ]
+ FirstSec: .ctors
+ LastSec: .got
+ VAddr: 0x26D0
+ Align: 0x1000
+ - Type: PT_LOAD
+ Flags: [ PF_W, PF_R ]
+ FirstSec: .data
+ LastSec: .bss
+ VAddr: 0x3860
+ Align: 0x1000
+ - Type: PT_DYNAMIC
+ Flags: [ PF_W, PF_R ]
+ FirstSec: .dynamic
+ LastSec: .dynamic
+ VAddr: 0x26F0
+ Align: 0x8
+ - Type: PT_GNU_RELRO
+ Flags: [ PF_R ]
+ FirstSec: .ctors
+ LastSec: .got
+ VAddr: 0x26D0
+ - Type: PT_GNU_EH_FRAME
+ Flags: [ PF_R ]
+ FirstSec: .eh_frame_hdr
+ LastSec: .eh_frame_hdr
+ VAddr: 0x4B0
+ 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: [ 0x1800021000801 ]
+ HashBuckets: [ 0x5 ]
+ HashValues: [ 0x2B60A, 0x61F7372E, 0xC033991D ]
+ - Name: .hash
+ Type: SHT_HASH
+ Flags: [ SHF_ALLOC ]
+ Address: 0x350
+ Link: .dynsym
+ AddressAlign: 0x4
+ Bucket: [ 0, 0, 0, 0, 7, 4, 5, 1 ]
+ Chain: [ 0, 0, 0, 2, 3, 0, 0, 6 ]
+ - Name: .dynstr
+ Type: SHT_STRTAB
+ Flags: [ SHF_ALLOC ]
+ Address: 0x398
+ AddressAlign: 0x1
+ - Name: .rela.dyn
+ Type: SHT_RELA
+ Flags: [ SHF_ALLOC ]
+ Address: 0x420
+ Link: .dynsym
+ AddressAlign: 0x8
+ Relocations:
+ - Offset: 0x3860
+ Type: R_X86_64_RELATIVE
+ Addend: 14432
+ - Offset: 0x2840
+ Symbol: __gmon_start__
+ Type: R_X86_64_GLOB_DAT
+ - Offset: 0x2848
+ Symbol: _ITM_deregisterTMCloneTable
+ Type: R_X86_64_GLOB_DAT
+ - Offset: 0x2850
+ Symbol: _ITM_registerTMCloneTable
+ Type: R_X86_64_GLOB_DAT
+ - Offset: 0x2858
+ Symbol: __cxa_finalize
+ Type: R_X86_64_GLOB_DAT
+ - Name: .rela.plt
+ Type: SHT_RELA
+ Flags: [ SHF_ALLOC, SHF_INFO_LINK ]
+ Address: 0x498
+ Link: .dynsym
+ AddressAlign: 0x8
+ Info: .got.plt
+ Relocations:
+ - Offset: 0x3888
+ Symbol: __cxa_finalize
+ Type: R_X86_64_JUMP_SLOT
+ - Name: .eh_frame_hdr
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x4B0
+ AddressAlign: 0x4
+ Content: 011B033B14000000010000007011000030000000
+ - Name: .eh_frame
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x4C8
+ AddressAlign: 0x8
+ Content: 1400000000000000017A5200017810011B0C0708900100001C0000001C000000381100000600000000410E108602430D06410C070800000000000000
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1510
+ AddressAlign: 0x10
+ Content: 488D3D59230000488D05522300004839F87415488B051E1300004885C07409FFE00F1F8000000000C30F1F8000000000488D3D29230000488D35222300004829FE4889F048C1EE3F48C1F8034801C648D1FE7414488B05E51200004885C07408FFE0660F1F440000C30F1F8000000000F30F1EFA803D0523000000757B5548833DC2120000004889E5415453740C488B3DBB220000E816010000488D052F110000488D1D301100004829C34989C4488B05D322000048C1FB034883EB014839D87321660F1F4400004883C001488905B522000041FF14C4488B05AA2200004839D872E5E818FFFFFF5B415CC6058E220000015DC30F1F4000C30F1F8000000000F30F1EFAE927FFFFFFCCCCCCCCCCCCCC554889E55DC3CCCCCCCCCCCCCCCCCCCCF30F1EFA488B05951000004883F8FF742F554889E553488D1D831000004883EC080F1F8000000000FFD0488B43F84883EB084883F8FF75F0488B5DF8C9C36690C3
+ - Name: .init
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1674
+ AddressAlign: 0x4
+ Content: 4883EC08488B05C11100004885C07402FFD0E885FFFFFFE8A0FFFFFF4883C408C3
+ - Name: .fini
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1698
+ AddressAlign: 0x4
+ Content: 4883EC08E8DFFEFFFF4883C408C3
+ - Name: .plt
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x16B0
+ AddressAlign: 0x10
+ Content: FF35C2210000FF25C42100000F1F4000FF25C22100006800000000E9E0FFFFFF
+ - Name: .ctors
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x26D0
+ AddressAlign: 0x8
+ Content: FFFFFFFFFFFFFFFF0000000000000000
+ - Name: .dtors
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x26E0
+ AddressAlign: 0x8
+ Content: FFFFFFFFFFFFFFFF0000000000000000
+ - Name: .dynamic
+ Type: SHT_DYNAMIC
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x26F0
+ Link: .dynstr
+ AddressAlign: 0x8
+ Entries:
+ - Tag: DT_NEEDED
+ Value: 0x6E
+ - Tag: DT_RELA
+ Value: 0x420
+ - Tag: DT_RELASZ
+ Value: 0x78
+ - Tag: DT_RELAENT
+ Value: 0x18
+ - Tag: DT_RELACOUNT
+ Value: 0x1
+ - Tag: DT_JMPREL
+ Value: 0x498
+ - Tag: DT_PLTRELSZ
+ Value: 0x18
+ - Tag: DT_PLTGOT
+ Value: 0x3870
+ - Tag: DT_PLTREL
+ Value: 0x7
+ - Tag: DT_SYMTAB
+ Value: 0x238
+ - Tag: DT_SYMENT
+ Value: 0x18
+ - Tag: DT_STRTAB
+ Value: 0x398
+ - Tag: DT_STRSZ
+ Value: 0x84
+ - Tag: DT_GNU_HASH
+ Value: 0x328
+ - Tag: DT_HASH
+ Value: 0x350
+ - Tag: DT_INIT
+ Value: 0x1674
+ - Tag: DT_FINI
+ Value: 0x1698
+ - 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: 0x2840
+ AddressAlign: 0x8
+ Content: '0000000000000000000000000000000000000000000000000000000000000000'
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3860
+ AddressAlign: 0x8
+ Content: '000000000000000002000000'
+ - Name: .tm_clone_table
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3870
+ AddressAlign: 0x8
+ - Name: .got.plt
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3870
+ AddressAlign: 0x8
+ Content: F02600000000000000000000000000000000000000000000C616000000000000
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3890
+ 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: 011101250E1305030E10171B0E110112060000023400030E49133F193A0B3B0B02180000032400030E3E0B0B0B0000042E01110112064018030E3A0B3B0B3F190000053400030E49133A0B3B0B0218000000
+ - Name: .debug_info
+ Type: SHT_PROGBITS
+ AddressAlign: 0x1
+ Content: 8300000004000000000008012E0000000C00020000000000000029000000201600000000000006000000020E0000003F000000010209036838000000000000031A000000050404201600000000000006000000015600000000010305970000003F00000001040903A03800000000000000021E0000003F00000001010903A43800000000000000
+ - Name: .debug_line
+ Type: SHT_PROGBITS
+ AddressAlign: 0x1
+ Content: 3900000004001E000000010101FB0E0D0001010101000000010000010066696C652E63000000000000090220160000000000001405010A4C0202000101
+Symbols:
+ - Name: crtstuff.c
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: __CTOR_LIST__
+ Type: STT_OBJECT
+ Section: .ctors
+ Value: 0x26D0
+ - Name: __DTOR_LIST__
+ Type: STT_OBJECT
+ Section: .dtors
+ Value: 0x26E0
+ - Name: __TMC_LIST__
+ Type: STT_OBJECT
+ Section: .tm_clone_table
+ Value: 0x3870
+ - Name: deregister_tm_clones
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1510
+ - Name: register_tm_clones
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1540
+ - Name: __do_global_dtors_aux
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1580
+ - Name: completed.1
+ Type: STT_OBJECT
+ Section: .bss
+ Value: 0x3890
+ Size: 0x1
+ - Name: dtor_idx.0
+ Type: STT_OBJECT
+ Section: .bss
+ Value: 0x3898
+ Size: 0x8
+ - Name: frame_dummy
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1610
+ - Name: __dso_handle
+ Type: STT_OBJECT
+ Section: .data
+ Value: 0x3860
+ Other: [ STV_HIDDEN ]
+ - Name: file.c
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: f.function_global
+ Type: STT_OBJECT
+ Section: .bss
+ Value: 0x38A0
+ Size: 0x4
+ - Name: 'crtstuff.c (1)'
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: __CTOR_END__
+ Type: STT_OBJECT
+ Section: .ctors
+ Value: 0x26D8
+ - Name: __FRAME_END__
+ Type: STT_OBJECT
+ Section: .eh_frame
+ Value: 0x4C8
+ - Name: __do_global_ctors_aux
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1630
+ - Name: __TMC_END__
+ Type: STT_OBJECT
+ Section: .tm_clone_table
+ Value: 0x3870
+ Other: [ STV_HIDDEN ]
+ - Name: __DTOR_END__
+ Type: STT_OBJECT
+ Section: .dtors
+ Value: 0x26E8
+ Other: [ STV_HIDDEN ]
+ - Name: _init
+ Type: STT_FUNC
+ Section: .init
+ Value: 0x1674
+ Other: [ STV_HIDDEN ]
+ - Name: _fini
+ Type: STT_FUNC
+ Section: .fini
+ Value: 0x1698
+ Other: [ STV_HIDDEN ]
+ - Name: _GLOBAL_OFFSET_TABLE_
+ Section: .got.plt
+ Value: 0x3870
+ Other: [ STV_HIDDEN ]
+ - Name: _DYNAMIC
+ Section: .dynamic
+ Value: 0x26F0
+ 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: 0x1620
+ Size: 0x6
+ - Name: data_global
+ Type: STT_OBJECT
+ Section: .data
+ Binding: STB_GLOBAL
+ Value: 0x3868
+ Size: 0x4
+ - Name: bss_global
+ Type: STT_OBJECT
+ Section: .bss
+ Binding: STB_GLOBAL
+ Value: 0x38A4
+ 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: 0x1620
+ Size: 0x6
+ - Name: data_global
+ Type: STT_OBJECT
+ Section: .data
+ Binding: STB_GLOBAL
+ Value: 0x3868
+ Size: 0x4
+ - Name: bss_global
+ Type: STT_OBJECT
+ Section: .bss
+ Binding: STB_GLOBAL
+ Value: 0x38A4
+ Size: 0x4
+DWARF:
+ debug_str:
+ - f
+ - '/tmp/file.c'
+ - data_global
+ - int
+ - bss_global
+ - '/tmp'
+ - 'clang version 14.0.0 (https://github.com/llvm/llvm-project.git 5357a98c823a5262814e269db265b5d8e1f2c4f2)'
+ - function_global
+...
Index: llvm/test/DebugInfo/Symbolize/ELF/data-command-symtab.yaml
===================================================================
--- llvm/test/DebugInfo/Symbolize/ELF/data-command-symtab.yaml
+++ 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
Index: llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
===================================================================
--- llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
+++ 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->getLineInfoForDataAddress(ModuleOffset);
+ if (DL.Line != 0) {
+ Res.DeclFile = DL.FileName;
+ Res.DeclLine = DL.Line;
+ }
return Res;
}
Index: llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
===================================================================
--- llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
+++ 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();
}
Index: llvm/lib/DebugInfo/PDB/PDBContext.cpp
===================================================================
--- llvm/lib/DebugInfo/PDB/PDBContext.cpp
+++ llvm/lib/DebugInfo/PDB/PDBContext.cpp
@@ -64,6 +64,12 @@
return Result;
}
+DILineInfo
+PDBContext::getLineInfoForDataAddress(object::SectionedAddress Address) {
+ // Unimplemented.
+ return DILineInfo();
+}
+
DILineInfoTable
PDBContext::getLineInfoForAddressRange(object::SectionedAddress Address,
uint64_t Size,
Index: llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
===================================================================
--- llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ 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,58 @@
return R->second.second;
}
+void DWARFUnit::updateVariableDieMap(DWARFDie Die) {
+ for (DWARFDie Child : Die) {
+ if (isType(Child.getTag()))
+ continue;
+ updateVariableDieMap(Child);
+ }
+
+ if (Die.getTag() != DW_TAG_variable)
+ return;
+
+ Expected<DWARFLocationExpressionsVector> Locations =
+ Die.getLocations(DW_AT_location);
+ if (!Locations) {
+ // Missing DW_AT_location is fine here.
+ consumeError(Locations.takeError());
+ 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<object::SectionedAddress> Pointer =
+ getAddrOffsetSectionItem(DebugAddrOffset);
+ if (Pointer)
+ VariableDieMap[Pointer->Address] = Die;
+ }
+ }
+}
+
+DWARFDie DWARFUnit::getVariableForAddress(uint64_t Address) {
+ extractDIEsIfNeeded(false);
+
+ auto RootDie = getUnitDIE();
+
+ auto RootLookup = RootsParsedForVariables.insert(RootDie.getOffset());
+ if (RootLookup.second)
+ updateVariableDieMap(RootDie);
+
+ auto it = VariableDieMap.find(Address);
+ if (it == VariableDieMap.end())
+ return DWARFDie();
+ return it->second;
+}
+
void
DWARFUnit::getInlinedChainForAddress(uint64_t Address,
SmallVectorImpl<DWARFDie> &InlinedChain) {
Index: llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
===================================================================
--- llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -1033,7 +1033,19 @@
// First, get the offset of the compile unit.
uint64_t CUOffset = getDebugAranges()->findAddress(Address);
// Retrieve the compile unit.
- return getCompileUnitForOffset(CUOffset);
+ DWARFCompileUnit *OffsetCU = getCompileUnitForOffset(CUOffset);
+ if (OffsetCU)
+ return OffsetCU;
+
+ // Unfortunately, debug_aranges by default don't inclue global variables. If
+ // we failed to find the CU using aranges, try and search for variables as
+ // well.
+ for (std::unique_ptr<DWARFUnit> &CU : compile_units()) {
+ if (DWARFDie Die = CU->getVariableForAddress(Address)) {
+ return static_cast<DWARFCompileUnit *>(CU.get());
+ }
+ }
+ return nullptr;
}
DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address) {
@@ -1262,7 +1274,6 @@
DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address,
DILineInfoSpecifier Spec) {
DILineInfo Result;
-
DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
if (!CU)
return Result;
@@ -1277,6 +1288,22 @@
Spec.FLIKind, Result);
}
}
+
+ return Result;
+}
+
+DILineInfo
+DWARFContext::getLineInfoForDataAddress(object::SectionedAddress Address) {
+ DILineInfo Result;
+ DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
+ if (!CU)
+ return Result;
+
+ if (DWARFDie Die = CU->getVariableForAddress(Address.Address)) {
+ Result.FileName = Die.getDeclFile(FileLineInfoKind::AbsoluteFilePath);
+ Result.Line = Die.getDeclLine();
+ }
+
return Result;
}
Index: llvm/include/llvm/DebugInfo/PDB/PDBContext.h
===================================================================
--- llvm/include/llvm/DebugInfo/PDB/PDBContext.h
+++ llvm/include/llvm/DebugInfo/PDB/PDBContext.h
@@ -45,6 +45,8 @@
DILineInfo getLineInfoForAddress(
object::SectionedAddress Address,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+ DILineInfo
+ getLineInfoForDataAddress(object::SectionedAddress Address) override;
DILineInfoTable getLineInfoForAddressRange(
object::SectionedAddress Address, uint64_t Size,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
Index: llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
===================================================================
--- llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -9,6 +9,8 @@
#ifndef LLVM_DEBUGINFO_DWARF_DWARFUNIT_H
#define LLVM_DEBUGINFO_DWARF_DWARFUNIT_H
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
@@ -27,6 +29,7 @@
#include <cstdint>
#include <map>
#include <memory>
+#include <set>
#include <utility>
#include <vector>
@@ -240,6 +243,11 @@
/// std::map::upper_bound for address range lookup.
std::map<uint64_t, std::pair<uint64_t, DWARFDie>> AddrDieMap;
+ /// Map from the location (interpreted DW_AT_location) of a DW_TAG_variable,
+ /// to the DIE.
+ DenseMap<uint64_t, DWARFDie> VariableDieMap;
+ DenseSet<uint64_t> RootsParsedForVariables;
+
using die_iterator_range =
iterator_range<std::vector<DWARFDebugInfoEntry>::iterator>;
@@ -322,6 +330,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 +447,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.
Index: llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
===================================================================
--- llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
+++ llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
@@ -360,6 +360,8 @@
DILineInfo getLineInfoForAddress(
object::SectionedAddress Address,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+ DILineInfo
+ getLineInfoForDataAddress(object::SectionedAddress Address) override;
DILineInfoTable getLineInfoForAddressRange(
object::SectionedAddress Address, uint64_t Size,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
Index: llvm/include/llvm/DebugInfo/DIContext.h
===================================================================
--- llvm/include/llvm/DebugInfo/DIContext.h
+++ 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) {}
};
@@ -239,6 +241,8 @@
virtual DILineInfo getLineInfoForAddress(
object::SectionedAddress Address,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
+ virtual DILineInfo
+ getLineInfoForDataAddress(object::SectionedAddress Address) = 0;
virtual DILineInfoTable getLineInfoForAddressRange(
object::SectionedAddress Address, uint64_t Size,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits