blob: d02c38db40eb8f01b19acb662f214fa62b057d89 [file] [log] [blame]
Brian Silverman86497922018-02-10 19:28:39 -05001/* 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
43struct filelist
44{
45 Dwarf_Fileinfo info;
46 struct filelist *next;
47};
48
49struct 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. */
58static int
59compare_lines (const void *a, const void *b)
60{
61 struct linelist *const *p1 = a;
62 struct linelist *const *p2 = b;
63 struct linelist *list1 = *p1;
64 struct linelist *list2 = *p2;
65 Dwarf_Line *line1 = &list1->line;
66 Dwarf_Line *line2 = &list2->line;
67
68 if (line1->addr != line2->addr)
69 return (line1->addr < line2->addr) ? -1 : 1;
70
71 /* An end_sequence marker precedes a normal record at the same address. */
72 if (line1->end_sequence != line2->end_sequence)
73 return line2->end_sequence - line1->end_sequence;
74
75 /* Otherwise, the linelist sequence maintains a stable sort. */
76 return (list1->sequence < list2->sequence) ? -1
77 : (list1->sequence > list2->sequence) ? 1
78 : 0;
79}
80
81struct 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
99static inline void
100run_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 state->addr += minimum_instr_len * ((state->op_index + op_advance)
104 / max_ops_per_instr);
105 state->op_index = (state->op_index + op_advance) % max_ops_per_instr;
106}
107
108static inline bool
109add_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 new_line->next = state->linelist;
116 new_line->sequence = state->nlinelist;
117 state->linelist = new_line;
118 ++(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 SET (addr);
132 SET (op_index);
133 SET (file);
134 SET (line);
135 SET (column);
136 SET (is_stmt);
137 SET (basic_block);
138 SET (end_sequence);
139 SET (prologue_end);
140 SET (epilogue_begin);
141 SET (isa);
142 SET (discriminator);
143
144#undef SET
145
146 return false;
147}
148
149static int
150read_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 int res = -1;
156
157 size_t nfilelist = 0;
158 unsigned int ndirlist = 0;
159
160 struct filelist null_file =
161 {
162 .info =
163 {
164 .name = "???",
165 .mtime = 0,
166 .length = 0
167 },
168 .next = NULL
169 };
170 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 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 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 if (unlikely (linep + 4 > lineendp))
208 {
209 invalid_data:
210 __libdw_seterrno (DWARF_E_INVALID_DEBUG_LINE);
211 goto out;
212 }
213
214 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
215 unsigned int length = 4;
216 if (unlikely (unit_length == DWARF3_LENGTH_64_BIT))
217 {
218 if (unlikely (linep + 8 > lineendp))
219 goto invalid_data;
220 unit_length = read_8ubyte_unaligned_inc (dbg, linep);
221 length = 8;
222 }
223
224 /* Check whether we have enough room in the section. */
225 if (unlikely (unit_length > (size_t) (lineendp - linep)
226 || unit_length < 2 + length + 5 * 1))
227 goto invalid_data;
228 lineendp = linep + unit_length;
229
230 /* The next element of the header is the version identifier. */
231 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
232 if (unlikely (version < 2) || unlikely (version > 4))
233 {
234 __libdw_seterrno (DWARF_E_VERSION);
235 goto out;
236 }
237
238 /* Next comes the header length. */
239 Dwarf_Word header_length;
240 if (length == 4)
241 header_length = read_4ubyte_unaligned_inc (dbg, linep);
242 else
243 header_length = read_8ubyte_unaligned_inc (dbg, linep);
244 const unsigned char *header_start = linep;
245
246 /* Next the minimum instruction length. */
247 uint_fast8_t minimum_instr_len = *linep++;
248
249 /* Next the maximum operations per instruction, in version 4 format. */
250 uint_fast8_t max_ops_per_instr = 1;
251 if (version >= 4)
252 {
253 if (unlikely (lineendp - linep < 5))
254 goto invalid_data;
255 max_ops_per_instr = *linep++;
256 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 uint_fast8_t default_is_stmt = *linep++;
263
264 /* Now the line base. */
265 int_fast8_t line_base = (int8_t) *linep++;
266
267 /* And the line range. */
268 uint_fast8_t line_range = *linep++;
269
270 /* The opcode base. */
271 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 const uint8_t *standard_opcode_lengths = linep - 1;
276 if (unlikely (lineendp - linep < opcode_base - 1))
277 goto invalid_data;
278 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 struct dirlist comp_dir_elem =
283 {
284 .dir = comp_dir,
285 .len = comp_dir ? strlen (comp_dir) : 0,
286 };
287 ndirlist = 1;
288
289 /* First count the entries. */
290 const unsigned char *dirp = linep;
291 unsigned int ndirs = 0;
292 while (*dirp != 0)
293 {
294 uint8_t *endp = memchr (dirp, '\0', lineendp - dirp);
295 if (endp == NULL)
296 goto invalid_data;
297 ++ndirs;
298 dirp = endp + 1;
299 }
300 ndirlist += ndirs;
301
302 /* Arrange the list in array form. */
303 if (ndirlist >= MAX_STACK_DIRS)
304 {
305 dirarray = (struct dirlist *) malloc (ndirlist * sizeof (*dirarray));
306 if (unlikely (dirarray == NULL))
307 {
308 no_mem:
309 __libdw_seterrno (DWARF_E_NOMEM);
310 goto out;
311 }
312 }
313 dirarray[0] = comp_dir_elem;
314 for (unsigned int n = 1; n < ndirlist; n++)
315 {
316 dirarray[n].dir = (char *) linep;
317 uint8_t *endp = memchr (linep, '\0', lineendp - linep);
318 assert (endp != NULL);
319 dirarray[n].len = endp - linep;
320 linep = endp + 1;
321 }
322 /* Skip the final NUL byte. */
323 ++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 nfilelist = 1;
341
342 if (unlikely (linep >= lineendp))
343 goto invalid_data;
344 while (*linep != 0)
345 {
346 struct filelist *new_file = NEW_FILE ();
347
348 /* First comes the file name. */
349 char *fname = (char *) linep;
350 uint8_t *endp = memchr (fname, '\0', lineendp - linep);
351 if (endp == NULL)
352 goto invalid_data;
353 size_t fnamelen = endp - (uint8_t *) fname;
354 linep = endp + 1;
355
356 /* Then the index. */
357 Dwarf_Word diridx;
358 if (unlikely (linep >= lineendp))
359 goto invalid_data;
360 get_uleb128 (diridx, linep, lineendp);
361 if (unlikely (diridx >= ndirlist))
362 {
363 __libdw_seterrno (DWARF_E_INVALID_DIR_IDX);
364 goto out;
365 }
366
367 if (*fname == '/')
368 /* It's an absolute path. */
369 new_file->info.name = fname;
370 else
371 {
372 new_file->info.name = libdw_alloc (dbg, char, 1,
373 dirarray[diridx].len + 1
374 + fnamelen + 1);
375 char *cp = new_file->info.name;
376
377 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 cp = stpcpy (cp, dirarray[diridx].dir);
384 }
385 *cp++ = '/';
386 strcpy (cp, fname);
387 assert (strlen (new_file->info.name)
388 < dirarray[diridx].len + 1 + fnamelen + 1);
389 }
390
391 /* Next comes the modification time. */
392 if (unlikely (linep >= lineendp))
393 goto invalid_data;
394 get_uleb128 (new_file->info.mtime, linep, lineendp);
395
396 /* Finally the length of the file. */
397 if (unlikely (linep >= lineendp))
398 goto invalid_data;
399 get_uleb128 (new_file->info.length, linep, lineendp);
400 }
401 /* Skip the final NUL byte. */
402 ++linep;
403
404 /* Consistency check. */
405 if (unlikely (linep != header_start + header_length))
406 {
407 __libdw_seterrno (DWARF_E_INVALID_DWARF);
408 goto out;
409 }
410
411 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 while (linep < lineendp)
436 {
437 unsigned int opcode;
438 unsigned int u128;
439 int s128;
440
441 /* Read the opcode. */
442 opcode = *linep++;
443
444 /* Is this a special opcode? */
445 if (likely (opcode >= opcode_base))
446 {
447 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 int line_increment = (line_base
457 + (opcode - opcode_base) % line_range);
458
459 /* Perform the increments. */
460 state.line += line_increment;
461 advance_pc ((opcode - opcode_base) / line_range);
462
463 /* Add a new line with the current state machine values. */
464 NEW_LINE (0);
465
466 /* Reset the flags. */
467 state.basic_block = false;
468 state.prologue_end = false;
469 state.epilogue_begin = false;
470 state.discriminator = 0;
471 }
472 else if (opcode == 0)
473 {
474 /* This an extended opcode. */
475 if (unlikely (lineendp - linep < 2))
476 goto invalid_data;
477
478 /* The length. */
479 uint_fast8_t len = *linep++;
480
481 if (unlikely ((size_t) (lineendp - linep) < len))
482 goto invalid_data;
483
484 /* The sub-opcode. */
485 opcode = *linep++;
486
487 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 NEW_LINE (1);
493
494 /* Reset the registers. */
495 state.addr = 0;
496 state.op_index = 0;
497 state.file = 1;
498 state.line = 1;
499 state.column = 0;
500 state.is_stmt = default_is_stmt;
501 state.basic_block = false;
502 state.prologue_end = false;
503 state.epilogue_begin = false;
504 state.isa = 0;
505 state.discriminator = 0;
506 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 state.op_index = 0;
513 if (unlikely (lineendp - linep < (uint8_t) address_size))
514 goto invalid_data;
515 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 char *fname = (char *) linep;
523 uint8_t *endp = memchr (linep, '\0', lineendp - linep);
524 if (endp == NULL)
525 goto invalid_data;
526 size_t fnamelen = endp - linep;
527 linep = endp + 1;
528
529 unsigned int diridx;
530 if (unlikely (linep >= lineendp))
531 goto invalid_data;
532 get_uleb128 (diridx, linep, lineendp);
533 if (unlikely (diridx >= ndirlist))
534 {
535 __libdw_seterrno (DWARF_E_INVALID_DIR_IDX);
536 goto invalid_data;
537 }
538 Dwarf_Word mtime;
539 if (unlikely (linep >= lineendp))
540 goto invalid_data;
541 get_uleb128 (mtime, linep, lineendp);
542 Dwarf_Word filelength;
543 if (unlikely (linep >= lineendp))
544 goto invalid_data;
545 get_uleb128 (filelength, linep, lineendp);
546
547 struct filelist *new_file = NEW_FILE ();
548 if (fname[0] == '/')
549 new_file->info.name = fname;
550 else
551 {
552 new_file->info.name =
553 libdw_alloc (dbg, char, 1, (dirarray[diridx].len + 1
554 + fnamelen + 1));
555 char *cp = new_file->info.name;
556
557 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 cp = stpcpy (cp, dirarray[diridx].dir);
564 *cp++ = '/';
565 strcpy (cp, fname);
566 }
567
568 new_file->info.mtime = mtime;
569 new_file->info.length = filelength;
570 }
571 break;
572
573 case DW_LNE_set_discriminator:
574 /* Takes one ULEB128 parameter, the discriminator. */
575 if (unlikely (standard_opcode_lengths[opcode] != 1))
576 goto invalid_data;
577
578 if (unlikely (linep >= lineendp))
579 goto invalid_data;
580 get_uleb128 (state.discriminator, linep, lineendp);
581 break;
582
583 default:
584 /* Unknown, ignore it. */
585 if (unlikely ((size_t) (lineendp - (linep - 1)) < len))
586 goto invalid_data;
587 linep += len - 1;
588 break;
589 }
590 }
591 else if (opcode <= DW_LNS_set_isa)
592 {
593 /* This is a known standard opcode. */
594 switch (opcode)
595 {
596 case DW_LNS_copy:
597 /* Takes no argument. */
598 if (unlikely (standard_opcode_lengths[opcode] != 0))
599 goto invalid_data;
600
601 /* Add a new line with the current state machine values. */
602 NEW_LINE (0);
603
604 /* Reset the flags. */
605 state.basic_block = false;
606 state.prologue_end = false;
607 state.epilogue_begin = false;
608 state.discriminator = 0;
609 break;
610
611 case DW_LNS_advance_pc:
612 /* Takes one uleb128 parameter which is added to the
613 address. */
614 if (unlikely (standard_opcode_lengths[opcode] != 1))
615 goto invalid_data;
616
617 if (unlikely (linep >= lineendp))
618 goto invalid_data;
619 get_uleb128 (u128, linep, lineendp);
620 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 if (unlikely (standard_opcode_lengths[opcode] != 1))
627 goto invalid_data;
628
629 if (unlikely (linep >= lineendp))
630 goto invalid_data;
631 get_sleb128 (s128, linep, lineendp);
632 state.line += s128;
633 break;
634
635 case DW_LNS_set_file:
636 /* Takes one uleb128 parameter which is stored in file. */
637 if (unlikely (standard_opcode_lengths[opcode] != 1))
638 goto invalid_data;
639
640 if (unlikely (linep >= lineendp))
641 goto invalid_data;
642 get_uleb128 (u128, linep, lineendp);
643 state.file = u128;
644 break;
645
646 case DW_LNS_set_column:
647 /* Takes one uleb128 parameter which is stored in column. */
648 if (unlikely (standard_opcode_lengths[opcode] != 1))
649 goto invalid_data;
650
651 if (unlikely (linep >= lineendp))
652 goto invalid_data;
653 get_uleb128 (u128, linep, lineendp);
654 state.column = u128;
655 break;
656
657 case DW_LNS_negate_stmt:
658 /* Takes no argument. */
659 if (unlikely (standard_opcode_lengths[opcode] != 0))
660 goto invalid_data;
661
662 state.is_stmt = 1 - state.is_stmt;
663 break;
664
665 case DW_LNS_set_basic_block:
666 /* Takes no argument. */
667 if (unlikely (standard_opcode_lengths[opcode] != 0))
668 goto invalid_data;
669
670 state.basic_block = true;
671 break;
672
673 case DW_LNS_const_add_pc:
674 /* Takes no argument. */
675 if (unlikely (standard_opcode_lengths[opcode] != 0))
676 goto invalid_data;
677
678 if (unlikely (line_range == 0))
679 goto invalid_data;
680
681 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 if (unlikely (standard_opcode_lengths[opcode] != 1)
688 || unlikely (lineendp - linep < 2))
689 goto invalid_data;
690
691 state.addr += read_2ubyte_unaligned_inc (dbg, linep);
692 state.op_index = 0;
693 break;
694
695 case DW_LNS_set_prologue_end:
696 /* Takes no argument. */
697 if (unlikely (standard_opcode_lengths[opcode] != 0))
698 goto invalid_data;
699
700 state.prologue_end = true;
701 break;
702
703 case DW_LNS_set_epilogue_begin:
704 /* Takes no argument. */
705 if (unlikely (standard_opcode_lengths[opcode] != 0))
706 goto invalid_data;
707
708 state.epilogue_begin = true;
709 break;
710
711 case DW_LNS_set_isa:
712 /* Takes one uleb128 parameter which is stored in isa. */
713 if (unlikely (standard_opcode_lengths[opcode] != 1))
714 goto invalid_data;
715
716 if (unlikely (linep >= lineendp))
717 goto invalid_data;
718 get_uleb128 (state.isa, linep, lineendp);
719 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 for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
728 {
729 if (unlikely (linep >= lineendp))
730 goto invalid_data;
731 get_uleb128 (u128, linep, lineendp);
732 }
733
734 /* Next round, ignore this opcode. */
735 continue;
736 }
737 }
738
739 /* Put all the files in an array. */
740 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 const char **dirs = (void *) &files->info[nfilelist];
746
747 struct filelist *fileslist = filelist;
748 files->nfiles = nfilelist;
749 for (size_t n = nfilelist; n > 0; n--)
750 {
751 files->info[n - 1] = fileslist->info;
752 fileslist = fileslist->next;
753 }
754 assert (fileslist == NULL);
755
756 /* Put all the directory strings in an array. */
757 files->ndirs = ndirlist;
758 for (unsigned int i = 0; i < ndirlist; ++i)
759 dirs[i] = dirarray[i].dir;
760 dirs[ndirlist] = NULL;
761
762 /* Pass the file data structure to the caller. */
763 if (filesp != NULL)
764 *filesp = files;
765
766 size_t buf_size = (sizeof (Dwarf_Lines)
767 + (sizeof (Dwarf_Line) * state.nlinelist));
768 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 struct linelist **sortlines = (buf + buf_size
775 - 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 struct linelist *lineslist = state.linelist;
781 for (size_t i = state.nlinelist; i-- > 0; )
782 {
783 sortlines[i] = lineslist;
784 lineslist = lineslist->next;
785 }
786 assert (lineslist == NULL);
787
788 /* Sort by ascending address. */
789 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 Dwarf_Lines *lines = buf;
795 lines->nlines = state.nlinelist;
796 for (size_t i = 0; i < state.nlinelist; ++i)
797 {
798 lines->info[i] = sortlines[i]->line;
799 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 if (state.nlinelist > 0)
806 lines->info[state.nlinelist - 1].end_sequence = 1;
807
808 /* Pass the line structure back to the caller. */
809 if (linesp != NULL)
810 *linesp = lines;
811
812 /* Success. */
813 res = 0;
814
815 out:
816 /* Free malloced line records, if any. */
817 for (size_t i = MAX_STACK_LINES; i < state.nlinelist; i++)
818 {
819 struct linelist *ll = state.linelist->next;
820 free (state.linelist);
821 state.linelist = ll;
822 }
823 if (ndirlist >= MAX_STACK_DIRS)
824 free (dirarray);
825 for (size_t i = MAX_STACK_FILES; i < nfilelist; i++)
826 {
827 struct filelist *fl = filelist->next;
828 free (filelist);
829 filelist = fl;
830 }
831
832 return res;
833}
834
835static int
836files_lines_compare (const void *p1, const void *p2)
837{
838 const struct files_lines_s *t1 = p1;
839 const struct files_lines_s *t2 = p2;
840
841 if (t1->debug_line_offset < t2->debug_line_offset)
842 return -1;
843 if (t1->debug_line_offset > t2->debug_line_offset)
844 return 1;
845
846 return 0;
847}
848
849int
850internal_function
851__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 struct files_lines_s fake = { .debug_line_offset = debug_line_offset };
856 struct files_lines_s **found = tfind (&fake, &dbg->files_lines,
857 files_lines_compare);
858 if (found == NULL)
859 {
860 Elf_Data *data = __libdw_checked_get_data (dbg, IDX_debug_line);
861 if (data == NULL
862 || __libdw_offset_in_section (dbg, IDX_debug_line,
863 debug_line_offset, 1) != 0)
864 return -1;
865
866 const unsigned char *linep = data->d_buf + debug_line_offset;
867 const unsigned char *lineendp = data->d_buf + data->d_size;
868
869 struct files_lines_s *node = libdw_alloc (dbg, struct files_lines_s,
870 sizeof *node, 1);
871
872 if (read_srclines (dbg, linep, lineendp, comp_dir, address_size,
873 &node->lines, &node->files) != 0)
874 return -1;
875
876 node->debug_line_offset = debug_line_offset;
877
878 found = tsearch (node, &dbg->files_lines, files_lines_compare);
879 if (found == NULL)
880 {
881 __libdw_seterrno (DWARF_E_NOMEM);
882 return -1;
883 }
884 }
885
886 if (linesp != NULL)
887 *linesp = (*found)->lines;
888
889 if (filesp != NULL)
890 *filesp = (*found)->files;
891
892 return 0;
893}
894
895/* Get the compilation directory, if any is set. */
896const char *
897__libdw_getcompdir (Dwarf_Die *cudie)
898{
899 Dwarf_Attribute compdir_attr_mem;
900 Dwarf_Attribute *compdir_attr = INTUSE(dwarf_attr) (cudie,
901 DW_AT_comp_dir,
902 &compdir_attr_mem);
903 return INTUSE(dwarf_formstring) (compdir_attr);
904}
905
906int
907dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
908{
909 if (cudie == NULL)
910 return -1;
911 if (! is_cudie (cudie))
912 {
913 __libdw_seterrno (DWARF_E_NOT_CUDIE);
914 return -1;
915 }
916
917 /* Get the information if it is not already known. */
918 struct Dwarf_CU *const cu = cudie->cu;
919 if (cu->lines == NULL)
920 {
921 /* Failsafe mode: no data found. */
922 cu->lines = (void *) -1l;
923 cu->files = (void *) -1l;
924
925 /* The die must have a statement list associated. */
926 Dwarf_Attribute stmt_list_mem;
927 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 if (__libdw_formptr (stmt_list, IDX_debug_line, DWARF_E_NO_DEBUG_LINE,
934 NULL, &debug_line_offset) == NULL)
935 return -1;
936
937 if (__libdw_getsrclines (cu->dbg, debug_line_offset,
938 __libdw_getcompdir (cudie),
939 cu->address_size, &cu->lines, &cu->files) < 0)
940 return -1;
941 }
942 else if (cu->lines == (void *) -1l)
943 return -1;
944
945 *lines = cu->lines;
946 *nlines = cu->lines->nlines;
947
948 // XXX Eventually: unlocking here.
949
950 return 0;
951}
952INTDEF(dwarf_getsrclines)