Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Commits on Source (3)
......@@ -28,6 +28,7 @@ class EhWriterImpl_t : public EhWriter_t
bool canExtend(const EhProgramListingManip_t &other);
void extend(const uint64_t inc_amt, const EhProgramListingManip_t &other);
bool isAdvanceDirective(const std::string &s) const;
std::string getPrintableString(const std::string &s) const;
private:
int getMergeIndex(const EhProgramListingManip_t &other);
......
/*
Copyright 2017-2018 University of Virginia
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef _DWARF2_H
#define _DWARF2_H 1
/* This file is derived from the DWARF specification (a public document)
Revision 2.0.0 (July 27, 1993) developed by the UNIX International
Programming Languages Special Interest Group (UI/PLSIG) and distributed
by UNIX International. Copies of this specification are available from
UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054. */
enum dwarf_tag
{
DW_TAG_padding = 0x00,
DW_TAG_array_type = 0x01,
DW_TAG_class_type = 0x02,
DW_TAG_entry_point = 0x03,
DW_TAG_enumeration_type = 0x04,
DW_TAG_formal_parameter = 0x05,
DW_TAG_imported_declaration = 0x08,
DW_TAG_label = 0x0a,
DW_TAG_lexical_block = 0x0b,
DW_TAG_member = 0x0d,
DW_TAG_pointer_type = 0x0f,
DW_TAG_reference_type = 0x10,
DW_TAG_compile_unit = 0x11,
DW_TAG_string_type = 0x12,
DW_TAG_structure_type = 0x13,
DW_TAG_subroutine_type = 0x15,
DW_TAG_typedef = 0x16,
DW_TAG_union_type = 0x17,
DW_TAG_unspecified_parameters = 0x18,
DW_TAG_variant = 0x19,
DW_TAG_common_block = 0x1a,
DW_TAG_common_inclusion = 0x1b,
DW_TAG_inheritance = 0x1c,
DW_TAG_inlined_subroutine = 0x1d,
DW_TAG_module = 0x1e,
DW_TAG_ptr_to_member_type = 0x1f,
DW_TAG_set_type = 0x20,
DW_TAG_subrange_type = 0x21,
DW_TAG_with_stmt = 0x22,
DW_TAG_access_declaration = 0x23,
DW_TAG_base_type = 0x24,
DW_TAG_catch_block = 0x25,
DW_TAG_const_type = 0x26,
DW_TAG_constant = 0x27,
DW_TAG_enumerator = 0x28,
DW_TAG_file_type = 0x29,
DW_TAG_friend = 0x2a,
DW_TAG_namelist = 0x2b,
DW_TAG_namelist_item = 0x2c,
DW_TAG_packed_type = 0x2d,
DW_TAG_subprogram = 0x2e,
DW_TAG_template_type_param = 0x2f,
DW_TAG_template_value_param = 0x30,
DW_TAG_thrown_type = 0x31,
DW_TAG_try_block = 0x32,
DW_TAG_variant_part = 0x33,
DW_TAG_variable = 0x34,
DW_TAG_volatile_type = 0x35,
/* SGI/MIPS Extensions */
DW_TAG_MIPS_loop = 0x4081,
/* GNU extensions */
DW_TAG_format_label = 0x4101, /* for FORTRAN 77 and Fortran 90 */
DW_TAG_function_template = 0x4102, /* for C++ */
DW_TAG_class_template = 0x4103, /* for C++ */
DW_TAG_GNU_BINCL = 0x4104,
DW_TAG_GNU_EINCL = 0x4105
};
#define DW_TAG_lo_user 0x4080
#define DW_TAG_hi_user 0xffff
/* flag that tells whether entry has a child or not */
#define DW_children_no 0
#define DW_children_yes 1
/* Form names and codes. */
enum dwarf_form
{
DW_FORM_addr = 0x01,
DW_FORM_block2 = 0x03,
DW_FORM_block4 = 0x04,
DW_FORM_data2 = 0x05,
DW_FORM_data4 = 0x06,
DW_FORM_data8 = 0x07,
DW_FORM_string = 0x08,
DW_FORM_block = 0x09,
DW_FORM_block1 = 0x0a,
DW_FORM_data1 = 0x0b,
DW_FORM_flag = 0x0c,
DW_FORM_sdata = 0x0d,
DW_FORM_strp = 0x0e,
DW_FORM_udata = 0x0f,
DW_FORM_ref_addr = 0x10,
DW_FORM_ref1 = 0x11,
DW_FORM_ref2 = 0x12,
DW_FORM_ref4 = 0x13,
DW_FORM_ref8 = 0x14,
DW_FORM_ref_udata = 0x15,
DW_FORM_indirect = 0x16
};
/* Attribute names and codes. */
enum dwarf_attribute
{
DW_AT_sibling = 0x01,
DW_AT_location = 0x02,
DW_AT_name = 0x03,
DW_AT_ordering = 0x09,
DW_AT_subscr_data = 0x0a,
DW_AT_byte_size = 0x0b,
DW_AT_bit_offset = 0x0c,
DW_AT_bit_size = 0x0d,
DW_AT_element_list = 0x0f,
DW_AT_stmt_list = 0x10,
DW_AT_low_pc = 0x11,
DW_AT_high_pc = 0x12,
DW_AT_language = 0x13,
DW_AT_member = 0x14,
DW_AT_discr = 0x15,
DW_AT_discr_value = 0x16,
DW_AT_visibility = 0x17,
DW_AT_import = 0x18,
DW_AT_string_length = 0x19,
DW_AT_common_reference = 0x1a,
DW_AT_comp_dir = 0x1b,
DW_AT_const_value = 0x1c,
DW_AT_containing_type = 0x1d,
DW_AT_default_value = 0x1e,
DW_AT_inline = 0x20,
DW_AT_is_optional = 0x21,
DW_AT_lower_bound = 0x22,
DW_AT_producer = 0x25,
DW_AT_prototyped = 0x27,
DW_AT_return_addr = 0x2a,
DW_AT_start_scope = 0x2c,
DW_AT_stride_size = 0x2e,
DW_AT_upper_bound = 0x2f,
DW_AT_abstract_origin = 0x31,
DW_AT_accessibility = 0x32,
DW_AT_address_class = 0x33,
DW_AT_artificial = 0x34,
DW_AT_base_types = 0x35,
DW_AT_calling_convention = 0x36,
DW_AT_count = 0x37,
DW_AT_data_member_location = 0x38,
DW_AT_decl_column = 0x39,
DW_AT_decl_file = 0x3a,
DW_AT_decl_line = 0x3b,
DW_AT_declaration = 0x3c,
DW_AT_discr_list = 0x3d,
DW_AT_encoding = 0x3e,
DW_AT_external = 0x3f,
DW_AT_frame_base = 0x40,
DW_AT_friend = 0x41,
DW_AT_identifier_case = 0x42,
DW_AT_macro_info = 0x43,
DW_AT_namelist_items = 0x44,
DW_AT_priority = 0x45,
DW_AT_segment = 0x46,
DW_AT_specification = 0x47,
DW_AT_static_link = 0x48,
DW_AT_type = 0x49,
DW_AT_use_location = 0x4a,
DW_AT_variable_parameter = 0x4b,
DW_AT_virtuality = 0x4c,
DW_AT_vtable_elem_location = 0x4d,
/* SGI/MIPS Extensions */
DW_AT_MIPS_fde = 0x2001,
DW_AT_MIPS_loop_begin = 0x2002,
DW_AT_MIPS_tail_loop_begin = 0x2003,
DW_AT_MIPS_epilog_begin = 0x2004,
DW_AT_MIPS_loop_unroll_factor = 0x2005,
DW_AT_MIPS_software_pipeline_depth = 0x2006,
DW_AT_MIPS_linkage_name = 0x2007,
DW_AT_MIPS_stride = 0x2008,
DW_AT_MIPS_abstract_name = 0x2009,
DW_AT_MIPS_clone_origin = 0x200a,
DW_AT_MIPS_has_inlines = 0x200b,
/* GNU extensions. */
DW_AT_sf_names = 0x2101,
DW_AT_src_info = 0x2102,
DW_AT_mac_info = 0x2103,
DW_AT_src_coords = 0x2104,
DW_AT_body_begin = 0x2105,
DW_AT_body_end = 0x2106
};
#define DW_AT_lo_user 0x2000 /* implementation-defined range start */
#define DW_AT_hi_user 0x3ff0 /* implementation-defined range end */
/* Location atom names and codes. */
enum dwarf_location_atom
{
DW_OP_addr = 0x03,
DW_OP_deref = 0x06,
DW_OP_const1u = 0x08,
DW_OP_const1s = 0x09,
DW_OP_const2u = 0x0a,
DW_OP_const2s = 0x0b,
DW_OP_const4u = 0x0c,
DW_OP_const4s = 0x0d,
DW_OP_const8u = 0x0e,
DW_OP_const8s = 0x0f,
DW_OP_constu = 0x10,
DW_OP_consts = 0x11,
DW_OP_dup = 0x12,
DW_OP_drop = 0x13,
DW_OP_over = 0x14,
DW_OP_pick = 0x15,
DW_OP_swap = 0x16,
DW_OP_rot = 0x17,
DW_OP_xderef = 0x18,
DW_OP_abs = 0x19,
DW_OP_and = 0x1a,
DW_OP_div = 0x1b,
DW_OP_minus = 0x1c,
DW_OP_mod = 0x1d,
DW_OP_mul = 0x1e,
DW_OP_neg = 0x1f,
DW_OP_not = 0x20,
DW_OP_or = 0x21,
DW_OP_plus = 0x22,
DW_OP_plus_uconst = 0x23,
DW_OP_shl = 0x24,
DW_OP_shr = 0x25,
DW_OP_shra = 0x26,
DW_OP_xor = 0x27,
DW_OP_bra = 0x28,
DW_OP_eq = 0x29,
DW_OP_ge = 0x2a,
DW_OP_gt = 0x2b,
DW_OP_le = 0x2c,
DW_OP_lt = 0x2d,
DW_OP_ne = 0x2e,
DW_OP_skip = 0x2f,
DW_OP_lit0 = 0x30,
DW_OP_lit1 = 0x31,
DW_OP_lit2 = 0x32,
DW_OP_lit3 = 0x33,
DW_OP_lit4 = 0x34,
DW_OP_lit5 = 0x35,
DW_OP_lit6 = 0x36,
DW_OP_lit7 = 0x37,
DW_OP_lit8 = 0x38,
DW_OP_lit9 = 0x39,
DW_OP_lit10 = 0x3a,
DW_OP_lit11 = 0x3b,
DW_OP_lit12 = 0x3c,
DW_OP_lit13 = 0x3d,
DW_OP_lit14 = 0x3e,
DW_OP_lit15 = 0x3f,
DW_OP_lit16 = 0x40,
DW_OP_lit17 = 0x41,
DW_OP_lit18 = 0x42,
DW_OP_lit19 = 0x43,
DW_OP_lit20 = 0x44,
DW_OP_lit21 = 0x45,
DW_OP_lit22 = 0x46,
DW_OP_lit23 = 0x47,
DW_OP_lit24 = 0x48,
DW_OP_lit25 = 0x49,
DW_OP_lit26 = 0x4a,
DW_OP_lit27 = 0x4b,
DW_OP_lit28 = 0x4c,
DW_OP_lit29 = 0x4d,
DW_OP_lit30 = 0x4e,
DW_OP_lit31 = 0x4f,
DW_OP_reg0 = 0x50,
DW_OP_reg1 = 0x51,
DW_OP_reg2 = 0x52,
DW_OP_reg3 = 0x53,
DW_OP_reg4 = 0x54,
DW_OP_reg5 = 0x55,
DW_OP_reg6 = 0x56,
DW_OP_reg7 = 0x57,
DW_OP_reg8 = 0x58,
DW_OP_reg9 = 0x59,
DW_OP_reg10 = 0x5a,
DW_OP_reg11 = 0x5b,
DW_OP_reg12 = 0x5c,
DW_OP_reg13 = 0x5d,
DW_OP_reg14 = 0x5e,
DW_OP_reg15 = 0x5f,
DW_OP_reg16 = 0x60,
DW_OP_reg17 = 0x61,
DW_OP_reg18 = 0x62,
DW_OP_reg19 = 0x63,
DW_OP_reg20 = 0x64,
DW_OP_reg21 = 0x65,
DW_OP_reg22 = 0x66,
DW_OP_reg23 = 0x67,
DW_OP_reg24 = 0x68,
DW_OP_reg25 = 0x69,
DW_OP_reg26 = 0x6a,
DW_OP_reg27 = 0x6b,
DW_OP_reg28 = 0x6c,
DW_OP_reg29 = 0x6d,
DW_OP_reg30 = 0x6e,
DW_OP_reg31 = 0x6f,
DW_OP_breg0 = 0x70,
DW_OP_breg1 = 0x71,
DW_OP_breg2 = 0x72,
DW_OP_breg3 = 0x73,
DW_OP_breg4 = 0x74,
DW_OP_breg5 = 0x75,
DW_OP_breg6 = 0x76,
DW_OP_breg7 = 0x77,
DW_OP_breg8 = 0x78,
DW_OP_breg9 = 0x79,
DW_OP_breg10 = 0x7a,
DW_OP_breg11 = 0x7b,
DW_OP_breg12 = 0x7c,
DW_OP_breg13 = 0x7d,
DW_OP_breg14 = 0x7e,
DW_OP_breg15 = 0x7f,
DW_OP_breg16 = 0x80,
DW_OP_breg17 = 0x81,
DW_OP_breg18 = 0x82,
DW_OP_breg19 = 0x83,
DW_OP_breg20 = 0x84,
DW_OP_breg21 = 0x85,
DW_OP_breg22 = 0x86,
DW_OP_breg23 = 0x87,
DW_OP_breg24 = 0x88,
DW_OP_breg25 = 0x89,
DW_OP_breg26 = 0x8a,
DW_OP_breg27 = 0x8b,
DW_OP_breg28 = 0x8c,
DW_OP_breg29 = 0x8d,
DW_OP_breg30 = 0x8e,
DW_OP_breg31 = 0x8f,
DW_OP_regx = 0x90,
DW_OP_fbreg = 0x91,
DW_OP_bregx = 0x92,
DW_OP_piece = 0x93,
DW_OP_deref_size = 0x94,
DW_OP_xderef_size = 0x95,
DW_OP_nop = 0x96
};
#define DW_OP_lo_user 0x80 /* implementation-defined range start */
#define DW_OP_hi_user 0xff /* implementation-defined range end */
/* Type encodings. */
enum dwarf_type
{
DW_ATE_void = 0x0,
DW_ATE_address = 0x1,
DW_ATE_boolean = 0x2,
DW_ATE_complex_float = 0x3,
DW_ATE_float = 0x4,
DW_ATE_signed = 0x5,
DW_ATE_signed_char = 0x6,
DW_ATE_unsigned = 0x7,
DW_ATE_unsigned_char = 0x8
};
#define DW_ATE_lo_user 0x80
#define DW_ATE_hi_user 0xff
/* Array ordering names and codes. */
enum dwarf_array_dim_ordering
{
DW_ORD_row_major = 0,
DW_ORD_col_major = 1
};
/* access attribute */
enum dwarf_access_attribute
{
DW_ACCESS_public = 1,
DW_ACCESS_protected = 2,
DW_ACCESS_private = 3
};
/* visibility */
enum dwarf_visibility_attribute
{
DW_VIS_local = 1,
DW_VIS_exported = 2,
DW_VIS_qualified = 3
};
/* virtuality */
enum dwarf_virtuality_attribute
{
DW_VIRTUALITY_none = 0,
DW_VIRTUALITY_virtual = 1,
DW_VIRTUALITY_pure_virtual = 2
};
/* case sensitivity */
enum dwarf_id_case
{
DW_ID_case_sensitive = 0,
DW_ID_up_case = 1,
DW_ID_down_case = 2,
DW_ID_case_insensitive = 3
};
/* calling convention */
enum dwarf_calling_convention
{
DW_CC_normal = 0x1,
DW_CC_program = 0x2,
DW_CC_nocall = 0x3
};
#define DW_CC_lo_user 0x40
#define DW_CC_hi_user 0xff
/* inline attribute */
enum dwarf_inline_attribute
{
DW_INL_not_inlined = 0,
DW_INL_inlined = 1,
DW_INL_declared_not_inlined = 2,
DW_INL_declared_inlined = 3
};
/* discriminant lists */
enum dwarf_discrim_list
{
DW_DSC_label = 0,
DW_DSC_range = 1
};
/* line number opcodes */
enum dwarf_line_number_ops
{
DW_LNS_extended_op = 0,
DW_LNS_copy = 1,
DW_LNS_advance_pc = 2,
DW_LNS_advance_line = 3,
DW_LNS_set_file = 4,
DW_LNS_set_column = 5,
DW_LNS_negate_stmt = 6,
DW_LNS_set_basic_block = 7,
DW_LNS_const_add_pc = 8,
DW_LNS_fixed_advance_pc = 9
};
/* line number extended opcodes */
enum dwarf_line_number_x_ops
{
DW_LNE_end_sequence = 1,
DW_LNE_set_address = 2,
DW_LNE_define_file = 3
};
/* call frame information */
enum dwarf_call_frame_info
{
DW_CFA_advance_loc = 0x40,
DW_CFA_offset = 0x80,
DW_CFA_restore = 0xc0,
DW_CFA_nop = 0x00,
DW_CFA_set_loc = 0x01,
DW_CFA_advance_loc1 = 0x02,
DW_CFA_advance_loc2 = 0x03,
DW_CFA_advance_loc4 = 0x04,
DW_CFA_offset_extended = 0x05,
DW_CFA_restore_extended = 0x06,
DW_CFA_undefined = 0x07,
DW_CFA_same_value = 0x08,
DW_CFA_register = 0x09,
DW_CFA_remember_state = 0x0a,
DW_CFA_restore_state = 0x0b,
DW_CFA_def_cfa = 0x0c,
DW_CFA_def_cfa_register = 0x0d,
DW_CFA_def_cfa_offset = 0x0e,
DW_CFA_def_cfa_expression = 0x0f,
DW_CFA_expression = 0x10,
/* Dwarf 2.1 */
DW_CFA_offset_extended_sf = 0x11,
DW_CFA_def_cfa_sf = 0x12,
DW_CFA_def_cfa_offset_sf = 0x13,
/* added by jdh for newer version of dwarf? libc uses this in ubuntu 14.04 */
DW_CFA_val_offset = 0x14,
DW_CFA_val_offset_sf = 0x15,
DW_CFA_val_expression = 0x16,
/* SGI/MIPS specific */
DW_CFA_MIPS_advance_loc8 = 0x1d,
/* GNU extensions */
DW_CFA_GNU_window_save = 0x2d,
DW_CFA_GNU_args_size = 0x2e,
DW_CFA_GNU_negative_offset_extended = 0x2f
};
#define DW_CIE_ID 0xffffffff
#define DW_CIE_VERSION 1
#define DW_CFA_extended 0
#define DW_CFA_low_user 0x1c
#define DW_CFA_high_user 0x3f
#define DW_CHILDREN_no 0x00
#define DW_CHILDREN_yes 0x01
#define DW_ADDR_none 0
/* Source language names and codes. */
enum dwarf_source_language
{
DW_LANG_C89 = 0x0001,
DW_LANG_C = 0x0002,
DW_LANG_Ada83 = 0x0003,
DW_LANG_C_plus_plus = 0x0004,
DW_LANG_Cobol74 = 0x0005,
DW_LANG_Cobol85 = 0x0006,
DW_LANG_Fortran77 = 0x0007,
DW_LANG_Fortran90 = 0x0008,
DW_LANG_Pascal83 = 0x0009,
DW_LANG_Modula2 = 0x000a,
DW_LANG_Java = 0x000b,
DW_LANG_Mips_Assembler = 0x8001
};
#define DW_LANG_lo_user 0x8000 /* implementation-defined range start */
#define DW_LANG_hi_user 0xffff /* implementation-defined range start */
/* Names and codes for macro information. */
enum dwarf_macinfo_record_type
{
DW_MACINFO_define = 1,
DW_MACINFO_undef = 2,
DW_MACINFO_start_file = 3,
DW_MACINFO_end_file = 4,
DW_MACINFO_vendor_ext = 255
};
/* @@@ For use with GNU frame unwind information. */
#define DW_EH_PE_absptr 0x00
#define DW_EH_PE_omit 0xff
#define DW_EH_PE_uleb128 0x01
#define DW_EH_PE_udata2 0x02
#define DW_EH_PE_udata4 0x03
#define DW_EH_PE_udata8 0x04
#define DW_EH_PE_sleb128 0x09
#define DW_EH_PE_sdata2 0x0A
#define DW_EH_PE_sdata4 0x0B
#define DW_EH_PE_sdata8 0x0C
#define DW_EH_PE_signed 0x08
#define DW_EH_PE_pcrel 0x10
#define DW_EH_PE_textrel 0x20
#define DW_EH_PE_datarel 0x30
#define DW_EH_PE_funcrel 0x40
#define DW_EH_PE_aligned 0x50
#define DW_EH_PE_indirect 0x80
#endif /* dwarf2.h */
......@@ -56,7 +56,7 @@ libpath='''
if sysname=="SunOS":
myenv.Append(LINKFLAGS=" -xldscope=global ") # export all symbols
else:
myenv.Append(CCFLAGS=" -Wall -Werror")
myenv.Append(CCFLAGS=" -Wall -Werror -fmax-errors=2")
myenv.Append(LINKFLAGS=" -Wl,-E ") # export all symbols
......
......@@ -15,10 +15,11 @@
#include <fstream>
#include <elf.h>
#include <zipr_dwarf2.hpp>
#include "elfio/elfio.hpp"
#include "elfio/elfio_dump.hpp"
#include "targ-config.h"
//#include "beaengine/BeaEngine.h"
using namespace libIRDB;
using namespace std;
......@@ -322,6 +323,301 @@ bool EhWriterImpl_t<ptrsize>::EhProgramListingManip_t::isAdvanceDirective(const
}
// see https://en.wikipedia.org/wiki/LEB128
template <int ptrsize>
static bool read_uleb128
( uint64_t &result,
uint32_t& position,
const uint8_t* const data,
const uint32_t max)
{
result = 0;
auto shift = 0;
while( position < max )
{
auto byte = data[position];
position++;
result |= ( ( byte & 0x7f ) << shift);
if ( ( byte & 0x80) == 0)
break;
shift += 7;
}
return ( position > max );
}
// see https://en.wikipedia.org/wiki/LEB128
template <int ptrsize>
static bool read_sleb128 (
int64_t &result,
uint32_t & position,
const uint8_t* const data,
const uint32_t max)
{
result = 0;
auto shift = 0;
auto size = 64; // number of bits in signed integer;
auto byte=uint8_t(0);
do
{
byte = data [position];
position++;
result |= ((byte & 0x7f)<< shift);
shift += 7;
} while( (byte & 0x80) != 0);
/* sign bit of byte is second high order bit (0x40) */
if ((shift < size) && ( (byte & 0x40) !=0 /* sign bit of byte is set */))
/* sign extend */
result |= - (1 << shift);
return ( position > max );
}
template <int ptrsize>
static void print_uleb_operand(
stringstream &sout,
uint32_t pos,
const uint8_t* const data,
const uint32_t max)
{
auto uleb=uint64_t(0xdeadbeef);
read_uleb128<ptrsize>(uleb, pos, data, max);
sout<<" "<<dec<<uleb;
}
template <int ptrsize>
static void print_sleb_operand(
stringstream &sout,
uint32_t pos,
const uint8_t* const data,
const uint32_t max)
{
auto leb=int64_t(0xdeadbeef);
read_sleb128<ptrsize>(leb, pos, data, max);
sout<<" "<<dec<<leb;
}
template <int ptrsize>
string EhWriterImpl_t<ptrsize>::EhProgramListingManip_t::getPrintableString(const string &s) const
{
stringstream sout;
// make sure uint8_t is an unsigned char.
static_assert(std::is_same<unsigned char, uint8_t>::value, "uint8_t is not unsigned char");
auto data=s;
auto opcode=(uint8_t)data[0];
auto opcode_upper2=(uint8_t)(opcode >> 6);
auto opcode_lower6=(uint8_t)(opcode & (0x3f));
auto pos=uint32_t(1);
auto max=data.size();
switch(opcode_upper2)
{
case 1:
{
// case DW_CFA_advance_loc:
sout<<" cfa_advance_loc "<<dec<<+opcode_lower6<<" * caf";
break;
}
case 2:
{
uint64_t uleb=0;
sout<<" cfa_offset ";
if(read_uleb128<ptrsize>(uleb, pos, (const uint8_t* const)data.data(), max))
break;
// case DW_CFA_offset:
sout <<dec<<uleb;
break;
}
case 3:
{
// case DW_CFA_restore (register #):
sout<<" cfa_restore";
break;
}
case 0:
{
switch(opcode_lower6)
{
case DW_CFA_nop:
sout<<" nop" ;
break;
case DW_CFA_remember_state:
sout<<" remember_state" ;
break;
case DW_CFA_restore_state:
sout<<" restore_state" ;
break;
// takes single uleb128
case DW_CFA_undefined:
sout<<" undefined" ;
print_uleb_operand<ptrsize>(sout,pos,(const uint8_t* const)data.data(),max);
break;
case DW_CFA_same_value:
sout<<" same_value ";
print_uleb_operand<ptrsize>(sout,pos,(const uint8_t* const)data.data(),max);
break;
case DW_CFA_restore_extended:
sout<<" restore_extended ";
print_uleb_operand<ptrsize>(sout,pos,(const uint8_t* const)data.data(),max);
break;
case DW_CFA_def_cfa_register:
sout<<" def_cfa_register ";
print_uleb_operand<ptrsize>(sout,pos,(const uint8_t* const)data.data(),max);
break;
case DW_CFA_GNU_args_size:
sout<<" GNU_arg_size ";
print_uleb_operand<ptrsize>(sout,pos,(const uint8_t* const)data.data(),max);
break;
case DW_CFA_def_cfa_offset:
sout<<" def_cfa_offset ";
print_uleb_operand<ptrsize>(sout,pos,(const uint8_t* const)data.data(),max);
break;
case DW_CFA_set_loc:
{
auto arg=uintptr_t(0xDEADBEEF);
switch(ptrsize)
{
case 4:
arg=*(uint32_t*)&data.data()[pos]; break;
case 8:
arg=*(uint64_t*)&data.data()[pos]; break;
default:
assert(0);
}
sout<<" set_loc "<<hex<<arg;
break;
}
case DW_CFA_advance_loc1:
{
auto loc=*(uint8_t*)(&data.data()[pos]);
sout<<" advance_loc1 "<<+loc<<" * caf " ;
break;
}
case DW_CFA_advance_loc2:
{
auto loc=*(uint16_t*)(&data.data()[pos]);
sout<<" advance_loc2 "<<+loc<<" * caf " ;
break;
}
case DW_CFA_advance_loc4:
{
auto loc=*(uint32_t*)(&data.data()[pos]);
sout<<" advance_loc4 "<<+loc<<" * caf " ;
break;
}
case DW_CFA_offset_extended:
sout<<" offset_extended ";
print_uleb_operand<ptrsize>(sout,pos,(const uint8_t* const)data.data(),max);
print_uleb_operand<ptrsize>(sout,pos,(const uint8_t* const)data.data(),max);
break;
case DW_CFA_register:
sout<<" register ";
print_uleb_operand<ptrsize>(sout,pos,(const uint8_t* const)data.data(),max);
print_uleb_operand<ptrsize>(sout,pos,(const uint8_t* const)data.data(),max);
break;
case DW_CFA_def_cfa:
sout<<" def_cfa ";
print_uleb_operand<ptrsize>(sout,pos,(const uint8_t* const)data.data(),max);
print_uleb_operand<ptrsize>(sout,pos,(const uint8_t* const)data.data(),max);
break;
case DW_CFA_def_cfa_sf:
sout<<" def_cfa_sf ";
print_uleb_operand<ptrsize>(sout,pos,(const uint8_t* const)data.data(),max);
print_sleb_operand<ptrsize>(sout,pos,(const uint8_t* const)data.data(),max);
break;
case DW_CFA_def_cfa_expression:
{
auto uleb=uint64_t(0);
sout<<" def_cfa_expression ";
if(read_uleb128<ptrsize>(uleb, pos, (const uint8_t* const)data.data(), max))
break;
sout <<dec<<uleb;
pos+=uleb; // doing this old school for now, as we aren't printing the expression.
sout <<" (not printing expression)";
break;
}
case DW_CFA_expression:
{
auto uleb1=uint64_t(0);
auto uleb2=uint64_t(0);
sout<<" expression ";
if(read_uleb128<ptrsize>(uleb1, pos, (const uint8_t* const)data.data(), max))
break;
if(read_uleb128<ptrsize>(uleb2, pos, (const uint8_t* const)data.data(), max))
break;
sout<<dec<<uleb1<<" "<<uleb2;
pos+=uleb2;
break;
}
case DW_CFA_val_expression:
{
auto uleb1=uint64_t(0);
auto uleb2=uint64_t(0);
sout<<" val_expression ";
if(read_uleb128<ptrsize>(uleb1, pos, (const uint8_t* const)data.data(), max))
break;
if(read_uleb128<ptrsize>(uleb2, pos, (const uint8_t* const)data.data(), max))
break;
sout <<dec<<uleb1<<" "<<uleb2;
pos+=uleb2;
break;
}
case DW_CFA_def_cfa_offset_sf:
{
auto leb=int64_t(0);
sout<<" def_cfa_offset_sf ";
if(read_sleb128<ptrsize>(leb, pos, (const uint8_t* const)data.data(), max))
break;
sout <<dec<<leb;
break;
}
case DW_CFA_offset_extended_sf:
{
auto uleb1=uint64_t(0);
auto sleb2=int64_t(0);
sout<<" offset_extended_sf ";
if(read_uleb128<ptrsize>(uleb1, pos, (const uint8_t* const)data.data(), max))
break;
if(read_sleb128<ptrsize>(sleb2, pos, (const uint8_t* const)data.data(), max))
break;
sout <<dec<<uleb1<<" "<<sleb2;
break;
}
/* SGI/MIPS specific */
case DW_CFA_MIPS_advance_loc8:
/* GNU extensions */
case DW_CFA_GNU_window_save:
case DW_CFA_GNU_negative_offset_extended:
default:
sout<<"Unhandled opcode cannot print. opcode="<<opcode;
}
break;
}
default:
assert(0);
}
return sout.str();
}
template <int ptrsize>
EhWriterImpl_t<ptrsize>::FDErepresentation_t::LSDArepresentation_t::LSDArepresentation_t(Instruction_t* insn)
// if there are call sites, use the call site encoding. if not, set to omit for initializer.
......@@ -613,7 +909,7 @@ void EhWriterImpl_t<ptrsize>::GenerateEhOutput()
first=false;
out<<"0x"<<hex<<setfill('0')<<setw(2)<<((int)c&0xff);
}
out << endl;
out << " # " << p.getPrintableString(s)<<endl;
}
out.flags(flags); // restore flags
};
......@@ -709,30 +1005,30 @@ void EhWriterImpl_t<ptrsize>::GenerateEhOutput()
const auto cs_end_addr=zipr_obj.GetLocationMap()->at(cs.cs_insn_start)+cs.cs_insn_start->GetDataBits().size();
const auto cs_len=cs_end_addr-cs_start_addr;
out<<"LSDA"<<dec<<lsda_num<<"_cs_tab_entry"<<cs_num<<"_start:"<<endl;
out<<" # 1) start of call site relative to FDE start addr"<<endl;
out<<" .uleb128 0x"<<hex<<cs_start_addr<<" - 0x"<<hex<<fde->start_addr<<endl;
out<<" # 2) length of call site"<<endl;
out<<" .uleb128 "<<dec<<cs_len<<endl;
out<<" # 1) start of call site relative to FDE start addr (call site encoding)"<<endl;
out<<" .sleb128 0x"<<hex<<cs_start_addr<<" - 0x"<<hex<<fde->start_addr<<endl;
out<<" # 2) length of call site (call site encoding)"<<endl;
out<<" .sleb128 "<<dec<<cs_len<<endl;
if(cs.landing_pad)
{
const auto lp_addr=zipr_obj.GetLocationMap()->at(cs.landing_pad);
out<<" # 3) the landing pad, or 0 if none exists."<<endl;
out<<" .uleb128 0x"<<hex<<lp_addr<<" - 0x"<<hex<<landing_pad_base<<endl;
out<<" # 3) the landing pad, or 0 if none exists. (call site encoding)"<<endl;
out<<" .sleb128 0x"<<hex<<lp_addr<<" - 0x"<<hex<<landing_pad_base<<endl;
}
else
{
out<<" # 3) the landing pad, or 0 if none exists."<<endl;
out<<" .uleb128 0"<<endl;
out<<" # 3) the landing pad, or 0 if none exists. (call site encoding)"<<endl;
out<<" .sleb128 0"<<endl;
}
if(cs.actions.size() > 0 )
{
out<<" # 4) index into action table + 1 -- 0 indicates unwind only"<<endl;
out<<" .uleb128 1 + LSDA"<<dec<<lsda_num<<"_act"
out<<" # 4) index into action table + 1 -- 0 indicates unwind only (call site encoding)"<<endl;
out<<" .sleb128 1 + LSDA"<<dec<<lsda_num<<"_act"
<<cs.action_table_index<<"_start_entry0 - LSDA"<<dec<<lsda_num<<"_action_tab_start"<<endl;
}
else
{
out<<" # 4) index into action table + 1 -- 0 indicates unwind only"<<endl;
out<<" # 4) index into action table + 1 -- 0 indicates unwind only (always uleb)"<<endl;
out<<" .uleb128 0 # no actions!" << endl;
}
out<<"LSDA"<<dec<<lsda_num<<"_cs_tab_entry"<<cs_num<<"_end:"<<endl;
......@@ -773,7 +1069,7 @@ void EhWriterImpl_t<ptrsize>::GenerateEhOutput()
out<<"LSDA"<<dec<<lsda_num<<"_tt_ptr_end:"<<endl;
out<<""<<endl;
out<<" # 5) call site table encoding"<<endl;
out<<" .byte 0x1 # DW_EH_PE_uleb128 "<<endl;
out<<" .byte 0x9 # DW_EH_PE_sleb128 "<<endl;
out<<""<<endl;
out<<" # 6) the length of the call site table"<<endl;
out<<" .uleb128 LSDA"<<dec<<lsda_num<<"_cs_tab_end-LSDA"<<dec<<lsda_num<<"_cs_tab_start"<<endl;
......
......@@ -1233,7 +1233,7 @@ Instruction_t* ZiprImpl_t::Emit68Sled(RangeAddress_t addr, Sled_t sled, Instruct
if(m_firp->GetArchitectureBitWidth()!=64)
{
decoration="dword";
string stack_reg="esp";
stack_reg="esp";
}
const int stack_push_size=m_firp->GetArchitectureBitWidth()/8;
......