Imported Upstream version 0.153
[platform/upstream/elfutils.git] / libdw / dwarf_getsrclines.c
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
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 int
90 dwarf_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 }
753 INTDEF(dwarf_getsrclines)