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