The new gcc12 release does not support stabs any more. This was a good reason to add support for dwarf. The stabs code still works and is used if configure option --dwarf is not used. Tested on x86_64, i386, arm, arm64, riscv64 with dwarf-5. Some debuggers may not support dwarf-5. Try using older dwarf versions i that case. The tccmacho.c code probably need some support for dwarf. arm-gen.c, arm64-gen.c, i386-gen.c, riscv64-gen.c, x86_64-gen. - fix get_sym_ref symbol size arm-link.c, arm64-link.c, i386-link.c, riscv64-link.c, x86_64-link.c - add R_DATA_32U libtcc.c: - parse -gdwarf option tcc.c: - add dwarf option tcc.h: - add dwarf option and sections tccelf.c: - init dwarf sections - avoid adding sh_addr for dwarf sections - remove dwarf relocs for output dll - add dwarf sections for tccrun tccgen.c: - add dwarf defines + global data - add dwarf_* functions - mix dwarf code with stabs code - a trick is used to emit function name in .debug_line section so only this section has to be parsed instead of .debug_info and .debug_abbrev. - fix init debug_modes tccrun.c: - add dwarf sections in rt_context - init them in tcc_run - add new dwarf code rt_printline_dwarf to find file/function dwarf.h: - New file tcc-doc.texi: - document dwarf configure: - add dwarf option lib/Makefile - change -gstabs into -gdwarf lib/bt-exe.c, tests/tests2/Makefile, tests/tests2/126_bound_global: - Add __bound_init call - Add new testcase to test it
Unified · Split
| @@ -24,6 +24,7 @@ config*.h · 23 unmodified lines | |||
| 24 | config*.mak | 24 | config*.mak |
| 25 | config.texi | 25 | config.texi |
| 26 | conftest* | 26 | conftest* |
| 27 | c2str | ||
| 27 | tags | 28 | tags |
| 28 | TAGS | 29 | TAGS |
| 29 | tcc.1 | 30 | tcc.1 |
| @@ -866,7 +866,7 @@ static void gen_bounds_epilog(void) · 865 unmodified lines | |||
| 866 | *bounds_ptr = 0; | 866 | *bounds_ptr = 0; |
| 867 | 867 | ||
| 868 | sym_data = get_sym_ref(&char_pointer_type, lbounds_section, | 868 | sym_data = get_sym_ref(&char_pointer_type, lbounds_section, |
| 869 | func_bound_offset, lbounds_section->data_offset); | 869 | func_bound_offset, PTR_SIZE); |
| 870 | 870 | ||
| 871 | /* generate bound local allocation */ | 871 | /* generate bound local allocation */ |
| 872 | if (offset_modified) { | 872 | if (offset_modified) { |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | /* relocation type for 32 bit data relocation */ | 5 | /* relocation type for 32 bit data relocation */ |
| 6 | #define R_DATA_32 R_ARM_ABS32 | 6 | #define R_DATA_32 R_ARM_ABS32 |
| 7 | #define R_DATA_32U R_ARM_ABS32 | ||
| 7 | #define R_DATA_PTR R_ARM_ABS32 | 8 | #define R_DATA_PTR R_ARM_ABS32 |
| 8 | #define R_JMP_SLOT R_ARM_JUMP_SLOT | 9 | #define R_JMP_SLOT R_ARM_JUMP_SLOT |
| 9 | #define R_GLOB_DAT R_ARM_GLOB_DAT | 10 | #define R_GLOB_DAT R_ARM_GLOB_DAT |
| @@ -710,7 +710,7 @@ static void gen_bounds_epilog(void) · 709 unmodified lines | |||
| 710 | *bounds_ptr = 0; | 710 | *bounds_ptr = 0; |
| 711 | 711 | ||
| 712 | sym_data = get_sym_ref(&char_pointer_type, lbounds_section, | 712 | sym_data = get_sym_ref(&char_pointer_type, lbounds_section, |
| 713 | func_bound_offset, lbounds_section->data_offset); | 713 | func_bound_offset, PTR_SIZE); |
| 714 | 714 | ||
| 715 | /* generate bound local allocation */ | 715 | /* generate bound local allocation */ |
| 716 | if (offset_modified) { | 716 | if (offset_modified) { |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | |||
| 3 | #define EM_TCC_TARGET EM_AARCH64 | 3 | #define EM_TCC_TARGET EM_AARCH64 |
| 4 | 4 | ||
| 5 | #define R_DATA_32 R_AARCH64_ABS32 | 5 | #define R_DATA_32 R_AARCH64_ABS32 |
| 6 | #define R_DATA_32U R_AARCH64_ABS32 | ||
| 6 | #define R_DATA_PTR R_AARCH64_ABS64 | 7 | #define R_DATA_PTR R_AARCH64_ABS64 |
| 7 | #define R_JMP_SLOT R_AARCH64_JUMP_SLOT | 8 | #define R_JMP_SLOT R_AARCH64_JUMP_SLOT |
| 8 | #define R_GLOB_DAT R_AARCH64_GLOB_DAT | 9 | #define R_GLOB_DAT R_AARCH64_GLOB_DAT |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | /* relocation type for 32 bit data relocation */ | 5 | /* relocation type for 32 bit data relocation */ |
| 6 | #define R_DATA_32 R_C60_32 | 6 | #define R_DATA_32 R_C60_32 |
| 7 | #define R_DATA_32U R_C60_32 | ||
| 7 | #define R_DATA_PTR R_C60_32 | 8 | #define R_DATA_PTR R_C60_32 |
| 8 | #define R_JMP_SLOT R_C60_JMP_SLOT | 9 | #define R_JMP_SLOT R_C60_JMP_SLOT |
| 9 | #define R_GLOB_DAT R_C60_GLOB_DAT | 10 | #define R_GLOB_DAT R_C60_GLOB_DAT |
| @@ -51,6 +51,7 @@ ar_set= · 50 unmodified lines | |||
| 51 | darwin= | 51 | darwin= |
| 52 | cpu= | 52 | cpu= |
| 53 | cpuver= | 53 | cpuver= |
| 54 | dwarf= | ||
| 54 | 55 | ||
| 55 | # OS specific | 56 | # OS specific |
| 56 | cpu_sys=`uname -m` | 57 | cpu_sys=`uname -m` |
| @@ -136,6 +137,8 @@ for opt do · 79 unmodified lines | |||
| 136 | ;; | 137 | ;; |
| 137 | --cpu=*) cpu=`echo $opt | cut -d '=' -f 2-` | 138 | --cpu=*) cpu=`echo $opt | cut -d '=' -f 2-` |
| 138 | ;; | 139 | ;; |
| 140 | --dwarf=*) dwarf=`echo $opt | cut -d '=' -f 2-` | ||
| 141 | ;; | ||
| 139 | --enable-cross) confvars="$confvars cross" | 142 | --enable-cross) confvars="$confvars cross" |
| 140 | ;; | 143 | ;; |
| 141 | --disable-static) confvars="$confvars static=no" | 144 | --disable-static) confvars="$confvars static=no" |
| @@ -328,6 +331,7 @@ Advanced options (experts only): · 186 unmodified lines | |||
| 328 | --config-backtrace=no disable stack backtraces (with -run or -bt) | 331 | --config-backtrace=no disable stack backtraces (with -run or -bt) |
| 329 | --config-bcheck=no disable bounds checker (-b) | 332 | --config-bcheck=no disable bounds checker (-b) |
| 330 | --config-predefs=no do not compile tccdefs.h, instead just include | 333 | --config-predefs=no do not compile tccdefs.h, instead just include |
| 334 | --dwarf=x Use dwarf debug info instead of stabs (x=2..5) | ||
| 331 | EOF | 335 | EOF |
| 332 | exit 1 | 336 | exit 1 |
| 333 | fi | 337 | fi |
| @@ -493,6 +497,7 @@ print_mak CONFIG_TCC_ELFINTERP "$tcc_elfinterp" · 159 unmodified lines | |||
| 493 | print_mak CONFIG_LDDIR "$tcc_lddir" | 497 | print_mak CONFIG_LDDIR "$tcc_lddir" |
| 494 | print_mak CONFIG_TRIPLET "$triplet" | 498 | print_mak CONFIG_TRIPLET "$triplet" |
| 495 | print_mak TCC_CPU_VERSION "$cpuver" num | 499 | print_mak TCC_CPU_VERSION "$cpuver" num |
| 500 | print_mak CONFIG_DWARF "$dwarf" | ||
| 496 | 501 | ||
| 497 | echo "ARCH=$cpu" >> config.mak | 502 | echo "ARCH=$cpu" >> config.mak |
| 498 | echo "TARGETOS=$targetos" >> config.mak | 503 | echo "TARGETOS=$targetos" >> config.mak |
| @@ -0,0 +1,1046 @@ | |||
| 1 | /* This file defines standard DWARF types, structures, and macros. | ||
| 2 | Copyright (C) 2000-2011, 2014, 2016, 2017, 2018 Red Hat, Inc. | ||
| 3 | This file is part of elfutils. | ||
| 4 | |||
| 5 | This file is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of either | ||
| 7 | |||
| 8 | * the GNU Lesser General Public License as published by the Free | ||
| 9 | Software Foundation; either version 3 of the License, or (at | ||
| 10 | your option) any later version | ||
| 11 | |||
| 12 | or | ||
| 13 | |||
| 14 | * the GNU General Public License as published by the Free | ||
| 15 | Software Foundation; either version 2 of the License, or (at | ||
| 16 | your option) any later version | ||
| 17 | |||
| 18 | or both in parallel, as here. | ||
| 19 | |||
| 20 | elfutils is distributed in the hope that it will be useful, but | ||
| 21 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 22 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 23 | General Public License for more details. | ||
| 24 | |||
| 25 | You should have received copies of the GNU General Public License and | ||
| 26 | the GNU Lesser General Public License along with this program. If | ||
| 27 | not, see <http://www.gnu.org/licenses/>. */ | ||
| 28 | |||
| 29 | #ifndef _DWARF_H | ||
| 30 | #define _DWARF_H 1 | ||
| 31 | |||
| 32 | /* DWARF Unit Header Types. */ | ||
| 33 | enum | ||
| 34 | { | ||
| 35 | DW_UT_compile = 0x01, | ||
| 36 | DW_UT_type = 0x02, | ||
| 37 | DW_UT_partial = 0x03, | ||
| 38 | DW_UT_skeleton = 0x04, | ||
| 39 | DW_UT_split_compile = 0x05, | ||
| 40 | DW_UT_split_type = 0x06, | ||
| 41 | |||
| 42 | DW_UT_lo_user = 0x80, | ||
| 43 | DW_UT_hi_user = 0xff | ||
| 44 | }; | ||
| 45 | |||
| 46 | /* DWARF tags. */ | ||
| 47 | enum | ||
| 48 | { | ||
| 49 | DW_TAG_array_type = 0x01, | ||
| 50 | DW_TAG_class_type = 0x02, | ||
| 51 | DW_TAG_entry_point = 0x03, | ||
| 52 | DW_TAG_enumeration_type = 0x04, | ||
| 53 | DW_TAG_formal_parameter = 0x05, | ||
| 54 | /* 0x06 reserved. */ | ||
| 55 | /* 0x07 reserved. */ | ||
| 56 | DW_TAG_imported_declaration = 0x08, | ||
| 57 | /* 0x09 reserved. */ | ||
| 58 | DW_TAG_label = 0x0a, | ||
| 59 | DW_TAG_lexical_block = 0x0b, | ||
| 60 | /* 0x0c reserved. */ | ||
| 61 | DW_TAG_member = 0x0d, | ||
| 62 | /* 0x0e reserved. */ | ||
| 63 | DW_TAG_pointer_type = 0x0f, | ||
| 64 | DW_TAG_reference_type = 0x10, | ||
| 65 | DW_TAG_compile_unit = 0x11, | ||
| 66 | DW_TAG_string_type = 0x12, | ||
| 67 | DW_TAG_structure_type = 0x13, | ||
| 68 | /* 0x14 reserved. */ | ||
| 69 | DW_TAG_subroutine_type = 0x15, | ||
| 70 | DW_TAG_typedef = 0x16, | ||
| 71 | DW_TAG_union_type = 0x17, | ||
| 72 | DW_TAG_unspecified_parameters = 0x18, | ||
| 73 | DW_TAG_variant = 0x19, | ||
| 74 | DW_TAG_common_block = 0x1a, | ||
| 75 | DW_TAG_common_inclusion = 0x1b, | ||
| 76 | DW_TAG_inheritance = 0x1c, | ||
| 77 | DW_TAG_inlined_subroutine = 0x1d, | ||
| 78 | DW_TAG_module = 0x1e, | ||
| 79 | DW_TAG_ptr_to_member_type = 0x1f, | ||
| 80 | DW_TAG_set_type = 0x20, | ||
| 81 | DW_TAG_subrange_type = 0x21, | ||
| 82 | DW_TAG_with_stmt = 0x22, | ||
| 83 | DW_TAG_access_declaration = 0x23, | ||
| 84 | DW_TAG_base_type = 0x24, | ||
| 85 | DW_TAG_catch_block = 0x25, | ||
| 86 | DW_TAG_const_type = 0x26, | ||
| 87 | DW_TAG_constant = 0x27, | ||
| 88 | DW_TAG_enumerator = 0x28, | ||
| 89 | DW_TAG_file_type = 0x29, | ||
| 90 | DW_TAG_friend = 0x2a, | ||
| 91 | DW_TAG_namelist = 0x2b, | ||
| 92 | DW_TAG_namelist_item = 0x2c, | ||
| 93 | DW_TAG_packed_type = 0x2d, | ||
| 94 | DW_TAG_subprogram = 0x2e, | ||
| 95 | DW_TAG_template_type_parameter = 0x2f, | ||
| 96 | DW_TAG_template_value_parameter = 0x30, | ||
| 97 | DW_TAG_thrown_type = 0x31, | ||
| 98 | DW_TAG_try_block = 0x32, | ||
| 99 | DW_TAG_variant_part = 0x33, | ||
| 100 | DW_TAG_variable = 0x34, | ||
| 101 | DW_TAG_volatile_type = 0x35, | ||
| 102 | DW_TAG_dwarf_procedure = 0x36, | ||
| 103 | DW_TAG_restrict_type = 0x37, | ||
| 104 | DW_TAG_interface_type = 0x38, | ||
| 105 | DW_TAG_namespace = 0x39, | ||
| 106 | DW_TAG_imported_module = 0x3a, | ||
| 107 | DW_TAG_unspecified_type = 0x3b, | ||
| 108 | DW_TAG_partial_unit = 0x3c, | ||
| 109 | DW_TAG_imported_unit = 0x3d, | ||
| 110 | /* 0x3e reserved. Was DW_TAG_mutable_type. */ | ||
| 111 | DW_TAG_condition = 0x3f, | ||
| 112 | DW_TAG_shared_type = 0x40, | ||
| 113 | DW_TAG_type_unit = 0x41, | ||
| 114 | DW_TAG_rvalue_reference_type = 0x42, | ||
| 115 | DW_TAG_template_alias = 0x43, | ||
| 116 | DW_TAG_coarray_type = 0x44, | ||
| 117 | DW_TAG_generic_subrange = 0x45, | ||
| 118 | DW_TAG_dynamic_type = 0x46, | ||
| 119 | DW_TAG_atomic_type = 0x47, | ||
| 120 | DW_TAG_call_site = 0x48, | ||
| 121 | DW_TAG_call_site_parameter = 0x49, | ||
| 122 | DW_TAG_skeleton_unit = 0x4a, | ||
| 123 | DW_TAG_immutable_type = 0x4b, | ||
| 124 | |||
| 125 | DW_TAG_lo_user = 0x4080, | ||
| 126 | |||
| 127 | DW_TAG_MIPS_loop = 0x4081, | ||
| 128 | DW_TAG_format_label = 0x4101, | ||
| 129 | DW_TAG_function_template = 0x4102, | ||
| 130 | DW_TAG_class_template = 0x4103, | ||
| 131 | |||
| 132 | DW_TAG_GNU_BINCL = 0x4104, | ||
| 133 | DW_TAG_GNU_EINCL = 0x4105, | ||
| 134 | |||
| 135 | DW_TAG_GNU_template_template_param = 0x4106, | ||
| 136 | DW_TAG_GNU_template_parameter_pack = 0x4107, | ||
| 137 | DW_TAG_GNU_formal_parameter_pack = 0x4108, | ||
| 138 | DW_TAG_GNU_call_site = 0x4109, | ||
| 139 | DW_TAG_GNU_call_site_parameter = 0x410a, | ||
| 140 | |||
| 141 | DW_TAG_hi_user = 0xffff | ||
| 142 | }; | ||
| 143 | |||
| 144 | |||
| 145 | /* Children determination encodings. */ | ||
| 146 | enum | ||
| 147 | { | ||
| 148 | DW_CHILDREN_no = 0, | ||
| 149 | DW_CHILDREN_yes = 1 | ||
| 150 | }; | ||
| 151 | |||
| 152 | |||
| 153 | /* DWARF attributes encodings. */ | ||
| 154 | enum | ||
| 155 | { | ||
| 156 | DW_AT_sibling = 0x01, | ||
| 157 | DW_AT_location = 0x02, | ||
| 158 | DW_AT_name = 0x03, | ||
| 159 | /* 0x04 reserved. */ | ||
| 160 | /* 0x05 reserved. */ | ||
| 161 | /* 0x06 reserved. */ | ||
| 162 | /* 0x07 reserved. */ | ||
| 163 | /* 0x08 reserved. */ | ||
| 164 | DW_AT_ordering = 0x09, | ||
| 165 | /* 0x0a reserved. */ | ||
| 166 | DW_AT_byte_size = 0x0b, | ||
| 167 | DW_AT_bit_offset = 0x0c, /* Deprecated in DWARF4. */ | ||
| 168 | DW_AT_bit_size = 0x0d, | ||
| 169 | /* 0x0e reserved. */ | ||
| 170 | /* 0x0f reserved. */ | ||
| 171 | DW_AT_stmt_list = 0x10, | ||
| 172 | DW_AT_low_pc = 0x11, | ||
| 173 | DW_AT_high_pc = 0x12, | ||
| 174 | DW_AT_language = 0x13, | ||
| 175 | /* 0x14 reserved. */ | ||
| 176 | DW_AT_discr = 0x15, | ||
| 177 | DW_AT_discr_value = 0x16, | ||
| 178 | DW_AT_visibility = 0x17, | ||
| 179 | DW_AT_import = 0x18, | ||
| 180 | DW_AT_string_length = 0x19, | ||
| 181 | DW_AT_common_reference = 0x1a, | ||
| 182 | DW_AT_comp_dir = 0x1b, | ||
| 183 | DW_AT_const_value = 0x1c, | ||
| 184 | DW_AT_containing_type = 0x1d, | ||
| 185 | DW_AT_default_value = 0x1e, | ||
| 186 | /* 0x1f reserved. */ | ||
| 187 | DW_AT_inline = 0x20, | ||
| 188 | DW_AT_is_optional = 0x21, | ||
| 189 | DW_AT_lower_bound = 0x22, | ||
| 190 | /* 0x23 reserved. */ | ||
| 191 | /* 0x24 reserved. */ | ||
| 192 | DW_AT_producer = 0x25, | ||
| 193 | /* 0x26 reserved. */ | ||
| 194 | DW_AT_prototyped = 0x27, | ||
| 195 | /* 0x28 reserved. */ | ||
| 196 | /* 0x29 reserved. */ | ||
| 197 | DW_AT_return_addr = 0x2a, | ||
| 198 | /* 0x2b reserved. */ | ||
| 199 | DW_AT_start_scope = 0x2c, | ||
| 200 | /* 0x2d reserved. */ | ||
| 201 | DW_AT_bit_stride = 0x2e, | ||
| 202 | DW_AT_upper_bound = 0x2f, | ||
| 203 | /* 0x30 reserved. */ | ||
| 204 | DW_AT_abstract_origin = 0x31, | ||
| 205 | DW_AT_accessibility = 0x32, | ||
| 206 | DW_AT_address_class = 0x33, | ||
| 207 | DW_AT_artificial = 0x34, | ||
| 208 | DW_AT_base_types = 0x35, | ||
| 209 | DW_AT_calling_convention = 0x36, | ||
| 210 | DW_AT_count = 0x37, | ||
| 211 | DW_AT_data_member_location = 0x38, | ||
| 212 | DW_AT_decl_column = 0x39, | ||
| 213 | DW_AT_decl_file = 0x3a, | ||
| 214 | DW_AT_decl_line = 0x3b, | ||
| 215 | DW_AT_declaration = 0x3c, | ||
| 216 | DW_AT_discr_list = 0x3d, | ||
| 217 | DW_AT_encoding = 0x3e, | ||
| 218 | DW_AT_external = 0x3f, | ||
| 219 | DW_AT_frame_base = 0x40, | ||
| 220 | DW_AT_friend = 0x41, | ||
| 221 | DW_AT_identifier_case = 0x42, | ||
| 222 | DW_AT_macro_info = 0x43, /* Deprecated in DWARF5. */ | ||
| 223 | DW_AT_namelist_item = 0x44, | ||
| 224 | DW_AT_priority = 0x45, | ||
| 225 | DW_AT_segment = 0x46, | ||
| 226 | DW_AT_specification = 0x47, | ||
| 227 | DW_AT_static_link = 0x48, | ||
| 228 | DW_AT_type = 0x49, | ||
| 229 | DW_AT_use_location = 0x4a, | ||
| 230 | DW_AT_variable_parameter = 0x4b, | ||
| 231 | DW_AT_virtuality = 0x4c, | ||
| 232 | DW_AT_vtable_elem_location = 0x4d, | ||
| 233 | DW_AT_allocated = 0x4e, | ||
| 234 | DW_AT_associated = 0x4f, | ||
| 235 | DW_AT_data_location = 0x50, | ||
| 236 | DW_AT_byte_stride = 0x51, | ||
| 237 | DW_AT_entry_pc = 0x52, | ||
| 238 | DW_AT_use_UTF8 = 0x53, | ||
| 239 | DW_AT_extension = 0x54, | ||
| 240 | DW_AT_ranges = 0x55, | ||
| 241 | DW_AT_trampoline = 0x56, | ||
| 242 | DW_AT_call_column = 0x57, | ||
| 243 | DW_AT_call_file = 0x58, | ||
| 244 | DW_AT_call_line = 0x59, | ||
| 245 | DW_AT_description = 0x5a, | ||
| 246 | DW_AT_binary_scale = 0x5b, | ||
| 247 | DW_AT_decimal_scale = 0x5c, | ||
| 248 | DW_AT_small = 0x5d, | ||
| 249 | DW_AT_decimal_sign = 0x5e, | ||
| 250 | DW_AT_digit_count = 0x5f, | ||
| 251 | DW_AT_picture_string = 0x60, | ||
| 252 | DW_AT_mutable = 0x61, | ||
| 253 | DW_AT_threads_scaled = 0x62, | ||
| 254 | DW_AT_explicit = 0x63, | ||
| 255 | DW_AT_object_pointer = 0x64, | ||
| 256 | DW_AT_endianity = 0x65, | ||
| 257 | DW_AT_elemental = 0x66, | ||
| 258 | DW_AT_pure = 0x67, | ||
| 259 | DW_AT_recursive = 0x68, | ||
| 260 | DW_AT_signature = 0x69, | ||
| 261 | DW_AT_main_subprogram = 0x6a, | ||
| 262 | DW_AT_data_bit_offset = 0x6b, | ||
| 263 | DW_AT_const_expr = 0x6c, | ||
| 264 | DW_AT_enum_class = 0x6d, | ||
| 265 | DW_AT_linkage_name = 0x6e, | ||
| 266 | DW_AT_string_length_bit_size = 0x6f, | ||
| 267 | DW_AT_string_length_byte_size = 0x70, | ||
| 268 | DW_AT_rank = 0x71, | ||
| 269 | DW_AT_str_offsets_base = 0x72, | ||
| 270 | DW_AT_addr_base = 0x73, | ||
| 271 | DW_AT_rnglists_base = 0x74, | ||
| 272 | /* 0x75 reserved. */ | ||
| 273 | DW_AT_dwo_name = 0x76, | ||
| 274 | DW_AT_reference = 0x77, | ||
| 275 | DW_AT_rvalue_reference = 0x78, | ||
| 276 | DW_AT_macros = 0x79, | ||
| 277 | DW_AT_call_all_calls = 0x7a, | ||
| 278 | DW_AT_call_all_source_calls = 0x7b, | ||
| 279 | DW_AT_call_all_tail_calls = 0x7c, | ||
| 280 | DW_AT_call_return_pc = 0x7d, | ||
| 281 | DW_AT_call_value = 0x7e, | ||
| 282 | DW_AT_call_origin = 0x7f, | ||
| 283 | DW_AT_call_parameter = 0x80, | ||
| 284 | DW_AT_call_pc = 0x81, | ||
| 285 | DW_AT_call_tail_call = 0x82, | ||
| 286 | DW_AT_call_target = 0x83, | ||
| 287 | DW_AT_call_target_clobbered = 0x84, | ||
| 288 | DW_AT_call_data_location = 0x85, | ||
| 289 | DW_AT_call_data_value = 0x86, | ||
| 290 | DW_AT_noreturn = 0x87, | ||
| 291 | DW_AT_alignment = 0x88, | ||
| 292 | DW_AT_export_symbols = 0x89, | ||
| 293 | DW_AT_deleted = 0x8a, | ||
| 294 | DW_AT_defaulted = 0x8b, | ||
| 295 | DW_AT_loclists_base = 0x8c, | ||
| 296 | |||
| 297 | DW_AT_lo_user = 0x2000, | ||
| 298 | |||
| 299 | DW_AT_MIPS_fde = 0x2001, | ||
| 300 | DW_AT_MIPS_loop_begin = 0x2002, | ||
| 301 | DW_AT_MIPS_tail_loop_begin = 0x2003, | ||
| 302 | DW_AT_MIPS_epilog_begin = 0x2004, | ||
| 303 | DW_AT_MIPS_loop_unroll_factor = 0x2005, | ||
| 304 | DW_AT_MIPS_software_pipeline_depth = 0x2006, | ||
| 305 | DW_AT_MIPS_linkage_name = 0x2007, | ||
| 306 | DW_AT_MIPS_stride = 0x2008, | ||
| 307 | DW_AT_MIPS_abstract_name = 0x2009, | ||
| 308 | DW_AT_MIPS_clone_origin = 0x200a, | ||
| 309 | DW_AT_MIPS_has_inlines = 0x200b, | ||
| 310 | DW_AT_MIPS_stride_byte = 0x200c, | ||
| 311 | DW_AT_MIPS_stride_elem = 0x200d, | ||
| 312 | DW_AT_MIPS_ptr_dopetype = 0x200e, | ||
| 313 | DW_AT_MIPS_allocatable_dopetype = 0x200f, | ||
| 314 | DW_AT_MIPS_assumed_shape_dopetype = 0x2010, | ||
| 315 | DW_AT_MIPS_assumed_size = 0x2011, | ||
| 316 | |||
| 317 | /* GNU extensions. */ | ||
| 318 | DW_AT_sf_names = 0x2101, | ||
| 319 | DW_AT_src_info = 0x2102, | ||
| 320 | DW_AT_mac_info = 0x2103, | ||
| 321 | DW_AT_src_coords = 0x2104, | ||
| 322 | DW_AT_body_begin = 0x2105, | ||
| 323 | DW_AT_body_end = 0x2106, | ||
| 324 | DW_AT_GNU_vector = 0x2107, | ||
| 325 | DW_AT_GNU_guarded_by = 0x2108, | ||
| 326 | DW_AT_GNU_pt_guarded_by = 0x2109, | ||
| 327 | DW_AT_GNU_guarded = 0x210a, | ||
| 328 | DW_AT_GNU_pt_guarded = 0x210b, | ||
| 329 | DW_AT_GNU_locks_excluded = 0x210c, | ||
| 330 | DW_AT_GNU_exclusive_locks_required = 0x210d, | ||
| 331 | DW_AT_GNU_shared_locks_required = 0x210e, | ||
| 332 | DW_AT_GNU_odr_signature = 0x210f, | ||
| 333 | DW_AT_GNU_template_name = 0x2110, | ||
| 334 | DW_AT_GNU_call_site_value = 0x2111, | ||
| 335 | DW_AT_GNU_call_site_data_value = 0x2112, | ||
| 336 | DW_AT_GNU_call_site_target = 0x2113, | ||
| 337 | DW_AT_GNU_call_site_target_clobbered = 0x2114, | ||
| 338 | DW_AT_GNU_tail_call = 0x2115, | ||
| 339 | DW_AT_GNU_all_tail_call_sites = 0x2116, | ||
| 340 | DW_AT_GNU_all_call_sites = 0x2117, | ||
| 341 | DW_AT_GNU_all_source_call_sites = 0x2118, | ||
| 342 | DW_AT_GNU_locviews = 0x2137, | ||
| 343 | DW_AT_GNU_entry_view = 0x2138, | ||
| 344 | DW_AT_GNU_macros = 0x2119, | ||
| 345 | DW_AT_GNU_deleted = 0x211a, | ||
| 346 | /* GNU Debug Fission extensions. */ | ||
| 347 | DW_AT_GNU_dwo_name = 0x2130, | ||
| 348 | DW_AT_GNU_dwo_id = 0x2131, | ||
| 349 | DW_AT_GNU_ranges_base = 0x2132, | ||
| 350 | DW_AT_GNU_addr_base = 0x2133, | ||
| 351 | DW_AT_GNU_pubnames = 0x2134, | ||
| 352 | DW_AT_GNU_pubtypes = 0x2135, | ||
| 353 | |||
| 354 | /* https://gcc.gnu.org/wiki/DW_AT_GNU_numerator_denominator */ | ||
| 355 | DW_AT_GNU_numerator = 0x2303, | ||
| 356 | DW_AT_GNU_denominator = 0x2304, | ||
| 357 | /* https://gcc.gnu.org/wiki/DW_AT_GNU_bias */ | ||
| 358 | DW_AT_GNU_bias = 0x2305, | ||
| 359 | |||
| 360 | DW_AT_hi_user = 0x3fff | ||
| 361 | }; | ||
| 362 | |||
| 363 | /* Old unofficially attribute names. Should not be used. | ||
| 364 | Will not appear in known-dwarf.h */ | ||
| 365 | |||
| 366 | /* DWARF1 array subscripts and element data types. */ | ||
| 367 | #define DW_AT_subscr_data 0x0a | ||
| 368 | /* DWARF1 enumeration literals. */ | ||
| 369 | #define DW_AT_element_list 0x0f | ||
| 370 | /* DWARF1 reference for variable to member structure, class or union. */ | ||
| 371 | #define DW_AT_member 0x14 | ||
| 372 | |||
| 373 | /* DWARF form encodings. */ | ||
| 374 | enum | ||
| 375 | { | ||
| 376 | DW_FORM_addr = 0x01, | ||
| 377 | DW_FORM_block2 = 0x03, | ||
| 378 | DW_FORM_block4 = 0x04, | ||
| 379 | DW_FORM_data2 = 0x05, | ||
| 380 | DW_FORM_data4 = 0x06, | ||
| 381 | DW_FORM_data8 = 0x07, | ||
| 382 | DW_FORM_string = 0x08, | ||
| 383 | DW_FORM_block = 0x09, | ||
| 384 | DW_FORM_block1 = 0x0a, | ||
| 385 | DW_FORM_data1 = 0x0b, | ||
| 386 | DW_FORM_flag = 0x0c, | ||
| 387 | DW_FORM_sdata = 0x0d, | ||
| 388 | DW_FORM_strp = 0x0e, | ||
| 389 | DW_FORM_udata = 0x0f, | ||
| 390 | DW_FORM_ref_addr = 0x10, | ||
| 391 | DW_FORM_ref1 = 0x11, | ||
| 392 | DW_FORM_ref2 = 0x12, | ||
| 393 | DW_FORM_ref4 = 0x13, | ||
| 394 | DW_FORM_ref8 = 0x14, | ||
| 395 | DW_FORM_ref_udata = 0x15, | ||
| 396 | DW_FORM_indirect = 0x16, | ||
| 397 | DW_FORM_sec_offset = 0x17, | ||
| 398 | DW_FORM_exprloc = 0x18, | ||
| 399 | DW_FORM_flag_present = 0x19, | ||
| 400 | DW_FORM_strx = 0x1a, | ||
| 401 | DW_FORM_addrx = 0x1b, | ||
| 402 | DW_FORM_ref_sup4 = 0x1c, | ||
| 403 | DW_FORM_strp_sup = 0x1d, | ||
| 404 | DW_FORM_data16 = 0x1e, | ||
| 405 | DW_FORM_line_strp = 0x1f, | ||
| 406 | DW_FORM_ref_sig8 = 0x20, | ||
| 407 | DW_FORM_implicit_const = 0x21, | ||
| 408 | DW_FORM_loclistx = 0x22, | ||
| 409 | DW_FORM_rnglistx = 0x23, | ||
| 410 | DW_FORM_ref_sup8 = 0x24, | ||
| 411 | DW_FORM_strx1 = 0x25, | ||
| 412 | DW_FORM_strx2 = 0x26, | ||
| 413 | DW_FORM_strx3 = 0x27, | ||
| 414 | DW_FORM_strx4 = 0x28, | ||
| 415 | DW_FORM_addrx1 = 0x29, | ||
| 416 | DW_FORM_addrx2 = 0x2a, | ||
| 417 | DW_FORM_addrx3 = 0x2b, | ||
| 418 | DW_FORM_addrx4 = 0x2c, | ||
| 419 | |||
| 420 | /* GNU Debug Fission extensions. */ | ||
| 421 | DW_FORM_GNU_addr_index = 0x1f01, | ||
| 422 | DW_FORM_GNU_str_index = 0x1f02, | ||
| 423 | |||
| 424 | DW_FORM_GNU_ref_alt = 0x1f20, /* offset in alternate .debuginfo. */ | ||
| 425 | DW_FORM_GNU_strp_alt = 0x1f21 /* offset in alternate .debug_str. */ | ||
| 426 | }; | ||
| 427 | |||
| 428 | |||
| 429 | /* DWARF location operation encodings. */ | ||
| 430 | enum | ||
| 431 | { | ||
| 432 | DW_OP_addr = 0x03, /* Constant address. */ | ||
| 433 | DW_OP_deref = 0x06, | ||
| 434 | DW_OP_const1u = 0x08, /* Unsigned 1-byte constant. */ | ||
| 435 | DW_OP_const1s = 0x09, /* Signed 1-byte constant. */ | ||
| 436 | DW_OP_const2u = 0x0a, /* Unsigned 2-byte constant. */ | ||
| 437 | DW_OP_const2s = 0x0b, /* Signed 2-byte constant. */ | ||
| 438 | DW_OP_const4u = 0x0c, /* Unsigned 4-byte constant. */ | ||
| 439 | DW_OP_const4s = 0x0d, /* Signed 4-byte constant. */ | ||
| 440 | DW_OP_const8u = 0x0e, /* Unsigned 8-byte constant. */ | ||
| 441 | DW_OP_const8s = 0x0f, /* Signed 8-byte constant. */ | ||
| 442 | DW_OP_constu = 0x10, /* Unsigned LEB128 constant. */ | ||
| 443 | DW_OP_consts = 0x11, /* Signed LEB128 constant. */ | ||
| 444 | DW_OP_dup = 0x12, | ||
| 445 | DW_OP_drop = 0x13, | ||
| 446 | DW_OP_over = 0x14, | ||
| 447 | DW_OP_pick = 0x15, /* 1-byte stack index. */ | ||
| 448 | DW_OP_swap = 0x16, | ||
| 449 | DW_OP_rot = 0x17, | ||
| 450 | DW_OP_xderef = 0x18, | ||
| 451 | DW_OP_abs = 0x19, | ||
| 452 | DW_OP_and = 0x1a, | ||
| 453 | DW_OP_div = 0x1b, | ||
| 454 | DW_OP_minus = 0x1c, | ||
| 455 | DW_OP_mod = 0x1d, | ||
| 456 | DW_OP_mul = 0x1e, | ||
| 457 | DW_OP_neg = 0x1f, | ||
| 458 | DW_OP_not = 0x20, | ||
| 459 | DW_OP_or = 0x21, | ||
| 460 | DW_OP_plus = 0x22, | ||
| 461 | DW_OP_plus_uconst = 0x23, /* Unsigned LEB128 addend. */ | ||
| 462 | DW_OP_shl = 0x24, | ||
| 463 | DW_OP_shr = 0x25, | ||
| 464 | DW_OP_shra = 0x26, | ||
| 465 | DW_OP_xor = 0x27, | ||
| 466 | DW_OP_bra = 0x28, /* Signed 2-byte constant. */ | ||
| 467 | DW_OP_eq = 0x29, | ||
| 468 | DW_OP_ge = 0x2a, | ||
| 469 | DW_OP_gt = 0x2b, | ||
| 470 | DW_OP_le = 0x2c, | ||
| 471 | DW_OP_lt = 0x2d, | ||
| 472 | DW_OP_ne = 0x2e, | ||
| 473 | DW_OP_skip = 0x2f, /* Signed 2-byte constant. */ | ||
| 474 | DW_OP_lit0 = 0x30, /* Literal 0. */ | ||
| 475 | DW_OP_lit1 = 0x31, /* Literal 1. */ | ||
| 476 | DW_OP_lit2 = 0x32, /* Literal 2. */ | ||
| 477 | DW_OP_lit3 = 0x33, /* Literal 3. */ | ||
| 478 | DW_OP_lit4 = 0x34, /* Literal 4. */ | ||
| 479 | DW_OP_lit5 = 0x35, /* Literal 5. */ | ||
| 480 | DW_OP_lit6 = 0x36, /* Literal 6. */ | ||
| 481 | DW_OP_lit7 = 0x37, /* Literal 7. */ | ||
| 482 | DW_OP_lit8 = 0x38, /* Literal 8. */ | ||
| 483 | DW_OP_lit9 = 0x39, /* Literal 9. */ | ||
| 484 | DW_OP_lit10 = 0x3a, /* Literal 10. */ | ||
| 485 | DW_OP_lit11 = 0x3b, /* Literal 11. */ | ||
| 486 | DW_OP_lit12 = 0x3c, /* Literal 12. */ | ||
| 487 | DW_OP_lit13 = 0x3d, /* Literal 13. */ | ||
| 488 | DW_OP_lit14 = 0x3e, /* Literal 14. */ | ||
| 489 | DW_OP_lit15 = 0x3f, /* Literal 15. */ | ||
| 490 | DW_OP_lit16 = 0x40, /* Literal 16. */ | ||
| 491 | DW_OP_lit17 = 0x41, /* Literal 17. */ | ||
| 492 | DW_OP_lit18 = 0x42, /* Literal 18. */ | ||
| 493 | DW_OP_lit19 = 0x43, /* Literal 19. */ | ||
| 494 | DW_OP_lit20 = 0x44, /* Literal 20. */ | ||
| 495 | DW_OP_lit21 = 0x45, /* Literal 21. */ | ||
| 496 | DW_OP_lit22 = 0x46, /* Literal 22. */ | ||
| 497 | DW_OP_lit23 = 0x47, /* Literal 23. */ | ||
| 498 | DW_OP_lit24 = 0x48, /* Literal 24. */ | ||
| 499 | DW_OP_lit25 = 0x49, /* Literal 25. */ | ||
| 500 | DW_OP_lit26 = 0x4a, /* Literal 26. */ | ||
| 501 | DW_OP_lit27 = 0x4b, /* Literal 27. */ | ||
| 502 | DW_OP_lit28 = 0x4c, /* Literal 28. */ | ||
| 503 | DW_OP_lit29 = 0x4d, /* Literal 29. */ | ||
| 504 | DW_OP_lit30 = 0x4e, /* Literal 30. */ | ||
| 505 | DW_OP_lit31 = 0x4f, /* Literal 31. */ | ||
| 506 | DW_OP_reg0 = 0x50, /* Register 0. */ | ||
| 507 | DW_OP_reg1 = 0x51, /* Register 1. */ | ||
| 508 | DW_OP_reg2 = 0x52, /* Register 2. */ | ||
| 509 | DW_OP_reg3 = 0x53, /* Register 3. */ | ||
| 510 | DW_OP_reg4 = 0x54, /* Register 4. */ | ||
| 511 | DW_OP_reg5 = 0x55, /* Register 5. */ | ||
| 512 | DW_OP_reg6 = 0x56, /* Register 6. */ | ||
| 513 | DW_OP_reg7 = 0x57, /* Register 7. */ | ||
| 514 | DW_OP_reg8 = 0x58, /* Register 8. */ | ||
| 515 | DW_OP_reg9 = 0x59, /* Register 9. */ | ||
| 516 | DW_OP_reg10 = 0x5a, /* Register 10. */ | ||
| 517 | DW_OP_reg11 = 0x5b, /* Register 11. */ | ||
| 518 | DW_OP_reg12 = 0x5c, /* Register 12. */ | ||
| 519 | DW_OP_reg13 = 0x5d, /* Register 13. */ | ||
| 520 | DW_OP_reg14 = 0x5e, /* Register 14. */ | ||
| 521 | DW_OP_reg15 = 0x5f, /* Register 15. */ | ||
| 522 | DW_OP_reg16 = 0x60, /* Register 16. */ | ||
| 523 | DW_OP_reg17 = 0x61, /* Register 17. */ | ||
| 524 | DW_OP_reg18 = 0x62, /* Register 18. */ | ||
| 525 | DW_OP_reg19 = 0x63, /* Register 19. */ | ||
| 526 | DW_OP_reg20 = 0x64, /* Register 20. */ | ||
| 527 | DW_OP_reg21 = 0x65, /* Register 21. */ | ||
| 528 | DW_OP_reg22 = 0x66, /* Register 22. */ | ||
| 529 | DW_OP_reg23 = 0x67, /* Register 24. */ | ||
| 530 | DW_OP_reg24 = 0x68, /* Register 24. */ | ||
| 531 | DW_OP_reg25 = 0x69, /* Register 25. */ | ||
| 532 | DW_OP_reg26 = 0x6a, /* Register 26. */ | ||
| 533 | DW_OP_reg27 = 0x6b, /* Register 27. */ | ||
| 534 | DW_OP_reg28 = 0x6c, /* Register 28. */ | ||
| 535 | DW_OP_reg29 = 0x6d, /* Register 29. */ | ||
| 536 | DW_OP_reg30 = 0x6e, /* Register 30. */ | ||
| 537 | DW_OP_reg31 = 0x6f, /* Register 31. */ | ||
| 538 | DW_OP_breg0 = 0x70, /* Base register 0. */ | ||
| 539 | DW_OP_breg1 = 0x71, /* Base register 1. */ | ||
| 540 | DW_OP_breg2 = 0x72, /* Base register 2. */ | ||
| 541 | DW_OP_breg3 = 0x73, /* Base register 3. */ | ||
| 542 | DW_OP_breg4 = 0x74, /* Base register 4. */ | ||
| 543 | DW_OP_breg5 = 0x75, /* Base register 5. */ | ||
| 544 | DW_OP_breg6 = 0x76, /* Base register 6. */ | ||
| 545 | DW_OP_breg7 = 0x77, /* Base register 7. */ | ||
| 546 | DW_OP_breg8 = 0x78, /* Base register 8. */ | ||
| 547 | DW_OP_breg9 = 0x79, /* Base register 9. */ | ||
| 548 | DW_OP_breg10 = 0x7a, /* Base register 10. */ | ||
| 549 | DW_OP_breg11 = 0x7b, /* Base register 11. */ | ||
| 550 | DW_OP_breg12 = 0x7c, /* Base register 12. */ | ||
| 551 | DW_OP_breg13 = 0x7d, /* Base register 13. */ | ||
| 552 | DW_OP_breg14 = 0x7e, /* Base register 14. */ | ||
| 553 | DW_OP_breg15 = 0x7f, /* Base register 15. */ | ||
| 554 | DW_OP_breg16 = 0x80, /* Base register 16. */ | ||
| 555 | DW_OP_breg17 = 0x81, /* Base register 17. */ | ||
| 556 | DW_OP_breg18 = 0x82, /* Base register 18. */ | ||
| 557 | DW_OP_breg19 = 0x83, /* Base register 19. */ | ||
| 558 | DW_OP_breg20 = 0x84, /* Base register 20. */ | ||
| 559 | DW_OP_breg21 = 0x85, /* Base register 21. */ | ||
| 560 | DW_OP_breg22 = 0x86, /* Base register 22. */ | ||
| 561 | DW_OP_breg23 = 0x87, /* Base register 23. */ | ||
| 562 | DW_OP_breg24 = 0x88, /* Base register 24. */ | ||
| 563 | DW_OP_breg25 = 0x89, /* Base register 25. */ | ||
| 564 | DW_OP_breg26 = 0x8a, /* Base register 26. */ | ||
| 565 | DW_OP_breg27 = 0x8b, /* Base register 27. */ | ||
| 566 | DW_OP_breg28 = 0x8c, /* Base register 28. */ | ||
| 567 | DW_OP_breg29 = 0x8d, /* Base register 29. */ | ||
| 568 | DW_OP_breg30 = 0x8e, /* Base register 30. */ | ||
| 569 | DW_OP_breg31 = 0x8f, /* Base register 31. */ | ||
| 570 | DW_OP_regx = 0x90, /* Unsigned LEB128 register. */ | ||
| 571 | DW_OP_fbreg = 0x91, /* Signed LEB128 offset. */ | ||
| 572 | DW_OP_bregx = 0x92, /* ULEB128 register followed by SLEB128 off. */ | ||
| 573 | DW_OP_piece = 0x93, /* ULEB128 size of piece addressed. */ | ||
| 574 | DW_OP_deref_size = 0x94, /* 1-byte size of data retrieved. */ | ||
| 575 | DW_OP_xderef_size = 0x95, /* 1-byte size of data retrieved. */ | ||
| 576 | DW_OP_nop = 0x96, | ||
| 577 | DW_OP_push_object_address = 0x97, | ||
| 578 | DW_OP_call2 = 0x98, | ||
| 579 | DW_OP_call4 = 0x99, | ||
| 580 | DW_OP_call_ref = 0x9a, | ||
| 581 | DW_OP_form_tls_address = 0x9b,/* TLS offset to address in current thread */ | ||
| 582 | DW_OP_call_frame_cfa = 0x9c,/* CFA as determined by CFI. */ | ||
| 583 | DW_OP_bit_piece = 0x9d, /* ULEB128 size and ULEB128 offset in bits. */ | ||
| 584 | DW_OP_implicit_value = 0x9e, /* DW_FORM_block follows opcode. */ | ||
| 585 | DW_OP_stack_value = 0x9f, /* No operands, special like DW_OP_piece. */ | ||
| 586 | |||
| 587 | DW_OP_implicit_pointer = 0xa0, | ||
| 588 | DW_OP_addrx = 0xa1, | ||
| 589 | DW_OP_constx = 0xa2, | ||
| 590 | DW_OP_entry_value = 0xa3, | ||
| 591 | DW_OP_const_type = 0xa4, | ||
| 592 | DW_OP_regval_type = 0xa5, | ||
| 593 | DW_OP_deref_type = 0xa6, | ||
| 594 | DW_OP_xderef_type = 0xa7, | ||
| 595 | DW_OP_convert = 0xa8, | ||
| 596 | DW_OP_reinterpret = 0xa9, | ||
| 597 | |||
| 598 | /* GNU extensions. */ | ||
| 599 | DW_OP_GNU_push_tls_address = 0xe0, | ||
| 600 | DW_OP_GNU_uninit = 0xf0, | ||
| 601 | DW_OP_GNU_encoded_addr = 0xf1, | ||
| 602 | DW_OP_GNU_implicit_pointer = 0xf2, | ||
| 603 | DW_OP_GNU_entry_value = 0xf3, | ||
| 604 | DW_OP_GNU_const_type = 0xf4, | ||
| 605 | DW_OP_GNU_regval_type = 0xf5, | ||
| 606 | DW_OP_GNU_deref_type = 0xf6, | ||
| 607 | DW_OP_GNU_convert = 0xf7, | ||
| 608 | DW_OP_GNU_reinterpret = 0xf9, | ||
| 609 | DW_OP_GNU_parameter_ref = 0xfa, | ||
| 610 | |||
| 611 | /* GNU Debug Fission extensions. */ | ||
| 612 | DW_OP_GNU_addr_index = 0xfb, | ||
| 613 | DW_OP_GNU_const_index = 0xfc, | ||
| 614 | |||
| 615 | DW_OP_GNU_variable_value = 0xfd, | ||
| 616 | |||
| 617 | DW_OP_lo_user = 0xe0, /* Implementation-defined range start. */ | ||
| 618 | DW_OP_hi_user = 0xff /* Implementation-defined range end. */ | ||
| 619 | }; | ||
| 620 | |||
| 621 | |||
| 622 | /* DWARF base type encodings. */ | ||
| 623 | enum | ||
| 624 | { | ||
| 625 | DW_ATE_void = 0x0, | ||
| 626 | DW_ATE_address = 0x1, | ||
| 627 | DW_ATE_boolean = 0x2, | ||
| 628 | DW_ATE_complex_float = 0x3, | ||
| 629 | DW_ATE_float = 0x4, | ||
| 630 | DW_ATE_signed = 0x5, | ||
| 631 | DW_ATE_signed_char = 0x6, | ||
| 632 | DW_ATE_unsigned = 0x7, | ||
| 633 | DW_ATE_unsigned_char = 0x8, | ||
| 634 | DW_ATE_imaginary_float = 0x9, | ||
| 635 | DW_ATE_packed_decimal = 0xa, | ||
| 636 | DW_ATE_numeric_string = 0xb, | ||
| 637 | DW_ATE_edited = 0xc, | ||
| 638 | DW_ATE_signed_fixed = 0xd, | ||
| 639 | DW_ATE_unsigned_fixed = 0xe, | ||
| 640 | DW_ATE_decimal_float = 0xf, | ||
| 641 | DW_ATE_UTF = 0x10, | ||
| 642 | DW_ATE_UCS = 0x11, | ||
| 643 | DW_ATE_ASCII = 0x12, | ||
| 644 | |||
| 645 | DW_ATE_lo_user = 0x80, | ||
| 646 | DW_ATE_hi_user = 0xff | ||
| 647 | }; | ||
| 648 | |||
| 649 | |||
| 650 | /* DWARF decimal sign encodings. */ | ||
| 651 | enum | ||
| 652 | { | ||
| 653 | DW_DS_unsigned = 1, | ||
| 654 | DW_DS_leading_overpunch = 2, | ||
| 655 | DW_DS_trailing_overpunch = 3, | ||
| 656 | DW_DS_leading_separate = 4, | ||
| 657 | DW_DS_trailing_separate = 5, | ||
| 658 | }; | ||
| 659 | |||
| 660 | |||
| 661 | /* DWARF endianity encodings. */ | ||
| 662 | enum | ||
| 663 | { | ||
| 664 | DW_END_default = 0, | ||
| 665 | DW_END_big = 1, | ||
| 666 | DW_END_little = 2, | ||
| 667 | |||
| 668 | DW_END_lo_user = 0x40, | ||
| 669 | DW_END_hi_user = 0xff | ||
| 670 | }; | ||
| 671 | |||
| 672 | |||
| 673 | /* DWARF accessibility encodings. */ | ||
| 674 | enum | ||
| 675 | { | ||
| 676 | DW_ACCESS_public = 1, | ||
| 677 | DW_ACCESS_protected = 2, | ||
| 678 | DW_ACCESS_private = 3 | ||
| 679 | }; | ||
| 680 | |||
| 681 | |||
| 682 | /* DWARF visibility encodings. */ | ||
| 683 | enum | ||
| 684 | { | ||
| 685 | DW_VIS_local = 1, | ||
| 686 | DW_VIS_exported = 2, | ||
| 687 | DW_VIS_qualified = 3 | ||
| 688 | }; | ||
| 689 | |||
| 690 | |||
| 691 | /* DWARF virtuality encodings. */ | ||
| 692 | enum | ||
| 693 | { | ||
| 694 | DW_VIRTUALITY_none = 0, | ||
| 695 | DW_VIRTUALITY_virtual = 1, | ||
| 696 | DW_VIRTUALITY_pure_virtual = 2 | ||
| 697 | }; | ||
| 698 | |||
| 699 | |||
| 700 | /* DWARF language encodings. */ | ||
| 701 | enum | ||
| 702 | { | ||
| 703 | DW_LANG_C89 = 0x0001, /* ISO C:1989 */ | ||
| 704 | DW_LANG_C = 0x0002, /* C */ | ||
| 705 | DW_LANG_Ada83 = 0x0003, /* ISO Ada:1983 */ | ||
| 706 | DW_LANG_C_plus_plus = 0x0004, /* ISO C++:1998 */ | ||
| 707 | DW_LANG_Cobol74 = 0x0005, /* ISO Cobol:1974 */ | ||
| 708 | DW_LANG_Cobol85 = 0x0006, /* ISO Cobol:1985 */ | ||
| 709 | DW_LANG_Fortran77 = 0x0007, /* ISO FORTRAN 77 */ | ||
| 710 | DW_LANG_Fortran90 = 0x0008, /* ISO Fortran 90 */ | ||
| 711 | DW_LANG_Pascal83 = 0x0009, /* ISO Pascal:1983 */ | ||
| 712 | DW_LANG_Modula2 = 0x000a, /* ISO Modula-2:1996 */ | ||
| 713 | DW_LANG_Java = 0x000b, /* Java */ | ||
| 714 | DW_LANG_C99 = 0x000c, /* ISO C:1999 */ | ||
| 715 | DW_LANG_Ada95 = 0x000d, /* ISO Ada:1995 */ | ||
| 716 | DW_LANG_Fortran95 = 0x000e, /* ISO Fortran 95 */ | ||
| 717 | DW_LANG_PLI = 0x000f, /* ISO PL/1:1976 */ | ||
| 718 | DW_LANG_ObjC = 0x0010, /* Objective-C */ | ||
| 719 | DW_LANG_ObjC_plus_plus = 0x0011, /* Objective-C++ */ | ||
| 720 | DW_LANG_UPC = 0x0012, /* Unified Parallel C */ | ||
| 721 | DW_LANG_D = 0x0013, /* D */ | ||
| 722 | DW_LANG_Python = 0x0014, /* Python */ | ||
| 723 | DW_LANG_OpenCL = 0x0015, /* OpenCL */ | ||
| 724 | DW_LANG_Go = 0x0016, /* Go */ | ||
| 725 | DW_LANG_Modula3 = 0x0017, /* Modula-3 */ | ||
| 726 | DW_LANG_Haskell = 0x0018, /* Haskell */ | ||
| 727 | DW_LANG_C_plus_plus_03 = 0x0019, /* ISO C++:2003 */ | ||
| 728 | DW_LANG_C_plus_plus_11 = 0x001a, /* ISO C++:2011 */ | ||
| 729 | DW_LANG_OCaml = 0x001b, /* OCaml */ | ||
| 730 | DW_LANG_Rust = 0x001c, /* Rust */ | ||
| 731 | DW_LANG_C11 = 0x001d, /* ISO C:2011 */ | ||
| 732 | DW_LANG_Swift = 0x001e, /* Swift */ | ||
| 733 | DW_LANG_Julia = 0x001f, /* Julia */ | ||
| 734 | DW_LANG_Dylan = 0x0020, /* Dylan */ | ||
| 735 | DW_LANG_C_plus_plus_14 = 0x0021, /* ISO C++:2014 */ | ||
| 736 | DW_LANG_Fortran03 = 0x0022, /* ISO/IEC 1539-1:2004 */ | ||
| 737 | DW_LANG_Fortran08 = 0x0023, /* ISO/IEC 1539-1:2010 */ | ||
| 738 | DW_LANG_RenderScript = 0x0024, /* RenderScript Kernal Language */ | ||
| 739 | DW_LANG_BLISS = 0x0025, /* BLISS */ | ||
| 740 | |||
| 741 | DW_LANG_lo_user = 0x8000, | ||
| 742 | DW_LANG_Mips_Assembler = 0x8001, /* Assembler */ | ||
| 743 | DW_LANG_hi_user = 0xffff | ||
| 744 | }; | ||
| 745 | |||
| 746 | /* Old (typo) '1' != 'I'. */ | ||
| 747 | #define DW_LANG_PL1 DW_LANG_PLI | ||
| 748 | |||
| 749 | /* DWARF identifier case encodings. */ | ||
| 750 | enum | ||
| 751 | { | ||
| 752 | DW_ID_case_sensitive = 0, | ||
| 753 | DW_ID_up_case = 1, | ||
| 754 | DW_ID_down_case = 2, | ||
| 755 | DW_ID_case_insensitive = 3 | ||
| 756 | }; | ||
| 757 | |||
| 758 | |||
| 759 | /* DWARF calling conventions encodings. | ||
| 760 | Used as values of DW_AT_calling_convention for subroutines | ||
| 761 | (normal, program or nocall) or structures, unions and class types | ||
| 762 | (normal, reference or value). */ | ||
| 763 | enum | ||
| 764 | { | ||
| 765 | DW_CC_normal = 0x1, | ||
| 766 | DW_CC_program = 0x2, | ||
| 767 | DW_CC_nocall = 0x3, | ||
| 768 | DW_CC_pass_by_reference = 0x4, | ||
| 769 | DW_CC_pass_by_value = 0x5, | ||
| 770 | DW_CC_lo_user = 0x40, | ||
| 771 | DW_CC_hi_user = 0xff | ||
| 772 | }; | ||
| 773 | |||
| 774 | |||
| 775 | /* DWARF inline encodings. */ | ||
| 776 | enum | ||
| 777 | { | ||
| 778 | DW_INL_not_inlined = 0, | ||
| 779 | DW_INL_inlined = 1, | ||
| 780 | DW_INL_declared_not_inlined = 2, | ||
| 781 | DW_INL_declared_inlined = 3 | ||
| 782 | }; | ||
| 783 | |||
| 784 | |||
| 785 | /* DWARF ordering encodings. */ | ||
| 786 | enum | ||
| 787 | { | ||
| 788 | DW_ORD_row_major = 0, | ||
| 789 | DW_ORD_col_major = 1 | ||
| 790 | }; | ||
| 791 | |||
| 792 | |||
| 793 | /* DWARF discriminant descriptor encodings. */ | ||
| 794 | enum | ||
| 795 | { | ||
| 796 | DW_DSC_label = 0, | ||
| 797 | DW_DSC_range = 1 | ||
| 798 | }; | ||
| 799 | |||
| 800 | /* DWARF defaulted member function encodings. */ | ||
| 801 | enum | ||
| 802 | { | ||
| 803 | DW_DEFAULTED_no = 0, | ||
| 804 | DW_DEFAULTED_in_class = 1, | ||
| 805 | DW_DEFAULTED_out_of_class = 2 | ||
| 806 | }; | ||
| 807 | |||
| 808 | /* DWARF line content descriptions. */ | ||
| 809 | enum | ||
| 810 | { | ||
| 811 | DW_LNCT_path = 0x1, | ||
| 812 | DW_LNCT_directory_index = 0x2, | ||
| 813 | DW_LNCT_timestamp = 0x3, | ||
| 814 | DW_LNCT_size = 0x4, | ||
| 815 | DW_LNCT_MD5 = 0x5, | ||
| 816 | DW_LNCT_lo_user = 0x2000, | ||
| 817 | DW_LNCT_hi_user = 0x3fff | ||
| 818 | }; | ||
| 819 | |||
| 820 | /* DWARF standard opcode encodings. */ | ||
| 821 | enum | ||
| 822 | { | ||
| 823 | DW_LNS_copy = 1, | ||
| 824 | DW_LNS_advance_pc = 2, | ||
| 825 | DW_LNS_advance_line = 3, | ||
| 826 | DW_LNS_set_file = 4, | ||
| 827 | DW_LNS_set_column = 5, | ||
| 828 | DW_LNS_negate_stmt = 6, | ||
| 829 | DW_LNS_set_basic_block = 7, | ||
| 830 | DW_LNS_const_add_pc = 8, | ||
| 831 | DW_LNS_fixed_advance_pc = 9, | ||
| 832 | DW_LNS_set_prologue_end = 10, | ||
| 833 | DW_LNS_set_epilogue_begin = 11, | ||
| 834 | DW_LNS_set_isa = 12 | ||
| 835 | }; | ||
| 836 | |||
| 837 | |||
| 838 | /* DWARF extended opcode encodings. */ | ||
| 839 | enum | ||
| 840 | { | ||
| 841 | DW_LNE_end_sequence = 1, | ||
| 842 | DW_LNE_set_address = 2, | ||
| 843 | DW_LNE_define_file = 3, | ||
| 844 | DW_LNE_set_discriminator = 4, | ||
| 845 | |||
| 846 | DW_LNE_lo_user = 128, | ||
| 847 | |||
| 848 | DW_LNE_NVIDIA_inlined_call = 144, | ||
| 849 | DW_LNE_NVIDIA_set_function_name = 145, | ||
| 850 | |||
| 851 | DW_LNE_hi_user = 255 | ||
| 852 | }; | ||
| 853 | |||
| 854 | |||
| 855 | /* DWARF macinfo type encodings. */ | ||
| 856 | enum | ||
| 857 | { | ||
| 858 | DW_MACINFO_define = 1, | ||
| 859 | DW_MACINFO_undef = 2, | ||
| 860 | DW_MACINFO_start_file = 3, | ||
| 861 | DW_MACINFO_end_file = 4, | ||
| 862 | DW_MACINFO_vendor_ext = 255 | ||
| 863 | }; | ||
| 864 | |||
| 865 | |||
| 866 | /* DWARF debug_macro type encodings. */ | ||
| 867 | enum | ||
| 868 | { | ||
| 869 | DW_MACRO_define = 0x01, | ||
| 870 | DW_MACRO_undef = 0x02, | ||
| 871 | DW_MACRO_start_file = 0x03, | ||
| 872 | DW_MACRO_end_file = 0x04, | ||
| 873 | DW_MACRO_define_strp = 0x05, | ||
| 874 | DW_MACRO_undef_strp = 0x06, | ||
| 875 | DW_MACRO_import = 0x07, | ||
| 876 | DW_MACRO_define_sup = 0x08, | ||
| 877 | DW_MACRO_undef_sup = 0x09, | ||
| 878 | DW_MACRO_import_sup = 0x0a, | ||
| 879 | DW_MACRO_define_strx = 0x0b, | ||
| 880 | DW_MACRO_undef_strx = 0x0c, | ||
| 881 | DW_MACRO_lo_user = 0xe0, | ||
| 882 | DW_MACRO_hi_user = 0xff | ||
| 883 | }; | ||
| 884 | |||
| 885 | /* Old GNU extension names for DWARF5 debug_macro type encodings. | ||
| 886 | There are no equivalents for the supplementary object file (sup) | ||
| 887 | and indirect string references (strx). */ | ||
| 888 | #define DW_MACRO_GNU_define DW_MACRO_define | ||
| 889 | #define DW_MACRO_GNU_undef DW_MACRO_undef | ||
| 890 | #define DW_MACRO_GNU_start_file DW_MACRO_start_file | ||
| 891 | #define DW_MACRO_GNU_end_file DW_MACRO_end_file | ||
| 892 | #define DW_MACRO_GNU_define_indirect DW_MACRO_define_strp | ||
| 893 | #define DW_MACRO_GNU_undef_indirect DW_MACRO_undef_strp | ||
| 894 | #define DW_MACRO_GNU_transparent_include DW_MACRO_import | ||
| 895 | #define DW_MACRO_GNU_lo_user DW_MACRO_lo_user | ||
| 896 | #define DW_MACRO_GNU_hi_user DW_MACRO_hi_user | ||
| 897 | |||
| 898 | |||
| 899 | /* Range list entry encoding. */ | ||
| 900 | enum | ||
| 901 | { | ||
| 902 | DW_RLE_end_of_list = 0x0, | ||
| 903 | DW_RLE_base_addressx = 0x1, | ||
| 904 | DW_RLE_startx_endx = 0x2, | ||
| 905 | DW_RLE_startx_length = 0x3, | ||
| 906 | DW_RLE_offset_pair = 0x4, | ||
| 907 | DW_RLE_base_address = 0x5, | ||
| 908 | DW_RLE_start_end = 0x6, | ||
| 909 | DW_RLE_start_length = 0x7 | ||
| 910 | }; | ||
| 911 | |||
| 912 | |||
| 913 | /* Location list entry encoding. */ | ||
| 914 | enum | ||
| 915 | { | ||
| 916 | DW_LLE_end_of_list = 0x0, | ||
| 917 | DW_LLE_base_addressx = 0x1, | ||
| 918 | DW_LLE_startx_endx = 0x2, | ||
| 919 | DW_LLE_startx_length = 0x3, | ||
| 920 | DW_LLE_offset_pair = 0x4, | ||
| 921 | DW_LLE_default_location = 0x5, | ||
| 922 | DW_LLE_base_address = 0x6, | ||
| 923 | DW_LLE_start_end = 0x7, | ||
| 924 | DW_LLE_start_length = 0x8 | ||
| 925 | }; | ||
| 926 | |||
| 927 | |||
| 928 | /* GNU DebugFission list entry encodings (.debug_loc.dwo). */ | ||
| 929 | enum | ||
| 930 | { | ||
| 931 | DW_LLE_GNU_end_of_list_entry = 0x0, | ||
| 932 | DW_LLE_GNU_base_address_selection_entry = 0x1, | ||
| 933 | DW_LLE_GNU_start_end_entry = 0x2, | ||
| 934 | DW_LLE_GNU_start_length_entry = 0x3 | ||
| 935 | }; | ||
| 936 | |||
| 937 | /* DWARF5 package file section identifiers. */ | ||
| 938 | enum | ||
| 939 | { | ||
| 940 | DW_SECT_INFO = 1, | ||
| 941 | /* Reserved = 2, */ | ||
| 942 | DW_SECT_ABBREV = 3, | ||
| 943 | DW_SECT_LINE = 4, | ||
| 944 | DW_SECT_LOCLISTS = 5, | ||
| 945 | DW_SECT_STR_OFFSETS = 6, | ||
| 946 | DW_SECT_MACRO = 7, | ||
| 947 | DW_SECT_RNGLISTS = 8, | ||
| 948 | }; | ||
| 949 | |||
| 950 | |||
| 951 | /* DWARF call frame instruction encodings. */ | ||
| 952 | enum | ||
| 953 | { | ||
| 954 | DW_CFA_advance_loc = 0x40, | ||
| 955 | DW_CFA_offset = 0x80, | ||
| 956 | DW_CFA_restore = 0xc0, | ||
| 957 | DW_CFA_extended = 0, | ||
| 958 | |||
| 959 | DW_CFA_nop = 0x00, | ||
| 960 | DW_CFA_set_loc = 0x01, | ||
| 961 | DW_CFA_advance_loc1 = 0x02, | ||
| 962 | DW_CFA_advance_loc2 = 0x03, | ||
| 963 | DW_CFA_advance_loc4 = 0x04, | ||
| 964 | DW_CFA_offset_extended = 0x05, | ||
| 965 | DW_CFA_restore_extended = 0x06, | ||
| 966 | DW_CFA_undefined = 0x07, | ||
| 967 | DW_CFA_same_value = 0x08, | ||
| 968 | DW_CFA_register = 0x09, | ||
| 969 | DW_CFA_remember_state = 0x0a, | ||
| 970 | DW_CFA_restore_state = 0x0b, | ||
| 971 | DW_CFA_def_cfa = 0x0c, | ||
| 972 | DW_CFA_def_cfa_register = 0x0d, | ||
| 973 | DW_CFA_def_cfa_offset = 0x0e, | ||
| 974 | DW_CFA_def_cfa_expression = 0x0f, | ||
| 975 | DW_CFA_expression = 0x10, | ||
| 976 | DW_CFA_offset_extended_sf = 0x11, | ||
| 977 | DW_CFA_def_cfa_sf = 0x12, | ||
| 978 | DW_CFA_def_cfa_offset_sf = 0x13, | ||
| 979 | DW_CFA_val_offset = 0x14, | ||
| 980 | DW_CFA_val_offset_sf = 0x15, | ||
| 981 | DW_CFA_val_expression = 0x16, | ||
| 982 | |||
| 983 | DW_CFA_low_user = 0x1c, | ||
| 984 | DW_CFA_MIPS_advance_loc8 = 0x1d, | ||
| 985 | DW_CFA_GNU_window_save = 0x2d, | ||
| 986 | DW_CFA_AARCH64_negate_ra_state = 0x2d, | ||
| 987 | DW_CFA_GNU_args_size = 0x2e, | ||
| 988 | DW_CFA_GNU_negative_offset_extended = 0x2f, | ||
| 989 | DW_CFA_high_user = 0x3f | ||
| 990 | }; | ||
| 991 | |||
| 992 | /* ID indicating CIE as opposed to FDE in .debug_frame. */ | ||
| 993 | enum | ||
| 994 | { | ||
| 995 | DW_CIE_ID_32 = 0xffffffffU, /* In 32-bit format CIE header. */ | ||
| 996 | DW_CIE_ID_64 = 0xffffffffffffffffULL /* In 64-bit format CIE header. */ | ||
| 997 | }; | ||
| 998 | |||
| 999 | |||
| 1000 | /* Information for GNU unwind information. */ | ||
| 1001 | enum | ||
| 1002 | { | ||
| 1003 | DW_EH_PE_absptr = 0x00, | ||
| 1004 | DW_EH_PE_omit = 0xff, | ||
| 1005 | |||
| 1006 | /* FDE data encoding. */ | ||
| 1007 | DW_EH_PE_uleb128 = 0x01, | ||
| 1008 | DW_EH_PE_udata2 = 0x02, | ||
| 1009 | DW_EH_PE_udata4 = 0x03, | ||
| 1010 | DW_EH_PE_udata8 = 0x04, | ||
| 1011 | DW_EH_PE_sleb128 = 0x09, | ||
| 1012 | DW_EH_PE_sdata2 = 0x0a, | ||
| 1013 | DW_EH_PE_sdata4 = 0x0b, | ||
| 1014 | DW_EH_PE_sdata8 = 0x0c, | ||
| 1015 | DW_EH_PE_signed = 0x08, | ||
| 1016 | |||
| 1017 | /* FDE flags. */ | ||
| 1018 | DW_EH_PE_pcrel = 0x10, | ||
| 1019 | DW_EH_PE_textrel = 0x20, | ||
| 1020 | DW_EH_PE_datarel = 0x30, | ||
| 1021 | DW_EH_PE_funcrel = 0x40, | ||
| 1022 | DW_EH_PE_aligned = 0x50, | ||
| 1023 | |||
| 1024 | DW_EH_PE_indirect = 0x80 | ||
| 1025 | }; | ||
| 1026 | |||
| 1027 | |||
| 1028 | /* DWARF XXX. */ | ||
| 1029 | #define DW_ADDR_none 0 | ||
| 1030 | |||
| 1031 | /* Section 7.2.2 of the DWARF3 specification defines a range of escape | ||
| 1032 | codes that can appear in the length field of certain DWARF structures. | ||
| 1033 | |||
| 1034 | These defines enumerate the minimum and maximum values of this range. | ||
| 1035 | Currently only the maximum value is used (to indicate that 64-bit | ||
| 1036 | values are going to be used in the dwarf data that accompanies the | ||
| 1037 | structure). The other values are reserved. | ||
| 1038 | |||
| 1039 | Note: There is a typo in DWARF3 spec (published Dec 20, 2005). In | ||
| 1040 | sections 7.4, 7.5.1, 7.19, 7.20 the minimum escape code is referred to | ||
| 1041 | as 0xffffff00 whereas in fact it should be 0xfffffff0. */ | ||
| 1042 | #define DWARF3_LENGTH_MIN_ESCAPE_CODE 0xfffffff0u | ||
| 1043 | #define DWARF3_LENGTH_MAX_ESCAPE_CODE 0xffffffffu | ||
| 1044 | #define DWARF3_LENGTH_64_BIT DWARF3_LENGTH_MAX_ESCAPE_CODE | ||
| 1045 | |||
| 1046 | #endif /* dwarf.h */ | ||
| @@ -1071,7 +1071,7 @@ static void gen_bounds_epilog(void) · 1070 unmodified lines | |||
| 1071 | *bounds_ptr = 0; | 1071 | *bounds_ptr = 0; |
| 1072 | 1072 | ||
| 1073 | sym_data = get_sym_ref(&char_pointer_type, lbounds_section, | 1073 | sym_data = get_sym_ref(&char_pointer_type, lbounds_section, |
| 1074 | func_bound_offset, lbounds_section->data_offset); | 1074 | func_bound_offset, PTR_SIZE); |
| 1075 | 1075 | ||
| 1076 | /* generate bound local allocation */ | 1076 | /* generate bound local allocation */ |
| 1077 | if (offset_modified) { | 1077 | if (offset_modified) { |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | /* relocation type for 32 bit data relocation */ | 5 | /* relocation type for 32 bit data relocation */ |
| 6 | #define R_DATA_32 R_386_32 | 6 | #define R_DATA_32 R_386_32 |
| 7 | #define R_DATA_32U R_386_32 | ||
| 7 | #define R_DATA_PTR R_386_32 | 8 | #define R_DATA_PTR R_386_32 |
| 8 | #define R_JMP_SLOT R_386_JMP_SLOT | 9 | #define R_JMP_SLOT R_386_JMP_SLOT |
| 9 | #define R_GLOB_DAT R_386_GLOB_DAT | 10 | #define R_GLOB_DAT R_386_GLOB_DAT |
| @@ -27,7 +27,7 @@ arm-libtcc1-usegcc ?= no · 26 unmodified lines | |||
| 27 | ifeq "$($(T)-libtcc1-usegcc)" "yes" | 27 | ifeq "$($(T)-libtcc1-usegcc)" "yes" |
| 28 | XCC = $(CC) | 28 | XCC = $(CC) |
| 29 | XAR = $(AR) | 29 | XAR = $(AR) |
| 30 | XFLAGS = $(CFLAGS) -fPIC -gstabs -fno-omit-frame-pointer -Wno-unused-function -Wno-unused-variable | 30 | XFLAGS = $(CFLAGS) -fPIC -gdwarf -fno-omit-frame-pointer -Wno-unused-function -Wno-unused-variable |
| 31 | endif | 31 | endif |
| 32 | 32 | ||
| 33 | ifneq ($(CONFIG_backtrace),no) | 33 | ifneq ($(CONFIG_backtrace),no) |
| @@ -18,6 +18,10 @@ void __bt_init(rt_context *p, int num_callers) · 17 unmodified lines | |||
| 18 | __attribute__((weak)) void __bound_init(void*, int); | 18 | __attribute__((weak)) void __bound_init(void*, int); |
| 19 | struct rt_context *rc = &g_rtctxt; | 19 | struct rt_context *rc = &g_rtctxt; |
| 20 | //fprintf(stderr, "__bt_init %d %p %p\n", num_callers, p->stab_sym, p->bounds_start), fflush(stderr); | 20 | //fprintf(stderr, "__bt_init %d %p %p\n", num_callers, p->stab_sym, p->bounds_start), fflush(stderr); |
| 21 | /* call __bound_init here due to redirection of sigaction */ | ||
| 22 | /* needed to add global symbols */ | ||
| 23 | if (__bound_init && p->bounds_start) | ||
| 24 | __bound_init(p->bounds_start, -1); | ||
| 21 | if (num_callers) { | 25 | if (num_callers) { |
| 22 | memcpy(rc, p, offsetof(rt_context, next)); | 26 | memcpy(rc, p, offsetof(rt_context, next)); |
| 23 | rc->num_callers = num_callers - 1; | 27 | rc->num_callers = num_callers - 1; |
| @@ -1722,6 +1722,12 @@ static void args_parser_listfile(TCCState *s, · 1721 unmodified lines | |||
| 1722 | *pargc = s->argc = argc, *pargv = s->argv = argv; | 1722 | *pargc = s->argc = argc, *pargv = s->argv = argv; |
| 1723 | } | 1723 | } |
| 1724 | 1724 | ||
| 1725 | #ifdef CONFIG_DWARF | ||
| 1726 | #define DWARF_VERSION atoi(CONFIG_DWARF) | ||
| 1727 | #else | ||
| 1728 | #define DWARF_VERSION 0 | ||
| 1729 | #endif | ||
| 1730 | |||
| 1725 | PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind) | 1731 | PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind) |
| 1726 | { | 1732 | { |
| 1727 | TCCState *s1 = s; | 1733 | TCCState *s1 = s; |
| @@ -1819,6 +1825,7 @@ reparse: · 91 unmodified lines | |||
| 1819 | s->rt_num_callers = atoi(optarg); | 1825 | s->rt_num_callers = atoi(optarg); |
| 1820 | s->do_backtrace = 1; | 1826 | s->do_backtrace = 1; |
| 1821 | s->do_debug = 1; | 1827 | s->do_debug = 1; |
| 1828 | s->dwarf = DWARF_VERSION; | ||
| 1822 | break; | 1829 | break; |
| 1823 | #endif | 1830 | #endif |
| 1824 | #ifdef CONFIG_TCC_BCHECK | 1831 | #ifdef CONFIG_TCC_BCHECK |
| @@ -1826,16 +1833,22 @@ reparse: · 1 unmodified line | |||
| 1826 | s->do_bounds_check = 1; | 1833 | s->do_bounds_check = 1; |
| 1827 | s->do_backtrace = 1; | 1834 | s->do_backtrace = 1; |
| 1828 | s->do_debug = 1; | 1835 | s->do_debug = 1; |
| 1836 | s->dwarf = DWARF_VERSION; | ||
| 1829 | break; | 1837 | break; |
| 1830 | #endif | 1838 | #endif |
| 1831 | case TCC_OPTION_g: | 1839 | case TCC_OPTION_g: |
| 1832 | /* Use "-g" as alias for "-g1". Use "-g0" to disable debug */ | 1840 | /* Use "-g" as alias for "-g1". Use "-g0" to disable debug */ |
| 1833 | /* Other common used values: "-g0", "-g1", "-g2" and "-g3" */ | 1841 | /* Other common used values: "-g0", "-g1", "-g2" and "-g3" */ |
| 1834 | /* no failure with unsupported options */ | 1842 | /* no failure with unsupported options */ |
| 1835 | if (isnum(*optarg)) | 1843 | s->do_debug = 1; |
| 1844 | s->dwarf = DWARF_VERSION; | ||
| 1845 | if (*optarg == 'd') { | ||
| 1846 | s->dwarf = 5; | ||
| 1847 | if (!strncmp(optarg,"dwarf-",6)) | ||
| 1848 | s->dwarf = atoi(optarg + 6); | ||
| 1849 | } | ||
| 1850 | else if (isnum(*optarg)) | ||
| 1836 | s->do_debug = atoi(optarg); | 1851 | s->do_debug = atoi(optarg); |
| 1837 | else | ||
| 1838 | s->do_debug = 1; | ||
| 1839 | break; | 1852 | break; |
| 1840 | case TCC_OPTION_c: | 1853 | case TCC_OPTION_c: |
| 1841 | x = TCC_OUTPUT_OBJ; | 1854 | x = TCC_OUTPUT_OBJ; |
| @@ -471,7 +471,7 @@ static void gen_bounds_epilog(void) · 470 unmodified lines | |||
| 471 | *bounds_ptr = 0; | 471 | *bounds_ptr = 0; |
| 472 | 472 | ||
| 473 | sym_data = get_sym_ref(&char_pointer_type, lbounds_section, | 473 | sym_data = get_sym_ref(&char_pointer_type, lbounds_section, |
| 474 | func_bound_offset, lbounds_section->data_offset); | 474 | func_bound_offset, PTR_SIZE); |
| 475 | 475 | ||
| 476 | label.type.t = VT_VOID | VT_STATIC; | 476 | label.type.t = VT_VOID | VT_STATIC; |
| 477 | /* generate bound local allocation */ | 477 | /* generate bound local allocation */ |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | |||
| 3 | #define EM_TCC_TARGET EM_RISCV | 3 | #define EM_TCC_TARGET EM_RISCV |
| 4 | 4 | ||
| 5 | #define R_DATA_32 R_RISCV_32 | 5 | #define R_DATA_32 R_RISCV_32 |
| 6 | #define R_DATA_32U R_RISCV_32 | ||
| 6 | #define R_DATA_PTR R_RISCV_64 | 7 | #define R_DATA_PTR R_RISCV_64 |
| 7 | #define R_JMP_SLOT R_RISCV_JUMP_SLOT | 8 | #define R_JMP_SLOT R_RISCV_JUMP_SLOT |
| 8 | #define R_GLOB_DAT R_RISCV_64 | 9 | #define R_GLOB_DAT R_RISCV_64 |
| @@ -349,12 +349,15 @@ Turn on/off linking of all objects in archives. · 348 unmodified lines | |||
| 349 | Debugger options: | 349 | Debugger options: |
| 350 | 350 | ||
| 351 | @table @option | 351 | @table @option |
| 352 | @item -g | 352 | @item -g[x] |
| 353 | Generate run time debug information so that you get clear run time | 353 | Generate run time stab debug information so that you get clear run time |
| 354 | error messages: @code{ test.c:68: in function 'test5()': dereferencing | 354 | error messages: @code{ test.c:68: in function 'test5()': dereferencing |
| 355 | invalid pointer} instead of the laconic @code{Segmentation | 355 | invalid pointer} instead of the laconic @code{Segmentation |
| 356 | fault}. | 356 | fault}. |
| 357 | 357 | ||
| 358 | @item -gdwarf[-x] | ||
| 359 | Generate run time dwarf debug information instead of stab debug information. | ||
| 360 | |||
| 358 | @item -b | 361 | @item -b |
| 359 | Generate additional support code to check memory allocations and array/pointer | 362 | Generate additional support code to check memory allocations and array/pointer |
| 360 | bounds (@pxref{Bounds}). @option{-g} is implied. | 363 | bounds (@pxref{Bounds}). @option{-g} is implied. |
| @@ -58,7 +58,8 @@ static const char help[] = · 57 unmodified lines | |||
| 58 | " -soname set name for shared library to be used at runtime\n" | 58 | " -soname set name for shared library to be used at runtime\n" |
| 59 | " -Wl,-opt[=val] set linker option (see tcc -hh)\n" | 59 | " -Wl,-opt[=val] set linker option (see tcc -hh)\n" |
| 60 | "Debugger options:\n" | 60 | "Debugger options:\n" |
| 61 | " -g generate runtime debug info\n" | 61 | " -g[x] generate stab runtime debug info\n" |
| 62 | " -gdwarf[-x] generate dwarf runtime debug info\n" | ||
| 62 | #ifdef CONFIG_TCC_BCHECK | 63 | #ifdef CONFIG_TCC_BCHECK |
| 63 | " -b compile with built-in memory and bounds checker (implies -g)\n" | 64 | " -b compile with built-in memory and bounds checker (implies -g)\n" |
| 64 | #endif | 65 | #endif |
| @@ -368,6 +368,7 @@ extern long double strtold (const char *__nptr, char **__endptr); · 367 unmodified lines | |||
| 368 | #include "libtcc.h" | 368 | #include "libtcc.h" |
| 369 | #include "elf.h" | 369 | #include "elf.h" |
| 370 | #include "stab.h" | 370 | #include "stab.h" |
| 371 | #include "dwarf.h" | ||
| 371 | 372 | ||
| 372 | /* -------------------------------------------- */ | 373 | /* -------------------------------------------- */ |
| 373 | 374 | ||
| @@ -792,6 +793,7 @@ struct TCCState { · 418 unmodified lines | |||
| 792 | 793 | ||
| 793 | /* compile with debug symbol (and use them if error during execution) */ | 794 | /* compile with debug symbol (and use them if error during execution) */ |
| 794 | unsigned char do_debug; | 795 | unsigned char do_debug; |
| 796 | unsigned char dwarf; | ||
| 795 | unsigned char do_backtrace; | 797 | unsigned char do_backtrace; |
| 796 | #ifdef CONFIG_TCC_BCHECK | 798 | #ifdef CONFIG_TCC_BCHECK |
| 797 | /* compile with built-in memory and bounds checker */ | 799 | /* compile with built-in memory and bounds checker */ |
| @@ -922,6 +924,12 @@ struct TCCState { · 124 unmodified lines | |||
| 922 | Section *symtab_section; | 924 | Section *symtab_section; |
| 923 | /* debug sections */ | 925 | /* debug sections */ |
| 924 | Section *stab_section; | 926 | Section *stab_section; |
| 927 | Section *dwarf_info_section; | ||
| 928 | Section *dwarf_abbrev_section; | ||
| 929 | Section *dwarf_line_section; | ||
| 930 | Section *dwarf_aranges_section; | ||
| 931 | Section *dwarf_str_section; | ||
| 932 | Section *dwarf_line_str_section; | ||
| 925 | /* Is there a new undefined sym since last new_undef_sym() */ | 933 | /* Is there a new undefined sym since last new_undef_sym() */ |
| 926 | int new_undef_sym; | 934 | int new_undef_sym; |
| 927 | 935 | ||
| @@ -1822,6 +1830,12 @@ ST_FUNC void post_sem(TCCSem *p); · 894 unmodified lines | |||
| 1822 | #define symtab_section TCC_STATE_VAR(symtab_section) | 1830 | #define symtab_section TCC_STATE_VAR(symtab_section) |
| 1823 | #define stab_section TCC_STATE_VAR(stab_section) | 1831 | #define stab_section TCC_STATE_VAR(stab_section) |
| 1824 | #define stabstr_section stab_section->link | 1832 | #define stabstr_section stab_section->link |
| 1833 | #define dwarf_info_section TCC_STATE_VAR(dwarf_info_section) | ||
| 1834 | #define dwarf_abbrev_section TCC_STATE_VAR(dwarf_abbrev_section) | ||
| 1835 | #define dwarf_line_section TCC_STATE_VAR(dwarf_line_section) | ||
| 1836 | #define dwarf_aranges_section TCC_STATE_VAR(dwarf_aranges_section) | ||
| 1837 | #define dwarf_str_section TCC_STATE_VAR(dwarf_str_section) | ||
| 1838 | #define dwarf_line_str_section TCC_STATE_VAR(dwarf_line_str_section) | ||
| 1825 | #define gnu_ext TCC_STATE_VAR(gnu_ext) | 1839 | #define gnu_ext TCC_STATE_VAR(gnu_ext) |
| 1826 | #define tcc_error_noabort TCC_SET_STATE(_tcc_error_noabort) | 1840 | #define tcc_error_noabort TCC_SET_STATE(_tcc_error_noabort) |
| 1827 | #define tcc_error TCC_SET_STATE(_tcc_error) | 1841 | #define tcc_error TCC_SET_STATE(_tcc_error) |
| @@ -47,6 +47,8 @@ struct sym_version { · 46 unmodified lines | |||
| 47 | /* section is dynsymtab_section */ | 47 | /* section is dynsymtab_section */ |
| 48 | #define SHF_DYNSYM 0x40000000 | 48 | #define SHF_DYNSYM 0x40000000 |
| 49 | 49 | ||
| 50 | #define DWARF_DEBUG(s) (!strncmp((s), ".debug_", sizeof(".debug_")-1)) | ||
| 51 | |||
| 50 | /* ------------------------------------------------------------------------- */ | 52 | /* ------------------------------------------------------------------------- */ |
| 51 | 53 | ||
| 52 | ST_FUNC void tccelf_new(TCCState *s) | 54 | ST_FUNC void tccelf_new(TCCState *s) |
| @@ -102,12 +104,39 @@ ST_FUNC void tccelf_stab_new(TCCState *s) · 49 unmodified lines | |||
| 102 | if (s->do_backtrace && s->output_type != TCC_OUTPUT_MEMORY) | 104 | if (s->do_backtrace && s->output_type != TCC_OUTPUT_MEMORY) |
| 103 | shf = SHF_ALLOC | SHF_WRITE; // SHF_WRITE needed for musl/SELINUX | 105 | shf = SHF_ALLOC | SHF_WRITE; // SHF_WRITE needed for musl/SELINUX |
| 104 | #endif | 106 | #endif |
| 105 | stab_section = new_section(s, ".stab", SHT_PROGBITS, shf); | 107 | if (s->dwarf) { |
| 106 | stab_section->sh_entsize = sizeof(Stab_Sym); | 108 | dwarf_info_section = |
| 107 | stab_section->sh_addralign = sizeof ((Stab_Sym*)0)->n_value; | 109 | new_section(s, ".debug_info", SHT_PROGBITS, shf); |
| 108 | stab_section->link = new_section(s, ".stabstr", SHT_STRTAB, shf); | 110 | dwarf_abbrev_section = |
| 109 | /* put first entry */ | 111 | new_section(s, ".debug_abbrev", SHT_PROGBITS, shf); |
| 110 | put_stabs(s, "", 0, 0, 0, 0); | 112 | dwarf_line_section = |
| 113 | new_section(s, ".debug_line", SHT_PROGBITS, shf); | ||
| 114 | dwarf_aranges_section = | ||
| 115 | new_section(s, ".debug_aranges", SHT_PROGBITS, shf); | ||
| 116 | shf |= SHF_MERGE | SHF_STRINGS; | ||
| 117 | dwarf_str_section = | ||
| 118 | new_section(s, ".debug_str", SHT_PROGBITS, shf); | ||
| 119 | dwarf_str_section->sh_entsize = 1; | ||
| 120 | dwarf_info_section->sh_addralign = | ||
| 121 | dwarf_abbrev_section->sh_addralign = | ||
| 122 | dwarf_line_section->sh_addralign = | ||
| 123 | dwarf_aranges_section->sh_addralign = | ||
| 124 | dwarf_str_section->sh_addralign = 1; | ||
| 125 | if (s1->dwarf >= 5) { | ||
| 126 | dwarf_line_str_section = | ||
| 127 | new_section(s, ".debug_line_str", SHT_PROGBITS, shf); | ||
| 128 | dwarf_line_str_section->sh_entsize = 1; | ||
| 129 | dwarf_line_str_section->sh_addralign = 1; | ||
| 130 | } | ||
| 131 | } | ||
| 132 | else { | ||
| 133 | stab_section = new_section(s, ".stab", SHT_PROGBITS, shf); | ||
| 134 | stab_section->sh_entsize = sizeof(Stab_Sym); | ||
| 135 | stab_section->sh_addralign = sizeof ((Stab_Sym*)0)->n_value; | ||
| 136 | stab_section->link = new_section(s, ".stabstr", SHT_STRTAB, shf); | ||
| 137 | /* put first entry */ | ||
| 138 | put_stabs(s, "", 0, 0, 0, 0); | ||
| 139 | } | ||
| 111 | } | 140 | } |
| 112 | 141 | ||
| 113 | static void free_section(Section *s) | 142 | static void free_section(Section *s) |
| @@ -944,7 +973,10 @@ ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve) · 830 unmodified lines | |||
| 944 | sym->st_value = 0; | 973 | sym->st_value = 0; |
| 945 | else | 974 | else |
| 946 | tcc_error_noabort("undefined symbol '%s'", name); | 975 | tcc_error_noabort("undefined symbol '%s'", name); |
| 947 | } else if (sh_num < SHN_LORESERVE) { | 976 | } else if (sh_num < SHN_LORESERVE && |
| 977 | /* Debug dwarf relocations must be relative to start section. | ||
| 978 | This only happens when backtrace is used. */ | ||
| 979 | (sym->st_name || !DWARF_DEBUG(s1->sections[sym->st_shndx]->name))) { | ||
| 948 | /* add section base */ | 980 | /* add section base */ |
| 949 | sym->st_value += s1->sections[sym->st_shndx]->sh_addr; | 981 | sym->st_value += s1->sections[sym->st_shndx]->sh_addr; |
| 950 | } | 982 | } |
| @@ -1330,7 +1362,7 @@ ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t · 379 unmodified lines | |||
| 1330 | if (sec && offs == -1) | 1362 | if (sec && offs == -1) |
| 1331 | offs = sec->data_offset; | 1363 | offs = sec->data_offset; |
| 1332 | return set_elf_sym(symtab_section, offs, 0, | 1364 | return set_elf_sym(symtab_section, offs, 0, |
| 1333 | ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name); | 1365 | ELFW(ST_INFO)(name && !strstr(name, "__dwarf") ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name); |
| 1334 | } | 1366 | } |
| 1335 | 1367 | ||
| 1336 | static void add_init_array_defines(TCCState *s1, const char *section_name) | 1368 | static void add_init_array_defines(TCCState *s1, const char *section_name) |
| @@ -1395,10 +1427,10 @@ static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset · 58 unmodified lines | |||
| 1395 | } | 1427 | } |
| 1396 | 1428 | ||
| 1397 | #ifdef CONFIG_TCC_BACKTRACE | 1429 | #ifdef CONFIG_TCC_BACKTRACE |
| 1398 | static void put_ptr(TCCState *s1, Section *s, int offs) | 1430 | static void put_ptr(TCCState *s1, Section *s, int offs, const char *name) |
| 1399 | { | 1431 | { |
| 1400 | int c; | 1432 | int c; |
| 1401 | c = set_global_sym(s1, NULL, s, offs); | 1433 | c = set_global_sym(s1, name, s, offs); |
| 1402 | s = data_section; | 1434 | s = data_section; |
| 1403 | put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c); | 1435 | put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c); |
| 1404 | section_ptr_add(s, PTR_SIZE); | 1436 | section_ptr_add(s, PTR_SIZE); |
| @@ -1415,16 +1447,29 @@ ST_FUNC void tcc_add_btstub(TCCState *s1) · 10 unmodified lines | |||
| 1415 | section_ptr_add(s, -s->data_offset & (PTR_SIZE - 1)); | 1447 | section_ptr_add(s, -s->data_offset & (PTR_SIZE - 1)); |
| 1416 | o = s->data_offset; | 1448 | o = s->data_offset; |
| 1417 | /* create (part of) a struct rt_context (see tccrun.c) */ | 1449 | /* create (part of) a struct rt_context (see tccrun.c) */ |
| 1418 | put_ptr(s1, stab_section, 0); | 1450 | if (s1->dwarf) { |
| 1419 | put_ptr(s1, stab_section, -1); | 1451 | put_ptr(s1, dwarf_line_section, 0, "__dwarf_line"); |
| 1420 | put_ptr(s1, stab_section->link, 0); | 1452 | put_ptr(s1, dwarf_line_section, -1, "__dwarf_line_end"); |
| 1453 | if (s1->dwarf >= 5) | ||
| 1454 | put_ptr(s1, dwarf_line_str_section, 0, "__dwarf_line_str"); | ||
| 1455 | else | ||
| 1456 | put_ptr(s1, dwarf_str_section, 0, "__dwarf_str"); | ||
| 1457 | put_ptr(s1, text_section, 0, "__dwarf_text"); | ||
| 1458 | } | ||
| 1459 | else { | ||
| 1460 | put_ptr(s1, stab_section, 0, NULL); | ||
| 1461 | put_ptr(s1, stab_section, -1, NULL); | ||
| 1462 | put_ptr(s1, stab_section->link, 0, NULL); | ||
| 1463 | section_ptr_add(s, PTR_SIZE); | ||
| 1464 | } | ||
| 1465 | /* skip esym_start/esym_end/elf_str (not loaded) */ | ||
| 1421 | section_ptr_add(s, 3 * PTR_SIZE); | 1466 | section_ptr_add(s, 3 * PTR_SIZE); |
| 1422 | /* prog_base : local nameless symbol with offset 0 at SHN_ABS */ | 1467 | /* prog_base : local nameless symbol with offset 0 at SHN_ABS */ |
| 1423 | put_ptr(s1, NULL, 0); | 1468 | put_ptr(s1, NULL, 0, NULL); |
| 1424 | n = 2 * PTR_SIZE; | 1469 | n = 2 * PTR_SIZE; |
| 1425 | #ifdef CONFIG_TCC_BCHECK | 1470 | #ifdef CONFIG_TCC_BCHECK |
| 1426 | if (s1->do_bounds_check) { | 1471 | if (s1->do_bounds_check) { |
| 1427 | put_ptr(s1, bounds_section, 0); | 1472 | put_ptr(s1, bounds_section, 0, NULL); |
| 1428 | n -= PTR_SIZE; | 1473 | n -= PTR_SIZE; |
| 1429 | } | 1474 | } |
| 1430 | #endif | 1475 | #endif |
| @@ -1849,6 +1894,8 @@ static int set_sec_sizes(TCCState *s1) · 418 unmodified lines | |||
| 1849 | /* when generating a DLL, we include relocations but | 1894 | /* when generating a DLL, we include relocations but |
| 1850 | we may patch them */ | 1895 | we may patch them */ |
| 1851 | if (file_type == TCC_OUTPUT_DLL | 1896 | if (file_type == TCC_OUTPUT_DLL |
| 1897 | /* Do not include dwarf relocatable sections. */ | ||
| 1898 | && !DWARF_DEBUG(s1->sections[s->sh_info]->name) | ||
| 1852 | && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) { | 1899 | && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) { |
| 1853 | int count = prepare_dynamic_rel(s1, s); | 1900 | int count = prepare_dynamic_rel(s1, s); |
| 1854 | if (count) { | 1901 | if (count) { |
| @@ -2963,8 +3010,7 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 1108 unmodified lines | |||
| 2963 | strcmp(strsec + sh->sh_name, ".stabstr") | 3010 | strcmp(strsec + sh->sh_name, ".stabstr") |
| 2964 | ) | 3011 | ) |
| 2965 | continue; | 3012 | continue; |
| 2966 | if (seencompressed | 3013 | if (seencompressed && DWARF_DEBUG(strsec + sh->sh_name)) |
| 2967 | && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1)) | ||
| 2968 | continue; | 3014 | continue; |
| 2969 | 3015 | ||
| 2970 | sh = &shdr[i]; | 3016 | sh = &shdr[i]; |
| @@ -142,52 +142,56 @@ static void init_prec(void); · 141 unmodified lines | |||
| 142 | 142 | ||
| 143 | static const struct { | 143 | static const struct { |
| 144 | int type; | 144 | int type; |
| 145 | int size; | ||
| 146 | int encoding; | ||
| 145 | const char *name; | 147 | const char *name; |
| 146 | } default_debug[] = { | 148 | } default_debug[] = { |
| 147 | { VT_INT, "int:t1=r1;-2147483648;2147483647;" }, | 149 | { VT_INT, 4, DW_ATE_signed, "int:t1=r1;-2147483648;2147483647;" }, |
| 148 | { VT_BYTE, "char:t2=r2;0;127;" }, | 150 | { VT_BYTE, 1, DW_ATE_signed_char, "char:t2=r2;0;127;" }, |
| 149 | #if LONG_SIZE == 4 | 151 | #if LONG_SIZE == 4 |
| 150 | { VT_LONG | VT_INT, "long int:t3=r3;-2147483648;2147483647;" }, | 152 | { VT_LONG | VT_INT, 4, DW_ATE_signed, "long int:t3=r3;-2147483648;2147483647;" }, |
| 151 | #else | 153 | #else |
| 152 | { VT_LLONG | VT_LONG, "long int:t3=r3;-9223372036854775808;9223372036854775807;" }, | 154 | { VT_LLONG | VT_LONG, 8, DW_ATE_signed, "long int:t3=r3;-9223372036854775808;9223372036854775807;" }, |
| 153 | #endif | 155 | #endif |
| 154 | { VT_INT | VT_UNSIGNED, "unsigned int:t4=r4;0;037777777777;" }, | 156 | { VT_INT | VT_UNSIGNED, 4, DW_ATE_unsigned, "unsigned int:t4=r4;0;037777777777;" }, |
| 155 | #if LONG_SIZE == 4 | 157 | #if LONG_SIZE == 4 |
| 156 | { VT_LONG | VT_INT | VT_UNSIGNED, "long unsigned int:t5=r5;0;037777777777;" }, | 158 | { VT_LONG | VT_INT | VT_UNSIGNED, 4, DW_ATE_unsigned, "long unsigned int:t5=r5;0;037777777777;" }, |
| 157 | #else | 159 | #else |
| 158 | /* use octal instead of -1 so size_t works (-gstabs+ in gcc) */ | 160 | /* use octal instead of -1 so size_t works (-gstabs+ in gcc) */ |
| 159 | { VT_LLONG | VT_LONG | VT_UNSIGNED, "long unsigned int:t5=r5;0;01777777777777777777777;" }, | 161 | { VT_LLONG | VT_LONG | VT_UNSIGNED, 8, DW_ATE_unsigned, "long unsigned int:t5=r5;0;01777777777777777777777;" }, |
| 160 | #endif | 162 | #endif |
| 161 | { VT_QLONG, "__int128:t6=r6;0;-1;" }, | 163 | { VT_QLONG, 16, DW_ATE_signed, "__int128:t6=r6;0;-1;" }, |
| 162 | { VT_QLONG | VT_UNSIGNED, "__int128 unsigned:t7=r7;0;-1;" }, | 164 | { VT_QLONG | VT_UNSIGNED, 16, DW_ATE_unsigned, "__int128 unsigned:t7=r7;0;-1;" }, |
| 163 | { VT_LLONG, "long long int:t8=r8;-9223372036854775808;9223372036854775807;" }, | 165 | { VT_LLONG, 8, DW_ATE_signed, "long long int:t8=r8;-9223372036854775808;9223372036854775807;" }, |
| 164 | { VT_LLONG | VT_UNSIGNED, "long long unsigned int:t9=r9;0;01777777777777777777777;" }, | 166 | { VT_LLONG | VT_UNSIGNED, 8, DW_ATE_unsigned, "long long unsigned int:t9=r9;0;01777777777777777777777;" }, |
| 165 | { VT_SHORT, "short int:t10=r10;-32768;32767;" }, | 167 | { VT_SHORT, 2, DW_ATE_signed, "short int:t10=r10;-32768;32767;" }, |
| 166 | { VT_SHORT | VT_UNSIGNED, "short unsigned int:t11=r11;0;65535;" }, | 168 | { VT_SHORT | VT_UNSIGNED, 2, DW_ATE_unsigned, "short unsigned int:t11=r11;0;65535;" }, |
| 167 | { VT_BYTE | VT_DEFSIGN, "signed char:t12=r12;-128;127;" }, | 169 | { VT_BYTE | VT_DEFSIGN, 1, DW_ATE_signed_char, "signed char:t12=r12;-128;127;" }, |
| 168 | { VT_BYTE | VT_DEFSIGN | VT_UNSIGNED, "unsigned char:t13=r13;0;255;" }, | 170 | { VT_BYTE | VT_DEFSIGN | VT_UNSIGNED, 1, DW_ATE_unsigned_char, "unsigned char:t13=r13;0;255;" }, |
| 169 | { VT_FLOAT, "float:t14=r1;4;0;" }, | 171 | { VT_FLOAT, 4, DW_ATE_float, "float:t14=r1;4;0;" }, |
| 170 | { VT_DOUBLE, "double:t15=r1;8;0;" }, | 172 | { VT_DOUBLE, 8, DW_ATE_float, "double:t15=r1;8;0;" }, |
| 171 | #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE | 173 | #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE |
| 172 | { VT_DOUBLE | VT_LONG, "long double:t16=r1;8;0;" }, | 174 | { VT_DOUBLE | VT_LONG, 8, DW_ATE_float, "long double:t16=r1;8;0;" }, |
| 173 | #else | 175 | #else |
| 174 | { VT_LDOUBLE, "long double:t16=r1;16;0;" }, | 176 | { VT_LDOUBLE, 16, DW_ATE_float, "long double:t16=r1;16;0;" }, |
| 175 | #endif | 177 | #endif |
| 176 | { -1, "_Float32:t17=r1;4;0;" }, | 178 | { -1, -1, -1, "_Float32:t17=r1;4;0;" }, |
| 177 | { -1, "_Float64:t18=r1;8;0;" }, | 179 | { -1, -1, -1, "_Float64:t18=r1;8;0;" }, |
| 178 | { -1, "_Float128:t19=r1;16;0;" }, | 180 | { -1, -1, -1, "_Float128:t19=r1;16;0;" }, |
| 179 | { -1, "_Float32x:t20=r1;8;0;" }, | 181 | { -1, -1, -1, "_Float32x:t20=r1;8;0;" }, |
| 180 | { -1, "_Float64x:t21=r1;16;0;" }, | 182 | { -1, -1, -1, "_Float64x:t21=r1;16;0;" }, |
| 181 | { -1, "_Decimal32:t22=r1;4;0;" }, | 183 | { -1, -1, -1, "_Decimal32:t22=r1;4;0;" }, |
| 182 | { -1, "_Decimal64:t23=r1;8;0;" }, | 184 | { -1, -1, -1, "_Decimal64:t23=r1;8;0;" }, |
| 183 | { -1, "_Decimal128:t24=r1;16;0;" }, | 185 | { -1, -1, -1, "_Decimal128:t24=r1;16;0;" }, |
| 184 | /* if default char is unsigned */ | 186 | /* if default char is unsigned */ |
| 185 | { VT_BYTE | VT_UNSIGNED, "unsigned char:t25=r25;0;255;" }, | 187 | { VT_BYTE | VT_UNSIGNED, 1, DW_ATE_unsigned_char, "unsigned char:t25=r25;0;255;" }, |
| 186 | /* boolean type */ | 188 | /* boolean type */ |
| 187 | { VT_BOOL, "bool:t26=r26;0;255;" }, | 189 | { VT_BOOL, 1, DW_ATE_unsigned_char, "bool:t26=r26;0;255;" }, |
| 188 | { VT_VOID, "void:t27=27" }, | 190 | { VT_VOID, 1, DW_ATE_void, "void:t27=27" }, |
| 189 | }; | 191 | }; |
| 190 | 192 | ||
| 193 | #define N_DEFAULT_DEBUG (sizeof (default_debug) / sizeof (default_debug[0])) | ||
| 194 | |||
| 191 | static int debug_next_type; | 195 | static int debug_next_type; |
| 192 | 196 | ||
| 193 | static struct debug_hash { | 197 | static struct debug_hash { |
| @@ -207,10 +211,231 @@ static struct debug_info { · 13 unmodified lines | |||
| 207 | char *str; | 211 | char *str; |
| 208 | Section *sec; | 212 | Section *sec; |
| 209 | int sym_index; | 213 | int sym_index; |
| 214 | int info; | ||
| 215 | int file; | ||
| 216 | int line; | ||
| 210 | } *sym; | 217 | } *sym; |
| 211 | struct debug_info *child, *next, *last, *parent; | 218 | struct debug_info *child, *next, *last, *parent; |
| 212 | } *debug_info, *debug_info_root; | 219 | } *debug_info, *debug_info_root; |
| 213 | 220 | ||
| 221 | /* dwarf debug */ | ||
| 222 | |||
| 223 | #define DWARF_LINE_BASE -5 | ||
| 224 | #define DWARF_LINE_RANGE 14 | ||
| 225 | #define DWARF_OPCODE_BASE 13 | ||
| 226 | |||
| 227 | #if defined TCC_TARGET_ARM64 | ||
| 228 | #define DWARF_MIN_INSTR_LEN 4 | ||
| 229 | #elif defined TCC_TARGET_ARM | ||
| 230 | #define DWARF_MIN_INSTR_LEN 2 | ||
| 231 | #else | ||
| 232 | #define DWARF_MIN_INSTR_LEN 1 | ||
| 233 | #endif | ||
| 234 | |||
| 235 | #define DWARF_ABBREV_COMPILE_UNIT 1 | ||
| 236 | #define DWARF_ABBREV_BASE_TYPE 2 | ||
| 237 | #define DWARF_ABBREV_VARIABLE_EXTERNAL 3 | ||
| 238 | #define DWARF_ABBREV_VARIABLE_STATIC 4 | ||
| 239 | #define DWARF_ABBREV_VARIABLE_LOCAL 5 | ||
| 240 | #define DWARF_ABBREV_FORMAL_PARAMETER 6 | ||
| 241 | #define DWARF_ABBREV_POINTER 7 | ||
| 242 | #define DWARF_ABBREV_ARRAY_TYPE 8 | ||
| 243 | #define DWARF_ABBREV_SUBRANGE_TYPE 9 | ||
| 244 | #define DWARF_ABBREV_TYPEDEF 10 | ||
| 245 | #define DWARF_ABBREV_ENUMERATOR 11 | ||
| 246 | #define DWARF_ABBREV_ENUMERATION_TYPE 12 | ||
| 247 | #define DWARF_ABBREV_MEMBER 13 | ||
| 248 | #define DWARF_ABBREV_MEMBER_BF 14 | ||
| 249 | #define DWARF_ABBREV_STRUCTURE_TYPE 15 | ||
| 250 | #define DWARF_ABBREV_UNION_TYPE 16 | ||
| 251 | #define DWARF_ABBREV_SUBPROGRAM_EXTERNAL 17 | ||
| 252 | #define DWARF_ABBREV_SUBPROGRAM_STATIC 18 | ||
| 253 | #define DWARF_ABBREV_LEXICAL_BLOCK 19 | ||
| 254 | |||
| 255 | static const unsigned char dwarf_abbrev_init[] = { | ||
| 256 | DWARF_ABBREV_COMPILE_UNIT, DW_TAG_compile_unit, 1, | ||
| 257 | DW_AT_producer, DW_FORM_strp, | ||
| 258 | DW_AT_language, DW_FORM_data1, | ||
| 259 | DW_AT_name, DW_FORM_line_strp, | ||
| 260 | DW_AT_comp_dir, DW_FORM_line_strp, | ||
| 261 | DW_AT_low_pc, DW_FORM_addr, | ||
| 262 | #if PTR_SIZE == 4 | ||
| 263 | DW_AT_high_pc, DW_FORM_data4, | ||
| 264 | #else | ||
| 265 | DW_AT_high_pc, DW_FORM_data8, | ||
| 266 | #endif | ||
| 267 | DW_AT_stmt_list, DW_FORM_data4, | ||
| 268 | 0, 0, | ||
| 269 | DWARF_ABBREV_BASE_TYPE, DW_TAG_base_type, 0, | ||
| 270 | DW_AT_byte_size, DW_FORM_udata, | ||
| 271 | DW_AT_encoding, DW_FORM_data1, | ||
| 272 | DW_AT_name, DW_FORM_strp, | ||
| 273 | 0, 0, | ||
| 274 | DWARF_ABBREV_VARIABLE_EXTERNAL, DW_TAG_variable, 0, | ||
| 275 | DW_AT_name, DW_FORM_strp, | ||
| 276 | DW_AT_decl_file, DW_FORM_udata, | ||
| 277 | DW_AT_decl_line, DW_FORM_udata, | ||
| 278 | DW_AT_type, DW_FORM_ref4, | ||
| 279 | DW_AT_external, DW_FORM_flag, | ||
| 280 | DW_AT_location, DW_FORM_block1, | ||
| 281 | 0, 0, | ||
| 282 | DWARF_ABBREV_VARIABLE_STATIC, DW_TAG_variable, 0, | ||
| 283 | DW_AT_name, DW_FORM_strp, | ||
| 284 | DW_AT_decl_file, DW_FORM_udata, | ||
| 285 | DW_AT_decl_line, DW_FORM_udata, | ||
| 286 | DW_AT_type, DW_FORM_ref4, | ||
| 287 | DW_AT_location, DW_FORM_block1, | ||
| 288 | 0, 0, | ||
| 289 | DWARF_ABBREV_VARIABLE_LOCAL, DW_TAG_variable, 0, | ||
| 290 | DW_AT_name, DW_FORM_strp, | ||
| 291 | DW_AT_type, DW_FORM_ref4, | ||
| 292 | DW_AT_location, DW_FORM_block1, | ||
| 293 | 0, 0, | ||
| 294 | DWARF_ABBREV_FORMAL_PARAMETER, DW_TAG_formal_parameter, 0, | ||
| 295 | DW_AT_name, DW_FORM_strp, | ||
| 296 | DW_AT_type, DW_FORM_ref4, | ||
| 297 | DW_AT_location, DW_FORM_block1, | ||
| 298 | 0, 0, | ||
| 299 | DWARF_ABBREV_POINTER, DW_TAG_pointer_type, 0, | ||
| 300 | DW_AT_byte_size, DW_FORM_data1, | ||
| 301 | DW_AT_byte_size, DW_FORM_implicit_const, 8, | ||
| 302 | DW_AT_type, DW_FORM_ref4, | ||
| 303 | 0, 0, | ||
| 304 | DWARF_ABBREV_ARRAY_TYPE, DW_TAG_array_type, 1, | ||
| 305 | DW_AT_type, DW_FORM_ref4, | ||
| 306 | DW_AT_sibling, DW_FORM_ref4, | ||
| 307 | 0, 0, | ||
| 308 | DWARF_ABBREV_SUBRANGE_TYPE, DW_TAG_subrange_type, 0, | ||
| 309 | DW_AT_type, DW_FORM_ref4, | ||
| 310 | DW_AT_upper_bound, DW_FORM_udata, | ||
| 311 | 0, 0, | ||
| 312 | DWARF_ABBREV_TYPEDEF, DW_TAG_typedef, 0, | ||
| 313 | DW_AT_name, DW_FORM_strp, | ||
| 314 | DW_AT_decl_file, DW_FORM_udata, | ||
| 315 | DW_AT_decl_line, DW_FORM_udata, | ||
| 316 | DW_AT_type, DW_FORM_ref4, | ||
| 317 | 0, 0, | ||
| 318 | DWARF_ABBREV_ENUMERATOR, DW_TAG_enumerator, 0, | ||
| 319 | DW_AT_name, DW_FORM_strp, | ||
| 320 | DW_AT_const_value, DW_FORM_data4, | ||
| 321 | 0, 0, | ||
| 322 | DWARF_ABBREV_ENUMERATION_TYPE, DW_TAG_enumeration_type, 1, | ||
| 323 | DW_AT_name, DW_FORM_strp, | ||
| 324 | DW_AT_encoding, DW_FORM_data1, | ||
| 325 | DW_AT_byte_size, DW_FORM_data1, | ||
| 326 | DW_AT_type, DW_FORM_ref4, | ||
| 327 | DW_AT_decl_file, DW_FORM_udata, | ||
| 328 | DW_AT_decl_line, DW_FORM_udata, | ||
| 329 | DW_AT_sibling, DW_FORM_ref4, | ||
| 330 | 0, 0, | ||
| 331 | DWARF_ABBREV_MEMBER, DW_TAG_member, 0, | ||
| 332 | DW_AT_name, DW_FORM_strp, | ||
| 333 | DW_AT_decl_file, DW_FORM_udata, | ||
| 334 | DW_AT_decl_line, DW_FORM_udata, | ||
| 335 | DW_AT_type, DW_FORM_ref4, | ||
| 336 | DW_AT_data_member_location, DW_FORM_udata, | ||
| 337 | 0, 0, | ||
| 338 | DWARF_ABBREV_MEMBER_BF, DW_TAG_member, 0, | ||
| 339 | DW_AT_name, DW_FORM_strp, | ||
| 340 | DW_AT_decl_file, DW_FORM_udata, | ||
| 341 | DW_AT_decl_line, DW_FORM_udata, | ||
| 342 | DW_AT_type, DW_FORM_ref4, | ||
| 343 | DW_AT_bit_size, DW_FORM_udata, | ||
| 344 | DW_AT_data_bit_offset, DW_FORM_udata, | ||
| 345 | 0, 0, | ||
| 346 | DWARF_ABBREV_STRUCTURE_TYPE, DW_TAG_structure_type, 1, | ||
| 347 | DW_AT_name, DW_FORM_strp, | ||
| 348 | DW_AT_byte_size, DW_FORM_udata, | ||
| 349 | DW_AT_decl_file, DW_FORM_udata, | ||
| 350 | DW_AT_decl_line, DW_FORM_udata, | ||
| 351 | DW_AT_sibling, DW_FORM_ref4, | ||
| 352 | 0, 0, | ||
| 353 | DWARF_ABBREV_UNION_TYPE, DW_TAG_union_type, 1, | ||
| 354 | DW_AT_name, DW_FORM_strp, | ||
| 355 | DW_AT_byte_size, DW_FORM_udata, | ||
| 356 | DW_AT_decl_file, DW_FORM_udata, | ||
| 357 | DW_AT_decl_line, DW_FORM_udata, | ||
| 358 | DW_AT_sibling, DW_FORM_ref4, | ||
| 359 | 0, 0, | ||
| 360 | DWARF_ABBREV_SUBPROGRAM_EXTERNAL, DW_TAG_subprogram, 1, | ||
| 361 | DW_AT_external, DW_FORM_flag, | ||
| 362 | DW_AT_name, DW_FORM_strp, | ||
| 363 | DW_AT_decl_file, DW_FORM_udata, | ||
| 364 | DW_AT_decl_line, DW_FORM_udata, | ||
| 365 | DW_AT_type, DW_FORM_ref4, | ||
| 366 | DW_AT_low_pc, DW_FORM_addr, | ||
| 367 | #if PTR_SIZE == 4 | ||
| 368 | DW_AT_high_pc, DW_FORM_data4, | ||
| 369 | #else | ||
| 370 | DW_AT_high_pc, DW_FORM_data8, | ||
| 371 | #endif | ||
| 372 | DW_AT_sibling, DW_FORM_ref4, | ||
| 373 | DW_AT_frame_base, DW_FORM_block1, | ||
| 374 | 0, 0, | ||
| 375 | DWARF_ABBREV_SUBPROGRAM_STATIC, DW_TAG_subprogram, 1, | ||
| 376 | DW_AT_name, DW_FORM_strp, | ||
| 377 | DW_AT_decl_file, DW_FORM_udata, | ||
| 378 | DW_AT_decl_line, DW_FORM_udata, | ||
| 379 | DW_AT_type, DW_FORM_ref4, | ||
| 380 | DW_AT_low_pc, DW_FORM_addr, | ||
| 381 | #if PTR_SIZE == 4 | ||
| 382 | DW_AT_high_pc, DW_FORM_data4, | ||
| 383 | #else | ||
| 384 | DW_AT_high_pc, DW_FORM_data8, | ||
| 385 | #endif | ||
| 386 | DW_AT_sibling, DW_FORM_ref4, | ||
| 387 | DW_AT_frame_base, DW_FORM_block1, | ||
| 388 | 0, 0, | ||
| 389 | DWARF_ABBREV_LEXICAL_BLOCK, DW_TAG_lexical_block, 1, | ||
| 390 | DW_AT_low_pc, DW_FORM_addr, | ||
| 391 | #if PTR_SIZE == 4 | ||
| 392 | DW_AT_high_pc, DW_FORM_data4, | ||
| 393 | #else | ||
| 394 | DW_AT_high_pc, DW_FORM_data8, | ||
| 395 | #endif | ||
| 396 | 0, 0, | ||
| 397 | 0 | ||
| 398 | }; | ||
| 399 | |||
| 400 | static const unsigned char dwarf_line_opcodes[] = { | ||
| 401 | 0 ,1 ,1 ,1 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,1 | ||
| 402 | }; | ||
| 403 | |||
| 404 | static struct { | ||
| 405 | int info; | ||
| 406 | int abbrev; | ||
| 407 | int line; | ||
| 408 | int str; | ||
| 409 | int line_str; | ||
| 410 | } dwarf_sym; | ||
| 411 | |||
| 412 | static struct { | ||
| 413 | int start; | ||
| 414 | int dir_size; | ||
| 415 | char **dir_table; | ||
| 416 | int filename_size; | ||
| 417 | struct dwarf_filename_struct { | ||
| 418 | int dir_entry; | ||
| 419 | char *name; | ||
| 420 | } *filename_table; | ||
| 421 | int line_size; | ||
| 422 | int line_max_size; | ||
| 423 | unsigned char *line_data; | ||
| 424 | int cur_file; | ||
| 425 | int last_file; | ||
| 426 | int last_pc; | ||
| 427 | int last_line; | ||
| 428 | } dwarf_line; | ||
| 429 | |||
| 430 | static struct { | ||
| 431 | int start; | ||
| 432 | Sym *func; | ||
| 433 | int line; | ||
| 434 | int base_type_used[N_DEFAULT_DEBUG]; | ||
| 435 | } dwarf_info; | ||
| 436 | |||
| 437 | /* test coverage */ | ||
| 438 | |||
| 214 | static struct { | 439 | static struct { |
| 215 | unsigned long offset; | 440 | unsigned long offset; |
| 216 | unsigned long last_file_name; | 441 | unsigned long last_file_name; |
| @@ -404,36 +629,323 @@ void pv (const char *lbl, int a, int b) · 187 unmodified lines | |||
| 404 | #endif | 629 | #endif |
| 405 | 630 | ||
| 406 | /* ------------------------------------------------------------------------- */ | 631 | /* ------------------------------------------------------------------------- */ |
| 632 | |||
| 633 | #define dwarf_data1(s,data) \ | ||
| 634 | { unsigned char *p = section_ptr_add((s), 1); *p = (data); } | ||
| 635 | #define dwarf_data2(s,data) \ | ||
| 636 | write16le(section_ptr_add((s), 2), (data)) | ||
| 637 | #define dwarf_data4(s,data) \ | ||
| 638 | write32le(section_ptr_add((s), 4), (data)) | ||
| 639 | #define dwarf_data8(s,data) \ | ||
| 640 | write64le(section_ptr_add((s), 8), (data)) | ||
| 641 | |||
| 642 | static int dwarf_get_section_sym(Section *s) | ||
| 643 | { | ||
| 644 | return put_elf_sym(symtab_section, 0, 0, | ||
| 645 | ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0, | ||
| 646 | s->sh_num, NULL); | ||
| 647 | } | ||
| 648 | |||
| 649 | static void dwarf_reloc(Section *s, int sym, int rel) | ||
| 650 | { | ||
| 651 | put_elf_reloca(symtab_section, s, s->data_offset, rel, sym, 0); | ||
| 652 | } | ||
| 653 | |||
| 654 | static void dwarf_string(Section *s, Section *dw, int sym, const char *str) | ||
| 655 | { | ||
| 656 | int offset, len; | ||
| 657 | char *ptr; | ||
| 658 | |||
| 659 | len = strlen(str) + 1; | ||
| 660 | offset = dw->data_offset; | ||
| 661 | ptr = section_ptr_add(dw, len); | ||
| 662 | memmove(ptr, str, len); | ||
| 663 | put_elf_reloca(symtab_section, s, s->data_offset, R_DATA_32U, sym, | ||
| 664 | PTR_SIZE == 4 ? 0 : offset); | ||
| 665 | dwarf_data4(s, PTR_SIZE == 4 ? offset : 0); | ||
| 666 | } | ||
| 667 | |||
| 668 | static void dwarf_strp(Section *s, const char *str) | ||
| 669 | { | ||
| 670 | dwarf_string(s, dwarf_str_section, dwarf_sym.str, str); | ||
| 671 | } | ||
| 672 | |||
| 673 | static void dwarf_line_strp(Section *s, const char *str) | ||
| 674 | { | ||
| 675 | dwarf_string(s, dwarf_line_str_section, dwarf_sym.line_str, str); | ||
| 676 | } | ||
| 677 | |||
| 678 | static void dwarf_line_op(unsigned char op) | ||
| 679 | { | ||
| 680 | if (dwarf_line.line_size >= dwarf_line.line_max_size) { | ||
| 681 | dwarf_line.line_max_size += 1024; | ||
| 682 | dwarf_line.line_data = | ||
| 683 | (unsigned char *)tcc_realloc(dwarf_line.line_data, | ||
| 684 | dwarf_line.line_max_size); | ||
| 685 | } | ||
| 686 | dwarf_line.line_data[dwarf_line.line_size++] = op; | ||
| 687 | } | ||
| 688 | |||
| 689 | static void dwarf_file(TCCState *s1) | ||
| 690 | { | ||
| 691 | int i; | ||
| 692 | char *filename; | ||
| 693 | |||
| 694 | if (!s1->do_debug || !s1->dwarf) | ||
| 695 | return; | ||
| 696 | filename = strrchr(file->filename, '/'); | ||
| 697 | if (filename == NULL) { | ||
| 698 | for (i = 1; i < dwarf_line.filename_size; i++) | ||
| 699 | if (dwarf_line.filename_table[i].dir_entry == 0 && | ||
| 700 | strcmp(dwarf_line.filename_table[i].name, | ||
| 701 | file->filename) == 0) { | ||
| 702 | dwarf_line.cur_file = i; | ||
| 703 | return; | ||
| 704 | } | ||
| 705 | } | ||
| 706 | else { | ||
| 707 | int j; | ||
| 708 | char *undo = filename; | ||
| 709 | |||
| 710 | *filename++ = '\0'; | ||
| 711 | for (i = 0; i < dwarf_line.dir_size; i++) | ||
| 712 | if (strcmp(dwarf_line.dir_table[i], file->filename) == 0) | ||
| 713 | for (j = 1; j < dwarf_line.filename_size; j++) | ||
| 714 | if (dwarf_line.filename_table[i].dir_entry == i && | ||
| 715 | strcmp(dwarf_line.filename_table[j].name, | ||
| 716 | filename) == 0) { | ||
| 717 | *undo = '/'; | ||
| 718 | dwarf_line.cur_file = j; | ||
| 719 | return; | ||
| 720 | } | ||
| 721 | *undo = '/'; | ||
| 722 | } | ||
| 723 | return; | ||
| 724 | } | ||
| 725 | |||
| 726 | #if 0 | ||
| 727 | static int dwarf_uleb128_size (unsigned long long value) | ||
| 728 | { | ||
| 729 | int size = 0; | ||
| 730 | |||
| 731 | do { | ||
| 732 | value >>= 7; | ||
| 733 | size++; | ||
| 734 | } while (value != 0); | ||
| 735 | return size; | ||
| 736 | } | ||
| 737 | #endif | ||
| 738 | |||
| 739 | static int dwarf_sleb128_size (long long value) | ||
| 740 | { | ||
| 741 | int more; | ||
| 742 | int size = 0; | ||
| 743 | |||
| 744 | do { | ||
| 745 | unsigned char byte = value & 0x7f; | ||
| 746 | |||
| 747 | value = (value >> 7) | ~(-1 >> 7); | ||
| 748 | more =!((((value == 0) && ((byte & 0x40) == 0)) | ||
| 749 | || ((value == -1) && ((byte & 0x40) != 0)))); | ||
| 750 | size++; | ||
| 751 | } while (more); | ||
| 752 | return size; | ||
| 753 | } | ||
| 754 | |||
| 755 | static void dwarf_uleb128 (Section *s, unsigned long long value) | ||
| 756 | { | ||
| 757 | do { | ||
| 758 | unsigned char byte = value & 0x7f; | ||
| 759 | |||
| 760 | value >>= 7; | ||
| 761 | if (value) | ||
| 762 | byte |= 0x80; | ||
| 763 | dwarf_data1(s, byte); | ||
| 764 | } while (value != 0); | ||
| 765 | } | ||
| 766 | |||
| 767 | static void dwarf_sleb128 (Section *s, long long value) | ||
| 768 | { | ||
| 769 | int more; | ||
| 770 | |||
| 771 | do { | ||
| 772 | unsigned char byte = value & 0x7f; | ||
| 773 | |||
| 774 | value = (value >> 7) | ~(-1 >> 7); | ||
| 775 | more =!((((value == 0) && ((byte & 0x40) == 0)) | ||
| 776 | || ((value == -1) && ((byte & 0x40) != 0)))); | ||
| 777 | if (more) | ||
| 778 | byte |= 0x80; | ||
| 779 | dwarf_data1(s, byte); | ||
| 780 | } while (more); | ||
| 781 | } | ||
| 782 | |||
| 783 | static void dwarf_uleb128_op (unsigned long long value) | ||
| 784 | { | ||
| 785 | do { | ||
| 786 | unsigned char byte = value & 0x7f; | ||
| 787 | |||
| 788 | value >>= 7; | ||
| 789 | if (value) | ||
| 790 | byte |= 0x80; | ||
| 791 | dwarf_line_op(byte); | ||
| 792 | } while (value != 0); | ||
| 793 | } | ||
| 794 | |||
| 795 | static void dwarf_sleb128_op (long long value) | ||
| 796 | { | ||
| 797 | int more; | ||
| 798 | |||
| 799 | do { | ||
| 800 | unsigned char byte = value & 0x7f; | ||
| 801 | |||
| 802 | value = (value >> 7) | ~(-1 >> 7); | ||
| 803 | more =!((((value == 0) && ((byte & 0x40) == 0)) | ||
| 804 | || ((value == -1) && ((byte & 0x40) != 0)))); | ||
| 805 | if (more) | ||
| 806 | byte |= 0x80; | ||
| 807 | dwarf_line_op(byte); | ||
| 808 | } while (more); | ||
| 809 | } | ||
| 810 | |||
| 407 | /* start of translation unit info */ | 811 | /* start of translation unit info */ |
| 408 | ST_FUNC void tcc_debug_start(TCCState *s1) | 812 | ST_FUNC void tcc_debug_start(TCCState *s1) |
| 409 | { | 813 | { |
| 410 | if (s1->do_debug) { | 814 | if (s1->do_debug) { |
| 411 | int i; | 815 | int i; |
| 816 | char *filename = file->prev ? file->prev->filename : file->filename; | ||
| 412 | char buf[512]; | 817 | char buf[512]; |
| 413 | 818 | ||
| 414 | /* file info: full path + filename */ | ||
| 415 | section_sym = put_elf_sym(symtab_section, 0, 0, | ||
| 416 | ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0, | ||
| 417 | text_section->sh_num, NULL); | ||
| 418 | getcwd(buf, sizeof(buf)); | 819 | getcwd(buf, sizeof(buf)); |
| 419 | #ifdef _WIN32 | 820 | #ifdef _WIN32 |
| 420 | normalize_slashes(buf); | 821 | normalize_slashes(buf); |
| 421 | #endif | 822 | #endif |
| 422 | pstrcat(buf, sizeof(buf), "/"); | 823 | pstrcat(buf, sizeof(buf), "/"); |
| 423 | put_stabs_r(s1, buf, N_SO, 0, 0, | ||
| 424 | text_section->data_offset, text_section, section_sym); | ||
| 425 | put_stabs_r(s1, file->prev ? file->prev->filename : file->filename, | ||
| 426 | N_SO, 0, 0, | ||
| 427 | text_section->data_offset, text_section, section_sym); | ||
| 428 | for (i = 0; i < sizeof (default_debug) / sizeof (default_debug[0]); i++) | ||
| 429 | put_stabs(s1, default_debug[i].name, N_LSYM, 0, 0, 0); | ||
| 430 | 824 | ||
| 825 | if (s1->dwarf) { | ||
| 826 | int start_abbrev; | ||
| 827 | unsigned char *ptr; | ||
| 828 | |||
| 829 | /* dwarf_abbrev */ | ||
| 830 | start_abbrev = dwarf_abbrev_section->data_offset; | ||
| 831 | ptr = section_ptr_add(dwarf_abbrev_section, sizeof(dwarf_abbrev_init)); | ||
| 832 | memcpy(ptr, dwarf_abbrev_init, sizeof(dwarf_abbrev_init)); | ||
| 833 | |||
| 834 | if (s1->dwarf < 5) { | ||
| 835 | while (*ptr) { | ||
| 836 | ptr += 3; | ||
| 837 | while (*ptr) { | ||
| 838 | if (ptr[1] == DW_FORM_line_strp) | ||
| 839 | ptr[1] = DW_FORM_strp; | ||
| 840 | ptr += 2; | ||
| 841 | } | ||
| 842 | } | ||
| 843 | } | ||
| 844 | |||
| 845 | dwarf_sym.info = dwarf_get_section_sym(dwarf_info_section); | ||
| 846 | dwarf_sym.abbrev = dwarf_get_section_sym(dwarf_abbrev_section); | ||
| 847 | dwarf_sym.line = dwarf_get_section_sym(dwarf_line_section); | ||
| 848 | dwarf_sym.str = dwarf_get_section_sym(dwarf_str_section); | ||
| 849 | if (tcc_state->dwarf >= 5) | ||
| 850 | dwarf_sym.line_str = dwarf_get_section_sym(dwarf_line_str_section); | ||
| 851 | else { | ||
| 852 | dwarf_line_str_section = dwarf_str_section; | ||
| 853 | dwarf_sym.line_str = dwarf_sym.str; | ||
| 854 | } | ||
| 855 | section_sym = dwarf_get_section_sym(text_section); | ||
| 856 | |||
| 857 | /* dwarf_info */ | ||
| 858 | dwarf_info.start = dwarf_info_section->data_offset; | ||
| 859 | dwarf_data4(dwarf_info_section, 0); // size | ||
| 860 | dwarf_data2(dwarf_info_section, s1->dwarf); // version | ||
| 861 | if (s1->dwarf >= 5) { | ||
| 862 | dwarf_data1(dwarf_info_section, DW_UT_compile); // unit type | ||
| 863 | dwarf_data1(dwarf_info_section, PTR_SIZE); | ||
| 864 | dwarf_reloc(dwarf_info_section, dwarf_sym.abbrev, R_DATA_32U); | ||
| 865 | dwarf_data4(dwarf_info_section, start_abbrev); | ||
| 866 | } | ||
| 867 | else { | ||
| 868 | dwarf_reloc(dwarf_info_section, dwarf_sym.abbrev, R_DATA_32U); | ||
| 869 | dwarf_data4(dwarf_info_section, start_abbrev); | ||
| 870 | dwarf_data1(dwarf_info_section, PTR_SIZE); | ||
| 871 | } | ||
| 872 | |||
| 873 | dwarf_data1(dwarf_info_section, DWARF_ABBREV_COMPILE_UNIT); | ||
| 874 | dwarf_strp(dwarf_info_section, "tcc " TCC_VERSION); | ||
| 875 | dwarf_data1(dwarf_info_section, DW_LANG_C11); | ||
| 876 | dwarf_line_strp(dwarf_info_section, filename); | ||
| 877 | dwarf_line_strp(dwarf_info_section, buf); | ||
| 878 | dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR); | ||
| 879 | #if PTR_SIZE == 4 | ||
| 880 | dwarf_data4(dwarf_info_section, ind); // low pc | ||
| 881 | dwarf_data4(dwarf_info_section, 0); // high pc | ||
| 882 | #else | ||
| 883 | dwarf_data8(dwarf_info_section, ind); // low pc | ||
| 884 | dwarf_data8(dwarf_info_section, 0); // high pc | ||
| 885 | #endif | ||
| 886 | dwarf_reloc(dwarf_info_section, dwarf_sym.line, R_DATA_32U); | ||
| 887 | dwarf_data4(dwarf_info_section, dwarf_line_section->data_offset); // stmt_list | ||
| 888 | |||
| 889 | /* dwarf_line */ | ||
| 890 | dwarf_line.start = dwarf_line_section->data_offset; | ||
| 891 | dwarf_data4(dwarf_line_section, 0); // length | ||
| 892 | dwarf_data2(dwarf_line_section, s1->dwarf); // version | ||
| 893 | if (s1->dwarf >= 5) { | ||
| 894 | dwarf_data1(dwarf_line_section, PTR_SIZE); // address size | ||
| 895 | dwarf_data1(dwarf_line_section, 0); // segment selector | ||
| 896 | } | ||
| 897 | dwarf_data4(dwarf_line_section, 0); // prologue Length | ||
| 898 | dwarf_data1(dwarf_line_section, DWARF_MIN_INSTR_LEN); | ||
| 899 | if (s1->dwarf >= 4) | ||
| 900 | dwarf_data1(dwarf_line_section, 1); // maximum ops per instruction | ||
| 901 | dwarf_data1(dwarf_line_section, 1); // Initial value of 'is_stmt' | ||
| 902 | dwarf_data1(dwarf_line_section, DWARF_LINE_BASE); | ||
| 903 | dwarf_data1(dwarf_line_section, DWARF_LINE_RANGE); | ||
| 904 | dwarf_data1(dwarf_line_section, DWARF_OPCODE_BASE); | ||
| 905 | ptr = section_ptr_add(dwarf_line_section, sizeof(dwarf_line_opcodes)); | ||
| 906 | memcpy(ptr, dwarf_line_opcodes, sizeof(dwarf_line_opcodes)); | ||
| 907 | dwarf_line.dir_size = 1; | ||
| 908 | dwarf_line.dir_table = (char **) tcc_malloc(sizeof (char *)); | ||
| 909 | dwarf_line.dir_table[0] = tcc_strdup(buf); | ||
| 910 | /* line state machine starts with file 1 instead of 0 */ | ||
| 911 | dwarf_line.filename_size = 2; | ||
| 912 | dwarf_line.filename_table = | ||
| 913 | (struct dwarf_filename_struct *) | ||
| 914 | tcc_malloc(2*sizeof (struct dwarf_filename_struct)); | ||
| 915 | dwarf_line.filename_table[0].dir_entry = 0; | ||
| 916 | dwarf_line.filename_table[0].name = tcc_strdup(filename); | ||
| 917 | dwarf_line.filename_table[1].dir_entry = 0; | ||
| 918 | dwarf_line.filename_table[1].name = tcc_strdup(filename); | ||
| 919 | dwarf_line.line_size = dwarf_line.line_max_size = 0; | ||
| 920 | dwarf_line.line_data = NULL; | ||
| 921 | dwarf_line.cur_file = 1; | ||
| 922 | dwarf_line.last_file = 0; | ||
| 923 | dwarf_line.last_pc = 0; | ||
| 924 | dwarf_line.last_line = 1; | ||
| 925 | dwarf_line_op(0); // extended | ||
| 926 | dwarf_uleb128_op(1 + PTR_SIZE); // extended size | ||
| 927 | dwarf_line_op(DW_LNE_set_address); | ||
| 928 | for (i = 0; i < PTR_SIZE; i++) | ||
| 929 | dwarf_line_op(0); | ||
| 930 | memset(&dwarf_info.base_type_used, 0, sizeof(dwarf_info.base_type_used)); | ||
| 931 | } | ||
| 932 | else { | ||
| 933 | /* file info: full path + filename */ | ||
| 934 | section_sym = put_elf_sym(symtab_section, 0, 0, | ||
| 935 | ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0, | ||
| 936 | text_section->sh_num, NULL); | ||
| 937 | put_stabs_r(s1, buf, N_SO, 0, 0, | ||
| 938 | text_section->data_offset, text_section, section_sym); | ||
| 939 | put_stabs_r(s1, filename, N_SO, 0, 0, | ||
| 940 | text_section->data_offset, text_section, section_sym); | ||
| 941 | for (i = 0; i < N_DEFAULT_DEBUG; i++) | ||
| 942 | put_stabs(s1, default_debug[i].name, N_LSYM, 0, 0, 0); | ||
| 943 | } | ||
| 431 | new_file = last_line_num = 0; | 944 | new_file = last_line_num = 0; |
| 432 | func_ind = -1; | 945 | func_ind = -1; |
| 433 | debug_next_type = sizeof(default_debug) / sizeof(default_debug[0]); | 946 | debug_next_type = N_DEFAULT_DEBUG; |
| 434 | debug_hash = NULL; | 947 | debug_hash = NULL; |
| 435 | n_debug_hash = 0; | 948 | n_debug_hash = 0; |
| 436 | |||
| 437 | /* we're currently 'including' the <command line> */ | 949 | /* we're currently 'including' the <command line> */ |
| 438 | tcc_debug_bincl(s1); | 950 | tcc_debug_bincl(s1); |
| 439 | } | 951 | } |
| @@ -450,8 +962,111 @@ ST_FUNC void tcc_debug_end(TCCState *s1) · 10 unmodified lines | |||
| 450 | { | 962 | { |
| 451 | if (!s1->do_debug) | 963 | if (!s1->do_debug) |
| 452 | return; | 964 | return; |
| 453 | put_stabs_r(s1, NULL, N_SO, 0, 0, | 965 | if (s1->dwarf) { |
| 454 | text_section->data_offset, text_section, section_sym); | 966 | int i; |
| 967 | int start_aranges; | ||
| 968 | unsigned char *ptr; | ||
| 969 | int text_size = text_section->data_offset; | ||
| 970 | |||
| 971 | /* dwarf_info */ | ||
| 972 | dwarf_data1(dwarf_info_section, 0); | ||
| 973 | ptr = dwarf_info_section->data + dwarf_info.start; | ||
| 974 | write32le(ptr, dwarf_info_section->data_offset - dwarf_info.start - 4); | ||
| 975 | write32le(ptr + 25 + (s1->dwarf >= 5) + PTR_SIZE, text_size); | ||
| 976 | |||
| 977 | /* dwarf_aranges */ | ||
| 978 | start_aranges = dwarf_aranges_section->data_offset; | ||
| 979 | dwarf_data4(dwarf_aranges_section, 0); // size | ||
| 980 | dwarf_data2(dwarf_aranges_section, 2); // version | ||
| 981 | dwarf_reloc(dwarf_aranges_section, dwarf_sym.info, R_DATA_32U); | ||
| 982 | dwarf_data4(dwarf_aranges_section, 0); // dwarf_info | ||
| 983 | #if PTR_SIZE == 4 | ||
| 984 | dwarf_data1(dwarf_aranges_section, 4); // address size | ||
| 985 | #else | ||
| 986 | dwarf_data1(dwarf_aranges_section, 8); // address size | ||
| 987 | #endif | ||
| 988 | dwarf_data1(dwarf_aranges_section, 0); // segment selector size | ||
| 989 | dwarf_data4(dwarf_aranges_section, 0); // padding | ||
| 990 | dwarf_reloc(dwarf_aranges_section, section_sym, R_DATA_PTR); | ||
| 991 | #if PTR_SIZE == 4 | ||
| 992 | dwarf_data4(dwarf_aranges_section, 0); // Begin | ||
| 993 | dwarf_data4(dwarf_aranges_section, text_size); // End | ||
| 994 | dwarf_data4(dwarf_aranges_section, 0); // End list | ||
| 995 | dwarf_data4(dwarf_aranges_section, 0); // End list | ||
| 996 | #else | ||
| 997 | dwarf_data8(dwarf_aranges_section, 0); // Begin | ||
| 998 | dwarf_data8(dwarf_aranges_section, text_size); // End | ||
| 999 | dwarf_data8(dwarf_aranges_section, 0); // End list | ||
| 1000 | dwarf_data8(dwarf_aranges_section, 0); // End list | ||
| 1001 | #endif | ||
| 1002 | ptr = dwarf_aranges_section->data + start_aranges; | ||
| 1003 | write32le(ptr, dwarf_aranges_section->data_offset - start_aranges - 4); | ||
| 1004 | |||
| 1005 | /* dwarf_line */ | ||
| 1006 | if (s1->dwarf >= 5) { | ||
| 1007 | dwarf_data1(dwarf_line_section, 1); /* col */ | ||
| 1008 | dwarf_uleb128(dwarf_line_section, DW_LNCT_path); | ||
| 1009 | dwarf_uleb128(dwarf_line_section, DW_FORM_line_strp); | ||
| 1010 | dwarf_uleb128(dwarf_line_section, dwarf_line.dir_size); | ||
| 1011 | for (i = 0; i < dwarf_line.dir_size; i++) | ||
| 1012 | dwarf_line_strp(dwarf_line_section, dwarf_line.dir_table[i]); | ||
| 1013 | dwarf_data1(dwarf_line_section, 2); /* col */ | ||
| 1014 | dwarf_uleb128(dwarf_line_section, DW_LNCT_path); | ||
| 1015 | dwarf_uleb128(dwarf_line_section, DW_FORM_line_strp); | ||
| 1016 | dwarf_uleb128(dwarf_line_section, DW_LNCT_directory_index); | ||
| 1017 | dwarf_uleb128(dwarf_line_section, DW_FORM_udata); | ||
| 1018 | dwarf_uleb128(dwarf_line_section, dwarf_line.filename_size); | ||
| 1019 | for (i = 0; i < dwarf_line.filename_size; i++) { | ||
| 1020 | dwarf_line_strp(dwarf_line_section, | ||
| 1021 | dwarf_line.filename_table[i].name); | ||
| 1022 | dwarf_uleb128(dwarf_line_section, | ||
| 1023 | dwarf_line.filename_table[i].dir_entry); | ||
| 1024 | } | ||
| 1025 | } | ||
| 1026 | else { | ||
| 1027 | int len; | ||
| 1028 | |||
| 1029 | for (i = 0; i < dwarf_line.dir_size; i++) { | ||
| 1030 | len = strlen(dwarf_line.dir_table[i]) + 1; | ||
| 1031 | ptr = section_ptr_add(dwarf_line_section, len); | ||
| 1032 | memmove(ptr, dwarf_line.dir_table[i], len); | ||
| 1033 | } | ||
| 1034 | dwarf_data1(dwarf_line_section, 0); /* end dir */ | ||
| 1035 | for (i = 0; i < dwarf_line.filename_size; i++) { | ||
| 1036 | len = strlen(dwarf_line.filename_table[i].name) + 1; | ||
| 1037 | ptr = section_ptr_add(dwarf_line_section, len); | ||
| 1038 | memmove(ptr, dwarf_line.filename_table[i].name, len); | ||
| 1039 | dwarf_uleb128(dwarf_line_section, | ||
| 1040 | dwarf_line.filename_table[i].dir_entry); | ||
| 1041 | dwarf_uleb128(dwarf_line_section, 0); /* time */ | ||
| 1042 | dwarf_uleb128(dwarf_line_section, 0); /* size */ | ||
| 1043 | } | ||
| 1044 | dwarf_data1(dwarf_line_section, 0); /* end file */ | ||
| 1045 | } | ||
| 1046 | for (i = 0; i < dwarf_line.dir_size; i++) | ||
| 1047 | tcc_free(dwarf_line.dir_table[i]); | ||
| 1048 | tcc_free(dwarf_line.dir_table); | ||
| 1049 | for (i = 0; i < dwarf_line.filename_size; i++) | ||
| 1050 | tcc_free(dwarf_line.filename_table[i].name); | ||
| 1051 | tcc_free(dwarf_line.filename_table); | ||
| 1052 | |||
| 1053 | dwarf_line_op(0); // extended | ||
| 1054 | dwarf_uleb128_op(1); // extended size | ||
| 1055 | dwarf_line_op(DW_LNE_end_sequence); | ||
| 1056 | i = (s1->dwarf >= 5) * 2; | ||
| 1057 | write32le(&dwarf_line_section->data[dwarf_line.start + 6 + i], | ||
| 1058 | dwarf_line_section->data_offset - dwarf_line.start - (10 + i)); | ||
| 1059 | section_ptr_add(dwarf_line_section, 3); | ||
| 1060 | dwarf_reloc(dwarf_line_section, section_sym, R_DATA_PTR); | ||
| 1061 | ptr = section_ptr_add(dwarf_line_section, dwarf_line.line_size - 3); | ||
| 1062 | memmove(ptr - 3, dwarf_line.line_data, dwarf_line.line_size); | ||
| 1063 | tcc_free(dwarf_line.line_data); | ||
| 1064 | write32le(dwarf_line_section->data + dwarf_line.start, | ||
| 1065 | dwarf_line_section->data_offset - dwarf_line.start - 4); | ||
| 1066 | } | ||
| 1067 | else | ||
| 1068 | put_stabs_r(s1, NULL, N_SO, 0, 0, | ||
| 1069 | text_section->data_offset, text_section, section_sym); | ||
| 455 | tcc_free(debug_hash); | 1070 | tcc_free(debug_hash); |
| 456 | } | 1071 | } |
| 457 | 1072 | ||
| @@ -462,8 +1077,10 @@ static BufferedFile* put_new_file(TCCState *s1) · 4 unmodified lines | |||
| 462 | if (f->filename[0] == ':') | 1077 | if (f->filename[0] == ':') |
| 463 | f = f->prev; | 1078 | f = f->prev; |
| 464 | if (f && new_file) { | 1079 | if (f && new_file) { |
| 465 | put_stabs_r(s1, f->filename, N_SOL, 0, 0, ind, text_section, section_sym); | 1080 | if (!s1->dwarf) |
| 1081 | put_stabs_r(s1, f->filename, N_SOL, 0, 0, ind, text_section, section_sym); | ||
| 466 | new_file = last_line_num = 0; | 1082 | new_file = last_line_num = 0; |
| 1083 | dwarf_file(s1); | ||
| 467 | } | 1084 | } |
| 468 | return f; | 1085 | return f; |
| 469 | } | 1086 | } |
| @@ -475,6 +1092,7 @@ ST_FUNC void tcc_debug_putfile(TCCState *s1, const char *filename) · 5 unmodified lines | |||
| 475 | return; | 1092 | return; |
| 476 | pstrcpy(file->filename, sizeof(file->filename), filename); | 1093 | pstrcpy(file->filename, sizeof(file->filename), filename); |
| 477 | new_file = 1; | 1094 | new_file = 1; |
| 1095 | dwarf_file(s1); | ||
| 478 | } | 1096 | } |
| 479 | 1097 | ||
| 480 | /* begin of #include */ | 1098 | /* begin of #include */ |
| @@ -482,8 +1100,53 @@ ST_FUNC void tcc_debug_bincl(TCCState *s1) · 1 unmodified line | |||
| 482 | { | 1100 | { |
| 483 | if (!s1->do_debug) | 1101 | if (!s1->do_debug) |
| 484 | return; | 1102 | return; |
| 485 | put_stabs(s1, file->filename, N_BINCL, 0, 0, 0); | 1103 | if (s1->dwarf) { |
| 1104 | int i, j; | ||
| 1105 | char *filename = strrchr(file->filename, '/'); | ||
| 1106 | char *dir; | ||
| 1107 | |||
| 1108 | if (filename == NULL) { | ||
| 1109 | filename = file->filename; | ||
| 1110 | i = 0; | ||
| 1111 | } | ||
| 1112 | else { | ||
| 1113 | char *undo = filename; | ||
| 1114 | |||
| 1115 | *filename++ = '\0'; | ||
| 1116 | dir = file->filename; | ||
| 1117 | for (i = 0; i < dwarf_line.dir_size; i++) | ||
| 1118 | if (strcmp (dwarf_line.dir_table[i], dir) == 0) | ||
| 1119 | break; | ||
| 1120 | if (i == dwarf_line.dir_size) { | ||
| 1121 | dwarf_line.dir_size++; | ||
| 1122 | dwarf_line.dir_table = | ||
| 1123 | (char **) tcc_realloc(dwarf_line.dir_table, | ||
| 1124 | dwarf_line.dir_size * | ||
| 1125 | sizeof (char *)); | ||
| 1126 | dwarf_line.dir_table[i] = tcc_strdup(dir); | ||
| 1127 | } | ||
| 1128 | *undo = '/'; | ||
| 1129 | } | ||
| 1130 | if (strcmp(filename, "<command line>")) { | ||
| 1131 | for (j = 0; j < dwarf_line.filename_size; j++) | ||
| 1132 | if (strcmp (dwarf_line.filename_table[j].name, filename) == 0) | ||
| 1133 | break; | ||
| 1134 | if (j == dwarf_line.filename_size) { | ||
| 1135 | dwarf_line.filename_table = | ||
| 1136 | (struct dwarf_filename_struct *) | ||
| 1137 | tcc_realloc(dwarf_line.filename_table, | ||
| 1138 | (dwarf_line.filename_size + 1) * | ||
| 1139 | sizeof (struct dwarf_filename_struct)); | ||
| 1140 | dwarf_line.filename_table[dwarf_line.filename_size].dir_entry = i; | ||
| 1141 | dwarf_line.filename_table[dwarf_line.filename_size++].name = | ||
| 1142 | tcc_strdup(filename); | ||
| 1143 | } | ||
| 1144 | } | ||
| 1145 | } | ||
| 1146 | else | ||
| 1147 | put_stabs(s1, file->filename, N_BINCL, 0, 0, 0); | ||
| 486 | new_file = 1; | 1148 | new_file = 1; |
| 1149 | dwarf_file(s1); | ||
| 487 | } | 1150 | } |
| 488 | 1151 | ||
| 489 | /* end of #include */ | 1152 | /* end of #include */ |
| @@ -491,30 +1154,73 @@ ST_FUNC void tcc_debug_eincl(TCCState *s1) · 1 unmodified line | |||
| 491 | { | 1154 | { |
| 492 | if (!s1->do_debug) | 1155 | if (!s1->do_debug) |
| 493 | return; | 1156 | return; |
| 494 | put_stabn(s1, N_EINCL, 0, 0, 0); | 1157 | if (!s1->dwarf) |
| 1158 | put_stabn(s1, N_EINCL, 0, 0, 0); | ||
| 495 | new_file = 1; | 1159 | new_file = 1; |
| 1160 | dwarf_file(s1); | ||
| 496 | } | 1161 | } |
| 497 | 1162 | ||
| 498 | /* generate line number info */ | 1163 | /* generate line number info */ |
| 499 | static void tcc_debug_line(TCCState *s1) | 1164 | static void tcc_debug_line(TCCState *s1) |
| 500 | { | 1165 | { |
| 501 | BufferedFile *f; | 1166 | BufferedFile *f; |
| 1167 | |||
| 502 | if (!s1->do_debug | 1168 | if (!s1->do_debug |
| 503 | || cur_text_section != text_section | 1169 | || cur_text_section != text_section |
| 504 | || !(f = put_new_file(s1)) | 1170 | || !(f = put_new_file(s1)) |
| 505 | || last_line_num == f->line_num) | 1171 | || last_line_num == f->line_num) |
| 506 | return; | 1172 | return; |
| 507 | if (func_ind != -1) { | 1173 | if (s1->dwarf) { |
| 508 | put_stabn(s1, N_SLINE, 0, f->line_num, ind - func_ind); | 1174 | int len_pc = (ind - dwarf_line.last_pc) / DWARF_MIN_INSTR_LEN; |
| 509 | } else { | 1175 | int len_line = f->line_num - dwarf_line.last_line; |
| 510 | /* from tcc_assemble */ | 1176 | int n = len_pc * DWARF_LINE_RANGE + len_line + DWARF_OPCODE_BASE - DWARF_LINE_BASE; |
| 511 | put_stabs_r(s1, NULL, N_SLINE, 0, f->line_num, ind, text_section, section_sym); | 1177 | |
| 1178 | if (dwarf_line.cur_file != dwarf_line.last_file) { | ||
| 1179 | dwarf_line.last_file = dwarf_line.cur_file; | ||
| 1180 | dwarf_line_op(DW_LNS_set_file); | ||
| 1181 | dwarf_uleb128_op(dwarf_line.cur_file); | ||
| 1182 | } | ||
| 1183 | if (len_pc && | ||
| 1184 | len_line >= DWARF_LINE_BASE && len_line <= (DWARF_OPCODE_BASE + DWARF_LINE_BASE) && | ||
| 1185 | n >= DWARF_OPCODE_BASE && n <= 255) | ||
| 1186 | dwarf_line_op(n); | ||
| 1187 | else { | ||
| 1188 | if (len_pc) { | ||
| 1189 | n = len_pc * DWARF_LINE_RANGE + 0 + DWARF_OPCODE_BASE - DWARF_LINE_BASE; | ||
| 1190 | if (n >= DWARF_OPCODE_BASE && n <= 255) | ||
| 1191 | dwarf_line_op(n); | ||
| 1192 | else { | ||
| 1193 | dwarf_line_op(DW_LNS_advance_pc); | ||
| 1194 | dwarf_uleb128_op(len_pc); | ||
| 1195 | } | ||
| 1196 | } | ||
| 1197 | if (len_line) { | ||
| 1198 | n = 0 * DWARF_LINE_RANGE + len_line + DWARF_OPCODE_BASE - DWARF_LINE_BASE; | ||
| 1199 | if (len_line >= DWARF_LINE_BASE && len_line <= (DWARF_OPCODE_BASE + DWARF_LINE_BASE) && | ||
| 1200 | n >= DWARF_OPCODE_BASE && n <= 255) | ||
| 1201 | dwarf_line_op(n); | ||
| 1202 | else { | ||
| 1203 | dwarf_line_op(DW_LNS_advance_line); | ||
| 1204 | dwarf_sleb128_op(len_line); | ||
| 1205 | } | ||
| 1206 | } | ||
| 1207 | } | ||
| 1208 | dwarf_line.last_pc = ind; | ||
| 1209 | dwarf_line.last_line = f->line_num; | ||
| 1210 | } | ||
| 1211 | else { | ||
| 1212 | if (func_ind != -1) { | ||
| 1213 | put_stabn(s1, N_SLINE, 0, f->line_num, ind - func_ind); | ||
| 1214 | } else { | ||
| 1215 | /* from tcc_assemble */ | ||
| 1216 | put_stabs_r(s1, NULL, N_SLINE, 0, f->line_num, ind, text_section, section_sym); | ||
| 1217 | } | ||
| 1218 | last_line_num = f->line_num; | ||
| 512 | } | 1219 | } |
| 513 | last_line_num = f->line_num; | ||
| 514 | } | 1220 | } |
| 515 | 1221 | ||
| 516 | static void tcc_debug_stabs (TCCState *s1, const char *str, int type, unsigned long value, | 1222 | static void tcc_debug_stabs (TCCState *s1, const char *str, int type, unsigned long value, |
| 517 | Section *sec, int sym_index) | 1223 | Section *sec, int sym_index, int info) |
| 518 | { | 1224 | { |
| 519 | struct debug_sym *s; | 1225 | struct debug_sym *s; |
| 520 | 1226 | ||
| @@ -529,6 +1235,9 @@ static void tcc_debug_stabs (TCCState *s1, const char *str, int type, unsigned l · 8 unmodified lines | |||
| 529 | s->str = tcc_strdup(str); | 1235 | s->str = tcc_strdup(str); |
| 530 | s->sec = sec; | 1236 | s->sec = sec; |
| 531 | s->sym_index = sym_index; | 1237 | s->sym_index = sym_index; |
| 1238 | s->info = info; | ||
| 1239 | s->file = dwarf_line.cur_file; | ||
| 1240 | s->line = file->line_num; | ||
| 532 | } | 1241 | } |
| 533 | else if (sec) | 1242 | else if (sec) |
| 534 | put_stabs_r (s1, str, type, 0, 0, value, sec, sym_index); | 1243 | put_stabs_r (s1, str, type, 0, 0, value, sec, sym_index); |
| @@ -567,6 +1276,40 @@ static void tcc_debug_stabn(TCCState *s1, int type, int value) · 32 unmodified lines | |||
| 567 | } | 1276 | } |
| 568 | } | 1277 | } |
| 569 | 1278 | ||
| 1279 | static int tcc_debug_find(Sym *t) | ||
| 1280 | { | ||
| 1281 | int i; | ||
| 1282 | |||
| 1283 | for (i = 0; i < n_debug_hash; i++) | ||
| 1284 | if (t == debug_hash[i].type) | ||
| 1285 | return debug_hash[i].debug_type; | ||
| 1286 | return -1; | ||
| 1287 | } | ||
| 1288 | |||
| 1289 | static int tcc_debug_add(Sym *t, int dwarf) | ||
| 1290 | { | ||
| 1291 | int offset = dwarf ? dwarf_info_section->data_offset : ++debug_next_type; | ||
| 1292 | |||
| 1293 | debug_hash = (struct debug_hash *) | ||
| 1294 | tcc_realloc (debug_hash, | ||
| 1295 | (n_debug_hash + 1) * sizeof(*debug_hash)); | ||
| 1296 | debug_hash[n_debug_hash].debug_type = offset; | ||
| 1297 | debug_hash[n_debug_hash++].type = t; | ||
| 1298 | return offset; | ||
| 1299 | } | ||
| 1300 | |||
| 1301 | static void tcc_debug_remove(Sym *t) | ||
| 1302 | { | ||
| 1303 | int i; | ||
| 1304 | |||
| 1305 | for (i = 0; i < n_debug_hash; i++) | ||
| 1306 | if (t == debug_hash[i].type) { | ||
| 1307 | n_debug_hash--; | ||
| 1308 | for (; i < n_debug_hash; i++) | ||
| 1309 | debug_hash[i] = debug_hash[i+1]; | ||
| 1310 | } | ||
| 1311 | } | ||
| 1312 | |||
| 570 | static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) | 1313 | static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) |
| 571 | { | 1314 | { |
| 572 | int type; | 1315 | int type; |
| @@ -585,22 +1328,12 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 12 unmodified lines | |||
| 585 | break; | 1328 | break; |
| 586 | } | 1329 | } |
| 587 | if ((type & VT_BTYPE) == VT_STRUCT) { | 1330 | if ((type & VT_BTYPE) == VT_STRUCT) { |
| 588 | int i; | 1331 | Sym *e = t; |
| 589 | 1332 | ||
| 590 | t = t->type.ref; | 1333 | t = t->type.ref; |
| 591 | for (i = 0; i < n_debug_hash; i++) { | 1334 | debug_type = tcc_debug_find(t); |
| 592 | if (t == debug_hash[i].type) { | ||
| 593 | debug_type = debug_hash[i].debug_type; | ||
| 594 | break; | ||
| 595 | } | ||
| 596 | } | ||
| 597 | if (debug_type == -1) { | 1335 | if (debug_type == -1) { |
| 598 | debug_type = ++debug_next_type; | 1336 | debug_type = tcc_debug_add(t, 0); |
| 599 | debug_hash = (struct debug_hash *) | ||
| 600 | tcc_realloc (debug_hash, | ||
| 601 | (n_debug_hash + 1) * sizeof(*debug_hash)); | ||
| 602 | debug_hash[n_debug_hash].debug_type = debug_type; | ||
| 603 | debug_hash[n_debug_hash++].type = t; | ||
| 604 | cstr_new (&str); | 1337 | cstr_new (&str); |
| 605 | cstr_printf (&str, "%s:T%d=%c%d", | 1338 | cstr_printf (&str, "%s:T%d=%c%d", |
| 606 | (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM | 1339 | (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM |
| @@ -627,39 +1360,44 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 20 unmodified lines | |||
| 627 | cstr_printf (&str, ",%d,%d;", pos, size); | 1360 | cstr_printf (&str, ",%d,%d;", pos, size); |
| 628 | } | 1361 | } |
| 629 | cstr_printf (&str, ";"); | 1362 | cstr_printf (&str, ";"); |
| 630 | tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0); | 1363 | tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0); |
| 631 | cstr_free (&str); | 1364 | cstr_free (&str); |
| 1365 | if (debug_info) | ||
| 1366 | tcc_debug_remove(e); | ||
| 632 | } | 1367 | } |
| 633 | } | 1368 | } |
| 634 | else if (IS_ENUM(type)) { | 1369 | else if (IS_ENUM(type)) { |
| 635 | Sym *e = t = t->type.ref; | 1370 | Sym *e = t = t->type.ref; |
| 636 | 1371 | ||
| 637 | debug_type = ++debug_next_type; | 1372 | debug_type = tcc_debug_find(t); |
| 638 | cstr_new (&str); | 1373 | if (debug_type == -1) { |
| 639 | cstr_printf (&str, "%s:T%d=e", | 1374 | debug_type = tcc_debug_add(t, 0); |
| 640 | (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM | 1375 | cstr_new (&str); |
| 641 | ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL), | 1376 | cstr_printf (&str, "%s:T%d=e", |
| 642 | debug_type); | 1377 | (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM |
| 643 | while (t->next) { | 1378 | ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL), |
| 644 | t = t->next; | 1379 | debug_type); |
| 645 | cstr_printf (&str, "%s:", | 1380 | while (t->next) { |
| 646 | (t->v & ~SYM_FIELD) >= SYM_FIRST_ANOM | 1381 | t = t->next; |
| 647 | ? "" : get_tok_str(t->v & ~SYM_FIELD, NULL)); | 1382 | cstr_printf (&str, "%s:", |
| 648 | cstr_printf (&str, e->type.t & VT_UNSIGNED ? "%u," : "%d,", | 1383 | (t->v & ~SYM_FIELD) >= SYM_FIRST_ANOM |
| 649 | (int)t->enum_val); | 1384 | ? "" : get_tok_str(t->v & ~SYM_FIELD, NULL)); |
| 650 | } | 1385 | cstr_printf (&str, e->type.t & VT_UNSIGNED ? "%u," : "%d,", |
| 651 | cstr_printf (&str, ";"); | 1386 | (int)t->enum_val); |
| 652 | tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0); | 1387 | } |
| 653 | cstr_free (&str); | 1388 | cstr_printf (&str, ";"); |
| 1389 | tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0); | ||
| 1390 | cstr_free (&str); | ||
| 1391 | if (debug_info) | ||
| 1392 | tcc_debug_remove(e); | ||
| 1393 | } | ||
| 654 | } | 1394 | } |
| 655 | else if ((type & VT_BTYPE) != VT_FUNC) { | 1395 | else if ((type & VT_BTYPE) != VT_FUNC) { |
| 656 | type &= ~VT_STRUCT_MASK; | 1396 | type &= ~VT_STRUCT_MASK; |
| 657 | for (debug_type = 1; | 1397 | for (debug_type = 1; debug_type <= N_DEFAULT_DEBUG; debug_type++) |
| 658 | debug_type <= sizeof(default_debug) / sizeof(default_debug[0]); | ||
| 659 | debug_type++) | ||
| 660 | if (default_debug[debug_type - 1].type == type) | 1398 | if (default_debug[debug_type - 1].type == type) |
| 661 | break; | 1399 | break; |
| 662 | if (debug_type > sizeof(default_debug) / sizeof(default_debug[0])) | 1400 | if (debug_type > N_DEFAULT_DEBUG) |
| 663 | return; | 1401 | return; |
| 664 | } | 1402 | } |
| 665 | if (n > 0) | 1403 | if (n > 0) |
| @@ -686,8 +1424,263 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 20 unmodified lines | |||
| 686 | cstr_printf (result, "%d", debug_type); | 1424 | cstr_printf (result, "%d", debug_type); |
| 687 | } | 1425 | } |
| 688 | 1426 | ||
| 1427 | static int tcc_get_dwarf_info(TCCState *s1, Sym *s) | ||
| 1428 | { | ||
| 1429 | int type; | ||
| 1430 | int debug_type = -1; | ||
| 1431 | Sym *e, *t = s; | ||
| 1432 | int i; | ||
| 1433 | |||
| 1434 | for (;;) { | ||
| 1435 | type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE); | ||
| 1436 | if ((type & VT_BTYPE) != VT_BYTE) | ||
| 1437 | type &= ~VT_DEFSIGN; | ||
| 1438 | if (type == VT_PTR || type == (VT_PTR | VT_ARRAY)) | ||
| 1439 | t = t->type.ref; | ||
| 1440 | else | ||
| 1441 | break; | ||
| 1442 | } | ||
| 1443 | if ((type & VT_BTYPE) == VT_STRUCT) { | ||
| 1444 | t = t->type.ref; | ||
| 1445 | debug_type = tcc_debug_find(t); | ||
| 1446 | if (debug_type == -1) { | ||
| 1447 | int pos_sib, i, *pos_type; | ||
| 1448 | |||
| 1449 | debug_type = tcc_debug_add(t, 1); | ||
| 1450 | e = t; | ||
| 1451 | i = 0; | ||
| 1452 | while (e->next) { | ||
| 1453 | e = e->next; | ||
| 1454 | i++; | ||
| 1455 | } | ||
| 1456 | pos_type = (int *) tcc_malloc(i * sizeof(int)); | ||
| 1457 | dwarf_data1(dwarf_info_section, | ||
| 1458 | IS_UNION (t->type.t) ? DWARF_ABBREV_UNION_TYPE | ||
| 1459 | : DWARF_ABBREV_STRUCTURE_TYPE); | ||
| 1460 | dwarf_strp(dwarf_info_section, | ||
| 1461 | (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM | ||
| 1462 | ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL)); | ||
| 1463 | dwarf_uleb128(dwarf_info_section, t->c); | ||
| 1464 | dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file); | ||
| 1465 | dwarf_uleb128(dwarf_info_section, file->line_num); | ||
| 1466 | pos_sib = dwarf_info_section->data_offset; | ||
| 1467 | dwarf_data4(dwarf_info_section, 0); | ||
| 1468 | e = t; | ||
| 1469 | i = 0; | ||
| 1470 | while (e->next) { | ||
| 1471 | e = e->next; | ||
| 1472 | if (e->type.t & VT_BITFIELD) { | ||
| 1473 | int pos = e->c * 8 + BIT_POS(e->type.t); | ||
| 1474 | int size = BIT_SIZE(e->type.t); | ||
| 1475 | |||
| 1476 | dwarf_data1(dwarf_info_section, DWARF_ABBREV_MEMBER_BF); | ||
| 1477 | dwarf_strp(dwarf_info_section, | ||
| 1478 | (e->v & ~SYM_FIELD) >= SYM_FIRST_ANOM | ||
| 1479 | ? "" : get_tok_str(e->v & ~SYM_FIELD, NULL)); | ||
| 1480 | dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file); | ||
| 1481 | dwarf_uleb128(dwarf_info_section, file->line_num); | ||
| 1482 | pos_type[i++] = dwarf_info_section->data_offset; | ||
| 1483 | dwarf_data4(dwarf_info_section, 0); | ||
| 1484 | dwarf_uleb128(dwarf_info_section, size); | ||
| 1485 | dwarf_uleb128(dwarf_info_section, pos); | ||
| 1486 | } | ||
| 1487 | else { | ||
| 1488 | dwarf_data1(dwarf_info_section, DWARF_ABBREV_MEMBER); | ||
| 1489 | dwarf_strp(dwarf_info_section, | ||
| 1490 | (e->v & ~SYM_FIELD) >= SYM_FIRST_ANOM | ||
| 1491 | ? "" : get_tok_str(e->v & ~SYM_FIELD, NULL)); | ||
| 1492 | dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file); | ||
| 1493 | dwarf_uleb128(dwarf_info_section, file->line_num); | ||
| 1494 | pos_type[i++] = dwarf_info_section->data_offset; | ||
| 1495 | dwarf_data4(dwarf_info_section, 0); | ||
| 1496 | dwarf_uleb128(dwarf_info_section, e->c); | ||
| 1497 | } | ||
| 1498 | } | ||
| 1499 | dwarf_data1(dwarf_info_section, 0); | ||
| 1500 | write32le(dwarf_info_section->data + pos_sib, | ||
| 1501 | dwarf_info_section->data_offset - dwarf_info.start); | ||
| 1502 | e = t; | ||
| 1503 | i = 0; | ||
| 1504 | while (e->next) { | ||
| 1505 | e = e->next; | ||
| 1506 | type = tcc_get_dwarf_info(s1, e); | ||
| 1507 | write32le(dwarf_info_section->data + pos_type[i++], | ||
| 1508 | type - dwarf_info.start); | ||
| 1509 | } | ||
| 1510 | tcc_free(pos_type); | ||
| 1511 | if (debug_info) | ||
| 1512 | tcc_debug_remove(t); | ||
| 1513 | } | ||
| 1514 | } | ||
| 1515 | else if (IS_ENUM(type)) { | ||
| 1516 | t = t->type.ref; | ||
| 1517 | debug_type = tcc_debug_find(t); | ||
| 1518 | if (debug_type == -1) { | ||
| 1519 | int pos_sib, pos_type; | ||
| 1520 | CType ct = { VT_INT | (type & VT_UNSIGNED) , NULL }; | ||
| 1521 | Sym sym = { .type = ct }; | ||
| 1522 | |||
| 1523 | pos_type = tcc_get_dwarf_info(s1, &sym); | ||
| 1524 | debug_type = tcc_debug_add(t, 1); | ||
| 1525 | dwarf_data1(dwarf_info_section, DWARF_ABBREV_ENUMERATION_TYPE); | ||
| 1526 | dwarf_strp(dwarf_info_section, | ||
| 1527 | (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM | ||
| 1528 | ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL)); | ||
| 1529 | dwarf_data1(dwarf_info_section, | ||
| 1530 | type & VT_UNSIGNED ? DW_ATE_unsigned : DW_ATE_signed ); | ||
| 1531 | dwarf_data1(dwarf_info_section, 4); | ||
| 1532 | dwarf_data4(dwarf_info_section, pos_type - dwarf_info.start); | ||
| 1533 | dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file); | ||
| 1534 | dwarf_uleb128(dwarf_info_section, file->line_num); | ||
| 1535 | pos_sib = dwarf_info_section->data_offset; | ||
| 1536 | dwarf_data4(dwarf_info_section, 0); | ||
| 1537 | e = t; | ||
| 1538 | while (e->next) { | ||
| 1539 | e = e->next; | ||
| 1540 | dwarf_data1(dwarf_info_section, DWARF_ABBREV_ENUMERATOR); | ||
| 1541 | dwarf_strp(dwarf_info_section, | ||
| 1542 | (e->v & ~SYM_FIELD) >= SYM_FIRST_ANOM | ||
| 1543 | ? "" : get_tok_str(e->v & ~SYM_FIELD, NULL)); | ||
| 1544 | dwarf_data4(dwarf_info_section, e->enum_val); | ||
| 1545 | } | ||
| 1546 | dwarf_data1(dwarf_info_section, 0); | ||
| 1547 | write32le(dwarf_info_section->data + pos_sib, | ||
| 1548 | dwarf_info_section->data_offset - dwarf_info.start); | ||
| 1549 | if (debug_info) | ||
| 1550 | tcc_debug_remove(t); | ||
| 1551 | } | ||
| 1552 | } | ||
| 1553 | else if ((type & VT_BTYPE) != VT_FUNC) { | ||
| 1554 | type &= ~VT_STRUCT_MASK; | ||
| 1555 | for (i = 1; i <= N_DEFAULT_DEBUG; i++) | ||
| 1556 | if (default_debug[i - 1].type == type) | ||
| 1557 | break; | ||
| 1558 | if (i > N_DEFAULT_DEBUG) | ||
| 1559 | return 0; | ||
| 1560 | debug_type = dwarf_info.base_type_used[i - 1]; | ||
| 1561 | if (debug_type == 0) { | ||
| 1562 | char name[100]; | ||
| 1563 | |||
| 1564 | debug_type = dwarf_info_section->data_offset; | ||
| 1565 | dwarf_data1(dwarf_info_section, DWARF_ABBREV_BASE_TYPE); | ||
| 1566 | dwarf_uleb128(dwarf_info_section, default_debug[i - 1].size); | ||
| 1567 | dwarf_data1(dwarf_info_section, default_debug[i - 1].encoding); | ||
| 1568 | strncpy(name, default_debug[i - 1].name, sizeof(name) -1); | ||
| 1569 | *strchr(name, ':') = 0; | ||
| 1570 | dwarf_strp(dwarf_info_section, name); | ||
| 1571 | dwarf_info.base_type_used[i - 1] = debug_type; | ||
| 1572 | } | ||
| 1573 | } | ||
| 1574 | t = s; | ||
| 1575 | for (;;) { | ||
| 1576 | type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE); | ||
| 1577 | if ((type & VT_BTYPE) != VT_BYTE) | ||
| 1578 | type &= ~VT_DEFSIGN; | ||
| 1579 | if (type == VT_PTR) { | ||
| 1580 | i = dwarf_info_section->data_offset; | ||
| 1581 | dwarf_data1(dwarf_info_section, DWARF_ABBREV_POINTER); | ||
| 1582 | dwarf_data1(dwarf_info_section, PTR_SIZE); | ||
| 1583 | dwarf_data4(dwarf_info_section, debug_type - dwarf_info.start); | ||
| 1584 | debug_type = i; | ||
| 1585 | } | ||
| 1586 | else if (type == (VT_PTR | VT_ARRAY)) { | ||
| 1587 | int sib_pos, sub_type; | ||
| 1588 | CType ct = { VT_INT | VT_UNSIGNED , NULL }; | ||
| 1589 | Sym sym = { .type = ct }; | ||
| 1590 | |||
| 1591 | sub_type = tcc_get_dwarf_info(s1, &sym); | ||
| 1592 | i = dwarf_info_section->data_offset; | ||
| 1593 | dwarf_data1(dwarf_info_section, DWARF_ABBREV_ARRAY_TYPE); | ||
| 1594 | dwarf_data4(dwarf_info_section, debug_type - dwarf_info.start); | ||
| 1595 | sib_pos = dwarf_info_section->data_offset; | ||
| 1596 | dwarf_data4(dwarf_info_section, 0); | ||
| 1597 | for (;;) { | ||
| 1598 | dwarf_data1(dwarf_info_section, DWARF_ABBREV_SUBRANGE_TYPE); | ||
| 1599 | dwarf_data4(dwarf_info_section, sub_type - dwarf_info.start); | ||
| 1600 | dwarf_uleb128(dwarf_info_section, t->type.ref->c - 1); | ||
| 1601 | s = t->type.ref; | ||
| 1602 | type = s->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE); | ||
| 1603 | if (type != (VT_PTR | VT_ARRAY)) | ||
| 1604 | break; | ||
| 1605 | t = s; | ||
| 1606 | } | ||
| 1607 | dwarf_data1(dwarf_info_section, 0); | ||
| 1608 | write32le(dwarf_info_section->data + sib_pos, | ||
| 1609 | dwarf_info_section->data_offset - dwarf_info.start); | ||
| 1610 | debug_type = i; | ||
| 1611 | } | ||
| 1612 | else if (type == VT_FUNC) { | ||
| 1613 | return tcc_get_dwarf_info (s1, t->type.ref); | ||
| 1614 | } | ||
| 1615 | else | ||
| 1616 | break; | ||
| 1617 | t = t->type.ref; | ||
| 1618 | } | ||
| 1619 | return debug_type; | ||
| 1620 | } | ||
| 1621 | |||
| 689 | static void tcc_debug_finish (TCCState *s1, struct debug_info *cur) | 1622 | static void tcc_debug_finish (TCCState *s1, struct debug_info *cur) |
| 690 | { | 1623 | { |
| 1624 | if (s1->dwarf) { | ||
| 1625 | while (cur) { | ||
| 1626 | int i; | ||
| 1627 | struct debug_info *next = cur->next; | ||
| 1628 | |||
| 1629 | for (i = cur->n_sym - 1; i >= 0; i--) { | ||
| 1630 | struct debug_sym *s = &cur->sym[i]; | ||
| 1631 | |||
| 1632 | dwarf_data1(dwarf_info_section, | ||
| 1633 | s->type == N_PSYM | ||
| 1634 | ? DWARF_ABBREV_FORMAL_PARAMETER | ||
| 1635 | : s->type == N_GSYM | ||
| 1636 | ? DWARF_ABBREV_VARIABLE_EXTERNAL | ||
| 1637 | : s->type == N_STSYM | ||
| 1638 | ? DWARF_ABBREV_VARIABLE_STATIC | ||
| 1639 | : DWARF_ABBREV_VARIABLE_LOCAL); | ||
| 1640 | dwarf_strp(dwarf_info_section, s->str); | ||
| 1641 | if (s->type == N_GSYM || s->type == N_STSYM) { | ||
| 1642 | dwarf_uleb128(dwarf_info_section, s->file); | ||
| 1643 | dwarf_uleb128(dwarf_info_section, s->line); | ||
| 1644 | } | ||
| 1645 | dwarf_data4(dwarf_info_section, s->info - dwarf_info.start); | ||
| 1646 | if (s->type == N_GSYM || s->type == N_STSYM) { | ||
| 1647 | /* global/static */ | ||
| 1648 | if (s->type == N_GSYM) | ||
| 1649 | dwarf_data1(dwarf_info_section, 1); | ||
| 1650 | dwarf_data1(dwarf_info_section, PTR_SIZE + 1); | ||
| 1651 | dwarf_data1(dwarf_info_section, DW_OP_addr); | ||
| 1652 | if (s->type == N_STSYM) | ||
| 1653 | dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR); | ||
| 1654 | #if PTR_SIZE == 4 | ||
| 1655 | dwarf_data4(dwarf_info_section, s->value); | ||
| 1656 | #else | ||
| 1657 | dwarf_data8(dwarf_info_section, s->value); | ||
| 1658 | #endif | ||
| 1659 | } | ||
| 1660 | else { | ||
| 1661 | /* param/local */ | ||
| 1662 | dwarf_data1(dwarf_info_section, dwarf_sleb128_size(s->value) + 1); | ||
| 1663 | dwarf_data1(dwarf_info_section, DW_OP_fbreg); | ||
| 1664 | dwarf_sleb128(dwarf_info_section, s->value); | ||
| 1665 | } | ||
| 1666 | tcc_free (s->str); | ||
| 1667 | } | ||
| 1668 | tcc_free (cur->sym); | ||
| 1669 | dwarf_data1(dwarf_info_section, DWARF_ABBREV_LEXICAL_BLOCK); | ||
| 1670 | dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR); | ||
| 1671 | #if PTR_SIZE == 4 | ||
| 1672 | dwarf_data4(dwarf_info_section, func_ind + cur->start); | ||
| 1673 | dwarf_data4(dwarf_info_section, cur->end - cur->start); | ||
| 1674 | #else | ||
| 1675 | dwarf_data8(dwarf_info_section, func_ind + cur->start); | ||
| 1676 | dwarf_data8(dwarf_info_section, cur->end - cur->start); | ||
| 1677 | #endif | ||
| 1678 | tcc_debug_finish (s1, cur->child); | ||
| 1679 | dwarf_data1(dwarf_info_section, 0); | ||
| 1680 | tcc_free (cur); | ||
| 1681 | cur = next; | ||
| 1682 | } | ||
| 1683 | } | ||
| 691 | while (cur) { | 1684 | while (cur) { |
| 692 | int i; | 1685 | int i; |
| 693 | struct debug_info *next = cur->next; | 1686 | struct debug_info *next = cur->next; |
| @@ -720,10 +1713,19 @@ static void tcc_add_debug_info(TCCState *s1, int param, Sym *s, Sym *e) · 26 unmodified lines | |||
| 720 | for (; s != e; s = s->prev) { | 1713 | for (; s != e; s = s->prev) { |
| 721 | if (!s->v || (s->r & VT_VALMASK) != VT_LOCAL) | 1714 | if (!s->v || (s->r & VT_VALMASK) != VT_LOCAL) |
| 722 | continue; | 1715 | continue; |
| 723 | cstr_reset (&debug_str); | 1716 | if (s1->dwarf) { |
| 724 | cstr_printf (&debug_str, "%s:%s", get_tok_str(s->v, NULL), param ? "p" : ""); | 1717 | tcc_debug_stabs(s1, get_tok_str(s->v, NULL), |
| 725 | tcc_get_debug_info(s1, s, &debug_str); | 1718 | param ? N_PSYM : N_LSYM, s->c, NULL, 0, |
| 726 | tcc_debug_stabs(s1, debug_str.data, param ? N_PSYM : N_LSYM, s->c, NULL, 0); | 1719 | tcc_get_dwarf_info(s1, s)); |
| 1720 | } | ||
| 1721 | else { | ||
| 1722 | cstr_reset (&debug_str); | ||
| 1723 | cstr_printf (&debug_str, "%s:%s", get_tok_str(s->v, NULL), | ||
| 1724 | param ? "p" : ""); | ||
| 1725 | tcc_get_debug_info(s1, s, &debug_str); | ||
| 1726 | tcc_debug_stabs(s1, debug_str.data, param ? N_PSYM : N_LSYM, | ||
| 1727 | s->c, NULL, 0, 0); | ||
| 1728 | } | ||
| 727 | } | 1729 | } |
| 728 | cstr_free (&debug_str); | 1730 | cstr_free (&debug_str); |
| 729 | } | 1731 | } |
| @@ -739,23 +1741,83 @@ static void tcc_debug_funcstart(TCCState *s1, Sym *sym) · 9 unmodified lines | |||
| 739 | debug_info = NULL; | 1741 | debug_info = NULL; |
| 740 | tcc_debug_stabn(s1, N_LBRAC, ind - func_ind); | 1742 | tcc_debug_stabn(s1, N_LBRAC, ind - func_ind); |
| 741 | if (!(f = put_new_file(s1))) | 1743 | if (!(f = put_new_file(s1))) |
| 742 | return; | 1744 | return; |
| 743 | cstr_new (&debug_str); | ||
| 744 | cstr_printf(&debug_str, "%s:%c", funcname, sym->type.t & VT_STATIC ? 'f' : 'F'); | ||
| 745 | tcc_get_debug_info(s1, sym->type.ref, &debug_str); | ||
| 746 | put_stabs_r(s1, debug_str.data, N_FUN, 0, f->line_num, 0, cur_text_section, sym->c); | ||
| 747 | cstr_free (&debug_str); | ||
| 748 | |||
| 749 | tcc_debug_line(s1); | 1745 | tcc_debug_line(s1); |
| 1746 | if (s1->dwarf) { | ||
| 1747 | dwarf_info.func = sym; | ||
| 1748 | dwarf_info.line = file->line_num; | ||
| 1749 | if (s1->do_backtrace) { | ||
| 1750 | int i; | ||
| 1751 | |||
| 1752 | dwarf_line_op(0); // extended | ||
| 1753 | dwarf_uleb128_op(strlen(funcname) + 2); | ||
| 1754 | dwarf_line_op(DW_LNE_hi_user - 1); | ||
| 1755 | for (i = 0; i < strlen(funcname) + 1; i++) | ||
| 1756 | dwarf_line_op(funcname[i]); | ||
| 1757 | } | ||
| 1758 | } | ||
| 1759 | else { | ||
| 1760 | cstr_new (&debug_str); | ||
| 1761 | cstr_printf(&debug_str, "%s:%c", funcname, sym->type.t & VT_STATIC ? 'f' : 'F'); | ||
| 1762 | tcc_get_debug_info(s1, sym->type.ref, &debug_str); | ||
| 1763 | put_stabs_r(s1, debug_str.data, N_FUN, 0, f->line_num, 0, cur_text_section, sym->c); | ||
| 1764 | cstr_free (&debug_str); | ||
| 1765 | } | ||
| 750 | } | 1766 | } |
| 751 | 1767 | ||
| 752 | /* put function size */ | 1768 | /* put function size */ |
| 753 | static void tcc_debug_funcend(TCCState *s1, int size) | 1769 | static void tcc_debug_funcend(TCCState *s1, int size) |
| 754 | { | 1770 | { |
| 1771 | int func_sib = 0; | ||
| 1772 | |||
| 755 | if (!s1->do_debug) | 1773 | if (!s1->do_debug) |
| 756 | return; | 1774 | return; |
| 1775 | tcc_debug_line(s1); | ||
| 757 | tcc_debug_stabn(s1, N_RBRAC, size); | 1776 | tcc_debug_stabn(s1, N_RBRAC, size); |
| 1777 | if (s1->dwarf) { | ||
| 1778 | Sym *sym = dwarf_info.func; | ||
| 1779 | int debug_info = tcc_get_dwarf_info(s1, sym->type.ref); | ||
| 1780 | |||
| 1781 | dwarf_data1(dwarf_info_section, | ||
| 1782 | sym->type.t & VT_STATIC ? DWARF_ABBREV_SUBPROGRAM_STATIC | ||
| 1783 | : DWARF_ABBREV_SUBPROGRAM_EXTERNAL); | ||
| 1784 | if ((sym->type.t & VT_STATIC) == 0) | ||
| 1785 | dwarf_data1(dwarf_info_section, 1); | ||
| 1786 | dwarf_strp(dwarf_info_section, funcname); | ||
| 1787 | dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file); | ||
| 1788 | dwarf_uleb128(dwarf_info_section, dwarf_info.line); | ||
| 1789 | dwarf_data4(dwarf_info_section, debug_info - dwarf_info.start); | ||
| 1790 | dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR); | ||
| 1791 | #if PTR_SIZE == 4 | ||
| 1792 | dwarf_data4(dwarf_info_section, func_ind); // low_pc | ||
| 1793 | dwarf_data4(dwarf_info_section, size); // high_pc | ||
| 1794 | #else | ||
| 1795 | dwarf_data8(dwarf_info_section, func_ind); // low_pc | ||
| 1796 | dwarf_data8(dwarf_info_section, size); // high_pc | ||
| 1797 | #endif | ||
| 1798 | func_sib = dwarf_info_section->data_offset; | ||
| 1799 | dwarf_data4(dwarf_info_section, 0); // sibling | ||
| 1800 | dwarf_data1(dwarf_info_section, 1); | ||
| 1801 | #if defined(TCC_TARGET_I386) | ||
| 1802 | dwarf_data1(dwarf_info_section, DW_OP_reg5); // ebp | ||
| 1803 | #elif defined(TCC_TARGET_X86_64) | ||
| 1804 | dwarf_data1(dwarf_info_section, DW_OP_reg6); // rbp | ||
| 1805 | #elif defined TCC_TARGET_ARM | ||
| 1806 | dwarf_data1(dwarf_info_section, DW_OP_reg13); // sp | ||
| 1807 | #elif defined TCC_TARGET_ARM64 | ||
| 1808 | dwarf_data1(dwarf_info_section, DW_OP_reg29); // reg 29 | ||
| 1809 | #elif defined TCC_TARGET_RISCV64 | ||
| 1810 | dwarf_data1(dwarf_info_section, DW_OP_reg8); // r8(s0) | ||
| 1811 | #else | ||
| 1812 | dwarf_data1(dwarf_info_section, DW_OP_call_frame_cfa); | ||
| 1813 | #endif | ||
| 1814 | } | ||
| 758 | tcc_debug_finish (s1, debug_info_root); | 1815 | tcc_debug_finish (s1, debug_info_root); |
| 1816 | if (s1->dwarf) { | ||
| 1817 | dwarf_data1(dwarf_info_section, 0); | ||
| 1818 | write32le(dwarf_info_section->data + func_sib, | ||
| 1819 | dwarf_info_section->data_offset - dwarf_info.start); | ||
| 1820 | } | ||
| 759 | } | 1821 | } |
| 760 | 1822 | ||
| 761 | 1823 | ||
| @@ -769,19 +1831,44 @@ static void tcc_debug_extern_sym(TCCState *s1, Sym *sym, int sh_num, int sym_bin · 7 unmodified lines | |||
| 769 | if (sym_type == STT_FUNC || sym->v >= SYM_FIRST_ANOM) | 1831 | if (sym_type == STT_FUNC || sym->v >= SYM_FIRST_ANOM) |
| 770 | return; | 1832 | return; |
| 771 | s = s1->sections[sh_num]; | 1833 | s = s1->sections[sh_num]; |
| 1834 | if (s1->dwarf) { | ||
| 1835 | int debug_type; | ||
| 1836 | |||
| 1837 | debug_type = tcc_get_dwarf_info(s1, sym); | ||
| 1838 | dwarf_data1(dwarf_info_section, | ||
| 1839 | sym_bind == STB_GLOBAL | ||
| 1840 | ? DWARF_ABBREV_VARIABLE_EXTERNAL | ||
| 1841 | : DWARF_ABBREV_VARIABLE_STATIC); | ||
| 1842 | dwarf_strp(dwarf_info_section, get_tok_str(sym->v, NULL)); | ||
| 1843 | dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file); | ||
| 1844 | dwarf_uleb128(dwarf_info_section, file->line_num); | ||
| 1845 | dwarf_data4(dwarf_info_section, debug_type - dwarf_info.start); | ||
| 1846 | if (sym_bind == STB_GLOBAL) | ||
| 1847 | dwarf_data1(dwarf_info_section, 1); | ||
| 1848 | dwarf_data1(dwarf_info_section, PTR_SIZE + 1); | ||
| 1849 | dwarf_data1(dwarf_info_section, DW_OP_addr); | ||
| 1850 | greloca(dwarf_info_section, sym, dwarf_info_section->data_offset, | ||
| 1851 | R_DATA_PTR, 0); | ||
| 1852 | #if PTR_SIZE == 4 | ||
| 1853 | dwarf_data4(dwarf_info_section, 0); | ||
| 1854 | #else | ||
| 1855 | dwarf_data8(dwarf_info_section, 0); | ||
| 1856 | #endif | ||
| 1857 | return; | ||
| 1858 | } | ||
| 772 | 1859 | ||
| 773 | cstr_new (&str); | 1860 | cstr_new (&str); |
| 774 | cstr_printf (&str, "%s:%c", | 1861 | cstr_printf (&str, "%s:%c", |
| 775 | get_tok_str(sym->v, NULL), | 1862 | get_tok_str(sym->v, NULL), |
| 776 | sym_bind == STB_GLOBAL ? 'G' : local_scope ? 'V' : 'S' | 1863 | sym_bind == STB_GLOBAL ? 'G' : local_scope ? 'V' : 'S' |
| 777 | ); | 1864 | ); |
| 778 | tcc_get_debug_info(s1, sym, &str); | 1865 | tcc_get_debug_info(s1, sym, &str); |
| 779 | if (sym_bind == STB_GLOBAL) | 1866 | if (sym_bind == STB_GLOBAL) |
| 780 | tcc_debug_stabs(s1, str.data, N_GSYM, 0, NULL, 0); | 1867 | tcc_debug_stabs(s1, str.data, N_GSYM, 0, NULL, 0, 0); |
| 781 | else | 1868 | else |
| 782 | tcc_debug_stabs(s1, str.data, | 1869 | tcc_debug_stabs(s1, str.data, |
| 783 | (sym->type.t & VT_STATIC) && data_section == s | 1870 | (sym->type.t & VT_STATIC) && data_section == s |
| 784 | ? N_STSYM : N_LCSYM, 0, s, sym->c); | 1871 | ? N_STSYM : N_LCSYM, 0, s, sym->c, 0); |
| 785 | cstr_free (&str); | 1872 | cstr_free (&str); |
| 786 | } | 1873 | } |
| 787 | 1874 | ||
| @@ -791,12 +1878,25 @@ static void tcc_debug_typedef(TCCState *s1, Sym *sym) · 3 unmodified lines | |||
| 791 | 1878 | ||
| 792 | if (!s1->do_debug) | 1879 | if (!s1->do_debug) |
| 793 | return; | 1880 | return; |
| 1881 | if (s1->dwarf) { | ||
| 1882 | int debug_type; | ||
| 1883 | |||
| 1884 | debug_type = tcc_get_dwarf_info(s1, sym); | ||
| 1885 | if (debug_type != -1) { | ||
| 1886 | dwarf_data1(dwarf_info_section, DWARF_ABBREV_TYPEDEF); | ||
| 1887 | dwarf_strp(dwarf_info_section, get_tok_str(sym->v & ~SYM_FIELD, NULL)); | ||
| 1888 | dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file); | ||
| 1889 | dwarf_uleb128(dwarf_info_section, file->line_num); | ||
| 1890 | dwarf_data4(dwarf_info_section, debug_type - dwarf_info.start); | ||
| 1891 | } | ||
| 1892 | return; | ||
| 1893 | } | ||
| 794 | cstr_new (&str); | 1894 | cstr_new (&str); |
| 795 | cstr_printf (&str, "%s:t", | 1895 | cstr_printf (&str, "%s:t", |
| 796 | (sym->v & ~SYM_FIELD) >= SYM_FIRST_ANOM | 1896 | (sym->v & ~SYM_FIELD) >= SYM_FIRST_ANOM |
| 797 | ? "" : get_tok_str(sym->v & ~SYM_FIELD, NULL)); | 1897 | ? "" : get_tok_str(sym->v & ~SYM_FIELD, NULL)); |
| 798 | tcc_get_debug_info(s1, sym, &str); | 1898 | tcc_get_debug_info(s1, sym, &str); |
| 799 | tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0); | 1899 | tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0); |
| 800 | cstr_free (&str); | 1900 | cstr_free (&str); |
| 801 | } | 1901 | } |
| 802 | 1902 | ||
| @@ -973,7 +2073,7 @@ ST_FUNC int tccgen_compile(TCCState *s1) · 170 unmodified lines | |||
| 973 | const_wanted = 0; | 2073 | const_wanted = 0; |
| 974 | nocode_wanted = 0x80000000; | 2074 | nocode_wanted = 0x80000000; |
| 975 | local_scope = 0; | 2075 | local_scope = 0; |
| 976 | debug_modes = s1->do_debug | s1->test_coverage << 1; | 2076 | debug_modes = (s1->do_debug ? 1 : 0) | s1->test_coverage << 1; |
| 977 | 2077 | ||
| 978 | tcc_debug_start(s1); | 2078 | tcc_debug_start(s1); |
| 979 | tcc_tcov_start (); | 2079 | tcc_tcov_start (); |
| @@ -27,8 +27,16 @@ · 26 unmodified lines | |||
| 27 | typedef struct rt_context | 27 | typedef struct rt_context |
| 28 | { | 28 | { |
| 29 | /* --> tccelf.c:tcc_add_btstub wants those below in that order: */ | 29 | /* --> tccelf.c:tcc_add_btstub wants those below in that order: */ |
| 30 | Stab_Sym *stab_sym, *stab_sym_end; | 30 | union { |
| 31 | char *stab_str; | 31 | struct { |
| 32 | Stab_Sym *stab_sym, *stab_sym_end; | ||
| 33 | char *stab_str; | ||
| 34 | }; | ||
| 35 | struct { | ||
| 36 | unsigned char *dwarf_line, *dwarf_line_end, *dwarf_line_str; | ||
| 37 | addr_t dwarf_text; | ||
| 38 | }; | ||
| 39 | }; | ||
| 32 | ElfW(Sym) *esym_start, *esym_end; | 40 | ElfW(Sym) *esym_start, *esym_end; |
| 33 | char *elf_str; | 41 | char *elf_str; |
| 34 | addr_t prog_base; | 42 | addr_t prog_base; |
| @@ -169,9 +177,18 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 134 unmodified lines | |||
| 169 | memset(rc, 0, sizeof *rc); | 177 | memset(rc, 0, sizeof *rc); |
| 170 | if (s1->do_debug) { | 178 | if (s1->do_debug) { |
| 171 | void *p; | 179 | void *p; |
| 172 | rc->stab_sym = (Stab_Sym *)stab_section->data; | 180 | if (s1->dwarf) { |
| 173 | rc->stab_sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset); | 181 | rc->dwarf_line = dwarf_line_section->data; |
| 174 | rc->stab_str = (char *)stab_section->link->data; | 182 | rc->dwarf_line_end = dwarf_line_section->data + dwarf_line_section->data_offset; |
| 183 | rc->dwarf_line_str = dwarf_line_str_section->data; | ||
| 184 | rc->dwarf_text = text_section->sh_addr; | ||
| 185 | } | ||
| 186 | else { | ||
| 187 | rc->stab_sym = (Stab_Sym *)stab_section->data; | ||
| 188 | rc->stab_sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset); | ||
| 189 | rc->stab_str = (char *)stab_section->link->data; | ||
| 190 | rc->dwarf_text = 0; | ||
| 191 | } | ||
| 175 | rc->esym_start = (ElfW(Sym) *)(symtab_section->data); | 192 | rc->esym_start = (ElfW(Sym) *)(symtab_section->data); |
| 176 | rc->esym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset); | 193 | rc->esym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset); |
| 177 | rc->elf_str = (char *)symtab_section->link->data; | 194 | rc->elf_str = (char *)symtab_section->link->data; |
| @@ -571,6 +588,337 @@ found: · 393 unmodified lines | |||
| 571 | return func_addr; | 588 | return func_addr; |
| 572 | } | 589 | } |
| 573 | 590 | ||
| 591 | #define MAX_128 ((8 * sizeof (long long) + 6) / 7) | ||
| 592 | |||
| 593 | #define DW_GETC(s,e) ((s) < (e) ? *(s)++ : 0) | ||
| 594 | |||
| 595 | #define DIR_TABLE_SIZE (64) | ||
| 596 | #define FILE_TABLE_SIZE (256) | ||
| 597 | |||
| 598 | static unsigned long long | ||
| 599 | dwarf_read_uleb128(unsigned char **ln, unsigned char *end) | ||
| 600 | { | ||
| 601 | unsigned char *cp = *ln; | ||
| 602 | unsigned long long retval = 0; | ||
| 603 | int i; | ||
| 604 | |||
| 605 | for (i = 0; i < MAX_128; i++) { | ||
| 606 | unsigned long long byte = DW_GETC(cp, end); | ||
| 607 | |||
| 608 | retval |= (byte & 0x7f) << (i * 7); | ||
| 609 | if ((byte & 0x80) == 0) | ||
| 610 | break; | ||
| 611 | } | ||
| 612 | *ln = cp; | ||
| 613 | return retval; | ||
| 614 | } | ||
| 615 | |||
| 616 | static long long | ||
| 617 | dwarf_read_sleb128(unsigned char **ln, unsigned char *end) | ||
| 618 | { | ||
| 619 | unsigned char *cp = *ln; | ||
| 620 | long long retval = 0; | ||
| 621 | int i; | ||
| 622 | |||
| 623 | for (i = 0; i < MAX_128; i++) { | ||
| 624 | unsigned long long byte = DW_GETC(cp, end); | ||
| 625 | |||
| 626 | retval |= (byte & 0x7f) << (i * 7); | ||
| 627 | if ((byte & 0x80) == 0) { | ||
| 628 | if ((byte & 0x40) && (i + 1) * 7 < 64) | ||
| 629 | retval |= -1LL << ((i + 1) * 7); | ||
| 630 | break; | ||
| 631 | } | ||
| 632 | } | ||
| 633 | *ln = cp; | ||
| 634 | return retval; | ||
| 635 | } | ||
| 636 | |||
| 637 | static unsigned int dwarf_read_32(unsigned char **ln, unsigned char *end) | ||
| 638 | { | ||
| 639 | unsigned char *cp = *ln; | ||
| 640 | unsigned int retval = 0; | ||
| 641 | |||
| 642 | if ((cp + 4) < end) { | ||
| 643 | retval = read32le(cp); | ||
| 644 | cp += 4; | ||
| 645 | } | ||
| 646 | *ln = cp; | ||
| 647 | return retval; | ||
| 648 | } | ||
| 649 | |||
| 650 | #if PTR_SIZE == 8 | ||
| 651 | static unsigned long long dwarf_read_64(unsigned char **ln, unsigned char *end) | ||
| 652 | { | ||
| 653 | unsigned char *cp = *ln; | ||
| 654 | unsigned long long retval = 0; | ||
| 655 | |||
| 656 | if ((cp + 8) < end) { | ||
| 657 | retval = read64le(cp); | ||
| 658 | cp += 8; | ||
| 659 | } | ||
| 660 | *ln = cp; | ||
| 661 | return retval; | ||
| 662 | } | ||
| 663 | #endif | ||
| 664 | |||
| 665 | static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc, | ||
| 666 | const char *msg, const char *skip) | ||
| 667 | { | ||
| 668 | unsigned char *ln; | ||
| 669 | unsigned char *cp; | ||
| 670 | unsigned char *end; | ||
| 671 | unsigned int size; | ||
| 672 | unsigned char version; | ||
| 673 | unsigned int min_insn_length; | ||
| 674 | unsigned int max_ops_per_insn; | ||
| 675 | int line_base; | ||
| 676 | unsigned int line_range; | ||
| 677 | unsigned int opcode_base; | ||
| 678 | unsigned int opindex; | ||
| 679 | unsigned int col; | ||
| 680 | unsigned int i; | ||
| 681 | unsigned int len; | ||
| 682 | unsigned int dir_size; | ||
| 683 | #if 0 | ||
| 684 | char *dirs[DIR_TABLE_SIZE]; | ||
| 685 | #endif | ||
| 686 | unsigned int filename_size; | ||
| 687 | struct dwarf_filename_struct { | ||
| 688 | unsigned int dir_entry; | ||
| 689 | char *name; | ||
| 690 | } filename_table[FILE_TABLE_SIZE]; | ||
| 691 | addr_t last_pc; | ||
| 692 | addr_t pc; | ||
| 693 | addr_t func_addr; | ||
| 694 | int line; | ||
| 695 | char *filename; | ||
| 696 | char *function; | ||
| 697 | ElfW(Sym) *esym; | ||
| 698 | |||
| 699 | next: | ||
| 700 | ln = rc->dwarf_line; | ||
| 701 | while (ln < rc->dwarf_line_end) { | ||
| 702 | dir_size = 0; | ||
| 703 | filename_size = 0; | ||
| 704 | last_pc = 0; | ||
| 705 | pc = 0; | ||
| 706 | func_addr = -1; | ||
| 707 | line = 1; | ||
| 708 | filename = NULL; | ||
| 709 | function = NULL; | ||
| 710 | size = dwarf_read_32(&ln, rc->dwarf_line_end); | ||
| 711 | end = ln + size; | ||
| 712 | version = DW_GETC(ln, end); | ||
| 713 | version += DW_GETC(ln, end) << 8; | ||
| 714 | if (version >= 5) | ||
| 715 | ln += 6; // address size, segment selector, prologue Length | ||
| 716 | else | ||
| 717 | ln += 4; // prologue Length | ||
| 718 | min_insn_length = DW_GETC(ln, end); | ||
| 719 | if (version >= 4) | ||
| 720 | max_ops_per_insn = DW_GETC(ln, end); | ||
| 721 | else | ||
| 722 | max_ops_per_insn = 1; | ||
| 723 | ln++; // Initial value of 'is_stmt' | ||
| 724 | line_base = DW_GETC(ln, end); | ||
| 725 | line_base |= line_base >= 0x80 ? ~0xff : 0; | ||
| 726 | line_range = DW_GETC(ln, end); | ||
| 727 | opcode_base = DW_GETC(ln, end); | ||
| 728 | opindex = 0; | ||
| 729 | ln += 12; | ||
| 730 | if (version >= 5) { | ||
| 731 | col = DW_GETC(ln, end); | ||
| 732 | for (i = 0; i < col * 2; i++) | ||
| 733 | dwarf_read_uleb128(&ln, end); | ||
| 734 | dir_size = dwarf_read_uleb128(&ln, end); | ||
| 735 | for (i = 0; i < dir_size; i++) | ||
| 736 | #if 0 | ||
| 737 | if (i < DIR_TABLE_SIZE) | ||
| 738 | dirs[i] = (char *)rc->dwarf_line_str + dwarf_read_32(&ln, end); | ||
| 739 | else | ||
| 740 | #endif | ||
| 741 | dwarf_read_32(&ln, end); | ||
| 742 | col = DW_GETC(ln, end); | ||
| 743 | for (i = 0; i < col * 2; i++) | ||
| 744 | dwarf_read_uleb128(&ln, end); | ||
| 745 | filename_size = dwarf_read_uleb128(&ln, end); | ||
| 746 | for (i = 0; i < filename_size; i++) | ||
| 747 | if (i < FILE_TABLE_SIZE) { | ||
| 748 | filename_table[i].name = (char *)rc->dwarf_line_str + dwarf_read_32(&ln, end); | ||
| 749 | filename_table[i].dir_entry = dwarf_read_uleb128(&ln, end); | ||
| 750 | } | ||
| 751 | else { | ||
| 752 | dwarf_read_32(&ln, end); | ||
| 753 | dwarf_read_uleb128(&ln, end); | ||
| 754 | } | ||
| 755 | } | ||
| 756 | else { | ||
| 757 | while ((i = DW_GETC(ln, end))) { | ||
| 758 | #if 0 | ||
| 759 | if (++dir_size < DIR_TABLE_SIZE) | ||
| 760 | dirs[dir_size - 1] = (char *)ln - 1; | ||
| 761 | #endif | ||
| 762 | while (DW_GETC(ln, end)) {} | ||
| 763 | } | ||
| 764 | while ((i = DW_GETC(ln, end))) { | ||
| 765 | if (++filename_size < FILE_TABLE_SIZE) { | ||
| 766 | filename_table[filename_size - 1].name = (char *)ln - 1; | ||
| 767 | while (DW_GETC(ln, end)) {} | ||
| 768 | filename_table[filename_size - 1].dir_entry = | ||
| 769 | dwarf_read_uleb128(&ln, end); | ||
| 770 | } | ||
| 771 | else { | ||
| 772 | while (DW_GETC(ln, end)) {} | ||
| 773 | dwarf_read_uleb128(&ln, end); | ||
| 774 | } | ||
| 775 | dwarf_read_uleb128(&ln, end); // time | ||
| 776 | dwarf_read_uleb128(&ln, end); // size | ||
| 777 | } | ||
| 778 | } | ||
| 779 | while (ln < end) { | ||
| 780 | last_pc = pc; | ||
| 781 | switch (DW_GETC(ln, end)) { | ||
| 782 | case 0: | ||
| 783 | len = dwarf_read_uleb128(&ln, end); | ||
| 784 | cp = ln; | ||
| 785 | ln += len; | ||
| 786 | if (len == 0) | ||
| 787 | goto next_line; | ||
| 788 | switch (DW_GETC(cp, end)) { | ||
| 789 | case DW_LNE_end_sequence: | ||
| 790 | goto next_line; | ||
| 791 | case DW_LNE_set_address: | ||
| 792 | #if PTR_SIZE == 4 | ||
| 793 | dwarf_read_32(&cp, end); | ||
| 794 | #else | ||
| 795 | dwarf_read_64(&cp, end); | ||
| 796 | #endif | ||
| 797 | pc = rc->dwarf_text; | ||
| 798 | opindex = 0; | ||
| 799 | break; | ||
| 800 | case DW_LNE_define_file: /* deprecated */ | ||
| 801 | break; | ||
| 802 | case DW_LNE_set_discriminator: | ||
| 803 | dwarf_read_uleb128(&cp, end); | ||
| 804 | break; | ||
| 805 | case DW_LNE_hi_user - 1: | ||
| 806 | function = (char *)cp; | ||
| 807 | func_addr = pc; | ||
| 808 | break; | ||
| 809 | default: | ||
| 810 | break; | ||
| 811 | } | ||
| 812 | break; | ||
| 813 | case DW_LNS_copy: | ||
| 814 | break; | ||
| 815 | case DW_LNS_advance_pc: | ||
| 816 | if (max_ops_per_insn == 1) | ||
| 817 | pc += dwarf_read_uleb128(&ln, end) * min_insn_length; | ||
| 818 | else { | ||
| 819 | unsigned long long off = dwarf_read_uleb128(&ln, end); | ||
| 820 | |||
| 821 | pc += (opindex + off) / max_ops_per_insn * | ||
| 822 | min_insn_length; | ||
| 823 | opindex = (opindex + off) % max_ops_per_insn; | ||
| 824 | } | ||
| 825 | i = 0; | ||
| 826 | goto check_pc; | ||
| 827 | case DW_LNS_advance_line: | ||
| 828 | line += dwarf_read_sleb128(&ln, end); | ||
| 829 | break; | ||
| 830 | case DW_LNS_set_file: | ||
| 831 | i = dwarf_read_uleb128(&ln, end); | ||
| 832 | if (i < FILE_TABLE_SIZE && i < filename_size) | ||
| 833 | filename = filename_table[i].name; | ||
| 834 | break; | ||
| 835 | case DW_LNS_set_column: | ||
| 836 | dwarf_read_uleb128(&ln, end); | ||
| 837 | break; | ||
| 838 | case DW_LNS_negate_stmt: | ||
| 839 | break; | ||
| 840 | case DW_LNS_set_basic_block: | ||
| 841 | break; | ||
| 842 | case DW_LNS_const_add_pc: | ||
| 843 | if (max_ops_per_insn == 1) | ||
| 844 | pc += ((255 - opcode_base) / line_range) * min_insn_length; | ||
| 845 | else { | ||
| 846 | unsigned int off = (255 - opcode_base) / line_range; | ||
| 847 | |||
| 848 | pc += ((opindex + off) / max_ops_per_insn) * | ||
| 849 | min_insn_length; | ||
| 850 | opindex = (opindex + off) % max_ops_per_insn; | ||
| 851 | } | ||
| 852 | i = 0; | ||
| 853 | goto check_pc; | ||
| 854 | case DW_LNS_fixed_advance_pc: | ||
| 855 | i = DW_GETC(ln, end); | ||
| 856 | i += DW_GETC(ln, end) << 8; | ||
| 857 | pc += i; | ||
| 858 | opindex = 0; | ||
| 859 | i = 0; | ||
| 860 | goto check_pc; | ||
| 861 | case DW_LNS_set_prologue_end: | ||
| 862 | break; | ||
| 863 | case DW_LNS_set_epilogue_begin: | ||
| 864 | break; | ||
| 865 | case DW_LNS_set_isa: | ||
| 866 | dwarf_read_uleb128(&ln, end); | ||
| 867 | break; | ||
| 868 | default: | ||
| 869 | i = ln[-1]; | ||
| 870 | if (max_ops_per_insn == 1) | ||
| 871 | pc += ((i - opcode_base) / line_range) * min_insn_length; | ||
| 872 | else { | ||
| 873 | pc += (opindex + (i - opcode_base) / line_range) / | ||
| 874 | max_ops_per_insn * min_insn_length; | ||
| 875 | opindex = (opindex + (i - opcode_base) / line_range) % | ||
| 876 | max_ops_per_insn; | ||
| 877 | } | ||
| 878 | i = (int)((i - opcode_base) % line_range) + line_base; | ||
| 879 | check_pc: | ||
| 880 | if (pc >= wanted_pc && wanted_pc >= last_pc) | ||
| 881 | goto found; | ||
| 882 | line += i; | ||
| 883 | break; | ||
| 884 | } | ||
| 885 | } | ||
| 886 | next_line: | ||
| 887 | ln = end; | ||
| 888 | } | ||
| 889 | |||
| 890 | filename = NULL; | ||
| 891 | function = NULL; | ||
| 892 | func_addr = -1; | ||
| 893 | |||
| 894 | /* we try symtab symbols (no line number info) */ | ||
| 895 | for (esym = rc->esym_start + 1; esym < rc->esym_end; ++esym) { | ||
| 896 | int type = ELFW(ST_TYPE)(esym->st_info); | ||
| 897 | if (type == STT_FUNC || type == STT_GNU_IFUNC) { | ||
| 898 | if (wanted_pc >= esym->st_value && | ||
| 899 | wanted_pc < esym->st_value + esym->st_size) { | ||
| 900 | function = rc->elf_str + esym->st_name; | ||
| 901 | func_addr = esym->st_value; | ||
| 902 | goto found; | ||
| 903 | } | ||
| 904 | } | ||
| 905 | } | ||
| 906 | |||
| 907 | if ((rc = rc->next)) | ||
| 908 | goto next; | ||
| 909 | |||
| 910 | found: | ||
| 911 | if (filename) { | ||
| 912 | if (skip[0] && strstr(filename, skip)) | ||
| 913 | return (addr_t)-1; | ||
| 914 | rt_printf("%s:%d: ", filename, line); | ||
| 915 | } | ||
| 916 | else | ||
| 917 | rt_printf("0x%08llx : ", (long long)wanted_pc); | ||
| 918 | rt_printf("%s %s", msg, function ? function : "???"); | ||
| 919 | return (addr_t)func_addr; | ||
| 920 | } | ||
| 921 | |||
| 574 | static int rt_get_caller_pc(addr_t *paddr, rt_context *rc, int level); | 922 | static int rt_get_caller_pc(addr_t *paddr, rt_context *rc, int level); |
| 575 | 923 | ||
| 576 | static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap) | 924 | static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap) |
| @@ -603,7 +951,10 @@ static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap) · 26 unmodified lines | |||
| 603 | ret = rt_get_caller_pc(&pc, rc, i); | 951 | ret = rt_get_caller_pc(&pc, rc, i); |
| 604 | a = "%s"; | 952 | a = "%s"; |
| 605 | if (ret != -1) { | 953 | if (ret != -1) { |
| 606 | pc = rt_printline(rc, pc, level ? "by" : "at", skip); | 954 | if ((addr_t)rc->dwarf_text) |
| 955 | pc = rt_printline_dwarf(rc, pc, level ? "by" : "at", skip); | ||
| 956 | else | ||
| 957 | pc = rt_printline(rc, pc, level ? "by" : "at", skip); | ||
| 607 | if (pc == (addr_t)-1) | 958 | if (pc == (addr_t)-1) |
| 608 | continue; | 959 | continue; |
| 609 | a = ": %s"; | 960 | a = ": %s"; |
| @@ -0,0 +1,13 @@ | |||
| 1 | /* test bound checking code without -run */ | ||
| 2 | |||
| 3 | int arr[10]; | ||
| 4 | |||
| 5 | int | ||
| 6 | main(int argc, char **argv) | ||
| 7 | { | ||
| 8 | int i; | ||
| 9 | |||
| 10 | for (i = 0; i <= sizeof(arr)/sizeof(arr[0]); i++) | ||
| 11 | arr[i] = 0; | ||
| 12 | return 0; | ||
| 13 | } | ||
| @@ -0,0 +1,2 @@ | |||
| 1 | 126_bound_global.c:11: at main: BCHECK: ........ is outside of the region | ||
| 2 | 126_bound_global.c:11: at main: RUNTIME ERROR: invalid memory access | ||
| @@ -58,6 +58,9 @@ ifneq (,$(filter OpenBSD FreeBSD NetBSD,$(TARGETOS))) · 57 unmodified lines | |||
| 58 | SKIP += 114_bound_signal.test # libc problem signal/fork | 58 | SKIP += 114_bound_signal.test # libc problem signal/fork |
| 59 | SKIP += 116_bound_setjmp2.test # No TLS_FUNC/TLS_VAR in bcheck.c | 59 | SKIP += 116_bound_setjmp2.test # No TLS_FUNC/TLS_VAR in bcheck.c |
| 60 | endif | 60 | endif |
| 61 | ifneq (,$(filter Darwin,$(TARGETOS))) | ||
| 62 | SKIP += 126_bound_global.test # bt-exe.c problem on apple | ||
| 63 | endif | ||
| 61 | 64 | ||
| 62 | # Some tests might need arguments | 65 | # Some tests might need arguments |
| 63 | ARGS = | 66 | ARGS = |
| @@ -100,7 +103,7 @@ GEN-ALWAYS = · 36 unmodified lines | |||
| 100 | 108_constructor.test: NORUN = true | 103 | 108_constructor.test: NORUN = true |
| 101 | 104 | ||
| 102 | 112_backtrace.test: FLAGS += -dt -b | 105 | 112_backtrace.test: FLAGS += -dt -b |
| 103 | 112_backtrace.test 113_btdll.test: FILTER += \ | 106 | 112_backtrace.test 113_btdll.test 126_bound_global.test: FILTER += \ |
| 104 | -e 's;[0-9A-Fa-fx]\{5,\};........;g' \ | 107 | -e 's;[0-9A-Fa-fx]\{5,\};........;g' \ |
| 105 | -e 's;0x[0-9A-Fa-f]\{1,\};0x?;g' | 108 | -e 's;0x[0-9A-Fa-f]\{1,\};0x?;g' |
| 106 | 109 | ||
| @@ -122,6 +125,8 @@ ifneq ($(CONFIG_bcheck),no) · 15 unmodified lines | |||
| 122 | endif | 125 | endif |
| 123 | 125_atomic_misc.test: FLAGS += -dt | 126 | 125_atomic_misc.test: FLAGS += -dt |
| 124 | 124_atomic_counter.test: FLAGS += -pthread | 127 | 124_atomic_counter.test: FLAGS += -pthread |
| 128 | 126_bound_global.test: FLAGS += -b | ||
| 129 | 126_bound_global.test: NORUN = true | ||
| 125 | 130 | ||
| 126 | # Filter source directory in warnings/errors (out-of-tree builds) | 131 | # Filter source directory in warnings/errors (out-of-tree builds) |
| 127 | FILTER = 2>&1 | sed -e 's,$(SRC)/,,g' | 132 | FILTER = 2>&1 | sed -e 's,$(SRC)/,,g' |
| @@ -701,7 +701,7 @@ static void gen_bounds_epilog(void) · 700 unmodified lines | |||
| 701 | *bounds_ptr = 0; | 701 | *bounds_ptr = 0; |
| 702 | 702 | ||
| 703 | sym_data = get_sym_ref(&char_pointer_type, lbounds_section, | 703 | sym_data = get_sym_ref(&char_pointer_type, lbounds_section, |
| 704 | func_bound_offset, lbounds_section->data_offset); | 704 | func_bound_offset, PTR_SIZE); |
| 705 | 705 | ||
| 706 | /* generate bound local allocation */ | 706 | /* generate bound local allocation */ |
| 707 | if (offset_modified) { | 707 | if (offset_modified) { |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | /* relocation type for 32 bit data relocation */ | 5 | /* relocation type for 32 bit data relocation */ |
| 6 | #define R_DATA_32 R_X86_64_32S | 6 | #define R_DATA_32 R_X86_64_32S |
| 7 | #define R_DATA_32U R_X86_64_32 | ||
| 7 | #define R_DATA_PTR R_X86_64_64 | 8 | #define R_DATA_PTR R_X86_64_64 |
| 8 | #define R_JMP_SLOT R_X86_64_JUMP_SLOT | 9 | #define R_JMP_SLOT R_X86_64_JUMP_SLOT |
| 9 | #define R_GLOB_DAT R_X86_64_GLOB_DAT | 10 | #define R_GLOB_DAT R_X86_64_GLOB_DAT |