Branch data Line data Source code
1 : : /* Read DWARF package file index sections.
2 : : Copyright (c) 2023 Meta Platforms, Inc. and affiliates.
3 : : This file is part of elfutils.
4 : :
5 : : This file is free software; you can redistribute it and/or modify
6 : : it under the terms of either
7 : :
8 : : * the GNU Lesser General Public License as published by the Free
9 : : Software Foundation; either version 3 of the License, or (at
10 : : your option) any later version
11 : :
12 : : or
13 : :
14 : : * the GNU General Public License as published by the Free
15 : : Software Foundation; either version 2 of the License, or (at
16 : : your option) any later version
17 : :
18 : : or both in parallel, as here.
19 : :
20 : : elfutils is distributed in the hope that it will be useful, but
21 : : WITHOUT ANY WARRANTY; without even the implied warranty of
22 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 : : General Public License for more details.
24 : :
25 : : You should have received copies of the GNU General Public License and
26 : : the GNU Lesser General Public License along with this program. If
27 : : not, see <http://www.gnu.org/licenses/>. */
28 : :
29 : : #ifdef HAVE_CONFIG_H
30 : : # include <config.h>
31 : : #endif
32 : :
33 : : #include <assert.h>
34 : :
35 : : #include "libdwP.h"
36 : :
37 : : static Dwarf_Package_Index *
38 : 26 : __libdw_read_package_index (Dwarf *dbg, bool tu)
39 : : {
40 : 26 : Elf_Data *data;
41 [ + + ]: 26 : if (tu)
42 : 9 : data = dbg->sectiondata[IDX_debug_tu_index];
43 : : else
44 : 17 : data = dbg->sectiondata[IDX_debug_cu_index];
45 : :
46 : : /* We need at least 16 bytes for the header. */
47 [ - + - + ]: 26 : if (data == NULL || data->d_size < 16)
48 : : {
49 : 0 : invalid:
50 : 0 : __libdw_seterrno (DWARF_E_INVALID_DWARF);
51 : 0 : return NULL;
52 : : }
53 : :
54 : 26 : const unsigned char *datap = data->d_buf;
55 : 26 : const unsigned char *endp = datap + data->d_size;
56 : 26 : uint16_t version;
57 : : /* In GNU DebugFission for DWARF 4, the version is 2 as a uword. In the
58 : : standardized DWARF 5 format, it is a uhalf followed by a padding uhalf.
59 : : Check for both. */
60 [ - + + + ]: 26 : if (read_4ubyte_unaligned (dbg, datap) == 2)
61 : : version = 2;
62 : : else
63 : : {
64 [ - + ]: 14 : version = read_2ubyte_unaligned (dbg, datap);
65 [ - + ]: 14 : if (version != 5)
66 : : {
67 : 0 : __libdw_seterrno (DWARF_E_VERSION);
68 : 0 : return NULL;
69 : : }
70 : : }
71 : 26 : datap += 4;
72 [ - + ]: 26 : uint32_t section_count = read_4ubyte_unaligned_inc (dbg, datap);
73 [ - + ]: 26 : uint32_t unit_count = read_4ubyte_unaligned_inc (dbg, datap);
74 [ - + ]: 26 : uint32_t slot_count = read_4ubyte_unaligned_inc (dbg, datap);
75 : :
76 : : /* The specification has a stricter requirement that
77 : : slot_count > 3 * unit_count / 2, but this is enough for us. */
78 [ - + ]: 26 : if (slot_count < unit_count)
79 : 0 : goto invalid;
80 : :
81 : : /* After the header, the section must contain:
82 : :
83 : : 8 byte signature per hash table slot
84 : : + 4 byte index per hash table slot
85 : : + Section offset table with 1 header row, 1 row per unit, 1 column per
86 : : section, 4 bytes per field
87 : : + Section size table with 1 row per unit, 1 column per section, 4 bytes
88 : : per field
89 : :
90 : : We have to be careful about overflow when checking this. */
91 : 26 : const unsigned char *hash_table = datap;
92 [ - + ]: 26 : if ((size_t) (endp - hash_table) < (uint64_t) slot_count * 12)
93 : 0 : goto invalid;
94 : 26 : const unsigned char *indices = hash_table + (size_t) slot_count * 8;
95 : 26 : const unsigned char *sections = indices + (size_t) slot_count * 4;
96 [ - + ]: 26 : if ((size_t) (endp - sections) < (uint64_t) section_count * 4)
97 : 0 : goto invalid;
98 : 26 : const unsigned char *section_offsets = sections + (size_t) section_count * 4;
99 [ + - ]: 26 : if ((uint64_t) unit_count * section_count > UINT64_MAX / 8
100 : 26 : || ((size_t) (endp - section_offsets)
101 [ - + ]: 26 : < (uint64_t) unit_count * section_count * 8))
102 : 0 : goto invalid;
103 : 26 : const unsigned char *section_sizes
104 : 26 : = section_offsets + (uint64_t) unit_count * section_count * 4;
105 : :
106 : 26 : Dwarf_Package_Index *index = malloc (sizeof (*index));
107 [ - + ]: 26 : if (index == NULL)
108 : : {
109 : 0 : __libdw_seterrno (DWARF_E_NOMEM);
110 : 0 : return NULL;
111 : : }
112 : :
113 : 26 : index->dbg = dbg;
114 : : /* Set absent sections to UINT32_MAX. */
115 : 26 : for (size_t i = 0;
116 [ + + ]: 234 : i < sizeof (index->sections) / sizeof (index->sections[0]); i++)
117 : 208 : index->sections[i] = UINT32_MAX;
118 [ + + ]: 196 : for (size_t i = 0; i < section_count; i++)
119 : : {
120 [ - + ]: 170 : uint32_t section = read_4ubyte_unaligned (dbg, sections + i * 4);
121 : : /* 2 is DW_SECT_TYPES in version 2 and reserved in version 5. We ignore
122 : : it for version 5.
123 : : 5 is DW_SECT_LOC in version 2 and DW_SECT_LOCLISTS in version 5. We
124 : : use the same index for both.
125 : : 7 is DW_SECT_MACINFO in version 2 and DW_SECT_MACRO in version 5. We
126 : : use the same index for both.
127 : : 8 is DW_SECT_MACRO in version 2 and DW_SECT_RNGLISTS in version 5. We
128 : : use the same index for version 2's DW_SECT_MACRO as version 2's
129 : : DW_SECT_MACINFO/version 5's DW_SECT_MACRO.
130 : : We ignore unknown sections. */
131 [ - + ]: 170 : if (section == 0)
132 : 0 : continue;
133 [ + + ]: 170 : if (version == 2)
134 : : {
135 [ - + ]: 72 : if (section > 8)
136 : 0 : continue;
137 [ + + ]: 72 : else if (section == 8)
138 : 170 : section = DW_SECT_MACRO;
139 : : }
140 : 98 : else if (section == 2
141 : 98 : || (section
142 [ - + ]: 98 : > sizeof (index->sections) / sizeof (index->sections[0])))
143 : 0 : continue;
144 : 170 : index->sections[section - 1] = i;
145 : : }
146 : :
147 : : /* DW_SECT_INFO (or DW_SECT_TYPES for DWARF 4 type units) and DW_SECT_ABBREV
148 : : are required. */
149 [ + + + + ]: 26 : if (((!tu || dbg->sectiondata[IDX_debug_types] == NULL)
150 [ + - ]: 24 : && index->sections[DW_SECT_INFO - 1] == UINT32_MAX)
151 [ + + + + ]: 26 : || (tu && dbg->sectiondata[IDX_debug_types] != NULL
152 [ + - ]: 2 : && index->sections[DW_SECT_TYPES - 1] == UINT32_MAX)
153 [ - + ]: 26 : || index->sections[DW_SECT_ABBREV - 1] == UINT32_MAX)
154 : : {
155 : 0 : free (index);
156 : 0 : __libdw_seterrno (DWARF_E_INVALID_DWARF);
157 : 0 : return NULL;
158 : : }
159 : :
160 : 26 : index->section_count = section_count;
161 : 26 : index->unit_count = unit_count;
162 : 26 : index->slot_count = slot_count;
163 : 26 : index->last_unit_found = 0;
164 : 26 : index->hash_table = hash_table;
165 : 26 : index->indices = indices;
166 : 26 : index->section_offsets = section_offsets;
167 : 26 : index->section_sizes = section_sizes;
168 : 26 : index->debug_info_offsets = NULL;
169 : :
170 : 26 : return index;
171 : : }
172 : :
173 : : static Dwarf_Package_Index *
174 : 102 : __libdw_package_index (Dwarf *dbg, bool tu)
175 : : {
176 [ + + + + ]: 102 : if (tu && dbg->tu_index != NULL)
177 : : return dbg->tu_index;
178 [ + + ]: 84 : else if (!tu && dbg->cu_index != NULL)
179 : : return dbg->cu_index;
180 : :
181 : 26 : Dwarf_Package_Index *index = __libdw_read_package_index (dbg, tu);
182 [ - + ]: 26 : if (index == NULL)
183 : : return NULL;
184 : :
185 : : /* Offsets in the section offset table are 32-bit unsigned integers. In
186 : : practice, the .debug_info.dwo section for very large executables can be
187 : : larger than 4GB. GNU dwp as of binutils 2.41 and llvm-dwp before LLVM 15
188 : : both accidentally truncate offsets larger than 4GB.
189 : :
190 : : LLVM 15 detects the overflow and errors out instead; see LLVM commit
191 : : f8df8114715b ("[DWP][DWARF] Detect and error on debug info offset
192 : : overflow"). However, lldb in LLVM 16 supports using dwp files with
193 : : truncated offsets by recovering them directly from the unit headers in the
194 : : .debug_info.dwo section; see LLVM commit c0db06227721 ("[DWARFLibrary] Add
195 : : support to re-construct cu-index"). Since LLVM 17, the overflow error can
196 : : be turned into a warning instead; see LLVM commit 53a483cee801 ("[DWP] add
197 : : overflow check for llvm-dwp tools if offset overflow").
198 : :
199 : : LLVM's support for > 4GB offsets is effectively an extension to the DWARF
200 : : package file format, which we implement here. The strategy is to walk the
201 : : unit headers in .debug_info.dwo in lockstep with the DW_SECT_INFO columns
202 : : in the section offset tables. As long as they are in the same order
203 : : (which they are in practice for both GNU dwp and llvm-dwp), we can
204 : : correlate the truncated offset and produce a corrected array of offsets.
205 : :
206 : : Note that this will be fixed properly in DWARF 6:
207 : : https://dwarfstd.org/issues/220708.2.html. */
208 [ + + ]: 26 : if (index->sections[DW_SECT_INFO - 1] != UINT32_MAX
209 [ - + ]: 24 : && dbg->sectiondata[IDX_debug_info]->d_size > UINT32_MAX)
210 : : {
211 : 0 : Dwarf_Package_Index *cu_index, *tu_index = NULL;
212 [ # # ]: 0 : if (tu)
213 : : {
214 : 0 : tu_index = index;
215 [ # # ]: 0 : assert (dbg->cu_index == NULL);
216 : 0 : cu_index = __libdw_read_package_index (dbg, false);
217 [ # # ]: 0 : if (cu_index == NULL)
218 : : {
219 : 0 : free(index);
220 : 0 : return NULL;
221 : : }
222 : : }
223 : : else
224 : : {
225 : 0 : cu_index = index;
226 [ # # ]: 0 : if (dbg->sectiondata[IDX_debug_tu_index] != NULL
227 [ # # ]: 0 : && dbg->sectiondata[IDX_debug_types] == NULL)
228 : : {
229 [ # # ]: 0 : assert (dbg->tu_index == NULL);
230 : 0 : tu_index = __libdw_read_package_index (dbg, true);
231 [ # # ]: 0 : if (tu_index == NULL)
232 : : {
233 : 0 : free(index);
234 : 0 : return NULL;
235 : : }
236 : : }
237 : : }
238 : :
239 : 0 : cu_index->debug_info_offsets = malloc (cu_index->unit_count
240 : : * sizeof (Dwarf_Off));
241 [ # # ]: 0 : if (cu_index->debug_info_offsets == NULL)
242 : : {
243 : 0 : free (tu_index);
244 : 0 : free (cu_index);
245 : 0 : __libdw_seterrno (DWARF_E_NOMEM);
246 : 0 : return NULL;
247 : : }
248 [ # # ]: 0 : if (tu_index != NULL)
249 : : {
250 : 0 : tu_index->debug_info_offsets = malloc (tu_index->unit_count
251 : : * sizeof (Dwarf_Off));
252 [ # # ]: 0 : if (tu_index->debug_info_offsets == NULL)
253 : : {
254 : 0 : free (tu_index);
255 : 0 : free (cu_index->debug_info_offsets);
256 : 0 : free (cu_index);
257 : 0 : __libdw_seterrno (DWARF_E_NOMEM);
258 : 0 : return NULL;
259 : : }
260 : : }
261 : :
262 : 0 : Dwarf_Off off = 0;
263 : 0 : uint32_t cui = 0, tui = 0;
264 : 0 : uint32_t cu_count = cu_index->unit_count;
265 : 0 : const unsigned char *cu_offset
266 : 0 : = cu_index->section_offsets + cu_index->sections[DW_SECT_INFO - 1] * 4;
267 : 0 : uint32_t tu_count = 0;
268 : 0 : const unsigned char *tu_offset = NULL;
269 [ # # ]: 0 : if (tu_index != NULL)
270 : : {
271 : 0 : tu_count = tu_index->unit_count;
272 : 0 : tu_offset = tu_index->section_offsets
273 : 0 : + tu_index->sections[DW_SECT_INFO - 1] * 4;
274 : : }
275 [ # # ]: 0 : while (cui < cu_count || tui < tu_count)
276 : : {
277 : 0 : Dwarf_Off next_off;
278 : 0 : uint8_t unit_type;
279 [ # # ]: 0 : if (__libdw_next_unit (dbg, false, off, &next_off, NULL, NULL,
280 : : &unit_type, NULL, NULL, NULL, NULL, NULL)
281 : : != 0)
282 : : {
283 : 0 : not_sorted:
284 : 0 : free (cu_index->debug_info_offsets);
285 : 0 : cu_index->debug_info_offsets = NULL;
286 [ # # ]: 0 : if (tu_index != NULL)
287 : : {
288 : 0 : free (tu_index->debug_info_offsets);
289 : 0 : tu_index->debug_info_offsets = NULL;
290 : : }
291 : 0 : break;
292 : : }
293 [ # # # # ]: 0 : if (unit_type != DW_UT_split_type && cui < cu_count)
294 : : {
295 [ # # # # ]: 0 : if ((off & UINT32_MAX) != read_4ubyte_unaligned (dbg, cu_offset))
296 : 0 : goto not_sorted;
297 : 0 : cu_index->debug_info_offsets[cui++] = off;
298 : 0 : cu_offset += cu_index->section_count * 4;
299 : : }
300 [ # # ]: 0 : else if (unit_type == DW_UT_split_type && tu_index != NULL
301 [ # # ]: 0 : && tui < tu_count)
302 : : {
303 [ # # # # ]: 0 : if ((off & UINT32_MAX) != read_4ubyte_unaligned (dbg, tu_offset))
304 : 0 : goto not_sorted;
305 : 0 : tu_index->debug_info_offsets[tui++] = off;
306 : 0 : tu_offset += tu_index->section_count * 4;
307 : : }
308 : 0 : off = next_off;
309 : : }
310 : :
311 [ # # ]: 0 : if (tu)
312 : 0 : dbg->cu_index = cu_index;
313 [ # # ]: 0 : else if (tu_index != NULL)
314 : 0 : dbg->tu_index = tu_index;
315 : : }
316 : :
317 [ + + ]: 26 : if (tu)
318 : 9 : dbg->tu_index = index;
319 : : else
320 : 17 : dbg->cu_index = index;
321 : : return index;
322 : : }
323 : :
324 : : static int
325 : 33 : __libdw_dwp_unit_row (Dwarf_Package_Index *index, uint64_t unit_id,
326 : : uint32_t *unit_rowp)
327 : : {
328 [ + - ]: 33 : if (index == NULL)
329 : : return -1;
330 : :
331 : 33 : uint32_t hash = unit_id;
332 : 33 : uint32_t hash2 = (unit_id >> 32) | 1;
333 : : /* Only check each slot once. */
334 [ + - ]: 33 : for (uint32_t n = index->slot_count; n-- > 0; )
335 : : {
336 : 33 : size_t slot = hash & (index->slot_count - 1);
337 [ - + ]: 33 : uint64_t sig = read_8ubyte_unaligned (index->dbg,
338 : : index->hash_table + slot * 8);
339 [ + - ]: 33 : if (sig == unit_id)
340 : : {
341 [ - + ]: 33 : uint32_t row = read_4ubyte_unaligned (index->dbg,
342 : : index->indices + slot * 4);
343 [ - + ]: 33 : if (row > index->unit_count)
344 : : {
345 : 0 : __libdw_seterrno (DWARF_E_INVALID_DWARF);
346 : 0 : return -1;
347 : : }
348 : 33 : *unit_rowp = row;
349 : 33 : return 0;
350 : : }
351 [ # # ]: 0 : else if (sig == 0
352 [ # # ]: 0 : && read_4ubyte_unaligned (index->dbg,
353 [ # # ]: 0 : index->indices + slot * 4) == 0)
354 : : break;
355 : 0 : hash += hash2;
356 : : }
357 : 0 : *unit_rowp = 0;
358 : 0 : return 0;
359 : : }
360 : :
361 : : static int
362 : 3204 : __libdw_dwp_section_info (Dwarf_Package_Index *index, uint32_t unit_row,
363 : : unsigned int section, Dwarf_Off *offsetp,
364 : : Dwarf_Off *sizep)
365 : : {
366 [ + - ]: 3204 : if (index == NULL)
367 : : return -1;
368 [ - + ]: 3204 : if (unit_row == 0)
369 : : {
370 : 0 : __libdw_seterrno (DWARF_E_INVALID_DWARF);
371 : 0 : return -1;
372 : : }
373 [ + + ]: 3204 : if (index->sections[section - 1] == UINT32_MAX)
374 : : {
375 [ + - ]: 25 : if (offsetp != NULL)
376 : 25 : *offsetp = 0;
377 [ + - ]: 25 : if (sizep != NULL)
378 : 25 : *sizep = 0;
379 : 25 : return 0;
380 : : }
381 : 3179 : size_t i = (size_t)(unit_row - 1) * index->section_count
382 : 3179 : + index->sections[section - 1];
383 [ + - ]: 3179 : if (offsetp != NULL)
384 : : {
385 [ + + - + ]: 3179 : if (section == DW_SECT_INFO && index->debug_info_offsets != NULL)
386 : 0 : *offsetp = index->debug_info_offsets[unit_row - 1];
387 : : else
388 [ - + ]: 3179 : *offsetp = read_4ubyte_unaligned (index->dbg,
389 : : index->section_offsets + i * 4);
390 : : }
391 [ + + ]: 3179 : if (sizep != NULL)
392 [ - + ]: 164 : *sizep = read_4ubyte_unaligned (index->dbg,
393 : : index->section_sizes + i * 4);
394 : : return 0;
395 : : }
396 : :
397 : : int
398 : : internal_function
399 : 39650 : __libdw_dwp_find_unit (Dwarf *dbg, bool debug_types, Dwarf_Off off,
400 : : uint16_t version, uint8_t unit_type, uint64_t unit_id8,
401 : : uint32_t *unit_rowp, Dwarf_Off *abbrev_offsetp)
402 : : {
403 : 39650 : if (version >= 5
404 [ + + + + ]: 39650 : && unit_type != DW_UT_split_compile && unit_type != DW_UT_split_type)
405 : : {
406 : 38862 : not_dwp:
407 : 39581 : *unit_rowp = 0;
408 : 39581 : *abbrev_offsetp = 0;
409 : 39581 : return 0;
410 : : }
411 : 788 : bool tu = unit_type == DW_UT_split_type || debug_types;
412 [ + + + + ]: 1540 : if (dbg->sectiondata[tu ? IDX_debug_tu_index : IDX_debug_cu_index] == NULL)
413 : 719 : goto not_dwp;
414 : 69 : Dwarf_Package_Index *index = __libdw_package_index (dbg, tu);
415 [ - + ]: 69 : if (index == NULL)
416 : : return -1;
417 : :
418 : : /* This is always called for ascending offsets. The most obvious way for a
419 : : producer to generate the section offset table is sorted by offset; both
420 : : GNU dwp and llvm-dwp do this. In this common case, we can avoid the full
421 : : lookup. */
422 [ + - ]: 69 : if (index->last_unit_found < index->unit_count)
423 : : {
424 : 69 : Dwarf_Off offset, size;
425 [ + + - + ]: 134 : if (__libdw_dwp_section_info (index, index->last_unit_found + 1,
426 : : debug_types ? DW_SECT_TYPES : DW_SECT_INFO,
427 : : &offset, &size) != 0)
428 : 0 : return -1;
429 [ + - + - ]: 69 : if (offset <= off && off - offset < size)
430 : : {
431 : 69 : *unit_rowp = ++index->last_unit_found;
432 : 69 : goto done;
433 : : }
434 : : else
435 : : /* The units are not sorted. Don't try again. */
436 : 0 : index->last_unit_found = index->unit_count;
437 : : }
438 : :
439 [ # # ]: 0 : if (version >= 5 || debug_types)
440 : : {
441 : : /* In DWARF 5 and in type units, the unit signature is available in the
442 : : unit header. */
443 [ # # ]: 0 : if (__libdw_dwp_unit_row (index, unit_id8, unit_rowp) != 0)
444 : : return -1;
445 : : }
446 : : else
447 : : {
448 : : /* In DWARF 4 compilation units, the unit signature is an attribute. We
449 : : can't parse attributes in the split unit until we get the abbreviation
450 : : table offset from the package index, which is a chicken-and-egg
451 : : problem. We could get the signature from the skeleton unit, but that
452 : : may not be available.
453 : :
454 : : Instead, we resort to a linear scan through the section offset table.
455 : : Finding all units is therefore quadratic in the number of units.
456 : : However, this will likely never be needed in practice because of the
457 : : sorted fast path above. If this ceases to be the case, we can try to
458 : : plumb through the skeleton unit's signature when it is available, or
459 : : build a sorted lookup table for binary search. */
460 [ # # ]: 0 : if (index->sections[DW_SECT_INFO - 1] == UINT32_MAX)
461 : : {
462 : 0 : __libdw_seterrno (DWARF_E_INVALID_DWARF);
463 : 0 : return -1;
464 : : }
465 [ # # ]: 0 : for (uint32_t i = 0; i < index->unit_count; i++)
466 : : {
467 : 0 : Dwarf_Off offset, size;
468 : 0 : __libdw_dwp_section_info (index, i + 1, DW_SECT_INFO, &offset,
469 : : &size);
470 [ # # # # ]: 0 : if (offset <= off && off - offset < size)
471 : : {
472 : 0 : *unit_rowp = i + 1;
473 : 0 : goto done;
474 : : }
475 : : }
476 : 0 : __libdw_seterrno (DWARF_E_INVALID_DWARF);
477 : 0 : return -1;
478 : : }
479 : :
480 : 69 : done:
481 : 69 : return __libdw_dwp_section_info (index, *unit_rowp, DW_SECT_ABBREV,
482 : : abbrev_offsetp, NULL);
483 : : }
484 : :
485 : : Dwarf_CU *
486 : : internal_function
487 : 33 : __libdw_dwp_findcu_id (Dwarf *dbg, uint64_t unit_id8)
488 : : {
489 : 33 : Dwarf_Package_Index *index = __libdw_package_index (dbg, false);
490 : 33 : uint32_t unit_row;
491 : 33 : Dwarf_Off offset;
492 : 33 : Dwarf_CU *cu;
493 [ + - ]: 33 : if (__libdw_dwp_unit_row (index, unit_id8, &unit_row) == 0
494 [ + - ]: 33 : && __libdw_dwp_section_info (index, unit_row, DW_SECT_INFO, &offset,
495 : : NULL) == 0
496 [ + - ]: 33 : && (cu = __libdw_findcu (dbg, offset, false)) != NULL
497 [ + - ]: 33 : && cu->unit_type == DW_UT_split_compile
498 [ - + ]: 33 : && cu->unit_id8 == unit_id8)
499 : : return cu;
500 : : else
501 : 0 : return NULL;
502 : : }
503 : :
504 : : int
505 : 294346 : dwarf_cu_dwp_section_info (Dwarf_CU *cu, unsigned int section,
506 : : Dwarf_Off *offsetp, Dwarf_Off *sizep)
507 : : {
508 [ - + ]: 294346 : if (cu == NULL)
509 : : return -1;
510 [ - + ]: 294346 : if (section < DW_SECT_INFO || section > DW_SECT_RNGLISTS)
511 : : {
512 : 0 : __libdw_seterrno (DWARF_E_UNKNOWN_SECTION);
513 : 0 : return -1;
514 : : }
515 [ + + ]: 294346 : if (cu->dwp_row == 0)
516 : : {
517 [ + - ]: 291313 : if (offsetp != NULL)
518 : 291313 : *offsetp = 0;
519 [ - + ]: 291313 : if (sizep != NULL)
520 : 0 : *sizep = 0;
521 : 291313 : return 0;
522 : : }
523 : : else
524 : : {
525 : 9099 : Dwarf_Package_Index *index
526 [ + + ]: 3033 : = cu->unit_type == DW_UT_split_compile
527 : 3033 : ? cu->dbg->cu_index : cu->dbg->tu_index;
528 : 3033 : return __libdw_dwp_section_info (index, cu->dwp_row, section, offsetp,
529 : : sizep);
530 : : }
531 : : }
532 : : INTDEF(dwarf_cu_dwp_section_info)
|