tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_die.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /* 
       
     2   Copyright (C) 2000,2004,2005,2006 Silicon Graphics, Inc.  All Rights Reserved.
       
     3   Portions Copyright 2007 Sun Microsystems, Inc. All rights reserved.
       
     4   Portions Copyright 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 of the GNU General Public License as
       
     8   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 General Public License along
       
    22   with this program; if not, write the Free Software Foundation, Inc., 51
       
    23   Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
       
    24 
       
    25   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
       
    26   Mountain View, CA 94043, or:
       
    27 
       
    28   http://www.sgi.com
       
    29 
       
    30   For further information regarding this notice, see:
       
    31 
       
    32   http://oss.sgi.com/projects/GenInfo/NoticeExplan
       
    33 
       
    34 
       
    35 $ Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_die.c,v 1.51 2006/04/01 16:20:21 davea Exp $ */
       
    36 
       
    37 #include "globals.h"
       
    38 #include "dwarf_names.h"
       
    39 #include "esb.h"		/* For flexible string buffer. */
       
    40 #include "makename.h"		/* Non-duplicating string table. */
       
    41 
       
    42 static void get_attr_value(Dwarf_Debug dbg, Dwarf_Half tag,
       
    43 			   Dwarf_Attribute attrib, 
       
    44                            char **srcfiles,
       
    45 			   Dwarf_Signed cnt, struct esb_s *esbp);
       
    46 static void print_attribute(Dwarf_Debug dbg, Dwarf_Die die,
       
    47 			    Dwarf_Half attr,
       
    48 			    Dwarf_Attribute actual_addr,
       
    49 			    boolean print_information, char **srcfiles,
       
    50 			    Dwarf_Signed cnt);
       
    51 static void get_location_list(Dwarf_Debug dbg, Dwarf_Die die,
       
    52 			      Dwarf_Attribute attr, struct esb_s *esbp);
       
    53 static int tag_attr_combination(Dwarf_Half tag, Dwarf_Half attr);
       
    54 static int _dwarf_print_one_expr_op(Dwarf_Debug dbg,Dwarf_Loc* expr,int index, struct esb_s *string_out);
       
    55 
       
    56 /* esb_base is static so gets initialized to zeros.  
       
    57    It is not thread-safe or
       
    58    safe for multiple open producer instances for
       
    59    but that does not matter here in dwarfdump.
       
    60 
       
    61    The memory used by esb_base is never freed.
       
    62 */
       
    63 static struct esb_s esb_base;	
       
    64 
       
    65 static int indent_level = 0;
       
    66 static boolean local_symbols_already_began = FALSE;
       
    67 
       
    68 typedef string(*encoding_type_func) (Dwarf_Debug dbg, Dwarf_Half val);
       
    69 
       
    70 Dwarf_Off fde_offset_for_cu_low = DW_DLV_BADOFFSET;
       
    71 Dwarf_Off fde_offset_for_cu_high = DW_DLV_BADOFFSET;
       
    72 
       
    73 /* Dwarf_Half list_of_attrs[] */
       
    74 /*#include "at_list.i" unreferenced */
       
    75 
       
    76 #define DIE_STACK_SIZE 300
       
    77 static Dwarf_Die die_stack[DIE_STACK_SIZE];
       
    78 
       
    79 #define PUSH_DIE_STACK(x) { die_stack[indent_level] = x; }
       
    80 #define POP_DIE_STACK { die_stack[indent_level] = 0; }
       
    81 
       
    82 #include "_tag_tree_table.c"
       
    83 
       
    84 /*
       
    85    Look only at valid table entries
       
    86    The check here must match the building-logic in
       
    87    tag_tree.c
       
    88    And must match the tags defined in dwarf.h
       
    89 */
       
    90 #define MAX_CHECKED_TAG_ID 0x35
       
    91 static int
       
    92 tag_tree_combination(Dwarf_Half tag_parent, Dwarf_Half tag_child)
       
    93 {
       
    94     if (tag_parent > 0 && tag_parent <= MAX_CHECKED_TAG_ID
       
    95 	&& tag_child > 0 && tag_child <= MAX_CHECKED_TAG_ID) {
       
    96 	return ((tag_tree_combination_table[tag_parent]
       
    97 		 [tag_child / 0x20]
       
    98 		 & (1 << (tag_child % 0x20))) > 0 ? TRUE : FALSE);
       
    99     } else
       
   100 	return (FALSE);
       
   101 }
       
   102 
       
   103 /* recursively follow the die tree */
       
   104 extern void
       
   105 print_die_and_children(Dwarf_Debug dbg, Dwarf_Die in_die_in,
       
   106 		       char **srcfiles, Dwarf_Signed cnt)
       
   107 {
       
   108     Dwarf_Die child;
       
   109     Dwarf_Die sibling;
       
   110     Dwarf_Error err;
       
   111     int tres;
       
   112     int cdres;
       
   113     Dwarf_Die in_die = in_die_in;
       
   114 
       
   115     for (;;) {
       
   116 	PUSH_DIE_STACK(in_die);
       
   117 
       
   118 	if (check_tag_tree) {
       
   119 	    tag_tree_result.checks++;
       
   120 	    if (indent_level == 0) {
       
   121 		Dwarf_Half tag;
       
   122 
       
   123 		tres = dwarf_tag(in_die, &tag, &err);
       
   124 		if (tres != DW_DLV_OK) {
       
   125 		    tag_tree_result.errors++;
       
   126 		    DWARF_CHECK_ERROR
       
   127 			("Tag-tree root is not DW_TAG_compile_unit")
       
   128 		} else if (tag == DW_TAG_compile_unit) {
       
   129 		    /* OK */
       
   130 		} else {
       
   131 		    tag_tree_result.errors++;
       
   132 		    DWARF_CHECK_ERROR
       
   133 			("tag-tree root is not DW_TAG_compile_unit")
       
   134 		}
       
   135 	    } else {
       
   136 		Dwarf_Half tag_parent, tag_child;
       
   137 		int pres;
       
   138 		int cres;
       
   139 		char *ctagname = "<child tag invalid>";
       
   140 		char *ptagname = "<parent tag invalid>";
       
   141 
       
   142 		pres =
       
   143 		    dwarf_tag(die_stack[indent_level - 1], &tag_parent,
       
   144 			      &err);
       
   145 		cres = dwarf_tag(in_die, &tag_child, &err);
       
   146 		if (pres != DW_DLV_OK)
       
   147 		    tag_parent = 0;
       
   148 		if (cres != DW_DLV_OK)
       
   149 		    tag_child = 0;
       
   150 		if (cres != DW_DLV_OK || pres != DW_DLV_OK) {
       
   151 		    if (cres == DW_DLV_OK) {
       
   152 			ctagname = get_TAG_name(dbg, tag_child);
       
   153 		    }
       
   154 		    if (pres == DW_DLV_OK) {
       
   155 			ptagname = get_TAG_name(dbg, tag_parent);
       
   156 		    }
       
   157 		    DWARF_CHECK_ERROR3(ptagname,
       
   158 				       ctagname,
       
   159 				       "Tag-tree relation is not standard..");
       
   160 		} else if (tag_tree_combination(tag_parent, tag_child)) {
       
   161 		    /* OK */
       
   162 		} else {
       
   163 		    DWARF_CHECK_ERROR3(get_TAG_name(dbg, tag_parent),
       
   164 				       get_TAG_name(dbg, tag_child),
       
   165 				       "tag-tree relation is not standard.");
       
   166 		}
       
   167 	    }
       
   168 	}
       
   169 
       
   170 	/* here to pre-descent processing of the die */
       
   171 	print_one_die(dbg, in_die, info_flag, srcfiles, cnt);
       
   172 
       
   173 	cdres = dwarf_child(in_die, &child, &err);
       
   174 	/* child first: we are doing depth-first walk */
       
   175 	if (cdres == DW_DLV_OK) {
       
   176 	    indent_level++;
       
   177 	    if(indent_level >= DIE_STACK_SIZE ) {
       
   178 	        print_error(dbg,
       
   179                   "compiled in DIE_STACK_SIZE limit exceeded",
       
   180                   DW_DLV_OK,err);
       
   181 	    }
       
   182 	    print_die_and_children(dbg, child, srcfiles, cnt);
       
   183 	    indent_level--;
       
   184 	    if (indent_level == 0)
       
   185 		local_symbols_already_began = FALSE;
       
   186 	    dwarf_dealloc(dbg, child, DW_DLA_DIE);
       
   187 	} else if (cdres == DW_DLV_ERROR) {
       
   188 	    print_error(dbg, "dwarf_child", cdres, err);
       
   189 	}
       
   190 
       
   191 	cdres = dwarf_siblingof(dbg, in_die, &sibling, &err);
       
   192 	if (cdres == DW_DLV_OK) {
       
   193 	    /* print_die_and_children(dbg, sibling, srcfiles, cnt); We
       
   194 	       loop around to actually print this, rather than
       
   195 	       recursing. Recursing is horribly wasteful of stack
       
   196 	       space. */
       
   197 	} else if (cdres == DW_DLV_ERROR) {
       
   198 	    print_error(dbg, "dwarf_siblingof", cdres, err);
       
   199 	}
       
   200 
       
   201 	/* Here do any post-descent (ie post-dwarf_child) processing of 
       
   202 	   the in_die. */
       
   203 
       
   204 	POP_DIE_STACK;
       
   205 	if (in_die != in_die_in) {
       
   206 	    /* Dealloc our in_die, but not the argument die, it belongs 
       
   207 	       to our caller. Whether the siblingof call worked or not. 
       
   208 	     */
       
   209 	    dwarf_dealloc(dbg, in_die, DW_DLA_DIE);
       
   210 	}
       
   211 	if (cdres == DW_DLV_OK) {
       
   212 	    /* Set to process the sibling, loop again. */
       
   213 	    in_die = sibling;
       
   214 	} else {
       
   215 	    /* We are done, no more siblings at this level. */
       
   216 
       
   217 	    break;
       
   218 	}
       
   219     }				/* end for loop on siblings */
       
   220     return;
       
   221 }
       
   222 
       
   223 #define SPACE(x) { register int i; for (i=0;i<x;i++) putchar(' '); }
       
   224 
       
   225 
       
   226 /* print info about die */
       
   227 void
       
   228 print_one_die(Dwarf_Debug dbg, Dwarf_Die die, boolean print_information,
       
   229 	      char **srcfiles, Dwarf_Signed cnt)
       
   230 {
       
   231     Dwarf_Signed i;
       
   232     Dwarf_Off offset, overall_offset;
       
   233     string tagname;
       
   234     Dwarf_Half tag;
       
   235     Dwarf_Signed atcnt;
       
   236     Dwarf_Attribute *atlist;
       
   237     int tres;
       
   238     int ores;
       
   239     int atres;
       
   240 
       
   241     tres = dwarf_tag(die, &tag, &err);
       
   242     if (tres != DW_DLV_OK) {
       
   243 	print_error(dbg, "accessing tag of die!", tres, err);
       
   244     }
       
   245     tagname = get_TAG_name(dbg, tag);
       
   246     ores = dwarf_dieoffset(die, &overall_offset, &err);
       
   247     if (ores != DW_DLV_OK) {
       
   248 	print_error(dbg, "dwarf_dieoffset", ores, err);
       
   249     }
       
   250     ores = dwarf_die_CU_offset(die, &offset, &err);
       
   251     if (ores != DW_DLV_OK) {
       
   252 	print_error(dbg, "dwarf_die_CU_offset", ores, err);
       
   253     }
       
   254 
       
   255     if (!dst_format && print_information) {
       
   256 	if (indent_level == 0) {
       
   257 	    if (dense)
       
   258 		printf("\n");
       
   259 	    else {
       
   260 		printf
       
   261 		    ("\nCOMPILE_UNIT<header overall offset = %llu>:\n",
       
   262 		     overall_offset - offset);
       
   263 	    }
       
   264 	} else if (local_symbols_already_began == FALSE &&
       
   265 		   indent_level == 1 && !dense) {
       
   266 	    printf("\nLOCAL_SYMBOLS:\n");
       
   267 	    local_symbols_already_began = TRUE;
       
   268 	}
       
   269 	if (dense) {
       
   270             if (show_global_offsets) {
       
   271 	        if (indent_level == 0) {
       
   272 		    printf("<%d><%llu+%llu GOFF=%llu><%s>", indent_level,
       
   273 		       overall_offset - offset, offset,
       
   274                        overall_offset, tagname);
       
   275 	        } else {
       
   276 		    printf("<%d><%llu GOFF=%llu><%s>", indent_level, 
       
   277                        offset, overall_offset, tagname);
       
   278 	        }
       
   279             } else {
       
   280 	        if (indent_level == 0) {
       
   281 		    printf("<%d><%llu+%llu><%s>", indent_level,
       
   282 		       overall_offset - offset, offset, tagname);
       
   283 	        } else {
       
   284 		    printf("<%d><%llu><%s>", indent_level, offset, tagname);
       
   285 	        }
       
   286 	    }
       
   287 	} else {
       
   288             if (show_global_offsets) {
       
   289 	        printf("<%d><%5llu GOFF=%llu>\t%s\n", indent_level, offset,
       
   290                     overall_offset, tagname);
       
   291             } else {
       
   292 	        printf("<%d><%5llu>\t%s\n", indent_level, offset, tagname);
       
   293 	    }
       
   294 	}
       
   295     }
       
   296 
       
   297     atres = dwarf_attrlist(die, &atlist, &atcnt, &err);
       
   298     if (atres == DW_DLV_ERROR) {
       
   299 	print_error(dbg, "dwarf_attrlist", atres, err);
       
   300     } else if (atres == DW_DLV_NO_ENTRY) {
       
   301 	/* indicates there are no attrs.  It is not an error. */
       
   302 	atcnt = 0;
       
   303     }
       
   304 
       
   305 
       
   306     for (i = 0; i < atcnt; i++) {
       
   307 	Dwarf_Half attr;
       
   308 	int ares;
       
   309 
       
   310 	ares = dwarf_whatattr(atlist[i], &attr, &err);
       
   311 	if (ares == DW_DLV_OK) {
       
   312 	    print_attribute(dbg, die, attr,
       
   313 			    atlist[i],
       
   314 			    print_information, srcfiles, cnt);
       
   315 	} else {
       
   316 	    print_error(dbg, "dwarf_whatattr entry missing", ares, err);
       
   317 	}
       
   318     }
       
   319 
       
   320     for (i = 0; i < atcnt; i++) {
       
   321 	dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);
       
   322     }
       
   323     if (atres == DW_DLV_OK) {
       
   324 	dwarf_dealloc(dbg, atlist, DW_DLA_LIST);
       
   325     }
       
   326 
       
   327     if (dense && print_information) {
       
   328 	printf("\n\n");
       
   329     }
       
   330     return;
       
   331 }
       
   332 
       
   333 /* Encodings have undefined signedness. Accept either
       
   334    signedness.  The values are small (they are defined
       
   335    in the DWARF specification), so the
       
   336    form the compiler uses (as long as it is
       
   337    a constant value) is a non-issue.
       
   338 
       
   339    If string_out is non-NULL, construct a string output, either
       
   340    an error message or the name of the encoding.
       
   341    The function pointer passed in is to code generated
       
   342    by a script at dwarfdump build time. The code for
       
   343    the val_as_string function is generated
       
   344    from dwarf.h.  See <build dir>/dwarf_names.c
       
   345 
       
   346    If string_out is non-NULL then attr_name and val_as_string
       
   347    must also be non-NULL.
       
   348 
       
   349 */
       
   350 int
       
   351 get_small_encoding_integer_and_name(Dwarf_Debug dbg,
       
   352 				    Dwarf_Attribute attrib,
       
   353 				    Dwarf_Unsigned * uval_out,
       
   354 				    char *attr_name,
       
   355 				    string * string_out,
       
   356 				    encoding_type_func val_as_string,
       
   357 				    Dwarf_Error * err)
       
   358 {
       
   359     Dwarf_Unsigned uval = 0;
       
   360     char buf[100];		/* The strings are small. */
       
   361     int vres = dwarf_formudata(attrib, &uval, err);
       
   362 
       
   363     if (vres != DW_DLV_OK) {
       
   364 	Dwarf_Signed sval = 0;
       
   365 
       
   366 	vres = dwarf_formsdata(attrib, &sval, err);
       
   367 	if (vres != DW_DLV_OK) {
       
   368 	    if (string_out != 0) {
       
   369 		snprintf(buf, sizeof(buf),
       
   370 			 "%s has a bad form.", attr_name);
       
   371 		*string_out = makename(buf);
       
   372 	    }
       
   373 	    return vres;
       
   374 	}
       
   375 	*uval_out = (Dwarf_Unsigned) sval;
       
   376     } else {
       
   377 	*uval_out = uval;
       
   378     }
       
   379     if (string_out)
       
   380 	*string_out = val_as_string(dbg, (Dwarf_Half) uval);
       
   381 
       
   382     return DW_DLV_OK;
       
   383 
       
   384 }
       
   385 
       
   386 
       
   387 
       
   388 
       
   389 /*
       
   390  * We need a 32-bit signed number here, but there's no portable
       
   391  * way of getting that.  So use __uint32_t instead.  It's supplied
       
   392  * in a reliable way by the autoconf infrastructure.
       
   393  */
       
   394 
       
   395 static void
       
   396 get_FLAG_BLOCK_string(Dwarf_Debug dbg, Dwarf_Attribute attrib)
       
   397 {
       
   398     int fres = 0;
       
   399     Dwarf_Block *tempb = 0;
       
   400     __uint32_t * array = 0;
       
   401     Dwarf_Unsigned array_len = 0;
       
   402     __uint32_t * array_ptr;
       
   403     Dwarf_Unsigned array_remain = 0;
       
   404     char linebuf[100];
       
   405 
       
   406     esb_empty_string(&esb_base);
       
   407     esb_append(&esb_base, "\n");
       
   408 
       
   409     /* first get compressed block data */
       
   410     fres = dwarf_formblock (attrib,&tempb, &err);
       
   411     if (fres != DW_DLV_OK) {
       
   412 	print_error(dbg,"DW_FORM_blockn cannot get block\n",fres,err);
       
   413 	return;
       
   414     }
       
   415 
       
   416     /* uncompress block into int array */
       
   417     array = dwarf_uncompress_integer_block(dbg,
       
   418 			   1, /* 'true' (meaning signed ints)*/
       
   419 			   32, /* bits per unit */
       
   420 			   tempb->bl_data,
       
   421 			   tempb->bl_len,
       
   422 			   &array_len, /* len of out array */
       
   423 			   &err);
       
   424     if (array == (void*) DW_DLV_BADOFFSET) {
       
   425 	print_error(dbg,"DW_AT_SUN_func_offsets cannot uncompress data\n",0,err);
       
   426 	return;
       
   427     }
       
   428     if (array_len == 0) {
       
   429 	print_error(dbg,"DW_AT_SUN_func_offsets has no data\n",0,err);
       
   430 	return;
       
   431     }
       
   432     
       
   433     /* fill in string buffer */
       
   434     array_remain = array_len;
       
   435     array_ptr = array;
       
   436     while (array_remain > 8) {
       
   437 	/* print a full line */
       
   438 	/* if you touch this string, update the magic number 78 below! */
       
   439 	snprintf(linebuf, sizeof(linebuf), 
       
   440 		"\n  %8x %8x %8x %8x %8x %8x %8x %8x",
       
   441 		array_ptr[0],		array_ptr[1],
       
   442 		array_ptr[2],		array_ptr[3],
       
   443 		array_ptr[4],		array_ptr[5],
       
   444 		array_ptr[6],		array_ptr[7]);
       
   445 	array_ptr += 8;
       
   446 	array_remain -= 8;
       
   447 	esb_append(&esb_base, linebuf);
       
   448     }
       
   449 
       
   450     /* now do the last line */
       
   451     if (array_remain > 0) {
       
   452 	esb_append(&esb_base, "\n ");
       
   453 	while (array_remain > 0) {
       
   454 	    snprintf(linebuf, sizeof(linebuf), " %8x", *array_ptr);
       
   455 	    array_remain--;
       
   456 	    array_ptr++;
       
   457 	    esb_append(&esb_base, linebuf);
       
   458 	}
       
   459     }
       
   460     
       
   461     /* free array buffer */
       
   462     dwarf_dealloc_uncompressed_block(dbg, array);
       
   463 
       
   464 }
       
   465 
       
   466 static void
       
   467 print_attribute(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attr,
       
   468 		Dwarf_Attribute attr_in,
       
   469 		boolean print_information,
       
   470 		char **srcfiles, Dwarf_Signed cnt)
       
   471 {
       
   472     Dwarf_Attribute attrib = 0;
       
   473     Dwarf_Unsigned uval = 0;
       
   474     string atname = 0;
       
   475     string valname = 0;
       
   476     int tres = 0;
       
   477     Dwarf_Half tag = 0;
       
   478 
       
   479     atname = get_AT_name(dbg, attr);
       
   480 
       
   481     /* the following gets the real attribute, even in the face of an 
       
   482        incorrect doubling, or worse, of attributes */
       
   483     attrib = attr_in;
       
   484     /* do not get attr via dwarf_attr: if there are (erroneously) 
       
   485        multiple of an attr in a DIE, dwarf_attr will not get the
       
   486        second, erroneous one and dwarfdump will print the first one
       
   487        multiple times. Oops. */
       
   488 
       
   489     tres = dwarf_tag(die, &tag, &err);
       
   490     if (tres == DW_DLV_ERROR) {
       
   491 	tag = 0;
       
   492     } else if (tres == DW_DLV_NO_ENTRY) {
       
   493 	tag = 0;
       
   494     } else {
       
   495 	/* ok */
       
   496     }
       
   497     if (check_attr_tag) {
       
   498 	char *tagname = "<tag invalid>";
       
   499 
       
   500 	attr_tag_result.checks++;
       
   501 	if (tres == DW_DLV_ERROR) {
       
   502 	    attr_tag_result.errors++;
       
   503 	    DWARF_CHECK_ERROR3(tagname,
       
   504 			       get_AT_name(dbg, attr),
       
   505 			       "check the tag-attr combination.");
       
   506 	} else if (tres == DW_DLV_NO_ENTRY) {
       
   507 	    attr_tag_result.errors++;
       
   508 	    DWARF_CHECK_ERROR3(tagname,
       
   509 			       get_AT_name(dbg, attr),
       
   510 			       "check the tag-attr combination..")
       
   511 	} else if (tag_attr_combination(tag, attr)) {
       
   512 	    /* OK */
       
   513 	} else {
       
   514 	    attr_tag_result.errors++;
       
   515 	    tagname = get_TAG_name(dbg, tag);
       
   516 	    DWARF_CHECK_ERROR3(tagname,
       
   517 			       get_AT_name(dbg, attr),
       
   518 			       "check the tag-attr combination")
       
   519 	}
       
   520     }
       
   521 
       
   522     switch (attr) {
       
   523     case DW_AT_language:
       
   524 	get_small_encoding_integer_and_name(dbg, attrib, &uval,
       
   525 					    "DW_AT_language", &valname,
       
   526 					    get_LANG_name, &err);
       
   527 	break;
       
   528     case DW_AT_accessibility:
       
   529 	get_small_encoding_integer_and_name(dbg, attrib, &uval,
       
   530 					    "DW_AT_accessibility",
       
   531 					    &valname, get_ACCESS_name,
       
   532 					    &err);
       
   533 	break;
       
   534     case DW_AT_visibility:
       
   535 	get_small_encoding_integer_and_name(dbg, attrib, &uval,
       
   536 					    "DW_AT_visibility",
       
   537 					    &valname, get_VIS_name,
       
   538 					    &err);
       
   539 	break;
       
   540     case DW_AT_virtuality:
       
   541 	get_small_encoding_integer_and_name(dbg, attrib, &uval,
       
   542 					    "DW_AT_virtuality",
       
   543 					    &valname,
       
   544 					    get_VIRTUALITY_name, &err);
       
   545 	break;
       
   546     case DW_AT_identifier_case:
       
   547 	get_small_encoding_integer_and_name(dbg, attrib, &uval,
       
   548 					    "DW_AT_identifier",
       
   549 					    &valname, get_ID_name,
       
   550 					    &err);
       
   551 	break;
       
   552     case DW_AT_inline:
       
   553 	get_small_encoding_integer_and_name(dbg, attrib, &uval,
       
   554 					    "DW_AT_inline", &valname,
       
   555 					    get_INL_name, &err);
       
   556 	break;
       
   557     case DW_AT_encoding:
       
   558 	get_small_encoding_integer_and_name(dbg, attrib, &uval,
       
   559 					    "DW_AT_encoding", &valname,
       
   560 					    get_ATE_name, &err);
       
   561 	break;
       
   562     case DW_AT_ordering:
       
   563 	get_small_encoding_integer_and_name(dbg, attrib, &uval,
       
   564 					    "DW_AT_ordering", &valname,
       
   565 					    get_ORD_name, &err);
       
   566 	break;
       
   567     case DW_AT_calling_convention:
       
   568 	get_small_encoding_integer_and_name(dbg, attrib, &uval,
       
   569 					    "DW_AT_calling_convention",
       
   570 					    &valname, get_CC_name,
       
   571 					    &err);
       
   572 	break;
       
   573     case DW_AT_discr_list:	/* DWARF3 */
       
   574 	get_small_encoding_integer_and_name(dbg, attrib, &uval,
       
   575 					    "DW_AT_discr_list",
       
   576 					    &valname, get_DSC_name,
       
   577 					    &err);
       
   578 	break;
       
   579     case DW_AT_location:
       
   580     case DW_AT_data_member_location:
       
   581     case DW_AT_vtable_elem_location:
       
   582     case DW_AT_string_length:
       
   583     case DW_AT_return_addr:
       
   584     case DW_AT_use_location:
       
   585     case DW_AT_static_link:
       
   586     case DW_AT_frame_base:
       
   587 	/* value is a location description or location list */
       
   588 	esb_empty_string(&esb_base);
       
   589 	get_location_list(dbg, die, attrib, &esb_base);
       
   590 	valname = esb_get_string(&esb_base);
       
   591 	break;
       
   592     case DW_AT_SUN_func_offsets:
       
   593 	get_FLAG_BLOCK_string(dbg, attrib);
       
   594 	valname = esb_get_string(&esb_base);
       
   595 	break;
       
   596     case DW_AT_SUN_cf_kind:
       
   597 	{
       
   598 	    Dwarf_Half kind;
       
   599 	    Dwarf_Unsigned tempud;
       
   600 	    Dwarf_Error err;
       
   601 	    int wres;
       
   602 	    wres = dwarf_formudata (attrib,&tempud, &err);
       
   603 	    if(wres == DW_DLV_OK) {
       
   604 		kind = tempud;
       
   605 		valname = get_ATCF_name(dbg, kind);
       
   606 	    } else if (wres == DW_DLV_NO_ENTRY) {
       
   607 		valname = "?";
       
   608 	    } else {
       
   609 		print_error(dbg,"Cannot get formudata....",wres,err);
       
   610 		valname = "??";
       
   611 	    }
       
   612 	}
       
   613 	break;
       
   614     case DW_AT_upper_bound:
       
   615 	{
       
   616 	    Dwarf_Half theform;
       
   617 	    int rv;
       
   618 	    rv = dwarf_whatform(attrib,&theform,&err);
       
   619 	    /* depending on the form and the attribute, process the form */
       
   620 	    if(rv == DW_DLV_ERROR) {
       
   621 		print_error(dbg, "dwarf_whatform cannot find attr form",
       
   622 			    rv, err);
       
   623 	    } else if (rv == DW_DLV_NO_ENTRY) {
       
   624 		break;
       
   625 	    }
       
   626 
       
   627 	    switch (theform) {
       
   628 	    case DW_FORM_block1:
       
   629 		get_location_list(dbg, die, attrib, &esb_base);
       
   630 		valname = esb_get_string(&esb_base);
       
   631 		break;
       
   632 	    default:
       
   633 		esb_empty_string(&esb_base);
       
   634 		get_attr_value(dbg, tag, attrib, srcfiles, cnt, &esb_base);
       
   635 		valname = esb_get_string(&esb_base);
       
   636 		break;
       
   637 	    }
       
   638 	    break;
       
   639 	}
       
   640     case DW_AT_high_pc:
       
   641         {
       
   642 	    Dwarf_Half theform;
       
   643 	    int rv;
       
   644 	    rv = dwarf_whatform(attrib,&theform,&err);
       
   645 	    /* depending on the form and the attribute, process the form */
       
   646 	    if(rv == DW_DLV_ERROR) {
       
   647 		print_error(dbg, "dwarf_whatform cannot find attr form",
       
   648 			    rv, err);
       
   649 	    } else if (rv == DW_DLV_NO_ENTRY) {
       
   650 		break;
       
   651 	    }
       
   652 	    esb_empty_string(&esb_base);
       
   653 	    get_attr_value(dbg, tag, attrib, srcfiles, cnt, &esb_base);
       
   654             if( theform != DW_FORM_addr) {
       
   655               /* New in DWARF4: other forms are not an address
       
   656                  but are instead offset from pc.
       
   657                  One could test for DWARF4 here before adding
       
   658                  this string, but that seems unnecessary as this
       
   659                  could not happen with DWARF3 or earlier. 
       
   660                  A normal consumer would have to add this value to
       
   661                  DW_AT_low_pc to get a grue pc. */
       
   662               esb_append(&esb_base,"<offset-from-lowpc>");
       
   663             }
       
   664 	    valname = esb_get_string(&esb_base);
       
   665         }
       
   666     default:
       
   667 	esb_empty_string(&esb_base);
       
   668 	get_attr_value(dbg, tag, attrib, srcfiles, cnt, &esb_base);
       
   669 	valname = esb_get_string(&esb_base);
       
   670 	break;
       
   671     }
       
   672     if (print_information) {
       
   673 	if (dense)
       
   674 	    printf(" %s<%s>", atname, valname);
       
   675 	else
       
   676 	    printf("\t\t%-28s%s\n", atname, valname);
       
   677     }
       
   678 }
       
   679 
       
   680 
       
   681 int
       
   682 dwarfdump_print_one_locdesc(Dwarf_Debug dbg,
       
   683 			 Dwarf_Locdesc * llbuf,
       
   684                          int skip_locdesc_header,
       
   685 			 struct esb_s *string_out)
       
   686 {
       
   687 
       
   688     Dwarf_Locdesc *locd = 0;
       
   689     Dwarf_Half no_of_ops = 0;
       
   690     int i = 0;
       
   691     char small_buf[100];
       
   692 
       
   693 
       
   694     if (!skip_locdesc_header && (verbose || llbuf->ld_from_loclist)) {
       
   695 	snprintf(small_buf, sizeof(small_buf), "<lowpc=0x%llx>",
       
   696 		 (unsigned long long) llbuf->ld_lopc);
       
   697 	esb_append(string_out, small_buf);
       
   698 
       
   699 
       
   700 	snprintf(small_buf, sizeof(small_buf), "<highpc=0x%llx>",
       
   701 		 (unsigned long long) llbuf->ld_hipc);
       
   702 	esb_append(string_out, small_buf);
       
   703 	if (verbose) {
       
   704 	    snprintf(small_buf, sizeof(small_buf),
       
   705 		     "<from %s offset 0x%llx>",
       
   706 		     llbuf->
       
   707 		     ld_from_loclist ? ".debug_loc" : ".debug_info",
       
   708 		     (unsigned long long) llbuf->ld_section_offset);
       
   709 	    esb_append(string_out, small_buf);
       
   710 
       
   711 	}
       
   712     }
       
   713 
       
   714 
       
   715     locd = llbuf;
       
   716     no_of_ops = llbuf->ld_cents;
       
   717     for (i = 0; i < no_of_ops; i++) {
       
   718         Dwarf_Loc * op = &locd->ld_s[i];
       
   719 
       
   720         int res = _dwarf_print_one_expr_op(dbg,op,i,string_out);
       
   721         if(res == DW_DLV_ERROR) {
       
   722           return res;
       
   723         }
       
   724     }
       
   725     return DW_DLV_OK;
       
   726 }
       
   727 
       
   728 int
       
   729 _dwarf_print_one_expr_op(Dwarf_Debug dbg,Dwarf_Loc* expr,int index,
       
   730 	struct esb_s *string_out)
       
   731 {
       
   732      /* local_space_needed is intended to be 'more than big enough'
       
   733        for a short group of loclist entries.  */
       
   734     char small_buf[100];
       
   735     Dwarf_Small op;
       
   736     Dwarf_Unsigned opd1;  
       
   737     Dwarf_Unsigned opd2;
       
   738     string op_name;
       
   739 
       
   740 
       
   741     if (index > 0)
       
   742         esb_append(string_out, " ");
       
   743 
       
   744     op = expr->lr_atom;
       
   745     if (op > DW_OP_nop) {
       
   746         print_error(dbg, "dwarf_op unexpected value", DW_DLV_OK,
       
   747 			err);
       
   748 	return DW_DLV_ERROR;
       
   749     }
       
   750     op_name = get_OP_name(dbg, op);
       
   751     esb_append(string_out, op_name);
       
   752 
       
   753     opd1 = expr->lr_number;
       
   754     if (op >= DW_OP_breg0 && op <= DW_OP_breg31) {
       
   755 	    snprintf(small_buf, sizeof(small_buf),
       
   756 		     "%+lld", (Dwarf_Signed) opd1);
       
   757 	    esb_append(string_out, small_buf);
       
   758     } else {
       
   759         switch (op) {
       
   760         case DW_OP_addr:
       
   761 		snprintf(small_buf, sizeof(small_buf), " %#llx", opd1);
       
   762 		esb_append(string_out, small_buf);
       
   763 		break;
       
   764         case DW_OP_const1s:
       
   765         case DW_OP_const2s:
       
   766         case DW_OP_const4s:
       
   767         case DW_OP_const8s:
       
   768         case DW_OP_consts:
       
   769         case DW_OP_skip:
       
   770         case DW_OP_bra:
       
   771         case DW_OP_fbreg:
       
   772 		snprintf(small_buf, sizeof(small_buf),
       
   773 			 " %lld", (Dwarf_Signed) opd1);
       
   774 		esb_append(string_out, small_buf);
       
   775 		break;
       
   776         case DW_OP_const1u:
       
   777         case DW_OP_const2u:
       
   778         case DW_OP_const4u:
       
   779         case DW_OP_const8u:
       
   780         case DW_OP_constu:
       
   781         case DW_OP_pick:
       
   782         case DW_OP_plus_uconst:
       
   783         case DW_OP_regx:
       
   784         case DW_OP_piece:
       
   785         case DW_OP_deref_size:
       
   786         case DW_OP_xderef_size:
       
   787             snprintf(small_buf, sizeof(small_buf), " %llu", opd1);
       
   788             esb_append(string_out, small_buf);
       
   789 		break;
       
   790         case DW_OP_bregx:
       
   791             snprintf(small_buf, sizeof(small_buf), "%llu", opd1);
       
   792             esb_append(string_out, small_buf);
       
   793 
       
   794 
       
   795 
       
   796             opd2 = expr->lr_number2;
       
   797             snprintf(small_buf, sizeof(small_buf),
       
   798                 "%+lld", (Dwarf_Signed) opd2);
       
   799             esb_append(string_out, small_buf);
       
   800             break;
       
   801         default:
       
   802             break;
       
   803 	}
       
   804     }
       
   805     return DW_DLV_OK;
       
   806 }
       
   807 
       
   808 /* Fill buffer with location lists 
       
   809    Buffer esbp expands as needed.
       
   810 */
       
   811  /*ARGSUSED*/ static void
       
   812 get_location_list(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Attribute attr,
       
   813 		  struct esb_s *esbp)
       
   814 {
       
   815     Dwarf_Locdesc *llbuf = 0;
       
   816     Dwarf_Locdesc **llbufarray = 0;
       
   817     Dwarf_Signed no_of_elements;
       
   818     Dwarf_Error err;
       
   819     int i;
       
   820     int lres = 0;
       
   821     int llent = 0;
       
   822     int skip_locdesc_header = 0;
       
   823 
       
   824 
       
   825     if (use_old_dwarf_loclist) {
       
   826 
       
   827 	lres = dwarf_loclist(attr, &llbuf, &no_of_elements, &err);
       
   828 	if (lres == DW_DLV_ERROR)
       
   829 	    print_error(dbg, "dwarf_loclist", lres, err);
       
   830 	if (lres == DW_DLV_NO_ENTRY)
       
   831 	    return;
       
   832 
       
   833 	dwarfdump_print_one_locdesc(dbg, llbuf,skip_locdesc_header,esbp);
       
   834 	dwarf_dealloc(dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK);
       
   835 	dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC);
       
   836 	return;
       
   837     }
       
   838 
       
   839     lres = dwarf_loclist_n(attr, &llbufarray, &no_of_elements, &err);
       
   840     if (lres == DW_DLV_ERROR)
       
   841 	print_error(dbg, "dwarf_loclist", lres, err);
       
   842     if (lres == DW_DLV_NO_ENTRY)
       
   843 	return;
       
   844 
       
   845     for (llent = 0; llent < no_of_elements; ++llent) {
       
   846 	char small_buf[100];
       
   847 
       
   848 	llbuf = llbufarray[llent];
       
   849 
       
   850 	if (!dense && llbuf->ld_from_loclist) {
       
   851 	    if (llent == 0) {
       
   852 		snprintf(small_buf, sizeof(small_buf),
       
   853 			 "<loclist with %ld entries follows>",
       
   854 			 (long) no_of_elements);
       
   855 		esb_append(esbp, small_buf);
       
   856 	    }
       
   857 	    esb_append(esbp, "\n\t\t\t");
       
   858 	    snprintf(small_buf, sizeof(small_buf), "[%2d]", llent);
       
   859 	    esb_append(esbp, small_buf);
       
   860 	}
       
   861 	lres = dwarfdump_print_one_locdesc(dbg,
       
   862               llbuf, 
       
   863               skip_locdesc_header,
       
   864               esbp);
       
   865 	if (lres == DW_DLV_ERROR) {
       
   866 	    return;
       
   867 	} else {
       
   868 	    /* DW_DLV_OK so we add follow-on at end, else is
       
   869 	       DW_DLV_NO_ENTRY (which is impossible, treat like
       
   870 	       DW_DLV_OK). */
       
   871 	}
       
   872     }
       
   873     for (i = 0; i < no_of_elements; ++i) {
       
   874 	dwarf_dealloc(dbg, llbufarray[i]->ld_s, DW_DLA_LOC_BLOCK);
       
   875 	dwarf_dealloc(dbg, llbufarray[i], DW_DLA_LOCDESC);
       
   876     }
       
   877     dwarf_dealloc(dbg, llbufarray, DW_DLA_LIST);
       
   878 }
       
   879 
       
   880 static void
       
   881 formx_unsigned(Dwarf_Unsigned u, struct esb_s *esbp)
       
   882 {
       
   883      char small_buf[40];
       
   884      snprintf(small_buf, sizeof(small_buf),
       
   885       "%llu", (unsigned long long)u);
       
   886      esb_append(esbp, small_buf);
       
   887 
       
   888 }
       
   889 static void
       
   890 formx_signed(Dwarf_Signed u, struct esb_s *esbp)
       
   891 {
       
   892      char small_buf[40];
       
   893      snprintf(small_buf, sizeof(small_buf),
       
   894       "%lld", (long long)u);
       
   895      esb_append(esbp, small_buf);
       
   896 }
       
   897 /* We think this is an integer. Figure out how to print it.
       
   898    In case the signedness is ambiguous (such as on 
       
   899    DW_FORM_data1 (ie, unknown signedness) print two ways.
       
   900 */
       
   901 static int
       
   902 formxdata_print_value(Dwarf_Attribute attrib, struct esb_s *esbp,
       
   903 	Dwarf_Error * err)
       
   904 {
       
   905     Dwarf_Signed tempsd = 0;
       
   906     Dwarf_Unsigned tempud = 0;
       
   907     int sres = 0;
       
   908     int ures = 0;
       
   909     Dwarf_Error serr = 0;
       
   910     ures = dwarf_formudata(attrib, &tempud, err);
       
   911     sres = dwarf_formsdata(attrib, &tempsd, &serr);
       
   912     if(ures == DW_DLV_OK) {
       
   913       if(sres == DW_DLV_OK) {
       
   914 	if(tempud == tempsd) {
       
   915 	   /* Data is the same value, so makes no difference which
       
   916 		we print. */
       
   917 	   formx_unsigned(tempud,esbp);
       
   918 	} else {
       
   919 	   formx_unsigned(tempud,esbp);
       
   920 	   esb_append(esbp,"(as signed = ");
       
   921 	   formx_signed(tempsd,esbp);
       
   922 	   esb_append(esbp,")");
       
   923         }
       
   924       } else if (sres == DW_DLV_NO_ENTRY) {
       
   925 	formx_unsigned(tempud,esbp);
       
   926       } else /* DW_DLV_ERROR */{
       
   927 	formx_unsigned(tempud,esbp);
       
   928       }
       
   929       return DW_DLV_OK;
       
   930     } else  if (ures == DW_DLV_NO_ENTRY) {
       
   931       if(sres == DW_DLV_OK) {
       
   932 	formx_signed(tempsd,esbp);
       
   933 	return sres;
       
   934       } else if (sres == DW_DLV_NO_ENTRY) {
       
   935 	return sres;
       
   936       } else /* DW_DLV_ERROR */{
       
   937 	*err = serr;
       
   938         return sres;
       
   939       }
       
   940     } 
       
   941     /* else ures ==  DW_DLV_ERROR */ 
       
   942     if(sres == DW_DLV_OK) {
       
   943 	formx_signed(tempsd,esbp);
       
   944     } else if (sres == DW_DLV_NO_ENTRY) {
       
   945 	return ures;
       
   946     } 
       
   947     /* DW_DLV_ERROR */
       
   948     return ures;
       
   949 }
       
   950 
       
   951 
       
   952 /* Fill buffer with attribute value.
       
   953    We pass in tag so we can try to do the right thing with
       
   954    broken compiler DW_TAG_enumerator 
       
   955 
       
   956    We append to esbp's buffer.
       
   957 
       
   958 */
       
   959 static void
       
   960 get_attr_value(Dwarf_Debug dbg, Dwarf_Half tag, Dwarf_Attribute attrib,
       
   961 	       char **srcfiles, Dwarf_Signed cnt, struct esb_s *esbp)
       
   962 {
       
   963     Dwarf_Half theform;
       
   964     string temps;
       
   965     Dwarf_Block *tempb;
       
   966     Dwarf_Signed tempsd = 0;
       
   967     Dwarf_Unsigned tempud = 0;
       
   968     int i;
       
   969     Dwarf_Half attr;
       
   970     Dwarf_Off off;
       
   971     Dwarf_Die die_for_check;
       
   972     Dwarf_Half tag_for_check;
       
   973     Dwarf_Bool tempbool;
       
   974     Dwarf_Addr addr = 0;
       
   975     int fres;
       
   976     int bres;
       
   977     int wres;
       
   978     int dres;
       
   979     Dwarf_Half direct_form = 0;
       
   980     char small_buf[100];
       
   981 
       
   982 
       
   983     fres = dwarf_whatform(attrib, &theform, &err);
       
   984     /* depending on the form and the attribute, process the form */
       
   985     if (fres == DW_DLV_ERROR) {
       
   986 	print_error(dbg, "dwarf_whatform cannot find attr form", fres,
       
   987 		    err);
       
   988     } else if (fres == DW_DLV_NO_ENTRY) {
       
   989 	return;
       
   990     }
       
   991 
       
   992     dwarf_whatform_direct(attrib, &direct_form, &err);
       
   993     /* ignore errors in dwarf_whatform_direct() */
       
   994 
       
   995 
       
   996     switch (theform) {
       
   997     case DW_FORM_addr:
       
   998 	bres = dwarf_formaddr(attrib, &addr, &err);
       
   999 	if (bres == DW_DLV_OK) {
       
  1000 	    snprintf(small_buf, sizeof(small_buf), "%#llx",
       
  1001 		     (unsigned long long) addr);
       
  1002 	    esb_append(esbp, small_buf);
       
  1003 	} else {
       
  1004 	    print_error(dbg, "addr formwith no addr?!", bres, err);
       
  1005 	}
       
  1006 	break;
       
  1007     case DW_FORM_ref_addr:
       
  1008 	/* DW_FORM_ref_addr is not accessed thru formref: ** it is an
       
  1009 	   address (global section offset) in ** the .debug_info
       
  1010 	   section. */
       
  1011 	bres = dwarf_global_formref(attrib, &off, &err);
       
  1012 	if (bres == DW_DLV_OK) {
       
  1013 	    snprintf(small_buf, sizeof(small_buf),
       
  1014 		     "<global die offset %llu>",
       
  1015 		     (unsigned long long) off);
       
  1016 	    esb_append(esbp, small_buf);
       
  1017 	} else {
       
  1018 	    print_error(dbg,
       
  1019 			"DW_FORM_ref_addr form with no reference?!",
       
  1020 			bres, err);
       
  1021 	}
       
  1022 	break;
       
  1023     case DW_FORM_ref1:
       
  1024     case DW_FORM_ref2:
       
  1025     case DW_FORM_ref4:
       
  1026     case DW_FORM_ref8:
       
  1027     case DW_FORM_ref_udata:
       
  1028 	bres = dwarf_formref(attrib, &off, &err);
       
  1029 	if (bres != DW_DLV_OK) {
       
  1030 	    print_error(dbg, "ref formwith no ref?!", bres, err);
       
  1031 	}
       
  1032 	/* do references inside <> to distinguish them ** from
       
  1033 	   constants. In dense form this results in <<>>. Ugly for
       
  1034 	   dense form, but better than ambiguous. davea 9/94 */
       
  1035 	snprintf(small_buf, sizeof(small_buf), "<%llu>", off);
       
  1036 	esb_append(esbp, small_buf);
       
  1037 	if (check_type_offset) {
       
  1038 	    wres = dwarf_whatattr(attrib, &attr, &err);
       
  1039 	    if (wres == DW_DLV_ERROR) {
       
  1040 
       
  1041 	    } else if (wres == DW_DLV_NO_ENTRY) {
       
  1042 	    }
       
  1043 	    if (attr == DW_AT_type) {
       
  1044 		dres = dwarf_offdie(dbg, cu_offset + off,
       
  1045 				    &die_for_check, &err);
       
  1046 		type_offset_result.checks++;
       
  1047 		if (dres != DW_DLV_OK) {
       
  1048 		    type_offset_result.errors++;
       
  1049 		    DWARF_CHECK_ERROR
       
  1050 			("DW_AT_type offset does not point to type info")
       
  1051 		} else {
       
  1052 		    int tres2;
       
  1053 
       
  1054 		    tres2 =
       
  1055 			dwarf_tag(die_for_check, &tag_for_check, &err);
       
  1056 		    if (tres2 == DW_DLV_OK) {
       
  1057 			switch (tag_for_check) {
       
  1058 			case DW_TAG_array_type:
       
  1059 			case DW_TAG_class_type:
       
  1060 			case DW_TAG_enumeration_type:
       
  1061 			case DW_TAG_pointer_type:
       
  1062 			case DW_TAG_reference_type:
       
  1063 			case DW_TAG_string_type:
       
  1064 			case DW_TAG_structure_type:
       
  1065 			case DW_TAG_subroutine_type:
       
  1066 			case DW_TAG_typedef:
       
  1067 			case DW_TAG_union_type:
       
  1068 			case DW_TAG_ptr_to_member_type:
       
  1069 			case DW_TAG_set_type:
       
  1070 			case DW_TAG_subrange_type:
       
  1071 			case DW_TAG_base_type:
       
  1072 			case DW_TAG_const_type:
       
  1073 			case DW_TAG_file_type:
       
  1074 			case DW_TAG_packed_type:
       
  1075 			case DW_TAG_thrown_type:
       
  1076 			case DW_TAG_volatile_type:
       
  1077 			    /* OK */
       
  1078 			    break;
       
  1079 			default:
       
  1080 			    type_offset_result.errors++;
       
  1081 			    DWARF_CHECK_ERROR
       
  1082 				("DW_AT_type offset does not point to type info")
       
  1083 				break;
       
  1084 			}
       
  1085 			dwarf_dealloc(dbg, die_for_check, DW_DLA_DIE);
       
  1086 		    } else {
       
  1087 			type_offset_result.errors++;
       
  1088 			DWARF_CHECK_ERROR
       
  1089 			    ("DW_AT_type offset does not exist")
       
  1090 		    }
       
  1091 		}
       
  1092 	    }
       
  1093 	}
       
  1094 	break;
       
  1095     case DW_FORM_block:
       
  1096     case DW_FORM_block1:
       
  1097     case DW_FORM_block2:
       
  1098     case DW_FORM_block4:
       
  1099 	fres = dwarf_formblock(attrib, &tempb, &err);
       
  1100 	if (fres == DW_DLV_OK) {
       
  1101 	    for (i = 0; i < tempb->bl_len; i++) {
       
  1102 		snprintf(small_buf, sizeof(small_buf), "%02x",
       
  1103 			 *(i + (unsigned char *) tempb->bl_data));
       
  1104 		esb_append(esbp, small_buf);
       
  1105 	    }
       
  1106 	    dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK);
       
  1107 	} else {
       
  1108 	    print_error(dbg, "DW_FORM_blockn cannot get block\n", fres,
       
  1109 			err);
       
  1110 	}
       
  1111 	break;
       
  1112     case DW_FORM_data1:
       
  1113     case DW_FORM_data2:
       
  1114     case DW_FORM_data4:
       
  1115     case DW_FORM_data8:
       
  1116 	fres = dwarf_whatattr(attrib, &attr, &err);
       
  1117 	if (fres == DW_DLV_ERROR) {
       
  1118 	    print_error(dbg, "FORM_datan cannot get attr", fres, err);
       
  1119 	} else if (fres == DW_DLV_NO_ENTRY) {
       
  1120 	    print_error(dbg, "FORM_datan cannot get attr", fres, err);
       
  1121 	} else {
       
  1122 	    switch (attr) {
       
  1123 	    case DW_AT_ordering:
       
  1124 	    case DW_AT_byte_size:
       
  1125 	    case DW_AT_bit_offset:
       
  1126 	    case DW_AT_bit_size:
       
  1127 	    case DW_AT_inline:
       
  1128 	    case DW_AT_language:
       
  1129 	    case DW_AT_visibility:
       
  1130 	    case DW_AT_virtuality:
       
  1131 	    case DW_AT_accessibility:
       
  1132 	    case DW_AT_address_class:
       
  1133 	    case DW_AT_calling_convention:
       
  1134 	    case DW_AT_discr_list:	/* DWARF3 */
       
  1135 	    case DW_AT_encoding:
       
  1136 	    case DW_AT_identifier_case:
       
  1137 	    case DW_AT_MIPS_loop_unroll_factor:
       
  1138 	    case DW_AT_MIPS_software_pipeline_depth:
       
  1139 	    case DW_AT_decl_column:
       
  1140 	    case DW_AT_decl_file:
       
  1141 	    case DW_AT_decl_line:
       
  1142 	    case DW_AT_start_scope:
       
  1143 	    case DW_AT_byte_stride:
       
  1144 	    case DW_AT_bit_stride:
       
  1145 	    case DW_AT_count:
       
  1146 	    case DW_AT_stmt_list:
       
  1147 	    case DW_AT_MIPS_fde:
       
  1148 		wres = get_small_encoding_integer_and_name(dbg,
       
  1149 							   attrib,
       
  1150 							   &tempud,
       
  1151 							   /* attrname */
       
  1152 		    (char *) NULL,
       
  1153 							   /* err_string 
       
  1154 							    */ 
       
  1155 							   (char **)
       
  1156 							   NULL,
       
  1157 							   (encoding_type_func) 0,
       
  1158 							   &err);
       
  1159 
       
  1160 		if (wres == DW_DLV_OK) {
       
  1161 		    snprintf(small_buf, sizeof(small_buf), "%llu",
       
  1162 			     tempud);
       
  1163 		    esb_append(esbp, small_buf);
       
  1164 		    if (attr == DW_AT_decl_file) {
       
  1165 			if (srcfiles && tempud > 0 && tempud <= cnt) {
       
  1166 			    /* added by user request */
       
  1167 			    /* srcfiles is indexed starting at 0, but
       
  1168 			       DW_AT_decl_file defines that 0 means no
       
  1169 			       file, so tempud 1 means the 0th entry in
       
  1170 			       srcfiles, thus tempud-1 is the correct
       
  1171 			       index into srcfiles.  */
       
  1172 			    char *fname = srcfiles[tempud - 1];
       
  1173 
       
  1174 			    esb_append(esbp, " ");
       
  1175 			    esb_append(esbp, fname);
       
  1176 			}
       
  1177 		    }
       
  1178 		} else {
       
  1179 		    print_error(dbg, "Cannot get encoding attribute ..",
       
  1180 				wres, err);
       
  1181 		}
       
  1182 		break;
       
  1183 	    case DW_AT_const_value:
       
  1184 		wres = formxdata_print_value(attrib,esbp, &err);
       
  1185 		if(wres == DW_DLV_OK){
       
  1186 		    /* String appended already. */
       
  1187 		} else if (wres == DW_DLV_NO_ENTRY) {
       
  1188 		    /* nothing? */
       
  1189 		} else {
       
  1190 		   print_error(dbg,"Cannot get DW_AT_const_value ",wres,err);
       
  1191 		}
       
  1192   
       
  1193 		
       
  1194 		break;
       
  1195 	    case DW_AT_upper_bound:
       
  1196 	    case DW_AT_lower_bound:
       
  1197 	    default:
       
  1198 		wres = formxdata_print_value(attrib,esbp, &err);
       
  1199 		if (wres == DW_DLV_OK) {
       
  1200 		    /* String appended already. */
       
  1201 		} else if (wres == DW_DLV_NO_ENTRY) {
       
  1202 		    /* nothing? */
       
  1203 		} else {
       
  1204 		    print_error(dbg, "Cannot get formsdata..", wres,
       
  1205 				err);
       
  1206 		}
       
  1207 		break;
       
  1208 	    }
       
  1209 	}
       
  1210 	if (cu_name_flag) {
       
  1211 	    if (attr == DW_AT_MIPS_fde) {
       
  1212 		if (fde_offset_for_cu_low == DW_DLV_BADOFFSET) {
       
  1213 		    fde_offset_for_cu_low
       
  1214 			= fde_offset_for_cu_high = tempud;
       
  1215 		} else if (tempud < fde_offset_for_cu_low) {
       
  1216 		    fde_offset_for_cu_low = tempud;
       
  1217 		} else if (tempud > fde_offset_for_cu_high) {
       
  1218 		    fde_offset_for_cu_high = tempud;
       
  1219 		}
       
  1220 	    }
       
  1221 	}
       
  1222 	break;
       
  1223     case DW_FORM_sdata:
       
  1224 	wres = dwarf_formsdata(attrib, &tempsd, &err);
       
  1225 	if (wres == DW_DLV_OK) {
       
  1226 	    snprintf(small_buf, sizeof(small_buf), "%lld", tempsd);
       
  1227 	    esb_append(esbp, small_buf);
       
  1228 	} else if (wres == DW_DLV_NO_ENTRY) {
       
  1229 	    /* nothing? */
       
  1230 	} else {
       
  1231 	    print_error(dbg, "Cannot get formsdata..", wres, err);
       
  1232 	}
       
  1233 	break;
       
  1234     case DW_FORM_udata:
       
  1235 	wres = dwarf_formudata(attrib, &tempud, &err);
       
  1236 	if (wres == DW_DLV_OK) {
       
  1237 	    snprintf(small_buf, sizeof(small_buf), "%llu", tempud);
       
  1238 	    esb_append(esbp, small_buf);
       
  1239 	} else if (wres == DW_DLV_NO_ENTRY) {
       
  1240 	    /* nothing? */
       
  1241 	} else {
       
  1242 	    print_error(dbg, "Cannot get formudata....", wres, err);
       
  1243 	}
       
  1244 	break;
       
  1245     case DW_FORM_string:
       
  1246     case DW_FORM_strp:
       
  1247 	wres = dwarf_formstring(attrib, &temps, &err);
       
  1248 	if (wres == DW_DLV_OK) {
       
  1249 	    esb_append(esbp, temps);
       
  1250 	} else if (wres == DW_DLV_NO_ENTRY) {
       
  1251 	    /* nothing? */
       
  1252 	} else {
       
  1253 	    print_error(dbg, "Cannot get formstr/p....", wres, err);
       
  1254 	}
       
  1255 
       
  1256 	break;
       
  1257     case DW_FORM_flag:
       
  1258 	wres = dwarf_formflag(attrib, &tempbool, &err);
       
  1259 	if (wres == DW_DLV_OK) {
       
  1260 	    if (tempbool) {
       
  1261 		snprintf(small_buf, sizeof(small_buf), "yes(%d)",
       
  1262 			 tempbool);
       
  1263 		esb_append(esbp, small_buf);
       
  1264 	    } else {
       
  1265 		snprintf(small_buf, sizeof(small_buf), "no");
       
  1266 		esb_append(esbp, small_buf);
       
  1267 	    }
       
  1268 	} else if (wres == DW_DLV_NO_ENTRY) {
       
  1269 	    /* nothing? */
       
  1270 	} else {
       
  1271 	    print_error(dbg, "Cannot get formflag/p....", wres, err);
       
  1272 	}
       
  1273 	break;
       
  1274     case DW_FORM_indirect:
       
  1275 	/* We should not ever get here, since the true form was
       
  1276 	   determined and direct_form has the DW_FORM_indirect if it is
       
  1277 	   used here in this attr. */
       
  1278 	esb_append(esbp, get_FORM_name(dbg, theform));
       
  1279 	break;
       
  1280     default:
       
  1281 	print_error(dbg, "dwarf_whatform unexpected value", DW_DLV_OK,
       
  1282 		    err);
       
  1283     }
       
  1284     if (verbose && direct_form && direct_form == DW_FORM_indirect) {
       
  1285 	char *form_indir = " (used DW_FORM_indirect) ";
       
  1286 
       
  1287 	esb_append(esbp, form_indir);
       
  1288     }
       
  1289 }
       
  1290 
       
  1291 /* A cleanup so that when using a memory checker
       
  1292    we don't show irrelevant leftovers.
       
  1293 */
       
  1294 void
       
  1295 clean_up_die_esb()
       
  1296 {
       
  1297    esb_destructor(&esb_base);
       
  1298 }
       
  1299 
       
  1300 #include "_tag_attr_table.c"
       
  1301 
       
  1302 static int
       
  1303 tag_attr_combination(Dwarf_Half tag, Dwarf_Half attr)
       
  1304 {
       
  1305     if (attr > 0 && attr < 0x60) {
       
  1306 	return ((tag_attr_combination_table[tag][attr / 0x20]
       
  1307 		 & (1 << (attr % 0x20))) > 0 ? TRUE : FALSE);
       
  1308     } else if (attr == DW_AT_MIPS_fde) {
       
  1309 	/* no check now */
       
  1310 	return (TRUE);
       
  1311     } else
       
  1312 	return (FALSE);
       
  1313 }