Merge from amd64-branch:
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Fri, 1 May 2009 12:31:02 +0000 (12:31 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Fri, 1 May 2009 12:31:02 +0000 (12:31 +0000)
37291, 3730, 37305, 37320, 37329, 37462, 37895, 38129, 38330, 38331, 38341, 38947, 38973, 39072, 39114, 39121, 40605
Implement rsym64 (Timo Kreuzer)

svn path=/trunk/; revision=40759

1  2 
reactos/tools/raddr2line.c
reactos/tools/rsym/dwarf2.h
reactos/tools/rsym/rsym.h
reactos/tools/rsym/rsym64.c
reactos/tools/rsym/rsym64.h

@@@ -18,8 -18,8 +18,8 @@@
  
  size_t fixup_offset ( size_t ImageBase, size_t offset )
  {
--      if ( offset >= ImageBase )
--              offset -= ImageBase;
++//    if ( offset >= ImageBase )
++//            offset -= ImageBase;
        return offset;
  }
  
index 0000000,18ff034..04b6237
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,832 +1,844 @@@
 -    ULONG Length;
+ /* Declarations and definitions of codes relating to the DWARF2 symbolic
+    debugging information format.
+    Copyright (C) 1992, 1993, 1995, 1996, 1997, 1999, 2000, 2001, 2002,
+    2003, 2004 Free Software Foundation, Inc.
+    Written by Gary Funck (gary@intrepid.com) The Ada Joint Program
+    Office (AJPO), Florida State University and Silicon Graphics Inc.
+    provided support for this effort -- June 21, 1995.
+    Derived from the DWARF 1 implementation written by Ron Guilmette
+    (rfg@netcom.com), November 1990.
+    This file is part of GCC.
+    GCC is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License as published by the Free
+    Software Foundation; either version 2, or (at your option) any later
+    version.
+    GCC 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 General Public
+    License for more details.
+    You should have received a copy of the GNU General Public License
+    along with GCC; see the file COPYING.  If not, write to the Free
+    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+    02111-1307, USA.  */
+ /* 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 also now contains definitions from the DWARF 3 specification.  */
+ /* This file is shared between GCC and GDB, and should not contain
+    prototypes.  */
+ #ifndef GCC_DWARF2_H
+ #define GCC_DWARF2_H
+ //#include "list.h"
+ #include <pshpack1.h>
+ /* Structure found in the .debug_line section.  */
+ typedef struct
+ {
+   unsigned char li_length          [4];
+   unsigned char li_version         [2];
+   unsigned char li_prologue_length [4];
+   unsigned char li_min_insn_length [1];
+   unsigned char li_default_is_stmt [1];
+   unsigned char li_line_base       [1];
+   unsigned char li_line_range      [1];
+   unsigned char li_opcode_base     [1];
+ }
+ DWARF2_External_LineInfo;
+ typedef struct
+ {
+   unsigned long  li_length;
+   unsigned short li_version;
+   unsigned int   li_prologue_length;
+   unsigned char  li_min_insn_length;
+   unsigned char  li_default_is_stmt;
+   int            li_line_base;
+   unsigned char  li_line_range;
+   unsigned char  li_opcode_base;
+ }
+ DWARF2_Internal_LineInfo;
+ /* Structure found in .debug_pubnames section.  */
+ typedef struct
+ {
+   unsigned char pn_length  [4];
+   unsigned char pn_version [2];
+   unsigned char pn_offset  [4];
+   unsigned char pn_size    [4];
+ }
+ DWARF2_External_PubNames;
+ typedef struct
+ {
+   unsigned long  pn_length;
+   unsigned short pn_version;
+   unsigned long  pn_offset;
+   unsigned long  pn_size;
+ }
+ DWARF2_Internal_PubNames;
+ /* Structure found in .debug_info section.  */
+ typedef struct
+ {
+   unsigned char  cu_length        [4];
+   unsigned char  cu_version       [2];
+   unsigned char  cu_abbrev_offset [4];
+   unsigned char  cu_pointer_size  [1];
+ }
+ DWARF2_External_CompUnit;
+ typedef struct
+ {
+   unsigned long  cu_length;
+   unsigned short cu_version;
+   unsigned long  cu_abbrev_offset;
+   unsigned char  cu_pointer_size;
+ }
+ DWARF2_Internal_CompUnit;
+ typedef struct
+ {
+   unsigned char  ar_length       [4];
+   unsigned char  ar_version      [2];
+   unsigned char  ar_info_offset  [4];
+   unsigned char  ar_pointer_size [1];
+   unsigned char  ar_segment_size [1];
+ }
+ DWARF2_External_ARange;
+ typedef struct
+ {
+   unsigned long  ar_length;
+   unsigned short ar_version;
+   unsigned long  ar_info_offset;
+   unsigned char  ar_pointer_size;
+   unsigned char  ar_segment_size;
+ }
+ DWARF2_Internal_ARange;
+ #include <poppack.h>
+ /* 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,
+     /* DWARF 3.  */
+     DW_TAG_dwarf_procedure = 0x36,
+     DW_TAG_restrict_type = 0x37,
+     DW_TAG_interface_type = 0x38,
+     DW_TAG_namespace = 0x39,
+     DW_TAG_imported_module = 0x3a,
+     DW_TAG_unspecified_type = 0x3b,
+     DW_TAG_partial_unit = 0x3c,
+     DW_TAG_imported_unit = 0x3d,
+     /* SGI/MIPS Extensions.  */
+     DW_TAG_MIPS_loop = 0x4081,
+     /* HP extensions.  See: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz .  */
+     DW_TAG_HP_array_descriptor = 0x4090,
+     /* 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,
+     /* Extensions for UPC.  See: http://upc.gwu.edu/~upc.  */
+     DW_TAG_upc_shared_type = 0x8765,
+     DW_TAG_upc_strict_type = 0x8766,
+     DW_TAG_upc_relaxed_type = 0x8767,
+     /* PGI (STMicroelectronics) extensions.  No documentation available.  */
+     DW_TAG_PGI_kanji_type      = 0xA000,
+     DW_TAG_PGI_interface_block = 0xA020
+   };
+ #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,
+     /* DWARF 3 values.  */
+     DW_AT_allocated     = 0x4e,
+     DW_AT_associated    = 0x4f,
+     DW_AT_data_location = 0x50,
+     DW_AT_stride        = 0x51,
+     DW_AT_entry_pc      = 0x52,
+     DW_AT_use_UTF8      = 0x53,
+     DW_AT_extension     = 0x54,
+     DW_AT_ranges        = 0x55,
+     DW_AT_trampoline    = 0x56,
+     DW_AT_call_column   = 0x57,
+     DW_AT_call_file     = 0x58,
+     DW_AT_call_line     = 0x59,
+     /* 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,
+     /* HP extensions.  */
+     DW_AT_HP_block_index         = 0x2000,
+     DW_AT_HP_unmodifiable        = 0x2001, /* Same as DW_AT_MIPS_fde.  */
+     DW_AT_HP_actuals_stmt_list   = 0x2010,
+     DW_AT_HP_proc_per_section    = 0x2011,
+     DW_AT_HP_raw_data_ptr        = 0x2012,
+     DW_AT_HP_pass_by_reference   = 0x2013,
+     DW_AT_HP_opt_level           = 0x2014,
+     DW_AT_HP_prof_version_id     = 0x2015,
+     DW_AT_HP_opt_flags           = 0x2016,
+     DW_AT_HP_cold_region_low_pc  = 0x2017,
+     DW_AT_HP_cold_region_high_pc = 0x2018,
+     DW_AT_HP_all_variables_modifiable = 0x2019,
+     DW_AT_HP_linkage_name        = 0x201a,
+     DW_AT_HP_prof_flags          = 0x201b,  /* In comp unit of procs_info for -g.  */
+     /* 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,
+     DW_AT_GNU_vector = 0x2107,
+     /* VMS extensions.  */
+     DW_AT_VMS_rtnbeg_pd_address = 0x2201,
+     /* UPC extension.  */
+     DW_AT_upc_threads_scaled = 0x3210,
+     /* PGI (STMicroelectronics) extensions.  */
+     DW_AT_PGI_lbase    = 0x3a00,
+     DW_AT_PGI_soffset  = 0x3a01,
+     DW_AT_PGI_lstride  = 0x3a02
+   };
+ #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,
+     /* DWARF 3 extensions.  */
+     DW_OP_push_object_address = 0x97,
+     DW_OP_call2 = 0x98,
+     DW_OP_call4 = 0x99,
+     DW_OP_call_ref = 0x9a,
+     /* GNU extensions.  */
+     DW_OP_GNU_push_tls_address = 0xe0,
+     /* HP extensions.  */
+     DW_OP_HP_unknown     = 0xe0, /* Ouch, the same as GNU_push_tls_address.  */
+     DW_OP_HP_is_value    = 0xe1,
+     DW_OP_HP_fltconst4   = 0xe2,
+     DW_OP_HP_fltconst8   = 0xe3,
+     DW_OP_HP_mod_range   = 0xe4,
+     DW_OP_HP_unmod_range = 0xe5,
+     DW_OP_HP_tls         = 0xe6
+   };
+ #define DW_OP_lo_user 0xe0    /* 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,
+     /* DWARF 3.  */
+     DW_ATE_imaginary_float = 0x9,
+     /* HP extensions.  */
+     DW_ATE_HP_float80            = 0x80, /* Floating-point (80 bit).  */
+     DW_ATE_HP_complex_float80    = 0x81, /* Complex floating-point (80 bit).  */
+     DW_ATE_HP_float128           = 0x82, /* Floating-point (128 bit).  */
+     DW_ATE_HP_complex_float128   = 0x83, /* Complex floating-point (128 bit).  */
+     DW_ATE_HP_floathpintel       = 0x84, /* Floating-point (82 bit IA64).  */
+     DW_ATE_HP_imaginary_float80  = 0x85,
+     DW_ATE_HP_imaginary_float128 = 0x86
+   };
+ #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,
+     DW_CC_GNU_renesas_sh = 0x40
+   };
+ #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,
+     /* DWARF 3.  */
+     DW_LNS_set_prologue_end = 10,
+     DW_LNS_set_epilogue_begin = 11,
+     DW_LNS_set_isa = 12
+   };
+ /* 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,
+     /* HP extensions.  */
+     DW_LNE_HP_negate_is_UV_update      = 0x11,
+     DW_LNE_HP_push_context             = 0x12,
+     DW_LNE_HP_pop_context              = 0x13,
+     DW_LNE_HP_set_file_line_column     = 0x14,
+     DW_LNE_HP_set_routine_name         = 0x15,
+     DW_LNE_HP_set_sequence             = 0x16,
+     DW_LNE_HP_negate_post_semantics    = 0x17,
+     DW_LNE_HP_negate_function_exit     = 0x18,
+     DW_LNE_HP_negate_front_end_logical = 0x19,
+     DW_LNE_HP_define_proc              = 0x20
+   };
+ /* 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,
+     /* DWARF 3.  */
+     DW_CFA_def_cfa_expression = 0x0f,
+     DW_CFA_expression = 0x10,
+     DW_CFA_offset_extended_sf = 0x11,
+     DW_CFA_def_cfa_sf = 0x12,
+     DW_CFA_def_cfa_offset_sf = 0x13,
+     /* 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_lo_user    0x1c
+ #define DW_CFA_hi_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,
+     /* DWARF 3.  */
+     DW_LANG_C99 = 0x000c,
+     DW_LANG_Ada95 = 0x000d,
+     DW_LANG_Fortran95 = 0x000e,
+     /* MIPS.  */
+     DW_LANG_Mips_Assembler = 0x8001,
+     /* UPC.  */
+     DW_LANG_Upc = 0x8765
+   };
+ #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
+   };
\f
+ /* @@@ 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
+ /** Private definitions ***/
+ typedef struct
+ {
+     ULONG Length;
+     ULONG CiePointer;
+ } DW2CIEFDE;
+ typedef struct
+ {
+     ULONG Length;
+     char *Next;
+     ULONG CieId;
+     char Version;
+     ULONG ReturnAddressRegister;
+     ULONG AugStringLength;
+     char *AugString;
+     ULONG AugLength;
+     char *AugData;
+     ULONG CodeAlign;
+     LONG DataAlign;
+     char *Instructions;
+ } DW2CIE, *PDW2CIE;
+ typedef struct
+ {
 -    ULONG PcBegin;
 -    ULONG PcRange;
 -    ULONG AugLength;
++    unsigned long Length;
+     char *Next;
+     char *CiePointer;
 -    ULONG Location;
 -    ULONG Code;
 -    ULONG Reg;
 -    ULONG Reg2;
 -    ULONG FramePtr;
 -    ULONG FramePtrDiff;
 -    ULONG Offset;
 -    ULONG IsUwop;
 -    ULONG Scope;
++    unsigned long PcBegin;
++    unsigned long PcRange;
++    unsigned long AugLength;
+     char *AugData;
+     char *Instructions;
+ } DW2FDE, *PDW2FDE;
++typedef struct _SEHBLOCK
++{
++    unsigned long BeginTry;
++    unsigned long EndTry;
++    unsigned long Target;
++    unsigned long Handler;
++    unsigned long End;
++} SEHBLOCK, *PSEHBLOCK;
++
+ typedef struct _CFSTATE
+ {
++    unsigned long Location;
++    unsigned long Code;
++    unsigned long Reg;
++    unsigned long Reg2;
++    long FramePtr;
++    long FramePtrDiff;
++    long Offset;
++    unsigned long IsUwop;
++    unsigned long Scope;
++    unsigned long cScopes;
++    unsigned long TryLevel;
++    SEHBLOCK SehBlock[20];
+ } DW2CFSTATE, *PDW2CFSTATE;
+ #define NextCIE(p) ((void*)((char*)p + p->Length + 4))
+ #endif /* dwarf2.h */
  #define IMAGE_DIRECTORY_ENTRY_BASERELOC       5
  
  #define IMAGE_SCN_TYPE_NOLOAD     0x00000002
