tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwarfdump.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /* 
       
     2   Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
       
     3   Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
       
     4   Portions Copyright 2007 Sun Microsystems, Inc. All rights reserved.
       
     5   
       
     6 
       
     7   This program is free software; you can redistribute it and/or modify it
       
     8   under the terms of version 2 of the GNU General Public License as
       
     9   published by the Free Software Foundation.
       
    10 
       
    11   This program is distributed in the hope that it would be useful, but
       
    12   WITHOUT ANY WARRANTY; without even the implied warranty of
       
    13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
       
    14 
       
    15   Further, this software is distributed without any warranty that it is
       
    16   free of the rightful claim of any third person regarding infringement
       
    17   or the like.  Any license provided herein, whether implied or
       
    18   otherwise, applies only to this software file.  Patent licenses, if
       
    19   any, provided herein do not apply to combinations of this program with
       
    20   other software, or any other product whatsoever.
       
    21 
       
    22   You should have received a copy of the GNU General Public License along
       
    23   with this program; if not, write the Free Software Foundation, Inc., 51
       
    24   Franklin Street - Fifth Floor, Boston MA 02110-1301, 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 $Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/dwarfdump.c,v 1.48 2006/04/18 18:05:57 davea Exp $ */
       
    37 
       
    38 /* The address of the Free Software Foundation is
       
    39    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
       
    40    Boston, MA 02110-1301, USA.
       
    41    SGI has moved from the Crittenden Lane address.
       
    42 */
       
    43 
       
    44 
       
    45 
       
    46 #include "globals.h"
       
    47 
       
    48 /* for 'open' */
       
    49 #include <sys/types.h>
       
    50 #include <sys/stat.h>
       
    51 #include <fcntl.h>
       
    52 #ifdef HAVE_GETOPT_H
       
    53 #include <getopt.h>
       
    54 #endif
       
    55 
       
    56 #include "makename.h"
       
    57 #include "dwconf.h"
       
    58 extern char *optarg;
       
    59 
       
    60 #define OKAY 0
       
    61 #define FAILED 1
       
    62 #define BYTES_PER_INSTRUCTION 4
       
    63 
       
    64 static string process_args(int argc, char *argv[]);
       
    65 static void print_infos(Dwarf_Debug dbg);
       
    66 static void print_usage_message(void);
       
    67 
       
    68 static string program_name;
       
    69 int check_error = 0;
       
    70 
       
    71 /* defined in print_sections.c, die for the current compile unit, 
       
    72    used in get_fde_proc_name() */
       
    73 extern Dwarf_Die current_cu_die_for_print_frames;
       
    74 
       
    75 
       
    76 boolean info_flag = FALSE;
       
    77 boolean use_old_dwarf_loclist = FALSE;	/* This so both dwarf_loclist() 
       
    78 					   and dwarf_loclist_n() can be
       
    79 					   tested. Defaults to new
       
    80 					   dwarf_loclist_n() */
       
    81 
       
    82 static boolean line_flag = FALSE;
       
    83 static boolean abbrev_flag = FALSE;
       
    84 static boolean frame_flag = FALSE;	/* .debug_frame section. */
       
    85 static boolean eh_frame_flag = FALSE;	/* GNU .eh_frame section. */
       
    86 static boolean pubnames_flag = FALSE;
       
    87 static boolean macinfo_flag = FALSE;
       
    88 static boolean loc_flag = FALSE;
       
    89 static boolean aranges_flag = FALSE;
       
    90 static boolean string_flag = FALSE;
       
    91 static boolean reloc_flag = FALSE;
       
    92 static boolean static_func_flag = FALSE;
       
    93 static boolean static_var_flag = FALSE;
       
    94 static boolean type_flag = FALSE;
       
    95 static boolean weakname_flag = FALSE;
       
    96 
       
    97 int verbose = 0;
       
    98 boolean dense = FALSE;
       
    99 boolean ellipsis = FALSE;
       
   100 boolean dst_format = FALSE;
       
   101 boolean show_global_offsets = FALSE;
       
   102 
       
   103 boolean check_abbrev_code = FALSE;
       
   104 boolean check_pubname_attr = FALSE;
       
   105 boolean check_reloc_offset = FALSE;
       
   106 boolean check_attr_tag = FALSE;
       
   107 boolean check_tag_tree = FALSE;
       
   108 boolean check_type_offset = FALSE;
       
   109 boolean generic_1000_regs = FALSE;
       
   110 
       
   111 static boolean dwarf_check = FALSE;
       
   112 
       
   113 /* These configure items are for the 
       
   114    frame data.
       
   115 */
       
   116 static char *config_file_path = 0;
       
   117 static char *config_file_abi = 0;
       
   118 static char *config_file_defaults[] = {
       
   119     "./dwarfdump.conf",
       
   120     /* Note: HOME location uses .dwarfdump.  */
       
   121     "HOME/.dwarfdump.conf",
       
   122 #ifdef CONFPREFIX
       
   123 /* See Makefile.in  "libdir"  and CFLAGS  */
       
   124 /* We need 2 levels of macro to get the name turned into
       
   125    the string we want. */
       
   126 #define STR2(s) # s
       
   127 #define STR(s)  STR2(s)
       
   128     STR(CONFPREFIX)
       
   129 	"/dwarfdump.conf",
       
   130 #else
       
   131     "/usr/lib/dwarfdump.conf",
       
   132 #endif
       
   133     0
       
   134 };
       
   135 static struct dwconf_s config_file_data;
       
   136 
       
   137 char cu_name[BUFSIZ];
       
   138 boolean cu_name_flag = FALSE;
       
   139 Dwarf_Unsigned cu_offset = 0;
       
   140 
       
   141 Dwarf_Check_Result abbrev_code_result;
       
   142 Dwarf_Check_Result pubname_attr_result;
       
   143 Dwarf_Check_Result reloc_offset_result;
       
   144 Dwarf_Check_Result attr_tag_result;
       
   145 Dwarf_Check_Result tag_tree_result;
       
   146 Dwarf_Check_Result type_offset_result;
       
   147 
       
   148 Dwarf_Error err;
       
   149 
       
   150 #define PRINT_CHECK_RESULT(str,result)  {\
       
   151     fprintf(stderr, "%-24s%8d%8d\n", str, result.checks, result.errors); \
       
   152 }
       
   153 
       
   154 static int process_one_file(Elf * elf, string file_name, int archive,
       
   155 			    struct dwconf_s *conf);
       
   156 static int
       
   157 open_a_file(string name)
       
   158 {
       
   159     int f = 0;
       
   160 
       
   161 #ifdef __CYGWIN__
       
   162     f = open(name, O_RDONLY | O_BINARY);
       
   163 #else
       
   164     f = open(name, O_RDONLY);
       
   165 #endif
       
   166     return f;
       
   167 
       
   168 }
       
   169 
       
   170 /*
       
   171  * Iterate through dwarf and print all info.
       
   172  */
       
   173 int
       
   174 main(int argc, char *argv[])
       
   175 {
       
   176     string file_name;
       
   177     int f;
       
   178     Elf_Cmd cmd;
       
   179     Elf *arf, *elf;
       
   180     int archive = 0;
       
   181 
       
   182     (void) elf_version(EV_NONE);
       
   183     if (elf_version(EV_CURRENT) == EV_NONE) {
       
   184 	(void) fprintf(stderr, "dwarfdump: libelf.a out of date.\n");
       
   185 	exit(1);
       
   186     }
       
   187 
       
   188     file_name = process_args(argc, argv);
       
   189     f = open_a_file(file_name);
       
   190     if (f == -1) {
       
   191 	fprintf(stderr, "%s ERROR:  can't open %s\n", program_name,
       
   192 		file_name);
       
   193 	return (FAILED);
       
   194     }
       
   195 
       
   196     cmd = ELF_C_READ;
       
   197     arf = elf_begin(f, cmd, (Elf *) 0);
       
   198     if (elf_kind(arf) == ELF_K_AR) {
       
   199 	archive = 1;
       
   200     }
       
   201     while ((elf = elf_begin(f, cmd, arf)) != 0) {
       
   202 	Elf32_Ehdr *eh32;
       
   203 
       
   204 #ifdef HAVE_ELF64_GETEHDR
       
   205 	Elf64_Ehdr *eh64;
       
   206 #endif /* HAVE_ELF64_GETEHDR */
       
   207 	eh32 = elf32_getehdr(elf);
       
   208 	if (!eh32) {
       
   209 #ifdef HAVE_ELF64_GETEHDR
       
   210 	    /* not a 32-bit obj */
       
   211 	    eh64 = elf64_getehdr(elf);
       
   212 	    if (!eh64) {
       
   213 		/* not a 64-bit obj either! */
       
   214 		/* dwarfdump is quiet when not an object */
       
   215 	    } else {
       
   216 		process_one_file(elf, file_name, archive,
       
   217 				 &config_file_data);
       
   218 	    }
       
   219 #endif /* HAVE_ELF64_GETEHDR */
       
   220 	} else {
       
   221 	    process_one_file(elf, file_name, archive,
       
   222 			     &config_file_data);
       
   223 	}
       
   224 	cmd = elf_next(elf);
       
   225 	elf_end(elf);
       
   226     }
       
   227     elf_end(arf);
       
   228     /* Trivial malloc space cleanup. */
       
   229     clean_up_die_esb();
       
   230     clean_up_syms_malloc_data();
       
   231 
       
   232     if (check_error)
       
   233 	return FAILED;
       
   234     else
       
   235 	return OKAY;
       
   236 }
       
   237 
       
   238 /*
       
   239   Given a file which we know is an elf file, process
       
   240   the dwarf data.
       
   241 
       
   242 */
       
   243 static int
       
   244 process_one_file(Elf * elf, string file_name, int archive,
       
   245 		 struct dwconf_s *config_file_data)
       
   246 {
       
   247     Dwarf_Debug dbg;
       
   248     int dres;
       
   249 
       
   250     dres = dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL, &dbg, &err);
       
   251     if (dres == DW_DLV_NO_ENTRY) {
       
   252 	printf("No DWARF information present in %s\n", file_name);
       
   253 	return 0;
       
   254     }
       
   255     if (dres != DW_DLV_OK) {
       
   256 	print_error(dbg, "dwarf_elf_init", dres, err);
       
   257     }
       
   258 
       
   259     if (archive) {
       
   260 	Elf_Arhdr *mem_header = elf_getarhdr(elf);
       
   261 
       
   262 	printf("\narchive member \t%s\n",
       
   263 	       mem_header ? mem_header->ar_name : "");
       
   264     }
       
   265     dwarf_set_frame_rule_inital_value(dbg,
       
   266 				      config_file_data->
       
   267 				      cf_initial_rule_value);
       
   268     dwarf_set_frame_rule_table_size(dbg,
       
   269 				    config_file_data->
       
   270 				    cf_table_entry_count);
       
   271 
       
   272     if (info_flag || line_flag || cu_name_flag)
       
   273 	print_infos(dbg);
       
   274     if (pubnames_flag)
       
   275 	print_pubnames(dbg);
       
   276     if (macinfo_flag)
       
   277 	print_macinfo(dbg);
       
   278     if (loc_flag)
       
   279 	print_locs(dbg);
       
   280     if (abbrev_flag)
       
   281 	print_abbrevs(dbg);
       
   282     if (string_flag)
       
   283 	print_strings(dbg);
       
   284     if (aranges_flag)
       
   285 	print_aranges(dbg);
       
   286     if (frame_flag || eh_frame_flag) {
       
   287 	current_cu_die_for_print_frames = 0;
       
   288 	print_frames(dbg, frame_flag, eh_frame_flag, config_file_data);
       
   289     }
       
   290     if (static_func_flag)
       
   291 	print_static_funcs(dbg);
       
   292     if (static_var_flag)
       
   293 	print_static_vars(dbg);
       
   294     /* DWARF_PUBTYPES is the standard typenames dwarf section.
       
   295        SGI_TYPENAME is the same concept but is SGI specific ( it was
       
   296        defined 10 years before dwarf pubtypes). */
       
   297 
       
   298     if (type_flag) {
       
   299 	print_types(dbg, DWARF_PUBTYPES);
       
   300 	print_types(dbg, SGI_TYPENAME);
       
   301     }
       
   302     if (weakname_flag)
       
   303 	print_weaknames(dbg);
       
   304     if (reloc_flag)
       
   305 	print_relocinfo(dbg);
       
   306     if (dwarf_check) {
       
   307 	fprintf(stderr, "DWARF CHECK RESULT\n");
       
   308 	fprintf(stderr, "<item>                  <checks><errors>\n");
       
   309     }
       
   310     if (check_pubname_attr)
       
   311 	PRINT_CHECK_RESULT("pubname_attr", pubname_attr_result)
       
   312 	    if (check_attr_tag)
       
   313 	    PRINT_CHECK_RESULT("attr_tag", attr_tag_result)
       
   314 		if (check_tag_tree)
       
   315 		PRINT_CHECK_RESULT("tag_tree", tag_tree_result)
       
   316 		    if (check_type_offset)
       
   317 		    PRINT_CHECK_RESULT("type_offset",
       
   318 				       type_offset_result)
       
   319 
       
   320 			dres = dwarf_finish(dbg, &err);
       
   321     if (dres != DW_DLV_OK) {
       
   322 	print_error(dbg, "dwarf_finish", dres, err);
       
   323     }
       
   324     return 0;
       
   325 
       
   326 }
       
   327 
       
   328 static void do_all()
       
   329 {
       
   330 	info_flag = line_flag = frame_flag = abbrev_flag = TRUE;
       
   331 	pubnames_flag = aranges_flag = macinfo_flag = TRUE;
       
   332 	loc_flag = string_flag = TRUE;
       
   333 	reloc_flag = TRUE;
       
   334 	static_func_flag = static_var_flag = TRUE;
       
   335 	type_flag = weakname_flag = TRUE;
       
   336 }
       
   337 
       
   338 /* process arguments and return object filename */
       
   339 static string
       
   340 process_args(int argc, char *argv[])
       
   341 {
       
   342     extern int optind;
       
   343     int c = 0;
       
   344     boolean usage_error = FALSE;
       
   345     int oarg = 0;
       
   346 
       
   347     program_name = argv[0];
       
   348 
       
   349     /* j q unused */
       
   350     if (argv[1] != NULL && argv[1][0] != '-') {
       
   351 		do_all();
       
   352     }
       
   353 
       
   354     while ((c =
       
   355 	    getopt(argc, argv,
       
   356 		   "abcdefFgGhik:lmoprRst:u:vVwx:yz")) != EOF) {
       
   357 	switch (c) {
       
   358 	case 'x':		/* Select abi/path to use */
       
   359 	    {
       
   360 		char *path = 0;
       
   361 		char *abi = 0;
       
   362 
       
   363 		/* -x name=<path> meaning name dwarfdump.conf file -x
       
   364 		   abi=<abi> meaning select abi from dwarfdump.conf
       
   365 		   file. Must always select abi to use dwarfdump.conf */
       
   366 		if (strncmp(optarg, "name=", 5) == 0) {
       
   367 		    path = makename(&optarg[5]);
       
   368 		    if (strlen(path) < 1)
       
   369 			goto badopt;
       
   370 		    config_file_path = path;
       
   371 		} else if (strncmp(optarg, "abi=", 4) == 0) {
       
   372 		    abi = makename(&optarg[4]);
       
   373 		    if (strlen(abi) < 1)
       
   374 			goto badopt;
       
   375 		    config_file_abi = abi;
       
   376 		    break;
       
   377 		} else {
       
   378 		  badopt:
       
   379 		    fprintf(stderr, "-x name=<path-to-conf> \n");
       
   380 		    fprintf(stderr, " and  \n");
       
   381 		    fprintf(stderr, "-x abi=<abi-in-conf> \n");
       
   382 		    fprintf(stderr, "are legal, not -x %s\n", optarg);
       
   383 		    usage_error = TRUE;
       
   384 		    break;
       
   385 		}
       
   386 	    }
       
   387 	    break;
       
   388 	case 'g':
       
   389 	    use_old_dwarf_loclist = TRUE;
       
   390 	    /* FALL THROUGH. */
       
   391 	case 'i':
       
   392 	    info_flag = TRUE;
       
   393 	    break;
       
   394 	case 'l':
       
   395 	    line_flag = TRUE;
       
   396 	    break;
       
   397 	case 'f':
       
   398 	    frame_flag = TRUE;
       
   399 	    break;
       
   400 	case 'F':
       
   401 	    eh_frame_flag = TRUE;
       
   402 	    break;
       
   403 	case 'b':
       
   404 	    abbrev_flag = TRUE;
       
   405 	    break;
       
   406 	case 'p':
       
   407 	    pubnames_flag = TRUE;
       
   408 	    break;
       
   409 	case 'r':
       
   410 	    aranges_flag = TRUE;
       
   411 	    break;
       
   412 	case 'R':
       
   413 	    generic_1000_regs = TRUE;
       
   414 	    info_flag = TRUE;
       
   415 	    break;
       
   416 	case 'm':
       
   417 	    macinfo_flag = TRUE;
       
   418 	    break;
       
   419 	case 'c':
       
   420 	    loc_flag = TRUE;
       
   421 	    break;
       
   422 	case 's':
       
   423 	    string_flag = TRUE;
       
   424 	    break;
       
   425 	case 'a':
       
   426 	    do_all();
       
   427 	    break;
       
   428 	case 'v':
       
   429 	    verbose++;
       
   430 	    break;
       
   431 	case 'V':
       
   432 	    {
       
   433 	    printf("%s\n","Version 4May2007");
       
   434 	    }
       
   435 	    break;
       
   436 	case 'd':
       
   437 	    dense = TRUE;
       
   438 	    break;
       
   439 	case 'e':
       
   440 	    ellipsis = TRUE;
       
   441 	    break;
       
   442 	case 'o':
       
   443 	    reloc_flag = TRUE;
       
   444 	    break;
       
   445 	case 'k':
       
   446 	    dwarf_check = TRUE;
       
   447 	    oarg = optarg[0];
       
   448 	    switch (oarg) {
       
   449 	    case 'a':
       
   450 		check_pubname_attr = TRUE;
       
   451 		check_attr_tag = TRUE;
       
   452 		check_tag_tree = check_type_offset = TRUE;
       
   453 		pubnames_flag = info_flag = TRUE;
       
   454 		break;
       
   455 	    case 'e':
       
   456 		check_pubname_attr = TRUE;
       
   457 		pubnames_flag = TRUE;
       
   458 		break;
       
   459 	    case 'r':
       
   460 		check_attr_tag = TRUE;
       
   461 		info_flag = TRUE;
       
   462 		break;
       
   463 	    case 't':
       
   464 		check_tag_tree = TRUE;
       
   465 		info_flag = TRUE;
       
   466 		break;
       
   467 	    case 'y':
       
   468 		check_type_offset = TRUE;
       
   469 		info_flag = TRUE;
       
   470 		break;
       
   471 	    default:
       
   472 		usage_error = TRUE;
       
   473 		break;
       
   474 	    }
       
   475 	    break;
       
   476 	case 'u':		/* compile unit */
       
   477 	    cu_name_flag = TRUE;
       
   478 	    strcpy(cu_name, optarg);
       
   479 	    break;
       
   480 	case 't':
       
   481 	    oarg = optarg[0];
       
   482 	    switch (oarg) {
       
   483 	    case 'a':
       
   484 		/* all */
       
   485 		static_func_flag = static_var_flag = TRUE;
       
   486 		break;
       
   487 	    case 'f':
       
   488 		/* .debug_static_func */
       
   489 		static_func_flag = TRUE;
       
   490 		break;
       
   491 	    case 'v':
       
   492 		/* .debug_static_var */
       
   493 		static_var_flag = TRUE;
       
   494 		break;
       
   495 	    default:
       
   496 		usage_error = TRUE;
       
   497 		break;
       
   498 	    }
       
   499 	    break;
       
   500 	case 'y':		/* .debug_types */
       
   501 	    type_flag = TRUE;
       
   502 	    break;
       
   503 	case 'w':		/* .debug_weaknames */
       
   504 	    weakname_flag = TRUE;
       
   505 	    break;
       
   506 	case 'z':
       
   507 	    fprintf(stderr, "-z is no longer supported:ignored\n");
       
   508 	    break;
       
   509 	case 'G':
       
   510 	    show_global_offsets = TRUE;
       
   511 	    break;
       
   512 	default:
       
   513 	    usage_error = TRUE;
       
   514 	    break;
       
   515 	}
       
   516     }
       
   517 
       
   518     init_conf_file_data(&config_file_data);
       
   519     if (config_file_abi && generic_1000_regs) {
       
   520         printf("Specifying both -R and -x abi= is not allowed. Use one "
       
   521               "or the other.  -x abi= ignored.\n");
       
   522         config_file_abi = FALSE;
       
   523     }
       
   524     if(generic_1000_regs) {
       
   525         init_generic_config_1000_regs(&config_file_data);
       
   526     }
       
   527     if (config_file_abi && (frame_flag || eh_frame_flag)) {
       
   528 	int res = find_conf_file_and_read_config(config_file_path,
       
   529 						 config_file_abi,
       
   530 						 config_file_defaults,
       
   531 						 &config_file_data);
       
   532 
       
   533 	if (res > 0) {
       
   534 	    printf
       
   535 		("Frame not configured due to error(s). Giving up.\n");
       
   536 	    eh_frame_flag = FALSE;
       
   537 	    frame_flag = FALSE;
       
   538 	}
       
   539     }
       
   540     if (usage_error || (optind != (argc - 1))) {
       
   541 	print_usage_message();
       
   542 	exit(FAILED);
       
   543     }
       
   544     return argv[optind];
       
   545 }
       
   546 
       
   547 static void
       
   548 print_usage_message(void)
       
   549 {
       
   550     fprintf(stderr, "Usage:  %s <options> <object file>\n",
       
   551 	    program_name);
       
   552     fprintf(stderr, "options:\t-a\tprint all .debug_* sections\n");
       
   553     fprintf(stderr, "\t\t-b\tprint abbrev section\n");
       
   554     fprintf(stderr, "\t\t-c\tprint loc section\n");
       
   555     fprintf(stderr,
       
   556 	    "\t\t-d\tdense: one line per entry (info section only)\n");
       
   557     fprintf(stderr,
       
   558 	    "\t\t-e\tellipsis: short names for tags, attrs etc.\n");
       
   559     fprintf(stderr, "\t\t-f\tprint dwarf frame section\n");
       
   560     fprintf(stderr, "\t\t-F\tprint gnu .eh_frame section\n");
       
   561     fprintf(stderr, "\t\t-g\t(use incomplete loclist support)\n");
       
   562     fprintf(stderr, "\t\t-G\tshow global die offsets\n");
       
   563     fprintf(stderr, "\t\t-h\tprint exception tables\n");
       
   564     fprintf(stderr, "\t\t-i\tprint info section\n");
       
   565     fprintf(stderr, "\t\t-k[aerty] check dwarf information\n");
       
   566     fprintf(stderr, "\t\t   a\tdo all checks\n");
       
   567     fprintf(stderr, "\t\t   e\texamine attributes of pubnames\n");
       
   568     fprintf(stderr, "\t\t   r\texamine attr-tag relation\n");
       
   569     fprintf(stderr, "\t\t   t\texamine tag trees\n");
       
   570     fprintf(stderr, "\t\t   y\texamine type info\n");
       
   571     fprintf(stderr, "\t\t-l\tprint line section\n");
       
   572     fprintf(stderr, "\t\t-m\tprint macinfo section\n");
       
   573     fprintf(stderr, "\t\t-o\tprint relocation info\n");
       
   574     fprintf(stderr, "\t\t-p\tprint pubnames section\n");
       
   575     fprintf(stderr, "\t\t-r\tprint aranges section\n");
       
   576     fprintf(stderr, "\t\t-R\tPrint frame register names as r33 etc\n");
       
   577     fprintf(stderr, "\t\t  \t    and allow up to 1000 registers.\n");
       
   578     fprintf(stderr, "\t\t  \t    Print using a 'generic' register set.\n");
       
   579     fprintf(stderr, "\t\t-s\tprint string section\n");
       
   580     fprintf(stderr, "\t\t-t[afv] static: \n");
       
   581     fprintf(stderr, "\t\t   a\tprint both sections\n");
       
   582     fprintf(stderr, "\t\t   f\tprint static func section\n");
       
   583     fprintf(stderr, "\t\t   v\tprint static var section\n");
       
   584     fprintf(stderr,
       
   585 	    "\t\t-u<file> print sections only for specified file\n");
       
   586     fprintf(stderr, "\t\t-v\tverbose: show more information\n");
       
   587     fprintf(stderr, "\t\t-vv verbose: show even more information\n");
       
   588     fprintf(stderr, "\t\t-V print version information\n");	
       
   589     fprintf(stderr, "\t\t-x name=<path>\tname dwarfdump.conf\n");
       
   590     fprintf(stderr, "\t\t-x abi=<abi>\tname abi in dwarfdump.conf\n");
       
   591     fprintf(stderr, "\t\t-w\tprint weakname section\n");
       
   592     fprintf(stderr, "\t\t-y\tprint type section\n");
       
   593 
       
   594 }
       
   595 
       
   596 /* process each compilation unit in .debug_info */
       
   597 static void
       
   598 print_infos(Dwarf_Debug dbg)
       
   599 {
       
   600     Dwarf_Unsigned cu_header_length = 0;
       
   601     Dwarf_Unsigned abbrev_offset = 0;
       
   602     Dwarf_Half version_stamp = 0;
       
   603     Dwarf_Half address_size = 0;
       
   604     Dwarf_Die cu_die = 0;
       
   605     Dwarf_Unsigned next_cu_offset = 0;
       
   606     int nres = DW_DLV_OK;
       
   607 
       
   608     if (info_flag)
       
   609 	printf("\n.debug_info\n");
       
   610 
       
   611     /* Loop until it fails.  */
       
   612     while ((nres =
       
   613 	    dwarf_next_cu_header(dbg, &cu_header_length, &version_stamp,
       
   614 				 &abbrev_offset, &address_size,
       
   615 				 &next_cu_offset, &err))
       
   616 	   == DW_DLV_OK) {
       
   617 	int sres;
       
   618 
       
   619 	if (cu_name_flag) {
       
   620 	    int tres;
       
   621 	    Dwarf_Half tag;
       
   622 	    Dwarf_Attribute attrib;
       
   623 	    Dwarf_Half theform;
       
   624 	    int fres;
       
   625 	    int ares;
       
   626 
       
   627 	    sres = dwarf_siblingof(dbg, NULL, &cu_die, &err);
       
   628 	    if (sres != DW_DLV_OK) {
       
   629 		print_error(dbg, "siblingof cu header", sres, err);
       
   630 	    }
       
   631 	    tres = dwarf_tag(cu_die, &tag, &err);
       
   632 	    if (tres != DW_DLV_OK) {
       
   633 		print_error(dbg, "tag of cu die", tres, err);
       
   634 	    }
       
   635 	    ares = dwarf_attr(cu_die, DW_AT_name, &attrib, &err);
       
   636 	    if (ares != DW_DLV_OK) {
       
   637 		print_error(dbg, "dwarf DW_AT_name ", ares, err);
       
   638 	    }
       
   639 	    fres = dwarf_whatform(attrib, &theform, &err);
       
   640 	    if (fres != DW_DLV_OK) {
       
   641 		print_error(dbg, "dwarf_whatform problem ", fres, err);
       
   642 	    } else if (theform == DW_FORM_string
       
   643 		       || theform == DW_FORM_strp) {
       
   644 		string temps;
       
   645 		int strres;
       
   646 		string p;
       
   647 
       
   648 		strres = dwarf_formstring(attrib, &temps, &err);
       
   649 		p = temps;
       
   650 		if (strres != DW_DLV_OK) {
       
   651 		    print_error(dbg,
       
   652 				"formstring failed unexpectedly",
       
   653 				strres, err);
       
   654 		}
       
   655 		if (cu_name[0] != '/') {
       
   656 		    p = strrchr(temps, '/');
       
   657 		    if (p == NULL) {
       
   658 			p = temps;
       
   659 		    } else {
       
   660 			p++;
       
   661 		    }
       
   662 		}
       
   663 		if (strcmp(cu_name, p)) {
       
   664 		    continue;
       
   665 		}
       
   666 	    } else {
       
   667 		print_error(dbg,
       
   668 			    "dwarf_whatform unexpected value",
       
   669 			    fres, err);
       
   670 	    }
       
   671 	    dwarf_dealloc(dbg, attrib, DW_DLA_ATTR);
       
   672 	    dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
       
   673 	}
       
   674 	if (verbose) {
       
   675 	    if (dense) {
       
   676 		printf("<%s>", "cu_header");
       
   677 		printf(" %s<%llu>", "cu_header_length",
       
   678 		       cu_header_length);
       
   679 		printf(" %s<%d>", "version_stamp", version_stamp);
       
   680 		printf(" %s<%llu>", "abbrev_offset", abbrev_offset);
       
   681 		printf(" %s<%d>\n", "address_size", address_size);
       
   682 
       
   683 	    } else {
       
   684 		printf("\nCU_HEADER:\n");
       
   685 		printf("\t\t%-28s%llu\n", "cu_header_length",
       
   686 		       cu_header_length);
       
   687 		printf("\t\t%-28s%d\n", "version_stamp", version_stamp);
       
   688 		printf("\t\t%-28s%llu\n", "abbrev_offset",
       
   689 		       abbrev_offset);
       
   690 		printf("\t\t%-28s%d", "address_size", address_size);
       
   691 	    }
       
   692 	}
       
   693 
       
   694 	/* process a single compilation unit in .debug_info. */
       
   695 	sres = dwarf_siblingof(dbg, NULL, &cu_die, &err);
       
   696 	if (sres == DW_DLV_OK) {
       
   697 	    if (info_flag || cu_name_flag) {
       
   698 		Dwarf_Signed cnt = 0;
       
   699 		char **srcfiles = 0;
       
   700 		int srcf = dwarf_srcfiles(cu_die,
       
   701 					  &srcfiles, &cnt, &err);
       
   702 
       
   703 		if (srcf != DW_DLV_OK) {
       
   704 		    srcfiles = 0;
       
   705 		    cnt = 0;
       
   706 		}
       
   707 
       
   708 		print_die_and_children(dbg, cu_die, srcfiles, cnt);
       
   709 		if (srcf == DW_DLV_OK) {
       
   710 		    int si;
       
   711 
       
   712 		    for (si = 0; si < cnt; ++si) {
       
   713 			dwarf_dealloc(dbg, srcfiles[si], DW_DLA_STRING);
       
   714 		    }
       
   715 		    dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST);
       
   716 		}
       
   717 	    }
       
   718 	    if (line_flag)
       
   719 		print_line_numbers_this_cu(dbg, cu_die);
       
   720 	    dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
       
   721 	} else if (sres == DW_DLV_NO_ENTRY) {
       
   722 	    /* do nothing I guess. */
       
   723 	} else {
       
   724 	    print_error(dbg, "Regetting cu_die", sres, err);
       
   725 	}
       
   726 	cu_offset = next_cu_offset;
       
   727     }
       
   728     if (nres == DW_DLV_ERROR) {
       
   729 	string errmsg = dwarf_errmsg(err);
       
   730 	Dwarf_Unsigned myerr = dwarf_errno(err);
       
   731 
       
   732 	fprintf(stderr, "%s ERROR:  %s:  %s (%lu)\n",
       
   733 		program_name, "attempting to print .debug_info",
       
   734 		errmsg, (unsigned long) myerr);
       
   735 	fprintf(stderr, "attempting to continue.\n");
       
   736     }
       
   737 }
       
   738 
       
   739 /* ARGSUSED */
       
   740 void
       
   741 print_error(Dwarf_Debug dbg, string msg, int dwarf_code,
       
   742 	    Dwarf_Error err)
       
   743 {
       
   744     fflush(stdout);
       
   745     fflush(stderr);
       
   746     if (dwarf_code == DW_DLV_ERROR) {
       
   747 	string errmsg = dwarf_errmsg(err);
       
   748 	Dwarf_Unsigned myerr = dwarf_errno(err);
       
   749 
       
   750 	fprintf(stderr, "%s ERROR:  %s:  %s (%lu)\n",
       
   751 		program_name, msg, errmsg, (unsigned long) myerr);
       
   752     } else if (dwarf_code == DW_DLV_NO_ENTRY) {
       
   753 	fprintf(stderr, "%s NO ENTRY:  %s: \n", program_name, msg);
       
   754     } else if (dwarf_code == DW_DLV_OK) {
       
   755 	fprintf(stderr, "%s:  %s \n", program_name, msg);
       
   756     } else {
       
   757 	fprintf(stderr, "%s InternalError:  %s:  code %d\n",
       
   758 		program_name, msg, dwarf_code);
       
   759     }
       
   760     fflush(stderr);
       
   761     exit(FAILED);
       
   762 
       
   763 }