tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_print_lines.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /*
       
     2 
       
     3   Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc.  All Rights Reserved.
       
     4   Portions Copyright (C) 2007 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 #ifdef HAVE_ALLOCA_H
       
    51 #include <alloca.h>
       
    52 #endif
       
    53 
       
    54 /* FIXME Need to add prologue_end epilogue_begin isa fields. */
       
    55 static void
       
    56 print_line_header(void)
       
    57 {
       
    58     printf
       
    59 	("                                                         s b e\n"
       
    60 	 "                                                         t l s\n"
       
    61 	 "                                                         m c e\n"
       
    62 	 " section    op                                       col t k q\n"
       
    63 	 " offset     code               address     file line umn ? ? ?\n");
       
    64 }
       
    65 
       
    66 /* FIXME: print new line values:   prologue_end epilogue_begin isa */
       
    67 static void
       
    68 print_line_detail(char *prefix,
       
    69 		  int opcode,
       
    70 		  unsigned long long address,
       
    71 		  unsigned long file,
       
    72 		  unsigned long line,
       
    73 		  unsigned long column,
       
    74 		  int is_stmt, int basic_block, int end_sequence,
       
    75 		  int prologue_end, int epilogue_begin, int isa)
       
    76 {
       
    77     printf("%-15s %2d 0x%08llx "
       
    78 	   "%2lu   %4lu %2lu   %1d %1d %1d\n",
       
    79 	   prefix,
       
    80 	   (int) opcode,
       
    81 	   (long long) address,
       
    82 	   (unsigned long) file,
       
    83 	   (unsigned long) line,
       
    84 	   (unsigned long) column,
       
    85 	   (int) is_stmt, (int) basic_block, (int) end_sequence);
       
    86 
       
    87 }
       
    88 
       
    89 
       
    90 /*
       
    91 	return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR
       
    92 */
       
    93 int
       
    94 _dwarf_internal_printlines(Dwarf_Die die, Dwarf_Error * error)
       
    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;
       
   100     Dwarf_Small *orig_line_ptr;
       
   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;
       
   111 
       
   112     /* Pointer to DW_AT_comp_dir attribute in die. */
       
   113     Dwarf_Attribute comp_dir_attr;
       
   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;
       
   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;
       
   140 
       
   141     /* 
       
   142        This is the current opcode read from the statement program. */
       
   143     Dwarf_Small opcode;
       
   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;
       
   151     Dwarf_Word leb128_length;
       
   152     Dwarf_Sword advance_line;
       
   153 
       
   154     /* 
       
   155        This is the operand of the latest fixed_advance_pc extended
       
   156        opcode. */
       
   157     Dwarf_Half fixed_advance_pc;
       
   158 
       
   159 
       
   160     /* The Dwarf_Debug this die belongs to. */
       
   161     Dwarf_Debug dbg;
       
   162     int resattr;
       
   163     int lres;
       
   164 
       
   165     int res;
       
   166 
       
   167     /* ***** BEGIN CODE ***** */
       
   168 
       
   169     if (error != NULL)
       
   170 	*error = NULL;
       
   171 
       
   172     CHECK_DIE(die, DW_DLV_ERROR);
       
   173     dbg = die->di_cu_context->cc_dbg;
       
   174 
       
   175     res =
       
   176 	_dwarf_load_section(dbg,
       
   177 			    dbg->de_debug_line_index,
       
   178 			    &dbg->de_debug_line, error);
       
   179     if (res != DW_DLV_OK) {
       
   180 	return res;
       
   181     }
       
   182 
       
   183     resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
       
   184     if (resattr != DW_DLV_OK) {
       
   185 	return resattr;
       
   186     }
       
   187 
       
   188 
       
   189 
       
   190     lres = dwarf_formudata(stmt_list_attr, &line_offset, error);
       
   191     if (lres != DW_DLV_OK) {
       
   192 	return lres;
       
   193     }
       
   194 
       
   195     if (line_offset >= dbg->de_debug_line_size) {
       
   196 	_dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
       
   197 	return (DW_DLV_ERROR);
       
   198     }
       
   199     orig_line_ptr = dbg->de_debug_line;
       
   200     line_ptr = dbg->de_debug_line + line_offset;
       
   201     dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
       
   202 
       
   203     /* 
       
   204        If die has DW_AT_comp_dir attribute, get the string that names
       
   205        the compilation directory. */
       
   206     resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
       
   207     if (resattr == DW_DLV_ERROR) {
       
   208 	return resattr;
       
   209     }
       
   210     if (resattr == DW_DLV_OK) {
       
   211 	int cres;
       
   212 	char *cdir;
       
   213 
       
   214 	cres = dwarf_formstring(comp_dir_attr, &cdir, error);
       
   215 	if (cres == DW_DLV_ERROR) {
       
   216 	    return cres;
       
   217 	} else if (cres == DW_DLV_OK) {
       
   218 	    comp_dir = (Dwarf_Small *) cdir;
       
   219 	}
       
   220     }
       
   221     if (resattr == DW_DLV_OK) {
       
   222 	dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
       
   223     }
       
   224 
       
   225     dwarf_init_line_table_prefix(&prefix);
       
   226     {
       
   227 	Dwarf_Small *line_ptr_out = 0;
       
   228 	int dres = dwarf_read_line_table_prefix(dbg,
       
   229 						line_ptr,
       
   230 						dbg->
       
   231 						de_debug_line_size -
       
   232 						line_offset,
       
   233 						&line_ptr_out,
       
   234 						&prefix, error);
       
   235 
       
   236 	if (dres == DW_DLV_ERROR) {
       
   237 	    dwarf_free_line_table_prefix(&prefix);
       
   238 	    return dres;
       
   239 	}
       
   240 	if (dres == DW_DLV_NO_ENTRY) {
       
   241 	    dwarf_free_line_table_prefix(&prefix);
       
   242 	    return dres;
       
   243 	}
       
   244 	line_ptr_end = prefix.pf_line_ptr_end;
       
   245 	line_ptr = line_ptr_out;
       
   246     }
       
   247 
       
   248 
       
   249 
       
   250     printf("total line info length %ld bytes, "
       
   251 	   "line offset 0x%llx %lld\n",
       
   252 	   (long) prefix.pf_total_length,
       
   253 	   (long long) line_offset, (long long) line_offset);
       
   254     printf("compilation_directory %s\n",
       
   255 	   comp_dir ? ((char *) comp_dir) : "");
       
   256 
       
   257     printf("  min instruction length %d\n",
       
   258 	   (int) prefix.pf_minimum_instruction_length);
       
   259     printf("  default is stmt        %d\n", (int)
       
   260 	   prefix.pf_default_is_stmt);
       
   261     printf("  line base              %d\n", (int)
       
   262 	   prefix.pf_line_base);
       
   263     printf("  line_range             %d\n", (int)
       
   264 	   prefix.pf_line_range);
       
   265 
       
   266 
       
   267     for (i = 1; i < prefix.pf_opcode_base; i++) {
       
   268 	printf("  opcode[%d] length %d\n", (int) i,
       
   269 	       (int) prefix.pf_opcode_length_table[i - 1]);
       
   270     }
       
   271 
       
   272     for (i = 0; i < prefix.pf_include_directories_count; ++i) {
       
   273 	printf("  include dir[%d] %s\n",
       
   274 	       (int) i, prefix.pf_include_directories[i]);
       
   275     }
       
   276 
       
   277 
       
   278     for (i = 0; i < prefix.pf_files_count; ++i) {
       
   279 	struct Line_Table_File_Entry_s *lfile =
       
   280 	    prefix.pf_line_table_file_entries + i;
       
   281 
       
   282 	Dwarf_Unsigned tlm2 = lfile->lte_last_modification_time;
       
   283 	Dwarf_Unsigned di = lfile->lte_directory_index;
       
   284 	Dwarf_Unsigned fl = lfile->lte_length_of_file;
       
   285 
       
   286 	printf("  file[%d]  %s\n",
       
   287 	       (int) i, (char *) lfile->lte_filename);
       
   288 
       
   289 	printf("    dir index %d\n", (int) di);
       
   290 	{
       
   291 	    time_t tt = (time_t) tlm2;
       
   292 
       
   293 	    printf("    last time 0x%x %s",	/* ctime supplies
       
   294 						   newline */
       
   295 		   (unsigned) tlm2, ctime(&tt));
       
   296 	}
       
   297 	printf("    file length %ld 0x%lx\n",
       
   298 	       (long) fl, (unsigned long) fl);
       
   299 
       
   300 
       
   301     }
       
   302 
       
   303 
       
   304     {
       
   305 	unsigned long long offset = line_ptr - orig_line_ptr;
       
   306 
       
   307 	printf("  statement prog offset in section: %llu 0x%llx\n",
       
   308 	       offset, offset);
       
   309     }
       
   310 
       
   311     /* Initialize the part of the state machine dependent on the
       
   312        prefix.  */
       
   313     is_stmt = prefix.pf_default_is_stmt;
       
   314 
       
   315 
       
   316     print_line_header();
       
   317     /* Start of statement program.  */
       
   318     while (line_ptr < line_ptr_end) {
       
   319 	int type;
       
   320 
       
   321 	printf(" [0x%06llx] ", (long long) (line_ptr - orig_line_ptr));
       
   322 	opcode = *(Dwarf_Small *) line_ptr;
       
   323 	line_ptr++;
       
   324 	/* 'type' is the output */
       
   325 	WHAT_IS_OPCODE(type, opcode, prefix.pf_opcode_base,
       
   326 		       prefix.pf_opcode_length_table, line_ptr,
       
   327 		       prefix.pf_std_op_count);
       
   328 
       
   329 	if (type == LOP_DISCARD) {
       
   330 	    int oc;
       
   331 	    int opcnt = prefix.pf_opcode_length_table[opcode];
       
   332 
       
   333 	    printf(" DISCARD standard opcode %d with %d operands: "
       
   334 		   "not understood:", opcode, opcnt);
       
   335 	    for (oc = 0; oc < opcnt; oc++) {
       
   336 		/* 
       
   337 		 * Read and discard operands we don't
       
   338 		 * understand.
       
   339 		 * Arbitrary choice of unsigned read.
       
   340 		 * Signed read would work as well.
       
   341 		 */
       
   342 		Dwarf_Unsigned utmp2;
       
   343 
       
   344 		DECODE_LEB128_UWORD(line_ptr, utmp2);
       
   345 		printf(" %llu (0x%llx)",
       
   346 		       (unsigned long long) utmp2,
       
   347 		       (unsigned long long) utmp2);
       
   348 	    }
       
   349 
       
   350 	    printf("\n");
       
   351 	    /* do nothing, necessary ops done */
       
   352 	} else if (type == LOP_SPECIAL) {
       
   353 	    /* This op code is a special op in the object, no matter
       
   354 	       that it might fall into the standard op range in this
       
   355 	       compile Thatis, these are special opcodes between
       
   356 	       special_opcode_base and MAX_LINE_OP_CODE.  (including
       
   357 	       special_opcode_base and MAX_LINE_OP_CODE) */
       
   358 	    char special[50];
       
   359 	    unsigned origop = opcode;
       
   360 
       
   361 	    opcode = opcode - prefix.pf_opcode_base;
       
   362 	    address = address + prefix.pf_minimum_instruction_length *
       
   363 		(opcode / prefix.pf_line_range);
       
   364 	    line =
       
   365 		line + prefix.pf_line_base +
       
   366 		opcode % prefix.pf_line_range;
       
   367 
       
   368 	    sprintf(special, "Specialop %3u", origop);
       
   369 	    print_line_detail(special,
       
   370 			      opcode, address, (int) file, line, column,
       
   371 			      is_stmt, basic_block, end_sequence,
       
   372 			      prologue_end, epilogue_begin, isa);
       
   373 
       
   374 	    basic_block = false;
       
   375 
       
   376 	} else if (type == LOP_STANDARD) {
       
   377 	    switch (opcode) {
       
   378 
       
   379 	    case DW_LNS_copy:{
       
   380 
       
   381 		    print_line_detail("DW_LNS_copy",
       
   382 				      opcode, address, file, line,
       
   383 				      column, is_stmt, basic_block,
       
   384 				      end_sequence, prologue_end,
       
   385 				      epilogue_begin, isa);
       
   386 
       
   387 		    basic_block = false;
       
   388 		    break;
       
   389 		}
       
   390 
       
   391 	    case DW_LNS_advance_pc:{
       
   392 		    Dwarf_Unsigned utmp2;
       
   393 
       
   394 
       
   395 		    DECODE_LEB128_UWORD(line_ptr, utmp2);
       
   396 		    printf("DW_LNS_advance_pc val %lld 0x%llx\n",
       
   397 			   (long long) (Dwarf_Word) utmp2,
       
   398 			   (long long) (Dwarf_Word) utmp2);
       
   399 		    leb128_num = (Dwarf_Word) utmp2;
       
   400 		    address =
       
   401 			address +
       
   402 			prefix.pf_minimum_instruction_length *
       
   403 			leb128_num;
       
   404 		    break;
       
   405 		}
       
   406 
       
   407 	    case DW_LNS_advance_line:{
       
   408 		    Dwarf_Signed stmp;
       
   409 
       
   410 
       
   411 		    DECODE_LEB128_SWORD(line_ptr, stmp);
       
   412 		    advance_line = (Dwarf_Sword) stmp;
       
   413 		    printf("DW_LNS_advance_line val %lld 0x%llx\n",
       
   414 			   (long long) advance_line,
       
   415 			   (long long) advance_line);
       
   416 		    line = line + advance_line;
       
   417 		    break;
       
   418 		}
       
   419 
       
   420 	    case DW_LNS_set_file:{
       
   421 		    Dwarf_Unsigned utmp2;
       
   422 
       
   423 
       
   424 		    DECODE_LEB128_UWORD(line_ptr, utmp2);
       
   425 		    file = (Dwarf_Word) utmp2;
       
   426 		    printf("DW_LNS_set_file  %ld\n", (long) file);
       
   427 		    break;
       
   428 		}
       
   429 
       
   430 	    case DW_LNS_set_column:{
       
   431 		    Dwarf_Unsigned utmp2;
       
   432 
       
   433 
       
   434 		    DECODE_LEB128_UWORD(line_ptr, utmp2);
       
   435 		    column = (Dwarf_Word) utmp2;
       
   436 		    printf("DW_LNS_set_column val %lld 0x%llx\n",
       
   437 			   (long long) column, (long long) column);
       
   438 		    break;
       
   439 		}
       
   440 
       
   441 	    case DW_LNS_negate_stmt:{
       
   442 		    is_stmt = !is_stmt;
       
   443 		    printf("DW_LNS_negate_stmt\n");
       
   444 		    break;
       
   445 		}
       
   446 
       
   447 	    case DW_LNS_set_basic_block:{
       
   448 
       
   449 		    printf("DW_LNS_set_basic_block\n");
       
   450 		    basic_block = true;
       
   451 		    break;
       
   452 		}
       
   453 
       
   454 	    case DW_LNS_const_add_pc:{
       
   455 		    opcode = MAX_LINE_OP_CODE - prefix.pf_opcode_base;
       
   456 		    address =
       
   457 			address +
       
   458 			prefix.pf_minimum_instruction_length * (opcode /
       
   459 								prefix.
       
   460 								pf_line_range);
       
   461 
       
   462 		    printf("DW_LNS_const_add_pc new address 0x%llx\n",
       
   463 			   (long long) address);
       
   464 		    break;
       
   465 		}
       
   466 
       
   467 	    case DW_LNS_fixed_advance_pc:{
       
   468 
       
   469 		    READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half,
       
   470 				   line_ptr, sizeof(Dwarf_Half));
       
   471 		    line_ptr += sizeof(Dwarf_Half);
       
   472 		    address = address + fixed_advance_pc;
       
   473 		    printf("DW_LNS_fixed_advance_pc val %lld 0x%llx"
       
   474 			   " new address 0x%llx\n",
       
   475 			   (long long) fixed_advance_pc,
       
   476 			   (long long) fixed_advance_pc,
       
   477 			   (long long) address);
       
   478 		    break;
       
   479 		}
       
   480 	    case DW_LNS_set_prologue_end:{
       
   481 
       
   482 		    prologue_end = true;
       
   483 		    printf("DW_LNS_set_prologue_end set true.\n");
       
   484 		    break;
       
   485 
       
   486 
       
   487 		}
       
   488 		/* New in DWARF3 */
       
   489 	    case DW_LNS_set_epilogue_begin:{
       
   490 		    epilogue_begin = true;
       
   491 		    printf("DW_LNS_set_epilogue_begin set true.\n");
       
   492 		    break;
       
   493 		}
       
   494 
       
   495 		/* New in DWARF3 */
       
   496 	    case DW_LNS_set_isa:{
       
   497 		    Dwarf_Unsigned utmp2;
       
   498 
       
   499 		    DECODE_LEB128_UWORD(line_ptr, utmp2);
       
   500 		    isa = utmp2;
       
   501 		    printf("DW_LNS_set_isa new value 0x%llx.\n",
       
   502 			   (unsigned long long) utmp2);
       
   503 		    if (isa != utmp2) {
       
   504 			/* The value of the isa did not fit in our
       
   505 			   local so we record it wrong. declare an
       
   506 			   error. */
       
   507 			dwarf_free_line_table_prefix(&prefix);
       
   508 
       
   509 			_dwarf_error(dbg, error,
       
   510 				     DW_DLE_LINE_NUM_OPERANDS_BAD);
       
   511 			return (DW_DLV_ERROR);
       
   512 		    }
       
   513 		    break;
       
   514 		}
       
   515 	    }
       
   516 
       
   517 
       
   518 	} else if (type == LOP_EXTENDED) {
       
   519 	    Dwarf_Unsigned utmp3 = 0;
       
   520 	    Dwarf_Word instr_length = 0;
       
   521 	    Dwarf_Small ext_opcode = 0;
       
   522 
       
   523 	    DECODE_LEB128_UWORD(line_ptr, utmp3);
       
   524 	    instr_length = (Dwarf_Word) utmp3;
       
   525 	    ext_opcode = *(Dwarf_Small *) line_ptr;
       
   526 	    line_ptr++;
       
   527 	    switch (ext_opcode) {
       
   528 
       
   529 	    case DW_LNE_end_sequence:{
       
   530 		    end_sequence = true;
       
   531 
       
   532 		    print_line_detail("DW_LNE_end_sequence extended",
       
   533 				      opcode, address, file, line,
       
   534 				      column, is_stmt, basic_block,
       
   535 				      end_sequence, prologue_end,
       
   536 				      epilogue_begin, isa);
       
   537 
       
   538 		    address = 0;
       
   539 		    file = 1;
       
   540 		    line = 1;
       
   541 		    column = 0;
       
   542 		    is_stmt = prefix.pf_default_is_stmt;
       
   543 		    basic_block = false;
       
   544 		    end_sequence = false;
       
   545 		    prologue_end = false;
       
   546 		    epilogue_begin = false;
       
   547 
       
   548 
       
   549 		    break;
       
   550 		}
       
   551 
       
   552 	    case DW_LNE_set_address:{
       
   553 		    if (instr_length - 1 == dbg->de_pointer_size) {
       
   554 			READ_UNALIGNED(dbg, address, Dwarf_Addr,
       
   555 				       line_ptr, dbg->de_pointer_size);
       
   556 
       
   557 			line_ptr += dbg->de_pointer_size;
       
   558 			printf("DW_LNE_set_address address 0x%llx\n",
       
   559 			       (long long) address);
       
   560 		    } else {
       
   561 			dwarf_free_line_table_prefix(&prefix);
       
   562 			_dwarf_error(dbg, error,
       
   563 				     DW_DLE_LINE_SET_ADDR_ERROR);
       
   564 			return (DW_DLV_ERROR);
       
   565 		    }
       
   566 
       
   567 		    break;
       
   568 		}
       
   569 
       
   570 	    case DW_LNE_define_file:{
       
   571 
       
   572 
       
   573 		    Dwarf_Small *fn;
       
   574 		    Dwarf_Unsigned di;
       
   575 		    Dwarf_Unsigned tlm;
       
   576 		    Dwarf_Unsigned fl;
       
   577 
       
   578 		    fn = (Dwarf_Small *) line_ptr;
       
   579 		    line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
       
   580 
       
   581 		    di = _dwarf_decode_u_leb128(line_ptr,
       
   582 						&leb128_length);
       
   583 		    line_ptr = line_ptr + leb128_length;
       
   584 
       
   585 		    tlm = _dwarf_decode_u_leb128(line_ptr,
       
   586 						 &leb128_length);
       
   587 		    line_ptr = line_ptr + leb128_length;
       
   588 
       
   589 		    fl = _dwarf_decode_u_leb128(line_ptr,
       
   590 						&leb128_length);
       
   591 		    line_ptr = line_ptr + leb128_length;
       
   592 
       
   593 
       
   594 		    printf("DW_LNE_define_file %s \n", fn);
       
   595 		    printf("    dir index %d\n", (int) di);
       
   596 		    {
       
   597 			time_t tt3 = (time_t) tlm;
       
   598 
       
   599 			/* ctime supplies newline */
       
   600 			printf("    last time 0x%x %s",
       
   601 			       (unsigned) tlm, ctime(&tt3));
       
   602 		    }
       
   603 		    printf("    file length %ld 0x%lx\n",
       
   604 			   (long) fl, (unsigned long) fl);
       
   605 
       
   606 		    break;
       
   607 		}
       
   608 
       
   609 	    default:{
       
   610 		    dwarf_free_line_table_prefix(&prefix);
       
   611 		    _dwarf_error(dbg, error,
       
   612 				 DW_DLE_LINE_EXT_OPCODE_BAD);
       
   613 		    return (DW_DLV_ERROR);
       
   614 		}
       
   615 	    }
       
   616 
       
   617 	}
       
   618     }
       
   619 
       
   620     dwarf_free_line_table_prefix(&prefix);
       
   621     return (DW_DLV_OK);
       
   622 }
       
   623 
       
   624 /*
       
   625         This is support for dwarfdump: making it possible
       
   626         for clients wanting line detail info on stdout
       
   627         to get that detail without including internal libdwarf
       
   628         header information.
       
   629 	Caller passes in compilation unit DIE.
       
   630         The _dwarf version is obsolete (though supported for
       
   631         compatibility.
       
   632         The dwarf_ version is preferred.
       
   633 */
       
   634 int
       
   635 dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error)
       
   636 {
       
   637     int res;
       
   638 
       
   639     res = _dwarf_internal_printlines(die, error);
       
   640     if (res != DW_DLV_OK) {
       
   641 	return res;
       
   642     }
       
   643     return res;
       
   644 }
       
   645 int
       
   646 _dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error)
       
   647 {
       
   648     int res;
       
   649 
       
   650     res = _dwarf_internal_printlines(die, error);
       
   651     if (res != DW_DLV_OK) {
       
   652 	return res;
       
   653     }
       
   654     return res;
       
   655 }