++#define IMAGE_SCN_TYPE_NO_PAD     0x00000008
++#define IMAGE_SCN_CNT_CODE        0x00000020
++#define IMAGE_SCN_CNT_INITIALIZED_DATA    0x00000040
++#define IMAGE_SCN_CNT_UNINITIALIZED_DATA  0x00000080
++#define IMAGE_SCN_LNK_OTHER       0x00000100
++#define IMAGE_SCN_LNK_INFO        0x00000200
  #define IMAGE_SCN_LNK_REMOVE      0x00000800
--#define IMAGE_SCN_MEM_READ        0x40000000
++#define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000
++#define IMAGE_SCN_GPREL           0x00008000
++#define IMAGE_SCN_MEM_PURGEABLE   0x00020000
++#define IMAGE_SCN_MEM_LOCKED      0x00040000
++#define IMAGE_SCN_MEM_PRELOAD     0x00080000
++#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000
  #define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
++#define IMAGE_SCN_MEM_NOT_CACHED  0x04000000
++#define IMAGE_SCN_MEM_NOT_PAGED   0x08000000
++#define IMAGE_SCN_MEM_SHARED      0x10000000
++#define IMAGE_SCN_MEM_EXECUTE     0x20000000
++#define IMAGE_SCN_MEM_READ        0x40000000
++#define IMAGE_SCN_MEM_WRITE       0x80000000
  
  #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
  
