Home | History | Annotate | Download | only in libdw
      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 (at) 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 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
     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
    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
    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 *
    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
    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