1 /*
2
3 Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc. All Rights Reserved.
4 Portions Copyright (C) 2007-2010 David Anderson. 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 Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
27 Mountain View, CA 94043, or:
28
29 http://www.sgi.com
30
31 For further information regarding this notice, see:
32
33 http://oss.sgi.com/projects/GenInfo/NoticeExplan
34
35 */
36 /* The address of the Free Software Foundation is
37 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
38 Boston, MA 02110-1301, USA.
39 SGI has moved from the Crittenden Lane address.
40 */
41
42
43
44
45 #include "config.h"
46 #include "dwarf_incl.h"
47 #include <stdio.h>
48 #include <time.h>
49 #include "dwarf_line.h"
50
51 /* FIXME Need to add prologue_end epilogue_begin isa fields. */
52 static void
print_line_header(void)53 print_line_header(void)
54 {
55 printf
56 (" s b e\n"
57 " t l s\n"
58 " m c e\n"
59 " section op col t k q\n"
60 " offset code address file line umn ? ? ?\n");
61 }
62
63 /* FIXME: print new line values: prologue_end epilogue_begin isa */
64 static void
print_line_detail(char * prefix,int opcode,Dwarf_Unsigned address,unsigned long file,unsigned long line,unsigned long column,int is_stmt,int basic_block,int end_sequence,int prologue_end,int epilogue_begin,int isa)65 print_line_detail(char *prefix,
66 int opcode,
67 Dwarf_Unsigned address,
68 unsigned long file,
69 unsigned long line,
70 unsigned long column,
71 int is_stmt, int basic_block, int end_sequence,
72 int prologue_end, int epilogue_begin, int isa)
73 {
74 printf("%-15s %2d 0x%08" DW_PR_DUx " "
75 "%2lu %4lu %2lu %1d %1d %1d\n",
76 prefix,
77 (int) opcode,
78 (Dwarf_Unsigned) address,
79 (unsigned long) file,
80 (unsigned long) line,
81 (unsigned long) column,
82 (int) is_stmt, (int) basic_block, (int) end_sequence);
83
84 }
85
86
87 /*
88 return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR
89 If err_count_out is non-NULL, this is a special 'check'
90 call.
91 */
92 int
_dwarf_internal_printlines(Dwarf_Die die,Dwarf_Error * error,int * err_count_out,int only_line_header)93 _dwarf_internal_printlines(Dwarf_Die die, Dwarf_Error * error,
94 int * err_count_out, int only_line_header)
95 {
96 /*
97 This pointer is used to scan the portion of the .debug_line
98 section for the current cu. */
99 Dwarf_Small *line_ptr = 0;
100 Dwarf_Small *orig_line_ptr = 0;
101
102 /*
103 This points to the last byte of the .debug_line portion for the
104 current cu. */
105 Dwarf_Small *line_ptr_end = 0;
106
107 /*
108 Pointer to a DW_AT_stmt_list attribute in case it exists in the
109 die. */
110 Dwarf_Attribute stmt_list_attr = 0;
111
112 /* Pointer to DW_AT_comp_dir attribute in die. */
113 Dwarf_Attribute comp_dir_attr = 0;
114
115 /* Pointer to name of compilation directory. */
116 Dwarf_Small *comp_dir = NULL;
117
118 /*
119 Offset into .debug_line specified by a DW_AT_stmt_list
120 attribute. */
121 Dwarf_Unsigned line_offset = 0;
122
123 struct Line_Table_Prefix_s prefix;
124
125
126 /* These are the state machine state variables. */
127 Dwarf_Addr address = 0;
128 Dwarf_Word file = 1;
129 Dwarf_Word line = 1;
130 Dwarf_Word column = 0;
131 Dwarf_Bool is_stmt = false;
132 Dwarf_Bool basic_block = false;
133 Dwarf_Bool end_sequence = false;
134 Dwarf_Bool prologue_end = false;
135 Dwarf_Bool epilogue_begin = false;
136 Dwarf_Small isa = 0;
137
138
139 Dwarf_Sword i=0;
140
141 /*
142 This is the current opcode read from the statement program. */
143 Dwarf_Small opcode=0;
144
145
146 /*
147 These variables are used to decode leb128 numbers. Leb128_num
148 holds the decoded number, and leb128_length is its length in
149 bytes. */
150 Dwarf_Word leb128_num=0;
151 Dwarf_Word leb128_length=0;
152 Dwarf_Sword advance_line=0;
153 Dwarf_Half attrform = 0;
154 /*
155 This is the operand of the latest fixed_advance_pc extended
156 opcode. */
157 Dwarf_Half fixed_advance_pc=0;
158
159 /* In case there are wierd bytes 'after' the line table
160 * prologue this lets us print something. This is a gcc
161 * compiler bug and we expect the bytes count to be 12.
162 */
163 Dwarf_Small* bogus_bytes_ptr = 0;
164 Dwarf_Unsigned bogus_bytes_count = 0;
165
166
167 /* The Dwarf_Debug this die belongs to. */
168 Dwarf_Debug dbg=0;
169 int resattr = DW_DLV_ERROR;
170 int lres = DW_DLV_ERROR;
171 int res = DW_DLV_ERROR;
172
173 /* ***** BEGIN CODE ***** */
174
175 if (error != NULL) {
176 *error = NULL;
177 }
178
179 CHECK_DIE(die, DW_DLV_ERROR);
180 dbg = die->di_cu_context->cc_dbg;
181
182 res = _dwarf_load_section(dbg, &dbg->de_debug_line,error);
183 if (res != DW_DLV_OK) {
184 return res;
185 }
186
187 resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
188 if (resattr != DW_DLV_OK) {
189 return resattr;
190 }
191
192
193 /* The list of relevant FORMs is small.
194 DW_FORM_data4, DW_FORM_data8, DW_FORM_sec_offset
195 */
196 lres = dwarf_whatform(stmt_list_attr,&attrform,error);
197 if (lres != DW_DLV_OK) {
198 return lres;
199 }
200 if (attrform != DW_FORM_data4 && attrform != DW_FORM_data8 &&
201 attrform != DW_FORM_sec_offset ) {
202 _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
203 return (DW_DLV_ERROR);
204 }
205 lres = dwarf_global_formref(stmt_list_attr, &line_offset, error);
206 if (lres != DW_DLV_OK) {
207 return lres;
208 }
209
210 if (line_offset >= dbg->de_debug_line.dss_size) {
211 _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
212 return (DW_DLV_ERROR);
213 }
214 orig_line_ptr = dbg->de_debug_line.dss_data;
215 line_ptr = dbg->de_debug_line.dss_data + line_offset;
216 dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
217
218 /*
219 If die has DW_AT_comp_dir attribute, get the string that names
220 the compilation directory. */
221 resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
222 if (resattr == DW_DLV_ERROR) {
223 return resattr;
224 }
225 if (resattr == DW_DLV_OK) {
226 int cres = DW_DLV_ERROR;
227 char *cdir = 0;
228
229 cres = dwarf_formstring(comp_dir_attr, &cdir, error);
230 if (cres == DW_DLV_ERROR) {
231 return cres;
232 } else if (cres == DW_DLV_OK) {
233 comp_dir = (Dwarf_Small *) cdir;
234 }
235 }
236 if (resattr == DW_DLV_OK) {
237 dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
238 }
239
240 dwarf_init_line_table_prefix(&prefix);
241 {
242 Dwarf_Small *line_ptr_out = 0;
243 int dres = dwarf_read_line_table_prefix(dbg,
244 line_ptr,dbg->de_debug_line.dss_size - line_offset,
245 &line_ptr_out,
246 &prefix,
247 &bogus_bytes_ptr,
248 &bogus_bytes_count,
249 error,
250 err_count_out);
251 if (dres == DW_DLV_ERROR) {
252 dwarf_free_line_table_prefix(&prefix);
253 return dres;
254 }
255 if (dres == DW_DLV_NO_ENTRY) {
256 dwarf_free_line_table_prefix(&prefix);
257 return dres;
258 }
259 line_ptr_end = prefix.pf_line_ptr_end;
260 line_ptr = line_ptr_out;
261 }
262 if(only_line_header) {
263 /* Just checking for header errors, nothing more here.*/
264 dwarf_free_line_table_prefix(&prefix);
265 return DW_DLV_OK;
266 }
267
268
269 printf("total line info length %ld bytes, "
270 "line offset 0x%" DW_PR_DUx " %" DW_PR_DSd "\n",
271 (long) prefix.pf_total_length,
272 (Dwarf_Unsigned) line_offset,
273 (Dwarf_Signed) line_offset);
274 printf("line table version %d\n",(int) prefix.pf_version);
275 printf("line table length field length %d prologue length %d\n",
276 (int)prefix.pf_length_field_length,
277 (int)prefix.pf_prologue_length);
278 printf("compilation_directory %s\n",
279 comp_dir ? ((char *) comp_dir) : "");
280
281 printf(" min instruction length %d\n",
282 (int) prefix.pf_minimum_instruction_length);
283 printf(" default is stmt %d\n", (int)
284 prefix.pf_default_is_stmt);
285 printf(" line base %d\n", (int)
286 prefix.pf_line_base);
287 printf(" line_range %d\n", (int)
288 prefix.pf_line_range);
289 printf(" opcode base %d\n", (int)
290 prefix.pf_opcode_base);
291 printf(" standard opcode count %d\n", (int)
292 prefix.pf_std_op_count);
293
294 for (i = 1; i < prefix.pf_opcode_base; i++) {
295 printf(" opcode[%2d] length %d\n", (int) i,
296 (int) prefix.pf_opcode_length_table[i - 1]);
297 }
298 printf(" include directories count %d\n", (int)
299 prefix.pf_include_directories_count);
300
301
302 for (i = 0; i < prefix.pf_include_directories_count; ++i) {
303 printf(" include dir[%d] %s\n",
304 (int) i, prefix.pf_include_directories[i]);
305 }
306 printf(" files count %d\n", (int)
307 prefix.pf_files_count);
308
309 for (i = 0; i < prefix.pf_files_count; ++i) {
310 struct Line_Table_File_Entry_s *lfile =
311 prefix.pf_line_table_file_entries + i;
312
313 Dwarf_Unsigned tlm2 = lfile->lte_last_modification_time;
314 Dwarf_Unsigned di = lfile->lte_directory_index;
315 Dwarf_Unsigned fl = lfile->lte_length_of_file;
316
317 printf(" file[%d] %s (file-number: %d) \n",
318 (int) i, (char *) lfile->lte_filename,
319 (int)(i+1));
320
321 printf(" dir index %d\n", (int) di);
322 {
323 time_t tt = (time_t) tlm2;
324
325 printf(" last time 0x%x %s", /* ctime supplies
326 newline */
327 (unsigned) tlm2, ctime(&tt));
328 }
329 printf(" file length %ld 0x%lx\n",
330 (long) fl, (unsigned long) fl);
331
332
333 }
334
335
336 {
337 Dwarf_Unsigned offset = 0;
338 if(bogus_bytes_count > 0) {
339 Dwarf_Unsigned wcount = bogus_bytes_count;
340 Dwarf_Unsigned boffset = bogus_bytes_ptr - orig_line_ptr;
341 printf("*** DWARF CHECK: the line table prologue header_length "
342 " is %" DW_PR_DUu " too high, we pretend it is smaller."
343 "Section offset: %" DW_PR_DUu " (0x%" DW_PR_DUx ") ***\n",
344 wcount, boffset,boffset);
345 *err_count_out += 1;
346 }
347 offset = line_ptr - orig_line_ptr;
348
349 printf(" statement prog offset in section: %" DW_PR_DUu " 0x%" DW_PR_DUx "\n",
350 offset, offset);
351 }
352
353 /* Initialize the part of the state machine dependent on the
354 prefix. */
355 is_stmt = prefix.pf_default_is_stmt;
356
357
358 print_line_header();
359 /* Start of statement program. */
360 while (line_ptr < line_ptr_end) {
361 int type = 0;
362
363 printf(" [0x%06" DW_PR_DSx "] ",
364 (Dwarf_Signed) (line_ptr - orig_line_ptr));
365 opcode = *(Dwarf_Small *) line_ptr;
366 line_ptr++;
367 /* 'type' is the output */
368 WHAT_IS_OPCODE(type, opcode, prefix.pf_opcode_base,
369 prefix.pf_opcode_length_table, line_ptr,
370 prefix.pf_std_op_count);
371
372 if (type == LOP_DISCARD) {
373 int oc;
374 int opcnt = prefix.pf_opcode_length_table[opcode];
375
376 printf("*** DWARF CHECK: DISCARD standard opcode %d "
377 "with %d operands: "
378 "not understood.", opcode, opcnt);
379 *err_count_out += 1;
380 for (oc = 0; oc < opcnt; oc++) {
381 /*
382 * Read and discard operands we don't
383 * understand.
384 * Arbitrary choice of unsigned read.
385 * Signed read would work as well.
386 */
387 Dwarf_Unsigned utmp2;
388
389 DECODE_LEB128_UWORD(line_ptr, utmp2);
390 printf(" %" DW_PR_DUu " (0x%" DW_PR_DUx ")",
391 (Dwarf_Unsigned) utmp2,
392 (Dwarf_Unsigned) utmp2);
393 }
394
395 printf("***\n");
396 /* do nothing, necessary ops done */
397 } else if (type == LOP_SPECIAL) {
398 /* This op code is a special op in the object, no matter
399 that it might fall into the standard op range in this
400 compile Thatis, these are special opcodes between
401 special_opcode_base and MAX_LINE_OP_CODE. (including
402 special_opcode_base and MAX_LINE_OP_CODE) */
403 char special[50];
404 unsigned origop = opcode;
405
406 opcode = opcode - prefix.pf_opcode_base;
407 address = address + prefix.pf_minimum_instruction_length *
408 (opcode / prefix.pf_line_range);
409 line =
410 line + prefix.pf_line_base +
411 opcode % prefix.pf_line_range;
412
413 sprintf(special, "Specialop %3u", origop);
414 print_line_detail(special,
415 opcode, address, (int) file, line, column,
416 is_stmt, basic_block, end_sequence,
417 prologue_end, epilogue_begin, isa);
418
419 basic_block = false;
420
421 } else if (type == LOP_STANDARD) {
422 switch (opcode) {
423
424 case DW_LNS_copy:{
425
426 print_line_detail("DW_LNS_copy",
427 opcode, address, file, line,
428 column, is_stmt, basic_block,
429 end_sequence, prologue_end,
430 epilogue_begin, isa);
431
432 basic_block = false;
433 break;
434 }
435
436 case DW_LNS_advance_pc:{
437 Dwarf_Unsigned utmp2;
438
439
440 DECODE_LEB128_UWORD(line_ptr, utmp2);
441 printf("DW_LNS_advance_pc val %" DW_PR_DSd " 0x%" DW_PR_DUx "\n",
442 (Dwarf_Signed) (Dwarf_Word) utmp2,
443 (Dwarf_Unsigned) (Dwarf_Word) utmp2);
444 leb128_num = (Dwarf_Word) utmp2;
445 address =
446 address +
447 prefix.pf_minimum_instruction_length *
448 leb128_num;
449 break;
450 }
451
452 case DW_LNS_advance_line:{
453 Dwarf_Signed stmp;
454
455
456 DECODE_LEB128_SWORD(line_ptr, stmp);
457 advance_line = (Dwarf_Sword) stmp;
458 printf("DW_LNS_advance_line val %" DW_PR_DSd " 0x%" DW_PR_DSx "\n",
459 (Dwarf_Signed) advance_line,
460 (Dwarf_Signed) advance_line);
461 line = line + advance_line;
462 break;
463 }
464
465 case DW_LNS_set_file:{
466 Dwarf_Unsigned utmp2;
467
468
469 DECODE_LEB128_UWORD(line_ptr, utmp2);
470 file = (Dwarf_Word) utmp2;
471 printf("DW_LNS_set_file %ld\n", (long) file);
472 break;
473 }
474
475 case DW_LNS_set_column:{
476 Dwarf_Unsigned utmp2;
477
478
479 DECODE_LEB128_UWORD(line_ptr, utmp2);
480 column = (Dwarf_Word) utmp2;
481 printf("DW_LNS_set_column val %" DW_PR_DSd " 0x%" DW_PR_DSx "\n",
482 (Dwarf_Signed) column, (Dwarf_Signed) column);
483 break;
484 }
485
486 case DW_LNS_negate_stmt:{
487 is_stmt = !is_stmt;
488 printf("DW_LNS_negate_stmt\n");
489 break;
490 }
491
492 case DW_LNS_set_basic_block:{
493
494 printf("DW_LNS_set_basic_block\n");
495 basic_block = true;
496 break;
497 }
498
499 case DW_LNS_const_add_pc:{
500 opcode = MAX_LINE_OP_CODE - prefix.pf_opcode_base;
501 address =
502 address +
503 prefix.pf_minimum_instruction_length * (opcode /
504 prefix.
505 pf_line_range);
506
507 printf("DW_LNS_const_add_pc new address 0x%" DW_PR_DSx "\n",
508 (Dwarf_Signed) address);
509 break;
510 }
511
512 case DW_LNS_fixed_advance_pc:{
513
514 READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half,
515 line_ptr, sizeof(Dwarf_Half));
516 line_ptr += sizeof(Dwarf_Half);
517 address = address + fixed_advance_pc;
518 printf("DW_LNS_fixed_advance_pc val %" DW_PR_DSd
519 " 0x%" DW_PR_DSx " new address 0x%" DW_PR_DSx "\n",
520 (Dwarf_Signed) fixed_advance_pc,
521 (Dwarf_Signed) fixed_advance_pc,
522 (Dwarf_Signed) address);
523 break;
524 }
525 case DW_LNS_set_prologue_end:{
526
527 prologue_end = true;
528 printf("DW_LNS_set_prologue_end set true.\n");
529 break;
530
531
532 }
533 /* New in DWARF3 */
534 case DW_LNS_set_epilogue_begin:{
535 epilogue_begin = true;
536 printf("DW_LNS_set_epilogue_begin set true.\n");
537 break;
538 }
539
540 /* New in DWARF3 */
541 case DW_LNS_set_isa:{
542 Dwarf_Unsigned utmp2;
543
544 DECODE_LEB128_UWORD(line_ptr, utmp2);
545 isa = utmp2;
546 printf("DW_LNS_set_isa new value 0x%" DW_PR_DUx ".\n",
547 (Dwarf_Unsigned) utmp2);
548 if (isa != utmp2) {
549 /* The value of the isa did not fit in our
550 local so we record it wrong. declare an
551 error. */
552 dwarf_free_line_table_prefix(&prefix);
553
554 _dwarf_error(dbg, error,
555 DW_DLE_LINE_NUM_OPERANDS_BAD);
556 return (DW_DLV_ERROR);
557 }
558 break;
559 }
560 }
561
562
563 } else if (type == LOP_EXTENDED) {
564 Dwarf_Unsigned utmp3 = 0;
565 Dwarf_Word instr_length = 0;
566 Dwarf_Small ext_opcode = 0;
567
568 DECODE_LEB128_UWORD(line_ptr, utmp3);
569 instr_length = (Dwarf_Word) utmp3;
570 ext_opcode = *(Dwarf_Small *) line_ptr;
571 line_ptr++;
572 switch (ext_opcode) {
573
574 case DW_LNE_end_sequence:{
575 end_sequence = true;
576
577 print_line_detail("DW_LNE_end_sequence extended",
578 opcode, address, file, line,
579 column, is_stmt, basic_block,
580 end_sequence, prologue_end,
581 epilogue_begin, isa);
582
583 address = 0;
584 file = 1;
585 line = 1;
586 column = 0;
587 is_stmt = prefix.pf_default_is_stmt;
588 basic_block = false;
589 end_sequence = false;
590 prologue_end = false;
591 epilogue_begin = false;
592
593
594 break;
595 }
596
597 case DW_LNE_set_address:{
598 {
599 READ_UNALIGNED(dbg, address, Dwarf_Addr,
600 line_ptr,
601 die->di_cu_context->cc_address_size);
602
603 line_ptr += die->di_cu_context->cc_address_size;
604 printf("DW_LNE_set_address address 0x%" DW_PR_DUx "\n",
605 (Dwarf_Unsigned) address);
606 }
607
608 break;
609 }
610
611 case DW_LNE_define_file:{
612 Dwarf_Unsigned di = 0;
613 Dwarf_Unsigned tlm = 0;
614 Dwarf_Unsigned fl = 0;
615
616 Dwarf_Small *fn = (Dwarf_Small *) line_ptr;
617 line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
618
619 di = _dwarf_decode_u_leb128(line_ptr,
620 &leb128_length);
621 line_ptr = line_ptr + leb128_length;
622
623 tlm = _dwarf_decode_u_leb128(line_ptr,
624 &leb128_length);
625 line_ptr = line_ptr + leb128_length;
626
627 fl = _dwarf_decode_u_leb128(line_ptr,
628 &leb128_length);
629 line_ptr = line_ptr + leb128_length;
630
631
632 printf("DW_LNE_define_file %s \n", fn);
633 printf(" dir index %d\n", (int) di);
634 {
635 time_t tt3 = (time_t) tlm;
636
637 /* ctime supplies newline */
638 printf(" last time 0x%x %s",
639 (unsigned) tlm, ctime(&tt3));
640 }
641 printf(" file length %ld 0x%lx\n",
642 (long) fl, (unsigned long) fl);
643
644 break;
645 }
646
647 default:{
648 /* This is an extended op code we do not know about,
649 other than we know now many bytes it is
650 (and the op code and the bytes of operand). */
651
652 Dwarf_Unsigned remaining_bytes = instr_length -1;
653 if(instr_length < 1 || remaining_bytes > DW_LNE_LEN_MAX) {
654 dwarf_free_line_table_prefix(&prefix);
655 _dwarf_error(dbg, error,
656 DW_DLE_LINE_EXT_OPCODE_BAD);
657 return (DW_DLV_ERROR);
658 }
659 printf("DW_LNE extended op 0x%x ",ext_opcode);
660 printf("Bytecount: " DW_PR_DUu , instr_length);
661 if(remaining_bytes > 0) {
662 printf(" linedata: 0x");
663 while (remaining_bytes > 0) {
664 printf("%02x",(unsigned char)(*(line_ptr)));
665 line_ptr++;
666 remaining_bytes--;
667 }
668 }
669 printf("\n");
670 }
671 break;
672 }
673
674 }
675 }
676
677 dwarf_free_line_table_prefix(&prefix);
678 return (DW_DLV_OK);
679 }
680
681 /*
682 This is support for dwarfdump: making it possible
683 for clients wanting line detail info on stdout
684 to get that detail without including internal libdwarf
685 header information.
686 Caller passes in compilation unit DIE.
687 The _dwarf_ version is obsolete (though supported for
688 compatibility).
689 The dwarf_ version is preferred.
690 The functions are intentionally identical: having
691 _dwarf_print_lines call dwarf_print_lines might
692 better emphasize they are intentionally identical, but
693 that seemed slightly silly given how short the functions are.
694 Interface adds error_count (output value) February 2009.
695 */
696 int
dwarf_print_lines(Dwarf_Die die,Dwarf_Error * error,int * error_count)697 dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error,int *error_count)
698 {
699 int only_line_header = 0;
700 int res = _dwarf_internal_printlines(die, error,
701 error_count,
702 only_line_header);
703 if (res != DW_DLV_OK) {
704 return res;
705 }
706 return res;
707 }
708 int
_dwarf_print_lines(Dwarf_Die die,Dwarf_Error * error)709 _dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error)
710 {
711 int only_line_header = 0;
712 int err_count = 0;
713 int res = _dwarf_internal_printlines(die, error,
714 &err_count,
715 only_line_header);
716 /* No way to get error count back in this interface */
717 if (res != DW_DLV_OK) {
718 return res;
719 }
720 return res;
721 }
722
723 /* The check is in case we are not printing full line data,
724 this gets some of the issues noted with .debug_line,
725 but not all. Call dwarf_print_lines() to get all issues.
726 Intended for apps like dwarfdump.
727 */
728 void
dwarf_check_lineheader(Dwarf_Die die,int * err_count_out)729 dwarf_check_lineheader(Dwarf_Die die, int *err_count_out)
730 {
731 Dwarf_Error err;
732 int only_line_header = 1;
733 _dwarf_internal_printlines(die, &err,err_count_out,
734 only_line_header);
735 return;
736 }
737
738