index 0000000,81235ba..e078e65
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,680 +1,910 @@@
 -              ulResult |= current & 0x7f << ulShift;
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include "rsym.h"
+ #include "rsym64.h"
+ #include "dwarf2.h"
++char DoPrint = 0;
++ULONG g_ehframep;
++
++#define DPRINT if(DoPrint) printf
++
+ struct {char *name; char regnt;} regs[] =
+ { {"rax", REG_RAX}, {"rdx", REG_RDX}, {"rcx", REG_RCX}, {"rbx", REG_RBX},
+   {"rsi", REG_RSI}, {"rdi", REG_RDI}, {"rbp", REG_RBP}, {"rsp", REG_RSP},
+   {"r8",  REG_R8},  {"r9",  REG_R9},  {"r10", REG_R10}, {"r11", REG_R11},
+   {"r12", REG_R12}, {"r13", REG_R13}, {"r14", REG_R14}, {"r15", REG_R15},
+   {"xmm0", REG_XMM0}, {"xmm1", REG_XMM1}, {"xmm2", REG_XMM2}, {"xmm3", REG_XMM3},
+   {"xmm4", REG_XMM4}, {"xmm5", REG_XMM5}, {"xmm6", REG_XMM6}, {"xmm7", REG_XMM7},
+   {"xmm8", REG_XMM8}, {"xmm9", REG_XMM9}, {"xmm10",REG_XMM10},{"xmm11",REG_XMM11},
+   {"xmm12",REG_XMM12},{"xmm13",REG_XMM13},{"xmm14",REG_XMM14},{"xmm15",REG_XMM15},
+ //      "st0", "st1", "st2", "st3",
+ //      "st4", "st5", "st6", "st7",
+ //      "mm0", "mm1", "mm2", "mm3",
+ //      "mm4", "mm5", "mm6", "mm7"
+ };
+ /** Functions for DWARF2 ******************************************************/
+ unsigned long
+ DwDecodeUleb128(unsigned long *pResult, char *pc)
+ {
+       unsigned long ulResult = 0;
+       unsigned long ulShift = 0;
+       unsigned char current;
+       unsigned long ulSize = 0;
+       do
+       {
+               current = pc[ulSize];
+               ulSize++;
 -              lResult |= current & 0x7f << ulShift;
++              ulResult |= (current & 0x7f) << ulShift;
+               ulShift += 7;
+       }
+       while (current & 0x80);
+     *pResult = ulResult;
+       return ulSize;
+ }
+ unsigned long
+ DwDecodeSleb128(long *pResult, char *pc)
+ {
+       long lResult = 0;
+       unsigned long ulShift = 0;
+       unsigned char current;
+       unsigned long ulSize = 0;
+       do
+       {
+               current = pc[ulSize];
+               ulSize++;
 -    return Cie->Length;
++              lResult |= (current & 0x7f) << ulShift;
+               ulShift += 7;
+       }
+       while (current & 0x80);
+       if (current & 0x40)
+               lResult |= - (1 << (ulShift));
+     *pResult = lResult;
+       return ulSize;
+ }
+ unsigned long
+ DwDecodeCie(PDW2CIE Cie, char *pc)
+ {
+     Cie->Length = *(ULONG*)pc;
+     Cie->Next = pc + 4 + Cie->Length;
+     Cie->CieId = *(ULONG*)(pc + 4);
+     Cie->Version = pc[8];
+     Cie->AugString = pc + 9;
+     Cie->AugStringLength = strlen(Cie->AugString);
+     pc = Cie->AugString + Cie->AugStringLength + 1;
+     pc += DwDecodeUleb128(&Cie->CodeAlign, pc);
+     pc += DwDecodeSleb128(&Cie->DataAlign, pc);
+     pc += DwDecodeUleb128(&Cie->ReturnAddressRegister, pc);
+     pc += DwDecodeUleb128(&Cie->AugLength, pc);
+     Cie->AugData = pc;
+     pc += Cie->AugLength;
+     Cie->Instructions = pc;
 -    return Fde->Length;
++    return Cie->Length + 4;
+ }
+ unsigned long
+ DwDecodeFde(PDW2FDE Fde, char *pc)
+ {
+     Fde->Length = *(ULONG*)pc;
+     Fde->Next = pc + 4 + Fde->Length;
+     Fde->CiePointer = pc + 4 - *(ULONG*)(pc + 4);
+     Fde->PcBegin = *(ULONG*)(pc + 8);
+     Fde->PcRange = *(ULONG*)(pc + 12);
+     pc += 16;
+     pc += DwDecodeUleb128(&Fde->AugLength, pc);
+     Fde->AugData = pc;
+     Fde->Instructions = Fde->AugData + Fde->AugLength;
 -        Length += DwDecodeUleb128(&State->Offset, pc + 1);
++    return Fde->Length + 4;
+ }
+ unsigned long
+ DwExecIntruction(PDW2CFSTATE State, char *pc)
+ {
+     unsigned char Code;
+     unsigned long Length;
+     unsigned long PrevFramePtr = State->FramePtr;
+     State->Scope = 0;
+     State->IsUwop = 0;
+     State->Code = Code = *pc;
+     Length = 1;
+     if ((Code & 0xc0) == DW_CFA_advance_loc)
+     {
+         State->Code = DW_CFA_advance_loc;
+         State->Location += Code & 0x3f;
+     }
+     else if ((Code & 0xc0) == DW_CFA_offset)
+     {
+         State->Code = DW_CFA_offset;
+         State->Reg = Code & 0x3f;
 -            Length += DwDecodeUleb128(&State->Offset, pc + Length);
++        Length += DwDecodeUleb128((unsigned long*)&State->Offset, pc + 1);
+         State->Offset *= 8; // fixme data alignment
+         State->IsUwop = 1;
+     }
+     else if ((Code & 0xc0) == DW_CFA_restore)
+     {
+         State->Code = DW_CFA_restore;
+         State->Reg = Code & 0x3f;
+     }
+     else switch (Code)
+     {
+         case DW_CFA_nop:
+             break;
+         case DW_CFA_set_loc:
+             Length = 9; // address
+             State->Location = *(DWORD*)(pc + 1);
+             break;
+         case DW_CFA_advance_loc1:
+             Length = 2;
+             State->Location += pc[1];
+             break;
+         case DW_CFA_advance_loc2:
+             Length = 3;
++//            printf("Found a DW_CFA_advance_loc2 : 0x%lx ->", *(WORD*)(pc + 1));
+             State->Location += *(WORD*)(pc + 1);
++//            printf(" 0x%lx\n", State->Location);
+             break;
+         case DW_CFA_advance_loc4:
+             Length = 5;
++//            printf("Found a DW_CFA_advance_loc4 : 0x%lx ->", *(DWORD*)(pc + 1));
+             State->Location += *(DWORD*)(pc + 1);
++//            printf(" 0x%lx\n", State->Location);
+             break;
+         case DW_CFA_offset_extended:
+             Length += DwDecodeUleb128(&State->Reg, pc + Length);
 -            Length += DwDecodeUleb128(&State->FramePtr, pc + Length);
++            Length += DwDecodeUleb128((unsigned long*)&State->Offset, pc + Length);
++            State->IsUwop = 1;
++            break;
++        case DW_CFA_offset_extended_sf:
++            Length += DwDecodeUleb128(&State->Reg, pc + Length);
++            Length += DwDecodeSleb128(&State->Offset, pc + Length);
+             State->IsUwop = 1;
+             break;
+         case DW_CFA_restore_extended:
+             Length += DwDecodeUleb128(&State->Reg, pc + Length);
+             break;
+         case DW_CFA_undefined:
+             Length += DwDecodeUleb128(&State->Reg, pc + Length);
+             break;
+         case DW_CFA_same_value:
+             Length += DwDecodeUleb128(&State->Reg, pc + Length);
+             break;
+         case DW_CFA_register:
+             Length += DwDecodeUleb128(&State->Reg, pc + Length);
+             Length += DwDecodeUleb128(&State->Reg2, pc + Length);
+             break;
+         case DW_CFA_remember_state:
+             break;
+         case DW_CFA_restore_state:
+             break;
+         case DW_CFA_def_cfa:
+             Length += DwDecodeUleb128(&State->Reg, pc + Length);
 -            Length += DwDecodeUleb128(&State->FramePtr, pc + Length);
++            Length += DwDecodeUleb128((unsigned long*)&State->FramePtr, pc + Length);
+             State->IsUwop = 1;
+             break;
+         case DW_CFA_def_cfa_register:
+             Length += DwDecodeUleb128(&State->Reg, pc + Length);
+             break;
+         case DW_CFA_def_cfa_offset:
 -            Length += DwDecodeSleb128((LONG*)&State->FramePtr, pc + Length);
++            Length += DwDecodeUleb128((unsigned long*)&State->FramePtr, pc + Length);
+             State->IsUwop = 1;
+             break;
+         case DW_CFA_def_cfa_sf:
+             Length += DwDecodeUleb128(&State->Reg, pc + Length);
 -        /* PSEH types */
 -        case 0x1c:
 -            State->Scope = 1;
++            Length += DwDecodeSleb128(&State->FramePtr, pc + Length);
+             State->FramePtr *= 8; // data alignment
+             State->IsUwop = 1;
+             break;
 -        case 0x1d:
 -            State->Scope = 2;
++        case DW_CFA_GNU_args_size:
++        {
++            unsigned long argsize;
++            printf("Warning, DW_CFA_GNU_args_size is unimplemented\n");
++            Length += DwDecodeUleb128(&argsize, pc + Length);
+             break;
 -    
 -//printf("@%p: code=%x, Loc=%lx, offset=%lx, reg=0x%lx:%s\n", pc, code, State->Location, State->Offset, State->Reg, regnames_64[State->Reg]);
++        }
++        /* PSEH */
++        case 0x21:
++        {
++            unsigned long SehType;
++
++//            printf("found 0x21 at %lx\n", State->Location);
++            Length += DwDecodeUleb128(&SehType, pc + Length);
++            switch (SehType)
++            {
++                case 1: /* Begin Try */
++                    State->TryLevel++;
++                    if (State->TryLevel >= 20)
++                    {
++                        printf("WTF? Trylevel of 20 exceeded...\n");
++                        exit(1);
++                    }
++                    State->SehBlock[State->TryLevel-1].BeginTry = State->Location;
++//                    printf("Found begintry at 0x%lx\n", State->Location);
++                    State->Scope = 1;
++                    break;
++
++                case 2: /* End Try */
++                    State->SehBlock[State->TryLevel-1].EndTry = State->Location;
++                    State->Scope = 2;
++                    break;
++
++                case 3: /* Jump target */
++                    State->SehBlock[State->TryLevel-1].Target = State->Location;
++                    State->Scope = 3;
++                    break;
++
++                case 4: /* SEH End */
++                    if (State->TryLevel == 20)
++                    {
++                        printf("Ooops, end of SEH with trylevel at 0!\n");
++                        exit(1);
++                    }
++                    State->SehBlock[State->TryLevel-1].End = State->Location;
++                    State->TryLevel--;
++                    State->cScopes++;
++                    State->Scope = 0;
++                    break;
++
++                case 5: /* Constant filter */
++                {
++                    unsigned long value;
++                    Length += DwDecodeUleb128(&value, pc + Length);
++                    State->SehBlock[State->TryLevel-1].Handler = value;
++//                     printf("Found a constant filter at 0x%lx\n", State->Location);
++                    break;
++                }
++
++               /* These work differently. We are in a new function.
++                 * We have to parse a lea opcode to find the adress of
++                 * the jump target. This is the reference to find the 
++                 * appropriate C_SCOPE_TABLE. */
++                case 6: /* Filter func */
++//                    printf("Found a filter func at 0x%lx\n", State->Location);
++                    break;
++
++                case 7: /* Finally func */
++                {
++//                     printf("Found a finally func at 0x%lx\n", State->Location);
++                    break;
++                }
++
++                default:
++                    printf("Found unknow PSEH code 0x%lx\n", SehType);
++                    exit(1);
++            }
+             break;
++        }
+         default:
+             fprintf(stderr, "unknown instruction 0x%x at 0x%p\n", Code, pc);
+             exit(1);
+     }
+     
+     State->FramePtrDiff = State->FramePtr - PrevFramePtr;
 -                Code[1].FrameOffset = (AllocSize / 8);
 -                Code[2].FrameOffset = (AllocSize / 8) >> 16;
++    DPRINT("@%p: code=%x, Loc=%lx, offset=%lx, reg=0x%lx:%s\n", 
++        (void*)((ULONG)pc - g_ehframep), Code, State->Location, State->Offset, State->Reg, regs[State->Reg].name);
+     return Length;
+ }
+ /** Windows unwind data functions *********************************************/
+ ULONG
+ StoreUnwindCodes(PUNWIND_INFO Info, PDW2CFSTATE State, ULONG FunctionStart)
+ {
+     ULONG cCodes = 0;
+     ULONG AllocSize;
+     UNWIND_CODE Code[3];
+     int i;
+     Code[0].CodeOffset = State->Location - FunctionStart;
+     switch (State->Code)
+     {
+         case DW_CFA_offset:
+         case DW_CFA_offset_extended:
+             // save register at offset
+             Code[0].OpInfo = regs[State->Reg].regnt;
+             if (State->Offset <= 0x7FFF8)
+             {
+                 Code[0].UnwindOp = UWOP_SAVE_NONVOL;
+                 Code[1].FrameOffset = State->Offset / 8;
+                 cCodes = 2;
+             }
+             else
+             {
+                 Code[0].UnwindOp = UWOP_SAVE_NONVOL_FAR;
+                 Code[1].FrameOffset = (State->Offset / 8);
+                 Code[2].FrameOffset = (State->Offset / 8) >> 16;
+                 cCodes = 3;
+             }
+             break;
+         case DW_CFA_def_cfa:
+         //case DW_CFA_def_cfa_register:
+         case DW_CFA_def_cfa_offset:
+         case DW_CFA_def_cfa_sf:
+             AllocSize = State->FramePtrDiff;
+             if (AllocSize <= 128)
+             {
+                 Code[0].UnwindOp = UWOP_ALLOC_SMALL;
+                 Code[0].OpInfo = (AllocSize / 8) - 1;
+                 cCodes = 1;
+             }
+             else if (AllocSize <= 0x7FFF8)
+             {
+                 Code[0].UnwindOp = UWOP_ALLOC_LARGE;
+                 Code[0].OpInfo = 0;
+                 Code[1].FrameOffset = AllocSize / 8;
+                 cCodes = 2;
+             }
+             else // if (AllocSize > 0x7FFF8)
+             {
+                 Code[0].UnwindOp = UWOP_ALLOC_LARGE;
+                 Code[0].OpInfo = 1;
 -#define GetSectionPointer(Info, i) \
 -    ((void*)(Info->FilePtr + Info->SectionHeaders[i].PointerToRawData))
 -
++                Code[1].FrameOffset = (USHORT)AllocSize;
++                Code[2].FrameOffset = (USHORT)(AllocSize >> 16);
+                 cCodes = 3;
+             }
+             break;
+     }
+     if (Info)
+     {
+         /* Move old codes */
+         for (i = Info->CountOfCodes - 1; i >= 0; i--)
+         {
+             Info->UnwindCode[i + cCodes] = Info->UnwindCode[i];
+         }
+         /* Copy new codes */
+         for (i = 0; i < cCodes; i++)
+         {
+             Info->UnwindCode[i] = Code[i];
+         }
+         Info->CountOfCodes += cCodes;
+     }
+     return cCodes;
+ }
 -//        else if
 -        // if is scope
 -            // if is first scope
 -                // align 4
 -                // emit gcc_specific handler
 -                // create pointer to C_SCOPE_TABLE
 -            // 
 -
