1 /*
2   Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc.  All Rights Reserved.
3   Portions Copyright (C) 2007-2013 David Anderson. All Rights Reserved.
4   Portions Copyright 2012 SN Systems Ltd. All rights reserved.
5 
6   This program is free software; you can redistribute it and/or modify it
7   under the terms of version 2.1 of the GNU Lesser General Public License
8   as published by the Free Software Foundation.
9 
10   This program is distributed in the hope that it would be useful, but
11   WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 
14   Further, this software is distributed without any warranty that it is
15   free of the rightful claim of any third person regarding infringement
16   or the like.  Any license provided herein, whether implied or
17   otherwise, applies only to this software file.  Patent licenses, if
18   any, provided herein do not apply to combinations of this program with
19   other software, or any other product whatsoever.
20 
21   You should have received a copy of the GNU Lesser General Public
22   License along with this program; if not, write the Free Software
23   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24   USA.
25 
26 */
27 
28 #include "config.h"
29 #include "dwarf_incl.h"
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <time.h>
33 #include "dwarf_line.h"
34 
35 #define PRINTING_DETAILS 1
36 
37 static void
print_line_header(Dwarf_Debug dbg,Dwarf_Bool is_single_tab,Dwarf_Bool is_actuals_tab)38 print_line_header(Dwarf_Debug dbg,
39     Dwarf_Bool is_single_tab,
40     Dwarf_Bool is_actuals_tab)
41 {
42 if (!is_single_tab) {
43     /* Ugly indenting follows, it makes lines shorter to see them better. */
44     if (is_actuals_tab) {
45         dwarf_printf(dbg,"\nActuals Table\n");
46 dwarf_printf(dbg,
47 "                                                         be\n"
48 "                                                         ls\n"
49 "                                                         ce\n"
50 " section    op                                           kq\n"
51 " offset     code                address/index    row isa ??\n");
52     return;
53     } else {
54         dwarf_printf(dbg,"\nLogicals Table\n");
55 dwarf_printf(dbg,
56 "                                                                              s pe\n"
57 "                                                                              tirp\n"
58 "                                                                              msoi\n"
59 " section          op                                                          tall\n"
60 " offset      row  code                address/indx fil lne col disc cntx subp ????\n");
61     return;
62     }
63 }
64 /* Single level table */
65 dwarf_printf(dbg,
66 "                                                         s b e p e i d\n"
67 "                                                         t l s r p s i\n"
68 "                                                         m c e o i a s\n"
69 " section    op                                       col t k q l l   c\n"
70 " offset     code               address     file line umn ? ? ? ? ? \n");
71 }
72 
73 static void
print_line_detail(Dwarf_Debug dbg,const char * prefix,int opcode,unsigned curr_line,struct Dwarf_Line_Registers_s * regs,Dwarf_Bool is_single_table,Dwarf_Bool is_actuals_table)74 print_line_detail(
75     Dwarf_Debug dbg,
76     const char *prefix,
77     int opcode,
78     unsigned curr_line,
79     struct Dwarf_Line_Registers_s * regs,
80     Dwarf_Bool is_single_table, Dwarf_Bool is_actuals_table)
81 {
82     if(!is_single_table && is_actuals_table) {
83         dwarf_printf(dbg,
84             "%-15s %3d 0x%" DW_PR_XZEROS DW_PR_DUx
85             "/%01u"
86             " %5lu"  /* lr_line, really logical row */
87             " %3d"   /* isa */
88             "   %1d"
89             "%1d\n",
90             prefix,
91             (int) opcode,
92             (Dwarf_Unsigned) regs->lr_address,
93             (unsigned) regs->lr_op_index,
94             (unsigned long) regs->lr_line, /*logical row */
95             regs->lr_isa,
96             (int) regs->lr_basic_block,
97             (int) regs->lr_end_sequence);
98         return;
99     }
100     if(!is_single_table && !is_actuals_table) {
101         dwarf_printf(dbg,
102             "[%3d] "  /* row number */
103             "%-15s %3d x%" DW_PR_XZEROS DW_PR_DUx "/%01u"
104             " %2lu %4lu  %1lu",
105             curr_line,
106             prefix,
107             (int) opcode,
108             (Dwarf_Unsigned) regs->lr_address,
109             (unsigned) regs->lr_op_index,
110             (unsigned long) regs->lr_file,
111             (unsigned long) regs->lr_line,
112             (unsigned long) regs->lr_column);
113         if (regs->lr_discriminator ||
114             regs->lr_prologue_end ||
115             regs->lr_epilogue_begin ||
116             regs->lr_isa ||
117             regs->lr_is_stmt ||
118             regs->lr_call_context ||
119             regs->lr_subprogram) {
120             dwarf_printf(dbg,
121                 "   x%02" DW_PR_DUx , regs->lr_discriminator); /* DWARF4 */
122             dwarf_printf(dbg,
123                 "  x%02" DW_PR_DUx , regs->lr_call_context); /* EXPERIMENTAL */
124             dwarf_printf(dbg,
125                 "  x%02" DW_PR_DUx , regs->lr_subprogram); /* EXPERIMENTAL */
126             dwarf_printf(dbg,
127                 "  %1d", (int) regs->lr_is_stmt);
128             dwarf_printf(dbg,
129                 "%1d", (int) regs->lr_isa);
130             dwarf_printf(dbg,
131                 "%1d", regs->lr_prologue_end); /* DWARF3 */
132             dwarf_printf(dbg,
133                 "%1d", regs->lr_epilogue_begin); /* DWARF3 */
134         }
135         dwarf_printf(dbg, "\n");
136         return;
137     }
138     /*  In the first quoted line below:
139         3d looks better than 2d, but best to do that as separate
140         change and test from two-level-line-tables.  */
141     dwarf_printf(dbg,
142         "%-15s %2d 0x%" DW_PR_XZEROS DW_PR_DUx " "
143         "%2lu   %4lu %2lu   %1d %1d %1d",
144         prefix,
145         (int) opcode,
146         (Dwarf_Unsigned) regs->lr_address,
147         (unsigned long) regs->lr_file,
148         (unsigned long) regs->lr_line,
149         (unsigned long) regs->lr_column,
150         (int) regs->lr_is_stmt,
151         (int) regs->lr_basic_block,
152         (int) regs->lr_end_sequence);
153     if (regs->lr_discriminator ||
154         regs->lr_prologue_end ||
155         regs->lr_epilogue_begin ||
156         regs->lr_isa) {
157         dwarf_printf(dbg,
158             " %1d", regs->lr_prologue_end); /* DWARF3 */
159         dwarf_printf(dbg,
160             " %1d", regs->lr_epilogue_begin); /* DWARF3 */
161         dwarf_printf(dbg,
162             " %1d", regs->lr_isa); /* DWARF3 */
163         dwarf_printf(dbg,
164             " 0x%" DW_PR_DUx , regs->lr_discriminator); /* DWARF4 */
165     }
166     dwarf_printf(dbg, "\n");
167 }
168 
169 
170 #include "dwarf_line_table_reader_common.c"
171 
172 void
_dwarf_print_line_context_record(UNUSEDARG Dwarf_Debug dbg,UNUSEDARG Dwarf_Line_Context line_context)173 _dwarf_print_line_context_record(UNUSEDARG Dwarf_Debug dbg,
174     UNUSEDARG Dwarf_Line_Context line_context)
175 {
176     return;
177 }
178 
179 /*  return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR
180     If err_count_out is non-NULL, this is a special 'check'
181     call.  */
182 static int
_dwarf_internal_printlines(Dwarf_Die die,Dwarf_Error * error,int * err_count_out,int only_line_header)183 _dwarf_internal_printlines(Dwarf_Die die,
184     Dwarf_Error * error,
185     int * err_count_out,
186     int only_line_header)
187 {
188     /*  This pointer is used to scan the portion of the .debug_line
189         section for the current cu. */
190     Dwarf_Small *line_ptr = 0;
191     Dwarf_Small *orig_line_ptr = 0;
192 
193     /*  Pointer to a DW_AT_stmt_list attribute in case it exists in the
194         die. */
195     Dwarf_Attribute stmt_list_attr = 0;
196 
197     /*  Pointer to DW_AT_comp_dir attribute in die. */
198     Dwarf_Attribute comp_dir_attr = 0;
199 
200     /*  Pointer to name of compilation directory. */
201     Dwarf_Small *comp_dir = NULL;
202 
203     /*  Offset into .debug_line specified by a DW_AT_stmt_list
204         attribute. */
205     Dwarf_Unsigned line_offset = 0;
206 
207     Dwarf_Sword i=0;
208     Dwarf_Word u=0;
209 
210     /*  These variables are used to decode leb128 numbers. Leb128_num
211         holds the decoded number, and leb128_length is its length in
212         bytes. */
213     Dwarf_Half attrform = 0;
214 
215     /*  In case there are wierd bytes 'after' the line table
216         prologue this lets us print something. This is a gcc
217         compiler bug and we expect the bytes count to be 12.  */
218     Dwarf_Small* bogus_bytes_ptr = 0;
219     Dwarf_Unsigned bogus_bytes_count = 0;
220     Dwarf_Half address_size = 0;
221     Dwarf_Unsigned fission_offset = 0;
222 
223 
224     /* The Dwarf_Debug this die belongs to. */
225     Dwarf_Debug dbg=0;
226     Dwarf_CU_Context cu_context = 0;
227     Dwarf_Line_Context line_context = 0;
228     int resattr = DW_DLV_ERROR;
229     int lres =    DW_DLV_ERROR;
230     int res  =    DW_DLV_ERROR;
231     Dwarf_Small *line_ptr_actuals  = 0;
232     Dwarf_Small *line_ptr_end = 0;
233     Dwarf_Small *section_start = 0;
234 
235     /* ***** BEGIN CODE ***** */
236 
237     if (error != NULL) {
238         *error = NULL;
239     }
240 
241     CHECK_DIE(die, DW_DLV_ERROR);
242     cu_context = die->di_cu_context;
243     dbg = cu_context->cc_dbg;
244 
245     res = _dwarf_load_section(dbg, &dbg->de_debug_line,error);
246     if (res != DW_DLV_OK) {
247         return res;
248     }
249     if (!dbg->de_debug_line.dss_size) {
250         return (DW_DLV_NO_ENTRY);
251     }
252 
253     address_size = _dwarf_get_address_size(dbg, die);
254     resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
255     if (resattr != DW_DLV_OK) {
256         return resattr;
257     }
258 
259 
260     /*  The list of relevant FORMs is small.
261         DW_FORM_data4, DW_FORM_data8, DW_FORM_sec_offset
262     */
263     lres = dwarf_whatform(stmt_list_attr,&attrform,error);
264     if (lres != DW_DLV_OK) {
265         return lres;
266     }
267     if (attrform != DW_FORM_data4 && attrform != DW_FORM_data8 &&
268         attrform != DW_FORM_sec_offset ) {
269         _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
270         return (DW_DLV_ERROR);
271     }
272     lres = dwarf_global_formref(stmt_list_attr, &line_offset, error);
273     if (lres != DW_DLV_OK) {
274         return lres;
275     }
276 
277     if (line_offset >= dbg->de_debug_line.dss_size) {
278         _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
279         return (DW_DLV_ERROR);
280     }
281     section_start =  dbg->de_debug_line.dss_data;
282     {
283         Dwarf_Unsigned fission_size = 0;
284         int resfis = _dwarf_get_fission_addition_die(die, DW_SECT_LINE,
285             &fission_offset,&fission_size,error);
286         if(resfis != DW_DLV_OK) {
287             return resfis;
288         }
289     }
290 
291     orig_line_ptr = section_start + line_offset + fission_offset;
292     line_ptr = orig_line_ptr;
293     dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
294 
295     /*  If die has DW_AT_comp_dir attribute, get the string that names
296         the compilation directory. */
297     resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
298     if (resattr == DW_DLV_ERROR) {
299         return resattr;
300     }
301     if (resattr == DW_DLV_OK) {
302         int cres = DW_DLV_ERROR;
303         char *cdir = 0;
304 
305         cres = dwarf_formstring(comp_dir_attr, &cdir, error);
306         if (cres == DW_DLV_ERROR) {
307             return cres;
308         } else if (cres == DW_DLV_OK) {
309             comp_dir = (Dwarf_Small *) cdir;
310         }
311     }
312     if (resattr == DW_DLV_OK) {
313         dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
314     }
315     line_context = (Dwarf_Line_Context)
316         _dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1);
317     if (line_context == NULL) {
318         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
319         return (DW_DLV_ERROR);
320     }
321     {
322         Dwarf_Small *newlinep = 0;
323         int dres = _dwarf_read_line_table_header(dbg,
324             cu_context,
325             section_start,
326             line_ptr,
327             dbg->de_debug_line.dss_size,
328             &newlinep,
329             line_context,
330             &bogus_bytes_ptr,
331             &bogus_bytes_count,
332             error,
333             err_count_out);
334         if (dres == DW_DLV_ERROR) {
335             dwarf_srclines_dealloc_b(line_context);
336             return dres;
337         }
338         if (dres == DW_DLV_NO_ENTRY) {
339             dwarf_srclines_dealloc_b(line_context);
340             return dres;
341         }
342         line_ptr_end = line_context->lc_line_ptr_end;
343         line_ptr = newlinep;
344         if (line_context->lc_actuals_table_offset > 0) {
345             line_ptr_actuals = line_context->lc_line_prologue_start +
346                 line_context->lc_actuals_table_offset;
347         }
348     }
349     line_context->lc_compilation_directory = comp_dir;
350     if (only_line_header) {
351         /* Just checking for header errors, nothing more here.*/
352         dwarf_srclines_dealloc_b(line_context);
353         return DW_DLV_OK;
354     }
355 
356     dwarf_printf(dbg,
357         "total line info length %ld bytes,"
358         " line offset 0x%" DW_PR_XZEROS DW_PR_DUx
359         " %" DW_PR_DUu "\n",
360         (long) line_context->lc_total_length,
361         line_context->lc_section_offset,
362         line_context->lc_section_offset);
363     if (line_context->lc_version_number <= DW_LINE_VERSION5) {
364         dwarf_printf(dbg,
365             "line table version %d\n",(int) line_context->lc_version_number);
366     } else {
367         dwarf_printf(dbg,
368             "line table version 0x%x\n",(int) line_context->lc_version_number);
369     }
370     dwarf_printf(dbg,
371         "line table length field length %d prologue length %d\n",
372         (int)line_context->lc_length_field_length,
373         (int)line_context->lc_prologue_length);
374     dwarf_printf(dbg,
375         "compilation_directory %s\n",
376         comp_dir ? ((char *) comp_dir) : "");
377 
378     dwarf_printf(dbg,
379         "  min instruction length %d\n",
380         (int) line_context->lc_minimum_instruction_length);
381     if (line_context->lc_version_number == EXPERIMENTAL_LINE_TABLES_VERSION) {
382         dwarf_printf(dbg, "  actuals table offset "
383             "0x%" DW_PR_XZEROS DW_PR_DUx
384             " logicals table offset "
385             "0x%" DW_PR_XZEROS DW_PR_DUx "\n",
386             line_context->lc_actuals_table_offset,
387             line_context->lc_logicals_table_offset);
388     }
389     if (line_context->lc_version_number == DW_LINE_VERSION5) {
390         dwarf_printf(dbg,
391             "  segment selector size %d\n",
392             (int) line_context->lc_segment_selector_size);
393         dwarf_printf(dbg,
394             "  address    size       %d\n",
395             (int) line_context->lc_address_size);
396     }
397     dwarf_printf(dbg,
398         "  default is stmt        %d\n",(int)line_context->lc_default_is_stmt);
399     dwarf_printf(dbg,
400         "  line base              %d\n",(int)line_context->lc_line_base);
401     dwarf_printf(dbg,
402         "  line_range             %d\n",(int)line_context->lc_line_range);
403     dwarf_printf(dbg,
404         "  opcode base            %d\n",(int)line_context->lc_opcode_base);
405     dwarf_printf(dbg,
406         "  standard opcode count  %d\n",(int)line_context->lc_std_op_count);
407 
408     for (i = 1; i < line_context->lc_opcode_base; i++) {
409         dwarf_printf(dbg,
410             "  opcode[%2d] length  %d\n", (int) i,
411             (int) line_context->lc_opcode_length_table[i - 1]);
412     }
413     dwarf_printf(dbg,
414         "  include directories count %d\n",
415         (int) line_context->lc_include_directories_count);
416     for (u = 0; u < line_context->lc_include_directories_count; ++u) {
417         dwarf_printf(dbg,
418             "  include dir[%u] %s\n",
419             (int) u, line_context->lc_include_directories[u]);
420     }
421     dwarf_printf(dbg,
422         "  files count            %d\n",
423         (int) line_context->lc_file_entry_count);
424 
425     if (line_context->lc_file_entry_count) {
426         Dwarf_File_Entry fe = line_context->lc_file_entries;
427         Dwarf_File_Entry fe2 = fe;
428         unsigned fiu = 0;
429 
430         for (fiu = 0 ; fe2 ; fe2 = fe->fi_next,++fiu ) {
431             Dwarf_Unsigned tlm2 = 0;
432             Dwarf_Unsigned di = 0;
433             Dwarf_Unsigned fl = 0;
434 
435             fe = fe2;
436             tlm2 = fe->fi_time_last_mod;
437             di = fe->fi_dir_index;
438             fl = fe->fi_file_length;
439 
440             dwarf_printf(dbg,
441                 "  file[%u]  %s (file-number: %u) \n",
442                 (unsigned) fiu, (char *) fe->fi_file_name,
443                 (unsigned)(fiu+1));
444             dwarf_printf(dbg,
445                 "    dir index %d\n", (int) di);
446             {
447                 time_t tt = (time_t) tlm2;
448 
449                 /* ctime supplies newline */
450                 dwarf_printf(dbg,
451                     "    last time 0x%x %s",
452                     (unsigned) tlm2, ctime(&tt));
453                 }
454             dwarf_printf(dbg,
455                 "    file length %ld 0x%lx\n",
456                 (long) fl, (unsigned long) fl);
457         }
458     }
459 
460     if (line_context->lc_version_number == EXPERIMENTAL_LINE_TABLES_VERSION) {
461         /*  Print the subprograms list. */
462         Dwarf_Unsigned count = line_context->lc_subprogs_count;
463         Dwarf_Unsigned exu = 0;
464         Dwarf_Subprog_Entry sub = line_context->lc_subprogs;
465         dwarf_printf(dbg,"  subprograms count"
466             " %" DW_PR_DUu "\n",count);
467         if (count > 0) {
468             dwarf_printf(dbg,"    indx  file   line   name\n");
469         }
470         for (exu = 0 ; exu < count ; exu++,sub++) {
471             dwarf_printf(dbg,"    [%2" DW_PR_DUu "] %4" DW_PR_DUu
472                 "    %4" DW_PR_DUu " %s\n",
473                 exu+1,
474                 sub->ds_decl_file,
475                 sub->ds_decl_line,
476                 sub->ds_subprog_name);
477         }
478     }
479     {
480         Dwarf_Unsigned offset = 0;
481         if (bogus_bytes_count > 0) {
482             Dwarf_Unsigned wcount = bogus_bytes_count;
483             Dwarf_Unsigned boffset = bogus_bytes_ptr - section_start;
484             dwarf_printf(dbg,
485                 "*** DWARF CHECK: the line table prologue  header_length "
486                 " is %" DW_PR_DUu " too high, we pretend it is smaller."
487                 "Section offset: 0x%" DW_PR_XZEROS DW_PR_DUx
488                 " (%" DW_PR_DUu ") ***\n",
489                 wcount, boffset,boffset);
490             *err_count_out += 1;
491         }
492         offset = line_ptr - section_start;
493         dwarf_printf(dbg,
494             "  statement prog offset in section: 0x%"
495             DW_PR_XZEROS DW_PR_DUx " (%" DW_PR_DUu ")\n",
496             offset, offset);
497     }
498 
499     {
500         Dwarf_Bool doaddrs = false;
501         Dwarf_Bool dolines = true;
502 
503         _dwarf_print_line_context_record(dbg,line_context);
504         if (!line_ptr_actuals) {
505             /* Normal single level line table. */
506 
507             Dwarf_Bool is_single_table = true;
508             Dwarf_Bool is_actuals_table = false;
509             print_line_header(dbg, is_single_table, is_actuals_table);
510             res = read_line_table_program(dbg,
511                 line_ptr, line_ptr_end, orig_line_ptr,
512                 section_start,
513                 line_context,
514                 address_size, doaddrs, dolines,
515                 is_single_table,
516                 is_actuals_table,
517                 error,
518                 err_count_out);
519             if (res != DW_DLV_OK) {
520                 dwarf_srclines_dealloc_b(line_context);
521                 return res;
522             }
523         } else {
524             Dwarf_Bool is_single_table = false;
525             Dwarf_Bool is_actuals_table = false;
526             if (line_context->lc_version_number !=
527                 EXPERIMENTAL_LINE_TABLES_VERSION) {
528                 dwarf_srclines_dealloc_b(line_context);
529                 _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
530                 return (DW_DLV_ERROR);
531             }
532             /* Read Logicals */
533             print_line_header(dbg, is_single_table, is_actuals_table);
534             res = read_line_table_program(dbg,
535                 line_ptr, line_ptr_actuals, orig_line_ptr,
536                 section_start,
537                 line_context,
538                 address_size, doaddrs, dolines,
539                 is_single_table,
540                 is_actuals_table,
541                 error,err_count_out);
542             if (res != DW_DLV_OK) {
543                 dwarf_srclines_dealloc_b(line_context);
544                 return res;
545             }
546             if (line_context->lc_actuals_table_offset > 0) {
547                 is_actuals_table = true;
548                 /* Read Actuals */
549 
550                 print_line_header(dbg, is_single_table, is_actuals_table);
551                 res = read_line_table_program(dbg,
552                     line_ptr_actuals, line_ptr_end, orig_line_ptr,
553                     section_start,
554                     line_context,
555                     address_size, doaddrs, dolines,
556                     is_single_table,
557                     is_actuals_table,
558                     error,
559                     err_count_out);
560                 if (res != DW_DLV_OK) {
561                     dwarf_srclines_dealloc_b(line_context);
562                     return res;
563                 }
564             }
565         }
566     }
567     dwarf_srclines_dealloc_b(line_context);
568     return DW_DLV_OK;
569 }
570 
571 
572 
573 /*  This is support for dwarfdump: making it possible
574     for clients wanting line detail info on stdout
575     to get that detail without including internal libdwarf
576     header information.
577     Caller passes in compilation unit DIE.
578     The _dwarf_ version is obsolete (though supported for
579     compatibility).
580     The dwarf_ version is preferred.
581     The functions are intentionally identical: having
582     _dwarf_print_lines call dwarf_print_lines might
583     better emphasize they are intentionally identical, but
584     that seemed slightly silly given how short the functions are.
585     Interface adds error_count (output value) February 2009.
586 
587     These *print_lines() functions print two-level tables in full
588     even when the user is not asking for both (ie, when
589     the caller asked for dwarf_srclines().
590     It was an accident, but after a short reflection
591     this seems like a good idea for -vvv. */
592 int
dwarf_print_lines(Dwarf_Die die,Dwarf_Error * error,int * error_count)593 dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error,int *error_count)
594 {
595     int only_line_header = 0;
596     int res = _dwarf_internal_printlines(die, error,
597         error_count,
598         only_line_header);
599     if (res != DW_DLV_OK) {
600         return res;
601     }
602     return res;
603 }
604 int
_dwarf_print_lines(Dwarf_Die die,Dwarf_Error * error)605 _dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error)
606 {
607     int only_line_header = 0;
608     int err_count = 0;
609     int res = _dwarf_internal_printlines(die, error,
610         &err_count,
611         only_line_header);
612     /* No way to get error count back in this interface */
613     if (res != DW_DLV_OK) {
614         return res;
615     }
616     return res;
617 }
618 
619 /* The check is in case we are not printing full line data,
620    this gets some of the issues noted with .debug_line,
621    but not all. Call dwarf_print_lines() to get all issues.
622    Intended for apps like dwarfdump.
623 */
624 void
dwarf_check_lineheader(Dwarf_Die die,int * err_count_out)625 dwarf_check_lineheader(Dwarf_Die die, int *err_count_out)
626 {
627     Dwarf_Error err;
628     int only_line_header = 1;
629     _dwarf_internal_printlines(die, &err,err_count_out,
630         only_line_header);
631     return;
632 }
633 
634 
635