Branch data Line data Source code
1 : : /* Return line number information of CU.
2 : : Copyright (C) 2004-2010, 2013, 2014, 2015, 2016, 2018 Red Hat, Inc.
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 : : #include <stdlib.h>
35 : : #include <string.h>
36 : :
37 : : #include "dwarf.h"
38 : : #include "libdwP.h"
39 : : #include "eu-search.h"
40 : :
41 : :
42 : : struct filelist
43 : : {
44 : : Dwarf_Fileinfo info;
45 : : struct filelist *next;
46 : : };
47 : :
48 : : struct linelist
49 : : {
50 : : Dwarf_Line line;
51 : : struct linelist *next;
52 : : size_t sequence;
53 : : };
54 : :
55 : : struct dirlist
56 : : {
57 : : const char *dir;
58 : : size_t len;
59 : : };
60 : :
61 : : /* Compare by Dwarf_Line.addr, given pointers into an array of pointers. */
62 : : static int
63 : 3819410 : compare_lines (const void *a, const void *b)
64 : : {
65 : 3819410 : struct linelist *const *p1 = a;
66 : 3819410 : struct linelist *const *p2 = b;
67 : 3819410 : struct linelist *list1 = *p1;
68 : 3819410 : struct linelist *list2 = *p2;
69 : 3819410 : Dwarf_Line *line1 = &list1->line;
70 : 3819410 : Dwarf_Line *line2 = &list2->line;
71 : :
72 [ + + ]: 3819410 : if (line1->addr != line2->addr)
73 [ + + ]: 3452192 : return (line1->addr < line2->addr) ? -1 : 1;
74 : :
75 : : /* An end_sequence marker precedes a normal record at the same address. */
76 [ + + ]: 367218 : if (line1->end_sequence != line2->end_sequence)
77 : 556 : return line2->end_sequence - line1->end_sequence;
78 : :
79 : : /* Otherwise, the linelist sequence maintains a stable sort. */
80 : 366662 : return (list1->sequence < list2->sequence) ? -1
81 [ - + ]: 366662 : : (list1->sequence > list2->sequence) ? 1
82 : 0 : : 0;
83 : : }
84 : :
85 : : /* Decoded .debug_line program header. */
86 : : struct line_header
87 : : {
88 : : /* Header entries */
89 : : Dwarf_Word unit_length;
90 : : unsigned int length;
91 : : uint_fast16_t version;
92 : : size_t line_address_size;
93 : : size_t segment_selector_size;
94 : : Dwarf_Word header_length;
95 : : const unsigned char *header_start;
96 : : uint_fast8_t minimum_instr_len;
97 : : uint_fast8_t max_ops_per_instr;
98 : : uint_fast8_t default_is_stmt;
99 : : int_fast8_t line_base;
100 : : uint_fast8_t line_range;
101 : : uint_fast8_t opcode_base;
102 : : const uint8_t *standard_opcode_lengths;
103 : : unsigned int debug_str_offset; /* CUBIN only */
104 : : size_t files_start;
105 : : };
106 : :
107 : : struct line_state
108 : : {
109 : : Dwarf_Word addr;
110 : : unsigned int op_index;
111 : : unsigned int file;
112 : : int64_t line;
113 : : unsigned int column;
114 : : uint_fast8_t is_stmt;
115 : : bool basic_block;
116 : : bool prologue_end;
117 : : bool epilogue_begin;
118 : : unsigned int isa;
119 : : unsigned int discriminator;
120 : : struct linelist *linelist;
121 : : size_t nlinelist;
122 : : unsigned int end_sequence;
123 : : unsigned int context;
124 : : unsigned int function_name;
125 : : };
126 : :
127 : : static inline void
128 : 645092 : run_advance_pc (struct line_state *state, unsigned int op_advance,
129 : : uint_fast8_t minimum_instr_len, uint_fast8_t max_ops_per_instr)
130 : : {
131 : 645092 : state->addr += minimum_instr_len * ((state->op_index + op_advance)
132 : 645092 : / max_ops_per_instr);
133 : 645092 : state->op_index = (state->op_index + op_advance) % max_ops_per_instr;
134 : 56714 : }
135 : :
136 : : static inline bool
137 : 805962 : add_new_line (struct line_state *state, struct linelist *new_line)
138 : : {
139 : : /* Set the line information. For some fields we use bitfields,
140 : : so we would lose information if the encoded values are too large.
141 : : Check just for paranoia, and call the data "invalid" if it
142 : : violates our assumptions on reasonable limits for the values. */
143 : 805962 : new_line->next = state->linelist;
144 : 805962 : new_line->sequence = state->nlinelist;
145 : 805962 : state->linelist = new_line;
146 : 805962 : ++(state->nlinelist);
147 : :
148 : : /* Set the line information. For some fields we use bitfields,
149 : : so we would lose information if the encoded values are too large.
150 : : Check just for paranoia, and call the data "invalid" if it
151 : : violates our assumptions on reasonable limits for the values. */
152 : : #define SET(field) \
153 : : do { \
154 : : new_line->line.field = state->field; \
155 : : if (unlikely (new_line->line.field != state->field)) \
156 : : return true; \
157 : : } while (0)
158 : :
159 : : /* Same as above, but don't flag as "invalid" just use truncated
160 : : value. Used for discriminator for which llvm might use a value
161 : : that won't fit 24 bits. */
162 : : #define SETX(field) \
163 : : new_line->line.field = state->field; \
164 : :
165 : 805962 : SET (addr);
166 [ - + ]: 805962 : SET (op_index);
167 : 805962 : SET (file);
168 [ - + ]: 805962 : SET (line);
169 [ - + ]: 805962 : SET (column);
170 [ - + ]: 805962 : SET (is_stmt);
171 : 805962 : SET (basic_block);
172 [ - + ]: 805962 : SET (end_sequence);
173 : 805962 : SET (prologue_end);
174 : 805962 : SET (epilogue_begin);
175 [ - + ]: 805962 : SET (isa);
176 : 805962 : SETX (discriminator);
177 : 805962 : SET (context);
178 : 805962 : SET (function_name);
179 : :
180 : : #undef SET
181 : :
182 : : return false;
183 : : }
184 : :
185 : : /* Read the .debug_line program header. Return 0 if sucessful, otherwise set
186 : : libdw errno and return -1. */
187 : :
188 : : static int
189 : 55250 : read_line_header (Dwarf *dbg, unsigned address_size,
190 : : const unsigned char *linep, const unsigned char *lineendp,
191 : : struct line_header *lh)
192 : : {
193 : 55250 : const unsigned char *line_start = linep;
194 : :
195 [ - + ]: 55250 : if (unlikely (linep + 4 > lineendp))
196 : 0 : goto invalid_data;
197 : :
198 [ + + ]: 55250 : lh->unit_length = read_4ubyte_unaligned_inc (dbg, linep);
199 : 55250 : lh->length = 4;
200 [ - + ]: 55250 : if (unlikely (lh->unit_length == DWARF3_LENGTH_64_BIT))
201 : : {
202 [ # # ]: 0 : if (unlikely (linep + 8 > lineendp))
203 : 0 : goto invalid_data;
204 [ # # ]: 0 : lh->unit_length = read_8ubyte_unaligned_inc (dbg, linep);
205 : 0 : lh->length = 8;
206 : : }
207 : :
208 : : /* Check whether we have enough room in the section. */
209 [ - + ]: 55250 : if (unlikely (lh->unit_length > (size_t) (lineendp - linep)))
210 : 0 : goto invalid_data;
211 : 55250 : lineendp = linep + lh->unit_length;
212 : :
213 : : /* The next element of the header is the version identifier. */
214 [ - + ]: 55250 : if ((size_t) (lineendp - linep) < 2)
215 : 0 : goto invalid_data;
216 [ + + ]: 55250 : lh->version = read_2ubyte_unaligned_inc (dbg, linep);
217 [ + - - + ]: 55250 : if (unlikely (lh->version < 2) || unlikely (lh->version > 5))
218 : : {
219 : 0 : __libdw_seterrno (DWARF_E_VERSION);
220 : 0 : return -1;
221 : : }
222 : :
223 : : /* DWARF5 explicitly lists address and segment_selector sizes. */
224 [ + + ]: 55250 : if (lh->version >= 5)
225 : : {
226 [ - + ]: 54458 : if ((size_t) (lineendp - linep) < 2)
227 : 0 : goto invalid_data;
228 : 54458 : lh->line_address_size = *linep++;
229 : 54458 : lh->segment_selector_size = *linep++;
230 [ + - - + ]: 54458 : if (lh->line_address_size != address_size || lh->segment_selector_size != 0)
231 : 0 : goto invalid_data;
232 : : }
233 : :
234 : : /* Next comes the header length. */
235 [ + - ]: 55250 : if (lh->length == 4)
236 : : {
237 [ - + ]: 55250 : if ((size_t) (lineendp - linep) < 4)
238 : 0 : goto invalid_data;
239 [ + + ]: 55250 : lh->header_length = read_4ubyte_unaligned_inc (dbg, linep);
240 : : }
241 : : else
242 : : {
243 [ # # ]: 0 : if ((size_t) (lineendp - linep) < 8)
244 : 0 : goto invalid_data;
245 [ # # ]: 0 : lh->header_length = read_8ubyte_unaligned_inc (dbg, linep);
246 : : }
247 : 55250 : lh->header_start = linep;
248 : :
249 : : /* The header length is the number of bytes from here to the start of
250 : : the line number program, so it must stay within the unit (and thus
251 : : the section). Without this check a bogus header_length makes
252 : : read_srcfiles/read_srclines compute an out-of-bounds end pointer
253 : : (header_start + header_length) and read past the section while
254 : : parsing the directory and file tables. */
255 [ - + ]: 55250 : if (unlikely (lh->header_length > (size_t) (lineendp - linep)))
256 : 0 : goto invalid_data;
257 : :
258 : : /* Next the minimum instruction length. */
259 [ - + ]: 55250 : if (unlikely ((size_t) (lineendp - linep) < 1))
260 : 0 : goto invalid_data;
261 : 55250 : lh->minimum_instr_len = *linep++;
262 : :
263 : : /* Next the maximum operations per instruction, in version 4 format. */
264 : 55250 : lh->max_ops_per_instr = 1;
265 [ + + ]: 55250 : if (lh->version >= 4)
266 : : {
267 [ - + ]: 54572 : if (unlikely ((size_t) (lineendp - linep) < 1))
268 : 0 : goto invalid_data;
269 : 54572 : lh->max_ops_per_instr = *linep++;
270 [ - + ]: 54572 : if (unlikely (lh->max_ops_per_instr == 0))
271 : 0 : goto invalid_data;
272 : : }
273 : :
274 : : /* 4 more bytes, is_stmt, line_base, line_range and opcode_base. */
275 [ - + ]: 55250 : if ((size_t) (lineendp - linep) < 4)
276 : 0 : goto invalid_data;
277 : :
278 : : /* Then the flag determining the default value of the is_stmt
279 : : register. */
280 : 55250 : lh->default_is_stmt = *linep++;
281 : :
282 : : /* Now the line base. */
283 : 55250 : lh->line_base = (int8_t) *linep++;
284 : :
285 : : /* And the line range. */
286 : 55250 : lh->line_range = *linep++;
287 : :
288 : : /* The opcode base. */
289 : 55250 : lh->opcode_base = *linep++;
290 : :
291 : : /* If the line header uses the NVIDIA CUBIN extension, debug_str_offset's
292 : : actual value will be read from the last 4 bytes of the header. */
293 : 55250 : lh->debug_str_offset = 0;
294 : :
295 : : /* Remember array with the standard opcode length (-1 to account for
296 : : the opcode with value zero not being mentioned). */
297 : 55250 : lh->standard_opcode_lengths = linep - 1;
298 [ - + ]: 55250 : if (unlikely (lineendp - linep < lh->opcode_base - 1))
299 : 0 : goto invalid_data;
300 : 55250 : linep += lh->opcode_base - 1;
301 : :
302 : : /* Record beginning of the file information. */
303 : 55250 : lh->files_start = (size_t) (linep - line_start);
304 : :
305 : 55250 : return 0;
306 : :
307 : 0 : invalid_data:
308 : 0 : __libdw_seterrno (DWARF_E_INVALID_DEBUG_LINE);
309 : 0 : return -1;
310 : : }
311 : :
312 : : /* If there are a large number of lines, files or dirs don't blow up
313 : : the stack. Stack allocate some entries, only dynamically malloc
314 : : when more than MAX. */
315 : : #define MAX_STACK_ALLOC 4096
316 : : #define MAX_STACK_LINES (MAX_STACK_ALLOC / 2)
317 : : #define MAX_STACK_FILES (MAX_STACK_ALLOC / 4)
318 : : #define MAX_STACK_DIRS (MAX_STACK_ALLOC / 16)
319 : :
320 : : static int
321 : 55214 : read_srcfiles (Dwarf *dbg,
322 : : const unsigned char *linep, const unsigned char *lineendp,
323 : : const char *comp_dir, unsigned address_size,
324 : : struct line_header *lh, Dwarf_Files **filesp)
325 : : {
326 [ - + ]: 55214 : if (filesp == NULL)
327 : : return -1;
328 : :
329 : 55214 : struct line_header lh_local;
330 : :
331 [ + + ]: 55214 : if (lh == NULL)
332 : : {
333 [ - + ]: 51958 : if (read_line_header (dbg, address_size, linep, lineendp, &lh_local) != 0)
334 : : return -1;
335 : : lh = &lh_local;
336 : : }
337 : :
338 : 55214 : int res = -1;
339 : :
340 : 55214 : struct filelist *filelist = NULL;
341 : 55214 : size_t nfilelist = 0;
342 : 55214 : size_t ndirlist = 0;
343 : :
344 : : /* The dirs normally go on the stack, but if there are too many
345 : : we alloc them all. Set up stack storage early, so we can check on
346 : : error if we need to free them or not. */
347 : 55214 : struct dirlist dirstack[MAX_STACK_DIRS];
348 : 55214 : struct dirlist *dirarray = dirstack;
349 : :
350 : : /* To read DWARF5 dir and file lists we need to know the forms. For
351 : : now we skip everything, except the DW_LNCT_path and
352 : : DW_LNCT_directory_index. */
353 : 55214 : uint16_t forms[256];
354 : 55214 : unsigned char nforms = 0;
355 : 55214 : unsigned char form_path = -1; /* Which forms is DW_LNCT_path. */
356 : 55214 : unsigned char form_idx = -1; /* And which is DW_LNCT_directory_index. */
357 : :
358 : : /* Set lineendp to the end of the file information. */
359 : 55214 : lineendp = lh->header_start + lh->header_length;
360 : :
361 : : /* Advance linep to the beginning of the header's srcfile information. */
362 : 55214 : linep += lh->files_start;
363 : :
364 : : /* To read/skip form data. */
365 : 55214 : Dwarf_CU fake_cu = {
366 : : .dbg = dbg,
367 : : .sec_idx = IDX_debug_line,
368 : : .version = 5,
369 : 55214 : .offset_size = lh->length,
370 : : .address_size = address_size,
371 : : .startp = (void *) linep,
372 : : .endp = (void *) lineendp,
373 : : };
374 : :
375 : : /* First count the entries. */
376 : 55214 : size_t ndirs = 0;
377 [ + + ]: 55214 : if (lh->version < 5)
378 : : {
379 : : const unsigned char *dirp = linep;
380 [ + - + + ]: 1650 : while (dirp < lineendp && *dirp != 0)
381 : : {
382 : 884 : const uint8_t *endp = memchr (dirp, '\0', lineendp - dirp);
383 [ - + ]: 884 : if (endp == NULL)
384 : 0 : goto invalid_data;
385 : 884 : ++ndirs;
386 : 884 : dirp = endp + 1;
387 : : }
388 [ + - - + ]: 766 : if (dirp >= lineendp || *dirp != '\0')
389 : 0 : goto invalid_data;
390 : 766 : ndirs = ndirs + 1; /* There is always the "unknown" dir. */
391 : : }
392 : : else
393 : : {
394 [ - + ]: 54448 : if ((size_t) (lineendp - linep) < 1)
395 : 0 : goto invalid_data;
396 : 54448 : nforms = *linep++;
397 [ + + ]: 108896 : for (int i = 0; i < nforms; i++)
398 : : {
399 : 54448 : uint16_t desc, form;
400 [ - + ]: 54448 : if ((size_t) (lineendp - linep) < 1)
401 : 0 : goto invalid_data;
402 : 54448 : get_uleb128 (desc, linep, lineendp);
403 [ - + ]: 54448 : if ((size_t) (lineendp - linep) < 1)
404 : 0 : goto invalid_data;
405 : 54448 : get_uleb128 (form, linep, lineendp);
406 : :
407 [ - + ]: 54448 : if (! libdw_valid_user_form (form))
408 : 0 : goto invalid_data;
409 : :
410 : 54448 : forms[i] = form;
411 [ + - ]: 54448 : if (desc == DW_LNCT_path)
412 : 54448 : form_path = i;
413 : : }
414 : :
415 [ - + ]: 54448 : if (nforms > 0 && form_path == (unsigned char) -1)
416 : 0 : goto invalid_data;
417 : :
418 [ - + ]: 54448 : if ((size_t) (lineendp - linep) < 1)
419 : 0 : goto invalid_data;
420 : 54448 : get_uleb128 (ndirs, linep, lineendp);
421 : :
422 [ - + ]: 54448 : if (nforms == 0 && ndirs != 0)
423 : 0 : goto invalid_data;
424 : :
425 : : /* Assume there is at least 1 byte needed per form to describe
426 : : the directory. Filters out insanely large ndirs. */
427 [ + - - + ]: 54448 : if (nforms != 0 && ndirs > (size_t) (lineendp - linep) / nforms)
428 : 0 : goto invalid_data;
429 : : }
430 : :
431 : : /* Arrange the list in array form. */
432 : 55214 : ndirlist = ndirs;
433 [ - + ]: 55214 : if (ndirlist >= MAX_STACK_DIRS)
434 : : {
435 [ # # ]: 0 : if (ndirlist > SIZE_MAX / sizeof (*dirarray))
436 : 0 : goto no_mem;
437 : 0 : dirarray = malloc (ndirlist * sizeof (*dirarray));
438 [ # # ]: 0 : if (unlikely (dirarray == NULL))
439 : : {
440 : 0 : no_mem:
441 : 0 : __libdw_seterrno (DWARF_E_NOMEM);
442 : 0 : goto out;
443 : : }
444 : : }
445 : :
446 : : /* Entry zero is implicit for older versions, but explicit for 5+. */
447 : 55214 : struct dirlist comp_dir_elem;
448 [ + + ]: 55214 : if (lh->version < 5)
449 : : {
450 : : /* First comes the list of directories. Add the compilation
451 : : directory first since the index zero is used for it. */
452 : 766 : comp_dir_elem.dir = comp_dir;
453 [ + + ]: 766 : comp_dir_elem.len = comp_dir ? strlen (comp_dir) : 0,
454 : 766 : dirarray[0] = comp_dir_elem;
455 [ + + ]: 1650 : for (unsigned int n = 1; n < ndirlist; n++)
456 : : {
457 : 884 : dirarray[n].dir = (char *) linep;
458 : 884 : const uint8_t *endp = memchr (linep, '\0', lineendp - linep);
459 [ - + ]: 884 : assert (endp != NULL); // Checked above when calculating ndirlist.
460 : 884 : dirarray[n].len = endp - linep;
461 : 884 : linep = endp + 1;
462 : : }
463 : : /* Skip the final NUL byte. */
464 [ - + ]: 766 : assert (*linep == '\0'); // Checked above when calculating ndirlist.
465 : 766 : ++linep;
466 : : }
467 : : else
468 : : {
469 : 54448 : Dwarf_Attribute attr;
470 : 54448 : attr.code = DW_AT_name;
471 : 54448 : attr.cu = &fake_cu;
472 [ + + ]: 468170 : for (unsigned int n = 0; n < ndirlist; n++)
473 : : {
474 : : const char *dir = NULL;
475 [ + + ]: 827444 : for (unsigned char m = 0; m < nforms; m++)
476 : : {
477 [ + - ]: 413722 : if (m == form_path)
478 : : {
479 : 413722 : attr.form = forms[m];
480 : 413722 : attr.valp = (void *) linep;
481 : 413722 : dir = dwarf_formstring (&attr);
482 : : }
483 : :
484 : 413722 : size_t len = __libdw_form_val_len (&fake_cu, forms[m], linep);
485 [ - + ]: 413722 : if ((size_t) (lineendp - linep) < len)
486 : 0 : goto invalid_data;
487 : :
488 : 413722 : linep += len;
489 : : }
490 : :
491 [ - + ]: 413722 : if (dir == NULL)
492 : 0 : goto invalid_data;
493 : :
494 : 413722 : dirarray[n].dir = dir;
495 : 413722 : dirarray[n].len = strlen (dir);
496 : : }
497 : : }
498 : :
499 : : /* File index zero doesn't exist for DWARF < 5. Files are indexed
500 : : starting from 1. But for DWARF5 they are indexed starting from
501 : : zero, but the default index is still 1. In both cases the
502 : : "first" file is special and refers to the main compile unit file,
503 : : equal to the DW_AT_name of the DW_TAG_compile_unit. */
504 : 55214 : struct filelist null_file =
505 : : {
506 : : .info =
507 : : {
508 : : .name = "???",
509 : : .mtime = 0,
510 : : .length = 0
511 : : },
512 : : .next = NULL
513 : : };
514 : 55214 : filelist = &null_file;
515 : 55214 : nfilelist = 1;
516 : :
517 : : /* Allocate memory for a new file. For the first MAX_STACK_FILES
518 : : entries just return a slot in the preallocated stack array.
519 : : This is slightly complicated because in DWARF < 5 new files could
520 : : be defined with DW_LNE_define_file after the normal file list was
521 : : read. */
522 : 55214 : struct filelist flstack[MAX_STACK_FILES];
523 : : #define NEW_FILE() ({ \
524 : : struct filelist *fl = (nfilelist < MAX_STACK_FILES \
525 : : ? &flstack[nfilelist] \
526 : : : malloc (sizeof (struct filelist))); \
527 : : if (unlikely (fl == NULL)) \
528 : : goto no_mem; \
529 : : ++nfilelist; \
530 : : fl->next = filelist; \
531 : : filelist = fl; \
532 : : fl; })
533 : :
534 : : /* Now read the files. */
535 [ + + ]: 55214 : if (lh->version < 5)
536 : : {
537 [ - + ]: 766 : if (unlikely (linep >= lineendp))
538 : 0 : goto invalid_data;
539 [ + - + + ]: 8852 : while (linep < lineendp && *linep != '\0')
540 : : {
541 [ + - - - ]: 8086 : struct filelist *new_file = NEW_FILE ();
542 : :
543 : : /* First comes the file name. */
544 : 8086 : char *fname = (char *) linep;
545 : 8086 : uint8_t *endp = memchr (fname, '\0', lineendp - linep);
546 [ - + ]: 8086 : if (endp == NULL)
547 : 0 : goto invalid_data;
548 : 8086 : size_t fnamelen = endp - (uint8_t *) fname;
549 : 8086 : linep = endp + 1;
550 : :
551 : : /* Then the index. */
552 : 8086 : Dwarf_Word diridx;
553 [ - + ]: 8086 : if (unlikely (linep >= lineendp))
554 : 0 : goto invalid_data;
555 : 8086 : get_uleb128 (diridx, linep, lineendp);
556 [ - + ]: 8086 : if (unlikely (diridx >= ndirlist))
557 : : {
558 : 0 : __libdw_seterrno (DWARF_E_INVALID_DIR_IDX);
559 : 0 : goto out;
560 : : }
561 : :
562 [ + + ]: 8086 : if (*fname == '/')
563 : : /* It's an absolute path. */
564 : 728 : new_file->info.name = fname;
565 : : else
566 : : {
567 [ + + ]: 7358 : new_file->info.name = libdw_alloc (dbg, char, 1,
568 : : dirarray[diridx].len + 1
569 : : + fnamelen + 1);
570 : 7358 : char *cp = new_file->info.name;
571 : :
572 [ + + ]: 7358 : if (dirarray[diridx].dir != NULL)
573 : : {
574 : : /* This value could be NULL in case the DW_AT_comp_dir
575 : : was not present. We cannot do much in this case.
576 : : Just keep the file relative. */
577 : 7346 : cp = stpcpy (cp, dirarray[diridx].dir);
578 : 7346 : *cp++ = '/';
579 : : }
580 [ - + ]: 7358 : strcpy (cp, fname);
581 [ - + ]: 7358 : assert (strlen (new_file->info.name)
582 : : < dirarray[diridx].len + 1 + fnamelen + 1);
583 : : }
584 : :
585 : : /* Next comes the modification time. */
586 [ - + ]: 8086 : if (unlikely (linep >= lineendp))
587 : 0 : goto invalid_data;
588 : 8086 : get_uleb128 (new_file->info.mtime, linep, lineendp);
589 : :
590 : : /* Finally the length of the file. */
591 [ - + ]: 8086 : if (unlikely (linep >= lineendp))
592 : 0 : goto invalid_data;
593 : 8086 : get_uleb128 (new_file->info.length, linep, lineendp);
594 : : }
595 [ + - - + ]: 766 : if (linep >= lineendp || *linep != '\0')
596 : 0 : goto invalid_data;
597 : : /* Skip the final NUL byte. */
598 : 766 : ++linep;
599 : : }
600 : : else
601 : : {
602 [ - + ]: 54448 : if ((size_t) (lineendp - linep) < 1)
603 : 0 : goto invalid_data;
604 : 54448 : nforms = *linep++;
605 : 54448 : form_path = form_idx = -1;
606 [ + + ]: 163358 : for (int i = 0; i < nforms; i++)
607 : : {
608 : 108910 : uint16_t desc, form;
609 [ - + ]: 108910 : if ((size_t) (lineendp - linep) < 1)
610 : 0 : goto invalid_data;
611 : 108910 : get_uleb128 (desc, linep, lineendp);
612 [ - + ]: 108910 : if ((size_t) (lineendp - linep) < 1)
613 : 0 : goto invalid_data;
614 : 108910 : get_uleb128 (form, linep, lineendp);
615 : :
616 [ - + ]: 108910 : if (! libdw_valid_user_form (form))
617 : 0 : goto invalid_data;
618 : :
619 : 108910 : forms[i] = form;
620 [ + + ]: 108910 : if (desc == DW_LNCT_path)
621 : 54448 : form_path = i;
622 [ + + ]: 54462 : else if (desc == DW_LNCT_directory_index)
623 : 54448 : form_idx = i;
624 : : }
625 : :
626 [ + - ]: 54448 : if (nforms > 0 && (form_path == (unsigned char) -1
627 [ - + ]: 54448 : || form_idx == (unsigned char) -1))
628 : 0 : goto invalid_data;
629 : :
630 : 54448 : size_t nfiles;
631 [ - + ]: 54448 : if ((size_t) (lineendp - linep) < 1)
632 : 0 : goto invalid_data;
633 : 54448 : get_uleb128 (nfiles, linep, lineendp);
634 : :
635 [ - + ]: 54448 : if (nforms == 0 && nfiles != 0)
636 : 0 : goto invalid_data;
637 : :
638 : : /* Assume there is at least 1 byte needed per form to describe
639 : : the file. Filters out insanely large nfiles. */
640 [ + - - + ]: 54448 : if (nforms != 0 && nfiles > (size_t) (lineendp - linep) / nforms)
641 : 0 : goto invalid_data;
642 : :
643 : 54448 : Dwarf_Attribute attr;
644 : 54448 : attr.cu = &fake_cu;
645 [ + + ]: 875064 : for (unsigned int n = 0; n < nfiles; n++)
646 : : {
647 : 820616 : const char *fname = NULL;
648 : 820616 : Dwarf_Word diridx = (Dwarf_Word) -1;
649 [ + + ]: 2461882 : for (unsigned char m = 0; m < nforms; m++)
650 : : {
651 [ + + ]: 1641266 : if (m == form_path)
652 : : {
653 : 820616 : attr.code = DW_AT_name;
654 : 820616 : attr.form = forms[m];
655 : 820616 : attr.valp = (void *) linep;
656 : 820616 : fname = dwarf_formstring (&attr);
657 : : }
658 [ + + ]: 820650 : else if (m == form_idx)
659 : : {
660 : 820616 : attr.code = DW_AT_decl_file; /* Close enough. */
661 : 820616 : attr.form = forms[m];
662 : 820616 : attr.valp = (void *) linep;
663 [ + - ]: 820616 : if (dwarf_formudata (&attr, &diridx) != 0)
664 : 0 : diridx = (Dwarf_Word) -1;
665 : : }
666 : :
667 : 1641266 : size_t len = __libdw_form_val_len (&fake_cu, forms[m], linep);
668 [ - + ]: 1641266 : if ((size_t) (lineendp - linep) < len)
669 : 0 : goto invalid_data;
670 : :
671 : 1641266 : linep += len;
672 : : }
673 : :
674 [ + - - + ]: 820616 : if (fname == NULL || diridx == (Dwarf_Word) -1)
675 : 0 : goto invalid_data;
676 : :
677 : 820616 : size_t fnamelen = strlen (fname);
678 : :
679 [ - + ]: 820616 : if (unlikely (diridx >= ndirlist))
680 : : {
681 : 0 : __libdw_seterrno (DWARF_E_INVALID_DIR_IDX);
682 : 0 : goto out;
683 : : }
684 : :
685 : : /* Yes, weird. Looks like an off-by-one in the spec. */
686 [ + + + - : 820616 : struct filelist *new_file = n == 0 ? &null_file : NEW_FILE ();
- - ]
687 : :
688 : : /* We follow the same rules as above for DWARF < 5, even
689 : : though the standard doesn't explicitly mention absolute
690 : : paths and ignoring the dir index. */
691 [ + + ]: 820616 : if (*fname == '/')
692 : : /* It's an absolute path. */
693 : 8 : new_file->info.name = (char *) fname;
694 : : else
695 : : {
696 [ + + ]: 820608 : new_file->info.name = libdw_alloc (dbg, char, 1,
697 : : dirarray[diridx].len + 1
698 : : + fnamelen + 1);
699 : 820608 : char *cp = new_file->info.name;
700 : :
701 : : /* In the DWARF >= 5 case, dir can never be NULL. */
702 [ - + ]: 820608 : cp = stpcpy (cp, dirarray[diridx].dir);
703 : 820608 : *cp++ = '/';
704 [ - + ]: 820608 : strcpy (cp, fname);
705 [ - + ]: 820608 : assert (strlen (new_file->info.name)
706 : : < dirarray[diridx].len + 1 + fnamelen + 1);
707 : : }
708 : :
709 : : /* For now we just ignore the modification time and file length. */
710 : 820616 : new_file->info.mtime = 0;
711 : 820616 : new_file->info.length = 0;
712 : : }
713 : : }
714 : :
715 [ + + ]: 55214 : if (unlikely (linep == lh->header_start + lh->header_length - 4))
716 : : {
717 : : /* CUBINs contain an unsigned 4-byte offset */
718 [ - + ]: 2 : lh->debug_str_offset = read_4ubyte_unaligned_inc (dbg, linep);
719 : : }
720 : :
721 : : /* Consistency check. */
722 [ - + ]: 55214 : if (unlikely (linep != lh->header_start + lh->header_length))
723 : 0 : goto invalid_data;
724 : :
725 : : /* Put all the files in an array. */
726 [ + + ]: 55214 : Dwarf_Files *files = libdw_alloc (dbg, Dwarf_Files,
727 : : sizeof (Dwarf_Files)
728 : : + nfilelist * sizeof (Dwarf_Fileinfo)
729 : : + (ndirlist + 1) * sizeof (char *),
730 : : 1);
731 : :
732 [ - + ]: 55214 : if (unlikely (files == NULL))
733 : 0 : goto no_mem;
734 : :
735 : 55214 : const char **dirs = (void *) &files->info[nfilelist];
736 : :
737 : 55214 : struct filelist *fileslist = filelist;
738 : 55214 : files->nfiles = nfilelist;
739 [ + + ]: 884682 : for (size_t n = nfilelist; n > 0; n--)
740 : : {
741 : 829468 : files->info[n - 1] = fileslist->info;
742 : 829468 : fileslist = fileslist->next;
743 : : }
744 [ - + ]: 55214 : assert (fileslist == NULL);
745 : :
746 : : /* Put all the directory strings in an array. */
747 : 55214 : files->ndirs = ndirlist;
748 [ + + ]: 470586 : for (unsigned int i = 0; i < ndirlist; ++i)
749 : 415372 : dirs[i] = dirarray[i].dir;
750 : 55214 : dirs[ndirlist] = NULL;
751 : :
752 : : /* Pass the file data structure to the caller. */
753 : 55214 : *filesp = files;
754 : :
755 : 55214 : res = 0;
756 : 55214 : goto out;
757 : :
758 : 0 : invalid_data:
759 : 0 : __libdw_seterrno (DWARF_E_INVALID_DEBUG_LINE);
760 : :
761 : 55214 : out:
762 [ - + ]: 55214 : if (dirarray != dirstack)
763 : 0 : free (dirarray);
764 [ - + ]: 55214 : for (size_t i = MAX_STACK_FILES; i < nfilelist; i++)
765 : : {
766 : 0 : struct filelist *fl = filelist->next;
767 : 0 : free (filelist);
768 : 0 : filelist = fl;
769 : : }
770 : :
771 : : return res;
772 : : }
773 : :
774 : : static int
775 : 3292 : read_srclines (Dwarf *dbg,
776 : : const unsigned char *linep, const unsigned char *lineendp,
777 : : const char *comp_dir, unsigned address_size,
778 : : Dwarf_Lines **linesp, Dwarf_Files **filesp,
779 : : bool use_cached_files)
780 : : {
781 : 3292 : int res = -1;
782 : 3292 : struct line_header lh;
783 : :
784 [ - + ]: 3292 : if (read_line_header (dbg, address_size, linep, lineendp, &lh) != 0)
785 : : return res;
786 : :
787 : : /* Use the filesp srcfiles if they've already been read. */
788 [ + + ]: 3292 : if (!use_cached_files
789 [ - + ]: 3256 : && read_srcfiles (dbg, linep, lineendp, comp_dir,
790 : : address_size, &lh, filesp) != 0)
791 : : return res;
792 : :
793 : : /* Initial statement program state (except for stmt_list, see below). */
794 : 3292 : struct line_state state =
795 : : {
796 : : .linelist = NULL,
797 : : .nlinelist = 0,
798 : : .addr = 0,
799 : : .op_index = 0,
800 : : .file = 1,
801 : : /* We only store int but want to check for overflow (see SET above). */
802 : : .line = 1,
803 : : .column = 0,
804 : : .basic_block = false,
805 : : .prologue_end = false,
806 : : .epilogue_begin = false,
807 : : .isa = 0,
808 : : .discriminator = 0,
809 : : .context = 0,
810 : : .function_name = 0
811 : : };
812 : :
813 : : /* We are about to process the statement program. Most state machine
814 : : registers have already been initialize above. Just add the is_stmt
815 : : default. See 6.2.2 in the v2.1 specification. */
816 : 3292 : state.is_stmt = lh.default_is_stmt;
817 : :
818 : : /* Apply the "operation advance" from a special opcode or
819 : : DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
820 : : #define advance_pc(op_advance) \
821 : : run_advance_pc (&state, op_advance, lh.minimum_instr_len, \
822 : : lh.max_ops_per_instr)
823 : :
824 : : /* Process the instructions. */
825 : :
826 : : /* Adds a new line to the matrix. For the first MAX_STACK_LINES
827 : : entries just return a slot in the preallocated stack array. */
828 : 3292 : struct linelist llstack[MAX_STACK_LINES];
829 : : #define NEW_LINE(end_seq) \
830 : : do { \
831 : : struct linelist *ll = (state.nlinelist < MAX_STACK_LINES \
832 : : ? &llstack[state.nlinelist] \
833 : : : malloc (sizeof (struct linelist))); \
834 : : if (unlikely (ll == NULL)) \
835 : : { \
836 : : __libdw_seterrno (DWARF_E_NOMEM); \
837 : : goto out; \
838 : : } \
839 : : state.end_sequence = end_seq; \
840 : : if (unlikely (add_new_line (&state, ll))) \
841 : : goto invalid_data; \
842 : : } while (0)
843 : :
844 : : /* If DW_LNE_define_file is present, then additional files will be
845 : : added to filesp. */
846 : 3292 : size_t nfilelist = 0;
847 : 3292 : struct filelist *filelist = NULL;
848 : :
849 : : /* Set lineendp to the end of the line program. */
850 : 3292 : lineendp = linep + lh.length + lh.unit_length;
851 : :
852 : : /* Set linep to the beginning of the line program. */
853 : 3292 : linep = lh.header_start + lh.header_length;
854 : :
855 [ + + ]: 2072804 : while (linep < lineendp)
856 : : {
857 : 2069512 : unsigned int opcode;
858 : 2069512 : unsigned int u128;
859 : 2069512 : int s128;
860 : :
861 : : /* Read the opcode. */
862 : 2069512 : opcode = *linep++;
863 : :
864 : : /* Is this a special opcode? */
865 [ + + ]: 2069512 : if (likely (opcode >= lh.opcode_base))
866 : : {
867 [ - + ]: 588378 : if (unlikely (lh.line_range == 0))
868 : 0 : goto invalid_data;
869 : :
870 : : /* Yes. Handling this is quite easy since the opcode value
871 : : is computed with
872 : :
873 : : opcode = (desired line increment - line_base)
874 : : + (line_range * address advance) + opcode_base
875 : : */
876 : 588378 : int line_increment = (lh.line_base
877 : 588378 : + (opcode - lh.opcode_base) % lh.line_range);
878 : :
879 : : /* Perform the increments. */
880 : 588378 : state.line += line_increment;
881 : 588378 : advance_pc ((opcode - lh.opcode_base) / lh.line_range);
882 : :
883 : : /* Add a new line with the current state machine values. */
884 [ + + - + : 588378 : NEW_LINE (0);
- + ]
885 : :
886 : : /* Reset the flags. */
887 : 588378 : state.basic_block = false;
888 : 588378 : state.prologue_end = false;
889 : 588378 : state.epilogue_begin = false;
890 : 588378 : state.discriminator = 0;
891 : : }
892 [ + + ]: 1481134 : else if (opcode == 0)
893 : : {
894 : : /* This an extended opcode. */
895 [ - + ]: 156912 : if (unlikely (lineendp - linep < 2))
896 : 0 : goto invalid_data;
897 : :
898 : : /* The length. */
899 : 156912 : uint_fast8_t len = *linep++;
900 : :
901 [ - + ]: 156912 : if (unlikely ((size_t) (lineendp - linep) < len))
902 : 0 : goto invalid_data;
903 : :
904 : : /* The sub-opcode. */
905 : 156912 : opcode = *linep++;
906 : :
907 [ + + + + : 156912 : switch (opcode)
+ - - ]
908 : : {
909 : 9180 : case DW_LNE_end_sequence:
910 : : /* Add a new line with the current state machine values.
911 : : The is the end of the sequence. */
912 [ + + - + : 9180 : NEW_LINE (1);
- + ]
913 : :
914 : : /* Reset the registers. */
915 : 9180 : state.addr = 0;
916 : 9180 : state.op_index = 0;
917 : 9180 : state.file = 1;
918 : 9180 : state.line = 1;
919 : 9180 : state.column = 0;
920 : 9180 : state.is_stmt = lh.default_is_stmt;
921 : 9180 : state.basic_block = false;
922 : 9180 : state.prologue_end = false;
923 : 9180 : state.epilogue_begin = false;
924 : 9180 : state.isa = 0;
925 : 9180 : state.discriminator = 0;
926 : 9180 : state.context = 0;
927 : 9180 : state.function_name = 0;
928 : 9180 : break;
929 : :
930 : 10988 : case DW_LNE_set_address:
931 : : /* The value is an address. The size is defined as
932 : : appropriate for the target machine. We use the
933 : : address size field from the CU header. */
934 : 10988 : state.op_index = 0;
935 [ - + ]: 10988 : if (unlikely (lineendp - linep < (uint8_t) address_size))
936 : 0 : goto invalid_data;
937 [ + - ]: 10988 : if (__libdw_read_address_inc (dbg, IDX_debug_line, &linep,
938 : : address_size, &state.addr))
939 : 0 : goto out;
940 : : break;
941 : :
942 : 4 : case DW_LNE_define_file:
943 : : {
944 : 4 : char *fname = (char *) linep;
945 : 4 : const uint8_t *endp = memchr (linep, '\0', lineendp - linep);
946 [ - + ]: 4 : if (endp == NULL)
947 : 0 : goto invalid_data;
948 : 4 : size_t fnamelen = endp - linep;
949 : 4 : linep = endp + 1;
950 : :
951 : 4 : unsigned int diridx;
952 [ - + ]: 4 : if (unlikely (linep >= lineendp))
953 : 0 : goto invalid_data;
954 : 4 : get_uleb128 (diridx, linep, lineendp);
955 : :
956 : 4 : size_t ndirs = (*filesp)->ndirs;
957 [ - + ]: 4 : if (unlikely (diridx >= ndirs))
958 : : {
959 : 0 : __libdw_seterrno (DWARF_E_INVALID_DIR_IDX);
960 : 0 : goto invalid_data;
961 : : }
962 : 4 : Dwarf_Word mtime;
963 [ - + ]: 4 : if (unlikely (linep >= lineendp))
964 : 0 : goto invalid_data;
965 : 4 : get_uleb128 (mtime, linep, lineendp);
966 : 4 : Dwarf_Word filelength;
967 [ - + ]: 4 : if (unlikely (linep >= lineendp))
968 : 0 : goto invalid_data;
969 : 4 : get_uleb128 (filelength, linep, lineendp);
970 : :
971 : : /* Add new_file to filelist that will be merged with filesp. */
972 : 4 : struct filelist *new_file = malloc (sizeof (struct filelist));
973 [ - + ]: 4 : if (unlikely (new_file == NULL))
974 : : {
975 : 0 : __libdw_seterrno (DWARF_E_NOMEM);
976 : 0 : goto out;
977 : : }
978 : 4 : nfilelist++;
979 : 4 : new_file->next = filelist;
980 : 4 : filelist = new_file;
981 : :
982 [ - + ]: 4 : if (fname[0] == '/')
983 : 0 : new_file->info.name = fname;
984 : : else
985 : : {
986 : : /* Directory names are stored in a char *[ndirs] located
987 : : after the last Dwarf_Fileinfo_s. */
988 : 4 : size_t nfiles = (*filesp)->nfiles;
989 : 4 : const char **dirarray
990 : : = (const char **) &((*filesp)->info[nfiles]);
991 : :
992 : 4 : const char *dname = dirarray[diridx];
993 : 4 : size_t dnamelen = strlen (dname);
994 : :
995 : 8 : new_file->info.name =
996 [ - + ]: 4 : libdw_alloc (dbg, char, 1, (dnamelen + fnamelen + 2));
997 : 4 : char *cp = new_file->info.name;
998 : :
999 : 4 : if (dname != NULL)
1000 : :
1001 : : /* This value could be NULL in case the
1002 : : DW_AT_comp_dir was not present. We
1003 : : cannot do much in this case. Just
1004 : : keep the file relative. */
1005 : :
1006 : : {
1007 : 4 : cp = stpcpy (cp, dname);
1008 : 4 : *cp++ = '/';
1009 : : }
1010 : 4 : strcpy (cp, fname);
1011 : : }
1012 : :
1013 : 4 : new_file->info.mtime = mtime;
1014 : 4 : new_file->info.length = filelength;
1015 : : }
1016 : 4 : break;
1017 : :
1018 : 136726 : case DW_LNE_set_discriminator:
1019 : : /* Takes one ULEB128 parameter, the discriminator. */
1020 [ - + ]: 136726 : if (unlikely (lh.standard_opcode_lengths[opcode] != 1))
1021 : 0 : goto invalid_data;
1022 : :
1023 [ - + ]: 136726 : if (unlikely (linep >= lineendp))
1024 : 0 : goto invalid_data;
1025 : 136726 : get_uleb128 (state.discriminator, linep, lineendp);
1026 : 136726 : break;
1027 : :
1028 : 14 : case DW_LNE_NVIDIA_inlined_call:
1029 [ - + ]: 14 : if (unlikely (linep >= lineendp))
1030 : 0 : goto invalid_data;
1031 : 14 : get_uleb128 (state.context, linep, lineendp);
1032 [ - + ]: 14 : if (unlikely (linep >= lineendp))
1033 : 0 : goto invalid_data;
1034 : 14 : get_uleb128 (state.function_name, linep, lineendp);
1035 : 14 : state.function_name += lh.debug_str_offset;
1036 : 14 : break;
1037 : :
1038 : 0 : case DW_LNE_NVIDIA_set_function_name:
1039 [ # # ]: 0 : if (unlikely (linep >= lineendp))
1040 : 0 : goto invalid_data;
1041 : 0 : get_uleb128 (state.function_name, linep, lineendp);
1042 : 0 : state.function_name += lh.debug_str_offset;
1043 : 0 : break;
1044 : :
1045 : : default:
1046 : : /* Unknown, ignore it. */
1047 : 0 : if (unlikely ((size_t) (lineendp - (linep - 1)) < len))
1048 : : goto invalid_data;
1049 : 0 : linep += len - 1;
1050 : 0 : break;
1051 : : }
1052 : : }
1053 [ + - ]: 1324222 : else if (opcode <= DW_LNS_set_isa)
1054 : : {
1055 : : /* This is a known standard opcode. */
1056 [ + + + + : 1324222 : switch (opcode)
+ + - + -
+ - - ]
1057 : : {
1058 : 208404 : case DW_LNS_copy:
1059 : : /* Takes no argument. */
1060 [ - + ]: 208404 : if (unlikely (lh.standard_opcode_lengths[opcode] != 0))
1061 : 0 : goto invalid_data;
1062 : :
1063 : : /* Add a new line with the current state machine values. */
1064 [ + + - + : 208404 : NEW_LINE (0);
- + ]
1065 : :
1066 : : /* Reset the flags. */
1067 : 208404 : state.basic_block = false;
1068 : 208404 : state.prologue_end = false;
1069 : 208404 : state.epilogue_begin = false;
1070 : 208404 : state.discriminator = 0;
1071 : 208404 : break;
1072 : :
1073 : 13120 : case DW_LNS_advance_pc:
1074 : : /* Takes one uleb128 parameter which is added to the
1075 : : address. */
1076 [ - + ]: 13120 : if (unlikely (lh.standard_opcode_lengths[opcode] != 1))
1077 : 0 : goto invalid_data;
1078 : :
1079 [ - + ]: 13120 : if (unlikely (linep >= lineendp))
1080 : 0 : goto invalid_data;
1081 : 13120 : get_uleb128 (u128, linep, lineendp);
1082 : 13120 : advance_pc (u128);
1083 : 13120 : break;
1084 : :
1085 : 152146 : case DW_LNS_advance_line:
1086 : : /* Takes one sleb128 parameter which is added to the
1087 : : line. */
1088 [ - + ]: 152146 : if (unlikely (lh.standard_opcode_lengths[opcode] != 1))
1089 : 0 : goto invalid_data;
1090 : :
1091 [ - + ]: 152146 : if (unlikely (linep >= lineendp))
1092 : 0 : goto invalid_data;
1093 : 152146 : get_sleb128 (s128, linep, lineendp);
1094 : 152146 : state.line += s128;
1095 : 152146 : break;
1096 : :
1097 : 48324 : case DW_LNS_set_file:
1098 : : /* Takes one uleb128 parameter which is stored in file. */
1099 [ - + ]: 48324 : if (unlikely (lh.standard_opcode_lengths[opcode] != 1))
1100 : 0 : goto invalid_data;
1101 : :
1102 [ - + ]: 48324 : if (unlikely (linep >= lineendp))
1103 : 0 : goto invalid_data;
1104 : 48324 : get_uleb128 (u128, linep, lineendp);
1105 : 48324 : state.file = u128;
1106 : 48324 : break;
1107 : :
1108 : 501588 : case DW_LNS_set_column:
1109 : : /* Takes one uleb128 parameter which is stored in column. */
1110 [ - + ]: 501588 : if (unlikely (lh.standard_opcode_lengths[opcode] != 1))
1111 : 0 : goto invalid_data;
1112 : :
1113 [ - + ]: 501588 : if (unlikely (linep >= lineendp))
1114 : 0 : goto invalid_data;
1115 : 501588 : get_uleb128 (u128, linep, lineendp);
1116 : 501588 : state.column = u128;
1117 : 501588 : break;
1118 : :
1119 : 357044 : case DW_LNS_negate_stmt:
1120 : : /* Takes no argument. */
1121 [ - + ]: 357044 : if (unlikely (lh.standard_opcode_lengths[opcode] != 0))
1122 : 0 : goto invalid_data;
1123 : :
1124 : 357044 : state.is_stmt = 1 - state.is_stmt;
1125 : 357044 : break;
1126 : :
1127 : 0 : case DW_LNS_set_basic_block:
1128 : : /* Takes no argument. */
1129 [ # # ]: 0 : if (unlikely (lh.standard_opcode_lengths[opcode] != 0))
1130 : 0 : goto invalid_data;
1131 : :
1132 : 0 : state.basic_block = true;
1133 : 0 : break;
1134 : :
1135 : 43594 : case DW_LNS_const_add_pc:
1136 : : /* Takes no argument. */
1137 [ - + ]: 43594 : if (unlikely (lh.standard_opcode_lengths[opcode] != 0))
1138 : 0 : goto invalid_data;
1139 : :
1140 [ - + ]: 43594 : if (unlikely (lh.line_range == 0))
1141 : 0 : goto invalid_data;
1142 : :
1143 : 43594 : advance_pc ((255 - lh.opcode_base) / lh.line_range);
1144 : 43594 : break;
1145 : :
1146 : 0 : case DW_LNS_fixed_advance_pc:
1147 : : /* Takes one 16 bit parameter which is added to the
1148 : : address. */
1149 [ # # ]: 0 : if (unlikely (lh.standard_opcode_lengths[opcode] != 1)
1150 [ # # ]: 0 : || unlikely (lineendp - linep < 2))
1151 : 0 : goto invalid_data;
1152 : :
1153 [ # # ]: 0 : state.addr += read_2ubyte_unaligned_inc (dbg, linep);
1154 : 0 : state.op_index = 0;
1155 : 0 : break;
1156 : :
1157 : 2 : case DW_LNS_set_prologue_end:
1158 : : /* Takes no argument. */
1159 [ - + ]: 2 : if (unlikely (lh.standard_opcode_lengths[opcode] != 0))
1160 : 0 : goto invalid_data;
1161 : :
1162 : 2 : state.prologue_end = true;
1163 : 2 : break;
1164 : :
1165 : 0 : case DW_LNS_set_epilogue_begin:
1166 : : /* Takes no argument. */
1167 [ # # ]: 0 : if (unlikely (lh.standard_opcode_lengths[opcode] != 0))
1168 : 0 : goto invalid_data;
1169 : :
1170 : 0 : state.epilogue_begin = true;
1171 : 0 : break;
1172 : :
1173 : 0 : case DW_LNS_set_isa:
1174 : : /* Takes one uleb128 parameter which is stored in isa. */
1175 [ # # ]: 0 : if (unlikely (lh.standard_opcode_lengths[opcode] != 1))
1176 : 0 : goto invalid_data;
1177 : :
1178 [ # # ]: 0 : if (unlikely (linep >= lineendp))
1179 : 0 : goto invalid_data;
1180 : 0 : get_uleb128 (state.isa, linep, lineendp);
1181 : 0 : break;
1182 : : }
1183 : : }
1184 : : else
1185 : : {
1186 : : /* This is a new opcode the generator but not we know about.
1187 : : Read the parameters associated with it but then discard
1188 : : everything. Read all the parameters for this opcode. */
1189 [ # # ]: 0 : for (int n = lh.standard_opcode_lengths[opcode]; n > 0; --n)
1190 : : {
1191 [ # # ]: 0 : if (unlikely (linep >= lineendp))
1192 : 0 : goto invalid_data;
1193 : 0 : get_uleb128 (u128, linep, lineendp);
1194 : : }
1195 : :
1196 : : /* Next round, ignore this opcode. */
1197 : 0 : continue;
1198 : : }
1199 : : }
1200 : :
1201 : : /* Merge filesp with the files from DW_LNE_define_file, if any. */
1202 [ + + ]: 3292 : if (unlikely (filelist != NULL))
1203 : : {
1204 : 2 : Dwarf_Files *prevfiles = *filesp;
1205 : 2 : size_t ndirs = prevfiles->ndirs;
1206 : 2 : size_t nprevfiles = prevfiles->nfiles;
1207 : 2 : size_t nnewfiles = nprevfiles + nfilelist;
1208 : :
1209 : 4 : Dwarf_Files *newfiles
1210 [ - + ]: 2 : = libdw_alloc (dbg, Dwarf_Files,
1211 : : sizeof (Dwarf_Files)
1212 : : + nnewfiles * sizeof (Dwarf_Fileinfo)
1213 : : + (ndirs + 1) * sizeof (char *),
1214 : : 1);
1215 : :
1216 : :
1217 : : /* Copy prevfiles to newfiles. */
1218 [ + + ]: 90 : for (size_t n = 0; n < nprevfiles; n++)
1219 : 88 : newfiles->info[n] = prevfiles->info[n];
1220 : :
1221 : : /* Add files from DW_LNE_define_file to newfiles. */
1222 : : struct filelist *fileslist = filelist;
1223 [ + + ]: 6 : for (size_t n = nfilelist; n > 0; n--)
1224 : : {
1225 : 4 : newfiles->info[nprevfiles + n - 1] = fileslist->info;
1226 : 4 : fileslist = fileslist->next;
1227 : : }
1228 : :
1229 [ - + ]: 2 : if (fileslist != NULL)
1230 : 0 : goto invalid_data;
1231 : :
1232 : 2 : const char **newdirs = (void *) &newfiles->info[nnewfiles];
1233 : 2 : const char **prevdirs = (void *) &prevfiles->info[nprevfiles];
1234 : :
1235 : : /* Copy prevdirs to newdirs. */
1236 [ + + ]: 12 : for (size_t n = 0; n < ndirs; n++)
1237 : 10 : newdirs[n] = prevdirs[n];
1238 : :
1239 : : /* Update filesp. */
1240 : 2 : newfiles->nfiles = nnewfiles;
1241 : 2 : newfiles->ndirs = prevfiles->ndirs;
1242 : 2 : *filesp = newfiles;
1243 : : }
1244 : :
1245 : 3292 : size_t buf_size = (sizeof (Dwarf_Lines)
1246 : 3292 : + (sizeof (Dwarf_Line) * state.nlinelist));
1247 [ + + ]: 3292 : void *buf = libdw_alloc (dbg, Dwarf_Lines, buf_size, 1);
1248 : :
1249 : : /* First use the buffer for the pointers, and sort the entries.
1250 : : We'll write the pointers in the end of the buffer, and then
1251 : : copy into the buffer from the beginning so the overlap works. */
1252 : 3292 : assert (sizeof (Dwarf_Line) >= sizeof (struct linelist *));
1253 : 3292 : struct linelist **sortlines = (buf + buf_size
1254 : 3292 : - sizeof (struct linelist **) * state.nlinelist);
1255 : :
1256 : : /* The list is in LIFO order and usually they come in clumps with
1257 : : ascending addresses. So fill from the back to probably start with
1258 : : runs already in order before we sort. */
1259 : 3292 : struct linelist *lineslist = state.linelist;
1260 [ + + ]: 809254 : for (size_t i = state.nlinelist; i-- > 0; )
1261 : : {
1262 : 805962 : sortlines[i] = lineslist;
1263 : 805962 : lineslist = lineslist->next;
1264 : : }
1265 [ - + ]: 3292 : assert (lineslist == NULL);
1266 : :
1267 : : /* Sort by ascending address. */
1268 : 3292 : qsort (sortlines, state.nlinelist, sizeof sortlines[0], &compare_lines);
1269 : :
1270 : : /* Now that they are sorted, put them in the final array.
1271 : : The buffers overlap, so we've clobbered the early elements
1272 : : of SORTLINES by the time we're reading the later ones. */
1273 : 3292 : Dwarf_Lines *lines = buf;
1274 : 3292 : lines->nlines = state.nlinelist;
1275 [ + + ]: 809254 : for (size_t i = 0; i < state.nlinelist; ++i)
1276 : : {
1277 : 805962 : lines->info[i] = sortlines[i]->line;
1278 : 805962 : lines->info[i].files = *filesp;
1279 : : }
1280 : :
1281 : : /* Make sure the highest address for the CU is marked as end_sequence.
1282 : : This is required by the DWARF spec, but some compilers forget and
1283 : : dwfl_module_getsrc depends on it. */
1284 [ + + ]: 3292 : if (state.nlinelist > 0)
1285 : 3274 : lines->info[state.nlinelist - 1].end_sequence = 1;
1286 : :
1287 : : /* Pass the line structure back to the caller. */
1288 [ + - ]: 3292 : if (linesp != NULL)
1289 : 3292 : *linesp = lines;
1290 : :
1291 : : /* Success. */
1292 : 3292 : res = 0;
1293 : 3292 : goto out;
1294 : :
1295 : 0 : invalid_data:
1296 : 0 : __libdw_seterrno (DWARF_E_INVALID_DEBUG_LINE);
1297 : :
1298 : 3292 : out:
1299 : : /* Free malloced line records, if any. */
1300 [ + + ]: 99854 : for (size_t i = MAX_STACK_LINES; i < state.nlinelist; i++)
1301 : : {
1302 : 96562 : struct linelist *ll = state.linelist->next;
1303 : 96562 : free (state.linelist);
1304 : 96562 : state.linelist = ll;
1305 : : }
1306 : :
1307 : : /* Free file records from DW_LNE_define_file, if any. */
1308 [ + + ]: 3296 : for (size_t i = 0; i < nfilelist; i++)
1309 : : {
1310 : 4 : struct filelist *fl = filelist->next;
1311 : 4 : free (filelist);
1312 : 4 : filelist = fl;
1313 : : }
1314 : :
1315 : : return res;
1316 : : }
1317 : :
1318 : : static int
1319 : 1235842 : files_lines_compare (const void *p1, const void *p2)
1320 : : {
1321 : 1235842 : const struct files_lines_s *t1 = p1;
1322 : 1235842 : const struct files_lines_s *t2 = p2;
1323 : :
1324 [ + + ]: 1235842 : if (t1->debug_line_offset < t2->debug_line_offset)
1325 : : return -1;
1326 [ + + ]: 1235806 : if (t1->debug_line_offset > t2->debug_line_offset)
1327 : 1235768 : return 1;
1328 : :
1329 : : return 0;
1330 : : }
1331 : :
1332 : : static int
1333 : 55252 : get_lines_or_files (Dwarf *dbg, Dwarf_Off debug_line_offset,
1334 : : const char *comp_dir, unsigned address_size,
1335 : : Dwarf_Lines **linesp, Dwarf_Files **filesp)
1336 : : {
1337 : 55252 : struct files_lines_s fake = { .debug_line_offset = debug_line_offset };
1338 : 55252 : struct files_lines_s **found = eu_tfind (&fake, &dbg->files_lines_tree,
1339 : : files_lines_compare);
1340 [ + + ]: 55252 : if (found == NULL)
1341 : : {
1342 : : /* This .debug_line is being read for the first time. */
1343 : 55214 : Elf_Data *data = __libdw_checked_get_data (dbg, IDX_debug_line);
1344 [ + - ]: 55214 : if (data == NULL
1345 [ - + ]: 55214 : || __libdw_offset_in_section (dbg, IDX_debug_line,
1346 : : debug_line_offset, 1) != 0)
1347 : 0 : return -1;
1348 : :
1349 : 55214 : const unsigned char *linep = data->d_buf + debug_line_offset;
1350 : 55214 : const unsigned char *lineendp = data->d_buf + data->d_size;
1351 : :
1352 [ + + ]: 55214 : struct files_lines_s *node = libdw_alloc (dbg, struct files_lines_s,
1353 : : sizeof *node, 1);
1354 : :
1355 : : /* Srcfiles will be read but srclines might not. Set lines here
1356 : : to avoid possible uninitialized value errors. */
1357 : 55214 : node->lines = NULL;
1358 : :
1359 : : /* If linesp is NULL then read srcfiles without reading srclines. */
1360 [ + + ]: 55214 : if (linesp == NULL)
1361 : : {
1362 [ - + ]: 51958 : if (read_srcfiles (dbg, linep, lineendp, comp_dir, address_size,
1363 : : NULL, &node->files) != 0)
1364 : : return -1;
1365 : : }
1366 [ - + ]: 3256 : else if (read_srclines (dbg, linep, lineendp, comp_dir, address_size,
1367 : : &node->lines, &node->files, false) != 0)
1368 : : return -1;
1369 : :
1370 : 55214 : node->debug_line_offset = debug_line_offset;
1371 : :
1372 : 55214 : found = eu_tsearch (node, &dbg->files_lines_tree, files_lines_compare);
1373 [ - + ]: 55214 : if (found == NULL)
1374 : : {
1375 : 0 : __libdw_seterrno (DWARF_E_NOMEM);
1376 : 0 : return -1;
1377 : : }
1378 : : }
1379 [ + - ]: 38 : else if (*found != NULL
1380 [ + - ]: 38 : && (*found)->files != NULL
1381 [ + + ]: 38 : && (*found)->lines == NULL)
1382 : : {
1383 : : /* Srcfiles were already read from this .debug_line. Now read
1384 : : srclines. */
1385 : 36 : Elf_Data *data = __libdw_checked_get_data (dbg, IDX_debug_line);
1386 [ + - ]: 36 : if (data == NULL
1387 [ - + ]: 36 : || __libdw_offset_in_section (dbg, IDX_debug_line,
1388 : : debug_line_offset, 1) != 0)
1389 : 0 : return -1;
1390 : :
1391 : 36 : const unsigned char *linep = data->d_buf + debug_line_offset;
1392 : 36 : const unsigned char *lineendp = data->d_buf + data->d_size;
1393 : :
1394 : 36 : struct files_lines_s *node = *found;
1395 : :
1396 [ - + ]: 36 : if (read_srclines (dbg, linep, lineendp, comp_dir, address_size,
1397 : : &node->lines, &node->files, true) != 0)
1398 : : return -1;
1399 : : }
1400 [ + - ]: 2 : else if (*found != NULL
1401 [ - + ]: 2 : && (*found)->files == NULL
1402 [ # # ]: 0 : && (*found)->lines != NULL)
1403 : : {
1404 : : /* If srclines were read then srcfiles should have also been read. */
1405 : 0 : __libdw_seterrno (DWARF_E_INVALID_DEBUG_LINE);
1406 : 0 : return -1;
1407 : : }
1408 : :
1409 [ + + ]: 55252 : if (linesp != NULL)
1410 : 3286 : *linesp = (*found)->lines;
1411 : :
1412 [ + + ]: 55252 : if (filesp != NULL)
1413 : 55122 : *filesp = (*found)->files;
1414 : :
1415 : : return 0;
1416 : : }
1417 : :
1418 : : int
1419 : : internal_function
1420 : 3344 : __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
1421 : : const char *comp_dir, unsigned address_size,
1422 : : Dwarf_Lines **linesp, Dwarf_Files **filesp)
1423 : : {
1424 : 3344 : return get_lines_or_files (dbg, debug_line_offset, comp_dir,
1425 : : address_size, linesp, filesp);
1426 : : }
1427 : :
1428 : : int
1429 : : internal_function
1430 : 51908 : __libdw_getsrcfiles (Dwarf *dbg, Dwarf_Off debug_line_offset,
1431 : : const char *comp_dir, unsigned address_size,
1432 : : Dwarf_Files **filesp)
1433 : : {
1434 : 51908 : return get_lines_or_files (dbg, debug_line_offset, comp_dir,
1435 : : address_size, NULL, filesp);
1436 : : }
1437 : :
1438 : : /* Get the compilation directory, if any is set. */
1439 : : const char *
1440 : 55188 : __libdw_getcompdir (Dwarf_Die *cudie)
1441 : : {
1442 : 55188 : Dwarf_Attribute compdir_attr_mem;
1443 : 55188 : Dwarf_Attribute *compdir_attr = INTUSE(dwarf_attr) (cudie,
1444 : : DW_AT_comp_dir,
1445 : : &compdir_attr_mem);
1446 : 55188 : return INTUSE(dwarf_formstring) (compdir_attr);
1447 : : }
1448 : :
1449 : : int
1450 : 3244 : dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
1451 : : {
1452 [ - + ]: 3244 : if (cudie == NULL)
1453 : : return -1;
1454 [ - + ]: 3244 : if (! is_cudie (cudie))
1455 : : {
1456 : 0 : __libdw_seterrno (DWARF_E_NOT_CUDIE);
1457 : 0 : return -1;
1458 : : }
1459 : :
1460 : 3244 : struct Dwarf_CU *const cu = cudie->cu;
1461 : 3244 : mutex_lock (cu->src_lock);
1462 : :
1463 : : /* Get the information if it is not already known. */
1464 [ + + ]: 3244 : if (cu->lines == NULL)
1465 : : {
1466 : : /* For split units always pick the lines from the skeleton. */
1467 : 3156 : if (cu->unit_type == DW_UT_split_compile
1468 [ - + ]: 3156 : || cu->unit_type == DW_UT_split_type)
1469 : : {
1470 : : /* We tries, assume we fail... */
1471 : 0 : cu->lines = (void *) -1l;
1472 : :
1473 : 0 : Dwarf_CU *skel = __libdw_find_split_unit (cu);
1474 [ # # ]: 0 : if (skel != NULL)
1475 : : {
1476 : 0 : Dwarf_Die skeldie = CUDIE (skel);
1477 : 0 : int res = INTUSE(dwarf_getsrclines) (&skeldie, lines, nlines);
1478 [ # # ]: 0 : if (res == 0)
1479 : : {
1480 : 0 : cu->lines = skel->lines;
1481 : 0 : *lines = cu->lines;
1482 : 0 : *nlines = cu->lines->nlines;
1483 : : }
1484 : :
1485 : 0 : mutex_unlock (cu->src_lock);
1486 : 0 : return res;
1487 : : }
1488 : :
1489 : 0 : __libdw_seterrno (DWARF_E_NO_DEBUG_LINE);
1490 : 0 : mutex_unlock (cu->src_lock);
1491 : 0 : return -1;
1492 : : }
1493 : :
1494 : : /* Failsafe mode: no data found. */
1495 : 3156 : cu->lines = (void *) -1l;
1496 : 3156 : cu->files = (void *) -1l;
1497 : :
1498 : : /* The die must have a statement list associated. */
1499 : 3156 : Dwarf_Attribute stmt_list_mem;
1500 : 3156 : Dwarf_Attribute *stmt_list = INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list,
1501 : : &stmt_list_mem);
1502 : :
1503 : : /* Get the offset into the .debug_line section. NB: this call
1504 : : also checks whether the previous dwarf_attr call failed. */
1505 : 3156 : Dwarf_Off debug_line_offset;
1506 [ + - ]: 3156 : if (__libdw_formptr (stmt_list, IDX_debug_line, DWARF_E_NO_DEBUG_LINE,
1507 : : NULL, &debug_line_offset) == NULL)
1508 : : {
1509 : : mutex_unlock (cu->src_lock);
1510 : : return -1;
1511 : : }
1512 : :
1513 [ + - ]: 3156 : if (__libdw_getsrclines (cu->dbg, debug_line_offset,
1514 : : __libdw_getcompdir (cudie),
1515 : 3156 : cu->address_size, &cu->lines, &cu->files) < 0)
1516 : : {
1517 : : mutex_unlock (cu->src_lock);
1518 : : return -1;
1519 : : }
1520 : : }
1521 [ - + ]: 88 : else if (cu->lines == (void *) -1l)
1522 : : {
1523 : : mutex_unlock (cu->src_lock);
1524 : : return -1;
1525 : : }
1526 : :
1527 : 3244 : *lines = cu->lines;
1528 : 3244 : *nlines = cu->lines->nlines;
1529 : :
1530 : 3244 : mutex_unlock (cu->src_lock);
1531 : 3244 : return 0;
1532 : : }
1533 : : INTDEF(dwarf_getsrclines)
|