Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.

This commit is contained in:
Colin Finck 2017-10-03 07:45:34 +00:00
parent b94e2d8ca0
commit c2c66aff7d
24198 changed files with 0 additions and 37285 deletions

View file

@ -0,0 +1,15 @@
include_directories(${REACTOS_SOURCE_DIR}/sdk/tools)
add_library(rsym_common rsym_common.c)
if(ARCH STREQUAL "i386")
add_definitions(-D_X86_)
add_host_tool(rsym rsym.c)
elseif(ARCH STREQUAL "amd64")
add_host_tool(rsym rsym64.c)
elseif(ARCH STREQUAL "arm")
add_executable(rsym rsym64.c)
endif()
target_link_libraries(rsym rsym_common dbghelphost zlibhost unicode)
add_host_tool(raddr2line rsym_common.c raddr2line.c)

839
sdk/tools/rsym/dwarf2.h Normal file
View file

@ -0,0 +1,839 @@
/* 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 this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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. */
#pragma once
//#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
};
/* @@@ 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
{
unsigned long Length;
char *Next;
char *CiePointer;
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))

192
sdk/tools/rsym/raddr2line.c Normal file
View file

@ -0,0 +1,192 @@
/*
* Usage: raddr2line input-file address/offset
*
* This is a tool and is compiled using the host compiler,
* i.e. on Linux gcc and not mingw-gcc (cross-compiler).
* Therefore we can't include SDK headers and we have to
* duplicate some definitions here.
* Also note that the internal functions are "old C-style",
* returning an int, where a return of 0 means success and
* non-zero is failure.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "rsym.h"
/* Assume if an offset > ABS_TRESHOLD, then it must be absolute */
#define ABS_TRESHOLD 0x00400000L
size_t fixup_offset ( size_t ImageBase, size_t offset )
{
if (offset > ABS_TRESHOLD)
offset -= ImageBase;
return offset;
}
long
my_atoi ( const char* a )
{
int i = 0;
const char* fmt = "%x";
if ( *a == '0' )
{
switch ( *++a )
{
case 'x':
fmt = "%x";
++a;
break;
case 'd':
fmt = "%d";
++a;
break;
default:
fmt = "%o";
break;
}
}
sscanf ( a, fmt, &i );
return i;
}
PIMAGE_SECTION_HEADER
find_rossym_section ( PIMAGE_FILE_HEADER PEFileHeader,
PIMAGE_SECTION_HEADER PESectionHeaders )
{
size_t i;
for ( i = 0; i < PEFileHeader->NumberOfSections; i++ )
{
if ( 0 == strcmp ( (char*)PESectionHeaders[i].Name, ".rossym" ) )
return &PESectionHeaders[i];
}
return NULL;
}
int
find_and_print_offset (
void* data,
size_t offset )
{
PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER)data;
PROSSYM_ENTRY Entries = (PROSSYM_ENTRY)((char*)data + RosSymHeader->SymbolsOffset);
char* Strings = (char*)data + RosSymHeader->StringsOffset;
size_t symbols = RosSymHeader->SymbolsLength / sizeof(ROSSYM_ENTRY);
size_t i;
//if ( RosSymHeader->SymbolsOffset )
for ( i = 0; i < symbols; i++ )
{
if ( Entries[i].Address > offset )
{
if ( !i-- )
return 1;
else
{
PROSSYM_ENTRY e = &Entries[i];
printf ( "%s:%u (%s)\n",
&Strings[e->FileOffset],
(unsigned int)e->SourceLine,
&Strings[e->FunctionOffset] );
return 0;
}
}
}
return 1;
}
int
process_data ( const void* FileData, size_t offset )
{
PIMAGE_DOS_HEADER PEDosHeader;
PIMAGE_FILE_HEADER PEFileHeader;
PIMAGE_OPTIONAL_HEADER PEOptHeader;
PIMAGE_SECTION_HEADER PESectionHeaders;
PIMAGE_SECTION_HEADER PERosSymSectionHeader;
size_t ImageBase;
int res;
/* Check if MZ header exists */
PEDosHeader = (PIMAGE_DOS_HEADER)FileData;
if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC || PEDosHeader->e_lfanew == 0L)
{
perror("Input file is not a PE image.\n");
return 1;
}
/* Locate PE file header */
/* sizeof(ULONG) = sizeof(MAGIC) */
PEFileHeader = (PIMAGE_FILE_HEADER)((char *)FileData + PEDosHeader->e_lfanew + sizeof(ULONG));
/* Locate optional header */
PEOptHeader = (PIMAGE_OPTIONAL_HEADER)(PEFileHeader + 1);
ImageBase = PEOptHeader->ImageBase;
/* Locate PE section headers */
PESectionHeaders = (PIMAGE_SECTION_HEADER)((char *) PEOptHeader + PEFileHeader->SizeOfOptionalHeader);
/* make sure offset is what we want */
offset = fixup_offset ( ImageBase, offset );
/* find rossym section */
PERosSymSectionHeader = find_rossym_section (
PEFileHeader, PESectionHeaders );
if ( !PERosSymSectionHeader )
{
fprintf ( stderr, "Couldn't find rossym section in executable\n" );
return 1;
}
res = find_and_print_offset ( (char*)FileData + PERosSymSectionHeader->PointerToRawData,
offset );
if ( res )
printf ( "??:0\n" );
return res;
}
int
process_file ( const char* file_name, size_t offset )
{
void* FileData;
size_t FileSize;
int res = 1;
FileData = load_file ( file_name, &FileSize );
if ( !FileData )
{
fprintf ( stderr, "An error occured loading '%s'\n", file_name );
}
else
{
res = process_data ( FileData, offset );
free ( FileData );
}
return res;
}
int main ( int argc, const char** argv )
{
char* path;
size_t offset;
int res;
if ( argc != 3 )
{
fprintf(stderr, "Usage: raddr2line <exefile> <offset>\n");
exit(1);
}
path = convert_path ( argv[1] );
offset = my_atoi ( argv[2] );
res = process_file ( path, offset );
free ( path );
return res;
}

