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