+ #define GetxdataSize(cFuncs, cUWOP, cScopes) \
+     ( cFuncs * (sizeof(UNWIND_INFO) + 2 + 4 + 4) \
+     + cUWOP * sizeof(UNWIND_CODE) \
+     + cScopes * sizeof(C_SCOPE_TABLE_ENTRY) )
+ ULONG
+ StoreUnwindInfo(PUNWIND_INFO Info, PDW2FDE pFde, ULONG FunctionStart)
+ {
+     ULONG cbSize;
+     DW2CFSTATE State;
+     char *pInst;
+     ULONG c;
+     DW2CIE Cie;
+     cbSize = 4; // sizeof(UNWIND_INFO);
+     Info->Version = 1;
+     Info->Flags = 0;
+     Info->SizeOfProlog = 0;
+     Info->CountOfCodes = 0;
+     Info->FrameRegister = 0;
+     Info->FrameOffset = 0;
+     /* Decode the CIE */
+     DwDecodeCie(&Cie, pFde->CiePointer);
+     /* Initialize state */
+     State.Location = FunctionStart;
+     State.FramePtr = 0;
++    State.TryLevel = 0;
++    State.cScopes = 0;
+     /* Parse the CIE's initial instructions */
+     pInst = Cie.Instructions;
+     while (pInst < Cie.Next)
+     {
+         pInst += DwExecIntruction(&State, pInst);
+     }
+     /* Parse the FDE instructions */
+     pInst = pFde->Instructions;
+     while (pInst < pFde->Next)
+     {
+         pInst += DwExecIntruction(&State, pInst);
+         if (State.IsUwop)
+         {
+             c = StoreUnwindCodes(Info, &State, FunctionStart);
+             cbSize += c * sizeof(UNWIND_CODE);
+             Info->SizeOfProlog = State.Location - FunctionStart;
+         }
 -    char *pInst;
+     }
+     cbSize = ROUND_UP(cbSize, 4);
++    /* Do we have scope table to write? */
++    if (State.cScopes > 0)
++    {
++        unsigned long i;
++        ULONG *pExceptionHandler;
++        PC_SCOPE_TABLE pScopeTable;
++
++        /* Set flag for exception handler */ 
++        Info->Flags |= UNW_FLAG_EHANDLER;
++
++        /* Store address of handler and number of scope tables */
++        pExceptionHandler = (ULONG*)((char*)Info + cbSize);
++        // HACK for testing purpose
++        *pExceptionHandler = FunctionStart; // _C_specific_handler
++
++        pScopeTable = (PC_SCOPE_TABLE)(pExceptionHandler + 1);
++        pScopeTable->NumEntries = State.cScopes;
++
++        /* Store the scope table entries */
++        for (i = 0; i < State.cScopes; i++)
++        {
++            pScopeTable->Entry[i].Begin = State.SehBlock[i].BeginTry;
++            pScopeTable->Entry[i].End = State.SehBlock[i].EndTry;
++            pScopeTable->Entry[i].Handler = 1;//State.SehBlock[i].Handler;
++            pScopeTable->Entry[i].Target = State.SehBlock[i].Target;
++        }
++        
++        /* Update size */
++        cbSize += 8 + State.cScopes * sizeof(C_SCOPE_TABLE_ENTRY);
++    }
++
+     return cbSize;
+ }
+ void
+ CountUnwindData(PFILE_INFO File)
+ {
+     DW2CIEFDE *p;
+     DW2FDE Fde;
 -    p = GetSectionPointer(File, File->eh_frame.idx);
 -    for (; p->Length; p = NextCIE(p))
++    char *pInst, *pmax;
+     DW2CFSTATE State;
+     File->cFuncs = 0;
+     File->cScopes = 0;
+     File->cUWOP = 0;
+     State.FramePtr = 0;
++    State.TryLevel = 0;
 -    eh_frame = GetSectionPointer(File, File->eh_frame.idx);
++    p = File->eh_frame.p;
++    pmax = (char*)p + File->eh_frame.psh->Misc.VirtualSize;
++    for (; p->Length && (char*)p < pmax; p = NextCIE(p))
+     {
+         /* Is this an FDE? */
+         if (p->CiePointer != 0)
+         {
+             File->cFuncs++;
+             DwDecodeFde(&Fde, (char*)p);
+             pInst = Fde.Instructions;
+             while (pInst < Fde.Next)
+             {
+                 pInst += DwExecIntruction(&State, pInst);
+                 File->cUWOP += StoreUnwindCodes(NULL, &State, 0);
+                 File->cScopes += State.Scope ? 1 : 0;
+             }
+         }
+     }
+     return;
+ }
+ int CompFunc(const void *p1, const void *p2)
+ {
+     PRUNTIME_FUNCTION prf1 = (void*)p1, prf2 = (void*)p2;
+     return (prf1->FunctionStart > prf2->FunctionStart ? 1 : -1);
+ }
+ void
+ GeneratePData(PFILE_INFO File)
+ {
+     DW2CIEFDE *p;
+     DW2FDE Fde;
+     PIMAGE_DATA_DIRECTORY Dir;
+     ULONG i, Offset;
+     void * eh_frame;
+     PRUNTIME_FUNCTION pdata;
+     ULONG xdata_va;
+     char *xdata_p;
+     ULONG cbSize;
+     PIMAGE_SECTION_HEADER pshp, pshx;
+     ULONG FileAlignment;
++    char *pmax;
+     FileAlignment = File->OptionalHeader->FileAlignment;
+     /* Get pointer to eh_frame section */
 -    /* Allocate .pdata buffer */
 -    File->pdata.idx = File->UsedSections;
 -    pshp = File->pdata.psh = &File->SectionHeaders[File->pdata.idx];
++    eh_frame = File->eh_frame.p;
++    g_ehframep = (ULONG)eh_frame;
+     /* Get sizes */
+     CountUnwindData(File);
+ //    printf("cFuncs = %ld, cUWOPS = %ld, cScopes = %ld\n", 
+ //        File->cFuncs, File->cUWOP, File->cScopes);
 -//    pshp->VirtualAddress = 
++    /* Initialize section header for .pdata */
++    i = File->pdata.idx = File->UsedSections;
++    pshp = File->pdata.psh = &File->NewSectionHeaders[i];
+     memcpy(pshp->Name, ".pdata", 7);
+     pshp->Misc.VirtualSize = (File->cFuncs + 1) * sizeof(RUNTIME_FUNCTION);
 -//    pshp->PointerToRawData = 
++    pshp->VirtualAddress = File->NewSectionHeaders[i - 1].VirtualAddress +
++                           File->NewSectionHeaders[i - 1].SizeOfRawData;
+     pshp->SizeOfRawData = ROUND_UP(pshp->Misc.VirtualSize, FileAlignment);
 -    /* Allocate .xdata buffer */
++    pshp->PointerToRawData = File->NewSectionHeaders[i - 1].PointerToRawData +
++                           File->NewSectionHeaders[i - 1].SizeOfRawData;
++    pshp->PointerToRelocations = 0;
++    pshp->PointerToLinenumbers = 0;
++    pshp->NumberOfRelocations = 0;
++    pshp->NumberOfLinenumbers = 0;
++    pshp->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_NOT_PAGED |
++                            IMAGE_SCN_CNT_INITIALIZED_DATA;
++
++    /* Allocate .pdata buffer */
+     pdata = File->pdata.p = malloc(pshp->SizeOfRawData);
+     memset(File->pdata.p, pshp->SizeOfRawData, 0);
+     /* Init exception data dir */
+     Dir = &File->OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION];
+     Dir->VirtualAddress = pshp->VirtualAddress;
+     Dir->Size = pshp->Misc.VirtualSize;
 -    pshx = File->xdata.psh = &File->SectionHeaders[File->xdata.idx];