1556
sdk/tools/rsym/rsym.c Normal file

File diff suppressed because it is too large Load diff

138
sdk/tools/rsym/rsym.cmake.c Normal file
View file

@ -0,0 +1,138 @@
/*
* Usage: rsym input-file output-file
*
* There are two sources of information: the .stab/.stabstr
* sections of the executable and the COFF symbol table. Most
* of the information is in the .stab/.stabstr sections.
* However, most of our asm files don't contain .stab directives,
* so routines implemented in assembler won't show up in the
* .stab section. They are present in the COFF symbol table.
* So, we mostly use the .stab/.stabstr sections, but we augment
* the info there with info from the COFF symbol table when
* possible.
*
* This is a tool and is compiled using the host compiler,
* i.e. on Linux gcc and not mingw-gcc (cross-compiler).
* Therefore we can't include SDK headers and we have to
* duplicate some definitions here.
* Also note that the internal functions are "old C-style",
* returning an int, where a return of 0 means success and
* non-zero is failure.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "rsym.h"
int
IsDebugSection(PIMAGE_SECTION_HEADER Section)
{
/* This is a hack, but works for us */
return (Section->Name[0] == '/');
}
int main(int argc, char* argv[])
{
unsigned int i;
PSYMBOLFILE_HEADER SymbolFileHeader;
PIMAGE_NT_HEADERS NtHeaders;
PIMAGE_DOS_HEADER DosHeader;
PIMAGE_FILE_HEADER FileHeader;
PIMAGE_OPTIONAL_HEADER OptionalHeader;
PIMAGE_SECTION_HEADER SectionHeaders, LastSection;
char* path1;
char* path2;
FILE* out;
size_t FileSize;
void *FileData;
char elfhdr[] = { '\377', 'E', 'L', 'F' };
if (argc != 3)
{
fprintf(stderr, "Usage: rsym <exefile> <symfile>\n");
exit(1);
}
path1 = convert_path(argv[1]);
path2 = convert_path(argv[2]);
/* Load the input file into memory */
FileData = load_file( path1, &FileSize);
if ( !FileData )
{
fprintf(stderr, "An error occured loading '%s'\n", path1);
exit(1);
}
/* Check if MZ header exists */
DosHeader = (PIMAGE_DOS_HEADER) FileData;
if (DosHeader->e_magic != IMAGE_DOS_MAGIC || DosHeader->e_lfanew == 0L)
{
/* Ignore elf */
if (!memcmp(DosHeader, elfhdr, sizeof(elfhdr)))
exit(0);
perror("Input file is not a PE image.\n");
free(FileData);
exit(1);
}
/* Locate the headers */
NtHeaders = (PIMAGE_NT_HEADERS)((char*)FileData + DosHeader->e_lfanew);
FileHeader = &NtHeaders->FileHeader;
OptionalHeader = &NtHeaders->OptionalHeader;
/* Locate PE section headers */
SectionHeaders = (PIMAGE_SECTION_HEADER)((char*)OptionalHeader +
FileHeader->SizeOfOptionalHeader);
/* Loop all sections */
for (i = 0; i < FileHeader->NumberOfSections; i++)
{
/* Check if this is a debug section */
if (IsDebugSection(&SectionHeaders[i]))
{
/* Make sure we have the correct characteristics */
SectionHeaders[i].Characteristics |= IMAGE_SCN_CNT_INITIALIZED_DATA;
SectionHeaders[i].Characteristics &= ~(IMAGE_SCN_MEM_PURGEABLE | IMAGE_SCN_MEM_DISCARDABLE);
}
}
/* Get a pointer to the last section header */
LastSection = &SectionHeaders[FileHeader->NumberOfSections - 1];
/* Set the size of the last section to cover the rest of the PE */
LastSection->SizeOfRawData = FileSize - LastSection->PointerToRawData;
/* Check if the virtual section size is smaller than the raw data */
if (LastSection->Misc.VirtualSize < LastSection->SizeOfRawData)
{
/* Make sure the virtual size of the section cover the raw data */
LastSection->Misc.VirtualSize = ROUND_UP(LastSection->SizeOfRawData,
OptionalHeader->SectionAlignment);
/* Fix up image size */
OptionalHeader->SizeOfImage = LastSection->VirtualAddress +
LastSection->Misc.VirtualSize;
}
/* Open the output file */
out = fopen(path2, "wb");
if (out == NULL)
{
perror("Cannot open output file");
free(FileData);
exit(1);
}
/* Write the output file */
fwrite(FileData, 1, FileSize, out);
fclose(out);
free(FileData);
return 0;
}
/* EOF */

