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