1 /* Return line number information of CU.
2    Copyright (C) 2004-2010, 2013, 2014 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 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)82 read_srclines (Dwarf *dbg,
83 	       const unsigned char *linep, const unsigned char *lineendp,
84 	       const char *comp_dir, unsigned address_size,
85 	       Dwarf_Lines **linesp, Dwarf_Files **filesp)
86 {
87   int res = -1;
88 
89   struct linelist *linelist = NULL;
90   size_t nlinelist = 0;
91 
92   /* If there are a large number of lines don't blow up the stack.
93      Keep track of the last malloced linelist record and free them
94      through the next pointer at the end.  */
95 #define MAX_STACK_ALLOC 4096
96   struct linelist *malloc_linelist = NULL;
97 
98   if (unlikely (linep + 4 > lineendp))
99     {
100     invalid_data:
101       __libdw_seterrno (DWARF_E_INVALID_DEBUG_LINE);
102       goto out;
103     }
104 
105   Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
106   unsigned int length = 4;
107   if (unlikely (unit_length == DWARF3_LENGTH_64_BIT))
108     {
109       if (unlikely (linep + 8 > lineendp))
110 	goto invalid_data;
111       unit_length = read_8ubyte_unaligned_inc (dbg, linep);
112       length = 8;
113     }
114 
115   /* Check whether we have enough room in the section.  */
116   if (unlikely (unit_length > (size_t) (lineendp - linep)
117       || unit_length < 2 + length + 5 * 1))
118     goto invalid_data;
119   lineendp = linep + unit_length;
120 
121   /* The next element of the header is the version identifier.  */
122   uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
123   if (unlikely (version < 2) || unlikely (version > 4))
124     {
125       __libdw_seterrno (DWARF_E_VERSION);
126       goto out;
127     }
128 
129   /* Next comes the header length.  */
130   Dwarf_Word header_length;
131   if (length == 4)
132     header_length = read_4ubyte_unaligned_inc (dbg, linep);
133   else
134     header_length = read_8ubyte_unaligned_inc (dbg, linep);
135   const unsigned char *header_start = linep;
136 
137   /* Next the minimum instruction length.  */
138   uint_fast8_t minimum_instr_len = *linep++;
139 
140   /* Next the maximum operations per instruction, in version 4 format.  */
141   uint_fast8_t max_ops_per_instr = 1;
142   if (version >= 4)
143     {
144       if (unlikely (lineendp - linep < 5))
145 	goto invalid_data;
146       max_ops_per_instr = *linep++;
147       if (unlikely (max_ops_per_instr == 0))
148 	goto invalid_data;
149     }
150 
151   /* Then the flag determining the default value of the is_stmt
152      register.  */
153   uint_fast8_t default_is_stmt = *linep++;
154 
155   /* Now the line base.  */
156   int_fast8_t line_base = (int8_t) *linep++;
157 
158   /* And the line range.  */
159   uint_fast8_t line_range = *linep++;
160 
161   /* The opcode base.  */
162   uint_fast8_t opcode_base = *linep++;
163 
164   /* Remember array with the standard opcode length (-1 to account for
165      the opcode with value zero not being mentioned).  */
166   const uint8_t *standard_opcode_lengths = linep - 1;
167   if (unlikely (lineendp - linep < opcode_base - 1))
168     goto invalid_data;
169   linep += opcode_base - 1;
170 
171   /* First comes the list of directories.  Add the compilation
172      directory first since the index zero is used for it.  */
173   struct dirlist
174   {
175     const char *dir;
176     size_t len;
177     struct dirlist *next;
178   } comp_dir_elem =
179     {
180       .dir = comp_dir,
181       .len = comp_dir ? strlen (comp_dir) : 0,
182       .next = NULL
183     };
184   struct dirlist *dirlist = &comp_dir_elem;
185   unsigned int ndirlist = 1;
186 
187   // XXX Directly construct array to conserve memory?
188   while (*linep != 0)
189     {
190       struct dirlist *new_dir =
191 	(struct dirlist *) alloca (sizeof (*new_dir));
192 
193       new_dir->dir = (char *) linep;
194       uint8_t *endp = memchr (linep, '\0', lineendp - linep);
195       if (endp == NULL)
196 	goto invalid_data;
197       new_dir->len = endp - linep;
198       new_dir->next = dirlist;
199       dirlist = new_dir;
200       ++ndirlist;
201       linep = endp + 1;
202     }
203   /* Skip the final NUL byte.  */
204   ++linep;
205 
206   /* Rearrange the list in array form.  */
207   struct dirlist **dirarray
208     = (struct dirlist **) alloca (ndirlist * sizeof (*dirarray));
209   for (unsigned int n = ndirlist; n-- > 0; dirlist = dirlist->next)
210     dirarray[n] = dirlist;
211 
212   /* Now read the files.  */
213   struct filelist null_file =
214     {
215       .info =
216       {
217 	.name = "???",
218 	.mtime = 0,
219 	.length = 0
220       },
221       .next = NULL
222     };
223   struct filelist *filelist = &null_file;
224   unsigned int nfilelist = 1;
225 
226   if (unlikely (linep >= lineendp))
227     goto invalid_data;
228   while (*linep != 0)
229     {
230       struct filelist *new_file =
231 	(struct filelist *) alloca (sizeof (*new_file));
232 
233       /* First comes the file name.  */
234       char *fname = (char *) linep;
235       uint8_t *endp = memchr (fname, '\0', lineendp - linep);
236       if (endp == NULL)
237 	goto invalid_data;
238       size_t fnamelen = endp - (uint8_t *) fname;
239       linep = endp + 1;
240 
241       /* Then the index.  */
242       Dwarf_Word diridx;
243       if (unlikely (linep >= lineendp))
244 	goto invalid_data;
245       get_uleb128 (diridx, linep, lineendp);
246       if (unlikely (diridx >= ndirlist))
247 	{
248 	  __libdw_seterrno (DWARF_E_INVALID_DIR_IDX);
249 	  goto out;
250 	}
251 
252       if (*fname == '/')
253 	/* It's an absolute path.  */
254 	new_file->info.name = fname;
255       else
256 	{
257 	  new_file->info.name = libdw_alloc (dbg, char, 1,
258 					     dirarray[diridx]->len + 1
259 					     + fnamelen + 1);
260 	  char *cp = new_file->info.name;
261 
262 	  if (dirarray[diridx]->dir != NULL)
263 	    {
264 	      /* This value could be NULL in case the DW_AT_comp_dir
265 		 was not present.  We cannot do much in this case.
266 		 The easiest thing is to convert the path in an
267 		 absolute path.  */
268 	      cp = stpcpy (cp, dirarray[diridx]->dir);
269 	    }
270 	  *cp++ = '/';
271 	  strcpy (cp, fname);
272 	  assert (strlen (new_file->info.name)
273 		  < dirarray[diridx]->len + 1 + fnamelen + 1);
274 	}
275 
276       /* Next comes the modification time.  */
277       if (unlikely (linep >= lineendp))
278 	goto invalid_data;
279       get_uleb128 (new_file->info.mtime, linep, lineendp);
280 
281       /* Finally the length of the file.  */
282       if (unlikely (linep >= lineendp))
283 	goto invalid_data;
284       get_uleb128 (new_file->info.length, linep, lineendp);
285 
286       new_file->next = filelist;
287       filelist = new_file;
288       ++nfilelist;
289     }
290   /* Skip the final NUL byte.  */
291   ++linep;
292 
293   /* Consistency check.  */
294   if (unlikely (linep != header_start + header_length))
295     {
296       __libdw_seterrno (DWARF_E_INVALID_DWARF);
297       goto out;
298     }
299 
300   /* We are about to process the statement program.  Initialize the
301      state machine registers (see 6.2.2 in the v2.1 specification).  */
302   Dwarf_Word addr = 0;
303   unsigned int op_index = 0;
304   unsigned int file = 1;
305   int line = 1;
306   unsigned int column = 0;
307   uint_fast8_t is_stmt = default_is_stmt;
308   bool basic_block = false;
309   bool prologue_end = false;
310   bool epilogue_begin = false;
311   unsigned int isa = 0;
312   unsigned int discriminator = 0;
313 
314   /* Apply the "operation advance" from a special opcode or
315      DW_LNS_advance_pc (as per DWARF4 6.2.5.1).  */
316   inline void advance_pc (unsigned int op_advance)
317   {
318     addr += minimum_instr_len * ((op_index + op_advance)
319 				 / max_ops_per_instr);
320     op_index = (op_index + op_advance) % max_ops_per_instr;
321   }
322 
323   /* Process the instructions.  */
324 
325   /* Adds a new line to the matrix.
326      We cannot simply define a function because we want to use alloca.  */
327 #define NEW_LINE(end_seq)						\
328   do {								\
329     struct linelist *ll = (nlinelist < MAX_STACK_ALLOC		\
330 			   ? alloca (sizeof (struct linelist))	\
331 			   : malloc (sizeof (struct linelist)));	\
332     if (nlinelist >= MAX_STACK_ALLOC)				\
333       malloc_linelist = ll;						\
334     if (unlikely (add_new_line (ll, end_seq)))			\
335       goto invalid_data;						\
336   } while (0)
337 
338   inline bool add_new_line (struct linelist *new_line, bool end_sequence)
339   {
340     new_line->next = linelist;
341     new_line->sequence = nlinelist;
342     linelist = new_line;
343     ++nlinelist;
344 
345     /* Set the line information.  For some fields we use bitfields,
346        so we would lose information if the encoded values are too large.
347        Check just for paranoia, and call the data "invalid" if it
348        violates our assumptions on reasonable limits for the values.  */
349 #define SET(field)							      \
350     do {								      \
351       new_line->line.field = field;					      \
352       if (unlikely (new_line->line.field != field))			      \
353 	return true;						      \
354     } while (0)
355 
356     SET (addr);
357     SET (op_index);
358     SET (file);
359     SET (line);
360     SET (column);
361     SET (is_stmt);
362     SET (basic_block);
363     SET (end_sequence);
364     SET (prologue_end);
365     SET (epilogue_begin);
366     SET (isa);
367     SET (discriminator);
368 
369 #undef SET
370 
371     return false;
372   }
373 
374   while (linep < lineendp)
375     {
376       unsigned int opcode;
377       unsigned int u128;
378       int s128;
379 
380       /* Read the opcode.  */
381       opcode = *linep++;
382 
383       /* Is this a special opcode?  */
384       if (likely (opcode >= opcode_base))
385 	{
386 	  if (unlikely (line_range == 0))
387 	    goto invalid_data;
388 
389 	  /* Yes.  Handling this is quite easy since the opcode value
390 	     is computed with
391 
392 	     opcode = (desired line increment - line_base)
393 		       + (line_range * address advance) + opcode_base
394 	  */
395 	  int line_increment = (line_base
396 				+ (opcode - opcode_base) % line_range);
397 
398 	  /* Perform the increments.  */
399 	  line += line_increment;
400 	  advance_pc ((opcode - opcode_base) / line_range);
401 
402 	  /* Add a new line with the current state machine values.  */
403 	  NEW_LINE (0);
404 
405 	  /* Reset the flags.  */
406 	  basic_block = false;
407 	  prologue_end = false;
408 	  epilogue_begin = false;
409 	  discriminator = 0;
410 	}
411       else if (opcode == 0)
412 	{
413 	  /* This an extended opcode.  */
414 	  if (unlikely (lineendp - linep < 2))
415 	    goto invalid_data;
416 
417 	  /* The length.  */
418 	  uint_fast8_t len = *linep++;
419 
420 	  if (unlikely ((size_t) (lineendp - linep) < len))
421 	    goto invalid_data;
422 
423 	  /* The sub-opcode.  */
424 	  opcode = *linep++;
425 
426 	  switch (opcode)
427 	    {
428 	    case DW_LNE_end_sequence:
429 	      /* Add a new line with the current state machine values.
430 		 The is the end of the sequence.  */
431 	      NEW_LINE (1);
432 
433 	      /* Reset the registers.  */
434 	      addr = 0;
435 	      op_index = 0;
436 	      file = 1;
437 	      line = 1;
438 	      column = 0;
439 	      is_stmt = default_is_stmt;
440 	      basic_block = false;
441 	      prologue_end = false;
442 	      epilogue_begin = false;
443 	      isa = 0;
444 	      discriminator = 0;
445 	      break;
446 
447 	    case DW_LNE_set_address:
448 	      /* The value is an address.  The size is defined as
449 		 apporiate for the target machine.  We use the
450 		 address size field from the CU header.  */
451 	      op_index = 0;
452 	      if (unlikely (lineendp - linep < (uint8_t) address_size))
453 		goto invalid_data;
454 	      if (__libdw_read_address_inc (dbg, IDX_debug_line, &linep,
455 					    address_size, &addr))
456 		goto out;
457 	      break;
458 
459 	    case DW_LNE_define_file:
460 	      {
461 		char *fname = (char *) linep;
462 		uint8_t *endp = memchr (linep, '\0', lineendp - linep);
463 		if (endp == NULL)
464 		  goto invalid_data;
465 		size_t fnamelen = endp - linep;
466 		linep = endp + 1;
467 
468 		unsigned int diridx;
469 		if (unlikely (linep >= lineendp))
470 		  goto invalid_data;
471 		get_uleb128 (diridx, linep, lineendp);
472 		if (unlikely (diridx >= ndirlist))
473 		  {
474 		    __libdw_seterrno (DWARF_E_INVALID_DIR_IDX);
475 		    goto invalid_data;
476 		  }
477 		Dwarf_Word mtime;
478 		if (unlikely (linep >= lineendp))
479 		  goto invalid_data;
480 		get_uleb128 (mtime, linep, lineendp);
481 		Dwarf_Word filelength;
482 		if (unlikely (linep >= lineendp))
483 		  goto invalid_data;
484 		get_uleb128 (filelength, linep, lineendp);
485 
486 		struct filelist *new_file =
487 		  (struct filelist *) alloca (sizeof (*new_file));
488 		if (fname[0] == '/')
489 		  new_file->info.name = fname;
490 		else
491 		  {
492 		    new_file->info.name =
493 		      libdw_alloc (dbg, char, 1, (dirarray[diridx]->len + 1
494 						  + fnamelen + 1));
495 		    char *cp = new_file->info.name;
496 
497 		    if (dirarray[diridx]->dir != NULL)
498 		      /* This value could be NULL in case the
499 			 DW_AT_comp_dir was not present.  We
500 			 cannot do much in this case.  The easiest
501 			 thing is to convert the path in an
502 			 absolute path.  */
503 		      cp = stpcpy (cp, dirarray[diridx]->dir);
504 		    *cp++ = '/';
505 		    strcpy (cp, fname);
506 		  }
507 
508 		new_file->info.mtime = mtime;
509 		new_file->info.length = filelength;
510 		new_file->next = filelist;
511 		filelist = new_file;
512 		++nfilelist;
513 	      }
514 	      break;
515 
516 	    case DW_LNE_set_discriminator:
517 	      /* Takes one ULEB128 parameter, the discriminator.  */
518 	      if (unlikely (standard_opcode_lengths[opcode] != 1))
519 		goto invalid_data;
520 
521 	      if (unlikely (linep >= lineendp))
522 		goto invalid_data;
523 	      get_uleb128 (discriminator, linep, lineendp);
524 	      break;
525 
526 	    default:
527 	      /* Unknown, ignore it.  */
528 	      if (unlikely ((size_t) (lineendp - (linep - 1)) < len))
529 		goto invalid_data;
530 	      linep += len - 1;
531 	      break;
532 	    }
533 	}
534       else if (opcode <= DW_LNS_set_isa)
535 	{
536 	  /* This is a known standard opcode.  */
537 	  switch (opcode)
538 	    {
539 	    case DW_LNS_copy:
540 	      /* Takes no argument.  */
541 	      if (unlikely (standard_opcode_lengths[opcode] != 0))
542 		goto invalid_data;
543 
544 	      /* Add a new line with the current state machine values.  */
545 	      NEW_LINE (0);
546 
547 	      /* Reset the flags.  */
548 	      basic_block = false;
549 	      prologue_end = false;
550 	      epilogue_begin = false;
551 	      discriminator = 0;
552 	      break;
553 
554 	    case DW_LNS_advance_pc:
555 	      /* Takes one uleb128 parameter which is added to the
556 		 address.  */
557 	      if (unlikely (standard_opcode_lengths[opcode] != 1))
558 		goto invalid_data;
559 
560 	      if (unlikely (linep >= lineendp))
561 		goto invalid_data;
562 	      get_uleb128 (u128, linep, lineendp);
563 	      advance_pc (u128);
564 	      break;
565 
566 	    case DW_LNS_advance_line:
567 	      /* Takes one sleb128 parameter which is added to the
568 		 line.  */
569 	      if (unlikely (standard_opcode_lengths[opcode] != 1))
570 		goto invalid_data;
571 
572 	      if (unlikely (linep >= lineendp))
573 		goto invalid_data;
574 	      get_sleb128 (s128, linep, lineendp);
575 	      line += s128;
576 	      break;
577 
578 	    case DW_LNS_set_file:
579 	      /* Takes one uleb128 parameter which is stored in file.  */
580 	      if (unlikely (standard_opcode_lengths[opcode] != 1))
581 		goto invalid_data;
582 
583 	      if (unlikely (linep >= lineendp))
584 		goto invalid_data;
585 	      get_uleb128 (u128, linep, lineendp);
586 	      file = u128;
587 	      break;
588 
589 	    case DW_LNS_set_column:
590 	      /* Takes one uleb128 parameter which is stored in column.  */
591 	      if (unlikely (standard_opcode_lengths[opcode] != 1))
592 		goto invalid_data;
593 
594 	      if (unlikely (linep >= lineendp))
595 		goto invalid_data;
596 	      get_uleb128 (u128, linep, lineendp);
597 	      column = u128;
598 	      break;
599 
600 	    case DW_LNS_negate_stmt:
601 	      /* Takes no argument.  */
602 	      if (unlikely (standard_opcode_lengths[opcode] != 0))
603 		goto invalid_data;
604 
605 	      is_stmt = 1 - is_stmt;
606 	      break;
607 
608 	    case DW_LNS_set_basic_block:
609 	      /* Takes no argument.  */
610 	      if (unlikely (standard_opcode_lengths[opcode] != 0))
611 		goto invalid_data;
612 
613 	      basic_block = true;
614 	      break;
615 
616 	    case DW_LNS_const_add_pc:
617 	      /* Takes no argument.  */
618 	      if (unlikely (standard_opcode_lengths[opcode] != 0))
619 		goto invalid_data;
620 
621 	      if (unlikely (line_range == 0))
622 		goto invalid_data;
623 
624 	      advance_pc ((255 - opcode_base) / line_range);
625 	      break;
626 
627 	    case DW_LNS_fixed_advance_pc:
628 	      /* Takes one 16 bit parameter which is added to the
629 		 address.  */
630 	      if (unlikely (standard_opcode_lengths[opcode] != 1)
631 		  || unlikely (lineendp - linep < 2))
632 		goto invalid_data;
633 
634 	      addr += read_2ubyte_unaligned_inc (dbg, linep);
635 	      op_index = 0;
636 	      break;
637 
638 	    case DW_LNS_set_prologue_end:
639 	      /* Takes no argument.  */
640 	      if (unlikely (standard_opcode_lengths[opcode] != 0))
641 		goto invalid_data;
642 
643 	      prologue_end = true;
644 	      break;
645 
646 	    case DW_LNS_set_epilogue_begin:
647 	      /* Takes no argument.  */
648 	      if (unlikely (standard_opcode_lengths[opcode] != 0))
649 		goto invalid_data;
650 
651 	      epilogue_begin = true;
652 	      break;
653 
654 	    case DW_LNS_set_isa:
655 	      /* Takes one uleb128 parameter which is stored in isa.  */
656 	      if (unlikely (standard_opcode_lengths[opcode] != 1))
657 		goto invalid_data;
658 
659 	      if (unlikely (linep >= lineendp))
660 		goto invalid_data;
661 	      get_uleb128 (isa, linep, lineendp);
662 	      break;
663 	    }
664 	}
665       else
666 	{
667 	  /* This is a new opcode the generator but not we know about.
668 	     Read the parameters associated with it but then discard
669 	     everything.  Read all the parameters for this opcode.  */
670 	  for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
671 	    {
672 	      if (unlikely (linep >= lineendp))
673 		goto invalid_data;
674 	      get_uleb128 (u128, linep, lineendp);
675 	    }
676 
677 	  /* Next round, ignore this opcode.  */
678 	  continue;
679 	}
680     }
681 
682   /* Put all the files in an array.  */
683   Dwarf_Files *files = libdw_alloc (dbg, Dwarf_Files,
684 				    sizeof (Dwarf_Files)
685 				    + nfilelist * sizeof (Dwarf_Fileinfo)
686 				    + (ndirlist + 1) * sizeof (char *),
687 				    1);
688   const char **dirs = (void *) &files->info[nfilelist];
689 
690   files->nfiles = nfilelist;
691   while (nfilelist-- > 0)
692     {
693       files->info[nfilelist] = filelist->info;
694       filelist = filelist->next;
695     }
696   assert (filelist == NULL);
697 
698   /* Put all the directory strings in an array.  */
699   files->ndirs = ndirlist;
700   for (unsigned int i = 0; i < ndirlist; ++i)
701     dirs[i] = dirarray[i]->dir;
702   dirs[ndirlist] = NULL;
703 
704   /* Pass the file data structure to the caller.  */
705   if (filesp != NULL)
706     *filesp = files;
707 
708   size_t buf_size = (sizeof (Dwarf_Lines) + (sizeof (Dwarf_Line) * nlinelist));
709   void *buf = libdw_alloc (dbg, Dwarf_Lines, buf_size, 1);
710 
711   /* First use the buffer for the pointers, and sort the entries.
712      We'll write the pointers in the end of the buffer, and then
713      copy into the buffer from the beginning so the overlap works.  */
714   assert (sizeof (Dwarf_Line) >= sizeof (struct linelist *));
715   struct linelist **sortlines = (buf + buf_size
716 				 - sizeof (struct linelist **) * nlinelist);
717 
718   /* The list is in LIFO order and usually they come in clumps with
719      ascending addresses.  So fill from the back to probably start with
720      runs already in order before we sort.  */
721   for (size_t i = nlinelist; i-- > 0; )
722     {
723       sortlines[i] = linelist;
724       linelist = linelist->next;
725     }
726   assert (linelist == NULL);
727 
728   /* Sort by ascending address.  */
729   qsort (sortlines, nlinelist, sizeof sortlines[0], &compare_lines);
730 
731   /* Now that they are sorted, put them in the final array.
732      The buffers overlap, so we've clobbered the early elements
733      of SORTLINES by the time we're reading the later ones.  */
734   Dwarf_Lines *lines = buf;
735   lines->nlines = nlinelist;
736   for (size_t i = 0; i < nlinelist; ++i)
737     {
738       lines->info[i] = sortlines[i]->line;
739       lines->info[i].files = files;
740     }
741 
742   /* Make sure the highest address for the CU is marked as end_sequence.
743      This is required by the DWARF spec, but some compilers forget and
744      dwfl_module_getsrc depends on it.  */
745   if (nlinelist > 0)
746     lines->info[nlinelist - 1].end_sequence = 1;
747 
748   /* Pass the line structure back to the caller.  */
749   if (linesp != NULL)
750     *linesp = lines;
751 
752   /* Success.  */
753   res = 0;
754 
755  out:
756   /* Free malloced line records, if any.  */
757   for (size_t i = MAX_STACK_ALLOC; i < nlinelist; i++)
758     {
759       struct linelist *ll = malloc_linelist->next;
760       free (malloc_linelist);
761       malloc_linelist = ll;
762     }
763 
764   return res;
765 }
766 
767 static int
files_lines_compare(const void * p1,const void * p2)768 files_lines_compare (const void *p1, const void *p2)
769 {
770   const struct files_lines_s *t1 = p1;
771   const struct files_lines_s *t2 = p2;
772 
773   if (t1->debug_line_offset < t2->debug_line_offset)
774     return -1;
775   if (t1->debug_line_offset > t2->debug_line_offset)
776     return 1;
777 
778   return 0;
779 }
780 
781 int
782 internal_function
__libdw_getsrclines(Dwarf * dbg,Dwarf_Off debug_line_offset,const char * comp_dir,unsigned address_size,Dwarf_Lines ** linesp,Dwarf_Files ** filesp)783 __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
784 		     const char *comp_dir, unsigned address_size,
785 		     Dwarf_Lines **linesp, Dwarf_Files **filesp)
786 {
787   struct files_lines_s fake = { .debug_line_offset = debug_line_offset };
788   struct files_lines_s **found = tfind (&fake, &dbg->files_lines,
789 					files_lines_compare);
790   if (found == NULL)
791     {
792       Elf_Data *data = __libdw_checked_get_data (dbg, IDX_debug_line);
793       if (data == NULL
794 	  || __libdw_offset_in_section (dbg, IDX_debug_line,
795 					debug_line_offset, 1) != 0)
796 	return -1;
797 
798       const unsigned char *linep = data->d_buf + debug_line_offset;
799       const unsigned char *lineendp = data->d_buf + data->d_size;
800 
801       struct files_lines_s *node = libdw_alloc (dbg, struct files_lines_s,
802 						sizeof *node, 1);
803 
804       if (read_srclines (dbg, linep, lineendp, comp_dir, address_size,
805 			 &node->lines, &node->files) != 0)
806 	return -1;
807 
808       node->debug_line_offset = debug_line_offset;
809 
810       found = tsearch (node, &dbg->files_lines, files_lines_compare);
811       if (found == NULL)
812 	{
813 	  __libdw_seterrno (DWARF_E_NOMEM);
814 	  return -1;
815 	}
816     }
817 
818   if (linesp != NULL)
819     *linesp = (*found)->lines;
820 
821   if (filesp != NULL)
822     *filesp = (*found)->files;
823 
824   return 0;
825 }
826 
827 /* Get the compilation directory, if any is set.  */
828 const char *
__libdw_getcompdir(Dwarf_Die * cudie)829 __libdw_getcompdir (Dwarf_Die *cudie)
830 {
831   Dwarf_Attribute compdir_attr_mem;
832   Dwarf_Attribute *compdir_attr = INTUSE(dwarf_attr) (cudie,
833 						      DW_AT_comp_dir,
834 						      &compdir_attr_mem);
835   return INTUSE(dwarf_formstring) (compdir_attr);
836 }
837 
838 int
dwarf_getsrclines(Dwarf_Die * cudie,Dwarf_Lines ** lines,size_t * nlines)839 dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
840 {
841   if (unlikely (cudie == NULL
842 		|| (INTUSE(dwarf_tag) (cudie) != DW_TAG_compile_unit
843 		    && INTUSE(dwarf_tag) (cudie) != DW_TAG_partial_unit)))
844     return -1;
845 
846   /* Get the information if it is not already known.  */
847   struct Dwarf_CU *const cu = cudie->cu;
848   if (cu->lines == NULL)
849     {
850       /* Failsafe mode: no data found.  */
851       cu->lines = (void *) -1l;
852       cu->files = (void *) -1l;
853 
854       /* The die must have a statement list associated.  */
855       Dwarf_Attribute stmt_list_mem;
856       Dwarf_Attribute *stmt_list = INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list,
857 						       &stmt_list_mem);
858 
859       /* Get the offset into the .debug_line section.  NB: this call
860 	 also checks whether the previous dwarf_attr call failed.  */
861       Dwarf_Off debug_line_offset;
862       if (__libdw_formptr (stmt_list, IDX_debug_line, DWARF_E_NO_DEBUG_LINE,
863 			   NULL, &debug_line_offset) == NULL)
864 	return -1;
865 
866       if (__libdw_getsrclines (cu->dbg, debug_line_offset,
867 			       __libdw_getcompdir (cudie),
868 			       cu->address_size, &cu->lines, &cu->files) < 0)
869 	return -1;
870     }
871   else if (cu->lines == (void *) -1l)
872     return -1;
873 
874   *lines = cu->lines;
875   *nlines = cu->lines->nlines;
876 
877   // XXX Eventually: unlocking here.
878 
879   return 0;
880 }
881 INTDEF(dwarf_getsrclines)
882