179
sdk/tools/rsym/rsym.h Normal file
View file

@ -0,0 +1,179 @@
/* rsym.h */
#pragma once
#include <typedefs.h>
#include <pecoff.h>
typedef struct {
USHORT f_magic; /* magic number */
USHORT f_nscns; /* number of sections */
ULONG f_timdat; /* time & date stamp */
ULONG f_symptr; /* file pointer to symtab */
ULONG f_nsyms; /* number of symtab entries */
USHORT f_opthdr; /* sizeof(optional hdr) */
USHORT f_flags; /* flags */
} FILHDR;
typedef struct {
char s_name[8]; /* section name */
ULONG s_paddr; /* physical address, aliased s_nlib */
ULONG s_vaddr; /* virtual address */
ULONG s_size; /* section size */
ULONG s_scnptr; /* file ptr to raw data for section */
ULONG s_relptr; /* file ptr to relocation */
ULONG s_lnnoptr; /* file ptr to line numbers */
USHORT s_nreloc; /* number of relocation entries */
USHORT s_nlnno; /* number of line number entries */
ULONG s_flags; /* flags */
} SCNHDR;
#pragma pack(4)
typedef struct _SYMBOLFILE_HEADER {
ULONG SymbolsOffset;
ULONG SymbolsLength;
ULONG StringsOffset;
ULONG StringsLength;
} SYMBOLFILE_HEADER, *PSYMBOLFILE_HEADER;
typedef struct _STAB_ENTRY {
ULONG n_strx; /* index into string table of name */
UCHAR n_type; /* type of symbol */
UCHAR n_other; /* misc info (usually empty) */
USHORT n_desc; /* description field */
ULONG n_value; /* value of symbol */
} STAB_ENTRY, *PSTAB_ENTRY;
/* http://www.math.utah.edu/docs/info/stabs_12.html */
#define N_GYSM 0x20
#define N_FNAME 0x22
#define N_FUN 0x24
#define N_STSYM 0x26
#define N_LCSYM 0x28
#define N_MAIN 0x2A
#define N_PC 0x30
#define N_NSYMS 0x32
#define N_NOMAP 0x34
#define N_RSYM 0x40
#define N_M2C 0x42
#define N_SLINE 0x44
#define N_DSLINE 0x46
#define N_BSLINE 0x48
#define N_BROWS 0x48
#define N_DEFD 0x4A
#define N_EHDECL 0x50
#define N_MOD2 0x50
#define N_CATCH 0x54
#define N_SSYM 0x60
#define N_SO 0x64
#define N_LSYM 0x80
#define N_BINCL 0x82
#define N_SOL 0x84
#define N_PSYM 0xA0
#define N_EINCL 0xA2
#define N_ENTRY 0xA4
#define N_LBRAC 0xC0
#define N_EXCL 0xC2
#define N_SCOPE 0xC4
#define N_RBRAC 0xE0
#define N_BCOMM 0xE2
#define N_ECOMM 0xE4
#define N_ECOML 0xE8
#define N_LENG 0xFE
/* COFF symbol table */
#define E_SYMNMLEN 8 /* # characters in a symbol name */
#define E_FILNMLEN 14 /* # characters in a file name */
#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
#define N_BTMASK (0xf)
#define N_TMASK (0x30)
#define N_BTSHFT (4)
#define N_TSHIFT (2)
/* derived types, in e_type */
#define DT_NON (0) /* no derived type */
#define DT_PTR (1) /* pointer */
#define DT_FCN (2) /* function */
#define DT_ARY (3) /* array */
#define BTYPE(x) ((x) & N_BTMASK)
#define ISPTR(x) (((x) & N_TMASK) == (DT_PTR << N_BTSHFT))
#define ISFCN(x) (((x) & N_TMASK) == (DT_FCN << N_BTSHFT))
#define ISARY(x) (((x) & N_TMASK) == (DT_ARY << N_BTSHFT))
#define ISTAG(x) ((x)==C_STRTAG||(x)==C_UNTAG||(x)==C_ENTAG)
#define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK))
#define C_EFCN 0xff /* physical end of function */
#define C_NULL 0
#define C_AUTO 1 /* automatic variable */
#define C_EXT 2 /* external symbol */
#define C_STAT 3 /* static */
#define C_REG 4 /* register variable */
#define C_EXTDEF 5 /* external definition */
#define C_LABEL 6 /* label */
#define C_ULABEL 7 /* undefined label */
#define C_MOS 8 /* member of structure */
#define C_ARG 9 /* function argument */
#define C_STRTAG 10 /* structure tag */
#define C_MOU 11 /* member of union */
#define C_UNTAG 12 /* union tag */
#define C_TPDEF 13 /* type definition */
#define C_USTATIC 14 /* undefined static */
#define C_ENTAG 15 /* enumeration tag */
#define C_MOE 16 /* member of enumeration */
#define C_REGPARM 17 /* register parameter */
#define C_FIELD 18 /* bit field */
#define C_AUTOARG 19 /* auto argument */
#define C_LASTENT 20 /* dummy entry (end of block) */
#define C_BLOCK 100 /* ".bb" or ".eb" */
#define C_FCN 101 /* ".bf" or ".ef" */
#define C_EOS 102 /* end of structure */
#define C_FILE 103 /* file name */
#define C_LINE 104 /* line # reformatted as symbol table entry */
#define C_ALIAS 105 /* duplicate tag */
#define C_HIDDEN 106 /* ext symbol in dmert public lib */
#pragma pack(1)
typedef struct _COFF_SYMENT
{
union
{
char e_name[E_SYMNMLEN];
struct
{
ULONG e_zeroes;
ULONG e_offset;
}
e;
}
e;
ULONG e_value;
short e_scnum;
USHORT e_type;
UCHAR e_sclass;
UCHAR e_numaux;
} COFF_SYMENT, *PCOFF_SYMENT;
#pragma pack(4)
#ifdef TARGET_i386
typedef ULONG TARGET_ULONG_PTR;
#else
typedef ULONGLONG TARGET_ULONG_PTR;
#endif
typedef struct _ROSSYM_ENTRY {
TARGET_ULONG_PTR Address;
ULONG FunctionOffset;
ULONG FileOffset;
ULONG SourceLine;
} ROSSYM_ENTRY, *PROSSYM_ENTRY;
#define ROUND_UP(N, S) (((N) + (S) - 1) & ~((S) - 1))
extern char*
convert_path(const char* origpath);
extern void*
load_file ( const char* file_name, size_t* file_size );