++    /* Initialize section header for .xdata */
+     File->xdata.idx = File->pdata.idx + 1;
 -    memset(File->pdata.p, pshx->SizeOfRawData, 0);
++    pshx = File->xdata.psh = &File->NewSectionHeaders[File->xdata.idx];
+     memcpy(pshx->Name, ".xdata", 7);
+     pshx->Misc.VirtualSize = GetxdataSize(File->cFuncs, File->cUWOP, File->cScopes);
+     pshx->VirtualAddress = pshp->VirtualAddress + pshp->SizeOfRawData;
+     pshx->SizeOfRawData = ROUND_UP(pshx->Misc.VirtualSize, FileAlignment);
+     pshx->PointerToRawData = pshp->PointerToRawData + pshp->SizeOfRawData;
++    pshx->PointerToRelocations = 0;
++    pshx->PointerToLinenumbers = 0;
++    pshx->NumberOfRelocations = 0;
++    pshx->NumberOfLinenumbers = 0;
++    pshx->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_NOT_PAGED |
++                            IMAGE_SCN_CNT_INITIALIZED_DATA;
++
++    /* Allocate .xdata buffer */
+     File->xdata.p = malloc(pshx->SizeOfRawData);
 -    for (p = eh_frame; p->Length; p = NextCIE(p))
