diff --git a/.gitignore b/.gitignore
index 902348ce..2bcddd92 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,7 +15,7 @@
.gdb_history
a.out
tcc_g
-tcc
+tcc/tcc
tcc_c
tcc_p
*-tcc
@@ -76,4 +76,6 @@ stamp-h1
*_old
*.cache
.deps
-build-aux
\ No newline at end of file
+build-aux
+configure
+.dirstamp
\ No newline at end of file
diff --git a/Changelog b/Changelog
index 7ccf11da..fae6936a 100644
--- a/Changelog
+++ b/Changelog
@@ -72,7 +72,7 @@ User interface:
- -pthread option (same as -D_REENTRANT -lpthread) (Henry Kroll III)
- -m32/-m64 to re-exec cross compiler (Henry Kroll III)
- -Wl, Mimic all GNU -option forms supported by ld (Kirill Smelkov)
-- new LIBTCCAPI tcc_set_options() (grischka)
+- new tcc_set_options() (grischka)
Platforms:
- Many improvements for x86-64 target (Shinichiro Hamaji, Michael Matz, grischka)
diff --git a/Makefile.am b/Makefile.am
index bc67671e..d53d090e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,12 +1,3 @@
AM_CFLAGS =
-
-noinst_LIBRARIES = libtcc.a
-libtcc_a_SOURCES = libtcc.c tccpp.c tccgen.c tccdbg.c tccasm.c tccelf.c i386-gen.c i386-link.c i386-asm.c
-libtcc_a_CPPFLAGS = -I$(top_srcdir)
-
-bin_PROGRAMS = tcc
-
-tcc_SOURCES = tcc.c
-tcc_LDADD = libtcc.a
-tcc_CPPFLAGS = -I$(top_srcdir)
+SUBDIRS = libtcc tcc
diff --git a/compile_flags.txt b/compile_flags.txt
new file mode 100644
index 00000000..3f2296c6
--- /dev/null
+++ b/compile_flags.txt
@@ -0,0 +1,3 @@
+-I.
+-DHAVE_CONFIG_H
+-Ilibtcc
\ No newline at end of file
diff --git a/configure.ac b/configure.ac
index 05657655..96555617 100644
--- a/configure.ac
+++ b/configure.ac
@@ -7,7 +7,10 @@ AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([foreign subdir-objects -Werror -Wall])
AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([
+ Makefile
+ libtcc/Makefile
+ tcc/Makefile])
AC_LANG([C])
AC_PROG_CC
diff --git a/dwarf.h b/dwarf.h
deleted file mode 100644
index c961bc36..00000000
--- a/dwarf.h
+++ /dev/null
@@ -1,1046 +0,0 @@
-/* This file defines standard DWARF types, structures, and macros.
- Copyright (C) 2000-2011, 2014, 2016, 2017, 2018 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils 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 copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see . */
-
-#ifndef _DWARF_H
-#define _DWARF_H 1
-
-/* DWARF Unit Header Types. */
-enum
- {
- DW_UT_compile = 0x01,
- DW_UT_type = 0x02,
- DW_UT_partial = 0x03,
- DW_UT_skeleton = 0x04,
- DW_UT_split_compile = 0x05,
- DW_UT_split_type = 0x06,
-
- DW_UT_lo_user = 0x80,
- DW_UT_hi_user = 0xff
- };
-
-/* DWARF tags. */
-enum
- {
- 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,
- /* 0x06 reserved. */
- /* 0x07 reserved. */
- DW_TAG_imported_declaration = 0x08,
- /* 0x09 reserved. */
- DW_TAG_label = 0x0a,
- DW_TAG_lexical_block = 0x0b,
- /* 0x0c reserved. */
- DW_TAG_member = 0x0d,
- /* 0x0e reserved. */
- 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,
- /* 0x14 reserved. */
- 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_parameter = 0x2f,
- DW_TAG_template_value_parameter = 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,
- 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,
- /* 0x3e reserved. Was DW_TAG_mutable_type. */
- DW_TAG_condition = 0x3f,
- DW_TAG_shared_type = 0x40,
- DW_TAG_type_unit = 0x41,
- DW_TAG_rvalue_reference_type = 0x42,
- DW_TAG_template_alias = 0x43,
- DW_TAG_coarray_type = 0x44,
- DW_TAG_generic_subrange = 0x45,
- DW_TAG_dynamic_type = 0x46,
- DW_TAG_atomic_type = 0x47,
- DW_TAG_call_site = 0x48,
- DW_TAG_call_site_parameter = 0x49,
- DW_TAG_skeleton_unit = 0x4a,
- DW_TAG_immutable_type = 0x4b,
-
- DW_TAG_lo_user = 0x4080,
-
- DW_TAG_MIPS_loop = 0x4081,
- DW_TAG_format_label = 0x4101,
- DW_TAG_function_template = 0x4102,
- DW_TAG_class_template = 0x4103,
-
- DW_TAG_GNU_BINCL = 0x4104,
- DW_TAG_GNU_EINCL = 0x4105,
-
- DW_TAG_GNU_template_template_param = 0x4106,
- DW_TAG_GNU_template_parameter_pack = 0x4107,
- DW_TAG_GNU_formal_parameter_pack = 0x4108,
- DW_TAG_GNU_call_site = 0x4109,
- DW_TAG_GNU_call_site_parameter = 0x410a,
-
- DW_TAG_hi_user = 0xffff
- };
-
-
-/* Children determination encodings. */
-enum
- {
- DW_CHILDREN_no = 0,
- DW_CHILDREN_yes = 1
- };
-
-
-/* DWARF attributes encodings. */
-enum
- {
- DW_AT_sibling = 0x01,
- DW_AT_location = 0x02,
- DW_AT_name = 0x03,
- /* 0x04 reserved. */
- /* 0x05 reserved. */
- /* 0x06 reserved. */
- /* 0x07 reserved. */
- /* 0x08 reserved. */
- DW_AT_ordering = 0x09,
- /* 0x0a reserved. */
- DW_AT_byte_size = 0x0b,
- DW_AT_bit_offset = 0x0c, /* Deprecated in DWARF4. */
- DW_AT_bit_size = 0x0d,
- /* 0x0e reserved. */
- /* 0x0f reserved. */
- DW_AT_stmt_list = 0x10,
- DW_AT_low_pc = 0x11,
- DW_AT_high_pc = 0x12,
- DW_AT_language = 0x13,
- /* 0x14 reserved. */
- 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,
- /* 0x1f reserved. */
- DW_AT_inline = 0x20,
- DW_AT_is_optional = 0x21,
- DW_AT_lower_bound = 0x22,
- /* 0x23 reserved. */
- /* 0x24 reserved. */
- DW_AT_producer = 0x25,
- /* 0x26 reserved. */
- DW_AT_prototyped = 0x27,
- /* 0x28 reserved. */
- /* 0x29 reserved. */
- DW_AT_return_addr = 0x2a,
- /* 0x2b reserved. */
- DW_AT_start_scope = 0x2c,
- /* 0x2d reserved. */
- DW_AT_bit_stride = 0x2e,
- DW_AT_upper_bound = 0x2f,
- /* 0x30 reserved. */
- 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, /* Deprecated in DWARF5. */
- DW_AT_namelist_item = 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,
- DW_AT_allocated = 0x4e,
- DW_AT_associated = 0x4f,
- DW_AT_data_location = 0x50,
- DW_AT_byte_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,
- DW_AT_description = 0x5a,
- DW_AT_binary_scale = 0x5b,
- DW_AT_decimal_scale = 0x5c,
- DW_AT_small = 0x5d,
- DW_AT_decimal_sign = 0x5e,
- DW_AT_digit_count = 0x5f,
- DW_AT_picture_string = 0x60,
- DW_AT_mutable = 0x61,
- DW_AT_threads_scaled = 0x62,
- DW_AT_explicit = 0x63,
- DW_AT_object_pointer = 0x64,
- DW_AT_endianity = 0x65,
- DW_AT_elemental = 0x66,
- DW_AT_pure = 0x67,
- DW_AT_recursive = 0x68,
- DW_AT_signature = 0x69,
- DW_AT_main_subprogram = 0x6a,
- DW_AT_data_bit_offset = 0x6b,
- DW_AT_const_expr = 0x6c,
- DW_AT_enum_class = 0x6d,
- DW_AT_linkage_name = 0x6e,
- DW_AT_string_length_bit_size = 0x6f,
- DW_AT_string_length_byte_size = 0x70,
- DW_AT_rank = 0x71,
- DW_AT_str_offsets_base = 0x72,
- DW_AT_addr_base = 0x73,
- DW_AT_rnglists_base = 0x74,
- /* 0x75 reserved. */
- DW_AT_dwo_name = 0x76,
- DW_AT_reference = 0x77,
- DW_AT_rvalue_reference = 0x78,
- DW_AT_macros = 0x79,
- DW_AT_call_all_calls = 0x7a,
- DW_AT_call_all_source_calls = 0x7b,
- DW_AT_call_all_tail_calls = 0x7c,
- DW_AT_call_return_pc = 0x7d,
- DW_AT_call_value = 0x7e,
- DW_AT_call_origin = 0x7f,
- DW_AT_call_parameter = 0x80,
- DW_AT_call_pc = 0x81,
- DW_AT_call_tail_call = 0x82,
- DW_AT_call_target = 0x83,
- DW_AT_call_target_clobbered = 0x84,
- DW_AT_call_data_location = 0x85,
- DW_AT_call_data_value = 0x86,
- DW_AT_noreturn = 0x87,
- DW_AT_alignment = 0x88,
- DW_AT_export_symbols = 0x89,
- DW_AT_deleted = 0x8a,
- DW_AT_defaulted = 0x8b,
- DW_AT_loclists_base = 0x8c,
-
- DW_AT_lo_user = 0x2000,
-
- 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,
- DW_AT_MIPS_stride_byte = 0x200c,
- DW_AT_MIPS_stride_elem = 0x200d,
- DW_AT_MIPS_ptr_dopetype = 0x200e,
- DW_AT_MIPS_allocatable_dopetype = 0x200f,
- DW_AT_MIPS_assumed_shape_dopetype = 0x2010,
- DW_AT_MIPS_assumed_size = 0x2011,
-
- /* 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,
- DW_AT_GNU_guarded_by = 0x2108,
- DW_AT_GNU_pt_guarded_by = 0x2109,
- DW_AT_GNU_guarded = 0x210a,
- DW_AT_GNU_pt_guarded = 0x210b,
- DW_AT_GNU_locks_excluded = 0x210c,
- DW_AT_GNU_exclusive_locks_required = 0x210d,
- DW_AT_GNU_shared_locks_required = 0x210e,
- DW_AT_GNU_odr_signature = 0x210f,
- DW_AT_GNU_template_name = 0x2110,
- DW_AT_GNU_call_site_value = 0x2111,
- DW_AT_GNU_call_site_data_value = 0x2112,
- DW_AT_GNU_call_site_target = 0x2113,
- DW_AT_GNU_call_site_target_clobbered = 0x2114,
- DW_AT_GNU_tail_call = 0x2115,
- DW_AT_GNU_all_tail_call_sites = 0x2116,
- DW_AT_GNU_all_call_sites = 0x2117,
- DW_AT_GNU_all_source_call_sites = 0x2118,
- DW_AT_GNU_locviews = 0x2137,
- DW_AT_GNU_entry_view = 0x2138,
- DW_AT_GNU_macros = 0x2119,
- DW_AT_GNU_deleted = 0x211a,
- /* GNU Debug Fission extensions. */
- DW_AT_GNU_dwo_name = 0x2130,
- DW_AT_GNU_dwo_id = 0x2131,
- DW_AT_GNU_ranges_base = 0x2132,
- DW_AT_GNU_addr_base = 0x2133,
- DW_AT_GNU_pubnames = 0x2134,
- DW_AT_GNU_pubtypes = 0x2135,
-
- /* https://gcc.gnu.org/wiki/DW_AT_GNU_numerator_denominator */
- DW_AT_GNU_numerator = 0x2303,
- DW_AT_GNU_denominator = 0x2304,
- /* https://gcc.gnu.org/wiki/DW_AT_GNU_bias */
- DW_AT_GNU_bias = 0x2305,
-
- DW_AT_hi_user = 0x3fff
- };
-
-/* Old unofficially attribute names. Should not be used.
- Will not appear in known-dwarf.h */
-
-/* DWARF1 array subscripts and element data types. */
-#define DW_AT_subscr_data 0x0a
-/* DWARF1 enumeration literals. */
-#define DW_AT_element_list 0x0f
-/* DWARF1 reference for variable to member structure, class or union. */
-#define DW_AT_member 0x14
-
-/* DWARF form encodings. */
-enum
- {
- 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,
- DW_FORM_sec_offset = 0x17,
- DW_FORM_exprloc = 0x18,
- DW_FORM_flag_present = 0x19,
- DW_FORM_strx = 0x1a,
- DW_FORM_addrx = 0x1b,
- DW_FORM_ref_sup4 = 0x1c,
- DW_FORM_strp_sup = 0x1d,
- DW_FORM_data16 = 0x1e,
- DW_FORM_line_strp = 0x1f,
- DW_FORM_ref_sig8 = 0x20,
- DW_FORM_implicit_const = 0x21,
- DW_FORM_loclistx = 0x22,
- DW_FORM_rnglistx = 0x23,
- DW_FORM_ref_sup8 = 0x24,
- DW_FORM_strx1 = 0x25,
- DW_FORM_strx2 = 0x26,
- DW_FORM_strx3 = 0x27,
- DW_FORM_strx4 = 0x28,
- DW_FORM_addrx1 = 0x29,
- DW_FORM_addrx2 = 0x2a,
- DW_FORM_addrx3 = 0x2b,
- DW_FORM_addrx4 = 0x2c,
-
- /* GNU Debug Fission extensions. */
- DW_FORM_GNU_addr_index = 0x1f01,
- DW_FORM_GNU_str_index = 0x1f02,
-
- DW_FORM_GNU_ref_alt = 0x1f20, /* offset in alternate .debuginfo. */
- DW_FORM_GNU_strp_alt = 0x1f21 /* offset in alternate .debug_str. */
- };
-
-
-/* DWARF location operation encodings. */
-enum
- {
- DW_OP_addr = 0x03, /* Constant address. */
- DW_OP_deref = 0x06,
- DW_OP_const1u = 0x08, /* Unsigned 1-byte constant. */
- DW_OP_const1s = 0x09, /* Signed 1-byte constant. */
- DW_OP_const2u = 0x0a, /* Unsigned 2-byte constant. */
- DW_OP_const2s = 0x0b, /* Signed 2-byte constant. */
- DW_OP_const4u = 0x0c, /* Unsigned 4-byte constant. */
- DW_OP_const4s = 0x0d, /* Signed 4-byte constant. */
- DW_OP_const8u = 0x0e, /* Unsigned 8-byte constant. */
- DW_OP_const8s = 0x0f, /* Signed 8-byte constant. */
- DW_OP_constu = 0x10, /* Unsigned LEB128 constant. */
- DW_OP_consts = 0x11, /* Signed LEB128 constant. */
- DW_OP_dup = 0x12,
- DW_OP_drop = 0x13,
- DW_OP_over = 0x14,
- DW_OP_pick = 0x15, /* 1-byte stack index. */
- 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, /* Unsigned LEB128 addend. */
- DW_OP_shl = 0x24,
- DW_OP_shr = 0x25,
- DW_OP_shra = 0x26,
- DW_OP_xor = 0x27,
- DW_OP_bra = 0x28, /* Signed 2-byte constant. */
- 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, /* Signed 2-byte constant. */
- DW_OP_lit0 = 0x30, /* Literal 0. */
- DW_OP_lit1 = 0x31, /* Literal 1. */
- DW_OP_lit2 = 0x32, /* Literal 2. */
- DW_OP_lit3 = 0x33, /* Literal 3. */
- DW_OP_lit4 = 0x34, /* Literal 4. */
- DW_OP_lit5 = 0x35, /* Literal 5. */
- DW_OP_lit6 = 0x36, /* Literal 6. */
- DW_OP_lit7 = 0x37, /* Literal 7. */
- DW_OP_lit8 = 0x38, /* Literal 8. */
- DW_OP_lit9 = 0x39, /* Literal 9. */
- DW_OP_lit10 = 0x3a, /* Literal 10. */
- DW_OP_lit11 = 0x3b, /* Literal 11. */
- DW_OP_lit12 = 0x3c, /* Literal 12. */
- DW_OP_lit13 = 0x3d, /* Literal 13. */
- DW_OP_lit14 = 0x3e, /* Literal 14. */
- DW_OP_lit15 = 0x3f, /* Literal 15. */
- DW_OP_lit16 = 0x40, /* Literal 16. */
- DW_OP_lit17 = 0x41, /* Literal 17. */
- DW_OP_lit18 = 0x42, /* Literal 18. */
- DW_OP_lit19 = 0x43, /* Literal 19. */
- DW_OP_lit20 = 0x44, /* Literal 20. */
- DW_OP_lit21 = 0x45, /* Literal 21. */
- DW_OP_lit22 = 0x46, /* Literal 22. */
- DW_OP_lit23 = 0x47, /* Literal 23. */
- DW_OP_lit24 = 0x48, /* Literal 24. */
- DW_OP_lit25 = 0x49, /* Literal 25. */
- DW_OP_lit26 = 0x4a, /* Literal 26. */
- DW_OP_lit27 = 0x4b, /* Literal 27. */
- DW_OP_lit28 = 0x4c, /* Literal 28. */
- DW_OP_lit29 = 0x4d, /* Literal 29. */
- DW_OP_lit30 = 0x4e, /* Literal 30. */
- DW_OP_lit31 = 0x4f, /* Literal 31. */
- DW_OP_reg0 = 0x50, /* Register 0. */
- DW_OP_reg1 = 0x51, /* Register 1. */
- DW_OP_reg2 = 0x52, /* Register 2. */
- DW_OP_reg3 = 0x53, /* Register 3. */
- DW_OP_reg4 = 0x54, /* Register 4. */
- DW_OP_reg5 = 0x55, /* Register 5. */
- DW_OP_reg6 = 0x56, /* Register 6. */
- DW_OP_reg7 = 0x57, /* Register 7. */
- DW_OP_reg8 = 0x58, /* Register 8. */
- DW_OP_reg9 = 0x59, /* Register 9. */
- DW_OP_reg10 = 0x5a, /* Register 10. */
- DW_OP_reg11 = 0x5b, /* Register 11. */
- DW_OP_reg12 = 0x5c, /* Register 12. */
- DW_OP_reg13 = 0x5d, /* Register 13. */
- DW_OP_reg14 = 0x5e, /* Register 14. */
- DW_OP_reg15 = 0x5f, /* Register 15. */
- DW_OP_reg16 = 0x60, /* Register 16. */
- DW_OP_reg17 = 0x61, /* Register 17. */
- DW_OP_reg18 = 0x62, /* Register 18. */
- DW_OP_reg19 = 0x63, /* Register 19. */
- DW_OP_reg20 = 0x64, /* Register 20. */
- DW_OP_reg21 = 0x65, /* Register 21. */
- DW_OP_reg22 = 0x66, /* Register 22. */
- DW_OP_reg23 = 0x67, /* Register 24. */
- DW_OP_reg24 = 0x68, /* Register 24. */
- DW_OP_reg25 = 0x69, /* Register 25. */
- DW_OP_reg26 = 0x6a, /* Register 26. */
- DW_OP_reg27 = 0x6b, /* Register 27. */
- DW_OP_reg28 = 0x6c, /* Register 28. */
- DW_OP_reg29 = 0x6d, /* Register 29. */
- DW_OP_reg30 = 0x6e, /* Register 30. */
- DW_OP_reg31 = 0x6f, /* Register 31. */
- DW_OP_breg0 = 0x70, /* Base register 0. */
- DW_OP_breg1 = 0x71, /* Base register 1. */
- DW_OP_breg2 = 0x72, /* Base register 2. */
- DW_OP_breg3 = 0x73, /* Base register 3. */
- DW_OP_breg4 = 0x74, /* Base register 4. */
- DW_OP_breg5 = 0x75, /* Base register 5. */
- DW_OP_breg6 = 0x76, /* Base register 6. */
- DW_OP_breg7 = 0x77, /* Base register 7. */
- DW_OP_breg8 = 0x78, /* Base register 8. */
- DW_OP_breg9 = 0x79, /* Base register 9. */
- DW_OP_breg10 = 0x7a, /* Base register 10. */
- DW_OP_breg11 = 0x7b, /* Base register 11. */
- DW_OP_breg12 = 0x7c, /* Base register 12. */
- DW_OP_breg13 = 0x7d, /* Base register 13. */
- DW_OP_breg14 = 0x7e, /* Base register 14. */
- DW_OP_breg15 = 0x7f, /* Base register 15. */
- DW_OP_breg16 = 0x80, /* Base register 16. */
- DW_OP_breg17 = 0x81, /* Base register 17. */
- DW_OP_breg18 = 0x82, /* Base register 18. */
- DW_OP_breg19 = 0x83, /* Base register 19. */
- DW_OP_breg20 = 0x84, /* Base register 20. */
- DW_OP_breg21 = 0x85, /* Base register 21. */
- DW_OP_breg22 = 0x86, /* Base register 22. */
- DW_OP_breg23 = 0x87, /* Base register 23. */
- DW_OP_breg24 = 0x88, /* Base register 24. */
- DW_OP_breg25 = 0x89, /* Base register 25. */
- DW_OP_breg26 = 0x8a, /* Base register 26. */
- DW_OP_breg27 = 0x8b, /* Base register 27. */
- DW_OP_breg28 = 0x8c, /* Base register 28. */
- DW_OP_breg29 = 0x8d, /* Base register 29. */
- DW_OP_breg30 = 0x8e, /* Base register 30. */
- DW_OP_breg31 = 0x8f, /* Base register 31. */
- DW_OP_regx = 0x90, /* Unsigned LEB128 register. */
- DW_OP_fbreg = 0x91, /* Signed LEB128 offset. */
- DW_OP_bregx = 0x92, /* ULEB128 register followed by SLEB128 off. */
- DW_OP_piece = 0x93, /* ULEB128 size of piece addressed. */
- DW_OP_deref_size = 0x94, /* 1-byte size of data retrieved. */
- DW_OP_xderef_size = 0x95, /* 1-byte size of data retrieved. */
- DW_OP_nop = 0x96,
- DW_OP_push_object_address = 0x97,
- DW_OP_call2 = 0x98,
- DW_OP_call4 = 0x99,
- DW_OP_call_ref = 0x9a,
- DW_OP_form_tls_address = 0x9b,/* TLS offset to address in current thread */
- DW_OP_call_frame_cfa = 0x9c,/* CFA as determined by CFI. */
- DW_OP_bit_piece = 0x9d, /* ULEB128 size and ULEB128 offset in bits. */
- DW_OP_implicit_value = 0x9e, /* DW_FORM_block follows opcode. */
- DW_OP_stack_value = 0x9f, /* No operands, special like DW_OP_piece. */
-
- DW_OP_implicit_pointer = 0xa0,
- DW_OP_addrx = 0xa1,
- DW_OP_constx = 0xa2,
- DW_OP_entry_value = 0xa3,
- DW_OP_const_type = 0xa4,
- DW_OP_regval_type = 0xa5,
- DW_OP_deref_type = 0xa6,
- DW_OP_xderef_type = 0xa7,
- DW_OP_convert = 0xa8,
- DW_OP_reinterpret = 0xa9,
-
- /* GNU extensions. */
- DW_OP_GNU_push_tls_address = 0xe0,
- DW_OP_GNU_uninit = 0xf0,
- DW_OP_GNU_encoded_addr = 0xf1,
- DW_OP_GNU_implicit_pointer = 0xf2,
- DW_OP_GNU_entry_value = 0xf3,
- DW_OP_GNU_const_type = 0xf4,
- DW_OP_GNU_regval_type = 0xf5,
- DW_OP_GNU_deref_type = 0xf6,
- DW_OP_GNU_convert = 0xf7,
- DW_OP_GNU_reinterpret = 0xf9,
- DW_OP_GNU_parameter_ref = 0xfa,
-
- /* GNU Debug Fission extensions. */
- DW_OP_GNU_addr_index = 0xfb,
- DW_OP_GNU_const_index = 0xfc,
-
- DW_OP_GNU_variable_value = 0xfd,
-
- DW_OP_lo_user = 0xe0, /* Implementation-defined range start. */
- DW_OP_hi_user = 0xff /* Implementation-defined range end. */
- };
-
-
-/* DWARF base type encodings. */
-enum
- {
- 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,
- DW_ATE_imaginary_float = 0x9,
- DW_ATE_packed_decimal = 0xa,
- DW_ATE_numeric_string = 0xb,
- DW_ATE_edited = 0xc,
- DW_ATE_signed_fixed = 0xd,
- DW_ATE_unsigned_fixed = 0xe,
- DW_ATE_decimal_float = 0xf,
- DW_ATE_UTF = 0x10,
- DW_ATE_UCS = 0x11,
- DW_ATE_ASCII = 0x12,
-
- DW_ATE_lo_user = 0x80,
- DW_ATE_hi_user = 0xff
- };
-
-
-/* DWARF decimal sign encodings. */
-enum
- {
- DW_DS_unsigned = 1,
- DW_DS_leading_overpunch = 2,
- DW_DS_trailing_overpunch = 3,
- DW_DS_leading_separate = 4,
- DW_DS_trailing_separate = 5,
- };
-
-
-/* DWARF endianity encodings. */
-enum
- {
- DW_END_default = 0,
- DW_END_big = 1,
- DW_END_little = 2,
-
- DW_END_lo_user = 0x40,
- DW_END_hi_user = 0xff
- };
-
-
-/* DWARF accessibility encodings. */
-enum
- {
- DW_ACCESS_public = 1,
- DW_ACCESS_protected = 2,
- DW_ACCESS_private = 3
- };
-
-
-/* DWARF visibility encodings. */
-enum
- {
- DW_VIS_local = 1,
- DW_VIS_exported = 2,
- DW_VIS_qualified = 3
- };
-
-
-/* DWARF virtuality encodings. */
-enum
- {
- DW_VIRTUALITY_none = 0,
- DW_VIRTUALITY_virtual = 1,
- DW_VIRTUALITY_pure_virtual = 2
- };
-
-
-/* DWARF language encodings. */
-enum
- {
- DW_LANG_C89 = 0x0001, /* ISO C:1989 */
- DW_LANG_C = 0x0002, /* C */
- DW_LANG_Ada83 = 0x0003, /* ISO Ada:1983 */
- DW_LANG_C_plus_plus = 0x0004, /* ISO C++:1998 */
- DW_LANG_Cobol74 = 0x0005, /* ISO Cobol:1974 */
- DW_LANG_Cobol85 = 0x0006, /* ISO Cobol:1985 */
- DW_LANG_Fortran77 = 0x0007, /* ISO FORTRAN 77 */
- DW_LANG_Fortran90 = 0x0008, /* ISO Fortran 90 */
- DW_LANG_Pascal83 = 0x0009, /* ISO Pascal:1983 */
- DW_LANG_Modula2 = 0x000a, /* ISO Modula-2:1996 */
- DW_LANG_Java = 0x000b, /* Java */
- DW_LANG_C99 = 0x000c, /* ISO C:1999 */
- DW_LANG_Ada95 = 0x000d, /* ISO Ada:1995 */
- DW_LANG_Fortran95 = 0x000e, /* ISO Fortran 95 */
- DW_LANG_PLI = 0x000f, /* ISO PL/1:1976 */
- DW_LANG_ObjC = 0x0010, /* Objective-C */
- DW_LANG_ObjC_plus_plus = 0x0011, /* Objective-C++ */
- DW_LANG_UPC = 0x0012, /* Unified Parallel C */
- DW_LANG_D = 0x0013, /* D */
- DW_LANG_Python = 0x0014, /* Python */
- DW_LANG_OpenCL = 0x0015, /* OpenCL */
- DW_LANG_Go = 0x0016, /* Go */
- DW_LANG_Modula3 = 0x0017, /* Modula-3 */
- DW_LANG_Haskell = 0x0018, /* Haskell */
- DW_LANG_C_plus_plus_03 = 0x0019, /* ISO C++:2003 */
- DW_LANG_C_plus_plus_11 = 0x001a, /* ISO C++:2011 */
- DW_LANG_OCaml = 0x001b, /* OCaml */
- DW_LANG_Rust = 0x001c, /* Rust */
- DW_LANG_C11 = 0x001d, /* ISO C:2011 */
- DW_LANG_Swift = 0x001e, /* Swift */
- DW_LANG_Julia = 0x001f, /* Julia */
- DW_LANG_Dylan = 0x0020, /* Dylan */
- DW_LANG_C_plus_plus_14 = 0x0021, /* ISO C++:2014 */
- DW_LANG_Fortran03 = 0x0022, /* ISO/IEC 1539-1:2004 */
- DW_LANG_Fortran08 = 0x0023, /* ISO/IEC 1539-1:2010 */
- DW_LANG_RenderScript = 0x0024, /* RenderScript Kernal Language */
- DW_LANG_BLISS = 0x0025, /* BLISS */
-
- DW_LANG_lo_user = 0x8000,
- DW_LANG_Mips_Assembler = 0x8001, /* Assembler */
- DW_LANG_hi_user = 0xffff
- };
-
-/* Old (typo) '1' != 'I'. */
-#define DW_LANG_PL1 DW_LANG_PLI
-
-/* DWARF identifier case encodings. */
-enum
- {
- DW_ID_case_sensitive = 0,
- DW_ID_up_case = 1,
- DW_ID_down_case = 2,
- DW_ID_case_insensitive = 3
- };
-
-
-/* DWARF calling conventions encodings.
- Used as values of DW_AT_calling_convention for subroutines
- (normal, program or nocall) or structures, unions and class types
- (normal, reference or value). */
-enum
- {
- DW_CC_normal = 0x1,
- DW_CC_program = 0x2,
- DW_CC_nocall = 0x3,
- DW_CC_pass_by_reference = 0x4,
- DW_CC_pass_by_value = 0x5,
- DW_CC_lo_user = 0x40,
- DW_CC_hi_user = 0xff
- };
-
-
-/* DWARF inline encodings. */
-enum
- {
- DW_INL_not_inlined = 0,
- DW_INL_inlined = 1,
- DW_INL_declared_not_inlined = 2,
- DW_INL_declared_inlined = 3
- };
-
-
-/* DWARF ordering encodings. */
-enum
- {
- DW_ORD_row_major = 0,
- DW_ORD_col_major = 1
- };
-
-
-/* DWARF discriminant descriptor encodings. */
-enum
- {
- DW_DSC_label = 0,
- DW_DSC_range = 1
- };
-
-/* DWARF defaulted member function encodings. */
-enum
- {
- DW_DEFAULTED_no = 0,
- DW_DEFAULTED_in_class = 1,
- DW_DEFAULTED_out_of_class = 2
- };
-
-/* DWARF line content descriptions. */
-enum
- {
- DW_LNCT_path = 0x1,
- DW_LNCT_directory_index = 0x2,
- DW_LNCT_timestamp = 0x3,
- DW_LNCT_size = 0x4,
- DW_LNCT_MD5 = 0x5,
- DW_LNCT_lo_user = 0x2000,
- DW_LNCT_hi_user = 0x3fff
- };
-
-/* DWARF standard opcode encodings. */
-enum
- {
- 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,
- DW_LNS_set_prologue_end = 10,
- DW_LNS_set_epilogue_begin = 11,
- DW_LNS_set_isa = 12
- };
-
-
-/* DWARF extended opcode encodings. */
-enum
- {
- DW_LNE_end_sequence = 1,
- DW_LNE_set_address = 2,
- DW_LNE_define_file = 3,
- DW_LNE_set_discriminator = 4,
-
- DW_LNE_lo_user = 128,
-
- DW_LNE_NVIDIA_inlined_call = 144,
- DW_LNE_NVIDIA_set_function_name = 145,
-
- DW_LNE_hi_user = 255
- };
-
-
-/* DWARF macinfo type encodings. */
-enum
- {
- DW_MACINFO_define = 1,
- DW_MACINFO_undef = 2,
- DW_MACINFO_start_file = 3,
- DW_MACINFO_end_file = 4,
- DW_MACINFO_vendor_ext = 255
- };
-
-
-/* DWARF debug_macro type encodings. */
-enum
- {
- DW_MACRO_define = 0x01,
- DW_MACRO_undef = 0x02,
- DW_MACRO_start_file = 0x03,
- DW_MACRO_end_file = 0x04,
- DW_MACRO_define_strp = 0x05,
- DW_MACRO_undef_strp = 0x06,
- DW_MACRO_import = 0x07,
- DW_MACRO_define_sup = 0x08,
- DW_MACRO_undef_sup = 0x09,
- DW_MACRO_import_sup = 0x0a,
- DW_MACRO_define_strx = 0x0b,
- DW_MACRO_undef_strx = 0x0c,
- DW_MACRO_lo_user = 0xe0,
- DW_MACRO_hi_user = 0xff
- };
-
-/* Old GNU extension names for DWARF5 debug_macro type encodings.
- There are no equivalents for the supplementary object file (sup)
- and indirect string references (strx). */
-#define DW_MACRO_GNU_define DW_MACRO_define
-#define DW_MACRO_GNU_undef DW_MACRO_undef
-#define DW_MACRO_GNU_start_file DW_MACRO_start_file
-#define DW_MACRO_GNU_end_file DW_MACRO_end_file
-#define DW_MACRO_GNU_define_indirect DW_MACRO_define_strp
-#define DW_MACRO_GNU_undef_indirect DW_MACRO_undef_strp
-#define DW_MACRO_GNU_transparent_include DW_MACRO_import
-#define DW_MACRO_GNU_lo_user DW_MACRO_lo_user
-#define DW_MACRO_GNU_hi_user DW_MACRO_hi_user
-
-
-/* Range list entry encoding. */
-enum
- {
- DW_RLE_end_of_list = 0x0,
- DW_RLE_base_addressx = 0x1,
- DW_RLE_startx_endx = 0x2,
- DW_RLE_startx_length = 0x3,
- DW_RLE_offset_pair = 0x4,
- DW_RLE_base_address = 0x5,
- DW_RLE_start_end = 0x6,
- DW_RLE_start_length = 0x7
- };
-
-
-/* Location list entry encoding. */
-enum
- {
- DW_LLE_end_of_list = 0x0,
- DW_LLE_base_addressx = 0x1,
- DW_LLE_startx_endx = 0x2,
- DW_LLE_startx_length = 0x3,
- DW_LLE_offset_pair = 0x4,
- DW_LLE_default_location = 0x5,
- DW_LLE_base_address = 0x6,
- DW_LLE_start_end = 0x7,
- DW_LLE_start_length = 0x8
- };
-
-
-/* GNU DebugFission list entry encodings (.debug_loc.dwo). */
-enum
- {
- DW_LLE_GNU_end_of_list_entry = 0x0,
- DW_LLE_GNU_base_address_selection_entry = 0x1,
- DW_LLE_GNU_start_end_entry = 0x2,
- DW_LLE_GNU_start_length_entry = 0x3
- };
-
-/* DWARF5 package file section identifiers. */
-enum
- {
- DW_SECT_INFO = 1,
- /* Reserved = 2, */
- DW_SECT_ABBREV = 3,
- DW_SECT_LINE = 4,
- DW_SECT_LOCLISTS = 5,
- DW_SECT_STR_OFFSETS = 6,
- DW_SECT_MACRO = 7,
- DW_SECT_RNGLISTS = 8,
- };
-
-
-/* DWARF call frame instruction encodings. */
-enum
- {
- DW_CFA_advance_loc = 0x40,
- DW_CFA_offset = 0x80,
- DW_CFA_restore = 0xc0,
- DW_CFA_extended = 0,
-
- DW_CFA_nop = 0x00,
- DW_CFA_set_loc = 0x01,
- DW_CFA_advance_loc1 = 0x02,
- DW_CFA_advance_loc2 = 0x03,
- DW_CFA_advance_loc4 = 0x04,
- DW_CFA_offset_extended = 0x05,
- DW_CFA_restore_extended = 0x06,
- DW_CFA_undefined = 0x07,
- DW_CFA_same_value = 0x08,
- DW_CFA_register = 0x09,
- DW_CFA_remember_state = 0x0a,
- DW_CFA_restore_state = 0x0b,
- DW_CFA_def_cfa = 0x0c,
- DW_CFA_def_cfa_register = 0x0d,
- DW_CFA_def_cfa_offset = 0x0e,
- DW_CFA_def_cfa_expression = 0x0f,
- DW_CFA_expression = 0x10,
- DW_CFA_offset_extended_sf = 0x11,
- DW_CFA_def_cfa_sf = 0x12,
- DW_CFA_def_cfa_offset_sf = 0x13,
- DW_CFA_val_offset = 0x14,
- DW_CFA_val_offset_sf = 0x15,
- DW_CFA_val_expression = 0x16,
-
- DW_CFA_low_user = 0x1c,
- DW_CFA_MIPS_advance_loc8 = 0x1d,
- DW_CFA_GNU_window_save = 0x2d,
- DW_CFA_AARCH64_negate_ra_state = 0x2d,
- DW_CFA_GNU_args_size = 0x2e,
- DW_CFA_GNU_negative_offset_extended = 0x2f,
- DW_CFA_high_user = 0x3f
- };
-
-/* ID indicating CIE as opposed to FDE in .debug_frame. */
-enum
- {
- DW_CIE_ID_32 = 0xffffffffU, /* In 32-bit format CIE header. */
- DW_CIE_ID_64 = 0xffffffffffffffffULL /* In 64-bit format CIE header. */
- };
-
-
-/* Information for GNU unwind information. */
-enum
- {
- DW_EH_PE_absptr = 0x00,
- DW_EH_PE_omit = 0xff,
-
- /* FDE data encoding. */
- DW_EH_PE_uleb128 = 0x01,
- DW_EH_PE_udata2 = 0x02,
- DW_EH_PE_udata4 = 0x03,
- DW_EH_PE_udata8 = 0x04,
- DW_EH_PE_sleb128 = 0x09,
- DW_EH_PE_sdata2 = 0x0a,
- DW_EH_PE_sdata4 = 0x0b,
- DW_EH_PE_sdata8 = 0x0c,
- DW_EH_PE_signed = 0x08,
-
- /* FDE flags. */
- DW_EH_PE_pcrel = 0x10,
- DW_EH_PE_textrel = 0x20,
- DW_EH_PE_datarel = 0x30,
- DW_EH_PE_funcrel = 0x40,
- DW_EH_PE_aligned = 0x50,
-
- DW_EH_PE_indirect = 0x80
- };
-
-
-/* DWARF XXX. */
-#define DW_ADDR_none 0
-
-/* Section 7.2.2 of the DWARF3 specification defines a range of escape
- codes that can appear in the length field of certain DWARF structures.
-
- These defines enumerate the minimum and maximum values of this range.
- Currently only the maximum value is used (to indicate that 64-bit
- values are going to be used in the dwarf data that accompanies the
- structure). The other values are reserved.
-
- Note: There is a typo in DWARF3 spec (published Dec 20, 2005). In
- sections 7.4, 7.5.1, 7.19, 7.20 the minimum escape code is referred to
- as 0xffffff00 whereas in fact it should be 0xfffffff0. */
-#define DWARF3_LENGTH_MIN_ESCAPE_CODE 0xfffffff0u
-#define DWARF3_LENGTH_MAX_ESCAPE_CODE 0xffffffffu
-#define DWARF3_LENGTH_64_BIT DWARF3_LENGTH_MAX_ESCAPE_CODE
-
-#endif /* dwarf.h */
diff --git a/lib/Makefile b/lib/Makefile
deleted file mode 100644
index 6524d829..00000000
--- a/lib/Makefile
+++ /dev/null
@@ -1,105 +0,0 @@
-#
-# Tiny C Compiler Makefile for libtcc1.a
-#
-
-TOP = ..
-include $(TOP)/Makefile
-VPATH = $(TOPSRC)/lib $(TOPSRC)/win32/lib
-T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown)
-X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-)
-XCFG = $(or $(findstring -win,$T),-unx)
-S = $(if $(findstring yes,$(SILENT)),@$(info * $@))
-
-TCC = $(TOP)/$(X)tcc$(EXESUF)
-XTCC ?= $(TOP)/$(X)tcc$(EXESUF)
-XCC = $(XTCC)
-XAR = $(XTCC) -ar
-XFLAGS-unx = -B$(TOPSRC)
-XFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include
-XFLAGS = $(XFLAGS$(XCFG))
-BFLAGS = -bt
-
-# in order to use gcc, type: make -libtcc1-usegcc=yes
-arm-libtcc1-usegcc ?= no
-
-# This makes bounds checking 40%..60% faster.
-#x86_64-libtcc1-usegcc=yes
-#i386-libtcc1-usegcc=yes
-
-ifeq "$($(T)-libtcc1-usegcc)" "yes"
- XCC = $(CC)
- XAR = $(AR)
- XFLAGS = $(CFLAGS) -fPIC -fno-omit-frame-pointer -Wno-unused-function -Wno-unused-variable
- BFLAGS = $(if $(CONFIG_dwarf),-gdwarf,-gstabs)
-endif
-
-I386_O = libtcc1.o alloca.o alloca-bt.o $(COMMON_O)
-X86_64_O = libtcc1.o alloca.o alloca-bt.o $(COMMON_O)
-ARM_O = libtcc1.o armeabi.o alloca.o armflush.o $(COMMON_O)
-ARM64_O = lib-arm64.o $(COMMON_O)
-RISCV64_O = lib-arm64.o $(COMMON_O)
-COMMON_O = stdatomic.o atomic.o builtin.o
-WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o
-LIN_O = dsohandle.o
-OSX_O =
-
-# backtrace/bcheck/run only for native compiler
-Nat = $(if $X,no,)
-Cbt = $(Nat)$(subst yes,,$(CONFIG_backtrace))
-Cbc = $(Cbt)$(subst yes,,$(CONFIG_bcheck))
-
-$(Nat)COMMON_O += runmain.o tcov.o
-$(Cbt)COMMON_O += bt-exe.o bt-log.o
-$(Cbt)WIN_O += bt-dll.o
-$(Cbc)COMMON_O += bcheck.o
-
-# not in libtcc1.a
-EXTRA_O = runmain.o bt-exe.o bt-dll.o bt-log.o bcheck.o
-
-OBJ-i386 = $(I386_O) $(LIN_O)
-OBJ-x86_64 = $(X86_64_O) va_list.o $(LIN_O)
-OBJ-x86_64-osx = $(X86_64_O) va_list.o $(OSX_O)
-OBJ-i386-win32 = $(I386_O) chkstk.o $(WIN_O)
-OBJ-x86_64-win32 = $(X86_64_O) chkstk.o $(WIN_O)
-OBJ-arm64 = $(ARM64_O) $(LIN_O)
-OBJ-arm64-osx = $(ARM64_O) $(OSX_O)
-OBJ-arm = $(ARM_O) $(LIN_O)
-OBJ-arm-fpa = $(OBJ-arm)
-OBJ-arm-fpa-ld = $(OBJ-arm)
-OBJ-arm-vfp = $(OBJ-arm)
-OBJ-arm-eabi = $(OBJ-arm)
-OBJ-arm-eabihf = $(OBJ-arm)
-OBJ-arm-wince = $(ARM_O) $(WIN_O)
-OBJ-riscv64 = $(RISCV64_O) $(LIN_O)
-
-OBJ-extra = $(filter $(EXTRA_O),$(OBJ-$T))
-OBJ-libtcc1 = $(addprefix $(X),$(filter-out $(OBJ-extra),$(OBJ-$T)))
-
-ALL = $(addprefix $(TOP)/,$(X)libtcc1.a $(OBJ-extra))
-
-all: $(ALL)
-
-$(TOP)/$(X)libtcc1.a : $(OBJ-libtcc1) $(TCC)
- $S$(XAR) rcs $@ $(OBJ-libtcc1)
-
-$(X)%.o : %.c $(TCC)
- $S$(XCC) -c $< -o $@ $(XFLAGS)
-
-$(X)%.o : %.S $(TCC)
- $S$(XCC) -c $< -o $@ $(XFLAGS)
-
-$(TOP)/%.o : %.c $(TCC)
- $S$(XCC) -c $< -o $@ $(XFLAGS)
-
-$(TOP)/bcheck.o : XFLAGS += $(BFLAGS) -I$(TOP)
-# includes tccrun.c, $(TOP) for config.h (tccrun.c prerequisite via $(TCC))
-$(TOP)/bt-exe.o : XFLAGS += -I$(TOP)
-
-$(X)crt1w.o : crt1.c
-$(X)wincrt1w.o : wincrt1.c
-
-# don't try to make it
-$(TCC) : ;
-
-clean :
- rm -f *.o $(addprefix $(TOP)/,*libtcc1.a $(EXTRA_O))
diff --git a/libtcc.h b/libtcc.h
deleted file mode 100644
index 5949c807..00000000
--- a/libtcc.h
+++ /dev/null
@@ -1,116 +0,0 @@
-#ifndef LIBTCC_H
-#define LIBTCC_H
-
-#ifndef LIBTCCAPI
-# define LIBTCCAPI
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*****************************/
-/* set custom allocator for all allocations (optional), NULL for default. */
-typedef void *TCCReallocFunc(void *ptr, unsigned long size);
-LIBTCCAPI void tcc_set_realloc(TCCReallocFunc *my_realloc);
-
-/*****************************/
-typedef struct TCCState TCCState;
-
-/* create a new TCC compilation context */
-LIBTCCAPI TCCState *tcc_new(void);
-
-/* free a TCC compilation context */
-LIBTCCAPI void tcc_delete(TCCState *s);
-
-/* set CONFIG_TCCDIR at runtime */
-LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path);
-
-/* set error/warning callback (optional) */
-typedef void TCCErrorFunc(void *opaque, const char *msg);
-LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc *error_func);
-
-/* set options as from command line (multiple supported) */
-LIBTCCAPI int tcc_set_options(TCCState *s, const char *str);
-
-/*****************************/
-/* preprocessor */
-
-/* add include path */
-LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname);
-
-/* add in system include path */
-LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname);
-
-/* define preprocessor symbol 'sym'. value can be NULL, sym can be "sym=val" */
-LIBTCCAPI void tcc_define_symbol(TCCState *s, const char *sym, const char *value);
-
-/* undefine preprocess symbol 'sym' */
-LIBTCCAPI void tcc_undefine_symbol(TCCState *s, const char *sym);
-
-/*****************************/
-/* compiling */
-
-/* add a file (C file, dll, object, library, ld script). Return -1 if error. */
-LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename);
-
-/* compile a string containing a C source. Return -1 if error. */
-LIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf);
-
-/* Tip: to have more specific errors/warnings from tcc_compile_string(),
- you can prefix the string with "#line \"\"\n" */
-
-/*****************************/
-/* linking commands */
-
-/* set output type. MUST BE CALLED before any compilation */
-LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type);
-#define TCC_OUTPUT_MEMORY 1 /* output will be run in memory */
-#define TCC_OUTPUT_EXE 2 /* executable file */
-#define TCC_OUTPUT_DLL 4 /* dynamic library */
-#define TCC_OUTPUT_OBJ 3 /* object file */
-#define TCC_OUTPUT_PREPROCESS 5 /* only preprocess */
-
-/* equivalent to -Lpath option */
-LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname);
-
-/* the library name is the same as the argument of the '-l' option */
-LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname);
-
-/* add a symbol to the compiled program */
-LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val);
-
-/* output an executable, library or object file. DO NOT call
- tcc_relocate() before. */
-LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename);
-
-/* link and run main() function and return its value. DO NOT call
- tcc_relocate() before. */
-LIBTCCAPI int tcc_run(TCCState *s, int argc, char **argv);
-
-/* do all relocations (needed before using tcc_get_symbol()) */
-LIBTCCAPI int tcc_relocate(TCCState *s1);
-
-/* return symbol value or NULL if not found */
-LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name);
-
-/* list all (global) symbols and their values via 'symbol_cb()' */
-LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
- void (*symbol_cb)(void *ctx, const char *name, const void *val));
-
-/* experimental/advanced section (see libtcc_test_mt.c for an example) */
-
-/* catch runtime exceptions (optionally limit backtraces at top_func),
- when using tcc_set_options("-bt") and when not using tcc_run() */
-LIBTCCAPI void *_tcc_setjmp(TCCState *s1, void *jmp_buf, void *top_func, void *longjmp);
-#define tcc_setjmp(s1,jb,f) setjmp(_tcc_setjmp(s1, jb, f, longjmp))
-
-/* custom error printer for runtime exceptions. Returning 0 stops backtrace */
-typedef int TCCBtFunc(void *udata, void *pc, const char *file, int line, const char* func, const char *msg);
-LIBTCCAPI void tcc_set_backtrace_func(TCCState *s1, void* userdata, TCCBtFunc*);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/libtcc/Makefile.am b/libtcc/Makefile.am
new file mode 100644
index 00000000..8f07c714
--- /dev/null
+++ b/libtcc/Makefile.am
@@ -0,0 +1,6 @@
+noinst_LIBRARIES = libtcc.a
+libtcc_a_SOURCES = libtcc.c tccpp.c tccgen.c \
+ tccasm.c tccelf.c \
+ i386/gen.c i386/link.c \
+ i386/asm.c tcccoff.c
+libtcc_a_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/libtcc
\ No newline at end of file
diff --git a/coff.h b/libtcc/coff.h
similarity index 99%
rename from coff.h
rename to libtcc/coff.h
index 1fb43fc2..285dfc23 100644
--- a/coff.h
+++ b/libtcc/coff.h
@@ -2,7 +2,8 @@
/* COFF.H */
/* COFF data structures and related definitions used by the linker */
/**************************************************************************/
-
+#ifndef COFF_H
+# define COFF_H 1
# include
/*------------------------------------------------------------------------*/
@@ -389,3 +390,5 @@ union auxent
#define _DORIGIN "_dorigin"
#define _SORIGIN "_sorigin"
+
+#endif /* COFF_H */
\ No newline at end of file
diff --git a/elf.h b/libtcc/elf.h
similarity index 100%
rename from elf.h
rename to libtcc/elf.h
diff --git a/i386-asm.c b/libtcc/i386/asm.c
similarity index 99%
rename from i386-asm.c
rename to libtcc/i386/asm.c
index d1038128..6f101b8c 100644
--- a/i386-asm.c
+++ b/libtcc/i386/asm.c
@@ -141,9 +141,6 @@ static const uint8_t reg_to_size[9] = {
[OP_REG8] = 0,
[OP_REG16] = 1,
[OP_REG32] = 2,
-#ifdef TCC_TARGET_X86_64
- [OP_REG64] = 3,
-#endif
*/
0, 0, 1, 0, 2, 0, 0, 0, 3
};
@@ -204,7 +201,7 @@ static const ASMInstr asm_instrs[] = {
#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 2, { op0, op1 }},
#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 3, { op0, op1, op2 }},
-#include "i386-asm.h"
+#include "asm.h"
/* last operation */
{ 0, },
};
@@ -216,7 +213,7 @@ static const uint16_t op0_codes[] = {
#define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
-#include "i386-asm.h"
+#include "asm.h"
};
static inline int get_reg_shift(TCCState *s1)
@@ -1293,11 +1290,6 @@ ST_FUNC void subst_asm_operand(CString *add_str,
size = 1;
else if ((sv->type.t & VT_BTYPE) == VT_SHORT)
size = 2;
-#ifdef TCC_TARGET_X86_64
- else if ((sv->type.t & VT_BTYPE) == VT_LLONG ||
- (sv->type.t & VT_BTYPE) == VT_PTR)
- size = 8;
-#endif
else
size = 4;
if (size == 1 && reg >= 4)
diff --git a/i386-asm.h b/libtcc/i386/asm.h
similarity index 100%
rename from i386-asm.h
rename to libtcc/i386/asm.h
diff --git a/i386-gen.c b/libtcc/i386/gen.c
similarity index 92%
rename from i386-gen.c
rename to libtcc/i386/gen.c
index 1d521160..f50a422c 100644
--- a/i386-gen.c
+++ b/libtcc/i386/gen.c
@@ -99,13 +99,6 @@ ST_DATA const int reg_classes[NB_REGS] = {
static unsigned long func_sub_sp_offset;
static int func_ret_sub;
-#ifdef CONFIG_TCC_BCHECK
-static addr_t func_bound_offset;
-static unsigned long func_bound_ind;
-ST_DATA int func_bound_add_epilog;
-static void gen_bounds_prolog(void);
-static void gen_bounds_epilog(void);
-#endif
/* XXX: make it faster ? */
ST_FUNC void g(int c)
@@ -335,17 +328,6 @@ static void gadd_sp(int val)
}
}
-#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_PE
-static void gen_static_call(int v)
-{
- Sym *sym;
-
- sym = external_helper_sym(v);
- oad(0xe8, -4);
- greloc(cur_text_section, sym, ind-4, R_386_PC32);
-}
-#endif
-
/* 'is_jmp' is '1' if it is a jump */
static void gcall_or_jmp(int is_jmp)
{
@@ -401,11 +383,6 @@ ST_FUNC void gfunc_call(int nb_args)
int size, align, r, args_size, i, func_call;
Sym *func_sym;
-#ifdef CONFIG_TCC_BCHECK
- if (tcc_state->do_bounds_check)
- gbound_args(nb_args);
-#endif
-
args_size = 0;
for(i = 0;i < nb_args; i++) {
if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
@@ -591,10 +568,6 @@ ST_FUNC void gfunc_prolog(Sym *func_sym)
func_ret_sub = 4;
#endif
-#ifdef CONFIG_TCC_BCHECK
- if (tcc_state->do_bounds_check)
- gen_bounds_prolog();
-#endif
}
/* generate function epilog */
@@ -602,11 +575,6 @@ ST_FUNC void gfunc_epilog(void)
{
addr_t v, saved_ind;
-#ifdef CONFIG_TCC_BCHECK
- if (tcc_state->do_bounds_check)
- gen_bounds_epilog();
-#endif
-
/* align local size to word & save local variables */
v = (-loc + 3) & -4;
@@ -1043,55 +1011,6 @@ ST_FUNC void ggoto(void)
vtop--;
}
-/* bound check support functions */
-#ifdef CONFIG_TCC_BCHECK
-
-static void gen_bounds_prolog(void)
-{
- /* leave some room for bound checking code */
- func_bound_offset = lbounds_section->data_offset;
- func_bound_ind = ind;
- func_bound_add_epilog = 0;
- oad(0xb8, 0); /* lbound section pointer */
- oad(0xb8, 0); /* call to function */
-}
-
-static void gen_bounds_epilog(void)
-{
- addr_t saved_ind;
- addr_t *bounds_ptr;
- Sym *sym_data;
- int offset_modified = func_bound_offset != lbounds_section->data_offset;
-
- if (!offset_modified && !func_bound_add_epilog)
- return;
-
- /* add end of table info */
- bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
- *bounds_ptr = 0;
-
- sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
- func_bound_offset, PTR_SIZE);
-
- /* generate bound local allocation */
- if (offset_modified) {
- saved_ind = ind;
- ind = func_bound_ind;
- greloc(cur_text_section, sym_data, ind + 1, R_386_32);
- ind = ind + 5;
- gen_static_call(TOK___bound_local_new);
- ind = saved_ind;
- }
-
- /* generate bound check local freeing */
- o(0x5250); /* save returned value, if any */
- greloc(cur_text_section, sym_data, ind + 1, R_386_32);
- oad(0xb8, 0); /* mov %eax, xxx */
- gen_static_call(TOK___bound_local_delete);
- o(0x585a); /* restore returned value, if any */
-}
-#endif
-
/* Save the stack pointer onto the stack */
ST_FUNC void gen_vla_sp_save(int addr) {
/* mov %esp,addr(%ebp)*/
@@ -1109,9 +1028,6 @@ ST_FUNC void gen_vla_sp_restore(int addr) {
ST_FUNC void gen_vla_alloc(CType *type, int align) {
int use_call = 0;
-#if defined(CONFIG_TCC_BCHECK)
- use_call = tcc_state->do_bounds_check;
-#endif
#ifdef TCC_TARGET_PE /* alloca does more than just adjust %rsp on Windows */
use_call = 1;
#endif
diff --git a/i386-link.c b/libtcc/i386/link.c
similarity index 88%
rename from i386-link.c
rename to libtcc/i386/link.c
index 278df264..005a8ee2 100644
--- a/i386-link.c
+++ b/libtcc/i386/link.c
@@ -99,11 +99,7 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_
int modrm;
unsigned plt_offset, relofs;
- /* on i386 if we build a DLL, we add a %ebx offset */
- if (s1->output_type & TCC_OUTPUT_DYN)
- modrm = 0xa3;
- else
- modrm = 0x25;
+ modrm = 0x25;
/* empty PLT: create PLT0 entry that pushes the library identifier
(GOT + PTR_SIZE) and jumps to ld.so resolution routine
@@ -148,7 +144,7 @@ ST_FUNC void relocate_plt(TCCState *s1)
p = s1->plt->data;
p_end = p + s1->plt->data_offset;
- if (!(s1->output_type & TCC_OUTPUT_DYN) && p < p_end) {
+ if (p < p_end) {
add32le(p + 2, s1->got->sh_addr);
add32le(p + 8, s1->got->sh_addr);
p += 16;
@@ -179,31 +175,9 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,
switch (type) {
case R_386_32:
- if (s1->output_type & TCC_OUTPUT_DYN) {
- esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
- qrel->r_offset = rel->r_offset;
- if (esym_index) {
- qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
- qrel++;
- return;
- } else {
- qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
- qrel++;
- }
- }
add32le(ptr, val);
return;
case R_386_PC32:
- if (s1->output_type == TCC_OUTPUT_DLL) {
- /* DLL relocation */
- esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
- if (esym_index) {
- qrel->r_offset = rel->r_offset;
- qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
- qrel++;
- return;
- }
- }
add32le(ptr, val - addr);
return;
case R_386_PLT32:
diff --git a/i386-tok.h b/libtcc/i386/tok.h
similarity index 99%
rename from i386-tok.h
rename to libtcc/i386/tok.h
index 04844d26..b1450bdf 100644
--- a/i386-tok.h
+++ b/libtcc/i386/tok.h
@@ -266,7 +266,7 @@
#define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
-#include "i386-asm.h"
+#include "asm.h"
#define ALT(x)
#define DEF_ASM_OP0(name, opcode)
@@ -274,4 +274,4 @@
#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name)
#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name)
#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name)
-#include "i386-asm.h"
+#include "asm.h"
diff --git a/libtcc.c b/libtcc/libtcc.c
similarity index 90%
rename from libtcc.c
rename to libtcc/libtcc.c
index ca31aa7e..a79ead7d 100644
--- a/libtcc.c
+++ b/libtcc/libtcc.c
@@ -19,6 +19,7 @@
*/
#include "tcc.h"
+#include "utils/string.h"
/********************************************************/
/* global variables */
@@ -78,44 +79,6 @@ PUB_FUNC void tcc_exit_state(TCCState *s1)
POST_SEM(&tcc_compile_sem);
}
-/********************************************************/
-/* copy a string and truncate it. */
-ST_FUNC char *pstrcpy(char *buf, size_t buf_size, const char *s)
-{
- char *q, *q_end;
- int c;
-
- if (buf_size > 0) {
- q = buf;
- q_end = buf + buf_size - 1;
- while (q < q_end) {
- c = *s++;
- if (c == '\0')
- break;
- *q++ = c;
- }
- *q = '\0';
- }
- return buf;
-}
-
-/* strcat and truncate. */
-ST_FUNC char *pstrcat(char *buf, size_t buf_size, const char *s)
-{
- size_t len;
- len = strlen(buf);
- if (len < buf_size)
- pstrcpy(buf + len, buf_size - len, s);
- return buf;
-}
-
-ST_FUNC char *pstrncpy(char *out, const char *in, size_t num)
-{
- memcpy(out, in, num);
- out[num] = '\0';
- return out;
-}
-
/* extract the basename of a file */
PUB_FUNC char *tcc_basename(const char *name)
{
@@ -180,7 +143,7 @@ ST_FUNC void libc_free(void *ptr)
/* global so that every tcc_alloc()/tcc_free() call doesn't need to be changed */
static void *(*reallocator)(void*, unsigned long) = default_reallocator;
-LIBTCCAPI void tcc_set_realloc(TCCReallocFunc *realloc)
+void tcc_set_realloc(TCCReallocFunc *realloc)
{
reallocator = realloc ? realloc : default_reallocator;
}
@@ -574,7 +537,7 @@ static void error1(int mode, const char *fmt, va_list ap)
}
}
-LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc *error_func)
+void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc *error_func)
{
s->error_opaque = error_opaque;
s->error_func = error_func;
@@ -720,13 +683,13 @@ static int tcc_compile(TCCState *s1, int filetype, const char *str, int fd)
return s1->nb_errors != 0 ? -1 : 0;
}
-LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str)
+int tcc_compile_string(TCCState *s, const char *str)
{
return tcc_compile(s, s->filetype, str, -1);
}
/* define a preprocessor symbol. value can be NULL, sym can be "sym=val" */
-LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
+void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
{
const char *eq;
if (NULL == (eq = strchr(sym, '=')))
@@ -737,13 +700,13 @@ LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *valu
}
/* undefine a preprocessor symbol */
-LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym)
+void tcc_undefine_symbol(TCCState *s1, const char *sym)
{
cstr_printf(&s1->cmdline_defs, "#undef %s\n", sym);
}
-LIBTCCAPI TCCState *tcc_new(void)
+TCCState *tcc_new(void)
{
TCCState *s;
@@ -779,7 +742,7 @@ LIBTCCAPI TCCState *tcc_new(void)
return s;
}
-LIBTCCAPI void tcc_delete(TCCState *s1)
+void tcc_delete(TCCState *s1)
{
/* free sections */
tccelf_delete(s1);
@@ -808,7 +771,6 @@ LIBTCCAPI void tcc_delete(TCCState *s1)
cstr_free(&s1->cmdline_defs);
cstr_free(&s1->cmdline_incl);
cstr_free(&s1->linker_arg);
- tcc_free(s1->dState);
/* free loaded dlls array */
dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
tcc_free(s1);
@@ -817,12 +779,8 @@ LIBTCCAPI void tcc_delete(TCCState *s1)
#endif
}
-LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
+int tcc_set_output_type(TCCState *s, int output_type)
{
-#ifdef CONFIG_TCC_PIE
- if (output_type == TCC_OUTPUT_EXE)
- output_type |= TCC_OUTPUT_DYN;
-#endif
s->output_type = output_type;
if (!s->nostdinc) {
@@ -832,7 +790,6 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
}
if (output_type == TCC_OUTPUT_PREPROCESS) {
- s->do_debug = 0;
return 0;
}
@@ -854,13 +811,13 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
return 0;
}
-LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname)
+int tcc_add_include_path(TCCState *s, const char *pathname)
{
tcc_split_path(s, &s->include_paths, &s->nb_include_paths, pathname);
return 0;
}
-LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname)
+int tcc_add_sysinclude_path(TCCState *s, const char *pathname)
{
tcc_split_path(s, &s->sysinclude_paths, &s->nb_sysinclude_paths, pathname);
return 0;
@@ -932,45 +889,10 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
ret = tcc_load_archive(s1, fd, !(flags & AFF_WHOLE_ARCHIVE));
break;
-#ifdef TCC_TARGET_PE
- default:
- ret = pe_load_file(s1, fd, filename);
- goto check_success;
+ case AFF_BINTYPE_COFF:
+ ret = coff_load_file(s1, fd, filename);
+ break;
-#elif defined TCC_TARGET_MACHO
- case AFF_BINTYPE_DYN:
- case_dyn_or_tbd:
- if (s1->output_type == TCC_OUTPUT_MEMORY) {
-#ifdef TCC_IS_NATIVE
- void* dl;
- const char* soname = filename;
- if (obj_type != AFF_BINTYPE_DYN)
- soname = macho_tbd_soname(filename);
- dl = dlopen(soname, RTLD_GLOBAL | RTLD_LAZY);
- if (dl)
- tcc_add_dllref(s1, soname, 0)->handle = dl, ret = 0;
- if (filename != soname)
- tcc_free((void *)soname);
-#endif
- } else if (obj_type == AFF_BINTYPE_DYN) {
- ret = macho_load_dll(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
- } else {
- ret = macho_load_tbd(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
- }
- goto check_success;
- default:
- {
- const char *ext = tcc_fileextension(filename);
- if (!strcmp(ext, ".tbd"))
- goto case_dyn_or_tbd;
- if (!strcmp(ext, ".dylib")) {
- obj_type = AFF_BINTYPE_DYN;
- goto case_dyn_or_tbd;
- }
- goto check_success;
- }
-
-#else /* unix */
case AFF_BINTYPE_DYN:
if (s1->output_type == TCC_OUTPUT_MEMORY) {
} else
@@ -980,20 +902,9 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
default:
/* as GNU ld, consider it is an ld script if not recognized */
ret = tcc_load_ldscript(s1, fd);
- goto check_success;
-
-#endif /* pe / macos / unix */
-
-check_success:
if (ret < 0)
tcc_error_noabort("%s: unrecognized file type", filename);
break;
-
-#ifdef TCC_TARGET_COFF
- case AFF_BINTYPE_C67:
- ret = tcc_load_coff(s1, fd);
- break;
-#endif
}
close(fd);
} else {
@@ -1030,12 +941,12 @@ static int guess_filetype(const char *filename)
return filetype;
}
-LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
+int tcc_add_file(TCCState *s, const char *filename)
{
return tcc_add_file_internal(s, filename, s->filetype | AFF_PRINT_ERROR);
}
-LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
+int tcc_add_library_path(TCCState *s, const char *pathname)
{
tcc_split_path(s, &s->library_paths, &s->nb_library_paths, pathname);
return 0;
@@ -1074,7 +985,7 @@ ST_FUNC int tcc_add_support(TCCState *s1, const char *filename)
return tcc_add_dll(s1, filename, AFF_PRINT_ERROR);
}
-#if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO
+#if !defined TCC_TARGET_PE
ST_FUNC int tcc_add_crt(TCCState *s1, const char *filename)
{
return tcc_add_library_internal(s1, "%s/%s",
@@ -1083,7 +994,7 @@ ST_FUNC int tcc_add_crt(TCCState *s1, const char *filename)
#endif
/* the library name is the same as the argument of the '-l' option */
-LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
+int tcc_add_library(TCCState *s, const char *libraryname)
{
static const char * const libs[] = { "%s/lib%s.a", NULL };
const char * const *pp = libs;
@@ -1106,7 +1017,7 @@ ST_FUNC void tcc_add_pragma_libs(TCCState *s1)
tcc_add_library(s1, s1->pragma_libs[i]);
}
-LIBTCCAPI int tcc_add_symbol(TCCState *s1, const char *name, const void *val)
+int tcc_add_symbol(TCCState *s1, const char *name, const void *val)
{
char buf[256];
if (s1->leading_underscore) {
@@ -1118,7 +1029,7 @@ LIBTCCAPI int tcc_add_symbol(TCCState *s1, const char *name, const void *val)
return 0;
}
-LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path)
+void tcc_set_lib_path(TCCState *s, const char *path)
{
tcc_free(s->tcc_lib_path);
s->tcc_lib_path = tcc_strdup(path);
@@ -1393,13 +1304,6 @@ static const TCCOption tcc_options[] = {
{ "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG },
{ "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG },
{ "bench", TCC_OPTION_bench, 0 },
-#ifdef CONFIG_TCC_BACKTRACE
- { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
-#endif
-#ifdef CONFIG_TCC_BCHECK
- { "b", TCC_OPTION_b, 0 },
-#endif
- { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
{ "c", TCC_OPTION_c, 0 },
{ "dumpmachine", TCC_OPTION_dumpmachine, 0},
{ "dumpversion", TCC_OPTION_dumpversion, 0},
@@ -1435,6 +1339,7 @@ static const TCCOption tcc_options[] = {
{ "ar", TCC_OPTION_ar, 0},
/* ignored (silently, except after -Wunsupported) */
{ "arch", 0, TCC_OPTION_HAS_ARG},
+ { "g", 0, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP},
{ "C", 0, 0 },
{ "-param", 0, TCC_OPTION_HAS_ARG },
{ "pedantic", 0, 0 },
@@ -1470,7 +1375,6 @@ static const FlagDef options_f[] = {
{ offsetof(TCCState, leading_underscore), 0, "leading-underscore" },
{ offsetof(TCCState, ms_extensions), 0, "ms-extensions" },
{ offsetof(TCCState, dollars_in_identifiers), 0, "dollars-in-identifiers" },
- { offsetof(TCCState, test_coverage), 0, "test-coverage" },
{ offsetof(TCCState, reverse_funcargs), 0, "reverse-funcargs" },
{ offsetof(TCCState, gnu89_inline), 0, "gnu89-inline" },
{ offsetof(TCCState, unwind_tables), 0, "asynchronous-unwind-tables" },
@@ -1675,32 +1579,6 @@ dorun:
case TCC_OPTION_bench:
s->do_bench = 1;
break;
-#ifdef CONFIG_TCC_BACKTRACE
- case TCC_OPTION_bt:
- s->rt_num_callers = atoi(optarg); /* zero = default (6) */
- goto enable_backtrace;
- enable_backtrace:
- s->do_backtrace = 1;
- s->do_debug = s->do_debug ? s->do_debug : 1;
- s->dwarf = CONFIG_DWARF_VERSION;
- break;
-#ifdef CONFIG_TCC_BCHECK
- case TCC_OPTION_b:
- s->do_bounds_check = 1;
- goto enable_backtrace;
-#endif
-#endif
- case TCC_OPTION_g:
- s->do_debug = 2;
- s->dwarf = CONFIG_DWARF_VERSION;
- if (strstart("dwarf", &optarg)) {
- s->dwarf = (*optarg) ? (0 - atoi(optarg)) : DEFAULT_DWARF_VERSION;
- } else if (isnum(*optarg)) {
- x = *optarg - '0';
- /* -g0 = no info, -g1 = lines/functions only, -g2 = full info */
- s->do_debug = x > 2 ? 2 : x == 0 && s->do_backtrace ? 1 : x;
- }
- break;
case TCC_OPTION_c:
x = TCC_OUTPUT_OBJ;
set_output_type:
@@ -1713,8 +1591,6 @@ dorun:
s->dflag = 3;
else if (*optarg == 'M')
s->dflag = 7;
- else if (*optarg == 't')
- s->dflag = 16;
else if (isnum(*optarg))
s->g_debug |= atoi(optarg);
else
@@ -1727,9 +1603,6 @@ dorun:
if (strcmp(optarg, "=c11") == 0 || strcmp(optarg, "=gnu11") == 0)
s->cversion = 201112;
break;
- case TCC_OPTION_shared:
- x = TCC_OUTPUT_DLL;
- goto set_output_type;
case TCC_OPTION_soname:
s->soname = tcc_strdup(optarg);
break;
@@ -1885,7 +1758,7 @@ unsupported_option:
return OPT_HELP;
}
-LIBTCCAPI int tcc_set_options(TCCState *s, const char *r)
+int tcc_set_options(TCCState *s, const char *r)
{
char **argv = NULL;
int argc = 0, ret;
@@ -1913,15 +1786,6 @@ PUB_FUNC void tcc_print_stats(TCCState *s1, unsigned total_time)
);
#ifdef MEM_DEBUG
fprintf(stderr, "# memory usage");
-#ifdef TCC_IS_NATIVE
- if (s1->run_size) {
- Section *s = s1->symtab;
- unsigned ms = s->data_offset + s->link->data_offset + s->hash->data_offset;
- unsigned rs = s1->run_size;
- fprintf(stderr, ": %d to run, %d symbols, %d other,",
- rs, ms, mem_cur_size - rs - ms);
- }
-#endif
fprintf(stderr, " %d max (bytes)\n", mem_max_size);
#endif
}
diff --git a/libtcc/libtcc.h b/libtcc/libtcc.h
new file mode 100644
index 00000000..fdb0c5c0
--- /dev/null
+++ b/libtcc/libtcc.h
@@ -0,0 +1,179 @@
+#ifndef LIBTCC_H
+# define LIBTCC_H 1
+
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+
+typedef void *TCCReallocFunc(void *ptr, unsigned long size);
+/**
+ * @brief set custom allocator for all allocations (optional), NULL for default.
+ */
+void tcc_set_realloc(TCCReallocFunc *my_realloc);
+
+typedef struct TCCState TCCState;
+
+/**
+ * @brief create a new TCC compilation context.
+ */
+TCCState *tcc_new(void);
+
+/**
+ * @brief free a TCC compilation context.
+ */
+void tcc_delete(TCCState *s);
+
+/**
+ * @brief set CONFIG_TCCDIR at runtime.
+ */
+void tcc_set_lib_path(TCCState *s, const char *path);
+
+typedef void TCCErrorFunc(void *opaque, const char *msg);
+
+/**
+ * @brief set error/warning callback (optional).
+ */
+void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc *error_func);
+
+/**
+ * @brief set options as from command line (multiple supported)
+ */
+int tcc_set_options(TCCState *s, const char *str);
+
+/**
+ * @defgroup preprocessor Preprocessor
+ * @{
+ */
+
+/**
+ * @brief add include path
+ */
+int tcc_add_include_path(TCCState *s, const char *pathname);
+
+/**
+ * @brief add in system include path
+ */
+int tcc_add_sysinclude_path(TCCState *s, const char *pathname);
+
+/**
+ * @brief define preprocessor symbol 'sym'. value can be NULL, sym can be "sym=val"
+ */
+void tcc_define_symbol(TCCState *s, const char *sym, const char *value);
+
+/**
+ * @brief undefine preprocess symbol 'sym'
+ */
+void tcc_undefine_symbol(TCCState *s, const char *sym);
+
+/**
+ * @}
+*/
+
+/**
+ * @defgroup compiling Compiling
+ * @{
+ */
+
+/**
+ * @brief add a file (C file, object, library, ld script). Return -1 if error.
+ */
+int tcc_add_file(TCCState *s, const char *filename);
+
+/**
+ * @brief compile a string containing a C source. Return -1 if error.
+ *
+ * Tip: to have more specific errors/warnings from tcc_compile_string(),
+ * you can prefix the string with "#line \"\"\n"
+ */
+int tcc_compile_string(TCCState *s, const char *buf);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup linking Linking commands
+ * @{
+ */
+# define TCC_OUTPUT_MEMORY 1 /** output will be run in memory */
+# define TCC_OUTPUT_EXE 2 /** executable file */
+# define TCC_OUTPUT_OBJ 3 /** object file */
+# define TCC_OUTPUT_PREPROCESS 5 /** only preprocess */
+
+/**
+ * @brief set output type. MUST BE CALLED before any compilation.
+ */
+int tcc_set_output_type(TCCState *s, int output_type);
+
+/**
+ * @brief equivalent to -Lpath option.
+ */
+int tcc_add_library_path(TCCState *s, const char *pathname);
+
+/**
+ * @brief the library name is the same as the argument of the '-l' option.
+ */
+int tcc_add_library(TCCState *s, const char *libraryname);
+
+/**
+ * @brief add a symbol to the compiled program.
+ */
+int tcc_add_symbol(TCCState *s, const char *name, const void *val);
+
+/**
+ * @brief output an executable, library or object file.
+ *
+ * DO NOT call tcc_relocate() before.
+ */
+int tcc_output_file(TCCState *s, const char *filename);
+
+/**
+ * @brief do all relocations (needed before using tcc_get_symbol()).
+ */
+int tcc_relocate(TCCState *s1);
+
+/**
+ * @brief return symbol value or NULL if not found.
+ */
+void *tcc_get_symbol(TCCState *s, const char *name);
+
+typedef void (TCCSymbolFunc)(void *ctx, const char *name, const void *val);
+
+/**
+ * @brief list all (global) symbols and their values via 'symbol_cb()'.
+ */
+void tcc_list_symbols(TCCState *s, void *ctx, TCCSymbolFunc *symbol_cb);
+
+/**
+ * @}
+ */
+
+/**
+ * experimental/advanced section (see libtcc_test_mt.c for an example).
+ * @defgroup experimental Experimental/Advanced
+ * @{
+ */
+
+/**
+ * @brief catch runtime exceptions (optionally limit backtraces at top_func), when using tcc_set_options("-bt").
+ */
+void *_tcc_setjmp(TCCState *s1, void *jmp_buf, void *top_func, void *longjmp);
+
+# define tcc_setjmp(s1,jb,f) setjmp(_tcc_setjmp(s1, jb, f, longjmp))
+
+typedef int TCCBtFunc(void *udata, void *pc, const char *file, int line, const char* func, const char *msg);
+
+/**
+ * @brief custom error printer for runtime exceptions. Returning 0 stops backtrace.
+ */
+void tcc_set_backtrace_func(TCCState *s1, void* userdata, TCCBtFunc*);
+
+/**
+ * @}
+ */
+
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+
+#endif /* !TCC_H */
\ No newline at end of file
diff --git a/libtcc/object/archive.h b/libtcc/object/archive.h
new file mode 100644
index 00000000..c560dd72
--- /dev/null
+++ b/libtcc/object/archive.h
@@ -0,0 +1,35 @@
+#ifndef LIBTCC_OBJECT_ARCHIVE_H
+# define LIBTCC_OBJECT_ARCHIVE_H 1
+
+/**
+ * @defgroup object_archive UNIX Archive
+ * @ingroup object
+ * @{
+ */
+
+# define ARCHIVE_MAGIC "!\n"
+# define ARCHIVE_MAGSZ 8
+# define ARCHIVE_FILMAG "`\n"
+
+typedef struct ArchiveFileHeader {
+ char name[16];
+ char last_mod[12];
+ char uid[6];
+ char gid[6];
+ char mode[8];
+ char size[10];
+ char fmag[2];
+} ArchiveFileHeader;
+
+typedef struct ArchiveEntry {
+} ArchiveEntry;
+
+typedef struct Archive {
+ char *filename;
+} Archive;
+
+/**
+ * @}
+ */
+
+#endif /* !LIBTCC_OBJECT_AR_H */
\ No newline at end of file
diff --git a/libtcc/object/coff.h b/libtcc/object/coff.h
new file mode 100644
index 00000000..e3af72cc
--- /dev/null
+++ b/libtcc/object/coff.h
@@ -0,0 +1,69 @@
+#ifndef LIBTCC_OBJECT_COFF_H
+# define LIBTCC_OBJECT_COFF_H 1
+
+# include
+
+/**
+ * @defgroup object_coff COFF Object
+ * @ingroup object
+ * @{
+ */
+
+# define COFF_MAGIC 0x14c
+
+typedef struct COFFFileHeader {
+ uint16_t magic;
+ uint16_t nscns;
+ int32_t timdat;
+ int32_t nsyms;
+ uint16_t opthdr;
+ uint16_t flags;
+} COFFFileHeader;
+
+# define COFF_FILHSZ sizeof(COFFFileHeader)
+
+# define COFF_F_RELFLG 0x0001
+# define COFF_F_EXEC 0x0002
+# define COFF_F_LNNO 0x0004
+# define COFF_F_LSYMS 0x0008
+# define COFF_F_LITTLE 0x0100
+# define COFF_F_BIG 0x0200
+# define COFF_F_SYMMERGE 0x1000
+
+typedef struct AOutHeader {
+ int16_t magic;
+ int16_t vstamp;
+ int32_t tsize;
+ int32_t dsize;
+ int32_t bsize;
+ int32_t entry;
+ int32_t text_start;
+ int32_t data_start;
+} AOutHeader;
+
+# define AOUT_HSZ sizeof(AOutHeader)
+
+# define AOUT_OMAGIC 0404
+# define AOUT_NMAGIC 0410
+# define AOUT_ZMAGIC 0413
+# define AOUT_STMAGIC 0401
+# define AOUT_SHMAGIC 0443
+
+typedef struct COFFSectionHeader {
+ int8_t name[8];
+ int32_t paddr;
+ int32_t vaddr;
+ int32_t size;
+ int32_t scnptr;
+ int32_t relptr;
+ int32_t lnnoptr;
+ uint16_t nreloc;
+ uint16_t nlnno;
+ int32_t flags;
+} COFFSectionHeader;
+
+/**
+ * @}
+ */
+
+#endif /* !LIBTCC_COFF_H */
\ No newline at end of file
diff --git a/libtcc/option.c b/libtcc/option.c
new file mode 100644
index 00000000..3091afc8
--- /dev/null
+++ b/libtcc/option.c
@@ -0,0 +1,2 @@
+#include "tcc.h"
+
diff --git a/libtcc/option.h b/libtcc/option.h
new file mode 100644
index 00000000..4539f91a
--- /dev/null
+++ b/libtcc/option.h
@@ -0,0 +1,6 @@
+#ifndef LIBTCC_OPTION_H
+# define LIBTCC_OPTION_H 1
+
+int tcc_parse_args(void *s, int *argc, char ***argv, int optind);
+
+#endif /* LIBTCC_OPTION_H */
\ No newline at end of file
diff --git a/tcc.h b/libtcc/tcc.h
similarity index 89%
rename from tcc.h
rename to libtcc/tcc.h
index d6352880..90527855 100644
--- a/tcc.h
+++ b/libtcc/tcc.h
@@ -69,7 +69,7 @@ extern long double strtold (const char *__nptr, char **__endptr);
# define strtoull _strtoui64
# endif
# ifdef LIBTCC_AS_DLL
-# define LIBTCCAPI __declspec(dllexport)
+# define __declspec(dllexport)
# define PUB_FUNC LIBTCCAPI
# endif
# ifdef _MSC_VER
@@ -138,29 +138,8 @@ extern long double strtold (const char *__nptr, char **__endptr);
/* assembler debug */
/* #define ASM_DEBUG */
-/* target selection */
-/* #define TCC_TARGET_I386 *//* i386 code generator */
-/* #define TCC_TARGET_X86_64 *//* x86-64 code generator */
-/* #define TCC_TARGET_ARM *//* ARMv4 code generator */
-/* #define TCC_TARGET_ARM64 *//* ARMv8 code generator */
-/* #define TCC_TARGET_C67 *//* TMS320C67xx code generator */
-/* #define TCC_TARGET_RISCV64 *//* risc-v code generator */
-
-/* default target is I386 */
# define TCC_TARGET_I386
-#if defined CONFIG_TCC_BACKTRACE && CONFIG_TCC_BACKTRACE==0
-# undef CONFIG_TCC_BACKTRACE
-#else
-# define CONFIG_TCC_BACKTRACE 1 /* enable builtin stack backtraces */
-#endif
-
-#if defined CONFIG_TCC_BCHECK && CONFIG_TCC_BCHECK==0
-# undef CONFIG_TCC_BCHECK
-#else
-# define CONFIG_TCC_BCHECK 1 /* enable bound checking code */
-#endif
-
#ifdef CONFIG_TCC_PIE
# define CONFIG_TCC_PIC 1
#endif
@@ -231,14 +210,6 @@ extern long double strtold (const char *__nptr, char **__endptr);
# define CONFIG_TCC_ELFINTERP "/lib/ld.so"
# elif defined(TCC_TARGET_PE)
# define CONFIG_TCC_ELFINTERP "-"
-# elif defined TCC_TARGET_ARM64
-# define CONFIG_TCC_ELFINTERP "/lib/ld-linux-aarch64.so.1"
-# elif defined(TCC_TARGET_X86_64)
-# define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2"
-# elif defined(TCC_TARGET_RISCV64)
-# define CONFIG_TCC_ELFINTERP "/lib/ld-linux-riscv64-lp64d.so.1"
-# elif defined(TCC_ARM_EABI)
-# define DEFAULT_ELFINTERP(s) default_elfinterp(s)
# else
# define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.2"
# endif
@@ -268,8 +239,7 @@ extern long double strtold (const char *__nptr, char **__endptr);
#include "libtcc.h"
#include "elf.h"
-#include "stab.h"
-#include "dwarf.h"
+#include "coff.h"
/* -------------------------------------------- */
@@ -290,8 +260,8 @@ extern long double strtold (const char *__nptr, char **__endptr);
/* include the target specific definitions */
#define TARGET_DEFS_ONLY
-# include "i386-gen.c"
-# include "i386-link.c"
+# include "i386/gen.c"
+# include "i386/link.c"
#undef TARGET_DEFS_ONLY
# define ELFCLASSW ELFCLASS32
@@ -606,9 +576,6 @@ struct sym_attr {
unsigned plt_offset;
int plt_sym;
int dyn_index;
-#ifdef TCC_TARGET_ARM
- unsigned char plt_thumb_stub:1;
-#endif
};
struct TCCState {
@@ -653,16 +620,6 @@ struct TCCState {
unsigned char include_sys_deps; /* option -MD */
unsigned char gen_phony_deps; /* option -MP */
- /* compile with debug symbol (and use them if error during execution) */
- unsigned char do_debug;
- unsigned char dwarf;
- unsigned char do_backtrace;
-#ifdef CONFIG_TCC_BCHECK
- /* compile with built-in memory and bounds checker */
- unsigned char do_bounds_check;
-#endif
- unsigned char test_coverage; /* generate test coverage code */
-
/* use GNU C extensions */
unsigned char gnu_ext;
/* use TinyCC extensions */
@@ -671,19 +628,11 @@ struct TCCState {
unsigned char dflag; /* -dX value */
unsigned char Pflag; /* -P switch (LINE_MACRO_OUTPUT_FORMAT) */
-#ifdef TCC_TARGET_X86_64
- unsigned char nosse; /* For -mno-sse support. */
-#endif
-#ifdef TCC_TARGET_ARM
- unsigned char float_abi; /* float ABI of the generated code*/
-#endif
-
unsigned char has_text_addr;
addr_t text_addr; /* address of text section */
unsigned section_align; /* section alignment */
-#ifdef TCC_TARGET_I386
+
int seg_size; /* 32. Can be 16 with i386 assembler (.code16) */
-#endif
char *tcc_lib_path; /* CONFIG_TCCDIR or -B option */
char *soname; /* as specified on the command line (-soname) */
@@ -697,8 +646,6 @@ struct TCCState {
int output_type;
/* output format, see TCC_OUTPUT_FORMAT_xxx */
int output_format;
- /* nth test to run with -dt -run */
- int run_test;
/* array of all loaded dlls (including those referenced by loaded dlls) */
DLLReference **loaded_dlls;
@@ -772,11 +719,6 @@ struct TCCState {
Section *text_section, *data_section, *rodata_section, *bss_section;
Section *common_section;
Section *cur_text_section; /* current section where function code is generated */
-#ifdef CONFIG_TCC_BCHECK
- /* bound check related sections */
- Section *bounds_section; /* contains global data bound description */
- Section *lbounds_section; /* contains local data bound description */
-#endif
/* symbol section */
union { Section *symtab_section, *symtab; }; /* historical alias */
/* temporary dynamic symbol sections (for dll loading) */
@@ -789,19 +731,6 @@ struct TCCState {
Section *eh_frame_section;
Section *eh_frame_hdr_section;
unsigned long eh_start;
- /* debug sections */
- Section *stab_section;
- Section *dwarf_info_section;
- Section *dwarf_abbrev_section;
- Section *dwarf_line_section;
- Section *dwarf_aranges_section;
- Section *dwarf_str_section;
- Section *dwarf_line_str_section;
- int dwlo, dwhi; /* dwarf section range */
- /* test coverage */
- Section *tcov_section;
- /* debug state */
- struct _tccdbg *dState;
/* Is there a new undefined sym since last new_undef_sym() */
int new_undef_sym;
@@ -812,11 +741,6 @@ struct TCCState {
ElfW_Rel *qrel;
#define qrel s1->qrel
-#ifdef TCC_TARGET_RISCV64
- struct pcrel_hi { addr_t addr, val; } last_hi;
- #define last_hi s1->last_hi
-#endif
-
#ifdef TCC_TARGET_PE
/* PE info */
int pe_subsystem;
@@ -824,17 +748,6 @@ struct TCCState {
unsigned pe_file_align;
unsigned pe_stack_size;
addr_t pe_imagebase;
-# ifdef TCC_TARGET_X86_64
- Section *uw_pdata;
- int uw_sym;
- unsigned uw_offs;
-# endif
-#endif
-
-#if defined TCC_TARGET_MACHO
- char *install_name;
- uint32_t compatibility_version;
- uint32_t current_version;
#endif
#ifndef ELF_OBJ_ONLY
@@ -847,24 +760,6 @@ struct TCCState {
Section *verneed_section;
#endif
-#ifdef TCC_IS_NATIVE
- const char *run_main; /* entry for tcc_run() */
- void *run_ptr; /* runtime_memory */
- unsigned run_size; /* size of runtime_memory */
-#ifdef _WIN64
- void *run_function_table; /* unwind data */
-#endif
- struct TCCState *next;
- struct rt_context *rc; /* pointer to backtrace info block */
- void *run_lj, *run_jb; /* sj/lj for tcc_setjmp()/tcc_run() */
- TCCBtFunc *bt_func;
- void *bt_data;
-#endif
-
-#ifdef CONFIG_TCC_BACKTRACE
- int rt_num_callers;
-#endif
-
/* benchmark info */
int total_idents;
int total_lines;
@@ -1079,9 +974,6 @@ ST_DATA void** stk_data;
ST_DATA int nb_stk_data;
/* public functions currently used by the tcc main function */
-ST_FUNC char *pstrcpy(char *buf, size_t buf_size, const char *s);
-ST_FUNC char *pstrcat(char *buf, size_t buf_size, const char *s);
-ST_FUNC char *pstrncpy(char *out, const char *in, size_t num);
PUB_FUNC char *tcc_basename(const char *name);
PUB_FUNC char *tcc_fileextension (const char *name);
@@ -1153,10 +1045,10 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
#define AFF_TYPE_LIB 8
#define AFF_TYPE_MASK (15 | AFF_TYPE_BIN)
/* values from tcc_object_type(...) */
-#define AFF_BINTYPE_REL 1
-#define AFF_BINTYPE_DYN 2
-#define AFF_BINTYPE_AR 3
-#define AFF_BINTYPE_C67 4
+#define AFF_BINTYPE_REL 1
+#define AFF_BINTYPE_DYN 2
+#define AFF_BINTYPE_AR 3
+#define AFF_BINTYPE_COFF 4
/* return value of tcc_add_file_internal(): 0, -1, or FILE_NOT_FOUND */
#define FILE_NOT_FOUND -2
@@ -1166,12 +1058,7 @@ ST_FUNC int tcc_add_crt(TCCState *s, const char *filename);
#endif
ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags);
ST_FUNC int tcc_add_support(TCCState *s1, const char *filename);
-#ifdef CONFIG_TCC_BCHECK
-ST_FUNC void tcc_add_bcheck(TCCState *s1);
-#endif
-#ifdef CONFIG_TCC_BACKTRACE
-ST_FUNC void tcc_add_btstub(TCCState *s1);
-#endif
+
ST_FUNC void tcc_add_pragma_libs(TCCState *s1);
PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f);
PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time);
@@ -1353,9 +1240,6 @@ ST_FUNC void vpop(void);
#if PTR_SIZE == 4
ST_FUNC void lexpand(void);
#endif
-#ifdef TCC_TARGET_ARM
-ST_FUNC int get_reg_ex(int rc, int rc2);
-#endif
ST_FUNC void save_reg(int r);
ST_FUNC void save_reg_upstack(int r, int n);
ST_FUNC int get_reg(int rc);
@@ -1374,23 +1258,12 @@ ST_FUNC void indir(void);
ST_FUNC void unary(void);
ST_FUNC void gexpr(void);
ST_FUNC int expr_const(void);
-#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67
-ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size);
-#endif
-#if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE
-ST_FUNC int classify_x86_64_va_arg(CType *ty);
-#endif
-#ifdef CONFIG_TCC_BCHECK
-ST_FUNC void gbound_args(int nb_args);
-ST_DATA int func_bound_add_epilog;
-#endif
/* ------------ tccelf.c ------------ */
#define TCC_OUTPUT_FORMAT_ELF 0 /* default output format: ELF */
#define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */
#define TCC_OUTPUT_FORMAT_COFF 2 /* COFF */
-#define TCC_OUTPUT_DYN TCC_OUTPUT_DLL
#define ARMAG "!\n" /* For COFF and a.out archives */
@@ -1455,9 +1328,11 @@ ST_FUNC void tccelf_add_crtend(TCCState *s1);
ST_FUNC void tcc_add_runtime(TCCState *s1);
#endif
+int coff_load_file(TCCState *s1, int fd, const char *fname);
+
/* ------------ xxx-link.c ------------ */
-#if !defined ELF_OBJ_ONLY || defined TCC_TARGET_MACHO
+#if !defined ELF_OBJ_ONLY
ST_FUNC int code_reloc (int reloc_type);
ST_FUNC int gotplt_entry_type (int reloc_type);
/* Whether to generate a GOT/PLT entry and when. NO_GOTPLT_ENTRY is first so
@@ -1470,13 +1345,11 @@ enum gotplt_entry {
};
#define NEED_RELOC_TYPE
-#if !defined TCC_TARGET_MACHO || defined TCC_IS_NATIVE
ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr);
ST_FUNC void relocate_plt(TCCState *s1);
ST_FUNC void build_got_entries(TCCState *s1, int got_sym); /* in tccelf.c */
#define NEED_BUILD_GOT
-#endif
#endif
ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val);
@@ -1504,9 +1377,7 @@ ST_FUNC void gen_cvt_ftoi(int t);
ST_FUNC void gen_cvt_itof(int t);
ST_FUNC void gen_cvt_ftof(int t);
ST_FUNC void ggoto(void);
-#ifndef TCC_TARGET_C67
ST_FUNC void o(unsigned int c);
-#endif
ST_FUNC void gen_vla_sp_save(int addr);
ST_FUNC void gen_vla_sp_restore(int addr);
ST_FUNC void gen_vla_alloc(CType *type, int align);
@@ -1584,17 +1455,15 @@ dwarf_read_sleb128(unsigned char **ln, unsigned char *end)
/* ------------ i386-gen.c ------------ */
-#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM
ST_FUNC void g(int c);
ST_FUNC void gen_le16(int c);
ST_FUNC void gen_le32(int c);
-#endif
-#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+
ST_FUNC void gen_addr32(int r, Sym *sym, int c);
ST_FUNC void gen_addrpc32(int r, Sym *sym, int c);
ST_FUNC void gen_cvt_csti(int t);
ST_FUNC void gen_increment_tcov (SValue *sv);
-#endif
+
@@ -1626,47 +1495,8 @@ ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str);
#define ST_ASM_SET 0x04
-/* ------------ tcctools.c ----------------- */
-#if 0 /* included in tcc.c */
-ST_FUNC int tcc_tool_ar(TCCState *s, int argc, char **argv);
-ST_FUNC int tcc_tool_cross(TCCState *s, char **argv, int option);
-ST_FUNC int gen_makedeps(TCCState *s, const char *target, const char *filename);
-#endif
-
/* ------------ tccdbg.c ------------ */
-ST_FUNC void tcc_debug_new(TCCState *s);
-
-ST_FUNC void tcc_debug_start(TCCState *s1);
-ST_FUNC void tcc_debug_end(TCCState *s1);
-ST_FUNC void tcc_debug_bincl(TCCState *s1);
-ST_FUNC void tcc_debug_eincl(TCCState *s1);
-ST_FUNC void tcc_debug_newfile(TCCState *s1);
-
-ST_FUNC void tcc_debug_line(TCCState *s1);
-ST_FUNC void tcc_add_debug_info(TCCState *s1, int param, Sym *s, Sym *e);
-ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym);
-ST_FUNC void tcc_debug_prolog_epilog(TCCState *s1, int value);
-ST_FUNC void tcc_debug_funcend(TCCState *s1, int size);
-ST_FUNC void tcc_debug_extern_sym(TCCState *s1, Sym *sym, int sh_num, int sym_bind, int sym_type);
-ST_FUNC void tcc_debug_typedef(TCCState *s1, Sym *sym);
-ST_FUNC void tcc_debug_stabn(TCCState *s1, int type, int value);
-ST_FUNC void tcc_debug_fix_anon(TCCState *s1, CType *t);
-
-#if !(defined ELF_OBJ_ONLY || defined TCC_TARGET_ARM || defined TARGETOS_BSD)
-ST_FUNC void tcc_eh_frame_start(TCCState *s1);
-ST_FUNC void tcc_eh_frame_end(TCCState *s1);
-ST_FUNC void tcc_eh_frame_hdr(TCCState *s1, int final);
-#define TCC_EH_FRAME 1
-#endif
-
-ST_FUNC void tcc_tcov_start(TCCState *s1);
-ST_FUNC void tcc_tcov_end(TCCState *s1);
-ST_FUNC void tcc_tcov_check_line(TCCState *s1, int start);
-ST_FUNC void tcc_tcov_block_end(TCCState *s1, int line);
-ST_FUNC void tcc_tcov_block_begin(TCCState *s1);
-ST_FUNC void tcc_tcov_reset_ind(TCCState *s1);
-
#define stab_section s1->stab_section
#define stabstr_section stab_section->link
#define tcov_section s1->tcov_section
@@ -1679,12 +1509,6 @@ ST_FUNC void tcc_tcov_reset_ind(TCCState *s1);
#define dwarf_str_section s1->dwarf_str_section
#define dwarf_line_str_section s1->dwarf_line_str_section
-/* default dwarf version for "-gdwarf" */
-#ifdef TCC_TARGET_MACHO
-# define DEFAULT_DWARF_VERSION 2
-#else
-# define DEFAULT_DWARF_VERSION 5
-#endif
/* default dwarf version for "-g". use 0 to emit stab debug infos */
#ifndef CONFIG_DWARF_VERSION
@@ -1693,8 +1517,6 @@ ST_FUNC void tcc_tcov_reset_ind(TCCState *s1);
#if defined TCC_TARGET_PE
# define R_DATA_32DW 'Z' /* fake code to avoid DLL relocs */
-#elif defined TCC_TARGET_X86_64
-# define R_DATA_32DW R_X86_64_32
#else
# define R_DATA_32DW R_DATA_32
#endif
diff --git a/tccasm.c b/libtcc/tccasm.c
similarity index 99%
rename from tccasm.c
rename to libtcc/tccasm.c
index 52d81fa8..907ba5e8 100644
--- a/tccasm.c
+++ b/libtcc/tccasm.c
@@ -20,6 +20,7 @@
#define USING_GLOBALS
#include "tcc.h"
+#include "utils/string.h"
#ifdef CONFIG_TCC_ASM
static Section *last_text_section; /* to handle .previous asm directive */
@@ -958,7 +959,6 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global)
next();
if (tok == TOK_EOF)
break;
- tcc_debug_line(s1);
parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
redo:
if (tok == '#') {
@@ -1009,14 +1009,12 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global)
ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
{
int ret;
- tcc_debug_start(s1);
/* default section is text */
cur_text_section = text_section;
ind = cur_text_section->data_offset;
nocode_wanted = 0;
ret = tcc_assemble_internal(s1, do_preprocess, 1);
cur_text_section->data_offset = ind;
- tcc_debug_end(s1);
return ret;
}
diff --git a/tcccoff.c b/libtcc/tcccoff.c
similarity index 81%
rename from tcccoff.c
rename to libtcc/tcccoff.c
index fbbc58ee..7fd44c96 100644
--- a/tcccoff.c
+++ b/libtcc/tcccoff.c
@@ -15,14 +15,29 @@ coff_load_lib(TCCState *s1, int fd)
return (0);
}
+static int
+coff_merge_or_create(void)
+{
+ return (0);
+}
+
+static int
+coff_resolve_symbols(void)
+{
+ return (0);
+}
+
int
coff_load_obj(TCCState *s1, int fd)
{
FILHDR hdr;
SCNHDR *scns;
SYMENT *syments;
+ RELOC *relocs;
+ Section *s;
uint16_t i;
int32_t j;
+ int k;
char buff[9];
if (!read_mem(fd, 0, &hdr, FILHSZ))
@@ -31,8 +46,6 @@ coff_load_obj(TCCState *s1, int fd)
if (hdr.f_magic != F_MACH_I386 || hdr.f_flags & F_EXEC)
return (tcc_error_noabort("invalid coff object file"));
- /* load symtab */
-
/* read sections */
scns = tcc_malloc(SCNHSZ * hdr.f_nscns);
if (!read_mem(fd, FILHSZ, scns, SCNHSZ * hdr.f_nscns))
@@ -46,6 +59,17 @@ coff_load_obj(TCCState *s1, int fd)
memset(buff, 0, 9);
memcpy(buff, scns[i].s_name, 8);
printf("sec: %s\n", buff);
+
+ for (k = 1; k < s1->nb_sections; k++)
+ {
+ if (strcmp(s1->sections[k]->name, buff) != 0)
+ {
+ continue;
+ }
+
+
+ }
+
}
/* load symtab */
@@ -54,7 +78,7 @@ coff_load_obj(TCCState *s1, int fd)
for (j = 0; j < hdr.f_nsyms; j++)
{
memset(buff, 0, 9);
- memcpy(buff, syments[i].n_name, 8);
+ memcpy(buff, syments[j].n_name, 8);
printf("sym: %s\n", buff);
}
diff --git a/libtcc/tcccoff.c_old.c b/libtcc/tcccoff.c_old.c
new file mode 100644
index 00000000..56064cdd
--- /dev/null
+++ b/libtcc/tcccoff.c_old.c
@@ -0,0 +1,951 @@
+/*
+ * COFF file handling for TCC
+ *
+ * Copyright (c) 2003, 2004 TK
+ * Copyright (c) 2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "tcc.h"
+
+/* XXX: this file uses tcc_error() to the effect of exit(1) */
+#undef _tcc_error
+
+#define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */
+#define MAX_STR_TABLE 1000000
+AOUTHDR o_filehdr; /* OPTIONAL (A.OUT) FILE HEADER */
+
+SCNHDR section_header[MAXNSCNS];
+
+#define MAX_FUNCS 1000
+#define MAX_FUNC_NAME_LENGTH 128
+
+int nFuncs;
+char Func[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
+char AssociatedFile[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
+int LineNoFilePtr[MAX_FUNCS];
+int EndAddress[MAX_FUNCS];
+int LastLineNo[MAX_FUNCS];
+int FuncEntries[MAX_FUNCS];
+
+int OutputTheSection(Section * sect);
+short int GetCoffFlags(const char *s);
+void SortSymbolTable(TCCState *s1);
+Section *FindSection(TCCState * s1, const char *sname);
+
+int C67_main_entry_point;
+
+int FindCoffSymbolIndex(TCCState * s1, const char *func_name);
+int nb_syms;
+
+typedef struct {
+ long tag;
+ long size;
+ long fileptr;
+ long nextsym;
+ short int dummy;
+} AUXFUNC;
+
+typedef struct {
+ long regmask;
+ unsigned short lineno;
+ unsigned short nentries;
+ int localframe;
+ int nextentry;
+ short int dummy;
+} AUXBF;
+
+typedef struct {
+ long dummy;
+ unsigned short lineno;
+ unsigned short dummy1;
+ int dummy2;
+ int dummy3;
+ unsigned short dummy4;
+} AUXEF;
+
+ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
+{
+ Section *tcc_sect;
+ SCNHDR *coff_sec;
+ int file_pointer;
+ char *Coff_str_table, *pCoff_str_table;
+ int CoffTextSectionNo, coff_nb_syms;
+ FILHDR file_hdr; /* FILE HEADER STRUCTURE */
+ Section *stext, *sdata, *sbss;
+ int i, NSectionsToOutput = 0;
+
+ Coff_str_table = pCoff_str_table = NULL;
+
+ stext = FindSection(s1, ".text");
+ sdata = FindSection(s1, ".data");
+ sbss = FindSection(s1, ".bss");
+
+ nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
+ coff_nb_syms = FindCoffSymbolIndex(s1, "XXXXXXXXXX1");
+
+ file_hdr.f_magic = COFF_C67_MAGIC; /* magic number */
+ file_hdr.f_timdat = 0; /* time & date stamp */
+ file_hdr.f_opthdr = sizeof(AOUTHDR); /* sizeof(optional hdr) */
+ file_hdr.f_flags = 0x1143; /* flags (copied from what code composer does) */
+ file_hdr.f_TargetID = 0x99; /* for C6x = 0x0099 */
+
+ o_filehdr.magic = 0x0108; /* see magic.h */
+ o_filehdr.vstamp = 0x0190; /* version stamp */
+ o_filehdr.tsize = stext->data_offset; /* text size in bytes, padded to FW bdry */
+ o_filehdr.dsize = sdata->data_offset; /* initialized data " " */
+ o_filehdr.bsize = sbss->data_offset; /* uninitialized data " " */
+ o_filehdr.entrypt = C67_main_entry_point; /* entry pt. */
+ o_filehdr.text_start = stext->sh_addr; /* base of text used for this file */
+ o_filehdr.data_start = sdata->sh_addr; /* base of data used for this file */
+
+
+ // create all the section headers
+
+ file_pointer = FILHSZ + sizeof(AOUTHDR);
+
+ CoffTextSectionNo = -1;
+
+ for (i = 1; i < s1->nb_sections; i++) {
+ coff_sec = §ion_header[i];
+ tcc_sect = s1->sections[i];
+
+ if (OutputTheSection(tcc_sect)) {
+ NSectionsToOutput++;
+
+ if (CoffTextSectionNo == -1 && tcc_sect == stext)
+ CoffTextSectionNo = NSectionsToOutput; // rem which coff sect number the .text sect is
+
+ strcpy(coff_sec->s_name, tcc_sect->name); /* section name */
+
+ coff_sec->s_paddr = tcc_sect->sh_addr; /* physical address */
+ coff_sec->s_vaddr = tcc_sect->sh_addr; /* virtual address */
+ coff_sec->s_size = tcc_sect->data_offset; /* section size */
+ coff_sec->s_scnptr = 0; /* file ptr to raw data for section */
+ coff_sec->s_relptr = 0; /* file ptr to relocation */
+ coff_sec->s_lnnoptr = 0; /* file ptr to line numbers */
+ coff_sec->s_nreloc = 0; /* number of relocation entries */
+ coff_sec->s_flags = GetCoffFlags(coff_sec->s_name); /* flags */
+ coff_sec->s_reserved = 0; /* reserved byte */
+ coff_sec->s_page = 0; /* memory page id */
+
+ file_pointer += sizeof(SCNHDR);
+ }
+ }
+
+ file_hdr.f_nscns = NSectionsToOutput; /* number of sections */
+
+ // now loop through and determine file pointer locations
+ // for the raw data
+
+
+ for (i = 1; i < s1->nb_sections; i++) {
+ coff_sec = §ion_header[i];
+ tcc_sect = s1->sections[i];
+
+ if (OutputTheSection(tcc_sect)) {
+ // put raw data
+ coff_sec->s_scnptr = file_pointer; /* file ptr to raw data for section */
+ file_pointer += coff_sec->s_size;
+ }
+ }
+
+ // now loop through and determine file pointer locations
+ // for the relocation data
+
+ for (i = 1; i < s1->nb_sections; i++) {
+ coff_sec = §ion_header[i];
+ tcc_sect = s1->sections[i];
+
+ if (OutputTheSection(tcc_sect)) {
+ // put relocations data
+ if (coff_sec->s_nreloc > 0) {
+ coff_sec->s_relptr = file_pointer; /* file ptr to relocation */
+ file_pointer += coff_sec->s_nreloc * sizeof(struct reloc);
+ }
+ }
+ }
+
+ // now loop through and determine file pointer locations
+ // for the line number data
+
+ for (i = 1; i < s1->nb_sections; i++) {
+ coff_sec = §ion_header[i];
+ tcc_sect = s1->sections[i];
+
+ coff_sec->s_nlnno = 0;
+ coff_sec->s_lnnoptr = 0;
+
+ if (s1->do_debug && tcc_sect == stext) {
+ // count how many line nos data
+
+ // also find association between source file name and function
+ // so we can sort the symbol table
+
+
+ Stab_Sym *sym, *sym_end;
+ char func_name[MAX_FUNC_NAME_LENGTH],
+ last_func_name[MAX_FUNC_NAME_LENGTH];
+ unsigned long func_addr, last_pc, pc;
+ const char *incl_files[INCLUDE_STACK_SIZE];
+ int incl_index, len, last_line_num;
+ const char *str, *p;
+
+ coff_sec->s_lnnoptr = file_pointer; /* file ptr to linno */
+
+
+ func_name[0] = '\0';
+ func_addr = 0;
+ incl_index = 0;
+ last_func_name[0] = '\0';
+ last_pc = 0xffffffff;
+ last_line_num = 1;
+ sym = (Stab_Sym *) stab_section->data + 1;
+ sym_end =
+ (Stab_Sym *) (stab_section->data +
+ stab_section->data_offset);
+
+ nFuncs = 0;
+ while (sym < sym_end) {
+ switch (sym->n_type) {
+ /* function start or end */
+ case N_FUN:
+ if (sym->n_strx == 0) {
+ // end of function
+
+ coff_sec->s_nlnno++;
+ file_pointer += LINESZ;
+
+ pc = sym->n_value + func_addr;
+ func_name[0] = '\0';
+ func_addr = 0;
+ EndAddress[nFuncs] = pc;
+ FuncEntries[nFuncs] =
+ (file_pointer -
+ LineNoFilePtr[nFuncs]) / LINESZ - 1;
+ LastLineNo[nFuncs++] = last_line_num + 1;
+ } else {
+ // beginning of function
+
+ LineNoFilePtr[nFuncs] = file_pointer;
+ coff_sec->s_nlnno++;
+ file_pointer += LINESZ;
+
+ str =
+ (const char *) stabstr_section->data +
+ sym->n_strx;
+
+ p = strchr(str, ':');
+ if (!p) {
+ pstrcpy(func_name, sizeof(func_name), str);
+ pstrcpy(Func[nFuncs], sizeof(func_name), str);
+ } else {
+ len = p - str;
+ if (len > sizeof(func_name) - 1)
+ len = sizeof(func_name) - 1;
+ memcpy(func_name, str, len);
+ memcpy(Func[nFuncs], str, len);
+ func_name[len] = '\0';
+ }
+
+ // save the file that it came in so we can sort later
+ pstrcpy(AssociatedFile[nFuncs], sizeof(func_name),
+ incl_files[incl_index - 1]);
+
+ func_addr = sym->n_value;
+ }
+ break;
+
+ /* line number info */
+ case N_SLINE:
+ pc = sym->n_value + func_addr;
+
+ last_pc = pc;
+ last_line_num = sym->n_desc;
+
+ /* XXX: slow! */
+ strcpy(last_func_name, func_name);
+
+ coff_sec->s_nlnno++;
+ file_pointer += LINESZ;
+ break;
+ /* include files */
+ case N_BINCL:
+ str =
+ (const char *) stabstr_section->data + sym->n_strx;
+ add_incl:
+ if (incl_index < INCLUDE_STACK_SIZE) {
+ incl_files[incl_index++] = str;
+ }
+ break;
+ case N_EINCL:
+ if (incl_index > 1)
+ incl_index--;
+ break;
+ case N_SO:
+ if (sym->n_strx == 0) {
+ incl_index = 0; /* end of translation unit */
+ } else {
+ str =
+ (const char *) stabstr_section->data +
+ sym->n_strx;
+ /* do not add path */
+ len = strlen(str);
+ if (len > 0 && str[len - 1] != '/')
+ goto add_incl;
+ }
+ break;
+ }
+ sym++;
+ }
+ }
+
+ }
+
+ file_hdr.f_symptr = file_pointer; /* file pointer to symtab */
+
+ if (s1->do_debug)
+ file_hdr.f_nsyms = coff_nb_syms; /* number of symtab entries */
+ else
+ file_hdr.f_nsyms = 0;
+
+ file_pointer += file_hdr.f_nsyms * SYMNMLEN;
+
+ // OK now we are all set to write the file
+
+
+ fwrite(&file_hdr, FILHSZ, 1, f);
+ fwrite(&o_filehdr, sizeof(o_filehdr), 1, f);
+
+ // write section headers
+ for (i = 1; i < s1->nb_sections; i++) {
+ coff_sec = §ion_header[i];
+ tcc_sect = s1->sections[i];
+
+ if (OutputTheSection(tcc_sect)) {
+ fwrite(coff_sec, sizeof(SCNHDR), 1, f);
+ }
+ }
+
+ // write raw data
+ for (i = 1; i < s1->nb_sections; i++) {
+ coff_sec = §ion_header[i];
+ tcc_sect = s1->sections[i];
+
+ if (OutputTheSection(tcc_sect)) {
+ fwrite(tcc_sect->data, tcc_sect->data_offset, 1, f);
+ }
+ }
+
+ // write relocation data
+ for (i = 1; i < s1->nb_sections; i++) {
+ coff_sec = §ion_header[i];
+ tcc_sect = s1->sections[i];
+
+ if (OutputTheSection(tcc_sect)) {
+ // put relocations data
+ if (coff_sec->s_nreloc > 0) {
+ fwrite(tcc_sect->reloc,
+ coff_sec->s_nreloc * sizeof(struct reloc), 1, f);
+ }
+ }
+ }
+
+
+ // group the symbols in order of filename, func1, func2, etc
+ // finally global symbols
+
+ if (s1->do_debug)
+ SortSymbolTable(s1);
+
+ // write line no data
+
+ for (i = 1; i < s1->nb_sections; i++) {
+ coff_sec = §ion_header[i];
+ tcc_sect = s1->sections[i];
+
+ if (s1->do_debug && tcc_sect == stext) {
+ // count how many line nos data
+
+
+ Stab_Sym *sym, *sym_end;
+ char func_name[128], last_func_name[128];
+ unsigned long func_addr, last_pc, pc;
+ const char *incl_files[INCLUDE_STACK_SIZE];
+ int incl_index, len, last_line_num;
+ const char *str, *p;
+
+ LINENO CoffLineNo;
+
+ func_name[0] = '\0';
+ func_addr = 0;
+ incl_index = 0;
+ last_func_name[0] = '\0';
+ last_pc = 0;
+ last_line_num = 1;
+ sym = (Stab_Sym *) stab_section->data + 1;
+ sym_end =
+ (Stab_Sym *) (stab_section->data +
+ stab_section->data_offset);
+
+ while (sym < sym_end) {
+ switch (sym->n_type) {
+ /* function start or end */
+ case N_FUN:
+ if (sym->n_strx == 0) {
+ // end of function
+
+ CoffLineNo.l_addr.l_paddr = last_pc;
+ CoffLineNo.l_lnno = last_line_num + 1;
+ fwrite(&CoffLineNo, 6, 1, f);
+
+ pc = sym->n_value + func_addr;
+ func_name[0] = '\0';
+ func_addr = 0;
+ } else {
+ // beginning of function
+
+ str =
+ (const char *) stabstr_section->data +
+ sym->n_strx;
+
+
+ p = strchr(str, ':');
+ if (!p) {
+ pstrcpy(func_name, sizeof(func_name), str);
+ } else {
+ len = p - str;
+ if (len > sizeof(func_name) - 1)
+ len = sizeof(func_name) - 1;
+ memcpy(func_name, str, len);
+ func_name[len] = '\0';
+ }
+ func_addr = sym->n_value;
+ last_pc = func_addr;
+ last_line_num = -1;
+
+ // output a function begin
+
+ CoffLineNo.l_addr.l_symndx =
+ FindCoffSymbolIndex(s1, func_name);
+ CoffLineNo.l_lnno = 0;
+
+ fwrite(&CoffLineNo, 6, 1, f);
+ }
+ break;
+
+ /* line number info */
+ case N_SLINE:
+ pc = sym->n_value + func_addr;
+
+
+ /* XXX: slow! */
+ strcpy(last_func_name, func_name);
+
+ // output a line reference
+
+ CoffLineNo.l_addr.l_paddr = last_pc;
+
+ if (last_line_num == -1) {
+ CoffLineNo.l_lnno = sym->n_desc;
+ } else {
+ CoffLineNo.l_lnno = last_line_num + 1;
+ }
+
+ fwrite(&CoffLineNo, 6, 1, f);
+
+ last_pc = pc;
+ last_line_num = sym->n_desc;
+
+ break;
+
+ /* include files */
+ case N_BINCL:
+ str =
+ (const char *) stabstr_section->data + sym->n_strx;
+ add_incl2:
+ if (incl_index < INCLUDE_STACK_SIZE) {
+ incl_files[incl_index++] = str;
+ }
+ break;
+ case N_EINCL:
+ if (incl_index > 1)
+ incl_index--;
+ break;
+ case N_SO:
+ if (sym->n_strx == 0) {
+ incl_index = 0; /* end of translation unit */
+ } else {
+ str =
+ (const char *) stabstr_section->data +
+ sym->n_strx;
+ /* do not add path */
+ len = strlen(str);
+ if (len > 0 && str[len - 1] != '/')
+ goto add_incl2;
+ }
+ break;
+ }
+ sym++;
+ }
+ }
+ }
+
+ // write symbol table
+ if (s1->do_debug) {
+ int k;
+ struct syment csym;
+ AUXFUNC auxfunc;
+ AUXBF auxbf;
+ AUXEF auxef;
+ int i;
+ Elf32_Sym *p;
+ const char *name;
+ int nstr;
+ int n = 0;
+
+ Coff_str_table = (char *) tcc_malloc(MAX_STR_TABLE);
+ pCoff_str_table = Coff_str_table;
+ nstr = 0;
+
+ p = (Elf32_Sym *) symtab_section->data;
+
+
+ for (i = 0; i < nb_syms; i++) {
+
+ name = symtab_section->link->data + p->st_name;
+
+ for (k = 0; k < 8; k++)
+ csym._n._n_name[k] = 0;
+
+ if (strlen(name) <= 8) {
+ strcpy(csym._n._n_name, name);
+ } else {
+ if (pCoff_str_table - Coff_str_table + strlen(name) >
+ MAX_STR_TABLE - 1)
+ tcc_error("String table too large");
+
+ csym._n._n_n._n_zeroes = 0;
+ csym._n._n_n._n_offset =
+ pCoff_str_table - Coff_str_table + 4;
+
+ strcpy(pCoff_str_table, name);
+ pCoff_str_table += strlen(name) + 1; // skip over null
+ nstr++;
+ }
+
+ if (p->st_info == 4) {
+ // put a filename symbol
+ csym.n_value = 33; // ?????
+ csym.n_scnum = N_DEBUG;
+ csym.n_type = 0;
+ csym.n_sclass = C_FILE;
+ csym.n_numaux = 0;
+ fwrite(&csym, 18, 1, f);
+ n++;
+
+ } else if (p->st_info == 0x12) {
+ // find the function data
+
+ for (k = 0; k < nFuncs; k++) {
+ if (strcmp(name, Func[k]) == 0)
+ break;
+ }
+
+ if (k >= nFuncs) {
+ tcc_error("debug info can't find function: %s", name);
+ }
+ // put a Function Name
+
+ csym.n_value = p->st_value; // physical address
+ csym.n_scnum = CoffTextSectionNo;
+ csym.n_type = MKTYPE(T_INT, DT_FCN, 0, 0, 0, 0, 0);
+ csym.n_sclass = C_EXT;
+ csym.n_numaux = 1;
+ fwrite(&csym, 18, 1, f);
+
+ // now put aux info
+
+ auxfunc.tag = 0;
+ auxfunc.size = EndAddress[k] - p->st_value;
+ auxfunc.fileptr = LineNoFilePtr[k];
+ auxfunc.nextsym = n + 6; // tktk
+ auxfunc.dummy = 0;
+ fwrite(&auxfunc, 18, 1, f);
+
+ // put a .bf
+
+ strcpy(csym._n._n_name, ".bf");
+ csym.n_value = p->st_value; // physical address
+ csym.n_scnum = CoffTextSectionNo;
+ csym.n_type = 0;
+ csym.n_sclass = C_FCN;
+ csym.n_numaux = 1;
+ fwrite(&csym, 18, 1, f);
+
+ // now put aux info
+
+ auxbf.regmask = 0;
+ auxbf.lineno = 0;
+ auxbf.nentries = FuncEntries[k];
+ auxbf.localframe = 0;
+ auxbf.nextentry = n + 6;
+ auxbf.dummy = 0;
+ fwrite(&auxbf, 18, 1, f);
+
+ // put a .ef
+
+ strcpy(csym._n._n_name, ".ef");
+ csym.n_value = EndAddress[k]; // physical address
+ csym.n_scnum = CoffTextSectionNo;
+ csym.n_type = 0;
+ csym.n_sclass = C_FCN;
+ csym.n_numaux = 1;
+ fwrite(&csym, 18, 1, f);
+
+ // now put aux info
+
+ auxef.dummy = 0;
+ auxef.lineno = LastLineNo[k];
+ auxef.dummy1 = 0;
+ auxef.dummy2 = 0;
+ auxef.dummy3 = 0;
+ auxef.dummy4 = 0;
+ fwrite(&auxef, 18, 1, f);
+
+ n += 6;
+
+ } else {
+ // try an put some type info
+
+ if ((p->st_other & VT_BTYPE) == VT_DOUBLE) {
+ csym.n_type = T_DOUBLE; // int
+ csym.n_sclass = C_EXT;
+ } else if ((p->st_other & VT_BTYPE) == VT_FLOAT) {
+ csym.n_type = T_FLOAT;
+ csym.n_sclass = C_EXT;
+ } else if ((p->st_other & VT_BTYPE) == VT_INT) {
+ csym.n_type = T_INT; // int
+ csym.n_sclass = C_EXT;
+ } else if ((p->st_other & VT_BTYPE) == VT_SHORT) {
+ csym.n_type = T_SHORT;
+ csym.n_sclass = C_EXT;
+ } else if ((p->st_other & VT_BTYPE) == VT_BYTE) {
+ csym.n_type = T_CHAR;
+ csym.n_sclass = C_EXT;
+ } else {
+ csym.n_type = T_INT; // just mark as a label
+ csym.n_sclass = C_LABEL;
+ }
+
+
+ csym.n_value = p->st_value;
+ csym.n_scnum = 2;
+ csym.n_numaux = 1;
+ fwrite(&csym, 18, 1, f);
+
+ auxfunc.tag = 0;
+ auxfunc.size = 0x20;
+ auxfunc.fileptr = 0;
+ auxfunc.nextsym = 0;
+ auxfunc.dummy = 0;
+ fwrite(&auxfunc, 18, 1, f);
+ n++;
+ n++;
+
+ }
+
+ p++;
+ }
+ }
+
+ if (s1->do_debug) {
+ // write string table
+
+ // first write the size
+ i = pCoff_str_table - Coff_str_table;
+ fwrite(&i, 4, 1, f);
+
+ // then write the strings
+ fwrite(Coff_str_table, i, 1, f);
+
+ tcc_free(Coff_str_table);
+ }
+
+ return 0;
+}
+
+
+
+// group the symbols in order of filename, func1, func2, etc
+// finally global symbols
+
+void SortSymbolTable(TCCState *s1)
+{
+ int i, j, k, n = 0;
+ Elf32_Sym *p, *p2, *NewTable;
+ char *name, *name2;
+
+ NewTable = (Elf32_Sym *) tcc_malloc(nb_syms * sizeof(Elf32_Sym));
+
+ p = (Elf32_Sym *) symtab_section->data;
+
+
+ // find a file symbol, copy it over
+ // then scan the whole symbol list and copy any function
+ // symbols that match the file association
+
+ for (i = 0; i < nb_syms; i++) {
+ if (p->st_info == 4) {
+ name = (char *) symtab_section->link->data + p->st_name;
+
+ // this is a file symbol, copy it over
+
+ NewTable[n++] = *p;
+
+ p2 = (Elf32_Sym *) symtab_section->data;
+
+ for (j = 0; j < nb_syms; j++) {
+ if (p2->st_info == 0x12) {
+ // this is a func symbol
+
+ name2 =
+ (char *) symtab_section->link->data + p2->st_name;
+
+ // find the function data index
+
+ for (k = 0; k < nFuncs; k++) {
+ if (strcmp(name2, Func[k]) == 0)
+ break;
+ }
+
+ if (k >= nFuncs) {
+ tcc_error("debug (sort) info can't find function: %s", name2);
+ }
+
+ if (strcmp(AssociatedFile[k], name) == 0) {
+ // yes they match copy it over
+
+ NewTable[n++] = *p2;
+ }
+ }
+ p2++;
+ }
+ }
+ p++;
+ }
+
+ // now all the filename and func symbols should have been copied over
+ // copy all the rest over (all except file and funcs)
+
+ p = (Elf32_Sym *) symtab_section->data;
+ for (i = 0; i < nb_syms; i++) {
+ if (p->st_info != 4 && p->st_info != 0x12) {
+ NewTable[n++] = *p;
+ }
+ p++;
+ }
+
+ if (n != nb_syms)
+ tcc_error("Internal Compiler error, debug info");
+
+ // copy it all back
+
+ p = (Elf32_Sym *) symtab_section->data;
+ for (i = 0; i < nb_syms; i++) {
+ *p++ = NewTable[i];
+ }
+
+ tcc_free(NewTable);
+}
+
+
+int FindCoffSymbolIndex(TCCState *s1, const char *func_name)
+{
+ int i, n = 0;
+ Elf32_Sym *p;
+ char *name;
+
+ p = (Elf32_Sym *) symtab_section->data;
+
+ for (i = 0; i < nb_syms; i++) {
+
+ name = (char *) symtab_section->link->data + p->st_name;
+
+ if (p->st_info == 4) {
+ // put a filename symbol
+ n++;
+ } else if (p->st_info == 0x12) {
+
+ if (strcmp(func_name, name) == 0)
+ return n;
+
+ n += 6;
+
+ // put a Function Name
+
+ // now put aux info
+
+ // put a .bf
+
+ // now put aux info
+
+ // put a .ef
+
+ // now put aux info
+
+ } else {
+ n += 2;
+ }
+
+ p++;
+ }
+
+ return n; // total number of symbols
+}
+
+int OutputTheSection(Section * sect)
+{
+ const char *s = sect->name;
+
+ if (!strcmp(s, ".text"))
+ return 1;
+ else if (!strcmp(s, ".data"))
+ return 1;
+ else
+ return 0;
+}
+
+short int GetCoffFlags(const char *s)
+{
+ if (!strcmp(s, ".text"))
+ return STYP_TEXT | STYP_DATA | STYP_ALIGN | 0x400;
+ else if (!strcmp(s, ".data"))
+ return STYP_DATA;
+ else if (!strcmp(s, ".bss"))
+ return STYP_BSS;
+ else if (!strcmp(s, ".stack"))
+ return STYP_BSS | STYP_ALIGN | 0x200;
+ else if (!strcmp(s, ".cinit"))
+ return STYP_COPY | STYP_DATA | STYP_ALIGN | 0x200;
+ else
+ return 0;
+}
+
+Section *FindSection(TCCState * s1, const char *sname)
+{
+ Section *s;
+ int i;
+
+ for (i = 1; i < s1->nb_sections; i++) {
+ s = s1->sections[i];
+
+ if (!strcmp(sname, s->name))
+ return s;
+ }
+
+ tcc_error("could not find section %s", sname);
+ return 0;
+}
+
+ST_FUNC int tcc_load_coff(TCCState * s1, int fd)
+{
+// tktk TokenSym *ts;
+
+ FILE *f;
+ unsigned int str_size;
+ char *Coff_str_table, *name;
+ int i, k;
+ struct syment csym;
+ char name2[9];
+ FILHDR file_hdr; /* FILE HEADER STRUCTURE */
+
+ f = fdopen(fd, "rb");
+ if (!f) {
+ tcc_error("Unable to open .out file for input");
+ }
+
+ if (fread(&file_hdr, FILHSZ, 1, f) != 1)
+ tcc_error("error reading .out file for input");
+
+ if (fread(&o_filehdr, sizeof(o_filehdr), 1, f) != 1)
+ tcc_error("error reading .out file for input");
+
+ // first read the string table
+
+ if (fseek(f, file_hdr.f_symptr + file_hdr.f_nsyms * SYMESZ, SEEK_SET))
+ tcc_error("error reading .out file for input");
+
+ if (fread(&str_size, sizeof(int), 1, f) != 1)
+ tcc_error("error reading .out file for input");
+
+
+ Coff_str_table = (char *) tcc_malloc(str_size);
+
+ if (fread(Coff_str_table, str_size - 4, 1, f) != 1)
+ tcc_error("error reading .out file for input");
+
+ // read/process all the symbols
+
+ // seek back to symbols
+
+ if (fseek(f, file_hdr.f_symptr, SEEK_SET))
+ tcc_error("error reading .out file for input");
+
+ for (i = 0; i < file_hdr.f_nsyms; i++) {
+ if (fread(&csym, SYMESZ, 1, f) != 1)
+ tcc_error("error reading .out file for input");
+
+ if (csym._n._n_n._n_zeroes == 0) {
+ name = Coff_str_table + csym._n._n_n._n_offset - 4;
+ } else {
+ name = csym._n._n_name;
+
+ if (name[7] != 0) {
+ for (k = 0; k < 8; k++)
+ name2[k] = name[k];
+
+ name2[8] = 0;
+
+ name = name2;
+ }
+ }
+// if (strcmp("_DAC_Buffer",name)==0) // tktk
+// name[0]=0;
+
+ if (((csym.n_type & 0x30) == 0x20 && csym.n_sclass == 0x2) || ((csym.n_type & 0x30) == 0x30 && csym.n_sclass == 0x2) || (csym.n_type == 0x4 && csym.n_sclass == 0x2) || (csym.n_type == 0x8 && csym.n_sclass == 0x2) || // structures
+ (csym.n_type == 0x18 && csym.n_sclass == 0x2) || // pointer to structure
+ (csym.n_type == 0x7 && csym.n_sclass == 0x2) || // doubles
+ (csym.n_type == 0x6 && csym.n_sclass == 0x2)) // floats
+ {
+ // strip off any leading underscore (except for other main routine)
+
+ if (name[0] == '_' && strcmp(name, "_main") != 0)
+ name++;
+
+ tcc_add_symbol(s1, name, (void*)(uintptr_t)csym.n_value);
+ }
+ // skip any aux records
+
+ if (csym.n_numaux == 1) {
+ if (fread(&csym, SYMESZ, 1, f) != 1)
+ tcc_error("error reading .out file for input");
+ i++;
+ }
+ }
+
+ return 0;
+}
diff --git a/tccelf.c b/libtcc/tccelf.c
similarity index 86%
rename from tccelf.c
rename to libtcc/tccelf.c
index c9286aa2..7fe67098 100644
--- a/tccelf.c
+++ b/libtcc/tccelf.c
@@ -19,6 +19,7 @@
*/
#include "tcc.h"
+#include "utils/string.h"
/* Define this to get some debug output during relocation processing. */
#undef DEBUG_RELOC
@@ -84,26 +85,6 @@ ST_FUNC void tccelf_new(TCCState *s)
".dynhashtab", SHF_PRIVATE);
get_sym_attr(s, 0, 1);
- if (s->do_debug) {
- /* add debug sections */
- tcc_debug_new(s);
- }
-
-#if TCC_EH_FRAME
- if (s->output_format != TCC_OUTPUT_FORMAT_ELF)
- s->unwind_tables = 0;
- tcc_eh_frame_start(s);
-#endif
-
-#ifdef CONFIG_TCC_BCHECK
- if (s->do_bounds_check) {
- /* if bound checking, then add corresponding sections */
- /* (make ro after relocation done with GNU_RELRO) */
- bounds_section = new_section(s, ".bounds", SHT_PROGBITS, shf_RELRO);
- lbounds_section = new_section(s, ".lbounds", SHT_PROGBITS, shf_RELRO);
- }
-#endif
-
#ifdef TCC_TARGET_PE
/* to make sure that -ltcc1 -Wl,-e,_start will grab the startup code
from libtcc1.a (unless _start defined) */
@@ -158,10 +139,6 @@ ST_FUNC void tccelf_begin_file(TCCState *s1)
}
/* disable symbol hashing during compilation */
s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
-#if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
- s1->uw_sym = 0;
- s1->uw_offs = 0;
-#endif
}
static void update_relocs(TCCState *s1, Section *s, int *old_to_new_syms, int first_sym);
@@ -520,7 +497,7 @@ ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc)
}
/* return elf symbol value */
-LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
+void *tcc_get_symbol(TCCState *s, const char *name)
{
addr_t addr = get_sym_addr(s, name, 0, 1);
return addr == -1 ? NULL : (void*)(uintptr_t)addr;
@@ -551,7 +528,7 @@ ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
}
/* list elf symbol names and values */
-LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
+void tcc_list_symbols(TCCState *s, void *ctx,
void (*symbol_cb)(void *ctx, const char *name, const void *val))
{
list_elf_symbols(s, ctx, symbol_cb);
@@ -1056,25 +1033,6 @@ ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
name = (char *) s1->symtab->link->data + sym->st_name;
/* Use ld.so to resolve symbol for us (for tcc -run) */
if (do_resolve) {
-#if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
- /* dlsym() needs the undecorated name. */
- void *addr = dlsym(RTLD_DEFAULT, &name[s1->leading_underscore]);
-#if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD || TARGETOS_ANDROID
- if (addr == NULL) {
- int i;
- for (i = 0; i < s1->nb_loaded_dlls; i++)
- if ((addr = dlsym(s1->loaded_dlls[i]->handle, name)))
- break;
- }
-#endif
- if (addr) {
- sym->st_value = (addr_t) addr;
-#ifdef DEBUG_RELOC
- printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
-#endif
- goto found;
- }
-#endif
/* if dynamic symbol exist, it will be used in relocate_section */
} else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
goto found;
@@ -1107,7 +1065,6 @@ static void relocate_section(TCCState *s1, Section *s, Section *sr)
int type, sym_index;
unsigned char *ptr;
addr_t tgt, addr;
- int is_dwarf = s->sh_num >= s1->dwlo && s->sh_num < s1->dwhi;
qrel = (ElfW_Rel *)sr->data;
for_each_elem(sr, 0, rel, ElfW_Rel) {
@@ -1119,12 +1076,6 @@ static void relocate_section(TCCState *s1, Section *s, Section *sr)
#if SHT_RELX == SHT_RELA
tgt += rel->r_addend;
#endif
- if (is_dwarf && type == R_DATA_32DW
- && sym->st_shndx >= s1->dwlo && sym->st_shndx < s1->dwhi) {
- /* dwarf section relocation to each other */
- add32le(ptr, tgt - s1->sections[sym->st_shndx]->sh_addr);
- continue;
- }
addr = s->sh_addr + rel->r_offset;
relocate(s1, rel, type, ptr, addr, tgt);
}
@@ -1132,17 +1083,6 @@ static void relocate_section(TCCState *s1, Section *s, Section *sr)
/* if the relocation is allocated, we change its symbol table */
if (sr->sh_flags & SHF_ALLOC) {
sr->link = s1->dynsym;
- if (s1->output_type & TCC_OUTPUT_DYN) {
- size_t r = (uint8_t*)qrel - sr->data;
- if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
- && 0 == strcmp(s->name, ".stab"))
- r = 0; /* cannot apply 64bit relocation to 32bit value */
- sr->data_offset = sr->sh_size = r;
-#ifdef CONFIG_TCC_PIE
- if (r && (s->sh_flags & SHF_EXECINSTR))
- tcc_warning("%d relocations to %s", (unsigned)(r / sizeof *qrel), s->name);
-#endif
- }
}
#endif
}
@@ -1158,11 +1098,9 @@ ST_FUNC void relocate_sections(TCCState *s1)
if (sr->sh_type != SHT_RELX)
continue;
s = s1->sections[sr->sh_info];
-#ifndef TCC_TARGET_MACHO
if (s != s1->got
|| s1->static_link
|| s1->output_type == TCC_OUTPUT_MEMORY)
-#endif
{
relocate_section(s1, s, sr);
}
@@ -1183,15 +1121,13 @@ ST_FUNC void relocate_sections(TCCState *s1)
static int prepare_dynamic_rel(TCCState *s1, Section *sr)
{
int count = 0;
-#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
- defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
- defined(TCC_TARGET_RISCV64)
+
ElfW_Rel *rel;
for_each_elem(sr, 0, rel, ElfW_Rel) {
int sym_index = ELFW(R_SYM)(rel->r_info);
int type = ELFW(R_TYPE)(rel->r_info);
switch(type) {
-#if defined(TCC_TARGET_I386)
+
case R_386_32:
if (!get_sym_attr(s1, sym_index, 0)->dyn_index
&& ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
@@ -1199,42 +1135,9 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr)
rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
break;
}
-#elif defined(TCC_TARGET_X86_64)
- case R_X86_64_32:
- case R_X86_64_32S:
- case R_X86_64_64:
-#elif defined(TCC_TARGET_ARM)
- case R_ARM_ABS32:
- case R_ARM_TARGET1:
-#elif defined(TCC_TARGET_ARM64)
- case R_AARCH64_ABS32:
- case R_AARCH64_ABS64:
-#elif defined(TCC_TARGET_RISCV64)
- case R_RISCV_32:
- case R_RISCV_64:
-#endif
count++;
break;
-#if defined(TCC_TARGET_I386)
case R_386_PC32:
-#elif defined(TCC_TARGET_X86_64)
- case R_X86_64_PC32:
- {
- ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
- /* Hidden defined symbols can and must be resolved locally.
- We're misusing a PLT32 reloc for this, as that's always
- resolved to its address even in shared libs. */
- if (sym->st_shndx != SHN_UNDEF &&
- ELFW(ST_VISIBILITY)(sym->st_other) == STV_HIDDEN) {
- rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PLT32);
- break;
- }
- }
-#elif defined(TCC_TARGET_ARM64)
- case R_AARCH64_PREL32:
-#endif
- if (s1->output_type != TCC_OUTPUT_DLL)
- break;
if (get_sym_attr(s1, sym_index, 0)->dyn_index)
count++;
break;
@@ -1242,7 +1145,7 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr)
break;
}
}
-#endif
+
return count;
}
#endif
@@ -1399,9 +1302,7 @@ redo:
if (sym->st_shndx == SHN_UNDEF) {
ElfW(Sym) *esym;
int dynindex;
- if (!PCRELATIVE_DLLPLT
- && (s1->output_type & TCC_OUTPUT_DYN))
- continue;
+
/* Relocations for UNDEF symbols would normally need
to be transferred into the executable or shared object.
If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
@@ -1425,28 +1326,14 @@ redo:
} else if (sym->st_shndx == SHN_ABS) {
if (sym->st_value == 0) /* from tcc_add_btstub() */
continue;
-#ifndef TCC_TARGET_ARM
if (PTR_SIZE != 8)
continue;
-#endif
/* from tcc_add_symbol(): on 64 bit platforms these
need to go through .got */
} else
continue;
}
-#ifdef TCC_TARGET_X86_64
- if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
- sym->st_shndx != SHN_UNDEF &&
- (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
- ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
- s1->output_type & TCC_OUTPUT_EXE)) {
- if (pass != 0)
- continue;
- rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
- continue;
- }
-#endif
reloc_type = code_reloc(type);
if (reloc_type == -1) {
tcc_error_noabort ("Unknown relocation type: %d", type);
@@ -1523,15 +1410,6 @@ ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
section_ptr_add(s, PTR_SIZE);
}
-#ifdef CONFIG_TCC_BCHECK
-ST_FUNC void tcc_add_bcheck(TCCState *s1)
-{
- if (0 == s1->do_bounds_check)
- return;
- section_ptr_add(bounds_section, sizeof(addr_t));
-}
-#endif
-
/* set symbol to STB_LOCAL and resolve. The point is to not export it as
a dynamic symbol to allow so's to have one each with a different value. */
static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
@@ -1548,209 +1426,23 @@ static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset
/* avoid generating debug/test_coverage code for stub functions */
static void tcc_compile_string_no_debug(TCCState *s, const char *str)
{
- int save_do_debug = s->do_debug;
- int save_test_coverage = s->test_coverage;
-
- s->do_debug = 0;
- s->test_coverage = 0;
tcc_compile_string(s, str);
- s->do_debug = save_do_debug;
- s->test_coverage = save_test_coverage;
}
-#ifdef CONFIG_TCC_BACKTRACE
-static void put_ptr(TCCState *s1, Section *s, int offs)
-{
- int c;
- c = set_global_sym(s1, NULL, s, offs);
- s = data_section;
- put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
- section_ptr_add(s, PTR_SIZE);
-}
-ST_FUNC void tcc_add_btstub(TCCState *s1)
-{
- Section *s;
- int n, o, *p;
- CString cstr;
- const char *__rt_info = &"___rt_info"[!s1->leading_underscore];
-
- s = data_section;
- /* Align to PTR_SIZE */
- section_ptr_add(s, -s->data_offset & (PTR_SIZE - 1));
- o = s->data_offset;
- /* create a struct rt_context (see tccrun.c) */
- if (s1->dwarf) {
- put_ptr(s1, dwarf_line_section, 0);
- put_ptr(s1, dwarf_line_section, -1);
- if (s1->dwarf >= 5)
- put_ptr(s1, dwarf_line_str_section, 0);
- else
- put_ptr(s1, dwarf_str_section, 0);
- }
- else
- {
- put_ptr(s1, stab_section, 0);
- put_ptr(s1, stab_section, -1);
- put_ptr(s1, stab_section->link, 0);
- }
-
- /* skip esym_start/esym_end/elf_str (not loaded) */
- section_ptr_add(s, 3 * PTR_SIZE);
-
- if (s1->output_type == TCC_OUTPUT_MEMORY && 0 == s1->dwarf) {
- put_ptr(s1, text_section, 0);
- } else {
- /* prog_base : local nameless symbol with offset 0 at SHN_ABS */
- put_ptr(s1, NULL, 0);
-#if defined TCC_TARGET_MACHO
- /* adjust for __PAGEZERO */
- if (s1->dwarf == 0 && s1->output_type == TCC_OUTPUT_EXE)
- write64le(data_section->data + data_section->data_offset - PTR_SIZE,
- (uint64_t)1 << 32);
-#endif
- }
- n = 3 * PTR_SIZE;
-#ifdef CONFIG_TCC_BCHECK
- if (s1->do_bounds_check) {
- put_ptr(s1, bounds_section, 0);
- n -= PTR_SIZE;
- }
-#endif
- section_ptr_add(s, n);
- p = section_ptr_add(s, 2 * sizeof (int));
- p[0] = s1->rt_num_callers;
- p[1] = s1->dwarf;
- // if (s->data_offset - o != 10*PTR_SIZE + 2*sizeof (int)) exit(99);
-
- if (s1->output_type == TCC_OUTPUT_MEMORY) {
- set_global_sym(s1, __rt_info, s, o);
- return;
- }
-
- cstr_new(&cstr);
- cstr_printf(&cstr,
- "extern void __bt_init(),__bt_exit(),__bt_init_dll();"
- "static void *__rt_info[];"
- "__attribute__((constructor)) static void __bt_init_rt(){");
-#ifdef TCC_TARGET_PE
- if (s1->output_type == TCC_OUTPUT_DLL)
-#ifdef CONFIG_TCC_BCHECK
- cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
-#else
- cstr_printf(&cstr, "__bt_init_dll(0);");
-#endif
-#endif
- cstr_printf(&cstr, "__bt_init(__rt_info,%d);}",
- s1->output_type != TCC_OUTPUT_DLL);
- /* In case dlcose is called by application */
- cstr_printf(&cstr,
- "__attribute__((destructor)) static void __bt_exit_rt(){"
- "__bt_exit(__rt_info);}");
- tcc_compile_string_no_debug(s1, cstr.data);
- cstr_free(&cstr);
- set_local_sym(s1, __rt_info, s, o);
-}
-#endif /* def CONFIG_TCC_BACKTRACE */
-
-static void tcc_tcov_add_file(TCCState *s1, const char *filename)
-{
- CString cstr;
- void *ptr;
- char wd[1024];
-
- if (tcov_section == NULL)
- return;
- section_ptr_add(tcov_section, 1);
- write32le (tcov_section->data, tcov_section->data_offset);
-
- cstr_new (&cstr);
- if (filename[0] == '/')
- cstr_printf (&cstr, "%s.tcov", filename);
- else {
- getcwd (wd, sizeof(wd));
- cstr_printf (&cstr, "%s/%s.tcov", wd, filename);
- }
- ptr = section_ptr_add(tcov_section, cstr.size + 1);
- strcpy((char *)ptr, cstr.data);
- unlink((char *)ptr);
-#ifdef _WIN32
- normalize_slashes((char *)ptr);
-#endif
- cstr_free (&cstr);
-
- cstr_new(&cstr);
- cstr_printf(&cstr,
- "extern char *__tcov_data[];"
- "extern void __store_test_coverage ();"
- "__attribute__((destructor)) static void __tcov_exit() {"
- "__store_test_coverage(__tcov_data);"
- "}");
- tcc_compile_string_no_debug(s1, cstr.data);
- cstr_free(&cstr);
- set_local_sym(s1, &"___tcov_data"[!s1->leading_underscore], tcov_section, 0);
-}
-
-#if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO
+#if !defined TCC_TARGET_PE
/* add libc crt1/crti objects */
ST_FUNC void tccelf_add_crtbegin(TCCState *s1)
{
-#if TARGETOS_OpenBSD
- if (s1->output_type != TCC_OUTPUT_DLL)
- tcc_add_crt(s1, "crt0.o");
- if (s1->output_type == TCC_OUTPUT_DLL)
- tcc_add_crt(s1, "crtbeginS.o");
- else
- tcc_add_crt(s1, "crtbegin.o");
-#elif TARGETOS_FreeBSD || TARGETOS_NetBSD
- if (s1->output_type != TCC_OUTPUT_DLL)
-#if TARGETOS_FreeBSD
- tcc_add_crt(s1, "crt1.o");
-#else
- tcc_add_crt(s1, "crt0.o");
-#endif
+ tcc_add_crt(s1, "crt1.o");
tcc_add_crt(s1, "crti.o");
- if (s1->static_link)
- tcc_add_crt(s1, "crtbeginT.o");
- else if (s1->output_type == TCC_OUTPUT_DLL)
- tcc_add_crt(s1, "crtbeginS.o");
- else
- tcc_add_crt(s1, "crtbegin.o");
-#elif TARGETOS_ANDROID
- if (s1->output_type == TCC_OUTPUT_DLL)
- tcc_add_crt(s1, "crtbegin_so.o");
- else
- tcc_add_crt(s1, "crtbegin_dynamic.o");
-#else
- if (s1->output_type != TCC_OUTPUT_DLL)
- tcc_add_crt(s1, "crt1.o");
- tcc_add_crt(s1, "crti.o");
-#endif
}
ST_FUNC void tccelf_add_crtend(TCCState *s1)
{
-#if TARGETOS_OpenBSD
- if (s1->output_type == TCC_OUTPUT_DLL)
- tcc_add_crt(s1, "crtendS.o");
- else
- tcc_add_crt(s1, "crtend.o");
-#elif TARGETOS_FreeBSD || TARGETOS_NetBSD
- if (s1->output_type == TCC_OUTPUT_DLL)
- tcc_add_crt(s1, "crtendS.o");
- else
- tcc_add_crt(s1, "crtend.o");
tcc_add_crt(s1, "crtn.o");
-#elif TARGETOS_ANDROID
- if (s1->output_type == TCC_OUTPUT_DLL)
- tcc_add_crt(s1, "crtend_so.o");
- else
- tcc_add_crt(s1, "crtend_android.o");
-#else
- tcc_add_crt(s1, "crtn.o");
-#endif
}
-#endif /* !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO */
+#endif /* !defined TCC_TARGET_PE */
#ifndef TCC_TARGET_PE
/* add tcc runtime libraries */
@@ -1758,34 +1450,12 @@ ST_FUNC void tcc_add_runtime(TCCState *s1)
{
s1->filetype = 0;
-#ifdef CONFIG_TCC_BCHECK
- tcc_add_bcheck(s1);
-#endif
tcc_add_pragma_libs(s1);
/* add libc */
if (!s1->nostdlib) {
int lpthread = s1->option_pthread;
-#ifdef CONFIG_TCC_BCHECK
- if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
- tcc_add_support(s1, "bcheck.o");
-# if !(TARGETOS_OpenBSD || TARGETOS_NetBSD)
- tcc_add_library(s1, "dl");
-# endif
- lpthread = 1;
- }
-#endif
-#ifdef CONFIG_TCC_BACKTRACE
- if (s1->do_backtrace) {
- if (s1->output_type & TCC_OUTPUT_EXE)
- tcc_add_support(s1, "bt-exe.o");
- if (s1->output_type != TCC_OUTPUT_DLL)
- tcc_add_support(s1, "bt-log.o");
- tcc_add_btstub(s1);
- lpthread = 1;
- }
-#endif
if (lpthread)
tcc_add_library(s1, "pthread");
tcc_add_library(s1, "c");
@@ -1797,15 +1467,11 @@ ST_FUNC void tcc_add_runtime(TCCState *s1)
tcc_add_dll(s1, TCC_LIBGCC, AFF_PRINT_ERROR);
}
#endif
-#if defined TCC_TARGET_ARM && TARGETOS_FreeBSD
- tcc_add_library(s1, "gcc_s"); // unwind code
-#endif
+
if (TCC_LIBTCC1[0])
tcc_add_support(s1, TCC_LIBTCC1);
-#ifndef TCC_TARGET_MACHO
if (s1->output_type != TCC_OUTPUT_MEMORY)
tccelf_add_crtend(s1);
-#endif
}
}
#endif /* ndef TCC_TARGET_PE */
@@ -1822,13 +1488,7 @@ static void tcc_add_linker_symbols(TCCState *s1)
set_global_sym(s1, "_etext", text_section, -1);
set_global_sym(s1, "_edata", data_section, -1);
set_global_sym(s1, "_end", bss_section, -1);
-#if TARGETOS_OpenBSD
- set_global_sym(s1, "__executable_start", NULL, ELF_START_ADDR);
-#endif
-#ifdef TCC_TARGET_RISCV64
- /* XXX should be .sdata+0x800, not .data+0x800 */
- set_global_sym(s1, "__global_pointer$", data_section, 0x800);
-#endif
+
/* horrible new standard ldscript defines */
add_init_array_defines(s1, ".preinit_array");
add_init_array_defines(s1, ".init_array");
@@ -2097,33 +1757,10 @@ static int set_sec_sizes(TCCState *s1)
if (s->sh_type == SHT_RELX && !(s->sh_flags & SHF_ALLOC)) {
/* when generating a DLL, we include relocations but
we may patch them */
- if ((file_type & TCC_OUTPUT_DYN)
- && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) {
- int count = prepare_dynamic_rel(s1, s);
- if (count) {
- /* allocate the section */
- s->sh_flags |= SHF_ALLOC;
- s->sh_size = count * sizeof(ElfW_Rel);
- if (s1->sections[s->sh_info]->sh_flags & SHF_EXECINSTR)
- textrel += count;
- }
- }
- } else if ((s->sh_flags & SHF_ALLOC)
-#ifdef TCC_TARGET_ARM
- || s->sh_type == SHT_ARM_ATTRIBUTES
-#endif
- || s1->do_debug) {
+ } else if ((s->sh_flags & SHF_ALLOC)) {
s->sh_size = s->data_offset;
}
-#ifdef TCC_TARGET_ARM
- /* XXX: Suppress stack unwinding section. */
- if (s->sh_type == SHT_ARM_EXIDX) {
- s->sh_flags = 0;
- s->sh_size = 0;
- }
-#endif
-
}
return textrel;
}
@@ -2313,8 +1950,6 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
s_align = s1->section_align;
addr = ELF_START_ADDR;
- if (s1->output_type & TCC_OUTPUT_DYN)
- addr = 0;
if (s1->has_text_addr) {
addr = s1->text_addr;
@@ -2509,8 +2144,6 @@ static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
if (s && s->data_offset) {
put_dt(dynamic, DT_FINI, s->sh_addr);
}
- if (s1->do_debug)
- put_dt(dynamic, DT_DEBUG, 0);
put_dt(dynamic, DT_NULL, 0);
}
@@ -2574,26 +2207,10 @@ static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr)
ehdr.e_ident[5] = ELFDATA2LSB;
ehdr.e_ident[6] = EV_CURRENT;
-#if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
- ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
-#elif defined TCC_TARGET_ARM && defined TCC_ARM_EABI
- ehdr.e_flags = EF_ARM_EABI_VER5;
- ehdr.e_flags |= s1->float_abi == ARM_HARD_FLOAT
- ? EF_ARM_VFP_FLOAT : EF_ARM_SOFT_FLOAT;
-#elif defined TCC_TARGET_ARM
- ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
-#elif defined TCC_TARGET_RISCV64
- /* XXX should be configurable */
- ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
-#endif
-
if (file_type == TCC_OUTPUT_OBJ) {
ehdr.e_type = ET_REL;
} else {
- if (file_type & TCC_OUTPUT_DYN)
- ehdr.e_type = ET_DYN;
- else
- ehdr.e_type = ET_EXEC;
+ ehdr.e_type = ET_EXEC;
if (s1->elf_entryname)
ehdr.e_entry = get_sym_addr(s1, s1->elf_entryname, 1, 0);
else
@@ -2752,63 +2369,6 @@ static void reorder_sections(TCCState *s1, int *sec_order)
tcc_free(backmap);
}
-#ifdef TCC_TARGET_ARM
-static void create_arm_attribute_section(TCCState *s1)
-{
- // Needed for DLL support.
- static const unsigned char arm_attr[] = {
- 0x41, // 'A'
- 0x2c, 0x00, 0x00, 0x00, // size 0x2c
- 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
- 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
- 0x05, 0x36, 0x00, // 'CPU_name', "6"
- 0x06, 0x06, // 'CPU_arch', 'v6'
- 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
- 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
- 0x0a, 0x02, // 'FP_arch', 'VFPv2'
- 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
- 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
- 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
- 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
- 0x18, 0x01, // 'ABI_align_needed', '8-byte'
- 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
- 0x1a, 0x02, // 'ABI_enum_size', 'int'
- 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
- 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
- };
- Section *attr = new_section(s1, ".ARM.attributes", SHT_ARM_ATTRIBUTES, 0);
- unsigned char *ptr = section_ptr_add(attr, sizeof(arm_attr));
- attr->sh_addralign = 1;
- memcpy(ptr, arm_attr, sizeof(arm_attr));
- if (s1->float_abi != ARM_HARD_FLOAT) {
- ptr[26] = 0x00; // 'FP_arch', 'No'
- ptr[41] = 0x1e; // 'ABI_optimization_goals'
- ptr[42] = 0x06; // 'Aggressive Debug'
- }
-}
-#endif
-
-#if TARGETOS_OpenBSD || TARGETOS_NetBSD
-static Section *create_bsd_note_section(TCCState *s1,
- const char *name,
- const char *value)
-{
- Section *s = find_section (s1, name);
-
- if (s->data_offset == 0) {
- char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
- ElfW(Nhdr) *note = (ElfW(Nhdr) *) ptr;
-
- s->sh_type = SHT_NOTE;
- note->n_namesz = 8;
- note->n_descsz = 4;
- note->n_type = ELF_NOTE_OS_GNU;
- strcpy (ptr + sizeof(ElfW(Nhdr)), value);
- }
- return s;
-}
-#endif
-
static void alloc_sec_names(TCCState *s1, int is_obj);
/* Output an elf, coff or binary file */
@@ -2827,21 +2387,6 @@ static int elf_output_file(TCCState *s1, const char *filename)
sec_order = NULL;
dyninf.roinf = &dyninf._roinf;
-#ifdef TCC_TARGET_ARM
- create_arm_attribute_section (s1);
-#endif
-
-#if TARGETOS_OpenBSD
- dyninf.note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD");
-#endif
-
-#if TARGETOS_NetBSD
- dyninf.note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD");
-#endif
-
-#if TARGETOS_FreeBSD || TARGETOS_NetBSD
- dyninf.roinf = NULL;
-#endif
/* if linking, also link in runtime libraries (libc, libgcc, etc.) */
tcc_add_runtime(s1);
resolve_common_syms(s1);
@@ -2876,7 +2421,6 @@ static int elf_output_file(TCCState *s1, const char *filename)
got_sym = build_got(s1);
if (file_type & TCC_OUTPUT_EXE) {
- bind_exe_dynsyms(s1, file_type & TCC_OUTPUT_DYN);
if (s1->nb_errors)
goto the_end;
}
@@ -2887,10 +2431,6 @@ static int elf_output_file(TCCState *s1, const char *filename)
/* shared library case: simply export all global symbols */
export_global_syms(s1);
}
-#if TCC_EH_FRAME
- /* fill with initial data */
- tcc_eh_frame_hdr(s1, 0);
-#endif
dyninf.gnu_hash = create_gnu_hash(s1);
} else {
build_got_entries(s1, 0);
@@ -2912,16 +2452,6 @@ static int elf_output_file(TCCState *s1, const char *filename)
put_elf_str(dynstr, s1->rpath));
dt_flags_1 = DF_1_NOW;
- if (file_type & TCC_OUTPUT_DYN) {
- if (s1->soname)
- put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
- /* XXX: currently, since we do not handle PIC code, we
- must relocate the readonly segments */
- if (textrel)
- put_dt(dynamic, DT_TEXTREL, 0);
- if (file_type & TCC_OUTPUT_EXE)
- dt_flags_1 = DF_1_NOW | DF_1_PIE;
- }
put_dt(dynamic, DT_FLAGS, DF_BIND_NOW);
put_dt(dynamic, DT_FLAGS_1, dt_flags_1);
if (s1->symbolic)
@@ -2946,8 +2476,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
if (dynamic) {
/* put in GOT the dynamic section address and relocate PLT */
write32le(s1->got->data, dynamic->sh_addr);
- if (file_type == TCC_OUTPUT_EXE
- || (RELOCATE_DLLPLT && (file_type & TCC_OUTPUT_DYN)))
+ if (file_type == TCC_OUTPUT_EXE)
relocate_plt(s1);
/* relocate symbols in .dynsym now that final addresses are known */
relocate_syms(s1, s1->dynsym, 2);
@@ -2974,10 +2503,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
update_gnu_hash(s1, dyninf.gnu_hash);
reorder_sections(s1, sec_order);
-#if TCC_EH_FRAME
- /* fill with final data */
- tcc_eh_frame_hdr(s1, 1);
-#endif
+
/* Create the ELF file with name 'filename' */
ret = tcc_write_elf_file(s1, filename, dyninf.phnum, dyninf.phdr);
the_end:
@@ -3027,16 +2553,12 @@ static int elf_output_obj(TCCState *s1, const char *filename)
return ret;
}
-LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
+int tcc_output_file(TCCState *s, const char *filename)
{
- if (s->test_coverage)
- tcc_tcov_add_file(s, filename);
if (s->output_type == TCC_OUTPUT_OBJ)
return elf_output_obj(s, filename);
#ifdef TCC_TARGET_PE
return pe_output_file(s, filename);
-#elif defined TCC_TARGET_MACHO
- return macho_output_file(s, filename);
#else
return elf_output_file(s, filename);
#endif
@@ -3082,10 +2604,8 @@ ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
} else if (size >= 8) {
if (0 == memcmp(h, ARMAG, 8))
return AFF_BINTYPE_AR;
-#ifdef TCC_TARGET_COFF
- if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
- return AFF_BINTYPE_C67;
-#endif
+ else if (((FILHDR *)h)->f_magic == F_MACH_I386)
+ return (AFF_BINTYPE_COFF);
}
return 0;
}
@@ -3167,7 +2687,7 @@ invalid:
sh_name = strsec + sh->sh_name;
if (0 == strncmp(sh_name, ".debug_", 7)
|| 0 == strncmp(sh_name, ".stab", 5)) {
- if (!s1->do_debug || seencompressed)
+ if (seencompressed)
continue;
} else
if (sh->sh_type != SHT_PROGBITS &&
@@ -3202,12 +2722,6 @@ invalid:
sm_table[i].link_once = 1;
goto next;
}
- if (stab_section) {
- if (s == stab_section)
- stab_index = i;
- if (s == stab_section->link)
- stabstr_index = i;
- }
goto found;
}
/* not found: create new section */
@@ -3335,12 +2849,6 @@ invalid:
sym_index = old_to_new_syms[sym_index];
/* ignore link_once in rel section. */
if (!sym_index && !sm_table[sh->sh_info].link_once
-#ifdef TCC_TARGET_ARM
- && type != R_ARM_V4BX
-#elif defined TCC_TARGET_RISCV64
- && type != R_RISCV_ALIGN
- && type != R_RISCV_RELAX
-#endif
) {
invalid_reloc:
tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
@@ -3350,18 +2858,6 @@ invalid:
rel->r_info = ELFW(R_INFO)(sym_index, type);
/* offset the relocation offset */
rel->r_offset += offseti;
-#ifdef TCC_TARGET_ARM
- /* Jumps and branches from a Thumb code to a PLT entry need
- special handling since PLT entries are ARM code.
- Unconditional bl instructions referencing PLT entries are
- handled by converting these instructions into blx
- instructions. Other case of instructions referencing a PLT
- entry require to add a Thumb stub before the PLT entry to
- switch to ARM mode. We set bit plt_thumb_stub of the
- attribute of a symbol to indicate such a case. */
- if (type == R_ARM_THM_JUMP24)
- get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
-#endif
}
break;
default:
diff --git a/tccgen.c b/libtcc/tccgen.c
similarity index 94%
rename from tccgen.c
rename to libtcc/tccgen.c
index b7d35ba7..1606b3c4 100644
--- a/tccgen.c
+++ b/libtcc/tccgen.c
@@ -20,6 +20,7 @@
#define USING_GLOBALS
#include "tcc.h"
+#include "utils/string.h"
/********************************************************/
/* global variables */
@@ -43,7 +44,6 @@ static int nb_sym_pools;
static Sym *all_cleanups, *pending_gotos;
static int local_scope;
-ST_DATA char debug_modes;
ST_DATA SValue *vtop;
static SValue _vstack[1 + VSTACK_SIZE];
@@ -176,8 +176,6 @@ static int gind()
{
int t = ind;
CODE_ON();
- if (debug_modes)
- tcc_tcov_block_begin(tcc_state);
return t;
}
@@ -233,13 +231,6 @@ static int R_RET(int t)
{
if (!is_float(t))
return REG_IRET;
-#ifdef TCC_TARGET_X86_64
- if ((t & VT_BTYPE) == VT_LDOUBLE)
- return TREG_ST0;
-#elif defined TCC_TARGET_RISCV64
- if ((t & VT_BTYPE) == VT_LDOUBLE)
- return REG_IRET;
-#endif
return REG_FRET;
}
@@ -250,14 +241,6 @@ static int R2_RET(int t)
#if PTR_SIZE == 4
if (t == VT_LLONG)
return REG_IRE2;
-#elif defined TCC_TARGET_X86_64
- if (t == VT_QLONG)
- return REG_IRE2;
- if (t == VT_QFLOAT)
- return REG_FRE2;
-#elif defined TCC_TARGET_RISCV64
- if (t == VT_LDOUBLE)
- return REG_IRE2;
#endif
return VT_CONST;
}
@@ -282,15 +265,6 @@ static int RC_TYPE(int t)
{
if (!is_float(t))
return RC_INT;
-#ifdef TCC_TARGET_X86_64
- if ((t & VT_BTYPE) == VT_LDOUBLE)
- return RC_ST0;
- if ((t & VT_BTYPE) == VT_QFLOAT)
- return RC_FRET;
-#elif defined TCC_TARGET_RISCV64
- if ((t & VT_BTYPE) == VT_LDOUBLE)
- return RC_INT;
-#endif
return RC_FLOAT;
}
@@ -323,10 +297,7 @@ ST_FUNC int ieee_finite(double d)
}
/* compiling intel long double natively */
-#if (defined __i386__ || defined __x86_64__) \
- && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
# define TCC_IS_NATIVE_387
-#endif
ST_FUNC void test_lvalue(void)
{
@@ -386,13 +357,7 @@ ST_FUNC int tccgen_compile(TCCState *s1)
func_ind = -1;
anon_sym = SYM_FIRST_ANOM;
nocode_wanted = DATA_ONLY_WANTED; /* no code outside of functions */
- debug_modes = (s1->do_debug ? 1 : 0) | s1->test_coverage << 1;
- tcc_debug_start(s1);
- tcc_tcov_start (s1);
-#ifdef TCC_TARGET_ARM
- arm_init(s1);
-#endif
#ifdef INC_DEBUG
printf("%s: **** new file\n", file->filename);
#endif
@@ -402,17 +367,12 @@ ST_FUNC int tccgen_compile(TCCState *s1)
gen_inline_functions(s1);
check_vstack();
/* end of translation unit info */
-#if TCC_EH_FRAME
- tcc_eh_frame_end(s1);
-#endif
- tcc_debug_end(s1);
- tcc_tcov_end(s1);
+
return 0;
}
ST_FUNC void tccgen_finish(TCCState *s1)
{
- tcc_debug_end(s1); /* just in case of errors: free memory */
free_inline_functions(s1);
sym_pop(&global_stack, NULL, 0);
sym_pop(&local_stack, NULL, 0);
@@ -546,9 +506,6 @@ ST_FUNC void put_extern_sym2(Sym *sym, int sh_num,
info = ELFW(ST_INFO)(sym_bind, sym_type);
sym->c = put_elf_sym(symtab_section, value, size, info, other, sh_num, name);
- if (debug_modes)
- tcc_debug_extern_sym(tcc_state, sym, sh_num, sym_bind, sym_type);
-
} else {
esym = elfsym(sym);
esym->st_value = value;
@@ -882,13 +839,10 @@ ST_FUNC void vpop(void)
{
int v;
v = vtop->r & VT_VALMASK;
-#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
/* for x86, we need to pop the FP stack */
if (v == TREG_ST0) {
o(0xd8dd); /* fstp %st(0) */
- } else
-#endif
- if (v == VT_CMP) {
+ } else if (v == VT_CMP) {
/* need to put correct jump if && or || without test */
gsym(vtop->jtrue);
gsym(vtop->jfalse);
@@ -1375,12 +1329,10 @@ ST_FUNC void save_reg_upstack(int r, int n)
sv.r = VT_LOCAL | VT_LVAL;
sv.c.i = l;
store(p->r & VT_VALMASK, &sv);
-#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
/* x86 specific: need to pop fp register ST0 if saved */
if (r == TREG_ST0) {
o(0xd8dd); /* fstp %st(0) */
}
-#endif
/* special long long case */
if (p->r2 < VT_CONST && USING_TWO_WORDS(bt)) {
sv.c.i += PTR_SIZE;
@@ -1404,31 +1356,6 @@ ST_FUNC void save_reg_upstack(int r, int n)
}
}
-#ifdef TCC_TARGET_ARM
-/* find a register of class 'rc2' with at most one reference on stack.
- * If none, call get_reg(rc) */
-ST_FUNC int get_reg_ex(int rc, int rc2)
-{
- int r;
- SValue *p;
-
- for(r=0;rr & VT_VALMASK) == r ||
- p->r2 == r)
- n++;
- }
- if (n <= 1)
- return r;
- }
- }
- return get_reg(rc);
-}
-#endif
-
/* find a free register of class 'rc'. If none, save one register */
ST_FUNC int get_reg(int rc)
{
@@ -1536,155 +1463,9 @@ ST_FUNC void gaddrof(void)
vtop->r = (vtop->r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL;
}
-#ifdef CONFIG_TCC_BCHECK
-/* generate a bounded pointer addition */
-static void gen_bounded_ptr_add(void)
-{
- int save = (vtop[-1].r & VT_VALMASK) == VT_LOCAL;
- if (save) {
- vpushv(&vtop[-1]);
- vrott(3);
- }
- vpush_helper_func(TOK___bound_ptr_add);
- vrott(3);
- gfunc_call(2);
- vtop -= save;
- vpushi(0);
- /* returned pointer is in REG_IRET */
- vtop->r = REG_IRET | VT_BOUNDED;
- if (nocode_wanted)
- return;
- /* relocation offset of the bounding function call point */
- vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(ElfW_Rel));
-}
-
-/* patch pointer addition in vtop so that pointer dereferencing is
- also tested */
-static void gen_bounded_ptr_deref(void)
-{
- addr_t func;
- int size, align;
- ElfW_Rel *rel;
- Sym *sym;
-
- if (nocode_wanted)
- return;
-
- size = type_size(&vtop->type, &align);
- switch(size) {
- case 1: func = TOK___bound_ptr_indir1; break;
- case 2: func = TOK___bound_ptr_indir2; break;
- case 4: func = TOK___bound_ptr_indir4; break;
- case 8: func = TOK___bound_ptr_indir8; break;
- case 12: func = TOK___bound_ptr_indir12; break;
- case 16: func = TOK___bound_ptr_indir16; break;
- default:
- /* may happen with struct member access */
- return;
- }
- sym = external_helper_sym(func);
- if (!sym->c)
- put_extern_sym(sym, NULL, 0, 0);
- /* patch relocation */
- /* XXX: find a better solution ? */
- rel = (ElfW_Rel *)(cur_text_section->reloc->data + vtop->c.i);
- rel->r_info = ELFW(R_INFO)(sym->c, ELFW(R_TYPE)(rel->r_info));
-}
-
-/* generate lvalue bound code */
-static void gbound(void)
-{
- CType type1;
-
- vtop->r &= ~VT_MUSTBOUND;
- /* if lvalue, then use checking code before dereferencing */
- if (vtop->r & VT_LVAL) {
- /* if not VT_BOUNDED value, then make one */
- if (!(vtop->r & VT_BOUNDED)) {
- /* must save type because we must set it to int to get pointer */
- type1 = vtop->type;
- vtop->type.t = VT_PTR;
- gaddrof();
- vpushi(0);
- gen_bounded_ptr_add();
- vtop->r |= VT_LVAL;
- vtop->type = type1;
- }
- /* then check for dereferencing */
- gen_bounded_ptr_deref();
- }
-}
-
-/* we need to call __bound_ptr_add before we start to load function
- args into registers */
-ST_FUNC void gbound_args(int nb_args)
-{
- int i, v;
- SValue *sv;
-
- for (i = 1; i <= nb_args; ++i)
- if (vtop[1 - i].r & VT_MUSTBOUND) {
- vrotb(i);
- gbound();
- vrott(i);
- }
-
- sv = vtop - nb_args;
- if (sv->r & VT_SYM) {
- v = sv->sym->v;
- if (v == TOK_setjmp
- || v == TOK__setjmp
-#ifndef TCC_TARGET_PE
- || v == TOK_sigsetjmp
- || v == TOK___sigsetjmp
-#endif
- ) {
- vpush_helper_func(TOK___bound_setjmp);
- vpushv(sv + 1);
- gfunc_call(1);
- func_bound_add_epilog = 1;
- }
-#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
- if (v == TOK_alloca)
- func_bound_add_epilog = 1;
-#endif
-#if TARGETOS_NetBSD
- if (v == TOK_longjmp) /* undo rename to __longjmp14 */
- sv->sym->asm_label = TOK___bound_longjmp;
-#endif
- }
-}
-
-/* Add bounds for local symbols from S to E (via ->prev) */
-static void add_local_bounds(Sym *s, Sym *e)
-{
- for (; s != e; s = s->prev) {
- if (!s->v || (s->r & VT_VALMASK) != VT_LOCAL)
- continue;
- /* Add arrays/structs/unions because we always take address */
- if ((s->type.t & VT_ARRAY)
- || (s->type.t & VT_BTYPE) == VT_STRUCT
- || s->a.addrtaken) {
- /* add local bound info */
- int align, size = type_size(&s->type, &align);
- addr_t *bounds_ptr = section_ptr_add(lbounds_section,
- 2 * sizeof(addr_t));
- bounds_ptr[0] = s->c;
- bounds_ptr[1] = size;
- }
- }
-}
-#endif
-
/* Wrapper around sym_pop, that potentially also registers local bounds. */
static void pop_local_syms(Sym *b, int keep)
{
-#ifdef CONFIG_TCC_BCHECK
- if (tcc_state->do_bounds_check && !keep && (local_scope || !func_var))
- add_local_bounds(local_stack, b);
-#endif
- if (debug_modes)
- tcc_add_debug_info (tcc_state, !local_scope, local_stack, b);
sym_pop(&local_stack, b, keep);
}
@@ -1846,18 +1627,9 @@ ST_FUNC int gv(int rc)
init_putv(&p, &vtop->type, offset);
vtop->r |= VT_LVAL;
}
-#ifdef CONFIG_TCC_BCHECK
- if (vtop->r & VT_MUSTBOUND)
- gbound();
-#endif
bt = vtop->type.t & VT_BTYPE;
-#ifdef TCC_TARGET_RISCV64
- /* XXX mega hack */
- if (bt == VT_LDOUBLE && rc == RC_FLOAT)
- rc = RC_INT;
-#endif
rc2 = RC2_TYPE(bt, rc);
/* need to reload if:
@@ -1932,11 +1704,6 @@ ST_FUNC int gv(int rc)
}
}
vtop->r = r;
-#ifdef TCC_TARGET_C67
- /* uses register pairs for doubles */
- if (bt == VT_DOUBLE)
- vtop->r2 = r+1;
-#endif
}
return r;
}
@@ -2066,10 +1833,6 @@ static void gen_opl(int op)
case TOK_UMOD:
func = TOK___umoddi3;
gen_mod_func:
-#ifdef TCC_ARM_EABI
- reg_iret = TREG_R2;
- reg_lret = TREG_R3;
-#endif
gen_func:
/* call generic long long function */
vpush_helper_func(func);
@@ -2445,38 +2208,8 @@ static void gen_opic(int op)
}
}
-#if defined TCC_TARGET_X86_64 || defined TCC_TARGET_I386
-# define gen_negf gen_opf
-#elif defined TCC_TARGET_ARM
-void gen_negf(int op)
-{
- /* arm will detect 0-x and replace by vneg */
- vpushi(0), vswap(), gen_op('-');
-}
-#else
-/* XXX: implement in gen_opf() for other backends too */
-void gen_negf(int op)
-{
- /* In IEEE negate(x) isn't subtract(0,x). Without NaNs it's
- subtract(-0, x), but with them it's really a sign flip
- operation. We implement this with bit manipulation and have
- to do some type reinterpretation for this, which TCC can do
- only via memory. */
+#define gen_negf gen_opf
- int align, size, bt;
-
- size = type_size(&vtop->type, &align);
- bt = vtop->type.t & VT_BTYPE;
- save_reg(gv(RC_TYPE(bt)));
- vdup();
- incr_bf_adr(size - 1);
- vdup();
- vpushi(0x80); /* flip sign */
- gen_op('^');
- vstore();
- vpop();
-}
-#endif
/* generate a floating point operation with constant propagation */
static void gen_opif(int op)
@@ -3037,21 +2770,7 @@ op_err:
type1 = vtop[-1].type;
vpush_type_size(pointed_type(&vtop[-1].type), &align);
gen_op('*');
-#ifdef CONFIG_TCC_BCHECK
- if (tcc_state->do_bounds_check && !CONST_WANTED) {
- /* if bounded pointers, we generate a special code to
- test bounds */
- if (op == '-') {
- vpushi(0);
- vswap();
- gen_op('-');
- }
- gen_bounded_ptr_add();
- } else
-#endif
- {
- gen_opic(op);
- }
+ gen_opic(op);
type1.t &= ~(VT_ARRAY|VT_VLA);
/* put again type if gen_opic() swaped operands */
vtop->type = type1;
@@ -3107,9 +2826,6 @@ op_err:
gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT);
}
-#if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64 || defined TCC_TARGET_ARM
-#define gen_cvt_itof1 gen_cvt_itof
-#else
/* generic itof for unsigned long long case */
static void gen_cvt_itof1(int t)
{
@@ -3132,11 +2848,7 @@ static void gen_cvt_itof1(int t)
gen_cvt_itof(t);
}
}
-#endif
-#if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64
-#define gen_cvt_ftoi1 gen_cvt_ftoi
-#else
/* generic ftoi for unsigned long long case */
static void gen_cvt_ftoi1(int t)
{
@@ -3160,7 +2872,6 @@ static void gen_cvt_ftoi1(int t)
gen_cvt_ftoi(t);
}
}
-#endif
/* special delayed cast for char/short */
static void force_charshort_cast(void)
@@ -3217,7 +2928,7 @@ error:
}
c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
-#if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387
+#if !defined TCC_IS_NATIVE_387
/* don't try to convert to ldouble when cross-compiling
(except when it's '0' which is needed for arm:gen_negf()) */
if (dbt_bt == VT_LDOUBLE && !nocode_wanted && (sf || vtop->c.i != 0))
@@ -3373,13 +3084,7 @@ error:
if (ds == 8) {
/* need to convert from 32bit to 64bit */
if (sbt & VT_UNSIGNED) {
-#if defined(TCC_TARGET_RISCV64)
- /* RISC-V keeps 32bit vals in registers sign-extended.
- So here we need a zero-extension. */
- trunc = 32;
-#else
goto done;
-#endif
} else {
gen_cvt_sxtw();
goto done;
@@ -3389,9 +3094,7 @@ error:
/* RISC-V keeps 32bit vals in registers sign-extended.
So here we need a sign-extension for signed types and
zero-extension. for unsigned types. */
-#if !defined(TCC_TARGET_RISCV64)
trunc = 32; /* zero upper 32 bits for non RISC-V targets */
-#endif
} else {
ss = 4;
}
@@ -3399,12 +3102,10 @@ error:
if (ds >= ss)
goto done;
-#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM64
if (ss == 4) {
gen_cvt_csti(dbt);
goto done;
}
-#endif
bits = (ss - ds) * 8;
/* for unsigned, gen_op will convert SAR to SHR */
vtop->type.t = (ss == 8 ? VT_LLONG : VT_INT) | (dbt & VT_UNSIGNED);
@@ -3451,8 +3152,7 @@ ST_FUNC int type_size(CType *type, int *a)
*a = LDOUBLE_ALIGN;
return LDOUBLE_SIZE;
} else if (bt == VT_DOUBLE || bt == VT_LLONG) {
-#if (defined TCC_TARGET_I386 && !defined TCC_TARGET_PE) \
- || (defined TCC_TARGET_ARM && !defined TCC_ARM_EABI)
+#if (defined TCC_TARGET_I386 && !defined TCC_TARGET_PE)
*a = 4;
#else
*a = 8;
@@ -3632,27 +3332,16 @@ ST_FUNC void vstore(void)
size = type_size(&vtop->type, &align);
/* destination, keep on stack() as result */
vpushv(vtop - 1);
-#ifdef CONFIG_TCC_BCHECK
- if (vtop->r & VT_MUSTBOUND)
- gbound(); /* check would be wrong after gaddrof() */
-#endif
+
vtop->type.t = VT_PTR;
gaddrof();
/* source */
vswap();
-#ifdef CONFIG_TCC_BCHECK
- if (vtop->r & VT_MUSTBOUND)
- gbound();
-#endif
vtop->type.t = VT_PTR;
gaddrof();
#ifdef TCC_TARGET_NATIVE_STRUCT_COPY
- if (1
-#ifdef CONFIG_TCC_BCHECK
- && !tcc_state->do_bounds_check
-#endif
- ) {
+ if (1) {
gen_struct_copy(size);
} else
#endif
@@ -3660,13 +3349,6 @@ ST_FUNC void vstore(void)
/* type size */
vpushi(size);
/* Use memmove, rather than memcpy, as dest and src may be same: */
-#ifdef TCC_ARM_EABI
- if(!(align & 7))
- vpush_helper_func(TOK_memmove8);
- else if(!(align & 3))
- vpush_helper_func(TOK_memmove4);
- else
-#endif
vpush_helper_func(TOK_memmove);
vrott(4);
gfunc_call(3);
@@ -3740,14 +3422,6 @@ ST_FUNC void vstore(void)
gen_cast(&vtop[-1].type);
}
-#ifdef CONFIG_TCC_BCHECK
- /* bound check case */
- if (vtop[-1].r & VT_MUSTBOUND) {
- vswap();
- gbound();
- vswap();
- }
-#endif
gv(RC_TYPE(dbt)); /* generate value */
if (delayed_cast) {
@@ -4283,11 +3957,7 @@ static void struct_layout(CType *type, AttributeDef *ad)
bit_pos = BIT_POS(f->type.t);
size = type_size(&f->type, &align);
- if (bit_pos + bit_size <= size * 8 && f->c + size <= c
-#ifdef TCC_TARGET_ARM
- && !(f->c & (align - 1))
-#endif
- )
+ if (bit_pos + bit_size <= size * 8 && f->c + size <= c)
continue;
/* try to access the field using a different type */
@@ -4313,11 +3983,7 @@ static void struct_layout(CType *type, AttributeDef *ad)
c0 = cx;
}
- if (px + bit_size <= s * 8 && cx + s <= c
-#ifdef TCC_TARGET_ARM
- && !(cx & (align - 1))
-#endif
- ) {
+ if (px + bit_size <= s * 8 && cx + s <= c) {
/* update offset and bit position */
f->c = cx;
bit_pos = px;
@@ -4590,8 +4256,6 @@ do_decl:
check_fields(type, 1);
check_fields(type, 0);
struct_layout(type, &ad);
- if (debug_modes)
- tcc_debug_fix_anon(tcc_state, type);
}
}
}
@@ -4696,13 +4360,6 @@ static int parse_btype(CType *type, AttributeDef *ad, int ignore_label)
}
next();
break;
-#ifdef TCC_TARGET_ARM64
- case TOK_UINT128:
- /* GCC's __uint128_t appears in some Linux header files. Make it a
- synonym for long double to get the size and alignment right. */
- u = VT_LDOUBLE;
- goto basic_type;
-#endif
case TOK_BOOL:
u = VT_BOOL;
goto basic_type;
@@ -5222,11 +4879,6 @@ ST_FUNC void indir(void)
if (!(vtop->type.t & (VT_ARRAY | VT_VLA))
&& (vtop->type.t & VT_BTYPE) != VT_FUNC) {
vtop->r |= VT_LVAL;
- /* if bound checking, the referenced pointer must be checked */
-#ifdef CONFIG_TCC_BCHECK
- if (tcc_state->do_bounds_check)
- vtop->r |= VT_MUSTBOUND;
-#endif
}
}
@@ -5487,10 +5139,6 @@ ST_FUNC void unary(void)
Sym *s;
AttributeDef ad;
- /* generate line number info */
- if (debug_modes)
- tcc_debug_line(tcc_state), tcc_tcov_check_line (tcc_state, 1);
-
type.ref = NULL;
/* XXX: GCC 2.95.3 does not generate a table although it should be
better here */
@@ -5764,92 +5412,18 @@ ST_FUNC void unary(void)
mk_pointer(&type);
vset(&type, VT_LOCAL, 0); /* local frame */
while (level--) {
-#ifdef TCC_TARGET_RISCV64
- vpushi(2*PTR_SIZE);
- gen_op('-');
-#endif
mk_pointer(&vtop->type);
indir(); /* -> parent frame */
}
if (tok1 == TOK_builtin_return_address) {
// assume return address is just above frame pointer on stack
-#ifdef TCC_TARGET_ARM
- vpushi(2*PTR_SIZE);
- gen_op('+');
-#elif defined TCC_TARGET_RISCV64
- vpushi(PTR_SIZE);
- gen_op('-');
-#else
vpushi(PTR_SIZE);
gen_op('+');
-#endif
mk_pointer(&vtop->type);
indir();
}
}
break;
-#ifdef TCC_TARGET_RISCV64
- case TOK_builtin_va_start:
- parse_builtin_params(0, "ee");
- r = vtop->r & VT_VALMASK;
- if (r == VT_LLOCAL)
- r = VT_LOCAL;
- if (r != VT_LOCAL)
- tcc_error("__builtin_va_start expects a local variable");
- gen_va_start();
- vstore();
- break;
-#endif
-#ifdef TCC_TARGET_X86_64
-#ifdef TCC_TARGET_PE
- case TOK_builtin_va_start:
- parse_builtin_params(0, "ee");
- r = vtop->r & VT_VALMASK;
- if (r == VT_LLOCAL)
- r = VT_LOCAL;
- if (r != VT_LOCAL)
- tcc_error("__builtin_va_start expects a local variable");
- vtop->r = r;
- vtop->type = char_pointer_type;
- vtop->c.i += 8;
- vstore();
- break;
-#else
- case TOK_builtin_va_arg_types:
- parse_builtin_params(0, "t");
- vpushi(classify_x86_64_va_arg(&vtop->type));
- vswap();
- vpop();
- break;
-#endif
-#endif
-
-#ifdef TCC_TARGET_ARM64
- case TOK_builtin_va_start: {
- parse_builtin_params(0, "ee");
- //xx check types
- gen_va_start();
- vpushi(0);
- vtop->type.t = VT_VOID;
- break;
- }
- case TOK_builtin_va_arg: {
- parse_builtin_params(0, "et");
- type = vtop->type;
- vpop();
- //xx check types
- gen_va_arg(&type);
- vtop->type = type;
- break;
- }
- case TOK___arm64_clear_cache: {
- parse_builtin_params(0, "ee");
- gen_clear_cache();
- vpushi(0);
- vtop->type.t = VT_VOID;
- break;
- }
-#endif
/* atomic operations */
case TOK___atomic_store:
@@ -6066,11 +5640,6 @@ special_math_val:
/* an array is never an lvalue */
if (!(vtop->type.t & VT_ARRAY)) {
vtop->r |= VT_LVAL;
-#ifdef CONFIG_TCC_BCHECK
- /* if bound checking, the referenced pointer must be checked */
- if (tcc_state->do_bounds_check)
- vtop->r |= VT_MUSTBOUND;
-#endif
}
next();
} else if (tok == '[') {
@@ -6113,25 +5682,12 @@ special_math_val:
if (ret_nregs <= 0) {
/* get some space for the returned structure */
size = type_size(&s->type, &align);
-#ifdef TCC_TARGET_ARM64
- /* On arm64, a small struct is return in registers.
- It is much easier to write it to memory if we know
- that we are allowed to write some extra bytes, so
- round the allocated space up to a power of 2: */
- if (size < 16)
- while (size & (size - 1))
- size = (size | (size - 1)) + 1;
-#endif
loc = (loc - size) & -align;
ret.type = s->type;
ret.r = VT_LOCAL | VT_LVAL;
/* pass it as 'int' to avoid structure arg passing
problems */
vseti(VT_LOCAL, loc);
-#ifdef CONFIG_TCC_BCHECK
- if (tcc_state->do_bounds_check)
- --loc;
-#endif
ret.c = vtop->c;
if (ret_nregs < 0)
vtop--;
@@ -6191,9 +5747,6 @@ special_math_val:
if (ret_nregs < 0) {
vsetc(&ret.type, ret.r, &ret.c);
-#ifdef TCC_TARGET_RISCV64
- arch_transfer_ret_regs(1);
-#endif
} else {
/* return value */
n = ret_nregs;
@@ -6251,8 +5804,6 @@ special_math_val:
}
}
if (s->f.func_noreturn) {
- if (debug_modes)
- tcc_tcov_block_end(tcc_state, -1);
CODE_OFF();
}
} else {
@@ -6679,7 +6230,7 @@ ST_FUNC int expr_const(void)
/* ------------------------------------------------------------------------- */
/* return from function */
-#ifndef TCC_TARGET_ARM64
+
static void gfunc_return(CType *func_type)
{
if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
@@ -6688,9 +6239,6 @@ static void gfunc_return(CType *func_type)
ret_nregs = gfunc_sret(func_type, func_var, &ret_type,
&ret_align, ®size);
if (ret_nregs < 0) {
-#ifdef TCC_TARGET_RISCV64
- arch_transfer_ret_regs(0);
-#endif
} else if (0 == ret_nregs) {
/* if returning structure, must copy it to implicit
first pointer arg location */
@@ -6739,7 +6287,6 @@ static void gfunc_return(CType *func_type)
}
vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
}
-#endif
static void check_func_return(void)
{
@@ -7027,9 +6574,6 @@ again:
goto expr;
next();
- if (debug_modes)
- tcc_tcov_check_line (tcc_state, 0), tcc_tcov_block_begin (tcc_state);
-
if (t == TOK_IF) {
new_scope_s(&o);
skip('(');
@@ -7063,8 +6607,6 @@ again:
prev_scope_s(&o);
} else if (t == '{') {
- if (debug_modes)
- tcc_debug_stabn(tcc_state, N_LBRAC, ind - func_ind);
new_scope(&o);
/* handle local labels declarations */
@@ -7089,8 +6631,6 @@ again:
}
prev_scope(&o, flags & STMT_EXPR);
- if (debug_modes)
- tcc_debug_stabn(tcc_state, N_RBRAC, ind - func_ind);
if (local_scope)
next();
else if (!nocode_wanted)
@@ -7118,8 +6658,6 @@ again:
/* jump unless last stmt in top-level block */
if (tok != '}' || local_scope != 1)
rsym = gjmp(rsym);
- if (debug_modes)
- tcc_tcov_block_end (tcc_state, -1);
CODE_OFF();
} else if (t == TOK_BREAK) {
@@ -7332,8 +6870,6 @@ again:
AttributeDef ad_tmp;
parse_attribute(&ad_tmp);
}
- if (debug_modes)
- tcc_tcov_reset_ind(tcc_state);
vla_restore(cur_scope->vla.loc);
if (tok != '}') {
@@ -7360,9 +6896,6 @@ again:
}
}
}
-
- if (debug_modes)
- tcc_tcov_check_line (tcc_state, 0), tcc_tcov_block_end (tcc_state, 0);
}
/* This skips over a stream of tokens containing balanced {} and ()
@@ -7459,9 +6992,6 @@ static void init_putz(init_params *p, unsigned long c, int size)
vseti(VT_LOCAL, c);
vpushi(0);
vpushs(size);
-#if defined TCC_TARGET_ARM && defined TCC_ARM_EABI
- vswap(); /* using __aeabi_memset(void*, size_t, int) */
-#endif
gfunc_call(3);
}
}
@@ -7834,10 +7364,6 @@ static void decl_initializer(init_params *p, CType *type, unsigned long c, int f
Sym indexsym;
CType *t1;
- /* generate line number info */
- if (debug_modes && !(flags & DIF_SIZE_ONLY) && !p->sec)
- tcc_debug_line(tcc_state), tcc_tcov_check_line (tcc_state, 1);
-
if (!(flags & DIF_HAVE_ELEM) && tok != '{' &&
/* In case of strings we have special handling for arrays, so
don't consume them as initializer value (which would commit them
@@ -8060,9 +7586,6 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
Sym *flexible_array;
Sym *sym;
int saved_nocode_wanted = nocode_wanted;
-#ifdef CONFIG_TCC_BCHECK
- int bcheck = tcc_state->do_bounds_check && !NODATA_WANTED;
-#endif
init_params p = {0};
/* Always allocate static or global variables */
@@ -8151,21 +7674,10 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
if ((r & VT_VALMASK) == VT_LOCAL) {
sec = NULL;
-#ifdef CONFIG_TCC_BCHECK
- if (bcheck && v) {
- /* add padding between stack variables for bound checking */
- loc -= align;
- }
-#endif
+
loc = (loc - size) & -align;
addr = loc;
p.local_offset = addr + size;
-#ifdef CONFIG_TCC_BCHECK
- if (bcheck && v) {
- /* add padding between stack variables for bound checking */
- loc -= align;
- }
-#endif
if (v) {
/* local variable */
#ifdef CONFIG_TCC_ASM
@@ -8229,11 +7741,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
if (sec) {
addr = section_add(sec, size, align);
-#ifdef CONFIG_TCC_BCHECK
- /* add padding if bound check */
- if (bcheck)
- section_add(sec, 1, 1);
-#endif
+
} else {
addr = align; /* SHN_COMMON is special, symbol value is align */
sec = common_section;
@@ -8253,19 +7761,6 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
vtop->r |= r;
}
-#ifdef CONFIG_TCC_BCHECK
- /* handles bounds now because the symbol must be defined
- before for the relocation */
- if (bcheck) {
- addr_t *bounds_ptr;
-
- greloca(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR, 0);
- /* then add global bound info */
- bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
- bounds_ptr[0] = 0; /* relocated */
- bounds_ptr[1] = size;
- }
-#endif
}
if (type->t & VT_VLA) {
@@ -8286,11 +7781,6 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
vpush_type_size(type, &a);
gen_vla_alloc(type, a);
-#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
- /* on _WIN64, because of the function args scratch area, the
- result of alloca differs from RSP and is returned in RAX. */
- gen_vla_result(addr), addr = (loc -= PTR_SIZE);
-#endif
gen_vla_sp_save(addr);
cur_scope->vla.loc = addr;
cur_scope->vla.num++;
@@ -8381,15 +7871,12 @@ static void gen_function(Sym *sym)
if (sym->type.ref->f.func_dtor)
add_array (tcc_state, ".fini_array", sym->c);
- /* put debug symbol */
- tcc_debug_funcstart(tcc_state, sym);
/* push a dummy symbol to enable local sym storage */
sym_push2(&local_stack, SYM_FIELD, 0, 0);
local_scope = 1; /* for function parameters */
nb_temp_local_vars = 0;
gfunc_prolog(sym);
- tcc_debug_prolog_epilog(tcc_state, 0);
local_scope = 0;
rsym = 0;
@@ -8400,11 +7887,8 @@ static void gen_function(Sym *sym)
nocode_wanted = 0;
/* reset local stack */
pop_local_syms(NULL, 0);
- tcc_debug_prolog_epilog(tcc_state, 1);
gfunc_epilog();
- /* end of function */
- tcc_debug_funcend(tcc_state, ind - func_ind);
/* patch symbol size */
elfsym(sym)->st_size = ind - func_ind;
@@ -8691,8 +8175,6 @@ static int decl(int l)
sym->a = ad.a;
if ((type.t & VT_BTYPE) == VT_FUNC)
merge_funcattr(&sym->type.ref->f, &ad.f);
- if (debug_modes)
- tcc_debug_typedef (tcc_state, sym);
} else if ((type.t & VT_BTYPE) == VT_VOID
&& !(type.t & VT_EXTERN)) {
tcc_error("declaration of void object");
diff --git a/tccpe.c b/libtcc/tccpe.c
similarity index 99%
rename from tccpe.c
rename to libtcc/tccpe.c
index a1fbb32c..e39d7a46 100644
--- a/tccpe.c
+++ b/libtcc/tccpe.c
@@ -20,6 +20,8 @@
#include "tcc.h"
+#define TCC_OUTPUT_DLL 666
+
#define PE_MERGE_DATA 1
#define PE_PRINT_SECTIONS 0
@@ -1880,22 +1882,6 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
++start_symbol;
}
-#ifdef CONFIG_TCC_BACKTRACE
- if (s1->do_backtrace) {
-#ifdef CONFIG_TCC_BCHECK
- if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL)
- tcc_add_support(s1, "bcheck.o");
-#endif
- if (s1->output_type == TCC_OUTPUT_EXE)
- tcc_add_support(s1, "bt-exe.o");
- if (s1->output_type == TCC_OUTPUT_DLL)
- tcc_add_support(s1, "bt-dll.o");
- if (s1->output_type != TCC_OUTPUT_DLL)
- tcc_add_support(s1, "bt-log.o");
- tcc_add_btstub(s1);
- }
-#endif
-
/* grab the startup code from libtcc1.a */
#ifdef TCC_IS_NATIVE
if (TCC_OUTPUT_MEMORY != s1->output_type || s1->run_main)
@@ -1982,9 +1968,6 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
pe.s1 = s1;
s1->filetype = 0;
-#ifdef CONFIG_TCC_BCHECK
- tcc_add_bcheck(s1);
-#endif
tcc_add_pragma_libs(s1);
pe_add_runtime(s1, &pe);
resolve_common_syms(s1);
diff --git a/tccpp.c b/libtcc/tccpp.c
similarity index 99%
rename from tccpp.c
rename to libtcc/tccpp.c
index 2bfe8954..15b540f7 100644
--- a/tccpp.c
+++ b/libtcc/tccpp.c
@@ -20,6 +20,7 @@
#define USING_GLOBALS
#include "tcc.h"
+#include "utils/string.h"
/* #define to 1 to enable (see parse_pp_string()) */
#define ACCEPT_LF_IN_STRINGS 0
@@ -946,12 +947,8 @@ redo_start:
else if (parse_flags & PARSE_FLAG_ASM_FILE)
p = parse_line_comment(p - 1);
}
-#if !defined(TCC_TARGET_ARM)
else if (parse_flags & PARSE_FLAG_ASM_FILE)
p = parse_line_comment(p - 1);
-#else
- /* ARM assembly uses '#' for constants */
-#endif
break;
_default:
default:
@@ -1326,8 +1323,8 @@ static void maybe_run_test(TCCState *s)
p = get_tok_str(tok, NULL);
if (0 != memcmp(p, "test_", 5))
return;
- if (0 != --s->run_test)
- return;
+ /*if (0 != --s->run_test)
+ return;*/
fprintf(s->ppfp, &"\n[%s]\n"[!(s->dflag & 32)], p), fflush(s->ppfp);
define_push(tok, MACRO_OBJ, NULL, NULL);
}
@@ -1446,8 +1443,6 @@ static int parse_include(TCCState *s1, int do_next, int test)
dynarray_add(&s1->target_deps, &s1->nb_target_deps,
tcc_strdup(buf));
}
- /* add include file debug info */
- tcc_debug_bincl(s1);
}
return 1;
}
@@ -1479,8 +1474,6 @@ static int expr_preprocess(TCCState *s1)
parse_flags |= PARSE_FLAG_PREPROCESS;
if (tok < TOK_IDENT)
expect("identifier after 'defined'");
- if (s1->run_test)
- maybe_run_test(s1);
c = 0;
if (define_find(tok)
|| tok == TOK___HAS_INCLUDE
@@ -1806,7 +1799,6 @@ ST_FUNC void tccpp_putfile(const char *filename)
if (file->true_filename == file->filename)
file->true_filename = tcc_strdup(file->filename);
pstrcpy(file->filename, sizeof file->filename, buf);
- tcc_debug_newfile(tcc_state);
}
/* is_bof is true if first non space token at beginning of file */
@@ -2615,8 +2607,6 @@ static void next_nomacro(void)
tok_flags &= ~TOK_FLAG_ENDIF;
}
- /* add end of include file debug info */
- tcc_debug_eincl(tcc_state);
/* pop include stack */
tcc_close();
s1->include_stack_ptr--;
@@ -2653,12 +2643,10 @@ maybe_newline:
p++;
tok = TOK_TWOSHARPS;
} else {
-#if !defined(TCC_TARGET_ARM)
if (parse_flags & PARSE_FLAG_ASM_FILE) {
p = parse_line_comment(p - 1);
goto redo_no_start;
} else
-#endif
{
tok = '#';
}
@@ -3576,24 +3564,12 @@ static void tcc_predefs(TCCState *s1, CString *cs, int is_asm)
putdefs(cs, target_machine_defs);
putdefs(cs, target_os_defs);
-#ifdef TCC_TARGET_ARM
- if (s1->float_abi == ARM_HARD_FLOAT)
- putdef(cs, "__ARM_PCS_VFP");
-#endif
if (is_asm)
putdef(cs, "__ASSEMBLER__");
if (s1->output_type == TCC_OUTPUT_PREPROCESS)
putdef(cs, "__TCC_PP__");
if (s1->output_type == TCC_OUTPUT_MEMORY)
putdef(cs, "__TCC_RUN__");
-#ifdef CONFIG_TCC_BACKTRACE
- if (s1->do_backtrace)
- putdef(cs, "__TCC_BACKTRACE__");
-#endif
-#ifdef CONFIG_TCC_BCHECK
- if (s1->do_bounds_check)
- putdef(cs, "__TCC_BCHECK__");
-#endif
if (s1->char_is_unsigned)
putdef(cs, "__CHAR_UNSIGNED__");
if (s1->optimize > 0)
diff --git a/tcctok.h b/libtcc/tcctok.h
similarity index 61%
rename from tcctok.h
rename to libtcc/tcctok.h
index bcd67f19..c1cfbe9e 100644
--- a/tcctok.h
+++ b/libtcc/tcctok.h
@@ -68,10 +68,6 @@
DEF(TOK_TYPEOF3, "__typeof__")
DEF(TOK_LABEL, "__label__")
-#ifdef TCC_TARGET_ARM64
- DEF(TOK_UINT128, "__uint128_t")
-#endif
-
/*********************************************************************/
/* the following are not keywords. They are included to ease parsing */
/* preprocessor only */
@@ -105,10 +101,6 @@
DEF(TOK___NAN__, "__nan__")
DEF(TOK___SNAN__, "__snan__")
DEF(TOK___INF__, "__inf__")
-#if defined TCC_TARGET_X86_64
- DEF(TOK___mzerosf, "__mzerosf") /* -0.0 */
- DEF(TOK___mzerodf, "__mzerodf") /* -0.0 */
-#endif
/* attribute identifiers */
/* XXX: handle all tokens generically since speed is not critical */
@@ -173,16 +165,6 @@
DEF(TOK_builtin_expect, "__builtin_expect")
DEF(TOK_builtin_unreachable, "__builtin_unreachable")
/*DEF(TOK_builtin_va_list, "__builtin_va_list")*/
-#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
- DEF(TOK_builtin_va_start, "__builtin_va_start")
-#elif defined TCC_TARGET_X86_64
- DEF(TOK_builtin_va_arg_types, "__builtin_va_arg_types")
-#elif defined TCC_TARGET_ARM64
- DEF(TOK_builtin_va_start, "__builtin_va_start")
- DEF(TOK_builtin_va_arg, "__builtin_va_arg")
-#elif defined TCC_TARGET_RISCV64
- DEF(TOK_builtin_va_start, "__builtin_va_start")
-#endif
/* atomic operations */
#define DEF_ATOMIC(ID) DEF(TOK_##__##ID, "__"#ID)
@@ -205,13 +187,6 @@
/* pragma */
DEF(TOK_pack, "pack")
-#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_X86_64) && \
- !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_ARM64) && \
- !defined(TCC_TARGET_RISCV64)
- /* already defined for assembler */
- DEF(TOK_ASM_push, "push")
- DEF(TOK_ASM_pop, "pop")
-#endif
DEF(TOK_comment, "comment")
DEF(TOK_lib, "lib")
DEF(TOK_push_macro, "push_macro")
@@ -220,7 +195,6 @@
DEF(TOK_option, "option")
/* builtin functions or variables */
-#ifndef TCC_ARM_EABI
DEF(TOK_memcpy, "memcpy")
DEF(TOK_memmove, "memmove")
DEF(TOK_memset, "memset")
@@ -233,134 +207,16 @@
DEF(TOK___ashldi3, "__ashldi3")
DEF(TOK___floatundisf, "__floatundisf")
DEF(TOK___floatundidf, "__floatundidf")
-# ifndef TCC_ARM_VFP
DEF(TOK___floatundixf, "__floatundixf")
DEF(TOK___fixunsxfdi, "__fixunsxfdi")
-# endif
DEF(TOK___fixunssfdi, "__fixunssfdi")
DEF(TOK___fixunsdfdi, "__fixunsdfdi")
-#endif
-#if defined TCC_TARGET_ARM
-# ifdef TCC_ARM_EABI
- DEF(TOK_memcpy, "__aeabi_memcpy")
- DEF(TOK_memmove, "__aeabi_memmove")
- DEF(TOK_memmove4, "__aeabi_memmove4")
- DEF(TOK_memmove8, "__aeabi_memmove8")
- DEF(TOK_memset, "__aeabi_memset")
- DEF(TOK___aeabi_ldivmod, "__aeabi_ldivmod")
- DEF(TOK___aeabi_uldivmod, "__aeabi_uldivmod")
- DEF(TOK___aeabi_idivmod, "__aeabi_idivmod")
- DEF(TOK___aeabi_uidivmod, "__aeabi_uidivmod")
- DEF(TOK___divsi3, "__aeabi_idiv")
- DEF(TOK___udivsi3, "__aeabi_uidiv")
- DEF(TOK___floatdisf, "__aeabi_l2f")
- DEF(TOK___floatdidf, "__aeabi_l2d")
- DEF(TOK___fixsfdi, "__aeabi_f2lz")
- DEF(TOK___fixdfdi, "__aeabi_d2lz")
- DEF(TOK___ashrdi3, "__aeabi_lasr")
- DEF(TOK___lshrdi3, "__aeabi_llsr")
- DEF(TOK___ashldi3, "__aeabi_llsl")
- DEF(TOK___floatundisf, "__aeabi_ul2f")
- DEF(TOK___floatundidf, "__aeabi_ul2d")
- DEF(TOK___fixunssfdi, "__aeabi_f2ulz")
- DEF(TOK___fixunsdfdi, "__aeabi_d2ulz")
-# else
- DEF(TOK___modsi3, "__modsi3")
- DEF(TOK___umodsi3, "__umodsi3")
- DEF(TOK___divsi3, "__divsi3")
- DEF(TOK___udivsi3, "__udivsi3")
- DEF(TOK___floatdisf, "__floatdisf")
- DEF(TOK___floatdidf, "__floatdidf")
-# ifndef TCC_ARM_VFP
- DEF(TOK___floatdixf, "__floatdixf")
- DEF(TOK___fixunssfsi, "__fixunssfsi")
- DEF(TOK___fixunsdfsi, "__fixunsdfsi")
- DEF(TOK___fixunsxfsi, "__fixunsxfsi")
- DEF(TOK___fixxfdi, "__fixxfdi")
-# endif
- DEF(TOK___fixsfdi, "__fixsfdi")
- DEF(TOK___fixdfdi, "__fixdfdi")
-# endif
-#endif
-
-#if defined TCC_TARGET_C67
- DEF(TOK__divi, "_divi")
- DEF(TOK__divu, "_divu")
- DEF(TOK__divf, "_divf")
- DEF(TOK__divd, "_divd")
- DEF(TOK__remi, "_remi")
- DEF(TOK__remu, "_remu")
-#endif
-
-#if defined TCC_TARGET_I386
DEF(TOK___fixsfdi, "__fixsfdi")
DEF(TOK___fixdfdi, "__fixdfdi")
DEF(TOK___fixxfdi, "__fixxfdi")
-#endif
-#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
DEF(TOK_alloca, "alloca")
-#endif
-
-#if defined TCC_TARGET_PE
- DEF(TOK___chkstk, "__chkstk")
-#endif
-#if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64
- DEF(TOK___arm64_clear_cache, "__arm64_clear_cache")
- DEF(TOK___addtf3, "__addtf3")
- DEF(TOK___subtf3, "__subtf3")
- DEF(TOK___multf3, "__multf3")
- DEF(TOK___divtf3, "__divtf3")
- DEF(TOK___extendsftf2, "__extendsftf2")
- DEF(TOK___extenddftf2, "__extenddftf2")
- DEF(TOK___trunctfsf2, "__trunctfsf2")
- DEF(TOK___trunctfdf2, "__trunctfdf2")
- DEF(TOK___fixtfsi, "__fixtfsi")
- DEF(TOK___fixtfdi, "__fixtfdi")
- DEF(TOK___fixunstfsi, "__fixunstfsi")
- DEF(TOK___fixunstfdi, "__fixunstfdi")
- DEF(TOK___floatsitf, "__floatsitf")
- DEF(TOK___floatditf, "__floatditf")
- DEF(TOK___floatunsitf, "__floatunsitf")
- DEF(TOK___floatunditf, "__floatunditf")
- DEF(TOK___eqtf2, "__eqtf2")
- DEF(TOK___netf2, "__netf2")
- DEF(TOK___lttf2, "__lttf2")
- DEF(TOK___letf2, "__letf2")
- DEF(TOK___gttf2, "__gttf2")
- DEF(TOK___getf2, "__getf2")
-#endif
-
-/* bound checking symbols */
-#ifdef CONFIG_TCC_BCHECK
- DEF(TOK___bound_ptr_add, "__bound_ptr_add")
- DEF(TOK___bound_ptr_indir1, "__bound_ptr_indir1")
- DEF(TOK___bound_ptr_indir2, "__bound_ptr_indir2")
- DEF(TOK___bound_ptr_indir4, "__bound_ptr_indir4")
- DEF(TOK___bound_ptr_indir8, "__bound_ptr_indir8")
- DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12")
- DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16")
- DEF(TOK___bound_main_arg, "__bound_main_arg")
- DEF(TOK___bound_local_new, "__bound_local_new")
- DEF(TOK___bound_local_delete, "__bound_local_delete")
- DEF(TOK___bound_setjmp, "__bound_setjmp")
- DEF(TOK___bound_longjmp, "__bound_longjmp")
- DEF(TOK___bound_new_region, "__bound_new_region")
-# ifdef TCC_TARGET_PE
-# ifdef TCC_TARGET_X86_64
- DEF(TOK___bound_alloca_nr, "__bound_alloca_nr")
-# endif
-# else
- DEF(TOK_sigsetjmp, "sigsetjmp")
- DEF(TOK___sigsetjmp, "__sigsetjmp")
- DEF(TOK_siglongjmp, "siglongjmp")
-# endif
- DEF(TOK_setjmp, "setjmp")
- DEF(TOK__setjmp, "_setjmp")
- DEF(TOK_longjmp, "longjmp")
-#endif
-
/*********************************************************************/
/* Tiny Assembler */
@@ -401,28 +257,12 @@
DEF_ASMDIR(endr)
DEF_ASMDIR(org)
DEF_ASMDIR(quad)
-#if defined(TCC_TARGET_I386)
DEF_ASMDIR(code16)
DEF_ASMDIR(code32)
-#elif defined(TCC_TARGET_X86_64)
- DEF_ASMDIR(code64)
-#elif defined(TCC_TARGET_RISCV64)
- DEF_ASMDIR(option)
-#endif
DEF_ASMDIR(short)
DEF_ASMDIR(long)
DEF_ASMDIR(int)
DEF_ASMDIR(symver)
DEF_ASMDIR(section) /* must be last directive */
-#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
-#include "i386-tok.h"
-#endif
-
-#if defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64
-#include "arm-tok.h"
-#endif
-
-#if defined TCC_TARGET_RISCV64
-#include "riscv64-tok.h"
-#endif
+#include "i386/tok.h"
diff --git a/libtcc/utils/string.h b/libtcc/utils/string.h
new file mode 100644
index 00000000..a44b0c4b
--- /dev/null
+++ b/libtcc/utils/string.h
@@ -0,0 +1,47 @@
+#ifndef LIBTCC_UTILS_STRING_H
+# define LIBTCC_UTILS_STRING_H 1
+
+# include
+# include
+
+/* copy a string and truncate it. */
+static inline char *
+pstrcpy(char *buf, size_t buf_size, const char *s)
+{
+ char *q, *q_end;
+ int c;
+
+ if (buf_size > 0) {
+ q = buf;
+ q_end = buf + buf_size - 1;
+ while (q < q_end) {
+ c = *s++;
+ if (c == '\0')
+ break;
+ *q++ = c;
+ }
+ *q = '\0';
+ }
+ return buf;
+}
+
+/* strcat and truncate. */
+static inline char *
+pstrcat(char *buf, size_t buf_size, const char *s)
+{
+ size_t len;
+ len = strlen(buf);
+ if (len < buf_size)
+ pstrcpy(buf + len, buf_size - len, s);
+ return buf;
+}
+
+static inline char *
+pstrncpy(char *out, const char *in, size_t num)
+{
+ memcpy(out, in, num);
+ out[num] = '\0';
+ return out;
+}
+
+#endif /* !LIBTCC_UTILS_STRING_H */
\ No newline at end of file
diff --git a/lib/alloca-bt.S b/libtcc1/alloca-bt.S
similarity index 100%
rename from lib/alloca-bt.S
rename to libtcc1/alloca-bt.S
diff --git a/lib/alloca.S b/libtcc1/alloca.S
similarity index 100%
rename from lib/alloca.S
rename to libtcc1/alloca.S
diff --git a/lib/armeabi.c b/libtcc1/armeabi.c
similarity index 100%
rename from lib/armeabi.c
rename to libtcc1/armeabi.c
diff --git a/lib/armflush.c b/libtcc1/armflush.c
similarity index 100%
rename from lib/armflush.c
rename to libtcc1/armflush.c
diff --git a/lib/atomic.S b/libtcc1/atomic.S
similarity index 100%
rename from lib/atomic.S
rename to libtcc1/atomic.S
diff --git a/lib/bcheck.c b/libtcc1/bcheck.c
similarity index 100%
rename from lib/bcheck.c
rename to libtcc1/bcheck.c
diff --git a/lib/bt-dll.c b/libtcc1/bt-dll.c
similarity index 100%
rename from lib/bt-dll.c
rename to libtcc1/bt-dll.c
diff --git a/lib/bt-exe.c b/libtcc1/bt-exe.c
similarity index 100%
rename from lib/bt-exe.c
rename to libtcc1/bt-exe.c
diff --git a/lib/bt-log.c b/libtcc1/bt-log.c
similarity index 100%
rename from lib/bt-log.c
rename to libtcc1/bt-log.c
diff --git a/lib/builtin.c b/libtcc1/builtin.c
similarity index 100%
rename from lib/builtin.c
rename to libtcc1/builtin.c
diff --git a/lib/dsohandle.c b/libtcc1/dsohandle.c
similarity index 100%
rename from lib/dsohandle.c
rename to libtcc1/dsohandle.c
diff --git a/lib/lib-arm64.c b/libtcc1/lib-arm64.c
similarity index 100%
rename from lib/lib-arm64.c
rename to libtcc1/lib-arm64.c
diff --git a/lib/libtcc1.c b/libtcc1/libtcc1.c
similarity index 100%
rename from lib/libtcc1.c
rename to libtcc1/libtcc1.c
diff --git a/lib/runmain.c b/libtcc1/runmain.c
similarity index 100%
rename from lib/runmain.c
rename to libtcc1/runmain.c
diff --git a/lib/stdatomic.c b/libtcc1/stdatomic.c
similarity index 100%
rename from lib/stdatomic.c
rename to libtcc1/stdatomic.c
diff --git a/tcclib.h b/libtcc1/tcclib.h
similarity index 100%
rename from tcclib.h
rename to libtcc1/tcclib.h
diff --git a/lib/tcov.c b/libtcc1/tcov.c
similarity index 100%
rename from lib/tcov.c
rename to libtcc1/tcov.c
diff --git a/lib/va_list.c b/libtcc1/va_list.c
similarity index 100%
rename from lib/va_list.c
rename to libtcc1/va_list.c
diff --git a/stab.def b/stab.def
deleted file mode 100644
index 48ea231e..00000000
--- a/stab.def
+++ /dev/null
@@ -1,234 +0,0 @@
-/* Table of DBX symbol codes for the GNU system.
- Copyright (C) 1988, 1997 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-/* This contains contribution from Cygnus Support. */
-
-/* Global variable. Only the name is significant.
- To find the address, look in the corresponding external symbol. */
-__define_stab (N_GSYM, 0x20, "GSYM")
-
-/* Function name for BSD Fortran. Only the name is significant.
- To find the address, look in the corresponding external symbol. */
-__define_stab (N_FNAME, 0x22, "FNAME")
-
-/* Function name or text-segment variable for C. Value is its address.
- Desc is supposedly starting line number, but GCC doesn't set it
- and DBX seems not to miss it. */
-__define_stab (N_FUN, 0x24, "FUN")
-
-/* Data-segment variable with internal linkage. Value is its address.
- "Static Sym". */
-__define_stab (N_STSYM, 0x26, "STSYM")
-
-/* BSS-segment variable with internal linkage. Value is its address. */
-__define_stab (N_LCSYM, 0x28, "LCSYM")
-
-/* Name of main routine. Only the name is significant.
- This is not used in C. */
-__define_stab (N_MAIN, 0x2a, "MAIN")
-
-/* Global symbol in Pascal.
- Supposedly the value is its line number; I'm skeptical. */
-__define_stab (N_PC, 0x30, "PC")
-
-/* Number of symbols: 0, files,,funcs,lines according to Ultrix V4.0. */
-__define_stab (N_NSYMS, 0x32, "NSYMS")
-
-/* "No DST map for sym: name, ,0,type,ignored" according to Ultrix V4.0. */
-__define_stab (N_NOMAP, 0x34, "NOMAP")
-
-/* New stab from Solaris. I don't know what it means, but it
- don't seem to contain useful information. */
-__define_stab (N_OBJ, 0x38, "OBJ")
-
-/* New stab from Solaris. I don't know what it means, but it
- don't seem to contain useful information. Possibly related to the
- optimization flags used in this module. */
-__define_stab (N_OPT, 0x3c, "OPT")
-
-/* Register variable. Value is number of register. */
-__define_stab (N_RSYM, 0x40, "RSYM")
-
-/* Modula-2 compilation unit. Can someone say what info it contains? */
-__define_stab (N_M2C, 0x42, "M2C")
-
-/* Line number in text segment. Desc is the line number;
- value is corresponding address. */
-__define_stab (N_SLINE, 0x44, "SLINE")
-
-/* Similar, for data segment. */
-__define_stab (N_DSLINE, 0x46, "DSLINE")
-
-/* Similar, for bss segment. */
-__define_stab (N_BSLINE, 0x48, "BSLINE")
-
-/* Sun's source-code browser stabs. ?? Don't know what the fields are.
- Supposedly the field is "path to associated .cb file". THIS VALUE
- OVERLAPS WITH N_BSLINE! */
-__define_stab (N_BROWS, 0x48, "BROWS")
-
-/* GNU Modula-2 definition module dependency. Value is the modification time
- of the definition file. Other is non-zero if it is imported with the
- GNU M2 keyword %INITIALIZE. Perhaps N_M2C can be used if there
- are enough empty fields? */
-__define_stab(N_DEFD, 0x4a, "DEFD")
-
-/* THE FOLLOWING TWO STAB VALUES CONFLICT. Happily, one is for Modula-2
- and one is for C++. Still,... */
-/* GNU C++ exception variable. Name is variable name. */
-__define_stab (N_EHDECL, 0x50, "EHDECL")
-/* Modula2 info "for imc": name,,0,0,0 according to Ultrix V4.0. */
-__define_stab (N_MOD2, 0x50, "MOD2")
-
-/* GNU C++ `catch' clause. Value is its address. Desc is nonzero if
- this entry is immediately followed by a CAUGHT stab saying what exception
- was caught. Multiple CAUGHT stabs means that multiple exceptions
- can be caught here. If Desc is 0, it means all exceptions are caught
- here. */
-__define_stab (N_CATCH, 0x54, "CATCH")
-
-/* Structure or union element. Value is offset in the structure. */
-__define_stab (N_SSYM, 0x60, "SSYM")
-
-/* Name of main source file.
- Value is starting text address of the compilation. */
-__define_stab (N_SO, 0x64, "SO")
-
-/* Automatic variable in the stack. Value is offset from frame pointer.
- Also used for type descriptions. */
-__define_stab (N_LSYM, 0x80, "LSYM")
-
-/* Beginning of an include file. Only Sun uses this.
- In an object file, only the name is significant.
- The Sun linker puts data into some of the other fields. */
-__define_stab (N_BINCL, 0x82, "BINCL")
-
-/* Name of sub-source file (#include file).
- Value is starting text address of the compilation. */
-__define_stab (N_SOL, 0x84, "SOL")
-
-/* Parameter variable. Value is offset from argument pointer.
- (On most machines the argument pointer is the same as the frame pointer. */
-__define_stab (N_PSYM, 0xa0, "PSYM")
-
-/* End of an include file. No name.
- This and N_BINCL act as brackets around the file's output.
- In an object file, there is no significant data in this entry.
- The Sun linker puts data into some of the fields. */
-__define_stab (N_EINCL, 0xa2, "EINCL")
-
-/* Alternate entry point. Value is its address. */
-__define_stab (N_ENTRY, 0xa4, "ENTRY")
-
-/* Beginning of lexical block.
- The desc is the nesting level in lexical blocks.
- The value is the address of the start of the text for the block.
- The variables declared inside the block *precede* the N_LBRAC symbol. */
-__define_stab (N_LBRAC, 0xc0, "LBRAC")
-
-/* Place holder for deleted include file. Replaces a N_BINCL and everything
- up to the corresponding N_EINCL. The Sun linker generates these when
- it finds multiple identical copies of the symbols from an include file.
- This appears only in output from the Sun linker. */
-__define_stab (N_EXCL, 0xc2, "EXCL")
-
-/* Modula-2 scope information. Can someone say what info it contains? */
-__define_stab (N_SCOPE, 0xc4, "SCOPE")
-
-/* End of a lexical block. Desc matches the N_LBRAC's desc.
- The value is the address of the end of the text for the block. */
-__define_stab (N_RBRAC, 0xe0, "RBRAC")
-
-/* Begin named common block. Only the name is significant. */
-__define_stab (N_BCOMM, 0xe2, "BCOMM")
-
-/* End named common block. Only the name is significant
- (and it should match the N_BCOMM). */
-__define_stab (N_ECOMM, 0xe4, "ECOMM")
-
-/* End common (local name): value is address.
- I'm not sure how this is used. */
-__define_stab (N_ECOML, 0xe8, "ECOML")
-
-/* These STAB's are used on Gould systems for Non-Base register symbols
- or something like that. FIXME. I have assigned the values at random
- since I don't have a Gould here. Fixups from Gould folk welcome... */
-__define_stab (N_NBTEXT, 0xF0, "NBTEXT")
-__define_stab (N_NBDATA, 0xF2, "NBDATA")
-__define_stab (N_NBBSS, 0xF4, "NBBSS")
-__define_stab (N_NBSTS, 0xF6, "NBSTS")
-__define_stab (N_NBLCS, 0xF8, "NBLCS")
-
-/* Second symbol entry containing a length-value for the preceding entry.
- The value is the length. */
-__define_stab (N_LENG, 0xfe, "LENG")
-
-/* The above information, in matrix format.
-
- STAB MATRIX
- _________________________________________________
- | 00 - 1F are not dbx stab symbols |
- | In most cases, the low bit is the EXTernal bit|
-
- | 00 UNDEF | 02 ABS | 04 TEXT | 06 DATA |
- | 01 |EXT | 03 |EXT | 05 |EXT | 07 |EXT |
-
- | 08 BSS | 0A INDR | 0C FN_SEQ | 0E |
- | 09 |EXT | 0B | 0D | 0F |
-
- | 10 | 12 COMM | 14 SETA | 16 SETT |
- | 11 | 13 | 15 | 17 |
-
- | 18 SETD | 1A SETB | 1C SETV | 1E WARNING|
- | 19 | 1B | 1D | 1F FN |
-
- |_______________________________________________|
- | Debug entries with bit 01 set are unused. |
- | 20 GSYM | 22 FNAME | 24 FUN | 26 STSYM |
- | 28 LCSYM | 2A MAIN | 2C | 2E |
- | 30 PC | 32 NSYMS | 34 NOMAP | 36 |
- | 38 OBJ | 3A | 3C OPT | 3E |
- | 40 RSYM | 42 M2C | 44 SLINE | 46 DSLINE |
- | 48 BSLINE*| 4A DEFD | 4C | 4E |
- | 50 EHDECL*| 52 | 54 CATCH | 56 |
- | 58 | 5A | 5C | 5E |
- | 60 SSYM | 62 | 64 SO | 66 |
- | 68 | 6A | 6C | 6E |
- | 70 | 72 | 74 | 76 |
- | 78 | 7A | 7C | 7E |
- | 80 LSYM | 82 BINCL | 84 SOL | 86 |
- | 88 | 8A | 8C | 8E |
- | 90 | 92 | 94 | 96 |
- | 98 | 9A | 9C | 9E |
- | A0 PSYM | A2 EINCL | A4 ENTRY | A6 |
- | A8 | AA | AC | AE |
- | B0 | B2 | B4 | B6 |
- | B8 | BA | BC | BE |
- | C0 LBRAC | C2 EXCL | C4 SCOPE | C6 |
- | C8 | CA | CC | CE |
- | D0 | D2 | D4 | D6 |
- | D8 | DA | DC | DE |
- | E0 RBRAC | E2 BCOMM | E4 ECOMM | E6 |
- | E8 ECOML | EA | EC | EE |
- | F0 | F2 | F4 | F6 |
- | F8 | FA | FC | FE LENG |
- +-----------------------------------------------+
- * 50 EHDECL is also MOD2.
- * 48 BSLINE is also BROWS.
- */
diff --git a/stab.h b/stab.h
deleted file mode 100644
index 80bd594a..00000000
--- a/stab.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __GNU_STAB__
-
-/* Indicate the GNU stab.h is in use. */
-
-#define __GNU_STAB__
-
-#define __define_stab(NAME, CODE, STRING) NAME=CODE,
-
-enum __stab_debug_code
-{
-#include "stab.def"
-LAST_UNUSED_STAB_CODE
-};
-
-#undef __define_stab
-
-#endif /* __GNU_STAB_ */
diff --git a/tcc.c b/tcc.c
deleted file mode 100644
index c6bb4534..00000000
--- a/tcc.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * TCC - Tiny C Compiler
- *
- * Copyright (c) 2001-2004 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "config.h"
-#include "tcc.h"
-#include "tcctools.c"
-
-static const char help[] =
- "Tiny C Compiler "PACKAGE_VERSION" - Copyright (C) 2001-2006 Fabrice Bellard\n"
- "Usage: tcc [options...] [-o outfile] [-c] infile(s)...\n"
- " tcc [options...] -run infile (or --) [arguments...]\n"
- "General options:\n"
- " -c compile only - generate an object file\n"
- " -o outfile set output filename\n"
- " -run run compiled source\n"
- " -fflag set or reset (with 'no-' prefix) 'flag' (see tcc -hh)\n"
- " -Wwarning set or reset (with 'no-' prefix) 'warning' (see tcc -hh)\n"
- " -w disable all warnings\n"
- " -v --version show version\n"
- " -vv show search paths or loaded files\n"
- " -h -hh show this, show more help\n"
- " -bench show compilation statistics\n"
- " - use stdin pipe as infile\n"
- " @listfile read arguments from listfile\n"
- "Preprocessor options:\n"
- " -Idir add include path 'dir'\n"
- " -Dsym[=val] define 'sym' with value 'val'\n"
- " -Usym undefine 'sym'\n"
- " -E preprocess only\n"
- "Linker options:\n"
- " -Ldir add library path 'dir'\n"
- " -llib link with dynamic or static library 'lib'\n"
- " -r generate (relocatable) object file\n"
- " -shared generate a shared library/dll\n"
- " -rdynamic export all global symbols to dynamic linker\n"
- " -soname set name for shared library to be used at runtime\n"
- " -Wl,-opt[=val] set linker option (see tcc -hh)\n"
- "Debugger options:\n"
- " -g generate stab runtime debug info\n"
- " -gdwarf[-x] generate dwarf runtime debug info\n"
-#ifdef CONFIG_TCC_BCHECK
- " -b compile with built-in memory and bounds checker (implies -g)\n"
-#endif
-#ifdef CONFIG_TCC_BACKTRACE
- " -bt[N] link with backtrace (stack dump) support [show max N callers]\n"
-#endif
- "Misc. options:\n"
- " -std=version define __STDC_VERSION__ according to version (c11/gnu11)\n"
- " -x[c|a|b|n] specify type of the next infile (C,ASM,BIN,NONE)\n"
- " -nostdinc do not use standard system include paths\n"
- " -nostdlib do not link with standard crt and libraries\n"
- " -Bdir set tcc's private include/library dir\n"
- " -M[M]D generate make dependency file [ignore system files]\n"
- " -M[M] as above but no other output\n"
- " -MF file specify dependency file name\n"
- "Tools:\n"
- " create library : tcc -ar [crstvx] lib [files]\n"
- ;
-
-static const char help2[] =
- "Tiny C Compiler "PACKAGE_VERSION" - More Options\n"
- "Special options:\n"
- " -P -P1 with -E: no/alternative #line output\n"
- " -dD -dM with -E: output #define directives\n"
- " -pthread same as -D_REENTRANT and -lpthread\n"
- " -On same as -D__OPTIMIZE__ for n > 0\n"
- " -Wp,-opt same as -opt\n"
- " -include file include 'file' above each input file\n"
- " -isystem dir add 'dir' to system include path\n"
- " -static link to static libraries (not recommended)\n"
- " -dumpversion print version\n"
- " -print-search-dirs print search paths\n"
- " -dt with -run/-E: auto-define 'test_...' macros\n"
- "Ignored options:\n"
- " -arch -C --param -pedantic -pipe -s -traditional\n"
- "-W[no-]... warnings:\n"
- " all turn on some (*) warnings\n"
- " error[=warning] stop after warning (any or specified)\n"
- " write-strings strings are const\n"
- " unsupported warn about ignored options, pragmas, etc.\n"
- " implicit-function-declaration warn for missing prototype (*)\n"
- " discarded-qualifiers warn when const is dropped (*)\n"
- "-f[no-]... flags:\n"
- " unsigned-char default char is unsigned\n"
- " signed-char default char is signed\n"
- " common use common section instead of bss\n"
- " leading-underscore decorate extern symbols\n"
- " ms-extensions allow anonymous struct in struct\n"
- " dollars-in-identifiers allow '$' in C symbols\n"
- " reverse-funcargs evaluate function arguments right to left\n"
- " gnu89-inline 'extern inline' is like 'static inline'\n"
- " asynchronous-unwind-tables create eh_frame section [on]\n"
- " test-coverage create code coverage code\n"
- "-m... target specific options:\n"
- " ms-bitfields use MSVC bitfield layout\n"
- "-Wl,... linker options:\n"
- " -nostdlib do not link with standard crt/libs\n"
- " -[no-]whole-archive load lib(s) fully/only as needed\n"
- " -export-all-symbols same as -rdynamic\n"
- " -export-dynamic same as -rdynamic\n"
- " -image-base= -Ttext= set base address of executable\n"
- " -section-alignment= set section alignment in executable\n"
- " -rpath= set dynamic library search path\n"
- " -enable-new-dtags set DT_RUNPATH instead of DT_RPATH\n"
- " -soname= set DT_SONAME elf tag\n"
- " -Bsymbolic set DT_SYMBOLIC elf tag\n"
- " -oformat=[elf32/64-* binary] set executable output format\n"
- " -init= -fini= -Map= -as-needed -O (ignored)\n"
- "Predefined macros:\n"
- " tcc -E -dM - < /dev/null\n"
- "See also the manual for more details.\n"
- ;
-
-static const char version[] =
- "tcc version "PACKAGE_VERSION
- " (i386)\n"
- ;
-
-static void print_dirs(const char *msg, char **paths, int nb_paths)
-{
- int i;
- printf("%s:\n%s", msg, nb_paths ? "" : " -\n");
- for(i = 0; i < nb_paths; i++)
- printf(" %s\n", paths[i]);
-}
-
-static void print_search_dirs(TCCState *s)
-{
- printf("install: %s\n", s->tcc_lib_path);
- /* print_dirs("programs", NULL, 0); */
- print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths);
- print_dirs("libraries", s->library_paths, s->nb_library_paths);
- printf("libtcc1:\n %s/%s\n", s->library_paths[0], CONFIG_TCC_CROSSPREFIX TCC_LIBTCC1);
- print_dirs("crt", s->crt_paths, s->nb_crt_paths);
- printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s));
-}
-
-static void set_environment(TCCState *s)
-{
- char * path;
-
- path = getenv("C_INCLUDE_PATH");
- if(path != NULL) {
- tcc_add_sysinclude_path(s, path);
- }
- path = getenv("CPATH");
- if(path != NULL) {
- tcc_add_include_path(s, path);
- }
- path = getenv("LIBRARY_PATH");
- if(path != NULL) {
- tcc_add_library_path(s, path);
- }
-}
-
-static char *default_outputfile(TCCState *s, const char *first_file)
-{
- char buf[1024];
- char *ext;
- const char *name = "a";
-
- if (first_file && strcmp(first_file, "-"))
- name = tcc_basename(first_file);
- snprintf(buf, sizeof(buf), "%s", name);
- ext = tcc_fileextension(buf);
- if ((s->just_deps || s->output_type == TCC_OUTPUT_OBJ) && !s->option_r && *ext)
- strcpy(ext, ".obj");
- else
- strcpy(buf, "a.out");
- return tcc_strdup(buf);
-}
-
-static unsigned getclock_ms(void)
-{
-#ifdef _WIN32
- return GetTickCount();
-#else
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return tv.tv_sec*1000 + (tv.tv_usec+500)/1000;
-#endif
-}
-
-int main(int argc0, char **argv0)
-{
- TCCState *s, *s1;
- int ret, opt, n = 0, t = 0, done;
- unsigned start_time = 0, end_time = 0;
- const char *first_file;
- int argc; char **argv;
- FILE *ppfp = stdout;
-
-redo:
- argc = argc0, argv = argv0;
- s = s1 = tcc_new();
-#ifdef CONFIG_TCC_SWITCHES /* predefined options */
- tcc_set_options(s, CONFIG_TCC_SWITCHES);
-#endif
- opt = tcc_parse_args(s, &argc, &argv, 1);
- if (opt < 0)
- return 1;
-
- if (n == 0) {
- if (opt == OPT_HELP) {
- fputs(help, stdout);
- if (!s->verbose)
- return 0;
- ++opt;
- }
- if (opt == OPT_HELP2) {
- fputs(help2, stdout);
- return 0;
- }
- if (opt == OPT_M32 || opt == OPT_M64)
- return tcc_tool_cross(s, argv, opt);
- if (s->verbose)
- printf("%s", version);
- if (opt == OPT_AR)
- return tcc_tool_ar(s, argc, argv);
- if (opt == OPT_V)
- return 0;
- if (opt == OPT_PRINT_DIRS) {
- /* initialize search dirs */
- set_environment(s);
- tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
- print_search_dirs(s);
- return 0;
- }
-
- if (s->nb_files == 0) {
- tcc_error_noabort("no input files");
- } else if (s->output_type == TCC_OUTPUT_PREPROCESS) {
- if (s->outfile && 0!=strcmp("-",s->outfile)) {
- ppfp = fopen(s->outfile, "wb");
- if (!ppfp)
- tcc_error_noabort("could not write '%s'", s->outfile);
- }
- } else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
- if (s->nb_libraries)
- tcc_error_noabort("cannot specify libraries with -c");
- else if (s->nb_files > 1 && s->outfile)
- tcc_error_noabort("cannot specify output file with -c many files");
- }
- if (s->nb_errors)
- return 1;
- if (s->do_bench)
- start_time = getclock_ms();
- }
-
- set_environment(s);
- if (s->output_type == 0)
- s->output_type = TCC_OUTPUT_EXE;
- tcc_set_output_type(s, s->output_type);
- s->ppfp = ppfp;
-
- if ((s->output_type == TCC_OUTPUT_MEMORY
- || s->output_type == TCC_OUTPUT_PREPROCESS)
- && (s->dflag & 16)) { /* -dt option */
- if (t)
- s->dflag |= 32;
- s->run_test = ++t;
- if (n)
- --n;
- }
-
- /* compile or add each files or library */
- first_file = NULL;
- do {
- struct filespec *f = s->files[n];
- s->filetype = f->type;
- if (f->type & AFF_TYPE_LIB) {
- ret = tcc_add_library(s, f->name);
- } else {
- if (1 == s->verbose)
- printf("-> %s\n", f->name);
- if (!first_file)
- first_file = f->name;
- ret = tcc_add_file(s, f->name);
- }
- } while (++n < s->nb_files
- && 0 == ret
- && (s->output_type != TCC_OUTPUT_OBJ || s->option_r));
-
- if (s->do_bench)
- end_time = getclock_ms();
-
- if (s->run_test) {
- t = 0;
- } else if (s->output_type == TCC_OUTPUT_PREPROCESS) {
- ;
- } else if (0 == ret) {
- if (s->output_type == TCC_OUTPUT_MEMORY) {
- } else {
- if (!s->outfile)
- s->outfile = default_outputfile(s, first_file);
- if (!s->just_deps)
- ret = tcc_output_file(s, s->outfile);
- if (!ret && s->gen_deps)
- gen_makedeps(s, s->outfile, s->deps_outfile);
- }
- }
-
- done = 1;
- if (t)
- done = 0; /* run more tests with -dt -run */
- else if (ret) {
- if (s->nb_errors)
- ret = 1;
- /* else keep the original exit code from tcc_run() */
- } else if (n < s->nb_files)
- done = 0; /* compile more files with -c */
- else if (s->do_bench)
- tcc_print_stats(s, end_time - start_time);
-
- tcc_delete(s);
-
- if (!done)
- goto redo;
- if (ppfp && ppfp != stdout)
- fclose(ppfp);
- return ret;
-}
diff --git a/tcc/Makefile.am b/tcc/Makefile.am
new file mode 100644
index 00000000..a268a1df
--- /dev/null
+++ b/tcc/Makefile.am
@@ -0,0 +1,5 @@
+bin_PROGRAMS = tcc
+
+tcc_SOURCES = tcc.c tcctools.c
+tcc_LDADD = ../libtcc/libtcc.a
+tcc_CPPFLAGS = -I$(top_srcdir)
diff --git a/tcc/tcc.c b/tcc/tcc.c
new file mode 100644
index 00000000..0d97bb3b
--- /dev/null
+++ b/tcc/tcc.c
@@ -0,0 +1,314 @@
+/*
+ * TCC - Tiny C Compiler
+ *
+ * Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+#include "libtcc/tcc.h"
+#include "tcctools.h"
+
+static const char HELP_STR[] =
+ "Tiny C Compiler "PACKAGE_VERSION" - Copyright (C) 2001-2006 Fabrice Bellard\n"
+ "Usage: tcc [options...] [-o outfile] [-c] infile(s)...\n"
+ " tcc [options...] -run infile (or --) [arguments...]\n"
+ "General options:\n"
+ " -c compile only - generate an object file\n"
+ " -o outfile set output filename\n"
+ " -run run compiled source\n"
+ " -fflag set or reset (with 'no-' prefix) 'flag' (see tcc -hh)\n"
+ " -Wwarning set or reset (with 'no-' prefix) 'warning' (see tcc -hh)\n"
+ " -w disable all warnings\n"
+ " -v --version show version\n"
+ " -vv show search paths or loaded files\n"
+ " -h -hh show this, show more help\n"
+ " -bench show compilation statistics\n"
+ " - use stdin pipe as infile\n"
+ " @listfile read arguments from listfile\n"
+ "Preprocessor options:\n"
+ " -Idir add include path 'dir'\n"
+ " -Dsym[=val] define 'sym' with value 'val'\n"
+ " -Usym undefine 'sym'\n"
+ " -E preprocess only\n"
+ "Linker options:\n"
+ " -Ldir add library path 'dir'\n"
+ " -llib link with dynamic or static library 'lib'\n"
+ " -r generate (relocatable) object file\n"
+ " -shared generate a shared library/dll\n"
+ " -rdynamic export all global symbols to dynamic linker\n"
+ " -soname set name for shared library to be used at runtime\n"
+ " -Wl,-opt[=val] set linker option (see tcc -hh)\n"
+ "Misc. options:\n"
+ " -std=version define __STDC_VERSION__ according to version (c11/gnu11)\n"
+ " -x[c|a|b|n] specify type of the next infile (C,ASM,BIN,NONE)\n"
+ " -nostdinc do not use standard system include paths\n"
+ " -nostdlib do not link with standard crt and libraries\n"
+ " -Bdir set tcc's private include/library dir\n"
+ " -M[M]D generate make dependency file [ignore system files]\n"
+ " -M[M] as above but no other output\n"
+ " -MF file specify dependency file name\n"
+ "Tools:\n"
+ " create library : tcc -ar [crstvx] lib [files]\n"
+ ;
+
+static const char HELP_MORE_STR[] =
+ "Tiny C Compiler "PACKAGE_VERSION" - More Options\n"
+ "Special options:\n"
+ " -P -P1 with -E: no/alternative #line output\n"
+ " -dD -dM with -E: output #define directives\n"
+ " -pthread same as -D_REENTRANT and -lpthread\n"
+ " -On same as -D__OPTIMIZE__ for n > 0\n"
+ " -Wp,-opt same as -opt\n"
+ " -include file include 'file' above each input file\n"
+ " -isystem dir add 'dir' to system include path\n"
+ " -static link to static libraries (not recommended)\n"
+ " -dumpversion print version\n"
+ " -print-search-dirs print search paths\n"
+ "Ignored options:\n"
+ " -arch -C --param -pedantic -pipe -s -traditional\n"
+ "-W[no-]... warnings:\n"
+ " all turn on some (*) warnings\n"
+ " error[=warning] stop after warning (any or specified)\n"
+ " write-strings strings are const\n"
+ " unsupported warn about ignored options, pragmas, etc.\n"
+ " implicit-function-declaration warn for missing prototype (*)\n"
+ " discarded-qualifiers warn when const is dropped (*)\n"
+ "-f[no-]... flags:\n"
+ " unsigned-char default char is unsigned\n"
+ " signed-char default char is signed\n"
+ " common use common section instead of bss\n"
+ " leading-underscore decorate extern symbols\n"
+ " ms-extensions allow anonymous struct in struct\n"
+ " dollars-in-identifiers allow '$' in C symbols\n"
+ " reverse-funcargs evaluate function arguments right to left\n"
+ " gnu89-inline 'extern inline' is like 'static inline'\n"
+ " asynchronous-unwind-tables create eh_frame section [on]\n"
+ "-m... target specific options:\n"
+ " ms-bitfields use MSVC bitfield layout\n"
+ "-Wl,... linker options:\n"
+ " -nostdlib do not link with standard crt/libs\n"
+ " -[no-]whole-archive load lib(s) fully/only as needed\n"
+ " -export-all-symbols same as -rdynamic\n"
+ " -export-dynamic same as -rdynamic\n"
+ " -image-base= -Ttext= set base address of executable\n"
+ " -section-alignment= set section alignment in executable\n"
+ " -rpath= set dynamic library search path\n"
+ " -enable-new-dtags set DT_RUNPATH instead of DT_RPATH\n"
+ " -soname= set DT_SONAME elf tag\n"
+ " -Bsymbolic set DT_SYMBOLIC elf tag\n"
+ " -oformat=[coff,binary] set executable output format\n"
+ " -init= -fini= -Map= -as-needed -O (ignored)\n"
+ "Predefined macros:\n"
+ " tcc -E -dM - < /dev/null\n"
+ "See also the manual for more details.\n"
+ ;
+
+static const char VERSION_STR[] =
+ "tcc version "PACKAGE_VERSION" (i386)\n";
+
+static void print_dirs(const char *msg, char **paths, int nb_paths)
+{
+ int i;
+ printf("%s:\n%s", msg, nb_paths ? "" : " -\n");
+ for(i = 0; i < nb_paths; i++)
+ printf(" %s\n", paths[i]);
+}
+
+static void print_search_dirs(TCCState *s)
+{
+ printf("install: %s\n", s->tcc_lib_path);
+ /* print_dirs("programs", NULL, 0); */
+ print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths);
+ print_dirs("libraries", s->library_paths, s->nb_library_paths);
+ printf("libtcc1:\n %s/%s\n", s->library_paths[0], CONFIG_TCC_CROSSPREFIX TCC_LIBTCC1);
+ print_dirs("crt", s->crt_paths, s->nb_crt_paths);
+ printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s));
+}
+
+static void set_environment(TCCState *s)
+{
+ char * path;
+
+ path = getenv("C_INCLUDE_PATH");
+ if(path != NULL) {
+ tcc_add_sysinclude_path(s, path);
+ }
+ path = getenv("CPATH");
+ if(path != NULL) {
+ tcc_add_include_path(s, path);
+ }
+ path = getenv("LIBRARY_PATH");
+ if(path != NULL) {
+ tcc_add_library_path(s, path);
+ }
+}
+
+static char *default_outputfile(TCCState *s, const char *first_file)
+{
+ char buf[1024];
+ char *ext;
+ const char *name = "a";
+
+ if (first_file && strcmp(first_file, "-"))
+ name = tcc_basename(first_file);
+ snprintf(buf, sizeof(buf), "%s", name);
+ ext = tcc_fileextension(buf);
+ if ((s->just_deps || s->output_type == TCC_OUTPUT_OBJ) && !s->option_r && *ext)
+ strcpy(ext, ".obj");
+ else
+ strcpy(buf, "a.out");
+ return tcc_strdup(buf);
+}
+
+static unsigned getclock_ms(void)
+{
+#ifdef _WIN32
+ return GetTickCount();
+#else
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return tv.tv_sec*1000 + (tv.tv_usec+500)/1000;
+#endif
+}
+
+int main(int argc0, char **argv0)
+{
+ TCCState *s, *s1;
+ int ret, opt, n = 0, t = 0, done;
+ unsigned start_time = 0, end_time = 0;
+ const char *first_file;
+ int argc; char **argv;
+ FILE *ppfp = stdout;
+
+redo:
+ argc = argc0, argv = argv0;
+ s = s1 = tcc_new();
+#ifdef CONFIG_TCC_SWITCHES /* predefined options */
+ tcc_set_options(s, CONFIG_TCC_SWITCHES);
+#endif
+ opt = tcc_parse_args(s, &argc, &argv, 1);
+ if (opt < 0)
+ return 1;
+
+ if (n == 0) {
+ if (opt == OPT_HELP) {
+ fputs(HELP_STR, stdout);
+ if (!s->verbose)
+ return 0;
+ ++opt;
+ }
+ if (opt == OPT_HELP2) {
+ fputs(HELP_MORE_STR, stdout);
+ return 0;
+ }
+ if (opt == OPT_M32 || opt == OPT_M64)
+ return tcc_tool_cross(s, argv, opt);
+ if (s->verbose)
+ printf("%s", VERSION_STR);
+ if (opt == OPT_AR)
+ return tcc_tool_ar(s, argc, argv);
+ if (opt == OPT_V)
+ return 0;
+ if (opt == OPT_PRINT_DIRS) {
+ /* initialize search dirs */
+ set_environment(s);
+ tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
+ print_search_dirs(s);
+ return 0;
+ }
+
+ if (s->nb_files == 0) {
+ tcc_error_noabort("no input files");
+ } else if (s->output_type == TCC_OUTPUT_PREPROCESS) {
+ if (s->outfile && 0!=strcmp("-",s->outfile)) {
+ ppfp = fopen(s->outfile, "wb");
+ if (!ppfp)
+ tcc_error_noabort("could not write '%s'", s->outfile);
+ }
+ } else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
+ if (s->nb_libraries)
+ tcc_error_noabort("cannot specify libraries with -c");
+ else if (s->nb_files > 1 && s->outfile)
+ tcc_error_noabort("cannot specify output file with -c many files");
+ }
+ if (s->nb_errors)
+ return 1;
+ if (s->do_bench)
+ start_time = getclock_ms();
+ }
+
+ set_environment(s);
+ if (s->output_type == 0)
+ s->output_type = TCC_OUTPUT_EXE;
+ tcc_set_output_type(s, s->output_type);
+ s->ppfp = ppfp;
+
+ /* compile or add each files or library */
+ first_file = NULL;
+ do {
+ struct filespec *f = s->files[n];
+ s->filetype = f->type;
+ if (f->type & AFF_TYPE_LIB) {
+ ret = tcc_add_library(s, f->name);
+ } else {
+ if (1 == s->verbose)
+ printf("-> %s\n", f->name);
+ if (!first_file)
+ first_file = f->name;
+ ret = tcc_add_file(s, f->name);
+ }
+ } while (++n < s->nb_files
+ && 0 == ret
+ && (s->output_type != TCC_OUTPUT_OBJ || s->option_r));
+
+ if (s->do_bench)
+ end_time = getclock_ms();
+
+ if (s->output_type == TCC_OUTPUT_PREPROCESS) {
+ ;
+ } else if (0 == ret) {
+ if (s->output_type == TCC_OUTPUT_MEMORY) {
+ } else {
+ if (!s->outfile)
+ s->outfile = default_outputfile(s, first_file);
+ if (!s->just_deps)
+ ret = tcc_output_file(s, s->outfile);
+ if (!ret && s->gen_deps)
+ gen_makedeps(s, s->outfile, s->deps_outfile);
+ }
+ }
+
+ done = 1;
+ if (t)
+ done = 0; /* run more tests with -dt -run */
+ else if (ret) {
+ if (s->nb_errors)
+ ret = 1;
+ /* else keep the original exit code from tcc_run() */
+ } else if (n < s->nb_files)
+ done = 0; /* compile more files with -c */
+ else if (s->do_bench)
+ tcc_print_stats(s, end_time - start_time);
+
+ tcc_delete(s);
+
+ if (!done)
+ goto redo;
+ if (ppfp && ppfp != stdout)
+ fclose(ppfp);
+ return ret;
+}
diff --git a/tcc/tcc_new.c b/tcc/tcc_new.c
new file mode 100644
index 00000000..db8e12b0
--- /dev/null
+++ b/tcc/tcc_new.c
@@ -0,0 +1,134 @@
+/*
+ * TCC - Tiny C Compiler
+ *
+ * Copyright (c) 2001-2004 Fabrice Bellard
+ * Copyright (c) 2025 d0p1
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include "libtcc.h"
+
+static const char help_str[] =
+ "Tiny C Compiler "PACKAGE_VERSION" - Copyright (C) 2001-2006 Fabrice Bellard\n"
+ "Usage: tcc [options...] [-o outfile] [-c] infile(s)...\n"
+ "General options:\n"
+ " -c compile only - generate an object file\n"
+ " -o outfile set output filename\n"
+ " -run run compiled source\n"
+ " -fflag set or reset (with 'no-' prefix) 'flag' (see tcc -hh)\n"
+ " -Wwarning set or reset (with 'no-' prefix) 'warning' (see tcc -hh)\n"
+ " -w disable all warnings\n"
+ " -v --version show version\n"
+ " -vv show search paths or loaded files\n"
+ " -h -hh show this, show more help\n"
+ " -bench show compilation statistics\n"
+ " - use stdin pipe as infile\n"
+ " @listfile read arguments from listfile\n"
+ "Preprocessor options:\n"
+ " -Idir add include path 'dir'\n"
+ " -Dsym[=val] define 'sym' with value 'val'\n"
+ " -Usym undefine 'sym'\n"
+ " -E preprocess only\n"
+ "Linker options:\n"
+ " -Ldir add library path 'dir'\n"
+ " -llib link with dynamic or static library 'lib'\n"
+ " -r generate (relocatable) object file\n"
+ " -rdynamic export all global symbols to dynamic linker\n"
+ " -soname set name for shared library to be used at runtime\n"
+ " -Wl,-opt[=val] set linker option (see tcc -hh)\n"
+ "Debugger options:\n"
+ " -g generate stab runtime debug info\n"
+ " -gdwarf[-x] generate dwarf runtime debug info\n"
+ "Misc. options:\n"
+ " -std=version define __STDC_VERSION__ according to version (c11/gnu11)\n"
+ " -x[c|a|b|n] specify type of the next infile (C,ASM,BIN,NONE)\n"
+ " -nostdinc do not use standard system include paths\n"
+ " -nostdlib do not link with standard crt and libraries\n"
+ " -Bdir set tcc's private include/library dir\n"
+ " -M[M]D generate make dependency file [ignore system files]\n"
+ " -M[M] as above but no other output\n"
+ " -MF file specify dependency file name\n"
+ "Tools:\n"
+ " create library : tcc -ar [crstvx] lib [files]\n"
+ ;
+
+static const char help_more_str[] =
+ "Tiny C Compiler "PACKAGE_VERSION" - More Options\n"
+ "Special options:\n"
+ " -P -P1 with -E: no/alternative #line output\n"
+ " -dD -dM with -E: output #define directives\n"
+ " -pthread same as -D_REENTRANT and -lpthread\n"
+ " -On same as -D__OPTIMIZE__ for n > 0\n"
+ " -Wp,-opt same as -opt\n"
+ " -include file include 'file' above each input file\n"
+ " -isystem dir add 'dir' to system include path\n"
+ " -static link to static libraries (not recommended)\n"
+ " -dumpversion print version\n"
+ " -print-search-dirs print search paths\n"
+ " -dt with -run/-E: auto-define 'test_...' macros\n"
+ "Ignored options:\n"
+ " -arch -C --param -pedantic -pipe -s -traditional\n"
+ "-W[no-]... warnings:\n"
+ " all turn on some (*) warnings\n"
+ " error[=warning] stop after warning (any or specified)\n"
+ " write-strings strings are const\n"
+ " unsupported warn about ignored options, pragmas, etc.\n"
+ " implicit-function-declaration warn for missing prototype (*)\n"
+ " discarded-qualifiers warn when const is dropped (*)\n"
+ "-f[no-]... flags:\n"
+ " unsigned-char default char is unsigned\n"
+ " signed-char default char is signed\n"
+ " common use common section instead of bss\n"
+ " leading-underscore decorate extern symbols\n"
+ " ms-extensions allow anonymous struct in struct\n"
+ " dollars-in-identifiers allow '$' in C symbols\n"
+ " reverse-funcargs evaluate function arguments right to left\n"
+ " gnu89-inline 'extern inline' is like 'static inline'\n"
+ " asynchronous-unwind-tables create eh_frame section [on]\n"
+ " test-coverage create code coverage code\n"
+ "-m... target specific options:\n"
+ " ms-bitfields use MSVC bitfield layout\n"
+ "-Wl,... linker options:\n"
+ " -nostdlib do not link with standard crt/libs\n"
+ " -[no-]whole-archive load lib(s) fully/only as needed\n"
+ " -export-all-symbols same as -rdynamic\n"
+ " -export-dynamic same as -rdynamic\n"
+ " -image-base= -Ttext= set base address of executable\n"
+ " -section-alignment= set section alignment in executable\n"
+ " -rpath= set dynamic library search path\n"
+ " -enable-new-dtags set DT_RUNPATH instead of DT_RPATH\n"
+ " -soname= set DT_SONAME elf tag\n"
+ " -Bsymbolic set DT_SYMBOLIC elf tag\n"
+ " -oformat=[coff,binary] set executable output format\n"
+ " -init= -fini= -Map= -as-needed -O (ignored)\n"
+ "Predefined macros:\n"
+ " tcc -E -dM - < /dev/null\n"
+ "See also the manual for more details.\n"
+ ;
+
+static const char version_str[] = "tcc version "PACKAGE_VERSION" (i386)\n";
+
+int
+main(int argc, char *argv[])
+{
+ TCCState *s;
+}
\ No newline at end of file
diff --git a/tcctools.c b/tcc/tcctools.c
similarity index 99%
rename from tcctools.c
rename to tcc/tcctools.c
index eccb22af..e36a388a 100644
--- a/tcctools.c
+++ b/tcc/tcctools.c
@@ -28,7 +28,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#include "tcc.h"
+#include "libtcc/tcc.h"
//#define ARMAG "!\n"
#define ARFMAG "`\n"
diff --git a/tcc/tcctools.h b/tcc/tcctools.h
new file mode 100644
index 00000000..bcb0a7cf
--- /dev/null
+++ b/tcc/tcctools.h
@@ -0,0 +1,10 @@
+#ifndef TCC_TCCTOOLS_H
+# define TCC_TCCTOOLS_H 1
+
+# include "libtcc/libtcc.h"
+
+int tcc_tool_ar(TCCState *s1, int argc, char **argv);
+int tcc_tool_cross(TCCState *s1, char **argv, int target);
+int gen_makedeps(TCCState *s1, const char *target, const char *filename);
+
+#endif /* !TCC_TCCTOOLS_H */
\ No newline at end of file
diff --git a/tccdbg.c b/tccdbg.c
deleted file mode 100644
index 711f1871..00000000
--- a/tccdbg.c
+++ /dev/null
@@ -1,2482 +0,0 @@
-/*
- * TCC - Tiny C Compiler
- *
- * Copyright (c) 2001-2004 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "tcc.h"
-
-/* stab debug support */
-
-static const struct {
- int type;
- int size;
- int encoding;
- const char *name;
-} default_debug[] = {
- { VT_INT, 4, DW_ATE_signed, "int:t1=r1;-2147483648;2147483647;" },
- { VT_BYTE, 1, DW_ATE_signed_char, "char:t2=r2;0;127;" },
-#if LONG_SIZE == 4
- { VT_LONG | VT_INT, 4, DW_ATE_signed, "long int:t3=r3;-2147483648;2147483647;" },
-#else
- { VT_LLONG | VT_LONG, 8, DW_ATE_signed, "long int:t3=r3;-9223372036854775808;9223372036854775807;" },
-#endif
- { VT_INT | VT_UNSIGNED, 4, DW_ATE_unsigned, "unsigned int:t4=r4;0;037777777777;" },
-#if LONG_SIZE == 4
- { VT_LONG | VT_INT | VT_UNSIGNED, 4, DW_ATE_unsigned, "long unsigned int:t5=r5;0;037777777777;" },
-#else
- /* use octal instead of -1 so size_t works (-gstabs+ in gcc) */
- { VT_LLONG | VT_LONG | VT_UNSIGNED, 8, DW_ATE_unsigned, "long unsigned int:t5=r5;0;01777777777777777777777;" },
-#endif
- { VT_QLONG, 16, DW_ATE_signed, "__int128:t6=r6;0;-1;" },
- { VT_QLONG | VT_UNSIGNED, 16, DW_ATE_unsigned, "__int128 unsigned:t7=r7;0;-1;" },
- { VT_LLONG, 8, DW_ATE_signed, "long long int:t8=r8;-9223372036854775808;9223372036854775807;" },
- { VT_LLONG | VT_UNSIGNED, 8, DW_ATE_unsigned, "long long unsigned int:t9=r9;0;01777777777777777777777;" },
- { VT_SHORT, 2, DW_ATE_signed, "short int:t10=r10;-32768;32767;" },
- { VT_SHORT | VT_UNSIGNED, 2, DW_ATE_unsigned, "short unsigned int:t11=r11;0;65535;" },
- { VT_BYTE | VT_DEFSIGN, 1, DW_ATE_signed_char, "signed char:t12=r12;-128;127;" },
- { VT_BYTE | VT_DEFSIGN | VT_UNSIGNED, 1, DW_ATE_unsigned_char, "unsigned char:t13=r13;0;255;" },
- { VT_FLOAT, 4, DW_ATE_float, "float:t14=r1;4;0;" },
- { VT_DOUBLE, 8, DW_ATE_float, "double:t15=r1;8;0;" },
-#ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
- { VT_DOUBLE | VT_LONG, 8, DW_ATE_float, "long double:t16=r1;8;0;" },
-#else
- { VT_LDOUBLE, 16, DW_ATE_float, "long double:t16=r1;16;0;" },
-#endif
- { -1, -1, -1, "_Float32:t17=r1;4;0;" },
- { -1, -1, -1, "_Float64:t18=r1;8;0;" },
- { -1, -1, -1, "_Float128:t19=r1;16;0;" },
- { -1, -1, -1, "_Float32x:t20=r1;8;0;" },
- { -1, -1, -1, "_Float64x:t21=r1;16;0;" },
- { -1, -1, -1, "_Decimal32:t22=r1;4;0;" },
- { -1, -1, -1, "_Decimal64:t23=r1;8;0;" },
- { -1, -1, -1, "_Decimal128:t24=r1;16;0;" },
- /* if default char is unsigned */
- { VT_BYTE | VT_UNSIGNED, 1, DW_ATE_unsigned_char, "unsigned char:t25=r25;0;255;" },
- /* boolean type */
- { VT_BOOL, 1, DW_ATE_boolean, "bool:t26=r26;0;255;" },
-#if LONG_SIZE == 4
- { VT_VOID, 1, DW_ATE_unsigned_char, "void:t27=27" },
-#else
- /* bitfields use these */
- { VT_LONG | VT_INT, 8, DW_ATE_signed, "long int:t27=r27;-9223372036854775808;9223372036854775807;" },
- { VT_LONG | VT_INT | VT_UNSIGNED, 8, DW_ATE_unsigned, "long unsigned int:t28=r28;0;01777777777777777777777;" },
- { VT_VOID, 1, DW_ATE_unsigned_char, "void:t29=29" },
-#endif
-};
-
-#define N_DEFAULT_DEBUG (sizeof (default_debug) / sizeof (default_debug[0]))
-
-/* dwarf debug */
-
-#define DWARF_LINE_BASE -5
-#define DWARF_LINE_RANGE 14
-#define DWARF_OPCODE_BASE 13
-
-#if defined TCC_TARGET_ARM64
-#define DWARF_MIN_INSTR_LEN 4
-#elif defined TCC_TARGET_ARM
-#define DWARF_MIN_INSTR_LEN 2
-#else
-#define DWARF_MIN_INSTR_LEN 1
-#endif
-
-#define DWARF_ABBREV_COMPILE_UNIT 1
-#define DWARF_ABBREV_BASE_TYPE 2
-#define DWARF_ABBREV_VARIABLE_EXTERNAL 3
-#define DWARF_ABBREV_VARIABLE_STATIC 4
-#define DWARF_ABBREV_VARIABLE_LOCAL 5
-#define DWARF_ABBREV_FORMAL_PARAMETER 6
-#define DWARF_ABBREV_POINTER 7
-#define DWARF_ABBREV_ARRAY_TYPE 8
-#define DWARF_ABBREV_SUBRANGE_TYPE 9
-#define DWARF_ABBREV_TYPEDEF 10
-#define DWARF_ABBREV_ENUMERATOR_SIGNED 11
-#define DWARF_ABBREV_ENUMERATOR_UNSIGNED 12
-#define DWARF_ABBREV_ENUMERATION_TYPE 13
-#define DWARF_ABBREV_MEMBER 14
-#define DWARF_ABBREV_MEMBER_BF 15
-#define DWARF_ABBREV_STRUCTURE_TYPE 16
-#define DWARF_ABBREV_STRUCTURE_EMPTY_TYPE 17
-#define DWARF_ABBREV_UNION_TYPE 18
-#define DWARF_ABBREV_UNION_EMPTY_TYPE 19
-#define DWARF_ABBREV_SUBPROGRAM_EXTERNAL 20
-#define DWARF_ABBREV_SUBPROGRAM_STATIC 21
-#define DWARF_ABBREV_LEXICAL_BLOCK 22
-#define DWARF_ABBREV_LEXICAL_EMPTY_BLOCK 23
-#define DWARF_ABBREV_SUBROUTINE_TYPE 24
-#define DWARF_ABBREV_SUBROUTINE_EMPTY_TYPE 25
-#define DWARF_ABBREV_FORMAL_PARAMETER2 26
-
-/* all entries should have been generated with dwarf_uleb128 except
- has_children. All values are currently below 128 so this currently
- works. */
-static const unsigned char dwarf_abbrev_init[] = {
- DWARF_ABBREV_COMPILE_UNIT, DW_TAG_compile_unit, 1,
- DW_AT_producer, DW_FORM_strp,
- DW_AT_language, DW_FORM_data1,
- DW_AT_name, DW_FORM_line_strp,
- DW_AT_comp_dir, DW_FORM_line_strp,
- DW_AT_low_pc, DW_FORM_addr,
-#if PTR_SIZE == 4
- DW_AT_high_pc, DW_FORM_data4,
-#else
- DW_AT_high_pc, DW_FORM_data8,
-#endif
- DW_AT_stmt_list, DW_FORM_sec_offset,
- 0, 0,
- DWARF_ABBREV_BASE_TYPE, DW_TAG_base_type, 0,
- DW_AT_byte_size, DW_FORM_udata,
- DW_AT_encoding, DW_FORM_data1,
- DW_AT_name, DW_FORM_strp,
- 0, 0,
- DWARF_ABBREV_VARIABLE_EXTERNAL, DW_TAG_variable, 0,
- DW_AT_name, DW_FORM_strp,
- DW_AT_decl_file, DW_FORM_udata,
- DW_AT_decl_line, DW_FORM_udata,
- DW_AT_type, DW_FORM_ref4,
- DW_AT_external, DW_FORM_flag,
- DW_AT_location, DW_FORM_exprloc,
- 0, 0,
- DWARF_ABBREV_VARIABLE_STATIC, DW_TAG_variable, 0,
- DW_AT_name, DW_FORM_strp,
- DW_AT_decl_file, DW_FORM_udata,
- DW_AT_decl_line, DW_FORM_udata,
- DW_AT_type, DW_FORM_ref4,
- DW_AT_location, DW_FORM_exprloc,
- 0, 0,
- DWARF_ABBREV_VARIABLE_LOCAL, DW_TAG_variable, 0,
- DW_AT_name, DW_FORM_strp,
- DW_AT_type, DW_FORM_ref4,
- DW_AT_location, DW_FORM_exprloc,
- 0, 0,
- DWARF_ABBREV_FORMAL_PARAMETER, DW_TAG_formal_parameter, 0,
- DW_AT_name, DW_FORM_strp,
- DW_AT_type, DW_FORM_ref4,
- DW_AT_location, DW_FORM_exprloc,
- 0, 0,
- DWARF_ABBREV_POINTER, DW_TAG_pointer_type, 0,
- DW_AT_byte_size, DW_FORM_data1,
- DW_AT_type, DW_FORM_ref4,
- 0, 0,
- DWARF_ABBREV_ARRAY_TYPE, DW_TAG_array_type, 1,
- DW_AT_type, DW_FORM_ref4,
- DW_AT_sibling, DW_FORM_ref4,
- 0, 0,
- DWARF_ABBREV_SUBRANGE_TYPE, DW_TAG_subrange_type, 0,
- DW_AT_type, DW_FORM_ref4,
- DW_AT_upper_bound, DW_FORM_udata,
- 0, 0,
- DWARF_ABBREV_TYPEDEF, DW_TAG_typedef, 0,
- DW_AT_name, DW_FORM_strp,
- DW_AT_decl_file, DW_FORM_udata,
- DW_AT_decl_line, DW_FORM_udata,
- DW_AT_type, DW_FORM_ref4,
- 0, 0,
- DWARF_ABBREV_ENUMERATOR_SIGNED, DW_TAG_enumerator, 0,
- DW_AT_name, DW_FORM_strp,
- DW_AT_const_value, DW_FORM_sdata,
- 0, 0,
- DWARF_ABBREV_ENUMERATOR_UNSIGNED, DW_TAG_enumerator, 0,
- DW_AT_name, DW_FORM_strp,
- DW_AT_const_value, DW_FORM_udata,
- 0, 0,
- DWARF_ABBREV_ENUMERATION_TYPE, DW_TAG_enumeration_type, 1,
- DW_AT_name, DW_FORM_strp,
- DW_AT_encoding, DW_FORM_data1,
- DW_AT_byte_size, DW_FORM_data1,
- DW_AT_type, DW_FORM_ref4,
- DW_AT_decl_file, DW_FORM_udata,
- DW_AT_decl_line, DW_FORM_udata,
- DW_AT_sibling, DW_FORM_ref4,
- 0, 0,
- DWARF_ABBREV_MEMBER, DW_TAG_member, 0,
- DW_AT_name, DW_FORM_strp,
- DW_AT_decl_file, DW_FORM_udata,
- DW_AT_decl_line, DW_FORM_udata,
- DW_AT_type, DW_FORM_ref4,
- DW_AT_data_member_location, DW_FORM_udata,
- 0, 0,
- DWARF_ABBREV_MEMBER_BF, DW_TAG_member, 0,
- DW_AT_name, DW_FORM_strp,
- DW_AT_decl_file, DW_FORM_udata,
- DW_AT_decl_line, DW_FORM_udata,
- DW_AT_type, DW_FORM_ref4,
- DW_AT_bit_size, DW_FORM_udata,
- DW_AT_data_bit_offset, DW_FORM_udata,
- 0, 0,
- DWARF_ABBREV_STRUCTURE_TYPE, DW_TAG_structure_type, 1,
- DW_AT_name, DW_FORM_strp,
- DW_AT_byte_size, DW_FORM_udata,
- DW_AT_decl_file, DW_FORM_udata,
- DW_AT_decl_line, DW_FORM_udata,
- DW_AT_sibling, DW_FORM_ref4,
- 0, 0,
- DWARF_ABBREV_STRUCTURE_EMPTY_TYPE, DW_TAG_structure_type, 0,
- DW_AT_name, DW_FORM_strp,
- DW_AT_byte_size, DW_FORM_udata,
- DW_AT_decl_file, DW_FORM_udata,
- DW_AT_decl_line, DW_FORM_udata,
- 0, 0,
- DWARF_ABBREV_UNION_TYPE, DW_TAG_union_type, 1,
- DW_AT_name, DW_FORM_strp,
- DW_AT_byte_size, DW_FORM_udata,
- DW_AT_decl_file, DW_FORM_udata,
- DW_AT_decl_line, DW_FORM_udata,
- DW_AT_sibling, DW_FORM_ref4,
- 0, 0,
- DWARF_ABBREV_UNION_EMPTY_TYPE, DW_TAG_union_type, 0,
- DW_AT_name, DW_FORM_strp,
- DW_AT_byte_size, DW_FORM_udata,
- DW_AT_decl_file, DW_FORM_udata,
- DW_AT_decl_line, DW_FORM_udata,
- 0, 0,
- DWARF_ABBREV_SUBPROGRAM_EXTERNAL, DW_TAG_subprogram, 1,
- DW_AT_external, DW_FORM_flag,
- DW_AT_name, DW_FORM_strp,
- DW_AT_decl_file, DW_FORM_udata,
- DW_AT_decl_line, DW_FORM_udata,
- DW_AT_type, DW_FORM_ref4,
- DW_AT_low_pc, DW_FORM_addr,
-#if PTR_SIZE == 4
- DW_AT_high_pc, DW_FORM_data4,
-#else
- DW_AT_high_pc, DW_FORM_data8,
-#endif
- DW_AT_sibling, DW_FORM_ref4,
- DW_AT_frame_base, DW_FORM_exprloc,
- 0, 0,
- DWARF_ABBREV_SUBPROGRAM_STATIC, DW_TAG_subprogram, 1,
- DW_AT_name, DW_FORM_strp,
- DW_AT_decl_file, DW_FORM_udata,
- DW_AT_decl_line, DW_FORM_udata,
- DW_AT_type, DW_FORM_ref4,
- DW_AT_low_pc, DW_FORM_addr,
-#if PTR_SIZE == 4
- DW_AT_high_pc, DW_FORM_data4,
-#else
- DW_AT_high_pc, DW_FORM_data8,
-#endif
- DW_AT_sibling, DW_FORM_ref4,
- DW_AT_frame_base, DW_FORM_exprloc,
- 0, 0,
- DWARF_ABBREV_LEXICAL_BLOCK, DW_TAG_lexical_block, 1,
- DW_AT_low_pc, DW_FORM_addr,
-#if PTR_SIZE == 4
- DW_AT_high_pc, DW_FORM_data4,
-#else
- DW_AT_high_pc, DW_FORM_data8,
-#endif
- 0, 0,
- DWARF_ABBREV_LEXICAL_EMPTY_BLOCK, DW_TAG_lexical_block, 0,
- DW_AT_low_pc, DW_FORM_addr,
-#if PTR_SIZE == 4
- DW_AT_high_pc, DW_FORM_data4,
-#else
- DW_AT_high_pc, DW_FORM_data8,
-#endif
- 0, 0,
- DWARF_ABBREV_SUBROUTINE_TYPE, DW_TAG_subroutine_type, 1,
- DW_AT_type, DW_FORM_ref4,
- DW_AT_sibling, DW_FORM_ref4,
- 0, 0,
- DWARF_ABBREV_SUBROUTINE_EMPTY_TYPE, DW_TAG_subroutine_type, 0,
- DW_AT_type, DW_FORM_ref4,
- 0, 0,
- DWARF_ABBREV_FORMAL_PARAMETER2, DW_TAG_formal_parameter, 0,
- DW_AT_type, DW_FORM_ref4,
- 0, 0,
- 0
-};
-
-static const unsigned char dwarf_line_opcodes[] = {
- 0 ,1 ,1 ,1 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,1
-};
-
-/* ------------------------------------------------------------------------- */
-/* debug state */
-
-struct _tccdbg {
-
- int last_line_num, new_file;
- int section_sym;
-
- int debug_next_type;
-
- struct _debug_hash {
- int debug_type;
- Sym *type;
- } *debug_hash;
-
- struct _debug_anon_hash {
- Sym *type;
- int n_debug_type;
- int *debug_type;
- } *debug_anon_hash;
-
- int n_debug_hash;
- int n_debug_anon_hash;
-
- struct _debug_info {
- int start;
- int end;
- int n_sym;
- struct debug_sym {
- int type;
- unsigned long value;
- char *str;
- Section *sec;
- int sym_index;
- int info;
- int file;
- int line;
- } *sym;
- struct _debug_info *child, *next, *last, *parent;
- } *debug_info, *debug_info_root;
-
- struct {
- int info;
- int abbrev;
- int line;
- int str;
- int line_str;
- } dwarf_sym;
-
- struct {
- int start;
- int dir_size;
- char **dir_table;
- int filename_size;
- struct dwarf_filename_struct {
- int dir_entry;
- char *name;
- } *filename_table;
- int line_size;
- int line_max_size;
- unsigned char *line_data;
- int cur_file;
- int last_file;
- int last_pc;
- int last_line;
- } dwarf_line;
-
- struct {
- int start;
- Sym *func;
- int line;
- int base_type_used[N_DEFAULT_DEBUG];
- } dwarf_info;
-
- /* test coverage */
- struct {
- unsigned long offset;
- unsigned long last_file_name;
- unsigned long last_func_name;
- int ind;
- int line;
- } tcov_data;
-
-};
-
-#define last_line_num s1->dState->last_line_num
-#define new_file s1->dState->new_file
-#define section_sym s1->dState->section_sym
-#define debug_next_type s1->dState->debug_next_type
-#define debug_hash s1->dState->debug_hash
-#define debug_anon_hash s1->dState->debug_anon_hash
-#define n_debug_hash s1->dState->n_debug_hash
-#define n_debug_anon_hash s1->dState->n_debug_anon_hash
-#define debug_info s1->dState->debug_info
-#define debug_info_root s1->dState->debug_info_root
-#define dwarf_sym s1->dState->dwarf_sym
-#define dwarf_line s1->dState->dwarf_line
-#define dwarf_info s1->dState->dwarf_info
-#define tcov_data s1->dState->tcov_data
-
-#define FDE_ENCODING (DW_EH_PE_udata4 | DW_EH_PE_signed | DW_EH_PE_pcrel)
-
-/* ------------------------------------------------------------------------- */
-static void put_stabs(TCCState *s1, const char *str, int type, int other,
- int desc, unsigned long value);
-
-ST_FUNC void tcc_debug_new(TCCState *s1)
-{
- int shf = 0;
- if (!s1->dState)
- s1->dState = tcc_mallocz(sizeof *s1->dState);
-
-#ifdef CONFIG_TCC_BACKTRACE
- /* include stab info with standalone backtrace support */
- if (s1->do_debug && s1->output_type == TCC_OUTPUT_MEMORY)
- s1->do_backtrace = 1;
- if (s1->do_backtrace)
- shf = SHF_ALLOC; /* have debug data available at runtime */
-#endif
-
- if (s1->dwarf) {
- s1->dwlo = s1->nb_sections;
- dwarf_info_section =
- new_section(s1, ".debug_info", SHT_PROGBITS, shf);
- dwarf_abbrev_section =
- new_section(s1, ".debug_abbrev", SHT_PROGBITS, shf);
- dwarf_line_section =
- new_section(s1, ".debug_line", SHT_PROGBITS, shf);
- dwarf_aranges_section =
- new_section(s1, ".debug_aranges", SHT_PROGBITS, shf);
- shf |= SHF_MERGE | SHF_STRINGS;
- dwarf_str_section =
- new_section(s1, ".debug_str", SHT_PROGBITS, shf);
- dwarf_str_section->sh_entsize = 1;
- dwarf_info_section->sh_addralign =
- dwarf_abbrev_section->sh_addralign =
- dwarf_line_section->sh_addralign =
- dwarf_aranges_section->sh_addralign =
- dwarf_str_section->sh_addralign = 1;
- if (s1->dwarf >= 5) {
- dwarf_line_str_section =
- new_section(s1, ".debug_line_str", SHT_PROGBITS, shf);
- dwarf_line_str_section->sh_entsize = 1;
- dwarf_line_str_section->sh_addralign = 1;
- }
- s1->dwhi = s1->nb_sections;
- }
- else
- {
- stab_section = new_section(s1, ".stab", SHT_PROGBITS, shf);
- stab_section->sh_entsize = sizeof(Stab_Sym);
- stab_section->sh_addralign = sizeof ((Stab_Sym*)0)->n_value;
- stab_section->link = new_section(s1, ".stabstr", SHT_STRTAB, shf);
- /* put first entry */
- put_stabs(s1, "", 0, 0, 0, 0);
- }
-}
-
-/* put stab debug information */
-static void put_stabs(TCCState *s1, const char *str, int type, int other, int desc,
- unsigned long value)
-{
- Stab_Sym *sym;
-
- unsigned offset;
- if (type == N_SLINE
- && (offset = stab_section->data_offset)
- && (sym = (Stab_Sym*)(stab_section->data + offset) - 1)
- && sym->n_type == type
- && sym->n_value == value) {
- /* just update line_number in previous entry */
- sym->n_desc = desc;
- return;
- }
-
- sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
- if (str) {
- sym->n_strx = put_elf_str(stab_section->link, str);
- } else {
- sym->n_strx = 0;
- }
- sym->n_type = type;
- sym->n_other = other;
- sym->n_desc = desc;
- sym->n_value = value;
-}
-
-static void put_stabs_r(TCCState *s1, const char *str, int type, int other, int desc,
- unsigned long value, Section *sec, int sym_index)
-{
- put_elf_reloc(symtab_section, stab_section,
- stab_section->data_offset + 8,
- sizeof ((Stab_Sym*)0)->n_value == PTR_SIZE ? R_DATA_PTR : R_DATA_32,
- sym_index);
- put_stabs(s1, str, type, other, desc, value);
-}
-
-static void put_stabn(TCCState *s1, int type, int other, int desc, int value)
-{
- put_stabs(s1, NULL, type, other, desc, value);
-}
-
-/* ------------------------------------------------------------------------- */
-#define dwarf_data1(s,data) \
- (*(uint8_t*)section_ptr_add((s), 1) = (data))
-#define dwarf_data2(s,data) \
- write16le(section_ptr_add((s), 2), (data))
-#define dwarf_data4(s,data) \
- write32le(section_ptr_add((s), 4), (data))
-#define dwarf_data8(s,data) \
- write64le(section_ptr_add((s), 8), (data))
-
-static int dwarf_get_section_sym(Section *s)
-{
- TCCState *s1 = s->s1;
- return put_elf_sym(symtab_section, 0, 0,
- ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
- s->sh_num, NULL);
-}
-
-static void dwarf_reloc(Section *s, int sym, int rel)
-{
- TCCState *s1 = s->s1;
- put_elf_reloca(symtab_section, s, s->data_offset, rel, sym, 0);
-}
-
-static void dwarf_string(Section *s, Section *dw, int sym, const char *str)
-{
- TCCState *s1 = s->s1;
- int offset, len;
- char *ptr;
-
- len = strlen(str) + 1;
- offset = dw->data_offset;
- ptr = section_ptr_add(dw, len);
- memmove(ptr, str, len);
- put_elf_reloca(symtab_section, s, s->data_offset, R_DATA_32DW, sym,
- PTR_SIZE == 4 ? 0 : offset);
- dwarf_data4(s, PTR_SIZE == 4 ? offset : 0);
-}
-
-static void dwarf_strp(Section *s, const char *str)
-{
- TCCState *s1 = s->s1;
- dwarf_string(s, dwarf_str_section, dwarf_sym.str, str);
-}
-
-static void dwarf_line_strp(Section *s, const char *str)
-{
- TCCState *s1 = s->s1;
- dwarf_string(s, dwarf_line_str_section, dwarf_sym.line_str, str);
-}
-
-static void dwarf_line_op(TCCState *s1, unsigned char op)
-{
- if (dwarf_line.line_size >= dwarf_line.line_max_size) {
- dwarf_line.line_max_size += 1024;
- dwarf_line.line_data =
- (unsigned char *)tcc_realloc(dwarf_line.line_data,
- dwarf_line.line_max_size);
- }
- dwarf_line.line_data[dwarf_line.line_size++] = op;
-}
-
-static void dwarf_file(TCCState *s1)
-{
- int i, j;
- char *filename;
- int index_offset = s1->dwarf < 5;
-
- if (!strcmp(file->filename, "")) {
- dwarf_line.cur_file = 1;
- return;
- }
- filename = strrchr(file->filename, '/');
- if (filename == NULL) {
- for (i = 1; i < dwarf_line.filename_size; i++)
- if (dwarf_line.filename_table[i].dir_entry == 0 &&
- strcmp(dwarf_line.filename_table[i].name,
- file->filename) == 0) {
- dwarf_line.cur_file = i + index_offset;
- return;
- }
- i = -index_offset;
- filename = file->filename;
- }
- else {
- char *undo = filename;
- char *dir = file->filename;
-
- *filename++ = '\0';
- for (i = 0; i < dwarf_line.dir_size; i++)
- if (strcmp(dwarf_line.dir_table[i], dir) == 0) {
- for (j = 1; j < dwarf_line.filename_size; j++)
- if (dwarf_line.filename_table[j].dir_entry - index_offset
- == i &&
- strcmp(dwarf_line.filename_table[j].name,
- filename) == 0) {
- *undo = '/';
- dwarf_line.cur_file = j + index_offset;
- return;
- }
- break;
- }
- if (i == dwarf_line.dir_size) {
- dwarf_line.dir_size++;
- dwarf_line.dir_table =
- (char **) tcc_realloc(dwarf_line.dir_table,
- dwarf_line.dir_size *
- sizeof (char *));
- dwarf_line.dir_table[i] = tcc_strdup(dir);
- }
- *undo = '/';
- }
- dwarf_line.filename_table =
- (struct dwarf_filename_struct *)
- tcc_realloc(dwarf_line.filename_table,
- (dwarf_line.filename_size + 1) *
- sizeof (struct dwarf_filename_struct));
- dwarf_line.filename_table[dwarf_line.filename_size].dir_entry =
- i + index_offset;
- dwarf_line.filename_table[dwarf_line.filename_size].name =
- tcc_strdup(filename);
- dwarf_line.cur_file = dwarf_line.filename_size++ + index_offset;
- return;
-}
-
-#if 0
-static int dwarf_uleb128_size (unsigned long long value)
-{
- int size = 0;
-
- do {
- value >>= 7;
- size++;
- } while (value != 0);
- return size;
-}
-#endif
-
-static int dwarf_sleb128_size (long long value)
-{
- int size = 0;
- long long end = value >> 63;
- unsigned char last = end & 0x40;
- unsigned char byte;
-
- do {
- byte = value & 0x7f;
- value >>= 7;
- size++;
- } while (value != end || (byte & 0x40) != last);
- return size;
-}
-
-static void dwarf_uleb128 (Section *s, unsigned long long value)
-{
- do {
- unsigned char byte = value & 0x7f;
-
- value >>= 7;
- dwarf_data1(s, byte | (value ? 0x80 : 0));
- } while (value != 0);
-}
-
-static void dwarf_sleb128 (Section *s, long long value)
-{
- int more;
- long long end = value >> 63;
- unsigned char last = end & 0x40;
-
- do {
- unsigned char byte = value & 0x7f;
-
- value >>= 7;
- more = value != end || (byte & 0x40) != last;
- dwarf_data1(s, byte | (0x80 * more));
- } while (more);
-}
-
-static void dwarf_uleb128_op (TCCState *s1, unsigned long long value)
-{
- do {
- unsigned char byte = value & 0x7f;
-
- value >>= 7;
- dwarf_line_op(s1, byte | (value ? 0x80 : 0));
- } while (value != 0);
-}
-
-static void dwarf_sleb128_op (TCCState *s1, long long value)
-{
- int more;
- long long end = value >> 63;
- unsigned char last = end & 0x40;
-
- do {
- unsigned char byte = value & 0x7f;
-
- value >>= 7;
- more = value != end || (byte & 0x40) != last;
- dwarf_line_op(s1, byte | (0x80 * more));
- } while (more);
-}
-
-#if TCC_EH_FRAME
-ST_FUNC void tcc_eh_frame_start(TCCState *s1)
-{
- if (!s1->unwind_tables)
- return;
- eh_frame_section = new_section(s1, ".eh_frame", SHT_PROGBITS, SHF_ALLOC);
-
- s1->eh_start = eh_frame_section->data_offset;
- dwarf_data4(eh_frame_section, 0); // length
- dwarf_data4(eh_frame_section, 0); // CIE ID
- dwarf_data1(eh_frame_section, 1); // Version
- dwarf_data1(eh_frame_section, 'z'); // Augmentation String
- dwarf_data1(eh_frame_section, 'R');
- dwarf_data1(eh_frame_section, 0);
-#if defined TCC_TARGET_I386
- dwarf_uleb128(eh_frame_section, 1); // code_alignment_factor
- dwarf_sleb128(eh_frame_section, -4); // data_alignment_factor
- dwarf_uleb128(eh_frame_section, 8); // return address column
- dwarf_uleb128(eh_frame_section, 1); // Augmentation len
- dwarf_data1(eh_frame_section, FDE_ENCODING);
- dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
- dwarf_uleb128(eh_frame_section, 4); // r4 (esp)
- dwarf_uleb128(eh_frame_section, 4); // ofs 4
- dwarf_data1(eh_frame_section, DW_CFA_offset + 8); // r8 (eip)
- dwarf_uleb128(eh_frame_section, 1); // cfa-4
-#elif defined TCC_TARGET_X86_64
- dwarf_uleb128(eh_frame_section, 1); // code_alignment_factor
- dwarf_sleb128(eh_frame_section, -8); // data_alignment_factor
- dwarf_uleb128(eh_frame_section, 16); // return address column
- dwarf_uleb128(eh_frame_section, 1); // Augmentation len
- dwarf_data1(eh_frame_section, FDE_ENCODING);
- dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
- dwarf_uleb128(eh_frame_section, 7); // r7 (rsp)
- dwarf_uleb128(eh_frame_section, 8); // ofs 8
- dwarf_data1(eh_frame_section, DW_CFA_offset + 16); // r16 (rip)
- dwarf_uleb128(eh_frame_section, 1); // cfa-8
-#elif defined TCC_TARGET_ARM
- /* TODO: arm must be compiled with: -funwind-tables */
- /* arm also uses .ARM.extab and .ARM.exidx sections */
- dwarf_uleb128(eh_frame_section, 2); // code_alignment_factor
- dwarf_sleb128(eh_frame_section, -4); // data_alignment_factor
- dwarf_uleb128(eh_frame_section, 14); // return address column
- dwarf_uleb128(eh_frame_section, 1); // Augmentation len
- dwarf_data1(eh_frame_section, FDE_ENCODING);
- dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
- dwarf_uleb128(eh_frame_section, 13); // r13 (sp)
- dwarf_uleb128(eh_frame_section, 0); // ofs 0
-#elif defined TCC_TARGET_ARM64
- dwarf_uleb128(eh_frame_section, 4); // code_alignment_factor
- dwarf_sleb128(eh_frame_section, -8); // data_alignment_factor
- dwarf_uleb128(eh_frame_section, 30); // return address column
- dwarf_uleb128(eh_frame_section, 1); // Augmentation len
- dwarf_data1(eh_frame_section, FDE_ENCODING);
- dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
- dwarf_uleb128(eh_frame_section, 31); // x31 (sp)
- dwarf_uleb128(eh_frame_section, 0); // ofs 0
-#elif defined TCC_TARGET_RISCV64
- eh_frame_section->data[s1->eh_start + 8] = 3; // version = 3
- dwarf_uleb128(eh_frame_section, 1); // code_alignment_factor
- dwarf_sleb128(eh_frame_section, -4); // data_alignment_factor
- dwarf_uleb128(eh_frame_section, 1); // return address column
- dwarf_uleb128(eh_frame_section, 1); // Augmentation len
- dwarf_data1(eh_frame_section, FDE_ENCODING);
- dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
- dwarf_uleb128(eh_frame_section, 2); // r2 (sp)
- dwarf_uleb128(eh_frame_section, 0); // ofs 0
-#endif
- while ((eh_frame_section->data_offset - s1->eh_start) & 3)
- dwarf_data1(eh_frame_section, DW_CFA_nop);
- write32le(eh_frame_section->data + s1->eh_start, // length
- eh_frame_section->data_offset - s1->eh_start - 4);
-}
-
-static void tcc_debug_frame_end(TCCState *s1, int size)
-{
- int eh_section_sym;
- unsigned long fde_start;
-
- if (!eh_frame_section)
- return;
- eh_section_sym = dwarf_get_section_sym(text_section);
- fde_start = eh_frame_section->data_offset;
- dwarf_data4(eh_frame_section, 0); // length
- dwarf_data4(eh_frame_section,
- fde_start - s1->eh_start + 4); // CIE Pointer
-#if defined TCC_TARGET_I386
- dwarf_reloc(eh_frame_section, eh_section_sym, R_386_PC32);
-#elif defined TCC_TARGET_X86_64
- dwarf_reloc(eh_frame_section, eh_section_sym, R_X86_64_PC32);
-#elif defined TCC_TARGET_ARM
- dwarf_reloc(eh_frame_section, eh_section_sym, R_ARM_REL32);
-#elif defined TCC_TARGET_ARM64
- dwarf_reloc(eh_frame_section, eh_section_sym, R_AARCH64_PREL32);
-#elif defined TCC_TARGET_RISCV64
- dwarf_reloc(eh_frame_section, eh_section_sym, R_RISCV_32_PCREL);
-#endif
- dwarf_data4(eh_frame_section, func_ind); // PC Begin
- dwarf_data4(eh_frame_section, size); // PC Range
- dwarf_data1(eh_frame_section, 0); // Augmentation Length
-#if defined TCC_TARGET_I386
- dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 1);
- dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
- dwarf_uleb128(eh_frame_section, 8);
- dwarf_data1(eh_frame_section, DW_CFA_offset + 5); // r5 (ebp)
- dwarf_uleb128(eh_frame_section, 2); // cfa-8
- dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 2);
- dwarf_data1(eh_frame_section, DW_CFA_def_cfa_register);
- dwarf_uleb128(eh_frame_section, 5); // r5 (ebp)
- dwarf_data1(eh_frame_section, DW_CFA_advance_loc4);
- dwarf_data4(eh_frame_section, size - 5);
- dwarf_data1(eh_frame_section, DW_CFA_restore + 5); // r5 (ebp)
- dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
- dwarf_uleb128(eh_frame_section, 4); // r4 (esp)
- dwarf_uleb128(eh_frame_section, 4); // ofs 4
-#elif defined TCC_TARGET_X86_64
- dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 1);
- dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
- dwarf_uleb128(eh_frame_section, 16);
- dwarf_data1(eh_frame_section, DW_CFA_offset + 6); // r6 (rbp)
- dwarf_uleb128(eh_frame_section, 2); // cfa-16
- dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 3);
- dwarf_data1(eh_frame_section, DW_CFA_def_cfa_register);
- dwarf_uleb128(eh_frame_section, 6); // r6 (rbp)
- dwarf_data1(eh_frame_section, DW_CFA_advance_loc4);
- dwarf_data4(eh_frame_section, size - 5);
- dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
- dwarf_uleb128(eh_frame_section, 7); // r7 (rsp)
- dwarf_uleb128(eh_frame_section, 8); // ofs 8
-#elif defined TCC_TARGET_ARM
- /* TODO */
- dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 2);
- dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
- dwarf_uleb128(eh_frame_section, 8);
- dwarf_data1(eh_frame_section, DW_CFA_offset + 14); // r14 (lr)
- dwarf_uleb128(eh_frame_section, 1);
- dwarf_data1(eh_frame_section, DW_CFA_offset + 11); // r11 (fp)
- dwarf_uleb128(eh_frame_section, 2);
- dwarf_data1(eh_frame_section, DW_CFA_advance_loc4);
- dwarf_data4(eh_frame_section, size / 2 - 5);
- dwarf_data1(eh_frame_section, DW_CFA_def_cfa_register);
- dwarf_uleb128(eh_frame_section, 11); // r11 (fp)
-#elif defined TCC_TARGET_ARM64
- dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 1);
- dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
- dwarf_uleb128(eh_frame_section, 224);
- dwarf_data1(eh_frame_section, DW_CFA_offset + 29); // x29 (fp)
- dwarf_uleb128(eh_frame_section, 28); // cfa-224
- dwarf_data1(eh_frame_section, DW_CFA_offset + 30); // x30 (lr)
- dwarf_uleb128(eh_frame_section, 27); // cfa-216
- dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 3);
- dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
- dwarf_uleb128(eh_frame_section, 224 + ((-loc + 15) & ~15));
- dwarf_data1(eh_frame_section, DW_CFA_advance_loc4);
- dwarf_data4(eh_frame_section, size / 4 - 5);
- dwarf_data1(eh_frame_section, DW_CFA_restore + 30); // x30 (lr)
- dwarf_data1(eh_frame_section, DW_CFA_restore + 29); // x29 (fp)
- dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
- dwarf_uleb128(eh_frame_section, 0);
-#elif defined TCC_TARGET_RISCV64
- dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 4);
- dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
- dwarf_uleb128(eh_frame_section, 16); // ofs 16
- dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 8);
- dwarf_data1(eh_frame_section, DW_CFA_offset + 1); // r1 (ra, lr)
- dwarf_uleb128(eh_frame_section, 2); // cfa-8
- dwarf_data1(eh_frame_section, DW_CFA_offset + 8); // r8 (s0, fp)
- dwarf_uleb128(eh_frame_section, 4); // cfa-16
- dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 8);
- dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
- dwarf_uleb128(eh_frame_section, 8); // r8 (s0, fp)
- dwarf_uleb128(eh_frame_section, 0); // ofs 0
- dwarf_data1(eh_frame_section, DW_CFA_advance_loc4);
- while (size >= 4 &&
- read32le(cur_text_section->data + func_ind + size - 4) != 0x00008067)
- size -= 4;
- dwarf_data4(eh_frame_section, size - 36);
- dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
- dwarf_uleb128(eh_frame_section, 2); // r2 (r2, sp)
- dwarf_uleb128(eh_frame_section, 16); // ofs 16
- dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 4);
- dwarf_data1(eh_frame_section, DW_CFA_restore + 1); // r1 (lr)
- dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 4);
- dwarf_data1(eh_frame_section, DW_CFA_restore + 8); // r8 (s0, fp)
- dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 4);
- dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
- dwarf_uleb128(eh_frame_section, 0); // ofs 0
-#endif
- while ((eh_frame_section->data_offset - fde_start) & 3)
- dwarf_data1(eh_frame_section, DW_CFA_nop);
- write32le(eh_frame_section->data + fde_start, // length
- eh_frame_section->data_offset - fde_start - 4);
-}
-
-ST_FUNC void tcc_eh_frame_end(TCCState *s1)
-{
- if (!eh_frame_section)
- return;
- dwarf_data4(eh_frame_section, 0);
-}
-
-struct eh_search_table {
- uint32_t pc_offset;
- uint32_t fde_offset;
-};
-
-static int sort_eh_table(const void *a, const void *b)
-{
- uint32_t pc1 = ((const struct eh_search_table *)a)->pc_offset;
- uint32_t pc2 = ((const struct eh_search_table *)b)->pc_offset;
-
- return pc1 < pc2 ? -1 : pc1 > pc2 ? 1 : 0;
-}
-
-ST_FUNC void tcc_eh_frame_hdr(TCCState *s1, int final)
-{
- int count = 0, offset;
- unsigned long count_offset, tab_offset;
- unsigned char *ln, *end;
- unsigned int last_cie_offset = 0xffffffff;
-
- if (!eh_frame_section || !eh_frame_section->data_offset)
- return;
- if (final && !eh_frame_hdr_section)
- return;
- if (final == 0)
- eh_frame_hdr_section =
- new_section(s1, ".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC);
- eh_frame_hdr_section->data_offset = 0;
- dwarf_data1(eh_frame_hdr_section, 1); // Version
- // Pointer Encoding Format
- dwarf_data1(eh_frame_hdr_section, DW_EH_PE_sdata4 | DW_EH_PE_pcrel);
- // Count Encoding Format
- dwarf_data1(eh_frame_hdr_section, DW_EH_PE_udata4 | DW_EH_PE_absptr);
- // Table Encoding Format
- dwarf_data1(eh_frame_hdr_section, DW_EH_PE_sdata4 | DW_EH_PE_datarel);
- offset = eh_frame_section->sh_addr -
- eh_frame_hdr_section->sh_addr -
- eh_frame_hdr_section->data_offset;
- dwarf_data4(eh_frame_hdr_section, offset); // eh_frame_ptr
- // Count
- count_offset = eh_frame_hdr_section->data_offset;
- dwarf_data4(eh_frame_hdr_section, 0);
- tab_offset = eh_frame_hdr_section->data_offset;
- ln = eh_frame_section->data;
- end = eh_frame_section->data + eh_frame_section->data_offset;
- while (ln < end) {
- unsigned char *fde = ln, *rd = ln;
- unsigned int cie_offset, version, length = dwarf_read_4(rd, end);
- unsigned int pc_offset, fde_offset;
-
- if (length == 0)
- goto next;
- cie_offset = dwarf_read_4(rd, end);
- if (cie_offset == 0)
- goto next;
- if (cie_offset != last_cie_offset) {
- unsigned char *cie = rd - cie_offset + 4;
-
- if (cie < eh_frame_section->data)
- goto next;
- version = dwarf_read_1(cie, end);
- if ((version == 1 || version == 3) &&
- dwarf_read_1(cie, end) == 'z' && // Augmentation String
- dwarf_read_1(cie, end) == 'R' &&
- dwarf_read_1(cie, end) == 0) {
- dwarf_read_uleb128(&cie, end); // code_alignment_factor
- dwarf_read_sleb128(&cie, end); // data_alignment_factor
- dwarf_read_1(cie, end); // return address column
- if (dwarf_read_uleb128(&cie, end) == 1 &&
- dwarf_read_1(cie, end) == FDE_ENCODING) {
- last_cie_offset = cie_offset;
- }
- else
- goto next;
- }
- else
- goto next;
- }
- count++;
- fde_offset = eh_frame_section->sh_addr +
- (fde - eh_frame_section->data) -
- eh_frame_hdr_section->sh_addr;
- pc_offset = dwarf_read_4(rd, end) + fde_offset + 8;
- dwarf_data4(eh_frame_hdr_section, pc_offset);
- dwarf_data4(eh_frame_hdr_section, fde_offset);
-next:
- ln += length + 4;
- }
- add32le(eh_frame_hdr_section->data + count_offset, count);
- qsort(eh_frame_hdr_section->data + tab_offset, count,
- sizeof(struct eh_search_table), sort_eh_table);
-}
-#endif
-
-/* start of translation unit info */
-ST_FUNC void tcc_debug_start(TCCState *s1)
-{
- int i;
- char buf[512];
- char *filename;
-
- /* we might currently #include the */
- filename = file->prev ? file->prev->filename : file->filename;
-
- /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
- symbols can be safely used */
- put_elf_sym(symtab_section, 0, 0,
- ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
- SHN_ABS, filename);
-
- if (s1->do_debug) {
-
- new_file = last_line_num = 0;
- debug_next_type = N_DEFAULT_DEBUG;
- debug_hash = NULL;
- debug_anon_hash = NULL;
- n_debug_hash = 0;
- n_debug_anon_hash = 0;
-
- getcwd(buf, sizeof(buf));
-#ifdef _WIN32
- normalize_slashes(buf);
-#endif
-
- if (s1->dwarf) {
- int start_abbrev;
- unsigned char *ptr;
- char *undo;
-
- /* dwarf_abbrev */
- start_abbrev = dwarf_abbrev_section->data_offset;
- ptr = section_ptr_add(dwarf_abbrev_section, sizeof(dwarf_abbrev_init));
- memcpy(ptr, dwarf_abbrev_init, sizeof(dwarf_abbrev_init));
-
- if (s1->dwarf < 5) {
- while (*ptr) {
- ptr += 3;
- while (*ptr) {
- if (ptr[1] == DW_FORM_line_strp)
- ptr[1] = DW_FORM_strp;
- if (s1->dwarf < 4) {
- /* These are compatable for DW_TAG_compile_unit
- DW_AT_stmt_list. */
- if (ptr[1] == DW_FORM_sec_offset)
- ptr[1] = DW_FORM_data4;
- /* This code uses only size < 0x80 so these are
- compatible. */
- if (ptr[1] == DW_FORM_exprloc)
- ptr[1] = DW_FORM_block1;
- }
- ptr += 2;
- }
- ptr += 2;
- }
- }
-
- dwarf_sym.info = dwarf_get_section_sym(dwarf_info_section);
- dwarf_sym.abbrev = dwarf_get_section_sym(dwarf_abbrev_section);
- dwarf_sym.line = dwarf_get_section_sym(dwarf_line_section);
- dwarf_sym.str = dwarf_get_section_sym(dwarf_str_section);
- if (tcc_state->dwarf >= 5)
- dwarf_sym.line_str = dwarf_get_section_sym(dwarf_line_str_section);
- else {
- dwarf_line_str_section = dwarf_str_section;
- dwarf_sym.line_str = dwarf_sym.str;
- }
- section_sym = dwarf_get_section_sym(text_section);
-
- /* dwarf_info */
- dwarf_info.start = dwarf_info_section->data_offset;
- dwarf_data4(dwarf_info_section, 0); // size
- dwarf_data2(dwarf_info_section, s1->dwarf); // version
- if (s1->dwarf >= 5) {
- dwarf_data1(dwarf_info_section, DW_UT_compile); // unit type
- dwarf_data1(dwarf_info_section, PTR_SIZE);
- dwarf_reloc(dwarf_info_section, dwarf_sym.abbrev, R_DATA_32DW);
- dwarf_data4(dwarf_info_section, start_abbrev);
- }
- else {
- dwarf_reloc(dwarf_info_section, dwarf_sym.abbrev, R_DATA_32DW);
- dwarf_data4(dwarf_info_section, start_abbrev);
- dwarf_data1(dwarf_info_section, PTR_SIZE);
- }
-
- dwarf_data1(dwarf_info_section, DWARF_ABBREV_COMPILE_UNIT);
- dwarf_strp(dwarf_info_section, "tcc " PACKAGE_VERSION);
- dwarf_data1(dwarf_info_section, s1->cversion == 201112 ? DW_LANG_C11 : DW_LANG_C99);
- dwarf_line_strp(dwarf_info_section, filename);
- dwarf_line_strp(dwarf_info_section, buf);
- dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR);
-#if PTR_SIZE == 4
- dwarf_data4(dwarf_info_section, ind); // low pc
- dwarf_data4(dwarf_info_section, 0); // high pc
-#else
- dwarf_data8(dwarf_info_section, ind); // low pc
- dwarf_data8(dwarf_info_section, 0); // high pc
-#endif
- dwarf_reloc(dwarf_info_section, dwarf_sym.line, R_DATA_32DW);
- dwarf_data4(dwarf_info_section, dwarf_line_section->data_offset); // stmt_list
-
- /* dwarf_line */
- dwarf_line.start = dwarf_line_section->data_offset;
- dwarf_data4(dwarf_line_section, 0); // length
- dwarf_data2(dwarf_line_section, s1->dwarf); // version
- if (s1->dwarf >= 5) {
- dwarf_data1(dwarf_line_section, PTR_SIZE); // address size
- dwarf_data1(dwarf_line_section, 0); // segment selector
- }
- dwarf_data4(dwarf_line_section, 0); // prologue Length
- dwarf_data1(dwarf_line_section, DWARF_MIN_INSTR_LEN);
- if (s1->dwarf >= 4)
- dwarf_data1(dwarf_line_section, 1); // maximum ops per instruction
- dwarf_data1(dwarf_line_section, 1); // Initial value of 'is_stmt'
- dwarf_data1(dwarf_line_section, DWARF_LINE_BASE);
- dwarf_data1(dwarf_line_section, DWARF_LINE_RANGE);
- dwarf_data1(dwarf_line_section, DWARF_OPCODE_BASE);
- ptr = section_ptr_add(dwarf_line_section, sizeof(dwarf_line_opcodes));
- memcpy(ptr, dwarf_line_opcodes, sizeof(dwarf_line_opcodes));
- undo = strrchr(filename, '/');
- if (undo)
- *undo = 0;
- dwarf_line.dir_size = 1 + (undo != NULL);
- dwarf_line.dir_table = (char **) tcc_malloc(sizeof (char *) *
- dwarf_line.dir_size);
- dwarf_line.dir_table[0] = tcc_strdup(buf);
- if (undo)
- dwarf_line.dir_table[1] = tcc_strdup(filename);
- dwarf_line.filename_size = 2;
- dwarf_line.filename_table =
- (struct dwarf_filename_struct *)
- tcc_malloc(2*sizeof (struct dwarf_filename_struct));
- dwarf_line.filename_table[0].dir_entry = 0;
- if (undo) {
- dwarf_line.filename_table[0].name = tcc_strdup(undo + 1);
- dwarf_line.filename_table[1].dir_entry = 1;
- dwarf_line.filename_table[1].name = tcc_strdup(undo + 1);
- *undo = '/';
- }
- else {
- dwarf_line.filename_table[0].name = tcc_strdup(filename);
- dwarf_line.filename_table[1].dir_entry = 0;
- dwarf_line.filename_table[1].name = tcc_strdup(filename);
- }
- dwarf_line.line_size = dwarf_line.line_max_size = 0;
- dwarf_line.line_data = NULL;
- dwarf_line.cur_file = 1;
- dwarf_line.last_file = 0;
- dwarf_line.last_pc = 0;
- dwarf_line.last_line = 1;
- dwarf_line_op(s1, 0); // extended
- dwarf_uleb128_op(s1, 1 + PTR_SIZE); // extended size
- dwarf_line_op(s1, DW_LNE_set_address);
- for (i = 0; i < PTR_SIZE; i++)
- dwarf_line_op(s1, 0);
- memset(&dwarf_info.base_type_used, 0, sizeof(dwarf_info.base_type_used));
- }
- else
- {
- /* file info: full path + filename */
- pstrcat(buf, sizeof(buf), "/");
- section_sym = put_elf_sym(symtab_section, 0, 0,
- ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
- text_section->sh_num, NULL);
- put_stabs_r(s1, buf, N_SO, 0, 0,
- text_section->data_offset, text_section, section_sym);
- put_stabs_r(s1, filename, N_SO, 0, 0,
- text_section->data_offset, text_section, section_sym);
- for (i = 0; i < N_DEFAULT_DEBUG; i++)
- put_stabs(s1, default_debug[i].name, N_LSYM, 0, 0, 0);
- }
- /* we're currently 'including' the */
- tcc_debug_bincl(s1);
- }
-}
-
-/* put end of translation unit info */
-ST_FUNC void tcc_debug_end(TCCState *s1)
-{
- if (!s1->do_debug || debug_next_type == 0)
- return;
-
- if (debug_info_root)
- tcc_debug_funcend(s1, 0); /* free stuff in case of errors */
-
- if (s1->dwarf) {
- int i, j;
- int start_aranges;
- unsigned char *ptr;
- int text_size = text_section->data_offset;
-
- /* dwarf_info */
- for (i = 0; i < n_debug_anon_hash; i++) {
- Sym *t = debug_anon_hash[i].type;
- int pos = dwarf_info_section->data_offset;
-
- dwarf_data1(dwarf_info_section,
- IS_UNION (t->type.t) ? DWARF_ABBREV_UNION_EMPTY_TYPE
- : DWARF_ABBREV_STRUCTURE_EMPTY_TYPE);
- dwarf_strp(dwarf_info_section,
- (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
- ? "" : get_tok_str(t->v, NULL));
- dwarf_uleb128(dwarf_info_section, 0);
- dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
- dwarf_uleb128(dwarf_info_section, file->line_num);
- for (j = 0; j < debug_anon_hash[i].n_debug_type; j++)
- write32le(dwarf_info_section->data +
- debug_anon_hash[i].debug_type[j],
- pos - dwarf_info.start);
- tcc_free (debug_anon_hash[i].debug_type);
- }
- tcc_free (debug_anon_hash);
- dwarf_data1(dwarf_info_section, 0);
- ptr = dwarf_info_section->data + dwarf_info.start;
- write32le(ptr, dwarf_info_section->data_offset - dwarf_info.start - 4);
- write32le(ptr + 25 + (s1->dwarf >= 5) + PTR_SIZE, text_size);
-
- /* dwarf_aranges */
- start_aranges = dwarf_aranges_section->data_offset;
- dwarf_data4(dwarf_aranges_section, 0); // size
- dwarf_data2(dwarf_aranges_section, 2); // version
- dwarf_reloc(dwarf_aranges_section, dwarf_sym.info, R_DATA_32DW);
- dwarf_data4(dwarf_aranges_section, 0); // dwarf_info
-#if PTR_SIZE == 4
- dwarf_data1(dwarf_aranges_section, 4); // address size
-#else
- dwarf_data1(dwarf_aranges_section, 8); // address size
-#endif
- dwarf_data1(dwarf_aranges_section, 0); // segment selector size
- dwarf_data4(dwarf_aranges_section, 0); // padding
- dwarf_reloc(dwarf_aranges_section, section_sym, R_DATA_PTR);
-#if PTR_SIZE == 4
- dwarf_data4(dwarf_aranges_section, 0); // Begin
- dwarf_data4(dwarf_aranges_section, text_size); // End
- dwarf_data4(dwarf_aranges_section, 0); // End list
- dwarf_data4(dwarf_aranges_section, 0); // End list
-#else
- dwarf_data8(dwarf_aranges_section, 0); // Begin
- dwarf_data8(dwarf_aranges_section, text_size); // End
- dwarf_data8(dwarf_aranges_section, 0); // End list
- dwarf_data8(dwarf_aranges_section, 0); // End list
-#endif
- ptr = dwarf_aranges_section->data + start_aranges;
- write32le(ptr, dwarf_aranges_section->data_offset - start_aranges - 4);
-
- /* dwarf_line */
- if (s1->dwarf >= 5) {
- dwarf_data1(dwarf_line_section, 1); /* col */
- dwarf_uleb128(dwarf_line_section, DW_LNCT_path);
- dwarf_uleb128(dwarf_line_section, DW_FORM_line_strp);
- dwarf_uleb128(dwarf_line_section, dwarf_line.dir_size);
- for (i = 0; i < dwarf_line.dir_size; i++)
- dwarf_line_strp(dwarf_line_section, dwarf_line.dir_table[i]);
- dwarf_data1(dwarf_line_section, 2); /* col */
- dwarf_uleb128(dwarf_line_section, DW_LNCT_path);
- dwarf_uleb128(dwarf_line_section, DW_FORM_line_strp);
- dwarf_uleb128(dwarf_line_section, DW_LNCT_directory_index);
- dwarf_uleb128(dwarf_line_section, DW_FORM_udata);
- dwarf_uleb128(dwarf_line_section, dwarf_line.filename_size);
- for (i = 0; i < dwarf_line.filename_size; i++) {
- dwarf_line_strp(dwarf_line_section,
- dwarf_line.filename_table[i].name);
- dwarf_uleb128(dwarf_line_section,
- dwarf_line.filename_table[i].dir_entry);
- }
- }
- else {
- int len;
-
- for (i = 0; i < dwarf_line.dir_size; i++) {
- len = strlen(dwarf_line.dir_table[i]) + 1;
- ptr = section_ptr_add(dwarf_line_section, len);
- memmove(ptr, dwarf_line.dir_table[i], len);
- }
- dwarf_data1(dwarf_line_section, 0); /* end dir */
- for (i = 0; i < dwarf_line.filename_size; i++) {
- len = strlen(dwarf_line.filename_table[i].name) + 1;
- ptr = section_ptr_add(dwarf_line_section, len);
- memmove(ptr, dwarf_line.filename_table[i].name, len);
- dwarf_uleb128(dwarf_line_section,
- dwarf_line.filename_table[i].dir_entry);
- dwarf_uleb128(dwarf_line_section, 0); /* time */
- dwarf_uleb128(dwarf_line_section, 0); /* size */
- }
- dwarf_data1(dwarf_line_section, 0); /* end file */
- }
- for (i = 0; i < dwarf_line.dir_size; i++)
- tcc_free(dwarf_line.dir_table[i]);
- tcc_free(dwarf_line.dir_table);
- for (i = 0; i < dwarf_line.filename_size; i++)
- tcc_free(dwarf_line.filename_table[i].name);
- tcc_free(dwarf_line.filename_table);
-
- dwarf_line_op(s1, 0); // extended
- dwarf_uleb128_op(s1, 1); // extended size
- dwarf_line_op(s1, DW_LNE_end_sequence);
- i = (s1->dwarf >= 5) * 2;
- write32le(&dwarf_line_section->data[dwarf_line.start + 6 + i],
- dwarf_line_section->data_offset - dwarf_line.start - (10 + i));
- section_ptr_add(dwarf_line_section, 3);
- dwarf_reloc(dwarf_line_section, section_sym, R_DATA_PTR);
- ptr = section_ptr_add(dwarf_line_section, dwarf_line.line_size - 3);
- memmove(ptr - 3, dwarf_line.line_data, dwarf_line.line_size);
- tcc_free(dwarf_line.line_data);
- write32le(dwarf_line_section->data + dwarf_line.start,
- dwarf_line_section->data_offset - dwarf_line.start - 4);
- }
- else
- {
- put_stabs_r(s1, NULL, N_SO, 0, 0,
- text_section->data_offset, text_section, section_sym);
- }
- tcc_free(debug_hash);
- debug_next_type = 0;
-}
-
-static BufferedFile* put_new_file(TCCState *s1)
-{
- BufferedFile *f = file;
- /* use upper file if from inline ":asm:" */
- if (f->filename[0] == ':')
- f = f->prev;
- if (f && new_file) {
- new_file = last_line_num = 0;
- if (s1->dwarf)
- dwarf_file(s1);
- else
- put_stabs_r(s1, f->filename, N_SOL, 0, 0, ind, text_section, section_sym);
- }
- return f;
-}
-
-/* put alternative filename */
-ST_FUNC void tcc_debug_newfile(TCCState *s1)
-{
- if (!s1->do_debug)
- return;
- if (s1->dwarf)
- dwarf_file(s1);
- new_file = 1;
-}
-
-/* begin of #include */
-ST_FUNC void tcc_debug_bincl(TCCState *s1)
-{
- if (!s1->do_debug)
- return;
- if (s1->dwarf)
- dwarf_file(s1);
- else
- put_stabs(s1, file->filename, N_BINCL, 0, 0, 0);
- new_file = 1;
-}
-
-/* end of #include */
-ST_FUNC void tcc_debug_eincl(TCCState *s1)
-{
- if (!s1->do_debug)
- return;
- if (s1->dwarf)
- dwarf_file(s1);
- else
- put_stabn(s1, N_EINCL, 0, 0, 0);
- new_file = 1;
-}
-
-/* generate line number info */
-ST_FUNC void tcc_debug_line(TCCState *s1)
-{
- BufferedFile *f;
-
- if (!s1->do_debug)
- return;
- if (cur_text_section != text_section || nocode_wanted)
- return;
- f = put_new_file(s1);
- if (!f)
- return;
- if (last_line_num == f->line_num)
- return;
- last_line_num = f->line_num;
-
- if (s1->dwarf) {
- int len_pc = (ind - dwarf_line.last_pc) / DWARF_MIN_INSTR_LEN;
- int len_line = f->line_num - dwarf_line.last_line;
- int n = len_pc * DWARF_LINE_RANGE + len_line + DWARF_OPCODE_BASE - DWARF_LINE_BASE;
-
- if (dwarf_line.cur_file != dwarf_line.last_file) {
- dwarf_line.last_file = dwarf_line.cur_file;
- dwarf_line_op(s1, DW_LNS_set_file);
- dwarf_uleb128_op(s1, dwarf_line.cur_file);
- }
- if (len_pc &&
- len_line >= DWARF_LINE_BASE && len_line <= (DWARF_OPCODE_BASE + DWARF_LINE_BASE) &&
- n >= DWARF_OPCODE_BASE && n <= 255)
- dwarf_line_op(s1, n);
- else {
- if (len_pc) {
- n = len_pc * DWARF_LINE_RANGE + 0 + DWARF_OPCODE_BASE - DWARF_LINE_BASE;
- if (n >= DWARF_OPCODE_BASE && n <= 255)
- dwarf_line_op(s1, n);
- else {
- dwarf_line_op(s1, DW_LNS_advance_pc);
- dwarf_uleb128_op(s1, len_pc);
- }
- }
- if (len_line) {
- n = 0 * DWARF_LINE_RANGE + len_line + DWARF_OPCODE_BASE - DWARF_LINE_BASE;
- if (len_line >= DWARF_LINE_BASE && len_line <= (DWARF_OPCODE_BASE + DWARF_LINE_BASE) &&
- n >= DWARF_OPCODE_BASE && n <= 255)
- dwarf_line_op(s1, n);
- else {
- dwarf_line_op(s1, DW_LNS_advance_line);
- dwarf_sleb128_op(s1, len_line);
- }
- }
- }
- dwarf_line.last_pc = ind;
- dwarf_line.last_line = f->line_num;
- }
- else
- {
- if (func_ind != -1) {
- put_stabn(s1, N_SLINE, 0, f->line_num, ind - func_ind);
- } else {
- /* from tcc_assemble */
- put_stabs_r(s1, NULL, N_SLINE, 0, f->line_num, ind, text_section, section_sym);
- }
- }
-}
-
-static void tcc_debug_stabs (TCCState *s1, const char *str, int type, unsigned long value,
- Section *sec, int sym_index, int info)
-{
- struct debug_sym *s;
-
- if (debug_info) {
- debug_info->sym =
- (struct debug_sym *)tcc_realloc (debug_info->sym,
- sizeof(struct debug_sym) *
- (debug_info->n_sym + 1));
- s = debug_info->sym + debug_info->n_sym++;
- s->type = type;
- s->value = value;
- s->str = tcc_strdup(str);
- s->sec = sec;
- s->sym_index = sym_index;
- s->info = info;
- s->file = dwarf_line.cur_file;
- s->line = file->line_num;
- }
- else if (sec)
- put_stabs_r (s1, str, type, 0, 0, value, sec, sym_index);
- else
- put_stabs (s1, str, type, 0, 0, value);
-}
-
-ST_FUNC void tcc_debug_stabn(TCCState *s1, int type, int value)
-{
- if (!s1->do_debug)
- return;
- if (type == N_LBRAC) {
- struct _debug_info *info =
- (struct _debug_info *) tcc_mallocz(sizeof (*info));
-
- info->start = value;
- info->parent = debug_info;
- if (debug_info) {
- if (debug_info->child) {
- if (debug_info->child->last)
- debug_info->child->last->next = info;
- else
- debug_info->child->next = info;
- debug_info->child->last = info;
- }
- else
- debug_info->child = info;
- }
- else
- debug_info_root = info;
- debug_info = info;
- }
- else {
- debug_info->end = value;
- debug_info = debug_info->parent;
- }
-}
-
-static int tcc_debug_find(TCCState *s1, Sym *t, int dwarf)
-{
- int i;
-
- if (!debug_info && dwarf &&
- (t->type.t & VT_BTYPE) == VT_STRUCT && t->c == -1) {
- for (i = 0; i < n_debug_anon_hash; i++)
- if (t == debug_anon_hash[i].type)
- return 0;
- debug_anon_hash = (struct _debug_anon_hash *)
- tcc_realloc (debug_anon_hash,
- (n_debug_anon_hash + 1) * sizeof(*debug_anon_hash));
- debug_anon_hash[n_debug_anon_hash].n_debug_type = 0;
- debug_anon_hash[n_debug_anon_hash].debug_type = NULL;
- debug_anon_hash[n_debug_anon_hash++].type = t;
- return 0;
- }
- for (i = 0; i < n_debug_hash; i++)
- if (t == debug_hash[i].type)
- return debug_hash[i].debug_type;
- return -1;
-}
-
-static int tcc_get_dwarf_info(TCCState *s1, Sym *s);
-
-static void tcc_debug_check_anon(TCCState *s1, Sym *t, int debug_type)
-{
- int i;
-
- if (!debug_info && (t->type.t & VT_BTYPE) == VT_STRUCT && t->type.ref->c == -1)
- for (i = 0; i < n_debug_anon_hash; i++)
- if (t->type.ref == debug_anon_hash[i].type) {
- debug_anon_hash[i].debug_type =
- tcc_realloc(debug_anon_hash[i].debug_type,
- (debug_anon_hash[i].n_debug_type + 1) * sizeof(int));
- debug_anon_hash[i].debug_type[debug_anon_hash[i].n_debug_type++] =
- debug_type;
- }
-}
-
-ST_FUNC void tcc_debug_fix_anon(TCCState *s1, CType *t)
-{
- int i, j, debug_type;
-
- if (!(s1->do_debug & 2) || !s1->dwarf || debug_info)
- return;
-
- if ((t->t & VT_BTYPE) == VT_STRUCT && t->ref->c != -1)
- for (i = 0; i < n_debug_anon_hash; i++)
- if (t->ref == debug_anon_hash[i].type) {
- Sym sym = {0}; sym .type = *t ;
-
- /* Trick to not hash this struct */
- debug_info = (struct _debug_info *) t;
- debug_type = tcc_get_dwarf_info(s1, &sym);
- debug_info = NULL;
- for (j = 0; j < debug_anon_hash[i].n_debug_type; j++)
- write32le(dwarf_info_section->data +
- debug_anon_hash[i].debug_type[j],
- debug_type - dwarf_info.start);
- tcc_free(debug_anon_hash[i].debug_type);
- n_debug_anon_hash--;
- for (; i < n_debug_anon_hash; i++)
- debug_anon_hash[i] = debug_anon_hash[i + 1];
- }
-}
-
-static int tcc_debug_add(TCCState *s1, Sym *t, int dwarf)
-{
- int offset = dwarf ? dwarf_info_section->data_offset : ++debug_next_type;
- debug_hash = (struct _debug_hash *)
- tcc_realloc (debug_hash,
- (n_debug_hash + 1) * sizeof(*debug_hash));
- debug_hash[n_debug_hash].debug_type = offset;
- debug_hash[n_debug_hash++].type = t;
- return offset;
-}
-
-static void tcc_debug_remove(TCCState *s1, Sym *t)
-{
- int i;
-
- for (i = 0; i < n_debug_hash; i++)
- if (t == debug_hash[i].type) {
- n_debug_hash--;
- for (; i < n_debug_hash; i++)
- debug_hash[i] = debug_hash[i+1];
- }
-}
-
-#define STRUCT_NODEBUG(s) \
- (s->a.nodebug || \
- ((s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM && \
- ((s->type.t & VT_BTYPE) == VT_BYTE || \
- (s->type.t & VT_BTYPE) == VT_BOOL || \
- (s->type.t & VT_BTYPE) == VT_SHORT || \
- (s->type.t & VT_BTYPE) == VT_INT || \
- (s->type.t & VT_BTYPE) == VT_LLONG)))
-
-static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result)
-{
- int type;
- int n = 0;
- int debug_type = -1;
- Sym *t = s;
- CString str;
-
- for (;;) {
- type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE | VT_VLA);
- if ((type & VT_BTYPE) != VT_BYTE)
- type &= ~VT_DEFSIGN;
- if (type == VT_PTR || type == (VT_PTR | VT_ARRAY))
- n++, t = t->type.ref;
- else
- break;
- }
- if ((type & VT_BTYPE) == VT_STRUCT) {
- Sym *e = t;
-
- t = t->type.ref;
- debug_type = tcc_debug_find(s1, t, 0);
- if (debug_type == -1) {
- debug_type = tcc_debug_add(s1, t, 0);
- cstr_new (&str);
- cstr_printf (&str, "%s:T%d=%c%d",
- (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
- ? "" : get_tok_str(t->v, NULL),
- debug_type,
- IS_UNION (t->type.t) ? 'u' : 's',
- t->c);
- while (t->next) {
- int pos, size, align;
-
- t = t->next;
- if (STRUCT_NODEBUG(t))
- continue;
- cstr_printf (&str, "%s:",
- get_tok_str(t->v, NULL));
- tcc_get_debug_info (s1, t, &str);
- if (t->type.t & VT_BITFIELD) {
- pos = t->c * 8 + BIT_POS(t->type.t);
- size = BIT_SIZE(t->type.t);
- }
- else {
- pos = t->c * 8;
- size = type_size(&t->type, &align) * 8;
- }
- cstr_printf (&str, ",%d,%d;", pos, size);
- }
- cstr_printf (&str, ";");
- tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0);
- cstr_free (&str);
- if (debug_info)
- tcc_debug_remove(s1, e);
- }
- }
- else if (IS_ENUM(type)) {
- Sym *e = t = t->type.ref;
-
- debug_type = tcc_debug_find(s1, t, 0);
- if (debug_type == -1) {
- debug_type = tcc_debug_add(s1, t, 0);
- cstr_new (&str);
- cstr_printf (&str, "%s:T%d=e",
- (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
- ? "" : get_tok_str(t->v, NULL),
- debug_type);
- while (t->next) {
- t = t->next;
- cstr_printf (&str, "%s:",
- (t->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
- ? "" : get_tok_str(t->v, NULL));
- cstr_printf (&str, e->type.t & VT_UNSIGNED ? "%u," : "%d,",
- (int)t->enum_val);
- }
- cstr_printf (&str, ";");
- tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0);
- cstr_free (&str);
- if (debug_info)
- tcc_debug_remove(s1, e);
- }
- }
- else if ((type & VT_BTYPE) != VT_FUNC) {
- type &= ~VT_STRUCT_MASK;
- for (debug_type = 1; debug_type <= N_DEFAULT_DEBUG; debug_type++)
- if (default_debug[debug_type - 1].type == type)
- break;
- if (debug_type > N_DEFAULT_DEBUG)
- return;
- }
- if (n > 0)
- cstr_printf (result, "%d=", ++debug_next_type);
- t = s;
- for (;;) {
- type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE | VT_VLA);
- if ((type & VT_BTYPE) != VT_BYTE)
- type &= ~VT_DEFSIGN;
- if (type == VT_PTR)
- cstr_printf (result, "%d=*", ++debug_next_type);
- else if (type == (VT_PTR | VT_ARRAY))
- cstr_printf (result, "%d=ar1;0;%d;",
- ++debug_next_type, t->type.ref->c - 1);
- else if (type == VT_FUNC) {
- cstr_printf (result, "%d=f", ++debug_next_type);
- tcc_get_debug_info (s1, t->type.ref, result);
- return;
- }
- else
- break;
- t = t->type.ref;
- }
- cstr_printf (result, "%d", debug_type);
-}
-
-static int tcc_get_dwarf_info(TCCState *s1, Sym *s)
-{
- int type;
- int debug_type = -1;
- Sym *e, *t = s;
- int i;
- int last_pos = -1;
- int retval;
-
- if (new_file)
- put_new_file(s1);
- for (;;) {
- type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE | VT_VLA);
- if ((type & VT_BTYPE) != VT_BYTE)
- type &= ~VT_DEFSIGN;
- if (type == VT_PTR || type == (VT_PTR | VT_ARRAY))
- t = t->type.ref;
- else
- break;
- }
- if ((type & VT_BTYPE) == VT_STRUCT) {
- t = t->type.ref;
- debug_type = tcc_debug_find(s1, t, 1);
- if (debug_type == -1) {
- int pos_sib = 0, i, *pos_type;
-
- debug_type = tcc_debug_add(s1, t, 1);
- e = t;
- i = 0;
- while (e->next) {
- e = e->next;
- if (STRUCT_NODEBUG(e))
- continue;
- i++;
- }
- pos_type = (int *) tcc_malloc(i * sizeof(int));
- dwarf_data1(dwarf_info_section,
- IS_UNION (t->type.t)
- ? t->next ? DWARF_ABBREV_UNION_TYPE
- : DWARF_ABBREV_UNION_EMPTY_TYPE
- : t->next ? DWARF_ABBREV_STRUCTURE_TYPE
- : DWARF_ABBREV_STRUCTURE_EMPTY_TYPE);
- dwarf_strp(dwarf_info_section,
- (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
- ? "" : get_tok_str(t->v, NULL));
- dwarf_uleb128(dwarf_info_section, t->c);
- dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
- dwarf_uleb128(dwarf_info_section, file->line_num);
- if (t->next) {
- pos_sib = dwarf_info_section->data_offset;
- dwarf_data4(dwarf_info_section, 0);
- }
- e = t;
- i = 0;
- while (e->next) {
- e = e->next;
- if (STRUCT_NODEBUG(e))
- continue;
- dwarf_data1(dwarf_info_section,
- e->type.t & VT_BITFIELD ? DWARF_ABBREV_MEMBER_BF
- : DWARF_ABBREV_MEMBER);
- dwarf_strp(dwarf_info_section,
- get_tok_str(e->v, NULL));
- dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
- dwarf_uleb128(dwarf_info_section, file->line_num);
- pos_type[i++] = dwarf_info_section->data_offset;
- dwarf_data4(dwarf_info_section, 0);
- if (e->type.t & VT_BITFIELD) {
- int pos = e->c * 8 + BIT_POS(e->type.t);
- int size = BIT_SIZE(e->type.t);
-
- dwarf_uleb128(dwarf_info_section, size);
- dwarf_uleb128(dwarf_info_section, pos);
- }
- else
- dwarf_uleb128(dwarf_info_section, e->c);
- }
- if (t->next) {
- dwarf_data1(dwarf_info_section, 0);
- write32le(dwarf_info_section->data + pos_sib,
- dwarf_info_section->data_offset - dwarf_info.start);
- }
- e = t;
- i = 0;
- while (e->next) {
- e = e->next;
- if (STRUCT_NODEBUG(e))
- continue;
- type = tcc_get_dwarf_info(s1, e);
- tcc_debug_check_anon(s1, e, pos_type[i]);
- write32le(dwarf_info_section->data + pos_type[i++],
- type - dwarf_info.start);
- }
- tcc_free(pos_type);
- if (debug_info)
- tcc_debug_remove(s1, t);
- }
- }
- else if (IS_ENUM(type)) {
- t = t->type.ref;
- debug_type = tcc_debug_find(s1, t, 1);
- if (debug_type == -1) {
- int pos_sib, pos_type;
- Sym sym = {0}; sym.type.t = VT_INT | (type & VT_UNSIGNED);
-
- pos_type = tcc_get_dwarf_info(s1, &sym);
- debug_type = tcc_debug_add(s1, t, 1);
- dwarf_data1(dwarf_info_section, DWARF_ABBREV_ENUMERATION_TYPE);
- dwarf_strp(dwarf_info_section,
- (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
- ? "" : get_tok_str(t->v, NULL));
- dwarf_data1(dwarf_info_section,
- type & VT_UNSIGNED ? DW_ATE_unsigned : DW_ATE_signed );
- dwarf_data1(dwarf_info_section, 4);
- dwarf_data4(dwarf_info_section, pos_type - dwarf_info.start);
- dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
- dwarf_uleb128(dwarf_info_section, file->line_num);
- pos_sib = dwarf_info_section->data_offset;
- dwarf_data4(dwarf_info_section, 0);
- e = t;
- while (e->next) {
- e = e->next;
- dwarf_data1(dwarf_info_section,
- type & VT_UNSIGNED ? DWARF_ABBREV_ENUMERATOR_UNSIGNED
- : DWARF_ABBREV_ENUMERATOR_SIGNED);
- dwarf_strp(dwarf_info_section,
- (e->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
- ? "" : get_tok_str(e->v, NULL));
- if (type & VT_UNSIGNED)
- dwarf_uleb128(dwarf_info_section, e->enum_val);
- else
- dwarf_sleb128(dwarf_info_section, e->enum_val);
- }
- dwarf_data1(dwarf_info_section, 0);
- write32le(dwarf_info_section->data + pos_sib,
- dwarf_info_section->data_offset - dwarf_info.start);
- if (debug_info)
- tcc_debug_remove(s1, t);
- }
- }
- else if ((type & VT_BTYPE) != VT_FUNC) {
- type &= ~VT_STRUCT_MASK;
- for (i = 1; i <= N_DEFAULT_DEBUG; i++)
- if (default_debug[i - 1].type == type)
- break;
- if (i > N_DEFAULT_DEBUG)
- return 0;
- debug_type = dwarf_info.base_type_used[i - 1];
- if (debug_type == 0) {
- char name[100];
-
- debug_type = dwarf_info_section->data_offset;
- dwarf_data1(dwarf_info_section, DWARF_ABBREV_BASE_TYPE);
- dwarf_uleb128(dwarf_info_section, default_debug[i - 1].size);
- dwarf_data1(dwarf_info_section, default_debug[i - 1].encoding);
- strncpy(name, default_debug[i - 1].name, sizeof(name) -1);
- *strchr(name, ':') = 0;
- dwarf_strp(dwarf_info_section, name);
- dwarf_info.base_type_used[i - 1] = debug_type;
- }
- }
- retval = debug_type;
- e = NULL;
- t = s;
- for (;;) {
- type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE | VT_VLA);
- if ((type & VT_BTYPE) != VT_BYTE)
- type &= ~VT_DEFSIGN;
- if (type == VT_PTR) {
- i = dwarf_info_section->data_offset;
- if (retval == debug_type)
- retval = i;
- dwarf_data1(dwarf_info_section, DWARF_ABBREV_POINTER);
- dwarf_data1(dwarf_info_section, PTR_SIZE);
- if (last_pos != -1) {
- tcc_debug_check_anon(s1, e, last_pos);
- write32le(dwarf_info_section->data + last_pos,
- i - dwarf_info.start);
- }
- last_pos = dwarf_info_section->data_offset;
- e = t->type.ref;
- dwarf_data4(dwarf_info_section, 0);
- }
- else if (type == (VT_PTR | VT_ARRAY)) {
- int sib_pos, sub_type;
-#if LONG_SIZE == 4
- Sym sym = {0}; sym.type.t = VT_LONG | VT_INT | VT_UNSIGNED;
-#else
- Sym sym = {0}; sym.type.t = VT_LLONG | VT_LONG | VT_UNSIGNED;
-#endif
-
- sub_type = tcc_get_dwarf_info(s1, &sym);
- i = dwarf_info_section->data_offset;
- if (retval == debug_type)
- retval = i;
- dwarf_data1(dwarf_info_section, DWARF_ABBREV_ARRAY_TYPE);
- if (last_pos != -1) {
- tcc_debug_check_anon(s1, e, last_pos);
- write32le(dwarf_info_section->data + last_pos,
- i - dwarf_info.start);
- }
- last_pos = dwarf_info_section->data_offset;
- e = t->type.ref;
- dwarf_data4(dwarf_info_section, 0);
- sib_pos = dwarf_info_section->data_offset;
- dwarf_data4(dwarf_info_section, 0);
- for (;;) {
- dwarf_data1(dwarf_info_section, DWARF_ABBREV_SUBRANGE_TYPE);
- dwarf_data4(dwarf_info_section, sub_type - dwarf_info.start);
- dwarf_uleb128(dwarf_info_section, t->type.ref->c - 1);
- s = t->type.ref;
- type = s->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE);
- if (type != (VT_PTR | VT_ARRAY))
- break;
- t = s;
- }
- dwarf_data1(dwarf_info_section, 0);
- write32le(dwarf_info_section->data + sib_pos,
- dwarf_info_section->data_offset - dwarf_info.start);
- }
- else if (type == VT_FUNC) {
- int sib_pos = 0, *pos_type;
- Sym *f;
-
- i = dwarf_info_section->data_offset;
- debug_type = tcc_get_dwarf_info(s1, t->type.ref);
- if (retval == debug_type)
- retval = i;
- dwarf_data1(dwarf_info_section,
- t->type.ref->next ? DWARF_ABBREV_SUBROUTINE_TYPE
- : DWARF_ABBREV_SUBROUTINE_EMPTY_TYPE);
- if (last_pos != -1) {
- tcc_debug_check_anon(s1, e, last_pos);
- write32le(dwarf_info_section->data + last_pos,
- i - dwarf_info.start);
- }
- last_pos = dwarf_info_section->data_offset;
- e = t->type.ref;
- dwarf_data4(dwarf_info_section, 0);
- if (t->type.ref->next) {
- sib_pos = dwarf_info_section->data_offset;
- dwarf_data4(dwarf_info_section, 0);
- }
- f = t->type.ref;
- i = 0;
- while (f->next) {
- f = f->next;
- i++;
- }
- pos_type = (int *) tcc_malloc(i * sizeof(int));
- f = t->type.ref;
- i = 0;
- while (f->next) {
- f = f->next;
- dwarf_data1(dwarf_info_section, DWARF_ABBREV_FORMAL_PARAMETER2);
- pos_type[i++] = dwarf_info_section->data_offset;
- dwarf_data4(dwarf_info_section, 0);
- }
- if (t->type.ref->next) {
- dwarf_data1(dwarf_info_section, 0);
- write32le(dwarf_info_section->data + sib_pos,
- dwarf_info_section->data_offset - dwarf_info.start);
- }
- f = t->type.ref;
- i = 0;
- while (f->next) {
- f = f->next;
- type = tcc_get_dwarf_info(s1, f);
- tcc_debug_check_anon(s1, f, pos_type[i]);
- write32le(dwarf_info_section->data + pos_type[i++],
- type - dwarf_info.start);
- }
- tcc_free(pos_type);
- }
- else {
- if (last_pos != -1) {
- tcc_debug_check_anon(s1, e, last_pos);
- write32le(dwarf_info_section->data + last_pos,
- debug_type - dwarf_info.start);
- }
- break;
- }
- t = t->type.ref;
- }
- return retval;
-}
-
-static void tcc_debug_finish (TCCState *s1, struct _debug_info *cur)
-{
- while (cur) {
- struct _debug_info *next = cur->next;
- int i;
-
- if (s1->dwarf) {
-
- for (i = cur->n_sym - 1; i >= 0; i--) {
- struct debug_sym *s = &cur->sym[i];
-
- dwarf_data1(dwarf_info_section,
- s->type == N_PSYM
- ? DWARF_ABBREV_FORMAL_PARAMETER
- : s->type == N_GSYM
- ? DWARF_ABBREV_VARIABLE_EXTERNAL
- : s->type == N_STSYM
- ? DWARF_ABBREV_VARIABLE_STATIC
- : DWARF_ABBREV_VARIABLE_LOCAL);
- dwarf_strp(dwarf_info_section, s->str);
- if (s->type == N_GSYM || s->type == N_STSYM) {
- dwarf_uleb128(dwarf_info_section, s->file);
- dwarf_uleb128(dwarf_info_section, s->line);
- }
- dwarf_data4(dwarf_info_section, s->info - dwarf_info.start);
- if (s->type == N_GSYM || s->type == N_STSYM) {
- /* global/static */
- if (s->type == N_GSYM)
- dwarf_data1(dwarf_info_section, 1);
- dwarf_data1(dwarf_info_section, PTR_SIZE + 1);
- dwarf_data1(dwarf_info_section, DW_OP_addr);
- if (s->type == N_STSYM)
- dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR);
-#if PTR_SIZE == 4
- dwarf_data4(dwarf_info_section, s->value);
-#else
- dwarf_data8(dwarf_info_section, s->value);
-#endif
- }
- else {
- /* param/local */
- dwarf_data1(dwarf_info_section, dwarf_sleb128_size(s->value) + 1);
- dwarf_data1(dwarf_info_section, DW_OP_fbreg);
- dwarf_sleb128(dwarf_info_section, s->value);
- }
- tcc_free (s->str);
- }
- tcc_free (cur->sym);
- dwarf_data1(dwarf_info_section,
- cur->child ? DWARF_ABBREV_LEXICAL_BLOCK
- : DWARF_ABBREV_LEXICAL_EMPTY_BLOCK);
- dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR);
-#if PTR_SIZE == 4
- dwarf_data4(dwarf_info_section, func_ind + cur->start);
- dwarf_data4(dwarf_info_section, cur->end - cur->start);
-#else
- dwarf_data8(dwarf_info_section, func_ind + cur->start);
- dwarf_data8(dwarf_info_section, cur->end - cur->start);
-#endif
- tcc_debug_finish (s1, cur->child);
- if (cur->child)
- dwarf_data1(dwarf_info_section, 0);
- }
- else
- {
- for (i = 0; i < cur->n_sym; i++) {
- struct debug_sym *s = &cur->sym[i];
-
- if (s->sec)
- put_stabs_r(s1, s->str, s->type, 0, 0, s->value,
- s->sec, s->sym_index);
- else
- put_stabs(s1, s->str, s->type, 0, 0, s->value);
- tcc_free (s->str);
- }
- tcc_free (cur->sym);
- put_stabn(s1, N_LBRAC, 0, 0, cur->start);
- tcc_debug_finish (s1, cur->child);
- put_stabn(s1, N_RBRAC, 0, 0, cur->end);
- }
- tcc_free (cur);
- cur = next;
- }
-}
-
-ST_FUNC void tcc_add_debug_info(TCCState *s1, int param, Sym *s, Sym *e)
-{
- CString debug_str;
-
- if (!(s1->do_debug & 2))
- return;
-
- cstr_new (&debug_str);
- for (; s != e; s = s->prev) {
- if (!s->v || (s->r & VT_VALMASK) != VT_LOCAL)
- continue;
- if (s1->dwarf) {
- tcc_debug_stabs(s1, get_tok_str(s->v, NULL),
- param ? N_PSYM : N_LSYM, s->c, NULL, 0,
- tcc_get_dwarf_info(s1, s));
- }
- else
- {
- cstr_reset (&debug_str);
- cstr_printf (&debug_str, "%s:%s", get_tok_str(s->v, NULL),
- param ? "p" : "");
- tcc_get_debug_info(s1, s, &debug_str);
- tcc_debug_stabs(s1, debug_str.data, param ? N_PSYM : N_LSYM,
- s->c, NULL, 0, 0);
- }
- }
- cstr_free (&debug_str);
-}
-
-/* put function symbol */
-ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym)
-{
- CString debug_str;
- BufferedFile *f;
-
- if (!s1->do_debug)
- return;
- debug_info_root = NULL;
- debug_info = NULL;
- tcc_debug_stabn(s1, N_LBRAC, ind - func_ind);
- f = put_new_file(s1);
- if (!f)
- return;
-
- if (s1->dwarf) {
- tcc_debug_line(s1);
- dwarf_info.func = sym;
- dwarf_info.line = file->line_num;
- if (s1->do_backtrace) {
- int i, len;
-
- dwarf_line_op(s1, 0); // extended
- dwarf_uleb128_op(s1, strlen(funcname) + 2);
- dwarf_line_op(s1, DW_LNE_hi_user - 1);
- len = strlen(funcname) + 1;
- for (i = 0; i < len; i++)
- dwarf_line_op(s1, funcname[i]);
- }
- }
- else
- {
- cstr_new (&debug_str);
- cstr_printf(&debug_str, "%s:%c", funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
- tcc_get_debug_info(s1, sym->type.ref, &debug_str);
- put_stabs_r(s1, debug_str.data, N_FUN, 0, f->line_num, 0, cur_text_section, sym->c);
- cstr_free (&debug_str);
- tcc_debug_line(s1);
- }
-}
-
-ST_FUNC void tcc_debug_prolog_epilog(TCCState *s1, int value)
-{
- if (!s1->do_debug)
- return;
- if (s1->dwarf) {
- dwarf_line_op(s1, value == 0 ? DW_LNS_set_prologue_end
- : DW_LNS_set_epilogue_begin);
- }
-}
-
-/* put function size */
-ST_FUNC void tcc_debug_funcend(TCCState *s1, int size)
-{
- /* lldb does not like function end and next function start at same pc */
- int min_instr_len;
-
-#if TCC_EH_FRAME
- tcc_debug_frame_end(s1, size);
-#endif
- if (!s1->do_debug)
- return;
- min_instr_len = dwarf_line.last_pc == ind ? 0 : DWARF_MIN_INSTR_LEN;
- ind -= min_instr_len;
- tcc_debug_line(s1);
- ind += min_instr_len;
- tcc_debug_stabn(s1, N_RBRAC, size);
- if (s1->dwarf) {
- int func_sib = 0;
- Sym *sym = dwarf_info.func;
- int n_debug_info = tcc_get_dwarf_info(s1, sym->type.ref);
-
- dwarf_data1(dwarf_info_section,
- sym->type.t & VT_STATIC ? DWARF_ABBREV_SUBPROGRAM_STATIC
- : DWARF_ABBREV_SUBPROGRAM_EXTERNAL);
- if ((sym->type.t & VT_STATIC) == 0)
- dwarf_data1(dwarf_info_section, 1);
- dwarf_strp(dwarf_info_section, funcname);
- dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
- dwarf_uleb128(dwarf_info_section, dwarf_info.line);
- tcc_debug_check_anon(s1, sym->type.ref, dwarf_info_section->data_offset);
- dwarf_data4(dwarf_info_section, n_debug_info - dwarf_info.start);
- dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR);
-#if PTR_SIZE == 4
- dwarf_data4(dwarf_info_section, func_ind); // low_pc
- dwarf_data4(dwarf_info_section, size); // high_pc
-#else
- dwarf_data8(dwarf_info_section, func_ind); // low_pc
- dwarf_data8(dwarf_info_section, size); // high_pc
-#endif
- func_sib = dwarf_info_section->data_offset;
- dwarf_data4(dwarf_info_section, 0); // sibling
- dwarf_data1(dwarf_info_section, 1);
-#if defined(TCC_TARGET_I386)
- dwarf_data1(dwarf_info_section, DW_OP_reg5); // ebp
-#elif defined(TCC_TARGET_X86_64)
- dwarf_data1(dwarf_info_section, DW_OP_reg6); // rbp
-#elif defined TCC_TARGET_ARM
- dwarf_data1(dwarf_info_section, DW_OP_reg13); // sp
-#elif defined TCC_TARGET_ARM64
- dwarf_data1(dwarf_info_section, DW_OP_reg29); // reg 29
-#elif defined TCC_TARGET_RISCV64
- dwarf_data1(dwarf_info_section, DW_OP_reg8); // r8(s0)
-#else
- dwarf_data1(dwarf_info_section, DW_OP_call_frame_cfa);
-#endif
- tcc_debug_finish (s1, debug_info_root);
- dwarf_data1(dwarf_info_section, 0);
- write32le(dwarf_info_section->data + func_sib,
- dwarf_info_section->data_offset - dwarf_info.start);
- }
- else
- {
- tcc_debug_finish (s1, debug_info_root);
- }
- debug_info_root = 0;
-}
-
-
-ST_FUNC void tcc_debug_extern_sym(TCCState *s1, Sym *sym, int sh_num, int sym_bind, int sym_type)
-{
- if (!(s1->do_debug & 2))
- return;
-
- if (sym_type == STT_FUNC || sym->v >= SYM_FIRST_ANOM)
- return;
- if (s1->dwarf) {
- int debug_type;
-
- debug_type = tcc_get_dwarf_info(s1, sym);
- dwarf_data1(dwarf_info_section,
- sym_bind == STB_GLOBAL
- ? DWARF_ABBREV_VARIABLE_EXTERNAL
- : DWARF_ABBREV_VARIABLE_STATIC);
- dwarf_strp(dwarf_info_section, get_tok_str(sym->v, NULL));
- dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
- dwarf_uleb128(dwarf_info_section, file->line_num);
- tcc_debug_check_anon(s1, sym, dwarf_info_section->data_offset);
- dwarf_data4(dwarf_info_section, debug_type - dwarf_info.start);
- if (sym_bind == STB_GLOBAL)
- dwarf_data1(dwarf_info_section, 1);
- dwarf_data1(dwarf_info_section, PTR_SIZE + 1);
- dwarf_data1(dwarf_info_section, DW_OP_addr);
- greloca(dwarf_info_section, sym, dwarf_info_section->data_offset,
- R_DATA_PTR, 0);
-#if PTR_SIZE == 4
- dwarf_data4(dwarf_info_section, 0);
-#else
- dwarf_data8(dwarf_info_section, 0);
-#endif
- }
- else
- {
- Section *s = sh_num == SHN_COMMON ? common_section
- : s1->sections[sh_num];
- CString str;
-
- cstr_new (&str);
- cstr_printf (&str, "%s:%c",
- get_tok_str(sym->v, NULL),
- sym_bind == STB_GLOBAL ? 'G' : func_ind != -1 ? 'V' : 'S'
- );
- tcc_get_debug_info(s1, sym, &str);
- if (sym_bind == STB_GLOBAL)
- tcc_debug_stabs(s1, str.data, N_GSYM, 0, NULL, 0, 0);
- else
- tcc_debug_stabs(s1, str.data,
- (sym->type.t & VT_STATIC) && data_section == s
- ? N_STSYM : N_LCSYM, 0, s, sym->c, 0);
- cstr_free (&str);
- }
-}
-
-ST_FUNC void tcc_debug_typedef(TCCState *s1, Sym *sym)
-{
- if (!(s1->do_debug & 2))
- return;
-
- if (s1->dwarf) {
- int debug_type;
-
- debug_type = tcc_get_dwarf_info(s1, sym);
- if (debug_type != -1) {
- dwarf_data1(dwarf_info_section, DWARF_ABBREV_TYPEDEF);
- dwarf_strp(dwarf_info_section, get_tok_str(sym->v, NULL));
- dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
- dwarf_uleb128(dwarf_info_section, file->line_num);
- tcc_debug_check_anon(s1, sym, dwarf_info_section->data_offset);
- dwarf_data4(dwarf_info_section, debug_type - dwarf_info.start);
- }
- }
- else
- {
- CString str;
- cstr_new (&str);
- cstr_printf (&str, "%s:t",
- (sym->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
- ? "" : get_tok_str(sym->v, NULL));
- tcc_get_debug_info(s1, sym, &str);
- tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0);
- cstr_free (&str);
- }
-}
-
-/* ------------------------------------------------------------------------- */
-/* for section layout see lib/tcov.c */
-
-ST_FUNC void tcc_tcov_block_end(TCCState *s1, int line);
-
-ST_FUNC void tcc_tcov_block_begin(TCCState *s1)
-{
- SValue sv;
- void *ptr;
- unsigned long last_offset = tcov_data.offset;
-
- tcc_tcov_block_end (tcc_state, 0);
- if (s1->test_coverage == 0 || nocode_wanted)
- return;
-
- if (tcov_data.last_file_name == 0 ||
- strcmp ((const char *)(tcov_section->data + tcov_data.last_file_name),
- file->true_filename) != 0) {
- char wd[1024];
- CString cstr;
-
- if (tcov_data.last_func_name)
- section_ptr_add(tcov_section, 1);
- if (tcov_data.last_file_name)
- section_ptr_add(tcov_section, 1);
- tcov_data.last_func_name = 0;
- cstr_new (&cstr);
- if (file->true_filename[0] == '/') {
- tcov_data.last_file_name = tcov_section->data_offset;
- cstr_printf (&cstr, "%s", file->true_filename);
- }
- else {
- getcwd (wd, sizeof(wd));
- tcov_data.last_file_name = tcov_section->data_offset + strlen(wd) + 1;
- cstr_printf (&cstr, "%s/%s", wd, file->true_filename);
- }
- ptr = section_ptr_add(tcov_section, cstr.size + 1);
- strcpy((char *)ptr, cstr.data);
-#ifdef _WIN32
- normalize_slashes((char *)ptr);
-#endif
- cstr_free (&cstr);
- }
- if (tcov_data.last_func_name == 0 ||
- strcmp ((const char *)(tcov_section->data + tcov_data.last_func_name),
- funcname) != 0) {
- size_t len;
-
- if (tcov_data.last_func_name)
- section_ptr_add(tcov_section, 1);
- tcov_data.last_func_name = tcov_section->data_offset;
- len = strlen (funcname);
- ptr = section_ptr_add(tcov_section, len + 1);
- strcpy((char *)ptr, funcname);
- section_ptr_add(tcov_section, -tcov_section->data_offset & 7);
- ptr = section_ptr_add(tcov_section, 8);
- write64le (ptr, file->line_num);
- }
- if (ind == tcov_data.ind && tcov_data.line == file->line_num)
- tcov_data.offset = last_offset;
- else {
- Sym label = {0};
- label.type.t = VT_LLONG | VT_STATIC;
-
- ptr = section_ptr_add(tcov_section, 16);
- tcov_data.line = file->line_num;
- write64le (ptr, (tcov_data.line << 8) | 0xff);
- put_extern_sym(&label, tcov_section,
- ((unsigned char *)ptr - tcov_section->data) + 8, 0);
- sv.type = label.type;
- sv.r = VT_SYM | VT_LVAL | VT_CONST;
- sv.r2 = VT_CONST;
- sv.c.i = 0;
- sv.sym = &label;
-#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || \
- defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64 || \
- defined TCC_TARGET_RISCV64
- gen_increment_tcov (&sv);
-#else
- vpushv(&sv);
- inc(0, TOK_INC);
- vpop();
-#endif
- tcov_data.offset = (unsigned char *)ptr - tcov_section->data;
- tcov_data.ind = ind;
- }
-}
-
-ST_FUNC void tcc_tcov_block_end(TCCState *s1, int line)
-{
- if (s1->test_coverage == 0)
- return;
- if (line == -1)
- line = tcov_data.line;
- if (tcov_data.offset) {
- void *ptr = tcov_section->data + tcov_data.offset;
- unsigned long long nline = line ? line : file->line_num;
-
- write64le (ptr, (read64le (ptr) & 0xfffffffffull) | (nline << 36));
- tcov_data.offset = 0;
- }
-}
-
-ST_FUNC void tcc_tcov_check_line(TCCState *s1, int start)
-{
- if (s1->test_coverage == 0)
- return;
- if (tcov_data.line != file->line_num) {
- if ((tcov_data.line + 1) != file->line_num) {
- tcc_tcov_block_end (s1, -1);
- if (start)
- tcc_tcov_block_begin (s1);
- }
- else
- tcov_data.line = file->line_num;
- }
-}
-
-ST_FUNC void tcc_tcov_start(TCCState *s1)
-{
- if (s1->test_coverage == 0)
- return;
- if (!s1->dState)
- s1->dState = tcc_mallocz(sizeof *s1->dState);
- memset (&tcov_data, 0, sizeof (tcov_data));
- if (tcov_section == NULL) {
- tcov_section = new_section(tcc_state, ".tcov", SHT_PROGBITS,
- SHF_ALLOC | SHF_WRITE);
- section_ptr_add(tcov_section, 4); // pointer to executable name
- }
-}
-
-ST_FUNC void tcc_tcov_end(TCCState *s1)
-{
- if (s1->test_coverage == 0)
- return;
- if (tcov_data.last_func_name)
- section_ptr_add(tcov_section, 1);
- if (tcov_data.last_file_name)
- section_ptr_add(tcov_section, 1);
-}
-
-ST_FUNC void tcc_tcov_reset_ind(TCCState *s1)
-{
- tcov_data.ind = 0;
-}
-
-/* ------------------------------------------------------------------------- */
-#undef last_line_num
-#undef new_file
-#undef section_sym
-#undef debug_next_type
-#undef debug_hash
-#undef n_debug_hash
-#undef debug_anon_hash
-#undef n_debug_anon_hash
-#undef debug_info
-#undef debug_info_root
-#undef dwarf_sym
-#undef dwarf_line
-#undef dwarf_info
-#undef tcov_data
diff --git a/tccmacho.c b/tccmacho.c
deleted file mode 100644
index 0b70457c..00000000
--- a/tccmacho.c
+++ /dev/null
@@ -1,2480 +0,0 @@
-/*
- * Mach-O file handling for TCC
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "tcc.h"
-
-/* In order to make life easy for us we are generating Mach-O files which
- don't make use of some modern features, but which aren't entirely classic
- either in that they do use some modern features. We're also only
- generating 64bit Mach-O files, and only native endian at that.
-
- In particular we're generating executables that don't make use of
- DYLD_INFO for dynamic linking info, as that requires us building a
- trie of exported names. We're simply using classic symbol tables which
- are still supported by modern dyld.
-
- But we do use LC_MAIN, which is a "modern" feature in order to not have
- to setup our own crt code. We're not using lazy linking, so even function
- calls are resolved at startup. */
-
-#if !defined TCC_TARGET_X86_64 && !defined TCC_TARGET_ARM64
-#error Platform not supported
-#endif
-
-/* XXX: this file uses tcc_error() to the effect of exit(1) */
-#undef _tcc_error
-
-#define DEBUG_MACHO 0
-#define dprintf if (DEBUG_MACHO) printf
-
-#define MH_EXECUTE (0x2)
-#define MH_DYLDLINK (0x4)
-#define MH_DYLIB (0x6)
-#define MH_PIE (0x200000)
-
-#define CPU_SUBTYPE_LIB64 (0x80000000)
-#define CPU_SUBTYPE_X86_ALL (3)
-#define CPU_SUBTYPE_ARM64_ALL (0)
-
-#define CPU_ARCH_ABI64 (0x01000000)
-
-#define CPU_TYPE_X86 (7)
-#define CPU_TYPE_X86_64 (CPU_TYPE_X86 | CPU_ARCH_ABI64)
-#define CPU_TYPE_ARM (12)
-#define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64)
-
-struct fat_header {
- uint32_t magic; /* FAT_MAGIC or FAT_MAGIC_64 */
- uint32_t nfat_arch; /* number of structs that follow */
-};
-
-struct fat_arch {
- int cputype; /* cpu specifier (int) */
- int cpusubtype; /* machine specifier (int) */
- uint32_t offset; /* file offset to this object file */
- uint32_t size; /* size of this object file */
- uint32_t align; /* alignment as a power of 2 */
-};
-
-#define FAT_MAGIC 0xcafebabe
-#define FAT_CIGAM 0xbebafeca
-#define FAT_MAGIC_64 0xcafebabf
-#define FAT_CIGAM_64 0xbfbafeca
-
-struct mach_header {
- uint32_t magic; /* mach magic number identifier */
- int cputype; /* cpu specifier */
- int cpusubtype; /* machine specifier */
- uint32_t filetype; /* type of file */
- uint32_t ncmds; /* number of load commands */
- uint32_t sizeofcmds; /* the size of all the load commands */
- uint32_t flags; /* flags */
-};
-
-struct mach_header_64 {
- struct mach_header mh;
- uint32_t reserved; /* reserved, pad to 64bit */
-};
-
-/* Constant for the magic field of the mach_header (32-bit architectures) */
-#define MH_MAGIC 0xfeedface /* the mach magic number */
-#define MH_CIGAM 0xcefaedfe /* NXSwapInt(MH_MAGIC) */
-#define MH_MAGIC_64 0xfeedfacf /* the 64-bit mach magic number */
-#define MH_CIGAM_64 0xcffaedfe /* NXSwapInt(MH_MAGIC_64) */
-
-struct load_command {
- uint32_t cmd; /* type of load command */
- uint32_t cmdsize; /* total size of command in bytes */
-};
-
-#define LC_REQ_DYLD 0x80000000
-#define LC_SYMTAB 0x2
-#define LC_DYSYMTAB 0xb
-#define LC_LOAD_DYLIB 0xc
-#define LC_ID_DYLIB 0xd
-#define LC_LOAD_DYLINKER 0xe
-#define LC_SEGMENT_64 0x19
-#define LC_RPATH (0x1c | LC_REQ_DYLD)
-#define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD)
-#define LC_DYLD_INFO_ONLY (0x22|LC_REQ_DYLD)
-#define LC_MAIN (0x28|LC_REQ_DYLD)
-#define LC_SOURCE_VERSION 0x2A
-#define LC_BUILD_VERSION 0x32
-#define LC_DYLD_EXPORTS_TRIE (0x33 | LC_REQ_DYLD)
-#define LC_DYLD_CHAINED_FIXUPS (0x34 | LC_REQ_DYLD)
-
-#define SG_READ_ONLY 0x10 /* This segment is made read-only after fixups */
-
-typedef int vm_prot_t;
-
-struct segment_command_64 { /* for 64-bit architectures */
- uint32_t cmd; /* LC_SEGMENT_64 */
- uint32_t cmdsize; /* includes sizeof section_64 structs */
- char segname[16]; /* segment name */
- uint64_t vmaddr; /* memory address of this segment */
- uint64_t vmsize; /* memory size of this segment */
- uint64_t fileoff; /* file offset of this segment */
- uint64_t filesize; /* amount to map from the file */
- vm_prot_t maxprot; /* maximum VM protection */
- vm_prot_t initprot; /* initial VM protection */
- uint32_t nsects; /* number of sections in segment */
- uint32_t flags; /* flags */
-};
-
-struct section_64 { /* for 64-bit architectures */
- char sectname[16]; /* name of this section */
- char segname[16]; /* segment this section goes in */
- uint64_t addr; /* memory address of this section */
- uint64_t size; /* size in bytes of this section */
- uint32_t offset; /* file offset of this section */
- uint32_t align; /* section alignment (power of 2) */
- uint32_t reloff; /* file offset of relocation entries */
- uint32_t nreloc; /* number of relocation entries */
- uint32_t flags; /* flags (section type and attributes)*/
- uint32_t reserved1; /* reserved (for offset or index) */
- uint32_t reserved2; /* reserved (for count or sizeof) */
- uint32_t reserved3; /* reserved */
-};
-
-enum {
- DYLD_CHAINED_IMPORT = 1,
-};
-
-struct dyld_chained_fixups_header {
- uint32_t fixups_version; ///< 0
- uint32_t starts_offset; ///< Offset of dyld_chained_starts_in_image.
- uint32_t imports_offset; ///< Offset of imports table in chain_data.
- uint32_t symbols_offset; ///< Offset of symbol strings in chain_data.
- uint32_t imports_count; ///< Number of imported symbol names.
- uint32_t imports_format; ///< DYLD_CHAINED_IMPORT*
- uint32_t symbols_format; ///< 0 => uncompressed, 1 => zlib compressed
-};
-
-struct dyld_chained_starts_in_image
-{
- uint32_t seg_count;
- uint32_t seg_info_offset[1]; // each entry is offset into this struct for that segment
- // followed by pool of dyld_chain_starts_in_segment data
-};
-
-enum {
- DYLD_CHAINED_PTR_64 = 2, // target is vmaddr
- DYLD_CHAINED_PTR_64_OFFSET = 6, // target is vm offset
-};
-
-enum {
- DYLD_CHAINED_PTR_START_NONE = 0xFFFF, // used in page_start[] to denote a page with no fixups
-};
-
-#define SEG_PAGE_SIZE 16384
-
-struct dyld_chained_starts_in_segment
-{
- uint32_t size; // size of this (amount kernel needs to copy)
- uint16_t page_size; // 0x1000 or 0x4000
- uint16_t pointer_format; // DYLD_CHAINED_PTR_*
- uint64_t segment_offset; // offset in memory to start of segment
- uint32_t max_valid_pointer; // for 32-bit OS, any value beyond this is not a pointer
- uint16_t page_count; // how many pages are in array
- uint16_t page_start[1]; // each entry is offset in each page of first element in chain
- // or DYLD_CHAINED_PTR_START_NONE if no fixups on page
-};
-
-enum BindSpecialDylib {
- BIND_SPECIAL_DYLIB_FLAT_LOOKUP = -2,
-};
-
-struct dyld_chained_import
-{
- uint32_t lib_ordinal : 8,
- weak_import : 1,
- name_offset : 23;
-};
-
-struct dyld_chained_ptr_64_rebase
-{
- uint64_t target : 36, // vmaddr, 64GB max image size
- high8 : 8, // top 8 bits set to this after slide added
- reserved : 7, // all zeros
- next : 12, // 4-byte stride
- bind : 1; // == 0
-};
-
-struct dyld_chained_ptr_64_bind
-{
- uint64_t ordinal : 24,
- addend : 8, // 0 thru 255
- reserved : 19, // all zeros
- next : 12, // 4-byte stride
- bind : 1; // == 1
-};
-
-#define S_REGULAR 0x0
-#define S_ZEROFILL 0x1
-#define S_NON_LAZY_SYMBOL_POINTERS 0x6
-#define S_LAZY_SYMBOL_POINTERS 0x7
-#define S_SYMBOL_STUBS 0x8
-#define S_MOD_INIT_FUNC_POINTERS 0x9
-#define S_MOD_TERM_FUNC_POINTERS 0xa
-
-#define S_ATTR_PURE_INSTRUCTIONS 0x80000000
-#define S_ATTR_SOME_INSTRUCTIONS 0x00000400
-#define S_ATTR_DEBUG 0x02000000
-
-
-typedef uint32_t lc_str;
-
-struct dylib_command {
- uint32_t cmd; /* LC_ID_DYLIB, LC_LOAD_{,WEAK_}DYLIB,
- LC_REEXPORT_DYLIB */
- uint32_t cmdsize; /* includes pathname string */
- lc_str name; /* library's path name */
- uint32_t timestamp; /* library's build time stamp */
- uint32_t current_version; /* library's current version number */
- uint32_t compatibility_version; /* library's compatibility vers number*/
-};
-
-struct rpath_command {
- uint32_t cmd; /* LC_RPATH */
- uint32_t cmdsize; /* includes string */
- lc_str path; /* path to add to run path */
-};
-
-struct dylinker_command {
- uint32_t cmd; /* LC_ID_DYLINKER, LC_LOAD_DYLINKER or
- LC_DYLD_ENVIRONMENT */
- uint32_t cmdsize; /* includes pathname string */
- lc_str name; /* dynamic linker's path name */
-};
-
-struct linkedit_data_command {
- uint32_t cmd; /* LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO,
- LC_FUNCTION_STARTS, LC_DATA_IN_CODE,
- LC_DYLIB_CODE_SIGN_DRS,
- LC_LINKER_OPTIMIZATION_HINT,
- LC_DYLD_EXPORTS_TRIE, or
- LC_DYLD_CHAINED_FIXUPS. */
- uint32_t cmdsize; /* sizeof(struct linkedit_data_command) */
- uint32_t dataoff; /* file offset of data in __LINKEDIT segment */
- uint32_t datasize; /* file size of data in __LINKEDIT segment */
-};
-
-#define PLATFORM_MACOS 1
-
-struct build_version_command {
- uint32_t cmd; /* LC_BUILD_VERSION */
- uint32_t cmdsize; /* sizeof(struct build_version_command) plus */
- /* ntools * sizeof(struct build_tool_version) */
- uint32_t platform; /* platform */
- uint32_t minos; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
- uint32_t sdk; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
- uint32_t ntools; /* number of tool entries following this */
-};
-
-struct source_version_command {
- uint32_t cmd; /* LC_SOURCE_VERSION */
- uint32_t cmdsize; /* 16 */
- uint64_t version; /* A.B.C.D.E packed as a24.b10.c10.d10.e10 */
-};
-
-struct symtab_command {
- uint32_t cmd; /* LC_SYMTAB */
- uint32_t cmdsize; /* sizeof(struct symtab_command) */
- uint32_t symoff; /* symbol table offset */
- uint32_t nsyms; /* number of symbol table entries */
- uint32_t stroff; /* string table offset */
- uint32_t strsize; /* string table size in bytes */
-};
-
-struct dysymtab_command {
- uint32_t cmd; /* LC_DYSYMTAB */
- uint32_t cmdsize; /* sizeof(struct dysymtab_command) */
-
- uint32_t ilocalsym; /* index to local symbols */
- uint32_t nlocalsym; /* number of local symbols */
-
- uint32_t iextdefsym;/* index to externally defined symbols */
- uint32_t nextdefsym;/* number of externally defined symbols */
-
- uint32_t iundefsym; /* index to undefined symbols */
- uint32_t nundefsym; /* number of undefined symbols */
-
- uint32_t tocoff; /* file offset to table of contents */
- uint32_t ntoc; /* number of entries in table of contents */
-
- uint32_t modtaboff; /* file offset to module table */
- uint32_t nmodtab; /* number of module table entries */
-
- uint32_t extrefsymoff; /* offset to referenced symbol table */
- uint32_t nextrefsyms; /* number of referenced symbol table entries */
-
- uint32_t indirectsymoff;/* file offset to the indirect symbol table */
- uint32_t nindirectsyms; /* number of indirect symbol table entries */
-
- uint32_t extreloff; /* offset to external relocation entries */
- uint32_t nextrel; /* number of external relocation entries */
- uint32_t locreloff; /* offset to local relocation entries */
- uint32_t nlocrel; /* number of local relocation entries */
-};
-
-#define BIND_OPCODE_DONE 0x00
-#define BIND_OPCODE_SET_DYLIB_SPECIAL_IMM 0x30
-#define BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM 0x40
-#define BIND_OPCODE_SET_TYPE_IMM 0x50
-#define BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB 0x70
-#define BIND_OPCODE_DO_BIND 0x90
-
-#define BIND_SYMBOL_FLAGS_WEAK_IMPORT 0x1
-
-#define BIND_TYPE_POINTER 1
-#define BIND_SPECIAL_DYLIB_FLAT_LOOKUP -2
-
-#define REBASE_OPCODE_DONE 0x00
-#define REBASE_OPCODE_SET_TYPE_IMM 0x10
-#define REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB 0x20
-#define REBASE_OPCODE_DO_REBASE_IMM_TIMES 0x50
-
-#define REBASE_TYPE_POINTER 1
-
-#define EXPORT_SYMBOL_FLAGS_KIND_REGULAR 0x00
-#define EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE 0x02
-#define EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION 0x04
-
-struct dyld_info_command {
- uint32_t cmd; /* LC_DYLD_INFO or LC_DYLD_INFO_ONLY */
- uint32_t cmdsize; /* sizeof(struct dyld_info_command) */
- uint32_t rebase_off; /* file offset to rebase info */
- uint32_t rebase_size; /* size of rebase info */
- uint32_t bind_off; /* file offset to binding info */
- uint32_t bind_size; /* size of binding info */
- uint32_t weak_bind_off; /* file offset to weak binding info */
- uint32_t weak_bind_size; /* size of weak binding info */
- uint32_t lazy_bind_off; /* file offset to lazy binding info */
- uint32_t lazy_bind_size; /* size of lazy binding infs */
- uint32_t export_off; /* file offset to lazy binding info */
- uint32_t export_size; /* size of lazy binding infs */
-};
-
-#define INDIRECT_SYMBOL_LOCAL 0x80000000
-
-struct entry_point_command {
- uint32_t cmd; /* LC_MAIN only used in MH_EXECUTE filetypes */
- uint32_t cmdsize; /* 24 */
- uint64_t entryoff; /* file (__TEXT) offset of main() */
- uint64_t stacksize;/* if not zero, initial stack size */
-};
-
-enum skind {
- sk_unknown = 0,
- sk_discard,
- sk_text,
- sk_stubs,
- sk_stub_helper,
- sk_ro_data,
- sk_uw_info,
- sk_nl_ptr, // non-lazy pointers, aka GOT
- sk_debug_info,
- sk_debug_abbrev,
- sk_debug_line,
- sk_debug_aranges,
- sk_debug_str,
- sk_debug_line_str,
- sk_stab,
- sk_stab_str,
- sk_la_ptr, // lazy pointers
- sk_init,
- sk_fini,
- sk_rw_data,
- sk_bss,
- sk_linkedit,
- sk_last
-};
-
-struct nlist_64 {
- uint32_t n_strx; /* index into the string table */
- uint8_t n_type; /* type flag, see below */
- uint8_t n_sect; /* section number or NO_SECT */
- uint16_t n_desc; /* see */
- uint64_t n_value; /* value of this symbol (or stab offset) */
-};
-
-#define N_UNDF 0x0
-#define N_ABS 0x2
-#define N_EXT 0x1
-#define N_SECT 0xe
-
-#define N_WEAK_REF 0x0040
-#define N_WEAK_DEF 0x0080
-
-struct macho {
- struct mach_header_64 mh;
- int *seg2lc, nseg;
- struct load_command **lc;
- struct entry_point_command *ep;
- int nlc;
- struct {
- Section *s;
- int machosect;
- } sk_to_sect[sk_last];
- int *elfsectomacho;
- int *e2msym;
- Section *symtab, *strtab, *indirsyms, *stubs, *exports;
- uint32_t ilocal, iextdef, iundef;
- int stubsym, n_got, nr_plt;
- int segment[sk_last];
-#ifdef CONFIG_NEW_MACHO
- Section *chained_fixups;
- int n_bind;
- int n_bind_rebase;
- struct bind_rebase {
- int section;
- int bind;
- ElfW_Rel rel;
- } *bind_rebase;
-#else
- Section *rebase, *binding, *weak_binding, *lazy_binding;
- Section *stub_helper, *la_symbol_ptr;
- struct dyld_info_command *dyldinfo;
- int helpsym, lasym, dyld_private, dyld_stub_binder;
- int n_lazy_bind;
- struct s_lazy_bind {
- int section;
- int bind_offset;
- int la_symbol_offset;
- ElfW_Rel rel;
- } *s_lazy_bind;
- int n_rebase;
- struct s_rebase {
- int section;
- ElfW_Rel rel;
- } *s_rebase;
- int n_bind;
- struct bind {
- int section;
- ElfW_Rel rel;
- } *bind;
-#endif
-};
-
-#define SHT_LINKEDIT (SHT_LOOS + 42)
-#define SHN_FROMDLL (SHN_LOOS + 2) /* Symbol is undefined, comes from a DLL */
-
-static void * add_lc(struct macho *mo, uint32_t cmd, uint32_t cmdsize)
-{
- struct load_command *lc = tcc_mallocz(cmdsize);
- lc->cmd = cmd;
- lc->cmdsize = cmdsize;
- mo->lc = tcc_realloc(mo->lc, sizeof(mo->lc[0]) * (mo->nlc + 1));
- mo->lc[mo->nlc++] = lc;
- return lc;
-}
-
-static struct segment_command_64 * add_segment(struct macho *mo, const char *name)
-{
- struct segment_command_64 *sc = add_lc(mo, LC_SEGMENT_64, sizeof(*sc));
- strncpy(sc->segname, name, 16);
- mo->seg2lc = tcc_realloc(mo->seg2lc, sizeof(*mo->seg2lc) * (mo->nseg + 1));
- mo->seg2lc[mo->nseg++] = mo->nlc - 1;
- return sc;
-}
-
-static struct segment_command_64 * get_segment(struct macho *mo, int i)
-{
- return (struct segment_command_64 *) (mo->lc[mo->seg2lc[i]]);
-}
-
-static int add_section(struct macho *mo, struct segment_command_64 **_seg, const char *name)
-{
- struct segment_command_64 *seg = *_seg;
- int ret = seg->nsects;
- struct section_64 *sec;
- seg->nsects++;
- seg->cmdsize += sizeof(*sec);
- seg = tcc_realloc(seg, sizeof(*seg) + seg->nsects * sizeof(*sec));
- sec = (struct section_64*)((char*)seg + sizeof(*seg)) + ret;
- memset(sec, 0, sizeof(*sec));
- strncpy(sec->sectname, name, 16);
- strncpy(sec->segname, seg->segname, 16);
- *_seg = seg;
- return ret;
-}
-
-static struct section_64 *get_section(struct segment_command_64 *seg, int i)
-{
- return (struct section_64*)((char*)seg + sizeof(*seg)) + i;
-}
-
-static void * add_dylib(struct macho *mo, char *name)
-{
- struct dylib_command *lc;
- int sz = (sizeof(*lc) + strlen(name) + 1 + 7) & -8;
- lc = add_lc(mo, LC_LOAD_DYLIB, sz);
- lc->name = sizeof(*lc);
- strcpy((char*)lc + lc->name, name);
- lc->timestamp = 2;
- lc->current_version = 1 << 16;
- lc->compatibility_version = 1 << 16;
- return lc;
-}
-
-static int uleb128_size (unsigned long long value)
-{
- int size = 0;
-
- do {
- value >>= 7;
- size++;
- } while (value != 0);
- return size;
-}
-
-static void write_uleb128(Section *section, uint64_t value)
-{
- do {
- unsigned char byte = value & 0x7f;
- uint8_t *ptr = section_ptr_add(section, 1);
-
- value >>= 7;
- *ptr = byte | (value ? 0x80 : 0);
- } while (value != 0);
-}
-
-static void tcc_macho_add_destructor(TCCState *s1)
-{
- int init_sym, mh_execute_header, at_exit_sym;
- Section *s;
- ElfW_Rel *rel;
- uint8_t *ptr;
-
- mh_execute_header = put_elf_sym(s1->symtab, -4096, 0,
- ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT), 0,
- text_section->sh_num, "__mh_execute_header");
- s = find_section(s1, ".fini_array");
- if (s->data_offset == 0)
- return;
- init_sym = put_elf_sym(s1->symtab, text_section->data_offset, 0,
- ELFW(ST_INFO)(STB_LOCAL, STT_FUNC), 0,
- text_section->sh_num, "___GLOBAL_init_65535");
- at_exit_sym = put_elf_sym(s1->symtab, 0, 0,
- ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0,
- SHN_UNDEF, "___cxa_atexit");
-#ifdef TCC_TARGET_X86_64
- ptr = section_ptr_add(text_section, 4);
- ptr[0] = 0x55; // pushq %rbp
- ptr[1] = 0x48; // movq %rsp, %rbp
- ptr[2] = 0x89;
- ptr[3] = 0xe5;
- for_each_elem(s->reloc, 0, rel, ElfW_Rel) {
- int sym_index = ELFW(R_SYM)(rel->r_info);
-
- ptr = section_ptr_add(text_section, 26);
- ptr[0] = 0x48; // lea destructor(%rip),%rax
- ptr[1] = 0x8d;
- ptr[2] = 0x05;
- put_elf_reloca(s1->symtab, text_section,
- text_section->data_offset - 23,
- R_X86_64_PC32, sym_index, -4);
- ptr[7] = 0x48; // mov %rax,%rdi
- ptr[8] = 0x89;
- ptr[9] = 0xc7;
- ptr[10] = 0x31; // xorl %ecx, %ecx
- ptr[11] = 0xc9;
- ptr[12] = 0x89; // movl %ecx, %esi
- ptr[13] = 0xce;
- ptr[14] = 0x48; // lea mh_execute_header(%rip),%rdx
- ptr[15] = 0x8d;
- ptr[16] = 0x15;
- put_elf_reloca(s1->symtab, text_section,
- text_section->data_offset - 9,
- R_X86_64_PC32, mh_execute_header, -4);
- ptr[21] = 0xe8; // call __cxa_atexit
- put_elf_reloca(s1->symtab, text_section,
- text_section->data_offset - 4,
- R_X86_64_PLT32, at_exit_sym, -4);
- }
- ptr = section_ptr_add(text_section, 2);
- ptr[0] = 0x5d; // pop %rbp
- ptr[1] = 0xc3; // ret
-#elif defined TCC_TARGET_ARM64
- ptr = section_ptr_add(text_section, 8);
- write32le(ptr, 0xa9bf7bfd); // stp x29, x30, [sp, #-16]!
- write32le(ptr + 4, 0x910003fd); // mov x29, sp
- for_each_elem(s->reloc, 0, rel, ElfW_Rel) {
- int sym_index = ELFW(R_SYM)(rel->r_info);
-
- ptr = section_ptr_add(text_section, 24);
- put_elf_reloc(s1->symtab, text_section,
- text_section->data_offset - 24,
- R_AARCH64_ADR_PREL_PG_HI21, sym_index);
- write32le(ptr, 0x90000000); // adrp x0, destructor@page
- put_elf_reloc(s1->symtab, text_section,
- text_section->data_offset - 20,
- R_AARCH64_LDST8_ABS_LO12_NC, sym_index);
- write32le(ptr + 4, 0x91000000); // add x0,x0,destructor@pageoff
- write32le(ptr + 8, 0xd2800001); // mov x1, #0
- put_elf_reloc(s1->symtab, text_section,
- text_section->data_offset - 12,
- R_AARCH64_ADR_PREL_PG_HI21, mh_execute_header);
- write32le(ptr + 12, 0x90000002); // adrp x2, mh_execute_header@page
- put_elf_reloc(s1->symtab, text_section,
- text_section->data_offset - 8,
- R_AARCH64_LDST8_ABS_LO12_NC, mh_execute_header);
- write32le(ptr + 16, 0x91000042); // add x2,x2,mh_execute_header@pageoff
- put_elf_reloc(s1->symtab, text_section,
- text_section->data_offset - 4,
- R_AARCH64_CALL26, at_exit_sym);
- write32le(ptr + 20, 0x94000000); // bl __cxa_atexit
- }
- ptr = section_ptr_add(text_section, 8);
- write32le(ptr, 0xa8c17bfd); // ldp x29, x30, [sp], #16
- write32le(ptr + 4, 0xd65f03c0); // ret
-#endif
- s->reloc->data_offset = s->data_offset = 0;
- s->sh_flags &= ~SHF_ALLOC;
- add_array (s1, ".init_array", init_sym);
-}
-
-#ifdef CONFIG_NEW_MACHO
-static void bind_rebase_add(struct macho *mo, int bind, int sh_info,
- ElfW_Rel *rel, struct sym_attr *attr)
-{
- mo->bind_rebase = tcc_realloc(mo->bind_rebase, (mo->n_bind_rebase + 1) *
- sizeof(struct bind_rebase));
- mo->bind_rebase[mo->n_bind_rebase].section = sh_info;
- mo->bind_rebase[mo->n_bind_rebase].bind = bind;
- mo->bind_rebase[mo->n_bind_rebase].rel = *rel;
- if (attr)
- mo->bind_rebase[mo->n_bind_rebase].rel.r_offset = attr->got_offset;
- mo->n_bind_rebase++;
- mo->n_bind += bind;
-}
-
-static void check_relocs(TCCState *s1, struct macho *mo)
-{
- Section *s;
- ElfW_Rel *rel, save_rel;
- ElfW(Sym) *sym;
- int i, j, type, gotplt_entry, sym_index, for_code;
- uint32_t *pi, *goti;
- struct sym_attr *attr;
-
- goti = NULL;
- mo->nr_plt = mo->n_got = 0;
- for (i = 1; i < s1->nb_sections; i++) {
- s = s1->sections[i];
- if (s->sh_type != SHT_RELX ||
- !strncmp(s1->sections[s->sh_info]->name, ".debug_", 7))
- continue;
- for_each_elem(s, 0, rel, ElfW_Rel) {
- save_rel = *rel;
- type = ELFW(R_TYPE)(rel->r_info);
- gotplt_entry = gotplt_entry_type(type);
- for_code = code_reloc(type);
- /* We generate a non-lazy pointer for used undefined symbols
- and for defined symbols that must have a place for their
- address due to codegen (i.e. a reloc requiring a got slot). */
- sym_index = ELFW(R_SYM)(rel->r_info);
- sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
- if (sym->st_shndx == SHN_UNDEF
- || gotplt_entry == ALWAYS_GOTPLT_ENTRY) {
- attr = get_sym_attr(s1, sym_index, 1);
- if (!attr->dyn_index) {
- attr->got_offset = s1->got->data_offset;
- attr->plt_offset = -1;
- attr->dyn_index = 1; /* used as flag */
- section_ptr_add(s1->got, PTR_SIZE);
- put_elf_reloc(s1->symtab, s1->got, attr->got_offset,
- R_JMP_SLOT, sym_index);
- goti = tcc_realloc(goti, (mo->n_got + 1) * sizeof(*goti));
- if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
- if (sym->st_shndx == SHN_UNDEF)
- tcc_error("undefined local symbo: '%s'",
- (char *) symtab_section->link->data + sym->st_name);
- goti[mo->n_got++] = INDIRECT_SYMBOL_LOCAL;
- } else {
- goti[mo->n_got++] = mo->e2msym[sym_index];
- if (sym->st_shndx == SHN_UNDEF
-#ifdef TCC_TARGET_X86_64
- && type == R_X86_64_GOTPCREL
-#elif defined TCC_TARGET_ARM64
- && type == R_AARCH64_ADR_GOT_PAGE
-#endif
- ) {
- attr->plt_offset = -mo->n_bind_rebase - 2;
- bind_rebase_add(mo, 1, s1->got->reloc->sh_info, &save_rel, attr);
- s1->got->reloc->data_offset -= sizeof (ElfW_Rel);
- }
- if (for_code && sym->st_shndx == SHN_UNDEF)
- s1->got->reloc->data_offset -= sizeof (ElfW_Rel);
- }
- }
- if (for_code && sym->st_shndx == SHN_UNDEF) {
- if ((int)attr->plt_offset < -1) {
- /* remove above bind and replace with plt */
- mo->bind_rebase[-attr->plt_offset - 2].bind = 2;
- attr->plt_offset = -1;
- }
- if (attr->plt_offset == -1) {
- uint8_t *jmp;
-
- attr->plt_offset = mo->stubs->data_offset;
-#ifdef TCC_TARGET_X86_64
- if (type != R_X86_64_PLT32)
- continue;
- jmp = section_ptr_add(mo->stubs, 6);
- jmp[0] = 0xff; /* jmpq *ofs(%rip) */
- jmp[1] = 0x25;
- put_elf_reloc(s1->symtab, mo->stubs,
- attr->plt_offset + 2,
- R_X86_64_GOTPCREL, sym_index);
-#elif defined TCC_TARGET_ARM64
- if (type != R_AARCH64_CALL26)
- continue;
- jmp = section_ptr_add(mo->stubs, 12);
- put_elf_reloc(s1->symtab, mo->stubs,
- attr->plt_offset,
- R_AARCH64_ADR_GOT_PAGE, sym_index);
- write32le(jmp, // adrp x16, #sym
- 0x90000010);
- put_elf_reloc(s1->symtab, mo->stubs,
- attr->plt_offset + 4,
- R_AARCH64_LD64_GOT_LO12_NC, sym_index);
- write32le(jmp + 4, // ld x16,[x16, #sym]
- 0xf9400210);
- write32le(jmp + 8, // br x16
- 0xd61f0200);
-#endif
- bind_rebase_add(mo, 1, s1->got->reloc->sh_info, &save_rel, attr);
- pi = section_ptr_add(mo->indirsyms, sizeof(*pi));
- *pi = mo->e2msym[sym_index];
- mo->nr_plt++;
- }
- rel->r_info = ELFW(R_INFO)(mo->stubsym, type);
- rel->r_addend += attr->plt_offset;
- }
- }
- if (type == R_DATA_PTR || type == R_JMP_SLOT)
- bind_rebase_add(mo, sym->st_shndx == SHN_UNDEF ? 1 : 0,
- s->sh_info, &save_rel, NULL);
- }
- }
- /* remove deleted binds */
- for (i = 0, j = 0; i < mo->n_bind_rebase; i++)
- if (mo->bind_rebase[i].bind == 2)
- mo->n_bind--;
- else
- mo->bind_rebase[j++] = mo->bind_rebase[i];
- mo->n_bind_rebase = j;
- pi = section_ptr_add(mo->indirsyms, mo->n_got * sizeof(*pi));
- memcpy(pi, goti, mo->n_got * sizeof(*pi));
- tcc_free(goti);
-}
-
-#else
-
-static void check_relocs(TCCState *s1, struct macho *mo)
-{
- uint8_t *jmp;
- Section *s;
- ElfW_Rel *rel, save_rel;
- ElfW(Sym) *sym;
- int i, type, gotplt_entry, sym_index, for_code;
- int bind_offset, la_symbol_offset;
- uint32_t *pi, *goti;
- struct sym_attr *attr;
-
-#ifdef TCC_TARGET_X86_64
- jmp = section_ptr_add(mo->stub_helper, 16);
- jmp[0] = 0x4c; /* leaq _dyld_private(%rip), %r11 */
- jmp[1] = 0x8d;
- jmp[2] = 0x1d;
- put_elf_reloca(s1->symtab, mo->stub_helper, 3,
- R_X86_64_PC32, mo->dyld_private, -4);
- jmp[7] = 0x41; /* pushq %r11 */
- jmp[8] = 0x53;
- jmp[9] = 0xff; /* jmpq *dyld_stub_binder@GOT(%rip) */
- jmp[10] = 0x25;
- put_elf_reloca(s1->symtab, mo->stub_helper, 11,
- R_X86_64_GOTPCREL, mo->dyld_stub_binder, -4);
- jmp[15] = 0x90; /* nop */
-#elif defined TCC_TARGET_ARM64
- jmp = section_ptr_add(mo->stub_helper, 24);
- put_elf_reloc(s1->symtab, mo->stub_helper, 0,
- R_AARCH64_ADR_PREL_PG_HI21, mo->dyld_private);
- write32le(jmp, 0x90000011); // adrp x17, _dyld_private@page
- put_elf_reloc(s1->symtab, mo->stub_helper, 4,
- R_AARCH64_LDST64_ABS_LO12_NC, mo->dyld_private);
- write32le(jmp + 4, 0x91000231); // add x17,x17,_dyld_private@pageoff
- write32le(jmp + 8, 0xa9bf47f0); // stp x16/x17, [sp, #-16]!
- put_elf_reloc(s1->symtab, mo->stub_helper, 12,
- R_AARCH64_ADR_GOT_PAGE, mo->dyld_stub_binder);
- write32le(jmp + 12, 0x90000010); // adrp x16, dyld_stub_binder@page
- put_elf_reloc(s1->symtab, mo->stub_helper, 16,
- R_AARCH64_LD64_GOT_LO12_NC, mo->dyld_stub_binder);
- write32le(jmp + 16, 0xf9400210); // ldr x16,[x16,dyld_stub_binder@pageoff]
- write32le(jmp + 20, 0xd61f0200); // br x16
-#endif
-
- goti = NULL;
- mo->nr_plt = mo->n_got = 0;
- for (i = 1; i < s1->nb_sections; i++) {
- s = s1->sections[i];
- if (s->sh_type != SHT_RELX ||
- !strncmp(s1->sections[s->sh_info]->name, ".debug_", 7))
- continue;
- for_each_elem(s, 0, rel, ElfW_Rel) {
- save_rel = *rel;
- type = ELFW(R_TYPE)(rel->r_info);
- gotplt_entry = gotplt_entry_type(type);
- for_code = code_reloc(type);
- /* We generate a non-lazy pointer for used undefined symbols
- and for defined symbols that must have a place for their
- address due to codegen (i.e. a reloc requiring a got slot). */
- sym_index = ELFW(R_SYM)(rel->r_info);
- sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
- if (sym->st_shndx == SHN_UNDEF
- || gotplt_entry == ALWAYS_GOTPLT_ENTRY) {
- attr = get_sym_attr(s1, sym_index, 1);
- if (!attr->dyn_index) {
- attr->got_offset = s1->got->data_offset;
- attr->plt_offset = -1;
- attr->dyn_index = 1; /* used as flag */
- section_ptr_add(s1->got, PTR_SIZE);
- put_elf_reloc(s1->symtab, s1->got, attr->got_offset,
- R_JMP_SLOT, sym_index);
- goti = tcc_realloc(goti, (mo->n_got + 1) * sizeof(*goti));
- if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
- if (sym->st_shndx == SHN_UNDEF)
- tcc_error("undefined local symbo: '%s'",
- (char *) symtab_section->link->data + sym->st_name);
- goti[mo->n_got++] = INDIRECT_SYMBOL_LOCAL;
- } else {
- goti[mo->n_got++] = mo->e2msym[sym_index];
- if (sym->st_shndx == SHN_UNDEF
-#ifdef TCC_TARGET_X86_64
- && type == R_X86_64_GOTPCREL
-#elif defined TCC_TARGET_ARM64
- && type == R_AARCH64_ADR_GOT_PAGE
-#endif
- ) {
- mo->bind =
- tcc_realloc(mo->bind,
- (mo->n_bind + 1) *
- sizeof(struct bind));
- mo->bind[mo->n_bind].section = s1->got->reloc->sh_info;
- mo->bind[mo->n_bind].rel = save_rel;
- mo->bind[mo->n_bind].rel.r_offset = attr->got_offset;
- mo->n_bind++;
- s1->got->reloc->data_offset -= sizeof (ElfW_Rel);
- }
- }
- }
- if (for_code && sym->st_shndx == SHN_UNDEF) {
- if (attr->plt_offset == -1) {
- attr->plt_offset = mo->stubs->data_offset;
-#ifdef TCC_TARGET_X86_64
- if (type != R_X86_64_PLT32)
- continue;
- /* __stubs */
- jmp = section_ptr_add(mo->stubs, 6);
- jmp[0] = 0xff; /* jmpq *__la_symbol_ptr(%rip) */
- jmp[1] = 0x25;
- put_elf_reloca(s1->symtab, mo->stubs,
- mo->stubs->data_offset - 4,
- R_X86_64_PC32, mo->lasym,
- mo->la_symbol_ptr->data_offset - 4);
-
- /* __stub_helper */
- bind_offset = mo->stub_helper->data_offset + 1;
- jmp = section_ptr_add(mo->stub_helper, 10);
- jmp[0] = 0x68; /* pushq $bind_offset */
- jmp[5] = 0xe9; /* jmpq __stub_helper */
- write32le(jmp + 6, -mo->stub_helper->data_offset);
-
- /* __la_symbol_ptr */
- la_symbol_offset = mo->la_symbol_ptr->data_offset;
- put_elf_reloca(s1->symtab, mo->la_symbol_ptr,
- mo->la_symbol_ptr->data_offset,
- R_DATA_PTR, mo->helpsym,
- mo->stub_helper->data_offset - 10);
- section_ptr_add(mo->la_symbol_ptr, PTR_SIZE);
-#elif defined TCC_TARGET_ARM64
- if (type != R_AARCH64_CALL26)
- continue;
- /* __stubs */
- jmp = section_ptr_add(mo->stubs, 12);
- put_elf_reloca(s1->symtab, mo->stubs,
- mo->stubs->data_offset - 12,
- R_AARCH64_ADR_PREL_PG_HI21, mo->lasym,
- mo->la_symbol_ptr->data_offset);
- write32le(jmp, // adrp x16, __la_symbol_ptr@page
- 0x90000010);
- put_elf_reloca(s1->symtab, mo->stubs,
- mo->stubs->data_offset - 8,
- R_AARCH64_LDST64_ABS_LO12_NC, mo->lasym,
- mo->la_symbol_ptr->data_offset);
- write32le(jmp + 4, // ldr x16,[x16, __la_symbol_ptr@pageoff]
- 0xf9400210);
- write32le(jmp + 8, // br x16
- 0xd61f0200);
-
- /* __stub_helper */
- bind_offset = mo->stub_helper->data_offset + 8;
- jmp = section_ptr_add(mo->stub_helper, 12);
- write32le(jmp + 0, // ldr w16, l0
- 0x18000050);
- write32le(jmp + 4, // b stubHelperHeader
- 0x14000000 +
- ((-(mo->stub_helper->data_offset - 8) / 4) &
- 0x3ffffff));
- write32le(jmp + 8, 0); // l0: .long bind_offset
-
- /* __la_symbol_ptr */
- la_symbol_offset = mo->la_symbol_ptr->data_offset;
- put_elf_reloca(s1->symtab, mo->la_symbol_ptr,
- mo->la_symbol_ptr->data_offset,
- R_DATA_PTR, mo->helpsym,
- mo->stub_helper->data_offset - 12);
- section_ptr_add(mo->la_symbol_ptr, PTR_SIZE);
-#endif
- mo->s_lazy_bind =
- tcc_realloc(mo->s_lazy_bind, (mo->n_lazy_bind + 1) *
- sizeof(struct s_lazy_bind));
- mo->s_lazy_bind[mo->n_lazy_bind].section =
- mo->stub_helper->reloc->sh_info;
- mo->s_lazy_bind[mo->n_lazy_bind].bind_offset =
- bind_offset;
- mo->s_lazy_bind[mo->n_lazy_bind].la_symbol_offset =
- la_symbol_offset;
- mo->s_lazy_bind[mo->n_lazy_bind].rel = save_rel;
- mo->s_lazy_bind[mo->n_lazy_bind].rel.r_offset =
- attr->plt_offset;
- mo->n_lazy_bind++;
- pi = section_ptr_add(mo->indirsyms, sizeof(*pi));
- *pi = mo->e2msym[sym_index];
- mo->nr_plt++;
- }
- rel->r_info = ELFW(R_INFO)(mo->stubsym, type);
- rel->r_addend += attr->plt_offset;
- }
- }
- if (type == R_DATA_PTR || type == R_JMP_SLOT) {
- if (sym->st_shndx == SHN_UNDEF) {
- mo->bind = tcc_realloc(mo->bind,
- (mo->n_bind + 1) *
- sizeof(struct bind));
- mo->bind[mo->n_bind].section = s->sh_info;
- mo->bind[mo->n_bind].rel = save_rel;
- mo->n_bind++;
- }
- else {
- mo->s_rebase =
- tcc_realloc(mo->s_rebase, (mo->n_rebase + 1) *
- sizeof(struct s_rebase));
- mo->s_rebase[mo->n_rebase].section = s->sh_info;
- mo->s_rebase[mo->n_rebase].rel = save_rel;
- mo->n_rebase++;
- }
- }
- }
- }
- pi = section_ptr_add(mo->indirsyms, mo->n_got * sizeof(*pi));
- memcpy(pi, goti, mo->n_got * sizeof(*pi));
- pi = section_ptr_add(mo->indirsyms, mo->nr_plt * sizeof(*pi));
- memcpy(pi, mo->indirsyms->data, mo->nr_plt * sizeof(*pi));
- tcc_free(goti);
-}
-#endif
-
-static int check_symbols(TCCState *s1, struct macho *mo)
-{
- int sym_index, sym_end;
- int ret = 0;
-
- mo->ilocal = mo->iextdef = mo->iundef = -1;
- sym_end = symtab_section->data_offset / sizeof(ElfW(Sym));
- for (sym_index = 1; sym_index < sym_end; ++sym_index) {
- int elf_index = ((struct nlist_64 *)mo->symtab->data + sym_index - 1)->n_value;
- ElfW(Sym) *sym = (ElfW(Sym) *)symtab_section->data + elf_index;
- const char *name = (char*)symtab_section->link->data + sym->st_name;
- unsigned type = ELFW(ST_TYPE)(sym->st_info);
- unsigned bind = ELFW(ST_BIND)(sym->st_info);
- unsigned vis = ELFW(ST_VISIBILITY)(sym->st_other);
-
- dprintf("%4d (%4d): %09lx %4d %4d %4d %3d %s\n",
- sym_index, elf_index, (long)sym->st_value,
- type, bind, vis, sym->st_shndx, name);
- if (bind == STB_LOCAL) {
- if (mo->ilocal == -1)
- mo->ilocal = sym_index - 1;
- if (mo->iextdef != -1 || mo->iundef != -1)
- tcc_error("local syms after global ones");
- } else if (sym->st_shndx != SHN_UNDEF) {
- if (mo->iextdef == -1)
- mo->iextdef = sym_index - 1;
- if (mo->iundef != -1)
- tcc_error("external defined symbol after undefined");
- } else if (sym->st_shndx == SHN_UNDEF) {
- if (mo->iundef == -1)
- mo->iundef = sym_index - 1;
- if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK
- || s1->output_type != TCC_OUTPUT_EXE
- || find_elf_sym(s1->dynsymtab_section, name)) {
- /* Mark the symbol as coming from a dylib so that
- relocate_syms doesn't complain. Normally bind_exe_dynsyms
- would do this check, and place the symbol into dynsym
- which is checked by relocate_syms. But Mach-O doesn't use
- bind_exe_dynsyms. */
- sym->st_shndx = SHN_FROMDLL;
- continue;
- }
- tcc_error_noabort("undefined symbol '%s'", name);
- ret = -1;
- }
- }
- return ret;
-}
-
-static void convert_symbol(TCCState *s1, struct macho *mo, struct nlist_64 *pn)
-{
- struct nlist_64 n = *pn;
- ElfSym *sym = (ElfW(Sym) *)symtab_section->data + pn->n_value;
- const char *name = (char*)symtab_section->link->data + sym->st_name;
- switch(ELFW(ST_TYPE)(sym->st_info)) {
- case STT_NOTYPE:
- case STT_OBJECT:
- case STT_FUNC:
- case STT_SECTION:
- n.n_type = N_SECT;
- break;
- case STT_FILE:
- n.n_type = N_ABS;
- break;
- default:
- tcc_error("unhandled ELF symbol type %d %s",
- ELFW(ST_TYPE)(sym->st_info), name);
- }
- if (sym->st_shndx == SHN_UNDEF)
- tcc_error("should have been rewritten to SHN_FROMDLL: %s", name);
- else if (sym->st_shndx == SHN_FROMDLL)
- n.n_type = N_UNDF, n.n_sect = 0;
- else if (sym->st_shndx == SHN_ABS)
- n.n_type = N_ABS, n.n_sect = 0;
- else if (sym->st_shndx >= SHN_LORESERVE)
- tcc_error("unhandled ELF symbol section %d %s", sym->st_shndx, name);
- else if (!mo->elfsectomacho[sym->st_shndx]) {
- if (strncmp(s1->sections[sym->st_shndx]->name, ".debug_", 7))
- tcc_error("ELF section %d(%s) not mapped into Mach-O for symbol %s",
- sym->st_shndx, s1->sections[sym->st_shndx]->name, name);
- }
- else
- n.n_sect = mo->elfsectomacho[sym->st_shndx];
- if (ELFW(ST_BIND)(sym->st_info) == STB_GLOBAL)
- n.n_type |= N_EXT;
- else if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
- n.n_desc |= N_WEAK_REF | (n.n_type != N_UNDF ? N_WEAK_DEF : 0);
- n.n_strx = pn->n_strx;
- n.n_value = sym->st_value;
- *pn = n;
-}
-
-static void convert_symbols(TCCState *s1, struct macho *mo)
-{
- struct nlist_64 *pn;
- for_each_elem(mo->symtab, 0, pn, struct nlist_64)
- convert_symbol(s1, mo, pn);
-}
-
-static int machosymcmp(const void *_a, const void *_b, void *arg)
-{
- TCCState *s1 = arg;
- int ea = ((struct nlist_64 *)_a)->n_value;
- int eb = ((struct nlist_64 *)_b)->n_value;
- ElfSym *sa = (ElfSym *)symtab_section->data + ea;
- ElfSym *sb = (ElfSym *)symtab_section->data + eb;
- int r;
- /* locals, then defined externals, then undefined externals, the
- last two sections also by name, otherwise stable sort */
- r = (ELFW(ST_BIND)(sb->st_info) == STB_LOCAL)
- - (ELFW(ST_BIND)(sa->st_info) == STB_LOCAL);
- if (r)
- return r;
- r = (sa->st_shndx == SHN_UNDEF) - (sb->st_shndx == SHN_UNDEF);
- if (r)
- return r;
- if (ELFW(ST_BIND)(sa->st_info) != STB_LOCAL) {
- const char * na = (char*)symtab_section->link->data + sa->st_name;
- const char * nb = (char*)symtab_section->link->data + sb->st_name;
- r = strcmp(na, nb);
- if (r)
- return r;
- }
- return ea - eb;
-}
-
-/* cannot use qsort because code has to be reentrant */
-static void tcc_qsort (void *base, size_t nel, size_t width,
- int (*comp)(const void *, const void *, void *), void *arg)
-{
- size_t wnel, gap, wgap, i, j, k;
- char *a, *b, tmp;
-
- wnel = width * nel;
- for (gap = 0; ++gap < nel;)
- gap *= 3;
- while ( gap /= 3 ) {
- wgap = width * gap;
- for (i = wgap; i < wnel; i += width) {
- for (j = i - wgap; ;j -= wgap) {
- a = j + (char *)base;
- b = a + wgap;
- if ( (*comp)(a, b, arg) <= 0 )
- break;
- k = width;
- do {
- tmp = *a;
- *a++ = *b;
- *b++ = tmp;
- } while ( --k );
- if (j < wgap)
- break;
- }
- }
- }
-}
-
-static void create_symtab(TCCState *s1, struct macho *mo)
-{
- int sym_index, sym_end;
- struct nlist_64 *pn;
-
- /* Stub creation belongs to check_relocs, but we need to create
- the symbol now, so its included in the sorting. */
- mo->stubs = new_section(s1, "__stubs", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
- s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
- mo->stubsym = put_elf_sym(s1->symtab, 0, 0,
- ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
- mo->stubs->sh_num, ".__stubs");
-#ifdef CONFIG_NEW_MACHO
- mo->chained_fixups = new_section(s1, "CHAINED_FIXUPS",
- SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
-#else
- mo->stub_helper = new_section(s1, "__stub_helper", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
- mo->la_symbol_ptr = new_section(s1, "__la_symbol_ptr", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
- mo->helpsym = put_elf_sym(s1->symtab, 0, 0,
- ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
- mo->stub_helper->sh_num, ".__stub_helper");
- mo->lasym = put_elf_sym(s1->symtab, 0, 0,
- ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
- mo->la_symbol_ptr->sh_num, ".__la_symbol_ptr");
- section_ptr_add(data_section, -data_section->data_offset & (PTR_SIZE - 1));
- mo->dyld_private = put_elf_sym(s1->symtab, data_section->data_offset, PTR_SIZE,
- ELFW(ST_INFO)(STB_LOCAL, STT_OBJECT), 0,
- data_section->sh_num, ".__dyld_private");
- section_ptr_add(data_section, PTR_SIZE);
- mo->dyld_stub_binder = put_elf_sym(s1->symtab, 0, 0,
- ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT), 0,
- SHN_UNDEF, "dyld_stub_binder");
- mo->rebase = new_section(s1, "REBASE", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
- mo->binding = new_section(s1, "BINDING", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
- mo->weak_binding = new_section(s1, "WEAK_BINDING", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
- mo->lazy_binding = new_section(s1, "LAZY_BINDING", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
-#endif
- mo->exports = new_section(s1, "EXPORT", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
- mo->indirsyms = new_section(s1, "LEINDIR", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
-
- mo->symtab = new_section(s1, "LESYMTAB", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
- mo->strtab = new_section(s1, "LESTRTAB", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
- put_elf_str(mo->strtab, " "); /* Mach-O starts strtab with a space */
- sym_end = symtab_section->data_offset / sizeof(ElfW(Sym));
- pn = section_ptr_add(mo->symtab, sizeof(*pn) * (sym_end - 1));
- for (sym_index = 1; sym_index < sym_end; ++sym_index) {
- ElfW(Sym) *sym = (ElfW(Sym) *)symtab_section->data + sym_index;
- const char *name = (char*)symtab_section->link->data + sym->st_name;
- pn[sym_index - 1].n_strx = put_elf_str(mo->strtab, name);
- pn[sym_index - 1].n_value = sym_index;
- }
- section_ptr_add(mo->strtab, -mo->strtab->data_offset & (PTR_SIZE - 1));
- tcc_qsort(pn, sym_end - 1, sizeof(*pn), machosymcmp, s1);
- mo->e2msym = tcc_malloc(sym_end * sizeof(*mo->e2msym));
- mo->e2msym[0] = -1;
- for (sym_index = 1; sym_index < sym_end; ++sym_index) {
- mo->e2msym[pn[sym_index - 1].n_value] = sym_index - 1;
- }
-}
-
-const struct {
- int seg_initial;
- uint32_t flags;
- const char *name;
-} skinfo[sk_last] = {
- /*[sk_unknown] =*/ { 0 },
- /*[sk_discard] =*/ { 0 },
- /*[sk_text] =*/ { 1, S_REGULAR | S_ATTR_PURE_INSTRUCTIONS
- | S_ATTR_SOME_INSTRUCTIONS, "__text" },
- /*[sk_stubs] =*/ { 1, S_REGULAR | S_ATTR_PURE_INSTRUCTIONS | S_SYMBOL_STUBS
- | S_ATTR_SOME_INSTRUCTIONS , "__stubs" },
- /*[sk_stub_helper] =*/ { 1, S_REGULAR | S_ATTR_PURE_INSTRUCTIONS
- | S_ATTR_SOME_INSTRUCTIONS , "__stub_helper" },
- /*[sk_ro_data] =*/ { 2, S_REGULAR, "__rodata" },
- /*[sk_uw_info] =*/ { 0 },
- /*[sk_nl_ptr] =*/ { 2, S_NON_LAZY_SYMBOL_POINTERS, "__got" },
- /*[sk_debug_info] =*/ { 3, S_REGULAR | S_ATTR_DEBUG, "__debug_info" },
- /*[sk_debug_abbrev] =*/ { 3, S_REGULAR | S_ATTR_DEBUG, "__debug_abbrev" },
- /*[sk_debug_line] =*/ { 3, S_REGULAR | S_ATTR_DEBUG, "__debug_line" },
- /*[sk_debug_aranges] =*/ { 3, S_REGULAR | S_ATTR_DEBUG, "__debug_aranges" },
- /*[sk_debug_str] =*/ { 3, S_REGULAR | S_ATTR_DEBUG, "__debug_str" },
- /*[sk_debug_line_str] =*/ { 3, S_REGULAR | S_ATTR_DEBUG, "__debug_line_str" },
- /*[sk_stab] =*/ { 4, S_REGULAR, "__stab" },
- /*[sk_stab_str] =*/ { 4, S_REGULAR, "__stab_str" },
- /*[sk_la_ptr] =*/ { 4, S_LAZY_SYMBOL_POINTERS, "__la_symbol_ptr" },
- /*[sk_init] =*/ { 4, S_MOD_INIT_FUNC_POINTERS, "__mod_init_func" },
- /*[sk_fini] =*/ { 4, S_MOD_TERM_FUNC_POINTERS, "__mod_term_func" },
- /*[sk_rw_data] =*/ { 4, S_REGULAR, "__data" },
- /*[sk_bss] =*/ { 4, S_ZEROFILL, "__bss" },
- /*[sk_linkedit] =*/ { 5, S_REGULAR, NULL },
-};
-
-#define START ((uint64_t)1 << 32)
-
-const struct {
- int used;
- const char *name;
- uint64_t vmaddr;
- uint64_t vmsize;
- vm_prot_t maxprot;
- vm_prot_t initprot;
- uint32_t flags;
-} all_segment[] = {
- { 1, "__PAGEZERO", 0, START, 0, 0, 0 },
- { 0, "__TEXT", START, 0, 5, 5, 0 },
- { 0, "__DATA_CONST", -1, 0, 3, 3, SG_READ_ONLY },
- { 0, "__DWARF", -1, 0, 7, 3, 0 },
- { 0, "__DATA", -1, 0, 3, 3, 0 },
- { 1, "__LINKEDIT", -1, 0, 1, 1, 0 },
-};
-
-#define N_SEGMENT (sizeof(all_segment)/sizeof(all_segment[0]))
-
-#ifdef CONFIG_NEW_MACHO
-static void calc_fixup_size(TCCState *s1, struct macho *mo)
-{
- int i, size;
-
- size = (sizeof(struct dyld_chained_fixups_header) + 7) & -8;
- size += (sizeof(struct dyld_chained_starts_in_image) + (mo->nseg - 1) * sizeof(uint32_t) + 7) & -8;
- for (i = (s1->output_type == TCC_OUTPUT_EXE); i < mo->nseg - 1; i++) {
- int page_count = (get_segment(mo, i)->vmsize + SEG_PAGE_SIZE - 1) / SEG_PAGE_SIZE;
- size += (sizeof(struct dyld_chained_starts_in_segment) + (page_count - 1) * sizeof(uint16_t) + 7) & -8;
- }
- size += mo->n_bind * sizeof (struct dyld_chained_import) + 1;
- for (i = 0; i < mo->n_bind_rebase; i++) {
- if (mo->bind_rebase[i].bind) {
- int sym_index = ELFW(R_SYM)(mo->bind_rebase[i].rel.r_info);
- ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
- const char *name = (char *) symtab_section->link->data + sym->st_name;
- size += strlen(name) + 1;
- }
- }
- size = (size + 7) & -8;
- section_ptr_add(mo->chained_fixups, size);
-}
-
-#else
-
-static void set_segment_and_offset(TCCState *s1, struct macho *mo, addr_t addr,
- uint8_t *ptr, int opcode,
- Section *sec, addr_t offset)
-{
- int i;
- struct segment_command_64 *seg = NULL;
-
- for (i = (s1->output_type == TCC_OUTPUT_EXE); i < mo->nseg - 1; i++) {
- seg = get_segment(mo, i);
- if (addr >= seg->vmaddr && addr < (seg->vmaddr + seg->vmsize))
- break;
- }
- *ptr = opcode | i;
- write_uleb128(sec, offset - seg->vmaddr);
-}
-
-static void bind_rebase(TCCState *s1, struct macho *mo)
-{
- int i;
- uint8_t *ptr;
- ElfW(Sym) *sym;
- const char *name;
-
- for (i = 0; i < mo->n_lazy_bind; i++) {
- int sym_index = ELFW(R_SYM)(mo->s_lazy_bind[i].rel.r_info);
-
- sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
- name = (char *) symtab_section->link->data + sym->st_name;
- write32le(mo->stub_helper->data +
- mo->s_lazy_bind[i].bind_offset,
- mo->lazy_binding->data_offset);
- ptr = section_ptr_add(mo->lazy_binding, 1);
- set_segment_and_offset(s1, mo, mo->la_symbol_ptr->sh_addr, ptr,
- BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,
- mo->lazy_binding,
- mo->s_lazy_bind[i].la_symbol_offset +
- mo->la_symbol_ptr->sh_addr);
- ptr = section_ptr_add(mo->lazy_binding, 5 + strlen(name));
- *ptr++ = BIND_OPCODE_SET_DYLIB_SPECIAL_IMM |
- (BIND_SPECIAL_DYLIB_FLAT_LOOKUP & 0xf);
- *ptr++ = BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | 0;
- strcpy((char *)ptr, name);
- ptr += strlen(name) + 1;
- *ptr++ = BIND_OPCODE_DO_BIND;
- *ptr = BIND_OPCODE_DONE;
- }
- for (i = 0; i < mo->n_rebase; i++) {
- Section *s = s1->sections[mo->s_rebase[i].section];
-
- ptr = section_ptr_add(mo->rebase, 2);
- *ptr++ = REBASE_OPCODE_SET_TYPE_IMM | REBASE_TYPE_POINTER;
- set_segment_and_offset(s1, mo, s->sh_addr, ptr,
- REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,
- mo->rebase,
- mo->s_rebase[i].rel.r_offset +
- s->sh_addr);
- ptr = section_ptr_add(mo->rebase, 1);
- *ptr = REBASE_OPCODE_DO_REBASE_IMM_TIMES | 1;
- }
- for (i = 0; i < mo->n_bind; i++) {
- int sym_index = ELFW(R_SYM)(mo->bind[i].rel.r_info);
- Section *s = s1->sections[mo->bind[i].section];
- Section *binding;
-
- sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
- name = (char *) symtab_section->link->data + sym->st_name;
- binding = ELFW(ST_BIND)(sym->st_info) == STB_WEAK
- ? mo->weak_binding : mo->binding;
- ptr = section_ptr_add(binding, 4 + (binding == mo->binding) +
- strlen(name));
- if (binding == mo->binding)
- *ptr++ = BIND_OPCODE_SET_DYLIB_SPECIAL_IMM |
- (BIND_SPECIAL_DYLIB_FLAT_LOOKUP & 0xf);
- *ptr++ = BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM |
- (binding == mo->weak_binding
- ? BIND_SYMBOL_FLAGS_WEAK_IMPORT : 0);
- strcpy((char *)ptr, name);
- ptr += strlen(name) + 1;
- *ptr++ = BIND_OPCODE_SET_TYPE_IMM | BIND_TYPE_POINTER;
- set_segment_and_offset(s1, mo, s->sh_addr, ptr,
- BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,
- binding,
- mo->bind[i].rel.r_offset + s->sh_addr);
- ptr = section_ptr_add(binding, 1);
- *ptr++ = BIND_OPCODE_DO_BIND;
- }
- if (mo->rebase->data_offset) {
- ptr = section_ptr_add(mo->rebase, 1);
- *ptr = REBASE_OPCODE_DONE;
- }
- if (mo->binding->data_offset) {
- ptr = section_ptr_add(mo->binding, 1);
- *ptr = BIND_OPCODE_DONE;
- }
- if (mo->weak_binding->data_offset) {
- ptr = section_ptr_add(mo->weak_binding, 1);
- *ptr = BIND_OPCODE_DONE;
- }
- tcc_free(mo->s_lazy_bind);
- tcc_free(mo->s_rebase);
- tcc_free(mo->bind);
-}
-#endif
-
-struct trie_info {
- const char *name;
- int flag;
- addr_t addr;
- int str_size;
- int term_size;
-};
-
-struct trie_node {
- int start;
- int end;
- int index_start;
- int index_end;
- int n_child;
- struct trie_node *child;
-};
-
-struct trie_seq {
- int n_child;
- struct trie_node *node;
- int offset;
- int nest_offset;
-};
-
-static void create_trie(struct trie_node *node,
- int from, int to, int index_start,
- int n_trie, struct trie_info *trie)
-{
- int i;
- int start, end, index_end;
- char cur;
- struct trie_node *child;
-
- for (i = from; i < to; i = end) {
- cur = trie[i].name[index_start];
- start = i++;
- for (; i < to; i++)
- if (cur != trie[i].name[index_start])
- break;
- end = i;
- if (start == end - 1 ||
- (trie[start].name[index_start] &&
- trie[start].name[index_start + 1] == 0))
- index_end = trie[start].str_size - 1;
- else {
- index_end = index_start + 1;
- for (;;) {
- cur = trie[start].name[index_end];
- for (i = start + 1; i < end; i++)
- if (cur != trie[i].name[index_end])
- break;
- if (trie[start].name[index_end] &&
- trie[start].name[index_end + 1] == 0) {
- end = start + 1;
- index_end = trie[start].str_size - 1;
- break;
- }
- if (i != end)
- break;
- index_end++;
- }
- }
- node->child = tcc_realloc(node->child,
- (node->n_child + 1) *
- sizeof(struct trie_node));
- child = &node->child[node->n_child];
- child->start = start;
- child->end = end;
- child->index_start = index_start;
- child->index_end = index_end;
- child->n_child = 0;
- child->child = NULL;
- node->n_child++;
- if (start != end - 1)
- create_trie(child, start, end, index_end, n_trie, trie);
- }
-}
-
-static int create_seq(int *offset, int *n_seq, struct trie_seq **seq,
- struct trie_node *node,
- int n_trie, struct trie_info *trie)
-{
- int i, nest_offset, last_seq = *n_seq, retval = *offset;
- struct trie_seq *p_seq;
- struct trie_node *p_nest;
-
- for (i = 0; i < node->n_child; i++) {
- p_nest = &node->child[i];
- *seq = tcc_realloc(*seq, (*n_seq + 1) * sizeof(struct trie_seq));
- p_seq = &(*seq)[(*n_seq)++];
- p_seq->n_child = i == 0 ? node->n_child : -1;
- p_seq->node = p_nest;
- p_seq->offset = *offset;
- p_seq->nest_offset = 0;
- *offset += (i == 0 ? 1 + 1 : 0) +
- p_nest->index_end - p_nest->index_start + 1 + 3;
- }
- for (i = 0; i < node->n_child; i++) {
- nest_offset =
- create_seq(offset, n_seq, seq, &node->child[i], n_trie, trie);
- p_seq = &(*seq)[last_seq + i];
- p_seq->nest_offset = nest_offset;
- }
- return retval;
-}
-
-static void node_free(struct trie_node *node)
-{
- int i;
-
- for (i = 0; i < node->n_child; i++)
- node_free(&node->child[i]);
- tcc_free(node->child);
-}
-
-static int triecmp(const void *_a, const void *_b, void *arg)
-{
- struct trie_info *a = (struct trie_info *) _a;
- struct trie_info *b = (struct trie_info *) _b;
- int len_a = strlen(a->name);
- int len_b = strlen(b->name);
-
- /* strange sorting needed. Name 'xx' should be after 'xx1' */
- if (!strncmp(a->name, b->name, len_a < len_b ? len_a : len_b))
- return len_a < len_b ? 1 : (len_a > len_b ? -1 : 0);
- return strcmp(a->name, b->name);
-}
-
-static void export_trie(TCCState *s1, struct macho *mo)
-{
- int i, size, offset = 0, save_offset;
- uint8_t *ptr;
- int sym_index;
- int sym_end = symtab_section->data_offset / sizeof(ElfW(Sym));
- int n_trie = 0, n_seq = 0;
- struct trie_info *trie = NULL, *p_trie;
- struct trie_node node, *p_node;
- struct trie_seq *seq = NULL;
- addr_t vm_addr = get_segment(mo, s1->output_type == TCC_OUTPUT_EXE)->vmaddr;
-
- for (sym_index = 1; sym_index < sym_end; ++sym_index) {
- ElfW(Sym) *sym = (ElfW(Sym) *)symtab_section->data + sym_index;
- const char *name = (char*)symtab_section->link->data + sym->st_name;
-
- if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE &&
- (ELFW(ST_BIND)(sym->st_info) == STB_GLOBAL ||
- ELFW(ST_BIND)(sym->st_info) == STB_WEAK)) {
- int flag = EXPORT_SYMBOL_FLAGS_KIND_REGULAR;
- addr_t addr =
- sym->st_value + s1->sections[sym->st_shndx]->sh_addr - vm_addr;
-
- if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
- flag |= EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION;
- dprintf ("%s %d %llx\n", name, flag, (long long)addr + vm_addr);
- trie = tcc_realloc(trie, (n_trie + 1) * sizeof(struct trie_info));
- trie[n_trie].name = name;
- trie[n_trie].flag = flag;
- trie[n_trie].addr = addr;
- trie[n_trie].str_size = strlen(name) + 1;
- trie[n_trie].term_size = uleb128_size(flag) + uleb128_size(addr);
- n_trie++;
- }
- }
- if (n_trie) {
- tcc_qsort(trie, n_trie, sizeof(struct trie_info), triecmp, NULL);
- memset(&node, 0, sizeof(node));
- create_trie(&node, 0, n_trie, 0, n_trie, trie);
- create_seq(&offset, &n_seq, &seq, &node, n_trie, trie);
- save_offset = offset;
- for (i = 0; i < n_seq; i++) {
- p_node = seq[i].node;
- if (p_node->n_child == 0) {
- p_trie = &trie[p_node->start];
- seq[i].nest_offset = offset;
- offset += 1 + p_trie->term_size + 1;
- }
- }
- for (i = 0; i < n_seq; i++) {
- p_node = seq[i].node;
- p_trie = &trie[p_node->start];
- if (seq[i].n_child >= 0) {
- section_ptr_add(mo->exports,
- seq[i].offset - mo->exports->data_offset);
- ptr = section_ptr_add(mo->exports, 2);
- *ptr++ = 0;
- *ptr = seq[i].n_child;
- }
- size = p_node->index_end - p_node->index_start;
- ptr = section_ptr_add(mo->exports, size + 1);
- memcpy(ptr, &p_trie->name[p_node->index_start], size);
- ptr[size] = 0;
- write_uleb128(mo->exports, seq[i].nest_offset);
- }
- section_ptr_add(mo->exports, save_offset - mo->exports->data_offset);
- for (i = 0; i < n_seq; i++) {
- p_node = seq[i].node;
- if (p_node->n_child == 0) {
- p_trie = &trie[p_node->start];
- write_uleb128(mo->exports, p_trie->term_size);
- write_uleb128(mo->exports, p_trie->flag);
- write_uleb128(mo->exports, p_trie->addr);
- ptr = section_ptr_add(mo->exports, 1);
- *ptr = 0;
- }
- }
- section_ptr_add(mo->exports, -mo->exports->data_offset & 7);
- node_free(&node);
- tcc_free(seq);
- }
- tcc_free(trie);
-}
-
-static void collect_sections(TCCState *s1, struct macho *mo, const char *filename)
-{
- int i, sk, numsec;
- int used_segment[N_SEGMENT];
- uint64_t curaddr, fileofs;
- Section *s;
- struct segment_command_64 *seg;
- struct dylib_command *dylib;
-#ifdef CONFIG_NEW_MACHO
- struct linkedit_data_command *chained_fixups_lc;
- struct linkedit_data_command *export_trie_lc;
-#endif
- struct build_version_command *dyldbv;
- struct source_version_command *dyldsv;
- struct rpath_command *rpath;
- struct dylinker_command *dyldlc;
- struct symtab_command *symlc;
- struct dysymtab_command *dysymlc;
- char *str;
-
- for (i = 0; i < N_SEGMENT; i++)
- used_segment[i] = all_segment[i].used;
-
- memset (mo->sk_to_sect, 0, sizeof(mo->sk_to_sect));
- for (i = s1->nb_sections; i-- > 1;) {
- int type, flags;
- s = s1->sections[i];
- type = s->sh_type;
- flags = s->sh_flags;
- sk = sk_unknown;
- /* debug sections have sometimes no SHF_ALLOC */
- if ((flags & SHF_ALLOC) || !strncmp(s->name, ".debug_", 7)) {
- switch (type) {
- default: sk = sk_unknown; break;
- case SHT_INIT_ARRAY: sk = sk_init; break;
- case SHT_FINI_ARRAY: sk = sk_fini; break;
- case SHT_NOBITS: sk = sk_bss; break;
- case SHT_SYMTAB: sk = sk_discard; break;
- case SHT_STRTAB:
- if (s == stabstr_section)
- sk = sk_stab_str;
- else
- sk = sk_discard;
- break;
- case SHT_RELX: sk = sk_discard; break;
- case SHT_LINKEDIT: sk = sk_linkedit; break;
- case SHT_PROGBITS:
- if (s == mo->stubs)
- sk = sk_stubs;
-#ifndef CONFIG_NEW_MACHO
- else if (s == mo->stub_helper)
- sk = sk_stub_helper;
- else if (s == mo->la_symbol_ptr)
- sk = sk_la_ptr;
-#endif
- else if (s == rodata_section)
- sk = sk_ro_data;
- else if (s == s1->got)
- sk = sk_nl_ptr;
- else if (s == stab_section)
- sk = sk_stab;
- else if (s == dwarf_info_section)
- sk = sk_debug_info;
- else if (s == dwarf_abbrev_section)
- sk = sk_debug_abbrev;
- else if (s == dwarf_line_section)
- sk = sk_debug_line;
- else if (s == dwarf_aranges_section)
- sk = sk_debug_aranges;
- else if (s == dwarf_str_section)
- sk = sk_debug_str;
- else if (s == dwarf_line_str_section)
- sk = sk_debug_line_str;
- else if (flags & SHF_EXECINSTR)
- sk = sk_text;
- else if (flags & SHF_WRITE)
- sk = sk_rw_data;
- else
- sk = sk_ro_data;
- break;
- }
- } else
- sk = sk_discard;
- s->prev = mo->sk_to_sect[sk].s;
- mo->sk_to_sect[sk].s = s;
- used_segment[skinfo[sk].seg_initial] = 1;
- }
-
- if (s1->output_type != TCC_OUTPUT_EXE)
- used_segment[0] = 0;
-
- for (i = 0; i < N_SEGMENT; i++)
- if (used_segment[i]) {
- seg = add_segment(mo, all_segment[i].name);
- if (i == 1 && s1->output_type != TCC_OUTPUT_EXE)
- seg->vmaddr = 0;
- else
- seg->vmaddr = all_segment[i].vmaddr;
- seg->vmsize = all_segment[i].vmsize;
- seg->maxprot = all_segment[i].maxprot;
- seg->initprot = all_segment[i].initprot;
- seg->flags = all_segment[i].flags;
- for (sk = sk_unknown; sk < sk_last; sk++)
- if (skinfo[sk].seg_initial == i)
- mo->segment[sk] = mo->nseg - 1;
- }
-
- if (s1->output_type != TCC_OUTPUT_EXE) {
- const char *name = s1->install_name ? s1->install_name : filename;
- i = (sizeof(*dylib) + strlen(name) + 1 + 7) &-8;
- dylib = add_lc(mo, LC_ID_DYLIB, i);
- dylib->name = sizeof(*dylib);
- dylib->timestamp = 1;
- dylib->current_version =
- s1->current_version ? s1->current_version : 1 << 16;
- dylib->compatibility_version =
- s1->compatibility_version ? s1->compatibility_version : 1 << 16;
- str = (char*)dylib + dylib->name;
- strcpy(str, name);
- }
-
-#ifdef CONFIG_NEW_MACHO
- chained_fixups_lc = add_lc(mo, LC_DYLD_CHAINED_FIXUPS,
- sizeof(struct linkedit_data_command));
- export_trie_lc = add_lc(mo, LC_DYLD_EXPORTS_TRIE,
- sizeof(struct linkedit_data_command));
-#else
- mo->dyldinfo = add_lc(mo, LC_DYLD_INFO_ONLY, sizeof(*mo->dyldinfo));
-#endif
-
- symlc = add_lc(mo, LC_SYMTAB, sizeof(*symlc));
- dysymlc = add_lc(mo, LC_DYSYMTAB, sizeof(*dysymlc));
-
- if (s1->output_type == TCC_OUTPUT_EXE) {
- i = (sizeof(*dyldlc) + strlen("/usr/lib/dyld") + 1 + 7) &-8;
- dyldlc = add_lc(mo, LC_LOAD_DYLINKER, i);
- dyldlc->name = sizeof(*dyldlc);
- str = (char*)dyldlc + dyldlc->name;
- strcpy(str, "/usr/lib/dyld");
- }
-
- dyldbv = add_lc(mo, LC_BUILD_VERSION, sizeof(*dyldbv));
- dyldbv->platform = PLATFORM_MACOS;
- dyldbv->minos = (10 << 16) + (6 << 8);
- dyldbv->sdk = (10 << 16) + (6 << 8);
- dyldbv->ntools = 0;
-
- dyldsv = add_lc(mo, LC_SOURCE_VERSION, sizeof(*dyldsv));
- dyldsv->version = 0;
-
- if (s1->output_type == TCC_OUTPUT_EXE) {
- mo->ep = add_lc(mo, LC_MAIN, sizeof(*mo->ep));
- mo->ep->entryoff = 4096;
- }
-
- for(i = 0; i < s1->nb_loaded_dlls; i++) {
- DLLReference *dllref = s1->loaded_dlls[i];
- if (dllref->level == 0)
- add_dylib(mo, dllref->name);
- }
-
- if (s1->rpath) {
- char *path = s1->rpath, *end;
- do {
- end = strchr(path, ':');
- if (!end)
- end = strchr(path, 0);
- i = (sizeof(*rpath) + (end - path) + 1 + 7) &-8;
- rpath = add_lc(mo, LC_RPATH, i);
- rpath->path = sizeof(*rpath);
- str = (char*)rpath + rpath->path;
- memcpy(str, path, end - path);
- str[end - path] = 0;
- path = end + 1;
- } while (*end);
- }
-
- fileofs = 4096; /* leave space for mach-o headers */
- curaddr = get_segment(mo, s1->output_type == TCC_OUTPUT_EXE)->vmaddr;
- curaddr += 4096;
- seg = NULL;
- numsec = 0;
- mo->elfsectomacho = tcc_mallocz(sizeof(*mo->elfsectomacho) * s1->nb_sections);
- for (sk = sk_unknown; sk < sk_last; sk++) {
- struct section_64 *sec = NULL;
- if (seg) {
- seg->vmsize = curaddr - seg->vmaddr;
- seg->filesize = fileofs - seg->fileoff;
- }
-#ifdef CONFIG_NEW_MACHO
- if (sk == sk_linkedit) {
- calc_fixup_size(s1, mo);
- export_trie(s1, mo);
- }
-#else
- if (sk == sk_linkedit) {
- bind_rebase(s1, mo);
- export_trie(s1, mo);
- }
-#endif
- if (skinfo[sk].seg_initial &&
- (s1->output_type != TCC_OUTPUT_EXE || mo->segment[sk]) &&
- mo->sk_to_sect[sk].s) {
- uint64_t al = 0;
- int si;
- seg = get_segment(mo, mo->segment[sk]);
- if (skinfo[sk].name) {
- si = add_section(mo, &seg, skinfo[sk].name);
- numsec++;
- mo->lc[mo->seg2lc[mo->segment[sk]]] = (struct load_command*)seg;
- mo->sk_to_sect[sk].machosect = si;
- sec = get_section(seg, si);
- sec->flags = skinfo[sk].flags;
- if (sk == sk_stubs)
-#ifdef TCC_TARGET_X86_64
- sec->reserved2 = 6;
-#elif defined TCC_TARGET_ARM64
- sec->reserved2 = 12;
-#endif
- if (sk == sk_nl_ptr)
- sec->reserved1 = mo->nr_plt;
-#ifndef CONFIG_NEW_MACHO
- if (sk == sk_la_ptr)
- sec->reserved1 = mo->nr_plt + mo->n_got;
-#endif
- }
- if (seg->vmaddr == -1) {
- curaddr = (curaddr + SEG_PAGE_SIZE - 1) & -SEG_PAGE_SIZE;
- seg->vmaddr = curaddr;
- fileofs = (fileofs + SEG_PAGE_SIZE - 1) & -SEG_PAGE_SIZE;
- seg->fileoff = fileofs;
- }
-
- for (s = mo->sk_to_sect[sk].s; s; s = s->prev) {
- int a = exact_log2p1(s->sh_addralign);
- if (a && al < (a - 1))
- al = a - 1;
- s->sh_size = s->data_offset;
- }
- if (sec)
- sec->align = al;
- al = 1ULL << al;
- if (al > 4096)
- tcc_warning("alignment > 4096"), sec->align = 12, al = 4096;
- curaddr = (curaddr + al - 1) & -al;
- fileofs = (fileofs + al - 1) & -al;
- if (sec) {
- sec->addr = curaddr;
- sec->offset = fileofs;
- }
- for (s = mo->sk_to_sect[sk].s; s; s = s->prev) {
- al = s->sh_addralign;
- curaddr = (curaddr + al - 1) & -al;
- dprintf("%s: curaddr now 0x%lx\n", s->name, (long)curaddr);
- s->sh_addr = curaddr;
- curaddr += s->sh_size;
- if (s->sh_type != SHT_NOBITS) {
- fileofs = (fileofs + al - 1) & -al;
- s->sh_offset = fileofs;
- fileofs += s->sh_size;
- dprintf("%s: fileofs now %ld\n", s->name, (long)fileofs);
- }
- if (sec)
- mo->elfsectomacho[s->sh_num] = numsec;
- }
- if (sec)
- sec->size = curaddr - sec->addr;
- }
- if (DEBUG_MACHO)
- for (s = mo->sk_to_sect[sk].s; s; s = s->prev) {
- int type = s->sh_type;
- int flags = s->sh_flags;
- printf("%d section %-16s %-10s %09lx %04x %02d %s,%s,%s\n",
- sk,
- s->name,
- type == SHT_PROGBITS ? "progbits" :
- type == SHT_NOBITS ? "nobits" :
- type == SHT_SYMTAB ? "symtab" :
- type == SHT_STRTAB ? "strtab" :
- type == SHT_INIT_ARRAY ? "init" :
- type == SHT_FINI_ARRAY ? "fini" :
- type == SHT_RELX ? "rel" : "???",
- (long)s->sh_addr,
- (unsigned)s->data_offset,
- s->sh_addralign,
- flags & SHF_ALLOC ? "alloc" : "",
- flags & SHF_WRITE ? "write" : "",
- flags & SHF_EXECINSTR ? "exec" : ""
- );
- }
- }
- if (seg) {
- seg->vmsize = curaddr - seg->vmaddr;
- seg->filesize = fileofs - seg->fileoff;
- }
-
- /* Fill symtab info */
- symlc->symoff = mo->symtab->sh_offset;
- symlc->nsyms = mo->symtab->data_offset / sizeof(struct nlist_64);
- symlc->stroff = mo->strtab->sh_offset;
- symlc->strsize = mo->strtab->data_offset;
-
- dysymlc->iundefsym = mo->iundef == -1 ? symlc->nsyms : mo->iundef;
- dysymlc->iextdefsym = mo->iextdef == -1 ? dysymlc->iundefsym : mo->iextdef;
- dysymlc->ilocalsym = mo->ilocal == -1 ? dysymlc->iextdefsym : mo->ilocal;
- dysymlc->nlocalsym = dysymlc->iextdefsym - dysymlc->ilocalsym;
- dysymlc->nextdefsym = dysymlc->iundefsym - dysymlc->iextdefsym;
- dysymlc->nundefsym = symlc->nsyms - dysymlc->iundefsym;
- dysymlc->indirectsymoff = mo->indirsyms->sh_offset;
- dysymlc->nindirectsyms = mo->indirsyms->data_offset / sizeof(uint32_t);
-
-#ifdef CONFIG_NEW_MACHO
- if (mo->chained_fixups->data_offset) {
- chained_fixups_lc->dataoff = mo->chained_fixups->sh_offset;
- chained_fixups_lc->datasize = mo->chained_fixups->data_offset;
- }
- if (mo->exports->data_offset) {
- export_trie_lc->dataoff = mo->exports->sh_offset;
- export_trie_lc->datasize = mo->exports->data_offset;
- }
-#else
- if (mo->rebase->data_offset) {
- mo->dyldinfo->rebase_off = mo->rebase->sh_offset;
- mo->dyldinfo->rebase_size = mo->rebase->data_offset;
- }
- if (mo->binding->data_offset) {
- mo->dyldinfo->bind_off = mo->binding->sh_offset;
- mo->dyldinfo->bind_size = mo->binding->data_offset;
- }
- if (mo->weak_binding->data_offset) {
- mo->dyldinfo->weak_bind_off = mo->weak_binding->sh_offset;
- mo->dyldinfo->weak_bind_size = mo->weak_binding->data_offset;
- }
- if (mo->lazy_binding->data_offset) {
- mo->dyldinfo->lazy_bind_off = mo->lazy_binding->sh_offset;
- mo->dyldinfo->lazy_bind_size = mo->lazy_binding->data_offset;
- }
- if (mo->exports->data_offset) {
- mo->dyldinfo->export_off = mo->exports->sh_offset;
- mo->dyldinfo->export_size = mo->exports->data_offset;
- }
-#endif
-}
-
-static void macho_write(TCCState *s1, struct macho *mo, FILE *fp)
-{
- int i, sk;
- uint64_t fileofs = 0;
- Section *s;
- mo->mh.mh.magic = MH_MAGIC_64;
-#ifdef TCC_TARGET_X86_64
- mo->mh.mh.cputype = CPU_TYPE_X86_64;
- mo->mh.mh.cpusubtype = CPU_SUBTYPE_LIB64 | CPU_SUBTYPE_X86_ALL;
-#elif defined TCC_TARGET_ARM64
- mo->mh.mh.cputype = CPU_TYPE_ARM64;
- mo->mh.mh.cpusubtype = CPU_SUBTYPE_ARM64_ALL;
-#endif
- if (s1->output_type == TCC_OUTPUT_EXE) {
- mo->mh.mh.filetype = MH_EXECUTE;
- mo->mh.mh.flags = MH_DYLDLINK | MH_PIE;
- }
- else {
- mo->mh.mh.filetype = MH_DYLIB;
- mo->mh.mh.flags = MH_DYLDLINK;
- }
- mo->mh.mh.ncmds = mo->nlc;
- mo->mh.mh.sizeofcmds = 0;
- for (i = 0; i < mo->nlc; i++)
- mo->mh.mh.sizeofcmds += mo->lc[i]->cmdsize;
-
- fwrite(&mo->mh, 1, sizeof(mo->mh), fp);
- fileofs += sizeof(mo->mh);
- for (i = 0; i < mo->nlc; i++) {
- fwrite(mo->lc[i], 1, mo->lc[i]->cmdsize, fp);
- fileofs += mo->lc[i]->cmdsize;
- }
-
- for (sk = sk_unknown; sk < sk_last; sk++) {
- //struct segment_command_64 *seg;
- if (skinfo[sk].seg_initial == 0 ||
- (s1->output_type == TCC_OUTPUT_EXE && !mo->segment[sk]) ||
- !mo->sk_to_sect[sk].s)
- continue;
- /*seg =*/ get_segment(mo, mo->segment[sk]);
- for (s = mo->sk_to_sect[sk].s; s; s = s->prev) {
- if (s->sh_type != SHT_NOBITS) {
- while (fileofs < s->sh_offset)
- fputc(0, fp), fileofs++;
- if (s->sh_size) {
- fwrite(s->data, 1, s->sh_size, fp);
- fileofs += s->sh_size;
- }
- }
- }
- }
-}
-
-#ifdef CONFIG_NEW_MACHO
-static int bind_rebase_cmp(const void *_a, const void *_b, void *arg)
-{
- TCCState *s1 = arg;
- struct bind_rebase *a = (struct bind_rebase *) _a;
- struct bind_rebase *b = (struct bind_rebase *) _b;
- addr_t aa = s1->sections[a->section]->sh_addr + a->rel.r_offset;
- addr_t ab = s1->sections[b->section]->sh_addr + b->rel.r_offset;
-
- return aa > ab ? 1 : aa < ab ? -1 : 0;
-}
-
-ST_FUNC void bind_rebase_import(TCCState *s1, struct macho *mo)
-{
- int i, j, k, bind_index, size, page_count, sym_index;
- const char *name;
- ElfW(Sym) *sym;
- unsigned char *data = mo->chained_fixups->data;
- struct segment_command_64 *seg;
- struct dyld_chained_fixups_header *header;
- struct dyld_chained_starts_in_image *image;
- struct dyld_chained_starts_in_segment *segment;
- struct dyld_chained_import *import;
-
- tcc_qsort(mo->bind_rebase, mo->n_bind_rebase, sizeof(struct bind_rebase),
- bind_rebase_cmp, s1);
- for (i = 0; i < mo->n_bind_rebase - 1; i++)
- if (mo->bind_rebase[i].section == mo->bind_rebase[i + 1].section &&
- mo->bind_rebase[i].rel.r_offset == mo->bind_rebase[i + 1].rel.r_offset) {
- sym_index = ELFW(R_SYM)(mo->bind_rebase[i].rel.r_info);
- sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
- name = (char *) symtab_section->link->data + sym->st_name;
- tcc_error("Overlap %s/%s %s:%s",
- mo->bind_rebase[i].bind ? "bind" : "rebase",
- mo->bind_rebase[i + 1].bind ? "bind" : "rebase",
- s1->sections[mo->bind_rebase[i].section]->name, name);
- }
- header = (struct dyld_chained_fixups_header *) data;
- data += (sizeof(struct dyld_chained_fixups_header) + 7) & -8;
- header->starts_offset = data - mo->chained_fixups->data;
- header->imports_count = mo->n_bind;
- header->imports_format = DYLD_CHAINED_IMPORT;
- header->symbols_format = 0;
- size = sizeof(struct dyld_chained_starts_in_image) +
- (mo->nseg - 1) * sizeof(uint32_t);
- image = (struct dyld_chained_starts_in_image *) data;
- data += (size + 7) & -8;
- image->seg_count = mo->nseg;
- for (i = (s1->output_type == TCC_OUTPUT_EXE); i < mo->nseg - 1; i++) {
- image->seg_info_offset[i] = (data - mo->chained_fixups->data) -
- header->starts_offset;
- seg = get_segment(mo, i);
- page_count = (seg->vmsize + SEG_PAGE_SIZE - 1) / SEG_PAGE_SIZE;
- size = sizeof(struct dyld_chained_starts_in_segment) +
- (page_count - 1) * sizeof(uint16_t);
- segment = (struct dyld_chained_starts_in_segment *) data;
- data += (size + 7) & -8;
- segment->size = size;
- segment->page_size = SEG_PAGE_SIZE;
-#if 1
-#define PTR_64_OFFSET 0
-#define PTR_64_MASK 0x7FFFFFFFFFFULL
- segment->pointer_format = DYLD_CHAINED_PTR_64;
-#else
-#define PTR_64_OFFSET 0x100000000ULL
-#define PTR_64_MASK 0xFFFFFFFFFFFFFFULL
- segment->pointer_format = DYLD_CHAINED_PTR_64_OFFSET;
-#endif
- segment->segment_offset = seg->fileoff;
- segment->max_valid_pointer = 0;
- segment->page_count = page_count;
- // add bind/rebase
- bind_index = 0;
- k = 0;
- for (j = 0; j < page_count; j++) {
- addr_t start = seg->vmaddr + j * SEG_PAGE_SIZE;
- addr_t end = start + SEG_PAGE_SIZE;
- void *last = NULL;
- addr_t last_o = 0;
- addr_t cur_o, cur;
- struct dyld_chained_ptr_64_rebase *rebase;
- struct dyld_chained_ptr_64_bind *bind;
-
- segment->page_start[j] = DYLD_CHAINED_PTR_START_NONE;
- for (; k < mo->n_bind_rebase; k++) {
- Section *s = s1->sections[mo->bind_rebase[k].section];
- addr_t r_offset = mo->bind_rebase[k].rel.r_offset;
- addr_t addr = s->sh_addr + r_offset;
-
- if ((addr & 3) ||
- (addr & (SEG_PAGE_SIZE - 1)) > SEG_PAGE_SIZE - PTR_SIZE)
- tcc_error("Illegal rel_offset %s %lld",
- s->name, (long long)r_offset);
- if (addr >= end)
- break;
- if (addr >= start) {
- cur_o = addr - start;
- if (mo->bind_rebase[k].bind) {
- if (segment->page_start[j] == DYLD_CHAINED_PTR_START_NONE)
- segment->page_start[j] = cur_o;
- else {
- bind = (struct dyld_chained_ptr_64_bind *) last;
- bind->next = (cur_o - last_o) / 4;
- }
- bind = (struct dyld_chained_ptr_64_bind *)
- (s->data + r_offset);
- last = bind;
- last_o = cur_o;
- bind->ordinal = bind_index;
- bind->addend = 0;
- bind->reserved = 0;
- bind->next = 0;
- bind->bind = 1;
- }
- else {
- if (segment->page_start[j] == DYLD_CHAINED_PTR_START_NONE)
- segment->page_start[j] = cur_o;
- else {
- rebase = (struct dyld_chained_ptr_64_rebase *) last;
- rebase->next = (cur_o - last_o) / 4;
- }
- rebase = (struct dyld_chained_ptr_64_rebase *)
- (s->data + r_offset);
- last = rebase;
- last_o = cur_o;
- cur = (*(uint64_t *) (s->data + r_offset)) -
- PTR_64_OFFSET;
- rebase->target = cur & PTR_64_MASK;
- rebase->high8 = cur >> (64 - 8);
- if (cur != ((uint64_t)rebase->high8 << (64 - 8)) + rebase->target)
- tcc_error("rebase error");
- rebase->reserved = 0;
- rebase->next = 0;
- rebase->bind = 0;
- }
- }
- bind_index += mo->bind_rebase[k].bind;
- }
- }
- }
- // add imports
- header->imports_offset = data - mo->chained_fixups->data;
- import = (struct dyld_chained_import *) data;
- data += mo->n_bind * sizeof (struct dyld_chained_import);
- header->symbols_offset = data - mo->chained_fixups->data;
- data++;
- for (i = 0, bind_index = 0; i < mo->n_bind_rebase; i++) {
- if (mo->bind_rebase[i].bind) {
- import[bind_index].lib_ordinal =
- BIND_SPECIAL_DYLIB_FLAT_LOOKUP & 0xffu;
- import[bind_index].name_offset =
- (data - mo->chained_fixups->data) - header->symbols_offset;
- sym_index = ELFW(R_SYM)(mo->bind_rebase[i].rel.r_info);
- sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
- import[bind_index].weak_import =
- ELFW(ST_BIND)(sym->st_info) == STB_WEAK;
- name = (char *) symtab_section->link->data + sym->st_name;
- strcpy((char *) data, name);
- data += strlen(name) + 1;
- bind_index++;
- }
- }
- tcc_free(mo->bind_rebase);
-}
-#endif
-
-ST_FUNC int macho_output_file(TCCState *s1, const char *filename)
-{
- int fd, mode, file_type;
- FILE *fp;
- int i, ret = -1;
- struct macho mo;
-
- (void)memset(&mo, 0, sizeof(mo));
-
- file_type = s1->output_type;
- if (file_type == TCC_OUTPUT_OBJ)
- mode = 0666;
- else
- mode = 0777;
- unlink(filename);
- fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
- if (fd < 0 || (fp = fdopen(fd, "wb")) == NULL) {
- tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno));
- return -1;
- }
- if (s1->verbose)
- printf("<- %s\n", filename);
-
- tcc_add_runtime(s1);
- tcc_macho_add_destructor(s1);
- resolve_common_syms(s1);
- create_symtab(s1, &mo);
- check_relocs(s1, &mo);
- ret = check_symbols(s1, &mo);
- if (!ret) {
- int save_output = s1->output_type;
-
- collect_sections(s1, &mo, filename);
- relocate_syms(s1, s1->symtab, 0);
- if (s1->output_type == TCC_OUTPUT_EXE)
- mo.ep->entryoff = get_sym_addr(s1, "main", 1, 1)
- - get_segment(&mo, 1)->vmaddr;
- if (s1->nb_errors)
- goto do_ret;
- // Macho uses bind/rebase instead of dynsym
- s1->output_type = TCC_OUTPUT_EXE;
- relocate_sections(s1);
- s1->output_type = save_output;
-#ifdef CONFIG_NEW_MACHO
- bind_rebase_import(s1, &mo);
-#endif
- convert_symbols(s1, &mo);
- macho_write(s1, &mo, fp);
- }
-
- do_ret:
- for (i = 0; i < mo.nlc; i++)
- tcc_free(mo.lc[i]);
- tcc_free(mo.seg2lc);
- tcc_free(mo.lc);
- tcc_free(mo.elfsectomacho);
- tcc_free(mo.e2msym);
-
- fclose(fp);
-#ifdef CONFIG_CODESIGN
- if (!ret) {
- char command[1024];
- int retval;
-
- snprintf(command, sizeof(command), "codesign -f -s - %s", filename);
- retval = system (command);
- if (retval == -1 || !(WIFEXITED(retval) && WEXITSTATUS(retval) == 0))
- tcc_error ("command failed '%s'", command);
- }
-#endif
- return ret;
-}
-
-static uint32_t macho_swap32(uint32_t x)
-{
- return (x >> 24) | (x << 24) | ((x >> 8) & 0xff00) | ((x & 0xff00) << 8);
-}
-#define SWAP(x) (swap ? macho_swap32(x) : (x))
-#define tbd_parse_movepast(s) \
- (pos = (pos = strstr(pos, s)) ? pos + strlen(s) : NULL)
-#define tbd_parse_movetoany(cs) (pos = strpbrk(pos, cs))
-#define tbd_parse_skipws while (*pos && (*pos==' '||*pos=='\n')) ++pos
-#define tbd_parse_tramplequote if(*pos=='\''||*pos=='"') tbd_parse_trample
-#define tbd_parse_tramplespace if(*pos==' ') tbd_parse_trample
-#define tbd_parse_trample *pos++=0
-
-#ifdef TCC_IS_NATIVE
-/* Looks for the active developer SDK set by xcode-select (or the default
- one set during installation.) */
-ST_FUNC void tcc_add_macos_sdkpath(TCCState* s)
-{
- char *sdkroot = NULL, *pos = NULL;
- void* xcs = dlopen("libxcselect.dylib", RTLD_GLOBAL | RTLD_LAZY);
- CString path;
- int (*f)(unsigned int, char**) = dlsym(xcs, "xcselect_host_sdk_path");
- cstr_new(&path);
- if (f) f(1, &sdkroot);
- if (sdkroot)
- pos = strstr(sdkroot,"SDKs/MacOSX");
- if (pos)
- cstr_printf(&path, "%.*s.sdk/usr/lib", (int)(pos - sdkroot + 11), sdkroot);
- /* must use free from libc directly */
-#pragma push_macro("free")
-#undef free
- free(sdkroot);
-#pragma pop_macro("free")
- if (path.size)
- tcc_add_library_path(s, (char*)path.data);
- else
- tcc_add_library_path(s,
- "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib"
- ":" "/Applications/Xcode.app/Developer/SDKs/MacOSX.sdk/usr/lib"
- );
- cstr_free(&path);
-}
-
-ST_FUNC const char* macho_tbd_soname(const char* filename) {
- char *soname, *data, *pos;
- const char *ret = filename;
-
- int fd = open(filename,O_RDONLY);
- if (fd<0) return ret;
- pos = data = tcc_load_text(fd);
- if (!tbd_parse_movepast("install-name: ")) goto the_end;
- tbd_parse_skipws;
- tbd_parse_tramplequote;
- soname = pos;
- if (!tbd_parse_movetoany("\n \"'")) goto the_end;
- tbd_parse_trample;
- ret = tcc_strdup(soname);
-the_end:
- tcc_free(data);
- return ret;
-}
-#endif /* TCC_IS_NATIVE */
-
-ST_FUNC int macho_load_tbd(TCCState* s1, int fd, const char* filename, int lev)
-{
- char *soname, *data, *pos;
- int ret = -1;
-
- pos = data = tcc_load_text(fd);
- if (!tbd_parse_movepast("install-name: ")) goto the_end;
- tbd_parse_skipws;
- tbd_parse_tramplequote;
- soname = pos;
- if (!tbd_parse_movetoany("\n \"'")) goto the_end;
- tbd_parse_trample;
- ret = 0;
- if (tcc_add_dllref(s1, soname, lev)->found)
- goto the_end;
- while(pos) {
- char* sym = NULL;
- int cont = 1;
- if (!tbd_parse_movepast("symbols: ")) break;
- if (!tbd_parse_movepast("[")) break;
- while (cont) {
- tbd_parse_skipws;
- tbd_parse_tramplequote;
- sym = pos;
- if (!tbd_parse_movetoany(",] \"'")) break;
- tbd_parse_tramplequote;
- tbd_parse_tramplespace;
- tbd_parse_skipws;
- if (*pos==0||*pos==']') cont=0;
- tbd_parse_trample;
- set_elf_sym(s1->dynsymtab_section, 0, 0,
- ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, SHN_UNDEF, sym);
- }
- }
-
-the_end:
- tcc_free(data);
- return ret;
-}
-
-ST_FUNC int macho_load_dll(TCCState * s1, int fd, const char* filename, int lev)
-{
- unsigned char buf[sizeof(struct mach_header_64)];
- void *buf2;
- uint32_t machofs = 0;
- struct fat_header fh;
- struct mach_header mh;
- struct load_command *lc;
- int i, swap = 0;
- const char *soname = filename;
- struct nlist_64 *symtab = 0;
- uint32_t nsyms = 0;
- char *strtab = 0;
- uint32_t strsize = 0;
- uint32_t iextdef = 0;
- uint32_t nextdef = 0;
-
- again:
- if (full_read(fd, buf, sizeof(buf)) != sizeof(buf))
- return -1;
- memcpy(&fh, buf, sizeof(fh));
- if (fh.magic == FAT_MAGIC || fh.magic == FAT_CIGAM) {
- struct fat_arch *fa = load_data(fd, sizeof(fh),
- fh.nfat_arch * sizeof(*fa));
- swap = fh.magic == FAT_CIGAM;
- for (i = 0; i < SWAP(fh.nfat_arch); i++)
-#ifdef TCC_TARGET_X86_64
- if (SWAP(fa[i].cputype) == CPU_TYPE_X86_64
- && SWAP(fa[i].cpusubtype) == CPU_SUBTYPE_X86_ALL)
-#elif defined TCC_TARGET_ARM64
- if (SWAP(fa[i].cputype) == CPU_TYPE_ARM64
- && SWAP(fa[i].cpusubtype) == CPU_SUBTYPE_ARM64_ALL)
-#endif
- break;
- if (i == SWAP(fh.nfat_arch)) {
- tcc_free(fa);
- return -1;
- }
- machofs = SWAP(fa[i].offset);
- tcc_free(fa);
- lseek(fd, machofs, SEEK_SET);
- goto again;
- } else if (fh.magic == FAT_MAGIC_64 || fh.magic == FAT_CIGAM_64) {
- tcc_warning("%s: Mach-O fat 64bit files of type 0x%x not handled",
- filename, fh.magic);
- return -1;
- }
-
- memcpy(&mh, buf, sizeof(mh));
- if (mh.magic != MH_MAGIC_64)
- return -1;
- dprintf("found Mach-O at %d\n", machofs);
- buf2 = load_data(fd, machofs + sizeof(struct mach_header_64), mh.sizeofcmds);
- for (i = 0, lc = buf2; i < mh.ncmds; i++) {
- dprintf("lc %2d: 0x%08x\n", i, lc->cmd);
- switch (lc->cmd) {
- case LC_SYMTAB:
- {
- struct symtab_command *sc = (struct symtab_command*)lc;
- nsyms = sc->nsyms;
- symtab = load_data(fd, machofs + sc->symoff, nsyms * sizeof(*symtab));
- strsize = sc->strsize;
- strtab = load_data(fd, machofs + sc->stroff, strsize);
- break;
- }
- case LC_ID_DYLIB:
- {
- struct dylib_command *dc = (struct dylib_command*)lc;
- soname = (char*)lc + dc->name;
- dprintf(" ID_DYLIB %d 0x%x 0x%x %s\n",
- dc->timestamp, dc->current_version,
- dc->compatibility_version, soname);
- break;
- }
- case LC_REEXPORT_DYLIB:
- {
- struct dylib_command *dc = (struct dylib_command*)lc;
- char *name = (char*)lc + dc->name;
- int subfd = open(name, O_RDONLY | O_BINARY);
- dprintf(" REEXPORT %s\n", name);
- if (subfd < 0)
- tcc_warning("can't open %s (reexported from %s)", name, filename);
- else {
- /* Hopefully the REEXPORTs never form a cycle, we don't check
- for that! */
- macho_load_dll(s1, subfd, name, lev + 1);
- close(subfd);
- }
- break;
- }
- case LC_DYSYMTAB:
- {
- struct dysymtab_command *dc = (struct dysymtab_command*)lc;
- iextdef = dc->iextdefsym;
- nextdef = dc->nextdefsym;
- break;
- }
- }
- lc = (struct load_command*) ((char*)lc + lc->cmdsize);
- }
-
- if (tcc_add_dllref(s1, soname, lev)->found)
- goto the_end;
-
- if (!nsyms || !nextdef)
- tcc_warning("%s doesn't export any symbols?", filename);
-
- //dprintf("symbols (all):\n");
- dprintf("symbols (exported):\n");
- dprintf(" n: typ sec desc value name\n");
- //for (i = 0; i < nsyms; i++) {
- for (i = iextdef; i < iextdef + nextdef; i++) {
- struct nlist_64 *sym = symtab + i;
- dprintf("%5d: %3d %3d 0x%04x 0x%016lx %s\n",
- i, sym->n_type, sym->n_sect, sym->n_desc, (long)sym->n_value,
- strtab + sym->n_strx);
- set_elf_sym(s1->dynsymtab_section, 0, 0,
- ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE),
- 0, SHN_UNDEF, strtab + sym->n_strx);
- }
-
- the_end:
- tcc_free(strtab);
- tcc_free(symtab);
- tcc_free(buf2);
- return 0;
-}