# HG changeset patch # User Richard Lowe # Date 1307569008 14400 # Node ID 2e5a34cc8a4995098a2f2c60efc1d1be07993b1c # Parent 3d898cde151ec1b40ad643b0fefd0df9c4f875e4 1057 should correctly integrate libdwarf sources Reviewed by: Gordon Ross Reviewed by: Garrett D'Amore Approved by: Eric Schrock diff -r 3d898cde151e -r 2e5a34cc8a49 exception_lists/packaging --- a/exception_lists/packaging Tue Jun 07 21:38:05 2011 -0500 +++ b/exception_lists/packaging Wed Jun 08 17:36:48 2011 -0400 @@ -939,6 +939,13 @@ # opt/onbld/bin/i386/elfsign i386 opt/onbld/bin/sparc/elfsign sparc + +# +# Private libdwarf +# +opt/onbld/lib/i386/libdwarf.so i386 +opt/onbld/lib/sparc/libdwarf.so sparc + # # Private socket filter API # diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/cvt/Makefile.com --- a/usr/src/tools/ctf/cvt/Makefile.com Tue Jun 07 21:38:05 2011 -0500 +++ b/usr/src/tools/ctf/cvt/Makefile.com Wed Jun 08 17:36:48 2011 -0400 @@ -22,7 +22,6 @@ # Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" include ../../Makefile.ctf @@ -68,13 +67,11 @@ OBJS=$(SRCS:%.c=%.o) LINTFILES=$(SRCS:%.c=%.ln) -DWARFSRCLIBDIR = ../../dwarf - DWARFLDFLAGS = \ - -L$(DWARFSRCLIBDIR)/$(MACH) \ + -L$(ROOTONBLDLIBMACH) \ '-R$$ORIGIN/../../lib/$(MACH)' \ -ldwarf -DWARFCPPFLAGS = -I$(DWARFSRCLIBDIR) +DWARFCPPFLAGS = -I../../dwarf/common LDLIBS += -lz -lelf CPPFLAGS += -D_REENTRANT diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/cvt/i386/Makefile --- a/usr/src/tools/ctf/cvt/i386/Makefile Tue Jun 07 21:38:05 2011 -0500 +++ b/usr/src/tools/ctf/cvt/i386/Makefile Wed Jun 08 17:36:48 2011 -0400 @@ -23,10 +23,7 @@ # Copyright 2004 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#ident "%Z%%M% %I% %E% SMI" include ../Makefile.com include ../Makefile.targ -DWARFLDFLAGS = -ctfconvert := LDLIBS += $(DWARFSRCLIBDIR)/$(MACH)/libdwarf.a diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/Makefile.com --- a/usr/src/tools/ctf/dwarf/Makefile.com Tue Jun 07 21:38:05 2011 -0500 +++ b/usr/src/tools/ctf/dwarf/Makefile.com Wed Jun 08 17:36:48 2011 -0400 @@ -2,25 +2,92 @@ # Copyright 2004 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#ident "%Z%%M% %I% %E% SMI" +# Copyright 2011, Richard Lowe. include ../../Makefile.ctf +LIBRARY= libdwarf.a +VERS= .1 + +OBJECTS= dwarf_abbrev.o \ + dwarf_addr_finder.o \ + dwarf_alloc.o \ + dwarf_arange.o \ + dwarf_die_deliv.o \ + dwarf_error.o \ + dwarf_form.o \ + dwarf_frame.o \ + dwarf_funcs.o \ + dwarf_global.o \ + dwarf_init_finish.o \ + dwarf_leb.o \ + dwarf_line.o \ + dwarf_loc.o \ + dwarf_macro.o \ + dwarf_print_lines.o \ + dwarf_query.o \ + dwarf_sort_line.o \ + dwarf_string.o \ + dwarf_stubs.o \ + dwarf_types.o \ + dwarf_util.o \ + dwarf_vars.o \ + dwarf_weaks.o \ + pro_alloc.o \ + pro_arange.o \ + pro_die.o \ + pro_encode_nm.o \ + pro_error.o \ + pro_expr.o \ + pro_finish.o \ + pro_forms.o \ + pro_frame.o \ + pro_funcs.o \ + pro_init.o \ + pro_line.o \ + pro_macinfo.o \ + pro_pubnames.o \ + pro_reloc.o \ + pro_reloc_stream.o \ + pro_reloc_symbolic.o \ + pro_section.o \ + pro_types.o \ + pro_vars.o \ + pro_weaks.o + + +include $(SRC)/lib/Makefile.lib + +SRCS= $(PICS:%.o=../common/%.c) + + +FILEMODE = 0755 + +SRCDIR = ../common/ + +CPPFLAGS += -I$(SRCDIR) + +LDLIBS = -lelf -lc + .KEEP_STATE: .PARALLEL: -all: libdwarf.so - -install: all $(ROOTONBLDLIBMACH)/libdwarf.so.1 +all: $(DYNLIB) -clean clobber: - $(RM) libdwarf.so - -FILEMODE = 0755 - -%.so: %.so.1 - -$(RM) $@ ; \ - $(SYMLINK) ./$< $@ +install: all $(ROOTONBLDLIBMACH)/libdwarf.so.1 $(ROOTONBLDLIBMACH)/libdwarf.so $(ROOTONBLDLIBMACH)/%: % $(INS.file) + +$(ROOTONBLDLIBMACH)/$(LIBLINKS): $(ROOTONBLDLIBMACH)/$(LIBLINKS)$(VERS) + $(INS.liblink) + +FRC: + +# We can't provide CTF information for libdwarf, as the CTF tools themselves +# depond upon it, and so aren't built yet. +$(DYNLIB) := CTFMERGE_POST= : +CTFCONVERT_O= : + +include $(SRC)/lib/Makefile.targ + diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/acconfig.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/acconfig.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,68 @@ +/* + + 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 + diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/cmplrs/dwarf_addr_finder.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/cmplrs/dwarf_addr_finder.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,55 @@ +/* + dwarf_addr_finder.h + $Source: /plroot/cmplrs.src/v7.4.2m/.RCS/PL/include/cmplrs/RCS/dwarf_addr_finder.h,v $ + $Date: 2002/06/11 17:49:06 $ + + Defines user interface. + +*/ + +/* return codes for functions +*/ +#define DW_DLV_NO_ENTRY -1 +#define DW_DLV_OK 0 +#define DW_DLV_ERROR 1 + + +/* the following are the 'section' number passed to the called-back + function. + The called-back application must translate this to the + appropriate elf section number/pointer. + + Putting this burden on the application avoids having to store + the numbers in the Dwarf_Debug structure (thereby saving space + for most consumers). +*/ +#define DW_SECTION_INFO 0 +#define DW_SECTION_FRAME 1 +#define DW_SECTION_ARANGES 2 +#define DW_SECTION_LINE 3 +#define DW_SECTION_LOC 4 /* .debug_loc */ + +/* section is one of the above codes: it specifies a section. + secoff is the offset in the dwarf section. + existingAddr is the value at the specified offset (so the + called back routine can sanity check the proceedings). + It's up to the caller to know the size of an address (4 or 8) + and update the right number of bytes. +*/ +typedef int (*Dwarf_addr_callback_func) (int /*section*/, + Dwarf_Off /*secoff*/, Dwarf_Addr /*existingAddr*/); + +/* call this to do the work: it calls back thru cb_func + once per each address to be modified. + Once this returns you are done. + Returns DW_DLV_OK if finished ok. + Returns DW_DLV_ERROR if there was some kind of error, in which + the dwarf error number was passed back thu the dwerr ptr. + Returns DW_DLV_NO_ENTRY if there are no relevant dwarf sections, + so there were no addresses to be modified (and none + called back). +*/ +int _dwarf_addr_finder(dwarf_elf_handle elf_file_ptr, + Dwarf_addr_callback_func cb_func, + int *dwerr); + diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/config.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,144 @@ +/* config.h. Generated 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 to 1 if you have the header file. */ +#define HAVE_ALLOCA_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_ELFACCESS_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ELF_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LIBELF_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LIBELF_LIBELF_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SGIDEFS_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_IA64_ELF_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* 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 +#else +#undef WORDS_BIGENDIAN +#endif diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,721 @@ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + Copyright (C) 2000, 2001 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 + +*/ + + +#ifndef __DWARF_H +#define __DWARF_H +#ifdef __cplusplus +extern "C" { +#endif + +/* + dwarf.h DWARF debugging information values + $Revision: 1.29 $ $Date: 2003/02/05 22:57:01 $ + + The comment "DWARF3" appears where there are + new entries from DWARF3. + +*/ + + +#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 + +/* 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++ */ + +/* 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 + +/* 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 + + + +#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_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 + + +/* 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 +/* 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 + + +#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_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 + +/* 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 + +/* 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_ACCESS_public 1 +#define DW_ACCESS_protected 2 +#define DW_ACCESS_private 3 + +#define DW_VIS_local 1 +#define DW_VIS_exported 2 +#define DW_VIS_qualified 3 + +#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 */ + +/* Sun extensions */ +#define DW_LANG_SUN_Assembler 0x9001 + +#define DW_LANG_hi_user 0xffff + + +#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_normal 0x1 +#define DW_CC_program 0x2 +#define DW_CC_nocall 0x3 +#define DW_CC_lo_user 0x40 +#define DW_CC_hi_user 0xff + +#define DW_INL_not_inlined 0 +#define DW_INL_inlined 1 +#define DW_INL_declared_not_inlined 2 +#define DW_INL_declared_inlined 3 + +#define DW_ORD_row_major 0 +#define DW_ORD_col_major 1 + +#define DW_DSC_label 0 +#define DW_DSC_range 1 + +#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 */ + +#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_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 + +#define DW_CFA_advance_loc 0x40 +#define DW_CFA_offset 0x80 +#define DW_CFA_restore 0xc0 +#define DW_CFA_extended 0 + +#define DW_CFA_nop 0x00 +#define DW_CFA_set_loc 0x01 +#define DW_CFA_advance_loc1 0x02 +#define DW_CFA_advance_loc2 0x03 +#define DW_CFA_advance_loc4 0x04 +#define DW_CFA_offset_extended 0x05 +#define DW_CFA_restore_extended 0x06 +#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_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_def_cfa_sf 0x12 /* DWARF3 */ +#define DW_CFA_def_cfa_offset_sf 0x13 /* DWARF3 */ + +#define DW_CFA_low_user 0x1c +#define DW_CFA_MIPS_advance_loc8 0x1d + +/* the following two from egcs-1.1.2 */ +#define DW_CFA_GNU_window_save 0x2d +#define DW_CFA_GNU_args_size 0x2e + +#define DW_CFA_high_user 0x3f + + +/* 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. + + The CFA (Canonical Frame Address) described in DWARF is called + the Virtual Frame Pointer on MIPS/SGI machines. + + Rule describes: +*/ +#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. + */ +#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 */ +#define DW_FRAME_FREG3 35 /* 64-bit floating point reg 3 */ +#define DW_FRAME_FREG4 36 /* 64-bit floating point reg 4 */ +#define DW_FRAME_FREG5 37 /* 64-bit floating point reg 5 */ +#define DW_FRAME_FREG6 38 /* 64-bit floating point reg 6 */ +#define DW_FRAME_FREG7 39 /* 64-bit floating point reg 7 */ +#define DW_FRAME_FREG8 40 /* 64-bit floating point reg 8 */ +#define DW_FRAME_FREG9 41 /* 64-bit floating point reg 9 */ +#define DW_FRAME_FREG10 42 /* 64-bit floating point reg 10 */ +#define DW_FRAME_FREG11 43 /* 64-bit floating point reg 11 */ +#define DW_FRAME_FREG12 44 /* 64-bit floating point reg 12 */ +#define DW_FRAME_FREG13 45 /* 64-bit floating point reg 13 */ +#define DW_FRAME_FREG14 46 /* 64-bit floating point reg 14 */ +#define DW_FRAME_FREG15 47 /* 64-bit floating point reg 15 */ +#define DW_FRAME_FREG16 48 /* 64-bit floating point reg 16 */ +#define DW_FRAME_FREG17 49 /* 64-bit floating point reg 17 */ +#define DW_FRAME_FREG18 50 /* 64-bit floating point reg 18 */ +#define DW_FRAME_FREG19 51 /* 64-bit floating point reg 19 */ +#define DW_FRAME_FREG20 52 /* 64-bit floating point reg 20 */ +#define DW_FRAME_FREG21 53 /* 64-bit floating point reg 21 */ +#define DW_FRAME_FREG22 54 /* 64-bit floating point reg 22 */ +#define DW_FRAME_FREG23 55 /* 64-bit floating point reg 23 */ +#define DW_FRAME_FREG24 56 /* 64-bit floating point reg 24 */ +#define DW_FRAME_FREG25 57 /* 64-bit floating point reg 25 */ +#define DW_FRAME_FREG26 58 /* 64-bit floating point reg 26 */ +#define DW_FRAME_FREG27 59 /* 64-bit floating point reg 27 */ +#define DW_FRAME_FREG28 60 /* 64-bit floating point reg 28 */ +#define DW_FRAME_FREG29 61 /* 64-bit floating point reg 29 */ +#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 */ + +#define DW_FRAME_STATIC_LINK 65 /* column recording static link*/ + /* applicable to up-level */ + /* addressing, as in mp code, */ + /* pascal, etc */ + +/* 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) + + +/* + DW_FRAME_UNDEFINED_VAL and DW_FRAME_SAME_VAL are + never on disk, just generated by libdwarf. See libdwarf.h + for their values. +*/ + + + +#define DW_CHILDREN_no 0x00 +#define DW_CHILDREN_yes 0x01 + +#define DW_ADDR_none 0 + +#ifdef __cplusplus +} +#endif +#endif /* __DWARF_H */ diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_abbrev.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_abbrev.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,248 @@ +/* + + Copyright (C) 2000,2001 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_abbrev.h" + +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_Small *abbrev_ptr; + Dwarf_Small *abbrev_section_end; + Dwarf_Half attr; + Dwarf_Half attr_form; + Dwarf_Abbrev ret_abbrev; + Dwarf_Unsigned labbr_count = 0; + Dwarf_Unsigned utmp; + + + if (dbg == NULL) { + _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 (res != DW_DLV_OK) { + return res; + } + } + + if (offset >= dbg->de_debug_abbrev_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); + } + 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); + } + + + *abbr_count = 0; + if (length != NULL) + *length = 1; + + abbrev_ptr = dbg->de_debug_abbrev + offset; + abbrev_section_end = + dbg->de_debug_abbrev + dbg->de_debug_abbrev_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); + } + + DECODE_LEB128_UWORD(abbrev_ptr, utmp); + ret_abbrev->ab_tag = utmp; + ret_abbrev->ab_has_child = *(abbrev_ptr++); + ret_abbrev->ab_abbrev_ptr = abbrev_ptr; + + 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; + + if (attr != 0) + (labbr_count)++; + + } while (abbrev_ptr < abbrev_section_end && + (attr != 0 || attr_form != 0)); + + if (abbrev_ptr > abbrev_section_end) { + _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR); + return (DW_DLV_ERROR); + } + + if (length != NULL) + *length = abbrev_ptr - dbg->de_debug_abbrev - offset; + + *returned_abbrev = ret_abbrev; + *abbr_count = labbr_count; + return (DW_DLV_OK); +} + +int +dwarf_get_abbrev_code(Dwarf_Abbrev abbrev, + Dwarf_Unsigned * returned_code, + Dwarf_Error * error) +{ + if (abbrev == NULL) { + _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); + return (DW_DLV_ERROR); + } + + *returned_code = abbrev->ab_code; + return (DW_DLV_OK); +} + +int +dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev, + Dwarf_Half * returned_tag, Dwarf_Error * error) +{ + if (abbrev == NULL) { + _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); + return (DW_DLV_ERROR); + } + + *returned_tag = abbrev->ab_tag; + return (DW_DLV_OK); +} + + +int +dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev, + Dwarf_Signed * returned_flag, + Dwarf_Error * error) +{ + if (abbrev == NULL) { + _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); + return (DW_DLV_ERROR); + } + + *returned_flag = abbrev->ab_has_child; + return (DW_DLV_OK); +} + + +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_Byte_Ptr abbrev_ptr; + Dwarf_Byte_Ptr abbrev_end; + Dwarf_Byte_Ptr mark_abbrev_ptr; + Dwarf_Half attr; + Dwarf_Half attr_form; + + if (index < 0) + return (DW_DLV_NO_ENTRY); + + if (abbrev == NULL) { + _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); + return (DW_DLV_ERROR); + } + + if (abbrev->ab_code == 0) { + return (DW_DLV_NO_ENTRY); + } + + if (abbrev->ab_dbg == NULL) { + _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; + + for (attr = 1, attr_form = 1; + 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; + } + + if (abbrev_ptr >= abbrev_end) { + _dwarf_error(abbrev->ab_dbg, error, DW_DLE_ABBREV_DECODE_ERROR); + return (DW_DLV_ERROR); + } + + if (index >= 0) { + return (DW_DLV_NO_ENTRY); + } + + if (form != NULL) + *form = attr_form; + if (offset != NULL) + *offset = mark_abbrev_ptr - abbrev->ab_dbg->de_debug_abbrev; + + *returned_attr_num = (attr); + return DW_DLV_OK; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_abbrev.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_abbrev.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,45 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + + +struct Dwarf_Abbrev_s { + Dwarf_Word ab_code; + Dwarf_Half ab_tag; + Dwarf_Small ab_has_child; + Dwarf_Byte_Ptr ab_abbrev_ptr; + Dwarf_Debug ab_dbg; +}; diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_addr_finder.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_addr_finder.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,686 @@ +/* + + Copyright (C) 2000, 2002 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 + +*/ + + +#include "config.h" +#include "libdwarfdefs.h" +#ifdef HAVE_ELF_H +#include +#endif +#include +#include +#include "dwarf_base_types.h" +#include "dwarf_alloc.h" +#include "dwarf_opaque.h" +#include "dwarf_arange.h" +#include "dwarf_line.h" +#include "dwarf_frame.h" +#include +#include "dwarf_error.h" + +typedef unsigned long long ull; + +static int do_this_die_and_dealloc(Dwarf_Debug dbg, Dwarf_Die die, + int *errval); +static int + handle_debug_info(Dwarf_Debug dbg, int *errval); +static int + handle_debug_frame(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func, int *errval); +static int + handle_debug_aranges(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func, int *errval); +static int + handle_debug_line(Dwarf_Debug dbg, Dwarf_Die cu_die, Dwarf_addr_callback_func cb_func, int *errval); +static int + handle_debug_loc(void); + + +static Dwarf_addr_callback_func send_addr_note; + +int +_dwarf_addr_finder(dwarf_elf_handle elf_file_ptr, + Dwarf_addr_callback_func cb_func, int *dwerr) +{ + + Dwarf_Error err = 0; + Dwarf_Debug dbg = 0; + int res = 0; + int errval = 0; + int sections_found = 0; + + res = dwarf_elf_init(elf_file_ptr, DW_DLC_READ, /* errhand */ 0, + /* errarg */ 0, &dbg, &err); + if (res == DW_DLV_ERROR) { + int errv = (int) dwarf_errno(err); + + return errv; + } + if (res == DW_DLV_NO_ENTRY) { + return res; + } + + send_addr_note = cb_func; + + res = handle_debug_info(dbg, &errval); + switch (res) { + case DW_DLV_OK: + ++sections_found; + break; + case DW_DLV_NO_ENTRY: + + break; + default: + case DW_DLV_ERROR: + 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; + case DW_DLV_NO_ENTRY: + break; + default: + case DW_DLV_ERROR: + 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; + case DW_DLV_NO_ENTRY: + break; + default: + case DW_DLV_ERROR: + dwarf_finish(dbg, &err); + *dwerr = errval; + return res; + } + + res = handle_debug_loc(); /* does nothing */ + switch (res) { + case DW_DLV_OK: + ++sections_found; + break; + case DW_DLV_NO_ENTRY: + break; + default: + case DW_DLV_ERROR: + /* IMPOSSIBLE : handle_debug_loc cannot return this */ + dwarf_finish(dbg, &err); + *dwerr = errval; + return res; + } + + + + *dwerr = 0; + res = dwarf_finish(dbg, &err); + if (res == DW_DLV_ERROR) { + *dwerr = (int) dwarf_errno(err); + return DW_DLV_ERROR; + } + if (sections_found == 0) { + return DW_DLV_NO_ENTRY; + } + return DW_DLV_OK; + +} + +/* + Return DW_DLV_OK, ERROR, or NO_ENTRY. +*/ +static int +handle_debug_info(Dwarf_Debug dbg, int *errval) +{ + Dwarf_Unsigned nxtoff = 1; + Dwarf_Unsigned hdr_length; + Dwarf_Half version_stamp; + Dwarf_Unsigned abbrev_offset; + Dwarf_Half addr_size; + Dwarf_Error err; + int terminate_now = 0; + int res = 0; + Dwarf_Die sibdie; + int sibres; + int nres = DW_DLV_OK; + + + 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) + ) { + + 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? */ + } + + } + if (nres == DW_DLV_ERROR) { + int localerr = (int) dwarf_errno(err); + + *errval = localerr; + return DW_DLV_ERROR; + } + return DW_DLV_OK; +} + +static int + might_have_addr[] = { + DW_AT_high_pc, + DW_AT_low_pc, +}; +static int + might_have_locdesc[] = { + DW_AT_segment, + DW_AT_return_addr, + DW_AT_frame_base, + DW_AT_static_link, + DW_AT_data_member_location, + DW_AT_string_length, + DW_AT_location, + DW_AT_use_location, + DW_AT_vtable_elem_location, +}; + +/* + 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) +{ + int res = DW_DLV_OK; + Dwarf_Off offset; + Dwarf_Addr addr; + Dwarf_Half form; + int ares; + + Dwarf_Attribute attr; + + ares = dwarf_attr(die, attrnum, &attr, perr); + if (ares == DW_DLV_OK) { + 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 (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? */ + + ; /* do nothing */ + } + dwarf_dealloc(dbg, attr, DW_DLA_ATTR); + + } else { + res = ares; + } + return res; +} + +/* + 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) +{ + int retval = DW_DLV_OK; + Dwarf_Attribute attr; + Dwarf_Locdesc *llbuf; + Dwarf_Signed i; + Dwarf_Off offset; + Dwarf_Loc *locp; + unsigned int entindx; + int res; + int ares; + + + ares = dwarf_attr(die, attrnum, &attr, perr); + if (ares == DW_DLV_OK) { + 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; + + 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); + } + } + } + + + 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; + } else { + retval = ares; + } + return retval; +} + +/* + Return DW_DLV_OK, or DW_DLV_ERROR + + Handle the addrs in a single die. +*/ +static int +process_this_die_attrs(Dwarf_Debug dbg, Dwarf_Die newdie, int *errval) +{ + Dwarf_Error err; + Dwarf_Half i; + Dwarf_Half newattrnum; + int res; + int tres; + Dwarf_Half ltag; + + Dwarf_Off doff; + int doffres = dwarf_dieoffset(newdie, &doff, &err); + + if (doffres != DW_DLV_OK) { + if (doffres == DW_DLV_ERROR) { + *errval = (int) dwarf_errno(err); + } + return doffres; + } + tres = dwarf_tag(newdie, <ag, &err); + if (tres != DW_DLV_OK) { + 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; + } + } + + for (i = 0; i < sizeof(might_have_addr) / sizeof(int); i++) { + 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; + } + } + } + for (i = 0; i < sizeof(might_have_locdesc) / sizeof(int); i++) { + 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; + } + } + } + + return DW_DLV_OK; +} + +/* + 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. + +*/ +static int +do_this_die_and_dealloc(Dwarf_Debug dbg, Dwarf_Die die, int *errval) +{ + + Dwarf_Die prevdie = 0; + Dwarf_Die newdie = die; + Dwarf_Error err = 0; + int res = 0; + int sibres = DW_DLV_OK; + int tres = DW_DLV_OK; + Dwarf_Die sibdie; + + while (sibres == DW_DLV_OK) { + 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; + } + + 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 (sibres == DW_DLV_NO_ENTRY) { + return DW_DLV_OK; + } + /* 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; + +} + + +static int +handle_debug_frame(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func, + int *errval) +{ + int retval = DW_DLV_OK; + int res; + Dwarf_Error err; + Dwarf_Addr *addrlist; + Dwarf_Off *offsetlist; + Dwarf_Signed count; + int i; + + res = + _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); + } else if (res == DW_DLV_NO_ENTRY) { + retval = res; + } else { + *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 retval = DW_DLV_OK; + Dwarf_Error err; + Dwarf_Addr *aranges; + Dwarf_Signed count; + int indx; + Dwarf_Off *offsets; + + retval = + _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); + } else if (retval == DW_DLV_NO_ENTRY) { + ; /* do nothing */ + } else { + *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) +{ + int retval = DW_DLV_OK; + int res; + Dwarf_Error err; + Dwarf_Addr *addrlist; + Dwarf_Off *offsetlist; + Dwarf_Unsigned count; + Dwarf_Unsigned i; + + res = + _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]); + + } + dwarf_dealloc(dbg, offsetlist, DW_DLA_ADDR); + dwarf_dealloc(dbg, addrlist, DW_DLA_ADDR); + } else if (res == DW_DLV_NO_ENTRY) { + retval = res; + } else { + *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! +*/ +static int +handle_debug_loc(void) +{ + int retval = DW_DLV_NO_ENTRY; + + return retval; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_alloc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_alloc.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,1122 @@ +/* + + 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 + 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include + +#include +#include +#include + +/* + These files are included to get the sizes + of structs to set the ah_bytes_one_struct field + of the Dwarf_Alloc_Hdr_s structs for each + allocation type. +*/ +#include "dwarf_line.h" +#include "dwarf_global.h" +#include "dwarf_arange.h" +#include "dwarf_abbrev.h" +#include "dwarf_die_deliv.h" +#include "dwarf_frame.h" +#include "dwarf_loc.h" +#include "dwarf_funcs.h" +#include "dwarf_types.h" +#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); +void _dwarf_simple_malloc_botch(int err); + +#endif /* DWARF_SIMPLE_MALLOC */ + + + + +/* + This macro adds the size of a pointer to the size of a + struct that is given to it. It rounds up the size to + 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 + 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 + + 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) + +/* Round size up to the next multiple of _DW_RESERVE bytes +*/ +#define ROUND_SIZE(inputsize) \ + (((inputsize) % (_DW_RESERVE)) == 0 ? \ + (inputsize): \ + ((inputsize) + \ + (_DW_RESERVE) - ((inputsize) % (_DW_RESERVE)) )) + +#define ROUND_SIZE_WITH_POINTER(i_size) (ROUND_SIZE(i_size) + _DW_RESERVE) +#define BASE_ALLOC 64 +#define BIG_ALLOC 128 + +/* This translates into de_alloc_hdr index +** the 0,1,1 entries are special: they don't use the +** table values at all. +** Rearranging the DW_DLA values would break binary compatibility +** so that is not an option. +*/ +struct ial_s { + 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). */ + int ia_struct_size; + + + /* Number of instances per alloc block. MUST be > 0. */ + int ia_base_count; +}; + +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}, + /* 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 */ + +/* 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. +*/ + {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 */ +}; + +#ifndef DWARF_SIMPLE_MALLOC + +/* + This function is given a pointer to the header + structure that is used to allocate 1 struct of + the type given by alloc_type. It first checks + if a struct is available in its free list. If + not, it checks if 1 is available in its blob, + which is a chunk of memory that is reserved for + its use. If not, it malloc's a chunk. The + initial part of it is used to store the end + address of the chunk, and also to keep track + of the number of free structs in that chunk. + This information is used for freeing the chunk + when all the structs in it are free. + + Assume all input arguments have been validated. + + This function can be used only to allocate 1 + struct of the given type. + + It returns a pointer to the struct that the + user can use. It returns NULL only when it + is out of free structs, and cannot malloc + any more. The struct returned is zero-ed. + + A pointer to the chunk that the struct belongs + to is stored in the bytes preceding the + returned address. Since this pointer it + never overwritten, when a struct is allocated + from the free_list this pointer does not + have to be written. In the 2 other cases, + where the struct is allocated from a new + chunk, or the blob, a pointer to the chunk + is written. +*/ +static Dwarf_Ptr +_dwarf_find_memory(Dwarf_Alloc_Hdr alloc_hdr) +{ + /* Pointer to the struct allocated. */ + Dwarf_Small *ret_mem = 0; + + /* Pointer to info about chunks allocated. */ + Dwarf_Alloc_Area alloc_area; + + /* Size of chunk malloc'ed when no free structs left. */ + Dwarf_Signed mem_block_size; + + /* Pointer to block malloc'ed. */ + Dwarf_Small *mem_block; + + /* + 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. */ + 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) { + + 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--; + + 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; + + /* + 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. */ +#ifdef DEBUG + 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; + + alloc_hdr->ah_chunks_allocated++; + + { /* 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); + } + + /* + 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); + } + + + /* + 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. */ +#ifdef DEBUG + fprintf(stderr, + "libdwarf Internal error: free structs in chunk %d\n", + (int) alloc_area->aa_free_structs_in_chunk); +#endif + 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; + + /* + 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); + return (ret_mem); +} + +#endif /* ndef DWARF_SIMPLE_MALLOC */ + +/* + This function returns a pointer to a region + of memory. For alloc_types that are not + strings or lists of pointers, only 1 struct + can be requested at a time. This is indicated + by an input count of 1. For strings, count + equals the length of the string it will + 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 + 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_Alloc_Hdr alloc_hdr; + + Dwarf_Ptr ret_mem; + + Dwarf_Signed size = 0; + unsigned int index; + unsigned int type = alloc_type; + + if (dbg == NULL) { + return (NULL); + } + + if (type >= ALLOC_AREA_INDEX_TABLE_MAX) { + /* internal error */ + return NULL; + } + index = index_into_allocated[type].ia_al_num; + /* zero also illegal but not tested for */ + + /* If the Dwarf_Debug is not fully set up, we will get index 0 for + any type and must do something. 'Not fully set up' can only + happen for DW_DLA_ERROR, I (davea) believe, and for that we call + 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. */ +#ifdef DEBUG + 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) { +#ifdef DWARF_SIMPLE_MALLOC + size = alloc_hdr->ah_bytes_one_struct; +#else + return (_dwarf_find_memory(alloc_hdr)); +#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. */ +#ifdef DWARF_SIMPLE_MALLOC + _dwarf_simple_malloc_botch(3); +#endif +#ifdef DEBUG + 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); +#endif + if (ret_mem != NULL) + memset(ret_mem,0, size); + + return (ret_mem); +} + + +/* + This function is used to deallocate a region of memory + that was obtained by a call to _dwarf_get_alloc. Note + that though dwarf_dealloc() is a public function, + _dwarf_get_alloc() isn't. + + For lists, typically arrays of pointers, it is assumed + 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. + + For strings, the pointer might point to a string in + .debug_info or .debug_string. After this is checked, + and if found not to be the case, a free() is done, + again on the assumption that a malloc was used to + obtain the space. + + For other types of structs, a pointer to the chunk that + the struct was allocated out of, is present in the bytes + preceding the pointer passed in. For this chunk it is + checked whether all the structs in that chunk are now free. + If so, the entire chunk is free_ed. Otherwise, the space + is added to the free list for that chunk, and the free count + incremented. + + This function does not return anything. +*/ +void +dwarf_dealloc(Dwarf_Debug dbg, + Dwarf_Ptr space, Dwarf_Unsigned alloc_type) +{ + Dwarf_Alloc_Hdr alloc_hdr; + Dwarf_Alloc_Area alloc_area; + unsigned int type = alloc_type; + unsigned int index; + + if (space == NULL) { + 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 (dbg == NULL) { + /* 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; + } + + index = index_into_allocated[alloc_type].ia_al_num; + /* + A string pointer may point into .debug_info or .debug_string. + Otherwise, they are directly malloc'ed. */ + 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 (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_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_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 != 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 != 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 != 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_weaknames != NULL && + (Dwarf_Small *) space >= dbg->de_debug_weaknames && + (Dwarf_Small *) space < + dbg->de_debug_weaknames + dbg->de_debug_weaknames_size) + return; + + 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) { + + 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; + + } + +#ifdef DWARF_SIMPLE_MALLOC + _dwarf_simple_malloc_delete_from_list(dbg, space, alloc_type); + free(space); +#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); + + /* 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... */ +#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); +#endif + return; + } + + alloc_hdr->ah_struct_user_holds--; + alloc_area->aa_free_structs_in_chunk++; + + /* + 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; + } + + if (alloc_area->aa_next != NULL) { + alloc_area->aa_next->aa_prev = alloc_area->aa_prev; + } + + 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); + } + + else { + ((Dwarf_Free_List) space)->fl_next = alloc_area->aa_free_list; + alloc_area->aa_free_list = space; + } +#endif /* !DWARF_SIMPLE_MALLOC */ +} + + +/* + Allocates space for a Dwarf_Debug_s struct, + since one does not exist. +*/ +Dwarf_Debug +_dwarf_get_debug(void + ) +{ + Dwarf_Debug dbg; + + dbg = (Dwarf_Debug) malloc(sizeof(struct Dwarf_Debug_s)); + if (dbg == NULL) + return (NULL); + else + memset(dbg,0, sizeof(struct Dwarf_Debug_s)); + + return (dbg); +} + + +/* + 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 + malloc'ed directly. + + This routine should be called after _dwarf_setup(), + so that information about the sizes of the Dwarf + sections can be used to decide the number of + structs of each type malloc'ed. + + Also DW_DLA_ELLIST, DW_DLA_BOUNDS, DW_DLA_TYPE, + DW_DLA_SUBSCR, DW_DLA_LINEBUF allocation types + are currently not used. + The ah_bytes_one_struct and ah_structs_per_chunk fields for + these types have been set to 1 for efficiency + in dwarf_get_alloc(). + + Ah_alloc_num should be greater than 1 for all + types that are currently being used. + + Therefore, for these allocation types the + ah_bytes_one_struct, and ah_structs_per_chunk fields do not + need to be initialized. + + Being an internal routine, assume proper dbg. + + + + +*/ +/* +** Set up all the Dwarf_Alloc_Hdr records. +*/ + +Dwarf_Debug +_dwarf_setup_debug(Dwarf_Debug dbg) +{ + 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); + + Dwarf_Alloc_Hdr alloc_hdr = &dbg->de_alloc_hdr[hdr_index]; + + 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; + } + return (dbg); +} + +/* + This function prints out the statistics + collected on allocation of memory chunks. +*/ +void +dwarf_print_memory_stats(Dwarf_Debug dbg) +{ + Dwarf_Alloc_Hdr alloc_hdr; + Dwarf_Shalf i; + + /* + 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" + }; + + if (dbg == NULL) + return; + + printf("Size of Dwarf_Debug %4ld bytes\n", + (long) sizeof(*dbg)); + printf("Size of Dwarf_Alloc_Hdr_s %4ld bytes\n", + (long) sizeof(struct Dwarf_Alloc_Hdr_s)); + printf("size of Dwarf_Alloc_Area_s %4ld bytes\n", + (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; + + 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 + forward chained through the aa_next + pointer. +*/ +static void +_dwarf_recursive_free(Dwarf_Alloc_Area alloc_area) +{ + if (alloc_area->aa_next != NULL) { + _dwarf_recursive_free(alloc_area->aa_next); + } + + alloc_area->aa_next = 0; + alloc_area->aa_prev = 0; + free(alloc_area); +} +#endif + +/* + Used to free all space allocated for this Dwarf_Debug. + The caller should assume that the Dwarf_Debug pointer + itself is no longer valid upon return from this function. + + In case of difficulty, this function simply returns quietly. +*/ +int +_dwarf_free_all_of_one_debug(Dwarf_Debug dbg) +{ + Dwarf_Alloc_Hdr alloc_hdr; + Dwarf_Shalf i; + + if (dbg == NULL) + return (DW_DLV_ERROR); + +#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; + dbg->de_simple_malloc_current = 0; + } +#else + for (i = 1; i < ALLOC_AREA_REAL_TABLE_MAX; 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); + } + } + +#endif + + memset(dbg,0, sizeof(*dbg)); /* prevent accidental use later */ + free(dbg); + return (DW_DLV_OK); +} + +/* A special case: we have no dbg, no alloc header etc. + So create something out of thin air that we can recognize + in dwarf_dealloc. + Something with the prefix (prefix space hidden from caller). + + Only applies to DW_DLA_ERROR, making up an error record. +*/ + +struct Dwarf_Error_s * +_dwarf_special_no_dbg_error_malloc(void) +{ + /* 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)]; + }; + char *mem; + + mem = malloc(sizeof(union u)); + + if (mem == 0) { + return 0; + + } + memset(mem,0, sizeof(union u)); + mem += _DW_RESERVE; + return (struct Dwarf_Error_s *) mem; +} + +/* The free side of _dwarf_special_no_dbg_error_malloc() +*/ +static void +_dwarf_free_special_error(Dwarf_Ptr space) +{ + char *mem = (char *) space; + + mem -= _DW_RESERVE; + free(mem); +} + + +#ifdef DWARF_SIMPLE_MALLOC +/* here solely for planting a breakpoint. */ +/* ARGSUSED */ +void +_dwarf_simple_malloc_botch(int err) +{ +} +static void +_dwarf_simple_malloc_add_to_list(Dwarf_Debug dbg, + 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; + + if(cur->sr_used >= DSM_BLOCK_COUNT) { + /* better not be > than as that means chaos */ + + /* 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; +} +/* + DWARF_SIMPLE_MALLOC is for testing the hypothesis that the existing + complex malloc scheme in libdwarf 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 + such does not test the complicated standard-libdwarf-alloc code). + + To properly answer the question, the simple-malloc allocate + and delete should be something other than a simple list. + Perhaps a heap, or perhaps a red-black tree. + +*/ +static void +_dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg, + Dwarf_Ptr space, + short alloc_type) +{ + if(space == 0) { + _dwarf_simple_malloc_botch(6); + } + if(dbg->de_simple_malloc_base) { + struct simple_malloc_record_s *smp = dbg->de_simple_malloc_base; + while( smp) + { + int 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; + } + } + smp = smp->sr_next; + } + } + /* Never found the space */ + _dwarf_simple_malloc_botch(1); + return; + +} +#endif + diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_alloc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_alloc.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,167 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +Dwarf_Ptr _dwarf_get_alloc(Dwarf_Debug, Dwarf_Small, Dwarf_Unsigned); +Dwarf_Debug _dwarf_get_debug(void); +Dwarf_Debug _dwarf_setup_debug(Dwarf_Debug); +int _dwarf_free_all_of_one_debug(Dwarf_Debug); + +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 + +/* + This struct is used to chain all the deallocated + structs on the free list of each chain. The structs + are chained internally, by using the memory they + contain. +*/ +struct Dwarf_Free_List_s { + Dwarf_Free_List fl_next; +}; + + +/* + This struct is used to manage all the chunks malloc'ed + for a particular alloc_type. Many of the fields are + initialized by dwarf_init(). +*/ +struct Dwarf_Alloc_Hdr_s { + + /* Count of actual number of structs user app holds pointers to + currently. */ + Dwarf_Sword ah_struct_user_holds; + + /* + Size of each struct that will be allocated for this alloc_type. + Initialized by dwarf_init(). */ + Dwarf_Half ah_bytes_one_struct; + + /* + Number of structs of this alloc_type that will be contained in + each chunk that is malloc'ed. Initialized by dwarf_init(). */ + Dwarf_Word ah_structs_per_chunk; + + /* + Number of bytes malloc'ed per chunk which is basically + (ah_bytes_one_struct+_DWARF_RESERVE) * ah_alloc_num. */ + Dwarf_Word ah_bytes_malloc_per_chunk; + + /* Count of chunks currently allocated for type. */ + Dwarf_Sword ah_chunks_allocated; + + /* + Points to a chain of Dwarf_Alloc_Area_s structs that represent + all the chunks currently allocated for the alloc_type. */ + Dwarf_Alloc_Area ah_alloc_area_head; + + /* Last Alloc Area that was allocated by malloc. The + free-space-search area looks here first and only if it is full + goes thru the list pointed to by ah_alloc_area_head. */ + Dwarf_Alloc_Area ah_last_alloc_area; +}; + + +/* + This struct is used to manage each chunk that is + malloc'ed for a particular alloc_type. For each + allocation type, the allocation header points to + a list of all the chunks malloc'ed for that type. +*/ +struct Dwarf_Alloc_Area_s { + + /* Points to the free list of structs in the chunk. */ + Dwarf_Ptr aa_free_list; + + /* + Count of the number of free structs in the chunk. This includes + both those on the free list, and in the blob. */ + Dwarf_Sword aa_free_structs_in_chunk; + + /* + Points to the first byte of the blob from which struct will be + allocated. A struct is put on the free_list only when it + dwarf_deallocated. Initial allocations are from the blob. */ + Dwarf_Small *aa_blob_start; + + /* Points just past the last byte of the blob. */ + Dwarf_Small *aa_blob_end; + + /* Points to alloc_hdr this alloc_area is linked to: The owner, in + other words. */ + Dwarf_Alloc_Hdr aa_alloc_hdr; + + /* + Used for chaining Dwarf_Alloc_Area_s atructs. Alloc areas are + doubly linked to enable deletion from the list in constant time. */ + Dwarf_Alloc_Area aa_next; + Dwarf_Alloc_Area aa_prev; +}; + +struct Dwarf_Error_s *_dwarf_special_no_dbg_error_malloc(void); + +#ifdef DWARF_SIMPLE_MALLOC +/* + DWARF_SIMPLE_MALLOC is for testing the hypothesis that the existing + complex malloc scheme in libdwarf 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 + such does not test the complicated standard-libdwarf-alloc code). + +*/ + +struct simple_malloc_entry_s { + Dwarf_Small *se_addr; + unsigned long se_size; + short se_type; +}; +#define DSM_BLOCK_COUNT (1000) +#define DSM_BLOCK_SIZE (sizeof(struct simple_malloc_entry_s)*DSM_BLOCK_COUNT) + +/* we do this so dwarf_dealloc can really free everything */ +struct simple_malloc_record_s { + struct simple_malloc_record_s *sr_next; + int sr_used; + struct simple_malloc_entry_s sr_entry[DSM_BLOCK_COUNT]; +}; + + + +#endif /* DWARF_SIMPLE_MALLOC */ diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_arange.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_arange.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,623 @@ +/* + + Copyright (C) 2000, 2002 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 + +*/ + + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_arange.h" + + +/* + This function returns the count of the number of + aranges in the .debug_aranges section. It sets + aranges to point to a block of Dwarf_Arange's + describing the arange's. It returns DW_DLV_ERROR + on error. + + Must be identical in most aspects to + dwarf_get_aranges_addr_offsets! +*/ +int +dwarf_get_aranges(Dwarf_Debug dbg, + 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; + + /* 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; + + /* Used to chain Dwarf_Aranges structs. */ + Dwarf_Chain curr_chain, prev_chain, head_chain = NULL; + + int res; + + /* ***** BEGIN CODE ***** */ + + if (dbg == NULL) { + _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); + 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); + } + + arange_block = (Dwarf_Arange *) + _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); + } + + 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); + } + + *aranges = arange_block; + *returned_count = (arange_count); + return DW_DLV_OK; +} + +/* + This function returns DW_DLV_OK if it succeeds + and DW_DLV_ERR or DW_DLV_OK otherwise. + count is set to the number of addresses in the + .debug_aranges section. + For each address, the corresponding element in + an array is set to the address itself(aranges) and + the section offset (offsets). + Must be identical in most aspects to + dwarf_get_aranges! +*/ +int +_dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg, + 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; + + /* Used to chain Dwarf_Aranges structs. */ + Dwarf_Chain curr_chain, prev_chain, head_chain = NULL; + + Dwarf_Addr *arange_addrs; + Dwarf_Off *arange_offsets; + + int res; + + /* ***** BEGIN CODE ***** */ + + if (error != NULL) + *error = NULL; + + if (dbg == NULL) { + _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); + 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); + } + + arange_addrs = (Dwarf_Addr *) + _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); + } + arange_offsets = (Dwarf_Off *) + _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); + } + + 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); + } + *count = arange_count; + *offsets = arange_offsets; + *addrs = arange_addrs; + return (DW_DLV_OK); +} + + +/* + This function takes a pointer to a block + of Dwarf_Arange's, and a count of the + length of the block. It checks if the + given address is within the range of an + address range in the block. If yes, it + returns the appropriate Dwarf_Arange. + Otherwise, it returns DW_DLV_ERROR. +*/ +int +dwarf_get_arange(Dwarf_Arange * aranges, + Dwarf_Unsigned arange_count, + Dwarf_Addr address, + Dwarf_Arange * returned_arange, Dwarf_Error * error) +{ + Dwarf_Arange curr_arange; + Dwarf_Unsigned i; + + if (aranges == NULL) { + _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); + } + } + + return (DW_DLV_NO_ENTRY); +} + + +/* + This function takes an Dwarf_Arange, + and returns the offset of the first + die in the compilation-unit that the + arange belongs to. Returns DW_DLV_ERROR + on error. +*/ +int +dwarf_get_cu_die_offset(Dwarf_Arange arange, + Dwarf_Off * returned_offset, + Dwarf_Error * error) +{ + Dwarf_Debug dbg; + Dwarf_Off offset; + + if (arange == NULL) { + _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) { + int res = _dwarf_load_debug_info(dbg,error); + if(res != DW_DLV_OK) { + return res; + } + } + + *returned_offset = offset + _dwarf_length_of_cu_header(dbg, offset); + return DW_DLV_OK; +} + +/* + This function takes an Dwarf_Arange, + and returns the offset of the CU header + in the compilation-unit that the + arange belongs to. Returns DW_DLV_ERROR + on error. +*/ +int +dwarf_get_arange_cu_header_offset(Dwarf_Arange arange, + Dwarf_Off * cu_header_offset_returned, + Dwarf_Error * error) +{ + if (arange == NULL) { + _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); + return (DW_DLV_ERROR); + } + + *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 + address of the range in *start, the length of the + range in *length, and the offset of the first die + in the compilation-unit in *cu_die_offset. It + returns false on error. +*/ +int +dwarf_get_arange_info(Dwarf_Arange arange, + 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 (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) { + 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); +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_arange.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_arange.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,63 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +/* This structure is used to read an arange into. */ +struct Dwarf_Arange_s { + + /* 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. */ + Dwarf_Off ar_info_offset; + + /* Corresponding Dwarf_Debug. */ + Dwarf_Debug ar_dbg; +}; + + + +int + _dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg, + Dwarf_Addr ** addrs, + Dwarf_Off ** offsets, + Dwarf_Signed * count, + Dwarf_Error * error); diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_base_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_base_types.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,107 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "libdwarfdefs.h" + +#define true 1 +#define false 0 + +/* to identify a cie */ +#define DW_CIE_ID ~(0x0) +#define DW_CIE_VERSION 1 +#define ABBREV_HASH_TABLE_SIZE 10 + + +/* + 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 + +/* Maximum number of allocation types for allocation routines. */ +#define MAX_DW_DLA DW_DLA_WEAK_CONTEXT + +/*Dwarf_Word is unsigned word usable for index, count in memory */ +/*Dwarf_Sword is signed word usable for index, count in memory */ +/* The are 32 or 64 bits depending if 64 bit longs or not, which +** fits the ILP32 and LP64 models +** These work equally well with ILP64. +*/ + +typedef unsigned long Dwarf_Word; +typedef signed long Dwarf_Sword; + +typedef signed char Dwarf_Sbyte; +typedef unsigned char Dwarf_Ubyte; +typedef signed short Dwarf_Shalf; +typedef Dwarf_Small *Dwarf_Byte_Ptr; + +/* these 2 are fixed sizes which must not vary with the +** ILP32/LP64 model. Between these two, stay at 32 bit. +*/ +typedef __uint32_t Dwarf_ufixed; +typedef __int32_t Dwarf_sfixed; + +/* + In various places the code mistakenly associates + forms 8 bytes long with Dwarf_Signed or Dwarf_Unsigned + 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 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_Alloc_Hdr_s *Dwarf_Alloc_Hdr; diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_die_deliv.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_die_deliv.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,765 @@ +/* + + Copyright (C) 2000,2001,2002,2003 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#ifdef HAVE_ELF_H +#include +#endif +#include +#include "dwarf_die_deliv.h" + + +/* + For a given Dwarf_Debug dbg, this function checks + if a CU that includes the given offset has been read + or not. If yes, it returns the Dwarf_CU_Context + for the CU. Otherwise it returns NULL. Being an + internal routine, it is assumed that a valid dbg + is passed. + + **This is a sequential search. May be too slow. + + If debug_info and debug_abbrev not loaded, this will + wind up returning NULL. So no need to load before calling + this. +*/ +static Dwarf_CU_Context +_dwarf_find_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset) +{ + Dwarf_CU_Context cu_context; + + if (offset >= dbg->de_info_last_offset) + 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) { + + return (dbg->de_cu_context->cc_next); + } + + if (dbg->de_cu_context != NULL && + 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) { + + 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); + } + } + } + + for (cu_context = dbg->de_cu_context_list; + 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) { + + return (cu_context); + } + } + + return (NULL); +} + + +/* + This routine checks the dwarf_offdie() list of + CU contexts for the right CU context. +*/ +static Dwarf_CU_Context +_dwarf_find_offdie_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset) +{ + Dwarf_CU_Context cu_context; + + for (cu_context = dbg->de_offdie_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) + + return (cu_context); + + return (NULL); +} + + +/* + This function is used to create a CU Context for + a compilation-unit that begins at offset in + .debug_info. The CU Context is attached to the + list of CU Contexts for this dbg. It is assumed + that the CU at offset has not been read before, + and so do not call this routine before making + sure of this with _dwarf_find_CU_Context(). + Returns NULL on error. As always, being an + internal routine, assumes a good dbg. + + This function must always set a dwarf error code + before returning NULL. Always. +*/ +static Dwarf_CU_Context +_dwarf_make_CU_Context(Dwarf_Debug dbg, + Dwarf_Off offset, Dwarf_Error * error) +{ + Dwarf_CU_Context cu_context; + Dwarf_Unsigned length; + Dwarf_Signed abbrev_offset; + Dwarf_Byte_Ptr cu_ptr; + int local_extension_size = 0; + int local_length_size; + + cu_context = + (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); + } + cu_context->cc_dbg = dbg; + + cu_ptr = (Dwarf_Byte_Ptr) (dbg->de_debug_info + 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_context->cc_length_size = local_length_size; + cu_context->cc_extension_size = local_extension_size; + + + 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); + + READ_UNALIGNED(dbg, abbrev_offset, Dwarf_Signed, + 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)) { + + _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) { + _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); + } + + cu_context->cc_abbrev_hash_table = + (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); + } + + cu_context->cc_debug_info_offset = (Dwarf_Word) offset; + dbg->de_info_last_offset = + (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; + } else { + dbg->de_cu_context_list_end->cc_next = cu_context; + dbg->de_cu_context_list_end = cu_context; + } + + return (cu_context); +} + + +/* + Returns offset of next compilation-unit thru next_cu_offset + pointer. + It basically sequentially moves from one + cu to the next. The current cu is recorded + internally by libdwarf. +*/ +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) +{ + /* Offset for current and new CU. */ + Dwarf_Unsigned new_offset; + + /* CU Context for current CU. */ + Dwarf_CU_Context cu_context; + + /* ***** BEGIN CODE ***** */ + + if (dbg == NULL) { + _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); + + 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; + } + + /* + Check that there is room in .debug_info beyond the new offset + for at least a new cu header. If not, return 0 to indicate end + 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); + } + + /* Check if this CU has been read before. */ + cu_context = _dwarf_find_CU_Context(dbg, new_offset); + + /* 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); + } + } + + dbg->de_cu_context = cu_context; + + if (cu_header_length != NULL) + *cu_header_length = cu_context->cc_length; + + if (version_stamp != NULL) + *version_stamp = cu_context->cc_version_stamp; + + if (abbrev_offset != NULL) + *abbrev_offset = cu_context->cc_abbrev_offset; + + if (address_size != NULL) + *address_size = cu_context->cc_address_size; + + new_offset = new_offset + cu_context->cc_length + + cu_context->cc_length_size + cu_context->cc_extension_size; + *next_cu_offset = new_offset; + return (DW_DLV_OK); +} + + +/* + This function does two slightly different things + depending on the input flag want_AT_sibling. If + this flag is true, it checks if the input die has + a DW_AT_sibling attribute. If it does it returns + a pointer to the start of the sibling die in the + .debug_info section. Otherwise it behaves the + same as the want_AT_sibling false case. + + If the want_AT_sibling flag is false, it returns + a pointer to the immediately adjacent die in the + .debug_info section. + + Die_info_end points to the end of the .debug_info + portion for the cu the die belongs to. It is used + to check that the search for the next die does not + cross the end of the current cu. Cu_info_start points + to the start of the .debug_info portion for the + current cu, and is used to add to the offset for + DW_AT_sibling attributes. Finally, has_die_child + is a pointer to a Dwarf_Bool that is set true if + the present die has children, false otherwise. + 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. +*/ +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_Byte_Ptr info_ptr; + Dwarf_Byte_Ptr abbrev_ptr; + Dwarf_Word abbrev_code; + 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; + + info_ptr = die_info_ptr; + DECODE_LEB128_UWORD(info_ptr, utmp) + abbrev_code = (Dwarf_Word) utmp; + if (abbrev_code == 0) { + return NULL; + } + + abbrev_list = _dwarf_get_abbrev_for_code(cu_context, abbrev_code); + if (abbrev_list == NULL) { + return (NULL); + } + dbg = cu_context->cc_dbg; + + *has_die_child = abbrev_list->ab_has_child; + + abbrev_ptr = abbrev_list->ab_abbrev_ptr; + 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; + 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; + + } + + 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); + } + + /* 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); + } + } + + 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); + } + } + } while (attr != 0 || attr_form != 0); + + return (info_ptr); +} + + +/* + Given a Dwarf_Debug dbg, and a Dwarf_Die die, it returns + a Dwarf_Die for the sibling of die. In case die is NULL, + it returns (thru ptr) a Dwarf_Die for the first die in the current + cu in dbg. Returns DW_DLV_ERROR on error. + + It is assumed that every sibling chain including those with + only one element is terminated with a NULL die, except a + chain with only a NULL die. + + The algorithm moves from one die to the adjacent one. It + returns when the depth of children it sees equals the number + of sibling chain terminations. A single count, child_depth + is used to track the depth of children and sibling terminations + encountered. Child_depth is incremented when a die has the + Has-Child flag set unless the child happens to be a NULL die. + Child_depth is decremented when a die has Has-Child false, + and the adjacent die is NULL. Algorithm returns when + child_depth is 0. + + **NOTE: Do not modify input die, since it is used at the end. +*/ +int +dwarf_siblingof(Dwarf_Debug dbg, + Dwarf_Die die, + Dwarf_Die * caller_ret_die, Dwarf_Error * error) +{ + Dwarf_Die ret_die; + Dwarf_Byte_Ptr die_info_ptr; + Dwarf_Byte_Ptr cu_info_start = 0; + Dwarf_Byte_Ptr die_info_end = 0; + Dwarf_Half abbrev_code; + Dwarf_Unsigned utmp; + + + if (dbg == NULL) { + _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; + + /* 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); + } + + 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) + + 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 && has_child) { + die_info_ptr++; + has_child = false; + } + + 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); + } + + if (die != NULL && die_info_ptr >= die_info_end) { + return (DW_DLV_NO_ENTRY); + } + + if ((*die_info_ptr) == 0) { + 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); + } + + ret_die->di_debug_info_ptr = die_info_ptr; + ret_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; + if (abbrev_code == 0) { + /* Zero means a null DIE */ + return (DW_DLV_NO_ENTRY); + } + ret_die->di_abbrev_list = + _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); + } + + *caller_ret_die = ret_die; + return (DW_DLV_OK); +} + + +int +dwarf_child(Dwarf_Die die, + 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_Debug dbg; + Dwarf_Half abbrev_code; + Dwarf_Unsigned utmp; + + + 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); + + 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_ptr = + _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); + } + + if (!has_die_child) + 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); + } + 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; + 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; + } + ret_die->di_abbrev_list = + _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); + } + + *caller_ret_die = ret_die; + return (DW_DLV_OK); +} + +/* + 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); +*/ +int +dwarf_offdie(Dwarf_Debug dbg, + Dwarf_Off offset, Dwarf_Die * new_die, Dwarf_Error * error) +{ + Dwarf_CU_Context cu_context; + Dwarf_Off new_cu_offset = 0; + Dwarf_Die die; + Dwarf_Byte_Ptr info_ptr; + Dwarf_Half abbrev_code; + Dwarf_Unsigned utmp; + + if (dbg == NULL) { + _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); + + if (cu_context == NULL) { + int res = _dwarf_load_debug_info(dbg, error); + + 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; + + 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. */ + + return (DW_DLV_ERROR); + } + + 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; + } + + 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); + } + die->di_cu_context = cu_context; + + info_ptr = dbg->de_debug_info + offset; + die->di_debug_info_ptr = info_ptr; + DECODE_LEB128_UWORD(info_ptr, utmp) + abbrev_code = (Dwarf_Half) utmp; + if (abbrev_code == 0) { + /* we are at a null DIE (or there is a bug). */ + *new_die = 0; + return DW_DLV_NO_ENTRY; + } + + die->di_abbrev_list = + _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); + } + + *new_die = die; + return (DW_DLV_OK); +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_die_deliv.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_die_deliv.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,56 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + + +/* + This struct holds information about a abbreviation. + It is put in the hash table for abbreviations for + a compile-unit. +*/ +struct Dwarf_Abbrev_List_s { + + Dwarf_Word ab_code; + Dwarf_Half ab_tag; + Dwarf_Half ab_has_child; + + /* + Points to start of attribute and form pairs in the .debug_abbrev + section for the abbrev. */ + Dwarf_Byte_Ptr ab_abbrev_ptr; + + struct Dwarf_Abbrev_List_s *ab_next; +}; diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_error.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_error.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,378 @@ +/* + + Copyright (C) 2000, 2002 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#ifdef HAVE_ELF_H +#include +#endif + +#include +#include +#include +#include + +/* Array to hold string representation of errors. Any time a + define is added to the list in libdwarf.h, a string should be + added to this Array +*/ + +const char *_dwarf_errmsgs[] = { + + "No error (0)\n", + "DW_DLE_VMM 1 dwarf format/library version mismatch", + "DW_DLE_MAP 2 memory map failure", + "DW_DLE_LEE 3 libelf error", + "DW_DLE_NDS 4 no debug section", + "DW_DLE_NLS 5 no line section ", + "DW_DLE_ID 6 invalid descriptor for query ", + "DW_DLE_IOF 7 I/O failure ", + "DW_DLE_MAF 8 memory allocation failure ", + "DW_DLE_IA 9 invalid argument ", + "DW_DLE_MDE 10 mangled debugging entry ", + "DW_DLE_MLE 11 mangled line number entry ", + "DW_DLE_FNO 12 file not open ", + "DW_DLE_FNR 13 file not a regular file ", + "DW_DLE_FWA 14 file open with wrong access ", + "DW_DLE_NOB 15 not an object file ", + "DW_DLE_MOF 16 mangled object file header ", + "DW_DLE_EOLL 17 end of location list entries ", + "DW_DLE_NOLL 18 no location list section ", + "DW_DLE_BADOFF 19 Invalid offset ", + "DW_DLE_EOS 20 end of section ", + "DW_DLE_ATRUNC 21 abbreviations section appears truncated", + "DW_DLE_BADBITC 22 Address size passed to dwarf bad", + + "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", + "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", + "DW_DLE_INIT_ACCESS_WRONG 26 A call to dwarf_init had an " + "access of other than DW_DLC_READ", + "DW_DLE_ELF_BEGIN_ERROR 27 a call to " + "elf_begin(... ELF_C_READ_MMAP... ) failed", + "DW_DLE_ELF_GETEHDR_ERROR 28 a call to " + "elf32_getehdr() or elf64_getehdr() failed", + "DW_DLE_ELF_GETSHDR_ERROR 29 a call to " + "elf32_getshdr() or elf64_getshdr() failed", + "DW_DLE_ELF_STRPTR_ERROR 30 a call to " + "elf_strptr() failed trying to get a section name", + "DW_DLE_DEBUG_INFO_DUPLICATE 31 Only one .debug_info " + "section is allowed", + "DW_DLE_DEBUG_INFO_NULL 32 .debug_info section present but " + "elf_getdata() failed or section is zero-length", + "DW_DLE_DEBUG_ABBREV_DUPLICATE 33 Only one .debug_abbrev " + "section is allowed", + "DW_DLE_DEBUG_ABBREV_NULL 34 .debug_abbrev section present but " + "elf_getdata() failed or section is zero-length", + "DW_DLE_DEBUG_ARANGES_DUPLICATE 35 Only one .debug_aranges " + "section is allowed", + "DW_DLE_DEBUG_ARANGES_NULL 36 .debug_aranges section present but " + "elf_getdata() failed or section is zero-length", + "DW_DLE_DEBUG_LINE_DUPLICATE 37 Only one .debug_line " + "section is allowed", + "DW_DLE_DEBUG_LINE_NULL (38) .debug_line section present but " + "elf_getdata() failed or section is zero-length", + "DW_DLE_DEBUG_LOC_DUPLICATE (39) Only one .debug_loc " + "section is allowed", + "DW_DLE_DEBUG_LOC_NULL (40) .debug_loc section present but " + "elf_getdata() failed or section is zero-length", + "DW_DLE_DEBUG_MACINFO_DUPLICATE (41) Only one .debug_macinfo " + "section is allowed", + "DW_DLE_DEBUG_MACINFO_NULL (42) .debug_macinfo section present but " + "elf_getdata() failed or section is zero-length", + "DW_DLE_DEBUG_PUBNAMES_DUPLICATE (43) Only one .debug_pubnames " + "section is allowed", + "DW_DLE_DEBUG_PUBNAMES_NULL (44) .debug_pubnames section present but " + "elf_getdata() failed or section is zero-length", + "DW_DLE_DEBUG_STR_DUPLICATE (45) Only one .debug_str " + "section is allowed", + "DW_DLE_DEBUG_STR_NULL (46) .debug_str section present but " + "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)", + "DW_DLE_ADDRESS_SIZE_ERROR (50)", + "DW_DLE_DEBUG_INFO_PTR_NULL (51)", + "DW_DLE_DIE_NULL (52)", + "DW_DLE_STRING_OFFSET_BAD (53)", + "DW_DLE_DEBUG_LINE_LENGTH_BAD (54)", + "DW_DLE_LINE_PROLOG_LENGTH_BAD (55)", + "DW_DLE_LINE_NUM_OPERANDS_BAD", + "DW_DLE_LINE_SET_ADDR_ERROR", + "DW_DLE_LINE_EXT_OPCODE_BAD", + "DW_DLE_DWARF_LINE_NULL", + "DW_DLE_INCL_DIR_NUM_BAD", + "DW_DLE_LINE_FILE_NUM_BAD", + "DW_DLE_ALLOC_FAIL", + "DW_DLE_NO_CALLBACK_FUNC", + "DW_DLE_SECT_ALLOC", + "DW_DLE_FILE_ENTRY_ALLOC", + "DW_DLE_LINE_ALLOC", + "DW_DLE_FPGM_ALLOC", + "DW_DLE_INCDIR_ALLOC", + "DW_DLE_STRING_ALLOC", + "DW_DLE_CHUNK_ALLOC", + "DW_DLE_BYTEOFF_ERR", + "DW_DLE_CIE_ALLOC", + "DW_DLE_FDE_ALLOC", + "DW_DLE_REGNO_OVFL", + "DW_DLE_CIE_OFFS_ALLOC", + "DW_DLE_WRONG_ADDRESS", + "DW_DLE_EXTRA_NEIGHBORS", + "DW_DLE_WRONG_TAG", + "DW_DLE_DIE_ALLOC", + "DW_DLE_PARENT_EXISTS", + "DW_DLE_DBG_NULL", + "DW_DLE_DEBUGLINE_ERROR", + "DW_DLE_DEBUGFRAME_ERROR", + "DW_DLE_DEBUGINFO_ERROR", + "DW_DLE_ATTR_ALLOC", + "DW_DLE_ABBREV_ALLOC", + "DW_DLE_OFFSET_UFLW", + "DW_DLE_ELF_SECT_ERR", + "DW_DLE_DEBUG_FRAME_LENGTH_BAD", + "DW_DLE_FRAME_VERSION_BAD", + "DW_DLE_CIE_RET_ADDR_REG_ERROR", + "DW_DLE_FDE_NULL", + "DW_DLE_FDE_DBG_NULL", + "DW_DLE_CIE_NULL", + "DW_DLE_CIE_DBG_NULL", + "DW_DLE_FRAME_TABLE_COL_BAD", + "DW_DLE_PC_NOT_IN_FDE_RANGE", + "DW_DLE_CIE_INSTR_EXEC_ERROR", + "DW_DLE_FRAME_INSTR_EXEC_ERROR", + "DW_DLE_FDE_PTR_NULL", + "DW_DLE_RET_OP_LIST_NULL", + "DW_DLE_LINE_CONTEXT_NULL", + "DW_DLE_DBG_NO_CU_CONTEXT", + "DW_DLE_DIE_NO_CU_CONTEXT", + "DW_DLE_FIRST_DIE_NOT_CU", + "DW_DLE_NEXT_DIE_PTR_NULL", + "DW_DLE_DEBUG_FRAME_DUPLICATE Only one .debug_frame " + "section is allowed", + "DW_DLE_DEBUG_FRAME_NULL .debug_frame section present but " + "elf_getdata() failed or section is zero-length", + "DW_DLE_ABBREV_DECODE_ERROR", + "DW_DLE_DWARF_ABBREV_NULL", + "DW_DLE_ATTR_NULL", + "DW_DLE_DIE_BAD", + "DW_DLE_DIE_ABBREV_BAD", + "DW_DLE_ATTR_FORM_BAD", + "DW_DLE_ATTR_NO_CU_CONTEXT", + "DW_DLE_ATTR_FORM_SIZE_BAD", + "DW_DLE_ATTR_DBG_NULL", + "DW_DLE_BAD_REF_FORM", + "DW_DLE_ATTR_FORM_OFFSET_BAD", + "DW_DLE_LINE_OFFSET_BAD", + "DW_DLE_DEBUG_STR_OFFSET_BAD", + "DW_DLE_STRING_PTR_NULL", + "DW_DLE_PUBNAMES_VERSION_ERROR", + "DW_DLE_PUBNAMES_LENGTH_BAD", + "DW_DLE_GLOBAL_NULL", + "DW_DLE_GLOBAL_CONTEXT_NULL", + "DW_DLE_DIR_INDEX_BAD", + "DW_DLE_LOC_EXPR_BAD", + "DW_DLE_DIE_LOC_EXPR_BAD", + "DW_DLE_ADDR_ALLOC", + "DW_DLE_OFFSET_BAD", + "DW_DLE_MAKE_CU_CONTEXT_FAIL", + "DW_DLE_REL_ALLOC", + "DW_DLE_ARANGE_OFFSET_BAD", + "DW_DLE_SEGMENT_SIZE_BAD", + "DW_DLE_ARANGE_LENGTH_BAD", + "DW_DLE_ARANGE_DECODE_ERROR", + "DW_DLE_ARANGES_NULL", + "DW_DLE_ARANGE_NULL", + "DW_DLE_NO_FILE_NAME", + "DW_DLE_NO_COMP_DIR", + "DW_DLE_CU_ADDRESS_SIZE_BAD", + "DW_DLE_INPUT_ATTR_BAD", + "DW_DLE_EXPR_NULL", + "DW_DLE_BAD_EXPR_OPCODE", + "DW_DLE_EXPR_LENGTH_BAD", + "DW_DLE_MULTIPLE_RELOC_IN_EXPR", + "DW_DLE_ELF_GETIDENT_ERROR", + "DW_DLE_NO_AT_MIPS_FDE", + "DW_DLE_NO_CIE_FOR_FDE", + "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", + "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", + "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", + "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", + + "DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR", + "DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD", + "DW_DLE_WEAK_NULL", + "DW_DLE_WEAK_CONTEXT_NULL (175)", + "DW_DLE_LOCDESC_COUNT_WRONG (176)", + "DW_DLE_MACINFO_STRING_NULL (177)", + "DW_DLE_MACINFO_STRING_EMPTY (178)", + "DW_DLE_MACINFO_INTERNAL_ERROR_SPACE (179)", + "DW_DLE_MACINFO_MALLOC_FAIL (180)", + "DW_DLE_DEBUGMACINFO_ERROR (181)", + "DW_DLE_DEBUG_MACRO_LENGTH_BAD (182)", + "DW_DLE_DEBUG_MACRO_MAX_BAD (183)", + "DW_DLE_DEBUG_MACRO_INTERNAL_ERR (184)", + "DW_DLE_DEBUG_MACRO_MALLOC_SPACE (185)", + "DW_DLE_DEBUG_MACRO_INCONSISTENT (186)", + "DW_DLE_DF_NO_CIE_AUGMENTATION(187)", + "DW_DLE_DF_REG_NUM_TOO_HIGH(188)", + "DW_DLE_DF_MAKE_INSTR_NO_INIT(189)", + "DW_DLE_DF_NEW_LOC_LESS_OLD_LOC(190)", + "DW_DLE_DF_POP_EMPTY_STACK(191)", + "DW_DLE_DF_ALLOC_FAIL(192)", + "DW_DLE_DF_FRAME_DECODING_ERROR(193)", + + + +}; + + + + +/* + This function performs error handling as described in the + libdwarf consumer document section 3. Dbg is the Dwarf_debug + structure being processed. Error is a pointer to the pointer + to the error descriptor that will be returned. Errval is an + error code listed in dwarf_error.h. +*/ +void +_dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Sword 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 (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(); + } + } + + 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; + } + fprintf(stderr, + "abort() in libdwarf. No error argument, no handler.\n"); + abort(); +} + + +Dwarf_Unsigned +dwarf_errno(Dwarf_Error error) +{ + if (error == NULL) { + return (0); + } + + return (error->er_errval); +} + + +/* +*/ +char * +dwarf_errmsg(Dwarf_Error error) +{ + if (error == NULL) { + return "Dwarf_Error is NULL"; + } + + if (error->er_errval > (sizeof(_dwarf_errmsgs) / sizeof(char *))) { + return "Dwarf_Error value out of range"; + } + + return ((char *) _dwarf_errmsgs[error->er_errval]); +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_error.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_error.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,43 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +void _dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error, + Dwarf_Sword errval); + +struct Dwarf_Error_s { + Dwarf_Sword er_errval; +}; diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_form.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_form.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,694 @@ +/* + + Copyright (C) 2000, 2002 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include "dwarf_die_deliv.h" + +int +dwarf_hasform(Dwarf_Attribute attr, + Dwarf_Half form, + Dwarf_Bool * return_bool, Dwarf_Error * error) +{ + Dwarf_CU_Context cu_context; + + 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); + } + + *return_bool = (attr->ar_attribute_form == form); + return DW_DLV_OK; +} + +/* Not often called, we do not worry about efficiency here. + The dwarf_whatform() call does the sanity checks for us. +*/ +int +dwarf_whatform_direct(Dwarf_Attribute attr, + Dwarf_Half * return_form, Dwarf_Error * error) +{ + int res = dwarf_whatform(attr, return_form, error); + + if (res != DW_DLV_OK) { + return res; + } + + *return_form = attr->ar_attribute_form_direct; + return (DW_DLV_OK); +} + +int +dwarf_whatform(Dwarf_Attribute attr, + Dwarf_Half * return_form, Dwarf_Error * error) +{ + Dwarf_CU_Context cu_context; + + 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); + } + + *return_form = attr->ar_attribute_form; + return (DW_DLV_OK); +} + + +/* + This function is analogous to dwarf_whatform. + It returns the attribute in attr instead of + the form. +*/ +int +dwarf_whatattr(Dwarf_Attribute attr, + Dwarf_Half * return_attr, Dwarf_Error * error) +{ + Dwarf_CU_Context cu_context; + + 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); + } + + *return_attr = (attr->ar_attribute); + return DW_DLV_OK; +} + + +/* + 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. + + 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(); + +*/ +int +dwarf_formref(Dwarf_Attribute attr, + Dwarf_Off * ret_offset, Dwarf_Error * error) +{ + Dwarf_Debug dbg; + Dwarf_Unsigned offset; + Dwarf_CU_Context cu_context; + + + 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; + + switch (attr->ar_attribute_form) { + + case DW_FORM_ref1: + 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; + + case DW_FORM_ref4: + 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; + + case DW_FORM_ref_udata: + 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); + } + + /* 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); + } + + *ret_offset = (offset); + return DW_DLV_OK; +} + +/* + Since this returns section-relative debug_info offsets, + this can represent all REFERENCE forms correctly + and allows all forms. + +*/ +int +dwarf_global_formref(Dwarf_Attribute attr, + Dwarf_Off * ret_offset, Dwarf_Error * error) +{ + Dwarf_Debug dbg; + Dwarf_Unsigned offset; + Dwarf_Addr ref_addr; + Dwarf_CU_Context cu_context; + + 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; + + switch (attr->ar_attribute_form) { + + case DW_FORM_ref1: + 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; + + case DW_FORM_ref4: + 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; + + case DW_FORM_ref_udata: + offset = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL); + + 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); + } + + /* globalize the offset */ + offset += cu_context->cc_debug_info_offset; + 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; + default: + _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); + return DW_DLV_OK; +} + + +int +dwarf_formaddr(Dwarf_Attribute attr, + Dwarf_Addr * return_addr, Dwarf_Error * error) +{ + Dwarf_Debug dbg; + Dwarf_Addr ret_addr; + Dwarf_CU_Context cu_context; + + 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_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. */ + ) { + + READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr, + attr->ar_debug_info_ptr, dbg->de_pointer_size); + *return_addr = ret_addr; + return (DW_DLV_OK); + } + + _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); +} + + +int +dwarf_formflag(Dwarf_Attribute attr, + Dwarf_Bool * ret_bool, Dwarf_Error * error) +{ + Dwarf_CU_Context cu_context; + + 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); + } + + if (attr->ar_attribute_form == DW_FORM_flag) { + *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); +} + + +int +dwarf_formudata(Dwarf_Attribute attr, + Dwarf_Unsigned * return_uval, Dwarf_Error * error) +{ + Dwarf_Unsigned ret_value; + Dwarf_Debug dbg; + Dwarf_CU_Context cu_context; + + 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); + } + + 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; + + 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; + } + + 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; + } + + 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; + } + + case DW_FORM_udata: + 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 */ + + + default: + break; + } + _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); +} + + +int +dwarf_formsdata(Dwarf_Attribute attr, + Dwarf_Signed * return_sval, Dwarf_Error * error) +{ + Dwarf_Signed ret_value; + Dwarf_Debug dbg; + Dwarf_CU_Context cu_context; + + 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); + } + + switch (attr->ar_attribute_form) { + + case DW_FORM_data1: + *return_sval = (*(Dwarf_Sbyte *) attr->ar_debug_info_ptr); + return DW_DLV_OK; + + 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; + + } + + 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; + } + + 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; + } + + case DW_FORM_sdata: + 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 */ + + + default: + break; + } + _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); +} + + +int +dwarf_formblock(Dwarf_Attribute attr, + 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; + + 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; + + 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; + + 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; + + 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; + + 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; + + default: + _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); + } + + 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); + } + + 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; + + + *return_block = ret_block; + return (DW_DLV_OK); +} + + +int +dwarf_formstring(Dwarf_Attribute attr, + char **return_str, Dwarf_Error * error) +{ + Dwarf_CU_Context cu_context; + Dwarf_Debug dbg; + Dwarf_Unsigned offset; + int res; + + 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_string) { + + 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 (attr->ar_attribute_form == DW_FORM_strp) { + 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; + } + + _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_frame.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_frame.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,2448 @@ +/* + + Copyright (C) 2000, 2002 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include +#include "dwarf_frame.h" +#include "dwarf_arange.h" /* using Arange as a way to build a + list */ + + +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); + +/* + This function is the heart of the debug_frame stuff. Don't even + think of reading this without reading both the Libdwarf and + consumer API carefully first. This function basically executes + frame instructions contained in a Cie or an Fde, but does in a + number of different ways depending on the information sought. + Start_instr_ptr points to the first byte of the frame instruction + stream, and final_instr_ptr to the to the first byte after the + last. + + The offsets returned in the frame instructions are factored. That + is they need to be multiplied by either the code_alignment_factor + or the data_alignment_factor, as appropriate to obtain the actual + offset. This makes it possible to expand an instruction stream + without the corresponding Cie. However, when an Fde frame instr + sequence is being expanded there must be a valid Cie with a pointer + to an initial table row. + + + 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...) + If unsuccessful, returns DW_DLV_ERROR + 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. + + (1) If make_instr is true, it makes a list of pointers to + Dwarf_Frame_Op structures containing the frame instructions + executed. A pointer to this list is returned in ret_frame_instr. + Make_instr is true only when a list of frame instructions is to be + returned. In this case since we are not interested in the contents + of the table, the input Cie can be NULL. This is the only case + where the inpute Cie can be NULL. + + (2) If search_pc is true, frame instructions are executed till + either a location is reached that is greater than the search_pc_val + provided, or all instructions are executed. At this point the + last row of the table generated is returned in a structure. + A pointer to this structure is supplied in table. + + (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. +*/ +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) +{ + /* Sweeps the frame instructions. */ + Dwarf_Small *instr_ptr; + + /* Obvious from the documents. */ + Dwarf_Small instr, opcode; + Dwarf_Small reg_no, reg_noA, reg_noB; + 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 */ + + struct Dwarf_Reg_Rule_s reg[DW_FRAME_LAST_REG_NUM]; + + + /* This is used to end executing frame instructions. */ + /* Becomes true when search_pc is true and loc */ + /* is greater than search_pc_val. */ + Dwarf_Bool search_over = false; + + /* Used by the DW_FRAME_advance_loc instr */ + /* to hold the increment in pc value. */ + Dwarf_Addr adv_pc; + + /* Contains the length in bytes of */ + /* an leb128 encoded number. */ + Dwarf_Word leb128_length; + + /* Counts the number of frame instructions executed. */ + Dwarf_Word instr_count = 0; + + /* + These contain the current fields of the current frame + instruction. */ + Dwarf_Small fp_base_op = 0; + Dwarf_Small fp_extended_op; + Dwarf_Half fp_register; + Dwarf_Unsigned fp_offset; + Dwarf_Off fp_instr_offset; + + /* + 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 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 + Dwarf_Frame_Op structs executed. */ + Dwarf_Frame_Op *curr_instr; + Dwarf_Chain curr_instr_item, dealloc_instr_item; + Dwarf_Chain head_instr_chain = NULL; + Dwarf_Chain tail_instr_chain = NULL; + Dwarf_Frame_Op *head_instr_block; + + /* + These are the alignment_factors taken from the Cie provided. + When no input Cie is provided they are set to 1, because only + factored offsets are required. */ + Dwarf_Sword code_alignment_factor = 1; + Dwarf_Sword data_alignment_factor = 1; + + /* + This flag indicates when an actual alignment factor is needed. + So if a frame instruction that computes an offset using an + alignment factor is encountered when this flag is set, an error + is returned because the Cie did not have a valid augmentation. */ + Dwarf_Bool need_augmentation = false; + + Dwarf_Word i; + + /* 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; + + + 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; + } + } + + /* + 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. */ + 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; + + instr_ptr = start_instr_ptr; + while ((instr_ptr < final_instr_ptr) && (!search_over)) { + + + 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) { + + *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION); + return DW_DLV_ERROR; + } + adv_pc = adv_pc * code_alignment_factor; + + 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; + } + + 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; + } + + 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) { + *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; + + break; + } + + 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; + } + + fp_register = reg_no; + + 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; + } + + 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); + + /* 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); + + /* 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); + + /* If gone past pc needed, retain old pc. */ + if (!search_over) + loc = 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) { + *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); + + /* If gone past pc needed, retain old pc. */ + if (!search_over) + loc = loc + adv_loc; + break; + } + + case DW_CFA_offset_extended:{ + 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[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; + } + + case DW_CFA_restore_extended:{ + 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; + } + + 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; + } + } + + fp_register = reg_no; + break; + } + + case DW_CFA_undefined:{ + 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[reg_no].ru_is_off = 0; + reg[reg_no].ru_register = DW_FRAME_UNDEFINED_VAL; + reg[reg_no].ru_offset = 0; + + fp_register = reg_no; + break; + } + + case DW_CFA_same_value:{ + 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[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; + } + + case DW_CFA_register:{ + Dwarf_Unsigned lreg; + + DECODE_LEB128_UWORD(instr_ptr, lreg) + reg_noA = (Dwarf_Small) lreg; + + 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_noB = (Dwarf_Small) lreg; + + if (reg_noB > DW_FRAME_LAST_REG_NUM) { + *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH); + return DW_DLV_ERROR; + } + + + 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; + } +#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; + + DECODE_LEB128_UWORD(instr_ptr, lreg) + reg_no = (Dwarf_Small) lreg; + + break; + } +#endif + } + + 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->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->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 (instr_ptr > final_instr_ptr) { + *returned_error = (DW_DLE_DF_FRAME_DECODING_ERROR); + return DW_DLV_ERROR; + } + + /* Create the last row generated. */ + 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; + } + } + + /* 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); + } + + 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; + } + + /* + 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; + } else { + *returned_count = 0; + } + 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; +} + +/* + * 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) +{ + 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; + + + /* READ_AREA_LENGTH updates cie_ptr for consumed bytes */ + READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned, + cie_ptr, local_length_size, local_extension_size); + + + + /* 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; +} + +int +dwarf_get_cie_of_fde(Dwarf_Fde fde, + Dwarf_Cie * cie_returned, Dwarf_Error * error) +{ + if (fde == NULL) { + _dwarf_error(NULL, error, DW_DLE_FDE_NULL); + return (DW_DLV_ERROR); + } + + *cie_returned = fde->fd_cie; + 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. + Or 0 if this is a true cie. + Non standard dwarf, designed this way to be + convenient at run time for an allocated + (mapped into memory as part of the running image) section. +*/ +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) +{ + int res; + + res = + _dwarf_load_section(dbg, + dbg->de_debug_frame_eh_gnu_index, + &dbg->de_debug_frame_eh_gnu, + error); + + if (res != DW_DLV_OK) { + 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); + return res; +} + + + +/* + For standard dwarf .debug_frame + cie_id is -1 in a cie, and + is the section offset in the .debug_frame section + of the cie otherwise. Standard dwarf +*/ +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) +{ + int res; + + res = + _dwarf_load_section(dbg, + dbg->de_debug_frame_index, + &dbg->de_debug_frame, + error); + + if (res != DW_DLV_OK) { + 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); + 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 +*/ +int +dwarf_get_fde_for_die(Dwarf_Debug dbg, + 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; + + /* 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; + + + Dwarf_Word leb128_length; + + if (die == NULL) { + _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; + } + + /* why is this formsdata? FIX */ + sdatares = dwarf_formsdata(attr, &signdval, error); + if (sdatares != DW_DLV_OK) { + return sdatares; + } + + res = + _dwarf_load_section(dbg, + dbg->de_debug_frame_index, + &dbg->de_debug_frame, + error); + if (res != DW_DLV_OK) { + 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); + + + if (length % cie_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, + 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; + + 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; + + 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 { + /* 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; + } else { + _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; +} + + +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) +{ + int res; + Dwarf_Debug dbg; + + 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); + } + + res = + _dwarf_load_section(dbg, + dbg->de_debug_frame_index, + &dbg->de_debug_frame, + error); + if (res != DW_DLV_OK) { + return res; + } + + if (low_pc != NULL) + *low_pc = fde->fd_initial_location; + if (func_length != NULL) + *func_length = fde->fd_address_range; + if (fde_bytes != NULL) + *fde_bytes = fde->fd_fde_start; + if (fde_byte_length != NULL) + *fde_byte_length = fde->fd_length; + if (cie_offset != NULL) + *cie_offset = fde->fd_cie_offset; + if (cie_index != NULL) + *cie_index = fde->fd_cie_index; + if (fde_offset != NULL) + *fde_offset = fde->fd_fde_start - dbg->de_debug_frame; + + return DW_DLV_OK; +} + +int +dwarf_get_fde_exception_info(Dwarf_Fde fde, + 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); + } + *offset_into_exception_tables = + fde->fd_offset_into_exception_tables; + return DW_DLV_OK; +} + + +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_Debug dbg; + + if (cie == NULL) { + _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); + } + + if (version != NULL) + *version = DW_CIE_VERSION; + if (augmenter != NULL) + *augmenter = cie->ci_augmentation; + if (code_alignment_factor != NULL) + *code_alignment_factor = cie->ci_code_alignment_factor; + if (data_alignment_factor != NULL) + *data_alignment_factor = cie->ci_data_alignment_factor; + if (return_address_register != NULL) + *return_address_register = cie->ci_return_address_register; + if (initial_instructions != NULL) + *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); + + } + *bytes_in_cie = (cie->ci_length); + return (DW_DLV_OK); +} + +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_Debug dbg; + Dwarf_Cie cie; + Dwarf_Sword i; + int dw_err; + Dwarf_Sword icount; + int res; + + 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); + } + + 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); + } + + 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; + } + + 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; + } + } + + 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); + if (res == DW_DLV_ERROR) { + _dwarf_error(dbg, error, dw_err); + return (res); + } else if (res == DW_DLV_NO_ENTRY) { + return res; + } + + return DW_DLV_OK; +} + +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) +{ + + struct Dwarf_Frame_s fde_table; + Dwarf_Sword i; + int 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); + if (res != DW_DLV_OK) { + 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; + } + + if (row_pc != NULL) + *row_pc = fde_table.fr_loc; + + return DW_DLV_OK; +} + + +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) +{ + struct Dwarf_Frame_s fde_table; + int res; + + + if (table_column > DW_FRAME_LAST_REG_NUM) { + _dwarf_error(NULL, 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); + if (res != DW_DLV_OK) { + 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; + + *offset_relevant = (fde_table.fr_reg[table_column].ru_is_off); + return DW_DLV_OK; +} + +/* + 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 len; + unsigned char *instrs; + Dwarf_Debug dbg; + + if (inFde == NULL) { + _dwarf_error(NULL, 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); + } + + 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; +} + +int +dwarf_get_fde_n(Dwarf_Fde * fde_data, + Dwarf_Unsigned fde_index, + Dwarf_Fde * returned_fde, Dwarf_Error * error) +{ + Dwarf_Debug dbg; + + 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); + } + + 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); + } + *returned_fde = (*(fde_data + fde_index)); + return DW_DLV_OK; +} + + +/* + Lopc and hipc are extensions to the interface to + return the range of addresses that are described + by the returned fde. +*/ +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_Debug dbg; + Dwarf_Fde fde = NULL; + + 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); + } + + 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; + + 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); + } + + return (DW_DLV_NO_ENTRY); +} + + +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_Sword instr_count; + int res; + int dw_err; + + if (dbg == 0) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + + if (returned_op_list == 0 || returned_op_count == 0) { + _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 + as it is just an i_length offset from 'instruction' itself. A + 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); + if (res != DW_DLV_OK) { + if (res == DW_DLV_ERROR) { + _dwarf_error(dbg, error, dw_err); + } + return (res); + } + + *returned_op_count = instr_count; + return DW_DLV_OK; +} + + + +/* + 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 +*/ +/* 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) +{ + int res; + char *start; + char *loc; + + 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; + loc = (char *) in_fde->fd_fde_start; + + *fde_off = (loc - start); + *cie_off = in_fde->fd_cie_offset; + return DW_DLV_OK; +} + +/* Used by dwarfdump -v to print offsets, for debugging + dwarf info +*/ +/* ARGSUSED 4 */ +int +_dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie, + Dwarf_Off * cie_off, Dwarf_Error * err) +{ + int res; + char *start; + char *loc; + + 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; + loc = (char *) in_cie->ci_cie_start; + + *cie_off = (loc - start); + return DW_DLV_OK; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_frame.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_frame.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,207 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +/* The dwarf 2.0 standard dictates that only the following + * fields can be read when an unexpected augmentation string + * (in the cie) is encountered: CIE length, CIE_id, version and + * augmentation; FDE: length, CIE pointer, initial location and + * address range. Unfortunately, with the above restrictions, it + * is impossible to read the instruction table from a CIE or a FDE + * when a new augmentation string is encountered. + * To fix this problem, the following layout is used, if the + * augmentation string starts with the string "z". + * CIE FDE + * length length + * CIE_id CIE_pointer + * version initial_location + * augmentation address_range + * length_of_augmented_fields (*NEW*) + * code_alignment_factor Any new fields as necessary + * data_alignment_factor instruction_table + * return_address + * length_of_augmented fields + * Any new fields as necessary + * initial_instructions + * + * The type of all the old data items are the same as what is + * described in dwarf 2.0 standard. The length_of_augmented_fields + * 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. + * + * 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. + */ + +#define DW_DEBUG_FRAME_VERSION 1 +#define DW_DEBUG_FRAME_AUGMENTER_STRING "mti v1" + +/* The value of the offset field for Cie's. */ +#define DW_CIE_OFFSET ~(0x0) + +/* The augmentation string may be NULL. */ +#define DW_EMPTY_STRING "" + +#define DW_FRAME_INSTR_OPCODE_SHIFT 6 +#define DW_FRAME_INSTR_OFFSET_MASK 0x3f + +/* + This struct denotes the rule for a register in a row of + the frame table. In other words, it is one element of + the table. +*/ +struct Dwarf_Reg_Rule_s { + + /* + 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 + 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'. + + The 'register' numbers are either real registers (ie, table + columns defined as real registers) or defined entries that are + not really hardware registers, such as DW_FRAME_SAME_VAL or + DW_FRAME_CFA_COL. + + */ + Dwarf_Sbyte ru_is_off; + + /* Register involved in this rule. */ + Dwarf_Half ru_register; + + /* Offset to add to register, if indicated by ru_is_offset. */ + Dwarf_Addr ru_offset; +}; + +typedef struct Dwarf_Frame_s *Dwarf_Frame; + +/* + 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. +*/ +struct Dwarf_Frame_s { + + /* Pc value corresponding to this row of the frame table. */ + Dwarf_Addr fr_loc; + + /* Rules for all the registers in this row. */ + struct Dwarf_Reg_Rule_s fr_reg[DW_FRAME_LAST_REG_NUM]; + + Dwarf_Frame fr_next; +}; + +typedef struct Dwarf_Frame_Op_List_s *Dwarf_Frame_Op_List; + +/* This is used to chain together Dwarf_Frame_Op structures. */ +struct Dwarf_Frame_Op_List_s { + Dwarf_Frame_Op *fl_frame_instr; + Dwarf_Frame_Op_List fl_next; +}; + +/* + This structure contains all the pertinent info for a Cie. Most + of the fields are taken straight from the definition of a Cie. + Ci_cie_start points to the address (in .debug_frame) where this + Cie begins. Ci_cie_instr_start points to the first byte of the + frame instructions for this Cie. Ci_dbg points to the associated + Dwarf_Debug structure. Ci_initial_table is a pointer to the table + row generated by the instructions for this Cie. +*/ +struct Dwarf_Cie_s { + Dwarf_Word ci_length; + char *ci_augmentation; + Dwarf_Small ci_code_alignment_factor; + Dwarf_Sbyte ci_data_alignment_factor; + Dwarf_Small ci_return_address_register; + Dwarf_Small *ci_cie_start; + Dwarf_Small *ci_cie_instr_start; + Dwarf_Debug ci_dbg; + Dwarf_Frame ci_initial_table; + Dwarf_Cie ci_next; + Dwarf_Small ci_length_size; + Dwarf_Small ci_extension_size; +}; + +/* + This structure contains all the pertinent info for a Fde. + Most of the fields are taken straight from the definition. + fd_cie_index is the index of the Cie associated with this + Fde in the list of Cie's for this debug_frame. Fd_cie + points to the corresponsing Dwarf_Cie structure. Fd_fde_start + points to the start address of the Fde. Fd_fde_instr_start + points to the start of the instructions for this Fde. Fd_dbg + points to the associated Dwarf_Debug structure. +*/ +struct Dwarf_Fde_s { + Dwarf_Word fd_length; + Dwarf_Addr fd_cie_offset; + Dwarf_Sword fd_cie_index; + Dwarf_Cie fd_cie; + Dwarf_Addr fd_initial_location; + Dwarf_Small *fd_initial_loc_pos; + Dwarf_Addr fd_address_range; + Dwarf_Small *fd_fde_start; + Dwarf_Small *fd_fde_instr_start; + Dwarf_Debug fd_dbg; + Dwarf_Signed fd_offset_into_exception_tables; + Dwarf_Fde fd_next; + Dwarf_Small fd_length_size; + Dwarf_Small fd_extension_size; +}; + + +int + _dwarf_frame_address_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrlist, + Dwarf_Off ** offsetlist, + Dwarf_Signed * returncount, + Dwarf_Error * err); diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_funcs.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_funcs.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,121 @@ +/* + + Copyright (C) 2000, 2002 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_funcs.h" +#include "dwarf_global.h" + +int +dwarf_get_funcs(Dwarf_Debug dbg, + 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); + if (res != DW_DLV_OK) { + 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); + +} + + +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); + } + + *ret_name = (char *) (func->gl_name); + return DW_DLV_OK; +} + +int +dwarf_func_die_offset(Dwarf_Func func_in, + Dwarf_Off * return_offset, Dwarf_Error * error) +{ + Dwarf_Global func = (Dwarf_Global) func_in; + + return dwarf_global_die_offset(func, return_offset, error); +} + + +int +dwarf_func_cu_offset(Dwarf_Func func_in, + Dwarf_Off * return_offset, Dwarf_Error * error) +{ + Dwarf_Global func = (Dwarf_Global) func_in; + + return dwarf_global_cu_offset(func, return_offset, error); +} + + +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) +{ + Dwarf_Global func = (Dwarf_Global) func_in; + + return dwarf_global_name_offsets(func, + ret_func_name, + die_offset, cu_die_offset, error); +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_funcs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_funcs.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,42 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + + +typedef struct Dwarf_Func_Context_s *Dwarf_Func_Context; + + +/* struct never completed: see dwarf_global.h */ diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_global.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_global.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,464 @@ +/* + + Copyright (C) 2000, 2002 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_global.h" + +int +dwarf_get_globals(Dwarf_Debug dbg, + 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); + if (res != DW_DLV_OK) { + return res; + } + + + + 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); + +} + + +/* Sweeps the complete section. +*/ +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 *pubnames_like_ptr; + + + + /* + 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_Half version; + + /* + Offset from the start of compilation-unit for the current + global. */ + Dwarf_Off die_offset_in_cu; + + Dwarf_Unsigned global_count = 0; + + /* Points to the current global read. */ + Dwarf_Global global; + + /* + 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; + + /* Points to contiguous block of Dwarf_Global's to be returned. */ + Dwarf_Global *ret_globals; + + /* Temporary counter. */ + Dwarf_Unsigned i; + + + + + if (dbg == NULL) { + _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 (section_data_ptr == NULL) { + return (DW_DLV_NO_ENTRY); + } + + pubnames_like_ptr = section_data_ptr; + do { + Dwarf_Unsigned length; + int local_extension_size; + int local_length_size; + + /* 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_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); + } + + /* 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; + + + 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); + } + + /* 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; + + /* 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++; + + global->gl_context = pubnames_context; + + global->gl_named_die_offset_within_cu = die_offset_in_cu; + + global->gl_name = pubnames_like_ptr; + + 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); + } + + /* 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; + } + + /* 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); + + } + /* 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); + if (ret_globals == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + /* + Store pointers to Dwarf_Global_s structs in contiguous block, + 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); + } + + *globals = ret_globals; + *return_count = (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. + +*/ +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); + } + + *ret_name = (char *) (glob->gl_name); + return DW_DLV_OK; +} + + +/* + 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) +{ + if (global == NULL) { + _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); + } + + *ret_off = (global->gl_named_die_offset_within_cu + + 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 + compilation unit the global is part of. + + 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 + 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). + +*/ +int +dwarf_global_cu_offset(Dwarf_Global global, + Dwarf_Off * cu_header_offset, + Dwarf_Error * error) +{ + Dwarf_Global_Context con; + + if (global == NULL) { + _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); + } + + /* In early libdwarf, this incorrectly returned the offset of the + CU DIE. Now correctly returns the header offset. */ + *cu_header_offset = con->pu_offset_of_cu_header; + + return DW_DLV_OK; +} + +/* + Give back the pubnames entry (or any other like section) + name, symbol DIE offset, and the cu-DIE offset. +*/ +int +dwarf_global_name_offsets(Dwarf_Global global, + 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; + + if (global == NULL) { + _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); + } + + off = con->pu_offset_of_cu_header; + if (die_offset != NULL) { + *die_offset = global->gl_named_die_offset_within_cu + off; + } + + dbg = con->pu_dbg; + if (dbg == NULL) { + _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); + } + + *ret_name = (char *) global->gl_name; + + 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. +*/ + +/* 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 len = + _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; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_global.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_global.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,104 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + + +typedef struct Dwarf_Global_Context_s *Dwarf_Global_Context; + +/* + This struct contains header information for a set of pubnames. + 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. + +*/ +struct Dwarf_Global_Context_s { + + /* + Length in .debug_pubnames of a set of pubnames 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 */ + unsigned char pu_length_size; + /* for this CU, size of the extension 0 except for dwarf2 extension + 64bit, in which case is 4. */ + unsigned char pu_extension_size; + + /* + Offset into .debug_info of the compilation-unit header (not DIE) + for this set of pubnames. */ + Dwarf_Off pu_offset_of_cu_header; + + /* Size of compilation-unit that these pubnames are in. */ + Dwarf_Unsigned pu_info_length; + + Dwarf_Debug pu_dbg; +}; + + +/* This struct contains information for a single pubname. */ +struct Dwarf_Global_s { + + /* + Offset from the start of the corresponding compilation-unit of + the DIE for the given pubname CU. */ + Dwarf_Off gl_named_die_offset_within_cu; + + /* Points to the given pubname. */ + Dwarf_Small *gl_name; + + /* Context for this pubname. */ + Dwarf_Global_Context gl_context; +}; + +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); diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_incl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_incl.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,57 @@ +/* + + Copyright (C) 2000, 2002 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 + +*/ + + + +#ifndef DWARF_INCL_H +#define DWARF_INCL_H + +#include "libdwarfdefs.h" +#include + +#ifdef HAVE_ELF_H +#include +#endif + +#include +#include +#include + +#include "dwarf_base_types.h" +#include "dwarf_alloc.h" +#include "dwarf_opaque.h" +#include "dwarf_error.h" +#include "dwarf_util.h" +#endif /* DWARF_INCL_H */ diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_init_finish.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_init_finish.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,809 @@ +/* + + Copyright (C) 2000,2002,2003 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#ifdef HAVE_ELF_H +#include +#endif +#ifdef __SGI_FAST_LIBELF +#include +#else +#ifdef HAVE_LIBELF_H +#include +#else +#ifdef HAVE_LIBELF_LIBELF_H +#include +#endif +#endif +#endif /* !defined(__SGI_FAST_LIBELF) */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "dwarf_incl.h" + +#define DWARF_DBG_ERROR(dbg,errval,retval) \ + _dwarf_error(dbg, error, errval); return(retval); + +#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 + so that the static need not be referenced at + run time, preserving better locality of + reference. + Value is 0 means do the string check. + Value non-zero means do not do the check. +*/ +static Dwarf_Small _dwarf_assume_string_bad; + + +int +dwarf_set_stringcheck(int newval) +{ + int oldval = _dwarf_assume_string_bad; + + _dwarf_assume_string_bad = newval; + return oldval; +} + +#ifdef __SGI_FAST_LIBELF +/* + This function translates an elf_sgi error code into a libdwarf + code. + */ +static int +_dwarf_error_code_from_elf_sgi_error_code(enum elf_sgi_error_type val) +{ + 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; + } +} +#endif + +/* + Given an Elf ptr, set up dbg with pointers + to all the Dwarf data sections. + Return NULL on error. + + This function is also responsible for determining + whether the given object contains Dwarf information + or not. The test currently used is that it contains + either a .debug_info or a .debug_frame section. If + not, it returns DW_DLV_NO_ENTRY causing dwarf_init() also to + return DW_DLV_NO_ENTRY. Earlier, we had thought of using only + the presence/absence of .debug_info to test, but we + added .debug_frame since there could be stripped objects + that have only a .debug_frame section for exception + processing. + 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) +{ +#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; + +#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_Unsigned section_size; + Dwarf_Unsigned section_count; + Dwarf_Half section_index; + + 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; +#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; + } +#else /* little endian */ + dbg->de_big_endian_object = 0; + if (ehdr_ident[EI_DATA] == ELFDATA2MSB) { + dbg->de_same_endian = 0; + dbg->de_big_endian_object = 1; + 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) */ + + dbg->de_nelfsecs = section_count; + + 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; + + 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); + } + +#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_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; + + 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) { + 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; + } + } + if (foundDwarf) { + return DW_DLV_OK; + } + + return (DW_DLV_NO_ENTRY); +} + + +/* + The basic dwarf initializer function for consumers. + Return NULL on error. +*/ +int +dwarf_init(int fd, + Dwarf_Unsigned access, + 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 + + 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 (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); + } + + if (access != DW_DLC_READ) { + DWARF_DBG_ERROR(dbg, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR); + } + dbg->de_access = access; + +#ifdef __SGI_FAST_LIBELF + elf = elf_sgi_new(); + if (elf == NULL) { + DWARF_DBG_ERROR(dbg, DW_DLE_MAF, DW_DLV_ERROR); + } + + 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 + + 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 */ + _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); +} + + +/* + Frees all memory that was not previously freed + by dwarf_dealloc. + Aside from certain categories. +*/ +int +dwarf_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); + } + + 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. + */ +int +_dwarf_load_section(Dwarf_Debug dbg, + Dwarf_Half section_index, + Dwarf_Small ** section_data, + Dwarf_Error * error) +{ + if (section_index == 0) { + return DW_DLV_NO_ENTRY; + } + + /* check to see if the section is already loaded */ + if (*section_data != NULL) { + return DW_DLV_OK; + } + + { +#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; + } + + /* + 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) */ + } + + return DW_DLV_OK; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_leb.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_leb.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,149 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include + + +/* + decode ULEB +*/ +Dwarf_Unsigned +_dwarf_decode_u_leb128(Dwarf_Small * leb128, Dwarf_Word * leb128_length) +{ + unsigned char byte; + Dwarf_Word word_number; + Dwarf_Unsigned number; + Dwarf_Sword shift; + Dwarf_Sword byte_length; + + /* The following unrolls-the-loop for the first few bytes and + unpacks into 32 bits to make this as fast as possible. + 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); + } else if ((*(leb128 + 1) & 0x80) == 0) { + if (leb128_length != NULL) + *leb128_length = 2; + + 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; + + 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; + + 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. */ + number = 0; + shift = 0; + byte_length = 1; + byte = *(leb128); + for (;;) { + number |= ((Dwarf_Unsigned) (byte & 0x7f)) << shift; + + if ((byte & 0x80) == 0) { + if (leb128_length != NULL) + *leb128_length = byte_length; + return (number); + } + shift += 7; + + byte_length++; + ++leb128; + byte = *leb128; + } +} + +#define BITSINBYTE 8 + +/* + decode SLEB +*/ +Dwarf_Signed +_dwarf_decode_s_leb128(Dwarf_Small * leb128, Dwarf_Word * leb128_length) +{ + Dwarf_Signed number = 0; + Dwarf_Bool sign = 0; + Dwarf_Sword shift = 0; + unsigned char byte = *leb128; + Dwarf_Sword byte_length = 1; + + /* byte_length being the number of bytes of data absorbed so far in + turning the leb into a Dwarf_Signed. */ + + for (;;) { + sign = byte & 0x40; + number |= ((Dwarf_Signed) ((byte & 0x7f))) << shift; + shift += 7; + + if ((byte & 0x80) == 0) { + break; + } + ++leb128; + byte = *leb128; + byte_length++; + } + + if ((shift < sizeof(Dwarf_Signed) * BITSINBYTE) && sign) { + number |= -((Dwarf_Signed) 1 << shift); + } + + if (leb128_length != NULL) + *leb128_length = byte_length; + return (number); +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_line.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_line.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,1548 @@ +/* + + 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 + 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_line.h" +#ifdef HAVE_ALLOCA_H +#include +#endif + + +/* + Although source files is supposed to return the + source files in the compilation-unit, it does + not look for any in the statement program. In + other words, it ignores those defined using the + extended opcode DW_LNE_define_file. +*/ +int +dwarf_srcfiles(Dwarf_Die die, + char ***srcfiles, + Dwarf_Signed * srcfilecount, 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 = 0; + + /* + 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 + file name. */ + char **ret_files = 0; + + /* The Dwarf_Debug this die belongs to. */ + Dwarf_Debug dbg; + + /* 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; + + /* ***** BEGIN CODE ***** */ + + /* Reset error. */ + if (error != NULL) + *error = NULL; + + 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); + } + + 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); + } + + 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); + } + + if (file_count == 0) { + *srcfiles = NULL; + *srcfilecount = 0; + return (DW_DLV_NO_ENTRY); + } + + 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); + } + + *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; + } + + 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_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); + } + + 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); + + 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); + } + + 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++; + + 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; + + 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; + + 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); + } + + /* 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 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) */ + + opcode = opcode - special_opcode_base; + address = address + minimum_instruction_length * + (opcode / line_range); + line = line + line_base + opcode % line_range; + + 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); + } + + 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++; + + 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; + } + } + + basic_block = false; + } 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); + } + + 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); + } + + 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++; + + 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; + } + } + + 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); + } + + 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) { + _dwarf_error(dbg, error, + 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) { + _dwarf_error(dbg, error, + 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) { + _dwarf_error(dbg, error, + 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) { + _dwarf_error(dbg, error, + 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) { + _dwarf_error(dbg, error, + 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 - special_opcode_base; + address = address + minimum_instruction_length * + (opcode / line_range); + + 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; + break; + } + } + + } else if (type == LOP_EXTENDED) { + Dwarf_Unsigned utmp3; + + 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_error(dbg, error, DW_DLE_ALLOC_FAIL); + 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 = + 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++; + + 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; + } + } + + 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 == 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); + } + + curr_line->li_address = address; + curr_line->li_addr_line.li_offset = + line_ptr - dbg->de_debug_line; + + 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; + + if (head_chain == NULL) + head_chain = curr_chain = chain_line; + else { + curr_chain->ch_next = chain_line; + curr_chain = chain_line; + } + } + + 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_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_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; + + 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; + + 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; + } + + 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); + if (block_line == NULL) { + _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); + } + + 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; + line_context->lc_line_count = line_count; + line_context->lc_compilation_directory = comp_dir; + line_context->lc_dbg = dbg; + *count = line_count; + + *linebuf = block_line; + return (DW_DLV_OK); +} + +int +dwarf_srclines(Dwarf_Die die, + 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); + if (res != DW_DLV_OK) { + return res; + } + *linecount = count; + return res; +} + + + + + +int +dwarf_linebeginstatement(Dwarf_Line line, + 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); + } + + *return_bool = (line->li_addr_line.li_l_data.li_is_stmt); + return DW_DLV_OK; +} + +int +dwarf_lineendsequence(Dwarf_Line line, + Dwarf_Bool * return_bool, Dwarf_Error * error) +{ + if (line == NULL) { + _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); + return DW_DLV_OK; +} + + +int +dwarf_lineno(Dwarf_Line line, + 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); + } + + *ret_lineno = (line->li_addr_line.li_l_data.li_line); + return DW_DLV_OK; +} + + +int +dwarf_lineaddr(Dwarf_Line line, + 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); + } + + *ret_lineaddr = (line->li_address); + return DW_DLV_OK; +} + + +int +dwarf_lineoff(Dwarf_Line line, + 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); + } + + *ret_lineoff = + (line->li_addr_line.li_l_data.li_column == + 0 ? -1 : line->li_addr_line.li_l_data.li_column); + return DW_DLV_OK; +} + + +int +dwarf_linesrc(Dwarf_Line line, char **ret_linesrc, Dwarf_Error * error) +{ + Dwarf_Signed i; + Dwarf_File_Entry file_entry; + Dwarf_Small *name_buffer; + Dwarf_Small *include_directories; + Dwarf_Debug dbg; + unsigned int comp_dir_len; + + if (line == NULL) { + _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); + } + 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); + } + + file_entry = line->li_context->lc_file_entries; + for (i = line->li_addr_line.li_l_data.li_file - 1; i > 0; i--) + 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); + } + + if (*(char *) file_entry->fi_file_name == '/') { + *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)); + } + + 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 (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); + } + + 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; + + if (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; + } + + 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); + if (name_buffer == NULL) { + _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; + } + } + } else { + strcpy((char *) name_buffer, ""); + } + strcat((char *) name_buffer, (char *) include_directories); + strcat((char *) name_buffer, "/"); + strcat((char *) name_buffer, (char *) file_entry->fi_file_name); + *ret_linesrc = ((char *) name_buffer); + return DW_DLV_OK; +} + + +int +dwarf_lineblock(Dwarf_Line line, + Dwarf_Bool * return_bool, Dwarf_Error * error) +{ + if (line == NULL) { + _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. */ +/* + This routine works by looking for exact matches between + the current line address and pc, and crossovers from + from less than pc value to greater than. At each line + that satisfies the above, it records a pointer to the + line, and the difference between the address and pc. + It then scans these pointers and picks out those with + the smallest difference between pc and address. +*/ +int +dwarf_pclines(Dwarf_Debug dbg, + 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 + exists in dbg. */ + Dwarf_Line line; + Dwarf_Line prev_line; + + /* + 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. */ + Dwarf_Bool check_line, first_line; + + /* + 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 + 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. */ + Dwarf_Addr pc_less, pc_more; + + /* + Pc_line_buf points to a chain of pointers to lines of which + those with a diff equal to the smallest difference will be + returned. */ + Dwarf_Line *pc_line_buf, *pc_line; + + /* + Chain_count counts the number of lines in the above chain for + which the diff is equal to the smallest difference This is the + number returned by this routine. */ + Dwarf_Signed chain_count; + + chain_head = NULL; + + check_line = true; + first_line = true; + diff = MAX_LINE_DIFF; + + 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); + + 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) + + 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 = 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; + } + + chain_count = 0; + for (chain_ptr = chain_head; chain_ptr != NULL; + 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); + 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++; + } + + 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); + } + + *linebuf = pc_line_buf; + return (chain_count); +} +#endif + + +/* + 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_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_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_dealloc(dbg, linebuf[i], DW_DLA_LINE); + } + dwarf_dealloc(dbg, linebuf, DW_DLA_LIST); + *returncount = lcount; + *offs = loffsets; + *addrs = laddrs; + return DW_DLV_OK; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_line.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_line.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,230 @@ +/* + + Copyright (C) 2000 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 DW_EXTENDED_OPCODE 0 + +/* + This is used as the starting value for an algorithm + to get the minimum difference between 2 values. + UINT_MAX is used as our approximation to infinity. +*/ +#define MAX_LINE_DIFF UINT_MAX + + +/* + This structure is used to build a list of all the + files that are used in the current compilation unit. + All of the fields execpt fi_next have meanings that + are obvious from section 6.2.4 of the Libdwarf Doc. +*/ +struct Dwarf_File_Entry_s { + /* Points to string naming the file. */ + Dwarf_Small *fi_file_name; + + /* + Index into the list of directories of the directory in which + this file exits. */ + Dwarf_Sword fi_dir_index; + + /* Time of last modification of the file. */ + Dwarf_Unsigned fi_time_last_mod; + + /* Length in bytes of the file. */ + Dwarf_Unsigned fi_file_length; + + /* Pointer for chaining file entries. */ + Dwarf_File_Entry fi_next; +}; + + +typedef struct Dwarf_Line_Context_s *Dwarf_Line_Context; + +/* + This structure provides the context in which the fields of + a Dwarf_Line structure are interpreted. They come from the + statement program prologue. **Updated by dwarf_srclines in + dwarf_line.c. +*/ +struct Dwarf_Line_Context_s { + /* + Points to a chain of entries providing info about source files + for the current set of Dwarf_Line structures. */ + Dwarf_File_Entry lc_file_entries; + /* + Count of number of source files for this set of Dwarf_Line + structures. */ + Dwarf_Sword lc_file_entry_count; + /* + Points to the portion of .debug_line section that contains a + list of strings naming the included directories. */ + Dwarf_Small *lc_include_directories; + + /* Count of the number of included directories. */ + Dwarf_Sword lc_include_directories_count; + + /* Count of the number of lines for this cu. */ + Dwarf_Sword lc_line_count; + + /* Points to name of compilation directory. */ + Dwarf_Small *lc_compilation_directory; + + Dwarf_Debug lc_dbg; +}; + + +/* + This structure defines a row of the line table. + All of the fields except li_offset have the exact + same meaning that is defined in Section 6.2.2 + of the Libdwarf Document. + + li_offset is used by _dwarf_addr_finder() which is called + by rqs(1), an sgi utility for 'moving' shared libraries + as if the static linker (ld) had linked the shared library + at the newly-specified address. Most libdwarf-using + apps will ignore li_offset and _dwarf_addr_finder(). + +*/ +struct Dwarf_Line_s { + Dwarf_Addr li_address; /* pc value of machine instr */ + union addr_or_line_s { + struct li_inner_s { + Dwarf_Sword li_file; /* int identifying src file */ + 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 */ + } li_l_data; + Dwarf_Off li_offset; /* for rqs */ + } li_addr_line; + Dwarf_Line_Context li_context; /* assoc Dwarf_Line_Context_s */ +}; + + +int + _dwarf_line_address_offsets(Dwarf_Debug dbg, + Dwarf_Die die, + Dwarf_Addr ** addrs, + Dwarf_Off ** offs, + Dwarf_Unsigned * returncount, + Dwarf_Error * err); + + +/* The LOP, WHAT_IS_OPCODE stuff is here so it can + be reused in 3 places. Seemed hard to keep + the 3 places the same without an inline func or + a macro. + + Handling the line section where the header and the + file being process 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. +*/ +#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 ) { \ + /* we know we must treat as a standard op \ + or a special case. \ + */ \ + if(opcode == DW_EXTENDED_OPCODE) { \ + type = LOP_EXTENDED; \ + } else if( (HIGHEST_STANDARD_OPCODE+1) >= \ + base) { \ + /* == Standard case: compile of \ + dwarf_line.c and object \ + have same standard op codes set. \ + \ + > Special case: compile of dwarf_line.c\ + has things in standard op codes list \ + in dwarf.h header not \ + in the object: handle this as a standard\ + op code in switch below. \ + The header special ops overlap the \ + object standard ops. \ + The new standard op codes will not \ + appear in the object. \ + */ \ + type = LOP_STANDARD; \ + } else { \ + /* These are standard opcodes in the object\ + ** that were not defined in the header \ + ** at the time dwarf_line.c \ + ** was compiled. Provides the ability of \ + ** 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; \ + } \ + \ + } else { \ + /* Is a special op code. \ + */ \ + type = LOP_SPECIAL; \ + } + +/* The following is from the dwarf definition of 'ubyte' + and is specifically mentioned in section 6.2.5.1, page 54 + of the Rev 2.0.0 dwarf specification. +*/ + +#define MAX_LINE_OP_CODE 255 diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_loc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_loc.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,912 @@ +/* + + Copyright (C) 2000,2003 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include "dwarf_loc.h" + + +/* + Given a Dwarf_Block that represents a location expression, + this function returns a pointer to a Dwarf_Locdesc struct + that has its ld_cents field set to the number of location + operators in the block, and its ld_s field pointing to a + contiguous block of Dwarf_Loc structs. However, the + ld_lopc and ld_hipc values are uninitialized. Returns + NULL on error. This function assumes that the length of + the block is greater than 0. Zero length location expressions + to represent variables that have been optimized away are + handled in the calling function. +*/ +static Dwarf_Locdesc * +_dwarf_get_locdesc(Dwarf_Debug dbg, + Dwarf_Block * loc_block, + Dwarf_Addr lowpc, + Dwarf_Addr highpc, Dwarf_Error * error) +{ + /* Size of the block containing the location expression. */ + Dwarf_Unsigned loc_len; + + /* Sweeps the block containing the location expression. */ + Dwarf_Small *loc_ptr; + + /* Current location operator. */ + Dwarf_Small atom; + + /* Offset of current operator from start of block. */ + Dwarf_Unsigned offset; + + /* 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; + + /* Count of the number of location operators. */ + Dwarf_Unsigned op_count; + + /* Contiguous block of Dwarf_Loc's for Dwarf_Locdesc. */ + Dwarf_Loc *block_loc; + + /* Dwarf_Locdesc pointer to be returned. */ + Dwarf_Locdesc *locdesc; + + Dwarf_Word leb128_length; + Dwarf_Unsigned i; + + /* ***** BEGIN CODE ***** */ + + loc_len = loc_block->bl_len; + loc_ptr = loc_block->bl_data; + + offset = 0; + op_count = 0; + while (offset < loc_len) { + + operand1 = 0; + operand2 = 0; + op_count++; + + 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) { + + 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_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_const1u: + operand1 = *(Dwarf_Small *) loc_ptr; + loc_ptr = loc_ptr + 1; + offset = offset + 1; + break; + + case DW_OP_const1s: + operand1 = *(Dwarf_Sbyte *) 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_const2s: + 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_const4s: + 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_const8s: + 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_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_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_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_xderef: + break; + + case DW_OP_xderef_size: + 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_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_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_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_nop: + break; + + default: + _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD); + return (NULL); + } + + + 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); + if (block_loc == 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; + + 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); + if (locdesc == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (NULL); + } + + locdesc->ld_cents = op_count; + locdesc->ld_s = block_loc; + locdesc->ld_from_loclist = loc_block->bl_from_loclist; + locdesc->ld_section_offset = loc_block->bl_section_offset; + locdesc->ld_lopc = lowpc; + locdesc->ld_hipc = highpc; + + return (locdesc); +} + +/* Using a loclist offset to get the in-memory + address of .debug_loc data to read, returns the loclist + 'header' info in return_block. +*/ + +#define MAX_ADDR ((address_size == 8)?0xffffffffffffffffULL:0xffffffff) + +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_Small *beg = dbg->de_debug_loc + sec_offset; + int address_size = dbg->de_pointer_size; + + 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); + + if (sec_offset >= dbg->de_debug_loc_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; + } + + READ_UNALIGNED(dbg, start_addr, Dwarf_Addr, beg, address_size); + READ_UNALIGNED(dbg, end_addr, Dwarf_Addr, + 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); + } 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); + } 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; + } + } +#undef MAX_ADDR + *lowpc = start_addr; + *hipc = end_addr; + + return_block->bl_len = exprblock_size; + 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; + + return DW_DLV_OK; + +} +static int +_dwarf_get_loclist_count(Dwarf_Debug dbg, + Dwarf_Off loclist_offset, + 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); + + 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; +} + +/* Helper routine to avoid code duplication. +*/ +static int +_dwarf_setup_loc(Dwarf_Attribute attr, + Dwarf_Debug * dbg_ret, + Dwarf_Half * form_ret, Dwarf_Error * error) +{ + Dwarf_Debug dbg = 0; + Dwarf_Half form = 0; + int blkres; + + if (attr == NULL) { + _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); + } + + dbg = attr->ar_cu_context->cc_dbg; + if (dbg == NULL) { + _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; + } + *form_ret = form; + + return DW_DLV_OK; +} + +/* Helper routine to avoid code duplication. +*/ +static int +_dwarf_get_loclist_header_start(Dwarf_Debug dbg, + 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); + } + + 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; + } + } + return DW_DLV_OK; +} + +/* When llbuf (see dwarf_loclist_n) is partially set up + and an error is encountered, tear it down as it + won't be used. +*/ +static void +_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, DW_DLA_LIST); +} + +/* + 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_Debug dbg; + + /* + Dwarf_Attribute that describes the DW_AT_location in die, if + present. */ + Dwarf_Attribute loc_attr = attr; + + /* 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_Half form = 0; + Dwarf_Addr lowpc = 0; + Dwarf_Addr highpc = 0; + Dwarf_Signed listlen = 0; + Dwarf_Locdesc **llbuf = 0; + + int blkres; + int setup_res; + + /* ***** BEGIN CODE ***** */ + setup_res = _dwarf_setup_loc(attr, &dbg, &form, error); + if (setup_res != DW_DLV_OK) { + return setup_res; + } + /* 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; + int count_res; + 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; + } + + 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; + + /* Now get to next loclist entry offset. */ + loclist_offset = loc_block.bl_section_offset + + loc_block.bl_len; + } + + + } else { + 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 */ + + /* 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; + } + + *llbuf_out = llbuf; + *listlen_out = listlen; + 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 + of location list entries. + + 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_Debug dbg; + + /* + Dwarf_Attribute that describes the DW_AT_location in die, if + present. */ + Dwarf_Attribute loc_attr = attr; + + /* 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_Half form = 0; + Dwarf_Addr lowpc = 0; + Dwarf_Addr highpc = 0; + + int blkres; + int setup_res; + + /* ***** BEGIN CODE ***** */ + setup_res = _dwarf_setup_loc(attr, &dbg, &form, error); + if (setup_res != DW_DLV_OK) { + return setup_res; + } + /* 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; + + 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); + } + + + + + } else { + 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 */ + } + + /* 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); + if (locdesc == NULL) { + /* low level error already set: let it be passed back */ + return (DW_DLV_ERROR); + } + + *llbuf = locdesc; + *listlen = 1; + return (DW_DLV_OK); +} + +/* Usable to read a single loclist or to read a block of them + or to read an entire section's loclists. + +*/ + + /*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_Block b; + Dwarf_Addr lowpc; + Dwarf_Addr highpc; + int res; + + 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; + } + } + + res = _dwarf_read_loc_section(dbg, + &b, &lowpc, &highpc, offset, error); + if (res != DW_DLV_OK) { + 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; + + + +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_loc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_loc.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,46 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +typedef struct Dwarf_Loc_Chain_s *Dwarf_Loc_Chain; + +struct Dwarf_Loc_Chain_s { + Dwarf_Small lc_atom; + Dwarf_Unsigned lc_number; + Dwarf_Unsigned lc_number2; + Dwarf_Unsigned lc_offset; + Dwarf_Loc_Chain lc_next; +}; diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_macro.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_macro.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,409 @@ +/* + + Copyright (C) 2000, 2002 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include +#include "dwarf_macro.h" + + +#define LEFTPAREN '(' +#define RIGHTPAREN ')' +#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). + + Only understands well-formed dwarf macinfo strings. +*/ +char * +dwarf_find_macro_value_start(char *str) +{ + char *lcp; + 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; + } + } + /* never found value: returns pointer to the 0 byte at end of + string */ + return lcp; + +} + + +/* + Try to keep fileindex correct in every Macro_Details + record by tracking file starts and ends. + Uses high water mark: space reused, not freed. + Presumption is that this makes sense for most uses. + 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; + +#define STARTERMAX 10 +static void +_dwarf_reset_index_stack(void) +{ + next_to_use = 0; + was_fault = 0; +} +static int +_dwarf_mac_push_index(Dwarf_Debug dbg, Dwarf_Signed indx) +{ + Dwarf_Signed *newbase; + + if (next_to_use >= 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; + } + st_base[next_to_use] = indx; + ++next_to_use; + return DW_DLV_OK; +} +static Dwarf_Signed +_dwarf_mac_pop_index(void) +{ + if (was_fault) { + return -1; + } + if (next_to_use > 0) { + next_to_use--; + return (*(st_base + next_to_use)); + } + 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). +*/ + +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_Small *macro_base; + Dwarf_Small *pnext; + Dwarf_Unsigned endloc; + unsigned char uc; + unsigned long depth; + + int res; + + /* 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 final_count = 0; + Dwarf_Signed fileindex = -1; + Dwarf_Small *latest_str_loc; + + unsigned long count; + unsigned long max_count = (unsigned long) maximum_count; + + _dwarf_reset_index_stack(); + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + + res = + _dwarf_load_section(dbg, + dbg->de_debug_macinfo_index, + &dbg->de_debug_macinfo, + error); + if (res != DW_DLV_OK) { + return res; + } + + macro_base = dbg->de_debug_macinfo; + if (macro_base == NULL) { + return (DW_DLV_NO_ENTRY); + } + if (macro_offset >= dbg->de_debug_macinfo_size) { + return (DW_DLV_NO_ENTRY); + } + + pnext = macro_base + macro_offset; + if (maximum_count == 0) { + 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); + } + for (count = 0; !done && count < max_count; ++count) { + 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); + + 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; + + 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); + } + } + if (count == 0) { + _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 + string space to provide for. */ + + string_offset = count * sizeof(Dwarf_Macro_Details); + + /* extra 2 not really needed */ + space_needed = string_offset + str_space + 2; + return_data = pdata = + _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); + } + pnext = macro_base + macro_offset; + + done = 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)); + + 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; + + 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; + + 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! */ + } + } + *entry_count = count; + *details = (Dwarf_Macro_Details *) return_data; + + return DW_DLV_OK; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_macro.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_macro.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,44 @@ +/* + + Copyright (C) 2000 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 + +*/ + + +/* + + + dwarf_macro.h + + $Revision: 1.3 $ $Date: 2001/09/18 19:23:55 $ + +*/ diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_opaque.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_opaque.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,269 @@ +/* + + Copyright (C) 2000,2002,2003 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 + +*/ + +#include + + +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; +}; + +struct Dwarf_Attribute_s { + Dwarf_Half ar_attribute; /* Attribute Value. */ + Dwarf_Half ar_attribute_form; /* Attribute Form. */ + Dwarf_Half ar_attribute_form_direct; + /* Identical to ar_attribute_form except that if + the original form uleb was DW_FORM_indirect, + ar_attribute_form_direct contains DW_FORM_indirect + but ar_attribute_form contains the true form. */ + + Dwarf_CU_Context ar_cu_context; + Dwarf_Small *ar_debug_info_ptr; + Dwarf_Attribute ar_next; +}; + +/* + This structure provides the context for a compilation unit. + Thus, it contains the Dwarf_Debug, cc_dbg, that this cu + belongs to. It contains the information in the compilation + unit header, cc_length, cc_version_stamp, cc_abbrev_offset, + and cc_address_size, in the .debug_info section for that cu. + In addition, it contains the count, cc_count_cu, of the cu + number of that cu in the list of cu's in the .debug_info. + The count starts at 1, ie cc_count_cu is 1 for the first cu, + 2 for the second and so on. This struct also contains a + pointer, cc_abbrev_table, to a list of pairs of abbrev code + and a pointer to the start of that abbrev + in the .debug_abbrev section. + + Each die will also contain a pointer to such a struct to + record the context for that die. + + **Updated by dwarf_next_cu_header in dwarf_die_deliv.c +*/ +struct Dwarf_CU_Context_s { + Dwarf_Debug cc_dbg; + Dwarf_Word cc_length; + Dwarf_Small cc_length_size; + Dwarf_Small cc_extension_size; + Dwarf_Half cc_version_stamp; + Dwarf_Sword cc_abbrev_offset; + Dwarf_Small cc_address_size; + 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; +}; + + +struct Dwarf_Debug_s { + dwarf_elf_handle de_elf; /* see de_elf_must_close at end of struct */ + unsigned int de_nelfsecs; + + Dwarf_Unsigned de_access; + Dwarf_Handler de_errhand; + Dwarf_Ptr de_errarg; + + /* + Context for the compilation_unit just read by a call to + dwarf_next_cu_header. **Updated by dwarf_next_cu_header in + dwarf_die_deliv.c */ + Dwarf_CU_Context de_cu_context; + + /* + Points to linked list of CU Contexts for the CU's already read. + These are only CU's read by dwarf_next_cu_header(). */ + Dwarf_CU_Context de_cu_context_list; + + /* + Points to the last CU Context added to the list by + dwarf_next_cu_header(). */ + Dwarf_CU_Context de_cu_context_list_end; + + /* + This is the list of CU contexts read for dwarf_offdie(). These + may read ahead of dwarf_next_cu_header(). */ + Dwarf_CU_Context de_offdie_cu_context; + Dwarf_CU_Context de_offdie_cu_context_end; + + /* Offset of last byte of last CU read. */ + Dwarf_Word de_info_last_offset; + + /* + Number of bytes in the length, and offset field in various + .debug_* sections. It's not very meaningful, and is + only used in one 'approximate' calculation. */ + Dwarf_Small de_length_size; + + /* number of bytes in a pointer of the target in various .debug_ + sections. 4 in 32bit, 8 in MIPS 64, ia64. */ + Dwarf_Small de_pointer_size; + + /* set at creation of a Dwarf_Debug to say if form_string should be + checked for valid length at every call. 0 means do the check. + non-zero means do not do the check. */ + Dwarf_Small de_assume_string_in_bounds; + + /* + Dwarf_Alloc_Hdr_s structs used to manage chunks that are + malloc'ed for each allocation type for structs. */ + 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 + + + /* + These fields are used to process debug_frame section. **Updated + by dwarf_get_fde_list in dwarf_frame.h */ + /* + Points to contiguous block of pointers to Dwarf_Cie_s structs. */ + Dwarf_Cie *de_cie_data; + /* Count of number of Dwarf_Cie_s structs. */ + Dwarf_Signed de_cie_count; + /* + 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; + + 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; + + 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; + + + Dwarf_Unsigned de_debug_frame_size; + + Dwarf_Unsigned de_debug_frame_size_eh_gnu; /* gnu for the g++ + eh_frame section */ + + Dwarf_Unsigned de_debug_funcnames_size; + Dwarf_Unsigned de_debug_typenames_size; + Dwarf_Unsigned de_debug_varnames_size; + Dwarf_Unsigned de_debug_weaknames_size; + + void *(*de_copy_word) (void *, const void *, size_t); + unsigned char de_same_endian; + unsigned char de_elf_must_close; /* if non-zero, then + 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. + + 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; + unsigned char de_big_endian_object; /* non-zero if big-endian + object opened. */ +}; + +typedef struct Dwarf_Chain_s *Dwarf_Chain; +struct Dwarf_Chain_s { + void *ch_item; + Dwarf_Chain ch_next; +}; + +#define CURRENT_VERSION_STAMP 2 + + /* Size of cu header version stamp field. */ +#define CU_VERSION_STAMP_SIZE sizeof(Dwarf_Half) + + /* Size of cu header address size field. */ +#define CU_ADDRESS_SIZE_SIZE sizeof(Dwarf_Small) + +void *_dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len); + +#define ORIGINAL_DWARF_OFFSET_SIZE 4 +#define DISTINGUISHED_VALUE 0xffffffff +#define DISTINGUISHED_VALUE_OFFSET_SIZE 8 + +/* + We don't load the sections until they are needed. This function is + used to load the section. + */ +int _dwarf_load_section(Dwarf_Debug, + Dwarf_Half, + Dwarf_Small **, + Dwarf_Error *); diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_print_lines.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_print_lines.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,666 @@ +/* + + 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 + 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include +#include "dwarf_line.h" +#ifdef HAVE_ALLOCA_H +#include +#endif + +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"); +} + +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) +{ + 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); + +} + + +/* + return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR +*/ +int +_dwarf_internal_printlines(Dwarf_Die die, Dwarf_Error * error) +{ + /* + 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; + + /* + 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 opcode_base; + + 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_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; + + + /* + 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; + + /* 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; + + /* The Dwarf_Debug this die belongs to. */ + Dwarf_Debug dbg; + int resattr; + int lres; + + 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; + } + + 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_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; + 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); + } + + 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); + } + + 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); + + 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); + 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); + + opcode_length = (Dwarf_Small *) + alloca(sizeof(Dwarf_Small) * opcode_base); + + 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); + } + + 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; + + 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); + } + + /* 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); + } + + 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; + + 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); + + + + 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; + + } 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); + } + + 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); + } + + 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); + } + + 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; + + if (opcode_length[DW_LNS_set_file] != 1) { + _dwarf_error(dbg, error, + DW_DLE_LINE_NUM_OPERANDS_BAD); + return (DW_DLV_ERROR); + } + + 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); + } + + 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; + } + + 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; + } + + 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; + } + } + + } 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); + + 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 == 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_Small *fn; + Dwarf_Signed di; + Dwarf_Signed tlm; + Dwarf_Unsigned fl; + + 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; + + + 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:{ + _dwarf_error(dbg, error, + DW_DLE_LINE_EXT_OPCODE_BAD); + return (DW_DLV_ERROR); + } + } + + } + } + + return (DW_DLV_OK); +} + +/* + Caller passes in compilation unit DIE. +*/ +int +_dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error) +{ + int res; + + res = _dwarf_internal_printlines(die, error); + if (res != DW_DLV_OK) { + return res; + } + return res; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_query.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_query.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,609 @@ +/* + + Copyright (C) 2000, 2002 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 + +*/ + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_die_deliv.h" + +int +dwarf_get_address_size(Dwarf_Debug dbg, + Dwarf_Half * ret_addr_size, Dwarf_Error * error) +{ + Dwarf_Half address_size; + + if (dbg == 0) { + _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; +} + +int +dwarf_dieoffset(Dwarf_Die die, + Dwarf_Off * ret_offset, Dwarf_Error * error) +{ + CHECK_DIE(die, DW_DLV_ERROR) + + * ret_offset = (die->di_debug_info_ptr - + die->di_cu_context->cc_dbg->de_debug_info); + return DW_DLV_OK; +} + + +/* + This function returns the offset of + the die relative to the start of its + compilation-unit rather than .debug_info. + Returns DW_DLV_ERROR on error. +*/ +int +dwarf_die_CU_offset(Dwarf_Die die, + Dwarf_Off * cu_off, Dwarf_Error * error) +{ + Dwarf_CU_Context 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); + 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); + return DW_DLV_OK; +} + + +int +dwarf_attrlist(Dwarf_Die die, + 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; + + 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); + if (abbrev_list == NULL) { + _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) + + 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; + + 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; + /* 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; + + info_ptr += _dwarf_get_size_of_val(dbg, attr_form, info_ptr, + die->di_cu_context-> + cc_length_size); + + 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); + } + + attr_ptr = (Dwarf_Attribute *) + _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); + } + + curr_attr = head_attr; + for (i = 0; i < attr_count; i++) { + *(attr_ptr + i) = curr_attr; + curr_attr = curr_attr->ar_next; + } + + *attrbuf = attr_ptr; + *attrcnt = attr_count; + return (DW_DLV_OK); +} + + +/* + This function takes a die, and an attr, and returns + a pointer to the start of the value of that attr in + the given die in the .debug_info section. The form + is returned in *attr_form. + + Returns NULL on error, or if attr is not found. + However, *attr_form is 0 on error, and positive + otherwise. +*/ +static Dwarf_Byte_Ptr +_dwarf_get_value_ptr(Dwarf_Die die, + Dwarf_Half attr, Dwarf_Half * attr_form) +{ + Dwarf_Byte_Ptr abbrev_ptr; + Dwarf_Abbrev_List abbrev_list; + Dwarf_Half curr_attr; + Dwarf_Half curr_attr_form; + Dwarf_Byte_Ptr info_ptr; + + abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context, + die->di_abbrev_list-> + ab_code); + if (abbrev_list == 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) + + do { + 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 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); + } + + 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); + } while (curr_attr != 0 || curr_attr_form != 0); + + *attr_form = 1; + return (NULL); +} + + +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; + + CHECK_DIE(die, DW_DLV_ERROR) + + 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 == DW_FORM_string) { + *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); + } + + READ_UNALIGNED(dbg, string_offset, Dwarf_Unsigned, + 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); + } + + res = + _dwarf_load_section(dbg, + dbg->de_debug_str_index, + &dbg->de_debug_str, + error); + if (res != DW_DLV_OK) { + return res; + } + + *ret_name = (char *) (dbg->de_debug_str + 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_form; + + 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; + } + + *return_bool = (true); + return DW_DLV_OK; +} + + +int +dwarf_attr(Dwarf_Die die, + 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; + + 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; + } + + 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); + } + + attrib->ar_attribute = attr; + attrib->ar_attribute_form = attr_form; + attrib->ar_attribute_form_direct = attr_form; + attrib->ar_cu_context = die->di_cu_context; + attrib->ar_debug_info_ptr = info_ptr; + *ret_attr = (attrib); + return DW_DLV_OK; +} + + +int +dwarf_lowpc(Dwarf_Die die, + Dwarf_Addr * return_addr, Dwarf_Error * error) +{ + Dwarf_Addr ret_addr; + Dwarf_Byte_Ptr info_ptr; + Dwarf_Half attr_form; + Dwarf_Debug dbg; + + CHECK_DIE(die, DW_DLV_ERROR) + + dbg = die->di_cu_context->cc_dbg; + 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); + } + if (info_ptr == NULL) { + return (DW_DLV_NO_ENTRY); + } + + + READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr, + info_ptr, dbg->de_pointer_size); + + *return_addr = ret_addr; + return (DW_DLV_OK); +} + + +int +dwarf_highpc(Dwarf_Die die, + Dwarf_Addr * return_addr, Dwarf_Error * error) +{ + Dwarf_Addr ret_addr; + Dwarf_Byte_Ptr info_ptr; + Dwarf_Half attr_form; + Dwarf_Debug dbg; + + CHECK_DIE(die, DW_DLV_ERROR) + + dbg = die->di_cu_context->cc_dbg; + 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); + } + if (info_ptr == NULL) { + return (DW_DLV_NO_ENTRY); + } + + READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr, + info_ptr, dbg->de_pointer_size); + + *return_addr = ret_addr; + return (DW_DLV_OK); +} + + +/* + Takes a die, an attribute attr, and checks if attr + occurs in die. Attr is required to be an attribute + whose form is in the "constant" class. If attr occurs + in die, the value is returned. + Returns DW_DLV_OK, DW_DLV_ERROR, or DW_DLV_NO_ENTRY as + appropriate. Sets the value thru the pointer return_val. + This function is meant to do all the + processing for dwarf_bytesize, dwarf_bitsize, dwarf_bitoffset, + and dwarf_srclang. +*/ +static int +_dwarf_die_attr_unsigned_constant(Dwarf_Die die, + 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) + + dbg = die->di_cu_context->cc_dbg; + info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form); + if (info_ptr != NULL) { + switch (attr_form) { + + 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_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_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); + } + } + if (attr_form == 0) { + _dwarf_error(dbg, error, DW_DLE_DIE_BAD); + return (DW_DLV_ERROR); + } + return DW_DLV_NO_ENTRY; +} + + +int +dwarf_bytesize(Dwarf_Die die, + Dwarf_Unsigned * ret_size, Dwarf_Error * error) +{ + Dwarf_Unsigned luns; + int res = + _dwarf_die_attr_unsigned_constant(die, DW_AT_byte_size, &luns, + error); + *ret_size = luns; + return res; +} + + +int +dwarf_bitsize(Dwarf_Die die, + 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); + *ret_size = luns; + return res; +} + + +int +dwarf_bitoffset(Dwarf_Die die, + 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); + *ret_size = luns; + return res; +} + + +/* Refer section 3.1, page 21 in Dwarf Definition. */ +int +dwarf_srclang(Dwarf_Die die, + Dwarf_Unsigned * ret_size, Dwarf_Error * error) +{ + Dwarf_Unsigned luns; + int res; + + res = + _dwarf_die_attr_unsigned_constant(die, DW_AT_language, &luns, + error); + *ret_size = luns; + return res; +} + + +/* Refer section 5.4, page 37 in Dwarf Definition. */ +int +dwarf_arrayorder(Dwarf_Die die, + Dwarf_Unsigned * ret_size, Dwarf_Error * error) +{ + Dwarf_Unsigned luns; + int res; + + 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. + + 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_Off attroff; + + CHECK_DIE(die, DW_DLV_ERROR) + + attroff = (attr->ar_debug_info_ptr - + die->di_cu_context->cc_dbg->de_debug_info); + *offset = attroff; + return DW_DLV_OK; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_sort_line.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_sort_line.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,727 @@ +/* + + 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 + 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include +#include "dwarf_line.h" +#ifdef HAVE_ALLOCA_H +#include +#endif +#include + +#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); + +/* 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 */ + struct a_line_area *ala_next; +}; + + + +/* + 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. + + 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. + + +*/ +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 */ + + 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; + + *any_change = 0; + line_ptr = malloc(buffer_len); + if (!line_ptr) { + *err_code = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + orig_line_ptr = line_ptr; + memcpy(line_ptr, orig_buffer, buffer_len); + + + /* + We must iterate thru each of a set of prologues and line data. + We process each set in turn. If all pass, we update the + passed-in buffer. */ + 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; + + 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; + } + + + /* 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; + } + free(orig_line_ptr); + + return sec_res; +} + + +/* By setting ala_entry_num we guarantee a stable sort, + no duplicates + Sorting in address order. +*/ +static int +cmpr(const void *lin, const void *rin) +{ + const struct a_line_area *l = lin; + const struct a_line_area *r = rin; + + if (l->ala_address < r->ala_address) { + return -1; + } + if (l->ala_address > r->ala_address) { + return 1; + } + if (l->ala_entry_num < r->ala_entry_num) { + return -1; + } + if (l->ala_entry_num > r->ala_entry_num) { + return 1; + } + return 0; /* should never happen. */ +} + + +/* + 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. + + + 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. + + 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). + + + 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. + + +*/ +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) +{ + + + /* + 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; + + Dwarf_Small *orig_line_ptr; + + /* 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; + Dwarf_Word line; + Dwarf_Bool is_stmt; + + struct a_line_area *area_base = 0; + struct a_line_area *area_current = 0; + long area_count = 0; + + 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; + + + /* + 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; + + /* 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); + + + + 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); + } + + + /* 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; + } + + 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; + + 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 = 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); + } + } + + } + } + + + if (!need_to_sort) { + 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; + + /* Build and sort a simple array of sections. Forcing a stable sort + by comparing on sequence number. We will use the sorted list to + move sections of this part of the line table. Each 'section' + starting with a DW_LNE_set_address opcode, on the assumption + that such only get out of order where there was an ld-cord + 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; + + ala_array = malloc(area_count * sizeof(struct a_line_area)); + if (!ala_array) { + *err_code = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + + for (local = area_base, i = 0; local; + local = local->ala_next, ++i) { + + ala_array[i] = *local; + } + + qsort(ala_array, area_count, sizeof(struct a_line_area), cmpr); + + /* Now we must rearrange the pieces of the line table. */ + + 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; + } + + memcpy(orig_line_ptr, new_area, remaining_bytes); + + free(new_area); + free(ala_array); + ala_array = 0; + new_area = 0; + } + + *any_change = 1; + return (DW_DLV_OK); +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_string.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_string.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,82 @@ +/* + + Copyright (C) 2000, 2002 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" + +int +dwarf_get_str(Dwarf_Debug dbg, + Dwarf_Off offset, + char **string, + Dwarf_Signed * returned_str_len, Dwarf_Error * error) +{ + int res; + + if (dbg == NULL) { + _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_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); + } + + res = + _dwarf_load_section(dbg, + dbg->de_debug_str_index, + &dbg->de_debug_str, + error); + if (res != DW_DLV_OK) { + return res; + } + + *string = (char *) dbg->de_debug_str + offset; + + *returned_str_len = (strlen(*string)); + return DW_DLV_OK; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_stubs.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_stubs.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,50 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include + + + + /*ARGSUSED*/ int +dwarf_nextglob(Dwarf_Debug dbg, + Dwarf_Global glob, + Dwarf_Global * returned_nextglob, Dwarf_Error * error) +{ + return (DW_DLV_NO_ENTRY); +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_types.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_types.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,123 @@ +/* + + Copyright (C) 2000, 2002 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_types.h" +#include "dwarf_global.h" + +int +dwarf_get_types(Dwarf_Debug dbg, + 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); + if (res != DW_DLV_OK) { + 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); + +} + + +int +dwarf_typename(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_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_type_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_type_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); +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_types.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,41 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + + +typedef struct Dwarf_Type_Context_s *Dwarf_Type_Context; + +/* type never completed see dwarf_global.h */ diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_util.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_util.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,383 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_die_deliv.h" + + + +/* + Given a form, and a pointer to the bytes encoding + a value of that form, val_ptr, this function returns + the length, in bytes, of a value of that form. + When using this function, check for a return of 0 + a recursive DW_FORM_INDIRECT value. +*/ +Dwarf_Unsigned +_dwarf_get_size_of_val(Dwarf_Debug dbg, + Dwarf_Unsigned form, + Dwarf_Small * val_ptr, int v_length_size) +{ + Dwarf_Unsigned length = 0; + Dwarf_Word leb128_length = 0; + Dwarf_Unsigned form_indirect = 0; + Dwarf_Unsigned ret_value = 0; + + switch (form) { + + default: /* Handles form = 0. */ + return (form); + + case DW_FORM_addr: + return (dbg->de_pointer_size); + + case DW_FORM_ref_addr: + return (v_length_size); + + case DW_FORM_block1: + 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)); + + case DW_FORM_block4: + READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, + val_ptr, sizeof(Dwarf_ufixed)); + return (ret_value + sizeof(Dwarf_ufixed)); + + + case DW_FORM_data1: + return (1); + + case DW_FORM_data2: + return (2); + + case DW_FORM_data4: + return (4); + + case DW_FORM_data8: + return (8); + + case DW_FORM_string: + 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_flag: + return (1); + + case DW_FORM_ref_udata: + _dwarf_decode_u_leb128(val_ptr, &leb128_length); + return (leb128_length); + + case DW_FORM_indirect: + { + 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)); + } + + case DW_FORM_ref1: + return (1); + + case DW_FORM_ref2: + return (2); + + case DW_FORM_ref4: + return (4); + + case DW_FORM_ref8: + return (8); + + case DW_FORM_sdata: + _dwarf_decode_s_leb128(val_ptr, &leb128_length); + return (leb128_length); + + case DW_FORM_strp: + return (v_length_size); + + case DW_FORM_udata: + _dwarf_decode_u_leb128(val_ptr, &leb128_length); + return (leb128_length); + } +} + + +/* + This function returns a pointer to a Dwarf_Abbrev_List_s + struct for the abbrev with the given code. It puts the + struct on the appropriate hash table. It also adds all + the abbrev between the last abbrev added and this one to + the hash table. In other words, the .debug_abbrev section + is scanned sequentially from the top for an abbrev with + the given code. All intervening abbrevs are also put + into the hash table. + + This function hashes the given code, and checks the chain + at that hash table entry to see if a Dwarf_Abbrev_List_s + with the given code exists. If yes, it returns a pointer + to that struct. Otherwise, it scans the .debug_abbrev + section from the last byte scanned for that CU till either + an abbrev with the given code is found, or an abbrev code + of 0 is read. It puts Dwarf_Abbrev_List_s entries for all + abbrev's read till that point into the hash table. The + hash table contains both a head pointer and a tail pointer + for each entry. + + Returns NULL on error. +*/ +Dwarf_Abbrev_List +_dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Word 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; + + 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); + + abbrev_ptr = cu_context->cc_last_abbrev_ptr != NULL ? + cu_context->cc_last_abbrev_ptr : + dbg->de_debug_abbrev + cu_context->cc_abbrev_offset; + + /* End of abbrev's for this cu, since abbrev code is 0. */ + if (*abbrev_ptr == 0) { + return (NULL); + } + + do { + Dwarf_Unsigned utmp; + + 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); + + 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; + } + + abbrev_list->ab_code = abbrev_code; + abbrev_list->ab_tag = abbrev_tag; + + abbrev_list->ab_has_child = *(abbrev_ptr++); + abbrev_list->ab_abbrev_ptr = abbrev_ptr; + + do { + Dwarf_Unsigned utmp3; + + 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); + + } while (*abbrev_ptr != 0 && abbrev_code != code); + + cu_context->cc_last_abbrev_ptr = abbrev_ptr; + return (abbrev_code == code ? abbrev_list : NULL); +} + + +/* return 1 if string ends before 'endptr' else +** return 0 meaning string is not properly terminated. +** Presumption is the 'endptr' pts to end of some dwarf section data. +*/ +int +_dwarf_string_valid(void *startptr, void *endptr) +{ + + char *start = startptr; + char *end = endptr; + + while (start < end) { + if (*start == 0) { + return 1; /* OK! */ + } + ++start; + ++end; + } + return 0; /* FAIL! bad string! */ +} + +/* + A byte-swapping version of memcpy + for cross-endian use. + Only 2,4,8 should be lengths passed in. +*/ +void * +_dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len) +{ + void *orig_s1 = s1; + unsigned char *targ = (unsigned char *) s1; + 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]; + } 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]; + } else if (len == 2) { + 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]; + } else { + memcpy(s1, s2, len); + } + + return orig_s1; +} + + +/* + This calculation used to be sprinkled all over. + Now brought to one place. + + We try to accurately compute the size of a cu header + given a known cu header location ( an offset in .debug_info). + +*/ +/* ARGSUSED */ +Dwarf_Unsigned +_dwarf_length_of_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned offset) +{ + int local_length_size = 0; + int local_extension_size = 0; + Dwarf_Unsigned length = 0; + Dwarf_Small *cuptr = dbg->de_debug_info + offset; + + READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned, + 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. */ + +} + +/* + 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. */ +} + +/* Now that we delay loading .debug_info, we need to do the + load in more places. So putting the load + code in one place now instead of replicating it in multiple + places. + +*/ +int +_dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error * error) +{ + int res; + + /* Testing de_debug_info allows us to avoid testing + de_debug_abbrev. One test instead of 2. .debug_info is useless + without .debug_abbrev. */ + if (dbg->de_debug_info) { + return DW_DLV_OK; + } + + res = _dwarf_load_section(dbg, dbg->de_debug_abbrev_index, + &dbg->de_debug_abbrev, error); + if (res != DW_DLV_OK) { + return res; + } + res = _dwarf_load_section(dbg, dbg->de_debug_info_index, + &dbg->de_debug_info, error); + return res; + +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_util.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_util.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,267 @@ +/* + + 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 + +*/ + + + +/* + Decodes unsigned leb128 encoded numbers that + are assumed to be less than 4 bytes long. + Make sure ptr is a pointer to a 1-byte type. + Returns UINT_MAX on error. + +*/ +#define DECODE_LEB128_UWORD(ptr, value) \ + { \ + Dwarf_Word uleblen; \ + value = _dwarf_decode_u_leb128(ptr,&uleblen); \ + ptr += uleblen; \ + } + +/* + Decodes signed leb128 encoded numbers. + Make sure ptr is a pointer to a 1-byte type. + +*/ +#define DECODE_LEB128_SWORD(ptr, value) \ + { \ + Dwarf_Word sleblen; \ + value = _dwarf_decode_s_leb128(ptr,&sleblen); \ + ptr += sleblen; \ + } + + +/* + Skips leb128_encoded numbers that are guaranteed + to be no more than 4 bytes long. Same for both + signed and unsigned numbers. +*/ +#define SKIP_LEB128_WORD(ptr) \ + if ((*(ptr++) & 0x80) != 0) { \ + if ((*(ptr++) & 0x80) != 0) { \ + if ((*(ptr++) & 0x80) != 0) { \ + if ((*(ptr++) & 0x80) != 0) { \ + } \ + } \ + } \ + } + + +#define CHECK_DIE(die, error_ret_value) \ + if (die == NULL) { \ + _dwarf_error(NULL, error, DW_DLE_DIE_NULL); \ + return(error_ret_value); \ + } \ + if (die->di_cu_context == NULL) { \ + _dwarf_error(NULL, error, DW_DLE_DIE_NO_CU_CONTEXT); \ + return(error_ret_value); \ + } \ + if (die->di_cu_context->cc_dbg == NULL) { \ + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); \ + return(error_ret_value); \ + } + + +/* + Reads 'source' for 'length' bytes from unaligned addr. + + Avoids any constant-in-conditional warnings and + avoids a test in the generated code (for non-const cases, + which are in the majority.) + Uses a temp to avoid the test. + The decl here should avoid any problem of size in the temp. + This code is ENDIAN DEPENDENT + The memcpy args are the endian issue. +*/ +typedef Dwarf_Unsigned BIGGEST_UINT; + +#ifdef WORDS_BIGENDIAN +#define READ_UNALIGNED(dbg,dest,desttype, source, length) \ + { \ + BIGGEST_UINT _ltmp = 0; \ + dbg->de_copy_word( (((char *)(&_ltmp)) + sizeof(_ltmp) - length), \ + source, length) ; \ + dest = (desttype)_ltmp; \ + } + + +/* + This macro sign-extends a variable depending on the length. + It fills the bytes between the size of the destination and + the length with appropriate padding. + This code is ENDIAN DEPENDENT but dependent only + on host endianness, not object file endianness. + The memcpy args are the issue. +*/ +#define SIGN_EXTEND(dest, length) \ + if (*(Dwarf_Sbyte *)((char *)&dest + sizeof(dest) - length) < 0) \ + memcpy((char *)&dest, "\xff\xff\xff\xff\xff\xff\xff\xff", \ + sizeof(dest) - length) +#else /* LITTLE ENDIAN */ + +#define READ_UNALIGNED(dbg,dest,desttype, source, length) \ + { \ + BIGGEST_UINT _ltmp = 0; \ + dbg->de_copy_word( (char *)(&_ltmp) , \ + source, length) ; \ + dest = (desttype)_ltmp; \ + } + + +/* + This macro sign-extends a variable depending on the length. + It fills the bytes between the size of the destination and + the length with appropriate padding. + This code is ENDIAN DEPENDENT but dependent only + on host endianness, not object file endianness. + The memcpy args are the issue. +*/ +#define SIGN_EXTEND(dest, length) \ + if (*(Dwarf_Sbyte *)((char *)&dest + (length-1)) < 0) \ + memcpy((char *)&dest+length, \ + "\xff\xff\xff\xff\xff\xff\xff\xff", \ + sizeof(dest) - length) + +#endif /* ! LITTLE_ENDIAN */ + + + +/* + READ_AREA LENGTH reads the length (the older way + of pure 32 or 64 bit + or the new proposed dwarfv2.1 64bit-extension way) + + 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). + + r_dbg is just the current dbg pointer. + w_target is the output length field. + r_targtype is the output type. Always Dwarf_Unsigned so far. + +*/ +/* This one handles the v2.1 64bit extension + and 32bit (and MIPS fixed 64 bit via the + dwarf_init-set r_dbg->de_length_size).. + It does not recognize any but the one distingushed value + (the only one with defined meaning). + It assumes that no CU will have a length + 0xffffffxx (32bit length) + or + 0xffffffxx xxxxxxxx (64bit length) + which makes possible auto-detection of the extension. + + This depends on knowing that only a non-zero length + is legitimate (AFAICT), and for IRIX non-standard -64 + 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)). + + 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, \ + rw_src_data_p, ORIGINAL_DWARF_OFFSET_SIZE); \ + if(w_target == DISTINGUISHED_VALUE) { \ + /* dwarf3 64bit extension */ \ + w_length_size = DISTINGUISHED_VALUE_OFFSET_SIZE; \ + rw_src_data_p += ORIGINAL_DWARF_OFFSET_SIZE; \ + w_exten_size = ORIGINAL_DWARF_OFFSET_SIZE; \ + READ_UNALIGNED(r_dbg,w_target,r_targtype, \ + rw_src_data_p, DISTINGUISHED_VALUE_OFFSET_SIZE);\ + rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE; \ + } else { \ + if(w_target == 0 && r_dbg->de_big_endian_object) { \ + /* IRIX 64 bit, big endian */ \ + READ_UNALIGNED(r_dbg,w_target,r_targtype, \ + rw_src_data_p, DISTINGUISHED_VALUE_OFFSET_SIZE); \ + w_length_size = DISTINGUISHED_VALUE_OFFSET_SIZE; \ + rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE; \ + w_exten_size = 0; \ + } else { \ + /* standard 32 bit dwarf2/dwarf3 */ \ + w_exten_size = 0; \ + w_length_size = ORIGINAL_DWARF_OFFSET_SIZE; \ + rw_src_data_p += w_length_size; \ + } \ + } + + + +Dwarf_Unsigned +_dwarf_decode_u_leb128(Dwarf_Small * leb128, + Dwarf_Word * leb128_length); + +Dwarf_Signed +_dwarf_decode_s_leb128(Dwarf_Small * leb128, + Dwarf_Word * leb128_length); + +Dwarf_Unsigned +_dwarf_get_size_of_val(Dwarf_Debug dbg, + Dwarf_Unsigned form, + Dwarf_Small * val_ptr, int v_length_size); + +/* + This struct is used to build a hash table for the + abbreviation codes for a compile-unit. +*/ +struct Dwarf_Hash_Table_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); + + +/* return 1 if string ends before 'endptr' else +** return 0 meaning string is not properly terminated. +** Presumption is the 'endptr' pts to end of some dwarf section data. +*/ +int _dwarf_string_valid(void *startptr, void *endptr); + +Dwarf_Unsigned _dwarf_length_of_cu_header(Dwarf_Debug, + Dwarf_Unsigned offset); +Dwarf_Unsigned _dwarf_length_of_cu_header_simple(Dwarf_Debug); + +int _dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error *error); diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_vars.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_vars.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,123 @@ +/* + + Copyright (C) 2000, 2002 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_vars.h" +#include "dwarf_global.h" + +int +dwarf_get_vars(Dwarf_Debug dbg, + 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); + if (res != DW_DLV_OK) { + 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); +} + + +int +dwarf_varname(Dwarf_Var var_in, char **ret_varname, Dwarf_Error * error) +{ + Dwarf_Global var = (Dwarf_Global) var_in; + + if (var == NULL) { + _dwarf_error(NULL, error, DW_DLE_VAR_NULL); + return (DW_DLV_ERROR); + } + + *ret_varname = (char *) (var->gl_name); + return DW_DLV_OK; +} + + +int +dwarf_var_die_offset(Dwarf_Var var_in, + Dwarf_Off * returned_offset, Dwarf_Error * error) +{ + Dwarf_Global var = (Dwarf_Global) var_in; + + return dwarf_global_die_offset(var, returned_offset, error); + +} + + +int +dwarf_var_cu_offset(Dwarf_Var var_in, + Dwarf_Off * returned_offset, Dwarf_Error * error) +{ + Dwarf_Global var = (Dwarf_Global) var_in; + + return dwarf_global_cu_offset(var, returned_offset, error); +} + + +int +dwarf_var_name_offsets(Dwarf_Var var_in, + 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); +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_vars.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_vars.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,41 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + + +typedef struct Dwarf_Var_Context_s *Dwarf_Var_Context; + +/* struct never completed: see dwarf_global.h */ diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_weaks.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_weaks.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,122 @@ +/* + + Copyright (C) 2000, 2002 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_weaks.h" +#include "dwarf_global.h" + +int +dwarf_get_weaks(Dwarf_Debug dbg, + 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); + if (res != DW_DLV_OK) { + 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); + +} + + + +int +dwarf_weakname(Dwarf_Weak weak_in, char **ret_name, Dwarf_Error * error) +{ + Dwarf_Global weak = (Dwarf_Global) weak_in; + + if (weak == NULL) { + _dwarf_error(NULL, error, DW_DLE_WEAK_NULL); + return (DW_DLV_ERROR); + } + *ret_name = (char *) (weak->gl_name); + return DW_DLV_OK; +} + + +int +dwarf_weak_die_offset(Dwarf_Weak weak_in, + Dwarf_Off * weak_off, Dwarf_Error * error) +{ + Dwarf_Global weak = (Dwarf_Global) weak_in; + + return dwarf_global_die_offset(weak, weak_off, error); +} + + +int +dwarf_weak_cu_offset(Dwarf_Weak weak_in, + Dwarf_Off * weak_off, Dwarf_Error * error) +{ + Dwarf_Global weak = (Dwarf_Global) weak_in; + + return dwarf_global_cu_offset(weak, weak_off, error); +} + + +int +dwarf_weak_name_offsets(Dwarf_Weak weak_in, + 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); +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/dwarf_weaks.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/dwarf_weaks.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,41 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + + +typedef struct Dwarf_Weak_Context_s *Dwarf_Weak_Context; + +/* struct never completed: see dwarf_global.h */ diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/libdwarf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/libdwarf.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,1602 @@ +/* + * 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. + + 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 + +*/ + + +#ifndef _LIBDWARF_H +#define _LIBDWARF_H +#ifdef __cplusplus +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... + +*/ + +#ifdef __SGI_FAST_LIBELF +struct elf_sgi; +typedef struct elf_sgi* dwarf_elf_handle; +#else +struct Elf; +typedef struct Elf* dwarf_elf_handle; +#endif + +#if (_MIPS_SZLONG == 64) +/* Special case for MIPS, so -64 (LP64) build gets simple -long-. + Non-MIPS LP64 or ILP64 environments should probably ensure + _MIPS_SZLONG set to 64 everywhere this header is #included. +*/ +typedef int Dwarf_Bool; /* boolean type */ +typedef unsigned long Dwarf_Off; /* 4 or 8 byte file offset */ +typedef unsigned long Dwarf_Unsigned; /* 4 or 8 byte unsigned value */ +typedef unsigned short Dwarf_Half; /* 2 byte unsigned value */ +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 */ +#else /* 32-bit */ +/* This is for ILP32, allowing i/o of 64bit dwarf info. + Also should be fine for LP64 and ILP64 cases. +*/ +typedef int Dwarf_Bool; /* boolean type */ +typedef unsigned long long Dwarf_Off; /* 8 byte file offset */ +typedef unsigned long long Dwarf_Unsigned; /* 8 byte unsigned value*/ +typedef unsigned short Dwarf_Half; /* 2 byte unsigned value */ +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 */ +#endif +typedef void* Dwarf_Ptr; /* host machine pointer */ + +/* 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 + which 'data' comes from. */ +} Dwarf_Block; + + +/* 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_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_Locdesc; + +/* 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 + */ +#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]; +} Dwarf_Regtable; + +/* 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 + size in any given ABI.) Changing drd_type to an unsigned char + 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 +}; +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; +}; + +/* Opaque types for Consumer Library. */ +typedef struct Dwarf_Debug_s* Dwarf_Debug; +typedef struct Dwarf_Die_s* Dwarf_Die; +typedef struct Dwarf_Line_s* Dwarf_Line; +typedef struct Dwarf_Global_s* Dwarf_Global; +typedef struct Dwarf_Func_s* Dwarf_Func; +typedef struct Dwarf_Type_s* Dwarf_Type; +typedef struct Dwarf_Var_s* Dwarf_Var; +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; + +/* 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; + + +/* error handler function +*/ +typedef void (*Dwarf_Handler)(Dwarf_Error /*error*/, Dwarf_Ptr /*errarg*/); + + +/* + 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 */ + +/* The augmenter string for CIE */ +#define DW_CIE_AUGMENTER_STRING_V0 "z" + +/* dwarf_init() access arguments +*/ +#define DW_DLC_READ 0 /* read only access */ +#define DW_DLC_WRITE 1 /* write only access */ +#define DW_DLC_RDWR 2 /* read/write access NOT SUPPORTED*/ + +/* dwarf_init() access flag modifiers +*/ +#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_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 */ + +/* dwarf_pcline() slide arguments +*/ +#define DW_DLS_BACKWARD -1 /* slide backward to find line */ +#define DW_DLS_NOSLIDE 0 /* match exactly without sliding */ +#define DW_DLS_FORWARD 1 /* slide forward to find line */ + +/* libdwarf error numbers +*/ +#define DW_DLE_NE 0 /* no error */ +#define DW_DLE_VMM 1 /* dwarf format/library version mismatch */ +#define DW_DLE_MAP 2 /* memory map failure */ +#define DW_DLE_LEE 3 /* libelf error */ +#define DW_DLE_NDS 4 /* no debug section */ +#define DW_DLE_NLS 5 /* no line section */ +#define DW_DLE_ID 6 /* invalid descriptor for query */ +#define DW_DLE_IOF 7 /* I/O failure */ +#define DW_DLE_MAF 8 /* memory allocation failure */ +#define DW_DLE_IA 9 /* invalid argument */ +#define DW_DLE_MDE 10 /* mangled debugging entry */ +#define DW_DLE_MLE 11 /* mangled line number entry */ +#define DW_DLE_FNO 12 /* file not open */ +#define DW_DLE_FNR 13 /* file not a regular file */ +#define DW_DLE_FWA 14 /* file open with wrong access */ +#define DW_DLE_NOB 15 /* not an object file */ +#define DW_DLE_MOF 16 /* mangled object file header */ +#define DW_DLE_EOLL 17 /* end of location list entries */ +#define DW_DLE_NOLL 18 /* no location list section */ +#define DW_DLE_BADOFF 19 /* Invalid offset */ +#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) */ + /* Error codes defined by the current Libdwarf Implementation. */ +#define DW_DLE_DBG_ALLOC 23 +#define DW_DLE_FSTAT_ERROR 24 +#define DW_DLE_FSTAT_MODE_ERROR 25 +#define DW_DLE_INIT_ACCESS_WRONG 26 +#define DW_DLE_ELF_BEGIN_ERROR 27 +#define DW_DLE_ELF_GETEHDR_ERROR 28 +#define DW_DLE_ELF_GETSHDR_ERROR 29 +#define DW_DLE_ELF_STRPTR_ERROR 30 +#define DW_DLE_DEBUG_INFO_DUPLICATE 31 +#define DW_DLE_DEBUG_INFO_NULL 32 +#define DW_DLE_DEBUG_ABBREV_DUPLICATE 33 +#define DW_DLE_DEBUG_ABBREV_NULL 34 +#define DW_DLE_DEBUG_ARANGES_DUPLICATE 35 +#define DW_DLE_DEBUG_ARANGES_NULL 36 +#define DW_DLE_DEBUG_LINE_DUPLICATE 37 +#define DW_DLE_DEBUG_LINE_NULL 38 +#define DW_DLE_DEBUG_LOC_DUPLICATE 39 +#define DW_DLE_DEBUG_LOC_NULL 40 +#define DW_DLE_DEBUG_MACINFO_DUPLICATE 41 +#define DW_DLE_DEBUG_MACINFO_NULL 42 +#define DW_DLE_DEBUG_PUBNAMES_DUPLICATE 43 +#define DW_DLE_DEBUG_PUBNAMES_NULL 44 +#define DW_DLE_DEBUG_STR_DUPLICATE 45 +#define DW_DLE_DEBUG_STR_NULL 46 +#define DW_DLE_CU_LENGTH_ERROR 47 +#define DW_DLE_VERSION_STAMP_ERROR 48 +#define DW_DLE_ABBREV_OFFSET_ERROR 49 +#define DW_DLE_ADDRESS_SIZE_ERROR 50 +#define DW_DLE_DEBUG_INFO_PTR_NULL 51 +#define DW_DLE_DIE_NULL 52 +#define DW_DLE_STRING_OFFSET_BAD 53 +#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_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_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 + + /* DW_DLE_LAST MUST EQUAL LAST ERROR NUMBER */ +#define DW_DLE_LAST 194 +#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 + */ +#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 + */ +#define DW_FRAME_SAME_VAL 1035 + + + +/* error return values +*/ +#define DW_DLV_BADADDR (~(Dwarf_Addr)0) + /* for functions returning target address */ + +#define DW_DLV_NOCOUNT ((Dwarf_Signed)-1) + /* for functions returning count */ + +#define DW_DLV_BADOFFSET (~(Dwarf_Off)0) + /* for functions returning offset */ + +/* standard return values for functions */ +#define DW_DLV_NO_ENTRY -1 +#define DW_DLV_OK 0 +#define DW_DLV_ERROR 1 + +/* 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) +/* 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) + + +/*===========================================================================*/ +/* 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 */ +int dwarf_elf_init(dwarf_elf_handle /*elf*/, + 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*/); + +int dwarf_finish(Dwarf_Debug /*dbg*/, Dwarf_Error* /*error*/); + +/* die traversal operations */ +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*/); + +int dwarf_siblingof(Dwarf_Debug /*dbg*/, + 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 */ +int dwarf_offdie(Dwarf_Debug /*dbg*/, + 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*/); + +/* Unimplemented */ +int dwarf_pcsubr(Dwarf_Debug /*dbg*/, + 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*/); + +/* operations on DIEs */ +int dwarf_tag(Dwarf_Die /*die*/, + Dwarf_Half* /*return_tag*/, + Dwarf_Error* /*error*/); + +/* utility? */ +int dwarf_dieoffset(Dwarf_Die /*die*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_die_CU_offset(Dwarf_Die /*die*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_attr (Dwarf_Die /*die*/, + Dwarf_Half /*attr*/, + Dwarf_Attribute * /*returned_attr*/, + Dwarf_Error* /*error*/); + +int dwarf_diename(Dwarf_Die /*die*/, + char ** /*diename*/, + Dwarf_Error* /*error*/); + +/* convenience functions, alternative to using dwarf_attrlist() */ +int dwarf_hasattr(Dwarf_Die /*die*/, + 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*/); + +int dwarf_loclist(Dwarf_Attribute /*attr*/, /* inflexible! */ + Dwarf_Locdesc** /*llbuf*/, + Dwarf_Signed * /*locCount*/, + Dwarf_Error* /*error*/); + +/* Unimplemented */ +int dwarf_stringlen(Dwarf_Die /*die*/, + Dwarf_Locdesc ** /*returned_locdesc*/, + Dwarf_Error* /*error*/); + +/* Unimplemented */ +int dwarf_subscrcnt(Dwarf_Die /*die*/, + Dwarf_Signed * /*returned_count*/, + Dwarf_Error* /*error*/); + +/* Unimplemented */ +int dwarf_nthsubscr(Dwarf_Die /*die*/, + Dwarf_Unsigned /*ssndx*/, + Dwarf_Die * /*returned_die*/, + Dwarf_Error* /*error*/); + +int dwarf_lowpc(Dwarf_Die /*die*/, + Dwarf_Addr * /*returned_addr*/, + Dwarf_Error* /*error*/); + +int dwarf_highpc(Dwarf_Die /*die*/, + Dwarf_Addr * /*returned_addr*/, + Dwarf_Error* /*error*/); + +int dwarf_bytesize(Dwarf_Die /*die*/, + Dwarf_Unsigned * /*returned_size*/, + Dwarf_Error* /*error*/); + +/* Unimplemented */ +int dwarf_isbitfield(Dwarf_Die /*die*/, + Dwarf_Bool * /*returned_bool*/, + Dwarf_Error* /*error*/); + +int dwarf_bitsize(Dwarf_Die /*die*/, + Dwarf_Unsigned * /*returned_size*/, + Dwarf_Error* /*error*/); + +int dwarf_bitoffset(Dwarf_Die /*die*/, + Dwarf_Unsigned * /*returned_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_srclang(Dwarf_Die /*die*/, + Dwarf_Unsigned * /*returned_lang*/, + Dwarf_Error* /*error*/); + +int dwarf_arrayorder(Dwarf_Die /*die*/, + 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*/); + +/* query operations for attributes */ +int dwarf_hasform(Dwarf_Attribute /*attr*/, + Dwarf_Half /*form*/, + Dwarf_Bool * /*returned_bool*/, + Dwarf_Error* /*error*/); + +int dwarf_whatform(Dwarf_Attribute /*attr*/, + Dwarf_Half * /*returned_form*/, + Dwarf_Error* /*error*/); + +int dwarf_whatform_direct(Dwarf_Attribute /*attr*/, + Dwarf_Half * /*returned_form*/, + Dwarf_Error* /*error*/); + +int dwarf_whatattr(Dwarf_Attribute /*attr*/, + 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*/ +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*/ +int dwarf_global_formref(Dwarf_Attribute /*attr*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_formaddr(Dwarf_Attribute /*attr*/, + Dwarf_Addr * /*returned_addr*/, + Dwarf_Error* /*error*/); + +int dwarf_formflag(Dwarf_Attribute /*attr*/, + 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*/); + +int dwarf_formblock(Dwarf_Attribute /*attr*/, + Dwarf_Block ** /*returned_block*/, + Dwarf_Error* /*error*/); + +int dwarf_formstring(Dwarf_Attribute /*attr*/, + char ** /*returned_string*/, + 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*/); + +int dwarf_srcfiles(Dwarf_Die /*die*/, + char*** /*srcfiles*/, + Dwarf_Signed * /*filecount*/, + Dwarf_Error* /*error*/); + +/* Unimplemented. */ +int dwarf_dieline(Dwarf_Die /*die*/, + Dwarf_Line * /*returned_line*/, + Dwarf_Error * /*error*/); + +int dwarf_linebeginstatement(Dwarf_Line /*line*/, + Dwarf_Bool * /*returned_bool*/, + Dwarf_Error* /*error*/); + +int dwarf_lineendsequence(Dwarf_Line /*line*/, + Dwarf_Bool * /*returned_bool*/, + Dwarf_Error* /*error*/); + +int dwarf_lineno(Dwarf_Line /*line*/, + Dwarf_Unsigned * /*returned_lineno*/, + Dwarf_Error* /*error*/); + +int dwarf_lineaddr(Dwarf_Line /*line*/, + Dwarf_Addr * /*returned_addr*/, + Dwarf_Error* /*error*/); + +int dwarf_lineoff(Dwarf_Line /*line*/, + Dwarf_Signed * /*returned_lineoffset*/, + Dwarf_Error* /*error*/); + +int dwarf_linesrc(Dwarf_Line /*line*/, + char ** /*returned_name*/, + Dwarf_Error* /*error*/); + +int dwarf_lineblock(Dwarf_Line /*line*/, + 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*/); +/* 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*/); + +int dwarf_globname(Dwarf_Global /*glob*/, + char ** /*returned_name*/, + Dwarf_Error* /*error*/); + +int dwarf_global_die_offset(Dwarf_Global /*global*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error * /*error*/); + +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*/); +#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*/); + +int dwarf_global_name_offsets(Dwarf_Global /*global*/, + 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_funcname(Dwarf_Func /*func*/, + char ** /*returned_name*/, + Dwarf_Error* /*error*/); + +int dwarf_func_die_offset(Dwarf_Func /*func*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_func_cu_offset(Dwarf_Func /*func*/, + 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*/); + +int dwarf_typename(Dwarf_Type /*type*/, + char ** /*returned_name*/, + Dwarf_Error* /*error*/); + +int dwarf_type_die_offset(Dwarf_Type /*type*/, + 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*/); + +/* 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_varname(Dwarf_Var /*var*/, + char ** /*returned_name*/, + Dwarf_Error* /*error*/); + +int dwarf_var_die_offset(Dwarf_Var /*var*/, + Dwarf_Off* /*return_offset*/, + Dwarf_Error* /*error*/); + +int dwarf_var_cu_offset(Dwarf_Var /*var*/, + 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*/); + +/* weak name operations. */ +int dwarf_get_weaks(Dwarf_Debug /*dbg*/, + Dwarf_Weak** /*weaks*/, + Dwarf_Signed * /*number_of_weaks*/, + Dwarf_Error* /*error*/); + +int dwarf_weakname(Dwarf_Weak /*weak*/, + char ** /*returned_name*/, + Dwarf_Error* /*error*/); + +int dwarf_weak_die_offset(Dwarf_Weak /*weak*/, + 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*/); + +/* 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*/); + +/* 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*/); + +int dwarf_get_abbrev_tag(Dwarf_Abbrev /*abbrev*/, + Dwarf_Half* /*return_tag_number*/, + Dwarf_Error* /*error*/); +int dwarf_get_abbrev_code(Dwarf_Abbrev /*abbrev*/, + Dwarf_Unsigned* /*return_code_number*/, + Dwarf_Error* /*error*/); + +int dwarf_get_abbrev_children_flag(Dwarf_Abbrev /*abbrev*/, + 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*/); + +/* consumer string section operation */ +int dwarf_get_str(Dwarf_Debug /*dbg*/, + 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*/); + + +/* 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*/); + + +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*/); + +int dwarf_get_fde_exception_info(Dwarf_Fde /*fde*/, + 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*/); + +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*/); + +int dwarf_get_fde_instr_bytes(Dwarf_Fde /*fde*/, + 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*/); + +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*/); + +int dwarf_get_fde_for_die(Dwarf_Debug /*dbg*/, + 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*/); + +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*/); + +/* Operations on .debug_aranges. */ +int dwarf_get_aranges(Dwarf_Debug /*dbg*/, + 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*/); + +int dwarf_get_cu_die_offset( + 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*/); +#ifdef __sgi /* pragma is sgi MIPS only */ +#pragma optional dwarf_get_arange_cu_header_offset +#endif + +int dwarf_get_arange_info( + Dwarf_Arange /*arange*/, + 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, + of this macro info */ + 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: + applies to define undef start_file + */ + char * dmd_macro; /* macro name (with value for defineop) + string from vendor ext + */ +}; + +/* _dwarf_print_lines is for use by dwarfdump: it prints + line info to stdout. +*/ +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 + section per function. + -OPT:procedure_reorder=ON + where ld-cord (cord(1)ing by ld, + not by cord(1)) may have changed the function order. +*/ +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 +*/ +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_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; + +int dwarf_get_macro(Dwarf_Debug /*dbg*/, + char * /*requested_macro_name*/, + Dwarf_Addr /*pc_of_request*/, + char ** /*returned_macro_value*/, + Dwarf_Error * /*error*/); + +int dwarf_get_all_defined_macros(Dwarf_Debug /*dbg*/, + Dwarf_Addr /*pc_of_request*/, + Dwarf_Signed * /*returned_count*/, + char *** /*returned_pointers_to_macros*/, + Dwarf_Error * /*error*/); + +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_Signed * /*entry_count*/, + Dwarf_Macro_Details ** /*details*/, + Dwarf_Error * /*err*/); + + +int dwarf_get_address_size(Dwarf_Debug /*dbg*/, + Dwarf_Half * /*addr_size*/, + Dwarf_Error * /*error*/); + +/* utility operations */ +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. +** Call with parameter value 1 to turn off many such checks (and +** increase performance). +** Call with zero for safest running. +** Actual value saved and returned is only 8 bits! Upper bits +** ignored by libdwarf (and zero on return). +** Returns previous value. +*/ +int dwarf_set_stringcheck(int /*stringcheck*/); + +/* Unimplemented */ +Dwarf_Handler dwarf_seterrhand(Dwarf_Debug /*dbg*/, Dwarf_Handler /*errhand*/); + +/* Unimplemented */ +Dwarf_Ptr dwarf_seterrarg(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*errarg*/); + +void dwarf_dealloc(Dwarf_Debug /*dbg*/, void* /*space*/, + Dwarf_Unsigned /*type*/); + +/* 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*/); + +Dwarf_P_Debug dwarf_producer_init( + 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*/); + + +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_Signed dwarf_transform_to_disk_form(Dwarf_P_Debug /*dbg*/, + 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*/); + +int dwarf_get_relocation_info_count( + 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*/); + +/* v1: no drd_length field, enum explicit */ +/* v2: has the drd_length field, enum value in uchar member */ +#define DWARF_DRD_BUFFER_VERSION 2 + +void dwarf_reset_section_bytes(Dwarf_P_Debug /*dbg*/); + +Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug /*dbg*/, + Dwarf_Error* /*error*/); + +/* 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_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_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_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_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_Attribute dwarf_add_AT_const_value_string(Dwarf_P_Die /*ownerdie*/, + 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_Attribute dwarf_add_AT_string(Dwarf_P_Debug /*dbg*/, + 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_Attribute dwarf_add_AT_producer(Dwarf_P_Die /*ownerdie*/, + 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_P_Attribute dwarf_add_AT_const_value_unsignedint( + 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*/); + +/* Producer line creation functions (.debug_line) */ +Dwarf_Unsigned dwarf_add_directory_decl(Dwarf_P_Debug /*dbg*/, + 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*/); + +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 dwarf_lne_set_address(Dwarf_P_Debug /*dbg*/, + 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*/); + +/* 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*/); + +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_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_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_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 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 dwarf_fde_cfa_offset( + 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_Unsigned dwarf_add_die_to_debug( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*die*/, + 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*/); + +/* Operations to create location expressions. */ +Dwarf_P_Expr dwarf_new_expr(Dwarf_P_Debug /*dbg*/, 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_Unsigned dwarf_add_expr_addr( + 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_Unsigned dwarf_expr_current_offset( + Dwarf_P_Expr /*expr*/, + Dwarf_Error* /*error*/); + +Dwarf_Addr dwarf_expr_into_block( + 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_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_Unsigned dwarf_add_pubname( + 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_Unsigned dwarf_add_typename( + 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_Unsigned dwarf_add_weakname( + 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*/); + +int dwarf_undef_macro(Dwarf_P_Debug /*dbg*/, + 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*/); + +int dwarf_end_macro_file(Dwarf_P_Debug /*dbg*/, + Dwarf_Error* /*error*/); + +int dwarf_vendor_ext(Dwarf_P_Debug /*dbg*/, + 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*/); + + +#ifdef __cplusplus +} +#endif +#endif /* _LIBDWARF_H */ + diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/libdwarfdefs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/libdwarfdefs.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,85 @@ +/* + + Copyright (C) 2000 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 + +*/ + + +/* libdwarfdefs.h +*/ + +#ifndef LIBDWARFDEFS_H +#define LIBDWARFDEFS_H + +/* We want __uint32_t and __uint64_t and __int32_t __int64_t + properly defined but not duplicated, since duplicate typedefs + are not legal C. +*/ +/* + HAVE___UINT32_T + HAVE___UINT64_T will be set by configure if + our 4 types are predefined in compiler +*/ + + +#if (!defined(HAVE___UINT32_T)) && defined(HAVE_SGIDEFS_H) +#include /* sgidefs.h defines them */ +#define HAVE___UINT32_T 1 +#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 +/* 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 +#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 diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/mapfile-vers --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/mapfile-vers Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,199 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2011, Richard Lowe. +# + +# +# MAPFILE HEADER START +# +# WARNING: STOP NOW. DO NOT MODIFY THIS FILE. +# Object versioning must comply with the rules detailed in +# +# usr/src/lib/README.mapfiles +# +# You should not be making modifications here until you've read the most current +# copy of that file. If you need help, contact a gatekeeper for guidance. +# +# MAPFILE HEADER END +# + +$mapfile_version 2 + +SYMBOL_VERSION ILLUMOSprivate_1.1 { + global: + 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_flag; + dwarf_add_AT_location_expr; + dwarf_add_AT_name; + dwarf_add_AT_producer; + 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_to_debug; + dwarf_add_directory_decl; + dwarf_add_expr_addr; + dwarf_add_expr_addr_b; + dwarf_add_expr_gen; + dwarf_add_fde_inst; + dwarf_add_file_decl; + dwarf_add_frame_cie; + dwarf_add_frame_fde; + dwarf_add_frame_fde_b; + dwarf_add_frame_info; + dwarf_add_frame_info_b; + dwarf_add_funcname; + dwarf_add_line_entry; + dwarf_add_pubname; + dwarf_add_typename; + dwarf_add_varname; + dwarf_add_weakname; + dwarf_arrayorder; + dwarf_attr; + dwarf_attr_offset; + dwarf_attrlist; + dwarf_bitoffset; + dwarf_bitsize; + dwarf_bytesize; + dwarf_child; + dwarf_dealloc; + dwarf_def_macro; + dwarf_die_CU_offset; + dwarf_die_link; + dwarf_diename; + dwarf_dieoffset; + dwarf_elf_init; + dwarf_end_macro_file; + dwarf_errmsg; + dwarf_errno; + dwarf_expand_frame_instructions; + dwarf_expr_current_offset; + dwarf_expr_into_block; + dwarf_fde_cfa_offset; + dwarf_find_macro_value_start; + dwarf_finish; + dwarf_formaddr; + dwarf_formblock; + dwarf_formflag; + dwarf_formref; + dwarf_formsdata; + dwarf_formstring; + dwarf_formudata; + dwarf_func_cu_offset; + dwarf_func_die_offset; + dwarf_func_name_offsets; + dwarf_funcname; + dwarf_get_abbrev; + dwarf_get_abbrev_children_flag; + dwarf_get_abbrev_code; + dwarf_get_abbrev_entry; + dwarf_get_abbrev_tag; + dwarf_get_address_size; + dwarf_get_arange; + dwarf_get_arange_cu_header_offset; + dwarf_get_arange_info; + dwarf_get_aranges; + 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_elf; + dwarf_get_fde_at_pc; + dwarf_get_fde_exception_info; + dwarf_get_fde_for_die; + dwarf_get_fde_info_for_all_regs; + dwarf_get_fde_info_for_reg; + dwarf_get_fde_instr_bytes; + dwarf_get_fde_list; + dwarf_get_fde_list_eh; + dwarf_get_fde_n; + dwarf_get_fde_range; + dwarf_get_funcs; + dwarf_get_globals; + dwarf_get_loclist_entry; + dwarf_get_macro_details; + dwarf_get_relocation_info; + dwarf_get_relocation_info_count; + dwarf_get_section_bytes; + dwarf_get_str; + dwarf_get_types; + dwarf_get_vars; + dwarf_get_weaks; + dwarf_global_cu_offset; + dwarf_global_die_offset; + dwarf_global_formref; + dwarf_global_name_offsets; + dwarf_globname; + dwarf_hasattr; + dwarf_hasform; + dwarf_highpc; + dwarf_init; + dwarf_lineaddr; + dwarf_linebeginstatement; + dwarf_lineblock; + dwarf_lineendsequence; + dwarf_lineno; + dwarf_lineoff; + dwarf_linesrc; + dwarf_lne_end_sequence; + dwarf_lne_set_address; + dwarf_loclist; + dwarf_loclist_n; + dwarf_lowpc; + dwarf_new_die; + dwarf_new_expr; + dwarf_new_fde; + dwarf_next_cu_header; + dwarf_nextglob; + dwarf_offdie; + dwarf_p_dealloc; + dwarf_print_memory_stats; + dwarf_producer_finish; + dwarf_producer_init; + dwarf_producer_init_b; + dwarf_reset_section_bytes; + dwarf_set_stringcheck; + dwarf_siblingof; + dwarf_srcfiles; + dwarf_srclang; + dwarf_srclines; + dwarf_start_macro_file; + dwarf_tag; + dwarf_transform_to_disk_form; + dwarf_type_cu_offset; + dwarf_type_die_offset; + dwarf_type_name_offsets; + dwarf_typename; + dwarf_undef_macro; + dwarf_var_cu_offset; + dwarf_var_die_offset; + dwarf_var_name_offsets; + dwarf_varname; + dwarf_vendor_ext; + dwarf_weak_cu_offset; + dwarf_weak_die_offset; + dwarf_weak_name_offsets; + dwarf_weakname; + dwarf_whatattr; + dwarf_whatform; + dwarf_whatform_direct; + local: + *; +}; diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_alloc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_alloc.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,71 @@ +/* + + 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 + 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 + +*/ + + + +#include "config.h" +#include "dwarf_incl.h" +#include + +/* + 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. +*/ + /*ARGSUSED*/ + Dwarf_Ptr _dwarf_p_get_alloc(Dwarf_P_Debug dbg, Dwarf_Unsigned size) +{ + void *sp; + + sp = malloc(size); + memset(sp,0, (int) size); + return sp; +} + + + /*ARGSUSED*/ void +dwarf_p_dealloc(void *space, Dwarf_Unsigned typ) +{ + free(space); + return; +} + + +/* Essentially a stub for now. */ + /*ARGSUSED*/ void +_dwarf_p_dealloc(Dwarf_P_Debug dbg, Dwarf_Small * ptr) +{ + dwarf_p_dealloc(ptr, DW_DLA_STRING); +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_alloc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_alloc.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,40 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +Dwarf_Ptr _dwarf_p_get_alloc(Dwarf_P_Debug, Dwarf_Unsigned); + +void _dwarf_p_dealloc(Dwarf_P_Debug dbg, Dwarf_Small * ptr); diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_arange.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_arange.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,336 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#ifdef HAVE_ELFACCESS_H +#include +#endif +#include "pro_incl.h" +#include "pro_arange.h" +#include "pro_section.h" +#include "pro_reloc.h" + + + +/* + This function adds another address range + to the list of address ranges for the + given Dwarf_P_Debug. It returns 0 on error, + and 1 otherwise. +*/ +Dwarf_Unsigned +dwarf_add_arange(Dwarf_P_Debug dbg, + 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); +} + +/* + This function adds another address range + to the list of address ranges for the + given Dwarf_P_Debug. It returns 0 on error, + and 1 otherwise. +*/ +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_P_Arange arange; + + if (dbg == NULL) { + _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)); + if (arange == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (0); + } + + arange->ag_begin_address = begin_address; + arange->ag_length = length; + arange->ag_symbol_index = symbol_index; + arange->ag_end_symbol_index = end_symbol_index; + arange->ag_end_symbol_offset = offset_from_end_sym; + + if (dbg->de_arange == NULL) + dbg->de_arange = dbg->de_last_arange = arange; + else { + dbg->de_last_arange->ag_next = arange; + dbg->de_last_arange = arange; + } + dbg->de_arange_count++; + + return (1); +} + + +int +_dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, Dwarf_Error * error) +{ + /* Total num of bytes in .debug_aranges section. */ + Dwarf_Unsigned arange_num_bytes; + + /* + Adjustment to align the start of the actual address ranges on a + boundary aligned with twice the address size. */ + Dwarf_Small remainder; + + /* Total number of bytes excluding the length field. */ + Dwarf_Unsigned adjusted_length; + + /* Points to first byte of .debug_aranges buffer. */ + Dwarf_Small *arange; + + /* Fills in the .debug_aranges buffer. */ + Dwarf_Small *arange_ptr; + + /* Scans the list of address ranges provided by user. */ + Dwarf_P_Arange given_arange; + + /* Used to fill in 0. */ + const Dwarf_Signed big_zero = 0; + + int extension_word_size = dbg->de_64bit_extension ? 4 : 0; + int uword_size = dbg->de_offset_size; + int upointer_size = dbg->de_pointer_size; + int res; + + + /* ***** 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. */ + + /* + Adjust the size so that the set of aranges begins on a boundary + that aligned with twice the address size. This is a Libdwarf + requirement. */ + remainder = arange_num_bytes % (2 * upointer_size); + if (remainder != 0) + 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_ptr = arange; + if (arange == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (0); + } + if (extension_word_size) { + 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 the total length of .debug_aranges section. */ + adjusted_length = arange_num_bytes - uword_size + - extension_word_size; + { + Dwarf_Unsigned du = adjusted_length; + + 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; + + 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); + arange_ptr += uword_size; + + { + 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); + } + } + } + + /* 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); + + /* Write the size of addresses. */ + *arange_ptr = dbg->de_pointer_size; + arange_ptr++; + + /* + Write the size of segment addresses. This is zero for MIPS + architectures. */ + *arange_ptr = 0; + arange_ptr++; + + /* + 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; + + + + + + /* 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) { + + /* 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; + + 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); + } + } + + /* 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; + } + } + + WRITE_UNALIGNED(dbg, (void *) arange_ptr, + (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); + return (int) dbg->de_n_debug_sect; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_arange.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_arange.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,62 @@ +/* + + Copyright (C) 2000 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 + +*/ + + +/* + If ag_end_symbol_index is zero, + ag_length must be known and non-zero. + + + Deals with length being known costant or fr + assembler output, not known. + +*/ + +struct Dwarf_P_Arange_s { + Dwarf_Addr ag_begin_address; /* known address or for + symbolic assem output, + offset of symbol */ + Dwarf_Addr ag_length; /* zero or address or offset */ + Dwarf_Unsigned ag_symbol_index; + + Dwarf_P_Arange ag_next; + + Dwarf_Unsigned ag_end_symbol_index; /* zero or index/id of end + symbol */ + Dwarf_Addr ag_end_symbol_offset; /* known address or for + symbolic assem output, + offset of end symbol */ + +}; diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_die.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_die.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,390 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#include "pro_incl.h" +#include "pro_die.h" + +#ifndef R_MIPS_NONE +#define R_MIPS_NONE 0 +#endif + +/* adds an attribute to a die */ +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 +-----------------------------------------------------------------------------*/ +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_Die new_die, ret_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); + } + new_die->di_parent = NULL; + new_die->di_left = NULL; + new_die->di_right = NULL; + new_die->di_child = NULL; + new_die->di_tag = tag; + 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 +-----------------------------------------------------------------------------*/ +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) +{ + int n_nulls; /* to count # of non null neighbors */ + + 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; + + 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; + } + 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; + } + 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; + } + 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; + } + 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; + +} + +/*---------------------------------------------------------------------------- + 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) +{ + if (first_die == NULL) { + 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); + } + dbg->de_dies = first_die; + return 0; +} + +int +_dwarf_pro_add_AT_stmt_list(Dwarf_P_Debug dbg, + 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)); + if (new_attr == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_NOCOUNT); + } + + new_attr->ar_attribute = DW_AT_stmt_list; + new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form; + new_attr->ar_rel_type = dbg->de_offset_reloc; + + new_attr->ar_nbytes = uwordb_size; + new_attr->ar_next = NULL; + new_attr->ar_reloc_len = uwordb_size; + new_attr->ar_data = (char *) + _dwarf_p_get_alloc(NULL, uwordb_size); + if (new_attr->ar_data == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT); + } + { + Dwarf_Unsigned du = 0; + + 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); + return 0; +} + +/*----------------------------------------------------------------------------- + Add AT_name attribute to die +------------------------------------------------------------------------------*/ +Dwarf_P_Attribute +dwarf_add_AT_name(Dwarf_P_Die die, char *name, Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr; + + if (die == NULL) { + 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)); + if (new_attr == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, + (Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + /* fill in the information */ + new_attr->ar_attribute = DW_AT_name; + /* assume that form is string, no debug_str yet */ + new_attr->ar_attribute_form = DW_FORM_string; + new_attr->ar_nbytes = strlen(name) + 1; + new_attr->ar_next = NULL; + new_attr->ar_reloc_len = 0; + new_attr->ar_data = (char *) + _dwarf_p_get_alloc(NULL, strlen(name) + 1); + if (new_attr->ar_data == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_STRING_ALLOC, + (Dwarf_P_Attribute) DW_DLV_BADADDR); + } + strcpy(new_attr->ar_data, name); + + new_attr->ar_rel_type = R_MIPS_NONE; + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(die, new_attr); + return new_attr; +} + + +/*----------------------------------------------------------------------------- + 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) +{ + Dwarf_P_Attribute new_attr; + + if (ownerdie == NULL) { + 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)); + if (new_attr == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, + (Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + /* fill in the information */ + new_attr->ar_attribute = DW_AT_comp_dir; + /* assume that form is string, no debug_str yet */ + new_attr->ar_attribute_form = DW_FORM_string; + new_attr->ar_nbytes = strlen(current_working_directory) + 1; + 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); + if (new_attr->ar_data == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_STRING_ALLOC, + (Dwarf_P_Attribute) DW_DLV_BADADDR); + } + strcpy(new_attr->ar_data, current_working_directory); + + new_attr->ar_rel_type = R_MIPS_NONE; + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + +int +_dwarf_pro_add_AT_fde(Dwarf_P_Debug dbg, + 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); + } + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, -1); + } + + /* fill in the information */ + new_attr->ar_attribute = DW_AT_MIPS_fde; + new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form;; + new_attr->ar_rel_type = dbg->de_offset_reloc; + new_attr->ar_nbytes = uwordb_size; + new_attr->ar_next = NULL; + new_attr->ar_reloc_len = uwordb_size; + new_attr->ar_data = (char *) + _dwarf_p_get_alloc(NULL, uwordb_size); + if (new_attr->ar_data == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT); + } + { + Dwarf_Unsigned du = offset; + + WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data, + (const void *) &du, sizeof(du), uwordb_size); + } + + _dwarf_pro_add_at_to_die(die, new_attr); + + return 0; +} + +int +_dwarf_pro_add_AT_macro_info(Dwarf_P_Debug dbg, + 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); + } + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, -1); + } + + /* fill in the information */ + new_attr->ar_attribute = DW_AT_macro_info; + new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form; + new_attr->ar_rel_type = dbg->de_offset_reloc; + + new_attr->ar_nbytes = uwordb_size; + new_attr->ar_next = NULL; + new_attr->ar_reloc_len = uwordb_size; + new_attr->ar_data = (char *) + _dwarf_p_get_alloc(NULL, uwordb_size); + if (new_attr->ar_data == NULL) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT); + } + { + Dwarf_Unsigned du = offset; + + WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data, + (const void *) &du, sizeof(du), uwordb_size); + } + + _dwarf_pro_add_at_to_die(die, new_attr); + + return 0; +} + + +void +_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++; + } else { + die->di_n_attr = 1; + die->di_attrs = die->di_last_attr = attr; + } +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_die.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_die.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,68 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + + +/* + This struct holds the abbreviation table, before they are written + on disk. Holds a linked list of abbreviations, each consisting of + a bitmap for attributes and a bitmap for forms +*/ +typedef struct Dwarf_P_Abbrev_s *Dwarf_P_Abbrev; + +struct Dwarf_P_Abbrev_s { + Dwarf_Unsigned abb_idx; /* index of abbreviation */ + Dwarf_Tag abb_tag; /* tag of die */ + Dwarf_Ubyte abb_children; /* if children are present */ + Dwarf_ufixed *abb_attrs; /* holds names of attrs */ + Dwarf_ufixed *abb_forms; /* forms of attributes */ + int abb_n_attr; /* num of attrs = # of forms */ + Dwarf_P_Abbrev abb_next; +}; + +/* used in pro_section.c */ + +int _dwarf_pro_add_AT_fde(Dwarf_P_Debug dbg, Dwarf_P_Die die, + Dwarf_Unsigned offset, Dwarf_Error * error); + +int _dwarf_pro_add_AT_stmt_list(Dwarf_P_Debug dbg, + Dwarf_P_Die first_die, + Dwarf_Error * error); + +int _dwarf_pro_add_AT_macro_info(Dwarf_P_Debug dbg, + Dwarf_P_Die first_die, + Dwarf_Unsigned offset, + Dwarf_Error * error); diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_encode_nm.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_encode_nm.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,123 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include "pro_incl.h" + +#define MORE_BYTES 0x80 +#define DATA_MASK 0x7f +#define DIGIT_WIDTH 7 +#define SIGN_BIT 0x40 + + +/*------------------------------------------------------------- + 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 +** passing length. +** number of bytes used returned thru nbytes arg +*/ +int +_dwarf_pro_encode_leb128_nm(Dwarf_Unsigned val, int *nbytes, + char *space, int splen) +{ + char *a; + char *end = space + splen; + + a = space; + do { + 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++; + } while (val); + *nbytes = a - space; + return DW_DLV_OK; +} + +/* return DW_DLV_ERROR or DW_DLV_OK. +** space to write leb number is provided by caller, with caller +** passing length. +** number of bytes used returned thru nbytes arg +** encodes a signed number. +*/ +int +_dwarf_pro_encode_signed_leb128_nm(Dwarf_Signed value, int *nbytes, + char *space, int splen) +{ + char *str; + Dwarf_Signed sign = -(value < 0); + int more = 1; + char *end = space + splen; + + str = space; + + do { + unsigned char byte = value & DATA_MASK; + + 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++; + } while (more); + *nbytes = str - space; + return DW_DLV_OK; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_encode_nm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_encode_nm.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,48 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +/* Bytes needed to encode a number. + Not a tight bound, just a reasonable bound. +*/ +#define ENCODE_SPACE_NEEDED (2*sizeof(Dwarf_Unsigned)) + + +int _dwarf_pro_encode_leb128_nm(Dwarf_Unsigned val, int *nbytes, + char *space, int splen); + +int _dwarf_pro_encode_signed_leb128_nm(Dwarf_Signed value, int *nbytes, + char *space, int splen); diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_error.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_error.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,97 @@ +/* + + Copyright (C) 2000, 2002 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 + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#ifdef HAVE_ELF_H +#include +#endif + +#include +#include +#include +#include +#include "pro_incl.h" + +extern char *_dwarf_errmsgs[]; + +/* + This function performs error handling as described in the + libdwarf consumer document section 3. Dbg is the Dwarf_P_debug + structure being processed. Error is a pointer to the pointer + to the error descriptor that will be returned. Errval is an + error code listed in dwarf_error.h. +*/ +void +_dwarf_p_error(Dwarf_P_Debug dbg, + 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]); + 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; + } + + 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; + } + + abort(); +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_error.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_error.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,52 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + + +/* Handle error passing in the name of the Dwarf_P_Debug + User must supply {} around the macro. + Putting the {} here leads to macro uses that don't look like C. + The error argument to dwarf_error is hard coded here as 'error' +*/ +#define DWARF_P_DBG_ERROR(dbg,errval,retval) \ + _dwarf_p_error(dbg,error,errval); return(retval); + +struct Dwarf_Error_s { + Dwarf_Sword er_errval; +}; + +void _dwarf_p_error(Dwarf_P_Debug dbg, Dwarf_Error * error, + Dwarf_Word errval); diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_expr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_expr.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,550 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#include +#include "pro_incl.h" +#include "pro_expr.h" + +/* + This function creates a new expression + struct that can be used to build up a + location expression. +*/ +Dwarf_P_Expr +dwarf_new_expr(Dwarf_P_Debug dbg, Dwarf_Error * error) +{ + Dwarf_P_Expr ret_expr; + + if (dbg == 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)); + if (ret_expr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (NULL); + } + + ret_expr->ex_dbg = dbg; + + return (ret_expr); +} + + +Dwarf_Unsigned +dwarf_add_expr_gen(Dwarf_P_Expr expr, + 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_buffer2[ENCODE_SPACE_NEEDED]; + int res; + Dwarf_P_Debug dbg = expr->ex_dbg; + + /* + Give the buffer where the operands are first going to be + assembled the largest alignment. */ + Dwarf_Unsigned operand_buffer[10]; + + /* + Size of the byte stream buffer that needs to be memcpy-ed. */ + int operand_size; + + /* + Points to the byte stream for the first operand, and finally to + the buffer that is memcp-ed into the Dwarf_P_Expr_s struct. */ + Dwarf_Small *operand; + + /* Size of the byte stream for second operand. */ + int operand2_size; + + /* Points to next byte to be written in Dwarf_P_Expr_s struct. */ + Dwarf_Small *next_byte_ptr; + + /* Offset past the last byte written into Dwarf_P_Expr_s. */ + int next_byte_offset; + + /* ***** BEGIN CODE ***** */ + + if (expr == NULL) { + _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); + } + + operand = NULL; + operand_size = 0; + + switch (opcode) { + 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_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: + 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; + + 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: + break; + + case DW_OP_addr: + _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; + + 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; + + 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; + + 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; + + 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; + + 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; + + 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; + + 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; + + case DW_OP_dup: + case DW_OP_drop: + 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; + + case DW_OP_over: + case DW_OP_swap: + case DW_OP_rot: + case DW_OP_deref: + case DW_OP_xderef: + 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; + + 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_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; + + 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_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); + + 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; + + case DW_OP_nop: + break; + + default: + _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); + } + + next_byte_ptr = + &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset; + + *next_byte_ptr = opcode; + next_byte_ptr++; + memcpy(next_byte_ptr, operand, operand_size); + + expr->ex_next_byte_offset = next_byte_offset; + return (next_byte_offset); +} + +Dwarf_Unsigned +dwarf_add_expr_addr_b(Dwarf_P_Expr expr, + Dwarf_Unsigned addr, + Dwarf_Unsigned sym_index, Dwarf_Error * error) +{ + Dwarf_P_Debug dbg; + Dwarf_Small *next_byte_ptr; + Dwarf_Unsigned next_byte_offset; + int upointer_size; + + if (expr == NULL) { + _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); + } + + 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); + } + + next_byte_ptr = + &(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); + + if (expr->ex_reloc_offset != 0) { + _dwarf_p_error(dbg, error, DW_DLE_MULTIPLE_RELOC_IN_EXPR); + return (DW_DLV_NOCOUNT); + } + + expr->ex_reloc_sym_index = sym_index; + expr->ex_reloc_offset = expr->ex_next_byte_offset + 1; + + expr->ex_next_byte_offset = next_byte_offset; + return (next_byte_offset); +} + +Dwarf_Unsigned +dwarf_add_expr_addr(Dwarf_P_Expr expr, + Dwarf_Unsigned addr, + Dwarf_Signed sym_index, Dwarf_Error * error) +{ + return + dwarf_add_expr_addr_b(expr, addr, (Dwarf_Unsigned) sym_index, + error); +} + + +Dwarf_Unsigned +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); + } + + if (expr->ex_dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_NOCOUNT); + } + + return (expr->ex_next_byte_offset); +} + + +Dwarf_Addr +dwarf_expr_into_block(Dwarf_P_Expr expr, + Dwarf_Unsigned * length, Dwarf_Error * error) +{ + if (expr == NULL) { + _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); + } + + if (length != NULL) + *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 + emit a warning about the following line). */ + return ((Dwarf_Addr)(uintptr_t) &(expr->ex_byte_stream[0])); +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_expr.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_expr.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,45 @@ +/* + + Copyright (C) 2000 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 MAXIMUM_LOC_EXPR_LENGTH 20 + +struct Dwarf_P_Expr_s { + Dwarf_Small ex_byte_stream[MAXIMUM_LOC_EXPR_LENGTH]; + Dwarf_P_Debug ex_dbg; + Dwarf_Unsigned ex_next_byte_offset; + Dwarf_Unsigned ex_reloc_sym_index; + Dwarf_Unsigned ex_reloc_offset; +}; diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_finish.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_finish.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,55 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include "pro_incl.h" + +/*--------------------------------------------------------------- + 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_dealloc((void *) dbg, 0); + return 0; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_forms.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_forms.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,857 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#include +#include "pro_incl.h" +#include "pro_expr.h" + +#ifndef R_MIPS_NONE +#define R_MIPS_NONE 0 +#endif + + + /* Indicates no relocation needed. */ +#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); + +/* + This function adds an attribute whose value is + a target address to the given die. The attribute + is given the name provided by attr. The address + is given in pc_value. +*/ +/* 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) +{ + return + dwarf_add_AT_targ_address_b(dbg, + ownerdie, + attr, + pc_value, + (Dwarf_Unsigned) sym_index, error); +} + +/* new interface */ +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_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); + } + + if (ownerdie == NULL) { + _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); + } + + 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); + } + + new_attr->ar_attribute = attr; + new_attr->ar_attribute_form = DW_FORM_addr; + 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; + else + new_attr->ar_rel_type = R_MIPS_NONE; + + new_attr->ar_data = (char *) + _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); + } + WRITE_UNALIGNED(dbg, new_attr->ar_data, + (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; +} + + +/* + This function adds attributes whose value + is an unsigned constant. It determines the + size of the value field from the value of + the constant. +*/ +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_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); + } + + if (ownerdie == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + switch (attr) { + case DW_AT_ordering: + case DW_AT_byte_size: + case DW_AT_bit_offset: + case DW_AT_bit_size: + case DW_AT_inline: + case DW_AT_language: + case DW_AT_visibility: + case DW_AT_virtuality: + case DW_AT_accessibility: + case DW_AT_address_class: + case DW_AT_calling_convention: + case DW_AT_encoding: + case DW_AT_identifier_case: + case DW_AT_MIPS_loop_unroll_factor: + case DW_AT_MIPS_software_pipeline_depth: + break; + + case DW_AT_decl_column: + case DW_AT_decl_file: + case DW_AT_decl_line: + case DW_AT_const_value: + case DW_AT_start_scope: + case DW_AT_stride_size: + case DW_AT_count: + break; + + default:{ + _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + } + + /* + Compute the number of bytes needed to hold constant. */ + if (value <= UCHAR_MAX) { + attr_form = DW_FORM_data1; + size = 1; + } else if (value <= USHRT_MAX) { + attr_form = DW_FORM_data2; + size = 2; + } else if (value <= UINT_MAX) { + attr_form = DW_FORM_data4; + size = 4; + } else { + attr_form = DW_FORM_data8; + size = 8; + } + + 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); + } + + 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_nbytes = size; + new_attr->ar_next = 0; + + new_attr->ar_data = (char *) + _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); + } + WRITE_UNALIGNED(dbg, new_attr->ar_data, + (const void *) &value, sizeof(value), size); + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + + +/* + This function adds attributes whose value + is an signed constant. It determines the + size of the value field from the value of + the constant. +*/ +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_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); + } + + if (ownerdie == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + switch (attr) { + case DW_AT_upper_bound: + case DW_AT_lower_bound: + break; + + default:{ + _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + } + + /* + Compute the number of bytes needed to hold constant. */ + if (value >= SCHAR_MIN && value <= SCHAR_MAX) { + attr_form = DW_FORM_data1; + size = 1; + } else if (value >= SHRT_MIN && value <= SHRT_MAX) { + attr_form = DW_FORM_data2; + size = 2; + } else if (value >= INT_MIN && value <= INT_MAX) { + attr_form = DW_FORM_data4; + size = 4; + } else { + attr_form = DW_FORM_data8; + size = 8; + } + + 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); + } + + 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_nbytes = size; + new_attr->ar_next = 0; + + new_attr->ar_data = (char *) + _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); + } + WRITE_UNALIGNED(dbg, new_attr->ar_data, + (const void *) &value, sizeof(value), size); + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + + +/* + This function adds attributes whose value + is a location expression. +*/ +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) +{ + char encode_buffer[ENCODE_SPACE_NEEDED]; + int res; + Dwarf_P_Attribute new_attr; + Dwarf_Half attr_form; + char *len_str; + 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); + } + + if (ownerdie == NULL) { + _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); + } + + if (loc_expr->ex_dbg != dbg) { + _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; + + switch (attr) { + case DW_AT_location: + case DW_AT_string_length: + case DW_AT_const_value: + case DW_AT_use_location: + case DW_AT_return_addr: + case DW_AT_data_member_location: + case DW_AT_frame_base: + case DW_AT_static_link: + case DW_AT_vtable_elem_location: + break; + + default:{ + _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + } + + /* + 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; + } else if (block_size <= USHRT_MAX) { + 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; + } 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; + } + + 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); + } + + 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; + } else { + 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; + + 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); + if (new_attr->ar_data == NULL) { + _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); + } else { + /* is uleb number form */ + 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); + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + + +/* + This function adds attributes of reference class. + The references here are local CU references, + not DW_FORM_ref_addr. + The offset field is 4 bytes for 32-bit objects, + and 8-bytes for 64-bit objects. Otherdie is the + that is referenced by ownerdie. + + For reference attributes, the ar_data and ar_nbytes + are not needed. Instead, the ar_ref_die points to + the other die, and its di_offset value is used as + the reference value. +*/ +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_Attribute new_attr; + + 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); + } + + if (otherdie == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + + switch (attr) { + case DW_AT_specification: + case DW_AT_discr: + case DW_AT_common_reference: + case DW_AT_import: + case DW_AT_containing_type: + case DW_AT_default_value: + case DW_AT_abstract_origin: + case DW_AT_friend: + case DW_AT_priority: + case DW_AT_type: + case DW_AT_lower_bound: + case DW_AT_upper_bound: + case DW_AT_count: + 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; + + default:{ + _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + } + + 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); + } + + new_attr->ar_attribute = attr; + new_attr->ar_attribute_form = dbg->de_ar_ref_attr_form; + new_attr->ar_nbytes = dbg->de_offset_size; + new_attr->ar_reloc_len = dbg->de_offset_size; + new_attr->ar_ref_die = otherdie; + new_attr->ar_rel_type = R_MIPS_NONE; + new_attr->ar_next = 0; + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + + +/* + This function adds attributes of the flag class. +*/ +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_Attribute new_attr; + + 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); + } + + switch (attr) { + case DW_AT_is_optional: + case DW_AT_artificial: + case DW_AT_declaration: + 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; + + default:{ + _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + } + + 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); + } + + 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_rel_type = R_MIPS_NONE; + new_attr->ar_next = 0; + + new_attr->ar_data = (char *) + _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); + } + memcpy(new_attr->ar_data, &flag, 1); + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + + +/* + This function adds values of attributes + belonging to the string class. +*/ +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_Attribute new_attr; + + 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); + } + + 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); + } + + switch (attr) { + case DW_AT_name: + 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; + + default:{ + _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + } + + new_attr->ar_attribute = attr; + new_attr->ar_attribute_form = DW_FORM_string; + new_attr->ar_nbytes = strlen(string) + 1; + new_attr->ar_next = 0; + + new_attr->ar_data = + (char *) _dwarf_p_get_alloc(NULL, 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); + } + + 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 */ + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + + +Dwarf_P_Attribute +dwarf_add_AT_const_value_string(Dwarf_P_Die ownerdie, + 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); + } + + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(NULL, 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); + } + + new_attr->ar_attribute = DW_AT_const_value; + new_attr->ar_attribute_form = DW_FORM_string; + new_attr->ar_nbytes = strlen(string_value) + 1; + new_attr->ar_next = 0; + + new_attr->ar_data = + (char *) _dwarf_p_get_alloc(NULL, 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); + } + + 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 */ + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + + +Dwarf_P_Attribute +dwarf_add_AT_producer(Dwarf_P_Die ownerdie, + 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); + } + + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(NULL, 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); + } + + new_attr->ar_attribute = DW_AT_producer; + new_attr->ar_attribute_form = DW_FORM_string; + new_attr->ar_nbytes = strlen(producer_string) + 1; + new_attr->ar_next = 0; + + new_attr->ar_data = + (char *) _dwarf_p_get_alloc(NULL, 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); + } + + 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 */ + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + + +Dwarf_P_Attribute +dwarf_add_AT_const_value_signedint(Dwarf_P_Die ownerdie, + Dwarf_Signed signed_value, + Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr; + int leb_size; + char encode_buffer[ENCODE_SPACE_NEEDED]; + int res; + + if (ownerdie == NULL) { + _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)); + if (new_attr == NULL) { + _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_next = 0; + + res = _dwarf_pro_encode_signed_leb128_nm(signed_value, &leb_size, + 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); + } + new_attr->ar_data = (char *) + _dwarf_p_get_alloc(NULL, leb_size); + if (new_attr->ar_data == NULL) { + _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; + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} + + +Dwarf_P_Attribute +dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die ownerdie, + Dwarf_Unsigned unsigned_value, + Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr; + int leb_size; + char encode_buffer[ENCODE_SPACE_NEEDED]; + int res; + + if (ownerdie == NULL) { + _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)); + if (new_attr == NULL) { + _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_next = 0; + + res = _dwarf_pro_encode_leb128_nm(unsigned_value, &leb_size, + 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); + } + new_attr->ar_data = (char *) + _dwarf_p_get_alloc(NULL, leb_size); + if (new_attr->ar_data == NULL) { + _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; + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + return new_attr; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_frame.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_frame.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,552 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#include +#include "pro_incl.h" +#include "pro_frame.h" + +static void _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, + 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 +--------------------------------------------------------------------------*/ +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) +{ + 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; + } 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->cie_version = DW_CIE_VERSION; + curcie->cie_aug = augmenter; + curcie->cie_code_align = code_align; + curcie->cie_data_align = data_align; + curcie->cie_ret_reg = return_reg; + curcie->cie_inst = (char *) init_bytes; + curcie->cie_inst_bytes = (long) init_n_bytes; + curcie->cie_next = NULL; + return dbg->de_n_cie; +} + + +/*------------------------------------------------------------------------- + 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 */ + 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) +{ + return dwarf_add_frame_fde_b(dbg, fde, die, cie, virt_addr, + 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 curfde; + + fde->fde_die = die; + fde->fde_cie = (long) cie; + fde->fde_initloc = virt_addr; + fde->fde_r_symidx = symidx; + fde->fde_addr_range = code_len; + fde->fde_offset_into_exception_tables = DW_DLX_NO_EH_OFFSET; + fde->fde_exception_table_symbol = 0; + fde->fde_end_symbol_offset = offset_from_end_sym; + fde->fde_end_symbol = symidx_of_end; + + curfde = dbg->de_last_fde; + if (curfde == NULL) { + 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++; + } + 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. +--------------------------------------------------------------------------*/ +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) +{ + + 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); + +} + + /*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 curfde; + + fde->fde_die = die; + fde->fde_cie = (long) cie; + fde->fde_initloc = virt_addr; + fde->fde_r_symidx = symidx; + fde->fde_addr_range = code_len; + fde->fde_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; + + + curfde = dbg->de_last_fde; + if (curfde == NULL) { + 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++; + } + return dbg->de_n_fde; +} + + +/*------------------------------------------------------------------- + Create a new fde +---------------------------------------------------------------------*/ +Dwarf_P_Fde +dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error * error) +{ + Dwarf_P_Fde fde; + + fde = (Dwarf_P_Fde) + _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); + } + 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 +-------------------------------------------------------------------------*/ +Dwarf_P_Fde +dwarf_fde_cfa_offset(Dwarf_P_Fde fde, + Dwarf_Unsigned reg, + Dwarf_Signed offset, Dwarf_Error * error) +{ + Dwarf_Ubyte opc, regno; + char *ptr; + Dwarf_P_Frame_Pgm curinst; + int nbytes; + int res; + char buff1[ENCODE_SPACE_NEEDED]; + + curinst = (Dwarf_P_Frame_Pgm) + _dwarf_p_get_alloc(NULL, 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); + } + opc = DW_CFA_offset; + regno = reg; + if (regno & 0xc0) { + DWARF_P_DBG_ERROR(NULL, DW_DLE_REGNO_OVFL, + (Dwarf_P_Fde) DW_DLV_BADADDR); + } + opc = opc | regno; /* lower 6 bits are register number */ + curinst->dfp_opcode = opc; + res = _dwarf_pro_encode_leb128_nm(offset, &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); + + curinst->dfp_args = ptr; + curinst->dfp_nbytes = nbytes; + curinst->dfp_next = NULL; + + _dwarf_pro_add_to_fde(fde, curinst); + return fde; +} + +/* + Generic routine to add opcode to fde instructions. val1 and + val2 are parameters whose interpretation depends on the 'op'. + + This does not work properly for DW_DLC_SYMBOLIC_RELOCATIONS + for DW_CFA_set_loc or DW_DVA_advance_loc* 'op', as + these ops normally are addresses or (DW_CFA_set_loc) + or code lengths (DW_DVA_advance_loc*) and such must be + represented with relocations and symbol indices for + DW_DLC_SYMBOLIC_RELOCATIONS. + +*/ +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_Frame_Pgm curinst; + int nbytes, nbytes1, nbytes2; + Dwarf_Ubyte db; + Dwarf_Half dh; + Dwarf_Word dw; + Dwarf_Unsigned du; + char *ptr; + int res; + char buff1[ENCODE_SPACE_NEEDED]; + char buff2[ENCODE_SPACE_NEEDED]; + + + nbytes = 0; + ptr = NULL; + curinst = (Dwarf_P_Frame_Pgm) + _dwarf_p_get_alloc(NULL, 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); + } + + 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; + + 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; + + 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; + + 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; + + 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); + } + + 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; + + 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; + + default: + break; + } + + curinst->dfp_opcode = op; + curinst->dfp_args = ptr; + curinst->dfp_nbytes = nbytes; + curinst->dfp_next = NULL; + + _dwarf_pro_add_to_fde(fde, curinst); + return fde; +} + + +/*------------------------------------------------------------------------ + instructions are added to 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)); + } 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)); + } +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_frame.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_frame.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,126 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +/* + Largest register value that can be coded into + the opcode since there are only 6 bits in the + register field. +*/ +#define MAX_6_BIT_VALUE 0x3f + +/* + This struct holds debug_frame instructions +*/ +typedef struct Dwarf_P_Frame_Pgm_s *Dwarf_P_Frame_Pgm; + +struct Dwarf_P_Frame_Pgm_s { + Dwarf_Ubyte dfp_opcode; /* opcode - includes reg # */ + char *dfp_args; /* operands */ + int dfp_nbytes; /* number of bytes in args */ +#if 0 + Dwarf_Unsigned dfp_sym_index; /* 0 unless reloc needed */ +#endif + Dwarf_P_Frame_Pgm dfp_next; +}; + + +/* + This struct has cie related information. Used to gather data + from user program, and later to transform to disk form +*/ +struct Dwarf_P_Cie_s { + Dwarf_Ubyte cie_version; + char *cie_aug; /* augmentation */ + Dwarf_Ubyte cie_code_align; /* alignment of code */ + Dwarf_Sbyte cie_data_align; + Dwarf_Ubyte cie_ret_reg; /* return register # */ + char *cie_inst; /* initial instruction */ + long cie_inst_bytes; + /* no of init_inst */ + Dwarf_P_Cie cie_next; +}; + + +/* producer fields */ +struct Dwarf_P_Fde_s { + Dwarf_Unsigned fde_unused1; + + /* function/subr die for this fde */ + Dwarf_P_Die fde_die; + + /* index to asso. cie */ + Dwarf_Word fde_cie; + + /* Address of first location of the code this frame applies to If + fde_end_symbol non-zero, this represents the offset from the + symbol indicated by fde_r_symidx */ + Dwarf_Addr fde_initloc; + + /* Relocation symbol for address of the code this frame applies to. + */ + Dwarf_Unsigned fde_r_symidx; + + /* Bytes of instr for this fde, if known */ + Dwarf_Unsigned fde_addr_range; + + /* linked list of instructions we will put in fde. */ + Dwarf_P_Frame_Pgm fde_inst; + + /* number of instructions in fde */ + long fde_n_inst; + + /* number of bytes of inst in fde */ + long fde_n_bytes; + + /* offset into exception table for this function. */ + Dwarf_Signed fde_offset_into_exception_tables; + + /* The symbol for the exception table elf section. */ + Dwarf_Unsigned fde_exception_table_symbol; + + /* pointer to last inst */ + Dwarf_P_Frame_Pgm fde_last_inst; + + Dwarf_P_Fde fde_next; + + /* The symbol and offset of the end symbol. When fde_end_symbol is + non-zero we must represent the */ + Dwarf_Addr fde_end_symbol_offset; + Dwarf_Unsigned fde_end_symbol; + + int fde_uwordb_size; +}; diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_funcs.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_funcs.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,62 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#ifdef HAVE_ELFACCESS_H +#include +#endif +#include "pro_incl.h" +#include "pro_section.h" + +/* + This function adds another function name to the + list of function names for the given Dwarf_P_Debug. + It returns 0 on error, and 1 otherwise. +*/ +Dwarf_Unsigned +dwarf_add_funcname(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + char *function_name, Dwarf_Error * error) +{ + return + _dwarf_add_simple_name_entry(dbg, die, function_name, + dwarf_snk_funcname, error); + +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_incl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_incl.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,73 @@ +/* + + Copyright (C) 2000, 2002 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 + +*/ + + + +#ifdef HAVE_ELF_H +#include +#endif + +/* The target address is given: the place in the source integer + is to be determined. +*/ +#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 + + + +#include "libdwarf.h" + +#include "dwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" +#include "pro_util.h" +#include "pro_encode_nm.h" +#include "pro_alloc.h" diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_init.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_init.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,249 @@ +/* + + 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 + 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 + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#include "pro_incl.h" +#include "pro_section.h" /* for MAGIC_SECT_NO */ +#include "pro_reloc_symbolic.h" +#include "pro_reloc_stream.h" + + +static void common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags); + +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 +--------------------------------------------------------------------*/ + /* We want the following to have an elf section number that matches + 'nothing' */ +static struct Dwarf_P_Section_Data_s init_sect = { + MAGIC_SECT_NO, 0, 0, 0, 0 +}; + +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_P_Debug dbg; + dbg = (Dwarf_P_Debug) _dwarf_p_get_alloc(NULL, + sizeof(struct + Dwarf_P_Debug_s)); + if (dbg == NULL) { + 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)); + /* For the time being */ + if (func == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC, + (Dwarf_P_Debug) DW_DLV_BADADDR); + } + dbg->de_func_b = func; + dbg->de_errhand = errhand; + dbg->de_errarg = errarg; + common_init(dbg, flags); + return dbg; + +} + +Dwarf_P_Debug +dwarf_producer_init(Dwarf_Unsigned flags, + Dwarf_Callback_Func 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)); + if (dbg == NULL) { + 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)); + /* For the time being */ + if (func == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC, + (Dwarf_P_Debug) DW_DLV_BADADDR); + } + dbg->de_func = func; + dbg->de_errhand = errhand; + dbg->de_errarg = errarg; + common_init(dbg, flags); + return dbg; +} +static void +common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags) +{ + unsigned int k; + + + dbg->de_version_magic_number = PRO_VERSION_MAGIC; + dbg->de_n_debug_sect = 0; + dbg->de_debug_sects = &init_sect; + dbg->de_current_active_section = &init_sect; + dbg->de_flags = flags; + + /* Now, with flags set, can use 64bit tests */ + + + +#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 */ + 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); + /* 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 + dwarf2 v2.0.0 32bit offsets, as emitted by cygnus tools. And + 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. */ + 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); + dbg->de_offset_reloc = dbg->de_ptr_reloc; +#endif + 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); + } else { +#if HAVE_ELF64_GETEHDR + dbg->de_relocation_record_size = + IS_64BIT(dbg) ? sizeof(Elf64_Rel) : sizeof(Elf32_Rel); +#else + dbg->de_relocation_record_size = sizeof(Elf32_Rel); +#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; + } else { + 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; + } 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; + } + for (k = 0; k < NUM_DEBUG_SECTIONS; ++k) { + + Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[k]; + + prel->pr_slots_per_block_to_alloc = DEFAULT_SLOTS_PER_BLOCK; + } + /* First assume host, target same endianness */ + dbg->de_same_endian = 1; + dbg->de_copy_word = memcpy; +#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; + } +#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; + } +#endif /* !WORDS_BIGENDIAN */ + + + return; + +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_line.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_line.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,300 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#ifdef HAVE_ELF_H +#include +#endif +#include "pro_incl.h" +#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); + +/*------------------------------------------------------------------------- + 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 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); + 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. +-------------------------------------------------------------------------*/ +Dwarf_Unsigned +dwarf_lne_set_address(Dwarf_P_Debug dbg, + 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); + 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. +-------------------------------------------------------------------------*/ +Dwarf_Unsigned +dwarf_lne_end_sequence(Dwarf_P_Debug dbg, + 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); + 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. +-----------------------------------------------------------------------------*/ +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) +{ + 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); + + } 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_address = code_address; + dbg->de_last_line->dpl_file = (unsigned long) file_index; + dbg->de_last_line->dpl_line = (unsigned long) line_no; + dbg->de_last_line->dpl_column = (unsigned long) col_no; + dbg->de_last_line->dpl_is_stmt = is_stmt_begin; + dbg->de_last_line->dpl_basic_block = is_bb_begin; + dbg->de_last_line->dpl_opc = opc; + dbg->de_last_line->dpl_r_symidx = symidx; + + return (0); +} + +/*----------------------------------------------------------------------- + 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) +{ + 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; + } 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_name = + (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); + } + strcpy(dbg->de_last_inc_dir->did_name, name); + dbg->de_last_inc_dir->did_next = NULL; + + return dbg->de_n_inc_dirs; +} + +/*----------------------------------------------------------------------- + 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) +{ + Dwarf_P_F_Entry cur; + char *ptr; + int nbytes_idx, nbytes_time, nbytes_len; + char buffidx[ENCODE_SPACE_NEEDED]; + char bufftime[ENCODE_SPACE_NEEDED]; + char bufflen[ENCODE_SPACE_NEEDED]; + 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; + } 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->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); + } + strcpy((char *) cur->dfe_name, name); + res = _dwarf_pro_encode_leb128_nm(dir_idx, &nbytes_idx, + buffidx, sizeof(buffidx)); + if (res != DW_DLV_OK) { + 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)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT); + } + res = _dwarf_pro_encode_leb128_nm(length, &nbytes_len, + bufflen, sizeof(bufflen)); + cur->dfe_args = (char *) + _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); + } + ptr = cur->dfe_args; + memcpy((void *) ptr, buffidx, nbytes_idx); + ptr += nbytes_idx; + memcpy((void *) ptr, bufftime, nbytes_time); + ptr += nbytes_time; + memcpy((void *) ptr, bufflen, nbytes_len); + ptr += nbytes_len; + cur->dfe_nbytes = nbytes_idx + nbytes_time + nbytes_len; + cur->dfe_next = NULL; + + return dbg->de_n_file_entries; +} + + +/*--------------------------------------------------------------------- + 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) +{ + cur_line->dpl_address = 0; + cur_line->dpl_file = 1; + cur_line->dpl_line = 1; + cur_line->dpl_column = 0; + cur_line->dpl_is_stmt = DEFAULT_IS_STMT; + cur_line->dpl_basic_block = false; + cur_line->dpl_next = NULL; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_line.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_line.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,111 @@ +/* + + Copyright (C) 2000 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 VERSION 2 +#define MIN_INST_LENGTH 4 +#define DEFAULT_IS_STMT false + /* line base and range are temporarily defines. + They need to be calculated later */ +#define LINE_BASE -1 +#define LINE_RANGE 4 + +#define OPCODE_BASE 10 +#define MAX_OPCODE 255 + + +/* + This struct is used to hold entries in the include directories + part of statement prologue. +*/ +struct Dwarf_P_Inc_Dir_s { + char *did_name; /* name of directory */ + Dwarf_P_Inc_Dir did_next; +}; + + +/* + This struct holds file entries for the statement prologue. + Defined in pro_line.h +*/ +struct Dwarf_P_F_Entry_s { + char *dfe_name; + char *dfe_args; /* has dir index, time of modification, + length in bytes. Encodes as leb128 */ + int dfe_nbytes; /* number of bytes in args */ + Dwarf_P_F_Entry dfe_next; +}; + + +/* + Struct holding line number information for each of the producer + line entries +*/ +struct Dwarf_P_Line_s { + /* code address */ + Dwarf_Addr dpl_address; + + /* file index, index into file entry */ + Dwarf_Word dpl_file; + + /* line number */ + Dwarf_Word dpl_line; + + /* column number */ + Dwarf_Word dpl_column; + + /* whether its a beginning of a stmt */ + Dwarf_Ubyte dpl_is_stmt; + + /* whether its a beginning of basic blk */ + Dwarf_Ubyte dpl_basic_block; + + /* used to store opcodes set_address, and end_seq */ + Dwarf_Ubyte dpl_opc; + + /* + Used only for relocations. Has index of symbol relative to + which relocation has to be done (the S part in S + A) */ + Dwarf_Unsigned dpl_r_symidx; + + Dwarf_P_Line dpl_next; +}; + +/* + to initialize state machine registers, definition in + pro_line.c +*/ +void _dwarf_pro_reg_init(Dwarf_P_Line); diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_macinfo.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_macinfo.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,472 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#include "pro_incl.h" +#include "pro_section.h" +#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. +*/ + +/* these are gross overestimates of the number of +** bytes needed to store a number in LEB form. +** Just estimates, and since blocks are reasonable size, +** the end-block waste is small. +** Of course the waste is NOT present on disk. +*/ + +#define COMMAND_LEN ENCODE_SPACE_NEEDED +#define LINE_LEN ENCODE_SPACE_NEEDED +#define BASE_MACINFO_MALLOC_LEN 2048 + +static int +libdwarf_compose_begin(Dwarf_P_Debug dbg, int code, + 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; + + /* 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; + } else if (curblk->mb_avail_len < maxlen) { + 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; + } + /* 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); + *nextchar = code; + dbg->de_compose_avail--; + ++dbg->de_compose_used_len; + return DW_DLV_OK; +} + + + +static void +libdwarf_compose_add_string(Dwarf_P_Debug dbg, char *string, size_t len) +{ + struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo; + unsigned char *nextchar; + + nextchar = + (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len); + + len += 1; /* count the null terminator */ + + memcpy(nextchar, string, len); + dbg->de_compose_avail -= len; + dbg->de_compose_used_len += len; + return; + +} +static int +libdwarf_compose_add_line(Dwarf_P_Debug dbg, + Dwarf_Unsigned line, int *compose_error_type) +{ + struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo; + unsigned char *nextchar; + int res; + int nbytes; + + nextchar = + (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); + if (res != DW_DLV_OK) { + *compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE; + return DW_DLV_ERROR; + } + + dbg->de_compose_avail -= nbytes; + dbg->de_compose_used_len += nbytes; + return DW_DLV_OK; +} + +/* + This function actually 'commits' the space used by the + preceeding calls. +*/ +static int +libdwarf_compose_complete(Dwarf_P_Debug dbg, int *compose_error_type) +{ + 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; + } + curblk->mb_avail_len = dbg->de_compose_avail; + curblk->mb_used_len = dbg->de_compose_used_len; + return DW_DLV_OK; +} + + + +int +dwarf_def_macro(Dwarf_P_Debug dbg, + Dwarf_Unsigned line, + char *macname, char *macvalue, Dwarf_Error * error) +{ + size_t len; + size_t len2; + 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); + } + if (macname == 0) { + _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); + } + if (macvalue) { + len2 = strlen(macvalue) + 1; + } else { + len2 = 0; + } + 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); + if (res != DW_DLV_OK) { + _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); + } + 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); + } + 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); + } + return DW_DLV_OK; +} + +int +dwarf_undef_macro(Dwarf_P_Debug dbg, + Dwarf_Unsigned line, + char *macname, Dwarf_Error * error) +{ + + size_t len; + 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); + } + if (macname == 0) { + _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); + } + length_est = COMMAND_LEN + LINE_LEN + len; + res = libdwarf_compose_begin(dbg, DW_MACINFO_undef, length_est, + &compose_error_type); + if (res != DW_DLV_OK) { + _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); + } + 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); + } + return DW_DLV_OK; +} + +int +dwarf_start_macro_file(Dwarf_P_Debug dbg, + 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); + } + length_est = COMMAND_LEN + LINE_LEN + LINE_LEN; + res = libdwarf_compose_begin(dbg, DW_MACINFO_start_file, length_est, + &compose_error_type); + if (res != DW_DLV_OK) { + _dwarf_p_error(NULL, error, compose_error_type); + return (DW_DLV_ERROR); + } + res = libdwarf_compose_add_line(dbg, fileindex, + &compose_error_type); + if (res != DW_DLV_OK) { + _dwarf_p_error(NULL, error, compose_error_type); + return (DW_DLV_ERROR); + } + res = libdwarf_compose_add_line(dbg, linenumber, + &compose_error_type); + if (res != DW_DLV_OK) { + _dwarf_p_error(NULL, error, compose_error_type); + return (DW_DLV_ERROR); + } + return DW_DLV_OK; +} + +int +dwarf_end_macro_file(Dwarf_P_Debug dbg, 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); + } + length_est = COMMAND_LEN; + res = libdwarf_compose_begin(dbg, DW_MACINFO_end_file, length_est, + &compose_error_type); + if (res != DW_DLV_OK) { + _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); + } + return DW_DLV_OK; +} + +int +dwarf_vendor_ext(Dwarf_P_Debug dbg, + Dwarf_Unsigned constant, + char *string, Dwarf_Error * error) +{ + size_t len; + 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); + } + if (string == 0) { + _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); + } + length_est = COMMAND_LEN + LINE_LEN + len; + res = libdwarf_compose_begin(dbg, DW_MACINFO_vendor_ext, length_est, + &compose_error_type); + if (res != DW_DLV_OK) { + _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); + } + 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); + } + return DW_DLV_OK; +} + + + +int +_dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg, + Dwarf_Error * error) +{ + /* Total num of bytes in .debug_macinfo section. */ + Dwarf_Unsigned mac_num_bytes; + + /* Points to first byte of .debug_macinfo buffer. */ + Dwarf_Small *macinfo; + + /* Fills in the .debug_macinfo buffer. */ + Dwarf_Small *macinfo_ptr; + + + /* Used to scan the section data buffers. */ + struct dw_macinfo_block_s *m_prev; + struct dw_macinfo_block_s *m_sect; + + + /* 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; + } + /* 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); + if (macinfo == NULL) { + _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; + } + *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; + } + + dbg->de_first_macinfo = NULL; + dbg->de_current_macinfo = NULL; + + return (int) dbg->de_n_debug_sect; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_macinfo.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_macinfo.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,40 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + + +int _dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg, + Dwarf_Error * error); diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_opaque.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_opaque.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,493 @@ +/* + + Copyright (C) 2000, 2002 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 + +*/ + + +#include + +/* + Sgidefs included to define __uint32_t, + a guaranteed 4-byte quantity. +*/ +#include "libdwarfdefs.h" + +#define true 1 +#define false 0 + +/* to identify a cie */ +#define DW_CIE_ID ~(0x0) +#define DW_CIE_VERSION 1 + +/*Dwarf_Word is unsigned word usable for index, count in memory */ +/*Dwarf_Sword is signed word usable for index, count in memory */ +/* The are 32 or 64 bits depending if 64 bit longs or not, which +** fits the ILP32 and LP64 models +** These work equally well with ILP64. +*/ + +typedef unsigned long Dwarf_Word; +typedef long Dwarf_Sword; + + +typedef signed char Dwarf_Sbyte; +typedef unsigned char Dwarf_Ubyte; +typedef signed short Dwarf_Shalf; + +/* + On any change that makes libdwarf producer + incompatible, increment this number. + 1->2->3 ... + +*/ +#define PRO_VERSION_MAGIC 0xdead1 + + +/* these 2 are fixed sizes which must not vary with the +** ILP32/LP64 model. These two stay at 32 bit. +*/ +typedef __uint32_t Dwarf_ufixed; +typedef __int32_t Dwarf_sfixed; + +/* + producer: + This struct is used to hold information about all + debug* sections. On creating a new section, section + names and indices are added to this struct + definition in pro_section.h +*/ +typedef struct Dwarf_P_Section_Data_s *Dwarf_P_Section_Data; + +/* + producer: + This struct is used to hold entries in the include directories + part of statement prologue. Definition in pro_line.h +*/ +typedef struct Dwarf_P_Inc_Dir_s *Dwarf_P_Inc_Dir; + +/* + producer: + This struct holds file entries for the statement prologue. + Defined in pro_line.h +*/ +typedef struct Dwarf_P_F_Entry_s *Dwarf_P_F_Entry; + +/* + producer: + This struct holds information for each cie. Defn in pro_frame.h +*/ +typedef struct Dwarf_P_Cie_s *Dwarf_P_Cie; + +/* + producer: + Struct to hold line number information, different from + Dwarf_Line opaque type. +*/ +typedef struct Dwarf_P_Line_s *Dwarf_P_Line; + +/* + producer: + Struct to hold information about address ranges. +*/ +typedef struct Dwarf_P_Simple_nameentry_s *Dwarf_P_Simple_nameentry; +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; + +/* Defined to get at the elf section numbers and section name + indices in symtab for the dwarf sections + Must match .rel.* names in _dwarf_rel_section_names + exactly. +*/ +#define DEBUG_INFO 0 +#define DEBUG_LINE 1 +#define DEBUG_ABBREV 2 +#define DEBUG_FRAME 3 +#define DEBUG_ARANGES 4 +#define DEBUG_PUBNAMES 5 +#define DEBUG_STR 6 +#define DEBUG_FUNCNAMES 7 +#define DEBUG_TYPENAMES 8 +#define DEBUG_VARNAMES 9 +#define DEBUG_WEAKNAMES 10 +#define DEBUG_MACINFO 11 +#define DEBUG_LOC 12 + + /* number of debug_* sections not including the relocations */ +#define NUM_DEBUG_SECTIONS DEBUG_LOC + 1 + + +struct Dwarf_P_Die_s { + Dwarf_Unsigned di_offset; /* offset in debug info */ + char *di_abbrev; /* abbreviation */ + Dwarf_Word di_abbrev_nbytes; /* # of bytes in abbrev */ + Dwarf_Tag di_tag; + Dwarf_P_Die di_parent; /* parent of current die */ + Dwarf_P_Die di_child; /* first 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 */ +}; + + +/* producer fields */ +struct Dwarf_P_Attribute_s { + Dwarf_Half ar_attribute; /* Attribute Value. */ + Dwarf_Half ar_attribute_form; /* Attribute Form. */ + Dwarf_P_Die ar_ref_die; /* die pointer if form ref */ + char *ar_data; /* data, format given by form */ + Dwarf_Unsigned ar_nbytes; /* no. of bytes of data */ + Dwarf_Unsigned ar_rel_symidx; /* when attribute has a + relocatable value, holds + index of symbol in SYMTAB */ + Dwarf_Ubyte ar_rel_type; /* relocation type */ + Dwarf_Word ar_rel_offset; /* Offset of relocation within block */ + char ar_reloc_len; /* Number of bytes that relocation + applies to. 4 or 8. Unused and may + be 0 if if ar_rel_type is + R_MIPS_NONE */ + Dwarf_P_Attribute ar_next; +}; + +/* A block of .debug_macinfo data: this forms a series of blocks. +** Each macinfo input is compressed immediately and put into +** the current block if room, else a newblock allocated. +** The space allocation is such that the block and the macinfo +** data are one malloc block: free with a pointer to this and the +** mb_data is freed automatically. +** Like the struct hack, but legal ANSI C. +*/ +struct dw_macinfo_block_s { + struct dw_macinfo_block_s *mb_next; + unsigned long mb_avail_len; + unsigned long mb_used_len; + unsigned long mb_macinfo_data_space_len; + char *mb_data; /* original malloc ptr. */ +}; + +/* dwarf_sn_kind is for the array of similarly-treated + name -> cu ties +*/ +enum dwarf_sn_kind { dwarf_snk_pubname, dwarf_snk_funcname, + dwarf_snk_weakname, dwarf_snk_typename, + dwarf_snk_varname, + dwarf_snk_entrycount /* this one must be last */ +}; + + + +/* The calls to add a varname etc use a list of + these as the list. +*/ +struct Dwarf_P_Simple_nameentry_s { + Dwarf_P_Die sne_die; + char *sne_name; + int sne_name_len; + Dwarf_P_Simple_nameentry sne_next; +}; + +/* An array of these, each of which heads a list + of Dwarf_P_Simple_nameentry +*/ +struct Dwarf_P_Simple_name_header_s { + Dwarf_P_Simple_nameentry sn_head; + Dwarf_P_Simple_nameentry sn_tail; + Dwarf_Signed sn_count; + + /* length that will be generated, not counting fixed header or + 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_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. + + 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 */ + Dwarf_Unsigned rb_next_slot_to_use; /* counter, start at 0. */ + struct Dwarf_P_Relocation_Block_s *rb_next; + char *rb_where_to_add_next; /* pointer to next slot (might be past + end, depending on + rb_next_slot_to_use) */ + char *rb_data; /* data area */ +}; + +/* One of these per potential relocation section + So one per actual dwarf section. + Left zeroed when not used (some sections have + no relocations). +*/ +struct Dwarf_P_Per_Reloc_Sect_s { + + + unsigned long pr_reloc_total_count; /* total number of entries + across all blocks */ + + unsigned long pr_slots_per_block_to_alloc; /* at Block alloc, this + 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. */ + + + /* singly-linked list. add at and ('last') with count of blocks */ + struct Dwarf_P_Relocation_Block_s *pr_first_block; + struct Dwarf_P_Relocation_Block_s *pr_last_block; + unsigned long pr_block_count; +}; + +#define DEFAULT_SLOTS_PER_BLOCK 3 + + +/* Fields used by producer */ +struct Dwarf_P_Debug_s { + /* used to catch dso passing dbg to another DSO with incompatible + 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 + by user. Only of these used per dbg. */ + Dwarf_Callback_Func de_func; + Dwarf_Callback_Func_b de_func_b; + + /* Flags from producer_init call */ + Dwarf_Unsigned de_flags; + + /* This holds information on debug section stream output, including + the stream data */ + Dwarf_P_Section_Data de_debug_sects; + + /* Pointer to the 'current active' section */ + Dwarf_P_Section_Data de_current_active_section; + + /* Number of debug data streams globs. */ + Dwarf_Word de_n_debug_sect; + + /* File entry information, null terminated singly-linked list */ + Dwarf_P_F_Entry de_file_entries; + Dwarf_P_F_Entry de_last_file_entry; + Dwarf_Unsigned de_n_file_entries; + + /* Has the directories used to search for source files */ + Dwarf_P_Inc_Dir de_inc_dirs; + Dwarf_P_Inc_Dir de_last_inc_dir; + Dwarf_Unsigned de_n_inc_dirs; + + /* Has all the line number info for the stmt program */ + Dwarf_P_Line de_lines; + Dwarf_P_Line de_last_line; + + /* List of cie's for the debug unit */ + Dwarf_P_Cie de_frame_cies; + 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; + Dwarf_Unsigned de_n_fde; + + /* First die, leads to all others */ + Dwarf_P_Die de_dies; + + /* Pointer to list of strings */ + char *de_strings; + + /* Pointer to chain of aranges */ + Dwarf_P_Arange de_arange; + Dwarf_P_Arange de_last_arange; + Dwarf_Sword de_arange_count; + + /* macinfo controls. */ + /* first points to beginning of the list during creation */ + struct dw_macinfo_block_s *de_first_macinfo; + + /* 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; + + /* handles pubnames, weaknames, etc. See dwarf_sn_kind in + pro_opaque.h */ + struct Dwarf_P_Simple_name_header_s + de_simple_name_headers[dwarf_snk_entrycount]; + + /* relocation data. not all sections will actally have relocation + info, of course */ + struct Dwarf_P_Per_Reloc_Sect_s de_reloc_sect[NUM_DEBUG_SECTIONS]; + int de_reloc_next_to_return; /* iterator on reloc sections + (SYMBOLIC output) */ + + /* used in remembering sections */ + 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 + */ + + + + int de_offset_reloc; /* offset reloc type, R_MIPS_32 for + example. Specific to the ABI being + produced. Relocates offset size + field */ + int de_exc_reloc; /* reloc type specific to exception + table relocs. */ + int de_ptr_reloc; /* standard reloc type, R_MIPS_32 for + example. Specific to the ABI being + 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_pointer_size; /* size of pointer in target. + Here to avoid test of abi in + macro at run time MIPS -n32 + 4, -64 is 8. */ + + unsigned char de_is_64bit; /* non-zero if is 64bit. Else 32 bit: + used for passing this info as a flag + */ + unsigned char de_relocation_record_size; /* reloc record size + varies by ABI and + relocation-output + method (stream or + symbolic) */ + + unsigned char de_64bit_extension; /* non-zero if creating 64 bit + offsets using dwarf2-99 + extension proposal */ + + int de_ar_data_attribute_form; /* data8, data4 abi dependent */ + int de_ar_ref_attr_form; /* ref8 ref4 , abi dependent */ + + /* simple name relocations */ + _dwarf_pro_reloc_name_func_ptr de_reloc_name; + + /* relocations for a length, requiring a pair of symbols */ + _dwarf_pro_reloc_length_func_ptr de_reloc_pair; + + _dwarf_pro_transform_relocs_func_ptr de_transform_relocs_to_disk; + + /* following used for macro buffers */ + unsigned long de_compose_avail; + unsigned long de_compose_used_len; + + unsigned char de_same_endian; + void *(*de_copy_word) (void *, const void *, size_t); + + /* Add new fields at the END of this struct to preserve some hope + of sensible behavior on dbg passing between DSOs linked with + mismatched libdwarf producer versions. */ + +}; + + +#define CURRENT_VERSION_STAMP 2 + +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); + + +#define DISTINGUISHED_VALUE 0xffffffff /* 64bit extension flag */ diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_pubnames.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_pubnames.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,63 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#ifdef HAVE_ELFACCESS_H +#include +#endif +#include "pro_incl.h" +#include "pro_section.h" + + +/* + This function adds another public name to the + list of public names for the given Dwarf_P_Debug. + It returns 0 on error, and 1 otherwise. +*/ + +Dwarf_Unsigned +dwarf_add_pubname(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + char *pubname_name, Dwarf_Error * error) +{ + return + _dwarf_add_simple_name_entry(dbg, die, pubname_name, + dwarf_snk_pubname, error); +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_reloc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_reloc.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,268 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +/*#include */ +#include "pro_incl.h" + + +/*Do initial alloc of newslots slots. + Fails only if malloc fails. + + Supposed to be called before any relocs allocated. + Ignored if after any allocated. + + Part of an optimization, so that for a known 'newslots' + relocations count we can preallocate the right size block. + Called from just 2 places. + + returns DW_DLV_OK or DW_DLV_ERROR +*/ +int +_dwarf_pro_pre_alloc_n_reloc_slots(Dwarf_P_Debug dbg, + int rel_sec_index, + Dwarf_Unsigned newslots) +{ + unsigned long len; + struct Dwarf_P_Relocation_Block_s *data; + 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 */ + + len = sizeof(struct Dwarf_P_Relocation_Block_s) + + slots_in_blk * rel_rec_size; + + + data = (struct Dwarf_P_Relocation_Block_s *) + _dwarf_p_get_alloc(dbg, len); + if (!data) { + 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_next_slot_to_use = 0; + data->rb_where_to_add_next = + ((char *) data) + sizeof(struct Dwarf_P_Relocation_Block_s); + data->rb_data = data->rb_where_to_add_next; + + prel->pr_first_block = data; + prel->pr_last_block = data; + prel->pr_block_count = 1; + + + return DW_DLV_OK; +} + + +/*Do alloc of slots. + Fails only if malloc fails. + + Only allocator used. + + returns DW_DLV_OK or DW_DLV_ERROR +*/ +int +_dwarf_pro_alloc_reloc_slots(Dwarf_P_Debug dbg, int rel_sec_index) +{ + unsigned long len; + struct Dwarf_P_Relocation_Block_s *data; + 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; + + data = (struct Dwarf_P_Relocation_Block_s *) + _dwarf_p_get_alloc(dbg, len); + if (!data) { + 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; + + } else { + + 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); + data->rb_data = data->rb_where_to_add_next; + + return DW_DLV_OK; + +} + +/* + Reserve a slot. return DW_DLV_OK if succeeds. + + Return DW_DLV_ERROR if fails (malloc error). + + 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) +{ + struct Dwarf_P_Relocation_Block_s *data; + 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; + + data = prel->pr_last_block; + if ((data == 0) || + (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; + } + } + + data = prel->pr_last_block; + /* now we have an empty slot */ + ret_addr = data->rb_where_to_add_next; + + data->rb_where_to_add_next += rel_rec_size; + data->rb_next_slot_to_use += 1; + + prel->pr_reloc_total_count += 1; + + *relrec_to_fill = (void *) ret_addr; + + return DW_DLV_OK; + +} + +/* + On success returns count of + .rel.* sections that are symbolic + thru count_of_relocation_sections. + + On success, returns DW_DLV_OK. + + If this is not a 'symbolic' run, returns + DW_DLV_NO_ENTRY. + + No errors are possible. + + + + +*/ + + /*ARGSUSED*/ int +dwarf_get_relocation_info_count(Dwarf_P_Debug dbg, + 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; + + 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) +{ + int next = dbg->de_reloc_next_to_return; + + if (dbg->de_flags & DW_DLC_SYMBOLIC_RELOCATIONS) { + int 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; + + + /* 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); + } + return DW_DLV_NO_ENTRY; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_reloc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_reloc.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,47 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + + +int _dwarf_pro_pre_alloc_n_reloc_slots(Dwarf_P_Debug dbg, + int rel_sec_index, + Dwarf_Unsigned newslots); + +int _dwarf_pro_alloc_reloc_slots(Dwarf_P_Debug dbg, int rel_sec_index); + +int _dwarf_pro_reloc_get_a_slot(Dwarf_P_Debug dbg, + int base_sec_index, + void **relrec_to_fill); diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_reloc_stream.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_reloc_stream.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,298 @@ +/* + + Copyright (C) 2000, 2001 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 + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#ifdef HAVE_ELFACCESS_H +#include +#else +/* Set r_info as defined by ELF generic ABI */ +#define Set_REL32_info(r,s,t) ((r).r_info = ELF32_R_INFO(s,t)) +#define Set_REL64_info(r,s,t) ((r).r_info = ELF64_R_INFO(s,t)) +#endif +#include "pro_incl.h" +#include "pro_section.h" +#include "pro_reloc.h" +#include "pro_reloc_stream.h" + +/* + 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) +{ +#if HAVE_ELF64_GETEHDR + Elf64_Rel *elf64_reloc; + void *relrec_to_fill; + int res; + int rel_type; + + res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, + &relrec_to_fill); + if (res != DW_DLV_OK) + 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; + } + } else if (type == dwarf_drt_segment_rel) { + rel_type = dbg->de_exc_reloc; + } else { + /* 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->r_offset = offset; + Set_REL64_info(*elf64_reloc, symidx, rel_type); + return DW_DLV_OK; +#else /* !HAVE_ELF64_GETEHDR */ + return DW_DLV_ERROR; +#endif /* #if HAVE_ELF64_GETEHDR */ +} + +/* + 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) +{ + Elf32_Rel *elf32_reloc; + void *relrec_to_fill; + int res; + int rel_type; + + res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, + &relrec_to_fill); + if (res != DW_DLV_OK) + 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; + } + } else if (type == dwarf_drt_segment_rel) { + rel_type = dbg->de_exc_reloc; + } else { + /* 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->r_offset = (Elf32_Addr) offset; + Set_REL32_info(*elf32_reloc, (Dwarf_Word) symidx, rel_type); + return DW_DLV_OK; + + /* get a slot, fill in the slot entry */ +} + + + +/* + 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) +{ + /* get a slot, fill in the slot entry */ + return DW_DLV_OK; +} + + +/* + 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. + + 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. + +*/ +int +_dwarf_stream_relocs_to_disk(Dwarf_P_Debug dbg, + Dwarf_Signed * new_sec_count) +{ + unsigned long total_size = 0; + Dwarf_Small *data; + int sec_index; + unsigned long i; + Dwarf_Error err; + Dwarf_Error *error = &err; + + 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; + 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; + + 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; + + 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); + } + + } + 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) { + + 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); + } + /* 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; + } + + *new_sec_count = sec_count; + return DW_DLV_OK; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_reloc_stream.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_reloc_stream.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,63 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + + +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, + int reltarget_length); +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, + int reltarget_length); +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, + int reltarget_length); + +int _dwarf_stream_relocs_to_disk(Dwarf_P_Debug dbg, + Dwarf_Signed * new_sec_count); diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_reloc_symbolic.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_reloc_symbolic.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,299 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +/*#include */ +#include "pro_incl.h" +#include "pro_section.h" +#include "pro_reloc.h" +#include "pro_reloc_symbolic.h" + +/* + 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) +{ + /* get a slot, fill in the slot entry */ + void *relrec_to_fill; + int res; + struct Dwarf_Relocation_Data_s *slotp; + + res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, + &relrec_to_fill); + if (res != DW_DLV_OK) + 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 +*/ +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) +{ + /* 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; + + + + res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, + &relrec_to_fill); + if (res != DW_DLV_OK) + 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); + if (res != DW_DLV_OK) + return res; + slotp2 = (struct Dwarf_Relocation_Data_s *) relrec_to_fill; + + /* ASSERT: type == dwarf_drt_first_of_length_type_pair */ + slotp1->drd_type = type; + slotp1->drd_length = reltarget_length; + slotp1->drd_offset = offset; + slotp1->drd_symbol_index = start_symidx; + + slotp2->drd_type = dwarf_drt_second_of_length_pair; + slotp2->drd_length = reltarget_length; + slotp2->drd_offset = offset; + slotp2->drd_symbol_index = end_symidx; + + return DW_DLV_OK; +} + +/* + Reset whatever fields of Dwarf_P_Per_Reloc_Sect_s + we must to allow adding a fresh new single + block easily (block consolidation use only). + +*/ +static void +_dwarf_reset_reloc_sect_info(struct Dwarf_P_Per_Reloc_Sect_s *pblk, + unsigned long ct) +{ + + + /* 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; + pblk->pr_block_count = 0; + pblk->pr_slots_per_block_to_alloc = ct; +} + +/* + 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) + + 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. + + Return -1 on error (malloc failure) + + + 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) +{ + /* unsigned long total_size =0; */ + Dwarf_Small *data; + int sec_index; + int res; + unsigned long i; + Dwarf_Error error; + + 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; + + + if (ct == 0) { + continue; + } + + /* 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; + + /* + 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; + } + + p_blk = p_reloc->pr_first_block; + + if (p_reloc->pr_block_count > 1) { + struct Dwarf_P_Relocation_Block_s *new_blk; + + /* HACK , not normal interfaces, trashing p_reloc + current contents! */ + _dwarf_reset_reloc_sect_info(p_reloc, ct); + + /* 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 { + + 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; + + /* have now created a single block, but no change in slots + used (pr_reloc_total_count) */ + } + } + + *new_sec_count = 0; + return DW_DLV_OK; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_reloc_symbolic.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_reloc_symbolic.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,55 @@ +/* + + Copyright (C) 2000 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 + +*/ + + +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, + int reltarget_length); +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, + int reltarget_length); + +int _dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg, + Dwarf_Signed * new_sec_count); diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_section.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_section.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,1958 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#ifdef HAVE_ELFACCESS_H +#include +#endif +#include "pro_incl.h" +#include "pro_section.h" +#include "pro_line.h" +#include "pro_frame.h" +#include "pro_die.h" +#include "pro_macinfo.h" +#include "pro_types.h" + +#ifndef SHF_MIPS_NOSTRIP +/* if this is not defined, we probably don't need it: just use 0 */ +#define SHF_MIPS_NOSTRIP 0 +#endif +#ifndef R_MIPS_NONE +#define R_MIPS_NONE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +/* must match up with pro_section.h defines of DEBUG_INFO etc +and sectnames (below) +*/ +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" +}; + +/* names of sections. Ensure that it matches the defines + in pro_section.h, in the same order + Must match also _dwarf_rel_section_names above +*/ +char *_dwarf_sectnames[] = { + ".debug_info", + ".debug_line", + ".debug_abbrev", + ".debug_frame", + ".debug_aranges", + ".debug_pubnames", + ".debug_str", + ".debug_funcnames", /* sgi extension */ + ".debug_typenames", /* sgi extension */ + ".debug_varnames", /* sgi extension */ + ".debug_weaknames", /* sgi extension */ + ".debug_macinfo", + ".debug_loc" +}; + + + + +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 + list of relocation structs, and will then be written at as a + whole into the relocation section. Whether its 32 bit or + 64 bit will be obtained from Dwarf_Debug pointer. +*/ + +typedef struct Dwarf_P_Rel_s *Dwarf_P_Rel; +struct Dwarf_P_Rel_s { + Dwarf_P_Rel dr_next; + void *dr_rel_datap; +}; +typedef struct Dwarf_P_Rel_Head_s *Dwarf_P_Rel_Head; +struct Dwarf_P_Rel_Head_s { + struct Dwarf_P_Rel_s *drh_head; + struct Dwarf_P_Rel_s *drh_tail; +}; + +static int _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, + Dwarf_Error * error); +static int _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, + Dwarf_Error * error); +static int _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, + 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 +static int _dwarf_pro_get_opc(Dwarf_Unsigned addr_adv, int line_adv); + + + +/* + Return TRUE if we need the section, FALSE otherwise + + If any of the 'line-data-related' calls were made + including file or directory entries, + produce .debug_line . + +*/ +static int +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; + } + return TRUE; +} + +/* + Convert debug information to a format such that + it can be written on disk. + Called exactly once per execution. +*/ +Dwarf_Signed +dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error * error) +{ + /* + 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 + buffers one at a time. */ + int nbufs; + int sect; + int name_idx; + int err; + Dwarf_Unsigned du; + + if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) { + 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; + + switch (sect) { + + 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_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_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_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_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_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; + + 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); + + } 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; + + dbg->de_sect_name_idx[sect] = du; + } + } + + nbufs = 0; + + /* + 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); + } + } + + 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); + } + } + 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); + } + } + + 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); + } + } + + 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); + } + } + + if (dbg->de_simple_name_headers[dwarf_snk_pubname].sn_head) { + 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 (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); + } + } + + 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); + } + } + + if (dbg->de_simple_name_headers[dwarf_snk_varname].sn_head) { + 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 (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); + } + } + + { + Dwarf_Signed new_secs; + int res; + + 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 +---------------------------------------------------------------*/ +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; + + /* 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 */ + /* temps for memcpy */ + Dwarf_Unsigned du; + Dwarf_Ubyte db; + Dwarf_Half dh; + int res; + 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++; /* 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++; /* 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 */ + + /* 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; + + /* copy over the data */ + /* total_length */ + du = 0; + if (extension_size) { + 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 *) &du, + sizeof(du), uwordb_size); + data += uwordb_size; + + dh = VERSION; + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dh, + sizeof(dh), sizeof(Dwarf_Half)); + data += sizeof(Dwarf_Half); + + /* prologue length */ + du = prolog_size - (uwordb_size + sizeof(Dwarf_Half) + 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)); + data += sizeof(Dwarf_Ubyte); + db = DEFAULT_IS_STMT; + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + 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)); + data += sizeof(Dwarf_Ubyte); + db = LINE_RANGE; + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + 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)); + data += sizeof(Dwarf_Ubyte); + WRITE_UNALIGNED(dbg, (void *) data, (const void *) 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; + } + *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; + } + *data = '\0'; + data++; + + sum_bytes += prolog_size; + + curline = dbg->de_lines; + prevline = (Dwarf_P_Line) + _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_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. ? */ + + 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: + + /* 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); + + /* 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; + + 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); + + /* 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); + + /* 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); + } + + 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); + } + + 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; + } + + /* write total length field */ + du = sum_bytes - uwordb_size - extension_size; /* subtract + length field + */ + { + 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 +---------------------------------------------------------------*/ +static int +_dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error) +{ + int elfsectno; + int i; + 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 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 */ + + elfsectno = dbg->de_elf_sects[DEBUG_FRAME]; + + curcie = dbg->de_frame_cies; + cie_length = 0; + cur_off = 0; + cie_offs = (long *) + _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); + } + /* generate cie number as we go along */ + 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; + + 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! + + 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; + + /* 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; + + 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; + + /* 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); + + 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; + + /* 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; + +#if 0 + unsigned char *fde_start_point; +#endif + + 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); + } + + 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 */ + } + + /* 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); + } + + /* 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) { + + 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); + } + } + + /* 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); +#if 0 + fde_start_point = data; +#endif + 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; + + /* 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; + + 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); + } + } + + /* 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; + } + } + + 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); +#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); + } + } + } +#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; + } + + + return (int) dbg->de_n_debug_sect; +} + + + +/*--------------------------------------------------------------- + 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; + + Dwarf_Small *start_info_sec; + + int uword_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 */ + GET_CHUNK(dbg, elfsectno_of_debug_info, data, cu_header_size, + 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 = 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; + + version = CURRENT_VERSION_STAMP; /* assume this length will not + change */ + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &version, + sizeof(version), sizeof(Dwarf_Half)); + data += sizeof(Dwarf_Half); + + du = 0; /* offset into abbrev table, not yet + known. */ + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &du, sizeof(du), uword_size); + data += uword_size; + + + db = dbg->de_pointer_size; + + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + 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 + longer except to refer to that first small chunk for the cu + header. */ + + curdie = dbg->de_dies; + + /* 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; + } + + /* 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; + + 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); + if (res != DW_DLV_OK) { + 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; + } + + /* pass 1: create abbrev info, get die offsets, calc relocations */ + while (curdie != NULL) { + int nbytes; + Dwarf_P_Attribute curattr; + char *space; + int res; + char buff1[ENCODE_SPACE_NEEDED]; + + 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); + + 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; + } + } + + /* 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); + + /* 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; + + } + 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]; + + 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); + } + + memcpy(data, buff1, nbytes); + break; + } + default: + memcpy((void *) data, + (const void *) curattr->ar_data, + curattr->ar_nbytes); + break; + } + 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; + } + } + + /* Write out debug_info size */ + /* Dont include length field or extension bytes */ + du = die_off - uword_size - extension_size; + WRITE_UNALIGNED(dbg, (void *) (start_info_sec + extension_size), + (const void *) &du, sizeof(du), uword_size); + + + 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]; + + 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)); + + /* 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; + } + + 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 +----------------------------------------------------------------------*/ + /*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_Ptr buf; + + if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, NULL); + } + + if (dbg->de_debug_sects == 0) { + /* no more data !! */ + return NULL; + } + if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) { + /* no data ever entered !! */ + return NULL; + } + *section_idx = dbg->de_debug_sects->ds_elf_sect_no; + *length = dbg->de_debug_sects->ds_nbytes; + + buf = (Dwarf_Ptr *) dbg->de_debug_sects->ds_data; + + dbg->de_debug_sects = dbg->de_debug_sects->ds_next; + + /* We may want to call the section stuff more than once: see + dwarf_reset_section_bytes() do not do: dbg->de_n_debug_sect--; */ + + return buf; +} + +/* + No errors possible. +*/ +void +dwarf_reset_section_bytes(Dwarf_P_Debug dbg) +{ + dbg->de_debug_sects = dbg->de_first_debug_sect; + /* No need to reset; commented out decrement. dbg->de_n_debug_sect + = ???; */ + dbg->de_reloc_next_to_return = 0; +} + +/* + Storage handler. Gets either a new chunk of memory, or + a pointer in existing memory, from the linked list attached + to dbg at de_debug_sects, depending on size of nbytes + + Assume dbg not null, checked in top level routine + + Returns a pointer to the allocated buffer space for the + lib to fill in, predincrements next-to-use count so the + space requested is already counted 'used' + when this returns (ie, reserved). + +*/ +Dwarf_Small * +_dwarf_pro_buffer(Dwarf_P_Debug dbg, + int elfsectno, unsigned long nbytes) +{ + Dwarf_P_Section_Data cursect; + + + cursect = dbg->de_current_active_section; + /* By using MAGIC_SECT_NO we allow the following MAGIC_SECT_NO must + 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) + ) { + + /* 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). + + */ + unsigned long space = nbytes; + + 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); + + + if (cursect == NULL) + return (NULL); + + /* _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 */ + + /* 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++; + + 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); + + cursect->ds_nbytes += nbytes; + return space_for_caller; + } +} + + +/*------------------------------------------------------------ + 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) +{ + int opc; + + addr_adv = addr_adv / MIN_INST_LENGTH; + if (line_adv == 0 && addr_adv == 0) + 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; + } else + 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. +-----------------------------------------------------------------------*/ +static Dwarf_P_Abbrev +_dwarf_pro_getabbrev(Dwarf_P_Die die, Dwarf_P_Abbrev head) +{ + Dwarf_P_Abbrev curabbrev; + Dwarf_P_Attribute curattr; + int res1; + int nattrs; + int match; + Dwarf_ufixed *forms = 0; + Dwarf_ufixed *attrs = 0; + + 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)) { + + /* 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; + } + nattrs = 0; + curattr = die->di_attrs; + while (curattr) { + 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)); + if (curabbrev == NULL) + return NULL; + + if (die->di_child == NULL) + curabbrev->abb_children = DW_CHILDREN_no; + else + curabbrev->abb_children = DW_CHILDREN_yes; + curabbrev->abb_tag = die->di_tag; + curabbrev->abb_attrs = attrs; + curabbrev->abb_forms = forms; + curabbrev->abb_n_attr = die->di_n_attr; + curabbrev->abb_idx = 0; + curabbrev->abb_next = NULL; + + return curabbrev; +} + +/*------------------------------------------------------------------ + 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) +{ + 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; + } + } + return found; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_section.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_section.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,112 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + + + +/* relocation section names */ +extern char *_dwarf_rel_section_names[]; + +/* section names */ +extern char *_dwarf_sectnames[]; + +/* struct to hold relocation entries. Its mantained as a linked + list of relocation structs, and will then be written at as a + whole into the relocation section. Whether its 32 bit or + 64 bit will be obtained from Dwarf_Debug pointer. +*/ + + + + + +/* + struct stores a chunk of data pertaining to a section +*/ +struct Dwarf_P_Section_Data_s { + int ds_elf_sect_no; /* elf section number */ + char *ds_data; /* data contained in section */ + unsigned long ds_nbytes; /* bytes of data used so far */ + unsigned long ds_orig_alloc; /* bytes allocated originally */ + Dwarf_P_Section_Data ds_next; /* next on the list */ +}; + +/* Used to allow a dummy initial struct (which we + drop before it gets used + This must not match any legitimate 'section' number. +*/ +#define MAGIC_SECT_NO -3 + +/* Size of chunk of data allocated in one alloc + Not clear if this is the best size. + Used to be just 4096 for user data, the section data struct + was a separate malloc. +*/ +#define CHUNK_SIZE (4096 - sizeof (struct Dwarf_P_Section_Data_s)) + +/* + chunk alloc routine - + if chunk->ds_data is nil, it will alloc CHUNK_SIZE bytes, + and return pointer to the beginning. If chunk is not nil, + it will see if there's enoungh space for nbytes in current + chunk, if not, add new chunk to linked list, and return + a char * pointer to it. Return null if unsuccessful. +*/ +Dwarf_Small *_dwarf_pro_buffer(Dwarf_P_Debug dbg, int sectno, + unsigned long nbytes); + +#define GET_CHUNK(dbg,sectno,ptr,nbytes,error) \ + { \ + (ptr) = _dwarf_pro_buffer((dbg),(sectno),(nbytes)); \ + if ((ptr) == NULL) { \ + DWARF_P_DBG_ERROR(dbg,DW_DLE_CHUNK_ALLOC,-1); \ + } \ + } + + + +int + _dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, + Dwarf_Error * error); + +/* These are for creating ELF section type codes. +*/ +#if defined(linux) || defined(__BEOS__) || !defined(SHT_MIPS_DWARF) +/* Intel's SoftSdv accepts only this */ +#define SECTION_TYPE SHT_PROGBITS +#else +#define SECTION_TYPE SHT_MIPS_DWARF +#endif diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_types.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_types.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,294 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#ifdef HAVE_ELFACCESS_H +#include +#endif +#include "pro_incl.h" +#include "pro_section.h" + + +/* + This function adds another type name to the + list of type names for the given Dwarf_P_Debug. + It returns 0 on error, and 1 otherwise. +*/ +Dwarf_Unsigned +dwarf_add_typename(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + char *type_name, Dwarf_Error * error) +{ + return + _dwarf_add_simple_name_entry(dbg, die, type_name, + dwarf_snk_typename, error); +} + +/* + The following is the generic 'add a simple name entry' + for any of the simple name sections. + + See enum dwarf_sn_kind in pro_opaque.h + +*/ +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_Simple_nameentry nameentry; + Dwarf_P_Simple_name_header hdr; + char *name; + int uword_size; + + if (dbg == NULL) { + _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); + } + + + nameentry = (Dwarf_P_Simple_nameentry) + _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); + } + + name = _dwarf_p_get_alloc(dbg, strlen(entry_name) + 1); + if (name == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (0); + } + strcpy(name, entry_name); + + nameentry->sne_die = die; + nameentry->sne_name = name; + nameentry->sne_name_len = strlen(name); + uword_size = dbg->de_offset_size; + + hdr = &dbg->de_simple_name_headers[entrykind]; + if (hdr->sn_head == NULL) + hdr->sn_head = hdr->sn_tail = nameentry; + else { + hdr->sn_tail->sne_next = nameentry; + hdr->sn_tail = nameentry; + } + hdr->sn_count++; + hdr->sn_net_len += uword_size + nameentry->sne_name_len + 1; + + return (1); +} + + + +/* + _dwarf_transform_simplename_to_disk writes + ".rel.debug_pubnames", + ".rel.debug_funcnames", sgi extension + ".rel.debug_typenames", sgi extension + ".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. + +*/ +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) +{ + + + /* Used to fill in 0. */ + const Dwarf_Signed big_zero = 0; + + /* Used to scan the section data buffers. */ + Dwarf_P_Section_Data debug_sect; + + Dwarf_Signed debug_info_size; + + Dwarf_P_Simple_nameentry nameentry_original; + Dwarf_P_Simple_nameentry nameentry; + Dwarf_Small *stream_bytes; + Dwarf_Small *cur_stream_bytes_ptr; + Dwarf_Unsigned stream_bytes_count; + Dwarf_Unsigned adjusted_length; /* count excluding length + field */ + + + int uword_size = dbg->de_offset_size; + int extension_size = dbg->de_64bit_extension ? 4 : 0; + + Dwarf_P_Simple_name_header hdr; + + + /* ***** BEGIN CODE ***** */ + + 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; + } + } + + 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. */ + + + + nameentry_original = hdr->sn_head; + nameentry = nameentry_original; + /* add in the content size */ + stream_bytes_count += hdr->sn_net_len; + + /* Size of the last 0 offset. */ + stream_bytes_count += uword_size; + + /* 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); + if (stream_bytes == NULL) { + _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; + + 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); + cur_stream_bytes_ptr += uword_size; + + /* Write the version as 2 bytes. */ + { + 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 the offset of the compile-unit. */ + WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, + (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); + + 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); + cur_stream_bytes_ptr += uword_size; + + + for (nameentry = nameentry_original; + 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 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); + + + + + return (int) dbg->de_n_debug_sect; +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_types.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,44 @@ +/* + + Copyright (C) 2000 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 + +*/ + + +/* pro_types.h */ + + +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); diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_util.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_util.h Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,107 @@ +/* + + Copyright (C) 2000 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 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) +/* certain sizes not defined here, but set in dbg record. + See pro_init.c +*/ + +/* Computes amount of padding necessary to align n to a k-boundary. */ +/* Important: Assumes n, k both GREATER than zero. */ +#define PADDING(n, k) ( (k)-1 - ((n)-1)%(k) ) + +/* The following defines are only important for users of the +** producer part of libdwarf, and such should have these +** defined correctly (as necessary) +** by the #include done in pro_incl.h +** before the #include "pro_util.h". +** For others producer macros do not matter so 0 is a usable value, and +** zero values let compilation succeed on more non-MIPS architectures. +** A better approach would be welcome. +*/ +/* 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. +*/ +#ifndef R_MIPS_64 +#define R_MIPS_64 0 +#endif +#ifndef R_MIPS_32 +#define R_MIPS_32 0 +#endif +#ifndef R_MIPS_SCN_DISP +#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 +#endif + +#ifdef HAVE_SYS_IA64_ELF_H +#define Get_REL64_isa(dbg) (ISA_IA64(dbg) ? \ + R_IA_64_DIR64LSB : R_MIPS_64) +#define Get_REL32_isa(dbg) (ISA_IA64(dbg) ? \ + R_IA_64_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 + +#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) +#endif + +#endif diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_vars.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_vars.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,62 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#ifdef HAVE_ELFACCESS_H +#include +#endif +#include "pro_incl.h" +#include "pro_section.h" + +/* + This function adds another variable name to the + list of variable names for the given Dwarf_P_Debug. + It returns 0 on error, and 1 otherwise. +*/ +Dwarf_Unsigned +dwarf_add_varname(Dwarf_P_Debug dbg, + Dwarf_P_Die die, char *var_name, Dwarf_Error * error) +{ + return + _dwarf_add_simple_name_entry(dbg, die, var_name, + dwarf_snk_varname, error); + + +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/common/pro_weaks.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/tools/ctf/dwarf/common/pro_weaks.c Wed Jun 08 17:36:48 2011 -0400 @@ -0,0 +1,61 @@ +/* + + Copyright (C) 2000 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 + +*/ + + + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#ifdef HAVE_ELFACCESS_H +#include +#endif +#include "pro_incl.h" +#include "pro_section.h" + +/* + This function adds another weak name to the + list of weak names for the given Dwarf_P_Debug. + It returns 0 on error, and 1 otherwise. +*/ +Dwarf_Unsigned +dwarf_add_weakname(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + char *weak_name, Dwarf_Error * error) +{ + return + _dwarf_add_simple_name_entry(dbg, die, weak_name, + dwarf_snk_weakname, error); +} diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/dwarf.h --- a/usr/src/tools/ctf/dwarf/dwarf.h Tue Jun 07 21:38:05 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,699 +0,0 @@ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - Copyright (C) 2000, 2001 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 - -*/ - - -#ifndef __DWARF_H -#define __DWARF_H -#ifdef __cplusplus -extern "C" { -#endif - -/* - dwarf.h DWARF debugging information values - $Revision: 1.24 $ $Date: 2001/05/23 23:34:51 $ - -*/ - - -#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 -#define DW_TAG_namelist_item 0x2c -#define DW_TAG_packed_type 0x2d -#define DW_TAG_subprogram 0x2e -#define DW_TAG_template_type_param 0x2f -#define DW_TAG_template_value_param 0x30 -#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 -#define DW_TAG_restrict_type 0x37 -#define DW_TAG_interface_type 0x38 -#define DW_TAG_namespace 0x39 -#define DW_TAG_imported_module 0x3a -#define DW_TAG_unspecified_type 0x3b -#define DW_TAG_partial_unit 0x3c -#define DW_TAG_imported_unit 0x3d -#define DW_TAG_mutable_type 0x3e -#define DW_TAG_lo_user 0x4080 -#define DW_TAG_MIPS_loop 0x4081 -#define DW_TAG_hi_user 0xffff - -/* 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++ */ - -/* 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 - - -#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_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 -#define DW_AT_associated 0x4f -#define DW_AT_data_location 0x50 -#define DW_AT_stride 0x51 -#define DW_AT_entry_pc 0x52 -#define DW_AT_use_UTF8 0x53 -#define DW_AT_extension 0x54 -#define DW_AT_ranges 0x55 -#define DW_AT_trampoline 0x56 -#define DW_AT_call_column 0x57 -#define DW_AT_call_file 0x58 -#define DW_AT_call_line 0x59 -#define DW_AT_description 0x5a -#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 - - -/* 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 - -/* 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 - - -#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_lo_user 0xe0 -#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 -#define DW_ATE_lo_user 0x80 - -/* 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 - -/* 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_ACCESS_public 1 -#define DW_ACCESS_protected 2 -#define DW_ACCESS_private 3 - -#define DW_VIS_local 1 -#define DW_VIS_exported 2 -#define DW_VIS_qualified 3 - -#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 -#define DW_LANG_C99 0x000c -#define DW_LANG_Ada95 0x000d -#define DW_LANG_Fortran95 0x000e -#define DW_LANG_lo_user 0x8000 -#define DW_LANG_Mips_Assembler 0x8001 - -/* Sun extensions */ -#define DW_LANG_SUN_Assembler 0x9001 - -#define DW_LANG_hi_user 0xffff - - -#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_normal 0x1 -#define DW_CC_program 0x2 -#define DW_CC_nocall 0x3 -#define DW_CC_lo_user 0x40 -#define DW_CC_hi_user 0xff - -#define DW_INL_not_inlined 0 -#define DW_INL_inlined 1 -#define DW_INL_declared_not_inlined 2 -#define DW_INL_declared_inlined 3 - -#define DW_ORD_row_major 0 -#define DW_ORD_col_major 1 - -#define DW_DSC_label 0 -#define DW_DSC_range 1 - -#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_LNE_end_sequence 1 -#define DW_LNE_set_address 2 -#define DW_LNE_define_file 3 - -#define DW_LNE_lo_user 128 -#define DW_LNE_hi_user 255 - -#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 - -#define DW_CFA_advance_loc 0x40 -#define DW_CFA_offset 0x80 -#define DW_CFA_restore 0xc0 -#define DW_CFA_extended 0 - -#define DW_CFA_nop 0x00 -#define DW_CFA_set_loc 0x01 -#define DW_CFA_advance_loc1 0x02 -#define DW_CFA_advance_loc2 0x03 -#define DW_CFA_advance_loc4 0x04 -#define DW_CFA_offset_extended 0x05 -#define DW_CFA_restore_extended 0x06 -#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_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 /* dwarf 2.1 */ -#define DW_CFA_expression 0x10 /* dwarf 2.1 */ -#define DW_CFA_cfa_offset_extended_sf 0x11 /* dwarf 2.1 */ -#define DW_CFA_def_cfa_sf 0x12 /* dwarf 2.1 */ -#define DW_CFA_def_cfa_offset_sf 0x13 /* dwarf 2.1 */ - -#define DW_CFA_low_user 0x1c -#define DW_CFA_MIPS_advance_loc8 0x1d - -/* the following two from egcs-1.1.2 */ -#define DW_CFA_GNU_window_save 0x2d -#define DW_CFA_GNU_args_size 0x2e - -#define DW_CFA_high_user 0x3f - - -/* 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. - - The CFA (Canonical Frame Address) described in DWARF is called - the Virtual Frame Pointer on MIPS/SGI machines. - - Rule describes: -*/ -#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. - */ -#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 */ -#define DW_FRAME_FREG3 35 /* 64-bit floating point reg 3 */ -#define DW_FRAME_FREG4 36 /* 64-bit floating point reg 4 */ -#define DW_FRAME_FREG5 37 /* 64-bit floating point reg 5 */ -#define DW_FRAME_FREG6 38 /* 64-bit floating point reg 6 */ -#define DW_FRAME_FREG7 39 /* 64-bit floating point reg 7 */ -#define DW_FRAME_FREG8 40 /* 64-bit floating point reg 8 */ -#define DW_FRAME_FREG9 41 /* 64-bit floating point reg 9 */ -#define DW_FRAME_FREG10 42 /* 64-bit floating point reg 10 */ -#define DW_FRAME_FREG11 43 /* 64-bit floating point reg 11 */ -#define DW_FRAME_FREG12 44 /* 64-bit floating point reg 12 */ -#define DW_FRAME_FREG13 45 /* 64-bit floating point reg 13 */ -#define DW_FRAME_FREG14 46 /* 64-bit floating point reg 14 */ -#define DW_FRAME_FREG15 47 /* 64-bit floating point reg 15 */ -#define DW_FRAME_FREG16 48 /* 64-bit floating point reg 16 */ -#define DW_FRAME_FREG17 49 /* 64-bit floating point reg 17 */ -#define DW_FRAME_FREG18 50 /* 64-bit floating point reg 18 */ -#define DW_FRAME_FREG19 51 /* 64-bit floating point reg 19 */ -#define DW_FRAME_FREG20 52 /* 64-bit floating point reg 20 */ -#define DW_FRAME_FREG21 53 /* 64-bit floating point reg 21 */ -#define DW_FRAME_FREG22 54 /* 64-bit floating point reg 22 */ -#define DW_FRAME_FREG23 55 /* 64-bit floating point reg 23 */ -#define DW_FRAME_FREG24 56 /* 64-bit floating point reg 24 */ -#define DW_FRAME_FREG25 57 /* 64-bit floating point reg 25 */ -#define DW_FRAME_FREG26 58 /* 64-bit floating point reg 26 */ -#define DW_FRAME_FREG27 59 /* 64-bit floating point reg 27 */ -#define DW_FRAME_FREG28 60 /* 64-bit floating point reg 28 */ -#define DW_FRAME_FREG29 61 /* 64-bit floating point reg 29 */ -#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 */ - -#define DW_FRAME_STATIC_LINK 65 /* column recording static link*/ - /* applicable to up-level */ - /* addressing, as in mp code, */ - /* pascal, etc */ - -/* 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) - - -/* - DW_FRAME_UNDEFINED_VAL and DW_FRAME_SAME_VAL are - never on disk, just generated by libdwarf. See libdwarf.h - for their values. -*/ - - - -#define DW_CHILDREN_no 0x00 -#define DW_CHILDREN_yes 0x01 - -#define DW_ADDR_none 0 - -#ifdef __cplusplus -} -#endif -#endif /* __DWARF_H */ diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/i386/Makefile --- a/usr/src/tools/ctf/dwarf/i386/Makefile Tue Jun 07 21:38:05 2011 -0500 +++ b/usr/src/tools/ctf/dwarf/i386/Makefile Wed Jun 08 17:36:48 2011 -0400 @@ -2,8 +2,7 @@ # Copyright 2004 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#ident "%Z%%M% %I% %E% SMI" include ../Makefile.com -all: libdwarf.so libdwarf.a +all: $(LIBS) diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/i386/libdwarf.a Binary file usr/src/tools/ctf/dwarf/i386/libdwarf.a has changed diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/i386/libdwarf.cpio.bz2 Binary file usr/src/tools/ctf/dwarf/i386/libdwarf.cpio.bz2 has changed diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/i386/libdwarf.so.1 Binary file usr/src/tools/ctf/dwarf/i386/libdwarf.so.1 has changed diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/libdwarf.h --- a/usr/src/tools/ctf/dwarf/libdwarf.h Tue Jun 07 21:38:05 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1615 +0,0 @@ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - - Copyright (C) 2000, 2001 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 - -*/ - - -#ifndef _LIBDWARF_H -#define _LIBDWARF_H -#ifdef __cplusplus -extern "C" { -#endif -/* - libdwarf.h - $Revision: 1.71 $ $Date: 2001/05/23 23:34:52 $ - - 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... - -*/ - -#if (_MIPS_SZLONG == 64) -/* Special case for MIPS, so -64 (LP64) build gets simple -long-. - Non-MIPS LP64 or ILP64 environments should probably ensure - _MIPS_SZLONG set to 64 everywhere this header is #included. -*/ -typedef int Dwarf_Bool; /* boolean type */ -typedef unsigned long Dwarf_Off; /* 4 or 8 byte file offset */ -typedef unsigned long Dwarf_Unsigned; /* 4 or 8 byte unsigned value */ -typedef unsigned short Dwarf_Half; /* 2 byte unsigned value */ -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 */ -#else /* 32-bit */ -/* This is for ILP32, allowing i/o of 64bit dwarf info. - Also should be fine for LP64 and ILP64 cases. -*/ -typedef int Dwarf_Bool; /* boolean type */ -typedef unsigned long long Dwarf_Off; /* 8 byte file offset */ -typedef unsigned long long Dwarf_Unsigned; /* 8 byte unsigned value*/ -typedef unsigned short Dwarf_Half; /* 2 byte unsigned value */ -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 */ -#endif -typedef void* Dwarf_Ptr; /* host machine pointer */ - -/* uninterpreted block of data -*/ -typedef struct { - Dwarf_Unsigned bl_len; /* length of block */ - Dwarf_Ptr bl_data; /* uninterpreted data */ -} Dwarf_Block; - - -/* 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_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_Locdesc; - -/* 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 - */ -#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]; -} Dwarf_Regtable; - -/* 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 - size in any given ABI.) Changing drd_type to an unsigned char - 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 -}; -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; -}; - -/* Opaque types for Consumer Library. */ -typedef struct Dwarf_Debug_s* Dwarf_Debug; -typedef struct Dwarf_Die_s* Dwarf_Die; -typedef struct Dwarf_Line_s* Dwarf_Line; -typedef struct Dwarf_Global_s* Dwarf_Global; -typedef struct Dwarf_Func_s* Dwarf_Func; -typedef struct Dwarf_Type_s* Dwarf_Type; -typedef struct Dwarf_Var_s* Dwarf_Var; -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; - -/* 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; - - -/* error handler function -*/ -typedef void (*Dwarf_Handler)(Dwarf_Error /*error*/, Dwarf_Ptr /*errarg*/); - - -/* - 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 */ - -/* The augmenter string for CIE */ -#define DW_CIE_AUGMENTER_STRING_V0 "z" - -/* dwarf_init() access arguments -*/ -#define DW_DLC_READ 0 /* read only access */ -#define DW_DLC_WRITE 1 /* write only access */ -#define DW_DLC_RDWR 2 /* read/write access NOT SUPPORTED*/ - -/* dwarf_init() access flag modifiers -*/ -#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_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 */ - -/* dwarf_pcline() slide arguments -*/ -#define DW_DLS_BACKWARD -1 /* slide backward to find line */ -#define DW_DLS_NOSLIDE 0 /* match exactly without sliding */ -#define DW_DLS_FORWARD 1 /* slide forward to find line */ - -/* libdwarf error numbers -*/ -#define DW_DLE_NE 0 /* no error */ -#define DW_DLE_VMM 1 /* dwarf format/library version mismatch */ -#define DW_DLE_MAP 2 /* memory map failure */ -#define DW_DLE_LEE 3 /* libelf error */ -#define DW_DLE_NDS 4 /* no debug section */ -#define DW_DLE_NLS 5 /* no line section */ -#define DW_DLE_ID 6 /* invalid descriptor for query */ -#define DW_DLE_IOF 7 /* I/O failure */ -#define DW_DLE_MAF 8 /* memory allocation failure */ -#define DW_DLE_IA 9 /* invalid argument */ -#define DW_DLE_MDE 10 /* mangled debugging entry */ -#define DW_DLE_MLE 11 /* mangled line number entry */ -#define DW_DLE_FNO 12 /* file not open */ -#define DW_DLE_FNR 13 /* file not a regular file */ -#define DW_DLE_FWA 14 /* file open with wrong access */ -#define DW_DLE_NOB 15 /* not an object file */ -#define DW_DLE_MOF 16 /* mangled object file header */ -#define DW_DLE_EOLL 17 /* end of location list entries */ -#define DW_DLE_NOLL 18 /* no location list section */ -#define DW_DLE_BADOFF 19 /* Invalid offset */ -#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) */ - /* Error codes defined by the current Libdwarf Implementation. */ -#define DW_DLE_DBG_ALLOC 23 -#define DW_DLE_FSTAT_ERROR 24 -#define DW_DLE_FSTAT_MODE_ERROR 25 -#define DW_DLE_INIT_ACCESS_WRONG 26 -#define DW_DLE_ELF_BEGIN_ERROR 27 -#define DW_DLE_ELF_GETEHDR_ERROR 28 -#define DW_DLE_ELF_GETSHDR_ERROR 29 -#define DW_DLE_ELF_STRPTR_ERROR 30 -#define DW_DLE_DEBUG_INFO_DUPLICATE 31 -#define DW_DLE_DEBUG_INFO_NULL 32 -#define DW_DLE_DEBUG_ABBREV_DUPLICATE 33 -#define DW_DLE_DEBUG_ABBREV_NULL 34 -#define DW_DLE_DEBUG_ARANGES_DUPLICATE 35 -#define DW_DLE_DEBUG_ARANGES_NULL 36 -#define DW_DLE_DEBUG_LINE_DUPLICATE 37 -#define DW_DLE_DEBUG_LINE_NULL 38 -#define DW_DLE_DEBUG_LOC_DUPLICATE 39 -#define DW_DLE_DEBUG_LOC_NULL 40 -#define DW_DLE_DEBUG_MACINFO_DUPLICATE 41 -#define DW_DLE_DEBUG_MACINFO_NULL 42 -#define DW_DLE_DEBUG_PUBNAMES_DUPLICATE 43 -#define DW_DLE_DEBUG_PUBNAMES_NULL 44 -#define DW_DLE_DEBUG_STR_DUPLICATE 45 -#define DW_DLE_DEBUG_STR_NULL 46 -#define DW_DLE_CU_LENGTH_ERROR 47 -#define DW_DLE_VERSION_STAMP_ERROR 48 -#define DW_DLE_ABBREV_OFFSET_ERROR 49 -#define DW_DLE_ADDRESS_SIZE_ERROR 50 -#define DW_DLE_DEBUG_INFO_PTR_NULL 51 -#define DW_DLE_DIE_NULL 52 -#define DW_DLE_STRING_OFFSET_BAD 53 -#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_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_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 - - /* DW_DLE_LAST MUST EQUAL LAST ERROR NUMBER */ -#define DW_DLE_LAST 193 -#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 - */ -#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 - */ -#define DW_FRAME_SAME_VAL 1035 - - - -/* error return values -*/ -#define DW_DLV_BADADDR (~(Dwarf_Addr)0) - /* for functions returning target address */ - -#define DW_DLV_NOCOUNT ((Dwarf_Signed)-1) - /* for functions returning count */ - -#define DW_DLV_BADOFFSET (~(Dwarf_Off)0) - /* for functions returning offset */ - -/* standard return values for functions */ -#define DW_DLV_NO_ENTRY -1 -#define DW_DLV_OK 0 -#define DW_DLV_ERROR 1 - -/* 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) -/* 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) - - -/*===========================================================================*/ -/* 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 */ -int dwarf_elf_init(Elf* /*elf*/, - 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*/, - Elf ** /*return_elfptr*/, - Dwarf_Error* /*error*/); - -int dwarf_finish(Dwarf_Debug /*dbg*/, Dwarf_Error* /*error*/); - -/* die traversal operations */ -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*/); - -int dwarf_siblingof(Dwarf_Debug /*dbg*/, - 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 */ -int dwarf_offdie(Dwarf_Debug /*dbg*/, - 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*/); - -/* Unimplemented */ -int dwarf_pcsubr(Dwarf_Debug /*dbg*/, - 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*/); - -/* operations on DIEs */ -int dwarf_tag(Dwarf_Die /*die*/, - Dwarf_Half* /*return_tag*/, - Dwarf_Error* /*error*/); - -/* utility? */ -int dwarf_dieoffset(Dwarf_Die /*die*/, - Dwarf_Off* /*return_offset*/, - Dwarf_Error* /*error*/); - -int dwarf_die_CU_offset(Dwarf_Die /*die*/, - Dwarf_Off* /*return_offset*/, - Dwarf_Error* /*error*/); - -int dwarf_attr (Dwarf_Die /*die*/, - Dwarf_Half /*attr*/, - Dwarf_Attribute * /*returned_attr*/, - Dwarf_Error* /*error*/); - -int dwarf_diename(Dwarf_Die /*die*/, - char ** /*diename*/, - Dwarf_Error* /*error*/); - -/* convenience functions, alternative to using dwarf_attrlist() */ -int dwarf_hasattr(Dwarf_Die /*die*/, - Dwarf_Half /*attr*/, - Dwarf_Bool * /*returned_bool*/, - Dwarf_Error* /*error*/); - -int dwarf_loclist(Dwarf_Attribute /*attr*/, - Dwarf_Locdesc** /*llbuf*/, - Dwarf_Signed * /*locCount*/, - Dwarf_Error* /*error*/); - -/* Unimplemented */ -int dwarf_stringlen(Dwarf_Die /*die*/, - Dwarf_Locdesc ** /*returned_locdesc*/, - Dwarf_Error* /*error*/); - -/* Unimplemented */ -int dwarf_subscrcnt(Dwarf_Die /*die*/, - Dwarf_Signed * /*returned_count*/, - Dwarf_Error* /*error*/); - -/* Unimplemented */ -int dwarf_nthsubscr(Dwarf_Die /*die*/, - Dwarf_Unsigned /*ssndx*/, - Dwarf_Die * /*returned_die*/, - Dwarf_Error* /*error*/); - -int dwarf_lowpc(Dwarf_Die /*die*/, - Dwarf_Addr * /*returned_addr*/, - Dwarf_Error* /*error*/); - -int dwarf_highpc(Dwarf_Die /*die*/, - Dwarf_Addr * /*returned_addr*/, - Dwarf_Error* /*error*/); - -int dwarf_bytesize(Dwarf_Die /*die*/, - Dwarf_Unsigned * /*returned_size*/, - Dwarf_Error* /*error*/); - -/* Unimplemented */ -int dwarf_isbitfield(Dwarf_Die /*die*/, - Dwarf_Bool * /*returned_bool*/, - Dwarf_Error* /*error*/); - -int dwarf_bitsize(Dwarf_Die /*die*/, - Dwarf_Unsigned * /*returned_size*/, - Dwarf_Error* /*error*/); - -int dwarf_bitoffset(Dwarf_Die /*die*/, - Dwarf_Unsigned * /*returned_offset*/, - Dwarf_Error* /*error*/); - -int dwarf_srclang(Dwarf_Die /*die*/, - Dwarf_Unsigned * /*returned_lang*/, - Dwarf_Error* /*error*/); - -int dwarf_arrayorder(Dwarf_Die /*die*/, - 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*/); - -/* query operations for attributes */ -int dwarf_hasform(Dwarf_Attribute /*attr*/, - Dwarf_Half /*form*/, - Dwarf_Bool * /*returned_bool*/, - Dwarf_Error* /*error*/); - -int dwarf_whatform(Dwarf_Attribute /*attr*/, - Dwarf_Half * /*returned_form*/, - Dwarf_Error* /*error*/); - -int dwarf_whatattr(Dwarf_Attribute /*attr*/, - 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*/ -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*/ -int dwarf_global_formref(Dwarf_Attribute /*attr*/, - Dwarf_Off* /*return_offset*/, - Dwarf_Error* /*error*/); - -int dwarf_formaddr(Dwarf_Attribute /*attr*/, - Dwarf_Addr * /*returned_addr*/, - Dwarf_Error* /*error*/); - -int dwarf_formflag(Dwarf_Attribute /*attr*/, - 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*/); - -int dwarf_formblock(Dwarf_Attribute /*attr*/, - Dwarf_Block ** /*returned_block*/, - Dwarf_Error* /*error*/); - -int dwarf_formstring(Dwarf_Attribute /*attr*/, - char ** /*returned_string*/, - 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*/); - -int dwarf_srcfiles(Dwarf_Die /*die*/, - char*** /*srcfiles*/, - Dwarf_Signed * /*filecount*/, - Dwarf_Error* /*error*/); - -/* Unimplemented. */ -int dwarf_dieline(Dwarf_Die /*die*/, - Dwarf_Line * /*returned_line*/, - Dwarf_Error * /*error*/); - -int dwarf_linebeginstatement(Dwarf_Line /*line*/, - Dwarf_Bool * /*returned_bool*/, - Dwarf_Error* /*error*/); - -int dwarf_lineendsequence(Dwarf_Line /*line*/, - Dwarf_Bool * /*returned_bool*/, - Dwarf_Error* /*error*/); - -int dwarf_lineno(Dwarf_Line /*line*/, - Dwarf_Unsigned * /*returned_lineno*/, - Dwarf_Error* /*error*/); - -int dwarf_lineaddr(Dwarf_Line /*line*/, - Dwarf_Addr * /*returned_addr*/, - Dwarf_Error* /*error*/); - -int dwarf_lineoff(Dwarf_Line /*line*/, - Dwarf_Signed * /*returned_lineoffset*/, - Dwarf_Error* /*error*/); - -int dwarf_linesrc(Dwarf_Line /*line*/, - char ** /*returned_name*/, - Dwarf_Error* /*error*/); - -int dwarf_lineblock(Dwarf_Line /*line*/, - 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*/); -/* 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*/); - -int dwarf_globname(Dwarf_Global /*glob*/, - char ** /*returned_name*/, - Dwarf_Error* /*error*/); - -int dwarf_global_die_offset(Dwarf_Global /*global*/, - Dwarf_Off* /*return_offset*/, - Dwarf_Error * /*error*/); - -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*/); -#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*/); - -int dwarf_global_name_offsets(Dwarf_Global /*global*/, - 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_funcname(Dwarf_Func /*func*/, - char ** /*returned_name*/, - Dwarf_Error* /*error*/); - -int dwarf_func_die_offset(Dwarf_Func /*func*/, - Dwarf_Off* /*return_offset*/, - Dwarf_Error* /*error*/); - -int dwarf_func_cu_offset(Dwarf_Func /*func*/, - 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*/); - -int dwarf_typename(Dwarf_Type /*type*/, - char ** /*returned_name*/, - Dwarf_Error* /*error*/); - -int dwarf_type_die_offset(Dwarf_Type /*type*/, - 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*/); - -/* 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_varname(Dwarf_Var /*var*/, - char ** /*returned_name*/, - Dwarf_Error* /*error*/); - -int dwarf_var_die_offset(Dwarf_Var /*var*/, - Dwarf_Off* /*return_offset*/, - Dwarf_Error* /*error*/); - -int dwarf_var_cu_offset(Dwarf_Var /*var*/, - 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*/); - -/* weak name operations. */ -int dwarf_get_weaks(Dwarf_Debug /*dbg*/, - Dwarf_Weak** /*weaks*/, - Dwarf_Signed * /*number_of_weaks*/, - Dwarf_Error* /*error*/); - -int dwarf_weakname(Dwarf_Weak /*weak*/, - char ** /*returned_name*/, - Dwarf_Error* /*error*/); - -int dwarf_weak_die_offset(Dwarf_Weak /*weak*/, - 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*/); - -/* 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*/); - -/* 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*/); - -int dwarf_get_abbrev_tag(Dwarf_Abbrev /*abbrev*/, - Dwarf_Half* /*return_tag_number*/, - Dwarf_Error* /*error*/); -int dwarf_get_abbrev_code(Dwarf_Abbrev /*abbrev*/, - Dwarf_Unsigned* /*return_code_number*/, - Dwarf_Error* /*error*/); - -int dwarf_get_abbrev_children_flag(Dwarf_Abbrev /*abbrev*/, - 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*/); - -/* consumer string section operation */ -int dwarf_get_str(Dwarf_Debug /*dbg*/, - 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*/); - - -/* 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*/); - - -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*/); - -int dwarf_get_fde_exception_info(Dwarf_Fde /*fde*/, - 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*/); - -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*/); - -int dwarf_get_fde_instr_bytes(Dwarf_Fde /*fde*/, - 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*/); - -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*/); - -int dwarf_get_fde_for_die(Dwarf_Debug /*dbg*/, - 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*/); - -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*/); - -/* Operations on .debug_aranges. */ -int dwarf_get_aranges(Dwarf_Debug /*dbg*/, - 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*/); - -int dwarf_get_cu_die_offset( - 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*/); -#ifdef __sgi /* pragma is sgi MIPS only */ -#pragma optional dwarf_get_arange_cu_header_offset -#endif - -int dwarf_get_arange_info( - Dwarf_Arange /*arange*/, - 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, - of this macro info */ - 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: - applies to define undef start_file - */ - char * dmd_macro; /* macro name (with value for defineop) - string from vendor ext - */ -}; - -/* _dwarf_print_lines is for use by dwarfdump: it prints - line info to stdout. -*/ -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 - section per function. - -OPT:procedure_reorder=ON - where ld-cord (cord(1)ing by ld, - not by cord(1)) may have changed the function order. -*/ -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 -*/ -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_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; - -int dwarf_get_macro(Dwarf_Debug /*dbg*/, - char * /*requested_macro_name*/, - Dwarf_Addr /*pc_of_request*/, - char ** /*returned_macro_value*/, - Dwarf_Error * /*error*/); - -int dwarf_get_all_defined_macros(Dwarf_Debug /*dbg*/, - Dwarf_Addr /*pc_of_request*/, - Dwarf_Signed * /*returned_count*/, - char *** /*returned_pointers_to_macros*/, - Dwarf_Error * /*error*/); - -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_Signed * /*entry_count*/, - Dwarf_Macro_Details ** /*details*/, - Dwarf_Error * /*err*/); - - -int dwarf_get_address_size(Dwarf_Debug /*dbg*/, - Dwarf_Half * /*addr_size*/, - Dwarf_Error * /*error*/); - -/* utility operations */ -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. -** Call with parameter value 1 to turn off many such checks (and -** increase performance). -** Call with zero for safest running. -** Actual value saved and returned is only 8 bits! Upper bits -** ignored by libdwarf (and zero on return). -** Returns previous value. -*/ -int dwarf_set_stringcheck(int /*stringcheck*/); - -/* Unimplemented */ -Dwarf_Handler dwarf_seterrhand(Dwarf_Debug /*dbg*/, Dwarf_Handler /*errhand*/); - -/* Unimplemented */ -Dwarf_Ptr dwarf_seterrarg(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*errarg*/); - -void dwarf_dealloc(Dwarf_Debug /*dbg*/, void* /*space*/, - Dwarf_Unsigned /*type*/); - -/* 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*/); - -Dwarf_P_Debug dwarf_producer_init( - 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*/); - - -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_Signed dwarf_transform_to_disk_form(Dwarf_P_Debug /*dbg*/, - 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*/); - -int dwarf_get_relocation_info_count( - 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*/); - -/* v1: no drd_length field, enum explicit */ -/* v2: has the drd_length field, enum value in uchar member */ -#define DWARF_DRD_BUFFER_VERSION 2 - -void dwarf_reset_section_bytes(Dwarf_P_Debug /*dbg*/); - -Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug /*dbg*/, - Dwarf_Error* /*error*/); - -/* 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_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_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_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_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_Attribute dwarf_add_AT_const_value_string(Dwarf_P_Die /*ownerdie*/, - 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_Attribute dwarf_add_AT_string(Dwarf_P_Debug /*dbg*/, - 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_Attribute dwarf_add_AT_producer(Dwarf_P_Die /*ownerdie*/, - 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_P_Attribute dwarf_add_AT_const_value_unsignedint( - 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*/); - -/* Producer line creation functions (.debug_line) */ -Dwarf_Unsigned dwarf_add_directory_decl(Dwarf_P_Debug /*dbg*/, - 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*/); - -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 dwarf_lne_set_address(Dwarf_P_Debug /*dbg*/, - 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*/); - -/* 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*/); - -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_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_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_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 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 dwarf_fde_cfa_offset( - 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_Unsigned dwarf_add_die_to_debug( - Dwarf_P_Debug /*dbg*/, - Dwarf_P_Die /*die*/, - 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*/); - -void dwarf_dealloc_compressed_block( - Dwarf_P_Debug, - void * -); - -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 */ -); - -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*, /* 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*/); - -Dwarf_Unsigned dwarf_add_expr_gen( - 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_Unsigned dwarf_add_expr_addr_b( - 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_Addr dwarf_expr_into_block( - 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_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_Unsigned dwarf_add_pubname( - 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_Unsigned dwarf_add_typename( - 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_Unsigned dwarf_add_weakname( - 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*/); - -int dwarf_undef_macro(Dwarf_P_Debug /*dbg*/, - 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*/); - -int dwarf_end_macro_file(Dwarf_P_Debug /*dbg*/, - Dwarf_Error* /*error*/); - -int dwarf_vendor_ext(Dwarf_P_Debug /*dbg*/, - 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*/); - - -#ifdef __cplusplus -} -#endif -#endif /* _LIBDWARF_H */ - diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/sparc/Makefile --- a/usr/src/tools/ctf/dwarf/sparc/Makefile Tue Jun 07 21:38:05 2011 -0500 +++ b/usr/src/tools/ctf/dwarf/sparc/Makefile Wed Jun 08 17:36:48 2011 -0400 @@ -2,6 +2,7 @@ # Copyright 2004 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#ident "%Z%%M% %I% %E% SMI" include ../Makefile.com + +all: $(LIBS) diff -r 3d898cde151e -r 2e5a34cc8a49 usr/src/tools/ctf/dwarf/sparc/libdwarf.so.1 Binary file usr/src/tools/ctf/dwarf/sparc/libdwarf.so.1 has changed