++    memset(File->xdata.p, pshx->SizeOfRawData, 0);
+     i = 0;
+     Offset = File->eh_frame.psh->VirtualAddress;
+     xdata_va = pshx->VirtualAddress;
+     xdata_p = File->xdata.p;
 -    for (i = 0; i < (cbSize + 1) / sizeof(WORD); i += 1)
++    pmax = (char*)eh_frame + File->eh_frame.psh->Misc.VirtualSize - 100;
++
++    for (p = eh_frame; p->Length && (char*)p < pmax; p = NextCIE(p))
+     {
+         /* Is this an FDE? */
+         if (p->CiePointer != 0)
+         {
+             DwDecodeFde(&Fde, (char*)p);
+             pdata[i].FunctionStart = Offset + 8 + Fde.PcBegin;
+             pdata[i].FunctionEnd = pdata[i].FunctionStart + Fde.PcRange;
+             pdata[i].UnwindInfo = xdata_va;
+ //            printf("%ld: RUNTIME_FUNCTION: {0x%lx, 0x%lx, 0x%lx}\n", i, pdata[i].FunctionStart, pdata[i].FunctionEnd, pdata[i].UnwindInfo);
+             cbSize = StoreUnwindInfo((void*)xdata_p, &Fde, pdata[i].FunctionStart);
+             xdata_va += cbSize;
+             xdata_p += cbSize;
+             i++;
+         }
+         Offset += 4 + p->Length;
+     }
+     /* Sort the RUNTIME_FUNCTIONS */
+     qsort(pdata, i, sizeof(RUNTIME_FUNCTION), CompFunc);
+ }
+ /** Functions for COFF ********************************************************/
+ WORD
+ CalculateChecksum(DWORD Start, void *pFile, ULONG cbSize)
+ {
+     WORD *Ptr = pFile;
+     DWORD i;
+     DWORD checksum = Start;
 -    int ret, Size, Pos;
 -    DWORD Checksum;
++    for (i = 0; i < (cbSize + 1) / sizeof(WORD); i++)
+     {
+         checksum += Ptr[i];
+         checksum = (checksum + (checksum >> 16)) & 0xffff;
+     }
+     return checksum ;
+ }
+ void
+ WriteOutFile(FILE *handle, PFILE_INFO File)
+ {
 -    /* Correct section count */
++    int ret, Size, Pos = 0;
++    DWORD CheckSum;
++    ULONG i, Alignment;
 -    /* Calculate size of file beginning */
 -    Size = File->SectionHeaders[File->UsedSections].PointerToRawData;
++    Alignment = File->OptionalHeader->FileAlignment;
++
++    /* Update section count */
+     File->FileHeader->NumberOfSections = File->UsedSections + 2; // FIXME!!!
 -    Checksum = CalculateChecksum(0, File->FilePtr, Size);
 -    Checksum = CalculateChecksum(Checksum, File->pdata.p, File->pdata.psh->Misc.VirtualSize);
 -    Checksum = CalculateChecksum(Checksum, File->xdata.p, File->xdata.psh->Misc.VirtualSize);
 -    File->OptionalHeader->CheckSum = Checksum + Size + File->pdata.psh->Misc.VirtualSize;
 -
 -    /* Write file beginning */
++    /* Update SizeOfImage */
++    Size = File->xdata.psh->VirtualAddress
++           + File->xdata.psh->SizeOfRawData;
++    File->OptionalHeader->SizeOfImage = Size;
+     /* Recalculate checksum */
 -    int i;
++    CheckSum = CalculateChecksum(0, File->FilePtr, File->HeaderSize);
++    for (i = 0; i < File->AllSections; i++)
++    {
++        if (File->UseSection[i])
++        {
++            Size = File->SectionHeaders[i].SizeOfRawData;
++            if (Size)
++            {
++                void *p;
++                p = File->FilePtr + File->SectionHeaders[i].PointerToRawData;
++                CheckSum = CalculateChecksum(CheckSum, p, Size);
++            }
++        }
++    }
++    Size = File->pdata.psh->Misc.VirtualSize;
++    CheckSum = CalculateChecksum(CheckSum, File->pdata.p, Size);
++    Size = File->xdata.psh->Misc.VirtualSize;
++    CheckSum = CalculateChecksum(CheckSum, File->xdata.p, Size);
++    CheckSum += File->HeaderSize;
++    CheckSum += File->pdata.psh->Misc.VirtualSize;
++    CheckSum += File->xdata.psh->Misc.VirtualSize;
++    File->OptionalHeader->CheckSum = CheckSum;
++
++    /* Write file header */
++    Size = File->HeaderSize;
+     ret = fwrite(File->DosHeader, 1, Size, handle);
+     Pos = Size;
++    /* Write Section headers */
++    Size = File->NewSectionHeaderSize;
++    ret = fwrite(File->NewSectionHeaders, 1, Size, handle);
++    Pos += Size;
++
++    /* Fill up to next alignement */
++    Size = ROUND_UP(Pos, Alignment) - Pos;
++    ret = fwrite(File->AlignBuf, 1, Size, handle);
++    Pos += Size;
++
++    /* Write sections */
++    for (i = 0; i < File->AllSections; i++)
++    {
++        if (File->UseSection[i])
++        {
++            void *p;
++            Size = File->SectionHeaders[i].SizeOfRawData;
++            if (Size)
++            {
++                p = File->FilePtr + File->SectionHeaders[i].PointerToRawData;
++                ret = fwrite(p, 1, Size, handle);
++                Pos += Size;
++            }
++        }
++    }
++
+     /* Write .pdata section */
+     Size = File->pdata.psh->SizeOfRawData;
+     ret = fwrite(File->pdata.p, 1, Size, handle);
+     Pos += Size;
+     /* Write .xdata section */
+     Size = File->xdata.psh->SizeOfRawData;
+     ret = fwrite(File->xdata.p, 1, Size, handle);
+     Pos += Size;
+ }
+ int
+ ParsePEHeaders(PFILE_INFO File)
+ {
+     DWORD OldChecksum, Checksum;
 -    if ((File->DosHeader->e_magic != IMAGE_DOS_MAGIC) || File->DosHeader->e_lfanew == 0L)
++    ULONG Alignment, CurrentPos;
++    int i, j;
+     /* Check if MZ header exists  */
+     File->DosHeader = (PIMAGE_DOS_HEADER)File->FilePtr;
 -        return 0;
++    if ((File->DosHeader->e_magic != IMAGE_DOS_MAGIC) || 
++        (File->DosHeader->e_lfanew == 0L))
+     {
+         perror("Input file is not a PE image.\n");
 -                                     File->DosHeader->e_lfanew + sizeof(ULONG));
++        return -1;
+     }
+     /* Locate PE file header  */
+     File->FileHeader = (PIMAGE_FILE_HEADER)(File->FilePtr + 
 -        return 0;
++                               File->DosHeader->e_lfanew + sizeof(ULONG));
++
++    /* Check for x64 image */
+     if (File->FileHeader->Machine != IMAGE_FILE_MACHINE_AMD64)
+     {
+         perror("Input file is not an x64 image.\n");
 -    File->ImageBase = File->OptionalHeader->ImageBase;
++        return -1;
+     }
+     /* Locate optional header */
+     File->OptionalHeader = (PIMAGE_OPTIONAL_HEADER64)(File->FileHeader + 1);
 -    Checksum = CalculateChecksum(0, File->FilePtr, File->cbInFileSize)
 -               + File->cbInFileSize;
 -    if (Checksum != OldChecksum)
