From b03983b90df31ea3688601b5d7bc56cee76eeca0 Mon Sep 17 00:00:00 2001 From: Jason Hiser <jdhiser@gmail.com> Date: Mon, 30 Jul 2018 19:46:31 +0000 Subject: [PATCH] added libehp, refactored split-eh-frame into standalone class that uses libehp. Former-commit-id: 86c1df8c8e05024a5378d41eb4757bee1361d088 --- SConstruct | 6 +- libIRDB/test/SConscript | 3 +- libIRDB/test/dwarf2.h | 595 ---------- libIRDB/test/eh_frame.hpp | 402 ------- libIRDB/test/fill_in_cfg.cpp | 4 +- libIRDB/test/split_eh_frame.cpp | 1810 +++---------------------------- libIRDB/test/split_eh_frame.hpp | 95 ++ libehp | 2 +- 8 files changed, 262 insertions(+), 2655 deletions(-) delete mode 100644 libIRDB/test/dwarf2.h delete mode 100644 libIRDB/test/eh_frame.hpp create mode 100644 libIRDB/test/split_eh_frame.hpp diff --git a/SConstruct b/SConstruct index 2eb231368..0180dbc4a 100644 --- a/SConstruct +++ b/SConstruct @@ -9,9 +9,9 @@ env=Environment() # default build options -env.Replace(CFLAGS="-fPIC -Wall -Werror ") -env.Replace(CXXFLAGS="-fPIC -Wall -Werror ") -env.Replace(LINKFLAGS="-fPIC -Wall -Werror ") +env.Replace(CFLAGS="-fPIC -Wall -Werror -fmax-errors=2") +env.Replace(CXXFLAGS="-fPIC -Wall -Werror -fmax-errors=2 ") +env.Replace(LINKFLAGS="-fPIC -Wall -Werror -fmax-errors=2 ") # parse arguments env.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) diff --git a/libIRDB/test/SConscript b/libIRDB/test/SConscript index 24c10568e..6610373ca 100644 --- a/libIRDB/test/SConscript +++ b/libIRDB/test/SConscript @@ -15,10 +15,11 @@ if 'build_tools' not in myenv or myenv['build_tools'] is None or int(myenv['buil $SECURITY_TRANSFORMS_HOME/libIRDB/include $SECURITY_TRANSFORMS_HOME/libMEDSannotation/include $SECURITY_TRANSFORMS_HOME/libEXEIO/include + $SECURITY_TRANSFORMS_HOME/libehp/include ''' LIBPATH="$SECURITY_TRANSFORMS_HOME/lib" - LIBS=Split( 'IRDB-cfg IRDB-util ' + env.subst('$BASE_IRDB_LIBS')+ " MEDSannotation") + LIBS=Split( 'IRDB-cfg IRDB-util ' + env.subst('$BASE_IRDB_LIBS')+ " MEDSannotation ehp") myenv=myenv.Clone(CPPPATH=Split(cpppath)) diff --git a/libIRDB/test/dwarf2.h b/libIRDB/test/dwarf2.h deleted file mode 100644 index 6917b1457..000000000 --- a/libIRDB/test/dwarf2.h +++ /dev/null @@ -1,595 +0,0 @@ -/* Declarations and definitions of codes relating to the DWARF2 symbolic - debugging information format. - Copyright (C) 1992-2014 Free Software Foundation, Inc. - Contributed by Gary Funck (gary@intrepid.com). Derived from the - DWARF 1 implementation written by Ron Guilmette (rfg@monkeys.com). - - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#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. */ - -/* This file is shared between GCC and GDB, and should not contain - prototypes. */ - -#ifndef __ASSEMBLER__ -/* Tag names and codes. */ - -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 - }; - -#endif /* !ASSEMBLER */ - -/* @@@ 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 */ diff --git a/libIRDB/test/eh_frame.hpp b/libIRDB/test/eh_frame.hpp deleted file mode 100644 index d5826f1eb..000000000 --- a/libIRDB/test/eh_frame.hpp +++ /dev/null @@ -1,402 +0,0 @@ -#ifndef eh_frame_hpp -#define eh_frame_hpp - -#include <libIRDB-core.hpp> -#include <iostream> -#include <iomanip> -#include <fstream> -#include <limits> -#include <stdlib.h> -#include <string.h> -#include <map> -#include <assert.h> -#include <elf.h> -#include <algorithm> -#include <memory> - -#include <exeio.h> -#include "dwarf2.h" - - - - -typedef std::map<libIRDB::virtual_offset_t, libIRDB::Instruction_t*> OffsetMap_t; - -template <int ptrsize> -class eh_frame_util_t -{ - public: - template <class T> - static bool read_type(T &value, uint32_t &position, const uint8_t* const data, const uint32_t max); - template <class T> - static bool read_type_with_encoding - (const uint8_t encoding, T &value, - uint32_t &position, - const uint8_t* const data, - const uint32_t max, - const uint64_t section_start_addr ); - - static bool read_string - (std::string &s, - uint32_t & position, - const uint8_t* const data, - const uint32_t max); - - - // see https://en.wikipedia.org/wiki/LEB128 - static bool read_uleb128 - ( uint64_t &result, - uint32_t& position, - const uint8_t* const data, - const uint32_t max); - - // see https://en.wikipedia.org/wiki/LEB128 - static bool read_sleb128 ( - int64_t &result, - uint32_t & position, - const uint8_t* const data, - const uint32_t max); - - static bool read_length( - uint64_t &act_length, - uint32_t &position, - const uint8_t* const data, - const uint32_t max); -}; - -template <int ptrsize> -class eh_program_insn_t -{ - public: - - eh_program_insn_t() ; - eh_program_insn_t(const std::string &s) ; - - void print(uint64_t &pc, int64_t caf=1) const; - - void push_byte(uint8_t c) ; - - static void print_uleb_operand( - uint32_t pos, - const uint8_t* const data, - const uint32_t max) ; - - static void print_sleb_operand( - uint32_t pos, - const uint8_t* const data, - const uint32_t max) ; - - bool parse_insn( - uint8_t opcode, - uint32_t& pos, - const uint8_t* const data, - const uint32_t &max); - - bool isNop() const ; - bool isRestoreState() const ; - bool isRememberState() const ; - - bool Advance(uint64_t &cur_addr, uint64_t CAF) const ; - - const std::vector<uint8_t>& GetBytes() const ; - std::vector<uint8_t>& GetBytes() ; - - private: - - std::vector<uint8_t> program_bytes; -}; - -template <int ptrsize> -bool operator<(const eh_program_insn_t<ptrsize>& a, const eh_program_insn_t<ptrsize>& b); - -template <int ptrsize> -class eh_program_t -{ - public: - void push_insn(const eh_program_insn_t<ptrsize> &i); - - void print(const uint64_t start_addr=0) const; - - bool parse_program( - const uint32_t& program_start_position, - const uint8_t* const data, - const uint32_t &max_program_pos); - const std::vector<eh_program_insn_t <ptrsize> >& GetInstructions() const ; - std::vector<eh_program_insn_t <ptrsize> >& GetInstructions() ; - private: - std::vector<eh_program_insn_t <ptrsize> > instructions; -}; - -template <int ptrsize> -bool operator<(const eh_program_t<ptrsize>& a, const eh_program_t<ptrsize>& b); - -template <int ptrsize> -class cie_contents_t : eh_frame_util_t<ptrsize> -{ - private: - uint64_t cie_position; - uint64_t length; - uint8_t cie_id; - uint8_t cie_version; - std::string augmentation; - uint64_t code_alignment_factor; - int64_t data_alignment_factor; - uint64_t return_address_register_column; - uint64_t augmentation_data_length; - uint8_t personality_encoding; - uint64_t personality; - uint8_t lsda_encoding; - uint8_t fde_encoding; - eh_program_t<ptrsize> eh_pgm; - - public: - - cie_contents_t() ; - - const eh_program_t<ptrsize>& GetProgram() const ; - uint64_t GetCAF() const ; - int64_t GetDAF() const ; - uint64_t GetPersonality() const ; - uint64_t GetReturnRegister() const ; - - std::string GetAugmentation() const ; - uint8_t GetLSDAEncoding() const ; - uint8_t GetFDEEncoding() const ; - - bool parse_cie( - const uint32_t &cie_position, - const uint8_t* const data, - const uint32_t max, - const uint64_t eh_addr); - void print() const ; - void build_ir(libIRDB::Instruction_t* insn) const; -}; - -template <int ptrsize> -class lsda_call_site_action_t : private eh_frame_util_t<ptrsize> -{ - private: - int64_t action; - - public: - lsda_call_site_action_t() ; - int64_t GetAction() const ; - - bool parse_lcsa(uint32_t& pos, const uint8_t* const data, const uint64_t max, bool &end); - void print() const; -}; - -template <int ptrsize> -bool operator< (const lsda_call_site_action_t <ptrsize> &lhs, const lsda_call_site_action_t <ptrsize> &rhs); - -template <int ptrsize> -class lsda_type_table_entry_t: private eh_frame_util_t<ptrsize> -{ - private: - uint64_t pointer_to_typeinfo; - uint64_t tt_encoding; - uint64_t tt_encoding_size; - - public: - lsda_type_table_entry_t() ; - - uint64_t GetTypeInfoPointer() const ; - uint64_t GetEncoding() const ; - uint64_t GetTTEncodingSize() const ; - - bool parse( - const uint64_t p_tt_encoding, - const uint64_t tt_pos, - const uint64_t index, - const uint8_t* const data, - const uint64_t max, - const uint64_t data_addr - ); - - void print() const; - -}; - -template <int ptrsize> -class lsda_call_site_t : private eh_frame_util_t<ptrsize> -{ - private: - uint64_t call_site_offset; - uint64_t call_site_addr; - uint64_t call_site_length; - uint64_t call_site_end_addr; - uint64_t landing_pad_offset; - uint64_t landing_pad_addr; - uint64_t action; - uint64_t action_table_offset; - uint64_t action_table_addr; - - std::vector<lsda_call_site_action_t <ptrsize> > action_table; - - public: - lsda_call_site_t() ; - - const std::vector<lsda_call_site_action_t <ptrsize> >& GetActionTable() const { return action_table; } - std::vector<lsda_call_site_action_t <ptrsize> >& GetActionTable() { return action_table; } - - uint64_t GetLandingPadAddress() const { return landing_pad_addr ; } - - bool parse_lcs( - const uint64_t action_table_start_addr, - const uint64_t cs_table_start_addr, - const uint8_t cs_table_encoding, - uint32_t &pos, - const uint8_t* const data, - const uint64_t max, /* call site table max */ - const uint64_t data_addr, - const uint64_t landing_pad_base_addr, - const uint64_t gcc_except_table_max); - - void print() const; - - bool appliesTo(const libIRDB::Instruction_t* insn) const; - - void build_ir(libIRDB::Instruction_t* insn, const std::vector<lsda_type_table_entry_t <ptrsize> > &type_table, const uint8_t& tt_encoding, const OffsetMap_t& om, libIRDB::FileIR_t* firp) const; -}; - - -// short hand for a vector of call sites -template <int ptrsize> using call_site_table_t = std::vector<lsda_call_site_t <ptrsize> > ; - -template <int ptrsize> -class lsda_t : private eh_frame_util_t<ptrsize> -{ - private: - uint8_t landing_pad_base_encoding; - uint64_t landing_pad_base_addr; // often ommitted. when ommitted, filled in from FDE region start. - uint8_t type_table_encoding; - uint64_t type_table_offset; - uint64_t type_table_addr; - uint8_t cs_table_encoding; - uint64_t cs_table_start_offset; - uint64_t cs_table_start_addr; - uint64_t cs_table_length; - uint64_t cs_table_end_addr; - uint64_t action_table_start_addr; - call_site_table_t <ptrsize> call_site_table; - std::vector<lsda_type_table_entry_t <ptrsize> > type_table; - - public: - - uint8_t GetTTEncoding() const ; - - lsda_t() ; - - bool parse_lsda(const uint64_t lsda_addr, const libIRDB::DataScoop_t* gcc_except_scoop, const uint64_t fde_region_start); - void print() const; - void build_ir(libIRDB::Instruction_t* insn, const OffsetMap_t& om, libIRDB::FileIR_t* firp) const; - - const call_site_table_t<ptrsize> GetCallSites() const { return call_site_table;} - -}; - - - -template <int ptrsize> -class fde_contents_t : eh_frame_util_t<ptrsize> -{ - uint32_t fde_position; - uint32_t cie_position; - uint64_t length; - uint8_t id; - uint64_t fde_start_addr; - uint64_t fde_end_addr; - uint64_t fde_range_len; - uint64_t lsda_addr; - - - lsda_t<ptrsize> lsda; - eh_program_t<ptrsize> eh_pgm; - cie_contents_t<ptrsize> cie_info; - - public: - fde_contents_t() ; - fde_contents_t(const uint64_t start_addr, const uint64_t end_addr) - : - fde_start_addr(start_addr), - fde_end_addr(end_addr) - {} - - bool appliesTo(const libIRDB::Instruction_t* insn) const; - - uint64_t GetFDEStartAddress() const { return fde_start_addr; } - uint64_t GetFDEEndAddress() const {return fde_end_addr; } - - const cie_contents_t<ptrsize>& GetCIE() const ; - cie_contents_t<ptrsize>& GetCIE() ; - - const eh_program_t<ptrsize>& GetProgram() const ; - eh_program_t<ptrsize>& GetProgram() ; - - const lsda_t<ptrsize>& GetLSDA() const { return lsda; } - - bool parse_fde( - const uint32_t &fde_position, - const uint32_t &cie_position, - const uint8_t* const data, - const uint64_t max, - const uint64_t eh_addr, - const libIRDB::DataScoop_t* gcc_except_scoop); - - void print() const; - - void build_ir(libIRDB::Instruction_t* insn, const OffsetMap_t &om, libIRDB::FileIR_t* firp) const; - -}; - -template <int ptrsize> -bool operator<(const fde_contents_t<ptrsize>& a, const fde_contents_t<ptrsize>& b) { return a.GetFDEEndAddress()-1 < b.GetFDEStartAddress(); } - - -class split_eh_frame_t -{ - public: - - virtual bool parse()=0; - virtual void build_ir() const =0; - virtual void print() const=0; - virtual libIRDB::Instruction_t* find_lp(libIRDB::Instruction_t*) const =0; - - static std::unique_ptr<split_eh_frame_t> factory(libIRDB::FileIR_t *firp); - -}; - -template <int ptrsize> -class split_eh_frame_impl_t : public split_eh_frame_t -{ - private: - - libIRDB::FileIR_t* firp; - libIRDB::DataScoop_t* eh_frame_scoop; - libIRDB::DataScoop_t* eh_frame_hdr_scoop; - libIRDB::DataScoop_t* gcc_except_table_scoop; - OffsetMap_t offset_to_insn_map; - std::vector<cie_contents_t <ptrsize> > cies; - std::set<fde_contents_t <ptrsize> > fdes; - - - bool init_offset_map(); - - bool iterate_fdes(); - - public: - - split_eh_frame_impl_t(libIRDB::FileIR_t* p_firp); - - bool parse(); - - void print() const; - - void build_ir() const; - - libIRDB::Instruction_t* find_lp(libIRDB::Instruction_t*) const ; -}; - -void split_eh_frame(libIRDB::FileIR_t* firp); - -#endif diff --git a/libIRDB/test/fill_in_cfg.cpp b/libIRDB/test/fill_in_cfg.cpp index a1d33d216..597830db3 100644 --- a/libIRDB/test/fill_in_cfg.cpp +++ b/libIRDB/test/fill_in_cfg.cpp @@ -29,7 +29,7 @@ #include <ctype.h> #include <exeio.h> #include "elfio/elfio.hpp" -#include "eh_frame.hpp" +#include "split_eh_frame.hpp" int odd_target_count=0; int bad_target_count=0; @@ -554,7 +554,7 @@ void fill_in_scoops(FileIR_t *firp) void fill_in_landing_pads(FileIR_t *firp) { const auto eh_frame_rep_ptr = split_eh_frame_t::factory(firp); - eh_frame_rep_ptr->parse(); + // eh_frame_rep_ptr->parse(); already parsed now. if(getenv("EHIR_VERBOSE")) eh_frame_rep_ptr->print(); cout<<"Completed eh-frame parsing"<<endl; diff --git a/libIRDB/test/split_eh_frame.cpp b/libIRDB/test/split_eh_frame.cpp index 117895efb..5c6009ca2 100644 --- a/libIRDB/test/split_eh_frame.cpp +++ b/libIRDB/test/split_eh_frame.cpp @@ -12,1254 +12,44 @@ #include <memory> #include <exeio.h> -#include "dwarf2.h" -#include "eh_frame.hpp" +#include "split_eh_frame.hpp" +#include "ehp.hpp" using namespace std; using namespace EXEIO; using namespace libIRDB; +using namespace EHP; -#define WHOLE_CONTAINER(s) begin(s), end(s) +#define ALLOF(s) begin(s), end(s) template <int ptrsize> -template <class T> -bool eh_frame_util_t<ptrsize>::read_type(T &value, uint32_t &position, const uint8_t* const data, const uint32_t max) -{ - if(position + sizeof(T) > max) return true; - - - // typecast to the right type - auto ptr=(const T*)&data[position]; - - // set output parameters - position+=sizeof(T); - value=*ptr; - - return false; - -} -template <int ptrsize> -template <class T> -bool eh_frame_util_t<ptrsize>::read_type_with_encoding - (const uint8_t encoding, T &value, - uint32_t &position, - const uint8_t* const data, - const uint32_t max, - const uint64_t section_start_addr ) -{ - auto orig_position=position; - auto encoding_lower8=encoding&0xf; - auto encoding_upper8=encoding&0xf0; - value=0; - switch(encoding_lower8) - { - case DW_EH_PE_omit : - return true; - - - case DW_EH_PE_uleb128: - { - auto newval=uint64_t(0); - if(eh_frame_util_t<ptrsize>::read_uleb128(newval,position,data,max)) - return true; - value=newval; - break; - } - case DW_EH_PE_sleb128: - { - auto newval=int64_t(0); - if(eh_frame_util_t<ptrsize>::read_sleb128(newval,position,data,max)) - return true; - value=newval; - break; - } - case DW_EH_PE_udata2 : - { - auto newval=uint16_t(0); - if(eh_frame_util_t<ptrsize>::read_type(newval,position,data,max)) - return true; - value=newval; - break; - } - case DW_EH_PE_udata4 : - { - auto newval=uint32_t(0); - if(eh_frame_util_t<ptrsize>::read_type(newval,position,data,max)) - return true; - value=newval; - break; - } - case DW_EH_PE_udata8 : - { - auto newval=uint64_t(0); - if(eh_frame_util_t<ptrsize>::read_type(newval,position,data,max)) - return true; - value=newval; - break; - } - case DW_EH_PE_absptr: - { - if(ptrsize==8) - { - if(eh_frame_util_t<ptrsize>::read_type_with_encoding(DW_EH_PE_udata8, value, position, data, max, section_start_addr)) - return true; - break; - } - else if(ptrsize==4) - { - if(eh_frame_util_t<ptrsize>::read_type_with_encoding(DW_EH_PE_udata4, value, position, data, max, section_start_addr)) - return true; - break; - } - assert(0); - - } - case DW_EH_PE_sdata2 : - { - auto newval=int16_t(0); - if(eh_frame_util_t<ptrsize>::read_type(newval,position,data,max)) - return true; - value=newval; - break; - } - case DW_EH_PE_sdata4 : - { - auto newval=int32_t(0); - if(eh_frame_util_t<ptrsize>::read_type(newval,position,data,max)) - return true; - value=newval; - break; - } - case DW_EH_PE_sdata8 : - { - auto newval=int64_t(0); - if(read_type(newval,position,data,max)) - return true; - value=newval; - break; - } - - case DW_EH_PE_signed : - default: - assert(0); - }; - - switch(encoding_upper8) - { - case DW_EH_PE_absptr: - break; - case DW_EH_PE_pcrel : - value+=section_start_addr+orig_position; - break; - case DW_EH_PE_textrel: - case DW_EH_PE_datarel: - case DW_EH_PE_funcrel: - case DW_EH_PE_aligned: - case DW_EH_PE_indirect: - default: - assert(0); - return true; - } - return false; -} - -template <int ptrsize> -bool eh_frame_util_t<ptrsize>::read_string - (string &s, - uint32_t & position, - const uint8_t* const data, - const uint32_t max) -{ - while(data[position]!='\0' && position < max) - { - s+=data[position]; - position++; - } - - position++; - return (position>max); -} - - -// see https://en.wikipedia.org/wiki/LEB128 -template <int ptrsize> -bool eh_frame_util_t<ptrsize>::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> -bool eh_frame_util_t<ptrsize>::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> -bool eh_frame_util_t<ptrsize>::read_length( - uint64_t &act_length, - uint32_t &position, - const uint8_t* const data, - const uint32_t max) -{ - auto eh_frame_scoop_data=data; - auto length=uint32_t(0); - auto length_64bit=uint64_t(0); - if(read_type(length,position, eh_frame_scoop_data, max)) - return true; - - if(length==0xffffffff) - { - if(read_type(length_64bit,position, eh_frame_scoop_data, max)) - return true; - act_length=length_64bit; - } - else - act_length=length; - - return false; -} - -template <int ptrsize> -eh_program_insn_t<ptrsize>::eh_program_insn_t() { } - -template <int ptrsize> -eh_program_insn_t<ptrsize>::eh_program_insn_t(const string &s) - : program_bytes(s.begin(), next(s.begin(), s.size())) -{ } - -template <int ptrsize> -void eh_program_insn_t<ptrsize>::print(uint64_t &pc, int64_t caf) const -{ - // 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=program_bytes; - auto opcode=program_bytes[0]; - auto opcode_upper2=(uint8_t)(opcode >> 6); - auto opcode_lower6=(uint8_t)(opcode & (0x3f)); - auto pos=uint32_t(1); - auto max=program_bytes.size(); - - switch(opcode_upper2) - { - case 1: - { - // case DW_CFA_advance_loc: - pc+=(opcode_lower6*caf); - cout<<" cfa_advance_loc "<<dec<<+opcode_lower6<<" to "<<hex<<pc<<endl; - break; - } - case 2: - { - uint64_t uleb=0; - if(eh_frame_util_t<ptrsize>::read_uleb128(uleb, pos, (const uint8_t* const)data.data(), max)) - return; - // case DW_CFA_offset: - cout<<" cfa_offset "<<dec<<uleb<<endl; - break; - } - case 3: - { - // case DW_CFA_restore (register #): - cout<<" cfa_restore"<<endl; - break; - } - case 0: - { - switch(opcode_lower6) - { - - case DW_CFA_nop: - cout<<" nop" <<endl; - break; - case DW_CFA_remember_state: - cout<<" remember_state" <<endl; - break; - case DW_CFA_restore_state: - cout<<" restore_state" <<endl; - break; - - // takes single uleb128 - case DW_CFA_undefined: - cout<<" undefined" ; - print_uleb_operand(pos,(const uint8_t* const)data.data(),max); - cout<<endl; - break; - - case DW_CFA_same_value: - cout<<" same_value "; - print_uleb_operand(pos,(const uint8_t* const)data.data(),max); - cout<<endl; - break; - case DW_CFA_restore_extended: - cout<<" restore_extended "; - print_uleb_operand(pos,(const uint8_t* const)data.data(),max); - cout<<endl; - break; - case DW_CFA_def_cfa_register: - cout<<" def_cfa_register "; - print_uleb_operand(pos,(const uint8_t* const)data.data(),max); - cout<<endl; - break; - case DW_CFA_GNU_args_size: - cout<<" GNU_arg_size "; - print_uleb_operand(pos,(const uint8_t* const)data.data(),max); - cout<<endl; - break; - case DW_CFA_def_cfa_offset: - cout<<" def_cfa_offset "; - print_uleb_operand(pos,(const uint8_t* const)data.data(),max); - cout<<endl; - 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; - } - cout<<" set_loc "<<hex<<arg<<endl; - break; - } - case DW_CFA_advance_loc1: - { - auto loc=*(uint8_t*)(&data.data()[pos]); - pc+=(loc*caf); - cout<<" advance_loc1 "<<+loc<<" to " <<pc << endl; - break; - } - - case DW_CFA_advance_loc2: - { - auto loc=*(uint16_t*)(&data.data()[pos]); - pc+=(loc*caf); - cout<<" advance_loc2 "<<+loc<<" to " <<pc << endl; - break; - } - - case DW_CFA_advance_loc4: - { - auto loc=*(uint32_t*)(&data.data()[pos]); - pc+=(loc*caf); - cout<<" advance_loc4 "<<+loc<<" to " <<pc << endl; - break; - } - case DW_CFA_offset_extended: - cout<<" offset_extended "; - print_uleb_operand(pos,(const uint8_t* const)data.data(),max); - print_uleb_operand(pos,(const uint8_t* const)data.data(),max); - cout<<endl; - break; - case DW_CFA_register: - cout<<" register "; - print_uleb_operand(pos,(const uint8_t* const)data.data(),max); - print_uleb_operand(pos,(const uint8_t* const)data.data(),max); - cout<<endl; - break; - case DW_CFA_def_cfa: - cout<<" def_cfa "; - print_uleb_operand(pos,(const uint8_t* const)data.data(),max); - print_uleb_operand(pos,(const uint8_t* const)data.data(),max); - cout<<endl; - break; - case DW_CFA_def_cfa_sf: - cout<<" def_cfa_sf "; - print_uleb_operand(pos,(const uint8_t* const)data.data(),max); - print_sleb_operand(pos,(const uint8_t* const)data.data(),max); - cout<<endl; - break; - - case DW_CFA_def_cfa_expression: - { - auto uleb=uint64_t(0); - if(eh_frame_util_t<ptrsize>::read_uleb128(uleb, pos, (const uint8_t* const)data.data(), max)) - return ; - cout<<" def_cfa_expression "<<dec<<uleb<<endl; - pos+=uleb; // doing this old school for now, as we aren't printing the expression. - break; - } - case DW_CFA_expression: - { - auto uleb1=uint64_t(0); - auto uleb2=uint64_t(0); - if(eh_frame_util_t<ptrsize>::read_uleb128(uleb1, pos, (const uint8_t* const)data.data(), max)) - return ; - if(eh_frame_util_t<ptrsize>::read_uleb128(uleb2, pos, (const uint8_t* const)data.data(), max)) - return ; - cout<<" expression "<<dec<<uleb1<<" "<<uleb2<<endl; - pos+=uleb2; - break; - } - case DW_CFA_val_expression: - { - auto uleb1=uint64_t(0); - auto uleb2=uint64_t(0); - if(eh_frame_util_t<ptrsize>::read_uleb128(uleb1, pos, (const uint8_t* const)data.data(), max)) - return ; - if(eh_frame_util_t<ptrsize>::read_uleb128(uleb2, pos, (const uint8_t* const)data.data(), max)) - return ; - cout<<" val_expression "<<dec<<uleb1<<" "<<uleb2<<endl; - pos+=uleb2; - break; - } - case DW_CFA_def_cfa_offset_sf: - { - auto leb=int64_t(0); - if(eh_frame_util_t<ptrsize>::read_sleb128(leb, pos, (const uint8_t* const)data.data(), max)) - return ; - cout<<" def_cfa_offset_sf "<<dec<<leb; - break; - } - case DW_CFA_offset_extended_sf: - { - auto uleb1=uint64_t(0); - auto sleb2=int64_t(0); - if(eh_frame_util_t<ptrsize>::read_uleb128(uleb1, pos, (const uint8_t* const)data.data(), max)) - return ; - if(eh_frame_util_t<ptrsize>::read_sleb128(sleb2, pos, (const uint8_t* const)data.data(), max)) - return ; - cout<<" offset_extended_sf "<<dec<<uleb1<<" "<<sleb2<<endl; - 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: - cout<<"Unhandled opcode cannot print. opcode="<<opcode<<endl; - } - break; - } - } - -} - -template <int ptrsize> -void eh_program_insn_t<ptrsize>::push_byte(uint8_t c) { program_bytes.push_back(c); } - -template <int ptrsize> -void eh_program_insn_t<ptrsize>::print_uleb_operand( - uint32_t pos, - const uint8_t* const data, - const uint32_t max) -{ - auto uleb=uint64_t(0xdeadbeef); - eh_frame_util_t<ptrsize>::read_uleb128(uleb, pos, data, max); - cout<<" "<<dec<<uleb; -} - -template <int ptrsize> -void eh_program_insn_t<ptrsize>::print_sleb_operand( - uint32_t pos, - const uint8_t* const data, - const uint32_t max) -{ - auto leb=int64_t(0xdeadbeef); - eh_frame_util_t<ptrsize>::read_sleb128(leb, pos, data, max); - cout<<" "<<dec<<leb; -} - -template <int ptrsize> -bool eh_program_insn_t<ptrsize>::parse_insn( - uint8_t opcode, - uint32_t& pos, - const uint8_t* const data, - const uint32_t &max) -{ - auto &eh_insn = *this; - auto insn_start=pos-1; - auto opcode_upper2=(uint8_t)(opcode >> 6); - auto opcode_lower6=(uint8_t)(opcode & (0x3f)); - - // calculate the end of the instruction, which is inherently per-opcode - switch(opcode_upper2) - { - case 1: - { - // case DW_CFA_advance_loc: - break; - } - case 2: - { - auto uleb=uint64_t(0); - if(eh_frame_util_t<ptrsize>::read_uleb128(uleb, pos, data, max)) - return true; - // case DW_CFA_offset: - break; - } - case 3: - { - // case DW_CFA_offset: - break; - } - case 0: - { - switch(opcode_lower6) - { - - case DW_CFA_nop: - case DW_CFA_remember_state: - case DW_CFA_restore_state: - break; - - // takes single uleb128 - case DW_CFA_undefined: - case DW_CFA_same_value: - case DW_CFA_restore_extended: - case DW_CFA_def_cfa_register: - case DW_CFA_GNU_args_size: - case DW_CFA_def_cfa_offset: - { - auto uleb=uint64_t(0); - if(eh_frame_util_t<ptrsize>::read_uleb128(uleb, pos, data, max)) - return true; - break; - } - - case DW_CFA_set_loc: - pos+=ptrsize; - break; - - case DW_CFA_advance_loc1: - pos+=1; - break; - - case DW_CFA_advance_loc2: - pos+=2; - break; - - case DW_CFA_advance_loc4: - pos+=4; - break; - - case DW_CFA_offset_extended: - case DW_CFA_register: - case DW_CFA_def_cfa: - { - auto uleb1=uint64_t(1); - auto uleb2=uint64_t(0); - if(eh_frame_util_t<ptrsize>::read_uleb128(uleb1, pos, data, max)) - return true; - if(eh_frame_util_t<ptrsize>::read_uleb128(uleb2, pos, data, max)) - return true; - break; - } - case DW_CFA_def_cfa_sf: - { - auto leb1=uint64_t(0); - auto leb2=int64_t(0); - if(eh_frame_util_t<ptrsize>::read_uleb128(leb1, pos, data, max)) - return true; - if(eh_frame_util_t<ptrsize>::read_sleb128(leb2, pos, data, max)) - return true; - break; - } - - case DW_CFA_def_cfa_expression: - { - auto uleb=uint64_t(0); - if(eh_frame_util_t<ptrsize>::read_uleb128(uleb, pos, data, max)) - return true; - pos+=uleb; - break; - } - case DW_CFA_expression: - case DW_CFA_val_expression: - { - auto uleb1=uint64_t(0); - auto uleb2=uint64_t(0); - if(eh_frame_util_t<ptrsize>::read_uleb128(uleb1, pos, data, max)) - return true; - if(eh_frame_util_t<ptrsize>::read_uleb128(uleb2, pos, data, max)) - return true; - pos+=uleb2; - break; - } - case DW_CFA_def_cfa_offset_sf: - { - auto leb=int64_t(0); - if(eh_frame_util_t<ptrsize>::read_sleb128(leb, pos, data, max)) - return true; - break; - } - case DW_CFA_offset_extended_sf: - { - auto uleb1=uint64_t(0); - auto sleb2=int64_t(0); - if(eh_frame_util_t<ptrsize>::read_uleb128(uleb1, pos, data, max)) - return true; - if(eh_frame_util_t<ptrsize>::read_sleb128(sleb2, pos, data, max)) - return true; - break; - } - /* Dwarf 2.1 */ - case DW_CFA_val_offset: - case DW_CFA_val_offset_sf: - - - /* 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: - // Unhandled opcode cannot xform this eh-frame - cout<<"No decoder for opcode "<<+opcode<<endl; - return true; - } - break; - } - default: - cout<<"No decoder for opcode "<<+opcode<<endl; - return true; - } - - // insert bytes into the instruction. - auto insn_end=pos; - for_each( &data[insn_start], &data[insn_end], [&](const uint8_t c) - { - eh_insn.push_byte(c); - }); - return false; -} - -template <int ptrsize> -bool eh_program_insn_t<ptrsize>::isNop() const -{ - const auto opcode=program_bytes[0]; - const auto opcode_upper2=(uint8_t)(opcode >> 6); - const auto opcode_lower6=(uint8_t)(opcode & (0x3f)); - switch(opcode_upper2) - { - case 0: - { - switch(opcode_lower6) - { - - case DW_CFA_nop: - return true; - } - } - } - return false; -} - -template <int ptrsize> -bool eh_program_insn_t<ptrsize>::isRestoreState() const -{ - const auto opcode=program_bytes[0]; - const auto opcode_upper2=(uint8_t)(opcode >> 6); - const auto opcode_lower6=(uint8_t)(opcode & (0x3f)); - switch(opcode_upper2) - { - case 0: - { - switch(opcode_lower6) - { - case DW_CFA_restore_state: - return true; - } - } - } - return false; -} - -template <int ptrsize> -bool eh_program_insn_t<ptrsize>::isRememberState() const -{ - const auto opcode=program_bytes[0]; - const auto opcode_upper2=(uint8_t)(opcode >> 6); - const auto opcode_lower6=(uint8_t)(opcode & (0x3f)); - switch(opcode_upper2) - { - case 0: - { - switch(opcode_lower6) - { - case DW_CFA_remember_state: - return true; - } - } - } - return false; -} - -template <int ptrsize> -bool eh_program_insn_t<ptrsize>::Advance(uint64_t &cur_addr, uint64_t CAF) const -{ - // 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=program_bytes; - auto opcode=program_bytes[0]; - auto opcode_upper2=(uint8_t)(opcode >> 6); - auto opcode_lower6=(uint8_t)(opcode & (0x3f)); - auto pos=uint32_t(1); - //auto max=program_bytes.size(); - - switch(opcode_upper2) - { - case 1: - { - // case DW_CFA_advance_loc: - cur_addr+=(opcode_lower6*CAF); - return true; - } - case 0: - { - switch(opcode_lower6) - { - case DW_CFA_set_loc: - { - assert(0); - return true; - } - case DW_CFA_advance_loc1: - { - auto loc=*(uint8_t*)(&data.data()[pos]); - cur_addr+=(loc*CAF); - return true; - } - - case DW_CFA_advance_loc2: - { - auto loc=*(uint16_t*)(&data.data()[pos]); - cur_addr+=(loc*CAF); - return true; - } - - case DW_CFA_advance_loc4: - { - auto loc=*(uint32_t*)(&data.data()[pos]); - cur_addr+=(loc*CAF); - return true; - } - } - } - } - return false; -} - -template <int ptrsize> -const vector<uint8_t>& eh_program_insn_t<ptrsize>::GetBytes() const { return program_bytes; } - -template <int ptrsize> -vector<uint8_t>& eh_program_insn_t<ptrsize>::GetBytes() { return program_bytes; } - - - - - - -template <int ptrsize> -bool operator<(const eh_program_insn_t<ptrsize>& a, const eh_program_insn_t<ptrsize>& b) -{ - return a.GetBytes() < b.GetBytes(); -} - -template <int ptrsize> -void eh_program_t<ptrsize>::push_insn(const eh_program_insn_t<ptrsize> &i) { instructions.push_back(i); } - -template <int ptrsize> -void eh_program_t<ptrsize>::print(const uint64_t start_addr) const -{ - auto pc=start_addr; - cout << " Program: " << endl ; - for_each(instructions.begin(), instructions.end(), [&](const eh_program_insn_t<ptrsize>& i) - { - i.print(pc); - }); -} - -template <int ptrsize> -bool eh_program_t<ptrsize>::parse_program( - const uint32_t& program_start_position, - const uint8_t* const data, - const uint32_t &max_program_pos) -{ - eh_program_t &eh_pgm=*this; - auto max=max_program_pos; - auto pos=program_start_position; - while(pos < max_program_pos) - { - auto opcode=uint8_t(0); - if(eh_frame_util_t<ptrsize>::read_type(opcode,pos,data,max)) - return true; - eh_program_insn_t<ptrsize> eh_insn; - if(eh_insn.parse_insn(opcode,pos,data,max)) - return true; - - eh_pgm.push_insn(eh_insn); - - - } - - return false; -} - -template <int ptrsize> -const vector<eh_program_insn_t <ptrsize> >& eh_program_t<ptrsize>::GetInstructions() const { return instructions; } - -template <int ptrsize> -vector<eh_program_insn_t <ptrsize> >& eh_program_t<ptrsize>::GetInstructions() { return instructions; } - -template <int ptrsize> -bool operator<(const eh_program_t<ptrsize>& a, const eh_program_t<ptrsize>& b) -{ - return a.GetInstructions() < b.GetInstructions(); -} - -template <int ptrsize> -cie_contents_t<ptrsize>::cie_contents_t() : - cie_position(0), - length(0), - cie_id(0), - cie_version(0), - code_alignment_factor(0), - data_alignment_factor(0), - return_address_register_column(0), - augmentation_data_length(0), - personality_encoding(0), - personality(0), - lsda_encoding(0), - fde_encoding(0) -{} - - -template <int ptrsize> -const eh_program_t<ptrsize>& cie_contents_t<ptrsize>::GetProgram() const { return eh_pgm; } - -template <int ptrsize> -uint64_t cie_contents_t<ptrsize>::GetCAF() const { return code_alignment_factor; } - -template <int ptrsize> -int64_t cie_contents_t<ptrsize>::GetDAF() const { return data_alignment_factor; } - -template <int ptrsize> -uint64_t cie_contents_t<ptrsize>::GetPersonality() const { return personality; } - -template <int ptrsize> -uint64_t cie_contents_t<ptrsize>::GetReturnRegister() const { return return_address_register_column; } - - -template <int ptrsize> -string cie_contents_t<ptrsize>::GetAugmentation() const { return augmentation; } - -template <int ptrsize> -uint8_t cie_contents_t<ptrsize>::GetLSDAEncoding() const { return lsda_encoding;} - -template <int ptrsize> -uint8_t cie_contents_t<ptrsize>::GetFDEEncoding() const { return fde_encoding;} - - -template <int ptrsize> -bool cie_contents_t<ptrsize>::parse_cie( - const uint32_t &cie_position, - const uint8_t* const data, - const uint32_t max, - const uint64_t eh_addr) -{ - auto &c=*this; - const auto eh_frame_scoop_data= data; - auto position=cie_position; - auto length= uint64_t(0); - - if(this->read_length(length, position, eh_frame_scoop_data, max)) - return true; - - auto end_pos=position+length; - - auto cie_id=uint32_t(0); - if(this->read_type(cie_id, position, eh_frame_scoop_data, max)) - return true; - - auto cie_version=uint8_t(0); - if(this->read_type(cie_version, position, eh_frame_scoop_data, max)) - return true; - - if(cie_version==1) - { } // OK - else if(cie_version==3) - { } // OK - else - // Err. - return true; - - auto augmentation=string(); - if(this->read_string(augmentation, position, eh_frame_scoop_data, max)) - return true; - - auto code_alignment_factor=uint64_t(0); - if(this->read_uleb128(code_alignment_factor, position, eh_frame_scoop_data, max)) - return true; - - auto data_alignment_factor=int64_t(0); - if(this->read_sleb128(data_alignment_factor, position, eh_frame_scoop_data, max)) - return true; - - // type depends on version info. can always promote to 64 bits. - auto return_address_register_column=uint64_t(0); - if(cie_version==1) - { - auto return_address_register_column_8=uint8_t(0); - if(this->read_type(return_address_register_column_8, position, eh_frame_scoop_data, max)) - return true; - return_address_register_column=return_address_register_column_8; - } - else if(cie_version==3) - { - auto return_address_register_column_64=uint64_t(0); - if(this->read_uleb128(return_address_register_column_64, position, eh_frame_scoop_data, max)) - return true; - return_address_register_column=return_address_register_column_64; - } - else - assert(0); - - auto augmentation_data_length=uint64_t(0); - if(augmentation.find("z") != string::npos) - { - if(this->read_uleb128(augmentation_data_length, position, eh_frame_scoop_data, max)) - return true; - } - auto personality_encoding=uint8_t(DW_EH_PE_omit); - auto personality=uint64_t(0); - if(augmentation.find("P") != string::npos) - { - if(this->read_type(personality_encoding, position, eh_frame_scoop_data, max)) - return true; - - // indirect is OK as a personality encoding, but we don't need to go that far. - // we just need to record what's in the CIE, regardless of whether it's the actual - // personality routine or it's the pointer to the personality routine. - auto personality_encoding_sans_indirect = personality_encoding&(~DW_EH_PE_indirect); - if(this->read_type_with_encoding(personality_encoding_sans_indirect, personality, position, eh_frame_scoop_data, max, eh_addr)) - return true; - } - - auto lsda_encoding=uint8_t(DW_EH_PE_omit); - if(augmentation.find("L") != string::npos) - { - if(this->read_type(lsda_encoding, position, eh_frame_scoop_data, max)) - return true; - } - auto fde_encoding=uint8_t(DW_EH_PE_omit); - if(augmentation.find("R") != string::npos) - { - if(this->read_type(fde_encoding, position, eh_frame_scoop_data, max)) - return true; - } - if(eh_pgm.parse_program(position, eh_frame_scoop_data, end_pos)) - return true; - - - c.cie_position=cie_position; - c.cie_id=cie_id; - c.cie_version=cie_version; - c.augmentation=augmentation; - c.code_alignment_factor=code_alignment_factor; - c.data_alignment_factor=data_alignment_factor; - c.return_address_register_column=return_address_register_column; - c.augmentation_data_length=augmentation_data_length; - c.personality_encoding=personality_encoding; - c.personality=personality; - c.lsda_encoding=lsda_encoding; - c.fde_encoding=fde_encoding; - - // all OK - return false; -} - -template <int ptrsize> -void cie_contents_t<ptrsize>::print() const -{ - cout << "["<<setw(6)<<hex<<cie_position<<"] CIE length="<<dec<<length<<endl; - cout << " CIE_id: " << +cie_id << endl; - cout << " version: " << +cie_version << endl; - cout << " augmentation: \"" << augmentation << "\"" << endl; - cout << " code_alignment_factor: " << code_alignment_factor << endl; - cout << " data_alignment_factor: " << dec << data_alignment_factor << endl; - cout << " return_address_register: " << dec << return_address_register_column << endl; - cout << " Augmentation data: " << endl ; - cout << " aug data len: " << hex << +augmentation_data_length << endl; - cout << " personality_encoding: " << hex << +personality_encoding << endl; - cout << " personality: " << hex << +personality << endl; - cout << " lsda_encoding: " << hex << +lsda_encoding << endl; - cout << " fde_encoding: " << hex << +fde_encoding << endl; - cout << " Program: " << endl ; - eh_pgm.print(); - -} - -template <int ptrsize> -void cie_contents_t<ptrsize>::build_ir(Instruction_t* insn) const -{ - // nothing to do? built up one level. - //eh_pgm.print(); -} - -template <int ptrsize> -lsda_call_site_action_t<ptrsize>::lsda_call_site_action_t() : - action(0) -{} - - -template <int ptrsize> -int64_t lsda_call_site_action_t<ptrsize>::GetAction() const { return action;} - - -template <int ptrsize> -bool lsda_call_site_action_t<ptrsize>::parse_lcsa(uint32_t& pos, const uint8_t* const data, const uint64_t max, bool &end) -{ - end=false; - if(this->read_sleb128(action, pos, data, max)) - return true; - - auto next_action=pos; - auto next_pos_offset=int64_t(0); - if(this->read_sleb128(next_pos_offset, pos, data, max)) - return true; - - if(next_pos_offset==0) - end=true; - else - pos=next_action+next_pos_offset; - return false; -} - -template <int ptrsize> -void lsda_call_site_action_t<ptrsize>::print() const -{ - cout<<" "<<action<<endl; -} - -template <int ptrsize> -bool operator< (const lsda_call_site_action_t <ptrsize> &lhs, const lsda_call_site_action_t <ptrsize> &rhs) -{ - return lhs.GetAction() < rhs.GetAction(); -} - -template <int ptrsize> -lsda_type_table_entry_t<ptrsize>::lsda_type_table_entry_t() : - pointer_to_typeinfo(0), tt_encoding(0) -{} - - -template <int ptrsize> -uint64_t lsda_type_table_entry_t<ptrsize>::GetTypeInfoPointer() const { return pointer_to_typeinfo; } - -template <int ptrsize> -uint64_t lsda_type_table_entry_t<ptrsize>::GetEncoding() const { return tt_encoding; } - -template <int ptrsize> -uint64_t lsda_type_table_entry_t<ptrsize>::GetTTEncodingSize() const { return tt_encoding_size; } - - -template <int ptrsize> -bool lsda_type_table_entry_t<ptrsize>::parse( - const uint64_t p_tt_encoding, - const uint64_t tt_pos, - const uint64_t index, - const uint8_t* const data, - const uint64_t max, - const uint64_t data_addr - ) -{ - tt_encoding=p_tt_encoding; - const auto tt_encoding_sans_indirect = tt_encoding&(~DW_EH_PE_indirect); - const auto tt_encoding_sans_indir_sans_pcrel = tt_encoding_sans_indirect & (~DW_EH_PE_pcrel); - const auto has_pcrel = (tt_encoding & DW_EH_PE_pcrel) == DW_EH_PE_pcrel; - switch(tt_encoding & 0xf) // get just the size field - { - case DW_EH_PE_udata4: - case DW_EH_PE_sdata4: - tt_encoding_size=4; - break; - default: - assert(0); - } - const auto orig_act_pos=uint32_t(tt_pos+(-index*tt_encoding_size)); - auto act_pos=uint32_t(tt_pos+(-index*tt_encoding_size)); - if(this->read_type_with_encoding(tt_encoding_sans_indir_sans_pcrel, pointer_to_typeinfo, act_pos, data, max, data_addr)) - return true; - - // check if there's a 0 in the field - if(pointer_to_typeinfo != 0 && has_pcrel) - pointer_to_typeinfo += orig_act_pos + data_addr; - - return false; -} - - -template <int ptrsize> -void lsda_type_table_entry_t<ptrsize>::print() const -{ - cout<<" pointer_to_typeinfo: 0x"<<hex<<pointer_to_typeinfo<<endl; -} - - - - -template <int ptrsize> -lsda_call_site_t<ptrsize>::lsda_call_site_t() : - call_site_offset(0), - call_site_addr(0), - call_site_length(0), - call_site_end_addr(0), - landing_pad_offset(0), - landing_pad_addr(0), - action(0), - action_table_offset(0), - action_table_addr(0) -{} - - - -template <int ptrsize> -bool lsda_call_site_t<ptrsize>::parse_lcs( - const uint64_t action_table_start_addr, - const uint64_t cs_table_start_addr, - const uint8_t cs_table_encoding, - uint32_t &pos, - const uint8_t* const data, - const uint64_t max, /* call site table max */ - const uint64_t data_addr, - const uint64_t landing_pad_base_addr, - const uint64_t gcc_except_table_max) -{ - - if(this->read_type_with_encoding(cs_table_encoding, call_site_offset, pos, data, max, data_addr)) - return true; - call_site_addr=landing_pad_base_addr+call_site_offset; - if(this->read_type_with_encoding(cs_table_encoding, call_site_length, pos, data, max, data_addr)) - return true; - call_site_end_addr=call_site_addr+call_site_length; - if(this->read_type_with_encoding(cs_table_encoding, landing_pad_offset, pos, data, max, data_addr)) - return true; - - // calc the actual addr. - if(landing_pad_offset == 0) - landing_pad_addr=0; - else - landing_pad_addr=landing_pad_base_addr+landing_pad_offset; - - if(this->read_uleb128(action, pos, data, max)) - return true; - - if(action == 0) - { /* no action table -- means no cleanup is needed, just unwinding. */ } - else if( action > 0 ) - { - action_table_offset=action-1; - action_table_addr=action_table_start_addr+action-1; - - // parse action tables - bool end=false; - auto act_table_pos=uint32_t(action_table_addr-data_addr); - while(!end) - { - lsda_call_site_action_t<ptrsize> lcsa; - if(lcsa.parse_lcsa(act_table_pos, data, gcc_except_table_max, end)) - return true; - action_table.push_back(lcsa); - - } - } - else if( action < 0 ) - { - assert(0); // how can the index into the action table be negative? - } - else - { - assert(0); // how is this possible? - } - - return false; -} - - -template <int ptrsize> -void lsda_call_site_t<ptrsize>::print() const -{ - cout<<" CS Offset : 0x"<<hex<<call_site_offset<<endl; - cout<<" CS len : 0x"<<hex<<call_site_length<<endl; - cout<<" landing pad off. : 0x"<<hex<<landing_pad_offset<<endl; - cout<<" action (1+addr) : 0x"<<hex<<action<<endl; - cout<<" ---interpreted---"<<endl; - cout<<" CS Addr : 0x"<<hex<<call_site_addr<<endl; - cout<<" CS End Addr : 0x"<<hex<<call_site_end_addr<<endl; - cout<<" landing pad addr : 0x"<<hex<<landing_pad_addr<<endl; - cout<<" act-tab off : 0x"<<hex<<action_table_offset<<endl; - cout<<" act-tab addr : 0x"<<hex<<action_table_addr<<endl; - cout<<" act-tab : "<<endl; - for_each(action_table.begin(), action_table.end(), [&](const lsda_call_site_action_t<ptrsize>& p) - { - p.print(); - }); -} - - -template <int ptrsize> -bool lsda_call_site_t<ptrsize>::appliesTo(const Instruction_t* insn) const +bool split_eh_frame_impl_t<ptrsize>::lsda_call_site_appliesTo(const LSDACallSite_t& cs, const Instruction_t* insn) { assert(insn && insn->GetAddress()); auto insn_addr=insn->GetAddress()->GetVirtualOffset(); + const auto call_site_addr=cs.getCallSiteAddress(); + const auto call_site_end_addr=cs.getCallSiteEndAddress(); + return ( call_site_addr <=insn_addr && insn_addr<call_site_end_addr ); } - template <int ptrsize> -void lsda_call_site_t<ptrsize>::build_ir(Instruction_t* insn, const vector<lsda_type_table_entry_t <ptrsize> > &type_table, const uint8_t& tt_encoding, const OffsetMap_t& om, FileIR_t* firp) const +void split_eh_frame_impl_t<ptrsize>::lsda_call_site_build_ir + ( + const LSDACallSite_t& cs, + Instruction_t* insn, + const /*vector<lsda_type_table_entry_t <ptrsize> > &*/ std::shared_ptr<EHP::TypeTableVector_t> type_table_ptr, + const uint8_t& tt_encoding + ) { - assert(appliesTo(insn)); + const auto &type_table=*type_table_ptr; + const auto &om=offset_to_insn_map; + const auto landing_pad_addr=cs.getLandingPadAddress(); + const auto action_table_ptr=cs.getActionTable(); + const auto &action_table=*action_table_ptr; + assert(lsda_call_site_appliesTo(cs,insn)); // find landing pad instruction. auto lp_insn=(Instruction_t*)NULL; @@ -1280,9 +70,9 @@ void lsda_call_site_t<ptrsize>::build_ir(Instruction_t* insn, const vector<lsda_ } else { - for_each(action_table.begin(), action_table.end(), [&](const lsda_call_site_action_t<ptrsize>& p) + for_each(action_table.begin(), action_table.end(), [&](const shared_ptr<LSDACallSiteAction_t>& p) { - const auto action=p.GetAction(); + const auto action=p->getAction(); if(action==0) { new_ehcs->GetTTOrderVector().push_back(action); @@ -1296,15 +86,15 @@ void lsda_call_site_t<ptrsize>::build_ir(Instruction_t* insn, const vector<lsda_ // the type table reveral was done during parsing, type table is right-side-up now. //type_table.at(index).print(); auto wrt=(DataScoop_t*)NULL; - if(type_table.at(index).GetTypeInfoPointer()!=0) + if(type_table.at(index)->getTypeInfoPointer()!=0) { - wrt=firp->FindScoop(type_table.at(index).GetTypeInfoPointer()); + wrt=firp->FindScoop(type_table.at(index)->getTypeInfoPointer()); assert(wrt); } - const auto offset=index*type_table.at(index).GetTTEncodingSize(); + const auto offset=index*type_table.at(index)->getTTEncodingSize(); auto addend=0; if(wrt!=NULL) - addend=type_table.at(index).GetTypeInfoPointer()-wrt->GetStart()->GetVirtualOffset(); + addend=type_table.at(index)->getTypeInfoPointer()-wrt->GetStart()->GetVirtualOffset(); auto newreloc=new Relocation_t(BaseObj_t::NOT_IN_DATABASE, offset, "type_table_entry", wrt, addend); new_ehcs->GetRelocations().insert(newreloc); firp->GetRelocations().insert(newreloc); @@ -1337,183 +127,23 @@ void lsda_call_site_t<ptrsize>::build_ir(Instruction_t* insn, const vector<lsda_ } } - -template <int ptrsize> -uint8_t lsda_t<ptrsize>::GetTTEncoding() const { return type_table_encoding; } - -template <int ptrsize> -lsda_t<ptrsize>::lsda_t() : - landing_pad_base_encoding(0), - landing_pad_base_addr(0), - type_table_encoding(0), - type_table_offset(0), - type_table_addr(0), - cs_table_encoding(0), - cs_table_start_offset(0), - cs_table_start_addr(0), - cs_table_length(0), - cs_table_end_addr(0), - action_table_start_addr(0) -{} - -template <int ptrsize> -bool lsda_t<ptrsize>::parse_lsda(const uint64_t lsda_addr, const DataScoop_t* gcc_except_scoop, const uint64_t fde_region_start) -{ - // make sure there's a scoop and that we're in the range. - if(!gcc_except_scoop) - return true; - if(lsda_addr<gcc_except_scoop->GetStart()->GetVirtualOffset()) - return true; - if(lsda_addr>=gcc_except_scoop->GetEnd()->GetVirtualOffset()) - return true; - - const auto &data=gcc_except_scoop->GetContents(); - const auto data_addr=gcc_except_scoop->GetStart()->GetVirtualOffset(); - const auto max=gcc_except_scoop->GetContents().size(); - auto pos=uint32_t(lsda_addr-data_addr); - auto start_pos=pos; - - if(this->read_type(landing_pad_base_encoding, pos, (const uint8_t* const)data.data(), max)) - return true; - if(landing_pad_base_encoding!=DW_EH_PE_omit) - { - if(this->read_type_with_encoding(landing_pad_base_encoding,landing_pad_base_addr, pos, (const uint8_t* const)data.data(), max, data_addr)) - return true; - } - else - landing_pad_base_addr=fde_region_start; - - if(this->read_type(type_table_encoding, pos, (const uint8_t* const)data.data(), max)) - return true; - - auto type_table_pos=0; - if(type_table_encoding!=DW_EH_PE_omit) - { - if(this->read_uleb128(type_table_offset, pos, (const uint8_t* const)data.data(), max)) - return true; - type_table_addr=lsda_addr+type_table_offset+(pos-start_pos); - type_table_pos=pos+type_table_offset; - } - else - type_table_addr=0; - - if(this->read_type(cs_table_encoding, pos, (const uint8_t* const)data.data(), max)) - return true; - - if(this->read_uleb128(cs_table_length, pos, (const uint8_t* const)data.data(), max)) - return true; - - auto cs_table_end=pos+cs_table_length; - //auto cs_table_start_pos=pos; - cs_table_start_offset=pos; - cs_table_start_addr=lsda_addr+pos-start_pos; - cs_table_end_addr=cs_table_start_addr+cs_table_length; - - // action table comes immediately after the call site table. - action_table_start_addr=cs_table_start_addr+cs_table_length; - while(1) - { - lsda_call_site_t<ptrsize> lcs; - if(lcs.parse_lcs(action_table_start_addr, - cs_table_start_addr,cs_table_encoding, pos, (const uint8_t* const)data.data(), cs_table_end, data_addr, landing_pad_base_addr, max)) - { - return true; - } - - call_site_table.push_back(lcs); - - if(pos>=cs_table_end) - break; - } - - if(type_table_encoding!=DW_EH_PE_omit) - { - for(const auto cs_tab_entry : call_site_table) - { - for(const auto act_tab_entry : cs_tab_entry.GetActionTable()) - { - const auto type_filter=act_tab_entry.GetAction(); - const auto parse_and_insert_tt_entry = [&] (const unsigned long index) -> bool - { - // cout<<"Parsing TypeTable at -"<<index<<endl; - // 1-based indexing because of odd backwards indexing of type table. - lsda_type_table_entry_t <ptrsize> ltte; - if(ltte.parse(type_table_encoding, type_table_pos, index, (const uint8_t* const)data.data(), max, data_addr )) - return true; - type_table.resize(std::max(index,type_table.size())); - type_table.at(index-1)=ltte; - return false; - }; - - if(type_filter==0) - { - // type-filter==0 means no TT entry in the action table. - } - else if(type_filter>0) - { - // type_filter > 0 indicates singleton type table entry - if(parse_and_insert_tt_entry(type_filter)) - return true; - } - else if(type_filter<0) - { - // a type filter < 0 indicates a dynamic exception specification is in play. - // these are not common and even less likely to be needed for correct execution. - // we ignore for now. A warning is printed if they are found in build_ir. - } - else - assert(0); - - }; - - }; - - } - - return false; -} - template <int ptrsize> -void lsda_t<ptrsize>::print() const +void split_eh_frame_impl_t<ptrsize>::lsda_build_ir(const LSDA_t& lsda, Instruction_t* insn) { - cout<<" LSDA:"<<endl; - cout<<" LP base encoding : 0x"<<hex<<+landing_pad_base_encoding<<endl; - cout<<" LP base addr : 0x"<<hex<<+landing_pad_base_addr<<endl; - cout<<" TypeTable encoding : 0x"<<hex<<+type_table_encoding<<endl; - cout<<" TypeTable offset : 0x"<<hex<<type_table_offset<<endl; - cout<<" TypeTable addr : 0x"<<hex<<+type_table_addr<<endl; - cout<<" CS tab encoding : 0x"<<hex<<+cs_table_encoding<<endl; - cout<<" CS tab addr : 0x"<<hex<<+cs_table_start_addr<<endl; - cout<<" CS tab offset : 0x"<<hex<<+cs_table_start_offset<<endl; - cout<<" CS tab length : 0x"<<hex<<+cs_table_length<<endl; - cout<<" CS tab end addr : 0x"<<hex<<+cs_table_end_addr<<endl; - cout<<" Act tab start_addr : 0x"<<hex<<+action_table_start_addr<<endl; - cout<<" CS tab :"<<endl; - int i=0; - for_each(call_site_table.begin(), call_site_table.end(), [&](const lsda_call_site_t<ptrsize>& p) - { - cout<<" [ "<<hex<<i++<<"] call site table entry "<<endl; - p.print(); - }); - i=0; - for_each(type_table.begin(), type_table.end(), [&](const lsda_type_table_entry_t<ptrsize>& p) - { - cout<<" [ -"<<dec<<++i<<"] Type table entry "<<endl; - p.print(); - }); -} + const auto call_site_table_ptr=lsda.getCallSites(); + const auto& call_site_table=*call_site_table_ptr; + const auto& type_table_ptr=lsda.getTypeTable(); +// auto& type_table=*type_table_ptr; -template <int ptrsize> -void lsda_t<ptrsize>::build_ir(Instruction_t* insn, const OffsetMap_t& om, FileIR_t* firp) const -{ - auto cs_it=find_if(call_site_table.begin(), call_site_table.end(), [&](const lsda_call_site_t<ptrsize>& p) + const auto cs_ptr_it=find_if(ALLOF(call_site_table), [&](const shared_ptr<LSDACallSite_t> &p) { - return p.appliesTo(insn); + return lsda_call_site_appliesTo(*p, insn); }); - if(cs_it!= call_site_table.end()) + if(cs_ptr_it!= call_site_table.end()) { - cs_it->build_ir(insn, type_table, GetTTEncoding(), om, firp); + const auto cs_ptr=*cs_ptr_it; + lsda_call_site_build_ir(*cs_ptr,insn, type_table_ptr, lsda.getTTEncoding()); } else { @@ -1521,212 +151,45 @@ void lsda_t<ptrsize>::build_ir(Instruction_t* insn, const OffsetMap_t& om, FileI } } - -template <int ptrsize> -fde_contents_t<ptrsize>::fde_contents_t() : - fde_position(0), - cie_position(0), - length(0), - id(0), - fde_start_addr(0), - fde_end_addr(0), - fde_range_len(0), - lsda_addr(0) -{} - - template <int ptrsize> -bool fde_contents_t<ptrsize>::appliesTo(const Instruction_t* insn) const +bool split_eh_frame_impl_t<ptrsize>::fde_contents_appliesTo(const FDEContents_t& fde, const Instruction_t* insn) { assert(insn && insn->GetAddress()); auto insn_addr=insn->GetAddress()->GetVirtualOffset(); - + const auto fde_start_addr=fde.getStartAddress(); + const auto fde_end_addr=fde.getEndAddress(); return ( fde_start_addr<=insn_addr && insn_addr<fde_end_addr ); } template <int ptrsize> -const cie_contents_t<ptrsize>& fde_contents_t<ptrsize>::GetCIE() const { return cie_info; } - -template <int ptrsize> -cie_contents_t<ptrsize>& fde_contents_t<ptrsize>::GetCIE() { return cie_info; } - -template <int ptrsize> -const eh_program_t<ptrsize>& fde_contents_t<ptrsize>::GetProgram() const { return eh_pgm; } - -template <int ptrsize> -eh_program_t<ptrsize>& fde_contents_t<ptrsize>::GetProgram() { return eh_pgm; } - -template <int ptrsize> -bool fde_contents_t<ptrsize>::parse_fde( - const uint32_t &fde_position, - const uint32_t &cie_position, - const uint8_t* const data, - const uint64_t max, - const uint64_t eh_addr, - const DataScoop_t* gcc_except_scoop) -{ - auto &c=*this; - const auto eh_frame_scoop_data=data; - - if(cie_info.parse_cie(cie_position, data, max, eh_addr)) - return true; - - auto pos=fde_position; - auto length=uint64_t(0); - if(this->read_length(length, pos, eh_frame_scoop_data, max)) - return true; - - - auto end_pos=pos+length; - //auto end_length_position=pos; - - auto cie_id=uint32_t(0); - if(this->read_type(cie_id, pos, eh_frame_scoop_data, max)) - return true; - - auto fde_start_addr=uint64_t(0); - if(this->read_type_with_encoding(c.GetCIE().GetFDEEncoding(),fde_start_addr, pos, eh_frame_scoop_data, max, eh_addr)) - return true; - - auto fde_range_len=uint64_t(0); - if(this->read_type_with_encoding(c.GetCIE().GetFDEEncoding() & 0xf /* drop pc-rel bits */,fde_range_len, pos, eh_frame_scoop_data, max, eh_addr)) - return true; - - auto fde_end_addr=fde_start_addr+fde_range_len; - - auto augmentation_data_length=uint64_t(0); - if(c.GetCIE().GetAugmentation().find("z") != string::npos) - { - if(this->read_uleb128(augmentation_data_length, pos, eh_frame_scoop_data, max)) - return true; - } - auto lsda_addr=uint64_t(0); - if(c.GetCIE().GetLSDAEncoding()!= DW_EH_PE_omit) - { - if(this->read_type_with_encoding(c.GetCIE().GetLSDAEncoding(), lsda_addr, pos, eh_frame_scoop_data, max, eh_addr)) - return true; - if(c.lsda.parse_lsda(lsda_addr,gcc_except_scoop, fde_start_addr)) - return true; - } - - if(c.eh_pgm.parse_program(pos, eh_frame_scoop_data, end_pos)) - return true; - - c.fde_position=fde_position; - c.cie_position=cie_position; - c.length=length; - c.id=id; - c.fde_start_addr=fde_start_addr; - c.fde_end_addr=fde_end_addr; - c.fde_range_len=fde_range_len; - c.lsda_addr=lsda_addr; - - return false; -} - -template <int ptrsize> -void fde_contents_t<ptrsize>::print() const -{ - - cout << "["<<setw(6)<<hex<<fde_position<<"] FDE length="<<dec<<length; - cout <<" cie=["<<setw(6)<<hex<<cie_position<<"]"<<endl; - cout<<" FDE len addr: "<<dec<<length<<endl; - cout<<" FDE Start addr: "<<hex<<fde_start_addr<<endl; - cout<<" FDE End addr: "<<hex<<fde_end_addr<<endl; - cout<<" FDE len: "<<dec<<fde_range_len<<endl; - cout<<" FDE LSDA: "<<hex<<lsda_addr<<endl; - eh_pgm.print(fde_start_addr); - if(GetCIE().GetLSDAEncoding()!= DW_EH_PE_omit) - lsda.print(); - else - cout<<" No LSDA for this FDE."<<endl; -} - -template <int ptrsize> -void fde_contents_t<ptrsize>::build_ir(Instruction_t* insn, const OffsetMap_t &om, FileIR_t* firp) const +void split_eh_frame_impl_t<ptrsize>::fde_contents_build_ir(const FDEContents_t& fde, Instruction_t* insn) { + const auto fde_start_addr=fde.getStartAddress(); + const auto fde_end_addr=fde.getEndAddress(); + const auto lsda_ptr=fde.getLSDA(); + const auto &lsda=*lsda_ptr; + const auto lsda_addr=fde.getLSDAAddress(); + // assert this is the right FDE. assert( fde_start_addr<= insn->GetAddress()->GetVirtualOffset() && insn->GetAddress()->GetVirtualOffset() <= fde_end_addr); //eh_pgm.print(fde_start_addr); if(lsda_addr!=0) - lsda.build_ir(insn,om,firp); + lsda_build_ir(lsda,insn); } - - - template <int ptrsize> bool split_eh_frame_impl_t<ptrsize>::init_offset_map() { - for_each(firp->GetInstructions().begin(), firp->GetInstructions().end(), [&](Instruction_t* i) + //for_each(firp->GetInstructions().begin(), firp->GetInstructions().end(), [&](Instruction_t* i) + for(const auto i : firp->GetInstructions()) { offset_to_insn_map[i->GetAddress()->GetVirtualOffset()]=i; - }); - return false; -} - - -template <int ptrsize> -bool split_eh_frame_impl_t<ptrsize>::iterate_fdes() -{ - auto eh_frame_scoop_data=(const uint8_t* const)eh_frame_scoop->GetContents().c_str(); - auto data=eh_frame_scoop_data; - auto eh_addr= eh_frame_scoop->GetStart()->GetVirtualOffset(); - auto max=eh_frame_scoop->GetContents().size(); - auto position=uint32_t(0); - - //cout << "----------------------------------------"<<endl; - while(1) - { - auto old_position=position; - auto act_length=uint64_t(0); - - if(eh_frame_util_t<ptrsize>::read_length(act_length, position, eh_frame_scoop_data, max)) - break; - - auto next_position=position + act_length; - auto cie_offset=uint32_t(0); - auto cie_offset_position=position; - - if(eh_frame_util_t<ptrsize>::read_type(cie_offset,position, eh_frame_scoop_data, max)) - break; - - //cout << " [ " << setw(6) << hex << old_position << "] " ; - if(act_length==0) - { - //cout << "Zero terminator " << endl; - break; - } - else if(cie_offset==0) - { - //cout << "CIE length="<< dec << act_length << endl; - cie_contents_t<ptrsize> c; - if(c.parse_cie(old_position, data, max, eh_addr)) - return true; - cies.push_back(c); - } - else - { - fde_contents_t<ptrsize> f; - auto cie_position = cie_offset_position - cie_offset; - //cout << "FDE length="<< dec << act_length << " cie=[" << setw(6) << hex << cie_position << "]" << endl; - if(f.parse_fde(old_position, cie_position, data, max, eh_addr, gcc_except_table_scoop)) - return true; - //const auto old_fde_size=fdes.size(); - fdes.insert(f); - } - //cout << "----------------------------------------"<<endl; - - - // next CIE/FDE - assert(position<=next_position); // so we don't accidentally over-read a CIE/FDE - position=next_position; - } + }; return false; } - +#if 0 template <int ptrsize> split_eh_frame_impl_t<ptrsize>::split_eh_frame_impl_t(FileIR_t* p_firp) : firp(p_firp), @@ -1754,43 +217,14 @@ split_eh_frame_impl_t<ptrsize>::split_eh_frame_impl_t(FileIR_t* p_firp) gcc_except_table_scoop=lookup_scoop_by_name(".gcc_except_table"); } - - -template <int ptrsize> -bool split_eh_frame_impl_t<ptrsize>::parse() -{ - if(eh_frame_scoop==NULL) - return true; // no frame info in this binary - - - if(init_offset_map()) - return true; - - if(iterate_fdes()) - return true; - - return false; -} - - -template <int ptrsize> -void split_eh_frame_impl_t<ptrsize>::print() const -{ - for_each(cies.begin(), cies.end(), [&](const cie_contents_t<ptrsize> &p) - { - p.print(); - }); - for_each(fdes.begin(), fdes.end(), [&](const fde_contents_t<ptrsize> &p) - { - p.print(); - }); -} - +#endif template <int ptrsize> void split_eh_frame_impl_t<ptrsize>::build_ir() const { typedef pair<EhProgram_t*,uint64_t> whole_pgm_t; + //const auto fdes_ptr=eh_frame_parser->getFDEs(); + //const auto &fdes=*fdes_ptr; auto reusedpgms=size_t(0); struct EhProgramComparator_t { @@ -1806,33 +240,46 @@ void split_eh_frame_impl_t<ptrsize>::build_ir() const // find the right cie and fde, and build the IR from those for this instruction. auto build_ir_insn=[&](Instruction_t* insn) -> void { + /* const auto tofind=fde_contents_t<ptrsize>( insn->GetAddress()->GetVirtualOffset(), insn->GetAddress()->GetVirtualOffset()+1 ); const auto fie_it=fdes.find(tofind); + */ + const auto find_addr=insn->GetAddress()->GetVirtualOffset(); + const auto fie_ptr_it=find_if + ( + ALLOF(*fdes), + [&](const shared_ptr<FDEContents_t>& fde) { return fde->getStartAddress() <= find_addr && find_addr < fde->getEndAddress(); } + ); - if(fie_it!=fdes.end()) + if(fie_ptr_it!=fdes->end()) { + const auto fie_ptr=*fie_ptr_it; if(getenv("EHIR_VERBOSE")!=NULL) { cout<<hex<<insn->GetAddress()->GetVirtualOffset()<<":" <<insn->GetBaseID()<<":"<<insn->getDisassembly()<<" -> "<<endl; //fie_it->GetCIE().print(); - fie_it->print(); + fie_ptr->print(); } - const auto fde_addr=fie_it->GetFDEStartAddress(); - const auto caf=fie_it->GetCIE().GetCAF(); - const auto daf=fie_it->GetCIE().GetDAF(); - const auto return_reg=fie_it->GetCIE().GetReturnRegister(); - const auto personality=fie_it->GetCIE().GetPersonality(); + const auto fde_addr=fie_ptr->getStartAddress(); + const auto caf=fie_ptr->getCIE().getCAF(); + const auto daf=fie_ptr->getCIE().getDAF(); + const auto return_reg=fie_ptr->getCIE().getReturnRegister(); + const auto personality=fie_ptr->getCIE().getPersonality(); const auto insn_addr=insn->GetAddress()->GetVirtualOffset(); - auto import_pgm = [&](EhProgramListing_t& out_pgm, const eh_program_t<ptrsize> in_pgm) -> void + auto import_pgm = [&](EhProgramListing_t& out_pgm_final, const EHProgram_t& in_pgm) -> void { + auto out_pgm=vector<shared_ptr<EHProgramInstruction_t> >(); auto cur_addr=fde_addr; - for(const auto & insn : in_pgm.GetInstructions()) + const auto in_pgm_instructions_ptr=in_pgm.getInstructions(); + const auto in_pgm_instructions=*in_pgm_instructions_ptr; + for(const auto & insn_ptr : in_pgm_instructions) { - if(insn.Advance(cur_addr, caf)) + const auto & insn=*insn_ptr; + if(insn.advance(cur_addr, caf)) { if(cur_addr > insn_addr) break; @@ -1853,17 +300,18 @@ void split_eh_frame_impl_t<ptrsize>::build_ir() const cerr<<"Error in CIE/FDE program: unmatched restore_state command"<<endl; break; } - const auto back_str=out_pgm.back(); + const auto back_insn=out_pgm.back(); out_pgm.pop_back(); - const auto back_insn=eh_program_insn_t<ptrsize>(back_str); - if(back_insn.isRememberState()) + //const auto back_insn=eh_program_insn_t<ptrsize>(back_str); + if(back_insn->isRememberState()) break; } } else { - string to_push(insn.GetBytes().begin(),insn.GetBytes().end()); - out_pgm.push_back(to_push); + // string to_push(insn.GetBytes().begin(),insn.GetBytes().end()); + // out_pgm.push_back(to_push); + out_pgm.push_back(insn_ptr); } } @@ -1871,13 +319,19 @@ void split_eh_frame_impl_t<ptrsize>::build_ir() const { cout<<"\tPgm has insn_count="<<out_pgm.size()<<endl; } + transform + ( + ALLOF(out_pgm), + back_inserter(out_pgm_final), + [](const shared_ptr<EHProgramInstruction_t>& p){ return string(ALLOF(p->getBytes()));} + ); }; // build an eh program on the stack; auto ehpgm=EhProgram_t(BaseObj_t::NOT_IN_DATABASE,caf,daf,return_reg, ptrsize); - import_pgm(ehpgm.GetCIEProgram(), fie_it->GetCIE().GetProgram()); - import_pgm(ehpgm.GetFDEProgram(), fie_it->GetProgram()); + import_pgm(ehpgm.GetCIEProgram(), fie_ptr->getCIE().getProgram()); + import_pgm(ehpgm.GetFDEProgram(), fie_ptr->getProgram()); if(getenv("EHIR_VERBOSE")!=NULL) @@ -1945,8 +399,7 @@ void split_eh_frame_impl_t<ptrsize>::build_ir() const } // build the IR from the FDE. - fie_it->GetCIE().build_ir(insn); - fie_it->build_ir(insn, offset_to_insn_map,firp); + fde_contents_build_ir(*fie_ptr.get(), insn); } else { @@ -2006,24 +459,35 @@ void split_eh_frame_impl_t<ptrsize>::build_ir() const template <int ptrsize> libIRDB::Instruction_t* split_eh_frame_impl_t<ptrsize>::find_lp(libIRDB::Instruction_t* i) const { - const auto tofind=fde_contents_t<ptrsize>( i->GetAddress()->GetVirtualOffset(), i->GetAddress()->GetVirtualOffset()+1); - const auto fde_it=fdes.find(tofind); + //const auto tofind=fde_contents_t<ptrsize>( i->GetAddress()->GetVirtualOffset(), i->GetAddress()->GetVirtualOffset()+1); + //const auto fde_it=fdes.find(tofind); + const auto find_addr=i->GetAddress()->GetVirtualOffset(); + const auto fde_ptr_it=find_if + ( + ALLOF(*fdes), + [&](const shared_ptr<FDEContents_t>& fde) { return fde->getStartAddress() <= find_addr && find_addr < fde->getEndAddress(); } + ); - if(fde_it==fdes.end()) + if(fde_ptr_it==fdes->end()) return NULL; + + const auto fde_ptr=*fde_ptr_it; - const auto &the_fde=*fde_it; - const auto &the_lsda=the_fde.GetLSDA(); - const auto &cstab = the_lsda.GetCallSites(); + const auto &the_fde=*fde_ptr; + const auto &the_lsda_ptr=the_fde.getLSDA(); + const auto &the_lsda=*the_lsda_ptr; + const auto &cstab_ptr = the_lsda.getCallSites(); + const auto &cstab = *cstab_ptr; - const auto cstab_it=find_if(cstab.begin(), cstab.end(), [&](const lsda_call_site_t <ptrsize>& cs) - { return cs.appliesTo(i); }); + const auto cstab_it=find_if(ALLOF(cstab), [&](const shared_ptr<LSDACallSite_t>& cs) + { return lsda_call_site_appliesTo(*cs,i); }); if(cstab_it==cstab.end()) return NULL; - const auto &the_cstab_entry=*cstab_it; - const auto lp_addr= the_cstab_entry.GetLandingPadAddress(); + const auto &the_cstab_entry_ptr=*cstab_it; + const auto &the_cstab_entry=*the_cstab_entry_ptr; + const auto lp_addr= the_cstab_entry.getLandingPadAddress(); const auto om_it=offset_to_insn_map.find(lp_addr); @@ -2034,6 +498,51 @@ libIRDB::Instruction_t* split_eh_frame_impl_t<ptrsize>::find_lp(libIRDB::Instruc return lp; } +template <int ptrsize> +void split_eh_frame_impl_t<ptrsize>::print() const +{ + eh_frame_parser->print(); +} + +template <int ptrsize> +split_eh_frame_impl_t<ptrsize>::split_eh_frame_impl_t(FileIR_t* p_firp) + : firp(p_firp), + eh_frame_scoop(NULL), + eh_frame_hdr_scoop(NULL), + gcc_except_table_scoop(NULL) +{ + assert(firp!=NULL); + + // function to find a scoop by name. + auto lookup_scoop_by_name=[&](const string &name) -> DataScoop_t* + { + auto scoop_it=find_if(firp->GetDataScoops().begin(), firp->GetDataScoops().end(), [name](DataScoop_t* scoop) + { + return scoop->GetName()==name; + }); + + if(scoop_it!=firp->GetDataScoops().end()) + return *scoop_it; + return NULL; + }; + auto scoop_address=[&](const DataScoop_t* p) -> uint64_t { return p==NULL ? 0 : p->GetStart()->GetVirtualOffset(); }; + auto scoop_contents=[&](const DataScoop_t* p) -> string { return p==NULL ? "" : p->GetContents(); }; + + eh_frame_scoop=lookup_scoop_by_name(".eh_frame"); + eh_frame_hdr_scoop=lookup_scoop_by_name(".eh_frame_hdr"); + gcc_except_table_scoop=lookup_scoop_by_name(".gcc_except_table"); + + eh_frame_parser=EHFrameParser_t::factory + ( + ptrsize, + scoop_contents(eh_frame_scoop), scoop_address(eh_frame_scoop), + scoop_contents(eh_frame_hdr_scoop), scoop_address(eh_frame_hdr_scoop), + scoop_contents(gcc_except_table_scoop), scoop_address(gcc_except_table_scoop) + ); + + if(eh_frame_parser!=NULL) + fdes=eh_frame_parser->getFDEs(); +} unique_ptr<split_eh_frame_t> split_eh_frame_t::factory(FileIR_t *firp) { @@ -2049,7 +558,6 @@ void split_eh_frame(FileIR_t* firp) auto found_err=false; //auto eh_frame_splitter=(unique_ptr<split_eh_frame_t>)NULL; const auto eh_frame_splitter=split_eh_frame_t::factory(firp); - found_err=eh_frame_splitter->parse(); eh_frame_splitter->build_ir(); assert(!found_err); diff --git a/libIRDB/test/split_eh_frame.hpp b/libIRDB/test/split_eh_frame.hpp new file mode 100644 index 000000000..17a082e75 --- /dev/null +++ b/libIRDB/test/split_eh_frame.hpp @@ -0,0 +1,95 @@ +#ifndef eh_frame_hpp +#define eh_frame_hpp + +#include <libIRDB-core.hpp> +#include <iostream> +#include <iomanip> +#include <fstream> +#include <limits> +#include <stdlib.h> +#include <string.h> +#include <map> +#include <assert.h> +#include <elf.h> +#include <algorithm> +#include <memory> + +#include <exeio.h> +#include <ehp.hpp> + + + + +using OffsetMap_t = std::map<libIRDB::virtual_offset_t, libIRDB::Instruction_t*>; + +class split_eh_frame_t +{ + public: + + virtual void build_ir() const =0; + virtual void print() const=0; + virtual libIRDB::Instruction_t* find_lp(libIRDB::Instruction_t*) const =0; + + static std::unique_ptr<split_eh_frame_t> factory(libIRDB::FileIR_t *firp); + +}; + +template <int ptrsize> +class split_eh_frame_impl_t : public split_eh_frame_t +{ + private: + + libIRDB::FileIR_t* firp; + libIRDB::DataScoop_t* eh_frame_scoop; + libIRDB::DataScoop_t* eh_frame_hdr_scoop; + libIRDB::DataScoop_t* gcc_except_table_scoop; + OffsetMap_t offset_to_insn_map; + + std::unique_ptr<const EHP::EHFrameParser_t> eh_frame_parser; + std::shared_ptr<const EHP::FDEVector_t> fdes; + + bool init_offset_map(); + + bool lsda_call_site_appliesTo + ( + const EHP::LSDACallSite_t& cs, + const libIRDB::Instruction_t* insn + ); + void lsda_call_site_build_ir + ( + const EHP::LSDACallSite_t& cs, + libIRDB::Instruction_t* insn, + /* const std::vector<lsda_type_table_entry_t <ptrsize> > &*/ std::shared_ptr<EHP::TypeTableVector_t> type_table_ptr, + const uint8_t& tt_encoding + ); + void lsda_build_ir + ( + const EHP::LSDA_t& lsda, + libIRDB::Instruction_t* insn + ); + bool fde_contents_appliesTo + ( + const EHP::FDEContents_t& fde, + const libIRDB::Instruction_t* insn + ); + void fde_contents_build_ir + ( + const EHP::FDEContents_t& fde, + libIRDB::Instruction_t* insn + ); + + public: + + split_eh_frame_impl_t(libIRDB::FileIR_t* p_firp); + + + void print() const; + + void build_ir() const; + + libIRDB::Instruction_t* find_lp(libIRDB::Instruction_t*) const ; +}; + +void split_eh_frame(libIRDB::FileIR_t* firp); + +#endif diff --git a/libehp b/libehp index 59da9c4c4..ff803c45b 160000 --- a/libehp +++ b/libehp @@ -1 +1 @@ -Subproject commit 59da9c4c4856423c6e7a2add814c7c2f5efd26f1 +Subproject commit ff803c45b1c258130b6f4348a8d977afa4fb87f0 -- GitLab