tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_sections.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /* 
       
     2   Copyright (C) 2000,2003,2004,2005,2006 Silicon Graphics, Inc.  All Rights Reserved.
       
     3   Portions Copyright 2007 Sun Microsystems, Inc. All rights reserved.
       
     4 
       
     5   This program is free software; you can redistribute it and/or modify it
       
     6   under the terms of version 2 of the GNU General Public License as
       
     7   published by the Free Software Foundation.
       
     8 
       
     9   This program is distributed in the hope that it would be useful, but
       
    10   WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
       
    12 
       
    13   Further, this software is distributed without any warranty that it is
       
    14   free of the rightful claim of any third person regarding infringement
       
    15   or the like.  Any license provided herein, whether implied or
       
    16   otherwise, applies only to this software file.  Patent licenses, if
       
    17   any, provided herein do not apply to combinations of this program with
       
    18   other software, or any other product whatsoever.
       
    19 
       
    20   You should have received a copy of the GNU General Public License along
       
    21   with this program; if not, write the Free Software Foundation, Inc., 51
       
    22   Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
       
    23 
       
    24   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
       
    25   Mountain View, CA 94043, or:
       
    26 
       
    27   http://www.sgi.com
       
    28 
       
    29   For further information regarding this notice, see:
       
    30 
       
    31   http://oss.sgi.com/projects/GenInfo/NoticeExplan
       
    32 
       
    33 
       
    34 
       
    35 $Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_sections.c,v 1.69 2006/04/17 00:09:56 davea Exp $ */
       
    36 #include "globals.h"
       
    37 #include "dwarf_names.h"
       
    38 #include "dwconf.h"
       
    39 
       
    40 #include "print_frames.h"
       
    41 /*
       
    42  * Print line number information:
       
    43  * 	filename
       
    44  *	new basic-block
       
    45  *	[line] [address] <new statement>
       
    46  */
       
    47 
       
    48 
       
    49 static void
       
    50   print_pubname_style_entry(Dwarf_Debug dbg,
       
    51 			    char *line_title,
       
    52 			    char *name,
       
    53 			    Dwarf_Unsigned die_off,
       
    54 			    Dwarf_Unsigned cu_off,
       
    55 			    Dwarf_Unsigned global_cu_off,
       
    56 			    Dwarf_Unsigned maxoff);
       
    57 
       
    58 
       
    59 /* referred in dwarfdump.c */
       
    60 Dwarf_Die current_cu_die_for_print_frames;
       
    61 
       
    62 /* If an offset is bad, libdwarf will notice it and
       
    63    return an error.
       
    64    If it does the error checking in
       
    65 	print_pubname_style_entry()
       
    66    will be useless as we give up here on an error.
       
    67 
       
    68    This intended for checking pubnames-style call return
       
    69    values (for all the pubnames-style interfaces).
       
    70 
       
    71    In at least one gigantic executable die_off turned out wrong.
       
    72 */
       
    73 
       
    74 static void
       
    75 deal_with_name_offset_err(Dwarf_Debug dbg,
       
    76 			  char *err_loc,
       
    77 			  char *name, Dwarf_Unsigned die_off,
       
    78 			  int nres, Dwarf_Error err)
       
    79 {
       
    80     if (nres == DW_DLV_ERROR) {
       
    81 	Dwarf_Unsigned myerr = dwarf_errno(err);
       
    82 
       
    83 	if (myerr == DW_DLE_OFFSET_BAD) {
       
    84 	    printf("Error: bad offset %s, %s %lld (0x%llx)\n",
       
    85 		   err_loc,
       
    86 		   name,
       
    87 		   (long long) die_off, (unsigned long long) die_off);
       
    88 	}
       
    89 	print_error(dbg, err_loc, nres, err);
       
    90     }
       
    91 }
       
    92 
       
    93 static void
       
    94 print_source_intro(Dwarf_Die cu_die)
       
    95 {
       
    96     Dwarf_Off off = 0;
       
    97     int ores = dwarf_dieoffset(cu_die, &off, &err);
       
    98 
       
    99     if (ores == DW_DLV_OK) {
       
   100 	printf
       
   101 	    ("Source lines (from CU-DIE at .debug_info offset %llu):\n",
       
   102 	     (unsigned long long) off);
       
   103     } else {
       
   104 	printf("Source lines (for the CU-DIE at unknown location):\n");
       
   105     }
       
   106 }
       
   107 
       
   108 
       
   109 extern void
       
   110 print_line_numbers_this_cu(Dwarf_Debug dbg, Dwarf_Die cu_die)
       
   111 {
       
   112     Dwarf_Signed linecount = 0;
       
   113     Dwarf_Line *linebuf = NULL;
       
   114     Dwarf_Signed i = 0;
       
   115     Dwarf_Addr pc = 0;
       
   116     Dwarf_Unsigned lineno = 0;
       
   117     Dwarf_Signed column = 0;
       
   118     string filename;
       
   119     Dwarf_Bool newstatement = 0;
       
   120     Dwarf_Bool lineendsequence = 0;
       
   121     Dwarf_Bool new_basic_block = 0;
       
   122     int lres = 0;
       
   123     int sres = 0;
       
   124     int ares = 0;
       
   125     int lires = 0;
       
   126     int cores = 0;
       
   127 
       
   128     printf("\n.debug_line: line number info for a single cu\n");
       
   129     if (verbose > 1) {
       
   130 	print_source_intro(cu_die);
       
   131 	print_one_die(dbg, cu_die, /* print_information= */ 1,
       
   132 		      /* srcfiles= */ 0, /* cnt= */ 0);
       
   133 
       
   134 	lres = dwarf_print_lines(cu_die, &err);
       
   135 	if (lres == DW_DLV_ERROR) {
       
   136 	    print_error(dbg, "dwarf_srclines details", lres, err);
       
   137 	}
       
   138 	return;
       
   139     }
       
   140     lres = dwarf_srclines(cu_die, &linebuf, &linecount, &err);
       
   141     if (lres == DW_DLV_ERROR) {
       
   142 	print_error(dbg, "dwarf_srclines", lres, err);
       
   143     } else if (lres == DW_DLV_NO_ENTRY) {
       
   144 	/* no line information is included */
       
   145     } else {
       
   146 	print_source_intro(cu_die);
       
   147 	if (verbose) {
       
   148 	    print_one_die(dbg, cu_die, /* print_information= */ 1,
       
   149 			  /* srcfiles= */ 0, /* cnt= */ 0);
       
   150 	}
       
   151 	printf
       
   152 	    ("<source>\t[row,column]\t<pc>\t//<new statement or basic block\n");
       
   153 
       
   154 	for (i = 0; i < linecount; i++) {
       
   155 	    Dwarf_Line line = linebuf[i];
       
   156 	    int nsres;
       
   157 
       
   158 	    sres = dwarf_linesrc(line, &filename, &err);
       
   159 	    ares = dwarf_lineaddr(line, &pc, &err);
       
   160 	    if (sres == DW_DLV_ERROR) {
       
   161 		print_error(dbg, "dwarf_linesrc", sres, err);
       
   162 	    }
       
   163 	    if (sres == DW_DLV_NO_ENTRY) {
       
   164 		filename = "<unknown>";
       
   165 	    }
       
   166 	    if (ares == DW_DLV_ERROR) {
       
   167 		print_error(dbg, "dwarf_lineaddr", ares, err);
       
   168 	    }
       
   169 	    if (ares == DW_DLV_NO_ENTRY) {
       
   170 		pc = 0;
       
   171 	    }
       
   172 	    lires = dwarf_lineno(line, &lineno, &err);
       
   173 	    if (lires == DW_DLV_ERROR) {
       
   174 		print_error(dbg, "dwarf_lineno", lires, err);
       
   175 	    }
       
   176 	    if (lires == DW_DLV_NO_ENTRY) {
       
   177 		lineno = -1LL;
       
   178 	    }
       
   179 	    cores = dwarf_lineoff(line, &column, &err);
       
   180 	    if (cores == DW_DLV_ERROR) {
       
   181 		print_error(dbg, "dwarf_lineoff", cores, err);
       
   182 	    }
       
   183 	    if (cores == DW_DLV_NO_ENTRY) {
       
   184 		column = -1LL;
       
   185 	    }
       
   186 	    printf("%s:\t[%3llu,%2lld]\t%#llx", filename, lineno,
       
   187 		   column, pc);
       
   188 	    if (sres == DW_DLV_OK)
       
   189 		dwarf_dealloc(dbg, filename, DW_DLA_STRING);
       
   190 
       
   191 	    nsres = dwarf_linebeginstatement(line, &newstatement, &err);
       
   192 	    if (nsres == DW_DLV_OK) {
       
   193 		if (newstatement) {
       
   194 		    printf("\t// new statement");
       
   195 		}
       
   196 	    } else if (nsres == DW_DLV_ERROR) {
       
   197 		print_error(dbg, "linebeginstatment failed", nsres,
       
   198 			    err);
       
   199 	    }
       
   200 	    nsres = dwarf_lineblock(line, &new_basic_block, &err);
       
   201 	    if (nsres == DW_DLV_OK) {
       
   202 		if (new_basic_block) {
       
   203 		    printf("\t// new basic block");
       
   204 		}
       
   205 	    } else if (nsres == DW_DLV_ERROR) {
       
   206 		print_error(dbg, "lineblock failed", nsres, err);
       
   207 	    }
       
   208 	    nsres = dwarf_lineendsequence(line, &lineendsequence, &err);
       
   209 	    if (nsres == DW_DLV_OK) {
       
   210 		if (lineendsequence) {
       
   211 		    printf("\t// end of text sequence");
       
   212 		}
       
   213 	    } else if (nsres == DW_DLV_ERROR) {
       
   214 		print_error(dbg, "lineblock failed", nsres, err);
       
   215 	    }
       
   216 	    printf("\n");
       
   217 
       
   218 	}
       
   219 	dwarf_srclines_dealloc(dbg, linebuf, linecount);
       
   220     }
       
   221 }
       
   222 
       
   223 /*
       
   224 
       
   225 A strcpy which ensures NUL terminated string
       
   226 and never overruns the output.
       
   227 
       
   228 */
       
   229 static void
       
   230 safe_strcpy(char *out, long outlen, char *in, long inlen)
       
   231 {
       
   232     if (inlen >= (outlen - 1)) {
       
   233 	strncpy(out, in, outlen - 1);
       
   234 	out[outlen - 1] = 0;
       
   235     } else {
       
   236 	strcpy(out, in);
       
   237     }
       
   238 }
       
   239 
       
   240 /*
       
   241 	Returns 1 if a proc with this low_pc found.
       
   242 	Else returns 0.
       
   243 
       
   244 
       
   245 */
       
   246 static int
       
   247 get_proc_name(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr low_pc,
       
   248 	      char *proc_name_buf, int proc_name_buf_len)
       
   249 {
       
   250     Dwarf_Signed atcnt = 0;
       
   251     Dwarf_Signed i = 0;
       
   252     Dwarf_Attribute *atlist = NULL;
       
   253     Dwarf_Addr low_pc_die = 0;
       
   254     int atres = 0;
       
   255     int funcres = 1;
       
   256     int funcpcfound = 0;
       
   257     int funcnamefound = 1;
       
   258 
       
   259     proc_name_buf[0] = 0;	/* always set to something */
       
   260     atres = dwarf_attrlist(die, &atlist, &atcnt, &err);
       
   261     if (atres == DW_DLV_ERROR) {
       
   262 	print_error(dbg, "dwarf_attrlist", atres, err);
       
   263 	return 0;
       
   264     }
       
   265     if (atres == DW_DLV_NO_ENTRY) {
       
   266 	return 0;
       
   267     }
       
   268     for (i = 0; i < atcnt; i++) {
       
   269 	Dwarf_Half attr;
       
   270 	int ares;
       
   271 	string temps;
       
   272 	int sres;
       
   273 	int dres;
       
   274 
       
   275 	if (funcnamefound == 1 && funcpcfound == 1) {
       
   276 	    /* stop as soon as both found */
       
   277 	    break;
       
   278 	}
       
   279 	ares = dwarf_whatattr(atlist[i], &attr, &err);
       
   280 	if (ares == DW_DLV_ERROR) {
       
   281 	    print_error(dbg, "get_proc_name whatattr error", ares, err);
       
   282 	} else if (ares == DW_DLV_OK) {
       
   283 	    switch (attr) {
       
   284 	    case DW_AT_name:
       
   285 		sres = dwarf_formstring(atlist[i], &temps, &err);
       
   286 		if (sres == DW_DLV_ERROR) {
       
   287 		    print_error(dbg,
       
   288 				"formstring in get_proc_name failed",
       
   289 				sres, err);
       
   290 		    /* 50 is safe wrong length since is bigger than the 
       
   291 		       actual string */
       
   292 		    safe_strcpy(proc_name_buf, proc_name_buf_len,
       
   293 				"ERROR in dwarf_formstring!", 50);
       
   294 		} else if (sres == DW_DLV_NO_ENTRY) {
       
   295 		    /* 50 is safe wrong length since is bigger than the 
       
   296 		       actual string */
       
   297 		    safe_strcpy(proc_name_buf, proc_name_buf_len,
       
   298 				"NO ENTRY on dwarf_formstring?!", 50);
       
   299 		} else {
       
   300 		    long len = (long) strlen(temps);
       
   301 
       
   302 		    safe_strcpy(proc_name_buf, proc_name_buf_len, temps,
       
   303 				len);
       
   304 		}
       
   305 		funcnamefound = 1;	/* FOUND THE NAME */
       
   306 		break;
       
   307 	    case DW_AT_low_pc:
       
   308 		dres = dwarf_formaddr(atlist[i], &low_pc_die, &err);
       
   309 		if (dres == DW_DLV_ERROR) {
       
   310 		    print_error(dbg, "formaddr in get_proc_name failed",
       
   311 				dres, err);
       
   312 		    low_pc_die = ~low_pc;
       
   313 		    /* ensure no match */
       
   314 		}
       
   315 		funcpcfound = 1;
       
   316 
       
   317 		break;
       
   318 	    default:
       
   319 		break;
       
   320 	    }
       
   321 	}
       
   322     }
       
   323     for (i = 0; i < atcnt; i++) {
       
   324 	dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);
       
   325     }
       
   326     dwarf_dealloc(dbg, atlist, DW_DLA_LIST);
       
   327     if (funcnamefound == 0 || funcpcfound == 0 || low_pc != low_pc_die) {
       
   328 	funcres = 0;
       
   329     }
       
   330     return (funcres);
       
   331 }
       
   332 
       
   333 /*
       
   334 	Modified Depth First Search looking for the procedure:
       
   335 	a) only looks for children of subprogram.
       
   336 	b) With subprogram looks at current die *before* looking
       
   337 	   for a child.
       
   338 	
       
   339 	Needed since some languages, including MP Fortran,
       
   340 	have nested functions.
       
   341 	Return 0 on failure, 1 on success.
       
   342 */
       
   343 static int
       
   344 get_nested_proc_name(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr low_pc,
       
   345 		     char *ret_name_buf, int ret_name_buf_len)
       
   346 {
       
   347     char name_buf[BUFSIZ];
       
   348     Dwarf_Die curdie = die;
       
   349     int die_locally_gotten = 0;
       
   350     Dwarf_Die prev_child = 0;
       
   351     Dwarf_Die newchild = 0;
       
   352     Dwarf_Die newsibling = 0;
       
   353     Dwarf_Half tag;
       
   354     Dwarf_Error err = 0;
       
   355     int chres = DW_DLV_OK;
       
   356 
       
   357     ret_name_buf[0] = 0;
       
   358     while (chres == DW_DLV_OK) {
       
   359 	int tres;
       
   360 
       
   361 	tres = dwarf_tag(curdie, &tag, &err);
       
   362 	newchild = 0;
       
   363 	err = 0;
       
   364 	if (tres == DW_DLV_OK) {
       
   365 	    int lchres;
       
   366 
       
   367 	    if (tag == DW_TAG_subprogram) {
       
   368 		int proc_name_v;
       
   369 
       
   370 		proc_name_v = get_proc_name(dbg, curdie, low_pc,
       
   371 					    name_buf, BUFSIZ);
       
   372 		if (proc_name_v) {
       
   373 		    /* this is it */
       
   374 		    safe_strcpy(ret_name_buf, ret_name_buf_len,
       
   375 				name_buf, (long) strlen(name_buf));
       
   376 		    if (die_locally_gotten) {
       
   377 			/* If we got this die from the parent, we do
       
   378 			   not want to dealloc here! */
       
   379 			dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
       
   380 		    }
       
   381 		    return 1;
       
   382 		}
       
   383 		/* check children of subprograms recursively should
       
   384 		   this really be check children of anything? */
       
   385 
       
   386 		lchres = dwarf_child(curdie, &newchild, &err);
       
   387 		if (lchres == DW_DLV_OK) {
       
   388 		    /* look for inner subprogram */
       
   389 		    int newprog =
       
   390 			get_nested_proc_name(dbg, newchild, low_pc,
       
   391 					     name_buf, BUFSIZ);
       
   392 
       
   393 		    dwarf_dealloc(dbg, newchild, DW_DLA_DIE);
       
   394 		    if (newprog) {
       
   395 			/* Found it.  We could just take this name or
       
   396 			   we could concatenate names together For now, 
       
   397 			   just take name */
       
   398 			if (die_locally_gotten) {
       
   399 			    /* If we got this die from the parent, we
       
   400 			       do not want to dealloc here! */
       
   401 			    dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
       
   402 			}
       
   403 			safe_strcpy(ret_name_buf, ret_name_buf_len,
       
   404 				    name_buf, (long) strlen(name_buf));
       
   405 			return 1;
       
   406 		    }
       
   407 		} else if (lchres == DW_DLV_NO_ENTRY) {
       
   408 		    /* nothing to do */
       
   409 		} else {
       
   410 		    print_error(dbg,
       
   411 				"get_nested_proc_name dwarf_child() failed ",
       
   412 				chres, err);
       
   413 		    if (die_locally_gotten) {
       
   414 			/* If we got this die from the parent, we do
       
   415 			   not want to dealloc here! */
       
   416 			dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
       
   417 		    }
       
   418 		    return 0;
       
   419 		}
       
   420 	    }			/* end if TAG_subprogram */
       
   421 	} else {
       
   422 	    print_error(dbg, "no tag on child read ", tres, err);
       
   423 	    if (die_locally_gotten) {
       
   424 		/* If we got this die from the parent, we do not want
       
   425 		   to dealloc here! */
       
   426 		dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
       
   427 	    }
       
   428 	    return 0;
       
   429 	}
       
   430 	/* try next sibling */
       
   431 	prev_child = curdie;
       
   432 	chres = dwarf_siblingof(dbg, curdie, &newsibling, &err);
       
   433 	if (chres == DW_DLV_ERROR) {
       
   434 	    print_error(dbg, "dwarf_cu_header On Child read ", chres,
       
   435 			err);
       
   436 	    if (die_locally_gotten) {
       
   437 		/* If we got this die from the parent, we do not want
       
   438 		   to dealloc here! */
       
   439 		dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
       
   440 	    }
       
   441 	    return 0;
       
   442 	} else if (chres == DW_DLV_NO_ENTRY) {
       
   443 	    if (die_locally_gotten) {
       
   444 		/* If we got this die from the parent, we do not want
       
   445 		   to dealloc here! */
       
   446 		dwarf_dealloc(dbg, prev_child, DW_DLA_DIE);
       
   447 	    }
       
   448 	    return 0;		/* proc name not at this level */
       
   449 	} else {		/* DW_DLV_OK */
       
   450 	    curdie = newsibling;
       
   451 	    if (die_locally_gotten) {
       
   452 		/* If we got this die from the parent, we do not want
       
   453 		   to dealloc here! */
       
   454 		dwarf_dealloc(dbg, prev_child, DW_DLA_DIE);
       
   455 	    }
       
   456 	    prev_child = 0;
       
   457 	    die_locally_gotten = 1;
       
   458 	}
       
   459 
       
   460     }
       
   461     if (die_locally_gotten) {
       
   462 	/* If we got this die from the parent, we do not want to
       
   463 	   dealloc here! */
       
   464 	dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
       
   465     }
       
   466     return 0;
       
   467 }
       
   468 
       
   469 /*
       
   470   For MP Fortran and possibly other languages, functions 
       
   471   nest!  As a result, we must dig thru all functions, 
       
   472   not just the top level.
       
   473 
       
   474 
       
   475   This remembers the CU die and restarts each search at the start
       
   476   of  the current cu.
       
   477 
       
   478   
       
   479 */
       
   480 string
       
   481 get_fde_proc_name(Dwarf_Debug dbg, Dwarf_Addr low_pc)
       
   482 {
       
   483     static char proc_name[BUFSIZ];
       
   484     Dwarf_Unsigned cu_header_length;
       
   485     Dwarf_Unsigned abbrev_offset;
       
   486     Dwarf_Half version_stamp;
       
   487     Dwarf_Half address_size;
       
   488     Dwarf_Unsigned next_cu_offset = 0;
       
   489     int cures = DW_DLV_OK;
       
   490     int dres = DW_DLV_OK;
       
   491     int chres = DW_DLV_OK;
       
   492     int looping = 0;
       
   493 
       
   494     if (current_cu_die_for_print_frames == NULL) {
       
   495 	cures
       
   496 	    = dwarf_next_cu_header(dbg, &cu_header_length,
       
   497 				   &version_stamp, &abbrev_offset,
       
   498 				   &address_size, &next_cu_offset,
       
   499 				   &err);
       
   500 	if (cures == DW_DLV_ERROR) {
       
   501 	    return NULL;
       
   502 	} else if (cures == DW_DLV_NO_ENTRY) {
       
   503 	    /* loop thru the list again */
       
   504 	    current_cu_die_for_print_frames = 0;
       
   505 	    ++looping;
       
   506 	} else {		/* DW_DLV_OK */
       
   507 	    dres = dwarf_siblingof(dbg, NULL,
       
   508 				   &current_cu_die_for_print_frames,
       
   509 				   &err);
       
   510 	    if (dres == DW_DLV_ERROR) {
       
   511 		return NULL;
       
   512 	    }
       
   513 	}
       
   514     }
       
   515     if (dres == DW_DLV_OK) {
       
   516 	Dwarf_Die child = 0;
       
   517 
       
   518 	if (current_cu_die_for_print_frames == 0) {
       
   519 	    /* no information. Possibly a stripped file */
       
   520 	    return NULL;
       
   521 	}
       
   522 	chres =
       
   523 	    dwarf_child(current_cu_die_for_print_frames, &child, &err);
       
   524 	if (chres == DW_DLV_ERROR) {
       
   525 	    print_error(dbg, "dwarf_cu_header on child read ", chres,
       
   526 			err);
       
   527 	} else if (chres == DW_DLV_NO_ENTRY) {
       
   528 	} else {		/* DW_DLV_OK */
       
   529 	    int gotname =
       
   530 		get_nested_proc_name(dbg, child, low_pc, proc_name,
       
   531 				     BUFSIZ);
       
   532 
       
   533 	    dwarf_dealloc(dbg, child, DW_DLA_DIE);
       
   534 	    if (gotname) {
       
   535 		return (proc_name);
       
   536 	    }
       
   537 	    child = 0;
       
   538 	}
       
   539     }
       
   540     for (;;) {
       
   541 	Dwarf_Die ldie;
       
   542 
       
   543 	cures = dwarf_next_cu_header(dbg, &cu_header_length,
       
   544 				     &version_stamp, &abbrev_offset,
       
   545 				     &address_size, &next_cu_offset,
       
   546 				     &err);
       
   547 
       
   548 	if (cures != DW_DLV_OK) {
       
   549 	    break;
       
   550 	}
       
   551 
       
   552 
       
   553 	dres = dwarf_siblingof(dbg, NULL, &ldie, &err);
       
   554 
       
   555 	if (current_cu_die_for_print_frames) {
       
   556 	    dwarf_dealloc(dbg, current_cu_die_for_print_frames,
       
   557 			  DW_DLA_DIE);
       
   558 	}
       
   559 	current_cu_die_for_print_frames = 0;
       
   560 	if (dres == DW_DLV_ERROR) {
       
   561 	    print_error(dbg,
       
   562 			"dwarf_cu_header Child Read finding proc name for .debug_frame",
       
   563 			chres, err);
       
   564 	    continue;
       
   565 	} else if (dres == DW_DLV_NO_ENTRY) {
       
   566 	    ++looping;
       
   567 	    if (looping > 1) {
       
   568 		print_error(dbg, "looping  on cu headers!", dres, err);
       
   569 		return NULL;
       
   570 	    }
       
   571 	    continue;
       
   572 	}
       
   573 	/* DW_DLV_OK */
       
   574 	current_cu_die_for_print_frames = ldie;
       
   575 	{
       
   576 	    int chres;
       
   577 	    Dwarf_Die child;
       
   578 
       
   579 	    chres =
       
   580 		dwarf_child(current_cu_die_for_print_frames, &child,
       
   581 			    &err);
       
   582 	    if (chres == DW_DLV_ERROR) {
       
   583 		print_error(dbg, "dwarf Child Read ", chres, err);
       
   584 	    } else if (chres == DW_DLV_NO_ENTRY) {
       
   585 
       
   586 		;		/* do nothing, loop on cu */
       
   587 	    } else {		/* DW_DLV_OK) */
       
   588 
       
   589 		int gotname =
       
   590 		    get_nested_proc_name(dbg, child, low_pc, proc_name,
       
   591 					 BUFSIZ);
       
   592 
       
   593 		dwarf_dealloc(dbg, child, DW_DLA_DIE);
       
   594 		if (gotname) {
       
   595 		    return (proc_name);
       
   596 		}
       
   597 	    }
       
   598 	}
       
   599     }
       
   600     return (NULL);
       
   601 }
       
   602 
       
   603 /* get all the data in .debug_frame (or .eh_frame). 
       
   604  The '3' versions mean print using the dwarf3 new interfaces.
       
   605  The non-3 mean use the old interfaces.
       
   606  All combinations of requests are possible.
       
   607 */
       
   608 extern void
       
   609 print_frames(Dwarf_Debug dbg, int print_debug_frame, int print_eh_frame,
       
   610 	     struct dwconf_s *config_data)
       
   611 {
       
   612     Dwarf_Cie *cie_data = NULL;
       
   613     Dwarf_Signed cie_element_count = 0;
       
   614     Dwarf_Fde *fde_data = NULL;
       
   615     Dwarf_Signed fde_element_count = 0;
       
   616     Dwarf_Signed i;
       
   617     int fres = 0;
       
   618     Dwarf_Half address_size = 0;
       
   619     int framed = 0;
       
   620 
       
   621     fres = dwarf_get_address_size(dbg, &address_size, &err);
       
   622     if (fres != DW_DLV_OK) {
       
   623 	print_error(dbg, "dwarf_get_address_size", fres, err);
       
   624     }
       
   625     for (framed = 0; framed < 2; ++framed) {
       
   626 	char *framename = 0;
       
   627 	int silent_if_missing = 0;
       
   628 	int is_eh = 0;
       
   629 
       
   630 	if (framed == 0) {
       
   631 	    if (!print_debug_frame) {
       
   632 		continue;
       
   633 	    }
       
   634 	    framename = ".debug_frame";
       
   635 	    /* 
       
   636 	     * Big question here is how to print all the info?
       
   637 	     * Can print the logical matrix, but that is huge,
       
   638 	     * though could skip lines that don't change.
       
   639 	     * Either that, or print the instruction statement program
       
   640 	     * that describes the changes.
       
   641 	     */
       
   642 	    fres =
       
   643 		dwarf_get_fde_list(dbg, &cie_data, &cie_element_count,
       
   644 				   &fde_data, &fde_element_count, &err);
       
   645 	} else {
       
   646 	    if (!print_eh_frame) {
       
   647 		continue;
       
   648 	    }
       
   649 	    is_eh = 1;
       
   650 	    /* This is gnu g++ exceptions in a .eh_frame section. Which 
       
   651 	       is just like .debug_frame except that the empty, or
       
   652 	       'special' CIE_id is 0, not -1 (to distinguish fde from
       
   653 	       cie). And the augmentation is "eh". As of egcs-1.1.2
       
   654 	       anyway. A non-zero cie_id is in a fde and is the
       
   655 	       difference between the fde address and the beginning of
       
   656 	       the cie it belongs to. This makes sense as this is
       
   657 	       intended to be referenced at run time, and is part of
       
   658 	       the running image. For more on augmentation strings, see 
       
   659 	       libdwarf/dwarf_frame.c.  */
       
   660 
       
   661 	    /* 
       
   662 	     * Big question here is how to print all the info?
       
   663 	     * Can print the logical matrix, but that is huge,
       
   664 	     * though could skip lines that don't change.
       
   665 	     * Either that, or print the instruction statement program
       
   666 	     * that describes the changes.
       
   667 	     */
       
   668 	    silent_if_missing = 1;
       
   669 	    framename = ".eh_frame";
       
   670 	    fres =
       
   671 		dwarf_get_fde_list_eh(dbg, &cie_data,
       
   672 				      &cie_element_count, &fde_data,
       
   673 				      &fde_element_count, &err);
       
   674 	}
       
   675 	if (fres == DW_DLV_ERROR) {
       
   676 	    printf("\n%s\n", framename);
       
   677 	    print_error(dbg, "dwarf_get_fde_list", fres, err);
       
   678 	} else if (fres == DW_DLV_NO_ENTRY) {
       
   679 	    if (!silent_if_missing)
       
   680 		printf("\n%s\n", framename);
       
   681 	    /* no frame information */
       
   682 	} else {		/* DW_DLV_OK */
       
   683 
       
   684 	    printf("\n%s\n", framename);
       
   685 	    printf("\nfde:\n");
       
   686 
       
   687 	    for (i = 0; i < fde_element_count; i++) {
       
   688 		print_one_fde(dbg, fde_data[i],
       
   689 			      i, cie_data, cie_element_count,
       
   690 			      address_size, is_eh, config_data);
       
   691 	    }
       
   692 	    /* 
       
   693 	       Print the cie set. */
       
   694 	    if (verbose) {
       
   695 		printf("\ncie:\n");
       
   696 		for (i = 0; i < cie_element_count; i++) {
       
   697 		    print_one_cie(dbg, cie_data[i], i, address_size,
       
   698 				  config_data);
       
   699 		}
       
   700 	    }
       
   701 	    dwarf_fde_cie_list_dealloc(dbg, cie_data, cie_element_count,
       
   702 				       fde_data, fde_element_count);
       
   703 	}
       
   704     }
       
   705     if (current_cu_die_for_print_frames) {
       
   706 	dwarf_dealloc(dbg, current_cu_die_for_print_frames, DW_DLA_DIE);
       
   707 	current_cu_die_for_print_frames = 0;
       
   708     }
       
   709 }
       
   710 
       
   711 
       
   712 
       
   713 
       
   714 int
       
   715   dwarf_get_section_max_offsets(Dwarf_Debug /* dbg */ ,
       
   716 				Dwarf_Unsigned *	/* debug_info_size 
       
   717 							 */ ,
       
   718 				Dwarf_Unsigned *	/* debug_abbrev_size 
       
   719 							 */
       
   720 				, Dwarf_Unsigned *	/* debug_line_size 
       
   721 							 */ ,
       
   722 				Dwarf_Unsigned *	/* debug_loc_size 
       
   723 							 */ ,
       
   724 				Dwarf_Unsigned *
       
   725 				/* debug_aranges_size */ ,
       
   726 				Dwarf_Unsigned *
       
   727 				/* debug_macinfo_size */ ,
       
   728 				Dwarf_Unsigned *
       
   729 				/* debug_pubnames_size */ ,
       
   730 				Dwarf_Unsigned *	/* debug_str_size 
       
   731 							 */ ,
       
   732 				Dwarf_Unsigned *	/* debug_frame_size 
       
   733 							 */
       
   734 				, Dwarf_Unsigned *	/* debug_ranges_size 
       
   735 							 */
       
   736 				, Dwarf_Unsigned *
       
   737 				/* debug_pubtypes_size */ );
       
   738 
       
   739 /* The new (April 2005) dwarf_get_section_max_offsets()
       
   740    in libdwarf returns all max-offsets, but we only
       
   741    want one of those offsets. This function returns 
       
   742    the one we want from that set,
       
   743    making functions needing this offset as readable as possible.
       
   744    (avoiding code duplication).
       
   745 */
       
   746 static Dwarf_Unsigned
       
   747 get_info_max_offset(Dwarf_Debug dbg)
       
   748 {
       
   749     Dwarf_Unsigned debug_info_size = 0;
       
   750     Dwarf_Unsigned debug_abbrev_size = 0;
       
   751     Dwarf_Unsigned debug_line_size = 0;
       
   752     Dwarf_Unsigned debug_loc_size = 0;
       
   753     Dwarf_Unsigned debug_aranges_size = 0;
       
   754     Dwarf_Unsigned debug_macinfo_size = 0;
       
   755     Dwarf_Unsigned debug_pubnames_size = 0;
       
   756     Dwarf_Unsigned debug_str_size = 0;
       
   757     Dwarf_Unsigned debug_frame_size = 0;
       
   758     Dwarf_Unsigned debug_ranges_size = 0;
       
   759     Dwarf_Unsigned debug_pubtypes_size = 0;
       
   760 
       
   761     dwarf_get_section_max_offsets(dbg,
       
   762 				  &debug_info_size,
       
   763 				  &debug_abbrev_size,
       
   764 				  &debug_line_size,
       
   765 				  &debug_loc_size,
       
   766 				  &debug_aranges_size,
       
   767 				  &debug_macinfo_size,
       
   768 				  &debug_pubnames_size,
       
   769 				  &debug_str_size,
       
   770 				  &debug_frame_size,
       
   771 				  &debug_ranges_size,
       
   772 				  &debug_pubtypes_size);
       
   773 
       
   774     return debug_info_size;
       
   775 }
       
   776 
       
   777 /* This unifies the code for some error checks to
       
   778    avoid code duplication.
       
   779 */
       
   780 static void
       
   781 check_info_offset_sanity(char *sec,
       
   782 			 char *field,
       
   783 			 char *global,
       
   784 			 Dwarf_Unsigned offset, Dwarf_Unsigned maxoff)
       
   785 {
       
   786     if (maxoff == 0) {
       
   787 	/* Lets make a heuristic check. */
       
   788 	if (offset > 0xffffffff) {
       
   789 	    printf("Warning: section %s %s %s offset 0x%llx "
       
   790 		   "exceptionally large \n",
       
   791 		   sec, field, global, (unsigned long long) offset);
       
   792 	}
       
   793     }
       
   794     if (offset >= maxoff) {
       
   795 	printf("Warning: section %s %s %s offset 0x%llx "
       
   796 	       "larger than max of 0x%llx\n",
       
   797 	       sec, field, global, (unsigned long long) offset,
       
   798 	       (unsigned long long) maxoff);
       
   799     }
       
   800 }
       
   801 
       
   802 /* Unified pubnames style output.
       
   803    The error checking here against maxoff may be useless
       
   804    (in that libdwarf may return an error if the offset is bad
       
   805    and we will not get called here).
       
   806    But we leave it in nonetheless as it looks sensible.
       
   807    In at least one gigantic executable such offsets turned out wrong.
       
   808 */
       
   809 static void
       
   810 print_pubname_style_entry(Dwarf_Debug dbg,
       
   811 			  char *line_title,
       
   812 			  char *name,
       
   813 			  Dwarf_Unsigned die_off,
       
   814 			  Dwarf_Unsigned cu_off,
       
   815 			  Dwarf_Unsigned global_cu_offset,
       
   816 			  Dwarf_Unsigned maxoff)
       
   817 {
       
   818     Dwarf_Die die = NULL;
       
   819     Dwarf_Die cu_die = NULL;
       
   820     Dwarf_Off die_CU_off = 0;
       
   821     int dres = 0;
       
   822     int ddres = 0;
       
   823     int cudres = 0;
       
   824 
       
   825     /* get die at die_off */
       
   826     dres = dwarf_offdie(dbg, die_off, &die, &err);
       
   827     if (dres != DW_DLV_OK)
       
   828 	print_error(dbg, "dwarf_offdie", dres, err);
       
   829 
       
   830     /* get offset of die from its cu-header */
       
   831     ddres = dwarf_die_CU_offset(die, &die_CU_off, &err);
       
   832     if (ddres != DW_DLV_OK) {
       
   833 	print_error(dbg, "dwarf_die_CU_offset", ddres, err);
       
   834     }
       
   835 
       
   836     /* get die at offset cu_off */
       
   837     cudres = dwarf_offdie(dbg, cu_off, &cu_die, &err);
       
   838     if (cudres != DW_DLV_OK) {
       
   839 	dwarf_dealloc(dbg, die, DW_DLA_DIE);
       
   840 	print_error(dbg, "dwarf_offdie", cudres, err);
       
   841     }
       
   842     printf("%s %-15s die-in-sect %lld, cu-in-sect %lld,"
       
   843 	   " die-in-cu %lld, cu-header-in-sect %lld",
       
   844 	   line_title, name, (long long) die_off, (long long) cu_off,
       
   845 	   /* the cu die offset */
       
   846 	   (long long) die_CU_off,
       
   847 	   /* following is absolute offset of the ** beginning of the
       
   848 	      cu */
       
   849 	   (long long) (die_off - die_CU_off));
       
   850 
       
   851     if ((die_off - die_CU_off) != global_cu_offset) {
       
   852 	printf(" error: real cuhdr %llu", global_cu_offset);
       
   853 	exit(1);
       
   854     }
       
   855     if (verbose) {
       
   856 	printf(" cuhdr %llu", global_cu_offset);
       
   857     }
       
   858 
       
   859 
       
   860     dwarf_dealloc(dbg, die, DW_DLA_DIE);
       
   861     dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
       
   862 
       
   863 
       
   864     printf("\n");
       
   865 
       
   866     check_info_offset_sanity(line_title,
       
   867 			     "die offset", name, die_off, maxoff);
       
   868     check_info_offset_sanity(line_title,
       
   869 			     "die cu offset", name, die_CU_off, maxoff);
       
   870     check_info_offset_sanity(line_title,
       
   871 			     "cu offset", name,
       
   872 			     (die_off - die_CU_off), maxoff);
       
   873 
       
   874 }
       
   875 
       
   876 
       
   877 /* get all the data in .debug_pubnames */
       
   878 extern void
       
   879 print_pubnames(Dwarf_Debug dbg)
       
   880 {
       
   881     Dwarf_Global *globbuf = NULL;
       
   882     Dwarf_Signed count = 0;
       
   883     Dwarf_Signed i = 0;
       
   884     Dwarf_Off die_off = 0;
       
   885     Dwarf_Off cu_off = 0;
       
   886     char *name = 0;
       
   887     int res = 0;
       
   888 
       
   889     printf("\n.debug_pubnames\n");
       
   890     res = dwarf_get_globals(dbg, &globbuf, &count, &err);
       
   891     if (res == DW_DLV_ERROR) {
       
   892 	print_error(dbg, "dwarf_get_globals", res, err);
       
   893     } else if (res == DW_DLV_NO_ENTRY) {
       
   894 	/* (err == 0 && count == DW_DLV_NOCOUNT) means there are no
       
   895 	   pubnames.  */
       
   896     } else {
       
   897 	Dwarf_Unsigned maxoff = get_info_max_offset(dbg);
       
   898 
       
   899 	for (i = 0; i < count; i++) {
       
   900 	    int nres;
       
   901 	    int cures3;
       
   902 	    Dwarf_Off global_cu_off = 0;
       
   903 
       
   904 	    nres = dwarf_global_name_offsets(globbuf[i],
       
   905 					     &name, &die_off, &cu_off,
       
   906 					     &err);
       
   907 	    deal_with_name_offset_err(dbg, "dwarf_global_name_offsets",
       
   908 				      name, die_off, nres, err);
       
   909 
       
   910 	    cures3 = dwarf_global_cu_offset(globbuf[i],
       
   911 					    &global_cu_off, &err);
       
   912 	    if (cures3 != DW_DLV_OK) {
       
   913 		print_error(dbg, "dwarf_global_cu_offset", cures3, err);
       
   914 	    }
       
   915 
       
   916 	    print_pubname_style_entry(dbg,
       
   917 				      "global",
       
   918 				      name, die_off, cu_off,
       
   919 				      global_cu_off, maxoff);
       
   920 
       
   921 	    /* print associated die too? */
       
   922 
       
   923 	    if (check_pubname_attr) {
       
   924 		Dwarf_Bool has_attr;
       
   925 		int ares;
       
   926 		int dres;
       
   927 		Dwarf_Die die;
       
   928 
       
   929 		/* get die at die_off */
       
   930 		dres = dwarf_offdie(dbg, die_off, &die, &err);
       
   931 		if (dres != DW_DLV_OK) {
       
   932 		    print_error(dbg, "dwarf_offdie", dres, err);
       
   933 		}
       
   934 
       
   935 
       
   936 		ares =
       
   937 		    dwarf_hasattr(die, DW_AT_external, &has_attr, &err);
       
   938 		if (ares == DW_DLV_ERROR) {
       
   939 		    print_error(dbg, "hassattr on DW_AT_external", ares,
       
   940 				err);
       
   941 		}
       
   942 		pubname_attr_result.checks++;
       
   943 		if (ares == DW_DLV_OK && has_attr) {
       
   944 		    /* Should the value of flag be examined? */
       
   945 		} else {
       
   946 		    pubname_attr_result.errors++;
       
   947 		    DWARF_CHECK_ERROR2(name,
       
   948 				       "pubname does not have DW_AT_external")
       
   949 		}
       
   950 		dwarf_dealloc(dbg, die, DW_DLA_DIE);
       
   951 	    }
       
   952 	}
       
   953 	dwarf_globals_dealloc(dbg, globbuf, count);
       
   954     }
       
   955 }				/* print_pubnames() */
       
   956 
       
   957 
       
   958 struct macro_counts_s {
       
   959     long mc_start_file;
       
   960     long mc_end_file;
       
   961     long mc_define;
       
   962     long mc_undef;
       
   963     long mc_extension;
       
   964     long mc_code_zero;
       
   965     long mc_unknown;
       
   966 };
       
   967 
       
   968 static void
       
   969 print_one_macro_entry_detail(long i,
       
   970 			     char *type,
       
   971 			     struct Dwarf_Macro_Details_s *mdp)
       
   972 {
       
   973     /* "DW_MACINFO_*: section-offset file-index [line] string\n" */
       
   974     if (mdp->dmd_macro) {
       
   975 	printf("%3ld %s: %6llu %2lld [%4lld] \"%s\" \n",
       
   976 	       i,
       
   977 	       type,
       
   978 	       mdp->dmd_offset,
       
   979 	       mdp->dmd_fileindex, mdp->dmd_lineno, mdp->dmd_macro);
       
   980     } else {
       
   981 	printf("%3ld %s: %6llu %2lld [%4lld] 0\n",
       
   982 	       i,
       
   983 	       type,
       
   984 	       mdp->dmd_offset, mdp->dmd_fileindex, mdp->dmd_lineno);
       
   985     }
       
   986 
       
   987 }
       
   988 
       
   989 static void
       
   990 print_one_macro_entry(long i,
       
   991 		      struct Dwarf_Macro_Details_s *mdp,
       
   992 		      struct macro_counts_s *counts)
       
   993 {
       
   994 
       
   995     switch (mdp->dmd_type) {
       
   996     case 0:
       
   997 	counts->mc_code_zero++;
       
   998 	print_one_macro_entry_detail(i, "DW_MACINFO_type-code-0", mdp);
       
   999 	break;
       
  1000 
       
  1001     case DW_MACINFO_start_file:
       
  1002 	counts->mc_start_file++;
       
  1003 	print_one_macro_entry_detail(i, "DW_MACINFO_start_file", mdp);
       
  1004 	break;
       
  1005 
       
  1006     case DW_MACINFO_end_file:
       
  1007 	counts->mc_end_file++;
       
  1008 	print_one_macro_entry_detail(i, "DW_MACINFO_end_file  ", mdp);
       
  1009 	break;
       
  1010 
       
  1011     case DW_MACINFO_vendor_ext:
       
  1012 	counts->mc_extension++;
       
  1013 	print_one_macro_entry_detail(i, "DW_MACINFO_vendor_ext", mdp);
       
  1014 	break;
       
  1015 
       
  1016     case DW_MACINFO_define:
       
  1017 	counts->mc_define++;
       
  1018 	print_one_macro_entry_detail(i, "DW_MACINFO_define    ", mdp);
       
  1019 	break;
       
  1020 
       
  1021     case DW_MACINFO_undef:
       
  1022 	counts->mc_undef++;
       
  1023 	print_one_macro_entry_detail(i, "DW_MACINFO_undef     ", mdp);
       
  1024 	break;
       
  1025 
       
  1026     default:
       
  1027 	{
       
  1028 	    char create_type[50];	/* More than large enough. */
       
  1029 
       
  1030 	    counts->mc_unknown++;
       
  1031 	    snprintf(create_type, sizeof(create_type),
       
  1032 		     "DW_MACINFO_0x%x", mdp->dmd_type);
       
  1033 	    print_one_macro_entry_detail(i, create_type, mdp);
       
  1034 	}
       
  1035 	break;
       
  1036     }
       
  1037 }
       
  1038 
       
  1039 /* print data in .debug_macinfo */
       
  1040 /* FIXME: should print name of file whose index is in macro data
       
  1041    here  --  somewhere.
       
  1042 */
       
  1043  /*ARGSUSED*/ extern void
       
  1044 print_macinfo(Dwarf_Debug dbg)
       
  1045 {
       
  1046     Dwarf_Off offset = 0;
       
  1047     Dwarf_Unsigned max = 0;
       
  1048     Dwarf_Signed count = 0;
       
  1049     long group = 0;
       
  1050     Dwarf_Macro_Details *maclist = NULL;
       
  1051     int lres = 0;
       
  1052 
       
  1053     printf("\n.debug_macinfo\n");
       
  1054 
       
  1055     while ((lres = dwarf_get_macro_details(dbg, offset,
       
  1056 					   max, &count, &maclist,
       
  1057 					   &err)) == DW_DLV_OK) {
       
  1058 	long i;
       
  1059 	struct macro_counts_s counts;
       
  1060 
       
  1061 
       
  1062 	memset(&counts, 0, sizeof(counts));
       
  1063 
       
  1064 	printf("\n");
       
  1065 	printf("compilation-unit .debug_macinfo # %ld\n", group);
       
  1066 	printf
       
  1067 	    ("num name section-offset file-index [line] \"string\"\n");
       
  1068 	for (i = 0; i < count; i++) {
       
  1069 	    struct Dwarf_Macro_Details_s *mdp = &maclist[i];
       
  1070 
       
  1071 	    print_one_macro_entry(i, mdp, &counts);
       
  1072 	}
       
  1073 
       
  1074 	if (counts.mc_start_file == 0) {
       
  1075 	    printf
       
  1076 		("DW_MACINFO file count of zero is invalid DWARF2/3\n");
       
  1077 	}
       
  1078 	if (counts.mc_start_file != counts.mc_end_file) {
       
  1079 	    printf("Counts of DW_MACINFO file (%ld) end_file (%ld) "
       
  1080 		   "do not match!.\n",
       
  1081 		   counts.mc_start_file, counts.mc_end_file);
       
  1082 	}
       
  1083 	if (counts.mc_code_zero < 1) {
       
  1084 	    printf("Count of zeros in macro group should be non-zero "
       
  1085 		   "(1 preferred), count is %ld\n",
       
  1086 		   counts.mc_code_zero);
       
  1087 	}
       
  1088 	printf("Macro counts: start file %ld, "
       
  1089 	       "end file %ld, "
       
  1090 	       "define %ld, "
       
  1091 	       "undef %ld "
       
  1092 	       "ext %ld, "
       
  1093 	       "code-zero %ld, "
       
  1094 	       "unknown %ld\n",
       
  1095 	       counts.mc_start_file,
       
  1096 	       counts.mc_end_file,
       
  1097 	       counts.mc_define,
       
  1098 	       counts.mc_undef,
       
  1099 	       counts.mc_extension,
       
  1100 	       counts.mc_code_zero, counts.mc_unknown);
       
  1101 
       
  1102 
       
  1103 	/* int type= maclist[count - 1].dmd_type; */
       
  1104 	/* ASSERT: type is zero */
       
  1105 
       
  1106 	offset = maclist[count - 1].dmd_offset + 1;
       
  1107 	dwarf_dealloc(dbg, maclist, DW_DLA_STRING);
       
  1108 	++group;
       
  1109     }
       
  1110     if (lres == DW_DLV_ERROR) {
       
  1111 	print_error(dbg, "dwarf_get_macro_details", lres, err);
       
  1112     }
       
  1113 }
       
  1114 
       
  1115 /* print data in .debug_loc */
       
  1116 extern void
       
  1117 print_locs(Dwarf_Debug dbg)
       
  1118 {
       
  1119     Dwarf_Unsigned offset = 0;
       
  1120     Dwarf_Addr hipc_offset = 0;
       
  1121     Dwarf_Addr lopc_offset = 0;
       
  1122     Dwarf_Ptr data = 0;
       
  1123     Dwarf_Unsigned entry_len = 0;
       
  1124     Dwarf_Unsigned next_entry = 0;
       
  1125     int lres = 0;
       
  1126 
       
  1127     printf("\n.debug_loc format <o b e l> means "
       
  1128 	   "section-offset begin-addr end-addr length-of-block-entry\n");
       
  1129     while ((lres = dwarf_get_loclist_entry(dbg, offset,
       
  1130 					   &hipc_offset, &lopc_offset,
       
  1131 					   &data, &entry_len,
       
  1132 					   &next_entry,
       
  1133 					   &err)) == DW_DLV_OK) {
       
  1134 	printf("\t <obel> 0x%08llx 0x%09llx " "0x%08llx " "%8lld\n",
       
  1135 	       (long long) offset, (long long) lopc_offset,
       
  1136 	       (long long) hipc_offset, (long long) entry_len);
       
  1137 	offset = next_entry;
       
  1138     }
       
  1139     if (lres == DW_DLV_ERROR) {
       
  1140 	print_error(dbg, "dwarf_get_loclist_entry", lres, err);
       
  1141     }
       
  1142 }
       
  1143 
       
  1144 /* print data in .debug_abbrev */
       
  1145 extern void
       
  1146 print_abbrevs(Dwarf_Debug dbg)
       
  1147 {
       
  1148     Dwarf_Abbrev ab;
       
  1149     Dwarf_Unsigned offset = 0;
       
  1150     Dwarf_Unsigned length = 0;
       
  1151     Dwarf_Unsigned attr_count = 0;
       
  1152     Dwarf_Half tag = 0;
       
  1153     Dwarf_Half attr = 0;
       
  1154     Dwarf_Signed form = 0;
       
  1155     Dwarf_Off off = 0;
       
  1156     Dwarf_Unsigned i = 0;
       
  1157     string child_name;
       
  1158     Dwarf_Unsigned abbrev_num = 1;
       
  1159     Dwarf_Signed child_flag = 0;
       
  1160     int abres = 0;
       
  1161     int tres = 0;
       
  1162     int acres = 0;
       
  1163     Dwarf_Unsigned abbrev_code = 0;
       
  1164 
       
  1165     printf("\n.debug_abbrev\n");
       
  1166     while ((abres = dwarf_get_abbrev(dbg, offset, &ab,
       
  1167 				     &length, &attr_count,
       
  1168 				     &err)) == DW_DLV_OK) {
       
  1169 
       
  1170 	if (attr_count == 0) {
       
  1171 	    /* Simple innocuous zero : null abbrev entry */
       
  1172 	    if (dense) {
       
  1173 		printf("<%lld><%lld><%lld><%s>\n", abbrev_num, offset, (signed long long)	/* abbrev_code 
       
  1174 												 */ 0,
       
  1175 		       "null .debug_abbrev entry");
       
  1176 	    } else {
       
  1177 		printf("<%4lld><%5lld><code: %2lld> %-20s\n", abbrev_num, offset, (signed long long)	/* abbrev_code 
       
  1178 													 */ 0,
       
  1179 		       "null .debug_abbrev entry");
       
  1180 	    }
       
  1181 
       
  1182 	    offset += length;
       
  1183 	    ++abbrev_num;
       
  1184 	    dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
       
  1185 	    continue;
       
  1186 	}
       
  1187 	tres = dwarf_get_abbrev_tag(ab, &tag, &err);
       
  1188 	if (tres != DW_DLV_OK) {
       
  1189 	    dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
       
  1190 	    print_error(dbg, "dwarf_get_abbrev_tag", tres, err);
       
  1191 	}
       
  1192 	tres = dwarf_get_abbrev_code(ab, &abbrev_code, &err);
       
  1193 	if (tres != DW_DLV_OK) {
       
  1194 	    dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
       
  1195 	    print_error(dbg, "dwarf_get_abbrev_code", tres, err);
       
  1196 	}
       
  1197 	if (dense)
       
  1198 	    printf("<%lld><%lld><%lld><%s>", abbrev_num,
       
  1199 		   offset, abbrev_code, get_TAG_name(dbg, tag));
       
  1200 	else
       
  1201 	    printf("<%4lld><%5lld><code: %2lld> %-20s", abbrev_num,
       
  1202 		   offset, abbrev_code, get_TAG_name(dbg, tag));
       
  1203 	++abbrev_num;
       
  1204 	acres = dwarf_get_abbrev_children_flag(ab, &child_flag, &err);
       
  1205 	if (acres == DW_DLV_ERROR) {
       
  1206 	    dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
       
  1207 	    print_error(dbg, "dwarf_get_abbrev_children_flag", acres,
       
  1208 			err);
       
  1209 	}
       
  1210 	if (acres == DW_DLV_NO_ENTRY) {
       
  1211 	    child_flag = 0;
       
  1212 	}
       
  1213 	child_name = get_children_name(dbg, child_flag);
       
  1214 	if (dense)
       
  1215 	    printf(" %s", child_name);
       
  1216 	else
       
  1217 	    printf("%s\n", child_name);
       
  1218 	/* Abbrev just contains the format of a die, which debug_info
       
  1219 	   then points to with the real data. So here we just print the 
       
  1220 	   given format. */
       
  1221 	for (i = 0; i < attr_count; i++) {
       
  1222 	    int aeres;
       
  1223 
       
  1224 	    aeres =
       
  1225 		dwarf_get_abbrev_entry(ab, i, &attr, &form, &off, &err);
       
  1226 	    if (aeres == DW_DLV_ERROR) {
       
  1227 		dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
       
  1228 		print_error(dbg, "dwarf_get_abbrev_entry", aeres, err);
       
  1229 	    }
       
  1230 	    if (aeres == DW_DLV_NO_ENTRY) {
       
  1231 		attr = -1LL;
       
  1232 		form = -1LL;
       
  1233 	    }
       
  1234 	    if (dense)
       
  1235 		printf(" <%ld>%s<%s>", (unsigned long) off,
       
  1236 		       get_AT_name(dbg, attr),
       
  1237 		       get_FORM_name(dbg, (Dwarf_Half) form));
       
  1238 	    else
       
  1239 		printf("      <%5ld>\t%-28s%s\n",
       
  1240 		       (unsigned long) off, get_AT_name(dbg, attr),
       
  1241 		       get_FORM_name(dbg, (Dwarf_Half) form));
       
  1242 	}
       
  1243 	dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
       
  1244 	offset += length;
       
  1245 	if (dense)
       
  1246 	    printf("\n");
       
  1247     }
       
  1248     if (abres == DW_DLV_ERROR) {
       
  1249 	print_error(dbg, "dwarf_get_abbrev", abres, err);
       
  1250     }
       
  1251 }
       
  1252 
       
  1253 /* print data in .debug_string */
       
  1254 extern void
       
  1255 print_strings(Dwarf_Debug dbg)
       
  1256 {
       
  1257     Dwarf_Signed length = 0;
       
  1258     string name;
       
  1259     Dwarf_Off offset = 0;
       
  1260     int sres = 0;
       
  1261 
       
  1262     printf("\n.debug_string\n");
       
  1263     while ((sres = dwarf_get_str(dbg, offset, &name, &length, &err))
       
  1264 	   == DW_DLV_OK) {
       
  1265 	printf("name at offset %lld, length %lld is %s\n",
       
  1266 	       offset, length, name);
       
  1267 	offset += length + 1;
       
  1268     }
       
  1269     /* An inability to find the section is not necessarily
       
  1270        a real error, so do not report error unless we've
       
  1271        seen a real record. */
       
  1272     if(sres == DW_DLV_ERROR && offset != 0) {
       
  1273        print_error(dbg, "dwarf_get_str failure", sres, err);
       
  1274     }
       
  1275 }
       
  1276 
       
  1277 /* get all the data in .debug_aranges */
       
  1278 extern void
       
  1279 print_aranges(Dwarf_Debug dbg)
       
  1280 {
       
  1281     Dwarf_Signed count = 0;
       
  1282     Dwarf_Signed i = 0;
       
  1283     Dwarf_Arange *arange_buf = NULL;
       
  1284     Dwarf_Addr start = 0;
       
  1285     Dwarf_Unsigned length = 0;
       
  1286     Dwarf_Off cu_die_offset = 0;
       
  1287     Dwarf_Die cu_die = NULL;
       
  1288     int ares = 0;
       
  1289     int aires = 0;
       
  1290 
       
  1291     printf("\n.debug_aranges\n");
       
  1292     ares = dwarf_get_aranges(dbg, &arange_buf, &count, &err);
       
  1293     if (ares == DW_DLV_ERROR) {
       
  1294 	print_error(dbg, "dwarf_get_aranges", ares, err);
       
  1295     } else if (ares == DW_DLV_NO_ENTRY) {
       
  1296 	/* no arange is included */
       
  1297     } else {
       
  1298 	for (i = 0; i < count; i++) {
       
  1299 	    aires = dwarf_get_arange_info(arange_buf[i],
       
  1300 					  &start, &length,
       
  1301 					  &cu_die_offset, &err);
       
  1302 	    if (aires != DW_DLV_OK) {
       
  1303 		print_error(dbg, "dwarf_get_arange_info", aires, err);
       
  1304 	    } else {
       
  1305 		int dres;
       
  1306 
       
  1307 		dres = dwarf_offdie(dbg, cu_die_offset, &cu_die, &err);
       
  1308 		if (dres != DW_DLV_OK) {
       
  1309 		    print_error(dbg, "dwarf_offdie", dres, err);
       
  1310 		} else {
       
  1311 		    if (cu_name_flag) {
       
  1312 			Dwarf_Half tag;
       
  1313 			Dwarf_Attribute attrib;
       
  1314 			Dwarf_Half theform;
       
  1315 			int tres;
       
  1316 			int dares;
       
  1317 			int fres;
       
  1318 
       
  1319 			tres = dwarf_tag(cu_die, &tag, &err);
       
  1320 			if (tres != DW_DLV_OK) {
       
  1321 			    print_error(dbg, "dwarf_tag in aranges",
       
  1322 					tres, err);
       
  1323 			}
       
  1324 			dares =
       
  1325 			    dwarf_attr(cu_die, DW_AT_name, &attrib,
       
  1326 				       &err);
       
  1327 			if (dares != DW_DLV_OK) {
       
  1328 			    print_error(dbg, "dwarf_attr arange"
       
  1329 					" derived die has no name",
       
  1330 					dres, err);
       
  1331 			}
       
  1332 			fres = dwarf_whatform(attrib, &theform, &err);
       
  1333 			if (fres == DW_DLV_OK) {
       
  1334 			    if (theform == DW_FORM_string
       
  1335 				|| theform == DW_FORM_strp) {
       
  1336 				string temps;
       
  1337 				int sres;
       
  1338 
       
  1339 				sres =
       
  1340 				    dwarf_formstring(attrib, &temps,
       
  1341 						     &err);
       
  1342 				if (sres == DW_DLV_OK) {
       
  1343 				    string p = temps;
       
  1344 
       
  1345 				    if (cu_name[0] != '/') {
       
  1346 					p = strrchr(temps, '/');
       
  1347 					if (p == NULL) {
       
  1348 					    p = temps;
       
  1349 					} else {
       
  1350 					    p++;
       
  1351 					}
       
  1352 				    }
       
  1353 				    if (!strcmp(cu_name, p)) {
       
  1354 				    } else {
       
  1355 					continue;
       
  1356 				    }
       
  1357 				} else {
       
  1358 				    print_error(dbg,
       
  1359 						"arange: string missing",
       
  1360 						sres, err);
       
  1361 				}
       
  1362 			    }
       
  1363 			} else {
       
  1364 			    print_error(dbg,
       
  1365 					"dwarf_whatform unexpected value",
       
  1366 					fres, err);
       
  1367 			}
       
  1368 			dwarf_dealloc(dbg, attrib, DW_DLA_ATTR);
       
  1369 		    }
       
  1370 		    printf("\narange starts at %llx, "
       
  1371 			   "length of %lld, cu_die_offset = %lld",
       
  1372 			   start, length, cu_die_offset);
       
  1373 		    /* get the offset of the cu header itself in the
       
  1374 		       section */
       
  1375 		    {
       
  1376 			Dwarf_Off off = 0;
       
  1377 			int cures3 =
       
  1378 			    dwarf_get_arange_cu_header_offset(arange_buf
       
  1379 							      [i],
       
  1380 							      &off,
       
  1381 							      &err);
       
  1382 
       
  1383 			if (cures3 != DW_DLV_OK) {
       
  1384 			    print_error(dbg, "dwarf_get_cu_hdr_offset",
       
  1385 					cures3, err);
       
  1386 			}
       
  1387 			if (verbose)
       
  1388 			    printf(" cuhdr %llu", off);
       
  1389 		    }
       
  1390 		    printf("\n");
       
  1391 		    print_one_die(dbg, cu_die, (boolean) TRUE,
       
  1392 				  /* srcfiles= */ 0,
       
  1393 				  /* cnt= */ 0);
       
  1394 
       
  1395 		    dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
       
  1396 		}
       
  1397 	    }
       
  1398 	    /* print associated die too? */
       
  1399 	    dwarf_dealloc(dbg, arange_buf[i], DW_DLA_ARANGE);
       
  1400 	}
       
  1401 	dwarf_dealloc(dbg, arange_buf, DW_DLA_LIST);
       
  1402     }
       
  1403 }
       
  1404 
       
  1405 /* Get all the data in .debug_static_funcs 
       
  1406    On error, this allows some dwarf memory leaks.
       
  1407 */
       
  1408 extern void
       
  1409 print_static_funcs(Dwarf_Debug dbg)
       
  1410 {
       
  1411     Dwarf_Func *funcbuf = NULL;
       
  1412     Dwarf_Signed count = 0;
       
  1413     Dwarf_Signed i = 0;
       
  1414     Dwarf_Off die_off = 0;
       
  1415     Dwarf_Off cu_off = 0;
       
  1416     int gfres = 0;
       
  1417 
       
  1418     printf("\n.debug_static_func\n");
       
  1419     gfres = dwarf_get_funcs(dbg, &funcbuf, &count, &err);
       
  1420     if (gfres == DW_DLV_ERROR) {
       
  1421 	print_error(dbg, "dwarf_get_funcs", gfres, err);
       
  1422     } else if (gfres == DW_DLV_NO_ENTRY) {
       
  1423 	/* no static funcs */
       
  1424     } else {
       
  1425 	Dwarf_Unsigned maxoff = get_info_max_offset(dbg);
       
  1426 
       
  1427 	for (i = 0; i < count; i++) {
       
  1428 	    int fnres;
       
  1429 	    int cures3;
       
  1430 	    Dwarf_Unsigned global_cu_off = 0;
       
  1431 	    char *name = 0;
       
  1432 
       
  1433 	    fnres =
       
  1434 		dwarf_func_name_offsets(funcbuf[i], &name, &die_off,
       
  1435 					&cu_off, &err);
       
  1436 	    deal_with_name_offset_err(dbg, "dwarf_func_name_offsets",
       
  1437 				      name, die_off, fnres, err);
       
  1438 
       
  1439 	    cures3 = dwarf_func_cu_offset(funcbuf[i],
       
  1440 					  &global_cu_off, &err);
       
  1441 	    if (cures3 != DW_DLV_OK) {
       
  1442 		print_error(dbg, "dwarf_global_cu_offset", cures3, err);
       
  1443 	    }
       
  1444 
       
  1445 	    print_pubname_style_entry(dbg,
       
  1446 				      "static-func", name, die_off,
       
  1447 				      cu_off, global_cu_off, maxoff);
       
  1448 
       
  1449 
       
  1450 	    /* print associated die too? */
       
  1451 	    if (check_pubname_attr) {
       
  1452 		Dwarf_Bool has_attr;
       
  1453 		int ares;
       
  1454 		int dres;
       
  1455 		Dwarf_Die die;
       
  1456 
       
  1457 		/* get die at die_off */
       
  1458 		dres = dwarf_offdie(dbg, die_off, &die, &err);
       
  1459 		if (dres != DW_DLV_OK) {
       
  1460 		    print_error(dbg, "dwarf_offdie", dres, err);
       
  1461 		}
       
  1462 
       
  1463 
       
  1464 		ares =
       
  1465 		    dwarf_hasattr(die, DW_AT_external, &has_attr, &err);
       
  1466 		if (ares == DW_DLV_ERROR) {
       
  1467 		    print_error(dbg, "hassattr on DW_AT_external", ares,
       
  1468 				err);
       
  1469 		}
       
  1470 		pubname_attr_result.checks++;
       
  1471 		if (ares == DW_DLV_OK && has_attr) {
       
  1472 		    /* Should the value of flag be examined? */
       
  1473 		} else {
       
  1474 		    pubname_attr_result.errors++;
       
  1475 		    DWARF_CHECK_ERROR2(name,
       
  1476 				       "pubname does not have DW_AT_external")
       
  1477 		}
       
  1478 		dwarf_dealloc(dbg, die, DW_DLA_DIE);
       
  1479 	    }
       
  1480 	}
       
  1481 	dwarf_funcs_dealloc(dbg, funcbuf, count);
       
  1482     }
       
  1483 }				/* print_static_funcs() */
       
  1484 
       
  1485 /* get all the data in .debug_static_vars */
       
  1486 extern void
       
  1487 print_static_vars(Dwarf_Debug dbg)
       
  1488 {
       
  1489     Dwarf_Var *varbuf = NULL;
       
  1490     Dwarf_Signed count = 0;
       
  1491     Dwarf_Signed i = 0;
       
  1492     Dwarf_Off die_off = 0;
       
  1493     Dwarf_Off cu_off = 0;
       
  1494     char *name = 0;
       
  1495     int gvres = 0;
       
  1496 
       
  1497     printf("\n.debug_static_vars\n");
       
  1498     gvres = dwarf_get_vars(dbg, &varbuf, &count, &err);
       
  1499     if (gvres == DW_DLV_ERROR) {
       
  1500 	print_error(dbg, "dwarf_get_vars", gvres, err);
       
  1501     } else if (gvres == DW_DLV_NO_ENTRY) {
       
  1502 	/* no static vars */
       
  1503     } else {
       
  1504 	Dwarf_Unsigned maxoff = get_info_max_offset(dbg);
       
  1505 
       
  1506 	for (i = 0; i < count; i++) {
       
  1507 	    int vnres;
       
  1508 	    int cures3;
       
  1509 	    Dwarf_Off global_cu_off = 0;
       
  1510 
       
  1511 	    vnres =
       
  1512 		dwarf_var_name_offsets(varbuf[i], &name, &die_off,
       
  1513 				       &cu_off, &err);
       
  1514 	    deal_with_name_offset_err(dbg,
       
  1515 				      "dwarf_var_name_offsets",
       
  1516 				      name, die_off, vnres, err);
       
  1517 
       
  1518 	    cures3 = dwarf_var_cu_offset(varbuf[i],
       
  1519 					 &global_cu_off, &err);
       
  1520 	    if (cures3 != DW_DLV_OK) {
       
  1521 		print_error(dbg, "dwarf_global_cu_offset", cures3, err);
       
  1522 	    }
       
  1523 
       
  1524 	    print_pubname_style_entry(dbg,
       
  1525 				      "static-var",
       
  1526 				      name, die_off, cu_off,
       
  1527 				      global_cu_off, maxoff);
       
  1528 
       
  1529 	    /* print associated die too? */
       
  1530 	}
       
  1531 	dwarf_vars_dealloc(dbg, varbuf, count);
       
  1532     }
       
  1533 }				/* print_static_vars */
       
  1534 
       
  1535 /* get all the data in .debug_types */
       
  1536 extern void
       
  1537 print_types(Dwarf_Debug dbg, enum type_type_e type_type)
       
  1538 {
       
  1539     Dwarf_Type *typebuf = NULL;
       
  1540     Dwarf_Signed count = 0;
       
  1541     Dwarf_Signed i = 0;
       
  1542     Dwarf_Off die_off = 0;
       
  1543     Dwarf_Off cu_off = 0;
       
  1544     char *name = NULL;
       
  1545     int gtres = 0;
       
  1546 
       
  1547     char *section_name = NULL;
       
  1548     char *offset_err_name = NULL;
       
  1549     char *section_open_name = NULL;
       
  1550     char *print_name_prefix = NULL;
       
  1551     int (*get_types) (Dwarf_Debug, Dwarf_Type **, Dwarf_Signed *,
       
  1552 		      Dwarf_Error *)
       
  1553 	= 0;
       
  1554     int (*get_offset) (Dwarf_Type, char **, Dwarf_Off *, Dwarf_Off *,
       
  1555 		       Dwarf_Error *) = NULL;
       
  1556     int (*get_cu_offset) (Dwarf_Type, Dwarf_Off *, Dwarf_Error *) =
       
  1557 	NULL;
       
  1558     void (*dealloctype) (Dwarf_Debug, Dwarf_Type *, Dwarf_Signed) =
       
  1559 	NULL;
       
  1560 
       
  1561 
       
  1562     if (type_type == DWARF_PUBTYPES) {
       
  1563 	section_name = ".debug_pubtypes";
       
  1564 	offset_err_name = "dwarf_pubtype_name_offsets";
       
  1565 	section_open_name = "dwarf_get_pubtypes";
       
  1566 	print_name_prefix = "pubtype";
       
  1567 	get_types = dwarf_get_pubtypes;
       
  1568 	get_offset = dwarf_pubtype_name_offsets;
       
  1569 	get_cu_offset = dwarf_pubtype_cu_offset;
       
  1570 	dealloctype = dwarf_pubtypes_dealloc;
       
  1571     } else {
       
  1572 	/* SGI_TYPENAME */
       
  1573 	section_name = ".debug_typenames";
       
  1574 	offset_err_name = "dwarf_type_name_offsets";
       
  1575 	section_open_name = "dwarf_get_types";
       
  1576 	print_name_prefix = "type";
       
  1577 	get_types = dwarf_get_types;
       
  1578 	get_offset = dwarf_type_name_offsets;
       
  1579 	get_cu_offset = dwarf_type_cu_offset;
       
  1580 	dealloctype = dwarf_types_dealloc;
       
  1581     }
       
  1582 
       
  1583 
       
  1584 
       
  1585     gtres = get_types(dbg, &typebuf, &count, &err);
       
  1586     if (gtres == DW_DLV_ERROR) {
       
  1587 	print_error(dbg, section_open_name, gtres, err);
       
  1588     } else if (gtres == DW_DLV_NO_ENTRY) {
       
  1589 	/* no types */
       
  1590     } else {
       
  1591 	Dwarf_Unsigned maxoff = get_info_max_offset(dbg);
       
  1592 
       
  1593 	/* Before July 2005, the section name was printed
       
  1594 	   unconditionally, now only prints if non-empty section really 
       
  1595 	   exists. */
       
  1596 	printf("\n%s\n", section_name);
       
  1597 
       
  1598 	for (i = 0; i < count; i++) {
       
  1599 	    int tnres;
       
  1600 	    int cures3;
       
  1601 	    Dwarf_Off global_cu_off = 0;
       
  1602 
       
  1603 	    tnres =
       
  1604 		get_offset(typebuf[i], &name, &die_off, &cu_off, &err);
       
  1605 	    deal_with_name_offset_err(dbg, offset_err_name, name,
       
  1606 				      die_off, tnres, err);
       
  1607 
       
  1608 	    cures3 = get_cu_offset(typebuf[i], &global_cu_off, &err);
       
  1609 
       
  1610 	    if (cures3 != DW_DLV_OK) {
       
  1611 		print_error(dbg, "dwarf_var_cu_offset", cures3, err);
       
  1612 	    }
       
  1613 	    print_pubname_style_entry(dbg,
       
  1614 				      print_name_prefix,
       
  1615 				      name, die_off, cu_off,
       
  1616 				      global_cu_off, maxoff);
       
  1617 
       
  1618 	    /* print associated die too? */
       
  1619 	}
       
  1620 	dealloctype(dbg, typebuf, count);
       
  1621     }
       
  1622 }				/* print_types() */
       
  1623 
       
  1624 /* get all the data in .debug_weaknames */
       
  1625 extern void
       
  1626 print_weaknames(Dwarf_Debug dbg)
       
  1627 {
       
  1628     Dwarf_Weak *weaknamebuf = NULL;
       
  1629     Dwarf_Signed count = 0;
       
  1630     Dwarf_Signed i = 0;
       
  1631     Dwarf_Off die_off = 0;
       
  1632     Dwarf_Off cu_off = 0;
       
  1633     char *name = NULL;
       
  1634     int wkres = 0;
       
  1635 
       
  1636     printf("\n.debug_weaknames\n");
       
  1637     wkres = dwarf_get_weaks(dbg, &weaknamebuf, &count, &err);
       
  1638     if (wkres == DW_DLV_ERROR) {
       
  1639 	print_error(dbg, "dwarf_get_weaks", wkres, err);
       
  1640     } else if (wkres == DW_DLV_NO_ENTRY) {
       
  1641 	/* no weaknames */
       
  1642     } else {
       
  1643 	Dwarf_Unsigned maxoff = get_info_max_offset(dbg);
       
  1644 
       
  1645 	for (i = 0; i < count; i++) {
       
  1646 	    int tnres;
       
  1647 	    int cures3;
       
  1648 
       
  1649 	    Dwarf_Unsigned global_cu_off = 0;
       
  1650 
       
  1651 	    tnres = dwarf_weak_name_offsets(weaknamebuf[i],
       
  1652 					    &name, &die_off, &cu_off,
       
  1653 					    &err);
       
  1654 	    deal_with_name_offset_err(dbg,
       
  1655 				      "dwarf_weak_name_offsets",
       
  1656 				      name, die_off, tnres, err);
       
  1657 
       
  1658 	    cures3 = dwarf_weak_cu_offset(weaknamebuf[i],
       
  1659 					  &global_cu_off, &err);
       
  1660 
       
  1661 	    if (cures3 != DW_DLV_OK) {
       
  1662 		print_error(dbg, "dwarf_weakname_cu_offset",
       
  1663 			    cures3, err);
       
  1664 	    }
       
  1665 	    print_pubname_style_entry(dbg,
       
  1666 				      "weakname",
       
  1667 				      name, die_off, cu_off,
       
  1668 				      global_cu_off, maxoff);
       
  1669 
       
  1670 	    /* print associated die too? */
       
  1671 	}
       
  1672 	dwarf_weaks_dealloc(dbg, weaknamebuf, count);
       
  1673     }
       
  1674 }				/* print_weaknames() */
       
  1675 
       
  1676 
       
  1677 
       
  1678 /*
       
  1679     decode ULEB
       
  1680 */
       
  1681 Dwarf_Unsigned
       
  1682 local_dwarf_decode_u_leb128(unsigned char *leb128,
       
  1683 			    unsigned int *leb128_length)
       
  1684 {
       
  1685     unsigned char byte = 0;
       
  1686     Dwarf_Unsigned number = 0;
       
  1687     unsigned int shift = 0;
       
  1688     unsigned int byte_length = 1;
       
  1689 
       
  1690     byte = *leb128;
       
  1691     for (;;) {
       
  1692 	number |= (byte & 0x7f) << shift;
       
  1693 	shift += 7;
       
  1694 
       
  1695 	if ((byte & 0x80) == 0) {
       
  1696 	    if (leb128_length != NULL)
       
  1697 		*leb128_length = byte_length;
       
  1698 	    return (number);
       
  1699 	}
       
  1700 
       
  1701 	byte_length++;
       
  1702 	byte = *(++leb128);
       
  1703     }
       
  1704 }
       
  1705 
       
  1706 #define BITSINBYTE 8
       
  1707 Dwarf_Signed
       
  1708 local_dwarf_decode_s_leb128(unsigned char *leb128,
       
  1709 			    unsigned int *leb128_length)
       
  1710 {
       
  1711     Dwarf_Signed number = 0;
       
  1712     Dwarf_Bool sign = 0;
       
  1713     Dwarf_Signed shift = 0;
       
  1714     unsigned char byte = *leb128;
       
  1715     Dwarf_Signed byte_length = 1;
       
  1716 
       
  1717     /* byte_length being the number of bytes of data absorbed so far in
       
  1718        turning the leb into a Dwarf_Signed. */
       
  1719 
       
  1720     for (;;) {
       
  1721 	sign = byte & 0x40;
       
  1722 	number |= ((Dwarf_Signed) ((byte & 0x7f))) << shift;
       
  1723 	shift += 7;
       
  1724 
       
  1725 	if ((byte & 0x80) == 0) {
       
  1726 	    break;
       
  1727 	}
       
  1728 	++leb128;
       
  1729 	byte = *leb128;
       
  1730 	byte_length++;
       
  1731     }
       
  1732 
       
  1733     if ((shift < sizeof(Dwarf_Signed) * BITSINBYTE) && sign) {
       
  1734 	number |= -((Dwarf_Signed) 1 << shift);
       
  1735     }
       
  1736 
       
  1737     if (leb128_length != NULL)
       
  1738 	*leb128_length = byte_length;
       
  1739     return (number);
       
  1740 }
       
  1741 
       
  1742 
       
  1743 /* Dumping a dwarf-expression as a byte stream. */
       
  1744 void
       
  1745 dump_block(char *prefix, char *data, Dwarf_Signed len)
       
  1746 {
       
  1747     char *end_data = data + len;
       
  1748     char *cur = data;
       
  1749     int i = 0;
       
  1750 
       
  1751     printf("%s", prefix);
       
  1752     for (; cur < end_data; ++cur, ++i) {
       
  1753 	if (i > 0 && i % 4 == 0)
       
  1754 	    printf(" ");
       
  1755 	printf("%02x", 0xff & *cur);
       
  1756 
       
  1757     }
       
  1758 }