910
sdk/tools/rsym/rsym64.c Normal file
View file

@ -0,0 +1,910 @@
#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++;
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++;
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 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;
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((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((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((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 += DwDecodeUleb128((unsigned long*)&State->FramePtr, pc + Length);
State->IsUwop = 1;
break;
case DW_CFA_def_cfa_sf:
Length += DwDecodeUleb128(&State->Reg, pc + Length);
Length += DwDecodeSleb128(&State->FramePtr, pc + Length);
State->FramePtr *= 8; // data alignment
State->IsUwop = 1;
break;
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;
}
/* 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;
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;
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;
}
#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;
}
}
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;
char *pInst, *pmax;
DW2CFSTATE State;
File->cFuncs = 0;
File->cScopes = 0;
File->cUWOP = 0;
State.FramePtr = 0;
State.TryLevel = 0;
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 */
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);
/* 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->VirtualAddress = File->NewSectionHeaders[i - 1].VirtualAddress +
File->NewSectionHeaders[i - 1].SizeOfRawData;
pshp->SizeOfRawData = ROUND_UP(pshp->Misc.VirtualSize, FileAlignment);
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, 0, pshp->SizeOfRawData);
/* Init exception data dir */
Dir = &File->OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION];
Dir->VirtualAddress = pshp->VirtualAddress;
Dir->Size = pshp->Misc.VirtualSize;
/* Initialize section header for .xdata */
File->xdata.idx = File->pdata.idx + 1;
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);
memset(File->xdata.p, 0, pshx->SizeOfRawData);
i = 0;
Offset = File->eh_frame.psh->VirtualAddress;
xdata_va = pshx->VirtualAddress;
xdata_p = File->xdata.p;
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;
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)
{
int ret, Size, Pos = 0;
DWORD CheckSum;
ULONG i, Alignment;
Alignment = File->OptionalHeader->FileAlignment;
/* Update section count */
File->FileHeader->NumberOfSections = File->UsedSections + 2; // FIXME!!!
/* Update SizeOfImage */
Size = File->xdata.psh->VirtualAddress
+ File->xdata.psh->SizeOfRawData;
File->OptionalHeader->SizeOfImage = Size;
/* Recalculate checksum */
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;
ULONG Alignment, CurrentPos;
int i, j;
/* Check if MZ header exists */
File->DosHeader = (PIMAGE_DOS_HEADER)File->FilePtr;
if ((File->DosHeader->e_magic != IMAGE_DOS_MAGIC) ||
(File->DosHeader->e_lfanew == 0L))
{
perror("Input file is not a PE image.\n");
return -1;
}
/* Locate PE file header */
File->FileHeader = (PIMAGE_FILE_HEADER)(File->FilePtr +
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");
return -1;
}
/* Locate optional header */
File->OptionalHeader = (PIMAGE_OPTIONAL_HEADER64)(File->FileHeader + 1);
/* Check if checksum is correct */
OldChecksum = File->OptionalHeader->CheckSum;
File->OptionalHeader->CheckSum = 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");
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 whether 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;
// 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.psh = &File->SectionHeaders[i];
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);
}
ret = ParsePEHeaders(&File);
if (ret != 1)
{
free(File.FilePtr);
exit(ret == -1 ? 1 : 0);
}
File.AlignBuf = malloc(File.OptionalHeader->FileAlignment);
memset(File.AlignBuf, 0, File.OptionalHeader->FileAlignment);
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;
}

