Line data Source code
1 : /* Return line number information of CU.
2 : Copyright (C) 2004-2010, 2013, 2014, 2015, 2016 Red Hat, Inc.
3 : This file is part of elfutils.
4 : Written by Ulrich Drepper <drepper@redhat.com>, 2004.
5 :
6 : This file is free software; you can redistribute it and/or modify
7 : it under the terms of either
8 :
9 : * the GNU Lesser General Public License as published by the Free
10 : Software Foundation; either version 3 of the License, or (at
11 : your option) any later version
12 :
13 : or
14 :
15 : * the GNU General Public License as published by the Free
16 : Software Foundation; either version 2 of the License, or (at
17 : your option) any later version
18 :
19 : or both in parallel, as here.
20 :
21 : elfutils is distributed in the hope that it will be useful, but
22 : WITHOUT ANY WARRANTY; without even the implied warranty of
23 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 : General Public License for more details.
25 :
26 : You should have received copies of the GNU General Public License and
27 : the GNU Lesser General Public License along with this program. If
28 : not, see <http://www.gnu.org/licenses/>. */
29 :
30 : #ifdef HAVE_CONFIG_H
31 : # include <config.h>
32 : #endif
33 :
34 : #include <assert.h>
35 : #include <stdlib.h>
36 : #include <string.h>
37 : #include <search.h>
38 :
39 : #include "dwarf.h"
40 : #include "libdwP.h"
41 :
42 :
43 : struct filelist
44 : {
45 : Dwarf_Fileinfo info;
46 : struct filelist *next;
47 : };
48 :
49 : struct linelist
50 : {
51 : Dwarf_Line line;
52 : struct linelist *next;
53 : size_t sequence;
54 : };
55 :
56 :
57 : /* Compare by Dwarf_Line.addr, given pointers into an array of pointers. */
58 : static int
59 1387397 : compare_lines (const void *a, const void *b)
60 : {
61 1387397 : struct linelist *const *p1 = a;
62 1387397 : struct linelist *const *p2 = b;
63 1387397 : struct linelist *list1 = *p1;
64 1387397 : struct linelist *list2 = *p2;
65 1387397 : Dwarf_Line *line1 = &list1->line;
66 1387397 : Dwarf_Line *line2 = &list2->line;
67 :
68 1387397 : if (line1->addr != line2->addr)
69 1383979 : return (line1->addr < line2->addr) ? -1 : 1;
70 :
71 : /* An end_sequence marker precedes a normal record at the same address. */
72 3418 : if (line1->end_sequence != line2->end_sequence)
73 13 : return line2->end_sequence - line1->end_sequence;
74 :
75 : /* Otherwise, the linelist sequence maintains a stable sort. */
76 3405 : return (list1->sequence < list2->sequence) ? -1
77 3405 : : (list1->sequence > list2->sequence) ? 1
78 0 : : 0;
79 : }
80 :
81 : struct line_state
82 : {
83 : Dwarf_Word addr;
84 : unsigned int op_index;
85 : unsigned int file;
86 : int64_t line;
87 : unsigned int column;
88 : uint_fast8_t is_stmt;
89 : bool basic_block;
90 : bool prologue_end;
91 : bool epilogue_begin;
92 : unsigned int isa;
93 : unsigned int discriminator;
94 : struct linelist *linelist;
95 : size_t nlinelist;
96 : unsigned int end_sequence;
97 : };
98 :
99 : static inline void
100 : run_advance_pc (struct line_state *state, unsigned int op_advance,
101 : uint_fast8_t minimum_instr_len, uint_fast8_t max_ops_per_instr)
102 : {
103 900400 : state->addr += minimum_instr_len * ((state->op_index + op_advance)
104 450200 : / max_ops_per_instr);
105 450200 : state->op_index = (state->op_index + op_advance) % max_ops_per_instr;
106 : }
107 :
108 : static inline bool
109 367106 : add_new_line (struct line_state *state, struct linelist *new_line)
110 : {
111 : /* Set the line information. For some fields we use bitfields,
112 : so we would lose information if the encoded values are too large.
113 : Check just for paranoia, and call the data "invalid" if it
114 : violates our assumptions on reasonable limits for the values. */
115 367106 : new_line->next = state->linelist;
116 367106 : new_line->sequence = state->nlinelist;
117 367106 : state->linelist = new_line;
118 367106 : ++(state->nlinelist);
119 :
120 : /* Set the line information. For some fields we use bitfields,
121 : so we would lose information if the encoded values are too large.
122 : Check just for paranoia, and call the data "invalid" if it
123 : violates our assumptions on reasonable limits for the values. */
124 : #define SET(field) \
125 : do { \
126 : new_line->line.field = state->field; \
127 : if (unlikely (new_line->line.field != state->field)) \
128 : return true; \
129 : } while (0)
130 :
131 367106 : SET (addr);
132 367106 : SET (op_index);
133 367106 : SET (file);
134 367106 : SET (line);
135 367106 : SET (column);
136 367106 : SET (is_stmt);
137 367106 : SET (basic_block);
138 367106 : SET (end_sequence);
139 367106 : SET (prologue_end);
140 367106 : SET (epilogue_begin);
141 367106 : SET (isa);
142 367106 : SET (discriminator);
143 :
144 : #undef SET
145 :
146 367106 : return false;
147 : }
148 :
149 : static int
150 4338 : read_srclines (Dwarf *dbg,
151 : const unsigned char *linep, const unsigned char *lineendp,
152 : const char *comp_dir, unsigned address_size,
153 : Dwarf_Lines **linesp, Dwarf_Files **filesp)
154 : {
155 4338 : int res = -1;
156 :
157 4338 : size_t nfilelist = 0;
158 4338 : unsigned int ndirlist = 0;
159 :
160 4338 : struct filelist null_file =
161 : {
162 : .info =
163 : {
164 : .name = "???",
165 : .mtime = 0,
166 : .length = 0
167 : },
168 : .next = NULL
169 : };
170 4338 : struct filelist *filelist = &null_file;
171 :
172 : /* If there are a large number of lines, files or dirs don't blow up
173 : the stack. Stack allocate some entries, only dynamically malloc
174 : when more than MAX. */
175 : #define MAX_STACK_ALLOC 4096
176 : #define MAX_STACK_LINES MAX_STACK_ALLOC
177 : #define MAX_STACK_FILES (MAX_STACK_ALLOC / 4)
178 : #define MAX_STACK_DIRS (MAX_STACK_ALLOC / 16)
179 :
180 : struct dirlist
181 : {
182 : const char *dir;
183 : size_t len;
184 : };
185 : struct dirlist dirstack[MAX_STACK_DIRS];
186 4338 : struct dirlist *dirarray = dirstack;
187 :
188 : /* We are about to process the statement program. Initialize the
189 : state machine registers (see 6.2.2 in the v2.1 specification). */
190 4338 : struct line_state state =
191 : {
192 : .linelist = NULL,
193 : .nlinelist = 0,
194 : .addr = 0,
195 : .op_index = 0,
196 : .file = 1,
197 : /* We only store int but want to check for overflow (see SET above). */
198 : .line = 1,
199 : .column = 0,
200 : .basic_block = false,
201 : .prologue_end = false,
202 : .epilogue_begin = false,
203 : .isa = 0,
204 : .discriminator = 0
205 : };
206 :
207 4338 : if (unlikely (linep + 4 > lineendp))
208 : {
209 : invalid_data:
210 0 : __libdw_seterrno (DWARF_E_INVALID_DEBUG_LINE);
211 0 : goto out;
212 : }
213 :
214 4354 : Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
215 4338 : unsigned int length = 4;
216 4338 : if (unlikely (unit_length == DWARF3_LENGTH_64_BIT))
217 : {
218 0 : if (unlikely (linep + 8 > lineendp))
219 : goto invalid_data;
220 0 : unit_length = read_8ubyte_unaligned_inc (dbg, linep);
221 0 : length = 8;
222 : }
223 :
224 : /* Check whether we have enough room in the section. */
225 4338 : if (unlikely (unit_length > (size_t) (lineendp - linep)
226 : || unit_length < 2 + length + 5 * 1))
227 : goto invalid_data;
228 4338 : lineendp = linep + unit_length;
229 :
230 : /* The next element of the header is the version identifier. */
231 4338 : uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
232 4338 : if (unlikely (version < 2) || unlikely (version > 4))
233 : {
234 0 : __libdw_seterrno (DWARF_E_VERSION);
235 0 : goto out;
236 : }
237 :
238 : /* Next comes the header length. */
239 : Dwarf_Word header_length;
240 4338 : if (length == 4)
241 4354 : header_length = read_4ubyte_unaligned_inc (dbg, linep);
242 : else
243 0 : header_length = read_8ubyte_unaligned_inc (dbg, linep);
244 4338 : const unsigned char *header_start = linep;
245 :
246 : /* Next the minimum instruction length. */
247 4338 : uint_fast8_t minimum_instr_len = *linep++;
248 :
249 : /* Next the maximum operations per instruction, in version 4 format. */
250 4338 : uint_fast8_t max_ops_per_instr = 1;
251 4338 : if (version >= 4)
252 : {
253 0 : if (unlikely (lineendp - linep < 5))
254 : goto invalid_data;
255 0 : max_ops_per_instr = *linep++;
256 0 : if (unlikely (max_ops_per_instr == 0))
257 : goto invalid_data;
258 : }
259 :
260 : /* Then the flag determining the default value of the is_stmt
261 : register. */
262 4338 : uint_fast8_t default_is_stmt = *linep++;
263 :
264 : /* Now the line base. */
265 4338 : int_fast8_t line_base = (int8_t) *linep++;
266 :
267 : /* And the line range. */
268 4338 : uint_fast8_t line_range = *linep++;
269 :
270 : /* The opcode base. */
271 4338 : uint_fast8_t opcode_base = *linep++;
272 :
273 : /* Remember array with the standard opcode length (-1 to account for
274 : the opcode with value zero not being mentioned). */
275 4338 : const uint8_t *standard_opcode_lengths = linep - 1;
276 4338 : if (unlikely (lineendp - linep < opcode_base - 1))
277 : goto invalid_data;
278 4338 : linep += opcode_base - 1;
279 :
280 : /* First comes the list of directories. Add the compilation
281 : directory first since the index zero is used for it. */
282 8676 : struct dirlist comp_dir_elem =
283 : {
284 : .dir = comp_dir,
285 4338 : .len = comp_dir ? strlen (comp_dir) : 0,
286 : };
287 4338 : ndirlist = 1;
288 :
289 : /* First count the entries. */
290 4338 : const unsigned char *dirp = linep;
291 4338 : unsigned int ndirs = 0;
292 33190 : while (*dirp != 0)
293 : {
294 24514 : uint8_t *endp = memchr (dirp, '\0', lineendp - dirp);
295 24514 : if (endp == NULL)
296 : goto invalid_data;
297 24514 : ++ndirs;
298 24514 : dirp = endp + 1;
299 : }
300 4338 : ndirlist += ndirs;
301 :
302 : /* Arrange the list in array form. */
303 4338 : if (ndirlist >= MAX_STACK_DIRS)
304 : {
305 0 : dirarray = (struct dirlist *) malloc (ndirlist * sizeof (*dirarray));
306 0 : if (unlikely (dirarray == NULL))
307 : {
308 : no_mem:
309 0 : __libdw_seterrno (DWARF_E_NOMEM);
310 0 : goto out;
311 : }
312 : }
313 4338 : dirarray[0] = comp_dir_elem;
314 28852 : for (unsigned int n = 1; n < ndirlist; n++)
315 : {
316 24514 : dirarray[n].dir = (char *) linep;
317 24514 : uint8_t *endp = memchr (linep, '\0', lineendp - linep);
318 24514 : assert (endp != NULL);
319 24514 : dirarray[n].len = endp - linep;
320 24514 : linep = endp + 1;
321 : }
322 : /* Skip the final NUL byte. */
323 4338 : ++linep;
324 :
325 : /* Allocate memory for a new file. For the first MAX_STACK_FILES
326 : entries just return a slot in the preallocated stack array. */
327 : struct filelist flstack[MAX_STACK_FILES];
328 : #define NEW_FILE() ({ \
329 : struct filelist *fl = (nfilelist < MAX_STACK_FILES \
330 : ? &flstack[nfilelist] \
331 : : malloc (sizeof (struct filelist))); \
332 : if (unlikely (fl == NULL)) \
333 : goto no_mem; \
334 : ++nfilelist; \
335 : fl->next = filelist; \
336 : filelist = fl; \
337 : fl; })
338 :
339 : /* Now read the files. */
340 4338 : nfilelist = 1;
341 :
342 4338 : if (unlikely (linep >= lineendp))
343 : goto invalid_data;
344 72662 : while (*linep != 0)
345 : {
346 68324 : struct filelist *new_file = NEW_FILE ();
347 :
348 : /* First comes the file name. */
349 68324 : char *fname = (char *) linep;
350 68324 : uint8_t *endp = memchr (fname, '\0', lineendp - linep);
351 68324 : if (endp == NULL)
352 : goto invalid_data;
353 68324 : size_t fnamelen = endp - (uint8_t *) fname;
354 68324 : linep = endp + 1;
355 :
356 : /* Then the index. */
357 : Dwarf_Word diridx;
358 68324 : if (unlikely (linep >= lineendp))
359 : goto invalid_data;
360 68324 : get_uleb128 (diridx, linep, lineendp);
361 68324 : if (unlikely (diridx >= ndirlist))
362 : {
363 0 : __libdw_seterrno (DWARF_E_INVALID_DIR_IDX);
364 0 : goto out;
365 : }
366 :
367 68324 : if (*fname == '/')
368 : /* It's an absolute path. */
369 302 : new_file->info.name = fname;
370 : else
371 : {
372 68022 : new_file->info.name = libdw_alloc (dbg, char, 1,
373 : dirarray[diridx].len + 1
374 : + fnamelen + 1);
375 68022 : char *cp = new_file->info.name;
376 :
377 68022 : if (dirarray[diridx].dir != NULL)
378 : {
379 : /* This value could be NULL in case the DW_AT_comp_dir
380 : was not present. We cannot do much in this case.
381 : The easiest thing is to convert the path in an
382 : absolute path. */
383 68022 : cp = stpcpy (cp, dirarray[diridx].dir);
384 : }
385 68022 : *cp++ = '/';
386 68022 : strcpy (cp, fname);
387 68022 : assert (strlen (new_file->info.name)
388 : < dirarray[diridx].len + 1 + fnamelen + 1);
389 : }
390 :
391 : /* Next comes the modification time. */
392 68324 : if (unlikely (linep >= lineendp))
393 : goto invalid_data;
394 68324 : get_uleb128 (new_file->info.mtime, linep, lineendp);
395 :
396 : /* Finally the length of the file. */
397 68324 : if (unlikely (linep >= lineendp))
398 : goto invalid_data;
399 68324 : get_uleb128 (new_file->info.length, linep, lineendp);
400 : }
401 : /* Skip the final NUL byte. */
402 4338 : ++linep;
403 :
404 : /* Consistency check. */
405 4338 : if (unlikely (linep != header_start + header_length))
406 : {
407 0 : __libdw_seterrno (DWARF_E_INVALID_DWARF);
408 0 : goto out;
409 : }
410 :
411 4338 : state.is_stmt = default_is_stmt;
412 :
413 : /* Apply the "operation advance" from a special opcode or
414 : DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
415 : #define advance_pc(op_advance) \
416 : run_advance_pc (&state, op_advance, minimum_instr_len, max_ops_per_instr)
417 :
418 : /* Process the instructions. */
419 :
420 : /* Adds a new line to the matrix. For the first MAX_STACK_LINES
421 : entries just return a slot in the preallocated stack array. */
422 : struct linelist llstack[MAX_STACK_LINES];
423 : #define NEW_LINE(end_seq) \
424 : do { \
425 : struct linelist *ll = (state.nlinelist < MAX_STACK_LINES \
426 : ? &llstack[state.nlinelist] \
427 : : malloc (sizeof (struct linelist))); \
428 : if (unlikely (ll == NULL)) \
429 : goto no_mem; \
430 : state.end_sequence = end_seq; \
431 : if (unlikely (add_new_line (&state, ll))) \
432 : goto invalid_data; \
433 : } while (0)
434 :
435 720177 : while (linep < lineendp)
436 : {
437 : unsigned int opcode;
438 : unsigned int u128;
439 : int s128;
440 :
441 : /* Read the opcode. */
442 711501 : opcode = *linep++;
443 :
444 : /* Is this a special opcode? */
445 711501 : if (likely (opcode >= opcode_base))
446 : {
447 340733 : if (unlikely (line_range == 0))
448 : goto invalid_data;
449 :
450 : /* Yes. Handling this is quite easy since the opcode value
451 : is computed with
452 :
453 : opcode = (desired line increment - line_base)
454 : + (line_range * address advance) + opcode_base
455 : */
456 340733 : int line_increment = (line_base
457 340733 : + (opcode - opcode_base) % line_range);
458 :
459 : /* Perform the increments. */
460 340733 : state.line += line_increment;
461 681466 : advance_pc ((opcode - opcode_base) / line_range);
462 :
463 : /* Add a new line with the current state machine values. */
464 340733 : NEW_LINE (0);
465 :
466 : /* Reset the flags. */
467 340733 : state.basic_block = false;
468 340733 : state.prologue_end = false;
469 340733 : state.epilogue_begin = false;
470 340733 : state.discriminator = 0;
471 : }
472 370768 : else if (opcode == 0)
473 : {
474 : /* This an extended opcode. */
475 46969 : if (unlikely (lineendp - linep < 2))
476 : goto invalid_data;
477 :
478 : /* The length. */
479 46969 : uint_fast8_t len = *linep++;
480 :
481 46969 : if (unlikely ((size_t) (lineendp - linep) < len))
482 : goto invalid_data;
483 :
484 : /* The sub-opcode. */
485 46969 : opcode = *linep++;
486 :
487 46969 : switch (opcode)
488 : {
489 : case DW_LNE_end_sequence:
490 : /* Add a new line with the current state machine values.
491 : The is the end of the sequence. */
492 4445 : NEW_LINE (1);
493 :
494 : /* Reset the registers. */
495 4445 : state.addr = 0;
496 4445 : state.op_index = 0;
497 4445 : state.file = 1;
498 4445 : state.line = 1;
499 4445 : state.column = 0;
500 4445 : state.is_stmt = default_is_stmt;
501 4445 : state.basic_block = false;
502 4445 : state.prologue_end = false;
503 4445 : state.epilogue_begin = false;
504 4445 : state.isa = 0;
505 4445 : state.discriminator = 0;
506 4445 : break;
507 :
508 : case DW_LNE_set_address:
509 : /* The value is an address. The size is defined as
510 : apporiate for the target machine. We use the
511 : address size field from the CU header. */
512 4630 : state.op_index = 0;
513 4630 : if (unlikely (lineendp - linep < (uint8_t) address_size))
514 : goto invalid_data;
515 4630 : if (__libdw_read_address_inc (dbg, IDX_debug_line, &linep,
516 : address_size, &state.addr))
517 : goto out;
518 : break;
519 :
520 : case DW_LNE_define_file:
521 : {
522 0 : char *fname = (char *) linep;
523 0 : uint8_t *endp = memchr (linep, '\0', lineendp - linep);
524 0 : if (endp == NULL)
525 : goto invalid_data;
526 0 : size_t fnamelen = endp - linep;
527 0 : linep = endp + 1;
528 :
529 : unsigned int diridx;
530 0 : if (unlikely (linep >= lineendp))
531 : goto invalid_data;
532 0 : get_uleb128 (diridx, linep, lineendp);
533 0 : if (unlikely (diridx >= ndirlist))
534 : {
535 0 : __libdw_seterrno (DWARF_E_INVALID_DIR_IDX);
536 0 : goto invalid_data;
537 : }
538 : Dwarf_Word mtime;
539 0 : if (unlikely (linep >= lineendp))
540 : goto invalid_data;
541 0 : get_uleb128 (mtime, linep, lineendp);
542 : Dwarf_Word filelength;
543 0 : if (unlikely (linep >= lineendp))
544 : goto invalid_data;
545 0 : get_uleb128 (filelength, linep, lineendp);
546 :
547 0 : struct filelist *new_file = NEW_FILE ();
548 0 : if (fname[0] == '/')
549 0 : new_file->info.name = fname;
550 : else
551 : {
552 0 : new_file->info.name =
553 0 : libdw_alloc (dbg, char, 1, (dirarray[diridx].len + 1
554 : + fnamelen + 1));
555 0 : char *cp = new_file->info.name;
556 :
557 0 : if (dirarray[diridx].dir != NULL)
558 : /* This value could be NULL in case the
559 : DW_AT_comp_dir was not present. We
560 : cannot do much in this case. The easiest
561 : thing is to convert the path in an
562 : absolute path. */
563 0 : cp = stpcpy (cp, dirarray[diridx].dir);
564 0 : *cp++ = '/';
565 0 : strcpy (cp, fname);
566 : }
567 :
568 0 : new_file->info.mtime = mtime;
569 0 : new_file->info.length = filelength;
570 : }
571 0 : break;
572 :
573 : case DW_LNE_set_discriminator:
574 : /* Takes one ULEB128 parameter, the discriminator. */
575 37890 : if (unlikely (standard_opcode_lengths[opcode] != 1))
576 : goto invalid_data;
577 :
578 37890 : if (unlikely (linep >= lineendp))
579 : goto invalid_data;
580 37890 : get_uleb128 (state.discriminator, linep, lineendp);
581 37890 : break;
582 :
583 : default:
584 : /* Unknown, ignore it. */
585 : if (unlikely ((size_t) (lineendp - (linep - 1)) < len))
586 : goto invalid_data;
587 4 : linep += len - 1;
588 4 : break;
589 : }
590 : }
591 323799 : else if (opcode <= DW_LNS_set_isa)
592 : {
593 : /* This is a known standard opcode. */
594 323799 : switch (opcode)
595 : {
596 : case DW_LNS_copy:
597 : /* Takes no argument. */
598 21928 : if (unlikely (standard_opcode_lengths[opcode] != 0))
599 : goto invalid_data;
600 :
601 : /* Add a new line with the current state machine values. */
602 21928 : NEW_LINE (0);
603 :
604 : /* Reset the flags. */
605 21928 : state.basic_block = false;
606 21928 : state.prologue_end = false;
607 21928 : state.epilogue_begin = false;
608 21928 : state.discriminator = 0;
609 21928 : break;
610 :
611 : case DW_LNS_advance_pc:
612 : /* Takes one uleb128 parameter which is added to the
613 : address. */
614 33537 : if (unlikely (standard_opcode_lengths[opcode] != 1))
615 : goto invalid_data;
616 :
617 33537 : if (unlikely (linep >= lineendp))
618 : goto invalid_data;
619 33537 : get_uleb128 (u128, linep, lineendp);
620 33537 : advance_pc (u128);
621 : break;
622 :
623 : case DW_LNS_advance_line:
624 : /* Takes one sleb128 parameter which is added to the
625 : line. */
626 136791 : if (unlikely (standard_opcode_lengths[opcode] != 1))
627 : goto invalid_data;
628 :
629 136791 : if (unlikely (linep >= lineendp))
630 : goto invalid_data;
631 136791 : get_sleb128 (s128, linep, lineendp);
632 136791 : state.line += s128;
633 136791 : break;
634 :
635 : case DW_LNS_set_file:
636 : /* Takes one uleb128 parameter which is stored in file. */
637 39522 : if (unlikely (standard_opcode_lengths[opcode] != 1))
638 : goto invalid_data;
639 :
640 39522 : if (unlikely (linep >= lineendp))
641 : goto invalid_data;
642 39522 : get_uleb128 (u128, linep, lineendp);
643 39522 : state.file = u128;
644 39522 : break;
645 :
646 : case DW_LNS_set_column:
647 : /* Takes one uleb128 parameter which is stored in column. */
648 0 : if (unlikely (standard_opcode_lengths[opcode] != 1))
649 : goto invalid_data;
650 :
651 0 : if (unlikely (linep >= lineendp))
652 : goto invalid_data;
653 0 : get_uleb128 (u128, linep, lineendp);
654 0 : state.column = u128;
655 0 : break;
656 :
657 : case DW_LNS_negate_stmt:
658 : /* Takes no argument. */
659 16089 : if (unlikely (standard_opcode_lengths[opcode] != 0))
660 : goto invalid_data;
661 :
662 16089 : state.is_stmt = 1 - state.is_stmt;
663 16089 : break;
664 :
665 : case DW_LNS_set_basic_block:
666 : /* Takes no argument. */
667 0 : if (unlikely (standard_opcode_lengths[opcode] != 0))
668 : goto invalid_data;
669 :
670 0 : state.basic_block = true;
671 0 : break;
672 :
673 : case DW_LNS_const_add_pc:
674 : /* Takes no argument. */
675 75930 : if (unlikely (standard_opcode_lengths[opcode] != 0))
676 : goto invalid_data;
677 :
678 75930 : if (unlikely (line_range == 0))
679 : goto invalid_data;
680 :
681 75930 : advance_pc ((255 - opcode_base) / line_range);
682 : break;
683 :
684 : case DW_LNS_fixed_advance_pc:
685 : /* Takes one 16 bit parameter which is added to the
686 : address. */
687 0 : if (unlikely (standard_opcode_lengths[opcode] != 1)
688 0 : || unlikely (lineendp - linep < 2))
689 : goto invalid_data;
690 :
691 0 : state.addr += read_2ubyte_unaligned_inc (dbg, linep);
692 0 : state.op_index = 0;
693 0 : break;
694 :
695 : case DW_LNS_set_prologue_end:
696 : /* Takes no argument. */
697 2 : if (unlikely (standard_opcode_lengths[opcode] != 0))
698 : goto invalid_data;
699 :
700 2 : state.prologue_end = true;
701 2 : break;
702 :
703 : case DW_LNS_set_epilogue_begin:
704 : /* Takes no argument. */
705 0 : if (unlikely (standard_opcode_lengths[opcode] != 0))
706 : goto invalid_data;
707 :
708 0 : state.epilogue_begin = true;
709 0 : break;
710 :
711 : case DW_LNS_set_isa:
712 : /* Takes one uleb128 parameter which is stored in isa. */
713 0 : if (unlikely (standard_opcode_lengths[opcode] != 1))
714 : goto invalid_data;
715 :
716 0 : if (unlikely (linep >= lineendp))
717 : goto invalid_data;
718 0 : get_uleb128 (state.isa, linep, lineendp);
719 0 : break;
720 : }
721 : }
722 : else
723 : {
724 : /* This is a new opcode the generator but not we know about.
725 : Read the parameters associated with it but then discard
726 : everything. Read all the parameters for this opcode. */
727 0 : for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
728 : {
729 0 : if (unlikely (linep >= lineendp))
730 : goto invalid_data;
731 0 : get_uleb128 (u128, linep, lineendp);
732 : }
733 :
734 : /* Next round, ignore this opcode. */
735 0 : continue;
736 : }
737 : }
738 :
739 : /* Put all the files in an array. */
740 4338 : Dwarf_Files *files = libdw_alloc (dbg, Dwarf_Files,
741 : sizeof (Dwarf_Files)
742 : + nfilelist * sizeof (Dwarf_Fileinfo)
743 : + (ndirlist + 1) * sizeof (char *),
744 : 1);
745 4338 : const char **dirs = (void *) &files->info[nfilelist];
746 :
747 4338 : struct filelist *fileslist = filelist;
748 4338 : files->nfiles = nfilelist;
749 77000 : for (size_t n = nfilelist; n > 0; n--)
750 : {
751 72662 : files->info[n - 1] = fileslist->info;
752 72662 : fileslist = fileslist->next;
753 : }
754 4338 : assert (fileslist == NULL);
755 :
756 : /* Put all the directory strings in an array. */
757 4338 : files->ndirs = ndirlist;
758 33190 : for (unsigned int i = 0; i < ndirlist; ++i)
759 28852 : dirs[i] = dirarray[i].dir;
760 4338 : dirs[ndirlist] = NULL;
761 :
762 : /* Pass the file data structure to the caller. */
763 4338 : if (filesp != NULL)
764 4338 : *filesp = files;
765 :
766 4338 : size_t buf_size = (sizeof (Dwarf_Lines)
767 4338 : + (sizeof (Dwarf_Line) * state.nlinelist));
768 4338 : void *buf = libdw_alloc (dbg, Dwarf_Lines, buf_size, 1);
769 :
770 : /* First use the buffer for the pointers, and sort the entries.
771 : We'll write the pointers in the end of the buffer, and then
772 : copy into the buffer from the beginning so the overlap works. */
773 : assert (sizeof (Dwarf_Line) >= sizeof (struct linelist *));
774 4338 : struct linelist **sortlines = (buf + buf_size
775 4338 : - sizeof (struct linelist **) * state.nlinelist);
776 :
777 : /* The list is in LIFO order and usually they come in clumps with
778 : ascending addresses. So fill from the back to probably start with
779 : runs already in order before we sort. */
780 4338 : struct linelist *lineslist = state.linelist;
781 375782 : for (size_t i = state.nlinelist; i-- > 0; )
782 : {
783 367106 : sortlines[i] = lineslist;
784 367106 : lineslist = lineslist->next;
785 : }
786 4338 : assert (lineslist == NULL);
787 :
788 : /* Sort by ascending address. */
789 4338 : qsort (sortlines, state.nlinelist, sizeof sortlines[0], &compare_lines);
790 :
791 : /* Now that they are sorted, put them in the final array.
792 : The buffers overlap, so we've clobbered the early elements
793 : of SORTLINES by the time we're reading the later ones. */
794 4338 : Dwarf_Lines *lines = buf;
795 4338 : lines->nlines = state.nlinelist;
796 371444 : for (size_t i = 0; i < state.nlinelist; ++i)
797 : {
798 367106 : lines->info[i] = sortlines[i]->line;
799 367106 : lines->info[i].files = files;
800 : }
801 :
802 : /* Make sure the highest address for the CU is marked as end_sequence.
803 : This is required by the DWARF spec, but some compilers forget and
804 : dwfl_module_getsrc depends on it. */
805 4338 : if (state.nlinelist > 0)
806 4336 : lines->info[state.nlinelist - 1].end_sequence = 1;
807 :
808 : /* Pass the line structure back to the caller. */
809 4338 : if (linesp != NULL)
810 4338 : *linesp = lines;
811 :
812 : /* Success. */
813 : res = 0;
814 :
815 : out:
816 : /* Free malloced line records, if any. */
817 7459 : for (size_t i = MAX_STACK_LINES; i < state.nlinelist; i++)
818 : {
819 3121 : struct linelist *ll = state.linelist->next;
820 3121 : free (state.linelist);
821 3121 : state.linelist = ll;
822 : }
823 4338 : if (ndirlist >= MAX_STACK_DIRS)
824 0 : free (dirarray);
825 0 : for (size_t i = MAX_STACK_FILES; i < nfilelist; i++)
826 : {
827 0 : struct filelist *fl = filelist->next;
828 0 : free (filelist);
829 0 : filelist = fl;
830 : }
831 :
832 4338 : return res;
833 : }
834 :
835 : static int
836 70046 : files_lines_compare (const void *p1, const void *p2)
837 : {
838 70046 : const struct files_lines_s *t1 = p1;
839 70046 : const struct files_lines_s *t2 = p2;
840 :
841 70046 : if (t1->debug_line_offset < t2->debug_line_offset)
842 : return -1;
843 70034 : if (t1->debug_line_offset > t2->debug_line_offset)
844 : return 1;
845 :
846 0 : return 0;
847 : }
848 :
849 : int
850 : internal_function
851 4338 : __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
852 : const char *comp_dir, unsigned address_size,
853 : Dwarf_Lines **linesp, Dwarf_Files **filesp)
854 : {
855 4338 : struct files_lines_s fake = { .debug_line_offset = debug_line_offset };
856 4338 : struct files_lines_s **found = tfind (&fake, &dbg->files_lines,
857 : files_lines_compare);
858 4338 : if (found == NULL)
859 : {
860 4338 : Elf_Data *data = __libdw_checked_get_data (dbg, IDX_debug_line);
861 4338 : if (data == NULL
862 4338 : || __libdw_offset_in_section (dbg, IDX_debug_line,
863 : debug_line_offset, 1) != 0)
864 : return -1;
865 :
866 4338 : const unsigned char *linep = data->d_buf + debug_line_offset;
867 4338 : const unsigned char *lineendp = data->d_buf + data->d_size;
868 :
869 4338 : struct files_lines_s *node = libdw_alloc (dbg, struct files_lines_s,
870 : sizeof *node, 1);
871 :
872 4338 : if (read_srclines (dbg, linep, lineendp, comp_dir, address_size,
873 : &node->lines, &node->files) != 0)
874 : return -1;
875 :
876 4338 : node->debug_line_offset = debug_line_offset;
877 :
878 4338 : found = tsearch (node, &dbg->files_lines, files_lines_compare);
879 4338 : if (found == NULL)
880 : {
881 0 : __libdw_seterrno (DWARF_E_NOMEM);
882 0 : return -1;
883 : }
884 : }
885 :
886 4338 : if (linesp != NULL)
887 4334 : *linesp = (*found)->lines;
888 :
889 4338 : if (filesp != NULL)
890 4338 : *filesp = (*found)->files;
891 :
892 : return 0;
893 : }
894 :
895 : /* Get the compilation directory, if any is set. */
896 : const char *
897 4348 : __libdw_getcompdir (Dwarf_Die *cudie)
898 : {
899 : Dwarf_Attribute compdir_attr_mem;
900 4348 : Dwarf_Attribute *compdir_attr = INTUSE(dwarf_attr) (cudie,
901 : DW_AT_comp_dir,
902 : &compdir_attr_mem);
903 4348 : return INTUSE(dwarf_formstring) (compdir_attr);
904 : }
905 :
906 : int
907 4366 : dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
908 : {
909 4366 : if (cudie == NULL)
910 : return -1;
911 8732 : if (! is_cudie (cudie))
912 : {
913 0 : __libdw_seterrno (DWARF_E_NOT_CUDIE);
914 0 : return -1;
915 : }
916 :
917 : /* Get the information if it is not already known. */
918 4366 : struct Dwarf_CU *const cu = cudie->cu;
919 4366 : if (cu->lines == NULL)
920 : {
921 : /* Failsafe mode: no data found. */
922 4334 : cu->lines = (void *) -1l;
923 4334 : cu->files = (void *) -1l;
924 :
925 : /* The die must have a statement list associated. */
926 : Dwarf_Attribute stmt_list_mem;
927 4334 : Dwarf_Attribute *stmt_list = INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list,
928 : &stmt_list_mem);
929 :
930 : /* Get the offset into the .debug_line section. NB: this call
931 : also checks whether the previous dwarf_attr call failed. */
932 : Dwarf_Off debug_line_offset;
933 4334 : if (__libdw_formptr (stmt_list, IDX_debug_line, DWARF_E_NO_DEBUG_LINE,
934 : NULL, &debug_line_offset) == NULL)
935 0 : return -1;
936 :
937 8668 : if (__libdw_getsrclines (cu->dbg, debug_line_offset,
938 : __libdw_getcompdir (cudie),
939 4334 : cu->address_size, &cu->lines, &cu->files) < 0)
940 : return -1;
941 : }
942 32 : else if (cu->lines == (void *) -1l)
943 : return -1;
944 :
945 4366 : *lines = cu->lines;
946 4366 : *nlines = cu->lines->nlines;
947 :
948 : // XXX Eventually: unlocking here.
949 :
950 4366 : return 0;
951 : }
952 : INTDEF(dwarf_getsrclines)
|