Skip to content

Commit 0092dbc

Browse files
committed
[lldb] Fix lookup of .debug_loclists with split-dwarf
This patch fixes the lookup of locations in .debug_loclists, if they are split in a .dwp file. Mainly, we need to consider the cu index offsets. Reviewed By: jankratochvil Differential Revision: https://reviews.llvm.org/D107161
1 parent b1802d6 commit 0092dbc

File tree

2 files changed

+254
-4
lines changed

2 files changed

+254
-4
lines changed

lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -453,20 +453,33 @@ ParseListTableHeader(const llvm::DWARFDataExtractor &data, uint64_t offset,
453453
}
454454

455455
void DWARFUnit::SetLoclistsBase(dw_addr_t loclists_base) {
456+
uint64_t offset = 0;
457+
if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) {
458+
const auto *contribution = entry->getContribution(llvm::DW_SECT_LOCLISTS);
459+
if (!contribution) {
460+
GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
461+
"Failed to find location list contribution for CU with DWO Id "
462+
"0x%" PRIx64,
463+
this->GetDWOId());
464+
return;
465+
}
466+
offset += contribution->Offset;
467+
}
456468
m_loclists_base = loclists_base;
457469

458470
uint64_t header_size = llvm::DWARFListTableHeader::getHeaderSize(DWARF32);
459471
if (loclists_base < header_size)
460472
return;
461473

462474
m_loclist_table_header.emplace(".debug_loclists", "locations");
463-
uint64_t offset = loclists_base - header_size;
475+
offset += loclists_base - header_size;
464476
if (llvm::Error E = m_loclist_table_header->extract(
465477
m_dwarf.GetDWARFContext().getOrLoadLocListsData().GetAsLLVM(),
466478
&offset)) {
467479
GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
468-
"Failed to extract location list table at offset 0x%" PRIx64 ": %s",
469-
loclists_base, toString(std::move(E)).c_str());
480+
"Failed to extract location list table at offset 0x%" PRIx64
481+
" (location list base: 0x%" PRIx64 "): %s",
482+
offset, loclists_base, toString(std::move(E)).c_str());
470483
}
471484
}
472485

