Home | History | Annotate | Download | only in libdw
      1 /* Return line number information of CU.
      2    Copyright (C) 2004, 2005, 2007, 2008 Red Hat, Inc.
      3    This file is part of Red Hat elfutils.
      4    Written by Ulrich Drepper <drepper (at) redhat.com>, 2004.
      5 
      6    Red Hat elfutils is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by the
      8    Free Software Foundation; version 2 of the License.
      9 
     10    Red Hat elfutils is distributed in the hope that it will be useful, but
     11    WITHOUT ANY WARRANTY; without even the implied warranty of
     12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13    General Public License for more details.
     14 
     15    You should have received a copy of the GNU General Public License along
     16    with Red Hat elfutils; if not, write to the Free Software Foundation,
     17    Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
     18 
     19    In addition, as a special exception, Red Hat, Inc. gives You the
     20    additional right to link the code of Red Hat elfutils with code licensed
     21    under any Open Source Initiative certified open source license
     22    (http://www.opensource.org/licenses/index.php) which requires the
     23    distribution of source code with any binary distribution and to
     24    distribute linked combinations of the two.  Non-GPL Code permitted under
     25    this exception must only link to the code of Red Hat elfutils through
     26    those well defined interfaces identified in the file named EXCEPTION
     27    found in the source code files (the "Approved Interfaces").  The files
     28    of Non-GPL Code may instantiate templates or use macros or inline
     29    functions from the Approved Interfaces without causing the resulting
     30    work to be covered by the GNU General Public License.  Only Red Hat,
     31    Inc. may make changes or additions to the list of Approved Interfaces.
     32    Red Hat's grant of this exception is conditioned upon your not adding
     33    any new exceptions.  If you wish to add a new Approved Interface or
     34    exception, please contact Red Hat.  You must obey the GNU General Public
     35    License in all respects for all of the Red Hat elfutils code and other
     36    code used in conjunction with Red Hat elfutils except the Non-GPL Code
     37    covered by this exception.  If you modify this file, you may extend this
     38    exception to your version of the file, but you are not obligated to do
     39    so.  If you do not wish to provide this exception without modification,
     40    you must delete this exception statement from your version and license
     41    this file solely under the GPL without exception.
     42 
     43    Red Hat elfutils is an included package of the Open Invention Network.
     44    An included package of the Open Invention Network is a package for which
     45    Open Invention Network licensees cross-license their patents.  No patent
     46    license is granted, either expressly or impliedly, by designation as an
     47    included package.  Should you wish to participate in the Open Invention
     48    Network licensing program, please visit www.openinventionnetwork.com
     49    <http://www.openinventionnetwork.com>.  */
     50 
     51 #ifdef HAVE_CONFIG_H
     52 # include <config.h>
     53 #endif
     54 
     55 #include <assert.h>
     56 #include <stdlib.h>
     57 #include <string.h>
     58 #include "dwarf.h"
     59 #include "libdwP.h"
     60 
     61 
     62 struct filelist
     63 {
     64   Dwarf_Fileinfo info;
     65   struct filelist *next;
     66 };
     67 
     68 struct linelist
     69 {
     70   Dwarf_Line line;
     71   struct linelist *next;
     72 };
     73 
     74 
     75 /* Compare by Dwarf_Line.addr, given pointers into an array of pointers.  */
     76 static int
     77 compare_lines (const void *a, const void *b)
     78 {
     79   Dwarf_Line *const *p1 = a;
     80   Dwarf_Line *const *p2 = b;
     81 
     82   if ((*p1)->addr == (*p2)->addr)
     83     /* An end_sequence marker precedes a normal record at the same address.  */
     84     return (*p2)->end_sequence - (*p1)->end_sequence;
     85 
     86   return (*p1)->addr - (*p2)->addr;
     87 }
     88 
     89 
     90 /* Adds a new line to the matrix.  We cannot define a function because
     91    we want to use alloca.  */
     92 #define NEW_LINE(end_seq) \
     93   do {									      \
     94     /* Add the new line.  */						      \
     95     new_line = (struct linelist *) alloca (sizeof (struct linelist));	      \
     96 									      \
     97     /* Set the line information.  */					      \
     98     new_line->line.addr = address;					      \
     99     new_line->line.file = file;						      \
    100     new_line->line.line = line;						      \
    101     new_line->line.column = column;					      \
    102     new_line->line.is_stmt = is_stmt;					      \
    103     new_line->line.basic_block = basic_block;				      \
    104     new_line->line.end_sequence = end_seq;				      \
    105     new_line->line.prologue_end = prologue_end;				      \
    106     new_line->line.epilogue_begin = epilogue_begin;			      \
    107 									      \
    108     new_line->next = linelist;						      \
    109     linelist = new_line;						      \
    110     ++nlinelist;							      \
    111   } while (0)
    112 
    113 
    114 int
    115 dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
    116 {
    117   if (unlikely (cudie == NULL
    118 		|| INTUSE(dwarf_tag) (cudie) != DW_TAG_compile_unit))
    119     return -1;
    120 
    121   int res = -1;
    122 
    123   /* Get the information if it is not already known.  */
    124   struct Dwarf_CU *const cu = cudie->cu;
    125   if (cu->lines == NULL)
    126     {
    127       /* Failsafe mode: no data found.  */
    128       cu->lines = (void *) -1l;
    129       cu->files = (void *) -1l;
    130 
    131       /* The die must have a statement list associated.  */
    132       Dwarf_Attribute stmt_list_mem;
    133       Dwarf_Attribute *stmt_list = INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list,
    134 						       &stmt_list_mem);
    135 
    136       /* Get the offset into the .debug_line section.  NB: this call
    137 	 also checks whether the previous dwarf_attr call failed.  */
    138       Dwarf_Word offset;
    139       if (INTUSE(dwarf_formudata) (stmt_list, &offset) != 0)
    140 	goto out;
    141 
    142       Dwarf *dbg = cu->dbg;
    143       if (dbg->sectiondata[IDX_debug_line] == NULL)
    144 	{
    145 	  __libdw_seterrno (DWARF_E_NO_DEBUG_LINE);
    146 	  goto out;
    147 	}
    148       const uint8_t *linep = dbg->sectiondata[IDX_debug_line]->d_buf + offset;
    149       const uint8_t *lineendp = (dbg->sectiondata[IDX_debug_line]->d_buf
    150 				 + dbg->sectiondata[IDX_debug_line]->d_size);
    151 
    152       /* Get the compilation directory.  */
    153       Dwarf_Attribute compdir_attr_mem;
    154       Dwarf_Attribute *compdir_attr = INTUSE(dwarf_attr) (cudie,
    155 							  DW_AT_comp_dir,
    156 							  &compdir_attr_mem);
    157       const char *comp_dir = INTUSE(dwarf_formstring) (compdir_attr);
    158 
    159       if (unlikely (linep + 4 > lineendp))
    160 	{
    161 	invalid_data:
    162 	  __libdw_seterrno (DWARF_E_INVALID_DEBUG_LINE);
    163 	  goto out;
    164 	}
    165       Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
    166       unsigned int length = 4;
    167       if (unlikely (unit_length == DWARF3_LENGTH_64_BIT))
    168 	{
    169 	  if (unlikely (linep + 8 > lineendp))
    170 	    goto invalid_data;
    171 	  unit_length = read_8ubyte_unaligned_inc (dbg, linep);
    172 	  length = 8;
    173 	}
    174 
    175       /* Check whether we have enough room in the section.  */
    176       if (unit_length < 2 + length + 5 * 1
    177 	  || unlikely (linep + unit_length > lineendp))
    178 	goto invalid_data;
    179       lineendp = linep + unit_length;
    180 
    181       /* The next element of the header is the version identifier.  */
    182       uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
    183       if (unlikely (version > DWARF_VERSION))
    184 	{
    185 	  __libdw_seterrno (DWARF_E_VERSION);
    186 	  goto out;
    187 	}
    188 
    189       /* Next comes the header length.  */
    190       Dwarf_Word header_length;
    191       if (length == 4)
    192 	header_length = read_4ubyte_unaligned_inc (dbg, linep);
    193       else
    194 	header_length = read_8ubyte_unaligned_inc (dbg, linep);
    195       const unsigned char *header_start = linep;
    196 
    197       /* Next the minimum instruction length.  */
    198       uint_fast8_t minimum_instr_len = *linep++;
    199 
    200         /* Then the flag determining the default value of the is_stmt
    201 	   register.  */
    202       uint_fast8_t default_is_stmt = *linep++;
    203 
    204       /* Now the line base.  */
    205       int_fast8_t line_base = *((int_fast8_t *) linep);
    206       ++linep;
    207 
    208       /* And the line range.  */
    209       uint_fast8_t line_range = *linep++;
    210 
    211       /* The opcode base.  */
    212       uint_fast8_t opcode_base = *linep++;
    213 
    214       /* Remember array with the standard opcode length (-1 to account for
    215 	 the opcode with value zero not being mentioned).  */
    216       const uint8_t *standard_opcode_lengths = linep - 1;
    217       linep += opcode_base - 1;
    218       if (unlikely (linep >= lineendp))
    219 	goto invalid_data;
    220 
    221       /* First comes the list of directories.  Add the compilation
    222 	 directory first since the index zero is used for it.  */
    223       struct dirlist
    224       {
    225 	const char *dir;
    226 	size_t len;
    227 	struct dirlist *next;
    228       } comp_dir_elem =
    229 	{
    230 	  .dir = comp_dir,
    231 	  .len = comp_dir ? strlen (comp_dir) : 0,
    232 	  .next = NULL
    233 	};
    234       struct dirlist *dirlist = &comp_dir_elem;
    235       unsigned int ndirlist = 1;
    236 
    237       // XXX Directly construct array to conserve memory?
    238       while (*linep != 0)
    239 	{
    240 	  struct dirlist *new_dir =
    241 	    (struct dirlist *) alloca (sizeof (*new_dir));
    242 
    243 	  new_dir->dir = (char *) linep;
    244 	  uint8_t *endp = memchr (linep, '\0', lineendp - linep);
    245 	  if (endp == NULL)
    246 	    goto invalid_data;
    247 	  new_dir->len = endp - linep;
    248 	  new_dir->next = dirlist;
    249 	  dirlist = new_dir;
    250 	  ++ndirlist;
    251 	  linep = endp + 1;
    252 	}
    253       /* Skip the final NUL byte.  */
    254       ++linep;
    255 
    256       /* Rearrange the list in array form.  */
    257       struct dirlist **dirarray
    258 	= (struct dirlist **) alloca (ndirlist * sizeof (*dirarray));
    259       for (unsigned int n = ndirlist; n-- > 0; dirlist = dirlist->next)
    260 	dirarray[n] = dirlist;
    261 
    262       /* Now read the files.  */
    263       struct filelist null_file =
    264 	{
    265 	  .info =
    266 	  {
    267 	    .name = "???",
    268 	    .mtime = 0,
    269 	    .length = 0
    270 	  },
    271 	  .next = NULL
    272 	};
    273       struct filelist *filelist = &null_file;
    274       unsigned int nfilelist = 1;
    275 
    276       if (unlikely (linep >= lineendp))
    277 	goto invalid_data;
    278       while (*linep != 0)
    279 	{
    280 	  struct filelist *new_file =
    281 	    (struct filelist *) alloca (sizeof (*new_file));
    282 
    283 	  /* First comes the file name.  */
    284 	  char *fname = (char *) linep;
    285 	  uint8_t *endp = memchr (fname, '\0', lineendp - linep);
    286 	  if (endp == NULL)
    287 	    goto invalid_data;
    288 	  size_t fnamelen = endp - (uint8_t *) fname;
    289 	  linep = endp + 1;
    290 
    291 	  /* Then the index.  */
    292 	  Dwarf_Word diridx;
    293 	  get_uleb128 (diridx, linep);
    294 	  if (unlikely (diridx >= ndirlist))
    295 	    {
    296 	      __libdw_seterrno (DWARF_E_INVALID_DIR_IDX);
    297 	      goto out;
    298 	    }
    299 
    300 	  if (*fname == '/')
    301 	    /* It's an absolute path.  */
    302 	    new_file->info.name = fname;
    303 	  else
    304 	    {
    305 	      new_file->info.name = libdw_alloc (dbg, char, 1,
    306 						 dirarray[diridx]->len + 1
    307 						 + fnamelen + 1);
    308               char *cp = new_file->info.name;
    309 
    310               if (dirarray[diridx]->dir != NULL)
    311 		{
    312 		  /* This value could be NULL in case the DW_AT_comp_dir
    313 		     was not present.  We cannot do much in this case.
    314 		     The easiest thing is to convert the path in an
    315                    absolute path.  */
    316 		  cp = stpcpy (cp, dirarray[diridx]->dir);
    317 		}
    318               *cp++ = '/';
    319               strcpy (cp, fname);
    320 	      assert (strlen (new_file->info.name)
    321 		      < dirarray[diridx]->len + 1 + fnamelen + 1);
    322             }
    323 
    324 	  /* Next comes the modification time.  */
    325 	  get_uleb128 (new_file->info.mtime, linep);
    326 
    327 	  /* Finally the length of the file.  */
    328 	  get_uleb128 (new_file->info.length, linep);
    329 
    330 	  new_file->next = filelist;
    331 	  filelist = new_file;
    332 	  ++nfilelist;
    333 	}
    334       /* Skip the final NUL byte.  */
    335       ++linep;
    336 
    337       /* Consistency check.  */
    338       if (unlikely (linep != header_start + header_length))
    339 	{
    340 	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
    341 	  goto out;
    342 	}
    343 
    344         /* We are about to process the statement program.  Initialize the
    345 	   state machine registers (see 6.2.2 in the v2.1 specification).  */
    346       Dwarf_Word address = 0;
    347       size_t file = 1;
    348       size_t line = 1;
    349       size_t column = 0;
    350       uint_fast8_t is_stmt = default_is_stmt;
    351       int basic_block = 0;
    352       int prologue_end = 0;
    353       int epilogue_begin = 0;
    354 
    355         /* Process the instructions.  */
    356       struct linelist *linelist = NULL;
    357       unsigned int nlinelist = 0;
    358       while (linep < lineendp)
    359 	{
    360 	  struct linelist *new_line;
    361 	  unsigned int opcode;
    362 	  unsigned int u128;
    363 	  int s128;
    364 
    365 	  /* Read the opcode.  */
    366 	  opcode = *linep++;
    367 
    368 	  /* Is this a special opcode?  */
    369 	  if (likely (opcode >= opcode_base))
    370 	    {
    371 	      /* Yes.  Handling this is quite easy since the opcode value
    372 		 is computed with
    373 
    374 		 opcode = (desired line increment - line_base)
    375 		           + (line_range * address advance) + opcode_base
    376 	      */
    377 	      int line_increment = (line_base
    378 				    + (opcode - opcode_base) % line_range);
    379 	      unsigned int address_increment = (minimum_instr_len
    380 						* ((opcode - opcode_base)
    381 						   / line_range));
    382 
    383 	      /* Perform the increments.  */
    384 	      line += line_increment;
    385 	      address += address_increment;
    386 
    387 	      /* Add a new line with the current state machine values.  */
    388 	      NEW_LINE (0);
    389 
    390 	      /* Reset the flags.  */
    391 	      basic_block = 0;
    392 	      prologue_end = 0;
    393 	      epilogue_begin = 0;
    394 	    }
    395 	  else if (opcode == 0)
    396 	    {
    397 	      /* This an extended opcode.  */
    398 	      if (unlikely (linep + 2 > lineendp))
    399 		goto invalid_data;
    400 
    401 	      /* The length.  */
    402 	      unsigned int len = *linep++;
    403 
    404 	      if (unlikely (linep + len > lineendp))
    405 		goto invalid_data;
    406 
    407 	      /* The sub-opcode.  */
    408 	      opcode = *linep++;
    409 
    410 	      switch (opcode)
    411 		{
    412 		case DW_LNE_end_sequence:
    413 		  /* Add a new line with the current state machine values.
    414 		     The is the end of the sequence.  */
    415 		  NEW_LINE (1);
    416 
    417 		  /* Reset the registers.  */
    418 		  address = 0;
    419 		  file = 1;
    420 		  line = 1;
    421 		  column = 0;
    422 		  is_stmt = default_is_stmt;
    423 		  basic_block = 0;
    424 		  prologue_end = 0;
    425 		  epilogue_begin = 0;
    426 		  break;
    427 
    428 		case DW_LNE_set_address:
    429 		  /* The value is an address.  The size is defined as
    430 		     apporiate for the target machine.  We use the
    431 		     address size field from the CU header.  */
    432 		  if (cu->address_size == 4)
    433 		    address = read_4ubyte_unaligned_inc (dbg, linep);
    434 		  else
    435 		    address = read_8ubyte_unaligned_inc (dbg, linep);
    436 		  break;
    437 
    438 		case DW_LNE_define_file:
    439 		  {
    440 		    char *fname = (char *) linep;
    441 		    uint8_t *endp = memchr (linep, '\0', lineendp - linep);
    442 		    if (endp == NULL)
    443 		      goto invalid_data;
    444 		    size_t fnamelen = endp - linep;
    445 		    linep = endp + 1;
    446 
    447 		    unsigned int diridx;
    448 		    get_uleb128 (diridx, linep);
    449 		    Dwarf_Word mtime;
    450 		    get_uleb128 (mtime, linep);
    451 		    Dwarf_Word filelength;
    452 		    get_uleb128 (filelength, linep);
    453 
    454 		    struct filelist *new_file =
    455 		      (struct filelist *) alloca (sizeof (*new_file));
    456 		    if (fname[0] == '/')
    457 		      new_file->info.name = fname;
    458 		    else
    459 		      {
    460 			new_file->info.name =
    461 			  libdw_alloc (dbg, char, 1, (dirarray[diridx]->len + 1
    462 						      + fnamelen + 1));
    463 			char *cp = new_file->info.name;
    464 
    465 			if (dirarray[diridx]->dir != NULL)
    466 			  /* This value could be NULL in case the
    467 			     DW_AT_comp_dir was not present.  We
    468 			     cannot do much in this case.  The easiest
    469 			     thing is to convert the path in an
    470 			     absolute path.  */
    471 			  cp = stpcpy (cp, dirarray[diridx]->dir);
    472 			*cp++ = '/';
    473 			strcpy (cp, fname);
    474 		      }
    475 
    476 		    new_file->info.mtime = mtime;
    477 		    new_file->info.length = filelength;
    478 		    new_file->next = filelist;
    479 		    filelist = new_file;
    480 		    ++nfilelist;
    481 		  }
    482 		  break;
    483 
    484 		default:
    485 		  /* Unknown, ignore it.  */
    486 		  linep += len - 1;
    487 		  break;
    488 		}
    489 	    }
    490 	  else if (opcode <= DW_LNS_set_epilogue_begin)
    491 	    {
    492 	      /* This is a known standard opcode.  */
    493 	      switch (opcode)
    494 		{
    495 		case DW_LNS_copy:
    496 		  /* Takes no argument.  */
    497 		  if (unlikely (standard_opcode_lengths[opcode] != 0))
    498 		    goto invalid_data;
    499 
    500 		  /* Add a new line with the current state machine values.  */
    501 		  NEW_LINE (0);
    502 
    503 		  /* Reset the flags.  */
    504 		  basic_block = 0;
    505 		  /* XXX Whether the following two lines are necessary is
    506 		     unclear.  I guess the current v2.1 specification has
    507 		     a bug in that it says clearing these two registers is
    508 		     not necessary.  */
    509 		  prologue_end = 0;
    510 		  epilogue_begin = 0;
    511 		  break;
    512 
    513 		case DW_LNS_advance_pc:
    514 		  /* Takes one uleb128 parameter which is added to the
    515 		     address.  */
    516 		  if (unlikely (standard_opcode_lengths[opcode] != 1))
    517 		    goto invalid_data;
    518 
    519 		  get_uleb128 (u128, linep);
    520 		  address += minimum_instr_len * u128;
    521 		  break;
    522 
    523 		case DW_LNS_advance_line:
    524 		  /* Takes one sleb128 parameter which is added to the
    525 		     line.  */
    526 		  if (unlikely (standard_opcode_lengths[opcode] != 1))
    527 		    goto invalid_data;
    528 
    529 		  get_sleb128 (s128, linep);
    530 		  line += s128;
    531 		  break;
    532 
    533 		case DW_LNS_set_file:
    534 		  /* Takes one uleb128 parameter which is stored in file.  */
    535 		  if (unlikely (standard_opcode_lengths[opcode] != 1))
    536 		    goto invalid_data;
    537 
    538 		  get_uleb128 (u128, linep);
    539 		  file = u128;
    540 		  break;
    541 
    542 		case DW_LNS_set_column:
    543 		  /* Takes one uleb128 parameter which is stored in column.  */
    544 		  if (unlikely (standard_opcode_lengths[opcode] != 1))
    545 		    goto invalid_data;
    546 
    547 		  get_uleb128 (u128, linep);
    548 		  column = u128;
    549 		  break;
    550 
    551 		case DW_LNS_negate_stmt:
    552 		  /* Takes no argument.  */
    553 		  if (unlikely (standard_opcode_lengths[opcode] != 0))
    554 		    goto invalid_data;
    555 
    556 		  is_stmt = 1 - is_stmt;
    557 		  break;
    558 
    559 		case DW_LNS_set_basic_block:
    560 		  /* Takes no argument.  */
    561 		  if (unlikely (standard_opcode_lengths[opcode] != 0))
    562 		    goto invalid_data;
    563 
    564 		  basic_block = 1;
    565 		  break;
    566 
    567 		case DW_LNS_const_add_pc:
    568 		  /* Takes no argument.  */
    569 		  if (unlikely (standard_opcode_lengths[opcode] != 0))
    570 		    goto invalid_data;
    571 
    572 		  address += (minimum_instr_len
    573 			      * ((255 - opcode_base) / line_range));
    574 		  break;
    575 
    576 		case DW_LNS_fixed_advance_pc:
    577 		  /* Takes one 16 bit parameter which is added to the
    578 		     address.  */
    579 		  if (unlikely (standard_opcode_lengths[opcode] != 1))
    580 		    goto invalid_data;
    581 
    582 		  address += read_2ubyte_unaligned_inc (dbg, linep);
    583 		  break;
    584 
    585 		case DW_LNS_set_prologue_end:
    586 		  /* Takes no argument.  */
    587 		  if (unlikely (standard_opcode_lengths[opcode] != 0))
    588 		    goto invalid_data;
    589 
    590 		  prologue_end = 1;
    591 		  break;
    592 
    593 		case DW_LNS_set_epilogue_begin:
    594 		  /* Takes no argument.  */
    595 		  if (unlikely (standard_opcode_lengths[opcode] != 0))
    596 		    goto invalid_data;
    597 
    598 		  epilogue_begin = 1;
    599 		  break;
    600 		}
    601 	    }
    602 	  else
    603 	    {
    604 	      /* This is a new opcode the generator but not we know about.
    605 		 Read the parameters associated with it but then discard
    606 		 everything.  Read all the parameters for this opcode.  */
    607 	      for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
    608 		get_uleb128 (u128, linep);
    609 
    610 	      /* Next round, ignore this opcode.  */
    611 	      continue;
    612 	    }
    613 	}
    614 
    615       /* Put all the files in an array.  */
    616       Dwarf_Files *files = libdw_alloc (dbg, Dwarf_Files,
    617 					sizeof (Dwarf_Files)
    618 					+ nfilelist * sizeof (Dwarf_Fileinfo)
    619 					+ (ndirlist + 1) * sizeof (char *),
    620 					1);
    621       const char **dirs = (void *) &files->info[nfilelist];
    622 
    623       files->nfiles = nfilelist;
    624       while (nfilelist-- > 0)
    625 	{
    626 	  files->info[nfilelist] = filelist->info;
    627 	  filelist = filelist->next;
    628 	}
    629       assert (filelist == NULL);
    630 
    631       /* Put all the directory strings in an array.  */
    632       files->ndirs = ndirlist;
    633       for (unsigned int i = 0; i < ndirlist; ++i)
    634 	dirs[i] = dirarray[i]->dir;
    635       dirs[ndirlist] = NULL;
    636 
    637       /* Remember the debugging descriptor.  */
    638       files->dbg = dbg;
    639 
    640       /* Make the file data structure available through the CU.  */
    641       cu->files = files;
    642 
    643       void *buf = libdw_alloc (dbg, Dwarf_Lines, (sizeof (Dwarf_Lines)
    644 						  + (sizeof (Dwarf_Line)
    645 						     * nlinelist)), 1);
    646 
    647       /* First use the buffer for the pointers, and sort the entries.
    648 	 We'll write the pointers in the end of the buffer, and then
    649 	 copy into the buffer from the beginning so the overlap works.  */
    650       assert (sizeof (Dwarf_Line) >= sizeof (Dwarf_Line *));
    651       Dwarf_Line **sortlines = (buf + sizeof (Dwarf_Lines)
    652 				+ ((sizeof (Dwarf_Line)
    653 				    - sizeof (Dwarf_Line *)) * nlinelist));
    654 
    655       /* The list is in LIFO order and usually they come in clumps with
    656 	 ascending addresses.  So fill from the back to probably start with
    657 	 runs already in order before we sort.  */
    658       unsigned int i = nlinelist;
    659       while (i-- > 0)
    660 	{
    661 	  sortlines[i] = &linelist->line;
    662 	  linelist = linelist->next;
    663 	}
    664       assert (linelist == NULL);
    665 
    666       /* Sort by ascending address.  */
    667       qsort (sortlines, nlinelist, sizeof sortlines[0], &compare_lines);
    668 
    669       /* Now that they are sorted, put them in the final array.
    670 	 The buffers overlap, so we've clobbered the early elements
    671 	 of SORTLINES by the time we're reading the later ones.  */
    672       cu->lines = buf;
    673       cu->lines->nlines = nlinelist;
    674       for (i = 0; i < nlinelist; ++i)
    675 	{
    676 	  cu->lines->info[i] = *sortlines[i];
    677 	  cu->lines->info[i].files = files;
    678 	}
    679 
    680       /* Success.  */
    681       res = 0;
    682     }
    683   else if (cu->lines != (void *) -1l)
    684     /* We already have the information.  */
    685     res = 0;
    686 
    687   if (likely (res == 0))
    688     {
    689       *lines = cu->lines;
    690       *nlines = cu->lines->nlines;
    691     }
    692  out:
    693 
    694   // XXX Eventually: unlocking here.
    695 
    696   return res;
    697 }
    698 INTDEF(dwarf_getsrclines)
    699