--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_frames.c Fri Jan 15 09:07:44 2010 +0000
@@ -0,0 +1,1104 @@
+/*
+ Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved.
+ Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU 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 General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+ Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ Mountain View, CA 94043, or:
+
+ http://www.sgi.com
+
+ For further information regarding this notice, see:
+
+ http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_frames.c,v 1.5 2006/06/14 20:34:02 davea Exp $ */
+
+/* The address of the Free Software Foundation is
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ SGI has moved from the Crittenden Lane address.
+*/
+
+
+
+#include "globals.h"
+
+#include "print_frames.h"
+#include "dwconf.h"
+#include "esb.h"
+
+
+static void
+ print_one_frame_reg_col(Dwarf_Debug dbg,
+ Dwarf_Unsigned rule_id,
+ Dwarf_Small value_type,
+ Dwarf_Unsigned reg_used,
+ struct dwconf_s *config_data,
+ Dwarf_Signed offset_relevant,
+ Dwarf_Signed offset, Dwarf_Ptr block_ptr);
+
+/*
+ Gather the fde print logic here so the control logic
+ determining what FDE to print is clearer.
+*/
+int
+print_one_fde(Dwarf_Debug dbg, Dwarf_Fde fde,
+ Dwarf_Unsigned fde_index,
+ Dwarf_Cie * cie_data,
+ Dwarf_Signed cie_element_count,
+ Dwarf_Half address_size, int is_eh,
+ struct dwconf_s *config_data)
+{
+ Dwarf_Addr j = 0;
+ Dwarf_Addr low_pc = 0;
+ Dwarf_Unsigned func_length = 0;
+ Dwarf_Ptr fde_bytes = NULL;
+ Dwarf_Unsigned fde_bytes_length = 0;
+ Dwarf_Off cie_offset = 0;
+ Dwarf_Signed cie_index = 0;
+ Dwarf_Off fde_offset = 0;
+ Dwarf_Signed eh_table_offset = 0;
+ int fres = 0;
+ int offres = 0;
+ string temps = 0;
+ Dwarf_Error err = 0;
+ int printed_intro_addr = 0;
+
+ fres = dwarf_get_fde_range(fde,
+ &low_pc, &func_length,
+ &fde_bytes,
+ &fde_bytes_length,
+ &cie_offset, &cie_index,
+ &fde_offset, &err);
+ if (fres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_get_fde_range", fres, err);
+ }
+ if (fres == DW_DLV_NO_ENTRY) {
+ return DW_DLV_NO_ENTRY;
+ }
+ if (cu_name_flag &&
+ fde_offset_for_cu_low != DW_DLV_BADOFFSET &&
+ (fde_offset < fde_offset_for_cu_low ||
+ fde_offset > fde_offset_for_cu_high)) {
+ return DW_DLV_NO_ENTRY;
+ }
+ /* eh_table_offset is IRIX ONLY. */
+ fres = dwarf_get_fde_exception_info(fde, &eh_table_offset, &err);
+ if (fres == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_get_fde_exception_info", fres, err);
+ }
+ temps = get_fde_proc_name(dbg, low_pc);
+ printf
+ ("<%3lld><%#llx:%#llx><%s><fde offset 0x%llx length: 0x%llx>",
+ cie_index, low_pc, (low_pc + func_length),
+ temps ? temps : "", fde_offset, fde_bytes_length);
+
+
+ if (!is_eh) {
+ /* IRIX uses eh_table_offset. */
+ if (eh_table_offset == DW_DLX_NO_EH_OFFSET) {
+ printf("<eh offset %s>\n", "none");
+ } else if (eh_table_offset == DW_DLX_EH_OFFSET_UNAVAILABLE) {
+ printf("<eh offset %s>\n", "unknown");
+ } else {
+ printf("<eh offset 0x%llx>\n", eh_table_offset);
+ }
+ } else {
+ int ares = 0;
+ Dwarf_Small *data = 0;
+ Dwarf_Unsigned len = 0;
+
+ ares = dwarf_get_fde_augmentation_data(fde, &data, &len, &err);
+ if (ares == DW_DLV_NO_ENTRY) {
+ /* do nothing. */
+ } else if (ares == DW_DLV_OK) {
+ int k2;
+
+ printf("<eh aug data len 0x%llx", (long long) len);
+ for (k2 = 0; k2 < len; ++k2) {
+ if (k2 == 0) {
+ printf(" bytes 0x");
+ }
+ printf("%02x ", (unsigned char) data[k2]);
+ }
+ printf(">");
+ } /* else DW_DLV_ERROR, do nothing */
+ printf("\n");
+ }
+ /* call dwarf_get_fde_info_for_reg() to get whole matrix */
+
+ for (j = low_pc; j < low_pc + func_length; j++) {
+ Dwarf_Half k;
+
+ if (config_data->cf_interface_number == 3) {
+ Dwarf_Signed reg = 0;
+ Dwarf_Signed offset_relevant = 0;
+ Dwarf_Small value_type = 0;
+ Dwarf_Signed offset_or_block_len = 0;
+ Dwarf_Signed offset = 0;
+ Dwarf_Ptr block_ptr = 0;
+ Dwarf_Addr row_pc = 0;
+
+ int fires = dwarf_get_fde_info_for_cfa_reg3(fde,
+ j,
+ &value_type,
+ &offset_relevant,
+ ®,
+ &offset_or_block_len,
+ &block_ptr,
+ &row_pc,
+ &err);
+
+ offset = offset_or_block_len;
+ if (fires == DW_DLV_ERROR) {
+ print_error(dbg,
+ "dwarf_get_fde_info_for_reg", fires, err);
+ }
+ if (fires == DW_DLV_NO_ENTRY) {
+ continue;
+ }
+ if (row_pc != j) {
+ /* duplicate row */
+ continue;
+ }
+ if (!printed_intro_addr) {
+ printf(" %08llx:\t", j);
+ printed_intro_addr = 1;
+ }
+ print_one_frame_reg_col(dbg, config_data->cf_cfa_reg,
+ value_type,
+ reg,
+ config_data,
+ offset_relevant, offset, block_ptr);
+ }
+ for (k = 0; k < config_data->cf_table_entry_count; k++) {
+ Dwarf_Signed reg = 0;
+ Dwarf_Signed offset_relevant = 0;
+ int fires = 0;
+ Dwarf_Small value_type = 0;
+ Dwarf_Ptr block_ptr = 0;
+ Dwarf_Signed offset_or_block_len = 0;
+ Dwarf_Signed offset = 0;
+ Dwarf_Addr row_pc = 0;
+
+ if (config_data->cf_interface_number == 3) {
+
+ fires = dwarf_get_fde_info_for_reg3(fde,
+ k,
+ j,
+ &value_type,
+ &offset_relevant,
+ ®,
+ &offset_or_block_len,
+ &block_ptr,
+ &row_pc, &err);
+ offset = offset_or_block_len;
+ } else { /* ASSERT:
+ config_data->cf_interface_number ==
+ 2 */
+
+
+ value_type = DW_EXPR_OFFSET;
+ fires = dwarf_get_fde_info_for_reg(fde,
+ k,
+ j,
+ &offset_relevant,
+ ®,
+ &offset, &row_pc,
+ &err);
+ }
+ if (fires == DW_DLV_ERROR) {
+ printf("\n");
+ print_error(dbg,
+ "dwarf_get_fde_info_for_reg", fires, err);
+ }
+ if (fires == DW_DLV_NO_ENTRY) {
+ continue;
+ }
+ if (row_pc != j) {
+ /* duplicate row */
+ break;
+ }
+ if (!printed_intro_addr) {
+ printf(" %08llx:\t", j);
+ printed_intro_addr = 1;
+ }
+ print_one_frame_reg_col(dbg,k,
+ value_type,
+ reg,
+ config_data,
+ offset_relevant, offset, block_ptr);
+
+ }
+ if (printed_intro_addr) {
+ printf("\n");
+ printed_intro_addr = 0;
+ }
+ }
+ if (verbose > 1) {
+ Dwarf_Off fde_off;
+ Dwarf_Off cie_off;
+
+ /* get the fde instructions and print them in raw form, just
+ like cie instructions */
+ Dwarf_Ptr instrs;
+ Dwarf_Unsigned ilen;
+ int res;
+
+ res = dwarf_get_fde_instr_bytes(fde, &instrs, &ilen, &err);
+ offres =
+ dwarf_fde_section_offset(dbg, fde, &fde_off, &cie_off,
+ &err);
+ if (offres == DW_DLV_OK) {
+ printf("\tfde sec. offset %llu 0x%llx"
+ " cie offset for fde: %llu 0x%llx\n",
+ (unsigned long long) fde_off,
+ (unsigned long long) fde_off,
+ (unsigned long long) cie_off,
+ (unsigned long long) cie_off);
+
+ }
+
+
+ if (res == DW_DLV_OK) {
+ int cires = 0;
+ Dwarf_Unsigned cie_length = 0;
+ Dwarf_Small version = 0;
+ string augmenter;
+ Dwarf_Unsigned code_alignment_factor = 0;
+ Dwarf_Signed data_alignment_factor = 0;
+ Dwarf_Half return_address_register_rule = 0;
+ Dwarf_Ptr initial_instructions = 0;
+ Dwarf_Unsigned initial_instructions_length = 0;
+
+ if (cie_index >= cie_element_count) {
+ printf("Bad cie index %lld with fde index %lld! "
+ "(table entry max %lld)\n",
+ (long long) cie_index, (long long) fde_index,
+ (long long) cie_element_count);
+ exit(1);
+ }
+
+ cires = dwarf_get_cie_info(cie_data[cie_index],
+ &cie_length,
+ &version,
+ &augmenter,
+ &code_alignment_factor,
+ &data_alignment_factor,
+ &return_address_register_rule,
+ &initial_instructions,
+ &initial_instructions_length,
+ &err);
+ if (cires == DW_DLV_ERROR) {
+ printf
+ ("Bad cie index %lld with fde index %lld!\n",
+ (long long) cie_index, (long long) fde_index);
+ print_error(dbg, "dwarf_get_cie_info", cires, err);
+ }
+ if (cires == DW_DLV_NO_ENTRY) {
+ ; /* ? */
+ } else {
+
+ print_frame_inst_bytes(dbg, instrs,
+ (Dwarf_Signed) ilen,
+ data_alignment_factor,
+ (int) code_alignment_factor,
+ address_size, config_data);
+ }
+ } else if (res == DW_DLV_NO_ENTRY) {
+ printf
+ ("Impossible: no instr bytes for fde index %d?\n",
+ (int) fde_index);
+ } else {
+ /* DW_DLV_ERROR */
+ printf
+ ("Error: on gettinginstr bytes for fde index %d?\n",
+ (int) fde_index);
+ print_error(dbg, "dwarf_get_fde_instr_bytes", res, err);
+ }
+
+ }
+ return DW_DLV_OK;
+}
+
+
+/* Print a cie. Gather the print logic here so the
+ control logic deciding what to print
+ is clearer.
+*/
+int
+print_one_cie(Dwarf_Debug dbg, Dwarf_Cie cie,
+ Dwarf_Unsigned cie_index, Dwarf_Half address_size,
+ struct dwconf_s *config_data)
+{
+
+ int cires = 0;
+ Dwarf_Unsigned cie_length = 0;
+ Dwarf_Small version = 0;
+ string augmenter = "";
+ Dwarf_Unsigned code_alignment_factor = 0;
+ Dwarf_Signed data_alignment_factor = 0;
+ Dwarf_Half return_address_register_rule = 0;
+ Dwarf_Ptr initial_instructions = 0;
+ Dwarf_Unsigned initial_instructions_length = 0;
+ Dwarf_Off cie_off = 0;
+ Dwarf_Error err = 0;
+
+ cires = dwarf_get_cie_info(cie,
+ &cie_length,
+ &version,
+ &augmenter,
+ &code_alignment_factor,
+ &data_alignment_factor,
+ &return_address_register_rule,
+ &initial_instructions,
+ &initial_instructions_length, &err);
+ if (cires == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_get_cie_info", cires, err);
+ }
+ if (cires == DW_DLV_NO_ENTRY) {
+ ; /* ? */
+ printf("Impossible DW_DLV_NO_ENTRY on cie %d\n",
+ (int) cie_index);
+ return DW_DLV_NO_ENTRY;
+ }
+ {
+ printf("<%3lld>\tversion\t\t\t\t%d\n", cie_index, version);
+ cires = dwarf_cie_section_offset(dbg, cie, &cie_off, &err);
+ if (cires == DW_DLV_OK) {
+ printf("\tcie sec. offset %llu 0x%llx\n",
+ (unsigned long long) cie_off,
+ (unsigned long long) cie_off);
+
+ }
+
+ printf("\taugmentation\t\t\t%s\n", augmenter);
+ printf("\tcode_alignment_factor\t\t%llu\n",
+ (unsigned long long) code_alignment_factor);
+ printf("\tdata_alignment_factor\t\t%lld\n",
+ (long long) data_alignment_factor);
+ printf("\treturn_address_register\t\t%d\n",
+ (int) return_address_register_rule);
+ {
+ int ares = 0;
+ Dwarf_Small *data = 0;
+ Dwarf_Unsigned len = 0;
+
+ ares =
+ dwarf_get_cie_augmentation_data(cie, &data, &len, &err);
+ if (ares == DW_DLV_NO_ENTRY) {
+ /* do nothing. */
+ } else if (ares == DW_DLV_OK && len > 0) {
+ int k2;
+
+ printf("\teh aug data len 0x%llx", (long long) len);
+ for (k2 = 0; data && k2 < len; ++k2) {
+ if (k2 == 0) {
+ printf(" bytes 0x");
+ }
+ printf("%02x ", (unsigned char) data[k2]);
+ }
+ printf("\n");
+ } /* else DW_DLV_ERROR or no data, do
+ nothing */
+ }
+
+ printf
+ ("\tbytes of initial instructions:\t%lld\n",
+ (long long) initial_instructions_length);
+ printf("\tcie length :\t\t\t%lld\n", (long long) cie_length);
+ print_frame_inst_bytes(dbg, initial_instructions, (Dwarf_Signed)
+ initial_instructions_length,
+ data_alignment_factor,
+ (int) code_alignment_factor,
+ address_size, config_data);
+ }
+ return DW_DLV_OK;
+}
+
+void
+get_string_from_locs(Dwarf_Debug dbg,
+ Dwarf_Ptr bytes_in,
+ Dwarf_Unsigned block_len,struct esb_s *out_string)
+{
+
+ Dwarf_Locdesc *locdescarray = 0;
+ Dwarf_Signed listlen = 0;
+ Dwarf_Error err2 =0;
+ int skip_locdesc_header=1;
+ int res2 = dwarf_loclist_from_expr(dbg,
+ bytes_in,block_len,
+ &locdescarray,
+ &listlen,&err2);
+ if (res2 == DW_DLV_ERROR) {
+ print_error(dbg, "dwarf_get_loclist_from_expr",
+ res2, err2);
+ }
+ if(res2==DW_DLV_NO_ENTRY) {
+ return;
+ }
+ /* lcnt is always 1 */
+
+ /* Use locdescarray here.*/
+ int res = dwarfdump_print_one_locdesc(dbg,
+ locdescarray,
+ skip_locdesc_header,
+ out_string);
+ if(res != DW_DLV_OK) {
+ printf("Bad status from _dwarf_print_one_locdesc %d\n",res);
+ exit(1);
+ }
+
+
+
+ dwarf_dealloc(dbg, locdescarray->ld_s, DW_DLA_LOC_BLOCK);
+ dwarf_dealloc(dbg, locdescarray, DW_DLA_LOCDESC);
+
+
+ return ;
+}
+
+/* Print the frame instructions in detail for a glob of instructions.
+*/
+
+ /*ARGSUSED*/ void
+print_frame_inst_bytes(Dwarf_Debug dbg,
+ Dwarf_Ptr cie_init_inst, Dwarf_Signed len,
+ Dwarf_Signed data_alignment_factor,
+ int code_alignment_factor, Dwarf_Half addr_size,
+ struct dwconf_s *config_data)
+{
+ unsigned char *instp = (unsigned char *) cie_init_inst;
+ Dwarf_Unsigned uval;
+ Dwarf_Unsigned uval2;
+ unsigned int uleblen;
+ unsigned int off = 0;
+ unsigned int loff = 0;
+ unsigned short u16;
+ unsigned int u32;
+ unsigned long long u64;
+
+ for (; len > 0;) {
+ unsigned char ibyte = *instp;
+ int top = ibyte & 0xc0;
+ int bottom = ibyte & 0x3f;
+ int delta;
+ int reg;
+
+ switch (top) {
+ case DW_CFA_advance_loc:
+ delta = ibyte & 0x3f;
+ printf("\t%2u DW_CFA_advance_loc %d", off,
+ (int) (delta * code_alignment_factor));
+ if (verbose) {
+ printf(" (%d * %d)", (int) delta,
+ (int) code_alignment_factor);
+ }
+ printf("\n");
+ break;
+ case DW_CFA_offset:
+ loff = off;
+ reg = ibyte & 0x3f;
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_offset ", loff);
+ printreg((Dwarf_Signed) reg, config_data);
+ printf(" %lld", (signed long long)
+ (((Dwarf_Signed) uval) * data_alignment_factor));
+ if (verbose) {
+ printf(" (%llu * %d)", (unsigned long long) uval,
+ (int) data_alignment_factor);
+ }
+ printf("\n");
+ break;
+
+ case DW_CFA_restore:
+ reg = ibyte & 0x3f;
+ printf("\t%2u DW_CFA_restore \n", off);
+ printreg((Dwarf_Signed) reg, config_data);
+ printf("\n");
+ break;
+
+ default:
+ loff = off;
+ switch (bottom) {
+ case DW_CFA_set_loc:
+ /* operand is address, so need address size */
+ /* which will be 4 or 8. */
+ switch (addr_size) {
+ case 4:
+ {
+ __uint32_t v32;
+
+ memcpy(&v32, instp + 1, addr_size);
+ uval = v32;
+ }
+ break;
+ case 8:
+ {
+ __uint64_t v64;
+
+ memcpy(&v64, instp + 1, addr_size);
+ uval = v64;
+ }
+ break;
+ default:
+ printf
+ ("Error: Unexpected address size %d in DW_CFA_set_loc!\n",
+ addr_size);
+ uval = 0;
+ }
+
+ instp += addr_size;
+ len -= (Dwarf_Signed) addr_size;
+ off += addr_size;
+ printf("\t%2u DW_CFA_set_loc %llu\n",
+ loff, (unsigned long long) uval);
+ break;
+ case DW_CFA_advance_loc1:
+ delta = (unsigned char) *(instp + 1);
+ uval2 = delta;
+ instp += 1;
+ len -= 1;
+ off += 1;
+ printf("\t%2u DW_CFA_advance_loc1 %llu\n",
+ loff, (unsigned long long) uval2);
+ break;
+ case DW_CFA_advance_loc2:
+ memcpy(&u16, instp + 1, 2);
+ uval2 = u16;
+ instp += 2;
+ len -= 2;
+ off += 2;
+ printf("\t%2u DW_CFA_advance_loc2 %llu\n",
+ loff, (unsigned long long) uval2);
+ break;
+ case DW_CFA_advance_loc4:
+ memcpy(&u32, instp + 1, 4);
+ uval2 = u32;
+ instp += 4;
+ len -= 4;
+ off += 4;
+ printf("\t%2u DW_CFA_advance_loc4 %llu\n",
+ loff, (unsigned long long) uval2);
+ break;
+ case DW_CFA_MIPS_advance_loc8:
+ memcpy(&u64, instp + 1, 8);
+ uval2 = u64;
+ instp += 8;
+ len -= 8;
+ off += 8;
+ printf("\t%2u DW_CFA_MIPS_advance_loc8 %llu\n",
+ loff, (unsigned long long) uval2);
+ break;
+ case DW_CFA_offset_extended:
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ uval2 =
+ local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_offset_extended ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf(" %lld", (signed long long)
+ (((Dwarf_Signed) uval2) *
+ data_alignment_factor));
+ if (verbose) {
+ printf(" (%llu * %d)", (unsigned long long) uval2,
+ (int) data_alignment_factor);
+ }
+ printf("\n");
+ break;
+
+ case DW_CFA_restore_extended:
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_restore_extended ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf("\n");
+ break;
+ case DW_CFA_undefined:
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_undefined ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf("\n");
+ break;
+ case DW_CFA_same_value:
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_same_value ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf("\n");
+ break;
+ case DW_CFA_register:
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ uval2 =
+ local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_register ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf(" = ");
+ printreg((Dwarf_Signed) uval2, config_data);
+ printf("\n");
+ break;
+ case DW_CFA_remember_state:
+ printf("\t%2u DW_CFA_remember_state\n", loff);
+ break;
+ case DW_CFA_restore_state:
+ printf("\t%2u DW_CFA_restore_state\n", loff);
+ break;
+ case DW_CFA_def_cfa:
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ uval2 =
+ local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_def_cfa ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf(" %llu", (unsigned long long) uval2);
+ printf("\n");
+ break;
+ case DW_CFA_def_cfa_register:
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_def_cfa_register ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf("\n");
+ break;
+ case DW_CFA_def_cfa_offset:
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_def_cfa_offset %llu\n",
+ loff, (unsigned long long) uval);
+ break;
+
+ case DW_CFA_nop:
+ printf("\t%2u DW_CFA_nop\n", loff);
+ break;
+
+ case DW_CFA_def_cfa_expression: /* DWARF3 */
+ {
+ Dwarf_Unsigned block_len =
+ local_dwarf_decode_u_leb128(instp + 1,
+ &uleblen);
+
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf
+ ("\t%2u DW_CFA_def_cfa_expression expr block len %lld\n",
+ loff, (unsigned long long)
+ block_len);
+ dump_block("\t\t", (char *) instp+1,
+ (Dwarf_Signed) block_len);
+ printf("\n");
+ if(verbose) {
+ struct esb_s exprstring;
+ esb_constructor(&exprstring);
+ get_string_from_locs(dbg,
+ instp+1,block_len,&exprstring);
+ printf("\t\t%s\n",esb_get_string(&exprstring));
+ esb_destructor(&exprstring);
+ }
+ instp += block_len;
+ len -= block_len;
+ off += block_len;
+ }
+ break;
+ case DW_CFA_expression: /* DWARF3 */
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ {
+ /* instp is always 1 byte back, so we need +1
+ when we use it. See the final increment
+ of this for loop. */
+ Dwarf_Unsigned block_len =
+ local_dwarf_decode_u_leb128(instp + 1,
+ &uleblen);
+
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf
+ ("\t%2u DW_CFA_expression %llu expr block len %lld\n",
+ loff, (unsigned long long) uval,
+ (unsigned long long)
+ block_len);
+ dump_block("\t\t", (char *) instp+1,
+ (Dwarf_Signed) block_len);
+ printf("\n");
+ if(verbose) {
+ struct esb_s exprstring;
+ esb_constructor(&exprstring);
+ get_string_from_locs(dbg,
+ instp+1,block_len,&exprstring);
+ printf("\t\t%s\n",esb_get_string(&exprstring));
+ esb_destructor(&exprstring);
+ }
+ instp += block_len;
+ len -= block_len;
+ off += block_len;
+ }
+
+ break;
+ case DW_CFA_cfa_offset_extended_sf: /* DWARF3 */
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ {
+ /* instp is always 1 byte back, so we need +1
+ when we use it. See the final increment
+ of this for loop. */
+ Dwarf_Signed sval2 =
+ local_dwarf_decode_s_leb128(instp + 1,
+ &uleblen);
+
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_offset_extended_sf ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf(" %lld", (signed long long)
+ ((sval2) * data_alignment_factor));
+ if (verbose) {
+ printf(" (%lld * %d)", (long long) sval2,
+ (int) data_alignment_factor);
+ }
+ }
+ printf("\n");
+ break;
+ case DW_CFA_def_cfa_sf: /* DWARF3 */
+ /* instp is always 1 byte back, so we need +1
+ when we use it. See the final increment
+ of this for loop. */
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ {
+ Dwarf_Signed sval2 =
+ local_dwarf_decode_s_leb128(instp + 1,
+ &uleblen);
+
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_def_cfa_sf ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf(" %lld", (long long) sval2);
+ printf(" (*data alignment factor=>%lld)",
+ (long long)(sval2*data_alignment_factor));
+ }
+ printf("\n");
+ break;
+ case DW_CFA_def_cfa_offset_sf: /* DWARF3 */
+ {
+ /* instp is always 1 byte back, so we need +1
+ when we use it. See the final increment
+ of this for loop. */
+ Dwarf_Signed sval =
+ local_dwarf_decode_s_leb128(instp + 1,
+ &uleblen);
+
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_def_cfa_offset_sf %lld (*data alignment factor=> %lld)\n",
+ loff, (long long) sval,
+ (long long)(data_alignment_factor*sval));
+
+ }
+ break;
+ case DW_CFA_val_offset: /* DWARF3 */
+ /* instp is always 1 byte back, so we need +1
+ when we use it. See the final increment
+ of this for loop. */
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ {
+ uval2 =
+ local_dwarf_decode_s_leb128(instp + 1,
+ &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_val_offset ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf(" %lld", (unsigned long long)
+ (((Dwarf_Signed) uval2) *
+ data_alignment_factor));
+ if (verbose) {
+ printf(" (%lld * %d)", (long long) uval2,
+ (int) data_alignment_factor);
+ }
+ }
+ printf("\n");
+
+ break;
+ case DW_CFA_val_offset_sf: /* DWARF3 */
+ /* instp is always 1 byte back, so we need +1
+ when we use it. See the final increment
+ of this for loop. */
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ {
+ Dwarf_Signed sval2 =
+ local_dwarf_decode_s_leb128(instp + 1,
+ &uleblen);
+
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf("\t%2u DW_CFA_val_offset_sf ", loff);
+ printreg((Dwarf_Signed) uval, config_data);
+ printf(" %lld", (signed long long)
+ ((sval2) * data_alignment_factor));
+ if (verbose) {
+ printf(" (%lld * %d)", (long long) sval2,
+ (int) data_alignment_factor);
+ }
+ }
+ printf("\n");
+
+ break;
+ case DW_CFA_val_expression: /* DWARF3 */
+ /* instp is always 1 byte back, so we need +1
+ when we use it. See the final increment
+ of this for loop. */
+ uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ {
+ Dwarf_Unsigned block_len =
+ local_dwarf_decode_u_leb128(instp + 1,
+ &uleblen);
+
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+ printf
+ ("\t%2u DW_CFA_val_expression %llu expr block len %lld\n",
+ loff, (unsigned long long) uval,
+ (unsigned long long)
+ block_len);
+ dump_block("\t\t", (char *) instp+1,
+ (Dwarf_Signed) block_len);
+ printf("\n");
+ if(verbose) {
+ struct esb_s exprstring;
+ esb_constructor(&exprstring);
+ get_string_from_locs(dbg,
+ instp+1,block_len,&exprstring);
+ printf("\t\t%s\n",esb_get_string(&exprstring));
+ esb_destructor(&exprstring);
+ }
+ instp += block_len;
+ len -= block_len;
+ off += block_len;
+ }
+
+
+ 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 */
+ printf("\t%2u DW_CFA_GNU_window_save \n", loff);
+ break;
+ }
+#endif
+#ifdef DW_CFA_GNU_negative_offset_extended
+ case DW_CFA_GNU_negative_offset_extended:{
+ printf
+ ("\t%2u DW_CFA_GNU_negative_offset_extended \n",
+ loff);
+ }
+#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;
+
+ /* instp is always 1 byte back, so we need +1
+ when we use it. See the final increment
+ of this for loop. */
+ lreg =
+ local_dwarf_decode_u_leb128(instp + 1,
+ &uleblen);
+ printf
+ ("\t%2u DW_CFA_GNU_args_size arg size: %llu\n",
+ loff, (unsigned long long) lreg);
+ instp += uleblen;
+ len -= uleblen;
+ off += uleblen;
+
+ break;
+ }
+#endif
+
+ default:
+ printf("\t%u Unexpected op 0x%x: \n",
+ loff, (unsigned int) bottom);
+ len = 0;
+ break;
+ }
+ }
+ instp++;
+ len--;
+ off++;
+ }
+}
+
+/* Print our register names for the cases we have a name.
+ Delegate to the configure code to actually do the print.
+*/
+void
+printreg(Dwarf_Signed reg, struct dwconf_s *config_data)
+{
+ print_reg_from_config_data(reg, config_data);
+}
+
+
+/*
+ Actually does the printing of a rule in the table.
+ This may print something or may print nothing!
+*/
+
+static void
+print_one_frame_reg_col(Dwarf_Debug dbg,
+ Dwarf_Unsigned rule_id,
+ Dwarf_Small value_type,
+ Dwarf_Unsigned reg_used,
+ struct dwconf_s *config_data,
+ Dwarf_Signed offset_relevant,
+ Dwarf_Signed offset,
+ Dwarf_Ptr block_ptr)
+{
+ char *type_title = "";
+ int print_type_title = 1;
+
+ if (config_data->cf_interface_number == 2)
+ print_type_title = 0;
+
+ switch (value_type) {
+ case DW_EXPR_OFFSET:
+ type_title = "off";
+ goto preg2;
+ case DW_EXPR_VAL_OFFSET:
+ type_title = "valoff";
+ preg2:
+ if (reg_used == config_data->cf_initial_rule_value) {
+ break;
+ }
+ if (print_type_title)
+ printf("<%s ", type_title);
+ printreg((Dwarf_Signed) rule_id, config_data);
+ printf("=");
+ if (offset_relevant == 0) {
+ printreg((Dwarf_Signed) reg_used, config_data);
+ printf(" ");
+ } else {
+ printf("%02lld", offset);
+ printf("(");
+ printreg((Dwarf_Signed) reg_used, config_data);
+ printf(") ");
+ }
+ if (print_type_title)
+ printf("%s", "> ");
+ break;
+ case DW_EXPR_EXPRESSION:
+ type_title = "expr";
+ goto pexp2;
+ case DW_EXPR_VAL_EXPRESSION:
+ type_title = "valexpr";
+ pexp2:
+ if (print_type_title)
+ printf("<%s ", type_title);
+ printreg((Dwarf_Signed) rule_id, config_data);
+ printf("=");
+ printf("expr-block-len=%lld", (long long) offset);
+ if (print_type_title)
+ printf("%s", "> ");
+ if (verbose) {
+ char pref[40];
+
+ strcpy(pref, "<");
+ strcat(pref, type_title);
+ strcat(pref, "bytes:");
+ dump_block(pref, block_ptr, offset);
+ printf("%s", "> ");
+ if(verbose) {
+ struct esb_s exprstring;
+ esb_constructor(&exprstring);
+ get_string_from_locs(dbg,
+ block_ptr,offset,&exprstring);
+ printf("<expr:%s>",esb_get_string(&exprstring));
+ esb_destructor(&exprstring);
+ }
+ }
+ break;
+ default:
+ printf("Internal error in libdwarf, value type %d\n",
+ value_type);
+ exit(1);
+ }
+ return;
+}