1 /* Return line number information of CU.
2 Copyright (C) 2004-2010, 2013, 2014, 2015 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
compare_lines(const void * a,const void * b)59 compare_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
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
run_advance_pc(struct line_state * state,unsigned int op_advance,uint_fast8_t minimum_instr_len,uint_fast8_t max_ops_per_instr)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 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
108 static inline bool
add_new_line(struct line_state * state,struct linelist * new_line)109 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 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
149 static int
read_srclines(Dwarf * dbg,const unsigned char * linep,const unsigned char * lineendp,const char * comp_dir,unsigned address_size,Dwarf_Lines ** linesp,Dwarf_Files ** filesp)150 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 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 while (*dirp != 0)
292 {
293 uint8_t *endp = memchr (dirp, '\0', lineendp - dirp);
294 if (endp == NULL)
295 goto invalid_data;
296 ++ndirlist;
297 dirp = endp + 1;
298 }
299
300 /* Arrange the list in array form. */
301 if (ndirlist >= MAX_STACK_DIRS)
302 {
303 dirarray = (struct dirlist *) malloc (ndirlist * sizeof (*dirarray));
304 if (unlikely (dirarray == NULL))
305 {
306 no_mem:
307 __libdw_seterrno (DWARF_E_NOMEM);
308 goto out;
309 }
310 }
311 dirarray[0] = comp_dir_elem;
312 for (unsigned int n = 1; n < ndirlist; n++)
313 {
314 dirarray[n].dir = (char *) linep;
315 uint8_t *endp = memchr (linep, '\0', lineendp - linep);
316 assert (endp != NULL);
317 dirarray[n].len = endp - linep;
318 linep = endp + 1;
319 }
320 /* Skip the final NUL byte. */
321 ++linep;
322
323 /* Allocate memory for a new file. For the first MAX_STACK_FILES
324 entries just return a slot in the preallocated stack array. */
325 struct filelist flstack[MAX_STACK_FILES];
326 #define NEW_FILE() ({ \
327 struct filelist *fl = (nfilelist < MAX_STACK_FILES \
328 ? &flstack[nfilelist] \
329 : malloc (sizeof (struct filelist))); \
330 if (unlikely (fl == NULL)) \
331 goto no_mem; \
332 ++nfilelist; \
333 fl->next = filelist; \
334 filelist = fl; \
335 fl; })
336
337 /* Now read the files. */
338 nfilelist = 1;
339
340 if (unlikely (linep >= lineendp))
341 goto invalid_data;
342 while (*linep != 0)
343 {
344 struct filelist *new_file = NEW_FILE ();
345
346 /* First comes the file name. */
347 char *fname = (char *) linep;
348 uint8_t *endp = memchr (fname, '\0', lineendp - linep);
349 if (endp == NULL)
350 goto invalid_data;
351 size_t fnamelen = endp - (uint8_t *) fname;
352 linep = endp + 1;
353
354 /* Then the index. */
355 Dwarf_Word diridx;
356 if (unlikely (linep >= lineendp))
357 goto invalid_data;
358 get_uleb128 (diridx, linep, lineendp);
359 if (unlikely (diridx >= ndirlist))
360 {
361 __libdw_seterrno (DWARF_E_INVALID_DIR_IDX);
362 goto out;
363 }
364
365 if (*fname == '/')
366 /* It's an absolute path. */
367 new_file->info.name = fname;
368 else
369 {
370 new_file->info.name = libdw_alloc (dbg, char, 1,
371 dirarray[diridx].len + 1
372 + fnamelen + 1);
373 char *cp = new_file->info.name;
374
375 if (dirarray[diridx].dir != NULL)
376 {
377 /* This value could be NULL in case the DW_AT_comp_dir
378 was not present. We cannot do much in this case.
379 The easiest thing is to convert the path in an
380 absolute path. */
381 cp = stpcpy (cp, dirarray[diridx].dir);
382 }
383 *cp++ = '/';
384 strcpy (cp, fname);
385 assert (strlen (new_file->info.name)
386 < dirarray[diridx].len + 1 + fnamelen + 1);
387 }
388
389 /* Next comes the modification time. */
390 if (unlikely (linep >= lineendp))
391 goto invalid_data;
392 get_uleb128 (new_file->info.mtime, linep, lineendp);
393
394 /* Finally the length of the file. */
395 if (unlikely (linep >= lineendp))
396 goto invalid_data;
397 get_uleb128 (new_file->info.length, linep, lineendp);
398 }
399 /* Skip the final NUL byte. */
400 ++linep;
401
402 /* Consistency check. */
403 if (unlikely (linep != header_start + header_length))
404 {
405 __libdw_seterrno (DWARF_E_INVALID_DWARF);
406 goto out;
407 }
408
409 state.is_stmt = default_is_stmt;
410
411 /* Apply the "operation advance" from a special opcode or
412 DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
413 #define advance_pc(op_advance) \
414 run_advance_pc (&state, op_advance, minimum_instr_len, max_ops_per_instr)
415
416 /* Process the instructions. */
417
418 /* Adds a new line to the matrix. For the first MAX_STACK_LINES
419 entries just return a slot in the preallocated stack array. */
420 struct linelist llstack[MAX_STACK_LINES];
421 #define NEW_LINE(end_seq) \
422 do { \
423 struct linelist *ll = (state.nlinelist < MAX_STACK_LINES \
424 ? &llstack[state.nlinelist] \
425 : malloc (sizeof (struct linelist))); \
426 if (unlikely (ll == NULL)) \
427 goto no_mem; \
428 state.end_sequence = end_seq; \
429 if (unlikely (add_new_line (&state, ll))) \
430 goto invalid_data; \
431 } while (0)
432
433 while (linep < lineendp)
434 {
435 unsigned int opcode;
436 unsigned int u128;
437 int s128;
438
439 /* Read the opcode. */
440 opcode = *linep++;
441
442 /* Is this a special opcode? */
443 if (likely (opcode >= opcode_base))
444 {
445 if (unlikely (line_range == 0))
446 goto invalid_data;
447
448 /* Yes. Handling this is quite easy since the opcode value
449 is computed with
450
451 opcode = (desired line increment - line_base)
452 + (line_range * address advance) + opcode_base
453 */
454 int line_increment = (line_base
455 + (opcode - opcode_base) % line_range);
456
457 /* Perform the increments. */
458 state.line += line_increment;
459 advance_pc ((opcode - opcode_base) / line_range);
460
461 /* Add a new line with the current state machine values. */
462 NEW_LINE (0);
463
464 /* Reset the flags. */
465 state.basic_block = false;
466 state.prologue_end = false;
467 state.epilogue_begin = false;
468 state.discriminator = 0;
469 }
470 else if (opcode == 0)
471 {
472 /* This an extended opcode. */
473 if (unlikely (lineendp - linep < 2))
474 goto invalid_data;
475
476 /* The length. */
477 uint_fast8_t len = *linep++;
478
479 if (unlikely ((size_t) (lineendp - linep) < len))
480 goto invalid_data;
481
482 /* The sub-opcode. */
483 opcode = *linep++;
484
485 switch (opcode)
486 {
487 case DW_LNE_end_sequence:
488 /* Add a new line with the current state machine values.
489 The is the end of the sequence. */
490 NEW_LINE (1);
491
492 /* Reset the registers. */
493 state.addr = 0;
494 state.op_index = 0;
495 state.file = 1;
496 state.line = 1;
497 state.column = 0;
498 state.is_stmt = default_is_stmt;
499 state.basic_block = false;
500 state.prologue_end = false;
501 state.epilogue_begin = false;
502 state.isa = 0;
503 state.discriminator = 0;
504 break;
505
506 case DW_LNE_set_address:
507 /* The value is an address. The size is defined as
508 apporiate for the target machine. We use the
509 address size field from the CU header. */
510 state.op_index = 0;
511 if (unlikely (lineendp - linep < (uint8_t) address_size))
512 goto invalid_data;
513 if (__libdw_read_address_inc (dbg, IDX_debug_line, &linep,
514 address_size, &state.addr))
515 goto out;
516 break;
517
518 case DW_LNE_define_file:
519 {
520 char *fname = (char *) linep;
521 uint8_t *endp = memchr (linep, '\0', lineendp - linep);
522 if (endp == NULL)
523 goto invalid_data;
524 size_t fnamelen = endp - linep;
525 linep = endp + 1;
526
527 unsigned int diridx;
528 if (unlikely (linep >= lineendp))
529 goto invalid_data;
530 get_uleb128 (diridx, linep, lineendp);
531 if (unlikely (diridx >= ndirlist))
532 {
533 __libdw_seterrno (DWARF_E_INVALID_DIR_IDX);
534 goto invalid_data;
535 }
536 Dwarf_Word mtime;
537 if (unlikely (linep >= lineendp))
538 goto invalid_data;
539 get_uleb128 (mtime, linep, lineendp);
540 Dwarf_Word filelength;
541 if (unlikely (linep >= lineendp))
542 goto invalid_data;
543 get_uleb128 (filelength, linep, lineendp);
544
545 struct filelist *new_file = NEW_FILE ();
546 if (fname[0] == '/')
547 new_file->info.name = fname;
548 else
549 {
550 new_file->info.name =
551 libdw_alloc (dbg, char, 1, (dirarray[diridx].len + 1
552 + fnamelen + 1));
553 char *cp = new_file->info.name;
554
555 if (dirarray[diridx].dir != NULL)
556 /* This value could be NULL in case the
557 DW_AT_comp_dir was not present. We
558 cannot do much in this case. The easiest
559 thing is to convert the path in an
560 absolute path. */
561 cp = stpcpy (cp, dirarray[diridx].dir);
562 *cp++ = '/';
563 strcpy (cp, fname);
564 }
565
566 new_file->info.mtime = mtime;
567 new_file->info.length = filelength;
568 }
569 break;
570
571 case DW_LNE_set_discriminator:
572 /* Takes one ULEB128 parameter, the discriminator. */
573 if (unlikely (standard_opcode_lengths[opcode] != 1))
574 goto invalid_data;
575
576 if (unlikely (linep >= lineendp))
577 goto invalid_data;
578 get_uleb128 (state.discriminator, linep, lineendp);
579 break;
580
581 default:
582 /* Unknown, ignore it. */
583 if (unlikely ((size_t) (lineendp - (linep - 1)) < len))
584 goto invalid_data;
585 linep += len - 1;
586 break;
587 }
588 }
589 else if (opcode <= DW_LNS_set_isa)
590 {
591 /* This is a known standard opcode. */
592 switch (opcode)
593 {
594 case DW_LNS_copy:
595 /* Takes no argument. */
596 if (unlikely (standard_opcode_lengths[opcode] != 0))
597 goto invalid_data;
598
599 /* Add a new line with the current state machine values. */
600 NEW_LINE (0);
601
602 /* Reset the flags. */
603 state.basic_block = false;
604 state.prologue_end = false;
605 state.epilogue_begin = false;
606 state.discriminator = 0;
607 break;
608
609 case DW_LNS_advance_pc:
610 /* Takes one uleb128 parameter which is added to the
611 address. */
612 if (unlikely (standard_opcode_lengths[opcode] != 1))
613 goto invalid_data;
614
615 if (unlikely (linep >= lineendp))
616 goto invalid_data;
617 get_uleb128 (u128, linep, lineendp);
618 advance_pc (u128);
619 break;
620
621 case DW_LNS_advance_line:
622 /* Takes one sleb128 parameter which is added to the
623 line. */
624 if (unlikely (standard_opcode_lengths[opcode] != 1))
625 goto invalid_data;
626
627 if (unlikely (linep >= lineendp))
628 goto invalid_data;
629 get_sleb128 (s128, linep, lineendp);
630 state.line += s128;
631 break;
632
633 case DW_LNS_set_file:
634 /* Takes one uleb128 parameter which is stored in file. */
635 if (unlikely (standard_opcode_lengths[opcode] != 1))
636 goto invalid_data;
637
638 if (unlikely (linep >= lineendp))
639 goto invalid_data;
640 get_uleb128 (u128, linep, lineendp);
641 state.file = u128;
642 break;
643
644 case DW_LNS_set_column:
645 /* Takes one uleb128 parameter which is stored in column. */
646 if (unlikely (standard_opcode_lengths[opcode] != 1))
647 goto invalid_data;
648
649 if (unlikely (linep >= lineendp))
650 goto invalid_data;
651 get_uleb128 (u128, linep, lineendp);
652 state.column = u128;
653 break;
654
655 case DW_LNS_negate_stmt:
656 /* Takes no argument. */
657 if (unlikely (standard_opcode_lengths[opcode] != 0))
658 goto invalid_data;
659
660 state.is_stmt = 1 - state.is_stmt;
661 break;
662
663 case DW_LNS_set_basic_block:
664 /* Takes no argument. */
665 if (unlikely (standard_opcode_lengths[opcode] != 0))
666 goto invalid_data;
667
668 state.basic_block = true;
669 break;
670
671 case DW_LNS_const_add_pc:
672 /* Takes no argument. */
673 if (unlikely (standard_opcode_lengths[opcode] != 0))
674 goto invalid_data;
675
676 if (unlikely (line_range == 0))
677 goto invalid_data;
678
679 advance_pc ((255 - opcode_base) / line_range);
680 break;
681
682 case DW_LNS_fixed_advance_pc:
683 /* Takes one 16 bit parameter which is added to the
684 address. */
685 if (unlikely (standard_opcode_lengths[opcode] != 1)
686 || unlikely (lineendp - linep < 2))
687 goto invalid_data;
688
689 state.addr += read_2ubyte_unaligned_inc (dbg, linep);
690 state.op_index = 0;
691 break;
692
693 case DW_LNS_set_prologue_end:
694 /* Takes no argument. */
695 if (unlikely (standard_opcode_lengths[opcode] != 0))
696 goto invalid_data;
697
698 state.prologue_end = true;
699 break;
700
701 case DW_LNS_set_epilogue_begin:
702 /* Takes no argument. */
703 if (unlikely (standard_opcode_lengths[opcode] != 0))
704 goto invalid_data;
705
706 state.epilogue_begin = true;
707 break;
708
709 case DW_LNS_set_isa:
710 /* Takes one uleb128 parameter which is stored in isa. */
711 if (unlikely (standard_opcode_lengths[opcode] != 1))
712 goto invalid_data;
713
714 if (unlikely (linep >= lineendp))
715 goto invalid_data;
716 get_uleb128 (state.isa, linep, lineendp);
717 break;
718 }
719 }
720 else
721 {
722 /* This is a new opcode the generator but not we know about.
723 Read the parameters associated with it but then discard
724 everything. Read all the parameters for this opcode. */
725 for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
726 {
727 if (unlikely (linep >= lineendp))
728 goto invalid_data;
729 get_uleb128 (u128, linep, lineendp);
730 }
731
732 /* Next round, ignore this opcode. */
733 continue;
734 }
735 }
736
737 /* Put all the files in an array. */
738 Dwarf_Files *files = libdw_alloc (dbg, Dwarf_Files,
739 sizeof (Dwarf_Files)
740 + nfilelist * sizeof (Dwarf_Fileinfo)
741 + (ndirlist + 1) * sizeof (char *),
742 1);
743 const char **dirs = (void *) &files->info[nfilelist];
744
745 struct filelist *fileslist = filelist;
746 files->nfiles = nfilelist;
747 for (size_t n = nfilelist; n > 0; n--)
748 {
749 files->info[n - 1] = fileslist->info;
750 fileslist = fileslist->next;
751 }
752 assert (fileslist == NULL);
753
754 /* Put all the directory strings in an array. */
755 files->ndirs = ndirlist;
756 for (unsigned int i = 0; i < ndirlist; ++i)
757 dirs[i] = dirarray[i].dir;
758 dirs[ndirlist] = NULL;
759
760 /* Pass the file data structure to the caller. */
761 if (filesp != NULL)
762 *filesp = files;
763
764 size_t buf_size = (sizeof (Dwarf_Lines)
765 + (sizeof (Dwarf_Line) * state.nlinelist));
766 void *buf = libdw_alloc (dbg, Dwarf_Lines, buf_size, 1);
767
768 /* First use the buffer for the pointers, and sort the entries.
769 We'll write the pointers in the end of the buffer, and then
770 copy into the buffer from the beginning so the overlap works. */
771 assert (sizeof (Dwarf_Line) >= sizeof (struct linelist *));
772 struct linelist **sortlines = (buf + buf_size
773 - sizeof (struct linelist **) * state.nlinelist);
774
775 /* The list is in LIFO order and usually they come in clumps with
776 ascending addresses. So fill from the back to probably start with
777 runs already in order before we sort. */
778 struct linelist *lineslist = state.linelist;
779 for (size_t i = state.nlinelist; i-- > 0; )
780 {
781 sortlines[i] = lineslist;
782 lineslist = lineslist->next;
783 }
784 assert (lineslist == NULL);
785
786 /* Sort by ascending address. */
787 qsort (sortlines, state.nlinelist, sizeof sortlines[0], &compare_lines);
788
789 /* Now that they are sorted, put them in the final array.
790 The buffers overlap, so we've clobbered the early elements
791 of SORTLINES by the time we're reading the later ones. */
792 Dwarf_Lines *lines = buf;
793 lines->nlines = state.nlinelist;
794 for (size_t i = 0; i < state.nlinelist; ++i)
795 {
796 lines->info[i] = sortlines[i]->line;
797 lines->info[i].files = files;
798 }
799
800 /* Make sure the highest address for the CU is marked as end_sequence.
801 This is required by the DWARF spec, but some compilers forget and
802 dwfl_module_getsrc depends on it. */
803 if (state.nlinelist > 0)
804 lines->info[state.nlinelist - 1].end_sequence = 1;
805
806 /* Pass the line structure back to the caller. */
807 if (linesp != NULL)
808 *linesp = lines;
809
810 /* Success. */
811 res = 0;
812
813 out:
814 /* Free malloced line records, if any. */
815 for (size_t i = MAX_STACK_LINES; i < state.nlinelist; i++)
816 {
817 struct linelist *ll = state.linelist->next;
818 free (state.linelist);
819 state.linelist = ll;
820 }
821 if (ndirlist >= MAX_STACK_DIRS)
822 free (dirarray);
823 for (size_t i = MAX_STACK_FILES; i < nfilelist; i++)
824 {
825 struct filelist *fl = filelist->next;
826 free (filelist);
827 filelist = fl;
828 }
829
830 return res;
831 }
832
833 static int
files_lines_compare(const void * p1,const void * p2)834 files_lines_compare (const void *p1, const void *p2)
835 {
836 const struct files_lines_s *t1 = p1;
837 const struct files_lines_s *t2 = p2;
838
839 if (t1->debug_line_offset < t2->debug_line_offset)
840 return -1;
841 if (t1->debug_line_offset > t2->debug_line_offset)
842 return 1;
843
844 return 0;
845 }
846
847 int
848 internal_function
__libdw_getsrclines(Dwarf * dbg,Dwarf_Off debug_line_offset,const char * comp_dir,unsigned address_size,Dwarf_Lines ** linesp,Dwarf_Files ** filesp)849 __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
850 const char *comp_dir, unsigned address_size,
851 Dwarf_Lines **linesp, Dwarf_Files **filesp)
852 {
853 struct files_lines_s fake = { .debug_line_offset = debug_line_offset };
854 struct files_lines_s **found = tfind (&fake, &dbg->files_lines,
855 files_lines_compare);
856 if (found == NULL)
857 {
858 Elf_Data *data = __libdw_checked_get_data (dbg, IDX_debug_line);
859 if (data == NULL
860 || __libdw_offset_in_section (dbg, IDX_debug_line,
861 debug_line_offset, 1) != 0)
862 return -1;
863
864 const unsigned char *linep = data->d_buf + debug_line_offset;
865 const unsigned char *lineendp = data->d_buf + data->d_size;
866
867 struct files_lines_s *node = libdw_alloc (dbg, struct files_lines_s,
868 sizeof *node, 1);
869
870 if (read_srclines (dbg, linep, lineendp, comp_dir, address_size,
871 &node->lines, &node->files) != 0)
872 return -1;
873
874 node->debug_line_offset = debug_line_offset;
875
876 found = tsearch (node, &dbg->files_lines, files_lines_compare);
877 if (found == NULL)
878 {
879 __libdw_seterrno (DWARF_E_NOMEM);
880 return -1;
881 }
882 }
883
884 if (linesp != NULL)
885 *linesp = (*found)->lines;
886
887 if (filesp != NULL)
888 *filesp = (*found)->files;
889
890 return 0;
891 }
892
893 /* Get the compilation directory, if any is set. */
894 const char *
__libdw_getcompdir(Dwarf_Die * cudie)895 __libdw_getcompdir (Dwarf_Die *cudie)
896 {
897 Dwarf_Attribute compdir_attr_mem;
898 Dwarf_Attribute *compdir_attr = INTUSE(dwarf_attr) (cudie,
899 DW_AT_comp_dir,
900 &compdir_attr_mem);
901 return INTUSE(dwarf_formstring) (compdir_attr);
902 }
903
904 int
dwarf_getsrclines(Dwarf_Die * cudie,Dwarf_Lines ** lines,size_t * nlines)905 dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
906 {
907 if (cudie == NULL)
908 return -1;
909 if (! is_cudie (cudie))
910 {
911 __libdw_seterrno (DWARF_E_NOT_CUDIE);
912 return -1;
913 }
914
915 /* Get the information if it is not already known. */
916 struct Dwarf_CU *const cu = cudie->cu;
917 if (cu->lines == NULL)
918 {
919 /* Failsafe mode: no data found. */
920 cu->lines = (void *) -1l;
921 cu->files = (void *) -1l;
922
923 /* The die must have a statement list associated. */
924 Dwarf_Attribute stmt_list_mem;
925 Dwarf_Attribute *stmt_list = INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list,
926 &stmt_list_mem);
927
928 /* Get the offset into the .debug_line section. NB: this call
929 also checks whether the previous dwarf_attr call failed. */
930 Dwarf_Off debug_line_offset;
931 if (__libdw_formptr (stmt_list, IDX_debug_line, DWARF_E_NO_DEBUG_LINE,
932 NULL, &debug_line_offset) == NULL)
933 return -1;
934
935 if (__libdw_getsrclines (cu->dbg, debug_line_offset,
936 __libdw_getcompdir (cudie),
937 cu->address_size, &cu->lines, &cu->files) < 0)
938 return -1;
939 }
940 else if (cu->lines == (void *) -1l)
941 return -1;
942
943 *lines = cu->lines;
944 *nlines = cu->lines->nlines;
945
946 // XXX Eventually: unlocking here.
947
948 return 0;
949 }
950 INTDEF(dwarf_getsrclines)
951