+     /* Check if checksum is correct */
+     OldChecksum = File->OptionalHeader->CheckSum;
+     File->OptionalHeader->CheckSum = 0;
 -        return 0;
++    Checksum = CalculateChecksum(0, File->FilePtr, File->cbInFileSize);
++    Checksum += File->cbInFileSize;
++    if ((Checksum & 0xffff) != (OldChecksum & 0xffff))
+     {
+         fprintf(stderr, "Input file has incorrect PE checksum: 0x%lx (calculated: 0x%lx)\n",
+             OldChecksum, Checksum);
+ //        return 0;
+     }
+     /* Locate PE section headers  */
+     File->SectionHeaders = (PIMAGE_SECTION_HEADER)((char*)File->OptionalHeader
+                            + File->FileHeader->SizeOfOptionalHeader);
+     File->HeaderSize = File->DosHeader->e_lfanew
+                        + sizeof(ULONG)
+                        + sizeof(IMAGE_FILE_HEADER)
+                        + File->FileHeader->SizeOfOptionalHeader;
+     if (!File->FileHeader->PointerToSymbolTable)
+     {
+         fprintf(stderr, "No symbol table.\n");
 -        }
 -        else
 -        {
 -            /* Mark last section with a short name */
 -            File->UsedSections = i + 1;
++        return -1;
+     }
++    /* Create some shortcuts */
++    File->ImageBase = File->OptionalHeader->ImageBase;
+     File->Symbols = File->FilePtr + File->FileHeader->PointerToSymbolTable;
+     File->Strings = (char*)File->Symbols + File->FileHeader->NumberOfSymbols * 18;
+     /* Check section names */
+     File->AllSections = File->FileHeader->NumberOfSections;
++    Alignment = File->OptionalHeader->FileAlignment;
++    File->NewSectionHeaders = malloc((File->AllSections+2) * sizeof(IMAGE_SECTION_HEADER));
++    File->UsedSections = 0;
+     File->eh_frame.idx = -1;
++
++    /* Allocate array of chars, specifiying wheter to copy the section */
++    File->UseSection = malloc(File->AllSections);
++
+     for (i = 0; i < File->AllSections; i++)
+     {
+         char *pName = (char*)File->SectionHeaders[i].Name;
++        File->UseSection[i] = 1;
+         /* Check for long name */
+         if (pName[0] == '/')
+         {
+             unsigned long index = strtoul(pName+1, 0, 10);
+             pName = File->Strings + index;
 -            File->eh_frame.idx = i;
++            
++            // Hack, simply remove all sections with long names
++            File->UseSection[i] = 0;
+         }
++        /* Chek if we have the eh_frame section */
+         if (strcmp(pName, ".eh_frame") == 0)
+         {
 -            File->eh_frame.p = GetSectionPointer(File, i);
+             File->eh_frame.psh = &File->SectionHeaders[i];
 -    if (!ParsePEHeaders(&File))
++            File->eh_frame.idx = i;
++            File->eh_frame.p = File->FilePtr + File->eh_frame.psh->PointerToRawData;
+         }
++        
++        /* Increase number of used sections */
++        if (File->UseSection[i])
++            File->UsedSections = i+1;
+     }
++    /* This is the actual size of the new section headers */
++    File->NewSectionHeaderSize = 
++        (File->UsedSections+2) * sizeof(IMAGE_SECTION_HEADER);
++
++    /* Calculate the position to start writing the sections to */
++    CurrentPos = File->HeaderSize + File->NewSectionHeaderSize;
++    CurrentPos = ROUND_UP(CurrentPos, Alignment);
++
++    /* Create new section headers */
++    for (i = 0, j = 0; i < File->UsedSections; i++)
++    {
++        /* Copy section header */
++        File->NewSectionHeaders[j] = File->SectionHeaders[i];
++
++        /* Shall we strip the section? */
++        if (File->UseSection[i] == 0)
++        {
++            /* Make it a bss section */
++            File->NewSectionHeaders[j].PointerToRawData = 0;
++            File->NewSectionHeaders[j].SizeOfRawData = 0;
++            File->NewSectionHeaders[j].Characteristics = 0xC0500080;
++        }
++
++        /* Fix Offset into File */
++        File->NewSectionHeaders[j].PointerToRawData =
++              File->NewSectionHeaders[j].PointerToRawData ? CurrentPos : 0;
++        CurrentPos += File->NewSectionHeaders[j].SizeOfRawData;
++        j++;
++    }
++
+     if (File->eh_frame.idx == -1)
+     {
+         fprintf(stderr, "No .eh_frame section found\n");
+         return 0;
+     }
+     return 1;
+ }
+ int main(int argc, char* argv[])
+ {
+     char* pszInFile;
+     char* pszOutFile;
+     FILE_INFO File;
+     FILE* outfile;
++    int ret;
+     if (argc != 3)
+     {
+         fprintf(stderr, "Usage: rsym <exefile> <symfile>\n");
+         exit(1);
+     }
+     pszInFile = convert_path(argv[1]);
+     pszOutFile = convert_path(argv[2]);
+     File.FilePtr = load_file(pszInFile, &File.cbInFileSize);
+     if (!File.FilePtr)
+     {
+         fprintf(stderr, "An error occured loading '%s'\n", pszInFile);
+         exit(1);
+     }
 -        exit(1);
++    ret = ParsePEHeaders(&File);
++    if (ret != 1)
+     {
+         free(File.FilePtr);
++        exit(ret == -1 ? 1 : 0);
+     }
+     File.AlignBuf = malloc(File.OptionalHeader->FileAlignment);
+     memset(File.AlignBuf, File.OptionalHeader->FileAlignment, 0);
+     GeneratePData(&File);
+     outfile = fopen(pszOutFile, "wb");
+     if (outfile == NULL)
+     {
+         perror("Cannot open output file");
+         free(File.FilePtr);
+         exit(1);
+     }
+     WriteOutFile(outfile, &File);
+     fclose(outfile);
+     return 0;
+ }
index 0000000,c58cf84..521b55c
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,175 +1,185 @@@
 -    C_SCOPE_TABLE_ENTRY Table[1];
