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.
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.
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.
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.
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.
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>. */
65 struct filelist *next;
71 struct linelist *next;
75 /* Compare by Dwarf_Line.addr, given pointers into an array of pointers. */
77 compare_lines (const void *a, const void *b)
79 Dwarf_Line *const *p1 = a;
80 Dwarf_Line *const *p2 = b;
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;
86 return (*p1)->addr - (*p2)->addr;
90 dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
92 if (unlikely (cudie == NULL
93 || INTUSE(dwarf_tag) (cudie) != DW_TAG_compile_unit))
98 /* Get the information if it is not already known. */
99 struct Dwarf_CU *const cu = cudie->cu;
100 if (cu->lines == NULL)
102 /* Failsafe mode: no data found. */
103 cu->lines = (void *) -1l;
104 cu->files = (void *) -1l;
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,
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);
120 /* Get the compilation directory. */
121 Dwarf_Attribute compdir_attr_mem;
122 Dwarf_Attribute *compdir_attr = INTUSE(dwarf_attr) (cudie,
125 const char *comp_dir = INTUSE(dwarf_formstring) (compdir_attr);
127 if (unlikely (linep + 4 > lineendp))
130 __libdw_seterrno (DWARF_E_INVALID_DEBUG_LINE);
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))
139 if (unlikely (linep + 8 > lineendp))
141 unit_length = read_8ubyte_unaligned_inc (dbg, linep);
145 /* Check whether we have enough room in the section. */
146 if (unit_length < 2 + length + 5 * 1
147 || unlikely (linep + unit_length > lineendp))
149 lineendp = linep + unit_length;
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))
155 __libdw_seterrno (DWARF_E_VERSION);
159 /* Next comes the header length. */
160 Dwarf_Word header_length;
162 header_length = read_4ubyte_unaligned_inc (dbg, linep);
164 header_length = read_8ubyte_unaligned_inc (dbg, linep);
165 const unsigned char *header_start = linep;
167 /* Next the minimum instruction length. */
168 uint_fast8_t minimum_instr_len = *linep++;
170 /* Next the maximum operations per instruction, in version 4 format. */
171 uint_fast8_t max_ops_per_instr = 1;
174 if (unlikely (lineendp - linep < 5))
176 max_ops_per_instr = *linep++;
177 if (unlikely (max_ops_per_instr == 0))
181 /* Then the flag determining the default value of the is_stmt
183 uint_fast8_t default_is_stmt = *linep++;
185 /* Now the line base. */
186 int_fast8_t line_base = (int8_t) *linep++;
188 /* And the line range. */
189 uint_fast8_t line_range = *linep++;
191 /* The opcode base. */
192 uint_fast8_t opcode_base = *linep++;
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))
199 linep += opcode_base - 1;
201 /* First comes the list of directories. Add the compilation
202 directory first since the index zero is used for it. */
207 struct dirlist *next;
211 .len = comp_dir ? strlen (comp_dir) : 0,
214 struct dirlist *dirlist = &comp_dir_elem;
215 unsigned int ndirlist = 1;
217 // XXX Directly construct array to conserve memory?
220 struct dirlist *new_dir =
221 (struct dirlist *) alloca (sizeof (*new_dir));
223 new_dir->dir = (char *) linep;
224 uint8_t *endp = memchr (linep, '\0', lineendp - linep);
227 new_dir->len = endp - linep;
228 new_dir->next = dirlist;
233 /* Skip the final NUL byte. */
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;
242 /* Now read the files. */
243 struct filelist null_file =
253 struct filelist *filelist = &null_file;
254 unsigned int nfilelist = 1;
256 if (unlikely (linep >= lineendp))
260 struct filelist *new_file =
261 (struct filelist *) alloca (sizeof (*new_file));
263 /* First comes the file name. */
264 char *fname = (char *) linep;
265 uint8_t *endp = memchr (fname, '\0', lineendp - linep);
268 size_t fnamelen = endp - (uint8_t *) fname;
271 /* Then the index. */
273 get_uleb128 (diridx, linep);
274 if (unlikely (diridx >= ndirlist))
276 __libdw_seterrno (DWARF_E_INVALID_DIR_IDX);
281 /* It's an absolute path. */
282 new_file->info.name = fname;
285 new_file->info.name = libdw_alloc (dbg, char, 1,
286 dirarray[diridx]->len + 1
288 char *cp = new_file->info.name;
290 if (dirarray[diridx]->dir != NULL)
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
296 cp = stpcpy (cp, dirarray[diridx]->dir);
300 assert (strlen (new_file->info.name)
301 < dirarray[diridx]->len + 1 + fnamelen + 1);
304 /* Next comes the modification time. */
305 get_uleb128 (new_file->info.mtime, linep);
307 /* Finally the length of the file. */
308 get_uleb128 (new_file->info.length, linep);
310 new_file->next = filelist;
314 /* Skip the final NUL byte. */
317 /* Consistency check. */
318 if (unlikely (linep != header_start + header_length))
320 __libdw_seterrno (DWARF_E_INVALID_DWARF);
324 /* We are about to process the statement program. Initialize the
325 state machine registers (see 6.2.2 in the v2.1 specification). */
327 unsigned int op_index = 0;
328 unsigned int file = 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;
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)
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;
347 /* Process the instructions. */
348 struct linelist *linelist = NULL;
349 unsigned int nlinelist = 0;
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) \
355 if (unlikely (add_new_line (alloca (sizeof (struct linelist)), \
360 inline bool add_new_line (struct linelist *new_line, bool end_sequence)
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. */
368 new_line->line.field = field; \
369 if (unlikely (new_line->line.field != field)) \
382 SET (epilogue_begin);
388 new_line->next = linelist;
395 while (linep < lineendp)
401 /* Read the opcode. */
404 /* Is this a special opcode? */
405 if (likely (opcode >= opcode_base))
407 /* Yes. Handling this is quite easy since the opcode value
410 opcode = (desired line increment - line_base)
411 + (line_range * address advance) + opcode_base
413 int line_increment = (line_base
414 + (opcode - opcode_base) % line_range);
416 /* Perform the increments. */
417 line += line_increment;
418 advance_pc ((opcode - opcode_base) / line_range);
420 /* Add a new line with the current state machine values. */
423 /* Reset the flags. */
425 prologue_end = false;
426 epilogue_begin = false;
429 else if (opcode == 0)
431 /* This an extended opcode. */
432 if (unlikely (lineendp - linep < 2))
436 uint_fast8_t len = *linep++;
438 if (unlikely ((size_t) (lineendp - linep) < len))
441 /* The sub-opcode. */
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. */
451 /* Reset the registers. */
457 is_stmt = default_is_stmt;
459 prologue_end = false;
460 epilogue_begin = false;
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. */
470 if (unlikely (lineendp - linep < cu->address_size))
472 if (__libdw_read_address_inc (dbg, IDX_debug_line, &linep,
473 cu->address_size, &addr))
477 case DW_LNE_define_file:
479 char *fname = (char *) linep;
480 uint8_t *endp = memchr (linep, '\0', lineendp - linep);
483 size_t fnamelen = endp - linep;
487 get_uleb128 (diridx, linep);
489 get_uleb128 (mtime, linep);
490 Dwarf_Word filelength;
491 get_uleb128 (filelength, linep);
493 struct filelist *new_file =
494 (struct filelist *) alloca (sizeof (*new_file));
496 new_file->info.name = fname;
499 new_file->info.name =
500 libdw_alloc (dbg, char, 1, (dirarray[diridx]->len + 1
502 char *cp = new_file->info.name;
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
510 cp = stpcpy (cp, dirarray[diridx]->dir);
515 new_file->info.mtime = mtime;
516 new_file->info.length = filelength;
517 new_file->next = filelist;
523 case DW_LNE_set_discriminator:
524 /* Takes one ULEB128 parameter, the discriminator. */
525 if (unlikely (standard_opcode_lengths[opcode] != 1))
528 get_uleb128 (discriminator, linep);
532 /* Unknown, ignore it. */
533 if (unlikely ((size_t) (lineendp - (linep - 1)) < len))
539 else if (opcode <= DW_LNS_set_isa)
541 /* This is a known standard opcode. */
545 /* Takes no argument. */
546 if (unlikely (standard_opcode_lengths[opcode] != 0))
549 /* Add a new line with the current state machine values. */
552 /* Reset the flags. */
554 prologue_end = false;
555 epilogue_begin = false;
559 case DW_LNS_advance_pc:
560 /* Takes one uleb128 parameter which is added to the
562 if (unlikely (standard_opcode_lengths[opcode] != 1))
565 get_uleb128 (u128, linep);
569 case DW_LNS_advance_line:
570 /* Takes one sleb128 parameter which is added to the
572 if (unlikely (standard_opcode_lengths[opcode] != 1))
575 get_sleb128 (s128, linep);
579 case DW_LNS_set_file:
580 /* Takes one uleb128 parameter which is stored in file. */
581 if (unlikely (standard_opcode_lengths[opcode] != 1))
584 get_uleb128 (u128, linep);
588 case DW_LNS_set_column:
589 /* Takes one uleb128 parameter which is stored in column. */
590 if (unlikely (standard_opcode_lengths[opcode] != 1))
593 get_uleb128 (u128, linep);
597 case DW_LNS_negate_stmt:
598 /* Takes no argument. */
599 if (unlikely (standard_opcode_lengths[opcode] != 0))
602 is_stmt = 1 - is_stmt;
605 case DW_LNS_set_basic_block:
606 /* Takes no argument. */
607 if (unlikely (standard_opcode_lengths[opcode] != 0))
613 case DW_LNS_const_add_pc:
614 /* Takes no argument. */
615 if (unlikely (standard_opcode_lengths[opcode] != 0))
618 advance_pc ((255 - opcode_base) / line_range);
621 case DW_LNS_fixed_advance_pc:
622 /* Takes one 16 bit parameter which is added to the
624 if (unlikely (standard_opcode_lengths[opcode] != 1)
625 || unlikely (lineendp - linep < 2))
628 addr += read_2ubyte_unaligned_inc (dbg, linep);
632 case DW_LNS_set_prologue_end:
633 /* Takes no argument. */
634 if (unlikely (standard_opcode_lengths[opcode] != 0))
640 case DW_LNS_set_epilogue_begin:
641 /* Takes no argument. */
642 if (unlikely (standard_opcode_lengths[opcode] != 0))
645 epilogue_begin = true;
649 /* Takes one uleb128 parameter which is stored in isa. */
650 if (unlikely (standard_opcode_lengths[opcode] != 1))
653 get_uleb128 (isa, linep);
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);
665 /* Next round, ignore this opcode. */
670 /* Put all the files in an array. */
671 Dwarf_Files *files = libdw_alloc (dbg, Dwarf_Files,
673 + nfilelist * sizeof (Dwarf_Fileinfo)
674 + (ndirlist + 1) * sizeof (char *),
676 const char **dirs = (void *) &files->info[nfilelist];
678 files->nfiles = nfilelist;
679 while (nfilelist-- > 0)
681 files->info[nfilelist] = filelist->info;
682 filelist = filelist->next;
684 assert (filelist == NULL);
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;
692 /* Remember the referring CU. */
695 /* Make the file data structure available through the CU. */
698 void *buf = libdw_alloc (dbg, Dwarf_Lines, (sizeof (Dwarf_Lines)
699 + (sizeof (Dwarf_Line)
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));
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;
716 sortlines[i] = &linelist->line;
717 linelist = linelist->next;
719 assert (linelist == NULL);
721 /* Sort by ascending address. */
722 qsort (sortlines, nlinelist, sizeof sortlines[0], &compare_lines);
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. */
728 cu->lines->nlines = nlinelist;
729 for (i = 0; i < nlinelist; ++i)
731 cu->lines->info[i] = *sortlines[i];
732 cu->lines->info[i].files = files;
738 else if (cu->lines != (void *) -1l)
739 /* We already have the information. */
742 if (likely (res == 0))
745 *nlines = cu->lines->nlines;
749 // XXX Eventually: unlocking here.
753 INTDEF(dwarf_getsrclines)