changeset 13581:eab0c2354e82

2004 newer gcc, and sanity, would benefit from a newer libdwarf Reviewed by: Jason King <jason.brian.king@gmail.com> Reviewed by: Igor Kozhukhov <ikozhukhov@gmail.com> Reviewed by: Dan McDonald <danmcd@nexenta.com> Reviewed by: Joshua M. Clulow <josh@sysmgr.org> Approved by: Gordon Ross <gwr@nexenta.com>
author Richard Lowe <richlowe@richlowe.net>
date Sun, 22 May 2011 03:13:22 +0100
parents e7b96961e15f
children 64b0427edfc3
files usr/src/tools/ctf/dwarf/Makefile.com usr/src/tools/ctf/dwarf/common/acconfig.h usr/src/tools/ctf/dwarf/common/cmplrs/dwarf_addr_finder.h usr/src/tools/ctf/dwarf/common/config.h usr/src/tools/ctf/dwarf/common/dwarf.h usr/src/tools/ctf/dwarf/common/dwarf_abbrev.c usr/src/tools/ctf/dwarf/common/dwarf_abbrev.h usr/src/tools/ctf/dwarf/common/dwarf_addr_finder.c usr/src/tools/ctf/dwarf/common/dwarf_alloc.c usr/src/tools/ctf/dwarf/common/dwarf_alloc.h usr/src/tools/ctf/dwarf/common/dwarf_arange.c usr/src/tools/ctf/dwarf/common/dwarf_arange.h usr/src/tools/ctf/dwarf/common/dwarf_base_types.h usr/src/tools/ctf/dwarf/common/dwarf_die_deliv.c usr/src/tools/ctf/dwarf/common/dwarf_die_deliv.h usr/src/tools/ctf/dwarf/common/dwarf_elf_access.c usr/src/tools/ctf/dwarf/common/dwarf_elf_access.h usr/src/tools/ctf/dwarf/common/dwarf_error.c usr/src/tools/ctf/dwarf/common/dwarf_error.h usr/src/tools/ctf/dwarf/common/dwarf_form.c usr/src/tools/ctf/dwarf/common/dwarf_frame.c usr/src/tools/ctf/dwarf/common/dwarf_frame.h usr/src/tools/ctf/dwarf/common/dwarf_frame2.c usr/src/tools/ctf/dwarf/common/dwarf_frame3.c usr/src/tools/ctf/dwarf/common/dwarf_funcs.c usr/src/tools/ctf/dwarf/common/dwarf_funcs.h usr/src/tools/ctf/dwarf/common/dwarf_global.c usr/src/tools/ctf/dwarf/common/dwarf_global.h usr/src/tools/ctf/dwarf/common/dwarf_harmless.c usr/src/tools/ctf/dwarf/common/dwarf_harmless.h usr/src/tools/ctf/dwarf/common/dwarf_incl.h usr/src/tools/ctf/dwarf/common/dwarf_init_finish.c usr/src/tools/ctf/dwarf/common/dwarf_leb.c usr/src/tools/ctf/dwarf/common/dwarf_line.c usr/src/tools/ctf/dwarf/common/dwarf_line.h usr/src/tools/ctf/dwarf/common/dwarf_line2.c usr/src/tools/ctf/dwarf/common/dwarf_loc.c usr/src/tools/ctf/dwarf/common/dwarf_loc.h usr/src/tools/ctf/dwarf/common/dwarf_macro.c usr/src/tools/ctf/dwarf/common/dwarf_macro.h usr/src/tools/ctf/dwarf/common/dwarf_names.c usr/src/tools/ctf/dwarf/common/dwarf_names.h usr/src/tools/ctf/dwarf/common/dwarf_opaque.h usr/src/tools/ctf/dwarf/common/dwarf_original_elf_init.c usr/src/tools/ctf/dwarf/common/dwarf_print_lines.c usr/src/tools/ctf/dwarf/common/dwarf_pubtypes.c usr/src/tools/ctf/dwarf/common/dwarf_query.c usr/src/tools/ctf/dwarf/common/dwarf_ranges.c usr/src/tools/ctf/dwarf/common/dwarf_sort_line.c usr/src/tools/ctf/dwarf/common/dwarf_string.c usr/src/tools/ctf/dwarf/common/dwarf_stubs.c usr/src/tools/ctf/dwarf/common/dwarf_types.c usr/src/tools/ctf/dwarf/common/dwarf_types.h usr/src/tools/ctf/dwarf/common/dwarf_util.c usr/src/tools/ctf/dwarf/common/dwarf_util.h usr/src/tools/ctf/dwarf/common/dwarf_vars.c usr/src/tools/ctf/dwarf/common/dwarf_vars.h usr/src/tools/ctf/dwarf/common/dwarf_weaks.c usr/src/tools/ctf/dwarf/common/dwarf_weaks.h usr/src/tools/ctf/dwarf/common/libdwarf.h usr/src/tools/ctf/dwarf/common/libdwarfdefs.h usr/src/tools/ctf/dwarf/common/malloc_check.c usr/src/tools/ctf/dwarf/common/malloc_check.h usr/src/tools/ctf/dwarf/common/mapfile-vers usr/src/tools/ctf/dwarf/common/pro_alloc.c usr/src/tools/ctf/dwarf/common/pro_alloc.h usr/src/tools/ctf/dwarf/common/pro_arange.c usr/src/tools/ctf/dwarf/common/pro_arange.h usr/src/tools/ctf/dwarf/common/pro_die.c usr/src/tools/ctf/dwarf/common/pro_die.h usr/src/tools/ctf/dwarf/common/pro_encode_nm.c usr/src/tools/ctf/dwarf/common/pro_encode_nm.h usr/src/tools/ctf/dwarf/common/pro_error.c usr/src/tools/ctf/dwarf/common/pro_error.h usr/src/tools/ctf/dwarf/common/pro_expr.c usr/src/tools/ctf/dwarf/common/pro_expr.h usr/src/tools/ctf/dwarf/common/pro_finish.c usr/src/tools/ctf/dwarf/common/pro_forms.c usr/src/tools/ctf/dwarf/common/pro_frame.c usr/src/tools/ctf/dwarf/common/pro_frame.h usr/src/tools/ctf/dwarf/common/pro_funcs.c usr/src/tools/ctf/dwarf/common/pro_incl.h usr/src/tools/ctf/dwarf/common/pro_init.c usr/src/tools/ctf/dwarf/common/pro_line.c usr/src/tools/ctf/dwarf/common/pro_line.h usr/src/tools/ctf/dwarf/common/pro_macinfo.c usr/src/tools/ctf/dwarf/common/pro_macinfo.h usr/src/tools/ctf/dwarf/common/pro_opaque.h usr/src/tools/ctf/dwarf/common/pro_pubnames.c usr/src/tools/ctf/dwarf/common/pro_reloc.c usr/src/tools/ctf/dwarf/common/pro_reloc.h usr/src/tools/ctf/dwarf/common/pro_reloc_stream.c usr/src/tools/ctf/dwarf/common/pro_reloc_stream.h usr/src/tools/ctf/dwarf/common/pro_reloc_symbolic.c usr/src/tools/ctf/dwarf/common/pro_reloc_symbolic.h usr/src/tools/ctf/dwarf/common/pro_section.c usr/src/tools/ctf/dwarf/common/pro_section.h usr/src/tools/ctf/dwarf/common/pro_types.c usr/src/tools/ctf/dwarf/common/pro_types.h usr/src/tools/ctf/dwarf/common/pro_util.h usr/src/tools/ctf/dwarf/common/pro_vars.c usr/src/tools/ctf/dwarf/common/pro_weaks.c
diffstat 102 files changed, 24822 insertions(+), 13798 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/tools/ctf/dwarf/Makefile.com	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/Makefile.com	Sun May 22 03:13:22 2011 +0100
@@ -9,23 +9,32 @@
 LIBRARY=	libdwarf.a
 VERS=		.1
 
-OBJECTS=	dwarf_abbrev.o		\
+OBJECTS=dwarf_abbrev.o		\
 	dwarf_addr_finder.o	\
 	dwarf_alloc.o		\
 	dwarf_arange.o		\
 	dwarf_die_deliv.o	\
+	dwarf_elf_access.o	\
 	dwarf_error.o		\
 	dwarf_form.o		\
 	dwarf_frame.o		\
+	dwarf_frame2.o		\
+	dwarf_frame3.o		\
 	dwarf_funcs.o		\
 	dwarf_global.o		\
+	dwarf_harmless.o	\
 	dwarf_init_finish.o	\
 	dwarf_leb.o		\
 	dwarf_line.o		\
+	dwarf_line2.o		\
 	dwarf_loc.o		\
 	dwarf_macro.o		\
+	dwarf_names.o		\
+	dwarf_original_elf_init.o	\
 	dwarf_print_lines.o	\
+	dwarf_pubtypes.o	\
 	dwarf_query.o		\
+	dwarf_ranges.o		\
 	dwarf_sort_line.o	\
 	dwarf_string.o		\
 	dwarf_stubs.o		\
@@ -33,6 +42,7 @@
 	dwarf_util.o		\
 	dwarf_vars.o		\
 	dwarf_weaks.o		\
+	malloc_check.o		\
 	pro_alloc.o		\
 	pro_arange.o		\
 	pro_die.o		\
@@ -55,17 +65,15 @@
 	pro_vars.o		\
 	pro_weaks.o
 
-
 include $(SRC)/lib/Makefile.lib
 
 SRCS=	$(PICS:%.o=../common/%.c)
 
-
 FILEMODE	= 0755
 
 SRCDIR = ../common/
 
-CPPFLAGS +=	-I$(SRCDIR)
+CPPFLAGS +=	-I$(SRCDIR) -DELF_TARGET_ALL=1
 
 LDLIBS = -lelf -lc
 
--- a/usr/src/tools/ctf/dwarf/common/acconfig.h	Thu Nov 17 11:20:13 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
-
-  Copyright (C) 2000,2003,2004 Silicon Graphics, Inc.  All Rights Reserved.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of version 2.1 of the GNU Lesser General Public License 
-  as published by the Free Software Foundation.
-
-  This program is distributed in the hope that it would be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-  Further, this software is distributed without any warranty that it is
-  free of the rightful claim of any third person regarding infringement 
-  or the like.  Any license provided herein, whether implied or 
-  otherwise, applies only to this software file.  Patent licenses, if
-  any, provided herein do not apply to combinations of this program with 
-  other software, or any other product whatsoever.  
-
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
-  USA.
-
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
-  Mountain View, CA 94043, or:
-
-  http://www.sgi.com
-
-  For further information regarding this notice, see:
-
-  http://oss.sgi.com/projects/GenInfo/NoticeExplan
-
-*/
-
-
-
-/* Define to 1 if the elf64_getshdr function is in libelf.a */
-#undef HAVE_ELF64_GETSHDR
-
-/* Define to 1 if the elf64_getehdr function is in libelf.a */
-#undef HAVE_ELF64_GETEHDR
-
-
-/* see if __uint32_t is predefined in the compiler */
-#undef HAVE___UINT32_T
-
-/* see if __uint64_t is predefined in the compiler */
-#undef HAVE___UINT64_T
-
-/* Define 1 if sys/types.h defines __uint32_t */
-#undef HAVE___UINT32_T_IN_SYS_TYPES_H
-
-/* Define 1 if  R_IA_64_DIR32LSB is defined (might be enum value) */
-#undef HAVE_R_IA_64_DIR32LSB
-
-/* Define 1 if sys/ia64/elf.h exists*/
-#undef HAVE_SYS_IA64_ELF_H
-
-/* Define 1 if want to build with 32/64bit section offsets for ia64 */
-/* per the dwarf2 committee proposal adopted Dec 1999 */
-#undef HAVE_DWARF2_99_EXTENSION
-
-/* Define 1 if want only 32bit section offsets per pure dwarf2.0.0 spec */
-/* Only one of HAVE_OLD_DWARF2_32BIT_OFFSET or HAVE_DWARF2_99_EXTENSION */
-/* may be defined */
-#undef HAVE_OLD_DWARF2_32BIT_OFFSET
-
--- a/usr/src/tools/ctf/dwarf/common/cmplrs/dwarf_addr_finder.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/cmplrs/dwarf_addr_finder.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
    dwarf_addr_finder.h
-   $Source: /plroot/cmplrs.src/v7.4.2m/.RCS/PL/include/cmplrs/RCS/dwarf_addr_finder.h,v $
+   $Source: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/include/cmplrs/RCS/dwarf_addr_finder.h,v $
    $Date: 2002/06/11 17:49:06 $
 
    Defines user interface.
--- a/usr/src/tools/ctf/dwarf/common/config.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/config.h	Sun May 22 03:13:22 2011 +0100
@@ -1,77 +1,28 @@
-/* config.h.  Generated by configure.  */
+/* config.h.  Generated from config.h.in by configure.  */
 /* config.h.in.  Generated from configure.in by autoheader.  */
-/*
-
-  Copyright (C) 2000,2003,2004 Silicon Graphics, Inc.  All Rights Reserved.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of version 2.1 of the GNU Lesser General Public License
-  as published by the Free Software Foundation.
-
-  This program is distributed in the hope that it would be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-  Further, this software is distributed without any warranty that it is
-  free of the rightful claim of any third person regarding infringement
-  or the like.  Any license provided herein, whether implied or
-  otherwise, applies only to this software file.  Patent licenses, if
-  any, provided herein do not apply to combinations of this program with
-  other software, or any other product whatsoever.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this program; if not, write the Free Software
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
-  USA.
-
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
-  Mountain View, CA 94043, or:
-
-  http://www.sgi.com
-
-  For further information regarding this notice, see:
-
-  http://oss.sgi.com/projects/GenInfo/NoticeExplan
 
-*/
-
-
-
-/* Define to 1 if the elf64_getshdr function is in libelf.a */
-#define HAVE_ELF64_GETSHDR 1
-
-/* Define to 1 if the elf64_getehdr function is in libelf.a */
-#define HAVE_ELF64_GETEHDR 1
-
-
-/* see if __uint32_t is predefined in the compiler */
-/* #undef HAVE___UINT32_T */
-
-/* see if __uint64_t is predefined in the compiler */
-/* #undef HAVE___UINT64_T */
-
-/* Define 1 if sys/types.h defines __uint32_t */
-/* #undef HAVE___UINT32_T_IN_SYS_TYPES_H */
-
-/* Define 1 if  R_IA_64_DIR32LSB is defined (might be enum value) */
-/* #undef HAVE_R_IA_64_DIR32LSB */
-
-/* Define 1 if sys/ia64/elf.h exists*/
-/* #undef HAVE_SYS_IA64_ELF_H */
-
-/* Define 1 if want to build with 32/64bit section offsets for ia64 */
-/* per the dwarf2 committee proposal adopted Dec 1999 */
-/* #undef HAVE_DWARF2_99_EXTENSION */
-
-/* Define 1 if want only 32bit section offsets per pure dwarf2.0.0 spec */
-/* Only one of HAVE_OLD_DWARF2_32BIT_OFFSET or HAVE_DWARF2_99_EXTENSION */
-/* may be defined */
-/* #undef HAVE_OLD_DWARF2_32BIT_OFFSET */
-
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
 
 /* Define to 1 if you have the <alloca.h> header file. */
 #define HAVE_ALLOCA_H 1
 
+/* Define 1 if want to allow producer to build with 32/64bit section offsets
+   per dwarf3 */
+#define HAVE_DWARF2_99_EXTENSION 1
+
+/* Define to 1 if the elf64_getehdr function is in libelf.a. */
+#define HAVE_ELF64_GETEHDR 1
+
+/* Define to 1 if the elf64_getshdr function is in libelf.a. */
+#define HAVE_ELF64_GETSHDR 1
+
+/* Define 1 if Elf64_Rela defined. */
+#define HAVE_ELF64_RELA 1
+
+/* Define 1 if Elf64_Sym defined. */
+#define HAVE_ELF64_SYM 1
+
 /* Define to 1 if you have the <elfaccess.h> header file. */
 /* #undef HAVE_ELFACCESS_H */
 
@@ -87,11 +38,26 @@
 /* Define to 1 if you have the <libelf/libelf.h> header file. */
 /* #undef HAVE_LIBELF_LIBELF_H */
 
+/* Define 1 if off64 is defined via libelf with GNU_SOURCE. */
+#define HAVE_LIBELF_OFF64_OK 1
+
 /* Define to 1 if you have the <memory.h> header file. */
 #define HAVE_MEMORY_H 1
 
-/* Define to 1 if you have the <sgidefs.h> header file. */
-/* #undef HAVE_SGIDEFS_H */
+/* Define 1 if need nonstandard printf format for 64bit */
+/* #undef HAVE_NONSTANDARD_PRINTF_64_FORMAT */
+
+/* Define 1 to default to old DW_FRAME_CFA_COL */
+/* #undef HAVE_OLD_FRAME_CFA_COL */
+
+/* Define 1 if plain libelf builds. */
+#define HAVE_RAW_LIBELF_OK 1
+
+/* Define 1 if R_IA_64_DIR32LSB is defined (might be enum value). */
+/* #undef HAVE_R_IA_64_DIR32LSB */
+
+/* Define 1 if want producer to build with IRIX offset sizes */
+/* #undef HAVE_SGI_IRIX_OFFSETS */
 
 /* Define to 1 if you have the <stdint.h> header file. */
 #define HAVE_STDINT_H 1
@@ -99,6 +65,9 @@
 /* Define to 1 if you have the <stdlib.h> header file. */
 #define HAVE_STDLIB_H 1
 
+/* Define 1 if want producer to build with only 32bit section offsets */
+/* #undef HAVE_STRICT_DWARF2_32BIT_OFFSET */
+
 /* Define to 1 if you have the <strings.h> header file. */
 #define HAVE_STRINGS_H 1
 
@@ -117,6 +86,27 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #define HAVE_UNISTD_H 1
 
+/* Define 1 if want to allow Windows full path detection */
+/* #undef HAVE_WINDOWS_PATH */
+
+/* See if __uint32_t is predefined in the compiler. */
+/* #undef HAVE___UINT32_T */
+
+/* Define 1 if __uint32_t is in sgidefs.h. */
+/* #undef HAVE___UINT32_T_IN_SGIDEFS_H */
+
+/* Define 1 if sys/types.h defines __uint32_t. */
+/* #undef HAVE___UINT32_T_IN_SYS_TYPES_H */
+
+/* See if __uint64_t is predefined in the compiler. */
+/* #undef HAVE___UINT64_T */
+
+/* Define 1 if is in sgidefs.h. */
+/* #undef HAVE___UINT64_T_IN_SGIDEFS_H */
+
+/* Define 1 if sys/types.h defines __uint64_t. */
+/* #undef HAVE___UINT64_T_IN_SYS_TYPES_H */
+
 /* Define to the address where bug reports for this package should be sent. */
 #define PACKAGE_BUGREPORT ""
 
@@ -129,16 +119,25 @@
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME ""
 
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
 /* Define to the version of this package. */
 #define PACKAGE_VERSION ""
 
 /* Define to 1 if you have the ANSI C header files. */
 #define STDC_HEADERS 1
 
-/* Define to 1 if your processor stores words with the most significant byte
-   first (like Motorola and SPARC, unlike Intel and VAX). */
-#if defined(__sparc)
-#define WORDS_BIGENDIAN 1
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
 #else
-#undef WORDS_BIGENDIAN
+# if defined(__sparc)
+#  define WORDS_BIGENDIAN 1
+# else
+#  undef WORDS_BIGENDIAN
+# endif         
 #endif
--- a/usr/src/tools/ctf/dwarf/common/dwarf.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf.h	Sun May 22 03:13:22 2011 +0100
@@ -1,10 +1,7 @@
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
-  Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2001,2003,2004,2005,2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
+  Portions Copyright 2007-2010 David Anderson. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License
@@ -21,12 +18,12 @@
   any, provided herein do not apply to combinations of this program with
   other software, or any other product whatsoever.
 
-  You should have received a copy of the GNU Lesser General Public
-  License along with this program; if not, write the Free Software
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -45,533 +42,814 @@
 #endif
 
 /*
-	dwarf.h   DWARF  debugging information values
-	$Revision: 1.29 $    $Date: 2003/02/05 22:57:01 $    
+        dwarf.h   DWARF  debugging information values
+        $Revision: 1.41 $    $Date: 2006/04/17 00:09:56 $
+
+        The comment "DWARF3" appears where there are
+        new entries from DWARF3 as of 2004, "DWARF3f"
+        where there are new entries as of the November 2005
+        public review document and other comments apply
+        where extension entries appear.
 
-	The comment "DWARF3" appears where there are
-	new entries from DWARF3.
+        Extensions part of DWARF4 are marked DWARF4.
+
+        A few extension names have omitted the 'vendor id'
+        (See chapter 7, "Vendor Extensibility"). Please
+        always use a 'vendor id' string in extension names.
+
+        Vendors should use a vendor string in names and
+        whereever possible avoid duplicating values used by
+        other vendor extensions
 
 */
 
 
-#define DW_TAG_array_type		0x01
-#define DW_TAG_class_type		0x02
-#define DW_TAG_entry_point		0x03
-#define DW_TAG_enumeration_type		0x04
-#define DW_TAG_formal_parameter		0x05
-#define DW_TAG_imported_declaration	0x08
-#define DW_TAG_label			0x0a
-#define DW_TAG_lexical_block		0x0b
-#define DW_TAG_member			0x0d
-#define DW_TAG_pointer_type		0x0f
-#define DW_TAG_reference_type		0x10
-#define DW_TAG_compile_unit		0x11
-#define DW_TAG_string_type		0x12
-#define DW_TAG_structure_type		0x13
-#define DW_TAG_subroutine_type		0x15
-#define DW_TAG_typedef			0x16
-#define DW_TAG_union_type		0x17
-#define DW_TAG_unspecified_parameters	0x18
-#define DW_TAG_variant			0x19
-#define DW_TAG_common_block		0x1a
-#define DW_TAG_common_inclusion		0x1b
-#define DW_TAG_inheritance		0x1c
-#define DW_TAG_inlined_subroutine	0x1d
-#define DW_TAG_module			0x1e
-#define DW_TAG_ptr_to_member_type	0x1f
-#define DW_TAG_set_type			0x20
-#define DW_TAG_subrange_type		0x21
-#define DW_TAG_with_stmt		0x22
-#define DW_TAG_access_declaration	0x23
-#define DW_TAG_base_type		0x24
-#define DW_TAG_catch_block		0x25
-#define DW_TAG_const_type		0x26
-#define DW_TAG_constant			0x27
-#define DW_TAG_enumerator		0x28
-#define DW_TAG_file_type		0x29
-#define DW_TAG_friend			0x2a
-#define DW_TAG_namelist			0x2b
-	/* Previous releases of this header had the following
-	   misspelled with a trailing 's' */
-#define DW_TAG_namelist_item		0x2c /* DWARF3/2 spelling */
-#define DW_TAG_namelist_items		0x2c /* SGI misspelling/typo */
-#define DW_TAG_packed_type		0x2d
-#define DW_TAG_subprogram		0x2e
-	/* The DWARF2 document had two spellings of the following
-	   two TAGs, DWARF3 specifies the longer spelling. */
-#define DW_TAG_template_type_parameter	0x2f /* DWARF3/2 spelling*/
-#define DW_TAG_template_type_param	0x2f /* DWARF2   spelling*/
-#define DW_TAG_template_value_parameter	0x30 /* DWARF3/2 spelling*/
-#define DW_TAG_template_value_param	0x30 /* DWARF2   spelling*/
-#define DW_TAG_thrown_type		0x31
-#define DW_TAG_try_block		0x32
-#define DW_TAG_variant_part		0x33
-#define DW_TAG_variable			0x34
-#define DW_TAG_volatile_type		0x35
-#define DW_TAG_dwarf_procedure		0x36  /* DWARF3 */
-#define DW_TAG_restrict_type		0x37  /* DWARF3 */
-#define DW_TAG_interface_type		0x38  /* DWARF3 */
-#define DW_TAG_namespace		0x39  /* DWARF3 */
-#define DW_TAG_imported_module		0x3a  /* DWARF3 */
-#define DW_TAG_unspecified_type		0x3b  /* DWARF3 */
-#define DW_TAG_partial_unit		0x3c  /* DWARF3 */
-#define DW_TAG_imported_unit		0x3d  /* DWARF3 */
-#define DW_TAG_mutable_type		0x3e  /* DWARF3 */
-#define DW_TAG_lo_user			0x4080
-#define DW_TAG_MIPS_loop		0x4081
-#define DW_TAG_hi_user			0xffff
+#define DW_TAG_array_type               0x01
+#define DW_TAG_class_type               0x02
+#define DW_TAG_entry_point              0x03
+#define DW_TAG_enumeration_type         0x04
+#define DW_TAG_formal_parameter         0x05
+#define DW_TAG_imported_declaration     0x08
+#define DW_TAG_label                    0x0a
+#define DW_TAG_lexical_block            0x0b
+#define DW_TAG_member                   0x0d
+#define DW_TAG_pointer_type             0x0f
+#define DW_TAG_reference_type           0x10
+#define DW_TAG_compile_unit             0x11
+#define DW_TAG_string_type              0x12
+#define DW_TAG_structure_type           0x13
+#define DW_TAG_subroutine_type          0x15
+#define DW_TAG_typedef                  0x16
+#define DW_TAG_union_type               0x17
+#define DW_TAG_unspecified_parameters   0x18
+#define DW_TAG_variant                  0x19
+#define DW_TAG_common_block             0x1a
+#define DW_TAG_common_inclusion         0x1b
+#define DW_TAG_inheritance              0x1c
+#define DW_TAG_inlined_subroutine       0x1d
+#define DW_TAG_module                   0x1e
+#define DW_TAG_ptr_to_member_type       0x1f
+#define DW_TAG_set_type                 0x20
+#define DW_TAG_subrange_type            0x21
+#define DW_TAG_with_stmt                0x22
+#define DW_TAG_access_declaration       0x23
+#define DW_TAG_base_type                0x24
+#define DW_TAG_catch_block              0x25
+#define DW_TAG_const_type               0x26
+#define DW_TAG_constant                 0x27
+#define DW_TAG_enumerator               0x28
+#define DW_TAG_file_type                0x29
+#define DW_TAG_friend                   0x2a
+#define DW_TAG_namelist                 0x2b
+        /* Early releases of this header had the following
+           misspelled with a trailing 's' */
+#define DW_TAG_namelist_item            0x2c /* DWARF3/2 spelling */
+#define DW_TAG_namelist_items           0x2c /* SGI misspelling/typo */
+#define DW_TAG_packed_type              0x2d
+#define DW_TAG_subprogram               0x2e
+        /* The DWARF2 document had two spellings of the following
+           two TAGs, DWARF3 specifies the longer spelling. */
+#define DW_TAG_template_type_parameter  0x2f /* DWARF3/2 spelling*/
+#define DW_TAG_template_type_param      0x2f /* DWARF2   spelling*/
+#define DW_TAG_template_value_parameter 0x30 /* DWARF3/2 spelling*/
+#define DW_TAG_template_value_param     0x30 /* DWARF2   spelling*/
+#define DW_TAG_thrown_type              0x31
+#define DW_TAG_try_block                0x32
+#define DW_TAG_variant_part             0x33
+#define DW_TAG_variable                 0x34
+#define DW_TAG_volatile_type            0x35
+#define DW_TAG_dwarf_procedure          0x36  /* DWARF3 */
+#define DW_TAG_restrict_type            0x37  /* DWARF3 */
+#define DW_TAG_interface_type           0x38  /* DWARF3 */
+#define DW_TAG_namespace                0x39  /* DWARF3 */
+#define DW_TAG_imported_module          0x3a  /* DWARF3 */
+#define DW_TAG_unspecified_type         0x3b  /* DWARF3 */
+#define DW_TAG_partial_unit             0x3c  /* DWARF3 */
+#define DW_TAG_imported_unit            0x3d  /* DWARF3 */
+        /* Do not use DW_TAG_mutable_type */
+#define DW_TAG_mutable_type 0x3e /* Withdrawn from DWARF3 by DWARF3f. */
+#define DW_TAG_condition                0x3f  /* DWARF3f */
+#define DW_TAG_shared_type              0x40  /* DWARF3f */
+#define DW_TAG_type_unit                0x41  /* DWARF4 */
+#define DW_TAG_rvalue_reference_type    0x42  /* DWARF4 */
+#define DW_TAG_template_alias           0x43  /* DWARF4 */
+#define DW_TAG_lo_user                  0x4080
 
-/* The following 3 are GNU extensions 
-   The TAG names are as if the extensions were dwarf standard,
-   not extensions.
-*/
-#define DW_TAG_format_label             0x4101 /* for FORTRAN 77, Fortran 90 */
-#define DW_TAG_function_template        0x4102 /* for C++ */
-#define DW_TAG_class_template           0x4103 /* for C++ */
+#define DW_TAG_MIPS_loop                0x4081
+
+/* HP extensions: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz  */
+#define DW_TAG_HP_array_descriptor      0x4090 /* HP */
+
+/* GNU extensions.  The first 3 missing the GNU_. */
+#define DW_TAG_format_label             0x4101 /* GNU. Fortran. */
+#define DW_TAG_function_template        0x4102 /* GNU. For C++ */
+#define DW_TAG_class_template           0x4103 /* GNU. For C++ */
+#define DW_TAG_GNU_BINCL                0x4104 /* GNU */
+#define DW_TAG_GNU_EINCL                0x4105 /* GNU */
+
 
-/* The following are SUN extensions */
-#define DW_TAG_SUN_function_template	0x4201
-#define DW_TAG_SUN_class_template	0x4202
-#define DW_TAG_SUN_struct_template	0x4203
-#define DW_TAG_SUN_union_template	0x4204
-#define DW_TAG_SUN_virtual_inheritance	0x4205
-#define DW_TAG_SUN_codeflags            0x4206
-#define DW_TAG_SUN_memop_info           0x4207    
-#define DW_TAG_SUN_omp_child_func       0x4208
-    
+/* GNU extension. http://gcc.gnu.org/wiki/TemplateParmsDwarf */
+#define DW_TAG_GNU_template_template_parameter  0x4106 /* GNU */
+#define DW_TAG_GNU_template_template_param      0x4106 /* GNU */
+#define DW_TAG_GNU_template_parameter_pack      0x4107 /* GNU */
+#define DW_TAG_GNU_formal_parameter_pack        0x4108 /* GNU */
+
+/* ALTIUM extensions */
+    /* DSP-C/Starcore __circ qualifier */
+#define DW_TAG_ALTIUM_circ_type         0x5101 /* ALTIUM */
+    /* Starcore __mwa_circ qualifier */ 
+#define DW_TAG_ALTIUM_mwa_circ_type     0x5102 /* ALTIUM */
+    /* Starcore __rev_carry qualifier */
+#define DW_TAG_ALTIUM_rev_carry_type    0x5103 /* ALTIUM */
+    /* M16 __rom qualifier */
+#define DW_TAG_ALTIUM_rom               0x5111 /* ALTIUM */
+
 /* The following 3 are extensions to support UPC */
 #define DW_TAG_upc_shared_type          0x8765 /* UPC */
 #define DW_TAG_upc_strict_type          0x8766 /* UPC */
 #define DW_TAG_upc_relaxed_type         0x8767 /* UPC */
 
-#define DW_children_no			0
-#define DW_children_yes			1
+/* PGI (STMicroelectronics) extensions. */
+#define DW_TAG_PGI_kanji_type           0xa000 /* PGI */
+#define DW_TAG_PGI_interface_block      0xa020 /* PGI */
+/* The following are SUN extensions */
+#define DW_TAG_SUN_function_template    0x4201 /* SUN */
+#define DW_TAG_SUN_class_template       0x4202 /* SUN */
+#define DW_TAG_SUN_struct_template      0x4203 /* SUN */
+#define DW_TAG_SUN_union_template       0x4204 /* SUN */
+#define DW_TAG_SUN_indirect_inheritance 0x4205 /* SUN */
+#define DW_TAG_SUN_codeflags            0x4206 /* SUN */
+#define DW_TAG_SUN_memop_info           0x4207 /* SUN */
+#define DW_TAG_SUN_omp_child_func       0x4208 /* SUN */
+#define DW_TAG_SUN_rtti_descriptor      0x4209 /* SUN */
+#define DW_TAG_SUN_dtor_info            0x420a /* SUN */
+#define DW_TAG_SUN_dtor                 0x420b /* SUN */
+#define DW_TAG_SUN_f90_interface        0x420c /* SUN */
+#define DW_TAG_SUN_fortran_vax_structure 0x420d /* SUN */
+#define DW_TAG_SUN_hi                   0x42ff /* SUN */
+    
+
+#define DW_TAG_hi_user                  0xffff
+
+#define DW_children_no                  0
+#define DW_children_yes                 1
 
 
 
-#define DW_FORM_addr			0x01
-#define DW_FORM_block2			0x03
-#define DW_FORM_block4			0x04
-#define DW_FORM_data2			0x05
-#define DW_FORM_data4			0x06
-#define DW_FORM_data8			0x07
-#define DW_FORM_string			0x08
-#define DW_FORM_block			0x09
-#define DW_FORM_block1			0x0a
-#define DW_FORM_data1			0x0b
-#define DW_FORM_flag			0x0c
-#define DW_FORM_sdata			0x0d
-#define DW_FORM_strp			0x0e
-#define DW_FORM_udata			0x0f
-#define DW_FORM_ref_addr		0x10
-#define DW_FORM_ref1			0x11
-#define DW_FORM_ref2			0x12
-#define DW_FORM_ref4			0x13
-#define DW_FORM_ref8 			0x14
-#define DW_FORM_ref_udata		0x15
-#define DW_FORM_indirect		0x16
+#define DW_FORM_addr                    0x01
+#define DW_FORM_block2                  0x03
+#define DW_FORM_block4                  0x04
+#define DW_FORM_data2                   0x05
+#define DW_FORM_data4                   0x06
+#define DW_FORM_data8                   0x07
+#define DW_FORM_string                  0x08
+#define DW_FORM_block                   0x09
+#define DW_FORM_block1                  0x0a
+#define DW_FORM_data1                   0x0b
+#define DW_FORM_flag                    0x0c
+#define DW_FORM_sdata                   0x0d
+#define DW_FORM_strp                    0x0e
+#define DW_FORM_udata                   0x0f
+#define DW_FORM_ref_addr                0x10
+#define DW_FORM_ref1                    0x11
+#define DW_FORM_ref2                    0x12
+#define DW_FORM_ref4                    0x13
+#define DW_FORM_ref8                    0x14
+#define DW_FORM_ref_udata               0x15
+#define DW_FORM_indirect                0x16
+#define DW_FORM_sec_offset              0x17 /* DWARF4 */
+#define DW_FORM_exprloc                 0x18 /* DWARF4 */
+#define DW_FORM_flag_present            0x19 /* DWARF4 */
+/* 0x1a thru 0x1f were left unused accidentally. Reserved for future use. */
+#define DW_FORM_ref_sig8                0x20 /* DWARF4 */
 
-#define DW_AT_sibling				0x01
-#define DW_AT_location				0x02
-#define DW_AT_name				0x03
-#define DW_AT_ordering				0x09
-#define DW_AT_subscr_data			0x0a
-#define DW_AT_byte_size				0x0b
-#define DW_AT_bit_offset			0x0c
-#define DW_AT_bit_size				0x0d
-#define DW_AT_element_list			0x0f
-#define DW_AT_stmt_list				0x10
-#define DW_AT_low_pc				0x11
-#define DW_AT_high_pc				0x12
-#define DW_AT_language				0x13
-#define DW_AT_member				0x14
-#define DW_AT_discr				0x15
-#define DW_AT_discr_value			0x16
-#define DW_AT_visibility			0x17
-#define DW_AT_import				0x18
-#define DW_AT_string_length			0x19
-#define DW_AT_common_reference			0x1a
-#define DW_AT_comp_dir				0x1b
-#define DW_AT_const_value			0x1c
-#define DW_AT_containing_type			0x1d
-#define DW_AT_default_value			0x1e
-#define DW_AT_inline				0x20
-#define DW_AT_is_optional			0x21
-#define DW_AT_lower_bound			0x22
-#define DW_AT_producer				0x25
-#define DW_AT_prototyped			0x27
-#define DW_AT_return_addr			0x2a
-#define DW_AT_start_scope			0x2c
-#define DW_AT_stride_size			0x2e
-#define DW_AT_upper_bound			0x2f
-#define DW_AT_abstract_origin			0x31
-#define DW_AT_accessibility			0x32
-#define DW_AT_address_class			0x33
-#define DW_AT_artificial			0x34
-#define DW_AT_base_types			0x35
-#define DW_AT_calling_convention		0x36
-#define DW_AT_count				0x37
-#define DW_AT_data_member_location		0x38
-#define DW_AT_decl_column			0x39
-#define DW_AT_decl_file				0x3a
-#define DW_AT_decl_line				0x3b
-#define DW_AT_declaration			0x3c
-#define DW_AT_discr_list			0x3d
-#define DW_AT_encoding				0x3e
-#define DW_AT_external				0x3f
-#define DW_AT_frame_base			0x40
-#define DW_AT_friend				0x41
-#define DW_AT_identifier_case			0x42
-#define DW_AT_macro_info			0x43
-#define DW_AT_namelist_item 			0x44
-#define DW_AT_priority				0x45
-#define DW_AT_segment				0x46
-#define DW_AT_specification			0x47
-#define DW_AT_static_link			0x48
-#define DW_AT_type				0x49
-#define DW_AT_use_location			0x4a
-#define DW_AT_variable_parameter		0x4b
-#define DW_AT_virtuality			0x4c
-#define DW_AT_vtable_elem_location		0x4d
-#define DW_AT_allocated				0x4e /* DWARF3 */
-#define DW_AT_associated			0x4f /* DWARF3 */
-#define DW_AT_data_location			0x50 /* DWARF3 */
-#define DW_AT_stride				0x51 /* DWARF3 */
-#define DW_AT_entry_pc				0x52 /* DWARF3 */
-#define DW_AT_use_UTF8				0x53 /* DWARF3 */
-#define DW_AT_extension				0x54 /* DWARF3 */
-#define DW_AT_ranges				0x55 /* DWARF3 */
-#define DW_AT_trampoline			0x56 /* DWARF3 */
-#define DW_AT_call_column			0x57 /* DWARF3 */
-#define DW_AT_call_file				0x58 /* DWARF3 */
-#define DW_AT_call_line				0x59 /* DWARF3 */
-#define DW_AT_description			0x5a /* DWARF3 */
-#define DW_AT_lo_user				0x2000
-#define DW_AT_MIPS_fde				0x2001
-#define DW_AT_MIPS_loop_begin			0x2002
-#define DW_AT_MIPS_tail_loop_begin		0x2003
-#define DW_AT_MIPS_epilog_begin			0x2004
-#define DW_AT_MIPS_loop_unroll_factor		0x2005
-#define DW_AT_MIPS_software_pipeline_depth	0x2006
-#define DW_AT_MIPS_linkage_name			0x2007
-#define DW_AT_MIPS_stride		        0x2008
-#define DW_AT_MIPS_abstract_name	        0x2009
-#define DW_AT_MIPS_clone_origin		        0x200a
-#define DW_AT_MIPS_has_inlines		        0x200b
-#define DW_AT_MIPS_stride_byte		        0x200c
-#define DW_AT_MIPS_stride_elem		        0x200d
-#define DW_AT_MIPS_ptr_dopetype			0x200e
-#define DW_AT_MIPS_allocatable_dopetype		0x200f
-#define DW_AT_MIPS_assumed_shape_dopetype	0x2010
-#define DW_AT_MIPS_assumed_size			0x2011
+#define DW_AT_sibling                           0x01
+#define DW_AT_location                          0x02
+#define DW_AT_name                              0x03
+#define DW_AT_ordering                          0x09
+#define DW_AT_subscr_data                       0x0a
+#define DW_AT_byte_size                         0x0b
+#define DW_AT_bit_offset                        0x0c
+#define DW_AT_bit_size                          0x0d
+#define DW_AT_element_list                      0x0f
+#define DW_AT_stmt_list                         0x10
+#define DW_AT_low_pc                            0x11
+#define DW_AT_high_pc                           0x12
+#define DW_AT_language                          0x13
+#define DW_AT_member                            0x14
+#define DW_AT_discr                             0x15
+#define DW_AT_discr_value                       0x16
+#define DW_AT_visibility                        0x17
+#define DW_AT_import                            0x18
+#define DW_AT_string_length                     0x19
+#define DW_AT_common_reference                  0x1a
+#define DW_AT_comp_dir                          0x1b
+#define DW_AT_const_value                       0x1c
+#define DW_AT_containing_type                   0x1d
+#define DW_AT_default_value                     0x1e
+#define DW_AT_inline                            0x20
+#define DW_AT_is_optional                       0x21
+#define DW_AT_lower_bound                       0x22
+#define DW_AT_producer                          0x25
+#define DW_AT_prototyped                        0x27
+#define DW_AT_return_addr                       0x2a
+#define DW_AT_start_scope                       0x2c
+#define DW_AT_bit_stride                        0x2e /* DWARF3 name */
+#define DW_AT_stride_size                       0x2e /* DWARF2 name */
+#define DW_AT_upper_bound                       0x2f
+#define DW_AT_abstract_origin                   0x31
+#define DW_AT_accessibility                     0x32
+#define DW_AT_address_class                     0x33
+#define DW_AT_artificial                        0x34
+#define DW_AT_base_types                        0x35
+#define DW_AT_calling_convention                0x36
+#define DW_AT_count                             0x37
+#define DW_AT_data_member_location              0x38
+#define DW_AT_decl_column                       0x39
+#define DW_AT_decl_file                         0x3a
+#define DW_AT_decl_line                         0x3b
+#define DW_AT_declaration                       0x3c
+#define DW_AT_discr_list                        0x3d
+#define DW_AT_encoding                          0x3e
+#define DW_AT_external                          0x3f
+#define DW_AT_frame_base                        0x40
+#define DW_AT_friend                            0x41
+#define DW_AT_identifier_case                   0x42
+#define DW_AT_macro_info                        0x43
+#define DW_AT_namelist_item                     0x44
+#define DW_AT_priority                          0x45
+#define DW_AT_segment                           0x46
+#define DW_AT_specification                     0x47
+#define DW_AT_static_link                       0x48
+#define DW_AT_type                              0x49
+#define DW_AT_use_location                      0x4a
+#define DW_AT_variable_parameter                0x4b
+#define DW_AT_virtuality                        0x4c
+#define DW_AT_vtable_elem_location              0x4d
+#define DW_AT_allocated                         0x4e /* DWARF3 */
+#define DW_AT_associated                        0x4f /* DWARF3 */
+#define DW_AT_data_location                     0x50 /* DWARF3 */
+#define DW_AT_byte_stride                       0x51 /* DWARF3f */
+#define DW_AT_stride                            0x51 /* DWARF3 (do not use) */
+#define DW_AT_entry_pc                          0x52 /* DWARF3 */
+#define DW_AT_use_UTF8                          0x53 /* DWARF3 */
+#define DW_AT_extension                         0x54 /* DWARF3 */
+#define DW_AT_ranges                            0x55 /* DWARF3 */
+#define DW_AT_trampoline                        0x56 /* DWARF3 */
+#define DW_AT_call_column                       0x57 /* DWARF3 */
+#define DW_AT_call_file                         0x58 /* DWARF3 */
+#define DW_AT_call_line                         0x59 /* DWARF3 */
+#define DW_AT_description                       0x5a /* DWARF3 */
+#define DW_AT_binary_scale                      0x5b /* DWARF3f */
+#define DW_AT_decimal_scale                     0x5c /* DWARF3f */
+#define DW_AT_small                             0x5d /* DWARF3f */
+#define DW_AT_decimal_sign                      0x5e /* DWARF3f */
+#define DW_AT_digit_count                       0x5f /* DWARF3f */
+#define DW_AT_picture_string                    0x60 /* DWARF3f */
+#define DW_AT_mutable                           0x61 /* DWARF3f */
+#define DW_AT_threads_scaled                    0x62 /* DWARF3f */
+#define DW_AT_explicit                          0x63 /* DWARF3f */
+#define DW_AT_object_pointer                    0x64 /* DWARF3f */
+#define DW_AT_endianity                         0x65 /* DWARF3f */
+#define DW_AT_elemental                         0x66 /* DWARF3f */
+#define DW_AT_pure                              0x67 /* DWARF3f */
+#define DW_AT_recursive                         0x68 /* DWARF3f */
+#define DW_AT_signature                         0x69 /* DWARF4 */
+#define DW_AT_main_subprogram                   0x6a /* DWARF4 */
+#define DW_AT_data_bit_offset                   0x6b /* DWARF4 */
+#define DW_AT_const_expr                        0x6c /* DWARF4 */
+#define DW_AT_enum_class                        0x6d /* DWARF4 */
+#define DW_AT_linkage_name                      0x6e /* DWARF4 */
+
+/* In extensions, we attempt to include the vendor extension
+   in the name even when the vendor leaves it out. */
+
+/* HP extensions. */
+#define DW_AT_HP_block_index                    0x2000  /* HP */
 
+/* Follows extension so dwarfdump prints the most-likely-useful name. */
+#define DW_AT_lo_user                           0x2000
 
-/* GNU extensions, currently not used in dwarf2 by egcs 
-   Mostly dwarf1 extensions not needed in dwarf2?
-*/
-#define DW_AT_sf_names                          0x2101
-#define DW_AT_src_info                          0x2102
-#define DW_AT_mac_info                          0x2103
-#define DW_AT_src_coords                        0x2104
-#define DW_AT_body_begin                        0x2105
-#define DW_AT_body_end                          0x2106
+#define DW_AT_MIPS_fde                          0x2001 /* MIPS/SGI */
+#define DW_AT_MIPS_loop_begin                   0x2002 /* MIPS/SGI */
+#define DW_AT_MIPS_tail_loop_begin              0x2003 /* MIPS/SGI */
+#define DW_AT_MIPS_epilog_begin                 0x2004 /* MIPS/SGI */
+#define DW_AT_MIPS_loop_unroll_factor           0x2005 /* MIPS/SGI */
+#define DW_AT_MIPS_software_pipeline_depth      0x2006 /* MIPS/SGI */
+#define DW_AT_MIPS_linkage_name                 0x2007 /* MIPS/SGI, GNU, and others.*/
+#define DW_AT_MIPS_stride                       0x2008 /* MIPS/SGI */
+#define DW_AT_MIPS_abstract_name                0x2009 /* MIPS/SGI */
+#define DW_AT_MIPS_clone_origin                 0x200a /* MIPS/SGI */
+#define DW_AT_MIPS_has_inlines                  0x200b /* MIPS/SGI */
+#define DW_AT_MIPS_stride_byte                  0x200c /* MIPS/SGI */
+#define DW_AT_MIPS_stride_elem                  0x200d /* MIPS/SGI */
+#define DW_AT_MIPS_ptr_dopetype                 0x200e /* MIPS/SGI */
+#define DW_AT_MIPS_allocatable_dopetype         0x200f /* MIPS/SGI */
+#define DW_AT_MIPS_assumed_shape_dopetype       0x2010 /* MIPS/SGI */
+#define DW_AT_MIPS_assumed_size                 0x2011 /* MIPS/SGI */
+
+/* HP extensions. */
+#define DW_AT_HP_unmodifiable                   0x2001 /* conflict: MIPS */
+#define DW_AT_HP_actuals_stmt_list              0x2010 /* conflict: MIPS */
+#define DW_AT_HP_proc_per_section               0x2011 /* conflict: MIPS */
+#define DW_AT_HP_raw_data_ptr                   0x2012 /* HP */
+#define DW_AT_HP_pass_by_reference              0x2013 /* HP */
+#define DW_AT_HP_opt_level                      0x2014 /* HP */
+#define DW_AT_HP_prof_version_id                0x2015 /* HP */
+#define DW_AT_HP_opt_flags                      0x2016 /* HP */
+#define DW_AT_HP_cold_region_low_pc             0x2017 /* HP */
+#define DW_AT_HP_cold_region_high_pc            0x2018 /* HP */
+#define DW_AT_HP_all_variables_modifiable       0x2019 /* HP */
+#define DW_AT_HP_linkage_name                   0x201a /* HP */
+#define DW_AT_HP_prof_flags                     0x201b /* HP */
+
+#define DW_AT_CPQ_discontig_ranges              0x2001 /* COMPAQ/HP */
+#define DW_AT_CPQ_semantic_events               0x2002 /* COMPAQ/HP */
+#define DW_AT_CPQ_split_lifetimes_var           0x2003 /* COMPAQ/HP */
+#define DW_AT_CPQ_split_lifetimes_rtn           0x2004 /* COMPAQ/HP */
+#define DW_AT_CPQ_prologue_length               0x2005 /* COMPAQ/HP */
+
+#define DW_AT_INTEL_other_endian                0x2026 /* Intel, 1 if byte swapped. */
+
+/* GNU extensions. */
+#define DW_AT_sf_names                          0x2101 /* GNU */
+#define DW_AT_src_info                          0x2102 /* GNU */
+#define DW_AT_mac_info                          0x2103 /* GNU */
+#define DW_AT_src_coords                        0x2104 /* GNU */
+#define DW_AT_body_begin                        0x2105 /* GNU */
+#define DW_AT_body_end                          0x2106 /* GNU */
+#define DW_AT_GNU_vector                        0x2107 /* GNU */
+#define DW_AT_GNU_template_name                 0x2108 /* GNU */
+
+/* ALTIUM extension: ALTIUM Compliant location lists (flag) */
+#define DW_AT_ALTIUM_loclist    0x2300          /* ALTIUM  */
+
+/* Sun extensions */
+#define DW_AT_SUN_template                      0x2201 /* SUN */
+#define DW_AT_VMS_rtnbeg_pd_address             0x2201 /* VMS */
+#define DW_AT_SUN_alignment                     0x2202 /* SUN */
+#define DW_AT_SUN_vtable                        0x2203 /* SUN */
+#define DW_AT_SUN_count_guarantee               0x2204 /* SUN */
+#define DW_AT_SUN_command_line                  0x2205 /* SUN */
+#define DW_AT_SUN_vbase                         0x2206 /* SUN */
+#define DW_AT_SUN_compile_options               0x2207 /* SUN */
+#define DW_AT_SUN_language                      0x2208 /* SUN */
+#define DW_AT_SUN_browser_file                  0x2209 /* SUN */
+#define DW_AT_SUN_vtable_abi                    0x2210 /* SUN */
+#define DW_AT_SUN_func_offsets                  0x2211 /* SUN */
+#define DW_AT_SUN_cf_kind                       0x2212 /* SUN */
+#define DW_AT_SUN_vtable_index                  0x2213 /* SUN */
+#define DW_AT_SUN_omp_tpriv_addr                0x2214 /* SUN */
+#define DW_AT_SUN_omp_child_func                0x2215 /* SUN */
+#define DW_AT_SUN_func_offset                   0x2216 /* SUN */
+#define DW_AT_SUN_memop_type_ref                0x2217 /* SUN */
+#define DW_AT_SUN_profile_id                    0x2218 /* SUN */
+#define DW_AT_SUN_memop_signature               0x2219 /* SUN */
+#define DW_AT_SUN_obj_dir                       0x2220 /* SUN */
+#define DW_AT_SUN_obj_file                      0x2221 /* SUN */
+#define DW_AT_SUN_original_name                 0x2222 /* SUN */
+#define DW_AT_SUN_hwcprof_signature             0x2223 /* SUN */
+#define DW_AT_SUN_amd64_parmdump                0x2224 /* SUN */
+#define DW_AT_SUN_part_link_name                0x2225 /* SUN */
+#define DW_AT_SUN_link_name                     0x2226 /* SUN */
+#define DW_AT_SUN_pass_with_const               0x2227 /* SUN */
+#define DW_AT_SUN_return_with_const             0x2228 /* SUN */
+#define DW_AT_SUN_import_by_name                0x2229 /* SUN */
+#define DW_AT_SUN_f90_pointer                   0x222a /* SUN */
+#define DW_AT_SUN_pass_by_ref                   0x222b /* SUN */
+#define DW_AT_SUN_f90_allocatable               0x222c /* SUN */
+#define DW_AT_SUN_f90_assumed_shape_array       0x222d /* SUN */
+#define DW_AT_SUN_c_vla                         0x222e /* SUN */
+#define DW_AT_SUN_return_value_ptr              0x2230 /* SUN */
+#define DW_AT_SUN_dtor_start                    0x2231 /* SUN */
+#define DW_AT_SUN_dtor_length                   0x2232 /* SUN */
+#define DW_AT_SUN_dtor_state_initial            0x2233 /* SUN */
+#define DW_AT_SUN_dtor_state_final              0x2234 /* SUN */
+#define DW_AT_SUN_dtor_state_deltas             0x2235 /* SUN */
+#define DW_AT_SUN_import_by_lname               0x2236 /* SUN */
+#define DW_AT_SUN_f90_use_only                  0x2237 /* SUN */
+#define DW_AT_SUN_namelist_spec                 0x2238 /* SUN */
+#define DW_AT_SUN_is_omp_child_func             0x2239 /* SUN */
+#define DW_AT_SUN_fortran_main_alias            0x223a /* SUN */
+#define DW_AT_SUN_fortran_based                 0x223b /* SUN */
+
 /* UPC extension */
 #define DW_AT_upc_threads_scaled                0x3210 /* UPC */
 
-/* Sun extensions */
-#define DW_AT_SUN_template			0x2201
-#define DW_AT_SUN_alignment			0x2202
-#define DW_AT_SUN_vtable			0x2203
-#define DW_AT_SUN_count_guarantee		0x2204
-#define DW_AT_SUN_command_line			0x2205
-#define DW_AT_SUN_vbase				0x2206
-#define DW_AT_SUN_compile_options		0x2207
-#define DW_AT_SUN_language			0x2208
-#define DW_AT_SUN_browser_file			0x2209
-#define DW_AT_SUN_vtable_abi                    0x2210
-#define DW_AT_SUN_func_offsets                  0x2211
-#define DW_AT_SUN_cf_kind                       0x2212
-#define DW_AT_SUN_vtable_index                  0x2213
-#define DW_AT_SUN_omp_tpriv_addr                0x2214
-#define DW_AT_SUN_omp_child_func                0x2215
-#define DW_AT_SUN_func_offset                   0x2216
-#define DW_AT_SUN_memop_type_ref                0x2217
-#define DW_AT_SUN_profile_id                    0x2218
-#define DW_AT_SUN_memop_signature               0x2219
-#define DW_AT_SUN_obj_dir                       0x2220
-#define DW_AT_SUN_obj_file                      0x2221    
-#define DW_AT_SUN_original_name                 0x2222
-    
+/* PGI (STMicroelectronics) extensions. */
+#define DW_AT_PGI_lbase                         0x3a00 /* PGI. Block, constant, reference. This attribute is an ASTPLAB extension used to describe the array local base.  */
+#define DW_AT_PGI_soffset                       0x3a01  /* PGI. Block, constant, reference. ASTPLAB adds this attribute to describe the section offset, or the offset to the first element in the dimension. */ 
+#define DW_AT_PGI_lstride                       0x3a02  /* PGI. Block, constant, reference. ASTPLAB adds this attribute to describe the linear stride or the distance between elements in the dimension. */
 
-#define DW_AT_hi_user				0x3fff
+/* Apple Extensions for closures  */
+#define DW_AT_APPLE_closure                     0x3fe4 /* Apple */
+/* Apple Extensions for Objective-C runtime info */
+#define DW_AT_APPLE_major_runtime_vers          0x3fe5 /* Apple */
+#define DW_AT_APPLE_runtime_class               0x3fe6 /* Apple */
+
+
+#define DW_AT_hi_user                           0x3fff
 
-#define DW_OP_addr			0x03
-#define DW_OP_deref			0x06
-#define DW_OP_const1u			0x08
-#define DW_OP_const1s			0x09
-#define DW_OP_const2u			0x0a
-#define DW_OP_const2s			0x0b
-#define DW_OP_const4u			0x0c
-#define DW_OP_const4s			0x0d
-#define DW_OP_const8u			0x0e
-#define DW_OP_const8s			0x0f
-#define DW_OP_constu			0x10
-#define DW_OP_consts			0x11
-#define DW_OP_dup			0x12
-#define DW_OP_drop			0x13
-#define DW_OP_over			0x14
-#define DW_OP_pick			0x15
-#define DW_OP_swap			0x16
-#define DW_OP_rot			0x17
-#define DW_OP_xderef			0x18
-#define DW_OP_abs			0x19
-#define DW_OP_and			0x1a
-#define DW_OP_div			0x1b
-#define DW_OP_minus			0x1c
-#define DW_OP_mod			0x1d
-#define DW_OP_mul			0x1e
-#define DW_OP_neg			0x1f
-#define DW_OP_not			0x20
-#define DW_OP_or			0x21
-#define DW_OP_plus			0x22
-#define DW_OP_plus_uconst		0x23
-#define DW_OP_shl			0x24
-#define DW_OP_shr			0x25
-#define DW_OP_shra			0x26
-#define DW_OP_xor			0x27
-#define DW_OP_bra			0x28
-#define DW_OP_eq			0x29
-#define DW_OP_ge			0x2a 
-#define DW_OP_gt			0x2b
-#define DW_OP_le			0x2c
-#define DW_OP_lt			0x2d
-#define DW_OP_ne			0x2e 
-#define DW_OP_skip			0x2f
-#define DW_OP_lit0			0x30
-#define DW_OP_lit1			0x31 
-#define DW_OP_lit2			0x32
-#define DW_OP_lit3			0x33
-#define DW_OP_lit4			0x34
-#define DW_OP_lit5			0x35
-#define DW_OP_lit6			0x36
-#define DW_OP_lit7			0x37
-#define DW_OP_lit8			0x38
-#define DW_OP_lit9			0x39
-#define DW_OP_lit10			0x3a
-#define DW_OP_lit11			0x3b
-#define DW_OP_lit12			0x3c
-#define DW_OP_lit13			0x3d
-#define DW_OP_lit14			0x3e
-#define DW_OP_lit15			0x3f
-#define DW_OP_lit16			0x40
-#define DW_OP_lit17			0x41
-#define DW_OP_lit18			0x42
-#define DW_OP_lit19			0x43
-#define DW_OP_lit20			0x44
-#define DW_OP_lit21			0x45
-#define DW_OP_lit22			0x46
-#define DW_OP_lit23			0x47
-#define DW_OP_lit24			0x48
-#define DW_OP_lit25			0x49
-#define DW_OP_lit26			0x4a
-#define DW_OP_lit27			0x4b
-#define DW_OP_lit28			0x4c
-#define DW_OP_lit29			0x4d
-#define DW_OP_lit30			0x4e
-#define DW_OP_lit31			0x4f
-#define DW_OP_reg0			0x50
-#define DW_OP_reg1			0x51
-#define DW_OP_reg2			0x52
-#define DW_OP_reg3			0x53
-#define DW_OP_reg4			0x54
-#define DW_OP_reg5			0x55
-#define DW_OP_reg6			0x56
-#define DW_OP_reg7			0x57
-#define DW_OP_reg8			0x58
-#define DW_OP_reg9			0x59
-#define DW_OP_reg10			0x5a
-#define DW_OP_reg11			0x5b
-#define DW_OP_reg12			0x5c
-#define DW_OP_reg13			0x5d
-#define DW_OP_reg14			0x5e
-#define DW_OP_reg15			0x5f
-#define DW_OP_reg16			0x60
-#define DW_OP_reg17			0x61
-#define DW_OP_reg18			0x62
-#define DW_OP_reg19			0x63
-#define DW_OP_reg20			0x64
-#define DW_OP_reg21			0x65
-#define DW_OP_reg22			0x66
-#define DW_OP_reg23			0x67
-#define DW_OP_reg24			0x68
-#define DW_OP_reg25			0x69
-#define DW_OP_reg26			0x6a
-#define DW_OP_reg27			0x6b
-#define DW_OP_reg28			0x6c
-#define DW_OP_reg29			0x6d
-#define DW_OP_reg30			0x6e
-#define DW_OP_reg31			0x6f
-#define DW_OP_breg0			0x70
-#define DW_OP_breg1			0x71
-#define DW_OP_breg2			0x72
-#define DW_OP_breg3			0x73
-#define DW_OP_breg4			0x74
-#define DW_OP_breg5			0x75
-#define DW_OP_breg6			0x76
-#define DW_OP_breg7			0x77
-#define DW_OP_breg8			0x78
-#define DW_OP_breg9			0x79
-#define DW_OP_breg10			0x7a
-#define DW_OP_breg11			0x7b
-#define DW_OP_breg12			0x7c
-#define DW_OP_breg13			0x7d
-#define DW_OP_breg14			0x7e
-#define DW_OP_breg15			0x7f
-#define DW_OP_breg16			0x80
-#define DW_OP_breg17			0x81
-#define DW_OP_breg18			0x82
-#define DW_OP_breg19			0x83
-#define DW_OP_breg20			0x84
-#define DW_OP_breg21			0x85
-#define DW_OP_breg22			0x86
-#define DW_OP_breg23			0x87
-#define DW_OP_breg24			0x88
-#define DW_OP_breg25			0x89
-#define DW_OP_breg26			0x8a
-#define DW_OP_breg27			0x8b
-#define DW_OP_breg28			0x8c
-#define DW_OP_breg29			0x8d
-#define DW_OP_breg30			0x8e
-#define DW_OP_breg31			0x8f
-#define DW_OP_regx			0x90
-#define DW_OP_fbreg			0x91
-#define DW_OP_bregx			0x92
-#define DW_OP_piece			0x93
-#define DW_OP_deref_size		0x94
-#define DW_OP_xderef_size		0x95
-#define DW_OP_nop			0x96
-#define DW_OP_push_object_address	0x97 /* DWARF3 */
-#define DW_OP_call2			0x98 /* DWARF3 */
-#define DW_OP_call4			0x99 /* DWARF3 */
-#define DW_OP_call_ref			0x9a /* DWARF3 */
-#define DW_OP_lo_user			0xe0
-#define DW_OP_hi_user			0xff
+#define DW_OP_addr                      0x03
+#define DW_OP_deref                     0x06
+#define DW_OP_const1u                   0x08
+#define DW_OP_const1s                   0x09
+#define DW_OP_const2u                   0x0a
+#define DW_OP_const2s                   0x0b
+#define DW_OP_const4u                   0x0c
+#define DW_OP_const4s                   0x0d
+#define DW_OP_const8u                   0x0e
+#define DW_OP_const8s                   0x0f
+#define DW_OP_constu                    0x10
+#define DW_OP_consts                    0x11
+#define DW_OP_dup                       0x12
+#define DW_OP_drop                      0x13
+#define DW_OP_over                      0x14
+#define DW_OP_pick                      0x15
+#define DW_OP_swap                      0x16
+#define DW_OP_rot                       0x17
+#define DW_OP_xderef                    0x18
+#define DW_OP_abs                       0x19
+#define DW_OP_and                       0x1a
+#define DW_OP_div                       0x1b
+#define DW_OP_minus                     0x1c
+#define DW_OP_mod                       0x1d
+#define DW_OP_mul                       0x1e
+#define DW_OP_neg                       0x1f
+#define DW_OP_not                       0x20
+#define DW_OP_or                        0x21
+#define DW_OP_plus                      0x22
+#define DW_OP_plus_uconst               0x23
+#define DW_OP_shl                       0x24
+#define DW_OP_shr                       0x25
+#define DW_OP_shra                      0x26
+#define DW_OP_xor                       0x27
+#define DW_OP_bra                       0x28
+#define DW_OP_eq                        0x29
+#define DW_OP_ge                        0x2a
+#define DW_OP_gt                        0x2b
+#define DW_OP_le                        0x2c
+#define DW_OP_lt                        0x2d
+#define DW_OP_ne                        0x2e
+#define DW_OP_skip                      0x2f
+#define DW_OP_lit0                      0x30
+#define DW_OP_lit1                      0x31
+#define DW_OP_lit2                      0x32
+#define DW_OP_lit3                      0x33
+#define DW_OP_lit4                      0x34
+#define DW_OP_lit5                      0x35
+#define DW_OP_lit6                      0x36
+#define DW_OP_lit7                      0x37
+#define DW_OP_lit8                      0x38
+#define DW_OP_lit9                      0x39
+#define DW_OP_lit10                     0x3a
+#define DW_OP_lit11                     0x3b
+#define DW_OP_lit12                     0x3c
+#define DW_OP_lit13                     0x3d
+#define DW_OP_lit14                     0x3e
+#define DW_OP_lit15                     0x3f
+#define DW_OP_lit16                     0x40
+#define DW_OP_lit17                     0x41
+#define DW_OP_lit18                     0x42
+#define DW_OP_lit19                     0x43
+#define DW_OP_lit20                     0x44
+#define DW_OP_lit21                     0x45
+#define DW_OP_lit22                     0x46
+#define DW_OP_lit23                     0x47
+#define DW_OP_lit24                     0x48
+#define DW_OP_lit25                     0x49
+#define DW_OP_lit26                     0x4a
+#define DW_OP_lit27                     0x4b
+#define DW_OP_lit28                     0x4c
+#define DW_OP_lit29                     0x4d
+#define DW_OP_lit30                     0x4e
+#define DW_OP_lit31                     0x4f
+#define DW_OP_reg0                      0x50
+#define DW_OP_reg1                      0x51
+#define DW_OP_reg2                      0x52
+#define DW_OP_reg3                      0x53
+#define DW_OP_reg4                      0x54
+#define DW_OP_reg5                      0x55
+#define DW_OP_reg6                      0x56
+#define DW_OP_reg7                      0x57
+#define DW_OP_reg8                      0x58
+#define DW_OP_reg9                      0x59
+#define DW_OP_reg10                     0x5a
+#define DW_OP_reg11                     0x5b
+#define DW_OP_reg12                     0x5c
+#define DW_OP_reg13                     0x5d
+#define DW_OP_reg14                     0x5e
+#define DW_OP_reg15                     0x5f
+#define DW_OP_reg16                     0x60
+#define DW_OP_reg17                     0x61
+#define DW_OP_reg18                     0x62
+#define DW_OP_reg19                     0x63
+#define DW_OP_reg20                     0x64
+#define DW_OP_reg21                     0x65
+#define DW_OP_reg22                     0x66
+#define DW_OP_reg23                     0x67
+#define DW_OP_reg24                     0x68
+#define DW_OP_reg25                     0x69
+#define DW_OP_reg26                     0x6a
+#define DW_OP_reg27                     0x6b
+#define DW_OP_reg28                     0x6c
+#define DW_OP_reg29                     0x6d
+#define DW_OP_reg30                     0x6e
+#define DW_OP_reg31                     0x6f
+#define DW_OP_breg0                     0x70
+#define DW_OP_breg1                     0x71
+#define DW_OP_breg2                     0x72
+#define DW_OP_breg3                     0x73
+#define DW_OP_breg4                     0x74
+#define DW_OP_breg5                     0x75
+#define DW_OP_breg6                     0x76
+#define DW_OP_breg7                     0x77
+#define DW_OP_breg8                     0x78
+#define DW_OP_breg9                     0x79
+#define DW_OP_breg10                    0x7a
+#define DW_OP_breg11                    0x7b
+#define DW_OP_breg12                    0x7c
+#define DW_OP_breg13                    0x7d
+#define DW_OP_breg14                    0x7e
+#define DW_OP_breg15                    0x7f
+#define DW_OP_breg16                    0x80
+#define DW_OP_breg17                    0x81
+#define DW_OP_breg18                    0x82
+#define DW_OP_breg19                    0x83
+#define DW_OP_breg20                    0x84
+#define DW_OP_breg21                    0x85
+#define DW_OP_breg22                    0x86
+#define DW_OP_breg23                    0x87
+#define DW_OP_breg24                    0x88
+#define DW_OP_breg25                    0x89
+#define DW_OP_breg26                    0x8a
+#define DW_OP_breg27                    0x8b
+#define DW_OP_breg28                    0x8c
+#define DW_OP_breg29                    0x8d
+#define DW_OP_breg30                    0x8e
+#define DW_OP_breg31                    0x8f
+#define DW_OP_regx                      0x90
+#define DW_OP_fbreg                     0x91
+#define DW_OP_bregx                     0x92
+#define DW_OP_piece                     0x93
+#define DW_OP_deref_size                0x94
+#define DW_OP_xderef_size               0x95
+#define DW_OP_nop                       0x96
+#define DW_OP_push_object_address       0x97 /* DWARF3 */
+#define DW_OP_call2                     0x98 /* DWARF3 */
+#define DW_OP_call4                     0x99 /* DWARF3 */
+#define DW_OP_call_ref                  0x9a /* DWARF3 */
+#define DW_OP_form_tls_address          0x9b /* DWARF3f */
+#define DW_OP_call_frame_cfa            0x9c /* DWARF3f */
+#define DW_OP_bit_piece                 0x9d /* DWARF3f */
+#define DW_OP_implicit_value            0x9e /* DWARF4 */
+#define DW_OP_stack_value               0x9f /* DWARF4 */
 
-#define DW_ATE_address			0x1
-#define DW_ATE_boolean			0x2
-#define DW_ATE_complex_float		0x3
-#define DW_ATE_float			0x4
-#define DW_ATE_signed			0x5
-#define DW_ATE_signed_char		0x6
-#define DW_ATE_unsigned			0x7
-#define DW_ATE_unsigned_char		0x8
-#define DW_ATE_imaginary_float		0x9  /* DWARF3 */
-#define DW_ATE_lo_user			0x80
+
+    /* GNU extensions. */
+#define DW_OP_GNU_push_tls_address      0xe0 /* GNU */
+
+/* Follows extension so dwarfdump prints the most-likely-useful name. */
+#define DW_OP_lo_user                   0xe0
+
+    /* HP extensions. */
+#define DW_OP_HP_unknown                0xe0 /* HP conflict: GNU */
+#define DW_OP_HP_is_value               0xe1 /* HP */
+#define DW_OP_HP_fltconst4              0xe2 /* HP */
+#define DW_OP_HP_fltconst8              0xe3 /* HP */
+#define DW_OP_HP_mod_range              0xe4 /* HP */
+#define DW_OP_HP_unmod_range            0xe5 /* HP */
+#define DW_OP_HP_tls                    0xe6 /* HP */
+
+#define DW_OP_INTEL_bit_piece           0xe8 /* Intel: made obsolete by DW_OP_bit_piece above. */
+
+
+   /* Apple extension. */
+#define DW_OP_APPLE_uninit              0xf0 /* Apple */ 
+
+#define DW_OP_hi_user                   0xff
+
+#define DW_ATE_address                  0x1
+#define DW_ATE_boolean                  0x2
+#define DW_ATE_complex_float            0x3
+#define DW_ATE_float                    0x4
+#define DW_ATE_signed                   0x5
+#define DW_ATE_signed_char              0x6
+#define DW_ATE_unsigned                 0x7
+#define DW_ATE_unsigned_char            0x8
+#define DW_ATE_imaginary_float          0x9  /* DWARF3 */
+#define DW_ATE_packed_decimal           0xa  /* DWARF3f */
+#define DW_ATE_numeric_string           0xb  /* DWARF3f */
+#define DW_ATE_edited                   0xc  /* DWARF3f */
+#define DW_ATE_signed_fixed             0xd  /* DWARF3f */
+#define DW_ATE_unsigned_fixed           0xe  /* DWARF3f */
+#define DW_ATE_decimal_float            0xf  /* DWARF3f */
+
+
+/* ALTIUM extensions. x80, x81 */
+#define DW_ATE_ALTIUM_fract           0x80 /* ALTIUM __fract type */
+
+/* Follows extension so dwarfdump prints the most-likely-useful name. */
+#define DW_ATE_lo_user                  0x80
+
+/* Shown here to help dwarfdump build script. */
+#define DW_ATE_ALTIUM_accum           0x81 /* ALTIUM __accum type */
+
+/* HP Floating point extensions. */
+#define DW_ATE_HP_float80             0x80 /* (80 bit). HP */
+
+
+#define DW_ATE_HP_complex_float80     0x81 /* Complex (80 bit). HP  */
+#define DW_ATE_HP_float128            0x82 /* (128 bit). HP */
+#define DW_ATE_HP_complex_float128    0x83 /* Complex (128 bit). HP */
+#define DW_ATE_HP_floathpintel        0x84 /* (82 bit IA64). HP */
+#define DW_ATE_HP_imaginary_float80   0x85 /* HP */
+#define DW_ATE_HP_imaginary_float128  0x86 /* HP */
 
 /* Sun extensions */
 #define DW_ATE_SUN_interval_float       0x91
 #define DW_ATE_SUN_imaginary_float      0x92 /* Obsolete: See DW_ATE_imaginary_float */
 
-#define DW_ATE_hi_user			0xff
+#define DW_ATE_hi_user                  0xff
+
+
+/* Decimal Sign codes. */
+#define DW_DS_unsigned                  0x01 /* DWARF3f */
+#define DW_DS_leading_overpunch         0x02 /* DWARF3f */
+#define DW_DS_trailing_overpunch        0x03 /* DWARF3f */
+#define DW_DS_leading_separate          0x04 /* DWARF3f */
 
-/* for use with DW_TAG_SUN_codeflags
+#define DW_DS_trailing_separate         0x05 /* DWARF3f */
+
+/* Endian code name. */
+#define DW_END_default                  0x00 /* DWARF3f */
+#define DW_END_big                      0x01 /* DWARF3f */
+#define DW_END_little                   0x02 /* DWARF3f */
+
+#define DW_END_lo_user                  0x40 /* DWARF3f */
+#define DW_END_hi_user                  0xff /* DWARF3f */
+
+/* For use with DW_TAG_SUN_codeflags
  * If DW_TAG_SUN_codeflags is accepted as a dwarf standard, then
  * standard dwarf ATCF entries start at 0x01
  */
-#define DW_ATCF_lo_user                 0x40
-#define DW_ATCF_SUN_mop_bitfield        0x41
-#define DW_ATCF_SUN_mop_spill           0x42
-#define DW_ATCF_SUN_mop_scopy           0x43
-#define DW_ATCF_SUN_func_start          0x44
-#define DW_ATCF_SUN_end_ctors           0x45
-#define DW_ATCF_SUN_branch_target       0x46
-#define DW_ATCF_SUN_mop_stack_probe     0x47
-#define DW_ATCF_hi_user                 0xff    
+#define DW_ATCF_lo_user                 0x40 /* SUN */
+#define DW_ATCF_SUN_mop_bitfield        0x41 /* SUN */
+#define DW_ATCF_SUN_mop_spill           0x42 /* SUN */
+#define DW_ATCF_SUN_mop_scopy           0x43 /* SUN */
+#define DW_ATCF_SUN_func_start          0x44 /* SUN */
+#define DW_ATCF_SUN_end_ctors           0x45 /* SUN */
+#define DW_ATCF_SUN_branch_target       0x46 /* SUN */
+#define DW_ATCF_SUN_mop_stack_probe     0x47 /* SUN */
+#define DW_ATCF_SUN_func_epilog         0x48 /* SUN */
+#define DW_ATCF_hi_user                 0xff /* SUN */   
 
-#define DW_ACCESS_public		1
-#define DW_ACCESS_protected		2
-#define DW_ACCESS_private		3
+/* Accessibility code name. */
+#define DW_ACCESS_public                0x01
+#define DW_ACCESS_protected             0x02
+#define DW_ACCESS_private               0x03
 
-#define DW_VIS_local			1
-#define DW_VIS_exported			2
-#define DW_VIS_qualified		3
+/* Visibility code name. */
+#define DW_VIS_local                    0x01
+#define DW_VIS_exported                 0x02
+#define DW_VIS_qualified                0x03
+
+/* Virtuality code name. */
+#define DW_VIRTUALITY_none              0x00
+#define DW_VIRTUALITY_virtual           0x01
+#define DW_VIRTUALITY_pure_virtual      0x02
 
-#define DW_VIRTUALITY_none		0
-#define DW_VIRTUALITY_virtual 		1
-#define DW_VIRTUALITY_pure_virtual 	2
-
-#define DW_LANG_C89			0x0001
-#define DW_LANG_C			0x0002
-#define DW_LANG_Ada83			0x0003
-#define DW_LANG_C_plus_plus		0x0004
-#define DW_LANG_Cobol74			0x0005
-#define DW_LANG_Cobol85			0x0006
-#define DW_LANG_Fortran77		0x0007
-#define DW_LANG_Fortran90		0x0008
-#define DW_LANG_Pascal83		0x0009
-#define DW_LANG_Modula2			0x000a
-#define DW_LANG_Java			0x000b /* DWARF3 */
-#define DW_LANG_C99			0x000c /* DWARF3 */
-#define DW_LANG_Ada95			0x000d /* DWARF3 */
-#define DW_LANG_Fortran95		0x000e /* DWARF3 */
-#define DW_LANG_PLI			0x000f /* DWARF3 */
-#define DW_LANG_lo_user			0x8000
-#define DW_LANG_Mips_Assembler		0x8001
-#define DW_LANG_Upc                     0x8765 /* UPC */
+#define DW_LANG_C89                     0x0001
+#define DW_LANG_C                       0x0002
+#define DW_LANG_Ada83                   0x0003
+#define DW_LANG_C_plus_plus             0x0004
+#define DW_LANG_Cobol74                 0x0005
+#define DW_LANG_Cobol85                 0x0006
+#define DW_LANG_Fortran77               0x0007
+#define DW_LANG_Fortran90               0x0008
+#define DW_LANG_Pascal83                0x0009
+#define DW_LANG_Modula2                 0x000a
+#define DW_LANG_Java                    0x000b /* DWARF3 */
+#define DW_LANG_C99                     0x000c /* DWARF3 */
+#define DW_LANG_Ada95                   0x000d /* DWARF3 */
+#define DW_LANG_Fortran95               0x000e /* DWARF3 */
+#define DW_LANG_PLI                     0x000f /* DWARF3 */
+#define DW_LANG_ObjC                    0x0010 /* DWARF3f */
+#define DW_LANG_ObjC_plus_plus          0x0011 /* DWARF3f */
+#define DW_LANG_UPC                     0x0012 /* DWARF3f */
+#define DW_LANG_D                       0x0013 /* DWARF3f */
+#define DW_LANG_Python                  0x0014 /* DWARF4 */
+/* The following 2 are not yet formally approved October 2010, but
+   it seems extremely likely they will be approved as the committee
+   chair agrees these should be ok and no one on the committee
+   has objected. */
+#define DW_LANG_OpenCL                  0x0015 /* Provisionally DWARF5 */
+#define DW_LANG_Go                      0x0016 /* Provisionally DWARF5 */
+#define DW_LANG_lo_user                 0x8000
+#define DW_LANG_Mips_Assembler          0x8001 /* MIPS   */
+#define DW_LANG_Upc                     0x8765 /* UPC, use
+                                        DW_LANG_UPC instead. */
+/* ALTIUM extension */
+#define DW_LANG_ALTIUM_Assembler        0x9101  /* ALTIUM */
 
 /* Sun extensions */
-#define DW_LANG_SUN_Assembler           0x9001
+#define DW_LANG_SUN_Assembler           0x9001 /* SUN */
+
+#define DW_LANG_hi_user                 0xffff
+
+/* Identifier case name. */
+#define DW_ID_case_sensitive            0x00
+#define DW_ID_up_case                   0x01
+#define DW_ID_down_case                 0x02
+#define DW_ID_case_insensitive          0x03
 
-#define DW_LANG_hi_user			0xffff
+/* Calling Convention Name. */
+#define DW_CC_normal                    0x01
+#define DW_CC_program                   0x02
+#define DW_CC_nocall                    0x03
+#define DW_CC_lo_user                   0x40
+
+/* ALTIUM extensions. */
+/* Function is an interrupt handler, return address on system stack. */
+#define DW_CC_ALTIUM_interrupt          0x65  /* ALTIUM*/
+
+/* Near function model, return address on system stack. */
+#define DW_CC_ALTIUM_near_system_stack  0x66  /*ALTIUM */
+
+/* Near function model, return address on user stack. */
+#define DW_CC_ALTIUM_near_user_stack    0x67  /* ALTIUM */  
+
+/* Huge function model, return address on user stack.  */
+#define DW_CC_ALTIUM_huge_user_stack    0x68  /* ALTIUM */    
 
 
-#define DW_ID_case_sensitive		0
-#define DW_ID_up_case			1
-#define DW_ID_down_case			2
-#define DW_ID_case_insensitive		3
+#define DW_CC_hi_user                   0xff
 
-#define DW_CC_normal			0x1
-#define DW_CC_program			0x2
-#define DW_CC_nocall			0x3
-#define DW_CC_lo_user			0x40
-#define DW_CC_hi_user			0xff
+/* Inline Code Name. */
+#define DW_INL_not_inlined              0x00
+#define DW_INL_inlined                  0x01
+#define DW_INL_declared_not_inlined     0x02
+#define DW_INL_declared_inlined         0x03
+
+/* Ordering Name. */
+#define DW_ORD_row_major                0x00
+#define DW_ORD_col_major                0x01
 
-#define DW_INL_not_inlined		0
-#define DW_INL_inlined			1
-#define DW_INL_declared_not_inlined	2
-#define DW_INL_declared_inlined		3
+/* Discriminant Descriptor Name. */
+#define DW_DSC_label                    0x00
+#define DW_DSC_range                    0x01
 
-#define DW_ORD_row_major		0
-#define DW_ORD_col_major		1
-
-#define DW_DSC_label			0
-#define DW_DSC_range			1
+/* Line number standard opcode name. */
+#define DW_LNS_copy                     0x01
+#define DW_LNS_advance_pc               0x02
+#define DW_LNS_advance_line             0x03
+#define DW_LNS_set_file                 0x04
+#define DW_LNS_set_column               0x05
+#define DW_LNS_negate_stmt              0x06
+#define DW_LNS_set_basic_block          0x07
+#define DW_LNS_const_add_pc             0x08
+#define DW_LNS_fixed_advance_pc         0x09
+#define DW_LNS_set_prologue_end         0x0a /* DWARF3 */
+#define DW_LNS_set_epilogue_begin       0x0b /* DWARF3 */
+#define DW_LNS_set_isa                  0x0c /* DWARF3 */
 
-#define DW_LNS_copy			1
-#define DW_LNS_advance_pc		2
-#define DW_LNS_advance_line		3
-#define DW_LNS_set_file			4
-#define DW_LNS_set_column		5
-#define DW_LNS_negate_stmt		6
-#define DW_LNS_set_basic_block		7
-#define DW_LNS_const_add_pc		8
-#define DW_LNS_fixed_advance_pc		9
-#define DW_LNS_set_prologue_end		10 /* DWARF3 */
-#define DW_LNS_set_epilogue_begin	11 /* DWARF3 */
-#define DW_LNS_set_isa			12 /* DWARF3 */
+/* Line number extended opcode name. */
+#define DW_LNE_end_sequence             0x01
+#define DW_LNE_set_address              0x02
+#define DW_LNE_define_file              0x03
+#define DW_LNE_set_discriminator        0x04  /* DWARF4 */
+
+/* HP extensions. */
+#define DW_LNE_HP_negate_is_UV_update       0x11 /* 17 HP */
+#define DW_LNE_HP_push_context              0x12 /* 18 HP */
+#define DW_LNE_HP_pop_context               0x13 /* 19 HP */
+#define DW_LNE_HP_set_file_line_column      0x14 /* 20 HP */
+#define DW_LNE_HP_set_routine_name          0x15 /* 21 HP */
+#define DW_LNE_HP_set_sequence              0x16 /* 22 HP */
+#define DW_LNE_HP_negate_post_semantics     0x17 /* 23 HP */
+#define DW_LNE_HP_negate_function_exit      0x18 /* 24 HP */
+#define DW_LNE_HP_negate_front_end_logical  0x19 /* 25 HP */
+#define DW_LNE_HP_define_proc               0x20 /* 32 HP */
 
-#define DW_LNE_end_sequence		1
-#define DW_LNE_set_address		2
-#define DW_LNE_define_file		3
-#define DW_LNE_lo_user			128 /* DWARF3 */
-#define DW_LNE_hi_user			255 /* DWARF3 */
+#define DW_LNE_lo_user                  0x80 /* DWARF3 */
+#define DW_LNE_hi_user                  0xff /* DWARF3 */
+
+/* These are known values for DW_LNS_set_isa. */
+#define DW_ISA_UNKNOWN   0
+/* The following two are ARM specific. */
+#define DW_ISA_ARM_thumb 1 /* ARM ISA */
+#define DW_ISA_ARM_arm   2 /* ARM ISA */
 
-#define DW_MACINFO_define		1
-#define DW_MACINFO_undef		2
-#define DW_MACINFO_start_file		3
-#define DW_MACINFO_end_file		4
-#define DW_MACINFO_vendor_ext		255
+/* Macro information. */
+#define DW_MACINFO_define               0x01
+#define DW_MACINFO_undef                0x02
+#define DW_MACINFO_start_file           0x03
+#define DW_MACINFO_end_file             0x04
+#define DW_MACINFO_vendor_ext           0xff
 
+/* CFA operator compaction (a space saving measure, see
+   the DWARF standard) means DW_CFA_extended and DW_CFA_nop 
+   have the same value here.  */
 #define DW_CFA_advance_loc        0x40
 #define DW_CFA_offset             0x80
 #define DW_CFA_restore            0xc0
@@ -587,76 +865,116 @@
 #define DW_CFA_undefined        0x07
 #define DW_CFA_same_value       0x08
 #define DW_CFA_register         0x09
-#define DW_CFA_remember_state   0x0a 
+#define DW_CFA_remember_state   0x0a
 #define DW_CFA_restore_state    0x0b
 #define DW_CFA_def_cfa          0x0c
 #define DW_CFA_def_cfa_register 0x0d
 #define DW_CFA_def_cfa_offset   0x0e
 #define DW_CFA_def_cfa_expression 0x0f     /* DWARF3 */
 #define DW_CFA_expression       0x10       /* DWARF3 */
-#define DW_CFA_cfa_offset_extended_sf 0x11 /* DWARF3 */
+#define DW_CFA_offset_extended_sf 0x11     /* DWARF3 */
 #define DW_CFA_def_cfa_sf       0x12       /* DWARF3 */
 #define DW_CFA_def_cfa_offset_sf 0x13      /* DWARF3 */
+#define DW_CFA_val_offset        0x14      /* DWARF3f */
+#define DW_CFA_val_offset_sf     0x15      /* DWARF3f */
+#define DW_CFA_val_expression    0x16      /* DWARF3f */
 
-#define DW_CFA_low_user          0x1c
-#define DW_CFA_MIPS_advance_loc8 0x1d
+#define DW_CFA_lo_user           0x1c
+#define DW_CFA_low_user          0x1c  /* Incorrect spelling, do not use. */
 
-/* the following two from egcs-1.1.2 */
-#define DW_CFA_GNU_window_save   0x2d 
-#define DW_CFA_GNU_args_size     0x2e
+/* SGI/MIPS extension. */
+#define DW_CFA_MIPS_advance_loc8 0x1d   /* MIPS */
+
+/* GNU extensions. */
+#define DW_CFA_GNU_window_save   0x2d  /* GNU */
+#define DW_CFA_GNU_args_size     0x2e /* GNU  */
+#define DW_CFA_GNU_negative_offset_extended  0x2f /* GNU */
 
 #define DW_CFA_high_user         0x3f
 
+/* GNU exception header encoding.  See the Generic
+   Elf Specification of the Linux Standard Base (LSB). 
+   http://refspecs.freestandards.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/dwarfext.html
+   The upper 4 bits indicate how the value is to be applied. 
+   The lower 4 bits indicate the format of the data.
+*/
+#define DW_EH_PE_absptr   0x00  /* GNU */
+#define DW_EH_PE_uleb128  0x01  /* GNU */
+#define DW_EH_PE_udata2   0x02  /* GNU */
+#define DW_EH_PE_udata4   0x03  /* GNU */
+#define DW_EH_PE_udata8   0x04  /* GNU */
+#define DW_EH_PE_sleb128  0x09  /* GNU */
+#define DW_EH_PE_sdata2   0x0A  /* GNU */
+#define DW_EH_PE_sdata4   0x0B  /* GNU */
+#define DW_EH_PE_sdata8   0x0C  /* GNU */
+
+#define DW_EH_PE_pcrel    0x10  /* GNU */
+#define DW_EH_PE_textrel  0x20  /* GNU */
+#define DW_EH_PE_datarel  0x30  /* GNU */
+#define DW_EH_PE_funcrel  0x40  /* GNU */
+#define DW_EH_PE_aligned  0x50  /* GNU */
+
+#define DW_EH_PE_omit     0xff  /* GNU.  Means no value present. */
+
 
 /* Mapping from machine registers and pseudo-regs into the .debug_frame table.
    DW_FRAME entries are machine specific. These describe
-   MIPS/SGI R3000, R4K, R4400.
-   And (simultaneously) a mapping from hardware register number to
-   the number used in the table to identify that register. 
+   MIPS/SGI R3000, R4K, R4400 and all later MIPS/SGI IRIX machines.
+   They describe a mapping from hardware register number to
+   the number used in the table to identify that register.
 
-   The CFA (Canonical Frame Address) described in DWARF is called 
+   The CFA (Canonical Frame Address) described in DWARF is called
    the Virtual Frame Pointer on MIPS/SGI machines.
 
-	                     Rule describes:
+   The DW_FRAME* names here are MIPS/SGI specfic.
+   Libdwarf interfaces defined in 2008 make the 
+   frame definitions
+   here (and the fixed table sizes they imply) obsolete.
+   They are left here for compatibility. 
 */
-#define DW_FRAME_CFA_COL 0  /* column used for CFA */
-#define DW_FRAME_REG1	1  /* integer reg 1 */
-#define DW_FRAME_REG2	2  /* integer reg 2 */
-#define DW_FRAME_REG3	3  /* integer reg 3 */
-#define DW_FRAME_REG4	4  /* integer reg 4 */
-#define DW_FRAME_REG5	5  /* integer reg 5 */
-#define DW_FRAME_REG6	6  /* integer reg 6 */
-#define DW_FRAME_REG7	7  /* integer reg 7 */
-#define DW_FRAME_REG8	8  /* integer reg 8 */
-#define DW_FRAME_REG9	9  /* integer reg 9 */
-#define DW_FRAME_REG10	10 /* integer reg 10 */
-#define DW_FRAME_REG11	11 /* integer reg 11 */
-#define DW_FRAME_REG12	12 /* integer reg 12 */
-#define DW_FRAME_REG13	13 /* integer reg 13 */
-#define DW_FRAME_REG14	14 /* integer reg 14 */
-#define DW_FRAME_REG15	15 /* integer reg 15 */
-#define DW_FRAME_REG16	16 /* integer reg 16 */
-#define DW_FRAME_REG17	17 /* integer reg 17 */
-#define DW_FRAME_REG18	18 /* integer reg 18 */
-#define DW_FRAME_REG19	19 /* integer reg 19 */
-#define DW_FRAME_REG20	20 /* integer reg 20 */
-#define DW_FRAME_REG21	21 /* integer reg 21 */
-#define DW_FRAME_REG22	22 /* integer reg 22 */
-#define DW_FRAME_REG23	23 /* integer reg 23 */
-#define DW_FRAME_REG24	24 /* integer reg 24 */
-#define DW_FRAME_REG25	25 /* integer reg 25 */
-#define DW_FRAME_REG26	26 /* integer reg 26 */
-#define DW_FRAME_REG27	27 /* integer reg 27 */
-#define DW_FRAME_REG28	28 /* integer reg 28 */
-#define DW_FRAME_REG29	29 /* integer reg 29 */
-#define DW_FRAME_REG30	30 /* integer reg 30 */
-#define DW_FRAME_REG31	31 /* integer reg 31, aka ra */
-	
-	/* MIPS1, 2 have only some of these 64-bit registers.
-	** MIPS1  save/restore takes 2 instructions per 64-bit reg, and
-	** in that case, the register is considered stored after the second
-	** swc1.
-	*/
+/* Default column used for CFA in the libdwarf reader client.
+   Assumes reg 0 never appears as
+   a register in DWARF information. Usable for MIPS,
+   but never a good idea, really.    */
+#define DW_FRAME_CFA_COL 0  
+
+#define DW_FRAME_REG1   1  /* integer reg 1 */
+#define DW_FRAME_REG2   2  /* integer reg 2 */
+#define DW_FRAME_REG3   3  /* integer reg 3 */
+#define DW_FRAME_REG4   4  /* integer reg 4 */
+#define DW_FRAME_REG5   5  /* integer reg 5 */
+#define DW_FRAME_REG6   6  /* integer reg 6 */
+#define DW_FRAME_REG7   7  /* integer reg 7 */
+#define DW_FRAME_REG8   8  /* integer reg 8 */
+#define DW_FRAME_REG9   9  /* integer reg 9 */
+#define DW_FRAME_REG10  10 /* integer reg 10 */
+#define DW_FRAME_REG11  11 /* integer reg 11 */
+#define DW_FRAME_REG12  12 /* integer reg 12 */
+#define DW_FRAME_REG13  13 /* integer reg 13 */
+#define DW_FRAME_REG14  14 /* integer reg 14 */
+#define DW_FRAME_REG15  15 /* integer reg 15 */
+#define DW_FRAME_REG16  16 /* integer reg 16 */
+#define DW_FRAME_REG17  17 /* integer reg 17 */
+#define DW_FRAME_REG18  18 /* integer reg 18 */
+#define DW_FRAME_REG19  19 /* integer reg 19 */
+#define DW_FRAME_REG20  20 /* integer reg 20 */
+#define DW_FRAME_REG21  21 /* integer reg 21 */
+#define DW_FRAME_REG22  22 /* integer reg 22 */
+#define DW_FRAME_REG23  23 /* integer reg 23 */
+#define DW_FRAME_REG24  24 /* integer reg 24 */
+#define DW_FRAME_REG25  25 /* integer reg 25 */
+#define DW_FRAME_REG26  26 /* integer reg 26 */
+#define DW_FRAME_REG27  27 /* integer reg 27 */
+#define DW_FRAME_REG28  28 /* integer reg 28 */
+#define DW_FRAME_REG29  29 /* integer reg 29 */
+#define DW_FRAME_REG30  30 /* integer reg 30 */
+#define DW_FRAME_REG31  31 /* integer reg 31, aka ra */
+
+        /* MIPS1, 2 have only some of these 64-bit registers.
+        ** MIPS1  save/restore takes 2 instructions per 64-bit reg, and
+        ** in that case, the register is considered stored after the second
+        ** swc1.
+        */
 #define DW_FRAME_FREG0  32 /* 64-bit floating point reg 0 */
 #define DW_FRAME_FREG1  33 /* 64-bit floating point reg 1 */
 #define DW_FRAME_FREG2  34 /* 64-bit floating point reg 2 */
@@ -690,19 +1008,58 @@
 #define DW_FRAME_FREG30 62 /* 64-bit floating point reg 30 */
 #define DW_FRAME_FREG31 63 /* 64-bit floating point reg 31 */
 
-#define DW_FRAME_RA_COL	64 /* column recording ra */
+/*  ***IMPORTANT NOTE, TARGET DEPENDENCY ****
+    The following 4 #defines are dependent on 
+    the target cpu(s) that you apply libdwarf to.
+    Ensure that DW_FRAME_UNDEFINED_VAL  and DW_FRAME_SAME_VAL
+    do not conflict with the range [0-DW_FRAME_STATIC_LINK].
+    The value 63 works for MIPS cpus at least up to the R16000.
+
+    For a cpu with more than 63 real registers
+    DW_FRAME_HIGHEST_NORMAL_REGISTER
+    must be increased for things to work properly!
+    Also ensure that DW_FRAME_UNDEFINED_VAL DW_FRAME_SAME_VAL
+    are not in the range [0-DW_FRAME_STATIC_LINK]
 
-#define DW_FRAME_STATIC_LINK 65 /* column recording static link*/
-				/* applicable to up-level      */
-				/* addressing, as in mp code,  */
-				/* pascal, etc */
+    Having DW_FRAME_HIGHEST_NORMAL_REGISTER be higher than
+    is strictly needed is safe.
+
+*/
 
-/* This is the number of columns in the Frame Table. This constant should
-   be kept in sync with DW_REG_TABLE_SIZE defined in libdwarf.h */
-#define DW_FRAME_LAST_REG_NUM   (DW_FRAME_STATIC_LINK + 1)
+#ifndef DW_FRAME_HIGHEST_NORMAL_REGISTER
+#define DW_FRAME_HIGHEST_NORMAL_REGISTER 63
+#endif
+/* This is the number of columns in the Frame Table. 
+   This constant should
+   be kept in sync with DW_REG_TABLE_SIZE defined in libdwarf.h 
+   It must also be large enough to be beyond the highest 
+   compiler-defined-register (meaning DW_FRAME_RA_COL DW_FRAME_STATIC_LINK
+   in the MIPS/IRIX case */
+#ifndef DW_FRAME_LAST_REG_NUM
+#define DW_FRAME_LAST_REG_NUM   (DW_FRAME_HIGHEST_NORMAL_REGISTER + 3)
+#endif
 
 
-/* 
+/* Column recording ra (return address from a function call). 
+   This is common to many architectures, but as a 'simple register'
+   is not necessarily adequate for all architectures.
+   For MIPS/IRIX this register number is actually recorded on disk
+   in the .debug_frame section.
+   */
+#define DW_FRAME_RA_COL  (DW_FRAME_HIGHEST_NORMAL_REGISTER + 1)
+
+/* Column recording static link applicable to up-level      
+   addressing, as in IRIX mp code, pascal, etc.
+   This is common to many architectures but
+   is not necessarily adequate for all architectures.
+   For MIPS/IRIX this register number is actually recorded on disk
+   in the .debug_frame section.
+*/
+#define DW_FRAME_STATIC_LINK (DW_FRAME_HIGHEST_NORMAL_REGISTER + 2)
+
+
+
+/*
   DW_FRAME_UNDEFINED_VAL and  DW_FRAME_SAME_VAL  are
   never on disk, just generated by libdwarf. See libdwarf.h
   for their values.
@@ -710,10 +1067,10 @@
 
 
 
-#define DW_CHILDREN_no		     0x00
-#define DW_CHILDREN_yes		     0x01
+#define DW_CHILDREN_no               0x00
+#define DW_CHILDREN_yes              0x01
 
-#define DW_ADDR_none		0
+#define DW_ADDR_none            0
 
 #ifdef __cplusplus
 }
--- a/usr/src/tools/ctf/dwarf/common/dwarf_abbrev.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_abbrev.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000,2001 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2009-2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -32,6 +33,12 @@
   http://oss.sgi.com/projects/GenInfo/NoticeExplan
 
 */
+/* The address of the Free Software Foundation is 
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the above address.
+*/
+
 
 
 
@@ -42,68 +49,69 @@
 
 int
 dwarf_get_abbrev(Dwarf_Debug dbg,
-		 Dwarf_Unsigned offset,
-		 Dwarf_Abbrev * returned_abbrev,
-		 Dwarf_Unsigned * length,
-		 Dwarf_Unsigned * abbr_count, Dwarf_Error * error)
+    Dwarf_Unsigned offset,
+    Dwarf_Abbrev * returned_abbrev,
+    Dwarf_Unsigned * length,
+    Dwarf_Unsigned * abbr_count, Dwarf_Error * error)
 {
-    Dwarf_Small *abbrev_ptr;
-    Dwarf_Small *abbrev_section_end;
-    Dwarf_Half attr;
-    Dwarf_Half attr_form;
-    Dwarf_Abbrev ret_abbrev;
+    Dwarf_Small *abbrev_ptr = 0;
+    Dwarf_Small *abbrev_section_end = 0;
+    Dwarf_Half attr = 0;
+    Dwarf_Half attr_form = 0;
+    Dwarf_Abbrev ret_abbrev = 0;
     Dwarf_Unsigned labbr_count = 0;
-    Dwarf_Unsigned utmp;
+    Dwarf_Unsigned utmp = 0;
 
 
     if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
-    if (dbg->de_debug_abbrev == 0) {
-	/* Loads abbrev section (and .debug_info as we do those
-	   together). */
-	int res = _dwarf_load_debug_info(dbg, error);
+    if (dbg->de_debug_abbrev.dss_data == 0) {
+        /* Loads abbrev section (and .debug_info as we do those
+           together). */
+        int res = _dwarf_load_debug_info(dbg, error);
 
-	if (res != DW_DLV_OK) {
-	    return res;
-	}
+        if (res != DW_DLV_OK) {
+            return res;
+        }
     }
 
-    if (offset >= dbg->de_debug_abbrev_size) {
-	return (DW_DLV_NO_ENTRY);
+    if (offset >= dbg->de_debug_abbrev.dss_size) {
+        return (DW_DLV_NO_ENTRY);
     }
 
 
     ret_abbrev = (Dwarf_Abbrev) _dwarf_get_alloc(dbg, DW_DLA_ABBREV, 1);
     if (ret_abbrev == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
     }
     ret_abbrev->ab_dbg = dbg;
     if (returned_abbrev == 0 || abbr_count == 0) {
-	_dwarf_error(dbg, error, DW_DLE_DWARF_ABBREV_NULL);
-	return (DW_DLV_ERROR);
+        dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV);
+        _dwarf_error(dbg, error, DW_DLE_DWARF_ABBREV_NULL);
+        return (DW_DLV_ERROR);
     }
 
 
     *abbr_count = 0;
     if (length != NULL)
-	*length = 1;
+        *length = 1;
 
-    abbrev_ptr = dbg->de_debug_abbrev + offset;
+    abbrev_ptr = dbg->de_debug_abbrev.dss_data + offset;
     abbrev_section_end =
-	dbg->de_debug_abbrev + dbg->de_debug_abbrev_size;
+        dbg->de_debug_abbrev.dss_data + dbg->de_debug_abbrev.dss_size;
 
     DECODE_LEB128_UWORD(abbrev_ptr, utmp);
     ret_abbrev->ab_code = (Dwarf_Word) utmp;
     if (ret_abbrev->ab_code == 0) {
-	*returned_abbrev = ret_abbrev;
-	*abbr_count = 0;
-	if (length) {
-	    *length = 1;
-	}
-	return (DW_DLV_OK);
+        *returned_abbrev = ret_abbrev;
+        *abbr_count = 0;
+        if (length) {
+            *length = 1;
+        }
+        return (DW_DLV_OK);
     }
 
     DECODE_LEB128_UWORD(abbrev_ptr, utmp);
@@ -112,26 +120,27 @@
     ret_abbrev->ab_abbrev_ptr = abbrev_ptr;
 
     do {
-	Dwarf_Unsigned utmp2;
+        Dwarf_Unsigned utmp2;
 
-	DECODE_LEB128_UWORD(abbrev_ptr, utmp2)
-	    attr = (Dwarf_Half) utmp2;
-	DECODE_LEB128_UWORD(abbrev_ptr, utmp2)
-	    attr_form = (Dwarf_Half) utmp2;
+        DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
+        attr = (Dwarf_Half) utmp2;
+        DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
+        attr_form = (Dwarf_Half) utmp2;
 
-	if (attr != 0)
-	    (labbr_count)++;
+        if (attr != 0)
+            (labbr_count)++;
 
     } while (abbrev_ptr < abbrev_section_end &&
-	     (attr != 0 || attr_form != 0));
+             (attr != 0 || attr_form != 0));
 
     if (abbrev_ptr > abbrev_section_end) {
-	_dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
-	return (DW_DLV_ERROR);
+        dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV);
+        _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
+        return (DW_DLV_ERROR);
     }
 
     if (length != NULL)
-	*length = abbrev_ptr - dbg->de_debug_abbrev - offset;
+        *length = abbrev_ptr - dbg->de_debug_abbrev.dss_data - offset;
 
     *returned_abbrev = ret_abbrev;
     *abbr_count = labbr_count;
@@ -140,25 +149,27 @@
 
 int
 dwarf_get_abbrev_code(Dwarf_Abbrev abbrev,
-		      Dwarf_Unsigned * returned_code,
-		      Dwarf_Error * error)
+    Dwarf_Unsigned * returned_code,
+    Dwarf_Error * error)
 {
     if (abbrev == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
+        return (DW_DLV_ERROR);
     }
 
     *returned_code = abbrev->ab_code;
     return (DW_DLV_OK);
 }
 
+/* DWARF defines DW_TAG_hi_user as 0xffff so no tag should be
+   over 16 bits.  */
 int
 dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev,
-		     Dwarf_Half * returned_tag, Dwarf_Error * error)
+    Dwarf_Half * returned_tag, Dwarf_Error * error)
 {
     if (abbrev == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
+        return (DW_DLV_ERROR);
     }
 
     *returned_tag = abbrev->ab_tag;
@@ -168,12 +179,12 @@
 
 int
 dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev,
-			       Dwarf_Signed * returned_flag,
-			       Dwarf_Error * error)
+    Dwarf_Signed * returned_flag,
+    Dwarf_Error * error)
 {
     if (abbrev == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
+        return (DW_DLV_ERROR);
     }
 
     *returned_flag = abbrev->ab_has_child;
@@ -183,65 +194,65 @@
 
 int
 dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev,
-		       Dwarf_Signed index,
-		       Dwarf_Half * returned_attr_num,
-		       Dwarf_Signed * form,
-		       Dwarf_Off * offset, Dwarf_Error * error)
+    Dwarf_Signed index,
+    Dwarf_Half * returned_attr_num,
+    Dwarf_Signed * form,
+    Dwarf_Off * offset, Dwarf_Error * error)
 {
-    Dwarf_Byte_Ptr abbrev_ptr;
-    Dwarf_Byte_Ptr abbrev_end;
-    Dwarf_Byte_Ptr mark_abbrev_ptr;
-    Dwarf_Half attr;
-    Dwarf_Half attr_form;
+    Dwarf_Byte_Ptr abbrev_ptr = 0;
+    Dwarf_Byte_Ptr abbrev_end = 0;
+    Dwarf_Byte_Ptr mark_abbrev_ptr = 0;
+    Dwarf_Half attr = 0;
+    Dwarf_Half attr_form = 0;
 
     if (index < 0)
-	return (DW_DLV_NO_ENTRY);
+        return (DW_DLV_NO_ENTRY);
 
     if (abbrev == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
+        return (DW_DLV_ERROR);
     }
 
     if (abbrev->ab_code == 0) {
-	return (DW_DLV_NO_ENTRY);
+        return (DW_DLV_NO_ENTRY);
     }
 
     if (abbrev->ab_dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
 
     abbrev_ptr = abbrev->ab_abbrev_ptr;
     abbrev_end =
-	abbrev->ab_dbg->de_debug_abbrev +
-	abbrev->ab_dbg->de_debug_abbrev_size;
+        abbrev->ab_dbg->de_debug_abbrev.dss_data +
+        abbrev->ab_dbg->de_debug_abbrev.dss_size;
 
     for (attr = 1, attr_form = 1;
-	 index >= 0 && abbrev_ptr < abbrev_end && (attr != 0 ||
-						   attr_form != 0);
-	 index--) {
-	Dwarf_Unsigned utmp4;
+         index >= 0 && abbrev_ptr < abbrev_end && (attr != 0 ||
+             attr_form != 0);
+         index--) {
+        Dwarf_Unsigned utmp4;
 
-	mark_abbrev_ptr = abbrev_ptr;
-	DECODE_LEB128_UWORD(abbrev_ptr, utmp4)
-	    attr = (Dwarf_Half) utmp4;
-	DECODE_LEB128_UWORD(abbrev_ptr, utmp4)
-	    attr_form = (Dwarf_Half) utmp4;
+        mark_abbrev_ptr = abbrev_ptr;
+        DECODE_LEB128_UWORD(abbrev_ptr, utmp4);
+        attr = (Dwarf_Half) utmp4;
+        DECODE_LEB128_UWORD(abbrev_ptr, utmp4);
+        attr_form = (Dwarf_Half) utmp4;
     }
 
     if (abbrev_ptr >= abbrev_end) {
-	_dwarf_error(abbrev->ab_dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
-	return (DW_DLV_ERROR);
+        _dwarf_error(abbrev->ab_dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
+        return (DW_DLV_ERROR);
     }
 
     if (index >= 0) {
-	return (DW_DLV_NO_ENTRY);
+        return (DW_DLV_NO_ENTRY);
     }
 
     if (form != NULL)
-	*form = attr_form;
+        *form = attr_form;
     if (offset != NULL)
-	*offset = mark_abbrev_ptr - abbrev->ab_dbg->de_debug_abbrev;
+        *offset = mark_abbrev_ptr - abbrev->ab_dbg->de_debug_abbrev.dss_data;
 
     *returned_attr_num = (attr);
     return DW_DLV_OK;
--- a/usr/src/tools/ctf/dwarf/common/dwarf_abbrev.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_abbrev.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
   Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2008-2010  David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +18,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -36,9 +37,18 @@
 
 
 
+/* In a given CU, one of these is (eventually) set up
+   for every abbreviation we need to find (and for all.
+   those ealier in the abbreviations for that CU).
+   So we don't want elements needlessly big.
+*/
 struct Dwarf_Abbrev_s {
+    /* No TAG should exceed DW_TAG_hi_user, 0xffff, but
+       we do allow a larger value here. */
+    Dwarf_Word ab_tag;
+    /* Abbreviations are numbered (normally sequentially from
+       1 and so 16 bits is not enough!  */
     Dwarf_Word ab_code;
-    Dwarf_Half ab_tag;
     Dwarf_Small ab_has_child;
     Dwarf_Byte_Ptr ab_abbrev_ptr;
     Dwarf_Debug ab_dbg;
--- a/usr/src/tools/ctf/dwarf/common/dwarf_addr_finder.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_addr_finder.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +19,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -32,7 +32,9 @@
   http://oss.sgi.com/projects/GenInfo/NoticeExplan
 
 */
-
+/* This code used by SGI-IRIX rqs processing, not needed by
+   any other system or application.
+*/
 
 #include "config.h"
 #include "libdwarfdefs.h"
@@ -53,7 +55,7 @@
 typedef unsigned long long ull;
 
 static int do_this_die_and_dealloc(Dwarf_Debug dbg, Dwarf_Die die,
-				   int *errval);
+                                   int *errval);
 static int
   handle_debug_info(Dwarf_Debug dbg, int *errval);
 static int
@@ -70,7 +72,7 @@
 
 int
 _dwarf_addr_finder(dwarf_elf_handle elf_file_ptr,
-		   Dwarf_addr_callback_func cb_func, int *dwerr)
+                   Dwarf_addr_callback_func cb_func, int *dwerr)
 {
 
     Dwarf_Error err = 0;
@@ -80,14 +82,14 @@
     int sections_found = 0;
 
     res = dwarf_elf_init(elf_file_ptr, DW_DLC_READ, /* errhand */ 0,
-			 /* errarg */ 0, &dbg, &err);
+                         /* errarg */ 0, &dbg, &err);
     if (res == DW_DLV_ERROR) {
-	int errv = (int) dwarf_errno(err);
+        int errv = (int) dwarf_errno(err);
 
-	return errv;
+        return errv;
     }
     if (res == DW_DLV_NO_ENTRY) {
-	return res;
+        return res;
     }
 
     send_addr_note = cb_func;
@@ -95,58 +97,58 @@
     res = handle_debug_info(dbg, &errval);
     switch (res) {
     case DW_DLV_OK:
-	++sections_found;
-	break;
+        ++sections_found;
+        break;
     case DW_DLV_NO_ENTRY:
 
-	break;
+        break;
     default:
     case DW_DLV_ERROR:
-	dwarf_finish(dbg, &err);
-	*dwerr = errval;
-	return res;
+        dwarf_finish(dbg, &err);
+        *dwerr = errval;
+        return res;
     }
 
     res = handle_debug_aranges(dbg, cb_func, &errval);
     switch (res) {
     case DW_DLV_OK:
-	++sections_found;
-	break;
+        ++sections_found;
+        break;
     case DW_DLV_NO_ENTRY:
-	break;
+        break;
     default:
     case DW_DLV_ERROR:
-	dwarf_finish(dbg, &err);
-	*dwerr = errval;
-	return res;
+        dwarf_finish(dbg, &err);
+        *dwerr = errval;
+        return res;
     }
     res = handle_debug_frame(dbg, cb_func, &errval);
     switch (res) {
     case DW_DLV_OK:
-	++sections_found;
-	break;
+        ++sections_found;
+        break;
     case DW_DLV_NO_ENTRY:
-	break;
+        break;
     default:
     case DW_DLV_ERROR:
-	dwarf_finish(dbg, &err);
-	*dwerr = errval;
-	return res;
+        dwarf_finish(dbg, &err);
+        *dwerr = errval;
+        return res;
     }
 
-    res = handle_debug_loc();	/* does nothing */
+    res = handle_debug_loc();   /* does nothing */
     switch (res) {
     case DW_DLV_OK:
-	++sections_found;
-	break;
+        ++sections_found;
+        break;
     case DW_DLV_NO_ENTRY:
-	break;
+        break;
     default:
     case DW_DLV_ERROR:
-	/* IMPOSSIBLE : handle_debug_loc cannot return this */
-	dwarf_finish(dbg, &err);
-	*dwerr = errval;
-	return res;
+        /* IMPOSSIBLE : handle_debug_loc cannot return this */
+        dwarf_finish(dbg, &err);
+        *dwerr = errval;
+        return res;
     }
 
 
@@ -154,18 +156,18 @@
     *dwerr = 0;
     res = dwarf_finish(dbg, &err);
     if (res == DW_DLV_ERROR) {
-	*dwerr = (int) dwarf_errno(err);
-	return DW_DLV_ERROR;
+        *dwerr = (int) dwarf_errno(err);
+        return DW_DLV_ERROR;
     }
     if (sections_found == 0) {
-	return DW_DLV_NO_ENTRY;
+        return DW_DLV_NO_ENTRY;
     }
     return DW_DLV_OK;
 
 }
 
 /*
-	Return DW_DLV_OK, ERROR, or NO_ENTRY.
+        Return DW_DLV_OK, ERROR, or NO_ENTRY.
 */
 static int
 handle_debug_info(Dwarf_Debug dbg, int *errval)
@@ -184,43 +186,43 @@
 
 
     for (nres = dwarf_next_cu_header(dbg, &hdr_length, &version_stamp,
-				     &abbrev_offset,
-				     &addr_size, &nxtoff, &err);
-	 terminate_now == 0 && nres == DW_DLV_OK;
-	 nres = dwarf_next_cu_header(dbg, &hdr_length, &version_stamp,
-				     &abbrev_offset,
-				     &addr_size, &nxtoff, &err)
-	) {
+                                     &abbrev_offset,
+                                     &addr_size, &nxtoff, &err);
+         terminate_now == 0 && nres == DW_DLV_OK;
+         nres = dwarf_next_cu_header(dbg, &hdr_length, &version_stamp,
+                                     &abbrev_offset,
+                                     &addr_size, &nxtoff, &err)
+        ) {
 
-	Dwarf_Die curdie = 0;
+        Dwarf_Die curdie = 0;
 
-	/* try to get the compilation unit die */
-	sibres = dwarf_siblingof(dbg, curdie, &sibdie, &err);
-	if (sibres == DW_DLV_OK) {
-	    res = do_this_die_and_dealloc(dbg, sibdie, errval);
-	    switch (res) {
-	    case DW_DLV_OK:
-		break;
-	    case DW_DLV_NO_ENTRY:
-		break;
-	    default:
-	    case DW_DLV_ERROR:
-		return DW_DLV_ERROR;
-	    }
-	} else if (sibres == DW_DLV_ERROR) {
-	    *errval = (int) dwarf_errno(err);
-	    return DW_DLV_ERROR;
-	} else {
-	    /* NO ENTRY! */
-	    /* impossible? */
-	}
+        /* try to get the compilation unit die */
+        sibres = dwarf_siblingof(dbg, curdie, &sibdie, &err);
+        if (sibres == DW_DLV_OK) {
+            res = do_this_die_and_dealloc(dbg, sibdie, errval);
+            switch (res) {
+            case DW_DLV_OK:
+                break;
+            case DW_DLV_NO_ENTRY:
+                break;
+            default:
+            case DW_DLV_ERROR:
+                return DW_DLV_ERROR;
+            }
+        } else if (sibres == DW_DLV_ERROR) {
+            *errval = (int) dwarf_errno(err);
+            return DW_DLV_ERROR;
+        } else {
+            /* NO ENTRY! */
+            /* impossible? */
+        }
 
     }
     if (nres == DW_DLV_ERROR) {
-	int localerr = (int) dwarf_errno(err);
+        int localerr = (int) dwarf_errno(err);
 
-	*errval = localerr;
-	return DW_DLV_ERROR;
+        *errval = localerr;
+        return DW_DLV_ERROR;
     }
     return DW_DLV_OK;
 }
@@ -244,11 +246,11 @@
 };
 
 /*
-	Return DW_DLV_OK if handling this went ok.
+        Return DW_DLV_OK if handling this went ok.
 */
 static int
 handle_attr_addr(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attrnum,
-		 Dwarf_Error * perr)
+                 Dwarf_Error * perr)
 {
     int res = DW_DLV_OK;
     Dwarf_Off offset;
@@ -260,52 +262,52 @@
 
     ares = dwarf_attr(die, attrnum, &attr, perr);
     if (ares == DW_DLV_OK) {
-	int formres = dwarf_whatform(attr, &form, perr);
+        int formres = dwarf_whatform(attr, &form, perr);
 
-	switch (formres) {
-	case DW_DLV_OK:
-	    break;
-	case DW_DLV_ERROR:
-	case DW_DLV_NO_ENTRY:	/* impossible. */
-	    return formres;
+        switch (formres) {
+        case DW_DLV_OK:
+            break;
+        case DW_DLV_ERROR:
+        case DW_DLV_NO_ENTRY:   /* impossible. */
+            return formres;
 
-	}
+        }
 
-	switch (form) {
-	case DW_FORM_ref_addr:
-	case DW_FORM_addr:
-	    res = dwarf_attr_offset(die, attr, &offset, perr);
-	    if (res == DW_DLV_OK) {
-		ares = dwarf_formaddr(attr, &addr, perr);
-		if (ares == DW_DLV_OK) {
-		    send_addr_note(DW_SECTION_INFO, offset, addr);
-		} else if (ares == DW_DLV_ERROR) {
-		    return ares;
-		}		/* no entry: ok. */
-	    } else {
-		res = DW_DLV_ERROR;	/* NO_ENTRY is impossible. */
-	    }
-	    break;
+        switch (form) {
+        case DW_FORM_ref_addr:
+        case DW_FORM_addr:
+            res = dwarf_attr_offset(die, attr, &offset, perr);
+            if (res == DW_DLV_OK) {
+                ares = dwarf_formaddr(attr, &addr, perr);
+                if (ares == DW_DLV_OK) {
+                    send_addr_note(DW_SECTION_INFO, offset, addr);
+                } else if (ares == DW_DLV_ERROR) {
+                    return ares;
+                }               /* no entry: ok. */
+            } else {
+                res = DW_DLV_ERROR;     /* NO_ENTRY is impossible. */
+            }
+            break;
 
-	default:
-	    /* surprising! An error? */
+        default:
+            /* surprising! An error? */
 
-	    ;			/* do nothing */
-	}
-	dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
+            ;                   /* do nothing */
+        }
+        dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
 
     } else {
-	res = ares;
+        res = ares;
     }
     return res;
 }
 
 /*
-	Return DW_DLV_OK if handling this went ok.
+        Return DW_DLV_OK if handling this went ok.
 */
 static int
 handle_attr_locdesc(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attrnum,
-		    Dwarf_Error * perr)
+                    Dwarf_Error * perr)
 {
     int retval = DW_DLV_OK;
     Dwarf_Attribute attr;
@@ -320,74 +322,73 @@
 
     ares = dwarf_attr(die, attrnum, &attr, perr);
     if (ares == DW_DLV_OK) {
-	Dwarf_Half form;
-	int fres = dwarf_whatform(attr, &form, perr);
+        Dwarf_Half form;
+        int fres = dwarf_whatform(attr, &form, perr);
 
-	if (fres == DW_DLV_OK) {
-	    switch (form) {
-	    case DW_FORM_block1:
-	    case DW_FORM_block2:
-	    case DW_FORM_block4:
-		/* must be location description */
-		res = dwarf_attr_offset(die, attr, &offset, perr);
-		llbuf = 0;
-		if (res == DW_DLV_OK) {
-		    Dwarf_Signed count;
-		    int lres =
-			dwarf_loclist(attr, &llbuf, &count, perr);
-		    if (lres != DW_DLV_OK) {
-			return lres;
-		    }
-		    if (count != 1) {
-			/* this cannot happen! */
-			/* perr? */
-			_dwarf_error(dbg, perr,
-				     DW_DLE_LOCDESC_COUNT_WRONG);
-			retval = DW_DLV_ERROR;
-			return retval;
-		    }
-		    for (i = 0; i < count; ++i) {
-			unsigned int ents = llbuf[i].ld_cents;
+        if (fres == DW_DLV_OK) {
+            switch (form) {
+            case DW_FORM_block1:
+            case DW_FORM_block2:
+            case DW_FORM_block4:
+                /* must be location description */
+                res = dwarf_attr_offset(die, attr, &offset, perr);
+                llbuf = 0;
+                if (res == DW_DLV_OK) {
+                    Dwarf_Signed count;
+                    int lres = dwarf_loclist(attr, &llbuf, &count, perr);
+                    if (lres != DW_DLV_OK) {
+                        return lres;
+                    }
+                    if (count != 1) {
+                        /* this cannot happen! */
+                        /* perr? */
+                        _dwarf_error(dbg, perr,
+                                     DW_DLE_LOCDESC_COUNT_WRONG);
+                        retval = DW_DLV_ERROR;
+                        return retval;
+                    }
+                    for (i = 0; i < count; ++i) {
+                        unsigned int ents = llbuf[i].ld_cents;
 
-			locp = llbuf[i].ld_s;
-			for (entindx = 0; entindx < ents; entindx++) {
-			    Dwarf_Loc *llocp;
+                        locp = llbuf[i].ld_s;
+                        for (entindx = 0; entindx < ents; entindx++) {
+                            Dwarf_Loc *llocp;
 
-			    llocp = locp + entindx;
-			    if (llocp->lr_atom == DW_OP_addr) {
-				send_addr_note(DW_SECTION_INFO, offset +
-					       llocp->lr_offset + 1
-					       /* The offset is the
-					          offset of the atom,
-					          ** and we know the
-					          addr is 1 past it. */
-					       , llocp->lr_number);
-			    }
-			}
-		    }
+                            llocp = locp + entindx;
+                            if (llocp->lr_atom == DW_OP_addr) {
+                                send_addr_note(DW_SECTION_INFO, offset +
+                                               llocp->lr_offset + 1
+                                               /* The offset is the
+                                                  offset of the atom,
+                                                  ** and we know the
+                                                  addr is 1 past it. */
+                                               , llocp->lr_number);
+                            }
+                        }
+                    }
 
 
-		    if (count > 0) {
-			for (i = 0; i < count; ++i) {
-			    dwarf_dealloc(dbg, llbuf[i].ld_s,
-					  DW_DLA_LOC_BLOCK);
-			}
-			dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC);
-		    }
-		} else {
-		    retval = res;
-		}
-		break;
+                    if (count > 0) {
+                        for (i = 0; i < count; ++i) {
+                            dwarf_dealloc(dbg, llbuf[i].ld_s,
+                                          DW_DLA_LOC_BLOCK);
+                        }
+                        dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC);
+                    }
+                } else {
+                    retval = res;
+                }
+                break;
 
-	    default:
-		/* must be a const offset in debug_loc */
-		;		/* do nothing */
-	    }
-	    dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
-	}			/* else error or no entry */
-	retval = fres;
+            default:
+                /* must be a const offset in debug_loc */
+                ;               /* do nothing */
+            }
+            dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
+        }                       /* else error or no entry */
+        retval = fres;
     } else {
-	retval = ares;
+        retval = ares;
     }
     return retval;
 }
@@ -411,88 +412,86 @@
     int doffres = dwarf_dieoffset(newdie, &doff, &err);
 
     if (doffres != DW_DLV_OK) {
-	if (doffres == DW_DLV_ERROR) {
-	    *errval = (int) dwarf_errno(err);
-	}
-	return doffres;
+        if (doffres == DW_DLV_ERROR) {
+            *errval = (int) dwarf_errno(err);
+        }
+        return doffres;
     }
     tres = dwarf_tag(newdie, &ltag, &err);
     if (tres != DW_DLV_OK) {
-	return tres;
+        return tres;
     }
     if (DW_TAG_compile_unit == ltag) {
-	/* because of the way the dwarf_line code works, we ** do lines 
-	   only per compile unit. ** This may turn out to be wrong if
-	   we have lines ** left unconnected to a CU. ** of course such 
-	   lines will not, at present, be ** used by gnome ** This is
-	   not ideal as coded due to the dwarf_line.c issue. */
-	int lres;
-
-	lres = handle_debug_line(dbg, newdie, send_addr_note, errval);
-	if (lres == DW_DLV_ERROR) {
-	    return lres;
-	}
+        /* because of the way the dwarf_line code works, we do lines 
+           only per compile unit. This may turn out to be wrong if
+           we have lines left unconnected to a CU. of course such 
+           lines will not, at present, be used by gnome. This is
+           not ideal as coded due to the dwarf_line.c issue. */
+        int lres = handle_debug_line(dbg, newdie, send_addr_note, errval);
+        if (lres == DW_DLV_ERROR) {
+            return lres;
+        }
     }
 
     for (i = 0; i < sizeof(might_have_addr) / sizeof(int); i++) {
-	int resattr;
-	Dwarf_Bool hasattr;
+        int resattr;
+        Dwarf_Bool hasattr;
 
-	newattrnum = might_have_addr[i];
-	err = 0;
-	resattr = dwarf_hasattr(newdie, newattrnum, &hasattr, &err);
-	if (DW_DLV_OK == resattr) {
-	    if (hasattr) {
-		res = handle_attr_addr(dbg, newdie, newattrnum, &err);
-		if (res != DW_DLV_OK) {
-		    *errval = (int) dwarf_errno(err);
-		    return DW_DLV_ERROR;
-		}
-	    }
-	} else {
-	    if (resattr == DW_DLV_ERROR) {
-		*errval = (int) dwarf_errno(err);
-		return resattr;
-	    }
-	}
+        newattrnum = might_have_addr[i];
+        err = 0;
+        resattr = dwarf_hasattr(newdie, newattrnum, &hasattr, &err);
+        if (DW_DLV_OK == resattr) {
+            if (hasattr) {
+                res = handle_attr_addr(dbg, newdie, newattrnum, &err);
+                if (res != DW_DLV_OK) {
+                    *errval = (int) dwarf_errno(err);
+                    return DW_DLV_ERROR;
+                }
+            }
+        } else {
+            if (resattr == DW_DLV_ERROR) {
+                *errval = (int) dwarf_errno(err);
+                return resattr;
+            }
+        }
     }
     for (i = 0; i < sizeof(might_have_locdesc) / sizeof(int); i++) {
-	int resattr;
-	Dwarf_Bool hasattr;
+        int resattr;
+        Dwarf_Bool hasattr;
 
-	newattrnum = might_have_locdesc[i];
-	err = 0;
-	resattr = dwarf_hasattr(newdie, newattrnum, &hasattr, &err);
-	if (DW_DLV_OK == resattr) {
-	    if (hasattr) {
-		res =
-		    handle_attr_locdesc(dbg, newdie, newattrnum, &err);
-		if (res != DW_DLV_OK) {
-		    *errval = (int) dwarf_errno(err);
-		    return DW_DLV_ERROR;
-		}
-	    }
-	} else {
-	    if (resattr == DW_DLV_ERROR) {
-		*errval = (int) dwarf_errno(err);
-		return resattr;
-	    }
-	}
+        newattrnum = might_have_locdesc[i];
+        err = 0;
+        resattr = dwarf_hasattr(newdie, newattrnum, &hasattr, &err);
+        if (DW_DLV_OK == resattr) {
+            if (hasattr) {
+                res =
+                    handle_attr_locdesc(dbg, newdie, newattrnum, &err);
+                if (res != DW_DLV_OK) {
+                    *errval = (int) dwarf_errno(err);
+                    return DW_DLV_ERROR;
+                }
+            }
+        } else {
+            if (resattr == DW_DLV_ERROR) {
+                *errval = (int) dwarf_errno(err);
+                return resattr;
+            }
+        }
     }
 
     return DW_DLV_OK;
 }
 
 /*
-	Handle siblings as a list,
-	Do children by recursing.
-	Effectively this is walking the tree preorder.
+        Handle siblings as a list,
+        Do children by recursing.
+        Effectively this is walking the tree preorder.
 
-	This dealloc's any die passed to it, so the
-	caller should not do that dealloc.
-	It seems more logical to have the one causing
-	the alloc to do the dealloc, but that way this
-	routine became a mess.
+        This dealloc's any die passed to it, so the
+        caller should not do that dealloc.
+        It seems more logical to have the one causing
+        the alloc to do the dealloc, but that way this
+        routine became a mess.
 
 */
 static int
@@ -508,69 +507,69 @@
     Dwarf_Die sibdie;
 
     while (sibres == DW_DLV_OK) {
-	Dwarf_Die ch_die;
+        Dwarf_Die ch_die;
 
 
-	res = process_this_die_attrs(dbg, newdie, errval);
-	switch (res) {
-	case DW_DLV_OK:
-	    break;
-	case DW_DLV_NO_ENTRY:
-	    break;
-	default:
-	case DW_DLV_ERROR:
-	    if (prevdie) {
-		dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
-		prevdie = 0;
-	    }
-	    return DW_DLV_ERROR;
-	}
+        res = process_this_die_attrs(dbg, newdie, errval);
+        switch (res) {
+        case DW_DLV_OK:
+            break;
+        case DW_DLV_NO_ENTRY:
+            break;
+        default:
+        case DW_DLV_ERROR:
+            if (prevdie) {
+                dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
+                prevdie = 0;
+            }
+            return DW_DLV_ERROR;
+        }
 
-	tres = dwarf_child(newdie, &ch_die, &err);
+        tres = dwarf_child(newdie, &ch_die, &err);
 
-	if (tres == DW_DLV_OK) {
-	    res = do_this_die_and_dealloc(dbg, ch_die, errval);
-	    switch (res) {
-	    case DW_DLV_OK:
-		break;
-	    case DW_DLV_NO_ENTRY:
-		break;
-	    default:
-	    case DW_DLV_ERROR:
-		if (prevdie) {
-		    dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
-		    prevdie = 0;
-		}
-		return DW_DLV_ERROR;
-	    }
-	} else if (tres == DW_DLV_ERROR) {
-	    /* An error! */
-	    *errval = (int) dwarf_errno(err);
-	    if (prevdie) {
-		dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
-		prevdie = 0;
-	    }
-	    dwarf_dealloc(dbg, err, DW_DLA_ERROR);
-	    return DW_DLV_ERROR;
-	}			/* else was NO ENTRY */
-	prevdie = newdie;
-	sibdie = 0;
-	sibres = dwarf_siblingof(dbg, newdie, &sibdie, &err);
-	if (prevdie) {
-	    dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
-	    prevdie = 0;
-	}
-	newdie = sibdie;
+        if (tres == DW_DLV_OK) {
+            res = do_this_die_and_dealloc(dbg, ch_die, errval);
+            switch (res) {
+            case DW_DLV_OK:
+                break;
+            case DW_DLV_NO_ENTRY:
+                break;
+            default:
+            case DW_DLV_ERROR:
+                if (prevdie) {
+                    dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
+                    prevdie = 0;
+                }
+                return DW_DLV_ERROR;
+            }
+        } else if (tres == DW_DLV_ERROR) {
+            /* An error! */
+            *errval = (int) dwarf_errno(err);
+            if (prevdie) {
+                dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
+                prevdie = 0;
+            }
+            dwarf_dealloc(dbg, err, DW_DLA_ERROR);
+            return DW_DLV_ERROR;
+        }                       /* else was NO ENTRY */
+        prevdie = newdie;
+        sibdie = 0;
+        sibres = dwarf_siblingof(dbg, newdie, &sibdie, &err);
+        if (prevdie) {
+            dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
+            prevdie = 0;
+        }
+        newdie = sibdie;
 
     }
     if (sibres == DW_DLV_NO_ENTRY) {
-	return DW_DLV_OK;
+        return DW_DLV_OK;
     }
     /* error. */
     *errval = (int) dwarf_errno(err);
     if (prevdie) {
-	dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
-	prevdie = 0;
+        dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
+        prevdie = 0;
     }
     dwarf_dealloc(dbg, err, DW_DLA_ERROR);
     return DW_DLV_ERROR;
@@ -580,7 +579,7 @@
 
 static int
 handle_debug_frame(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func,
-		   int *errval)
+                   int *errval)
 {
     int retval = DW_DLV_OK;
     int res;
@@ -591,26 +590,26 @@
     int i;
 
     res =
-	_dwarf_frame_address_offsets(dbg, &addrlist, &offsetlist,
-				     &count, &err);
+        _dwarf_frame_address_offsets(dbg, &addrlist, &offsetlist,
+                                     &count, &err);
     if (res == DW_DLV_OK) {
-	for (i = 0; i < count; i++) {
-	    cb_func(DW_SECTION_FRAME, offsetlist[i], addrlist[i]);
-	}
-	dwarf_dealloc(dbg, offsetlist, DW_DLA_ADDR);
-	dwarf_dealloc(dbg, addrlist, DW_DLA_ADDR);
+        for (i = 0; i < count; i++) {
+            cb_func(DW_SECTION_FRAME, offsetlist[i], addrlist[i]);
+        }
+        dwarf_dealloc(dbg, offsetlist, DW_DLA_ADDR);
+        dwarf_dealloc(dbg, addrlist, DW_DLA_ADDR);
     } else if (res == DW_DLV_NO_ENTRY) {
-	retval = res;
+        retval = res;
     } else {
-	*errval = (int) dwarf_errno(err);
-	retval = DW_DLV_ERROR;
+        *errval = (int) dwarf_errno(err);
+        retval = DW_DLV_ERROR;
     }
     return retval;
 
 }
 static int
 handle_debug_aranges(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func,
-		     int *errval)
+                     int *errval)
 {
     int retval = DW_DLV_OK;
     Dwarf_Error err;
@@ -620,30 +619,30 @@
     Dwarf_Off *offsets;
 
     retval =
-	_dwarf_get_aranges_addr_offsets(dbg, &aranges, &offsets, &count,
-					&err);
+        _dwarf_get_aranges_addr_offsets(dbg, &aranges, &offsets, &count,
+                                        &err);
     if (retval == DW_DLV_OK) {
-	if (count == 0) {
-	    retval = DW_DLV_NO_ENTRY;
-	} else {
-	    for (indx = 0; indx < count; indx++) {
-		cb_func(DW_SECTION_ARANGES, offsets[indx],
-			aranges[indx]);
-	    }
-	}
-	dwarf_dealloc(dbg, aranges, DW_DLA_ADDR);
-	dwarf_dealloc(dbg, offsets, DW_DLA_ADDR);
+        if (count == 0) {
+            retval = DW_DLV_NO_ENTRY;
+        } else {
+            for (indx = 0; indx < count; indx++) {
+                cb_func(DW_SECTION_ARANGES, offsets[indx],
+                        aranges[indx]);
+            }
+        }
+        dwarf_dealloc(dbg, aranges, DW_DLA_ADDR);
+        dwarf_dealloc(dbg, offsets, DW_DLA_ADDR);
     } else if (retval == DW_DLV_NO_ENTRY) {
-	;			/* do nothing */
+        ;                       /* do nothing */
     } else {
-	*errval = (int) dwarf_errno(err);
-	retval = DW_DLV_ERROR;
+        *errval = (int) dwarf_errno(err);
+        retval = DW_DLV_ERROR;
     }
     return retval;
 }
 static int
 handle_debug_line(Dwarf_Debug dbg, Dwarf_Die cu_die,
-		  Dwarf_addr_callback_func cb_func, int *errval)
+                  Dwarf_addr_callback_func cb_func, int *errval)
 {
     int retval = DW_DLV_OK;
     int res;
@@ -654,28 +653,28 @@
     Dwarf_Unsigned i;
 
     res =
-	_dwarf_line_address_offsets(dbg, cu_die, &addrlist, &offsetlist,
-				    &count, &err);
+        _dwarf_line_address_offsets(dbg, cu_die, &addrlist, &offsetlist,
+                                    &count, &err);
     if (res == DW_DLV_OK) {
-	for (i = 0; i < count; i++) {
-	    cb_func(DW_SECTION_LINE, offsetlist[i], addrlist[i]);
+        for (i = 0; i < count; i++) {
+            cb_func(DW_SECTION_LINE, offsetlist[i], addrlist[i]);
 
-	}
-	dwarf_dealloc(dbg, offsetlist, DW_DLA_ADDR);
-	dwarf_dealloc(dbg, addrlist, DW_DLA_ADDR);
+        }
+        dwarf_dealloc(dbg, offsetlist, DW_DLA_ADDR);
+        dwarf_dealloc(dbg, addrlist, DW_DLA_ADDR);
     } else if (res == DW_DLV_NO_ENTRY) {
-	retval = res;
+        retval = res;
     } else {
-	*errval = (int) dwarf_errno(err);
-	retval = DW_DLV_ERROR;
+        *errval = (int) dwarf_errno(err);
+        retval = DW_DLV_ERROR;
     }
     return retval;
 }
 
 /*
-	We need to add support for this. Currently we do not
-	generate this section.
-	FIX!
+        We need to add support for this. Currently we do not
+        generate this section.
+        FIX!
 */
 static int
 handle_debug_loc(void)
--- a/usr/src/tools/ctf/dwarf/common/dwarf_alloc.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_alloc.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007-2010  David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -32,8 +33,14 @@
   http://oss.sgi.com/projects/GenInfo/NoticeExplan
 
 */
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
 
 
+#undef  DEBUG
 
 #include "config.h"
 #include "dwarf_incl.h"
@@ -41,7 +48,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-#include <malloc.h>
+#include "malloc_check.h"
 
 /*
     These files are included to get the sizes
@@ -61,15 +68,17 @@
 #include "dwarf_vars.h"
 #include "dwarf_weaks.h"
 
+
 static void _dwarf_free_special_error(Dwarf_Ptr space);
+
 #ifdef DWARF_SIMPLE_MALLOC
 static void _dwarf_simple_malloc_add_to_list(Dwarf_Debug dbg,
-		Dwarf_Ptr addr, 
-		unsigned long size,
-        	short alloc_type);
-static void _dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg, 
-		Dwarf_Ptr space, 
-		short alloc_type);
+    Dwarf_Ptr addr,
+    unsigned long size,
+    short alloc_type);
+static void _dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg,
+    Dwarf_Ptr space,
+    short alloc_type);
 void _dwarf_simple_malloc_botch(int err);
 
 #endif /* DWARF_SIMPLE_MALLOC */
@@ -83,40 +92,49 @@
     be a multiple of the size of a pointer.  This is done
     so that every struct returned by _dwarf_get_alloc()
     can be preceded by a pointer to the chunk it came from.
-    Before, it checks if the size of struct is less than
+    Before allocating, it checks if the size of struct is less than
     the size of a pointer.  If yes, it returns the size
     of 2 pointers.  The returned size should be at least
     the size of 2 pointers, since the first points to the
     chunk the struct was allocated from, and the second
     is used to link the free list.
 
-    If this is n32, we want the sizes to be 64-bit aligned
-    so that longlong in the structure we return to user
-    is aligned properly. Thus the _dw_fac of 2
+    We want DW_RESERVE to be at least the size of
+    a long long and at least the size of a pointer because
+    our struct has a long long and we want that aligned right.
+    Now Standard C defines long long as 8 bytes, so lets
+    make that standard. It will become unworkable when
+    long long or pointer grows beyound 8 bytes.
+    Unclear what to do with wierd requirements, like
+    36 bit pointers.
 
-    Only long longs need to be properly aligned: we don't
-    have long double and don't align for that.
 
 */
-#if _MIPS_SIM == _MIPS_SIM_NABI32
-#define _DW_FAC 2
-#define _DW_PS sizeof(void *)
-#else
-#define _DW_FAC 1
-#define _DW_PS sizeof(void *)
-#endif
-#define _DW_RESERVE (_DW_FAC * _DW_PS)
+#define DW_RESERVE 8
 
-/* Round size up to the next multiple of _DW_RESERVE bytes 
+/* Round size up to the next multiple of DW_RESERVE bytes 
 */
 #define ROUND_SIZE(inputsize)                 \
-        (((inputsize) % (_DW_RESERVE)) == 0 ? \
+        (((inputsize) % (DW_RESERVE)) == 0 ? \
             (inputsize):                      \
             ((inputsize)  +                   \
-               (_DW_RESERVE) - ((inputsize) % (_DW_RESERVE)) ))
+               (DW_RESERVE) - ((inputsize) % (DW_RESERVE)) ))
+
+#define ROUND_SIZE_WITH_POINTER(i_size) (ROUND_SIZE(i_size) + DW_RESERVE)
+
+/* SMALL_ALLOC is for trivia where allocation is a waste.
+   Things that should be removed, really. */
+#define SMALL_ALLOC 2
 
-#define ROUND_SIZE_WITH_POINTER(i_size) (ROUND_SIZE(i_size) + _DW_RESERVE)
+/* BASE_ALLOC is where a basic allocation makes sense, but 'not too large'. 
+   No thorough evaluation of this value has been done, though
+   it was found wasteful of memory to have BASE_ALLOC be as large as
+   BIG_ALLOC. */
 #define BASE_ALLOC 64
+
+/* BIG_ALLOC is where a larger-than-BASE_ALLOC 
+   allocation makes sense, but still 'not too large'.
+   No thorough evaluation of this value has been done. */
 #define BIG_ALLOC  128
 
 /* This translates into de_alloc_hdr index 
@@ -126,110 +144,126 @@
 ** so that is not an option.
 */
 struct ial_s {
-    int ia_al_num;		/* Index into de_alloc_hdr table. */
+    int ia_al_num;              /* Index into de_alloc_hdr table. */
 
     /* In bytes, one struct instance. This does not account for extra
-       space needed per block, but that (_DW_RESERVE) will be added in
-       later where it is needed (_DW_RESERVE space never added in
-       here). */
+       space needed per block, but that (DW_RESERVE) will be added in
+       later where it is needed (DW_RESERVE space never added in here). 
+     */
     int ia_struct_size;
 
 
     /* Number of instances per alloc block. MUST be > 0. */
     int ia_base_count;
+
+    int (*specialconstructor) (Dwarf_Debug, void *);
+    void (*specialdestructor) (void *);
 };
 
 static const
 struct ial_s index_into_allocated[ALLOC_AREA_INDEX_TABLE_MAX] = {
-    {0, 1, 1},			/* none */
-    {0, 1, 1,},			/* 1 DW_DLA_STRING */
-    {1, sizeof(Dwarf_Loc), BASE_ALLOC}
-    ,				/* 2 DW_DLA_LOC */
-    {2, sizeof(Dwarf_Locdesc), BASE_ALLOC}
-    ,				/* 3 DW_DLA_LOCDESC */
-    {0, 1, 1}
-    ,				/* not used *//* 4 DW_DLA_ELLIST */
-    {0, 1, 1}
-    ,				/* not used *//* 5 DW_DLA_BOUNDS */
-    {3, sizeof(Dwarf_Block), BASE_ALLOC}
-    ,				/* 6 DW_DLA_BLOCK */
-    {0, 1, 1}
-    ,				/* the actual dwarf_debug structure *//* 7 DW_DLA_DEBUG */
-    {4, sizeof(struct Dwarf_Die_s), BIG_ALLOC},	/* 8 DW_DLA_DIE */
-    {5, sizeof(struct Dwarf_Line_s), BIG_ALLOC},	/* 9
-							   DW_DLA_LINE */
-    {6, sizeof(struct Dwarf_Attribute_s), BIG_ALLOC * 2},
+    {0, 1, 1, 0, 0},            /* none */
+    {0, 1, 1, 0, 0},            /* 1 DW_DLA_STRING */
+    {1, sizeof(Dwarf_Loc), BASE_ALLOC, 0, 0}
+    ,                           /* 2 DW_DLA_LOC */
+    {2, sizeof(Dwarf_Locdesc), BASE_ALLOC, 0, 0}
+    ,                           /* 3 DW_DLA_LOCDESC */
+    {0, 1, 1, 0, 0}
+    ,                           /* not used *//* 4 DW_DLA_ELLIST */
+    {0, 1, 1, 0, 0}
+    ,                           /* not used *//* 5 DW_DLA_BOUNDS */
+    {3, sizeof(Dwarf_Block), BASE_ALLOC, 0, 0}
+    ,                           /* 6 DW_DLA_BLOCK */
+    {0, 1, 1, 0, 0}
+    ,                           /* the actual dwarf_debug structure *//* 7 DW_DLA_DEBUG */
+    {4, sizeof(struct Dwarf_Die_s), BIG_ALLOC, 0, 0},   /* 8 DW_DLA_DIE 
+                                                         */
+    {5, sizeof(struct Dwarf_Line_s), BIG_ALLOC, 0, 0},  /* 9
+                                                           DW_DLA_LINE */
+    {6, sizeof(struct Dwarf_Attribute_s), BIG_ALLOC * 2, 0, 0},
     /* 10 DW_DLA_ATTR */
-    {0, 1, 1},			/* not used *//* 11 DW_DLA_TYPE */
-    {0, 1, 1},			/* not used *//* 12 DW_DLA_SUBSCR */
-    {7, sizeof(struct Dwarf_Global_s), BIG_ALLOC},	/* 13
-							   DW_DLA_GLOBAL 
-							 */
-    {8, sizeof(struct Dwarf_Error_s), BASE_ALLOC},	/* 14
-							   DW_DLA_ERROR 
-							 */
-    {0, 1, 1},			/* 15 DW_DLA_LIST */
-    {0, 1, 1},			/* not used *//* 16 DW_DLA_LINEBUF */
-    {9, sizeof(struct Dwarf_Arange_s), BASE_ALLOC},	/* 17
-							   DW_DLA_ARANGE 
-							 */
-    {10, sizeof(struct Dwarf_Abbrev_s), BIG_ALLOC},	/* 18
-							   DW_DLA_ABBREV 
-							 */
-    {11, sizeof(Dwarf_Frame_Op), BIG_ALLOC}
-    ,				/* 19 DW_DLA_FRAME_OP */
-    {12, sizeof(struct Dwarf_Cie_s), BASE_ALLOC},	/* 20
-							   DW_DLA_CIE */
-    {13, sizeof(struct Dwarf_Fde_s), BASE_ALLOC},	/* 21
-							   DW_DLA_FDE */
-    {0, 1, 1},			/* 22 DW_DLA_LOC_BLOCK */
-    {0, 1, 1},			/* 23 DW_DLA_FRAME_BLOCK */
-    {14, sizeof(struct Dwarf_Global_s), BIG_ALLOC},	/* 24
-							   DW_DLA_FUNC */
-    {15, sizeof(struct Dwarf_Global_s), BIG_ALLOC},	/* 25
-							   DW_DLA_TYPENAME 
-							 */
-    {16, sizeof(struct Dwarf_Global_s), BIG_ALLOC},	/* 26
-							   DW_DLA_VAR */
-    {17, sizeof(struct Dwarf_Global_s), BASE_ALLOC},	/* 27
-							   DW_DLA_WEAK */
-    {0, 1, 1},			/* 28 DW_DLA_ADDR */
-    {18, sizeof(struct Dwarf_Abbrev_List_s), BIG_ALLOC},
-    /* 29 DW_DLA_ABBREV_LIST */
-    {19, sizeof(struct Dwarf_Chain_s), BIG_ALLOC},	/* 30
-							   DW_DLA_CHAIN 
-							 */
-    {20, sizeof(struct Dwarf_CU_Context_s), BASE_ALLOC},
-    /* 31 DW_DLA_CU_CONTEXT */
-    {21, sizeof(struct Dwarf_Frame_s), BASE_ALLOC},	/* 32
-							   DW_DLA_FRAME 
-							 */
-    {22, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC},
-    /* 33 DW_DLA_GLOBAL_CONTEXT */
-    {23, sizeof(struct Dwarf_File_Entry_s), BASE_ALLOC},
-    /* 34 DW_DLA_FILE_ENTRY */
-    {24, sizeof(struct Dwarf_Line_Context_s), BASE_ALLOC},
-    /* 35 DW_DLA_LINE_CONTEXT */
-    {25, sizeof(struct Dwarf_Loc_Chain_s), BASE_ALLOC},
-    /* 36 DW_DLA_LOC_CHAIN */
-    {26, ABBREV_HASH_TABLE_SIZE * 2 * sizeof(Dwarf_Abbrev_List),
-     BASE_ALLOC}
-    ,
-    /* 37 DW_DLA_HASH_TABLE */
+    {0, 1, 1, 0, 0},            /* not used *//* 11 DW_DLA_TYPE */
+    {0, 1, 1, 0, 0},            /* not used *//* 12 DW_DLA_SUBSCR */
+    {7, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0},       /* 13
+                                                                   DW_DLA_GLOBAL 
+                                                                 */
+    {8, sizeof(struct Dwarf_Error_s), BASE_ALLOC, 0, 0},        /* 14
+                                                                   DW_DLA_ERROR 
+                                                                 */
+    {0, 1, 1, 0, 0},            /* 15 DW_DLA_LIST */
+    {0, 1, 1, 0, 0},            /* not used *//* 16 DW_DLA_LINEBUF */
+    {9, sizeof(struct Dwarf_Arange_s), BASE_ALLOC, 0, 0},       /* 17
+                                                                   DW_DLA_ARANGE 
+                                                                 */
+    {10, sizeof(struct Dwarf_Abbrev_s), BIG_ALLOC, 0, 0},       /* 18
+                                                                   DW_DLA_ABBREV 
+                                                                 */
+    {11, sizeof(Dwarf_Frame_Op), BIG_ALLOC, 0, 0}
+    ,                           /* 19 DW_DLA_FRAME_OP */
+    {12, sizeof(struct Dwarf_Cie_s), BASE_ALLOC, 0, 0}, /* 20
+                                                           DW_DLA_CIE */
+    {13, sizeof(struct Dwarf_Fde_s), BASE_ALLOC, 0, 0}, /* 21 DW_DLA_FDE */
+    {0, 1, 1, 0, 0},            /* 22 DW_DLA_LOC_BLOCK */
+    {0, 1, 1, 0, 0},            /* 23 DW_DLA_FRAME_BLOCK */
+    {14, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 24 DW_DLA_FUNC 
+                                                              UNUSED */
+    {15, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 25 
+                                                              DW_DLA_TYPENAME
+                                                              UNUSED */
+    {16, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 26 DW_DLA_VAR 
+                                                              UNUSED */
+    {17, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 27 DW_DLA_WEAK 
+                                                              UNUSED */
+    {0, 1, 1, 0, 0},            /* 28 DW_DLA_ADDR */
+    {0, 1,1,0,0 },              /* 29 DW_DLA_RANGES */
+
+    /* The following DW_DLA data types
+       are known only inside libdwarf.  */
+    
+    {18, sizeof(struct Dwarf_Abbrev_List_s), BIG_ALLOC, 0, 0},
+    /* 30 DW_DLA_ABBREV_LIST */
+
+    {19, sizeof(struct Dwarf_Chain_s), BIG_ALLOC, 0, 0}, /* 31 DW_DLA_CHAIN */
+    {20, sizeof(struct Dwarf_CU_Context_s), BASE_ALLOC, 0, 0},
+    /* 32 DW_DLA_CU_CONTEXT */
+    {21, sizeof(struct Dwarf_Frame_s), BASE_ALLOC,
+     _dwarf_frame_constructor,
+     _dwarf_frame_destructor},  /* 33 DW_DLA_FRAME */
+    {22, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
+    /* 34 DW_DLA_GLOBAL_CONTEXT */
+    {23, sizeof(struct Dwarf_File_Entry_s), BASE_ALLOC, 0, 0},  /* 34 */
+    /* 35 DW_DLA_FILE_ENTRY */
+    {24, sizeof(struct Dwarf_Line_Context_s), BASE_ALLOC, 0, 0},
+    /* 36 DW_DLA_LINE_CONTEXT */
+    {25, sizeof(struct Dwarf_Loc_Chain_s), BASE_ALLOC, 0, 0},   /* 36 */
+    /* 37 DW_DLA_LOC_CHAIN */
+
+    {26, sizeof(struct Dwarf_Hash_Table_s),BASE_ALLOC, 0, 0},   /* 37 */
+    /* 38 DW_DLA_HASH_TABLE */
 
 /* The following really use Global struct: used to be unique struct
    per type, but now merged (11/99).  The opaque types
-   are visible in the interface. The types are left in existence,
-   with unchanged numbers.
+   are visible in the interface. The types  for
+   DW_DLA_FUNC,
+   DW_DLA_TYPENAME, DW_DLA_VAR, DW_DLA_WEAK also use
+   the global types.
+  
 */
-    {27, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC},
-    /* 38 DW_DLA_FUNC_CONTEXT */
-    {28, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC},
-    /* 39 DW_DLA_TYPENAME_CONTEXT */
-    {29, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC},
-    /* 40 DW_DLA_VAR_CONTEXT */
-    {30, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC},
-    /* 41 DW_DLA_WEAK_CONTEXT */
+    {27, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
+    /* 39 DW_DLA_FUNC_CONTEXT */
+    {28, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
+    /* 40 DW_DLA_TYPENAME_CONTEXT */
+    {29, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
+    /* 41 DW_DLA_VAR_CONTEXT */
+    {30, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
+    /* 42 DW_DLA_WEAK_CONTEXT */
+    {31, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
+    /* 43 DW_DLA_PUBTYPES_CONTEXT DWARF3 */
+
+    {0,1,1,0,0 },
+    /* 44 DW_DLA_HASH_TABLE_ENTRY */
+
+
 };
 
 #ifndef DWARF_SIMPLE_MALLOC
@@ -285,126 +319,126 @@
 
     /* 
        Check the alloc_area from which the last allocation was made
-       (most recent new block). If that is not successful, then
-       search the list of alloc_area's from alloc_header. */
+       (most recent new block). If that is not successful, then search
+       the list of alloc_area's from alloc_header. */
     alloc_area = alloc_hdr->ah_last_alloc_area;
     if (alloc_area == NULL || alloc_area->aa_free_structs_in_chunk == 0)
-	for (alloc_area = alloc_hdr->ah_alloc_area_head;
-	     alloc_area != NULL; alloc_area = alloc_area->aa_next) {
+        for (alloc_area = alloc_hdr->ah_alloc_area_head;
+             alloc_area != NULL; alloc_area = alloc_area->aa_next) {
 
-	    if (alloc_area->aa_free_structs_in_chunk > 0) {
-		break;		/* found a free entry! */
-	    }
+            if (alloc_area->aa_free_structs_in_chunk > 0) {
+                break;          /* found a free entry! */
+            }
 
-	}
+        }
 
     if (alloc_area != NULL) {
-	alloc_area->aa_free_structs_in_chunk--;
+        alloc_area->aa_free_structs_in_chunk--;
 
-	if (alloc_area->aa_free_list != NULL) {
-	    ret_mem = alloc_area->aa_free_list;
+        if (alloc_area->aa_free_list != NULL) {
+            ret_mem = alloc_area->aa_free_list;
 
-	    /* 
-	       Update the free list.  The initial part of the struct is 
-	       used to hold a pointer to the next struct on the free
-	       list.  In this way, the free list chain is maintained at
-	       0 memory cost. */
-	    alloc_area->aa_free_list =
-		((Dwarf_Free_List) ret_mem)->fl_next;
-	} else if (alloc_area->aa_blob_start < alloc_area->aa_blob_end) {
-	    ret_mem = alloc_area->aa_blob_start;
+            /* 
+               Update the free list.  The initial part of the struct is 
+               used to hold a pointer to the next struct on the free
+               list.  In this way, the free list chain is maintained at
+               0 memory cost. */
+            alloc_area->aa_free_list =
+                ((Dwarf_Free_List) ret_mem)->fl_next;
+        } else if (alloc_area->aa_blob_start < alloc_area->aa_blob_end) {
+            ret_mem = alloc_area->aa_blob_start;
 
-	    /* 
-	       Store pointer to chunk this struct belongs to in the
-	       first few bytes.  Return pointer to bytes after this
-	       pointer storage. */
-	    *(Dwarf_Alloc_Area *) ret_mem = alloc_area;
-	    ret_mem += _DW_RESERVE;
+            /* 
+               Store pointer to chunk this struct belongs to in the
+               first few bytes.  Return pointer to bytes after this
+               pointer storage. */
+            *(Dwarf_Alloc_Area *) ret_mem = alloc_area;
+            ret_mem += DW_RESERVE;
 
-	    alloc_area->aa_blob_start += alloc_hdr->ah_bytes_one_struct;
-	} else {
-	    /* else fall thru , though it should be impossible to fall
-	       thru. And represents a disastrous programming error if
-	       we get here. */
+            alloc_area->aa_blob_start += alloc_hdr->ah_bytes_one_struct;
+        } else {
+            /* else fall thru , though it should be impossible to fall
+               thru. And represents a disastrous programming error if
+               we get here. */
 #ifdef DEBUG
-	    fprintf(stderr, "libdwarf Internal error start %x end %x\n",
-		    (int) alloc_area->aa_blob_start,
-		    (int) alloc_area->aa_blob_end);
+            fprintf(stderr, "libdwarf Internal error start %x end %x\n",
+                    (int) alloc_area->aa_blob_start,
+                    (int) alloc_area->aa_blob_end);
 #endif
-	}
+        }
     }
 
     /* New memory has to malloc'ed since there are no free structs. */
     if (ret_mem == 0) {
-	Dwarf_Word rounded_area_hdr_size;
+        Dwarf_Word rounded_area_hdr_size;
 
-	alloc_hdr->ah_chunks_allocated++;
+        alloc_hdr->ah_chunks_allocated++;
 
-	{			/* this nonsense avoids a warning */
-	    /* CONSTCOND would be better */
-	    unsigned long v = sizeof(struct Dwarf_Alloc_Area_s);
+        {                       /* this nonsense avoids a warning */
+            /* CONSTCOND would be better */
+            unsigned long v = sizeof(struct Dwarf_Alloc_Area_s);
 
-	    rounded_area_hdr_size = ROUND_SIZE(v);
-	}
+            rounded_area_hdr_size = ROUND_SIZE(v);
+        }
 
-	/* 
-	   Allocate memory to contain the required number of structs
-	   and the Dwarf_Alloc_Area_s to control it. */
-	mem_block_size = alloc_hdr->ah_bytes_malloc_per_chunk +
-	    rounded_area_hdr_size;
+        /* 
+           Allocate memory to contain the required number of structs
+           and the Dwarf_Alloc_Area_s to control it. */
+        mem_block_size = alloc_hdr->ah_bytes_malloc_per_chunk +
+            rounded_area_hdr_size;
 
-	mem_block = malloc(mem_block_size);
-	if (mem_block == NULL) {
-	    return (NULL);
-	}
+        mem_block = malloc(mem_block_size);
+        if (mem_block == NULL) {
+            return (NULL);
+        }
 
 
-	/* 
-	   Attach the Dwarf_Alloc_Area_s struct to the list of chunks
-	   malloc'ed for this struct type. Also initialize the fields
-	   of the Dwarf_Alloc_Area_s. */
-	alloc_area = (Dwarf_Alloc_Area) mem_block;
-	alloc_area->aa_prev = 0;
-	if (alloc_hdr->ah_alloc_area_head != NULL) {
-	    alloc_hdr->ah_alloc_area_head->aa_prev = alloc_area;
-	}
-	alloc_area->aa_free_list = 0;
-	alloc_area->aa_next = alloc_hdr->ah_alloc_area_head;
-	alloc_hdr->ah_alloc_area_head = alloc_area;
+        /* 
+           Attach the Dwarf_Alloc_Area_s struct to the list of chunks
+           malloc'ed for this struct type. Also initialize the fields
+           of the Dwarf_Alloc_Area_s. */
+        alloc_area = (Dwarf_Alloc_Area) mem_block;
+        alloc_area->aa_prev = 0;
+        if (alloc_hdr->ah_alloc_area_head != NULL) {
+            alloc_hdr->ah_alloc_area_head->aa_prev = alloc_area;
+        }
+        alloc_area->aa_free_list = 0;
+        alloc_area->aa_next = alloc_hdr->ah_alloc_area_head;
+        alloc_hdr->ah_alloc_area_head = alloc_area;
 
-	alloc_area->aa_alloc_hdr = alloc_hdr;
-	alloc_area->aa_free_structs_in_chunk =
-	    (Dwarf_Sword) alloc_hdr->ah_structs_per_chunk - 1;
-	if (alloc_area->aa_free_structs_in_chunk < 1) {
-	    /* If we get here, there is a disastrous programming error
-	       somewhere. */
+        alloc_area->aa_alloc_hdr = alloc_hdr;
+        alloc_area->aa_free_structs_in_chunk =
+            (Dwarf_Sword) alloc_hdr->ah_structs_per_chunk - 1;
+        if (alloc_area->aa_free_structs_in_chunk < 1) {
+            /* If we get here, there is a disastrous programming error
+               somewhere. */
 #ifdef DEBUG
-	    fprintf(stderr,
-		    "libdwarf Internal error: free structs in chunk %d\n",
-		    (int) alloc_area->aa_free_structs_in_chunk);
+            fprintf(stderr,
+                    "libdwarf Internal error: free structs in chunk %d\n",
+                    (int) alloc_area->aa_free_structs_in_chunk);
 #endif
-	    return NULL;
-	}
+            return NULL;
+        }
 
-	/* 
-	   The struct returned begins immediately after the
-	   Dwarf_Alloc_Area_s struct. */
-	ret_mem = mem_block + rounded_area_hdr_size;
-	alloc_area->aa_blob_start =
-	    ret_mem + alloc_hdr->ah_bytes_one_struct;
-	alloc_area->aa_blob_end = mem_block + mem_block_size;
+        /* 
+           The struct returned begins immediately after the
+           Dwarf_Alloc_Area_s struct. */
+        ret_mem = mem_block + rounded_area_hdr_size;
+        alloc_area->aa_blob_start =
+            ret_mem + alloc_hdr->ah_bytes_one_struct;
+        alloc_area->aa_blob_end = mem_block + mem_block_size;
 
-	/* 
-	   Store pointer to chunk this struct belongs to in the first
-	   few bytes.  Return pointer to bytes after this pointer
-	   storage. */
-	*(Dwarf_Alloc_Area *) ret_mem = alloc_area;
-	ret_mem += _DW_RESERVE;
+        /* 
+           Store pointer to chunk this struct belongs to in the first
+           few bytes.  Return pointer to bytes after this pointer
+           storage. */
+        *(Dwarf_Alloc_Area *) ret_mem = alloc_area;
+        ret_mem += DW_RESERVE;
     }
 
     alloc_hdr->ah_last_alloc_area = alloc_area;
     alloc_hdr->ah_struct_user_holds++;
-    memset(ret_mem,0, alloc_hdr->ah_bytes_one_struct - _DW_RESERVE);
+    memset(ret_mem, 0, alloc_hdr->ah_bytes_one_struct - DW_RESERVE);
     return (ret_mem);
 }
 
@@ -420,16 +454,17 @@
     contain, i.e it the length of the string
     plus 1 for the terminating null.  For lists
     of pointers, count is equal to the number of
-    pointers.  For DW_DLA_FRAME_BLOCK, and
+    pointers.  For DW_DLA_FRAME_BLOCK, DW_DLA_RANGES, and 
     DW_DLA_LOC_BLOCK allocation types also, count
     is the count of the number of structs needed.
 
     This function cannot be used to allocate a 
     Dwarf_Debug_s struct.
+
 */
 Dwarf_Ptr
 _dwarf_get_alloc(Dwarf_Debug dbg,
-		 Dwarf_Small alloc_type, Dwarf_Unsigned count)
+                 Dwarf_Small alloc_type, Dwarf_Unsigned count)
 {
     Dwarf_Alloc_Hdr alloc_hdr;
 
@@ -440,12 +475,12 @@
     unsigned int type = alloc_type;
 
     if (dbg == NULL) {
-	return (NULL);
+        return (NULL);
     }
 
     if (type >= ALLOC_AREA_INDEX_TABLE_MAX) {
-	/* internal error */
-	return NULL;
+        /* internal error */
+        return NULL;
     }
     index = index_into_allocated[type].ia_al_num;
     /* zero also illegal but not tested for */
@@ -456,71 +491,109 @@
        special code here.. */
 
     if (index == 0) {
-	if (alloc_type == DW_DLA_STRING) {
-	    size = count;
-	} else if (alloc_type == DW_DLA_LIST) {
-	    size = count * sizeof(Dwarf_Ptr);
-	} else if (alloc_type == DW_DLA_FRAME_BLOCK) {
-	    size = count * sizeof(Dwarf_Frame_Op);
-	} else if (alloc_type == DW_DLA_LOC_BLOCK) {
-	    size = count * sizeof(Dwarf_Loc);
-	} else if (alloc_type == DW_DLA_ADDR) {
-	    size = count *
-		(sizeof(Dwarf_Addr) > sizeof(Dwarf_Off) ?
-		 sizeof(Dwarf_Addr) : sizeof(Dwarf_Off));
-	} else if (alloc_type == DW_DLA_ERROR) {
-	    return _dwarf_special_no_dbg_error_malloc();
-	} else {
-	    /* If we get here, there is a disastrous programming error
-	       somewhere. */
+        if (alloc_type == DW_DLA_STRING) {
+            size = count;
+        } else if (alloc_type == DW_DLA_LIST) {
+            size = count * sizeof(Dwarf_Ptr);
+        } else if (alloc_type == DW_DLA_FRAME_BLOCK) {
+            size = count * sizeof(Dwarf_Frame_Op);
+        } else if (alloc_type == DW_DLA_LOC_BLOCK) {
+            size = count * sizeof(Dwarf_Loc);
+        } else if (alloc_type == DW_DLA_HASH_TABLE_ENTRY) {
+            size = count * sizeof(struct Dwarf_Hash_Table_Entry_s);
+        } else if (alloc_type == DW_DLA_ADDR) {
+            size = count *
+                (sizeof(Dwarf_Addr) > sizeof(Dwarf_Off) ?
+                 sizeof(Dwarf_Addr) : sizeof(Dwarf_Off));
+        } else if (alloc_type == DW_DLA_RANGES) {
+            size = count * sizeof(Dwarf_Ranges);
+        } else if (alloc_type == DW_DLA_ERROR) {
+            void *m = _dwarf_special_no_dbg_error_malloc();
+
+            dwarf_malloc_check_alloc_data(m, DW_DLA_ERROR);
+            return m;
+
+        } else {
+            /* If we get here, there is a disastrous programming error
+               somewhere. */
 #ifdef DEBUG
-	    fprintf(stderr,
-		    "libdwarf Internal error: type %d  unexpected\n",
-		    (int) type);
+            fprintf(stderr,
+                    "libdwarf Internal error: type %d  unexpected\n",
+                    (int) type);
 #endif
-	}
+        }
     } else {
-	alloc_hdr = &dbg->de_alloc_hdr[index];
-	if (alloc_hdr->ah_bytes_one_struct > 0) {
+        alloc_hdr = &dbg->de_alloc_hdr[index];
+        if (alloc_hdr->ah_bytes_one_struct > 0) {
 #ifdef DWARF_SIMPLE_MALLOC
-	    size = alloc_hdr->ah_bytes_one_struct;
+            size = alloc_hdr->ah_bytes_one_struct;
 #else
-	    return (_dwarf_find_memory(alloc_hdr));
+            {
+                void *m = _dwarf_find_memory(alloc_hdr);
+
+                dwarf_malloc_check_alloc_data(m, type);
+                if (index_into_allocated[type].specialconstructor) {
+                    int res =
+                        index_into_allocated[type].
+                        specialconstructor(dbg, m);
+                    if (res != DW_DLV_OK) {
+                        /* We leak what we allocated in
+                           _dwarf_find_memory when constructor fails. */
+                        return NULL;
+                    }
+                }
+                return m;
+            }
 #endif
 
-	} else {
-	    /* Special case: should not really happen at all. */
-	    if (type == DW_DLA_ERROR) {
-		/* dwarf_init failure. Because dbg is incomplete we
-		   won't use it to record the malloc. */
-		return _dwarf_special_no_dbg_error_malloc();
-	    } else {
-		/* If we get here, there is a disastrous programming
-		   error somewhere. */
+        } else {
+            /* Special case: should not really happen at all. */
+            if (type == DW_DLA_ERROR) {
+                /* dwarf_init failure. Because dbg is incomplete we
+                   won't use it to record the malloc. */
+                void *m = _dwarf_special_no_dbg_error_malloc();
+
+                dwarf_malloc_check_alloc_data(m, DW_DLA_ERROR);
+                return m;
+            } else {
+                /* If we get here, there is a disastrous programming
+                   error somewhere. */
 #ifdef DWARF_SIMPLE_MALLOC
-		_dwarf_simple_malloc_botch(3);
+                _dwarf_simple_malloc_botch(3);
 #endif
 #ifdef DEBUG
-		fprintf(stderr,
-			"libdwarf Internal error: Type %d  unexpected\n",
-			(int) type);
+                fprintf(stderr,
+                        "libdwarf Internal error: Type %d  unexpected\n",
+                        (int) type);
 #endif
-	    }
-	}
+            }
+        }
     }
 
     ret_mem = malloc(size);
 #ifdef DWARF_SIMPLE_MALLOC
-    _dwarf_simple_malloc_add_to_list(dbg,ret_mem,(unsigned long)size,
-		alloc_type);
+    _dwarf_simple_malloc_add_to_list(dbg, ret_mem, (unsigned long) size,
+                                     type);
 #endif
     if (ret_mem != NULL)
-	memset(ret_mem,0, size);
+        memset(ret_mem, 0, size);
+
+    dwarf_malloc_check_alloc_data(ret_mem, type);
+    if (index_into_allocated[type].specialconstructor) {
+        int res =
+            index_into_allocated[type].specialconstructor(dbg, ret_mem);
+        if (res != DW_DLV_OK) {
+            /* We leak what we allocated in _dwarf_find_memory when
+               constructor fails. */
+            return NULL;
+        }
+    }
 
     return (ret_mem);
 }
 
 
+
 /*
     This function is used to deallocate a region of memory
     that was obtained by a call to _dwarf_get_alloc.  Note
@@ -531,7 +604,7 @@
     that the space was allocated by a direct call to malloc,
     and so a straight free() is done.  This is also the case
     for variable length blocks such as DW_DLA_FRAME_BLOCK
-    and DW_DLA_LOC_BLOCK.
+    and DW_DLA_LOC_BLOCK and DW_DLA_RANGES.
 
     For strings, the pointer might point to a string in 
     .debug_info or .debug_string.  After this is checked,
@@ -551,7 +624,7 @@
 */
 void
 dwarf_dealloc(Dwarf_Debug dbg,
-	      Dwarf_Ptr space, Dwarf_Unsigned alloc_type)
+              Dwarf_Ptr space, Dwarf_Unsigned alloc_type)
 {
     Dwarf_Alloc_Hdr alloc_hdr;
     Dwarf_Alloc_Area alloc_area;
@@ -559,145 +632,167 @@
     unsigned int index;
 
     if (space == NULL) {
-	return;
+        return;
     }
-    if (alloc_type == DW_DLA_ERROR) {
-	/* Get pointer to Dwarf_Alloc_Area this struct came from. See
-	   dwarf_alloc.h ROUND_SIZE_WITH_POINTER stuff */
-	alloc_area =
-	    *(Dwarf_Alloc_Area *) ((char *) space - _DW_RESERVE);
-	if (alloc_area == 0) {
-	    /* This is the special case of a failed dwarf_init(). Also
-	       (and more signficantly) there are a variety of other
-	       situations where libdwarf does not *know* what dbg is
-	       involved (because of a libdwarf-caller-error) so
-	       libdwarf uses NULL as the dbg. Those too wind up here. */
-	    _dwarf_free_special_error(space);
-	    return;
-	}
+    if (type == DW_DLA_ERROR) {
+        /* Get pointer to Dwarf_Alloc_Area this struct came from. See
+           dwarf_alloc.h ROUND_SIZE_WITH_POINTER stuff */
+        alloc_area =
+            *(Dwarf_Alloc_Area *) ((char *) space - DW_RESERVE);
+        if (alloc_area == 0) {
+            /* This is the special case of a failed dwarf_init(). Also
+               (and more signficantly) there are a variety of other
+               situations where libdwarf does not *know* what dbg is
+               involved (because of a libdwarf-caller-error) so
+               libdwarf uses NULL as the dbg. Those too wind up here. */
+            _dwarf_free_special_error(space);
+            dwarf_malloc_check_dealloc_data(space, type);
+            return;
+        }
 
     }
     if (dbg == NULL) {
-	/* App error, or an app that failed to succeed in a
-	   dwarf_init() call. */
-	return;
+        /* App error, or an app that failed to succeed in a
+           dwarf_init() call. */
+        return;
     }
     if (type >= ALLOC_AREA_INDEX_TABLE_MAX) {
-	/* internal or user app error */
-	return;
+        /* internal or user app error */
+        return;
     }
 
-    index = index_into_allocated[alloc_type].ia_al_num;
+    index = index_into_allocated[type].ia_al_num;
     /* 
        A string pointer may point into .debug_info or .debug_string.
        Otherwise, they are directly malloc'ed. */
+    dwarf_malloc_check_dealloc_data(space, type);
     if (index == 0) {
-	if (alloc_type == DW_DLA_STRING) {
-	    if ((Dwarf_Small *) space >= dbg->de_debug_info &&
-		(Dwarf_Small *) space <
-		dbg->de_debug_info + dbg->de_debug_info_size)
-		return;
+        if (type == DW_DLA_STRING) {
+            if ((Dwarf_Small *) space >= dbg->de_debug_info.dss_data &&
+                (Dwarf_Small *) space <
+                dbg->de_debug_info.dss_data + dbg->de_debug_info.dss_size)
+                return;
 
-	    if (dbg->de_debug_line != NULL &&
-		(Dwarf_Small *) space >= dbg->de_debug_line &&
-		(Dwarf_Small *) space <
-		dbg->de_debug_line + dbg->de_debug_line_size)
-		return;
+            if (dbg->de_debug_line.dss_data != NULL &&
+                (Dwarf_Small *) space >= dbg->de_debug_line.dss_data &&
+                (Dwarf_Small *) space <
+                dbg->de_debug_line.dss_data + dbg->de_debug_line.dss_size)
+                return;
 
-	    if (dbg->de_debug_pubnames != NULL &&
-		(Dwarf_Small *) space >= dbg->de_debug_pubnames &&
-		(Dwarf_Small *) space <
-		dbg->de_debug_pubnames + dbg->de_debug_pubnames_size)
-		return;
+            if (dbg->de_debug_pubnames.dss_data != NULL &&
+                (Dwarf_Small *) space >= dbg->de_debug_pubnames.dss_data &&
+                (Dwarf_Small *) space <
+                dbg->de_debug_pubnames.dss_data + 
+                dbg->de_debug_pubnames.dss_size)
+                return;
+
+            if (dbg->de_debug_frame.dss_data != NULL &&
+                (Dwarf_Small *) space >= dbg->de_debug_frame.dss_data &&
+                (Dwarf_Small *) space <
+                dbg->de_debug_frame.dss_data + dbg->de_debug_frame.dss_size)
+                return;
 
-	    if (dbg->de_debug_frame != NULL &&
-		(Dwarf_Small *) space >= dbg->de_debug_frame &&
-		(Dwarf_Small *) space <
-		dbg->de_debug_frame + dbg->de_debug_frame_size)
-		return;
+            if (dbg->de_debug_str.dss_data != NULL &&
+                (Dwarf_Small *) space >= dbg->de_debug_str.dss_data &&
+                (Dwarf_Small *) space <
+                dbg->de_debug_str.dss_data + dbg->de_debug_str.dss_size)
+                return;
 
-	    if (dbg->de_debug_str != NULL &&
-		(Dwarf_Small *) space >= dbg->de_debug_str &&
-		(Dwarf_Small *) space <
-		dbg->de_debug_str + dbg->de_debug_str_size)
-		return;
+            if (dbg->de_debug_funcnames.dss_data != NULL &&
+                (Dwarf_Small *) space >= dbg->de_debug_funcnames.dss_data &&
+                (Dwarf_Small *) space <
+                dbg->de_debug_funcnames.dss_data + 
+                dbg->de_debug_funcnames.dss_size)
+                return;
 
-	    if (dbg->de_debug_funcnames != NULL &&
-		(Dwarf_Small *) space >= dbg->de_debug_funcnames &&
-		(Dwarf_Small *) space <
-		dbg->de_debug_funcnames + dbg->de_debug_funcnames_size)
-		return;
+            if (dbg->de_debug_typenames.dss_data != NULL &&
+                (Dwarf_Small *) space >= dbg->de_debug_typenames.dss_data &&
+                (Dwarf_Small *) space <
+                dbg->de_debug_typenames.dss_data + 
+                dbg->de_debug_typenames.dss_size)
+                return;
+            if (dbg->de_debug_pubtypes.dss_data != NULL &&
+                (Dwarf_Small *) space >= dbg->de_debug_pubtypes.dss_data &&
+                (Dwarf_Small *) space <
+                    dbg->de_debug_pubtypes.dss_data + 
+                    dbg->de_debug_pubtypes.dss_size)
+                return;
 
-	    if (dbg->de_debug_typenames != NULL &&
-		(Dwarf_Small *) space >= dbg->de_debug_typenames &&
-		(Dwarf_Small *) space <
-		dbg->de_debug_typenames + dbg->de_debug_typenames_size)
-		return;
-
-	    if (dbg->de_debug_varnames != NULL &&
-		(Dwarf_Small *) space >= dbg->de_debug_varnames &&
-		(Dwarf_Small *) space <
-		dbg->de_debug_varnames + dbg->de_debug_varnames_size)
-		return;
+            if (dbg->de_debug_varnames.dss_data != NULL &&
+                (Dwarf_Small *) space >= dbg->de_debug_varnames.dss_data &&
+                (Dwarf_Small *) space <
+                dbg->de_debug_varnames.dss_data + 
+                dbg->de_debug_varnames.dss_size)
+                return;
 
-	    if (dbg->de_debug_weaknames != NULL &&
-		(Dwarf_Small *) space >= dbg->de_debug_weaknames &&
-		(Dwarf_Small *) space <
-		dbg->de_debug_weaknames + dbg->de_debug_weaknames_size)
-		return;
+            if (dbg->de_debug_weaknames.dss_data != NULL &&
+                (Dwarf_Small *) space >= dbg->de_debug_weaknames.dss_data &&
+                (Dwarf_Small *) space <
+                dbg->de_debug_weaknames.dss_data + 
+                dbg->de_debug_weaknames.dss_size)
+                return;
 
-	    free(space);
-	    return;
-	}
+#ifdef DWARF_SIMPLE_MALLOC
+            _dwarf_simple_malloc_delete_from_list(dbg, space, type);
+#endif
+            free(space);
+            return;
+        }
 
-	if (alloc_type == DW_DLA_LIST ||
-	    alloc_type == DW_DLA_FRAME_BLOCK ||
-	    alloc_type == DW_DLA_LOC_BLOCK ||
-	    alloc_type == DW_DLA_ADDR) {
+        if (type == DW_DLA_LIST ||
+            type == DW_DLA_FRAME_BLOCK ||
+            type == DW_DLA_LOC_BLOCK || type == DW_DLA_ADDR ||
+            type == DW_DLA_RANGES ||
+            type == DW_DLA_HASH_TABLE_ENTRY) {
 
-	    free(space);
-	    return;
-	}
-	/* else is an alloc type that is not used */
-	/* app or internal error */
+#ifdef DWARF_SIMPLE_MALLOC
+            _dwarf_simple_malloc_delete_from_list(dbg, space, type);
+#endif
+            free(space);
+            return;
+        }
+        /* else is an alloc type that is not used */
+        /* app or internal error */
 #ifdef DWARF_SIMPLE_MALLOC
         _dwarf_simple_malloc_botch(4);
 #endif
-	return;
+        return;
 
     }
-
+    if (index_into_allocated[type].specialdestructor) {
+        index_into_allocated[type].specialdestructor(space);
+    }
 #ifdef DWARF_SIMPLE_MALLOC
-    _dwarf_simple_malloc_delete_from_list(dbg, space, alloc_type);
+    _dwarf_simple_malloc_delete_from_list(dbg, space, type);
     free(space);
-#else  /* !DWARF_SIMPLE_MALLOC */
+#else /* !DWARF_SIMPLE_MALLOC */
     alloc_hdr = &dbg->de_alloc_hdr[index];
 
     /* Get pointer to Dwarf_Alloc_Area this struct came from. See
        dwarf_alloc.h ROUND_SIZE_WITH_POINTER stuff */
-    alloc_area = *(Dwarf_Alloc_Area *) ((char *) space - _DW_RESERVE);
+    alloc_area = *(Dwarf_Alloc_Area *) ((char *) space - DW_RESERVE);
 
-    /* ASSERT: alloc_area != NULL
-       If NULL we could abort, let it coredump below, 
-       or return, pretending all is well. We go
-       on, letting program crash. Is caller error. */
+    /* ASSERT: alloc_area != NULL If NULL we could abort, let it
+       coredump below, or return, pretending all is well. We go on,
+       letting program crash. Is caller error. */
 
     /* 
        Check that the alloc_hdr field of the alloc_area we have is
        pointing to the right alloc_hdr.  This is used to catch use of
        incorrect deallocation code by the user. */
     if (alloc_area->aa_alloc_hdr != alloc_hdr) {
-	/* If we get here, the user has called dwarf_dealloc wrongly or 
-	   there is some other disastrous error. By leaking mem here we 
-	   try to be safe... */
+        /* If we get here, the user has called dwarf_dealloc wrongly or 
+           there is some other disastrous error. By leaking mem here we 
+           try to be safe... */
 #ifdef DEBUG
-	fprintf(stderr,
-		"libdwarf Internal error: type %d hdr mismatch %x %x area ptr %x\n",
-		(int) alloc_type,
-		(int) alloc_area->aa_alloc_hdr,
-		(int) alloc_hdr, (int) alloc_area);
+        fprintf(stderr,
+                "libdwarf Internal error: type %d hdr mismatch %lx %lx "
+                "area ptr %lx\n",
+                (int) type,
+                (long) alloc_area->aa_alloc_hdr,
+                (long) alloc_hdr, (long) alloc_area);
 #endif
-	return;
+        return;
     }
 
     alloc_hdr->ah_struct_user_holds--;
@@ -706,29 +801,29 @@
     /* 
        Give chunk back to malloc only when every struct is freed */
     if (alloc_area->aa_free_structs_in_chunk ==
-	alloc_hdr->ah_structs_per_chunk) {
-	if (alloc_area->aa_prev != NULL) {
-	    alloc_area->aa_prev->aa_next = alloc_area->aa_next;
-	} else {
-	    alloc_hdr->ah_alloc_area_head = alloc_area->aa_next;
-	}
+        alloc_hdr->ah_structs_per_chunk) {
+        if (alloc_area->aa_prev != NULL) {
+            alloc_area->aa_prev->aa_next = alloc_area->aa_next;
+        } else {
+            alloc_hdr->ah_alloc_area_head = alloc_area->aa_next;
+        }
 
-	if (alloc_area->aa_next != NULL) {
-	    alloc_area->aa_next->aa_prev = alloc_area->aa_prev;
-	}
+        if (alloc_area->aa_next != NULL) {
+            alloc_area->aa_next->aa_prev = alloc_area->aa_prev;
+        }
 
-	alloc_hdr->ah_chunks_allocated--;
+        alloc_hdr->ah_chunks_allocated--;
 
-	if (alloc_area == alloc_hdr->ah_last_alloc_area) {
-	    alloc_hdr->ah_last_alloc_area = NULL;
-	}
-	memset(alloc_area,0, sizeof(*alloc_area));
-	free(alloc_area);
+        if (alloc_area == alloc_hdr->ah_last_alloc_area) {
+            alloc_hdr->ah_last_alloc_area = NULL;
+        }
+        memset(alloc_area, 0, sizeof(*alloc_area));
+        free(alloc_area);
     }
 
     else {
-	((Dwarf_Free_List) space)->fl_next = alloc_area->aa_free_list;
-	alloc_area->aa_free_list = space;
+        ((Dwarf_Free_List) space)->fl_next = alloc_area->aa_free_list;
+        alloc_area->aa_free_list = space;
     }
 #endif /* !DWARF_SIMPLE_MALLOC */
 }
@@ -746,10 +841,9 @@
 
     dbg = (Dwarf_Debug) malloc(sizeof(struct Dwarf_Debug_s));
     if (dbg == NULL)
-	return (NULL);
+        return (NULL);
     else
-	memset(dbg,0, sizeof(struct Dwarf_Debug_s));
-
+        memset(dbg, 0, sizeof(struct Dwarf_Debug_s));
     return (dbg);
 }
 
@@ -758,7 +852,7 @@
     Sets up the Dwarf_Debug_s struct for all the
     allocation types currently defined.  
     Allocation types DW_DLA_STRING, DW_DLA_LIST,
-    DW_DLA_FRAME_BLOCK, DW_DLA_LOC_BLOCK are 
+    DW_DLA_FRAME_BLOCK, DW_DLA_LOC_BLOCK, DW_DLA_RANGES are 
     malloc'ed directly.
 
     This routine should be called after _dwarf_setup(),
@@ -781,13 +875,6 @@
     need to be initialized.
 
     Being an internal routine, assume proper dbg.
-
-
-
-
-*/
-/* 
-**  Set up all the Dwarf_Alloc_Hdr records.
 */
 
 Dwarf_Debug
@@ -796,19 +883,19 @@
     int i;
 
     for (i = 1; i <= MAX_DW_DLA; i++) {
-	const struct ial_s *ialp = &index_into_allocated[i];
-	unsigned int hdr_index = ialp->ia_al_num;
-	Dwarf_Word str_size = ialp->ia_struct_size;
-	Dwarf_Word str_count = ialp->ia_base_count;
-	Dwarf_Word rnded_size = ROUND_SIZE_WITH_POINTER(str_size);
+        const struct ial_s *ialp = &index_into_allocated[i];
+        unsigned int hdr_index = ialp->ia_al_num;
+        Dwarf_Word str_size = ialp->ia_struct_size;
+        Dwarf_Word str_count = ialp->ia_base_count;
+        Dwarf_Word rnded_size = ROUND_SIZE_WITH_POINTER(str_size);
 
-	Dwarf_Alloc_Hdr alloc_hdr = &dbg->de_alloc_hdr[hdr_index];
+        Dwarf_Alloc_Hdr alloc_hdr = &dbg->de_alloc_hdr[hdr_index];
 
-	alloc_hdr->ah_bytes_one_struct = (Dwarf_Half) rnded_size;
+        alloc_hdr->ah_bytes_one_struct = (Dwarf_Half) rnded_size;
 
-	/* ah_structs_per_chunk must be >0 else we are in trouble */
-	alloc_hdr->ah_structs_per_chunk = str_count;
-	alloc_hdr->ah_bytes_malloc_per_chunk = rnded_size * str_count;
+        /* ah_structs_per_chunk must be >0 else we are in trouble */
+        alloc_hdr->ah_structs_per_chunk = str_count;
+        alloc_hdr->ah_bytes_malloc_per_chunk = rnded_size * str_count;
     }
     return (dbg);
 }
@@ -824,86 +911,89 @@
     Dwarf_Shalf i;
 
     /* 
-       Alloc types start at 1, not 0. Hence, the first NULL string,
-       and also a size of MAX_DW_DLA + 1. */
+       Alloc types start at 1, not 0. Hence, the first NULL string, and 
+       also a size of MAX_DW_DLA + 1. */
     char *alloc_type_name[MAX_DW_DLA + 1] = {
-	"",
-	"DW_DLA_STRING",
-	"DW_DLA_LOC",
-	"DW_DLA_LOCDESC",
-	"DW_DLA_ELLIST",
-	"DW_DLA_BOUNDS",
-	"DW_DLA_BLOCK",
-	"DW_DLA_DEBUG",
-	"DW_DLA_DIE",
-	"DW_DLA_LINE",
-	"DW_DLA_ATTR",
-	"DW_DLA_TYPE",
-	"DW_DLA_SUBSCR",
-	"DW_DLA_GLOBAL",
-	"DW_DLA_ERROR",
-	"DW_DLA_LIST",
-	"DW_DLA_LINEBUF",
-	"DW_DLA_ARANGE",
-	"DW_DLA_ABBREV",
-	"DW_DLA_FRAME_OP",
-	"DW_DLA_CIE",
-	"DW_DLA_FDE",
-	"DW_DLA_LOC_BLOCK",
-	"DW_DLA_FRAME_BLOCK",
-	"DW_DLA_FUNC",
-	"DW_DLA_TYPENAME",
-	"DW_DLA_VAR",
-	"DW_DLA_WEAK",
-	"DW_DLA_ADDR",
-	"DW_DLA_ABBREV_LIST",
-	"DW_DLA_CHAIN",
-	"DW_DLA_CU_CONTEXT",
-	"DW_DLA_FRAME",
-	"DW_DLA_GLOBAL_CONTEXT",
-	"DW_DLA_FILE_ENTRY",
-	"DW_DLA_LINE_CONTEXT",
-	"DW_DLA_LOC_CHAIN",
-	"DW_DLA_HASH_TABLE",
-	"DW_DLA_FUNC_CONTEXT",
-	"DW_DLA_TYPENAME_CONTEXT",
-	"DW_DLA_VAR_CONTEXT",
-	"DW_DLA_WEAK_CONTEXT"
+        "",
+        "DW_DLA_STRING",
+        "DW_DLA_LOC",
+        "DW_DLA_LOCDESC",
+        "DW_DLA_ELLIST",
+        "DW_DLA_BOUNDS",
+        "DW_DLA_BLOCK",
+        "DW_DLA_DEBUG",
+        "DW_DLA_DIE",
+        "DW_DLA_LINE",
+        "DW_DLA_ATTR",
+        "DW_DLA_TYPE",
+        "DW_DLA_SUBSCR",
+        "DW_DLA_GLOBAL",
+        "DW_DLA_ERROR",
+        "DW_DLA_LIST",
+        "DW_DLA_LINEBUF",
+        "DW_DLA_ARANGE",
+        "DW_DLA_ABBREV",
+        "DW_DLA_FRAME_OP",
+        "DW_DLA_CIE",
+        "DW_DLA_FDE",
+        "DW_DLA_LOC_BLOCK",
+        "DW_DLA_FRAME_BLOCK",
+        "DW_DLA_FUNC",
+        "DW_DLA_TYPENAME",
+        "DW_DLA_VAR",
+        "DW_DLA_WEAK",
+        "DW_DLA_ADDR",
+        "DW_DLA_RANGES",
+        "DW_DLA_ABBREV_LIST",
+        "DW_DLA_CHAIN",
+        "DW_DLA_CU_CONTEXT",
+        "DW_DLA_FRAME",
+        "DW_DLA_GLOBAL_CONTEXT",
+        "DW_DLA_FILE_ENTRY",
+        "DW_DLA_LINE_CONTEXT",
+        "DW_DLA_LOC_CHAIN",
+        "DW_DLA_HASH_TABLE",
+        "DW_DLA_FUNC_CONTEXT",
+        "DW_DLA_TYPENAME_CONTEXT",
+        "DW_DLA_VAR_CONTEXT",
+        "DW_DLA_WEAK_CONTEXT",
+        "DW_DLA_PUBTYPES_CONTEXT",
+        "DW_DLA_HASH_TABLE_ENTRY",
     };
 
     if (dbg == NULL)
-	return;
+        return;
 
     printf("Size of Dwarf_Debug        %4ld bytes\n",
-	   (long) sizeof(*dbg));
+           (long) sizeof(*dbg));
     printf("Size of Dwarf_Alloc_Hdr_s  %4ld bytes\n",
-	   (long) sizeof(struct Dwarf_Alloc_Hdr_s));
+           (long) sizeof(struct Dwarf_Alloc_Hdr_s));
     printf("size of Dwarf_Alloc_Area_s %4ld bytes\n",
-	   (long) sizeof(struct Dwarf_Alloc_Area_s));
+           (long) sizeof(struct Dwarf_Alloc_Area_s));
 
     printf("   Alloc Type                   Curr  Structs byt   str\n");
     printf("   ----------                   ----  ------- per   per\n");
     for (i = 1; i <= MAX_DW_DLA; i++) {
-	int indx = index_into_allocated[i].ia_al_num;
+        int indx = index_into_allocated[i].ia_al_num;
 
-	alloc_hdr = &dbg->de_alloc_hdr[indx];
-	if (alloc_hdr->ah_bytes_one_struct != 1) {
-	    printf("%2d %-25s   %6d %8d %6d %6d\n",
-		   (int) i,
-		   alloc_type_name[i],
-		   (int) alloc_hdr->ah_chunks_allocated,
-		   (int) alloc_hdr->ah_struct_user_holds,
-		   (int) alloc_hdr->ah_bytes_malloc_per_chunk,
-		   (int) alloc_hdr->ah_structs_per_chunk);
-	}
+        alloc_hdr = &dbg->de_alloc_hdr[indx];
+        if (alloc_hdr->ah_bytes_one_struct != 1) {
+            printf("%2d %-25s   %6d %8d %6d %6d\n",
+                   (int) i,
+                   alloc_type_name[i],
+                   (int) alloc_hdr->ah_chunks_allocated,
+                   (int) alloc_hdr->ah_struct_user_holds,
+                   (int) alloc_hdr->ah_bytes_malloc_per_chunk,
+                   (int) alloc_hdr->ah_structs_per_chunk);
+        }
     }
 }
 
 
 #ifndef DWARF_SIMPLE_MALLOC
 /*
-    This function is used to recursively
-    free the chunks still allocated, and
+    This recursively frees
+    the chunks still allocated, and
     forward chained through the aa_next
     pointer.
 */
@@ -911,7 +1001,7 @@
 _dwarf_recursive_free(Dwarf_Alloc_Area alloc_area)
 {
     if (alloc_area->aa_next != NULL) {
-	_dwarf_recursive_free(alloc_area->aa_next);
+        _dwarf_recursive_free(alloc_area->aa_next);
     }
 
     alloc_area->aa_next = 0;
@@ -920,6 +1010,18 @@
 }
 #endif
 
+/* In the 'rela' relocation case we might have malloc'd
+   space to ensure it is read-write. In that case, free the space.  */
+static void 
+rela_free(struct Dwarf_Section_s * sec)
+{
+    if (sec->dss_data_was_malloc) {
+        free(sec->dss_data);
+    }
+    sec->dss_data = 0;
+    sec->dss_data_was_malloc = 0;
+}
+
 /*
     Used to free all space allocated for this Dwarf_Debug.
     The caller should assume that the Dwarf_Debug pointer 
@@ -932,46 +1034,80 @@
 {
     Dwarf_Alloc_Hdr alloc_hdr;
     Dwarf_Shalf i;
+    Dwarf_CU_Context context = 0;
+    Dwarf_CU_Context nextcontext = 0;
 
     if (dbg == NULL)
-	return (DW_DLV_ERROR);
+        return (DW_DLV_ERROR);
+
+    /* To do complete validation that we have no surprising missing or
+       erroneous deallocs it is advisable to do the dwarf_deallocs here 
+       that are not things the user can otherwise request.
+       Housecleaning.  */
 
-#ifdef DWARF_SIMPLE_MALLOC
-    if(dbg->de_simple_malloc_base) {
-	struct simple_malloc_record_s *smp = dbg->de_simple_malloc_base;
-	while( smp)
-	{
-	    int i;
-	    struct simple_malloc_record_s *prev_smp = 0;
+    for (context = dbg->de_cu_context_list;
+         context; context = nextcontext) {
+        Dwarf_Hash_Table hash_table = context->cc_abbrev_hash_table;
+        _dwarf_free_abbrev_hash_table_contents(dbg,hash_table);
+        nextcontext = context->cc_next;
+        dwarf_dealloc(dbg, hash_table, DW_DLA_HASH_TABLE);
+        dwarf_dealloc(dbg, context, DW_DLA_CU_CONTEXT);
+    }
 
-	    for(i = 0; i < smp->sr_used; ++i) {
-	        struct simple_malloc_entry_s *cur;
-		cur = &smp->sr_entry[i];
-		if(cur->se_addr != 0) {
-		     free(cur->se_addr);
-		     cur->se_addr = 0;
-	        }
-	    }
-	    prev_smp = smp;
-	    smp = smp->sr_next;
-	    free(prev_smp);
-	}
-	dbg->de_simple_malloc_base = 0;
-	dbg->de_simple_malloc_current = 0;
+    /* Housecleaning done. Now really free all the space. */
+#ifdef DWARF_SIMPLE_MALLOC
+    if (dbg->de_simple_malloc_base) {
+        struct simple_malloc_record_s *smp = dbg->de_simple_malloc_base;
+
+        while (smp) {
+            int i;
+            struct simple_malloc_record_s *prev_smp = 0;
+
+            for (i = 0; i < smp->sr_used; ++i) {
+                struct simple_malloc_entry_s *cur;
+
+                cur = &smp->sr_entry[i];
+                if (cur->se_addr != 0) {
+                    free(cur->se_addr);
+                    cur->se_addr = 0;
+                }
+            }
+            prev_smp = smp;
+            smp = smp->sr_next;
+            free(prev_smp);
+        }
+        dbg->de_simple_malloc_base = 0;
     }
 #else
     for (i = 1; i < ALLOC_AREA_REAL_TABLE_MAX; i++) {
-	int indx = i;
+        int indx = i;
 
-	alloc_hdr = &dbg->de_alloc_hdr[indx];
-	if (alloc_hdr->ah_alloc_area_head != NULL) {
-	    _dwarf_recursive_free(alloc_hdr->ah_alloc_area_head);
-	}
+        alloc_hdr = &dbg->de_alloc_hdr[indx];
+        if (alloc_hdr->ah_alloc_area_head != NULL) {
+            _dwarf_recursive_free(alloc_hdr->ah_alloc_area_head);
+        }
     }
 
 #endif
+    rela_free(&dbg->de_debug_info);
+    rela_free(&dbg->de_debug_abbrev);
+    rela_free(&dbg->de_debug_line);
+    rela_free(&dbg->de_debug_loc);
+    rela_free(&dbg->de_debug_aranges);
+    rela_free(&dbg->de_debug_macinfo);
+    rela_free(&dbg->de_debug_pubnames);
+    rela_free(&dbg->de_debug_str);
+    rela_free(&dbg->de_debug_frame);
+    rela_free(&dbg->de_debug_frame_eh_gnu);
+    rela_free(&dbg->de_debug_pubtypes);
+    rela_free(&dbg->de_debug_funcnames);
+    rela_free(&dbg->de_debug_typenames);
+    rela_free(&dbg->de_debug_varnames);
+    rela_free(&dbg->de_debug_weaknames);
+    rela_free(&dbg->de_debug_ranges);
+    dwarf_harmless_cleanout(&dbg->de_harmless_errors);
 
-    memset(dbg,0, sizeof(*dbg));	/* prevent accidental use later */
+    memset(dbg, 0, sizeof(*dbg)); /* Prevent accidental use later. */
     free(dbg);
     return (DW_DLV_OK);
 }
@@ -989,21 +1125,21 @@
 {
     /* the union unused things are to guarantee proper alignment */
     union u {
-	Dwarf_Alloc_Area ptr_not_used;
-	struct Dwarf_Error_s base_not_used;
-	char data_space[sizeof(struct Dwarf_Error_s) +
-			(_DW_RESERVE * 2)];
+        Dwarf_Alloc_Area ptr_not_used;
+        struct Dwarf_Error_s base_not_used;
+        char data_space[sizeof(struct Dwarf_Error_s) +
+                        (DW_RESERVE * 2)];
     };
     char *mem;
 
     mem = malloc(sizeof(union u));
 
     if (mem == 0) {
-	return 0;
+        return 0;
 
     }
-    memset(mem,0, sizeof(union u));
-    mem += _DW_RESERVE;
+    memset(mem, 0, sizeof(union u));
+    mem += DW_RESERVE;
     return (struct Dwarf_Error_s *) mem;
 }
 
@@ -1014,7 +1150,7 @@
 {
     char *mem = (char *) space;
 
-    mem -= _DW_RESERVE;
+    mem -= DW_RESERVE;
     free(mem);
 }
 
@@ -1025,56 +1161,57 @@
 void
 _dwarf_simple_malloc_botch(int err)
 {
+       fprintf(stderr,"simple malloc botch %d\n",err);
 }
-static void   
+static void
 _dwarf_simple_malloc_add_to_list(Dwarf_Debug dbg,
-	Dwarf_Ptr addr, 
-	unsigned long size,
-	short alloc_type)
+                                 Dwarf_Ptr addr,
+                                 unsigned long size, short alloc_type)
 {
-	struct simple_malloc_record_s *cur;
-	struct simple_malloc_entry_s *newentry;
-	if (!dbg->de_simple_malloc_current) {
-	  /* First entry to this routine. */
-	  dbg->de_simple_malloc_current = 
-		malloc(sizeof(struct simple_malloc_record_s));
-	  if(!dbg->de_simple_malloc_current) {
-		return; /* no memory, give up */
-	  }
-	  memset(dbg->de_simple_malloc_current, 
-		0,
-		sizeof(struct simple_malloc_record_s));
-	  dbg->de_simple_malloc_base = dbg->de_simple_malloc_current;
-	}
-	cur = dbg->de_simple_malloc_current;
+    struct simple_malloc_record_s *cur;
+    struct simple_malloc_entry_s *newentry;
+
+    if (!dbg->de_simple_malloc_base) {
+        /* First entry to this routine. */
+        dbg->de_simple_malloc_base =
+            malloc(sizeof(struct simple_malloc_record_s));
+        if (!dbg->de_simple_malloc_base) {
+            _dwarf_simple_malloc_botch(7);
+            return;             /* no memory, give up */
+        }
+        memset(dbg->de_simple_malloc_base,
+               0, sizeof(struct simple_malloc_record_s));
+    }
+    cur = dbg->de_simple_malloc_base;
+
+    if (cur->sr_used >= DSM_BLOCK_COUNT) {
+        /* Better not be > than as that means chaos */
 
-	if(cur->sr_used >= DSM_BLOCK_COUNT) {
-	    /* better not be > than as that means chaos */
-
-	    /* Create a new block to link at the head. */
+        /* Create a new block to link at the head. */
 
-	    struct simple_malloc_record_s *newblock =
-	        malloc(sizeof(struct simple_malloc_record_s));
-	    if(!newblock) {
-		return; /* Can do nothing, out of memory */
-	    }
-	    memset(newblock,0, sizeof(struct simple_malloc_record_s));
-	    /* Link the new block at the head of the chain,
-	       and make it 'current'
-	    */
-	    dbg->de_simple_malloc_current = newblock;
-	    newblock->sr_next = cur;
-	    cur = newblock;
-	}
-	newentry = &cur->sr_entry[cur->sr_used];
-	newentry->se_addr = addr;
-	newentry->se_size = size;
-	newentry->se_type = alloc_type;
-	++cur->sr_used;
+        struct simple_malloc_record_s *newblock =
+            malloc(sizeof(struct simple_malloc_record_s));
+        if (!newblock) {
+            _dwarf_simple_malloc_botch(8);
+            return;             /* Can do nothing, out of memory */
+        }
+        memset(newblock, 0, sizeof(struct simple_malloc_record_s));
+        /* Link the new block at the head of the chain, and make it
+           'current' */
+        dbg->de_simple_malloc_base = newblock;
+        newblock->sr_next = cur;
+        cur = newblock;
+    }
+    newentry = &cur->sr_entry[cur->sr_used];
+    newentry->se_addr = addr;
+    newentry->se_size = size;
+    newentry->se_type = alloc_type;
+    ++cur->sr_used;
 }
+
 /*
-   DWARF_SIMPLE_MALLOC is for testing the hypothesis that the existing
-   complex malloc scheme in libdwarf is pointless complexity.
+   DWARF_SIMPLE_MALLOC: testing the hypothesis that the existing
+   malloc scheme here (see _dwarf_get_alloc()) is pointless complexity.
 
    DWARF_SIMPLE_MALLOC also makes it easy for a malloc-tracing
    tool to verify libdwarf malloc has no botches (though of course
@@ -1086,37 +1223,36 @@
 
 */
 static void
-_dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg, 
-	Dwarf_Ptr space, 
-	short alloc_type)
+_dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg,
+                                      Dwarf_Ptr space, short alloc_type)
 {
-    if(space == 0) {
-	_dwarf_simple_malloc_botch(6);
+    if (space == 0) {
+        _dwarf_simple_malloc_botch(6);
     }
-    if(dbg->de_simple_malloc_base) {
+    if (dbg->de_simple_malloc_base) {
         struct simple_malloc_record_s *smp = dbg->de_simple_malloc_base;
-        while( smp)
-        {
+
+        while (smp) {
             int i;
 
-            for(i = 0; i < smp->sr_used; ++i) {
+            for (i = 0; i < smp->sr_used; ++i) {
                 struct simple_malloc_entry_s *cur;
+
                 cur = &smp->sr_entry[i];
-                if(cur->se_addr == space) {
-		     if(cur->se_type != alloc_type ) {
-			 _dwarf_simple_malloc_botch(0);
-		     }
-                     cur->se_addr = 0;
-		     return;
+                if (cur->se_addr == space) {
+                    if (cur->se_type != alloc_type) {
+                        _dwarf_simple_malloc_botch(0);
+                    }
+                    cur->se_addr = 0;
+                    return;
                 }
             }
             smp = smp->sr_next;
         }
     }
-    /* Never found the space */
+    /* Never found the space. */
     _dwarf_simple_malloc_botch(1);
     return;
 
 }
 #endif
-
--- a/usr/src/tools/ctf/dwarf/common/dwarf_alloc.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_alloc.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2008-2010  David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +18,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -33,7 +34,7 @@
 
 */
 
-
+/* #define DWARF_SIMPLE_MALLOC 1  */
 
 Dwarf_Ptr _dwarf_get_alloc(Dwarf_Debug, Dwarf_Small, Dwarf_Unsigned);
 Dwarf_Debug _dwarf_get_debug(void);
@@ -43,8 +44,17 @@
 typedef struct Dwarf_Alloc_Area_s *Dwarf_Alloc_Area;
 typedef struct Dwarf_Free_List_s *Dwarf_Free_List;
 
-#define ALLOC_AREA_INDEX_TABLE_MAX 42
-#define ALLOC_AREA_REAL_TABLE_MAX 31
+/* ALLOC_AREA_INDEX_TABLE_MAX is the size of the
+   struct ial_s index_into_allocated array in dwarf_alloc.c
+*/
+#define ALLOC_AREA_INDEX_TABLE_MAX 45
+/* ALLOC_AREA_REAL_TABLE_MAX is the size of the array needed
+   to hold pointers to dwarf alloc chunk areas.
+   It's smaller as some of the index_into_allocated 
+   entries (they look like {0,1,1,0,0} )
+   are treated specially and don't use 'chunks'.
+*/
+#define ALLOC_AREA_REAL_TABLE_MAX 32
 
 /* 
     This struct is used to chain all the deallocated
--- a/usr/src/tools/ctf/dwarf/common/dwarf_arange.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_arange.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -32,6 +33,13 @@
   http://oss.sgi.com/projects/GenInfo/NoticeExplan
 
 */
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
 
 
 
@@ -40,8 +48,215 @@
 #include "dwarf_incl.h"
 #include <stdio.h>
 #include "dwarf_arange.h"
+#include "dwarf_global.h"       /* for _dwarf_fixup_* */
 
 
+/* Common code for two user-visible routines to share. 
+   Errors here result in memory leaks, but errors here
+   are serious (making aranges unusable) so we assume
+   callers will not repeat the error often or mind the leaks.
+*/
+static int
+dwarf_get_aranges_list(Dwarf_Debug dbg,
+    Dwarf_Chain  * chain_out,
+    Dwarf_Signed * chain_count_out,
+    Dwarf_Error  * error)
+{
+    /* Sweeps through the arange. */
+    Dwarf_Small *arange_ptr = 0;
+    Dwarf_Small *arange_ptr_start = 0;
+
+    /* Start of arange header.  Used for rounding offset of arange_ptr
+       to twice the tuple size.  Libdwarf requirement. */
+    Dwarf_Small *header_ptr = 0;
+
+    /* Version of .debug_aranges header. */
+    Dwarf_Half version = 0;
+
+    /* Offset of current set of aranges into .debug_info. */
+    Dwarf_Off info_offset = 0;
+
+    /* Size in bytes of addresses in target. */
+    Dwarf_Small address_size = 0;
+
+    /* Size in bytes of segment offsets in target. */
+    Dwarf_Small segment_size = 0;
+
+    /* Count of total number of aranges. */
+    Dwarf_Unsigned arange_count = 0;
+
+    Dwarf_Arange arange = 0;
+
+    /* Used to chain Dwarf_Aranges structs. */
+    Dwarf_Chain curr_chain = NULL;
+    Dwarf_Chain prev_chain = NULL;
+    Dwarf_Chain head_chain = NULL;
+
+    arange_ptr = dbg->de_debug_aranges.dss_data;
+    arange_ptr_start = arange_ptr;
+    do {
+        /* Length of current set of aranges. */
+        Dwarf_Unsigned length = 0;
+        Dwarf_Small remainder = 0;
+        Dwarf_Small *arange_ptr_past_end = 0;
+        Dwarf_Unsigned range_entry_size = 0;
+
+        int local_length_size;
+
+         /*REFERENCED*/ /* Not used in this instance of the macro */
+        int local_extension_size = 0;
+
+        header_ptr = arange_ptr;
+
+        /* READ_AREA_LENGTH updates arange_ptr for consumed bytes */
+        READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
+            arange_ptr, local_length_size,
+            local_extension_size);
+        arange_ptr_past_end = arange_ptr + length;
+
+
+        READ_UNALIGNED(dbg, version, Dwarf_Half,
+            arange_ptr, sizeof(Dwarf_Half));
+        arange_ptr += sizeof(Dwarf_Half);
+        length = length - sizeof(Dwarf_Half);
+        if (version != CURRENT_VERSION_STAMP) {
+            _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
+            return (DW_DLV_ERROR);
+        }
+
+        READ_UNALIGNED(dbg, info_offset, Dwarf_Off,
+            arange_ptr, local_length_size);
+        arange_ptr += local_length_size;
+        length = length - local_length_size;
+        if (info_offset >= dbg->de_debug_info.dss_size) {
+            FIX_UP_OFFSET_IRIX_BUG(dbg, info_offset,
+                "arange info offset.a");
+            if (info_offset >= dbg->de_debug_info.dss_size) {
+                _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD);
+                return (DW_DLV_ERROR);
+            }
+        }
+
+        address_size = *(Dwarf_Small *) arange_ptr;
+        /* It is not an error if the sizes differ.
+           Unusual, but not an error. */
+        arange_ptr = arange_ptr + sizeof(Dwarf_Small);
+        length = length - sizeof(Dwarf_Small);
+
+        segment_size = *(Dwarf_Small *) arange_ptr;
+        arange_ptr = arange_ptr + sizeof(Dwarf_Small);
+        length = length - sizeof(Dwarf_Small);
+        if (segment_size != 0) {
+            _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD);
+            return (DW_DLV_ERROR);
+        }
+
+        range_entry_size = 2*address_size + segment_size;
+        /* Round arange_ptr offset to next multiple of address_size. */
+        remainder = (Dwarf_Unsigned) (arange_ptr - header_ptr) %
+            (range_entry_size);
+        if (remainder != 0) {
+            arange_ptr = arange_ptr + (2 * address_size) - remainder;
+            length = length - ((2 * address_size) - remainder);
+        }
+        do {
+            Dwarf_Addr range_address = 0;
+            Dwarf_Unsigned segment_selector = 0;
+            Dwarf_Unsigned range_length = 0;
+            /* For segmented address spaces, the first field to
+               read is a segment selector (new in DWARF4) */
+            if(version == 4 && segment_size != 0) {
+                READ_UNALIGNED(dbg, segment_selector, Dwarf_Unsigned,
+                    arange_ptr, segment_size);
+                arange_ptr += address_size;
+                length = length - address_size;
+            }
+
+            READ_UNALIGNED(dbg, range_address, Dwarf_Addr,
+                arange_ptr, address_size);
+            arange_ptr += address_size;
+            length = length - address_size;
+
+            READ_UNALIGNED(dbg, range_length, Dwarf_Unsigned,
+                arange_ptr, address_size);
+            arange_ptr += address_size;
+            length = length - address_size;
+
+            { /* We used to suppress all-zero entries, but
+                 now we return all aranges entries so we show
+                 the entire content.  March 31, 2010. */
+
+                arange = (Dwarf_Arange)
+                    _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
+                if (arange == NULL) {
+                    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+                    return (DW_DLV_ERROR);
+                }
+
+                arange->ar_segment_selector = segment_selector;
+                arange->ar_segment_selector_size = segment_size;
+                arange->ar_address = range_address;
+                arange->ar_length = range_length;
+                arange->ar_info_offset = info_offset;
+                arange->ar_dbg = dbg;
+                arange_count++;
+
+                curr_chain = (Dwarf_Chain)
+                    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+                if (curr_chain == NULL) {
+                    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+                    return (DW_DLV_ERROR);
+                }
+
+                curr_chain->ch_item = arange;
+                if (head_chain == NULL)
+                    head_chain = prev_chain = curr_chain;
+                else {
+                    prev_chain->ch_next = curr_chain;
+                    prev_chain = curr_chain;
+                }
+            }
+            /* The current set of ranges is terminated by
+               range_address 0 and range_length 0, but that
+               does not necessarily terminate the ranges for this CU! 
+               There can be multiple sets in that DWARF
+               does not explicitly forbid multiple sets. 
+               DWARF2,3,4 section 7.20 
+               We stop short to avoid overrun of the end of the CU.
+               */
+              
+        } while (arange_ptr_past_end >= (arange_ptr + range_entry_size));
+
+        /* A compiler could emit some padding bytes here. dwarf2/3
+           (dwarf4 sec 7.20) does not clearly make extra padding 
+           bytes illegal. */
+        if (arange_ptr_past_end < arange_ptr) {
+            char buf[200];
+            Dwarf_Unsigned pad_count = arange_ptr - arange_ptr_past_end;
+            Dwarf_Unsigned offset = arange_ptr - arange_ptr_start;
+            snprintf(buf,sizeof(buf),"DW_DLE_ARANGE_LENGTH_BAD."
+                " 0x%" DW_PR_DUx 
+                " pad bytes at offset 0x%" DW_PR_DUx 
+                " in .debug_aranges",
+                pad_count, offset);
+            dwarf_insert_harmless_error(dbg,buf);
+        }
+        /* For most compilers, arange_ptr == arange_ptr_past_end at
+           this point. But not if there were padding bytes */
+        arange_ptr = arange_ptr_past_end;
+    } while (arange_ptr <
+        dbg->de_debug_aranges.dss_data + dbg->de_debug_aranges.dss_size);
+
+    if (arange_ptr !=
+        dbg->de_debug_aranges.dss_data + dbg->de_debug_aranges.dss_size) {
+        _dwarf_error(dbg, error, DW_DLE_ARANGE_DECODE_ERROR);
+        return (DW_DLV_ERROR);
+    }
+    *chain_out = head_chain;
+    *chain_count_out = arange_count;
+    return DW_DLV_OK;
+}
+
 /*
     This function returns the count of the number of
     aranges in the .debug_aranges section.  It sets
@@ -50,208 +265,56 @@
     on error.
 
     Must be identical in most aspects to
-	dwarf_get_aranges_addr_offsets!
+        dwarf_get_aranges_addr_offsets!
+
 */
 int
 dwarf_get_aranges(Dwarf_Debug dbg,
-		  Dwarf_Arange ** aranges,
-		  Dwarf_Signed * returned_count, Dwarf_Error * error)
+    Dwarf_Arange ** aranges,
+    Dwarf_Signed * returned_count, Dwarf_Error * error)
 {
-    /* Sweeps the .debug_aranges section. */
-    Dwarf_Small *arange_ptr;
-
-    /* 
-       Start of arange header.  Used for rounding offset of arange_ptr
-       to twice the tuple size.  Libdwarf requirement. */
-    Dwarf_Small *header_ptr;
-
-
-    /* Version of .debug_aranges header. */
-    Dwarf_Half version;
-
-    /* Offset of current set of aranges into .debug_info. */
-    Dwarf_Off info_offset;
+    /* Count of total number of aranges. */
+    Dwarf_Signed arange_count = 0;
 
-    /* Size in bytes of addresses in target. */
-    Dwarf_Small address_size;
-
-    /* Size in bytes of segment offsets in target. */
-    Dwarf_Small segment_size;
-
-    Dwarf_Small remainder;
-
-    /* Count of total number of aranges. */
-    Dwarf_Unsigned arange_count = 0;
-
-    /* Start address of arange. */
-    Dwarf_Addr range_address;
-
-    /* Length of arange. */
-    Dwarf_Unsigned range_length;
-
-    Dwarf_Arange arange, *arange_block;
-
-    Dwarf_Unsigned i;
+    Dwarf_Arange *arange_block = 0;
 
     /* Used to chain Dwarf_Aranges structs. */
-    Dwarf_Chain curr_chain, prev_chain, head_chain = NULL;
-
-    int res;
+    Dwarf_Chain curr_chain = NULL;
+    Dwarf_Chain prev_chain = NULL;
+    Dwarf_Chain head_chain = NULL;
+    Dwarf_Unsigned i = 0;
+    int res = DW_DLV_ERROR;
 
     /* ***** BEGIN CODE ***** */
 
     if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
 
-    res =
-        _dwarf_load_section(dbg,
-			    dbg->de_debug_aranges_index,
-			    &dbg->de_debug_aranges,
-			    error);
+    res = _dwarf_load_section(dbg, &dbg->de_debug_aranges, error);
     if (res != DW_DLV_OK) {
         return res;
     }
 
-    arange_ptr = dbg->de_debug_aranges;
-    do {
-        /* Length of current set of aranges. */
-        Dwarf_Unsigned length;
-	Dwarf_Small *arange_ptr_past_end = 0;
-
-	int local_length_size;
-	/*REFERENCED*/ /* Not used in this instance of the macro */
-	int local_extension_size;
-
-	header_ptr = arange_ptr;
-
-	/* READ_AREA_LENGTH updates arange_ptr for consumed bytes */
-	READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
-			 arange_ptr, local_length_size,
-			 local_extension_size);
-	arange_ptr_past_end = arange_ptr + length;
-
-
-	READ_UNALIGNED(dbg, version, Dwarf_Half,
-		       arange_ptr, sizeof(Dwarf_Half));
-	arange_ptr += sizeof(Dwarf_Half);
-	length = length - sizeof(Dwarf_Half);
-	if (version != CURRENT_VERSION_STAMP) {
-	    _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
-	    return (DW_DLV_ERROR);
-	}
-
-	READ_UNALIGNED(dbg, info_offset, Dwarf_Off,
-		       arange_ptr, local_length_size);
-	arange_ptr += local_length_size;
-	length = length - local_length_size;
-	if (info_offset >= dbg->de_debug_info_size) {
-	    _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD);
-	    return (DW_DLV_ERROR);
-	}
-
-	address_size = *(Dwarf_Small *) arange_ptr;
-	if (address_size != dbg->de_pointer_size) {
-	    /* Internal error of some kind */
-	    _dwarf_error(dbg, error, DW_DLE_BADBITC);
-	    return (DW_DLV_ERROR);
-	}
-	arange_ptr = arange_ptr + sizeof(Dwarf_Small);
-	length = length - sizeof(Dwarf_Small);
-
-	segment_size = *(Dwarf_Small *) arange_ptr;
-	arange_ptr = arange_ptr + sizeof(Dwarf_Small);
-	length = length - sizeof(Dwarf_Small);
-	if (segment_size != 0) {
-	    _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD);
-	    return (DW_DLV_ERROR);
-	}
-
-	/* Round arange_ptr offset to next multiple of address_size. */
-	remainder = (Dwarf_Unsigned) (arange_ptr - header_ptr) %
-	    (2 * address_size);
-	if (remainder != 0) {
-	    arange_ptr = arange_ptr + (2 * address_size) - remainder;
-	    length = length - ((2 * address_size) - remainder);
-	}
-
-	do {
-	    READ_UNALIGNED(dbg, range_address, Dwarf_Addr,
-			   arange_ptr, address_size);
-	    arange_ptr += address_size;
-	    length = length - address_size;
-
-	    READ_UNALIGNED(dbg, range_length, Dwarf_Unsigned,
-			   arange_ptr, address_size);
-	    arange_ptr += address_size;
-	    length = length - address_size;
-
-	    if (range_address != 0 || range_length != 0) {
-
-		arange = (Dwarf_Arange)
-		    _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
-		if (arange == NULL) {
-		    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-		    return (DW_DLV_ERROR);
-		}
-
-		arange->ar_address = range_address;
-		arange->ar_length = range_length;
-		arange->ar_info_offset = info_offset;
-		arange->ar_dbg = dbg;
-		arange_count++;
-
-		curr_chain = (Dwarf_Chain)
-		    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
-		if (curr_chain == NULL) {
-		    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-		    return (DW_DLV_ERROR);
-		}
-
-		curr_chain->ch_item = arange;
-		if (head_chain == NULL)
-		    head_chain = prev_chain = curr_chain;
-		else {
-		    prev_chain->ch_next = curr_chain;
-		    prev_chain = curr_chain;
-		}
-	    }
-	} while (range_address != 0 || range_length != 0);
-
-	/* A compiler could emit some padding bytes here.
-	   dwarf2/3 (dwarf3 draft8 sec 7.20) does not clearly make
-	   extra padding bytes illegal. */
-	if(arange_ptr_past_end < arange_ptr) {
-	    _dwarf_error(dbg, error, DW_DLE_ARANGE_LENGTH_BAD);
-	    return (DW_DLV_ERROR);
-	}
-	/* For most compilers, arange_ptr == arange_ptr_past_end
-	   at this point. But not if there were padding bytes */
-	arange_ptr = arange_ptr_past_end;
-
-    } while (arange_ptr <
-	     dbg->de_debug_aranges + dbg->de_debug_aranges_size);
-
-    if (arange_ptr !=
-	dbg->de_debug_aranges + dbg->de_debug_aranges_size) {
-	_dwarf_error(dbg, error, DW_DLE_ARANGE_DECODE_ERROR);
-	return (DW_DLV_ERROR);
+    res = dwarf_get_aranges_list(dbg,&head_chain,&arange_count,error);
+    if(res != DW_DLV_OK) {
+        return res;
     }
 
     arange_block = (Dwarf_Arange *)
-	_dwarf_get_alloc(dbg, DW_DLA_LIST, arange_count);
+        _dwarf_get_alloc(dbg, DW_DLA_LIST, arange_count);
     if (arange_block == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
     }
 
     curr_chain = head_chain;
     for (i = 0; i < arange_count; i++) {
-	*(arange_block + i) = curr_chain->ch_item;
-	prev_chain = curr_chain;
-	curr_chain = curr_chain->ch_next;
-	dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
+        *(arange_block + i) = curr_chain->ch_item;
+        prev_chain = curr_chain;
+        curr_chain = curr_chain->ch_next;
+        dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
     }
 
     *aranges = arange_block;
@@ -268,216 +331,71 @@
     an array is set to the address itself(aranges) and
     the section offset (offsets).
     Must be identical in most aspects to
-	dwarf_get_aranges!
+        dwarf_get_aranges!
 */
 int
 _dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg,
-				Dwarf_Addr ** addrs,
-				Dwarf_Off ** offsets,
-				Dwarf_Signed * count,
-				Dwarf_Error * error)
+    Dwarf_Addr ** addrs,
+    Dwarf_Off ** offsets,
+    Dwarf_Signed * count,
+    Dwarf_Error * error)
 {
-    /* Sweeps the .debug_aranges section. */
-    Dwarf_Small *arange_ptr;
-    Dwarf_Small *arange_start_ptr;
-
-    /* 
-       Start of arange header.  Used for rounding offset of arange_ptr
-       to twice the tuple size.  Libdwarf requirement. */
-    Dwarf_Small *header_ptr;
-
-    /* Length of current set of aranges. */
-    Dwarf_Unsigned length;
-
-    /* Version of .debug_aranges header. */
-    Dwarf_Half version;
-
-    /* Offset of current set of aranges into .debug_info. */
-    Dwarf_Off info_offset;
-
-    /* Size in bytes of addresses in target. */
-    Dwarf_Small address_size;
-
-    /* Size in bytes of segment offsets in target. */
-    Dwarf_Small segment_size;
-
-    Dwarf_Small remainder;
-
-    /* Count of total number of aranges. */
-    Dwarf_Unsigned arange_count = 0;
-
-    /* Start address of arange. */
-    Dwarf_Addr range_address;
-
-    /* Length of arange. */
-    Dwarf_Unsigned range_length;
-
-    Dwarf_Arange arange;
-
-    Dwarf_Unsigned i;
+    Dwarf_Unsigned i = 0;
 
     /* Used to chain Dwarf_Aranges structs. */
-    Dwarf_Chain curr_chain, prev_chain, head_chain = NULL;
+    Dwarf_Chain curr_chain = NULL;
+    Dwarf_Chain prev_chain = NULL;
+    Dwarf_Chain head_chain = NULL;
 
-    Dwarf_Addr *arange_addrs;
-    Dwarf_Off *arange_offsets;
+    Dwarf_Signed arange_count = 0;
+    Dwarf_Addr *arange_addrs = 0;
+    Dwarf_Off *arange_offsets = 0;
 
-    int res;
+    int res = DW_DLV_ERROR;
 
     /* ***** BEGIN CODE ***** */
 
     if (error != NULL)
-	*error = NULL;
+        *error = NULL;
 
     if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
 
-    res =
-        _dwarf_load_section(dbg,
-			    dbg->de_debug_aranges_index,
-			    &dbg->de_debug_aranges,
-			    error);
+    res = _dwarf_load_section(dbg, &dbg->de_debug_aranges,error);
     if (res != DW_DLV_OK) {
         return res;
     }
 
-    arange_ptr = dbg->de_debug_aranges;
-    do {
-	int local_length_size;
-	/*REFERENCED*/ /* not used in this instance of the macro */
-	int local_extension_size;
-
-	header_ptr = arange_ptr;
-
-
-	/* READ_AREA_LENGTH updates arange_ptr for consumed bytes */
-	READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
-			 arange_ptr, local_length_size,
-			 local_extension_size);
-
-
-	READ_UNALIGNED(dbg, version, Dwarf_Half,
-		       arange_ptr, sizeof(Dwarf_Half));
-	arange_ptr += sizeof(Dwarf_Half);
-	length = length - sizeof(Dwarf_Half);
-	if (version != CURRENT_VERSION_STAMP) {
-	    _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
-	    return (DW_DLV_ERROR);
-	}
-
-	READ_UNALIGNED(dbg, info_offset, Dwarf_Off,
-		       arange_ptr, local_length_size);
-	arange_ptr += local_length_size;
-	length = length - local_length_size;
-	if (info_offset >= dbg->de_debug_info_size) {
-	    _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD);
-	    return (DW_DLV_ERROR);
-	}
-
-	address_size = *(Dwarf_Small *) arange_ptr;
-	arange_ptr = arange_ptr + sizeof(Dwarf_Small);
-	length = length - sizeof(Dwarf_Small);
-
-	segment_size = *(Dwarf_Small *) arange_ptr;
-	arange_ptr = arange_ptr + sizeof(Dwarf_Small);
-	length = length - sizeof(Dwarf_Small);
-	if (segment_size != 0) {
-	    _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD);
-	    return (DW_DLV_ERROR);
-	}
-
-	/* Round arange_ptr offset to next multiple of address_size. */
-	remainder = (Dwarf_Unsigned) (arange_ptr - header_ptr) %
-	    (2 * address_size);
-	if (remainder != 0) {
-	    arange_ptr = arange_ptr + (2 * address_size) - remainder;
-	    length = length - ((2 * address_size) - remainder);
-	}
-
-	do {
-	    arange_start_ptr = arange_ptr;
-	    READ_UNALIGNED(dbg, range_address, Dwarf_Addr,
-			   arange_ptr, dbg->de_pointer_size);
-	    arange_ptr += dbg->de_pointer_size;
-	    length = length - dbg->de_pointer_size;
-
-	    READ_UNALIGNED(dbg, range_length, Dwarf_Unsigned,
-			   arange_ptr, local_length_size);
-	    arange_ptr += local_length_size;
-	    length = length - local_length_size;
-
-	    if (range_address != 0 || range_length != 0) {
-
-		arange = (Dwarf_Arange)
-		    _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
-		if (arange == NULL) {
-		    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-		    return (DW_DLV_ERROR);
-		}
-
-		arange->ar_address = range_address;
-		arange->ar_length = range_length;
-		arange->ar_info_offset =
-		    arange_start_ptr - dbg->de_debug_aranges;
-		arange->ar_dbg = dbg;
-		arange_count++;
-
-		curr_chain = (Dwarf_Chain)
-		    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
-		if (curr_chain == NULL) {
-		    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-		    return (DW_DLV_ERROR);
-		}
-
-		curr_chain->ch_item = arange;
-		if (head_chain == NULL)
-		    head_chain = prev_chain = curr_chain;
-		else {
-		    prev_chain->ch_next = curr_chain;
-		    prev_chain = curr_chain;
-		}
-	    }
-	} while (range_address != 0 || range_length != 0);
-
-	if (length != 0) {
-	    _dwarf_error(dbg, error, DW_DLE_ARANGE_LENGTH_BAD);
-	    return (DW_DLV_ERROR);
-	}
-
-    } while (arange_ptr <
-	     dbg->de_debug_aranges + dbg->de_debug_aranges_size);
-
-    if (arange_ptr !=
-	dbg->de_debug_aranges + dbg->de_debug_aranges_size) {
-	_dwarf_error(dbg, error, DW_DLE_ARANGE_DECODE_ERROR);
-	return (DW_DLV_ERROR);
+    res = dwarf_get_aranges_list(dbg,&head_chain,&arange_count,error);
+    if(res != DW_DLV_OK) {
+        return res;
     }
 
     arange_addrs = (Dwarf_Addr *)
-	_dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
+        _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
     if (arange_addrs == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
     }
     arange_offsets = (Dwarf_Off *)
-	_dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
+        _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
     if (arange_offsets == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
     }
 
     curr_chain = head_chain;
     for (i = 0; i < arange_count; i++) {
-	Dwarf_Arange ar = curr_chain->ch_item;
+        Dwarf_Arange ar = curr_chain->ch_item;
 
-	arange_addrs[i] = ar->ar_address;
-	arange_offsets[i] = ar->ar_info_offset;
-	prev_chain = curr_chain;
-	curr_chain = curr_chain->ch_next;
-	dwarf_dealloc(dbg, ar, DW_DLA_ARANGE);
-	dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
+        arange_addrs[i] = ar->ar_address;
+        arange_offsets[i] = ar->ar_info_offset;
+        prev_chain = curr_chain;
+        curr_chain = curr_chain->ch_next;
+        dwarf_dealloc(dbg, ar, DW_DLA_ARANGE);
+        dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
     }
     *count = arange_count;
     *offsets = arange_offsets;
@@ -497,26 +415,25 @@
 */
 int
 dwarf_get_arange(Dwarf_Arange * aranges,
-		 Dwarf_Unsigned arange_count,
-		 Dwarf_Addr address,
-		 Dwarf_Arange * returned_arange, Dwarf_Error * error)
+    Dwarf_Unsigned arange_count,
+    Dwarf_Addr address,
+    Dwarf_Arange * returned_arange, Dwarf_Error * error)
 {
-    Dwarf_Arange curr_arange;
-    Dwarf_Unsigned i;
+    Dwarf_Arange curr_arange = 0;
+    Dwarf_Unsigned i = 0;
 
     if (aranges == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ARANGES_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ARANGES_NULL);
+        return (DW_DLV_ERROR);
     }
-
     for (i = 0; i < arange_count; i++) {
-	curr_arange = *(aranges + i);
-	if (address >= curr_arange->ar_address &&
-	    address <
-	    curr_arange->ar_address + curr_arange->ar_length) {
-	    *returned_arange = curr_arange;
-	    return (DW_DLV_OK);
-	}
+        curr_arange = *(aranges + i);
+        if (address >= curr_arange->ar_address &&
+            address <
+            curr_arange->ar_address + curr_arange->ar_length) {
+            *returned_arange = curr_arange;
+            return (DW_DLV_OK);
+        }
     }
 
     return (DW_DLV_NO_ENTRY);
@@ -532,29 +449,25 @@
 */
 int
 dwarf_get_cu_die_offset(Dwarf_Arange arange,
-			Dwarf_Off * returned_offset,
-			Dwarf_Error * error)
+    Dwarf_Off * returned_offset,
+    Dwarf_Error * error)
 {
-    Dwarf_Debug dbg;
-    Dwarf_Off offset;
+    Dwarf_Debug dbg = 0;
+    Dwarf_Off offset = 0;
 
     if (arange == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
+        return (DW_DLV_ERROR);
     }
-
-
     dbg = arange->ar_dbg;
+    offset = arange->ar_info_offset;
+    if (!dbg->de_debug_info.dss_data) {
+        int res = _dwarf_load_debug_info(dbg, error);
 
-
-    offset = arange->ar_info_offset;
-    if(!dbg->de_debug_info) {
-        int res = _dwarf_load_debug_info(dbg,error);
-        if(res != DW_DLV_OK) {
-	    return res;
+        if (res != DW_DLV_OK) {
+            return res;
         }
     }
-
     *returned_offset = offset + _dwarf_length_of_cu_header(dbg, offset);
     return DW_DLV_OK;
 }
@@ -564,24 +477,37 @@
     and returns the offset of the CU header
     in the compilation-unit that the
     arange belongs to.  Returns DW_DLV_ERROR
-    on error.
+    on error.   
+    Ensures .debug_info loaded so
+    the cu_offset is meaningful.
 */
 int
 dwarf_get_arange_cu_header_offset(Dwarf_Arange arange,
-				  Dwarf_Off * cu_header_offset_returned,
-				  Dwarf_Error * error)
+    Dwarf_Off * cu_header_offset_returned,
+    Dwarf_Error * error)
 {
+    Dwarf_Debug dbg = 0;
     if (arange == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
+        return (DW_DLV_ERROR);
     }
-
+    dbg = arange->ar_dbg;
+    /* Like dwarf_get_arange_info this ensures debug_info loaded:
+       the cu_header is in debug_info and will be used else
+       we would not call dwarf_get_arange_cu_header_offset. */
+    if (!dbg->de_debug_info.dss_data) {
+        int res = _dwarf_load_debug_info(dbg, error);
+        if (res != DW_DLV_OK) {
+                return res;
+        }
+    }
     *cu_header_offset_returned = arange->ar_info_offset;
     return DW_DLV_OK;
 }
 
 
 
+
 /*
     This function takes a Dwarf_Arange, and returns
     true if it is not NULL.  It also stores the start
@@ -589,35 +515,79 @@
     range in *length, and the offset of the first die
     in the compilation-unit in *cu_die_offset.  It
     returns false on error.
+    If cu_die_offset returned ensures .debug_info loaded so
+    the cu_die_offset is meaningful.
 */
 int
 dwarf_get_arange_info(Dwarf_Arange arange,
-		      Dwarf_Addr * start,
-		      Dwarf_Unsigned * length,
-		      Dwarf_Off * cu_die_offset, Dwarf_Error * error)
+    Dwarf_Addr * start,
+    Dwarf_Unsigned * length,
+    Dwarf_Off * cu_die_offset, Dwarf_Error * error)
 {
     if (arange == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
+        return (DW_DLV_ERROR);
     }
 
     if (start != NULL)
-	*start = arange->ar_address;
+        *start = arange->ar_address;
     if (length != NULL)
-	*length = arange->ar_length;
+        *length = arange->ar_length;
     if (cu_die_offset != NULL) {
-	Dwarf_Debug dbg = arange->ar_dbg;
-	Dwarf_Off offset = arange->ar_info_offset;
+        Dwarf_Debug dbg = arange->ar_dbg;
+        Dwarf_Off offset = arange->ar_info_offset;
 
-	if(!dbg->de_debug_info) {
-	   int res = _dwarf_load_debug_info(dbg,error);
-           if(res != DW_DLV_OK) {
-               return res;
-           }
+        if (!dbg->de_debug_info.dss_data) {
+            int res = _dwarf_load_debug_info(dbg, error);
+            if (res != DW_DLV_OK) {
+                return res;
+            }
         }
-
-	*cu_die_offset =
-	    offset + _dwarf_length_of_cu_header(dbg, offset);
+        *cu_die_offset =
+            offset + _dwarf_length_of_cu_header(dbg, offset);
     }
     return (DW_DLV_OK);
 }
+
+
+/* New for DWARF4, entries may have segment information. 
+   *segment is only meaningful if *segment_entry_size is non-zero. */
+int 
+dwarf_get_arange_info_b(Dwarf_Arange arange,
+    Dwarf_Unsigned*  segment,
+    Dwarf_Unsigned*  segment_entry_size,
+    Dwarf_Addr    * start,
+    Dwarf_Unsigned* length,
+    Dwarf_Off     * cu_die_offset, 
+    Dwarf_Error   * error)
+{   
+    if (arange == NULL) {
+        _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
+        return (DW_DLV_ERROR);
+    }
+    
+    if(segment != NULL) {
+       *segment = arange->ar_segment_selector;
+    }
+    if(segment_entry_size != NULL) {
+       *segment_entry_size = arange->ar_segment_selector_size;
+    }
+    if (start != NULL)
+        *start = arange->ar_address;
+    if (length != NULL)
+        *length = arange->ar_length;
+    if (cu_die_offset != NULL) {
+        Dwarf_Debug dbg = arange->ar_dbg;
+        Dwarf_Off offset = arange->ar_info_offset;
+
+        if (!dbg->de_debug_info.dss_data) {
+            int res = _dwarf_load_debug_info(dbg, error);
+            if (res != DW_DLV_OK) {
+                return res;
+            }
+        }
+        *cu_die_offset =
+            offset + _dwarf_length_of_cu_header(dbg, offset);
+    }
+    return (DW_DLV_OK);
+}   
--- a/usr/src/tools/ctf/dwarf/common/dwarf_arange.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_arange.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
   Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +18,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -38,12 +39,17 @@
 /* This structure is used to read an arange into. */
 struct Dwarf_Arange_s {
 
+    /* The segment selector. Only non-zero if Dwarf4, only
+       meaningful if ar_segment_selector_size non-zero   */
+    Dwarf_Unsigned ar_segment_selector;
+
     /* Starting address of the arange, ie low-pc. */
     Dwarf_Addr ar_address;
 
     /* Length of the arange. */
     Dwarf_Unsigned ar_length;
 
+
     /* 
        Offset into .debug_info of the start of the compilation-unit
        containing this set of aranges. */
@@ -51,6 +57,8 @@
 
     /* Corresponding Dwarf_Debug. */
     Dwarf_Debug ar_dbg;
+
+    Dwarf_Half ar_segment_selector_size;
 };
 
 
--- a/usr/src/tools/ctf/dwarf/common/dwarf_base_types.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_base_types.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2008-2010  David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +18,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -42,30 +43,44 @@
 
 /* to identify a cie */
 #define DW_CIE_ID 		~(0x0)
-#define DW_CIE_VERSION		1
-#define ABBREV_HASH_TABLE_SIZE	10
+#define DW_CIE_VERSION		1 /* DWARF2 */
+#define DW_CIE_VERSION3		3 /* DWARF3 */
+#define DW_CIE_VERSION4		4 /* DWARF4 */
+
+#define DW_CU_VERSION2 2
+#define DW_CU_VERSION3 3
+#define DW_CU_VERSION4 4
+
+/* DWARF2,3 and 4 */
+#define DW_ARANGES_VERSION2 2
+
+#define DW_LINE_VERSION2   2
+#define DW_LINE_VERSION3   3
+#define DW_LINE_VERSION4   4
 
 
 /* 
     These are allocation type codes for structs that
     are internal to the Libdwarf Consumer library.
 */
-#define DW_DLA_ABBREV_LIST	DW_DLA_ADDR + 1
-#define DW_DLA_CHAIN		DW_DLA_ADDR + 2
-#define DW_DLA_CU_CONTEXT	DW_DLA_ADDR + 3
-#define DW_DLA_FRAME		DW_DLA_ADDR + 4
-#define DW_DLA_GLOBAL_CONTEXT	DW_DLA_ADDR + 5
-#define DW_DLA_FILE_ENTRY	DW_DLA_ADDR + 6
-#define DW_DLA_LINE_CONTEXT	DW_DLA_ADDR + 7
-#define DW_DLA_LOC_CHAIN	DW_DLA_ADDR + 8
-#define DW_DLA_HASH_TABLE	DW_DLA_ADDR + 9
-#define DW_DLA_FUNC_CONTEXT	DW_DLA_ADDR + 10
-#define DW_DLA_TYPENAME_CONTEXT	DW_DLA_ADDR + 11
-#define DW_DLA_VAR_CONTEXT	DW_DLA_ADDR + 12
-#define DW_DLA_WEAK_CONTEXT	DW_DLA_ADDR + 13
+#define DW_DLA_ABBREV_LIST	DW_DLA_RANGES + 1
+#define DW_DLA_CHAIN		DW_DLA_RANGES + 2
+#define DW_DLA_CU_CONTEXT	DW_DLA_RANGES + 3
+#define DW_DLA_FRAME		DW_DLA_RANGES + 4
+#define DW_DLA_GLOBAL_CONTEXT	DW_DLA_RANGES + 5
+#define DW_DLA_FILE_ENTRY	DW_DLA_RANGES + 6
+#define DW_DLA_LINE_CONTEXT	DW_DLA_RANGES + 7
+#define DW_DLA_LOC_CHAIN	DW_DLA_RANGES + 8
+#define DW_DLA_HASH_TABLE	DW_DLA_RANGES + 9
+#define DW_DLA_FUNC_CONTEXT	DW_DLA_RANGES + 10
+#define DW_DLA_TYPENAME_CONTEXT	DW_DLA_RANGES + 11
+#define DW_DLA_VAR_CONTEXT	DW_DLA_RANGES + 12
+#define DW_DLA_WEAK_CONTEXT	DW_DLA_RANGES + 13
+#define DW_DLA_PUBTYPES_CONTEXT	DW_DLA_RANGES + 14 /* DWARF3 */
+#define DW_DLA_HASH_TABLE_ENTRY	DW_DLA_RANGES + 15 
 
 /* Maximum number of allocation types for allocation routines. */
-#define MAX_DW_DLA		DW_DLA_WEAK_CONTEXT
+#define MAX_DW_DLA		DW_DLA_HASH_TABLE_ENTRY
 
 /*Dwarf_Word  is unsigned word usable for index, count in memory */
 /*Dwarf_Sword is   signed word usable for index, count in memory */
@@ -94,14 +109,15 @@
 	This is not a very portable assumption.
         The following should be used instead for 64 bit integers.
 */
-typedef __uint32_t Dwarf_ufixed64;
-typedef __int32_t Dwarf_sfixed64;
+typedef __uint64_t Dwarf_ufixed64;
+typedef __int64_t Dwarf_sfixed64;
 
 
 typedef struct Dwarf_Abbrev_List_s *Dwarf_Abbrev_List;
 typedef struct Dwarf_File_Entry_s *Dwarf_File_Entry;
 typedef struct Dwarf_CU_Context_s *Dwarf_CU_Context;
 typedef struct Dwarf_Hash_Table_s *Dwarf_Hash_Table;
+typedef struct Dwarf_Hash_Table_Entry_s *Dwarf_Hash_Table_Entry;
 
 
 typedef struct Dwarf_Alloc_Hdr_s *Dwarf_Alloc_Hdr;
--- a/usr/src/tools/ctf/dwarf/common/dwarf_die_deliv.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_die_deliv.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000,2001,2002,2003 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -32,6 +33,12 @@
   http://oss.sgi.com/projects/GenInfo/NoticeExplan
 
 */
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
 
 
 
@@ -61,44 +68,44 @@
 static Dwarf_CU_Context
 _dwarf_find_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset)
 {
-    Dwarf_CU_Context cu_context;
+    Dwarf_CU_Context cu_context = 0;
 
     if (offset >= dbg->de_info_last_offset)
-	return (NULL);
+        return (NULL);
 
     if (dbg->de_cu_context != NULL &&
-	dbg->de_cu_context->cc_next != NULL &&
-	dbg->de_cu_context->cc_next->cc_debug_info_offset == offset) {
+        dbg->de_cu_context->cc_next != NULL &&
+        dbg->de_cu_context->cc_next->cc_debug_info_offset == offset) {
 
-	return (dbg->de_cu_context->cc_next);
+        return (dbg->de_cu_context->cc_next);
     }
 
     if (dbg->de_cu_context != NULL &&
-	dbg->de_cu_context->cc_debug_info_offset <= offset) {
+        dbg->de_cu_context->cc_debug_info_offset <= offset) {
 
-	for (cu_context = dbg->de_cu_context;
-	     cu_context != NULL; cu_context = cu_context->cc_next) {
+        for (cu_context = dbg->de_cu_context;
+             cu_context != NULL; cu_context = cu_context->cc_next) {
 
-	    if (offset >= cu_context->cc_debug_info_offset &&
-		offset < cu_context->cc_debug_info_offset +
-		cu_context->cc_length + cu_context->cc_length_size
-		+ cu_context->cc_extension_size) {
+            if (offset >= cu_context->cc_debug_info_offset &&
+                offset < cu_context->cc_debug_info_offset +
+                cu_context->cc_length + cu_context->cc_length_size
+                + cu_context->cc_extension_size) {
 
-		return (cu_context);
-	    }
-	}
+                return (cu_context);
+            }
+        }
     }
 
     for (cu_context = dbg->de_cu_context_list;
-	 cu_context != NULL; cu_context = cu_context->cc_next) {
+         cu_context != NULL; cu_context = cu_context->cc_next) {
 
-	if (offset >= cu_context->cc_debug_info_offset &&
-	    offset < cu_context->cc_debug_info_offset +
-	    cu_context->cc_length + cu_context->cc_length_size
-	    + cu_context->cc_extension_size) {
+        if (offset >= cu_context->cc_debug_info_offset &&
+            offset < cu_context->cc_debug_info_offset +
+            cu_context->cc_length + cu_context->cc_length_size
+            + cu_context->cc_extension_size) {
 
-	    return (cu_context);
-	}
+            return (cu_context);
+        }
     }
 
     return (NULL);
@@ -112,17 +119,17 @@
 static Dwarf_CU_Context
 _dwarf_find_offdie_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset)
 {
-    Dwarf_CU_Context cu_context;
+    Dwarf_CU_Context cu_context = 0;
 
     for (cu_context = dbg->de_offdie_cu_context;
-	 cu_context != NULL; cu_context = cu_context->cc_next)
+         cu_context != NULL; cu_context = cu_context->cc_next)
 
-	if (offset >= cu_context->cc_debug_info_offset &&
-	    offset < cu_context->cc_debug_info_offset +
-	    cu_context->cc_length + cu_context->cc_length_size
-	    + cu_context->cc_extension_size)
+        if (offset >= cu_context->cc_debug_info_offset &&
+            offset < cu_context->cc_debug_info_offset +
+            cu_context->cc_length + cu_context->cc_length_size
+            + cu_context->cc_extension_size)
 
-	    return (cu_context);
+            return (cu_context);
 
     return (NULL);
 }
@@ -144,28 +151,28 @@
 */
 static Dwarf_CU_Context
 _dwarf_make_CU_Context(Dwarf_Debug dbg,
-		       Dwarf_Off offset, Dwarf_Error * error)
+                       Dwarf_Off offset, Dwarf_Error * error)
 {
-    Dwarf_CU_Context cu_context;
-    Dwarf_Unsigned length;
-    Dwarf_Signed abbrev_offset;
-    Dwarf_Byte_Ptr cu_ptr;
+    Dwarf_CU_Context cu_context = 0;
+    Dwarf_Unsigned length = 0;
+    Dwarf_Signed abbrev_offset = 0;
+    Dwarf_Byte_Ptr cu_ptr = 0;
     int local_extension_size = 0;
-    int local_length_size;
+    int local_length_size = 0;
 
     cu_context =
-	(Dwarf_CU_Context) _dwarf_get_alloc(dbg, DW_DLA_CU_CONTEXT, 1);
+        (Dwarf_CU_Context) _dwarf_get_alloc(dbg, DW_DLA_CU_CONTEXT, 1);
     if (cu_context == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (NULL);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (NULL);
     }
     cu_context->cc_dbg = dbg;
 
-    cu_ptr = (Dwarf_Byte_Ptr) (dbg->de_debug_info + offset);
+    cu_ptr = (Dwarf_Byte_Ptr) (dbg->de_debug_info.dss_data + offset);
 
     /* READ_AREA_LENGTH updates cu_ptr for consumed bytes */
     READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
-		     cu_ptr, local_length_size, local_extension_size);
+                     cu_ptr, local_length_size, local_extension_size);
     cu_context->cc_length_size = local_length_size;
     cu_context->cc_extension_size = local_extension_size;
 
@@ -173,58 +180,58 @@
     cu_context->cc_length = (Dwarf_Word) length;
 
     READ_UNALIGNED(dbg, cu_context->cc_version_stamp, Dwarf_Half,
-		   cu_ptr, sizeof(Dwarf_Half));
+                   cu_ptr, sizeof(Dwarf_Half));
     cu_ptr += sizeof(Dwarf_Half);
 
     READ_UNALIGNED(dbg, abbrev_offset, Dwarf_Signed,
-		   cu_ptr, local_length_size);
+                   cu_ptr, local_length_size);
     cu_ptr += local_length_size;
     cu_context->cc_abbrev_offset = (Dwarf_Sword) abbrev_offset;
 
     cu_context->cc_address_size = *(Dwarf_Small *) cu_ptr;
 
     if ((length < CU_VERSION_STAMP_SIZE + local_length_size +
-	 CU_ADDRESS_SIZE_SIZE) ||
-	(offset + length + local_length_size +
-	 local_extension_size > dbg->de_debug_info_size)) {
+         CU_ADDRESS_SIZE_SIZE) ||
+        (offset + length + local_length_size +
+         local_extension_size > dbg->de_debug_info.dss_size)) {
 
-	_dwarf_error(dbg, error, DW_DLE_CU_LENGTH_ERROR);
-	return (NULL);
+        dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
+        _dwarf_error(dbg, error, DW_DLE_CU_LENGTH_ERROR);
+        return (NULL);
     }
 
-    if (cu_context->cc_address_size != dbg->de_pointer_size) {
-	_dwarf_error(dbg, error, DW_DLE_CU_ADDRESS_SIZE_BAD);
-	return (NULL);
+    if (cu_context->cc_version_stamp != CURRENT_VERSION_STAMP
+        && cu_context->cc_version_stamp != CURRENT_VERSION_STAMP3
+        && cu_context->cc_version_stamp != CURRENT_VERSION_STAMP4) {
+        dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
+        _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
+        return (NULL);
     }
 
-    if (cu_context->cc_version_stamp != CURRENT_VERSION_STAMP) {
-	_dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
-	return (NULL);
-    }
-
-    if (abbrev_offset >= dbg->de_debug_abbrev_size) {
-	_dwarf_error(dbg, error, DW_DLE_ABBREV_OFFSET_ERROR);
-	return (NULL);
+    if (abbrev_offset >= dbg->de_debug_abbrev.dss_size) {
+        dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
+        _dwarf_error(dbg, error, DW_DLE_ABBREV_OFFSET_ERROR);
+        return (NULL);
     }
 
     cu_context->cc_abbrev_hash_table =
-	(Dwarf_Hash_Table) _dwarf_get_alloc(dbg, DW_DLA_HASH_TABLE, 1);
+        (Dwarf_Hash_Table) _dwarf_get_alloc(dbg, DW_DLA_HASH_TABLE, 1);
     if (cu_context->cc_abbrev_hash_table == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (NULL);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (NULL);
     }
 
     cu_context->cc_debug_info_offset = (Dwarf_Word) offset;
     dbg->de_info_last_offset =
-	(Dwarf_Word) (offset + length +
-		      local_extension_size + local_length_size);
+        (Dwarf_Word) (offset + length +
+                      local_extension_size + local_length_size);
 
     if (dbg->de_cu_context_list == NULL) {
-	dbg->de_cu_context_list = cu_context;
-	dbg->de_cu_context_list_end = cu_context;
+        dbg->de_cu_context_list = cu_context;
+        dbg->de_cu_context_list_end = cu_context;
     } else {
-	dbg->de_cu_context_list_end->cc_next = cu_context;
-	dbg->de_cu_context_list_end = cu_context;
+        dbg->de_cu_context_list_end->cc_next = cu_context;
+        dbg->de_cu_context_list_end = cu_context;
     }
 
     return (cu_context);
@@ -233,50 +240,72 @@
 
 /*
     Returns offset of next compilation-unit thru next_cu_offset
-	pointer.
+        pointer.
     It basically sequentially moves from one
     cu to the next.  The current cu is recorded
     internally by libdwarf.
+
+    The _b form is new for DWARF4 adding new returned fields.
 */
 int
 dwarf_next_cu_header(Dwarf_Debug dbg,
-		     Dwarf_Unsigned * cu_header_length,
-		     Dwarf_Half * version_stamp,
-		     Dwarf_Unsigned * abbrev_offset,
-		     Dwarf_Half * address_size,
-		     Dwarf_Unsigned * next_cu_offset,
-		     Dwarf_Error * error)
+                     Dwarf_Unsigned * cu_header_length,
+                     Dwarf_Half * version_stamp,
+                     Dwarf_Unsigned * abbrev_offset,
+                     Dwarf_Half * address_size,
+                     Dwarf_Unsigned * next_cu_offset,
+                     Dwarf_Error * error)
+{
+    return dwarf_next_cu_header_b(dbg,
+       cu_header_length,
+       version_stamp,
+       abbrev_offset,
+       address_size,
+       0,0,
+       next_cu_offset,
+       error);
+}
+int
+dwarf_next_cu_header_b(Dwarf_Debug dbg,
+                     Dwarf_Unsigned * cu_header_length,
+                     Dwarf_Half * version_stamp,
+                     Dwarf_Unsigned * abbrev_offset,
+                     Dwarf_Half * address_size,
+                     Dwarf_Half * offset_size,
+                     Dwarf_Half * extension_size,
+                     Dwarf_Unsigned * next_cu_offset,
+                     Dwarf_Error * error)
 {
     /* Offset for current and new CU. */
-    Dwarf_Unsigned new_offset;
+    Dwarf_Unsigned new_offset = 0;
 
     /* CU Context for current CU. */
-    Dwarf_CU_Context cu_context;
+    Dwarf_CU_Context cu_context = 0;
 
     /* ***** BEGIN CODE ***** */
 
     if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
     /* 
        Get offset into .debug_info of next CU. If dbg has no context,
        this has to be the first one. */
     if (dbg->de_cu_context == NULL) {
-	new_offset = 0;
-	if (!dbg->de_debug_info) {
-	    int res = _dwarf_load_debug_info(dbg, error);
+        new_offset = 0;
+        if (!dbg->de_debug_info.dss_data) {
+            int res = _dwarf_load_debug_info(dbg, error);
 
-	    if (res != DW_DLV_OK) {
-		return res;
-	    }
-	}
+            if (res != DW_DLV_OK) {
+                return res;
+            }
+        }
 
     } else {
-	new_offset = dbg->de_cu_context->cc_debug_info_offset +
-	    dbg->de_cu_context->cc_length +
-	    dbg->de_cu_context->cc_length_size +
-	    dbg->de_cu_context->cc_extension_size;
+        new_offset = dbg->de_cu_context->cc_debug_info_offset +
+            dbg->de_cu_context->cc_length +
+            dbg->de_cu_context->cc_length_size +
+            dbg->de_cu_context->cc_extension_size;
     }
 
     /* 
@@ -285,9 +314,9 @@
        of debug_info section, and reset de_cu_debug_info_offset to
        enable looping back through the cu's. */
     if ((new_offset + _dwarf_length_of_cu_header_simple(dbg)) >=
-	dbg->de_debug_info_size) {
-	dbg->de_cu_context = NULL;
-	return (DW_DLV_NO_ENTRY);
+        dbg->de_debug_info.dss_size) {
+        dbg->de_cu_context = NULL;
+        return (DW_DLV_NO_ENTRY);
     }
 
     /* Check if this CU has been read before. */
@@ -295,32 +324,36 @@
 
     /* If not, make CU Context for it. */
     if (cu_context == NULL) {
-	cu_context = _dwarf_make_CU_Context(dbg, new_offset, error);
-	if (cu_context == NULL) {
-	    /* Error if CU Context could not be made. Since
-	       _dwarf_make_CU_Context has already registered an error
-	       we do not do that here: we let the lower error pass
-	       thru. */
-	    return (DW_DLV_ERROR);
-	}
+        cu_context = _dwarf_make_CU_Context(dbg, new_offset, error);
+        if (cu_context == NULL) {
+            /* Error if CU Context could not be made. Since
+               _dwarf_make_CU_Context has already registered an error
+               we do not do that here: we let the lower error pass
+               thru. */
+            return (DW_DLV_ERROR);
+        }
     }
 
     dbg->de_cu_context = cu_context;
 
     if (cu_header_length != NULL)
-	*cu_header_length = cu_context->cc_length;
+        *cu_header_length = cu_context->cc_length;
 
     if (version_stamp != NULL)
-	*version_stamp = cu_context->cc_version_stamp;
+        *version_stamp = cu_context->cc_version_stamp;
 
     if (abbrev_offset != NULL)
-	*abbrev_offset = cu_context->cc_abbrev_offset;
+        *abbrev_offset = cu_context->cc_abbrev_offset;
 
     if (address_size != NULL)
-	*address_size = cu_context->cc_address_size;
+        *address_size = cu_context->cc_address_size;
+    if (offset_size != NULL)
+        *offset_size = cu_context->cc_length_size;
+    if (extension_size != NULL)
+        *extension_size = cu_context->cc_extension_size;
 
     new_offset = new_offset + cu_context->cc_length +
-	cu_context->cc_length_size + cu_context->cc_extension_size;
+        cu_context->cc_length_size + cu_context->cc_extension_size;
     *next_cu_offset = new_offset;
     return (DW_DLV_OK);
 }
@@ -351,36 +384,40 @@
     However, in case want_AT_child is true and the die 
     has a DW_AT_sibling attribute *has_die_child is set 
     false to indicate that the children are being skipped.
+
+    die_info_end  points to the last byte+1 of the cu.
+    
 */
 static Dwarf_Byte_Ptr
 _dwarf_next_die_info_ptr(Dwarf_Byte_Ptr die_info_ptr,
-			 Dwarf_CU_Context cu_context,
-			 Dwarf_Byte_Ptr die_info_end,
-			 Dwarf_Byte_Ptr cu_info_start,
-			 Dwarf_Bool want_AT_sibling,
-			 Dwarf_Bool * has_die_child)
+                         Dwarf_CU_Context cu_context,
+                         Dwarf_Byte_Ptr die_info_end,
+                         Dwarf_Byte_Ptr cu_info_start,
+                         Dwarf_Bool want_AT_sibling,
+                         Dwarf_Bool * has_die_child)
 {
-    Dwarf_Byte_Ptr info_ptr;
-    Dwarf_Byte_Ptr abbrev_ptr;
-    Dwarf_Word abbrev_code;
+    Dwarf_Byte_Ptr info_ptr = 0;
+    Dwarf_Byte_Ptr abbrev_ptr = 0;
+    Dwarf_Word abbrev_code = 0;
     Dwarf_Abbrev_List abbrev_list;
-    Dwarf_Half attr;
-    Dwarf_Half attr_form;
-    Dwarf_Unsigned offset;
-    Dwarf_Word leb128_length;
-    Dwarf_Unsigned utmp;
-    Dwarf_Debug dbg;
+    Dwarf_Half attr = 0;
+    Dwarf_Half attr_form = 0;
+    Dwarf_Unsigned offset = 0;
+    Dwarf_Word leb128_length = 0;
+    Dwarf_Unsigned utmp = 0;
+    Dwarf_Debug dbg = 0;
 
     info_ptr = die_info_ptr;
-    DECODE_LEB128_UWORD(info_ptr, utmp)
-	abbrev_code = (Dwarf_Word) utmp;
+    DECODE_LEB128_UWORD(info_ptr, utmp);
+    abbrev_code = (Dwarf_Word) utmp;
     if (abbrev_code == 0) {
-	return NULL;
+        return NULL;
     }
 
+
     abbrev_list = _dwarf_get_abbrev_for_code(cu_context, abbrev_code);
     if (abbrev_list == NULL) {
-	return (NULL);
+        return (NULL);
     }
     dbg = cu_context->cc_dbg;
 
@@ -388,65 +425,90 @@
 
     abbrev_ptr = abbrev_list->ab_abbrev_ptr;
     do {
-	Dwarf_Unsigned utmp2;
+        Dwarf_Unsigned utmp2;
 
-	DECODE_LEB128_UWORD(abbrev_ptr, utmp2)
-	    attr = (Dwarf_Half) utmp2;
-	DECODE_LEB128_UWORD(abbrev_ptr, utmp2)
-	    attr_form = (Dwarf_Half) utmp2;
-	if (attr_form == DW_FORM_indirect) {
-	    Dwarf_Unsigned utmp6;
+        DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
+        attr = (Dwarf_Half) utmp2;
+        DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
+        attr_form = (Dwarf_Half) utmp2;
+        if (attr_form == DW_FORM_indirect) {
+            Dwarf_Unsigned utmp6;
 
-	    /* READ_UNALIGNED does update info_ptr */
-	    DECODE_LEB128_UWORD(info_ptr, utmp6)
-		attr_form = (Dwarf_Half) utmp6;
+            /* DECODE_LEB128_UWORD updates info_ptr */
+            DECODE_LEB128_UWORD(info_ptr, utmp6);
+            attr_form = (Dwarf_Half) utmp6;
 
-	}
+        }
 
-	if (want_AT_sibling && attr == DW_AT_sibling) {
-	    switch (attr_form) {
-	    case DW_FORM_ref1:
-		offset = *(Dwarf_Small *) info_ptr;
-		break;
-	    case DW_FORM_ref2:
-		READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
-			       info_ptr, sizeof(Dwarf_Half));
-		break;
-	    case DW_FORM_ref4:
-		READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
-			       info_ptr, sizeof(Dwarf_ufixed));
-		break;
-	    case DW_FORM_ref8:
-		READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
-			       info_ptr, sizeof(Dwarf_Unsigned));
-		break;
-	    case DW_FORM_ref_udata:
-		offset =
-		    _dwarf_decode_u_leb128(info_ptr, &leb128_length);
-		break;
-	    default:
-		return (NULL);
-	    }
+        if (want_AT_sibling && attr == DW_AT_sibling) {
+            switch (attr_form) {
+            case DW_FORM_ref1:
+                offset = *(Dwarf_Small *) info_ptr;
+                break;
+            case DW_FORM_ref2:
+                /* READ_UNALIGNED does not update info_ptr */
+                READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+                               info_ptr, sizeof(Dwarf_Half));
+                break;
+            case DW_FORM_ref4:
+                READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+                               info_ptr, sizeof(Dwarf_ufixed));
+                break;
+            case DW_FORM_ref8:
+                READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+                               info_ptr, sizeof(Dwarf_Unsigned));
+                break;
+            case DW_FORM_ref_udata:
+                offset =
+                    _dwarf_decode_u_leb128(info_ptr, &leb128_length);
+                break;
+            case DW_FORM_ref_addr:
+                /* Very unusual.  The FORM is intended to refer to
+                   a different CU, but a different CU cannot
+                   be a sibling, can it? 
+                   We could ignore this and treat as if no DW_AT_sibling
+                   present.   Or derive the offset from it and if
+                   it is in the same CU use it directly. 
+                   The offset here is *supposed* to be a global offset,
+                   so adding cu_info_start is wrong  to any offset
+                   we find here unless cu_info_start
+                   is zero! Lets pretend there is no DW_AT_sibling
+                   attribute.  */
+                goto no_sibling_attr;
+            default:
+                return (NULL);
+            }
 
-	    /* Reset *has_die_child to indicate children skipped.  */
-	    *has_die_child = false;
+            /* Reset *has_die_child to indicate children skipped.  */
+            *has_die_child = false;
 
-	    if (cu_info_start + offset > die_info_end) {
-		return (NULL);
-	    } else {
-		return (cu_info_start + offset);
-	    }
-	}
+            /* A value beyond die_info_end indicates an error. Exactly
+               at die_info_end means 1-past-cu-end and simply means we
+               are at the end, do not return NULL. Higher level code
+               will detect that we are at the end. */
+            if (cu_info_start + offset > die_info_end) {
+                /* Error case, bad DWARF. */
+                return (NULL);
+            }
+            /* At or before end-of-cu */
+            return (cu_info_start + offset);
+        }
 
-	if (attr_form != 0) {
-	    info_ptr += _dwarf_get_size_of_val(cu_context->cc_dbg,
-					       attr_form, info_ptr,
-					       cu_context->
-					       cc_length_size);
-	    if (info_ptr > die_info_end) {
-		return (NULL);
-	    }
-	}
+        no_sibling_attr:
+        if (attr_form != 0) {
+            info_ptr += _dwarf_get_size_of_val(cu_context->cc_dbg,
+                    attr_form, 
+                    cu_context->cc_address_size,
+                    info_ptr,
+                    cu_context->cc_length_size);
+            /* It is ok for info_ptr == die_info_end, as we will test
+               later before using a too-large info_ptr */
+            if (info_ptr > die_info_end) {
+                /* More than one-past-end indicates a bug somewhere,
+                   likely bad dwarf generation. */
+                return (NULL);
+            }
+        }
     } while (attr != 0 || attr_form != 0);
 
     return (info_ptr);
@@ -477,119 +539,136 @@
 */
 int
 dwarf_siblingof(Dwarf_Debug dbg,
-		Dwarf_Die die,
-		Dwarf_Die * caller_ret_die, Dwarf_Error * error)
+                Dwarf_Die die,
+                Dwarf_Die * caller_ret_die, Dwarf_Error * error)
 {
-    Dwarf_Die ret_die;
-    Dwarf_Byte_Ptr die_info_ptr;
+    Dwarf_Die ret_die = 0;
+    Dwarf_Byte_Ptr die_info_ptr = 0;
     Dwarf_Byte_Ptr cu_info_start = 0;
+
+    /* die_info_end points 1-past end of die (once set) */
     Dwarf_Byte_Ptr die_info_end = 0;
-    Dwarf_Half abbrev_code;
-    Dwarf_Unsigned utmp;
+    Dwarf_Word abbrev_code = 0;
+    Dwarf_Unsigned utmp = 0;
 
 
     if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
 
     if (die == NULL) {
-	/* Find root die of cu */
-	/* die_info_end is untouched here, need not be set in this
-	   branch. */
-	Dwarf_Off off2;
+        /* Find root die of cu */
+        /* die_info_end is untouched here, need not be set in this
+           branch. */
+        Dwarf_Off off2;
 
-	/* If we've not loaded debug_info, de_cu_context will be NULL,
-	   so no need to laod */
+        /* If we've not loaded debug_info, de_cu_context will be NULL,
+           so no need to laod */
+
+        if (dbg->de_cu_context == NULL) {
+            _dwarf_error(dbg, error, DW_DLE_DBG_NO_CU_CONTEXT);
+            return (DW_DLV_ERROR);
+        }
 
-	if (dbg->de_cu_context == NULL) {
-	    _dwarf_error(dbg, error, DW_DLE_DBG_NO_CU_CONTEXT);
-	    return (DW_DLV_ERROR);
-	}
+        off2 = dbg->de_cu_context->cc_debug_info_offset;
+        die_info_ptr = dbg->de_debug_info.dss_data +
+            off2 + _dwarf_length_of_cu_header(dbg, off2);
+    } else {
+        /* Find sibling die. */
+        Dwarf_Bool has_child = false;
+        Dwarf_Sword child_depth = 0;
 
-	off2 = dbg->de_cu_context->cc_debug_info_offset;
-	die_info_ptr = dbg->de_debug_info +
-	    off2 + _dwarf_length_of_cu_header(dbg, off2);
-    } else {
-	/* Find sibling die. */
-	Dwarf_Bool has_child;
-	Dwarf_Sword child_depth;
+        /* We cannot have a legal die unless debug_info was loaded, so
+           no need to load debug_info here. */
+        CHECK_DIE(die, DW_DLV_ERROR);
 
-	/* We cannot have a legal die unless debug_info was loaded, so
-	   no need to load debug_info here. */
-	CHECK_DIE(die, DW_DLV_ERROR)
+        die_info_ptr = die->di_debug_info_ptr;
+        if (*die_info_ptr == 0) {
+            return (DW_DLV_NO_ENTRY);
+        }
+        cu_info_start = dbg->de_debug_info.dss_data +
+            die->di_cu_context->cc_debug_info_offset;
+        die_info_end = cu_info_start + die->di_cu_context->cc_length +
+            die->di_cu_context->cc_length_size +
+            die->di_cu_context->cc_extension_size;
 
-	    die_info_ptr = die->di_debug_info_ptr;
-	if (*die_info_ptr == 0) {
-	    return (DW_DLV_NO_ENTRY);
-	}
-	cu_info_start = dbg->de_debug_info +
-	    die->di_cu_context->cc_debug_info_offset;
-	die_info_end = cu_info_start + die->di_cu_context->cc_length +
-	    die->di_cu_context->cc_length_size +
-	    die->di_cu_context->cc_extension_size;
+        if ((*die_info_ptr) == 0) {
+            return (DW_DLV_NO_ENTRY);
+        }
+        child_depth = 0;
+        do {
+            die_info_ptr = _dwarf_next_die_info_ptr(die_info_ptr,
+                                                    die->di_cu_context,
+                                                    die_info_end,
+                                                    cu_info_start, true,
+                                                    &has_child);
+            if (die_info_ptr == NULL) {
+                _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PTR_NULL);
+                return (DW_DLV_ERROR);
+            }
 
-	if ((*die_info_ptr) == 0) {
-	    return (DW_DLV_NO_ENTRY);
-	}
-	child_depth = 0;
-	do {
-	    die_info_ptr = _dwarf_next_die_info_ptr(die_info_ptr,
-						    die->di_cu_context,
-						    die_info_end,
-						    cu_info_start, true,
-						    &has_child);
-	    if (die_info_ptr == NULL) {
-		_dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PTR_NULL);
-		return (DW_DLV_ERROR);
-	    }
+            /* die_info_end is one past end. Do not read it!  
+               A test for ``!= die_info_end''  would work as well,
+               but perhaps < reads more like the meaning. */
+            if(die_info_ptr < die_info_end) { 
+                if ((*die_info_ptr) == 0 && has_child) {
+                    die_info_ptr++;
+                    has_child = false;
+                }
+            }
 
-	    if ((*die_info_ptr) == 0 && has_child) {
-		die_info_ptr++;
-		has_child = false;
-	    }
+            /* die_info_ptr can be one-past-end. */
+            if ((die_info_ptr == die_info_end) ||
+                ((*die_info_ptr) == 0)) {
+                for (; child_depth > 0 && *die_info_ptr == 0;
+                     child_depth--, die_info_ptr++);
+            } else {
+                child_depth = has_child ? child_depth + 1 : child_depth;
+            }
 
-	    if ((*die_info_ptr) == 0)
-		for (; child_depth > 0 && *die_info_ptr == 0;
-		     child_depth--, die_info_ptr++);
-	    else
-		child_depth = has_child ? child_depth + 1 : child_depth;
-
-	} while (child_depth != 0);
+        } while (child_depth != 0);
     }
 
+    /* die_info_ptr > die_info_end is really a bug (possibly in dwarf
+       generation)(but we are past end, no more DIEs here), whereas
+       die_info_ptr == die_info_end means 'one past end, no more DIEs
+       here'. */
     if (die != NULL && die_info_ptr >= die_info_end) {
-	return (DW_DLV_NO_ENTRY);
+        return (DW_DLV_NO_ENTRY);
     }
 
     if ((*die_info_ptr) == 0) {
-	return (DW_DLV_NO_ENTRY);
+        return (DW_DLV_NO_ENTRY);
     }
 
     ret_die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1);
     if (ret_die == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
     }
 
     ret_die->di_debug_info_ptr = die_info_ptr;
     ret_die->di_cu_context =
-	die == NULL ? dbg->de_cu_context : die->di_cu_context;
+        die == NULL ? dbg->de_cu_context : die->di_cu_context;
 
-    DECODE_LEB128_UWORD(die_info_ptr, utmp)
-	abbrev_code = (Dwarf_Half) utmp;
+    DECODE_LEB128_UWORD(die_info_ptr, utmp);
+    abbrev_code = (Dwarf_Word) utmp;
     if (abbrev_code == 0) {
-	/* Zero means a null DIE */
-	return (DW_DLV_NO_ENTRY);
+        /* Zero means a null DIE */
+        dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
+        return (DW_DLV_NO_ENTRY);
     }
+    ret_die->di_abbrev_code = abbrev_code;
     ret_die->di_abbrev_list =
-	_dwarf_get_abbrev_for_code(ret_die->di_cu_context, abbrev_code);
+        _dwarf_get_abbrev_for_code(ret_die->di_cu_context, abbrev_code);
     if (ret_die->di_abbrev_list == NULL || (die == NULL &&
-					    ret_die->di_abbrev_list->
-					    ab_tag !=
-					    DW_TAG_compile_unit)) {
-	_dwarf_error(dbg, error, DW_DLE_FIRST_DIE_NOT_CU);
-	return (DW_DLV_ERROR);
+                                            ret_die->di_abbrev_list->
+                                            ab_tag !=
+                                            DW_TAG_compile_unit)) {
+        dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
+        _dwarf_error(dbg, error, DW_DLE_FIRST_DIE_NOT_CU);
+        return (DW_DLV_ERROR);
     }
 
     *caller_ret_die = ret_die;
@@ -599,64 +678,69 @@
 
 int
 dwarf_child(Dwarf_Die die,
-	    Dwarf_Die * caller_ret_die, Dwarf_Error * error)
+            Dwarf_Die * caller_ret_die, Dwarf_Error * error)
 {
-    Dwarf_Byte_Ptr die_info_ptr;
-    Dwarf_Byte_Ptr die_info_end;
-    Dwarf_Die ret_die;
-    Dwarf_Bool has_die_child;
+    Dwarf_Byte_Ptr die_info_ptr = 0;
+
+    /* die_info_end points one-past-end of die area. */
+    Dwarf_Byte_Ptr die_info_end = 0;
+    Dwarf_Die ret_die = 0;
+    Dwarf_Bool has_die_child = 0;
     Dwarf_Debug dbg;
-    Dwarf_Half abbrev_code;
-    Dwarf_Unsigned utmp;
+    Dwarf_Word abbrev_code = 0;
+    Dwarf_Unsigned utmp = 0;
 
 
-    CHECK_DIE(die, DW_DLV_ERROR)
-	dbg = die->di_cu_context->cc_dbg;
+    CHECK_DIE(die, DW_DLV_ERROR);
+    dbg = die->di_cu_context->cc_dbg;
     die_info_ptr = die->di_debug_info_ptr;
 
     /* NULL die has no child. */
     if ((*die_info_ptr) == 0)
-	return (DW_DLV_NO_ENTRY);
+        return (DW_DLV_NO_ENTRY);
 
-    die_info_end = dbg->de_debug_info +
-	die->di_cu_context->cc_debug_info_offset +
-	die->di_cu_context->cc_length +
-	die->di_cu_context->cc_length_size +
-	die->di_cu_context->cc_extension_size;
+    die_info_end = dbg->de_debug_info.dss_data +
+        die->di_cu_context->cc_debug_info_offset +
+        die->di_cu_context->cc_length +
+        die->di_cu_context->cc_length_size +
+        die->di_cu_context->cc_extension_size;
 
     die_info_ptr =
-	_dwarf_next_die_info_ptr(die_info_ptr, die->di_cu_context,
-				 die_info_end, NULL, false,
-				 &has_die_child);
+        _dwarf_next_die_info_ptr(die_info_ptr, die->di_cu_context,
+                                 die_info_end, NULL, false,
+                                 &has_die_child);
     if (die_info_ptr == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PTR_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PTR_NULL);
+        return (DW_DLV_ERROR);
     }
 
     if (!has_die_child)
-	return (DW_DLV_NO_ENTRY);
+        return (DW_DLV_NO_ENTRY);
 
     ret_die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1);
     if (ret_die == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
     }
     ret_die->di_debug_info_ptr = die_info_ptr;
     ret_die->di_cu_context = die->di_cu_context;
 
-    DECODE_LEB128_UWORD(die_info_ptr, utmp)
-	abbrev_code = (Dwarf_Half) utmp;
+    DECODE_LEB128_UWORD(die_info_ptr, utmp);
+    abbrev_code = (Dwarf_Word) utmp;
     if (abbrev_code == 0) {
-	/* We have arrived at a null DIE, at the end of a CU or the end 
-	   of a list of siblings. */
-	*caller_ret_die = 0;
-	return DW_DLV_NO_ENTRY;
+        /* We have arrived at a null DIE, at the end of a CU or the end 
+           of a list of siblings. */
+        *caller_ret_die = 0;
+        dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
+        return DW_DLV_NO_ENTRY;
     }
+    ret_die->di_abbrev_code = abbrev_code;
     ret_die->di_abbrev_list =
-	_dwarf_get_abbrev_for_code(die->di_cu_context, abbrev_code);
+        _dwarf_get_abbrev_for_code(die->di_cu_context, abbrev_code);
     if (ret_die->di_abbrev_list == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_DIE_BAD);
-	return (DW_DLV_ERROR);
+        dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
+        _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
+        return (DW_DLV_ERROR);
     }
 
     *caller_ret_die = ret_die;
@@ -664,100 +748,106 @@
 }
 
 /*
-	Given a die offset, this returns
-	a pointer to a DIE thru *new_die.
-	It is up to the caller to do a
-	dwarf_dealloc(dbg,*new_die,DW_DLE_DIE);
+        Given a (global, not cu_relative) die offset, this returns
+        a pointer to a DIE thru *new_die.
+        It is up to the caller to do a
+        dwarf_dealloc(dbg,*new_die,DW_DLE_DIE);
 */
 int
 dwarf_offdie(Dwarf_Debug dbg,
-	     Dwarf_Off offset, Dwarf_Die * new_die, Dwarf_Error * error)
+             Dwarf_Off offset, Dwarf_Die * new_die, Dwarf_Error * error)
 {
-    Dwarf_CU_Context cu_context;
+    Dwarf_CU_Context cu_context = 0;
     Dwarf_Off new_cu_offset = 0;
-    Dwarf_Die die;
-    Dwarf_Byte_Ptr info_ptr;
-    Dwarf_Half abbrev_code;
-    Dwarf_Unsigned utmp;
+    Dwarf_Die die = 0;
+    Dwarf_Byte_Ptr info_ptr = 0;
+    Dwarf_Unsigned abbrev_code = 0;
+    Dwarf_Unsigned utmp = 0;
 
     if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
 
     cu_context = _dwarf_find_CU_Context(dbg, offset);
     if (cu_context == NULL)
-	cu_context = _dwarf_find_offdie_CU_Context(dbg, offset);
+        cu_context = _dwarf_find_offdie_CU_Context(dbg, offset);
 
     if (cu_context == NULL) {
-	int res = _dwarf_load_debug_info(dbg, error);
+        int res = _dwarf_load_debug_info(dbg, error);
 
-	if (res != DW_DLV_OK) {
-	    return res;
-	}
+        if (res != DW_DLV_OK) {
+            return res;
+        }
 
-	if (dbg->de_cu_context_list_end != NULL)
-	    new_cu_offset =
-		dbg->de_cu_context_list_end->cc_debug_info_offset +
-		dbg->de_cu_context_list_end->cc_length +
-		dbg->de_cu_context_list_end->cc_length_size +
-		dbg->de_cu_context_list_end->cc_extension_size;
+        if (dbg->de_offdie_cu_context_end != NULL) {
+            Dwarf_CU_Context lcu_context =
+                dbg->de_offdie_cu_context_end;
+            new_cu_offset =
+                lcu_context->cc_debug_info_offset +
+                lcu_context->cc_length +
+                lcu_context->cc_length_size +
+                lcu_context->cc_extension_size;
+        }
 
-	do {
-	    if ((new_cu_offset +
-		 _dwarf_length_of_cu_header_simple(dbg)) >=
-		dbg->de_debug_info_size) {
-		_dwarf_error(dbg, error, DW_DLE_OFFSET_BAD);
-		return (DW_DLV_ERROR);
-	    }
 
-	    cu_context =
-		_dwarf_make_CU_Context(dbg, new_cu_offset, error);
-	    if (cu_context == NULL) {
-		/* Error if CU Context could not be made. Since
-		   _dwarf_make_CU_Context has already registered an
-		   error we do not do that here: we let the lower error
-		   pass thru. */
+        do {
+            if ((new_cu_offset +
+                 _dwarf_length_of_cu_header_simple(dbg)) >=
+                dbg->de_debug_info.dss_size) {
+                _dwarf_error(dbg, error, DW_DLE_OFFSET_BAD);
+                return (DW_DLV_ERROR);
+            }
 
-		return (DW_DLV_ERROR);
-	    }
+            cu_context =
+                _dwarf_make_CU_Context(dbg, new_cu_offset, error);
+            if (cu_context == NULL) {
+                /* Error if CU Context could not be made. Since
+                   _dwarf_make_CU_Context has already registered an
+                   error we do not do that here: we let the lower error
+                   pass thru. */
 
-	    if (dbg->de_offdie_cu_context == NULL) {
-		dbg->de_offdie_cu_context = cu_context;
-		dbg->de_offdie_cu_context_end = cu_context;
-	    } else {
-		dbg->de_offdie_cu_context_end->cc_next = cu_context;
-		dbg->de_offdie_cu_context_end = cu_context;
-	    }
+                return (DW_DLV_ERROR);
+            }
 
-	    new_cu_offset = new_cu_offset + cu_context->cc_length +
-		cu_context->cc_length_size;
+            if (dbg->de_offdie_cu_context == NULL) {
+                dbg->de_offdie_cu_context = cu_context;
+                dbg->de_offdie_cu_context_end = cu_context;
+            } else {
+                dbg->de_offdie_cu_context_end->cc_next = cu_context;
+                dbg->de_offdie_cu_context_end = cu_context;
+            }
 
-	} while (offset >= new_cu_offset);
+            new_cu_offset = new_cu_offset + cu_context->cc_length +
+                cu_context->cc_length_size;
+
+        } while (offset >= new_cu_offset);
     }
 
     die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1);
     if (die == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
     }
     die->di_cu_context = cu_context;
 
-    info_ptr = dbg->de_debug_info + offset;
+    info_ptr = dbg->de_debug_info.dss_data + offset;
     die->di_debug_info_ptr = info_ptr;
-    DECODE_LEB128_UWORD(info_ptr, utmp)
-	abbrev_code = (Dwarf_Half) utmp;
+    DECODE_LEB128_UWORD(info_ptr, utmp);
+    abbrev_code = utmp;
     if (abbrev_code == 0) {
-	/* we are at a null DIE (or there is a bug). */
-	*new_die = 0;
-	return DW_DLV_NO_ENTRY;
+        /* we are at a null DIE (or there is a bug). */
+        *new_die = 0;
+        dwarf_dealloc(dbg, die, DW_DLA_DIE);
+        return DW_DLV_NO_ENTRY;
     }
-
+    die->di_abbrev_code = abbrev_code;
     die->di_abbrev_list =
-	_dwarf_get_abbrev_for_code(cu_context, abbrev_code);
+        _dwarf_get_abbrev_for_code(cu_context, abbrev_code);
     if (die->di_abbrev_list == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_LIST_NULL);
-	return (DW_DLV_ERROR);
+        dwarf_dealloc(dbg, die, DW_DLA_DIE);
+        _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_LIST_NULL);
+        return (DW_DLV_ERROR);
     }
 
     *new_die = die;
--- a/usr/src/tools/ctf/dwarf/common/dwarf_die_deliv.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_die_deliv.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
   Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2008-2010  David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +18,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -43,7 +44,7 @@
 */
 struct Dwarf_Abbrev_List_s {
 
-    Dwarf_Word ab_code;
+    Dwarf_Unsigned ab_code;
     Dwarf_Half ab_tag;
     Dwarf_Half ab_has_child;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_elf_access.c	Sun May 22 03:13:22 2011 +0100
@@ -0,0 +1,976 @@
+/*
+  Copyright (C) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
+  Portions Copyright 2008-2010 Arxan Technologies, Inc. All Rights Reserved.
+  Portions Copyright 2009-2010 David Anderson. All rights reserved.
+  Portions Copyright 2009-2010 Novell Inc. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include "dwarf_elf_access.h"
+
+#ifdef HAVE_ELF_H
+#include <elf.h>
+#endif
+#ifdef HAVE_LIBELF_H
+#include <libelf.h>
+#else
+#ifdef HAVE_LIBELF_LIBELF_H
+#include <libelf/libelf.h>
+#endif
+#endif
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define FALSE 0
+#define TRUE  1
+
+#ifndef EM_MIPS
+/* This is the standard elf value EM_MIPS. */
+#define EM_MIPS 8
+#endif
+
+
+#ifdef HAVE_ELF64_GETEHDR
+extern Elf64_Ehdr *elf64_getehdr(Elf *);
+#endif
+#ifdef HAVE_ELF64_GETSHDR
+extern Elf64_Shdr *elf64_getshdr(Elf_Scn *);
+#endif
+#ifdef WORDS_BIGENDIAN
+#define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \
+    { \
+      dbg->de_copy_word(dest, \
+                        ((char *)source) +srclength-len_out,  \
+                        len_out) ; \
+    }
+
+
+#else /* LITTLE ENDIAN */
+
+#define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \
+    { \
+      dbg->de_copy_word( (dest) , \
+                        ((char *)source) ,  \
+                        len_out) ; \
+    }
+#endif
+
+
+
+typedef struct {
+    dwarf_elf_handle elf;
+    int              is_64bit;
+    Dwarf_Small      length_size;
+    Dwarf_Small      pointer_size;
+    Dwarf_Unsigned   section_count;
+    Dwarf_Endianness endianness;
+    Dwarf_Small      machine;
+    int              libdwarf_owns_elf;
+    Elf32_Ehdr *ehdr32;
+
+#ifdef HAVE_ELF64_GETEHDR
+    Elf64_Ehdr *ehdr64;
+#endif
+    /* Elf symtab and its strtab.  Initialized at first
+       call to do relocations, the actual data is in the Dwarf_Debug
+       struct, not allocated locally here. */
+    struct Dwarf_Section_s *symtab; 
+    struct Dwarf_Section_s *strtab; 
+
+} dwarf_elf_object_access_internals_t;
+
+struct Dwarf_Elf_Rela {
+    Dwarf_ufixed64 r_offset;
+    /*Dwarf_ufixed64 r_info; */
+    Dwarf_ufixed64 r_type;
+    Dwarf_ufixed64 r_symidx;
+    Dwarf_ufixed64 r_addend; 
+};
+
+
+static int dwarf_elf_object_access_load_section(void* obj_in, 
+    Dwarf_Half section_index, 
+    Dwarf_Small** section_data, 
+    int* error);
+
+/*
+    dwarf_elf_object_access_internals_init()
+ */
+static int 
+dwarf_elf_object_access_internals_init(void* obj_in, 
+                              dwarf_elf_handle elf, 
+                              int* error)
+{
+    dwarf_elf_object_access_internals_t*obj = 
+        (dwarf_elf_object_access_internals_t*)obj_in;
+    char *ehdr_ident = 0;
+    Dwarf_Half machine = 0;
+    obj->elf = elf;
+
+    if ((ehdr_ident = elf_getident(elf, NULL)) == NULL) {
+        *error = DW_DLE_ELF_GETIDENT_ERROR;
+        return DW_DLV_ERROR;
+    }
+
+    obj->is_64bit = (ehdr_ident[EI_CLASS] == ELFCLASS64);
+
+
+    if(ehdr_ident[EI_DATA] == ELFDATA2LSB){
+        obj->endianness = DW_OBJECT_LSB;
+    }
+    else if(ehdr_ident[EI_DATA] == ELFDATA2MSB){
+        obj->endianness = DW_OBJECT_MSB;
+    }
+
+    if (obj->is_64bit) {
+#ifdef HAVE_ELF64_GETEHDR
+        obj->ehdr64 = elf64_getehdr(elf);
+        if (obj->ehdr64 == NULL) {
+            *error = DW_DLE_ELF_GETEHDR_ERROR;
+            return DW_DLV_ERROR;
+        }
+        obj->section_count = obj->ehdr64->e_shnum;
+        machine = obj->ehdr64->e_machine;
+        obj->machine = machine;
+#else
+        *error = DW_DLE_NO_ELF64_SUPPORT;
+        return DW_DLV_ERROR;
+#endif
+    } 
+    else {
+        obj->ehdr32 = elf32_getehdr(elf);
+        if (obj->ehdr32 == NULL) {
+           *error = DW_DLE_ELF_GETEHDR_ERROR;
+           return DW_DLV_ERROR;
+        }
+        obj->section_count = obj->ehdr32->e_shnum;
+        machine = obj->ehdr32->e_machine;
+        obj->machine = machine;
+    }
+
+    /* The following length_size is Not Too Significant. Only used
+       one calculation, and an approximate one at that. */
+    obj->length_size = obj->is_64bit ? 8 : 4;
+    obj->pointer_size = obj->is_64bit ? 8 : 4;    
+
+    if (obj->is_64bit && machine != EM_MIPS) {
+        /* MIPS/IRIX makes pointer size and length size 8 for -64.
+           Other platforms make length 4 always. */
+        /* 4 here supports 32bit-offset dwarf2, as emitted by cygnus
+           tools, and the dwarfv2.1 64bit extension setting. 
+           This is not the same as the size-of-an-offset, which
+           is 4 in 32bit dwarf and 8 in 64bit dwarf.  */
+        obj->length_size = 4;
+    }
+    return DW_DLV_OK;
+}
+
+/*
+    dwarf_elf_object_access_get_byte_order
+ */
+static
+Dwarf_Endianness 
+dwarf_elf_object_access_get_byte_order(void* obj_in)
+{
+    dwarf_elf_object_access_internals_t*obj = 
+        (dwarf_elf_object_access_internals_t*)obj_in;
+    return obj->endianness;
+}
+
+/*
+    dwarf_elf_object_access_get_section_count()
+ */
+static
+Dwarf_Unsigned 
+dwarf_elf_object_access_get_section_count(void * obj_in)
+{
+    dwarf_elf_object_access_internals_t*obj = 
+        (dwarf_elf_object_access_internals_t*)obj_in;
+    return obj->section_count;
+}
+
+
+/*
+    dwarf_elf_object_access_get_section()
+ */
+static 
+int 
+dwarf_elf_object_access_get_section_info(
+    void* obj_in, 
+    Dwarf_Half section_index, 
+    Dwarf_Obj_Access_Section* ret_scn, 
+    int* error)
+{
+    dwarf_elf_object_access_internals_t*obj = 
+        (dwarf_elf_object_access_internals_t*)obj_in;
+
+    Elf32_Shdr *shdr32 = 0;
+
+#ifdef HAVE_ELF64_GETSHDR
+    Elf64_Shdr *shdr64 = 0;
+#endif
+    Elf_Scn *scn = 0;
+
+
+    scn = elf_getscn(obj->elf, section_index);
+    if (scn == NULL) {
+        *error = DW_DLE_MDE;
+        return DW_DLV_ERROR;
+    }
+    if (obj->is_64bit) {
+#ifdef HAVE_ELF64_GETSHDR
+        shdr64 = elf64_getshdr(scn);
+        if (shdr64 == NULL) {
+            *error = DW_DLE_ELF_GETSHDR_ERROR;
+            return DW_DLV_ERROR;
+        }
+
+        ret_scn->size = shdr64->sh_size;
+        ret_scn->addr = shdr64->sh_addr;
+        ret_scn->link = shdr64->sh_link;
+
+        ret_scn->name = elf_strptr(obj->elf, obj->ehdr64->e_shstrndx,
+                                        shdr64->sh_name);
+        if(ret_scn->name == NULL) {
+            *error = DW_DLE_ELF_STRPTR_ERROR;
+            return DW_DLV_ERROR;
+        }
+        return DW_DLV_OK;
+#else
+        *error = DW_DLE_MISSING_ELF64_SUPPORT;
+        return DW_DLV_ERROR;
+#endif /* HAVE_ELF64_GETSHDR */
+    } 
+    if ((shdr32 = elf32_getshdr(scn)) == NULL) {
+        *error = DW_DLE_ELF_GETSHDR_ERROR;
+        return DW_DLV_ERROR;
+    }
+
+    ret_scn->size = shdr32->sh_size;
+    ret_scn->addr = shdr32->sh_addr;
+    ret_scn->link = shdr32->sh_link;
+
+    ret_scn->name = elf_strptr(obj->elf, obj->ehdr32->e_shstrndx,
+        shdr32->sh_name);
+    if (ret_scn->name == NULL) {
+        *error = DW_DLE_ELF_STRPTR_ERROR;
+        return DW_DLV_ERROR;
+    }
+    return DW_DLV_OK;
+}
+
+/*
+    dwarf_elf_object_access_get_length_size
+ */
+static
+Dwarf_Small 
+dwarf_elf_object_access_get_length_size(void* obj_in)
+{
+    dwarf_elf_object_access_internals_t*obj = 
+        (dwarf_elf_object_access_internals_t*)obj_in;
+    return obj->length_size;
+}
+
+/*
+    dwarf_elf_object_access_get_pointer_size
+ */
+static
+Dwarf_Small 
+dwarf_elf_object_access_get_pointer_size(void* obj_in)
+{
+    dwarf_elf_object_access_internals_t*obj = 
+        (dwarf_elf_object_access_internals_t*)obj_in;
+    return obj->pointer_size;
+}
+
+#define MATCH_REL_SEC(i_,s_,r_)  \
+if(i_ == s_.dss_index) { \
+    *r_ = &s_;            \
+    return DW_DLV_OK;    \
+}
+
+static int
+find_section_to_relocate(Dwarf_Debug dbg,Dwarf_Half section_index,
+   struct Dwarf_Section_s **relocatablesec, int *error)
+{
+    MATCH_REL_SEC(section_index,dbg->de_debug_info,relocatablesec);
+    MATCH_REL_SEC(section_index,dbg->de_debug_abbrev,relocatablesec);
+    MATCH_REL_SEC(section_index,dbg->de_debug_line,relocatablesec);
+    MATCH_REL_SEC(section_index,dbg->de_debug_loc,relocatablesec);
+    MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec);
+    MATCH_REL_SEC(section_index,dbg->de_debug_macinfo,relocatablesec);
+    MATCH_REL_SEC(section_index,dbg->de_debug_pubnames,relocatablesec);
+    MATCH_REL_SEC(section_index,dbg->de_debug_ranges,relocatablesec);
+    MATCH_REL_SEC(section_index,dbg->de_debug_frame,relocatablesec);
+    MATCH_REL_SEC(section_index,dbg->de_debug_frame_eh_gnu,relocatablesec);
+    MATCH_REL_SEC(section_index,dbg->de_debug_pubtypes,relocatablesec);
+    MATCH_REL_SEC(section_index,dbg->de_debug_funcnames,relocatablesec);
+    MATCH_REL_SEC(section_index,dbg->de_debug_typenames,relocatablesec);
+    MATCH_REL_SEC(section_index,dbg->de_debug_varnames,relocatablesec);
+    MATCH_REL_SEC(section_index,dbg->de_debug_weaknames,relocatablesec);
+    /* dbg-> de_debug_str,syms); */
+    /* de_elf_symtab,syms); */
+    /* de_elf_strtab,syms); */
+    *error = DW_DLE_RELOC_SECTION_MISMATCH;
+    return DW_DLV_ERROR;
+   
+}
+#undef MATCH_REL_SEC
+
+static void
+get_rela_elf32(Dwarf_Small *data, unsigned int i,
+  int endianness,
+  int machine, struct Dwarf_Elf_Rela *relap)
+{
+    Elf32_Rela *relp = (Elf32_Rela*)(data + (i * sizeof(Elf32_Rela)));
+    relap->r_offset = relp->r_offset;
+    /*
+    relap->r_info = relp->r_info;
+   */
+    relap->r_type = ELF32_R_TYPE(relp->r_info);
+    relap->r_symidx = ELF32_R_SYM(relp->r_info);
+    relap->r_addend = relp->r_addend;
+}
+
+static void
+get_rela_elf64(Dwarf_Small *data, unsigned int i, 
+  int endianness,
+  int machine,struct Dwarf_Elf_Rela *relap)
+{
+#ifdef HAVE_ELF64_RELA
+    Elf64_Rela * relp = (Elf64_Rela*)(data + (i * sizeof(Elf64_Rela)));
+    relap->r_offset = relp->r_offset;
+    /*
+    relap->r_info = relp->r_info;
+    */
+    if(machine == EM_MIPS && endianness == DW_OBJECT_LSB ) {
+        /* This is really wierd. Treat this very specially. 
+           The Elf64 LE MIPS object used for
+           testing (that has rela) wants the
+           values as  sym  ssym type3 type2 type, treating
+           each value as independent value. But libelf xlate
+           treats it as something else so we fudge here.  
+           It is unclear
+           how to precisely characterize where these relocations
+           were used.
+           SGI MIPS on IRIX never used .rela relocations.
+           The BE 64bit elf MIPS test object with rela uses traditional
+           elf relocation layouts, not this special case.  */
+#define ELF64MIPS_REL_SYM(i) ((i) & 0xffffffff)
+#define ELF64MIPS_REL_TYPE(i) ((i >> 56) &0xff)
+        /* We ignore the special TYPE2 and TYPE3, they should be
+           value R_MIPS_NONE in rela. */
+        relap->r_type = ELF64MIPS_REL_TYPE(relp->r_info);
+        relap->r_symidx = ELF64MIPS_REL_SYM(relp->r_info);
+#undef MIPS64SYM
+#undef MIPS64TYPE
+    } else 
+    {
+        relap->r_type = ELF64_R_TYPE(relp->r_info);
+        relap->r_symidx = ELF64_R_SYM(relp->r_info);
+    }
+    relap->r_addend = relp->r_addend;
+#endif
+}
+
+static void
+get_relocations_array(Dwarf_Bool is_64bit, 
+    int endianness,
+    int machine,
+    Dwarf_Small *data, 
+    unsigned int num_relocations, 
+    struct Dwarf_Elf_Rela *relap)
+{
+    unsigned int i = 0;
+    void (*get_relocations)(Dwarf_Small *data, unsigned int i, 
+         int endianness,
+         int machine,
+         struct Dwarf_Elf_Rela *relap);
+
+    /* Handle 32/64 bit issue
+     */
+    if (is_64bit) {
+        get_relocations = get_rela_elf64;
+    } else {
+        get_relocations = get_rela_elf32;
+    }
+
+    for (i=0; i < num_relocations; i++) {
+       get_relocations(data, i,endianness,machine, &(relap[i]));
+    }
+
+}
+
+static int
+get_relocation_entries(Dwarf_Bool is_64bit,
+    int endianness,
+    int machine,
+    Dwarf_Small *relocation_section,
+    Dwarf_Unsigned relocation_section_size,
+    struct Dwarf_Elf_Rela **relas,
+    unsigned int *nrelas,
+    int *error)
+{
+    unsigned int relocation_size = 0;
+
+    if (is_64bit) {
+#ifdef HAVE_ELF64_RELA
+        relocation_size = sizeof(Elf64_Rela);
+#else
+        *error = DW_DLE_MISSING_ELF64_SUPPORT;
+        return DW_DLV_ERROR;
+#endif
+    } else {
+        relocation_size = sizeof(Elf32_Rela);
+    }
+
+    if (relocation_section == NULL) {
+        *error = DW_DLE_RELOC_SECTION_PTR_NULL;
+        return(DW_DLV_ERROR);
+    }
+
+    if ((relocation_section_size != 0)) {
+        size_t bytescount = 0;
+        if(relocation_section_size%relocation_size) {
+            *error = DW_DLE_RELOC_SECTION_LENGTH_ODD;
+            return DW_DLV_ERROR;
+        }
+        *nrelas = relocation_section_size/relocation_size;
+        bytescount = (*nrelas) * sizeof(struct Dwarf_Elf_Rela);
+        *relas = malloc(bytescount);
+        if (!*relas) {
+            *error = DW_DLE_MAF;
+            return(DW_DLV_ERROR);
+        }
+        memset(*relas,0,bytescount);
+        get_relocations_array(is_64bit,endianness,machine, relocation_section, 
+            *nrelas, *relas);
+    }
+    return(DW_DLV_OK);
+}
+
+static Dwarf_Bool
+is_32bit_abs_reloc(unsigned int type, Dwarf_Half machine) 
+{
+    Dwarf_Bool r = 0;
+    switch (machine) {
+#if defined(EM_MIPS) && defined (R_MIPS_32)
+    case EM_MIPS:
+         r = (type == R_MIPS_32);
+         break;
+#endif
+#if defined(EM_SPARC32PLUS)  && defined (R_SPARC_UA32)
+    case EM_SPARC32PLUS:
+         r =  (type == R_SPARC_UA32);
+         break;
+#endif
+#if defined(EM_SPARCV9)  && defined (R_SPARC_UA32)
+    case EM_SPARCV9:
+         r =  (type == R_SPARC_UA32);
+         break;
+#endif
+#if defined(EM_SPARC) && defined (R_SPARC_UA32)
+    case EM_SPARC:
+         r =  (type == R_SPARC_UA32);
+         break;
+#endif
+#if defined(EM_386) && defined (R_386_32)
+    case EM_386:
+        r =  (type == R_386_32);
+        break;
+#endif
+#if defined(EM_IA_64) && defined (R_IA64_SECREL32LSB)
+    case EM_IA_64:
+        r =  (type == R_IA64_SECREL32LSB);
+        break;
+#endif
+#if defined(EM_PPC64) && defined (R_PPC64_ADDR32)
+    case EM_PPC64:
+        r =  (type == R_PPC64_ADDR32);
+        break;
+#endif
+#if defined(EM_PPC) && defined (R_PPC_ADDR32)
+    case EM_PPC:
+        r =  (type == R_PPC_ADDR32);
+        break;
+#endif
+#if defined(EM_S390) && defined (R_390_32)
+    case EM_S390:
+        r =  (type == R_390_32);
+        break;
+#endif
+#if defined(EM_X86_64) && defined (R_X86_64_32)
+    case EM_X86_64:
+        r = (type == R_X86_64_32);
+        break;
+#endif
+    }
+    return r;
+}
+
+static Dwarf_Bool
+is_64bit_abs_reloc(unsigned int type, Dwarf_Half machine) 
+{
+    Dwarf_Bool r = 0;
+    switch (machine) {
+#if defined(EM_MIPS) && defined (R_MIPS_64)
+    case EM_MIPS:
+        r =  (type == R_MIPS_64);
+        break;
+#endif
+#if defined(EM_SPARC32PLUS) && defined (R_SPARC_UA64)
+    case EM_SPARC32PLUS:
+        r =  (type == R_SPARC_UA64);
+        break;
+#endif
+#if defined(EM_SPARCV9) && defined (R_SPARC_UA64)
+    case EM_SPARCV9:
+        r = (type == R_SPARC_UA64);
+        break;
+#endif
+#if defined(EM_SPARC) && defined (R_SPARC_UA64)
+    case EM_SPARC:
+        r = (type == R_SPARC_UA64);
+        break;
+#endif
+#if defined(EM_IA_64) && defined (R_IA64_SECREL32LSB)
+    case EM_IA_64:
+        r =  (type == R_IA64_DIR64LSB);
+        break;
+#endif
+#if defined(EM_PPC64) && defined (R_PPC64_ADDR64)
+    case EM_PPC64:
+        r =  (type == R_PPC64_ADDR64);
+        break;
+#endif
+#if defined(EM_S390) && defined (R_390_64)
+    case EM_S390:
+        r =  (type == R_390_64);
+        break;
+#endif
+#if defined(EM_X86_64) && defined (R_X86_64_64)
+    case EM_X86_64:
+        r =  (type == R_X86_64_64);
+        break;
+#endif
+    }
+    return r;
+}
+
+
+static void
+update_entry(Dwarf_Debug dbg,
+    Dwarf_Bool is_64bit, Dwarf_Endianness endianess,
+    Dwarf_Half machine, struct Dwarf_Elf_Rela *rela,
+    Dwarf_Small *target_section, Dwarf_Small *section_data)
+{
+    unsigned int type = 0; 
+    unsigned int sym_idx = 0;
+#ifdef HAVE_ELF64_SYM
+    Elf64_Sym sym_buf;
+    Elf64_Sym *sym = 0;
+#else
+    Elf32_Sym sym_buf;
+    Elf32_Sym *sym = 0; 
+#endif
+    Elf32_Sym *sym32 = 0;
+    Dwarf_ufixed64 offset = 0;
+    Dwarf_sfixed64 addend = 0;
+    Dwarf_Unsigned reloc_size = 0;
+
+
+    /* Dwarf_Elf_Rela dereferencing */
+    offset = rela->r_offset;
+    addend = rela->r_addend;
+    type = rela->r_type;
+    sym_idx = rela->r_symidx;
+
+    if (is_64bit) {
+#ifdef HAVE_ELF64_SYM
+       sym = &((Elf64_Sym*)section_data)[sym_idx];
+#endif
+    } else {
+       sym32 = &((Elf32_Sym*)section_data)[sym_idx];
+
+       /* Convert Elf32_Sym struct to Elf64_Sym struct. We point at
+        * an Elf64_Sym local variable (sym_buf) to allow us to use the
+        * same pointer (sym) for both 32-bit and 64-bit instances.
+        */
+       sym = &sym_buf;
+       sym->st_name = sym32->st_name;
+       sym->st_info = sym32->st_info;
+       sym->st_other = sym32->st_other;
+       sym->st_shndx = sym32->st_shndx;
+       sym->st_value = sym32->st_value;
+       sym->st_size = sym32->st_size;
+    }
+
+    /* Determine relocation size */
+    if (is_32bit_abs_reloc(type, machine)) {
+        reloc_size = 4;
+    } else if (is_64bit_abs_reloc(type, machine)) {
+        reloc_size = 8;
+    } else {
+        return;
+    }
+
+
+    {
+        /* Assuming we do not need to do a READ_UNALIGNED here
+           at target_section + offset and add its value to
+           outval.  Some ABIs say no read (for example MIPS),
+           but if some do then which ones? */
+        Dwarf_Unsigned outval = sym->st_value + addend;
+        WRITE_UNALIGNED(dbg,target_section + offset,
+                  &outval,sizeof(outval),reloc_size);
+    }
+}
+
+
+
+static int 
+apply_rela_entries(Dwarf_Debug dbg,
+    Dwarf_Bool is_64bit,
+    Dwarf_Endianness endianess,
+    Dwarf_Half machine,
+    Dwarf_Small *target_section,
+    Dwarf_Small *symtab_section,
+    struct Dwarf_Elf_Rela *relas, unsigned int nrelas,
+    int *error)
+{
+    if ((target_section != NULL)  && (relas != NULL)) {
+        unsigned int i;
+        for (i = 0; i < nrelas; i++) {
+            update_entry(dbg, is_64bit,
+                endianess,
+                machine,
+                &(relas)[i],
+                target_section,
+                symtab_section);
+        }
+    }
+    return DW_DLV_OK;
+}
+
+
+static int
+loop_through_relocations(
+   Dwarf_Debug dbg,
+   dwarf_elf_object_access_internals_t* obj,
+   struct Dwarf_Section_s *relocatablesec,
+   int *error)
+{
+    Dwarf_Small *target_section = 0;
+    Dwarf_Small *symtab_section = obj->symtab->dss_data;
+    Dwarf_Small *relocation_section  = relocatablesec->dss_reloc_data;
+    Dwarf_Unsigned relocation_section_size =
+              relocatablesec->dss_reloc_size;
+    int ret = DW_DLV_ERROR;
+    struct Dwarf_Elf_Rela *relas = 0;
+    unsigned int nrelas = 0;
+    Dwarf_Small *mspace = 0;
+
+    ret = get_relocation_entries(obj->is_64bit,
+        obj->endianness,
+        obj->machine,
+        relocation_section, 
+        relocation_section_size, 
+        &relas, &nrelas, error);
+    if(ret != DW_DLV_OK) {
+        free(relas);
+        return ret;
+    }
+
+    /* Some systems read Elf in read-only memory via mmap or the like.
+       So the only safe thing is to copy the current data into
+       malloc space and refer to the malloc space instead of the
+       space returned by the elf library */
+    mspace = malloc(relocatablesec->dss_size);
+    if(!mspace) {
+        *error = DW_DLE_RELOC_SECTION_MALLOC_FAIL;
+        return DW_DLV_ERROR;
+    }
+    memcpy(mspace,relocatablesec->dss_data,relocatablesec->dss_size);
+    relocatablesec->dss_data = mspace;
+    target_section = relocatablesec->dss_data;
+    relocatablesec->dss_data_was_malloc = 1;
+
+    ret = apply_rela_entries(
+        dbg,
+        obj->is_64bit,
+        obj->endianness, obj->machine, 
+        target_section, 
+        symtab_section,
+        relas, nrelas, error);
+
+    free(relas);
+
+    return ret;
+}
+
+/*
+    Find the section data in dbg and find all the relevant
+    sections.  Then do relocations.
+*/
+static int
+dwarf_elf_object_relocate_a_section(void* obj_in,
+    Dwarf_Half section_index,
+    Dwarf_Debug dbg,
+    int* error)
+{
+    int res = DW_DLV_ERROR;
+    dwarf_elf_object_access_internals_t*obj = 0; 
+    struct Dwarf_Section_s * relocatablesec = 0;
+    if (section_index == 0) {
+        return DW_DLV_NO_ENTRY;
+    }
+    obj = (dwarf_elf_object_access_internals_t*)obj_in;
+
+    /* The section to relocate must already be loaded into memory. */
+    res = find_section_to_relocate(dbg, section_index,&relocatablesec,error);
+    if(res != DW_DLV_OK) {
+         return res;
+    }
+
+    /* Sun and possibly others do not always set sh_link in .debug_* sections. 
+       So we cannot do full  consistency checks. */
+    if(relocatablesec->dss_reloc_index == 0 ) {
+        /* Something is wrong. */
+        *error = DW_DLE_RELOC_SECTION_MISSING_INDEX;
+        return DW_DLV_ERROR;
+    }
+    /* Now load the relocations themselves. */
+    res =  dwarf_elf_object_access_load_section(obj_in,
+            relocatablesec->dss_reloc_index,
+            &relocatablesec->dss_reloc_data, error);
+    if(res != DW_DLV_OK) {
+            return res;
+    }
+
+    /* Now get the symtab. */
+    if  (!obj->symtab) {
+       obj->symtab = &dbg->de_elf_symtab;
+       obj->strtab = &dbg->de_elf_strtab;
+    }
+    if( obj->symtab->dss_index != relocatablesec->dss_reloc_link) {
+        /* Something is wrong. */
+        *error = DW_DLE_RELOC_MISMATCH_RELOC_INDEX;
+        return DW_DLV_ERROR;
+    }
+    if( obj->strtab->dss_index != obj->symtab->dss_link) {
+        /* Something is wrong. */
+        *error = DW_DLE_RELOC_MISMATCH_STRTAB_INDEX;
+        return DW_DLV_ERROR;
+    }
+    if(!obj->symtab->dss_data) {
+        /* Now load the symtab */
+        res =  dwarf_elf_object_access_load_section(obj_in,
+            obj->symtab->dss_index,
+            &obj->symtab->dss_data, error);
+        if(res != DW_DLV_OK) {
+            return res;
+        }
+    }
+    if(! obj->strtab->dss_data) {
+        /* Now load the strtab */
+        res = dwarf_elf_object_access_load_section(obj_in, 
+            obj->strtab->dss_index,
+            &obj->strtab->dss_data,error);
+        if(res != DW_DLV_OK){
+            return res;
+        }
+    }
+
+    /* We have all the data we need in memory. */
+    res = loop_through_relocations(dbg,obj,relocatablesec,error);
+
+    return res;
+}
+
+/* 
+    dwarf_elf_object_access_load_section
+ */
+static int 
+dwarf_elf_object_access_load_section(void* obj_in, 
+    Dwarf_Half section_index, 
+    Dwarf_Small** section_data, 
+    int* error)
+{
+    dwarf_elf_object_access_internals_t*obj = 
+        (dwarf_elf_object_access_internals_t*)obj_in;
+    if (section_index == 0) {
+        return DW_DLV_NO_ENTRY;
+    }
+
+    {
+        Elf_Scn *scn = 0;
+        Elf_Data *data = 0;
+
+        scn = elf_getscn(obj->elf, section_index);
+        if (scn == NULL) {
+            *error = DW_DLE_MDE;
+            return DW_DLV_ERROR;
+        }
+
+        /* 
+           When using libelf as a producer, section data may be stored
+           in multiple buffers. In libdwarf however, we only use libelf
+           as a consumer (there is a dwarf producer API, but it doesn't
+           use libelf). Because of this, this single call to elf_getdata
+           will retrieve the entire section in a single contiguous
+           buffer. */
+        data = elf_getdata(scn, NULL);
+        if (data == NULL) {
+                  *error = DW_DLE_MDE;
+                  return DW_DLV_ERROR;
+        }
+        *section_data = data->d_buf;
+    }
+    return DW_DLV_OK;
+}
+
+
+/* dwarf_elf_access method table. */
+static const struct Dwarf_Obj_Access_Methods_s dwarf_elf_object_access_methods = 
+{
+    dwarf_elf_object_access_get_section_info,
+    dwarf_elf_object_access_get_byte_order,
+    dwarf_elf_object_access_get_length_size,
+    dwarf_elf_object_access_get_pointer_size,
+    dwarf_elf_object_access_get_section_count,
+    dwarf_elf_object_access_load_section,
+    dwarf_elf_object_relocate_a_section 
+};
+
+
+/*
+    Interface for the ELF object file implementation.
+ */
+int 
+dwarf_elf_object_access_init(dwarf_elf_handle elf, 
+    int libdwarf_owns_elf,
+    Dwarf_Obj_Access_Interface** ret_obj,
+    int *err)
+{
+    int res = 0;
+    dwarf_elf_object_access_internals_t *internals = 0;
+    Dwarf_Obj_Access_Interface *intfc = 0;
+
+    internals = malloc(sizeof(dwarf_elf_object_access_internals_t));
+    if(!internals) {
+        /* Impossible case, we hope. Give up. */
+        return DW_DLV_ERROR;
+    }
+    memset(internals,0,sizeof(*internals));
+    res = dwarf_elf_object_access_internals_init(internals, elf, err);
+    if(res != DW_DLV_OK){
+        free(internals);
+        return DW_DLV_ERROR;
+    }
+    internals->libdwarf_owns_elf = libdwarf_owns_elf;
+    
+    intfc = malloc(sizeof(Dwarf_Obj_Access_Interface));
+    if(!intfc) {
+        /* Impossible case, we hope. Give up. */
+        free(internals);
+        return DW_DLV_ERROR;
+    }
+    /* Initialize the interface struct */
+    intfc->object = internals;
+    intfc->methods = &dwarf_elf_object_access_methods;
+
+    *ret_obj = intfc;
+    return DW_DLV_OK;
+}
+
+
+
+/*
+    Clean up the Dwarf_Obj_Access_Interface returned by elf_access_init.
+ */
+void 
+dwarf_elf_object_access_finish(Dwarf_Obj_Access_Interface* obj)
+{
+    if(!obj) {
+        return;
+    }
+    if(obj->object) {
+        dwarf_elf_object_access_internals_t *internals = 
+            (dwarf_elf_object_access_internals_t *)obj->object;
+        if(internals->libdwarf_owns_elf){
+            elf_end(internals->elf);
+        }
+    }
+    free(obj->object);
+    free(obj);
+}
+
+/*
+    This function returns the Elf * pointer
+    associated with a Dwarf_Debug.
+
+    This function only makes sense if ELF is implied.
+ */
+int
+dwarf_get_elf(Dwarf_Debug dbg, dwarf_elf_handle * elf,
+              Dwarf_Error * error)
+{   
+    struct Dwarf_Obj_Access_Interface_s * obj = 0;
+    if (dbg == NULL) {
+        _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_ERROR);
+    }
+
+    obj = dbg->de_obj_file; 
+    if(obj) {
+       dwarf_elf_object_access_internals_t *internals =
+           (dwarf_elf_object_access_internals_t*)obj->object;
+       if(internals->elf == NULL) {
+           _dwarf_error(dbg, error, DW_DLE_FNO);
+           return (DW_DLV_ERROR);
+       }
+       *elf = internals->elf;
+       return DW_DLV_OK;
+       
+    }
+    _dwarf_error(dbg, error, DW_DLE_FNO);
+    return DW_DLV_ERROR;
+}
+    
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_elf_access.h	Sun May 22 03:13:22 2011 +0100
@@ -0,0 +1,55 @@
+#ifndef _DWARF_ELF_PORT_H
+#define _DWARF_ELF_PORT_H
+/*
+
+  Copyright (C) 2008-2010 David Anderson. All rights reserved.
+  Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+/* ELF (usually libelf) object access for the generic object file interface */
+
+int
+dwarf_elf_object_access_init(dwarf_elf_handle  elf ,
+                    int libdwarf_owns_elf,
+                    Dwarf_Obj_Access_Interface**  ret_obj,
+                    int *err );
+
+void
+dwarf_elf_object_access_finish(Dwarf_Obj_Access_Interface*  obj );
+  
+/* End ELF object access for the generic object file interface */
+
+
+#endif
--- a/usr/src/tools/ctf/dwarf/common/dwarf_error.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_error.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+  Portions Copyright (C) 2008-2010 David Anderson.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -79,52 +80,52 @@
 
     "DW_DLE_DBG_ALLOC 23 Unable to malloc a Dwarf_Debug structure",
     "DW_DLE_FSTAT_ERROR 24 The file fd passed to dwarf_init "
-	"cannot be fstat()ed",
+        "cannot be fstat()ed",
     "DW_DLE_FSTAT_MODE_ERROR 25 The file mode bits do not "
-	"indicate that the file being opened via "
-	"dwarf_init() is a normal file",
+        "indicate that the file being opened via "
+        "dwarf_init() is a normal file",
     "DW_DLE_INIT_ACCESS_WRONG 26 A call to dwarf_init had an "
-	"access of other than DW_DLC_READ",
+        "access of other than DW_DLC_READ",
     "DW_DLE_ELF_BEGIN_ERROR 27 a call to "
-	"elf_begin(... ELF_C_READ_MMAP... ) failed",
+        "elf_begin(... ELF_C_READ_MMAP... ) failed",
     "DW_DLE_ELF_GETEHDR_ERROR 28 a call to "
-	"elf32_getehdr() or elf64_getehdr() failed",
+        "elf32_getehdr() or elf64_getehdr() failed",
     "DW_DLE_ELF_GETSHDR_ERROR 29 a call to "
-	"elf32_getshdr() or elf64_getshdr() failed",
+        "elf32_getshdr() or elf64_getshdr() failed",
     "DW_DLE_ELF_STRPTR_ERROR 30 a call to "
-	"elf_strptr() failed trying to get a section name",
+        "elf_strptr() failed trying to get a section name",
     "DW_DLE_DEBUG_INFO_DUPLICATE 31  Only one .debug_info  "
-	"section is allowed",
+        "section is allowed",
     "DW_DLE_DEBUG_INFO_NULL 32 .debug_info section present but "
-	"elf_getdata() failed or section is zero-length",
+        "elf_getdata() failed or section is zero-length",
     "DW_DLE_DEBUG_ABBREV_DUPLICATE 33 Only one .debug_abbrev  "
-	"section is allowed",
+        "section is allowed",
     "DW_DLE_DEBUG_ABBREV_NULL 34 .debug_abbrev section present but "
-	"elf_getdata() failed or section is zero-length",
+        "elf_getdata() failed or section is zero-length",
     "DW_DLE_DEBUG_ARANGES_DUPLICATE 35 Only one .debug_aranges  "
-	"section is allowed",
+        "section is allowed",
     "DW_DLE_DEBUG_ARANGES_NULL 36 .debug_aranges section present but "
-	"elf_getdata() failed or section is zero-length",
+        "elf_getdata() failed or section is zero-length",
     "DW_DLE_DEBUG_LINE_DUPLICATE 37 Only one .debug_line  "
-	"section is allowed",
+        "section is allowed",
     "DW_DLE_DEBUG_LINE_NULL (38) .debug_line section present but "
-	"elf_getdata() failed or section is zero-length",
+        "elf_getdata() failed or section is zero-length",
     "DW_DLE_DEBUG_LOC_DUPLICATE (39) Only one .debug_loc  "
-	"section is allowed",
+        "section is allowed",
     "DW_DLE_DEBUG_LOC_NULL (40) .debug_loc section present but "
-	"elf_getdata() failed or section is zero-length",
+        "elf_getdata() failed or section is zero-length",
     "DW_DLE_DEBUG_MACINFO_DUPLICATE (41) Only one .debug_macinfo  "
-	"section is allowed",
+        "section is allowed",
     "DW_DLE_DEBUG_MACINFO_NULL (42) .debug_macinfo section present but "
-	"elf_getdata() failed or section is zero-length",
+        "elf_getdata() failed or section is zero-length",
     "DW_DLE_DEBUG_PUBNAMES_DUPLICATE (43) Only one .debug_pubnames  "
-	"section is allowed",
+        "section is allowed",
     "DW_DLE_DEBUG_PUBNAMES_NULL (44) .debug_pubnames section present but "
-	"elf_getdata() failed or section is zero-length",
+        "elf_getdata() failed or section is zero-length",
     "DW_DLE_DEBUG_STR_DUPLICATE (45)  Only one .debug_str  "
-	"section is allowed",
+        "section is allowed",
     "DW_DLE_DEBUG_STR_NULL (46) .debug_str section present but "
-	"elf_getdata() failed or section is zero-length",
+        "elf_getdata() failed or section is zero-length",
     "DW_DLE_CU_LENGTH_ERROR (47)",
     "DW_DLE_VERSION_STAMP_ERROR (48)",
     "DW_DLE_ABBREV_OFFSET_ERROR (49)",
@@ -186,9 +187,9 @@
     "DW_DLE_FIRST_DIE_NOT_CU",
     "DW_DLE_NEXT_DIE_PTR_NULL",
     "DW_DLE_DEBUG_FRAME_DUPLICATE  Only one .debug_frame  "
-	"section is allowed",
+        "section is allowed",
     "DW_DLE_DEBUG_FRAME_NULL  .debug_frame section present but "
-	"elf_getdata() failed or section is zero-length",
+        "elf_getdata() failed or section is zero-length",
     "DW_DLE_ABBREV_DECODE_ERROR",
     "DW_DLE_DWARF_ABBREV_NULL",
     "DW_DLE_ATTR_NULL",
@@ -234,28 +235,28 @@
     "DW_DLE_DIE_ABBREV_LIST_NULL",
     "DW_DLE_DEBUG_FUNCNAMES_DUPLICATE",
     "DW_DLE_DEBUG_FUNCNAMES_NULL .debug_funcnames section present but "
-	"elf_getdata() failed or section is zero-length",
+        "elf_getdata() failed or section is zero-length",
     "DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR",
     "DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD",
     "DW_DLE_FUNC_NULL",
     "DW_DLE_FUNC_CONTEXT_NULL",
     "DW_DLE_DEBUG_TYPENAMES_DUPLICATE",
     "DW_DLE_DEBUG_TYPENAMES_NULL .debug_typenames section present but "
-	"elf_getdata() failed or section is zero-length",
+        "elf_getdata() failed or section is zero-length",
     "DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR",
     "DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD",
     "DW_DLE_TYPE_NULL",
     "DW_DLE_TYPE_CONTEXT_NULL",
     "DW_DLE_DEBUG_VARNAMES_DUPLICATE",
     "DW_DLE_DEBUG_VARNAMES_NULL .debug_varnames section present but "
-	"elf_getdata() failed or section is zero-length",
+        "elf_getdata() failed or section is zero-length",
     "DW_DLE_DEBUG_VARNAMES_VERSION_ERROR",
     "DW_DLE_DEBUG_VARNAMES_LENGTH_BAD",
     "DW_DLE_VAR_NULL",
     "DW_DLE_VAR_CONTEXT_NULL",
     "DW_DLE_DEBUG_WEAKNAMES_DUPLICATE",
     "DW_DLE_DEBUG_WEAKNAMES_NULL .debug_weaknames section present but "
-	"elf_getdata() failed or section is zero-length",
+        "elf_getdata() failed or section is zero-length",
 
     "DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR",
     "DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD",
@@ -279,9 +280,40 @@
     "DW_DLE_DF_POP_EMPTY_STACK(191)",
     "DW_DLE_DF_ALLOC_FAIL(192)",
     "DW_DLE_DF_FRAME_DECODING_ERROR(193)",
-
-
-
+    "DW_DLE_DEBUG_LOC_SECTION_SHORT(194)",
+    "DW_DLE_FRAME_AUGMENTATION_UNKNOWN(195)",
+    "DW_DLE_PUBTYPE_CONTEXT(196)",
+    "DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD(197)",
+    "DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR(198)",
+    "DW_DLE_DEBUG_PUBTYPES_DUPLICATE(199)",
+    "DW_DLE_FRAME_CIE_DECODE_ERROR(200)",
+    "DW_DLE_FRAME_REGISTER_UNREPRESENTABLE(201)",
+    "DW_DLE_FRAME_REGISTER_COUNT_MISMATCH(202)",
+    "DW_DLE_LINK_LOOP(203)",
+    "DW_DLE_STRP_OFFSET_BAD(204)",
+    "DW_DLE_DEBUG_RANGES_DUPLICATE(205)",
+    "DW_DLE_DEBUG_RANGES_OFFSET_BAD(206)",
+    "DW_DLE_DEBUG_RANGES_MISSING_END(207)",
+    "DW_DLE_DEBUG_RANGES_OUT_OF_MEM(208)",
+    "DW_DLE_DEBUG_SYMTAB_ERR(209)",
+    "DW_DLE_DEBUG_STRTAB_ERR(210)",
+    "DW_DLE_RELOC_MISMATCH_INDEX(211)",
+    "DW_DLE_RELOC_MISMATCH_RELOC_INDEX(212)",
+    "DW_DLE_RELOC_MISMATCH_STRTAB_INDEX(213)",
+    "DW_DLE_RELOC_SECTION_MISMATCH(214)",
+    "DW_DLE_RELOC_SECTION_MISSING_INDEX(215)",
+    "DW_DLE_RELOC_SECTION_LENGTH_ODD(216)",
+    "DW_DLE_RELOC_SECTION_PTR_NULL(217)",
+    "DW_DLE_RELOC_SECTION_MALLOC_FAIL(218)",
+    "DW_DLE_NO_ELF64_SUPPORT(219)",
+    "DW_DLE_MISSING_ELF64_SUPPORT(220)",
+    "DW_DLE_ORPHAN_FDE(221)",
+    "DW_DLE_DUPLICATE_INST_BLOCK(222)",
+    "DW_DLE_BAD_REF_SIG8_FORM(223)",
+    "DW_DLE_ATTR_EXPRLOC_FORM_BAD(224)",
+    "DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD(225)",
+    "DW_DLE_NOT_REF_FORM(226)",
+    "DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE(227)"
 };
 
 
@@ -304,48 +336,48 @@
        want to report the upper-level error, not this one. */
     if (error != NULL) {
 
-	/* 
-	   If dbg is NULL, use the alternate error struct. However,
-	   this will overwrite the earlier error. */
-	if (dbg != NULL) {
-	    errptr =
-		(Dwarf_Error) _dwarf_get_alloc(dbg, DW_DLA_ERROR, 1);
-	    if (errptr == NULL) {
-		fprintf(stderr,
-			"Could not allocate Dwarf_Error structure, "
-			"abort() in libdwarf.\n");
-		abort();
-	    }
-	} else {
-	    /* We have no dbg to work with. dwarf_init failed. We hack
-	       up a special area. */
-	    errptr = _dwarf_special_no_dbg_error_malloc();
-	    if (errptr == NULL) {
-		fprintf(stderr,
-			"Could not allocate Dwarf_Error structure, "
-			"abort() in libdwarf..\n");
-		abort();
-	    }
-	}
+        /* 
+           If dbg is NULL, use the alternate error struct. However,
+           this will overwrite the earlier error. */
+        if (dbg != NULL) {
+            errptr =
+                (Dwarf_Error) _dwarf_get_alloc(dbg, DW_DLA_ERROR, 1);
+            if (errptr == NULL) {
+                fprintf(stderr,
+                        "Could not allocate Dwarf_Error structure, "
+                        "abort() in libdwarf.\n");
+                abort();
+            }
+        } else {
+            /* We have no dbg to work with. dwarf_init failed. We hack
+               up a special area. */
+            errptr = _dwarf_special_no_dbg_error_malloc();
+            if (errptr == NULL) {
+                fprintf(stderr,
+                        "Could not allocate Dwarf_Error structure, "
+                        "abort() in libdwarf..\n");
+                abort();
+            }
+        }
 
-	errptr->er_errval = errval;
-	*error = errptr;
-	return;
+        errptr->er_errval = errval;
+        *error = errptr;
+        return;
     }
 
     if (dbg != NULL && dbg->de_errhand != NULL) {
-	errptr = (Dwarf_Error) _dwarf_get_alloc(dbg, DW_DLA_ERROR, 1);
-	if (errptr == NULL) {
-	    fprintf(stderr, "Could not allocate Dwarf_Error structure,"
-		    " abort() in libdwarf.\n");
-	    abort();
-	}
-	errptr->er_errval = errval;
-	dbg->de_errhand(errptr, dbg->de_errarg);
-	return;
+        errptr = (Dwarf_Error) _dwarf_get_alloc(dbg, DW_DLA_ERROR, 1);
+        if (errptr == NULL) {
+            fprintf(stderr, "Could not allocate Dwarf_Error structure,"
+                    " abort() in libdwarf.\n");
+            abort();
+        }
+        errptr->er_errval = errval;
+        dbg->de_errhand(errptr, dbg->de_errarg);
+        return;
     }
     fprintf(stderr,
-	    "abort() in libdwarf. No error argument, no handler.\n");
+            "abort() in libdwarf. No error argument, no handler.\n");
     abort();
 }
 
@@ -354,7 +386,7 @@
 dwarf_errno(Dwarf_Error error)
 {
     if (error == NULL) {
-	return (0);
+        return (0);
     }
 
     return (error->er_errval);
@@ -367,11 +399,11 @@
 dwarf_errmsg(Dwarf_Error error)
 {
     if (error == NULL) {
-	return "Dwarf_Error is NULL";
+        return "Dwarf_Error is NULL";
     }
 
     if (error->er_errval > (sizeof(_dwarf_errmsgs) / sizeof(char *))) {
-	return "Dwarf_Error value out of range";
+        return "Dwarf_Error value out of range";
     }
 
     return ((char *) _dwarf_errmsgs[error->er_errval]);
--- a/usr/src/tools/ctf/dwarf/common/dwarf_error.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_error.h	Sun May 22 03:13:22 2011 +0100
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
--- a/usr/src/tools/ctf/dwarf/common/dwarf_form.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_form.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,8 @@
 /*
 
-  Copyright (C) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved.
+  Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
+  Portions Copyright 2008-2010 David Anderson. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +21,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -41,25 +43,25 @@
 
 int
 dwarf_hasform(Dwarf_Attribute attr,
-	      Dwarf_Half form,
-	      Dwarf_Bool * return_bool, Dwarf_Error * error)
+              Dwarf_Half form,
+              Dwarf_Bool * return_bool, Dwarf_Error * error)
 {
-    Dwarf_CU_Context cu_context;
+    Dwarf_CU_Context cu_context = 0;
 
     if (attr == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+        return (DW_DLV_ERROR);
     }
 
     cu_context = attr->ar_cu_context;
     if (cu_context == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+        return (DW_DLV_ERROR);
     }
 
     if (cu_context->cc_dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
 
     *return_bool = (attr->ar_attribute_form == form);
@@ -71,38 +73,133 @@
 */
 int
 dwarf_whatform_direct(Dwarf_Attribute attr,
-		      Dwarf_Half * return_form, Dwarf_Error * error)
+                      Dwarf_Half * return_form, Dwarf_Error * error)
 {
     int res = dwarf_whatform(attr, return_form, error);
 
     if (res != DW_DLV_OK) {
-	return res;
+        return res;
     }
 
     *return_form = attr->ar_attribute_form_direct;
     return (DW_DLV_OK);
 }
+void *
+dwarf_uncompress_integer_block(
+    Dwarf_Debug      dbg,
+    Dwarf_Bool       unit_is_signed,
+    Dwarf_Small      unit_length_in_bits,
+    void*            input_block,
+    Dwarf_Unsigned   input_length_in_bytes,
+    Dwarf_Unsigned*  output_length_in_units_ptr,
+    Dwarf_Error*     error
+)
+{
+    Dwarf_Unsigned output_length_in_units = 0;
+    void * output_block = 0;
+    int i = 0;
+    char * ptr = 0;
+    int remain = 0;
+    Dwarf_sfixed * array = 0;
+
+    if (dbg == NULL) {
+        _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+        return((void *)DW_DLV_BADADDR);
+    }
+    
+    if (unit_is_signed == false ||
+        unit_length_in_bits != 32 ||
+        input_block == NULL ||
+        input_length_in_bytes == 0 ||
+        output_length_in_units_ptr == NULL) {
+        
+        _dwarf_error(NULL, error, DW_DLE_BADBITC);
+        return ((void *) DW_DLV_BADADDR);
+    }
+
+    /* At this point we assume the format is: signed 32 bit */
+
+    /* first uncompress everything to find the total size. */
+
+    output_length_in_units = 0;
+    remain = input_length_in_bytes;
+    ptr = input_block;
+    while (remain > 0) {
+        Dwarf_Signed num;
+        Dwarf_Word len;
+        num = _dwarf_decode_s_leb128((unsigned char *)ptr, &len);
+        ptr += len;
+        remain -= len;
+        output_length_in_units++;
+    }
+
+    if (remain != 0) {
+        _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
+        return((void *)DW_DLV_BADADDR);
+    }
+    
+    /* then alloc */
+
+    output_block = (void *)
+        _dwarf_get_alloc(dbg,
+                         DW_DLA_STRING,
+                         output_length_in_units * (unit_length_in_bits / 8));
+    if (output_block == NULL) {
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return((void*)DW_DLV_BADADDR);
+    }
+    
+    /* then uncompress again and copy into new buffer */
+
+    array = (Dwarf_sfixed *) output_block;
+    remain = input_length_in_bytes;
+    ptr = input_block;
+    for (i=0; i<output_length_in_units && remain>0; i++) {
+        Dwarf_Signed num;
+        Dwarf_Word len;
+        num = _dwarf_decode_s_leb128((unsigned char *)ptr, &len);
+        ptr += len;
+        remain -= len;
+        array[i] = num;
+    }
+
+    if (remain != 0) {
+        dwarf_dealloc(dbg, (unsigned char *)output_block, DW_DLA_STRING);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
+    }
+
+    *output_length_in_units_ptr = output_length_in_units;
+    return output_block;
+}
+
+void
+dwarf_dealloc_uncompressed_block(Dwarf_Debug dbg, void * space)
+{
+    dwarf_dealloc(dbg, space, DW_DLA_STRING);
+}
+
 
 int
 dwarf_whatform(Dwarf_Attribute attr,
-	       Dwarf_Half * return_form, Dwarf_Error * error)
+               Dwarf_Half * return_form, Dwarf_Error * error)
 {
-    Dwarf_CU_Context cu_context;
+    Dwarf_CU_Context cu_context = 0;
 
     if (attr == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+        return (DW_DLV_ERROR);
     }
 
     cu_context = attr->ar_cu_context;
     if (cu_context == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+        return (DW_DLV_ERROR);
     }
 
     if (cu_context->cc_dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
 
     *return_form = attr->ar_attribute_form;
@@ -117,24 +214,24 @@
 */
 int
 dwarf_whatattr(Dwarf_Attribute attr,
-	       Dwarf_Half * return_attr, Dwarf_Error * error)
+               Dwarf_Half * return_attr, Dwarf_Error * error)
 {
-    Dwarf_CU_Context cu_context;
+    Dwarf_CU_Context cu_context = 0;
 
     if (attr == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+        return (DW_DLV_ERROR);
     }
 
     cu_context = attr->ar_cu_context;
     if (cu_context == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+        return (DW_DLV_ERROR);
     }
 
     if (cu_context->cc_dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
 
     *return_attr = (attr->ar_attribute);
@@ -143,216 +240,325 @@
 
 
 /* 
+    A global offset cannot be returned by this interface:
+    see dwarf_global_formref().
+
     DW_FORM_ref_addr is considered an incorrect form 
-    for this call because this function returns an 
-    offset  within the local CU thru the pointer.
+    for this call because DW_FORM_ref_addr is a global-offset into 
+    the debug_info section.
+
+    For the same reason DW_FORM_data4/data8 are not returned
+    from this function.
 
-    DW_FORM_ref_addr has a value which is an address-size value which
-    is a global-offset into the debug_info section.
-    A DW_FORM_ref_addr cannot be returned by this interface:
-    see dwarf_global_formref();
+    For the same reason DW_FORM_sec_offset is not returned
+    from this function, DW_FORM_sec_offset is a global offset 
+    (to various sections, not a CU relative offset.
+
+    DW_FORM_ref_addr has a value which was documented in
+    DWARF2 as address-size but which was always an offset
+    so should have always been offset size (wording
+    corrected in DWARF3). 
+
     
 */
 int
 dwarf_formref(Dwarf_Attribute attr,
-	      Dwarf_Off * ret_offset, Dwarf_Error * error)
+              Dwarf_Off * ret_offset, Dwarf_Error * error)
 {
-    Dwarf_Debug dbg;
-    Dwarf_Unsigned offset;
-    Dwarf_CU_Context cu_context;
+    Dwarf_Debug dbg = 0;
+    Dwarf_Unsigned offset = 0;
+    Dwarf_CU_Context cu_context = 0;
 
 
     if (attr == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+        return (DW_DLV_ERROR);
     }
 
     cu_context = attr->ar_cu_context;
     if (cu_context == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+        return (DW_DLV_ERROR);
     }
 
     if (cu_context->cc_dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
     dbg = cu_context->cc_dbg;
 
     switch (attr->ar_attribute_form) {
 
     case DW_FORM_ref1:
-	offset = *(Dwarf_Small *) attr->ar_debug_info_ptr;
-	break;
+        offset = *(Dwarf_Small *) attr->ar_debug_info_ptr;
+        break;
 
     case DW_FORM_ref2:
-	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
-		       attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
-	break;
+        READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+                       attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
+        break;
 
     case DW_FORM_ref4:
-	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
-		       attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
-	break;
+        READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+                       attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
+        break;
 
     case DW_FORM_ref8:
-	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
-		       attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned));
-	break;
+        READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+                       attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned));
+        break;
 
     case DW_FORM_ref_udata:
-	offset = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL);
-	break;
+        offset = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL);
+        break;
 
     default:
-	_dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM);
+        return (DW_DLV_ERROR);
     }
 
     /* Check that offset is within current cu portion of .debug_info. */
-
     if (offset >= cu_context->cc_length +
-	cu_context->cc_length_size + cu_context->cc_extension_size) {
-	_dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD);
-	return (DW_DLV_ERROR);
+        cu_context->cc_length_size + cu_context->cc_extension_size) {
+        _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD);
+        return (DW_DLV_ERROR);
     }
 
     *ret_offset = (offset);
     return DW_DLV_OK;
 }
 
+/*  dwarf_formsig8 returns in the caller-provided 8 byte area
+    the 8 bytes of a DW_FORM_ref_sig8 (copying the bytes
+    directly to the caller).  Not a string, an 8 byte
+    MD5 hash.  This function is new in DWARF4 libdwarf.
+*/
+int dwarf_formsig8(Dwarf_Attribute attr,
+    Dwarf_Sig8 * returned_sig_bytes,
+    Dwarf_Error*     error)
+{
+    Dwarf_Debug dbg = 0;
+    Dwarf_Unsigned field_end_offset = 0;
+    Dwarf_CU_Context cu_context = 0;
+
+
+    if (attr == NULL) {
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+        return (DW_DLV_ERROR);
+    }
+
+    cu_context = attr->ar_cu_context;
+    if (cu_context == NULL) {
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+        return (DW_DLV_ERROR);
+    }
+
+    if (cu_context->cc_dbg == NULL) {
+        _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+        return (DW_DLV_ERROR);
+    }
+    dbg = cu_context->cc_dbg;
+
+    if(attr->ar_attribute_form != DW_FORM_ref_sig8 ) {
+        _dwarf_error(dbg, error, DW_DLE_BAD_REF_SIG8_FORM);
+        return (DW_DLV_ERROR);
+    }
+
+    field_end_offset = attr->ar_debug_info_ptr + sizeof(Dwarf_Sig8) -
+        (dbg->de_debug_info.dss_data + cu_context->cc_debug_info_offset);
+    /* Check that offset is within current cu portion of .debug_info. */
+    if (field_end_offset > cu_context->cc_length +
+        cu_context->cc_length_size + cu_context->cc_extension_size) {
+        _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD);
+        return (DW_DLV_ERROR);
+    }
+  
+    memcpy(returned_sig_bytes, attr->ar_debug_info_ptr, 
+        sizeof(Dwarf_Sig8));
+    return DW_DLV_OK;
+}
+
+
 /* 
-	Since this returns section-relative debug_info offsets,
-	this can represent all REFERENCE forms correctly
-	and allows all forms.
+    Since this returns section-relative debug_info offsets,
+    this can represent all REFERENCE forms correctly
+    and allows all applicable forms.
+
+    DW_FORM_ref_addr has a value which was documented in
+    DWARF2 as address-size but which was always an offset
+    so should have always been offset size (wording
+    corrected in DWARF3).
+
+    See the DWARF4 document for the 3 cases fitting
+    reference forms.  The caller must determine which section the
+    reference 'points' to.  The function added in November 2009, 
+    dwarf_get_form_class(), helps in this regard.
     
 */
 int
 dwarf_global_formref(Dwarf_Attribute attr,
-		     Dwarf_Off * ret_offset, Dwarf_Error * error)
+                     Dwarf_Off * ret_offset, Dwarf_Error * error)
 {
-    Dwarf_Debug dbg;
-    Dwarf_Unsigned offset;
-    Dwarf_Addr ref_addr;
-    Dwarf_CU_Context cu_context;
+    Dwarf_Debug dbg = 0;
+    Dwarf_Unsigned offset = 0;
+    Dwarf_Addr ref_addr = 0;
+    Dwarf_CU_Context cu_context = 0;
+    Dwarf_Half context_version = 0;
 
     if (attr == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+        return (DW_DLV_ERROR);
     }
 
     cu_context = attr->ar_cu_context;
     if (cu_context == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+        return (DW_DLV_ERROR);
     }
+    context_version = cu_context->cc_version_stamp;
 
     if (cu_context->cc_dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
     dbg = cu_context->cc_dbg;
 
     switch (attr->ar_attribute_form) {
 
     case DW_FORM_ref1:
-	offset = *(Dwarf_Small *) attr->ar_debug_info_ptr;
-	goto fixoffset;
+        offset = *(Dwarf_Small *) attr->ar_debug_info_ptr;
+        goto fixoffset;
 
     case DW_FORM_ref2:
-	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
-		       attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
-	goto fixoffset;
+        READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+                       attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
+        goto fixoffset;
 
     case DW_FORM_ref4:
-	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
-		       attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
-	goto fixoffset;
+        READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+                       attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
+        goto fixoffset;
 
     case DW_FORM_ref8:
-	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
-		       attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned));
-	goto fixoffset;
+        READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+                       attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned));
+        goto fixoffset;
 
     case DW_FORM_ref_udata:
-	offset = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL);
+        offset = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL);
 
-      fixoffset:		/* we have a local offset, make it
-				   global */
+      fixoffset:                /* we have a local offset, make it
+                                   global */
 
-	/* check legality of offset */
-	if (offset >= cu_context->cc_length +
-	    cu_context->cc_length_size +
-	    cu_context->cc_extension_size) {
-	    _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD);
-	    return (DW_DLV_ERROR);
-	}
+        /* check legality of offset */
+        if (offset >= cu_context->cc_length +
+            cu_context->cc_length_size +
+            cu_context->cc_extension_size) {
+            _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD);
+            return (DW_DLV_ERROR);
+        }
 
-	/* globalize the offset */
-	offset += cu_context->cc_debug_info_offset;
-	break;
-
+        /* globalize the offset */
+        offset += cu_context->cc_debug_info_offset;
+        break;
+    /* The DWARF2 document did not make clear that
+       DW_FORM_data4( and 8) were references with
+       global offsets to some section.
+       That was first clearly documented in DWARF3.
+       In DWARF4 these two forms are no longer references. */
+    case DW_FORM_data4:
+        if(context_version == DW_CU_VERSION4) {
+            _dwarf_error(dbg, error, DW_DLE_NOT_REF_FORM);
+            return (DW_DLV_ERROR);
+        }
+        READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+                       attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
+        /* The offset is global. */
+        break;
+    case DW_FORM_data8:
+        if(context_version == DW_CU_VERSION4) {
+            _dwarf_error(dbg, error, DW_DLE_NOT_REF_FORM);
+            return (DW_DLV_ERROR);
+        }
+        READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+                       attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned));
+        /* The offset is global. */
+        break;
     case DW_FORM_ref_addr:
-	/* This offset is defined to be debug_info global already, so
-	   use this value unaltered. */
-	READ_UNALIGNED(dbg, ref_addr, Dwarf_Addr,
-		       attr->ar_debug_info_ptr,
-		       cu_context->cc_length_size);
-	offset = ref_addr;
-	break;
+    case DW_FORM_sec_offset:
+        {
+            /* DW_FORM_sec_offset first exists in DWARF4.*/
+            /* It is up to the caller to know what the offset 
+               of DW_FORM_sec_offset refers to,
+               the offset is not going to refer to .debug_info! */
+            unsigned length_size = cu_context->cc_length_size;
+            if(length_size == 4) {
+                READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+                       attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
+            } else if (length_size == 8) {
+                READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+                       attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned));
+            } else {
+                _dwarf_error(dbg, error, DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD);
+                return (DW_DLV_ERROR);
+            }
+        }
+        break;
+
     default:
-	_dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM);
+        return (DW_DLV_ERROR);
     }
 
-    /* Check that offset is within current cu portion of .debug_info. */
-
-    *ret_offset = (offset);
+    /* We do not know what section the offset refers to, so
+       we have no way to check it for correctness. */
+    *ret_offset = offset;
     return DW_DLV_OK;
 }
 
 
 int
 dwarf_formaddr(Dwarf_Attribute attr,
-	       Dwarf_Addr * return_addr, Dwarf_Error * error)
+               Dwarf_Addr * return_addr, Dwarf_Error * error)
 {
-    Dwarf_Debug dbg;
-    Dwarf_Addr ret_addr;
-    Dwarf_CU_Context cu_context;
+    Dwarf_Debug dbg = 0;
+    Dwarf_Addr ret_addr = 0;
+    Dwarf_CU_Context cu_context = 0;
 
     if (attr == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+        return (DW_DLV_ERROR);
     }
 
     cu_context = attr->ar_cu_context;
     if (cu_context == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+        return (DW_DLV_ERROR);
     }
 
     if (cu_context->cc_dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
     dbg = cu_context->cc_dbg;
 
     if (attr->ar_attribute_form == DW_FORM_addr
-	/* || attr->ar_attribute_form == DW_FORM_ref_addr Allowance of
-	   DW_FORM_ref_addr was a mistake. The value returned in that
-	   case is NOT an address it is a global debug_info offset (ie, 
-	   not CU-relative offset within the CU in debug_info). The
-	   Dwarf document refers to it as an address (misleadingly) in
-	   sec 6.5.4 where it describes the reference form. It is
-	   address-sized so that the linker can easily update it, but
-	   it is a reference inside the debug_info section. No longer
-	   allowed. */
-	) {
+        /* || attr->ar_attribute_form == DW_FORM_ref_addr Allowance of
+           DW_FORM_ref_addr was a mistake. The value returned in that
+           case is NOT an address it is a global debug_info offset (ie, 
+           not CU-relative offset within the CU in debug_info). The
+           Dwarf document refers to it as an address (misleadingly) in
+           sec 6.5.4 where it describes the reference form. It is
+           address-sized so that the linker can easily update it, but
+           it is a reference inside the debug_info section. No longer
+           allowed. */
+        ) {
 
-	READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
-		       attr->ar_debug_info_ptr, dbg->de_pointer_size);
-	*return_addr = ret_addr;
-	return (DW_DLV_OK);
+        READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
+                       attr->ar_debug_info_ptr, 
+                       cu_context->cc_address_size);
+        *return_addr = ret_addr;
+        return (DW_DLV_OK);
     }
 
     _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
@@ -362,29 +568,35 @@
 
 int
 dwarf_formflag(Dwarf_Attribute attr,
-	       Dwarf_Bool * ret_bool, Dwarf_Error * error)
+               Dwarf_Bool * ret_bool, Dwarf_Error * error)
 {
-    Dwarf_CU_Context cu_context;
+    Dwarf_CU_Context cu_context = 0;
 
     if (attr == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+        return (DW_DLV_ERROR);
     }
 
     cu_context = attr->ar_cu_context;
     if (cu_context == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+        return (DW_DLV_ERROR);
     }
 
     if (cu_context->cc_dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+        return (DW_DLV_ERROR);
+    }
+    if (attr->ar_attribute_form == DW_FORM_flag_present) {
+        /* Implicit means we don't read any data at all. Just
+           the existence of the Form does it. DWARF4. */
+        *ret_bool = 1;
+        return (DW_DLV_OK);
     }
 
     if (attr->ar_attribute_form == DW_FORM_flag) {
-	*ret_bool = (*(Dwarf_Small *) attr->ar_debug_info_ptr != 0);
-	return (DW_DLV_OK);
+        *ret_bool = (*(Dwarf_Small *) attr->ar_debug_info_ptr != 0);
+        return (DW_DLV_OK);
     }
     _dwarf_error(cu_context->cc_dbg, error, DW_DLE_ATTR_FORM_BAD);
     return (DW_DLV_ERROR);
@@ -393,74 +605,77 @@
 
 int
 dwarf_formudata(Dwarf_Attribute attr,
-		Dwarf_Unsigned * return_uval, Dwarf_Error * error)
+                Dwarf_Unsigned * return_uval, Dwarf_Error * error)
 {
-    Dwarf_Unsigned ret_value;
-    Dwarf_Debug dbg;
-    Dwarf_CU_Context cu_context;
+    Dwarf_Unsigned ret_value = 0;
+    Dwarf_Debug dbg = 0;
+    Dwarf_CU_Context cu_context = 0;
 
     if (attr == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+        return (DW_DLV_ERROR);
     }
 
 
     cu_context = attr->ar_cu_context;
     if (cu_context == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+        return (DW_DLV_ERROR);
     }
 
     dbg = cu_context->cc_dbg;
     if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
 
     switch (attr->ar_attribute_form) {
 
     case DW_FORM_data1:
-	READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
-		       attr->ar_debug_info_ptr, sizeof(Dwarf_Small));
-	*return_uval = ret_value;
-	return DW_DLV_OK;
+        READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+                       attr->ar_debug_info_ptr, sizeof(Dwarf_Small));
+        *return_uval = ret_value;
+        return DW_DLV_OK;
 
+    /* READ_UNALIGNED does the right thing as it reads
+       the right number bits and generates host order. 
+       So we can just assign to *return_uval. */
     case DW_FORM_data2:{
-	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
-			   attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
-	    *return_uval = ret_value;
-	    return DW_DLV_OK;
-	}
+            READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+                           attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
+            *return_uval = ret_value;
+            return DW_DLV_OK;
+        }
 
     case DW_FORM_data4:{
-	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
-			   attr->ar_debug_info_ptr,
-			   sizeof(Dwarf_ufixed));
-	    *return_uval = ret_value;
-	    return DW_DLV_OK;
-	}
+            READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+                           attr->ar_debug_info_ptr,
+                           sizeof(Dwarf_ufixed));
+            *return_uval = ret_value;
+            return DW_DLV_OK;
+        }
 
     case DW_FORM_data8:{
-	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
-			   attr->ar_debug_info_ptr,
-			   sizeof(Dwarf_Unsigned));
-	    *return_uval = ret_value;
-	    return DW_DLV_OK;
-	}
-
+            READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+                           attr->ar_debug_info_ptr,
+                           sizeof(Dwarf_Unsigned));
+            *return_uval = ret_value;
+            return DW_DLV_OK;
+        }
+        break;
     case DW_FORM_udata:
-	ret_value =
-	    (_dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL));
-	*return_uval = ret_value;
-	return DW_DLV_OK;
+        ret_value =
+            (_dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL));
+        *return_uval = ret_value;
+        return DW_DLV_OK;
 
 
-	/* see bug 583450. We do not allow reading sdata from a udata
-	   value. Caller can retry, calling sdata */
+        /* see bug 583450. We do not allow reading sdata from a udata
+           value. Caller can retry, calling sdata */
 
 
     default:
-	break;
+        break;
     }
     _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
     return (DW_DLV_ERROR);
@@ -469,73 +684,76 @@
 
 int
 dwarf_formsdata(Dwarf_Attribute attr,
-		Dwarf_Signed * return_sval, Dwarf_Error * error)
+                Dwarf_Signed * return_sval, Dwarf_Error * error)
 {
-    Dwarf_Signed ret_value;
-    Dwarf_Debug dbg;
-    Dwarf_CU_Context cu_context;
+    Dwarf_Signed ret_value = 0;
+    Dwarf_Debug dbg = 0;
+    Dwarf_CU_Context cu_context = 0;
 
     if (attr == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+        return (DW_DLV_ERROR);
     }
 
     cu_context = attr->ar_cu_context;
     if (cu_context == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+        return (DW_DLV_ERROR);
     }
 
     dbg = cu_context->cc_dbg;
     if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
 
     switch (attr->ar_attribute_form) {
 
     case DW_FORM_data1:
-	*return_sval = (*(Dwarf_Sbyte *) attr->ar_debug_info_ptr);
-	return DW_DLV_OK;
+        *return_sval = (*(Dwarf_Sbyte *) attr->ar_debug_info_ptr);
+        return DW_DLV_OK;
 
+    /* READ_UNALIGNED does not sign extend. 
+       So we have to use a cast to get the
+       value sign extended in the right way for each case. */
     case DW_FORM_data2:{
-	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
-			   attr->ar_debug_info_ptr,
-			   sizeof(Dwarf_Shalf));
-	    *return_sval = (Dwarf_Shalf) ret_value;
-	    return DW_DLV_OK;
+            READ_UNALIGNED(dbg, ret_value, Dwarf_Signed,
+                           attr->ar_debug_info_ptr,
+                           sizeof(Dwarf_Shalf));
+            *return_sval = (Dwarf_Shalf) ret_value;
+            return DW_DLV_OK;
 
-	}
+        }
 
     case DW_FORM_data4:{
-	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
-			   attr->ar_debug_info_ptr,
-			   sizeof(Dwarf_sfixed));
-	    *return_sval = (Dwarf_Sword) ret_value;
-	    return DW_DLV_OK;
-	}
+            READ_UNALIGNED(dbg, ret_value, Dwarf_Signed,
+                           attr->ar_debug_info_ptr,
+                           sizeof(Dwarf_sfixed));
+            *return_sval = (Dwarf_sfixed) ret_value;
+            return DW_DLV_OK;
+        }
 
     case DW_FORM_data8:{
-	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
-			   attr->ar_debug_info_ptr,
-			   sizeof(Dwarf_Signed));
-	    *return_sval = (Dwarf_Signed) ret_value;
-	    return DW_DLV_OK;
-	}
+            READ_UNALIGNED(dbg, ret_value, Dwarf_Signed,
+                           attr->ar_debug_info_ptr,
+                           sizeof(Dwarf_Signed));
+            *return_sval = (Dwarf_Signed) ret_value;
+            return DW_DLV_OK;
+        }
 
     case DW_FORM_sdata:
-	ret_value =
-	    (_dwarf_decode_s_leb128(attr->ar_debug_info_ptr, NULL));
-	*return_sval = ret_value;
-	return DW_DLV_OK;
+        ret_value =
+            (_dwarf_decode_s_leb128(attr->ar_debug_info_ptr, NULL));
+        *return_sval = ret_value;
+        return DW_DLV_OK;
 
 
-	/* see bug 583450. We do not allow reading sdata from a udata
-	   value. Caller can retry, calling sdata */
+        /* see bug 583450. We do not allow reading sdata from a udata
+           value. Caller can retry, calling sdata */
 
 
     default:
-	break;
+        break;
     }
     _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
     return (DW_DLV_ERROR);
@@ -544,81 +762,81 @@
 
 int
 dwarf_formblock(Dwarf_Attribute attr,
-		Dwarf_Block ** return_block, Dwarf_Error * error)
+                Dwarf_Block ** return_block, Dwarf_Error * error)
 {
-    Dwarf_CU_Context cu_context;
-    Dwarf_Debug dbg;
-    Dwarf_Unsigned length;
-    Dwarf_Small *data;
-    Dwarf_Word leb128_length;
-    Dwarf_Block *ret_block;
+    Dwarf_CU_Context cu_context = 0;
+    Dwarf_Debug dbg = 0;
+    Dwarf_Unsigned length = 0;
+    Dwarf_Small *data = 0;
+    Dwarf_Word leb128_length = 0;
+    Dwarf_Block *ret_block = 0;
 
     if (attr == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+        return (DW_DLV_ERROR);
     }
 
     cu_context = attr->ar_cu_context;
     if (cu_context == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+        return (DW_DLV_ERROR);
     }
 
     if (cu_context->cc_dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
     dbg = cu_context->cc_dbg;
 
     switch (attr->ar_attribute_form) {
 
     case DW_FORM_block1:
-	length = *(Dwarf_Small *) attr->ar_debug_info_ptr;
-	data = attr->ar_debug_info_ptr + sizeof(Dwarf_Small);
-	break;
+        length = *(Dwarf_Small *) attr->ar_debug_info_ptr;
+        data = attr->ar_debug_info_ptr + sizeof(Dwarf_Small);
+        break;
 
     case DW_FORM_block2:
-	READ_UNALIGNED(dbg, length, Dwarf_Unsigned,
-		       attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
-	data = attr->ar_debug_info_ptr + sizeof(Dwarf_Half);
-	break;
+        READ_UNALIGNED(dbg, length, Dwarf_Unsigned,
+                       attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
+        data = attr->ar_debug_info_ptr + sizeof(Dwarf_Half);
+        break;
 
     case DW_FORM_block4:
-	READ_UNALIGNED(dbg, length, Dwarf_Unsigned,
-		       attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
-	data = attr->ar_debug_info_ptr + sizeof(Dwarf_ufixed);
-	break;
+        READ_UNALIGNED(dbg, length, Dwarf_Unsigned,
+                       attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
+        data = attr->ar_debug_info_ptr + sizeof(Dwarf_ufixed);
+        break;
 
     case DW_FORM_block:
-	length = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr,
-					&leb128_length);
-	data = attr->ar_debug_info_ptr + leb128_length;
-	break;
+        length = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr,
+                                        &leb128_length);
+        data = attr->ar_debug_info_ptr + leb128_length;
+        break;
 
     default:
-	_dwarf_error(cu_context->cc_dbg, error, DW_DLE_ATTR_FORM_BAD);
-	return (DW_DLV_ERROR);
+        _dwarf_error(cu_context->cc_dbg, error, DW_DLE_ATTR_FORM_BAD);
+        return (DW_DLV_ERROR);
     }
 
     /* Check that block lies within current cu in .debug_info. */
     if (attr->ar_debug_info_ptr + length >=
-	dbg->de_debug_info + cu_context->cc_debug_info_offset +
-	cu_context->cc_length + cu_context->cc_length_size +
-	cu_context->cc_extension_size) {
-	_dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD);
-	return (DW_DLV_ERROR);
+        dbg->de_debug_info.dss_data + cu_context->cc_debug_info_offset +
+        cu_context->cc_length + cu_context->cc_length_size +
+        cu_context->cc_extension_size) {
+        _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD);
+        return (DW_DLV_ERROR);
     }
 
     ret_block = (Dwarf_Block *) _dwarf_get_alloc(dbg, DW_DLA_BLOCK, 1);
     if (ret_block == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
     }
 
     ret_block->bl_len = length;
     ret_block->bl_data = (Dwarf_Ptr) data;
     ret_block->bl_from_loclist = 0;
-    ret_block->bl_section_offset = data - dbg->de_debug_info;
+    ret_block->bl_section_offset = data - dbg->de_debug_info.dss_data;
 
 
     *return_block = ret_block;
@@ -626,69 +844,120 @@
 }
 
 
+/* Contrary to long standing documentation,
+   The string pointer returned thru return_str must
+   never have dwarf_dealloc() applied to it.
+   Documentation fixed July 2005.
+*/
 int
 dwarf_formstring(Dwarf_Attribute attr,
-		 char **return_str, Dwarf_Error * error)
+                 char **return_str, Dwarf_Error * error)
 {
-    Dwarf_CU_Context cu_context;
-    Dwarf_Debug dbg;
-    Dwarf_Unsigned offset;
-    int res;
+    Dwarf_CU_Context cu_context = 0;
+    Dwarf_Debug dbg = 0;
+    Dwarf_Unsigned offset = 0;
+    int res = DW_DLV_ERROR;
 
     if (attr == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+        return (DW_DLV_ERROR);
     }
 
     cu_context = attr->ar_cu_context;
     if (cu_context == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+        return (DW_DLV_ERROR);
     }
 
     if (cu_context->cc_dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
     dbg = cu_context->cc_dbg;
 
     if (attr->ar_attribute_form == DW_FORM_string) {
 
-	void *begin = attr->ar_debug_info_ptr;
+        void *begin = attr->ar_debug_info_ptr;
 
-	if (0 == dbg->de_assume_string_in_bounds) {
-	    /* Check that string lies within current cu in .debug_info. 
-	     */
-	    void *end = dbg->de_debug_info +
-		cu_context->cc_debug_info_offset +
-		cu_context->cc_length + cu_context->cc_length_size +
-		cu_context->cc_extension_size;
-	    if (0 == _dwarf_string_valid(begin, end)) {
-		_dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD);
-		return (DW_DLV_ERROR);
-	    }
-	}
-	*return_str = (char *) (begin);
-	return DW_DLV_OK;
+        if (0 == dbg->de_assume_string_in_bounds) {
+            /* Check that string lies within current cu in .debug_info. 
+             */
+            void *end = dbg->de_debug_info.dss_data +
+                cu_context->cc_debug_info_offset +
+                cu_context->cc_length + cu_context->cc_length_size +
+                cu_context->cc_extension_size;
+            if (0 == _dwarf_string_valid(begin, end)) {
+                _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD);
+                return (DW_DLV_ERROR);
+            }
+        }
+        *return_str = (char *) (begin);
+        return DW_DLV_OK;
     }
 
     if (attr->ar_attribute_form == DW_FORM_strp) {
-	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
-		       attr->ar_debug_info_ptr,
-		       cu_context->cc_length_size);
+        READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+                       attr->ar_debug_info_ptr,
+                       cu_context->cc_length_size);
 
-	res =
-	    _dwarf_load_section(dbg,
-				dbg->de_debug_str_index,
-				&dbg->de_debug_str, error);
-	if (res != DW_DLV_OK) {
-	    return res;
-	}
-
-	*return_str = (char *) (dbg->de_debug_str + offset);
-	return DW_DLV_OK;
+        res = _dwarf_load_section(dbg, &dbg->de_debug_str,error);
+        if (res != DW_DLV_OK) {
+            return res;
+        }
+        if (0 == dbg->de_assume_string_in_bounds) {
+            /* Check that string lies within current cu in .debug_info. 
+             */
+            void *end = dbg->de_debug_str.dss_data + 
+                dbg->de_debug_str.dss_size;
+            void*begin = dbg->de_debug_str.dss_data + offset;
+            if (0 == _dwarf_string_valid(begin, end)) {
+                _dwarf_error(dbg, error, DW_DLE_STRP_OFFSET_BAD);
+                return (DW_DLV_ERROR);
+            }
+        }
+        *return_str = (char *) (dbg->de_debug_str.dss_data + offset);
+        return DW_DLV_OK;
     }
 
     _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
     return (DW_DLV_ERROR);
 }
+
+int
+dwarf_formexprloc(Dwarf_Attribute attr,
+    Dwarf_Unsigned * return_exprlen, 
+    Dwarf_Ptr  * block_ptr,
+    Dwarf_Error * error)
+{
+    Dwarf_Debug dbg = 0;
+    Dwarf_CU_Context cu_context = 0;
+
+    if (attr == NULL) {
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+        return (DW_DLV_ERROR);
+    }
+
+    cu_context = attr->ar_cu_context;
+    if (cu_context == NULL) {
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+        return (DW_DLV_ERROR);
+    }
+
+    dbg = cu_context->cc_dbg;
+    if (dbg == NULL) {
+        _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+        return (DW_DLV_ERROR);
+    }
+
+    if (attr->ar_attribute_form == DW_FORM_exprloc ) {
+        Dwarf_Unsigned exprlen =
+            (_dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL));
+        Dwarf_Small * addr = attr->ar_debug_info_ptr;
+        *return_exprlen = exprlen;
+        *block_ptr = addr + exprlen;
+        return DW_DLV_OK;
+
+    }
+    _dwarf_error(dbg, error, DW_DLE_ATTR_EXPRLOC_FORM_BAD);
+    return (DW_DLV_ERROR);
+}
--- a/usr/src/tools/ctf/dwarf/common/dwarf_frame.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_frame.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -32,6 +33,13 @@
   http://oss.sgi.com/projects/GenInfo/NoticeExplan
 
 */
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
 
 
 
@@ -39,22 +47,42 @@
 #include "dwarf_incl.h"
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/types.h>
 #include "dwarf_frame.h"
-#include "dwarf_arange.h"	/* using Arange as a way to build a
-				   list */
+#include "dwarf_arange.h"       /* Using Arange as a way to build a
+                                   list */
+
+#define FDE_NULL_CHECKS_AND_SET_DBG(fde,dbg )          \
+    do {                                               \
+     if ((fde) == NULL) {                              \
+        _dwarf_error(NULL, error, DW_DLE_FDE_NULL);    \
+        return (DW_DLV_ERROR);                         \
+    }                                                  \
+    (dbg)= (fde)->fd_dbg;                              \
+    if ((dbg) == NULL) {                               \
+        _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);\
+        return (DW_DLV_ERROR);                         \
+    } } while (0)
 
 
-static int
-  __dwarf_get_fde_list_internal(Dwarf_Debug dbg,
-				Dwarf_Cie ** cie_data,
-				Dwarf_Signed * cie_element_count,
-				Dwarf_Fde ** fde_data,
-				Dwarf_Signed * fde_element_count,
-				Dwarf_Small * section_ptr,
-				Dwarf_Unsigned section_length,
-				Dwarf_Unsigned cie_id_value,
-				int use_gnu_cie_calc,
-				Dwarf_Error * error);
+#define MIN(a,b)  (((a) < (b))? a:b)
+
+static void _dwarf_init_regrule_table(struct Dwarf_Reg_Rule_s *t1reg,
+                                      int last_reg_num,
+                                      int initial_value);
+static int dwarf_initialize_fde_table(Dwarf_Debug dbg,
+                                      struct Dwarf_Frame_s *fde_table,
+                                      unsigned table_real_data_size,
+                                      Dwarf_Error * error);
+static void dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table);
+
+#if 0
+/* Only used for debugging libdwarf. */
+static void dump_frame_rule(char *msg,
+                            struct Dwarf_Reg_Rule_s *reg_rule);
+#endif
+
+
 
 /* 
     This function is the heart of the debug_frame stuff.  Don't even
@@ -76,13 +104,13 @@
                                                                          
 
     If successful, returns DW_DLV_OK
-		And sets returned_count thru the pointer
-		 if make_instr is true.
-		If make_instr is false returned_count 
-		 should NOT be used by the caller (returned_count
-		 is set to 0 thru the pointer by this routine...)
+                And sets returned_count thru the pointer
+                 if make_instr is true.
+                If make_instr is false returned_count 
+                 should NOT be used by the caller (returned_count
+                 is set to 0 thru the pointer by this routine...)
     If unsuccessful, returns DW_DLV_ERROR
-		and sets returned_error to the error code
+                and sets returned_error to the error code
 
     It does not do a whole lot of input validation being a private 
     function.  Please make sure inputs are valid.
@@ -104,57 +132,78 @@
     (3) This function is also used to create the initial table row       
     defined by a Cie.  In this case, the Dwarf_Cie pointer cie, is       
     NULL.  For an FDE, however, cie points to the associated Cie.        
+
+    make_instr - make list of frame instr? 0/1
+    ret_frame_instr -  Ptr to list of ptrs to frame instrs
+    search_pc  - Search for a pc value?  0/1
+     search_pc_val -  Search for this pc value
+    initial_loc - Initial code location value.
+    start_instr_ptr -   Ptr to start of frame instrs.
+    final_instr_ptr -   Ptr just past frame instrs. 
+    table       -     Ptr to struct with last row. 
+    cie     -   Ptr to Cie used by the Fde.
+       Different cies may have distinct address-sizes, so the cie
+       is used, not de_pointer_size.
+
 */
-static int
-_dwarf_exec_frame_instr(Dwarf_Bool make_instr,	/* Make list of frame
-						   instr? */
-			Dwarf_Frame_Op ** ret_frame_instr,	/* Ptr
-								   to
-								   list 
-								   of
-								   ptrs 
-								   to
-								   fr
-								   instrs 
-								 */
-			Dwarf_Bool search_pc,	/* Search for a pc
-						   value? */
-			Dwarf_Addr search_pc_val,	/* Search for
-							   this pc
-							   value */
-			Dwarf_Addr loc,	/* initial location value */
-			Dwarf_Small * start_instr_ptr,	/* Ptr to start 
-							   of frame
-							   instrs.  */
-			Dwarf_Small * final_instr_ptr,	/* Ptr just
-							   past frame
-							   instrs.  */
-			Dwarf_Frame table,	/* Ptr to struct with
-						   last row.  */
-			Dwarf_Cie cie,	/* Ptr to Cie used by the Fde.
-					   */
-			Dwarf_Debug dbg,	/* Associated
-						   Dwarf_Debug */
-			Dwarf_Sword * returned_count,
-			int *returned_error)
+
+int
+_dwarf_exec_frame_instr(Dwarf_Bool make_instr,
+    Dwarf_Frame_Op ** ret_frame_instr,
+    Dwarf_Bool search_pc,
+    Dwarf_Addr search_pc_val,
+    Dwarf_Addr initial_loc,
+    Dwarf_Small * start_instr_ptr,
+    Dwarf_Small * final_instr_ptr,
+    Dwarf_Frame table,
+    Dwarf_Cie cie,
+    Dwarf_Debug dbg,
+    Dwarf_Half reg_num_of_cfa,
+    Dwarf_Sword * returned_count,
+    int *returned_error)
 {
+#define ERROR_IF_REG_NUM_TOO_HIGH(macreg,machigh_reg)               \
+     do {                                             \
+       if ((macreg) >= (machigh_reg) || (macreg) < 0) {            \
+        SIMPLE_ERROR_RETURN(DW_DLE_DF_REG_NUM_TOO_HIGH); \
+       }                                              \
+     } /*CONSTCOND */ while(0)
+#define SIMPLE_ERROR_RETURN(code) \
+        free(localregtab); \
+        *returned_error = code; \
+        return DW_DLV_ERROR
+
     /* Sweeps the frame instructions. */
     Dwarf_Small *instr_ptr;
 
-    /* Obvious from the documents. */
-    Dwarf_Small instr, opcode;
-    Dwarf_Small reg_no, reg_noA, reg_noB;
+    /* Register numbers not limited to just 255, thus not using
+       Dwarf_Small. */
+    typedef int reg_num_type;
+
     Dwarf_Unsigned factored_N_value;
-    Dwarf_Addr new_loc;		/* must be min de_pointer_size bytes */
-    Dwarf_Unsigned adv_loc;	/* must be min de_pointer_size bytes
-				   and must be at least sizeof
-				   Dwarf_ufixed */
+    Dwarf_Signed signed_factored_N_value;
+    Dwarf_Addr current_loc = initial_loc;       /* code location/
+                                                   pc-value
+                                                   corresponding to the 
+                                                   frame instructions.
+                                                   Starts at zero when
+                                                   the caller has no
+                                                   value to pass in. */
 
-    struct Dwarf_Reg_Rule_s reg[DW_FRAME_LAST_REG_NUM];
+    /* Must be min de_pointer_size bytes and must be at least sizeof
+       Dwarf_ufixed */
+    Dwarf_Unsigned adv_loc = 0;
+
+    int reg_count = dbg->de_frame_reg_rules_entry_count;
+    struct Dwarf_Reg_Rule_s *localregtab = calloc(reg_count,
+                                          sizeof(struct
+                                                 Dwarf_Reg_Rule_s));
+
+    struct Dwarf_Reg_Rule_s cfa_reg;
 
 
     /* This is used to end executing frame instructions.  */
-    /* Becomes true when search_pc is true and loc */
+    /* Becomes true when search_pc is true and current_loc */
     /* is greater than search_pc_val.  */
     Dwarf_Bool search_over = false;
 
@@ -166,6 +215,9 @@
     /* an leb128 encoded number.  */
     Dwarf_Word leb128_length;
 
+    Dwarf_Half address_size = (cie)? cie->ci_address_size: 
+        dbg->de_pointer_size;
+
     /* Counts the number of frame instructions executed.  */
     Dwarf_Word instr_count = 0;
 
@@ -174,7 +226,10 @@
        instruction. */
     Dwarf_Small fp_base_op = 0;
     Dwarf_Small fp_extended_op;
-    Dwarf_Half fp_register;
+    reg_num_type fp_register;
+
+    /* The value in fp_offset may be signed, though we call it
+       unsigned. This works ok for 2-s complement arithmetic. */
     Dwarf_Unsigned fp_offset;
     Dwarf_Off fp_instr_offset;
 
@@ -182,16 +237,16 @@
        Stack_table points to the row (Dwarf_Frame ie) being pushed or
        popped by a remember or restore instruction. Top_stack points to 
        the top of the stack of rows. */
-    Dwarf_Frame stack_table;
+    Dwarf_Frame stack_table = NULL;
     Dwarf_Frame top_stack = NULL;
 
     /* 
        These are used only when make_instr is true. Curr_instr is a
        pointer to the current frame instruction executed.
-       Curr_instr_ptr, head_instr_list, and curr_instr_list are used
-       to form a chain of Dwarf_Frame_Op structs. Dealloc_instr_ptr
-       is used to deallocate the structs used to form the chain.
-       Head_instr_block points to a contiguous list of pointers to the 
+       Curr_instr_ptr, head_instr_list, and curr_instr_list are used to 
+       form a chain of Dwarf_Frame_Op structs. Dealloc_instr_ptr is
+       used to deallocate the structs used to form the chain.
+       Head_instr_block points to a contiguous list of pointers to the
        Dwarf_Frame_Op structs executed. */
     Dwarf_Frame_Op *curr_instr;
     Dwarf_Chain curr_instr_item, dealloc_instr_item;
@@ -217,606 +272,812 @@
 
     /* Initialize first row from associated Cie. Using temp regs
        explicity */
-    struct Dwarf_Reg_Rule_s *t1reg;
-    struct Dwarf_Reg_Rule_s *t1end;
-    struct Dwarf_Reg_Rule_s *t2reg;
 
+    if (localregtab == 0) {
+        SIMPLE_ERROR_RETURN(DW_DLE_ALLOC_FAIL);
+    }
+    {
+        struct Dwarf_Reg_Rule_s *t1reg = localregtab;
+        struct Dwarf_Reg_Rule_s *t1end = t1reg + reg_count;
+
+        if (cie != NULL && cie->ci_initial_table != NULL) {
+            struct Dwarf_Reg_Rule_s *t2reg =
+                cie->ci_initial_table->fr_reg;
 
-    t1reg = reg;
-    t1end = t1reg + DW_FRAME_LAST_REG_NUM;
-    if (cie != NULL && cie->ci_initial_table != NULL) {
-	t2reg = cie->ci_initial_table->fr_reg;
-	for (; t1reg < t1end; t1reg++, t2reg++) {
-	    *t1reg = *t2reg;
-	}
-    } else {			/* initialize with same_value */
-	for (; t1reg < t1end; t1reg++) {
-	    t1reg->ru_is_off = 0;
-	    t1reg->ru_register = DW_FRAME_SAME_VAL;
-	    t1reg->ru_offset = 0;
-	}
+            if (reg_count != cie->ci_initial_table->fr_reg_count) {
+                /* Should never happen, it makes no sense to have the
+                   table sizes change. There is no real allowance for
+                   the set of registers to change dynamically in a
+                   single Dwarf_Debug (except the size can be set near
+                   initial Dwarf_Debug creation time). */
+                SIMPLE_ERROR_RETURN
+                    (DW_DLE_FRAME_REGISTER_COUNT_MISMATCH);
+            }
+
+            for (; t1reg < t1end; t1reg++, t2reg++) {
+                *t1reg = *t2reg;
+            }
+            cfa_reg = cie->ci_initial_table->fr_cfa_rule;
+        } else {
+            _dwarf_init_regrule_table(t1reg,
+                                      reg_count,
+                                      dbg->de_frame_rule_initial_value);
+            _dwarf_init_regrule_table(&cfa_reg, 1,
+                                      dbg->de_frame_rule_initial_value);
+        }
     }
 
     /* 
        The idea here is that the code_alignment_factor and
        data_alignment_factor which are needed for certain instructions
-       are valid only when the Cie has a proper augmentation string.
-       So if the augmentation is not right, only Frame instruction can
-       be read. */
+       are valid only when the Cie has a proper augmentation string. So 
+       if the augmentation is not right, only Frame instruction can be
+       read. */
     if (cie != NULL && cie->ci_augmentation != NULL) {
-	code_alignment_factor = cie->ci_code_alignment_factor;
-	data_alignment_factor = cie->ci_data_alignment_factor;
-    } else
-	need_augmentation = !make_instr;
+        code_alignment_factor = cie->ci_code_alignment_factor;
+        data_alignment_factor = cie->ci_data_alignment_factor;
+    } else {
+        need_augmentation = !make_instr;
+    }
 
     instr_ptr = start_instr_ptr;
     while ((instr_ptr < final_instr_ptr) && (!search_over)) {
+        Dwarf_Small instr = 0;
+        Dwarf_Small opcode = 0;
+        reg_num_type reg_no = 0;
+
+        fp_instr_offset = instr_ptr - start_instr_ptr;
+        instr = *(Dwarf_Small *) instr_ptr;
+        instr_ptr += sizeof(Dwarf_Small);
+
+        fp_base_op = (instr & 0xc0) >> 6;
+        if ((instr & 0xc0) == 0x00) {
+            opcode = instr;     /* is really extended op */
+            fp_extended_op = (instr & (~(0xc0))) & 0xff;
+        } else {
+            opcode = instr & 0xc0;      /* is base op */
+            fp_extended_op = 0;
+        }
+
+        fp_register = 0;
+        fp_offset = 0;
+        switch (opcode) {
+        case DW_CFA_advance_loc:
+            {
+                /* base op */
+                fp_offset = adv_pc = instr & DW_FRAME_INSTR_OFFSET_MASK;
+
+                if (need_augmentation) {
+                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+                }
+                adv_pc = adv_pc * code_alignment_factor;
+
+                search_over = search_pc &&
+                    (current_loc + adv_pc > search_pc_val);
+                /* If gone past pc needed, retain old pc.  */
+                if (!search_over) {
+                    current_loc = current_loc + adv_pc;
+                }
+                break;
+            }
+
+        case DW_CFA_offset:
+            {                   /* base op */
+                reg_no =
+                    (reg_num_type) (instr & DW_FRAME_INSTR_OFFSET_MASK);
+                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+
+                factored_N_value =
+                    _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
+                instr_ptr = instr_ptr + leb128_length;
+
+                fp_register = reg_no;
+                fp_offset = factored_N_value;
+
+                if (need_augmentation) {
+                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+                }
+
+                localregtab[reg_no].ru_is_off = 1;
+                localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
+                localregtab[reg_no].ru_register = reg_num_of_cfa;
+                localregtab[reg_no].ru_offset_or_block_len =
+                    factored_N_value * data_alignment_factor;
+
+                break;
+            }
+
+        case DW_CFA_restore:
+            {                   /* base op */
+                reg_no = (instr & DW_FRAME_INSTR_OFFSET_MASK);
+                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+
+                fp_register = reg_no;
+
+                if (cie != NULL && cie->ci_initial_table != NULL)
+                    localregtab[reg_no] = 
+                       cie->ci_initial_table->fr_reg[reg_no];
+                else if (!make_instr) {
+                    SIMPLE_ERROR_RETURN(DW_DLE_DF_MAKE_INSTR_NO_INIT);
+                }
+
+                break;
+            }
+        case DW_CFA_set_loc:
+            {
+                Dwarf_Addr new_loc = 0;
+
+                READ_UNALIGNED(dbg, new_loc, Dwarf_Addr,
+                               instr_ptr, address_size);
+                instr_ptr += address_size;
+                if (new_loc != 0 && current_loc != 0) {
+                    /* Pre-relocation or before current_loc is set the
+                       test comparing new_loc and current_loc makes no
+                       sense. Testing for non-zero (above) is a way
+                       (fallible) to check that current_loc, new_loc
+                       are already relocated.  */
+                    if (new_loc <= current_loc) {
+                        /* Within a frame, address must increase.
+                           Seemingly it has not. Seems to be an error. */
+
+                        SIMPLE_ERROR_RETURN
+                            (DW_DLE_DF_NEW_LOC_LESS_OLD_LOC);
+                    }
+                }
+
+                search_over = search_pc && (new_loc > search_pc_val);
+
+                /* If gone past pc needed, retain old pc.  */
+                if (!search_over) {
+                    current_loc = new_loc;
+                }
+                fp_offset = new_loc;
+                break;
+            }
+
+        case DW_CFA_advance_loc1:
+            {
+                fp_offset = adv_loc = *(Dwarf_Small *) instr_ptr;
+                instr_ptr += sizeof(Dwarf_Small);
+
+                if (need_augmentation) {
+                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+                }
+                adv_loc *= code_alignment_factor;
+
+                search_over = search_pc &&
+                    (current_loc + adv_loc > search_pc_val);
+
+                /* If gone past pc needed, retain old pc.  */
+                if (!search_over) {
+                    current_loc = current_loc + adv_loc;
+                }
+                break;
+            }
+
+        case DW_CFA_advance_loc2:
+            {
+                READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned,
+                               instr_ptr, sizeof(Dwarf_Half));
+                instr_ptr += sizeof(Dwarf_Half);
+                fp_offset = adv_loc;
+
+                if (need_augmentation) {
+                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+                }
+                adv_loc *= code_alignment_factor;
+
+                search_over = search_pc &&
+                    (current_loc + adv_loc > search_pc_val);
+
+                /* If gone past pc needed, retain old pc.  */
+                if (!search_over) {
+                    current_loc = current_loc + adv_loc;
+                }
+                break;
+            }
+
+        case DW_CFA_advance_loc4:
+            {
+                READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned,
+                               instr_ptr, sizeof(Dwarf_ufixed));
+                instr_ptr += sizeof(Dwarf_ufixed);
+                fp_offset = adv_loc;
+
+                if (need_augmentation) {
+                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+                }
+                adv_loc *= code_alignment_factor;
+
+                search_over = search_pc &&
+                    (current_loc + adv_loc > search_pc_val);
+
+                /* If gone past pc needed, retain old pc.  */
+                if (!search_over) {
+                    current_loc = current_loc + adv_loc;
+                }
+                break;
+            }
+
+        case DW_CFA_offset_extended:
+            {
+                Dwarf_Unsigned lreg;
+
+                DECODE_LEB128_UWORD(instr_ptr, lreg);
+                reg_no = (reg_num_type) lreg;
+                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);;
+                factored_N_value =
+                    _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
+                instr_ptr += leb128_length;
+
+                if (need_augmentation) {
+                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+                }
+                localregtab[reg_no].ru_is_off = 1;
+                localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
+                localregtab[reg_no].ru_register = reg_num_of_cfa;
+                localregtab[reg_no].ru_offset_or_block_len = factored_N_value *
+                    data_alignment_factor;
+
+                fp_register = reg_no;
+                fp_offset = factored_N_value;
+                break;
+            }
+
+        case DW_CFA_restore_extended:
+            {
+                Dwarf_Unsigned lreg;
+
+                DECODE_LEB128_UWORD(instr_ptr, lreg);
+                reg_no = (reg_num_type) lreg;
+
+                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+
+                if (cie != NULL && cie->ci_initial_table != NULL) {
+                    localregtab[reg_no] = cie->ci_initial_table->fr_reg[reg_no];
+                } else {
+                    if (!make_instr) {
+                        SIMPLE_ERROR_RETURN
+                            (DW_DLE_DF_MAKE_INSTR_NO_INIT);
+                    }
+                }
+
+                fp_register = reg_no;
+                break;
+            }
+
+        case DW_CFA_undefined:
+            {
+                Dwarf_Unsigned lreg;
+
+                DECODE_LEB128_UWORD(instr_ptr, lreg);
+                reg_no = (reg_num_type) lreg;
+                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+
+                localregtab[reg_no].ru_is_off = 0;
+                localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
+                localregtab[reg_no].ru_register = 
+                    dbg->de_frame_undefined_value_number;
+                localregtab[reg_no].ru_offset_or_block_len = 0;
+
+                fp_register = reg_no;
+                break;
+            }
+
+        case DW_CFA_same_value:
+            {
+                Dwarf_Unsigned lreg;
+
+                DECODE_LEB128_UWORD(instr_ptr, lreg);
+                reg_no = (reg_num_type) lreg;
+                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+
+                localregtab[reg_no].ru_is_off = 0;
+                localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
+                localregtab[reg_no].ru_register = 
+                    dbg->de_frame_same_value_number;
+                localregtab[reg_no].ru_offset_or_block_len = 0;
+                fp_register = reg_no;
+                break;
+            }
+
+        case DW_CFA_register:
+            {
+                Dwarf_Unsigned lreg;
+                reg_num_type reg_noA = 0;
+                reg_num_type reg_noB = 0;
+
+                DECODE_LEB128_UWORD(instr_ptr, lreg);
+                reg_noA = (reg_num_type) lreg;
+
+                ERROR_IF_REG_NUM_TOO_HIGH(reg_noA, reg_count);
+
+                DECODE_LEB128_UWORD(instr_ptr, lreg);
+                reg_noB = (reg_num_type) lreg;
+
+                if (reg_noB > reg_count) {
+                    SIMPLE_ERROR_RETURN(DW_DLE_DF_REG_NUM_TOO_HIGH);
+                }
 
 
-	fp_instr_offset = instr_ptr - start_instr_ptr;
-	instr = *(Dwarf_Small *) instr_ptr;
-	instr_ptr += sizeof(Dwarf_Small);
+                localregtab[reg_noA].ru_is_off = 0;
+                localregtab[reg_noA].ru_value_type = DW_EXPR_OFFSET;
+                localregtab[reg_noA].ru_register = reg_noB;
+                localregtab[reg_noA].ru_offset_or_block_len = 0;
 
-	fp_base_op = (instr & 0xc0) >> 6;
-	if ((instr & 0xc0) == 0x00) {
-	    opcode = instr;	/* is really extended op */
-	    fp_extended_op = (instr & (~(0xc0))) & 0xff;
-	} else {
-	    opcode = instr & 0xc0;	/* is base op */
-	    fp_extended_op = 0;
-	}
+                fp_register = reg_noA;
+                fp_offset = reg_noB;
+                break;
+            }
+
+        case DW_CFA_remember_state:
+            {
+                stack_table = (Dwarf_Frame)
+                    _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
+                if (stack_table == NULL) {
+                    SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
+                }
 
-	fp_register = 0;
-	fp_offset = 0;
-	switch (opcode) {
+                for (i = 0; i < reg_count; i++)
+                    stack_table->fr_reg[i] = localregtab[i];
+                stack_table->fr_cfa_rule = cfa_reg;
+
+                if (top_stack != NULL)
+                    stack_table->fr_next = top_stack;
+                top_stack = stack_table;
 
-	case DW_CFA_advance_loc:{
-				/* base op */
-		fp_offset = adv_pc = instr & DW_FRAME_INSTR_OFFSET_MASK;
+                break;
+            }
 
-		if (need_augmentation) {
-
-		    *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION);
-		    return DW_DLV_ERROR;
-		}
-		adv_pc = adv_pc * code_alignment_factor;
+        case DW_CFA_restore_state:
+            {
+                if (top_stack == NULL) {
+                    SIMPLE_ERROR_RETURN(DW_DLE_DF_POP_EMPTY_STACK);
+                }
+                stack_table = top_stack;
+                top_stack = stack_table->fr_next;
 
-		search_over = search_pc &&
-		    (loc + adv_pc > search_pc_val);
-		/* If gone past pc needed, retain old pc.  */
-		if (!search_over)
-		    loc = loc + adv_pc;
-		break;
-	    }
+                for (i = 0; i < reg_count; i++)
+                    localregtab[i] = stack_table->fr_reg[i];
+                cfa_reg = stack_table->fr_cfa_rule;
+
+                dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
+                break;
+            }
 
-	case DW_CFA_offset:{	/* base op */
-		reg_no = (instr & DW_FRAME_INSTR_OFFSET_MASK);
-		if (reg_no > DW_FRAME_LAST_REG_NUM) {
-		    *returned_error = DW_DLE_DF_REG_NUM_TOO_HIGH;
-		    return DW_DLV_ERROR;
-		}
+        case DW_CFA_def_cfa:
+            {
+                Dwarf_Unsigned lreg;
+
+                DECODE_LEB128_UWORD(instr_ptr, lreg);
+                reg_no = (reg_num_type) lreg;
+
+                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
 
-		factored_N_value =
-		    _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
-		instr_ptr = instr_ptr + leb128_length;
-
-		fp_register = reg_no;
-		fp_offset = factored_N_value;
+                factored_N_value =
+                    _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
+                instr_ptr += leb128_length;
 
-		if (need_augmentation) {
-		    *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION);
-		    return DW_DLV_ERROR;
-		}
+                if (need_augmentation) {
+                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+                }
+                cfa_reg.ru_is_off = 1;
+                cfa_reg.ru_value_type = DW_EXPR_OFFSET;
+                cfa_reg.ru_register = reg_no;
+                cfa_reg.ru_offset_or_block_len = factored_N_value;
 
-		reg[reg_no].ru_is_off = 1;
-		reg[reg_no].ru_register = DW_FRAME_CFA_COL;
-		reg[reg_no].ru_offset = factored_N_value *
-		    data_alignment_factor;
+                fp_register = reg_no;
+                fp_offset = factored_N_value;
+                break;
+            }
 
-		break;
-	    }
+        case DW_CFA_def_cfa_register:
+            {
+                Dwarf_Unsigned lreg;
 
-	case DW_CFA_restore:{	/* base op */
-		reg_no = (instr & DW_FRAME_INSTR_OFFSET_MASK);
-		if (reg_no > DW_FRAME_LAST_REG_NUM) {
-		    *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH);
-		    return DW_DLV_ERROR;
-		}
+                DECODE_LEB128_UWORD(instr_ptr, lreg);
+                reg_no = (reg_num_type) lreg;
+                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
 
-		fp_register = reg_no;
+                cfa_reg.ru_register = reg_no;
+                /* Do NOT set ru_offset_or_block_len or ru_is_off here. 
+                   See dwarf2/3 spec.  */
+                fp_register = reg_no;
+                break;
+            }
+
+        case DW_CFA_def_cfa_offset:
+            {
+                factored_N_value =
+                    _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
+                instr_ptr += leb128_length;
 
-		if (cie != NULL && cie->ci_initial_table != NULL)
-		    reg[reg_no] = cie->ci_initial_table->fr_reg[reg_no];
-		else if (!make_instr) {
-		    *returned_error = (DW_DLE_DF_MAKE_INSTR_NO_INIT);
-		    return DW_DLV_ERROR;
-		}
+                if (need_augmentation) {
+                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+                }
+                /* Do set ru_is_off here, as here factored_N_value
+                   counts.  */
+                cfa_reg.ru_is_off = 1;
+                cfa_reg.ru_value_type = DW_EXPR_OFFSET;
+                cfa_reg.ru_offset_or_block_len = factored_N_value;
 
-		break;
-	    }
-	case DW_CFA_set_loc:{
-		READ_UNALIGNED(dbg, new_loc, Dwarf_Addr,
-			       instr_ptr, dbg->de_pointer_size);
-		instr_ptr += dbg->de_pointer_size;
-		if (new_loc <= loc) {
-		    *returned_error = (DW_DLE_DF_NEW_LOC_LESS_OLD_LOC);
-		    return DW_DLV_ERROR;
-		}
-
-		search_over = search_pc && (new_loc > search_pc_val);
+                fp_offset = factored_N_value;
+                break;
+            }
+        case DW_CFA_nop:
+            {
+                break;
+            }
+            /* DWARF3 ops begin here. */
+        case DW_CFA_def_cfa_expression:
+            {
+                /* A single DW_FORM_block representing a dwarf
+                   expression. The form block establishes the way to
+                   compute the CFA. */
+                Dwarf_Unsigned block_len = 0;
 
-		/* If gone past pc needed, retain old pc.  */
-		if (!search_over)
-		    loc = new_loc;
-		fp_offset = new_loc;
-		break;
-	    }
-
-	case DW_CFA_advance_loc1:{
-		fp_offset = adv_loc = *(Dwarf_Small *) instr_ptr;
-		instr_ptr += sizeof(Dwarf_Small);
-
-		if (need_augmentation) {
-		    *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION);
-		    return DW_DLV_ERROR;
-		}
-		adv_loc *= code_alignment_factor;
-
-		search_over = search_pc &&
-		    (loc + adv_loc > search_pc_val);
+                DECODE_LEB128_UWORD(instr_ptr, block_len);
+                cfa_reg.ru_is_off = 0;  /* arbitrary */
+                cfa_reg.ru_value_type = DW_EXPR_EXPRESSION;
+                cfa_reg.ru_offset_or_block_len = block_len;
+                cfa_reg.ru_block = instr_ptr;
+                fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr;
+                instr_ptr += block_len;
+            }
+            break;
+        case DW_CFA_expression:
+            {
+                /* An unsigned leb128 value is the first operand (a
+                   register number). The second operand is single
+                   DW_FORM_block representing a dwarf expression. The
+                   evaluator pushes the CFA on the evaluation stack
+                   then evaluates the expression to compute the value
+                   of the register contents. */
+                Dwarf_Unsigned lreg = 0;
+                Dwarf_Unsigned block_len = 0;
 
-		/* If gone past pc needed, retain old pc.  */
-		if (!search_over)
-		    loc = loc + adv_loc;
-		break;
-	    }
-
-	case DW_CFA_advance_loc2:{
-		READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned,
-			       instr_ptr, sizeof(Dwarf_Half));
-		instr_ptr += sizeof(Dwarf_Half);
-		fp_offset = adv_loc;
-
-		if (need_augmentation) {
-		    *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION);
-		    return DW_DLV_ERROR;
-		}
-		adv_loc *= code_alignment_factor;
-
-		search_over = search_pc &&
-		    (loc + adv_loc > search_pc_val);
+                DECODE_LEB128_UWORD(instr_ptr, lreg);
+                reg_no = (reg_num_type) lreg;
+                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+                DECODE_LEB128_UWORD(instr_ptr, block_len);
+                localregtab[lreg].ru_is_off = 0;        /* arbitrary */
+                localregtab[lreg].ru_value_type = DW_EXPR_EXPRESSION;
+                localregtab[lreg].ru_offset_or_block_len = block_len;
+                localregtab[lreg].ru_block = instr_ptr;
+                fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr;
+                fp_register = reg_no;
+                instr_ptr += block_len;
+            }
+            break;
+        case DW_CFA_offset_extended_sf:
+            {
+                /* The first operand is an unsigned leb128 register
+                   number. The second is a signed factored offset.
+                   Identical to DW_CFA_offset_extended except the
+                   secondoperand is signed */
+                Dwarf_Unsigned lreg;
 
-		/* If gone past pc needed, retain old pc.  */
-		if (!search_over)
-		    loc = loc + adv_loc;
-		break;
-	    }
+                DECODE_LEB128_UWORD(instr_ptr, lreg);
+                reg_no = (reg_num_type) lreg;
+                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+                signed_factored_N_value =
+                    _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
+                instr_ptr += leb128_length;
 
-	case DW_CFA_advance_loc4:{
-		READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned,
-			       instr_ptr, sizeof(Dwarf_ufixed));
-		instr_ptr += sizeof(Dwarf_ufixed);
-		fp_offset = adv_loc;
+                if (need_augmentation) {
+                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+                }
+                localregtab[reg_no].ru_is_off = 1;
+                localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
+                localregtab[reg_no].ru_register = reg_num_of_cfa;
+                localregtab[reg_no].ru_offset_or_block_len =
+                    signed_factored_N_value * data_alignment_factor;
 
-		if (need_augmentation) {
-		    *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION);
-		    return DW_DLV_ERROR;
-		}
-		adv_loc *= code_alignment_factor;
-
-		search_over = search_pc &&
-		    (loc + adv_loc > search_pc_val);
+                fp_register = reg_no;
+                fp_offset = signed_factored_N_value;
+            }
+            break;
+        case DW_CFA_def_cfa_sf:
+            {
+                /* The first operand is an unsigned leb128 register
+                   number. The second is a signed leb128 factored
+                   offset. Identical to DW_CFA_def_cfa except that the
+                   second operand is signed and factored. */
+                Dwarf_Unsigned lreg;
 
-		/* If gone past pc needed, retain old pc.  */
-		if (!search_over)
-		    loc = loc + adv_loc;
-		break;
-	    }
+                DECODE_LEB128_UWORD(instr_ptr, lreg);
+                reg_no = (reg_num_type) lreg;
+                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
 
-	case DW_CFA_offset_extended:{
-		Dwarf_Unsigned lreg;
+                signed_factored_N_value =
+                    _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
+                instr_ptr += leb128_length;
 
-		DECODE_LEB128_UWORD(instr_ptr, lreg)
-		    reg_no = (Dwarf_Small) lreg;
-		if (reg_no > DW_FRAME_LAST_REG_NUM) {
-		    *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH);
-		    return DW_DLV_ERROR;
-		}
-		factored_N_value =
-		    _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
-		instr_ptr += leb128_length;
+                if (need_augmentation) {
+                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+                }
+                cfa_reg.ru_is_off = 1;
+                cfa_reg.ru_value_type = DW_EXPR_OFFSET;
+                cfa_reg.ru_register = reg_no;
+                cfa_reg.ru_offset_or_block_len =
+                    signed_factored_N_value * data_alignment_factor;
+
+                fp_register = reg_no;
+                fp_offset = signed_factored_N_value;
+            }
+            break;
+        case DW_CFA_def_cfa_offset_sf:
+            {
+                /* The operand is a signed leb128 operand representing
+                   a factored offset.  Identical to
+                   DW_CFA_def_cfa_offset excep the operand is signed
+                   and factored. */
 
-		if (need_augmentation) {
-		    *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION);
-		    return DW_DLV_ERROR;
-		}
-		reg[reg_no].ru_is_off = 1;
-		reg[reg_no].ru_register = DW_FRAME_CFA_COL;
-		reg[reg_no].ru_offset = factored_N_value *
-		    data_alignment_factor;
+                signed_factored_N_value =
+                    _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
+                instr_ptr += leb128_length;
 
-		fp_register = reg_no;
-		fp_offset = factored_N_value;
-		break;
-	    }
-
-	case DW_CFA_restore_extended:{
-		Dwarf_Unsigned lreg;
+                if (need_augmentation) {
+                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+                }
+                /* Do set ru_is_off here, as here factored_N_value
+                   counts.  */
+                cfa_reg.ru_is_off = 1;
+                cfa_reg.ru_value_type = DW_EXPR_OFFSET;
+                cfa_reg.ru_offset_or_block_len =
+                    signed_factored_N_value * data_alignment_factor;
 
-		DECODE_LEB128_UWORD(instr_ptr, lreg)
-		    reg_no = (Dwarf_Small) lreg;
-
-		if (reg_no > DW_FRAME_LAST_REG_NUM) {
-		    *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH);
-		    return DW_DLV_ERROR;
-		}
+                fp_offset = signed_factored_N_value;
+            }
+            break;
+        case DW_CFA_val_offset:
+            {
+                /* The first operand is an unsigned leb128 register
+                   number. The second is a factored unsigned offset.
+                   Makes the register be a val_offset(N) rule with N =
+                   factored_offset*data_alignment_factor. */
 
-		if (cie != NULL && cie->ci_initial_table != NULL) {
-		    reg[reg_no] = cie->ci_initial_table->fr_reg[reg_no];
-		} else {
-		    if (!make_instr) {
-			*returned_error =
-			    (DW_DLE_DF_MAKE_INSTR_NO_INIT);
-			return DW_DLV_ERROR;
-		    }
-		}
+                Dwarf_Unsigned lreg;
+
+                DECODE_LEB128_UWORD(instr_ptr, lreg);
+                reg_no = (reg_num_type) lreg;
 
-		fp_register = reg_no;
-		break;
-	    }
+                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+
+                factored_N_value =
+                    _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
+                instr_ptr += leb128_length;
 
-	case DW_CFA_undefined:{
-		Dwarf_Unsigned lreg;
+                if (need_augmentation) {
+                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+                }
+                /* Do set ru_is_off here, as here factored_N_value
+                   counts.  */
+                localregtab[reg_no].ru_is_off = 1;
+                localregtab[reg_no].ru_register = reg_num_of_cfa;
+                localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET;
+                localregtab[reg_no].ru_offset_or_block_len =
+                    factored_N_value * data_alignment_factor;
 
-		DECODE_LEB128_UWORD(instr_ptr, lreg)
-		    reg_no = (Dwarf_Small) lreg;
-		if (reg_no > DW_FRAME_LAST_REG_NUM) {
-		    *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH);
-		    return DW_DLV_ERROR;
-		}
+                fp_offset = factored_N_value;
+                break;
+            }
+        case DW_CFA_val_offset_sf:
+            {
+                /* The first operand is an unsigned leb128 register
+                   number. The second is a factored signed offset.
+                   Makes the register be a val_offset(N) rule with N =
+                   factored_offset*data_alignment_factor. */
+                Dwarf_Unsigned lreg;
 
-		reg[reg_no].ru_is_off = 0;
-		reg[reg_no].ru_register = DW_FRAME_UNDEFINED_VAL;
-		reg[reg_no].ru_offset = 0;
+                DECODE_LEB128_UWORD(instr_ptr, lreg);
+                reg_no = (reg_num_type) lreg;
 
-		fp_register = reg_no;
-		break;
-	    }
+                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+                signed_factored_N_value =
+                    _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
+                instr_ptr += leb128_length;
 
-	case DW_CFA_same_value:{
-		Dwarf_Unsigned lreg;
+                if (need_augmentation) {
+                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+                }
+                /* Do set ru_is_off here, as here factored_N_value
+                   counts.  */
+                localregtab[reg_no].ru_is_off = 1;
+                localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET;
+                localregtab[reg_no].ru_offset_or_block_len =
+                    signed_factored_N_value * data_alignment_factor;
 
-		DECODE_LEB128_UWORD(instr_ptr, lreg)
-		    reg_no = (Dwarf_Small) lreg;
-		if (reg_no > DW_FRAME_LAST_REG_NUM) {
-		    *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH);
-		    return DW_DLV_ERROR;
-		}
-
-		reg[reg_no].ru_is_off = 0;
-		reg[reg_no].ru_register = DW_FRAME_SAME_VAL;
-		reg[reg_no].ru_offset = 0;
-		fp_register = reg_no;
-		break;
-	    }
+                fp_offset = signed_factored_N_value;
 
-	case DW_CFA_register:{
-		Dwarf_Unsigned lreg;
-
-		DECODE_LEB128_UWORD(instr_ptr, lreg)
-		    reg_noA = (Dwarf_Small) lreg;
+            }
+            break;
+        case DW_CFA_val_expression:
+            {
+                /* The first operand is an unsigned leb128 register
+                   number. The second is a DW_FORM_block representing a 
+                   DWARF expression. The rule for the register number
+                   becomes a val_expression(E) rule. */
+                Dwarf_Unsigned lreg = 0;
+                Dwarf_Unsigned block_len = 0;
 
-		if (reg_noA > DW_FRAME_LAST_REG_NUM) {
-		    *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH);
-		    return DW_DLV_ERROR;
-		}
+                DECODE_LEB128_UWORD(instr_ptr, lreg);
+                reg_no = (reg_num_type) lreg;
+                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+                DECODE_LEB128_UWORD(instr_ptr, block_len);
+                localregtab[lreg].ru_is_off = 0;        /* arbitrary */
+                localregtab[lreg].ru_value_type = DW_EXPR_VAL_EXPRESSION;
+                localregtab[lreg].ru_offset_or_block_len = block_len;
+                localregtab[lreg].ru_block = instr_ptr;
+                fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr;
 
-		DECODE_LEB128_UWORD(instr_ptr, lreg)
-		    reg_noB = (Dwarf_Small) lreg;
+                instr_ptr += block_len;
+                fp_register = reg_no;
 
-		if (reg_noB > DW_FRAME_LAST_REG_NUM) {
-		    *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH);
-		    return DW_DLV_ERROR;
-		}
+            }
+            break;
+
+            /* END DWARF3 new ops. */
 
 
-		reg[reg_noA].ru_is_off = 0;
-		reg[reg_noA].ru_register = reg_noB;
-
-		reg[reg_noA].ru_offset = 0;
-
-		fp_register = reg_noA;
-		fp_offset = reg_noB;
-		break;
-	    }
-
-	case DW_CFA_remember_state:{
-		stack_table = (Dwarf_Frame)
-		    _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
-		if (stack_table == NULL) {
-		    *returned_error = (DW_DLE_DF_ALLOC_FAIL);
-		    return DW_DLV_ERROR;
-		}
-
-		for (i = 0; i < DW_FRAME_LAST_REG_NUM; i++)
-		    stack_table->fr_reg[i] = reg[i];
-
-		if (top_stack != NULL)
-		    stack_table->fr_next = top_stack;
-		top_stack = stack_table;
-
-		break;
-	    }
-
-	case DW_CFA_restore_state:{
-		if (top_stack == NULL) {
-		    *returned_error = (DW_DLE_DF_POP_EMPTY_STACK);
-		    return DW_DLV_ERROR;
-		}
-		stack_table = top_stack;
-		top_stack = stack_table->fr_next;
-
-		for (i = 0; i < DW_FRAME_LAST_REG_NUM; i++)
-		    reg[i] = stack_table->fr_reg[i];
-
-		dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
-		break;
-	    }
-
-	case DW_CFA_def_cfa:{
-		Dwarf_Unsigned lreg;
-
-		DECODE_LEB128_UWORD(instr_ptr, lreg)
-		    reg_no = (Dwarf_Small) lreg;
-
-		if (reg_no > DW_FRAME_LAST_REG_NUM) {
-		    *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH);
-		    return (DW_DLV_ERROR);
-		}
-
-		factored_N_value =
-		    _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
-		instr_ptr += leb128_length;
-
-		if (need_augmentation) {
-		    *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION);
-		    return DW_DLV_ERROR;
-		}
-		reg[DW_FRAME_CFA_COL].ru_is_off = 1;
-		reg[DW_FRAME_CFA_COL].ru_register = reg_no;
-		reg[DW_FRAME_CFA_COL].ru_offset = factored_N_value;
-
-		fp_register = reg_no;
-		fp_offset = factored_N_value;
-		break;
-	    }
-
-	case DW_CFA_def_cfa_register:{
-		Dwarf_Unsigned lreg;
-
-		DECODE_LEB128_UWORD(instr_ptr, lreg)
-		    reg_no = (Dwarf_Small) lreg;
-
-		if (reg_no > DW_FRAME_LAST_REG_NUM) {
-		    *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH);
-		    return DW_DLV_ERROR;
-		}
-
-		reg[DW_FRAME_CFA_COL].ru_is_off = 0;
-		reg[DW_FRAME_CFA_COL].ru_register = reg_no;
-		reg[DW_FRAME_CFA_COL].ru_offset = 0;
-		fp_register = reg_no;
-		break;
-	    }
-
-	case DW_CFA_def_cfa_offset:{
-		factored_N_value =
-		    _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
-		instr_ptr += leb128_length;
-
-		if (need_augmentation) {
-		    *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION);
-		    return DW_DLV_ERROR;
-		}
-		reg[DW_FRAME_CFA_COL].ru_offset = factored_N_value;
-
-		fp_offset = factored_N_value;
-		break;
-	    }
-
-	case DW_CFA_nop:{
-		break;
-	    }
-
 #ifdef DW_CFA_GNU_window_save
-	case DW_CFA_GNU_window_save:{
-		/* no information: this just tells unwinder to restore
-		   the window registers from the previous frame's
-		   window save area */
-		break;
-	    }
+        case DW_CFA_GNU_window_save:
+            {
+                /* no information: this just tells unwinder to restore
+                   the window registers from the previous frame's
+                   window save area */
+                break;
+            }
 #endif
 #ifdef  DW_CFA_GNU_args_size
-	    /* single uleb128 is the current arg area size in bytes. No 
-	       register exists yet to save this in */
-	case DW_CFA_GNU_args_size:{
-		Dwarf_Unsigned lreg;
+            /* single uleb128 is the current arg area size in bytes. No 
+               register exists yet to save this in */
+        case DW_CFA_GNU_args_size:
+            {
+                Dwarf_Unsigned lreg;
 
-		DECODE_LEB128_UWORD(instr_ptr, lreg)
-		    reg_no = (Dwarf_Small) lreg;
+                DECODE_LEB128_UWORD(instr_ptr, lreg);
+                reg_no = (reg_num_type) lreg;
 
-		break;
-	    }
+                break;
+            }
 #endif
-	}
+        default:
+            /* ERROR, we have an opcode we know nothing about. Memory
+               leak here, but an error like this is not supposed to
+               happen so we ignore the leak. These used to be ignored,
+               now we notice and report. */
+            SIMPLE_ERROR_RETURN(DW_DLE_DF_FRAME_DECODING_ERROR);
 
-	if (make_instr) {
-	    instr_count++;
+        }
+
+        if (make_instr) {
+            instr_count++;
 
-	    curr_instr = (Dwarf_Frame_Op *)
-		_dwarf_get_alloc(dbg, DW_DLA_FRAME_OP, 1);
-	    if (curr_instr == NULL) {
-		*returned_error = (DW_DLE_DF_ALLOC_FAIL);
-		return DW_DLV_ERROR;
-	    }
+            curr_instr = (Dwarf_Frame_Op *)
+                _dwarf_get_alloc(dbg, DW_DLA_FRAME_OP, 1);
+            if (curr_instr == NULL) {
+                SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
+            }
 
-	    curr_instr->fp_base_op = fp_base_op;
-	    curr_instr->fp_extended_op = fp_extended_op;
-	    curr_instr->fp_register = fp_register;
-	    curr_instr->fp_offset = fp_offset;
-	    curr_instr->fp_instr_offset = fp_instr_offset;
+            curr_instr->fp_base_op = fp_base_op;
+            curr_instr->fp_extended_op = fp_extended_op;
+            curr_instr->fp_register = fp_register;
+            curr_instr->fp_offset = fp_offset;
+            curr_instr->fp_instr_offset = fp_instr_offset;
 
-	    curr_instr_item = (Dwarf_Chain)
-		_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
-	    if (curr_instr_item == NULL) {
-		*returned_error = (DW_DLE_DF_ALLOC_FAIL);
-		return DW_DLV_ERROR;
-	    }
+            curr_instr_item = (Dwarf_Chain)
+                _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+            if (curr_instr_item == NULL) {
+                SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
+            }
 
-	    curr_instr_item->ch_item = curr_instr;
-	    if (head_instr_chain == NULL)
-		head_instr_chain = tail_instr_chain = curr_instr_item;
-	    else {
-		tail_instr_chain->ch_next = curr_instr_item;
-		tail_instr_chain = curr_instr_item;
-	    }
-	}
+            curr_instr_item->ch_item = curr_instr;
+            if (head_instr_chain == NULL)
+                head_instr_chain = tail_instr_chain = curr_instr_item;
+            else {
+                tail_instr_chain->ch_next = curr_instr_item;
+                tail_instr_chain = curr_instr_item;
+            }
+        }
     }
 
     /* 
-       If frame instruction decoding was right we would stop exactly
-       at final_instr_ptr. */
+       If frame instruction decoding was right we would stop exactly at 
+       final_instr_ptr. */
     if (instr_ptr > final_instr_ptr) {
-	*returned_error = (DW_DLE_DF_FRAME_DECODING_ERROR);
-	return DW_DLV_ERROR;
+        SIMPLE_ERROR_RETURN(DW_DLE_DF_FRAME_DECODING_ERROR);
     }
 
-    /* Create the last row generated.  */
+    /* Fill in the actual output table, the space the caller passed in. */
     if (table != NULL) {
-	t1reg = reg;
-	t1end = t1reg + DW_FRAME_LAST_REG_NUM;
-	table->fr_loc = loc;
-	t2reg = table->fr_reg;
-	for (; t1reg < t1end; t1reg++, t2reg++) {
-	    *t2reg = *t1reg;
-	}
+
+        struct Dwarf_Reg_Rule_s *t2reg = table->fr_reg;
+        struct Dwarf_Reg_Rule_s *t3reg = localregtab;
+        struct Dwarf_Reg_Rule_s *t3end = t3reg + reg_count;
+
+        table->fr_loc = current_loc;
+        for (; t3reg < t3end; t3reg++, t2reg++) {
+            *t2reg = *t3reg;
+        }
+
+        /* CONSTCOND */
+        /* Do not update the main table with the cfa_reg.
+           Just leave cfa_reg as cfa_reg. */
+        table->fr_cfa_rule = cfa_reg;
     }
 
     /* Dealloc anything remaining on stack. */
     for (; top_stack != NULL;) {
-	stack_table = top_stack;
-	top_stack = top_stack->fr_next;
-	dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
+        stack_table = top_stack;
+        top_stack = top_stack->fr_next;
+        dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
     }
 
     if (make_instr) {
-	/* Allocate list of pointers to Dwarf_Frame_Op's.  */
-	head_instr_block = (Dwarf_Frame_Op *)
-	    _dwarf_get_alloc(dbg, DW_DLA_FRAME_BLOCK, instr_count);
-	if (head_instr_block == NULL) {
-	    *returned_error = DW_DLE_DF_ALLOC_FAIL;
-	    return DW_DLV_ERROR;
-	}
+        /* Allocate list of pointers to Dwarf_Frame_Op's.  */
+        head_instr_block = (Dwarf_Frame_Op *)
+            _dwarf_get_alloc(dbg, DW_DLA_FRAME_BLOCK, instr_count);
+        if (head_instr_block == NULL) {
+            SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
+        }
 
-	/* 
-	   Store pointers to Dwarf_Frame_Op's in this list and
-	   deallocate the structs that chain the Dwarf_Frame_Op's. */
-	curr_instr_item = head_instr_chain;
-	for (i = 0; i < instr_count; i++) {
-	    *(head_instr_block + i) =
-		*(Dwarf_Frame_Op *) curr_instr_item->ch_item;
-	    dealloc_instr_item = curr_instr_item;
-	    curr_instr_item = curr_instr_item->ch_next;
-	    dwarf_dealloc(dbg, dealloc_instr_item->ch_item,
-			  DW_DLA_FRAME_OP);
-	    dwarf_dealloc(dbg, dealloc_instr_item, DW_DLA_CHAIN);
-	}
-	*ret_frame_instr = head_instr_block;
+        /* 
+           Store pointers to Dwarf_Frame_Op's in this list and
+           deallocate the structs that chain the Dwarf_Frame_Op's. */
+        curr_instr_item = head_instr_chain;
+        for (i = 0; i < instr_count; i++) {
+            *(head_instr_block + i) =
+                *(Dwarf_Frame_Op *) curr_instr_item->ch_item;
+            dealloc_instr_item = curr_instr_item;
+            curr_instr_item = curr_instr_item->ch_next;
+            dwarf_dealloc(dbg, dealloc_instr_item->ch_item,
+                          DW_DLA_FRAME_OP);
+            dwarf_dealloc(dbg, dealloc_instr_item, DW_DLA_CHAIN);
+        }
+        *ret_frame_instr = head_instr_block;
 
-	*returned_count = (Dwarf_Sword) instr_count;
+        *returned_count = (Dwarf_Sword) instr_count;
     } else {
-	*returned_count = 0;
+        *returned_count = 0;
     }
+    free(localregtab);
     return DW_DLV_OK;
-}
-
-static int
-qsort_compare(const void *elem1, const void *elem2)
-{
-    Dwarf_Fde fde1 = *(Dwarf_Fde *) elem1;
-    Dwarf_Fde fde2 = *(Dwarf_Fde *) elem2;
-    Dwarf_Addr addr1 = fde1->fd_initial_location;
-    Dwarf_Addr addr2 = fde2->fd_initial_location;
-
-    if (addr1 < addr2) {
-	return -1;
-    } else if (addr1 > addr2) {
-	return 1;
-    }
-    return 0;
+#undef ERROR_IF_REG_NUM_TOO_HIGH
+#undef SIMPLE_ERROR_RETURN
 }
 
-/*
- * This function expects as input a pointer to Dwarf_Debug (dbg) and a
- * a pointer to Cie. It finds the augmentation string and returns after 
- * setting *augmentation to point to it.
- */
-static int
-get_augmentation_string(Dwarf_Debug dbg,
-			Dwarf_Small * cie_ptr,
-			Dwarf_Unsigned cie_id_value,
-			Dwarf_Small ** augmentation,
-			Dwarf_Error * error)
+/*  Depending on version, either read the return address register
+    as a ubyte or as an leb number.
+    The form of this value changed for DWARF3.
+*/
+Dwarf_Unsigned
+_dwarf_get_return_address_reg(Dwarf_Small * frame_ptr,
+    int version, unsigned long *size)
 {
-    Dwarf_Unsigned cie_id;	/* must be min de_length_size bytes in 
-				   size */
-    Dwarf_Small version;
-    int local_length_size;
-    Dwarf_Unsigned length;
-    /*REFERENCED*/ /* Not used in this instance of the macro */
-    int local_extension_size;
+    Dwarf_Unsigned uvalue = 0;
+    Dwarf_Word leb128_length = 0;
 
-
-    /* READ_AREA_LENGTH updates cie_ptr for consumed bytes */
-    READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
-		     cie_ptr, local_length_size, local_extension_size);
-
+    if (version == 1) {
+        *size = 1;
+        uvalue = *(unsigned char *) frame_ptr;
+        return uvalue;
+    }
+    uvalue = _dwarf_decode_u_leb128(frame_ptr, &leb128_length);
+    *size = leb128_length;
+    return uvalue;
+}
 
 
-    /* Read the Cie Id field. */
-    READ_UNALIGNED(dbg, cie_id, Dwarf_Unsigned,
-		   cie_ptr, local_length_size);
-    SIGN_EXTEND(cie_id, local_length_size);
-    if (cie_id != cie_id_value) {
-	/* egcs-1.1.2 .eh_frame uses 0 as the distinguishing id. sgi
-	   uses -1 in .debug_frame. .eh_frame not quite identical to
-	   .debug_frame */
-	_dwarf_error(dbg, error, DW_DLE_FRAME_VERSION_BAD);
-	return (DW_DLV_ERROR);
-    }
-    cie_ptr += local_length_size;
-
-
-    /* Read the version. */
-    version = *(Dwarf_Small *) cie_ptr;
-    cie_ptr++;
-    if (version != DW_CIE_VERSION) {
-	_dwarf_error(dbg, error, DW_DLE_FRAME_VERSION_BAD);
-	return (DW_DLV_ERROR);
-    }
-
-    /* At this point, cie_ptr is pointing at the augmentation string. */
-    *augmentation = cie_ptr;
-    return DW_DLV_OK;
-}
-
+/* Trivial consumer function. 
+*/
 int
 dwarf_get_cie_of_fde(Dwarf_Fde fde,
-		     Dwarf_Cie * cie_returned, Dwarf_Error * error)
+    Dwarf_Cie * cie_returned, Dwarf_Error * error)
 {
     if (fde == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_FDE_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
+        return (DW_DLV_ERROR);
     }
 
     *cie_returned = fde->fd_cie;
@@ -824,12 +1085,28 @@
 
 }
 
+int dwarf_get_cie_index(
+    Dwarf_Cie cie,
+    Dwarf_Signed* index, 
+    Dwarf_Error* error )
+{
+    if( cie == NULL )
+    {
+        _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
+        return (DW_DLV_ERROR);
+    }
+
+    *index = cie->ci_index;
+    return (DW_DLV_OK);
+}
+
+
 /*
   For g++ .eh_frame fde and cie.
   the cie id is different as the
   definition of the cie_id in an fde
-	is the distance back from the address of the
-	value to the cie.
+        is the distance back from the address of the
+        value to the cie.
   Or 0 if this is a true cie.
   Non standard dwarf, designed this way to be
   convenient at run time for an allocated 
@@ -837,35 +1114,28 @@
 */
 int
 dwarf_get_fde_list_eh(Dwarf_Debug dbg,
-		      Dwarf_Cie ** cie_data,
-		      Dwarf_Signed * cie_element_count,
-		      Dwarf_Fde ** fde_data,
-		      Dwarf_Signed * fde_element_count,
-		      Dwarf_Error * error)
+    Dwarf_Cie ** cie_data,
+    Dwarf_Signed * cie_element_count,
+    Dwarf_Fde ** fde_data,
+    Dwarf_Signed * fde_element_count,
+    Dwarf_Error * error)
 {
-    int res;
-
-    res =
-        _dwarf_load_section(dbg,
-			    dbg->de_debug_frame_eh_gnu_index,
-			    &dbg->de_debug_frame_eh_gnu,
-			    error);
-
+    int res = _dwarf_load_section(dbg, &dbg->de_debug_frame_eh_gnu,error);
     if (res != DW_DLV_OK) {
-      return res;
+        return res;
     }
 
-    res =
-	__dwarf_get_fde_list_internal(dbg,
-				      cie_data,
-				      cie_element_count,
-				      fde_data,
-				      fde_element_count,
-				      dbg->de_debug_frame_eh_gnu,
-				      dbg->de_debug_frame_size_eh_gnu,
-				      /* cie_id_value */ 0,
-				      /* use_gnu_cie_calc= */ 1,
-				      error);
+    res = _dwarf_get_fde_list_internal(dbg,
+        cie_data,
+        cie_element_count,
+        fde_data,
+        fde_element_count,
+        dbg->de_debug_frame_eh_gnu.dss_data,
+        dbg->de_debug_frame_eh_gnu.dss_index,
+        dbg->de_debug_frame_eh_gnu.dss_size,
+        /* cie_id_value */ 0,
+        /* use_gnu_cie_calc= */ 1,
+        error);
     return res;
 }
 
@@ -879,1154 +1149,819 @@
 */
 int
 dwarf_get_fde_list(Dwarf_Debug dbg,
-		   Dwarf_Cie ** cie_data,
-		   Dwarf_Signed * cie_element_count,
-		   Dwarf_Fde ** fde_data,
-		   Dwarf_Signed * fde_element_count,
-		   Dwarf_Error * error)
+    Dwarf_Cie ** cie_data,
+    Dwarf_Signed * cie_element_count,
+    Dwarf_Fde ** fde_data,
+    Dwarf_Signed * fde_element_count,
+    Dwarf_Error * error)
 {
-    int res;
-
-    res =
-        _dwarf_load_section(dbg,
-			    dbg->de_debug_frame_index,
-			    &dbg->de_debug_frame,
-			    error);
-
+    int res = _dwarf_load_section(dbg, &dbg->de_debug_frame,error);
     if (res != DW_DLV_OK) {
-      return res;
+        return res;
     }
 
-    res =
-	__dwarf_get_fde_list_internal(dbg, cie_data,
-				      cie_element_count,
-				      fde_data,
-				      fde_element_count,
-				      dbg->de_debug_frame,
-				      dbg->de_debug_frame_size,
-				      DW_CIE_ID,
-				      /* use_gnu_cie_calc= */ 0,
-				      error);
+    res = _dwarf_get_fde_list_internal(dbg, cie_data,
+        cie_element_count,
+        fde_data,
+        fde_element_count,
+        dbg->de_debug_frame.dss_data,
+        dbg->de_debug_frame.dss_index,
+        dbg->de_debug_frame.dss_size,
+        DW_CIE_ID,
+        /* use_gnu_cie_calc= */ 0,
+        error);
+
     return res;
 }
 
-static int
-__dwarf_get_fde_list_internal(Dwarf_Debug dbg,
-			      Dwarf_Cie ** cie_data,
-			      Dwarf_Signed * cie_element_count,
-			      Dwarf_Fde ** fde_data,
-			      Dwarf_Signed * fde_element_count,
-			      Dwarf_Small * section_ptr,
-			      Dwarf_Unsigned section_length,
-			      Dwarf_Unsigned cie_id_value,
-			      int use_gnu_cie_calc, Dwarf_Error * error)
-{
-    /* Scans the debug_frame section. */
-    Dwarf_Small *frame_ptr = 0;
-
-    /* Points to the start of the current Fde or Cie. */
-    Dwarf_Small *start_frame_ptr = 0;
-
-    /* Points to the start of the augmented entries of Fde or Cie. */
-    Dwarf_Small *saved_frame_ptr = 0;
-
-    /* Fields for the current Cie being read. */
-    Dwarf_Unsigned length = 0;	/* READ_UNALIGNED needs min
-				   de_length_size byte dest */
-    Dwarf_Unsigned cie_base_offset = 0;	/* needs to be min
-					   de_length_size byte dest */
-    Dwarf_Unsigned cie_id;
-    Dwarf_Small version = 0;
-    Dwarf_Small *augmentation = 0;
-    Dwarf_Word code_alignment_factor = 4;
-    Dwarf_Sword data_alignment_factor = -1;
-    Dwarf_Small return_address_register = 31;
-    Dwarf_Word length_of_augmented_fields = 0;
-
-    /* 
-       New_cie points to the Cie being read, and head_cie_ptr and
-       cur_cie_ptr are used for chaining them up in sequence. */
-    Dwarf_Cie new_cie;
-    Dwarf_Cie head_cie_ptr = NULL;
-    Dwarf_Cie cur_cie_ptr;
-    Dwarf_Word cie_count = 0;
-
-    /* 
-       Points to a list of contiguous pointers to Dwarf_Cie
-       structures. */
-    Dwarf_Cie *cie_list_ptr;
-
-    /* Fields for the current Fde being read.  */
-    Dwarf_Addr initial_location;	/* must be min de_pointer_size
-					   bytes in size */
-    Dwarf_Addr address_range;	/* must be min de_pointer_size bytes in 
-				   size */
-
-    /* 
-       New_fde points to the current Fde being read, and head_fde_ptr
-       and cur_fde_ptr are used to chain them up. */
-    Dwarf_Fde new_fde;
-    Dwarf_Fde head_fde_ptr = NULL;
-    Dwarf_Fde cur_fde_ptr;
-    Dwarf_Word fde_count = 0;
-
-    /* 
-       Points to a list of contiguous pointers to Dwarf_Fde
-       structures. */
-    Dwarf_Fde *fde_list_ptr;
-
-    /* 
-       Is used to check the offset field in the Fde by checking for a
-       Cie at this address. */
-    Dwarf_Small *fde_cie_ptr;
-
-    Dwarf_Word leb128_length;
-    Dwarf_Word i, j;
-    int res;
-    Dwarf_Word last_cie_index;
-
-
-    Dwarf_Small *prev_augmentation_cie_ptr = 0;
-    Dwarf_Small *prev_augmentation_ptr = 0;
-
-
-    frame_ptr = section_ptr;
-
-    if (frame_ptr == 0) {
-	return DW_DLV_NO_ENTRY;
-    }
-
-    while (frame_ptr < section_ptr + section_length) {
-	Dwarf_Small *cie_ptr_addr = 0;
-	int local_extension_size = 0;
-	int local_length_size = 0;
-
-	start_frame_ptr = frame_ptr;
-
-	/* READ_AREA_LENGTH updates frame_ptr for consumed bytes */
-	READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
-			 frame_ptr, local_length_size,
-			 local_extension_size);
-
-
-	if (length % local_length_size != 0) {
-	    _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
-	    return (DW_DLV_ERROR);
-	}
-
-	if (length == 0) {
-	    /* nul bytes at end of section, seen at end of egcs
-	       eh_frame sections (in a.out). Take this as meaning no
-	       more CIE/FDE data. We should be very close to end of
-	       section. */
-	    break;
-	}
-
-	cie_ptr_addr = frame_ptr;
-	READ_UNALIGNED(dbg, cie_id, Dwarf_Unsigned,
-		       frame_ptr, local_length_size);
-	SIGN_EXTEND(cie_id, local_length_size);
-	cie_base_offset = cie_id;	/* if this is a CIE, this is
-					   ignored.  If it is an FDE,
-					   this is the section offset
-					   that allows us to get to the 
-					   cie of this fde. Save it for 
-					   the fde part of the 'if'
-					   below */
-
-	frame_ptr += local_length_size;
-
-	if (cie_id == cie_id_value) {
-	    /* egcs-1.1.2 .eh_frame uses 0 as the distinguishing id.
-	       sgi uses -1 (in .debug_frame). .eh_frame not quite
-	       identical to .debug_frame */
-
-
-
-	    /* this is a CIE, Common Information Entry: See the dwarf
-	       spec, section 6.4.1 */
-	    version = *(Dwarf_Small *) frame_ptr;
-	    frame_ptr++;
-	    if (version != DW_CIE_VERSION) {
-		_dwarf_error(dbg, error, DW_DLE_FRAME_VERSION_BAD);
-		return (DW_DLV_ERROR);
-	    }
-
-	    augmentation = frame_ptr;
-	    frame_ptr = frame_ptr + strlen((char *) frame_ptr) + 1;
-	    if ((strcmp((char *) augmentation,
-			DW_DEBUG_FRAME_AUGMENTER_STRING) == 0) ||
-		(strcmp((char *) augmentation, DW_EMPTY_STRING) == 0)) {
-
-		Dwarf_Unsigned lreg;
-
-		DECODE_LEB128_UWORD(frame_ptr, lreg)
-		    code_alignment_factor = (Dwarf_Word) lreg;
-
-
-		data_alignment_factor =
-		    (Dwarf_Sword) _dwarf_decode_s_leb128(frame_ptr,
-							 &leb128_length);
-
-		frame_ptr = frame_ptr + leb128_length;
-
-		return_address_register = *(Dwarf_Small *) frame_ptr;
-		if (return_address_register > DW_FRAME_LAST_REG_NUM) {
-		    _dwarf_error(dbg, error,
-				 DW_DLE_CIE_RET_ADDR_REG_ERROR);
-		    return (DW_DLV_ERROR);
-		}
-		frame_ptr++;
-	    } else if (augmentation[0] == 'z') {
-		/* The augmentation starts with a known prefix. See the
-		   dwarf_frame.h for details on the layout. */
-
-		Dwarf_Unsigned lreg;
-
-		DECODE_LEB128_UWORD(frame_ptr, lreg)
-		    code_alignment_factor = (Dwarf_Word) lreg;
-
-
-		data_alignment_factor =
-		    (Dwarf_Sword) _dwarf_decode_s_leb128(frame_ptr,
-							 &leb128_length);
-		frame_ptr = frame_ptr + leb128_length;
-
-		return_address_register = *(Dwarf_Small *) frame_ptr;
-		if (return_address_register > DW_FRAME_LAST_REG_NUM) {
-		    _dwarf_error(dbg, error,
-				 DW_DLE_CIE_RET_ADDR_REG_ERROR);
-		    return (DW_DLV_ERROR);
-		}
-		frame_ptr++;
-
-		/* Decode the length of augmented fields. */
-		DECODE_LEB128_UWORD(frame_ptr, lreg)
-		    length_of_augmented_fields = (Dwarf_Word) lreg;
-
-
-		/* set the frame_ptr to point at the instruction start. 
-		 */
-		frame_ptr += length_of_augmented_fields;
-	    } else if (0 == strcmp((const char *) augmentation, "eh")) {
-
-    	    	/*REFERENCED*/ /* Not used in this instance of the macro */
-		Dwarf_Unsigned exception_table_addr;
-
-		/* this is per egcs-1.1.2 as on RH 6.0 */
-		READ_UNALIGNED(dbg, exception_table_addr,
-			       Dwarf_Unsigned, frame_ptr,
-			       local_length_size);
-		frame_ptr += local_length_size;
-
-		code_alignment_factor =
-		    (Dwarf_Word) _dwarf_decode_s_leb128(frame_ptr,
-							&leb128_length);
-		frame_ptr = frame_ptr + leb128_length;
-
-
-		data_alignment_factor =
-		    (Dwarf_Sword) _dwarf_decode_s_leb128(frame_ptr,
-							 &leb128_length);
-
-		frame_ptr = frame_ptr + leb128_length;
-
-		return_address_register = *(Dwarf_Small *) frame_ptr;
-		if (return_address_register > DW_FRAME_LAST_REG_NUM) {
-		    _dwarf_error(dbg, error,
-				 DW_DLE_CIE_RET_ADDR_REG_ERROR);
-		    return (DW_DLV_ERROR);
-		}
-		frame_ptr++;
-
-	    } else {
-		/* We do not understand the augmentation string. No
-		   assumption can be made about any fields other than
-		   what we have already read. */
-		frame_ptr = start_frame_ptr + length + local_length_size
-		    + local_extension_size;
-		/* FIX -- What are the values of data_alignment_factor,
-		   code_alignement_factor, return_address_register and
-		   instruction start? They were clearly uninitalized in
-		   the previous version and I am leaving them the same
-		   way. */
-	    }
-
-	    new_cie = (Dwarf_Cie) _dwarf_get_alloc(dbg, DW_DLA_CIE, 1);
-	    if (new_cie == NULL) {
-		_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-		return (DW_DLV_ERROR);
-	    }
-
-	    new_cie->ci_initial_table = NULL;
-	    new_cie->ci_length = (Dwarf_Word) length;
-	    new_cie->ci_length_size = local_length_size;
-	    new_cie->ci_extension_size = local_extension_size;
-	    new_cie->ci_augmentation = (char *) augmentation;
-
-	    new_cie->ci_data_alignment_factor =
-		(Dwarf_Sbyte) data_alignment_factor;
-	    new_cie->ci_code_alignment_factor =
-		(Dwarf_Small) code_alignment_factor;
-	    new_cie->ci_return_address_register =
-		return_address_register;
-	    new_cie->ci_cie_start = start_frame_ptr;
-	    new_cie->ci_cie_instr_start = frame_ptr;
-	    new_cie->ci_dbg = dbg;
-
-	    cie_count++;
-	    if (head_cie_ptr == NULL)
-		head_cie_ptr = cur_cie_ptr = new_cie;
-	    else {
-		cur_cie_ptr->ci_next = new_cie;
-		cur_cie_ptr = new_cie;
-	    }
-	} else {
-
-
-
-	    /* this is an FDE, Frame Description Entry, see the Dwarf
-	       Spec, section 6.4.1 */
-	    Dwarf_Small *cieptr;
-
-	    Dwarf_Small *initloc = frame_ptr;
-	    Dwarf_Signed offset_into_exception_tables
-		/* must be min dwarf_sfixed in size */
-		= (Dwarf_Signed) DW_DLX_NO_EH_OFFSET;
-
-	    READ_UNALIGNED(dbg, initial_location, Dwarf_Addr,
-			   frame_ptr, dbg->de_pointer_size);
-	    frame_ptr += dbg->de_pointer_size;
-
-	    READ_UNALIGNED(dbg, address_range, Dwarf_Addr,
-			   frame_ptr, dbg->de_pointer_size);
-	    frame_ptr += dbg->de_pointer_size;
-	    /* Get the augmentation string from Cie to identify the
-	       layout of this Fde.  */
-	    if (use_gnu_cie_calc) {
-		/* cie_id value is offset, in section, of the cie_id
-		   itself, to use vm ptr of the value, less the value,
-		   to get to the cie itself. In addition, munge
-		   cie_base_offset to look *as if* it was from real
-		   dwarf. */
-		cieptr = cie_ptr_addr - cie_base_offset;
-		cie_base_offset = cieptr - section_ptr;
-	    } else {
-		/* Traditional dwarf section offset is in cie_id */
-		cieptr =
-		    (Dwarf_Small *) (section_ptr + cie_base_offset);
-	    }
-
-
-	    if (prev_augmentation_cie_ptr == cieptr &&
-		prev_augmentation_ptr != NULL) {
-		augmentation = prev_augmentation_ptr;
-	    } else {
-		res = get_augmentation_string(dbg,
-					      cieptr,
-					      cie_id_value,
-					      &augmentation, error);
-		if (res != DW_DLV_OK) {
-		    return res;
-		}
-		prev_augmentation_cie_ptr = cieptr;
-		prev_augmentation_ptr = augmentation;
-	    }
-	    if ((strcmp((char *) augmentation,
-			DW_DEBUG_FRAME_AUGMENTER_STRING) == 0) ||
-		(strcmp((char *) augmentation, DW_EMPTY_STRING) == 0)) {
-		/* We are pointing at the start of instructions. Do
-		   nothing. */
-	    } else if (augmentation[0] == 'z') {
-		Dwarf_Unsigned lreg;
-
-		DECODE_LEB128_UWORD(frame_ptr, lreg)
-		    length_of_augmented_fields = (Dwarf_Word) lreg;
-
-		saved_frame_ptr = frame_ptr;
-		if (strcmp((char *) augmentation,
-			   DW_CIE_AUGMENTER_STRING_V0) == 0) {
-		    /* The first word is an offset into execption
-		       tables. */
-		    /* ?? THis presumes that the offset is always 32
-		       bits */
-		    READ_UNALIGNED(dbg, offset_into_exception_tables,
-				   Dwarf_Addr, frame_ptr,
-				   sizeof(Dwarf_sfixed));
-		    SIGN_EXTEND(offset_into_exception_tables,
-				sizeof(Dwarf_sfixed));
-		    frame_ptr += local_length_size;
-		}
-		frame_ptr =
-		    saved_frame_ptr + length_of_augmented_fields;
-	    } else if (strcmp((const char *) augmentation, "eh") == 0) {
-		/* gnu eh fde case. we do not need to do anything */
-    	    	/*REFERENCED*/ /* Not used in this instance of the macro */
-		Dwarf_Unsigned exception_table_addr;
-
-		READ_UNALIGNED(dbg, exception_table_addr,
-			       Dwarf_Unsigned, frame_ptr,
-			       dbg->de_pointer_size);
-		frame_ptr += dbg->de_pointer_size;
-	    } else {
-		/* We do not understand the augmentation string. No
-		   assumption can be made about if the instructions is
-		   present. */
-		/* FIX -- The old code assumed that the instruction
-		   table starts at the location pointed to by
-		   frame_ptr, clearly incorrect. */
-	    }
-	    new_fde = (Dwarf_Fde) _dwarf_get_alloc(dbg, DW_DLA_FDE, 1);
-	    if (new_fde == NULL) {
-		_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-		return (DW_DLV_ERROR);
-	    }
-
-	    new_fde->fd_length = (Dwarf_Word) length;
-	    new_fde->fd_length_size = local_length_size;
-	    new_fde->fd_extension_size = local_extension_size;
-	    new_fde->fd_cie_offset = cie_base_offset;
-	    new_fde->fd_initial_location = initial_location;
-	    new_fde->fd_initial_loc_pos = initloc;
-	    new_fde->fd_address_range = address_range;
-	    new_fde->fd_fde_start = start_frame_ptr;
-	    new_fde->fd_fde_instr_start = frame_ptr;
-	    new_fde->fd_dbg = dbg;
-	    new_fde->fd_offset_into_exception_tables =
-		offset_into_exception_tables;
-
-	    fde_count++;
-	    if (head_fde_ptr == NULL)
-		head_fde_ptr = cur_fde_ptr = new_fde;
-	    else {
-		cur_fde_ptr->fd_next = new_fde;
-		cur_fde_ptr = new_fde;
-	    }
-	}
-
-	/* Skip over instructions to start of next frame. */
-	frame_ptr = start_frame_ptr + length + local_length_size +
-	    local_extension_size;
-    }
-
-    if (cie_count > 0) {
-	cie_list_ptr = (Dwarf_Cie *)
-	    _dwarf_get_alloc(dbg, DW_DLA_LIST, cie_count);
-    } else {
-	return (DW_DLV_NO_ENTRY);
-    }
-    if (cie_list_ptr == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
-    }
-    /* Return arguments. */
-    *cie_data = cie_list_ptr;
-    *cie_element_count = cie_count;
-    dbg->de_cie_data = cie_list_ptr;
-    dbg->de_cie_count = cie_count;
-
-    cur_cie_ptr = head_cie_ptr;
-    for (i = 0; i < cie_count; i++) {
-	*(cie_list_ptr + i) = cur_cie_ptr;
-	cur_cie_ptr = cur_cie_ptr->ci_next;
-    }
-
-    if (fde_count > 0) {
-	fde_list_ptr = (Dwarf_Fde *)
-	    _dwarf_get_alloc(dbg, DW_DLA_LIST, fde_count);
-    } else {
-	return (DW_DLV_NO_ENTRY);
-    }
-    if (fde_list_ptr == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
-    }
-    /* Return arguments. */
-    *fde_data = fde_list_ptr;
-    *fde_element_count = fde_count;
-    dbg->de_fde_data = fde_list_ptr;
-    dbg->de_fde_count = fde_count;
-    last_cie_index = 0;
-
-    cur_fde_ptr = head_fde_ptr;
-    for (i = 0; i < fde_count; i++) {
-	Dwarf_Sword new_cie_index = (Dwarf_Sword) cie_count;
-
-	*(fde_list_ptr + i) = cur_fde_ptr;
-
-	fde_cie_ptr = (Dwarf_Small *) (section_ptr +
-				       cur_fde_ptr->fd_cie_offset);
-
-
-	/* we assume that the next fde has the same cie as the ** last
-	   fde and resume the search where we left off */
-	for (j = last_cie_index; j < cie_count; j++) {
-	    Dwarf_Cie ciep = (Dwarf_Cie) * (cie_list_ptr + j);
-
-	    if (ciep->ci_cie_start == fde_cie_ptr) {
-		new_cie_index = (Dwarf_Sword) j;
-		break;
-	    }
-	}
-	/* did not find it above, start from 0 and try again */
-	if (new_cie_index == cie_count) {
-	    for (j = 0; j < last_cie_index; ++j) {
-		Dwarf_Cie ciep = (Dwarf_Cie) * (cie_list_ptr + j);
-
-		if (ciep->ci_cie_start == fde_cie_ptr) {
-		    new_cie_index = (Dwarf_Sword) j;
-		    break;
-		}
-	    }
-	}
-	j = new_cie_index;
-	last_cie_index = new_cie_index;
-	if (j == cie_count) {
-	    _dwarf_error(dbg, error, DW_DLE_NO_CIE_FOR_FDE);
-	    return (DW_DLV_ERROR);
-	} else {
-	    cur_fde_ptr->fd_cie_index = (Dwarf_Sword) j;
-	    cur_fde_ptr->fd_cie = *(cie_list_ptr + j);
-	}
-
-	cur_fde_ptr = cur_fde_ptr->fd_next;
-    }
-
-    /* sort the list by the address, so that dwarf_get_fde_at_pc() can
-       binary search this list. */
-    qsort((void *) fde_list_ptr, fde_count, sizeof(Dwarf_Ptr),
-	  qsort_compare);
-
-    return (DW_DLV_OK);
-}
 
 /*
    Only works on dwarf sections, not eh_frame
+   Given a Dwarf_Die, see if it has a
+   DW_AT_MIPS_fde attribute and if so use that
+   to get an fde offset.
+   Then create a Dwarf_Fde to return thru the ret_fde pointer.
+   Also creates a cie (pointed at from the Dwarf_Fde).
 */
 int
 dwarf_get_fde_for_die(Dwarf_Debug dbg,
-		      Dwarf_Die die,
-		      Dwarf_Fde * ret_fde, Dwarf_Error * error)
+    Dwarf_Die die,
+    Dwarf_Fde * ret_fde, Dwarf_Error * error)
 {
     Dwarf_Attribute attr;
-    Dwarf_Unsigned fde_offset;
-    Dwarf_Signed signdval;
-    Dwarf_Unsigned length;	/* must be min de_length_size bytes */
-    Dwarf_Signed signed_offset;	/* must be min de_length_size bytes */
-    Dwarf_Addr initial_location;	/* must be min de_pointer_size 
-					   bytes */
-    Dwarf_Addr address_range;	/* must be min de_pointer_size bytes */
-    Dwarf_Fde new_fde;
-    unsigned char *fde_ptr;
-    Dwarf_Small *saved_fde_ptr;
-    unsigned char *cie_ptr;
-    unsigned char *start_cie_ptr;
-    Dwarf_Cie new_cie;
+    Dwarf_Unsigned fde_offset = 0;
+    Dwarf_Signed signdval = 0;
+    Dwarf_Fde new_fde = 0;
+    unsigned char *fde_ptr = 0;
+    unsigned char *cie_ptr = 0;
+    Dwarf_Unsigned cie_id = 0;
 
     /* Fields for the current Cie being read. */
-    Dwarf_Small version;
-    Dwarf_Small *augmentation;
-    Dwarf_Word code_alignment_factor;
-    Dwarf_Sword data_alignment_factor;
-    Dwarf_Small return_address_register;
-    Dwarf_Word length_of_augmented_fields;
-    Dwarf_Signed offset_into_exception_tables =
-	(Dwarf_Signed) DW_DLX_NO_EH_OFFSET;
-    int res;
-    int resattr;
-    int sdatares;
-    int fde_local_extension_size = 0;
-    int fde_local_length_size = 0;
-    int cie_local_extension_size = 0;
-    int cie_local_length_size = 0;
+    int res = 0;
+    int resattr = 0;
+    int sdatares = 0;
 
-
-    Dwarf_Word leb128_length;
+    struct cie_fde_prefix_s prefix;
+    struct cie_fde_prefix_s prefix_c;
 
     if (die == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_DIE_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DIE_NULL);
+        return (DW_DLV_ERROR);
     }
 
     resattr = dwarf_attr(die, DW_AT_MIPS_fde, &attr, error);
     if (resattr != DW_DLV_OK) {
-	return resattr;
+        return resattr;
     }
 
     /* why is this formsdata? FIX */
     sdatares = dwarf_formsdata(attr, &signdval, error);
     if (sdatares != DW_DLV_OK) {
-	return sdatares;
+        return sdatares;
     }
 
-    res = 
-        _dwarf_load_section(dbg,
-			    dbg->de_debug_frame_index,
-			    &dbg->de_debug_frame,
-			    error);
+    res = _dwarf_load_section(dbg, &dbg->de_debug_frame,error);
     if (res != DW_DLV_OK) {
-      return res;
+        return res;
     }
 
     fde_offset = signdval;
-    fde_ptr = (dbg->de_debug_frame + fde_offset);
-
-    /* READ_AREA_LENGTH updates fde_ptr for consumed bytes */
-    READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
-		     fde_ptr, fde_local_length_size,
-		     fde_local_extension_size);
-
-
-    if (length % fde_local_length_size != 0) {
-	_dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
-	return (DW_DLV_ERROR);
-    }
-
-    READ_UNALIGNED(dbg, signed_offset, Dwarf_Signed,
-		   fde_ptr, fde_local_length_size);
-    SIGN_EXTEND(signed_offset, fde_local_length_size);
-    fde_ptr += fde_local_length_size;
-
-    READ_UNALIGNED(dbg, initial_location, Dwarf_Addr,
-		   fde_ptr, dbg->de_pointer_size);
-    fde_ptr += dbg->de_pointer_size;
-
-    READ_UNALIGNED(dbg, address_range, Dwarf_Addr,
-		   fde_ptr, dbg->de_pointer_size);
-    fde_ptr += dbg->de_pointer_size;
-
-    res = get_augmentation_string(dbg,
-				  (Dwarf_Small *) (dbg->de_debug_frame +
-						   signed_offset),
-				  DW_CIE_ID, &augmentation, error);
-    if (res != DW_DLV_OK) {
-	return res;
-    }
-
-    if ((strcmp((char *) augmentation, DW_DEBUG_FRAME_AUGMENTER_STRING)
-	 == 0) ||
-	(strcmp((char *) augmentation, DW_EMPTY_STRING) == 0)) {
-	/* Do nothing. The fde_ptr is pointing at start of
-	   instructions. */
-    } else if (augmentation[0] == 'z') {
-	/* The augmentation starts with a known prefix. See the
-	   dwarf_frame.h for details on the layout. */
-
-	Dwarf_Unsigned lreg;
-
-	DECODE_LEB128_UWORD(fde_ptr, lreg)
-	    length_of_augmented_fields = (Dwarf_Word) lreg;
-
-	saved_fde_ptr = fde_ptr;
-	if (strcmp((char *) augmentation, DW_CIE_AUGMENTER_STRING_V0) ==
-	    0) {
-	    /* The first word is an offset into execption tables. */
-	    READ_UNALIGNED(dbg, offset_into_exception_tables,
-			   Dwarf_Signed, fde_ptr, sizeof(Dwarf_sfixed));
-	    SIGN_EXTEND(offset_into_exception_tables,
-			sizeof(Dwarf_sfixed));
-	    fde_ptr += sizeof(Dwarf_sfixed);
-	}
-	fde_ptr = saved_fde_ptr + length_of_augmented_fields;
-    } else {
-	/* We do not understand the augmentation string. No assumption
-	   can be made about if the instructions is present. */
-	/* FIX -- The old code assumed that the instruction table
-	   starts at location pointed to by fde_ptr, clearly incorrect. 
-	 */
-    }
-
-    new_fde = (Dwarf_Fde) _dwarf_get_alloc(dbg, DW_DLA_FDE, 1);
-    if (new_fde == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
-    }
-
-    new_fde->fd_length = (Dwarf_Word) length;
-    new_fde->fd_length_size = fde_local_length_size;
-    new_fde->fd_extension_size = fde_local_extension_size;
-    new_fde->fd_cie_offset = signed_offset;
-    new_fde->fd_initial_location = initial_location;
-    new_fde->fd_address_range = address_range;
-    new_fde->fd_fde_start = dbg->de_debug_frame + fde_offset;
-    new_fde->fd_fde_instr_start = (Dwarf_Small *) fde_ptr;
-    new_fde->fd_dbg = dbg;
-    new_fde->fd_offset_into_exception_tables =
-	offset_into_exception_tables;
-
-    /* now read the cie corresponding to the fde */
-    cie_ptr = (dbg->de_debug_frame + signed_offset);
-    start_cie_ptr = cie_ptr;
-
-    /* READ_AREA_LENGTH updates cie_ptr for consumed bytes */
-    READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
-		     cie_ptr, cie_local_length_size,
-		     cie_local_extension_size);
+    fde_ptr = (dbg->de_debug_frame.dss_data + fde_offset);
 
 
-    if (length % cie_local_length_size != 0) {
-	_dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
-	return (DW_DLV_ERROR);
+    /* First read in the 'common prefix' to figure out what * we are to 
+       do with this entry. */
+    memset(&prefix_c, 0, sizeof(prefix_c));
+    memset(&prefix, 0, sizeof(prefix));
+    res = dwarf_read_cie_fde_prefix(dbg, fde_ptr,
+        dbg->de_debug_frame.dss_data,
+        dbg->de_debug_frame.dss_index,
+        dbg->de_debug_frame.dss_size, 
+        &prefix,
+        error);
+    if (res == DW_DLV_ERROR) {
+        return res;
     }
-
-    READ_UNALIGNED(dbg, signed_offset, Dwarf_Signed,
-		   cie_ptr, cie_local_length_size);
-    SIGN_EXTEND(signed_offset, cie_local_length_size);
-    cie_ptr += cie_local_length_size;
-
-    if (signed_offset == DW_CIE_ID) {
-
-	version = *(Dwarf_Small *) cie_ptr;
-	cie_ptr++;
-	if (version != DW_CIE_VERSION) {
-	    _dwarf_error(dbg, error, DW_DLE_FRAME_VERSION_BAD);
-	    return (DW_DLV_ERROR);
-	}
-
-	augmentation = cie_ptr;
-	cie_ptr = cie_ptr + strlen((char *) cie_ptr) + 1;
-	if ((strcmp((char *) augmentation,
-		    DW_DEBUG_FRAME_AUGMENTER_STRING) == 0) ||
-	    (strcmp((char *) augmentation, DW_EMPTY_STRING) == 0)) {
-
-	    Dwarf_Unsigned lreg;
-
-	    DECODE_LEB128_UWORD(cie_ptr, lreg)
-		code_alignment_factor = (Dwarf_Word) lreg;
-
-
-	    data_alignment_factor = (Dwarf_Sword)
-		_dwarf_decode_s_leb128(cie_ptr, &leb128_length);
-	    cie_ptr = cie_ptr + leb128_length;
-
-	    return_address_register = *(Dwarf_Small *) cie_ptr;
-	    if (return_address_register > DW_FRAME_LAST_REG_NUM) {
-		_dwarf_error(dbg, error, DW_DLE_CIE_RET_ADDR_REG_ERROR);
-		return (DW_DLV_ERROR);
-	    }
-	    cie_ptr++;
-	} else if (augmentation[0] == 'z') {
-	    /* The augmentation starts with a known prefix. We can
-	       asssume that the first field is the length of the
-	       augmented fields. */
-
-	    Dwarf_Unsigned lreg;
-
-	    DECODE_LEB128_UWORD(cie_ptr, lreg)
-		code_alignment_factor = (Dwarf_Word) lreg;
-	    data_alignment_factor = (Dwarf_Sword)
-		_dwarf_decode_s_leb128(cie_ptr, &leb128_length);
-	    cie_ptr = cie_ptr + leb128_length;
+    if (res == DW_DLV_NO_ENTRY)
+        return res;
+    fde_ptr = prefix.cf_addr_after_prefix;
+    cie_id = prefix.cf_cie_id;
+    /* Pass NULL, not section pointer, for 3rd argument. 
+       de_debug_frame.dss_data has no eh_frame relevance. */
+    res = dwarf_create_fde_from_after_start(dbg, &prefix,
+        (Dwarf_Small *) NULL,
+        fde_ptr,
+        /* use_gnu_cie_calc= */ 0,
+        /* Dwarf_Cie = */ 0,
+        &new_fde, error);
+    if (res == DW_DLV_ERROR) {
+        return res;
+    } else if (res == DW_DLV_NO_ENTRY) {
+        return res;
+    }
+    /* DW_DLV_OK */
 
-	    return_address_register = *(Dwarf_Small *) cie_ptr;
-	    if (return_address_register > DW_FRAME_LAST_REG_NUM) {
-		_dwarf_error(dbg, error, DW_DLE_CIE_RET_ADDR_REG_ERROR);
-		return (DW_DLV_ERROR);
-	    }
-	    cie_ptr++;
-	    /* Decode the length of augmented fields. */
-	    DECODE_LEB128_UWORD(cie_ptr, lreg)
-		length_of_augmented_fields = (Dwarf_Word) lreg;
-
-	    /* set the cie_ptr to point at the instruction start. */
-	    cie_ptr += length_of_augmented_fields;
-	} else if (strcmp((const char *) augmentation, "eh") == 0) {
-	    Dwarf_Unsigned lreg;
+    /* now read the cie corresponding to the fde */
+    cie_ptr = new_fde->fd_section_ptr + cie_id;
+    res = dwarf_read_cie_fde_prefix(dbg, cie_ptr,
+        dbg->de_debug_frame.dss_data,
+        dbg->de_debug_frame.dss_index,
+        dbg->de_debug_frame.dss_size,
+        &prefix_c, error);
+    if (res == DW_DLV_ERROR) {
+        return res;
+    }
+    if (res == DW_DLV_NO_ENTRY)
+        return res;
 
-	    DECODE_LEB128_UWORD(cie_ptr, lreg)
-		code_alignment_factor = (Dwarf_Word) lreg;
-
+    cie_ptr = prefix_c.cf_addr_after_prefix;
+    cie_id = prefix_c.cf_cie_id;
 
-	    data_alignment_factor = (Dwarf_Sword)
-		_dwarf_decode_s_leb128(cie_ptr, &leb128_length);
-	    cie_ptr = cie_ptr + leb128_length;
-
-	    return_address_register = *(Dwarf_Small *) cie_ptr;
-	    if (return_address_register > DW_FRAME_LAST_REG_NUM) {
-		_dwarf_error(dbg, error, DW_DLE_CIE_RET_ADDR_REG_ERROR);
-		return (DW_DLV_ERROR);
-	    }
-	    cie_ptr++;
+    if (cie_id == DW_CIE_ID) {
+        int res2 = 0;
+        Dwarf_Cie new_cie = 0;
 
-	} else {
-	    /* We do not understand the augmentation string. No
-	       assumption can be made about any fields other than what
-	       we have already read. */
-	    cie_ptr = start_cie_ptr + length + cie_local_length_size
-		+ cie_local_extension_size;
-	    /* FIX -- What are the values of data_alignment_factor,
-	       code_alignement_factor, return_address_register and
-	       instruction start? They were clearly uninitalized in
-	       the previous version and I am leaving them the same way. 
-	     */
-	}
-
-	new_cie = (Dwarf_Cie) _dwarf_get_alloc(dbg, DW_DLA_CIE, 1);
-	if (new_cie == NULL) {
-	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	    return (DW_DLV_ERROR);
-	}
-
-	new_cie->ci_initial_table = NULL;
-	new_cie->ci_length = (Dwarf_Word) length;
-	new_cie->ci_length_size = cie_local_length_size;
-	new_cie->ci_extension_size = cie_local_extension_size;
-	new_cie->ci_augmentation = (char *) augmentation;
-	new_cie->ci_data_alignment_factor =
-	    (Dwarf_Sbyte) data_alignment_factor;
-	new_cie->ci_code_alignment_factor =
-	    (Dwarf_Small) code_alignment_factor;
-	new_cie->ci_return_address_register = return_address_register;
-	new_cie->ci_cie_start = start_cie_ptr;
-	new_cie->ci_cie_instr_start = cie_ptr;
-	new_cie->ci_dbg = dbg;
+        /* Pass NULL, not section pointer, for 3rd argument.
+           de_debug_frame.dss_data has no eh_frame relevance. */
+        res2 = dwarf_create_cie_from_after_start(dbg,
+            &prefix_c,
+            (Dwarf_Small *) NULL,
+            cie_ptr,
+            /* cie_count= */ 0,
+            /* use_gnu_cie_calc= */
+            0, &new_cie, error);
+        if (res2 == DW_DLV_ERROR) {
+            dwarf_dealloc(dbg, new_fde, DW_DLA_FDE);
+            return res;
+        } else if (res2 == DW_DLV_NO_ENTRY) {
+            dwarf_dealloc(dbg, new_fde, DW_DLA_FDE);
+            return res;
+        }
+        new_fde->fd_cie = new_cie;
     } else {
-	_dwarf_error(dbg, error, DW_DLE_NO_CIE_FOR_FDE);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_NO_CIE_FOR_FDE);
+        return (DW_DLV_ERROR);
     }
-    new_fde->fd_cie = new_cie;
 
     *ret_fde = new_fde;
     return DW_DLV_OK;
 }
 
-
+/* A dwarf consumer operation, see the consumer library documentation.
+*/
 int
 dwarf_get_fde_range(Dwarf_Fde fde,
-		    Dwarf_Addr * low_pc,
-		    Dwarf_Unsigned * func_length,
-		    Dwarf_Ptr * fde_bytes,
-		    Dwarf_Unsigned * fde_byte_length,
-		    Dwarf_Off * cie_offset,
-		    Dwarf_Signed * cie_index,
-		    Dwarf_Off * fde_offset, Dwarf_Error * error)
+    Dwarf_Addr * low_pc,
+    Dwarf_Unsigned * func_length,
+    Dwarf_Ptr * fde_bytes,
+    Dwarf_Unsigned * fde_byte_length,
+    Dwarf_Off * cie_offset,
+    Dwarf_Signed * cie_index,
+    Dwarf_Off * fde_offset, Dwarf_Error * error)
 {
-    int res;
     Dwarf_Debug dbg;
 
     if (fde == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_FDE_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
+        return (DW_DLV_ERROR);
     }
 
     dbg = fde->fd_dbg;
     if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
 
-    res =
-        _dwarf_load_section(dbg,
-			    dbg->de_debug_frame_index,
-			    &dbg->de_debug_frame,
-			    error);
-    if (res != DW_DLV_OK) {
-        return res;
-    }
+
+    /* We have always already done the section load here, so no need to 
+       load the section. We did the section load in order to create the 
+       Dwarf_Fde pointer passed in here. */
+
 
     if (low_pc != NULL)
-	*low_pc = fde->fd_initial_location;
+        *low_pc = fde->fd_initial_location;
     if (func_length != NULL)
-	*func_length = fde->fd_address_range;
+        *func_length = fde->fd_address_range;
     if (fde_bytes != NULL)
-	*fde_bytes = fde->fd_fde_start;
+        *fde_bytes = fde->fd_fde_start;
     if (fde_byte_length != NULL)
-	*fde_byte_length = fde->fd_length;
+        *fde_byte_length = fde->fd_length;
     if (cie_offset != NULL)
-	*cie_offset = fde->fd_cie_offset;
+        *cie_offset = fde->fd_cie_offset;
     if (cie_index != NULL)
-	*cie_index = fde->fd_cie_index;
+        *cie_index = fde->fd_cie_index;
     if (fde_offset != NULL)
-	*fde_offset = fde->fd_fde_start - dbg->de_debug_frame;
+        *fde_offset = fde->fd_fde_start - fde->fd_section_ptr;
 
     return DW_DLV_OK;
 }
 
+/* IRIX specific function.   The exception tables
+   have C++ destructor information and are
+   at present undocumented.  */
 int
 dwarf_get_fde_exception_info(Dwarf_Fde fde,
-			     Dwarf_Signed *
-			     offset_into_exception_tables,
-			     Dwarf_Error * error)
+    Dwarf_Signed *
+    offset_into_exception_tables,
+    Dwarf_Error * error)
 {
     Dwarf_Debug dbg;
 
     dbg = fde->fd_dbg;
     if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
     *offset_into_exception_tables =
-	fde->fd_offset_into_exception_tables;
+        fde->fd_offset_into_exception_tables;
     return DW_DLV_OK;
 }
 
 
+/* A consumer code function.
+   Given a CIE pointer, return the normal CIE data thru
+   pointers.
+   Special augmentation data is not returned here.
+*/
 int
 dwarf_get_cie_info(Dwarf_Cie cie,
-		   Dwarf_Unsigned * bytes_in_cie,
-		   Dwarf_Small * version,
-		   char **augmenter,
-		   Dwarf_Unsigned * code_alignment_factor,
-		   Dwarf_Signed * data_alignment_factor,
-		   Dwarf_Half * return_address_register,
-		   Dwarf_Ptr * initial_instructions,
-		   Dwarf_Unsigned * initial_instructions_length,
-		   Dwarf_Error * error)
+    Dwarf_Unsigned * bytes_in_cie,
+    Dwarf_Small * ptr_to_version,
+    char **augmenter,
+    Dwarf_Unsigned * code_alignment_factor,
+    Dwarf_Signed * data_alignment_factor,
+    Dwarf_Half * return_address_register,
+    Dwarf_Ptr * initial_instructions,
+    Dwarf_Unsigned * initial_instructions_length,
+    Dwarf_Error * error)
 {
     Dwarf_Debug dbg;
 
     if (cie == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_CIE_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
+        return (DW_DLV_ERROR);
     }
 
     dbg = cie->ci_dbg;
     if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_CIE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_CIE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
 
-    if (version != NULL)
-	*version = DW_CIE_VERSION;
+    if (ptr_to_version != NULL)
+        *ptr_to_version = cie->ci_cie_version_number;
     if (augmenter != NULL)
-	*augmenter = cie->ci_augmentation;
+        *augmenter = cie->ci_augmentation;
     if (code_alignment_factor != NULL)
-	*code_alignment_factor = cie->ci_code_alignment_factor;
+        *code_alignment_factor = cie->ci_code_alignment_factor;
     if (data_alignment_factor != NULL)
-	*data_alignment_factor = cie->ci_data_alignment_factor;
+        *data_alignment_factor = cie->ci_data_alignment_factor;
     if (return_address_register != NULL)
-	*return_address_register = cie->ci_return_address_register;
+        *return_address_register = cie->ci_return_address_register;
     if (initial_instructions != NULL)
-	*initial_instructions = cie->ci_cie_instr_start;
+        *initial_instructions = cie->ci_cie_instr_start;
     if (initial_instructions_length != NULL) {
-	*initial_instructions_length = cie->ci_length +
-	    cie->ci_length_size +
-	    cie->ci_extension_size -
-	    (cie->ci_cie_instr_start - cie->ci_cie_start);
+        *initial_instructions_length = cie->ci_length +
+            cie->ci_length_size +
+            cie->ci_extension_size -
+            (cie->ci_cie_instr_start - cie->ci_cie_start);
 
     }
     *bytes_in_cie = (cie->ci_length);
     return (DW_DLV_OK);
 }
 
+/* Return the register rules for all registers at a given pc. 
+*/
 static int
 _dwarf_get_fde_info_for_a_pc_row(Dwarf_Fde fde,
-				 Dwarf_Addr pc_requested,
-				 Dwarf_Frame table, Dwarf_Error * error)
-/* Return the register rules for all registers at a given pc. */
+    Dwarf_Addr pc_requested,
+    Dwarf_Frame table,
+    Dwarf_Half cfa_reg_col_num,
+    Dwarf_Error * error)
 {
-    Dwarf_Debug dbg;
-    Dwarf_Cie cie;
-    Dwarf_Sword i;
-    int dw_err;
-    Dwarf_Sword icount;
-    int res;
+    Dwarf_Debug dbg = 0;
+    Dwarf_Cie cie = 0;
+    int dw_err = 0;
+    Dwarf_Sword icount = 0;
+    int res = 0;
 
     if (fde == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_FDE_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
+        return (DW_DLV_ERROR);
     }
 
     dbg = fde->fd_dbg;
     if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
 
     if (pc_requested < fde->fd_initial_location ||
-	pc_requested >=
-	fde->fd_initial_location + fde->fd_address_range) {
-	_dwarf_error(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
-	return (DW_DLV_ERROR);
+        pc_requested >=
+        fde->fd_initial_location + fde->fd_address_range) {
+        _dwarf_error(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
+        return (DW_DLV_ERROR);
     }
 
     cie = fde->fd_cie;
     if (cie->ci_initial_table == NULL) {
-	cie->ci_initial_table = _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
-	if (cie->ci_initial_table == NULL) {
-	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	    return (DW_DLV_ERROR);
-	}
-	for (i = 0; i < DW_FRAME_LAST_REG_NUM; i++) {
-	    cie->ci_initial_table->fr_reg[i].ru_is_off = 0;
-	    cie->ci_initial_table->fr_reg[i].ru_register =
-		DW_FRAME_SAME_VAL;
-	    cie->ci_initial_table->fr_reg[i].ru_offset = 0;
-	}
+        cie->ci_initial_table = _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
 
-	res = _dwarf_exec_frame_instr( /* make_instr= */ false,
-				      /* ret_frame_instr= */ NULL,
-				      /* search_pc */ false,
-				      /* search_pc_val */ 0,
-				      /* location */ 0,
-				      cie->ci_cie_instr_start,
-				      cie->ci_cie_instr_start +
-				      (cie->ci_length +
-				       cie->ci_length_size +
-				       cie->ci_extension_size -
-				       (cie->ci_cie_instr_start -
-					cie->ci_cie_start)),
-				      cie->ci_initial_table, cie, dbg,
-				      &icount, &dw_err);
-	if (res == DW_DLV_ERROR) {
-	    _dwarf_error(dbg, error, dw_err);
-	    return (res);
-	} else if (res == DW_DLV_NO_ENTRY) {
-	    return res;
-	}
+        if (cie->ci_initial_table == NULL) {
+            _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+            return (DW_DLV_ERROR);
+        }
+        _dwarf_init_regrule_table(cie->ci_initial_table->fr_reg,
+            dbg->de_frame_reg_rules_entry_count,
+            dbg->de_frame_rule_initial_value);
+        _dwarf_init_regrule_table(&cie->ci_initial_table->fr_cfa_rule,
+            1, dbg->de_frame_rule_initial_value);
+        res = _dwarf_exec_frame_instr( /* make_instr= */ false,
+            /* ret_frame_instr= */ NULL,
+            /* search_pc */ false,
+            /* search_pc_val */ 0,
+            /* location */ 0,
+            cie->ci_cie_instr_start,
+            cie->ci_cie_instr_start + (cie->ci_length +
+                cie->ci_length_size +
+                cie->ci_extension_size -
+                (cie->ci_cie_instr_start -
+                cie->ci_cie_start)),
+            cie->ci_initial_table, cie, dbg,
+            cfa_reg_col_num, &icount,
+            &dw_err);
+        if (res == DW_DLV_ERROR) {
+            _dwarf_error(dbg, error, dw_err);
+            return (res);
+        } else if (res == DW_DLV_NO_ENTRY) {
+            return res;
+        }
     }
 
-    res = _dwarf_exec_frame_instr( /* make_instr= */ false,
-				  /* ret_frame_instr= */ NULL,
-				  /* search_pc */ true,
-				  /* search_pc_val */ pc_requested,
-				  fde->fd_initial_location,
-				  fde->fd_fde_instr_start,
-				  fde->fd_fde_start + fde->fd_length +
-				  fde->fd_length_size +
-				  fde->fd_extension_size,
-				  table, cie, dbg, &icount, &dw_err);
+    {
+        Dwarf_Small *instr_end = fde->fd_fde_instr_start +
+            fde->fd_length +
+            fde->fd_length_size +
+            fde->fd_extension_size - (fde->fd_fde_instr_start -
+                                      fde->fd_fde_start);
+
+        res = _dwarf_exec_frame_instr( /* make_instr= */ false,
+            /* ret_frame_instr= */ NULL,
+            /* search_pc */ true,
+            /* search_pc_val */ pc_requested,
+            fde->fd_initial_location,
+            fde->fd_fde_instr_start,
+            instr_end,
+            table,
+            cie, dbg,
+            cfa_reg_col_num, &icount,
+            &dw_err);
+    }
     if (res == DW_DLV_ERROR) {
-	_dwarf_error(dbg, error, dw_err);
-	return (res);
+        _dwarf_error(dbg, error, dw_err);
+        return (res);
     } else if (res == DW_DLV_NO_ENTRY) {
-	return res;
+        return res;
     }
 
     return DW_DLV_OK;
 }
 
+/* A consumer call for efficiently getting the register info
+   for all registers in one call.
+
+   The output table rules array is size DW_REG_TABLE_SIZE.
+   The frame info  rules array in fde_table is of size
+   DW_REG_TABLE_SIZE too.
+
+   This interface  really only works well with MIPS/IRIX
+   where DW_FRAME_CFA_COL is zero (in that case it's safe).
+
+   It is also restricted to the case  where
+   DW_REG_TABLE_SIZE == DW_FRAME_LAST_REG_NUM  ==
+   dbg->de_frame_reg_rules_entry_count (true for MIPS/IRIX).
+   If this condition is not met calling this routine can result in
+   incorrect output or in memory corruption.
+
+   It is much better to use dwarf_get_fde_info_for_all_regs3()
+   instead of this interface.
+*/
 int
 dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde,
-				Dwarf_Addr pc_requested,
-				Dwarf_Regtable * reg_table,
-				Dwarf_Addr * row_pc,
-				Dwarf_Error * error)
+    Dwarf_Addr pc_requested,
+    Dwarf_Regtable * reg_table,
+    Dwarf_Addr * row_pc,
+    Dwarf_Error * error)
 {
 
+    /* Table size: DW_REG_TABLE_SIZE */
     struct Dwarf_Frame_s fde_table;
-    Dwarf_Sword i;
-    int res;
+    Dwarf_Sword i = 0;
+    struct Dwarf_Reg_Rule_s *rule = NULL;
+    struct Dwarf_Regtable_Entry_s *out_rule = NULL;
+    int res = 0;
+    Dwarf_Debug dbg = 0;
+
+    /* For this interface the size is fixed at compile time. */
+    int output_table_real_data_size = DW_REG_TABLE_SIZE;
+
+    FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
+
+    res = dwarf_initialize_fde_table(dbg, &fde_table,
+        output_table_real_data_size,
+        error);
+    if (res != DW_DLV_OK)
+        return res;
 
     /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks 
      */
     res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested,
-					   &fde_table, error);
+        &fde_table, dbg->de_frame_cfa_col_number, error);
     if (res != DW_DLV_OK) {
-	return res;
+        dwarf_free_fde_table(&fde_table);
+        return res;
     }
 
-    for (i = 0; i < DW_REG_TABLE_SIZE; i++) {
-	reg_table->rules[i].dw_offset_relevant =
-	    fde_table.fr_reg[i].ru_is_off;
-	reg_table->rules[i].dw_regnum = fde_table.fr_reg[i].ru_register;
-	reg_table->rules[i].dw_offset = fde_table.fr_reg[i].ru_offset;
+    out_rule = &reg_table->rules[0];
+    rule = &fde_table.fr_reg[0];
+    for (i = 0; i < output_table_real_data_size;
+         i++, ++out_rule, ++rule) {
+        out_rule->dw_offset_relevant = rule->ru_is_off;
+        out_rule->dw_value_type = rule->ru_value_type;
+        out_rule->dw_regnum = rule->ru_register;
+        out_rule->dw_offset = rule->ru_offset_or_block_len;
+    }
+    for (; i < DW_REG_TABLE_SIZE; ++i, ++out_rule) {
+        out_rule->dw_offset_relevant = 0;
+        out_rule->dw_value_type = DW_EXPR_OFFSET;
+        out_rule->dw_regnum = dbg->de_frame_undefined_value_number;
+        out_rule->dw_offset = 0;
+    }
+
+    /* The test is just in case it's not inside the table. For non-MIPS 
+       it could be outside the table and that is just fine, it was
+       really a mistake to put it in the table in 1993.  */
+    /* CONSTCOND */
+    if (dbg->de_frame_cfa_col_number < DW_REG_TABLE_SIZE) {
+        out_rule = &reg_table->rules[dbg->de_frame_cfa_col_number];
+        out_rule->dw_offset_relevant = fde_table.fr_cfa_rule.ru_is_off;
+        out_rule->dw_value_type = fde_table.fr_cfa_rule.ru_value_type;
+        out_rule->dw_regnum = fde_table.fr_cfa_rule.ru_register;
+        out_rule->dw_offset =
+            fde_table.fr_cfa_rule.ru_offset_or_block_len;
     }
 
     if (row_pc != NULL)
-	*row_pc = fde_table.fr_loc;
+        *row_pc = fde_table.fr_loc;
+    dwarf_free_fde_table(&fde_table);
+    return DW_DLV_OK;
+}
+
+/* A consumer call for efficiently getting the register info
+   for all registers in one call.
+
+   The output table rules array is size output_table_real_data_size.
+   (normally  DW_REG_TABLE_SIZE).
+   The frame info  rules array in fde_table is normally of size
+   DW_FRAME_LAST_REG_NUM.
+*/
+int
+dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde,
+    Dwarf_Addr pc_requested,
+    Dwarf_Regtable3 * reg_table,
+    Dwarf_Addr * row_pc,
+    Dwarf_Error * error)
+{
+
+    struct Dwarf_Frame_s fde_table;
+    Dwarf_Sword i = 0;
+    int res = 0;
+    struct Dwarf_Reg_Rule_s *rule = NULL;
+    struct Dwarf_Regtable_Entry3_s *out_rule = NULL;
+    Dwarf_Debug dbg = 0;
+    int output_table_real_data_size = reg_table->rt3_reg_table_size;
+
+    FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
+
+    output_table_real_data_size =
+        MIN(output_table_real_data_size,
+            dbg->de_frame_reg_rules_entry_count);
+
+    res = dwarf_initialize_fde_table(dbg, &fde_table,
+       output_table_real_data_size,
+       error);
 
+    /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks 
+     */
+    res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested,
+        &fde_table,
+        dbg->de_frame_cfa_col_number,
+        error);
+    if (res != DW_DLV_OK) {
+        dwarf_free_fde_table(&fde_table);
+        return res;
+    }
+
+    out_rule = &reg_table->rt3_rules[0];
+    rule = &fde_table.fr_reg[0];
+    for (i = 0; i < output_table_real_data_size;
+         i++, ++out_rule, ++rule) {
+        out_rule->dw_offset_relevant = rule->ru_is_off;
+        out_rule->dw_value_type = rule->ru_value_type;
+        out_rule->dw_regnum = rule->ru_register;
+        out_rule->dw_offset_or_block_len = rule->ru_offset_or_block_len;
+        out_rule->dw_block_ptr = rule->ru_block;
+    }
+    for (; i < reg_table->rt3_reg_table_size; i++, ++out_rule) {
+        out_rule->dw_offset_relevant = 0;
+        out_rule->dw_value_type = DW_EXPR_OFFSET;
+        out_rule->dw_regnum = dbg->de_frame_undefined_value_number;
+        out_rule->dw_offset_or_block_len = 0;
+        out_rule->dw_block_ptr = 0;
+    }
+    reg_table->rt3_cfa_rule.dw_offset_relevant =
+        fde_table.fr_cfa_rule.ru_is_off;
+    reg_table->rt3_cfa_rule.dw_value_type =
+        fde_table.fr_cfa_rule.ru_value_type;
+    reg_table->rt3_cfa_rule.dw_regnum =
+        fde_table.fr_cfa_rule.ru_register;
+    reg_table->rt3_cfa_rule.dw_offset_or_block_len =
+        fde_table.fr_cfa_rule.ru_offset_or_block_len;
+    reg_table->rt3_cfa_rule.dw_block_ptr =
+        fde_table.fr_cfa_rule.ru_block;
+
+    if (row_pc != NULL)
+        *row_pc = fde_table.fr_loc;
+
+    dwarf_free_fde_table(&fde_table);
     return DW_DLV_OK;
 }
 
 
+/* Gets the register info for a single register at a given PC value
+   for the FDE specified.
+   
+   This is the old MIPS interface and should no longer be used.
+   Use dwarf_get_fde_info_for_reg3() instead.
+*/
 int
 dwarf_get_fde_info_for_reg(Dwarf_Fde fde,
-			   Dwarf_Half table_column,
-			   Dwarf_Addr pc_requested,
-			   Dwarf_Signed * offset_relevant,
-			   Dwarf_Signed * register_num,
-			   Dwarf_Signed * offset,
-			   Dwarf_Addr * row_pc, Dwarf_Error * error)
+    Dwarf_Half table_column,
+    Dwarf_Addr pc_requested,
+    Dwarf_Signed * offset_relevant,
+    Dwarf_Signed * register_num,
+    Dwarf_Signed * offset,
+    Dwarf_Addr * row_pc, Dwarf_Error * error)
 {
     struct Dwarf_Frame_s fde_table;
-    int res;
+    int res = DW_DLV_ERROR;
+    Dwarf_Debug dbg = 0;
+    int output_table_real_data_size = 0;
 
+    FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
+    output_table_real_data_size = dbg->de_frame_reg_rules_entry_count;
 
-    if (table_column > DW_FRAME_LAST_REG_NUM) {
-	_dwarf_error(NULL, error, DW_DLE_FRAME_TABLE_COL_BAD);
-	return (DW_DLV_ERROR);
+    res = dwarf_initialize_fde_table(dbg, &fde_table,
+        output_table_real_data_size,
+        error);
+    if (res != DW_DLV_OK)
+        return res;
+
+    if (table_column >= output_table_real_data_size) {
+        dwarf_free_fde_table(&fde_table);
+        _dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD);
+        return (DW_DLV_ERROR);
     }
 
     /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks 
      */
     res =
-	_dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
-					 error);
+        _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
+            dbg->de_frame_cfa_col_number, error);
     if (res != DW_DLV_OK) {
-	return res;
+        dwarf_free_fde_table(&fde_table);
+        return res;
     }
 
-    if (register_num != NULL)
-	*register_num = fde_table.fr_reg[table_column].ru_register;
-    if (offset != NULL)
-	*offset = fde_table.fr_reg[table_column].ru_offset;
-    if (row_pc != NULL)
-	*row_pc = fde_table.fr_loc;
+    if (fde_table.fr_reg[table_column].ru_value_type != DW_EXPR_OFFSET) {
+        /* The problem here is that this interface cannot deal with
+           other sorts of (newer) dwarf frame values.  Code must
+           use dwarf_get_fde_info_for_reg3() to get these
+           values correctly.  We error rather than return
+           misleading incomplete data. */
+        dwarf_free_fde_table(&fde_table);
+        _dwarf_error(NULL, error,
+            DW_DLE_FRAME_REGISTER_UNREPRESENTABLE);
+        return (DW_DLV_ERROR);
+    }
+    if(table_column == dbg->de_frame_cfa_col_number) {
+        if (register_num != NULL)
+            *register_num = fde_table.fr_cfa_rule.ru_register;
+        if (offset != NULL)
+            *offset = fde_table.fr_cfa_rule.ru_offset_or_block_len;
+        if (row_pc != NULL)
+            *row_pc = fde_table.fr_loc;
+        *offset_relevant = fde_table.fr_cfa_rule.ru_is_off;
+       
+    } else {
+        if (register_num != NULL)
+            *register_num = fde_table.fr_reg[table_column].ru_register;
+        if (offset != NULL)
+            *offset = fde_table.fr_reg[table_column].ru_offset_or_block_len;
+        if (row_pc != NULL)
+            *row_pc = fde_table.fr_loc;
 
-    *offset_relevant = (fde_table.fr_reg[table_column].ru_is_off);
+        *offset_relevant = fde_table.fr_reg[table_column].ru_is_off;
+    }
+    dwarf_free_fde_table(&fde_table);
     return DW_DLV_OK;
 }
 
+/* In this interface, table_column of DW_FRAME_CFA_COL
+   is not meaningful.
+   Use  dwarf_get_fde_info_for_cfa_reg3() to get the CFA.
+   Call dwarf_set_frame_cfa_value() to set the correct column
+   after calling dwarf_init()
+   (DW_FRAME_CFA_COL3 is a sensible column to use).
+*/
+int
+dwarf_get_fde_info_for_reg3(Dwarf_Fde fde,
+    Dwarf_Half table_column,
+    Dwarf_Addr pc_requested,
+    Dwarf_Small * value_type,
+    Dwarf_Signed * offset_relevant,
+    Dwarf_Signed * register_num,
+    Dwarf_Signed * offset_or_block_len,
+    Dwarf_Ptr * block_ptr,
+    Dwarf_Addr * row_pc_out,
+    Dwarf_Error * error)
+{
+    struct Dwarf_Frame_s fde_table;
+    int res = DW_DLV_ERROR;
+
+    Dwarf_Debug dbg = 0;
+    int table_real_data_size = 0;
+
+    FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
+    table_real_data_size = dbg->de_frame_reg_rules_entry_count;
+    res = dwarf_initialize_fde_table(dbg, &fde_table,
+        table_real_data_size, error);
+    if (res != DW_DLV_OK)
+        return res;
+    if (table_column >= table_real_data_size) {
+        dwarf_free_fde_table(&fde_table);
+        _dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD);
+        return (DW_DLV_ERROR);
+    }
+
+    /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks 
+     */
+    res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
+        dbg->de_frame_cfa_col_number,
+        error);
+    if (res != DW_DLV_OK) {
+        dwarf_free_fde_table(&fde_table);
+        return res;
+    }
+
+    if (register_num != NULL)
+        *register_num = fde_table.fr_reg[table_column].ru_register;
+    if (offset_or_block_len != NULL)
+        *offset_or_block_len =
+            fde_table.fr_reg[table_column].ru_offset_or_block_len;
+    if (row_pc_out != NULL)
+        *row_pc_out = fde_table.fr_loc;
+    if (block_ptr)
+        *block_ptr = fde_table.fr_reg[table_column].ru_block;
+
+    /* Without value_type the data cannot be understood, so we insist
+       on it being present, we don't test it. */
+    *value_type = fde_table.fr_reg[table_column].ru_value_type;
+    *offset_relevant = (fde_table.fr_reg[table_column].ru_is_off);
+    dwarf_free_fde_table(&fde_table);
+    return DW_DLV_OK;
+
+}
+
+/* For latest DWARF, this is the preferred interface.
+   It more portably deals with the  CFA by not
+   making the CFA a column number, which means
+   DW_FRAME_CFA_COL3 becomes, like DW_CFA_SAME_VALUE,
+   a special value, not something one uses as an index.
+
+   Call dwarf_set_frame_cfa_value() to set the correct column
+   after calling dwarf_init()
+   (DW_FRAME_CFA_COL3 is a sensible column to use, and
+   is the default unless '--enable-oldframecol' 
+   is used to configure libdwarf).  */
+int
+dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde,
+    Dwarf_Addr pc_requested,
+    Dwarf_Small * value_type,
+    Dwarf_Signed * offset_relevant,
+    Dwarf_Signed * register_num,
+    Dwarf_Signed * offset_or_block_len,
+    Dwarf_Ptr * block_ptr,
+    Dwarf_Addr * row_pc_out,
+    Dwarf_Error * error)
+{
+    struct Dwarf_Frame_s fde_table;
+    int res = DW_DLV_ERROR;
+    Dwarf_Debug dbg = 0;
+
+    int table_real_data_size = 0;
+
+    FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
+
+    table_real_data_size = dbg->de_frame_reg_rules_entry_count;
+    res = dwarf_initialize_fde_table(dbg, &fde_table,
+        table_real_data_size, error);
+    if (res != DW_DLV_OK)
+        return res;
+    res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
+          dbg->de_frame_cfa_col_number,error);
+    if (res != DW_DLV_OK) {
+        dwarf_free_fde_table(&fde_table);
+        return res;
+    }
+
+    if (register_num != NULL)
+        *register_num = fde_table.fr_cfa_rule.ru_register;
+    if (offset_or_block_len != NULL)
+        *offset_or_block_len =
+            fde_table.fr_cfa_rule.ru_offset_or_block_len;
+    if (row_pc_out != NULL)
+        *row_pc_out = fde_table.fr_loc;
+    if (block_ptr)
+        *block_ptr = fde_table.fr_cfa_rule.ru_block;
+
+    /* Without value_type the data cannot be understood, so we insist
+       on it being present, we don't test it. */
+    *value_type = fde_table.fr_cfa_rule.ru_value_type;
+    *offset_relevant = fde_table.fr_cfa_rule.ru_is_off;
+    dwarf_free_fde_table(&fde_table);
+    return DW_DLV_OK;
+}
+
+
+
 /*
-	Return pointer to the instructions in the dwarf
-	fde.
+        Return pointer to the instructions in the dwarf
+        fde.
 */
 int
 dwarf_get_fde_instr_bytes(Dwarf_Fde inFde, Dwarf_Ptr * outinstraddr,
-			  Dwarf_Unsigned * outaddrlen,
-			  Dwarf_Error * error)
+    Dwarf_Unsigned * outaddrlen,
+    Dwarf_Error * error)
 {
-    Dwarf_Unsigned len;
-    unsigned char *instrs;
-    Dwarf_Debug dbg;
+    Dwarf_Unsigned len = 0;
+    unsigned char *instrs = 0;
+    Dwarf_Debug dbg = 0;
 
     if (inFde == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_FDE_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_FDE_NULL);
+        return (DW_DLV_ERROR);
     }
 
     dbg = inFde->fd_dbg;
     if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_FDE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
 
-    instrs = inFde->fd_fde_instr_start,
-	len = (inFde->fd_fde_start + inFde->fd_length +
-	       inFde->fd_length_size + inFde->fd_extension_size)
-	- instrs;
+    instrs = inFde->fd_fde_instr_start;
+
+    len = (inFde->fd_fde_start + inFde->fd_length +
+           inFde->fd_length_size + inFde->fd_extension_size) - instrs;
 
     *outinstraddr = instrs;
     *outaddrlen = len;
     return DW_DLV_OK;
 }
 
+/* Allows getting an fde from its table via an index.  
+   With more error checking than simply indexing oneself.
+*/
 int
 dwarf_get_fde_n(Dwarf_Fde * fde_data,
-		Dwarf_Unsigned fde_index,
-		Dwarf_Fde * returned_fde, Dwarf_Error * error)
+    Dwarf_Unsigned fde_index,
+    Dwarf_Fde * returned_fde, Dwarf_Error * error)
 {
-    Dwarf_Debug dbg;
+    Dwarf_Debug dbg = 0;
+    Dwarf_Signed fdecount = 0;
 
     if (fde_data == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_FDE_PTR_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_FDE_PTR_NULL);
+        return (DW_DLV_ERROR);
     }
 
-    if (*fde_data == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_FDE_NULL);
-	return (DW_DLV_ERROR);
-    }
-
-    dbg = (*fde_data)->fd_dbg;
-    if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
-	return (DW_DLV_ERROR);
-    }
-
-    if (fde_index >= dbg->de_fde_count) {
-	return (DW_DLV_NO_ENTRY);
+    FDE_NULL_CHECKS_AND_SET_DBG(*fde_data, dbg);
+    /* Assumes fde_data table has at least one entry. */
+    fdecount = fde_data[0]->fd_is_eh? 
+        dbg->de_fde_count_eh:dbg->de_fde_count;
+    if (fde_index >= fdecount) {
+        return (DW_DLV_NO_ENTRY);
     }
     *returned_fde = (*(fde_data + fde_index));
     return DW_DLV_OK;
@@ -2040,87 +1975,101 @@
 */
 int
 dwarf_get_fde_at_pc(Dwarf_Fde * fde_data,
-		    Dwarf_Addr pc_of_interest,
-		    Dwarf_Fde * returned_fde,
-		    Dwarf_Addr * lopc,
-		    Dwarf_Addr * hipc, Dwarf_Error * error)
+    Dwarf_Addr pc_of_interest,
+    Dwarf_Fde * returned_fde,
+    Dwarf_Addr * lopc,
+    Dwarf_Addr * hipc, Dwarf_Error * error)
 {
-    Dwarf_Debug dbg;
+    Dwarf_Debug dbg = NULL;
     Dwarf_Fde fde = NULL;
+    Dwarf_Fde entryfde = NULL;
+    Dwarf_Signed fdecount = 0;
 
     if (fde_data == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_FDE_PTR_NULL);
-	return (DW_DLV_ERROR);
-    }
-
-    if (*fde_data == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_FDE_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_FDE_PTR_NULL);
+        return (DW_DLV_ERROR);
     }
 
-    dbg = (*fde_data)->fd_dbg;
-    if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
-	return (DW_DLV_ERROR);
-    }
-    {
-	/* The fde's are sorted by their addresses. Binary search to
-	   find correct fde. */
-	int low = 0;
-	int high = dbg->de_fde_count - 1;
-	int middle = 0;
-	Dwarf_Fde cur_fde;
+    /* Assumes fde_data table has at least one entry. */
+    entryfde = *fde_data;
+    FDE_NULL_CHECKS_AND_SET_DBG(entryfde, dbg);
 
-	while (low <= high) {
-	    middle = (low + high) / 2;
-	    cur_fde = fde_data[middle];
-	    if (pc_of_interest < cur_fde->fd_initial_location) {
-		high = middle - 1;
-	    } else if (pc_of_interest >=
-		       (cur_fde->fd_initial_location +
-			cur_fde->fd_address_range)) {
-		low = middle + 1;
-	    } else {
-		fde = fde_data[middle];
-		break;
-	    }
-	}
+    if (dbg == NULL) {
+        _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
+        return (DW_DLV_ERROR);
+    }
+    fdecount = entryfde->fd_is_eh? 
+        dbg->de_fde_count_eh:dbg->de_fde_count;
+    {
+        /* The fde's are sorted by their addresses. Binary search to
+           find correct fde. */
+        Dwarf_Signed low = 0;
+        Dwarf_Signed high = fdecount - 1L;
+        Dwarf_Signed middle = 0;
+        Dwarf_Fde cur_fde;
+
+        while (low <= high) {
+            middle = (low + high) / 2;
+            cur_fde = fde_data[middle];
+            if (pc_of_interest < cur_fde->fd_initial_location) {
+                high = middle - 1;
+            } else if (pc_of_interest >=
+                       (cur_fde->fd_initial_location +
+                        cur_fde->fd_address_range)) {
+                low = middle + 1;
+            } else {
+                fde = fde_data[middle];
+                break;
+            }
+        }
     }
 
     if (fde) {
-	if (lopc != NULL)
-	    *lopc = fde->fd_initial_location;
-	if (hipc != NULL)
-	    *hipc = fde->fd_initial_location +
-		fde->fd_address_range - 1;
-	*returned_fde = fde;
-	return (DW_DLV_OK);
+        if (lopc != NULL)
+            *lopc = fde->fd_initial_location;
+        if (hipc != NULL)
+            *hipc =
+                fde->fd_initial_location + fde->fd_address_range - 1;
+        *returned_fde = fde;
+        return (DW_DLV_OK);
     }
 
     return (DW_DLV_NO_ENTRY);
 }
 
 
+/* Expands a single frame instruction block
+   from a specific cie
+   into a n array of Dwarf_Frame_Op-s.
+   This depends on having the cfa column set sensibly.
+
+   Call dwarf_set_frame_cfa_value() to set the correct column
+   after calling dwarf_init() unless you are using
+   the old MIPS frame interfaces (in which case the default
+   will be ok). (DW_FRAME_CFA_COL3 is a sensible column to use ).
+*/
 int
-dwarf_expand_frame_instructions(Dwarf_Debug dbg,
-				Dwarf_Ptr instruction,
-				Dwarf_Unsigned i_length,
-				Dwarf_Frame_Op ** returned_op_list,
-				Dwarf_Signed * returned_op_count,
-				Dwarf_Error * error)
+dwarf_expand_frame_instructions(Dwarf_Cie cie,
+    Dwarf_Ptr instruction,
+    Dwarf_Unsigned i_length,
+    Dwarf_Frame_Op ** returned_op_list,
+    Dwarf_Signed * returned_op_count,
+    Dwarf_Error * error)
 {
     Dwarf_Sword instr_count;
-    int res;
+    int res = DW_DLV_ERROR;
     int dw_err;
+    Dwarf_Debug dbg = 0;
 
-    if (dbg == 0) {
-	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_ERROR);
+    if (cie == 0) {
+        _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
+    dbg = cie->ci_dbg;
 
     if (returned_op_list == 0 || returned_op_count == 0) {
-	_dwarf_error(dbg, error, DW_DLE_RET_OP_LIST_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_RET_OP_LIST_NULL);
+        return (DW_DLV_ERROR);
     }
 
     /* The cast to Dwarf_Ptr may get a compiler warning, but it is safe 
@@ -2128,20 +2077,22 @@
        caller has made a big mistake if the result is not a valid
        pointer. */
     res = _dwarf_exec_frame_instr( /* make_instr= */ true,
-				  returned_op_list,
-				  /* search_pc */ false,
-				  /* search_pc_val */ 0,
-				  /* location */ 0,
-				  instruction,
-				  (Dwarf_Ptr)((char *)instruction + i_length),
-				  /* Dwarf_Frame */ NULL,
-				  /* cie_ptr */ NULL,
-				  dbg, &instr_count, &dw_err);
+        returned_op_list,
+        /* search_pc */ false,
+        /* search_pc_val */ 0,
+        /* location */ 0,
+        instruction,
+        (Dwarf_Ptr)((char *)instruction + i_length),
+        /* Dwarf_Frame */ NULL,
+        cie,
+        dbg,
+        dbg->de_frame_cfa_col_number, &instr_count,
+        &dw_err);
     if (res != DW_DLV_OK) {
-	if (res == DW_DLV_ERROR) {
-	    _dwarf_error(dbg, error, dw_err);
-	}
-	return (res);
+        if (res == DW_DLV_ERROR) {
+            _dwarf_error(dbg, error, dw_err);
+        }
+        return (res);
     }
 
     *returned_op_count = instr_count;
@@ -2149,269 +2100,32 @@
 }
 
 
-
-/*
-	Used by rqs.  Returns DW_DLV_OK if returns the arrays.
-	Returns DW_DLV_NO_ENTRY if no section. ?? (How do I tell?)
-	Returns DW_DLV_ERROR if there is an error.
-
-*/
-int
-_dwarf_frame_address_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrlist,
-			     Dwarf_Off ** offsetlist,
-			     Dwarf_Signed * returncount,
-			     Dwarf_Error * err)
-{
-    int retval = DW_DLV_OK;
-    int res;
-    Dwarf_Cie *cie_data;
-    Dwarf_Signed cie_count;
-    Dwarf_Fde *fde_data;
-    Dwarf_Signed fde_count;
-    Dwarf_Signed i;
-    Dwarf_Frame_Op *frame_inst;
-    Dwarf_Fde fdep;
-    Dwarf_Cie ciep;
-    Dwarf_Chain curr_chain = 0;
-    Dwarf_Chain head_chain = 0;
-    Dwarf_Chain prev_chain = 0;
-    Dwarf_Arange arange;
-    Dwarf_Unsigned arange_count = 0;
-    Dwarf_Addr *arange_addrs = 0;
-    Dwarf_Off *arange_offsets = 0;
-
-    res = dwarf_get_fde_list(dbg, &cie_data, &cie_count,
-			     &fde_data, &fde_count, err);
-    if (res != DW_DLV_OK) {
-	return res;
-    }
-
-    res =
-        _dwarf_load_section(dbg,
-			    dbg->de_debug_frame_index,
-			    &dbg->de_debug_frame,
-			    err);
-    if (res != DW_DLV_OK) {
-      return res;
-    }
-
-    for (i = 0; i < cie_count; i++) {
-	Dwarf_Off instoff = 0;
-	Dwarf_Signed initial_instructions_length = 0;
-	Dwarf_Small *instr_end = 0;
-	Dwarf_Sword icount = 0;
-	int j;
-	int dw_err;
-
-	ciep = cie_data[i];
-	instoff = ciep->ci_cie_instr_start - dbg->de_debug_frame;
-	initial_instructions_length = ciep->ci_length +
-	    ciep->ci_length_size + ciep->ci_extension_size -
-	    (ciep->ci_cie_instr_start - ciep->ci_cie_start);
-	instr_end = ciep->ci_cie_instr_start +
-	    initial_instructions_length;
-	res = _dwarf_exec_frame_instr( /* make_instr */ true,
-				      &frame_inst,
-				      /* search_pc= */ false,
-				      /* search_pc_val= */ 0,
-				      /* location */ 0,
-				      ciep->ci_cie_instr_start,
-				      instr_end,
-				      /* Dwarf_frame= */ 0,
-				      /* cie= */ 0,
-				      dbg, &icount, &dw_err);
-	if (res == DW_DLV_ERROR) {
-	    _dwarf_error(dbg, err, dw_err);
-	    return (res);
-	} else if (res == DW_DLV_NO_ENTRY) {
-	    continue;
-	}
-
-	for (j = 0; j < icount; ++j) {
-	    Dwarf_Frame_Op *finst = frame_inst + j;
-
-	    if (finst->fp_base_op == 0 && finst->fp_extended_op == 1) {
-		/* is DW_CFA_set_loc */
-		Dwarf_Addr add = (Dwarf_Addr) finst->fp_offset;
-		Dwarf_Off off = finst->fp_instr_offset + instoff;
-
-		arange = (Dwarf_Arange)
-		    _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
-		if (arange == NULL) {
-		    _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
-		    return (DW_DLV_ERROR);
-		}
-		arange->ar_address = add;
-		arange->ar_info_offset = off;
-		arange_count++;
-		curr_chain = (Dwarf_Chain)
-		    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
-		if (curr_chain == NULL) {
-		    _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
-		    return (DW_DLV_ERROR);
-		}
-		curr_chain->ch_item = arange;
-		if (head_chain == NULL)
-		    head_chain = prev_chain = curr_chain;
-		else {
-		    prev_chain->ch_next = curr_chain;
-		    prev_chain = curr_chain;
-		}
-	    }
-	}
-	dwarf_dealloc(dbg, frame_inst, DW_DLA_FRAME_BLOCK);
-
-    }
-    for (i = 0; i < fde_count; i++) {
-	Dwarf_Small *instr_end = 0;
-	Dwarf_Sword icount = 0;
-	Dwarf_Signed instructions_length = 0;
-	Dwarf_Off instoff = 0;
-	Dwarf_Off off = 0;
-	Dwarf_Addr addr = 0;
-	int j;
-	int dw_err;
-
-	fdep = fde_data[i];
-	off = fdep->fd_initial_loc_pos - dbg->de_debug_frame;
-	addr = fdep->fd_initial_location;
-	arange = (Dwarf_Arange)
-	    _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
-	if (arange == NULL) {
-	    _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
-	    return (DW_DLV_ERROR);
-	}
-	arange->ar_address = addr;
-	arange->ar_info_offset = off;
-	arange_count++;
-	curr_chain = (Dwarf_Chain)
-	    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
-	if (curr_chain == NULL) {
-	    _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
-	    return (DW_DLV_ERROR);
-	}
-	curr_chain->ch_item = arange;
-	if (head_chain == NULL)
-	    head_chain = prev_chain = curr_chain;
-	else {
-	    prev_chain->ch_next = curr_chain;
-	    prev_chain = curr_chain;
-	}
-
-
-	instoff = fdep->fd_fde_instr_start - dbg->de_debug_frame;
-	instructions_length = fdep->fd_length +
-	    fdep->fd_length_size + fdep->fd_extension_size -
-	    (fdep->fd_fde_instr_start - fdep->fd_fde_start);
-	instr_end = fdep->fd_fde_instr_start + instructions_length;
-	res = _dwarf_exec_frame_instr( /* make_instr */ true,
-				      &frame_inst,
-				      /* search_pc= */ false,
-				      /* search_pc_val= */ 0,
-				      /* location */ 0,
-				      fdep->fd_fde_instr_start,
-				      instr_end,
-				      /* Dwarf_frame= */ 0,
-				      /* cie= */ 0,
-				      dbg, &icount, &dw_err);
-	if (res == DW_DLV_ERROR) {
-	    _dwarf_error(dbg, err, dw_err);
-	    return (res);
-	} else if (res == DW_DLV_NO_ENTRY) {
-	    continue;
-	}
-
-	for (j = 0; j < icount; ++j) {
-	    Dwarf_Frame_Op *finst2 = frame_inst + j;
-
-	    if (finst2->fp_base_op == 0 && finst2->fp_extended_op == 1) {
-		/* is DW_CFA_set_loc */
-		Dwarf_Addr add = (Dwarf_Addr) finst2->fp_offset;
-		Dwarf_Off off = finst2->fp_instr_offset + instoff;
-
-		arange = (Dwarf_Arange)
-		    _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
-		if (arange == NULL) {
-		    _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
-		    return (DW_DLV_ERROR);
-		}
-		arange->ar_address = add;
-		arange->ar_info_offset = off;
-		arange_count++;
-		curr_chain = (Dwarf_Chain)
-		    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
-		if (curr_chain == NULL) {
-		    _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
-		    return (DW_DLV_ERROR);
-		}
-		curr_chain->ch_item = arange;
-		if (head_chain == NULL)
-		    head_chain = prev_chain = curr_chain;
-		else {
-		    prev_chain->ch_next = curr_chain;
-		    prev_chain = curr_chain;
-		}
-
-	    }
-	}
-	dwarf_dealloc(dbg, frame_inst, DW_DLA_FRAME_BLOCK);
-
-    }
-    dwarf_dealloc(dbg, fde_data, DW_DLA_LIST);
-    dwarf_dealloc(dbg, cie_data, DW_DLA_LIST);
-    arange_addrs = (Dwarf_Addr *)
-	_dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
-    if (arange_addrs == NULL) {
-	_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
-    }
-    arange_offsets = (Dwarf_Off *)
-	_dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
-    if (arange_offsets == NULL) {
-	_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
-    }
-
-    curr_chain = head_chain;
-    for (i = 0; i < arange_count; i++) {
-	Dwarf_Arange ar = curr_chain->ch_item;
-
-	arange_addrs[i] = ar->ar_address;
-	arange_offsets[i] = ar->ar_info_offset;
-	prev_chain = curr_chain;
-	curr_chain = curr_chain->ch_next;
-	dwarf_dealloc(dbg, ar, DW_DLA_ARANGE);
-	dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
-    }
-    *returncount = arange_count;
-    *offsetlist = arange_offsets;
-    *addrlist = arange_addrs;
-    return retval;
-}
-
 /* Used by dwarfdump -v to print offsets, for debugging
-   dwarf info
+   dwarf info.
+   The dwarf_ version is preferred over the obsolete _dwarf version.
+   _dwarf version kept for compatibility.
 */
 /* ARGSUSED 4 */
 int
 _dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde,
-			  Dwarf_Off * fde_off, Dwarf_Off * cie_off,
-			  Dwarf_Error * err)
+    Dwarf_Off * fde_off, Dwarf_Off * cie_off,
+    Dwarf_Error * err) 
 {
-    int res;
-    char *start;
-    char *loc;
+  return dwarf_fde_section_offset(dbg,in_fde,fde_off,
+     cie_off,err);
+}
+/* ARGSUSED 4 */
+int
+dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde,
+    Dwarf_Off * fde_off, Dwarf_Off * cie_off,
+    Dwarf_Error * err)
+{
+    char *start = 0;
+    char *loc = 0;
 
-    res =
-        _dwarf_load_section(dbg,
-			    dbg->de_debug_frame_index,
-			    &dbg->de_debug_frame,
-			    err);
-    if (res != DW_DLV_OK) {
-        return res;
-    }
+
 
-    start = (char *) dbg->de_debug_frame;
+    start = (char *) in_fde->fd_section_ptr;
     loc = (char *) in_fde->fd_fde_start;
 
     *fde_off = (loc - start);
@@ -2420,29 +2134,309 @@
 }
 
 /* Used by dwarfdump -v to print offsets, for debugging
-   dwarf info
+   dwarf info.
+   The dwarf_ version is preferred over the obsolete _dwarf version.
+   _dwarf version kept for compatibility.
 */
 /* ARGSUSED 4 */
 int
 _dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie,
-			  Dwarf_Off * cie_off, Dwarf_Error * err)
+    Dwarf_Off * cie_off, Dwarf_Error * err)
 {
-    int res;
-    char *start;
-    char *loc;
+    return dwarf_cie_section_offset(dbg,in_cie,cie_off,err);
+}
+/* ARGSUSED 4 */
+int
+dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie,
+    Dwarf_Off * cie_off, Dwarf_Error * err)
+{
+    char *start = 0;
+    char *loc = 0;
 
-    res =
-        _dwarf_load_section(dbg,
-			    dbg->de_debug_frame_index,
-			    &dbg->de_debug_frame,
-			    err);
-    if (res != DW_DLV_OK) {
-        return res;
-    }
-
-    start = (char *) dbg->de_debug_frame;
+    start = (char *) in_cie->ci_section_ptr;
     loc = (char *) in_cie->ci_cie_start;
 
     *cie_off = (loc - start);
     return DW_DLV_OK;
 }
+
+/* Returns  a pointer to target-specific augmentation data thru augdata
+   and returns the length of the data thru augdata_len.
+
+   It's up to the consumer code to know how to interpret the bytes
+   of target-specific data (endian issues apply too, these
+   are just raw bytes pointed to).
+   See  Linux Standard Base Core Specification version 3.0 for
+   the details on .eh_frame info.
+
+   Returns DW_DLV_ERROR if fde is NULL or some other serious
+   error.
+   Returns DW_DLV_NO_ENTRY if there is no target-specific
+   augmentation data. 
+
+   The bytes pointed to are in the Dwarf_Cie, and as long as that
+   is valid the bytes are there. No 'dealloc' call is needed
+   for the bytes.
+*/
+int
+dwarf_get_cie_augmentation_data(Dwarf_Cie cie,
+    Dwarf_Small ** augdata,
+    Dwarf_Unsigned * augdata_len,
+    Dwarf_Error * error)
+{
+    if (cie == NULL) {
+        _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
+        return (DW_DLV_ERROR);
+    }
+    if (cie->ci_gnu_eh_augmentation_len == 0) {
+        return DW_DLV_NO_ENTRY;
+    }
+    *augdata = (Dwarf_Small *) (cie->ci_gnu_eh_augmentation_bytes);
+    *augdata_len = cie->ci_gnu_eh_augmentation_len;
+    return DW_DLV_OK;
+}
+
+
+/* Returns  a pointer to target-specific augmentation data thru augdata
+   and returns the length of the data thru augdata_len.
+
+   It's up to the consumer code to know how to interpret the bytes
+   of target-specific data (endian issues apply too, these
+   are just raw bytes pointed to).
+   See  Linux Standard Base Core Specification version 3.0 for
+   the details on .eh_frame info.
+
+   Returns DW_DLV_ERROR if fde is NULL or some other serious
+   error.
+   Returns DW_DLV_NO_ENTRY if there is no target-specific
+   augmentation data. 
+
+   The bytes pointed to are in the Dwarf_Fde, and as long as that
+   is valid the bytes are there. No 'dealloc' call is needed
+   for the bytes.
+
+*/
+int
+dwarf_get_fde_augmentation_data(Dwarf_Fde fde,
+    Dwarf_Small * *augdata,
+    Dwarf_Unsigned * augdata_len,
+    Dwarf_Error * error)
+{
+    Dwarf_Cie cie = 0;
+
+    if (fde == NULL) {
+        _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
+        return (DW_DLV_ERROR);
+    }
+    cie = fde->fd_cie;
+    if (cie == NULL) {
+        _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
+        return (DW_DLV_ERROR);
+    }
+    if (cie->ci_gnu_eh_augmentation_len == 0) {
+        return DW_DLV_NO_ENTRY;
+    }
+    *augdata = (Dwarf_Small *) fde->fd_gnu_eh_augmentation_bytes;
+    *augdata_len = fde->fd_gnu_eh_augmentation_len;
+    return DW_DLV_OK;
+}
+
+
+/* Initialize with same_value , a value which makes sense
+   for IRIX/MIPS.
+   The correct value to use is ABI dependent.
+   For register-windows machines most
+   or all registers should get DW_FRAME_UNDEFINED_VAL as the
+   correct initial value.
+   Some think DW_FRAME_UNDEFINED_VAL is always the
+   right value.   
+
+   For some ABIs a setting which varies by register
+   would be more appropriate.
+
+   FIXME. */
+
+static void
+_dwarf_init_regrule_table(struct Dwarf_Reg_Rule_s *t1reg,
+    int last_reg_num, int initial_value)
+{
+    struct Dwarf_Reg_Rule_s *t1end = t1reg + last_reg_num;
+
+    for (; t1reg < t1end; t1reg++) {
+        t1reg->ru_is_off = 0;
+        t1reg->ru_value_type = DW_EXPR_OFFSET;
+        t1reg->ru_register = initial_value;
+        t1reg->ru_offset_or_block_len = 0;
+        t1reg->ru_block = 0;
+    }
+}
+
+#if 0
+/* Used solely for debugging libdwarf. */
+static void
+dump_frame_rule(char *msg, struct Dwarf_Reg_Rule_s *reg_rule)
+{
+    printf
+        ("%s type %s (" DW_PR_DUx "), is_off " 
+         DW_PR_DUu " reg " DW_PR_DUu " offset " DW_PR_DUx " blockp "
+         DW_PR_DUx "\n",
+         msg,
+         (reg_rule->ru_value_type == DW_EXPR_OFFSET) ? 
+             "DW_EXPR_OFFSET" : 
+          (reg_rule->ru_value_type == DW_EXPR_VAL_OFFSET) ?
+             "DW_EXPR_VAL_OFFSET" : 
+          (reg_rule->ru_value_type == DW_EXPR_VAL_EXPRESSION) ?
+             "DW_EXPR_VAL_EXPRESSION" : 
+          (reg_rule->ru_value_type == DW_EXPR_EXPRESSION) ?
+             "DW_EXPR_EXPRESSION" : "Unknown",
+         (Dwarf_Unsigned) reg_rule->ru_value_type, 
+         (Dwarf_Unsigned) reg_rule->ru_is_off,
+         (Dwarf_Unsigned) reg_rule->ru_register,
+         (Dwarf_Unsigned) reg_rule->ru_offset_or_block_len,
+         (Dwarf_Unsigned) reg_rule->ru_block);
+    return;
+}
+#endif
+
+/* This allows consumers to set the 'initial value' so that
+   an ISA/ABI specific default can be used, dynamically,
+   at run time.  Useful for dwarfdump and non-MIPS architectures.. 
+   The value  defaults to one of
+        DW_FRAME_SAME_VALUE or DW_FRAME_UNKNOWN_VALUE
+   but dwarfdump can dump multiple ISA/ABI objects so
+   we may want to get this set to what the ABI says is correct.
+
+   Returns the value that was present before we changed it here.
+*/
+Dwarf_Half
+dwarf_set_frame_rule_initial_value(Dwarf_Debug dbg, Dwarf_Half value)
+{
+    Dwarf_Half orig = dbg->de_frame_rule_initial_value;
+    dbg->de_frame_rule_initial_value = value;
+    return orig;
+}
+
+/* The following spelling for backwards compatibility. */
+Dwarf_Half
+dwarf_set_frame_rule_inital_value(Dwarf_Debug dbg, Dwarf_Half value)
+{
+    return dwarf_set_frame_rule_initial_value(dbg,value);
+}
+
+/* This allows consumers to set the array size of the  reg rules
+   table so that
+   an ISA/ABI specific value can be used, dynamically,
+   at run time.  Useful for non-MIPS archtectures.
+   The value  defaults  to DW_FRAME_LAST_REG_NUM.
+   but dwarfdump can dump multiple ISA/ABI objects so
+   consumers want to get this set to what the ABI says is correct.
+
+   Returns the value that was present before we changed it here.
+*/
+
+Dwarf_Half
+dwarf_set_frame_rule_table_size(Dwarf_Debug dbg, Dwarf_Half value)
+{
+    Dwarf_Half orig = dbg->de_frame_reg_rules_entry_count;
+    dbg->de_frame_reg_rules_entry_count = value;
+    return orig;
+}
+/* This allows consumers to set the CFA register value
+ * so that an ISA/ABI specific value can be used, dynamically,
+ * at run time.  Useful for non-MIPS archtectures.
+ * The value  defaults  to DW_FRAME_CFA_COL3 and should be
+ * higher than any real register in the ABI. 
+ * Dwarfdump can dump multiple ISA/ABI objects so
+ * consumers want to get this set to what the ABI says is correct.
+ 
+ * Returns the value that was present before we changed it here.
+ * */
+
+Dwarf_Half
+dwarf_set_frame_cfa_value(Dwarf_Debug dbg, Dwarf_Half value)
+{
+    Dwarf_Half orig = dbg->de_frame_cfa_col_number;
+    dbg->de_frame_cfa_col_number = value;
+    return orig;
+}
+/* Similar to above, but for the other crucial fields for frames. */
+Dwarf_Half
+dwarf_set_frame_same_value(Dwarf_Debug dbg, Dwarf_Half value)
+{
+    Dwarf_Half orig = dbg->de_frame_same_value_number;
+    dbg->de_frame_same_value_number = value;
+    return orig;
+}
+Dwarf_Half
+dwarf_set_frame_undefined_value(Dwarf_Debug dbg, Dwarf_Half value)
+{
+    Dwarf_Half orig = dbg->de_frame_same_value_number;
+    dbg->de_frame_undefined_value_number = value;
+    return orig;
+}
+
+
+
+
+
+static int
+dwarf_initialize_fde_table(Dwarf_Debug dbg,
+    struct Dwarf_Frame_s *fde_table,
+    unsigned table_real_data_size,
+    Dwarf_Error * error)
+{
+    unsigned entry_size = sizeof(struct Dwarf_Frame_s);
+
+    fde_table->fr_loc = 0;
+    fde_table->fr_reg_count = table_real_data_size;
+    fde_table->fr_next = 0;
+
+    fde_table->fr_reg = (struct Dwarf_Reg_Rule_s *)
+        calloc(entry_size, table_real_data_size);
+    if (fde_table->fr_reg == 0) {
+        _dwarf_error(dbg, error, DW_DLE_DF_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
+    }
+    return DW_DLV_OK;
+
+}
+static void
+dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table)
+{
+    free(fde_table->fr_reg);
+    fde_table->fr_reg_count = 0;
+    fde_table->fr_reg = 0;
+}
+
+
+/* Return DW_DLV_OK if we succeed. else return DW_DLV_ERROR.
+*/
+int
+_dwarf_frame_constructor(Dwarf_Debug dbg, void *frame)
+{
+    struct Dwarf_Frame_s *fp = frame;
+
+    if (!dbg) {
+        return DW_DLV_ERROR;
+    }
+
+    fp->fr_reg = calloc(dbg->de_frame_reg_rules_entry_count,
+                        sizeof(struct Dwarf_Reg_Rule_s));
+    if (!fp->fr_reg) {
+        return DW_DLV_ERROR;
+    }
+    fp->fr_reg_count = dbg->de_frame_reg_rules_entry_count;
+    return DW_DLV_OK;
+}
+
+void
+_dwarf_frame_destructor(void *frame)
+{
+    struct Dwarf_Frame_s *fp = frame;
+
+    if (fp->fr_reg) {
+        free(fp->fr_reg);
+    }
+    fp->fr_reg = 0;
+    fp->fr_reg_count = 0;
+}
--- a/usr/src/tools/ctf/dwarf/common/dwarf_frame.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_frame.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000, 2004, 2006 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -62,25 +62,38 @@
  * is an LEB128 data item that denotes the size (in bytes) of
  * the augmented fields (not including the size of
  * "length_of_augmented_fields" itself).
- * This implementation of libdwarf will assume that the length of
- * augmented fields follow the augmenter string when the augmentation
- * starts with the string "z". It will skip over any augmented fields
- * that it does not understand to the start of  initial instructions 
- * (in case of CIE) or the instruction table (in case of FDE).
- * 
- * Future sgi versions of cie or fde should use "z1", "z2" as the
- * augmenter strings and it should guarantee that all the above fields
- * are laid out in the same fashion. Older libraries will continue to be able 
- * to read all the old data, skipping over newly added data items.
+ 
+ * Handling of cie augmentation strings is necessarly a heuristic.
+ * See dwarf_frame.c for the currently known augmentation strings.
+
+
+   ---START SGI-ONLY COMMENT:
+ * SGI-IRIX versions of cie or fde  were intended to use "z1", "z2" as the
+ * augmenter strings if required for new augmentation.
+ * However, that never happened (as of March 2005).
  *
- * The fde's augmented by the string "z" have a new field (signed constant, 4
-   byte field)
- * called offset_into_exception_tables, following the length_of_augmented field.
- * This field contains an offset into the "_MIPS_eh_region", which describes
- * the exception handling tables.
+ * The fde's augmented by the string "z" have a new field 
+ * (signed constant, 4 byte field)
+ * called offset_into_exception_tables, following the 
+ * length_of_augmented field.   This field contains an offset 
+ * into the "_MIPS_eh_region", which describes
+ * the IRIX CC exception handling tables.
+   ---END SGI-ONLY COMMENT
+ 
+
+ * GNU .eh_frame has an augmentation string of z[RLP]* (gcc 3.4)
+ * The similarity to IRIX 'z' (and proposed but never
+ * implemented IRIX z1, z2 etc) was confusing things.
+ * If the section is .eh_frame then 'z' means GNU exception
+ * information 'Augmentation Data' not IRIX 'z'.
+ * See The Linux Standard Base Core Specification version 3.0
  */
 
-#define DW_DEBUG_FRAME_VERSION                 	1
+#define DW_DEBUG_FRAME_VERSION                 	1 /* DWARF2 */
+#define DW_DEBUG_FRAME_VERSION3                	3 /* DWARF3 */
+#define DW_DEBUG_FRAME_VERSION4                	4 /* DWARF4 */
+/* The following is SGI/IRIX specific, and probably no longer
+   in use anywhere. */
 #define DW_DEBUG_FRAME_AUGMENTER_STRING     	"mti v1"
 
 /* The value of the offset field for Cie's. */
@@ -101,8 +114,9 @@
 
     /* 
        Is a flag indicating whether the rule includes the offset
-       field, ie whether the ru_offset field is valid or not. It is
-       important, since reg+offset (offset of 0) is different from
+       field, ie whether the ru_offset field is valid or not. 
+       Applies only if DW_EXPR_OFFSET or DW_EXPR_VAL_OFFSET.
+       It is important, since reg+offset (offset of 0) is different from
        just 'register' since the former means 'read memory at address
        given by the sum of register contents plus offset to get the
        value'. whereas the latter means 'the value is in the register'.
@@ -113,13 +127,27 @@
        DW_FRAME_CFA_COL.
 
      */
-    Dwarf_Sbyte ru_is_off;
+    Dwarf_Sbyte ru_is_off; 
+
+    /* DW_EXPR_OFFSET (0, DWARF2)  
+       DW_EXPR_VAL_OFFSET 1 (dwarf2/3)
+       DW_EXPR_EXPRESSION 2  (dwarf2/3)
+	DW_EXPR_VAL_EXPRESSION 3 (dwarf2/3) 
+       See dwarf_frame.h. */
+    Dwarf_Sbyte ru_value_type;
 
     /* Register involved in this rule. */
     Dwarf_Half ru_register;
 
-    /* Offset to add to register, if indicated by ru_is_offset. */
-    Dwarf_Addr ru_offset;
+    /* Offset to add to register, if indicated by ru_is_offset
+       and if DW_EXPR_OFFSET or DW_EXPR_VAL_OFFSET. 
+       If DW_EXPR_EXPRESSION or DW_EXPR_VAL_EXPRESSION
+       this is DW_FORM_block block-length, not offset. */
+    Dwarf_Unsigned ru_offset_or_block_len;
+    
+    /* For DW_EXPR_EXPRESSION DW_EXPR_VAL_EXPRESSION these is set,
+       else 0. */
+    Dwarf_Small *ru_block;
 };
 
 typedef struct Dwarf_Frame_s *Dwarf_Frame;
@@ -128,6 +156,9 @@
     This structure represents a row of the frame table. 
     Fr_loc is the pc value for this row, and Fr_reg
     contains the rule for each column.
+
+    Entry DW_FRAME_CFA_COL of fr_reg was the tradional MIPS
+    way of setting CFA.  cfa_rule is the new one.
 */
 struct Dwarf_Frame_s {
 
@@ -135,7 +166,12 @@
     Dwarf_Addr fr_loc;
 
     /* Rules for all the registers in this row. */
-    struct Dwarf_Reg_Rule_s fr_reg[DW_FRAME_LAST_REG_NUM];
+    struct Dwarf_Reg_Rule_s fr_cfa_rule;
+
+	/* fr_reg_count is the the number of
+	entries of the fr_reg array. */
+    unsigned long            fr_reg_count;
+    struct Dwarf_Reg_Rule_s *fr_reg;
 
     Dwarf_Frame fr_next;
 };
@@ -148,6 +184,39 @@
     Dwarf_Frame_Op_List fl_next;
 };
 
+/* See dwarf_frame.c for the heuristics used to set the
+   Dwarf_Cie ci_augmentation_type.  
+
+   This succinctly helps interpret the size and meaning of .debug_frame
+   and (for gcc) .eh_frame.
+
+   In the case of gcc .eh_frame (gcc 3.3, 3.4)
+   z may be followed by one or more of
+   L R P.  
+
+*/
+enum Dwarf_augmentation_type {
+        aug_empty_string, /* Default empty augmentation string.  */
+        aug_irix_exception_table,  /* IRIX  plain  "z",
+                   for exception handling, IRIX CC compiler.
+		   Proposed z1 z2 ... never implemented.  */
+        aug_gcc_eh_z,       /* gcc z augmentation,  (including
+			L R P variations). gcc 3.3 3.4 exception
+			handling in eh_frame.  */
+        aug_irix_mti_v1,  /* IRIX "mti v1" augmentation string. Probably
+                             never in any released SGI-IRIX compiler. */
+        aug_eh,           /* For gcc .eh_frame, "eh" is the string.,
+				gcc 1,2, egcs. Older values.  */
+        aug_armcc,  /* "armcc+" meaning the  cfa calculation
+                    is corrected to be standard (output by
+                    Arm C RVCT 3.0 SP1 and later). See
+                    http://sourceware.org/ml/gdb-patches/2006-12/msg00249.html
+                    for details. */
+        aug_unknown,      /* Unknown augmentation, we cannot do much. */
+        aug_past_last
+};
+
+
 /* 
     This structure contains all the pertinent info for a Cie. Most 
     of the fields are taken straight from the definition of a Cie.  
@@ -158,7 +227,7 @@
     row generated by the instructions for this Cie.
 */
 struct Dwarf_Cie_s {
-    Dwarf_Word ci_length;
+    Dwarf_Unsigned ci_length;
     char *ci_augmentation;
     Dwarf_Small ci_code_alignment_factor;
     Dwarf_Sbyte ci_data_alignment_factor;
@@ -170,6 +239,38 @@
     Dwarf_Cie ci_next;
     Dwarf_Small ci_length_size;
     Dwarf_Small ci_extension_size;
+    Dwarf_Half ci_cie_version_number;
+    enum Dwarf_augmentation_type ci_augmentation_type;	 
+
+    /* The following 2 for GNU .eh_frame exception handling
+       Augmentation Data. Set if ci_augmentation_type
+       is aug_gcc_eh_z. Zero if unused. */
+    Dwarf_Unsigned ci_gnu_eh_augmentation_len;
+    Dwarf_Ptr      ci_gnu_eh_augmentation_bytes;
+
+    /* These are extracted from the gnu eh_frame
+       augmentation if the
+       augmentation begins with 'z'. See Linux LSB documents.
+       Otherwize these are zero. */
+    unsigned char    ci_gnu_personality_handler_encoding;
+    unsigned char    ci_gnu_lsda_encoding;
+    unsigned char    ci_gnu_fde_begin_encoding;
+
+    /* If 'P' augmentation present, is handler addr. Else
+	is zero. */
+    Dwarf_Addr     ci_gnu_personality_handler_addr;
+
+
+    /* In creating list of cie's (which will become an array)
+       record the position so fde can get it on fde creation. */
+    Dwarf_Unsigned ci_index;
+    Dwarf_Small *  ci_section_ptr;
+    /* DWARF4 adds address size and segment size to the CIE: the .debug_info
+       section may not always be present to allow libdwarf to
+       find address_size from the compilation-unit. */
+    Dwarf_Half   ci_address_size;
+    Dwarf_Half   ci_segment_size;
+
 };
 
 /*
@@ -183,9 +284,9 @@
 	points to the associated Dwarf_Debug structure.
 */
 struct Dwarf_Fde_s {
-    Dwarf_Word fd_length;
+    Dwarf_Unsigned fd_length;
     Dwarf_Addr fd_cie_offset;
-    Dwarf_Sword fd_cie_index;
+    Dwarf_Unsigned fd_cie_index;
     Dwarf_Cie fd_cie;
     Dwarf_Addr fd_initial_location;
     Dwarf_Small *fd_initial_loc_pos;
@@ -193,10 +294,31 @@
     Dwarf_Small *fd_fde_start;
     Dwarf_Small *fd_fde_instr_start;
     Dwarf_Debug fd_dbg;
+
+	/* fd_offset_into_exception_tables is SGI/IRIX exception table
+	   offset. Unused and zero if not IRIX .debug_frame. */
     Dwarf_Signed fd_offset_into_exception_tables;
+
     Dwarf_Fde fd_next;
     Dwarf_Small fd_length_size;
     Dwarf_Small fd_extension_size;
+    /* So we know from an fde which 'count' of fde-s in
+       Dwarf_Debug applies:  eh or standard. */
+    Dwarf_Small fd_is_eh;
+    /* The following 2 for GNU .eh_frame exception handling
+       Augmentation Data. Set if CIE ci_augmentation_type
+       is aug_gcc_eh_z. Zero if unused. */
+    Dwarf_Unsigned fd_gnu_eh_augmentation_len;
+    Dwarf_Ptr fd_gnu_eh_augmentation_bytes;
+    Dwarf_Addr fd_gnu_eh_lsda; /* If 'L' augmentation letter
+         present:  is address of the 
+         Language Specific Data Area (LSDA). If not 'L" is zero. */
+
+    /* The following 3 are about the Elf section the FDEs come from. */
+    Dwarf_Small * fd_section_ptr;
+    Dwarf_Unsigned fd_section_length;
+    Dwarf_Unsigned fd_section_index; 
+
 };
 
 
@@ -205,3 +327,95 @@
 			       Dwarf_Off ** offsetlist,
 			       Dwarf_Signed * returncount,
 			       Dwarf_Error * err);
+
+int
+_dwarf_get_fde_list_internal(Dwarf_Debug dbg,
+                              Dwarf_Cie ** cie_data,
+                              Dwarf_Signed * cie_element_count,
+                              Dwarf_Fde ** fde_data,
+                              Dwarf_Signed * fde_element_count,
+                              Dwarf_Small * section_ptr,
+                              Dwarf_Unsigned section_index,
+                              Dwarf_Unsigned section_length,
+                              Dwarf_Unsigned cie_id_value,
+                              int use_gnu_cie_calc,  /* If non-zero,
+                                this is gcc eh_frame. */
+                              Dwarf_Error * error);
+
+enum Dwarf_augmentation_type
+_dwarf_get_augmentation_type(Dwarf_Debug dbg,
+        Dwarf_Small *augmentation_string,
+        int is_gcc_eh_frame);
+
+Dwarf_Unsigned _dwarf_get_return_address_reg(Dwarf_Small *frame_ptr,
+                        int version,
+                        unsigned long *size);
+
+/* Temporary recording of crucial cie/fde prefix data.
+ * Vastly simplifies some argument lists.
+ */
+struct cie_fde_prefix_s {
+   /* cf_start_addr is a pointer to the first byte of this fde/cie
+      we are reading now. */
+   Dwarf_Small *  cf_start_addr;
+   Dwarf_Small *  cf_addr_after_prefix;
+   Dwarf_Unsigned cf_length;
+   int            cf_local_length_size;
+   int            cf_local_extension_size;
+   Dwarf_Unsigned cf_cie_id;
+   Dwarf_Small *  cf_cie_id_addr; /* used for eh_frame calculations. */
+
+   /* Simplifies passing around these values to create fde having
+      these here. */
+   /* cf_section_ptr is a pointer to the first byte
+      of the object section the prefix is read from.  */
+   Dwarf_Small *  cf_section_ptr;
+   Dwarf_Unsigned cf_section_index; 
+   Dwarf_Unsigned cf_section_length; 
+};
+
+int
+_dwarf_exec_frame_instr(Dwarf_Bool make_instr,
+                        Dwarf_Frame_Op ** ret_frame_instr,
+                        Dwarf_Bool search_pc,
+                        Dwarf_Addr search_pc_val,
+                        Dwarf_Addr initial_loc,
+                        Dwarf_Small * start_instr_ptr,
+                        Dwarf_Small * final_instr_ptr,
+                        Dwarf_Frame table,
+                        Dwarf_Cie cie,
+                        Dwarf_Debug dbg,
+			Dwarf_Half reg_num_of_cfa,
+                        Dwarf_Sword * returned_count,
+                        int *returned_error);
+
+
+int dwarf_read_cie_fde_prefix(Dwarf_Debug dbg,
+        Dwarf_Small *frame_ptr_in,
+        Dwarf_Small *section_ptr_in,
+        Dwarf_Unsigned section_index_in,
+	Dwarf_Unsigned section_length_in,
+        struct cie_fde_prefix_s *prefix_out,
+        Dwarf_Error *error);
+
+int dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
+        struct cie_fde_prefix_s *  prefix,
+        Dwarf_Small *section_pointer,
+        Dwarf_Small *frame_ptr,
+        int use_gnu_cie_calc,
+        Dwarf_Cie  cie_ptr_in,
+        Dwarf_Fde *fde_ptr_out,
+        Dwarf_Error *error);
+
+int dwarf_create_cie_from_after_start(Dwarf_Debug dbg,
+        struct cie_fde_prefix_s *prefix,
+        Dwarf_Small* section_pointer,
+        Dwarf_Small* frame_ptr,
+        Dwarf_Unsigned cie_count,
+        int use_gnu_cie_calc,
+        Dwarf_Cie *cie_ptr_out,
+        Dwarf_Error *error);
+
+
+int _dwarf_frame_constructor(Dwarf_Debug dbg,void * );
+void _dwarf_frame_destructor (void *);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_frame2.c	Sun May 22 03:13:22 2011 +0100
@@ -0,0 +1,1540 @@
+/*
+
+  Copyright (C) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+/*
+        This  implements _dwarf_get_fde_list_internal()
+        and related helper functions for reading cie/fde data.
+*/
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include "dwarf_frame.h"
+#include "dwarf_arange.h"       /* using Arange as a way to build a
+                                   list */
+
+
+static int dwarf_find_existing_cie_ptr(Dwarf_Small * cie_ptr,
+                                       Dwarf_Cie cur_cie_ptr,
+                                       Dwarf_Cie * cie_ptr_to_use_out,
+                                       Dwarf_Cie head_cie_ptr);
+static void dealloc_fde_cie_list_internal(Dwarf_Fde head_fde_ptr,
+                                          Dwarf_Cie head_cie_ptr);
+static int dwarf_create_cie_from_start(Dwarf_Debug dbg,
+                                       Dwarf_Small * cie_ptr_val,
+                                       Dwarf_Small * section_ptr,
+                                       Dwarf_Unsigned section_index,
+                                       Dwarf_Unsigned section_length,
+                                       Dwarf_Small * frame_ptr_end,
+                                       Dwarf_Unsigned cie_id_value,
+                                       Dwarf_Unsigned cie_count,
+                                       int use_gnu_cie_calc,
+                                       Dwarf_Cie * cie_ptr_to_use_out,
+                                       Dwarf_Error * error);
+
+static Dwarf_Small *get_cieptr_given_offset(Dwarf_Unsigned cie_id_value,
+                                            int use_gnu_cie_calc,
+                                            Dwarf_Small * section_ptr,
+                                            Dwarf_Small * cie_id_addr);
+static int get_gcc_eh_augmentation(Dwarf_Debug dbg,
+                                   Dwarf_Small * frame_ptr,
+                                   unsigned long
+                                   *size_of_augmentation_data,
+                                   enum Dwarf_augmentation_type augtype,
+                                   Dwarf_Small * section_pointer,
+                                   Dwarf_Small * fde_eh_encoding_out,
+                                   char *augmentation);
+
+static int
+  gnu_aug_encodings(Dwarf_Debug dbg, char *augmentation,
+                    Dwarf_Small * aug_data, Dwarf_Unsigned aug_data_len,
+                    Dwarf_Half address_size,
+                    unsigned char *pers_hand_enc_out,
+                    unsigned char *lsda_enc_out,
+                    unsigned char *fde_begin_enc_out,
+                    Dwarf_Addr * gnu_pers_addr_out);
+
+
+static int read_encoded_ptr(Dwarf_Debug dbg,
+                            Dwarf_Small * section_pointer,
+                            Dwarf_Small * input_field,
+                            int gnu_encoding,
+                            Dwarf_Half address_size,
+                            Dwarf_Unsigned * addr,
+                            Dwarf_Small ** input_field_out);
+
+
+
+static int qsort_compare(const void *elem1, const void *elem2);
+
+
+/* Adds 'newone' to the end of the list starting at 'head'
+   and makes the new one 'cur'rent. */
+static void
+chain_up_fde(Dwarf_Fde newone, Dwarf_Fde * head, Dwarf_Fde * cur)
+{
+    if (*head == NULL)
+        *head = newone;
+    else {
+        (*cur)->fd_next = newone;
+    }
+    *cur = newone;
+
+}
+
+/* Adds 'newone' to the end of the list starting at 'head'
+   and makes the new one 'cur'rent. */
+static void
+chain_up_cie(Dwarf_Cie newone, Dwarf_Cie * head, Dwarf_Cie * cur)
+{
+    if (*head == NULL) {
+        *head = newone;
+    } else {
+        (*cur)->ci_next = newone;
+    }
+    *cur = newone;
+}
+
+/* The size of the length field plus the 
+    value of length must be an integral 
+    multiple of the address size.  Dwarf4 standard. 
+
+    A constant that gives the number of bytes of the CIE 
+    structure, not including the length field itself 
+    (where length mod <size of an address> == 0) 
+    (see Section 7.2.2). Dwarf3 standard.
+ 
+    A uword constant that gives the number of bytes of 
+    the CIE structure, not including the
+    length field, itself (length mod <addressing unit size> == 0).
+    Dwarf2 standard.*/
+static void
+validate_length(Dwarf_Debug dbg,
+    Dwarf_Cie cieptr, Dwarf_Unsigned length,
+    Dwarf_Unsigned length_size,
+    Dwarf_Unsigned extension_size,
+    Dwarf_Small * section_ptr,
+    Dwarf_Small * ciefde_start,
+    const char * cieorfde)
+{
+    Dwarf_Unsigned address_size = cieptr->ci_address_size;
+    Dwarf_Unsigned length_field_summed = length_size + extension_size;
+    Dwarf_Unsigned total_len = length + length_field_summed;
+    Dwarf_Unsigned mod = total_len % address_size;
+
+    if (mod != 0) {
+        char msg[DW_HARMLESS_ERROR_MSG_STRING_SIZE];
+        Dwarf_Unsigned sectionoffset = ciefde_start - section_ptr;
+        snprintf(msg,sizeof(msg),
+            "DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE"
+            " len=0x%" DW_PR_DUx
+            ", len size=0x%" DW_PR_DUx
+            ", extn size=0x%" DW_PR_DUx
+            ", totl length=0x%" DW_PR_DUx
+            ", addr size=0x%" DW_PR_DUx
+            ", mod=0x%" DW_PR_DUx " must be zero"
+            " in %s"
+            ", offset 0x%" DW_PR_DUx ".",
+            length,
+            length_size,
+            extension_size,
+            total_len,address_size, mod,
+            cieorfde,
+            sectionoffset);
+        dwarf_insert_harmless_error(dbg,msg);
+    }
+    return;
+}
+
+
+#if 0
+/* For debugging only. */
+static void
+print_prefix(struct cie_fde_prefix_s *prefix, int line)
+{
+    printf("prefix-print, prefix at 0x%lx, line %d\n",
+           (long) prefix, line);
+    printf("  start addr 0x%lx after prefix 0x%lx\n",
+           (long) prefix->cf_start_addr,
+           (long) prefix->cf_addr_after_prefix);
+    printf("  length 0x%" DW_PR_DUx ", len size %d ext size %d\n", 
+           (Dwarf_Unsigned) prefix->cf_length,
+           prefix->cf_local_length_size,
+           prefix->cf_local_extension_size);
+    printf("  cie_id 0x%" DW_PR_DUx " cie_id  cie_id_addr 0x%lx\n",
+           (Dwarf_Unsigned) prefix->cf_cie_id,
+           (long) prefix->cf_cie_id_addr);
+    printf
+        ("  sec ptr 0x%lx sec index %" DW_PR_DSd " sec len 0x%" DW_PR_DUx " sec past end 0x%lx\n",
+         (long) prefix->cf_section_ptr,
+         (Dwarf_Signed) prefix->cf_section_index,
+         (Dwarf_Unsigned) prefix->cf_section_length,
+         (long) prefix->cf_section_ptr + prefix->cf_section_length);
+}
+#endif
+
+
+
+/* Internal function called from various places to create
+   lists of CIEs and FDEs.  Not directly called
+   by consumer code */
+int
+_dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data,
+    Dwarf_Signed * cie_element_count,
+    Dwarf_Fde ** fde_data,
+    Dwarf_Signed * fde_element_count,
+    Dwarf_Small * section_ptr,
+    Dwarf_Unsigned section_index,
+    Dwarf_Unsigned section_length,
+    Dwarf_Unsigned cie_id_value,
+    int use_gnu_cie_calc, Dwarf_Error * error)
+{
+    /* Scans the debug_frame section. */
+    Dwarf_Small *frame_ptr = section_ptr;
+    Dwarf_Small *frame_ptr_end = section_ptr + section_length;
+
+
+
+    /* 
+       New_cie points to the Cie being read, and head_cie_ptr and
+       cur_cie_ptr are used for chaining them up in sequence. 
+       In case cie's are reused aggressively we need tail_cie_ptr
+       to add to the chain.  If we re-use an early cie
+       later on, that does not mean we chain a new cie to the early one,
+       we always chain it to the tail.  */
+    Dwarf_Cie head_cie_ptr = NULL;
+    Dwarf_Cie cur_cie_ptr = NULL;
+    Dwarf_Cie tail_cie_ptr = NULL;
+    Dwarf_Word cie_count = 0;
+
+    /* 
+       Points to a list of contiguous pointers to Dwarf_Cie structures. 
+     */
+    Dwarf_Cie *cie_list_ptr = 0;
+
+
+    /* 
+       New_fde points to the Fde being created, and head_fde_ptr and
+       cur_fde_ptr are used to chain them up. */
+    Dwarf_Fde head_fde_ptr = NULL;
+    Dwarf_Fde cur_fde_ptr = NULL;
+    Dwarf_Word fde_count = 0;
+
+    /* 
+       Points to a list of contiguous pointers to Dwarf_Fde structures. 
+     */
+    Dwarf_Fde *fde_list_ptr = NULL;
+
+    Dwarf_Word i = 0;
+    int res = DW_DLV_ERROR;
+
+    if (frame_ptr == 0) {
+        return DW_DLV_NO_ENTRY;
+    }
+
+    /* We create the fde and cie arrays. Processing each CIE as we come 
+       to it or as an FDE refers to it.  We cannot process 'late' CIEs
+       late as GNU .eh_frame complexities mean we need the whole CIE
+       before we can process the FDE correctly. */
+    while (frame_ptr < frame_ptr_end) {
+
+        struct cie_fde_prefix_s prefix;
+
+        /* First read in the 'common prefix' to figure out what we are
+           to do with this entry. */
+        memset(&prefix, 0, sizeof(prefix));
+        res = dwarf_read_cie_fde_prefix(dbg,
+                                        frame_ptr, section_ptr,
+                                        section_index,
+                                        section_length, &prefix, error);
+        if (res == DW_DLV_ERROR) {
+            dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
+            return res;
+        }
+        if (res == DW_DLV_NO_ENTRY)
+            break;
+        frame_ptr = prefix.cf_addr_after_prefix;
+        if (frame_ptr >= frame_ptr_end) {
+            dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
+            _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
+            return DW_DLV_ERROR;
+
+        }
+
+        if (prefix.cf_cie_id == cie_id_value) {
+            /* This is a CIE.  */
+            Dwarf_Cie cie_ptr_to_use = 0;
+
+            int res = dwarf_find_existing_cie_ptr(prefix.cf_start_addr,
+                                                  cur_cie_ptr,
+                                                  &cie_ptr_to_use,
+                                                  head_cie_ptr);
+
+            if (res == DW_DLV_OK) {
+                cur_cie_ptr = cie_ptr_to_use;
+                /* Ok. Seen already. */
+            } else if (res == DW_DLV_NO_ENTRY) {
+                /* CIE before its FDE in this case. */
+                res = dwarf_create_cie_from_after_start(dbg,
+                                                        &prefix,
+                                                        section_ptr,
+                                                        frame_ptr,
+                                                        cie_count,
+                                                        use_gnu_cie_calc,
+                                                        &cie_ptr_to_use,
+                                                        error);
+                /* ASSERT: res==DW_DLV_NO_ENTRY impossible. */
+                if (res == DW_DLV_ERROR) {
+                    dealloc_fde_cie_list_internal(head_fde_ptr,
+                                                  head_cie_ptr);
+                    return res;
+                }
+                /* ASSERT res != DW_DLV_NO_ENTRY */
+                cie_count++;
+                chain_up_cie(cie_ptr_to_use, &head_cie_ptr,
+                             &tail_cie_ptr);
+                cur_cie_ptr = tail_cie_ptr;
+            } else {            /* res == DW_DLV_ERROR */
+
+                dealloc_fde_cie_list_internal(head_fde_ptr,
+                                              head_cie_ptr);
+                return res;
+            }
+            frame_ptr = cie_ptr_to_use->ci_cie_start +
+                cie_ptr_to_use->ci_length +
+                cie_ptr_to_use->ci_length_size +
+                cie_ptr_to_use->ci_extension_size;
+            continue;
+        } else {
+            /* this is an FDE, Frame Description Entry, see the Dwarf
+               Spec, section 6.4.1 */
+            int res = DW_DLV_ERROR;
+            Dwarf_Cie cie_ptr_to_use = 0;
+            Dwarf_Fde fde_ptr_to_use = 0;
+
+            /* Do not call this twice on one prefix, as
+               prefix.cf_cie_id_addr is altered as a side effect. */
+            Dwarf_Small *cieptr_val =
+                get_cieptr_given_offset(prefix.cf_cie_id,
+                                        use_gnu_cie_calc,
+                                        section_ptr,
+                                        prefix.cf_cie_id_addr);
+
+            res = dwarf_find_existing_cie_ptr(cieptr_val,
+                                              cur_cie_ptr,
+                                              &cie_ptr_to_use,
+                                              head_cie_ptr);
+            if (res == DW_DLV_OK) {
+                cur_cie_ptr = cie_ptr_to_use;
+                /* Ok. Seen CIE already. */
+            } else if (res == DW_DLV_NO_ENTRY) {
+                res = dwarf_create_cie_from_start(dbg,
+                                                  cieptr_val,
+                                                  section_ptr,
+                                                  section_index,
+                                                  section_length,
+                                                  frame_ptr_end,
+                                                  cie_id_value,
+                                                  cie_count,
+                                                  use_gnu_cie_calc,
+                                                  &cie_ptr_to_use,
+                                                  error);
+                if (res == DW_DLV_ERROR) {
+                    dealloc_fde_cie_list_internal(head_fde_ptr,
+                                                  head_cie_ptr);
+                    return res;
+                } else if (res == DW_DLV_NO_ENTRY) {
+                    return res;
+                }
+                ++cie_count;
+                chain_up_cie(cie_ptr_to_use, &head_cie_ptr,
+                             &tail_cie_ptr);
+                cur_cie_ptr = tail_cie_ptr;
+
+            } else {
+                /* DW_DLV_ERROR */
+                return res;
+            }
+
+            res = dwarf_create_fde_from_after_start(dbg,
+                                                    &prefix,
+                                                    section_ptr,
+                                                    frame_ptr,
+                                                    use_gnu_cie_calc,
+                                                    cie_ptr_to_use,
+                                                    &fde_ptr_to_use,
+                                                    error);
+            if (res == DW_DLV_ERROR) {
+                return res;
+            }
+            chain_up_fde(fde_ptr_to_use, &head_fde_ptr, &cur_fde_ptr);
+            fde_count++;
+            /* ASSERT: DW_DLV_OK. */
+            frame_ptr = fde_ptr_to_use->fd_fde_start +
+                fde_ptr_to_use->fd_length +
+                fde_ptr_to_use->fd_length_size +
+                fde_ptr_to_use->fd_extension_size;
+            continue;
+
+        }
+
+    }
+
+    /* Now build list of CIEs from the list. If there are no CIEs
+       there should be no FDEs. */
+    if (cie_count > 0) {
+        cie_list_ptr = (Dwarf_Cie *)
+            _dwarf_get_alloc(dbg, DW_DLA_LIST, cie_count);
+    } else {
+        if(fde_count > 0) {
+            dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
+            _dwarf_error(dbg, error, DW_DLE_ORPHAN_FDE);
+            return DW_DLV_ERROR;
+        }
+        dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
+        return DW_DLV_NO_ENTRY;
+    }
+    if (cie_list_ptr == NULL) {
+        dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return DW_DLV_ERROR;
+    }
+    cur_cie_ptr = head_cie_ptr;
+    for (i = 0; i < cie_count; i++) {
+        *(cie_list_ptr + i) = cur_cie_ptr;
+        cur_cie_ptr = cur_cie_ptr->ci_next;
+    }
+
+
+
+    /* Now build array of FDEs from the list. 
+       With orphan CIEs (meaning no FDEs) lets not return DW_DLV_NO_ENTRY */
+    if (fde_count > 0) {
+        fde_list_ptr = (Dwarf_Fde *)
+            _dwarf_get_alloc(dbg, DW_DLA_LIST, fde_count);
+    }
+
+    /* It is ok if fde_list_ptr is NULL, we just have no fdes. */
+    cur_fde_ptr = head_fde_ptr;
+    for (i = 0; i < fde_count; i++) {
+        *(fde_list_ptr + i) = cur_fde_ptr;
+        cur_fde_ptr = cur_fde_ptr->fd_next;
+    }
+
+
+    /* Return arguments. */
+    *cie_data = cie_list_ptr;
+    *cie_element_count = cie_count;
+
+    *fde_data = fde_list_ptr;
+    *fde_element_count = fde_count;
+    if(use_gnu_cie_calc) {
+      dbg->de_fde_data_eh = fde_list_ptr;
+      dbg->de_fde_count_eh = fde_count;
+      dbg->de_cie_data_eh = cie_list_ptr;
+      dbg->de_cie_count_eh = cie_count;
+    } else {
+      dbg->de_fde_data = fde_list_ptr;
+      dbg->de_fde_count = fde_count;
+      dbg->de_cie_data = cie_list_ptr;
+      dbg->de_cie_count = cie_count;
+    }
+
+    /* Sort the list by the address so that dwarf_get_fde_at_pc() can
+       binary search this list.  */
+    if(fde_count > 0) {
+        qsort((void *) fde_list_ptr, fde_count, sizeof(Dwarf_Ptr),
+           qsort_compare);
+    }
+
+    return (DW_DLV_OK);
+}
+
+/* Internal function, not called by consumer code.
+   'prefix' has accumulated the info up thru the cie-id
+   and now we consume the rest and build a Dwarf_Cie_s structure.
+*/
+int
+dwarf_create_cie_from_after_start(Dwarf_Debug dbg,
+    struct cie_fde_prefix_s *prefix,
+    Dwarf_Small * section_pointer,
+    Dwarf_Small * frame_ptr,
+    Dwarf_Unsigned cie_count,
+    int use_gnu_cie_calc,
+    Dwarf_Cie * cie_ptr_out,
+    Dwarf_Error * error)
+{
+    Dwarf_Cie new_cie = 0;
+
+    /* egcs-1.1.2 .eh_frame uses 0 as the distinguishing id. sgi uses
+       -1 (in .debug_frame). .eh_frame not quite identical to
+       .debug_frame */
+    /* We here default the address size as it is not present
+       in DWARF2 or DWARF3 cie data, below we set it right if
+       it is present. */
+    Dwarf_Half address_size = dbg->de_pointer_size;
+    Dwarf_Small eh_fde_encoding = 0;
+    Dwarf_Small *augmentation = 0;
+    Dwarf_Half segment_size = 0;
+    Dwarf_Sword data_alignment_factor = -1;
+    Dwarf_Word code_alignment_factor = 4;
+    Dwarf_Unsigned return_address_register = 31;
+    int local_length_size = 0;
+    Dwarf_Word leb128_length = 0;
+    Dwarf_Unsigned cie_aug_data_len = 0;
+    Dwarf_Small *cie_aug_data = 0;
+    Dwarf_Addr gnu_personality_handler_addr = 0;
+    unsigned char gnu_personality_handler_encoding = 0;
+    unsigned char gnu_lsda_encoding = 0;
+    unsigned char gnu_fde_begin_encoding = 0;
+
+
+    enum Dwarf_augmentation_type augt = aug_unknown;
+
+
+    /* this is a CIE, Common Information Entry: See the dwarf spec,
+       section 6.4.1 */
+    Dwarf_Small version = *(Dwarf_Small *) frame_ptr;
+
+    frame_ptr++;
+    if (version != DW_CIE_VERSION && version != DW_CIE_VERSION3 &&
+        version != DW_CIE_VERSION4) {
+        _dwarf_error(dbg, error, DW_DLE_FRAME_VERSION_BAD);
+        return (DW_DLV_ERROR);
+    }
+
+    augmentation = frame_ptr;
+    frame_ptr = frame_ptr + strlen((char *) frame_ptr) + 1;
+    augt = _dwarf_get_augmentation_type(dbg,
+                                        augmentation, use_gnu_cie_calc);
+    if (augt == aug_eh) {
+        /* REFERENCED *//* Not used in this instance */
+        Dwarf_Unsigned exception_table_addr;
+
+        /* this is per egcs-1.1.2 as on RH 6.0 */
+        READ_UNALIGNED(dbg, exception_table_addr,
+                       Dwarf_Unsigned, frame_ptr, local_length_size);
+        frame_ptr += local_length_size;
+    }
+    {
+        Dwarf_Unsigned lreg = 0;
+        unsigned long size = 0;
+
+        if( version == DW_CIE_VERSION4) {
+            address_size = *((unsigned char *)frame_ptr);
+            ++frame_ptr;
+            segment_size = *((unsigned char *)frame_ptr);
+            ++frame_ptr;
+        }
+
+        DECODE_LEB128_UWORD(frame_ptr, lreg);
+        code_alignment_factor = (Dwarf_Word) lreg;
+
+        data_alignment_factor =
+            (Dwarf_Sword) _dwarf_decode_s_leb128(frame_ptr,
+                                                 &leb128_length);
+
+        frame_ptr = frame_ptr + leb128_length;
+
+        return_address_register =
+            _dwarf_get_return_address_reg(frame_ptr, version, &size);
+        if (return_address_register > dbg->de_frame_reg_rules_entry_count) {
+            _dwarf_error(dbg, error, DW_DLE_CIE_RET_ADDR_REG_ERROR);
+            return (DW_DLV_ERROR);
+        }
+        frame_ptr += size;
+    }
+    switch (augt) {
+    case aug_empty_string:
+        break;
+    case aug_irix_mti_v1:
+        break;
+    case aug_irix_exception_table:{
+            Dwarf_Unsigned lreg = 0;
+            Dwarf_Word length_of_augmented_fields;
+
+            /* Decode the length of augmented fields. */
+            DECODE_LEB128_UWORD(frame_ptr, lreg);
+            length_of_augmented_fields = (Dwarf_Word) lreg;
+
+
+            /* set the frame_ptr to point at the instruction start. */
+            frame_ptr += length_of_augmented_fields;
+        }
+        break;
+
+    case aug_eh:{
+
+            int err = 0;
+            unsigned long increment = 0;
+
+            if (!use_gnu_cie_calc) {
+                /* This should be impossible. */
+                _dwarf_error(dbg, error,
+                             DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
+                return DW_DLV_ERROR;
+            }
+
+            err = get_gcc_eh_augmentation(dbg, frame_ptr, &increment,
+                                          augt,
+                                          prefix->cf_section_ptr,
+                                          &eh_fde_encoding,
+                                          (char *) augmentation);
+            if (err == DW_DLV_ERROR) {
+                _dwarf_error(dbg, error,
+                             DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
+                return DW_DLV_ERROR;
+            }
+            frame_ptr += increment;
+            break;
+        }
+    case aug_gcc_eh_z:{
+            /* Here we have Augmentation Data Length (uleb128) followed 
+               by Augmentation Data bytes. */
+            int res = DW_DLV_ERROR;
+            Dwarf_Unsigned adlen = 0;
+
+            DECODE_LEB128_UWORD(frame_ptr, adlen);
+            cie_aug_data_len = adlen;
+            cie_aug_data = frame_ptr;
+            res = gnu_aug_encodings(dbg,
+                                    (char *) augmentation,
+                                    cie_aug_data,
+                                    cie_aug_data_len,
+                                    address_size,
+                                    &gnu_personality_handler_encoding,
+                                    &gnu_lsda_encoding,
+                                    &gnu_fde_begin_encoding,
+                                    &gnu_personality_handler_addr);
+            if (res != DW_DLV_OK) {
+                _dwarf_error(dbg, error,
+                             DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
+                return res;
+            }
+
+
+            frame_ptr += adlen;
+            break;
+        }
+    case aug_armcc:
+        break;
+    default:{
+            /* We do not understand the augmentation string. No
+               assumption can be made about any fields other than what
+               we have already read. */
+            frame_ptr = prefix->cf_start_addr +
+                prefix->cf_length + prefix->cf_local_length_size
+                + prefix->cf_local_extension_size;
+            /* FIX -- What are the values of data_alignment_factor,
+               code_alignement_factor, return_address_register and
+               instruction start? They were clearly uninitalized in the 
+               previous version and I am leaving them the same way. */
+            break;
+        }
+    }                           /* End switch on augmentation type. */
+
+    new_cie = (Dwarf_Cie) _dwarf_get_alloc(dbg, DW_DLA_CIE, 1);
+    if (new_cie == NULL) {
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
+    }
+
+    new_cie->ci_cie_version_number = version;
+    new_cie->ci_initial_table = NULL;
+    new_cie->ci_length = (Dwarf_Word) prefix->cf_length;
+    new_cie->ci_length_size = prefix->cf_local_length_size;
+    new_cie->ci_extension_size = prefix->cf_local_extension_size;
+    new_cie->ci_augmentation = (char *) augmentation;
+
+    new_cie->ci_data_alignment_factor =
+        (Dwarf_Sbyte) data_alignment_factor;
+    new_cie->ci_code_alignment_factor =
+        (Dwarf_Small) code_alignment_factor;
+    new_cie->ci_return_address_register = return_address_register;
+    new_cie->ci_cie_start = prefix->cf_start_addr;
+    new_cie->ci_cie_instr_start = frame_ptr;
+    new_cie->ci_dbg = dbg;
+    new_cie->ci_augmentation_type = augt;
+    new_cie->ci_gnu_eh_augmentation_len = cie_aug_data_len;
+    new_cie->ci_gnu_eh_augmentation_bytes = cie_aug_data;
+    new_cie->ci_gnu_personality_handler_encoding =
+        gnu_personality_handler_encoding;
+    new_cie->ci_gnu_personality_handler_addr =
+        gnu_personality_handler_addr;
+    new_cie->ci_gnu_lsda_encoding = gnu_lsda_encoding;
+    new_cie->ci_gnu_fde_begin_encoding = gnu_fde_begin_encoding;
+
+    new_cie->ci_index = cie_count;
+    new_cie->ci_section_ptr = prefix->cf_section_ptr;
+    /* The Following new in DWARF4 */
+    new_cie->ci_address_size = address_size;
+    new_cie->ci_segment_size = segment_size;
+    validate_length(dbg,new_cie,new_cie->ci_length,
+        new_cie->ci_length_size, new_cie->ci_extension_size,
+        new_cie->ci_section_ptr,
+        new_cie->ci_cie_start,"cie");
+
+    *cie_ptr_out = new_cie;
+    return DW_DLV_OK;
+
+}
+
+
+/* Internal function, not called by consumer code.
+   'prefix' has accumulated the info up thru the cie-id
+   and now we consume the rest and build a Dwarf_Fde_s structure.
+*/
+
+int
+dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
+    struct cie_fde_prefix_s *prefix,
+    Dwarf_Small * section_pointer,
+    Dwarf_Small * frame_ptr,
+    int use_gnu_cie_calc,
+    Dwarf_Cie cie_ptr_in,
+    Dwarf_Fde * fde_ptr_out,
+    Dwarf_Error * error)
+{
+    Dwarf_Fde new_fde = 0;
+    Dwarf_Cie cieptr = cie_ptr_in;
+    Dwarf_Small *saved_frame_ptr = 0;
+
+    Dwarf_Small *initloc = frame_ptr;
+    Dwarf_Signed offset_into_exception_tables
+        /* must be min dwarf_sfixed in size */
+        = (Dwarf_Signed) DW_DLX_NO_EH_OFFSET;
+    Dwarf_Small *fde_aug_data = 0;
+    Dwarf_Unsigned fde_aug_data_len = 0;
+    Dwarf_Addr cie_base_offset = prefix->cf_cie_id;
+    Dwarf_Addr initial_location = 0;    /* must be min de_pointer_size
+                                           bytes in size */
+    Dwarf_Addr address_range = 0;       /* must be min de_pointer_size
+                                           bytes in size */
+    Dwarf_Half address_size = cie_ptr_in->ci_address_size;
+
+    enum Dwarf_augmentation_type augt = cieptr->ci_augmentation_type;
+
+    if (augt == aug_gcc_eh_z) {
+        /* If z augmentation this is eh_frame, and initial_location and 
+           address_range in the FDE are read according to the CIE
+           augmentation string instructions.  */
+
+        {
+            Dwarf_Small *fp_updated = 0;
+            int res = read_encoded_ptr(dbg,
+                section_pointer,
+                frame_ptr,
+                cieptr-> ci_gnu_fde_begin_encoding,
+                address_size,
+                &initial_location,
+                &fp_updated);
+            if (res != DW_DLV_OK) {
+                _dwarf_error(dbg, error,
+                             DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
+                return DW_DLV_ERROR;
+            }
+            frame_ptr = fp_updated;
+            /* For the address-range it makes no sense to be
+               pc-relative, so we turn it off with a section_pointer of 
+               NULL. Masking off DW_EH_PE_pcrel from the
+               ci_gnu_fde_begin_encoding in this call would also work
+               to turn off DW_EH_PE_pcrel. */
+            res = read_encoded_ptr(dbg, (Dwarf_Small *) NULL,
+                                   frame_ptr,
+                                   cieptr->ci_gnu_fde_begin_encoding,
+                                   address_size,
+                                   &address_range, &fp_updated);
+            if (res != DW_DLV_OK) {
+                _dwarf_error(dbg, error,
+                             DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
+                return DW_DLV_ERROR;
+            }
+            frame_ptr = fp_updated;
+        }
+        {
+            Dwarf_Unsigned adlen = 0;
+
+            DECODE_LEB128_UWORD(frame_ptr, adlen);
+            fde_aug_data_len = adlen;
+            fde_aug_data = frame_ptr;
+            frame_ptr += adlen;
+        }
+
+    } else {
+        READ_UNALIGNED(dbg, initial_location, Dwarf_Addr,
+                       frame_ptr, address_size);
+        frame_ptr += address_size;
+
+        READ_UNALIGNED(dbg, address_range, Dwarf_Addr,
+                       frame_ptr, address_size);
+        frame_ptr += address_size;
+    }
+
+
+
+
+
+    switch (augt) {
+    case aug_irix_mti_v1:
+    case aug_empty_string:
+        break;
+    case aug_irix_exception_table:{
+            Dwarf_Unsigned lreg = 0;
+            Dwarf_Word length_of_augmented_fields = 0;
+
+            DECODE_LEB128_UWORD(frame_ptr, lreg);
+            length_of_augmented_fields = (Dwarf_Word) lreg;
+
+            saved_frame_ptr = frame_ptr;
+            /* The first word is an offset into exception tables.
+               Defined as a 32bit offset even for CC -64. */
+            READ_UNALIGNED(dbg, offset_into_exception_tables,
+                           Dwarf_Addr, frame_ptr, sizeof(Dwarf_sfixed));
+            SIGN_EXTEND(offset_into_exception_tables,
+                        sizeof(Dwarf_sfixed));
+            frame_ptr = saved_frame_ptr + length_of_augmented_fields;
+        }
+        break;
+    case aug_eh:{
+            Dwarf_Unsigned eh_table_value = 0;
+
+            if (!use_gnu_cie_calc) {
+                /* This should be impossible. */
+                _dwarf_error(dbg, error,
+                             DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
+                return DW_DLV_ERROR;
+            }
+
+            /* gnu eh fde case. we do not need to do anything */
+             /*REFERENCED*/     /* Not used in this instance of the
+                                   macro */
+                READ_UNALIGNED(dbg, eh_table_value,
+                               Dwarf_Unsigned, frame_ptr,
+                               address_size);
+            frame_ptr += address_size;
+        }
+        break;
+
+    case aug_gcc_eh_z:{
+            /* The Augmentation Data Length is here, followed by the
+               Augmentation Data bytes themselves. */
+        }
+        break;
+    case aug_armcc:
+        break;
+    case aug_past_last:
+        break;
+    case aug_unknown:
+        _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
+        return DW_DLV_ERROR;
+    }                           /* End switch on augmentation type */
+    new_fde = (Dwarf_Fde) _dwarf_get_alloc(dbg, DW_DLA_FDE, 1);
+    if (new_fde == NULL) {
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
+    }
+
+    new_fde->fd_length = prefix->cf_length;
+    new_fde->fd_length_size = prefix->cf_local_length_size;
+    new_fde->fd_extension_size = prefix->cf_local_extension_size;
+    new_fde->fd_is_eh = use_gnu_cie_calc;
+    new_fde->fd_cie_offset = cie_base_offset;
+    new_fde->fd_cie_index = cieptr->ci_index;
+    new_fde->fd_cie = cieptr;
+    new_fde->fd_initial_location = initial_location;
+    new_fde->fd_initial_loc_pos = initloc;
+    new_fde->fd_address_range = address_range;
+    new_fde->fd_fde_start = prefix->cf_start_addr;
+    new_fde->fd_fde_instr_start = frame_ptr;
+    new_fde->fd_dbg = dbg;
+    new_fde->fd_offset_into_exception_tables =
+        offset_into_exception_tables;
+
+    new_fde->fd_section_ptr = prefix->cf_section_ptr;
+    new_fde->fd_section_index = prefix->cf_section_index;
+    new_fde->fd_section_length = prefix->cf_section_length;
+
+    new_fde->fd_gnu_eh_augmentation_bytes = fde_aug_data;
+    new_fde->fd_gnu_eh_augmentation_len = fde_aug_data_len;
+    validate_length(dbg,cieptr,new_fde->fd_length,
+        new_fde->fd_length_size, new_fde->fd_extension_size,
+        new_fde->fd_section_ptr,new_fde->fd_fde_start,"fde");
+
+
+    *fde_ptr_out = new_fde;
+    return DW_DLV_OK;
+}
+
+/* called by qsort to compare FDE entries.
+   Consumer code expects the array of FDE pointers to be in address order.
+*/
+static int
+qsort_compare(const void *elem1, const void *elem2)
+{
+    Dwarf_Fde fde1 = *(Dwarf_Fde *) elem1;
+    Dwarf_Fde fde2 = *(Dwarf_Fde *) elem2;
+    Dwarf_Addr addr1 = fde1->fd_initial_location;
+    Dwarf_Addr addr2 = fde2->fd_initial_location;
+
+    if (addr1 < addr2) {
+        return -1;
+    } else if (addr1 > addr2) {
+        return 1;
+    }
+    return 0;
+}
+
+
+/* Read in the common cie/fde prefix, including reading
+ * the cie-value which shows which this is: cie or fde.
+ * */
+int
+dwarf_read_cie_fde_prefix(Dwarf_Debug dbg,
+                          Dwarf_Small * frame_ptr_in,
+                          Dwarf_Small * section_ptr_in,
+                          Dwarf_Unsigned section_index_in,
+                          Dwarf_Unsigned section_length_in,
+                          struct cie_fde_prefix_s *data_out,
+                          Dwarf_Error * error)
+{
+    Dwarf_Unsigned length = 0;
+    int local_length_size = 0;
+    int local_extension_size = 0;
+    Dwarf_Small *frame_ptr = frame_ptr_in;
+    Dwarf_Small *cie_ptr_addr = 0;
+    Dwarf_Unsigned cie_id = 0;
+
+    /* READ_AREA_LENGTH updates frame_ptr for consumed bytes */
+    READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
+                     frame_ptr, local_length_size,
+                     local_extension_size);
+
+    if (length == 0) {
+        /* nul bytes at end of section, seen at end of egcs eh_frame
+           sections (in a.out). Take this as meaning no more CIE/FDE
+           data. We should be very close to end of section. */
+        return DW_DLV_NO_ENTRY;
+    }
+
+    cie_ptr_addr = frame_ptr;
+    READ_UNALIGNED(dbg, cie_id, Dwarf_Unsigned,
+                   frame_ptr, local_length_size);
+    SIGN_EXTEND(cie_id, local_length_size);
+    frame_ptr += local_length_size;
+
+    data_out->cf_start_addr = frame_ptr_in;
+    data_out->cf_addr_after_prefix = frame_ptr;
+
+    data_out->cf_length = length;
+    data_out->cf_local_length_size = local_length_size;
+    data_out->cf_local_extension_size = local_extension_size;
+    data_out->cf_cie_id = cie_id;
+    data_out->cf_cie_id_addr = cie_ptr_addr;
+    data_out->cf_section_ptr = section_ptr_in;
+    data_out->cf_section_index = section_index_in;
+    data_out->cf_section_length = section_length_in;
+    return DW_DLV_OK;
+}
+
+/* On various errors previously-allocated CIEs and FDEs
+   must be cleaned up.
+   This helps avoid leaks in case of errors.
+*/
+static void
+dealloc_fde_cie_list_internal(Dwarf_Fde head_fde_ptr,
+    Dwarf_Cie head_cie_ptr)
+{
+    Dwarf_Fde curfde = 0;
+    Dwarf_Cie curcie = 0;
+    Dwarf_Fde nextfde = 0;
+    Dwarf_Cie nextcie = 0;
+
+    for (curfde = head_fde_ptr; curfde; curfde = nextfde) {
+        nextfde = curfde->fd_next;
+        dwarf_dealloc(curfde->fd_dbg, curfde, DW_DLA_FDE);
+    }
+    for (curcie = head_cie_ptr; curcie; curcie = nextcie) {
+        Dwarf_Frame frame = curcie->ci_initial_table;
+
+        nextcie = curcie->ci_next;
+        if (frame)
+            dwarf_dealloc(curcie->ci_dbg, frame, DW_DLA_FRAME);
+        dwarf_dealloc(curcie->ci_dbg, curcie, DW_DLA_CIE);
+    }
+}
+
+/* Find the cie whose id value is given: the id
+ * value is, per DWARF2/3, an offset in the section. 
+ * For .debug_frame, zero is a legal offset. For
+ * GNU .eh_frame it is not a legal offset.
+ * 'cie_ptr' is a pointer into our section, not an offset. */
+static int
+dwarf_find_existing_cie_ptr(Dwarf_Small * cie_ptr,
+                            Dwarf_Cie cur_cie_ptr,
+                            Dwarf_Cie * cie_ptr_to_use_out,
+                            Dwarf_Cie head_cie_ptr)
+{
+    Dwarf_Cie next = 0;
+
+    if (cur_cie_ptr && cie_ptr == cur_cie_ptr->ci_cie_start) {
+        /* Usually, we use the same cie again and again. */
+        *cie_ptr_to_use_out = cur_cie_ptr;
+        return DW_DLV_OK;
+    }
+    for (next = head_cie_ptr; next; next = next->ci_next) {
+        if (cie_ptr == next->ci_cie_start) {
+            *cie_ptr_to_use_out = next;
+            return DW_DLV_OK;
+        }
+    }
+    return DW_DLV_NO_ENTRY;
+}
+
+
+/* We have a valid cie_ptr_val that has not been
+ * turned into an internal Cie yet. Do so now.
+ * Returns DW_DLV_OK or DW_DLV_ERROR, never
+ * DW_DLV_NO_ENTRY.
+
+ 'section_ptr'    - Points to first byte of section data.
+ 'section_length' - Length of the section, in bytes.
+ 'frame_ptr_end'  - Points 1-past last byte of section data.
+ * */
+static int
+dwarf_create_cie_from_start(Dwarf_Debug dbg,
+    Dwarf_Small * cie_ptr_val,
+    Dwarf_Small * section_ptr,
+    Dwarf_Unsigned section_index,
+    Dwarf_Unsigned section_length,
+    Dwarf_Small * frame_ptr_end,
+    Dwarf_Unsigned cie_id_value,
+    Dwarf_Unsigned cie_count,
+    int use_gnu_cie_calc,
+    Dwarf_Cie * cie_ptr_to_use_out,
+    Dwarf_Error * error)
+{
+    struct cie_fde_prefix_s prefix;
+    int res = DW_DLV_ERROR;
+    Dwarf_Small *frame_ptr = cie_ptr_val;
+
+    if (frame_ptr < section_ptr || frame_ptr > frame_ptr_end) {
+        _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
+        return DW_DLV_ERROR;
+    }
+    /* First read in the 'common prefix' to figure out what * we are to 
+       do with this entry. If it is not a cie * we are in big trouble. */
+    memset(&prefix, 0, sizeof(prefix));
+    res = dwarf_read_cie_fde_prefix(dbg, frame_ptr, section_ptr,
+        section_index, section_length,
+        &prefix, error);
+    if (res == DW_DLV_ERROR) {
+        return res;
+    }
+    if (res == DW_DLV_NO_ENTRY) {
+        /* error. */
+        _dwarf_error(dbg, error, DW_DLE_FRAME_CIE_DECODE_ERROR);
+        return DW_DLV_ERROR;
+
+    }
+
+    if (prefix.cf_cie_id != cie_id_value) {
+        _dwarf_error(dbg, error, DW_DLE_FRAME_CIE_DECODE_ERROR);
+        return DW_DLV_ERROR;
+    }
+    frame_ptr = prefix.cf_addr_after_prefix;
+    res = dwarf_create_cie_from_after_start(dbg,
+        &prefix,
+        section_ptr,
+        frame_ptr,
+        cie_count,
+        use_gnu_cie_calc,
+        cie_ptr_to_use_out, error);
+    return res;
+
+}
+
+
+/* This is for gnu eh frames, the 'z' case.
+   We find the letter involved
+   Return the augmentation character and, if applicable,
+   the personality routine address.
+
+   personality_routine_out - 
+        if 'P' is augchar, is personality handler addr. 
+        Otherwise is not set.
+   aug_data  - if 'P' points  to data space of the
+   aug_data_len - length of areas aug_data points to.
+   
+*/
+#if 0
+/* For debugging only. */
+void
+dump_bytes(Dwarf_Small * start, long len)
+{
+    Dwarf_Small *end = start + len;
+    Dwarf_Small *cur = start;
+
+    for (; cur < end; cur++) {
+        printf(" byte %d, data %02x\n", (int) (cur - start), *cur);
+    }
+
+}
+#endif
+static int
+gnu_aug_encodings(Dwarf_Debug dbg, char *augmentation,
+    Dwarf_Small * aug_data, Dwarf_Unsigned aug_data_len,
+    Dwarf_Half address_size,
+    unsigned char *pers_hand_enc_out,
+    unsigned char *lsda_enc_out,
+    unsigned char *fde_begin_enc_out,
+    Dwarf_Addr * gnu_pers_addr_out)
+{
+    char *nc = 0;
+    Dwarf_Small *cur_aug_p = aug_data;
+    Dwarf_Small *end_aug_p = aug_data + aug_data_len;
+
+    for (nc = augmentation; *nc; ++nc) {
+        char c = *nc;
+
+        switch (c) {
+        case 'z':
+            /* Means that the augmentation data is present. */
+            continue;
+
+        case 'S':
+            /* Indicates this is a signal stack frame.  Debuggers have to do 
+               special handling.  We don't need to do more than print this flag at 
+               the right time, though (see dwarfdump where it prints the augmentation
+               string). 
+               A signal stack frame (in some OS's) can only be
+               unwound (backtraced) by knowing it is a signal stack frame 
+               (perhaps by noticing the name of the function for the stack frame
+               if the name can be found somehow) and figuring
+               out (or knowing) how the kernel and libc pushed a structure
+               onto the stack and loading registers from that structure.
+               Totally different from normal stack unwinding.
+               This flag gives an unwinder a big leg up by decoupling the
+               'hint: this is a stack frame' from knowledge like
+               the function name (the name might be unavailable at unwind time).
+            */
+            break;
+            
+        case 'L':
+            if (cur_aug_p > end_aug_p) {
+                return DW_DLV_ERROR;
+            }
+            *lsda_enc_out = *(unsigned char *) cur_aug_p;
+            ++cur_aug_p;
+            break;
+        case 'R':
+            /* Followed by a one byte argument giving the
+               pointer encoding for the address pointers in the fde. */
+            if (cur_aug_p >= end_aug_p) {
+                return DW_DLV_ERROR;
+            }
+            *fde_begin_enc_out = *(unsigned char *) cur_aug_p;
+            ++cur_aug_p;
+            break;
+        case 'P':{
+                int res = DW_DLV_ERROR;
+                Dwarf_Small *updated_aug_p = 0;
+                unsigned char encoding = 0;
+
+                if (cur_aug_p >= end_aug_p) {
+                    return DW_DLV_ERROR;
+                }
+                encoding = *(unsigned char *) cur_aug_p;
+                *pers_hand_enc_out = encoding;
+                ++cur_aug_p;
+                if (cur_aug_p > end_aug_p) {
+                    return DW_DLV_ERROR;
+                }
+                /* DW_EH_PE_pcrel makes no sense here, so we turn it
+                   off via a section pointer of NULL. */
+                res = read_encoded_ptr(dbg,
+                                       (Dwarf_Small *) NULL,
+                                       cur_aug_p,
+                                       encoding,
+                                       address_size,
+                                       gnu_pers_addr_out,
+                                       &updated_aug_p);
+                if (res != DW_DLV_OK) {
+                    return res;
+                }
+                cur_aug_p = updated_aug_p;
+                if (cur_aug_p > end_aug_p) {
+                    return DW_DLV_ERROR;
+                }
+            }
+            break;
+        default:
+            return DW_DLV_ERROR;
+
+        }
+    }
+
+    return DW_DLV_OK;
+}
+
+/* Given augmentation character (the encoding) giving the
+address format, read the address from input_field
+and return an incremented value 1 past the input bytes of the
+address.
+Push the address read back thru the *addr pointer.
+See LSB (Linux Standar Base)  exception handling documents. 
+*/
+static int
+read_encoded_ptr(Dwarf_Debug dbg,
+    Dwarf_Small * section_pointer,
+    Dwarf_Small * input_field,
+    int gnu_encoding,
+    Dwarf_Half address_size,
+    Dwarf_Unsigned * addr,
+    Dwarf_Small ** input_field_updated)
+{
+    Dwarf_Word length = 0;
+    int value_type = gnu_encoding & 0xf;
+    Dwarf_Small *input_field_original = input_field;
+
+    if (gnu_encoding == 0xff) {
+        /* There is no data here. */
+
+        *addr = 0;
+        *input_field_updated = input_field;
+        /* Should we return DW_DLV_NO_ENTRY? */
+        return DW_DLV_OK;
+    }
+    switch (value_type) {
+    case DW_EH_PE_absptr:{
+            /* value_type is zero. Treat as pointer size of the object. 
+             */
+            Dwarf_Unsigned ret_value = 0;
+
+            READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+                           input_field, address_size);
+            *addr = ret_value;
+            *input_field_updated = input_field + address_size;
+        }
+        break;
+    case DW_EH_PE_uleb128:{
+            Dwarf_Unsigned val = _dwarf_decode_u_leb128(input_field,
+                                                        &length);
+
+            *addr = val;
+            *input_field_updated = input_field + length;
+        }
+        break;
+    case DW_EH_PE_udata2:{
+            Dwarf_Unsigned ret_value = 0;
+
+            READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+                           input_field, 2);
+            *addr = ret_value;
+            *input_field_updated = input_field + 2;
+        }
+        break;
+
+    case DW_EH_PE_udata4:{
+
+            Dwarf_Unsigned ret_value = 0;
+
+            /* ASSERT: sizeof(Dwarf_ufixed) == 4 */
+            READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+                           input_field, sizeof(Dwarf_ufixed));
+            *addr = ret_value;
+            *input_field_updated = input_field + sizeof(Dwarf_ufixed);
+        }
+        break;
+
+    case DW_EH_PE_udata8:{
+            Dwarf_Unsigned ret_value = 0;
+
+            /* ASSERT: sizeof(Dwarf_Unsigned) == 8 */
+            READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+                           input_field, sizeof(Dwarf_Unsigned));
+            *addr = ret_value;
+            *input_field_updated = input_field + sizeof(Dwarf_Unsigned);
+        }
+        break;
+
+    case DW_EH_PE_sleb128:{
+            Dwarf_Signed val = _dwarf_decode_s_leb128(input_field,
+                                                      &length);
+
+            *addr = (Dwarf_Unsigned) val;
+            *input_field_updated = input_field + length;
+        }
+        break;
+    case DW_EH_PE_sdata2:{
+            Dwarf_Unsigned val = 0;
+
+            READ_UNALIGNED(dbg, val, Dwarf_Unsigned, input_field, 2);
+            SIGN_EXTEND(val, 2);
+            *addr = (Dwarf_Unsigned) val;
+            *input_field_updated = input_field + 2;
+        }
+        break;
+
+    case DW_EH_PE_sdata4:{
+            Dwarf_Unsigned val = 0;
+
+            /* ASSERT: sizeof(Dwarf_ufixed) == 4 */
+            READ_UNALIGNED(dbg, val,
+                           Dwarf_Unsigned, input_field,
+                           sizeof(Dwarf_ufixed));
+            SIGN_EXTEND(val, sizeof(Dwarf_ufixed));
+            *addr = (Dwarf_Unsigned) val;
+            *input_field_updated = input_field + sizeof(Dwarf_ufixed);
+        }
+        break;
+    case DW_EH_PE_sdata8:{
+            Dwarf_Unsigned val = 0;
+
+            /* ASSERT: sizeof(Dwarf_Unsigned) == 8 */
+            READ_UNALIGNED(dbg, val,
+                           Dwarf_Unsigned, input_field,
+                           sizeof(Dwarf_Unsigned));
+            *addr = (Dwarf_Unsigned) val;
+            *input_field_updated = input_field + sizeof(Dwarf_Unsigned);
+        }
+        break;
+    default:
+        return DW_DLV_ERROR;
+
+    };
+    /* The ELF ABI for gnu does not document the meaning of
+       DW_EH_PE_pcrel, which is awkward.  It apparently means the value 
+       we got above is pc-relative (meaning section-relative), so we
+       adjust the value. Section_pointer may be null if it is known
+       DW_EH_PE_pcrel cannot apply, such as for .debug_frame or for an
+       address-range value. */
+    if (section_pointer && ((gnu_encoding & 0x70) == DW_EH_PE_pcrel)) {
+        /* Address (*addr) above is pc relative with respect to a
+           section. Add to the offset the base address (from elf) of
+           section and the distance of the field we are reading from
+           the section-beginning to get the actual address. */
+        /* ASSERT: input_field_original >= section_pointer */
+        Dwarf_Unsigned distance =
+            input_field_original - section_pointer;
+        *addr += dbg->de_debug_frame_eh_gnu.dss_addr + distance;
+    }
+
+    return DW_DLV_OK;
+}
+
+
+
+
+/* 
+        All augmentation string checking done here now.
+
+        For .eh_frame, gcc from 3.3 uses the z style, earlier used
+        only "eh" as augmentation.  We don't yet handle 
+        decoding .eh_frame with the z style extensions like L P. 
+
+        These are nasty heuristics, but then that's life
+        as augmentations are implementation specific.
+*/
+/* ARGSUSED */
+enum Dwarf_augmentation_type
+_dwarf_get_augmentation_type(Dwarf_Debug dbg,
+    Dwarf_Small * augmentation_string,
+    int is_gcc_eh_frame)
+{
+    enum Dwarf_augmentation_type t = aug_unknown;
+    char *ag_string = (char *) augmentation_string;
+
+    if (ag_string[0] == 0) {
+        /* Empty string. We'll just guess that we know what this means: 
+           standard dwarf2/3 with no implementation-defined fields.  */
+        t = aug_empty_string;
+    } else if (strcmp(ag_string, DW_DEBUG_FRAME_AUGMENTER_STRING) == 0) {
+        /* The string is "mti v1". Used internally at SGI, probably
+           never shipped. Replaced by "z". Treat like 'nothing
+           special'.  */
+        t = aug_irix_mti_v1;
+    } else if (ag_string[0] == 'z') {
+        /* If it's IRIX cc, z means aug_irix_exception_table. z1 z2
+           were designed as for IRIX CC, but never implemented */
+        /* If it's gcc, z may be any of several things. "z" or z
+           followed optionally followed by one or more of L R P, each
+           of which means a value may be present. Should be in eh_frame 
+           only, I think. */
+        if (is_gcc_eh_frame) {
+            t = aug_gcc_eh_z;
+        } else if (ag_string[1] == 0) {
+            /* This is the normal IRIX C++ case, where there is an
+               offset into a table in each fde. The table being for
+               IRIX CC exception handling.  */
+            /* DW_CIE_AUGMENTER_STRING_V0 "z" */
+            t = aug_irix_exception_table;
+        }                       /* Else unknown. */
+    } else if (strncmp(ag_string, "eh", 2) == 0) {
+        /* gcc .eh_frame augmentation for egcs and gcc 2.x, at least
+           for x86. */
+        t = aug_eh;
+    } else if (strcmp(ag_string, "armcc+") == 0) {
+        /* Arm  uses this string to mean a bug in
+           in Arm compilers was fixed, changing to the standard
+           calculation of the CFA.  See
+           http://sourceware.org/ml/gdb-patches/2006-12/msg00249.html
+           for details. */
+        t = aug_armcc;
+    } else {
+
+    }
+    return t;
+}
+
+/* Using augmentation, and version 
+   read in the augmentation data for GNU eh. 
+
+   Return DW_DLV_OK if we succeeded,
+   DW_DLV_ERR if we fail.
+
+   On success, update  'size_of_augmentation_data' with
+   the length of the fields that are part of augmentation (so the
+   caller can increment frame_ptr appropriately).
+
+   'frame_ptr' points within section.
+   'section_pointer' points to section base address in memory.
+*/
+/* ARGSUSED */
+static int
+get_gcc_eh_augmentation(Dwarf_Debug dbg, Dwarf_Small * frame_ptr,
+    unsigned long *size_of_augmentation_data,
+    enum Dwarf_augmentation_type augtype,
+    Dwarf_Small * section_pointer,
+    Dwarf_Small * fde_eh_encoding_out,
+    char *augmentation)
+{
+    char *suffix = 0;
+    unsigned long augdata_size = 0;
+
+    if (augtype == aug_gcc_eh_z) {
+        /* Has leading 'z'. */
+        Dwarf_Word leb128_length = 0;
+
+        /* Dwarf_Unsigned eh_value = */
+        _dwarf_decode_u_leb128(frame_ptr, &leb128_length);
+        augdata_size += leb128_length;
+        frame_ptr += leb128_length;
+        suffix = augmentation + 1;
+    } else {
+        /* Prefix is 'eh'.  As in gcc 3.2. No suffix present
+           apparently. */
+        suffix = augmentation + 2;
+    }
+    for (; *suffix; ++suffix) {
+        /* We have no idea what this is as yet. Some extensions beyond
+           dwarf exist which we do not yet handle. */
+        return DW_DLV_ERROR;
+
+    }
+
+    *size_of_augmentation_data = augdata_size;
+    return DW_DLV_OK;
+}
+
+
+/* Make the 'cie_id_addr' consistent across .debug_frame and .eh_frame.
+   Calculate a pointer into section bytes given a cie_id, which is
+   trivial for .debug_frame, but a bit more work for .eh_frame.  
+*/
+static Dwarf_Small *
+get_cieptr_given_offset(Dwarf_Unsigned cie_id_value,
+    int use_gnu_cie_calc,
+    Dwarf_Small * section_ptr,
+    Dwarf_Small * cie_id_addr)
+{
+    Dwarf_Small *cieptr = 0;
+
+    if (use_gnu_cie_calc) {
+        /* cie_id value is offset, in section, of the cie_id itself, to 
+           use vm ptr of the value, less the value, to get to the cie
+           itself. In addition, munge *cie_id_addr to look *as if* it
+           was from real dwarf. */
+        cieptr = (Dwarf_Small *)(uintptr_t)
+          ((Dwarf_Unsigned)(uintptr_t)cie_id_addr) -
+          ((Dwarf_Unsigned) cie_id_value);
+    } else {
+        /* Traditional dwarf section offset is in cie_id */
+        cieptr = (section_ptr + cie_id_value);
+    }
+    return cieptr;
+}
+
+/* To properly release all spaced used.
+   Earlier approaches (before July 15, 2005)
+   letting client do the dealloc directly left
+   some data allocated.
+   This is directly called by consumer code.
+*/
+void
+dwarf_fde_cie_list_dealloc(Dwarf_Debug dbg,
+    Dwarf_Cie * cie_data,
+    Dwarf_Signed cie_element_count,
+    Dwarf_Fde * fde_data,
+    Dwarf_Signed fde_element_count)
+{
+    Dwarf_Signed i = 0;
+
+    for (i = 0; i < cie_element_count; ++i) {
+        Dwarf_Frame frame = cie_data[i]->ci_initial_table;
+
+        if (frame)
+            dwarf_dealloc(dbg, frame, DW_DLA_FRAME);
+        dwarf_dealloc(dbg, cie_data[i], DW_DLA_CIE);
+    }
+    for (i = 0; i < fde_element_count; ++i) {
+        dwarf_dealloc(dbg, fde_data[i], DW_DLA_FDE);
+    }
+    if (cie_data)
+        dwarf_dealloc(dbg, cie_data, DW_DLA_LIST);
+    if (fde_data)
+        dwarf_dealloc(dbg, fde_data, DW_DLA_LIST);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_frame3.c	Sun May 22 03:13:22 2011 +0100
@@ -0,0 +1,290 @@
+/*
+
+  Copyright (C) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2009-2010 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "dwarf_frame.h"
+#include "dwarf_arange.h" /* using Arange as a way to build a list */
+
+/*
+    Used by rqs (an IRIX application).  
+    Not needed except for that one application.
+    Should be moved to its own source file since
+    it is so rarely needed.
+    Returns DW_DLV_OK if returns the arrays.
+    Returns DW_DLV_NO_ENTRY if no section. ?? (How do I tell?)
+    Returns DW_DLV_ERROR if there is an error.
+
+    Uses DW_FRAME_CFA_COL because IRIX is only DWARF2
+    and that is what IRIX compilers and compatible
+    compilers support on IRIX.
+*/
+int
+_dwarf_frame_address_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrlist,
+                             Dwarf_Off ** offsetlist,
+                             Dwarf_Signed * returncount,
+                             Dwarf_Error * err)
+{
+    int retval = DW_DLV_OK;
+    int res = DW_DLV_ERROR;
+    Dwarf_Cie *cie_data;
+    Dwarf_Signed cie_count;
+    Dwarf_Fde *fde_data;
+    Dwarf_Signed fde_count;
+    Dwarf_Signed i;
+    Dwarf_Frame_Op *frame_inst;
+    Dwarf_Fde fdep;
+    Dwarf_Cie ciep;
+    Dwarf_Chain curr_chain = 0;
+    Dwarf_Chain head_chain = 0;
+    Dwarf_Chain prev_chain = 0;
+    Dwarf_Arange arange;
+    Dwarf_Unsigned arange_count = 0;
+    Dwarf_Addr *arange_addrs = 0;
+    Dwarf_Off *arange_offsets = 0;
+
+    res = dwarf_get_fde_list(dbg, &cie_data, &cie_count,
+                             &fde_data, &fde_count, err);
+    if (res != DW_DLV_OK) {
+        return res;
+    }
+
+    res = _dwarf_load_section(dbg, &dbg->de_debug_frame, err);
+    if (res != DW_DLV_OK) {
+        return res;
+    }
+
+    for (i = 0; i < cie_count; i++) {
+        Dwarf_Off instoff = 0;
+        Dwarf_Signed initial_instructions_length = 0;
+        Dwarf_Small *instr_end = 0;
+        Dwarf_Sword icount = 0;
+        int j = 0;
+        int dw_err;
+
+        ciep = cie_data[i];
+        instoff = ciep->ci_cie_instr_start - dbg->de_debug_frame.dss_data;
+        initial_instructions_length = ciep->ci_length +
+            ciep->ci_length_size + ciep->ci_extension_size -
+            (ciep->ci_cie_instr_start - ciep->ci_cie_start);
+        instr_end = ciep->ci_cie_instr_start +
+            initial_instructions_length;
+        res = _dwarf_exec_frame_instr( /* make_instr */ true,
+            &frame_inst,
+            /* search_pc= */ false,
+            /* search_pc_val= */ 0,
+            /* location */ 0,
+            ciep->ci_cie_instr_start,
+            instr_end,
+            /* Dwarf_frame= */ 0,
+            /* cie= */ 0,
+            dbg,
+            DW_FRAME_CFA_COL,
+            &icount, &dw_err);
+        if (res == DW_DLV_ERROR) {
+            _dwarf_error(dbg, err, dw_err);
+            return (res);
+        } else if (res == DW_DLV_NO_ENTRY) {
+            continue;
+        }
+
+        for (j = 0; j < icount; ++j) {
+            Dwarf_Frame_Op *finst = frame_inst + j;
+
+            if (finst->fp_base_op == 0 && finst->fp_extended_op == 1) {
+                /* is DW_CFA_set_loc */
+                Dwarf_Addr add = (Dwarf_Addr) finst->fp_offset;
+                Dwarf_Off off = finst->fp_instr_offset + instoff;
+
+                arange = (Dwarf_Arange)
+                    _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
+                if (arange == NULL) {
+                    _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+                    return (DW_DLV_ERROR);
+                }
+                arange->ar_address = add;
+                arange->ar_info_offset = off;
+                arange_count++;
+                curr_chain = (Dwarf_Chain)
+                    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+                if (curr_chain == NULL) {
+                    _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+                    return (DW_DLV_ERROR);
+                }
+                curr_chain->ch_item = arange;
+                if (head_chain == NULL)
+                    head_chain = prev_chain = curr_chain;
+                else {
+                    prev_chain->ch_next = curr_chain;
+                    prev_chain = curr_chain;
+                }
+            }
+        }
+        dwarf_dealloc(dbg, frame_inst, DW_DLA_FRAME_BLOCK);
+
+    }
+    for (i = 0; i < fde_count; i++) {
+        Dwarf_Small *instr_end = 0;
+        Dwarf_Sword icount = 0;
+        Dwarf_Signed instructions_length = 0;
+        Dwarf_Off instoff = 0;
+        Dwarf_Off off = 0;
+        Dwarf_Addr addr = 0;
+        int j = 0;
+        int dw_err;
+
+        fdep = fde_data[i];
+        off = fdep->fd_initial_loc_pos - dbg->de_debug_frame.dss_data;
+        addr = fdep->fd_initial_location;
+        arange = (Dwarf_Arange)
+            _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
+        if (arange == NULL) {
+            _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+            return (DW_DLV_ERROR);
+        }
+        arange->ar_address = addr;
+        arange->ar_info_offset = off;
+        arange_count++;
+        curr_chain = (Dwarf_Chain)
+            _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+        if (curr_chain == NULL) {
+            _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+            return (DW_DLV_ERROR);
+        }
+        curr_chain->ch_item = arange;
+        if (head_chain == NULL)
+            head_chain = prev_chain = curr_chain;
+        else {
+            prev_chain->ch_next = curr_chain;
+            prev_chain = curr_chain;
+        }
+
+
+        instoff = fdep->fd_fde_instr_start - dbg->de_debug_frame.dss_data;
+        instructions_length = fdep->fd_length +
+            fdep->fd_length_size + fdep->fd_extension_size -
+            (fdep->fd_fde_instr_start - fdep->fd_fde_start);
+        instr_end = fdep->fd_fde_instr_start + instructions_length;
+        res = _dwarf_exec_frame_instr( /* make_instr */ true,
+            &frame_inst,
+            /* search_pc= */ false,
+            /* search_pc_val= */ 0,
+            /* location */ 0,
+            fdep->fd_fde_instr_start,
+            instr_end,
+            /* Dwarf_frame= */ 0,
+            /* cie= */ 0,
+            dbg,
+            DW_FRAME_CFA_COL,
+            &icount, &dw_err);
+        if (res == DW_DLV_ERROR) {
+            _dwarf_error(dbg, err, dw_err);
+            return (res);
+        } else if (res == DW_DLV_NO_ENTRY) {
+            continue;
+        }
+
+        for (j = 0; j < icount; ++j) {
+            Dwarf_Frame_Op *finst2 = frame_inst + j;
+
+            if (finst2->fp_base_op == 0 && finst2->fp_extended_op == 1) {
+                /* is DW_CFA_set_loc */
+                Dwarf_Addr add = (Dwarf_Addr) finst2->fp_offset;
+                Dwarf_Off off = finst2->fp_instr_offset + instoff;
+
+                arange = (Dwarf_Arange)
+                    _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
+                if (arange == NULL) {
+                    _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+                    return (DW_DLV_ERROR);
+                }
+                arange->ar_address = add;
+                arange->ar_info_offset = off;
+                arange_count++;
+                curr_chain = (Dwarf_Chain)
+                    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+                if (curr_chain == NULL) {
+                    _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+                    return (DW_DLV_ERROR);
+                }
+                curr_chain->ch_item = arange;
+                if (head_chain == NULL)
+                    head_chain = prev_chain = curr_chain;
+                else {
+                    prev_chain->ch_next = curr_chain;
+                    prev_chain = curr_chain;
+                }
+
+            }
+        }
+        dwarf_dealloc(dbg, frame_inst, DW_DLA_FRAME_BLOCK);
+
+    }
+    dwarf_dealloc(dbg, fde_data, DW_DLA_LIST);
+    dwarf_dealloc(dbg, cie_data, DW_DLA_LIST);
+    arange_addrs = (Dwarf_Addr *)
+        _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
+    if (arange_addrs == NULL) {
+        _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
+    }
+    arange_offsets = (Dwarf_Off *)
+        _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
+    if (arange_offsets == NULL) {
+        _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
+    }
+
+    curr_chain = head_chain;
+    for (i = 0; i < arange_count; i++) {
+        Dwarf_Arange ar = curr_chain->ch_item;
+
+        arange_addrs[i] = ar->ar_address;
+        arange_offsets[i] = ar->ar_info_offset;
+        prev_chain = curr_chain;
+        curr_chain = curr_chain->ch_next;
+        dwarf_dealloc(dbg, ar, DW_DLA_ARANGE);
+        dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
+    }
+    *returncount = arange_count;
+    *offsetlist = arange_offsets;
+    *addrlist = arange_addrs;
+    return retval;
+}
--- a/usr/src/tools/ctf/dwarf/common/dwarf_funcs.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_funcs.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2009-2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -43,44 +44,52 @@
 
 int
 dwarf_get_funcs(Dwarf_Debug dbg,
-		Dwarf_Func ** funcs,
-		Dwarf_Signed * ret_func_count, Dwarf_Error * error)
+    Dwarf_Func ** funcs,
+    Dwarf_Signed * ret_func_count, Dwarf_Error * error)
 {
-    int res;
-
-    res =
-	_dwarf_load_section(dbg,
-			    dbg->de_debug_funcnames_index,
-			    &dbg->de_debug_funcnames,
-			    error);
+    int res = _dwarf_load_section(dbg, &dbg->de_debug_funcnames,error);
     if (res != DW_DLV_OK) {
-	return res;
+        return res;
     }
 
-    return _dwarf_internal_get_pubnames_like_data(dbg, dbg->de_debug_funcnames, dbg->de_debug_funcnames_size, (Dwarf_Global **) funcs,	/* type 
-																	   punning,
-																	   Dwarf_Type 
-																	   is never
-																	   a
-																	   completed 
-																	   type */
-						  ret_func_count,
-						  error,
-						  DW_DLA_FUNC_CONTEXT,
-						  DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD,
-						  DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR);
+    return _dwarf_internal_get_pubnames_like_data(dbg, 
+        dbg->de_debug_funcnames.dss_data, 
+        dbg->de_debug_funcnames.dss_size, 
+        (Dwarf_Global **) funcs, /* Type punning for sections with identical format. */
+        ret_func_count,
+        error,
+        DW_DLA_FUNC_CONTEXT,
+        DW_DLA_FUNC,
+        DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD,
+        DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR);
+}
 
+/* Deallocating fully requires deallocating the list
+   and all entries.  But some internal data is
+   not exposed, so we need a function with internal knowledge.
+*/
+
+void
+dwarf_funcs_dealloc(Dwarf_Debug dbg, Dwarf_Func * dwgl,
+    Dwarf_Signed count)
+{
+    _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl,
+        count,
+        DW_DLA_FUNC_CONTEXT,
+        DW_DLA_FUNC, DW_DLA_LIST);
+    return;
 }
 
 
+
 int
 dwarf_funcname(Dwarf_Func func_in, char **ret_name, Dwarf_Error * error)
 {
     Dwarf_Global func = (Dwarf_Global) func_in;
 
     if (func == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_FUNC_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_FUNC_NULL);
+        return (DW_DLV_ERROR);
     }
 
     *ret_name = (char *) (func->gl_name);
@@ -89,7 +98,7 @@
 
 int
 dwarf_func_die_offset(Dwarf_Func func_in,
-		      Dwarf_Off * return_offset, Dwarf_Error * error)
+    Dwarf_Off * return_offset, Dwarf_Error * error)
 {
     Dwarf_Global func = (Dwarf_Global) func_in;
 
@@ -99,7 +108,7 @@
 
 int
 dwarf_func_cu_offset(Dwarf_Func func_in,
-		     Dwarf_Off * return_offset, Dwarf_Error * error)
+    Dwarf_Off * return_offset, Dwarf_Error * error)
 {
     Dwarf_Global func = (Dwarf_Global) func_in;
 
@@ -109,13 +118,13 @@
 
 int
 dwarf_func_name_offsets(Dwarf_Func func_in,
-			char **ret_func_name,
-			Dwarf_Off * die_offset,
-			Dwarf_Off * cu_die_offset, Dwarf_Error * error)
+    char **ret_func_name,
+    Dwarf_Off * die_offset,
+    Dwarf_Off * cu_die_offset, Dwarf_Error * error)
 {
     Dwarf_Global func = (Dwarf_Global) func_in;
 
     return dwarf_global_name_offsets(func,
-				     ret_func_name,
-				     die_offset, cu_die_offset, error);
+        ret_func_name,
+        die_offset, cu_die_offset, error);
 }
--- a/usr/src/tools/ctf/dwarf/common/dwarf_funcs.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_funcs.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000, 2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
--- a/usr/src/tools/ctf/dwarf/common/dwarf_global.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_global.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -32,6 +33,12 @@
   http://oss.sgi.com/projects/GenInfo/NoticeExplan
 
 */
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
 
 
 
@@ -40,35 +47,106 @@
 #include <stdio.h>
 #include "dwarf_global.h"
 
+
+#ifdef __sgi  /* __sgi should only be defined for IRIX/MIPS. */
+/* The 'fixup' here intended for IRIX targets only.
+   With a  2+GB Elf64 IRIX executable (under 4GB in size),  
+   some DIE offsets wrongly
+   got the 32bit upper bit sign extended.  For the cu-header
+   offset in the .debug_pubnames section  and in the
+   .debug_aranges section.
+   the 'varp' here is a pointer to an offset into .debug_info.
+   We fix up the offset here if it seems advisable..
+   
+   As of June 2005 we have identified a series of mistakes
+   in ldx64 that can cause this (64 bit values getting passed
+   thru 32-bit signed knothole).  
+*/
+void
+_dwarf_fix_up_offset_irix(Dwarf_Debug dbg,
+    Dwarf_Unsigned * varp, char *caller_site_name)
+{
+
+    Dwarf_Unsigned var = *varp;
+
+#define UPPER33 0xffffffff80000000LL
+#define LOWER32         0xffffffffLL
+    /* Restrict the hack to the known case. Upper 32 bits erroneously
+       sign extended from lower 32 upper bit. */
+    if ((var & UPPER33) == UPPER33) {
+        var &= LOWER32;
+        /* Apply the fix. Dreadful hack. */
+        *varp = var;
+    }
+#undef UPPER33
+#undef LOWER32
+    return;
+}
+#endif
+
+
 int
 dwarf_get_globals(Dwarf_Debug dbg,
-		  Dwarf_Global ** globals,
-		  Dwarf_Signed * return_count, Dwarf_Error * error)
+    Dwarf_Global ** globals,
+    Dwarf_Signed * return_count, Dwarf_Error * error)
 {
-    int res;
-
-    res =
-       _dwarf_load_section(dbg, 
-			   dbg->de_debug_pubnames_index,
-			   &dbg->de_debug_pubnames,
-			   error);
+    int res = _dwarf_load_section(dbg, &dbg->de_debug_pubnames,error);
     if (res != DW_DLV_OK) {
         return res;
     }
 
+    return _dwarf_internal_get_pubnames_like_data(dbg,
+        dbg->de_debug_pubnames.dss_data,
+        dbg->de_debug_pubnames.dss_size,
+        globals, 
+        return_count,
+        error,
+        DW_DLA_GLOBAL_CONTEXT,
+        DW_DLA_GLOBAL,
+        DW_DLE_PUBNAMES_LENGTH_BAD,
+        DW_DLE_PUBNAMES_VERSION_ERROR);
 
+}
+
+/* Deallocating fully requires deallocating the list
+   and all entries.  But some internal data is
+   not exposed, so we need a function with internal knowledge.
+*/
 
-    return _dwarf_internal_get_pubnames_like_data(dbg,
-						  dbg->
-						  de_debug_pubnames,
-						  dbg->
-						  de_debug_pubnames_size,
-						  globals, return_count,
-						  error,
-						  DW_DLA_GLOBAL_CONTEXT,
-						  DW_DLE_PUBNAMES_LENGTH_BAD,
-						  DW_DLE_PUBNAMES_VERSION_ERROR);
+void
+dwarf_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl,
+    Dwarf_Signed count)
+{
+    _dwarf_internal_globals_dealloc(dbg, dwgl,
+        count,
+        DW_DLA_GLOBAL_CONTEXT,
+        DW_DLA_GLOBAL, DW_DLA_LIST);
+    return;
+}
 
+void
+_dwarf_internal_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl,
+    Dwarf_Signed count,
+    int context_code,
+    int global_code, int list_code)
+{
+    Dwarf_Signed i;
+    struct Dwarf_Global_Context_s *gcp = 0;
+    struct Dwarf_Global_Context_s *lastgcp = 0;
+
+    for (i = 0; i < count; i++) {
+        Dwarf_Global dgb = dwgl[i];
+
+        gcp = dgb->gl_context;
+
+        if (lastgcp != gcp) {
+            lastgcp = gcp;
+            dwarf_dealloc(dbg, gcp, context_code);
+        }
+        dwarf_dealloc(dbg, dgb, global_code);
+    }
+    dwarf_dealloc(dbg, dwgl, list_code);
+    return;
 }
 
 
@@ -76,212 +154,221 @@
 */
 int
 _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg,
-				       Dwarf_Small * section_data_ptr,
-				       Dwarf_Unsigned section_length,
-				       Dwarf_Global ** globals,
-				       Dwarf_Signed * return_count,
-				       Dwarf_Error * error,
-				       int allocation_code,
-				       int length_err_num,
-				       int version_err_num)
+    Dwarf_Small * section_data_ptr,
+    Dwarf_Unsigned section_length,
+    Dwarf_Global ** globals,
+    Dwarf_Signed * return_count,
+    Dwarf_Error * error,
+    int context_code,
+    int global_code,
+    int length_err_num,
+    int version_err_num)
 {
 
 
-    Dwarf_Small *pubnames_like_ptr;
+    Dwarf_Small *pubnames_like_ptr = 0;
 
 
 
-    /* 
-       Points to the context for the current set of global names, and
+    /* Points to the context for the current set of global names, and
        contains information to identify the compilation-unit that the
        set refers to. */
-    Dwarf_Global_Context pubnames_context;
+    Dwarf_Global_Context pubnames_context = 0;
 
-    Dwarf_Half version;
+    Dwarf_Half version = 0;
 
     /* 
        Offset from the start of compilation-unit for the current
        global. */
-    Dwarf_Off die_offset_in_cu;
+    Dwarf_Off die_offset_in_cu = 0;
 
     Dwarf_Unsigned global_count = 0;
 
     /* Points to the current global read. */
-    Dwarf_Global global;
+    Dwarf_Global global = 0;
 
-    /* 
-       Used to chain the Dwarf_Global_s structs for creating contiguous 
+    /* Used to chain the Dwarf_Global_s structs for creating contiguous 
        list of pointers to the structs. */
-    Dwarf_Chain curr_chain, prev_chain, head_chain = NULL;
+    Dwarf_Chain curr_chain = 0;
+    Dwarf_Chain prev_chain = 0;
+    Dwarf_Chain head_chain = 0;
 
     /* Points to contiguous block of Dwarf_Global's to be returned. */
-    Dwarf_Global *ret_globals;
+    Dwarf_Global *ret_globals = 0;
 
     /* Temporary counter. */
-    Dwarf_Unsigned i;
+    Dwarf_Unsigned i = 0;
 
 
 
 
     if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
     /* We will eventually need the .debug_info data. Load it now. */
-    if(!dbg->de_debug_info) {
-        int res = _dwarf_load_debug_info(dbg,error);
-        if(res != DW_DLV_OK) {
-              return res;
+    if (!dbg->de_debug_info.dss_data) {
+        int res = _dwarf_load_debug_info(dbg, error);
+
+        if (res != DW_DLV_OK) {
+            return res;
         }
     }
 
     if (section_data_ptr == NULL) {
-	return (DW_DLV_NO_ENTRY);
+        return (DW_DLV_NO_ENTRY);
     }
 
     pubnames_like_ptr = section_data_ptr;
     do {
-	Dwarf_Unsigned length;
-	int local_extension_size;
-	int local_length_size;
+        Dwarf_Unsigned length = 0;
+        int local_extension_size = 0;
+        int local_length_size = 0;
 
-	/* Some compilers emit padding at the end of each cu's
-	   area. pubnames_ptr_past_end_cu records the true
-           area end for this cu's data.  Essentially the
-	   length in the header and the  0 terminator of the
-           data are redundant information. The dwarf2/3
-	   spec does not mention what to do if the length
-           is past the 0 terminator. So we take any bytes
-	   left after the 0 as padding and ignore them. */
+        /* Some compilers emit padding at the end of each cu's area.
+           pubnames_ptr_past_end_cu records the true area end for this
+           cu's data.  Essentially the length in the header and the 0
+           terminator of the data are redundant information. The
+           dwarf2/3 spec does not mention what to do if the length is
+           past the 0 terminator. So we take any bytes left after the 0 
+           as padding and ignore them. */
         Dwarf_Small *pubnames_ptr_past_end_cu = 0;
-	
+
 
-	pubnames_context = (Dwarf_Global_Context)
-	    _dwarf_get_alloc(dbg, allocation_code, 1);
-	if (pubnames_context == NULL) {
-	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	    return (DW_DLV_ERROR);
-	}
-	/* READ_AREA_LENGTH updates pubnames_like_ptr for consumed
-	   bytes */
-	READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
-			 pubnames_like_ptr, local_length_size,
-			 local_extension_size);
-	pubnames_context->pu_length_size = local_length_size;
-	pubnames_context->pu_extension_size = local_extension_size;
-	pubnames_context->pu_dbg = dbg;
+        pubnames_context = (Dwarf_Global_Context)
+            _dwarf_get_alloc(dbg, context_code, 1);
+        if (pubnames_context == NULL) {
+            _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
+        }
+        /* READ_AREA_LENGTH updates pubnames_like_ptr for consumed
+           bytes. */
+        READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
+            pubnames_like_ptr, local_length_size,
+            local_extension_size);
+        pubnames_context->pu_length_size = local_length_size;
+        pubnames_context->pu_extension_size = local_extension_size;
+        pubnames_context->pu_dbg = dbg;
+
+        pubnames_ptr_past_end_cu = pubnames_like_ptr + length;
 
-        pubnames_ptr_past_end_cu  = pubnames_like_ptr + length;
+        READ_UNALIGNED(dbg, version, Dwarf_Half,
+                       pubnames_like_ptr, sizeof(Dwarf_Half));
+        pubnames_like_ptr += sizeof(Dwarf_Half);
+        if (version != CURRENT_VERSION_STAMP) {
+            _dwarf_error(dbg, error, version_err_num);
+            return (DW_DLV_ERROR);
+        }
 
-	READ_UNALIGNED(dbg, version, Dwarf_Half,
-		       pubnames_like_ptr, sizeof(Dwarf_Half));
-	pubnames_like_ptr += sizeof(Dwarf_Half);
-	if (version != CURRENT_VERSION_STAMP) {
-	    _dwarf_error(dbg, error, version_err_num);
-	    return (DW_DLV_ERROR);
-	}
+        /* Offset of CU header in debug section. */
+        READ_UNALIGNED(dbg, pubnames_context->pu_offset_of_cu_header,
+                       Dwarf_Off, pubnames_like_ptr,
+                       pubnames_context->pu_length_size);
+        pubnames_like_ptr += pubnames_context->pu_length_size;
 
-	/* offset of CU header in debug section */
-	READ_UNALIGNED(dbg, pubnames_context->pu_offset_of_cu_header,
-		       Dwarf_Off, pubnames_like_ptr,
-		       pubnames_context->pu_length_size);
-	pubnames_like_ptr += pubnames_context->pu_length_size;
+        FIX_UP_OFFSET_IRIX_BUG(dbg,
+                               pubnames_context->pu_offset_of_cu_header,
+                               "pubnames cu header offset");
 
 
-	READ_UNALIGNED(dbg, pubnames_context->pu_info_length,
-		       Dwarf_Unsigned, pubnames_like_ptr,
-		       pubnames_context->pu_length_size);
-	pubnames_like_ptr += pubnames_context->pu_length_size;
+        READ_UNALIGNED(dbg, pubnames_context->pu_info_length,
+                       Dwarf_Unsigned, pubnames_like_ptr,
+                       pubnames_context->pu_length_size);
+        pubnames_like_ptr += pubnames_context->pu_length_size;
 
-	if (pubnames_like_ptr > (section_data_ptr + section_length)) {
-	    _dwarf_error(dbg, error, length_err_num);
-	    return (DW_DLV_ERROR);
-	}
+        if (pubnames_like_ptr > (section_data_ptr + section_length)) {
+            _dwarf_error(dbg, error, length_err_num);
+            return (DW_DLV_ERROR);
+        }
 
-	/* read initial offset (of DIE within CU) of a pubname, final
-	   entry is not a pair, just a zero offset */
-	READ_UNALIGNED(dbg, die_offset_in_cu, Dwarf_Off,
-		       pubnames_like_ptr,
-		       pubnames_context->pu_length_size);
-	pubnames_like_ptr += pubnames_context->pu_length_size;
+        /* Read initial offset (of DIE within CU) of a pubname, final
+           entry is not a pair, just a zero offset. */
+        READ_UNALIGNED(dbg, die_offset_in_cu, Dwarf_Off,
+                       pubnames_like_ptr,
+                       pubnames_context->pu_length_size);
+        pubnames_like_ptr += pubnames_context->pu_length_size;
+        FIX_UP_OFFSET_IRIX_BUG(dbg,
+                               die_offset_in_cu, "offset of die in cu");
 
-	/* loop thru pairs. DIE off with CU followed by string */
-	while (die_offset_in_cu != 0) {
+        /* Loop thru pairs. DIE off with CU followed by string. */
+        while (die_offset_in_cu != 0) {
 
-	    /* Already read offset, pubnames_like_ptr now points to the 
-	       string */
-	    global =
-		(Dwarf_Global) _dwarf_get_alloc(dbg, DW_DLA_GLOBAL, 1);
-	    if (global == NULL) {
-		_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-		return (DW_DLV_ERROR);
-	    }
-	    global_count++;
+            /* Already read offset, pubnames_like_ptr now points to the 
+               string. */
+            global =
+                (Dwarf_Global) _dwarf_get_alloc(dbg, global_code, 1);
+            if (global == NULL) {
+                _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+                return (DW_DLV_ERROR);
+            }
+            global_count++;
 
-	    global->gl_context = pubnames_context;
+            global->gl_context = pubnames_context;
 
-	    global->gl_named_die_offset_within_cu = die_offset_in_cu;
+            global->gl_named_die_offset_within_cu = die_offset_in_cu;
 
-	    global->gl_name = pubnames_like_ptr;
+            global->gl_name = pubnames_like_ptr;
 
-	    pubnames_like_ptr = pubnames_like_ptr +
-		strlen((char *) pubnames_like_ptr) + 1;
+            pubnames_like_ptr = pubnames_like_ptr +
+                strlen((char *) pubnames_like_ptr) + 1;
 
 
-	    /* finish off current entry chain */
-	    curr_chain =
-		(Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
-	    if (curr_chain == NULL) {
-		_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-		return (DW_DLV_ERROR);
-	    }
+            /* finish off current entry chain */
+            curr_chain =
+                (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+            if (curr_chain == NULL) {
+                _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+                return (DW_DLV_ERROR);
+            }
 
-	    /* Put current global on singly_linked list. */
-	    curr_chain->ch_item = (Dwarf_Global) global;
+            /* Put current global on singly_linked list. */
+            curr_chain->ch_item = (Dwarf_Global) global;
 
-	    if (head_chain == NULL)
-		head_chain = prev_chain = curr_chain;
-	    else {
-		prev_chain->ch_next = curr_chain;
-		prev_chain = curr_chain;
-	    }
+            if (head_chain == NULL)
+                head_chain = prev_chain = curr_chain;
+            else {
+                prev_chain->ch_next = curr_chain;
+                prev_chain = curr_chain;
+            }
 
-	    /* read offset for the *next* entry */
-	    READ_UNALIGNED(dbg, die_offset_in_cu, Dwarf_Off,
-			   pubnames_like_ptr,
-			   pubnames_context->pu_length_size);
+            /* read offset for the *next* entry */
+            READ_UNALIGNED(dbg, die_offset_in_cu, Dwarf_Off,
+                           pubnames_like_ptr,
+                           pubnames_context->pu_length_size);
 
-	    pubnames_like_ptr += pubnames_context->pu_length_size;
-	    if (pubnames_like_ptr > (section_data_ptr + section_length)) {
-		_dwarf_error(dbg, error, length_err_num);
-		return (DW_DLV_ERROR);
-	    }
-	}
-	/* ASSERT: die_offset_in_cu == 0 */
-	if(pubnames_like_ptr > pubnames_ptr_past_end_cu) {
-	   /* This is some kind of error. This simply cannot happen.
-	      The encoding is wrong or the length in the header 
-	      for this cu's contribution is wrong. */
-	   _dwarf_error(dbg, error, length_err_num);
-	   return (DW_DLV_ERROR);
-	
+            pubnames_like_ptr += pubnames_context->pu_length_size;
+            FIX_UP_OFFSET_IRIX_BUG(dbg,
+                                   die_offset_in_cu,
+                                   "offset of next die in cu");
+
+            if (pubnames_like_ptr > (section_data_ptr + section_length)) {
+                _dwarf_error(dbg, error, length_err_num);
+                return (DW_DLV_ERROR);
+            }
         }
-	/* If there is some kind of padding at the end of
-           the section, as emitted by some compilers,
-	   skip over that padding and simply ignore the bytes
-	   thus passed-over.   With most compilers,
-	     pubnames_like_ptr == pubnames_ptr_past_end_cu
-	   at this point */
-	pubnames_like_ptr =  pubnames_ptr_past_end_cu;
+        /* ASSERT: die_offset_in_cu == 0 */
+        if (pubnames_like_ptr > pubnames_ptr_past_end_cu) {
+            /* This is some kind of error. This simply cannot happen.
+            The encoding is wrong or the length in the header for
+            this cu's contribution is wrong. */
+            _dwarf_error(dbg, error, length_err_num);
+            return (DW_DLV_ERROR);
+        }
+        /* If there is some kind of padding at the end of the section,
+           as emitted by some compilers, skip over that padding and
+           simply ignore the bytes thus passed-over.  With most
+           compilers, pubnames_like_ptr == pubnames_ptr_past_end_cu at
+           this point */
+        pubnames_like_ptr = pubnames_ptr_past_end_cu;
 
     } while (pubnames_like_ptr < (section_data_ptr + section_length));
 
     /* Points to contiguous block of Dwarf_Global's. */
     ret_globals = (Dwarf_Global *)
-	_dwarf_get_alloc(dbg, DW_DLA_LIST, global_count);
+        _dwarf_get_alloc(dbg, DW_DLA_LIST, global_count);
     if (ret_globals == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
     }
 
     /* 
@@ -289,29 +376,30 @@
        and deallocate the chain. */
     curr_chain = head_chain;
     for (i = 0; i < global_count; i++) {
-	*(ret_globals + i) = curr_chain->ch_item;
-	prev_chain = curr_chain;
-	curr_chain = curr_chain->ch_next;
-	dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
+        *(ret_globals + i) = curr_chain->ch_item;
+        prev_chain = curr_chain;
+        curr_chain = curr_chain->ch_next;
+        dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
     }
 
     *globals = ret_globals;
-    *return_count = (global_count);
+    *return_count = (Dwarf_Signed) global_count;
     return DW_DLV_OK;
 }
 
+
 /*
-	Given a pubnames entry (or other like section entry)
-	return thru the ret_name pointer
-	a pointer to the string which is the entry name.
-	
+        Given a pubnames entry (or other like section entry)
+        return thru the ret_name pointer
+        a pointer to the string which is the entry name.
+        
 */
 int
 dwarf_globname(Dwarf_Global glob, char **ret_name, Dwarf_Error * error)
 {
     if (glob == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
+        return (DW_DLV_ERROR);
     }
 
     *ret_name = (char *) (glob->gl_name);
@@ -320,40 +408,40 @@
 
 
 /*
-	Given a pubnames entry (or other like section entry)
-	return thru the ret_off pointer the
-	global offset of the DIE for this entry.
-	The global offset is the offset within the .debug_info
-	section as a whole.
+        Given a pubnames entry (or other like section entry)
+        return thru the ret_off pointer the
+        global offset of the DIE for this entry.
+        The global offset is the offset within the .debug_info
+        section as a whole.
 */
 int
 dwarf_global_die_offset(Dwarf_Global global,
-			Dwarf_Off * ret_off, Dwarf_Error * error)
+                        Dwarf_Off * ret_off, Dwarf_Error * error)
 {
     if (global == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
+        return (DW_DLV_ERROR);
     }
 
     if (global->gl_context == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
+        return (DW_DLV_ERROR);
     }
 
     *ret_off = (global->gl_named_die_offset_within_cu +
-		global->gl_context->pu_offset_of_cu_header);
+                global->gl_context->pu_offset_of_cu_header);
     return DW_DLV_OK;
 }
 
 /*
-	Given a pubnames entry (or other like section entry)
-	return thru the ret_off pointer the
-	offset of the compilation unit header of the
+        Given a pubnames entry (or other like section entry)
+        return thru the ret_off pointer the
+        offset of the compilation unit header of the
         compilation unit the global is part of.
 
-	In early versions of this, the value returned was
+        In early versions of this, the value returned was
         the offset of the compilation unit die, and
-	other cu-local die offsets were faked so adding this to 
+        other cu-local die offsets were faked so adding this to 
         such a cu-local offset got a true section offset.
         Now things do as they say (adding *cu_header_offset to
         a cu-local offset gets the section offset).
@@ -361,21 +449,21 @@
 */
 int
 dwarf_global_cu_offset(Dwarf_Global global,
-		       Dwarf_Off * cu_header_offset,
-		       Dwarf_Error * error)
+                       Dwarf_Off * cu_header_offset,
+                       Dwarf_Error * error)
 {
-    Dwarf_Global_Context con;
+    Dwarf_Global_Context con = 0;
 
     if (global == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
+        return (DW_DLV_ERROR);
     }
 
     con = global->gl_context;
 
     if (con == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
+        return (DW_DLV_ERROR);
     }
 
     /* In early libdwarf, this incorrectly returned the offset of the
@@ -388,77 +476,132 @@
 /*
   Give back the pubnames entry (or any other like section)
   name, symbol DIE offset, and the cu-DIE offset.
+
+  Various errors are possible.
+
+  The string pointer returned thru ret_name is not
+  dwarf_get_alloc()ed, so no dwarf_dealloc() 
+  DW_DLA_STRING should be applied to it.
+
 */
 int
 dwarf_global_name_offsets(Dwarf_Global global,
-			  char **ret_name,
-			  Dwarf_Off * die_offset,
-			  Dwarf_Off * cu_die_offset,
-			  Dwarf_Error * error)
+                          char **ret_name,
+                          Dwarf_Off * die_offset,
+                          Dwarf_Off * cu_die_offset,
+                          Dwarf_Error * error)
 {
-    Dwarf_Global_Context con;
-    Dwarf_Debug dbg;
-    Dwarf_Off off;
+    Dwarf_Global_Context con = 0;
+    Dwarf_Debug dbg = 0;
+    Dwarf_Off off = 0;
 
     if (global == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
+        return (DW_DLV_ERROR);
     }
 
     con = global->gl_context;
 
     if (con == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
+        return (DW_DLV_ERROR);
     }
 
     off = con->pu_offset_of_cu_header;
-    if (die_offset != NULL) {
-	*die_offset = global->gl_named_die_offset_within_cu + off;
-    }
-
+    /* The offset had better not be too close to the end. If it is,
+       _dwarf_length_of_cu_header() will step off the end and therefore 
+       must not be used. 10 is a meaningless heuristic, but no CU
+       header is that small so it is safe. An erroneous offset is due
+       to a bug in the tool chain. A bug like this has been seen on
+       IRIX with MIPSpro 7.3.1.3 and an executable > 2GB in size and
+       with 2 million pubnames entries. */
+#define MIN_CU_HDR_SIZE 10
     dbg = con->pu_dbg;
     if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
-
-    if (cu_die_offset != NULL) {
- 	int res = _dwarf_load_debug_info(dbg,error);
-	if(res != DW_DLV_OK) {
-	   return res;
-	}
-	*cu_die_offset = off + _dwarf_length_of_cu_header(dbg, off);
+    if (dbg->de_debug_info.dss_size &&
+        ((off + MIN_CU_HDR_SIZE) >= dbg->de_debug_info.dss_size)) {
+        _dwarf_error(NULL, error, DW_DLE_OFFSET_BAD);
+        return (DW_DLV_ERROR);
+    }
+#undef MIN_CU_HDR_SIZE
+    if (die_offset != NULL) {
+        *die_offset = global->gl_named_die_offset_within_cu + off;
     }
 
     *ret_name = (char *) global->gl_name;
 
+    if (cu_die_offset != NULL) {
+        int res = _dwarf_load_debug_info(dbg, error);
+
+        if (res != DW_DLV_OK) {
+            return res;
+        }
+        /* The offset had better not be too close to the end. If it is, 
+           _dwarf_length_of_cu_header() will step off the end and
+           therefore must not be used. 10 is a meaningless heuristic,
+           but no CU header is that small so it is safe. */
+        if ((off + 10) >= dbg->de_debug_info.dss_size) {
+            _dwarf_error(NULL, error, DW_DLE_OFFSET_BAD);
+            return (DW_DLV_ERROR);
+        }
+        *cu_die_offset = off + _dwarf_length_of_cu_header(dbg, off);
+    }
+
+
     return DW_DLV_OK;
 }
 
 /*
-	We have the offset to a CU header.
-	Return thru outFileOffset the offset of the CU DIE.
-	
-	New June, 2001.
-	Used by SGI debuggers.
-	No error is possible.
+        We have the offset to a CU header.
+        Return thru outFileOffset the offset of the CU DIE.
+        
+        New June, 2001.
+        Used by SGI debuggers.
+        No error is possible.
+
+        See also dwarf_CU_dieoffset_given_die().
 */
 
 /* ARGSUSED */
 int
 dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg,
-					       Dwarf_Off
-					       in_cu_header_offset,
-					       Dwarf_Off *
-					       out_cu_die_offset,
-					       Dwarf_Error * err)
+    Dwarf_Off in_cu_header_offset,
+    Dwarf_Off * out_cu_die_offset,
+    Dwarf_Error * err)
 {
     Dwarf_Off len =
-	_dwarf_length_of_cu_header(dbg, in_cu_header_offset);
+        _dwarf_length_of_cu_header(dbg, in_cu_header_offset);
 
     Dwarf_Off newoff = in_cu_header_offset + len;
 
     *out_cu_die_offset = newoff;
     return DW_DLV_OK;
 }
+/* dwarf_CU_dieoffset_given_die returns
+   the global debug_info section offset of the CU die
+   that is the CU containing the given (passed-in) die. 
+   This information makes it possible for a consumer to
+   find and print context information for any die. 
+
+   Use dwarf_offdie() passing in the offset this returns
+   to get a die pointer to the CU die.
+ */  
+int 
+dwarf_CU_dieoffset_given_die(Dwarf_Die die,
+    Dwarf_Off*       return_offset,
+    Dwarf_Error*     error)
+{   
+    Dwarf_Off  dieoff = 0;
+    Dwarf_CU_Context cucontext = 0;
+    
+    CHECK_DIE(die, DW_DLV_ERROR);
+    cucontext = die->di_cu_context;
+    dieoff =  cucontext->cc_debug_info_offset;
+    /* The following call cannot fail, so no error check. */
+    dwarf_get_cu_die_offset_given_cu_header_offset(
+       cucontext->cc_dbg, dieoff, return_offset,error);
+    return DW_DLV_OK;
+}
--- a/usr/src/tools/ctf/dwarf/common/dwarf_global.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_global.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -43,24 +43,25 @@
     Essentially, they contain the context for a set of pubnames 
     belonging to a compilation-unit.
 
-
     This is also used for the sgi-specific
     weaknames, typenames, varnames, funcnames data:
     the structs for those are incomplete and
     instances of this are used instead.
 
+    Also used for DWARF3 .debug_pubtypes.
+
 */
 struct Dwarf_Global_Context_s {
 
-    /* 
-       Length in .debug_pubnames of a set of pubnames for a
+    /* Length in .debug_pubnames (etc) of a set of names for a
        compilation-unit. Dwarf_Word pu_length; The value is not made
        available outside libdwarf and not used inside, so no need to
        record it. */
 
-    /* for this context, size of a length. 4 or 8 */
+    /* For this context, size of a length. 4 or 8 */
     unsigned char pu_length_size;
-    /* for this CU, size of the extension 0 except for dwarf2 extension 
+
+    /* For this CU, size of the extension 0 except for dwarf2 extension 
        64bit, in which case is 4. */
     unsigned char pu_extension_size;
 
@@ -99,6 +100,25 @@
 					   Dwarf_Global ** globals,
 					   Dwarf_Signed * return_count,
 					   Dwarf_Error * error,
-					   int allocation_code,
+					   int context_code,
+					   int global_code,
 					   int length_err_num,
 					   int version_err_num);
+
+void
+_dwarf_internal_globals_dealloc( Dwarf_Debug dbg, Dwarf_Global *dwgl,
+        Dwarf_Signed count,
+        int context_code,
+        int global_code,
+        int list_code);
+
+
+#ifdef __sgi  /* __sgi should only be defined for IRIX/MIPS. */
+void _dwarf_fix_up_offset_irix(Dwarf_Debug dbg,
+        Dwarf_Unsigned *varp,
+        char *caller_site_name);
+#define FIX_UP_OFFSET_IRIX_BUG(ldbg,var,name) _dwarf_fix_up_offset_irix(ldbg,&var,name)
+#else
+#define FIX_UP_OFFSET_IRIX_BUG(ldbg,var,name)
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_harmless.c	Sun May 22 03:13:22 2011 +0100
@@ -0,0 +1,226 @@
+/*
+
+  Copyright (C) 2010 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+*/
+
+/*
+        This  implements _dwarf_insert_harmless_error
+        and related helper functions for recording
+        compiler errors that need not make the input
+        unusable.
+ 
+        Applications can use dwarf_get_harmless_error_list to
+        find (and possibly print) a warning about such errors.
+
+        The initial error reported here is 
+        DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE which was a
+        bug in a specific compiler.
+
+        It is a fixed length circular list to constrain
+        the space used for errors.
+
+        The assumption is that these errors are exceedingly
+        rare, and indicate a broken compiler (the one that
+        produced the object getting the error(s)).
+
+        dh_maxcount is recorded internally as 1 greater than
+        requested.  Hiding the fact we always leave one
+        slot unused (at least).   So a user request for
+        N slots really gives the user N usable slots.
+*/
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "dwarf_frame.h"
+#include "dwarf_harmless.h"
+
+
+/* The pointers returned here through errmsg_ptrs_array
+   become invalidated by any call to libdwarf. Any call.
+*/
+int dwarf_get_harmless_error_list(Dwarf_Debug dbg,
+    unsigned  count,
+    const char ** errmsg_ptrs_array,
+    unsigned * errs_count)
+{
+    struct Dwarf_Harmless_s *dhp = &dbg->de_harmless_errors;
+    if(!dhp->dh_errors) {
+        dhp->dh_errs_count = 0;
+        return DW_DLV_NO_ENTRY;
+    }
+    if(dhp->dh_errs_count == 0) {
+        return DW_DLV_NO_ENTRY;
+    }
+    if(errs_count) {
+        *errs_count = dhp->dh_errs_count;
+    }
+    if(count) {
+        /* NULL terminate the array of pointers */
+        --count;
+        errmsg_ptrs_array[count] = 0;
+
+        if(dhp->dh_next_to_use != dhp->dh_first) {
+            unsigned i = 0;
+            unsigned cur = dhp->dh_first;
+            for(i = 0;  cur != dhp->dh_next_to_use; ++i) {
+                if(i >= count ) {
+                    /* All output spaces are used. */
+                    break;
+                }
+                errmsg_ptrs_array[i] = dhp->dh_errors[cur];
+                cur = (cur +1) % dhp->dh_maxcount;
+            }
+            errmsg_ptrs_array[i] = 0;
+        }
+    }
+    dhp->dh_next_to_use = 0;
+    dhp->dh_first = 0;
+    dhp->dh_errs_count = 0;
+    return DW_DLV_OK;
+}
+
+/* strncpy does not null-terminate, this does it. */
+static void
+safe_strncpy(char *targ, char *src, unsigned spaceavail)
+{
+    unsigned goodcount = spaceavail-1;
+    if(spaceavail < 1) {
+        return; /* impossible */
+    }
+    strncpy(targ,src,goodcount);
+    targ[goodcount] = 0;
+}
+
+/* Insertion made public is only for testing the harmless error code, 
+   it is not necessarily useful for libdwarf client code aside
+   from code testing libdwarf. */
+void dwarf_insert_harmless_error(Dwarf_Debug dbg,
+    char *newerror)
+{
+    struct Dwarf_Harmless_s *dhp = &dbg->de_harmless_errors;
+    unsigned next = 0;
+    unsigned cur = dhp->dh_next_to_use;
+    char *msgspace;
+    if(!dhp->dh_errors) {
+        dhp->dh_errs_count++;
+        return;
+    }
+    msgspace = dhp->dh_errors[cur];
+    safe_strncpy(msgspace, newerror,DW_HARMLESS_ERROR_MSG_STRING_SIZE);
+    next = (cur+1) % dhp->dh_maxcount;
+    dhp->dh_errs_count++;
+    dhp->dh_next_to_use = next;
+    if (dhp->dh_next_to_use ==  dhp->dh_first) {
+        /* Array is full set full invariant. */
+        dhp->dh_first = (dhp->dh_first+1) % dhp->dh_maxcount;
+    }
+}
+
+/* The size of the circular list of strings may be set
+    and reset as desired. Returns the previous size of
+    the list. If the list is shortened excess error entries
+    are simply dropped. 
+    If the reallocation fails the list size is left unchanged.
+    Do not make this a long list!
+
+    Remember the maxcount we record is 1 > the user count,
+    so we adjust it so it looks like the user count.
+*/
+unsigned dwarf_set_harmless_error_list_size(Dwarf_Debug dbg,
+    unsigned maxcount )
+{
+    struct Dwarf_Harmless_s *dhp = &dbg->de_harmless_errors;
+    unsigned prevcount = dhp->dh_maxcount;
+    if(maxcount != 0) {
+        ++maxcount;
+        if(maxcount != dhp->dh_maxcount) {
+            /* Assign transfers 'ownership' of the malloc areas
+               to oldarray. */
+            struct Dwarf_Harmless_s oldarray = *dhp;
+            /* Do not double increment the max, the init() func
+               increments it too. */
+            dwarf_harmless_init(dhp,maxcount-1);
+            if(oldarray.dh_next_to_use != oldarray.dh_first) {
+                unsigned i = 0;
+                for(i = oldarray.dh_first; i != oldarray.dh_next_to_use; 
+                     i = (i+1)%oldarray.dh_maxcount) {
+                    dwarf_insert_harmless_error(dbg,oldarray.dh_errors[i]);
+                }
+                if( oldarray.dh_errs_count > dhp->dh_errs_count) {
+                    dhp->dh_errs_count = oldarray.dh_errs_count;
+                }
+            }
+            dwarf_harmless_cleanout(&oldarray);
+        }
+    }
+    return prevcount-1;
+}
+
+void 
+dwarf_harmless_init(struct Dwarf_Harmless_s *dhp,unsigned size)
+{
+    unsigned i = 0;
+    memset(dhp,0,sizeof(*dhp));
+    dhp->dh_maxcount = size +1;
+    dhp->dh_errors = (char **)malloc(sizeof( char *) *dhp->dh_maxcount);
+    if (!dhp->dh_errors) {
+        dhp->dh_maxcount = 0;
+        return;
+    }
+
+    for(i = 0; i < dhp->dh_maxcount; ++i) {
+        char *newstr =
+             (char *)malloc(DW_HARMLESS_ERROR_MSG_STRING_SIZE);
+        dhp->dh_errors[i] = newstr;
+        if(!newstr) {
+            dhp->dh_maxcount = 0;
+            /* Let it leak, the leak is a constrained amount. */
+            dhp->dh_errors = 0;
+            return;
+        }
+        /* We make the string content well-defined by an initial
+           NUL byte, but this is not really necessary. */
+        newstr[0] = 0;
+    }
+}
+
+void 
+dwarf_harmless_cleanout(struct Dwarf_Harmless_s *dhp)
+{
+     unsigned i = 0;
+     if(!dhp->dh_errors) {
+         return;
+     }
+     for(i = 0; i < dhp->dh_maxcount; ++i) {
+         free(dhp->dh_errors[i]);
+     } 
+     free(dhp->dh_errors); 
+     dhp->dh_errors = 0;     
+     dhp->dh_maxcount = 0;     
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_harmless.h	Sun May 22 03:13:22 2011 +0100
@@ -0,0 +1,31 @@
+/*
+
+  Copyright (C) 2010 David Anderson.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+*/
+
+
+
+void dwarf_harmless_init(struct Dwarf_Harmless_s *dhp,unsigned size);
+void dwarf_harmless_cleanout(struct Dwarf_Harmless_s *dhp);
+
--- a/usr/src/tools/ctf/dwarf/common/dwarf_incl.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_incl.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000, 2002, 2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2008-2010 David Anderson. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +18,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -37,6 +38,14 @@
 
 #ifndef DWARF_INCL_H
 #define DWARF_INCL_H
+#if (!defined(HAVE_RAW_LIBELF_OK) && defined(HAVE_LIBELF_OFF64_OK) )
+/* At a certain point libelf.h requires _GNU_SOURCE.
+   here we assume the criteria in configure determine that
+   usefully.
+*/
+#define _GNU_SOURCE 1
+#endif
+
 
 #include "libdwarfdefs.h"
 #include <string.h>
@@ -46,8 +55,8 @@
 #endif
 
 #include <limits.h>
+#include <dwarf.h>
 #include <libdwarf.h>
-#include <dwarf.h>
 
 #include "dwarf_base_types.h"
 #include "dwarf_alloc.h"
--- a/usr/src/tools/ctf/dwarf/common/dwarf_init_finish.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_init_finish.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,8 @@
 /*
 
-  Copyright (C) 2000,2002,2003 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2002,2003,2004,2005 Silicon Graphics, Inc. All Rights Reserved.
+  Portions Copyright (C) 2008-2010 Arxan Technologies, Inc. All Rights Reserved.
+  Portions Copyright (C) 2009-2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +21,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -33,53 +35,24 @@
 
 */
 
-
-
 #include "config.h"
 #include "dwarf_incl.h"
-#ifdef HAVE_ELF_H
-#include <elf.h>
-#endif
-#ifdef __SGI_FAST_LIBELF
-#include <libelf_sgi.h>
-#else
-#ifdef HAVE_LIBELF_H
-#include <libelf.h>
-#else
-#ifdef HAVE_LIBELF_LIBELF_H
-#include <libelf/libelf.h>
-#endif
-#endif
-#endif /* !defined(__SGI_FAST_LIBELF) */
-
-#include <gelf.h>
-#include <strings.h>
-#include <sys/elf_386.h>
 
 #include <stdio.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <string.h>
 #include <stdlib.h>
-#include <malloc.h>
 
 #include "dwarf_incl.h"
+#include "malloc_check.h"
 
 #define DWARF_DBG_ERROR(dbg,errval,retval) \
      _dwarf_error(dbg, error, errval); return(retval);
 
-#define FALSE	0
-#define TRUE	1
+#define FALSE 0
+#define TRUE  1
 
-#ifdef __SGI_FAST_LIBELF
-#else
-#ifdef HAVE_ELF64_GETEHDR
-extern Elf64_Ehdr *elf64_getehdr(Elf *);
-#endif
-#ifdef HAVE_ELF64_GETSHDR
-extern Elf64_Shdr *elf64_getshdr(Elf_Scn *);
-#endif
-#endif /* !defined(__SGI_FAST_LIBELF) */
 
 
 /* This static is copied to the dbg on dbg init
@@ -90,7 +63,18 @@
    Value non-zero means do not do the check.
 */
 static Dwarf_Small _dwarf_assume_string_bad;
+static Dwarf_Small _dwarf_apply_relocs = 1;
 
+/* Call this after calling dwarf_init but before doing anything else.
+ * It applies to all objects, not just the current object.
+ */
+int
+dwarf_set_reloc_application(int apply)
+{
+    int oldval = _dwarf_apply_relocs;
+    _dwarf_apply_relocs = apply;
+    return oldval;
+}
 
 int
 dwarf_set_stringcheck(int newval)
@@ -101,24 +85,46 @@
     return oldval;
 }
 
-#ifdef __SGI_FAST_LIBELF
-/*
-	This function translates an elf_sgi error code into a libdwarf
-	code.
- */
+/* Unifies the basic duplicate/empty testing and section
+ * data setting to one place. */
 static int
-_dwarf_error_code_from_elf_sgi_error_code(enum elf_sgi_error_type val)
+get_basic_section_data(Dwarf_Debug dbg,
+    struct Dwarf_Section_s *secdata,
+    struct Dwarf_Obj_Access_Section_s *doas,
+    Dwarf_Half section_index,
+    Dwarf_Error* error,
+    int duperr, int emptyerr )
 {
-    switch (val) {
-    case ELF_SGI_ERROR_OK:        return DW_DLE_NE;
-    case ELF_SGI_ERROR_BAD_ALLOC: return DW_DLE_MAF;
-    case ELF_SGI_ERROR_FORMAT:    return DW_DLE_MDE;
-    case ELF_SGI_ERROR_ERRNO:     return DW_DLE_IOF;
-    case ELF_SGI_ERROR_TOO_BIG:   return DW_DLE_MOF;
-    default:                      return DW_DLE_LEE;
+    if (secdata->dss_index != 0) {
+        DWARF_DBG_ERROR(dbg, duperr, DW_DLV_ERROR);
+    }
+    if (doas->size == 0) {
+        if (emptyerr == 0 ) {
+            /* Allow empty section. */
+            return DW_DLV_OK;
+        }
+        /* Know no reason to allow section */
+        DWARF_DBG_ERROR(dbg, emptyerr, DW_DLV_ERROR);
     }
+    secdata->dss_index = section_index;
+    secdata->dss_size = doas->size;
+    secdata->dss_addr = doas->addr;
+    secdata->dss_link = doas->link;
+    return DW_DLV_OK;
 }
-#endif
+
+
+static void
+add_rela_data( struct Dwarf_Section_s *secdata,
+    struct Dwarf_Obj_Access_Section_s *doas,
+    Dwarf_Half section_index)
+{
+    secdata->dss_reloc_index = section_index;
+    secdata->dss_reloc_size = doas->size;
+    secdata->dss_reloc_addr = doas->addr;
+    secdata->dss_reloc_symtab = doas->link;
+    secdata->dss_reloc_link = doas->link;
+}
 
 /*
     Given an Elf ptr, set up dbg with pointers
@@ -138,672 +144,434 @@
     DW_DLV_NO_ENTRY or DW_DLV_OK or DW_DLV_ERROR
 */
 static int
-_dwarf_setup(Dwarf_Debug dbg, dwarf_elf_handle elf, Dwarf_Error * error)
+_dwarf_setup(Dwarf_Debug dbg, Dwarf_Error * error)
 {
-#ifdef __SGI_FAST_LIBELF
-    Elf64_Ehdr ehdr;
-    Elf64_Shdr shdr;
-    enum elf_sgi_error_type sres;
-    unsigned char const* ehdr_ident;
-#else
-    Elf32_Ehdr *ehdr32;
-
-#ifdef HAVE_ELF64_GETEHDR
-    Elf64_Ehdr *ehdr64;
-#endif
-    Elf32_Shdr *shdr32;
+    const char *scn_name = 0;
+    int foundDwarf = 0;
+    struct Dwarf_Obj_Access_Interface_s * obj = 0;
 
-#ifdef HAVE_ELF64_GETSHDR
-    Elf64_Shdr *shdr64;
-#endif
-    Elf_Scn *scn;
-    char *ehdr_ident;
-#endif /* !defined(__SGI_FAST_LIBELF) */
-    Dwarf_Half machine;
-    char *scn_name;
-    int is_64bit;
-    int foundDwarf;
+    Dwarf_Endianness endianness;
 
-    Dwarf_Unsigned section_size;
-    Dwarf_Unsigned section_count;
-    Dwarf_Half section_index;
+    Dwarf_Unsigned section_size = 0;
+    Dwarf_Unsigned section_count = 0;
+    Dwarf_Half section_index = 0;
+    Dwarf_Addr section_addr = 0;
 
     foundDwarf = FALSE;
-    dbg->de_elf = elf;
 
     dbg->de_assume_string_in_bounds = _dwarf_assume_string_bad;
 
-#ifdef __SGI_FAST_LIBELF
-    sres = elf_sgi_ehdr(elf, &ehdr);
-    if (sres != ELF_SGI_ERROR_OK) {
-	DWARF_DBG_ERROR(dbg, _dwarf_error_code_from_elf_sgi_error_code(sres),
-			DW_DLV_ERROR);
-    }
-    ehdr_ident = ehdr.e_ident;
-    section_count = ehdr.e_shnum;
-    machine = ehdr.e_machine;
-#else
-    if ((ehdr_ident = elf_getident(elf, NULL)) == NULL) {
-	DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETIDENT_ERROR, DW_DLV_ERROR);
-    }
-#endif
-
-    is_64bit = (ehdr_ident[EI_CLASS] == ELFCLASS64);
-
-
     dbg->de_same_endian = 1;
     dbg->de_copy_word = memcpy;
+    obj = dbg->de_obj_file;
+    endianness = obj->methods->get_byte_order(obj->object);
 #ifdef WORDS_BIGENDIAN
     dbg->de_big_endian_object = 1;
-    if (ehdr_ident[EI_DATA] == ELFDATA2LSB) {
-	dbg->de_same_endian = 0;
-	dbg->de_big_endian_object = 0;
-	dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
+    if (endianness == DW_OBJECT_LSB ) {
+        dbg->de_same_endian = 0;
+        dbg->de_big_endian_object = 0;
+        dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
     }
 #else /* little endian */
     dbg->de_big_endian_object = 0;
-    if (ehdr_ident[EI_DATA] == ELFDATA2MSB) {
-	dbg->de_same_endian = 0;
+    if (endianness == DW_OBJECT_MSB ) {
+        dbg->de_same_endian = 0;
         dbg->de_big_endian_object = 1;
-	dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
+        dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
     }
 #endif /* !WORDS_BIGENDIAN */
 
-    /* The following de_length_size is Not Too Significant.
-	Only used one calculation, and an appoximate one at that. */
-    dbg->de_length_size = is_64bit ? 8 : 4;
-    dbg->de_pointer_size = is_64bit ? 8 : 4;
-
 
-#ifdef __SGI_FAST_LIBELF
-    /* We've already loaded the ELF header, so there's nothing to do here */
-#else
-#ifdef HAVE_ELF64_GETEHDR
-    if (is_64bit) {
-	ehdr64 = elf64_getehdr(elf);
-	if (ehdr64 == NULL) {
-	    DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETEHDR_ERROR,
-			    DW_DLV_ERROR);
-	}
-        section_count = ehdr64->e_shnum;
-        machine = ehdr64->e_machine;
-    } else
-#endif
-    {
-	ehdr32 = elf32_getehdr(elf);
-	if (ehdr32 == NULL) {
-	    DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETEHDR_ERROR,
-			    DW_DLV_ERROR);
-	}
-        section_count = ehdr32->e_shnum;
-        machine = ehdr32->e_machine;
-    }
-#endif /* !defined(__SGI_FAST_LIBELF) */
+    /* The following de_length_size is Not Too Significant. Only used
+       one calculation, and an approximate one at that. */
+    dbg->de_length_size = obj->methods->get_length_size(obj->object);
+    dbg->de_pointer_size = obj->methods->get_pointer_size(obj->object);
 
-    dbg->de_nelfsecs = section_count;
+    section_count = obj->methods->get_section_count(obj->object);
 
-    if (is_64bit && machine != EM_MIPS) {
-        /* MIPS/IRIX makes pointer size and length size 8 for -64.
-           Other platforms make length 4 always. */
-        /* 4 here supports 32bit-offset dwarf2, as emitted by
-           cygnus tools, and the dwarfv2.1 64bit extension setting. */
-        dbg->de_length_size = 4;
-    }
-
-    /* We start at index 1 to skip the initial empty section. */
-    for (section_index = 1; section_index < section_count; ++section_index) {
-
-#ifdef __SGI_FAST_LIBELF
-	sres = elf_sgi_shdr(elf, section_index, &shdr);
-	if (sres != ELF_SGI_ERROR_OK) {
-	    DWARF_DBG_ERROR(dbg, _dwarf_error_code_from_elf_sgi_error_code(sres),
-			    DW_DLV_ERROR);
-	}
-
-	section_size = shdr.sh_size;
+    /* We can skip index 0 when considering ELF files, but not other
+       object types. */
+    for (section_index = 0; section_index < section_count;
+         ++section_index) {
+        
+        struct Dwarf_Obj_Access_Section_s doas;
+        int res = DW_DLV_ERROR;
+        int err;
 
-	sres = elf_sgi_string(elf, ehdr.e_shstrndx, shdr.sh_name, (char const** )&scn_name);
-	if (sres != ELF_SGI_ERROR_OK) {
-	    DWARF_DBG_ERROR(dbg, _dwarf_error_code_from_elf_sgi_error_code(sres),
-			    DW_DLV_ERROR);
-	}
-#else /* !defined(__SGI_FAST_LIBELF) */
-	scn = elf_getscn(elf, section_index);
-	if (scn == NULL) {
-	    DWARF_DBG_ERROR(dbg, DW_DLE_MDE,
-			    DW_DLV_ERROR);
-	}
+        res = obj->methods->get_section_info(obj->object, 
+                                             section_index, 
+                                             &doas, &err);
+        if(res == DW_DLV_ERROR){
+          DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR);
+        }
 
-#ifdef HAVE_ELF64_GETSHDR
-	if (is_64bit) {
-	    shdr64 = elf64_getshdr(scn);
-	    if (shdr64 == NULL) {
-		DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETSHDR_ERROR,
-				DW_DLV_ERROR);
-	    }
+        section_addr = doas.addr;
+        section_size = doas.size;
+        scn_name = doas.name;
 
-	    section_size = shdr64->sh_size;
-
-	    if ((scn_name = elf_strptr(elf, ehdr64->e_shstrndx,
-				       shdr64->sh_name))
-		== NULL) {
-		DWARF_DBG_ERROR(dbg, DW_DLE_ELF_STRPTR_ERROR,
-				DW_DLV_ERROR);
-	    }
-	} else
-#endif /* HAVE_ELF64_GETSHDR */
-	{
-	    if ((shdr32 = elf32_getshdr(scn)) == NULL) {
-		DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETSHDR_ERROR, 0);
-	    }
-
-	    section_size = shdr32->sh_size;
-
-	    if ((scn_name = elf_strptr(elf, ehdr32->e_shstrndx,
-				       shdr32->sh_name)) == NULL) {
-		DWARF_DBG_ERROR(dbg, DW_DLE_ELF_STRPTR_ERROR,
-				DW_DLV_ERROR);
-	    }
-	}
-#endif /* !defined(__SGI_FAST_LIBELF) */
-
-	if (strncmp(scn_name, ".debug_", 7)
-	    && strcmp(scn_name, ".eh_frame")
-	    )
-	    continue;
+        if (strncmp(scn_name, ".debug_", 7)
+            && strcmp(scn_name, ".eh_frame")
+            && strcmp(scn_name, ".symtab")
+            && strcmp(scn_name, ".strtab")
+            && strncmp(scn_name, ".rela.",6))  {
+            continue;
+        }
+        else if (strcmp(scn_name, ".debug_info") == 0) {
+            res = get_basic_section_data(dbg,&dbg->de_debug_info, &doas,
+                  section_index,error,
+                  DW_DLE_DEBUG_INFO_DUPLICATE,DW_DLE_DEBUG_INFO_NULL);
+            if(res != DW_DLV_OK) {
+                  return res;
+            }
+            foundDwarf = TRUE;
+        }
+        else if (strcmp(scn_name, ".debug_abbrev") == 0) {
+            res = get_basic_section_data(dbg,&dbg->de_debug_abbrev, &doas,
+                  section_index,error,
+                  DW_DLE_DEBUG_ABBREV_DUPLICATE,DW_DLE_DEBUG_ABBREV_NULL);
+            if(res != DW_DLV_OK) {
+                  return res;
+            }
+        }
+        else if (strcmp(scn_name, ".debug_aranges") == 0) {
+            res = get_basic_section_data(dbg,&dbg->de_debug_aranges, &doas,
+                  section_index,error,
+                  DW_DLE_DEBUG_ARANGES_DUPLICATE,0);
+            if(res != DW_DLV_OK) {
+                  return res;
+            }
+        }
 
-	else if (strcmp(scn_name, ".debug_info") == 0) {
-	    if (dbg->de_debug_info != NULL) {
-		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_INFO_DUPLICATE,
-				DW_DLV_ERROR);
-	    }
-	    if (section_size == 0) {
-		/* Know no reason to allow empty debug_info section */
-		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_INFO_NULL,
-				DW_DLV_ERROR);
-	    }
-	    foundDwarf = TRUE;
-	    dbg->de_debug_info_index = section_index;
-	    dbg->de_debug_info_size = section_size;
-	}
-
-	else if (strcmp(scn_name, ".debug_abbrev") == 0) {
-	    if (dbg->de_debug_abbrev != NULL) {
-		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_ABBREV_DUPLICATE,
-				DW_DLV_ERROR);
-	    }
-	    if (section_size == 0) {
-		/* Know no reason to allow empty debug_abbrev section */
-		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_ABBREV_NULL,
-				DW_DLV_ERROR);
-	    }
-	    dbg->de_debug_abbrev_index = section_index;
-	    dbg->de_debug_abbrev_size = section_size;
-	}
-
-	else if (strcmp(scn_name, ".debug_aranges") == 0) {
-	    if (dbg->de_debug_aranges_index != 0) {
-		DWARF_DBG_ERROR(dbg,
-				DW_DLE_DEBUG_ARANGES_DUPLICATE,
-				DW_DLV_ERROR);
-	    }
-	    if (section_size == 0) {
-		/* a zero size section is just empty. Ok, no error */
-		continue;
-	    }
-	    dbg->de_debug_aranges_index = section_index;
-	    dbg->de_debug_aranges_size = section_size;
-	}
+        else if (strcmp(scn_name, ".debug_line") == 0) {
+            res = get_basic_section_data(dbg,&dbg->de_debug_line, &doas,
+                  section_index,error,
+                  DW_DLE_DEBUG_LINE_DUPLICATE,0);
+            if(res != DW_DLV_OK) {
+                  return res;
+            }
+        }
+        else if (strcmp(scn_name, ".debug_frame") == 0) {
+            res = get_basic_section_data(dbg,&dbg->de_debug_frame, &doas,
+                  section_index,error,
+                  DW_DLE_DEBUG_FRAME_DUPLICATE,0);
+            if(res != DW_DLV_OK) {
+                  return res;
+            }
+            foundDwarf = TRUE;
+        } else if (strcmp(scn_name, ".eh_frame") == 0) {
+            /* gnu egcs-1.1.2 data */
+            res = get_basic_section_data(dbg,&dbg->de_debug_frame_eh_gnu, &doas,
+                  section_index,error,
+                  DW_DLE_DEBUG_FRAME_DUPLICATE,0);
+            if(res != DW_DLV_OK) {
+                  return res;
+            }
+            foundDwarf = TRUE;
+        }
+        else if (strcmp(scn_name, ".debug_loc") == 0) {
+            res = get_basic_section_data(dbg,&dbg->de_debug_loc, &doas,
+                  section_index,error,
+                  DW_DLE_DEBUG_LOC_DUPLICATE,0);
+            if(res != DW_DLV_OK) {
+                  return res;
+            }
+        }
+        else if (strcmp(scn_name, ".debug_pubnames") == 0) {
+            res = get_basic_section_data(dbg,&dbg->de_debug_pubnames, &doas,
+                  section_index,error,
+                  DW_DLE_DEBUG_PUBNAMES_DUPLICATE,0);
+            if(res != DW_DLV_OK) {
+                  return res;
+            }
+        }
 
-	else if (strcmp(scn_name, ".debug_line") == 0) {
-	    if (dbg->de_debug_line_index != 0) {
-		DWARF_DBG_ERROR(dbg,
-				DW_DLE_DEBUG_LINE_DUPLICATE,
-				DW_DLV_ERROR);
-	    }
-	    if (section_size == 0) {
-		/* a zero size section is just empty. Ok, no error */
-		continue;
-	    }
-	    dbg->de_debug_line_index = section_index;
-	    dbg->de_debug_line_size = section_size;
-	}
-
-	else if (strcmp(scn_name, ".debug_frame") == 0) {
-	    if (dbg->de_debug_frame_index != 0) {
-		DWARF_DBG_ERROR(dbg,
-				DW_DLE_DEBUG_FRAME_DUPLICATE,
-				DW_DLV_ERROR);
-	    }
-	    if (section_size == 0) {
-		/* a zero size section is just empty. Ok, no error */
-		continue;
-	    }
-	    dbg->de_debug_frame_index = section_index;
-	    dbg->de_debug_frame_size = section_size;
-	    foundDwarf = TRUE;
-	} else if (strcmp(scn_name, ".eh_frame") == 0) {
-	    /* gnu egcs-1.1.2 data */
-	    if (dbg->de_debug_frame_eh_gnu_index != 0) {
-		DWARF_DBG_ERROR(dbg,
-				DW_DLE_DEBUG_FRAME_DUPLICATE,
-				DW_DLV_ERROR);
-	    }
-	    if (section_size == 0) {
-		/* a zero size section is just empty. Ok, no error */
-		continue;
-	    }
-	    dbg->de_debug_frame_eh_gnu_index = section_index;
-	    dbg->de_debug_frame_size_eh_gnu = section_size;
-	    foundDwarf = TRUE;
-	}
-
-	else if (strcmp(scn_name, ".debug_loc") == 0) {
-	    if (dbg->de_debug_loc_index != 0) {
-		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_LOC_DUPLICATE,
-				DW_DLV_ERROR);
-	    }
-	    if (section_size == 0) {
-		/* a zero size section is just empty. Ok, no error */
-		continue;
-	    }
-	    dbg->de_debug_loc_index = section_index;
-	    dbg->de_debug_loc_size = section_size;
-	}
-
-
-	else if (strcmp(scn_name, ".debug_pubnames") == 0) {
-	    if (dbg->de_debug_pubnames_index != 0) {
-		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_PUBNAMES_DUPLICATE,
-				DW_DLV_ERROR);
-	    }
-	    if (section_size == 0) {
-		/* a zero size section is just empty. Ok, no error */
-		continue;
-	    }
-	    dbg->de_debug_pubnames_index = section_index;
-	    dbg->de_debug_pubnames_size = section_size;
-	}
-
-	else if (strcmp(scn_name, ".debug_str") == 0) {
-	    if (dbg->de_debug_str_index != 0) {
-		DWARF_DBG_ERROR(dbg,
-				DW_DLE_DEBUG_STR_DUPLICATE,
-				DW_DLV_ERROR);
-	    }
-	    if (section_size == 0) {
-		/* a zero size section is just empty. Ok, no error */
-		continue;
-	    }
-	    dbg->de_debug_str_index = section_index;
-	    dbg->de_debug_str_size = section_size;
-	}
-
-	else if (strcmp(scn_name, ".debug_funcnames") == 0) {
-	    if (dbg->de_debug_funcnames_index != 0) {
-		DWARF_DBG_ERROR(dbg,
-				DW_DLE_DEBUG_FUNCNAMES_DUPLICATE,
-				DW_DLV_ERROR);
-	    }
-	    if (section_size == 0) {
-		/* a zero size section is just empty. Ok, no error */
-		continue;
-	    }
-	    dbg->de_debug_funcnames_index = section_index;
-	    dbg->de_debug_funcnames_size = section_size;
-	}
-
-	else if (strcmp(scn_name, ".debug_typenames") == 0) {
-	    if (dbg->de_debug_typenames_index != 0) {
-		DWARF_DBG_ERROR(dbg,
-				DW_DLE_DEBUG_TYPENAMES_DUPLICATE,
-				DW_DLV_ERROR);
-	    }
-	    if (section_size == 0) {
-		/* a zero size section is just empty. Ok, no error */
-		continue;
-	    }
-	    dbg->de_debug_typenames_index = section_index;
-	    dbg->de_debug_typenames_size = section_size;
-	}
-
-	else if (strcmp(scn_name, ".debug_varnames") == 0) {
-	    if (dbg->de_debug_varnames_index != 0) {
-		DWARF_DBG_ERROR(dbg,
-				DW_DLE_DEBUG_VARNAMES_DUPLICATE,
-				DW_DLV_ERROR);
-	    }
-	    if (section_size == 0) {
-		/* a zero size section is just empty. Ok, no error */
-		continue;
-	    }
-	    dbg->de_debug_varnames_index = section_index;
-	    dbg->de_debug_varnames_size = section_size;
-	}
-
-	else if (strcmp(scn_name, ".debug_weaknames") == 0) {
-	    if (dbg->de_debug_weaknames_index != 0) {
-		DWARF_DBG_ERROR(dbg,
-				DW_DLE_DEBUG_WEAKNAMES_DUPLICATE,
-				DW_DLV_ERROR);
-	    }
-	    if (section_size == 0) {
-		/* a zero size section is just empty. Ok, no error */
-		continue;
-	    }
-	    dbg->de_debug_weaknames_index = section_index;
-	    dbg->de_debug_weaknames_size = section_size;
-	} else if (strcmp(scn_name, ".debug_macinfo") == 0) {
-	    if (dbg->de_debug_macinfo_index != 0) {
-		DWARF_DBG_ERROR(dbg,
-				DW_DLE_DEBUG_MACINFO_DUPLICATE,
-				DW_DLV_ERROR);
-	    }
-	    if (section_size == 0) {
-		/* a zero size section is just empty. Ok, no error */
-		continue;
-	    }
-	    dbg->de_debug_macinfo_index = section_index;
-	    dbg->de_debug_macinfo_size = section_size;
-	}
+        else if (strcmp(scn_name, ".debug_str") == 0) {
+            res = get_basic_section_data(dbg,&dbg->de_debug_str, &doas,
+                  section_index,error,
+                  DW_DLE_DEBUG_STR_DUPLICATE,0);
+            if(res != DW_DLV_OK) {
+                  return res;
+            }
+        }
+        else if (strcmp(scn_name, ".debug_funcnames") == 0) {
+            /* SGI IRIX-only. */
+            res = get_basic_section_data(dbg,&dbg->de_debug_funcnames, &doas,
+                  section_index,error,
+                  DW_DLE_DEBUG_FUNCNAMES_DUPLICATE,0);
+            if(res != DW_DLV_OK) {
+                  return res;
+            }
+        }
+        else if (strcmp(scn_name, ".debug_typenames") == 0) {
+            /* SGI IRIX-only, created years before DWARF3. Content
+               essentially identical to .debug_pubtypes.  */
+            res = get_basic_section_data(dbg,&dbg->de_debug_typenames, &doas,
+                  section_index,error,
+                  DW_DLE_DEBUG_TYPENAMES_DUPLICATE,0);
+            if(res != DW_DLV_OK) {
+                  return res;
+            }
+        } else if (strcmp(scn_name, ".debug_pubtypes") == 0) {
+            /* Section new in DWARF3.  */
+            res = get_basic_section_data(dbg,&dbg->de_debug_pubtypes, &doas,
+                  section_index,error,
+                  DW_DLE_DEBUG_PUBTYPES_DUPLICATE,0);
+            if(res != DW_DLV_OK) {
+                  return res;
+            }
+        }
+        else if (strcmp(scn_name, ".debug_varnames") == 0) {
+            /* SGI IRIX-only.  */
+            res = get_basic_section_data(dbg,&dbg->de_debug_varnames, &doas,
+                  section_index,error,
+                  DW_DLE_DEBUG_VARNAMES_DUPLICATE,0);
+            if(res != DW_DLV_OK) {
+                  return res;
+            }
+        }
+        else if (strcmp(scn_name, ".debug_weaknames") == 0) {
+            /* SGI IRIX-only. */
+            res = get_basic_section_data(dbg,&dbg->de_debug_weaknames, &doas,
+                  section_index,error,
+                  DW_DLE_DEBUG_WEAKNAMES_DUPLICATE,0);
+            if(res != DW_DLV_OK) {
+                  return res;
+            }
+        } else if (strcmp(scn_name, ".debug_macinfo") == 0) {
+            res = get_basic_section_data(dbg,&dbg->de_debug_macinfo, &doas,
+                  section_index,error,
+                  DW_DLE_DEBUG_MACINFO_DUPLICATE,0);
+            if(res != DW_DLV_OK) {
+                  return res;
+            }
+        }
+        else if (strcmp(scn_name, ".debug_ranges") == 0) {
+            res = get_basic_section_data(dbg,&dbg->de_debug_ranges, &doas,
+                  section_index,error,
+                  DW_DLE_DEBUG_RANGES_DUPLICATE,0);
+            if(res != DW_DLV_OK) {
+                  return res;
+            }
+            foundDwarf = TRUE;
+        }
+        else if (strcmp(scn_name, ".symtab") == 0) {
+            res = get_basic_section_data(dbg,&dbg->de_elf_symtab, &doas,
+                  section_index,error,
+                  DW_DLE_DEBUG_SYMTAB_ERR,0);
+            if(res != DW_DLV_OK) {
+                  return res;
+            }
+        }
+        else if (strcmp(scn_name, ".strtab")  == 0) {
+            res = get_basic_section_data(dbg,&dbg->de_elf_strtab, &doas,
+                  section_index,error,
+                  DW_DLE_DEBUG_STRTAB_ERR,0);
+            if(res != DW_DLV_OK) {
+                  return res;
+            }
+        }
+        else if (strncmp(scn_name, ".rela.debug_",12) == 0) {
+            const char *rcn_name = scn_name + 5;
+            if (strcmp(rcn_name, ".debug_info") == 0) {
+                add_rela_data(&dbg->de_debug_info,&doas,section_index);
+            } else if (strcmp(rcn_name, ".debug_abbrev") == 0) {
+                add_rela_data(&dbg->de_debug_abbrev,&doas,section_index);
+            } else if (strcmp(rcn_name, ".debug_aranges") == 0) {
+                add_rela_data(&dbg->de_debug_aranges,&doas,section_index);
+            } else if (strcmp(rcn_name, ".debug_line") == 0) {
+                add_rela_data(&dbg->de_debug_line,&doas,section_index);
+            } else if (strcmp(rcn_name, ".debug_frame") == 0) {
+                add_rela_data(&dbg->de_debug_frame,&doas,section_index);
+            } else if (strcmp(rcn_name, ".eh_frame") == 0) {
+                add_rela_data(&dbg->de_debug_frame_eh_gnu,&doas,section_index);
+            } else if (strcmp(rcn_name, ".debug_loc") == 0) {
+                add_rela_data(&dbg->de_debug_loc,&doas,section_index);
+            } else if (strcmp(rcn_name, ".debug_pubnames") == 0) {
+                add_rela_data(&dbg->de_debug_pubnames,&doas,section_index);
+            } else if (strcmp(rcn_name, ".debug_str") == 0) {
+                add_rela_data(&dbg->de_debug_str,&doas,section_index);
+            } else if (strcmp(rcn_name, ".debug_funcnames") == 0) {
+                add_rela_data(&dbg->de_debug_funcnames,&doas,section_index);
+            } else if (strcmp(rcn_name, ".debug_typenames") == 0) {
+                add_rela_data(&dbg->de_debug_typenames,&doas,section_index);
+            } else if (strcmp(rcn_name, ".debug_pubtypes") == 0) {
+                add_rela_data(&dbg->de_debug_pubtypes,&doas,section_index);
+            } else if (strcmp(rcn_name, ".debug_varnames") == 0) {
+                add_rela_data(&dbg->de_debug_varnames,&doas,section_index);
+            } else if (strcmp(rcn_name, ".debug_weaknames") == 0) {
+                add_rela_data(&dbg->de_debug_weaknames,&doas,section_index);
+            } else if (strcmp(rcn_name, ".debug_macinfo") == 0) {
+                add_rela_data(&dbg->de_debug_macinfo,&doas,section_index);
+            }
+        }
     }
     if (foundDwarf) {
-	return DW_DLV_OK;
+        return DW_DLV_OK;
     }
-
-    return (DW_DLV_NO_ENTRY);
+    return DW_DLV_NO_ENTRY;
 }
 
 
 /*
-    The basic dwarf initializer function for consumers.
-    Return NULL on error.
+    Use a Dwarf_Obj_Access_Interface to kick things off. All other 
+    init routines eventually use this one.
+    The returned Dwarf_Debug contains a copy of *obj
+    the callers copy of *obj may be freed whenever the caller
+    wishes.
 */
-int
-dwarf_init(int fd,
-	   Dwarf_Unsigned access,
-	   Dwarf_Handler errhand,
-	   Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, Dwarf_Error * error)
+int 
+dwarf_object_init(Dwarf_Obj_Access_Interface* obj, Dwarf_Handler errhand,
+               Dwarf_Ptr errarg, Dwarf_Debug* ret_dbg, 
+               Dwarf_Error* error)
 {
-    Dwarf_Debug dbg;
-    struct stat fstat_buf;
-    dwarf_elf_handle elf;
-    int res;
-#ifdef __SGI_FAST_LIBELF
-    enum elf_sgi_error_type sres;
-#else
-    Elf_Cmd what_kind_of_elf_read;
-#endif
+    Dwarf_Debug dbg = 0;
+    int setup_result = DW_DLV_OK;
 
     dbg = _dwarf_get_debug();
     if (dbg == NULL) {
-	DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR);
+        DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR);
     }
     dbg->de_errhand = errhand;
     dbg->de_errarg = errarg;
-
-    if (fstat(fd, &fstat_buf) != 0) {
-	DWARF_DBG_ERROR(dbg, DW_DLE_FSTAT_ERROR, DW_DLV_ERROR);
-    }
-    if (!S_ISREG(fstat_buf.st_mode)) {
-	DWARF_DBG_ERROR(dbg, DW_DLE_FSTAT_MODE_ERROR, DW_DLV_ERROR);
-    }
+    dbg->de_frame_rule_initial_value = DW_FRAME_REG_INITIAL_VALUE;
+    dbg->de_frame_reg_rules_entry_count = DW_FRAME_LAST_REG_NUM;
+#ifdef HAVE_OLD_FRAME_CFA_COL
+    /* DW_FRAME_CFA_COL is really only suitable for old libdwarf frame
+       interfaces and its value of 0 there is only usable where
+       (as in MIPS) register 0 has no value other than 0 so
+       we can use the frame table column 0 for the CFA value
+       (and rely on client software to know when 'register 0'
+       is the cfa and when to just use a value 0 for register 0). 
+    */
+    dbg->de_frame_cfa_col_number = DW_FRAME_CFA_COL;
+#else
+    dbg->de_frame_cfa_col_number = DW_FRAME_CFA_COL3;
+#endif
+    dbg->de_frame_same_value_number = DW_FRAME_SAME_VAL;
+    dbg->de_frame_undefined_value_number  = DW_FRAME_UNDEFINED_VAL;
 
-    if (access != DW_DLC_READ) {
-	DWARF_DBG_ERROR(dbg, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR);
-    }
-    dbg->de_access = access;
+    dbg->de_obj_file = obj;
 
-#ifdef __SGI_FAST_LIBELF
-    elf = elf_sgi_new();
-    if (elf == NULL) {
-	DWARF_DBG_ERROR(dbg, DW_DLE_MAF, DW_DLV_ERROR);
+    setup_result = _dwarf_setup(dbg, error);
+    if (setup_result != DW_DLV_OK) {
+        /* The status we want to return  here is of _dwarf_setup,
+           not of the  _dwarf_free_all_of_one_debug(dbg) call. 
+           So use a local status variable for the free.  */
+        int freeresult = _dwarf_free_all_of_one_debug(dbg);
+        if (freeresult == DW_DLV_ERROR) {
+            DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR);
+        }
+        dwarf_malloc_check_complete("After Final free");
+        return setup_result;
     }
 
-    sres = elf_sgi_begin_fd(elf, fd, 0);
-    if (sres != ELF_SGI_ERROR_OK) {
-	DWARF_DBG_ERROR(dbg, _dwarf_error_code_from_elf_sgi_error_code(sres),
-			DW_DLV_ERROR);
-    }
-#else
-    elf_version(EV_CURRENT);
-    /* changed to mmap request per bug 281217. 6/95 */
-#ifdef HAVE_ELF_C_READ_MMAP
-    /* ELF_C_READ_MMAP is an SGI IRIX specific enum value from IRIX
-       libelf.h meaning read but use mmap */
-    what_kind_of_elf_read = ELF_C_READ_MMAP;
-#else
-    /* ELF_C_READ is a portable value */
-    what_kind_of_elf_read  = ELF_C_READ;
-#endif
+    dwarf_harmless_init(&dbg->de_harmless_errors,
+        DW_HARMLESS_ERROR_CIRCULAR_LIST_DEFAULT_SIZE);
 
-    if ((elf = elf_begin(fd, what_kind_of_elf_read, 0)) == NULL) {
-	DWARF_DBG_ERROR(dbg, DW_DLE_ELF_BEGIN_ERROR, DW_DLV_ERROR);
-    }
-#endif /* !defined(__SGI_FAST_LIBELF) */
-
-    dbg->de_elf_must_close = 1;
-    if ((res = _dwarf_setup(dbg, elf, error)) != DW_DLV_OK) {
-	free(dbg);
-	return (res);
-    }
-
-    /* call cannot fail: no malloc or free involved */
+    /* This call cannot fail: allocates nothing, releases nothing */
     _dwarf_setup_debug(dbg);
 
-    *ret_dbg = dbg;
-    return (DW_DLV_OK);
-}
-
 
-/*
-    The alternate dwarf setup call for consumers
-*/
-int
-dwarf_elf_init(dwarf_elf_handle elf_file_pointer,
-	       Dwarf_Unsigned access,
-	       Dwarf_Handler errhand,
-	       Dwarf_Ptr errarg,
-	       Dwarf_Debug * ret_dbg, Dwarf_Error * error)
-{
-    Dwarf_Debug dbg;
-    int res;
-
-    dbg = _dwarf_get_debug();
-    if (dbg == NULL) {
-	DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR);
-    }
-    dbg->de_errhand = errhand;
-    dbg->de_errarg = errarg;
-
-    if (access != DW_DLC_READ) {
-	DWARF_DBG_ERROR(dbg, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR);
-    }
-    dbg->de_access = access;
-
-    dbg->de_elf_must_close = 0;
-    if ((res = _dwarf_setup(dbg, elf_file_pointer, error)) != DW_DLV_OK) {
-	free(dbg);
-	return (res);
-    }
-
-    /* this call cannot fail: allocates nothing, releases nothing */
-    _dwarf_setup_debug(dbg);
-
     *ret_dbg = dbg;
-    return (DW_DLV_OK);
+    return DW_DLV_OK;    
 }
 
 
 /*
-	Frees all memory that was not previously freed
-	by dwarf_dealloc.
-	Aside from certain categories.
-*/
-int
-dwarf_finish(Dwarf_Debug dbg, Dwarf_Error * error)
+    A finish routine that is completely unaware of ELF.
+
+    Frees all memory that was not previously freed by
+    dwarf_dealloc.
+    Aside frmo certain categories.
+ */
+int 
+dwarf_object_finish(Dwarf_Debug dbg, Dwarf_Error * error)
 {
     int res = DW_DLV_OK;
-    if(dbg->de_elf_must_close) {
-	/* Must do this *before* _dwarf_free_all_of_one_debug()
-	   as that zeroes out dbg contents
-	*/
-#ifdef __SGI_FAST_LIBELF
-	elf_sgi_free(dbg->de_elf);
-#else
-	elf_end(dbg->de_elf);
-#endif
-    }
 
     res = _dwarf_free_all_of_one_debug(dbg);
     if (res == DW_DLV_ERROR) {
-	DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR);
+        DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR);
     }
+    dwarf_malloc_check_complete("After Final free");
 
-    return res;
-
-
+    return res;  
 }
 
 
 /*
-    This function returns the Elf * pointer
-    associated with a Dwarf_Debug.
-*/
-int
-dwarf_get_elf(Dwarf_Debug dbg, dwarf_elf_handle* elf, Dwarf_Error * error)
-{
-    if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_ERROR);
-    }
-
-    *elf = dbg->de_elf;
-    return (DW_DLV_OK);
-}
-
-#if defined(__i386)
-static Dwarf_Small *
-_dwarf_reloc_section(Dwarf_Debug dbg, Dwarf_Half scnidx, Elf_Data *scndata,
-    Dwarf_Error *error)
-{
-	Elf_Data *reldata;
-	GElf_Rela rela;
-	Elf_Scn *scn;
-	GElf_Shdr shdr;
-	char *newdata;
-	int ridx, rscnidx;
-
-	for (rscnidx = 0; rscnidx < dbg->de_nelfsecs; rscnidx++) {
-		if ((scn = elf_getscn(dbg->de_elf, rscnidx)) == NULL ||
-		    gelf_getshdr(scn, &shdr) == NULL) {
-			_dwarf_error(dbg, error, DW_DLE_LEE);
-			return (NULL);
-		}
-
-		if (shdr.sh_type == SHT_RELA &&
-		    shdr.sh_info == scnidx)
-			break;
-	}
-
-	if (rscnidx == dbg->de_nelfsecs)
-		return (scndata->d_buf);
-
-	if ((reldata = elf_getdata(scn, NULL)) == NULL) {
-		_dwarf_error(dbg, error, DW_DLE_LEE);
-		return (NULL);
-	}
-
-	if ((newdata = malloc(scndata->d_size)) == NULL) {
-		_dwarf_error(dbg, error, DW_DLE_MAF);
-		return (NULL);
-	}
-
-	bcopy(scndata->d_buf, newdata, scndata->d_size);
-
-	for (ridx = 0; ridx < shdr.sh_size / sizeof (GElf_Rela); ridx++) {
-		if (gelf_getrela(reldata, ridx, &rela) == NULL)
-			continue;
-
-		if (GELF_R_TYPE(rela.r_info) != R_386_32 &&
-		    GELF_R_TYPE(rela.r_info) != R_386_GOTPC) {
-			fprintf(stderr, "achtung: tell simmonmt@eng about "
-			    "unexpected reloc type %d\n", 
-			    GELF_R_TYPE(rela.r_info));
-			continue;
-		}
-
-		*(uint32_t *)(newdata + rela.r_offset) = rela.r_addend;
-	}
-
-	return ((Dwarf_Small *)newdata);
-}
-#endif
-
-/*
-	Load the ELF section with the specified index and set the
-	pointer pointed to by section_data to the memory where it
-	was loaded.
+    Load the ELF section with the specified index and set the
+    pointer pointed to by section_data to the memory where it
+    was loaded.
  */
 int
 _dwarf_load_section(Dwarf_Debug dbg,
-		    Dwarf_Half section_index,
-		    Dwarf_Small ** section_data,
-		    Dwarf_Error * error)
+    struct Dwarf_Section_s *section,
+    Dwarf_Error * error)
 {
-    if (section_index == 0) {
-	return DW_DLV_NO_ENTRY;
-    }
+    int res  = DW_DLV_ERROR;
+    int err = 0;
+    struct Dwarf_Obj_Access_Interface_s *o = 0;
 
     /* check to see if the section is already loaded */
-    if (*section_data != NULL) {
-	return DW_DLV_OK;
+    if (section->dss_data !=  NULL) {
+        return DW_DLV_OK;
+    }
+    o = dbg->de_obj_file; 
+    res = o->methods->load_section(
+        o->object, section->dss_index, 
+        &section->dss_data, &err);
+    if(res == DW_DLV_ERROR){
+        DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR);
+    }
+    if(_dwarf_apply_relocs == 0) {
+        return res;
     }
-
-    {
-#ifdef __SGI_FAST_LIBELF
-        enum elf_sgi_error_type sres;
-
-        sres = elf_sgi_section(dbg->de_elf,
-		               section_index,
-			       (void**) section_data);
-        if (sres != ELF_SGI_ERROR_OK) {
-	    DWARF_DBG_ERROR(dbg, _dwarf_error_code_from_elf_sgi_error_code(sres),
-			    DW_DLV_ERROR);
-        }
-#else
-        Elf_Scn* scn;
-        Elf_Data* data;
-
-        scn = elf_getscn(dbg->de_elf, section_index);
-        if (scn == NULL) {
-	    _dwarf_error(dbg, error, DW_DLE_MDE);
-	    return DW_DLV_ERROR;
-        }
+    if(section->dss_reloc_size == 0) {
+        return res;
+    }
+    if(!o->methods->relocate_a_section) {
+        return res;
+    }
+    /*apply relocations */
+    res = o->methods->relocate_a_section( o->object, section->dss_index,
+        dbg, &err);
+    if(res == DW_DLV_ERROR) {
+        DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR);
+    }
+    return res;
+}
 
-	/* 
-	    When using libelf as a producer, section data may be stored
-	    in multiple buffers. In libdwarf however, we only use libelf
-	    as a consumer (there is a dwarf producer API, but it doesn't
-	    use libelf). Because of this, this single call to elf_getdata
-	    will retrieve the entire section in a single contiguous buffer.
-	 */
-        data = elf_getdata(scn, NULL);
-        if (data == NULL) {
-	    _dwarf_error(dbg, error, DW_DLE_MDE);
-	    return DW_DLV_ERROR;
-        }
-
-#if defined(__i386)
-	if ((*section_data = _dwarf_reloc_section(dbg, section_index, data,
-	    error)) == NULL)
-		return (DW_DLV_ERROR); /* _dwarf_error is set for us */
-#else
-	*section_data = data->d_buf;
-#endif
-
-#endif /* !defined(__SGI_FAST_LIBELF) */
-    }
-
+/* This is a hack so clients can verify offsets.
+   Added April 2005 so that debugger can detect broken offsets
+   (which happened in an IRIX  -64 executable larger than 2GB
+    using MIPSpro 7.3.1.3 compilers. A couple .debug_pubnames
+    offsets were wrong.).
+*/
+int
+dwarf_get_section_max_offsets(Dwarf_Debug dbg,
+    Dwarf_Unsigned * debug_info_size,
+    Dwarf_Unsigned * debug_abbrev_size,
+    Dwarf_Unsigned * debug_line_size,
+    Dwarf_Unsigned * debug_loc_size,
+    Dwarf_Unsigned * debug_aranges_size,
+    Dwarf_Unsigned * debug_macinfo_size,
+    Dwarf_Unsigned * debug_pubnames_size,
+    Dwarf_Unsigned * debug_str_size,
+    Dwarf_Unsigned * debug_frame_size,
+    Dwarf_Unsigned * debug_ranges_size,
+    Dwarf_Unsigned * debug_typenames_size)
+{
+    *debug_info_size = dbg->de_debug_info.dss_size;
+    *debug_abbrev_size = dbg->de_debug_abbrev.dss_size;
+    *debug_line_size = dbg->de_debug_line.dss_size;
+    *debug_loc_size = dbg->de_debug_loc.dss_size;
+    *debug_aranges_size = dbg->de_debug_aranges.dss_size;
+    *debug_macinfo_size = dbg->de_debug_macinfo.dss_size;
+    *debug_pubnames_size = dbg->de_debug_pubnames.dss_size;
+    *debug_str_size = dbg->de_debug_str.dss_size;
+    *debug_frame_size = dbg->de_debug_frame.dss_size;
+    *debug_ranges_size = dbg->de_debug_ranges.dss_size;
+    *debug_typenames_size = dbg->de_debug_typenames.dss_size;
     return DW_DLV_OK;
 }
--- a/usr/src/tools/ctf/dwarf/common/dwarf_leb.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_leb.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +19,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -57,55 +57,55 @@
        word_number is assumed big enough that the shift has a defined
        result. */
     if ((*leb128 & 0x80) == 0) {
-	if (leb128_length != NULL)
-	    *leb128_length = 1;
-	return (*leb128);
+        if (leb128_length != NULL)
+            *leb128_length = 1;
+        return (*leb128);
     } else if ((*(leb128 + 1) & 0x80) == 0) {
-	if (leb128_length != NULL)
-	    *leb128_length = 2;
+        if (leb128_length != NULL)
+            *leb128_length = 2;
 
-	word_number = *leb128 & 0x7f;
-	word_number |= (*(leb128 + 1) & 0x7f) << 7;
-	return (word_number);
+        word_number = *leb128 & 0x7f;
+        word_number |= (*(leb128 + 1) & 0x7f) << 7;
+        return (word_number);
     } else if ((*(leb128 + 2) & 0x80) == 0) {
-	if (leb128_length != NULL)
-	    *leb128_length = 3;
+        if (leb128_length != NULL)
+            *leb128_length = 3;
 
-	word_number = *leb128 & 0x7f;
-	word_number |= (*(leb128 + 1) & 0x7f) << 7;
-	word_number |= (*(leb128 + 2) & 0x7f) << 14;
-	return (word_number);
+        word_number = *leb128 & 0x7f;
+        word_number |= (*(leb128 + 1) & 0x7f) << 7;
+        word_number |= (*(leb128 + 2) & 0x7f) << 14;
+        return (word_number);
     } else if ((*(leb128 + 3) & 0x80) == 0) {
-	if (leb128_length != NULL)
-	    *leb128_length = 4;
+        if (leb128_length != NULL)
+            *leb128_length = 4;
 
-	word_number = *leb128 & 0x7f;
-	word_number |= (*(leb128 + 1) & 0x7f) << 7;
-	word_number |= (*(leb128 + 2) & 0x7f) << 14;
-	word_number |= (*(leb128 + 3) & 0x7f) << 21;
-	return (word_number);
+        word_number = *leb128 & 0x7f;
+        word_number |= (*(leb128 + 1) & 0x7f) << 7;
+        word_number |= (*(leb128 + 2) & 0x7f) << 14;
+        word_number |= (*(leb128 + 3) & 0x7f) << 21;
+        return (word_number);
     }
 
-    /* The rest handles long numbers Because the 'number' may be
-       larger than the default int/unsigned, we must cast the 'byte'
-       before the shift for the shift to have a defined result. */
+    /* The rest handles long numbers Because the 'number' may be larger 
+       than the default int/unsigned, we must cast the 'byte' before
+       the shift for the shift to have a defined result. */
     number = 0;
     shift = 0;
     byte_length = 1;
     byte = *(leb128);
     for (;;) {
-	number |= ((Dwarf_Unsigned) (byte & 0x7f)) << shift;
+        number |= ((Dwarf_Unsigned) (byte & 0x7f)) << shift;
 
-	if ((byte & 0x80) == 0) {
-	    if (leb128_length != NULL)
-		*leb128_length = byte_length;
-	    return (number);
-	}
-	shift += 7;
+        if ((byte & 0x80) == 0) {
+            if (leb128_length != NULL)
+                *leb128_length = byte_length;
+            return (number);
+        }
+        shift += 7;
 
-	byte_length++;
-	++leb128;
-	byte = *leb128;
+        byte_length++;
+        ++leb128;
+        byte = *leb128;
     }
 }
 
@@ -127,23 +127,23 @@
        turning the leb into a Dwarf_Signed. */
 
     for (;;) {
-	sign = byte & 0x40;
-	number |= ((Dwarf_Signed) ((byte & 0x7f))) << shift;
-	shift += 7;
+        sign = byte & 0x40;
+        number |= ((Dwarf_Signed) ((byte & 0x7f))) << shift;
+        shift += 7;
 
-	if ((byte & 0x80) == 0) {
-	    break;
-	}
-	++leb128;
-	byte = *leb128;
-	byte_length++;
+        if ((byte & 0x80) == 0) {
+            break;
+        }
+        ++leb128;
+        byte = *leb128;
+        byte_length++;
     }
 
     if ((shift < sizeof(Dwarf_Signed) * BITSINBYTE) && sign) {
-	number |= -((Dwarf_Signed) 1 << shift);
+        number |= -((Dwarf_Signed) 1 << shift);
     }
 
     if (leb128_length != NULL)
-	*leb128_length = byte_length;
+        *leb128_length = byte_length;
     return (number);
 }
--- a/usr/src/tools/ctf/dwarf/common/dwarf_line.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_line.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
-
-  Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +19,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -32,17 +32,62 @@
   http://oss.sgi.com/projects/GenInfo/NoticeExplan
 
 */
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
 
 
 
 #include "config.h"
 #include "dwarf_incl.h"
 #include <stdio.h>
+#include <stdlib.h>
 #include "dwarf_line.h"
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
+
+static int
+is_path_separator(Dwarf_Small s)
+{
+    if(s == '/') {
+        return 1;
+    }
+#ifdef HAVE_WINDOWS_PATH
+    if(s == '\\') {
+        return 1;
+    }
 #endif
+    return 0;
+}
 
+/* Return 0 if false, 1 if true. 
+   If HAVE_WINDOWS_PATH is defined we
+   attempt to handle windows full paths:
+   \\something   or  C:cwdpath.c
+*/ 
+static int
+file_name_is_full_path(Dwarf_Small  *fname)
+{
+    Dwarf_Small firstc = *fname;
+    if(is_path_separator(firstc)) {
+        /* Full path. */
+        return 1;
+    }
+    if(!firstc) {
+        return 0;
+    }
+#ifdef HAVE_WINDOWS_PATH
+    if((firstc >= 'A' && firstc <= 'Z') ||
+       (firstc >= 'a' && firstc <= 'z')) {
+         Dwarf_Small secondc = fname[1];
+         if (secondc == ':') {
+             return 1;
+         }
+    }
+#endif
+    return 0;
+}
 
 /* 
     Although source files is supposed to return the
@@ -53,27 +98,14 @@
 */
 int
 dwarf_srcfiles(Dwarf_Die die,
-	       char ***srcfiles,
-	       Dwarf_Signed * srcfilecount, Dwarf_Error * error)
+               char ***srcfiles,
+               Dwarf_Signed * srcfilecount, Dwarf_Error * error)
 {
-    /* 
-       This pointer is used to scan the portion of the .debug_line
+    /* This pointer is used to scan the portion of the .debug_line
        section for the current cu. */
     Dwarf_Small *line_ptr;
 
-    /* 
-       This points to the last byte of the .debug_line portion for the 
-       current cu. */
-    Dwarf_Small *line_ptr_end;
-
-    /* 
-       This points to the end of the statement program prologue for the 
-       current cu, and serves to check that the prologue was correctly 
-       decoded. */
-    Dwarf_Small *check_line_ptr;
-
-    /* 
-       Pointer to a DW_AT_stmt_list attribute in case it exists in the 
+    /* Pointer to a DW_AT_stmt_list attribute in case it exists in the
        die. */
     Dwarf_Attribute stmt_list_attr;
 
@@ -83,444 +115,69 @@
     /* Pointer to name of compilation directory. */
     Dwarf_Small *comp_dir = 0;
 
-    /* 
-       Offset into .debug_line specified by a DW_AT_stmt_list
+    /* Offset into .debug_line specified by a DW_AT_stmt_list
        attribute. */
     Dwarf_Unsigned line_offset = 0;
 
-    /* Some of the fields of the statement program header. */
-    Dwarf_Unsigned total_length = 0;
-    Dwarf_Half version = 0;
-    Dwarf_Unsigned prologue_length = 0;
-    Dwarf_Small special_opcode_base= 0;
-
-    /* File name excluding included directory. */
-    char *file_name = 0;
-
-    /* Name of directory that the file is in. */
-    char *dir_name = 0;
-
-    /* Name concatenating both directory and file name. */
-    char *full_name = 0;
-
-    /* 
-       This is the directory index for the file. The compilation
-       directory is 0, and the first included directory is 1. */
-    Dwarf_Sword dir_index = 0;
-
-    Dwarf_Small *include_directories = 0;
-
-    Dwarf_Sword i = 0; 
-    Dwarf_Sword file_count = 0; 
-    Dwarf_Sword directories_count = 0;
-
-    /* 
-       This is the current opcode read from the statement program. */
-
-    Dwarf_Word leb128_length;
-
-    /* This is the length of an extended opcode instr.  */
-
-    /* 
-       This points to a block of char *'s, each of which points to a
+    /* This points to a block of char *'s, each of which points to a
        file name. */
     char **ret_files = 0;
 
     /* The Dwarf_Debug this die belongs to. */
-    Dwarf_Debug dbg;
+    Dwarf_Debug dbg = 0;
 
     /* Used to chain the file names. */
-    Dwarf_Chain curr_chain, prev_chain, head_chain = NULL;
-    int resattr;
-    int lres;
-
-    int local_length_size = 0;
-    /*REFERENCED*/ /* Not used in this instance of the macro */
-    int local_extension_size = 0;
-
-    int res;
+    Dwarf_Chain curr_chain = NULL;
+    Dwarf_Chain prev_chain = NULL;
+    Dwarf_Chain head_chain = NULL;
+    Dwarf_Half attrform = 0;
+    int resattr = DW_DLV_ERROR;
+    int lres = DW_DLV_ERROR;
+    struct Line_Table_Prefix_s line_prefix;
+    int i = 0;
+    int res = DW_DLV_ERROR;
 
     /* ***** BEGIN CODE ***** */
-
     /* Reset error. */
     if (error != NULL)
-	*error = NULL;
+        *error = NULL;
 
-    CHECK_DIE(die, DW_DLV_ERROR)
-	dbg = die->di_cu_context->cc_dbg;
+    CHECK_DIE(die, DW_DLV_ERROR);
+    dbg = die->di_cu_context->cc_dbg;
 
     resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
     if (resattr != DW_DLV_OK) {
-	return resattr;
-    }
-    
-    if (dbg->de_debug_line_index == 0) {
-	_dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_NULL);
-	return (DW_DLV_ERROR);
-    }
-
-    res =
-       _dwarf_load_section(dbg,
-		           dbg->de_debug_line_index,
-			   &dbg->de_debug_line,
-			   error);
-    if (res != DW_DLV_OK) {
-	return res;
-    }
-
-    lres = dwarf_formudata(stmt_list_attr, &line_offset, error);
-    if (lres != DW_DLV_OK) {
-	return lres;
-    }
-    if (line_offset >= dbg->de_debug_line_size) {
-	_dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
-	return (DW_DLV_ERROR);
-    }
-    line_ptr = dbg->de_debug_line + line_offset;
-    dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
-
-    /* 
-       If die has DW_AT_comp_dir attribute, get the string that names
-       the compilation directory. */
-    resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
-    if (resattr == DW_DLV_ERROR) {
-	return resattr;
-    }
-    if (resattr == DW_DLV_OK) {
-	int cres;
-	char *cdir;
-
-	cres = dwarf_formstring(comp_dir_attr, &cdir, error);
-	if (cres == DW_DLV_ERROR) {
-	    return cres;
-	} else if (cres == DW_DLV_OK) {
-	    comp_dir = (Dwarf_Small *) cdir;
-	}
-    }
-    if (resattr == DW_DLV_OK) {
-	dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
-    }
-
-    /* 
-       Following is a straightforward decoding of the statement
-       program prologue information. */
-    /* READ_AREA_LENGTH updates line_ptr for consumed bytes */
-    READ_AREA_LENGTH(dbg, total_length, Dwarf_Unsigned,
-		     line_ptr, local_length_size, local_extension_size);
-
-
-    line_ptr_end = line_ptr + total_length;
-    if (line_ptr_end > dbg->de_debug_line + dbg->de_debug_line_size) {
-	_dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_LENGTH_BAD);
-	return (DW_DLV_ERROR);
-    }
-
-    READ_UNALIGNED(dbg, version, Dwarf_Half,
-		   line_ptr, sizeof(Dwarf_Half));
-    line_ptr += sizeof(Dwarf_Half);
-    if (version != CURRENT_VERSION_STAMP) {
-	_dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
-	return (DW_DLV_ERROR);
+        return resattr;
     }
 
-    READ_UNALIGNED(dbg, prologue_length, Dwarf_Unsigned,
-		   line_ptr, local_length_size);
-    line_ptr += local_length_size;
-    check_line_ptr = line_ptr;
-
-    /* Skip over minimum instruction length. */
-    line_ptr = line_ptr + sizeof(Dwarf_Small);
-
-    /* Skip over default_is_stmt. */
-    line_ptr = line_ptr + sizeof(Dwarf_Small);
-
-    /* Skip over line_base. */
-    line_ptr = line_ptr + sizeof(Dwarf_Sbyte);
-
-    /* Skip over line_ptr. */
-    line_ptr = line_ptr + sizeof(Dwarf_Small);
-
-    special_opcode_base = *(Dwarf_Small *) line_ptr;
-    line_ptr = line_ptr + sizeof(Dwarf_Small);
-
-    for (i = 1; i < special_opcode_base; i++) {
-	/* Skip over opcode lengths for standard opcodes. */
-	line_ptr = line_ptr + sizeof(Dwarf_Small);
+    if (dbg->de_debug_line.dss_index == 0) {
+        _dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_NULL);
+        return (DW_DLV_ERROR);
     }
 
-    directories_count = 0;
-    include_directories = line_ptr;
-    while ((*(char *) line_ptr) != '\0') {
-	line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
-	directories_count++;
-    }
-    line_ptr++;
-
-    file_count = 0;
-    while (*(char *) line_ptr != '\0') {
-	Dwarf_Unsigned utmp;
-
-	file_name = (char *) line_ptr;
-	line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
-
-	DECODE_LEB128_UWORD(line_ptr, utmp)
-	    dir_index = (Dwarf_Sword) utmp;
-	if (dir_index > directories_count) {
-	    _dwarf_error(dbg, error, DW_DLE_DIR_INDEX_BAD);
-	    return (DW_DLV_ERROR);
-	}
-
-	if (dir_index == 0)
-	    dir_name = (char *) comp_dir;
-	else {
-	    dir_name = (char *) include_directories;
-	    for (i = 1; i < dir_index; i++)
-		/* FIX: this is probably very slow: redoing strlen!
-		   davea 9/94 */
-		dir_name = dir_name + strlen(dir_name) + 1;
-	}
-
-	/* dir_name can be NULL if there is no DW_AT_comp_dir */
-	if ((*file_name) == '/' || dir_name == 0)
-	    full_name = file_name;
-	else {
-	    full_name = (char *) _dwarf_get_alloc(dbg, DW_DLA_STRING,
-						  strlen(dir_name) + 1 +
-						  strlen(file_name) +
-						  1);
-	    if (full_name == NULL) {
-		_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-		return (DW_DLV_ERROR);
-	    }
-
-	    strcpy(full_name, dir_name);
-	    strcat(full_name, "/");
-	    strcat(full_name, file_name);
-	}
-
-	/* Skip over time of last modification. */
-	_dwarf_decode_u_leb128(line_ptr, &leb128_length);
-	line_ptr = line_ptr + leb128_length;
-
-	/* Skip over file length. */
-	_dwarf_decode_u_leb128(line_ptr, &leb128_length);
-	line_ptr = line_ptr + leb128_length;
-
-	curr_chain =
-	    (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
-	if (curr_chain == NULL) {
-	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	    return (DW_DLV_ERROR);
-	}
-
-	curr_chain->ch_item = full_name;
-
-	if (head_chain == NULL)
-	    head_chain = prev_chain = curr_chain;
-	else {
-	    prev_chain->ch_next = curr_chain;
-	    prev_chain = curr_chain;
-	}
-
-	file_count++;
-    }
-    line_ptr++;
-
-    if (line_ptr != check_line_ptr + prologue_length) {
-	_dwarf_error(dbg, error, DW_DLE_LINE_PROLOG_LENGTH_BAD);
-	return (DW_DLV_ERROR);
+    res = _dwarf_load_section(dbg, &dbg->de_debug_line,error);
+    if (res != DW_DLV_OK) {
+        return res;
     }
 
-    if (file_count == 0) {
-	*srcfiles = NULL;
-	*srcfilecount = 0;
-	return (DW_DLV_NO_ENTRY);
+    lres = dwarf_whatform(stmt_list_attr,&attrform,error);
+    if (lres != DW_DLV_OK) {
+        return lres;
     }
-
-    ret_files = (char **)
-	_dwarf_get_alloc(dbg, DW_DLA_LIST, file_count);
-    if (ret_files == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
-    }
-
-    curr_chain = head_chain;
-    for (i = 0; i < file_count; i++) {
-	*(ret_files + i) = curr_chain->ch_item;
-	prev_chain = curr_chain;
-	curr_chain = curr_chain->ch_next;
-	dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
+    if (attrform != DW_FORM_data4 && attrform != DW_FORM_data8 &&
+        attrform != DW_FORM_sec_offset ) {
+        _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
+        return (DW_DLV_ERROR);
     }
-
-    *srcfiles = ret_files;
-    *srcfilecount = file_count;
-    return (DW_DLV_OK);
-}
-
-
-/*
-	return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR
-*/
-int
-_dwarf_internal_srclines(Dwarf_Die die,
-			 Dwarf_Line ** linebuf,
-			 Dwarf_Signed * count,
-			 Dwarf_Bool doaddrs,
-			 Dwarf_Bool dolines, Dwarf_Error * error)
-{
-    /* 
-       This pointer is used to scan the portion of the .debug_line
-       section for the current cu. */
-    Dwarf_Small *line_ptr;
-
-    /* 
-       This points to the last byte of the .debug_line portion for the 
-       current cu. */
-    Dwarf_Small *line_ptr_end;
-
-    /* 
-       This points to the end of the statement program prologue for the 
-       current cu, and serves to check that the prologue was correctly 
-       decoded. */
-    Dwarf_Small *check_line_ptr;
-
-    /* 
-       Pointer to a DW_AT_stmt_list attribute in case it exists in the 
-       die. */
-    Dwarf_Attribute stmt_list_attr;
-
-    /* Pointer to DW_AT_comp_dir attribute in die. */
-    Dwarf_Attribute comp_dir_attr;
-
-    /* Pointer to name of compilation directory. */
-    Dwarf_Small *comp_dir = NULL;
-
-    /* 
-       Offset into .debug_line specified by a DW_AT_stmt_list
-       attribute. */
-    Dwarf_Unsigned line_offset;
-
-    /* These are the fields of the statement program header. */
-    Dwarf_Unsigned total_length;
-    Dwarf_Half version;
-    Dwarf_Unsigned prologue_length;
-    Dwarf_Small minimum_instruction_length;
-    Dwarf_Small default_is_stmt;
-    Dwarf_Sbyte line_base;
-    Dwarf_Small line_range;
-    Dwarf_Small special_opcode_base;
-
-    Dwarf_Small *opcode_length;
-    Dwarf_Small *include_directories;
-    Dwarf_File_Entry file_entries;
-
-    /* These are the state machine state variables. */
-    Dwarf_Addr address;
-    Dwarf_Word file;
-    Dwarf_Word line;
-    Dwarf_Word column;
-    Dwarf_Bool is_stmt;
-    Dwarf_Bool basic_block;
-    Dwarf_Bool end_sequence;
-
-    /* 
-       These pointers are used to build the list of files names by
-       this cu.  cur_file_entry points to the file name being added,
-       and prev_file_entry to the previous one. */
-    Dwarf_File_Entry cur_file_entry, prev_file_entry;
-
-    Dwarf_Sword i, file_entry_count, include_directories_count;
-
-    /* 
-       This is the current opcode read from the statement program. */
-    Dwarf_Small opcode;
-
-    /* 
-       Pointer to a Dwarf_Line_Context_s structure that contains the
-       context such as file names and include directories for the set
-       of lines being generated. */
-    Dwarf_Line_Context line_context;
-
-    /* 
-       This is a pointer to the current line being added to the line
-       matrix. */
-    Dwarf_Line curr_line;
-
-    /* 
-       These variables are used to decode leb128 numbers. Leb128_num
-       holds the decoded number, and leb128_length is its length in
-       bytes. */
-    Dwarf_Word leb128_num;
-    Dwarf_Word leb128_length;
-    Dwarf_Sword advance_line;
-
-    /* 
-       This is the operand of the latest fixed_advance_pc extended
-       opcode. */
-    Dwarf_Half fixed_advance_pc;
-
-    /* 
-       Counts the number of lines in the line matrix. */
-    Dwarf_Sword line_count = 0;
-
-    /* This is the length of an extended opcode instr.  */
-    Dwarf_Word instr_length;
-    Dwarf_Small ext_opcode;
-
-    /* 
-       Used to chain together pointers to line table entries that are
-       later used to create a block of Dwarf_Line entries. */
-    Dwarf_Chain chain_line, head_chain = NULL, curr_chain;
-
-    /* 
-       This points to a block of Dwarf_Lines, a pointer to which is
-       returned in linebuf. */
-    Dwarf_Line *block_line;
-
-    /* The Dwarf_Debug this die belongs to. */
-    Dwarf_Debug dbg;
-    int resattr;
-    int lres;
-    int local_length_size = 0;
-    /*REFERENCED*/ /* Not used in this instance of the macro */
-    int local_extension_size = 0;
-
-    int res;
-
-    /* ***** BEGIN CODE ***** */
-
-    if (error != NULL)
-	*error = NULL;
-
-    CHECK_DIE(die, DW_DLV_ERROR)
-	dbg = die->di_cu_context->cc_dbg;
-
-    res =
-       _dwarf_load_section(dbg,
-		           dbg->de_debug_line_index,
-			   &dbg->de_debug_line,
-			   error);
-    if (res != DW_DLV_OK) {
-	return res;
+    lres = dwarf_global_formref(stmt_list_attr, &line_offset, error);
+    if (lres != DW_DLV_OK) {
+        return lres;
     }
-
-    resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
-    if (resattr != DW_DLV_OK) {
-	return resattr;
+    if (line_offset >= dbg->de_debug_line.dss_size) {
+        _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
+        return (DW_DLV_ERROR);
     }
-
-
-
-    lres = dwarf_formudata(stmt_list_attr, &line_offset, error);
-    if (lres != DW_DLV_OK) {
-	return lres;
-    }
-
-    if (line_offset >= dbg->de_debug_line_size) {
-	_dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
-	return (DW_DLV_ERROR);
-    }
-    line_ptr = dbg->de_debug_line + line_offset;
+    line_ptr = dbg->de_debug_line.dss_data + line_offset;
     dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
 
     /* 
@@ -528,576 +185,849 @@
        the compilation directory. */
     resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
     if (resattr == DW_DLV_ERROR) {
-	return resattr;
+        return resattr;
     }
     if (resattr == DW_DLV_OK) {
-	int cres;
-	char *cdir;
+        int cres = DW_DLV_ERROR;
+        char *cdir = 0;
 
-	cres = dwarf_formstring(comp_dir_attr, &cdir, error);
-	if (cres == DW_DLV_ERROR) {
-	    return cres;
-	} else if (cres == DW_DLV_OK) {
-	    comp_dir = (Dwarf_Small *) cdir;
-	}
+        cres = dwarf_formstring(comp_dir_attr, &cdir, error);
+        if (cres == DW_DLV_ERROR) {
+            return cres;
+        } else if (cres == DW_DLV_OK) {
+            comp_dir = (Dwarf_Small *) cdir;
+        }
     }
     if (resattr == DW_DLV_OK) {
-	dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
+        dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
     }
-
-    /* 
-       Following is a straightforward decoding of the statement
-       program prologue information. */
-    /* READ_AREA_LENGTH updates line_ptr for consumed bytes */
-    READ_AREA_LENGTH(dbg, total_length, Dwarf_Unsigned,
-		     line_ptr, local_length_size, local_extension_size);
-
-    line_ptr_end = line_ptr + total_length;
-    if (line_ptr_end > dbg->de_debug_line + dbg->de_debug_line_size) {
-	_dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_LENGTH_BAD);
-	return (DW_DLV_ERROR);
-    }
-
-    READ_UNALIGNED(dbg, version, Dwarf_Half,
-		   line_ptr, sizeof(Dwarf_Half));
-    line_ptr += sizeof(Dwarf_Half);
-    if (version != CURRENT_VERSION_STAMP) {
-	_dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
-	return (DW_DLV_ERROR);
-    }
+    dwarf_init_line_table_prefix(&line_prefix);
+    {
+        Dwarf_Small *line_ptr_out = 0;
+        int dres = dwarf_read_line_table_prefix(dbg,
+            line_ptr,
+            dbg->de_debug_line.dss_size,
+            &line_ptr_out,
+            &line_prefix, 
+            NULL, NULL,error,
+            0);
 
-    READ_UNALIGNED(dbg, prologue_length, Dwarf_Unsigned,
-		   line_ptr, local_length_size);
-    line_ptr += local_length_size;
-    check_line_ptr = line_ptr;
-
-    minimum_instruction_length = *(Dwarf_Small *) line_ptr;
-    line_ptr = line_ptr + sizeof(Dwarf_Small);
-
-    default_is_stmt = *(Dwarf_Small *) line_ptr;
-    line_ptr = line_ptr + sizeof(Dwarf_Small);
+        if (dres == DW_DLV_ERROR) {
+            dwarf_free_line_table_prefix(&line_prefix);
+            return dres;
+        }
+        if (dres == DW_DLV_NO_ENTRY) {
+            dwarf_free_line_table_prefix(&line_prefix);
+            return dres;
+        }
 
-    line_base = *(Dwarf_Sbyte *) line_ptr;
-    line_ptr = line_ptr + sizeof(Dwarf_Sbyte);
-
-    line_range = *(Dwarf_Small *) line_ptr;
-    line_ptr = line_ptr + sizeof(Dwarf_Small);
-
-    special_opcode_base = *(Dwarf_Small *) line_ptr;
-    line_ptr = line_ptr + sizeof(Dwarf_Small);
-
-    opcode_length = (Dwarf_Small *)
-	alloca(sizeof(Dwarf_Small) * special_opcode_base);
-    for (i = 1; i < special_opcode_base; i++) {
-	opcode_length[i] = *(Dwarf_Small *) line_ptr;
-	line_ptr = line_ptr + sizeof(Dwarf_Small);
+        line_ptr = line_ptr_out;
     }
 
-    include_directories_count = 0;
-    include_directories = line_ptr;
-    while ((*(char *) line_ptr) != '\0') {
-	line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
-	include_directories_count++;
-    }
-    line_ptr++;
+    for (i = 0; i < line_prefix.pf_files_count; ++i) {
+        struct Line_Table_File_Entry_s *fe =
+            line_prefix.pf_line_table_file_entries + i;
+        char *file_name = (char *) fe->lte_filename;
+        char *dir_name = 0;
+        char *full_name = 0;
+        Dwarf_Unsigned dir_index = fe->lte_directory_index;
 
-    file_entry_count = 0;
-    file_entries = prev_file_entry = NULL;
-    while (*(char *) line_ptr != '\0') {
-
-	cur_file_entry = (Dwarf_File_Entry)
-	    _dwarf_get_alloc(dbg, DW_DLA_FILE_ENTRY, 1);
-	if (cur_file_entry == NULL) {
-	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	    return (DW_DLV_ERROR);
-	}
-
-	cur_file_entry->fi_file_name = (Dwarf_Small *) line_ptr;
-	line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
+        if (dir_index == 0) {
+            dir_name = (char *) comp_dir;
+        } else {
+            dir_name =
+                (char *) line_prefix.pf_include_directories[
+                    fe->lte_directory_index - 1];
+        }
 
-	cur_file_entry->fi_dir_index =
-	    (Dwarf_Sword) _dwarf_decode_u_leb128(line_ptr,
-						 &leb128_length);
-	line_ptr = line_ptr + leb128_length;
-
-	cur_file_entry->fi_time_last_mod =
-	    _dwarf_decode_u_leb128(line_ptr, &leb128_length);
-	line_ptr = line_ptr + leb128_length;
-
-	cur_file_entry->fi_file_length =
-	    _dwarf_decode_u_leb128(line_ptr, &leb128_length);
-	line_ptr = line_ptr + leb128_length;
+        /* dir_name can be NULL if there is no DW_AT_comp_dir */
+        if(dir_name == 0 || file_name_is_full_path((unsigned char *)file_name)) { 
+            /* This is safe because dwarf_dealloc is careful to not
+               dealloc strings which are part of the raw .debug_* data. 
+             */
+            full_name = file_name;
+        } else {
+            full_name = (char *) _dwarf_get_alloc(dbg, DW_DLA_STRING,
+                                                  strlen(dir_name) + 1 +
+                                                  strlen(file_name) +
+                                                  1);
+            if (full_name == NULL) {
+                dwarf_free_line_table_prefix(&line_prefix);
+                _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+                return (DW_DLV_ERROR);
+            }
 
-	if (file_entries == NULL)
-	    file_entries = cur_file_entry;
-	else
-	    prev_file_entry->fi_next = cur_file_entry;
-	prev_file_entry = cur_file_entry;
-
-	file_entry_count++;
-    }
-    line_ptr++;
-
-    if (line_ptr != check_line_ptr + prologue_length) {
-	_dwarf_error(dbg, error, DW_DLE_LINE_PROLOG_LENGTH_BAD);
-	return (DW_DLV_ERROR);
+            /* This is not careful to avoid // in the output, Nothing
+               forces a 'canonical' name format here. Unclear if this
+               needs to be fixed. */
+            strcpy(full_name, dir_name);
+            strcat(full_name, "/");
+            strcat(full_name, file_name);
+        }
+        curr_chain =
+            (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+        if (curr_chain == NULL) {
+            dwarf_free_line_table_prefix(&line_prefix);
+            _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+            return (DW_DLV_ERROR);
+        }
+        curr_chain->ch_item = full_name;
+        if (head_chain == NULL)
+            head_chain = prev_chain = curr_chain;
+        else {
+            prev_chain->ch_next = curr_chain;
+            prev_chain = curr_chain;
+        }
     }
 
-    /* Set up context structure for this set of lines. */
-    line_context = (Dwarf_Line_Context)
-	_dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1);
-    if (line_context == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
+    curr_chain = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+    if (curr_chain == NULL) {
+        dwarf_free_line_table_prefix(&line_prefix);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
     }
 
-    /* Initialize the state machine.  */
-    address = 0;
-    file = 1;
-    line = 1;
-    column = 0;
-    is_stmt = default_is_stmt;
-    basic_block = false;
-    end_sequence = false;
-
-    /* Start of statement program.  */
-    while (line_ptr < line_ptr_end) {
-	int type;
-
-	opcode = *(Dwarf_Small *) line_ptr;
-	line_ptr++;
-
-
-	/* 'type' is the output */
-	WHAT_IS_OPCODE(type, opcode, special_opcode_base,
-		       opcode_length, line_ptr);
 
 
 
-	if (type == LOP_DISCARD) {
-	    /* do nothing, necessary ops done */
-	} else if (type == LOP_SPECIAL) {
-	    /* This op code is a special op in the object, no matter
-	       that it might fall into the standard op range in this
-	       compile Thatis, these are special opcodes between
-	       special_opcode_base and MAX_LINE_OP_CODE.  (including
-	       special_opcode_base and MAX_LINE_OP_CODE) */
+    if (line_prefix.pf_files_count == 0) {
+        *srcfiles = NULL;
+        *srcfilecount = 0;
+        dwarf_free_line_table_prefix(&line_prefix);
+        return (DW_DLV_NO_ENTRY);
+    }
+
+    ret_files = (char **)
+        _dwarf_get_alloc(dbg, DW_DLA_LIST, line_prefix.pf_files_count);
+    if (ret_files == NULL) {
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        dwarf_free_line_table_prefix(&line_prefix);
+        return (DW_DLV_ERROR);
+    }
 
-	    opcode = opcode - special_opcode_base;
-	    address = address + minimum_instruction_length *
-		(opcode / line_range);
-	    line = line + line_base + opcode % line_range;
+    curr_chain = head_chain;
+    for (i = 0; i < line_prefix.pf_files_count; i++) {
+        *(ret_files + i) = curr_chain->ch_item;
+        prev_chain = curr_chain;
+        curr_chain = curr_chain->ch_next;
+        dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
+    }
 
-	    if (dolines) {
-		curr_line =
-		    (Dwarf_Line) _dwarf_get_alloc(dbg, DW_DLA_LINE, 1);
-		if (curr_line == NULL) {
-		    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-		    return (DW_DLV_ERROR);
-		}
+    *srcfiles = ret_files;
+    *srcfilecount = line_prefix.pf_files_count;
+    dwarf_free_line_table_prefix(&line_prefix);
+    return (DW_DLV_OK);
+}
+
 
-		curr_line->li_address = address;
-		curr_line->li_addr_line.li_l_data.li_file =
-		    (Dwarf_Sword) file;
-		curr_line->li_addr_line.li_l_data.li_line =
-		    (Dwarf_Sword) line;
-		curr_line->li_addr_line.li_l_data.li_column =
-		    (Dwarf_Half) column;
-		curr_line->li_addr_line.li_l_data.li_is_stmt = is_stmt;
-		curr_line->li_addr_line.li_l_data.li_basic_block =
-		    basic_block;
-		curr_line->li_addr_line.li_l_data.li_end_sequence =
-		    end_sequence;
-		curr_line->li_context = line_context;
-		line_count++;
+/*
+        return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR
+*/
+int
+_dwarf_internal_srclines(Dwarf_Die die,
+    Dwarf_Line ** linebuf,
+    Dwarf_Signed * count,
+    Dwarf_Bool doaddrs,
+    Dwarf_Bool dolines, Dwarf_Error * error)
+{
+    /* This pointer is used to scan the portion of the .debug_line
+       section for the current cu. */
+    Dwarf_Small *line_ptr = 0;
+
+    /* This points to the last byte of the .debug_line portion for the
+       current cu. */
+    Dwarf_Small *line_ptr_end = 0;
+
+    /* Pointer to a DW_AT_stmt_list attribute in case it exists in the
+       die. */
+    Dwarf_Attribute stmt_list_attr = 0;
 
-		chain_line = (Dwarf_Chain)
-		    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
-		if (chain_line == NULL) {
-		    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-		    return (DW_DLV_ERROR);
-		}
-		chain_line->ch_item = curr_line;
+    /* Pointer to DW_AT_comp_dir attribute in die. */
+    Dwarf_Attribute comp_dir_attr = 0;
+
+    /* Pointer to name of compilation directory. */
+    Dwarf_Small *comp_dir = NULL;
+
+    /* Offset into .debug_line specified by a DW_AT_stmt_list
+       attribute. */
+    Dwarf_Unsigned line_offset = 0;
+
+    Dwarf_File_Entry file_entries = 0;
+
+    /* These are the state machine state variables. */
+    Dwarf_Addr address = 0;
+    Dwarf_Word file = 1;
+    Dwarf_Word line = 1;
+    Dwarf_Word column = 0;
+
+    /* Phony init. See below for true initialization. */
+    Dwarf_Bool is_stmt = false;
+
+    Dwarf_Bool basic_block = false;
+    Dwarf_Bool prologue_end = false;
+    Dwarf_Bool epilogue_begin = false;
+    Dwarf_Small isa = 0;
+    Dwarf_Bool end_sequence = false;
 
-		if (head_chain == NULL)
-		    head_chain = curr_chain = chain_line;
-		else {
-		    curr_chain->ch_next = chain_line;
-		    curr_chain = chain_line;
-		}
-	    }
+    /* These pointers are used to build the list of files names by this 
+       cu.  cur_file_entry points to the file name being added, and
+       prev_file_entry to the previous one. */
+    Dwarf_File_Entry cur_file_entry, prev_file_entry;
+
+    Dwarf_Sword i = 0;
+    Dwarf_Sword file_entry_count = 0;
+
+    /* This is the current opcode read from the statement program. */
+    Dwarf_Small opcode = 0;
+
+    /* Pointer to a Dwarf_Line_Context_s structure that contains the
+       context such as file names and include directories for the set
+       of lines being generated. */
+    Dwarf_Line_Context line_context = 0;
 
-	    basic_block = false;
-	} else if (type == LOP_STANDARD) {
-	    switch (opcode) {
+    /* This is a pointer to the current line being added to the line
+       matrix. */
+    Dwarf_Line curr_line = 0;
+
+    /* These variables are used to decode leb128 numbers. Leb128_num
+       holds the decoded number, and leb128_length is its length in
+       bytes. */
+    Dwarf_Word leb128_num = 0;
+    Dwarf_Word leb128_length = 0;
+    Dwarf_Sword advance_line = 0;
 
-	    case DW_LNS_copy:{
-		    if (opcode_length[DW_LNS_copy] != 0) {
-			_dwarf_error(dbg, error,
-				     DW_DLE_LINE_NUM_OPERANDS_BAD);
-			return (DW_DLV_ERROR);
-		    }
+    /* This is the operand of the latest fixed_advance_pc extended
+       opcode. */
+    Dwarf_Half fixed_advance_pc = 0;
 
-		    if (dolines) {
+    /* Counts the number of lines in the line matrix. */
+    Dwarf_Sword line_count = 0;
+
+    /* This is the length of an extended opcode instr.  */
+    Dwarf_Word instr_length = 0;
+    Dwarf_Small ext_opcode = 0;
+    struct Line_Table_Prefix_s prefix;
 
-			curr_line =
-			    (Dwarf_Line) _dwarf_get_alloc(dbg,
-							  DW_DLA_LINE,
-							  1);
-			if (curr_line == NULL) {
-			    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-			    return (DW_DLV_ERROR);
-			}
+    /* Used to chain together pointers to line table entries that are
+       later used to create a block of Dwarf_Line entries. */
+    Dwarf_Chain chain_line = NULL;
+    Dwarf_Chain head_chain = NULL;
+    Dwarf_Chain curr_chain = NULL;
+
+    /* This points to a block of Dwarf_Lines, a pointer to which is
+       returned in linebuf. */
+    Dwarf_Line *block_line = 0;
+
+    /* The Dwarf_Debug this die belongs to. */
+    Dwarf_Debug dbg = 0;
+    int resattr = DW_DLV_ERROR;
+    int lres = DW_DLV_ERROR;
+    Dwarf_Half address_size = 0;
+
+    int res = DW_DLV_ERROR;
+
+    /* ***** BEGIN CODE ***** */
+    if (error != NULL)
+        *error = NULL;
 
-			curr_line->li_address = address;
-			curr_line->li_addr_line.li_l_data.li_file =
-			    (Dwarf_Sword) file;
-			curr_line->li_addr_line.li_l_data.li_line =
-			    (Dwarf_Sword) line;
-			curr_line->li_addr_line.li_l_data.li_column =
-			    (Dwarf_Half) column;
-			curr_line->li_addr_line.li_l_data.li_is_stmt =
-			    is_stmt;
-			curr_line->li_addr_line.li_l_data.
-			    li_basic_block = basic_block;
-			curr_line->li_addr_line.li_l_data.
-			    li_end_sequence = end_sequence;
-			curr_line->li_context = line_context;
-			line_count++;
+    CHECK_DIE(die, DW_DLV_ERROR);
+    dbg = die->di_cu_context->cc_dbg;
+
+    res = _dwarf_load_section(dbg, &dbg->de_debug_line,error);
+    if (res != DW_DLV_OK) {
+        return res;
+    }
+    address_size = _dwarf_get_address_size(dbg, die);
+    resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
+    if (resattr != DW_DLV_OK) {
+        return resattr;
+    }
+
+    lres = dwarf_formudata(stmt_list_attr, &line_offset, error);
+    if (lres != DW_DLV_OK) {
+        return lres;
+    }
+
+    if (line_offset >= dbg->de_debug_line.dss_size) {
+        _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
+        return (DW_DLV_ERROR);
+    }
+    line_ptr = dbg->de_debug_line.dss_data + line_offset;
+    dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
 
-			chain_line = (Dwarf_Chain)
-			    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
-			if (chain_line == NULL) {
-			    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-			    return (DW_DLV_ERROR);
-			}
-			chain_line->ch_item = curr_line;
-			if (head_chain == NULL)
-			    head_chain = curr_chain = chain_line;
-			else {
-			    curr_chain->ch_next = chain_line;
-			    curr_chain = chain_line;
-			}
-		    }
+    /* If die has DW_AT_comp_dir attribute, get the string that names
+       the compilation directory. */
+    resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
+    if (resattr == DW_DLV_ERROR) {
+        return resattr;
+    }
+    if (resattr == DW_DLV_OK) {
+        int cres = DW_DLV_ERROR;
+        char *cdir = 0;
 
-		    basic_block = false;
-		    break;
-		}
+        cres = dwarf_formstring(comp_dir_attr, &cdir, error);
+        if (cres == DW_DLV_ERROR) {
+            return cres;
+        } else if (cres == DW_DLV_OK) {
+            comp_dir = (Dwarf_Small *) cdir;
+        }
+    }
+    if (resattr == DW_DLV_OK) {
+        dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
+    }
+    dwarf_init_line_table_prefix(&prefix);
 
-	    case DW_LNS_advance_pc:{
-		    Dwarf_Unsigned utmp2;
+    {
+        Dwarf_Small *newlinep = 0;
+        int res = dwarf_read_line_table_prefix(dbg,
+            line_ptr,
+            dbg->de_debug_line.dss_size,
+            &newlinep,
+            &prefix,
+            NULL,NULL,
+            error,
+            0);
 
-		    if (opcode_length[DW_LNS_advance_pc] != 1) {
-			_dwarf_error(dbg, error,
-				     DW_DLE_LINE_NUM_OPERANDS_BAD);
-			return (DW_DLV_ERROR);
-		    }
+        if (res == DW_DLV_ERROR) {
+            dwarf_free_line_table_prefix(&prefix);
+            return res;
+        }
+        if (res == DW_DLV_NO_ENTRY) {
+            dwarf_free_line_table_prefix(&prefix);
+            return res;
+        }
+        line_ptr_end = prefix.pf_line_ptr_end;
+        line_ptr = newlinep;
+    }
+
+
+    /* Set up context structure for this set of lines. */
+    line_context = (Dwarf_Line_Context)
+        _dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1);
+    if (line_context == NULL) {
+        dwarf_free_line_table_prefix(&prefix);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
+    }
 
-		    DECODE_LEB128_UWORD(line_ptr, utmp2)
-			leb128_num = (Dwarf_Word) utmp2;
-		    address =
-			address +
-			minimum_instruction_length * leb128_num;
-		    break;
-		}
+    /* Fill out a Dwarf_File_Entry list as we use that to implement the 
+       define_file operation. */
+    file_entries = prev_file_entry = NULL;
+    for (i = 0; i < prefix.pf_files_count; ++i) {
+        struct Line_Table_File_Entry_s *pfxfile =
+            prefix.pf_line_table_file_entries + i;
 
-	    case DW_LNS_advance_line:{
-		    Dwarf_Signed stmp;
+        cur_file_entry = (Dwarf_File_Entry)
+            _dwarf_get_alloc(dbg, DW_DLA_FILE_ENTRY, 1);
+        if (cur_file_entry == NULL) {
+            dwarf_free_line_table_prefix(&prefix);
+            _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+            return (DW_DLV_ERROR);
+        }
 
-		    if (opcode_length[DW_LNS_advance_line] != 1) {
-			_dwarf_error(dbg, error,
-				     DW_DLE_LINE_NUM_OPERANDS_BAD);
-			return (DW_DLV_ERROR);
-		    }
+        cur_file_entry->fi_file_name = pfxfile->lte_filename;
+        cur_file_entry->fi_dir_index = pfxfile->lte_directory_index;
+        cur_file_entry->fi_time_last_mod =
+            pfxfile->lte_last_modification_time;
+
+        cur_file_entry->fi_file_length = pfxfile->lte_length_of_file;
+
+        if (file_entries == NULL)
+            file_entries = cur_file_entry;
+        else
+            prev_file_entry->fi_next = cur_file_entry;
+        prev_file_entry = cur_file_entry;
 
-		    DECODE_LEB128_SWORD(line_ptr, stmp)
-			advance_line = (Dwarf_Sword) stmp;
-		    line = line + advance_line;
-		    break;
-		}
+        file_entry_count++;
+    }
+
+
+    /* Initialize the one state machine variable that depends on the
+       prefix.  */
+    is_stmt = prefix.pf_default_is_stmt;
+
 
-	    case DW_LNS_set_file:{
-		    Dwarf_Unsigned utmp2;
+    /* Start of statement program.  */
+    while (line_ptr < line_ptr_end) {
+        int type;
+
+        opcode = *(Dwarf_Small *) line_ptr;
+        line_ptr++;
+
+
+        /* 'type' is the output */
+        WHAT_IS_OPCODE(type, opcode, prefix.pf_opcode_base,
+                       prefix.pf_opcode_length_table, line_ptr,
+                       prefix.pf_std_op_count);
 
-		    if (opcode_length[DW_LNS_set_file] != 1) {
-			_dwarf_error(dbg, error,
-				     DW_DLE_LINE_NUM_OPERANDS_BAD);
-			return (DW_DLV_ERROR);
-		    }
+        if (type == LOP_DISCARD) {
+            int oc;
+            int opcnt = prefix.pf_opcode_length_table[opcode];
 
-		    DECODE_LEB128_UWORD(line_ptr, utmp2)
-			file = (Dwarf_Word) utmp2;
-		    break;
-		}
+            for (oc = 0; oc < opcnt; oc++) {
+                /* 
+                 ** Read and discard operands we don't 
+                 ** understand.                        
+                 ** arbitrary choice of unsigned read. 
+                 ** signed read would work as well.    
+                 */
+                Dwarf_Unsigned utmp2;
 
-	    case DW_LNS_set_column:{
-		    Dwarf_Unsigned utmp2;
+                DECODE_LEB128_UWORD(line_ptr, utmp2);
+            }
+        } else if (type == LOP_SPECIAL) {
+            /* This op code is a special op in the object, no matter
+               that it might fall into the standard op range in this
+               compile. That is, these are special opcodes between
+               opcode_base and MAX_LINE_OP_CODE.  (including
+               opcode_base and MAX_LINE_OP_CODE) */
 
-		    if (opcode_length[DW_LNS_set_column] != 1) {
-			_dwarf_error(dbg, error,
-				     DW_DLE_LINE_NUM_OPERANDS_BAD);
-			return (DW_DLV_ERROR);
-		    }
+            opcode = opcode - prefix.pf_opcode_base;
+            address = address + prefix.pf_minimum_instruction_length *
+                (opcode / prefix.pf_line_range);
+            line =
+                line + prefix.pf_line_base +
+                opcode % prefix.pf_line_range;
 
-		    DECODE_LEB128_UWORD(line_ptr, utmp2)
-			column = (Dwarf_Word) utmp2;
-		    break;
-		}
+            if (dolines) {
+                curr_line =
+                    (Dwarf_Line) _dwarf_get_alloc(dbg, DW_DLA_LINE, 1);
+                if (curr_line == NULL) {
+                    dwarf_free_line_table_prefix(&prefix);
+                    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+                    return (DW_DLV_ERROR);
+                }
 
-	    case DW_LNS_negate_stmt:{
-		    if (opcode_length[DW_LNS_negate_stmt] != 0) {
-			_dwarf_error(dbg, error,
-				     DW_DLE_LINE_NUM_OPERANDS_BAD);
-			return (DW_DLV_ERROR);
-		    }
+                curr_line->li_address = address;
+                curr_line->li_addr_line.li_l_data.li_file =
+                    (Dwarf_Sword) file;
+                curr_line->li_addr_line.li_l_data.li_line =
+                    (Dwarf_Sword) line;
+                curr_line->li_addr_line.li_l_data.li_column =
+                    (Dwarf_Half) column;
+                curr_line->li_addr_line.li_l_data.li_is_stmt = is_stmt;
+                curr_line->li_addr_line.li_l_data.li_basic_block =
+                    basic_block;
+                curr_line->li_addr_line.li_l_data.li_end_sequence =
+                    curr_line->li_addr_line.li_l_data.
+                    li_epilogue_begin = epilogue_begin;
+                curr_line->li_addr_line.li_l_data.li_prologue_end =
+                    prologue_end;
+                curr_line->li_addr_line.li_l_data.li_isa = isa;
+                curr_line->li_context = line_context;
+                line_count++;
 
-		    is_stmt = !is_stmt;
-		    break;
-		}
-
-	    case DW_LNS_set_basic_block:{
-		    if (opcode_length[DW_LNS_set_basic_block] != 0) {
-			_dwarf_error(dbg, error,
-				     DW_DLE_LINE_NUM_OPERANDS_BAD);
-			return (DW_DLV_ERROR);
-		    }
+                chain_line = (Dwarf_Chain)
+                    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+                if (chain_line == NULL) {
+                    dwarf_free_line_table_prefix(&prefix);
+                    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+                    return (DW_DLV_ERROR);
+                }
+                chain_line->ch_item = curr_line;
 
-		    basic_block = true;
-		    break;
-		}
+                if (head_chain == NULL)
+                    head_chain = curr_chain = chain_line;
+                else {
+                    curr_chain->ch_next = chain_line;
+                    curr_chain = chain_line;
+                }
+            }
 
-	    case DW_LNS_const_add_pc:{
-		    opcode = MAX_LINE_OP_CODE - special_opcode_base;
-		    address = address + minimum_instruction_length *
-			(opcode / line_range);
+            basic_block = false;
+        } else if (type == LOP_STANDARD) {
+            switch (opcode) {
 
-		    break;
-		}
+            case DW_LNS_copy:{
+                    if (dolines) {
 
-	    case DW_LNS_fixed_advance_pc:{
-		    if (opcode_length[DW_LNS_fixed_advance_pc] != 1) {
-			_dwarf_error(dbg, error,
-				     DW_DLE_LINE_NUM_OPERANDS_BAD);
-			return (DW_DLV_ERROR);
-		    }
+                        curr_line =
+                            (Dwarf_Line) _dwarf_get_alloc(dbg,
+                                                          DW_DLA_LINE,
+                                                          1);
+                        if (curr_line == NULL) {
+                            dwarf_free_line_table_prefix(&prefix);
+                            _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+                            return (DW_DLV_ERROR);
+                        }
 
-		    READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half,
-				   line_ptr, sizeof(Dwarf_Half));
-		    line_ptr += sizeof(Dwarf_Half);
-		    address = address + fixed_advance_pc;
-		    break;
-		}
-	    }
-
-	} else if (type == LOP_EXTENDED) {
-	    Dwarf_Unsigned utmp3;
+                        curr_line->li_address = address;
+                        curr_line->li_addr_line.li_l_data.li_file =
+                            (Dwarf_Sword) file;
+                        curr_line->li_addr_line.li_l_data.li_line =
+                            (Dwarf_Sword) line;
+                        curr_line->li_addr_line.li_l_data.li_column =
+                            (Dwarf_Half) column;
+                        curr_line->li_addr_line.li_l_data.li_is_stmt =
+                            is_stmt;
+                        curr_line->li_addr_line.li_l_data.
+                            li_basic_block = basic_block;
+                        curr_line->li_addr_line.li_l_data.
+                            li_end_sequence = end_sequence;
+                        curr_line->li_context = line_context;
+                        curr_line->li_addr_line.li_l_data.
+                            li_epilogue_begin = epilogue_begin;
+                        curr_line->li_addr_line.li_l_data.
+                            li_prologue_end = prologue_end;
+                        curr_line->li_addr_line.li_l_data.li_isa = isa;
+                        line_count++;
 
-	    DECODE_LEB128_UWORD(line_ptr, utmp3)
-		instr_length = (Dwarf_Word) utmp3;
-	    /* Dwarf_Small is a ubyte and the extended opcode
-	       is a ubyte, though not stated as clearly in
-	       the 2.0.0 spec as one might hope.
-	    */
-	    ext_opcode = *(Dwarf_Small *) line_ptr;
-	    line_ptr++;
-	    switch (ext_opcode) {
+                        chain_line = (Dwarf_Chain)
+                            _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+                        if (chain_line == NULL) {
+                            dwarf_free_line_table_prefix(&prefix);
+                            _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+                            return (DW_DLV_ERROR);
+                        }
+                        chain_line->ch_item = curr_line;
+                        if (head_chain == NULL)
+                            head_chain = curr_chain = chain_line;
+                        else {
+                            curr_chain->ch_next = chain_line;
+                            curr_chain = chain_line;
+                        }
+                    }
 
-	    case DW_LNE_end_sequence:{
-		    end_sequence = true;
+                    basic_block = false;
+                    prologue_end = false;
+                    epilogue_begin = false;
+                    break;
+                }
+
+            case DW_LNS_advance_pc:{
+                    Dwarf_Unsigned utmp2;
+
+                    DECODE_LEB128_UWORD(line_ptr, utmp2);
+                    leb128_num = (Dwarf_Word) utmp2;
+                    address =
+                        address +
+                        prefix.pf_minimum_instruction_length *
+                        leb128_num;
+                    break;
+                }
+
+            case DW_LNS_advance_line:{
+                    Dwarf_Signed stmp;
 
-		    if (dolines) {
-			curr_line = (Dwarf_Line)
-			    _dwarf_get_alloc(dbg, DW_DLA_LINE, 1);
-			if (curr_line == NULL) {
-			    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-			    return (DW_DLV_ERROR);
-			}
+                    DECODE_LEB128_SWORD(line_ptr, stmp);
+                    advance_line = (Dwarf_Sword) stmp;
+                    line = line + advance_line;
+                    break;
+                }
+
+            case DW_LNS_set_file:{
+                    Dwarf_Unsigned utmp2;
+
+                    DECODE_LEB128_UWORD(line_ptr, utmp2);
+                    file = (Dwarf_Word) utmp2;
+                    break;
+                }
+
+            case DW_LNS_set_column:{
+                    Dwarf_Unsigned utmp2;
 
-			curr_line->li_address = address;
-			curr_line->li_addr_line.li_l_data.li_file =
-			    (Dwarf_Sword) file;
-			curr_line->li_addr_line.li_l_data.li_line =
-			    (Dwarf_Sword) line;
-			curr_line->li_addr_line.li_l_data.li_column =
-			    (Dwarf_Half) column;
-			curr_line->li_addr_line.li_l_data.li_is_stmt =
-			    default_is_stmt;
-			curr_line->li_addr_line.li_l_data.
-			    li_basic_block = basic_block;
-			curr_line->li_addr_line.li_l_data.
-			    li_end_sequence = end_sequence;
-			curr_line->li_context = line_context;
-			line_count++;
+                    DECODE_LEB128_UWORD(line_ptr, utmp2);
+                    column = (Dwarf_Word) utmp2;
+                    break;
+                }
+
+            case DW_LNS_negate_stmt:{
+
+                    is_stmt = !is_stmt;
+                    break;
+                }
+
+            case DW_LNS_set_basic_block:{
+
+                    basic_block = true;
+                    break;
+                }
+
+            case DW_LNS_const_add_pc:{
+                    opcode = MAX_LINE_OP_CODE - prefix.pf_opcode_base;
+                    address = address +
+                        prefix.pf_minimum_instruction_length * (opcode /
+                            prefix.
+                            pf_line_range);
+                    break;
+                }
 
-			chain_line = (Dwarf_Chain)
-			    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
-			if (chain_line == NULL) {
-			    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-			    return (DW_DLV_ERROR);
-			}
-			chain_line->ch_item = curr_line;
+            case DW_LNS_fixed_advance_pc:{
+
+                    READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half,
+                                   line_ptr, sizeof(Dwarf_Half));
+                    line_ptr += sizeof(Dwarf_Half);
+                    address = address + fixed_advance_pc;
+                    break;
+                }
+
+                /* New in DWARF3 */
+            case DW_LNS_set_prologue_end:{
+
+                    prologue_end = true;
+                    break;
+
+
+                }
+                /* New in DWARF3 */
+            case DW_LNS_set_epilogue_begin:{
+                    epilogue_begin = true;
+                    break;
+                }
 
-			if (head_chain == NULL)
-			    head_chain = curr_chain = chain_line;
-			else {
-			    curr_chain->ch_next = chain_line;
-			    curr_chain = chain_line;
-			}
-		    }
+                /* New in DWARF3 */
+            case DW_LNS_set_isa:{
+                    Dwarf_Unsigned utmp2;
 
-		    address = 0;
-		    file = 1;
-		    line = 1;
-		    column = 0;
-		    is_stmt = default_is_stmt;
-		    basic_block = false;
-		    end_sequence = false;
+                    DECODE_LEB128_UWORD(line_ptr, utmp2);
+                    isa = utmp2;
+                    if (isa != utmp2) {
+                        /* The value of the isa did not fit in our
+                           local so we record it wrong. declare an
+                           error. */
+                        dwarf_free_line_table_prefix(&prefix);
 
-		    break;
-		}
+                        _dwarf_error(dbg, error,
+                                     DW_DLE_LINE_NUM_OPERANDS_BAD);
+                        return (DW_DLV_ERROR);
+                    }
+                    break;
+                }
+            }
+
+        } else if (type == LOP_EXTENDED) {
+            Dwarf_Unsigned utmp3;
 
-	    case DW_LNE_set_address:{
-		    if (instr_length - 1 == dbg->de_pointer_size) {
-			READ_UNALIGNED(dbg, address, Dwarf_Addr,
-				       line_ptr, dbg->de_pointer_size);
-			if (doaddrs) {
-			    curr_line =
-				(Dwarf_Line) _dwarf_get_alloc(dbg,
-							      DW_DLA_LINE,
-							      1);
-			    if (curr_line == NULL) {
-				_dwarf_error(dbg, error,
-					     DW_DLE_ALLOC_FAIL);
-				return (DW_DLV_ERROR);
-			    }
+            DECODE_LEB128_UWORD(line_ptr, utmp3);
+            instr_length = (Dwarf_Word) utmp3;
+            /* Dwarf_Small is a ubyte and the extended opcode is a
+               ubyte, though not stated as clearly in the 2.0.0 spec as 
+               one might hope. */
+            ext_opcode = *(Dwarf_Small *) line_ptr;
+            line_ptr++;
+            switch (ext_opcode) {
+
+            case DW_LNE_end_sequence:{
+                    end_sequence = true;
+
+                    if (dolines) {
+                        curr_line = (Dwarf_Line)
+                            _dwarf_get_alloc(dbg, DW_DLA_LINE, 1);
+                        if (curr_line == NULL) {
+                            dwarf_free_line_table_prefix(&prefix);
+                            _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+                            return (DW_DLV_ERROR);
+                        }
 
-			    curr_line->li_address = address;
-			    curr_line->li_addr_line.li_offset =
-				line_ptr - dbg->de_debug_line;
-
-			    line_count++;
+                        curr_line->li_address = address;
+                        curr_line->li_addr_line.li_l_data.li_file =
+                            (Dwarf_Sword) file;
+                        curr_line->li_addr_line.li_l_data.li_line =
+                            (Dwarf_Sword) line;
+                        curr_line->li_addr_line.li_l_data.li_column =
+                            (Dwarf_Half) column;
+                        curr_line->li_addr_line.li_l_data.li_is_stmt =
+                            prefix.pf_default_is_stmt;
+                        curr_line->li_addr_line.li_l_data.
+                            li_basic_block = basic_block;
+                        curr_line->li_addr_line.li_l_data.
+                            li_end_sequence = end_sequence;
+                        curr_line->li_context = line_context;
+                        curr_line->li_addr_line.li_l_data.
+                            li_epilogue_begin = epilogue_begin;
+                        curr_line->li_addr_line.li_l_data.
+                            li_prologue_end = prologue_end;
+                        curr_line->li_addr_line.li_l_data.li_isa = isa;
+                        line_count++;
 
-			    chain_line = (Dwarf_Chain)
-				_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
-			    if (chain_line == NULL) {
-				_dwarf_error(dbg, error,
-					     DW_DLE_ALLOC_FAIL);
-				return (DW_DLV_ERROR);
-			    }
-			    chain_line->ch_item = curr_line;
+                        chain_line = (Dwarf_Chain)
+                            _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+                        if (chain_line == NULL) {
+                            dwarf_free_line_table_prefix(&prefix);
+                            _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+                            return (DW_DLV_ERROR);
+                        }
+                        chain_line->ch_item = curr_line;
+
+                        if (head_chain == NULL)
+                            head_chain = curr_chain = chain_line;
+                        else {
+                            curr_chain->ch_next = chain_line;
+                            curr_chain = chain_line;
+                        }
+                    }
 
-			    if (head_chain == NULL)
-				head_chain = curr_chain = chain_line;
-			    else {
-				curr_chain->ch_next = chain_line;
-				curr_chain = chain_line;
-			    }
-			}
+                    address = 0;
+                    file = 1;
+                    line = 1;
+                    column = 0;
+                    is_stmt = prefix.pf_default_is_stmt;
+                    basic_block = false;
+                    end_sequence = false;
+                    prologue_end = false;
+                    epilogue_begin = false;
+
+
+                    break;
+                }
 
-			line_ptr += dbg->de_pointer_size;
-		    } else {
-			_dwarf_error(dbg, error,
-				     DW_DLE_LINE_SET_ADDR_ERROR);
-			return (DW_DLV_ERROR);
-		    }
-
-		    break;
-		}
+            case DW_LNE_set_address:{
+                    {
+                        READ_UNALIGNED(dbg, address, Dwarf_Addr,
+                                       line_ptr, address_size);
+                        if (doaddrs) {
+                            curr_line =
+                                (Dwarf_Line) _dwarf_get_alloc(dbg,
+                                                              DW_DLA_LINE,
+                                                              1);
+                            if (curr_line == NULL) {
+                                dwarf_free_line_table_prefix(&prefix);
+                                _dwarf_error(dbg, error,
+                                             DW_DLE_ALLOC_FAIL);
+                                return (DW_DLV_ERROR);
+                            }
 
-	    case DW_LNE_define_file:{
+                            curr_line->li_address = address;
+                            curr_line->li_addr_line.li_offset =
+                                line_ptr - dbg->de_debug_line.dss_data;
+
+                            line_count++;
 
-		    if (dolines) {
-			cur_file_entry = (Dwarf_File_Entry)
-			    _dwarf_get_alloc(dbg, DW_DLA_FILE_ENTRY, 1);
-			if (cur_file_entry == NULL) {
-			    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-			    return (DW_DLV_ERROR);
-			}
+                            chain_line = (Dwarf_Chain)
+                                _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+                            if (chain_line == NULL) {
+                                dwarf_free_line_table_prefix(&prefix);
+                                _dwarf_error(dbg, error,
+                                             DW_DLE_ALLOC_FAIL);
+                                return (DW_DLV_ERROR);
+                            }
+                            chain_line->ch_item = curr_line;
 
-			cur_file_entry->fi_file_name =
-			    (Dwarf_Small *) line_ptr;
-			line_ptr =
-			    line_ptr + strlen((char *) line_ptr) + 1;
+                            if (head_chain == NULL)
+                                head_chain = curr_chain = chain_line;
+                            else {
+                                curr_chain->ch_next = chain_line;
+                                curr_chain = chain_line;
+                            }
+                        }
+
+                        line_ptr += address_size;
+                    } 
 
-			cur_file_entry->fi_dir_index =
-			    (Dwarf_Sword)
-			    _dwarf_decode_u_leb128(line_ptr,
-						   &leb128_length);
-			line_ptr = line_ptr + leb128_length;
+                    break;
+                }
+
+            case DW_LNE_define_file:{
+
+                    if (dolines) {
+                        cur_file_entry = (Dwarf_File_Entry)
+                            _dwarf_get_alloc(dbg, DW_DLA_FILE_ENTRY, 1);
+                        if (cur_file_entry == NULL) {
+                            dwarf_free_line_table_prefix(&prefix);
+                            _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+                            return (DW_DLV_ERROR);
+                        }
 
-			cur_file_entry->fi_time_last_mod =
-			    _dwarf_decode_u_leb128(line_ptr,
-						   &leb128_length);
-			line_ptr = line_ptr + leb128_length;
+                        cur_file_entry->fi_file_name =
+                            (Dwarf_Small *) line_ptr;
+                        line_ptr =
+                            line_ptr + strlen((char *) line_ptr) + 1;
+
+                        cur_file_entry->fi_dir_index = (Dwarf_Sword)
+                            _dwarf_decode_u_leb128(line_ptr,
+                                                   &leb128_length);
+                        line_ptr = line_ptr + leb128_length;
 
-			cur_file_entry->fi_file_length =
-			    _dwarf_decode_u_leb128(line_ptr,
-						   &leb128_length);
-			line_ptr = line_ptr + leb128_length;
+                        cur_file_entry->fi_time_last_mod =
+                            _dwarf_decode_u_leb128(line_ptr,
+                                                   &leb128_length);
+                        line_ptr = line_ptr + leb128_length;
+
+                        cur_file_entry->fi_file_length =
+                            _dwarf_decode_u_leb128(line_ptr,
+                                                   &leb128_length);
+                        line_ptr = line_ptr + leb128_length;
 
-			if (file_entries == NULL)
-			    file_entries = cur_file_entry;
-			else
-			    prev_file_entry->fi_next = cur_file_entry;
-			prev_file_entry = cur_file_entry;
+                        if (file_entries == NULL)
+                            file_entries = cur_file_entry;
+                        else
+                            prev_file_entry->fi_next = cur_file_entry;
+                        prev_file_entry = cur_file_entry;
+
+                        file_entry_count++;
+                    }
+                    break;
+                }
 
-			file_entry_count++;
-		    }
-		    break;
-		}
+            default:{
+                 /* This is an extended op code we do not know about,
+                    other than we know now many bytes it is
+                    and the op code and the bytes of operand. */
+                 Dwarf_Unsigned remaining_bytes = instr_length -1;
+                 if(instr_length < 1 || remaining_bytes > DW_LNE_LEN_MAX) {
+                      dwarf_free_line_table_prefix(&prefix);
+                      _dwarf_error(dbg, error,
+                                 DW_DLE_LINE_EXT_OPCODE_BAD);
+                      return (DW_DLV_ERROR);
+                 }
+                 line_ptr += remaining_bytes;
+                 break;
+                }
+            }
 
-	    default:{
-		    _dwarf_error(dbg, error,
-				 DW_DLE_LINE_EXT_OPCODE_BAD);
-		    return (DW_DLV_ERROR);
-		}
-	    }
-
-	}
+        }
     }
 
     block_line = (Dwarf_Line *)
-	_dwarf_get_alloc(dbg, DW_DLA_LIST, line_count);
+        _dwarf_get_alloc(dbg, DW_DLA_LIST, line_count);
     if (block_line == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
+        dwarf_free_line_table_prefix(&prefix);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
     }
 
     curr_chain = head_chain;
     for (i = 0; i < line_count; i++) {
-	*(block_line + i) = curr_chain->ch_item;
-	head_chain = curr_chain;
-	curr_chain = curr_chain->ch_next;
-	dwarf_dealloc(dbg, head_chain, DW_DLA_CHAIN);
+        *(block_line + i) = curr_chain->ch_item;
+        head_chain = curr_chain;
+        curr_chain = curr_chain->ch_next;
+        dwarf_dealloc(dbg, head_chain, DW_DLA_CHAIN);
     }
 
     line_context->lc_file_entries = file_entries;
     line_context->lc_file_entry_count = file_entry_count;
-    line_context->lc_include_directories = include_directories;
     line_context->lc_include_directories_count =
-	include_directories_count;
+        prefix.pf_include_directories_count;
+    if (prefix.pf_include_directories_count > 0) {
+        /* This gets a pointer to the *first* include dir. The others
+           follow directly with the standard DWARF2/3 NUL byte
+           following the last. */
+        line_context->lc_include_directories =
+            prefix.pf_include_directories[0];
+    }
+
     line_context->lc_line_count = line_count;
     line_context->lc_compilation_directory = comp_dir;
+    line_context->lc_version_number = prefix.pf_version;
     line_context->lc_dbg = dbg;
     *count = line_count;
 
     *linebuf = block_line;
+    dwarf_free_line_table_prefix(&prefix);
     return (DW_DLV_OK);
 }
 
 int
 dwarf_srclines(Dwarf_Die die,
-	       Dwarf_Line ** linebuf,
-	       Dwarf_Signed * linecount, Dwarf_Error * error)
+               Dwarf_Line ** linebuf,
+               Dwarf_Signed * linecount, Dwarf_Error * error)
 {
-    Dwarf_Signed count;
-    int res;
-
-    res = _dwarf_internal_srclines(die, linebuf,
-				   &count, /* addrlist= */ false,
-				   /* linelist= */ true, error);
+    Dwarf_Signed count = 0;
+    int res  = _dwarf_internal_srclines(die, linebuf, &count,
+        /* addrlist= */ false,
+        /* linelist= */ true, error);
     if (res != DW_DLV_OK) {
-	return res;
+        return res;
     }
     *linecount = count;
     return res;
@@ -1105,28 +1035,46 @@
 
 
 
-
+/* Every line table entry (except DW_DLE_end_sequence,
+   which is returned using dwarf_lineendsequence())
+   potentially has the begin-statement
+   flag marked 'on'.   This returns thru *return_bool,
+   the begin-statement flag.
+*/
 
 int
 dwarf_linebeginstatement(Dwarf_Line line,
-			 Dwarf_Bool * return_bool, Dwarf_Error * error)
+    Dwarf_Bool * return_bool, Dwarf_Error * error)
 {
     if (line == NULL || return_bool == 0) {
-	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
+        return (DW_DLV_ERROR);
     }
 
     *return_bool = (line->li_addr_line.li_l_data.li_is_stmt);
     return DW_DLV_OK;
 }
 
+/* At the end of any contiguous line-table there may be
+   a DW_LNE_end_sequence operator.
+   This returns non-zero thru *return_bool
+   if and only if this 'line' entry was a DW_LNE_end_sequence.
+
+   Within a compilation unit or function there may be multiple
+   line tables, each ending with a DW_LNE_end_sequence.
+   Each table describes a contiguous region.
+   Because compilers may split function code up in arbitrary ways
+   compilers may need to emit multiple contigous regions (ie
+   line tables) for a single function.
+   See the DWARF3 spec section 6.2.
+*/
 int
 dwarf_lineendsequence(Dwarf_Line line,
-		      Dwarf_Bool * return_bool, Dwarf_Error * error)
+    Dwarf_Bool * return_bool, Dwarf_Error * error)
 {
     if (line == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
+        return (DW_DLV_ERROR);
     }
 
     *return_bool = (line->li_addr_line.li_l_data.li_end_sequence);
@@ -1134,27 +1082,64 @@
 }
 
 
+/* Each 'line' entry has a line-number.
+   If the entry is a DW_LNE_end_sequence the line-number is
+   meaningless (see dwarf_lineendsequence(), just above).
+*/
 int
 dwarf_lineno(Dwarf_Line line,
-	     Dwarf_Unsigned * ret_lineno, Dwarf_Error * error)
+    Dwarf_Unsigned * ret_lineno, Dwarf_Error * error)
 {
     if (line == NULL || ret_lineno == 0) {
-	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
+        return (DW_DLV_ERROR);
     }
 
     *ret_lineno = (line->li_addr_line.li_l_data.li_line);
     return DW_DLV_OK;
 }
 
+/* Each 'line' entry has a file-number, and index into the file table.
+   If the entry is a DW_LNE_end_sequence the index is
+   meaningless (see dwarf_lineendsequence(), just above).
+   The file number returned is an index into the file table
+   produced by dwarf_srcfiles(), but care is required: the
+   li_file begins with 1 for real files, so that the li_file returned here
+   is 1 greater than its index into the dwarf_srcfiles() output array.
+   And entries from DW_LNE_define_file don't appear in
+   the dwarf_srcfiles() output so file indexes from here may exceed
+   the size of the dwarf_srcfiles() output array size.
+*/
+int
+dwarf_line_srcfileno(Dwarf_Line line,
+    Dwarf_Unsigned * ret_fileno, Dwarf_Error * error)
+{
+    if (line == NULL || ret_fileno == 0) {
+        _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
+        return (DW_DLV_ERROR);
+    }
+    /* li_file must be <= line->li_context->lc_file_entry_count else it 
+       is trash. li_file 0 means not attributable to any source file
+       per dwarf2/3 spec. */
 
+    *ret_fileno = (line->li_addr_line.li_l_data.li_file);
+    return DW_DLV_OK;
+}
+
+
+/* Each 'line' entry has a line-address.
+   If the entry is a DW_LNE_end_sequence the adddress
+   is one-beyond the last address this contigous region
+   covers, so the address is not inside the region, 
+   but is just outside it.
+*/
 int
 dwarf_lineaddr(Dwarf_Line line,
-	       Dwarf_Addr * ret_lineaddr, Dwarf_Error * error)
+    Dwarf_Addr * ret_lineaddr, Dwarf_Error * error)
 {
     if (line == NULL || ret_lineaddr == 0) {
-	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
+        return (DW_DLV_ERROR);
     }
 
     *ret_lineaddr = (line->li_address);
@@ -1162,18 +1147,27 @@
 }
 
 
+/* Each 'line' entry has a column-within-line (offset
+   within the line) where the
+   source text begins.
+   If the entry is a DW_LNE_end_sequence the line-number is
+   meaningless (see dwarf_lineendsequence(), just above).
+   Lines of text begin at column 1.  The value 0
+   means the line begins at the left edge of the line.
+   (See the DWARF3 spec, section 6.2.2).
+*/
 int
 dwarf_lineoff(Dwarf_Line line,
-	      Dwarf_Signed * ret_lineoff, Dwarf_Error * error)
+    Dwarf_Signed * ret_lineoff, Dwarf_Error * error)
 {
     if (line == NULL || ret_lineoff == 0) {
-	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
+        return (DW_DLV_ERROR);
     }
 
     *ret_lineoff =
-	(line->li_addr_line.li_l_data.li_column ==
-	 0 ? -1 : line->li_addr_line.li_l_data.li_column);
+        (line->li_addr_line.li_l_data.li_column ==
+         0 ? -1 : line->li_addr_line.li_l_data.li_column);
     return DW_DLV_OK;
 }
 
@@ -1181,135 +1175,149 @@
 int
 dwarf_linesrc(Dwarf_Line line, char **ret_linesrc, Dwarf_Error * error)
 {
-    Dwarf_Signed i;
+    Dwarf_Signed i = 0;
     Dwarf_File_Entry file_entry;
-    Dwarf_Small *name_buffer;
-    Dwarf_Small *include_directories;
-    Dwarf_Debug dbg;
-    unsigned int comp_dir_len;
+    Dwarf_Small *name_buffer = 0;
+    Dwarf_Small *include_directories = 0;
+    Dwarf_Small include_direc_full_path = 0;
+    Dwarf_Small file_name_full_path = 0;
+    Dwarf_Debug dbg = 0;
+    unsigned int comp_dir_len = 0;
 
     if (line == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
+        return (DW_DLV_ERROR);
     }
 
     if (line->li_context == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_NULL);
+        return (DW_DLV_ERROR);
     }
     dbg = line->li_context->lc_dbg;
 
     if (line->li_addr_line.li_l_data.li_file >
-	line->li_context->lc_file_entry_count) {
-	_dwarf_error(dbg, error, DW_DLE_LINE_FILE_NUM_BAD);
-	return (DW_DLV_ERROR);
+        line->li_context->lc_file_entry_count) {
+        _dwarf_error(dbg, error, DW_DLE_LINE_FILE_NUM_BAD);
+        return (DW_DLV_ERROR);
     }
 
+    if (line->li_addr_line.li_l_data.li_file == 0) {
+        /* No file name known: see dwarf2/3 spec. */
+        _dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME);
+        return (DW_DLV_ERROR);
+    }
     file_entry = line->li_context->lc_file_entries;
+    /* ASSERT: li_file > 0, dwarf correctness issue, see line table
+       definition of dwarf2/3 spec. */
+    /* Example: if li_file is 2 and lc_file_entry_count is 3,
+       file_entry is file 3 (1 based), aka 2( 0 based) file_entry->next 
+       is file 2 (1 based), aka 1( 0 based) file_entry->next->next is
+       file 1 (1 based), aka 0( 0 based) file_entry->next->next->next
+       is NULL.
+
+       and this loop finds the file_entry we need (2 (1 based) in this
+       case). Because lc_file_entries are in reverse order and
+       effectively zero based as a count whereas li_file is 1 based. */
     for (i = line->li_addr_line.li_l_data.li_file - 1; i > 0; i--)
-	file_entry = file_entry->fi_next;
+        file_entry = file_entry->fi_next;
 
     if (file_entry->fi_file_name == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME);
+        return (DW_DLV_ERROR);
     }
 
-    if (*(char *) file_entry->fi_file_name == '/') {
-	*ret_linesrc = ((char *) file_entry->fi_file_name);
-	return DW_DLV_OK;
+    file_name_full_path = file_name_is_full_path(file_entry->fi_file_name);
+    if (file_name_full_path) {
+        *ret_linesrc = ((char *) file_entry->fi_file_name);
+        return DW_DLV_OK;
     }
 
     if (file_entry->fi_dir_index == 0) {
 
-	/* dir_index of 0 means that the compilation was in the
-	   'current directory of compilation' */
-	if (line->li_context->lc_compilation_directory == NULL) {
-	    /* we don't actually *have* a current directory of
-	       compilation: DW_AT_comp_dir was not present Rather than
-	       emitting DW_DLE_NO_COMP_DIR lets just make an empty name 
-	       here. In other words, do the best we can with what we do 
-	       have instead of reporting an error. _dwarf_error(dbg,
-	       error, DW_DLE_NO_COMP_DIR); return(DW_DLV_ERROR); */
-	    comp_dir_len = 0;
-	} else {
-	    comp_dir_len = strlen((char *)
-				  (line->li_context->
-				   lc_compilation_directory));
-	}
+        /* dir_index of 0 means that the compilation was in the
+           'current directory of compilation' */
+        if (line->li_context->lc_compilation_directory == NULL) {
+            /* we don't actually *have* a current directory of
+               compilation: DW_AT_comp_dir was not present Rather than
+               emitting DW_DLE_NO_COMP_DIR lets just make an empty name 
+               here. In other words, do the best we can with what we do 
+               have instead of reporting an error. _dwarf_error(dbg,
+               error, DW_DLE_NO_COMP_DIR); return(DW_DLV_ERROR); */
+            comp_dir_len = 0;
+        } else {
+            comp_dir_len = strlen((char *)
+                                  (line->li_context->
+                                   lc_compilation_directory));
+        }
 
-	name_buffer =
-	    _dwarf_get_alloc(line->li_context->lc_dbg, DW_DLA_STRING,
-			     comp_dir_len + 1 +
-			     strlen((char *) file_entry->fi_file_name) +
-			     1);
-	if (name_buffer == NULL) {
-	    _dwarf_error(line->li_context->lc_dbg, error,
-			 DW_DLE_ALLOC_FAIL);
-	    return (DW_DLV_ERROR);
-	}
+        name_buffer =
+            _dwarf_get_alloc(line->li_context->lc_dbg, DW_DLA_STRING,
+                             comp_dir_len + 1 +
+                             strlen((char *) file_entry->fi_file_name) +
+                             1);
+        if (name_buffer == NULL) {
+            _dwarf_error(line->li_context->lc_dbg, error,
+                         DW_DLE_ALLOC_FAIL);
+            return (DW_DLV_ERROR);
+        }
 
-	if (comp_dir_len > 0) {
-	    /* if comp_dir_len is 0 we do not want to put a / in front
-	       of the fi_file_name as we just don't know anything. */
-	    strcpy((char *) name_buffer,
-		   (char *) (line->li_context->
-			     lc_compilation_directory));
-	    strcat((char *) name_buffer, "/");
-	}
-	strcat((char *) name_buffer, (char *) file_entry->fi_file_name);
-	*ret_linesrc = ((char *) name_buffer);
-	return DW_DLV_OK;
+        if (comp_dir_len > 0) {
+            /* if comp_dir_len is 0 we do not want to put a / in front
+               of the fi_file_name as we just don't know anything. */
+            strcpy((char *) name_buffer,
+                   (char *) (line->li_context->
+                             lc_compilation_directory));
+            strcat((char *) name_buffer, "/");
+        }
+        strcat((char *) name_buffer, (char *) file_entry->fi_file_name);
+        *ret_linesrc = ((char *) name_buffer);
+        return DW_DLV_OK;
     }
 
     if (file_entry->fi_dir_index >
-	line->li_context->lc_include_directories_count) {
-	_dwarf_error(dbg, error, DW_DLE_INCL_DIR_NUM_BAD);
-	return (DW_DLV_ERROR);
+        line->li_context->lc_include_directories_count) {
+        _dwarf_error(dbg, error, DW_DLE_INCL_DIR_NUM_BAD);
+        return (DW_DLV_ERROR);
     }
 
     include_directories = line->li_context->lc_include_directories;
     for (i = file_entry->fi_dir_index - 1; i > 0; i--)
-	include_directories += strlen((char *) include_directories) + 1;
+        include_directories += strlen((char *) include_directories) + 1;
 
     if (line->li_context->lc_compilation_directory) {
-	comp_dir_len = strlen((char *)
-			      (line->li_context->
-			       lc_compilation_directory));
+        comp_dir_len = strlen((char *)
+            (line->li_context->lc_compilation_directory));
     } else {
-	/* No DW_AT_comp_dir present. Do the best we can without it. */
-	comp_dir_len = 0;
+        /* No DW_AT_comp_dir present. Do the best we can without it. */
+        comp_dir_len = 0;
     }
 
+    include_direc_full_path = file_name_is_full_path(include_directories);
     name_buffer = _dwarf_get_alloc(dbg, DW_DLA_STRING,
-				   (*include_directories == '/' ?
-				    0 : comp_dir_len + 1) +
-				   strlen((char *) include_directories)
-				   + 1 +
-				   strlen((char *) file_entry->
-					  fi_file_name) + 1);
+        (include_direc_full_path ?  0 : comp_dir_len + 1) +
+            strlen((char *)include_directories) + 1 + 
+            strlen((char *)file_entry->fi_file_name) + 1);
     if (name_buffer == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
     }
 
-    if (*include_directories != '/') {
-	if (comp_dir_len > 0) {
-	    strcpy((char *) name_buffer,
-		   (char *) line->li_context->lc_compilation_directory);
-	    /* Who provides the / needed after the compilation
-	       directory? */
-	    if (name_buffer[comp_dir_len - 1] != '/') {
-		/* Here we provide the / separator */
-		name_buffer[comp_dir_len] = '/';	/* overwrite
-							   previous nul 
-							   terminator
-							   with needed
-							   / */
-		name_buffer[comp_dir_len + 1] = 0;
-	    }
-	}
+    if (!include_direc_full_path) {
+        if (comp_dir_len > 0) {
+            strcpy((char *)name_buffer,
+                (char *)line->li_context->lc_compilation_directory);
+            /* Who provides the / needed after the compilation
+               directory? */
+            if (!is_path_separator(name_buffer[comp_dir_len - 1])) {
+                /* Here we provide the / separator. It
+                   should work ok for Windows */
+                /* Overwrite previous nul terminator with needed / */
+                name_buffer[comp_dir_len] = '/';   
+                name_buffer[comp_dir_len + 1] = 0;
+            }
+        }
     } else {
-	strcpy((char *) name_buffer, "");
+        strcpy((char *) name_buffer, "");
     }
     strcat((char *) name_buffer, (char *) include_directories);
     strcat((char *) name_buffer, "/");
@@ -1318,23 +1326,25 @@
     return DW_DLV_OK;
 }
 
-
+/* Every line table entry potentially has the basic-block-start
+   flag marked 'on'.   This returns thru *return_bool,
+   the basic-block-start flag.
+*/
 int
 dwarf_lineblock(Dwarf_Line line,
-		Dwarf_Bool * return_bool, Dwarf_Error * error)
+    Dwarf_Bool * return_bool, Dwarf_Error * error)
 {
     if (line == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
+        return (DW_DLV_ERROR);
     }
-
     *return_bool = (line->li_addr_line.li_l_data.li_basic_block);
     return DW_DLV_OK;
 }
 
 
-#if 0				/* Ignore this.  This needs major
-				   re-work. */
+#if 0                           /* Ignore this.  This needs major
+                                   re-work. */
 /* 
     This routine works by looking for exact matches between 
     the current line address and pc, and crossovers from
@@ -1346,10 +1356,10 @@
 */
 int
 dwarf_pclines(Dwarf_Debug dbg,
-	      Dwarf_Addr pc,
-	      Dwarf_Line ** linebuf,
-	      Dwarf_Signed slide,
-	      Dwarf_Signed * linecount, Dwarf_Error * error)
+              Dwarf_Addr pc,
+              Dwarf_Line ** linebuf,
+              Dwarf_Signed slide,
+              Dwarf_Signed * linecount, Dwarf_Error * error)
 {
     /* 
        Scans the line matrix for the current cu to which a pointer
@@ -1359,29 +1369,29 @@
 
     /* 
        These flags are for efficiency reasons. Check_line is true
-       initially, but set false when the address of the current line
-       is greater than pc.  It is set true only when the address of the 
-       current line falls below pc.  This assumes that addresses
-       within the same segment increase, and we are only interested in
-       the switch from a less than pc address to a greater than.
-       First_line is set true initially, but set false after the first
-       line is scanned.  This is to prevent looking at the address of
-       previous line when slide is DW_DLS_BACKWARD, and the first line
-       is being scanned. */
+       initially, but set false when the address of the current line is 
+       greater than pc.  It is set true only when the address of the
+       current line falls below pc.  This assumes that addresses within 
+       the same segment increase, and we are only interested in the
+       switch from a less than pc address to a greater than. First_line 
+       is set true initially, but set false after the first line is
+       scanned.  This is to prevent looking at the address of previous
+       line when slide is DW_DLS_BACKWARD, and the first line is being
+       scanned. */
     Dwarf_Bool check_line, first_line;
 
     /* 
-       Diff tracks the smallest difference a line address and the
-       input pc value. */
+       Diff tracks the smallest difference a line address and the input 
+       pc value. */
     Dwarf_Signed diff, i;
 
     /* 
        For the slide = DW_DLS_BACKWARD case, pc_less is the value of
        the address of the line immediately preceding the first line
-       that has value greater than pc. For the slide = DW_DLS_FORWARD 
+       that has value greater than pc. For the slide = DW_DLS_FORWARD
        case, pc_more is the values of address for the first line that
-       is greater than pc. Diff is the difference between either of
-       the these values and pc. */
+       is greater than pc. Diff is the difference between either of the 
+       these values and pc. */
     Dwarf_Addr pc_less, pc_more;
 
     /* 
@@ -1404,88 +1414,88 @@
 
     for (i = 0; i < dbg->de_cu_line_count; i++) {
 
-	line = *(dbg->de_cu_line_ptr + i);
-	prev_line = first_line ? NULL : *(dbg->de_cu_line_ptr + i - 1);
+        line = *(dbg->de_cu_line_ptr + i);
+        prev_line = first_line ? NULL : *(dbg->de_cu_line_ptr + i - 1);
 
-	if (line->li_address == pc) {
-	    chain_ptr = (struct chain *)
-		_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
-	    if (chain_ptr == NULL) {
-		_dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
-		return (DW_DLV_ERROR);
-	    }
+        if (line->li_address == pc) {
+            chain_ptr = (struct chain *)
+                _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+            if (chain_ptr == NULL) {
+                _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
+                return (DW_DLV_ERROR);
+            }
 
-	    chain_ptr->line = line;
-	    chain_ptr->diff = diff = 0;
-	    chain_ptr->next = chain_head;
-	    chain_head = chain_ptr;
-	} else
-	    /* 
-	       Look for crossover from less than pc address to greater 
-	       than. */
-	if (check_line && line->li_address > pc &&
-		(first_line ? 0 : prev_line->li_address) < pc)
+            chain_ptr->line = line;
+            chain_ptr->diff = diff = 0;
+            chain_ptr->next = chain_head;
+            chain_head = chain_ptr;
+        } else
+            /* 
+               Look for crossover from less than pc address to greater
+               than. */
+        if (check_line && line->li_address > pc &&
+                (first_line ? 0 : prev_line->li_address) < pc)
 
-	    if (slide == DW_DLS_BACKWARD && !first_line) {
-		pc_less = prev_line->li_address;
-		if (pc - pc_less <= diff) {
-		    chain_ptr = (struct chain *)
-			_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
-		    if (chain_ptr == NULL) {
-			_dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
-			return (DW_DLV_ERROR);
-		    }
+            if (slide == DW_DLS_BACKWARD && !first_line) {
+                pc_less = prev_line->li_address;
+                if (pc - pc_less <= diff) {
+                    chain_ptr = (struct chain *)
+                        _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+                    if (chain_ptr == NULL) {
+                        _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
+                        return (DW_DLV_ERROR);
+                    }
 
-		    chain_ptr->line = prev_line;
-		    chain_ptr->diff = diff = pc - pc_less;
-		    chain_ptr->next = chain_head;
-		    chain_head = chain_ptr;
-		}
-		check_line = false;
-	    } else if (slide == DW_DLS_FORWARD) {
-		pc_more = line->li_address;
-		if (pc_more - pc <= diff) {
-		    chain_ptr = (struct chain *)
-			_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
-		    if (chain_ptr == NULL) {
-			_dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
-			return (DW_DLV_ERROR);
-		    }
+                    chain_ptr->line = prev_line;
+                    chain_ptr->diff = diff = pc - pc_less;
+                    chain_ptr->next = chain_head;
+                    chain_head = chain_ptr;
+                }
+                check_line = false;
+            } else if (slide == DW_DLS_FORWARD) {
+                pc_more = line->li_address;
+                if (pc_more - pc <= diff) {
+                    chain_ptr = (struct chain *)
+                        _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+                    if (chain_ptr == NULL) {
+                        _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
+                        return (DW_DLV_ERROR);
+                    }
 
-		    chain_ptr->line = line;
-		    chain_ptr->diff = diff = pc_more - pc;
-		    chain_ptr->next = chain_head;
-		    chain_head = chain_ptr;
-		}
-		check_line = false;
-	    } else
-		/* Check addresses only when they go */
-		/* below pc.  */
-	    if (line->li_address < pc)
-		check_line = true;
+                    chain_ptr->line = line;
+                    chain_ptr->diff = diff = pc_more - pc;
+                    chain_ptr->next = chain_head;
+                    chain_head = chain_ptr;
+                }
+                check_line = false;
+            } else
+                /* Check addresses only when they go */
+                /* below pc.  */
+            if (line->li_address < pc)
+                check_line = true;
 
-	first_line = false;
+        first_line = false;
     }
 
     chain_count = 0;
     for (chain_ptr = chain_head; chain_ptr != NULL;
-	 chain_ptr = chain_ptr->next)
-	if (chain_ptr->diff == diff)
-	    chain_count++;
+         chain_ptr = chain_ptr->next)
+        if (chain_ptr->diff == diff)
+            chain_count++;
 
     pc_line_buf = pc_line = (Dwarf_Line)
-	_dwarf_get_alloc(dbg, DW_DLA_LIST, chain_count);
+        _dwarf_get_alloc(dbg, DW_DLA_LIST, chain_count);
     for (chain_ptr = chain_head; chain_ptr != NULL;
-	 chain_ptr = chain_ptr->next)
-	if (chain_ptr->diff == diff) {
-	    *pc_line = chain_ptr->line;
-	    pc_line++;
-	}
+         chain_ptr = chain_ptr->next)
+        if (chain_ptr->diff == diff) {
+            *pc_line = chain_ptr->line;
+            pc_line++;
+        }
 
     for (chain_ptr = chain_head; chain_ptr != NULL;) {
-	chain_head = chain_ptr;
-	chain_ptr = chain_ptr->next;
-	dwarf_dealloc(dbg, chain_head, DW_DLA_CHAIN);
+        chain_head = chain_ptr;
+        chain_ptr = chain_ptr->next;
+        dwarf_dealloc(dbg, chain_head, DW_DLA_CHAIN);
     }
 
     *linebuf = pc_line_buf;
@@ -1494,55 +1504,448 @@
 #endif
 
 
+
 /*
-	Return DW_DLV_OK or, if error,
-	DW_DLV_ERROR.
+   It's impossible for callers of dwarf_srclines() to get to and
+   free all the resources (in particular, the li_context and its
+   lc_file_entries). 
+   So this function, new July 2005, does it.  
+*/
+
+void
+dwarf_srclines_dealloc(Dwarf_Debug dbg, Dwarf_Line * linebuf,
+    Dwarf_Signed count)
+{
+
+    Dwarf_Signed i = 0;
+    struct Dwarf_Line_Context_s *context = 0;
+
+    if (count > 0) {
+        /* All these entries share a single context */
+        context = linebuf[0]->li_context;
+    }
+    for (i = 0; i < count; ++i) {
+        dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE);
+    }
+    dwarf_dealloc(dbg, linebuf, DW_DLA_LIST);
+
+    if (context) {
+        Dwarf_File_Entry fe = context->lc_file_entries;
+
+        while (fe) {
+            Dwarf_File_Entry fenext = fe->fi_next;
+
+            dwarf_dealloc(dbg, fe, DW_DLA_FILE_ENTRY);
+            fe = fenext;
+        }
+        dwarf_dealloc(dbg, context, DW_DLA_LINE_CONTEXT);
+    }
+
+    return;
+}
+
+/* Operand counts per standard operand.
+   The initial zero is for DW_LNS_copy. 
+   This is an economical way to verify we understand the table
+   of standard-opcode-lengths in the line table prologue.  */
+#define STANDARD_OPERAND_COUNT_DWARF2 9
+#define STANDARD_OPERAND_COUNT_DWARF3 12
+static unsigned char
+  dwarf_standard_opcode_operand_count[STANDARD_OPERAND_COUNT_DWARF3] = {
+    /* DWARF2 */
+    0,
+    1, 1, 1, 1,
+    0, 0, 0,
+    1,
+    /* Following are new for DWARF3. */
+    0, 0, 1
+};
 
-	Thru pointers, return 2 arrays and a count
-	for rqs.
+/* We have a normal standard opcode base, but
+   an arm compiler emitted a non-standard table! 
+   This could lead to problems...
+   ARM C/C++ Compiler, RVCT4.0 [Build 4
+   00] seems to get the table wrong .  */
+static unsigned char
+dwarf_arm_standard_opcode_operand_count[STANDARD_OPERAND_COUNT_DWARF3] = {
+    /* DWARF2 */
+    0,
+    1, 1, 1, 1,
+    0, 0, 0,
+    0,  /* <<< --- this is wrong */
+    /* Following are new for DWARF3. */
+    0, 0, 1
+};
+
+static void
+print_header_issue(Dwarf_Debug dbg,
+    char *specific_msg,
+    Dwarf_Small *data_start,
+    int *err_count_out)
+{
+    if(!err_count_out)
+        return;
+    printf("*** DWARF CHECK: "
+        "line table header: %s", 
+        specific_msg);
+    if( data_start >= dbg->de_debug_line.dss_data && 
+        (data_start < (dbg->de_debug_line.dss_data + 
+        dbg->de_debug_line.dss_size))) {
+        Dwarf_Unsigned off = data_start - dbg->de_debug_line.dss_data;
+        printf(" at .debug_line section offset 0x%" DW_PR_DUx 
+            "  ( %" DW_PR_DUu " ) ",
+            off,off);
+    } else {
+        printf(" (unknown section location) ");
+    }
+    printf("***\n");
+    *err_count_out += 1;
+}
+
+
+
+/* Common line table prefix reading code. 
+   Returns DW_DLV_OK, DW_DLV_ERROR.
+   DW_DLV_NO_ENTRY cannot be returned, but callers should
+   assume it is possible.
+
+   The prefix_out area must be initialized properly before calling this.
+
+   Has the side effect of allocating arrays which
+   must be freed (see the Line_Table_Prefix_s struct which
+   holds the pointers to space we allocate here).
+
+   bogus_bytes_ptr and bogus_bytes are output values which
+   let a print-program notify the user of some surprising bytes
+   after a line table header and before the line table instructions.
+   These can be ignored unless one is printing.
+   And are ignored if NULL passed as the pointer.
+*/
+
+/* err_count_out may be NULL, in which case we
+   make no attempt to count checking-type errors.
+   Checking-type errors do not stop us, we just report them.
 */
 int
-_dwarf_line_address_offsets(Dwarf_Debug dbg,
-			    Dwarf_Die die,
-			    Dwarf_Addr ** addrs,
-			    Dwarf_Off ** offs,
-			    Dwarf_Unsigned * returncount,
-			    Dwarf_Error * err)
+dwarf_read_line_table_prefix(Dwarf_Debug dbg,
+    Dwarf_Small * data_start,
+    Dwarf_Unsigned data_length,
+    Dwarf_Small ** updated_data_start_out,
+    struct Line_Table_Prefix_s *prefix_out,
+    Dwarf_Small ** bogus_bytes_ptr,
+    Dwarf_Unsigned *bogus_bytes,
+    Dwarf_Error * err,
+    int *err_count_out)
 {
-    Dwarf_Addr *laddrs;
-    Dwarf_Off *loffsets;
-    Dwarf_Signed lcount;
-    Dwarf_Signed i;
-    int res;
-    Dwarf_Line *linebuf;
+    Dwarf_Small *line_ptr = data_start;
+    Dwarf_Unsigned total_length = 0;
+    int local_length_size = 0;
+    int local_extension_size = 0;
+    Dwarf_Unsigned prologue_length = 0;
+    Dwarf_Half version = 0;
+    Dwarf_Unsigned directories_count = 0;
+    Dwarf_Unsigned directories_malloc = 0;
+    Dwarf_Unsigned files_count = 0;
+    Dwarf_Unsigned files_malloc = 0;
+    Dwarf_Small *line_ptr_end = 0;
+    Dwarf_Small *lp_begin = 0;
+    if(bogus_bytes_ptr) *bogus_bytes_ptr = 0;
+    if(bogus_bytes) *bogus_bytes= 0;
 
-    res = _dwarf_internal_srclines(die, &linebuf,
-				   &lcount, /* addrlist= */ true,
-				   /* linelist= */ false, err);
-    if (res != DW_DLV_OK) {
-	return res;
+    prefix_out->pf_line_ptr_start = line_ptr;
+    /* READ_AREA_LENGTH updates line_ptr for consumed bytes */
+    READ_AREA_LENGTH(dbg, total_length, Dwarf_Unsigned,
+                     line_ptr, local_length_size, local_extension_size);
+
+
+    line_ptr_end = line_ptr + total_length;
+    prefix_out->pf_line_ptr_end = line_ptr_end;
+    prefix_out->pf_length_field_length = local_length_size +
+        local_extension_size;
+    /* ASSERT: prefix_out->pf_length_field_length == line_ptr
+       -prefix_out->pf_line_ptr_start; */
+    if (line_ptr_end > dbg->de_debug_line.dss_data + 
+        dbg->de_debug_line.dss_size) {
+        _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
+        return (DW_DLV_ERROR);
     }
-    laddrs = (Dwarf_Addr *)
-	_dwarf_get_alloc(dbg, DW_DLA_ADDR, lcount);
-    if (laddrs == NULL) {
-	_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
+    if (line_ptr_end > data_start + data_length) {
+        _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
+        return (DW_DLV_ERROR);
     }
-    loffsets = (Dwarf_Off *)
-	_dwarf_get_alloc(dbg, DW_DLA_ADDR, lcount);
-    if (loffsets == NULL) {
-	_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
+    prefix_out->pf_total_length = total_length;
+
+    READ_UNALIGNED(dbg, version, Dwarf_Half,
+                   line_ptr, sizeof(Dwarf_Half));
+    prefix_out->pf_version = version;
+    line_ptr += sizeof(Dwarf_Half);
+    if (version != CURRENT_VERSION_STAMP &&
+        version != CURRENT_VERSION_STAMP3) {
+        _dwarf_error(dbg, err, DW_DLE_VERSION_STAMP_ERROR);
+        return (DW_DLV_ERROR);
     }
 
-    for (i = 0; i < lcount; i++) {
-	laddrs[i] = linebuf[i]->li_address;
-	loffsets[i] = linebuf[i]->li_addr_line.li_offset;
-	dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE);
+    READ_UNALIGNED(dbg, prologue_length, Dwarf_Unsigned,
+                   line_ptr, local_length_size);
+    prefix_out->pf_prologue_length = prologue_length;
+    line_ptr += local_length_size;
+    prefix_out->pf_line_prologue_start = line_ptr;
+
+    prefix_out->pf_minimum_instruction_length =
+        *(unsigned char *) line_ptr;
+    line_ptr = line_ptr + sizeof(Dwarf_Small);
+
+    prefix_out->pf_default_is_stmt = *(unsigned char *) line_ptr;
+    line_ptr = line_ptr + sizeof(Dwarf_Small);
+
+    prefix_out->pf_line_base = *(signed char *) line_ptr;
+    line_ptr = line_ptr + sizeof(Dwarf_Sbyte);
+
+    prefix_out->pf_line_range = *(unsigned char *) line_ptr;
+    line_ptr = line_ptr + sizeof(Dwarf_Small);
+
+    prefix_out->pf_opcode_base = *(unsigned char *) line_ptr;
+    line_ptr = line_ptr + sizeof(Dwarf_Small);
+
+    /* Set up the array of standard opcode lengths. */
+    /* We think this works ok even for cross-endian processing of
+       objects.  It might be wrong, we might need to specially process
+       the array of ubyte into host order.  */
+    prefix_out->pf_opcode_length_table = line_ptr;
+
+    /* pf_opcode_base is one greater than the size of the array. */
+    line_ptr += prefix_out->pf_opcode_base - 1;
+
+    {
+        /* Determine (as best we can) whether the
+           pf_opcode_length_table holds 9 or 12 standard-conforming
+           entries.  gcc4 upped to DWARF3's 12 without updating the
+           version number.   */
+        int operand_ck_fail = true;
+
+        if (prefix_out->pf_opcode_base >= STANDARD_OPERAND_COUNT_DWARF3) {
+            int mismatch = memcmp(dwarf_standard_opcode_operand_count,
+                                  prefix_out->pf_opcode_length_table,
+                                  STANDARD_OPERAND_COUNT_DWARF3);
+            if(mismatch) {
+                 if(err_count_out) {
+                     print_header_issue(dbg,"standard-operands did not match", 
+                         data_start,err_count_out);
+                 }
+                 mismatch = memcmp(dwarf_arm_standard_opcode_operand_count,
+                                  prefix_out->pf_opcode_length_table,
+                                  STANDARD_OPERAND_COUNT_DWARF3);
+                 if(!mismatch && err_count_out) {
+                     print_header_issue(dbg,"arm (incorrect) operands in use", 
+                         data_start,err_count_out);
+                 }
+            }
+            if (!mismatch) {
+                if (version == 2) {
+                    if(err_count_out) {
+                        print_header_issue(dbg,
+                        "standard DWARF3 operands matched, but is DWARF2 linetable", 
+                            data_start,err_count_out);
+                    }
+                }
+                operand_ck_fail = false;
+                prefix_out->pf_std_op_count =
+                    STANDARD_OPERAND_COUNT_DWARF3;
+            } 
+        }
+        if (operand_ck_fail) {
+            if (prefix_out->pf_opcode_base >=
+                STANDARD_OPERAND_COUNT_DWARF2) {
+
+                int mismatch =
+                    memcmp(dwarf_standard_opcode_operand_count,
+                           prefix_out->pf_opcode_length_table,
+                           STANDARD_OPERAND_COUNT_DWARF2);
+                if(mismatch) {
+                    if(err_count_out) {
+                        print_header_issue(dbg,"standard-operands-lengths did not match", 
+                            data_start,err_count_out);
+                    }
+                    mismatch = memcmp(dwarf_arm_standard_opcode_operand_count,
+                                  prefix_out->pf_opcode_length_table,
+                                  STANDARD_OPERAND_COUNT_DWARF2);
+                    if(!mismatch && err_count_out) {
+                        print_header_issue(dbg,"arm (incorrect) operand in use", 
+                            data_start,err_count_out);
+                    }
+                }
+
+                if (!mismatch) {
+                    operand_ck_fail = false;
+                    prefix_out->pf_std_op_count =
+                        STANDARD_OPERAND_COUNT_DWARF2;
+                }
+            }
+        } 
+        if (operand_ck_fail) {
+            /* Here we are not sure what the pf_std_op_count is. */
+            _dwarf_error(dbg, err, DW_DLE_LINE_NUM_OPERANDS_BAD);
+            return (DW_DLV_ERROR);
+        }
+    }
+    /* At this point we no longer need to check operand counts. */
+
+
+    directories_count = 0;
+    directories_malloc = 5;
+    prefix_out->pf_include_directories = malloc(sizeof(Dwarf_Small *) *
+                                                directories_malloc);
+    if (prefix_out->pf_include_directories == NULL) {
+        _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
     }
-    dwarf_dealloc(dbg, linebuf, DW_DLA_LIST);
-    *returncount = lcount;
-    *offs = loffsets;
-    *addrs = laddrs;
+    memset(prefix_out->pf_include_directories, 0,
+           sizeof(Dwarf_Small *) * directories_malloc);
+
+    while ((*(char *) line_ptr) != '\0') {
+        if (directories_count >= directories_malloc) {
+            Dwarf_Unsigned expand = 2 * directories_malloc;
+            Dwarf_Unsigned bytesalloc = sizeof(Dwarf_Small *) * expand;
+            Dwarf_Small **newdirs =
+                realloc(prefix_out->pf_include_directories,
+                        bytesalloc);
+
+            if (!newdirs) {
+                _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+                return (DW_DLV_ERROR);
+            }
+            /* Doubled size, zero out second half. */
+            memset(newdirs + directories_malloc, 0,
+                   sizeof(Dwarf_Small *) * directories_malloc);
+            directories_malloc = expand;
+            prefix_out->pf_include_directories = newdirs;
+        }
+        prefix_out->pf_include_directories[directories_count] =
+            line_ptr;
+        line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
+        directories_count++;
+    }
+    prefix_out->pf_include_directories_count = directories_count;
+    line_ptr++;
+
+    files_count = 0;
+    files_malloc = 5;
+    prefix_out->pf_line_table_file_entries =
+        malloc(sizeof(struct Line_Table_File_Entry_s) * files_malloc);
+    if (prefix_out->pf_line_table_file_entries == NULL) {
+        _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
+    }
+    memset(prefix_out->pf_line_table_file_entries, 0,
+           sizeof(struct Line_Table_File_Entry_s) * files_malloc);
+
+    while (*(char *) line_ptr != '\0') {
+        Dwarf_Unsigned utmp;
+        Dwarf_Unsigned dir_index = 0;
+        Dwarf_Unsigned lastmod = 0;
+        Dwarf_Unsigned file_length = 0;
+        struct Line_Table_File_Entry_s *curline;
+        Dwarf_Word leb128_length = 0;
+
+
+        if (files_count >= files_malloc) {
+            Dwarf_Unsigned expand = 2 * files_malloc;
+            struct Line_Table_File_Entry_s *newfiles =
+                realloc(prefix_out->pf_line_table_file_entries,
+                        sizeof(struct Line_Table_File_Entry_s) *
+                        expand);
+            if (!newfiles) {
+                _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+                return (DW_DLV_ERROR);
+            }
+            memset(newfiles + files_malloc, 0,
+                   sizeof(struct Line_Table_File_Entry_s) *
+                   files_malloc);
+            files_malloc = expand;
+            prefix_out->pf_line_table_file_entries = newfiles;
+        }
+        curline = prefix_out->pf_line_table_file_entries + files_count;
+
+        curline->lte_filename = line_ptr;
+        line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
+
+        DECODE_LEB128_UWORD(line_ptr, utmp);
+        dir_index = (Dwarf_Sword) utmp;
+        if (dir_index > directories_count) {
+            _dwarf_error(dbg, err, DW_DLE_DIR_INDEX_BAD);
+            return (DW_DLV_ERROR);
+        }
+        curline->lte_directory_index = dir_index;
+
+        lastmod = _dwarf_decode_u_leb128(line_ptr, &leb128_length);
+        line_ptr = line_ptr + leb128_length;
+        curline->lte_last_modification_time = lastmod;
+
+        /* Skip over file length. */
+        file_length = _dwarf_decode_u_leb128(line_ptr, &leb128_length);
+        line_ptr = line_ptr + leb128_length;
+        curline->lte_length_of_file = file_length;
+
+        ++files_count;
+
+    }
+    prefix_out->pf_files_count = files_count;
+    /* Skip trailing nul byte */
+    ++line_ptr;
+
+   
+    lp_begin = prefix_out->pf_line_prologue_start +
+                     prefix_out->pf_prologue_length;
+    if (line_ptr != lp_begin) {
+        if(line_ptr > lp_begin) { 
+            _dwarf_error(dbg, err, DW_DLE_LINE_PROLOG_LENGTH_BAD);
+            return (DW_DLV_ERROR);
+        } else {
+            /* Bug in compiler. These
+             * bytes are really part of the instruction
+             * stream.  The prefix_out->pf_prologue_length is
+             * wrong (12 too high).  */
+            if(bogus_bytes_ptr) {
+               *bogus_bytes_ptr = line_ptr;
+            }
+            if(bogus_bytes) {
+               /* How far off things are. We expect the
+                  value 12 ! */
+               *bogus_bytes = (lp_begin - line_ptr);
+            }
+        }
+        /* Ignore the lp_begin calc. Assume line_ptr right.
+           Making up for compiler bug. */
+        lp_begin = line_ptr; 
+        
+    }
+
+    *updated_data_start_out = lp_begin;
     return DW_DLV_OK;
 }
+
+
+/* Initialize the Line_Table_Prefix_s struct. 
+   memset is not guaranteed a portable initializer, but works
+   fine for current architectures.   AFAIK.
+*/
+void
+dwarf_init_line_table_prefix(struct Line_Table_Prefix_s *pf)
+{
+    memset(pf, 0, sizeof(*pf));
+}
+
+/* Free any malloc'd area.  of the Line_Table_Prefix_s struct. */
+void
+dwarf_free_line_table_prefix(struct Line_Table_Prefix_s *pf)
+{
+    if (pf->pf_include_directories) {
+        free(pf->pf_include_directories);
+        pf->pf_include_directories = 0;
+    }
+    if (pf->pf_line_table_file_entries) {
+        free(pf->pf_line_table_file_entries);
+        pf->pf_line_table_file_entries = 0;
+    }
+    return;
+}
--- a/usr/src/tools/ctf/dwarf/common/dwarf_line.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_line.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000, 2004, 2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2009-2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +18,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -44,6 +45,12 @@
 */
 #define MAX_LINE_DIFF       UINT_MAX
 
+/* This is for a sanity check on line
+   table extended opcodes.
+   It is entirely arbitrary, and 100 is surely too small if
+   someone was inserting strings in the opcode. */
+#define DW_LNE_LEN_MAX   100
+
 
 /*
     This structure is used to build a list of all the
@@ -82,7 +89,11 @@
 struct Dwarf_Line_Context_s {
     /* 
        Points to a chain of entries providing info about source files
-       for the current set of Dwarf_Line structures. */
+       for the current set of Dwarf_Line structures. File number
+       'li_file 1' is last on the list, the first list entry is the
+       file numbered lc_file_entry_count. The numbering of the file
+       names matches the dwarf2/3 line table specification file table
+       and DW_LNE_define_file numbering rules.  */
     Dwarf_File_Entry lc_file_entries;
     /* 
        Count of number of source files for this set of Dwarf_Line
@@ -103,6 +114,9 @@
     Dwarf_Small *lc_compilation_directory;
 
     Dwarf_Debug lc_dbg;
+
+    Dwarf_Half lc_version_number;	/* DWARF2/3 version number, 2
+					   for DWARF2, 3 for DWARF3. */
 };
 
 
@@ -124,12 +138,27 @@
     union addr_or_line_s {
 	struct li_inner_s {
 	    Dwarf_Sword li_file;	/* int identifying src file */
+	    /* li_file is a number 1-N, indexing into a conceptual
+	       source file table as described in dwarf2/3 spec line
+	       table doc. (see Dwarf_File_Entry lc_file_entries; and
+	       Dwarf_Sword lc_file_entry_count;) */
+
 	    Dwarf_Sword li_line;	/* source file line number. */
 	    Dwarf_Half li_column;	/* source file column number */
-	    Dwarf_Small li_is_stmt;	/* indicate start of stmt */
-	    Dwarf_Small li_basic_block;	/* indicate start basic block */
-	    Dwarf_Small li_end_sequence;	/* first post sequence
-						   instr */
+	    Dwarf_Small li_isa;
+
+	    /* To save space, use bit flags. */
+	    /* indicate start of stmt */
+	    unsigned char li_is_stmt:1;
+
+	    /* indicate start basic block */
+	    unsigned char li_basic_block:1;
+
+	    /* first post sequence instr */
+	    unsigned char li_end_sequence:1;
+
+	    unsigned char li_prologue_end:1;
+	    unsigned char li_epilogue_begin:1;
 	} li_l_data;
 	Dwarf_Off li_offset;	/* for rqs */
     } li_addr_line;
@@ -137,13 +166,18 @@
 };
 
 
-int
-  _dwarf_line_address_offsets(Dwarf_Debug dbg,
-			      Dwarf_Die die,
-			      Dwarf_Addr ** addrs,
-			      Dwarf_Off ** offs,
-			      Dwarf_Unsigned * returncount,
-			      Dwarf_Error * err);
+int _dwarf_line_address_offsets(Dwarf_Debug dbg,
+				Dwarf_Die die,
+				Dwarf_Addr ** addrs,
+				Dwarf_Off ** offs,
+				Dwarf_Unsigned * returncount,
+				Dwarf_Error * err);
+int _dwarf_internal_srclines(Dwarf_Die die,
+			     Dwarf_Line ** linebuf,
+			     Dwarf_Signed * count,
+			     Dwarf_Bool doaddrs,
+			     Dwarf_Bool dolines, Dwarf_Error * error);
+
 
 
 /* The LOP, WHAT_IS_OPCODE stuff is here so it can
@@ -152,27 +186,27 @@
    a macro.
 
    Handling the line section where the header and the
-    file being process do not match (unusual, but
+   file being processed do not match (unusual, but
    planned for in the  design of .debug_line)
    is too tricky to recode this several times and keep
    it right.
+
+   As it is the code starting up line-reading is duplicated
+   and that is just wrong to do. FIXME!
 */
 #define LOP_EXTENDED 1
 #define LOP_DISCARD  2
 #define LOP_STANDARD 3
 #define LOP_SPECIAL  4
 
-#define HIGHEST_STANDARD_OPCODE  DW_LNS_fixed_advance_pc
-
-#define WHAT_IS_OPCODE(type,opcode,base,opcode_length,line_ptr) \
-        if( opcode < base ) {                              \
+#define WHAT_IS_OPCODE(type,opcode,base,opcode_length,line_ptr,highest_std) \
+        if( (opcode) < (base) ) {                          \
            /* we know we must treat as a standard op       \
                 or a special case.                         \
            */                                              \
-           if(opcode == DW_EXTENDED_OPCODE) {              \
+           if((opcode) == DW_EXTENDED_OPCODE) {            \
                 type = LOP_EXTENDED;                       \
-           } else  if( (HIGHEST_STANDARD_OPCODE+1) >=      \
-                        base) {                            \
+           } else  if( ((highest_std)+1) >=  (base)) {     \
                 /* == Standard case: compile of            \
                    dwarf_line.c and object                 \
                    have same standard op codes set.        \
@@ -196,23 +230,6 @@
                 ** out-of-date dwarf reader to read newer  \
                 ** line table data transparently.          \
                 */                                         \
-                int opcnt =  opcode_length[opcode];        \
-                int oc;                                    \
-                for(oc = 0; oc < opcnt; oc++)              \
-                  {                                         \
-                      /*                                    \
-                      ** Read and discard operands we don't \
-                      ** understand.                        \
-                      ** arbitrary choice of unsigned read. \
-                      ** signed read would work as well.    \
-                      */                                    \
-                      Dwarf_Unsigned utmp2;                 \
-                      DECODE_LEB128_UWORD(line_ptr, utmp2)  \
-                  }                                         \
-                /* Done processing this, do not             \
-                   do the switch , nor do                   \
-                   special op code processing.              \
-                */                                          \
                 type = LOP_DISCARD;                         \
            }                                                \
                                                             \
@@ -228,3 +245,87 @@
 */
 
 #define MAX_LINE_OP_CODE  255
+
+
+/* The following structs (Line_Table_File_Entry_s,Line_Table_Prefix_s)
+   and functions allow refactoring common code into a single
+   reader routine.
+*/
+/* There can be zero of more of these needed for 1 line prologue. */
+struct Line_Table_File_Entry_s {
+    Dwarf_Small *lte_filename;
+    Dwarf_Unsigned lte_directory_index;
+    Dwarf_Unsigned lte_last_modification_time;
+    Dwarf_Unsigned lte_length_of_file;
+};
+
+/* Data  picked up from the line table prologue for a single
+CU. */
+struct Line_Table_Prefix_s {
+
+    /* pf_total_length is the value of the length field for the line
+       table of this CU. So it does not count the length of itself (the 
+       length value) for consistency with the say lenghts recorded in
+       DWARF2/3. */
+    Dwarf_Unsigned pf_total_length;
+
+    /* Length of the initial length field itself. */
+    Dwarf_Half pf_length_field_length;
+
+    /* The version is 2 for DWARF2, 3 for DWARF3 */
+    Dwarf_Half pf_version;
+
+    Dwarf_Unsigned pf_prologue_length;
+    Dwarf_Small pf_minimum_instruction_length;
+
+    /* Start and end of this CU line area. pf_line_ptr_start +
+       pf_total_length + pf_length_field_length == pf_line_ptr_end.
+       Meaning pf_line_ptr_start is before the length info. */
+    Dwarf_Small *pf_line_ptr_start;
+    Dwarf_Small *pf_line_ptr_end;
+
+    /* Used to check that decoding of the line prologue is done right. */
+    Dwarf_Small *pf_line_prologue_start;
+
+    Dwarf_Small pf_default_is_stmt;
+    Dwarf_Sbyte pf_line_base;
+    Dwarf_Small pf_line_range;
+
+    /* Highest std opcode (+1).  */
+    Dwarf_Small pf_opcode_base;
+
+    /* pf_opcode_base -1 entries (each a count, normally the value of
+       each entry is 0 or 1). */
+    Dwarf_Small *pf_opcode_length_table;
+
+    Dwarf_Unsigned pf_include_directories_count;
+    /* Array of pointers to dir strings. pf_include_directories_count
+       entriesin the array. */
+    Dwarf_Small **pf_include_directories;
+
+    /* Count of entries in line_table_file_entries array. */
+    Dwarf_Unsigned pf_files_count;
+    struct Line_Table_File_Entry_s *pf_line_table_file_entries;
+
+    /* The number to treat as standard ops. This is a special
+       accomodation of gcc using the new standard opcodes but not
+       updating the version number. It's legal dwarf2, but much better
+       for the user to understand as dwarf3 when 'it looks ok'. */
+    Dwarf_Bool pf_std_op_count;
+
+};
+
+void dwarf_init_line_table_prefix(struct Line_Table_Prefix_s *pf);
+void dwarf_free_line_table_prefix(struct Line_Table_Prefix_s *pf);
+
+int dwarf_read_line_table_prefix(Dwarf_Debug dbg,
+    Dwarf_Small * data_start,
+    Dwarf_Unsigned data_length,
+    Dwarf_Small ** updated_data_start_out, 
+    struct Line_Table_Prefix_s *prefix_out,
+    /* The following 2 arguments are solely for warning users
+     * when there is a surprising 'gap' in the .debug_line info. */
+    Dwarf_Small ** bogus_bytes_ptr,
+    Dwarf_Unsigned * bogus_bytes_count,
+    Dwarf_Error * err,
+    int * err_count_out);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_line2.c	Sun May 22 03:13:22 2011 +0100
@@ -0,0 +1,110 @@
+/*
+
+  Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc. All Rights Reserved.
+  Portions Copyright 2008-2010 David Anderson, Inc. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+/* This source file used for SGI-IRIX rqs processing.
+   Unused otherwise.
+*/
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include "dwarf_line.h"
+
+/*
+        Return DW_DLV_OK or, if error,
+        DW_DLV_ERROR.
+
+        Thru pointers, return 2 arrays and a count
+        for rqs.
+*/
+int
+_dwarf_line_address_offsets(Dwarf_Debug dbg,
+                            Dwarf_Die die,
+                            Dwarf_Addr ** addrs,
+                            Dwarf_Off ** offs,
+                            Dwarf_Unsigned * returncount,
+                            Dwarf_Error * err)
+{
+    Dwarf_Addr *laddrs;
+    Dwarf_Off *loffsets;
+    Dwarf_Signed lcount;
+    Dwarf_Signed i;
+    int res;
+    Dwarf_Line *linebuf;
+
+    res = _dwarf_internal_srclines(die, &linebuf, &lcount,      /* addrlist= 
+                                                                 */ true,
+                                   /* linelist= */ false, err);
+    if (res != DW_DLV_OK) {
+        return res;
+    }
+    laddrs = (Dwarf_Addr *)
+        _dwarf_get_alloc(dbg, DW_DLA_ADDR, lcount);
+    if (laddrs == NULL) {
+        dwarf_srclines_dealloc(dbg, linebuf, lcount);
+        _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
+    }
+    loffsets = (Dwarf_Off *)
+        _dwarf_get_alloc(dbg, DW_DLA_ADDR, lcount);
+    if (loffsets == NULL) {
+        dwarf_srclines_dealloc(dbg, linebuf, lcount);
+        /* We already allocated what laddrs points at, so we'e better
+           deallocate that space since we are not going to return the
+           pointer to the caller. */
+        dwarf_dealloc(dbg, laddrs, DW_DLA_ADDR);
+        _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
+    }
+
+    for (i = 0; i < lcount; i++) {
+        laddrs[i] = linebuf[i]->li_address;
+        loffsets[i] = linebuf[i]->li_addr_line.li_offset;
+    }
+    dwarf_srclines_dealloc(dbg, linebuf, lcount);
+    *returncount = lcount;
+    *offs = loffsets;
+    *addrs = laddrs;
+    return DW_DLV_OK;
+}
+
+/*
+   It's impossible for callers of dwarf_srclines() to get to and
+   free all the resources (in particular, the li_context and its
+   lc_file_entries). 
+   So this function, new July 2005, does it.  
+*/
--- a/usr/src/tools/ctf/dwarf/common/dwarf_loc.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_loc.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000,2003 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -32,13 +33,20 @@
   http://oss.sgi.com/projects/GenInfo/NoticeExplan
 
 */
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
 
 
 
 #include "config.h"
 #include "dwarf_incl.h"
 #include "dwarf_loc.h"
-
+#include <stdio.h> /* for debugging only. */
+#include <sys/types.h>
 
 /*
     Given a Dwarf_Block that represents a location expression,
@@ -54,39 +62,43 @@
 */
 static Dwarf_Locdesc *
 _dwarf_get_locdesc(Dwarf_Debug dbg,
-		   Dwarf_Block * loc_block,
-		   Dwarf_Addr lowpc,
-		   Dwarf_Addr highpc, Dwarf_Error * error)
+    Dwarf_Block * loc_block,
+    Dwarf_Half address_size,
+    Dwarf_Addr lowpc,
+    Dwarf_Addr highpc, 
+    Dwarf_Error * error)
 {
     /* Size of the block containing the location expression. */
-    Dwarf_Unsigned loc_len;
+    Dwarf_Unsigned loc_len = 0;
 
     /* Sweeps the block containing the location expression. */
-    Dwarf_Small *loc_ptr;
+    Dwarf_Small *loc_ptr = 0;
 
     /* Current location operator. */
-    Dwarf_Small atom;
+    Dwarf_Small atom = 0;
 
     /* Offset of current operator from start of block. */
-    Dwarf_Unsigned offset;
+    Dwarf_Unsigned offset = 0;
 
     /* Operands of current location operator. */
     Dwarf_Unsigned operand1, operand2;
 
     /* Used to chain the Dwarf_Loc_Chain_s structs. */
-    Dwarf_Loc_Chain curr_loc, prev_loc, head_loc = NULL;
+    Dwarf_Loc_Chain curr_loc = NULL;
+    Dwarf_Loc_Chain prev_loc = NULL;
+    Dwarf_Loc_Chain head_loc = NULL;
 
     /* Count of the number of location operators. */
-    Dwarf_Unsigned op_count;
+    Dwarf_Unsigned op_count = 0;
 
     /* Contiguous block of Dwarf_Loc's for Dwarf_Locdesc. */
-    Dwarf_Loc *block_loc;
+    Dwarf_Loc *block_loc = 0;
 
     /* Dwarf_Locdesc pointer to be returned. */
-    Dwarf_Locdesc *locdesc;
+    Dwarf_Locdesc *locdesc = 0;
 
-    Dwarf_Word leb128_length;
-    Dwarf_Unsigned i;
+    Dwarf_Word leb128_length = 0;
+    Dwarf_Unsigned i = 0;
 
     /* ***** BEGIN CODE ***** */
 
@@ -97,341 +109,396 @@
     op_count = 0;
     while (offset < loc_len) {
 
-	operand1 = 0;
-	operand2 = 0;
-	op_count++;
+        operand1 = 0;
+        operand2 = 0;
+        op_count++;
 
-	atom = *(Dwarf_Small *) loc_ptr;
-	loc_ptr++;
-	offset++;
+        atom = *(Dwarf_Small *) loc_ptr;
+        loc_ptr++;
+        offset++;
 
-	curr_loc =
-	    (Dwarf_Loc_Chain) _dwarf_get_alloc(dbg, DW_DLA_LOC_CHAIN,
-					       1);
-	if (curr_loc == NULL) {
-	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	    return (NULL);
-	}
-	curr_loc->lc_offset = offset;
-	curr_loc->lc_atom = atom;
-	switch (atom) {
+        curr_loc =
+            (Dwarf_Loc_Chain) _dwarf_get_alloc(dbg, DW_DLA_LOC_CHAIN,
+                                               1);
+        if (curr_loc == NULL) {
+            _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+            return (NULL);
+        }
+        curr_loc->lc_offset = offset;
+        curr_loc->lc_atom = atom;
+        switch (atom) {
 
-	case DW_OP_reg0:
-	case DW_OP_reg1:
-	case DW_OP_reg2:
-	case DW_OP_reg3:
-	case DW_OP_reg4:
-	case DW_OP_reg5:
-	case DW_OP_reg6:
-	case DW_OP_reg7:
-	case DW_OP_reg8:
-	case DW_OP_reg9:
-	case DW_OP_reg10:
-	case DW_OP_reg11:
-	case DW_OP_reg12:
-	case DW_OP_reg13:
-	case DW_OP_reg14:
-	case DW_OP_reg15:
-	case DW_OP_reg16:
-	case DW_OP_reg17:
-	case DW_OP_reg18:
-	case DW_OP_reg19:
-	case DW_OP_reg20:
-	case DW_OP_reg21:
-	case DW_OP_reg22:
-	case DW_OP_reg23:
-	case DW_OP_reg24:
-	case DW_OP_reg25:
-	case DW_OP_reg26:
-	case DW_OP_reg27:
-	case DW_OP_reg28:
-	case DW_OP_reg29:
-	case DW_OP_reg30:
-	case DW_OP_reg31:
-	    break;
+        case DW_OP_reg0:
+        case DW_OP_reg1:
+        case DW_OP_reg2:
+        case DW_OP_reg3:
+        case DW_OP_reg4:
+        case DW_OP_reg5:
+        case DW_OP_reg6:
+        case DW_OP_reg7:
+        case DW_OP_reg8:
+        case DW_OP_reg9:
+        case DW_OP_reg10:
+        case DW_OP_reg11:
+        case DW_OP_reg12:
+        case DW_OP_reg13:
+        case DW_OP_reg14:
+        case DW_OP_reg15:
+        case DW_OP_reg16:
+        case DW_OP_reg17:
+        case DW_OP_reg18:
+        case DW_OP_reg19:
+        case DW_OP_reg20:
+        case DW_OP_reg21:
+        case DW_OP_reg22:
+        case DW_OP_reg23:
+        case DW_OP_reg24:
+        case DW_OP_reg25:
+        case DW_OP_reg26:
+        case DW_OP_reg27:
+        case DW_OP_reg28:
+        case DW_OP_reg29:
+        case DW_OP_reg30:
+        case DW_OP_reg31:
+            break;
 
-	case DW_OP_regx:
-	    operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
-	    loc_ptr = loc_ptr + leb128_length;
-	    offset = offset + leb128_length;
-	    break;
+        case DW_OP_regx:
+            operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
+            loc_ptr = loc_ptr + leb128_length;
+            offset = offset + leb128_length;
+            break;
 
-	case DW_OP_lit0:
-	case DW_OP_lit1:
-	case DW_OP_lit2:
-	case DW_OP_lit3:
-	case DW_OP_lit4:
-	case DW_OP_lit5:
-	case DW_OP_lit6:
-	case DW_OP_lit7:
-	case DW_OP_lit8:
-	case DW_OP_lit9:
-	case DW_OP_lit10:
-	case DW_OP_lit11:
-	case DW_OP_lit12:
-	case DW_OP_lit13:
-	case DW_OP_lit14:
-	case DW_OP_lit15:
-	case DW_OP_lit16:
-	case DW_OP_lit17:
-	case DW_OP_lit18:
-	case DW_OP_lit19:
-	case DW_OP_lit20:
-	case DW_OP_lit21:
-	case DW_OP_lit22:
-	case DW_OP_lit23:
-	case DW_OP_lit24:
-	case DW_OP_lit25:
-	case DW_OP_lit26:
-	case DW_OP_lit27:
-	case DW_OP_lit28:
-	case DW_OP_lit29:
-	case DW_OP_lit30:
-	case DW_OP_lit31:
-	    operand1 = atom - DW_OP_lit0;
-	    break;
+        case DW_OP_lit0:
+        case DW_OP_lit1:
+        case DW_OP_lit2:
+        case DW_OP_lit3:
+        case DW_OP_lit4:
+        case DW_OP_lit5:
+        case DW_OP_lit6:
+        case DW_OP_lit7:
+        case DW_OP_lit8:
+        case DW_OP_lit9:
+        case DW_OP_lit10:
+        case DW_OP_lit11:
+        case DW_OP_lit12:
+        case DW_OP_lit13:
+        case DW_OP_lit14:
+        case DW_OP_lit15:
+        case DW_OP_lit16:
+        case DW_OP_lit17:
+        case DW_OP_lit18:
+        case DW_OP_lit19:
+        case DW_OP_lit20:
+        case DW_OP_lit21:
+        case DW_OP_lit22:
+        case DW_OP_lit23:
+        case DW_OP_lit24:
+        case DW_OP_lit25:
+        case DW_OP_lit26:
+        case DW_OP_lit27:
+        case DW_OP_lit28:
+        case DW_OP_lit29:
+        case DW_OP_lit30:
+        case DW_OP_lit31:
+            operand1 = atom - DW_OP_lit0;
+            break;
 
-	case DW_OP_addr:
-	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned,
-			   loc_ptr, dbg->de_pointer_size);
-	    loc_ptr += dbg->de_pointer_size;
-	    offset += dbg->de_pointer_size;
-	    break;
+        case DW_OP_addr:
+            READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned,
+                           loc_ptr, address_size);
+            loc_ptr += address_size;
+            offset += address_size;
+            break;
+
+        case DW_OP_const1u:
+            operand1 = *(Dwarf_Small *) loc_ptr;
+            loc_ptr = loc_ptr + 1;
+            offset = offset + 1;
+            break;
+
+        case DW_OP_const1s:
+            operand1 = *(Dwarf_Sbyte *) loc_ptr;
+            SIGN_EXTEND(operand1,1);
+            loc_ptr = loc_ptr + 1;
+            offset = offset + 1;
+            break;
 
-	case DW_OP_const1u:
-	    operand1 = *(Dwarf_Small *) loc_ptr;
-	    loc_ptr = loc_ptr + 1;
-	    offset = offset + 1;
-	    break;
+        case DW_OP_const2u:
+            READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
+            loc_ptr = loc_ptr + 2;
+            offset = offset + 2;
+            break;
 
-	case DW_OP_const1s:
-	    operand1 = *(Dwarf_Sbyte *) loc_ptr;
-	    loc_ptr = loc_ptr + 1;
-	    offset = offset + 1;
-	    break;
+        case DW_OP_const2s:
+            READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
+            SIGN_EXTEND(operand1,2);
+            loc_ptr = loc_ptr + 2;
+            offset = offset + 2;
+            break;
 
-	case DW_OP_const2u:
-	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
-	    loc_ptr = loc_ptr + 2;
-	    offset = offset + 2;
-	    break;
+        case DW_OP_const4u:
+            READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
+            loc_ptr = loc_ptr + 4;
+            offset = offset + 4;
+            break;
 
-	case DW_OP_const2s:
-	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
-	    loc_ptr = loc_ptr + 2;
-	    offset = offset + 2;
-	    break;
+        case DW_OP_const4s:
+            READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
+            SIGN_EXTEND(operand1,4);
+            loc_ptr = loc_ptr + 4;
+            offset = offset + 4;
+            break;
 
-	case DW_OP_const4u:
-	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
-	    loc_ptr = loc_ptr + 4;
-	    offset = offset + 4;
-	    break;
+        case DW_OP_const8u:
+            READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8);
+            loc_ptr = loc_ptr + 8;
+            offset = offset + 8;
+            break;
 
-	case DW_OP_const4s:
-	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
-	    loc_ptr = loc_ptr + 4;
-	    offset = offset + 4;
-	    break;
+        case DW_OP_const8s:
+            READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8);
+            loc_ptr = loc_ptr + 8;
+            offset = offset + 8;
+            break;
 
-	case DW_OP_const8u:
-	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8);
-	    loc_ptr = loc_ptr + 8;
-	    offset = offset + 8;
-	    break;
+        case DW_OP_constu:
+            operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
+            loc_ptr = loc_ptr + leb128_length;
+            offset = offset + leb128_length;
+            break;
 
-	case DW_OP_const8s:
-	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8);
-	    loc_ptr = loc_ptr + 8;
-	    offset = offset + 8;
-	    break;
+        case DW_OP_consts:
+            operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
+            loc_ptr = loc_ptr + leb128_length;
+            offset = offset + leb128_length;
+            break;
+
+        case DW_OP_fbreg:
+            operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
+            loc_ptr = loc_ptr + leb128_length;
+            offset = offset + leb128_length;
+            break;
 
-	case DW_OP_constu:
-	    operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
-	    loc_ptr = loc_ptr + leb128_length;
-	    offset = offset + leb128_length;
-	    break;
-
-	case DW_OP_consts:
-	    operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
-	    loc_ptr = loc_ptr + leb128_length;
-	    offset = offset + leb128_length;
-	    break;
-
-	case DW_OP_fbreg:
-	    operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
-	    loc_ptr = loc_ptr + leb128_length;
-	    offset = offset + leb128_length;
-	    break;
+        case DW_OP_breg0:
+        case DW_OP_breg1:
+        case DW_OP_breg2:
+        case DW_OP_breg3:
+        case DW_OP_breg4:
+        case DW_OP_breg5:
+        case DW_OP_breg6:
+        case DW_OP_breg7:
+        case DW_OP_breg8:
+        case DW_OP_breg9:
+        case DW_OP_breg10:
+        case DW_OP_breg11:
+        case DW_OP_breg12:
+        case DW_OP_breg13:
+        case DW_OP_breg14:
+        case DW_OP_breg15:
+        case DW_OP_breg16:
+        case DW_OP_breg17:
+        case DW_OP_breg18:
+        case DW_OP_breg19:
+        case DW_OP_breg20:
+        case DW_OP_breg21:
+        case DW_OP_breg22:
+        case DW_OP_breg23:
+        case DW_OP_breg24:
+        case DW_OP_breg25:
+        case DW_OP_breg26:
+        case DW_OP_breg27:
+        case DW_OP_breg28:
+        case DW_OP_breg29:
+        case DW_OP_breg30:
+        case DW_OP_breg31:
+            operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
+            loc_ptr = loc_ptr + leb128_length;
+            offset = offset + leb128_length;
+            break;
 
-	case DW_OP_breg0:
-	case DW_OP_breg1:
-	case DW_OP_breg2:
-	case DW_OP_breg3:
-	case DW_OP_breg4:
-	case DW_OP_breg5:
-	case DW_OP_breg6:
-	case DW_OP_breg7:
-	case DW_OP_breg8:
-	case DW_OP_breg9:
-	case DW_OP_breg10:
-	case DW_OP_breg11:
-	case DW_OP_breg12:
-	case DW_OP_breg13:
-	case DW_OP_breg14:
-	case DW_OP_breg15:
-	case DW_OP_breg16:
-	case DW_OP_breg17:
-	case DW_OP_breg18:
-	case DW_OP_breg19:
-	case DW_OP_breg20:
-	case DW_OP_breg21:
-	case DW_OP_breg22:
-	case DW_OP_breg23:
-	case DW_OP_breg24:
-	case DW_OP_breg25:
-	case DW_OP_breg26:
-	case DW_OP_breg27:
-	case DW_OP_breg28:
-	case DW_OP_breg29:
-	case DW_OP_breg30:
-	case DW_OP_breg31:
-	    operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
-	    loc_ptr = loc_ptr + leb128_length;
-	    offset = offset + leb128_length;
-	    break;
+        case DW_OP_bregx:
+            /* uleb reg num followed by sleb offset */
+            operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
+            loc_ptr = loc_ptr + leb128_length;
+            offset = offset + leb128_length;
+
+            operand2 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
+            loc_ptr = loc_ptr + leb128_length;
+            offset = offset + leb128_length;
+            break;
+
+        case DW_OP_dup:
+        case DW_OP_drop:
+            break;
+
+        case DW_OP_pick:
+            operand1 = *(Dwarf_Small *) loc_ptr;
+            loc_ptr = loc_ptr + 1;
+            offset = offset + 1;
+            break;
 
-	case DW_OP_bregx:
-	    /* uleb reg num followed by sleb offset */
-	    operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
-	    loc_ptr = loc_ptr + leb128_length;
-	    offset = offset + leb128_length;
+        case DW_OP_over:
+        case DW_OP_swap:
+        case DW_OP_rot:
+        case DW_OP_deref:
+            break;
 
-	    operand2 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
-	    loc_ptr = loc_ptr + leb128_length;
-	    offset = offset + leb128_length;
-	    break;
+        case DW_OP_deref_size:
+            operand1 = *(Dwarf_Small *) loc_ptr;
+            loc_ptr = loc_ptr + 1;
+            offset = offset + 1;
+            break;
 
-	case DW_OP_dup:
-	case DW_OP_drop:
-	    break;
+        case DW_OP_xderef:
+            break;
+
+        case DW_OP_xderef_size:
+            operand1 = *(Dwarf_Small *) loc_ptr;
+            loc_ptr = loc_ptr + 1;
+            offset = offset + 1;
+            break;
 
-	case DW_OP_pick:
-	    operand1 = *(Dwarf_Small *) loc_ptr;
-	    loc_ptr = loc_ptr + 1;
-	    offset = offset + 1;
-	    break;
+        case DW_OP_abs:
+        case DW_OP_and:
+        case DW_OP_div:
+        case DW_OP_minus:
+        case DW_OP_mod:
+        case DW_OP_mul:
+        case DW_OP_neg:
+        case DW_OP_not:
+        case DW_OP_or:
+        case DW_OP_plus:
+            break;
 
-	case DW_OP_over:
-	case DW_OP_swap:
-	case DW_OP_rot:
-	case DW_OP_deref:
-	    break;
-
-	case DW_OP_deref_size:
-	    operand1 = *(Dwarf_Small *) loc_ptr;
-	    loc_ptr = loc_ptr + 1;
-	    offset = offset + 1;
-	    break;
+        case DW_OP_plus_uconst:
+            operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
+            loc_ptr = loc_ptr + leb128_length;
+            offset = offset + leb128_length;
+            break;
 
-	case DW_OP_xderef:
-	    break;
-
-	case DW_OP_xderef_size:
-	    operand1 = *(Dwarf_Small *) loc_ptr;
-	    loc_ptr = loc_ptr + 1;
-	    offset = offset + 1;
-	    break;
+        case DW_OP_shl:
+        case DW_OP_shr:
+        case DW_OP_shra:
+        case DW_OP_xor:
+            break;
 
-	case DW_OP_abs:
-	case DW_OP_and:
-	case DW_OP_div:
-	case DW_OP_minus:
-	case DW_OP_mod:
-	case DW_OP_mul:
-	case DW_OP_neg:
-	case DW_OP_not:
-	case DW_OP_or:
-	case DW_OP_plus:
-	    break;
+        case DW_OP_le:
+        case DW_OP_ge:
+        case DW_OP_eq:
+        case DW_OP_lt:
+        case DW_OP_gt:
+        case DW_OP_ne:
+            break;
+
+        case DW_OP_skip:
+        case DW_OP_bra:
+            READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
+            loc_ptr = loc_ptr + 2;
+            offset = offset + 2;
+            break;
+
+        case DW_OP_piece:
+            operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
+            loc_ptr = loc_ptr + leb128_length;
+            offset = offset + leb128_length;
+            break;
 
-	case DW_OP_plus_uconst:
-	    operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
-	    loc_ptr = loc_ptr + leb128_length;
-	    offset = offset + leb128_length;
-	    break;
+        case DW_OP_nop:
+            break;
+        case DW_OP_push_object_address: /* DWARF3 */
+            break;
+        case DW_OP_call2:       /* DWARF3 */
+            READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
+            loc_ptr = loc_ptr + 2;
+            offset = offset + 2;
+            break;
 
-	case DW_OP_shl:
-	case DW_OP_shr:
-	case DW_OP_shra:
-	case DW_OP_xor:
-	    break;
-
-	case DW_OP_le:
-	case DW_OP_ge:
-	case DW_OP_eq:
-	case DW_OP_lt:
-	case DW_OP_gt:
-	case DW_OP_ne:
-	    break;
+        case DW_OP_call4:       /* DWARF3 */
+            READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
+            loc_ptr = loc_ptr + 4;
+            offset = offset + 4;
+            break;
+        case DW_OP_call_ref:    /* DWARF3 */
+            READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr,
+                           dbg->de_length_size);
+            loc_ptr = loc_ptr + dbg->de_length_size;
+            offset = offset + dbg->de_length_size;
+            break;
 
-	case DW_OP_skip:
-	case DW_OP_bra:
-	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
-	    loc_ptr = loc_ptr + 2;
-	    offset = offset + 2;
-	    break;
+        case DW_OP_form_tls_address:    /* DWARF3f */
+            break;
+        case DW_OP_call_frame_cfa:      /* DWARF3f */
+            break;
+        case DW_OP_bit_piece:   /* DWARF3f */
+            /* uleb size in bits followed by uleb offset in bits */
+            operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
+            loc_ptr = loc_ptr + leb128_length;
+            offset = offset + leb128_length;
 
-	case DW_OP_piece:
-	    operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
-	    loc_ptr = loc_ptr + leb128_length;
-	    offset = offset + leb128_length;
-	    break;
+            operand2 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
+            loc_ptr = loc_ptr + leb128_length;
+            offset = offset + leb128_length;
+            break;
+        case DW_OP_implicit_value: /* DWARF4 */
+            /* uleb length of value bytes followed by that
+               number of bytes of the value. */
+            operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
+            loc_ptr = loc_ptr + leb128_length;
+            offset = offset + leb128_length;
 
-	case DW_OP_nop:
-	    break;
-
-	default:
-	    _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
-	    return (NULL);
-	}
+            /* Second operand is block of 'operand1' bytes of stuff. */
+            /* This using the second operand as a pointer
+               is quite ugly. */
+            /* This gets an ugly compiler warning. Sorry. */
+            operand2 = (Dwarf_Unsigned)(uintptr_t)loc_ptr; 
+            offset = offset + operand1;
+            loc_ptr = loc_ptr + operand1;
+            break;
+        case DW_OP_stack_value:  /* DWARF4 */
+            break;
 
 
-	curr_loc->lc_number = operand1;
-	curr_loc->lc_number2 = operand2;
+        default:
+            _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
+            return (NULL);
+        }
+
 
-	if (head_loc == NULL)
-	    head_loc = prev_loc = curr_loc;
-	else {
-	    prev_loc->lc_next = curr_loc;
-	    prev_loc = curr_loc;
-	}
+        curr_loc->lc_number = operand1;
+        curr_loc->lc_number2 = operand2;
+
+        if (head_loc == NULL)
+            head_loc = prev_loc = curr_loc;
+        else {
+            prev_loc->lc_next = curr_loc;
+            prev_loc = curr_loc;
+        }
     }
 
     block_loc =
-	(Dwarf_Loc *) _dwarf_get_alloc(dbg, DW_DLA_LOC_BLOCK, op_count);
+        (Dwarf_Loc *) _dwarf_get_alloc(dbg, DW_DLA_LOC_BLOCK, op_count);
     if (block_loc == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (NULL);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (NULL);
     }
 
     curr_loc = head_loc;
     for (i = 0; i < op_count; i++) {
-	(block_loc + i)->lr_atom = curr_loc->lc_atom;
-	(block_loc + i)->lr_number = curr_loc->lc_number;
-	(block_loc + i)->lr_number2 = curr_loc->lc_number2;
-	(block_loc + i)->lr_offset = curr_loc->lc_offset;
+        (block_loc + i)->lr_atom = curr_loc->lc_atom;
+        (block_loc + i)->lr_number = curr_loc->lc_number;
+        (block_loc + i)->lr_number2 = curr_loc->lc_number2;
+        (block_loc + i)->lr_offset = curr_loc->lc_offset;
 
-	prev_loc = curr_loc;
-	curr_loc = curr_loc->lc_next;
-	dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN);
+        prev_loc = curr_loc;
+        curr_loc = curr_loc->lc_next;
+        dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN);
     }
 
     locdesc =
-	(Dwarf_Locdesc *) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC, 1);
+        (Dwarf_Locdesc *) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC, 1);
     if (locdesc == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (NULL);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (NULL);
     }
 
     locdesc->ld_cents = op_count;
@@ -453,52 +520,53 @@
 
 static int
 _dwarf_read_loc_section(Dwarf_Debug dbg,
-			Dwarf_Block * return_block,
-			Dwarf_Addr * lowpc, Dwarf_Addr * hipc,
-			Dwarf_Off sec_offset, Dwarf_Error * error)
+                        Dwarf_Block * return_block,
+                        Dwarf_Addr * lowpc, Dwarf_Addr * hipc,
+                        Dwarf_Off sec_offset, 
+                        Dwarf_Half address_size, 
+                        Dwarf_Error * error)
 {
-    Dwarf_Small *beg = dbg->de_debug_loc + sec_offset;
-    int address_size = dbg->de_pointer_size;
+    Dwarf_Small *beg = dbg->de_debug_loc.dss_data + sec_offset;
 
     Dwarf_Addr start_addr = 0;
     Dwarf_Addr end_addr = 0;
     Dwarf_Half exprblock_size = 0;
     Dwarf_Unsigned exprblock_off =
-	2 * address_size + sizeof(Dwarf_Half);
+        2 * address_size + sizeof(Dwarf_Half);
 
-    if (sec_offset >= dbg->de_debug_loc_size) {
-	/* We're at the end. No more present. */
-	return DW_DLV_NO_ENTRY;
+    if (sec_offset >= dbg->de_debug_loc.dss_size) {
+        /* We're at the end. No more present. */
+        return DW_DLV_NO_ENTRY;
     }
 
     /* If it goes past end, error */
-    if (exprblock_off > dbg->de_debug_loc_size) {
-	_dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
-	return DW_DLV_ERROR;
+    if (exprblock_off > dbg->de_debug_loc.dss_size) {
+        _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
+        return DW_DLV_ERROR;
     }
 
     READ_UNALIGNED(dbg, start_addr, Dwarf_Addr, beg, address_size);
     READ_UNALIGNED(dbg, end_addr, Dwarf_Addr,
-		   beg + address_size, address_size);
+                   beg + address_size, address_size);
     if (start_addr == 0 && end_addr == 0) {
-	/* If start_addr and end_addr are 0, it's the end and no
-	   exprblock_size field follows. */
-	exprblock_size = 0;
-	exprblock_off -= sizeof(Dwarf_Half);
+        /* If start_addr and end_addr are 0, it's the end and no
+           exprblock_size field follows. */
+        exprblock_size = 0;
+        exprblock_off -= sizeof(Dwarf_Half);
     } else if (start_addr == MAX_ADDR) {
-	/* end address is a base address, no exprblock_size field here
-	   either */
-	exprblock_size = 0;
-	exprblock_off -= sizeof(Dwarf_Half);
+        /* end address is a base address, no exprblock_size field here
+           either */
+        exprblock_size = 0;
+        exprblock_off -= sizeof(Dwarf_Half);
     } else {
 
-	READ_UNALIGNED(dbg, exprblock_size, Dwarf_Half,
-		       beg + 2 * address_size, sizeof(Dwarf_Half));
-	/* exprblock_size can be zero, means no expression */
-	if ((exprblock_off + exprblock_size) > dbg->de_debug_loc_size) {
-	    _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
-	    return DW_DLV_ERROR;
-	}
+        READ_UNALIGNED(dbg, exprblock_size, Dwarf_Half,
+                       beg + 2 * address_size, sizeof(Dwarf_Half));
+        /* exprblock_size can be zero, means no expression */
+        if ((exprblock_off + exprblock_size) > dbg->de_debug_loc.dss_size) {
+            _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
+            return DW_DLV_ERROR;
+        }
     }
 #undef MAX_ADDR
     *lowpc = start_addr;
@@ -508,37 +576,37 @@
     return_block->bl_from_loclist = 1;
     return_block->bl_data = beg + exprblock_off;
     return_block->bl_section_offset =
-	((Dwarf_Small *) return_block->bl_data) - dbg->de_debug_loc;
+        ((Dwarf_Small *) return_block->bl_data) - dbg->de_debug_loc.dss_data;
 
     return DW_DLV_OK;
 
 }
 static int
 _dwarf_get_loclist_count(Dwarf_Debug dbg,
-			 Dwarf_Off loclist_offset,
-			 int *loclist_count, Dwarf_Error * error)
+                         Dwarf_Off loclist_offset,
+                         Dwarf_Half address_size,
+                         int *loclist_count, Dwarf_Error * error)
 {
     int count = 0;
     Dwarf_Off offset = loclist_offset;
 
 
     for (;;) {
-	Dwarf_Block b;
-	Dwarf_Addr lowpc;
-	Dwarf_Addr highpc;
-	int res = _dwarf_read_loc_section(dbg, &b,
-
-					  &lowpc, &highpc,
-					  offset, error);
+        Dwarf_Block b;
+        Dwarf_Addr lowpc;
+        Dwarf_Addr highpc;
+        int res = _dwarf_read_loc_section(dbg, &b,
+                  &lowpc, &highpc,
+                  offset, address_size,error);
 
-	if (res != DW_DLV_OK) {
-	    return res;
-	}
-	offset = b.bl_len + b.bl_section_offset;
-	if (lowpc == 0 && highpc == 0) {
-	    break;
-	}
-	count++;
+        if (res != DW_DLV_OK) {
+            return res;
+        }
+        offset = b.bl_len + b.bl_section_offset;
+        if (lowpc == 0 && highpc == 0) {
+            break;
+        }
+        count++;
     }
     *loclist_count = count;
     return DW_DLV_OK;
@@ -548,35 +616,36 @@
 */
 static int
 _dwarf_setup_loc(Dwarf_Attribute attr,
-		 Dwarf_Debug * dbg_ret,
-		 Dwarf_Half * form_ret, Dwarf_Error * error)
+                 Dwarf_Debug * dbg_ret,
+                 Dwarf_CU_Context *cucontext_ret,
+                 Dwarf_Half * form_ret, Dwarf_Error * error)
 {
     Dwarf_Debug dbg = 0;
     Dwarf_Half form = 0;
-    int blkres;
+    int blkres = DW_DLV_ERROR;
 
     if (attr == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+        return (DW_DLV_ERROR);
     }
     if (attr->ar_cu_context == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+        return (DW_DLV_ERROR);
     }
+    *cucontext_ret = attr->ar_cu_context;
 
     dbg = attr->ar_cu_context->cc_dbg;
     if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
     *dbg_ret = dbg;
     blkres = dwarf_whatform(attr, &form, error);
     if (blkres != DW_DLV_OK) {
-	_dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
-	return blkres;
+        _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
+        return blkres;
     }
     *form_ret = form;
-
     return DW_DLV_OK;
 }
 
@@ -584,24 +653,20 @@
 */
 static int
 _dwarf_get_loclist_header_start(Dwarf_Debug dbg,
-				Dwarf_Attribute attr,
-				Dwarf_Unsigned * loclist_offset,
-				Dwarf_Error * error)
+                                Dwarf_Attribute attr,
+                                Dwarf_Unsigned * loclist_offset,
+                                Dwarf_Error * error)
 {
-    int secload = 0;
     int blkres = dwarf_formudata(attr, loclist_offset, error);
-
     if (blkres != DW_DLV_OK) {
-	return (blkres);
+        return (blkres);
     }
 
-    if (!dbg->de_debug_loc) {
-	secload = _dwarf_load_section(dbg,
-				      dbg->de_debug_loc_index,
-				      &dbg->de_debug_loc, error);
-	if (secload != DW_DLV_OK) {
-	    return secload;
-	}
+    if (!dbg->de_debug_loc.dss_data) {
+        int secload = _dwarf_load_section(dbg, &dbg->de_debug_loc,error);
+        if (secload != DW_DLV_OK) {
+            return secload;
+        }
     }
     return DW_DLV_OK;
 }
@@ -614,23 +679,22 @@
 _dwarf_cleanup_llbuf(Dwarf_Debug dbg, Dwarf_Locdesc ** llbuf, int count)
 {
     int i;
-
     for (i = 0; i < count; ++i) {
-	dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK);
-	dwarf_dealloc(dbg, llbuf[i], DW_DLA_LOCDESC);
+        dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK);
+        dwarf_dealloc(dbg, llbuf[i], DW_DLA_LOCDESC);
     }
     dwarf_dealloc(dbg, llbuf, DW_DLA_LIST);
 }
 
 /* 
-	Handles simple location entries and loclists.
-	Returns all the Locdesc's thru llbuf. 
-	
+        Handles simple location entries and loclists.
+        Returns all the Locdesc's thru llbuf. 
+        
 */
 int
 dwarf_loclist_n(Dwarf_Attribute attr,
-		Dwarf_Locdesc *** llbuf_out,
-		Dwarf_Signed * listlen_out, Dwarf_Error * error)
+                Dwarf_Locdesc *** llbuf_out,
+                Dwarf_Signed * listlen_out, Dwarf_Error * error)
 {
     Dwarf_Debug dbg;
 
@@ -650,110 +714,123 @@
     Dwarf_Addr highpc = 0;
     Dwarf_Signed listlen = 0;
     Dwarf_Locdesc **llbuf = 0;
+    Dwarf_CU_Context cucontext = 0;
+    unsigned address_size = 0;
 
-    int blkres;
-    int setup_res;
+    int blkres = DW_DLV_ERROR;
+    int setup_res = DW_DLV_ERROR;
 
     /* ***** BEGIN CODE ***** */
-    setup_res = _dwarf_setup_loc(attr, &dbg, &form, error);
+    setup_res = _dwarf_setup_loc(attr, &dbg,&cucontext, &form, error);
     if (setup_res != DW_DLV_OK) {
-	return setup_res;
+        return setup_res;
     }
+    address_size = cucontext->cc_address_size;
     /* If this is a form_block then it's a location expression. If it's 
        DW_FORM_data4 or DW_FORM_data8 it's a loclist offset */
-    if (form == DW_FORM_data4 || form == DW_FORM_data8) {
+    if (((cucontext->cc_version_stamp == CURRENT_VERSION_STAMP ||
+          cucontext->cc_version_stamp == CURRENT_VERSION_STAMP3) &&
+          (form == DW_FORM_data4 || form == DW_FORM_data8)) ||
+         (cucontext->cc_version_stamp == CURRENT_VERSION_STAMP4 &&
+            form == DW_FORM_sec_offset))
+        {
+
 
-	/* A reference to .debug_loc, with an offset in .debug_loc of a 
-	   loclist */
-	Dwarf_Unsigned loclist_offset = 0;
-	int off_res;
-	int count_res;
-	int loclist_count;
-	int lli;
+        /* A reference to .debug_loc, with an offset in .debug_loc of a 
+           loclist */
+        Dwarf_Unsigned loclist_offset = 0;
+        int off_res  = DW_DLV_ERROR;
+        int count_res = DW_DLV_ERROR;
+        int loclist_count;
+        int lli;
 
-	off_res = _dwarf_get_loclist_header_start(dbg,
-						  attr, &loclist_offset,
-						  error);
-	if (off_res != DW_DLV_OK) {
-	    return off_res;
-	}
-	count_res = _dwarf_get_loclist_count(dbg, loclist_offset,
-					     &loclist_count, error);
-	listlen = loclist_count;
-	if (count_res != DW_DLV_OK) {
-	    return count_res;
-	}
-	if (loclist_count == 0) {
-	    return DW_DLV_NO_ENTRY;
-	}
+        off_res = _dwarf_get_loclist_header_start(dbg,
+                                                  attr, &loclist_offset,
+                                                  error);
+        if (off_res != DW_DLV_OK) {
+            return off_res;
+        }
+        count_res = _dwarf_get_loclist_count(dbg, loclist_offset,
+                                             address_size,
+                                             &loclist_count, error);
+        listlen = loclist_count;
+        if (count_res != DW_DLV_OK) {
+            return count_res;
+        }
+        if (loclist_count == 0) {
+            return DW_DLV_NO_ENTRY;
+        }
 
-	llbuf = (Dwarf_Locdesc **)
-	    _dwarf_get_alloc(dbg, DW_DLA_LIST, loclist_count);
-	if (!llbuf) {
-	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	    return (DW_DLV_ERROR);
-	}
+        llbuf = (Dwarf_Locdesc **)
+            _dwarf_get_alloc(dbg, DW_DLA_LIST, loclist_count);
+        if (!llbuf) {
+            _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+            return (DW_DLV_ERROR);
+        }
 
-	for (lli = 0; lli < loclist_count; ++lli) {
-	    blkres = _dwarf_read_loc_section(dbg, &loc_block,
-					     &lowpc,
-					     &highpc,
-					     loclist_offset, error);
-	    if (blkres != DW_DLV_OK) {
-		_dwarf_cleanup_llbuf(dbg, llbuf, lli);
-		return (blkres);
-	    }
-	    locdesc = _dwarf_get_locdesc(dbg, &loc_block,
-					 lowpc, highpc, error);
-	    if (locdesc == NULL) {
-		_dwarf_cleanup_llbuf(dbg, llbuf, lli);
-		/* low level error already set: let it be passed back */
-		return (DW_DLV_ERROR);
-	    }
-	    llbuf[lli] = locdesc;
+        for (lli = 0; lli < loclist_count; ++lli) {
+            blkres = _dwarf_read_loc_section(dbg, &loc_block,
+                &lowpc,
+                &highpc,
+                loclist_offset, 
+                address_size,
+                error);
+            if (blkres != DW_DLV_OK) {
+                _dwarf_cleanup_llbuf(dbg, llbuf, lli);
+                return (blkres);
+            }
+            locdesc = _dwarf_get_locdesc(dbg, &loc_block,
+                address_size,
+                lowpc, highpc, error);
+            if (locdesc == NULL) {
+                _dwarf_cleanup_llbuf(dbg, llbuf, lli);
+                /* low level error already set: let it be passed back */
+                return (DW_DLV_ERROR);
+            }
+            llbuf[lli] = locdesc;
 
-	    /* Now get to next loclist entry offset. */
-	    loclist_offset = loc_block.bl_section_offset +
-		loc_block.bl_len;
-	}
+            /* Now get to next loclist entry offset. */
+            loclist_offset = loc_block.bl_section_offset +
+                loc_block.bl_len;
+        }
 
 
     } else {
-	Dwarf_Block *tblock = 0;
+        Dwarf_Block *tblock = 0;
 
-	blkres = dwarf_formblock(loc_attr, &tblock, error);
-	if (blkres != DW_DLV_OK) {
-	    return (blkres);
-	}
-	loc_block = *tblock;
-	/* We copied tblock contents to the stack var, so can dealloc
-	   tblock now.  Avoids leaks. */
-	dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
-	listlen = 1;		/* One by definition of a location
-				   entry. */
-	lowpc = 0;		/* HACK */
-	highpc = (Dwarf_Unsigned) (-1LL);	/* HACK */
+        blkres = dwarf_formblock(loc_attr, &tblock, error);
+        if (blkres != DW_DLV_OK) {
+            return (blkres);
+        }
+        loc_block = *tblock;
+        /* We copied tblock contents to the stack var, so can dealloc
+           tblock now.  Avoids leaks. */
+        dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
+        listlen = 1; /* One by definition of a location entry. */
+        lowpc = 0;   /* HACK */
+        highpc = (Dwarf_Unsigned) (-1LL); /* HACK */
 
-	/* An empty location description (block length 0) means the
-	   code generator emitted no variable, the variable was not
-	   generated, it was unused or perhaps never tested after being 
-	   set. Dwarf2, section 2.4.1 In other words, it is not an
-	   error, and we don't test for block length 0 specially here. */
-	locdesc = _dwarf_get_locdesc(dbg, &loc_block,
-				     lowpc, highpc, error);
-	if (locdesc == NULL) {
-	    /* low level error already set: let it be passed back */
-	    return (DW_DLV_ERROR);
-	}
-	llbuf = (Dwarf_Locdesc **)
-	    _dwarf_get_alloc(dbg, DW_DLA_LIST, listlen);
-	if (!llbuf) {
-	    /* Free the locdesc we allocated but won't use. */
-	    dwarf_dealloc(dbg, locdesc, DW_DLA_LOCDESC);
-	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	    return (DW_DLV_ERROR);
-	}
-	llbuf[0] = locdesc;
+        /* An empty location description (block length 0) means the
+           code generator emitted no variable, the variable was not
+           generated, it was unused or perhaps never tested after being 
+           set. Dwarf2, section 2.4.1 In other words, it is not an
+           error, and we don't test for block length 0 specially here. */
+        locdesc = _dwarf_get_locdesc(dbg, &loc_block,
+            address_size,
+            lowpc, highpc, error);
+        if (locdesc == NULL) {
+            /* low level error already set: let it be passed back */
+            return (DW_DLV_ERROR);
+        }
+        llbuf = (Dwarf_Locdesc **)
+            _dwarf_get_alloc(dbg, DW_DLA_LIST, listlen);
+        if (!llbuf) {
+            /* Free the locdesc we allocated but won't use. */
+            dwarf_dealloc(dbg, locdesc, DW_DLA_LOCDESC);
+            _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+            return (DW_DLV_ERROR);
+        }
+        llbuf[0] = locdesc;
     }
 
     *llbuf_out = llbuf;
@@ -761,27 +838,27 @@
     return (DW_DLV_OK);
 }
 
+
 /* 
-	Handles only a location expression.
-	If called on a loclist, just returns one of those.
-	Cannot not handle a real loclist. 
- 	It returns the location expression as a loclist with
-	a single entry.
-	See dwarf_loclist_n() which handles any number
+        Handles only a location expression.
+        If called on a loclist, just returns one of those.
+        Cannot not handle a real loclist. 
+        It returns the location expression as a loclist with
+        a single entry.
+        See dwarf_loclist_n() which handles any number
         of location list entries.
 
-	This is the original definition, and it simply
-	does not work for loclists. Kept for compatibility.
+        This is the original definition, and it simply
+        does not work for loclists. Kept for compatibility.
 */
 int
 dwarf_loclist(Dwarf_Attribute attr,
-	      Dwarf_Locdesc ** llbuf,
-	      Dwarf_Signed * listlen, Dwarf_Error * error)
+    Dwarf_Locdesc ** llbuf,
+    Dwarf_Signed * listlen, Dwarf_Error * error)
 {
     Dwarf_Debug dbg;
 
-    /* 
-       Dwarf_Attribute that describes the DW_AT_location in die, if
+    /* Dwarf_Attribute that describes the DW_AT_location in die, if
        present. */
     Dwarf_Attribute loc_attr = attr;
 
@@ -794,68 +871,151 @@
     Dwarf_Half form = 0;
     Dwarf_Addr lowpc = 0;
     Dwarf_Addr highpc = 0;
+    Dwarf_CU_Context cucontext = 0;
+    unsigned address_size = 0;
 
-    int blkres;
-    int setup_res;
+    int blkres = DW_DLV_ERROR;
+    int setup_res = DW_DLV_ERROR;
 
     /* ***** BEGIN CODE ***** */
-    setup_res = _dwarf_setup_loc(attr, &dbg, &form, error);
+    setup_res = _dwarf_setup_loc(attr, &dbg, &cucontext, &form, error);
     if (setup_res != DW_DLV_OK) {
-	return setup_res;
+        return setup_res;
     }
+    address_size = cucontext->cc_address_size;
     /* If this is a form_block then it's a location expression. If it's 
        DW_FORM_data4 or DW_FORM_data8 it's a loclist offset */
-    if (form == DW_FORM_data4 || form == DW_FORM_data8) {
-
-	/* A reference to .debug_loc, with an offset in .debug_loc of a 
-	   loclist */
-	Dwarf_Unsigned loclist_offset = 0;
-	int off_res;
+    if (((cucontext->cc_version_stamp == CURRENT_VERSION_STAMP ||
+          cucontext->cc_version_stamp == CURRENT_VERSION_STAMP3) &&
+          (form == DW_FORM_data4 || form == DW_FORM_data8)) ||
+         (cucontext->cc_version_stamp == CURRENT_VERSION_STAMP4 &&
+            form == DW_FORM_sec_offset))
+        {
 
-	off_res = _dwarf_get_loclist_header_start(dbg,
-						  attr, &loclist_offset,
-						  error);
-	if (off_res != DW_DLV_OK) {
-	    return off_res;
-	}
+        /* A reference to .debug_loc, with an offset in .debug_loc of a 
+           loclist */
+        Dwarf_Unsigned loclist_offset = 0;
+        int off_res = DW_DLV_ERROR;
+
+        off_res = _dwarf_get_loclist_header_start(dbg,
+            attr, &loclist_offset,
+            error);
+        if (off_res != DW_DLV_OK) {
+            return off_res;
+        }
 
-	/* With dwarf_loclist, just read a single entry */
-	blkres = _dwarf_read_loc_section(dbg, &loc_block,
-					 &lowpc,
-					 &highpc,
-					 loclist_offset, error);
-	if (blkres != DW_DLV_OK) {
-	    return (blkres);
-	}
-
-
-
-
+        /* With dwarf_loclist, just read a single entry */
+        blkres = _dwarf_read_loc_section(dbg, &loc_block,
+            &lowpc,
+            &highpc,
+            loclist_offset, 
+            address_size,
+            error);
+        if (blkres != DW_DLV_OK) {
+            return (blkres);
+        }
     } else {
-	Dwarf_Block *tblock = 0;
+        Dwarf_Block *tblock = 0;
 
-	blkres = dwarf_formblock(loc_attr, &tblock, error);
-	if (blkres != DW_DLV_OK) {
-	    return (blkres);
-	}
-	loc_block = *tblock;
-	/* We copied tblock contents to the stack var, so can dealloc
-	   tblock now.  Avoids leaks. */
-	dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
-	lowpc = 0;		/* HACK */
-	highpc = (Dwarf_Unsigned) (-1LL);	/* HACK */
+        blkres = dwarf_formblock(loc_attr, &tblock, error);
+        if (blkres != DW_DLV_OK) {
+            return (blkres);
+        }
+        loc_block = *tblock;
+        /* We copied tblock contents to the stack var, so can dealloc
+           tblock now.  Avoids leaks. */
+        dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
+        lowpc = 0;              /* HACK */
+        highpc = (Dwarf_Unsigned) (-1LL);       /* HACK */
     }
 
     /* An empty location description (block length 0) means the code
        generator emitted no variable, the variable was not generated,
        it was unused or perhaps never tested after being set. Dwarf2,
        section 2.4.1 In other words, it is not an error, and we don't
-       test for block length 0 specially here. FIXME: doing this once
-       is wrong, needs to handle low/hi pc sets. */
-    locdesc = _dwarf_get_locdesc(dbg, &loc_block, lowpc, highpc, error);
+       test for block length 0 specially here. 
+       See *dwarf_loclist_n() which handles the general case, this case
+       handles only a single location expression.  */
+    locdesc = _dwarf_get_locdesc(dbg, &loc_block,
+        address_size,
+        lowpc, highpc, error);
     if (locdesc == NULL) {
-	/* low level error already set: let it be passed back */
-	return (DW_DLV_ERROR);
+        /* low level error already set: let it be passed back */
+        return (DW_DLV_ERROR);
+    }
+
+    *llbuf = locdesc;
+    *listlen = 1;
+    return (DW_DLV_OK);
+}
+
+
+
+/* 
+        Handles only a location expression.
+        It returns the location expression as a loclist with
+        a single entry.
+
+        Usable to access dwarf expressions from any source, but
+        specifically from
+            DW_CFA_def_cfa_expression
+            DW_CFA_expression
+            DW_CFA_val_expression
+ 
+        expression_in must point to a valid dwarf expression
+        set of bytes of length expression_length. Not
+        a DW_FORM_block*, just the expression bytes.
+
+        If the address_size != de_pointer_size this will not work
+        right. FIXME.
+*/
+int
+dwarf_loclist_from_expr(Dwarf_Debug dbg,
+    Dwarf_Ptr expression_in,
+    Dwarf_Unsigned expression_length,
+    Dwarf_Locdesc ** llbuf,
+    Dwarf_Signed * listlen, Dwarf_Error * error)
+{
+    int res = 0;
+    Dwarf_Half addr_size =  dbg->de_pointer_size;
+    res = dwarf_loclist_from_expr_a(dbg,expression_in,
+        expression_length, addr_size,llbuf,listlen,error);
+    return res;
+}
+/* New April 27 2009. Adding addr_size argument for the rare
+ * cases where an object has CUs with a different address_size. */
+int
+dwarf_loclist_from_expr_a(Dwarf_Debug dbg,
+    Dwarf_Ptr expression_in,
+    Dwarf_Unsigned expression_length,
+    Dwarf_Half addr_size,
+    Dwarf_Locdesc ** llbuf,
+    Dwarf_Signed * listlen, Dwarf_Error * error)
+{
+    /* Dwarf_Block that describes a single location expression. */
+    Dwarf_Block loc_block;
+
+    /* A pointer to the current Dwarf_Locdesc read. */
+    Dwarf_Locdesc *locdesc = 0;
+    Dwarf_Addr lowpc = 0;
+    Dwarf_Addr highpc = (Dwarf_Unsigned) (-1LL);
+
+    memset(&loc_block,0,sizeof(loc_block));
+    loc_block.bl_len = expression_length;
+    loc_block.bl_data = expression_in;
+    loc_block.bl_from_loclist = 0; /* Not from loclist. */
+    loc_block.bl_section_offset = 0; /* Fake. Not meaningful. */
+
+    /* An empty location description (block length 0) means the code
+    generator emitted no variable, the variable was not generated,
+    it was unused or perhaps never tested after being set. Dwarf2,
+    section 2.4.1 In other words, it is not an error, and we don't
+    test for block length 0 specially here.  */
+    locdesc = _dwarf_get_locdesc(dbg, &loc_block, 
+        addr_size,lowpc, highpc, error);
+    if (locdesc == NULL) {
+        /* low level error already set: let it be passed back */
+        return (DW_DLV_ERROR);
     }
 
     *llbuf = locdesc;
@@ -866,47 +1026,48 @@
 /* Usable to read a single loclist or to read a block of them
    or to read an entire section's loclists.
 
+   It's broken because it's not safe to read a loclist entry
+   when we do not know the address size (in any object where
+   address size can vary by compilation unit).
 */
 
  /*ARGSUSED*/ int
 dwarf_get_loclist_entry(Dwarf_Debug dbg,
-			Dwarf_Unsigned offset,
-			Dwarf_Addr * hipc_offset,
-			Dwarf_Addr * lopc_offset,
-			Dwarf_Ptr * data,
-			Dwarf_Unsigned * entry_len,
-			Dwarf_Unsigned * next_entry,
-			Dwarf_Error * error)
+    Dwarf_Unsigned offset,
+    Dwarf_Addr * hipc_offset,
+    Dwarf_Addr * lopc_offset,
+    Dwarf_Ptr * data,
+    Dwarf_Unsigned * entry_len,
+    Dwarf_Unsigned * next_entry,
+    Dwarf_Error * error)
 {
     Dwarf_Block b;
-    Dwarf_Addr lowpc;
-    Dwarf_Addr highpc;
-    int res;
+    Dwarf_Addr lowpc = 0;
+    Dwarf_Addr highpc = 0;
+    Dwarf_Half address_size = 0;
+    int res = DW_DLV_ERROR;
 
-    if (!dbg->de_debug_loc) {
-	int secload = _dwarf_load_section(dbg,
-					  dbg->de_debug_loc_index,
-					  &dbg->de_debug_loc,
-					  error);
-
-	if (secload != DW_DLV_OK) {
-	    return secload;
-	}
+    if (!dbg->de_debug_loc.dss_data) {
+        int secload = _dwarf_load_section(dbg, &dbg->de_debug_loc,error);
+        if (secload != DW_DLV_OK) {
+            return secload;
+        }
     }
 
+    /* FIXME: address_size is not necessarily the same in every frame. */
+    address_size = dbg->de_pointer_size;
     res = _dwarf_read_loc_section(dbg,
-				  &b, &lowpc, &highpc, offset, error);
+         &b, &lowpc, &highpc, offset, 
+         address_size,error);
     if (res != DW_DLV_OK) {
-	return res;
+        return res;
     }
     *hipc_offset = highpc;
     *lopc_offset = lowpc;
     *entry_len = b.bl_len;
     *data = b.bl_data;
     *next_entry = b.bl_len + b.bl_section_offset;
-
     return DW_DLV_OK;
+}
 
 
-
-}
--- a/usr/src/tools/ctf/dwarf/common/dwarf_loc.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_loc.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000, 2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
--- a/usr/src/tools/ctf/dwarf/common/dwarf_macro.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_macro.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -32,6 +33,12 @@
   http://oss.sgi.com/projects/GenInfo/NoticeExplan
 
 */
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
 
 
 
@@ -39,6 +46,9 @@
 #include "dwarf_incl.h"
 #include <stdio.h>
 #include <limits.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif /* HAVE_STDLIB_H */
 #include "dwarf_macro.h"
 
 
@@ -47,11 +57,11 @@
 #define SPACE ' '
 
 /*
-	Given the dwarf macro string, return a pointer to
-	the value.  Returns pointer to 0 byte at end of string
-	if no value found (meaning the value is the empty string).
+        Given the dwarf macro string, return a pointer to
+        the value.  Returns pointer to 0 byte at end of string
+        if no value found (meaning the value is the empty string).
 
-	Only understands well-formed dwarf macinfo strings.
+        Only understands well-formed dwarf macinfo strings.
 */
 char *
 dwarf_find_macro_value_start(char *str)
@@ -60,21 +70,21 @@
     int funclike = 0;
 
     for (lcp = str; *lcp; ++lcp) {
-	switch (*lcp) {
-	case LEFTPAREN:
-	    funclike = 1;
-	    break;
-	case RIGHTPAREN:
-	    /* lcp+1 must be a space, and following char is the value */
-	    return lcp + 2;
-	case SPACE:
-	    /* we allow extraneous spaces inside macro parameter **
-	       list, just in case... This is not really needed. */
-	    if (!funclike) {
-		return lcp + 1;
-	    }
-	    break;
-	}
+        switch (*lcp) {
+        case LEFTPAREN:
+            funclike = 1;
+            break;
+        case RIGHTPAREN:
+            /* lcp+1 must be a space, and following char is the value */
+            return lcp + 2;
+        case SPACE:
+            /* we allow extraneous spaces inside macro parameter **
+               list, just in case... This is not really needed. */
+            if (!funclike) {
+                return lcp + 1;
+            }
+            break;
+        }
     }
     /* never found value: returns pointer to the 0 byte at end of
        string */
@@ -91,211 +101,248 @@
    STARTERMAX is set so that the array need not be expanded for
    most files: it is the initial include file depth.
 */
-static Dwarf_Signed *st_base;
-static long max;
-static long next_to_use;
-static int was_fault = 0;
+struct macro_stack_s {
+    Dwarf_Signed *st_base;
+    long max;
+    long next_to_use;
+    int was_fault;
+};
+
+static void _dwarf_reset_index_macro_stack(struct macro_stack_s *ms);
+static void
+free_macro_stack(Dwarf_Debug dbg, struct macro_stack_s *ms)
+{
+    dwarf_dealloc(dbg,ms->st_base,DW_DLA_STRING);
+    _dwarf_reset_index_macro_stack(ms);
+}
 
 #define STARTERMAX 10
 static void
-_dwarf_reset_index_stack(void)
+_dwarf_reset_index_macro_stack(struct macro_stack_s *ms)
 {
-    next_to_use = 0;
-    was_fault = 0;
+    ms->st_base = 0;
+    ms->max = 0;
+    ms->next_to_use = 0;
+    ms->was_fault = 0;
 }
 static int
-_dwarf_mac_push_index(Dwarf_Debug dbg, Dwarf_Signed indx)
+_dwarf_macro_stack_push_index(Dwarf_Debug dbg, Dwarf_Signed indx,
+    struct macro_stack_s *ms)
 {
     Dwarf_Signed *newbase;
 
-    if (next_to_use >= max) {
-	long new_size;
+    if (ms->next_to_use >= ms->max) {
+        long new_size;
 
-	if (max == 0) {
-	    max = STARTERMAX;
-	}
-	new_size = max * 2;
-	newbase =
-	    _dwarf_get_alloc(dbg, DW_DLA_STRING,
-			     new_size * sizeof(Dwarf_Signed));
-	if (newbase == 0) {
-	    /* just leave the old array in place */
-	    was_fault = 1;
-	    return DW_DLV_ERROR;
-	}
-	memcpy(newbase, st_base, next_to_use * sizeof(Dwarf_Signed));
-	dwarf_dealloc(dbg, st_base, DW_DLA_STRING);
-	st_base = newbase;
-	max = new_size;
+        if (ms->max == 0) {
+            ms->max = STARTERMAX;
+        }
+        new_size = ms->max * 2;
+        newbase =
+            _dwarf_get_alloc(dbg, DW_DLA_STRING,
+                             new_size * sizeof(Dwarf_Signed));
+        if (newbase == 0) {
+            /* just leave the old array in place */
+            ms->was_fault = 1;
+            return DW_DLV_ERROR;
+        }
+        if(ms->st_base) {
+            memcpy(newbase, ms->st_base,
+               ms->next_to_use * sizeof(Dwarf_Signed));
+            dwarf_dealloc(dbg, ms->st_base, DW_DLA_STRING);
+        }
+        ms->st_base = newbase;
+        ms->max = new_size;
     }
-    st_base[next_to_use] = indx;
-    ++next_to_use;
+    ms->st_base[ms->next_to_use] = indx;
+    ++ms->next_to_use;
     return DW_DLV_OK;
 }
+
 static Dwarf_Signed
-_dwarf_mac_pop_index(void)
+_dwarf_macro_stack_pop_index(struct macro_stack_s *ms)
 {
-    if (was_fault) {
-	return -1;
+    if (ms->was_fault) {
+        return -1;
     }
-    if (next_to_use > 0) {
-	next_to_use--;
-	return (*(st_base + next_to_use));
+    if (ms->next_to_use > 0) {
+        ms->next_to_use--;
+        return (ms->st_base[ms->next_to_use]);
+    } else {
+        ms->was_fault = 1;
     }
     return -1;
 }
 
 /* starting at macro_offset in .debug_macinfo,
-	if maximum_count is 0, treat as if it is infinite.
-	get macro data up thru
-	maximum_count entries or the end of a compilation
-	unit's entries (whichever comes first). 
+        if maximum_count is 0, treat as if it is infinite.
+        get macro data up thru
+        maximum_count entries or the end of a compilation
+        unit's entries (whichever comes first). 
 */
 
 int
 dwarf_get_macro_details(Dwarf_Debug dbg,
-			Dwarf_Off macro_offset,
-			Dwarf_Unsigned maximum_count,
-			Dwarf_Signed * entry_count,
-			Dwarf_Macro_Details ** details,
-			Dwarf_Error * error)
+    Dwarf_Off macro_offset,
+    Dwarf_Unsigned maximum_count,
+    Dwarf_Signed * entry_count,
+    Dwarf_Macro_Details ** details,
+    Dwarf_Error * error)
 {
-    Dwarf_Small *macro_base;
-    Dwarf_Small *pnext;
-    Dwarf_Unsigned endloc;
-    unsigned char uc;
-    unsigned long depth;
-
-    int res;
-
+    Dwarf_Small *macro_base = 0;
+    Dwarf_Small *pnext = 0;
+    Dwarf_Unsigned endloc = 0;
+    unsigned char uc = 0;
+    unsigned long depth = 0;    
+        /* By section 6.3.2 Dwarf3 draft 8/9,
+        the base file should appear as
+        DW_MACINFO_start_file. See
+        http://gcc.gnu.org/ml/gcc-bugs/2005-02/msg03442.html
+        on "[Bug debug/20253] New: [3.4/4.0 regression]:
+        Macro debug info broken due to lexer change" for how
+        gcc is broken in some versions. We no longer use
+        depth as a stopping point, it's not needed as a
+        stopping point anyway.  */
+    int res = 0;
     /* count space used by strings */
     unsigned long str_space = 0;
     int done = 0;
-    unsigned long space_needed;
-    unsigned long string_offset;
-    Dwarf_Small *return_data;
-    Dwarf_Small *pdata;
+    unsigned long space_needed = 0;
+    unsigned long string_offset = 0;
+    Dwarf_Small *return_data = 0;
+    Dwarf_Small *pdata = 0;
     unsigned long final_count = 0;
     Dwarf_Signed fileindex = -1;
-    Dwarf_Small *latest_str_loc;
+    Dwarf_Small *latest_str_loc = 0;
+    struct macro_stack_s msdata;
 
-    unsigned long count;
+    unsigned long count = 0;
     unsigned long max_count = (unsigned long) maximum_count;
 
-    _dwarf_reset_index_stack();
+    _dwarf_reset_index_macro_stack(&msdata);
     if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+        free_macro_stack(dbg,&msdata);
+        return (DW_DLV_ERROR);
     }
 
-    res =
-       _dwarf_load_section(dbg,
-		           dbg->de_debug_macinfo_index,
-			   &dbg->de_debug_macinfo,
-			   error);
+    res = _dwarf_load_section(dbg, &dbg->de_debug_macinfo,error);
     if (res != DW_DLV_OK) {
-	return res;
+        free_macro_stack(dbg,&msdata);
+        return res;
     }
 
-    macro_base = dbg->de_debug_macinfo;
+    macro_base = dbg->de_debug_macinfo.dss_data;
     if (macro_base == NULL) {
-	return (DW_DLV_NO_ENTRY);
+        free_macro_stack(dbg,&msdata);
+        return (DW_DLV_NO_ENTRY);
     }
-    if (macro_offset >= dbg->de_debug_macinfo_size) {
-	return (DW_DLV_NO_ENTRY);
+    if (macro_offset >= dbg->de_debug_macinfo.dss_size) {
+        free_macro_stack(dbg,&msdata);
+        return (DW_DLV_NO_ENTRY);
     }
 
     pnext = macro_base + macro_offset;
     if (maximum_count == 0) {
-	max_count = ULONG_MAX;
+        max_count = ULONG_MAX;
     }
 
 
     /* how many entries and how much space will they take? */
 
     endloc = (pnext - macro_base);
-    if (endloc >= dbg->de_debug_macinfo_size) {
-	if (endloc == dbg->de_debug_macinfo_size) {
-	    /* normal: found last entry */
-	    return DW_DLV_NO_ENTRY;
-	}
-	_dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
-	return (DW_DLV_ERROR);
+    if (endloc >= dbg->de_debug_macinfo.dss_size) {
+        if (endloc == dbg->de_debug_macinfo.dss_size) {
+            /* normal: found last entry */
+            free_macro_stack(dbg,&msdata);
+            return DW_DLV_NO_ENTRY;
+        }
+        _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
+        free_macro_stack(dbg,&msdata);
+        return (DW_DLV_ERROR);
     }
     for (count = 0; !done && count < max_count; ++count) {
-	unsigned long slen;
-	Dwarf_Word len;
+        unsigned long slen;
+        Dwarf_Word len;
 
-	uc = *pnext;
-	++pnext;		/* get past the type code */
-	switch (uc) {
-	case DW_MACINFO_define:
-	case DW_MACINFO_undef:
-	    /* line, string */
-	case DW_MACINFO_vendor_ext:
-	    /* number, string */
-	    (void) _dwarf_decode_u_leb128(pnext, &len);
+        uc = *pnext;
+        ++pnext;                /* get past the type code */
+        switch (uc) {
+        case DW_MACINFO_define:
+        case DW_MACINFO_undef:
+            /* line, string */
+        case DW_MACINFO_vendor_ext:
+            /* number, string */
+            (void) _dwarf_decode_u_leb128(pnext, &len);
 
-	    pnext += len;
-	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
-		_dwarf_error(dbg, error,
-			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
-		return (DW_DLV_ERROR);
-	    }
-	    slen = strlen((char *) pnext) + 1;
-	    pnext += slen;
-	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
-		_dwarf_error(dbg, error,
-			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
-		return (DW_DLV_ERROR);
-	    }
-	    str_space += slen;
-	    break;
-	case DW_MACINFO_start_file:
-	    /* line, file index */
-	    (void) _dwarf_decode_u_leb128(pnext, &len);
-	    pnext += len;
-	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
-		_dwarf_error(dbg, error,
-			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
-		return (DW_DLV_ERROR);
-	    }
-	    (void) _dwarf_decode_u_leb128(pnext, &len);
-	    pnext += len;
-	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
-		_dwarf_error(dbg, error,
-			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
-		return (DW_DLV_ERROR);
-	    }
-	    ++depth;
-	    break;
+            pnext += len;
+            if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
+                free_macro_stack(dbg,&msdata);
+                _dwarf_error(dbg, error,
+                    DW_DLE_DEBUG_MACRO_INCONSISTENT);
+                return (DW_DLV_ERROR);
+            }
+            slen = strlen((char *) pnext) + 1;
+            pnext += slen;
+            if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
+                free_macro_stack(dbg,&msdata);
+                _dwarf_error(dbg, error,
+                    DW_DLE_DEBUG_MACRO_INCONSISTENT);
+                return (DW_DLV_ERROR);
+            }
+            str_space += slen;
+            break;
+        case DW_MACINFO_start_file:
+            /* line, file index */
+            (void) _dwarf_decode_u_leb128(pnext, &len);
+            pnext += len;
+            if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
+                free_macro_stack(dbg,&msdata);
+                _dwarf_error(dbg, error,
+                    DW_DLE_DEBUG_MACRO_INCONSISTENT);
+                return (DW_DLV_ERROR);
+            }
+            (void) _dwarf_decode_u_leb128(pnext, &len);
+            pnext += len;
+            if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
+                free_macro_stack(dbg,&msdata);
+                _dwarf_error(dbg, error,
+                    DW_DLE_DEBUG_MACRO_INCONSISTENT);
+                return (DW_DLV_ERROR);
+            }
+            ++depth;
+            break;
 
-	case DW_MACINFO_end_file:
-	    if (--depth == 0) {
-		done = 1;
-	    }
-	    break;		/* no string or number here */
-	case 0:
-	    /* end of cu's entries */
-	    done = 1;
-	    break;
-	default:
-	    _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT);
-	    return (DW_DLV_ERROR);
-	    /* bogus macinfo! */
-	}
-        
-	endloc = (pnext - macro_base);
-	if (endloc == dbg->de_debug_macinfo_size) {
-	    done = 1;
-	} else if (endloc > dbg->de_debug_macinfo_size) {
-	    _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
-	    return (DW_DLV_ERROR);
-	}
+        case DW_MACINFO_end_file:
+            if (--depth == 0) {
+                /* done = 1; no, do not stop here, at least one gcc had 
+                   the wrong depth settings in the gcc 3.4 timeframe. */
+            }
+            break;              /* no string or number here */
+        case 0:
+            /* end of cu's entries */
+            done = 1;
+            break;
+        default:
+            free_macro_stack(dbg,&msdata);
+            _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT);
+            return (DW_DLV_ERROR);
+            /* bogus macinfo! */
+        }
+
+        endloc = (pnext - macro_base);
+        if (endloc == dbg->de_debug_macinfo.dss_size) {
+            done = 1;
+        } else if (endloc > dbg->de_debug_macinfo.dss_size) {
+            _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
+            free_macro_stack(dbg,&msdata);
+            return (DW_DLV_ERROR);
+        }
     }
     if (count == 0) {
-	_dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INTERNAL_ERR);
-	return (DW_DLV_ERROR);
+        free_macro_stack(dbg,&msdata);
+        _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INTERNAL_ERR);
+        return (DW_DLV_ERROR);
     }
 
     /* we have 'count' array entries to allocate and str_space bytes of 
@@ -306,104 +353,115 @@
     /* extra 2 not really needed */
     space_needed = string_offset + str_space + 2;
     return_data = pdata =
-	_dwarf_get_alloc(dbg, DW_DLA_STRING, space_needed);
+        _dwarf_get_alloc(dbg, DW_DLA_STRING, space_needed);
     latest_str_loc = pdata + string_offset;
     if (pdata == 0) {
-	_dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_MALLOC_SPACE);
-	return (DW_DLV_ERROR);
+        free_macro_stack(dbg,&msdata);
+        _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_MALLOC_SPACE);
+        return (DW_DLV_ERROR);
     }
     pnext = macro_base + macro_offset;
 
     done = 0;
-    
+
+    /* A series ends with a type code of 0. */
+
     for (final_count = 0; !done && final_count < count; ++final_count) {
-	unsigned long slen;
-	Dwarf_Word len;
-	Dwarf_Unsigned v1;
-	Dwarf_Macro_Details *pdmd = (Dwarf_Macro_Details *) (pdata +
-							     final_count
-							     *
-							     sizeof
-							     (Dwarf_Macro_Details));
+        unsigned long slen;
+        Dwarf_Word len;
+        Dwarf_Unsigned v1;
+        Dwarf_Macro_Details *pdmd = (Dwarf_Macro_Details *) (pdata +
+            (final_count * sizeof (Dwarf_Macro_Details)));
 
-	endloc = (pnext - macro_base);
-	if (endloc > dbg->de_debug_macinfo_size) {
-	    _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
-	    return (DW_DLV_ERROR);
-	}
-	uc = *pnext;
-	pdmd->dmd_offset = (pnext - macro_base);
-	pdmd->dmd_type = uc;
-	pdmd->dmd_fileindex = fileindex;
-	pdmd->dmd_lineno = 0;
-	pdmd->dmd_macro = 0;
-	++pnext;		/* get past the type code */
-	switch (uc) {
-	case DW_MACINFO_define:
-	case DW_MACINFO_undef:
-	    /* line, string */
-	case DW_MACINFO_vendor_ext:
-	    /* number, string */
-	    v1 = _dwarf_decode_u_leb128(pnext, &len);
-	    pdmd->dmd_lineno = v1;
+        endloc = (pnext - macro_base);
+        if (endloc > dbg->de_debug_macinfo.dss_size) {
+            free_macro_stack(dbg,&msdata);
+            _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
+            return (DW_DLV_ERROR);
+        }
+        uc = *pnext;
+        pdmd->dmd_offset = (pnext - macro_base);
+        pdmd->dmd_type = uc;
+        pdmd->dmd_fileindex = fileindex;
+        pdmd->dmd_lineno = 0;
+        pdmd->dmd_macro = 0;
+        ++pnext;                /* get past the type code */
+        switch (uc) {
+        case DW_MACINFO_define:
+        case DW_MACINFO_undef:
+            /* line, string */
+        case DW_MACINFO_vendor_ext:
+            /* number, string */
+            v1 = _dwarf_decode_u_leb128(pnext, &len);
+            pdmd->dmd_lineno = v1;
 
-	    pnext += len;
-	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
-		_dwarf_error(dbg, error,
-			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
-		return (DW_DLV_ERROR);
-	    }
-	    slen = strlen((char *) pnext) + 1;
-	    strcpy((char *) latest_str_loc, (char *) pnext);
-	    pdmd->dmd_macro = (char *) latest_str_loc;
-	    latest_str_loc += slen;
-	    pnext += slen;
-	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
-		_dwarf_error(dbg, error,
-			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
-		return (DW_DLV_ERROR);
-	    }
-	    str_space += slen;
-	    break;
-	case DW_MACINFO_start_file:
-	    /* line, file index */
-	    v1 = _dwarf_decode_u_leb128(pnext, &len);
-	    pdmd->dmd_lineno = v1;
-	    pnext += len;
-	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
-		_dwarf_error(dbg, error,
-			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
-		return (DW_DLV_ERROR);
-	    }
-	    v1 = _dwarf_decode_u_leb128(pnext, &len);
-	    pdmd->dmd_fileindex = v1;
-	    (void) _dwarf_mac_push_index(dbg, fileindex);
-	    /* we ignore the error, we just let fileindex ** be -1 when 
-	       we pop this one */
-	    fileindex = v1;
-	    pnext += len;
-	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
-		_dwarf_error(dbg, error,
-			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
-		return (DW_DLV_ERROR);
-	    }
-	    break;
+            pnext += len;
+            if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
+                free_macro_stack(dbg,&msdata);
+                dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
+                _dwarf_error(dbg, error,
+                    DW_DLE_DEBUG_MACRO_INCONSISTENT);
+                return (DW_DLV_ERROR);
+            }
+            slen = strlen((char *) pnext) + 1;
+            strcpy((char *) latest_str_loc, (char *) pnext);
+            pdmd->dmd_macro = (char *) latest_str_loc;
+            latest_str_loc += slen;
+            pnext += slen;
+            if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
+                free_macro_stack(dbg,&msdata);
+                dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
+                _dwarf_error(dbg, error,
+                    DW_DLE_DEBUG_MACRO_INCONSISTENT);
+                return (DW_DLV_ERROR);
+            }
+            break;
+        case DW_MACINFO_start_file:
+            /* Line, file index */
+            v1 = _dwarf_decode_u_leb128(pnext, &len);
+            pdmd->dmd_lineno = v1;
+            pnext += len;
+            if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
+                free_macro_stack(dbg,&msdata);
+                dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
+                _dwarf_error(dbg, error,
+                    DW_DLE_DEBUG_MACRO_INCONSISTENT);
+                return (DW_DLV_ERROR);
+            }
+            v1 = _dwarf_decode_u_leb128(pnext, &len);
+            pdmd->dmd_fileindex = v1;
+            (void) _dwarf_macro_stack_push_index(dbg, fileindex,
+                                                 &msdata);
+            /* We ignore the error, we just let fileindex ** be -1 when 
+               we pop this one. */
+            fileindex = v1;
+            pnext += len;
+            if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) {
+                free_macro_stack(dbg,&msdata);
+                dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
+                _dwarf_error(dbg, error,
+                    DW_DLE_DEBUG_MACRO_INCONSISTENT);
+                return (DW_DLV_ERROR);
+            }
+            break;
 
-	case DW_MACINFO_end_file:
-	    fileindex = _dwarf_mac_pop_index();
-	    break;		/* no string or number here */
-	case 0:
-	    /* end of cu's entries */
-	    done = 1;
-	    break;
-	default:
-	    _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT);
-	    return (DW_DLV_ERROR);
-	    /* bogus macinfo! */
-	}
+        case DW_MACINFO_end_file:
+            fileindex = _dwarf_macro_stack_pop_index(&msdata);
+            break;              /* no string or number here */
+        case 0:
+            /* Type code of 0 means the end of cu's entries. */
+            done = 1;
+            break;
+        default:
+            /* Bogus macinfo! */
+            dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
+            free_macro_stack(dbg,&msdata);
+            _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT);
+            return (DW_DLV_ERROR);
+        }
     }
     *entry_count = count;
     *details = (Dwarf_Macro_Details *) return_data;
-
+    free_macro_stack(dbg,&msdata);
     return DW_DLV_OK;
 }
--- a/usr/src/tools/ctf/dwarf/common/dwarf_macro.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_macro.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000, 2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -39,6 +39,6 @@
 
    dwarf_macro.h
 
-   $Revision: 1.3 $    $Date: 2001/09/18 19:23:55 $
+   $Revision: 1.4 $    $Date: 2004/10/28 22:19:14 $
 
 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_names.c	Sun May 22 03:13:22 2011 +0100
@@ -0,0 +1,2408 @@
+/* Generated routines, do not edit. */
+/* Generated on May 22 2011  03:05:33 */
+
+/* BEGIN FILE */
+
+#include "dwarf.h"
+
+#include "libdwarf.h"
+
+/* ARGSUSED */
+int
+dwarf_get_TAG_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_TAG_array_type:
+        *s_out = "DW_TAG_array_type";
+        return DW_DLV_OK;
+    case DW_TAG_class_type:
+        *s_out = "DW_TAG_class_type";
+        return DW_DLV_OK;
+    case DW_TAG_entry_point:
+        *s_out = "DW_TAG_entry_point";
+        return DW_DLV_OK;
+    case DW_TAG_enumeration_type:
+        *s_out = "DW_TAG_enumeration_type";
+        return DW_DLV_OK;
+    case DW_TAG_formal_parameter:
+        *s_out = "DW_TAG_formal_parameter";
+        return DW_DLV_OK;
+    case DW_TAG_imported_declaration:
+        *s_out = "DW_TAG_imported_declaration";
+        return DW_DLV_OK;
+    case DW_TAG_label:
+        *s_out = "DW_TAG_label";
+        return DW_DLV_OK;
+    case DW_TAG_lexical_block:
+        *s_out = "DW_TAG_lexical_block";
+        return DW_DLV_OK;
+    case DW_TAG_member:
+        *s_out = "DW_TAG_member";
+        return DW_DLV_OK;
+    case DW_TAG_pointer_type:
+        *s_out = "DW_TAG_pointer_type";
+        return DW_DLV_OK;
+    case DW_TAG_reference_type:
+        *s_out = "DW_TAG_reference_type";
+        return DW_DLV_OK;
+    case DW_TAG_compile_unit:
+        *s_out = "DW_TAG_compile_unit";
+        return DW_DLV_OK;
+    case DW_TAG_string_type:
+        *s_out = "DW_TAG_string_type";
+        return DW_DLV_OK;
+    case DW_TAG_structure_type:
+        *s_out = "DW_TAG_structure_type";
+        return DW_DLV_OK;
+    case DW_TAG_subroutine_type:
+        *s_out = "DW_TAG_subroutine_type";
+        return DW_DLV_OK;
+    case DW_TAG_typedef:
+        *s_out = "DW_TAG_typedef";
+        return DW_DLV_OK;
+    case DW_TAG_union_type:
+        *s_out = "DW_TAG_union_type";
+        return DW_DLV_OK;
+    case DW_TAG_unspecified_parameters:
+        *s_out = "DW_TAG_unspecified_parameters";
+        return DW_DLV_OK;
+    case DW_TAG_variant:
+        *s_out = "DW_TAG_variant";
+        return DW_DLV_OK;
+    case DW_TAG_common_block:
+        *s_out = "DW_TAG_common_block";
+        return DW_DLV_OK;
+    case DW_TAG_common_inclusion:
+        *s_out = "DW_TAG_common_inclusion";
+        return DW_DLV_OK;
+    case DW_TAG_inheritance:
+        *s_out = "DW_TAG_inheritance";
+        return DW_DLV_OK;
+    case DW_TAG_inlined_subroutine:
+        *s_out = "DW_TAG_inlined_subroutine";
+        return DW_DLV_OK;
+    case DW_TAG_module:
+        *s_out = "DW_TAG_module";
+        return DW_DLV_OK;
+    case DW_TAG_ptr_to_member_type:
+        *s_out = "DW_TAG_ptr_to_member_type";
+        return DW_DLV_OK;
+    case DW_TAG_set_type:
+        *s_out = "DW_TAG_set_type";
+        return DW_DLV_OK;
+    case DW_TAG_subrange_type:
+        *s_out = "DW_TAG_subrange_type";
+        return DW_DLV_OK;
+    case DW_TAG_with_stmt:
+        *s_out = "DW_TAG_with_stmt";
+        return DW_DLV_OK;
+    case DW_TAG_access_declaration:
+        *s_out = "DW_TAG_access_declaration";
+        return DW_DLV_OK;
+    case DW_TAG_base_type:
+        *s_out = "DW_TAG_base_type";
+        return DW_DLV_OK;
+    case DW_TAG_catch_block:
+        *s_out = "DW_TAG_catch_block";
+        return DW_DLV_OK;
+    case DW_TAG_const_type:
+        *s_out = "DW_TAG_const_type";
+        return DW_DLV_OK;
+    case DW_TAG_constant:
+        *s_out = "DW_TAG_constant";
+        return DW_DLV_OK;
+    case DW_TAG_enumerator:
+        *s_out = "DW_TAG_enumerator";
+        return DW_DLV_OK;
+    case DW_TAG_file_type:
+        *s_out = "DW_TAG_file_type";
+        return DW_DLV_OK;
+    case DW_TAG_friend:
+        *s_out = "DW_TAG_friend";
+        return DW_DLV_OK;
+    case DW_TAG_namelist:
+        *s_out = "DW_TAG_namelist";
+        return DW_DLV_OK;
+    case DW_TAG_namelist_item:
+        *s_out = "DW_TAG_namelist_item";
+        return DW_DLV_OK;
+    case DW_TAG_packed_type:
+        *s_out = "DW_TAG_packed_type";
+        return DW_DLV_OK;
+    case DW_TAG_subprogram:
+        *s_out = "DW_TAG_subprogram";
+        return DW_DLV_OK;
+    case DW_TAG_template_type_parameter:
+        *s_out = "DW_TAG_template_type_parameter";
+        return DW_DLV_OK;
+    case DW_TAG_template_value_parameter:
+        *s_out = "DW_TAG_template_value_parameter";
+        return DW_DLV_OK;
+    case DW_TAG_thrown_type:
+        *s_out = "DW_TAG_thrown_type";
+        return DW_DLV_OK;
+    case DW_TAG_try_block:
+        *s_out = "DW_TAG_try_block";
+        return DW_DLV_OK;
+    case DW_TAG_variant_part:
+        *s_out = "DW_TAG_variant_part";
+        return DW_DLV_OK;
+    case DW_TAG_variable:
+        *s_out = "DW_TAG_variable";
+        return DW_DLV_OK;
+    case DW_TAG_volatile_type:
+        *s_out = "DW_TAG_volatile_type";
+        return DW_DLV_OK;
+    case DW_TAG_dwarf_procedure:
+        *s_out = "DW_TAG_dwarf_procedure";
+        return DW_DLV_OK;
+    case DW_TAG_restrict_type:
+        *s_out = "DW_TAG_restrict_type";
+        return DW_DLV_OK;
+    case DW_TAG_interface_type:
+        *s_out = "DW_TAG_interface_type";
+        return DW_DLV_OK;
+    case DW_TAG_namespace:
+        *s_out = "DW_TAG_namespace";
+        return DW_DLV_OK;
+    case DW_TAG_imported_module:
+        *s_out = "DW_TAG_imported_module";
+        return DW_DLV_OK;
+    case DW_TAG_unspecified_type:
+        *s_out = "DW_TAG_unspecified_type";
+        return DW_DLV_OK;
+    case DW_TAG_partial_unit:
+        *s_out = "DW_TAG_partial_unit";
+        return DW_DLV_OK;
+    case DW_TAG_imported_unit:
+        *s_out = "DW_TAG_imported_unit";
+        return DW_DLV_OK;
+    case DW_TAG_mutable_type:
+        *s_out = "DW_TAG_mutable_type";
+        return DW_DLV_OK;
+    case DW_TAG_condition:
+        *s_out = "DW_TAG_condition";
+        return DW_DLV_OK;
+    case DW_TAG_shared_type:
+        *s_out = "DW_TAG_shared_type";
+        return DW_DLV_OK;
+    case DW_TAG_type_unit:
+        *s_out = "DW_TAG_type_unit";
+        return DW_DLV_OK;
+    case DW_TAG_rvalue_reference_type:
+        *s_out = "DW_TAG_rvalue_reference_type";
+        return DW_DLV_OK;
+    case DW_TAG_template_alias:
+        *s_out = "DW_TAG_template_alias";
+        return DW_DLV_OK;
+    case DW_TAG_lo_user:
+        *s_out = "DW_TAG_lo_user";
+        return DW_DLV_OK;
+    case DW_TAG_MIPS_loop:
+        *s_out = "DW_TAG_MIPS_loop";
+        return DW_DLV_OK;
+    case DW_TAG_HP_array_descriptor:
+        *s_out = "DW_TAG_HP_array_descriptor";
+        return DW_DLV_OK;
+    case DW_TAG_format_label:
+        *s_out = "DW_TAG_format_label";
+        return DW_DLV_OK;
+    case DW_TAG_function_template:
+        *s_out = "DW_TAG_function_template";
+        return DW_DLV_OK;
+    case DW_TAG_class_template:
+        *s_out = "DW_TAG_class_template";
+        return DW_DLV_OK;
+    case DW_TAG_GNU_BINCL:
+        *s_out = "DW_TAG_GNU_BINCL";
+        return DW_DLV_OK;
+    case DW_TAG_GNU_EINCL:
+        *s_out = "DW_TAG_GNU_EINCL";
+        return DW_DLV_OK;
+    case DW_TAG_GNU_template_template_parameter:
+        *s_out = "DW_TAG_GNU_template_template_parameter";
+        return DW_DLV_OK;
+    case DW_TAG_GNU_template_parameter_pack:
+        *s_out = "DW_TAG_GNU_template_parameter_pack";
+        return DW_DLV_OK;
+    case DW_TAG_GNU_formal_parameter_pack:
+        *s_out = "DW_TAG_GNU_formal_parameter_pack";
+        return DW_DLV_OK;
+    case DW_TAG_SUN_function_template:
+        *s_out = "DW_TAG_SUN_function_template";
+        return DW_DLV_OK;
+    case DW_TAG_SUN_class_template:
+        *s_out = "DW_TAG_SUN_class_template";
+        return DW_DLV_OK;
+    case DW_TAG_SUN_struct_template:
+        *s_out = "DW_TAG_SUN_struct_template";
+        return DW_DLV_OK;
+    case DW_TAG_SUN_union_template:
+        *s_out = "DW_TAG_SUN_union_template";
+        return DW_DLV_OK;
+    case DW_TAG_SUN_indirect_inheritance:
+        *s_out = "DW_TAG_SUN_indirect_inheritance";
+        return DW_DLV_OK;
+    case DW_TAG_SUN_codeflags:
+        *s_out = "DW_TAG_SUN_codeflags";
+        return DW_DLV_OK;
+    case DW_TAG_SUN_memop_info:
+        *s_out = "DW_TAG_SUN_memop_info";
+        return DW_DLV_OK;
+    case DW_TAG_SUN_omp_child_func:
+        *s_out = "DW_TAG_SUN_omp_child_func";
+        return DW_DLV_OK;
+    case DW_TAG_SUN_rtti_descriptor:
+        *s_out = "DW_TAG_SUN_rtti_descriptor";
+        return DW_DLV_OK;
+    case DW_TAG_SUN_dtor_info:
+        *s_out = "DW_TAG_SUN_dtor_info";
+        return DW_DLV_OK;
+    case DW_TAG_SUN_dtor:
+        *s_out = "DW_TAG_SUN_dtor";
+        return DW_DLV_OK;
+    case DW_TAG_SUN_f90_interface:
+        *s_out = "DW_TAG_SUN_f90_interface";
+        return DW_DLV_OK;
+    case DW_TAG_SUN_fortran_vax_structure:
+        *s_out = "DW_TAG_SUN_fortran_vax_structure";
+        return DW_DLV_OK;
+    case DW_TAG_SUN_hi:
+        *s_out = "DW_TAG_SUN_hi";
+        return DW_DLV_OK;
+    case DW_TAG_ALTIUM_circ_type:
+        *s_out = "DW_TAG_ALTIUM_circ_type";
+        return DW_DLV_OK;
+    case DW_TAG_ALTIUM_mwa_circ_type:
+        *s_out = "DW_TAG_ALTIUM_mwa_circ_type";
+        return DW_DLV_OK;
+    case DW_TAG_ALTIUM_rev_carry_type:
+        *s_out = "DW_TAG_ALTIUM_rev_carry_type";
+        return DW_DLV_OK;
+    case DW_TAG_ALTIUM_rom:
+        *s_out = "DW_TAG_ALTIUM_rom";
+        return DW_DLV_OK;
+    case DW_TAG_upc_shared_type:
+        *s_out = "DW_TAG_upc_shared_type";
+        return DW_DLV_OK;
+    case DW_TAG_upc_strict_type:
+        *s_out = "DW_TAG_upc_strict_type";
+        return DW_DLV_OK;
+    case DW_TAG_upc_relaxed_type:
+        *s_out = "DW_TAG_upc_relaxed_type";
+        return DW_DLV_OK;
+    case DW_TAG_PGI_kanji_type:
+        *s_out = "DW_TAG_PGI_kanji_type";
+        return DW_DLV_OK;
+    case DW_TAG_PGI_interface_block:
+        *s_out = "DW_TAG_PGI_interface_block";
+        return DW_DLV_OK;
+    case DW_TAG_hi_user:
+        *s_out = "DW_TAG_hi_user";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_children_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_children_no:
+        *s_out = "DW_children_no";
+        return DW_DLV_OK;
+    case DW_children_yes:
+        *s_out = "DW_children_yes";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_FORM_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_FORM_addr:
+        *s_out = "DW_FORM_addr";
+        return DW_DLV_OK;
+    case DW_FORM_block2:
+        *s_out = "DW_FORM_block2";
+        return DW_DLV_OK;
+    case DW_FORM_block4:
+        *s_out = "DW_FORM_block4";
+        return DW_DLV_OK;
+    case DW_FORM_data2:
+        *s_out = "DW_FORM_data2";
+        return DW_DLV_OK;
+    case DW_FORM_data4:
+        *s_out = "DW_FORM_data4";
+        return DW_DLV_OK;
+    case DW_FORM_data8:
+        *s_out = "DW_FORM_data8";
+        return DW_DLV_OK;
+    case DW_FORM_string:
+        *s_out = "DW_FORM_string";
+        return DW_DLV_OK;
+    case DW_FORM_block:
+        *s_out = "DW_FORM_block";
+        return DW_DLV_OK;
+    case DW_FORM_block1:
+        *s_out = "DW_FORM_block1";
+        return DW_DLV_OK;
+    case DW_FORM_data1:
+        *s_out = "DW_FORM_data1";
+        return DW_DLV_OK;
+    case DW_FORM_flag:
+        *s_out = "DW_FORM_flag";
+        return DW_DLV_OK;
+    case DW_FORM_sdata:
+        *s_out = "DW_FORM_sdata";
+        return DW_DLV_OK;
+    case DW_FORM_strp:
+        *s_out = "DW_FORM_strp";
+        return DW_DLV_OK;
+    case DW_FORM_udata:
+        *s_out = "DW_FORM_udata";
+        return DW_DLV_OK;
+    case DW_FORM_ref_addr:
+        *s_out = "DW_FORM_ref_addr";
+        return DW_DLV_OK;
+    case DW_FORM_ref1:
+        *s_out = "DW_FORM_ref1";
+        return DW_DLV_OK;
+    case DW_FORM_ref2:
+        *s_out = "DW_FORM_ref2";
+        return DW_DLV_OK;
+    case DW_FORM_ref4:
+        *s_out = "DW_FORM_ref4";
+        return DW_DLV_OK;
+    case DW_FORM_ref8:
+        *s_out = "DW_FORM_ref8";
+        return DW_DLV_OK;
+    case DW_FORM_ref_udata:
+        *s_out = "DW_FORM_ref_udata";
+        return DW_DLV_OK;
+    case DW_FORM_indirect:
+        *s_out = "DW_FORM_indirect";
+        return DW_DLV_OK;
+    case DW_FORM_sec_offset:
+        *s_out = "DW_FORM_sec_offset";
+        return DW_DLV_OK;
+    case DW_FORM_exprloc:
+        *s_out = "DW_FORM_exprloc";
+        return DW_DLV_OK;
+    case DW_FORM_flag_present:
+        *s_out = "DW_FORM_flag_present";
+        return DW_DLV_OK;
+    case DW_FORM_ref_sig8:
+        *s_out = "DW_FORM_ref_sig8";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_AT_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_AT_sibling:
+        *s_out = "DW_AT_sibling";
+        return DW_DLV_OK;
+    case DW_AT_location:
+        *s_out = "DW_AT_location";
+        return DW_DLV_OK;
+    case DW_AT_name:
+        *s_out = "DW_AT_name";
+        return DW_DLV_OK;
+    case DW_AT_ordering:
+        *s_out = "DW_AT_ordering";
+        return DW_DLV_OK;
+    case DW_AT_subscr_data:
+        *s_out = "DW_AT_subscr_data";
+        return DW_DLV_OK;
+    case DW_AT_byte_size:
+        *s_out = "DW_AT_byte_size";
+        return DW_DLV_OK;
+    case DW_AT_bit_offset:
+        *s_out = "DW_AT_bit_offset";
+        return DW_DLV_OK;
+    case DW_AT_bit_size:
+        *s_out = "DW_AT_bit_size";
+        return DW_DLV_OK;
+    case DW_AT_element_list:
+        *s_out = "DW_AT_element_list";
+        return DW_DLV_OK;
+    case DW_AT_stmt_list:
+        *s_out = "DW_AT_stmt_list";
+        return DW_DLV_OK;
+    case DW_AT_low_pc:
+        *s_out = "DW_AT_low_pc";
+        return DW_DLV_OK;
+    case DW_AT_high_pc:
+        *s_out = "DW_AT_high_pc";
+        return DW_DLV_OK;
+    case DW_AT_language:
+        *s_out = "DW_AT_language";
+        return DW_DLV_OK;
+    case DW_AT_member:
+        *s_out = "DW_AT_member";
+        return DW_DLV_OK;
+    case DW_AT_discr:
+        *s_out = "DW_AT_discr";
+        return DW_DLV_OK;
+    case DW_AT_discr_value:
+        *s_out = "DW_AT_discr_value";
+        return DW_DLV_OK;
+    case DW_AT_visibility:
+        *s_out = "DW_AT_visibility";
+        return DW_DLV_OK;
+    case DW_AT_import:
+        *s_out = "DW_AT_import";
+        return DW_DLV_OK;
+    case DW_AT_string_length:
+        *s_out = "DW_AT_string_length";
+        return DW_DLV_OK;
+    case DW_AT_common_reference:
+        *s_out = "DW_AT_common_reference";
+        return DW_DLV_OK;
+    case DW_AT_comp_dir:
+        *s_out = "DW_AT_comp_dir";
+        return DW_DLV_OK;
+    case DW_AT_const_value:
+        *s_out = "DW_AT_const_value";
+        return DW_DLV_OK;
+    case DW_AT_containing_type:
+        *s_out = "DW_AT_containing_type";
+        return DW_DLV_OK;
+    case DW_AT_default_value:
+        *s_out = "DW_AT_default_value";
+        return DW_DLV_OK;
+    case DW_AT_inline:
+        *s_out = "DW_AT_inline";
+        return DW_DLV_OK;
+    case DW_AT_is_optional:
+        *s_out = "DW_AT_is_optional";
+        return DW_DLV_OK;
+    case DW_AT_lower_bound:
+        *s_out = "DW_AT_lower_bound";
+        return DW_DLV_OK;
+    case DW_AT_producer:
+        *s_out = "DW_AT_producer";
+        return DW_DLV_OK;
+    case DW_AT_prototyped:
+        *s_out = "DW_AT_prototyped";
+        return DW_DLV_OK;
+    case DW_AT_return_addr:
+        *s_out = "DW_AT_return_addr";
+        return DW_DLV_OK;
+    case DW_AT_start_scope:
+        *s_out = "DW_AT_start_scope";
+        return DW_DLV_OK;
+    case DW_AT_bit_stride:
+        *s_out = "DW_AT_bit_stride";
+        return DW_DLV_OK;
+    case DW_AT_upper_bound:
+        *s_out = "DW_AT_upper_bound";
+        return DW_DLV_OK;
+    case DW_AT_abstract_origin:
+        *s_out = "DW_AT_abstract_origin";
+        return DW_DLV_OK;
+    case DW_AT_accessibility:
+        *s_out = "DW_AT_accessibility";
+        return DW_DLV_OK;
+    case DW_AT_address_class:
+        *s_out = "DW_AT_address_class";
+        return DW_DLV_OK;
+    case DW_AT_artificial:
+        *s_out = "DW_AT_artificial";
+        return DW_DLV_OK;
+    case DW_AT_base_types:
+        *s_out = "DW_AT_base_types";
+        return DW_DLV_OK;
+    case DW_AT_calling_convention:
+        *s_out = "DW_AT_calling_convention";
+        return DW_DLV_OK;
+    case DW_AT_count:
+        *s_out = "DW_AT_count";
+        return DW_DLV_OK;
+    case DW_AT_data_member_location:
+        *s_out = "DW_AT_data_member_location";
+        return DW_DLV_OK;
+    case DW_AT_decl_column:
+        *s_out = "DW_AT_decl_column";
+        return DW_DLV_OK;
+    case DW_AT_decl_file:
+        *s_out = "DW_AT_decl_file";
+        return DW_DLV_OK;
+    case DW_AT_decl_line:
+        *s_out = "DW_AT_decl_line";
+        return DW_DLV_OK;
+    case DW_AT_declaration:
+        *s_out = "DW_AT_declaration";
+        return DW_DLV_OK;
+    case DW_AT_discr_list:
+        *s_out = "DW_AT_discr_list";
+        return DW_DLV_OK;
+    case DW_AT_encoding:
+        *s_out = "DW_AT_encoding";
+        return DW_DLV_OK;
+    case DW_AT_external:
+        *s_out = "DW_AT_external";
+        return DW_DLV_OK;
+    case DW_AT_frame_base:
+        *s_out = "DW_AT_frame_base";
+        return DW_DLV_OK;
+    case DW_AT_friend:
+        *s_out = "DW_AT_friend";
+        return DW_DLV_OK;
+    case DW_AT_identifier_case:
+        *s_out = "DW_AT_identifier_case";
+        return DW_DLV_OK;
+    case DW_AT_macro_info:
+        *s_out = "DW_AT_macro_info";
+        return DW_DLV_OK;
+    case DW_AT_namelist_item:
+        *s_out = "DW_AT_namelist_item";
+        return DW_DLV_OK;
+    case DW_AT_priority:
+        *s_out = "DW_AT_priority";
+        return DW_DLV_OK;
+    case DW_AT_segment:
+        *s_out = "DW_AT_segment";
+        return DW_DLV_OK;
+    case DW_AT_specification:
+        *s_out = "DW_AT_specification";
+        return DW_DLV_OK;
+    case DW_AT_static_link:
+        *s_out = "DW_AT_static_link";
+        return DW_DLV_OK;
+    case DW_AT_type:
+        *s_out = "DW_AT_type";
+        return DW_DLV_OK;
+    case DW_AT_use_location:
+        *s_out = "DW_AT_use_location";
+        return DW_DLV_OK;
+    case DW_AT_variable_parameter:
+        *s_out = "DW_AT_variable_parameter";
+        return DW_DLV_OK;
+    case DW_AT_virtuality:
+        *s_out = "DW_AT_virtuality";
+        return DW_DLV_OK;
+    case DW_AT_vtable_elem_location:
+        *s_out = "DW_AT_vtable_elem_location";
+        return DW_DLV_OK;
+    case DW_AT_allocated:
+        *s_out = "DW_AT_allocated";
+        return DW_DLV_OK;
+    case DW_AT_associated:
+        *s_out = "DW_AT_associated";
+        return DW_DLV_OK;
+    case DW_AT_data_location:
+        *s_out = "DW_AT_data_location";
+        return DW_DLV_OK;
+    case DW_AT_stride:
+        *s_out = "DW_AT_stride";
+        return DW_DLV_OK;
+    case DW_AT_entry_pc:
+        *s_out = "DW_AT_entry_pc";
+        return DW_DLV_OK;
+    case DW_AT_use_UTF8:
+        *s_out = "DW_AT_use_UTF8";
+        return DW_DLV_OK;
+    case DW_AT_extension:
+        *s_out = "DW_AT_extension";
+        return DW_DLV_OK;
+    case DW_AT_ranges:
+        *s_out = "DW_AT_ranges";
+        return DW_DLV_OK;
+    case DW_AT_trampoline:
+        *s_out = "DW_AT_trampoline";
+        return DW_DLV_OK;
+    case DW_AT_call_column:
+        *s_out = "DW_AT_call_column";
+        return DW_DLV_OK;
+    case DW_AT_call_file:
+        *s_out = "DW_AT_call_file";
+        return DW_DLV_OK;
+    case DW_AT_call_line:
+        *s_out = "DW_AT_call_line";
+        return DW_DLV_OK;
+    case DW_AT_description:
+        *s_out = "DW_AT_description";
+        return DW_DLV_OK;
+    case DW_AT_binary_scale:
+        *s_out = "DW_AT_binary_scale";
+        return DW_DLV_OK;
+    case DW_AT_decimal_scale:
+        *s_out = "DW_AT_decimal_scale";
+        return DW_DLV_OK;
+    case DW_AT_small:
+        *s_out = "DW_AT_small";
+        return DW_DLV_OK;
+    case DW_AT_decimal_sign:
+        *s_out = "DW_AT_decimal_sign";
+        return DW_DLV_OK;
+    case DW_AT_digit_count:
+        *s_out = "DW_AT_digit_count";
+        return DW_DLV_OK;
+    case DW_AT_picture_string:
+        *s_out = "DW_AT_picture_string";
+        return DW_DLV_OK;
+    case DW_AT_mutable:
+        *s_out = "DW_AT_mutable";
+        return DW_DLV_OK;
+    case DW_AT_threads_scaled:
+        *s_out = "DW_AT_threads_scaled";
+        return DW_DLV_OK;
+    case DW_AT_explicit:
+        *s_out = "DW_AT_explicit";
+        return DW_DLV_OK;
+    case DW_AT_object_pointer:
+        *s_out = "DW_AT_object_pointer";
+        return DW_DLV_OK;
+    case DW_AT_endianity:
+        *s_out = "DW_AT_endianity";
+        return DW_DLV_OK;
+    case DW_AT_elemental:
+        *s_out = "DW_AT_elemental";
+        return DW_DLV_OK;
+    case DW_AT_pure:
+        *s_out = "DW_AT_pure";
+        return DW_DLV_OK;
+    case DW_AT_recursive:
+        *s_out = "DW_AT_recursive";
+        return DW_DLV_OK;
+    case DW_AT_signature:
+        *s_out = "DW_AT_signature";
+        return DW_DLV_OK;
+    case DW_AT_main_subprogram:
+        *s_out = "DW_AT_main_subprogram";
+        return DW_DLV_OK;
+    case DW_AT_data_bit_offset:
+        *s_out = "DW_AT_data_bit_offset";
+        return DW_DLV_OK;
+    case DW_AT_const_expr:
+        *s_out = "DW_AT_const_expr";
+        return DW_DLV_OK;
+    case DW_AT_enum_class:
+        *s_out = "DW_AT_enum_class";
+        return DW_DLV_OK;
+    case DW_AT_linkage_name:
+        *s_out = "DW_AT_linkage_name";
+        return DW_DLV_OK;
+    case DW_AT_lo_user:
+        *s_out = "DW_AT_lo_user";
+        return DW_DLV_OK;
+    case DW_AT_HP_unmodifiable:
+        *s_out = "DW_AT_HP_unmodifiable";
+        return DW_DLV_OK;
+    case DW_AT_MIPS_loop_begin:
+        *s_out = "DW_AT_MIPS_loop_begin";
+        return DW_DLV_OK;
+    case DW_AT_CPQ_split_lifetimes_var:
+        *s_out = "DW_AT_CPQ_split_lifetimes_var";
+        return DW_DLV_OK;
+    case DW_AT_MIPS_epilog_begin:
+        *s_out = "DW_AT_MIPS_epilog_begin";
+        return DW_DLV_OK;
+    case DW_AT_CPQ_prologue_length:
+        *s_out = "DW_AT_CPQ_prologue_length";
+        return DW_DLV_OK;
+    case DW_AT_MIPS_software_pipeline_depth:
+        *s_out = "DW_AT_MIPS_software_pipeline_depth";
+        return DW_DLV_OK;
+    case DW_AT_MIPS_linkage_name:
+        *s_out = "DW_AT_MIPS_linkage_name";
+        return DW_DLV_OK;
+    case DW_AT_MIPS_stride:
+        *s_out = "DW_AT_MIPS_stride";
+        return DW_DLV_OK;
+    case DW_AT_MIPS_abstract_name:
+        *s_out = "DW_AT_MIPS_abstract_name";
+        return DW_DLV_OK;
+    case DW_AT_MIPS_clone_origin:
+        *s_out = "DW_AT_MIPS_clone_origin";
+        return DW_DLV_OK;
+    case DW_AT_MIPS_has_inlines:
+        *s_out = "DW_AT_MIPS_has_inlines";
+        return DW_DLV_OK;
+    case DW_AT_MIPS_stride_byte:
+        *s_out = "DW_AT_MIPS_stride_byte";
+        return DW_DLV_OK;
+    case DW_AT_MIPS_stride_elem:
+        *s_out = "DW_AT_MIPS_stride_elem";
+        return DW_DLV_OK;
+    case DW_AT_MIPS_ptr_dopetype:
+        *s_out = "DW_AT_MIPS_ptr_dopetype";
+        return DW_DLV_OK;
+    case DW_AT_MIPS_allocatable_dopetype:
+        *s_out = "DW_AT_MIPS_allocatable_dopetype";
+        return DW_DLV_OK;
+    case DW_AT_MIPS_assumed_shape_dopetype:
+        *s_out = "DW_AT_MIPS_assumed_shape_dopetype";
+        return DW_DLV_OK;
+    case DW_AT_HP_proc_per_section:
+        *s_out = "DW_AT_HP_proc_per_section";
+        return DW_DLV_OK;
+    case DW_AT_HP_raw_data_ptr:
+        *s_out = "DW_AT_HP_raw_data_ptr";
+        return DW_DLV_OK;
+    case DW_AT_HP_pass_by_reference:
+        *s_out = "DW_AT_HP_pass_by_reference";
+        return DW_DLV_OK;
+    case DW_AT_HP_opt_level:
+        *s_out = "DW_AT_HP_opt_level";
+        return DW_DLV_OK;
+    case DW_AT_HP_prof_version_id:
+        *s_out = "DW_AT_HP_prof_version_id";
+        return DW_DLV_OK;
+    case DW_AT_HP_opt_flags:
+        *s_out = "DW_AT_HP_opt_flags";
+        return DW_DLV_OK;
+    case DW_AT_HP_cold_region_low_pc:
+        *s_out = "DW_AT_HP_cold_region_low_pc";
+        return DW_DLV_OK;
+    case DW_AT_HP_cold_region_high_pc:
+        *s_out = "DW_AT_HP_cold_region_high_pc";
+        return DW_DLV_OK;
+    case DW_AT_HP_all_variables_modifiable:
+        *s_out = "DW_AT_HP_all_variables_modifiable";
+        return DW_DLV_OK;
+    case DW_AT_HP_linkage_name:
+        *s_out = "DW_AT_HP_linkage_name";
+        return DW_DLV_OK;
+    case DW_AT_HP_prof_flags:
+        *s_out = "DW_AT_HP_prof_flags";
+        return DW_DLV_OK;
+    case DW_AT_INTEL_other_endian:
+        *s_out = "DW_AT_INTEL_other_endian";
+        return DW_DLV_OK;
+    case DW_AT_sf_names:
+        *s_out = "DW_AT_sf_names";
+        return DW_DLV_OK;
+    case DW_AT_src_info:
+        *s_out = "DW_AT_src_info";
+        return DW_DLV_OK;
+    case DW_AT_mac_info:
+        *s_out = "DW_AT_mac_info";
+        return DW_DLV_OK;
+    case DW_AT_src_coords:
+        *s_out = "DW_AT_src_coords";
+        return DW_DLV_OK;
+    case DW_AT_body_begin:
+        *s_out = "DW_AT_body_begin";
+        return DW_DLV_OK;
+    case DW_AT_body_end:
+        *s_out = "DW_AT_body_end";
+        return DW_DLV_OK;
+    case DW_AT_GNU_vector:
+        *s_out = "DW_AT_GNU_vector";
+        return DW_DLV_OK;
+    case DW_AT_GNU_template_name:
+        *s_out = "DW_AT_GNU_template_name";
+        return DW_DLV_OK;
+    case DW_AT_VMS_rtnbeg_pd_address:
+        *s_out = "DW_AT_VMS_rtnbeg_pd_address";
+        return DW_DLV_OK;
+    case DW_AT_SUN_alignment:
+        *s_out = "DW_AT_SUN_alignment";
+        return DW_DLV_OK;
+    case DW_AT_SUN_vtable:
+        *s_out = "DW_AT_SUN_vtable";
+        return DW_DLV_OK;
+    case DW_AT_SUN_count_guarantee:
+        *s_out = "DW_AT_SUN_count_guarantee";
+        return DW_DLV_OK;
+    case DW_AT_SUN_command_line:
+        *s_out = "DW_AT_SUN_command_line";
+        return DW_DLV_OK;
+    case DW_AT_SUN_vbase:
+        *s_out = "DW_AT_SUN_vbase";
+        return DW_DLV_OK;
+    case DW_AT_SUN_compile_options:
+        *s_out = "DW_AT_SUN_compile_options";
+        return DW_DLV_OK;
+    case DW_AT_SUN_language:
+        *s_out = "DW_AT_SUN_language";
+        return DW_DLV_OK;
+    case DW_AT_SUN_browser_file:
+        *s_out = "DW_AT_SUN_browser_file";
+        return DW_DLV_OK;
+    case DW_AT_SUN_vtable_abi:
+        *s_out = "DW_AT_SUN_vtable_abi";
+        return DW_DLV_OK;
+    case DW_AT_SUN_func_offsets:
+        *s_out = "DW_AT_SUN_func_offsets";
+        return DW_DLV_OK;
+    case DW_AT_SUN_cf_kind:
+        *s_out = "DW_AT_SUN_cf_kind";
+        return DW_DLV_OK;
+    case DW_AT_SUN_vtable_index:
+        *s_out = "DW_AT_SUN_vtable_index";
+        return DW_DLV_OK;
+    case DW_AT_SUN_omp_tpriv_addr:
+        *s_out = "DW_AT_SUN_omp_tpriv_addr";
+        return DW_DLV_OK;
+    case DW_AT_SUN_omp_child_func:
+        *s_out = "DW_AT_SUN_omp_child_func";
+        return DW_DLV_OK;
+    case DW_AT_SUN_func_offset:
+        *s_out = "DW_AT_SUN_func_offset";
+        return DW_DLV_OK;
+    case DW_AT_SUN_memop_type_ref:
+        *s_out = "DW_AT_SUN_memop_type_ref";
+        return DW_DLV_OK;
+    case DW_AT_SUN_profile_id:
+        *s_out = "DW_AT_SUN_profile_id";
+        return DW_DLV_OK;
+    case DW_AT_SUN_memop_signature:
+        *s_out = "DW_AT_SUN_memop_signature";
+        return DW_DLV_OK;
+    case DW_AT_SUN_obj_dir:
+        *s_out = "DW_AT_SUN_obj_dir";
+        return DW_DLV_OK;
+    case DW_AT_SUN_obj_file:
+        *s_out = "DW_AT_SUN_obj_file";
+        return DW_DLV_OK;
+    case DW_AT_SUN_original_name:
+        *s_out = "DW_AT_SUN_original_name";
+        return DW_DLV_OK;
+    case DW_AT_SUN_hwcprof_signature:
+        *s_out = "DW_AT_SUN_hwcprof_signature";
+        return DW_DLV_OK;
+    case DW_AT_SUN_amd64_parmdump:
+        *s_out = "DW_AT_SUN_amd64_parmdump";
+        return DW_DLV_OK;
+    case DW_AT_SUN_part_link_name:
+        *s_out = "DW_AT_SUN_part_link_name";
+        return DW_DLV_OK;
+    case DW_AT_SUN_link_name:
+        *s_out = "DW_AT_SUN_link_name";
+        return DW_DLV_OK;
+    case DW_AT_SUN_pass_with_const:
+        *s_out = "DW_AT_SUN_pass_with_const";
+        return DW_DLV_OK;
+    case DW_AT_SUN_return_with_const:
+        *s_out = "DW_AT_SUN_return_with_const";
+        return DW_DLV_OK;
+    case DW_AT_SUN_import_by_name:
+        *s_out = "DW_AT_SUN_import_by_name";
+        return DW_DLV_OK;
+    case DW_AT_SUN_f90_pointer:
+        *s_out = "DW_AT_SUN_f90_pointer";
+        return DW_DLV_OK;
+    case DW_AT_SUN_pass_by_ref:
+        *s_out = "DW_AT_SUN_pass_by_ref";
+        return DW_DLV_OK;
+    case DW_AT_SUN_f90_allocatable:
+        *s_out = "DW_AT_SUN_f90_allocatable";
+        return DW_DLV_OK;
+    case DW_AT_SUN_f90_assumed_shape_array:
+        *s_out = "DW_AT_SUN_f90_assumed_shape_array";
+        return DW_DLV_OK;
+    case DW_AT_SUN_c_vla:
+        *s_out = "DW_AT_SUN_c_vla";
+        return DW_DLV_OK;
+    case DW_AT_SUN_return_value_ptr:
+        *s_out = "DW_AT_SUN_return_value_ptr";
+        return DW_DLV_OK;
+    case DW_AT_SUN_dtor_start:
+        *s_out = "DW_AT_SUN_dtor_start";
+        return DW_DLV_OK;
+    case DW_AT_SUN_dtor_length:
+        *s_out = "DW_AT_SUN_dtor_length";
+        return DW_DLV_OK;
+    case DW_AT_SUN_dtor_state_initial:
+        *s_out = "DW_AT_SUN_dtor_state_initial";
+        return DW_DLV_OK;
+    case DW_AT_SUN_dtor_state_final:
+        *s_out = "DW_AT_SUN_dtor_state_final";
+        return DW_DLV_OK;
+    case DW_AT_SUN_dtor_state_deltas:
+        *s_out = "DW_AT_SUN_dtor_state_deltas";
+        return DW_DLV_OK;
+    case DW_AT_SUN_import_by_lname:
+        *s_out = "DW_AT_SUN_import_by_lname";
+        return DW_DLV_OK;
+    case DW_AT_SUN_f90_use_only:
+        *s_out = "DW_AT_SUN_f90_use_only";
+        return DW_DLV_OK;
+    case DW_AT_SUN_namelist_spec:
+        *s_out = "DW_AT_SUN_namelist_spec";
+        return DW_DLV_OK;
+    case DW_AT_SUN_is_omp_child_func:
+        *s_out = "DW_AT_SUN_is_omp_child_func";
+        return DW_DLV_OK;
+    case DW_AT_SUN_fortran_main_alias:
+        *s_out = "DW_AT_SUN_fortran_main_alias";
+        return DW_DLV_OK;
+    case DW_AT_SUN_fortran_based:
+        *s_out = "DW_AT_SUN_fortran_based";
+        return DW_DLV_OK;
+    case DW_AT_ALTIUM_loclist:
+        *s_out = "DW_AT_ALTIUM_loclist";
+        return DW_DLV_OK;
+    case DW_AT_upc_threads_scaled:
+        *s_out = "DW_AT_upc_threads_scaled";
+        return DW_DLV_OK;
+    case DW_AT_PGI_lbase:
+        *s_out = "DW_AT_PGI_lbase";
+        return DW_DLV_OK;
+    case DW_AT_PGI_soffset:
+        *s_out = "DW_AT_PGI_soffset";
+        return DW_DLV_OK;
+    case DW_AT_PGI_lstride:
+        *s_out = "DW_AT_PGI_lstride";
+        return DW_DLV_OK;
+    case DW_AT_APPLE_closure:
+        *s_out = "DW_AT_APPLE_closure";
+        return DW_DLV_OK;
+    case DW_AT_APPLE_major_runtime_vers:
+        *s_out = "DW_AT_APPLE_major_runtime_vers";
+        return DW_DLV_OK;
+    case DW_AT_APPLE_runtime_class:
+        *s_out = "DW_AT_APPLE_runtime_class";
+        return DW_DLV_OK;
+    case DW_AT_hi_user:
+        *s_out = "DW_AT_hi_user";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_OP_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_OP_addr:
+        *s_out = "DW_OP_addr";
+        return DW_DLV_OK;
+    case DW_OP_deref:
+        *s_out = "DW_OP_deref";
+        return DW_DLV_OK;
+    case DW_OP_const1u:
+        *s_out = "DW_OP_const1u";
+        return DW_DLV_OK;
+    case DW_OP_const1s:
+        *s_out = "DW_OP_const1s";
+        return DW_DLV_OK;
+    case DW_OP_const2u:
+        *s_out = "DW_OP_const2u";
+        return DW_DLV_OK;
+    case DW_OP_const2s:
+        *s_out = "DW_OP_const2s";
+        return DW_DLV_OK;
+    case DW_OP_const4u:
+        *s_out = "DW_OP_const4u";
+        return DW_DLV_OK;
+    case DW_OP_const4s:
+        *s_out = "DW_OP_const4s";
+        return DW_DLV_OK;
+    case DW_OP_const8u:
+        *s_out = "DW_OP_const8u";
+        return DW_DLV_OK;
+    case DW_OP_const8s:
+        *s_out = "DW_OP_const8s";
+        return DW_DLV_OK;
+    case DW_OP_constu:
+        *s_out = "DW_OP_constu";
+        return DW_DLV_OK;
+    case DW_OP_consts:
+        *s_out = "DW_OP_consts";
+        return DW_DLV_OK;
+    case DW_OP_dup:
+        *s_out = "DW_OP_dup";
+        return DW_DLV_OK;
+    case DW_OP_drop:
+        *s_out = "DW_OP_drop";
+        return DW_DLV_OK;
+    case DW_OP_over:
+        *s_out = "DW_OP_over";
+        return DW_DLV_OK;
+    case DW_OP_pick:
+        *s_out = "DW_OP_pick";
+        return DW_DLV_OK;
+    case DW_OP_swap:
+        *s_out = "DW_OP_swap";
+        return DW_DLV_OK;
+    case DW_OP_rot:
+        *s_out = "DW_OP_rot";
+        return DW_DLV_OK;
+    case DW_OP_xderef:
+        *s_out = "DW_OP_xderef";
+        return DW_DLV_OK;
+    case DW_OP_abs:
+        *s_out = "DW_OP_abs";
+        return DW_DLV_OK;
+    case DW_OP_and:
+        *s_out = "DW_OP_and";
+        return DW_DLV_OK;
+    case DW_OP_div:
+        *s_out = "DW_OP_div";
+        return DW_DLV_OK;
+    case DW_OP_minus:
+        *s_out = "DW_OP_minus";
+        return DW_DLV_OK;
+    case DW_OP_mod:
+        *s_out = "DW_OP_mod";
+        return DW_DLV_OK;
+    case DW_OP_mul:
+        *s_out = "DW_OP_mul";
+        return DW_DLV_OK;
+    case DW_OP_neg:
+        *s_out = "DW_OP_neg";
+        return DW_DLV_OK;
+    case DW_OP_not:
+        *s_out = "DW_OP_not";
+        return DW_DLV_OK;
+    case DW_OP_or:
+        *s_out = "DW_OP_or";
+        return DW_DLV_OK;
+    case DW_OP_plus:
+        *s_out = "DW_OP_plus";
+        return DW_DLV_OK;
+    case DW_OP_plus_uconst:
+        *s_out = "DW_OP_plus_uconst";
+        return DW_DLV_OK;
+    case DW_OP_shl:
+        *s_out = "DW_OP_shl";
+        return DW_DLV_OK;
+    case DW_OP_shr:
+        *s_out = "DW_OP_shr";
+        return DW_DLV_OK;
+    case DW_OP_shra:
+        *s_out = "DW_OP_shra";
+        return DW_DLV_OK;
+    case DW_OP_xor:
+        *s_out = "DW_OP_xor";
+        return DW_DLV_OK;
+    case DW_OP_bra:
+        *s_out = "DW_OP_bra";
+        return DW_DLV_OK;
+    case DW_OP_eq:
+        *s_out = "DW_OP_eq";
+        return DW_DLV_OK;
+    case DW_OP_ge:
+        *s_out = "DW_OP_ge";
+        return DW_DLV_OK;
+    case DW_OP_gt:
+        *s_out = "DW_OP_gt";
+        return DW_DLV_OK;
+    case DW_OP_le:
+        *s_out = "DW_OP_le";
+        return DW_DLV_OK;
+    case DW_OP_lt:
+        *s_out = "DW_OP_lt";
+        return DW_DLV_OK;
+    case DW_OP_ne:
+        *s_out = "DW_OP_ne";
+        return DW_DLV_OK;
+    case DW_OP_skip:
+        *s_out = "DW_OP_skip";
+        return DW_DLV_OK;
+    case DW_OP_lit0:
+        *s_out = "DW_OP_lit0";
+        return DW_DLV_OK;
+    case DW_OP_lit1:
+        *s_out = "DW_OP_lit1";
+        return DW_DLV_OK;
+    case DW_OP_lit2:
+        *s_out = "DW_OP_lit2";
+        return DW_DLV_OK;
+    case DW_OP_lit3:
+        *s_out = "DW_OP_lit3";
+        return DW_DLV_OK;
+    case DW_OP_lit4:
+        *s_out = "DW_OP_lit4";
+        return DW_DLV_OK;
+    case DW_OP_lit5:
+        *s_out = "DW_OP_lit5";
+        return DW_DLV_OK;
+    case DW_OP_lit6:
+        *s_out = "DW_OP_lit6";
+        return DW_DLV_OK;
+    case DW_OP_lit7:
+        *s_out = "DW_OP_lit7";
+        return DW_DLV_OK;
+    case DW_OP_lit8:
+        *s_out = "DW_OP_lit8";
+        return DW_DLV_OK;
+    case DW_OP_lit9:
+        *s_out = "DW_OP_lit9";
+        return DW_DLV_OK;
+    case DW_OP_lit10:
+        *s_out = "DW_OP_lit10";
+        return DW_DLV_OK;
+    case DW_OP_lit11:
+        *s_out = "DW_OP_lit11";
+        return DW_DLV_OK;
+    case DW_OP_lit12:
+        *s_out = "DW_OP_lit12";
+        return DW_DLV_OK;
+    case DW_OP_lit13:
+        *s_out = "DW_OP_lit13";
+        return DW_DLV_OK;
+    case DW_OP_lit14:
+        *s_out = "DW_OP_lit14";
+        return DW_DLV_OK;
+    case DW_OP_lit15:
+        *s_out = "DW_OP_lit15";
+        return DW_DLV_OK;
+    case DW_OP_lit16:
+        *s_out = "DW_OP_lit16";
+        return DW_DLV_OK;
+    case DW_OP_lit17:
+        *s_out = "DW_OP_lit17";
+        return DW_DLV_OK;
+    case DW_OP_lit18:
+        *s_out = "DW_OP_lit18";
+        return DW_DLV_OK;
+    case DW_OP_lit19:
+        *s_out = "DW_OP_lit19";
+        return DW_DLV_OK;
+    case DW_OP_lit20:
+        *s_out = "DW_OP_lit20";
+        return DW_DLV_OK;
+    case DW_OP_lit21:
+        *s_out = "DW_OP_lit21";
+        return DW_DLV_OK;
+    case DW_OP_lit22:
+        *s_out = "DW_OP_lit22";
+        return DW_DLV_OK;
+    case DW_OP_lit23:
+        *s_out = "DW_OP_lit23";
+        return DW_DLV_OK;
+    case DW_OP_lit24:
+        *s_out = "DW_OP_lit24";
+        return DW_DLV_OK;
+    case DW_OP_lit25:
+        *s_out = "DW_OP_lit25";
+        return DW_DLV_OK;
+    case DW_OP_lit26:
+        *s_out = "DW_OP_lit26";
+        return DW_DLV_OK;
+    case DW_OP_lit27:
+        *s_out = "DW_OP_lit27";
+        return DW_DLV_OK;
+    case DW_OP_lit28:
+        *s_out = "DW_OP_lit28";
+        return DW_DLV_OK;
+    case DW_OP_lit29:
+        *s_out = "DW_OP_lit29";
+        return DW_DLV_OK;
+    case DW_OP_lit30:
+        *s_out = "DW_OP_lit30";
+        return DW_DLV_OK;
+    case DW_OP_lit31:
+        *s_out = "DW_OP_lit31";
+        return DW_DLV_OK;
+    case DW_OP_reg0:
+        *s_out = "DW_OP_reg0";
+        return DW_DLV_OK;
+    case DW_OP_reg1:
+        *s_out = "DW_OP_reg1";
+        return DW_DLV_OK;
+    case DW_OP_reg2:
+        *s_out = "DW_OP_reg2";
+        return DW_DLV_OK;
+    case DW_OP_reg3:
+        *s_out = "DW_OP_reg3";
+        return DW_DLV_OK;
+    case DW_OP_reg4:
+        *s_out = "DW_OP_reg4";
+        return DW_DLV_OK;
+    case DW_OP_reg5:
+        *s_out = "DW_OP_reg5";
+        return DW_DLV_OK;
+    case DW_OP_reg6:
+        *s_out = "DW_OP_reg6";
+        return DW_DLV_OK;
+    case DW_OP_reg7:
+        *s_out = "DW_OP_reg7";
+        return DW_DLV_OK;
+    case DW_OP_reg8:
+        *s_out = "DW_OP_reg8";
+        return DW_DLV_OK;
+    case DW_OP_reg9:
+        *s_out = "DW_OP_reg9";
+        return DW_DLV_OK;
+    case DW_OP_reg10:
+        *s_out = "DW_OP_reg10";
+        return DW_DLV_OK;
+    case DW_OP_reg11:
+        *s_out = "DW_OP_reg11";
+        return DW_DLV_OK;
+    case DW_OP_reg12:
+        *s_out = "DW_OP_reg12";
+        return DW_DLV_OK;
+    case DW_OP_reg13:
+        *s_out = "DW_OP_reg13";
+        return DW_DLV_OK;
+    case DW_OP_reg14:
+        *s_out = "DW_OP_reg14";
+        return DW_DLV_OK;
+    case DW_OP_reg15:
+        *s_out = "DW_OP_reg15";
+        return DW_DLV_OK;
+    case DW_OP_reg16:
+        *s_out = "DW_OP_reg16";
+        return DW_DLV_OK;
+    case DW_OP_reg17:
+        *s_out = "DW_OP_reg17";
+        return DW_DLV_OK;
+    case DW_OP_reg18:
+        *s_out = "DW_OP_reg18";
+        return DW_DLV_OK;
+    case DW_OP_reg19:
+        *s_out = "DW_OP_reg19";
+        return DW_DLV_OK;
+    case DW_OP_reg20:
+        *s_out = "DW_OP_reg20";
+        return DW_DLV_OK;
+    case DW_OP_reg21:
+        *s_out = "DW_OP_reg21";
+        return DW_DLV_OK;
+    case DW_OP_reg22:
+        *s_out = "DW_OP_reg22";
+        return DW_DLV_OK;
+    case DW_OP_reg23:
+        *s_out = "DW_OP_reg23";
+        return DW_DLV_OK;
+    case DW_OP_reg24:
+        *s_out = "DW_OP_reg24";
+        return DW_DLV_OK;
+    case DW_OP_reg25:
+        *s_out = "DW_OP_reg25";
+        return DW_DLV_OK;
+    case DW_OP_reg26:
+        *s_out = "DW_OP_reg26";
+        return DW_DLV_OK;
+    case DW_OP_reg27:
+        *s_out = "DW_OP_reg27";
+        return DW_DLV_OK;
+    case DW_OP_reg28:
+        *s_out = "DW_OP_reg28";
+        return DW_DLV_OK;
+    case DW_OP_reg29:
+        *s_out = "DW_OP_reg29";
+        return DW_DLV_OK;
+    case DW_OP_reg30:
+        *s_out = "DW_OP_reg30";
+        return DW_DLV_OK;
+    case DW_OP_reg31:
+        *s_out = "DW_OP_reg31";
+        return DW_DLV_OK;
+    case DW_OP_breg0:
+        *s_out = "DW_OP_breg0";
+        return DW_DLV_OK;
+    case DW_OP_breg1:
+        *s_out = "DW_OP_breg1";
+        return DW_DLV_OK;
+    case DW_OP_breg2:
+        *s_out = "DW_OP_breg2";
+        return DW_DLV_OK;
+    case DW_OP_breg3:
+        *s_out = "DW_OP_breg3";
+        return DW_DLV_OK;
+    case DW_OP_breg4:
+        *s_out = "DW_OP_breg4";
+        return DW_DLV_OK;
+    case DW_OP_breg5:
+        *s_out = "DW_OP_breg5";
+        return DW_DLV_OK;
+    case DW_OP_breg6:
+        *s_out = "DW_OP_breg6";
+        return DW_DLV_OK;
+    case DW_OP_breg7:
+        *s_out = "DW_OP_breg7";
+        return DW_DLV_OK;
+    case DW_OP_breg8:
+        *s_out = "DW_OP_breg8";
+        return DW_DLV_OK;
+    case DW_OP_breg9:
+        *s_out = "DW_OP_breg9";
+        return DW_DLV_OK;
+    case DW_OP_breg10:
+        *s_out = "DW_OP_breg10";
+        return DW_DLV_OK;
+    case DW_OP_breg11:
+        *s_out = "DW_OP_breg11";
+        return DW_DLV_OK;
+    case DW_OP_breg12:
+        *s_out = "DW_OP_breg12";
+        return DW_DLV_OK;
+    case DW_OP_breg13:
+        *s_out = "DW_OP_breg13";
+        return DW_DLV_OK;
+    case DW_OP_breg14:
+        *s_out = "DW_OP_breg14";
+        return DW_DLV_OK;
+    case DW_OP_breg15:
+        *s_out = "DW_OP_breg15";
+        return DW_DLV_OK;
+    case DW_OP_breg16:
+        *s_out = "DW_OP_breg16";
+        return DW_DLV_OK;
+    case DW_OP_breg17:
+        *s_out = "DW_OP_breg17";
+        return DW_DLV_OK;
+    case DW_OP_breg18:
+        *s_out = "DW_OP_breg18";
+        return DW_DLV_OK;
+    case DW_OP_breg19:
+        *s_out = "DW_OP_breg19";
+        return DW_DLV_OK;
+    case DW_OP_breg20:
+        *s_out = "DW_OP_breg20";
+        return DW_DLV_OK;
+    case DW_OP_breg21:
+        *s_out = "DW_OP_breg21";
+        return DW_DLV_OK;
+    case DW_OP_breg22:
+        *s_out = "DW_OP_breg22";
+        return DW_DLV_OK;
+    case DW_OP_breg23:
+        *s_out = "DW_OP_breg23";
+        return DW_DLV_OK;
+    case DW_OP_breg24:
+        *s_out = "DW_OP_breg24";
+        return DW_DLV_OK;
+    case DW_OP_breg25:
+        *s_out = "DW_OP_breg25";
+        return DW_DLV_OK;
+    case DW_OP_breg26:
+        *s_out = "DW_OP_breg26";
+        return DW_DLV_OK;
+    case DW_OP_breg27:
+        *s_out = "DW_OP_breg27";
+        return DW_DLV_OK;
+    case DW_OP_breg28:
+        *s_out = "DW_OP_breg28";
+        return DW_DLV_OK;
+    case DW_OP_breg29:
+        *s_out = "DW_OP_breg29";
+        return DW_DLV_OK;
+    case DW_OP_breg30:
+        *s_out = "DW_OP_breg30";
+        return DW_DLV_OK;
+    case DW_OP_breg31:
+        *s_out = "DW_OP_breg31";
+        return DW_DLV_OK;
+    case DW_OP_regx:
+        *s_out = "DW_OP_regx";
+        return DW_DLV_OK;
+    case DW_OP_fbreg:
+        *s_out = "DW_OP_fbreg";
+        return DW_DLV_OK;
+    case DW_OP_bregx:
+        *s_out = "DW_OP_bregx";
+        return DW_DLV_OK;
+    case DW_OP_piece:
+        *s_out = "DW_OP_piece";
+        return DW_DLV_OK;
+    case DW_OP_deref_size:
+        *s_out = "DW_OP_deref_size";
+        return DW_DLV_OK;
+    case DW_OP_xderef_size:
+        *s_out = "DW_OP_xderef_size";
+        return DW_DLV_OK;
+    case DW_OP_nop:
+        *s_out = "DW_OP_nop";
+        return DW_DLV_OK;
+    case DW_OP_push_object_address:
+        *s_out = "DW_OP_push_object_address";
+        return DW_DLV_OK;
+    case DW_OP_call2:
+        *s_out = "DW_OP_call2";
+        return DW_DLV_OK;
+    case DW_OP_call4:
+        *s_out = "DW_OP_call4";
+        return DW_DLV_OK;
+    case DW_OP_call_ref:
+        *s_out = "DW_OP_call_ref";
+        return DW_DLV_OK;
+    case DW_OP_form_tls_address:
+        *s_out = "DW_OP_form_tls_address";
+        return DW_DLV_OK;
+    case DW_OP_call_frame_cfa:
+        *s_out = "DW_OP_call_frame_cfa";
+        return DW_DLV_OK;
+    case DW_OP_bit_piece:
+        *s_out = "DW_OP_bit_piece";
+        return DW_DLV_OK;
+    case DW_OP_implicit_value:
+        *s_out = "DW_OP_implicit_value";
+        return DW_DLV_OK;
+    case DW_OP_stack_value:
+        *s_out = "DW_OP_stack_value";
+        return DW_DLV_OK;
+    case DW_OP_lo_user:
+        *s_out = "DW_OP_lo_user";
+        return DW_DLV_OK;
+    case DW_OP_HP_is_value:
+        *s_out = "DW_OP_HP_is_value";
+        return DW_DLV_OK;
+    case DW_OP_HP_fltconst4:
+        *s_out = "DW_OP_HP_fltconst4";
+        return DW_DLV_OK;
+    case DW_OP_HP_fltconst8:
+        *s_out = "DW_OP_HP_fltconst8";
+        return DW_DLV_OK;
+    case DW_OP_HP_mod_range:
+        *s_out = "DW_OP_HP_mod_range";
+        return DW_DLV_OK;
+    case DW_OP_HP_unmod_range:
+        *s_out = "DW_OP_HP_unmod_range";
+        return DW_DLV_OK;
+    case DW_OP_HP_tls:
+        *s_out = "DW_OP_HP_tls";
+        return DW_DLV_OK;
+    case DW_OP_INTEL_bit_piece:
+        *s_out = "DW_OP_INTEL_bit_piece";
+        return DW_DLV_OK;
+    case DW_OP_APPLE_uninit:
+        *s_out = "DW_OP_APPLE_uninit";
+        return DW_DLV_OK;
+    case DW_OP_hi_user:
+        *s_out = "DW_OP_hi_user";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_ATE_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_ATE_address:
+        *s_out = "DW_ATE_address";
+        return DW_DLV_OK;
+    case DW_ATE_boolean:
+        *s_out = "DW_ATE_boolean";
+        return DW_DLV_OK;
+    case DW_ATE_complex_float:
+        *s_out = "DW_ATE_complex_float";
+        return DW_DLV_OK;
+    case DW_ATE_float:
+        *s_out = "DW_ATE_float";
+        return DW_DLV_OK;
+    case DW_ATE_signed:
+        *s_out = "DW_ATE_signed";
+        return DW_DLV_OK;
+    case DW_ATE_signed_char:
+        *s_out = "DW_ATE_signed_char";
+        return DW_DLV_OK;
+    case DW_ATE_unsigned:
+        *s_out = "DW_ATE_unsigned";
+        return DW_DLV_OK;
+    case DW_ATE_unsigned_char:
+        *s_out = "DW_ATE_unsigned_char";
+        return DW_DLV_OK;
+    case DW_ATE_imaginary_float:
+        *s_out = "DW_ATE_imaginary_float";
+        return DW_DLV_OK;
+    case DW_ATE_packed_decimal:
+        *s_out = "DW_ATE_packed_decimal";
+        return DW_DLV_OK;
+    case DW_ATE_numeric_string:
+        *s_out = "DW_ATE_numeric_string";
+        return DW_DLV_OK;
+    case DW_ATE_edited:
+        *s_out = "DW_ATE_edited";
+        return DW_DLV_OK;
+    case DW_ATE_signed_fixed:
+        *s_out = "DW_ATE_signed_fixed";
+        return DW_DLV_OK;
+    case DW_ATE_unsigned_fixed:
+        *s_out = "DW_ATE_unsigned_fixed";
+        return DW_DLV_OK;
+    case DW_ATE_decimal_float:
+        *s_out = "DW_ATE_decimal_float";
+        return DW_DLV_OK;
+    case DW_ATE_HP_float80:
+        *s_out = "DW_ATE_HP_float80";
+        return DW_DLV_OK;
+    case DW_ATE_HP_complex_float80:
+        *s_out = "DW_ATE_HP_complex_float80";
+        return DW_DLV_OK;
+    case DW_ATE_HP_float128:
+        *s_out = "DW_ATE_HP_float128";
+        return DW_DLV_OK;
+    case DW_ATE_HP_complex_float128:
+        *s_out = "DW_ATE_HP_complex_float128";
+        return DW_DLV_OK;
+    case DW_ATE_HP_floathpintel:
+        *s_out = "DW_ATE_HP_floathpintel";
+        return DW_DLV_OK;
+    case DW_ATE_HP_imaginary_float80:
+        *s_out = "DW_ATE_HP_imaginary_float80";
+        return DW_DLV_OK;
+    case DW_ATE_HP_imaginary_float128:
+        *s_out = "DW_ATE_HP_imaginary_float128";
+        return DW_DLV_OK;
+    case DW_ATE_SUN_interval_float:
+        *s_out = "DW_ATE_SUN_interval_float";
+        return DW_DLV_OK;
+    case DW_ATE_SUN_imaginary_float:
+        *s_out = "DW_ATE_SUN_imaginary_float";
+        return DW_DLV_OK;
+    case DW_ATE_hi_user:
+        *s_out = "DW_ATE_hi_user";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_DS_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_DS_unsigned:
+        *s_out = "DW_DS_unsigned";
+        return DW_DLV_OK;
+    case DW_DS_leading_overpunch:
+        *s_out = "DW_DS_leading_overpunch";
+        return DW_DLV_OK;
+    case DW_DS_trailing_overpunch:
+        *s_out = "DW_DS_trailing_overpunch";
+        return DW_DLV_OK;
+    case DW_DS_leading_separate:
+        *s_out = "DW_DS_leading_separate";
+        return DW_DLV_OK;
+    case DW_DS_trailing_separate:
+        *s_out = "DW_DS_trailing_separate";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_END_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_END_default:
+        *s_out = "DW_END_default";
+        return DW_DLV_OK;
+    case DW_END_big:
+        *s_out = "DW_END_big";
+        return DW_DLV_OK;
+    case DW_END_little:
+        *s_out = "DW_END_little";
+        return DW_DLV_OK;
+    case DW_END_lo_user:
+        *s_out = "DW_END_lo_user";
+        return DW_DLV_OK;
+    case DW_END_hi_user:
+        *s_out = "DW_END_hi_user";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_ATCF_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_ATCF_lo_user:
+        *s_out = "DW_ATCF_lo_user";
+        return DW_DLV_OK;
+    case DW_ATCF_SUN_mop_bitfield:
+        *s_out = "DW_ATCF_SUN_mop_bitfield";
+        return DW_DLV_OK;
+    case DW_ATCF_SUN_mop_spill:
+        *s_out = "DW_ATCF_SUN_mop_spill";
+        return DW_DLV_OK;
+    case DW_ATCF_SUN_mop_scopy:
+        *s_out = "DW_ATCF_SUN_mop_scopy";
+        return DW_DLV_OK;
+    case DW_ATCF_SUN_func_start:
+        *s_out = "DW_ATCF_SUN_func_start";
+        return DW_DLV_OK;
+    case DW_ATCF_SUN_end_ctors:
+        *s_out = "DW_ATCF_SUN_end_ctors";
+        return DW_DLV_OK;
+    case DW_ATCF_SUN_branch_target:
+        *s_out = "DW_ATCF_SUN_branch_target";
+        return DW_DLV_OK;
+    case DW_ATCF_SUN_mop_stack_probe:
+        *s_out = "DW_ATCF_SUN_mop_stack_probe";
+        return DW_DLV_OK;
+    case DW_ATCF_SUN_func_epilog:
+        *s_out = "DW_ATCF_SUN_func_epilog";
+        return DW_DLV_OK;
+    case DW_ATCF_hi_user:
+        *s_out = "DW_ATCF_hi_user";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_ACCESS_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_ACCESS_public:
+        *s_out = "DW_ACCESS_public";
+        return DW_DLV_OK;
+    case DW_ACCESS_protected:
+        *s_out = "DW_ACCESS_protected";
+        return DW_DLV_OK;
+    case DW_ACCESS_private:
+        *s_out = "DW_ACCESS_private";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_VIS_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_VIS_local:
+        *s_out = "DW_VIS_local";
+        return DW_DLV_OK;
+    case DW_VIS_exported:
+        *s_out = "DW_VIS_exported";
+        return DW_DLV_OK;
+    case DW_VIS_qualified:
+        *s_out = "DW_VIS_qualified";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_VIRTUALITY_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_VIRTUALITY_none:
+        *s_out = "DW_VIRTUALITY_none";
+        return DW_DLV_OK;
+    case DW_VIRTUALITY_virtual:
+        *s_out = "DW_VIRTUALITY_virtual";
+        return DW_DLV_OK;
+    case DW_VIRTUALITY_pure_virtual:
+        *s_out = "DW_VIRTUALITY_pure_virtual";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_LANG_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_LANG_C89:
+        *s_out = "DW_LANG_C89";
+        return DW_DLV_OK;
+    case DW_LANG_C:
+        *s_out = "DW_LANG_C";
+        return DW_DLV_OK;
+    case DW_LANG_Ada83:
+        *s_out = "DW_LANG_Ada83";
+        return DW_DLV_OK;
+    case DW_LANG_C_plus_plus:
+        *s_out = "DW_LANG_C_plus_plus";
+        return DW_DLV_OK;
+    case DW_LANG_Cobol74:
+        *s_out = "DW_LANG_Cobol74";
+        return DW_DLV_OK;
+    case DW_LANG_Cobol85:
+        *s_out = "DW_LANG_Cobol85";
+        return DW_DLV_OK;
+    case DW_LANG_Fortran77:
+        *s_out = "DW_LANG_Fortran77";
+        return DW_DLV_OK;
+    case DW_LANG_Fortran90:
+        *s_out = "DW_LANG_Fortran90";
+        return DW_DLV_OK;
+    case DW_LANG_Pascal83:
+        *s_out = "DW_LANG_Pascal83";
+        return DW_DLV_OK;
+    case DW_LANG_Modula2:
+        *s_out = "DW_LANG_Modula2";
+        return DW_DLV_OK;
+    case DW_LANG_Java:
+        *s_out = "DW_LANG_Java";
+        return DW_DLV_OK;
+    case DW_LANG_C99:
+        *s_out = "DW_LANG_C99";
+        return DW_DLV_OK;
+    case DW_LANG_Ada95:
+        *s_out = "DW_LANG_Ada95";
+        return DW_DLV_OK;
+    case DW_LANG_Fortran95:
+        *s_out = "DW_LANG_Fortran95";
+        return DW_DLV_OK;
+    case DW_LANG_PLI:
+        *s_out = "DW_LANG_PLI";
+        return DW_DLV_OK;
+    case DW_LANG_ObjC:
+        *s_out = "DW_LANG_ObjC";
+        return DW_DLV_OK;
+    case DW_LANG_ObjC_plus_plus:
+        *s_out = "DW_LANG_ObjC_plus_plus";
+        return DW_DLV_OK;
+    case DW_LANG_UPC:
+        *s_out = "DW_LANG_UPC";
+        return DW_DLV_OK;
+    case DW_LANG_D:
+        *s_out = "DW_LANG_D";
+        return DW_DLV_OK;
+    case DW_LANG_Python:
+        *s_out = "DW_LANG_Python";
+        return DW_DLV_OK;
+    case DW_LANG_OpenCL:
+        *s_out = "DW_LANG_OpenCL";
+        return DW_DLV_OK;
+    case DW_LANG_Go:
+        *s_out = "DW_LANG_Go";
+        return DW_DLV_OK;
+    case DW_LANG_lo_user:
+        *s_out = "DW_LANG_lo_user";
+        return DW_DLV_OK;
+    case DW_LANG_Mips_Assembler:
+        *s_out = "DW_LANG_Mips_Assembler";
+        return DW_DLV_OK;
+    case DW_LANG_Upc:
+        *s_out = "DW_LANG_Upc";
+        return DW_DLV_OK;
+    case DW_LANG_SUN_Assembler:
+        *s_out = "DW_LANG_SUN_Assembler";
+        return DW_DLV_OK;
+    case DW_LANG_ALTIUM_Assembler:
+        *s_out = "DW_LANG_ALTIUM_Assembler";
+        return DW_DLV_OK;
+    case DW_LANG_hi_user:
+        *s_out = "DW_LANG_hi_user";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_ID_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_ID_case_sensitive:
+        *s_out = "DW_ID_case_sensitive";
+        return DW_DLV_OK;
+    case DW_ID_up_case:
+        *s_out = "DW_ID_up_case";
+        return DW_DLV_OK;
+    case DW_ID_down_case:
+        *s_out = "DW_ID_down_case";
+        return DW_DLV_OK;
+    case DW_ID_case_insensitive:
+        *s_out = "DW_ID_case_insensitive";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_CC_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_CC_normal:
+        *s_out = "DW_CC_normal";
+        return DW_DLV_OK;
+    case DW_CC_program:
+        *s_out = "DW_CC_program";
+        return DW_DLV_OK;
+    case DW_CC_nocall:
+        *s_out = "DW_CC_nocall";
+        return DW_DLV_OK;
+    case DW_CC_lo_user:
+        *s_out = "DW_CC_lo_user";
+        return DW_DLV_OK;
+    case DW_CC_ALTIUM_interrupt:
+        *s_out = "DW_CC_ALTIUM_interrupt";
+        return DW_DLV_OK;
+    case DW_CC_ALTIUM_near_system_stack:
+        *s_out = "DW_CC_ALTIUM_near_system_stack";
+        return DW_DLV_OK;
+    case DW_CC_ALTIUM_near_user_stack:
+        *s_out = "DW_CC_ALTIUM_near_user_stack";
+        return DW_DLV_OK;
+    case DW_CC_ALTIUM_huge_user_stack:
+        *s_out = "DW_CC_ALTIUM_huge_user_stack";
+        return DW_DLV_OK;
+    case DW_CC_hi_user:
+        *s_out = "DW_CC_hi_user";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_INL_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_INL_not_inlined:
+        *s_out = "DW_INL_not_inlined";
+        return DW_DLV_OK;
+    case DW_INL_inlined:
+        *s_out = "DW_INL_inlined";
+        return DW_DLV_OK;
+    case DW_INL_declared_not_inlined:
+        *s_out = "DW_INL_declared_not_inlined";
+        return DW_DLV_OK;
+    case DW_INL_declared_inlined:
+        *s_out = "DW_INL_declared_inlined";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_ORD_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_ORD_row_major:
+        *s_out = "DW_ORD_row_major";
+        return DW_DLV_OK;
+    case DW_ORD_col_major:
+        *s_out = "DW_ORD_col_major";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_DSC_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_DSC_label:
+        *s_out = "DW_DSC_label";
+        return DW_DLV_OK;
+    case DW_DSC_range:
+        *s_out = "DW_DSC_range";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_LNS_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_LNS_copy:
+        *s_out = "DW_LNS_copy";
+        return DW_DLV_OK;
+    case DW_LNS_advance_pc:
+        *s_out = "DW_LNS_advance_pc";
+        return DW_DLV_OK;
+    case DW_LNS_advance_line:
+        *s_out = "DW_LNS_advance_line";
+        return DW_DLV_OK;
+    case DW_LNS_set_file:
+        *s_out = "DW_LNS_set_file";
+        return DW_DLV_OK;
+    case DW_LNS_set_column:
+        *s_out = "DW_LNS_set_column";
+        return DW_DLV_OK;
+    case DW_LNS_negate_stmt:
+        *s_out = "DW_LNS_negate_stmt";
+        return DW_DLV_OK;
+    case DW_LNS_set_basic_block:
+        *s_out = "DW_LNS_set_basic_block";
+        return DW_DLV_OK;
+    case DW_LNS_const_add_pc:
+        *s_out = "DW_LNS_const_add_pc";
+        return DW_DLV_OK;
+    case DW_LNS_fixed_advance_pc:
+        *s_out = "DW_LNS_fixed_advance_pc";
+        return DW_DLV_OK;
+    case DW_LNS_set_prologue_end:
+        *s_out = "DW_LNS_set_prologue_end";
+        return DW_DLV_OK;
+    case DW_LNS_set_epilogue_begin:
+        *s_out = "DW_LNS_set_epilogue_begin";
+        return DW_DLV_OK;
+    case DW_LNS_set_isa:
+        *s_out = "DW_LNS_set_isa";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_LNE_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_LNE_end_sequence:
+        *s_out = "DW_LNE_end_sequence";
+        return DW_DLV_OK;
+    case DW_LNE_set_address:
+        *s_out = "DW_LNE_set_address";
+        return DW_DLV_OK;
+    case DW_LNE_define_file:
+        *s_out = "DW_LNE_define_file";
+        return DW_DLV_OK;
+    case DW_LNE_set_discriminator:
+        *s_out = "DW_LNE_set_discriminator";
+        return DW_DLV_OK;
+    case DW_LNE_HP_negate_is_UV_update:
+        *s_out = "DW_LNE_HP_negate_is_UV_update";
+        return DW_DLV_OK;
+    case DW_LNE_HP_push_context:
+        *s_out = "DW_LNE_HP_push_context";
+        return DW_DLV_OK;
+    case DW_LNE_HP_pop_context:
+        *s_out = "DW_LNE_HP_pop_context";
+        return DW_DLV_OK;
+    case DW_LNE_HP_set_file_line_column:
+        *s_out = "DW_LNE_HP_set_file_line_column";
+        return DW_DLV_OK;
+    case DW_LNE_HP_set_routine_name:
+        *s_out = "DW_LNE_HP_set_routine_name";
+        return DW_DLV_OK;
+    case DW_LNE_HP_set_sequence:
+        *s_out = "DW_LNE_HP_set_sequence";
+        return DW_DLV_OK;
+    case DW_LNE_HP_negate_post_semantics:
+        *s_out = "DW_LNE_HP_negate_post_semantics";
+        return DW_DLV_OK;
+    case DW_LNE_HP_negate_function_exit:
+        *s_out = "DW_LNE_HP_negate_function_exit";
+        return DW_DLV_OK;
+    case DW_LNE_HP_negate_front_end_logical:
+        *s_out = "DW_LNE_HP_negate_front_end_logical";
+        return DW_DLV_OK;
+    case DW_LNE_HP_define_proc:
+        *s_out = "DW_LNE_HP_define_proc";
+        return DW_DLV_OK;
+    case DW_LNE_lo_user:
+        *s_out = "DW_LNE_lo_user";
+        return DW_DLV_OK;
+    case DW_LNE_hi_user:
+        *s_out = "DW_LNE_hi_user";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_ISA_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_ISA_UNKNOWN:
+        *s_out = "DW_ISA_UNKNOWN";
+        return DW_DLV_OK;
+    case DW_ISA_ARM_thumb:
+        *s_out = "DW_ISA_ARM_thumb";
+        return DW_DLV_OK;
+    case DW_ISA_ARM_arm:
+        *s_out = "DW_ISA_ARM_arm";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_MACINFO_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_MACINFO_define:
+        *s_out = "DW_MACINFO_define";
+        return DW_DLV_OK;
+    case DW_MACINFO_undef:
+        *s_out = "DW_MACINFO_undef";
+        return DW_DLV_OK;
+    case DW_MACINFO_start_file:
+        *s_out = "DW_MACINFO_start_file";
+        return DW_DLV_OK;
+    case DW_MACINFO_end_file:
+        *s_out = "DW_MACINFO_end_file";
+        return DW_DLV_OK;
+    case DW_MACINFO_vendor_ext:
+        *s_out = "DW_MACINFO_vendor_ext";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_CFA_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_CFA_extended:
+        *s_out = "DW_CFA_extended";
+        return DW_DLV_OK;
+    case DW_CFA_set_loc:
+        *s_out = "DW_CFA_set_loc";
+        return DW_DLV_OK;
+    case DW_CFA_advance_loc1:
+        *s_out = "DW_CFA_advance_loc1";
+        return DW_DLV_OK;
+    case DW_CFA_advance_loc2:
+        *s_out = "DW_CFA_advance_loc2";
+        return DW_DLV_OK;
+    case DW_CFA_advance_loc4:
+        *s_out = "DW_CFA_advance_loc4";
+        return DW_DLV_OK;
+    case DW_CFA_offset_extended:
+        *s_out = "DW_CFA_offset_extended";
+        return DW_DLV_OK;
+    case DW_CFA_restore_extended:
+        *s_out = "DW_CFA_restore_extended";
+        return DW_DLV_OK;
+    case DW_CFA_undefined:
+        *s_out = "DW_CFA_undefined";
+        return DW_DLV_OK;
+    case DW_CFA_same_value:
+        *s_out = "DW_CFA_same_value";
+        return DW_DLV_OK;
+    case DW_CFA_register:
+        *s_out = "DW_CFA_register";
+        return DW_DLV_OK;
+    case DW_CFA_remember_state:
+        *s_out = "DW_CFA_remember_state";
+        return DW_DLV_OK;
+    case DW_CFA_restore_state:
+        *s_out = "DW_CFA_restore_state";
+        return DW_DLV_OK;
+    case DW_CFA_def_cfa:
+        *s_out = "DW_CFA_def_cfa";
+        return DW_DLV_OK;
+    case DW_CFA_def_cfa_register:
+        *s_out = "DW_CFA_def_cfa_register";
+        return DW_DLV_OK;
+    case DW_CFA_def_cfa_offset:
+        *s_out = "DW_CFA_def_cfa_offset";
+        return DW_DLV_OK;
+    case DW_CFA_def_cfa_expression:
+        *s_out = "DW_CFA_def_cfa_expression";
+        return DW_DLV_OK;
+    case DW_CFA_expression:
+        *s_out = "DW_CFA_expression";
+        return DW_DLV_OK;
+    case DW_CFA_offset_extended_sf:
+        *s_out = "DW_CFA_offset_extended_sf";
+        return DW_DLV_OK;
+    case DW_CFA_def_cfa_sf:
+        *s_out = "DW_CFA_def_cfa_sf";
+        return DW_DLV_OK;
+    case DW_CFA_def_cfa_offset_sf:
+        *s_out = "DW_CFA_def_cfa_offset_sf";
+        return DW_DLV_OK;
+    case DW_CFA_val_offset:
+        *s_out = "DW_CFA_val_offset";
+        return DW_DLV_OK;
+    case DW_CFA_val_offset_sf:
+        *s_out = "DW_CFA_val_offset_sf";
+        return DW_DLV_OK;
+    case DW_CFA_val_expression:
+        *s_out = "DW_CFA_val_expression";
+        return DW_DLV_OK;
+    case DW_CFA_lo_user:
+        *s_out = "DW_CFA_lo_user";
+        return DW_DLV_OK;
+    case DW_CFA_MIPS_advance_loc8:
+        *s_out = "DW_CFA_MIPS_advance_loc8";
+        return DW_DLV_OK;
+    case DW_CFA_GNU_window_save:
+        *s_out = "DW_CFA_GNU_window_save";
+        return DW_DLV_OK;
+    case DW_CFA_GNU_args_size:
+        *s_out = "DW_CFA_GNU_args_size";
+        return DW_DLV_OK;
+    case DW_CFA_GNU_negative_offset_extended:
+        *s_out = "DW_CFA_GNU_negative_offset_extended";
+        return DW_DLV_OK;
+    case DW_CFA_high_user:
+        *s_out = "DW_CFA_high_user";
+        return DW_DLV_OK;
+    case DW_CFA_advance_loc:
+        *s_out = "DW_CFA_advance_loc";
+        return DW_DLV_OK;
+    case DW_CFA_offset:
+        *s_out = "DW_CFA_offset";
+        return DW_DLV_OK;
+    case DW_CFA_restore:
+        *s_out = "DW_CFA_restore";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_EH_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_EH_PE_absptr:
+        *s_out = "DW_EH_PE_absptr";
+        return DW_DLV_OK;
+    case DW_EH_PE_uleb128:
+        *s_out = "DW_EH_PE_uleb128";
+        return DW_DLV_OK;
+    case DW_EH_PE_udata2:
+        *s_out = "DW_EH_PE_udata2";
+        return DW_DLV_OK;
+    case DW_EH_PE_udata4:
+        *s_out = "DW_EH_PE_udata4";
+        return DW_DLV_OK;
+    case DW_EH_PE_udata8:
+        *s_out = "DW_EH_PE_udata8";
+        return DW_DLV_OK;
+    case DW_EH_PE_sleb128:
+        *s_out = "DW_EH_PE_sleb128";
+        return DW_DLV_OK;
+    case DW_EH_PE_sdata2:
+        *s_out = "DW_EH_PE_sdata2";
+        return DW_DLV_OK;
+    case DW_EH_PE_sdata4:
+        *s_out = "DW_EH_PE_sdata4";
+        return DW_DLV_OK;
+    case DW_EH_PE_sdata8:
+        *s_out = "DW_EH_PE_sdata8";
+        return DW_DLV_OK;
+    case DW_EH_PE_pcrel:
+        *s_out = "DW_EH_PE_pcrel";
+        return DW_DLV_OK;
+    case DW_EH_PE_textrel:
+        *s_out = "DW_EH_PE_textrel";
+        return DW_DLV_OK;
+    case DW_EH_PE_datarel:
+        *s_out = "DW_EH_PE_datarel";
+        return DW_DLV_OK;
+    case DW_EH_PE_funcrel:
+        *s_out = "DW_EH_PE_funcrel";
+        return DW_DLV_OK;
+    case DW_EH_PE_aligned:
+        *s_out = "DW_EH_PE_aligned";
+        return DW_DLV_OK;
+    case DW_EH_PE_omit:
+        *s_out = "DW_EH_PE_omit";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_FRAME_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_FRAME_CFA_COL:
+        *s_out = "DW_FRAME_CFA_COL";
+        return DW_DLV_OK;
+    case DW_FRAME_REG1:
+        *s_out = "DW_FRAME_REG1";
+        return DW_DLV_OK;
+    case DW_FRAME_REG2:
+        *s_out = "DW_FRAME_REG2";
+        return DW_DLV_OK;
+    case DW_FRAME_REG3:
+        *s_out = "DW_FRAME_REG3";
+        return DW_DLV_OK;
+    case DW_FRAME_REG4:
+        *s_out = "DW_FRAME_REG4";
+        return DW_DLV_OK;
+    case DW_FRAME_REG5:
+        *s_out = "DW_FRAME_REG5";
+        return DW_DLV_OK;
+    case DW_FRAME_REG6:
+        *s_out = "DW_FRAME_REG6";
+        return DW_DLV_OK;
+    case DW_FRAME_REG7:
+        *s_out = "DW_FRAME_REG7";
+        return DW_DLV_OK;
+    case DW_FRAME_REG8:
+        *s_out = "DW_FRAME_REG8";
+        return DW_DLV_OK;
+    case DW_FRAME_REG9:
+        *s_out = "DW_FRAME_REG9";
+        return DW_DLV_OK;
+    case DW_FRAME_REG10:
+        *s_out = "DW_FRAME_REG10";
+        return DW_DLV_OK;
+    case DW_FRAME_REG11:
+        *s_out = "DW_FRAME_REG11";
+        return DW_DLV_OK;
+    case DW_FRAME_REG12:
+        *s_out = "DW_FRAME_REG12";
+        return DW_DLV_OK;
+    case DW_FRAME_REG13:
+        *s_out = "DW_FRAME_REG13";
+        return DW_DLV_OK;
+    case DW_FRAME_REG14:
+        *s_out = "DW_FRAME_REG14";
+        return DW_DLV_OK;
+    case DW_FRAME_REG15:
+        *s_out = "DW_FRAME_REG15";
+        return DW_DLV_OK;
+    case DW_FRAME_REG16:
+        *s_out = "DW_FRAME_REG16";
+        return DW_DLV_OK;
+    case DW_FRAME_REG17:
+        *s_out = "DW_FRAME_REG17";
+        return DW_DLV_OK;
+    case DW_FRAME_REG18:
+        *s_out = "DW_FRAME_REG18";
+        return DW_DLV_OK;
+    case DW_FRAME_REG19:
+        *s_out = "DW_FRAME_REG19";
+        return DW_DLV_OK;
+    case DW_FRAME_REG20:
+        *s_out = "DW_FRAME_REG20";
+        return DW_DLV_OK;
+    case DW_FRAME_REG21:
+        *s_out = "DW_FRAME_REG21";
+        return DW_DLV_OK;
+    case DW_FRAME_REG22:
+        *s_out = "DW_FRAME_REG22";
+        return DW_DLV_OK;
+    case DW_FRAME_REG23:
+        *s_out = "DW_FRAME_REG23";
+        return DW_DLV_OK;
+    case DW_FRAME_REG24:
+        *s_out = "DW_FRAME_REG24";
+        return DW_DLV_OK;
+    case DW_FRAME_REG25:
+        *s_out = "DW_FRAME_REG25";
+        return DW_DLV_OK;
+    case DW_FRAME_REG26:
+        *s_out = "DW_FRAME_REG26";
+        return DW_DLV_OK;
+    case DW_FRAME_REG27:
+        *s_out = "DW_FRAME_REG27";
+        return DW_DLV_OK;
+    case DW_FRAME_REG28:
+        *s_out = "DW_FRAME_REG28";
+        return DW_DLV_OK;
+    case DW_FRAME_REG29:
+        *s_out = "DW_FRAME_REG29";
+        return DW_DLV_OK;
+    case DW_FRAME_REG30:
+        *s_out = "DW_FRAME_REG30";
+        return DW_DLV_OK;
+    case DW_FRAME_REG31:
+        *s_out = "DW_FRAME_REG31";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG0:
+        *s_out = "DW_FRAME_FREG0";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG1:
+        *s_out = "DW_FRAME_FREG1";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG2:
+        *s_out = "DW_FRAME_FREG2";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG3:
+        *s_out = "DW_FRAME_FREG3";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG4:
+        *s_out = "DW_FRAME_FREG4";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG5:
+        *s_out = "DW_FRAME_FREG5";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG6:
+        *s_out = "DW_FRAME_FREG6";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG7:
+        *s_out = "DW_FRAME_FREG7";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG8:
+        *s_out = "DW_FRAME_FREG8";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG9:
+        *s_out = "DW_FRAME_FREG9";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG10:
+        *s_out = "DW_FRAME_FREG10";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG11:
+        *s_out = "DW_FRAME_FREG11";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG12:
+        *s_out = "DW_FRAME_FREG12";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG13:
+        *s_out = "DW_FRAME_FREG13";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG14:
+        *s_out = "DW_FRAME_FREG14";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG15:
+        *s_out = "DW_FRAME_FREG15";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG16:
+        *s_out = "DW_FRAME_FREG16";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG17:
+        *s_out = "DW_FRAME_FREG17";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG18:
+        *s_out = "DW_FRAME_FREG18";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG19:
+        *s_out = "DW_FRAME_FREG19";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG20:
+        *s_out = "DW_FRAME_FREG20";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG21:
+        *s_out = "DW_FRAME_FREG21";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG22:
+        *s_out = "DW_FRAME_FREG22";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG23:
+        *s_out = "DW_FRAME_FREG23";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG24:
+        *s_out = "DW_FRAME_FREG24";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG25:
+        *s_out = "DW_FRAME_FREG25";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG26:
+        *s_out = "DW_FRAME_FREG26";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG27:
+        *s_out = "DW_FRAME_FREG27";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG28:
+        *s_out = "DW_FRAME_FREG28";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG29:
+        *s_out = "DW_FRAME_FREG29";
+        return DW_DLV_OK;
+    case DW_FRAME_FREG30:
+        *s_out = "DW_FRAME_FREG30";
+        return DW_DLV_OK;
+    case DW_FRAME_HIGHEST_NORMAL_REGISTER:
+        *s_out = "DW_FRAME_HIGHEST_NORMAL_REGISTER";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_CHILDREN_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_CHILDREN_no:
+        *s_out = "DW_CHILDREN_no";
+        return DW_DLV_OK;
+    case DW_CHILDREN_yes:
+        *s_out = "DW_CHILDREN_yes";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+/* ARGSUSED */
+int
+dwarf_get_ADDR_name (unsigned int val,const char ** s_out)
+{
+    switch (val) {
+    case DW_ADDR_none:
+        *s_out = "DW_ADDR_none";
+        return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY; 
+}
+
+/* END FILE */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_names.h	Sun May 22 03:13:22 2011 +0100
@@ -0,0 +1,34 @@
+/* Generated routines, do not edit. */
+/* Generated on May 22 2011  03:05:33 */
+
+/* BEGIN FILE */
+
+extern int dwarf_get_TAG_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_children_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_FORM_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_AT_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_OP_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_ATE_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_DS_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_END_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_ATCF_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_ACCESS_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_VIS_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_VIRTUALITY_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_LANG_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_ID_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_CC_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_INL_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_ORD_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_DSC_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_LNS_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_LNE_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_ISA_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_MACINFO_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_CFA_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_EH_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_FRAME_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_CHILDREN_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_ADDR_name(unsigned int /*val_in*/, const char ** /*s_out */);
+
+/* END FILE */
--- a/usr/src/tools/ctf/dwarf/common/dwarf_opaque.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_opaque.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,8 @@
 /*
 
-  Copyright (C) 2000,2002,2003 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
+  Portions Copyright (C) 2008-2010 Arxan Technologies, Inc. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +21,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -32,20 +34,30 @@
   http://oss.sgi.com/projects/GenInfo/NoticeExplan
 
 */
+/* The versions applicable by section are:
+                       DWARF2 DWARF3 DWARF4
+ .debug_abbrev           -      -      -
+ .debug_aranges          2      2      2
+ .debug_frame            1      3      4
+ .debug_info             2      3      4
+ .debug_line             2      3      4
+ .debug_loc              -      -      -
+ .debug_macinfo          -      -      -
+ .debug_pubtypes         x      2      2
+ .debug_pubnames         2      2      2
+ .debug_ranges           x      -      -
+ .debug_str              -      -      -
+ .debug_types            x      x      4
+*/
 
 #include <stddef.h>
 
 
 struct Dwarf_Die_s {
-    /* 
-       Points to the start of the portion corresponding to this Die in 
-       the .debug_info section. */
     Dwarf_Byte_Ptr di_debug_info_ptr;
-
     Dwarf_Abbrev_List di_abbrev_list;
-
-    /* Points to cu context for this die.  */
     Dwarf_CU_Context di_cu_context;
+    int  di_abbrev_code;
 };
 
 struct Dwarf_Attribute_s {
@@ -78,30 +90,101 @@
 
     Each die will also contain a pointer to such a struct to 
     record the context for that die.  
+
+    Notice that a pointer to the CU DIE itself is 
+    Dwarf_Off off2 = cu_context->cc_debug_info_offset;
+    cu_die_info_ptr = dbg->de_debug_info.dss_data +
+            off2 + _dwarf_length_of_cu_header(dbg, off2);
     
     **Updated by dwarf_next_cu_header in dwarf_die_deliv.c
 */
 struct Dwarf_CU_Context_s {
     Dwarf_Debug cc_dbg;
+    /* The sum of cc_length, cc_length_size, and cc_extension_size
+       is the total length of the CU including its header. */
     Dwarf_Word cc_length;
+    /* cc_length_size is the size in bytes of an offset.
+       4 for 32bit dwarf, 8 for 64bit dwarf (whether MIPS/IRIX
+       64bit dwarf or standard 64bit dwarf using the extension
+       mechanism). */
     Dwarf_Small cc_length_size;
+    /* cc_extension_size is zero unless this is standard
+       DWARF3 and later 64bit dwarf using the extension mechanism.
+       If it is the DWARF3 and later 64bit dwarf cc_extension
+       size is 4. So for 32bit dwarf and MIPS/IRIX 64bit dwarf
+       cc_extension_size is zero.  */
     Dwarf_Small cc_extension_size;
     Dwarf_Half cc_version_stamp;
     Dwarf_Sword cc_abbrev_offset;
     Dwarf_Small cc_address_size;
+    /* cc_debug_info_offset is the offset in the section
+       of the CU header of this CU.  Dwarf_Word
+       should be large enough. */
     Dwarf_Word cc_debug_info_offset;
     Dwarf_Byte_Ptr cc_last_abbrev_ptr;
     Dwarf_Hash_Table cc_abbrev_hash_table;
     Dwarf_CU_Context cc_next;
-    unsigned char cc_offset_length;
+    /*unsigned char cc_offset_length; */
 };
 
+/* Consolidates section-specific data in one place.
+   Section is an Elf specific term, intended as a general
+   term (for non-Elf objects some code must synthesize the 
+   values somehow).
+   Makes adding more section-data much simpler. */
+struct Dwarf_Section_s {
+    Dwarf_Small *  dss_data;
+    Dwarf_Unsigned dss_size;
+    Dwarf_Word     dss_index;
+    /* dss_addr is the 'section address' which is only
+       non-zero for a GNU eh section.
+       Purpose: to handle DW_EH_PE_pcrel encoding. Leaving
+       it zero is fine for non-elf.  */
+    Dwarf_Addr     dss_addr;
+    Dwarf_Small    dss_data_was_malloc;
+
+    /* For non-elf, leaving the following fields zero
+       will mean they are ignored. */
+    /* dss_link should be zero unless a section has a link
+       to another (sh_link).  Used to access relocation data for
+       a section (and for symtab section, access its strtab). */
+    Dwarf_Word     dss_link;
+    /* The following is used when reading .rela sections
+       (such sections appear in some .o files). */
+    Dwarf_Half     dss_reloc_index; /* Zero means ignore the reloc fields. */
+    Dwarf_Small *  dss_reloc_data;
+    Dwarf_Unsigned dss_reloc_size;
+    Dwarf_Addr     dss_reloc_addr;
+    /* dss_reloc_symtab is the sh_link of a .rela to its .symtab, leave
+       it 0 if non-meaningful. */
+    Dwarf_Addr     dss_reloc_symtab;
+    /* dss_reloc_link should be zero unless a reloc section has a link
+       to another (sh_link).  Used to access the symtab for relocations
+       a section. */
+    Dwarf_Word     dss_reloc_link;
+    /* Pointer to the elf symtab, used for elf .rela. Leave it 0
+       if not relevant. */
+    struct Dwarf_Section_s *dss_symtab;
+};
+
+/* Overview: if next_to_use== first, no error slots are used.
+   If next_to_use+1 (mod maxcount) == first the slots are all used
+*/
+struct Dwarf_Harmless_s {
+  unsigned dh_maxcount;
+  unsigned dh_next_to_use;
+  unsigned dh_first;
+  unsigned dh_errs_count;
+  char **  dh_errors;
+};
 
 struct Dwarf_Debug_s {
-    dwarf_elf_handle de_elf; /* see de_elf_must_close at end of struct */
-    unsigned int de_nelfsecs;
+    /* All file access methods and support data 
+       are hidden in this structure. 
+       We get a pointer, callers control the lifetime of the
+       structure and contents. */
+    struct Dwarf_Obj_Access_Interface_s *de_obj_file;
 
-    Dwarf_Unsigned de_access;
     Dwarf_Handler de_errhand;
     Dwarf_Ptr de_errarg;
 
@@ -151,7 +234,6 @@
     struct Dwarf_Alloc_Hdr_s de_alloc_hdr[ALLOC_AREA_REAL_TABLE_MAX];
 #ifdef DWARF_SIMPLE_MALLOC
     struct simple_malloc_record_s *  de_simple_malloc_base;
-    struct simple_malloc_record_s *  de_simple_malloc_current;
 #endif
     
 
@@ -163,48 +245,45 @@
     Dwarf_Cie *de_cie_data;
     /* Count of number of Dwarf_Cie_s structs. */
     Dwarf_Signed de_cie_count;
+    /* Keep eh (GNU) separate!. */
+    Dwarf_Cie *de_cie_data_eh;
+    Dwarf_Signed de_cie_count_eh;
     /* 
        Points to contiguous block of pointers to Dwarf_Fde_s structs. */
     Dwarf_Fde *de_fde_data;
     /* Count of number of Dwarf_Fde_s structs. */
     Dwarf_Signed de_fde_count;
+    /* Keep eh (GNU) separate!. */
+    Dwarf_Fde *de_fde_data_eh;
+    Dwarf_Signed de_fde_count_eh;
 
-    Dwarf_Small *de_debug_info;
-    Dwarf_Small *de_debug_abbrev;
-    Dwarf_Small *de_debug_line;
-    Dwarf_Small *de_debug_loc;
-    Dwarf_Small *de_debug_aranges;
-    Dwarf_Small *de_debug_macinfo;
-    Dwarf_Small *de_debug_pubnames;
-    Dwarf_Small *de_debug_str;
-    Dwarf_Small *de_debug_frame;
-    Dwarf_Small *de_debug_frame_eh_gnu;	/* gnu for the g++ eh_frame
-					   section */
-
-    Dwarf_Small *de_debug_funcnames;
-    Dwarf_Small *de_debug_typenames;
-    Dwarf_Small *de_debug_varnames;
-    Dwarf_Small *de_debug_weaknames;
+    struct Dwarf_Section_s de_debug_info; 
+    struct Dwarf_Section_s de_debug_abbrev;
+    struct Dwarf_Section_s de_debug_line;
+    struct Dwarf_Section_s de_debug_loc;
+    struct Dwarf_Section_s de_debug_aranges;
+    struct Dwarf_Section_s de_debug_macinfo;
+    struct Dwarf_Section_s de_debug_pubnames;
+    struct Dwarf_Section_s de_debug_str;
+    struct Dwarf_Section_s de_debug_frame;
 
-    Dwarf_Unsigned de_debug_info_size;
-    Dwarf_Unsigned de_debug_abbrev_size;
-    Dwarf_Unsigned de_debug_line_size;
-    Dwarf_Unsigned de_debug_loc_size;
-    Dwarf_Unsigned de_debug_aranges_size;
-    Dwarf_Unsigned de_debug_macinfo_size;
-    Dwarf_Unsigned de_debug_pubnames_size;
-    Dwarf_Unsigned de_debug_str_size;
+    /* gnu: the g++ eh_frame section */
+    struct Dwarf_Section_s de_debug_frame_eh_gnu;
 
+    struct Dwarf_Section_s de_debug_pubtypes; /* DWARF3 .debug_pubtypes */
 
-    Dwarf_Unsigned de_debug_frame_size;
-
-    Dwarf_Unsigned de_debug_frame_size_eh_gnu;	/* gnu for the g++
-					   eh_frame section */
+    struct Dwarf_Section_s de_debug_funcnames;
+    struct Dwarf_Section_s de_debug_typenames; /* SGI IRIX extension essentially
+			identical to DWARF3 .debug_pubtypes. */
+    struct Dwarf_Section_s de_debug_varnames;
+    struct Dwarf_Section_s de_debug_weaknames;
+    struct Dwarf_Section_s de_debug_ranges;	
 
-    Dwarf_Unsigned de_debug_funcnames_size;
-    Dwarf_Unsigned de_debug_typenames_size;
-    Dwarf_Unsigned de_debug_varnames_size;
-    Dwarf_Unsigned de_debug_weaknames_size;
+    /* For non-elf, simply leave the following two structs zeroed and
+       they will be ignored. */
+    struct Dwarf_Section_s de_elf_symtab;	
+    struct Dwarf_Section_s de_elf_strtab;	
+
 
     void *(*de_copy_word) (void *, const void *, size_t);
     unsigned char de_same_endian;
@@ -212,31 +291,20 @@
 	it was dwarf_init (not dwarf_elf_init)
 	so must elf_end() */
 
-    /*
-       The following are used for storing section indicies.
-
-       After a Dwarf_Debug is initialized, a zero for any of
-       these indicies indicates an absent section.
+    /* Default is DW_FRAME_INITIAL_VALUE from header. */
+    Dwarf_Half de_frame_rule_initial_value;  
 
-       If the ELF spec is ever changed to permit 32-bit section
-       indicies, these will need to be changed.
-     */
-    Dwarf_Half de_debug_aranges_index;
-    Dwarf_Half de_debug_line_index;
-    Dwarf_Half de_debug_loc_index;
-    Dwarf_Half de_debug_macinfo_index;
-    Dwarf_Half de_debug_pubnames_index;
-    Dwarf_Half de_debug_funcnames_index;
-    Dwarf_Half de_debug_typenames_index;
-    Dwarf_Half de_debug_varnames_index;
-    Dwarf_Half de_debug_weaknames_index;
-    Dwarf_Half de_debug_frame_index;
-    Dwarf_Half de_debug_frame_eh_gnu_index;
-    Dwarf_Half de_debug_str_index;
-    Dwarf_Half de_debug_info_index;
-    Dwarf_Half de_debug_abbrev_index;
+    /* Default is   DW_FRAME_LAST_REG_NUM. */
+    Dwarf_Half de_frame_reg_rules_entry_count; 
+
+    Dwarf_Half de_frame_cfa_col_number; 
+    Dwarf_Half de_frame_same_value_number; 
+    Dwarf_Half de_frame_undefined_value_number; 
+
     unsigned char de_big_endian_object; /* non-zero if big-endian
 		object opened. */
+
+    struct Dwarf_Harmless_s de_harmless_errors;
 };
 
 typedef struct Dwarf_Chain_s *Dwarf_Chain;
@@ -245,7 +313,10 @@
     Dwarf_Chain ch_next;
 };
 
-#define CURRENT_VERSION_STAMP		2
+
+#define CURRENT_VERSION_STAMP		2 /* DWARF2 */
+#define CURRENT_VERSION_STAMP3		3 /* DWARF3 */
+#define CURRENT_VERSION_STAMP4		4 /* DWARF4 */
 
     /* Size of cu header version stamp field. */
 #define CU_VERSION_STAMP_SIZE   sizeof(Dwarf_Half)
@@ -264,6 +335,5 @@
     used to load the section.
  */
 int _dwarf_load_section(Dwarf_Debug,
-		        Dwarf_Half,
-			Dwarf_Small **,
-			Dwarf_Error *);
+    struct Dwarf_Section_s *,
+    Dwarf_Error *);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_original_elf_init.c	Sun May 22 03:13:22 2011 +0100
@@ -0,0 +1,209 @@
+/*
+
+  Copyright (C) 2000,2001,2002,2005,2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
+  Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include "dwarf_elf_access.h"
+
+#ifdef HAVE_ELF_H
+#include <elf.h>
+#endif
+#ifdef HAVE_LIBELF_H
+#include <libelf.h>
+#else
+#ifdef HAVE_LIBELF_LIBELF_H
+#include <libelf/libelf.h>
+#endif
+#endif
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define DWARF_DBG_ERROR(dbg,errval,retval) \
+     _dwarf_error(dbg, error, errval); return(retval);
+
+#define FALSE  0
+#define TRUE   1
+
+static int
+dwarf_elf_init_file_ownership(dwarf_elf_handle elf_file_pointer,
+                              int libdwarf_owns_elf,
+                              Dwarf_Unsigned access,
+                              Dwarf_Handler errhand,
+                              Dwarf_Ptr errarg,
+                              Dwarf_Debug * ret_dbg,
+                              Dwarf_Error * error);
+
+
+/*
+    The basic dwarf initializer function for consumers using
+    libelf. 
+    Return a libdwarf error code on error, return DW_DLV_OK
+    if this succeeds.
+*/
+int
+dwarf_init(int fd,
+    Dwarf_Unsigned access,
+    Dwarf_Handler errhand,
+    Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, Dwarf_Error * error)
+{
+    struct stat fstat_buf;
+    dwarf_elf_handle elf_file_pointer = 0;
+    /* ELF_C_READ is a portable value */
+    Elf_Cmd what_kind_of_elf_read = ELF_C_READ;
+
+#if !defined(S_ISREG)
+#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
+#endif
+    if (fstat(fd, &fstat_buf) != 0) {
+        DWARF_DBG_ERROR(NULL, DW_DLE_FSTAT_ERROR, DW_DLV_ERROR);
+    }
+    if (!S_ISREG(fstat_buf.st_mode)) {
+        DWARF_DBG_ERROR(NULL, DW_DLE_FSTAT_MODE_ERROR, DW_DLV_ERROR);
+    }
+
+    if (access != DW_DLC_READ) {
+        DWARF_DBG_ERROR(NULL, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR);
+    }
+
+    elf_version(EV_CURRENT);
+    /* changed to mmap request per bug 281217. 6/95 */
+#ifdef HAVE_ELF_C_READ_MMAP
+    /* ELF_C_READ_MMAP is an SGI IRIX specific enum value from IRIX
+       libelf.h meaning read but use mmap */
+    what_kind_of_elf_read = ELF_C_READ_MMAP;
+#endif /* !HAVE_ELF_C_READ_MMAP */
+
+    elf_file_pointer = elf_begin(fd, what_kind_of_elf_read, 0);
+    if (elf_file_pointer == NULL) {
+        DWARF_DBG_ERROR(NULL, DW_DLE_ELF_BEGIN_ERROR, DW_DLV_ERROR);
+    }
+
+    return dwarf_elf_init_file_ownership(elf_file_pointer, 
+                                         TRUE, 
+                                         access, 
+                                         errhand, 
+                                         errarg, 
+                                         ret_dbg, 
+                                         error);
+}
+
+/*
+    An alternate dwarf setup call for consumers using
+    libelf.
+    When the caller has opened libelf already, so the
+    caller must free libelf.
+*/
+int
+dwarf_elf_init(dwarf_elf_handle elf_file_pointer,
+    Dwarf_Unsigned access,
+    Dwarf_Handler errhand,
+    Dwarf_Ptr errarg,
+    Dwarf_Debug * ret_dbg, Dwarf_Error * error)
+{
+  return dwarf_elf_init_file_ownership(elf_file_pointer, 
+                                       FALSE, 
+                                       access, 
+                                       errhand, 
+                                       errarg, 
+                                       ret_dbg, 
+                                       error);
+}
+
+
+/*
+    Initialize the ELF object access for libdwarf.
+ */
+static int 
+dwarf_elf_init_file_ownership(dwarf_elf_handle elf_file_pointer, 
+                              int libdwarf_owns_elf, 
+                              Dwarf_Unsigned access, 
+                              Dwarf_Handler errhand, 
+                              Dwarf_Ptr errarg, 
+                              Dwarf_Debug * ret_dbg, 
+                              Dwarf_Error * error)
+{
+    /* ELF is no longer tied to libdwarf. */
+    Dwarf_Obj_Access_Interface *binary_interface = 0;
+    int res = DW_DLV_OK;
+    int err = 0;
+
+    if (access != DW_DLC_READ) {
+        DWARF_DBG_ERROR(NULL, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR);
+    }
+   
+    /* This allocates and fills in *binary_interface. */
+    res = dwarf_elf_object_access_init(
+        elf_file_pointer, 
+        libdwarf_owns_elf,
+        &binary_interface,
+        &err);
+    if(res != DW_DLV_OK){
+        DWARF_DBG_ERROR(NULL, err, DW_DLV_ERROR);
+    }
+
+    /* This mallocs space and returns pointer thru ret_dbg, 
+       saving  the binary interface in 'ret-dbg' */
+    res = dwarf_object_init(binary_interface, errhand, errarg, 
+                         ret_dbg, error);
+    if(res != DW_DLV_OK){
+        dwarf_elf_object_access_finish(binary_interface);
+    }
+    return res;
+}
+
+
+/*
+    Frees all memory that was not previously freed
+    by dwarf_dealloc.
+    Aside from certain categories.
+
+    This is only applicable when dwarf_init() or dwarf_elf_init()
+    was used to init 'dbg'.
+*/
+int
+dwarf_finish(Dwarf_Debug dbg, Dwarf_Error * error)
+{
+    dwarf_elf_object_access_finish(dbg->de_obj_file);
+
+    return dwarf_object_finish(dbg, error);
+}
+
--- a/usr/src/tools/ctf/dwarf/common/dwarf_print_lines.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_print_lines.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -32,6 +33,12 @@
   http://oss.sgi.com/projects/GenInfo/NoticeExplan
 
 */
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
 
 
 
@@ -40,73 +47,70 @@
 #include <stdio.h>
 #include <time.h>
 #include "dwarf_line.h"
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
 
+/* FIXME Need to add prologue_end epilogue_begin isa fields. */
 static void
 print_line_header(void)
 {
     printf
-	("                                                         s b e\n"
-	 "                                                         t l s\n"
-	 "                                                         m c e\n"
-	 " section    op                                       col t k q\n"
-	 " offset     code               address     file line umn ? ? ?\n");
+        ("                                                         s b e\n"
+         "                                                         t l s\n"
+         "                                                         m c e\n"
+         " section    op                                       col t k q\n"
+         " offset     code               address     file line umn ? ? ?\n");
 }
 
+/* FIXME: print new line values:   prologue_end epilogue_begin isa */
 static void
 print_line_detail(char *prefix,
-		  int opcode,
-		  unsigned long long address,
-		  unsigned long file,
-		  unsigned long line,
-		  unsigned long column,
-		  int is_stmt, int basic_block, int end_sequence)
+                  int opcode,
+                  Dwarf_Unsigned address,
+                  unsigned long file,
+                  unsigned long line,
+                  unsigned long column,
+                  int is_stmt, int basic_block, int end_sequence,
+                  int prologue_end, int epilogue_begin, int isa)
 {
-    printf("%-15s %2d 0x%08llx "
-	   "%2lu   %4lu %2lu   %1d %1d %1d\n",
-	   prefix,
-	   (int) opcode,
-	   (long long) address,
-	   (unsigned long) file,
-	   (unsigned long) line,
-	   (unsigned long) column,
-	   (int) is_stmt, (int) basic_block, (int) end_sequence);
+    printf("%-15s %2d 0x%08" DW_PR_DUx " "
+           "%2lu   %4lu %2lu   %1d %1d %1d\n",
+           prefix,
+           (int) opcode,
+           (Dwarf_Unsigned) address,
+           (unsigned long) file,
+           (unsigned long) line,
+           (unsigned long) column,
+           (int) is_stmt, (int) basic_block, (int) end_sequence);
 
 }
 
 
 /*
-	return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR
+        return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR
+        If err_count_out is non-NULL, this is a special 'check'
+        call.
 */
 int
-_dwarf_internal_printlines(Dwarf_Die die, Dwarf_Error * error)
+_dwarf_internal_printlines(Dwarf_Die die, Dwarf_Error * error,
+   int * err_count_out, int only_line_header)
 {
     /* 
        This pointer is used to scan the portion of the .debug_line
        section for the current cu. */
-    Dwarf_Small *line_ptr;
-    Dwarf_Small *orig_line_ptr;
-
-    /* 
-       This points to the last byte of the .debug_line portion for the 
-       current cu. */
-    Dwarf_Small *line_ptr_end;
+    Dwarf_Small *line_ptr = 0;
+    Dwarf_Small *orig_line_ptr = 0;
 
     /* 
-       This points to the end of the statement program prologue for the 
-       current cu, and serves to check that the prologue was correctly 
-       decoded. */
-    Dwarf_Small *check_line_ptr;
+       This points to the last byte of the .debug_line portion for the
+       current cu. */
+    Dwarf_Small *line_ptr_end = 0;
 
     /* 
-       Pointer to a DW_AT_stmt_list attribute in case it exists in the 
+       Pointer to a DW_AT_stmt_list attribute in case it exists in the
        die. */
-    Dwarf_Attribute stmt_list_attr;
+    Dwarf_Attribute stmt_list_attr = 0;
 
     /* Pointer to DW_AT_comp_dir attribute in die. */
-    Dwarf_Attribute comp_dir_attr;
+    Dwarf_Attribute comp_dir_attr = 0;
 
     /* Pointer to name of compilation directory. */
     Dwarf_Small *comp_dir = NULL;
@@ -114,104 +118,101 @@
     /* 
        Offset into .debug_line specified by a DW_AT_stmt_list
        attribute. */
-    Dwarf_Unsigned line_offset;
+    Dwarf_Unsigned line_offset = 0;
 
-    /* These are the fields of the statement program header. */
-    Dwarf_Unsigned total_length;
-    Dwarf_Half version;
-    Dwarf_Unsigned prologue_length;
-    Dwarf_Small minimum_instruction_length;
-    Dwarf_Small default_is_stmt;
-    Dwarf_Sbyte line_base;
-    Dwarf_Small line_range;
-    Dwarf_Small opcode_base;
+    struct Line_Table_Prefix_s prefix;
 
-    Dwarf_Small *opcode_length;
 
     /* These are the state machine state variables. */
-    Dwarf_Addr address;
-    Dwarf_Word file;
-    Dwarf_Word line;
-    Dwarf_Word column;
-    Dwarf_Bool is_stmt;
-    Dwarf_Bool basic_block;
-    Dwarf_Bool end_sequence;
+    Dwarf_Addr address = 0;
+    Dwarf_Word file = 1;
+    Dwarf_Word line = 1;
+    Dwarf_Word column = 0;
+    Dwarf_Bool is_stmt = false;
+    Dwarf_Bool basic_block = false;
+    Dwarf_Bool end_sequence = false;
+    Dwarf_Bool prologue_end = false;
+    Dwarf_Bool epilogue_begin = false;
+    Dwarf_Small isa = 0;
 
-    Dwarf_Sword i, file_entry_count, include_directories_count;
+
+    Dwarf_Sword i=0;
 
     /* 
        This is the current opcode read from the statement program. */
-    Dwarf_Small opcode;
-
-    /* 
-       Pointer to a Dwarf_Line_Context_s structure that contains the
-       context such as file names and include directories for the set
-       of lines being generated. */
-    Dwarf_Line_Context line_context;
+    Dwarf_Small opcode=0;
 
 
     /* 
        These variables are used to decode leb128 numbers. Leb128_num
        holds the decoded number, and leb128_length is its length in
        bytes. */
-    Dwarf_Word leb128_num;
-    Dwarf_Word leb128_length;
-    Dwarf_Sword advance_line;
-
+    Dwarf_Word leb128_num=0;
+    Dwarf_Word leb128_length=0;
+    Dwarf_Sword advance_line=0;
+    Dwarf_Half attrform = 0;
     /* 
        This is the operand of the latest fixed_advance_pc extended
        opcode. */
-    Dwarf_Half fixed_advance_pc;
+    Dwarf_Half fixed_advance_pc=0;
 
-    /* This is the length of an extended opcode instr.  */
-    Dwarf_Word instr_length;
-    Dwarf_Small ext_opcode;
-    int local_length_size;
-    /*REFERENCED*/ /* Not used in this instance of the macro */
-    int local_extension_size;
+    /* In case there are wierd bytes 'after' the line table
+     * prologue this lets us print something. This is a gcc
+     * compiler bug and we expect the bytes count to be 12.
+     */
+    Dwarf_Small* bogus_bytes_ptr = 0;
+    Dwarf_Unsigned bogus_bytes_count = 0;
+
 
     /* The Dwarf_Debug this die belongs to. */
-    Dwarf_Debug dbg;
-    int resattr;
-    int lres;
-
-    int res;
+    Dwarf_Debug dbg=0;
+    int resattr = DW_DLV_ERROR;
+    int lres =    DW_DLV_ERROR;
+    int res  =    DW_DLV_ERROR;
 
     /* ***** BEGIN CODE ***** */
 
-    if (error != NULL)
-	*error = NULL;
-
-    CHECK_DIE(die, DW_DLV_ERROR)
-	dbg = die->di_cu_context->cc_dbg;
+    if (error != NULL) {
+        *error = NULL;
+    }
 
-    res =
-       _dwarf_load_section(dbg,
-		           dbg->de_debug_line_index,
-			   &dbg->de_debug_line,
-		           error);
+    CHECK_DIE(die, DW_DLV_ERROR);
+    dbg = die->di_cu_context->cc_dbg;
+
+    res = _dwarf_load_section(dbg, &dbg->de_debug_line,error);
     if (res != DW_DLV_OK) {
-	return res;
+        return res;
     }
 
     resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
     if (resattr != DW_DLV_OK) {
-	return resattr;
+        return resattr;
     }
 
 
-
-    lres = dwarf_formudata(stmt_list_attr, &line_offset, error);
+    /* The list of relevant FORMs is small. 
+       DW_FORM_data4, DW_FORM_data8, DW_FORM_sec_offset 
+    */
+    lres = dwarf_whatform(stmt_list_attr,&attrform,error);
     if (lres != DW_DLV_OK) {
-	return lres;
+        return lres;
+    }
+    if (attrform != DW_FORM_data4 && attrform != DW_FORM_data8 &&
+        attrform != DW_FORM_sec_offset ) {
+        _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
+        return (DW_DLV_ERROR);
+    }
+    lres = dwarf_global_formref(stmt_list_attr, &line_offset, error);
+    if (lres != DW_DLV_OK) {
+        return lres;
     }
 
-    if (line_offset >= dbg->de_debug_line_size) {
-	_dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
-	return (DW_DLV_ERROR);
+    if (line_offset >= dbg->de_debug_line.dss_size) {
+        _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
+        return (DW_DLV_ERROR);
     }
-    orig_line_ptr = dbg->de_debug_line;
-    line_ptr = dbg->de_debug_line + line_offset;
+    orig_line_ptr = dbg->de_debug_line.dss_data;
+    line_ptr = dbg->de_debug_line.dss_data + line_offset;
     dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
 
     /* 
@@ -219,448 +220,518 @@
        the compilation directory. */
     resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
     if (resattr == DW_DLV_ERROR) {
-	return resattr;
+        return resattr;
     }
     if (resattr == DW_DLV_OK) {
-	int cres;
-	char *cdir;
+        int cres = DW_DLV_ERROR;
+        char *cdir = 0;
 
-	cres = dwarf_formstring(comp_dir_attr, &cdir, error);
-	if (cres == DW_DLV_ERROR) {
-	    return cres;
-	} else if (cres == DW_DLV_OK) {
-	    comp_dir = (Dwarf_Small *) cdir;
-	}
+        cres = dwarf_formstring(comp_dir_attr, &cdir, error);
+        if (cres == DW_DLV_ERROR) {
+            return cres;
+        } else if (cres == DW_DLV_OK) {
+            comp_dir = (Dwarf_Small *) cdir;
+        }
     }
     if (resattr == DW_DLV_OK) {
-	dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
+        dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
     }
 
-    /* 
-       Following is a straightforward decoding of the statement
-       program prologue information. */
-
-    /* READ_AREA_LENGTH updates line_ptr for consumed bytes */
-    READ_AREA_LENGTH(dbg, total_length, Dwarf_Unsigned,
-		     line_ptr, local_length_size, local_extension_size);
-
-
-
-    line_ptr_end = line_ptr + total_length;
-    if (line_ptr_end > dbg->de_debug_line + dbg->de_debug_line_size) {
-	_dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_LENGTH_BAD);
-	return (DW_DLV_ERROR);
+    dwarf_init_line_table_prefix(&prefix);
+    {
+        Dwarf_Small *line_ptr_out = 0;
+        int dres = dwarf_read_line_table_prefix(dbg,
+            line_ptr,dbg->de_debug_line.dss_size - line_offset,
+            &line_ptr_out,
+            &prefix, 
+            &bogus_bytes_ptr,
+            &bogus_bytes_count,
+            error,
+            err_count_out);
+        if (dres == DW_DLV_ERROR) {
+            dwarf_free_line_table_prefix(&prefix);
+            return dres;
+        }
+        if (dres == DW_DLV_NO_ENTRY) {
+            dwarf_free_line_table_prefix(&prefix);
+            return dres;
+        }
+        line_ptr_end = prefix.pf_line_ptr_end;
+        line_ptr = line_ptr_out;
     }
-
-    printf("total line info length %ld bytes, "
-	   "line offset 0x%llx %lld\n",
-	   (long) total_length,
-	   (long long) line_offset, (long long) line_offset);
-    printf("compilation_directory %s\n",
-	   comp_dir ? ((char *) comp_dir) : "");
-    READ_UNALIGNED(dbg, version, Dwarf_Half,
-		   line_ptr, sizeof(Dwarf_Half));
-    line_ptr += sizeof(Dwarf_Half);
-    if (version != CURRENT_VERSION_STAMP) {
-	_dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
-	return (DW_DLV_ERROR);
+    if(only_line_header) {
+         /* Just checking for header errors, nothing more here.*/
+         dwarf_free_line_table_prefix(&prefix);
+         return DW_DLV_OK;
     }
 
-    READ_UNALIGNED(dbg, prologue_length, Dwarf_Unsigned,
-		   line_ptr, local_length_size);
-    line_ptr += local_length_size;
-    check_line_ptr = line_ptr;
 
-    minimum_instruction_length = *(Dwarf_Small *) line_ptr;
-    line_ptr = line_ptr + sizeof(Dwarf_Small);
+    printf("total line info length %ld bytes, "
+           "line offset 0x%" DW_PR_DUx " %" DW_PR_DSd "\n",
+           (long) prefix.pf_total_length,
+           (Dwarf_Unsigned) line_offset, 
+           (Dwarf_Signed) line_offset);
+    printf("line table version %d\n",(int) prefix.pf_version);
+    printf("line table length field length %d prologue length %d\n",
+           (int)prefix.pf_length_field_length,
+           (int)prefix.pf_prologue_length);
+    printf("compilation_directory %s\n",
+           comp_dir ? ((char *) comp_dir) : "");
 
-    default_is_stmt = *(Dwarf_Small *) line_ptr;
-    line_ptr = line_ptr + sizeof(Dwarf_Small);
+    printf("  min instruction length %d\n",
+           (int) prefix.pf_minimum_instruction_length);
+    printf("  default is stmt        %d\n", (int)
+           prefix.pf_default_is_stmt);
+    printf("  line base              %d\n", (int)
+           prefix.pf_line_base);
+    printf("  line_range             %d\n", (int)
+           prefix.pf_line_range);
+    printf("  opcode base            %d\n", (int)
+           prefix.pf_opcode_base);
+    printf("  standard opcode count  %d\n", (int)
+           prefix.pf_std_op_count);
 
-    line_base = *(Dwarf_Sbyte *) line_ptr;
-    line_ptr = line_ptr + sizeof(Dwarf_Sbyte);
-
-    line_range = *(Dwarf_Small *) line_ptr;
-    line_ptr = line_ptr + sizeof(Dwarf_Small);
+    for (i = 1; i < prefix.pf_opcode_base; i++) {
+        printf("  opcode[%2d] length  %d\n", (int) i,
+               (int) prefix.pf_opcode_length_table[i - 1]);
+    }
+    printf("  include directories count %d\n", (int)
+           prefix.pf_include_directories_count);
 
-    opcode_base = *(Dwarf_Small *) line_ptr;
-    line_ptr = line_ptr + sizeof(Dwarf_Small);
-    printf("  min instruction length %d\n",
-	   (int) minimum_instruction_length);
-    printf("  default is stmt        %d\n", (int) default_is_stmt);
-    printf("  line base              %d\n", (int) line_base);
-    printf("  line_range             %d\n", (int) line_range);
+    
+    for (i = 0; i < prefix.pf_include_directories_count; ++i) {
+        printf("  include dir[%d] %s\n",
+               (int) i, prefix.pf_include_directories[i]);
+    }
+    printf("  files count            %d\n", (int)
+           prefix.pf_files_count);
+
+    for (i = 0; i < prefix.pf_files_count; ++i) {
+        struct Line_Table_File_Entry_s *lfile =
+            prefix.pf_line_table_file_entries + i;
+
+        Dwarf_Unsigned tlm2 = lfile->lte_last_modification_time;
+        Dwarf_Unsigned di = lfile->lte_directory_index;
+        Dwarf_Unsigned fl = lfile->lte_length_of_file;
 
-    opcode_length = (Dwarf_Small *)
-	alloca(sizeof(Dwarf_Small) * opcode_base);
+        printf("  file[%d]  %s (file-number: %d) \n",
+               (int) i, (char *) lfile->lte_filename,
+               (int)(i+1));
+
+        printf("    dir index %d\n", (int) di);
+        {
+            time_t tt = (time_t) tlm2;
 
-    for (i = 1; i < opcode_base; i++) {
-	opcode_length[i] = *(Dwarf_Small *) line_ptr;
-	printf("  opcode[%d] length %d\n", (int) i,
-	       (int) opcode_length[i]);
-	line_ptr = line_ptr + sizeof(Dwarf_Small);
+            printf("    last time 0x%x %s",     /* ctime supplies
+                                                   newline */
+                   (unsigned) tlm2, ctime(&tt));
+        }
+        printf("    file length %ld 0x%lx\n",
+               (long) fl, (unsigned long) fl);
+
+
     }
 
-    include_directories_count = 0;
-    while ((*(char *) line_ptr) != '\0') {
-	printf("  include dir[%d] %s\n",
-	       (int) include_directories_count, line_ptr);
-	line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
-	include_directories_count++;
-    }
-    line_ptr++;
-
-    file_entry_count = 0;
-    while (*(char *) line_ptr != '\0') {
-
-	Dwarf_Unsigned tlm2;
-	Dwarf_Unsigned di;
-	Dwarf_Unsigned fl;
-
-	printf("  file[%d]  %s\n",
-	       (int) file_entry_count, (char *) line_ptr);
-
-	line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
-
-	di = _dwarf_decode_u_leb128(line_ptr, &leb128_length);
-	line_ptr = line_ptr + leb128_length;
 
-	tlm2 = _dwarf_decode_u_leb128(line_ptr, &leb128_length);
-	line_ptr = line_ptr + leb128_length;
-
-	fl = _dwarf_decode_u_leb128(line_ptr, &leb128_length);
-	line_ptr = line_ptr + leb128_length;
-
-	printf("    dir index %d\n", (int) di);
-	{
-	    time_t tt = (time_t) tlm2;
+    {
+        Dwarf_Unsigned offset = 0;
+        if(bogus_bytes_count > 0) {
+            Dwarf_Unsigned wcount = bogus_bytes_count;
+            Dwarf_Unsigned boffset = bogus_bytes_ptr - orig_line_ptr;
+            printf("*** DWARF CHECK: the line table prologue  header_length "
+                " is %" DW_PR_DUu " too high, we pretend it is smaller."
+                "Section offset: %" DW_PR_DUu " (0x%" DW_PR_DUx ") ***\n",
+                wcount, boffset,boffset);
+            *err_count_out += 1;
+        }
+        offset = line_ptr - orig_line_ptr;
 
-	    printf("    last time 0x%x %s",	/* ctime supplies
-						   newline */
-		   (unsigned) tlm2, ctime(&tt));
-	}
-	printf("    file length %ld 0x%lx\n",
-	       (long) fl, (unsigned long) fl);
-
-
-	file_entry_count++;
-    }
-    line_ptr++;
-
-    if (line_ptr != check_line_ptr + prologue_length) {
-	_dwarf_error(dbg, error, DW_DLE_LINE_PROLOG_LENGTH_BAD);
-	return (DW_DLV_ERROR);
+        printf("  statement prog offset in section: %" DW_PR_DUu " 0x%" DW_PR_DUx "\n",
+               offset, offset);
     }
 
-    /* Set up context structure for this set of lines. */
-    line_context = (Dwarf_Line_Context)
-	_dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1);
-    if (line_context == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
-    }
+    /* Initialize the part of the state machine dependent on the
+       prefix.  */
+    is_stmt = prefix.pf_default_is_stmt;
 
-    printf("  statement prog offset in section: %lld 0x%llx\n",
-	   (long long) (line_ptr - orig_line_ptr),
-	   (long long) (line_ptr - orig_line_ptr));
-
-    /* Initialize the state machine.  */
-    address = 0;
-    file = 1;
-    line = 1;
-    column = 0;
-    is_stmt = default_is_stmt;
-    basic_block = false;
-    end_sequence = false;
 
     print_line_header();
     /* Start of statement program.  */
     while (line_ptr < line_ptr_end) {
-	int type;
+        int type = 0;
+
+        printf(" [0x%06" DW_PR_DSx "] ", 
+            (Dwarf_Signed) (line_ptr - orig_line_ptr));
+        opcode = *(Dwarf_Small *) line_ptr;
+        line_ptr++;
+        /* 'type' is the output */
+        WHAT_IS_OPCODE(type, opcode, prefix.pf_opcode_base,
+                       prefix.pf_opcode_length_table, line_ptr,
+                       prefix.pf_std_op_count);
+
+        if (type == LOP_DISCARD) {
+            int oc;
+            int opcnt = prefix.pf_opcode_length_table[opcode];
+
+            printf("*** DWARF CHECK: DISCARD standard opcode %d "
+                "with %d operands: "
+                "not understood.", opcode, opcnt);
+            *err_count_out += 1;
+            for (oc = 0; oc < opcnt; oc++) {
+                /* 
+                 * Read and discard operands we don't
+                 * understand.
+                 * Arbitrary choice of unsigned read.
+                 * Signed read would work as well.
+                 */
+                Dwarf_Unsigned utmp2;
+
+                DECODE_LEB128_UWORD(line_ptr, utmp2);
+                printf(" %" DW_PR_DUu " (0x%" DW_PR_DUx ")",
+                       (Dwarf_Unsigned) utmp2,
+                       (Dwarf_Unsigned) utmp2);
+            }
+
+            printf("***\n");
+            /* do nothing, necessary ops done */
+        } else if (type == LOP_SPECIAL) {
+            /* This op code is a special op in the object, no matter
+               that it might fall into the standard op range in this
+               compile Thatis, these are special opcodes between
+               special_opcode_base and MAX_LINE_OP_CODE.  (including
+               special_opcode_base and MAX_LINE_OP_CODE) */
+            char special[50];
+            unsigned origop = opcode;
+
+            opcode = opcode - prefix.pf_opcode_base;
+            address = address + prefix.pf_minimum_instruction_length *
+                (opcode / prefix.pf_line_range);
+            line =
+                line + prefix.pf_line_base +
+                opcode % prefix.pf_line_range;
+
+            sprintf(special, "Specialop %3u", origop);
+            print_line_detail(special,
+                              opcode, address, (int) file, line, column,
+                              is_stmt, basic_block, end_sequence,
+                              prologue_end, epilogue_begin, isa);
 
-	printf(" [0x%06llx] ", (long long) (line_ptr - orig_line_ptr));
-	opcode = *(Dwarf_Small *) line_ptr;
-	line_ptr++;
-	/* 'type' is the output */
-	WHAT_IS_OPCODE(type, opcode, opcode_base,
-		       opcode_length, line_ptr);
+            basic_block = false;
+
+        } else if (type == LOP_STANDARD) {
+            switch (opcode) {
+
+            case DW_LNS_copy:{
+
+                    print_line_detail("DW_LNS_copy",
+                                      opcode, address, file, line,
+                                      column, is_stmt, basic_block,
+                                      end_sequence, prologue_end,
+                                      epilogue_begin, isa);
+
+                    basic_block = false;
+                    break;
+                }
+
+            case DW_LNS_advance_pc:{
+                    Dwarf_Unsigned utmp2;
+
 
+                    DECODE_LEB128_UWORD(line_ptr, utmp2);
+                    printf("DW_LNS_advance_pc val %" DW_PR_DSd " 0x%" DW_PR_DUx "\n",
+                           (Dwarf_Signed) (Dwarf_Word) utmp2,
+                           (Dwarf_Unsigned) (Dwarf_Word) utmp2);
+                    leb128_num = (Dwarf_Word) utmp2;
+                    address =
+                        address +
+                        prefix.pf_minimum_instruction_length *
+                        leb128_num;
+                    break;
+                }
+
+            case DW_LNS_advance_line:{
+                    Dwarf_Signed stmp;
+
+
+                    DECODE_LEB128_SWORD(line_ptr, stmp);
+                    advance_line = (Dwarf_Sword) stmp;
+                    printf("DW_LNS_advance_line val %" DW_PR_DSd " 0x%" DW_PR_DSx "\n",
+                           (Dwarf_Signed) advance_line,
+                           (Dwarf_Signed) advance_line);
+                    line = line + advance_line;
+                    break;
+                }
+
+            case DW_LNS_set_file:{
+                    Dwarf_Unsigned utmp2;
+
+
+                    DECODE_LEB128_UWORD(line_ptr, utmp2);
+                    file = (Dwarf_Word) utmp2;
+                    printf("DW_LNS_set_file  %ld\n", (long) file);
+                    break;
+                }
+
+            case DW_LNS_set_column:{
+                    Dwarf_Unsigned utmp2;
 
 
-	if (type == LOP_DISCARD) {
-	    /* do nothing, necessary ops done */
-	} else if (type == LOP_SPECIAL) {
-	    /* This op code is a special op in the object, no matter
-	       that it might fall into the standard op range in this
-	       compile Thatis, these are special opcodes between
-	       special_opcode_base and MAX_LINE_OP_CODE.  (including
-	       special_opcode_base and MAX_LINE_OP_CODE) */
-	    char special[50];
-	    unsigned origop = opcode;
-
-	    opcode = opcode - opcode_base;
-	    address = address + minimum_instruction_length *
-		(opcode / line_range);
-	    line = line + line_base + opcode % line_range;
-
-	    sprintf(special, "Specialop %3u", origop);
-	    print_line_detail(special,
-			      opcode, address, (int) file, line, column,
-			      is_stmt, basic_block, end_sequence);
-
-	    basic_block = false;
+                    DECODE_LEB128_UWORD(line_ptr, utmp2);
+                    column = (Dwarf_Word) utmp2;
+                    printf("DW_LNS_set_column val %" DW_PR_DSd " 0x%" DW_PR_DSx "\n",
+                           (Dwarf_Signed) column, (Dwarf_Signed) column);
+                    break;
+                }
 
-	} else if (type == LOP_STANDARD) {
-	    switch (opcode) {
-
-	    case DW_LNS_copy:{
-		    if (opcode_length[DW_LNS_copy] != 0) {
-			_dwarf_error(dbg, error,
-				     DW_DLE_LINE_NUM_OPERANDS_BAD);
-			return (DW_DLV_ERROR);
-		    }
+            case DW_LNS_negate_stmt:{
+                    is_stmt = !is_stmt;
+                    printf("DW_LNS_negate_stmt\n");
+                    break;
+                }
 
-		    print_line_detail("DW_LNS_copy",
-				      opcode, address, file, line,
-				      column, is_stmt, basic_block,
-				      end_sequence);
-
-		    basic_block = false;
-		    break;
-		}
-
-	    case DW_LNS_advance_pc:{
-		    Dwarf_Unsigned utmp2;
-
-		    if (opcode_length[DW_LNS_advance_pc] != 1) {
-			_dwarf_error(dbg, error,
-				     DW_DLE_LINE_NUM_OPERANDS_BAD);
-			return (DW_DLV_ERROR);
-		    }
+            case DW_LNS_set_basic_block:{
 
-		    DECODE_LEB128_UWORD(line_ptr, utmp2)
-			printf("DW_LNS_advance_pc val %lld 0x%llx\n",
-			       (long long) (Dwarf_Word) utmp2,
-			       (long long) (Dwarf_Word) utmp2);
-		    leb128_num = (Dwarf_Word) utmp2;
-		    address =
-			address +
-			minimum_instruction_length * leb128_num;
-		    break;
-		}
-
-	    case DW_LNS_advance_line:{
-		    Dwarf_Signed stmp;
-
-		    if (opcode_length[DW_LNS_advance_line] != 1) {
-			_dwarf_error(dbg, error,
-				     DW_DLE_LINE_NUM_OPERANDS_BAD);
-			return (DW_DLV_ERROR);
-		    }
+                    printf("DW_LNS_set_basic_block\n");
+                    basic_block = true;
+                    break;
+                }
 
-		    DECODE_LEB128_SWORD(line_ptr, stmp)
-			advance_line = (Dwarf_Sword) stmp;
-		    printf("DW_LNS_advance_line val %lld 0x%llx\n",
-			   (long long) advance_line,
-			   (long long) advance_line);
-		    line = line + advance_line;
-		    break;
-		}
-
-	    case DW_LNS_set_file:{
-		    Dwarf_Unsigned utmp2;
+            case DW_LNS_const_add_pc:{
+                    opcode = MAX_LINE_OP_CODE - prefix.pf_opcode_base;
+                    address =
+                        address +
+                        prefix.pf_minimum_instruction_length * (opcode /
+                                                                prefix.
+                                                                pf_line_range);
 
-		    if (opcode_length[DW_LNS_set_file] != 1) {
-			_dwarf_error(dbg, error,
-				     DW_DLE_LINE_NUM_OPERANDS_BAD);
-			return (DW_DLV_ERROR);
-		    }
+                    printf("DW_LNS_const_add_pc new address 0x%" DW_PR_DSx "\n",
+                           (Dwarf_Signed) address);
+                    break;
+                }
 
-		    DECODE_LEB128_UWORD(line_ptr, utmp2)
-			file = (Dwarf_Word) utmp2;
-		    printf("DW_LNS_set_file  %ld\n", (long) file);
-		    break;
-		}
-
-	    case DW_LNS_set_column:{
-		    Dwarf_Unsigned utmp2;
-
-		    if (opcode_length[DW_LNS_set_column] != 1) {
-			_dwarf_error(dbg, error,
-				     DW_DLE_LINE_NUM_OPERANDS_BAD);
-			return (DW_DLV_ERROR);
-		    }
+            case DW_LNS_fixed_advance_pc:{
 
-		    DECODE_LEB128_UWORD(line_ptr, utmp2)
-			column = (Dwarf_Word) utmp2;
-		    printf("DW_LNS_set_column val %lld 0x%llx\n",
-			   (long long) column, (long long) column);
-		    break;
-		}
-
-	    case DW_LNS_negate_stmt:{
-		    if (opcode_length[DW_LNS_negate_stmt] != 0) {
-			_dwarf_error(dbg, error,
-				     DW_DLE_LINE_NUM_OPERANDS_BAD);
-			return (DW_DLV_ERROR);
-		    }
-
-		    is_stmt = !is_stmt;
-		    printf("DW_LNS_negate_stmt\n");
-		    break;
-		}
+                    READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half,
+                                   line_ptr, sizeof(Dwarf_Half));
+                    line_ptr += sizeof(Dwarf_Half);
+                    address = address + fixed_advance_pc;
+                    printf("DW_LNS_fixed_advance_pc val %" DW_PR_DSd 
+                       " 0x%" DW_PR_DSx " new address 0x%" DW_PR_DSx "\n",
+                           (Dwarf_Signed) fixed_advance_pc,
+                           (Dwarf_Signed) fixed_advance_pc,
+                           (Dwarf_Signed) address);
+                    break;
+                }
+            case DW_LNS_set_prologue_end:{
 
-	    case DW_LNS_set_basic_block:{
-		    if (opcode_length[DW_LNS_set_basic_block] != 0) {
-			_dwarf_error(dbg, error,
-				     DW_DLE_LINE_NUM_OPERANDS_BAD);
-			return (DW_DLV_ERROR);
-		    }
-
-		    printf("DW_LNS_set_basic_block\n");
-		    basic_block = true;
-		    break;
-		}
+                    prologue_end = true;
+                    printf("DW_LNS_set_prologue_end set true.\n");
+                    break;
 
-	    case DW_LNS_const_add_pc:{
-		    opcode = MAX_LINE_OP_CODE - opcode_base;
-		    address = address + minimum_instruction_length *
-			(opcode / line_range);
-
-		    printf("DW_LNS_const_add_pc new address 0x%llx\n",
-			   (long long) address);
-		    break;
-		}
-
-	    case DW_LNS_fixed_advance_pc:{
-		    if (opcode_length[DW_LNS_fixed_advance_pc] != 1) {
-			_dwarf_error(dbg, error,
-				     DW_DLE_LINE_NUM_OPERANDS_BAD);
-			return (DW_DLV_ERROR);
-		    }
 
-		    READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half,
-				   line_ptr, sizeof(Dwarf_Half));
-		    line_ptr += sizeof(Dwarf_Half);
-		    address = address + fixed_advance_pc;
-		    printf("DW_LNS_fixed_advance_pc val %lld 0x%llx"
-			   " new address 0x%llx\n",
-			   (long long) fixed_advance_pc,
-			   (long long) fixed_advance_pc,
-			   (long long) address);
-		    break;
-		}
-	    }
+                }
+                /* New in DWARF3 */
+            case DW_LNS_set_epilogue_begin:{
+                    epilogue_begin = true;
+                    printf("DW_LNS_set_epilogue_begin set true.\n");
+                    break;
+                }
 
-	} else if (type == LOP_EXTENDED) {
-	    Dwarf_Unsigned utmp3;
-
-	    DECODE_LEB128_UWORD(line_ptr, utmp3)
-		instr_length = (Dwarf_Word) utmp3;
-	    ext_opcode = *(Dwarf_Small *) line_ptr;
-	    line_ptr++;
-	    switch (ext_opcode) {
-
-	    case DW_LNE_end_sequence:{
-		    end_sequence = true;
-
-		    print_line_detail("DW_LNE_end_sequence extended",
-				      opcode, address, file, line,
-				      column, is_stmt, basic_block,
-				      end_sequence);
+                /* New in DWARF3 */
+            case DW_LNS_set_isa:{
+                    Dwarf_Unsigned utmp2;
 
-		    address = 0;
-		    file = 1;
-		    line = 1;
-		    column = 0;
-		    is_stmt = default_is_stmt;
-		    basic_block = false;
-		    end_sequence = false;
-
-		    break;
-		}
+                    DECODE_LEB128_UWORD(line_ptr, utmp2);
+                    isa = utmp2;
+                    printf("DW_LNS_set_isa new value 0x%" DW_PR_DUx ".\n",
+                           (Dwarf_Unsigned) utmp2);
+                    if (isa != utmp2) {
+                        /* The value of the isa did not fit in our
+                           local so we record it wrong. declare an
+                           error. */
+                        dwarf_free_line_table_prefix(&prefix);
 
-	    case DW_LNE_set_address:{
-		    if (instr_length - 1 == dbg->de_pointer_size) {
-			READ_UNALIGNED(dbg, address, Dwarf_Addr,
-				       line_ptr, dbg->de_pointer_size);
-
-			line_ptr += dbg->de_pointer_size;
-			printf("DW_LNE_set_address address 0x%llx\n",
-			       (long long) address);
-		    } else {
-			_dwarf_error(dbg, error,
-				     DW_DLE_LINE_SET_ADDR_ERROR);
-			return (DW_DLV_ERROR);
-		    }
-
-		    break;
-		}
-
-	    case DW_LNE_define_file:{
+                        _dwarf_error(dbg, error,
+                                     DW_DLE_LINE_NUM_OPERANDS_BAD);
+                        return (DW_DLV_ERROR);
+                    }
+                    break;
+                }
+            }
 
 
-		    Dwarf_Small *fn;
-		    Dwarf_Signed di;
-		    Dwarf_Signed tlm;
-		    Dwarf_Unsigned fl;
+        } else if (type == LOP_EXTENDED) {
+            Dwarf_Unsigned utmp3 = 0;
+            Dwarf_Word instr_length = 0;
+            Dwarf_Small ext_opcode = 0;
 
-		    fn = (Dwarf_Small *) line_ptr;
-		    line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
+            DECODE_LEB128_UWORD(line_ptr, utmp3);
+            instr_length = (Dwarf_Word) utmp3;
+            ext_opcode = *(Dwarf_Small *) line_ptr;
+            line_ptr++;
+            switch (ext_opcode) {
+
+            case DW_LNE_end_sequence:{
+                    end_sequence = true;
 
-		    di = _dwarf_decode_u_leb128(line_ptr,
-						&leb128_length);
-		    line_ptr = line_ptr + leb128_length;
+                    print_line_detail("DW_LNE_end_sequence extended",
+                                      opcode, address, file, line,
+                                      column, is_stmt, basic_block,
+                                      end_sequence, prologue_end,
+                                      epilogue_begin, isa);
 
-		    tlm =
-			_dwarf_decode_u_leb128(line_ptr,
-					       &leb128_length);
-		    line_ptr = line_ptr + leb128_length;
-
-		    fl = _dwarf_decode_u_leb128(line_ptr,
-						&leb128_length);
-		    line_ptr = line_ptr + leb128_length;
+                    address = 0;
+                    file = 1;
+                    line = 1;
+                    column = 0;
+                    is_stmt = prefix.pf_default_is_stmt;
+                    basic_block = false;
+                    end_sequence = false;
+                    prologue_end = false;
+                    epilogue_begin = false;
 
 
-		    printf("DW_LNE_define_file %s \n", fn);
-		    printf("    dir index %d\n", (int) di);
-		    {
-			time_t tt3 = (time_t) tlm;
+                    break;
+                }
+
+            case DW_LNE_set_address:{
+                    {
+                        READ_UNALIGNED(dbg, address, Dwarf_Addr,
+                                       line_ptr, 
+                                       die->di_cu_context->cc_address_size);
+
+                        line_ptr += die->di_cu_context->cc_address_size;
+                        printf("DW_LNE_set_address address 0x%" DW_PR_DUx "\n",
+                               (Dwarf_Unsigned) address);
+                    }
+
+                    break;
+                }
 
-			/* ctime supplies newline */
-			printf("    last time 0x%x %s",
-			       (unsigned) tlm, ctime(&tt3));
-		    }
-		    printf("    file length %ld 0x%lx\n",
-			   (long) fl, (unsigned long) fl);
+            case DW_LNE_define_file:{
+                    Dwarf_Unsigned di = 0;
+                    Dwarf_Unsigned tlm = 0;
+                    Dwarf_Unsigned fl = 0;
+
+                    Dwarf_Small *fn = (Dwarf_Small *) line_ptr;
+                    line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
+
+                    di = _dwarf_decode_u_leb128(line_ptr,
+                                                &leb128_length);
+                    line_ptr = line_ptr + leb128_length;
+
+                    tlm = _dwarf_decode_u_leb128(line_ptr,
+                                                 &leb128_length);
+                    line_ptr = line_ptr + leb128_length;
+
+                    fl = _dwarf_decode_u_leb128(line_ptr,
+                                                &leb128_length);
+                    line_ptr = line_ptr + leb128_length;
+
 
-		    break;
-		}
+                    printf("DW_LNE_define_file %s \n", fn);
+                    printf("    dir index %d\n", (int) di);
+                    {
+                        time_t tt3 = (time_t) tlm;
+
+                        /* ctime supplies newline */
+                        printf("    last time 0x%x %s",
+                               (unsigned) tlm, ctime(&tt3));
+                    }
+                    printf("    file length %ld 0x%lx\n",
+                           (long) fl, (unsigned long) fl);
+
+                    break;
+                }
+
+            default:{
+                 /* This is an extended op code we do not know about,
+                    other than we know now many bytes it is
+                    (and the op code and the bytes of operand). */
 
-	    default:{
-		    _dwarf_error(dbg, error,
-				 DW_DLE_LINE_EXT_OPCODE_BAD);
-		    return (DW_DLV_ERROR);
-		}
-	    }
+                 Dwarf_Unsigned remaining_bytes = instr_length -1;
+                 if(instr_length < 1 || remaining_bytes > DW_LNE_LEN_MAX) {
+                      dwarf_free_line_table_prefix(&prefix);
+                      _dwarf_error(dbg, error,
+                                 DW_DLE_LINE_EXT_OPCODE_BAD);
+                      return (DW_DLV_ERROR);
+                 }
+                 printf("DW_LNE extended op 0x%x ",ext_opcode);
+                 printf("Bytecount: " DW_PR_DUu , instr_length);
+                 if(remaining_bytes > 0) {
+                     printf(" linedata: 0x");
+                     while (remaining_bytes > 0) {
+                        printf("%02x",(unsigned char)(*(line_ptr)));
+                        line_ptr++;
+                        remaining_bytes--;
+                     }
+                 }
+                 printf("\n");
+                }
+                break;
+            }
 
-	}
+        }
     }
 
+    dwarf_free_line_table_prefix(&prefix);
     return (DW_DLV_OK);
 }
 
 /*
-	Caller passes in compilation unit DIE.
+        This is support for dwarfdump: making it possible
+        for clients wanting line detail info on stdout
+        to get that detail without including internal libdwarf
+        header information.
+        Caller passes in compilation unit DIE.
+        The _dwarf_ version is obsolete (though supported for
+        compatibility).
+        The dwarf_ version is preferred.
+        The functions are intentionally identical: having
+        _dwarf_print_lines call dwarf_print_lines might
+        better emphasize they are intentionally identical, but
+        that seemed slightly silly given how short the functions are.
+        Interface adds error_count (output value) February 2009.
 */
 int
+dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error,int *error_count)
+{
+    int only_line_header = 0;
+    int res = _dwarf_internal_printlines(die, error,
+        error_count,
+        only_line_header);
+    if (res != DW_DLV_OK) {
+        return res;
+    }
+    return res;
+}
+int
 _dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error)
 {
-    int res;
-
-    res = _dwarf_internal_printlines(die, error);
+    int only_line_header = 0;
+    int err_count = 0;
+    int res = _dwarf_internal_printlines(die, error,
+        &err_count,
+        only_line_header);
+    /* No way to get error count back in this interface */
     if (res != DW_DLV_OK) {
-	return res;
+        return res;
     }
     return res;
 }
+
+/* The check is in case we are not printing full line data,
+   this gets some of the issues noted with .debug_line,
+   but not all. Call dwarf_print_lines() to get all issues.
+   Intended for apps like dwarfdump.
+*/
+void
+dwarf_check_lineheader(Dwarf_Die die, int *err_count_out)
+{
+    Dwarf_Error err;
+    int only_line_header = 1;
+    _dwarf_internal_printlines(die, &err,err_count_out,
+        only_line_header);
+    return;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_pubtypes.c	Sun May 22 03:13:22 2011 +0100
@@ -0,0 +1,138 @@
+/*
+
+  Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2009-2010 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+/* Reads DWARF3 .debug_pubtypes section. */
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include "dwarf_types.h"
+#include "dwarf_global.h"
+
+int
+dwarf_get_pubtypes(Dwarf_Debug dbg,
+    Dwarf_Type ** types,
+    Dwarf_Signed * ret_type_count, Dwarf_Error * error)
+{
+    int res = _dwarf_load_section(dbg, &dbg->de_debug_pubtypes,error);
+    if (res != DW_DLV_OK) {
+        return res;
+    }
+
+    return _dwarf_internal_get_pubnames_like_data(dbg, 
+        dbg->de_debug_pubtypes.dss_data, 
+        dbg->de_debug_pubtypes.dss_size, 
+        (Dwarf_Global **) types, /* Type punning for sections 
+            with identical format. */
+        ret_type_count, error, 
+        DW_DLA_PUBTYPES_CONTEXT, 
+        DW_DLA_GLOBAL, /* We don't have DW_DLA_PUBTYPES, 
+            so use DW_DLA_GLOBAL. */
+        DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD,
+        DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR);
+}
+
+/* Deallocating fully requires deallocating the list
+   and all entries.  But some internal data is
+   not exposed, so we need a function with internal knowledge.
+*/
+
+void
+dwarf_pubtypes_dealloc(Dwarf_Debug dbg, Dwarf_Type * dwgl,
+    Dwarf_Signed count)
+{
+    _dwarf_internal_globals_dealloc(dbg, 
+        (Dwarf_Global *) dwgl, 
+        count, 
+        DW_DLA_PUBTYPES_CONTEXT, 
+        DW_DLA_GLOBAL, /* We don't have DW_DLA_PUBTYPES, 
+            so use DW_DLA_GLOBAL. */
+        DW_DLA_LIST);
+    return;
+}
+
+
+
+int
+dwarf_pubtypename(Dwarf_Type type_in, char **ret_name,
+    Dwarf_Error * error)
+{
+    Dwarf_Global type = (Dwarf_Global) type_in;
+    if (type == NULL) {
+        _dwarf_error(NULL, error, DW_DLE_TYPE_NULL);
+        return (DW_DLV_ERROR);
+    }
+    *ret_name = (char *) (type->gl_name);
+    return DW_DLV_OK;
+}
+
+
+int
+dwarf_pubtype_type_die_offset(Dwarf_Type type_in,
+    Dwarf_Off * ret_offset,
+    Dwarf_Error * error)
+{
+    Dwarf_Global type = (Dwarf_Global) type_in;
+
+    return dwarf_global_die_offset(type, ret_offset, error);
+}
+
+
+int
+dwarf_pubtype_cu_offset(Dwarf_Type type_in,
+    Dwarf_Off * ret_offset, Dwarf_Error * error)
+{
+    Dwarf_Global type = (Dwarf_Global) type_in;
+
+    return dwarf_global_cu_offset(type, ret_offset, error);
+
+}
+
+
+int
+dwarf_pubtype_name_offsets(Dwarf_Type type_in,
+    char **returned_name,
+    Dwarf_Off * die_offset,
+    Dwarf_Off * cu_die_offset,
+    Dwarf_Error * error)
+{
+    Dwarf_Global type = (Dwarf_Global) type_in;
+
+    return dwarf_global_name_offsets(type,
+        returned_name,
+        die_offset, cu_die_offset, error);
+}
--- a/usr/src/tools/ctf/dwarf/common/dwarf_query.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_query.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -32,6 +33,13 @@
   http://oss.sgi.com/projects/GenInfo/NoticeExplan
 
 */
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
 
 
 #include "config.h"
@@ -39,30 +47,52 @@
 #include <stdio.h>
 #include "dwarf_die_deliv.h"
 
+/* This is normally reliable.
+But not always.
+If different compilation
+units have different address sizes 
+this may not give the correct value in all contexts. 
+If the Elf offset size != address_size 
+(for example if address_size = 4 but recorded in elf64 object)
+this may not give the correct value in all contexts. 
+*/
 int
 dwarf_get_address_size(Dwarf_Debug dbg,
-		       Dwarf_Half * ret_addr_size, Dwarf_Error * error)
+    Dwarf_Half * ret_addr_size, Dwarf_Error * error)
 {
-    Dwarf_Half address_size;
+    Dwarf_Half address_size = 0;
 
     if (dbg == 0) {
-	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
-    /* length size same as address size */
     address_size = dbg->de_pointer_size;
     *ret_addr_size = address_size;
     return DW_DLV_OK;
 }
 
+/* This will be correct in all contexts where the
+   CU context of a DIE is known.
+*/
+int
+dwarf_get_die_address_size(Dwarf_Die die,
+    Dwarf_Half * ret_addr_size, Dwarf_Error * error)
+{
+    Dwarf_Half address_size = 0;
+    CHECK_DIE(die, DW_DLV_ERROR);
+    address_size = die->di_cu_context->cc_address_size;
+    *ret_addr_size = address_size;
+    return DW_DLV_OK;
+}
+
 int
 dwarf_dieoffset(Dwarf_Die die,
-		Dwarf_Off * ret_offset, Dwarf_Error * error)
+    Dwarf_Off * ret_offset, Dwarf_Error * error)
 {
-    CHECK_DIE(die, DW_DLV_ERROR)
+    CHECK_DIE(die, DW_DLV_ERROR);
 
-	* ret_offset = (die->di_debug_info_ptr -
-			die->di_cu_context->cc_dbg->de_debug_info);
+    *ret_offset = (die->di_debug_info_ptr -
+        die->di_cu_context->cc_dbg->de_debug_info.dss_data);
     return DW_DLV_OK;
 }
 
@@ -75,123 +105,153 @@
 */
 int
 dwarf_die_CU_offset(Dwarf_Die die,
-		    Dwarf_Off * cu_off, Dwarf_Error * error)
+    Dwarf_Off * cu_off, Dwarf_Error * error)
 {
-    Dwarf_CU_Context cu_context;
+    Dwarf_CU_Context cu_context = 0;
 
-    CHECK_DIE(die, DW_DLV_ERROR)
-	cu_context = die->di_cu_context;
+    CHECK_DIE(die, DW_DLV_ERROR);
+    cu_context = die->di_cu_context;
 
     *cu_off =
-	(die->di_debug_info_ptr - cu_context->cc_dbg->de_debug_info -
-	 cu_context->cc_debug_info_offset);
+        (die->di_debug_info_ptr - cu_context->cc_dbg->de_debug_info.dss_data -
+         cu_context->cc_debug_info_offset);
     return DW_DLV_OK;
 }
 
+/*
+    This function returns the global offset 
+    (meaning the section offset) and length of
+    the CU that this die is a part of.
+    Used for correctness checking by dwarfdump.
+*/
+int
+dwarf_die_CU_offset_range(Dwarf_Die die,
+     Dwarf_Off * cu_off, 
+     Dwarf_Off * cu_length,
+     Dwarf_Error * error)
+{
+    Dwarf_CU_Context cu_context = 0;
+
+    CHECK_DIE(die, DW_DLV_ERROR);
+    cu_context = die->di_cu_context;
+
+    *cu_off = cu_context->cc_debug_info_offset;
+    *cu_length = cu_context->cc_length + cu_context->cc_length_size
+            + cu_context->cc_extension_size;
+    return DW_DLV_OK;
+}
+
+
 
 int
 dwarf_tag(Dwarf_Die die, Dwarf_Half * tag, Dwarf_Error * error)
 {
-    CHECK_DIE(die, DW_DLV_ERROR)
-
-
-	* tag = (die->di_abbrev_list->ab_tag);
+    CHECK_DIE(die, DW_DLV_ERROR);
+    *tag = (die->di_abbrev_list->ab_tag);
     return DW_DLV_OK;
 }
 
 
 int
 dwarf_attrlist(Dwarf_Die die,
-	       Dwarf_Attribute ** attrbuf,
-	       Dwarf_Signed * attrcnt, Dwarf_Error * error)
+    Dwarf_Attribute ** attrbuf,
+    Dwarf_Signed * attrcnt, Dwarf_Error * error)
 {
     Dwarf_Word attr_count = 0;
-    Dwarf_Word i;
-    Dwarf_Half attr;
-    Dwarf_Half attr_form;
-    Dwarf_Byte_Ptr abbrev_ptr;
-    Dwarf_Abbrev_List abbrev_list;
-    Dwarf_Attribute new_attr;
-    Dwarf_Attribute head_attr = NULL, curr_attr;
-    Dwarf_Attribute *attr_ptr;
-    Dwarf_Debug dbg;
-    Dwarf_Byte_Ptr info_ptr;
+    Dwarf_Word i = 0;
+    Dwarf_Half attr = 0;
+    Dwarf_Half attr_form = 0;
+    Dwarf_Byte_Ptr abbrev_ptr = 0;
+    Dwarf_Abbrev_List abbrev_list = 0;
+    Dwarf_Attribute new_attr = 0;
+    Dwarf_Attribute head_attr = NULL;
+    Dwarf_Attribute curr_attr = NULL;
+    Dwarf_Attribute *attr_ptr = 0;
+    Dwarf_Debug dbg = 0;
+    Dwarf_Byte_Ptr info_ptr = 0;
 
-    CHECK_DIE(die, DW_DLV_ERROR)
-	dbg = die->di_cu_context->cc_dbg;
+    CHECK_DIE(die, DW_DLV_ERROR);
+    dbg = die->di_cu_context->cc_dbg;
 
     abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context,
-					     die->di_abbrev_list->
-					     ab_code);
+                                             die->di_abbrev_list->
+                                             ab_code);
     if (abbrev_list == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_BAD);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_BAD);
+        return (DW_DLV_ERROR);
     }
     abbrev_ptr = abbrev_list->ab_abbrev_ptr;
 
     info_ptr = die->di_debug_info_ptr;
-    SKIP_LEB128_WORD(info_ptr)
+    SKIP_LEB128_WORD(info_ptr);
+
+    do {
+        Dwarf_Unsigned utmp2;
 
-	do {
-	Dwarf_Unsigned utmp2;
+        DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
+        attr = (Dwarf_Half) utmp2;
+        DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
+        attr_form = (Dwarf_Half) utmp2;
 
-	DECODE_LEB128_UWORD(abbrev_ptr, utmp2)
-	    attr = (Dwarf_Half) utmp2;
-	DECODE_LEB128_UWORD(abbrev_ptr, utmp2)
-	    attr_form = (Dwarf_Half) utmp2;
+        if (attr != 0) {
+            new_attr =
+                (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
+            if (new_attr == NULL) {
+                _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+                return (DW_DLV_ERROR);
+            }
 
-	if (attr != 0) {
-	    new_attr =
-		(Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
-	    if (new_attr == NULL) {
-		_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-		return (DW_DLV_ERROR);
-	    }
+            new_attr->ar_attribute = attr;
+            new_attr->ar_attribute_form_direct = attr_form;
+            new_attr->ar_attribute_form = attr_form;
+            if (attr_form == DW_FORM_indirect) {
+                Dwarf_Unsigned utmp6;
 
-	    new_attr->ar_attribute = attr;
-	    new_attr->ar_attribute_form_direct = attr_form;
-	    new_attr->ar_attribute_form = attr_form;
-	    if(attr_form == DW_FORM_indirect) {
-		Dwarf_Unsigned utmp6;
-		/* DECODE_LEB128_UWORD does info_ptr update */
-		DECODE_LEB128_UWORD(info_ptr, utmp6)
+                /* DECODE_LEB128_UWORD does info_ptr update */
+                DECODE_LEB128_UWORD(info_ptr, utmp6);
                 attr_form = (Dwarf_Half) utmp6;
-	        new_attr->ar_attribute_form = attr_form;
-	    }
-	    new_attr->ar_cu_context = die->di_cu_context;
-	    new_attr->ar_debug_info_ptr = info_ptr;
+                new_attr->ar_attribute_form = attr_form;
+            }
+            new_attr->ar_cu_context = die->di_cu_context;
+            new_attr->ar_debug_info_ptr = info_ptr;
 
-	    info_ptr += _dwarf_get_size_of_val(dbg, attr_form, info_ptr,
-					       die->di_cu_context->
-					       cc_length_size);
+            {
+                Dwarf_Unsigned sov = _dwarf_get_size_of_val(dbg, 
+                    attr_form, 
+                    die->di_cu_context->cc_address_size,
+                    info_ptr,
+                    die->di_cu_context->cc_length_size);
+                info_ptr += sov;
+            }
+ 
 
-	    if (head_attr == NULL)
-		head_attr = curr_attr = new_attr;
-	    else {
-		curr_attr->ar_next = new_attr;
-		curr_attr = new_attr;
-	    }
-	    attr_count++;
-	}
+            if (head_attr == NULL)
+                head_attr = curr_attr = new_attr;
+            else {
+                curr_attr->ar_next = new_attr;
+                curr_attr = new_attr;
+            }
+            attr_count++;
+        }
     } while (attr != 0 || attr_form != 0);
 
     if (attr_count == 0) {
-	*attrbuf = NULL;
-	*attrcnt = 0;
-	return (DW_DLV_NO_ENTRY);
+        *attrbuf = NULL;
+        *attrcnt = 0;
+        return (DW_DLV_NO_ENTRY);
     }
 
     attr_ptr = (Dwarf_Attribute *)
-	_dwarf_get_alloc(dbg, DW_DLA_LIST, attr_count);
+        _dwarf_get_alloc(dbg, DW_DLA_LIST, attr_count);
     if (attr_ptr == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
     }
 
     curr_attr = head_attr;
     for (i = 0; i < attr_count; i++) {
-	*(attr_ptr + i) = curr_attr;
-	curr_attr = curr_attr->ar_next;
+        *(attr_ptr + i) = curr_attr;
+        curr_attr = curr_attr->ar_next;
     }
 
     *attrbuf = attr_ptr;
@@ -212,50 +272,50 @@
 */
 static Dwarf_Byte_Ptr
 _dwarf_get_value_ptr(Dwarf_Die die,
-		     Dwarf_Half attr, Dwarf_Half * attr_form)
+    Dwarf_Half attr, Dwarf_Half * attr_form)
 {
-    Dwarf_Byte_Ptr abbrev_ptr;
+    Dwarf_Byte_Ptr abbrev_ptr = 0;
     Dwarf_Abbrev_List abbrev_list;
-    Dwarf_Half curr_attr;
-    Dwarf_Half curr_attr_form;
-    Dwarf_Byte_Ptr info_ptr;
+    Dwarf_Half curr_attr = 0;
+    Dwarf_Half curr_attr_form = 0;
+    Dwarf_Byte_Ptr info_ptr = 0;
 
     abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context,
-					     die->di_abbrev_list->
-					     ab_code);
+        die->di_abbrev_list->ab_code);
     if (abbrev_list == NULL) {
-	*attr_form = 0;
-	return (NULL);
+        *attr_form = 0;
+        return (NULL);
     }
     abbrev_ptr = abbrev_list->ab_abbrev_ptr;
 
     info_ptr = die->di_debug_info_ptr;
-    SKIP_LEB128_WORD(info_ptr)
+    SKIP_LEB128_WORD(info_ptr);
 
     do {
-	Dwarf_Unsigned utmp3;
+        Dwarf_Unsigned utmp3;
 
-	DECODE_LEB128_UWORD(abbrev_ptr, utmp3)
-	    curr_attr = (Dwarf_Half) utmp3;
-	DECODE_LEB128_UWORD(abbrev_ptr, utmp3)
-	    curr_attr_form = (Dwarf_Half) utmp3;
-	if(curr_attr_form == DW_FORM_indirect) {
-                Dwarf_Unsigned utmp6;
+        DECODE_LEB128_UWORD(abbrev_ptr, utmp3);
+        curr_attr = (Dwarf_Half) utmp3;
+        DECODE_LEB128_UWORD(abbrev_ptr, utmp3);
+        curr_attr_form = (Dwarf_Half) utmp3;
+        if (curr_attr_form == DW_FORM_indirect) {
+            Dwarf_Unsigned utmp6;
 
-	        /* DECODE_LEB128_UWORD updates info_ptr */
-                DECODE_LEB128_UWORD(info_ptr, utmp6)
-                curr_attr_form = (Dwarf_Half) utmp6;
+            /* DECODE_LEB128_UWORD updates info_ptr */
+            DECODE_LEB128_UWORD(info_ptr, utmp6);
+            curr_attr_form = (Dwarf_Half) utmp6;
         }
 
-	if (curr_attr == attr) {
-	    *attr_form = curr_attr_form;
-	    return (info_ptr);
-	}
+        if (curr_attr == attr) {
+            *attr_form = curr_attr_form;
+            return (info_ptr);
+        }
 
-	info_ptr += _dwarf_get_size_of_val(die->di_cu_context->cc_dbg,
-					   curr_attr_form, info_ptr,
-					   die->di_cu_context->
-					   cc_length_size);
+        info_ptr += _dwarf_get_size_of_val(die->di_cu_context->cc_dbg,
+                         curr_attr_form, 
+                         die->di_cu_context->cc_address_size,
+                         info_ptr, 
+                         die->di_cu_context->cc_length_size);
     } while (curr_attr != 0 || curr_attr_form != 0);
 
     *attr_form = 1;
@@ -266,74 +326,70 @@
 int
 dwarf_diename(Dwarf_Die die, char **ret_name, Dwarf_Error * error)
 {
-    Dwarf_Half attr_form;
-    Dwarf_Debug dbg;
-    Dwarf_Byte_Ptr info_ptr;
-    Dwarf_Unsigned string_offset;
-    int res;
+    Dwarf_Half attr_form = 0;
+    Dwarf_Debug dbg = 0;
+    Dwarf_Byte_Ptr info_ptr = 0;
+    Dwarf_Unsigned string_offset = 0;
+    int res = DW_DLV_ERROR;
 
-    CHECK_DIE(die, DW_DLV_ERROR)
+    CHECK_DIE(die, DW_DLV_ERROR);
 
-	info_ptr = _dwarf_get_value_ptr(die, DW_AT_name, &attr_form);
+    info_ptr = _dwarf_get_value_ptr(die, DW_AT_name, &attr_form);
     if (info_ptr == NULL) {
-	if (attr_form == 0) {
-	    _dwarf_error(die->di_cu_context->cc_dbg, error,
-			 DW_DLE_DIE_BAD);
-	    return (DW_DLV_ERROR);
-	}
-	return DW_DLV_NO_ENTRY;
+        if (attr_form == 0) {
+            _dwarf_error(die->di_cu_context->cc_dbg, error,
+                         DW_DLE_DIE_BAD);
+            return (DW_DLV_ERROR);
+        }
+        return DW_DLV_NO_ENTRY;
     }
 
     if (attr_form == DW_FORM_string) {
-	*ret_name = (char *) (info_ptr);
-	return DW_DLV_OK;
+        *ret_name = (char *) (info_ptr);
+        return DW_DLV_OK;
     }
 
     dbg = die->di_cu_context->cc_dbg;
     if (attr_form != DW_FORM_strp) {
-	_dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
+        return (DW_DLV_ERROR);
     }
 
     READ_UNALIGNED(dbg, string_offset, Dwarf_Unsigned,
-		   info_ptr, die->di_cu_context->cc_length_size);
+        info_ptr, die->di_cu_context->cc_length_size);
 
-    if (string_offset >= dbg->de_debug_str_size) {
-	_dwarf_error(dbg, error, DW_DLE_STRING_OFFSET_BAD);
-	return (DW_DLV_ERROR);
+    if (string_offset >= dbg->de_debug_str.dss_size) {
+        _dwarf_error(dbg, error, DW_DLE_STRING_OFFSET_BAD);
+        return (DW_DLV_ERROR);
     }
 
-    res =
-       _dwarf_load_section(dbg,
-                           dbg->de_debug_str_index,
-                           &dbg->de_debug_str,
-                           error);
+    res = _dwarf_load_section(dbg, &dbg->de_debug_str,error);
     if (res != DW_DLV_OK) {
         return res;
     }
 
-    *ret_name = (char *) (dbg->de_debug_str + string_offset);
+    *ret_name = (char *) (dbg->de_debug_str.dss_data + string_offset);
     return DW_DLV_OK;
 }
 
 
 int
 dwarf_hasattr(Dwarf_Die die,
-	      Dwarf_Half attr,
-	      Dwarf_Bool * return_bool, Dwarf_Error * error)
+    Dwarf_Half attr,
+    Dwarf_Bool * return_bool, Dwarf_Error * error)
 {
-    Dwarf_Half attr_form;
+    Dwarf_Half attr_form = 0;
 
-    CHECK_DIE(die, DW_DLV_ERROR)
+    CHECK_DIE(die, DW_DLV_ERROR);
 
-	if (_dwarf_get_value_ptr(die, attr, &attr_form) == NULL) {
-	if (attr_form == 0) {
-	    _dwarf_error(die->di_cu_context->cc_dbg, error,
-			 DW_DLE_DIE_BAD);
-	    return (DW_DLV_ERROR);
-	}
-	*return_bool = false;
-	return DW_DLV_OK;
+    if (_dwarf_get_value_ptr(die, attr, &attr_form) == NULL) {
+        if (attr_form == 0) {
+            _dwarf_error(die->di_cu_context->cc_dbg, error,
+                DW_DLE_DIE_BAD);
+            return (DW_DLV_ERROR);
+        }
+        *return_bool = false;
+        return DW_DLV_OK;
     }
 
     *return_bool = (true);
@@ -343,30 +399,30 @@
 
 int
 dwarf_attr(Dwarf_Die die,
-	   Dwarf_Half attr,
-	   Dwarf_Attribute * ret_attr, Dwarf_Error * error)
+    Dwarf_Half attr,
+    Dwarf_Attribute * ret_attr, Dwarf_Error * error)
 {
-    Dwarf_Half attr_form;
-    Dwarf_Attribute attrib;
-    Dwarf_Byte_Ptr info_ptr;
-    Dwarf_Debug dbg;
+    Dwarf_Half attr_form = 0;
+    Dwarf_Attribute attrib = 0;
+    Dwarf_Byte_Ptr info_ptr = 0;
+    Dwarf_Debug dbg = 0;
 
-    CHECK_DIE(die, DW_DLV_ERROR)
-	dbg = die->di_cu_context->cc_dbg;
+    CHECK_DIE(die, DW_DLV_ERROR);
+    dbg = die->di_cu_context->cc_dbg;
 
     info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form);
     if (info_ptr == NULL) {
-	if (attr_form == 0) {
-	    _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
-	    return (DW_DLV_ERROR);
-	}
-	return DW_DLV_NO_ENTRY;
+        if (attr_form == 0) {
+            _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
+            return (DW_DLV_ERROR);
+        }
+        return DW_DLV_NO_ENTRY;
     }
 
     attrib = (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
     if (attrib == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (DW_DLV_ERROR);
     }
 
     attrib->ar_attribute = attr;
@@ -381,29 +437,31 @@
 
 int
 dwarf_lowpc(Dwarf_Die die,
-	    Dwarf_Addr * return_addr, Dwarf_Error * error)
+    Dwarf_Addr * return_addr, Dwarf_Error * error)
 {
-    Dwarf_Addr ret_addr;
-    Dwarf_Byte_Ptr info_ptr;
-    Dwarf_Half attr_form;
-    Dwarf_Debug dbg;
+    Dwarf_Addr ret_addr = 0;
+    Dwarf_Byte_Ptr info_ptr = 0;
+    Dwarf_Half attr_form = 0;
+    Dwarf_Debug dbg = 0;
+    Dwarf_Half address_size = 0;
 
-    CHECK_DIE(die, DW_DLV_ERROR)
+    CHECK_DIE(die, DW_DLV_ERROR);
 
-	dbg = die->di_cu_context->cc_dbg;
+    dbg = die->di_cu_context->cc_dbg;
+    address_size = die->di_cu_context->cc_address_size;
     info_ptr = _dwarf_get_value_ptr(die, DW_AT_low_pc, &attr_form);
     if ((info_ptr == NULL && attr_form == 0) ||
-	(info_ptr != NULL && attr_form != DW_FORM_addr)) {
-	_dwarf_error(dbg, error, DW_DLE_DIE_BAD);
-	return (DW_DLV_ERROR);
+        (info_ptr != NULL && attr_form != DW_FORM_addr)) {
+        _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
+        return (DW_DLV_ERROR);
     }
     if (info_ptr == NULL) {
-	return (DW_DLV_NO_ENTRY);
+        return (DW_DLV_NO_ENTRY);
     }
 
 
     READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
-		   info_ptr, dbg->de_pointer_size);
+                   info_ptr, address_size);
 
     *return_addr = ret_addr;
     return (DW_DLV_OK);
@@ -412,28 +470,29 @@
 
 int
 dwarf_highpc(Dwarf_Die die,
-	     Dwarf_Addr * return_addr, Dwarf_Error * error)
+    Dwarf_Addr * return_addr, Dwarf_Error * error)
 {
-    Dwarf_Addr ret_addr;
-    Dwarf_Byte_Ptr info_ptr;
-    Dwarf_Half attr_form;
-    Dwarf_Debug dbg;
+    Dwarf_Addr ret_addr = 0;
+    Dwarf_Byte_Ptr info_ptr = 0;
+    Dwarf_Half attr_form = 0;
+    Dwarf_Debug dbg = 0;
+    Dwarf_Half address_size = 0;
 
-    CHECK_DIE(die, DW_DLV_ERROR)
-
-	dbg = die->di_cu_context->cc_dbg;
+    CHECK_DIE(die, DW_DLV_ERROR);
+    dbg = die->di_cu_context->cc_dbg;
+    address_size = die->di_cu_context->cc_address_size;
     info_ptr = _dwarf_get_value_ptr(die, DW_AT_high_pc, &attr_form);
     if ((info_ptr == NULL && attr_form == 0) ||
-	(info_ptr != NULL && attr_form != DW_FORM_addr)) {
-	_dwarf_error(dbg, error, DW_DLE_DIE_BAD);
-	return (DW_DLV_ERROR);
+        (info_ptr != NULL && attr_form != DW_FORM_addr)) {
+        _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
+        return (DW_DLV_ERROR);
     }
     if (info_ptr == NULL) {
-	return (DW_DLV_NO_ENTRY);
+        return (DW_DLV_NO_ENTRY);
     }
 
     READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
-		   info_ptr, dbg->de_pointer_size);
+                   info_ptr, address_size);
 
     *return_addr = ret_addr;
     return (DW_DLV_OK);
@@ -453,56 +512,56 @@
 */
 static int
 _dwarf_die_attr_unsigned_constant(Dwarf_Die die,
-				  Dwarf_Half attr,
-				  Dwarf_Unsigned * return_val,
-				  Dwarf_Error * error)
+    Dwarf_Half attr,
+    Dwarf_Unsigned * return_val,
+    Dwarf_Error * error)
 {
     Dwarf_Byte_Ptr info_ptr;
     Dwarf_Half attr_form;
     Dwarf_Unsigned ret_value;
     Dwarf_Debug dbg;
 
-    CHECK_DIE(die, DW_DLV_ERROR)
+    CHECK_DIE(die, DW_DLV_ERROR);
 
-	dbg = die->di_cu_context->cc_dbg;
+    dbg = die->di_cu_context->cc_dbg;
     info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form);
     if (info_ptr != NULL) {
-	switch (attr_form) {
+        switch (attr_form) {
 
-	case DW_FORM_data1:
-	    *return_val = (*(Dwarf_Small *) info_ptr);
-	    return (DW_DLV_OK);
+        case DW_FORM_data1:
+            *return_val = (*(Dwarf_Small *) info_ptr);
+            return (DW_DLV_OK);
 
-	case DW_FORM_data2:
-	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
-			   info_ptr, sizeof(Dwarf_Shalf));
-	    *return_val = ret_value;
-	    return (DW_DLV_OK);
+        case DW_FORM_data2:
+            READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+                           info_ptr, sizeof(Dwarf_Shalf));
+            *return_val = ret_value;
+            return (DW_DLV_OK);
 
-	case DW_FORM_data4:
-	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
-			   info_ptr, sizeof(Dwarf_sfixed));
-	    *return_val = ret_value;
-	    return (DW_DLV_OK);
+        case DW_FORM_data4:
+            READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+                           info_ptr, sizeof(Dwarf_sfixed));
+            *return_val = ret_value;
+            return (DW_DLV_OK);
 
-	case DW_FORM_data8:
-	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
-			   info_ptr, sizeof(Dwarf_Unsigned));
-	    *return_val = ret_value;
-	    return (DW_DLV_OK);
+        case DW_FORM_data8:
+            READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+                           info_ptr, sizeof(Dwarf_Unsigned));
+            *return_val = ret_value;
+            return (DW_DLV_OK);
 
-	case DW_FORM_udata:
-	    *return_val = (_dwarf_decode_u_leb128(info_ptr, NULL));
-	    return (DW_DLV_OK);
+        case DW_FORM_udata:
+            *return_val = (_dwarf_decode_u_leb128(info_ptr, NULL));
+            return (DW_DLV_OK);
 
-	default:
-	    _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
-	    return (DW_DLV_ERROR);
-	}
+        default:
+            _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
+            return (DW_DLV_ERROR);
+        }
     }
     if (attr_form == 0) {
-	_dwarf_error(dbg, error, DW_DLE_DIE_BAD);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
+        return (DW_DLV_ERROR);
     }
     return DW_DLV_NO_ENTRY;
 }
@@ -510,12 +569,11 @@
 
 int
 dwarf_bytesize(Dwarf_Die die,
-	       Dwarf_Unsigned * ret_size, Dwarf_Error * error)
+    Dwarf_Unsigned * ret_size, Dwarf_Error * error)
 {
-    Dwarf_Unsigned luns;
-    int res =
-	_dwarf_die_attr_unsigned_constant(die, DW_AT_byte_size, &luns,
-					  error);
+    Dwarf_Unsigned luns = 0;
+    int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_byte_size, 
+        &luns, error);
     *ret_size = luns;
     return res;
 }
@@ -523,14 +581,11 @@
 
 int
 dwarf_bitsize(Dwarf_Die die,
-	      Dwarf_Unsigned * ret_size, Dwarf_Error * error)
+    Dwarf_Unsigned * ret_size, Dwarf_Error * error)
 {
-    Dwarf_Unsigned luns;
-    int res;
-
-    res =
-	_dwarf_die_attr_unsigned_constant(die, DW_AT_bit_size, &luns,
-					  error);
+    Dwarf_Unsigned luns = 0;
+    int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_size, 
+        &luns, error);
     *ret_size = luns;
     return res;
 }
@@ -538,14 +593,11 @@
 
 int
 dwarf_bitoffset(Dwarf_Die die,
-		Dwarf_Unsigned * ret_size, Dwarf_Error * error)
+    Dwarf_Unsigned * ret_size, Dwarf_Error * error)
 {
-    Dwarf_Unsigned luns;
-    int res;
-
-    res =
-	_dwarf_die_attr_unsigned_constant(die, DW_AT_bit_offset, &luns,
-					  error);
+    Dwarf_Unsigned luns = 0;
+    int res = _dwarf_die_attr_unsigned_constant(die, 
+        DW_AT_bit_offset, &luns, error);
     *ret_size = luns;
     return res;
 }
@@ -554,14 +606,11 @@
 /* Refer section 3.1, page 21 in Dwarf Definition. */
 int
 dwarf_srclang(Dwarf_Die die,
-	      Dwarf_Unsigned * ret_size, Dwarf_Error * error)
+    Dwarf_Unsigned * ret_size, Dwarf_Error * error)
 {
-    Dwarf_Unsigned luns;
-    int res;
-
-    res =
-	_dwarf_die_attr_unsigned_constant(die, DW_AT_language, &luns,
-					  error);
+    Dwarf_Unsigned luns = 0;
+    int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_language, 
+        &luns, error);
     *ret_size = luns;
     return res;
 }
@@ -570,40 +619,171 @@
 /* Refer section 5.4, page 37 in Dwarf Definition. */
 int
 dwarf_arrayorder(Dwarf_Die die,
-		 Dwarf_Unsigned * ret_size, Dwarf_Error * error)
+    Dwarf_Unsigned * ret_size, Dwarf_Error * error)
 {
-    Dwarf_Unsigned luns;
-    int res;
-
-    res =
-	_dwarf_die_attr_unsigned_constant(die, DW_AT_ordering, &luns,
-					  error);
+    Dwarf_Unsigned luns = 0;
+    int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_ordering, 
+        &luns, error);
     *ret_size = luns;
     return res;
 }
 
 /*
-	Return DW_DLV_OK if ok
-	DW_DLV_ERROR if failure.
+        Return DW_DLV_OK if ok
+        DW_DLV_ERROR if failure.
 
-	If the die and the attr are not related the result is
-	meaningless.
+        If the die and the attr are not related the result is
+        meaningless.
 */
 int
-dwarf_attr_offset(Dwarf_Die die, Dwarf_Attribute attr, Dwarf_Off * offset,	/* return 
-										   offset 
-										   thru 
-										   this 
-										   ptr 
-										 */
-		  Dwarf_Error * error)
+dwarf_attr_offset(Dwarf_Die die, Dwarf_Attribute attr, 
+    Dwarf_Off * offset /* return offset thru this ptr */,
+    Dwarf_Error * error)
 {
-    Dwarf_Off attroff;
+    Dwarf_Off attroff = 0;
 
-    CHECK_DIE(die, DW_DLV_ERROR)
+    CHECK_DIE(die, DW_DLV_ERROR);
 
-	attroff = (attr->ar_debug_info_ptr -
-		   die->di_cu_context->cc_dbg->de_debug_info);
+    attroff = (attr->ar_debug_info_ptr -
+               die->di_cu_context->cc_dbg->de_debug_info.dss_data);
     *offset = attroff;
     return DW_DLV_OK;
 }
+
+int
+dwarf_die_abbrev_code(Dwarf_Die die)
+{
+    return die->di_abbrev_code;
+}
+
+/* Helper function for finding form class. */
+static enum Dwarf_Form_Class 
+dw_get_special_offset(Dwarf_Half attrnum)
+{
+    switch(attrnum) {
+    case DW_AT_stmt_list:
+             return DW_FORM_CLASS_LINEPTR;
+    case DW_AT_macro_info:
+             return DW_FORM_CLASS_MACPTR;
+    case DW_AT_ranges:
+             return DW_FORM_CLASS_RANGELISTPTR;
+    case DW_AT_location:
+    case DW_AT_string_length:
+    case DW_AT_return_addr:
+    case DW_AT_data_member_location:
+    case DW_AT_frame_base:
+    case DW_AT_segment:
+    case DW_AT_static_link:
+    case DW_AT_use_location:
+    case DW_AT_vtable_elem_location:
+             return DW_FORM_CLASS_LOCLISTPTR;
+    case DW_AT_sibling:
+    case DW_AT_byte_size :
+    case DW_AT_bit_offset :
+    case DW_AT_bit_size :
+    case DW_AT_discr :
+    case DW_AT_import :
+    case DW_AT_common_reference:
+    case DW_AT_containing_type:
+    case DW_AT_default_value:
+    case DW_AT_lower_bound:
+    case DW_AT_bit_stride:
+    case DW_AT_upper_bound:
+    case DW_AT_abstract_origin:
+    case DW_AT_base_types:
+    case DW_AT_count:
+    case DW_AT_friend:
+    case DW_AT_namelist_item:
+    case DW_AT_priority:
+    case DW_AT_specification:
+    case DW_AT_type:
+    case DW_AT_allocated:
+    case DW_AT_associated:
+    case DW_AT_byte_stride:
+    case DW_AT_extension:
+    case DW_AT_trampoline:
+    case DW_AT_small:
+    case DW_AT_object_pointer:
+    case DW_AT_signature:
+                return DW_FORM_CLASS_REFERENCE;
+    case DW_AT_MIPS_fde: /* SGI/IRIX extension */
+                return DW_FORM_CLASS_FRAMEPTR;
+    }
+    return DW_FORM_CLASS_UNKNOWN;
+}
+
+/* It takes 4 pieces of data (including the FORM)
+   to accurately determine the form 'class' as documented
+   in the DWARF spec. This is per DWARF4, but will work
+   for DWARF2 or 3 as well.  */
+enum Dwarf_Form_Class dwarf_get_form_class(
+    Dwarf_Half dwversion,
+    Dwarf_Half attrnum, 
+    Dwarf_Half offset_size, 
+    Dwarf_Half form)
+{
+    switch(form) {
+    case  DW_FORM_addr: return DW_FORM_CLASS_ADDRESS;
+
+    case  DW_FORM_data2:  return DW_FORM_CLASS_CONSTANT;
+
+    case  DW_FORM_data4: 
+        if(dwversion <= 3 && offset_size == 4) {
+            enum Dwarf_Form_Class class = dw_get_special_offset(attrnum);
+            if(class != DW_FORM_CLASS_UNKNOWN) {
+                return class;
+            }
+        }
+        return DW_FORM_CLASS_CONSTANT;
+    case  DW_FORM_data8:
+        if(dwversion <= 3 && offset_size == 8) {
+            enum Dwarf_Form_Class class = dw_get_special_offset(attrnum);
+            if(class != DW_FORM_CLASS_UNKNOWN) {
+                return class;
+            }
+        }
+        return DW_FORM_CLASS_CONSTANT;
+
+    case  DW_FORM_sec_offset:
+        {
+            enum Dwarf_Form_Class class = dw_get_special_offset(attrnum);
+            if(class != DW_FORM_CLASS_UNKNOWN) {
+                return class;
+            }
+        }
+        /* We do not know what this is. */
+        break;
+
+    case  DW_FORM_string: return DW_FORM_CLASS_STRING;
+    case  DW_FORM_strp:   return DW_FORM_CLASS_STRING;
+
+    case  DW_FORM_block:  return DW_FORM_CLASS_BLOCK;
+    case  DW_FORM_block1: return DW_FORM_CLASS_BLOCK;
+    case  DW_FORM_block2: return DW_FORM_CLASS_BLOCK;
+    case  DW_FORM_block4: return DW_FORM_CLASS_BLOCK;
+
+    case  DW_FORM_data1:  return DW_FORM_CLASS_CONSTANT;
+    case  DW_FORM_sdata:  return DW_FORM_CLASS_CONSTANT;
+    case  DW_FORM_udata:  return DW_FORM_CLASS_CONSTANT;
+
+    case  DW_FORM_ref_addr:    return DW_FORM_CLASS_REFERENCE;
+    case  DW_FORM_ref1:        return DW_FORM_CLASS_REFERENCE;
+    case  DW_FORM_ref2:        return DW_FORM_CLASS_REFERENCE;
+    case  DW_FORM_ref4:        return DW_FORM_CLASS_REFERENCE;
+    case  DW_FORM_ref8:        return DW_FORM_CLASS_REFERENCE;
+    case  DW_FORM_ref_udata:   return DW_FORM_CLASS_REFERENCE;
+    case  DW_FORM_ref_sig8:    return DW_FORM_CLASS_REFERENCE;
+
+    case  DW_FORM_exprloc:      return DW_FORM_CLASS_EXPRLOC;
+
+    case  DW_FORM_flag:         return DW_FORM_CLASS_FLAG;
+    case  DW_FORM_flag_present: return DW_FORM_CLASS_FLAG;
+
+   
+    case  DW_FORM_indirect: 
+    default: 
+        break;
+    };
+    return DW_FORM_CLASS_UNKNOWN;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_ranges.c	Sun May 22 03:13:22 2011 +0100
@@ -0,0 +1,171 @@
+/*
+
+  Copyright (C) 2008-2010 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+
+#include "config.h"
+#include <stdlib.h>
+#include "dwarf_incl.h"
+
+struct ranges_entry {
+   struct ranges_entry *next;
+   Dwarf_Ranges cur;
+};
+
+
+#define MAX_ADDR ((address_size == 8)?0xffffffffffffffffULL:0xffffffff)
+int dwarf_get_ranges_a(Dwarf_Debug dbg,
+    Dwarf_Off rangesoffset,
+    Dwarf_Die die,
+    Dwarf_Ranges ** rangesbuf,
+    Dwarf_Signed * listlen,
+    Dwarf_Unsigned * bytecount,
+    Dwarf_Error * error)
+{
+    Dwarf_Small *rangeptr = 0;
+    Dwarf_Small *beginrangeptr = 0;
+    Dwarf_Small *section_end = 0;
+    unsigned entry_count = 0;
+    struct ranges_entry *base = 0;
+    struct ranges_entry *last = 0;
+    struct ranges_entry *curre = 0;
+    Dwarf_Ranges * ranges_data_out = 0;
+    unsigned copyindex = 0;
+    Dwarf_Half address_size = 0;
+    int res = DW_DLV_ERROR;
+
+    res = _dwarf_load_section(dbg, &dbg->de_debug_ranges,error);
+    if (res != DW_DLV_OK) {
+        return res;
+    }
+    if(rangesoffset >= dbg->de_debug_ranges.dss_size) {
+        _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OFFSET_BAD);
+        return (DW_DLV_ERROR);
+
+    }
+    address_size = _dwarf_get_address_size(dbg, die);
+    section_end = dbg->de_debug_ranges.dss_data + 
+        dbg->de_debug_ranges.dss_size;
+    rangeptr = dbg->de_debug_ranges.dss_data + rangesoffset;
+    beginrangeptr = rangeptr;
+
+    for(;;) {
+        struct ranges_entry * re = calloc(sizeof(struct ranges_entry),1);
+        if(!re) {
+            _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OUT_OF_MEM);
+            return (DW_DLV_ERROR);
+        }
+        if(rangeptr  >= section_end) {
+            return (DW_DLV_NO_ENTRY);
+        }
+        if((rangeptr + (2*address_size)) > section_end) {
+            _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OFFSET_BAD);
+            return (DW_DLV_ERROR);
+        }
+        entry_count++;
+        READ_UNALIGNED(dbg,re->cur.dwr_addr1,
+                       Dwarf_Addr, rangeptr,
+                       address_size);
+        rangeptr +=  address_size;
+        READ_UNALIGNED(dbg,re->cur.dwr_addr2 ,
+                       Dwarf_Addr, rangeptr,
+                       address_size);
+        rangeptr +=  address_size;
+        if(!base) {
+           base = re;
+           last = re;
+        } else {
+           last->next = re;
+           last = re;
+        }
+        if(re->cur.dwr_addr1 == 0 && re->cur.dwr_addr2 == 0) {
+            re->cur.dwr_type =  DW_RANGES_END;
+            break;
+        } else if ( re->cur.dwr_addr1 == MAX_ADDR) {
+            re->cur.dwr_type =  DW_RANGES_ADDRESS_SELECTION;
+        } else {
+            re->cur.dwr_type =  DW_RANGES_ENTRY;
+        }
+    }
+
+    ranges_data_out =   (Dwarf_Ranges *)
+    _dwarf_get_alloc(dbg,DW_DLA_RANGES,entry_count);
+    if(!ranges_data_out) {
+            _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OUT_OF_MEM);
+            return (DW_DLV_ERROR);
+    }
+    curre = base;
+    *rangesbuf = ranges_data_out;
+    *listlen = entry_count;
+    for( copyindex = 0; curre && (copyindex < entry_count); 
+        ++copyindex,++ranges_data_out) {
+
+        struct ranges_entry *r = curre;
+        *ranges_data_out = curre->cur;
+        curre = curre->next;
+        free(r);
+    }
+    /* Callers will often not care about the bytes used. */
+    if(bytecount) {
+        *bytecount = rangeptr - beginrangeptr;
+    }
+    return DW_DLV_OK; 
+}
+int dwarf_get_ranges(Dwarf_Debug dbg,
+    Dwarf_Off rangesoffset,
+    Dwarf_Ranges ** rangesbuf,
+    Dwarf_Signed * listlen,
+    Dwarf_Unsigned * bytecount,
+    Dwarf_Error * error)
+{
+    Dwarf_Die die = 0;
+    int res = dwarf_get_ranges_a(dbg,rangesoffset,die,
+        rangesbuf,listlen,bytecount,error);
+    return res;
+}
+
+void 
+dwarf_ranges_dealloc(Dwarf_Debug dbg, Dwarf_Ranges * rangesbuf,
+    Dwarf_Signed rangecount)
+{
+    dwarf_dealloc(dbg,rangesbuf, DW_DLA_RANGES);
+   
+}
+
--- a/usr/src/tools/ctf/dwarf/common/dwarf_sort_line.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_sort_line.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
-
-  Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2002,2004,2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +19,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -32,6 +32,20 @@
   http://oss.sgi.com/projects/GenInfo/NoticeExplan
 
 */
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+/* This file was designed for SGI IRIX compiler use.
+   The static linker can rearrange the order of functions
+   in the layout in memory
+   and provided each has the right  form
+   this will (when called by the SGI IRIX
+   static linker) rearrange the table so the line table
+   is arranged in the same order as the memory layout. */
 
 
 
@@ -43,97 +57,115 @@
 #ifdef HAVE_ALLOCA_H
 #include <alloca.h>
 #endif
-#include <malloc.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
 
-#define MINIMUM_POSSIBLE_PROLOG_LEN 10  /* 10 is  based on */
-	/*  the definition of the DWARF2/3 line table prolog.
-	    The value here should be >8 (accounting for
-	    a 64 bit read) and  <= the length
-	    of a legal DWARF2/3 line prolog, 
-	    which is at least 10 bytes long (but can be longer).
-	    What this constant helps avoid is reading past the end of a 
-	    malloc'd buffer in _dwarf_update_line_sec().
-	*/
+#define MINIMUM_POSSIBLE_PROLOG_LEN 10  /* 10 is based on */
+        /* the definition of the DWARF2/3 line table prolog. The value
+           here should be >8 (accounting for a 64 bit read) and <= the
+           length of a legal DWARF2/3 line prolog, which is at least 10 
+           bytes long (but can be longer). What this constant helps
+           avoid is reading past the end of a malloc'd buffer in
+           _dwarf_update_line_sec(). */
 
 static int
   _dwarf_update_line_sec(Dwarf_Small * line_ptr,
-			 unsigned long remaining_bytes,
-			 int *any_change,
-			 int length_size,
-			 int *err_code, Dwarf_Small ** new_line_ptr);
+                         unsigned long remaining_bytes,
+                         int *any_change,
+                         int length_size,
+                         int *err_code, Dwarf_Small ** new_line_ptr);
 
 /* Used to construct
    a linked list of so we can sort and reorder the line info.
 */
 struct a_line_area {
-    Dwarf_Addr ala_address;	/* from DW_LNE_set_address */
-    Dwarf_Unsigned ala_offset;	/* byte offset in buffer */
-    Dwarf_Unsigned ala_length;	/* byte length in buffer */
-    int ala_entry_num;		/* to guarantee stable sort */
+    Dwarf_Addr ala_address;     /* from DW_LNE_set_address */
+    Dwarf_Unsigned ala_offset;  /* byte offset in buffer */
+    Dwarf_Unsigned ala_length;  /* byte length in buffer */
+    long ala_entry_num;         /* to guarantee stable sort */
     struct a_line_area *ala_next;
 };
 
 
+/*
+        Written to support the SGI IRIX static linker. 
+        It helps SGI IRIX ld 
+        rearrange lines in .debug_line in a .o created with a text
+        section per function.   The SGI IRIX linker option is: 
+                -OPT:procedure_reorder=ON
+        where ld-cord (cord(1)ing by ld, 
+        not by cord(1)) may have changed the function order.
 
-/* 
-	returns
-	DW_DLV_OK if nothing went wrong.
-	DW_DLV_ERROR if could not do anything due to
-		error.  the original buffer is unchanged.
-
-	is_64_bit must be passed in by caller and tells
-	if this is a 32 or 64bit pointer object section
-	being processed.
+        Returns
+        DW_DLV_OK if nothing went wrong.
+        DW_DLV_ERROR if could not do anything due to
+                error.  the original buffer is unchanged.
 
-	err_code must be a non-null pointer to integer.
-	If DW_DLV_ERROR is returned that integer is set
-	to a dwarf error code so the caller may
-	print it for diagnostic purposes.
+        is_64_bit must be passed in by caller and tells
+        if this is a 32 or 64bit pointer object section
+        being processed.
+
+        err_code must be a non-null pointer to integer.
+        If DW_DLV_ERROR is returned that integer is set
+        to a dwarf error code so the caller may
+        print it for diagnostic purposes.
 
-	*any_change is set here 
-		set 0 if no sorting (movement) done.
-		set 1 if some sorting (movement) done.
-	on all returns. On error return sets to 0.
-	
+        *any_change is set here 
+                set 0 if no sorting (movement) done.
+                set 1 if some sorting (movement) done.
+        on all returns. On error return sets to 0.
+        
+        The _dwarf name form is now obsolete,
+        the dwarf_ name for is preferred.
+        Both names supported.
 
 */
 int
 _dwarf_ld_sort_lines(void *orig_buffer,
-		     unsigned long buffer_len,
-		     int is_64_bit, int *any_change, int *err_code)
+                     unsigned long buffer_len,
+                     int is_64_bit, int *any_change, int *err_code)
+{
+    return dwarf_ld_sort_lines(orig_buffer,buffer_len,
+        is_64_bit,any_change,err_code);
+}
+int
+dwarf_ld_sort_lines(void *orig_buffer,
+                     unsigned long buffer_len,
+                     int is_64_bit, int *any_change, int *err_code)
 {
 
     int length_size = 4;
-    Dwarf_Small *orig_line_ptr;	/* our local copy of the user's input
-				   buffer */
-    Dwarf_Small *line_ptr;	/* starts at orig_line_ptr, gets
-				   incremented thru to end of our copy
-				   of the input buffer */
-    Dwarf_Small *new_line_ptr;	/* output of _dwarf_update_line_sec(),
-				   used to update line_ptr as we pass
-				   thru compilation units in a .o
-				   .debug_line */
+    Dwarf_Small *orig_line_ptr; /* our local copy of the user's input
+                                   buffer */
+    Dwarf_Small *line_ptr;      /* starts at orig_line_ptr, gets
+                                   incremented thru to end of our copy
+                                   of the input buffer */
+    Dwarf_Small *new_line_ptr;  /* output of _dwarf_update_line_sec(),
+                                   used to update line_ptr as we pass
+                                   thru compilation units in a .o
+                                   .debug_line */
 
-    unsigned long remaining_bytes = buffer_len;	/* total length of
-						   original area left
-						   to be processed.
-						   Changes as we pass
-						   thru compilation
-						   units in a .o
-						   .debug_line */
+    unsigned long remaining_bytes = buffer_len; /* total length of
+                                                   original area left
+                                                   to be processed.
+                                                   Changes as we pass
+                                                   thru compilation
+                                                   units in a .o
+                                                   .debug_line */
 
     int sec_res;
     int lany_change = 0;
     int did_change = 0;
 
     if (is_64_bit)
-	length_size = 8;
+        length_size = 8;
 
     *any_change = 0;
     line_ptr = malloc(buffer_len);
     if (!line_ptr) {
-	*err_code = DW_DLE_ALLOC_FAIL;
-	return DW_DLV_ERROR;
+        *err_code = DW_DLE_ALLOC_FAIL;
+        return DW_DLV_ERROR;
     }
     orig_line_ptr = line_ptr;
     memcpy(line_ptr, orig_buffer, buffer_len);
@@ -146,42 +178,41 @@
     sec_res = DW_DLV_OK;
 
     for (sec_res = _dwarf_update_line_sec(line_ptr,
-					  remaining_bytes,
-					  &lany_change,
-					  length_size,
-					  err_code,
-					  &new_line_ptr);
-	 (sec_res == DW_DLV_OK) && (remaining_bytes > 0);
-	 sec_res = _dwarf_update_line_sec(line_ptr,
-					  remaining_bytes,
-					  &lany_change,
-					  length_size,
-					  err_code, &new_line_ptr)) {
-	long bytes_used = new_line_ptr - line_ptr;
+                                          remaining_bytes,
+                                          &lany_change,
+                                          length_size,
+                                          err_code,
+                                          &new_line_ptr);
+         (sec_res == DW_DLV_OK) && (remaining_bytes > 0);
+         sec_res = _dwarf_update_line_sec(line_ptr,
+                                          remaining_bytes,
+                                          &lany_change,
+                                          length_size,
+                                          err_code, &new_line_ptr)) {
+        long bytes_used = new_line_ptr - line_ptr;
 
-	line_ptr = new_line_ptr;
-	remaining_bytes -= bytes_used;
-	if (lany_change) {
-	    did_change = 1;
-	}
-	if (remaining_bytes > 0) {
-	    continue;
-	}
-	break;
+        line_ptr = new_line_ptr;
+        remaining_bytes -= bytes_used;
+        if (lany_change) {
+            did_change = 1;
+        }
+        if (remaining_bytes > 0) {
+            continue;
+        }
+        break;
     }
     if (sec_res == DW_DLV_ERROR) {
-	free(orig_line_ptr);
-	return sec_res;
+        free(orig_line_ptr);
+        return sec_res;
     }
 
 
     /* all passed */
     if (did_change) {
-	/* So update the passed in buffer orig_buffer is caller's
-	   input area. orig_line_ptr is our modified copy of input
-	   area. */
-	memcpy(orig_buffer, orig_line_ptr, buffer_len);
-	*any_change = 1;
+        /* So update the passed in buffer orig_buffer is caller's input 
+           area. orig_line_ptr is our modified copy of input area. */
+        memcpy(orig_buffer, orig_line_ptr, buffer_len);
+        *any_change = 1;
     }
     free(orig_line_ptr);
 
@@ -190,7 +221,7 @@
 
 
 /* By setting ala_entry_num we guarantee a stable sort,
-	no duplicates
+        no duplicates
    Sorting in address order.
 */
 static int
@@ -200,99 +231,103 @@
     const struct a_line_area *r = rin;
 
     if (l->ala_address < r->ala_address) {
-	return -1;
+        return -1;
     }
     if (l->ala_address > r->ala_address) {
-	return 1;
+        return 1;
     }
     if (l->ala_entry_num < r->ala_entry_num) {
-	return -1;
+        return -1;
     }
     if (l->ala_entry_num > r->ala_entry_num) {
-	return 1;
+        return 1;
     }
-    return 0;			/* should never happen. */
+    return 0;                   /* should never happen. */
 }
 
+/* The list of line area records is no longer needed.
+   Free the data allocated. */
+static void
+free_area_data(struct a_line_area *arp)
+{
+    while(arp) {
+        struct a_line_area *next = arp->ala_next;
+        free(arp);
+        arp = next;
+    }    
+}
 
 /*
-	On entry:
-	  line_ptr must point to first
-	  byte of a line group for one (original) .o
-	  
-	  remaining_bytes is the size of the area pointed to
-	  by line_ptr: may be larger than the
-	  current original compilation unit .
+        On entry:
+          line_ptr must point to first
+          byte of a line group for one (original) .o
+          
+          remaining_bytes is the size of the area pointed to
+          by line_ptr: may be larger than the
+          current original compilation unit .
 
-	  length size is 4 for 32bit pointers, 8 for 64bit pointers
-	  in the data pointed to.
+          length size is 4 for 32bit pointers, 8 for 64bit pointers
+          in the data pointed to.
 
 
-	On return:
-	  return DW_DLV_OK if all ok.  (ignore 
-		*err_code in this case)
+        On return:
+          return DW_DLV_OK if all ok.  (ignore 
+                *err_code in this case)
 
-	  return DW_DLV_ERROR and set *err_code if an error.
+          return DW_DLV_ERROR and set *err_code if an error.
 
-	  If some line data was moved around, set *any_change to 1.
-	  If error or no movement, set *any_change to 0;
+          If some line data was moved around, set *any_change to 1.
+          If error or no movement, set *any_change to 0;
 
-	  Set *new_line_ptr to one-byte-past the end of the
-	  current original compilation unit  (not necessary
-	  if returning DW_DLV_ERROR, but not harmful).
+          Set *new_line_ptr to one-byte-past the end of the
+          current original compilation unit  (not necessary
+          if returning DW_DLV_ERROR, but not harmful).
 
 
-	This copies the entire array to a malloc area, then
-	mallocs pieces of it (another malloc) for sorting a CU entries
-	and copying back.  Then at end  the whole new thing copied in.
-	The result is that on error, the input is not touched.
+        This copies the entire array to a malloc area, then
+        mallocs pieces of it (another malloc) for sorting a CU entries
+        and copying back.  Then at end  the whole new thing copied in.
+        The result is that on error, the input is not touched.
 
-	An alternative would be to just update a piece at a time
-	and on error stop updating but leave what was done, done.
-	This alternative would save some temporary malloc space.
-	
-	
+        An alternative would be to just update a piece at a time
+        and on error stop updating but leave what was done, done.
+        This alternative would save some temporary malloc space.
+        
+        
 */
 static int
 _dwarf_update_line_sec(Dwarf_Small * line_ptr,
-		       unsigned long remaining_bytes,
-		       int *any_change,
-		       int length_size,
-		       int *err_code, Dwarf_Small ** new_line_ptr)
+                       unsigned long remaining_bytes,
+                       int *any_change,
+                       int length_size,
+                       int *err_code, Dwarf_Small ** new_line_ptr)
 {
 
 
     /* 
-       This points to the last byte of the .debug_line portion for the 
+       This points to the last byte of the .debug_line portion for the
        current cu. */
-    Dwarf_Small *line_ptr_end;
+    Dwarf_Small *line_ptr_end = 0;
 
     /* 
        This points to the end of the statement program prologue for the 
-       current cu, and serves to check that the prologue was correctly 
+       current cu, and serves to check that the prologue was correctly
        decoded. */
-    Dwarf_Small *check_line_ptr;
 
-    Dwarf_Small *orig_line_ptr;
+    Dwarf_Small *orig_line_ptr = 0;
 
     /* These are the fields of the statement program header. */
-    Dwarf_Unsigned total_length;
-    Dwarf_Half version;
-    Dwarf_Unsigned prologue_length;
-    Dwarf_Small minimum_instruction_length;
-    Dwarf_Small default_is_stmt;
-    Dwarf_Sbyte line_base;
-    Dwarf_Small line_range;
-    Dwarf_Small opcode_base;
     struct Dwarf_Debug_s dbg_data;
     Dwarf_Debug dbg = &dbg_data;
 
-    Dwarf_Small *opcode_length = 0;
+    /* These are the state machine state variables. */
+    Dwarf_Addr address = 0;
+    Dwarf_Word line = 1;
+    Dwarf_Bool is_stmt = false;
 
-    /* These are the state machine state variables. */
-    Dwarf_Addr address;
-    Dwarf_Word line;
-    Dwarf_Bool is_stmt;
+    /* Dwarf_Bool prologue_end; Dwarf_Bool epilogue_begin; */
+    Dwarf_Small isa = 0;
+
 
     struct a_line_area *area_base = 0;
     struct a_line_area *area_current = 0;
@@ -301,373 +336,334 @@
     Dwarf_Addr last_address = 0;
     int need_to_sort = 0;
 
-    Dwarf_Sword i;
-    Dwarf_Sword file_entry_count;
-    Dwarf_Sword include_directories_count;
-
     /* 
        This is the current opcode read from the statement program. */
-    Dwarf_Small opcode;
+    Dwarf_Small opcode = 0;
 
 
     /* 
        These variables are used to decode leb128 numbers. Leb128_num
        holds the decoded number, and leb128_length is its length in
        bytes. */
-    Dwarf_Word leb128_num;
-    Dwarf_Word leb128_length;
-    Dwarf_Sword advance_line;
+    Dwarf_Word leb128_num = 0;
+    Dwarf_Sword advance_line = 0;
 
     /* 
        This is the operand of the latest fixed_advance_pc extended
        opcode. */
-    Dwarf_Half fixed_advance_pc;
+    Dwarf_Half fixed_advance_pc = 0;
 
     /* This is the length of an extended opcode instr.  */
-    Dwarf_Word instr_length;
-    Dwarf_Small ext_opcode;
-
-
-
-    dbg->de_copy_word = memcpy;
-    /* 
-       Following is a straightforward decoding of the statement
-       program prologue information. */
-    *any_change = 0;
-    orig_line_ptr = line_ptr;
-    if(remaining_bytes < MINIMUM_POSSIBLE_PROLOG_LEN) {
-        /* We are at the end. Remaining should be zero bytes,
-           padding.
-           This is really just 'end of CU buffer'
-                not an error.
-	   The is no 'entry' left so report there is none.
-	   We don't want to READ_UNALIGNED the total_length below
-	   and then belatedly discover that we read off the end 
-	   already.
-        */
-        return(DW_DLV_NO_ENTRY);
-    }
-
-    READ_UNALIGNED(dbg, total_length, Dwarf_Unsigned,
-		   line_ptr, length_size);
-    line_ptr += length_size;
-    line_ptr_end = line_ptr + total_length;
-    if (line_ptr_end > line_ptr + remaining_bytes) {
-	*err_code = DW_DLE_DEBUG_LINE_LENGTH_BAD;
-	return (DW_DLV_ERROR);
-    }
-
-    *new_line_ptr = line_ptr_end;
-    READ_UNALIGNED(dbg, version, Dwarf_Half,
-		   line_ptr, sizeof(Dwarf_Half));
-    line_ptr += sizeof(Dwarf_Half);
-    if (version != CURRENT_VERSION_STAMP) {
-	*err_code = DW_DLE_VERSION_STAMP_ERROR;
-	return (DW_DLV_ERROR);
-    }
-
-    READ_UNALIGNED(dbg, prologue_length, Dwarf_Unsigned,
-		   line_ptr, length_size);
-    line_ptr += length_size;
-    check_line_ptr = line_ptr;
-
-    minimum_instruction_length = *(Dwarf_Small *) line_ptr;
-    line_ptr = line_ptr + sizeof(Dwarf_Small);
-
-    default_is_stmt = *(Dwarf_Small *) line_ptr;
-    line_ptr = line_ptr + sizeof(Dwarf_Small);
-
-    line_base = *(Dwarf_Sbyte *) line_ptr;
-    line_ptr = line_ptr + sizeof(Dwarf_Sbyte);
-
-    line_range = *(Dwarf_Small *) line_ptr;
-    line_ptr = line_ptr + sizeof(Dwarf_Small);
-
-    opcode_base = *(Dwarf_Small *) line_ptr;
-    line_ptr = line_ptr + sizeof(Dwarf_Small);
-
-    opcode_length = (Dwarf_Small *)
-	alloca(sizeof(Dwarf_Small) * opcode_base);
-    for (i = 1; i < opcode_base; i++) {
-	opcode_length[i] = *(Dwarf_Small *) line_ptr;
-	line_ptr = line_ptr + sizeof(Dwarf_Small);
-    }
-
-    include_directories_count = 0;
-    while ((*(char *) line_ptr) != '\0') {
-	line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
-	include_directories_count++;
-    }
-    line_ptr++;
-
-    file_entry_count = 0;
-    while (*(char *) line_ptr != '\0') {
-
-
-	/* filename = (Dwarf_Small *)line_ptr; */
-	line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
-
-	/* dir_index = */
-	_dwarf_decode_u_leb128(line_ptr, &leb128_length);
-	line_ptr = line_ptr + leb128_length;
-
-	/* time_last_mod = */
-	_dwarf_decode_u_leb128(line_ptr, &leb128_length);
-	line_ptr = line_ptr + leb128_length;
-
-	/* file_length = */
-	_dwarf_decode_u_leb128(line_ptr, &leb128_length);
-	line_ptr = line_ptr + leb128_length;
-
-	file_entry_count++;
-    }
-    line_ptr++;
-
-    if (line_ptr != check_line_ptr + prologue_length) {
-	*err_code = DW_DLE_LINE_PROLOG_LENGTH_BAD;
-	return (DW_DLV_ERROR);
-    }
-
-    /* Initialize the state machine.  */
-    address = 0;
-    /* file = 1; */
-    line = 1;
-    /* column = 0; */
-    is_stmt = default_is_stmt;
-    /* basic_block = false; */
-    /* end_sequence = false; */
-
-    /* Start of statement program.  */
-    while (line_ptr < line_ptr_end) {
-	int type;
-
-	Dwarf_Small *stmt_prog_entry_start = line_ptr;
-
-	opcode = *(Dwarf_Small *) line_ptr;
-	line_ptr++;
-	/* 'type' is the output */
-	WHAT_IS_OPCODE(type, opcode, opcode_base,
-		       opcode_length, line_ptr);
+    Dwarf_Word instr_length = 0;
+    Dwarf_Small ext_opcode = 0;
+    struct Line_Table_Prefix_s prefix;
 
 
 
-	if (type == LOP_DISCARD) {
-	    /* do nothing, necessary ops done */
-	} else if (type == LOP_SPECIAL) {
-	    opcode = opcode - opcode_base;
-	    address = address + minimum_instruction_length *
-		(opcode / line_range);
-	    line = line + line_base + opcode % line_range;
-
-	    /* basic_block = false; */
-
-
-	} else if (type == LOP_STANDARD) {
-
-
-	    switch (opcode) {
-
-
-	    case DW_LNS_copy:{
-		    if (opcode_length[DW_LNS_copy] != 0) {
-			*err_code = DW_DLE_LINE_NUM_OPERANDS_BAD;
-			return (DW_DLV_ERROR);
-		    }
+    memset(dbg, 0, sizeof(struct Dwarf_Debug_s));
+    dbg->de_copy_word = memcpy;
+    /* 
+       Following is a straightforward decoding of the statement program 
+       prologue information. */
+    *any_change = 0;
 
 
-		    /* basic_block = false; */
-		    break;
-		}
-
-	    case DW_LNS_advance_pc:{
-		    Dwarf_Unsigned utmp2;
-
-		    if (opcode_length[DW_LNS_advance_pc] != 1) {
-			*err_code = DW_DLE_LINE_NUM_OPERANDS_BAD;
-			return (DW_DLV_ERROR);
-		    }
-
-		    DECODE_LEB128_UWORD(line_ptr, utmp2)
-			leb128_num = (Dwarf_Word) utmp2;
-		    address =
-			address +
-			minimum_instruction_length * leb128_num;
-		    break;
-		}
-
-	    case DW_LNS_advance_line:{
-		    Dwarf_Signed stmp;
-
-		    if (opcode_length[DW_LNS_advance_line] != 1) {
-			*err_code = DW_DLE_LINE_NUM_OPERANDS_BAD;
-			return (DW_DLV_ERROR);
-		    }
-
-		    DECODE_LEB128_SWORD(line_ptr, stmp)
-			advance_line = (Dwarf_Sword) stmp;
-		    line = line + advance_line;
-		    break;
-		}
-
-	    case DW_LNS_set_file:{
-		    Dwarf_Unsigned utmp2;
-
-		    if (opcode_length[DW_LNS_set_file] != 1) {
-			*err_code = DW_DLE_LINE_NUM_OPERANDS_BAD;
-			return (DW_DLV_ERROR);
-		    }
-
-		    DECODE_LEB128_UWORD(line_ptr, utmp2)
-			/* file = (Dwarf_Word)utmp2; */
-			break;
-		}
-
-	    case DW_LNS_set_column:{
-		    Dwarf_Unsigned utmp2;
-
-		    if (opcode_length[DW_LNS_set_column] != 1) {
-			*err_code = DW_DLE_LINE_NUM_OPERANDS_BAD;
-			return (DW_DLV_ERROR);
-		    }
-
-		    DECODE_LEB128_UWORD(line_ptr, utmp2)
-			/* column = (Dwarf_Word)utmp2; */
-			break;
-		}
-
-	    case DW_LNS_negate_stmt:{
-		    if (opcode_length[DW_LNS_negate_stmt] != 0) {
-			*err_code = DW_DLE_LINE_NUM_OPERANDS_BAD;
-			return (DW_DLV_ERROR);
-		    }
-
-		    is_stmt = !is_stmt;
-		    break;
-		}
-
-	    case DW_LNS_set_basic_block:{
-		    if (opcode_length[DW_LNS_set_basic_block] != 0) {
-			*err_code = DW_DLE_LINE_NUM_OPERANDS_BAD;
-			return (DW_DLV_ERROR);
-		    }
-
-		    /* basic_block = true; */
-		    break;
-		}
-
-	    case DW_LNS_const_add_pc:{
-		    opcode = MAX_LINE_OP_CODE - opcode_base;
-		    address = address + minimum_instruction_length *
-			(opcode / line_range);
-
-		    break;
-		}
+    orig_line_ptr = line_ptr;
+    if (remaining_bytes < MINIMUM_POSSIBLE_PROLOG_LEN) {
+        /* We are at the end. Remaining should be zero bytes, padding.
+           This is really just 'end of CU buffer' not an error. The is
+           no 'entry' left so report there is none. We don't want to
+           READ_UNALIGNED the total_length below and then belatedly
+           discover that we read off the end already. */
+        return (DW_DLV_NO_ENTRY);
+    }
 
-	    case DW_LNS_fixed_advance_pc:{
-		    if (opcode_length[DW_LNS_fixed_advance_pc] != 1) {
-			*err_code = DW_DLE_LINE_NUM_OPERANDS_BAD;
-			return (DW_DLV_ERROR);
-		    }
-
-		    READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half,
-				   line_ptr, sizeof(Dwarf_Half));
-		    line_ptr += sizeof(Dwarf_Half);
-		    address = address + fixed_advance_pc;
-		    break;
-		}
-	    }
-	} else if (type == LOP_EXTENDED) {
-
-
-	    Dwarf_Unsigned utmp3;
-
-	    DECODE_LEB128_UWORD(line_ptr, utmp3)
-		instr_length = (Dwarf_Word) utmp3;
-	    ext_opcode = *(Dwarf_Small *) line_ptr;
-	    line_ptr++;
-	    switch (ext_opcode) {
-
-	    case DW_LNE_end_sequence:{
-		    /* end_sequence = true; */
-
-		    address = 0;
-		    /* file = 1; */
-		    line = 1;
-		    /* column = 0; */
-		    is_stmt = default_is_stmt;
-		    /* basic_block = false; */
-		    /* end_sequence = false; */
-
-		    break;
-		}
-
-	    case DW_LNE_set_address:{
-		    if (instr_length - 1 == length_size) {
-			struct a_line_area *area;
+    dwarf_init_line_table_prefix(&prefix);
+    {
+        Dwarf_Small *line_ptr_out = 0;
+        Dwarf_Error error;
+        int dres = dwarf_read_line_table_prefix(dbg,
+            line_ptr,
+            remaining_bytes,
+            &line_ptr_out,
+            &prefix, 
+            NULL, NULL,&error,
+            NULL);
 
-			READ_UNALIGNED(dbg, address, Dwarf_Addr,
-				       line_ptr, length_size);
-			/* Here we need to remember the offset into the 
-			   buffer and check to see if address went
-			   down. */
-			if (address < last_address) {
-			    need_to_sort = 1;
-			}
-			last_address = address;
+        if (dres == DW_DLV_ERROR) {
+            dwarf_free_line_table_prefix(&prefix);
+            *err_code = dwarf_errno(error);
+            dwarf_dealloc(dbg, error, DW_DLA_ERROR);
+            free_area_data(area_base);
+            return dres;
+        }
+        if (dres == DW_DLV_NO_ENTRY) {
+            dwarf_free_line_table_prefix(&prefix);
+            return dres;
+        }
+        line_ptr_end = prefix.pf_line_ptr_end;
 
-			area = alloca(sizeof(struct a_line_area));
-			area->ala_address = address;
-			area->ala_offset = stmt_prog_entry_start -
-			    orig_line_ptr;
-			area->ala_entry_num = area_count;
-			area->ala_next = 0;
-			area->ala_length = 0;
-			if (area_current) {
-			    area_current->ala_next = area;
-			    area_current->ala_length =
-				area->ala_offset -
-				area_current->ala_offset;
-			}
-			++area_count;
-			area_current = area;
-			if (area_base == 0) {
-			    area_base = area;
-			}
-
-			line_ptr += length_size;
-		    } else {
-			*err_code = DW_DLE_LINE_SET_ADDR_ERROR;
-			return (DW_DLV_ERROR);
-		    }
-
-
-		    break;
-		}
-
-	    case DW_LNE_define_file:{
-
-		    break;
-		}
-
-	    default:{
-		    *err_code = DW_DLE_LINE_EXT_OPCODE_BAD;
-		    return (DW_DLV_ERROR);
-		}
-	    }
-
-	}
+        line_ptr = line_ptr_out;
     }
 
 
-    if (!need_to_sort) {
-	return (DW_DLV_OK);
+    /* Initialize the state machine.  */
+    /* file = 1; */
+    /* column = 0; */
+    is_stmt = prefix.pf_default_is_stmt;
+    /* basic_block = false; */
+    /* end_sequence = false; */
+    /* prologue_end = false; */
+    /* epilogue_begin = false; */
+    isa = 0;
+
+
+    /* Start of statement program.  */
+    while (line_ptr < line_ptr_end) {
+        int type;
+
+        Dwarf_Small *stmt_prog_entry_start = line_ptr;
+
+        opcode = *(Dwarf_Small *) line_ptr;
+        line_ptr++;
+        /* 'type' is the output */
+        WHAT_IS_OPCODE(type, opcode, prefix.pf_opcode_base,
+                       prefix.pf_opcode_length_table, line_ptr,
+                       prefix.pf_std_op_count);
+
+        if (type == LOP_DISCARD) {
+            int oc;
+            int opcnt = prefix.pf_opcode_length_table[opcode];
+
+            for (oc = 0; oc < opcnt; oc++) {
+                /* 
+                 ** Read and discard operands we don't
+                 ** understand.
+                 ** arbitrary choice of unsigned read.
+                 ** signed read would work as well.
+                 */
+                Dwarf_Unsigned utmp2;
+
+                DECODE_LEB128_UWORD(line_ptr, utmp2);
+            }
+
+        } else if (type == LOP_SPECIAL) {
+            opcode = opcode - prefix.pf_opcode_base;
+            address = address + prefix.pf_minimum_instruction_length *
+                (opcode / prefix.pf_line_range);
+            line =
+                line + prefix.pf_line_base +
+                opcode % prefix.pf_line_range;
+
+            /* basic_block = false; */
+
+
+        } else if (type == LOP_STANDARD) {
+
+
+            switch (opcode) {
+
+
+            case DW_LNS_copy:{
+
+                    /* basic_block = false; */
+                    break;
+                }
+
+            case DW_LNS_advance_pc:{
+                    Dwarf_Unsigned utmp2;
+
+
+                    DECODE_LEB128_UWORD(line_ptr, utmp2);
+                    leb128_num = (Dwarf_Word) utmp2;
+                    address =
+                        address +
+                        prefix.pf_minimum_instruction_length *
+                        leb128_num;
+                    break;
+                }
+
+            case DW_LNS_advance_line:{
+                    Dwarf_Signed stmp;
+
+
+                    DECODE_LEB128_SWORD(line_ptr, stmp);
+                    advance_line = (Dwarf_Sword) stmp;
+                    line = line + advance_line;
+                    break;
+                }
+
+            case DW_LNS_set_file:{
+                    Dwarf_Unsigned utmp2;
+
+
+                    DECODE_LEB128_UWORD(line_ptr, utmp2);
+                    /* file = (Dwarf_Word)utmp2; */
+                    break;
+                }
+
+            case DW_LNS_set_column:{
+                    Dwarf_Unsigned utmp2;
+
+
+                    DECODE_LEB128_UWORD(line_ptr, utmp2);
+                    /* column = (Dwarf_Word)utmp2; */
+                    break;
+                }
+
+            case DW_LNS_negate_stmt:{
+
+                    is_stmt = !is_stmt;
+                    break;
+                }
+
+            case DW_LNS_set_basic_block:{
+
+                    /* basic_block = true; */
+                    break;
+                }
+
+            case DW_LNS_const_add_pc:{
+                    opcode = MAX_LINE_OP_CODE - prefix.pf_opcode_base;
+                    address =
+                        address +
+                        prefix.pf_minimum_instruction_length * (opcode /
+                                                                prefix.
+                                                                pf_line_range);
+
+                    break;
+                }
+
+            case DW_LNS_fixed_advance_pc:{
+
+                    READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half,
+                                   line_ptr, sizeof(Dwarf_Half));
+                    line_ptr += sizeof(Dwarf_Half);
+                    address = address + fixed_advance_pc;
+                    break;
+                }
+                /* New in DWARF3 */
+            case DW_LNS_set_prologue_end:{
+
+                    /* prologue_end = true; */
+                    break;
+
+
+                }
+                /* New in DWARF3 */
+            case DW_LNS_set_epilogue_begin:{
+                    /* epilogue_begin = true; */
+                    break;
+                }
+
+                /* New in DWARF3 */
+            case DW_LNS_set_isa:{
+                    Dwarf_Unsigned utmp2;
+
+                    DECODE_LEB128_UWORD(line_ptr, utmp2);
+                    isa = utmp2;
+                    if (isa != utmp2) {
+                        /* The value of the isa did not fit in our
+                           local so we record it wrong. declare an
+                           error. */
+                        dwarf_free_line_table_prefix(&prefix);
+                        *err_code = DW_DLE_LINE_NUM_OPERANDS_BAD;
+                        free_area_data(area_base);
+                        return (DW_DLV_ERROR);
+                    }
+                    break;
+                }
+
+            }
+        } else if (type == LOP_EXTENDED) {
+
+            Dwarf_Unsigned utmp3;
+
+            DECODE_LEB128_UWORD(line_ptr, utmp3);
+            instr_length = (Dwarf_Word) utmp3;
+            ext_opcode = *(Dwarf_Small *) line_ptr;
+            line_ptr++;
+            switch (ext_opcode) {
+
+            case DW_LNE_end_sequence:{
+                    /* end_sequence = true; */
+
+                    address = 0;
+                    /* file = 1; */
+                    line = 1;
+                    /* column = 0; */
+                    is_stmt = prefix.pf_default_is_stmt;
+                    /* basic_block = false; */
+                    /* end_sequence = false; */
+                    /* prologue_end = false; */
+                    /* epilogue_begin = false; */
+                    break;
+                }
+
+            case DW_LNE_set_address:{
+                    {
+                        struct a_line_area *area;
+
+                        READ_UNALIGNED(dbg, address, Dwarf_Addr,
+                                       line_ptr, length_size);
+                        /* Here we need to remember the offset into the 
+                           buffer and check to see if address went
+                           down. */
+                        if (address < last_address) {
+                            need_to_sort = 1;
+                        }
+                        last_address = address;
+
+                        area = malloc(sizeof(struct a_line_area));
+                        area->ala_address = address;
+                        area->ala_offset = stmt_prog_entry_start -
+                            orig_line_ptr;
+                        area->ala_entry_num = area_count;
+                        area->ala_next = 0;
+                        area->ala_length = 0;
+                        if (area_current) {
+                            area_current->ala_next = area;
+                            area_current->ala_length =
+                                area->ala_offset -
+                                area_current->ala_offset;
+                        }
+                        ++area_count;
+                        area_current = area;
+                        if (area_base == 0) {
+                            area_base = area;
+                        }
+
+                        line_ptr += length_size;
+                    }
+                    break;
+                }
+
+            case DW_LNE_define_file:{
+                    break;
+                }
+
+            default:{
+                 Dwarf_Unsigned remaining_bytes = instr_length -1;
+                 line_ptr += remaining_bytes;
+                 break;
+                }
+            }
+
+        }
     }
 
-    /* so now we have something to sort. First, finish off the last
+
+    *new_line_ptr = line_ptr;
+    if (!need_to_sort) {
+        dwarf_free_line_table_prefix(&prefix);
+        free_area_data(area_base);
+        return (DW_DLV_OK);
+    }
+
+    /* So now we have something to sort. First, finish off the last
        area record: */
-    area_current->ala_length = (line_ptr - orig_line_ptr)	/* final 
-								   offset */
-	-area_current->ala_offset;
+    area_current->ala_length = (line_ptr - orig_line_ptr)
+        -area_current->ala_offset;
 
     /* Build and sort a simple array of sections. Forcing a stable sort 
        by comparing on sequence number. We will use the sorted list to
@@ -677,51 +673,61 @@
        function rearrangement and that it is meaningful to restart the
        line info there. */
     {
-	struct a_line_area *ala_array;
-	struct a_line_area *local;
-	long start_len;
-	Dwarf_Small *new_area;
-	long i;
+        struct a_line_area *ala_array;
+        struct a_line_area *local;
+        long start_len;
+        Dwarf_Small *new_area;
+        long i;
 
-	ala_array = malloc(area_count * sizeof(struct a_line_area));
-	if (!ala_array) {
-	    *err_code = DW_DLE_ALLOC_FAIL;
-	    return DW_DLV_ERROR;
-	}
+        ala_array = malloc(area_count * sizeof(struct a_line_area));
+        if (!ala_array) {
+            dwarf_free_line_table_prefix(&prefix);
+            *err_code = DW_DLE_ALLOC_FAIL;
+            free_area_data(area_base);
+            return DW_DLV_ERROR;
+        }
 
-	for (local = area_base, i = 0; local;
-	     local = local->ala_next, ++i) {
+        for (local = area_base, i = 0; local;
+             local = local->ala_next, ++i) {
 
-	    ala_array[i] = *local;
-	}
+            ala_array[i] = *local;
+        }
+        free_area_data(area_base);
+        /* Zero the stale pointers so we don't use them accidentally. */
+        area_base = 0;
+        area_current = 0;
 
-	qsort(ala_array, area_count, sizeof(struct a_line_area), cmpr);
-
-	/* Now we must rearrange the pieces of the line table. */
+        qsort(ala_array, area_count, sizeof(struct a_line_area), cmpr);
 
-	start_len = (check_line_ptr + prologue_length) - orig_line_ptr;
-	new_area = malloc(remaining_bytes);
-	if (!new_area) {
-	    free(ala_array);
-	    *err_code = DW_DLE_ALLOC_FAIL;
-	    return DW_DLV_ERROR;
-	}
-	memcpy(new_area, orig_line_ptr, start_len);
-	line_ptr = new_area + start_len;
-	for (i = 0; i < area_count; ++i) {
-	    memcpy(line_ptr, orig_line_ptr +
-		   ala_array[i].ala_offset, ala_array[i].ala_length);
-	    line_ptr += ala_array[i].ala_length;
-	}
+        /* Now we must rearrange the pieces of the line table. */
 
-	memcpy(orig_line_ptr, new_area, remaining_bytes);
+        start_len =
+            (prefix.pf_line_prologue_start +
+             prefix.pf_prologue_length) - orig_line_ptr;
+        new_area = malloc(remaining_bytes);
+        if (!new_area) {
+            free(ala_array);
+            *err_code = DW_DLE_ALLOC_FAIL;
+            dwarf_free_line_table_prefix(&prefix);
+            return DW_DLV_ERROR;
+        }
+        memcpy(new_area, orig_line_ptr, start_len);
+        line_ptr = new_area + start_len;
+        for (i = 0; i < area_count; ++i) {
+            memcpy(line_ptr, orig_line_ptr +
+                   ala_array[i].ala_offset, ala_array[i].ala_length);
+            line_ptr += ala_array[i].ala_length;
+        }
 
-	free(new_area);
-	free(ala_array);
-	ala_array = 0;
-	new_area = 0;
+        memcpy(orig_line_ptr, new_area, remaining_bytes);
+
+        free(new_area);
+        free(ala_array);
+        ala_array = 0;
+        new_area = 0;
     }
 
     *any_change = 1;
+    dwarf_free_line_table_prefix(&prefix);
     return (DW_DLV_OK);
 }
--- a/usr/src/tools/ctf/dwarf/common/dwarf_string.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_string.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2009-2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -40,42 +41,38 @@
 
 int
 dwarf_get_str(Dwarf_Debug dbg,
-	      Dwarf_Off offset,
-	      char **string,
-	      Dwarf_Signed * returned_str_len, Dwarf_Error * error)
+              Dwarf_Off offset,
+              char **string,
+              Dwarf_Signed * returned_str_len, Dwarf_Error * error)
 {
-    int res;
+    int res = DW_DLV_ERROR;
 
     if (dbg == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
 
-    if (offset == dbg->de_debug_str_size) {
-	/* Normal (if we've iterated thru the set of strings
-	   using dwarf_get_str and are at the end). */
-	return DW_DLV_NO_ENTRY;
+    if (offset == dbg->de_debug_str.dss_size) {
+        /* Normal (if we've iterated thru the set of strings using
+           dwarf_get_str and are at the end). */
+        return DW_DLV_NO_ENTRY;
     }
-    if (offset > dbg->de_debug_str_size) {
-	_dwarf_error(dbg, error, DW_DLE_DEBUG_STR_OFFSET_BAD);
-	return (DW_DLV_ERROR);
+    if (offset > dbg->de_debug_str.dss_size) {
+        _dwarf_error(dbg, error, DW_DLE_DEBUG_STR_OFFSET_BAD);
+        return (DW_DLV_ERROR);
     }
 
     if (string == NULL) {
-	_dwarf_error(dbg, error, DW_DLE_STRING_PTR_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(dbg, error, DW_DLE_STRING_PTR_NULL);
+        return (DW_DLV_ERROR);
     }
 
-    res =
-       _dwarf_load_section(dbg,
-                           dbg->de_debug_str_index,
-                           &dbg->de_debug_str,
-                           error);
+    res = _dwarf_load_section(dbg, &dbg->de_debug_str,error);
     if (res != DW_DLV_OK) {
         return res;
     }
 
-    *string = (char *) dbg->de_debug_str + offset;
+    *string = (char *) dbg->de_debug_str.dss_data + offset;
 
     *returned_str_len = (strlen(*string));
     return DW_DLV_OK;
--- a/usr/src/tools/ctf/dwarf/common/dwarf_stubs.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_stubs.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +19,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -43,8 +43,8 @@
 
  /*ARGSUSED*/ int
 dwarf_nextglob(Dwarf_Debug dbg,
-	       Dwarf_Global glob,
-	       Dwarf_Global * returned_nextglob, Dwarf_Error * error)
+               Dwarf_Global glob,
+               Dwarf_Global * returned_nextglob, Dwarf_Error * error)
 {
     return (DW_DLV_NO_ENTRY);
 }
--- a/usr/src/tools/ctf/dwarf/common/dwarf_types.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_types.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
-
-  Copyright (C) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2009-2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +19,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -43,33 +43,41 @@
 
 int
 dwarf_get_types(Dwarf_Debug dbg,
-		Dwarf_Type ** types,
-		Dwarf_Signed * ret_type_count, Dwarf_Error * error)
+    Dwarf_Type ** types,
+    Dwarf_Signed * ret_type_count, Dwarf_Error * error)
 {
-    int res;
-
-    res =
-       _dwarf_load_section(dbg,
-		           dbg->de_debug_typenames_index,
-			   &dbg->de_debug_typenames,
-			   error);
+    int res = _dwarf_load_section(dbg, &dbg->de_debug_typenames,error);
     if (res != DW_DLV_OK) {
-	return res;
+        return res;
     }
 
-    return _dwarf_internal_get_pubnames_like_data(dbg, dbg->de_debug_typenames, dbg->de_debug_typenames_size, (Dwarf_Global **) types,	/* type 
-																	   punning,
-																	   Dwarf_Type 
-																	   is never
-																	   a
-																	   completed 
-																	   type */
-						  ret_type_count,
-						  error,
-						  DW_DLA_TYPENAME_CONTEXT,
-						  DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD,
-						  DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR);
+    return _dwarf_internal_get_pubnames_like_data(dbg, 
+          dbg->de_debug_typenames.dss_data, 
+          dbg->de_debug_typenames.dss_size, 
+          (Dwarf_Global **) types,  /* type punning, Dwarf_Type is 
+               never a completed type */
+          ret_type_count,
+          error,
+          DW_DLA_TYPENAME_CONTEXT,
+          DW_DLA_TYPENAME,
+          DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD,
+          DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR);
+}
 
+/* Deallocating fully requires deallocating the list
+   and all entries.  But some internal data is
+   not exposed, so we need a function with internal knowledge.
+*/
+
+void
+dwarf_types_dealloc(Dwarf_Debug dbg, Dwarf_Type * dwgl,
+    Dwarf_Signed count)
+{
+    _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl,
+        count,
+        DW_DLA_TYPENAME_CONTEXT,
+        DW_DLA_TYPENAME, DW_DLA_LIST);
+    return;
 }
 
 
@@ -79,8 +87,8 @@
     Dwarf_Global type = (Dwarf_Global) type_in;
 
     if (type == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_TYPE_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_TYPE_NULL);
+        return (DW_DLV_ERROR);
     }
 
     *ret_name = (char *) (type->gl_name);
@@ -90,7 +98,7 @@
 
 int
 dwarf_type_die_offset(Dwarf_Type type_in,
-		      Dwarf_Off * ret_offset, Dwarf_Error * error)
+                      Dwarf_Off * ret_offset, Dwarf_Error * error)
 {
     Dwarf_Global type = (Dwarf_Global) type_in;
 
@@ -100,24 +108,22 @@
 
 int
 dwarf_type_cu_offset(Dwarf_Type type_in,
-		     Dwarf_Off * ret_offset, Dwarf_Error * error)
+                     Dwarf_Off * ret_offset, Dwarf_Error * error)
 {
     Dwarf_Global type = (Dwarf_Global) type_in;
 
     return dwarf_global_cu_offset(type, ret_offset, error);
-
 }
 
 
 int
 dwarf_type_name_offsets(Dwarf_Type type_in,
-			char **returned_name,
-			Dwarf_Off * die_offset,
-			Dwarf_Off * cu_die_offset, Dwarf_Error * error)
+    char **returned_name,
+    Dwarf_Off * die_offset,
+    Dwarf_Off * cu_die_offset, Dwarf_Error * error)
 {
     Dwarf_Global type = (Dwarf_Global) type_in;
-
     return dwarf_global_name_offsets(type,
-				     returned_name,
-				     die_offset, cu_die_offset, error);
+        returned_name,
+        die_offset, cu_die_offset, error);
 }
--- a/usr/src/tools/ctf/dwarf/common/dwarf_types.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_types.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
--- a/usr/src/tools/ctf/dwarf/common/dwarf_util.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_util.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
-
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +19,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -32,6 +32,13 @@
   http://oss.sgi.com/projects/GenInfo/NoticeExplan
 
 */
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
 
 
 
@@ -51,8 +58,9 @@
 */
 Dwarf_Unsigned
 _dwarf_get_size_of_val(Dwarf_Debug dbg,
-		       Dwarf_Unsigned form,
-		       Dwarf_Small * val_ptr, int v_length_size)
+    Dwarf_Unsigned form,
+    Dwarf_Half address_size,
+    Dwarf_Small * val_ptr, int v_length_size)
 {
     Dwarf_Unsigned length = 0;
     Dwarf_Word leb128_length = 0;
@@ -61,98 +69,153 @@
 
     switch (form) {
 
-    default:			/* Handles form = 0. */
-	return (form);
+    default:                    /* Handles form = 0. */
+        return (form);
 
     case DW_FORM_addr:
-	return (dbg->de_pointer_size);
+        if(address_size) {
+            return address_size;
+        }
+        /* This should never happen, address_size should be set. */
+        return (dbg->de_pointer_size);
 
+    /* DWARF2 was wrong on the size of the attribute for
+       DW_FORM_ref_addr.  We assume compilers are using the 
+       corrected DWARF3 text (for 32bit pointer target objects pointer and
+       offsets are the same size anyway). */
     case DW_FORM_ref_addr:
-	return (v_length_size);
+        return (v_length_size);
 
     case DW_FORM_block1:
-	return (*(Dwarf_Small *) val_ptr + 1);
+        return (*(Dwarf_Small *) val_ptr + 1);
 
     case DW_FORM_block2:
-	READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
-		       val_ptr, sizeof(Dwarf_Half));
-	return (ret_value + sizeof(Dwarf_Half));
+        READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+                       val_ptr, sizeof(Dwarf_Half));
+        return (ret_value + sizeof(Dwarf_Half));
 
     case DW_FORM_block4:
-	READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
-		       val_ptr, sizeof(Dwarf_ufixed));
-	return (ret_value + sizeof(Dwarf_ufixed));
+        READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+                       val_ptr, sizeof(Dwarf_ufixed));
+        return (ret_value + sizeof(Dwarf_ufixed));
 
 
     case DW_FORM_data1:
-	return (1);
+        return (1);
 
     case DW_FORM_data2:
-	return (2);
+        return (2);
 
     case DW_FORM_data4:
-	return (4);
+        return (4);
 
     case DW_FORM_data8:
-	return (8);
+        return (8);
 
     case DW_FORM_string:
-	return (strlen((char *) val_ptr) + 1);
+        return (strlen((char *) val_ptr) + 1);
 
     case DW_FORM_block:
-	length = _dwarf_decode_u_leb128(val_ptr, &leb128_length);
-	return (length + leb128_length);
+    case DW_FORM_exprloc:
+        length = _dwarf_decode_u_leb128(val_ptr, &leb128_length);
+        return (length + leb128_length);
 
+    case DW_FORM_flag_present:
+        return (0);
     case DW_FORM_flag:
-	return (1);
+        return (1);
+
+    case DW_FORM_sec_offset:
+        /* If 32bit dwarf, is 4. Else is 64bit dwarf and is 8. */
+        return (v_length_size);
 
     case DW_FORM_ref_udata:
-	_dwarf_decode_u_leb128(val_ptr, &leb128_length);
-	return (leb128_length);
+        length = _dwarf_decode_u_leb128(val_ptr, &leb128_length);
+        return (leb128_length);
 
     case DW_FORM_indirect:
-	{
-	    Dwarf_Word indir_len = 0;
+        {
+            Dwarf_Word indir_len = 0;
 
-	    form_indirect = _dwarf_decode_u_leb128(val_ptr, &indir_len);
-	    if (form_indirect == DW_FORM_indirect) {
-		return (0);	/* We are in big trouble: The true form 
-				   of DW_FORM_indirect is
-				   DW_FORM_indirect? Nonsense. Should
-				   never happen. */
-	    }
-	    return (indir_len + _dwarf_get_size_of_val(dbg,
-						       form_indirect,
-						       val_ptr +
-						       indir_len,
-						       v_length_size));
-	}
+            form_indirect = _dwarf_decode_u_leb128(val_ptr, &indir_len);
+            if (form_indirect == DW_FORM_indirect) {
+                return (0);     /* We are in big trouble: The true form 
+                                   of DW_FORM_indirect is
+                                   DW_FORM_indirect? Nonsense. Should
+                                   never happen. */
+            }
+            return (indir_len + _dwarf_get_size_of_val(dbg,
+                   form_indirect,
+                   address_size,
+                   val_ptr + indir_len,
+                   v_length_size));
+        }
 
     case DW_FORM_ref1:
-	return (1);
+        return (1);
 
     case DW_FORM_ref2:
-	return (2);
+        return (2);
 
     case DW_FORM_ref4:
-	return (4);
+        return (4);
 
     case DW_FORM_ref8:
-	return (8);
+        return (8);
 
     case DW_FORM_sdata:
-	_dwarf_decode_s_leb128(val_ptr, &leb128_length);
-	return (leb128_length);
+        _dwarf_decode_s_leb128(val_ptr, &leb128_length);
+        return (leb128_length);
 
     case DW_FORM_strp:
-	return (v_length_size);
+        return (v_length_size);
 
     case DW_FORM_udata:
-	_dwarf_decode_u_leb128(val_ptr, &leb128_length);
-	return (leb128_length);
+        _dwarf_decode_u_leb128(val_ptr, &leb128_length);
+        return (leb128_length);
     }
 }
 
+/* We allow an arbitrary number of HT_MULTIPLE entries
+   before resizing.  It seems up to 20 or 30
+   would work nearly as well.
+   We could have a different resize multiple than 'resize now'
+   test multiple, but for now we don't do that.
+*/
+#define HT_MULTIPLE 8
+
+/* Copy the old entries, updating each to be in
+   a new list.  Don't delete anything. Leave the
+   htin with stale data. */
+static void
+copy_abbrev_table_to_new_table(Dwarf_Hash_Table htin, 
+  Dwarf_Hash_Table htout)
+{
+    Dwarf_Hash_Table_Entry entry_in = htin->tb_entries;
+    unsigned entry_in_count = htin->tb_table_entry_count;
+    Dwarf_Hash_Table_Entry entry_out = htout->tb_entries;
+    unsigned entry_out_count = htout->tb_table_entry_count;
+    unsigned k = 0;
+    for ( ;  k < entry_in_count; ++k,++entry_in) {
+        Dwarf_Abbrev_List listent = entry_in->at_head;
+        Dwarf_Abbrev_List nextlistent = 0;
+
+        for (  ; listent ; listent = nextlistent) {
+             unsigned newtmp = listent->ab_code;
+             unsigned newhash = newtmp%entry_out_count;
+             Dwarf_Hash_Table_Entry e;
+             nextlistent = listent->ab_next;
+             e = entry_out+newhash; 
+             /* Move_entry_to_new_hash. This reverses the
+                order of the entries, effectively, but
+                that does not seem significant. */
+             listent->ab_next = e->at_head;
+             e->at_head = listent;
+
+             htout->tb_total_abbrev_count++;
+        } 
+    }
+}
 
 /*
     This function returns a pointer to a Dwarf_Abbrev_List_s
@@ -175,77 +238,131 @@
     hash table contains both a head pointer and a tail pointer
     for each entry.
 
+    While the lists can move and entries can be moved between
+    lists on reallocation, any given Dwarf_Abbrev_list entry
+    never moves once allocated, so the pointer is safe to return.
+
     Returns NULL on error.
 */
 Dwarf_Abbrev_List
-_dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Word code)
+_dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Unsigned code)
 {
     Dwarf_Debug dbg = cu_context->cc_dbg;
-    Dwarf_Hash_Table hash_table = cu_context->cc_abbrev_hash_table;
-    Dwarf_Word hash_num;
-    Dwarf_Abbrev_List hash_abbrev_list;
-    Dwarf_Abbrev_List abbrev_list;
-    Dwarf_Byte_Ptr abbrev_ptr;
-    Dwarf_Half abbrev_code, abbrev_tag;
-    Dwarf_Half attr_name, attr_form;
+    Dwarf_Hash_Table hash_table_base = cu_context->cc_abbrev_hash_table;
+    Dwarf_Hash_Table_Entry entry_base = 0; 
+    Dwarf_Hash_Table_Entry entry_cur = 0; 
+    Dwarf_Word hash_num = 0;
+    Dwarf_Unsigned abbrev_code = 0; 
+    Dwarf_Unsigned abbrev_tag  = 0;
+    Dwarf_Unsigned attr_name = 0;
+    Dwarf_Unsigned attr_form = 0;
+
+    Dwarf_Abbrev_List hash_abbrev_entry = 0;
+
+    Dwarf_Abbrev_List inner_list_entry = 0; 
+    Dwarf_Hash_Table_Entry inner_hash_entry = 0; 
+
+    Dwarf_Byte_Ptr abbrev_ptr = 0;
+    unsigned hashable_val;
+
+    if ( !hash_table_base->tb_entries ) {
+         hash_table_base->tb_table_entry_count =  HT_MULTIPLE;
+         hash_table_base->tb_total_abbrev_count= 0;
+         hash_table_base->tb_entries =  _dwarf_get_alloc(dbg,
+            DW_DLA_HASH_TABLE_ENTRY, 
+            hash_table_base->tb_table_entry_count);
+         if(! hash_table_base->tb_entries) {
+             return NULL;
+         }
 
-    hash_num = code % ABBREV_HASH_TABLE_SIZE;
-    for (hash_abbrev_list = hash_table[hash_num].at_head;
-	 hash_abbrev_list != NULL && hash_abbrev_list->ab_code != code;
-	 hash_abbrev_list = hash_abbrev_list->ab_next);
-    if (hash_abbrev_list != NULL)
-	return (hash_abbrev_list);
+    } else if (hash_table_base->tb_total_abbrev_count >
+          ( hash_table_base->tb_table_entry_count * HT_MULTIPLE) ) {
+        struct Dwarf_Hash_Table_s newht;
+        /* Effectively multiplies by >= HT_MULTIPLE */
+        newht.tb_table_entry_count =  hash_table_base->tb_total_abbrev_count;
+        newht.tb_total_abbrev_count = 0;
+        newht.tb_entries =  _dwarf_get_alloc(dbg,
+            DW_DLA_HASH_TABLE_ENTRY, 
+            newht.tb_table_entry_count);
+
+        if(! newht.tb_entries) {
+             return NULL;
+        }
+        /* Copy the existing entries to the new table,
+           rehashing each. 
+        */
+        copy_abbrev_table_to_new_table(hash_table_base, &newht);
+        /* Dealloc only the entries hash table array, not the lists
+           of things pointed to by a hash table entry array. */
+        dwarf_dealloc(dbg, hash_table_base->tb_entries,DW_DLA_HASH_TABLE_ENTRY);
+        hash_table_base->tb_entries = 0;
+        /* Now overwrite the existing table descriptor with
+           the new, newly valid, contents. */
+        *hash_table_base = newht;
+    } /* Else is ok as is, add entry */ 
+
+    
+    hashable_val = code;
+    hash_num = hashable_val % 
+        hash_table_base->tb_table_entry_count;
+    entry_base = hash_table_base->tb_entries;
+    entry_cur  = entry_base + hash_num;
+   
+    /* Determine if the 'code' is the list of synonyms already. */
+    for (hash_abbrev_entry = entry_cur->at_head;
+         hash_abbrev_entry != NULL && hash_abbrev_entry->ab_code != code;
+         hash_abbrev_entry = hash_abbrev_entry->ab_next);
+    if (hash_abbrev_entry != NULL) {
+        /* This returns a pointer to an abbrev list entry, not 
+           the list itself. */
+        return (hash_abbrev_entry);
+    }
 
     abbrev_ptr = cu_context->cc_last_abbrev_ptr != NULL ?
-	cu_context->cc_last_abbrev_ptr :
-	dbg->de_debug_abbrev + cu_context->cc_abbrev_offset;
+        cu_context->cc_last_abbrev_ptr :
+        dbg->de_debug_abbrev.dss_data + cu_context->cc_abbrev_offset;
 
     /* End of abbrev's for this cu, since abbrev code is 0. */
     if (*abbrev_ptr == 0) {
-	return (NULL);
+        return (NULL);
     }
 
     do {
-	Dwarf_Unsigned utmp;
+        unsigned new_hashable_val;
+        DECODE_LEB128_UWORD(abbrev_ptr, abbrev_code);
+        DECODE_LEB128_UWORD(abbrev_ptr, abbrev_tag);
 
-	DECODE_LEB128_UWORD(abbrev_ptr, utmp)
-	    abbrev_code = (Dwarf_Half) utmp;
-	DECODE_LEB128_UWORD(abbrev_ptr, utmp)
-	    abbrev_tag = (Dwarf_Half) utmp;
-
-	abbrev_list = (Dwarf_Abbrev_List)
-	    _dwarf_get_alloc(cu_context->cc_dbg, DW_DLA_ABBREV_LIST, 1);
-	if (abbrev_list == NULL)
-	    return (NULL);
+        inner_list_entry = (Dwarf_Abbrev_List)
+            _dwarf_get_alloc(cu_context->cc_dbg, DW_DLA_ABBREV_LIST, 1);
+        if (inner_list_entry == NULL)
+            return (NULL);
 
-	hash_num = abbrev_code % ABBREV_HASH_TABLE_SIZE;
-	if (hash_table[hash_num].at_head == NULL) {
-	    hash_table[hash_num].at_head =
-		hash_table[hash_num].at_tail = abbrev_list;
-	} else {
-	    hash_table[hash_num].at_tail->ab_next = abbrev_list;
-	    hash_table[hash_num].at_tail = abbrev_list;
-	}
+        new_hashable_val = abbrev_code;
+        hash_num = new_hashable_val % 
+            hash_table_base->tb_table_entry_count;
+        inner_hash_entry = entry_base + hash_num;
+        /* Move_entry_to_new_hash */
+        inner_list_entry->ab_next = inner_hash_entry->at_head;
+        inner_hash_entry->at_head = inner_list_entry;
 
-	abbrev_list->ab_code = abbrev_code;
-	abbrev_list->ab_tag = abbrev_tag;
+        hash_table_base->tb_total_abbrev_count++;
 
-	abbrev_list->ab_has_child = *(abbrev_ptr++);
-	abbrev_list->ab_abbrev_ptr = abbrev_ptr;
-
-	do {
-	    Dwarf_Unsigned utmp3;
+        inner_list_entry->ab_code = abbrev_code;
+        inner_list_entry->ab_tag = abbrev_tag;
+        inner_list_entry->ab_has_child = *(abbrev_ptr++);
+        inner_list_entry->ab_abbrev_ptr = abbrev_ptr;
 
-	    DECODE_LEB128_UWORD(abbrev_ptr, utmp3)
-		attr_name = (Dwarf_Half) utmp3;
-	    DECODE_LEB128_UWORD(abbrev_ptr, utmp3)
-		attr_form = (Dwarf_Half) utmp3;
-	} while (attr_name != 0 && attr_form != 0);
+        /* Cycle thru the abbrev content, ignoring the content except
+           to find the end of the content. */
+        do {
+            DECODE_LEB128_UWORD(abbrev_ptr, attr_name);
+            DECODE_LEB128_UWORD(abbrev_ptr, attr_form);
+        } while (attr_name != 0 && attr_form != 0);
 
     } while (*abbrev_ptr != 0 && abbrev_code != code);
 
     cu_context->cc_last_abbrev_ptr = abbrev_ptr;
-    return (abbrev_code == code ? abbrev_list : NULL);
+    return (abbrev_code == code ? inner_list_entry : NULL);
 }
 
 
@@ -261,13 +378,13 @@
     char *end = endptr;
 
     while (start < end) {
-	if (*start == 0) {
-	    return 1;		/* OK! */
-	}
-	++start;
-	++end;
+        if (*start == 0) {
+            return 1;           /* OK! */
+        }
+        ++start;
+        ++end;
     }
-    return 0;			/* FAIL! bad string! */
+    return 0;                   /* FAIL! bad string! */
 }
 
 /*
@@ -283,28 +400,28 @@
     unsigned char *src = (unsigned char *) s2;
 
     if (len == 4) {
-	targ[3] = src[0];
-	targ[2] = src[1];
-	targ[1] = src[2];
-	targ[0] = src[3];
+        targ[3] = src[0];
+        targ[2] = src[1];
+        targ[1] = src[2];
+        targ[0] = src[3];
     } else if (len == 8) {
-	targ[7] = src[0];
-	targ[6] = src[1];
-	targ[5] = src[2];
-	targ[4] = src[3];
-	targ[3] = src[4];
-	targ[2] = src[5];
-	targ[1] = src[6];
-	targ[0] = src[7];
+        targ[7] = src[0];
+        targ[6] = src[1];
+        targ[5] = src[2];
+        targ[4] = src[3];
+        targ[3] = src[4];
+        targ[2] = src[5];
+        targ[1] = src[6];
+        targ[0] = src[7];
     } else if (len == 2) {
-	targ[1] = src[0];
-	targ[0] = src[1];
+        targ[1] = src[0];
+        targ[0] = src[1];
     }
 /* should NOT get below here: is not the intended use */
     else if (len == 1) {
-	targ[0] = src[0];
+        targ[0] = src[0];
     } else {
-	memcpy(s1, s2, len);
+        memcpy(s1, s2, len);
     }
 
     return orig_s1;
@@ -326,31 +443,31 @@
     int local_length_size = 0;
     int local_extension_size = 0;
     Dwarf_Unsigned length = 0;
-    Dwarf_Small *cuptr = dbg->de_debug_info + offset;
+    Dwarf_Small *cuptr = dbg->de_debug_info.dss_data + offset;
 
     READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
-		     cuptr, local_length_size, local_extension_size);
+                     cuptr, local_length_size, local_extension_size);
 
-    return local_extension_size +	/* initial extesion, if present 
-					 */
-	local_length_size +	/* Size of cu length field. */
-	sizeof(Dwarf_Half) +	/* Size of version stamp field. */
-	local_length_size +	/* Size of abbrev offset field. */
-	sizeof(Dwarf_Small);	/* Size of address size field. */
+    return local_extension_size +       /* initial extesion, if present 
+                                         */
+        local_length_size +     /* Size of cu length field. */
+        sizeof(Dwarf_Half) +    /* Size of version stamp field. */
+        local_length_size +     /* Size of abbrev offset field. */
+        sizeof(Dwarf_Small);    /* Size of address size field. */
 
 }
 
 /*
-	Pretend we know nothing about the CU
-	and just roughly compute the result. 
+        Pretend we know nothing about the CU
+        and just roughly compute the result. 
 */
 Dwarf_Unsigned
 _dwarf_length_of_cu_header_simple(Dwarf_Debug dbg)
 {
-    return dbg->de_length_size +	/* Size of cu length field. */
-	sizeof(Dwarf_Half) +	/* Size of version stamp field. */
-	dbg->de_length_size +	/* Size of abbrev offset field. */
-	sizeof(Dwarf_Small);	/* Size of address size field. */
+    return dbg->de_length_size +        /* Size of cu length field. */
+        sizeof(Dwarf_Half) +    /* Size of version stamp field. */
+        dbg->de_length_size +   /* Size of abbrev offset field. */
+        sizeof(Dwarf_Small);    /* Size of address size field. */
 }
 
 /* Now that we delay loading .debug_info, we need to do the
@@ -362,22 +479,69 @@
 int
 _dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error * error)
 {
-    int res;
+    int res = DW_DLV_ERROR;
 
-    /* Testing de_debug_info allows us to avoid testing
-       de_debug_abbrev. One test instead of 2. .debug_info is useless
+    /* Testing de_debug_info.dss_data allows us to avoid testing
+       de_debug_abbrev.dss_data. 
+       One test instead of 2. .debug_info is useless
        without .debug_abbrev. */
-    if (dbg->de_debug_info) {
-	return DW_DLV_OK;
+    if (dbg->de_debug_info.dss_data) {
+        return DW_DLV_OK;
     }
 
-    res = _dwarf_load_section(dbg, dbg->de_debug_abbrev_index,
-			      &dbg->de_debug_abbrev, error);
+    res = _dwarf_load_section(dbg, &dbg->de_debug_abbrev,error);
     if (res != DW_DLV_OK) {
-	return res;
+        return res;
     }
-    res = _dwarf_load_section(dbg, dbg->de_debug_info_index,
-			      &dbg->de_debug_info, error);
+    res = _dwarf_load_section(dbg, &dbg->de_debug_info, error);
     return res;
 
 }
+void
+_dwarf_free_abbrev_hash_table_contents(Dwarf_Debug dbg,Dwarf_Hash_Table hash_table)
+{
+    /* A Hash Table is an array with tb_table_entry_count struct
+       Dwarf_Hash_Table_s entries in the array. */
+    int hashnum = 0;
+    for (; hashnum < hash_table->tb_table_entry_count; ++hashnum) {
+        struct Dwarf_Abbrev_List_s *abbrev = 0;
+        struct Dwarf_Abbrev_List_s *nextabbrev = 0;
+        struct  Dwarf_Hash_Table_Entry_s *tb =  &hash_table->tb_entries[hashnum];
+
+        abbrev = tb->at_head;
+        for (; abbrev; abbrev = nextabbrev) {
+            nextabbrev = abbrev->ab_next;
+            dwarf_dealloc(dbg, abbrev, DW_DLA_ABBREV_LIST);
+        }
+    }
+    /* Frees all the entries at once: an array. */
+    dwarf_dealloc(dbg,hash_table->tb_entries,DW_DLA_HASH_TABLE_ENTRY);
+}
+
+/* 
+    If no die provided the size value returned might be wrong.
+    If different compilation units have different address sizes 
+    this may not give the correct value in all contexts if the die
+    pointer is NULL. 
+    If the Elf offset size != address_size 
+    (for example if address_size = 4 but recorded in elf64 object)
+    this may not give the correct value in all contexts if the die
+    pointer is NULL. 
+    If the die pointer is non-NULL (in which case it must point to
+    a valid DIE) this will return the correct size.
+*/
+int 
+_dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Die die)
+{
+    Dwarf_CU_Context context = 0;
+    Dwarf_Half addrsize = 0;
+    if(!die) {
+        return dbg->de_pointer_size;
+    }
+    context = die->di_cu_context;
+    addrsize = context->cc_address_size;
+    return addrsize;
+}
+
+
+
--- a/usr/src/tools/ctf/dwarf/common/dwarf_util.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_util.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,9 @@
+#ifndef DWARF_UTIL_H
+#define DWARF_UTIL_H
 /*
 
   Copyright (C) 2000,2003,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +20,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -32,34 +35,43 @@
   http://oss.sgi.com/projects/GenInfo/NoticeExplan
 
 */
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
 
 
 
 /*
-    Decodes unsigned leb128 encoded numbers that 
-    are assumed to be less than 4 bytes long.  
+    Decodes unsigned leb128 encoded numbers.
     Make sure ptr is a pointer to a 1-byte type.  
-    Returns UINT_MAX on error.
-
+    In 2003 and earlier this was a hand-inlined
+    version of _dwarf_decode_u_leb128() which did
+    not work correctly if Dwarf_Word was 64 bits.
 */
 #define DECODE_LEB128_UWORD(ptr, value) \
-    { \
+    do { \
        Dwarf_Word uleblen; \
 	value = _dwarf_decode_u_leb128(ptr,&uleblen); \
         ptr += uleblen; \
-    }
+    } while (0)
 
 /*
     Decodes signed leb128 encoded numbers.
     Make sure ptr is a pointer to a 1-byte type.
+    In 2003 and earlier this was a hand-inlined
+    version of _dwarf_decode_s_leb128() which did
+    not work correctly if Dwarf_Word was 64 bits.
 
 */
 #define DECODE_LEB128_SWORD(ptr, value) \
-    { \
+    do { \
        Dwarf_Word sleblen; \
 	value = _dwarf_decode_s_leb128(ptr,&sleblen); \
         ptr += sleblen; \
-    }
+    } while(0)
 
 
 /*
@@ -68,18 +80,18 @@
     signed and unsigned numbers.
 */
 #define SKIP_LEB128_WORD(ptr) \
-    if ((*(ptr++) & 0x80) != 0) { \
+    do{ if ((*(ptr++) & 0x80) != 0) { \
         if ((*(ptr++) & 0x80) != 0) { \
             if ((*(ptr++) & 0x80) != 0) { \
 	        if ((*(ptr++) & 0x80) != 0) { \
 	        } \
 	    } \
         } \
-    }
+    } } while (0)
 
 
 #define CHECK_DIE(die, error_ret_value) \
-    if (die == NULL) { \
+do {if (die == NULL) { \
 	_dwarf_error(NULL, error, DW_DLE_DIE_NULL); \
 	return(error_ret_value); \
     } \
@@ -90,7 +102,8 @@
     if (die->di_cu_context->cc_dbg == NULL) { \
 	_dwarf_error(NULL, error, DW_DLE_DBG_NULL); \
 	return(error_ret_value); \
-    }
+    }  \
+} while (0)
 
 
 /* 
@@ -108,12 +121,12 @@
 
 #ifdef WORDS_BIGENDIAN
 #define READ_UNALIGNED(dbg,dest,desttype, source, length) \
-    { \
+    do { \
       BIGGEST_UINT _ltmp = 0;  \
       dbg->de_copy_word( (((char *)(&_ltmp)) + sizeof(_ltmp) - length), \
 			source, length) ; \
       dest = (desttype)_ltmp;  \
-    }
+    } while (0)
 
 
 /*
@@ -125,18 +138,20 @@
     The memcpy args are the issue.
 */
 #define SIGN_EXTEND(dest, length) \
-    if (*(Dwarf_Sbyte *)((char *)&dest + sizeof(dest) - length) < 0) \
+    do {if (*(Dwarf_Sbyte *)((char *)&dest + sizeof(dest) - length) < 0) {\
 	memcpy((char *)&dest, "\xff\xff\xff\xff\xff\xff\xff\xff", \
-	    sizeof(dest) - length)
+	    sizeof(dest) - length);  \
+        } \
+     } while (0)
 #else /* LITTLE ENDIAN */
 
 #define READ_UNALIGNED(dbg,dest,desttype, source, length) \
-    { \
+    do  { \
       BIGGEST_UINT _ltmp = 0;  \
       dbg->de_copy_word( (char *)(&_ltmp) , \
                         source, length) ; \
       dest = (desttype)_ltmp;  \
-    }
+     } while (0)
 
 
 /*
@@ -148,10 +163,12 @@
     The memcpy args are the issue.
 */
 #define SIGN_EXTEND(dest, length) \
-    if (*(Dwarf_Sbyte *)((char *)&dest + (length-1)) < 0) \
+    do {if (*(Dwarf_Sbyte *)((char *)&dest + (length-1)) < 0) {\
         memcpy((char *)&dest+length,    \
                 "\xff\xff\xff\xff\xff\xff\xff\xff", \
-            sizeof(dest) - length)
+            sizeof(dest) - length); \
+        }  \
+    } while (0)
 
 #endif /* ! LITTLE_ENDIAN */
 
@@ -165,8 +182,9 @@
    It reads the bits from where rw_src_data_p  points to 
    and updates the rw_src_data_p to point past what was just read.
 
-   It updates w_length_size and w_exten_size (which
-	are really issues only for the dwarfv2.1  64bit extension).
+   It updates w_length_size (to the size of an offset, either 4 or 8)
+   and w_exten_size (set 0 unless this frame has the DWARF3,4 64bit
+   extension, in which case w_exten_size is set to 4).
 
    r_dbg is just the current dbg pointer.
    w_target is the output length field.
@@ -189,17 +207,15 @@
    dwarf that the first 32 bits of the 64bit offset will be
    zero (because the compiler could not handle a truly large 
    value as of Jan 2003 and because no app has that much debug 
-   info anyway (yet)).
+   info anyway, at least not in the IRIX case).
 
    At present not testing for '64bit elf' here as that
    does not seem necessary (none of the 64bit length seems 
    appropriate unless it's  ident[EI_CLASS] == ELFCLASS64).
-   Might be a good idea though.
-
 */
 #   define    READ_AREA_LENGTH(r_dbg,w_target,r_targtype,         \
 	rw_src_data_p,w_length_size,w_exten_size)                 \
-    READ_UNALIGNED(r_dbg,w_target,r_targtype,                     \
+do {    READ_UNALIGNED(r_dbg,w_target,r_targtype,                 \
                 rw_src_data_p, ORIGINAL_DWARF_OFFSET_SIZE);       \
     if(w_target == DISTINGUISHED_VALUE) {                         \
 	     /* dwarf3 64bit extension */                         \
@@ -211,7 +227,9 @@
              rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE;    \
     } else {                                                      \
 	if(w_target == 0 && r_dbg->de_big_endian_object) {        \
-	     /* IRIX 64 bit, big endian */                        \
+	     /* IRIX 64 bit, big endian.  This test */            \
+	     /* is not a truly precise test, a precise test */    \
+             /* would check if the target was IRIX.  */           \
              READ_UNALIGNED(r_dbg,w_target,r_targtype,            \
                 rw_src_data_p, DISTINGUISHED_VALUE_OFFSET_SIZE);  \
 	     w_length_size  = DISTINGUISHED_VALUE_OFFSET_SIZE;    \
@@ -223,9 +241,7 @@
              w_length_size  = ORIGINAL_DWARF_OFFSET_SIZE;         \
              rw_src_data_p += w_length_size;                      \
 	}                                                         \
-    }
-
-
+    } } while(0)
 
 Dwarf_Unsigned
 _dwarf_decode_u_leb128(Dwarf_Small * leb128,
@@ -237,21 +253,44 @@
 
 Dwarf_Unsigned
 _dwarf_get_size_of_val(Dwarf_Debug dbg,
-		       Dwarf_Unsigned form,
-		       Dwarf_Small * val_ptr, int v_length_size);
+    Dwarf_Unsigned form,
+    Dwarf_Half address_size,
+    Dwarf_Small * val_ptr, 
+    int v_length_size);
+
+struct Dwarf_Hash_Table_Entry_s;
+/* This single struct is the base for the hash table.
+   The intent is that once the total_abbrev_count across
+   all the entries is greater than  10*current_table_entry_count
+   one should build a new Dwarf_Hash_Table_Base_s, rehash
+   all the existing entries, and delete the old table and entries. 
+   (10 is a heuristic, nothing magic about it, but once the
+   count gets to 30 or 40 times current_table_entry_count
+   things really slow down a lot. One (500MB) application had
+   127000 abbreviations in one compilation unit)
+   The incoming 'code' is an abbrev number and those simply
+   increase linearly so the hashing is perfect always.
+*/
+struct Dwarf_Hash_Table_s {
+      unsigned long       tb_table_entry_count;
+      unsigned long       tb_total_abbrev_count;
+      /* Each table entry is a list of abbreviations. */
+      struct  Dwarf_Hash_Table_Entry_s *tb_entries;
+};
 
 /*
     This struct is used to build a hash table for the
     abbreviation codes for a compile-unit.  
 */
-struct Dwarf_Hash_Table_s {
+struct Dwarf_Hash_Table_Entry_s {
     Dwarf_Abbrev_List at_head;
-    Dwarf_Abbrev_List at_tail;
 };
 
+
+
 Dwarf_Abbrev_List
 _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context,
-			   Dwarf_Word code);
+			   Dwarf_Unsigned code);
 
 
 /* return 1 if string ends before 'endptr' else
@@ -264,4 +303,9 @@
 					  Dwarf_Unsigned offset);
 Dwarf_Unsigned _dwarf_length_of_cu_header_simple(Dwarf_Debug);
 
-int _dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error *error);
+int  _dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error *error);
+void _dwarf_free_abbrev_hash_table_contents(Dwarf_Debug dbg,
+    struct Dwarf_Hash_Table_s* hash_table);
+int _dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Die die);
+
+#endif /* DWARF_UTIL_H */
--- a/usr/src/tools/ctf/dwarf/common/dwarf_vars.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_vars.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2009-2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -43,32 +44,41 @@
 
 int
 dwarf_get_vars(Dwarf_Debug dbg,
-	       Dwarf_Var ** vars,
-	       Dwarf_Signed * ret_var_count, Dwarf_Error * error)
+    Dwarf_Var ** vars,
+    Dwarf_Signed * ret_var_count, Dwarf_Error * error)
 {
-    int res;
-
-    res =
-       _dwarf_load_section(dbg,
-		           dbg->de_debug_varnames_index,
-			   &dbg->de_debug_varnames,
-		           error);
+    int res = _dwarf_load_section(dbg, &dbg->de_debug_varnames,error);
     if (res != DW_DLV_OK) {
-	return res;
+        return res;
     }
 
-    return _dwarf_internal_get_pubnames_like_data(dbg, dbg->de_debug_varnames, dbg->de_debug_varnames_size, (Dwarf_Global **) vars,	/* type 
-																	   punning,
-																	   Dwarf_Type 
-																	   is never
-																	   a
-																	   completed 
-																	   type */
-						  ret_var_count,
-						  error,
-						  DW_DLA_VAR_CONTEXT,
-						  DW_DLE_DEBUG_VARNAMES_LENGTH_BAD,
-						  DW_DLE_DEBUG_VARNAMES_VERSION_ERROR);
+    return _dwarf_internal_get_pubnames_like_data(dbg, 
+        dbg->de_debug_varnames.dss_data, 
+        dbg->de_debug_varnames.dss_size, 
+        (Dwarf_Global **) vars, /* Type punning for sections 
+            with identical format. */
+        ret_var_count,
+        error,
+        DW_DLA_VAR_CONTEXT,
+        DW_DLA_VAR,
+        DW_DLE_DEBUG_VARNAMES_LENGTH_BAD,
+        DW_DLE_DEBUG_VARNAMES_VERSION_ERROR);
+}
+
+/* Deallocating fully requires deallocating the list
+   and all entries.  But some internal data is
+   not exposed, so we need a function with internal knowledge.
+*/
+
+void
+dwarf_vars_dealloc(Dwarf_Debug dbg, Dwarf_Var * dwgl,
+                   Dwarf_Signed count)
+{
+    _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl,
+        count,
+        DW_DLA_VAR_CONTEXT,
+        DW_DLA_VAR, DW_DLA_LIST);
+    return;
 }
 
 
@@ -78,8 +88,8 @@
     Dwarf_Global var = (Dwarf_Global) var_in;
 
     if (var == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_VAR_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_VAR_NULL);
+        return (DW_DLV_ERROR);
     }
 
     *ret_varname = (char *) (var->gl_name);
@@ -89,7 +99,7 @@
 
 int
 dwarf_var_die_offset(Dwarf_Var var_in,
-		     Dwarf_Off * returned_offset, Dwarf_Error * error)
+        Dwarf_Off * returned_offset, Dwarf_Error * error)
 {
     Dwarf_Global var = (Dwarf_Global) var_in;
 
@@ -100,7 +110,7 @@
 
 int
 dwarf_var_cu_offset(Dwarf_Var var_in,
-		    Dwarf_Off * returned_offset, Dwarf_Error * error)
+                    Dwarf_Off * returned_offset, Dwarf_Error * error)
 {
     Dwarf_Global var = (Dwarf_Global) var_in;
 
@@ -110,14 +120,14 @@
 
 int
 dwarf_var_name_offsets(Dwarf_Var var_in,
-		       char **returned_name,
-		       Dwarf_Off * die_offset,
-		       Dwarf_Off * cu_offset, Dwarf_Error * error)
+        char **returned_name,
+        Dwarf_Off * die_offset,
+        Dwarf_Off * cu_offset, Dwarf_Error * error)
 {
     Dwarf_Global var = (Dwarf_Global) var_in;
 
     return
-	dwarf_global_name_offsets(var,
-				  returned_name, die_offset, cu_offset,
-				  error);
+        dwarf_global_name_offsets(var,
+            returned_name, die_offset, cu_offset,
+            error);
 }
--- a/usr/src/tools/ctf/dwarf/common/dwarf_vars.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_vars.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
--- a/usr/src/tools/ctf/dwarf/common/dwarf_weaks.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_weaks.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2009-2010 David Anderson. All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -43,33 +44,41 @@
 
 int
 dwarf_get_weaks(Dwarf_Debug dbg,
-		Dwarf_Weak ** weaks,
-		Dwarf_Signed * ret_weak_count, Dwarf_Error * error)
+    Dwarf_Weak ** weaks,
+    Dwarf_Signed * ret_weak_count, Dwarf_Error * error)
 {
-    int res;
-
-    res =
-       _dwarf_load_section(dbg,
-		           dbg->de_debug_weaknames_index,
-			   &dbg->de_debug_weaknames,
-		           error);
+    int res = _dwarf_load_section(dbg, &dbg->de_debug_weaknames,error);
     if (res != DW_DLV_OK) {
-	return res;
+        return res;
     }
 
-    return _dwarf_internal_get_pubnames_like_data(dbg, dbg->de_debug_weaknames, dbg->de_debug_weaknames_size, (Dwarf_Global **) weaks,	/* type 
-																	   punning,
-																	   Dwarf_Type 
-																	   is never
-																	   a
-																	   completed 
-																	   type */
-						  ret_weak_count,
-						  error,
-						  DW_DLA_WEAK_CONTEXT,
-						  DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD,
-						  DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR);
+    return _dwarf_internal_get_pubnames_like_data(dbg, 
+        dbg->de_debug_weaknames.dss_data, 
+        dbg->de_debug_weaknames.dss_size, 
+        (Dwarf_Global **) weaks, /* Type punning for sections 
+            with identical format. */
+        ret_weak_count,
+        error,
+        DW_DLA_WEAK_CONTEXT,
+        DW_DLA_WEAK,
+        DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD,
+        DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR);
+}
 
+/* Deallocating fully requires deallocating the list
+   and all entries.  But some internal data is
+   not exposed, so we need a function with internal knowledge.
+*/
+
+void
+dwarf_weaks_dealloc(Dwarf_Debug dbg, Dwarf_Weak * dwgl,
+    Dwarf_Signed count)
+{
+    _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl,
+        count,
+        DW_DLA_WEAK_CONTEXT,
+        DW_DLA_WEAK, DW_DLA_LIST);
+    return;
 }
 
 
@@ -80,8 +89,8 @@
     Dwarf_Global weak = (Dwarf_Global) weak_in;
 
     if (weak == NULL) {
-	_dwarf_error(NULL, error, DW_DLE_WEAK_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_error(NULL, error, DW_DLE_WEAK_NULL);
+        return (DW_DLV_ERROR);
     }
     *ret_name = (char *) (weak->gl_name);
     return DW_DLV_OK;
@@ -90,7 +99,7 @@
 
 int
 dwarf_weak_die_offset(Dwarf_Weak weak_in,
-		      Dwarf_Off * weak_off, Dwarf_Error * error)
+    Dwarf_Off * weak_off, Dwarf_Error * error)
 {
     Dwarf_Global weak = (Dwarf_Global) weak_in;
 
@@ -100,7 +109,7 @@
 
 int
 dwarf_weak_cu_offset(Dwarf_Weak weak_in,
-		     Dwarf_Off * weak_off, Dwarf_Error * error)
+    Dwarf_Off * weak_off, Dwarf_Error * error)
 {
     Dwarf_Global weak = (Dwarf_Global) weak_in;
 
@@ -110,13 +119,12 @@
 
 int
 dwarf_weak_name_offsets(Dwarf_Weak weak_in,
-			char **weak_name,
-			Dwarf_Off * die_offset,
-			Dwarf_Off * cu_offset, Dwarf_Error * error)
+    char **weak_name,
+    Dwarf_Off * die_offset,
+    Dwarf_Off * cu_offset, Dwarf_Error * error)
 {
     Dwarf_Global weak = (Dwarf_Global) weak_in;
 
     return dwarf_global_name_offsets(weak,
-				     weak_name,
-				     die_offset, cu_offset, error);
+        weak_name, die_offset, cu_offset, error);
 }
--- a/usr/src/tools/ctf/dwarf/common/dwarf_weaks.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/dwarf_weaks.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
--- a/usr/src/tools/ctf/dwarf/common/libdwarf.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/libdwarf.h	Sun May 22 03:13:22 2011 +0100
@@ -1,10 +1,9 @@
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
-  Copyright (C) 2000, 2001, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+
+  Copyright (C) 2000-2010 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
+  Portions Copyright 2008-2010 David Anderson. All rights reserved.
+  Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License
@@ -23,10 +22,10 @@
 
   You should have received a copy of the GNU Lesser General Public
   License along with this program; if not, write the Free Software
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -44,33 +43,30 @@
 extern "C" {
 #endif
 /*
-	libdwarf.h  
-	$Revision: 1.74 $ $Date: 2002/06/11 17:49:06 $
-
-	For libdwarf producers and consumers
-
-	The interface is defined as having 8-byte signed and unsigned
-	values so it can handle 64-or-32bit target on 64-or-32bit host.
-	Addr is the native size: it represents pointers on
-	the host machine (not the target!).
-
-	This contains declarations for types and all producer
-	and consumer functions.
-
-	Function declarations are written on a single line each here
-	so one can use grep  to each declaration in its entirety.
-	The declarations are a little harder to read this way, but...
+    libdwarf.h  
+    $Revision: #9 $ $Date: 2008/01/17 $
+
+    For libdwarf producers and consumers
+
+    The interface is defined as having 8-byte signed and unsigned
+    values so it can handle 64-or-32bit target on 64-or-32bit host.
+    Addr is the native size: it represents pointers on
+    the host machine (not the target!).
+
+    This contains declarations for types and all producer
+    and consumer functions.
+
+    Function declarations are written on a single line each here
+    so one can use grep  to each declaration in its entirety.
+    The declarations are a little harder to read this way, but...
 
 */
 
-#ifdef __SGI_FAST_LIBELF
-struct elf_sgi;
-typedef struct elf_sgi* dwarf_elf_handle;
-#else
 struct Elf;
 typedef struct Elf* dwarf_elf_handle;
-#endif
-
+
+/* To enable printing with printf regardless of the
+   actual underlying data type, we define the DW_PR_xxx macros. */
 #if (_MIPS_SZLONG == 64)
 /* Special case for MIPS, so -64 (LP64) build gets simple -long-.
    Non-MIPS LP64 or ILP64 environments should probably ensure
@@ -83,6 +79,11 @@
 typedef unsigned char   Dwarf_Small;        /* 1 byte unsigned value */
 typedef signed   long   Dwarf_Signed;       /* 4 or 8 byte signed value */
 typedef unsigned long   Dwarf_Addr;         /* target memory address */
+#define  DW_PR_DUx  "lx"
+#define  DW_PR_DSx  "lx"
+#define  DW_PR_DUu  "lu"
+#define  DW_PR_DSd  "ld"
+
 #else /* 32-bit */
 /* This is for ILP32, allowing i/o of 64bit dwarf info.
    Also should be fine for LP64 and ILP64 cases.
@@ -94,16 +95,40 @@
 typedef unsigned char       Dwarf_Small;    /* 1 byte unsigned value */
 typedef signed   long long  Dwarf_Signed;   /* 8 byte signed value */
 typedef unsigned long long  Dwarf_Addr;     /* target memory address */
+#define  DW_PR_DUx  "llx"
+#define  DW_PR_DSx  "llx"
+#define  DW_PR_DUu  "llu"
+#define  DW_PR_DSd  "lld"
 #endif
-typedef void*		Dwarf_Ptr;          /* host machine pointer */
+#ifdef HAVE_NONSTANDARD_PRINTF_64_FORMAT
+/* Windows does not use std C formatting, so allow it. */
+#undef DW_PR_DUx
+#undef DW_PR_DSx
+#undef DW_PR_DUu
+#undef DW_PR_DSd
+#define  DW_PR_DUx  "I64x"
+#define  DW_PR_DSx  "I64x"
+#define  DW_PR_DUu  "I64u"
+#define  DW_PR_DSd  "I64d"
+#endif /* HAVE_NONSTANDARD_FORMAT */
+
+typedef void*        Dwarf_Ptr;          /* host machine pointer */
+
+/* Used for DW_FORM_ref_sig8. It is not a string, it
+   is 8 bytes of a signature one would use to find
+   a type unit. See dwarf_formsig8()
+*/
+typedef struct  {
+    char signature[8];
+} Dwarf_Sig8;
 
 /* Contains info on an uninterpreted block of data
 */
 typedef struct {
-        Dwarf_Unsigned  bl_len;         /* length of block */
-        Dwarf_Ptr       bl_data;        /* uninterpreted data */
-	Dwarf_Small     bl_from_loclist; /*non-0 if loclist, else debug_info*/
-	Dwarf_Unsigned  bl_section_offset; /* Section (not CU) offset
+    Dwarf_Unsigned  bl_len;         /* length of block */
+    Dwarf_Ptr       bl_data;        /* uninterpreted data */
+    Dwarf_Small     bl_from_loclist; /*non-0 if loclist, else debug_info*/
+    Dwarf_Unsigned  bl_section_offset; /* Section (not CU) offset
                                         which 'data' comes from. */
 } Dwarf_Block;
 
@@ -111,50 +136,313 @@
 /* location record
 */
 typedef struct {
-        Dwarf_Small     lr_atom;        /* location operation */
-        Dwarf_Unsigned  lr_number;      /* operand */
-	Dwarf_Unsigned  lr_number2;     /* for OP_BREGx */
-	Dwarf_Unsigned  lr_offset;      /* offset in locexpr for OP_BRA etc */
+    Dwarf_Small     lr_atom;        /* location operation */
+    Dwarf_Unsigned  lr_number;      /* operand */
+    Dwarf_Unsigned  lr_number2;     /* for OP_BREGx */
+    Dwarf_Unsigned  lr_offset;      /* offset in locexpr for OP_BRA etc */
 } Dwarf_Loc;
 
 
 /* location description
 */
 typedef struct {
-        Dwarf_Addr      ld_lopc;        /* beginning of active range */ 
-        Dwarf_Addr      ld_hipc;        /* end of active range */
-        Dwarf_Half      ld_cents;       /* count of location records */
-        Dwarf_Loc*      ld_s;           /* pointer to list of same */
-	Dwarf_Small     ld_from_loclist; 
-				      /* non-0 if loclist, else debug_info*/
-
-	Dwarf_Unsigned  ld_section_offset; /* Section (not CU) offset
-					where loc-expr begins*/
+    Dwarf_Addr      ld_lopc;        /* beginning of active range */ 
+    Dwarf_Addr      ld_hipc;        /* end of active range */
+    Dwarf_Half      ld_cents;       /* count of location records */
+    Dwarf_Loc*      ld_s;           /* pointer to list of same */
+    Dwarf_Small     ld_from_loclist; 
+                      /* non-0 if loclist, else debug_info*/
+
+    Dwarf_Unsigned  ld_section_offset; /* Section (not CU) offset
+                    where loc-expr begins*/
 } Dwarf_Locdesc;
 
+/* First appears in DWARF3.
+   The dwr_addr1/addr2 data is either an offset (DW_RANGES_ENTRY)
+   or an address (dwr_addr2 in DW_RANGES_ADDRESS_SELECTION) or
+   both are zero (DW_RANGES_END).
+*/
+enum Dwarf_Ranges_Entry_Type { DW_RANGES_ENTRY, 
+    DW_RANGES_ADDRESS_SELECTION,
+    DW_RANGES_END };
+typedef struct {
+    Dwarf_Addr dwr_addr1;
+    Dwarf_Addr dwr_addr2; 
+    enum Dwarf_Ranges_Entry_Type  dwr_type;
+} Dwarf_Ranges;
+
 /* Frame description instructions expanded.
 */
 typedef struct {
-        Dwarf_Small     fp_base_op;
-        Dwarf_Small     fp_extended_op;
-        Dwarf_Half      fp_register;
-        Dwarf_Unsigned  fp_offset;
-        Dwarf_Off       fp_instr_offset;
-} Dwarf_Frame_Op;
-
-/* DW_REG_TABLE_SIZE must reflect the number of registers 
- *(DW_FRAME_LAST_REG_NUM) as defined in dwarf.h
+    Dwarf_Small     fp_base_op;
+    Dwarf_Small     fp_extended_op;
+    Dwarf_Half      fp_register;
+
+    /* Value may be signed, depends on op. 
+           Any applicable data_alignment_factor has
+           not been applied, this is the  raw offset. */
+    Dwarf_Unsigned  fp_offset;
+    Dwarf_Off       fp_instr_offset;
+} Dwarf_Frame_Op; /* DWARF2 */
+
+typedef struct {
+    Dwarf_Small     fp_base_op;
+    Dwarf_Small     fp_extended_op;
+    Dwarf_Half      fp_register;
+
+    /* Value may be signed, depends on op. 
+           Any applicable data_alignment_factor has
+           not been applied, this is the  raw offset. */
+    Dwarf_Unsigned  fp_offset_or_block_len; 
+    Dwarf_Small     *fp_expr_block;
+
+    Dwarf_Off       fp_instr_offset;
+} Dwarf_Frame_Op3;  /* DWARF3 and DWARF2 compatible */
+
+/*  ***IMPORTANT NOTE, TARGET DEPENDENCY ****
+   DW_REG_TABLE_SIZE must be at least as large as
+   the number of registers
+   (DW_FRAME_LAST_REG_NUM) as defined in dwarf.h
+   Preferably identical to DW_FRAME_LAST_REG_NUM.
+   Ensure [0-DW_REG_TABLE_SIZE] does not overlap 
+   DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL. 
+   Also ensure DW_FRAME_REG_INITIAL_VALUE is set to what
+   is appropriate to your cpu.
+   For various CPUs  DW_FRAME_UNDEFINED_VAL is correct
+   as the value for DW_FRAME_REG_INITIAL_VALUE.
+
+   For consumer apps, this can be set dynamically: see
+   dwarf_set_frame_rule_table_size();
  */
+#ifndef DW_REG_TABLE_SIZE
 #define DW_REG_TABLE_SIZE  66
-typedef struct {
-    struct {
-	Dwarf_Small         dw_offset_relevant;
-	Dwarf_Half          dw_regnum;
-	Dwarf_Addr          dw_offset;
-    }			    rules[DW_REG_TABLE_SIZE];
+#endif
+
+/* For MIPS, DW_FRAME_SAME_VAL is the correct default value 
+   for a frame register value. For other CPUS another value
+   may be better, such as DW_FRAME_UNDEFINED_VAL.
+   See dwarf_set_frame_rule_table_size
+*/
+#ifndef DW_FRAME_REG_INITIAL_VALUE
+#define DW_FRAME_REG_INITIAL_VALUE DW_FRAME_SAME_VAL
+#endif
+
+/* Taken as meaning 'undefined value', this is not
+   a column or register number.
+   Only present at libdwarf runtime in the consumer
+   interfaces. Never on disk.
+   DW_FRAME_* Values present on disk are in dwarf.h
+   Ensure this is > DW_REG_TABLE_SIZE (the reg table
+   size is changeable at runtime with the *reg3() interfaces,
+   and this value must be greater than the reg table size).
+*/
+#define DW_FRAME_UNDEFINED_VAL          1034
+
+/* Taken as meaning 'same value' as caller had, not a column
+   or register number.
+   Only present at libdwarf runtime in the consumer
+   interfaces. Never on disk.
+   DW_FRAME_* Values present on disk are in dwarf.h
+   Ensure this is > DW_REG_TABLE_SIZE (the reg table
+   size is changeable at runtime with the *reg3() interfaces,
+   and this value must be greater than the reg table size).
+*/
+#define DW_FRAME_SAME_VAL               1035
+
+/* For DWARF3 consumer interfaces, make the CFA a column with no
+   real table number.  This is what should have been done
+   for the DWARF2 interfaces.  This actually works for
+   both DWARF2 and DWARF3, but see the libdwarf documentation
+   on Dwarf_Regtable3 and  dwarf_get_fde_info_for_reg3()
+   and  dwarf_get_fde_info_for_all_regs3()  
+   Do NOT use this with the older dwarf_get_fde_info_for_reg()
+   or dwarf_get_fde_info_for_all_regs() consumer interfaces.
+   Must be higher than any register count for *any* ABI
+   (ensures maximum applicability with minimum effort).
+   Ensure this is > DW_REG_TABLE_SIZE (the reg table
+   size is changeable at runtime with the *reg3() interfaces,
+   and this value must be greater than the reg table size).
+   Only present at libdwarf runtime in the consumer
+   interfaces. Never on disk.
+*/
+#define DW_FRAME_CFA_COL3               1436
+
+/* The following are all needed to evaluate DWARF3 register rules.
+*/
+#define DW_EXPR_OFFSET 0  /* DWARF2 only sees this. */
+#define DW_EXPR_VAL_OFFSET 1
+#define DW_EXPR_EXPRESSION 2
+#define DW_EXPR_VAL_EXPRESSION 3
+
+typedef struct Dwarf_Regtable_Entry_s {
+    /*  For each index i (naming a hardware register with dwarf number
+            i) the following is true and defines the value of that register:
+
+           If dw_regnum is Register DW_FRAME_UNDEFINED_VAL  
+         it is not DWARF register number but
+        a place holder indicating the register has no defined value.
+           If dw_regnum is Register DW_FRAME_SAME_VAL 
+           it  is not DWARF register number but
+        a place holder indicating the register has the same
+                value in the previous frame.
+       DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL are
+           only present at libdwarf runtime. Never on disk.
+           DW_FRAME_* Values present on disk are in dwarf.h
+
+          Otherwise: the register number is a DWARF register number
+          (see ABI documents for how this translates to hardware/
+           software register numbers in the machine hardware)
+      and the following applies:
+
+          if dw_value_type == DW_EXPR_OFFSET (the only case for dwarf2):
+            If dw_offset_relevant is non-zero, then
+                the value is stored at at the address CFA+N where 
+                N is a signed offset. 
+                Rule: Offset(N)
+            If dw_offset_relevant is zero, then the value of the register
+                is the value of (DWARF) register number dw_regnum.
+                Rule: register(F)
+          Other values of dw_value_type are an error.
+        */
+    Dwarf_Small         dw_offset_relevant;
+
+    /* For DWARF2, always 0 */
+        Dwarf_Small         dw_value_type; 
+
+    Dwarf_Half          dw_regnum;
+
+    /* The data type here should  the larger of Dwarf_Addr
+           and Dwarf_Unsigned and Dwarf_Signed. */
+    Dwarf_Addr          dw_offset;
+} Dwarf_Regtable_Entry;
+
+typedef struct Dwarf_Regtable_s {
+    struct Dwarf_Regtable_Entry_s rules[DW_REG_TABLE_SIZE];
 } Dwarf_Regtable;
 
-/* for DW_DLC_SYMBOLIC_RELOCATIONS output to caller 
+/* opaque type. Functional interface shown later. */
+struct Dwarf_Reg_value3_s;
+typedef struct Dwarf_Reg_value3_s Dwarf_Reg_Value3; 
+
+typedef struct Dwarf_Regtable_Entry3_s {
+    /*  For each index i (naming a hardware register with dwarf number
+        i) the following is true and defines the value of that register:
+
+          If dw_regnum is Register DW_FRAME_UNDEFINED_VAL  
+             it is not DWARF register number but
+             a place holder indicating the register has no defined value.
+          If dw_regnum is Register DW_FRAME_SAME_VAL 
+             it  is not DWARF register number but
+             a place holder indicating the register has the same
+             value in the previous frame.
+           DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL and
+             DW_FRAME_CFA_COL3 are only present at libdwarf runtime. 
+             Never on disk.
+             DW_FRAME_* Values present on disk are in dwarf.h
+           Because DW_FRAME_SAME_VAL and DW_FRAME_UNDEFINED_VAL 
+           and DW_FRAME_CFA_COL3 are defineable at runtime 
+           consider the names symbolic in this comment, not absolute.
+
+          Otherwise: the register number is a DWARF register number
+            (see ABI documents for how this translates to hardware/
+             software register numbers in the machine hardware)
+             and the following applies:
+
+           In a cfa-defining entry (rt3_cfa_rule) the regnum is the
+           CFA 'register number'. Which is some 'normal' register,
+           not DW_FRAME_CFA_COL3, nor DW_FRAME_SAME_VAL, nor 
+           DW_FRAME_UNDEFINED_VAL.
+
+          If dw_value_type == DW_EXPR_OFFSET (the only  possible case for 
+             dwarf2):
+            If dw_offset_relevant is non-zero, then
+               the value is stored at at the address 
+               CFA+N where N is a signed offset. 
+               dw_regnum is the cfa register rule which means
+               one ignores dw_regnum and uses the CFA appropriately.
+               So dw_offset_or_block_len is a signed value, really,
+               and must be printed/evaluated as such.
+               Rule: Offset(N)
+            If dw_offset_relevant is zero, then the value of the register
+               is the value of (DWARF) register number dw_regnum.
+               Rule: register(R)
+          If dw_value_type  == DW_EXPR_VAL_OFFSET
+            the  value of this register is CFA +N where N is a signed offset.
+            dw_regnum is the cfa register rule which means
+            one ignores dw_regnum and uses the CFA appropriately.
+            Rule: val_offset(N)
+          If dw_value_type  == DW_EXPR_EXPRESSION
+            The value of the register is the value at the address
+            computed by evaluating the DWARF expression E.
+            Rule: expression(E)
+            The expression E byte stream is pointed to by dw_block_ptr.
+            The expression length in bytes is given by
+            dw_offset_or_block_len.
+          If dw_value_type  == DW_EXPR_VAL_EXPRESSION
+            The value of the register is the value
+            computed by evaluating the DWARF expression E.
+            Rule: val_expression(E)
+            The expression E byte stream is pointed to by dw_block_ptr.
+            The expression length in bytes is given by
+            dw_offset_or_block_len.
+          Other values of dw_value_type are an error.
+        */
+    Dwarf_Small         dw_offset_relevant;
+    Dwarf_Small         dw_value_type; 
+    Dwarf_Half          dw_regnum;
+    Dwarf_Unsigned      dw_offset_or_block_len;
+    Dwarf_Ptr           dw_block_ptr;
+
+}Dwarf_Regtable_Entry3;
+
+/* For the DWARF3 version, moved the DW_FRAME_CFA_COL
+   out of the array and into its own struct.  
+   Having it part of the array is not very easy to work
+   with from a portability point of view: changing
+   the number for every architecture is a pain (if one fails
+   to set it correctly a register rule gets clobbered when
+   setting CFA).  With MIPS it just happened to be easy to use 
+   DW_FRAME_CFA_COL (it was wrong conceptually but it was easy...).
+
+   rt3_rules and rt3_reg_table_size must be filled in before 
+   calling libdwarf.  Filled in with a pointer to an array 
+   (pointer and array  set up by the calling application) 
+   of rt3_reg_table_size Dwarf_Regtable_Entry3_s structs.   
+   libdwarf does not allocate or deallocate space for the
+   rules, you must do so.   libdwarf will initialize the
+   contents rules array, you do not need to do so (though
+   if you choose to initialize the array somehow that is ok:
+   libdwarf will overwrite your initializations with its own).
+
+*/
+typedef struct Dwarf_Regtable3_s {
+    struct Dwarf_Regtable_Entry3_s   rt3_cfa_rule;
+
+    Dwarf_Half                       rt3_reg_table_size;
+    struct Dwarf_Regtable_Entry3_s * rt3_rules;
+} Dwarf_Regtable3;
+
+
+/* Use for DW_EPXR_STANDARD., DW_EXPR_VAL_OFFSET. 
+   Returns DW_DLV_OK if the value is available.
+   If DW_DLV_OK returns the regnum and offset thru the pointers
+   (which the consumer must use appropriately). 
+*/
+int dwarf_frame_get_reg_register(struct Dwarf_Regtable_Entry3_s *reg_in,
+    Dwarf_Small *offset_relevant,
+    Dwarf_Half *regnum_out,
+    Dwarf_Signed *offset_out);
+
+/* Use for DW_EXPR_EXPRESSION, DW_EXPR_VAL_EXPRESSION.
+   Returns DW_DLV_OK if the value is available.
+   The caller must pass in the address of a valid
+   Dwarf_Block (the caller need not initialize it).
+*/
+int dwarf_frame_get_reg_expression(struct Dwarf_Regtable_Entry3_s *reg_in,
+    Dwarf_Block *block_out);
+
+
+/* For DW_DLC_SYMBOLIC_RELOCATIONS output to caller 
    v2, adding drd_length: some relocations are 4 and
    some 8 bytes (pointers are 8, section offsets 4) in
    some dwarf environments. (MIPS relocations are all one
@@ -162,25 +450,39 @@
    to keep struct size down.
 */
 enum Dwarf_Rel_Type {
-		dwarf_drt_none, /* should not get to caller */
-                dwarf_drt_data_reloc, /* simple normal relocation */
-                dwarf_drt_segment_rel, /* special reloc, exceptions*/
-                dwarf_drt_first_of_length_pair,/* this and drt_second 
-				for .word end - begin
-			 	case */
-                dwarf_drt_second_of_length_pair
+        dwarf_drt_none,        /* Should not get to caller */
+        dwarf_drt_data_reloc,  /* Simple normal relocation. */
+        dwarf_drt_segment_rel, /* Special reloc, exceptions. */
+        /* dwarf_drt_first_of_length_pair  and drt_second 
+           are for for the  .word end - begin case. */
+        dwarf_drt_first_of_length_pair,
+        dwarf_drt_second_of_length_pair
 };
+
+typedef struct Dwarf_P_Marker_s * Dwarf_P_Marker;
+struct Dwarf_P_Marker_s {
+    Dwarf_Unsigned ma_marker;
+    Dwarf_Unsigned ma_offset;
+};
+
 typedef struct Dwarf_Relocation_Data_s  * Dwarf_Relocation_Data;
 struct Dwarf_Relocation_Data_s {
-        unsigned char drd_type; /* cast to/from Dwarf_Rel_Type
-					  to keep size small in struct */
-	unsigned char drd_length; /* length in bytes
-			         of data being relocated. 4 for 32bit.
-				 8 for 64bit data */
-        Dwarf_Unsigned       drd_offset; /* where the data to reloc is */
-        Dwarf_Unsigned       drd_symbol_index;
+    unsigned char drd_type;   /* Cast to/from Dwarf_Rel_Type
+                               to keep size small in struct. */
+    unsigned char drd_length; /* Length in bytes of data being 
+                               relocated. 4 for 32bit data,
+                               8 for 64bit data. */
+    Dwarf_Unsigned       drd_offset; /* Where the data to reloc is. */
+    Dwarf_Unsigned       drd_symbol_index;
 };
 
+typedef struct Dwarf_P_String_Attr_s  * Dwarf_P_String_Attr;
+struct Dwarf_P_String_Attr_s {
+    Dwarf_Unsigned        sa_offset;  /* Offset of string attribute data */
+    Dwarf_Unsigned        sa_nbytes;  
+};
+    
+
 /* Opaque types for Consumer Library. */
 typedef struct Dwarf_Debug_s*      Dwarf_Debug;
 typedef struct Dwarf_Die_s*        Dwarf_Die;
@@ -192,18 +494,18 @@
 typedef struct Dwarf_Weak_s*       Dwarf_Weak;
 typedef struct Dwarf_Error_s*      Dwarf_Error;
 typedef struct Dwarf_Attribute_s*  Dwarf_Attribute;
-typedef struct Dwarf_Abbrev_s*	   Dwarf_Abbrev;
-typedef struct Dwarf_Fde_s*  	   Dwarf_Fde;
-typedef struct Dwarf_Cie_s*  	   Dwarf_Cie;
-typedef struct Dwarf_Arange_s*	   Dwarf_Arange;
+typedef struct Dwarf_Abbrev_s*       Dwarf_Abbrev;
+typedef struct Dwarf_Fde_s*         Dwarf_Fde;
+typedef struct Dwarf_Cie_s*         Dwarf_Cie;
+typedef struct Dwarf_Arange_s*       Dwarf_Arange;
 
 /* Opaque types for Producer Library. */
-typedef struct Dwarf_P_Debug_s*	   	Dwarf_P_Debug;
-typedef struct Dwarf_P_Die_s*	   	Dwarf_P_Die;
-typedef struct Dwarf_P_Attribute_s*	Dwarf_P_Attribute;
-typedef struct Dwarf_P_Fde_s*		Dwarf_P_Fde;
-typedef struct Dwarf_P_Expr_s*		Dwarf_P_Expr;
-typedef Dwarf_Unsigned 		   	Dwarf_Tag;
+typedef struct Dwarf_P_Debug_s*           Dwarf_P_Debug;
+typedef struct Dwarf_P_Die_s*           Dwarf_P_Die;
+typedef struct Dwarf_P_Attribute_s*    Dwarf_P_Attribute;
+typedef struct Dwarf_P_Fde_s*        Dwarf_P_Fde;
+typedef struct Dwarf_P_Expr_s*        Dwarf_P_Expr;
+typedef Dwarf_Unsigned                Dwarf_Tag;
 
 
 /* error handler function
@@ -211,38 +513,242 @@
 typedef void  (*Dwarf_Handler)(Dwarf_Error /*error*/, Dwarf_Ptr /*errarg*/); 
 
 
+/* Begin libdwarf Object File Interface declarations.
+
+As of February 2008 there are multiple dwarf_reader object access
+initialization methods available:
+The traditional dwarf_elf_init() and dwarf_init()  and dwarf_finish() 
+    which assume libelf and POSIX file access. 
+An object-file and library agnostic dwarf_object_init() and dwarf_object_finish()
+    which allow the coder to provide object access routines
+    abstracting away the elf interface.  So there is no dependence in the
+    reader code on the object format and no dependence on libelf.
+    See the code in dwarf_elf_access.c  and dwarf_original_elf_init.c 
+    to see an example of initializing the structures mentioned below.
+
+Projects using dwarf_elf_init() or dwarf_init() can ignore
+the Dwarf_Obj_Access* structures entirely as all these details
+are completed for you.
+
+*/
+
+typedef struct Dwarf_Obj_Access_Interface_s   Dwarf_Obj_Access_Interface;
+typedef struct Dwarf_Obj_Access_Methods_s     Dwarf_Obj_Access_Methods;
+typedef struct Dwarf_Obj_Access_Section_s     Dwarf_Obj_Access_Section;
+
+
+/* Used in the get_section interface function
+   in Dwarf_Obj_Access_Section_s.  Since libdwarf
+   depends on standard DWARF section names an object
+   format that has no such names (but has some
+   method of setting up 'sections equivalents')
+   must arrange to return standard DWARF section
+   names in the 'name' field.  libdwarf does
+   not free the strings in 'name'. */
+struct Dwarf_Obj_Access_Section_s {
+    Dwarf_Addr     addr;
+    Dwarf_Unsigned size;
+    const char*    name;
+    /* Set link to zero if it is meaningless.  If non-zero
+       it should be a link to a rela section or from symtab
+       to strtab.  In Elf it is sh_link. */
+    Dwarf_Unsigned link;
+};
+
+/* Returned by the get_endianness function in 
+   Dwarf_Obj_Access_Methods_s. */
+typedef enum {
+    DW_OBJECT_MSB,
+    DW_OBJECT_LSB
+} Dwarf_Endianness;
+
+/* The functions we need to access object data from libdwarf are declared here.
+
+   In these function pointer declarations
+   'void *obj' is intended to be a pointer (the object field in  
+   Dwarf_Obj_Access_Interface_s)
+   that hides the library-specific and object-specific data that makes
+   it possible to handle multiple object formats and multiple libraries. 
+   It's not required that one handles multiple such in a single libdwarf
+   archive/shared-library (but not ruled out either).
+   See  dwarf_elf_object_access_internals_t and dwarf_elf_access.c
+   for an example. 
+
+*/
+struct Dwarf_Obj_Access_Methods_s {
+    /**
+     * get_section_info
+     *
+     * Get address, size, and name info about a section.
+     * 
+     * Parameters
+     * section_index - Zero-based index.
+     * return_section - Pointer to a structure in which section info 
+     *   will be placed.   Caller must provide a valid pointer to a
+     *   structure area.  The structure's contents will be overwritten
+     *   by the call to get_section_info.
+     * error - A pointer to an integer in which an error code may be stored.
+     *
+     * Return
+     * DW_DLV_OK - Everything ok.
+     * DW_DLV_ERROR - Error occurred. Use 'error' to determine the 
+     *    libdwarf defined error.
+     * DW_DLV_NO_ENTRY - No such section.
+     */
+    int    (*get_section_info)(void* obj, Dwarf_Half section_index, 
+        Dwarf_Obj_Access_Section* return_section, int* error);
+    /**
+     * get_byte_order
+     *
+     * Get whether the object file represented by this interface is big-endian 
+     * (DW_OBJECT_MSB) or little endian (DW_OBJECT_LSB).
+     *
+     * Parameters
+     * obj - Equivalent to 'this' in OO languages.
+     *
+     * Return
+     * Endianness of object. Cannot fail.
+     */
+    Dwarf_Endianness  (*get_byte_order)(void* obj);
+    /**
+     * get_length_size
+     *
+     * Get the size of a length field in the underlying object file. 
+     * libdwarf currently supports * 4 and 8 byte sizes, but may 
+     * support larger in the future.
+     * Perhaps the return type should be an enumeration?
+     *
+     * Parameters
+     * obj - Equivalent to 'this' in OO languages.
+     *
+     * Return
+     * Size of length. Cannot fail.
+     */
+    Dwarf_Small   (*get_length_size)(void* obj);
+    /**
+     * get_pointer_size
+     *
+     * Get the size of a pointer field in the underlying object file. 
+     * libdwarf currently supports  4 and 8 byte sizes.
+     * Perhaps the return type should be an enumeration?
+
+     * Return
+     * Size of pointer. Cannot fail.
+     */
+    Dwarf_Small   (*get_pointer_size)(void* obj);
+    /**
+     * get_section_count
+     *
+     * Get the number of sections in the object file.
+     *
+     * Parameters
+     *
+     * Return
+     * Number of sections
+     */
+    Dwarf_Unsigned  (*get_section_count)(void* obj);
+    /**
+     * load_section
+     *
+     * Get a pointer to an array of bytes that represent the section.
+     *
+     * Parameters
+     * section_index - Zero-based index.
+     * return_data - The address of a pointer to which the section data block 
+     *   will be assigned.
+     * error - Pointer to an integer for returning libdwarf-defined 
+     *   error numbers.
+     *
+     * Return
+     * DW_DLV_OK - No error.
+     * DW_DLV_ERROR - Error. Use 'error' to indicate a libdwarf-defined 
+     *    error number.
+     * DW_DLV_NO_ENTRY - No such section.
+     */
+    int    (*load_section)(void* obj, Dwarf_Half section_index, 
+        Dwarf_Small** return_data, int* error);
+
+   /**
+    * relocate_a_section
+    * If relocations are not supported leave this pointer NULL.
+    *
+    * Get a pointer to an array of bytes that represent the section.
+    *
+    * Parameters
+    * section_index - Zero-based index of the section to be relocated.
+    * error - Pointer to an integer for returning libdwarf-defined 
+    *   error numbers.
+    *
+    * Return
+    * DW_DLV_OK - No error.
+    * DW_DLV_ERROR - Error. Use 'error' to indicate a libdwarf-defined 
+    *    error number.
+    * DW_DLV_NO_ENTRY - No such section.
+    */
+    int    (*relocate_a_section)(void* obj, Dwarf_Half section_index,
+         Dwarf_Debug dbg,
+         int* error);
+
+};
+
+
+
+/* These structures are allocated and deallocated by your code
+   when you are using the libdwarf Object File Interface  
+   [dwarf_object_init() and dwarf_object_finish()] directly.
+   dwarf_object_finish() does not free
+   struct Dwarf_Obj_Access_Interface_s or its content. 
+   (libdwarf does record a pointer to this struct: you must
+   ensure that pointer remains valid for as long as
+   a libdwarf instance is open (meaning
+   after dwarf_init() and before dwarf_finish()).
+
+   If you are reading Elf objects and libelf use dwarf_init()
+   or dwarf_elf_init() which take care of these details.
+*/
+struct Dwarf_Obj_Access_Interface_s {
+    /* object is a void* as it hides the data the object access routines
+       need (which varies by library in use and object format). 
+    */
+    void* object;
+    const Dwarf_Obj_Access_Methods * methods;
+};
+  
+/* End libdwarf Object File Interface */
+
 /* 
     Dwarf_dealloc() alloc_type arguments.
     Argument points to:
 */
-#define DW_DLA_STRING      	0x01     /* char* */
-#define DW_DLA_LOC         	0x02     /* Dwarf_Loc */
-#define DW_DLA_LOCDESC     	0x03     /* Dwarf_Locdesc */
-#define DW_DLA_ELLIST      	0x04     /* Dwarf_Ellist (not used)*/
-#define DW_DLA_BOUNDS      	0x05     /* Dwarf_Bounds (not used) */
-#define DW_DLA_BLOCK       	0x06     /* Dwarf_Block */
-#define DW_DLA_DEBUG       	0x07     /* Dwarf_Debug */
-#define DW_DLA_DIE         	0x08     /* Dwarf_Die */
-#define DW_DLA_LINE        	0x09     /* Dwarf_Line */
-#define DW_DLA_ATTR        	0x0a     /* Dwarf_Attribute */
-#define DW_DLA_TYPE        	0x0b     /* Dwarf_Type  (not used) */
-#define DW_DLA_SUBSCR      	0x0c     /* Dwarf_Subscr (not used) */
-#define DW_DLA_GLOBAL      	0x0d     /* Dwarf_Global */
-#define DW_DLA_ERROR       	0x0e     /* Dwarf_Error */
-#define DW_DLA_LIST        	0x0f     /* a list */
-#define DW_DLA_LINEBUF     	0x10     /* Dwarf_Line* (not used) */
-#define DW_DLA_ARANGE      	0x11     /* Dwarf_Arange */
-#define DW_DLA_ABBREV		0x12 	 /* Dwarf_Abbrev */
-#define DW_DLA_FRAME_OP		0x13 	 /* Dwarf_Frame_Op */
-#define DW_DLA_CIE		0x14	 /* Dwarf_Cie */
-#define DW_DLA_FDE		0x15	 /* Dwarf_Fde */
-#define DW_DLA_LOC_BLOCK	0x16	 /* Dwarf_Loc Block (not used) */
-#define DW_DLA_FRAME_BLOCK	0x17	 /* Dwarf_Frame Block (not used) */
-#define DW_DLA_FUNC		0x18	 /* Dwarf_Func */
-#define DW_DLA_TYPENAME		0x19	 /* Dwarf_Type */
-#define DW_DLA_VAR		0x1a	 /* Dwarf_Var */
-#define DW_DLA_WEAK		0x1b	 /* Dwarf_Weak */
-#define DW_DLA_ADDR		0x1c	 /* Dwarf_Addr sized entries */
+#define DW_DLA_STRING          0x01     /* char* */
+#define DW_DLA_LOC             0x02     /* Dwarf_Loc */
+#define DW_DLA_LOCDESC         0x03     /* Dwarf_Locdesc */
+#define DW_DLA_ELLIST          0x04     /* Dwarf_Ellist (not used)*/
+#define DW_DLA_BOUNDS          0x05     /* Dwarf_Bounds (not used) */
+#define DW_DLA_BLOCK           0x06     /* Dwarf_Block */
+#define DW_DLA_DEBUG           0x07     /* Dwarf_Debug */
+#define DW_DLA_DIE             0x08     /* Dwarf_Die */
+#define DW_DLA_LINE            0x09     /* Dwarf_Line */
+#define DW_DLA_ATTR            0x0a     /* Dwarf_Attribute */
+#define DW_DLA_TYPE            0x0b     /* Dwarf_Type  (not used) */
+#define DW_DLA_SUBSCR          0x0c     /* Dwarf_Subscr (not used) */
+#define DW_DLA_GLOBAL          0x0d     /* Dwarf_Global */
+#define DW_DLA_ERROR           0x0e     /* Dwarf_Error */
+#define DW_DLA_LIST            0x0f     /* a list */
+#define DW_DLA_LINEBUF         0x10     /* Dwarf_Line* (not used) */
+#define DW_DLA_ARANGE          0x11     /* Dwarf_Arange */
+#define DW_DLA_ABBREV          0x12      /* Dwarf_Abbrev */
+#define DW_DLA_FRAME_OP        0x13      /* Dwarf_Frame_Op */
+#define DW_DLA_CIE             0x14     /* Dwarf_Cie */
+#define DW_DLA_FDE             0x15     /* Dwarf_Fde */
+#define DW_DLA_LOC_BLOCK       0x16     /* Dwarf_Loc Block (not used) */
+#define DW_DLA_FRAME_BLOCK     0x17     /* Dwarf_Frame Block (not used) */
+#define DW_DLA_FUNC            0x18     /* Dwarf_Func */
+#define DW_DLA_TYPENAME        0x19     /* Dwarf_Type */
+#define DW_DLA_VAR             0x1a     /* Dwarf_Var */
+#define DW_DLA_WEAK            0x1b     /* Dwarf_Weak */
+#define DW_DLA_ADDR            0x1c     /* Dwarf_Addr sized entries */
+#define DW_DLA_RANGES          0x1d     /* Dwarf_Ranges */
 
 /* The augmenter string for CIE */
 #define DW_CIE_AUGMENTER_STRING_V0              "z"
@@ -253,19 +759,41 @@
 #define DW_DLC_WRITE       1        /* write only access */
 #define DW_DLC_RDWR        2        /* read/write access NOT SUPPORTED*/
 
-/* dwarf_init() access flag modifiers
+/* pro_init() access flag modifiers
+   If HAVE_DWARF2_99_EXTENSION is defined at libdwarf build time
+   and DW_DLC_OFFSET_SIZE_64  is passed in pro_init() flags then the DWARF3 
+   64 bit offset extension is used to generate 64 bit offsets.
 */
-#define DW_DLC_SIZE_64     0x40000000 /* 32-bit target */
-#define DW_DLC_SIZE_32     0x20000000 /* 64-bit target */
-
-/* dwarf_init() access flag modifiers
+#define DW_DLC_SIZE_64     0x40000000 /* 32-bit address-size target */
+#define DW_DLC_SIZE_32     0x20000000 /* 64-bit address-size target */
+#define DW_DLC_OFFSET_SIZE_64 0x10000000 /* 64-bit offset-size DWARF */
+
+/* dwarf_pro_init() access flag modifiers
 */
 #define DW_DLC_ISA_MIPS             0x00000000 /* MIPS target */
 #define DW_DLC_ISA_IA64             0x01000000 /* IA64 target */
-#define DW_DLC_STREAM_RELOCATIONS   0x02000000 /* old style binary relocs */
-#define DW_DLC_SYMBOLIC_RELOCATIONS 0x04000000 /* usable with assem output */
-#define DW_DLC_TARGET_BIGENDIAN     0x08000000 /* big    endian target */
-#define DW_DLC_TARGET_LITTLEENDIAN  0x00100000 /* little endian target */
+#define DW_DLC_STREAM_RELOCATIONS   0x02000000 /* Old style binary relocs */
+
+    /* Usable with assembly output because it is up to the producer to
+       deal with locations in whatever manner the producer code wishes. 
+       Possibly emitting text an assembler will recognize. */
+#define DW_DLC_SYMBOLIC_RELOCATIONS 0x04000000 
+
+#define DW_DLC_TARGET_BIGENDIAN     0x08000000 /* Big    endian target */
+#define DW_DLC_TARGET_LITTLEENDIAN  0x00100000 /* Little endian target */
+
+#if 0
+  /*
+   The libdwarf producer interfaces jumble these two semantics together in
+   confusing ways.  We *should* have flags like these...
+   But changing the code means a lot of diffs.  So for now,
+   we leave things as they are 
+  */
+  #define DW_DLC_SUN_OFFSET32        0x00010000 /* use 32-bit sec offsets */
+  #define DW_DLC_SUN_OFFSET64        0x00020000 /* use 64-bit sec offsets */
+  #define DW_DLC_SUN_POINTER32        0x00040000 /* use 4 for address_size */
+  #define DW_DLC_SUN_POINTER64        0x00080000 /* use 8 for address_size */
+#endif
 
 /* dwarf_pcline() slide arguments
 */
@@ -298,7 +826,7 @@
 #define DW_DLE_EOS         20     /* end of section  */
 #define DW_DLE_ATRUNC      21     /* abbreviations section appears truncated*/
 #define DW_DLE_BADBITC     22     /* Address size passed to dwarf bad*/
-				    /* It is not an allowed size (64 or 32) */
+                    /* It is not an allowed size (64 or 32) */
     /* Error codes defined by the current Libdwarf Implementation. */
 #define DW_DLE_DBG_ALLOC                        23
 #define DW_DLE_FSTAT_ERROR                      24
@@ -334,161 +862,196 @@
 #define DW_DLE_DEBUG_LINE_LENGTH_BAD            54
 #define DW_DLE_LINE_PROLOG_LENGTH_BAD           55
 #define DW_DLE_LINE_NUM_OPERANDS_BAD            56
-#define DW_DLE_LINE_SET_ADDR_ERROR              57
+#define DW_DLE_LINE_SET_ADDR_ERROR              57 /* No longer used. */
 #define DW_DLE_LINE_EXT_OPCODE_BAD              58
 #define DW_DLE_DWARF_LINE_NULL                  59
 #define DW_DLE_INCL_DIR_NUM_BAD                 60
 #define DW_DLE_LINE_FILE_NUM_BAD                61
 #define DW_DLE_ALLOC_FAIL                       62
-#define DW_DLE_NO_CALLBACK_FUNC		    	63
-#define DW_DLE_SECT_ALLOC		    	64
-#define DW_DLE_FILE_ENTRY_ALLOC		    	65
-#define DW_DLE_LINE_ALLOC		    	66
-#define DW_DLE_FPGM_ALLOC		    	67
-#define DW_DLE_INCDIR_ALLOC		    	68
-#define DW_DLE_STRING_ALLOC		    	69
-#define DW_DLE_CHUNK_ALLOC		    	70
-#define DW_DLE_BYTEOFF_ERR		    	71
-#define	DW_DLE_CIE_ALLOC		    	72
-#define DW_DLE_FDE_ALLOC		    	73
-#define DW_DLE_REGNO_OVFL		    	74
-#define DW_DLE_CIE_OFFS_ALLOC		    	75
-#define DW_DLE_WRONG_ADDRESS		    	76
-#define DW_DLE_EXTRA_NEIGHBORS		    	77
-#define	DW_DLE_WRONG_TAG		    	78
-#define DW_DLE_DIE_ALLOC		    	79
-#define DW_DLE_PARENT_EXISTS		    	80
+#define DW_DLE_NO_CALLBACK_FUNC                 63
+#define DW_DLE_SECT_ALLOC                       64
+#define DW_DLE_FILE_ENTRY_ALLOC                 65
+#define DW_DLE_LINE_ALLOC                       66
+#define DW_DLE_FPGM_ALLOC                       67
+#define DW_DLE_INCDIR_ALLOC                     68
+#define DW_DLE_STRING_ALLOC                     69
+#define DW_DLE_CHUNK_ALLOC                      70
+#define DW_DLE_BYTEOFF_ERR                      71
+#define DW_DLE_CIE_ALLOC                        72
+#define DW_DLE_FDE_ALLOC                        73
+#define DW_DLE_REGNO_OVFL                       74
+#define DW_DLE_CIE_OFFS_ALLOC                   75
+#define DW_DLE_WRONG_ADDRESS                    76
+#define DW_DLE_EXTRA_NEIGHBORS                  77
+#define    DW_DLE_WRONG_TAG                     78
+#define DW_DLE_DIE_ALLOC                        79
+#define DW_DLE_PARENT_EXISTS                    80
 #define DW_DLE_DBG_NULL                         81
-#define DW_DLE_DEBUGLINE_ERROR		    	82
-#define DW_DLE_DEBUGFRAME_ERROR		    	83
-#define DW_DLE_DEBUGINFO_ERROR		    	84
-#define DW_DLE_ATTR_ALLOC		    	85
-#define DW_DLE_ABBREV_ALLOC		    	86
-#define DW_DLE_OFFSET_UFLW		    	87
-#define DW_DLE_ELF_SECT_ERR		    	88
-#define DW_DLE_DEBUG_FRAME_LENGTH_BAD	    	89
-#define DW_DLE_FRAME_VERSION_BAD	    	90
-#define DW_DLE_CIE_RET_ADDR_REG_ERROR	    	91
-#define DW_DLE_FDE_NULL			    	92
-#define DW_DLE_FDE_DBG_NULL		    	93
-#define DW_DLE_CIE_NULL			    	94
-#define DW_DLE_CIE_DBG_NULL		    	95
-#define DW_DLE_FRAME_TABLE_COL_BAD	    	96
-#define DW_DLE_PC_NOT_IN_FDE_RANGE	    	97
-#define DW_DLE_CIE_INSTR_EXEC_ERROR	    	98
-#define DW_DLE_FRAME_INSTR_EXEC_ERROR	    	99
-#define DW_DLE_FDE_PTR_NULL		    	100
-#define DW_DLE_RET_OP_LIST_NULL		    	101
-#define DW_DLE_LINE_CONTEXT_NULL	    	102
-#define DW_DLE_DBG_NO_CU_CONTEXT	    	103
-#define DW_DLE_DIE_NO_CU_CONTEXT	    	104
-#define DW_DLE_FIRST_DIE_NOT_CU		    	105
-#define DW_DLE_NEXT_DIE_PTR_NULL	    	106
-#define DW_DLE_DEBUG_FRAME_DUPLICATE	    	107
-#define DW_DLE_DEBUG_FRAME_NULL		    	108
-#define DW_DLE_ABBREV_DECODE_ERROR	    	109
-#define DW_DLE_DWARF_ABBREV_NULL		110
-#define DW_DLE_ATTR_NULL		    	111
-#define DW_DLE_DIE_BAD			    	112
-#define DW_DLE_DIE_ABBREV_BAD		    	113
-#define DW_DLE_ATTR_FORM_BAD		    	114
-#define DW_DLE_ATTR_NO_CU_CONTEXT	    	115
-#define DW_DLE_ATTR_FORM_SIZE_BAD	    	116
-#define DW_DLE_ATTR_DBG_NULL		    	117
-#define DW_DLE_BAD_REF_FORM		    	118
-#define DW_DLE_ATTR_FORM_OFFSET_BAD	    	119
-#define DW_DLE_LINE_OFFSET_BAD		    	120
-#define DW_DLE_DEBUG_STR_OFFSET_BAD	    	121
-#define DW_DLE_STRING_PTR_NULL		    	122
-#define DW_DLE_PUBNAMES_VERSION_ERROR	    	123
-#define DW_DLE_PUBNAMES_LENGTH_BAD	    	124
-#define DW_DLE_GLOBAL_NULL		    	125
-#define DW_DLE_GLOBAL_CONTEXT_NULL	    	126
-#define DW_DLE_DIR_INDEX_BAD		    	127
-#define DW_DLE_LOC_EXPR_BAD		    	128
-#define DW_DLE_DIE_LOC_EXPR_BAD		    	129
-#define DW_DLE_ADDR_ALLOC		    	130
-#define DW_DLE_OFFSET_BAD		    	131
-#define DW_DLE_MAKE_CU_CONTEXT_FAIL	    	132
-#define DW_DLE_REL_ALLOC		    	133
-#define DW_DLE_ARANGE_OFFSET_BAD	    	134
-#define DW_DLE_SEGMENT_SIZE_BAD		    	135
-#define DW_DLE_ARANGE_LENGTH_BAD	    	136
-#define DW_DLE_ARANGE_DECODE_ERROR	    	137
-#define DW_DLE_ARANGES_NULL		    	138
-#define DW_DLE_ARANGE_NULL		    	139
-#define DW_DLE_NO_FILE_NAME		    	140
-#define DW_DLE_NO_COMP_DIR		    	141
-#define DW_DLE_CU_ADDRESS_SIZE_BAD	    	142
-#define DW_DLE_INPUT_ATTR_BAD		    	143
-#define DW_DLE_EXPR_NULL		    	144
-#define DW_DLE_BAD_EXPR_OPCODE		    	145
-#define DW_DLE_EXPR_LENGTH_BAD		    	146
-#define DW_DLE_MULTIPLE_RELOC_IN_EXPR	    	147
-#define DW_DLE_ELF_GETIDENT_ERROR	    	148
-#define DW_DLE_NO_AT_MIPS_FDE		    	149
-#define DW_DLE_NO_CIE_FOR_FDE		    	150
-#define DW_DLE_DIE_ABBREV_LIST_NULL	    	151
-#define DW_DLE_DEBUG_FUNCNAMES_DUPLICATE    	152
-#define DW_DLE_DEBUG_FUNCNAMES_NULL	    	153
-#define DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR    154
-#define DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD       155
-#define DW_DLE_FUNC_NULL		    	156
-#define DW_DLE_FUNC_CONTEXT_NULL	    	157
-#define DW_DLE_DEBUG_TYPENAMES_DUPLICATE    	158
-#define DW_DLE_DEBUG_TYPENAMES_NULL	    	159
-#define DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR    160
-#define DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD       161
-#define DW_DLE_TYPE_NULL		    	162
-#define DW_DLE_TYPE_CONTEXT_NULL	    	163
-#define DW_DLE_DEBUG_VARNAMES_DUPLICATE	    	164
-#define DW_DLE_DEBUG_VARNAMES_NULL	    	165
-#define DW_DLE_DEBUG_VARNAMES_VERSION_ERROR     166
-#define DW_DLE_DEBUG_VARNAMES_LENGTH_BAD        167
-#define DW_DLE_VAR_NULL			    	168
-#define DW_DLE_VAR_CONTEXT_NULL		    	169
-#define DW_DLE_DEBUG_WEAKNAMES_DUPLICATE    	170
-#define DW_DLE_DEBUG_WEAKNAMES_NULL	    	171
-#define DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR    172
-#define DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD       173
-#define DW_DLE_WEAK_NULL		    	174
-#define DW_DLE_WEAK_CONTEXT_NULL	    	175
-#define DW_DLE_LOCDESC_COUNT_WRONG              176
-#define DW_DLE_MACINFO_STRING_NULL              177
-#define DW_DLE_MACINFO_STRING_EMPTY             178
-#define DW_DLE_MACINFO_INTERNAL_ERROR_SPACE     179
-#define DW_DLE_MACINFO_MALLOC_FAIL              180
-#define DW_DLE_DEBUGMACINFO_ERROR		181
-#define DW_DLE_DEBUG_MACRO_LENGTH_BAD		182
-#define DW_DLE_DEBUG_MACRO_MAX_BAD		183
-#define DW_DLE_DEBUG_MACRO_INTERNAL_ERR		184
-#define DW_DLE_DEBUG_MACRO_MALLOC_SPACE	        185
-#define DW_DLE_DEBUG_MACRO_INCONSISTENT	        186
-#define DW_DLE_DF_NO_CIE_AUGMENTATION          	187
-#define DW_DLE_DF_REG_NUM_TOO_HIGH  		188 
-#define DW_DLE_DF_MAKE_INSTR_NO_INIT          	189 
-#define DW_DLE_DF_NEW_LOC_LESS_OLD_LOC         	190
-#define DW_DLE_DF_POP_EMPTY_STACK              	191
-#define DW_DLE_DF_ALLOC_FAIL                   	192
-#define DW_DLE_DF_FRAME_DECODING_ERROR         	193
-#define DW_DLE_DEBUG_LOC_SECTION_SHORT         	194
+#define DW_DLE_DEBUGLINE_ERROR                  82
+#define DW_DLE_DEBUGFRAME_ERROR                 83
+#define DW_DLE_DEBUGINFO_ERROR                  84
+#define DW_DLE_ATTR_ALLOC                       85
+#define DW_DLE_ABBREV_ALLOC                     86
+#define DW_DLE_OFFSET_UFLW                      87
+#define DW_DLE_ELF_SECT_ERR                     88
+#define DW_DLE_DEBUG_FRAME_LENGTH_BAD           89
+#define DW_DLE_FRAME_VERSION_BAD                90
+#define DW_DLE_CIE_RET_ADDR_REG_ERROR           91
+#define DW_DLE_FDE_NULL                         92
+#define DW_DLE_FDE_DBG_NULL                     93
+#define DW_DLE_CIE_NULL                         94
+#define DW_DLE_CIE_DBG_NULL                     95
+#define DW_DLE_FRAME_TABLE_COL_BAD              96
+#define DW_DLE_PC_NOT_IN_FDE_RANGE              97
+#define DW_DLE_CIE_INSTR_EXEC_ERROR             98
+#define DW_DLE_FRAME_INSTR_EXEC_ERROR           99
+#define DW_DLE_FDE_PTR_NULL                    100
+#define DW_DLE_RET_OP_LIST_NULL                101
+#define DW_DLE_LINE_CONTEXT_NULL               102
+#define DW_DLE_DBG_NO_CU_CONTEXT               103
+#define DW_DLE_DIE_NO_CU_CONTEXT               104
+#define DW_DLE_FIRST_DIE_NOT_CU                105
+#define DW_DLE_NEXT_DIE_PTR_NULL               106
+#define DW_DLE_DEBUG_FRAME_DUPLICATE           107
+#define DW_DLE_DEBUG_FRAME_NULL                108
+#define DW_DLE_ABBREV_DECODE_ERROR             109
+#define DW_DLE_DWARF_ABBREV_NULL               110
+#define DW_DLE_ATTR_NULL                       111
+#define DW_DLE_DIE_BAD                         112
+#define DW_DLE_DIE_ABBREV_BAD                  113
+#define DW_DLE_ATTR_FORM_BAD                   114
+#define DW_DLE_ATTR_NO_CU_CONTEXT              115
+#define DW_DLE_ATTR_FORM_SIZE_BAD              116
+#define DW_DLE_ATTR_DBG_NULL                   117
+#define DW_DLE_BAD_REF_FORM                    118
+#define DW_DLE_ATTR_FORM_OFFSET_BAD            119
+#define DW_DLE_LINE_OFFSET_BAD                 120
+#define DW_DLE_DEBUG_STR_OFFSET_BAD            121
+#define DW_DLE_STRING_PTR_NULL                 122
+#define DW_DLE_PUBNAMES_VERSION_ERROR          123
+#define DW_DLE_PUBNAMES_LENGTH_BAD             124
+#define DW_DLE_GLOBAL_NULL                     125
+#define DW_DLE_GLOBAL_CONTEXT_NULL             126
+#define DW_DLE_DIR_INDEX_BAD                   127
+#define DW_DLE_LOC_EXPR_BAD                    128
+#define DW_DLE_DIE_LOC_EXPR_BAD                129
+#define DW_DLE_ADDR_ALLOC                      130
+#define DW_DLE_OFFSET_BAD                      131
+#define DW_DLE_MAKE_CU_CONTEXT_FAIL            132
+#define DW_DLE_REL_ALLOC                       133
+#define DW_DLE_ARANGE_OFFSET_BAD               134
+#define DW_DLE_SEGMENT_SIZE_BAD                135
+#define DW_DLE_ARANGE_LENGTH_BAD               136
+#define DW_DLE_ARANGE_DECODE_ERROR             137
+#define DW_DLE_ARANGES_NULL                    138
+#define DW_DLE_ARANGE_NULL                     139
+#define DW_DLE_NO_FILE_NAME                    140
+#define DW_DLE_NO_COMP_DIR                     141
+#define DW_DLE_CU_ADDRESS_SIZE_BAD             142
+#define DW_DLE_INPUT_ATTR_BAD                  143
+#define DW_DLE_EXPR_NULL                       144
+#define DW_DLE_BAD_EXPR_OPCODE                 145
+#define DW_DLE_EXPR_LENGTH_BAD                 146
+#define DW_DLE_MULTIPLE_RELOC_IN_EXPR          147
+#define DW_DLE_ELF_GETIDENT_ERROR              148
+#define DW_DLE_NO_AT_MIPS_FDE                  149
+#define DW_DLE_NO_CIE_FOR_FDE                  150
+#define DW_DLE_DIE_ABBREV_LIST_NULL            151
+#define DW_DLE_DEBUG_FUNCNAMES_DUPLICATE       152
+#define DW_DLE_DEBUG_FUNCNAMES_NULL            153
+#define DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR   154
+#define DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD      155
+#define DW_DLE_FUNC_NULL                       156
+#define DW_DLE_FUNC_CONTEXT_NULL               157
+#define DW_DLE_DEBUG_TYPENAMES_DUPLICATE       158
+#define DW_DLE_DEBUG_TYPENAMES_NULL            159
+#define DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR   160
+#define DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD      161
+#define DW_DLE_TYPE_NULL                       162
+#define DW_DLE_TYPE_CONTEXT_NULL               163
+#define DW_DLE_DEBUG_VARNAMES_DUPLICATE        164
+#define DW_DLE_DEBUG_VARNAMES_NULL             165
+#define DW_DLE_DEBUG_VARNAMES_VERSION_ERROR    166
+#define DW_DLE_DEBUG_VARNAMES_LENGTH_BAD       167
+#define DW_DLE_VAR_NULL                        168
+#define DW_DLE_VAR_CONTEXT_NULL                169
+#define DW_DLE_DEBUG_WEAKNAMES_DUPLICATE       170
+#define DW_DLE_DEBUG_WEAKNAMES_NULL            171
+#define DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR   172
+#define DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD      173
+#define DW_DLE_WEAK_NULL                       174
+#define DW_DLE_WEAK_CONTEXT_NULL               175
+#define DW_DLE_LOCDESC_COUNT_WRONG             176
+#define DW_DLE_MACINFO_STRING_NULL             177
+#define DW_DLE_MACINFO_STRING_EMPTY            178
+#define DW_DLE_MACINFO_INTERNAL_ERROR_SPACE    179
+#define DW_DLE_MACINFO_MALLOC_FAIL             180
+#define DW_DLE_DEBUGMACINFO_ERROR              181
+#define DW_DLE_DEBUG_MACRO_LENGTH_BAD          182
+#define DW_DLE_DEBUG_MACRO_MAX_BAD             183
+#define DW_DLE_DEBUG_MACRO_INTERNAL_ERR        184
+#define DW_DLE_DEBUG_MACRO_MALLOC_SPACE        185
+#define DW_DLE_DEBUG_MACRO_INCONSISTENT        186
+#define DW_DLE_DF_NO_CIE_AUGMENTATION          187
+#define DW_DLE_DF_REG_NUM_TOO_HIGH             188 
+#define DW_DLE_DF_MAKE_INSTR_NO_INIT           189 
+#define DW_DLE_DF_NEW_LOC_LESS_OLD_LOC         190
+#define DW_DLE_DF_POP_EMPTY_STACK              191
+#define DW_DLE_DF_ALLOC_FAIL                   192
+#define DW_DLE_DF_FRAME_DECODING_ERROR         193
+#define DW_DLE_DEBUG_LOC_SECTION_SHORT         194
+#define DW_DLE_FRAME_AUGMENTATION_UNKNOWN      195
+#define DW_DLE_PUBTYPE_CONTEXT                 196 /* Unused. */
+#define DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD       197
+#define DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR    198
+#define DW_DLE_DEBUG_PUBTYPES_DUPLICATE        199
+#define DW_DLE_FRAME_CIE_DECODE_ERROR          200
+#define DW_DLE_FRAME_REGISTER_UNREPRESENTABLE  201
+#define DW_DLE_FRAME_REGISTER_COUNT_MISMATCH   202
+#define DW_DLE_LINK_LOOP                       203
+#define DW_DLE_STRP_OFFSET_BAD                 204
+#define DW_DLE_DEBUG_RANGES_DUPLICATE          205
+#define DW_DLE_DEBUG_RANGES_OFFSET_BAD         206
+#define DW_DLE_DEBUG_RANGES_MISSING_END        207
+#define DW_DLE_DEBUG_RANGES_OUT_OF_MEM         208
+#define DW_DLE_DEBUG_SYMTAB_ERR                209
+#define DW_DLE_DEBUG_STRTAB_ERR                210
+#define DW_DLE_RELOC_MISMATCH_INDEX            211
+#define DW_DLE_RELOC_MISMATCH_RELOC_INDEX      212
+#define DW_DLE_RELOC_MISMATCH_STRTAB_INDEX     213
+#define DW_DLE_RELOC_SECTION_MISMATCH          214
+#define DW_DLE_RELOC_SECTION_MISSING_INDEX     215
+#define DW_DLE_RELOC_SECTION_LENGTH_ODD        216
+#define DW_DLE_RELOC_SECTION_PTR_NULL          217
+#define DW_DLE_RELOC_SECTION_MALLOC_FAIL       218
+#define DW_DLE_NO_ELF64_SUPPORT                219
+#define DW_DLE_MISSING_ELF64_SUPPORT           220
+#define DW_DLE_ORPHAN_FDE                      221
+#define DW_DLE_DUPLICATE_INST_BLOCK            222
+#define DW_DLE_BAD_REF_SIG8_FORM               223
+#define DW_DLE_ATTR_EXPRLOC_FORM_BAD           224
+#define DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD      225
+#define DW_DLE_NOT_REF_FORM                    226
+#define DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE 227
+
+
 
     /* DW_DLE_LAST MUST EQUAL LAST ERROR NUMBER */
-#define DW_DLE_LAST        			194
+#define DW_DLE_LAST        227
 #define DW_DLE_LO_USER     0x10000
 
-        /* taken as meaning 'undefined value', this is not
-           a column or register number.
-           Only present at libdwarf runtime. Never on disk.
-	   DW_FRAME_* Values present on disk are in dwarf.h
-        */
+   /* Taken as meaning 'undefined value', this is not
+      a column or register number.
+      Only present at libdwarf runtime. Never on disk.
+      DW_FRAME_* Values present on disk are in dwarf.h
+   */
 #define DW_FRAME_UNDEFINED_VAL          1034
 
-        /* taken as meaning 'same value' as caller had, not a column
-           or register number
-           Only present at libdwarf runtime. Never on disk.
-	   DW_FRAME_* Values present on disk are in dwarf.h
-        */
+   /* Taken as meaning 'same value' as caller had, not a column
+      or register number
+      Only present at libdwarf runtime. Never on disk.
+      DW_FRAME_* Values present on disk are in dwarf.h
+   */
 #define DW_FRAME_SAME_VAL               1035
 
 
@@ -496,13 +1059,13 @@
 /* error return values  
 */
 #define DW_DLV_BADADDR     (~(Dwarf_Addr)0)   
-	/* for functions returning target address */
+    /* for functions returning target address */
 
 #define DW_DLV_NOCOUNT     ((Dwarf_Signed)-1) 
-	/* for functions returning count */
+    /* for functions returning count */
 
 #define DW_DLV_BADOFFSET   (~(Dwarf_Off)0)    
-	/* for functions returning offset */
+    /* for functions returning offset */
 
 /* standard return values for functions */
 #define DW_DLV_NO_ENTRY -1
@@ -512,7 +1075,7 @@
 /* Special values for offset_into_exception_table field of dwarf fde's. */
 /* The following value indicates that there is no Exception table offset
    associated with a dwarf frame. */
-#define DW_DLX_NO_EH_OFFSET  	   (-1LL)
+#define DW_DLX_NO_EH_OFFSET         (-1LL)
 /* The following value indicates that the producer was unable to analyse the
    source file to generate Exception tables for this function. */
 #define DW_DLX_EH_OFFSET_UNAVAILABLE  (-2LL)
@@ -521,639 +1084,897 @@
 /*===========================================================================*/
 /*  Dwarf consumer interface initialization and termination operations */
 
-/* non-elf initialization */
-int dwarf_init(int 	/*fd*/, 
-    Dwarf_Unsigned 	/*access*/, 
-    Dwarf_Handler 	/*errhand*/, 
-    Dwarf_Ptr 		/*errarg*/, 
-    Dwarf_Debug      *  /*dbg*/,
-    Dwarf_Error* 	/*error*/);
-
-/* elf intialization */
+/* Initialization based on Unix open fd (using libelf internally). */
+int dwarf_init(int    /*fd*/, 
+    Dwarf_Unsigned    /*access*/, 
+    Dwarf_Handler     /*errhand*/, 
+    Dwarf_Ptr         /*errarg*/, 
+    Dwarf_Debug*      /*dbg*/,
+    Dwarf_Error*      /*error*/);
+
+/* Initialization based on libelf/sgi-fastlibelf open pointer. */
 int dwarf_elf_init(dwarf_elf_handle /*elf*/,
-    Dwarf_Unsigned 	/*access*/, 
-    Dwarf_Handler 	/*errhand*/, 
-    Dwarf_Ptr 		/*errarg*/, 
-    Dwarf_Debug      *  /*dbg*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Unsigned    /*access*/, 
+    Dwarf_Handler     /*errhand*/, 
+    Dwarf_Ptr         /*errarg*/, 
+    Dwarf_Debug*      /*dbg*/,
+    Dwarf_Error*      /*error*/);
 
 /* Undocumented function for memory allocator. */
 void dwarf_print_memory_stats(Dwarf_Debug  /*dbg*/);
 
-
 int dwarf_get_elf(Dwarf_Debug /*dbg*/,
-    dwarf_elf_handle*   /*return_elfptr*/,
-    Dwarf_Error*	/*error*/);
+    dwarf_elf_handle* /*return_elfptr*/,
+    Dwarf_Error*      /*error*/);
 
 int dwarf_finish(Dwarf_Debug /*dbg*/, Dwarf_Error* /*error*/);
 
+
+int dwarf_object_init(Dwarf_Obj_Access_Interface* /* obj */,
+    Dwarf_Handler /* errhand */,
+    Dwarf_Ptr     /* errarg */,
+    Dwarf_Debug*  /* dbg */,
+    Dwarf_Error*  /* error */);
+
+int dwarf_object_finish(Dwarf_Debug /* dbg */,
+    Dwarf_Error* /* error */);
+  
 /* die traversal operations */
+int dwarf_next_cu_header_b(Dwarf_Debug /*dbg*/, 
+    Dwarf_Unsigned* /*cu_header_length*/, 
+    Dwarf_Half*     /*version_stamp*/, 
+    Dwarf_Off*      /*abbrev_offset*/, 
+    Dwarf_Half*     /*address_size*/, 
+    Dwarf_Half*     /*length_size*/, 
+    Dwarf_Half*     /*extension_size*/, 
+    Dwarf_Unsigned* /*next_cu_header_offset*/,
+    Dwarf_Error*    /*error*/);
+/* The following is now obsolete, though supported. November 2009. */
 int dwarf_next_cu_header(Dwarf_Debug /*dbg*/, 
-    Dwarf_Unsigned* 	/*cu_header_length*/, 
-    Dwarf_Half*     	/*version_stamp*/, 
-    Dwarf_Off*  	/*abbrev_offset*/, 
-    Dwarf_Half* 	/*address_size*/, 
-    Dwarf_Unsigned*     /*next_cu_header_offset*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Unsigned* /*cu_header_length*/, 
+    Dwarf_Half*     /*version_stamp*/, 
+    Dwarf_Off*      /*abbrev_offset*/, 
+    Dwarf_Half*     /*address_size*/, 
+    Dwarf_Unsigned* /*next_cu_header_offset*/,
+    Dwarf_Error*    /*error*/);
 
 int dwarf_siblingof(Dwarf_Debug /*dbg*/, 
-    Dwarf_Die 		/*die*/, 
-    Dwarf_Die*          /*return_siblingdie*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Die        /*die*/, 
+    Dwarf_Die*       /*return_siblingdie*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_child(Dwarf_Die /*die*/, 
-    Dwarf_Die*          /*return_childdie*/,
-    Dwarf_Error* 	/*error*/);
-
-/* finding die given offset */
+    Dwarf_Die*       /*return_childdie*/,
+    Dwarf_Error*     /*error*/);
+
+/* Finding die given global (not CU-relative) offset */
 int dwarf_offdie(Dwarf_Debug /*dbg*/, 
-    Dwarf_Off 		/*offset*/, 
-    Dwarf_Die*          /*return_die*/,
-    Dwarf_Error* 	/*error*/);
-
-/* higher level functions (Unimplemented) */
+    Dwarf_Off        /*offset*/, 
+    Dwarf_Die*       /*return_die*/,
+    Dwarf_Error*     /*error*/);
+
+/* Higher level functions (Unimplemented) */
 int dwarf_pcfile(Dwarf_Debug /*dbg*/, 
-    Dwarf_Addr 		/*pc*/, 
-    Dwarf_Die*          /*return_die*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Addr       /*pc*/, 
+    Dwarf_Die*       /*return_die*/,
+    Dwarf_Error*     /*error*/);
 
 /* Unimplemented */
 int dwarf_pcsubr(Dwarf_Debug /*dbg*/, 
-    Dwarf_Addr 		/*pc*/, 
-    Dwarf_Die*          /*return_die*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Addr       /*pc*/, 
+    Dwarf_Die*       /*return_die*/,
+    Dwarf_Error*     /*error*/);
 
 /* Unimplemented */
 int dwarf_pcscope(Dwarf_Debug /*dbg*/, 
-    Dwarf_Addr 		/*pc*/, 
-    Dwarf_Die*          /*return_die*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Addr       /*pc*/, 
+    Dwarf_Die*       /*return_die*/,
+    Dwarf_Error*     /*error*/);
 
 /* operations on DIEs */
 int dwarf_tag(Dwarf_Die /*die*/, 
-    Dwarf_Half*	        /*return_tag*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Half*      /*return_tag*/,
+    Dwarf_Error*     /*error*/);
 
 /* utility? */
+/* dwarf_dieoffset returns the global debug_info
+   section offset, not the CU relative offset. */
 int dwarf_dieoffset(Dwarf_Die /*die*/, 
-    Dwarf_Off*          /*return_offset*/,
-    Dwarf_Error* 	/*error*/);
-
+    Dwarf_Off*       /*return_offset*/,
+    Dwarf_Error*     /*error*/);
+
+/* dwarf_CU_dieoffset_given_die returns
+   the global debug_info section offset of the CU die
+   that is the CU containing the given_die
+   (the passed in DIE can be any DIE). 
+   This information makes it possible for a consumer to
+   find and print CU context information for any die. 
+   See also dwarf_get_cu_die_offset_given_cu_header_offset(). */
+int dwarf_CU_dieoffset_given_die(Dwarf_Die /*given_die*/, 
+    Dwarf_Off*       /*return_offset*/,
+    Dwarf_Error*     /*error*/);
+
+/* dwarf_die_CU_offset returns the CU relative offset
+   not the global debug_info section offset, given
+   any DIE in the CU.  See also dwarf_CU_dieoffset_given_die().
+   */
 int dwarf_die_CU_offset(Dwarf_Die /*die*/,
-    Dwarf_Off*          /*return_offset*/,
-    Dwarf_Error*	/*error*/);
+    Dwarf_Off*       /*return_offset*/,
+    Dwarf_Error*     /*error*/);
+
+int dwarf_die_CU_offset_range(Dwarf_Die /*die*/,
+    Dwarf_Off*       /*return_CU_header_offset*/,
+    Dwarf_Off*       /*return_CU_length_bytes*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_attr (Dwarf_Die /*die*/, 
-    Dwarf_Half 		/*attr*/, 
-    Dwarf_Attribute *   /*returned_attr*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Half        /*attr*/, 
+    Dwarf_Attribute * /*returned_attr*/,
+    Dwarf_Error*      /*error*/);
 
 int dwarf_diename(Dwarf_Die /*die*/, 
-    char   **           /*diename*/,
-    Dwarf_Error* 	/*error*/);
+    char   **        /*diename*/,
+    Dwarf_Error*     /*error*/);
+
+/* Returns the  abbrev code of the die. Cannot fail. */
+int dwarf_die_abbrev_code(Dwarf_Die /*die */);
+
 
 /* convenience functions, alternative to using dwarf_attrlist() */
 int dwarf_hasattr(Dwarf_Die /*die*/, 
-    Dwarf_Half 		/*attr*/, 
-    Dwarf_Bool     *    /*returned_bool*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Half       /*attr*/, 
+    Dwarf_Bool *     /*returned_bool*/,
+    Dwarf_Error*     /*error*/);
 
 /* dwarf_loclist_n preferred over dwarf_loclist */
 int dwarf_loclist_n(Dwarf_Attribute /*attr*/,  
-    Dwarf_Locdesc***	/*llbuf*/, 
-    Dwarf_Signed *      /*locCount*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Locdesc*** /*llbuf*/, 
+    Dwarf_Signed *   /*locCount*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_loclist(Dwarf_Attribute /*attr*/,  /* inflexible! */
-    Dwarf_Locdesc** 	/*llbuf*/, 
-    Dwarf_Signed *      /*locCount*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Locdesc**  /*llbuf*/, 
+    Dwarf_Signed *   /*locCount*/,
+    Dwarf_Error*     /*error*/);
+
+/* Extracts a dwarf expression from an expression byte stream.
+   Useful to get expressions from DW_CFA_def_cfa_expression
+   DW_CFA_expression DW_CFA_val_expression expression bytes.
+   27 April 2009: dwarf_loclist_from_expr() interface with
+   no addr_size is obsolete but supported, 
+   use dwarf_loclist_from_expr_a() instead.  
+*/
+int dwarf_loclist_from_expr(Dwarf_Debug dbg,
+    Dwarf_Ptr expression_in,
+    Dwarf_Unsigned expression_length,
+    Dwarf_Locdesc ** llbuf,
+    Dwarf_Signed * listlen, Dwarf_Error * error);
+
+/* dwarf_loclist_from_expr_a() new 27 Apr 2009: added addr_size argument. */
+int dwarf_loclist_from_expr_a(Dwarf_Debug dbg,
+    Dwarf_Ptr expression_in,
+    Dwarf_Unsigned expression_length,
+    Dwarf_Half addr_size,
+    Dwarf_Locdesc ** llbuf,
+    Dwarf_Signed * listlen, Dwarf_Error * error);
 
 /* Unimplemented */
 int dwarf_stringlen(Dwarf_Die /*die*/, 
-    Dwarf_Locdesc **    /*returned_locdesc*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Locdesc ** /*returned_locdesc*/,
+    Dwarf_Error*     /*error*/);
 
 /* Unimplemented */
 int dwarf_subscrcnt(Dwarf_Die /*die*/, 
-    Dwarf_Signed *      /*returned_count*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Signed *   /*returned_count*/,
+    Dwarf_Error*     /*error*/);
 
 /* Unimplemented */
 int dwarf_nthsubscr(Dwarf_Die /*die*/, 
-    Dwarf_Unsigned 	/*ssndx*/, 
-    Dwarf_Die *         /*returned_die*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Unsigned   /*ssndx*/, 
+    Dwarf_Die *      /*returned_die*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_lowpc(Dwarf_Die /*die*/, 
-    Dwarf_Addr  *       /*returned_addr*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Addr  *    /*returned_addr*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_highpc(Dwarf_Die /*die*/, 
-    Dwarf_Addr  *       /*returned_addr*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Addr  *    /*returned_addr*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_bytesize(Dwarf_Die /*die*/, 
-    Dwarf_Unsigned *    /*returned_size*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Unsigned * /*returned_size*/,
+    Dwarf_Error*     /*error*/);
 
 /* Unimplemented */
 int dwarf_isbitfield(Dwarf_Die /*die*/, 
-    Dwarf_Bool  *       /*returned_bool*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Bool  *    /*returned_bool*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_bitsize(Dwarf_Die /*die*/, 
-    Dwarf_Unsigned *    /*returned_size*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Unsigned * /*returned_size*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_bitoffset(Dwarf_Die /*die*/, 
-    Dwarf_Unsigned *    /*returned_offset*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Unsigned * /*returned_offset*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_srclang(Dwarf_Die /*die*/, 
-    Dwarf_Unsigned *    /*returned_lang*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Unsigned * /*returned_lang*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_arrayorder(Dwarf_Die /*die*/, 
-    Dwarf_Unsigned *    /*returned_order*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Unsigned * /*returned_order*/,
+    Dwarf_Error*     /*error*/);
 
 /* end of convenience function list */
 
 /* this is the main interface to attributes of a DIE */
 int dwarf_attrlist(Dwarf_Die /*die*/, 
-    Dwarf_Attribute** 	/*attrbuf*/, 
-    Dwarf_Signed   *    /*attrcount*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Attribute** /*attrbuf*/, 
+    Dwarf_Signed   * /*attrcount*/,
+    Dwarf_Error*     /*error*/);
 
 /* query operations for attributes */
 int dwarf_hasform(Dwarf_Attribute /*attr*/, 
-    Dwarf_Half 		/*form*/, 
-    Dwarf_Bool *        /*returned_bool*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Half       /*form*/, 
+    Dwarf_Bool *     /*returned_bool*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_whatform(Dwarf_Attribute /*attr*/, 
-    Dwarf_Half *        /*returned_form*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Half *     /*returned_form*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_whatform_direct(Dwarf_Attribute /*attr*/, 
-    Dwarf_Half *        /*returned_form*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Half *     /*returned_form*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_whatattr(Dwarf_Attribute /*attr*/, 
-    Dwarf_Half *        /*returned_attr_num*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Half *     /*returned_attr_num*/,
+    Dwarf_Error*     /*error*/);
 
 /* 
     The following are concerned with the Primary Interface: getting
     the actual data values. One function per 'kind' of FORM.
 */
-	/*dwarf_formref returns, thru return_offset, a CU-relative offset
-	** and does not allow DW_FORM_ref_addr*/
+/*  dwarf_formref returns, thru return_offset, a CU-relative offset
+    and does not allow DW_FORM_ref_addr*/
 int dwarf_formref(Dwarf_Attribute /*attr*/, 
-    Dwarf_Off*          /*return_offset*/,
-    Dwarf_Error* 	/*error*/);
-	/*dwarf_global_formref returns, thru return_offset, 
-	 a debug_info-relative offset and does allow all reference forms*/
+    Dwarf_Off*       /*return_offset*/,
+    Dwarf_Error*     /*error*/);
+/*  dwarf_global_formref returns, thru return_offset, 
+    a debug_info-relative offset and does allow all reference forms*/
 int dwarf_global_formref(Dwarf_Attribute /*attr*/, 
-    Dwarf_Off*          /*return_offset*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Off*       /*return_offset*/,
+    Dwarf_Error*     /*error*/);
+
+/*  dwarf_formsig8 returns in the caller-provided 8 byte area
+    the 8 bytes of a DW_FORM_ref_sig8.  Not a string.  */
+int dwarf_formsig8(Dwarf_Attribute /*attr*/,
+    Dwarf_Sig8 * /*returned sig bytes*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_formaddr(Dwarf_Attribute /*attr*/, 
-    Dwarf_Addr   *      /*returned_addr*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Addr   *   /*returned_addr*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_formflag(Dwarf_Attribute /*attr*/,
-    Dwarf_Bool *        /*returned_bool*/,
-    Dwarf_Error*	/*error*/);
+    Dwarf_Bool *     /*returned_bool*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_formudata(Dwarf_Attribute /*attr*/, 
-    Dwarf_Unsigned  *   /*returned_val*/,
-    Dwarf_Error* 	/*error*/);
-
-int dwarf_formsdata(Dwarf_Attribute 	/*attr*/, 
-    Dwarf_Signed  *     /*returned_val*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Unsigned  * /*returned_val*/,
+    Dwarf_Error*     /*error*/);
+
+int dwarf_formsdata(Dwarf_Attribute     /*attr*/, 
+    Dwarf_Signed  *  /*returned_val*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_formblock(Dwarf_Attribute /*attr*/, 
-    Dwarf_Block    **   /*returned_block*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Block    ** /*returned_block*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_formstring(Dwarf_Attribute /*attr*/, 
-    char   **           /*returned_string*/,
-    Dwarf_Error* 	/*error*/);
+    char   **        /*returned_string*/,
+    Dwarf_Error*     /*error*/);
+
+int dwarf_formexprloc(Dwarf_Attribute /*attr*/,
+    Dwarf_Unsigned * /*return_exprlen*/,
+    Dwarf_Ptr  * /*block_ptr*/,
+    Dwarf_Error * /*error*/);
+
 
 /* end attribute query operations. */
 
 /* line number operations */
 /* dwarf_srclines  is the normal interface */
 int dwarf_srclines(Dwarf_Die /*die*/, 
-    Dwarf_Line** 	/*linebuf*/, 
-    Dwarf_Signed *      /*linecount*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Line**     /*linebuf*/, 
+    Dwarf_Signed *   /*linecount*/,
+    Dwarf_Error*     /*error*/);
+
+/* dwarf_srclines_dealloc, created July 2005, is the new
+   method for deallocating what dwarf_srclines returns.
+   More complete free than using dwarf_dealloc directly. */
+void dwarf_srclines_dealloc(Dwarf_Debug /*dbg*/, 
+    Dwarf_Line*       /*linebuf*/,
+    Dwarf_Signed      /*count */);
+
 
 int dwarf_srcfiles(Dwarf_Die /*die*/, 
-    char*** 		/*srcfiles*/, 
-    Dwarf_Signed *      /*filecount*/,
-    Dwarf_Error* 	/*error*/);
+    char***          /*srcfiles*/, 
+    Dwarf_Signed *   /*filecount*/,
+    Dwarf_Error*     /*error*/);
 
 /* Unimplemented. */
 int dwarf_dieline(Dwarf_Die /*die*/, 
-    Dwarf_Line  *       /*returned_line*/,
-    Dwarf_Error *       /*error*/);
+    Dwarf_Line  *    /*returned_line*/,
+    Dwarf_Error *    /*error*/);
 
 int dwarf_linebeginstatement(Dwarf_Line /*line*/, 
-    Dwarf_Bool  *       /*returned_bool*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Bool  *    /*returned_bool*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_lineendsequence(Dwarf_Line /*line*/,
-    Dwarf_Bool  *       /*returned_bool*/,
-    Dwarf_Error*        /*error*/);
+    Dwarf_Bool  *    /*returned_bool*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_lineno(Dwarf_Line /*line*/, 
-    Dwarf_Unsigned *    /*returned_lineno*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Unsigned * /*returned_lineno*/,
+    Dwarf_Error*     /*error*/);
+
+int dwarf_line_srcfileno(Dwarf_Line /*line*/,
+    Dwarf_Unsigned * /*ret_fileno*/, 
+    Dwarf_Error *    /*error*/);
 
 int dwarf_lineaddr(Dwarf_Line /*line*/, 
-    Dwarf_Addr *        /*returned_addr*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Addr *     /*returned_addr*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_lineoff(Dwarf_Line /*line*/, 
-    Dwarf_Signed  *     /*returned_lineoffset*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Signed  *  /*returned_lineoffset*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_linesrc(Dwarf_Line /*line*/, 
-    char   **           /*returned_name*/,
-    Dwarf_Error* 	/*error*/);
+    char   **        /*returned_name*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_lineblock(Dwarf_Line /*line*/, 
-    Dwarf_Bool  *       /*returned_bool*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Bool  *    /*returned_bool*/,
+    Dwarf_Error*     /*error*/);
 
 /* tertiary interface to line info */
 /* Unimplemented */
 int dwarf_pclines(Dwarf_Debug /*dbg*/, 
-    Dwarf_Addr 		/*pc*/, 
-    Dwarf_Line** 	/*linebuf*/, 
-    Dwarf_Signed *      /*linecount*/,
-    Dwarf_Signed 	/*slide*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Addr       /*pc*/, 
+    Dwarf_Line**     /*linebuf*/, 
+    Dwarf_Signed *   /*linecount*/,
+    Dwarf_Signed     /*slide*/, 
+    Dwarf_Error*     /*error*/);
 /* end line number operations */
 
 /* global name space operations (.debug_pubnames access) */
 int dwarf_get_globals(Dwarf_Debug /*dbg*/, 
-    Dwarf_Global** 	/*globals*/, 
-    Dwarf_Signed *      /*number_of_globals*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Global**   /*globals*/, 
+    Dwarf_Signed *   /*number_of_globals*/,
+    Dwarf_Error*     /*error*/);
+void dwarf_globals_dealloc(Dwarf_Debug /*dbg*/,
+    Dwarf_Global*    /*globals*/,
+    Dwarf_Signed     /*number_of_globals*/);
 
 int dwarf_globname(Dwarf_Global /*glob*/, 
-    char   **           /*returned_name*/,
-    Dwarf_Error* 	/*error*/);
+    char   **        /*returned_name*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_global_die_offset(Dwarf_Global /*global*/, 
-    Dwarf_Off*          /*return_offset*/,
-    Dwarf_Error * 	/*error*/);
-
+    Dwarf_Off*       /*return_offset*/,
+    Dwarf_Error *    /*error*/);
+
+/* This returns the CU die global offset if one knows the
+   CU header global offset.
+   See also dwarf_CU_dieoffset_given_die(). */ 
 int dwarf_get_cu_die_offset_given_cu_header_offset(
-	Dwarf_Debug     /*dbg*/,
-	Dwarf_Off       /*in_cu_header_offset*/,
-        Dwarf_Off *     /*out_cu_die_offset*/, 
-	Dwarf_Error *   /*err*/);
+    Dwarf_Debug      /*dbg*/,
+    Dwarf_Off        /*in_cu_header_offset*/,
+    Dwarf_Off *  /*out_cu_die_offset*/, 
+    Dwarf_Error *    /*err*/);
 #ifdef __sgi /* pragma is sgi MIPS only */
 #pragma optional dwarf_get_cu_die_offset_given_cu_header_offset
 #endif
 
 int dwarf_global_cu_offset(Dwarf_Global /*global*/, 
-    Dwarf_Off*          /*return_offset*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Off*       /*return_offset*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_global_name_offsets(Dwarf_Global /*global*/, 
-    char   **           /*returned_name*/,
-    Dwarf_Off* 		/*die_offset*/, 
-    Dwarf_Off* 		/*cu_offset*/, 
-    Dwarf_Error* 	/*error*/);
+    char   **        /*returned_name*/,
+    Dwarf_Off*       /*die_offset*/, 
+    Dwarf_Off*       /*cu_offset*/, 
+    Dwarf_Error*     /*error*/);
 
 /* Static function name operations.  */
-int dwarf_get_funcs(Dwarf_Debug	/*dbg*/,
-    Dwarf_Func**	/*funcs*/,
-    Dwarf_Signed *      /*number_of_funcs*/,
-    Dwarf_Error*	/*error*/);
+int dwarf_get_funcs(Dwarf_Debug    /*dbg*/,
+    Dwarf_Func**     /*funcs*/,
+    Dwarf_Signed *   /*number_of_funcs*/,
+    Dwarf_Error*     /*error*/);
+void dwarf_funcs_dealloc(Dwarf_Debug /*dbg*/,
+    Dwarf_Func*      /*funcs*/,
+    Dwarf_Signed     /*number_of_funcs*/);
 
 int dwarf_funcname(Dwarf_Func /*func*/,
-    char   **           /*returned_name*/,
-    Dwarf_Error*	/*error*/);
+    char   **        /*returned_name*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_func_die_offset(Dwarf_Func /*func*/,
-    Dwarf_Off*          /*return_offset*/,
-    Dwarf_Error*	/*error*/);
+    Dwarf_Off*       /*return_offset*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_func_cu_offset(Dwarf_Func /*func*/,
-    Dwarf_Off*          /*return_offset*/,
-    Dwarf_Error*	/*error*/);
+    Dwarf_Off*       /*return_offset*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_func_name_offsets(Dwarf_Func /*func*/,
-    char   **           /*returned_name*/,
-    Dwarf_Off*		/*die_offset*/,
-    Dwarf_Off*		/*cu_offset*/,
-    Dwarf_Error*	/*error*/);
-
-/* User-defined type name operations.  */
-int dwarf_get_types(Dwarf_Debug	/*dbg*/,
-    Dwarf_Type**	/*types*/,
-    Dwarf_Signed *      /*number_of_types*/,
-    Dwarf_Error*	/*error*/);
+    char   **        /*returned_name*/,
+    Dwarf_Off*       /*die_offset*/,
+    Dwarf_Off*       /*cu_offset*/,
+    Dwarf_Error*     /*error*/);
+
+/* User-defined type name operations, SGI IRIX .debug_typenames section.
+   Same content as DWARF3 .debug_pubtypes, but defined years before
+   .debug_pubtypes was defined.   SGI IRIX only. */
+int dwarf_get_types(Dwarf_Debug    /*dbg*/,
+    Dwarf_Type**     /*types*/,
+    Dwarf_Signed *   /*number_of_types*/,
+    Dwarf_Error*     /*error*/);
+void dwarf_types_dealloc(Dwarf_Debug /*dbg*/,
+    Dwarf_Type*      /*types*/,
+    Dwarf_Signed     /*number_of_types*/);
+
 
 int dwarf_typename(Dwarf_Type /*type*/,
-    char   **           /*returned_name*/,
-    Dwarf_Error*	/*error*/);
+    char   **        /*returned_name*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_type_die_offset(Dwarf_Type /*type*/,
-    Dwarf_Off*          /*return_offset*/,
-    Dwarf_Error*	/*error*/);
+    Dwarf_Off*       /*return_offset*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_type_cu_offset(Dwarf_Type /*type*/,
-    Dwarf_Off*          /*return_offset*/,
-    Dwarf_Error*	/*error*/);
-
-int dwarf_type_name_offsets(Dwarf_Type	/*type*/,
-    char   **           /*returned_name*/,
-    Dwarf_Off*		/*die_offset*/,
-    Dwarf_Off*		/*cu_offset*/,
-    Dwarf_Error*	/*error*/);
+    Dwarf_Off*       /*return_offset*/,
+    Dwarf_Error*     /*error*/);
+
+int dwarf_type_name_offsets(Dwarf_Type    /*type*/,
+    char   **        /*returned_name*/,
+    Dwarf_Off*       /*die_offset*/,
+    Dwarf_Off*       /*cu_offset*/,
+    Dwarf_Error*     /*error*/);
+
+/* User-defined type name operations, DWARF3  .debug_pubtypes section. 
+*/
+int dwarf_get_pubtypes(Dwarf_Debug    /*dbg*/,
+    Dwarf_Type**     /*types*/,
+    Dwarf_Signed *   /*number_of_types*/,
+    Dwarf_Error*     /*error*/);
+void dwarf_pubtypes_dealloc(Dwarf_Debug /*dbg*/,
+    Dwarf_Type*      /*pubtypes*/,
+    Dwarf_Signed     /*number_of_pubtypes*/);
+
+
+int dwarf_pubtypename(Dwarf_Type /*type*/,
+    char   **        /*returned_name*/,
+    Dwarf_Error*     /*error*/);
+
+int dwarf_pubtype_die_offset(Dwarf_Type /*type*/,
+    Dwarf_Off*       /*return_offset*/,
+    Dwarf_Error*     /*error*/);
+
+int dwarf_pubtype_cu_offset(Dwarf_Type /*type*/,
+    Dwarf_Off*       /*return_offset*/,
+    Dwarf_Error*     /*error*/);
+
+int dwarf_pubtype_name_offsets(Dwarf_Type    /*type*/,
+    char   **        /*returned_name*/,
+    Dwarf_Off*       /*die_offset*/,
+    Dwarf_Off*       /*cu_offset*/,
+    Dwarf_Error*     /*error*/);
 
 /* File-scope static variable name operations.  */
-int dwarf_get_vars(Dwarf_Debug	/*dbg*/,
-    Dwarf_Var**		/*vars*/,
-    Dwarf_Signed *      /*number_of_vars*/,
-    Dwarf_Error*	/*error*/);
+int dwarf_get_vars(Dwarf_Debug    /*dbg*/,
+    Dwarf_Var**      /*vars*/,
+    Dwarf_Signed *   /*number_of_vars*/,
+    Dwarf_Error*     /*error*/);
+void dwarf_vars_dealloc(Dwarf_Debug /*dbg*/,
+    Dwarf_Var*       /*vars*/,
+    Dwarf_Signed     /*number_of_vars*/);
+
 
 int dwarf_varname(Dwarf_Var /*var*/,
-    char   **           /*returned_name*/,
-    Dwarf_Error*	/*error*/);
+    char   **        /*returned_name*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_var_die_offset(Dwarf_Var /*var*/,
-    Dwarf_Off*          /*return_offset*/,
-    Dwarf_Error*	/*error*/);
+    Dwarf_Off*       /*return_offset*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_var_cu_offset(Dwarf_Var /*var*/,
-    Dwarf_Off*          /*return_offset*/,
-    Dwarf_Error*	/*error*/);
+    Dwarf_Off*       /*return_offset*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_var_name_offsets(Dwarf_Var /*var*/,
-    char   **           /*returned_name*/,
-    Dwarf_Off*		/*die_offset*/,
-    Dwarf_Off*		/*cu_offset*/,
-    Dwarf_Error*	/*error*/);
+    char   **        /*returned_name*/,
+    Dwarf_Off*       /*die_offset*/,
+    Dwarf_Off*       /*cu_offset*/,
+    Dwarf_Error*     /*error*/);
 
 /* weak name operations.  */
-int dwarf_get_weaks(Dwarf_Debug	/*dbg*/,
-    Dwarf_Weak**	/*weaks*/,
-    Dwarf_Signed *      /*number_of_weaks*/,
-    Dwarf_Error*	/*error*/);
+int dwarf_get_weaks(Dwarf_Debug    /*dbg*/,
+    Dwarf_Weak**     /*weaks*/,
+    Dwarf_Signed *   /*number_of_weaks*/,
+    Dwarf_Error*     /*error*/);
+void dwarf_weaks_dealloc(Dwarf_Debug /*dbg*/,
+    Dwarf_Weak*      /*weaks*/,
+    Dwarf_Signed     /*number_of_weaks*/);
+
 
 int dwarf_weakname(Dwarf_Weak /*weak*/,
-    char   **           /*returned_name*/,
-    Dwarf_Error*	/*error*/);
+    char   **        /*returned_name*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_weak_die_offset(Dwarf_Weak /*weak*/,
-    Dwarf_Off*          /*return_offset*/,
-    Dwarf_Error*	/*error*/);
+    Dwarf_Off*       /*return_offset*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_weak_cu_offset(Dwarf_Weak /*weak*/,
-    Dwarf_Off*          /*return_offset*/,
-    Dwarf_Error*	/*error*/);
-
-int dwarf_weak_name_offsets(Dwarf_Weak	/*weak*/,
-    char   **           /*returned_name*/,
-    Dwarf_Off*		/*die_offset*/,
-    Dwarf_Off*		/*cu_offset*/,
-    Dwarf_Error*	/*error*/);
+    Dwarf_Off*       /*return_offset*/,
+    Dwarf_Error*     /*error*/);
+
+int dwarf_weak_name_offsets(Dwarf_Weak    /*weak*/,
+    char   **        /*returned_name*/,
+    Dwarf_Off*       /*die_offset*/,
+    Dwarf_Off*       /*cu_offset*/,
+    Dwarf_Error*     /*error*/);
 
 /* location list section operation.  (.debug_loc access) */
-/* Unimplemented. */
 int dwarf_get_loclist_entry(Dwarf_Debug /*dbg*/, 
-    Dwarf_Unsigned 	/*offset*/, 
-    Dwarf_Addr* 	/*hipc*/, 
-    Dwarf_Addr* 	/*lopc*/, 
-    Dwarf_Ptr* 		/*data*/, 
-    Dwarf_Unsigned* 	/*entry_len*/, 
-    Dwarf_Unsigned* 	/*next_entry*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Unsigned   /*offset*/, 
+    Dwarf_Addr*      /*hipc*/, 
+    Dwarf_Addr*      /*lopc*/, 
+    Dwarf_Ptr*       /*data*/, 
+    Dwarf_Unsigned*  /*entry_len*/, 
+    Dwarf_Unsigned*  /*next_entry*/, 
+    Dwarf_Error*     /*error*/);
 
 /* abbreviation section operations */
 int dwarf_get_abbrev(Dwarf_Debug /*dbg*/, 
-    Dwarf_Unsigned 	/*offset*/, 
-    Dwarf_Abbrev  *     /*returned_abbrev*/,
-    Dwarf_Unsigned* 	/*length*/, 
-    Dwarf_Unsigned* 	/*attr_count*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Unsigned   /*offset*/, 
+    Dwarf_Abbrev  *  /*returned_abbrev*/,
+    Dwarf_Unsigned*  /*length*/, 
+    Dwarf_Unsigned*  /*attr_count*/, 
+    Dwarf_Error*     /*error*/);
 
 int dwarf_get_abbrev_tag(Dwarf_Abbrev /*abbrev*/, 
-    Dwarf_Half*        /*return_tag_number*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Half*      /*return_tag_number*/,
+    Dwarf_Error*     /*error*/);
 int dwarf_get_abbrev_code(Dwarf_Abbrev /*abbrev*/, 
-    Dwarf_Unsigned*        /*return_code_number*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Unsigned*  /*return_code_number*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_get_abbrev_children_flag(Dwarf_Abbrev /*abbrev*/, 
-    Dwarf_Signed*        /*return_flag*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Signed*    /*return_flag*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_get_abbrev_entry(Dwarf_Abbrev /*abbrev*/, 
-    Dwarf_Signed  	/*index*/, 
-    Dwarf_Half  *       /*returned_attr_num*/,
-    Dwarf_Signed* 	/*form*/, 
-    Dwarf_Off*    	/*offset*/, 
-    Dwarf_Error*  	/*error*/);
+    Dwarf_Signed     /*index*/, 
+    Dwarf_Half  *    /*returned_attr_num*/,
+    Dwarf_Signed*    /*form*/, 
+    Dwarf_Off*       /*offset*/, 
+    Dwarf_Error*     /*error*/);
 
 /* consumer string section operation */
 int dwarf_get_str(Dwarf_Debug /*dbg*/, 
-    Dwarf_Off    	/*offset*/, 
-    char** 		/*string*/, 
-    Dwarf_Signed *      /*strlen_of_string*/,
-    Dwarf_Error*  	/*error*/);
+    Dwarf_Off        /*offset*/, 
+    char**           /*string*/, 
+    Dwarf_Signed *   /*strlen_of_string*/,
+    Dwarf_Error*     /*error*/);
 
 /* Consumer op on  gnu .eh_frame info */
 int dwarf_get_fde_list_eh(
-    Dwarf_Debug        /*dbg*/,
-    Dwarf_Cie       ** /*cie_data*/,
-    Dwarf_Signed    *  /*cie_element_count*/,
-    Dwarf_Fde       ** /*fde_data*/,
-    Dwarf_Signed    *  /*fde_element_count*/,
-    Dwarf_Error     *  /*error*/);
+    Dwarf_Debug      /*dbg*/,
+    Dwarf_Cie**      /*cie_data*/,
+    Dwarf_Signed*    /*cie_element_count*/,
+    Dwarf_Fde**      /*fde_data*/,
+    Dwarf_Signed*    /*fde_element_count*/,
+    Dwarf_Error*     /*error*/);
 
 
 /* consumer operations on frame info: .debug_frame */
 int dwarf_get_fde_list(Dwarf_Debug /*dbg*/, 
-    Dwarf_Cie**   	/*cie_data*/, 
-    Dwarf_Signed* 	/*cie_element_count*/, 
-    Dwarf_Fde**   	/*fde_data*/, 
-    Dwarf_Signed* 	/*fde_element_count*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Cie**      /*cie_data*/, 
+    Dwarf_Signed*    /*cie_element_count*/, 
+    Dwarf_Fde**      /*fde_data*/, 
+    Dwarf_Signed*    /*fde_element_count*/, 
+    Dwarf_Error*     /*error*/);
+
+/* Release storage gotten by dwarf_get_fde_list_eh() or
+   dwarf_get_fde_list() */
+void dwarf_fde_cie_list_dealloc(Dwarf_Debug dbg,
+    Dwarf_Cie *cie_data,
+    Dwarf_Signed cie_element_count,
+    Dwarf_Fde *fde_data,
+    Dwarf_Signed fde_element_count);
+
 
 
 int dwarf_get_fde_range(Dwarf_Fde /*fde*/, 
-    Dwarf_Addr* 	/*low_pc*/, 
-    Dwarf_Unsigned* 	/*func_length*/, 
-    Dwarf_Ptr*    	/*fde_bytes*/, 
-    Dwarf_Unsigned* 	/*fde_byte_length*/, 
-    Dwarf_Off*    	/*cie_offset*/, 
-    Dwarf_Signed*  	/*cie_index*/, 
-    Dwarf_Off*   	/*fde_offset*/, 
-    Dwarf_Error* 	/*error*/);
-
+    Dwarf_Addr*      /*low_pc*/, 
+    Dwarf_Unsigned*  /*func_length*/, 
+    Dwarf_Ptr*       /*fde_bytes*/, 
+    Dwarf_Unsigned*  /*fde_byte_length*/, 
+    Dwarf_Off*       /*cie_offset*/, 
+    Dwarf_Signed*    /*cie_index*/, 
+    Dwarf_Off*       /*fde_offset*/, 
+    Dwarf_Error*     /*error*/);
+
+/*  Useful for IRIX only:  see dwarf_get_cie_augmentation_data()
+       dwarf_get_fde_augmentation_data() for GNU .eh_frame. */
 int dwarf_get_fde_exception_info(Dwarf_Fde /*fde*/,
-    Dwarf_Signed*	/* offset_into_exception_tables */,
-    Dwarf_Error*        /*error*/);
+    Dwarf_Signed*    /* offset_into_exception_tables */,
+    Dwarf_Error*     /*error*/);
+
 
 int dwarf_get_cie_of_fde(Dwarf_Fde /*fde*/,
-    Dwarf_Cie *         /*cie_returned*/,
-    Dwarf_Error*        /*error*/);
+    Dwarf_Cie *      /*cie_returned*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_get_cie_info(Dwarf_Cie /*cie*/, 
-    Dwarf_Unsigned *    /*bytes_in_cie*/,
-    Dwarf_Small*    	/*version*/, 
-    char        **      /*augmenter*/,
-    Dwarf_Unsigned* 	/*code_alignment_factor*/, 
-    Dwarf_Signed* 	/*data_alignment_factor*/, 
-    Dwarf_Half*     	/*return_address_register_rule*/, 
-    Dwarf_Ptr*     	/*initial_instructions*/, 
-    Dwarf_Unsigned*  	/*initial_instructions_length*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Unsigned * /*bytes_in_cie*/,
+    Dwarf_Small*     /*version*/, 
+    char        **   /*augmenter*/,
+    Dwarf_Unsigned*  /*code_alignment_factor*/, 
+    Dwarf_Signed*    /*data_alignment_factor*/, 
+    Dwarf_Half*      /*return_address_register_rule*/, 
+    Dwarf_Ptr*       /*initial_instructions*/, 
+    Dwarf_Unsigned*  /*initial_instructions_length*/, 
+    Dwarf_Error*     /*error*/);
+
+/* dwarf_get_cie_index new September 2009. */
+int dwarf_get_cie_index(
+    Dwarf_Cie /*cie*/,
+    Dwarf_Signed* /*index*/, 
+    Dwarf_Error* /*error*/ );
+
 
 int dwarf_get_fde_instr_bytes(Dwarf_Fde /*fde*/, 
-    Dwarf_Ptr * /*outinstrs*/, Dwarf_Unsigned * /*outlen*/, 
-    Dwarf_Error * /*error*/);
+    Dwarf_Ptr *      /*outinstrs*/, Dwarf_Unsigned * /*outlen*/, 
+    Dwarf_Error *    /*error*/);
 
 int dwarf_get_fde_info_for_all_regs(Dwarf_Fde /*fde*/, 
-    Dwarf_Addr          /*pc_requested*/,
-    Dwarf_Regtable*     /*reg_table*/,
-    Dwarf_Addr*         /*row_pc*/,
-    Dwarf_Error*        /*error*/);
-
+    Dwarf_Addr       /*pc_requested*/,
+    Dwarf_Regtable*  /*reg_table*/,
+    Dwarf_Addr*      /*row_pc*/,
+    Dwarf_Error*     /*error*/);
+
+int dwarf_get_fde_info_for_all_regs3(Dwarf_Fde /*fde*/, 
+    Dwarf_Addr       /*pc_requested*/,
+    Dwarf_Regtable3* /*reg_table*/,
+    Dwarf_Addr*      /*row_pc*/,
+    Dwarf_Error*     /*error*/);
+
+/* In this older interface DW_FRAME_CFA_COL is a meaningful
+    column (which does not work well with DWARF3 or
+    non-MIPS architectures). */
 int dwarf_get_fde_info_for_reg(Dwarf_Fde /*fde*/, 
-    Dwarf_Half    	/*table_column*/, 
-    Dwarf_Addr    	/*pc_requested*/, 
-    Dwarf_Signed*       /*offset_relevant*/,
-    Dwarf_Signed* 	/*register*/,  
-    Dwarf_Signed* 	/*offset*/, 
-    Dwarf_Addr* 	/*row_pc*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Half       /*table_column*/, 
+    Dwarf_Addr       /*pc_requested*/, 
+    Dwarf_Signed*    /*offset_relevant*/,
+    Dwarf_Signed*    /*register*/,  
+    Dwarf_Signed*    /*offset*/, 
+    Dwarf_Addr*      /*row_pc*/, 
+    Dwarf_Error*     /*error*/);
+
+/* See discussion of dw_value_type, libdwarf.h. 
+   Use of DW_FRAME_CFA_COL is not meaningful in this interface.
+   See dwarf_get_fde_info_for_cfa_reg3().
+*/
+/* dwarf_get_fde_info_for_reg3 is useful on a single column, but
+   it is inefficient to iterate across all table_columns using this
+   function.  Instead call dwarf_get_fde_info_for_all_regs3() and index
+   into the table it fills in. */
+int dwarf_get_fde_info_for_reg3(Dwarf_Fde /*fde*/, 
+    Dwarf_Half       /*table_column*/, 
+    Dwarf_Addr       /*pc_requested*/, 
+    Dwarf_Small  *   /*value_type*/, 
+    Dwarf_Signed *   /*offset_relevant*/,
+    Dwarf_Signed*    /*register*/,  
+    Dwarf_Signed*    /*offset_or_block_len*/, 
+    Dwarf_Ptr   *    /*block_ptr */,
+    Dwarf_Addr*      /*row_pc_out*/, 
+    Dwarf_Error*     /*error*/);
+
+/* Use this to get the cfa. */
+int dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde /*fde*/, 
+    Dwarf_Addr       /*pc_requested*/, 
+    Dwarf_Small  *   /*value_type*/, 
+    Dwarf_Signed *   /*offset_relevant*/,
+    Dwarf_Signed*    /*register*/,  
+    Dwarf_Signed*    /*offset_or_block_len*/, 
+    Dwarf_Ptr   *    /*block_ptr */,
+    Dwarf_Addr*      /*row_pc_out*/, 
+    Dwarf_Error*     /*error*/);
 
 int dwarf_get_fde_for_die(Dwarf_Debug /*dbg*/, 
-    Dwarf_Die 		/*subr_die */, 
-    Dwarf_Fde  *        /*returned_fde*/,
-    Dwarf_Error*	/*error*/);
+    Dwarf_Die        /*subr_die */, 
+    Dwarf_Fde  *     /*returned_fde*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_get_fde_n(Dwarf_Fde* /*fde_data*/, 
-    Dwarf_Unsigned 	/*fde_index*/, 
-    Dwarf_Fde  *        /*returned_fde*/,
-    Dwarf_Error*  	/*error*/);
+    Dwarf_Unsigned   /*fde_index*/, 
+    Dwarf_Fde  *     /*returned_fde*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_get_fde_at_pc(Dwarf_Fde* /*fde_data*/, 
-    Dwarf_Addr 		/*pc_of_interest*/, 
-    Dwarf_Fde  *        /*returned_fde*/,
-    Dwarf_Addr* 	/*lopc*/, 
-    Dwarf_Addr* 	/*hipc*/, 
-    Dwarf_Error* 	/*error*/);
-
-int dwarf_expand_frame_instructions(Dwarf_Debug /*dbg*/, 
-    Dwarf_Ptr 		/*instruction*/, 
-    Dwarf_Unsigned  	/*i_length*/, 
-    Dwarf_Frame_Op** 	/*returned_op_list*/, 
-    Dwarf_Signed*       /*op_count*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Addr       /*pc_of_interest*/, 
+    Dwarf_Fde  *     /*returned_fde*/,
+    Dwarf_Addr*      /*lopc*/, 
+    Dwarf_Addr*      /*hipc*/, 
+    Dwarf_Error*     /*error*/);
+
+/* GNU .eh_frame augmentation information, raw form, see
+   Linux Standard Base Core Specification version 3.0 . */
+int dwarf_get_cie_augmentation_data(Dwarf_Cie /* cie*/,
+    Dwarf_Small **   /* augdata */,
+    Dwarf_Unsigned * /* augdata_len */,
+    Dwarf_Error*     /*error*/);
+/* GNU .eh_frame augmentation information, raw form, see
+   Linux Standard Base Core Specification version 3.0 . */
+int dwarf_get_fde_augmentation_data(Dwarf_Fde /* fde*/,
+    Dwarf_Small **   /* augdata */,
+    Dwarf_Unsigned * /* augdata_len */,
+    Dwarf_Error*     /*error*/);
+
+int dwarf_expand_frame_instructions(Dwarf_Cie /*cie*/, 
+    Dwarf_Ptr        /*instruction*/, 
+    Dwarf_Unsigned   /*i_length*/, 
+    Dwarf_Frame_Op** /*returned_op_list*/, 
+    Dwarf_Signed*    /*op_count*/,
+    Dwarf_Error*     /*error*/);
 
 /* Operations on .debug_aranges. */
 int dwarf_get_aranges(Dwarf_Debug /*dbg*/, 
-    Dwarf_Arange** 	/*aranges*/, 
-    Dwarf_Signed *      /*arange_count*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Arange**   /*aranges*/, 
+    Dwarf_Signed *   /*arange_count*/,
+    Dwarf_Error*     /*error*/);
 
 
 
 int dwarf_get_arange(
-    Dwarf_Arange* 	/*aranges*/, 
-    Dwarf_Unsigned 	/*arange_count*/, 
-    Dwarf_Addr 		/*address*/, 
-    Dwarf_Arange *      /*returned_arange*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Arange*    /*aranges*/, 
+    Dwarf_Unsigned   /*arange_count*/, 
+    Dwarf_Addr       /*address*/, 
+    Dwarf_Arange *   /*returned_arange*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_get_cu_die_offset(
-    Dwarf_Arange 	/*arange*/, 
-    Dwarf_Off*          /*return_offset*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Arange     /*arange*/, 
+    Dwarf_Off*       /*return_offset*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_get_arange_cu_header_offset(
-    Dwarf_Arange 	/*arange*/, 
-    Dwarf_Off*          /*return_cu_header_offset*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Arange     /*arange*/, 
+    Dwarf_Off*       /*return_cu_header_offset*/,
+    Dwarf_Error*     /*error*/);
 #ifdef __sgi /* pragma is sgi MIPS only */
 #pragma optional dwarf_get_arange_cu_header_offset
 #endif
 
+/* DWARF2,3 interface. No longer really adequate (it was never
+   right for segmented address spaces, please switch
+   to using dwarf_get_arange_info_b instead.  
+   There is no effective difference between these
+   functions  if the address space
+   of the target is not segmented.  */
 int dwarf_get_arange_info(
-    Dwarf_Arange 	/*arange*/, 
-    Dwarf_Addr* 	/*start*/, 
-    Dwarf_Unsigned* 	/*length*/, 
-    Dwarf_Off* 		/*cu_die_offset*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Arange     /*arange*/, 
+    Dwarf_Addr*      /*start*/, 
+    Dwarf_Unsigned*  /*length*/, 
+    Dwarf_Off*       /*cu_die_offset*/, 
+    Dwarf_Error*     /*error*/ );
+
+/* New for DWARF4, entries may have segment information. 
+   *segment is only meaningful if *segment_entry_size is non-zero. */
+int dwarf_get_arange_info_b(
+    Dwarf_Arange     /*arange*/, 
+    Dwarf_Unsigned*  /*segment*/, 
+    Dwarf_Unsigned*  /*segment_entry_size*/, 
+    Dwarf_Addr    *  /*start*/, 
+    Dwarf_Unsigned*  /*length*/, 
+    Dwarf_Off     *  /*cu_die_offset*/, 
+    Dwarf_Error   *  /*error*/ );
 
 
 /* consumer .debug_macinfo information interface.
 */
 struct Dwarf_Macro_Details_s {
-  Dwarf_Off    dmd_offset; /* offset, in the section,
+    Dwarf_Off    dmd_offset; /* offset, in the section,
                               of this macro info */
-  Dwarf_Small  dmd_type;   /* the type, DW_MACINFO_define etc*/
-  Dwarf_Signed dmd_lineno; /* the source line number where
+    Dwarf_Small  dmd_type;   /* the type, DW_MACINFO_define etc*/
+    Dwarf_Signed dmd_lineno; /* the source line number where
                               applicable and vend_def # if
                               vendor_extension op
-                           */
-
-  Dwarf_Signed dmd_fileindex;/* the source file index:
+                             */
+
+    Dwarf_Signed dmd_fileindex;/* the source file index:
                               applies to define undef start_file
+                               */
+    char *       dmd_macro;  /* macro name (with value for defineop)
+                              string from vendor ext
                              */
-  char *       dmd_macro;  /* macro name (with value for defineop)
-                              string from vendor ext
-                           */
 };
 
-/* _dwarf_print_lines is for use by dwarfdump: it prints
+/* dwarf_print_lines is for use by dwarfdump: it prints
    line info to stdout.
+   The _dwarf name is obsolete. Use dwarf_ instead.
+   Added extra argnument 2/2009 for better checking.
 */
-int _dwarf_print_lines(Dwarf_Die cu_die,Dwarf_Error * /*error*/);
-
-/* _dwarf_ld_sort_lines is for use solely by ld for
-   rearranging lines in .debug_line in a .o created with a text
+int _dwarf_print_lines(Dwarf_Die /*cu_die*/,Dwarf_Error * /*error*/);
+int dwarf_print_lines(Dwarf_Die /*cu_die*/,Dwarf_Error * /*error*/,
+   int * /*error_count_out */);
+
+/* dwarf_check_lineheader lets dwarfdump get detailed messages
+   about some compiler errors we detect.
+   We return the count of detected errors throught the
+   pointer.
+*/
+void dwarf_check_lineheader(Dwarf_Die /*cu_die*/,int *errcount_out);
+
+/* dwarf_ld_sort_lines helps SGI IRIX ld 
+   rearrange lines in .debug_line in a .o created with a text
    section per function.  
-		-OPT:procedure_reorder=ON
+        -OPT:procedure_reorder=ON
    where ld-cord (cord(1)ing by ld, 
    not by cord(1)) may have changed the function order.
+   The _dwarf name is obsolete. Use dwarf_ instead.
 */
 int _dwarf_ld_sort_lines(
-        void * orig_buffer,
-        unsigned long   buffer_len,
-        int is_64_bit,
-        int *any_change,
-        int * err_code);
-
-/* Used by dwarfdump -v to print offsets, for debugging
-   dwarf info
+    void *         /*orig_buffer*/,
+    unsigned long  /* buffer_len*/,
+    int            /*is_64_bit*/,
+    int *          /*any_change*/,
+    int *          /*err_code*/);
+int dwarf_ld_sort_lines(
+    void *         /*orig_buffer*/,
+    unsigned long  /*buffer_len*/,
+    int            /*is_64_bit*/,
+    int *          /*any_change*/,
+    int *          /*err_code*/);
+
+/* Used by dwarfdump -v to print fde offsets from debugging
+   info.
+   The _dwarf name is obsolete. Use dwarf_ instead.
 */
-int _dwarf_fde_section_offset(Dwarf_Debug dbg,Dwarf_Fde in_fde,
-        Dwarf_Off *fde_off, Dwarf_Off *cie_off,
-        Dwarf_Error *err);
-
-/* Used by dwarfdump -v to print offsets, for debugging
-   dwarf info
+int _dwarf_fde_section_offset(Dwarf_Debug dbg,
+    Dwarf_Fde         /*in_fde*/,
+    Dwarf_Off *       /*fde_off*/, 
+    Dwarf_Off *       /*cie_off*/,
+    Dwarf_Error *     /*err*/);
+int dwarf_fde_section_offset(Dwarf_Debug dbg,
+    Dwarf_Fde         /*in_fde*/,
+    Dwarf_Off *       /*fde_off*/, 
+    Dwarf_Off *       /*cie_off*/,
+    Dwarf_Error *     /*err*/);
+
+/* Used by dwarfdump -v to print cie offsets from debugging
+   info.
+   The _dwarf name is obsolete. Use dwarf_ instead.
 */
-int _dwarf_cie_section_offset(Dwarf_Debug dbg,Dwarf_Cie in_cie,
-        Dwarf_Off *cie_off,
-        Dwarf_Error *err);
-
-
-
+int dwarf_cie_section_offset(Dwarf_Debug /*dbg*/,
+    Dwarf_Cie     /*in_cie*/,
+    Dwarf_Off *   /*cie_off */,
+    Dwarf_Error * /*err*/);
+int _dwarf_cie_section_offset(Dwarf_Debug /*dbg*/,
+    Dwarf_Cie     /*in_cie*/,
+    Dwarf_Off *   /*cie_off*/,
+    Dwarf_Error * /*err*/);
 
 typedef struct Dwarf_Macro_Details_s Dwarf_Macro_Details;
 
@@ -1172,21 +1993,54 @@
 char *dwarf_find_macro_value_start(char * /*macro_string*/);
 
 int dwarf_get_macro_details(Dwarf_Debug /*dbg*/,
-    Dwarf_Off              /*macro_offset*/,
-    Dwarf_Unsigned	   /*maximum_count*/,
+    Dwarf_Off            /*macro_offset*/,
+    Dwarf_Unsigned       /*maximum_count*/,
     Dwarf_Signed         * /*entry_count*/,
     Dwarf_Macro_Details ** /*details*/,
-    Dwarf_Error *          /*err*/);
+    Dwarf_Error *        /*err*/);
 
 
 int dwarf_get_address_size(Dwarf_Debug /*dbg*/,
-        Dwarf_Half  * /*addr_size*/,
-        Dwarf_Error * /*error*/);
+    Dwarf_Half  *    /*addr_size*/,
+    Dwarf_Error *    /*error*/);
+int dwarf_get_die_address_size(Dwarf_Die /*die*/,
+    Dwarf_Half  *    /*addr_size*/,
+    Dwarf_Error *    /*error*/);
+
+/* The dwarf specification separates FORMs into
+different classes.  To do the seperation properly
+requires 4 pieces of data as of DWARF4 (thus the
+function arguments listed here). 
+The DWARF4 specification class definition suffices to
+describe all DWARF versions.
+See section 7.5.4, Attribute Encodings.
+A return of DW_FORM_CLASS_UNKNOWN means we could not properly figure
+out what form-class it is.
+
+    DW_FORM_CLASS_FRAMEPTR is MIPS/IRIX only, and refers
+    to the DW_AT_MIPS_fde attribute (a reference to the
+    .debug_frame section).
+*/
+enum Dwarf_Form_Class {
+    DW_FORM_CLASS_UNKNOWN,   DW_FORM_CLASS_ADDRESS,
+    DW_FORM_CLASS_BLOCK,     DW_FORM_CLASS_CONSTANT, 
+    DW_FORM_CLASS_EXPRLOC,   DW_FORM_CLASS_FLAG, 
+    DW_FORM_CLASS_LINEPTR,   DW_FORM_CLASS_LOCLISTPTR, 
+    DW_FORM_CLASS_MACPTR,    DW_FORM_CLASS_RANGELISTPTR, 
+    DW_FORM_CLASS_REFERENCE, DW_FORM_CLASS_STRING,
+    DW_FORM_CLASS_FRAMEPTR
+};
+
+enum Dwarf_Form_Class dwarf_get_form_class(
+    Dwarf_Half /* dwversion */,
+    Dwarf_Half /* attrnum */, 
+    Dwarf_Half /*offset_size */, 
+    Dwarf_Half /*form*/);
 
 /* utility operations */
-Dwarf_Unsigned dwarf_errno(Dwarf_Error 	/*error*/);
-
-char* dwarf_errmsg(Dwarf_Error	/*error*/);
+Dwarf_Unsigned dwarf_errno(Dwarf_Error     /*error*/);
+
+char* dwarf_errmsg(Dwarf_Error    /*error*/);
 
 /* stringcheck zero is default and means do all
 ** string length validity checks.
@@ -1199,6 +2053,23 @@
 */
 int dwarf_set_stringcheck(int /*stringcheck*/);
 
+/* 'apply' defaults to 1 and means do all
+ * 'rela' relocations on reading in a dwarf object section with
+ * such relocations.
+ * Call with parameter value 0 to turn off application of 
+ * such relocations.
+ * Since the static linker leaves 'bogus' data in object sections
+ * with a 'rela' relocation section such data cannot be read
+ * sensibly without processing the relocations.  Such relocations
+ * do not exist in executables and shared objects (.so), the
+ * relocations only exist in plain .o relocatable object files.
+ * Actual value saved and returned is only 8 bits! Upper bits
+ * ignored by libdwarf (and zero on return).
+ * Returns previous value.
+ * */
+int dwarf_set_reloc_application(int /*apply*/);
+
+
 /* Unimplemented */
 Dwarf_Handler dwarf_seterrhand(Dwarf_Debug /*dbg*/, Dwarf_Handler /*errhand*/);
 
@@ -1211,31 +2082,31 @@
 /* DWARF Producer Interface */
 
 typedef int (*Dwarf_Callback_Func)(
-    char* /*name*/, 
-    int 		/*size*/, 
-    Dwarf_Unsigned 	/*type*/,
-    Dwarf_Unsigned 	/*flags*/, 
-    Dwarf_Unsigned 	/*link*/, 
-    Dwarf_Unsigned 	/*info*/, 
-    int* 		/*sect name index*/, 
-    int* 		/*error*/);
+    char*           /*name*/, 
+    int             /*size*/, 
+    Dwarf_Unsigned  /*type*/,
+    Dwarf_Unsigned  /*flags*/, 
+    Dwarf_Unsigned  /*link*/, 
+    Dwarf_Unsigned  /*info*/, 
+    int*            /*sect name index*/, 
+    int*            /*error*/);
 
 Dwarf_P_Debug dwarf_producer_init(
-    Dwarf_Unsigned      /*creation_flags*/, 
-    Dwarf_Callback_Func	/*func*/,
-    Dwarf_Handler 	/*errhand*/, 
-    Dwarf_Ptr 		/*errarg*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Unsigned  /*creation_flags*/, 
+    Dwarf_Callback_Func    /*func*/,
+    Dwarf_Handler   /*errhand*/, 
+    Dwarf_Ptr       /*errarg*/, 
+    Dwarf_Error*    /*error*/);
 
 typedef int (*Dwarf_Callback_Func_b)(
-    char* 		/*name*/,
-    int                 /*size*/,
-    Dwarf_Unsigned      /*type*/,
-    Dwarf_Unsigned      /*flags*/,
-    Dwarf_Unsigned      /*link*/,
-    Dwarf_Unsigned      /*info*/,
-    Dwarf_Unsigned*     /*sect_name_index*/,
-    int*                /*error*/);
+    char*           /*name*/,
+    int             /*size*/,
+    Dwarf_Unsigned  /*type*/,
+    Dwarf_Unsigned  /*flags*/,
+    Dwarf_Unsigned  /*link*/,
+    Dwarf_Unsigned  /*info*/,
+    Dwarf_Unsigned* /*sect_name_index*/,
+    int*            /*error*/);
 
 
 Dwarf_P_Debug dwarf_producer_init_b(
@@ -1247,32 +2118,52 @@
 
 
 Dwarf_Signed dwarf_transform_to_disk_form(Dwarf_P_Debug /*dbg*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Error*     /*error*/);
 
 Dwarf_Ptr dwarf_get_section_bytes(Dwarf_P_Debug /*dbg*/, 
-    Dwarf_Signed 	/*dwarf_section*/,
-    Dwarf_Signed* 	/*elf_section_index*/, 
-    Dwarf_Unsigned* 	/*length*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Signed     /*dwarf_section*/,
+    Dwarf_Signed*    /*elf_section_index*/, 
+    Dwarf_Unsigned*  /*length*/, 
+    Dwarf_Error*     /*error*/);
 
 int  dwarf_get_relocation_info_count(
-        Dwarf_P_Debug    /*dbg*/,
-        Dwarf_Unsigned * /*count_of_relocation_sections*/,
-	int *            /*drd_buffer_version*/,
-        Dwarf_Error*     /*error*/);
+    Dwarf_P_Debug    /*dbg*/,
+    Dwarf_Unsigned * /*count_of_relocation_sections*/,
+    int *                /*drd_buffer_version*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_get_relocation_info(
-        Dwarf_P_Debug           /*dbg*/,
-        Dwarf_Signed          * /*elf_section_index*/,
-        Dwarf_Signed          * /*elf_section_index_link*/,
-        Dwarf_Unsigned        * /*relocation_buffer_count*/,
-        Dwarf_Relocation_Data * /*reldata_buffer*/,
-        Dwarf_Error*            /*error*/);
+    Dwarf_P_Debug           /*dbg*/,
+    Dwarf_Signed          * /*elf_section_index*/,
+    Dwarf_Signed          * /*elf_section_index_link*/,
+    Dwarf_Unsigned        * /*relocation_buffer_count*/,
+    Dwarf_Relocation_Data * /*reldata_buffer*/,
+    Dwarf_Error*            /*error*/);
 
 /* v1:  no drd_length field, enum explicit */
 /* v2:  has the drd_length field, enum value in uchar member */
 #define DWARF_DRD_BUFFER_VERSION 2
 
+/* Markers are not written  to DWARF2/3/4, they are user
+   defined and may be used for any purpose.
+*/
+Dwarf_Signed dwarf_get_die_markers(
+    Dwarf_P_Debug     /*dbg*/,
+    Dwarf_P_Marker *  /*marker_list*/,
+    Dwarf_Unsigned *  /*marker_count*/,
+    Dwarf_Error *     /*error*/);
+
+int dwarf_get_string_attributes_count(Dwarf_P_Debug,
+    Dwarf_Unsigned *,
+    int *,
+    Dwarf_Error *);
+
+int dwarf_get_string_attributes_info(Dwarf_P_Debug, 
+    Dwarf_Signed *,
+    Dwarf_Unsigned *,
+    Dwarf_P_String_Attr *,
+    Dwarf_Error *);
+
 void dwarf_reset_section_bytes(Dwarf_P_Debug /*dbg*/);
 
 Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug /*dbg*/, 
@@ -1280,323 +2171,566 @@
 
 /* Producer attribute addition functions. */
 Dwarf_P_Attribute dwarf_add_AT_targ_address(Dwarf_P_Debug /*dbg*/, 
-    Dwarf_P_Die 	/*ownerdie*/, 
-    Dwarf_Half 		/*attr*/, 
-    Dwarf_Unsigned 	/*pc_value*/, 
-    Dwarf_Signed 	/*sym_index*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_P_Die     /*ownerdie*/, 
+    Dwarf_Half      /*attr*/, 
+    Dwarf_Unsigned  /*pc_value*/, 
+    Dwarf_Signed    /*sym_index*/, 
+    Dwarf_Error*    /*error*/);
+
+Dwarf_P_Attribute dwarf_add_AT_block(Dwarf_P_Debug /*dbg*/, 
+    Dwarf_P_Die     /*ownerdie*/, 
+    Dwarf_Half      /*attr*/, 
+    Dwarf_Small*    /*block_data*/,
+    Dwarf_Unsigned  /*block_len*/,
+    Dwarf_Error*    /*error*/);
 
 Dwarf_P_Attribute dwarf_add_AT_targ_address_b(Dwarf_P_Debug /*dbg*/, 
-    Dwarf_P_Die 	/*ownerdie*/, 
-    Dwarf_Half 		/*attr*/, 
-    Dwarf_Unsigned 	/*pc_value*/, 
-    Dwarf_Unsigned 	/*sym_index*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_P_Die     /*ownerdie*/, 
+    Dwarf_Half      /*attr*/, 
+    Dwarf_Unsigned  /*pc_value*/, 
+    Dwarf_Unsigned  /*sym_index*/, 
+    Dwarf_Error*    /*error*/);
+
+Dwarf_P_Attribute dwarf_add_AT_ref_address(Dwarf_P_Debug /*dbg*/, 
+    Dwarf_P_Die     /*ownerdie*/, 
+    Dwarf_Half      /*attr*/, 
+    Dwarf_Unsigned  /*pc_value*/, 
+    Dwarf_Unsigned  /*sym_index*/, 
+    Dwarf_Error*    /*error*/);
 
 Dwarf_P_Attribute dwarf_add_AT_unsigned_const(Dwarf_P_Debug /*dbg*/, 
-    Dwarf_P_Die 	/*ownerdie*/, 
-    Dwarf_Half 		/*attr*/, 
-    Dwarf_Unsigned 	/*value*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_P_Die     /*ownerdie*/, 
+    Dwarf_Half      /*attr*/, 
+    Dwarf_Unsigned  /*value*/, 
+    Dwarf_Error*    /*error*/);
 
 Dwarf_P_Attribute dwarf_add_AT_signed_const(Dwarf_P_Debug /*dbg*/, 
-    Dwarf_P_Die 	/*ownerdie*/, 
-    Dwarf_Half 		/*attr*/, 
-    Dwarf_Signed 	/*value*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_P_Die     /*ownerdie*/, 
+    Dwarf_Half      /*attr*/, 
+    Dwarf_Signed    /*value*/, 
+    Dwarf_Error*    /*error*/);
 
 Dwarf_P_Attribute dwarf_add_AT_reference(Dwarf_P_Debug /*dbg*/, 
-    Dwarf_P_Die 	/*ownerdie*/, 
-    Dwarf_Half 		/*attr*/, 
-    Dwarf_P_Die 	/*otherdie*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_P_Die     /*ownerdie*/, 
+    Dwarf_Half      /*attr*/, 
+    Dwarf_P_Die     /*otherdie*/, 
+    Dwarf_Error*    /*error*/);
+
+Dwarf_P_Attribute dwarf_add_AT_dataref(
+    Dwarf_P_Debug   /* dbg*/,
+    Dwarf_P_Die     /*ownerdie*/, 
+    Dwarf_Half      /*attr*/,
+    Dwarf_Unsigned  /*pcvalue*/,
+    Dwarf_Unsigned  /*sym_index*/,
+    Dwarf_Error*    /*error*/);
 
 Dwarf_P_Attribute dwarf_add_AT_const_value_string(Dwarf_P_Die /*ownerdie*/, 
-    char* 		/*string_value*/, 
-    Dwarf_Error* 	/*error*/);
+    char*           /*string_value*/, 
+    Dwarf_Error*    /*error*/);
 
 Dwarf_P_Attribute dwarf_add_AT_location_expr(Dwarf_P_Debug /*dbg*/, 
-    Dwarf_P_Die 	/*ownerdie*/, 
-    Dwarf_Half 		/*attr*/, 
-    Dwarf_P_Expr 	/*loc_expr*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_P_Die     /*ownerdie*/, 
+    Dwarf_Half      /*attr*/, 
+    Dwarf_P_Expr    /*loc_expr*/, 
+    Dwarf_Error*    /*error*/);
 
 Dwarf_P_Attribute dwarf_add_AT_string(Dwarf_P_Debug /*dbg*/, 
-    Dwarf_P_Die 	/*ownerdie*/, 
-    Dwarf_Half 		/*attr*/, 
-    char* 		/*string*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_P_Die     /*ownerdie*/, 
+    Dwarf_Half      /*attr*/, 
+    char*           /*string*/, 
+    Dwarf_Error*     /*error*/);
 
 Dwarf_P_Attribute dwarf_add_AT_flag(Dwarf_P_Debug /*dbg*/, 
-    Dwarf_P_Die 	/*ownerdie*/, 
-    Dwarf_Half 		/*attr*/, 
-    Dwarf_Small 	/*flag*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_P_Die     /*ownerdie*/, 
+    Dwarf_Half      /*attr*/, 
+    Dwarf_Small     /*flag*/, 
+    Dwarf_Error*    /*error*/);
 
 Dwarf_P_Attribute dwarf_add_AT_producer(Dwarf_P_Die /*ownerdie*/, 
-    char* 		/*producer_string*/, 
-    Dwarf_Error* 	/*error*/);
+    char*           /*producer_string*/, 
+    Dwarf_Error*    /*error*/);
 
 Dwarf_P_Attribute dwarf_add_AT_const_value_signedint(Dwarf_P_Die /*ownerdie*/, 
-    Dwarf_Signed 	/*signed_value*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Signed    /*signed_value*/, 
+    Dwarf_Error*    /*error*/);
 
 Dwarf_P_Attribute dwarf_add_AT_const_value_unsignedint(
-    Dwarf_P_Die         /*ownerdie*/, 
-    Dwarf_Unsigned 	/*unsigned_value*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_P_Die     /*ownerdie*/, 
+    Dwarf_Unsigned  /*unsigned_value*/, 
+    Dwarf_Error*    /*error*/);
 
 Dwarf_P_Attribute dwarf_add_AT_comp_dir(Dwarf_P_Die /*ownerdie*/, 
-    char* 		/*current_working_directory*/, 
-    Dwarf_Error* 	/*error*/);
-
-Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die	/*die*/,
-    char* 		/*name*/,
-    Dwarf_Error* 	/*error*/);
+    char*           /*current_working_directory*/, 
+    Dwarf_Error*    /*error*/);
+
+Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die    /*die*/,
+    char*           /*name*/,
+    Dwarf_Error*    /*error*/);
 
 /* Producer line creation functions (.debug_line) */
 Dwarf_Unsigned dwarf_add_directory_decl(Dwarf_P_Debug /*dbg*/, 
-    char* 		/*name*/, 
-    Dwarf_Error*	/*error*/);
+    char*           /*name*/, 
+    Dwarf_Error*    /*error*/);
 
 Dwarf_Unsigned dwarf_add_file_decl(Dwarf_P_Debug /*dbg*/, 
-    char* 		/*name*/,
-    Dwarf_Unsigned 	/*dir_index*/, 
-    Dwarf_Unsigned 	/*time_last_modified*/, 
-    Dwarf_Unsigned 	/*length*/, 
-    Dwarf_Error*	/*error*/);
+    char*           /*name*/,
+    Dwarf_Unsigned  /*dir_index*/, 
+    Dwarf_Unsigned  /*time_last_modified*/, 
+    Dwarf_Unsigned  /*length*/, 
+    Dwarf_Error*    /*error*/);
 
 Dwarf_Unsigned dwarf_add_line_entry(Dwarf_P_Debug /*dbg*/, 
-    Dwarf_Unsigned 	/*file_index*/, 
-    Dwarf_Addr 		/*code_address*/, 
-    Dwarf_Unsigned 	/*lineno*/, 
-    Dwarf_Signed 	/*column_number*/, 
-    Dwarf_Bool 		/*is_source_stmt_begin*/, 
-    Dwarf_Bool 		/*is_basic_block_begin*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Unsigned  /*file_index*/, 
+    Dwarf_Addr      /*code_address*/, 
+    Dwarf_Unsigned  /*lineno*/, 
+    Dwarf_Signed    /*column_number*/, 
+    Dwarf_Bool      /*is_source_stmt_begin*/, 
+    Dwarf_Bool      /*is_basic_block_begin*/, 
+    Dwarf_Error*    /*error*/);
 
 Dwarf_Unsigned dwarf_lne_set_address(Dwarf_P_Debug /*dbg*/, 
-    Dwarf_Unsigned 	/*offset*/, 
-    Dwarf_Unsigned 	/*symbol_index*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Unsigned  /*offset*/, 
+    Dwarf_Unsigned  /*symbol_index*/, 
+    Dwarf_Error*    /*error*/);
 
 Dwarf_Unsigned dwarf_lne_end_sequence(Dwarf_P_Debug /*dbg*/, 
-    Dwarf_Addr		/*end_address*/,
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Addr      /*end_address*/,
+    Dwarf_Error*    /*error*/);
 
 /* Producer .debug_frame functions */
 Dwarf_Unsigned dwarf_add_frame_cie(Dwarf_P_Debug /*dbg*/, 
-    char* 		/*augmenter*/, 
-    Dwarf_Small 	/*code_alignent_factor*/, 
-    Dwarf_Small 	/*data_alignment_factor*/, 
-    Dwarf_Small 	/*return_address_reg*/, 
-    Dwarf_Ptr 		/*initialization_bytes*/, 
-    Dwarf_Unsigned 	/*init_byte_len*/, 
-    Dwarf_Error* 	/*error*/);
+    char*           /*augmenter*/, 
+    Dwarf_Small     /*code_alignent_factor*/, 
+    Dwarf_Small     /*data_alignment_factor*/, 
+    Dwarf_Small     /*return_address_reg*/, 
+    Dwarf_Ptr       /*initialization_bytes*/, 
+    Dwarf_Unsigned  /*init_byte_len*/, 
+    Dwarf_Error*    /*error*/);
 
 Dwarf_Unsigned dwarf_add_frame_fde( 
-    Dwarf_P_Debug 	/*dbg*/,
-    Dwarf_P_Fde 	/*fde*/, 
-    Dwarf_P_Die 	/*corresponding subprogram die*/,
-    Dwarf_Unsigned 	/*cie_to_use*/, 
-    Dwarf_Unsigned  	/*virt_addr_of_described_code*/, 
-    Dwarf_Unsigned  	/*length_of_code*/, 
-    Dwarf_Unsigned 	/*symbol_index*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_P_Debug   /*dbg*/,
+    Dwarf_P_Fde     /*fde*/, 
+    Dwarf_P_Die     /*corresponding subprogram die*/,
+    Dwarf_Unsigned  /*cie_to_use*/, 
+    Dwarf_Unsigned  /*virt_addr_of_described_code*/, 
+    Dwarf_Unsigned  /*length_of_code*/, 
+    Dwarf_Unsigned  /*symbol_index*/, 
+    Dwarf_Error*    /*error*/);
 
 Dwarf_Unsigned dwarf_add_frame_fde_b(
-        Dwarf_P_Debug  /*dbg*/,
-        Dwarf_P_Fde    /*fde*/,
-        Dwarf_P_Die    /*die*/,
-        Dwarf_Unsigned /*cie*/,
-        Dwarf_Addr     /*virt_addr*/,
-        Dwarf_Unsigned /*code_len*/,
-        Dwarf_Unsigned /*sym_idx*/,
-        Dwarf_Unsigned /*sym_idx_of_end*/,
-        Dwarf_Addr     /*offset_from_end_sym*/,
-        Dwarf_Error*   /*error*/);
+    Dwarf_P_Debug  /*dbg*/,
+    Dwarf_P_Fde    /*fde*/,
+    Dwarf_P_Die    /*die*/,
+    Dwarf_Unsigned /*cie*/,
+    Dwarf_Addr     /*virt_addr*/,
+    Dwarf_Unsigned /*code_len*/,
+    Dwarf_Unsigned /*sym_idx*/,
+    Dwarf_Unsigned /*sym_idx_of_end*/,
+    Dwarf_Addr     /*offset_from_end_sym*/,
+    Dwarf_Error*   /*error*/);
 
 Dwarf_Unsigned dwarf_add_frame_info_b( 
     Dwarf_P_Debug dbg   /*dbg*/,
-    Dwarf_P_Fde 	/*fde*/,
-    Dwarf_P_Die 	/*die*/,
-    Dwarf_Unsigned 	/*cie*/,
-    Dwarf_Addr 	        /*virt_addr*/,
-    Dwarf_Unsigned 	/*code_len*/,
-    Dwarf_Unsigned 	/*symidx*/,
-    Dwarf_Unsigned      /* end_symbol */,
-    Dwarf_Addr          /* offset_from_end_symbol */,
-    Dwarf_Signed   	/*offset_into_exception_tables*/,
-    Dwarf_Unsigned 	/*exception_table_symbol*/,
-    Dwarf_Error*	/*error*/);
+    Dwarf_P_Fde     /*fde*/,
+    Dwarf_P_Die     /*die*/,
+    Dwarf_Unsigned  /*cie*/,
+    Dwarf_Addr      /*virt_addr*/,
+    Dwarf_Unsigned  /*code_len*/,
+    Dwarf_Unsigned  /*symidx*/,
+    Dwarf_Unsigned  /*end_symbol */,
+    Dwarf_Addr      /*offset_from_end_symbol */,
+    Dwarf_Signed    /*offset_into_exception_tables*/,
+    Dwarf_Unsigned  /*exception_table_symbol*/,
+    Dwarf_Error*    /*error*/);
 
 Dwarf_Unsigned dwarf_add_frame_info( 
     Dwarf_P_Debug dbg   /*dbg*/,
-    Dwarf_P_Fde 	/*fde*/,
-    Dwarf_P_Die 	/*die*/,
-    Dwarf_Unsigned 	/*cie*/,
-    Dwarf_Addr 	        /*virt_addr*/,
-    Dwarf_Unsigned 	/*code_len*/,
-    Dwarf_Unsigned 	/*symidx*/,
-    Dwarf_Signed   	/*offset_into_exception_tables*/,
-    Dwarf_Unsigned 	/*exception_table_symbol*/,
-    Dwarf_Error*	/*error*/);
+    Dwarf_P_Fde     /*fde*/,
+    Dwarf_P_Die     /*die*/,
+    Dwarf_Unsigned  /*cie*/,
+    Dwarf_Addr      /*virt_addr*/,
+    Dwarf_Unsigned  /*code_len*/,
+    Dwarf_Unsigned  /*symidx*/,
+    Dwarf_Signed    /*offset_into_exception_tables*/,
+    Dwarf_Unsigned  /*exception_table_symbol*/,
+    Dwarf_Error*    /*error*/);
 
 Dwarf_P_Fde dwarf_add_fde_inst(
-    Dwarf_P_Fde         /*fde*/,
-    Dwarf_Small 	/*op*/, 
-    Dwarf_Unsigned 	/*val1*/, 
-    Dwarf_Unsigned 	/*val2*/, 
-    Dwarf_Error* 	/*error*/);
-
-Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug	/*dbg*/, Dwarf_Error* /*error*/);
+    Dwarf_P_Fde     /*fde*/,
+    Dwarf_Small     /*op*/, 
+    Dwarf_Unsigned  /*val1*/, 
+    Dwarf_Unsigned  /*val2*/, 
+    Dwarf_Error*    /*error*/);
+
+/* New September 17, 2009 */
+int dwarf_insert_fde_inst_bytes(
+    Dwarf_P_Debug  /*dbg*/,
+    Dwarf_P_Fde    /*fde*/,
+    Dwarf_Unsigned /*len*/, 
+    Dwarf_Ptr      /*ibytes*/,
+    Dwarf_Error*   /*error*/);
+
+
+Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug    /*dbg*/, Dwarf_Error* /*error*/);
 
 Dwarf_P_Fde dwarf_fde_cfa_offset(
-    Dwarf_P_Fde         /*fde*/, 
-    Dwarf_Unsigned  	/*register_number*/, 
-    Dwarf_Signed    	/*offset*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_P_Fde     /*fde*/, 
+    Dwarf_Unsigned  /*register_number*/, 
+    Dwarf_Signed    /*offset*/, 
+    Dwarf_Error*    /*error*/);
 
 /* die creation & addition routines */
 Dwarf_P_Die dwarf_new_die(
-    Dwarf_P_Debug	/*dbg*/,
-    Dwarf_Tag 		/*tag*/,
-    Dwarf_P_Die 	/*parent*/, 
-    Dwarf_P_Die 	/*child*/, 
-    Dwarf_P_Die 	/*left */,
-    Dwarf_P_Die 	/*right*/,
-    Dwarf_Error*	/*error*/);
+    Dwarf_P_Debug    /*dbg*/,
+    Dwarf_Tag         /*tag*/,
+    Dwarf_P_Die     /*parent*/, 
+    Dwarf_P_Die     /*child*/, 
+    Dwarf_P_Die     /*left */,
+    Dwarf_P_Die     /*right*/,
+    Dwarf_Error*    /*error*/);
 
 Dwarf_Unsigned dwarf_add_die_to_debug(
-    Dwarf_P_Debug       /*dbg*/,
-    Dwarf_P_Die		/*die*/,
-    Dwarf_Error*	/*error*/);
+    Dwarf_P_Debug   /*dbg*/,
+    Dwarf_P_Die     /*die*/,
+    Dwarf_Error*    /*error*/);
+
+/* Markers are not written  to DWARF2/3/4, they are user
+   defined and may be used for any purpose.
+*/
+Dwarf_Unsigned dwarf_add_die_marker(
+    Dwarf_P_Debug   /*dbg*/,
+    Dwarf_P_Die     /*die*/,
+    Dwarf_Unsigned  /*marker*/,
+    Dwarf_Error *   /*error*/);
+
+Dwarf_Unsigned dwarf_get_die_marker(
+    Dwarf_P_Debug   /*dbg*/,
+    Dwarf_P_Die     /*die*/,
+    Dwarf_Unsigned *  /*marker*/,
+    Dwarf_Error *   /*error*/);
 
 Dwarf_P_Die dwarf_die_link(
-    Dwarf_P_Die         /*die*/,
-    Dwarf_P_Die 	/*parent*/,
-    Dwarf_P_Die 	/*child*/, 
-    Dwarf_P_Die		/*left*/,
-    Dwarf_P_Die		/*right*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_P_Die     /*die*/,
+    Dwarf_P_Die     /*parent*/,
+    Dwarf_P_Die     /*child*/, 
+    Dwarf_P_Die     /*left*/,
+    Dwarf_P_Die     /*right*/, 
+    Dwarf_Error*    /*error*/);
+
+void dwarf_dealloc_compressed_block(
+    Dwarf_P_Debug,
+    void *
+);
+
+/* Call this passing in return value from dwarf_uncompress_integer_block()
+ * to free the space the decompression allocated. */
+void dwarf_dealloc_uncompressed_block(
+    Dwarf_Debug,
+    void *
+);
+
+void * dwarf_compress_integer_block(
+    Dwarf_P_Debug,    /* dbg */
+    Dwarf_Bool,       /* signed==true (or unsigned) */
+    Dwarf_Small,      /* size of integer units: 8, 16, 32, 64 */
+    void*,            /* data */
+    Dwarf_Unsigned,   /* number of elements */
+    Dwarf_Unsigned*,  /* number of bytes in output block */
+    Dwarf_Error*      /* error */
+);
+
+/* Decode an array of signed leb integers (so of course the
+ * array is not composed of fixed length values, but is instead
+ * a sequence of sleb values).
+ * Returns a DW_DLV_BADADDR on error.
+ * Otherwise returns a pointer to an array of 32bit integers.
+ * The signed argument must be non-zero (the decode
+ * assumes sleb integers in the input data) at this time.
+ * Size of integer units must be 32 (32 bits each) at this time.
+ * Number of bytes in block is a byte count (not array count).
+ * Returns number of units in output block (ie, number of elements
+ * of the array that the return value points to) thru the argument.
+ */
+void * dwarf_uncompress_integer_block(
+    Dwarf_Debug,      /* dbg */
+    Dwarf_Bool,       /* signed==true (or unsigned) */
+    Dwarf_Small,      /* size of integer units: 8, 16, 32, 64 */
+    void*,            /* input data */
+    Dwarf_Unsigned,   /* number of bytes in input */
+    Dwarf_Unsigned*,  /* number of units in output block */
+    Dwarf_Error*      /* error */
+);
 
 /* Operations to create location expressions. */
 Dwarf_P_Expr dwarf_new_expr(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/);
 
+void dwarf_expr_reset(
+    Dwarf_P_Expr      /*expr*/,
+    Dwarf_Error*      /*error*/);
+
 Dwarf_Unsigned dwarf_add_expr_gen(
-    Dwarf_P_Expr        /*expr*/, 
-    Dwarf_Small 	/*opcode*/, 
-    Dwarf_Unsigned 	/*val1*/, 
-    Dwarf_Unsigned 	/*val2*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_P_Expr      /*expr*/, 
+    Dwarf_Small       /*opcode*/, 
+    Dwarf_Unsigned    /*val1*/, 
+    Dwarf_Unsigned    /*val2*/, 
+    Dwarf_Error*      /*error*/);
 
 Dwarf_Unsigned dwarf_add_expr_addr(
-    Dwarf_P_Expr        /*expr*/, 
-    Dwarf_Unsigned 	/*addr*/, 
-    Dwarf_Signed 	/*sym_index*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_P_Expr      /*expr*/, 
+    Dwarf_Unsigned    /*addr*/, 
+    Dwarf_Signed      /*sym_index*/, 
+    Dwarf_Error*      /*error*/);
 
 Dwarf_Unsigned dwarf_add_expr_addr_b(
-    Dwarf_P_Expr        /*expr*/,
-    Dwarf_Unsigned      /*addr*/,
-    Dwarf_Unsigned      /*sym_index*/,
-    Dwarf_Error*        /*error*/);
+    Dwarf_P_Expr      /*expr*/,
+    Dwarf_Unsigned    /*addr*/,
+    Dwarf_Unsigned    /*sym_index*/,
+    Dwarf_Error*      /*error*/);
 
 Dwarf_Unsigned dwarf_expr_current_offset(
-    Dwarf_P_Expr /*expr*/, 
-    Dwarf_Error* /*error*/);
+    Dwarf_P_Expr      /*expr*/, 
+    Dwarf_Error*      /*error*/);
 
 Dwarf_Addr dwarf_expr_into_block(
-    Dwarf_P_Expr        /*expr*/, 
-    Dwarf_Unsigned* 	/*length*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_P_Expr      /*expr*/, 
+    Dwarf_Unsigned*   /*length*/, 
+    Dwarf_Error*      /*error*/);
 
 Dwarf_Unsigned dwarf_add_arange(Dwarf_P_Debug /*dbg*/, 
-    Dwarf_Addr 		/*begin_address*/, 
-    Dwarf_Unsigned 	/*length*/, 
-    Dwarf_Signed 	/*symbol_index*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_Addr        /*begin_address*/, 
+    Dwarf_Unsigned    /*length*/, 
+    Dwarf_Signed      /*symbol_index*/, 
+    Dwarf_Error*      /*error*/);
 
 Dwarf_Unsigned dwarf_add_arange_b(
-        Dwarf_P_Debug  /*dbg*/,
-        Dwarf_Addr     /*begin_address*/,
-        Dwarf_Unsigned /*length*/,
-        Dwarf_Unsigned /*symbol_index*/,
-        Dwarf_Unsigned /*end_symbol_index*/,
-        Dwarf_Addr     /*offset_from_end_symbol*/,
-        Dwarf_Error *  /*error*/);
+    Dwarf_P_Debug  /*dbg*/,
+    Dwarf_Addr     /*begin_address*/,
+    Dwarf_Unsigned /*length*/,
+    Dwarf_Unsigned /*symbol_index*/,
+    Dwarf_Unsigned /*end_symbol_index*/,
+    Dwarf_Addr     /*offset_from_end_symbol*/,
+    Dwarf_Error *  /*error*/);
 
 Dwarf_Unsigned dwarf_add_pubname(
-    Dwarf_P_Debug       /*dbg*/, 
-    Dwarf_P_Die 	/*die*/, 
-    char* 		/*pubname_name*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_P_Debug      /*dbg*/, 
+    Dwarf_P_Die        /*die*/, 
+    char*              /*pubname_name*/, 
+    Dwarf_Error*       /*error*/);
 
 Dwarf_Unsigned dwarf_add_funcname(
-    Dwarf_P_Debug       /*dbg*/, 
-    Dwarf_P_Die 	/*die*/, 
-    char* 		/*func_name*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_P_Debug      /*dbg*/, 
+    Dwarf_P_Die        /*die*/, 
+    char*              /*func_name*/, 
+    Dwarf_Error*       /*error*/);
 
 Dwarf_Unsigned dwarf_add_typename(
-    Dwarf_P_Debug       /*dbg*/, 
-    Dwarf_P_Die 	/*die*/, 
-    char* 		/*type_name*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_P_Debug     /*dbg*/, 
+    Dwarf_P_Die       /*die*/, 
+    char*             /*type_name*/, 
+    Dwarf_Error*      /*error*/);
 
 Dwarf_Unsigned dwarf_add_varname(
-    Dwarf_P_Debug       /*dbg*/, 
-    Dwarf_P_Die 	/*die*/, 
-    char* 		/*var_name*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_P_Debug     /*dbg*/, 
+    Dwarf_P_Die       /*die*/, 
+    char*             /*var_name*/, 
+    Dwarf_Error*      /*error*/);
 
 Dwarf_Unsigned dwarf_add_weakname(
-    Dwarf_P_Debug       /*dbg*/, 
-    Dwarf_P_Die 	/*die*/, 
-    char* 		/*weak_name*/, 
-    Dwarf_Error* 	/*error*/);
+    Dwarf_P_Debug    /*dbg*/, 
+    Dwarf_P_Die      /*die*/, 
+    char*            /*weak_name*/, 
+    Dwarf_Error*     /*error*/);
 
 /* .debug_macinfo producer functions
    Functions must be called in right order: the section is output
    In the order these are presented.
 */
 int dwarf_def_macro(Dwarf_P_Debug /*dbg*/,
-    Dwarf_Unsigned  /*line*/,
-    char *          /*macname, with (arglist), no space before (*/, 
-    char *	    /*macvalue*/,
-    Dwarf_Error*    /*error*/);
+    Dwarf_Unsigned   /*line*/,
+    char *           /*macname, with (arglist), no space before (*/, 
+    char *           /*macvalue*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_undef_macro(Dwarf_P_Debug /*dbg*/,
-    Dwarf_Unsigned  /*line*/,
-    char *          /*macname, no arglist, of course*/,
-    Dwarf_Error*    /*error*/);
+    Dwarf_Unsigned   /*line*/,
+    char *           /*macname, no arglist, of course*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_start_macro_file(Dwarf_P_Debug /*dbg*/,
-    Dwarf_Unsigned /*fileindex*/,
-    Dwarf_Unsigned /*linenumber*/,
-    Dwarf_Error*   /*error*/);
+    Dwarf_Unsigned   /*fileindex*/,
+    Dwarf_Unsigned   /*linenumber*/,
+    Dwarf_Error*     /*error*/);
 
 int dwarf_end_macro_file(Dwarf_P_Debug /*dbg*/,
-    Dwarf_Error*   /*error*/);
+    Dwarf_Error*     /*error*/);
 
 int dwarf_vendor_ext(Dwarf_P_Debug /*dbg*/,
-    Dwarf_Unsigned /*constant*/,
-    char *         /*string*/,
-    Dwarf_Error*   /*error*/);
+    Dwarf_Unsigned   /*constant*/,
+    char *           /*string*/,
+    Dwarf_Error*     /*error*/);
 
 /* end macinfo producer functions */
 
-
-void dwarf_p_dealloc(void* /*space*/, Dwarf_Unsigned /*type*/);
-
 int dwarf_attr_offset(Dwarf_Die /*die*/,
     Dwarf_Attribute /*attr of above die*/,
     Dwarf_Off     * /*returns offset thru this ptr */,
     Dwarf_Error   * /*error*/);
 
+/* This is a hack so clients can verify offsets.
+   Added April 2005 so that debugger can detect broken offsets
+   (which happened in an IRIX executable larger than 2GB
+    with MIPSpro 7.3.1.3 toolchain.).
+*/
+int
+dwarf_get_section_max_offsets(Dwarf_Debug /*dbg*/,
+    Dwarf_Unsigned * /*debug_info_size*/,
+    Dwarf_Unsigned * /*debug_abbrev_size*/,
+    Dwarf_Unsigned * /*debug_line_size*/,
+    Dwarf_Unsigned * /*debug_loc_size*/,
+    Dwarf_Unsigned * /*debug_aranges_size*/,
+    Dwarf_Unsigned * /*debug_macinfo_size*/,
+    Dwarf_Unsigned * /*debug_pubnames_size*/,
+    Dwarf_Unsigned * /*debug_str_size*/,
+    Dwarf_Unsigned * /*debug_frame_size*/,
+    Dwarf_Unsigned * /*debug_ranges_size*/,
+    Dwarf_Unsigned * /*debug_pubtypes_size*/);
+
+/* Multiple releases spelled 'initial' as 'inital' . 
+   The 'inital' spelling should not be used. */ 
+Dwarf_Half dwarf_set_frame_rule_inital_value(Dwarf_Debug /*dbg*/,
+    Dwarf_Half /*value*/);
+/* Additional interface with correct 'initial' spelling. */
+/* It is likely you will want to call the following 5 functions
+   before accessing any frame information.  All are useful
+   to tailor handling of pseudo-registers needed to turn
+   frame operation references into simpler forms and to
+   reflect ABI specific data.  Of course altering libdwarf.h
+   and dwarf.h allow the same capabilities, but such header changes
+   do not let one change these values at runtime. */
+Dwarf_Half dwarf_set_frame_rule_initial_value(Dwarf_Debug /*dbg*/,
+    Dwarf_Half /*value*/);
+Dwarf_Half dwarf_set_frame_rule_table_size(Dwarf_Debug /*dbg*/, 
+    Dwarf_Half /*value*/);
+Dwarf_Half dwarf_set_frame_cfa_value(Dwarf_Debug /*dbg*/, 
+    Dwarf_Half /*value*/);
+Dwarf_Half dwarf_set_frame_same_value(Dwarf_Debug /*dbg*/, 
+    Dwarf_Half /*value*/);
+Dwarf_Half dwarf_set_frame_undefined_value(Dwarf_Debug /*dbg*/, 
+    Dwarf_Half /*value*/);
+
+/* As of April 27, 2009, this version with no diepointer is
+   obsolete though supported.  Use dwarf_get_ranges_a() instead. */
+int dwarf_get_ranges(Dwarf_Debug /*dbg*/, 
+    Dwarf_Off /*rangesoffset*/,
+    Dwarf_Ranges ** /*rangesbuf*/,
+    Dwarf_Signed * /*listlen*/,
+    Dwarf_Unsigned * /*bytecount*/,
+    Dwarf_Error * /*error*/);
+
+/* This adds the address_size argument. New April 27, 2009 */
+int dwarf_get_ranges_a(Dwarf_Debug /*dbg*/, 
+    Dwarf_Off /*rangesoffset*/,
+    Dwarf_Die  /* diepointer */,
+    Dwarf_Ranges ** /*rangesbuf*/,
+    Dwarf_Signed * /*listlen*/,
+    Dwarf_Unsigned * /*bytecount*/,
+    Dwarf_Error * /*error*/);
+
+void dwarf_ranges_dealloc(Dwarf_Debug /*dbg*/, 
+    Dwarf_Ranges * /*rangesbuf*/,
+    Dwarf_Signed /*rangecount*/);
+
+/* The harmless error list is a circular buffer of
+   errors we note but which do not stop us from processing
+   the object.  Created so dwarfdump or other tools
+   can report such inconsequential errors without causing
+   anything to stop early. */
+#define DW_HARMLESS_ERROR_CIRCULAR_LIST_DEFAULT_SIZE 4
+#define DW_HARMLESS_ERROR_MSG_STRING_SIZE   200
+/* User code supplies size of array of pointers errmsg_ptrs_array
+    in count and the array of pointers (the pointers themselves
+    need not be initialized).
+    The pointers returned in the array of pointers
+    are invalidated by ANY call to libdwarf.
+    Use them before making another libdwarf call!
+    The array of string pointers passed in always has
+    a final null pointer, so if there are N pointers the
+    and M actual strings, then MIN(M,N-1) pointers are
+    set to point to error strings.  The array of pointers
+    to strings always terminates with a NULL pointer.
+    If 'count' is passed in zero then errmsg_ptrs_array
+    is not touched.
+
+    The function returns DW_DLV_NO_ENTRY if no harmless errors 
+    were noted so far.  Returns DW_DLV_OK if there are errors.
+    Never returns DW_DLV_ERROR. 
+
+    Each call empties the error list (discarding all current entries).
+    If newerr_count is non-NULL the count of harmless errors
+    since the last call is returned through the pointer
+    (some may have been discarded or not returned, it is a circular
+    list...).
+    If DW_DLV_NO_ENTRY is returned none of the arguments
+    here are touched or used.
+    */
+int dwarf_get_harmless_error_list(Dwarf_Debug /*dbg*/,
+    unsigned  /*count*/, 
+    const char ** /*errmsg_ptrs_array*/,
+    unsigned * /*newerr_count*/);
+
+/* Insertion is only for testing the harmless error code, it is not
+    necessarily useful otherwise. */
+void dwarf_insert_harmless_error(Dwarf_Debug /*dbg*/,
+    char * /*newerror*/);
+
+/* The size of the circular list of strings may be set
+   and reset as needed.  If it is shortened excess
+   messages are simply dropped.  It returns the previous
+   size. If zero passed in the size is unchanged
+   and it simply returns the current size  */
+unsigned dwarf_set_harmless_error_list_size(Dwarf_Debug /*dbg*/,
+    unsigned /*maxcount*/);
+/* The harmless error strings (if any) are freed when the dbg
+   is dwarf_finish()ed. */
+
+/*  When the val_in is known these dwarf_get_TAG_name (etc)
+    functions return the string corresponding to the val_in passed in
+    through the pointer s_out and the value returned is DW_DLV_OK.   
+    The strings are in static storage 
+    and must not be freed.
+    If DW_DLV_NO_ENTRY is returned the val_in is not known and
+    *s_out is not set.  DW_DLV_ERROR is never returned.*/
+
+extern int dwarf_get_TAG_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_children_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_FORM_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_AT_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_OP_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_ATE_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_DS_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_END_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_ATCF_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_ACCESS_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_VIS_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_VIRTUALITY_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_LANG_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_ID_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_CC_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_INL_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_ORD_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_DSC_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_LNS_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_LNE_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_MACINFO_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_CFA_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_EH_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_FRAME_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_CHILDREN_name(unsigned int /*val_in*/, const char ** /*s_out */);
+extern int dwarf_get_ADDR_name(unsigned int /*val_in*/, const char ** /*s_out */);
 
 #ifdef __cplusplus
 }
 #endif
 #endif /* _LIBDWARF_H */
 
+
--- a/usr/src/tools/ctf/dwarf/common/libdwarfdefs.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/libdwarfdefs.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -51,35 +51,41 @@
 */
 
 
-#if (!defined(HAVE___UINT32_T)) && defined(HAVE_SGIDEFS_H)
+#if (!defined(HAVE___UINT32_T)) && defined(HAVE___UINT32_T_IN_SGIDEFS_H)
 #include <sgidefs.h>		/* sgidefs.h defines them */
 #define HAVE___UINT32_T 1
+#endif
+
+#if (!defined(HAVE___UINT64_T)) && defined(HAVE___UINT64_T_IN_SGIDEFS_H)
+#include <sgidefs.h>		/* sgidefs.h defines them */
 #define HAVE___UINT64_T 1
 #endif
 
 
-
 #if (!defined(HAVE___UINT32_T)) &&   \
 	defined(HAVE_SYS_TYPES_H) &&   \
 	defined(HAVE___UINT32_T_IN_SYS_TYPES_H)
 #  include <sys/types.h>
-/* we assume __[u]int32_t and __[u]int64_t defined 
-   since __uint32_t defined in the sys/types.h in use */
 #define HAVE___UINT32_T 1
+#endif
+
+#if (!defined(HAVE___UINT64_T)) &&   \
+	defined(HAVE_SYS_TYPES_H) &&   \
+	defined(HAVE___UINT64_T_IN_SYS_TYPES_H)
+#  include <sys/types.h>
 #define HAVE___UINT64_T 1
 #endif
 
 #ifndef HAVE___UINT32_T
 typedef int __int32_t;
 typedef unsigned __uint32_t;
-
 #define HAVE___UINT32_T 1
 #endif
+
 #ifndef HAVE___UINT64_T
 typedef long long __int64_t;
 typedef unsigned long long __uint64_t;
-
 #define HAVE___UINT64_T 1
 #endif
 
-#endif
+#endif /* LIBDWARFDEFS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/tools/ctf/dwarf/common/malloc_check.c	Sun May 22 03:13:22 2011 +0100
@@ -0,0 +1,339 @@
+/*
+
+  Copyright (C) 2005 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+/* malloc_check.c For checking dealloc completeness. 
+
+   This code is as simple as possible and works ok for
+   reasonable size allocation counts.
+
+   It treats allocation as global, and so will not
+   work very well if an application opens more than one
+   Dwarf_Debug.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>             /* for exit() and various malloc
+                                   prototypes */
+#include "config.h"
+#include "dwarf_incl.h"
+#include "malloc_check.h"
+#ifdef  WANT_LIBBDWARF_MALLOC_CHECK
+
+/* To turn off printing every entry, just change the define
+   to set PRINT_MALLOC_DETAILS 0.
+*/
+#define PRINT_MALLOC_DETAILS 0
+
+#define MC_TYPE_UNKNOWN 0
+#define MC_TYPE_ALLOC 1
+#define MC_TYPE_DEALLOC 2
+
+struct mc_data_s {
+    struct mc_data_s *mc_prev;
+    unsigned long mc_address;   /* Assumes this is large enough to hold 
+                                   a pointer! */
+
+    long mc_alloc_number;       /* Assigned in order by when record
+                                   created. */
+    unsigned char mc_alloc_code;        /* Allocation code, libdwarf. */
+    unsigned char mc_type;
+    unsigned char mc_dealloc_noted;     /* Used on an ALLOC node. */
+    unsigned char mc_dealloc_noted_count;       /* Used on an ALLOC
+                                                   node. */
+};
+
+/* 
+   
+   
+*/
+#define HASH_TABLE_SIZE 10501
+static struct mc_data_s *mc_data_hash[HASH_TABLE_SIZE];
+static long mc_data_list_size = 0;
+
+static char *alloc_type_name[MAX_DW_DLA + 1] = {
+    "",
+    "DW_DLA_STRING",
+    "DW_DLA_LOC",
+    "DW_DLA_LOCDESC",
+    "DW_DLA_ELLIST",
+    "DW_DLA_BOUNDS",
+    "DW_DLA_BLOCK",
+    "DW_DLA_DEBUG",
+    "DW_DLA_DIE",
+    "DW_DLA_LINE",
+    "DW_DLA_ATTR",
+    "DW_DLA_TYPE",
+    "DW_DLA_SUBSCR",
+    "DW_DLA_GLOBAL",
+    "DW_DLA_ERROR",
+    "DW_DLA_LIST",
+    "DW_DLA_LINEBUF",
+    "DW_DLA_ARANGE",
+    "DW_DLA_ABBREV",
+    "DW_DLA_FRAME_OP",
+    "DW_DLA_CIE",
+    "DW_DLA_FDE",
+    "DW_DLA_LOC_BLOCK",
+    "DW_DLA_FRAME_BLOCK",
+    "DW_DLA_FUNC",
+    "DW_DLA_TYPENAME",
+    "DW_DLA_VAR",
+    "DW_DLA_WEAK",
+    "DW_DLA_ADDR",
+    "DW_DLA_ABBREV_LIST",
+    "DW_DLA_CHAIN",
+    "DW_DLA_CU_CONTEXT",
+    "DW_DLA_FRAME",
+    "DW_DLA_GLOBAL_CONTEXT",
+    "DW_DLA_FILE_ENTRY",
+    "DW_DLA_LINE_CONTEXT",
+    "DW_DLA_LOC_CHAIN",
+    "DW_DLA_HASH_TABLE",
+    "DW_DLA_FUNC_CONTEXT",
+    "DW_DLA_TYPENAME_CONTEXT",
+    "DW_DLA_VAR_CONTEXT",
+    "DW_DLA_WEAK_CONTEXT",
+    "DW_DLA_PUBTYPES_CONTEXT"
+        /* Don't forget to expand this list if the list of codes
+           expands. */
+};
+
+static unsigned
+hash_address(unsigned long addr)
+{
+    unsigned long a = addr >> 2;
+
+    return a % HASH_TABLE_SIZE;
+}
+
+#if PRINT_MALLOC_DETAILS
+static void
+print_alloc_dealloc_detail(unsigned long addr,
+                           int code, char *whichisit)
+{
+    fprintf(stderr,
+            "%s  addr 0x%lx code %d (%s) entry %ld\n",
+            whichisit, addr, code, alloc_type_name[code],
+            mc_data_list_size);
+}
+#else
+#define  print_alloc_dealloc_detail(a,b,c)      /* nothing */
+#endif
+
+/* Create a zeroed struct or die. */
+static void *
+newone(void)
+{
+    struct mc_data_s *newd = malloc(sizeof(struct mc_data_s));
+
+    if (newd == 0) {
+        fprintf(stderr, "out of memory , # %ld\n", mc_data_list_size);
+        exit(1);
+    }
+    memset(newd, 0, sizeof(struct mc_data_s));
+    return newd;
+}
+
+/* Notify checker that get_alloc has allocated user data. */
+void
+dwarf_malloc_check_alloc_data(void *addr_in, unsigned char code)
+{
+    struct mc_data_s *newd = newone();
+    unsigned long addr = (unsigned long) addr_in;
+    struct mc_data_s **base = &mc_data_hash[hash_address(addr)];
+
+    print_alloc_dealloc_detail(addr, code, "alloc   ");
+    newd->mc_address = addr;
+    newd->mc_alloc_code = code;
+    newd->mc_type = MC_TYPE_ALLOC;
+    newd->mc_alloc_number = mc_data_list_size;
+    newd->mc_prev = *base;
+    *base = newd;
+    newd->mc_alloc_number = mc_data_list_size;
+    mc_data_list_size += 1;
+}
+
+static void
+print_entry(char *msg, struct mc_data_s *data)
+{
+    fprintf(stderr,
+            "%s: 0x%08lx code %2d (%s) type %s dealloc noted %u ct %u\n",
+            msg,
+            (long) data->mc_address,
+            data->mc_alloc_code,
+            alloc_type_name[data->mc_alloc_code],
+            (data->mc_type == MC_TYPE_ALLOC) ? "alloc  " :
+            (data->mc_type == MC_TYPE_DEALLOC) ? "dealloc" : "unknown",
+            (unsigned) data->mc_dealloc_noted,
+            (unsigned) data->mc_dealloc_noted_count);
+}
+
+/* newd is a 'dealloc'.
+*/
+static long
+balanced_by_alloc_p(struct mc_data_s *newd,
+                    long *addr_match_num,
+                    struct mc_data_s **addr_match,
+                    struct mc_data_s *base)
+{
+    struct mc_data_s *cur = base;
+
+    for (; cur; cur = cur->mc_prev) {
+        if (cur->mc_address == newd->mc_address) {
+            if (cur->mc_type == MC_TYPE_ALLOC) {
+                if (cur->mc_alloc_code == newd->mc_alloc_code) {
+                    *addr_match = cur;
+                    *addr_match_num = cur->mc_alloc_number;
+                    return cur->mc_alloc_number;
+                } else {
+                    /* code mismatch */
+                    *addr_match = cur;
+                    *addr_match_num = cur->mc_alloc_number;
+                    return -1;
+                }
+            } else {
+                /* Unbalanced new/del */
+                *addr_match = cur;
+                *addr_match_num = cur->mc_alloc_number;
+                return -1;
+            }
+        }
+    }
+    return -1;
+}
+
+/*  A dealloc is to take place. Ensure it balances an alloc.
+*/
+void
+dwarf_malloc_check_dealloc_data(void *addr_in, unsigned char code)
+{
+    struct mc_data_s *newd = newone();
+    long prev;
+    long addr_match_num = -1;
+    struct mc_data_s *addr_match = 0;
+    unsigned long addr = (unsigned long) addr_in;
+    struct mc_data_s **base = &mc_data_hash[hash_address(addr)];
+
+
+    print_alloc_dealloc_detail(addr, code, "dealloc ");
+    newd->mc_address = (unsigned long) addr;
+    newd->mc_alloc_code = code;
+    newd->mc_type = MC_TYPE_DEALLOC;
+    newd->mc_prev = *base;
+    prev =
+        balanced_by_alloc_p(newd, &addr_match_num, &addr_match, *base);
+    if (prev < 0) {
+        fprintf(stderr,
+                "Unbalanced dealloc at index %ld\n", mc_data_list_size);
+        print_entry("new", newd);
+        fprintf(stderr, "addr-match_num? %ld\n", addr_match_num);
+        if (addr_match) {
+            print_entry("prev entry", addr_match);
+            if (addr_match->mc_dealloc_noted > 1) {
+                fprintf(stderr, "Above is Duplicate dealloc!\n");
+            }
+        }
+        abort();
+        exit(3);
+    }
+    addr_match->mc_dealloc_noted = 1;
+    addr_match->mc_dealloc_noted_count += 1;
+    if (addr_match->mc_dealloc_noted_count > 1) {
+        fprintf(stderr, "Double dealloc entry %ld\n", addr_match_num);
+        print_entry("new dealloc entry", newd);
+        print_entry("bad alloc entry", addr_match);
+    }
+    *base = newd;
+    mc_data_list_size += 1;
+}
+
+/* Final check for leaks.
+*/
+void
+dwarf_malloc_check_complete(char *msg)
+{
+    long i = 0;
+    long total = mc_data_list_size;
+    long hash_slots_used = 0;
+    long max_chain_length = 0;
+
+    fprintf(stderr, "Run complete, %s. %ld entries\n", msg, total);
+    for (; i < HASH_TABLE_SIZE; ++i) {
+        struct mc_data_s *cur = mc_data_hash[i];
+        long cur_chain_length = 0;
+
+        if (cur == 0)
+            continue;
+        ++hash_slots_used;
+        for (; cur; cur = cur->mc_prev) {
+            ++cur_chain_length;
+            if (cur->mc_type == MC_TYPE_ALLOC) {
+                if (cur->mc_dealloc_noted) {
+                    if (cur->mc_dealloc_noted > 1) {
+                        fprintf(stderr,
+                                " Duplicate dealloc! entry %ld\n",
+                                cur->mc_alloc_number);
+                        print_entry("duplicate dealloc", cur);
+
+                    }
+                    continue;
+                } else {
+                    fprintf(stderr, "malloc no dealloc, entry %ld\n",
+                            cur->mc_alloc_number);
+                    print_entry("dangle", cur);
+                }
+            } else {
+                /* mc_type is MC_TYPE_DEALLOC, already checked */
+
+            }
+        }
+        if (cur_chain_length > max_chain_length) {
+            max_chain_length = cur_chain_length;
+        }
+    }
+    fprintf(stderr, "mc hash table slots=%ld, "
+            "used=%ld,  maxchain=%ld\n",
+            (long) HASH_TABLE_SIZE, hash_slots_used, max_chain_length);
+    return;
+}
+
+#else
+
+extern void *libdwarf_an_unused_function_so_not_empty_c_file();
+
+#endif /* WANT_LIBBDWARF_MALLOC_CHECK */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/tools/ctf/dwarf/common/malloc_check.h	Sun May 22 03:13:22 2011 +0100
@@ -0,0 +1,62 @@
+/*
+
+  Copyright (C) 2005 Silicon Graphics, Inc.  All Rights Reserved.
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+/* malloc_check.h */
+
+/* A simple libdwarf-aware malloc checker. 
+   define WANT_LIBBDWARF_MALLOC_CHECK and rebuild libdwarf
+   do make a checking-for-alloc-mistakes libdwarf.
+   NOT  recommended for production use.
+
+   When defined, also add malloc_check.c to the list of
+   files in Makefile.
+*/
+
+#undef WANT_LIBBDWARF_MALLOC_CHECK 
+/*#define WANT_LIBBDWARF_MALLOC_CHECK  1 */
+
+#ifdef WANT_LIBBDWARF_MALLOC_CHECK
+
+void dwarf_malloc_check_alloc_data(void * addr,unsigned char code);
+void dwarf_malloc_check_dealloc_data(void * addr,unsigned char code);
+void dwarf_malloc_check_complete(char *wheremsg); /* called at exit of app */
+
+#else /* !WANT_LIBBDWARF_MALLOC_CHECK */
+
+#define dwarf_malloc_check_alloc_data(a,b)  /* nothing */
+#define dwarf_malloc_check_dealloc_data(a,b)  /* nothing */
+#define dwarf_malloc_check_complete(a) /* nothing */
+
+#endif /* WANT_LIBBDWARF_MALLOC_CHECK */
--- a/usr/src/tools/ctf/dwarf/common/mapfile-vers	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/mapfile-vers	Sun May 22 03:13:22 2011 +0100
@@ -31,22 +31,26 @@
 
 SYMBOL_VERSION ILLUMOSprivate_1.1 {
     global:
+        dwarf_add_arange;
+        dwarf_add_arange_b;
+        dwarf_add_AT_block;
         dwarf_add_AT_comp_dir;
         dwarf_add_AT_const_value_signedint;
         dwarf_add_AT_const_value_string;
         dwarf_add_AT_const_value_unsignedint;
+        dwarf_add_AT_dataref;
         dwarf_add_AT_flag;
         dwarf_add_AT_location_expr;
         dwarf_add_AT_name;
         dwarf_add_AT_producer;
+        dwarf_add_AT_ref_address;
         dwarf_add_AT_reference;
         dwarf_add_AT_signed_const;
         dwarf_add_AT_string;
         dwarf_add_AT_targ_address;
         dwarf_add_AT_targ_address_b;
         dwarf_add_AT_unsigned_const;
-        dwarf_add_arange;
-        dwarf_add_arange_b;
+        dwarf_add_die_marker;
         dwarf_add_die_to_debug;
         dwarf_add_directory_decl;
         dwarf_add_expr_addr;
@@ -72,79 +76,151 @@
         dwarf_bitoffset;
         dwarf_bitsize;
         dwarf_bytesize;
+        dwarf_check_lineheader;
         dwarf_child;
+        dwarf_cie_section_offset;
+        dwarf_compress_integer_block;
+        dwarf_create_cie_from_after_start;
+        dwarf_create_fde_from_after_start;
+        dwarf_CU_dieoffset_given_die;
         dwarf_dealloc;
+        dwarf_dealloc_compressed_block;
+        dwarf_dealloc_uncompressed_block;
         dwarf_def_macro;
+        dwarf_die_abbrev_code;
         dwarf_die_CU_offset;
+        dwarf_die_CU_offset_range;
         dwarf_die_link;
         dwarf_diename;
         dwarf_dieoffset;
         dwarf_elf_init;
+        dwarf_elf_object_access_finish;
+        dwarf_elf_object_access_init;
         dwarf_end_macro_file;
         dwarf_errmsg;
         dwarf_errno;
         dwarf_expand_frame_instructions;
         dwarf_expr_current_offset;
         dwarf_expr_into_block;
+        dwarf_expr_reset;
         dwarf_fde_cfa_offset;
+        dwarf_fde_cie_list_dealloc;
+        dwarf_fde_section_offset;
         dwarf_find_macro_value_start;
         dwarf_finish;
         dwarf_formaddr;
         dwarf_formblock;
+        dwarf_formexprloc;
         dwarf_formflag;
         dwarf_formref;
         dwarf_formsdata;
+        dwarf_formsig8;
         dwarf_formstring;
         dwarf_formudata;
+        dwarf_free_line_table_prefix;
         dwarf_func_cu_offset;
         dwarf_func_die_offset;
         dwarf_func_name_offsets;
         dwarf_funcname;
+        dwarf_funcs_dealloc;
         dwarf_get_abbrev;
         dwarf_get_abbrev_children_flag;
         dwarf_get_abbrev_code;
         dwarf_get_abbrev_entry;
         dwarf_get_abbrev_tag;
+        dwarf_get_ACCESS_name;
+        dwarf_get_ADDR_name;
         dwarf_get_address_size;
         dwarf_get_arange;
         dwarf_get_arange_cu_header_offset;
         dwarf_get_arange_info;
+        dwarf_get_arange_info_b;
         dwarf_get_aranges;
+        dwarf_get_AT_name;
+        dwarf_get_ATCF_name;
+        dwarf_get_ATE_name;
+        dwarf_get_CC_name;
+        dwarf_get_CFA_name;
+        dwarf_get_children_name;
+        dwarf_get_CHILDREN_name;
+        dwarf_get_cie_augmentation_data;
+        dwarf_get_cie_index;
         dwarf_get_cie_info;
         dwarf_get_cie_of_fde;
         dwarf_get_cu_die_offset;
         dwarf_get_cu_die_offset_given_cu_header_offset;
+        dwarf_get_die_address_size;
+        dwarf_get_die_marker;
+        dwarf_get_die_markers;
+        dwarf_get_DS_name;
+        dwarf_get_DSC_name;
+        dwarf_get_EH_name;
         dwarf_get_elf;
+        dwarf_get_END_name;
         dwarf_get_fde_at_pc;
+        dwarf_get_fde_augmentation_data;
         dwarf_get_fde_exception_info;
         dwarf_get_fde_for_die;
         dwarf_get_fde_info_for_all_regs;
+        dwarf_get_fde_info_for_all_regs3;
+        dwarf_get_fde_info_for_cfa_reg3;
         dwarf_get_fde_info_for_reg;
+        dwarf_get_fde_info_for_reg3;
         dwarf_get_fde_instr_bytes;
         dwarf_get_fde_list;
         dwarf_get_fde_list_eh;
         dwarf_get_fde_n;
         dwarf_get_fde_range;
+        dwarf_get_form_class;
+        dwarf_get_FORM_name;
+        dwarf_get_FRAME_name;
         dwarf_get_funcs;
         dwarf_get_globals;
+        dwarf_get_harmless_error_list;
+        dwarf_get_ID_name;
+        dwarf_get_INL_name;
+        dwarf_get_ISA_name;
+        dwarf_get_LANG_name;
+        dwarf_get_LNE_name;
+        dwarf_get_LNS_name;
         dwarf_get_loclist_entry;
+        dwarf_get_MACINFO_name;
         dwarf_get_macro_details;
+        dwarf_get_OP_name;
+        dwarf_get_ORD_name;
+        dwarf_get_pubtypes;
+        dwarf_get_ranges;
+        dwarf_get_ranges_a;
         dwarf_get_relocation_info;
         dwarf_get_relocation_info_count;
         dwarf_get_section_bytes;
+        dwarf_get_section_max_offsets;
         dwarf_get_str;
+        dwarf_get_string_attributes_count;
+        dwarf_get_string_attributes_info;
+        dwarf_get_TAG_name;
         dwarf_get_types;
         dwarf_get_vars;
+        dwarf_get_VIRTUALITY_name;
+        dwarf_get_VIS_name;
         dwarf_get_weaks;
         dwarf_global_cu_offset;
         dwarf_global_die_offset;
         dwarf_global_formref;
         dwarf_global_name_offsets;
+        dwarf_globals_dealloc;
         dwarf_globname;
+        dwarf_harmless_cleanout;
+        dwarf_harmless_init;
         dwarf_hasattr;
         dwarf_hasform;
         dwarf_highpc;
         dwarf_init;
+        dwarf_init_line_table_prefix;
+        dwarf_insert_fde_inst_bytes;
+        dwarf_insert_harmless_error;
+        dwarf_ld_sort_lines;
+        dwarf_line_srcfileno;
         dwarf_lineaddr;
         dwarf_linebeginstatement;
         dwarf_lineblock;
@@ -155,25 +231,48 @@
         dwarf_lne_end_sequence;
         dwarf_lne_set_address;
         dwarf_loclist;
+        dwarf_loclist_from_expr;
+        dwarf_loclist_from_expr_a;
         dwarf_loclist_n;
         dwarf_lowpc;
         dwarf_new_die;
         dwarf_new_expr;
         dwarf_new_fde;
         dwarf_next_cu_header;
+        dwarf_next_cu_header_b;
         dwarf_nextglob;
+        dwarf_object_finish;
+        dwarf_object_init;
         dwarf_offdie;
         dwarf_p_dealloc;
+        dwarf_print_lines;
         dwarf_print_memory_stats;
         dwarf_producer_finish;
         dwarf_producer_init;
         dwarf_producer_init_b;
+        dwarf_pubtype_cu_offset;
+        dwarf_pubtype_name_offsets;
+        dwarf_pubtype_type_die_offset;
+        dwarf_pubtypename;
+        dwarf_pubtypes_dealloc;
+        dwarf_ranges_dealloc;
+        dwarf_read_cie_fde_prefix;
+        dwarf_read_line_table_prefix;
         dwarf_reset_section_bytes;
+        dwarf_set_frame_cfa_value;
+        dwarf_set_frame_rule_inital_value;
+        dwarf_set_frame_rule_initial_value;
+        dwarf_set_frame_rule_table_size;
+        dwarf_set_frame_same_value;
+        dwarf_set_frame_undefined_value;
+        dwarf_set_harmless_error_list_size;
+        dwarf_set_reloc_application;
         dwarf_set_stringcheck;
         dwarf_siblingof;
         dwarf_srcfiles;
         dwarf_srclang;
         dwarf_srclines;
+        dwarf_srclines_dealloc;
         dwarf_start_macro_file;
         dwarf_tag;
         dwarf_transform_to_disk_form;
@@ -181,16 +280,20 @@
         dwarf_type_die_offset;
         dwarf_type_name_offsets;
         dwarf_typename;
+        dwarf_types_dealloc;
+        dwarf_uncompress_integer_block;
         dwarf_undef_macro;
         dwarf_var_cu_offset;
         dwarf_var_die_offset;
         dwarf_var_name_offsets;
         dwarf_varname;
+        dwarf_vars_dealloc;
         dwarf_vendor_ext;
         dwarf_weak_cu_offset;
         dwarf_weak_die_offset;
         dwarf_weak_name_offsets;
         dwarf_weakname;
+        dwarf_weaks_dealloc;
         dwarf_whatattr;
         dwarf_whatform;
         dwarf_whatform_direct;
--- a/usr/src/tools/ctf/dwarf/common/pro_alloc.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_alloc.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
   Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -36,36 +37,152 @@
 
 
 #include "config.h"
-#include "dwarf_incl.h"
+#include "pro_incl.h"
+#ifdef HAVE_STDLIB_H
 #include <stdlib.h>
+#endif /* HAVE_STDLIB_H */
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#include <malloc.h>
+
+/*
+ When each block is allocated, there is a two-word structure
+ allocated at the beginning so the block can go on a list.
+ The address returned is the address *after* the two pointers
+ at the start.  But this allows us to be given a pointer to
+ a generic block, and go backwards to find the list-node.  Then
+ we can remove this block from it's list without the need to search
+ through a linked list in order to remove the node.  It also allows
+ us to 'delete' a memory block without needing the dbg structure.
+ We still need the dbg structure on allocation so that we know which
+ linked list to add the block to.
+
+ Only the allocation of the dbg structure itself cannot use _dwarf_p_get_alloc.
+ That structure should be set up by hand, and the two list pointers
+ should be initialized to point at the node itself.  That initializes
+ the doubly linked list.
+*/
+
+#define LIST_TO_BLOCK(lst) ((void*) (((char *)lst) + sizeof(memory_list_t)))
+#define BLOCK_TO_LIST(blk) ((memory_list_t*) (((char*)blk) - sizeof(memory_list_t)))
+
 
 /*
-	The allocator wants to know which region
-	this is to be in so it can allocate the new space
-	with respect to the right region.
+  dbg should be NULL only when allocating dbg itself.  In that
+  case we initialize it to an empty circular doubly-linked list.
 */
- /*ARGSUSED*/
-    Dwarf_Ptr _dwarf_p_get_alloc(Dwarf_P_Debug dbg, Dwarf_Unsigned size)
+
+Dwarf_Ptr
+_dwarf_p_get_alloc(Dwarf_P_Debug dbg, Dwarf_Unsigned size)
 {
     void *sp;
+    memory_list_t *lp = NULL;
+    memory_list_t *dbglp = NULL;
+    memory_list_t *nextblock = NULL;
 
-    sp = malloc(size);
-    memset(sp,0, (int) size);
+    /* alloc control struct and data block together for performance reasons */
+    lp = (memory_list_t *) malloc(size + sizeof(memory_list_t));
+    if (lp == NULL) {
+        /* should throw an error */
+        return NULL;
+    }
+    
+    /* point to 'size' bytes just beyond lp struct */
+    sp = LIST_TO_BLOCK(lp);
+    memset(sp, 0, size);
+
+    if (dbg == NULL) {
+        lp->next = lp->prev = lp;
+    } else {
+        /* I always have to draw a picture to understand this part. */
+
+        dbglp = BLOCK_TO_LIST(dbg);
+        nextblock = dbglp->next;
+        
+        /* Insert between dbglp and nextblock */
+        dbglp->next = lp;
+        lp->prev = dbglp;
+        lp->next = nextblock;
+        nextblock->prev = lp;
+    }
+
     return sp;
 }
 
+/*
+  This routine is only here in case a caller of an older version of the
+  library is calling this for some reason.
+  We will clean up any stray blocks when the session is closed.
+  No need to remove this block.  In theory the user might be 
+  depending on the fact that we used to just 'free' this.  
+  In theory they might also be
+  passing a block that they got from libdwarf.  So we don't know if we
+  should try to remove this block from our global list.  Safest just to
+  do nothing at this point.
 
- /*ARGSUSED*/ void
-dwarf_p_dealloc(void *space, Dwarf_Unsigned typ)
+  !!!
+  This function is deprecated!  Don't call it inside libdwarf or outside of it.
+  !!!
+*/
+       
+void
+dwarf_p_dealloc(Dwarf_Small * ptr)
 {
-    free(space);
     return;
 }
 
+/*
+  The dbg structure is not needed here anymore.
+*/
 
-/* Essentially a stub for now. */
- /*ARGSUSED*/ void
-_dwarf_p_dealloc(Dwarf_P_Debug dbg, Dwarf_Small * ptr)
+void
+_dwarf_p_dealloc(Dwarf_P_Debug dbg, Dwarf_Small * ptr) /* ARGSUSED */
 {
-    dwarf_p_dealloc(ptr, DW_DLA_STRING);
+  memory_list_t *lp;
+  lp = BLOCK_TO_LIST(ptr);
+
+  /*
+    Remove from a doubly linked, circular list.
+    Read carefully, use a white board if necessary.
+    If this is an empty list, the following statements are no-ops, and
+    will write to the same memory location they read from.
+    This should only happen when we deallocate the dbg structure itself.
+  */
+  
+  lp->prev->next = lp->next;
+  lp->next->prev = lp->prev;
+
+  free((void*)lp);
 }
+
+
+/*
+  This routine deallocates all the nodes on the dbg list,
+  and then deallocates the dbg structure itself.
+*/
+
+void
+_dwarf_p_dealloc_all(Dwarf_P_Debug dbg)
+{
+    memory_list_t *dbglp;
+
+    if (dbg == NULL) {
+        /* should throw an error */
+        return;
+    }
+    
+    dbglp = BLOCK_TO_LIST(dbg);
+    while (dbglp->next != dbglp) {
+        _dwarf_p_dealloc(dbg, LIST_TO_BLOCK(dbglp->next));
+    }
+    if (dbglp->next != dbglp ||
+        dbglp->prev != dbglp) {
+
+        /* should throw error */
+        /* For some reason we couldn't free all the blocks? */
+        return;
+    }
+    _dwarf_p_dealloc(NULL, (void*)dbg);
+}
+
--- a/usr/src/tools/ctf/dwarf/common/pro_alloc.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_alloc.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -38,3 +38,5 @@
 Dwarf_Ptr _dwarf_p_get_alloc(Dwarf_P_Debug, Dwarf_Unsigned);
 
 void _dwarf_p_dealloc(Dwarf_P_Debug dbg, Dwarf_Small * ptr);
+
+void _dwarf_p_dealloc_all(Dwarf_P_Debug dbg);
--- a/usr/src/tools/ctf/dwarf/common/pro_arange.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_arange.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +19,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -57,14 +57,14 @@
 */
 Dwarf_Unsigned
 dwarf_add_arange(Dwarf_P_Debug dbg,
-		 Dwarf_Addr begin_address,
-		 Dwarf_Unsigned length,
-		 Dwarf_Signed symbol_index, Dwarf_Error * error)
+                 Dwarf_Addr begin_address,
+                 Dwarf_Unsigned length,
+                 Dwarf_Signed symbol_index, Dwarf_Error * error)
 {
     return dwarf_add_arange_b(dbg, begin_address, length, symbol_index,
-			      /* end_symbol_index */ 0,
-			      /* offset_from_end_sym */ 0,
-			      error);
+                              /* end_symbol_index */ 0,
+                              /* offset_from_end_sym */ 0,
+                              error);
 }
 
 /*
@@ -75,24 +75,24 @@
 */
 Dwarf_Unsigned
 dwarf_add_arange_b(Dwarf_P_Debug dbg,
-		   Dwarf_Addr begin_address,
-		   Dwarf_Unsigned length,
-		   Dwarf_Unsigned symbol_index,
-		   Dwarf_Unsigned end_symbol_index,
-		   Dwarf_Addr offset_from_end_sym, Dwarf_Error * error)
+                   Dwarf_Addr begin_address,
+                   Dwarf_Unsigned length,
+                   Dwarf_Unsigned symbol_index,
+                   Dwarf_Unsigned end_symbol_index,
+                   Dwarf_Addr offset_from_end_sym, Dwarf_Error * error)
 {
     Dwarf_P_Arange arange;
 
     if (dbg == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
-	return (0);
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return (0);
     }
 
     arange = (Dwarf_P_Arange)
-	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Arange_s));
+        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Arange_s));
     if (arange == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (0);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (0);
     }
 
     arange->ag_begin_address = begin_address;
@@ -102,10 +102,10 @@
     arange->ag_end_symbol_offset = offset_from_end_sym;
 
     if (dbg->de_arange == NULL)
-	dbg->de_arange = dbg->de_last_arange = arange;
+        dbg->de_arange = dbg->de_last_arange = arange;
     else {
-	dbg->de_last_arange->ag_next = arange;
-	dbg->de_last_arange = arange;
+        dbg->de_last_arange->ag_next = arange;
+        dbg->de_last_arange = arange;
     }
     dbg->de_arange_count++;
 
@@ -148,15 +148,15 @@
     /* ***** BEGIN CODE ***** */
 
     /* Size of the .debug_aranges section header. */
-    arange_num_bytes = extension_word_size + uword_size +	/* Size 
-								   of
-								   length 
-								   field. 
-								 */
-	sizeof(Dwarf_Half) +	/* Size of version field. */
-	uword_size +		/* Size of .debug_info offset. */
-	sizeof(Dwarf_Small) +	/* Size of address size field. */
-	sizeof(Dwarf_Small);	/* Size of segment size field. */
+    arange_num_bytes = extension_word_size + uword_size +       /* Size 
+                                                                   of
+                                                                   length 
+                                                                   field. 
+                                                                 */
+        sizeof(Dwarf_Half) +    /* Size of version field. */
+        uword_size +            /* Size of .debug_info offset. */
+        sizeof(Dwarf_Small) +   /* Size of address size field. */
+        sizeof(Dwarf_Small);    /* Size of segment size field. */
 
     /* 
        Adjust the size so that the set of aranges begins on a boundary
@@ -164,82 +164,82 @@
        requirement. */
     remainder = arange_num_bytes % (2 * upointer_size);
     if (remainder != 0)
-	arange_num_bytes += (2 * upointer_size) - remainder;
+        arange_num_bytes += (2 * upointer_size) - remainder;
 
 
     /* Add the bytes for the actual address ranges. */
     arange_num_bytes += upointer_size * 2 * (dbg->de_arange_count + 1);
 
     GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_ARANGES],
-	      arange, (unsigned long) arange_num_bytes, error);
+              arange, (unsigned long) arange_num_bytes, error);
     arange_ptr = arange;
     if (arange == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (0);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (0);
     }
     if (extension_word_size) {
-	Dwarf_Word x = DISTINGUISHED_VALUE;
+        Dwarf_Word x = DISTINGUISHED_VALUE;
 
-	WRITE_UNALIGNED(dbg, (void *) arange_ptr,
-			(const void *) &x,
-			sizeof(x), extension_word_size);
-	arange_ptr += extension_word_size;
+        WRITE_UNALIGNED(dbg, (void *) arange_ptr,
+                        (const void *) &x,
+                        sizeof(x), extension_word_size);
+        arange_ptr += extension_word_size;
     }
 
     /* Write the total length of .debug_aranges section. */
     adjusted_length = arange_num_bytes - uword_size
-	- extension_word_size;
+        - extension_word_size;
     {
-	Dwarf_Unsigned du = adjusted_length;
+        Dwarf_Unsigned du = adjusted_length;
 
-	WRITE_UNALIGNED(dbg, (void *) arange_ptr,
-			(const void *) &du, sizeof(du), uword_size);
-	arange_ptr += uword_size;
+        WRITE_UNALIGNED(dbg, (void *) arange_ptr,
+                        (const void *) &du, sizeof(du), uword_size);
+        arange_ptr += uword_size;
     }
 
     /* Write the version as 2 bytes. */
     {
-	Dwarf_Half verstamp = CURRENT_VERSION_STAMP;
+        Dwarf_Half verstamp = CURRENT_VERSION_STAMP;
 
-	WRITE_UNALIGNED(dbg, (void *) arange_ptr,
-			(const void *) &verstamp,
-			sizeof(verstamp), sizeof(Dwarf_Half));
-	arange_ptr += sizeof(Dwarf_Half);
+        WRITE_UNALIGNED(dbg, (void *) arange_ptr,
+                        (const void *) &verstamp,
+                        sizeof(verstamp), sizeof(Dwarf_Half));
+        arange_ptr += sizeof(Dwarf_Half);
     }
 
 
     /* Write the .debug_info offset.  This is always 0. */
     WRITE_UNALIGNED(dbg, (void *) arange_ptr,
-		    (const void *) &big_zero,
-		    sizeof(big_zero), uword_size);
+                    (const void *) &big_zero,
+                    sizeof(big_zero), uword_size);
     arange_ptr += uword_size;
 
     {
-	unsigned long count = dbg->de_arange_count + 1;
-	int res;
+        unsigned long count = dbg->de_arange_count + 1;
+        int res;
 
-	if (dbg->de_reloc_pair) {
-	    count = (3 * dbg->de_arange_count) + 1;
-	}
-	/* the following is a small optimization: not needed for
-	   correctness */
-	res = _dwarf_pro_pre_alloc_n_reloc_slots(dbg,
-						 DEBUG_ARANGES, count);
-	if (res != DW_DLV_OK) {
-	    {
-		_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-		return (0);
-	    }
-	}
+        if (dbg->de_reloc_pair) {
+            count = (3 * dbg->de_arange_count) + 1;
+        }
+        /* the following is a small optimization: not needed for
+           correctness */
+        res = _dwarf_pro_pre_alloc_n_reloc_slots(dbg,
+                                                 DEBUG_ARANGES, count);
+        if (res != DW_DLV_OK) {
+            {
+                _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+                return (0);
+            }
+        }
     }
 
     /* reloc for .debug_info */
     res = dbg->de_reloc_name(dbg,
-			     DEBUG_ARANGES,
-			     extension_word_size +
-			     uword_size + sizeof(Dwarf_Half),
-			     dbg->de_sect_name_idx[DEBUG_INFO],
-			     dwarf_drt_data_reloc, uword_size);
+                             DEBUG_ARANGES,
+                             extension_word_size +
+                             uword_size + sizeof(Dwarf_Half),
+                             dbg->de_sect_name_idx[DEBUG_INFO],
+                             dwarf_drt_data_reloc, uword_size);
 
     /* Write the size of addresses. */
     *arange_ptr = dbg->de_pointer_size;
@@ -255,7 +255,7 @@
        Skip over the padding to align the start of the actual address
        ranges to twice the address size. */
     if (remainder != 0)
-	arange_ptr += (2 * upointer_size) - remainder;
+        arange_ptr += (2 * upointer_size) - remainder;
 
 
 
@@ -264,73 +264,74 @@
     /* The arange address, length are pointer-size fields of the target 
        machine. */
     for (given_arange = dbg->de_arange; given_arange != NULL;
-	 given_arange = given_arange->ag_next) {
+         given_arange = given_arange->ag_next) {
 
-	/* Write relocation record for beginning of address range. */
-	res = dbg->de_reloc_name(dbg, DEBUG_ARANGES, arange_ptr - arange,	/* r_offset */
-				 (long) given_arange->ag_symbol_index,
-				 dwarf_drt_data_reloc, upointer_size);
-	if (res != DW_DLV_OK) {
-	    {
-		_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-		return (0);
-	    }
-	}
+        /* Write relocation record for beginning of address range. */
+        res = dbg->de_reloc_name(dbg, DEBUG_ARANGES, arange_ptr - arange,       /* r_offset 
+                                                                                 */
+                                 (long) given_arange->ag_symbol_index,
+                                 dwarf_drt_data_reloc, upointer_size);
+        if (res != DW_DLV_OK) {
+            {
+                _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+                return (0);
+            }
+        }
 
-	/* Copy beginning address of range. */
-	WRITE_UNALIGNED(dbg, (void *) arange_ptr,
-			(const void *) &given_arange->ag_begin_address,
-			sizeof(given_arange->ag_begin_address),
-			upointer_size);
-	arange_ptr += upointer_size;
+        /* Copy beginning address of range. */
+        WRITE_UNALIGNED(dbg, (void *) arange_ptr,
+                        (const void *) &given_arange->ag_begin_address,
+                        sizeof(given_arange->ag_begin_address),
+                        upointer_size);
+        arange_ptr += upointer_size;
 
-	if (dbg->de_reloc_pair &&
-	    given_arange->ag_end_symbol_index != 0 &&
-	    given_arange->ag_length == 0) {
-	    /* symbolic reloc, need reloc for length What if we really 
-	       know the length? If so, should use the other part of
-	       'if'. */
-	    Dwarf_Unsigned val;
+        if (dbg->de_reloc_pair &&
+            given_arange->ag_end_symbol_index != 0 &&
+            given_arange->ag_length == 0) {
+            /* symbolic reloc, need reloc for length What if we really
+               know the length? If so, should use the other part of
+               'if'. */
+            Dwarf_Unsigned val;
 
-	    res = dbg->de_reloc_pair(dbg, DEBUG_ARANGES, arange_ptr - arange,	/* r_offset 
-										 */
-				     given_arange->ag_symbol_index,
-				     given_arange->ag_end_symbol_index,
-				     dwarf_drt_first_of_length_pair,
-				     upointer_size);
-	    if (res != DW_DLV_OK) {
-		{
-		    _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-		    return (0);
-		}
-	    }
+            res = dbg->de_reloc_pair(dbg, DEBUG_ARANGES, arange_ptr - arange,   /* r_offset 
+                                                                                 */
+                                     given_arange->ag_symbol_index,
+                                     given_arange->ag_end_symbol_index,
+                                     dwarf_drt_first_of_length_pair,
+                                     upointer_size);
+            if (res != DW_DLV_OK) {
+                {
+                    _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+                    return (0);
+                }
+            }
 
-	    /* arrange pre-calc so assem text can do .word end - begin
-	       + val (gets val from stream) */
-	    val = given_arange->ag_end_symbol_offset -
-		given_arange->ag_begin_address;
-	    WRITE_UNALIGNED(dbg, (void *) arange_ptr,
-			    (const void *) &val,
-			    sizeof(val), upointer_size);
-	    arange_ptr += upointer_size;
+            /* arrange pre-calc so assem text can do .word end - begin
+               + val (gets val from stream) */
+            val = given_arange->ag_end_symbol_offset -
+                given_arange->ag_begin_address;
+            WRITE_UNALIGNED(dbg, (void *) arange_ptr,
+                            (const void *) &val,
+                            sizeof(val), upointer_size);
+            arange_ptr += upointer_size;
 
-	} else {
-	    /* plain old length to copy, no relocation at all */
-	    WRITE_UNALIGNED(dbg, (void *) arange_ptr,
-			    (const void *) &given_arange->ag_length,
-			    sizeof(given_arange->ag_length),
-			    upointer_size);
-	    arange_ptr += upointer_size;
-	}
+        } else {
+            /* plain old length to copy, no relocation at all */
+            WRITE_UNALIGNED(dbg, (void *) arange_ptr,
+                            (const void *) &given_arange->ag_length,
+                            sizeof(given_arange->ag_length),
+                            upointer_size);
+            arange_ptr += upointer_size;
+        }
     }
 
     WRITE_UNALIGNED(dbg, (void *) arange_ptr,
-		    (const void *) &big_zero,
-		    sizeof(big_zero), upointer_size);
+                    (const void *) &big_zero,
+                    sizeof(big_zero), upointer_size);
 
     arange_ptr += upointer_size;
     WRITE_UNALIGNED(dbg, (void *) arange_ptr,
-		    (const void *) &big_zero,
-		    sizeof(big_zero), upointer_size);
+                    (const void *) &big_zero,
+                    sizeof(big_zero), upointer_size);
     return (int) dbg->de_n_debug_sect;
 }
--- a/usr/src/tools/ctf/dwarf/common/pro_arange.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_arange.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
--- a/usr/src/tools/ctf/dwarf/common/pro_die.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_die.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -50,121 +51,170 @@
 void _dwarf_pro_add_at_to_die(Dwarf_P_Die die, Dwarf_P_Attribute attr);
 
 /*----------------------------------------------------------------------------
-	This function creates a new die. 
-	tag: tag of the new die to be created
-	parent,child,left,right: specify neighbors of the new die. Only
-	    one of these may be non-null
+    This function creates a new die. 
+    tag: tag of the new die to be created
+    parent,child,left,right: specify neighbors of the new die. Only
+    one of these may be non-null
 -----------------------------------------------------------------------------*/
 Dwarf_P_Die
 dwarf_new_die(Dwarf_P_Debug dbg,
-	      Dwarf_Tag tag,
-	      Dwarf_P_Die parent,
-	      Dwarf_P_Die child,
-	      Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error)
+      Dwarf_Tag tag,
+      Dwarf_P_Die parent,
+      Dwarf_P_Die child,
+      Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error)
 {
-    Dwarf_P_Die new_die, ret_die;
+    Dwarf_P_Die ret_die = 0;
 
-    new_die = (Dwarf_P_Die)
-	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Die_s));
+    Dwarf_P_Die new_die = (Dwarf_P_Die)
+        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Die_s));
     if (new_die == NULL) {
-	DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_ALLOC,
-			  (Dwarf_P_Die) DW_DLV_BADADDR);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_ALLOC,
+            (Dwarf_P_Die) DW_DLV_BADADDR);
     }
     new_die->di_parent = NULL;
     new_die->di_left = NULL;
     new_die->di_right = NULL;
     new_die->di_child = NULL;
+    new_die->di_last_child = NULL;
     new_die->di_tag = tag;
-    ret_die =
-	dwarf_die_link(new_die, parent, child, left, right, error);
+    new_die->di_dbg = dbg;
+    new_die->di_marker = 0;
+    ret_die = 
+        dwarf_die_link(new_die, parent, child, left, right, error);
     return ret_die;
 }
 
 /*----------------------------------------------------------------------------
-	This function links up a die to specified neighbors
-	parent,child,left,right: specify neighbors of the new die. Only
-	    one of these may be non-null
+    This function links up a die to specified neighbors
+    parent,child,left,right: specify neighbors of the new die. Only
+    one of these may be non-null
 -----------------------------------------------------------------------------*/
 Dwarf_P_Die
 dwarf_die_link(Dwarf_P_Die new_die,
-	       Dwarf_P_Die parent,
-	       Dwarf_P_Die child,
-	       Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error)
+       Dwarf_P_Die parent,
+       Dwarf_P_Die child,
+       Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error)
 {
-    int n_nulls;		/* to count # of non null neighbors */
+    /* Count the # of non null neighbors. */
+    int n_nulls = 0;  
 
-    n_nulls = 0;
     if (parent != NULL) {
-	n_nulls++;
-	new_die->di_parent = parent;
-	if (parent->di_child) {	/* got to traverse the child's siblings 
-				 */
-	    Dwarf_P_Die curdie;
+        n_nulls++;
+        if (new_die->di_parent != NULL) {
+              DWARF_P_DBG_ERROR(NULL, DW_DLE_LINK_LOOP,
+                    (Dwarf_P_Die) DW_DLV_BADADDR);
+        }
+        new_die->di_parent = parent;
+        if (parent->di_child) {
 
-	    curdie = parent->di_child;
-	    while (curdie->di_right)
-		curdie = curdie->di_right;
-	    curdie->di_right = new_die;	/* attach to sibling list */
-	    new_die->di_left = curdie;	/* back pointer */
-	} else
-	    parent->di_child = new_die;
+            /* di_last_child identifies the last sibling, the
+               die we want to attach new_die to. */
+            /* ASSERT: if di_child is set so is di_last_child. */
+            Dwarf_P_Die former_lastchild = parent->di_last_child;
+            parent->di_last_child = new_die;
+            /* Attach to  the new die to end of the sibling list. */
+            former_lastchild->di_right = new_die;
+            new_die->di_left = former_lastchild;
+        } else {
+            parent->di_child = new_die;
+            parent->di_last_child = new_die;
+        }
     }
     if (child != NULL) {
-	n_nulls++;
-	new_die->di_child = child;
-	if (child->di_parent) {
-	    DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS,
-			      (Dwarf_P_Die) DW_DLV_BADADDR);
-	} else
-	    child->di_parent = new_die;
+        n_nulls++;
+        new_die->di_child = child;
+        new_die->di_last_child = child;
+        if (child->di_parent) {
+            DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS,
+                              (Dwarf_P_Die) DW_DLV_BADADDR);
+        } else {
+            child->di_parent = new_die;
+        }
     }
     if (left != NULL) {
-	n_nulls++;
-	new_die->di_left = left;
-	if (left->di_right)	/* there's already a right sibl, lets
-				   insert */
-	    new_die->di_right = left->di_right;
-	left->di_right = new_die;
-	/* add parent pointer */
-	if (new_die->di_parent) {
-	    DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS,
-			      (Dwarf_P_Die) DW_DLV_BADADDR);
-	} else
-	    new_die->di_parent = left->di_parent;
+        n_nulls++;
+        new_die->di_left = left;
+        if (left->di_right) { 
+            /* There's already a right sibling of left, 
+               insert the new die in the list. */ 
+            new_die->di_right = left->di_right;
+            left->di_right->di_left = new_die;
+        }
+        left->di_right = new_die;
+        if (new_die->di_parent) {
+            DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS,
+                              (Dwarf_P_Die) DW_DLV_BADADDR);
+        } else {
+            new_die->di_parent = left->di_parent;
+        }
     }
     if (right != NULL) {
-	n_nulls++;
-	new_die->di_right = right;
-	if (right->di_left)	/* left sibl exists, try inserting */
-	    new_die->di_left = right->di_left;
-	right->di_left = new_die;
-	if (new_die->di_parent) {
-	    DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS,
-			      (Dwarf_P_Die) DW_DLV_BADADDR);
-	} else
-	    new_die->di_parent = right->di_parent;
+        n_nulls++;
+        new_die->di_right = right;
+        if (right->di_left) {
+            /* There is already a left sibling of the right die,
+               insert the new die in the list.  */
+            new_die->di_left = right->di_left;
+            right->di_left->di_right = new_die;
+        }
+        right->di_left = new_die;
+        if (new_die->di_parent) {
+             DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS,
+                              (Dwarf_P_Die) DW_DLV_BADADDR);
+         } else {
+             new_die->di_parent = right->di_parent;
+        }
     }
-    if (n_nulls > 1) {		/* multiple neighbors, error */
-	DWARF_P_DBG_ERROR(NULL, DW_DLE_EXTRA_NEIGHBORS,
-			  (Dwarf_P_Die) DW_DLV_BADADDR);
+    if (n_nulls > 1) { 
+         /* Multiple neighbors! error! */
+         DWARF_P_DBG_ERROR(NULL, DW_DLE_EXTRA_NEIGHBORS,
+             (Dwarf_P_Die) DW_DLV_BADADDR);
     }
     return new_die;
 
 }
 
+Dwarf_Unsigned
+dwarf_add_die_marker(Dwarf_P_Debug dbg,
+    Dwarf_P_Die die,
+    Dwarf_Unsigned marker,
+    Dwarf_Error * error)
+{
+    if (die == NULL) {
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT);
+    }
+    die->di_marker = marker;
+    return 0;
+}
+
+
+Dwarf_Unsigned
+dwarf_get_die_marker(Dwarf_P_Debug dbg,
+     Dwarf_P_Die die,
+     Dwarf_Unsigned * marker,
+     Dwarf_Error * error)
+{
+    if (die == NULL) {
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT);
+    }
+    *marker = die->di_marker;
+    return 0;
+}
+
+
 /*----------------------------------------------------------------------------
-	This function adds a die to dbg struct. It should be called using 
-	the root of all the dies.
+    This function adds a die to dbg struct. It should be called using 
+    the root of all the dies.
 -----------------------------------------------------------------------------*/
 Dwarf_Unsigned
 dwarf_add_die_to_debug(Dwarf_P_Debug dbg,
-		       Dwarf_P_Die first_die, Dwarf_Error * error)
+     Dwarf_P_Die first_die, Dwarf_Error * error)
 {
     if (first_die == NULL) {
-	DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT);
     }
     if (first_die->di_tag != DW_TAG_compile_unit) {
-	DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_TAG, DW_DLV_NOCOUNT);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_TAG, DW_DLV_NOCOUNT);
     }
     dbg->de_dies = first_die;
     return 0;
@@ -172,16 +222,16 @@
 
 int
 _dwarf_pro_add_AT_stmt_list(Dwarf_P_Debug dbg,
-			    Dwarf_P_Die first_die, Dwarf_Error * error)
+    Dwarf_P_Die first_die, Dwarf_Error * error)
 {
     Dwarf_P_Attribute new_attr;
     int uwordb_size = dbg->de_offset_size;
 
     /* Add AT_stmt_list attribute */
     new_attr = (Dwarf_P_Attribute)
-	_dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Attribute_s));
+        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
     if (new_attr == NULL) {
-	DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_NOCOUNT);
+         DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_NOCOUNT);
     }
 
     new_attr->ar_attribute = DW_AT_stmt_list;
@@ -192,15 +242,15 @@
     new_attr->ar_next = NULL;
     new_attr->ar_reloc_len = uwordb_size;
     new_attr->ar_data = (char *)
-	_dwarf_p_get_alloc(NULL, uwordb_size);
+        _dwarf_p_get_alloc(dbg, uwordb_size);
     if (new_attr->ar_data == NULL) {
-	DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT);
+        DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT);
     }
     {
-	Dwarf_Unsigned du = 0;
+       Dwarf_Unsigned du = 0;
 
-	WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data,
-			(const void *) &du, sizeof(du), uwordb_size);
+       WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data,
+           (const void *) &du, sizeof(du), uwordb_size);
     }
 
     _dwarf_pro_add_at_to_die(first_die, new_attr);
@@ -208,7 +258,7 @@
 }
 
 /*-----------------------------------------------------------------------------
-	Add AT_name attribute to die
+    Add AT_name attribute to die
 ------------------------------------------------------------------------------*/
 Dwarf_P_Attribute
 dwarf_add_AT_name(Dwarf_P_Die die, char *name, Dwarf_Error * error)
@@ -216,14 +266,14 @@
     Dwarf_P_Attribute new_attr;
 
     if (die == NULL) {
-	DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL,
-			  (Dwarf_P_Attribute) DW_DLV_BADADDR);
+        DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL,
+           (Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
     new_attr = (Dwarf_P_Attribute)
-	_dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Attribute_s));
+        _dwarf_p_get_alloc(die->di_dbg,sizeof(struct Dwarf_P_Attribute_s));
     if (new_attr == NULL) {
-	DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC,
-			  (Dwarf_P_Attribute) DW_DLV_BADADDR);
+        DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC,
+            (Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     /* fill in the information */
@@ -234,10 +284,10 @@
     new_attr->ar_next = NULL;
     new_attr->ar_reloc_len = 0;
     new_attr->ar_data = (char *)
-	_dwarf_p_get_alloc(NULL, strlen(name) + 1);
+        _dwarf_p_get_alloc(die->di_dbg, strlen(name)+1);
     if (new_attr->ar_data == NULL) {
-	DWARF_P_DBG_ERROR(NULL, DW_DLE_STRING_ALLOC,
-			  (Dwarf_P_Attribute) DW_DLV_BADADDR);
+        DWARF_P_DBG_ERROR(NULL, DW_DLE_STRING_ALLOC,
+            (Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
     strcpy(new_attr->ar_data, name);
 
@@ -250,24 +300,25 @@
 
 
 /*-----------------------------------------------------------------------------
-	Add AT_comp_dir attribute to die
+    Add AT_comp_dir attribute to die
 ------------------------------------------------------------------------------*/
 Dwarf_P_Attribute
 dwarf_add_AT_comp_dir(Dwarf_P_Die ownerdie,
-		      char *current_working_directory,
-		      Dwarf_Error * error)
+    char *current_working_directory,
+    Dwarf_Error * error)
 {
     Dwarf_P_Attribute new_attr;
 
     if (ownerdie == NULL) {
-	DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL,
-			  (Dwarf_P_Attribute) DW_DLV_BADADDR);
+        DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL,
+            (Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
     new_attr = (Dwarf_P_Attribute)
-	_dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Attribute_s));
+        _dwarf_p_get_alloc(ownerdie->di_dbg,
+        sizeof(struct Dwarf_P_Attribute_s));
     if (new_attr == NULL) {
-	DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC,
-			  (Dwarf_P_Attribute) DW_DLV_BADADDR);
+        DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC,
+            (Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     /* fill in the information */
@@ -278,10 +329,11 @@
     new_attr->ar_next = NULL;
     new_attr->ar_reloc_len = 0;
     new_attr->ar_data = (char *)
-	_dwarf_p_get_alloc(NULL, strlen(current_working_directory) + 1);
+        _dwarf_p_get_alloc(ownerdie->di_dbg, 
+        strlen(current_working_directory)+1);
     if (new_attr->ar_data == NULL) {
-	DWARF_P_DBG_ERROR(NULL, DW_DLE_STRING_ALLOC,
-			  (Dwarf_P_Attribute) DW_DLV_BADADDR);
+        DWARF_P_DBG_ERROR(NULL, DW_DLE_STRING_ALLOC,
+            (Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
     strcpy(new_attr->ar_data, current_working_directory);
 
@@ -294,19 +346,19 @@
 
 int
 _dwarf_pro_add_AT_fde(Dwarf_P_Debug dbg,
-		      Dwarf_P_Die die,
-		      Dwarf_Unsigned offset, Dwarf_Error * error)
+    Dwarf_P_Die die,
+    Dwarf_Unsigned offset, Dwarf_Error * error)
 {
     Dwarf_P_Attribute new_attr;
     int uwordb_size = dbg->de_offset_size;
 
     if (die == NULL) {
-	DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, -1);
+        DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, -1);
     }
     new_attr = (Dwarf_P_Attribute)
-	_dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Attribute_s));
+        _dwarf_p_get_alloc(dbg,sizeof(struct Dwarf_P_Attribute_s));
     if (new_attr == NULL) {
-	DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, -1);
+        DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, -1);
     }
 
     /* fill in the information */
@@ -317,15 +369,15 @@
     new_attr->ar_next = NULL;
     new_attr->ar_reloc_len = uwordb_size;
     new_attr->ar_data = (char *)
-	_dwarf_p_get_alloc(NULL, uwordb_size);
+        _dwarf_p_get_alloc(dbg, uwordb_size);
     if (new_attr->ar_data == NULL) {
-	DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT);
+        DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT);
     }
     {
-	Dwarf_Unsigned du = offset;
+        Dwarf_Unsigned du = offset;
 
-	WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data,
-			(const void *) &du, sizeof(du), uwordb_size);
+        WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data,
+            (const void *) &du, sizeof(du), uwordb_size);
     }
 
     _dwarf_pro_add_at_to_die(die, new_attr);
@@ -335,19 +387,19 @@
 
 int
 _dwarf_pro_add_AT_macro_info(Dwarf_P_Debug dbg,
-			     Dwarf_P_Die die,
-			     Dwarf_Unsigned offset, Dwarf_Error * error)
+    Dwarf_P_Die die,
+    Dwarf_Unsigned offset, Dwarf_Error * error)
 {
     Dwarf_P_Attribute new_attr;
     int uwordb_size = dbg->de_offset_size;
 
     if (die == NULL) {
-	DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, -1);
+        DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, -1);
     }
     new_attr = (Dwarf_P_Attribute)
-	_dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Attribute_s));
+        _dwarf_p_get_alloc(dbg,sizeof(struct Dwarf_P_Attribute_s));
     if (new_attr == NULL) {
-	DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, -1);
+        DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, -1);
     }
 
     /* fill in the information */
@@ -359,15 +411,15 @@
     new_attr->ar_next = NULL;
     new_attr->ar_reloc_len = uwordb_size;
     new_attr->ar_data = (char *)
-	_dwarf_p_get_alloc(NULL, uwordb_size);
+        _dwarf_p_get_alloc(dbg, uwordb_size);
     if (new_attr->ar_data == NULL) {
-	DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT);
+        DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT);
     }
     {
-	Dwarf_Unsigned du = offset;
+        Dwarf_Unsigned du = offset;
 
-	WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data,
-			(const void *) &du, sizeof(du), uwordb_size);
+        WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data,
+            (const void *) &du, sizeof(du), uwordb_size);
     }
 
     _dwarf_pro_add_at_to_die(die, new_attr);
@@ -380,11 +432,11 @@
 _dwarf_pro_add_at_to_die(Dwarf_P_Die die, Dwarf_P_Attribute attr)
 {
     if (die->di_last_attr) {
-	die->di_last_attr->ar_next = attr;
-	die->di_last_attr = attr;
-	die->di_n_attr++;
+        die->di_last_attr->ar_next = attr;
+        die->di_last_attr = attr;
+        die->di_n_attr++;
     } else {
-	die->di_n_attr = 1;
-	die->di_attrs = die->di_last_attr = attr;
+        die->di_n_attr = 1;
+        die->di_attrs = die->di_last_attr = attr;
     }
 }
--- a/usr/src/tools/ctf/dwarf/common/pro_die.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_die.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
--- a/usr/src/tools/ctf/dwarf/common/pro_encode_nm.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_encode_nm.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +19,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -47,8 +47,8 @@
 
 
 /*-------------------------------------------------------------
-	Encode val as a leb128. This encodes it as an unsigned 
-	number.
+        Encode val as a leb128. This encodes it as an unsigned 
+        number.
 ---------------------------------------------------------------*/
 /* return DW_DLV_ERROR or DW_DLV_OK.
 ** space to write leb number is provided by caller, with caller
@@ -57,25 +57,25 @@
 */
 int
 _dwarf_pro_encode_leb128_nm(Dwarf_Unsigned val, int *nbytes,
-			    char *space, int splen)
+                            char *space, int splen)
 {
     char *a;
     char *end = space + splen;
 
     a = space;
     do {
-	unsigned char uc;
+        unsigned char uc;
 
-	if (a >= end) {
-	    return DW_DLV_ERROR;
-	}
-	uc = val & DATA_MASK;
-	val >>= DIGIT_WIDTH;
-	if (val != 0) {
-	    uc |= MORE_BYTES;
-	}
-	*a = uc;
-	a++;
+        if (a >= end) {
+            return DW_DLV_ERROR;
+        }
+        uc = val & DATA_MASK;
+        val >>= DIGIT_WIDTH;
+        if (val != 0) {
+            uc |= MORE_BYTES;
+        }
+        *a = uc;
+        a++;
     } while (val);
     *nbytes = a - space;
     return DW_DLV_OK;
@@ -89,7 +89,7 @@
 */
 int
 _dwarf_pro_encode_signed_leb128_nm(Dwarf_Signed value, int *nbytes,
-				   char *space, int splen)
+                                   char *space, int splen)
 {
     char *str;
     Dwarf_Signed sign = -(value < 0);
@@ -99,24 +99,24 @@
     str = space;
 
     do {
-	unsigned char byte = value & DATA_MASK;
+        unsigned char byte = value & DATA_MASK;
 
-	value >>= DIGIT_WIDTH;
+        value >>= DIGIT_WIDTH;
 
-	if (str >= end) {
-	    return DW_DLV_ERROR;
-	}
-	/* 
-	 * Remaining chunks would just contain the sign bit, and this chunk
-	 * has already captured at least one sign bit.
-	 */
-	if (value == sign && ((byte & SIGN_BIT) == (sign & SIGN_BIT))) {
-	    more = 0;
-	} else {
-	    byte |= MORE_BYTES;
-	}
-	*str = byte;
-	str++;
+        if (str >= end) {
+            return DW_DLV_ERROR;
+        }
+        /* 
+         * Remaining chunks would just contain the sign bit, and this chunk
+         * has already captured at least one sign bit.
+         */
+        if (value == sign && ((byte & SIGN_BIT) == (sign & SIGN_BIT))) {
+            more = 0;
+        } else {
+            byte |= MORE_BYTES;
+        }
+        *str = byte;
+        str++;
     } while (more);
     *nbytes = str - space;
     return DW_DLV_OK;
--- a/usr/src/tools/ctf/dwarf/common/pro_encode_nm.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_encode_nm.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
--- a/usr/src/tools/ctf/dwarf/common/pro_error.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_error.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +19,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -58,39 +58,39 @@
 */
 void
 _dwarf_p_error(Dwarf_P_Debug dbg,
-	       Dwarf_Error * error, Dwarf_Word errval)
+               Dwarf_Error * error, Dwarf_Word errval)
 {
     Dwarf_Error errptr;
 
     /* Allow NULL dbg on entry, since sometimes that can happen and we
        want to report the upper-level error, not this one. */
     if ((Dwarf_Sword) errval < 0)
-	printf("ERROR VALUE: %ld - %s\n",
-	       (long) errval, _dwarf_errmsgs[-errval - 1]);
+        printf("ERROR VALUE: %ld - %s\n",
+               (long) errval, _dwarf_errmsgs[-errval - 1]);
     if (error != NULL) {
-	errptr = (Dwarf_Error)
-	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_Error_s));
-	if (errptr == NULL) {
-	    fprintf(stderr,
-		    "Could not allocate Dwarf_Error structure\n");
-	    abort();
-	}
-	errptr->er_errval = (Dwarf_Sword) errval;
-	*error = errptr;
-	return;
+        errptr = (Dwarf_Error)
+            _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_Error_s));
+        if (errptr == NULL) {
+            fprintf(stderr,
+                    "Could not allocate Dwarf_Error structure\n");
+            abort();
+        }
+        errptr->er_errval = (Dwarf_Sword) errval;
+        *error = errptr;
+        return;
     }
 
     if (dbg != NULL && dbg->de_errhand != NULL) {
-	errptr = (Dwarf_Error)
-	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_Error_s));
-	if (errptr == NULL) {
-	    fprintf(stderr,
-		    "Could not allocate Dwarf_Error structure\n");
-	    abort();
-	}
-	errptr->er_errval = (Dwarf_Sword) errval;
-	dbg->de_errhand(errptr, dbg->de_errarg);
-	return;
+        errptr = (Dwarf_Error)
+            _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_Error_s));
+        if (errptr == NULL) {
+            fprintf(stderr,
+                    "Could not allocate Dwarf_Error structure\n");
+            abort();
+        }
+        errptr->er_errval = (Dwarf_Sword) errval;
+        dbg->de_errhand(errptr, dbg->de_errarg);
+        return;
     }
 
     abort();
--- a/usr/src/tools/ctf/dwarf/common/pro_error.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_error.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
--- a/usr/src/tools/ctf/dwarf/common/pro_expr.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_expr.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004,2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -54,15 +55,15 @@
     Dwarf_P_Expr ret_expr;
 
     if (dbg == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
-	return (NULL);
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return (NULL);
     }
 
     ret_expr = (Dwarf_P_Expr)
-	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Expr_s));
+        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Expr_s));
     if (ret_expr == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (NULL);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (NULL);
     }
 
     ret_expr->ex_dbg = dbg;
@@ -73,15 +74,15 @@
 
 Dwarf_Unsigned
 dwarf_add_expr_gen(Dwarf_P_Expr expr,
-		   Dwarf_Small opcode,
-		   Dwarf_Unsigned val1,
-		   Dwarf_Unsigned val2, Dwarf_Error * error)
+                   Dwarf_Small opcode,
+                   Dwarf_Unsigned val1,
+                   Dwarf_Unsigned val2, Dwarf_Error * error)
 {
-    char encode_buffer[2 * ENCODE_SPACE_NEEDED];	/* 2* since
-							   used to
-							   concatenate
-							   2 leb's
-							   below */
+    char encode_buffer[2 * ENCODE_SPACE_NEEDED];        /* 2* since
+                                                           used to
+                                                           concatenate
+                                                           2 leb's
+                                                           below */
     char encode_buffer2[ENCODE_SPACE_NEEDED];
     int res;
     Dwarf_P_Debug dbg = expr->ex_dbg;
@@ -112,13 +113,13 @@
     /* ***** BEGIN CODE ***** */
 
     if (expr == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
-	return (DW_DLV_NOCOUNT);
+        _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
+        return (DW_DLV_NOCOUNT);
     }
 
     if (expr->ex_dbg == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_NOCOUNT);
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_NOCOUNT);
     }
 
     operand = NULL;
@@ -157,7 +158,7 @@
     case DW_OP_reg29:
     case DW_OP_reg30:
     case DW_OP_reg31:
-	break;
+        break;
 
     case DW_OP_breg0:
     case DW_OP_breg1:
@@ -191,27 +192,27 @@
     case DW_OP_breg29:
     case DW_OP_breg30:
     case DW_OP_breg31:
-	res = _dwarf_pro_encode_signed_leb128_nm(val1,
-						 &operand_size,
-						 encode_buffer,
-						 sizeof(encode_buffer));
-	if (res != DW_DLV_OK) {
-	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
-	    return (DW_DLV_NOCOUNT);
-	}
-	operand = (Dwarf_Small *) encode_buffer;
-	break;
+        res = _dwarf_pro_encode_signed_leb128_nm(val1,
+                                                 &operand_size,
+                                                 encode_buffer,
+                                                 sizeof(encode_buffer));
+        if (res != DW_DLV_OK) {
+            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+            return (DW_DLV_NOCOUNT);
+        }
+        operand = (Dwarf_Small *) encode_buffer;
+        break;
 
     case DW_OP_regx:
-	res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
-					  encode_buffer,
-					  sizeof(encode_buffer));
-	if (res != DW_DLV_OK) {
-	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
-	    return (DW_DLV_NOCOUNT);
-	}
-	operand = (Dwarf_Small *) encode_buffer;
-	break;
+        res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
+                                          encode_buffer,
+                                          sizeof(encode_buffer));
+        if (res != DW_DLV_OK) {
+            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+            return (DW_DLV_NOCOUNT);
+        }
+        operand = (Dwarf_Small *) encode_buffer;
+        break;
 
     case DW_OP_lit0:
     case DW_OP_lit1:
@@ -245,130 +246,122 @@
     case DW_OP_lit29:
     case DW_OP_lit30:
     case DW_OP_lit31:
-	break;
+        break;
 
     case DW_OP_addr:
-	_dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
-	return (DW_DLV_NOCOUNT);
+        _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
+        return (DW_DLV_NOCOUNT);
 
     case DW_OP_const1u:
     case DW_OP_const1s:
-	operand = (Dwarf_Small *) & operand_buffer[0];
-	WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 1);
-	operand_size = 1;
-	break;
+        operand = (Dwarf_Small *) & operand_buffer[0];
+        WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 1);
+        operand_size = 1;
+        break;
 
     case DW_OP_const2u:
     case DW_OP_const2s:
-	operand = (Dwarf_Small *) & operand_buffer[0];
-	WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 2);
-	operand_size = 2;
-	break;
+        operand = (Dwarf_Small *) & operand_buffer[0];
+        WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 2);
+        operand_size = 2;
+        break;
 
     case DW_OP_const4u:
     case DW_OP_const4s:
-	operand = (Dwarf_Small *) & operand_buffer[0];
-	WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 4);
-	operand_size = 4;
-	break;
+        operand = (Dwarf_Small *) & operand_buffer[0];
+        WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 4);
+        operand_size = 4;
+        break;
 
     case DW_OP_const8u:
     case DW_OP_const8s:
-	operand = (Dwarf_Small *) & operand_buffer[0];
-	WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 8);
-	operand_size = 8;
-	break;
+        operand = (Dwarf_Small *) & operand_buffer[0];
+        WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 8);
+        operand_size = 8;
+        break;
 
     case DW_OP_constu:
-	res = _dwarf_pro_encode_leb128_nm(val1,
-					  &operand_size,
-					  encode_buffer,
-					  sizeof(encode_buffer));
-	if (res != DW_DLV_OK) {
-	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
-	    return (DW_DLV_NOCOUNT);
-	}
-	operand = (Dwarf_Small *) encode_buffer;
-	break;
+        res = _dwarf_pro_encode_leb128_nm(val1,
+                                          &operand_size,
+                                          encode_buffer,
+                                          sizeof(encode_buffer));
+        if (res != DW_DLV_OK) {
+            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+            return (DW_DLV_NOCOUNT);
+        }
+        operand = (Dwarf_Small *) encode_buffer;
+        break;
 
     case DW_OP_consts:
-	res = _dwarf_pro_encode_signed_leb128_nm(val1,
-						 &operand_size,
-						 encode_buffer,
-						 sizeof(encode_buffer));
-	if (res != DW_DLV_OK) {
-	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
-	    return (DW_DLV_NOCOUNT);
-	}
-	operand = (Dwarf_Small *) encode_buffer;
-	break;
+        res = _dwarf_pro_encode_signed_leb128_nm(val1,
+                                                 &operand_size,
+                                                 encode_buffer,
+                                                 sizeof(encode_buffer));
+        if (res != DW_DLV_OK) {
+            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+            return (DW_DLV_NOCOUNT);
+        }
+        operand = (Dwarf_Small *) encode_buffer;
+        break;
 
     case DW_OP_fbreg:
-	res = _dwarf_pro_encode_signed_leb128_nm(val1,
-						 &operand_size,
-						 encode_buffer,
-						 sizeof(encode_buffer));
-	if (res != DW_DLV_OK) {
-	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
-	    return (DW_DLV_NOCOUNT);
-	}
-	operand = (Dwarf_Small *) encode_buffer;
-	break;
+        res = _dwarf_pro_encode_signed_leb128_nm(val1,
+                                                 &operand_size,
+                                                 encode_buffer,
+                                                 sizeof(encode_buffer));
+        if (res != DW_DLV_OK) {
+            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+            return (DW_DLV_NOCOUNT);
+        }
+        operand = (Dwarf_Small *) encode_buffer;
+        break;
 
     case DW_OP_bregx:
-	res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
-					  encode_buffer,
-					  sizeof(encode_buffer));
-	if (res != DW_DLV_OK) {
-	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
-	    return (DW_DLV_NOCOUNT);
-	}
-	operand = (Dwarf_Small *) encode_buffer;
-	/* put this one directly into 'operand' at tail of prev value */
-	res = _dwarf_pro_encode_signed_leb128_nm(val2, &operand2_size,
-						 ((char *) operand) +
-						 operand_size,
-						 sizeof
-						 (encode_buffer2));
-	if (res != DW_DLV_OK) {
-	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
-	    return (DW_DLV_NOCOUNT);
-	}
-	operand_size += operand2_size;
+        res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
+                                          encode_buffer,
+                                          sizeof(encode_buffer));
+        if (res != DW_DLV_OK) {
+            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+            return (DW_DLV_NOCOUNT);
+        }
+        operand = (Dwarf_Small *) encode_buffer;
+        /* put this one directly into 'operand' at tail of prev value */
+        res = _dwarf_pro_encode_signed_leb128_nm(val2, &operand2_size,
+                                                 ((char *) operand) +
+                                                 operand_size,
+                                                 sizeof
+                                                 (encode_buffer2));
+        if (res != DW_DLV_OK) {
+            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+            return (DW_DLV_NOCOUNT);
+        }
+        operand_size += operand2_size;
 
     case DW_OP_dup:
     case DW_OP_drop:
-	break;
+        break;
 
     case DW_OP_pick:
-	operand = (Dwarf_Small *) & operand_buffer[0];
-	/* Cast of val1 to pointer is ok as if val1 does not point into 
-	   our (process) address space we are in big trouble anyway
-	   (internal error in libdwarf or in libdwarf caller). Compiler 
-	   may warn about cast to pointer. */
-	WRITE_UNALIGNED(dbg, operand, (const void *)(uintptr_t)val1,
-			sizeof(val1), 1);
-	operand_size = 1;
-	break;
+        operand = (Dwarf_Small *) & operand_buffer[0];
+        WRITE_UNALIGNED(dbg, operand, (const void *) &val1,
+                        sizeof(val1), 1);
+        operand_size = 1;
+        break;
 
     case DW_OP_over:
     case DW_OP_swap:
     case DW_OP_rot:
     case DW_OP_deref:
     case DW_OP_xderef:
-	break;
+        break;
 
     case DW_OP_deref_size:
     case DW_OP_xderef_size:
-	operand = (Dwarf_Small *) & operand_buffer[0];
-	/* Cast of val1 to pointer is ok as if val1 does not point into 
-	   our (process) address space we are in big trouble anyway
-	   (internal error in libdwarf or in libdwarf caller). Compiler 
-	   may warn about cast to pointer. */
-	WRITE_UNALIGNED(dbg, operand, (const void *)(uintptr_t) val1,
-			sizeof(val1), 1);
-	operand_size = 1;
-	break;
+        operand = (Dwarf_Small *) & operand_buffer[0];
+        WRITE_UNALIGNED(dbg, operand, (const void *) &val1,
+                        sizeof(val1), 1);
+        operand_size = 1;
+        break;
 
     case DW_OP_abs:
     case DW_OP_and:
@@ -380,24 +373,24 @@
     case DW_OP_not:
     case DW_OP_or:
     case DW_OP_plus:
-	break;
+        break;
 
     case DW_OP_plus_uconst:
-	res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
-					  encode_buffer,
-					  sizeof(encode_buffer));
-	if (res != DW_DLV_OK) {
-	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
-	    return (DW_DLV_NOCOUNT);
-	}
-	operand = (Dwarf_Small *) encode_buffer;
-	break;
+        res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
+                                          encode_buffer,
+                                          sizeof(encode_buffer));
+        if (res != DW_DLV_OK) {
+            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+            return (DW_DLV_NOCOUNT);
+        }
+        operand = (Dwarf_Small *) encode_buffer;
+        break;
 
     case DW_OP_shl:
     case DW_OP_shr:
     case DW_OP_shra:
     case DW_OP_xor:
-	break;
+        break;
 
     case DW_OP_le:
     case DW_OP_ge:
@@ -405,42 +398,86 @@
     case DW_OP_lt:
     case DW_OP_gt:
     case DW_OP_ne:
-	break;
+        break;
 
     case DW_OP_skip:
     case DW_OP_bra:
-	/* FIX: unhandled! OP_bra, OP_skip! */
-	_dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
-	return (DW_DLV_NOCOUNT);
+        /* FIX: unhandled! OP_bra, OP_skip! */
+        _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
+        return (DW_DLV_NOCOUNT);
 
     case DW_OP_piece:
-	res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
-					  encode_buffer,
-					  sizeof(encode_buffer));
-	if (res != DW_DLV_OK) {
-	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
-	    return (DW_DLV_NOCOUNT);
-	}
-	operand = (Dwarf_Small *) encode_buffer;
-	break;
+        res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
+                                          encode_buffer,
+                                          sizeof(encode_buffer));
+        if (res != DW_DLV_OK) {
+            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+            return (DW_DLV_NOCOUNT);
+        }
+        operand = (Dwarf_Small *) encode_buffer;
+        break;
 
     case DW_OP_nop:
-	break;
+        break;
+    case DW_OP_push_object_address:     /* DWARF3 */
+        break;
+    case DW_OP_call2:           /* DWARF3 */
+        operand = (Dwarf_Small *) & operand_buffer[0];
+        WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 2);
+        operand_size = 2;
+        break;
+
+    case DW_OP_call4:           /* DWARF3 */
+        operand = (Dwarf_Small *) & operand_buffer[0];
+        WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 4);
+        operand_size = 4;
+        break;
+
+    case DW_OP_call_ref:        /* DWARF3 */
+        operand = (Dwarf_Small *) & operand_buffer[0];
+        WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1),
+                        dbg->de_offset_size);
+        operand_size = dbg->de_offset_size;
+        break;
+    case DW_OP_form_tls_address:        /* DWARF3f */
+        break;
+    case DW_OP_call_frame_cfa:  /* DWARF3f */
+        break;
+    case DW_OP_bit_piece:       /* DWARF3f */
+        res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
+                                          encode_buffer,
+                                          sizeof(encode_buffer));
+        if (res != DW_DLV_OK) {
+            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+            return (DW_DLV_NOCOUNT);
+        }
+        operand = (Dwarf_Small *) encode_buffer;
+        /* put this one directly into 'operand' at tail of prev value */
+        res = _dwarf_pro_encode_leb128_nm(val2, &operand2_size,
+                                          ((char *) operand) +
+                                          operand_size,
+                                          sizeof(encode_buffer2));
+        if (res != DW_DLV_OK) {
+            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+            return (DW_DLV_NOCOUNT);
+        }
+        operand_size += operand2_size;
+
 
     default:
-	_dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
-	return (DW_DLV_NOCOUNT);
+        _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
+        return (DW_DLV_NOCOUNT);
     }
 
     next_byte_offset = expr->ex_next_byte_offset + operand_size + 1;
 
     if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) {
-	_dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
-	return (DW_DLV_NOCOUNT);
+        _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+        return (DW_DLV_NOCOUNT);
     }
 
     next_byte_ptr =
-	&(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset;
+        &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset;
 
     *next_byte_ptr = opcode;
     next_byte_ptr++;
@@ -452,8 +489,8 @@
 
 Dwarf_Unsigned
 dwarf_add_expr_addr_b(Dwarf_P_Expr expr,
-		      Dwarf_Unsigned addr,
-		      Dwarf_Unsigned sym_index, Dwarf_Error * error)
+                      Dwarf_Unsigned addr,
+                      Dwarf_Unsigned sym_index, Dwarf_Error * error)
 {
     Dwarf_P_Debug dbg;
     Dwarf_Small *next_byte_ptr;
@@ -461,34 +498,34 @@
     int upointer_size;
 
     if (expr == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
-	return (DW_DLV_NOCOUNT);
+        _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
+        return (DW_DLV_NOCOUNT);
     }
 
     dbg = expr->ex_dbg;
     if (dbg == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_NOCOUNT);
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_NOCOUNT);
     }
 
     upointer_size = dbg->de_pointer_size;
     next_byte_offset = expr->ex_next_byte_offset + upointer_size + 1;
     if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) {
-	_dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD);
-	return (DW_DLV_NOCOUNT);
+        _dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+        return (DW_DLV_NOCOUNT);
     }
 
     next_byte_ptr =
-	&(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset;
+        &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset;
 
     *next_byte_ptr = DW_OP_addr;
     next_byte_ptr++;
     WRITE_UNALIGNED(dbg, next_byte_ptr, (const void *) &addr,
-		    sizeof(addr), upointer_size);
+                    sizeof(addr), upointer_size);
 
     if (expr->ex_reloc_offset != 0) {
-	_dwarf_p_error(dbg, error, DW_DLE_MULTIPLE_RELOC_IN_EXPR);
-	return (DW_DLV_NOCOUNT);
+        _dwarf_p_error(dbg, error, DW_DLE_MULTIPLE_RELOC_IN_EXPR);
+        return (DW_DLV_NOCOUNT);
     }
 
     expr->ex_reloc_sym_index = sym_index;
@@ -500,12 +537,12 @@
 
 Dwarf_Unsigned
 dwarf_add_expr_addr(Dwarf_P_Expr expr,
-		    Dwarf_Unsigned addr,
-		    Dwarf_Signed sym_index, Dwarf_Error * error)
+                    Dwarf_Unsigned addr,
+                    Dwarf_Signed sym_index, Dwarf_Error * error)
 {
     return
-	dwarf_add_expr_addr_b(expr, addr, (Dwarf_Unsigned) sym_index,
-			      error);
+        dwarf_add_expr_addr_b(expr, addr, (Dwarf_Unsigned) sym_index,
+                              error);
 }
 
 
@@ -513,35 +550,45 @@
 dwarf_expr_current_offset(Dwarf_P_Expr expr, Dwarf_Error * error)
 {
     if (expr == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
-	return (DW_DLV_NOCOUNT);
+        _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
+        return (DW_DLV_NOCOUNT);
     }
 
     if (expr->ex_dbg == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_NOCOUNT);
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_NOCOUNT);
     }
 
     return (expr->ex_next_byte_offset);
 }
 
+void
+dwarf_expr_reset(Dwarf_P_Expr expr, Dwarf_Error * error)
+{
+   if (expr == NULL) {
+      _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
+      return;
+   }
+   expr->ex_next_byte_offset=0;
+}
+
 
 Dwarf_Addr
 dwarf_expr_into_block(Dwarf_P_Expr expr,
-		      Dwarf_Unsigned * length, Dwarf_Error * error)
+                      Dwarf_Unsigned * length, Dwarf_Error * error)
 {
     if (expr == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
-	return (DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
+        return (DW_DLV_BADADDR);
     }
 
     if (expr->ex_dbg == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_BADADDR);
     }
 
     if (length != NULL)
-	*length = expr->ex_next_byte_offset;
+        *length = expr->ex_next_byte_offset;
     /* The following cast from pointer to integer is ok as long as
        Dwarf_Addr is at least as large as a pointer. Which is a
        requirement of libdwarf so must be satisfied (some compilers
--- a/usr/src/tools/ctf/dwarf/common/pro_expr.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_expr.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
--- a/usr/src/tools/ctf/dwarf/common/pro_finish.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_finish.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -40,16 +41,17 @@
 #include "pro_incl.h"
 
 /*---------------------------------------------------------------
-	This routine deallocates all memory, and does some 
-	finishing up
+        This routine deallocates all memory, and does some 
+        finishing up
 -----------------------------------------------------------------*/
  /*ARGSUSED*/ Dwarf_Unsigned
 dwarf_producer_finish(Dwarf_P_Debug dbg, Dwarf_Error * error)
 {
     if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) {
-	DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_NOCOUNT);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_NOCOUNT);
     }
 
-    dwarf_p_dealloc((void *) dbg, 0);
+    /* this frees all blocks, then frees dbg. */
+    _dwarf_p_dealloc_all(dbg);
     return 0;
 }
--- a/usr/src/tools/ctf/dwarf/common/pro_forms.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_forms.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
-
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
+  Portions Copyright 2007-2010 David Anderson. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -49,12 +50,12 @@
 
 
     /* Indicates no relocation needed. */
-#define NO_ELF_SYM_INDEX	0
+#define NO_ELF_SYM_INDEX        0
 
 
 /* adds an attribute to a die */
 extern void _dwarf_pro_add_at_to_die(Dwarf_P_Die die,
-				     Dwarf_P_Attribute attr);
+                                     Dwarf_P_Attribute attr);
 
 /*
     This function adds an attribute whose value is
@@ -62,85 +63,372 @@
     is given the name provided by attr.  The address
     is given in pc_value.
 */
+
+static Dwarf_P_Attribute
+local_add_AT_address(Dwarf_P_Debug dbg,
+                     Dwarf_P_Die ownerdie,
+                     Dwarf_Half attr,
+                     Dwarf_Signed form,
+                     Dwarf_Unsigned pc_value,
+                     Dwarf_Unsigned sym_index,
+                     Dwarf_Error * error);
+     
 /* old interface */
 Dwarf_P_Attribute
 dwarf_add_AT_targ_address(Dwarf_P_Debug dbg,
-			  Dwarf_P_Die ownerdie,
-			  Dwarf_Half attr,
-			  Dwarf_Unsigned pc_value,
-			  Dwarf_Signed sym_index, Dwarf_Error * error)
+                          Dwarf_P_Die ownerdie,
+                          Dwarf_Half attr,
+                          Dwarf_Unsigned pc_value,
+                          Dwarf_Signed sym_index, Dwarf_Error * error)
 {
-    return
-	dwarf_add_AT_targ_address_b(dbg,
-				    ownerdie,
-				    attr,
-				    pc_value,
-				    (Dwarf_Unsigned) sym_index, error);
+    return 
+        dwarf_add_AT_targ_address_b(dbg,
+                                    ownerdie, 
+                                    attr,
+                                    pc_value, 
+                                    (Dwarf_Unsigned) sym_index, error);
 }
 
-/* new interface */
+/* New interface, replacing dwarf_add_AT_targ_address. 
+   Essentially just makes sym_index a Dwarf_Unsigned
+   so for symbolic relocations it can be a full address.
+*/
 Dwarf_P_Attribute
 dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg,
-			    Dwarf_P_Die ownerdie,
-			    Dwarf_Half attr,
-			    Dwarf_Unsigned pc_value,
-			    Dwarf_Unsigned sym_index,
-			    Dwarf_Error * error)
+                            Dwarf_P_Die ownerdie,
+                            Dwarf_Half attr,
+                            Dwarf_Unsigned pc_value,
+                            Dwarf_Unsigned sym_index,
+                            Dwarf_Error * error)
+{
+    switch (attr) {
+    case DW_AT_low_pc:
+    case DW_AT_high_pc:
+
+    /* added to support location lists */
+    /* no way to check that this is a loclist-style address though */
+    case DW_AT_location:
+    case DW_AT_string_length:
+    case DW_AT_return_addr:
+    case DW_AT_frame_base:
+    case DW_AT_segment:
+    case DW_AT_static_link:
+    case DW_AT_use_location:
+    case DW_AT_vtable_elem_location:
+    case DW_AT_const_value: /* Gcc can generate this as address. */
+    case DW_AT_entry_pc:
+        break;
+    default: 
+        if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
+            _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
+            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        }
+        break;
+    }
+    
+    return local_add_AT_address(dbg, ownerdie, attr, DW_FORM_addr,
+                                pc_value, sym_index, error);
+}
+
+Dwarf_P_Attribute
+dwarf_add_AT_ref_address(Dwarf_P_Debug dbg,
+                         Dwarf_P_Die ownerdie,
+                         Dwarf_Half attr,
+                         Dwarf_Unsigned pc_value,
+                         Dwarf_Unsigned sym_index,
+                         Dwarf_Error * error)
+{
+    switch (attr) {
+    case DW_AT_type:
+    case DW_AT_import:
+        break;
+
+    default: 
+        if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
+            _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
+            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        }
+        break;
+    }
+    
+    return local_add_AT_address(dbg, ownerdie, attr, DW_FORM_ref_addr,
+                                pc_value, sym_index, error);    
+}
+
+
+/* Make sure attribute types are checked before entering here. */
+static Dwarf_P_Attribute
+local_add_AT_address(Dwarf_P_Debug dbg,
+                     Dwarf_P_Die ownerdie,
+                     Dwarf_Half attr,
+                     Dwarf_Signed form,
+                     Dwarf_Unsigned pc_value,
+                     Dwarf_Unsigned sym_index,
+                     Dwarf_Error * error)
 {
     Dwarf_P_Attribute new_attr;
     int upointer_size = dbg->de_pointer_size;
 
     if (dbg == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     if (ownerdie == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
-    if (attr != DW_AT_low_pc && attr != DW_AT_high_pc &&
-	attr != DW_AT_MIPS_loop_begin &&
-	attr != DW_AT_MIPS_tail_loop_begin &&
-	attr != DW_AT_MIPS_epilog_begin) {
-	_dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
-    }
+    /* attribute types have already been checked */
+    /* switch (attr) { ... } */
 
     new_attr = (Dwarf_P_Attribute)
-	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
+        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
     if (new_attr == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     new_attr->ar_attribute = attr;
-    new_attr->ar_attribute_form = DW_FORM_addr;
+    new_attr->ar_attribute_form = form;
     new_attr->ar_nbytes = upointer_size;
     new_attr->ar_rel_symidx = sym_index;
     new_attr->ar_reloc_len = upointer_size;
     new_attr->ar_next = 0;
     if (sym_index != NO_ELF_SYM_INDEX)
-	new_attr->ar_rel_type = dbg->de_ptr_reloc;
+        new_attr->ar_rel_type = dbg->de_ptr_reloc;
     else
-	new_attr->ar_rel_type = R_MIPS_NONE;
+        new_attr->ar_rel_type = R_MIPS_NONE;
 
     new_attr->ar_data = (char *)
-	_dwarf_p_get_alloc(dbg, upointer_size);
+        _dwarf_p_get_alloc(dbg, upointer_size);
     if (new_attr->ar_data == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
     WRITE_UNALIGNED(dbg, new_attr->ar_data,
-		    (const void *) &pc_value,
-		    sizeof(pc_value), upointer_size);
+                    (const void *) &pc_value,
+                    sizeof(pc_value), upointer_size);
 
     /* add attribute to the die */
     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
     return new_attr;
 }
 
+/*
+ * Functions to compress and uncompress data from normal
+ * arrays of integral types into arrays of LEB128 numbers.
+ * Extend these functions as needed to handle wider input
+ * variety.  Return values should be freed with _dwarf_p_dealloc
+ * after they aren't needed any more.
+ */
+
+/* return value points to an array of LEB number */
+
+void *
+dwarf_compress_integer_block(
+    Dwarf_P_Debug    dbg,
+    Dwarf_Bool       unit_is_signed,
+    Dwarf_Small      unit_length_in_bits,
+    void*            input_block,
+    Dwarf_Unsigned   input_length_in_units,
+    Dwarf_Unsigned*  output_length_in_bytes_ptr,
+    Dwarf_Error*     error
+)
+{
+    Dwarf_Unsigned output_length_in_bytes = 0;
+    char * output_block = 0;
+    char encode_buffer[ENCODE_SPACE_NEEDED];
+    int i = 0;
+    char * ptr = 0;
+    int remain = 0;
+    int result = 0;
+
+    if (dbg == NULL) {
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return((void *)DW_DLV_BADADDR);
+    }
+    
+    if (unit_is_signed == false ||
+        unit_length_in_bits != 32 ||
+        input_block == NULL ||
+        input_length_in_units == 0 ||
+        output_length_in_bytes_ptr == NULL) {
+        
+        _dwarf_p_error(NULL, error, DW_DLE_BADBITC);
+        return ((void *) DW_DLV_BADADDR);
+    }
+
+    /* At this point we assume the format is: signed 32 bit */
+
+    /* first compress everything to find the total size. */
+
+    output_length_in_bytes = 0;
+    for (i=0; i<input_length_in_units; i++) {
+        int unit_encoded_size;
+        Dwarf_sfixed unit; /* this is fixed at signed-32-bits */
+        
+        unit = ((Dwarf_sfixed*)input_block)[i];
+        
+        result = _dwarf_pro_encode_signed_leb128_nm(unit, &unit_encoded_size,
+                                             encode_buffer,sizeof(encode_buffer));
+        if (result !=  DW_DLV_OK) {
+            _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+            return((Dwarf_P_Attribute)DW_DLV_BADADDR);
+        }
+        output_length_in_bytes += unit_encoded_size;
+    }
+
+    
+    /* then alloc */
+
+    output_block = (void *)
+        _dwarf_p_get_alloc(dbg, output_length_in_bytes);
+    if (output_block == NULL) {
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return((void*)DW_DLV_BADADDR);
+    }
+    
+    /* then compress again and copy into new buffer */
+
+    ptr = output_block;
+    remain = output_length_in_bytes;
+    for (i=0; i<input_length_in_units; i++) {
+        int unit_encoded_size;
+        Dwarf_sfixed unit; /* this is fixed at signed-32-bits */
+        
+        unit = ((Dwarf_sfixed*)input_block)[i];
+        
+        result = _dwarf_pro_encode_signed_leb128_nm(unit, &unit_encoded_size,
+                                             ptr, remain);
+        if (result !=  DW_DLV_OK) {
+            _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+            return((Dwarf_P_Attribute)DW_DLV_BADADDR);
+        }
+        remain -= unit_encoded_size;
+        ptr += unit_encoded_size;
+    }
+
+    if (remain != 0) {
+        _dwarf_p_dealloc(dbg, (unsigned char *)output_block);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
+    }
+
+    *output_length_in_bytes_ptr = output_length_in_bytes;
+    return (void*) output_block;
+
+}
+
+void
+dwarf_dealloc_compressed_block(Dwarf_P_Debug dbg, void * space)
+{
+    _dwarf_p_dealloc(dbg, space);
+}
+
+/* This is very similar to targ_address but results in a different FORM */
+/* dbg->de_ar_data_attribute_form is data4 or data8
+   and dwarf4 changes the definition for such on DW_AT_high_pc.
+   DWARF 3: the FORM here has no defined meaning for dwarf3.
+   DWARF 4: the FORM here means that for DW_AT_high_pc the value
+            is not a high address but is instead an offset
+            from a (separate) DW_AT_low_pc. 
+   The intent for DWARF4 is that this is not a relocated
+   address at all.  Instead a simple offset.
+   But this should NOT be called for a simple non-relocated offset.
+   So do not call this with an attr of DW_AT_high_pc.
+   Use dwarf_add_AT_unsigned_const() (for example) instead of
+   dwarf_add_AT_dataref when the value is a simple offset .
+*/
+Dwarf_P_Attribute
+dwarf_add_AT_dataref(
+    Dwarf_P_Debug dbg,
+    Dwarf_P_Die ownerdie,
+    Dwarf_Half attr,
+    Dwarf_Unsigned pc_value,
+    Dwarf_Unsigned sym_index,
+    Dwarf_Error * error)
+{
+    /* TODO: Add checking here */
+    return local_add_AT_address(dbg, ownerdie, attr,
+                                dbg->de_ar_data_attribute_form,
+                                pc_value,
+                                sym_index,
+                                error);
+}
+
+
+
+Dwarf_P_Attribute 
+dwarf_add_AT_block(
+    Dwarf_P_Debug       dbg,
+    Dwarf_P_Die         ownerdie,
+    Dwarf_Half          attr,
+    Dwarf_Small         *block_data,
+    Dwarf_Unsigned      block_size,
+    Dwarf_Error         *error
+)
+{
+    Dwarf_P_Attribute   new_attr;
+    int result;
+    char encode_buffer[ENCODE_SPACE_NEEDED];
+    int len_size;
+    char * attrdata;
+
+    if (dbg == NULL) {
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
+    }
+
+    if (ownerdie == NULL) {
+        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
+        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
+    }
+
+    /* I don't mess with block1, block2, block4, not worth the effort */
+
+    /* So, encode the length into LEB128 */
+    result = _dwarf_pro_encode_leb128_nm(block_size, &len_size,
+                                         encode_buffer,sizeof(encode_buffer));
+    if (result !=  DW_DLV_OK) {
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
+    }
+
+    /* Allocate the new attribute */
+    new_attr = (Dwarf_P_Attribute)
+        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
+    if (new_attr == NULL) {
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
+    }
+
+    /* Fill in the attribute */
+    new_attr->ar_attribute = attr;
+    new_attr->ar_attribute_form = DW_FORM_block;
+    new_attr->ar_nbytes = len_size + block_size;
+    new_attr->ar_next = 0;
+
+    new_attr->ar_data = attrdata = (char *)
+        _dwarf_p_get_alloc(dbg, len_size + block_size);
+    if (new_attr->ar_data == NULL) {
+        /* free the block we got earlier */
+        _dwarf_p_dealloc(dbg, (unsigned char *) new_attr);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
+    }
+
+    /* write length and data to attribute data buffer */
+    memcpy(attrdata, encode_buffer, len_size);
+    attrdata += len_size;
+    memcpy(attrdata, block_data, block_size);
+    
+    /* add attribute to the die */
+    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
+
+    return new_attr;
+}
+
 
 /*
     This function adds attributes whose value
@@ -150,22 +438,22 @@
 */
 Dwarf_P_Attribute
 dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg,
-			    Dwarf_P_Die ownerdie,
-			    Dwarf_Half attr,
-			    Dwarf_Unsigned value, Dwarf_Error * error)
+                            Dwarf_P_Die ownerdie,
+                            Dwarf_Half attr,
+                            Dwarf_Unsigned value, Dwarf_Error * error)
 {
     Dwarf_P_Attribute new_attr;
     Dwarf_Half attr_form;
     Dwarf_Small size;
 
     if (dbg == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     if (ownerdie == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     switch (attr) {
@@ -184,7 +472,7 @@
     case DW_AT_identifier_case:
     case DW_AT_MIPS_loop_unroll_factor:
     case DW_AT_MIPS_software_pipeline_depth:
-	break;
+        break;
 
     case DW_AT_decl_column:
     case DW_AT_decl_file:
@@ -193,52 +481,61 @@
     case DW_AT_start_scope:
     case DW_AT_stride_size:
     case DW_AT_count:
-	break;
+    case DW_AT_associated:
+    case DW_AT_allocated:
+    case DW_AT_upper_bound:
+    case DW_AT_lower_bound:
+    case DW_AT_call_file:
+    case DW_AT_call_line:
+        break;
 
-    default:{
-	    _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
-	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
-	}
-    }
+        default: {
+                 if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
+                     _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
+                     return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+               }
+               break;
+            }
+        }
 
     /* 
        Compute the number of bytes needed to hold constant. */
     if (value <= UCHAR_MAX) {
-	attr_form = DW_FORM_data1;
-	size = 1;
+        attr_form = DW_FORM_data1;
+        size = 1;
     } else if (value <= USHRT_MAX) {
-	attr_form = DW_FORM_data2;
-	size = 2;
+        attr_form = DW_FORM_data2;
+        size = 2;
     } else if (value <= UINT_MAX) {
-	attr_form = DW_FORM_data4;
-	size = 4;
+        attr_form = DW_FORM_data4;
+        size = 4;
     } else {
-	attr_form = DW_FORM_data8;
-	size = 8;
+        attr_form = DW_FORM_data8;
+        size = 8;
     }
 
     new_attr = (Dwarf_P_Attribute)
-	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
+        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
     if (new_attr == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     new_attr->ar_attribute = attr;
     new_attr->ar_attribute_form = attr_form;
     new_attr->ar_rel_type = R_MIPS_NONE;
-    new_attr->ar_reloc_len = 0;	/* irrelevant: unused with R_MIPS_NONE */
+    new_attr->ar_reloc_len = 0; /* irrelevant: unused with R_MIPS_NONE */
     new_attr->ar_nbytes = size;
     new_attr->ar_next = 0;
 
     new_attr->ar_data = (char *)
-	_dwarf_p_get_alloc(dbg, size);
+        _dwarf_p_get_alloc(dbg, size);
     if (new_attr->ar_data == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
     WRITE_UNALIGNED(dbg, new_attr->ar_data,
-		    (const void *) &value, sizeof(value), size);
+                    (const void *) &value, sizeof(value), size);
 
     /* add attribute to the die */
     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
@@ -254,74 +551,85 @@
 */
 Dwarf_P_Attribute
 dwarf_add_AT_signed_const(Dwarf_P_Debug dbg,
-			  Dwarf_P_Die ownerdie,
-			  Dwarf_Half attr,
-			  Dwarf_Signed value, Dwarf_Error * error)
+                          Dwarf_P_Die ownerdie,
+                          Dwarf_Half attr,
+                          Dwarf_Signed value, Dwarf_Error * error)
 {
     Dwarf_P_Attribute new_attr;
     Dwarf_Half attr_form;
     Dwarf_Small size;
 
     if (dbg == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     if (ownerdie == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     switch (attr) {
+    case DW_AT_lower_bound:
     case DW_AT_upper_bound:
-    case DW_AT_lower_bound:
-	break;
+    case DW_AT_const_value:
+    case DW_AT_bit_offset:
+    case DW_AT_bit_size:
+    case DW_AT_byte_size:
+    case DW_AT_count:
+    case DW_AT_byte_stride:
+    case DW_AT_bit_stride:
+    case DW_AT_allocated:
+    case DW_AT_associated:
+        break;
 
-    default:{
-	    _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
-	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
-	}
+    default:{ 
+                if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
+                     _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
+                     return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+                }
+        }
+        break;
     }
 
     /* 
        Compute the number of bytes needed to hold constant. */
     if (value >= SCHAR_MIN && value <= SCHAR_MAX) {
-	attr_form = DW_FORM_data1;
-	size = 1;
+        attr_form = DW_FORM_data1;
+        size = 1;
     } else if (value >= SHRT_MIN && value <= SHRT_MAX) {
-	attr_form = DW_FORM_data2;
-	size = 2;
+        attr_form = DW_FORM_data2;
+        size = 2;
     } else if (value >= INT_MIN && value <= INT_MAX) {
-	attr_form = DW_FORM_data4;
-	size = 4;
+        attr_form = DW_FORM_data4;
+        size = 4;
     } else {
-	attr_form = DW_FORM_data8;
-	size = 8;
+        attr_form = DW_FORM_data8;
+        size = 8;
     }
 
     new_attr = (Dwarf_P_Attribute)
-	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
+        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
     if (new_attr == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     new_attr->ar_attribute = attr;
     new_attr->ar_attribute_form = attr_form;
     new_attr->ar_rel_type = R_MIPS_NONE;
-    new_attr->ar_reloc_len = 0;	/* irrelevant: unused with R_MIPS_NONE 
-				 */
+    new_attr->ar_reloc_len = 0; /* irrelevant: unused with R_MIPS_NONE */
     new_attr->ar_nbytes = size;
     new_attr->ar_next = 0;
 
     new_attr->ar_data = (char *)
-	_dwarf_p_get_alloc(dbg, size);
+        _dwarf_p_get_alloc(dbg, size);
     if (new_attr->ar_data == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
     WRITE_UNALIGNED(dbg, new_attr->ar_data,
-		    (const void *) &value, sizeof(value), size);
+                    (const void *) &value, sizeof(value), size);
 
     /* add attribute to the die */
     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
@@ -335,38 +643,38 @@
 */
 Dwarf_P_Attribute
 dwarf_add_AT_location_expr(Dwarf_P_Debug dbg,
-			   Dwarf_P_Die ownerdie,
-			   Dwarf_Half attr,
-			   Dwarf_P_Expr loc_expr, Dwarf_Error * error)
+                           Dwarf_P_Die ownerdie,
+                           Dwarf_Half attr,
+                           Dwarf_P_Expr loc_expr, Dwarf_Error * error)
 {
     char encode_buffer[ENCODE_SPACE_NEEDED];
     int res;
     Dwarf_P_Attribute new_attr;
     Dwarf_Half attr_form;
-    char *len_str;
+    char *len_str = 0;
     int len_size;
     int block_size;
     char *block_dest_ptr;
     int do_len_as_int = 0;
 
     if (dbg == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     if (ownerdie == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     if (loc_expr == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_EXPR_NULL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_EXPR_NULL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     if (loc_expr->ex_dbg != dbg) {
-	_dwarf_p_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
     block_size = loc_expr->ex_next_byte_offset;
 
@@ -380,75 +688,87 @@
     case DW_AT_frame_base:
     case DW_AT_static_link:
     case DW_AT_vtable_elem_location:
-	break;
+    case DW_AT_lower_bound:
+    case DW_AT_upper_bound:
+    case DW_AT_count:
+    case DW_AT_associated:
+    case DW_AT_allocated:
+    case DW_AT_data_location:
+    case DW_AT_byte_stride:
+    case DW_AT_bit_stride:
+    case DW_AT_byte_size:
+    case DW_AT_bit_size:
+    break;
 
-    default:{
-	    _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
-	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
-	}
+    default:
+        if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
+            _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
+            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        }
+    break;
     }
 
     /* 
        Compute the number of bytes needed to hold constant. */
     if (block_size <= UCHAR_MAX) {
-	attr_form = DW_FORM_block1;
-	len_size = 1;
-	do_len_as_int = 1;
+        attr_form = DW_FORM_block1;
+        len_size = 1;
+        do_len_as_int = 1;
     } else if (block_size <= USHRT_MAX) {
-	attr_form = DW_FORM_block2;
-	len_size = 2;
-	do_len_as_int = 1;
+        attr_form = DW_FORM_block2;
+        len_size = 2;
+        do_len_as_int = 1;
     } else if (block_size <= UINT_MAX) {
-	attr_form = DW_FORM_block4;
-	len_size = 4;
-	do_len_as_int = 1;
+        attr_form = DW_FORM_block4;
+        len_size = 4;
+        do_len_as_int = 1;
     } else {
-	attr_form = DW_FORM_block;
-	res = _dwarf_pro_encode_leb128_nm(block_size, &len_size,
-					  encode_buffer,
-					  sizeof(encode_buffer));
-	if (res != DW_DLV_OK) {
-	    _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
-	}
-	len_str = (char *) encode_buffer;
+        attr_form = DW_FORM_block;
+        res = _dwarf_pro_encode_leb128_nm(block_size, &len_size,
+                                          encode_buffer,
+                                          sizeof(encode_buffer));
+        if (res != DW_DLV_OK) {
+            _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        }
+        len_str = (char *) encode_buffer;
     }
 
     new_attr = (Dwarf_P_Attribute)
-	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
+        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
     if (new_attr == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     new_attr->ar_attribute = attr;
     new_attr->ar_attribute_form = attr_form;
     new_attr->ar_reloc_len = dbg->de_pointer_size;
     if (loc_expr->ex_reloc_sym_index != NO_ELF_SYM_INDEX) {
-	new_attr->ar_rel_type = dbg->de_ptr_reloc;
+        new_attr->ar_rel_type = dbg->de_ptr_reloc;
     } else {
-	new_attr->ar_rel_type = R_MIPS_NONE;
+        new_attr->ar_rel_type = R_MIPS_NONE;
     }
     new_attr->ar_rel_symidx = loc_expr->ex_reloc_sym_index;
     new_attr->ar_rel_offset =
-	(Dwarf_Word) loc_expr->ex_reloc_offset + len_size;
+        (Dwarf_Word) loc_expr->ex_reloc_offset + len_size;
 
     new_attr->ar_nbytes = block_size + len_size;
 
     new_attr->ar_next = 0;
     new_attr->ar_data = block_dest_ptr =
-	(char *) _dwarf_p_get_alloc(dbg, block_size + len_size);
+        (char *) _dwarf_p_get_alloc(dbg, block_size + len_size);
     if (new_attr->ar_data == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     if (do_len_as_int) {
-	WRITE_UNALIGNED(dbg, block_dest_ptr, (const void *) &block_size,
-			sizeof(block_size), len_size);
+        WRITE_UNALIGNED(dbg, block_dest_ptr, (const void *) &block_size,
+                        sizeof(block_size), len_size);
     } else {
-	/* is uleb number form */
-	memcpy(block_dest_ptr, len_str, len_size);
+        /* Is uleb number form, DW_FORM_block. See above. */
+        memcpy(block_dest_ptr, len_str, len_size);
     }
     block_dest_ptr += len_size;
     memcpy(block_dest_ptr, &(loc_expr->ex_byte_stream[0]), block_size);
@@ -474,25 +794,25 @@
 */
 Dwarf_P_Attribute
 dwarf_add_AT_reference(Dwarf_P_Debug dbg,
-		       Dwarf_P_Die ownerdie,
-		       Dwarf_Half attr,
-		       Dwarf_P_Die otherdie, Dwarf_Error * error)
+                       Dwarf_P_Die ownerdie,
+                       Dwarf_Half attr,
+                       Dwarf_P_Die otherdie, Dwarf_Error * error)
 {
     Dwarf_P_Attribute new_attr;
 
     if (dbg == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     if (ownerdie == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     if (otherdie == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     switch (attr) {
@@ -509,27 +829,30 @@
     case DW_AT_lower_bound:
     case DW_AT_upper_bound:
     case DW_AT_count:
+    case DW_AT_associated:
+    case DW_AT_allocated:
+    case DW_AT_bit_offset:
+    case DW_AT_bit_size:
+    case DW_AT_byte_size:
     case DW_AT_sibling:
-    case DW_AT_MIPS_stride:
-    case DW_AT_MIPS_stride_byte:
-    case DW_AT_MIPS_stride_elem:
-    case DW_AT_MIPS_clone_origin:
-    case DW_AT_MIPS_ptr_dopetype:
-    case DW_AT_MIPS_allocatable_dopetype:
-    case DW_AT_MIPS_assumed_shape_dopetype:
-	break;
+    case DW_AT_bit_stride:
+    case DW_AT_byte_stride:
+    case DW_AT_namelist_item:
+        break;
 
-    default:{
-	    _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
-	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
-	}
+    default:
+        if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
+            _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
+            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        }
+        break;
     }
 
     new_attr = (Dwarf_P_Attribute)
-	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
+        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
     if (new_attr == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     new_attr->ar_attribute = attr;
@@ -551,22 +874,23 @@
 */
 Dwarf_P_Attribute
 dwarf_add_AT_flag(Dwarf_P_Debug dbg,
-		  Dwarf_P_Die ownerdie,
-		  Dwarf_Half attr,
-		  Dwarf_Small flag, Dwarf_Error * error)
+                  Dwarf_P_Die ownerdie,
+                  Dwarf_Half attr,
+                  Dwarf_Small flag, Dwarf_Error * error)
 {
     Dwarf_P_Attribute new_attr;
 
     if (dbg == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     if (ownerdie == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
+#if 0    
     switch (attr) {
     case DW_AT_is_optional:
     case DW_AT_artificial:
@@ -574,35 +898,36 @@
     case DW_AT_external:
     case DW_AT_prototyped:
     case DW_AT_variable_parameter:
-    case DW_AT_MIPS_has_inlines:
-    case DW_AT_MIPS_assumed_size:
-	break;
+        break;
 
-    default:{
-	    _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
-	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
-	}
+        default:
+            if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
+            _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
+            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        }
+            break;
     }
+#endif    
 
     new_attr = (Dwarf_P_Attribute)
-	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
+        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
     if (new_attr == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     new_attr->ar_attribute = attr;
     new_attr->ar_attribute_form = DW_FORM_flag;
     new_attr->ar_nbytes = 1;
-    new_attr->ar_reloc_len = 0;	/* not used */
+    new_attr->ar_reloc_len = 0; /* not used */
     new_attr->ar_rel_type = R_MIPS_NONE;
     new_attr->ar_next = 0;
 
     new_attr->ar_data = (char *)
-	_dwarf_p_get_alloc(dbg, 1);
+        _dwarf_p_get_alloc(dbg, 1);
     if (new_attr->ar_data == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
     memcpy(new_attr->ar_data, &flag, 1);
 
@@ -618,26 +943,26 @@
 */
 Dwarf_P_Attribute
 dwarf_add_AT_string(Dwarf_P_Debug dbg,
-		    Dwarf_P_Die ownerdie,
-		    Dwarf_Half attr, char *string, Dwarf_Error * error)
+                    Dwarf_P_Die ownerdie,
+                    Dwarf_Half attr, char *string, Dwarf_Error * error)
 {
     Dwarf_P_Attribute new_attr;
 
     if (dbg == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     if (ownerdie == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     new_attr = (Dwarf_P_Attribute)
-	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
+        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
     if (new_attr == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     switch (attr) {
@@ -645,14 +970,14 @@
     case DW_AT_comp_dir:
     case DW_AT_const_value:
     case DW_AT_producer:
-    case DW_AT_MIPS_linkage_name:
-    case DW_AT_MIPS_abstract_name:
-	break;
+        break;
 
-    default:{
-	    _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
-	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
-	}
+        default:
+            if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
+            _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
+            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        }
+            break;
     }
 
     new_attr->ar_attribute = attr;
@@ -661,15 +986,15 @@
     new_attr->ar_next = 0;
 
     new_attr->ar_data =
-	(char *) _dwarf_p_get_alloc(NULL, strlen(string) + 1);
+        (char *) _dwarf_p_get_alloc(dbg, strlen(string)+1);
     if (new_attr->ar_data == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     strcpy(new_attr->ar_data, string);
     new_attr->ar_rel_type = R_MIPS_NONE;
-    new_attr->ar_reloc_len = 0;	/* unused for R_MIPS_NONE */
+    new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
 
     /* add attribute to the die */
     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
@@ -679,20 +1004,20 @@
 
 Dwarf_P_Attribute
 dwarf_add_AT_const_value_string(Dwarf_P_Die ownerdie,
-				char *string_value, Dwarf_Error * error)
+                                char *string_value, Dwarf_Error * error)
 {
     Dwarf_P_Attribute new_attr;
 
     if (ownerdie == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     new_attr = (Dwarf_P_Attribute)
-	_dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Attribute_s));
+        _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
     if (new_attr == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     new_attr->ar_attribute = DW_AT_const_value;
@@ -701,15 +1026,15 @@
     new_attr->ar_next = 0;
 
     new_attr->ar_data =
-	(char *) _dwarf_p_get_alloc(NULL, strlen(string_value) + 1);
+        (char *) _dwarf_p_get_alloc(ownerdie->di_dbg, strlen(string_value)+1);
     if (new_attr->ar_data == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     strcpy(new_attr->ar_data, string_value);
     new_attr->ar_rel_type = R_MIPS_NONE;
-    new_attr->ar_reloc_len = 0;	/* unused for R_MIPS_NONE */
+    new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
 
     /* add attribute to the die */
     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
@@ -719,20 +1044,20 @@
 
 Dwarf_P_Attribute
 dwarf_add_AT_producer(Dwarf_P_Die ownerdie,
-		      char *producer_string, Dwarf_Error * error)
+                      char *producer_string, Dwarf_Error * error)
 {
     Dwarf_P_Attribute new_attr;
 
     if (ownerdie == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     new_attr = (Dwarf_P_Attribute)
-	_dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Attribute_s));
+        _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
     if (new_attr == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     new_attr->ar_attribute = DW_AT_producer;
@@ -741,15 +1066,15 @@
     new_attr->ar_next = 0;
 
     new_attr->ar_data =
-	(char *) _dwarf_p_get_alloc(NULL, strlen(producer_string) + 1);
+        (char *) _dwarf_p_get_alloc(ownerdie->di_dbg, strlen(producer_string)+1);
     if (new_attr->ar_data == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     strcpy(new_attr->ar_data, producer_string);
     new_attr->ar_rel_type = R_MIPS_NONE;
-    new_attr->ar_reloc_len = 0;	/* unused for R_MIPS_NONE */
+    new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
 
     /* add attribute to the die */
     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
@@ -759,8 +1084,8 @@
 
 Dwarf_P_Attribute
 dwarf_add_AT_const_value_signedint(Dwarf_P_Die ownerdie,
-				   Dwarf_Signed signed_value,
-				   Dwarf_Error * error)
+                                   Dwarf_Signed signed_value,
+                                   Dwarf_Error * error)
 {
     Dwarf_P_Attribute new_attr;
     int leb_size;
@@ -768,35 +1093,35 @@
     int res;
 
     if (ownerdie == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     new_attr = (Dwarf_P_Attribute)
-	_dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Attribute_s));
+        _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
     if (new_attr == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     new_attr->ar_attribute = DW_AT_const_value;
     new_attr->ar_attribute_form = DW_FORM_sdata;
     new_attr->ar_rel_type = R_MIPS_NONE;
-    new_attr->ar_reloc_len = 0;	/* unused for R_MIPS_NONE */
+    new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
     new_attr->ar_next = 0;
 
     res = _dwarf_pro_encode_signed_leb128_nm(signed_value, &leb_size,
-					     encode_buffer,
-					     sizeof(encode_buffer));
+                                             encode_buffer,
+                                             sizeof(encode_buffer));
     if (res != DW_DLV_OK) {
-	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
     new_attr->ar_data = (char *)
-	_dwarf_p_get_alloc(NULL, leb_size);
+        _dwarf_p_get_alloc(ownerdie->di_dbg, leb_size);
     if (new_attr->ar_data == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
     memcpy(new_attr->ar_data, encode_buffer, leb_size);
     new_attr->ar_nbytes = leb_size;
@@ -809,8 +1134,8 @@
 
 Dwarf_P_Attribute
 dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die ownerdie,
-				     Dwarf_Unsigned unsigned_value,
-				     Dwarf_Error * error)
+                                     Dwarf_Unsigned unsigned_value,
+                                     Dwarf_Error * error)
 {
     Dwarf_P_Attribute new_attr;
     int leb_size;
@@ -818,35 +1143,35 @@
     int res;
 
     if (ownerdie == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     new_attr = (Dwarf_P_Attribute)
-	_dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Attribute_s));
+        _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
     if (new_attr == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
 
     new_attr->ar_attribute = DW_AT_const_value;
     new_attr->ar_attribute_form = DW_FORM_udata;
     new_attr->ar_rel_type = R_MIPS_NONE;
-    new_attr->ar_reloc_len = 0;	/* unused for R_MIPS_NONE */
+    new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
     new_attr->ar_next = 0;
 
     res = _dwarf_pro_encode_leb128_nm(unsigned_value, &leb_size,
-				      encode_buffer,
-				      sizeof(encode_buffer));
+                                      encode_buffer,
+                                      sizeof(encode_buffer));
     if (res != DW_DLV_OK) {
-	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
     new_attr->ar_data = (char *)
-	_dwarf_p_get_alloc(NULL, leb_size);
+        _dwarf_p_get_alloc(ownerdie->di_dbg, leb_size);
     if (new_attr->ar_data == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
-	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
+        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
     }
     memcpy(new_attr->ar_data, encode_buffer, leb_size);
     new_attr->ar_nbytes = leb_size;
--- a/usr/src/tools/ctf/dwarf/common/pro_frame.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_frame.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +19,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -44,47 +44,47 @@
 #include "pro_frame.h"
 
 static void _dwarf_pro_add_to_fde(Dwarf_P_Fde fde,
-				  Dwarf_P_Frame_Pgm inst);
+                                  Dwarf_P_Frame_Pgm inst);
 
 /*-------------------------------------------------------------------------
-	This functions adds a cie struct to the debug pointer. Its in the
-	form of a linked list.
-	augmenter: string reps augmentation (implementation defined)
-	code_align: alignment of code
-	data_align: alignment of data
-	init_bytes: byts having initial instructions
-	init_n_bytes: number of bytes of initial instructions
+        This function adds a cie struct to the debug pointer. Its in the
+        form of a linked list.
+        augmenter: string reps augmentation (implementation defined)
+        code_align: alignment of code
+        data_align: alignment of data
+        init_bytes: byts having initial instructions
+        init_n_bytes: number of bytes of initial instructions
 --------------------------------------------------------------------------*/
 Dwarf_Unsigned
 dwarf_add_frame_cie(Dwarf_P_Debug dbg,
-		    char *augmenter,
-		    Dwarf_Small code_align,
-		    Dwarf_Small data_align,
-		    Dwarf_Small return_reg,
-		    Dwarf_Ptr init_bytes,
-		    Dwarf_Unsigned init_n_bytes, Dwarf_Error * error)
+                    char *augmenter,
+                    Dwarf_Small code_align,
+                    Dwarf_Small data_align,
+                    Dwarf_Small return_reg,
+                    Dwarf_Ptr init_bytes,
+                    Dwarf_Unsigned init_n_bytes, Dwarf_Error * error)
 {
     Dwarf_P_Cie curcie;
 
     if (dbg->de_frame_cies == NULL) {
-	dbg->de_frame_cies = (Dwarf_P_Cie)
-	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s));
-	if (dbg->de_frame_cies == NULL) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT);
-	}
-	curcie = dbg->de_frame_cies;
-	dbg->de_n_cie = 1;
-	dbg->de_last_cie = curcie;
+        dbg->de_frame_cies = (Dwarf_P_Cie)
+            _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s));
+        if (dbg->de_frame_cies == NULL) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT);
+        }
+        curcie = dbg->de_frame_cies;
+        dbg->de_n_cie = 1;
+        dbg->de_last_cie = curcie;
     } else {
-	curcie = dbg->de_last_cie;
-	curcie->cie_next = (Dwarf_P_Cie)
-	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s));
-	if (curcie->cie_next == NULL) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT);
-	}
-	curcie = curcie->cie_next;
-	dbg->de_n_cie++;
-	dbg->de_last_cie = curcie;
+        curcie = dbg->de_last_cie;
+        curcie->cie_next = (Dwarf_P_Cie)
+            _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s));
+        if (curcie->cie_next == NULL) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT);
+        }
+        curcie = curcie->cie_next;
+        dbg->de_n_cie++;
+        dbg->de_last_cie = curcie;
     }
     curcie->cie_version = DW_CIE_VERSION;
     curcie->cie_aug = augmenter;
@@ -99,40 +99,40 @@
 
 
 /*-------------------------------------------------------------------------
-	This functions adds a fde struct to the debug pointer. Its in the
-	form of a linked list.
-	die: subprogram/function die corresponding to this fde
-	cie: cie referred to by this fde, obtained from call to 
-	    add_frame_cie() routine.
-	virt_addr: beginning address
-	code_len: length of code reps by the fde
+        This functions adds a fde struct to the debug pointer. Its in the
+        form of a linked list.
+        die: subprogram/function die corresponding to this fde
+        cie: cie referred to by this fde, obtained from call to 
+            add_frame_cie() routine.
+        virt_addr: beginning address
+        code_len: length of code reps by the fde
 --------------------------------------------------------------------------*/
- /*ARGSUSED*/			/* pretend all args used */
+ /*ARGSUSED*/                   /* pretend all args used */
     Dwarf_Unsigned
 dwarf_add_frame_fde(Dwarf_P_Debug dbg,
-		    Dwarf_P_Fde fde,
-		    Dwarf_P_Die die,
-		    Dwarf_Unsigned cie,
-		    Dwarf_Unsigned virt_addr,
-		    Dwarf_Unsigned code_len,
-		    Dwarf_Unsigned symidx, Dwarf_Error * error)
+                    Dwarf_P_Fde fde,
+                    Dwarf_P_Die die,
+                    Dwarf_Unsigned cie,
+                    Dwarf_Unsigned virt_addr,
+                    Dwarf_Unsigned code_len,
+                    Dwarf_Unsigned symidx, Dwarf_Error * error)
 {
     return dwarf_add_frame_fde_b(dbg, fde, die, cie, virt_addr,
-				 code_len, symidx, 0, 0, error);
+                                 code_len, symidx, 0, 0, error);
 }
 
 /*ARGSUSED10*/
 Dwarf_Unsigned
 dwarf_add_frame_fde_b(Dwarf_P_Debug dbg,
-		      Dwarf_P_Fde fde,
-		      Dwarf_P_Die die,
-		      Dwarf_Unsigned cie,
-		      Dwarf_Unsigned virt_addr,
-		      Dwarf_Unsigned code_len,
-		      Dwarf_Unsigned symidx,
-		      Dwarf_Unsigned symidx_of_end,
-		      Dwarf_Addr offset_from_end_sym,
-		      Dwarf_Error * error)
+                      Dwarf_P_Fde fde,
+                      Dwarf_P_Die die,
+                      Dwarf_Unsigned cie,
+                      Dwarf_Unsigned virt_addr,
+                      Dwarf_Unsigned code_len,
+                      Dwarf_Unsigned symidx,
+                      Dwarf_Unsigned symidx_of_end,
+                      Dwarf_Addr offset_from_end_sym,
+                      Dwarf_Error * error)
 {
     Dwarf_P_Fde curfde;
 
@@ -145,77 +145,78 @@
     fde->fde_exception_table_symbol = 0;
     fde->fde_end_symbol_offset = offset_from_end_sym;
     fde->fde_end_symbol = symidx_of_end;
+    fde->fde_dbg = dbg;
 
     curfde = dbg->de_last_fde;
     if (curfde == NULL) {
-	dbg->de_frame_fdes = fde;
-	dbg->de_last_fde = fde;
-	dbg->de_n_fde = 1;
+        dbg->de_frame_fdes = fde;
+        dbg->de_last_fde = fde;
+        dbg->de_n_fde = 1;
     } else {
-	curfde->fde_next = fde;
-	dbg->de_last_fde = fde;
-	dbg->de_n_fde++;
+        curfde->fde_next = fde;
+        dbg->de_last_fde = fde;
+        dbg->de_n_fde++;
     }
     return dbg->de_n_fde;
 }
 
 /*-------------------------------------------------------------------------
-	This functions adds information to an fde. The fde is
-	linked into the linked list of fde's maintained in the Dwarf_P_Debug
-	structure.
-	dbg: The debug descriptor.
-	fde: The fde to be added.
-	die: subprogram/function die corresponding to this fde
-	cie: cie referred to by this fde, obtained from call to 
-	    add_frame_cie() routine.
-	virt_addr: beginning address
-	code_len: length of code reps by the fde
-	symidx: The symbol id of the symbol wrt to which relocation needs
-		to be performed for 'virt_addr'.
-	offset_into_exception_tables: The start of exception tables for
-		this function (indicated as an offset into the exception
-		tables). A value of -1 indicates that there is no exception
-		table entries associated with this function.
-	exception_table_symbol: The symbol id of the section for exception
-		tables wrt to which the offset_into_exception_tables will
-		be relocated.
+        This functions adds information to an fde. The fde is
+        linked into the linked list of fde's maintained in the Dwarf_P_Debug
+        structure.
+        dbg: The debug descriptor.
+        fde: The fde to be added.
+        die: subprogram/function die corresponding to this fde
+        cie: cie referred to by this fde, obtained from call to 
+            add_frame_cie() routine.
+        virt_addr: beginning address
+        code_len: length of code reps by the fde
+        symidx: The symbol id of the symbol wrt to which relocation needs
+                to be performed for 'virt_addr'.
+        offset_into_exception_tables: The start of exception tables for
+                this function (indicated as an offset into the exception
+                tables). A value of -1 indicates that there is no exception
+                table entries associated with this function.
+        exception_table_symbol: The symbol id of the section for exception
+                tables wrt to which the offset_into_exception_tables will
+                be relocated.
 --------------------------------------------------------------------------*/
 Dwarf_Unsigned
 dwarf_add_frame_info(Dwarf_P_Debug dbg,
-		     Dwarf_P_Fde fde,
-		     Dwarf_P_Die die,
-		     Dwarf_Unsigned cie,
-		     Dwarf_Unsigned virt_addr,
-		     Dwarf_Unsigned code_len,
-		     Dwarf_Unsigned symidx,
-		     Dwarf_Signed offset_into_exception_tables,
-		     Dwarf_Unsigned exception_table_symbol,
-		     Dwarf_Error * error)
+                     Dwarf_P_Fde fde,
+                     Dwarf_P_Die die,
+                     Dwarf_Unsigned cie,
+                     Dwarf_Unsigned virt_addr,
+                     Dwarf_Unsigned code_len,
+                     Dwarf_Unsigned symidx,
+                     Dwarf_Signed offset_into_exception_tables,
+                     Dwarf_Unsigned exception_table_symbol,
+                     Dwarf_Error * error)
 {
 
     return dwarf_add_frame_info_b(dbg, fde, die, cie, virt_addr,
-				  code_len, symidx,
-				  /* end_symbol */ 0,
-				  /* offset_from_end */ 0,
-				  offset_into_exception_tables,
-				  exception_table_symbol, error);
+                                  code_len, symidx,
+                                  /* end_symbol */ 0,
+                                  /* offset_from_end */ 0,
+                                  offset_into_exception_tables,
+                                  exception_table_symbol, error);
 
 }
 
- /*ARGSUSED*/			/* pretend all args used */
-    Dwarf_Unsigned
+ /*ARGSUSED*/                   /* pretend all args used */
+Dwarf_Unsigned
 dwarf_add_frame_info_b(Dwarf_P_Debug dbg,
-		       Dwarf_P_Fde fde,
-		       Dwarf_P_Die die,
-		       Dwarf_Unsigned cie,
-		       Dwarf_Unsigned virt_addr,
-		       Dwarf_Unsigned code_len,
-		       Dwarf_Unsigned symidx,
-		       Dwarf_Unsigned end_symidx,
-		       Dwarf_Unsigned offset_from_end_symbol,
-		       Dwarf_Signed offset_into_exception_tables,
-		       Dwarf_Unsigned exception_table_symbol,
-		       Dwarf_Error * error)
+                       Dwarf_P_Fde fde,
+                       Dwarf_P_Die die,
+                       Dwarf_Unsigned cie,
+                       Dwarf_Unsigned virt_addr,
+                       Dwarf_Unsigned code_len,
+                       Dwarf_Unsigned symidx,
+                       Dwarf_Unsigned end_symidx,
+                       Dwarf_Unsigned offset_from_end_symbol,
+                       Dwarf_Signed offset_into_exception_tables,
+                       Dwarf_Unsigned exception_table_symbol,
+                       Dwarf_Error * error)
 {
     Dwarf_P_Fde curfde;
 
@@ -225,28 +226,51 @@
     fde->fde_r_symidx = symidx;
     fde->fde_addr_range = code_len;
     fde->fde_offset_into_exception_tables =
-	offset_into_exception_tables;
+        offset_into_exception_tables;
     fde->fde_exception_table_symbol = exception_table_symbol;
     fde->fde_end_symbol_offset = offset_from_end_symbol;
     fde->fde_end_symbol = end_symidx;
-
+    fde->fde_dbg = dbg;
 
     curfde = dbg->de_last_fde;
     if (curfde == NULL) {
-	dbg->de_frame_fdes = fde;
-	dbg->de_last_fde = fde;
-	dbg->de_n_fde = 1;
+        dbg->de_frame_fdes = fde;
+        dbg->de_last_fde = fde;
+        dbg->de_n_fde = 1;
     } else {
-	curfde->fde_next = fde;
-	dbg->de_last_fde = fde;
-	dbg->de_n_fde++;
+        curfde->fde_next = fde;
+        dbg->de_last_fde = fde;
+        dbg->de_n_fde++;
     }
     return dbg->de_n_fde;
 }
 
+/* This is an alternate to inserting frame instructions
+   one instruction at a time.  But use either this
+   or instruction level, not both in one fde. */
+int
+dwarf_insert_fde_inst_bytes(Dwarf_P_Debug dbg,
+    Dwarf_P_Fde fde,Dwarf_Unsigned len, Dwarf_Ptr ibytes,
+    Dwarf_Error *error)
+{
+    if( len == 0) {
+        return DW_DLV_OK;
+    }
+    if(fde->fde_block || fde->fde_inst) {
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_DUPLICATE_INST_BLOCK,
+            (int)DW_DLV_BADADDR);
+    }
+    fde->fde_block = (Dwarf_Ptr)_dwarf_p_get_alloc(dbg, len);
+    memcpy(fde->fde_block,ibytes,len);
+    fde->fde_inst_block_size = len;
+    fde->fde_n_bytes += len;
+    return DW_DLV_OK;
+}
+    
+
 
 /*-------------------------------------------------------------------
-	Create a new fde 
+        Create a new fde.
 ---------------------------------------------------------------------*/
 Dwarf_P_Fde
 dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error * error)
@@ -254,27 +278,25 @@
     Dwarf_P_Fde fde;
 
     fde = (Dwarf_P_Fde)
-	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Fde_s));
+        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Fde_s));
     if (fde == NULL) {
-	DWARF_P_DBG_ERROR(dbg, DW_DLE_FDE_ALLOC,
-			  (Dwarf_P_Fde) DW_DLV_BADADDR);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_FDE_ALLOC,
+                          (Dwarf_P_Fde) DW_DLV_BADADDR);
     }
-    fde->fde_next = NULL;
-    fde->fde_inst = NULL;
-    fde->fde_n_inst = 0;
-    fde->fde_n_bytes = 0;
-    fde->fde_last_inst = NULL;
+    
     fde->fde_uwordb_size = dbg->de_offset_size;
+
     return fde;
 }
 
+
 /*------------------------------------------------------------------------
-	Add cfe_offset instruction to fde
+        Add a cfe_offset instruction to the fde passed in.
 -------------------------------------------------------------------------*/
 Dwarf_P_Fde
 dwarf_fde_cfa_offset(Dwarf_P_Fde fde,
-		     Dwarf_Unsigned reg,
-		     Dwarf_Signed offset, Dwarf_Error * error)
+                     Dwarf_Unsigned reg,
+                     Dwarf_Signed offset, Dwarf_Error * error)
 {
     Dwarf_Ubyte opc, regno;
     char *ptr;
@@ -282,31 +304,32 @@
     int nbytes;
     int res;
     char buff1[ENCODE_SPACE_NEEDED];
+    Dwarf_P_Debug dbg = fde->fde_dbg;
 
     curinst = (Dwarf_P_Frame_Pgm)
-	_dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Frame_Pgm_s));
+        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s));
     if (curinst == NULL) {
-	DWARF_P_DBG_ERROR(NULL, DW_DLE_FPGM_ALLOC,
-			  (Dwarf_P_Fde) DW_DLV_BADADDR);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_FPGM_ALLOC,
+                          (Dwarf_P_Fde) DW_DLV_BADADDR);
     }
     opc = DW_CFA_offset;
     regno = reg;
     if (regno & 0xc0) {
-	DWARF_P_DBG_ERROR(NULL, DW_DLE_REGNO_OVFL,
-			  (Dwarf_P_Fde) DW_DLV_BADADDR);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_REGNO_OVFL,
+                          (Dwarf_P_Fde) DW_DLV_BADADDR);
     }
-    opc = opc | regno;		/* lower 6 bits are register number */
+    opc = opc | regno;          /* lower 6 bits are register number */
     curinst->dfp_opcode = opc;
     res = _dwarf_pro_encode_leb128_nm(offset, &nbytes,
-				      buff1, sizeof(buff1));
+                                      buff1, sizeof(buff1));
     if (res != DW_DLV_OK) {
-	_dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
-	return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+        return ((Dwarf_P_Fde) DW_DLV_BADADDR);
     }
-    ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes);
+    ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
     if (ptr == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
-	return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+        return ((Dwarf_P_Fde) DW_DLV_BADADDR);
     }
     memcpy(ptr, buff1, nbytes);
 
@@ -329,12 +352,22 @@
     represented with relocations and symbol indices for
     DW_DLC_SYMBOLIC_RELOCATIONS.
 
+    This does not treat all DW_CFA instructions yet.
+
+    For certain operations a val? value must be
+    signed (though passed in as unsigned here).
+
+    Currently this does not check that the frame
+    version is 3(for dwarf3) or 4 (for dwarf4)
+    when applying operations that are only valid for
+    dwarf3 or dwarf4.
+
 */
 Dwarf_P_Fde
 dwarf_add_fde_inst(Dwarf_P_Fde fde,
-		   Dwarf_Small op,
-		   Dwarf_Unsigned val1,
-		   Dwarf_Unsigned val2, Dwarf_Error * error)
+                   Dwarf_Small op,
+                   Dwarf_Unsigned val1,
+                   Dwarf_Unsigned val2, Dwarf_Error * error)
 {
     Dwarf_P_Frame_Pgm curinst;
     int nbytes, nbytes1, nbytes2;
@@ -346,177 +379,190 @@
     int res;
     char buff1[ENCODE_SPACE_NEEDED];
     char buff2[ENCODE_SPACE_NEEDED];
+    Dwarf_P_Debug dbg = fde->fde_dbg;
+    /* This is a hack telling the code when to transform
+       a value to a signed leb number. */
+    int signed_second = 0;
+    int signed_first = 0;
 
 
     nbytes = 0;
     ptr = NULL;
     curinst = (Dwarf_P_Frame_Pgm)
-	_dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Frame_Pgm_s));
+        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s));
     if (curinst == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_FPGM_ALLOC);
-	return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+        _dwarf_p_error(dbg, error, DW_DLE_FPGM_ALLOC);
+        return ((Dwarf_P_Fde) DW_DLV_BADADDR);
     }
 
     switch (op) {
 
     case DW_CFA_advance_loc:
-	if (val1 <= 0x3f) {
-	    db = val1;
-	    op |= db;
-	}
-	/* test not portable FIX */
-	else if (val1 <= UCHAR_MAX) {
-	    op = DW_CFA_advance_loc1;
-	    db = val1;
-	    ptr = (char *) _dwarf_p_get_alloc(NULL, 1);
-	    if (ptr == NULL) {
-		_dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
-		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
-	    }
-	    memcpy((void *) ptr, (const void *) &db, 1);
-	    nbytes = 1;
-	}
-	/* test not portable FIX */
-	else if (val1 <= USHRT_MAX) {
-	    op = DW_CFA_advance_loc2;
-	    dh = val1;
-	    ptr = (char *) _dwarf_p_get_alloc(NULL, 2);
-	    if (ptr == NULL) {
-		_dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
-		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
-	    }
-	    memcpy((void *) ptr, (const void *) &dh, 2);
-	    nbytes = 2;
-	}
-	/* test not portable FIX */
-	else if (val1 <= ULONG_MAX) {
-	    op = DW_CFA_advance_loc4;
-	    dw = (Dwarf_Word) val1;
-	    ptr = (char *) _dwarf_p_get_alloc(NULL, 4);
-	    if (ptr == NULL) {
-		_dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
-		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
-	    }
-	    memcpy((void *) ptr, (const void *) &dw, 4);
-	    nbytes = 4;
-	} else {
-	    op = DW_CFA_MIPS_advance_loc8;
-	    du = val1;
-	    ptr =
-		(char *) _dwarf_p_get_alloc(NULL,
-					    sizeof(Dwarf_Unsigned));
-	    if (ptr == NULL) {
-		_dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
-		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
-	    }
-	    memcpy((void *) ptr, (const void *) &du, 8);
-	    nbytes = 8;
-	}
-	break;
+        if (val1 <= 0x3f) {
+            db = val1;
+            op |= db;
+        }
+        /* test not portable FIX */
+        else if (val1 <= UCHAR_MAX) {
+            op = DW_CFA_advance_loc1;
+            db = val1;
+            ptr = (char *) _dwarf_p_get_alloc(dbg, 1);
+            if (ptr == NULL) {
+                _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+                return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+            }
+            memcpy((void *) ptr, (const void *) &db, 1);
+            nbytes = 1;
+        }
+        /* test not portable FIX */
+        else if (val1 <= USHRT_MAX) {
+            op = DW_CFA_advance_loc2;
+            dh = val1;
+            ptr = (char *) _dwarf_p_get_alloc(dbg, 2);
+            if (ptr == NULL) {
+                _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+                return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+            }
+            memcpy((void *) ptr, (const void *) &dh, 2);
+            nbytes = 2;
+        }
+        /* test not portable FIX */
+        else if (val1 <= ULONG_MAX) {
+            op = DW_CFA_advance_loc4;
+            dw = (Dwarf_Word) val1;
+            ptr = (char *) _dwarf_p_get_alloc(dbg, 4);
+            if (ptr == NULL) {
+                _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+                return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+            }
+            memcpy((void *) ptr, (const void *) &dw, 4);
+            nbytes = 4;
+        } else {
+            op = DW_CFA_MIPS_advance_loc8;
+            du = val1;
+            ptr =
+                (char *) _dwarf_p_get_alloc(dbg,
+                                            sizeof(Dwarf_Unsigned));
+            if (ptr == NULL) {
+                _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+                return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+            }
+            memcpy((void *) ptr, (const void *) &du, 8);
+            nbytes = 8;
+        }
+        break;
 
     case DW_CFA_offset:
-	if (val1 <= MAX_6_BIT_VALUE) {
-	    db = val1;
-	    op |= db;
-	    res = _dwarf_pro_encode_leb128_nm(val2, &nbytes,
-					      buff1, sizeof(buff1));
-	    if (res != DW_DLV_OK) {
-		_dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
-		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
-	    }
-	    ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes);
-	    if (ptr == NULL) {
-		_dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
-		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
-	    }
-	    memcpy(ptr, buff1, nbytes);
-
-	} else {
-	    op = DW_CFA_offset_extended;
+        if (val1 <= MAX_6_BIT_VALUE) {
+            db = val1;
+            op |= db;
+            res = _dwarf_pro_encode_leb128_nm(val2, &nbytes,
+                                              buff1, sizeof(buff1));
+            if (res != DW_DLV_OK) {
+                _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+                return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+            }
+            ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
+            if (ptr == NULL) {
+                _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+                return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+            }
+            memcpy(ptr, buff1, nbytes);
 
-	    res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1,
-					      buff1, sizeof(buff1));
-	    if (res != DW_DLV_OK) {
-		_dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
-		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
-	    }
-	    res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2,
-					      buff2, sizeof(buff2));
-	    if (res != DW_DLV_OK) {
-		_dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
-		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
-	    }
-	    ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes1 + nbytes2);
-	    if (ptr == NULL) {
-		_dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
-		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
-	    }
-	    memcpy(ptr, buff1, nbytes1);
-	    memcpy(ptr + nbytes1, buff2, nbytes2);
-	    nbytes = nbytes1 + nbytes2;
-	}
-	break;
+        } else {
+            op = DW_CFA_offset_extended;
+            goto two_leb;
+        }
+        break;
+    case DW_CFA_offset_extended_sf: /* DWARF3 */
+            signed_second = 1;
+            goto two_leb;
+    case DW_CFA_offset_extended:
+            goto two_leb;
 
     case DW_CFA_undefined:
     case DW_CFA_same_value:
-	res = _dwarf_pro_encode_leb128_nm(val1, &nbytes,
-					  buff1, sizeof(buff1));
-	if (res != DW_DLV_OK) {
-	    _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
-	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
-	}
-	ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes);
-	if (ptr == NULL) {
-	    _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
-	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
-	}
-	memcpy(ptr, buff1, nbytes);
-	break;
+        goto one_leb;
 
+    case DW_CFA_val_offset:
+         goto two_leb;
+    case DW_CFA_val_offset_sf:
+         signed_second = 1;
+         goto two_leb;
+    case DW_CFA_def_cfa_sf:
+         signed_second = 1;
+         goto two_leb;
     case DW_CFA_register:
     case DW_CFA_def_cfa:
-	res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1,
-					  buff1, sizeof(buff1));
-	if (res != DW_DLV_OK) {
-	    _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
-	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
-	}
+    two_leb:
+        res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1,
+                                          buff1, sizeof(buff1));
+        if (res != DW_DLV_OK) {
+            _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+            return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+        }
+        if (!signed_second) {
+                res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2,
+                                              buff2, sizeof(buff2));
+        } else {
+            Dwarf_Signed val2s = val2;
+            res = _dwarf_pro_encode_signed_leb128_nm(val2s, &nbytes2,
+                                              buff2, sizeof(buff2));
+        }
 
-	res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2,
-					  buff2, sizeof(buff2));
-	if (res != DW_DLV_OK) {
-	    _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
-	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
-	}
+        res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2,
+                                          buff2, sizeof(buff2));
+        if (res != DW_DLV_OK) {
+            _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+            return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+        }
 
-	ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes1 + nbytes2);
-	if (ptr == NULL) {
-	    _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
-	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
-	}
-	memcpy(ptr, buff1, nbytes1);
-	memcpy(ptr + nbytes1, buff2, nbytes2);
-	nbytes = nbytes1 + nbytes2;
-	break;
+        ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes1 + nbytes2);
+        if (ptr == NULL) {
+            _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+            return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+        }
+        memcpy(ptr, buff1, nbytes1);
+        memcpy(ptr + nbytes1, buff2, nbytes2);
+        nbytes = nbytes1 + nbytes2;
+        break;
 
+    case DW_CFA_def_cfa_offset_sf: /* DWARF3 */
+        signed_first = 1;
+        goto one_leb;
     case DW_CFA_def_cfa_register:
     case DW_CFA_def_cfa_offset:
-	res = _dwarf_pro_encode_leb128_nm(val1, &nbytes,
-					  buff1, sizeof(buff1));
-	if (res != DW_DLV_OK) {
-	    _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
-	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
-	}
-	ptr = (char *) _dwarf_p_get_alloc(NULL, nbytes);
-	if (ptr == NULL) {
-	    _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
-	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
-	}
-	memcpy(ptr, buff1, nbytes);
-	break;
-
+    one_leb:
+        if(!signed_first) {
+            res = _dwarf_pro_encode_leb128_nm(val1, &nbytes,
+                                          buff1, sizeof(buff1));
+        } else {
+            Dwarf_Signed val1s = val1;
+            res = _dwarf_pro_encode_signed_leb128_nm(val1s, &nbytes,
+                                          buff1, sizeof(buff1));
+        }
+        if (res != DW_DLV_OK) {
+            _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+            return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+        }
+        ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
+        if (ptr == NULL) {
+            _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+            return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+        }
+        memcpy(ptr, buff1, nbytes);
+        break;
+    case DW_CFA_def_cfa_expression: /* DWARF3 */
+        /* FIXME: argument is dwarf expr, not handled yet. */
+    case DW_CFA_expression: /* DWARF3 */
+        /* First arg: ULEB reg num. 2nd arg dwarf expr in form block.
+           FIXME: not handled yet. */
+    case DW_CFA_val_expression: /* DWARF3f */
+        /* First arg: ULEB reg num. 2nd arg dwarf expr in form block.
+           FIXME: not handled yet. */
     default:
-	break;
+        _dwarf_p_error(dbg, error, DW_DLE_DEBUGFRAME_ERROR);
+        return ((Dwarf_P_Fde) DW_DLV_BADADDR);
     }
 
     curinst->dfp_opcode = op;
@@ -530,23 +576,23 @@
 
 
 /*------------------------------------------------------------------------
-	instructions are added to fde in the form of a linked
-	list. This function manages the linked list
+        Instructions are added to an fde in the form of a linked
+        list. This function manages the linked list.
 -------------------------------------------------------------------------*/
 void
 _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, Dwarf_P_Frame_Pgm curinst)
 {
     if (fde->fde_last_inst) {
-	fde->fde_last_inst->dfp_next = curinst;
-	fde->fde_last_inst = curinst;
-	fde->fde_n_inst++;
-	fde->fde_n_bytes +=
-	    (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte));
+        fde->fde_last_inst->dfp_next = curinst;
+        fde->fde_last_inst = curinst;
+        fde->fde_n_inst++;
+        fde->fde_n_bytes +=
+            (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte));
     } else {
-	fde->fde_last_inst = curinst;
-	fde->fde_inst = curinst;
-	fde->fde_n_inst = 1;
-	fde->fde_n_bytes =
-	    (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte));
+        fde->fde_last_inst = curinst;
+        fde->fde_inst = curinst;
+        fde->fde_n_inst = 1;
+        fde->fde_n_bytes =
+            (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte));
     }
 }
--- a/usr/src/tools/ctf/dwarf/common/pro_frame.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_frame.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -123,4 +123,10 @@
     Dwarf_Unsigned fde_end_symbol;
 
     int fde_uwordb_size;
+    Dwarf_P_Debug fde_dbg;
+
+    /* If fde_block is non-null, then it is the set of instructions.
+       so we should use it rather than fde_inst. */
+    Dwarf_Unsigned fde_inst_block_size;
+    void *fde_block;
 };
--- a/usr/src/tools/ctf/dwarf/common/pro_funcs.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_funcs.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +19,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -52,11 +52,11 @@
 */
 Dwarf_Unsigned
 dwarf_add_funcname(Dwarf_P_Debug dbg,
-		   Dwarf_P_Die die,
-		   char *function_name, Dwarf_Error * error)
+                   Dwarf_P_Die die,
+                   char *function_name, Dwarf_Error * error)
 {
     return
-	_dwarf_add_simple_name_entry(dbg, die, function_name,
-				     dwarf_snk_funcname, error);
+        _dwarf_add_simple_name_entry(dbg, die, function_name,
+                                     dwarf_snk_funcname, error);
 
 }
--- a/usr/src/tools/ctf/dwarf/common/pro_incl.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_incl.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,8 @@
 /*
 
-  Copyright (C) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
+  Portions Copyright 2008-2010 David Anderson. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +19,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -34,9 +36,17 @@
 */
 
 
-
 #ifdef HAVE_ELF_H
 #include <elf.h>
+#elif defined(HAVE_LIBELF_H) 
+/* On one platform without elf.h this gets Elf32_Rel 
+   type defined (a required type). */
+#include <libelf.h>
+#endif
+
+#if defined(sun)
+#include <sys/elf_SPARC.h>
+#include <sys/elf_386.h>
 #endif
 
 /* The target address is given: the place in the source integer
@@ -62,10 +72,19 @@
 #endif
 
 
+#if defined(sparc) && defined(sun)
+#define REL32 Elf32_Rela
+#define REL64 Elf64_Rela
+#define REL_SEC_PREFIX ".rela"
+#else
+#define REL32 Elf32_Rel
+#define REL64 Elf64_Rel
+#define REL_SEC_PREFIX ".rel"
+#endif
 
+#include "dwarf.h"
 #include "libdwarf.h"
 
-#include "dwarf.h"
 #include "pro_opaque.h"
 #include "pro_error.h"
 #include "pro_util.h"
--- a/usr/src/tools/ctf/dwarf/common/pro_init.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_init.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,8 @@
 /*
 
   Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
+  Portions Copyright 2008-2010 David Anderson, Inc. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +21,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -40,7 +42,7 @@
 #include <stdio.h>
 #include <string.h>
 #include "pro_incl.h"
-#include "pro_section.h"	/* for MAGIC_SECT_NO */
+#include "pro_section.h"        /* for MAGIC_SECT_NO */
 #include "pro_reloc_symbolic.h"
 #include "pro_reloc_stream.h"
 
@@ -50,12 +52,12 @@
 void *_dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len);
 
 /*--------------------------------------------------------------------
-	This function sets up a new dwarf producing region. 
-	flags: Indicates type of access method, one of DW_DLC* macros
-	func(): Used to create a new object file, a call back function
-	errhand(): Error Handler provided by user
-	errarg: Argument to errhand()
-	error: returned error value
+        This function sets up a new dwarf producing region. 
+        flags: Indicates type of access method, one of DW_DLC* macros
+        func(): Used to create a new object file, a call back function
+        errhand(): Error Handler provided by user
+        errarg: Argument to errhand()
+        error: returned error value
 --------------------------------------------------------------------*/
     /* We want the following to have an elf section number that matches 
        'nothing' */
@@ -65,25 +67,25 @@
 
 Dwarf_P_Debug
 dwarf_producer_init_b(Dwarf_Unsigned flags,
-		      Dwarf_Callback_Func_b func,
-		      Dwarf_Handler errhand,
-		      Dwarf_Ptr errarg, Dwarf_Error * error)
+                      Dwarf_Callback_Func_b func,
+                      Dwarf_Handler errhand,
+                      Dwarf_Ptr errarg, Dwarf_Error * error)
 {
     Dwarf_P_Debug dbg;
     dbg = (Dwarf_P_Debug) _dwarf_p_get_alloc(NULL,
-					     sizeof(struct
-						    Dwarf_P_Debug_s));
+                                             sizeof(struct
+                                                    Dwarf_P_Debug_s));
     if (dbg == NULL) {
-	DWARF_P_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC,
-			  (Dwarf_P_Debug) DW_DLV_BADADDR);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC,
+                          (Dwarf_P_Debug) DW_DLV_BADADDR);
     }
-    memset((void *) dbg,0, sizeof(struct Dwarf_P_Debug_s));
+    memset((void *) dbg, 0, sizeof(struct Dwarf_P_Debug_s));
     /* For the time being */
     if (func == NULL) {
-	DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC,
-			  (Dwarf_P_Debug) DW_DLV_BADADDR);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC,
+                          (Dwarf_P_Debug) DW_DLV_BADADDR);
     }
-    dbg->de_func_b = func;
+    dbg->de_callback_func_b = func;
     dbg->de_errhand = errhand;
     dbg->de_errarg = errarg;
     common_init(dbg, flags);
@@ -93,9 +95,9 @@
 
 Dwarf_P_Debug
 dwarf_producer_init(Dwarf_Unsigned flags,
-		    Dwarf_Callback_Func func,
-		    Dwarf_Handler errhand,
-		    Dwarf_Ptr errarg, Dwarf_Error * error)
+                    Dwarf_Callback_Func func,
+                    Dwarf_Handler errhand,
+                    Dwarf_Ptr errarg, Dwarf_Error * error)
 {
 
     Dwarf_P_Debug dbg;
@@ -103,19 +105,19 @@
 
 
     dbg = (Dwarf_P_Debug) _dwarf_p_get_alloc(NULL,
-					     sizeof(struct
-						    Dwarf_P_Debug_s));
+                                             sizeof(struct
+                                                    Dwarf_P_Debug_s));
     if (dbg == NULL) {
-	DWARF_P_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC,
-			  (Dwarf_P_Debug) DW_DLV_BADADDR);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC,
+                          (Dwarf_P_Debug) DW_DLV_BADADDR);
     }
-    memset((void *) dbg,0, sizeof(struct Dwarf_P_Debug_s));
+    memset((void *) dbg, 0, sizeof(struct Dwarf_P_Debug_s));
     /* For the time being */
     if (func == NULL) {
-	DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC,
-			  (Dwarf_P_Debug) DW_DLV_BADADDR);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC,
+                          (Dwarf_P_Debug) DW_DLV_BADADDR);
     }
-    dbg->de_func = func;
+    dbg->de_callback_func = func;
     dbg->de_errhand = errhand;
     dbg->de_errarg = errarg;
     common_init(dbg, flags);
@@ -137,31 +139,15 @@
 
 
 
-#if  defined(HAVE_DWARF2_99_EXTENSION)
-    /* Revised 64 bit output, using distingushed values. Per 1999
-       dwarf2 revision This produces 64bit extension with ia64 objects.
-
-       Some might want library run time selection of offset size. Not
-       provided here at present. */
-    dbg->de_64bit_extension = (IS_64BIT(dbg) ? 1 : 0);
-    dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4);
-    dbg->de_offset_size = (IS_64BIT(dbg) ? 8 : 4);
-    dbg->de_ptr_reloc =
-	IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg);
-    /* Non-MIPS, dwarf lengths and offsets are 32 bits even for 64bit
-       pointer environments. */
-    /* Get_REL??_isa here supports 64bit-offset dwarf. For 64bit, we
-       emit the extension bytes. */
-
-    dbg->de_offset_reloc = IS_64BIT(dbg) ? Get_REL64_isa(dbg)
-	: Get_REL32_isa(dbg);
-#elif defined(HAVE_OLD_DWARF2_32BIT_OFFSET)
-    /* This is cygnus 32bit offset, as specified in pure dwarf2 v2.0.0 */
+#if defined(HAVE_STRICT_DWARF2_32BIT_OFFSET)
+    /* This is cygnus 32bit offset, as specified in pure dwarf2 v2.0.0.
+       It is consistent with normal DWARF2/3 generation of always
+       generating 32 bit offsets. */
     dbg->de_64bit_extension = 0;
     dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4);
     dbg->de_offset_size = (IS_64BIT(dbg) ? 4 : 4);
     dbg->de_ptr_reloc =
-	IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg);
+        IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg);
     /* non-MIPS, dwarf lengths and offsets are 32 bits even for 64bit
        pointer environments. */
     /* Get_REL32_isa here supports 64-bit-pointer dwarf with pure
@@ -169,62 +155,88 @@
        pure 32 bit offset dwarf for 32bit pointer apps. */
 
     dbg->de_offset_reloc = Get_REL32_isa(dbg);
-#else
-    /* MIPS-SGI 32 or 64, where offsets and lengths are both 64 bit for 
-       64bit pointer objects and both 32 bit for 32bit pointer
-       objects. And a dwarf-reader must check elf info to tell which
-       applies. */
+#elif defined(HAVE_SGI_IRIX_OFFSETS) 
+    /* MIPS-SGI-IRIX 32 or 64, where offsets and lengths are both 64 bit for 
+       64bit pointer objects and both 32 bit for 32bit pointer objects. 
+       And a dwarf-reader must check elf info to tell which applies. */
     dbg->de_64bit_extension = 0;
     dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4);
     dbg->de_offset_size = (IS_64BIT(dbg) ? 8 : 4);
     dbg->de_ptr_reloc =
-	IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg);
+        IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg);
     dbg->de_offset_reloc = dbg->de_ptr_reloc;
-#endif
+#else /* HAVE_DWARF2_99_EXTENSION or default. */ 
+    /* Revised 64 bit output, using distingushed values. Per 1999
+       dwarf3.  This allows run-time selection of offset size.  */
+    dbg->de_64bit_extension = (IS_64BIT(dbg) ? 1 : 0);
+    dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4);
+    if( flags & DW_DLC_OFFSET_SIZE_64 && (dbg->de_pointer_size == 8)) {
+        /* When it's 64 bit address, a 64bit offset is sensible.
+           Arguably a 32 bit address with 64 bit offset could be
+           sensible, but who would want that? */
+        dbg->de_offset_size = 8;
+        dbg->de_64bit_extension = 1;
+    }  else {
+        dbg->de_offset_size = 4;
+        dbg->de_64bit_extension = 0;
+    }
+    dbg->de_ptr_reloc =
+        IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg);
+    /* Non-MIPS, dwarf lengths and offsets are 32 bits even for 64bit
+       pointer environments. */
+    /* Get_REL??_isa here supports 64bit-offset dwarf. For 64bit, we
+       emit the extension bytes. */
+
+    dbg->de_offset_reloc = IS_64BIT(dbg) ? Get_REL64_isa(dbg)
+        : Get_REL32_isa(dbg);
+#endif /*  HAVE_DWARF2_99_EXTENSION etc. */
+
     dbg->de_exc_reloc = Get_REL_SEGREL_isa(dbg);
 
     dbg->de_is_64bit = IS_64BIT(dbg);
 
 
     if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) {
-	dbg->de_relocation_record_size =
-	    sizeof(struct Dwarf_Relocation_Data_s);
+        dbg->de_relocation_record_size =
+            sizeof(struct Dwarf_Relocation_Data_s);
     } else {
+        
 #if HAVE_ELF64_GETEHDR
-	dbg->de_relocation_record_size =
-	    IS_64BIT(dbg) ? sizeof(Elf64_Rel) : sizeof(Elf32_Rel);
+        dbg->de_relocation_record_size =
+            IS_64BIT(dbg)? sizeof(REL64) : sizeof(REL32);
 #else
-	dbg->de_relocation_record_size = sizeof(Elf32_Rel);
+        dbg->de_relocation_record_size = sizeof(REL32);
 #endif
+
     }
 
     if (dbg->de_offset_size == 8) {
-	dbg->de_ar_data_attribute_form = DW_FORM_data8;
-	dbg->de_ar_ref_attr_form = DW_FORM_ref8;
+        dbg->de_ar_data_attribute_form = DW_FORM_data8;
+        dbg->de_ar_ref_attr_form = DW_FORM_ref8;
     } else {
-	dbg->de_ar_data_attribute_form = DW_FORM_data4;
-	dbg->de_ar_ref_attr_form = DW_FORM_ref4;
+        dbg->de_ar_data_attribute_form = DW_FORM_data4;
+        dbg->de_ar_ref_attr_form = DW_FORM_ref4;
     }
 
     if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) {
-	dbg->de_reloc_name = _dwarf_pro_reloc_name_symbolic;
-	dbg->de_reloc_pair = _dwarf_pro_reloc_length_symbolic;
-	dbg->de_transform_relocs_to_disk =
-	    _dwarf_symbolic_relocs_to_disk;
+        dbg->de_reloc_name = _dwarf_pro_reloc_name_symbolic;
+        dbg->de_reloc_pair = _dwarf_pro_reloc_length_symbolic;
+        dbg->de_transform_relocs_to_disk =
+            _dwarf_symbolic_relocs_to_disk;
     } else {
-	if (IS_64BIT(dbg)) {
-	    dbg->de_reloc_name = _dwarf_pro_reloc_name_stream64;
-	} else {
-	    dbg->de_reloc_name = _dwarf_pro_reloc_name_stream32;
-	}
-	dbg->de_reloc_pair = 0;
-	dbg->de_transform_relocs_to_disk = _dwarf_stream_relocs_to_disk;
+        if (IS_64BIT(dbg)) {
+            dbg->de_reloc_name = _dwarf_pro_reloc_name_stream64;
+        } else {
+            dbg->de_reloc_name = _dwarf_pro_reloc_name_stream32;
+        }
+        dbg->de_reloc_pair = 0;
+        dbg->de_transform_relocs_to_disk = _dwarf_stream_relocs_to_disk;
     }
     for (k = 0; k < NUM_DEBUG_SECTIONS; ++k) {
 
-	Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[k];
+        Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[k];
 
-	prel->pr_slots_per_block_to_alloc = DEFAULT_SLOTS_PER_BLOCK;
+        prel->pr_slots_per_block_to_alloc = DEFAULT_SLOTS_PER_BLOCK;
     }
     /* First assume host, target same endianness */
     dbg->de_same_endian = 1;
@@ -232,14 +244,14 @@
 #ifdef WORDS_BIGENDIAN
     /* host is big endian, so what endian is target? */
     if (flags & DW_DLC_TARGET_LITTLEENDIAN) {
-	dbg->de_same_endian = 0;
-	dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
+        dbg->de_same_endian = 0;
+        dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
     }
 #else /* little endian */
     /* host is little endian, so what endian is target? */
     if (flags & DW_DLC_TARGET_BIGENDIAN) {
-	dbg->de_same_endian = 0;
-	dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
+        dbg->de_same_endian = 0;
+        dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
     }
 #endif /* !WORDS_BIGENDIAN */
 
--- a/usr/src/tools/ctf/dwarf/common/pro_line.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_line.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +19,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -46,116 +46,116 @@
 #include "pro_line.h"
 
 Dwarf_Unsigned _dwarf_pro_add_line_entry(Dwarf_P_Debug,
-					 Dwarf_Unsigned file_index,
-					 Dwarf_Addr code_address,
-					 Dwarf_Unsigned symidx,
-					 Dwarf_Unsigned line_no,
-					 Dwarf_Signed col_no,
-					 Dwarf_Bool is_stmt_begin,
-					 Dwarf_Bool is_bb_begin,
-					 Dwarf_Ubyte opc,
-					 Dwarf_Error * error);
+                                         Dwarf_Unsigned file_index,
+                                         Dwarf_Addr code_address,
+                                         Dwarf_Unsigned symidx,
+                                         Dwarf_Unsigned line_no,
+                                         Dwarf_Signed col_no,
+                                         Dwarf_Bool is_stmt_begin,
+                                         Dwarf_Bool is_bb_begin,
+                                         Dwarf_Ubyte opc,
+                                         Dwarf_Error * error);
 
 /*-------------------------------------------------------------------------
-	Add a entry to the line information section
-	file_index: index of file in file entries, obtained from
-	add_file_entry() call. 
-	
-	This function actually calls _dwarf_pro_add_line_entry(), with
-	an extra parameter, the opcode. Done so that interface calls
-	dwarf_lne_set_address() and dwarf_lne_end_sequence() can use
-	this internal routine.
+        Add a entry to the line information section
+        file_index: index of file in file entries, obtained from
+        add_file_entry() call. 
+        
+        This function actually calls _dwarf_pro_add_line_entry(), with
+        an extra parameter, the opcode. Done so that interface calls
+        dwarf_lne_set_address() and dwarf_lne_end_sequence() can use
+        this internal routine.
 ---------------------------------------------------------------------------*/
 Dwarf_Unsigned
 dwarf_add_line_entry(Dwarf_P_Debug dbg,
-		     Dwarf_Unsigned file_index,
-		     Dwarf_Addr code_address,
-		     Dwarf_Unsigned line_no,
-		     Dwarf_Signed col_no,
-		     Dwarf_Bool is_stmt_begin,
-		     Dwarf_Bool is_bb_begin, Dwarf_Error * error)
+                     Dwarf_Unsigned file_index,
+                     Dwarf_Addr code_address,
+                     Dwarf_Unsigned line_no,
+                     Dwarf_Signed col_no,
+                     Dwarf_Bool is_stmt_begin,
+                     Dwarf_Bool is_bb_begin, Dwarf_Error * error)
 {
     Dwarf_Unsigned retval;
 
     retval = _dwarf_pro_add_line_entry(dbg, file_index, code_address, 0,
-				       line_no, col_no, is_stmt_begin,
-				       is_bb_begin, 0, error);
+                                       line_no, col_no, is_stmt_begin,
+                                       is_bb_begin, 0, error);
     return retval;
 }
 
 /*------------------------------------------------------------------------
-	Ask to emit DW_LNE_set_address opcode explicitly. Used by be
-	to emit start of a new .text section, or to force a relocated
-	address into debug line information entry.
+        Ask to emit DW_LNE_set_address opcode explicitly. Used by be
+        to emit start of a new .text section, or to force a relocated
+        address into debug line information entry.
 -------------------------------------------------------------------------*/
 Dwarf_Unsigned
 dwarf_lne_set_address(Dwarf_P_Debug dbg,
-		      Dwarf_Addr offs,
-		      Dwarf_Unsigned symidx, Dwarf_Error * error)
+                      Dwarf_Addr offs,
+                      Dwarf_Unsigned symidx, Dwarf_Error * error)
 {
     Dwarf_Ubyte opc;
     Dwarf_Unsigned retval;
 
     opc = DW_LNE_set_address;
     retval =
-	_dwarf_pro_add_line_entry(dbg, 0, offs, symidx, 0, 0, 0, 0, opc,
-				  error);
+        _dwarf_pro_add_line_entry(dbg, 0, offs, symidx, 0, 0, 0, 0, opc,
+                                  error);
     return retval;
 }
 
 /*------------------------------------------------------------------------
-	Ask to emit end_seqence opcode. Used normally at the end of a 
-	compilation unit. Can also be used in the middle if there
-	are gaps in the region described by the code address. 
+        Ask to emit end_seqence opcode. Used normally at the end of a 
+        compilation unit. Can also be used in the middle if there
+        are gaps in the region described by the code address. 
 -------------------------------------------------------------------------*/
 Dwarf_Unsigned
 dwarf_lne_end_sequence(Dwarf_P_Debug dbg,
-		       Dwarf_Addr end_address, Dwarf_Error * error)
+                       Dwarf_Addr end_address, Dwarf_Error * error)
 {
     Dwarf_Ubyte opc;
     Dwarf_Unsigned retval;
 
     opc = DW_LNE_end_sequence;
     retval =
-	_dwarf_pro_add_line_entry(dbg, 0, end_address, 0, 0, 0, 0, 0,
-				  opc, error);
+        _dwarf_pro_add_line_entry(dbg, 0, end_address, 0, 0, 0, 0, 0,
+                                  opc, error);
     return retval;
 }
 
 /*----------------------------------------------------------------------------
-	Add an entry in the internal list of lines mantained by producer. 
-	Opc indicates if an opcode needs to be generated, rather than just
-	an entry in the matrix. During opcodes generation time, these 
-	opcodes will be used.
+        Add an entry in the internal list of lines mantained by producer. 
+        Opc indicates if an opcode needs to be generated, rather than just
+        an entry in the matrix. During opcodes generation time, these 
+        opcodes will be used.
 -----------------------------------------------------------------------------*/
 Dwarf_Unsigned
 _dwarf_pro_add_line_entry(Dwarf_P_Debug dbg,
-			  Dwarf_Unsigned file_index,
-			  Dwarf_Addr code_address,
-			  Dwarf_Unsigned symidx,
-			  Dwarf_Unsigned line_no,
-			  Dwarf_Signed col_no,
-			  Dwarf_Bool is_stmt_begin,
-			  Dwarf_Bool is_bb_begin,
-			  Dwarf_Ubyte opc, Dwarf_Error * error)
+                          Dwarf_Unsigned file_index,
+                          Dwarf_Addr code_address,
+                          Dwarf_Unsigned symidx,
+                          Dwarf_Unsigned line_no,
+                          Dwarf_Signed col_no,
+                          Dwarf_Bool is_stmt_begin,
+                          Dwarf_Bool is_bb_begin,
+                          Dwarf_Ubyte opc, Dwarf_Error * error)
 {
     if (dbg->de_lines == NULL) {
-	dbg->de_lines = (Dwarf_P_Line)
-	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
-	if (dbg->de_lines == NULL) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_NOCOUNT);
-	}
-	dbg->de_last_line = dbg->de_lines;
-	_dwarf_pro_reg_init(dbg->de_lines);
+        dbg->de_lines = (Dwarf_P_Line)
+            _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
+        if (dbg->de_lines == NULL) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_NOCOUNT);
+        }
+        dbg->de_last_line = dbg->de_lines;
+        _dwarf_pro_reg_init(dbg->de_lines);
 
     } else {
-	dbg->de_last_line->dpl_next = (Dwarf_P_Line)
-	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
-	if (dbg->de_last_line->dpl_next == NULL) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_NOCOUNT);
-	}
-	dbg->de_last_line = dbg->de_last_line->dpl_next;
-	_dwarf_pro_reg_init(dbg->de_last_line);
+        dbg->de_last_line->dpl_next = (Dwarf_P_Line)
+            _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
+        if (dbg->de_last_line->dpl_next == NULL) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_NOCOUNT);
+        }
+        dbg->de_last_line = dbg->de_last_line->dpl_next;
+        _dwarf_pro_reg_init(dbg->de_last_line);
     }
     dbg->de_last_line->dpl_address = code_address;
     dbg->de_last_line->dpl_file = (unsigned long) file_index;
@@ -170,34 +170,34 @@
 }
 
 /*-----------------------------------------------------------------------
-	Add a directory declaration to the debug_line section. Stored
-	in linked list.
+        Add a directory declaration to the debug_line section. Stored
+        in linked list.
 ------------------------------------------------------------------------*/
 Dwarf_Unsigned
 dwarf_add_directory_decl(Dwarf_P_Debug dbg,
-			 char *name, Dwarf_Error * error)
+                         char *name, Dwarf_Error * error)
 {
     if (dbg->de_inc_dirs == NULL) {
-	dbg->de_inc_dirs = (Dwarf_P_Inc_Dir)
-	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Inc_Dir_s));
-	if (dbg->de_inc_dirs == NULL) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, DW_DLV_NOCOUNT);
-	}
-	dbg->de_last_inc_dir = dbg->de_inc_dirs;
-	dbg->de_n_inc_dirs = 1;
+        dbg->de_inc_dirs = (Dwarf_P_Inc_Dir)
+            _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Inc_Dir_s));
+        if (dbg->de_inc_dirs == NULL) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, DW_DLV_NOCOUNT);
+        }
+        dbg->de_last_inc_dir = dbg->de_inc_dirs;
+        dbg->de_n_inc_dirs = 1;
     } else {
-	dbg->de_last_inc_dir->did_next = (Dwarf_P_Inc_Dir)
-	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Inc_Dir_s));
-	if (dbg->de_last_inc_dir->did_next == NULL) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, DW_DLV_NOCOUNT);
-	}
-	dbg->de_last_inc_dir = dbg->de_last_inc_dir->did_next;
-	dbg->de_n_inc_dirs++;
+        dbg->de_last_inc_dir->did_next = (Dwarf_P_Inc_Dir)
+            _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Inc_Dir_s));
+        if (dbg->de_last_inc_dir->did_next == NULL) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, DW_DLV_NOCOUNT);
+        }
+        dbg->de_last_inc_dir = dbg->de_last_inc_dir->did_next;
+        dbg->de_n_inc_dirs++;
     }
     dbg->de_last_inc_dir->did_name =
-	(char *) _dwarf_p_get_alloc(dbg, strlen(name) + 1);
+        (char *) _dwarf_p_get_alloc(dbg, strlen(name) + 1);
     if (dbg->de_last_inc_dir->did_name == NULL) {
-	DWARF_P_DBG_ERROR(dbg, DW_DLE_STRING_ALLOC, DW_DLV_NOCOUNT);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_STRING_ALLOC, DW_DLV_NOCOUNT);
     }
     strcpy(dbg->de_last_inc_dir->did_name, name);
     dbg->de_last_inc_dir->did_next = NULL;
@@ -206,16 +206,16 @@
 }
 
 /*-----------------------------------------------------------------------
-	Add a file entry declaration to the debug_line section. Stored
-	in linked list. The data is immediately encodes as leb128
-	and stored in Dwarf_P_F_Entry_s struct.
+        Add a file entry declaration to the debug_line section. Stored
+        in linked list. The data is immediately encodes as leb128
+        and stored in Dwarf_P_F_Entry_s struct.
 ------------------------------------------------------------------------*/
 Dwarf_Unsigned
 dwarf_add_file_decl(Dwarf_P_Debug dbg,
-		    char *name,
-		    Dwarf_Unsigned dir_idx,
-		    Dwarf_Unsigned time_mod,
-		    Dwarf_Unsigned length, Dwarf_Error * error)
+                    char *name,
+                    Dwarf_Unsigned dir_idx,
+                    Dwarf_Unsigned time_mod,
+                    Dwarf_Unsigned length, Dwarf_Error * error)
 {
     Dwarf_P_F_Entry cur;
     char *ptr;
@@ -226,48 +226,48 @@
     int res;
 
     if (dbg->de_file_entries == NULL) {
-	dbg->de_file_entries = (Dwarf_P_F_Entry)
-	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s));
-	if (dbg->de_file_entries == NULL) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_FILE_ENTRY_ALLOC,
-			      DW_DLV_NOCOUNT);
-	}
-	cur = dbg->de_file_entries;
-	dbg->de_last_file_entry = cur;
-	dbg->de_n_file_entries = 1;
+        dbg->de_file_entries = (Dwarf_P_F_Entry)
+            _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s));
+        if (dbg->de_file_entries == NULL) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_FILE_ENTRY_ALLOC,
+                              DW_DLV_NOCOUNT);
+        }
+        cur = dbg->de_file_entries;
+        dbg->de_last_file_entry = cur;
+        dbg->de_n_file_entries = 1;
     } else {
-	cur = dbg->de_last_file_entry;
-	cur->dfe_next = (Dwarf_P_F_Entry)
-	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s));
-	if (cur->dfe_next == NULL) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_FILE_ENTRY_ALLOC,
-			      DW_DLV_NOCOUNT);
-	}
-	cur = cur->dfe_next;
-	dbg->de_last_file_entry = cur;
-	dbg->de_n_file_entries++;
+        cur = dbg->de_last_file_entry;
+        cur->dfe_next = (Dwarf_P_F_Entry)
+            _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s));
+        if (cur->dfe_next == NULL) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_FILE_ENTRY_ALLOC,
+                              DW_DLV_NOCOUNT);
+        }
+        cur = cur->dfe_next;
+        dbg->de_last_file_entry = cur;
+        dbg->de_n_file_entries++;
     }
     cur->dfe_name = (char *) _dwarf_p_get_alloc(dbg, strlen(name) + 1);
     if (cur->dfe_name == NULL) {
-	DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT);
     }
     strcpy((char *) cur->dfe_name, name);
     res = _dwarf_pro_encode_leb128_nm(dir_idx, &nbytes_idx,
-				      buffidx, sizeof(buffidx));
+                                      buffidx, sizeof(buffidx));
     if (res != DW_DLV_OK) {
-	DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT);
     }
     res = _dwarf_pro_encode_leb128_nm(time_mod, &nbytes_time,
-				      bufftime, sizeof(bufftime));
+                                      bufftime, sizeof(bufftime));
     if (res != DW_DLV_OK) {
-	DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT);
     }
     res = _dwarf_pro_encode_leb128_nm(length, &nbytes_len,
-				      bufflen, sizeof(bufflen));
+                                      bufflen, sizeof(bufflen));
     cur->dfe_args = (char *)
-	_dwarf_p_get_alloc(dbg, nbytes_idx + nbytes_time + nbytes_len);
+        _dwarf_p_get_alloc(dbg, nbytes_idx + nbytes_time + nbytes_len);
     if (cur->dfe_args == NULL) {
-	DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT);
     }
     ptr = cur->dfe_args;
     memcpy((void *) ptr, buffidx, nbytes_idx);
@@ -284,8 +284,8 @@
 
 
 /*---------------------------------------------------------------------
-	Initialize a row of the matrix for line numbers, meaning 
-	initialize the struct corresponding to it
+        Initialize a row of the matrix for line numbers, meaning 
+        initialize the struct corresponding to it
 ----------------------------------------------------------------------*/
 void
 _dwarf_pro_reg_init(Dwarf_P_Line cur_line)
--- a/usr/src/tools/ctf/dwarf/common/pro_line.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_line.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +18,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -36,7 +37,11 @@
 
 
 #define VERSION				2
+#ifdef __i386
+#define MIN_INST_LENGTH			1
+#else
 #define MIN_INST_LENGTH			4
+#endif
 #define DEFAULT_IS_STMT			false
 			/* line base and range are temporarily defines.
 			   They need to be calculated later */
--- a/usr/src/tools/ctf/dwarf/common/pro_macinfo.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_macinfo.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +19,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -44,11 +44,11 @@
 #include "pro_macinfo.h"
 
 /*
-	I don't much like the error strings this generates, since
-	like the rest of libdwarf they are simple strings with
-	no useful numbers in them. But that's not something I can
-	fix without more work than I have time for
-	right now.  davea Nov 94.
+        I don't much like the error strings this generates, since
+        like the rest of libdwarf they are simple strings with
+        no useful numbers in them. But that's not something I can
+        fix without more work than I have time for
+        right now.  davea Nov 94.
 */
 
 /* these are gross overestimates of the number of
@@ -64,67 +64,67 @@
 
 static int
 libdwarf_compose_begin(Dwarf_P_Debug dbg, int code,
-		       size_t maxlen, int *compose_error_type)
+                       size_t maxlen, int *compose_error_type)
 {
     unsigned char *nextchar;
     struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo;
 
     if (curblk == 0) {
-	struct dw_macinfo_block_s *newb;
-	size_t len;
+        struct dw_macinfo_block_s *newb;
+        size_t len;
 
-	/* initial allocation */
-	size_t blen = BASE_MACINFO_MALLOC_LEN;
+        /* initial allocation */
+        size_t blen = BASE_MACINFO_MALLOC_LEN;
 
-	if (blen < maxlen) {
-	    blen = 2 * maxlen;
-	}
-	len = sizeof(struct dw_macinfo_block_s) + blen;
-	newb =
-	    (struct dw_macinfo_block_s *) _dwarf_p_get_alloc(dbg, len);
-	if (!newb) {
-	    *compose_error_type = DW_DLE_MACINFO_MALLOC_FAIL;
-	    return DW_DLV_ERROR;
-	}
-	newb->mb_data =
-	    (char *) newb + sizeof(struct dw_macinfo_block_s);
-	newb->mb_avail_len = blen;
-	newb->mb_used_len = 0;
-	newb->mb_macinfo_data_space_len = blen;
-	dbg->de_first_macinfo = newb;
-	dbg->de_current_macinfo = newb;
-	curblk = newb;
+        if (blen < maxlen) {
+            blen = 2 * maxlen;
+        }
+        len = sizeof(struct dw_macinfo_block_s) + blen;
+        newb =
+            (struct dw_macinfo_block_s *) _dwarf_p_get_alloc(dbg, len);
+        if (!newb) {
+            *compose_error_type = DW_DLE_MACINFO_MALLOC_FAIL;
+            return DW_DLV_ERROR;
+        }
+        newb->mb_data =
+            (char *) newb + sizeof(struct dw_macinfo_block_s);
+        newb->mb_avail_len = blen;
+        newb->mb_used_len = 0;
+        newb->mb_macinfo_data_space_len = blen;
+        dbg->de_first_macinfo = newb;
+        dbg->de_current_macinfo = newb;
+        curblk = newb;
     } else if (curblk->mb_avail_len < maxlen) {
-	struct dw_macinfo_block_s *newb;
-	size_t len;
+        struct dw_macinfo_block_s *newb;
+        size_t len;
 
-	/* no space left in block: allocate a new block */
-	size_t blen =
-	    dbg->de_current_macinfo->mb_macinfo_data_space_len * 2;
-	if (blen < maxlen) {
-	    blen = 2 * maxlen;
-	}
-	len = sizeof(struct dw_macinfo_block_s) + blen;
-	newb =
-	    (struct dw_macinfo_block_s *) _dwarf_p_get_alloc(dbg, len);
-	if (!newb) {
-	    *compose_error_type = DW_DLE_MACINFO_MALLOC_FAIL;
-	    return DW_DLV_ERROR;
-	}
-	newb->mb_data =
-	    (char *) newb + sizeof(struct dw_macinfo_block_s);
-	newb->mb_avail_len = blen;
-	newb->mb_used_len = 0;
-	newb->mb_macinfo_data_space_len = blen;
-	dbg->de_first_macinfo->mb_next = newb;
-	dbg->de_current_macinfo = newb;
-	curblk = newb;
+        /* no space left in block: allocate a new block */
+        size_t blen =
+            dbg->de_current_macinfo->mb_macinfo_data_space_len * 2;
+        if (blen < maxlen) {
+            blen = 2 * maxlen;
+        }
+        len = sizeof(struct dw_macinfo_block_s) + blen;
+        newb =
+            (struct dw_macinfo_block_s *) _dwarf_p_get_alloc(dbg, len);
+        if (!newb) {
+            *compose_error_type = DW_DLE_MACINFO_MALLOC_FAIL;
+            return DW_DLV_ERROR;
+        }
+        newb->mb_data =
+            (char *) newb + sizeof(struct dw_macinfo_block_s);
+        newb->mb_avail_len = blen;
+        newb->mb_used_len = 0;
+        newb->mb_macinfo_data_space_len = blen;
+        dbg->de_first_macinfo->mb_next = newb;
+        dbg->de_current_macinfo = newb;
+        curblk = newb;
     }
     /* now curblk has enough room */
     dbg->de_compose_avail = curblk->mb_avail_len;
     dbg->de_compose_used_len = curblk->mb_used_len;
     nextchar =
-	(unsigned char *) (curblk->mb_data + dbg->de_compose_used_len);
+        (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len);
     *nextchar = code;
     dbg->de_compose_avail--;
     ++dbg->de_compose_used_len;
@@ -140,9 +140,9 @@
     unsigned char *nextchar;
 
     nextchar =
-	(unsigned char *) (curblk->mb_data + dbg->de_compose_used_len);
+        (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len);
 
-    len += 1;			/* count the null terminator */
+    len += 1;                   /* count the null terminator */
 
     memcpy(nextchar, string, len);
     dbg->de_compose_avail -= len;
@@ -152,7 +152,7 @@
 }
 static int
 libdwarf_compose_add_line(Dwarf_P_Debug dbg,
-			  Dwarf_Unsigned line, int *compose_error_type)
+                          Dwarf_Unsigned line, int *compose_error_type)
 {
     struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo;
     unsigned char *nextchar;
@@ -160,18 +160,18 @@
     int nbytes;
 
     nextchar =
-	(unsigned char *) (curblk->mb_data + dbg->de_compose_used_len);
+        (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len);
 
     /* Put the created leb number directly into the macro buffer If
        dbg->de_compose_avail is > INT_MAX this will not work as the
        'int' will look negative to _dwarf_pro_encode_leb128_nm! */
 
     res = _dwarf_pro_encode_leb128_nm(line, &nbytes,
-				      (char *) nextchar,
-				      (int) dbg->de_compose_avail);
+                                      (char *) nextchar,
+                                      (int) dbg->de_compose_avail);
     if (res != DW_DLV_OK) {
-	*compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE;
-	return DW_DLV_ERROR;
+        *compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE;
+        return DW_DLV_ERROR;
     }
 
     dbg->de_compose_avail -= nbytes;
@@ -189,8 +189,8 @@
     struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo;
 
     if (dbg->de_compose_used_len > curblk->mb_macinfo_data_space_len) {
-	*compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE;
-	return DW_DLV_ERROR;
+        *compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE;
+        return DW_DLV_ERROR;
     }
     curblk->mb_avail_len = dbg->de_compose_avail;
     curblk->mb_used_len = dbg->de_compose_used_len;
@@ -201,8 +201,8 @@
 
 int
 dwarf_def_macro(Dwarf_P_Debug dbg,
-		Dwarf_Unsigned line,
-		char *macname, char *macvalue, Dwarf_Error * error)
+                Dwarf_Unsigned line,
+                char *macname, char *macvalue, Dwarf_Error * error)
 {
     size_t len;
     size_t len2;
@@ -211,58 +211,58 @@
     int compose_error_type;
 
     if (dbg == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
     if (macname == 0) {
-	_dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL);
+        return (DW_DLV_ERROR);
     }
     len = strlen(macname) + 1;
     if (len == 0) {
-	_dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY);
+        return (DW_DLV_ERROR);
     }
     if (macvalue) {
-	len2 = strlen(macvalue) + 1;
+        len2 = strlen(macvalue) + 1;
     } else {
-	len2 = 0;
+        len2 = 0;
     }
-    length_est = COMMAND_LEN + LINE_LEN + len + len2 + 1;	/* 1
-								   for
-								   space 
-								   character 
-								   we
-								   add */
+    length_est = COMMAND_LEN + LINE_LEN + len + len2 + 1;       /* 1
+                                                                   for
+                                                                   space 
+                                                                   character 
+                                                                   we
+                                                                   add */
     res = libdwarf_compose_begin(dbg, DW_MACINFO_define, length_est,
-				 &compose_error_type);
+                                 &compose_error_type);
     if (res != DW_DLV_OK) {
-	_dwarf_p_error(NULL, error, compose_error_type);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, compose_error_type);
+        return (DW_DLV_ERROR);
     }
     res = libdwarf_compose_add_line(dbg, line, &compose_error_type);
     if (res != DW_DLV_OK) {
-	_dwarf_p_error(NULL, error, compose_error_type);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, compose_error_type);
+        return (DW_DLV_ERROR);
     }
     libdwarf_compose_add_string(dbg, macname, len);
     libdwarf_compose_add_string(dbg, " ", 1);
     if (macvalue) {
-	libdwarf_compose_add_string(dbg, " ", 1);
-	libdwarf_compose_add_string(dbg, macvalue, len2);
+        libdwarf_compose_add_string(dbg, " ", 1);
+        libdwarf_compose_add_string(dbg, macvalue, len2);
     }
     res = libdwarf_compose_complete(dbg, &compose_error_type);
     if (res != DW_DLV_OK) {
-	_dwarf_p_error(NULL, error, compose_error_type);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, compose_error_type);
+        return (DW_DLV_ERROR);
     }
     return DW_DLV_OK;
 }
 
 int
 dwarf_undef_macro(Dwarf_P_Debug dbg,
-		  Dwarf_Unsigned line,
-		  char *macname, Dwarf_Error * error)
+                  Dwarf_Unsigned line,
+                  char *macname, Dwarf_Error * error)
 {
 
     size_t len;
@@ -271,70 +271,70 @@
     int compose_error_type;
 
     if (dbg == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
     if (macname == 0) {
-	_dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL);
+        return (DW_DLV_ERROR);
     }
     len = strlen(macname) + 1;
     if (len == 0) {
-	_dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY);
+        return (DW_DLV_ERROR);
     }
     length_est = COMMAND_LEN + LINE_LEN + len;
     res = libdwarf_compose_begin(dbg, DW_MACINFO_undef, length_est,
-				 &compose_error_type);
+                                 &compose_error_type);
     if (res != DW_DLV_OK) {
-	_dwarf_p_error(NULL, error, compose_error_type);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, compose_error_type);
+        return (DW_DLV_ERROR);
     }
     res = libdwarf_compose_add_line(dbg, line, &compose_error_type);
     if (res != DW_DLV_OK) {
-	_dwarf_p_error(NULL, error, compose_error_type);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, compose_error_type);
+        return (DW_DLV_ERROR);
     }
     libdwarf_compose_add_string(dbg, macname, len);
     res = libdwarf_compose_complete(dbg, &compose_error_type);
     if (res != DW_DLV_OK) {
-	_dwarf_p_error(NULL, error, compose_error_type);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, compose_error_type);
+        return (DW_DLV_ERROR);
     }
     return DW_DLV_OK;
 }
 
 int
 dwarf_start_macro_file(Dwarf_P_Debug dbg,
-		       Dwarf_Unsigned fileindex,
-		       Dwarf_Unsigned linenumber, Dwarf_Error * error)
+                       Dwarf_Unsigned fileindex,
+                       Dwarf_Unsigned linenumber, Dwarf_Error * error)
 {
     size_t length_est;
     int res;
     int compose_error_type;
 
     if (dbg == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
     length_est = COMMAND_LEN + LINE_LEN + LINE_LEN;
     res = libdwarf_compose_begin(dbg, DW_MACINFO_start_file, length_est,
-				 &compose_error_type);
+                                 &compose_error_type);
     if (res != DW_DLV_OK) {
-	_dwarf_p_error(NULL, error, compose_error_type);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, compose_error_type);
+        return (DW_DLV_ERROR);
     }
     res = libdwarf_compose_add_line(dbg, fileindex,
-				    &compose_error_type);
+                                    &compose_error_type);
     if (res != DW_DLV_OK) {
-	_dwarf_p_error(NULL, error, compose_error_type);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, compose_error_type);
+        return (DW_DLV_ERROR);
     }
     res = libdwarf_compose_add_line(dbg, linenumber,
-				    &compose_error_type);
+                                    &compose_error_type);
     if (res != DW_DLV_OK) {
-	_dwarf_p_error(NULL, error, compose_error_type);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, compose_error_type);
+        return (DW_DLV_ERROR);
     }
     return DW_DLV_OK;
 }
@@ -347,28 +347,28 @@
     int compose_error_type;
 
     if (dbg == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
     length_est = COMMAND_LEN;
     res = libdwarf_compose_begin(dbg, DW_MACINFO_end_file, length_est,
-				 &compose_error_type);
+                                 &compose_error_type);
     if (res != DW_DLV_OK) {
-	_dwarf_p_error(NULL, error, compose_error_type);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, compose_error_type);
+        return (DW_DLV_ERROR);
     }
     res = libdwarf_compose_complete(dbg, &compose_error_type);
     if (res != DW_DLV_OK) {
-	_dwarf_p_error(NULL, error, compose_error_type);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, compose_error_type);
+        return (DW_DLV_ERROR);
     }
     return DW_DLV_OK;
 }
 
 int
 dwarf_vendor_ext(Dwarf_P_Debug dbg,
-		 Dwarf_Unsigned constant,
-		 char *string, Dwarf_Error * error)
+                 Dwarf_Unsigned constant,
+                 char *string, Dwarf_Error * error)
 {
     size_t len;
     size_t length_est;
@@ -376,35 +376,35 @@
     int compose_error_type;
 
     if (dbg == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return (DW_DLV_ERROR);
     }
     if (string == 0) {
-	_dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL);
+        return (DW_DLV_ERROR);
     }
     len = strlen(string) + 1;
     if (len == 0) {
-	_dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY);
+        return (DW_DLV_ERROR);
     }
     length_est = COMMAND_LEN + LINE_LEN + len;
     res = libdwarf_compose_begin(dbg, DW_MACINFO_vendor_ext, length_est,
-				 &compose_error_type);
+                                 &compose_error_type);
     if (res != DW_DLV_OK) {
-	_dwarf_p_error(NULL, error, compose_error_type);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, compose_error_type);
+        return (DW_DLV_ERROR);
     }
     res = libdwarf_compose_add_line(dbg, constant, &compose_error_type);
     if (res != DW_DLV_OK) {
-	_dwarf_p_error(NULL, error, compose_error_type);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, compose_error_type);
+        return (DW_DLV_ERROR);
     }
     libdwarf_compose_add_string(dbg, string, len);
     libdwarf_compose_complete(dbg, &compose_error_type);
     if (res != DW_DLV_OK) {
-	_dwarf_p_error(NULL, error, compose_error_type);
-	return (DW_DLV_ERROR);
+        _dwarf_p_error(NULL, error, compose_error_type);
+        return (DW_DLV_ERROR);
     }
     return DW_DLV_OK;
 }
@@ -413,7 +413,7 @@
 
 int
 _dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg,
-					Dwarf_Error * error)
+                                        Dwarf_Error * error)
 {
     /* Total num of bytes in .debug_macinfo section. */
     Dwarf_Unsigned mac_num_bytes;
@@ -433,36 +433,36 @@
     /* Get the size of the debug_macinfo data */
     mac_num_bytes = 0;
     for (m_sect = dbg->de_first_macinfo; m_sect != NULL;
-	 m_sect = m_sect->mb_next) {
-	mac_num_bytes += m_sect->mb_used_len;
+         m_sect = m_sect->mb_next) {
+        mac_num_bytes += m_sect->mb_used_len;
     }
     /* Tthe final entry has a type code of 0 to indicate It is final
        for this CU Takes just 1 byte. */
     mac_num_bytes += 1;
 
     GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_MACINFO],
-	      macinfo, (unsigned long) mac_num_bytes, error);
+              macinfo, (unsigned long) mac_num_bytes, error);
     if (macinfo == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (0);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (0);
     }
 
     macinfo_ptr = macinfo;
     m_prev = 0;
     for (m_sect = dbg->de_first_macinfo; m_sect != NULL;
-	 m_sect = m_sect->mb_next) {
-	memcpy(macinfo_ptr, m_sect->mb_data, m_sect->mb_used_len);
-	macinfo_ptr += m_sect->mb_used_len;
-	if (m_prev) {
-	    _dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev);
-	    m_prev = 0;
-	}
-	m_prev = m_sect;
+         m_sect = m_sect->mb_next) {
+        memcpy(macinfo_ptr, m_sect->mb_data, m_sect->mb_used_len);
+        macinfo_ptr += m_sect->mb_used_len;
+        if (m_prev) {
+            _dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev);
+            m_prev = 0;
+        }
+        m_prev = m_sect;
     }
-    *macinfo_ptr = 0;		/* the type code of 0 as last entry */
+    *macinfo_ptr = 0;           /* the type code of 0 as last entry */
     if (m_prev) {
-	_dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev);
-	m_prev = 0;
+        _dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev);
+        m_prev = 0;
     }
 
     dbg->de_first_macinfo = NULL;
--- a/usr/src/tools/ctf/dwarf/common/pro_macinfo.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_macinfo.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
--- a/usr/src/tools/ctf/dwarf/common/pro_opaque.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_opaque.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +18,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -123,6 +124,7 @@
 typedef struct Dwarf_P_Simple_name_header_s *Dwarf_P_Simple_name_header;
 typedef struct Dwarf_P_Arange_s *Dwarf_P_Arange;
 typedef struct Dwarf_P_Per_Reloc_Sect_s *Dwarf_P_Per_Reloc_Sect;
+typedef struct Dwarf_P_Per_Sect_String_Attrs_s *Dwarf_P_Per_Sect_String_Attrs;
 
 /* Defined to get at the elf section numbers and section name
    indices in symtab for the dwarf sections
@@ -154,11 +156,16 @@
     Dwarf_Tag di_tag;
     Dwarf_P_Die di_parent;	/* parent of current die */
     Dwarf_P_Die di_child;	/* first child */
+    /* The last child field makes linking up children an O(1) operation,
+       See pro_die.c. */
+    Dwarf_P_Die di_last_child;	
     Dwarf_P_Die di_left;	/* left sibling */
     Dwarf_P_Die di_right;	/* right sibling */
     Dwarf_P_Attribute di_attrs;	/* list of attributes */
     Dwarf_P_Attribute di_last_attr;	/* last attribute */
     int di_n_attr;		/* number of attributes */
+    Dwarf_P_Debug di_dbg;	/* For memory management */
+    Dwarf_Unsigned di_marker;   /* used to attach symbols to dies */
 };
 
 
@@ -230,41 +237,38 @@
        trailer */
     Dwarf_Signed sn_net_len;
 };
-typedef int (*_dwarf_pro_reloc_name_func_ptr) (Dwarf_P_Debug dbg, int sec_index, Dwarf_Unsigned offset,	/* r_offset 
-													 */
-					       Dwarf_Unsigned symidx,
-					       enum Dwarf_Rel_Type type,
-					       int reltarget_length);
+typedef int (*_dwarf_pro_reloc_name_func_ptr) (Dwarf_P_Debug dbg, 
+    int sec_index, 
+    Dwarf_Unsigned offset,/* r_offset */
+    Dwarf_Unsigned symidx,
+    enum Dwarf_Rel_Type type,
+    int reltarget_length);
 
-typedef int (*_dwarf_pro_reloc_length_func_ptr) (Dwarf_P_Debug dbg, int sec_index, Dwarf_Unsigned offset,	/* r_offset 
-														 */
-						 Dwarf_Unsigned
-						 start_symidx,
-						 Dwarf_Unsigned
-						 end_symidx,
-						 enum Dwarf_Rel_Type
-						 type,
-						 int reltarget_length);
+typedef int (*_dwarf_pro_reloc_length_func_ptr) (Dwarf_P_Debug dbg, 
+    int sec_index, Dwarf_Unsigned offset,/* r_offset */
+    Dwarf_Unsigned start_symidx,
+    Dwarf_Unsigned end_symidx,
+    enum Dwarf_Rel_Type type,
+    int reltarget_length);
 typedef int (*_dwarf_pro_transform_relocs_func_ptr) (Dwarf_P_Debug dbg,
 						     Dwarf_Signed *
 						     new_sec_count);
 
 /*
-	Each slot in a block of slots could be:
-	a binary stream relocation entry (32 or 64bit relocation data)
-        a SYMBOLIC relocation entry.
-	During creation sometimes we create multiple chained blocks,
-	but sometimes we create a single long block.
-        Before returning reloc data to caller, 
-        we switch to a single, long-enough,
-	block.
+    Each slot in a block of slots could be:
+    a binary stream relocation entry (32 or 64bit relocation data)
+    a SYMBOLIC relocation entry.
+    During creation sometimes we create multiple chained blocks,
+    but sometimes we create a single long block.
+    Before returning reloc data to caller, 
+    we switch to a single, long-enough,
+    block.
 
-	We make counters here Dwarf_Unsigned so that we
-	get sufficient alignment. Since we use space after
-	the struct (at malloc time) for user data which
-        must have Dwarf_Unsigned alignment, this
-	struct must have that alignment too.
-
+    We make counters here Dwarf_Unsigned so that we
+    get sufficient alignment. Since we use space after
+    the struct (at malloc time) for user data which
+    must have Dwarf_Unsigned alignment, this
+    struct must have that alignment too.
 */
 struct Dwarf_P_Relocation_Block_s {
     Dwarf_Unsigned rb_slots_in_block;	/* slots in block, as created */
@@ -282,22 +286,15 @@
    no relocations).
 */
 struct Dwarf_P_Per_Reloc_Sect_s {
-
-
     unsigned long pr_reloc_total_count;	/* total number of entries
-					   across all blocks */
+        across all blocks */
 
     unsigned long pr_slots_per_block_to_alloc;	/* at Block alloc, this 
-						   is the default
-						   number of slots to
-						   use */
+        is the default number of slots to use */
 
     int pr_sect_num_of_reloc_sect;	/* sect number returned by
-					   de_func() or de_func_b()
-					   call, this is the sect
-					   number of the relocation
-					   section. */
-
+        de_callback_func() or de_callback_func_b() call, this is the sect
+        number of the relocation section. */
 
     /* singly-linked list. add at and ('last') with count of blocks */
     struct Dwarf_P_Relocation_Block_s *pr_first_block;
@@ -307,6 +304,17 @@
 
 #define DEFAULT_SLOTS_PER_BLOCK 3
 
+typedef struct memory_list_s {
+  struct memory_list_s *prev;
+  struct memory_list_s *next;
+} memory_list_t;
+
+struct Dwarf_P_Per_Sect_String_Attrs_s {
+    int sect_sa_section_number;
+    unsigned sect_sa_n_alloc;
+    unsigned sect_sa_n_used;
+    Dwarf_P_String_Attr sect_sa_list;
+};
 
 /* Fields used by producer */
 struct Dwarf_P_Debug_s {
@@ -314,15 +322,13 @@
        version of libdwarf See PRO_VERSION_MAGIC */
     int de_version_magic_number;
 
-    Dwarf_Unsigned de_access;
     Dwarf_Handler de_errhand;
     Dwarf_Ptr de_errarg;
 
-    /* 
-       Call back function, used to create .debug* sections. Provided
+    /* Call back function, used to create .debug* sections. Provided
        by user. Only of these used per dbg. */
-    Dwarf_Callback_Func de_func;
-    Dwarf_Callback_Func_b de_func_b;
+    Dwarf_Callback_Func de_callback_func;
+    Dwarf_Callback_Func_b de_callback_func_b;
 
     /* Flags from producer_init call */
     Dwarf_Unsigned de_flags;
@@ -356,7 +362,6 @@
     Dwarf_P_Cie de_last_cie;
     Dwarf_Unsigned de_n_cie;
 
-
     /* Singly-linked list of fde's for the debug unit */
     Dwarf_P_Fde de_frame_fdes;
     Dwarf_P_Fde de_last_fde;
@@ -380,7 +385,6 @@
     /* current points to the current, unfilled, block */
     struct dw_macinfo_block_s *de_current_macinfo;
 
-
     /* Pointer to the first section, to support reset_section_bytes */
     Dwarf_P_Section_Data de_first_debug_sect;
 
@@ -396,30 +400,12 @@
 					   (SYMBOLIC output) */
 
     /* used in remembering sections */
-    int de_elf_sects[NUM_DEBUG_SECTIONS];	/* 
-						   elf sect number of
-						   the section itself,
-						   DEBUG_LINE for
-						   example */
+    int de_elf_sects[NUM_DEBUG_SECTIONS];  /* elf sect number of
+        the section itself, DEBUG_LINE for example */
 
-    Dwarf_Unsigned de_sect_name_idx[NUM_DEBUG_SECTIONS];	/* section 
-								   name 
-								   index 
-								   or
-								   handle 
-								   for
-								   the
-								   name 
-								   of
-								   the
-								   symbol 
-								   for
-								   DEBUG_LINE 
-								   for
-								   example 
-								 */
-
-
+    Dwarf_Unsigned de_sect_name_idx[NUM_DEBUG_SECTIONS]; /* section 
+        name index or handle for the name of the symbol for
+        DEBUG_LINE for example */
 
     int de_offset_reloc;	/* offset reloc type, R_MIPS_32 for
 				   example. Specific to the ABI being
@@ -432,10 +418,10 @@
 				   produced. relocates pointer size
 				   field */
 
-    unsigned char de_offset_size;	/* section offset. Here to
-					   avoid test of abi in macro
-					   at run time MIPS -n32 4,
-					   -64 8.  */
+    unsigned char de_offset_size;  /* section offset. Here to
+                                      avoid test of abi in macro
+                                      at run time MIPS -n32 4,
+                                      -64 8.  */
 
     unsigned char de_pointer_size;	/* size of pointer in target.
 					   Here to avoid test of abi in 
@@ -477,9 +463,14 @@
        of sensible behavior on dbg passing between DSOs linked with
        mismatched libdwarf producer versions. */
 
+    Dwarf_P_Marker de_markers;  /* pointer to array of markers */
+    unsigned de_marker_n_alloc;
+    unsigned de_marker_n_used;
+    int de_sect_sa_next_to_return;  /* Iterator on sring attrib sects */
+    /* String attributes data of each section. */
+    struct Dwarf_P_Per_Sect_String_Attrs_s de_sect_string_attr[NUM_DEBUG_SECTIONS];
 };
 
-
 #define CURRENT_VERSION_STAMP		2
 
 Dwarf_Unsigned _dwarf_add_simple_name_entry(Dwarf_P_Debug dbg,
--- a/usr/src/tools/ctf/dwarf/common/pro_pubnames.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_pubnames.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +19,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -54,10 +54,10 @@
 
 Dwarf_Unsigned
 dwarf_add_pubname(Dwarf_P_Debug dbg,
-		  Dwarf_P_Die die,
-		  char *pubname_name, Dwarf_Error * error)
+                  Dwarf_P_Die die,
+                  char *pubname_name, Dwarf_Error * error)
 {
     return
-	_dwarf_add_simple_name_entry(dbg, die, pubname_name,
-				     dwarf_snk_pubname, error);
+        _dwarf_add_simple_name_entry(dbg, die, pubname_name,
+                                     dwarf_snk_pubname, error);
 }
--- a/usr/src/tools/ctf/dwarf/common/pro_reloc.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_reloc.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2008-2010 David Anderson, Inc. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +20,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -57,39 +58,39 @@
 */
 int
 _dwarf_pro_pre_alloc_n_reloc_slots(Dwarf_P_Debug dbg,
-				   int rel_sec_index,
-				   Dwarf_Unsigned newslots)
+    int rel_sec_index,
+    Dwarf_Unsigned newslots)
 {
-    unsigned long len;
-    struct Dwarf_P_Relocation_Block_s *data;
+    unsigned long len = 0;
+    struct Dwarf_P_Relocation_Block_s *data = 0;
     Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[rel_sec_index];
     unsigned long slots_in_blk = (unsigned long) newslots;
     unsigned long rel_rec_size = dbg->de_relocation_record_size;
 
     if (prel->pr_first_block)
-	return DW_DLV_OK;	/* do nothing */
+        return DW_DLV_OK;       /* do nothing */
 
     len = sizeof(struct Dwarf_P_Relocation_Block_s) +
-	slots_in_blk * rel_rec_size;
+        slots_in_blk * rel_rec_size;
 
 
     data = (struct Dwarf_P_Relocation_Block_s *)
-	_dwarf_p_get_alloc(dbg, len);
+        _dwarf_p_get_alloc(dbg, len);
     if (!data) {
-	return DW_DLV_ERROR;
+        return DW_DLV_ERROR;
     }
-    data->rb_slots_in_block = slots_in_blk;	/* could use default
-						   here, as fallback in 
-						   case our origininal
-						   estimate wrong.
-						   When we call this we 
-						   presumably know what 
-						   we are doing, so
-						   keep this count for
-						   now */
+    data->rb_slots_in_block = slots_in_blk;     /* could use default
+                                                   here, as fallback in 
+                                                   case our origininal
+                                                   estimate wrong. When 
+                                                   we call this we
+                                                   presumably know what 
+                                                   we are doing, so
+                                                   keep this count for
+                                                   now */
     data->rb_next_slot_to_use = 0;
     data->rb_where_to_add_next =
-	((char *) data) + sizeof(struct Dwarf_P_Relocation_Block_s);
+        ((char *) data) + sizeof(struct Dwarf_P_Relocation_Block_s);
     data->rb_data = data->rb_where_to_add_next;
 
     prel->pr_first_block = data;
@@ -111,37 +112,37 @@
 int
 _dwarf_pro_alloc_reloc_slots(Dwarf_P_Debug dbg, int rel_sec_index)
 {
-    unsigned long len;
-    struct Dwarf_P_Relocation_Block_s *data;
+    unsigned long len = 0;
+    struct Dwarf_P_Relocation_Block_s *data = 0;
     Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[rel_sec_index];
     unsigned long slots_in_blk = prel->pr_slots_per_block_to_alloc;
     unsigned long rel_rec_size = dbg->de_relocation_record_size;
 
     len = sizeof(struct Dwarf_P_Relocation_Block_s) +
-	slots_in_blk * rel_rec_size;
+        slots_in_blk * rel_rec_size;
 
     data = (struct Dwarf_P_Relocation_Block_s *)
-	_dwarf_p_get_alloc(dbg, len);
+        _dwarf_p_get_alloc(dbg, len);
     if (!data) {
-	return DW_DLV_ERROR;
+        return DW_DLV_ERROR;
     }
 
     if (prel->pr_first_block) {
-	prel->pr_last_block->rb_next = data;
-	prel->pr_last_block = data;
-	prel->pr_block_count += 1;
+        prel->pr_last_block->rb_next = data;
+        prel->pr_last_block = data;
+        prel->pr_block_count += 1;
 
     } else {
 
-	prel->pr_first_block = data;
-	prel->pr_last_block = data;
-	prel->pr_block_count = 1;
+        prel->pr_first_block = data;
+        prel->pr_last_block = data;
+        prel->pr_block_count = 1;
     }
 
     data->rb_slots_in_block = slots_in_blk;
     data->rb_next_slot_to_use = 0;
     data->rb_where_to_add_next =
-	((char *) data) + sizeof(struct Dwarf_P_Relocation_Block_s);
+        ((char *) data) + sizeof(struct Dwarf_P_Relocation_Block_s);
     data->rb_data = data->rb_where_to_add_next;
 
     return DW_DLV_OK;
@@ -149,32 +150,32 @@
 }
 
 /*
-	Reserve a slot. return DW_DLV_OK if succeeds.
+        Reserve a slot. return DW_DLV_OK if succeeds.
 
-	Return DW_DLV_ERROR if fails (malloc error).
+        Return DW_DLV_ERROR if fails (malloc error).
 
-	Use the relrec_to_fill to pass back a pointer to
-	a slot space to use.
+        Use the relrec_to_fill to pass back a pointer to
+        a slot space to use.
 */
 int
 _dwarf_pro_reloc_get_a_slot(Dwarf_P_Debug dbg,
-			    int base_sec_index, void **relrec_to_fill)
+    int base_sec_index, void **relrec_to_fill)
 {
-    struct Dwarf_P_Relocation_Block_s *data;
+    struct Dwarf_P_Relocation_Block_s *data = 0;
     Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[base_sec_index];
     unsigned long rel_rec_size = dbg->de_relocation_record_size;
 
-    char *ret_addr;
+    char *ret_addr = 0;
 
     data = prel->pr_last_block;
     if ((data == 0) ||
-	(data->rb_next_slot_to_use >= data->rb_slots_in_block)) {
-	int res;
+        (data->rb_next_slot_to_use >= data->rb_slots_in_block)) {
+        int res;
 
-	res = _dwarf_pro_alloc_reloc_slots(dbg, base_sec_index);
-	if (res != DW_DLV_OK) {
-	    return res;
-	}
+        res = _dwarf_pro_alloc_reloc_slots(dbg, base_sec_index);
+        if (res != DW_DLV_OK) {
+            return res;
+        }
     }
 
     data = prel->pr_last_block;
@@ -211,58 +212,58 @@
 
  /*ARGSUSED*/ int
 dwarf_get_relocation_info_count(Dwarf_P_Debug dbg,
-				Dwarf_Unsigned *
-				count_of_relocation_sections,
-				int *drd_buffer_version,
-				Dwarf_Error * error)
+    Dwarf_Unsigned *
+    count_of_relocation_sections,
+    int *drd_buffer_version,
+    Dwarf_Error * error)
 {
     if (dbg->de_flags & DW_DLC_SYMBOLIC_RELOCATIONS) {
-	int i;
-	unsigned int count = 0;
+        int i;
+        unsigned int count = 0;
 
-	for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) {
-	    if (dbg->de_reloc_sect[i].pr_reloc_total_count > 0) {
-		++count;
-	    }
-	}
-	*count_of_relocation_sections = (Dwarf_Unsigned) count;
-	*drd_buffer_version = DWARF_DRD_BUFFER_VERSION;
-	return DW_DLV_OK;
+        for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) {
+            if (dbg->de_reloc_sect[i].pr_reloc_total_count > 0) {
+                ++count;
+            }
+        }
+        *count_of_relocation_sections = (Dwarf_Unsigned) count;
+        *drd_buffer_version = DWARF_DRD_BUFFER_VERSION;
+        return DW_DLV_OK;
     }
     return DW_DLV_NO_ENTRY;
 }
 
 int
 dwarf_get_relocation_info(Dwarf_P_Debug dbg,
-			  Dwarf_Signed * elf_section_index,
-			  Dwarf_Signed * elf_section_index_link,
-			  Dwarf_Unsigned * relocation_buffer_count,
-			  Dwarf_Relocation_Data * reldata_buffer,
-			  Dwarf_Error * error)
+    Dwarf_Signed * elf_section_index,
+    Dwarf_Signed * elf_section_index_link,
+    Dwarf_Unsigned * relocation_buffer_count,
+    Dwarf_Relocation_Data * reldata_buffer,
+    Dwarf_Error * error)
 {
     int next = dbg->de_reloc_next_to_return;
 
     if (dbg->de_flags & DW_DLC_SYMBOLIC_RELOCATIONS) {
-	int i;
+        int i;
 
-	for (i = next; i < NUM_DEBUG_SECTIONS; ++i) {
-	    Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[i];
+        for (i = next; i < NUM_DEBUG_SECTIONS; ++i) {
+            Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[i];
 
-	    if (prel->pr_reloc_total_count > 0) {
-		dbg->de_reloc_next_to_return = i + 1;
+            if (prel->pr_reloc_total_count > 0) {
+                dbg->de_reloc_next_to_return = i + 1;
 
 
-		/* ASSERT: prel->.pr_block_count == 1 */
+                /* ASSERT: prel->.pr_block_count == 1 */
 
-		*elf_section_index = prel->pr_sect_num_of_reloc_sect;
-		*elf_section_index_link = dbg->de_elf_sects[i];
-		*relocation_buffer_count = prel->pr_reloc_total_count;
-		*reldata_buffer = (Dwarf_Relocation_Data)
-		    (prel->pr_first_block->rb_data);
-		return DW_DLV_OK;
-	    }
-	}
-	DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR);
+                *elf_section_index = prel->pr_sect_num_of_reloc_sect;
+                *elf_section_index_link = dbg->de_elf_sects[i];
+                *relocation_buffer_count = prel->pr_reloc_total_count;
+                *reldata_buffer = (Dwarf_Relocation_Data)
+                    (prel->pr_first_block->rb_data);
+                return DW_DLV_OK;
+            }
+        }
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR);
     }
     return DW_DLV_NO_ENTRY;
 }
--- a/usr/src/tools/ctf/dwarf/common/pro_reloc.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_reloc.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
--- a/usr/src/tools/ctf/dwarf/common/pro_reloc_stream.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_reloc_stream.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,8 @@
 /*
 
-  Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2001,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
+  Portions Copyright 2008-2010 David Anderson, Inc. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +21,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -52,50 +54,49 @@
 #include "pro_reloc_stream.h"
 
 /*
-	Return DW_DLV_ERROR on malloc error or reltarget_length error.
-	Return DW_DLV_OK otherwise
+        Return DW_DLV_ERROR on malloc error or reltarget_length error.
+        Return DW_DLV_OK otherwise
 
 
 
 */
  /*ARGSUSED*/ int
-_dwarf_pro_reloc_name_stream64(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,	/* r_offset 
-												   of 
-												   reloc 
-												 */
-			       Dwarf_Unsigned symidx,
-			       enum Dwarf_Rel_Type type,
-			       int reltarget_length)
+_dwarf_pro_reloc_name_stream64(Dwarf_P_Debug dbg,
+    int base_sec_index,
+    Dwarf_Unsigned offset,      /* r_offset of reloc */
+    Dwarf_Unsigned symidx,
+    enum Dwarf_Rel_Type type,
+    int reltarget_length)
 {
 #if HAVE_ELF64_GETEHDR
-    Elf64_Rel *elf64_reloc;
-    void *relrec_to_fill;
-    int res;
-    int rel_type;
+    REL64 *elf64_reloc = 0;
+    void *relrec_to_fill = 0;
+    int res = 0;
+    int rel_type = 0;
 
     res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index,
-				      &relrec_to_fill);
+                                      &relrec_to_fill);
     if (res != DW_DLV_OK)
-	return res;
+        return res;
 
 
     if (type == dwarf_drt_data_reloc) {
-	if (reltarget_length == dbg->de_offset_size) {
-	    rel_type = dbg->de_offset_reloc;
-	} else if (reltarget_length == dbg->de_pointer_size) {
-	    rel_type = dbg->de_ptr_reloc;
-	} else {
-	    return DW_DLV_ERROR;
-	}
+        if (reltarget_length == dbg->de_offset_size) {
+            rel_type = dbg->de_offset_reloc;
+        } else if (reltarget_length == dbg->de_pointer_size) {
+            rel_type = dbg->de_ptr_reloc;
+        } else {
+            return DW_DLV_ERROR;
+        }
     } else if (type == dwarf_drt_segment_rel) {
-	rel_type = dbg->de_exc_reloc;
+        rel_type = dbg->de_exc_reloc;
     } else {
-	/* We are in trouble: improper use of stream relocations.
-	   Someone else will diagnose */
-	rel_type = 0;
+        /* We are in trouble: improper use of stream relocations.
+           Someone else will diagnose */
+        rel_type = 0;
     }
 
-    elf64_reloc = (Elf64_Rel *) relrec_to_fill;
+    elf64_reloc = (REL64 *)relrec_to_fill;
     elf64_reloc->r_offset = offset;
     Set_REL64_info(*elf64_reloc, symidx, rel_type);
     return DW_DLV_OK;
@@ -105,45 +106,43 @@
 }
 
 /*
-	Return DW_DLV_ERROR on malloc error or reltarget_length error.
-	Return DW_DLV_OK otherwise
-	a binary reloc: 32bit ABI
+        Return DW_DLV_ERROR on malloc error or reltarget_length error.
+        Return DW_DLV_OK otherwise
+        a binary reloc: 32bit ABI
 */
 int
-_dwarf_pro_reloc_name_stream32(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,	/* r_offset 
-												   of 
-												   reloc 
-												 */
-			       Dwarf_Unsigned symidx,
-			       enum Dwarf_Rel_Type type,
-			       int reltarget_length)
+_dwarf_pro_reloc_name_stream32(Dwarf_P_Debug dbg, int base_sec_index, 
+    Dwarf_Unsigned offset,      /* r_offset of reloc */
+    Dwarf_Unsigned symidx,
+    enum Dwarf_Rel_Type type,
+    int reltarget_length)
 {
-    Elf32_Rel *elf32_reloc;
-    void *relrec_to_fill;
-    int res;
-    int rel_type;
+    REL32 *elf32_reloc = 0;
+    void *relrec_to_fill = 0;
+    int res = 0;
+    int rel_type = 0;
 
     res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index,
-				      &relrec_to_fill);
+                                      &relrec_to_fill);
     if (res != DW_DLV_OK)
-	return res;
+        return res;
     if (type == dwarf_drt_data_reloc) {
-	if (reltarget_length == dbg->de_offset_size) {
-	    rel_type = dbg->de_offset_reloc;
-	} else if (reltarget_length == dbg->de_pointer_size) {
-	    rel_type = dbg->de_ptr_reloc;
-	} else {
-	    return DW_DLV_ERROR;
-	}
+        if (reltarget_length == dbg->de_offset_size) {
+            rel_type = dbg->de_offset_reloc;
+        } else if (reltarget_length == dbg->de_pointer_size) {
+            rel_type = dbg->de_ptr_reloc;
+        } else {
+            return DW_DLV_ERROR;
+        }
     } else if (type == dwarf_drt_segment_rel) {
-	rel_type = dbg->de_exc_reloc;
+        rel_type = dbg->de_exc_reloc;
     } else {
-	/* We are in trouble: improper use of stream relocations.
-	   Someone else will diagnose */
-	rel_type = 0;
+        /* We are in trouble: improper use of stream relocations.
+           Someone else will diagnose */
+        rel_type = 0;
     }
 
-    elf32_reloc = (Elf32_Rel *) relrec_to_fill;
+    elf32_reloc = (REL32*)relrec_to_fill;
     elf32_reloc->r_offset = (Elf32_Addr) offset;
     Set_REL32_info(*elf32_reloc, (Dwarf_Word) symidx, rel_type);
     return DW_DLV_OK;
@@ -154,20 +153,19 @@
 
 
 /*
-	Return DW_DLV_OK.
-	Never can really do anything: lengths cannot
-	be represented as end-start in a stream.
+        Return DW_DLV_OK.
+        Never can really do anything: lengths cannot
+        be represented as end-start in a stream.
 
 */
  /*ARGSUSED*/ int
-_dwarf_pro_reloc_length_stream(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,	/* r_offset 
-												   of 
-												   reloc 
-												 */
-			       Dwarf_Unsigned start_symidx,
-			       Dwarf_Unsigned end_symidx,
-			       enum Dwarf_Rel_Type type,
-			       int reltarget_length)
+_dwarf_pro_reloc_length_stream(Dwarf_P_Debug dbg, 
+    int base_sec_index, 
+    Dwarf_Unsigned offset,    /* r_offset of reloc */
+    Dwarf_Unsigned start_symidx,
+    Dwarf_Unsigned end_symidx,
+    enum Dwarf_Rel_Type type,
+    int reltarget_length)
 {
     /* get a slot, fill in the slot entry */
     return DW_DLV_OK;
@@ -178,25 +176,25 @@
         Ensure each stream is a single buffer and
         add that single buffer to the set of stream buffers.
 
-	By creating a new buffer and copying if necessary.
+        By creating a new buffer and copying if necessary.
 
         Free the input set of buffers if we consolidate.
         Return -1 on error (malloc failure)
 
 
         Return DW_DLV_OK on success. Any other return indicates 
-	malloc failed.
-	
+        malloc failed.
+        
 */
 int
 _dwarf_stream_relocs_to_disk(Dwarf_P_Debug dbg,
-			     Dwarf_Signed * new_sec_count)
+    Dwarf_Signed * new_sec_count)
 {
     unsigned long total_size = 0;
-    Dwarf_Small *data;
-    int sec_index;
-    unsigned long i;
-    Dwarf_Error err;
+    Dwarf_Small *data = 0;
+    int sec_index = 0;
+    unsigned long i = 0;
+    Dwarf_Error err = 0;
     Dwarf_Error *error = &err;
 
     Dwarf_Signed sec_count = 0;
@@ -204,93 +202,94 @@
     Dwarf_P_Per_Reloc_Sect p_reloc = &dbg->de_reloc_sect[0];
 
     for (i = 0; i < NUM_DEBUG_SECTIONS; ++i, ++p_reloc) {
-	unsigned long ct = p_reloc->pr_reloc_total_count;
-	unsigned len;
-	struct Dwarf_P_Relocation_Block_s *p_blk;
-	struct Dwarf_P_Relocation_Block_s *p_blk_last;
-	Dwarf_P_Per_Reloc_Sect prb;
+        unsigned long ct = p_reloc->pr_reloc_total_count;
+        unsigned len = 0;
+        struct Dwarf_P_Relocation_Block_s *p_blk = 0;
+        struct Dwarf_P_Relocation_Block_s *p_blk_last = 0;
+        Dwarf_P_Per_Reloc_Sect prb = 0;
 
-	if (ct == 0) {
-	    continue;
-	}
-	prb = &dbg->de_reloc_sect[i];
-	len = dbg->de_relocation_record_size;
-	++sec_count;
+        if (ct == 0) {
+            continue;
+        }
+        prb = &dbg->de_reloc_sect[i];
+        len = dbg->de_relocation_record_size;
+        ++sec_count;
 
-	total_size = ct * len;
-	sec_index = prb->pr_sect_num_of_reloc_sect;
-	if (sec_index == 0) {
-	    /* call de_func or de_func_b, getting section number of
-	       reloc sec */
-	    int rel_section_index;
-	    Dwarf_Unsigned name_idx;
-	    int int_name;
-	    int err;
+        total_size = ct * len;
+        sec_index = prb->pr_sect_num_of_reloc_sect;
+        if (sec_index == 0) {
+            /* Call de_callback_func or de_callback_func_b, getting 
+               section number of reloc section. */
+            int rel_section_index = 0;
+            Dwarf_Unsigned name_idx = 0;
+            int int_name = 0;
+            int err = 0;
 
-	    if (dbg->de_func_b) {
-		rel_section_index =
-		    dbg->de_func_b(_dwarf_rel_section_names[i],
-				   /* size */
-				   dbg->de_relocation_record_size,
-				   /* type */ SHT_REL,
-				   /* flags */ 0,
-				   /* link to symtab, which we cannot
-				      know */ 0,
-				   /* info == link to sec rels apply to */
-				   dbg->de_elf_sects[i],
-				   &name_idx, &err);
-	    } else {
-		rel_section_index =
-		    dbg->de_func(_dwarf_rel_section_names[i],
-				 /* size */
-				 dbg->de_relocation_record_size,
-				 /* type */ SHT_REL,
-				 /* flags */ 0,
-				 /* link to symtab, which we cannot
-				    know */ 0,
-				 /* info == link to sec rels apply to */
-				 dbg->de_elf_sects[i], &int_name, &err);
-		name_idx = int_name;
-	    }
-	    if (rel_section_index == -1) {
-		{
-		    _dwarf_p_error(dbg, error, DW_DLE_ELF_SECT_ERR);
-		    return (DW_DLV_ERROR);
-		}
+            if (dbg->de_callback_func_b) {
+                rel_section_index =
+                    dbg->de_callback_func_b(_dwarf_rel_section_names[i],
+                                   /* size */
+                                   dbg->de_relocation_record_size,
+                                   /* type */ SHT_REL,
+                                   /* flags */ 0,
+                                   /* link to symtab, which we cannot
+                                      know */ 0,
+                                   /* info == link to sec rels apply to 
+                                    */
+                                   dbg->de_elf_sects[i],
+                                   &name_idx, &err);
+            } else {
+                rel_section_index =
+                    dbg->de_callback_func(_dwarf_rel_section_names[i],
+                                 /* size */
+                                 dbg->de_relocation_record_size,
+                                 /* type */ SHT_REL,
+                                 /* flags */ 0,
+                                 /* link to symtab, which we cannot
+                                    know */ 0,
+                                 /* info == link to sec rels apply to */
+                                 dbg->de_elf_sects[i], &int_name, &err);
+                name_idx = int_name;
+            }
+            if (rel_section_index == -1) {
+                {
+                    _dwarf_p_error(dbg, error, DW_DLE_ELF_SECT_ERR);
+                    return (DW_DLV_ERROR);
+                }
 
-	    }
-	    prb->pr_sect_num_of_reloc_sect = rel_section_index;
-	    sec_index = rel_section_index;
-	}
-	GET_CHUNK(dbg, sec_index, data, total_size, &err);
-	p_blk = p_reloc->pr_first_block;
+            }
+            prb->pr_sect_num_of_reloc_sect = rel_section_index;
+            sec_index = rel_section_index;
+        }
+        GET_CHUNK(dbg, sec_index, data, total_size, &err);
+        p_blk = p_reloc->pr_first_block;
 
-	/* following loop executes at least once. Effects the
-	   consolidation to a single block or, if already a single
-	   block, simply copies to the output buffer. And frees the
-	   input block. The new block is in the de_debug_sects list. */
-	while (p_blk) {
+        /* following loop executes at least once. Effects the
+           consolidation to a single block or, if already a single
+           block, simply copies to the output buffer. And frees the
+           input block. The new block is in the de_debug_sects list. */
+        while (p_blk) {
 
-	    unsigned long len =
-		p_blk->rb_where_to_add_next - p_blk->rb_data;
+            unsigned long len =
+                p_blk->rb_where_to_add_next - p_blk->rb_data;
 
-	    memcpy(data, p_blk->rb_data, len);
+            memcpy(data, p_blk->rb_data, len);
 
 
-	    data += len;
+            data += len;
 
-	    p_blk_last = p_blk;
-	    p_blk = p_blk->rb_next;
+            p_blk_last = p_blk;
+            p_blk = p_blk->rb_next;
 
-	    _dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last);
-	}
-	/* ASSERT: sum of len copied == total_size */
+            _dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last);
+        }
+        /* ASSERT: sum of len copied == total_size */
 
-	/* 
-	   We have copied the input, now drop the pointers to it. For
-	   debugging, leave the other data untouched. */
-	p_reloc->pr_first_block = 0;
-	p_reloc->pr_last_block = 0;
+        /* 
+           We have copied the input, now drop the pointers to it. For
+           debugging, leave the other data untouched. */
+        p_reloc->pr_first_block = 0;
+        p_reloc->pr_last_block = 0;
     }
 
     *new_sec_count = sec_count;
--- a/usr/src/tools/ctf/dwarf/common/pro_reloc_stream.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_reloc_stream.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
--- a/usr/src/tools/ctf/dwarf/common/pro_reloc_symbolic.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_reloc_symbolic.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +19,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -46,71 +46,65 @@
 #include "pro_reloc_symbolic.h"
 
 /*
-	Return DW_DLV_ERROR on malloc error.
-	Return DW_DLV_OK otherwise
+        Return DW_DLV_ERROR on malloc error.
+        Return DW_DLV_OK otherwise
 */
 
 int
-_dwarf_pro_reloc_name_symbolic(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,	/* r_offset 
-												   of 
-												   reloc 
-												 */
-			       Dwarf_Unsigned symidx,
-			       enum Dwarf_Rel_Type type,
-			       int reltarget_length)
+_dwarf_pro_reloc_name_symbolic(Dwarf_P_Debug dbg, 
+    int base_sec_index, 
+    Dwarf_Unsigned offset, /* r_offset of reloc */
+    Dwarf_Unsigned symidx,
+    enum Dwarf_Rel_Type type,
+    int reltarget_length)
 {
     /* get a slot, fill in the slot entry */
-    void *relrec_to_fill;
-    int res;
+    void *relrec_to_fill = 0;
+    int res = 0;
     struct Dwarf_Relocation_Data_s *slotp;
 
     res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index,
-				      &relrec_to_fill);
+                                      &relrec_to_fill);
     if (res != DW_DLV_OK)
-	return res;
-
+        return res;
     slotp = (struct Dwarf_Relocation_Data_s *) relrec_to_fill;
     slotp->drd_type = type;
     slotp->drd_length = reltarget_length;
     slotp->drd_offset = offset;
     slotp->drd_symbol_index = symidx;
     return DW_DLV_OK;
-
 }
 
 
 
 /*
-	Return DW_DLV_ERROR on malloc error.
-	Return DW_DLV_OK otherwise
+        Return DW_DLV_ERROR on malloc error.
+        Return DW_DLV_OK otherwise
 */
 int
-_dwarf_pro_reloc_length_symbolic(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,	/* r_offset 
-												   of 
-												   reloc 
-												 */
-				 Dwarf_Unsigned start_symidx,
-				 Dwarf_Unsigned end_symidx,
-				 enum Dwarf_Rel_Type type,
-				 int reltarget_length)
+_dwarf_pro_reloc_length_symbolic(Dwarf_P_Debug dbg, 
+    int base_sec_index, 
+    Dwarf_Unsigned offset,  /* r_offset of reloc */
+    Dwarf_Unsigned start_symidx,
+    Dwarf_Unsigned end_symidx,
+    enum Dwarf_Rel_Type type,
+    int reltarget_length)
 {
     /* get a slot, fill in the slot entry */
-    void *relrec_to_fill;
-    int res;
-    struct Dwarf_Relocation_Data_s *slotp1;
-    struct Dwarf_Relocation_Data_s *slotp2;
-
-
+    void *relrec_to_fill = 0;
+    int res = 0;
+    struct Dwarf_Relocation_Data_s *slotp1 = 0;
+    struct Dwarf_Relocation_Data_s *slotp2 = 0;
 
     res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index,
-				      &relrec_to_fill);
+                                      &relrec_to_fill);
     if (res != DW_DLV_OK)
-	return res;
+        return res;
     slotp1 = (struct Dwarf_Relocation_Data_s *) relrec_to_fill;
     res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index,
-				      &relrec_to_fill);
+                                      &relrec_to_fill);
     if (res != DW_DLV_OK)
-	return res;
+        return res;
     slotp2 = (struct Dwarf_Relocation_Data_s *) relrec_to_fill;
 
     /* ASSERT: type == dwarf_drt_first_of_length_type_pair */
@@ -123,7 +117,6 @@
     slotp2->drd_length = reltarget_length;
     slotp2->drd_offset = offset;
     slotp2->drd_symbol_index = end_symidx;
-
     return DW_DLV_OK;
 }
 
@@ -135,12 +128,11 @@
 */
 static void
 _dwarf_reset_reloc_sect_info(struct Dwarf_P_Per_Reloc_Sect_s *pblk,
-			     unsigned long ct)
+    unsigned long ct)
 {
 
 
-    /* do not zero pr_sect_num_of_reloc_sect */
-
+    /* Do not zero pr_sect_num_of_reloc_sect */
     pblk->pr_reloc_total_count = 0;
     pblk->pr_first_block = 0;
     pblk->pr_last_block = 0;
@@ -149,151 +141,136 @@
 }
 
 /*
-        Ensure each stream is a single buffer and
-        add that single buffer to the set of stream buffers.
+    Ensure each stream is a single buffer and
+    add that single buffer to the set of stream buffers.
 
-	By creating a new buffer and copying if necessary.
-	(If > 1 block, reduce to 1 block)
+    By creating a new buffer and copying if necessary.
+    (If > 1 block, reduce to 1 block)
 
-        Free the input set of buffers if we consolidate.
+    Free the input set of buffers if we consolidate.
 
-	We pass back *new_sec_count as zero because we
-        are not creating normal sections for a .o, but
-	symbolic relocations, separately counted.
+    We pass back *new_sec_count as zero because we
+    are not creating normal sections for a .o, but
+    symbolic relocations, separately counted.
 
-        Return -1 on error (malloc failure)
-
+    Return -1 on error (malloc failure)
 
-        Return DW_DLV_OK on success. Any other return indicates 
-	malloc failed.
+    Return DW_DLV_OK on success. Any other return indicates 
+    malloc failed.
 */
 int
 _dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg,
-			       Dwarf_Signed * new_sec_count)
+    Dwarf_Signed * new_sec_count)
 {
     /* unsigned long total_size =0; */
-    Dwarf_Small *data;
-    int sec_index;
-    int res;
-    unsigned long i;
-    Dwarf_Error error;
-
+    Dwarf_Small *data = 0;
+    int sec_index = 0;
+    int res = 0;
+    unsigned long i = 0;
+    Dwarf_Error error = 0;
     Dwarf_Signed sec_count = 0;
-
     Dwarf_P_Per_Reloc_Sect p_reloc = &dbg->de_reloc_sect[0];
 
     for (i = 0; i < NUM_DEBUG_SECTIONS; ++i, ++p_reloc) {
-
-	unsigned long ct = p_reloc->pr_reloc_total_count;
-	struct Dwarf_P_Relocation_Block_s *p_blk;
-	struct Dwarf_P_Relocation_Block_s *p_blk_last;
-
-	/* int len */
-	int err;
+        unsigned long ct = p_reloc->pr_reloc_total_count;
+        struct Dwarf_P_Relocation_Block_s *p_blk;
+        struct Dwarf_P_Relocation_Block_s *p_blk_last;
+        int err;
+        if (ct == 0) {
+            continue;
+        }
 
-
-	if (ct == 0) {
-	    continue;
-	}
-
-	/* len = dbg->de_relocation_record_size; */
-	++sec_count;
+        /* len = dbg->de_relocation_record_size; */
+        ++sec_count;
 
-	/* total_size = ct *len; */
-	sec_index = p_reloc->pr_sect_num_of_reloc_sect;
-	if (sec_index == 0) {
-	    /* call de_func or de_func_b, getting section number of
-	       reloc sec */
-	    int rel_section_index;
-	    int int_name;
-	    Dwarf_Unsigned name_idx;
+        /* total_size = ct *len; */
+        sec_index = p_reloc->pr_sect_num_of_reloc_sect;
+        if (sec_index == 0) {
+            /* Call de_callback_func or de_callback_func_b, 
+               getting section number of reloc section. */
+            int rel_section_index = 0;
+            int int_name = 0;
+            Dwarf_Unsigned name_idx = 0;
 
-	    /* 
-	       This is a bit of a fake, as we do not really have true
-	       elf sections at all. Just the data such might contain.
-	       But this lets the caller eventually link things
-	       together: without this call we would not know what rel
-	       data goes with what section when we are asked for the
-	       real arrays. */
+            /* 
+               This is a bit of a fake, as we do not really have true
+               elf sections at all. Just the data such might contain.
+               But this lets the caller eventually link things
+               together: without this call we would not know what rel
+               data goes with what section when we are asked for the
+               real arrays. */
 
-	    if (dbg->de_func_b) {
-		rel_section_index =
-		    dbg->de_func_b(_dwarf_rel_section_names[i],
-				   dbg->de_relocation_record_size,
-				   /* type */ SHT_REL,
-				   /* flags */ 0,
-				   /* link to symtab, which we cannot
-				      know */ SHN_UNDEF,
-				   /* sec rels apply to */
-				   dbg->de_elf_sects[i],
-				   &name_idx, &err);
-	    } else {
-		rel_section_index =
-		    dbg->de_func(_dwarf_rel_section_names[i],
-				 dbg->de_relocation_record_size,
-				 /* type */ SHT_REL,
-				 /* flags */ 0,
-				 /* link to symtab, which we cannot
-				    know */ SHN_UNDEF,
-				 /* sec rels apply to, in elf, sh_info */
-				 dbg->de_elf_sects[i], &int_name, &err);
-		name_idx = int_name;
-	    }
-	    if (rel_section_index == -1) {
-		{
-		    _dwarf_p_error(dbg, &error, DW_DLE_ELF_SECT_ERR);
-		    return (DW_DLV_ERROR);
-		}
-	    }
-	    p_reloc->pr_sect_num_of_reloc_sect = rel_section_index;
-	    sec_index = rel_section_index;
-	}
+            if (dbg->de_callback_func_b) {
+                rel_section_index =
+                    dbg->de_callback_func_b(_dwarf_rel_section_names[i],
+                                   dbg->de_relocation_record_size,
+                                   /* type */ SHT_REL,
+                                   /* flags */ 0,
+                                   /* link to symtab, which we cannot
+                                      know */ SHN_UNDEF,
+                                   /* sec rels apply to */
+                                   dbg->de_elf_sects[i],
+                                   &name_idx, &err);
+            } else {
+                rel_section_index =
+                    dbg->de_callback_func(_dwarf_rel_section_names[i],
+                                 dbg->de_relocation_record_size,
+                                 /* type */ SHT_REL,
+                                 /* flags */ 0,
+                                 /* link to symtab, which we cannot
+                                    know */ SHN_UNDEF,
+                                 /* sec rels apply to, in elf, sh_info */
+                                 dbg->de_elf_sects[i], &int_name, &err);
+                name_idx = int_name;
+            }
+            if (rel_section_index == -1) {
+                {
+                    _dwarf_p_error(dbg, &error, DW_DLE_ELF_SECT_ERR);
+                    return (DW_DLV_ERROR);
+                }
+            }
+            p_reloc->pr_sect_num_of_reloc_sect = rel_section_index;
+            sec_index = rel_section_index;
+        }
 
-	p_blk = p_reloc->pr_first_block;
-
-	if (p_reloc->pr_block_count > 1) {
-	    struct Dwarf_P_Relocation_Block_s *new_blk;
+        p_blk = p_reloc->pr_first_block;
 
-	    /* HACK , not normal interfaces, trashing p_reloc
-	       current contents! */
-	    _dwarf_reset_reloc_sect_info(p_reloc, ct);
+        if (p_reloc->pr_block_count > 1) {
+            struct Dwarf_P_Relocation_Block_s *new_blk;
 
-	    /* Creating new single block for all 'ct' entries */
-	    res = _dwarf_pro_pre_alloc_n_reloc_slots(dbg, (int) i, ct);
-
+            /* HACK , not normal interfaces, trashing p_reloc current
+               contents! */
+            _dwarf_reset_reloc_sect_info(p_reloc, ct);
 
-	    if (res != DW_DLV_OK) {
-		return res;
-	    }
-	    new_blk = p_reloc->pr_first_block;
+            /* Creating new single block for all 'ct' entries */
+            res = _dwarf_pro_pre_alloc_n_reloc_slots(dbg, (int) i, ct);
+            if (res != DW_DLV_OK) {
+                return res;
+            }
+            new_blk = p_reloc->pr_first_block;
 
-	    data = (Dwarf_Small *) new_blk->rb_data;
-
-	    /* The following loop does the consolidation to a 
-	       single block and frees the input block(s). */
-	    do {
+            data = (Dwarf_Small *) new_blk->rb_data;
 
-		unsigned long len =
-		    p_blk->rb_where_to_add_next - p_blk->rb_data;
-
-		memcpy(data, p_blk->rb_data, len);
-		data += len;
-
-		p_blk_last = p_blk;
-		p_blk = p_blk->rb_next;
+            /* The following loop does the consolidation to a single
+               block and frees the input block(s). */
+            do {
+                unsigned long len =
+                    p_blk->rb_where_to_add_next - p_blk->rb_data;
+                memcpy(data, p_blk->rb_data, len);
+                data += len;
+                p_blk_last = p_blk;
+                p_blk = p_blk->rb_next;
+                _dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last);
+            } while (p_blk);
+            /* ASSERT: sum of len copied == total_size */
+            new_blk->rb_next_slot_to_use = ct;
+            new_blk->rb_where_to_add_next = (char *) data;
+            p_reloc->pr_reloc_total_count = ct;
 
-		_dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last);
-	    } while (p_blk) ;
-	    /* ASSERT: sum of len copied == total_size */
-	    new_blk->rb_next_slot_to_use = ct;
-	    new_blk->rb_where_to_add_next = (char *) data;
-	    p_reloc->pr_reloc_total_count = ct;
-
-	    /* have now created a single block, but no change in slots
-	       used (pr_reloc_total_count) */
-	}
+            /* have now created a single block, but no change in slots
+               used (pr_reloc_total_count) */
+        }
     }
-
     *new_sec_count = 0;
     return DW_DLV_OK;
 }
--- a/usr/src/tools/ctf/dwarf/common/pro_reloc_symbolic.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_reloc_symbolic.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
--- a/usr/src/tools/ctf/dwarf/common/pro_section.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_section.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,8 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004,2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
+  Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +21,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -32,6 +34,11 @@
   http://oss.sgi.com/projects/GenInfo/NoticeExplan
 
 */
+/* 
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
 
 
 
@@ -66,22 +73,23 @@
 #endif
 
 /* must match up with pro_section.h defines of DEBUG_INFO etc 
-and sectnames (below)
+and sectnames (below).  REL_SEC_PREFIX is either ".rel" or ".rela"
+see pro_incl.h
 */
 char *_dwarf_rel_section_names[] = {
-    ".rel.debug_info",
-    ".rel.debug_line",
-    ".rel.debug_abbrev",	/* no relocations on this, really */
-    ".rel.debug_frame",
-    ".rel.debug_aranges",
-    ".rel.debug_pubnames",
-    ".rel.debug_str",
-    ".rel.debug_funcnames",	/* sgi extension */
-    ".rel.debug_typenames",	/* sgi extension */
-    ".rel.debug_varnames",	/* sgi extension */
-    ".rel.debug_weaknames",	/* sgi extension */
-    ".rel.debug_macinfo",
-    ".rel.debug_loc"
+    REL_SEC_PREFIX ".debug_info",
+    REL_SEC_PREFIX ".debug_line",
+    REL_SEC_PREFIX ".debug_abbrev",     /* no relocations on this, really */
+    REL_SEC_PREFIX ".debug_frame",
+    REL_SEC_PREFIX ".debug_aranges",
+    REL_SEC_PREFIX ".debug_pubnames",
+    REL_SEC_PREFIX ".debug_str",
+    REL_SEC_PREFIX ".debug_funcnames",  /* sgi extension */
+    REL_SEC_PREFIX ".debug_typenames",  /* sgi extension */
+    REL_SEC_PREFIX ".debug_varnames",   /* sgi extension */
+    REL_SEC_PREFIX ".debug_weaknames",  /* sgi extension */
+    REL_SEC_PREFIX ".debug_macinfo",
+    REL_SEC_PREFIX ".debug_loc"
 };
 
 /* names of sections. Ensure that it matches the defines 
@@ -96,10 +104,10 @@
     ".debug_aranges",
     ".debug_pubnames",
     ".debug_str",
-    ".debug_funcnames",		/* sgi extension */
-    ".debug_typenames",		/* sgi extension */
-    ".debug_varnames",		/* sgi extension */
-    ".debug_weaknames",		/* sgi extension */
+    ".debug_funcnames",         /* sgi extension */
+    ".debug_typenames",         /* sgi extension */
+    ".debug_varnames",          /* sgi extension */
+    ".debug_weaknames",         /* sgi extension */
     ".debug_macinfo",
     ".debug_loc"
 };
@@ -107,15 +115,15 @@
 
 
 
-static Dwarf_Ubyte std_opcode_len[] = { 0,	/* DW_LNS_copy */
-    1,				/* DW_LNS_advance_pc */
-    1,				/* DW_LNS_advance_line */
-    1,				/* DW_LNS_set_file */
-    1,				/* DW_LNS_set_column */
-    0,				/* DW_LNS_negate_stmt */
-    0,				/* DW_LNS_set_basic_block */
-    0,				/* DW_LNS_const_add_pc */
-    1,				/* DW_LNS_fixed_advance_pc */
+static Dwarf_Ubyte std_opcode_len[] = { 0,      /* DW_LNS_copy */
+    1,                          /* DW_LNS_advance_pc */
+    1,                          /* DW_LNS_advance_line */
+    1,                          /* DW_LNS_set_file */
+    1,                          /* DW_LNS_set_column */
+    0,                          /* DW_LNS_negate_stmt */
+    0,                          /* DW_LNS_set_basic_block */
+    0,                          /* DW_LNS_const_add_pc */
+    1,                          /* DW_LNS_fixed_advance_pc */
 };
 
 /* struct to hold relocation entries. Its mantained as a linked
@@ -136,25 +144,34 @@
 };
 
 static int _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg,
-					 Dwarf_Error * error);
+                                         Dwarf_Error * error);
 static int _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg,
-					  Dwarf_Error * error);
+                                          Dwarf_Error * error);
 static int _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg,
-					 Dwarf_Error * error);
+                                         Dwarf_Error * error);
 static Dwarf_P_Abbrev _dwarf_pro_getabbrev(Dwarf_P_Die, Dwarf_P_Abbrev);
 static int _dwarf_pro_match_attr
     (Dwarf_P_Attribute, Dwarf_P_Abbrev, int no_attr);
 
 /* these macros used as return value for below functions */
-#define		OPC_INCS_ZERO		-1
-#define		OPC_OUT_OF_RANGE	-2
-#define		LINE_OUT_OF_RANGE	-3
+#define         OPC_INCS_ZERO           -1
+#define         OPC_OUT_OF_RANGE        -2
+#define         LINE_OUT_OF_RANGE       -3
 static int _dwarf_pro_get_opc(Dwarf_Unsigned addr_adv, int line_adv);
 
 
+/* BEGIN_LEN_SIZE is the size of the 'length' field in total. 
+   Which may be 4,8, or 12 bytes! 
+   4 is standard DWARF2.
+   8 is non-standard MIPS-IRIX 64-bit.
+   12 is standard DWARF3 for 64 bit offsets.
+   Used in various routines: local variable names
+   must match the names here.
+*/
+#define BEGIN_LEN_SIZE (uwordb_size + extension_size)
 
 /*
-	Return TRUE if we need the section, FALSE otherwise
+        Return TRUE if we need the section, FALSE otherwise
 
         If any of the 'line-data-related' calls were made
         including file or directory entries,
@@ -165,8 +182,8 @@
 dwarf_need_debug_line_section(Dwarf_P_Debug dbg)
 {
     if (dbg->de_lines == NULL && dbg->de_file_entries == NULL
-	&& dbg->de_inc_dirs == NULL) {
-	return FALSE;
+        && dbg->de_inc_dirs == NULL) {
+        return FALSE;
     }
     return TRUE;
 }
@@ -182,311 +199,306 @@
     /* 
        Section data in written out in a number of buffers. Each
        _generate_*() function returns a cumulative count of buffers for 
-       all the sections. get_section_bytes() returns pointers to these 
+       all the sections. get_section_bytes() returns pointers to these
        buffers one at a time. */
-    int nbufs;
-    int sect;
-    int name_idx;
-    int err;
-    Dwarf_Unsigned du;
+    int nbufs = 0;
+    int sect = 0;
+    int err = 0;
+    Dwarf_Unsigned du = 0;
 
     if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) {
-	DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_NOCOUNT);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_NOCOUNT);
     }
 
     /* Create dwarf section headers */
     for (sect = 0; sect < NUM_DEBUG_SECTIONS; sect++) {
-	long flags = 0;
+        long flags = 0;
 
-	switch (sect) {
+        switch (sect) {
 
-	case DEBUG_INFO:
-	    if (dbg->de_dies == NULL)
-		continue;
-	    break;
+        case DEBUG_INFO:
+            if (dbg->de_dies == NULL)
+                continue;
+            break;
 
-	case DEBUG_LINE:
-	    if (dwarf_need_debug_line_section(dbg) == FALSE) {
-		continue;
-	    }
-	    break;
+        case DEBUG_LINE:
+            if (dwarf_need_debug_line_section(dbg) == FALSE) {
+                continue;
+            }
+            break;
 
-	case DEBUG_ABBREV:
-	    if (dbg->de_dies == NULL)
-		continue;
-	    break;
+        case DEBUG_ABBREV:
+            if (dbg->de_dies == NULL)
+                continue;
+            break;
 
-	case DEBUG_FRAME:
-	    if (dbg->de_frame_cies == NULL)
-		continue;
-	    flags = SHF_MIPS_NOSTRIP;
-	    break;
+        case DEBUG_FRAME:
+            if (dbg->de_frame_cies == NULL)
+                continue;
+            flags = SHF_MIPS_NOSTRIP;
+            break;
 
-	case DEBUG_ARANGES:
-	    if (dbg->de_arange == NULL)
-		continue;
-	    break;
+        case DEBUG_ARANGES:
+            if (dbg->de_arange == NULL)
+                continue;
+            break;
 
-	case DEBUG_PUBNAMES:
-	    if (dbg->de_simple_name_headers[dwarf_snk_pubname].
-		sn_head == NULL)
-		continue;
-	    break;
+        case DEBUG_PUBNAMES:
+            if (dbg->de_simple_name_headers[dwarf_snk_pubname].
+                sn_head == NULL)
+                continue;
+            break;
 
-	case DEBUG_STR:
-	    if (dbg->de_strings == NULL)
-		continue;
-	    break;
+        case DEBUG_STR:
+            if (dbg->de_strings == NULL)
+                continue;
+            break;
 
-	case DEBUG_FUNCNAMES:
-	    if (dbg->de_simple_name_headers[dwarf_snk_funcname].
-		sn_head == NULL)
-		continue;
-	    break;
+        case DEBUG_FUNCNAMES:
+            if (dbg->de_simple_name_headers[dwarf_snk_funcname].
+                sn_head == NULL)
+                continue;
+            break;
 
-	case DEBUG_TYPENAMES:
-	    if (dbg->de_simple_name_headers[dwarf_snk_typename].
-		sn_head == NULL)
-		continue;
-	    break;
+        case DEBUG_TYPENAMES:
+            if (dbg->de_simple_name_headers[dwarf_snk_typename].
+                sn_head == NULL)
+                continue;
+            break;
 
-	case DEBUG_VARNAMES:
-	    if (dbg->de_simple_name_headers[dwarf_snk_varname].
-		sn_head == NULL)
-		continue;
-	    break;
+        case DEBUG_VARNAMES:
+            if (dbg->de_simple_name_headers[dwarf_snk_varname].
+                sn_head == NULL)
+                continue;
+            break;
 
-	case DEBUG_WEAKNAMES:
-	    if (dbg->de_simple_name_headers[dwarf_snk_weakname].
-		sn_head == NULL)
-		continue;
-	    break;
+        case DEBUG_WEAKNAMES:
+            if (dbg->de_simple_name_headers[dwarf_snk_weakname].
+                sn_head == NULL)
+                continue;
+            break;
 
-	case DEBUG_MACINFO:
-	    if (dbg->de_first_macinfo == NULL)
-		continue;
-	    break;
-	case DEBUG_LOC:
-	    /* not handled yet */
-	    continue;
-	default:
-	    /* logic error: missing a case */
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_NOCOUNT);
-	}
-	{
-	    int new_base_elf_sect;
+        case DEBUG_MACINFO:
+            if (dbg->de_first_macinfo == NULL)
+                continue;
+            break;
+        case DEBUG_LOC:
+            /* not handled yet */
+            continue;
+        default:
+            /* logic error: missing a case */
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_NOCOUNT);
+        }
+        {
+            int new_base_elf_sect;
 
-	    if (dbg->de_func_b) {
-		new_base_elf_sect =
-		    dbg->de_func_b(_dwarf_sectnames[sect],
-				   /* rec size */ 1,
-				   SECTION_TYPE,
-				   flags, SHN_UNDEF, 0, &du, &err);
+            if (dbg->de_callback_func_b) {
+                new_base_elf_sect =
+                    dbg->de_callback_func_b(_dwarf_sectnames[sect],
+                        /* rec size */ 1,
+                        SECTION_TYPE,
+                        flags, SHN_UNDEF, 0, &du, &err);
 
-	    } else {
-		new_base_elf_sect = dbg->de_func(_dwarf_sectnames[sect],
-						 dbg->
-						 de_relocation_record_size,
-						 SECTION_TYPE, flags,
-						 SHN_UNDEF, 0,
-						 &name_idx, &err);
-		du = name_idx;
-	    }
-	    if (new_base_elf_sect == -1) {
-		DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR,
-				  DW_DLV_NOCOUNT);
-	    }
-	    dbg->de_elf_sects[sect] = new_base_elf_sect;
+            } else {
+                int name_idx = 0;
+                new_base_elf_sect = dbg->de_callback_func(
+                    _dwarf_sectnames[sect],
+                    dbg->de_relocation_record_size,
+                    SECTION_TYPE, flags,
+                    SHN_UNDEF, 0,
+                    &name_idx, &err);
+                du = name_idx;
+            }
+            if (new_base_elf_sect == -1) {
+                DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR,
+                                  DW_DLV_NOCOUNT);
+            }
+            dbg->de_elf_sects[sect] = new_base_elf_sect;
 
-	    dbg->de_sect_name_idx[sect] = du;
-	}
+            dbg->de_sect_name_idx[sect] = du;
+        }
     }
 
     nbufs = 0;
 
     /* 
-       Changing the order in which the sections are generated may
-       cause problems because of relocations. */
+       Changing the order in which the sections are generated may cause 
+       problems because of relocations. */
 
     if (dwarf_need_debug_line_section(dbg) == TRUE) {
-	nbufs = _dwarf_pro_generate_debugline(dbg, error);
-	if (nbufs < 0) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGLINE_ERROR,
-			      DW_DLV_NOCOUNT);
-	}
+        nbufs = _dwarf_pro_generate_debugline(dbg, error);
+        if (nbufs < 0) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGLINE_ERROR,
+                              DW_DLV_NOCOUNT);
+        }
     }
 
     if (dbg->de_frame_cies) {
-	nbufs = _dwarf_pro_generate_debugframe(dbg, error);
-	if (nbufs < 0) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGFRAME_ERROR,
-			      DW_DLV_NOCOUNT);
-	}
+        nbufs = _dwarf_pro_generate_debugframe(dbg, error);
+        if (nbufs < 0) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGFRAME_ERROR,
+                              DW_DLV_NOCOUNT);
+        }
     }
     if (dbg->de_first_macinfo) {
-	nbufs = _dwarf_pro_transform_macro_info_to_disk(dbg, error);
-	if (nbufs < 0) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGMACINFO_ERROR,
-			      DW_DLV_NOCOUNT);
-	}
+        nbufs = _dwarf_pro_transform_macro_info_to_disk(dbg, error);
+        if (nbufs < 0) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGMACINFO_ERROR,
+                              DW_DLV_NOCOUNT);
+        }
     }
 
     if (dbg->de_dies) {
-	nbufs = _dwarf_pro_generate_debuginfo(dbg, error);
-	if (nbufs < 0) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
-			      DW_DLV_NOCOUNT);
-	}
+        nbufs = _dwarf_pro_generate_debuginfo(dbg, error);
+        if (nbufs < 0) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
+                              DW_DLV_NOCOUNT);
+        }
     }
 
     if (dbg->de_arange) {
-	nbufs = _dwarf_transform_arange_to_disk(dbg, error);
-	if (nbufs < 0) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
-			      DW_DLV_NOCOUNT);
-	}
+        nbufs = _dwarf_transform_arange_to_disk(dbg, error);
+        if (nbufs < 0) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
+                              DW_DLV_NOCOUNT);
+        }
     }
 
     if (dbg->de_simple_name_headers[dwarf_snk_pubname].sn_head) {
-	nbufs = _dwarf_transform_simplename_to_disk(dbg,
-						    dwarf_snk_pubname,
-						    DEBUG_PUBNAMES,
-						    error);
+        nbufs = _dwarf_transform_simplename_to_disk(dbg,
+                                                    dwarf_snk_pubname,
+                                                    DEBUG_PUBNAMES,
+                                                    error);
 
 
-	if (nbufs < 0) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
-			      DW_DLV_NOCOUNT);
-	}
+        if (nbufs < 0) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
+                              DW_DLV_NOCOUNT);
+        }
     }
 
     if (dbg->de_simple_name_headers[dwarf_snk_funcname].sn_head) {
-	nbufs = _dwarf_transform_simplename_to_disk(dbg,
-						    dwarf_snk_funcname,
-						    DEBUG_FUNCNAMES,
-						    error);
-	if (nbufs < 0) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
-			      DW_DLV_NOCOUNT);
-	}
+        nbufs = _dwarf_transform_simplename_to_disk(dbg,
+                                                    dwarf_snk_funcname,
+                                                    DEBUG_FUNCNAMES,
+                                                    error);
+        if (nbufs < 0) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
+                              DW_DLV_NOCOUNT);
+        }
     }
 
     if (dbg->de_simple_name_headers[dwarf_snk_typename].sn_head) {
-	nbufs = _dwarf_transform_simplename_to_disk(dbg,
-						    dwarf_snk_typename,
-						    DEBUG_TYPENAMES,
-						    error);
-	if (nbufs < 0) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
-			      DW_DLV_NOCOUNT);
-	}
+        nbufs = _dwarf_transform_simplename_to_disk(dbg,
+                                                    dwarf_snk_typename,
+                                                    DEBUG_TYPENAMES,
+                                                    error);
+        if (nbufs < 0) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
+                              DW_DLV_NOCOUNT);
+        }
     }
 
     if (dbg->de_simple_name_headers[dwarf_snk_varname].sn_head) {
-	nbufs = _dwarf_transform_simplename_to_disk(dbg,
-						    dwarf_snk_varname,
-						    DEBUG_VARNAMES,
-						    error);
+        nbufs = _dwarf_transform_simplename_to_disk(dbg,
+                                                    dwarf_snk_varname,
+                                                    DEBUG_VARNAMES,
+                                                    error);
 
-	if (nbufs < 0) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
-			      DW_DLV_NOCOUNT);
-	}
+        if (nbufs < 0) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
+                              DW_DLV_NOCOUNT);
+        }
     }
 
     if (dbg->de_simple_name_headers[dwarf_snk_weakname].sn_head) {
-	nbufs = _dwarf_transform_simplename_to_disk(dbg,
-						    dwarf_snk_weakname,
-						    DEBUG_WEAKNAMES,
-						    error);
-
-	if (nbufs < 0) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
-			      DW_DLV_NOCOUNT);
-	}
+        nbufs = _dwarf_transform_simplename_to_disk(dbg,
+            dwarf_snk_weakname, DEBUG_WEAKNAMES, error);
+        if (nbufs < 0) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
+                              DW_DLV_NOCOUNT);
+        }
     }
 
     {
-	Dwarf_Signed new_secs;
-	int res;
+        Dwarf_Signed new_secs = 0;
+        int res = 0;
 
-	res = dbg->de_transform_relocs_to_disk(dbg, &new_secs);
-	if (res != DW_DLV_OK) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
-			      DW_DLV_NOCOUNT);
-	}
-	nbufs += new_secs;
+        res = dbg->de_transform_relocs_to_disk(dbg, &new_secs);
+        if (res != DW_DLV_OK) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
+                              DW_DLV_NOCOUNT);
+        }
+        nbufs += new_secs;
     }
     return nbufs;
 }
 
 
 /*---------------------------------------------------------------
-	Generate debug_line section 
+        Generate debug_line section 
 ---------------------------------------------------------------*/
 static int
 _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Error * error)
 {
-    Dwarf_P_Inc_Dir curdir;
-    Dwarf_P_F_Entry curentry;
-    Dwarf_P_Line curline, prevline;
+    Dwarf_P_Inc_Dir curdir = 0;
+    Dwarf_P_F_Entry curentry = 0;
+    Dwarf_P_Line curline = 0;
+    Dwarf_P_Line prevline = 0;
 
     /* all data named cur* are used to loop thru linked lists */
 
-    int sum_bytes;
-    int prolog_size;
-    unsigned char *data;	/* holds disk form data */
-    int elfsectno;
-    unsigned char *start_line_sec;	/* pointer to the buffer at
-					   section start */
+    int sum_bytes = 0;
+    int prolog_size = 0;
+    unsigned char *data = 0;    /* holds disk form data */
+    int elfsectno = 0;
+    unsigned char *start_line_sec = 0;  /* pointer to the buffer at
+                                           section start */
     /* temps for memcpy */
-    Dwarf_Unsigned du;
-    Dwarf_Ubyte db;
-    Dwarf_Half dh;
-    int res;
+    Dwarf_Unsigned du = 0;
+    Dwarf_Ubyte db = 0;
+    Dwarf_Half dh = 0;
+    int res = 0;
     int uwordb_size = dbg->de_offset_size;
     int extension_size = dbg->de_64bit_extension ? 4 : 0;
     int upointer_size = dbg->de_pointer_size;
     char buff1[ENCODE_SPACE_NEEDED];
 
 
+
     sum_bytes = 0;
 
     elfsectno = dbg->de_elf_sects[DEBUG_LINE];
 
-    /* statement prologue information */
-    prolog_size = 0;
     /* include directories */
     curdir = dbg->de_inc_dirs;
     while (curdir) {
-	prolog_size += strlen(curdir->did_name) + 1;
-	curdir = curdir->did_next;
+        prolog_size += strlen(curdir->did_name) + 1;
+        curdir = curdir->did_next;
     }
-    prolog_size++;		/* last null following last directory
-				   entry. */
+    prolog_size++;              /* last null following last directory
+                                   entry. */
 
     /* file entries */
     curentry = dbg->de_file_entries;
     while (curentry) {
-	prolog_size +=
-	    strlen(curentry->dfe_name) + 1 + curentry->dfe_nbytes;
-	curentry = curentry->dfe_next;
+        prolog_size +=
+            strlen(curentry->dfe_name) + 1 + curentry->dfe_nbytes;
+        curentry = curentry->dfe_next;
     }
-    prolog_size++;		/* last null byte */
+    prolog_size++;              /* last null byte */
 
 
-    prolog_size += extension_size +	/* DISTINGUISHED VALUE */
-	sizeof_uhalf(dbg) +	/* version # */
-	uwordb_size +		/* prologue length */
-	sizeof_ubyte(dbg) +	/* min_instr length */
-	sizeof_ubyte(dbg) +	/* default is_stmt */
-	sizeof_ubyte(dbg) +	/* linebase */
-	sizeof_ubyte(dbg) +	/* linerange */
-	sizeof_ubyte(dbg);	/* opcode base */
+    prolog_size += BEGIN_LEN_SIZE + sizeof_uhalf(dbg) + /* version # */
+        uwordb_size +           /* header length */
+        sizeof_ubyte(dbg) +     /* min_instr length */
+        sizeof_ubyte(dbg) +     /* default is_stmt */
+        sizeof_ubyte(dbg) +     /* linebase */
+        sizeof_ubyte(dbg) +     /* linerange */
+        sizeof_ubyte(dbg);      /* opcode base */
 
     /* length of table specifying # of opnds */
     prolog_size += sizeof(std_opcode_len);
-    prolog_size += uwordb_size;	/* for total length field */
 
     GET_CHUNK(dbg, elfsectno, data, prolog_size, error);
     start_line_sec = data;
@@ -495,73 +507,74 @@
     /* total_length */
     du = 0;
     if (extension_size) {
-	Dwarf_Word x = DISTINGUISHED_VALUE;
+        Dwarf_Word x = DISTINGUISHED_VALUE;
 
-	WRITE_UNALIGNED(dbg, (void *) data, (const void *) &x,
-			sizeof(x), extension_size);
-	data += extension_size;
+        WRITE_UNALIGNED(dbg, (void *) data, (const void *) &x,
+                        sizeof(x), extension_size);
+        data += extension_size;
     }
 
     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
-		    sizeof(du), uwordb_size);
+                    sizeof(du), uwordb_size);
     data += uwordb_size;
 
     dh = VERSION;
     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dh,
-		    sizeof(dh), sizeof(Dwarf_Half));
+                    sizeof(dh), sizeof(Dwarf_Half));
     data += sizeof(Dwarf_Half);
 
-    /* prologue length */
-    du = prolog_size - (uwordb_size + sizeof(Dwarf_Half) + uwordb_size);
+    /* header length */
+    du = prolog_size - (BEGIN_LEN_SIZE + sizeof(Dwarf_Half) +
+                        uwordb_size);
     {
-	WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
-			sizeof(du), uwordb_size);
-	data += uwordb_size;
+        WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
+                        sizeof(du), uwordb_size);
+        data += uwordb_size;
     }
     db = MIN_INST_LENGTH;
     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
-		    sizeof(db), sizeof(Dwarf_Ubyte));
+                    sizeof(db), sizeof(Dwarf_Ubyte));
     data += sizeof(Dwarf_Ubyte);
     db = DEFAULT_IS_STMT;
     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
-		    sizeof(db), sizeof(Dwarf_Ubyte));
+                    sizeof(db), sizeof(Dwarf_Ubyte));
     data += sizeof(Dwarf_Ubyte);
     db = (Dwarf_Ubyte) LINE_BASE;
     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
-		    sizeof(db), sizeof(Dwarf_Ubyte));
+                    sizeof(db), sizeof(Dwarf_Ubyte));
     data += sizeof(Dwarf_Ubyte);
     db = LINE_RANGE;
     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
-		    sizeof(db), sizeof(Dwarf_Ubyte));
+                    sizeof(db), sizeof(Dwarf_Ubyte));
     data += sizeof(Dwarf_Ubyte);
     db = OPCODE_BASE;
     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
-		    sizeof(db), sizeof(Dwarf_Ubyte));
+                    sizeof(db), sizeof(Dwarf_Ubyte));
     data += sizeof(Dwarf_Ubyte);
     WRITE_UNALIGNED(dbg, (void *) data, (const void *) std_opcode_len,
-		    sizeof(std_opcode_len), sizeof(std_opcode_len));
+                    sizeof(std_opcode_len), sizeof(std_opcode_len));
     data += sizeof(std_opcode_len);
 
     /* copy over include directories */
     curdir = dbg->de_inc_dirs;
     while (curdir) {
-	strcpy((char *) data, curdir->did_name);
-	data += strlen(curdir->did_name) + 1;
-	curdir = curdir->did_next;
+        strcpy((char *) data, curdir->did_name);
+        data += strlen(curdir->did_name) + 1;
+        curdir = curdir->did_next;
     }
-    *data = '\0';		/* last null */
+    *data = '\0';               /* last null */
     data++;
 
     /* copy file entries */
     curentry = dbg->de_file_entries;
     while (curentry) {
-	strcpy((char *) data, curentry->dfe_name);
-	data += strlen(curentry->dfe_name) + 1;
-	/* copies of leb numbers, no endian issues */
-	memcpy((void *) data,
-	       (const void *) curentry->dfe_args, curentry->dfe_nbytes);
-	data += curentry->dfe_nbytes;
-	curentry = curentry->dfe_next;
+        strcpy((char *) data, curentry->dfe_name);
+        data += strlen(curentry->dfe_name) + 1;
+        /* copies of leb numbers, no endian issues */
+        memcpy((void *) data,
+               (const void *) curentry->dfe_args, curentry->dfe_nbytes);
+        data += curentry->dfe_nbytes;
+        curentry = curentry->dfe_next;
     }
     *data = '\0';
     data++;
@@ -570,334 +583,330 @@
 
     curline = dbg->de_lines;
     prevline = (Dwarf_P_Line)
-	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
+        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
     if (prevline == NULL) {
-	DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, -1);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, -1);
     }
     _dwarf_pro_reg_init(prevline);
     /* generate opcodes for line numbers */
     while (curline) {
-	int nbytes;
-	char *arg;
-	int opc;
-	int no_lns_copy;	/* if lns copy opcode doesnt need to be 
-				   generated, if special opcode or end 
-				   sequence */
-	Dwarf_Unsigned addr_adv;
-	int line_adv;		/* supposed to be a reasonably small
-				   number, so the size should not be a
-				   problem. ? */
+        int nbytes;
+        char *arg;
+        int opc;
+        int no_lns_copy;        /* if lns copy opcode doesnt need to be 
+                                   generated, if special opcode or end
+                                   sequence */
+        Dwarf_Unsigned addr_adv;
+        int line_adv;           /* supposed to be a reasonably small
+                                   number, so the size should not be a
+                                   problem. ? */
 
-	no_lns_copy = 0;
-	if (curline->dpl_opc != 0) {
-	    int inst_bytes;	/* no of bytes in extended opcode */
-	    char *str;		/* hold leb encoded inst_bytes */
-	    int str_nbytes;	/* no of bytes in str */
+        no_lns_copy = 0;
+        if (curline->dpl_opc != 0) {
+            int inst_bytes;     /* no of bytes in extended opcode */
+            char *str;          /* hold leb encoded inst_bytes */
+            int str_nbytes;     /* no of bytes in str */
 
-	    switch (curline->dpl_opc) {
-	    case DW_LNE_end_sequence:
+            switch (curline->dpl_opc) {
+            case DW_LNE_end_sequence:
 
-		/* Advance pc to end of text section. */
-		addr_adv = curline->dpl_address - prevline->dpl_address;
-		if (addr_adv > 0) {
-		    db = DW_LNS_advance_pc;
-		    res =
-			_dwarf_pro_encode_leb128_nm(addr_adv /
-						    MIN_INST_LENGTH,
-						    &nbytes, buff1,
-						    sizeof(buff1));
-		    if (res != DW_DLV_OK) {
-			DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
-		    }
-		    GET_CHUNK(dbg, elfsectno, data,
-			      nbytes + sizeof(Dwarf_Ubyte), error);
-		    WRITE_UNALIGNED(dbg, (void *) data,
-				    (const void *) &db, sizeof(db),
-				    sizeof(Dwarf_Ubyte));
-		    data += sizeof(Dwarf_Ubyte);
-		    /* leb, no endianness issue */
-		    memcpy((void *) data, (const void *) buff1, nbytes);
-		    data += nbytes + sizeof(Dwarf_Ubyte);
-		    sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
-		    prevline->dpl_address = curline->dpl_address;
-		}
+                /* Advance pc to end of text section. */
+                addr_adv = curline->dpl_address - prevline->dpl_address;
+                if (addr_adv > 0) {
+                    db = DW_LNS_advance_pc;
+                    res =
+                        _dwarf_pro_encode_leb128_nm(addr_adv /
+                                                    MIN_INST_LENGTH,
+                                                    &nbytes, buff1,
+                                                    sizeof(buff1));
+                    if (res != DW_DLV_OK) {
+                        DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+                    }
+                    GET_CHUNK(dbg, elfsectno, data,
+                              nbytes + sizeof(Dwarf_Ubyte), error);
+                    WRITE_UNALIGNED(dbg, (void *) data,
+                                    (const void *) &db, sizeof(db),
+                                    sizeof(Dwarf_Ubyte));
+                    data += sizeof(Dwarf_Ubyte);
+                    /* leb, no endianness issue */
+                    memcpy((void *) data, (const void *) buff1, nbytes);
+                    data += nbytes + sizeof(Dwarf_Ubyte);
+                    sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
+                    prevline->dpl_address = curline->dpl_address;
+                }
 
-		/* first null byte */
-		db = 0;
-		GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
-			  error);
-		WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
-				sizeof(db), sizeof(Dwarf_Ubyte));
-		data += sizeof(Dwarf_Ubyte);
-		sum_bytes += sizeof(Dwarf_Ubyte);
+                /* first null byte */
+                db = 0;
+                GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
+                          error);
+                WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+                                sizeof(db), sizeof(Dwarf_Ubyte));
+                data += sizeof(Dwarf_Ubyte);
+                sum_bytes += sizeof(Dwarf_Ubyte);
 
-		/* write length of extended opcode */
-		inst_bytes = sizeof(Dwarf_Ubyte);
-		res =
-		    _dwarf_pro_encode_leb128_nm(inst_bytes, &str_nbytes,
-						buff1, sizeof(buff1));
-		if (res != DW_DLV_OK) {
-		    DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
-		}
-		GET_CHUNK(dbg, elfsectno, data, str_nbytes, error);
-		memcpy((void *) data, (const void *) buff1, str_nbytes);
-		data += str_nbytes;
-		sum_bytes += str_nbytes;
+                /* write length of extended opcode */
+                inst_bytes = sizeof(Dwarf_Ubyte);
+                res =
+                    _dwarf_pro_encode_leb128_nm(inst_bytes, &str_nbytes,
+                                                buff1, sizeof(buff1));
+                if (res != DW_DLV_OK) {
+                    DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+                }
+                GET_CHUNK(dbg, elfsectno, data, str_nbytes, error);
+                memcpy((void *) data, (const void *) buff1, str_nbytes);
+                data += str_nbytes;
+                sum_bytes += str_nbytes;
 
-		/* write extended opcode */
-		db = DW_LNE_end_sequence;
-		GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
-			  error);
-		WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
-				sizeof(db), sizeof(Dwarf_Ubyte));
-		data += sizeof(Dwarf_Ubyte);
-		sum_bytes += sizeof(Dwarf_Ubyte);
-		/* reset value to original values */
-		_dwarf_pro_reg_init(prevline);
-		no_lns_copy = 1;
-		/* this is set only for end_sequence, so that a
-		   dw_lns_copy is not generated */
-		break;
+                /* write extended opcode */
+                db = DW_LNE_end_sequence;
+                GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
+                          error);
+                WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+                                sizeof(db), sizeof(Dwarf_Ubyte));
+                data += sizeof(Dwarf_Ubyte);
+                sum_bytes += sizeof(Dwarf_Ubyte);
+                /* reset value to original values */
+                _dwarf_pro_reg_init(prevline);
+                no_lns_copy = 1;
+                /* this is set only for end_sequence, so that a
+                   dw_lns_copy is not generated */
+                break;
 
-	    case DW_LNE_set_address:
+            case DW_LNE_set_address:
 
-		/* first null byte */
-		db = 0;
-		GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
-			  error);
-		WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
-				sizeof(db), sizeof(Dwarf_Ubyte));
-		data += sizeof(Dwarf_Ubyte);
-		sum_bytes += sizeof(Dwarf_Ubyte);
+                /* first null byte */
+                db = 0;
+                GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
+                          error);
+                WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+                                sizeof(db), sizeof(Dwarf_Ubyte));
+                data += sizeof(Dwarf_Ubyte);
+                sum_bytes += sizeof(Dwarf_Ubyte);
 
-		/* write length of extended opcode */
-		inst_bytes = sizeof(Dwarf_Ubyte) + upointer_size;
-		res =
-		    _dwarf_pro_encode_leb128_nm(inst_bytes, &str_nbytes,
-						buff1, sizeof(buff1));
-		if (res != DW_DLV_OK) {
-		    DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
-		}
-		GET_CHUNK(dbg, elfsectno, data, str_nbytes, error);
-		str = buff1;
-		/* leb number, no endian issue */
-		memcpy((void *) data, (const void *) str, str_nbytes);
-		data += str_nbytes;
-		sum_bytes += str_nbytes;
+                /* write length of extended opcode */
+                inst_bytes = sizeof(Dwarf_Ubyte) + upointer_size;
+                res =
+                    _dwarf_pro_encode_leb128_nm(inst_bytes, &str_nbytes,
+                                                buff1, sizeof(buff1));
+                if (res != DW_DLV_OK) {
+                    DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+                }
+                GET_CHUNK(dbg, elfsectno, data, str_nbytes, error);
+                str = buff1;
+                /* leb number, no endian issue */
+                memcpy((void *) data, (const void *) str, str_nbytes);
+                data += str_nbytes;
+                sum_bytes += str_nbytes;
 
-		/* write extended opcode */
-		db = DW_LNE_set_address;
-		GET_CHUNK(dbg, elfsectno, data, upointer_size +
-			  sizeof(Dwarf_Ubyte), error);
-		WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
-				sizeof(db), sizeof(Dwarf_Ubyte));
-		data += sizeof(Dwarf_Ubyte);
-		sum_bytes += sizeof(Dwarf_Ubyte);
+                /* write extended opcode */
+                db = DW_LNE_set_address;
+                GET_CHUNK(dbg, elfsectno, data, upointer_size +
+                          sizeof(Dwarf_Ubyte), error);
+                WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+                                sizeof(db), sizeof(Dwarf_Ubyte));
+                data += sizeof(Dwarf_Ubyte);
+                sum_bytes += sizeof(Dwarf_Ubyte);
 
-		/* reloc for address */
-		res = dbg->de_reloc_name(dbg, DEBUG_LINE, sum_bytes,	/* r_offset 
-									 */
-					 curline->dpl_r_symidx,
-					 dwarf_drt_data_reloc,
-					 uwordb_size);
-		if (res != DW_DLV_OK) {
-		    DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
-		}
+                /* reloc for address */
+                res = dbg->de_reloc_name(dbg, DEBUG_LINE, 
+                    sum_bytes,  /* r_offset  */
+                    curline->dpl_r_symidx,
+                    dwarf_drt_data_reloc,
+                    uwordb_size);
+                if (res != DW_DLV_OK) {
+                    DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+                }
 
-		/* write offset (address) */
-		du = curline->dpl_address;
-		WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
-				sizeof(du), upointer_size);
-		data += upointer_size;
-		sum_bytes += upointer_size;
-		prevline->dpl_address = curline->dpl_address;
-		no_lns_copy = 1;
-		break;
-	    }
-	} else {
-	    if (curline->dpl_file != prevline->dpl_file) {
-		db = DW_LNS_set_file;
-		res =
-		    _dwarf_pro_encode_leb128_nm(curline->dpl_file,
-						&nbytes, buff1,
-						sizeof(buff1));
-		if (res != DW_DLV_OK) {
-		    DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
-		}
-		arg = buff1;
-		GET_CHUNK(dbg, elfsectno, data,
-			  nbytes + sizeof(Dwarf_Ubyte), error);
-		WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
-				sizeof(db), sizeof(Dwarf_Ubyte));
-		data += sizeof(Dwarf_Ubyte);
-		memcpy((void *) data, (const void *) arg, nbytes);
-		data += nbytes;
-		sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
-		prevline->dpl_file = curline->dpl_file;
-	    }
-	    if (curline->dpl_column != prevline->dpl_column) {
-		db = DW_LNS_set_column;
-		res = _dwarf_pro_encode_leb128_nm(curline->dpl_column,
-						  &nbytes,
-						  buff1, sizeof(buff1));
-		if (res != DW_DLV_OK) {
-		    DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
-		}
+                /* write offset (address) */
+                du = curline->dpl_address;
+                WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
+                                sizeof(du), upointer_size);
+                data += upointer_size;
+                sum_bytes += upointer_size;
+                prevline->dpl_address = curline->dpl_address;
+                no_lns_copy = 1;
+                break;
+            }
+        } else {
+            if (curline->dpl_file != prevline->dpl_file) {
+                db = DW_LNS_set_file;
+                res =
+                    _dwarf_pro_encode_leb128_nm(curline->dpl_file,
+                                                &nbytes, buff1,
+                                                sizeof(buff1));
+                if (res != DW_DLV_OK) {
+                    DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+                }
+                arg = buff1;
+                GET_CHUNK(dbg, elfsectno, data,
+                          nbytes + sizeof(Dwarf_Ubyte), error);
+                WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+                                sizeof(db), sizeof(Dwarf_Ubyte));
+                data += sizeof(Dwarf_Ubyte);
+                memcpy((void *) data, (const void *) arg, nbytes);
+                data += nbytes;
+                sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
+                prevline->dpl_file = curline->dpl_file;
+            }
+            if (curline->dpl_column != prevline->dpl_column) {
+                db = DW_LNS_set_column;
+                res = _dwarf_pro_encode_leb128_nm(curline->dpl_column,
+                                                  &nbytes,
+                                                  buff1, sizeof(buff1));
+                if (res != DW_DLV_OK) {
+                    DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+                }
 
-		arg = buff1;
-		GET_CHUNK(dbg, elfsectno, data,
-			  nbytes + sizeof(Dwarf_Ubyte), error);
-		WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
-				sizeof(db), sizeof(Dwarf_Ubyte));
-		data += sizeof(Dwarf_Ubyte);
-		memcpy((void *) data, (const void *) arg, nbytes);
-		data += nbytes;
-		sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
-		prevline->dpl_column = curline->dpl_column;
-	    }
-	    if (curline->dpl_is_stmt != prevline->dpl_is_stmt) {
-		db = DW_LNS_negate_stmt;
-		GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
-			  error);
-		WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
-				sizeof(db), sizeof(Dwarf_Ubyte));
-		data += sizeof(Dwarf_Ubyte);
-		sum_bytes += sizeof(Dwarf_Ubyte);
-		prevline->dpl_is_stmt = curline->dpl_is_stmt;
-	    }
-	    if (curline->dpl_basic_block == true &&
-		prevline->dpl_basic_block == false) {
-		db = DW_LNS_set_basic_block;
-		GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
-			  error);
-		WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
-				sizeof(db), sizeof(Dwarf_Ubyte));
-		data += sizeof(Dwarf_Ubyte);
-		sum_bytes += sizeof(Dwarf_Ubyte);
-		prevline->dpl_basic_block = curline->dpl_basic_block;
-	    }
-	    addr_adv = curline->dpl_address - prevline->dpl_address;
+                arg = buff1;
+                GET_CHUNK(dbg, elfsectno, data,
+                          nbytes + sizeof(Dwarf_Ubyte), error);
+                WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+                                sizeof(db), sizeof(Dwarf_Ubyte));
+                data += sizeof(Dwarf_Ubyte);
+                memcpy((void *) data, (const void *) arg, nbytes);
+                data += nbytes;
+                sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
+                prevline->dpl_column = curline->dpl_column;
+            }
+            if (curline->dpl_is_stmt != prevline->dpl_is_stmt) {
+                db = DW_LNS_negate_stmt;
+                GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
+                          error);
+                WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+                                sizeof(db), sizeof(Dwarf_Ubyte));
+                data += sizeof(Dwarf_Ubyte);
+                sum_bytes += sizeof(Dwarf_Ubyte);
+                prevline->dpl_is_stmt = curline->dpl_is_stmt;
+            }
+            if (curline->dpl_basic_block == true &&
+                prevline->dpl_basic_block == false) {
+                db = DW_LNS_set_basic_block;
+                GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
+                          error);
+                WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+                                sizeof(db), sizeof(Dwarf_Ubyte));
+                data += sizeof(Dwarf_Ubyte);
+                sum_bytes += sizeof(Dwarf_Ubyte);
+                prevline->dpl_basic_block = curline->dpl_basic_block;
+            }
+            addr_adv = curline->dpl_address - prevline->dpl_address;
 
-	    line_adv = (int) (curline->dpl_line - prevline->dpl_line);
-	    if ((addr_adv % MIN_INST_LENGTH) != 0) {
-		DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_ADDRESS, -1);
-	    }
-	    if ((opc = _dwarf_pro_get_opc(addr_adv, line_adv)) > 0) {
-		no_lns_copy = 1;
-		db = opc;
-		GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
-			  error);
-		WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
-				sizeof(db), sizeof(Dwarf_Ubyte));
-		data += sizeof(Dwarf_Ubyte);
-		sum_bytes += sizeof(Dwarf_Ubyte);
-		prevline->dpl_basic_block = false;
-		prevline->dpl_address = curline->dpl_address;
-		prevline->dpl_line = curline->dpl_line;
-	    } else {
-		if (addr_adv > 0) {
-		    db = DW_LNS_advance_pc;
-		    res =
-			_dwarf_pro_encode_leb128_nm(addr_adv /
-						    MIN_INST_LENGTH,
-						    &nbytes, buff1,
-						    sizeof(buff1));
-		    if (res != DW_DLV_OK) {
-			DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
-		    }
+            line_adv = (int) (curline->dpl_line - prevline->dpl_line);
+            if ((addr_adv % MIN_INST_LENGTH) != 0) {
+                DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_ADDRESS, -1);
+            }
+            if ((opc = _dwarf_pro_get_opc(addr_adv, line_adv)) > 0) {
+                no_lns_copy = 1;
+                db = opc;
+                GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
+                          error);
+                WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+                                sizeof(db), sizeof(Dwarf_Ubyte));
+                data += sizeof(Dwarf_Ubyte);
+                sum_bytes += sizeof(Dwarf_Ubyte);
+                prevline->dpl_basic_block = false;
+                prevline->dpl_address = curline->dpl_address;
+                prevline->dpl_line = curline->dpl_line;
+            } else {
+                if (addr_adv > 0) {
+                    db = DW_LNS_advance_pc;
+                    res =
+                        _dwarf_pro_encode_leb128_nm(addr_adv /
+                                                    MIN_INST_LENGTH,
+                                                    &nbytes, buff1,
+                                                    sizeof(buff1));
+                    if (res != DW_DLV_OK) {
+                        DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+                    }
 
-		    arg = buff1;
-		    GET_CHUNK(dbg, elfsectno, data,
-			      nbytes + sizeof(Dwarf_Ubyte), error);
-		    WRITE_UNALIGNED(dbg, (void *) data,
-				    (const void *) &db,
-				    sizeof(db), sizeof(Dwarf_Ubyte));
-		    data += sizeof(Dwarf_Ubyte);
-		    memcpy((void *) data, (const void *) arg, nbytes);
-		    data += nbytes + sizeof(Dwarf_Ubyte);
-		    sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
-		    prevline->dpl_basic_block = false;
-		    prevline->dpl_address = curline->dpl_address;
-		}
-		if (line_adv != 0) {
-		    db = DW_LNS_advance_line;
-		    res = _dwarf_pro_encode_signed_leb128_nm(line_adv,
-							     &nbytes,
-							     buff1,
-							     sizeof
-							     (buff1));
-		    if (res != DW_DLV_OK) {
-			DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
-		    }
+                    arg = buff1;
+                    GET_CHUNK(dbg, elfsectno, data,
+                              nbytes + sizeof(Dwarf_Ubyte), error);
+                    WRITE_UNALIGNED(dbg, (void *) data,
+                                    (const void *) &db,
+                                    sizeof(db), sizeof(Dwarf_Ubyte));
+                    data += sizeof(Dwarf_Ubyte);
+                    memcpy((void *) data, (const void *) arg, nbytes);
+                    data += nbytes + sizeof(Dwarf_Ubyte);
+                    sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
+                    prevline->dpl_basic_block = false;
+                    prevline->dpl_address = curline->dpl_address;
+                }
+                if (line_adv != 0) {
+                    db = DW_LNS_advance_line;
+                    res = _dwarf_pro_encode_signed_leb128_nm(line_adv,
+                                                             &nbytes,
+                                                             buff1,
+                                                             sizeof
+                                                             (buff1));
+                    if (res != DW_DLV_OK) {
+                        DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+                    }
 
-		    arg = buff1;
-		    GET_CHUNK(dbg, elfsectno, data,
-			      nbytes + sizeof(Dwarf_Ubyte), error);
-		    WRITE_UNALIGNED(dbg, (void *) data,
-				    (const void *) &db, sizeof(db),
-				    sizeof(Dwarf_Ubyte));
-		    data += sizeof(Dwarf_Ubyte);
-		    memcpy((void *) data, (const void *) arg, nbytes);
-		    data += nbytes + sizeof(Dwarf_Ubyte);
-		    sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
-		    prevline->dpl_basic_block = false;
-		    prevline->dpl_line = curline->dpl_line;
-		}
-	    }
-	}			/* ends else for opc != 0 */
-	if (no_lns_copy == 0) {	/* if not a special or dw_lne_end_seq
-				   generate a matrix line */
-	    db = DW_LNS_copy;
-	    GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), error);
-	    WRITE_UNALIGNED(dbg, (void *) data,
-			    (const void *) &db,
-			    sizeof(db), sizeof(Dwarf_Ubyte));
-	    data += sizeof(Dwarf_Ubyte);
-	    sum_bytes += sizeof(Dwarf_Ubyte);
-	    prevline->dpl_basic_block = false;
-	}
-	curline = curline->dpl_next;
+                    arg = buff1;
+                    GET_CHUNK(dbg, elfsectno, data,
+                              nbytes + sizeof(Dwarf_Ubyte), error);
+                    WRITE_UNALIGNED(dbg, (void *) data,
+                                    (const void *) &db, sizeof(db),
+                                    sizeof(Dwarf_Ubyte));
+                    data += sizeof(Dwarf_Ubyte);
+                    memcpy((void *) data, (const void *) arg, nbytes);
+                    data += nbytes + sizeof(Dwarf_Ubyte);
+                    sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
+                    prevline->dpl_basic_block = false;
+                    prevline->dpl_line = curline->dpl_line;
+                }
+            }
+        }                       /* ends else for opc != 0 */
+        if (no_lns_copy == 0) { /* if not a special or dw_lne_end_seq
+                                   generate a matrix line */
+            db = DW_LNS_copy;
+            GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), error);
+            WRITE_UNALIGNED(dbg, (void *) data,
+                            (const void *) &db,
+                            sizeof(db), sizeof(Dwarf_Ubyte));
+            data += sizeof(Dwarf_Ubyte);
+            sum_bytes += sizeof(Dwarf_Ubyte);
+            prevline->dpl_basic_block = false;
+        }
+        curline = curline->dpl_next;
     }
 
     /* write total length field */
-    du = sum_bytes - uwordb_size - extension_size;	/* subtract
-							   length field 
-							 */
+    du = sum_bytes - BEGIN_LEN_SIZE;
     {
-	start_line_sec += extension_size;
-	WRITE_UNALIGNED(dbg, (void *) start_line_sec,
-			(const void *) &du, sizeof(du), uwordb_size);
+        start_line_sec += extension_size;
+        WRITE_UNALIGNED(dbg, (void *) start_line_sec,
+                        (const void *) &du, sizeof(du), uwordb_size);
     }
 
     return (int) dbg->de_n_debug_sect;
 }
 
 /*---------------------------------------------------------------
-	Generate debug_frame section 
+        Generate debug_frame section 
 ---------------------------------------------------------------*/
 static int
 _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error)
 {
-    int elfsectno;
-    int i;
+    int elfsectno = 0;
+    int i = 0;
     int firsttime = 1;
-    int pad;			/* pad for padding to align cies and
-				   fdes */
-    Dwarf_P_Cie curcie;
-    Dwarf_P_Fde curfde;
-    unsigned char *data;
-    Dwarf_sfixed dsw;
-    Dwarf_Unsigned du;
-    Dwarf_Ubyte db;
-    long *cie_offs;		/* holds byte offsets for links to
-				   fde's */
-    unsigned long cie_length;
-    int cie_no;
+    int pad = 0;     /* Pad for padding to align cies and fdes */
+    Dwarf_P_Cie curcie = 0;
+    Dwarf_P_Fde curfde = 0;
+    unsigned char *data = 0;
+    Dwarf_sfixed dsw = 0;
+    Dwarf_Unsigned du = 0;
+    Dwarf_Ubyte db = 0;
+    long *cie_offs = 0;   /* Holds byte offsets for links to fde's */
+    unsigned long cie_length = 0;
+    int cie_no = 0;
     int uwordb_size = dbg->de_offset_size;
     int extension_size = dbg->de_64bit_extension ? 4 : 0;
     int upointer_size = dbg->de_pointer_size;
-    Dwarf_Unsigned cur_off;	/* current offset of written data,
-				   held for relocation info */
+    Dwarf_Unsigned cur_off = 0; /* current offset of written data, held 
+                                   for relocation info */
 
     elfsectno = dbg->de_elf_sects[DEBUG_FRAME];
 
@@ -905,457 +914,618 @@
     cie_length = 0;
     cur_off = 0;
     cie_offs = (long *)
-	_dwarf_p_get_alloc(dbg, sizeof(long) * dbg->de_n_cie);
+        _dwarf_p_get_alloc(dbg, sizeof(long) * dbg->de_n_cie);
     if (cie_offs == NULL) {
-	DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
     }
-    /* generate cie number as we go along */
+    /* Generate cie number as we go along.  This writes
+       all CIEs first before any FDEs, which is rather
+       different from the order a compiler might like (which
+       might be each CIE followed by its FDEs then the next CIE, and
+       so on). */
     cie_no = 1;
     while (curcie) {
-	char *code_al;
-	int c_bytes;
-	char *data_al;
-	int d_bytes;
-	int res;
-	char buff1[ENCODE_SPACE_NEEDED];
-	char buff2[ENCODE_SPACE_NEEDED];
-	char buff3[ENCODE_SPACE_NEEDED];
-	char *augmentation;
-	char *augmented_al;
-	long augmented_fields_length;
-	int a_bytes;
+        char *code_al = 0;
+        int c_bytes = 0;
+        char *data_al = 0;
+        int d_bytes = 0;
+        int res = 0;
+        char buff1[ENCODE_SPACE_NEEDED];
+        char buff2[ENCODE_SPACE_NEEDED];
+        char buff3[ENCODE_SPACE_NEEDED];
+        char *augmentation = 0;
+        char *augmented_al = 0;
+        long augmented_fields_length = 0;
+        int a_bytes = 0;
 
-	res = _dwarf_pro_encode_leb128_nm(curcie->cie_code_align,
-					  &c_bytes,
-					  buff1, sizeof(buff1));
-	if (res != DW_DLV_OK) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
-	}
-	/* Before April 1999, the following was using an unsigned
-	   encode. That worked ok even though the decoder used the
-	   correct signed leb read, but doing the encode correctly
-	   (according to the dwarf spec) saves space in the output file 
-	   and is completely compatible.
+        res = _dwarf_pro_encode_leb128_nm(curcie->cie_code_align,
+                                          &c_bytes,
+                                          buff1, sizeof(buff1));
+        if (res != DW_DLV_OK) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
+        }
+        /* Before April 1999, the following was using an unsigned
+           encode. That worked ok even though the decoder used the
+           correct signed leb read, but doing the encode correctly
+           (according to the dwarf spec) saves space in the output file 
+           and is completely compatible.
 
-	   Note the actual stored amount on MIPS was 10 bytes (!) to
-	   store the value -4. (hex)fc ffffffff ffffffff 01 The
-	   libdwarf consumer consumed all 10 bytes too!
+           Note the actual stored amount on MIPS was 10 bytes (!) to
+           store the value -4. (hex)fc ffffffff ffffffff 01 The
+           libdwarf consumer consumed all 10 bytes too!
 
-	   old version res =
-	   _dwarf_pro_encode_leb128_nm(curcie->cie_data_align,
+           old version res =
+           _dwarf_pro_encode_leb128_nm(curcie->cie_data_align,
 
-	   below is corrected signed version. */
-	res = _dwarf_pro_encode_signed_leb128_nm(curcie->cie_data_align,
-						 &d_bytes,
-						 buff2, sizeof(buff2));
-	if (res != DW_DLV_OK) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
-	}
-	code_al = buff1;
-	data_al = buff2;
+           below is corrected signed version. */
+        res = _dwarf_pro_encode_signed_leb128_nm(curcie->cie_data_align,
+                                                 &d_bytes,
+                                                 buff2, sizeof(buff2));
+        if (res != DW_DLV_OK) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
+        }
+        code_al = buff1;
+        data_al = buff2;
 
-	/* get the correct offset */
-	if (firsttime) {
-	    cie_offs[cie_no - 1] = 0;
-	    firsttime = 0;
-	} else {
-	    cie_offs[cie_no - 1] = cie_offs[cie_no - 2] +
-		(long) cie_length + uwordb_size + extension_size;
-	}
-	cie_no++;
-	augmentation = curcie->cie_aug;
-	if (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) {
-	    augmented_fields_length = 0;
-	    res = _dwarf_pro_encode_leb128_nm(augmented_fields_length,
-					      &a_bytes, buff3,
-					      sizeof(buff3));
-	    augmented_al = buff3;
-	    if (res != DW_DLV_OK) {
-		DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
-	    }
-	    cie_length = uwordb_size +	/* cie_id */
-		sizeof(Dwarf_Ubyte) +	/* cie version */
-		strlen(curcie->cie_aug) + 1 +	/* augmentation */
-		c_bytes +	/* code alignment factor */
-		d_bytes +	/* data alignment factor */
-		sizeof(Dwarf_Ubyte) +	/* return reg address */
-		a_bytes +	/* augmentation length */
-		curcie->cie_inst_bytes;
-	} else {
-	    cie_length = uwordb_size +	/* cie_id */
-		sizeof(Dwarf_Ubyte) +	/* cie version */
-		strlen(curcie->cie_aug) + 1 +	/* augmentation */
-		c_bytes + d_bytes + sizeof(Dwarf_Ubyte) +	/* return 
-								   reg
-								   address 
-								 */
-		curcie->cie_inst_bytes;
-	}
-	pad = (int) PADDING(cie_length, upointer_size);
-	cie_length += pad;
-	GET_CHUNK(dbg, elfsectno, data, cie_length + uwordb_size
-		  + extension_size, error);
-	if (extension_size) {
-	    Dwarf_Unsigned x = DISTINGUISHED_VALUE;
+        /* get the correct offset */
+        if (firsttime) {
+            cie_offs[cie_no - 1] = 0;
+            firsttime = 0;
+        } else {
+            cie_offs[cie_no - 1] = cie_offs[cie_no - 2] +
+                (long) cie_length + BEGIN_LEN_SIZE;
+        }
+        cie_no++;
+        augmentation = curcie->cie_aug;
+        if (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) {
+            augmented_fields_length = 0;
+            res = _dwarf_pro_encode_leb128_nm(augmented_fields_length,
+                                              &a_bytes, buff3,
+                                              sizeof(buff3));
+            augmented_al = buff3;
+            if (res != DW_DLV_OK) {
+                DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
+            }
+            cie_length = uwordb_size +  /* cie_id */
+                sizeof(Dwarf_Ubyte) +   /* cie version */
+                strlen(curcie->cie_aug) + 1 +   /* augmentation */
+                c_bytes +       /* code alignment factor */
+                d_bytes +       /* data alignment factor */
+                sizeof(Dwarf_Ubyte) +   /* return reg address */
+                a_bytes +       /* augmentation length */
+                curcie->cie_inst_bytes;
+        } else {
+            cie_length = uwordb_size +  /* cie_id */
+                sizeof(Dwarf_Ubyte) +   /* cie version */
+                strlen(curcie->cie_aug) + 1 +   /* augmentation */
+                c_bytes + d_bytes + sizeof(Dwarf_Ubyte) +       /* return 
+                                                                   reg
+                                                                   address 
+                                                                 */
+                curcie->cie_inst_bytes;
+        }
+        pad = (int) PADDING(cie_length, upointer_size);
+        cie_length += pad;
+        GET_CHUNK(dbg, elfsectno, data, cie_length +
+                  BEGIN_LEN_SIZE, error);
+        if (extension_size) {
+            Dwarf_Unsigned x = DISTINGUISHED_VALUE;
 
-	    WRITE_UNALIGNED(dbg, (void *) data,
-			    (const void *) &x,
-			    sizeof(x), extension_size);
-	    data += extension_size;
+            WRITE_UNALIGNED(dbg, (void *) data,
+                            (const void *) &x,
+                            sizeof(x), extension_size);
+            data += extension_size;
 
-	}
-	du = cie_length;
-	/* total length of cie */
-	WRITE_UNALIGNED(dbg, (void *) data,
-			(const void *) &du, sizeof(du), uwordb_size);
-	data += uwordb_size;
+        }
+        du = cie_length;
+        /* total length of cie */
+        WRITE_UNALIGNED(dbg, (void *) data,
+                        (const void *) &du, sizeof(du), uwordb_size);
+        data += uwordb_size;
 
-	/* cie-id is a special value. */
-	du = DW_CIE_ID;
-	WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
-			sizeof(du), uwordb_size);
-	data += uwordb_size;
+        /* cie-id is a special value. */
+        du = DW_CIE_ID;
+        WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
+                        sizeof(du), uwordb_size);
+        data += uwordb_size;
 
-	db = curcie->cie_version;
-	WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
-			sizeof(db), sizeof(Dwarf_Ubyte));
-	data += sizeof(Dwarf_Ubyte);
-	strcpy((char *) data, curcie->cie_aug);
-	data += strlen(curcie->cie_aug) + 1;
-	memcpy((void *) data, (const void *) code_al, c_bytes);
-	data += c_bytes;
-	memcpy((void *) data, (const void *) data_al, d_bytes);
-	data += d_bytes;
-	db = curcie->cie_ret_reg;
-	WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
-			sizeof(db), sizeof(Dwarf_Ubyte));
-	data += sizeof(Dwarf_Ubyte);
+        db = curcie->cie_version;
+        WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+                        sizeof(db), sizeof(Dwarf_Ubyte));
+        data += sizeof(Dwarf_Ubyte);
+        strcpy((char *) data, curcie->cie_aug);
+        data += strlen(curcie->cie_aug) + 1;
+        memcpy((void *) data, (const void *) code_al, c_bytes);
+        data += c_bytes;
+        memcpy((void *) data, (const void *) data_al, d_bytes);
+        data += d_bytes;
+        db = curcie->cie_ret_reg;
+        WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+                        sizeof(db), sizeof(Dwarf_Ubyte));
+        data += sizeof(Dwarf_Ubyte);
 
-	if (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) {
-	    memcpy((void *) data, (const void *) augmented_al, a_bytes);
-	    data += a_bytes;
-	}
-	memcpy((void *) data, (const void *) curcie->cie_inst,
-	       curcie->cie_inst_bytes);
-	data += curcie->cie_inst_bytes;
-	for (i = 0; i < pad; i++) {
-	    *data = DW_CFA_nop;
-	    data++;
-	}
-	curcie = curcie->cie_next;
+        if (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) {
+            memcpy((void *) data, (const void *) augmented_al, a_bytes);
+            data += a_bytes;
+        }
+        memcpy((void *) data, (const void *) curcie->cie_inst,
+               curcie->cie_inst_bytes);
+        data += curcie->cie_inst_bytes;
+        for (i = 0; i < pad; i++) {
+            *data = DW_CFA_nop;
+            data++;
+        }
+        curcie = curcie->cie_next;
     }
     /* calculate current offset */
-    cur_off = cie_offs[cie_no - 2] + cie_length + uwordb_size
-	+ extension_size;
+    cur_off = cie_offs[cie_no - 2] + cie_length + BEGIN_LEN_SIZE;
 
     /* write out fde's */
     curfde = dbg->de_frame_fdes;
     while (curfde) {
-	Dwarf_P_Frame_Pgm curinst;
-	long fde_length;
-	int pad;
-	Dwarf_P_Cie cie_ptr;
-	Dwarf_Word cie_index, index;
-	int oet_length, afl_length, res;
-	int v0_augmentation = 0;
-
+        Dwarf_P_Frame_Pgm curinst = 0;
+        long fde_length = 0;
+        int pad = 0;
+        Dwarf_P_Cie cie_ptr = 0;
+        Dwarf_Word cie_index = 0; 
+        Dwarf_Word index = 0;
+        int oet_length = 0;
+        int afl_length = 0; 
+        int res = 0;
+        int v0_augmentation = 0;
 #if 0
-	unsigned char *fde_start_point;
+        unsigned char *fde_start_point = 0;
 #endif
-
-	char afl_buff[ENCODE_SPACE_NEEDED];
+        char afl_buff[ENCODE_SPACE_NEEDED];
 
-	/* Find the CIE associated with this fde. */
-	cie_ptr = dbg->de_frame_cies;
-	cie_index = curfde->fde_cie;
-	index = 1;		/* The cie_index of the first cie is 1, 
-				   not 0. */
-	while (cie_ptr && index < cie_index) {
-	    cie_ptr = cie_ptr->cie_next;
-	    index++;
-	}
-	if (cie_ptr == NULL) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_NULL, -1);
-	}
+        /* Find the CIE associated with this fde. */
+        cie_ptr = dbg->de_frame_cies;
+        cie_index = curfde->fde_cie;
+        index = 1;              /* The cie_index of the first cie is 1, 
+                                   not 0. */
+        while (cie_ptr && index < cie_index) {
+            cie_ptr = cie_ptr->cie_next;
+            index++;
+        }
+        if (cie_ptr == NULL) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_NULL, -1);
+        }
 
-	if (strcmp(cie_ptr->cie_aug, DW_CIE_AUGMENTER_STRING_V0) == 0) {
-	    v0_augmentation = 1;
-	    oet_length = sizeof(Dwarf_sfixed);
-	    /* encode the length of augmented fields. */
-	    res = _dwarf_pro_encode_leb128_nm(oet_length,
-					      &afl_length, afl_buff,
-					      sizeof(afl_buff));
-	    if (res != DW_DLV_OK) {
-		DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
-	    }
+        if (strcmp(cie_ptr->cie_aug, DW_CIE_AUGMENTER_STRING_V0) == 0) {
+            v0_augmentation = 1;
+            oet_length = sizeof(Dwarf_sfixed);
+            /* encode the length of augmented fields. */
+            res = _dwarf_pro_encode_leb128_nm(oet_length,
+                                              &afl_length, afl_buff,
+                                              sizeof(afl_buff));
+            if (res != DW_DLV_OK) {
+                DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
+            }
 
-	    fde_length = curfde->fde_n_bytes + uwordb_size +	/* cie
-								   pointer 
-								 */
-		upointer_size +	/* initial loc */
-		upointer_size +	/* address range */
-		afl_length +	/* augmented field length */
-		oet_length;	/* exception_table offset */
-	} else {
-	    fde_length = curfde->fde_n_bytes + uwordb_size +	/* cie
-								   pointer 
-								 */
-		upointer_size +	/* initial loc */
-		upointer_size;	/* address range */
-	}
+            fde_length = curfde->fde_n_bytes + BEGIN_LEN_SIZE + /* cie
+                                                                   pointer 
+                                                                 */
+                upointer_size + /* initial loc */
+                upointer_size + /* address range */
+                afl_length +    /* augmented field length */
+                oet_length;     /* exception_table offset */
+        } else {
+            fde_length = curfde->fde_n_bytes + BEGIN_LEN_SIZE + /* cie
+                                                                   pointer 
+                                                                 */
+                upointer_size + /* initial loc */
+                upointer_size;  /* address range */
+        }
 
-	/* using fde offset, generate DW_AT_MIPS_fde attribute for the 
-	   die corresponding to this fde */
-	if (_dwarf_pro_add_AT_fde(dbg, curfde->fde_die, cur_off, error)
-	    < 0)
-	    return -1;
-
-	/* store relocation for cie pointer */
-	res = dbg->de_reloc_name(dbg, DEBUG_FRAME, cur_off + uwordb_size,	/* r_offset 
-										 */
-				 dbg->de_sect_name_idx[DEBUG_FRAME],
-				 dwarf_drt_data_reloc, uwordb_size);
-	if (res != DW_DLV_OK) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
-	}
+     
+        if (curfde->fde_die) {
+            /* IRIX/MIPS extension:
+               Using fde offset, generate DW_AT_MIPS_fde attribute for the
+               die corresponding to this fde.  */
+            if(_dwarf_pro_add_AT_fde(dbg, curfde->fde_die, cur_off,  
+                error) < 0) {
+                return -1;
+            }
+        }
 
-	/* store relocation information for initial location */
-	res = dbg->de_reloc_name(dbg, DEBUG_FRAME, cur_off + uwordb_size + upointer_size,	/* r_offset 
-												 */
-				 curfde->fde_r_symidx,
-				 dwarf_drt_data_reloc, upointer_size);
-	if (res != DW_DLV_OK) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
-	}
-	/* Store the relocation information for the
-	   offset_into_exception_info field, if the offset is valid (0 
-	   is a valid offset). */
-	if (v0_augmentation &&
-	    curfde->fde_offset_into_exception_tables >= 0) {
+        /* store relocation for cie pointer */
+        res = dbg->de_reloc_name(dbg, DEBUG_FRAME, cur_off +
+                                     BEGIN_LEN_SIZE /* r_offset */,
+                                 dbg->de_sect_name_idx[DEBUG_FRAME],
+                                 dwarf_drt_data_reloc, uwordb_size);
+        if (res != DW_DLV_OK) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+        }
 
-	    res = dbg->de_reloc_name(dbg, DEBUG_FRAME,
-				     /* r_offset, where in cie this
-				        field starts */
-				     cur_off + 2 * uwordb_size +
-				     2 * upointer_size + afl_length,
-				     curfde->fde_exception_table_symbol,
-				     dwarf_drt_segment_rel,
-				     sizeof(Dwarf_sfixed));
-	    if (res != DW_DLV_OK) {
-		DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
-	    }
-	}
+        /* store relocation information for initial location */
+        res = dbg->de_reloc_name(dbg, DEBUG_FRAME,
+                                 cur_off + BEGIN_LEN_SIZE +
+                                     upointer_size /* r_offset */,
+                                 curfde->fde_r_symidx,
+                                 dwarf_drt_data_reloc, upointer_size);
+        if (res != DW_DLV_OK) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+        }
+        /* Store the relocation information for the
+           offset_into_exception_info field, if the offset is valid (0
+           is a valid offset). */
+        if (v0_augmentation &&
+            curfde->fde_offset_into_exception_tables >= 0) {
 
-	/* adjust for padding */
-	pad = (int) PADDING(fde_length, upointer_size);
-	fde_length += pad;
+            res = dbg->de_reloc_name(dbg, DEBUG_FRAME,
+                                     /* r_offset, where in cie this
+                                        field starts */
+                                     cur_off + BEGIN_LEN_SIZE +
+                                         uwordb_size + 2 * upointer_size +
+                                         afl_length,
+                                     curfde->fde_exception_table_symbol,
+                                     dwarf_drt_segment_rel,
+                                     sizeof(Dwarf_sfixed));
+            if (res != DW_DLV_OK) {
+                DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+            }
+        }
+
+        /* adjust for padding */
+        pad = (int) PADDING(fde_length, upointer_size);
+        fde_length += pad;
 
 
-	/* write out fde */
-	GET_CHUNK(dbg, elfsectno, data, fde_length + uwordb_size +
-		  extension_size, error);
+        /* write out fde */
+        GET_CHUNK(dbg, elfsectno, data, fde_length + BEGIN_LEN_SIZE,
+                  error);
 #if 0
-	fde_start_point = data;
+        fde_start_point = data;
 #endif
-	du = fde_length;
-	{
-	    if (extension_size) {
-		Dwarf_Word x = DISTINGUISHED_VALUE;
+        du = fde_length;
+        {
+            if (extension_size) {
+                Dwarf_Word x = DISTINGUISHED_VALUE;
 
-		WRITE_UNALIGNED(dbg, (void *) data,
-				(const void *) &x,
-				sizeof(x), extension_size);
-		data += extension_size;
-	    }
-	    /* length */
-	    WRITE_UNALIGNED(dbg, (void *) data,
-			    (const void *) &du,
-			    sizeof(du), uwordb_size);
-	    data += uwordb_size;
+                WRITE_UNALIGNED(dbg, (void *) data,
+                                (const void *) &x,
+                                sizeof(x), extension_size);
+                data += extension_size;
+            }
+            /* length */
+            WRITE_UNALIGNED(dbg, (void *) data,
+                            (const void *) &du,
+                            sizeof(du), uwordb_size);
+            data += uwordb_size;
 
-	    /* offset to cie */
-	    du = cie_offs[curfde->fde_cie - 1];
-	    WRITE_UNALIGNED(dbg, (void *) data,
-			    (const void *) &du,
-			    sizeof(du), uwordb_size);
-	    data += uwordb_size;
+            /* offset to cie */
+            du = cie_offs[curfde->fde_cie - 1];
+            WRITE_UNALIGNED(dbg, (void *) data,
+                            (const void *) &du,
+                            sizeof(du), uwordb_size);
+            data += uwordb_size;
 
-	    du = curfde->fde_initloc;
-	    WRITE_UNALIGNED(dbg, (void *) data,
-			    (const void *) &du,
-			    sizeof(du), upointer_size);
-	    data += upointer_size;
+            du = curfde->fde_initloc;
+            WRITE_UNALIGNED(dbg, (void *) data,
+                            (const void *) &du,
+                            sizeof(du), upointer_size);
+            data += upointer_size;
 
-	    if (dbg->de_reloc_pair &&
-		curfde->fde_end_symbol != 0 &&
-		curfde->fde_addr_range == 0) {
-		/* symbolic reloc, need reloc for length What if we
-		   really know the length? If so, should use the other
-		   part of 'if'. */
-		Dwarf_Unsigned val;
+            if (dbg->de_reloc_pair &&
+                curfde->fde_end_symbol != 0 &&
+                curfde->fde_addr_range == 0) {
+                /* symbolic reloc, need reloc for length What if we
+                   really know the length? If so, should use the other
+                   part of 'if'. */
+                Dwarf_Unsigned val;
 
-		res = dbg->de_reloc_pair(dbg,
-					 /* DEBUG_ARANGES, */
-					 DEBUG_FRAME, cur_off + 2 * uwordb_size + upointer_size,	/* r_offset 
-													 */
-					 curfde->fde_r_symidx,
-					 curfde->fde_end_symbol,
-					 dwarf_drt_first_of_length_pair,
-					 upointer_size);
-		if (res != DW_DLV_OK) {
-		    {
-			_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-			return (0);
-		    }
-		}
+                res = dbg->de_reloc_pair(dbg,
+                                         /* DEBUG_ARANGES, */
+                                         DEBUG_FRAME, cur_off + 2 * uwordb_size + upointer_size,        /* r_offset 
+                                                                                                         */
+                                         curfde->fde_r_symidx,
+                                         curfde->fde_end_symbol,
+                                         dwarf_drt_first_of_length_pair,
+                                         upointer_size);
+                if (res != DW_DLV_OK) {
+                    {
+                        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+                        return (0);
+                    }
+                }
 
-		/* arrange pre-calc so assem text can do .word end -
-		   begin + val (gets val from stream) */
-		val = curfde->fde_end_symbol_offset -
-		    curfde->fde_initloc;
-		WRITE_UNALIGNED(dbg, data,
-				(const void *) &val,
-				sizeof(val), upointer_size);
-		data += upointer_size;
-	    } else {
+                /* arrange pre-calc so assem text can do .word end -
+                   begin + val (gets val from stream) */
+                val = curfde->fde_end_symbol_offset -
+                    curfde->fde_initloc;
+                WRITE_UNALIGNED(dbg, data,
+                                (const void *) &val,
+                                sizeof(val), upointer_size);
+                data += upointer_size;
+            } else {
 
-		du = curfde->fde_addr_range;
-		WRITE_UNALIGNED(dbg, (void *) data,
-				(const void *) &du,
-				sizeof(du), upointer_size);
-		data += upointer_size;
-	    }
-	}
+                du = curfde->fde_addr_range;
+                WRITE_UNALIGNED(dbg, (void *) data,
+                                (const void *) &du,
+                                sizeof(du), upointer_size);
+                data += upointer_size;
+            }
+        }
 
-	if (v0_augmentation) {
-	    /* write the encoded augmented field length. */
-	    memcpy((void *) data, (const void *) afl_buff, afl_length);
-	    data += afl_length;
-	    /* write the offset_into_exception_tables field. */
-	    dsw =
-		(Dwarf_sfixed) curfde->fde_offset_into_exception_tables;
-	    WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dsw,
-			    sizeof(dsw), sizeof(Dwarf_sfixed));
-	    data += sizeof(Dwarf_sfixed);
-	}
+        if (v0_augmentation) {
+            /* write the encoded augmented field length. */
+            memcpy((void *) data, (const void *) afl_buff, afl_length);
+            data += afl_length;
+            /* write the offset_into_exception_tables field. */
+            dsw =
+                (Dwarf_sfixed) curfde->fde_offset_into_exception_tables;
+            WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dsw,
+                            sizeof(dsw), sizeof(Dwarf_sfixed));
+            data += sizeof(Dwarf_sfixed);
+        }
 
-	curinst = curfde->fde_inst;
-	while (curinst) {
-	    db = curinst->dfp_opcode;
-	    WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
-			    sizeof(db), sizeof(Dwarf_Ubyte));
-	    data += sizeof(Dwarf_Ubyte);
+        curinst = curfde->fde_inst;
+        if(curfde->fde_block) {
+            unsigned long size = curfde->fde_inst_block_size;
+            memcpy((void *) data, (const void *) curfde->fde_block, size);
+            data += size;
+        } else {
+            while (curinst) {
+                db = curinst->dfp_opcode;
+                WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+                     sizeof(db), sizeof(Dwarf_Ubyte));
+                data += sizeof(Dwarf_Ubyte);
 #if 0
-	    if (curinst->dfp_sym_index) {
-		int res;
-
-		res = dbg->de_reloc_name(dbg,
-					 DEBUG_FRAME,
-					 (data - fde_start_point)
-					 + cur_off + uwordb_size,	/* r_offset 
-									 */
-					 curinst->dfp_sym_index,
-					 dwarf_drt_data_reloc,
-					 upointer_size);
-		if (res != DW_DLV_OK) {
-		    {
-			_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-			return (0);
-		    }
-		}
-	    }
+                if (curinst->dfp_sym_index) {
+                    int res = dbg->de_reloc_name(dbg,
+                        DEBUG_FRAME,
+                        /* r_offset = */
+                        (data - fde_start_point) + cur_off + uwordb_size, 
+                        curinst->dfp_sym_index,
+                        dwarf_drt_data_reloc,
+                        upointer_size);
+                    if (res != DW_DLV_OK) {
+                        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+                        return (0);
+                    }
+                }
 #endif
-	    memcpy((void *) data,
-		   (const void *) curinst->dfp_args,
-		   curinst->dfp_nbytes);
-	    data += curinst->dfp_nbytes;
-	    curinst = curinst->dfp_next;
-	}
-	/* padding */
-	for (i = 0; i < pad; i++) {
-	    *data = DW_CFA_nop;
-	    data++;
-	}
-	cur_off += fde_length + uwordb_size;
-	curfde = curfde->fde_next;
+                memcpy((void *) data,
+                   (const void *) curinst->dfp_args,
+                   curinst->dfp_nbytes);
+                data += curinst->dfp_nbytes;
+                curinst = curinst->dfp_next;
+            }
+        }
+        /* padding */
+        for (i = 0; i < pad; i++) {
+            *data = DW_CFA_nop;
+            data++;
+        }
+        cur_off += fde_length + uwordb_size;
+        curfde = curfde->fde_next;
     }
 
 
     return (int) dbg->de_n_debug_sect;
 }
 
+/*
+  These functions remember all the markers we see along
+  with the right offset in the .debug_info section so that
+  we can dump them all back to the user with the section info.
+*/
+
+static int
+marker_init(Dwarf_P_Debug dbg,
+            unsigned count)
+{
+    dbg->de_marker_n_alloc = count;
+    dbg->de_markers = NULL;
+    if (count > 0) {
+        dbg->de_markers = _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Marker_s) *
+                                             dbg->de_marker_n_alloc);
+        if (dbg->de_markers == NULL) {
+            dbg->de_marker_n_alloc = 0;
+            return -1;
+        }
+    }
+    return 0;
+}
+
+static int
+marker_add(Dwarf_P_Debug dbg,
+           Dwarf_Unsigned offset,
+           Dwarf_Unsigned marker)
+{
+    if (dbg->de_marker_n_alloc >= (dbg->de_marker_n_used + 1)) {
+        unsigned n = dbg->de_marker_n_used++;
+        dbg->de_markers[n].ma_offset = offset;
+        dbg->de_markers[n].ma_marker = marker;
+        return 0;
+    }
+
+    return -1;
+}
+
+Dwarf_Signed
+dwarf_get_die_markers(Dwarf_P_Debug dbg,
+                      Dwarf_P_Marker * marker_list, /* pointer to a pointer */
+                      Dwarf_Unsigned * marker_count,
+                      Dwarf_Error * error)
+{
+    if (marker_list == NULL || marker_count == NULL) {
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_BADADDR);
+    }
+    if (dbg->de_marker_n_used != dbg->de_marker_n_alloc) {
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_MAF, DW_DLV_BADADDR);
+    }
+    
+    *marker_list = dbg->de_markers;
+    *marker_count = dbg->de_marker_n_used;
+    return DW_DLV_OK;
+}
+
+/* These functions provide the offsets of DW_FORM_string
+   attributes in the section section_index. These information
+   will enable a producer app that is generating assembly 
+   text output to easily emit those attributes in ascii form 
+   without having to decode the byte stream.
+ */
+static int
+string_attr_init (Dwarf_P_Debug dbg, 
+                  Dwarf_Signed section_index,
+                  unsigned count)
+{
+    Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[section_index];
+    
+    sect_sa->sect_sa_n_alloc = count;
+    sect_sa->sect_sa_list = NULL;
+    if (count > 0) {
+        sect_sa->sect_sa_section_number = section_index;
+        sect_sa->sect_sa_list = _dwarf_p_get_alloc(dbg,
+                                                   sizeof(struct Dwarf_P_String_Attr_s)
+                                                   * sect_sa->sect_sa_n_alloc);
+        if (sect_sa->sect_sa_list == NULL) {
+            sect_sa->sect_sa_n_alloc = 0;
+            return -1;
+        }
+    }
+    return 0;
+}
+
+static int 
+string_attr_add (Dwarf_P_Debug dbg, 
+                 Dwarf_Signed section_index,
+                 Dwarf_Unsigned offset,
+                 Dwarf_P_Attribute attr)
+{
+    Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[section_index];
+    if (sect_sa->sect_sa_n_alloc >= (sect_sa->sect_sa_n_used + 1)) {
+        unsigned n = sect_sa->sect_sa_n_used++;
+        sect_sa->sect_sa_list[n].sa_offset = offset;
+        sect_sa->sect_sa_list[n].sa_nbytes = attr->ar_nbytes;
+        return 0;
+    }
+    
+    return -1;
+}
+
+int
+dwarf_get_string_attributes_count(Dwarf_P_Debug dbg,
+                                  Dwarf_Unsigned *
+                                  count_of_sa_sections,
+                                  int *drd_buffer_version,
+                                  Dwarf_Error *error)
+{
+    int i;
+    unsigned int count = 0;
+    
+    for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) {
+        if (dbg->de_sect_string_attr[i].sect_sa_n_used > 0) {
+            ++count;
+        }
+    }
+    *count_of_sa_sections = (Dwarf_Unsigned) count;
+    *drd_buffer_version = DWARF_DRD_BUFFER_VERSION;
+
+    return DW_DLV_OK;
+}
+
+int 
+dwarf_get_string_attributes_info(Dwarf_P_Debug dbg,
+                                 Dwarf_Signed *elf_section_index,
+                                 Dwarf_Unsigned *sect_sa_buffer_count,
+                                 Dwarf_P_String_Attr *sect_sa_buffer,
+                                 Dwarf_Error *error)
+{
+    int i;
+    int next = dbg->de_sect_sa_next_to_return;
+
+    for (i = next; i < NUM_DEBUG_SECTIONS; ++i) {
+        Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[i];        
+        if (sect_sa->sect_sa_n_used > 0) {
+            dbg->de_sect_sa_next_to_return = i + 1;
+            *elf_section_index = sect_sa->sect_sa_section_number;
+            *sect_sa_buffer_count = sect_sa->sect_sa_n_used;
+            *sect_sa_buffer = sect_sa->sect_sa_list;
+            return DW_DLV_OK;
+        }
+    }
+    return DW_DLV_NO_ENTRY;
+}
+
 
 
 /*---------------------------------------------------------------
-	Generate debug_info and debug_abbrev sections
+        Generate debug_info and debug_abbrev sections
 ---------------------------------------------------------------*/
 static int
 _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Error * error)
 {
-    int elfsectno_of_debug_info;
-    int abbrevsectno;
-    unsigned char *data;
-    int cu_header_size;
-    Dwarf_P_Abbrev curabbrev, abbrev_head, abbrev_tail;
-    Dwarf_P_Die curdie;
-    Dwarf_P_Die first_child;
-    Dwarf_Word dw;
-    Dwarf_Unsigned du;
-    Dwarf_Half dh;
-    Dwarf_Ubyte db;
-    Dwarf_Half version;		/* need 2 byte quantity */
-    Dwarf_Unsigned die_off;	/* offset of die in debug_info */
-    int n_abbrevs;
-    int res;
+    int elfsectno_of_debug_info = 0;
+    int abbrevsectno = 0;
+    unsigned char *data = 0;
+    int cu_header_size = 0;
+    Dwarf_P_Abbrev curabbrev = 0;
+    Dwarf_P_Abbrev abbrev_head = 0;
+    Dwarf_P_Abbrev abbrev_tail = 0;
+    Dwarf_P_Die curdie = 0;
+    Dwarf_P_Die first_child = 0;
+    Dwarf_Word dw = 0;
+    Dwarf_Unsigned du = 0;
+    Dwarf_Half dh = 0;
+    Dwarf_Ubyte db = 0;
+    Dwarf_Half version = 0;     /* Need 2 byte quantity. */
+    Dwarf_Unsigned die_off = 0; /* Offset of die in debug_info. */
+    int n_abbrevs = 0;
+    int res = 0;
+    unsigned marker_count = 0;
+    unsigned string_attr_count = 0;
+    unsigned string_attr_offset = 0;
 
-    Dwarf_Small *start_info_sec;
+    Dwarf_Small *start_info_sec = 0;
 
-    int uword_size = dbg->de_offset_size;
+    int uwordb_size = dbg->de_offset_size;
     int extension_size = dbg->de_64bit_extension ? 4 : 0;
 
     abbrev_head = abbrev_tail = NULL;
     elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO];
 
     /* write cu header */
-    cu_header_size = extension_size + uword_size +	/* length of
-							   info section 
-							 */
-	sizeof(Dwarf_Half) +	/* version stamp */
-	uword_size +		/* offset into abbrev table */
-	sizeof(Dwarf_Ubyte);	/* size of target address */
+    cu_header_size = BEGIN_LEN_SIZE + sizeof(Dwarf_Half) +      /* version 
+                                                                   stamp 
+                                                                 */
+        uwordb_size +           /* offset into abbrev table */
+        sizeof(Dwarf_Ubyte);    /* size of target address */
     GET_CHUNK(dbg, elfsectno_of_debug_info, data, cu_header_size,
-	      error);
+              error);
     start_info_sec = data;
     if (extension_size) {
-	du = DISTINGUISHED_VALUE;
-	WRITE_UNALIGNED(dbg, (void *) data,
-			(const void *) &du, sizeof(du), extension_size);
-	data += extension_size;
+        du = DISTINGUISHED_VALUE;
+        WRITE_UNALIGNED(dbg, (void *) data,
+                        (const void *) &du, sizeof(du), extension_size);
+        data += extension_size;
     }
-    du = 0;			/* length of debug_info, not counting
-				   this field itself (unknown at this
-				   point). */
+    du = 0;                     /* length of debug_info, not counting
+                                   this field itself (unknown at this
+                                   point). */
     WRITE_UNALIGNED(dbg, (void *) data,
-		    (const void *) &du, sizeof(du), uword_size);
-    data += uword_size;
+                    (const void *) &du, sizeof(du), uwordb_size);
+    data += uwordb_size;
 
-    version = CURRENT_VERSION_STAMP;	/* assume this length will not 
-					   change */
+    version = CURRENT_VERSION_STAMP;    /* assume this length will not
+                                           change */
     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &version,
-		    sizeof(version), sizeof(Dwarf_Half));
+                    sizeof(version), sizeof(Dwarf_Half));
     data += sizeof(Dwarf_Half);
 
-    du = 0;			/* offset into abbrev table, not yet
-				   known. */
+    du = 0;                     /* offset into abbrev table, not yet
+                                   known. */
     WRITE_UNALIGNED(dbg, (void *) data,
-		    (const void *) &du, sizeof(du), uword_size);
-    data += uword_size;
+                    (const void *) &du, sizeof(du), uwordb_size);
+    data += uwordb_size;
 
 
     db = dbg->de_pointer_size;
 
     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
-		    sizeof(db), 1);
+                    sizeof(db), 1);
 
     /* We have filled the chunk we got with GET_CHUNK. At this point we 
        no longer dare use "data" or "start_info_sec" as a pointer any
@@ -1366,350 +1536,442 @@
 
     /* create AT_macro_info if appropriate */
     if (dbg->de_first_macinfo != NULL) {
-	if (_dwarf_pro_add_AT_macro_info(dbg, curdie, 0, error) < 0)
-	    return -1;
+        if (_dwarf_pro_add_AT_macro_info(dbg, curdie, 0, error) < 0)
+            return -1;
     }
 
     /* create AT_stmt_list attribute if necessary */
     if (dwarf_need_debug_line_section(dbg) == TRUE)
-	if (_dwarf_pro_add_AT_stmt_list(dbg, curdie, error) < 0)
-	    return -1;
+        if (_dwarf_pro_add_AT_stmt_list(dbg, curdie, error) < 0)
+            return -1;
 
     die_off = cu_header_size;
 
     /* 
        Relocation for abbrev offset in cu header store relocation
        record in linked list */
-    res = dbg->de_reloc_name(dbg, DEBUG_INFO, extension_size + uword_size + sizeof(Dwarf_Half),	/* r_offset 
-												 */
-			     dbg->de_sect_name_idx[DEBUG_ABBREV],
-			     dwarf_drt_data_reloc, uword_size);
+    res = dbg->de_reloc_name(dbg, DEBUG_INFO, BEGIN_LEN_SIZE +
+                             sizeof(Dwarf_Half),
+                             /* r_offset */
+                             dbg->de_sect_name_idx[DEBUG_ABBREV],
+                             dwarf_drt_data_reloc, uwordb_size);
     if (res != DW_DLV_OK) {
-	DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
     }
 
     /* pass 0: only top level dies, add at_sibling attribute to those
        dies with children */
     first_child = curdie->di_child;
     while (first_child && first_child->di_right) {
-	if (first_child->di_child)
-	    dwarf_add_AT_reference(dbg,
-				   first_child,
-				   DW_AT_sibling,
-				   first_child->di_right, error);
-	first_child = first_child->di_right;
+        if (first_child->di_child)
+            dwarf_add_AT_reference(dbg,
+                                   first_child,
+                                   DW_AT_sibling,
+                                   first_child->di_right, error);
+        first_child = first_child->di_right;
     }
 
     /* pass 1: create abbrev info, get die offsets, calc relocations */
+    marker_count = 0;
+    string_attr_count = 0;
     while (curdie != NULL) {
-	int nbytes;
-	Dwarf_P_Attribute curattr;
-	char *space;
-	int res;
-	char buff1[ENCODE_SPACE_NEEDED];
+        int nbytes = 0;
+        Dwarf_P_Attribute curattr;
+        Dwarf_P_Attribute new_first_attr;
+        Dwarf_P_Attribute new_last_attr;
+        char *space = 0;
+        int res = 0;
+        char buff1[ENCODE_SPACE_NEEDED];
+        int i = 0;
+
+        curdie->di_offset = die_off;
+
+        if (curdie->di_marker != 0)
+            marker_count++;
+        
+        curabbrev = _dwarf_pro_getabbrev(curdie, abbrev_head);
+        if (curabbrev == NULL) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
+        }
+        if (abbrev_head == NULL) {
+            n_abbrevs = 1;
+            curabbrev->abb_idx = n_abbrevs;
+            abbrev_tail = abbrev_head = curabbrev;
+        } else {
+            /* check if its a new abbreviation, if yes, add to tail */
+            if (curabbrev->abb_idx == 0) {
+                n_abbrevs++;
+                curabbrev->abb_idx = n_abbrevs;
+                abbrev_tail->abb_next = curabbrev;
+                abbrev_tail = curabbrev;
+            }
+        }
+        res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx,
+                                          &nbytes,
+                                          buff1, sizeof(buff1));
+        if (res != DW_DLV_OK) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
+        }
+        space = _dwarf_p_get_alloc(dbg, nbytes);
+        if (space == NULL) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
+        }
+        memcpy(space, buff1, nbytes);
+        curdie->di_abbrev = space;
+        curdie->di_abbrev_nbytes = nbytes;
+        die_off += nbytes;
+
+        /* Resorting the attributes!! */
+        new_first_attr = new_last_attr = NULL;
+        curattr = curdie->di_attrs;
+        for (i = 0; i < (int)curabbrev->abb_n_attr; i++) {
+            Dwarf_P_Attribute ca;
+            Dwarf_P_Attribute cl;
+
+            /* The following should always find an attribute! */
+            for (ca = cl = curattr;
+                 ca && curabbrev->abb_attrs[i] != ca->ar_attribute;
+                 cl = ca, ca = ca->ar_next)
+            {
+            }
+
+            if (!ca) {
+                DWARF_P_DBG_ERROR(dbg,DW_DLE_ABBREV_ALLOC, -1);
+            }
+
+            /* Remove the attribute from the old list. */
+            if (ca == curattr) {
+                curattr = ca->ar_next;
+            } else {
+                cl->ar_next = ca->ar_next;
+            }
 
-	curdie->di_offset = die_off;
-	curabbrev = _dwarf_pro_getabbrev(curdie, abbrev_head);
-	if (curabbrev == NULL) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
-	}
-	if (abbrev_head == NULL) {
-	    n_abbrevs = 1;
-	    curabbrev->abb_idx = n_abbrevs;
-	    abbrev_tail = abbrev_head = curabbrev;
-	} else {
-	    /* check if its a new abbreviation, if yes, add to tail */
-	    if (curabbrev->abb_idx == 0) {
-		n_abbrevs++;
-		curabbrev->abb_idx = n_abbrevs;
-		abbrev_tail->abb_next = curabbrev;
-		abbrev_tail = curabbrev;
-	    }
-	}
-	res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx,
-					  &nbytes,
-					  buff1, sizeof(buff1));
-	if (res != DW_DLV_OK) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
-	}
-	space = _dwarf_p_get_alloc(dbg, nbytes);
-	if (space == NULL) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
-	}
-	memcpy(space, buff1, nbytes);
-	curdie->di_abbrev = space;
-	curdie->di_abbrev_nbytes = nbytes;
-	die_off += nbytes;
-	curattr = curdie->di_attrs;
-	while (curattr) {
-	    if (curattr->ar_rel_type != R_MIPS_NONE) {
-		switch (curattr->ar_attribute) {
-		case DW_AT_stmt_list:
-		    curattr->ar_rel_symidx =
-			dbg->de_sect_name_idx[DEBUG_LINE];
-		    break;
-		case DW_AT_MIPS_fde:
-		    curattr->ar_rel_symidx =
-			dbg->de_sect_name_idx[DEBUG_FRAME];
-		    break;
-		case DW_AT_macro_info:
-		    curattr->ar_rel_symidx =
-			dbg->de_sect_name_idx[DEBUG_MACINFO];
-		    break;
-		default:
-		    break;
-		}
-		res = dbg->de_reloc_name(dbg, DEBUG_INFO, die_off + curattr->ar_rel_offset,	/* r_offset 
-												 */
-					 curattr->ar_rel_symidx,
-					 dwarf_drt_data_reloc,
-					 curattr->ar_reloc_len);
+            ca->ar_next = NULL;
+                
+            /* Add the attribute to the new list. */
+            if (new_first_attr == NULL) {
+                new_first_attr = new_last_attr = ca;
+            } else {
+                new_last_attr->ar_next = ca;
+                new_last_attr = ca;
+            }
+        }
 
-		if (res != DW_DLV_OK) {
-		    DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
-		}
+        curdie->di_attrs = new_first_attr;
+            
+        curattr = curdie->di_attrs;
+        
+        while (curattr) {
+            if (curattr->ar_rel_type != R_MIPS_NONE) {
+                switch (curattr->ar_attribute) {
+                case DW_AT_stmt_list:
+                    curattr->ar_rel_symidx =
+                        dbg->de_sect_name_idx[DEBUG_LINE];
+                    break;
+                case DW_AT_MIPS_fde:
+                    curattr->ar_rel_symidx =
+                        dbg->de_sect_name_idx[DEBUG_FRAME];
+                    break;
+                case DW_AT_macro_info:
+                    curattr->ar_rel_symidx =
+                        dbg->de_sect_name_idx[DEBUG_MACINFO];
+                    break;
+                default:
+                    break;
+                }
+                res = dbg->de_reloc_name(dbg, DEBUG_INFO, die_off + curattr->ar_rel_offset,     /* r_offset 
+                                                                                                 */
+                                         curattr->ar_rel_symidx,
+                                         dwarf_drt_data_reloc,
+                                         curattr->ar_reloc_len);
+
+                if (res != DW_DLV_OK) {
+                    DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
+                }
 
-	    }
-	    die_off += curattr->ar_nbytes;
-	    curattr = curattr->ar_next;
-	}
-	/* depth first search */
-	if (curdie->di_child)
-	    curdie = curdie->di_child;
-	else {
-	    while (curdie != NULL && curdie->di_right == NULL) {
-		curdie = curdie->di_parent;
-		die_off++;	/* since we are writing a null die at
-				   the end of each sibling chain */
-	    }
-	    if (curdie != NULL)
-		curdie = curdie->di_right;
-	}
+            }
+            if (curattr->ar_attribute_form == DW_FORM_string) {
+                string_attr_count++;
+            }
+            die_off += curattr->ar_nbytes;
+            curattr = curattr->ar_next;
+        }
+        
+        /* depth first search */
+        if (curdie->di_child)
+            curdie = curdie->di_child;
+        else {
+            while (curdie != NULL && curdie->di_right == NULL) {
+                curdie = curdie->di_parent;
+                die_off++;      /* since we are writing a null die at
+                                   the end of each sibling chain */
+            }
+            if (curdie != NULL)
+                curdie = curdie->di_right;
+        }
+        
+    } /* end while (curdie != NULL) */
+
+    res = marker_init(dbg, marker_count);
+    if (res == -1) {
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);   
     }
-
+    res = string_attr_init(dbg, DEBUG_INFO, string_attr_count);
+    if (res == -1) {
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);   
+    } 
+    
     /* Pass 2: Write out the die information Here 'data' is a
        temporary, one block for each GET_CHUNK.  'data' is overused. */
     curdie = dbg->de_dies;
     while (curdie != NULL) {
-	Dwarf_P_Attribute curattr;
-
-	/* index to abbreviation table */
-	GET_CHUNK(dbg, elfsectno_of_debug_info,
-		  data, curdie->di_abbrev_nbytes, error);
-
-	memcpy((void *) data,
-	       (const void *) curdie->di_abbrev,
-	       curdie->di_abbrev_nbytes);
+        Dwarf_P_Attribute curattr;
 
-	/* Attribute values - need to fill in all form attributes */
-	curattr = curdie->di_attrs;
-	while (curattr) {
-	    GET_CHUNK(dbg, elfsectno_of_debug_info, data,
-		      (unsigned long) curattr->ar_nbytes, error);
-	    switch (curattr->ar_attribute_form) {
-	    case DW_FORM_ref1:
-		{
-		    if (curattr->ar_ref_die->di_offset >
-			(unsigned) 0xff) {
-			DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1);
-		    }
-		    db = curattr->ar_ref_die->di_offset;
-		    WRITE_UNALIGNED(dbg, (void *) data,
-				    (const void *) &db,
-				    sizeof(db), sizeof(Dwarf_Ubyte));
-		    break;
-		}
-	    case DW_FORM_ref2:
-		{
-		    if (curattr->ar_ref_die->di_offset >
-			(unsigned) 0xffff) {
-			DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1);
-		    }
-		    dh = curattr->ar_ref_die->di_offset;
-		    WRITE_UNALIGNED(dbg, (void *) data,
-				    (const void *) &dh,
-				    sizeof(dh), sizeof(Dwarf_Half));
-		    break;
-		}
-	    case DW_FORM_ref_addr:
-		{
-		    du = curattr->ar_ref_die->di_offset;
-		    {
-			/* ref to offset of die */
-			WRITE_UNALIGNED(dbg, (void *) data,
-					(const void *) &du,
-					sizeof(du), uword_size);
-		    }
-		    break;
+        if (curdie->di_marker != 0) {
+            res = marker_add(dbg, curdie->di_offset, curdie->di_marker);
+            if (res == -1) {
+                DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);   
+            }
+        }
+
+        /* index to abbreviation table */
+        GET_CHUNK(dbg, elfsectno_of_debug_info,
+                  data, curdie->di_abbrev_nbytes, error);
+
+        memcpy((void *) data,
+               (const void *) curdie->di_abbrev,
+               curdie->di_abbrev_nbytes);
 
-		}
-	    case DW_FORM_ref4:
-		{
-		    if (curattr->ar_ref_die->di_offset >
-			(unsigned) 0xffffffff) {
-			DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1);
-		    }
-		    dw = (Dwarf_Word) curattr->ar_ref_die->di_offset;
-		    WRITE_UNALIGNED(dbg, (void *) data,
-				    (const void *) &dw,
-				    sizeof(dw), sizeof(Dwarf_ufixed));
-		    break;
-		}
-	    case DW_FORM_ref8:
-		du = curattr->ar_ref_die->di_offset;
-		WRITE_UNALIGNED(dbg, (void *) data,
-				(const void *) &du,
-				sizeof(du), sizeof(Dwarf_Unsigned));
-		break;
-	    case DW_FORM_ref_udata:
-		{		/* unsigned leb128 offset */
-
-		    int nbytes;
-		    char buff1[ENCODE_SPACE_NEEDED];
+        /* Attribute values - need to fill in all form attributes */
+        curattr = curdie->di_attrs;
+        string_attr_offset = curdie->di_offset + curdie->di_abbrev_nbytes;
+        
+        while (curattr) {
+            GET_CHUNK(dbg, elfsectno_of_debug_info, data,
+                      (unsigned long) curattr->ar_nbytes, error);
+            switch (curattr->ar_attribute_form) {
+            case DW_FORM_ref1:
+                {
+                    if (curattr->ar_ref_die->di_offset >
+                        (unsigned) 0xff) {
+                        DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1);
+                    }
+                    db = curattr->ar_ref_die->di_offset;
+                    WRITE_UNALIGNED(dbg, (void *) data,
+                                    (const void *) &db,
+                                    sizeof(db), sizeof(Dwarf_Ubyte));
+                    break;
+                }
+            case DW_FORM_ref2:
+                {
+                    if (curattr->ar_ref_die->di_offset >
+                        (unsigned) 0xffff) {
+                        DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1);
+                    }
+                    dh = curattr->ar_ref_die->di_offset;
+                    WRITE_UNALIGNED(dbg, (void *) data,
+                                    (const void *) &dh,
+                                    sizeof(dh), sizeof(Dwarf_Half));
+                    break;
+                }
+            case DW_FORM_ref_addr:
+                {
+                    /* curattr->ar_ref_die == NULL!
+                     *
+                     * ref_addr doesn't take a CU-offset.
+                     * This is different than other refs.
+                     * This value will be set by the user of the
+                     * producer library using a relocation.
+                     * No need to set a value here.
+                     */
+#if 0               
+                    du = curattr->ar_ref_die->di_offset;
+                    {
+                        /* ref to offset of die */
+                        WRITE_UNALIGNED(dbg, (void *) data,
+                                        (const void *) &du,
+                                        sizeof(du), uwordb_size);
+                    }
+#endif          
+                    break;
 
-		    res =
-			_dwarf_pro_encode_leb128_nm(curattr->
-						    ar_ref_die->
-						    di_offset, &nbytes,
-						    buff1,
-						    sizeof(buff1));
-		    if (res != DW_DLV_OK) {
-			DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
-		    }
+                }
+            case DW_FORM_ref4:
+                {
+                    if (curattr->ar_ref_die->di_offset >
+                        (unsigned) 0xffffffff) {
+                        DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1);
+                    }
+                    dw = (Dwarf_Word) curattr->ar_ref_die->di_offset;
+                    WRITE_UNALIGNED(dbg, (void *) data,
+                                    (const void *) &dw,
+                                    sizeof(dw), sizeof(Dwarf_ufixed));
+                    break;
+                }
+            case DW_FORM_ref8:
+                du = curattr->ar_ref_die->di_offset;
+                WRITE_UNALIGNED(dbg, (void *) data,
+                                (const void *) &du,
+                                sizeof(du), sizeof(Dwarf_Unsigned));
+                break;
+            case DW_FORM_ref_udata:
+                {               /* unsigned leb128 offset */
+
+                    int nbytes;
+                    char buff1[ENCODE_SPACE_NEEDED];
 
-		    memcpy(data, buff1, nbytes);
-		    break;
-		}
-	    default:
-		memcpy((void *) data,
-		       (const void *) curattr->ar_data,
-		       curattr->ar_nbytes);
-		break;
-	    }
-	    curattr = curattr->ar_next;
-	}
+                    res =
+                        _dwarf_pro_encode_leb128_nm(curattr->
+                                                    ar_ref_die->
+                                                    di_offset, &nbytes,
+                                                    buff1,
+                                                    sizeof(buff1));
+                    if (res != DW_DLV_OK) {
+                        DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
+                    }
 
-	/* depth first search */
-	if (curdie->di_child)
-	    curdie = curdie->di_child;
-	else {
-	    while (curdie != NULL && curdie->di_right == NULL) {
-		GET_CHUNK(dbg, elfsectno_of_debug_info, data, 1, error);
-		*data = '\0';
-		curdie = curdie->di_parent;
-	    }
-	    if (curdie != NULL)
-		curdie = curdie->di_right;
-	}
-    }
+                    memcpy(data, buff1, nbytes);
+                    break;
+                }
+            default:
+                memcpy((void *) data,
+                       (const void *) curattr->ar_data,
+                       curattr->ar_nbytes);
+                break;
+            }
+            if (curattr->ar_attribute_form == DW_FORM_string) {
+                string_attr_add(dbg, DEBUG_INFO, string_attr_offset, curattr);
+            }
+            string_attr_offset += curattr->ar_nbytes;
+            curattr = curattr->ar_next;
+        }
+
+        /* depth first search */
+        if (curdie->di_child)
+            curdie = curdie->di_child;
+        else {
+            while (curdie != NULL && curdie->di_right == NULL) {
+                GET_CHUNK(dbg, elfsectno_of_debug_info, data, 1, error);
+                *data = '\0';
+                curdie = curdie->di_parent;
+            }
+            if (curdie != NULL)
+                curdie = curdie->di_right;
+        }
+    } /* end while (curdir != NULL) */
 
     /* Write out debug_info size */
     /* Dont include length field or extension bytes */
-    du = die_off - uword_size - extension_size;
+    du = die_off - BEGIN_LEN_SIZE;
     WRITE_UNALIGNED(dbg, (void *) (start_info_sec + extension_size),
-		    (const void *) &du, sizeof(du), uword_size);
+                    (const void *) &du, sizeof(du), uwordb_size);
 
 
-    data = 0;			/* Emphasise not usable now */
+    data = 0;                   /* Emphasise not usable now */
 
     /* Write out debug_abbrev section */
     abbrevsectno = dbg->de_elf_sects[DEBUG_ABBREV];
 
     curabbrev = abbrev_head;
     while (curabbrev) {
-	char *val;
-	int nbytes;
-	int idx;
-	int res;
-	char buff1[ENCODE_SPACE_NEEDED];
+        char *val;
+        int nbytes;
+        int idx;
+        int res;
+        char buff1[ENCODE_SPACE_NEEDED];
 
-	res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx, &nbytes,
-					  buff1, sizeof(buff1));
-	if (res != DW_DLV_OK) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
-	}
+        res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx, &nbytes,
+                                          buff1, sizeof(buff1));
+        if (res != DW_DLV_OK) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
+        }
 
-	GET_CHUNK(dbg, abbrevsectno, data, nbytes, error);
-	val = buff1;
-	memcpy((void *) data, (const void *) val, nbytes);
-	res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_tag, &nbytes,
-					  buff1, sizeof(buff1));
-	if (res != DW_DLV_OK) {
-	    DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
-	}
-	val = buff1;
-	GET_CHUNK(dbg, abbrevsectno, data, nbytes, error);
-	memcpy((void *) data, (const void *) val, nbytes);
-	db = curabbrev->abb_children;
-	GET_CHUNK(dbg, abbrevsectno, data, sizeof(Dwarf_Ubyte), error);
-	WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
-			sizeof(db), sizeof(Dwarf_Ubyte));
+        GET_CHUNK(dbg, abbrevsectno, data, nbytes, error);
+        val = buff1;
+        memcpy((void *) data, (const void *) val, nbytes);
+        res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_tag, &nbytes,
+                                          buff1, sizeof(buff1));
+        if (res != DW_DLV_OK) {
+            DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
+        }
+        val = buff1;
+        GET_CHUNK(dbg, abbrevsectno, data, nbytes, error);
+        memcpy((void *) data, (const void *) val, nbytes);
+        db = curabbrev->abb_children;
+        GET_CHUNK(dbg, abbrevsectno, data, sizeof(Dwarf_Ubyte), error);
+        WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+                        sizeof(db), sizeof(Dwarf_Ubyte));
 
-	/* add attributes and forms */
-	for (idx = 0; idx < curabbrev->abb_n_attr; idx++) {
-	    res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_attrs[idx],
-					      &nbytes,
-					      buff1, sizeof(buff1));
-	    if (res != DW_DLV_OK) {
-		DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
-	    }
-	    val = buff1;
-	    GET_CHUNK(dbg, abbrevsectno, data, nbytes, error);
-	    memcpy((void *) data, (const void *) val, nbytes);
-	    res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_forms[idx],
-					      &nbytes,
-					      buff1, sizeof(buff1));
-	    if (res != DW_DLV_OK) {
-		DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
-	    }
-	    val = buff1;
-	    GET_CHUNK(dbg, abbrevsectno, data, nbytes, error);
-	    memcpy((void *) data, (const void *) val, nbytes);
-	}
-	GET_CHUNK(dbg, abbrevsectno, data, 2, error);	/* two zeros,
-			for last
-			entry, see dwarf2 sec 7.5.3 */
-	*data = 0;
-	data++;
-	*data = 0;
+        /* add attributes and forms */
+        for (idx = 0; idx < curabbrev->abb_n_attr; idx++) {
+            res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_attrs[idx],
+                                              &nbytes,
+                                              buff1, sizeof(buff1));
+            if (res != DW_DLV_OK) {
+                DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
+            }
+            val = buff1;
+            GET_CHUNK(dbg, abbrevsectno, data, nbytes, error);
+            memcpy((void *) data, (const void *) val, nbytes);
+            res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_forms[idx],
+                                              &nbytes,
+                                              buff1, sizeof(buff1));
+            if (res != DW_DLV_OK) {
+                DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
+            }
+            val = buff1;
+            GET_CHUNK(dbg, abbrevsectno, data, nbytes, error);
+            memcpy((void *) data, (const void *) val, nbytes);
+        }
+        GET_CHUNK(dbg, abbrevsectno, data, 2, error);   /* two zeros,
+                                                           for last
+                                                           entry, see
+                                                           dwarf2 sec
+                                                           7.5.3 */
+        *data = 0;
+        data++;
+        *data = 0;
 
-	curabbrev = curabbrev->abb_next;
+        curabbrev = curabbrev->abb_next;
     }
 
-    GET_CHUNK(dbg,abbrevsectno,data,1,error);       /* one zero, 
-                        for end of cu, see dwarf2 sec 7.5.3 */
+    GET_CHUNK(dbg, abbrevsectno, data, 1, error);       /* one zero,
+                                                           for end of
+                                                           cu, see
+                                                           dwarf2 sec
+                                                           7.5.3 */
     *data = 0;
-  
+
 
     return (int) dbg->de_n_debug_sect;
 }
 
 
 /*---------------------------------------------------------------------
-	Get a buffer of section data. 
-	section_idx is the elf-section number that this data applies to. 
-	length shows length of returned data 
+        Get a buffer of section data. 
+        section_idx is the elf-section number that this data applies to. 
+        length shows length of returned data 
 ----------------------------------------------------------------------*/
- /*ARGSUSED*/			/* pretend all args used */
+ /*ARGSUSED*/                   /* pretend all args used */
     Dwarf_Ptr
 dwarf_get_section_bytes(Dwarf_P_Debug dbg,
-			Dwarf_Signed dwarf_section,
-			Dwarf_Signed * section_idx,
-			Dwarf_Unsigned * length, Dwarf_Error * error)
+                        Dwarf_Signed dwarf_section,
+                        Dwarf_Signed * section_idx,
+                        Dwarf_Unsigned * length, Dwarf_Error * error)
 {
     Dwarf_Ptr buf;
 
     if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) {
-	DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, NULL);
+        DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, NULL);
     }
 
     if (dbg->de_debug_sects == 0) {
-	/* no more data !! */
-	return NULL;
+        /* no more data !! */
+        return NULL;
     }
     if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) {
-	/* no data ever entered !! */
-	return NULL;
+        /* no data ever entered !! */
+        return NULL;
     }
     *section_idx = dbg->de_debug_sects->ds_elf_sect_no;
     *length = dbg->de_debug_sects->ds_nbytes;
@@ -1725,7 +1987,7 @@
 }
 
 /*
-	No errors possible.
+        No errors possible.
 */
 void
 dwarf_reset_section_bytes(Dwarf_P_Debug dbg)
@@ -1734,6 +1996,7 @@
     /* No need to reset; commented out decrement. dbg->de_n_debug_sect
        = ???; */
     dbg->de_reloc_next_to_return = 0;
+    dbg->de_sect_sa_next_to_return = 0;
 }
 
 /*
@@ -1751,7 +2014,7 @@
 */
 Dwarf_Small *
 _dwarf_pro_buffer(Dwarf_P_Debug dbg,
-		  int elfsectno, unsigned long nbytes)
+                  int elfsectno, unsigned long nbytes)
 {
     Dwarf_P_Section_Data cursect;
 
@@ -1761,74 +2024,74 @@
        not match any legit section number. test to have just two
        clauses (no NULL pointer test) See dwarf_producer_init(). */
     if ((cursect->ds_elf_sect_no != elfsectno) ||
-	((cursect->ds_nbytes + nbytes) > cursect->ds_orig_alloc)
-	) {
+        ((cursect->ds_nbytes + nbytes) > cursect->ds_orig_alloc)
+        ) {
 
-	/* Either the elf section has changed or there is not enough
-	   space in the current section.
+        /* Either the elf section has changed or there is not enough
+           space in the current section.
 
-	   Create a new Dwarf_P_Section_Data_s for the chunk. and have
-	   space 'on the end' for the buffer itself so we just do one
-	   malloc (not two).
+           Create a new Dwarf_P_Section_Data_s for the chunk. and have
+           space 'on the end' for the buffer itself so we just do one
+           malloc (not two).
 
-	 */
-	unsigned long space = nbytes;
+         */
+        unsigned long space = nbytes;
 
-	if (nbytes < CHUNK_SIZE)
-	    space = CHUNK_SIZE;
+        if (nbytes < CHUNK_SIZE)
+            space = CHUNK_SIZE;
 
-	cursect = (Dwarf_P_Section_Data)
-	    _dwarf_p_get_alloc(dbg,
-			       sizeof(struct Dwarf_P_Section_Data_s)
-			       + space);
+        cursect = (Dwarf_P_Section_Data)
+            _dwarf_p_get_alloc(dbg,
+                               sizeof(struct Dwarf_P_Section_Data_s)
+                               + space);
 
 
-	if (cursect == NULL)
-	    return (NULL);
+        if (cursect == NULL)
+            return (NULL);
 
-	/* _dwarf_p_get_alloc zeroes the space... */
+        /* _dwarf_p_get_alloc zeroes the space... */
 
-	cursect->ds_data = (char *) cursect +
-	    sizeof(struct Dwarf_P_Section_Data_s);
-	cursect->ds_orig_alloc = space;
-	cursect->ds_elf_sect_no = elfsectno;
-	cursect->ds_nbytes = nbytes;	/* reserve this number of bytes 
-					   of space for caller to fill
-					   in */
+        cursect->ds_data = (char *) cursect +
+            sizeof(struct Dwarf_P_Section_Data_s);
+        cursect->ds_orig_alloc = space;
+        cursect->ds_elf_sect_no = elfsectno;
+        cursect->ds_nbytes = nbytes;    /* reserve this number of bytes 
+                                           of space for caller to fill
+                                           in */
 
-	/* Now link on the end of the list, and mark this one as the
-	   current one */
+        /* Now link on the end of the list, and mark this one as the
+           current one */
 
-	if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) {
-	    /* the only entry is the special one for 'no entry' so
-	       delete that phony one while adding this initial real
-	       one. */
-	    dbg->de_debug_sects = cursect;
-	    dbg->de_current_active_section = cursect;
-	    dbg->de_first_debug_sect = cursect;
-	} else {
-	    dbg->de_current_active_section->ds_next = cursect;
-	    dbg->de_current_active_section = cursect;
-	}
-	dbg->de_n_debug_sect++;
+        if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) {
+            /* the only entry is the special one for 'no entry' so
+               delete that phony one while adding this initial real
+               one. */
+            dbg->de_debug_sects = cursect;
+            dbg->de_current_active_section = cursect;
+            dbg->de_first_debug_sect = cursect;
+        } else {
+            dbg->de_current_active_section->ds_next = cursect;
+            dbg->de_current_active_section = cursect;
+        }
+        dbg->de_n_debug_sect++;
 
-	return ((Dwarf_Small *) cursect->ds_data);
+        return ((Dwarf_Small *) cursect->ds_data);
     }
 
     /* There is enough space in the current buffer */
     {
-	Dwarf_Small *space_for_caller = (Dwarf_Small *)
-	    (cursect->ds_data + cursect->ds_nbytes);
+        Dwarf_Small *space_for_caller = (Dwarf_Small *)
+            (cursect->ds_data + cursect->ds_nbytes);
 
-	cursect->ds_nbytes += nbytes;
-	return space_for_caller;
+        cursect->ds_nbytes += nbytes;
+        return space_for_caller;
     }
 }
 
 
 /*------------------------------------------------------------
-	Given address advance and line advance, it gives 
-	either special opcode, or a number < 0
+        Given address advance and line advance, it gives 
+        either special opcode, or a number < 0
 ------------------------------------------------------------*/
 static int
 _dwarf_pro_get_opc(Dwarf_Unsigned addr_adv, int line_adv)
@@ -1837,25 +2100,25 @@
 
     addr_adv = addr_adv / MIN_INST_LENGTH;
     if (line_adv == 0 && addr_adv == 0)
-	return OPC_INCS_ZERO;
+        return OPC_INCS_ZERO;
     if (line_adv >= LINE_BASE && line_adv < LINE_BASE + LINE_RANGE) {
-	opc =
-	    (line_adv - LINE_BASE) + (addr_adv * LINE_RANGE) +
-	    OPCODE_BASE;
-	if (opc > 255)
-	    return OPC_OUT_OF_RANGE;
-	return opc;
+        opc =
+            (line_adv - LINE_BASE) + (addr_adv * LINE_RANGE) +
+            OPCODE_BASE;
+        if (opc > 255)
+            return OPC_OUT_OF_RANGE;
+        return opc;
     } else
-	return LINE_OUT_OF_RANGE;
+        return LINE_OUT_OF_RANGE;
 }
 
 /*-----------------------------------------------------------------------
-	Handles abbreviations. It takes a die, searches through 
-	current list of abbreviations for matching one. If it
-	finds one, it returns a pointer to it, and if it doesnt, 
-	it returns a new one. Upto the user of this function to 
-	link it up to the abbreviation head. If its a new one,
-	abb_idx has 0.
+        Handles abbreviations. It takes a die, searches through 
+        current list of abbreviations for matching one. If it
+        finds one, it returns a pointer to it, and if it doesnt, 
+        it returns a new one. Upto the user of this function to 
+        link it up to the abbreviation head. If its a new one,
+        abb_idx has 0.
 -----------------------------------------------------------------------*/
 static Dwarf_P_Abbrev
 _dwarf_pro_getabbrev(Dwarf_P_Die die, Dwarf_P_Abbrev head)
@@ -1870,62 +2133,62 @@
 
     curabbrev = head;
     while (curabbrev) {
-	if ((die->di_tag == curabbrev->abb_tag) &&
-	    ((die->di_child != NULL &&
-	      curabbrev->abb_children == DW_CHILDREN_yes) ||
-	     (die->di_child == NULL &&
-	      curabbrev->abb_children == DW_CHILDREN_no)) &&
-	    (die->di_n_attr == curabbrev->abb_n_attr)) {
+        if ((die->di_tag == curabbrev->abb_tag) &&
+            ((die->di_child != NULL &&
+              curabbrev->abb_children == DW_CHILDREN_yes) ||
+             (die->di_child == NULL &&
+              curabbrev->abb_children == DW_CHILDREN_no)) &&
+            (die->di_n_attr == curabbrev->abb_n_attr)) {
 
-	    /* There is a chance of a match. */
-	    curattr = die->di_attrs;
-	    match = 1;		/* Assume match found. */
-	    while (match && curattr) {
-		res1 = _dwarf_pro_match_attr(curattr,
-					     curabbrev,
-					     (int) curabbrev->
-					     abb_n_attr);
-		if (res1 == 0)
-		    match = 0;
-		curattr = curattr->ar_next;
-	    }
-	    if (match == 1)
-		return curabbrev;
-	}
-	curabbrev = curabbrev->abb_next;
+            /* There is a chance of a match. */
+            curattr = die->di_attrs;
+            match = 1;          /* Assume match found. */
+            while (match && curattr) {
+                res1 = _dwarf_pro_match_attr(curattr,
+                                             curabbrev,
+                                             (int) curabbrev->
+                                             abb_n_attr);
+                if (res1 == 0)
+                    match = 0;
+                curattr = curattr->ar_next;
+            }
+            if (match == 1)
+                return curabbrev;
+        }
+        curabbrev = curabbrev->abb_next;
     }
 
     /* no match, create new abbreviation */
     if (die->di_n_attr != 0) {
-	forms = (Dwarf_ufixed *)
-	    _dwarf_p_get_alloc(NULL,
-			       sizeof(Dwarf_ufixed) * die->di_n_attr);
-	if (forms == NULL)
-	    return NULL;
-	attrs = (Dwarf_ufixed *)
-	    _dwarf_p_get_alloc(NULL,
-			       sizeof(Dwarf_ufixed) * die->di_n_attr);
-	if (attrs == NULL)
-	    return NULL;
+        forms = (Dwarf_ufixed *)
+            _dwarf_p_get_alloc(die->di_dbg,
+                               sizeof(Dwarf_ufixed) * die->di_n_attr);
+        if (forms == NULL)
+            return NULL;
+        attrs = (Dwarf_ufixed *)
+            _dwarf_p_get_alloc(die->di_dbg,
+                               sizeof(Dwarf_ufixed) * die->di_n_attr);
+        if (attrs == NULL)
+            return NULL;
     }
     nattrs = 0;
     curattr = die->di_attrs;
     while (curattr) {
-	attrs[nattrs] = curattr->ar_attribute;
-	forms[nattrs] = curattr->ar_attribute_form;
-	nattrs++;
-	curattr = curattr->ar_next;
+        attrs[nattrs] = curattr->ar_attribute;
+        forms[nattrs] = curattr->ar_attribute_form;
+        nattrs++;
+        curattr = curattr->ar_next;
     }
 
     curabbrev = (Dwarf_P_Abbrev)
-	_dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Abbrev_s));
+        _dwarf_p_get_alloc(die->di_dbg, sizeof(struct Dwarf_P_Abbrev_s));
     if (curabbrev == NULL)
-	return NULL;
+        return NULL;
 
     if (die->di_child == NULL)
-	curabbrev->abb_children = DW_CHILDREN_no;
+        curabbrev->abb_children = DW_CHILDREN_no;
     else
-	curabbrev->abb_children = DW_CHILDREN_yes;
+        curabbrev->abb_children = DW_CHILDREN_yes;
     curabbrev->abb_tag = die->di_tag;
     curabbrev->abb_attrs = attrs;
     curabbrev->abb_forms = forms;
@@ -1937,22 +2200,22 @@
 }
 
 /*------------------------------------------------------------------
-	Tries to see if given attribute and form combination 
-	exists in the given abbreviation
+        Tries to see if given attribute and form combination 
+        exists in the given abbreviation
 -------------------------------------------------------------------*/
 static int
 _dwarf_pro_match_attr(Dwarf_P_Attribute attr,
-		      Dwarf_P_Abbrev abbrev, int no_attr)
+                      Dwarf_P_Abbrev abbrev, int no_attr)
 {
     int i;
     int found = 0;
 
     for (i = 0; i < no_attr; i++) {
-	if (attr->ar_attribute == abbrev->abb_attrs[i] &&
-	    attr->ar_attribute_form == abbrev->abb_forms[i]) {
-	    found = 1;
-	    break;
-	}
+        if (attr->ar_attribute == abbrev->abb_attrs[i] &&
+            attr->ar_attribute_form == abbrev->abb_forms[i]) {
+            found = 1;
+            break;
+        }
     }
     return found;
 }
--- a/usr/src/tools/ctf/dwarf/common/pro_section.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_section.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
--- a/usr/src/tools/ctf/dwarf/common/pro_types.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_types.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +19,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -53,12 +53,12 @@
 */
 Dwarf_Unsigned
 dwarf_add_typename(Dwarf_P_Debug dbg,
-		   Dwarf_P_Die die,
-		   char *type_name, Dwarf_Error * error)
+                   Dwarf_P_Die die,
+                   char *type_name, Dwarf_Error * error)
 {
     return
-	_dwarf_add_simple_name_entry(dbg, die, type_name,
-				     dwarf_snk_typename, error);
+        _dwarf_add_simple_name_entry(dbg, die, type_name,
+                                     dwarf_snk_typename, error);
 }
 
 /*
@@ -70,10 +70,10 @@
 */
 Dwarf_Unsigned
 _dwarf_add_simple_name_entry(Dwarf_P_Debug dbg,
-			     Dwarf_P_Die die,
-			     char *entry_name,
-			     enum dwarf_sn_kind entrykind,
-			     Dwarf_Error * error)
+                             Dwarf_P_Die die,
+                             char *entry_name,
+                             enum dwarf_sn_kind entrykind,
+                             Dwarf_Error * error)
 {
     Dwarf_P_Simple_nameentry nameentry;
     Dwarf_P_Simple_name_header hdr;
@@ -81,28 +81,28 @@
     int uword_size;
 
     if (dbg == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
-	return (0);
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return (0);
     }
 
     if (die == NULL) {
-	_dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
-	return (0);
+        _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
+        return (0);
     }
 
 
     nameentry = (Dwarf_P_Simple_nameentry)
-	_dwarf_p_get_alloc(dbg,
-			   sizeof(struct Dwarf_P_Simple_nameentry_s));
+        _dwarf_p_get_alloc(dbg,
+                           sizeof(struct Dwarf_P_Simple_nameentry_s));
     if (nameentry == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (0);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (0);
     }
 
     name = _dwarf_p_get_alloc(dbg, strlen(entry_name) + 1);
     if (name == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (0);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (0);
     }
     strcpy(name, entry_name);
 
@@ -113,10 +113,10 @@
 
     hdr = &dbg->de_simple_name_headers[entrykind];
     if (hdr->sn_head == NULL)
-	hdr->sn_head = hdr->sn_tail = nameentry;
+        hdr->sn_head = hdr->sn_tail = nameentry;
     else {
-	hdr->sn_tail->sne_next = nameentry;
-	hdr->sn_tail = nameentry;
+        hdr->sn_tail->sne_next = nameentry;
+        hdr->sn_tail = nameentry;
     }
     hdr->sn_count++;
     hdr->sn_net_len += uword_size + nameentry->sne_name_len + 1;
@@ -134,15 +134,16 @@
      ".rel.debug_varnames",        sgi extension
      ".rel.debug_weaknames",       sgi extension 
      to disk.
-	section_index indexes one of those sections.
-	entrykind is one of those 'kind's.
+        section_index indexes one of those sections.
+        entrykind is one of those 'kind's.
 
 */
 int
-_dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, 
-		enum dwarf_sn_kind entrykind, 
-		int section_index,	/* in de_elf_sects etc */
-		Dwarf_Error * error)
+_dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, enum dwarf_sn_kind entrykind, int section_index, /* in 
+                                                                                                           de_elf_sects 
+                                                                                                           etc 
+                                                                                                         */
+                                    Dwarf_Error * error)
 {
 
 
@@ -159,8 +160,8 @@
     Dwarf_Small *stream_bytes;
     Dwarf_Small *cur_stream_bytes_ptr;
     Dwarf_Unsigned stream_bytes_count;
-    Dwarf_Unsigned adjusted_length;	/* count excluding length
-					   field */
+    Dwarf_Unsigned adjusted_length;     /* count excluding length field 
+                                         */
 
 
     int uword_size = dbg->de_offset_size;
@@ -173,24 +174,23 @@
 
     debug_info_size = 0;
     for (debug_sect = dbg->de_debug_sects; debug_sect != NULL;
-	 debug_sect = debug_sect->ds_next) {
-	/* We want the size of the .debug_info section for this CU
-	   because the dwarf spec requires us to output it below
-	   so we look for it specifically. */
-	if (debug_sect->ds_elf_sect_no ==
-	    dbg->de_elf_sects[DEBUG_INFO]) {
-	    debug_info_size += debug_sect->ds_nbytes;
-	}
+         debug_sect = debug_sect->ds_next) {
+        /* We want the size of the .debug_info section for this CU
+           because the dwarf spec requires us to output it below so we
+           look for it specifically. */
+        if (debug_sect->ds_elf_sect_no == dbg->de_elf_sects[DEBUG_INFO]) {
+            debug_info_size += debug_sect->ds_nbytes;
+        }
     }
 
     hdr = &dbg->de_simple_name_headers[entrykind];
     /* Size of the .debug_typenames (or similar) section header. */
-    stream_bytes_count = extension_size + uword_size +	/* Size of
-							   length
-							   field. */
-	sizeof(Dwarf_Half) +	/* Size of version field. */
-	uword_size +		/* Size of .debug_info offset. */
-	uword_size;		/* Size of .debug_names. */
+    stream_bytes_count = extension_size + uword_size +  /* Size of
+                                                           length
+                                                           field. */
+        sizeof(Dwarf_Half) +    /* Size of version field. */
+        uword_size +            /* Size of .debug_info offset. */
+        uword_size;             /* Size of .debug_names. */
 
 
 
@@ -204,88 +204,90 @@
 
     /* Now we know how long the entire section is */
     GET_CHUNK(dbg, dbg->de_elf_sects[section_index],
-	      stream_bytes, (unsigned long) stream_bytes_count, error);
+              stream_bytes, (unsigned long) stream_bytes_count, error);
     if (stream_bytes == NULL) {
-	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-	return (0);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return (0);
     }
     cur_stream_bytes_ptr = stream_bytes;
 
     if (extension_size) {
-	Dwarf_Unsigned x = DISTINGUISHED_VALUE;
+        Dwarf_Unsigned x = DISTINGUISHED_VALUE;
 
-	WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
-			(const void *) &x, sizeof(x), extension_size);
-	cur_stream_bytes_ptr += extension_size;
+        WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
+                        (const void *) &x, sizeof(x), extension_size);
+        cur_stream_bytes_ptr += extension_size;
 
     }
     /* Write the adjusted length of .debug_*names section. */
     adjusted_length = stream_bytes_count - uword_size - extension_size;
     WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
-		    (const void *) &adjusted_length,
-		    sizeof(adjusted_length), uword_size);
+                    (const void *) &adjusted_length,
+                    sizeof(adjusted_length), uword_size);
     cur_stream_bytes_ptr += uword_size;
 
     /* Write the version as 2 bytes. */
     {
-	Dwarf_Half verstamp = CURRENT_VERSION_STAMP;
+        Dwarf_Half verstamp = CURRENT_VERSION_STAMP;
 
-	WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
-			(const void *) &verstamp,
-			sizeof(verstamp), sizeof(Dwarf_Half));
-	cur_stream_bytes_ptr += sizeof(Dwarf_Half);
+        WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
+                        (const void *) &verstamp,
+                        sizeof(verstamp), sizeof(Dwarf_Half));
+        cur_stream_bytes_ptr += sizeof(Dwarf_Half);
     }
 
     /* Write the offset of the compile-unit. */
     WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
-		    (const void *) &big_zero,
-		    sizeof(big_zero), uword_size);
+                    (const void *) &big_zero,
+                    sizeof(big_zero), uword_size);
     cur_stream_bytes_ptr += uword_size;
 
     /* now create the relocation for the compile_unit offset */
     {
-	int res = dbg->de_reloc_name(dbg,
-		section_index,
-		extension_size + uword_size + sizeof(Dwarf_Half)
-				/* r_offset */ ,
-	        /* debug_info section name symbol */
-		     dbg->de_sect_name_idx[DEBUG_INFO],
-		dwarf_drt_data_reloc, 
-		uword_size);
+        int res = dbg->de_reloc_name(dbg,
+                                     section_index,
+                                     extension_size + uword_size +
+                                     sizeof(Dwarf_Half)
+                                     /* r_offset */
+                                     ,
+                                     /* debug_info section name symbol */
+                                     dbg->de_sect_name_idx[DEBUG_INFO],
+                                     dwarf_drt_data_reloc,
+                                     uword_size);
 
-	if (res != DW_DLV_OK) {
-	    {
-		_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
-		return (0);
-	    }
-	}
+        if (res != DW_DLV_OK) {
+            {
+                _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+                return (0);
+            }
+        }
     }
 
     /* Write the size of .debug_info section. */
     WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
-		    (const void *) &debug_info_size,
-		    sizeof(debug_info_size), uword_size);
+                    (const void *) &debug_info_size,
+                    sizeof(debug_info_size), uword_size);
     cur_stream_bytes_ptr += uword_size;
 
 
     for (nameentry = nameentry_original;
-	 nameentry != NULL; nameentry = nameentry->sne_next) {
+         nameentry != NULL; nameentry = nameentry->sne_next) {
 
-	/* Copy offset of die from start of compile-unit. */
-	WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
-			(const void *) &nameentry->sne_die->di_offset,
-			sizeof(nameentry->sne_die->di_offset),
-			uword_size);
-	cur_stream_bytes_ptr += uword_size;
+        /* Copy offset of die from start of compile-unit. */
+        WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
+                        (const void *) &nameentry->sne_die->di_offset,
+                        sizeof(nameentry->sne_die->di_offset),
+                        uword_size);
+        cur_stream_bytes_ptr += uword_size;
 
-	/* Copy the type name. */
-	strcpy((char *) cur_stream_bytes_ptr, nameentry->sne_name);
-	cur_stream_bytes_ptr += nameentry->sne_name_len + 1;
+        /* Copy the type name. */
+        strcpy((char *) cur_stream_bytes_ptr, nameentry->sne_name);
+        cur_stream_bytes_ptr += nameentry->sne_name_len + 1;
     }
 
     WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
-		    (const void *) &big_zero,
-		    sizeof(big_zero), uword_size);
+                    (const void *) &big_zero,
+                    sizeof(big_zero), uword_size);
 
 
 
--- a/usr/src/tools/ctf/dwarf/common/pro_types.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_types.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +17,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
--- a/usr/src/tools/ctf/dwarf/common/pro_util.h	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_util.h	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,7 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -17,12 +18,12 @@
   any, provided herein do not apply to combinations of this program with 
   other software, or any other product whatsoever.  
 
-  You should have received a copy of the GNU Lesser General Public 
-  License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -36,13 +37,13 @@
 
 
 
-#define IS_64BIT(dbg) 	((dbg)->de_flags & DW_DLC_SIZE_64 ? 1 : 0)
-#define ISA_IA64(dbg) 	((dbg)->de_flags & DW_DLC_ISA_IA64 ? 1 : 0)
+#define IS_64BIT(dbg) ((dbg)->de_flags & DW_DLC_SIZE_64 ? 1 : 0)
+#define ISA_IA64(dbg) ((dbg)->de_flags & DW_DLC_ISA_IA64 ? 1 : 0)
 
 /* definition of sizes of types, given target machine */
-#define sizeof_sbyte(dbg) 	sizeof(Dwarf_Sbyte)
-#define sizeof_ubyte(dbg)	sizeof(Dwarf_Ubyte)
-#define sizeof_uhalf(dbg)	sizeof(Dwarf_Half)
+#define sizeof_sbyte(dbg) sizeof(Dwarf_Sbyte)
+#define sizeof_ubyte(dbg) sizeof(Dwarf_Ubyte)
+#define sizeof_uhalf(dbg) sizeof(Dwarf_Half)
 /* certain sizes not defined here, but set in dbg record.
    See pro_init.c
 */
@@ -63,7 +64,7 @@
 /* R_MIPS* are #define so #ifndef works */
 /* R_IA_64* are not necessarily #define (might be enum) so #ifndef
    is useless, we use the configure script generating 
-   HAVE_R_IA_64_DIR32LSB.
+   HAVE_R_IA_64_DIR32LSB and HAVE_R_IA64_DIR32LSB.
 */
 #ifndef R_MIPS_64
 #define R_MIPS_64 0
@@ -75,33 +76,73 @@
 #define R_MIPS_SCN_DISP 0
 #endif
 
-#ifndef HAVE_R_IA_64_DIR32LSB
-#define R_IA_64_DIR32LSB 0
-#define R_IA_64_DIR64LSB 0
-#define R_IA_64_SEGREL64LSB 0
-#define R_IA_64_SEGREL32LSB 0
+/* R_IA_64_DIR32LSB came before the now-standard R_IA64_DIR32LSB
+   (etc) was defined.  This now deals with either form,
+   preferring the new form if available.  */
+#ifdef HAVE_R_IA64_DIR32LSB
+#define DWARF_PRO_R_IA64_DIR32LSB R_IA64_DIR32LSB
+#define DWARF_PRO_R_IA64_DIR64LSB R_IA64_DIR64LSB
+#define DWARF_PRO_R_IA64_SEGREL64LSB R_IA64_SEGREL64LSB
+#define DWARF_PRO_R_IA64_SEGREL32LSB R_IA64_SEGREL32LSB
+#endif
+#if defined(HAVE_R_IA_64_DIR32LSB) && !defined(HAVE_R_IA64_DIR32LSB)
+#define DWARF_PRO_R_IA64_DIR32LSB R_IA_64_DIR32LSB
+#define DWARF_PRO_R_IA64_DIR64LSB R_IA_64_DIR64LSB
+#define DWARF_PRO_R_IA64_SEGREL64LSB R_IA_64_SEGREL64LSB
+#define DWARF_PRO_R_IA64_SEGREL32LSB R_IA_64_SEGREL32LSB
+#endif
+#if !defined(HAVE_R_IA_64_DIR32LSB) && !defined(HAVE_R_IA64_DIR32LSB)
+#define DWARF_PRO_R_IA64_DIR32LSB 0
+#define DWARF_PRO_R_IA64_DIR64LSB 0
+#define DWARF_PRO_R_IA64_SEGREL64LSB 0
+#define DWARF_PRO_R_IA64_SEGREL32LSB 0
 #endif
 
+/*
+ * The default "I don't know" value can't be zero.
+ * Because that's the sentinel value that means "no relocation".
+ * In order to use this library in 'symbolic relocation mode we
+ * don't care if this value is the right relocation value,
+ * only that it's non-NULL.  So at the end, we define it
+ * to something sensible.
+ */
+
+
+
+#if defined(sun)
+#if defined(sparc)
+#define Get_REL64_isa(dbg)         (R_SPARC_UA64)
+#define Get_REL32_isa(dbg)         (R_SPARC_UA32)
+#define Get_REL_SEGREL_isa(dbg)    (R_SPARC_NONE) /* I don't know! */
+#else  /* i386 */
+#define Get_REL64_isa(dbg)         (R_386_32)   /* Any non-zero value is ok */
+#define Get_REL32_isa(dbg)         (R_386_32)
+#define Get_REL_SEGREL_isa(dbg)    (R_386_NONE) /* I don't know! */
+#endif /* sparc || i386 */
+#else  /* !sun */
 #ifdef HAVE_SYS_IA64_ELF_H
 #define Get_REL64_isa(dbg)         (ISA_IA64(dbg) ? \
-				R_IA_64_DIR64LSB : R_MIPS_64)
+    DWARF_PRO_R_IA64_DIR64LSB : R_MIPS_64)
 #define Get_REL32_isa(dbg)         (ISA_IA64(dbg) ? \
-				R_IA_64_DIR32LSB : R_MIPS_32)
+    DWARF_PRO_R_IA64_DIR32LSB : R_MIPS_32)
 
 
 /* ia64 uses 32bit dwarf offsets for sections */
 #define Get_REL_SEGREL_isa(dbg)    (ISA_IA64(dbg) ? \
-				R_IA_64_SEGREL32LSB : R_MIPS_SCN_DISP)
-#else
+    DWARF_PRO_R_IA64_SEGREL32LSB : R_MIPS_SCN_DISP)
+#else /* HAVE_SYS_IA64_ELF_H */
 
 #if !defined(linux) && !defined(__BEOS__)
 #define Get_REL64_isa(dbg)         (R_MIPS_64)
 #define Get_REL32_isa(dbg)         (R_MIPS_32)
 #define Get_REL_SEGREL_isa(dbg)    (R_MIPS_SCN_DISP)
 #else
-#define Get_REL64_isa(dbg)	(R_IA_64_DIR64LSB)
-#define Get_REL32_isa(dbg)	(R_IA_64_DIR32LSB)
-#define Get_REL_SEGREL_isa(dbg)	(R_IA_64_SEGREL64LSB)
+#define Get_REL64_isa(dbg) (1)
+#define Get_REL32_isa(dbg) (1)   /* these are used on linux */
+#define Get_REL_SEGREL_isa(dbg) (1)   /* non zero values, see comments above */
 #endif
 
-#endif
+#endif /* HAVE_SYS_IA64_ELF_H */
+#endif /* !sun */
+
+
--- a/usr/src/tools/ctf/dwarf/common/pro_vars.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_vars.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +19,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -52,11 +52,11 @@
 */
 Dwarf_Unsigned
 dwarf_add_varname(Dwarf_P_Debug dbg,
-		  Dwarf_P_Die die, char *var_name, Dwarf_Error * error)
+                  Dwarf_P_Die die, char *var_name, Dwarf_Error * error)
 {
     return
-	_dwarf_add_simple_name_entry(dbg, die, var_name,
-				     dwarf_snk_varname, error);
+        _dwarf_add_simple_name_entry(dbg, die, var_name,
+                                     dwarf_snk_varname, error);
 
 
 }
--- a/usr/src/tools/ctf/dwarf/common/pro_weaks.c	Thu Nov 17 11:20:13 2011 +0300
+++ b/usr/src/tools/ctf/dwarf/common/pro_weaks.c	Sun May 22 03:13:22 2011 +0100
@@ -1,6 +1,6 @@
 /*
 
-  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2.1 of the GNU Lesser General Public License 
@@ -19,10 +19,10 @@
 
   You should have received a copy of the GNU Lesser General Public 
   License along with this program; if not, write the Free Software 
-  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
   USA.
 
-  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
   Mountain View, CA 94043, or:
 
   http://www.sgi.com
@@ -52,10 +52,10 @@
 */
 Dwarf_Unsigned
 dwarf_add_weakname(Dwarf_P_Debug dbg,
-		   Dwarf_P_Die die,
-		   char *weak_name, Dwarf_Error * error)
+                   Dwarf_P_Die die,
+                   char *weak_name, Dwarf_Error * error)
 {
     return
-	_dwarf_add_simple_name_entry(dbg, die, weak_name,
-				     dwarf_snk_weakname, error);
+        _dwarf_add_simple_name_entry(dbg, die, weak_name,
+                                     dwarf_snk_weakname, error);
 }