+ #ifndef _RSYM64_H
+ #define _RSYM64_H
+ //C_ASSERT(sizeof(ULONG) == 4);
+ typedef unsigned char UBYTE;
+ typedef unsigned __int64 ULONG64;
+ #define IMAGE_FILE_MACHINE_AMD64 0x8664
+ #define IMAGE_DIRECTORY_ENTRY_IMPORT 1
+ #define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
+ #define UWOP_PUSH_NONVOL 0
+ #define UWOP_ALLOC_LARGE 1
+ #define UWOP_ALLOC_SMALL 2
+ #define UWOP_SET_FPREG 3
+ #define UWOP_SAVE_NONVOL 4
+ #define UWOP_SAVE_NONVOL_FAR 5
+ #define UWOP_SAVE_XMM 6
+ #define UWOP_SAVE_XMM_FAR 7
+ #define UWOP_SAVE_XMM128 8
+ #define UWOP_SAVE_XMM128_FAR 9
+ #define UWOP_PUSH_MACHFRAME 10
+ #define REG_RAX 0
+ #define REG_RCX 1
+ #define REG_RDX 2
+ #define REG_RBX 3
+ #define REG_RSP 4
+ #define REG_RBP 5
+ #define REG_RSI 6
+ #define REG_RDI 7
+ #define REG_R8 8
+ #define REG_R9 9
+ #define REG_R10 10
+ #define REG_R11 11
+ #define REG_R12 12
+ #define REG_R13 13
+ #define REG_R14 14
+ #define REG_R15 15
+ #define REG_XMM0 0
+ #define REG_XMM1 1
+ #define REG_XMM2 2
+ #define REG_XMM3 3
+ #define REG_XMM4 4
+ #define REG_XMM5 5
+ #define REG_XMM6 6
+ #define REG_XMM7 7
+ #define REG_XMM8 8
+ #define REG_XMM9 9
+ #define REG_XMM10 10
+ #define REG_XMM11 11
+ #define REG_XMM12 12
+ #define REG_XMM13 13
+ #define REG_XMM14 14
+ #define REG_XMM15 15
+ typedef struct _IMAGE_IMPORT_DESCRIPTOR
+ {
+     union {
+         DWORD   Characteristics;
+         DWORD   OriginalFirstThunk;
+     };
+     DWORD   TimeDateStamp;
+     DWORD   ForwarderChain;
+     DWORD   Name;
+     DWORD   FirstThunk;
+ } IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR;
+ typedef struct _IMAGE_THUNK_DATA64
+ {
+     union {
+         ULONGLONG ForwarderString;
+         ULONGLONG Function;
+         ULONGLONG Ordinal;
+         ULONGLONG AddressOfData;
+     } u1;
+ } IMAGE_THUNK_DATA64, *PIMAGE_THUNK_DATA64;
+ typedef struct _RUNTIME_FUNCTION
+ {
+     ULONG FunctionStart;
+     ULONG FunctionEnd;
+     ULONG UnwindInfo;
+ } RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
+ typedef union _UNWIND_CODE
+ {
+     struct
+     {
+         UBYTE CodeOffset;
+         UBYTE UnwindOp:4;
+         UBYTE OpInfo:4;
+     };
+     USHORT FrameOffset;
+ } UNWIND_CODE, *PUNWIND_CODE;
++enum
++{
++    UNW_FLAG_EHANDLER  = 0x01,
++    UNW_FLAG_UHANDLER  = 0x02,
++    UNW_FLAG_CHAININFO = 0x03,
++};
++
+ typedef struct _UNWIND_INFO
+ {
+     UBYTE Version:3;
+     UBYTE Flags:5;
+     UBYTE SizeOfProlog;
+     UBYTE CountOfCodes;
+     UBYTE FrameRegister:4;
+     UBYTE FrameOffset:4;
+     UNWIND_CODE UnwindCode[1];
+ /*    union {
+         OPTIONAL ULONG ExceptionHandler;
+         OPTIONAL ULONG FunctionEntry;
+     };
+     OPTIONAL ULONG ExceptionData[]; 
+ */
+ } UNWIND_INFO, *PUNWIND_INFO;
+ typedef struct _C_SCOPE_TABLE_ENTRY
+ {
+     ULONG Begin;
+     ULONG End;
+     ULONG Handler;
+     ULONG Target;
+ } C_SCOPE_TABLE_ENTRY, *PC_SCOPE_TABLE_ENTRY;
+ typedef struct _C_SCOPE_TABLE
+ {
+     ULONG NumEntries;
++    C_SCOPE_TABLE_ENTRY Entry[1];
+ } C_SCOPE_TABLE, *PC_SCOPE_TABLE;
+ typedef struct
+ {
+     IMAGE_SECTION_HEADER *psh;
+     char *pName;
+     void *p;
+     ULONG idx;
+ } SECTION;
+ typedef struct
+ {
+     char* FilePtr;
+     size_t cbInFileSize;
+     size_t cbNewFileSize;
+     /* PE data pointers */
+     PIMAGE_DOS_HEADER DosHeader;
+     PIMAGE_FILE_HEADER FileHeader;
+     PIMAGE_OPTIONAL_HEADER64 OptionalHeader;
+     PIMAGE_SECTION_HEADER SectionHeaders;
++    PIMAGE_SECTION_HEADER NewSectionHeaders;
++    ULONG NewSectionHeaderSize;
+     PIMAGE_BASE_RELOCATION Relocations;
+     void *Symbols;
+     char *Strings;
+     ULONG64 ImageBase;
+     ULONG HeaderSize;
++    char *UseSection;
+     /* Sections */
+     ULONG AllSections;
+     ULONG UsedSections;
+     SECTION eh_frame;
+     SECTION pdata;
+     SECTION xdata;
+     char *AlignBuf;
+     ULONG cFuncs;
+     ULONG cUWOP;
+     ULONG cScopes;
+ } FILE_INFO, *PFILE_INFO;
+ #endif // !_RSYM64_H