@@ -486,7 +499,8 @@ DWARFDataExtractor DWARFUnit::GetLocationData() const {
486499
const DWARFDataExtractor &data =
487500
GetVersion() >= 5 ? Ctx.getOrLoadLocListsData() : Ctx.getOrLoadLocData();
488501
if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) {
489-
if (const auto *contribution = entry->getContribution(llvm::DW_SECT_EXT_LOC))
502+
if (const auto *contribution = entry->getContribution(
503+
GetVersion() >= 5 ? llvm::DW_SECT_LOCLISTS : llvm::DW_SECT_EXT_LOC))
490504
return DWARFDataExtractor(data, contribution->Offset,
491505
contribution->Length);
492506
return DWARFDataExtractor();
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
## This tests if .debug_loclists.dwo are correctly read if they are part
2+
## of a dwp file.
3+
4+
# RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s --defsym MAIN=0 > %t
5+
# RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s > %t.dwp
6+
# RUN: %lldb %t -o "image lookup -v -s lookup_loclists" -o exit | FileCheck %s
7+
8+
# CHECK-LABEL: image lookup -v -s lookup_loclists
9+
# CHECK: Variable: id = {{.*}}, name = "x0", type = "int", location = DW_OP_reg0 RAX,
10+
# CHECK: Variable: id = {{.*}}, name = "x1", type = "int", location = DW_OP_reg1 RDX,
11+
12+
## This part is kept in both the main and the dwp file to be able to reference the offsets.
13+
loclists:
14+
nop
15+
nop
16+
.Ltmp1:
17+
lookup_loclists:
18+
nop
19+
.Ltmp2:
20+
nop
21+
.Ltmp3:
22+
nop
23+
.Lloclists_end:
24+
25+
## The main file.
26+
.ifdef MAIN
27+
.section .debug_abbrev,"",@progbits
28+
.byte 1 # Abbreviation Code
29+
.byte 74 # DW_TAG_compile_unit
30+
.byte 0 # DW_CHILDREN_no
31+
.byte 0x76 # DW_AT_dwo_name
32+
.byte 8 # DW_FORM_string
33+
.byte 115 # DW_AT_addr_base
34+
.byte 23 # DW_FORM_sec_offset
35+
.byte 17 # DW_AT_low_pc
36+
.byte 1 # DW_FORM_addr
37+
.byte 85 # DW_AT_ranges
38+
.byte 35 # DW_FORM_rnglistx
39+
.byte 116 # DW_AT_rnglists_base
40+
.byte 23 # DW_FORM_sec_offset
41+
.byte 0 # EOM(1)
42+
.byte 0 # EOM(2)
43+
.byte 0 # EOM(3)
44+
45+
.section .debug_info,"",@progbits
46+
.Lcu_begin0:
47+
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
48+
.Ldebug_info_start0:
49+
.short 5 # DWARF version number
50+
.byte 4 # DWARF Unit Type
51+
.byte 8 # Address Size (in bytes)
52+
.long .debug_abbrev # Offset Into Abbrev. Section
53+
.quad 1026699901672188186 # DWO id
54+
.byte 1 # Abbrev [1] DW_TAG_compile_unit
55+
.asciz "debug_loclists-dwp.dwo" # DW_AT_dwo_name
56+
.long .Laddr_table_base0 # DW_AT_addr_base
57+
.quad loclists # DW_AT_low_pc
58+
.byte 0 # DW_AT_ranges
59+
.long .Lskel_rnglists_table_base # DW_AT_rnglists_base
60+
.Ldebug_info_end0:
61+
.section .debug_rnglists,"",@progbits
62+
.long .Lskel_rnglist_table_end-.Lskel_rnglist_table_start # Length
63+
.Lskel_rnglist_table_start:
64+
.short 5 # Version
65+
.byte 8 # Address size
66+
.byte 0 # Segment selector size
67+
.long 1 # Offset entry count
68+
.Lskel_rnglists_table_base:
69+
.long .Lskel_ranges0-.Lskel_rnglists_table_base
70+
.Lskel_ranges0:
71+
.byte 7 # DW_RLE_start_length
72+
.quad loclists
73+
.uleb128 .Lloclists_end-loclists
74+
.byte 0 # DW_RLE_end_of_list
75+
.Lskel_rnglist_table_end:
76+
.section .debug_addr,"",@progbits
77+
.long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
78+
.Ldebug_addr_start0:
79+
.short 5 # DWARF version number
80+
.byte 8 # Address size
81+
.byte 0 # Segment selector size
82+
.Laddr_table_base0:
83+
.quad loclists
84+
.quad .Ltmp1
85+
.Ldebug_addr_end0:
86+
87+
.else
88+
## DWP file starts here.
89+
90+
.section .debug_loclists.dwo,"e",@progbits
91+
## Start the section with an unused table to check that the reading offset
92+
## of the real table is correctly adjusted.
93+
.long .LLLDummyEnd-.LLLDummyVersion # Length of Unit
94+
.LLLDummyVersion:
95+
.short 5 # Version
96+
.byte 8 # Address size
97+
.byte 0 # Segment selector size
98+
.long 0 # Offset entry count
99+
.byte 0 # DW_LLE_end_of_list
100+
.LLLDummyEnd:
101+
.LLLBegin:
102+
.long .Ldebug_loclist_table_end0-.Ldebug_loclist_table_start0 # Length
103+
.Ldebug_loclist_table_start0:
104+
.short 5 # Version
105+
.byte 8 # Address size
106+
.byte 0 # Segment selector size
107+
.long 2 # Offset entry count
108+
.Lloclists_table_base:
109+
.long .Ldebug_loc0-.Lloclists_table_base
110+
.long .Ldebug_loc1-.Lloclists_table_base
111+
.Ldebug_loc0:
112+
.byte 4 # DW_LLE_offset_pair
113+
.uleb128 loclists-loclists
114+
.uleb128 .Ltmp2-loclists
115+
.uleb128 1 # Expression size
116+
.byte 80 # super-register DW_OP_reg0
117+
.byte 0 # DW_LLE_end_of_list
118+
.Ldebug_loc1:
119+
.byte 3 # DW_LLE_startx_length
120+
.uleb128 1
121+
.uleb128 .Ltmp3-.Ltmp1
122+
.uleb128 1 # Expression size
123+
.byte 81 # super-register DW_OP_reg1
124+
.byte 0 # DW_LLE_end_of_list
125+
.Ldebug_loclist_table_end0:
126+
.LLLEnd:
127+
.section .debug_abbrev.dwo,"e",@progbits
128+
.LAbbrevBegin:
129+
.byte 1 # Abbreviation Code
130+
.byte 17 # DW_TAG_compile_unit
131+
.byte 1 # DW_CHILDREN_yes
132+
.byte 37 # DW_AT_producer
133+
.byte 8 # DW_FORM_string
134+
.byte 19 # DW_AT_language
135+
.byte 5 # DW_FORM_data2
136+
.byte 0 # EOM(1)
137+
.byte 0 # EOM(2)
138+
.byte 2 # Abbreviation Code
139+
.byte 46 # DW_TAG_subprogram
140+
.byte 1 # DW_CHILDREN_yes
141+
.byte 17 # DW_AT_low_pc
142+
.byte 27 # DW_FORM_addrx
143+
.byte 18 # DW_AT_high_pc
144+
.byte 6 # DW_FORM_data4
145+
.byte 3 # DW_AT_name
146+
.byte 8 # DW_FORM_string
147+
.byte 73 # DW_AT_type
148+
.byte 19 # DW_FORM_ref4
149+
.byte 0 # EOM(1)
150+
.byte 0 # EOM(2)
151+
.byte 3 # Abbreviation Code
152+
.byte 5 # DW_TAG_formal_parameter
153+
.byte 0 # DW_CHILDREN_no
154+
.byte 2 # DW_AT_location
155+
.byte 0x22 # DW_FORM_loclistx
156+
.byte 3 # DW_AT_name
157+
.byte 8 # DW_FORM_string
158+
.byte 73 # DW_AT_type
159+
.byte 19 # DW_FORM_ref4
160+
.byte 0 # EOM(1)
161+
.byte 0 # EOM(2)
162+
.byte 4 # Abbreviation Code
163+
.byte 36 # DW_TAG_base_type
164+
.byte 0 # DW_CHILDREN_no
165+
.byte 3 # DW_AT_name
166+
.byte 8 # DW_FORM_string
167+
.byte 62 # DW_AT_encoding
168+
.byte 11 # DW_FORM_data1
169+
.byte 11 # DW_AT_byte_size
170+
.byte 11 # DW_FORM_data1
171+
.byte 0 # EOM(1)
172+
.byte 0 # EOM(2)
173+
.byte 0 # EOM(3)
174+
.LAbbrevEnd:
175+
.section .debug_info.dwo,"e",@progbits
176+
.LCUBegin:
177+
.Lcu_begin1:
178+
.long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit
179+
.Ldebug_info_start1:
180+
.short 5 # DWARF version number
181+
.byte 5 # DWARF Unit Type
182+
.byte 8 # Address Size (in bytes)
183+
.long 0 # Offset Into Abbrev. Section
184+
.quad 1026699901672188186 # DWO id
185+
.byte 1 # Abbrev [1] DW_TAG_compile_unit
186+
.asciz "Hand-written DWARF" # DW_AT_producer
187+
.short 12 # DW_AT_language
188+
.byte 2 # Abbrev [2] DW_TAG_subprogram
189+
.byte 0 # DW_AT_low_pc
190+
.long .Lloclists_end-loclists # DW_AT_high_pc
191+
.asciz "loclists" # DW_AT_name
192+
.long .Lint # DW_AT_type
193+
.byte 3 # Abbrev [3] DW_TAG_formal_parameter
194+
.uleb128 0 # DW_AT_location
195+
.asciz "x0" # DW_AT_name
196+
.long .Lint # DW_AT_type
197+
.byte 3 # Abbrev [3] DW_TAG_formal_parameter
198+
.uleb128 1 # DW_AT_location
199+
.asciz "x1" # DW_AT_name
200+
.long .Lint # DW_AT_type
201+
.byte 0 # End Of Children Mark
202+
.Lint:
203+
.byte 4 # Abbrev [4] DW_TAG_base_type
204+
.asciz "int" # DW_AT_name
205+
.byte 5 # DW_AT_encoding
206+
.byte 4 # DW_AT_byte_size
207+
.byte 0 # End Of Children Mark
208+
.Ldebug_info_end1:
209+
.LCUEnd:
210+
.section .debug_cu_index, "", @progbits
211+
## Header:
212+
.short 5 # Version
213+
.short 0 # Padding
214+
.long 3 # Section count
215+
.long 1 # Unit count
216+
.long 2 # Slot count
217+
## Hash Table of Signatures:
218+
.quad 1026699901672188186
219+
.quad 0
220+
## Parallel Table of Indexes:
221+
.long 1
222+
.long 0
223+
## Table of Section Offsets:
224+
## Row 0:
225+
.long 1 # DW_SECT_INFO
226+
.long 3 # DW_SECT_ABBREV
227+
.long 5 # DW_SECT_LOCLISTS
228+
## Row 1:
229+
.long 0 # Offset in .debug_info.dwo
230+
.long 0 # Offset in .debug_abbrev.dwo
231+
.long .LLLBegin-.debug_loclists.dwo # Offset in .debug_loclists.dwo
232+
## Table of Section Sizes:
233+
.long .LCUEnd-.LCUBegin # Size in .debug_info.dwo
234+
.long .LAbbrevEnd-.LAbbrevBegin # Size in .debug_abbrev.dwo
235+
.long .LLLEnd-.LLLBegin # Size in .debug_loclists.dwo
236+
.endif

0 commit comments

Comments
 (0)