186
sdk/tools/rsym/rsym64.h Normal file
View file

@ -0,0 +1,186 @@
#pragma once
//C_ASSERT(sizeof(ULONG) == 4);
typedef unsigned char UBYTE;
#if defined(_MSC_VER) || defined(__MINGW32__)
typedef unsigned __int64 ULONG64;
#else
#include <stdint.h>
typedef uint64_t ULONG64;
#endif
#define IMAGE_FILE_MACHINE_I386 0x14c
#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;

View file

@ -0,0 +1,62 @@
/* rsym_common.c */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "rsym.h"
char*
convert_path ( const char* origpath )
{
char* newpath;
int i;
newpath = strdup(origpath);
i = 0;
while (newpath[i] != 0)
{
#ifdef UNIX_PATHS
if (newpath[i] == '\\')
{
newpath[i] = '/';
}
#else
#ifdef DOS_PATHS
if (newpath[i] == '/')
{
newpath[i] = '\\';
}
#endif
#endif
i++;
}
return(newpath);
}
void*
load_file ( const char* file_name, size_t* file_size )
{
FILE* f;
void* FileData = NULL;
f = fopen ( file_name, "rb" );
if (f != NULL)
{
fseek(f, 0L, SEEK_END);
*file_size = ftell(f);
fseek(f, 0L, SEEK_SET);
FileData = malloc(*file_size);
if (FileData != NULL)
{
if ( *file_size != fread(FileData, 1, *file_size, f) )
{
free(FileData);
FileData = NULL;
}
}
fclose(f);
}
return FileData;
}