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 | 24 | config*.mak |
| 25 | 25 | config.texi |
| 26 | 26 | conftest* |
| 27 | +c2str | |
| 27 | 28 | tags |
| 28 | 29 | TAGS |
| 29 | 30 | tcc.1 |
| @@ -866,7 +866,7 @@ static void gen_bounds_epilog(void) · 865 unmodified lines | ||
| 866 | 866 | *bounds_ptr = 0; |
| 867 | 867 | |
| 868 | 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 | 871 | /* generate bound local allocation */ |
| 872 | 872 | if (offset_modified) { |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | /* relocation type for 32 bit data relocation */ |
| 6 | 6 | #define R_DATA_32 R_ARM_ABS32 |
| 7 | +#define R_DATA_32U R_ARM_ABS32 | |
| 7 | 8 | #define R_DATA_PTR R_ARM_ABS32 |
| 8 | 9 | #define R_JMP_SLOT R_ARM_JUMP_SLOT |
| 9 | 10 | #define R_GLOB_DAT R_ARM_GLOB_DAT |
| @@ -710,7 +710,7 @@ static void gen_bounds_epilog(void) · 709 unmodified lines | ||
| 710 | 710 | *bounds_ptr = 0; |
| 711 | 711 | |
| 712 | 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 | 715 | /* generate bound local allocation */ |
| 716 | 716 | if (offset_modified) { |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | #define EM_TCC_TARGET EM_AARCH64 |
| 4 | 4 | |
| 5 | 5 | #define R_DATA_32 R_AARCH64_ABS32 |
| 6 | +#define R_DATA_32U R_AARCH64_ABS32 | |
| 6 | 7 | #define R_DATA_PTR R_AARCH64_ABS64 |
| 7 | 8 | #define R_JMP_SLOT R_AARCH64_JUMP_SLOT |
| 8 | 9 | #define R_GLOB_DAT R_AARCH64_GLOB_DAT |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | /* relocation type for 32 bit data relocation */ |
| 6 | 6 | #define R_DATA_32 R_C60_32 |
| 7 | +#define R_DATA_32U R_C60_32 | |
| 7 | 8 | #define R_DATA_PTR R_C60_32 |
| 8 | 9 | #define R_JMP_SLOT R_C60_JMP_SLOT |
| 9 | 10 | #define R_GLOB_DAT R_C60_GLOB_DAT |
| @@ -51,6 +51,7 @@ ar_set= · 50 unmodified lines | ||
| 51 | 51 | darwin= |
| 52 | 52 | cpu= |
| 53 | 53 | cpuver= |
| 54 | +dwarf= | |
| 54 | 55 | |
| 55 | 56 | # OS specific |
| 56 | 57 | cpu_sys=`uname -m` |
| @@ -136,6 +137,8 @@ for opt do · 79 unmodified lines | ||
| 136 | 137 | ;; |
| 137 | 138 | --cpu=*) cpu=`echo $opt | cut -d '=' -f 2-` |
| 138 | 139 | ;; |
| 140 | + --dwarf=*) dwarf=`echo $opt | cut -d '=' -f 2-` | |
| 141 | + ;; | |
| 139 | 142 | --enable-cross) confvars="$confvars cross" |
| 140 | 143 | ;; |
| 141 | 144 | --disable-static) confvars="$confvars static=no" |
| @@ -328,6 +331,7 @@ Advanced options (experts only): · 186 unmodified lines | ||
| 328 | 331 | --config-backtrace=no disable stack backtraces (with -run or -bt) |
| 329 | 332 | --config-bcheck=no disable bounds checker (-b) |
| 330 | 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 | 335 | EOF |
| 332 | 336 | exit 1 |
| 333 | 337 | fi |
| @@ -493,6 +497,7 @@ print_mak CONFIG_TCC_ELFINTERP "$tcc_elfinterp" · 159 unmodified lines | ||
| 493 | 497 | print_mak CONFIG_LDDIR "$tcc_lddir" |
| 494 | 498 | print_mak CONFIG_TRIPLET "$triplet" |
| 495 | 499 | print_mak TCC_CPU_VERSION "$cpuver" num |
| 500 | +print_mak CONFIG_DWARF "$dwarf" | |
| 496 | 501 | |
| 497 | 502 | echo "ARCH=$cpu" >> config.mak |
| 498 | 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 | 1071 | *bounds_ptr = 0; |
| 1072 | 1072 | |
| 1073 | 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 | 1076 | /* generate bound local allocation */ |
| 1077 | 1077 | if (offset_modified) { |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | /* relocation type for 32 bit data relocation */ |
| 6 | 6 | #define R_DATA_32 R_386_32 |
| 7 | +#define R_DATA_32U R_386_32 | |
| 7 | 8 | #define R_DATA_PTR R_386_32 |
| 8 | 9 | #define R_JMP_SLOT R_386_JMP_SLOT |
| 9 | 10 | #define R_GLOB_DAT R_386_GLOB_DAT |
| @@ -27,7 +27,7 @@ arm-libtcc1-usegcc ?= no · 26 unmodified lines | ||
| 27 | 27 | ifeq "$($(T)-libtcc1-usegcc)" "yes" |
| 28 | 28 | XCC = $(CC) |
| 29 | 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 | 31 | endif |
| 32 | 32 | |
| 33 | 33 | ifneq ($(CONFIG_backtrace),no) |
| @@ -18,6 +18,10 @@ void __bt_init(rt_context *p, int num_callers) · 17 unmodified lines | ||
| 18 | 18 | __attribute__((weak)) void __bound_init(void*, int); |
| 19 | 19 | struct rt_context *rc = &g_rtctxt; |
| 20 | 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 | 25 | if (num_callers) { |
| 22 | 26 | memcpy(rc, p, offsetof(rt_context, next)); |
| 23 | 27 | rc->num_callers = num_callers - 1; |
| @@ -1722,6 +1722,12 @@ static void args_parser_listfile(TCCState *s, · 1721 unmodified lines | ||
| 1722 | 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 | 1731 | PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind) |
| 1726 | 1732 | { |
| 1727 | 1733 | TCCState *s1 = s; |
| @@ -1819,6 +1825,7 @@ reparse: · 91 unmodified lines | ||
| 1819 | 1825 | s->rt_num_callers = atoi(optarg); |
| 1820 | 1826 | s->do_backtrace = 1; |
| 1821 | 1827 | s->do_debug = 1; |
| 1828 | + s->dwarf = DWARF_VERSION; | |
| 1822 | 1829 | break; |
| 1823 | 1830 | #endif |
| 1824 | 1831 | #ifdef CONFIG_TCC_BCHECK |
| @@ -1826,16 +1833,22 @@ reparse: · 1 unmodified line | ||
| 1826 | 1833 | s->do_bounds_check = 1; |
| 1827 | 1834 | s->do_backtrace = 1; |
| 1828 | 1835 | s->do_debug = 1; |
| 1836 | + s->dwarf = DWARF_VERSION; | |
| 1829 | 1837 | break; |
| 1830 | 1838 | #endif |
| 1831 | 1839 | case TCC_OPTION_g: |
| 1832 | 1840 | /* Use "-g" as alias for "-g1". Use "-g0" to disable debug */ |
| 1833 | 1841 | /* Other common used values: "-g0", "-g1", "-g2" and "-g3" */ |
| 1834 | 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 | 1851 | s->do_debug = atoi(optarg); |
| 1837 | − else | |
| 1838 | − s->do_debug = 1; | |
| 1839 | 1852 | break; |
| 1840 | 1853 | case TCC_OPTION_c: |
| 1841 | 1854 | x = TCC_OUTPUT_OBJ; |
| @@ -471,7 +471,7 @@ static void gen_bounds_epilog(void) · 470 unmodified lines | ||
| 471 | 471 | *bounds_ptr = 0; |
| 472 | 472 | |
| 473 | 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 | 476 | label.type.t = VT_VOID | VT_STATIC; |
| 477 | 477 | /* generate bound local allocation */ |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | #define EM_TCC_TARGET EM_RISCV |
| 4 | 4 | |
| 5 | 5 | #define R_DATA_32 R_RISCV_32 |
| 6 | +#define R_DATA_32U R_RISCV_32 | |
| 6 | 7 | #define R_DATA_PTR R_RISCV_64 |
| 7 | 8 | #define R_JMP_SLOT R_RISCV_JUMP_SLOT |
| 8 | 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 | 349 | Debugger options: |
| 350 | 350 | |
| 351 | 351 | @table @option |
| 352 | −@item -g | |
| 353 | −Generate run time debug information so that you get clear run time | |
| 352 | +@item -g[x] | |
| 353 | +Generate run time stab debug information so that you get clear run time | |
| 354 | 354 | error messages: @code{ test.c:68: in function 'test5()': dereferencing |
| 355 | 355 | invalid pointer} instead of the laconic @code{Segmentation |
| 356 | 356 | fault}. |
| 357 | 357 | |
| 358 | +@item -gdwarf[-x] | |
| 359 | +Generate run time dwarf debug information instead of stab debug information. | |
| 360 | + | |
| 358 | 361 | @item -b |
| 359 | 362 | Generate additional support code to check memory allocations and array/pointer |
| 360 | 363 | bounds (@pxref{Bounds}). @option{-g} is implied. |
| @@ -58,7 +58,8 @@ static const char help[] = · 57 unmodified lines | ||
| 58 | 58 | " -soname set name for shared library to be used at runtime\n" |
| 59 | 59 | " -Wl,-opt[=val] set linker option (see tcc -hh)\n" |
| 60 | 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 | 63 | #ifdef CONFIG_TCC_BCHECK |
| 63 | 64 | " -b compile with built-in memory and bounds checker (implies -g)\n" |
| 64 | 65 | #endif |
| @@ -368,6 +368,7 @@ extern long double strtold (const char *__nptr, char **__endptr); · 367 unmodified lines | ||
| 368 | 368 | #include "libtcc.h" |
| 369 | 369 | #include "elf.h" |
| 370 | 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 | 794 | /* compile with debug symbol (and use them if error during execution) */ |
| 794 | 795 | unsigned char do_debug; |
| 796 | + unsigned char dwarf; | |
| 795 | 797 | unsigned char do_backtrace; |
| 796 | 798 | #ifdef CONFIG_TCC_BCHECK |
| 797 | 799 | /* compile with built-in memory and bounds checker */ |
| @@ -922,6 +924,12 @@ struct TCCState { · 124 unmodified lines | ||
| 922 | 924 | Section *symtab_section; |
| 923 | 925 | /* debug sections */ |
| 924 | 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 | 933 | /* Is there a new undefined sym since last new_undef_sym() */ |
| 926 | 934 | int new_undef_sym; |
| 927 | 935 | |
| @@ -1822,6 +1830,12 @@ ST_FUNC void post_sem(TCCSem *p); · 894 unmodified lines | ||
| 1822 | 1830 | #define symtab_section TCC_STATE_VAR(symtab_section) |
| 1823 | 1831 | #define stab_section TCC_STATE_VAR(stab_section) |
| 1824 | 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 | 1839 | #define gnu_ext TCC_STATE_VAR(gnu_ext) |
| 1826 | 1840 | #define tcc_error_noabort TCC_SET_STATE(_tcc_error_noabort) |
| 1827 | 1841 | #define tcc_error TCC_SET_STATE(_tcc_error) |
| @@ -47,6 +47,8 @@ struct sym_version { · 46 unmodified lines | ||
| 47 | 47 | /* section is dynsymtab_section */ |
| 48 | 48 | #define SHF_DYNSYM 0x40000000 |
| 49 | 49 | |
| 50 | +#define DWARF_DEBUG(s) (!strncmp((s), ".debug_", sizeof(".debug_")-1)) | |
| 51 | + | |
| 50 | 52 | /* ------------------------------------------------------------------------- */ |
| 51 | 53 | |
| 52 | 54 | ST_FUNC void tccelf_new(TCCState *s) |
| @@ -102,12 +104,39 @@ ST_FUNC void tccelf_stab_new(TCCState *s) · 49 unmodified lines | ||
| 102 | 104 | if (s->do_backtrace && s->output_type != TCC_OUTPUT_MEMORY) |
| 103 | 105 | shf = SHF_ALLOC | SHF_WRITE; // SHF_WRITE needed for musl/SELINUX |
| 104 | 106 | #endif |
| 105 | − stab_section = new_section(s, ".stab", SHT_PROGBITS, shf); | |
| 106 | − stab_section->sh_entsize = sizeof(Stab_Sym); | |
| 107 | − stab_section->sh_addralign = sizeof ((Stab_Sym*)0)->n_value; | |
| 108 | − stab_section->link = new_section(s, ".stabstr", SHT_STRTAB, shf); | |
| 109 | − /* put first entry */ | |
| 110 | − put_stabs(s, "", 0, 0, 0, 0); | |
| 107 | + if (s->dwarf) { | |
| 108 | + dwarf_info_section = | |
| 109 | + new_section(s, ".debug_info", SHT_PROGBITS, shf); | |
| 110 | + dwarf_abbrev_section = | |
| 111 | + new_section(s, ".debug_abbrev", SHT_PROGBITS, shf); | |
| 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 | 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 | 973 | sym->st_value = 0; |
| 945 | 974 | else |
| 946 | 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 | 980 | /* add section base */ |
| 949 | 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 | 1362 | if (sec && offs == -1) |
| 1331 | 1363 | offs = sec->data_offset; |
| 1332 | 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 | 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 | 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 | 1432 | int c; |
| 1401 | − c = set_global_sym(s1, NULL, s, offs); | |
| 1433 | + c = set_global_sym(s1, name, s, offs); | |
| 1402 | 1434 | s = data_section; |
| 1403 | 1435 | put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c); |
| 1404 | 1436 | section_ptr_add(s, PTR_SIZE); |
| @@ -1415,16 +1447,29 @@ ST_FUNC void tcc_add_btstub(TCCState *s1) · 10 unmodified lines | ||
| 1415 | 1447 | section_ptr_add(s, -s->data_offset & (PTR_SIZE - 1)); |
| 1416 | 1448 | o = s->data_offset; |
| 1417 | 1449 | /* create (part of) a struct rt_context (see tccrun.c) */ |
| 1418 | − put_ptr(s1, stab_section, 0); | |
| 1419 | − put_ptr(s1, stab_section, -1); | |
| 1420 | − put_ptr(s1, stab_section->link, 0); | |
| 1450 | + if (s1->dwarf) { | |
| 1451 | + put_ptr(s1, dwarf_line_section, 0, "__dwarf_line"); | |
| 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 | 1466 | section_ptr_add(s, 3 * PTR_SIZE); |
| 1422 | 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 | 1469 | n = 2 * PTR_SIZE; |
| 1425 | 1470 | #ifdef CONFIG_TCC_BCHECK |
| 1426 | 1471 | if (s1->do_bounds_check) { |
| 1427 | − put_ptr(s1, bounds_section, 0); | |
| 1472 | + put_ptr(s1, bounds_section, 0, NULL); | |
| 1428 | 1473 | n -= PTR_SIZE; |
| 1429 | 1474 | } |
| 1430 | 1475 | #endif |
| @@ -1849,6 +1894,8 @@ static int set_sec_sizes(TCCState *s1) · 418 unmodified lines | ||
| 1849 | 1894 | /* when generating a DLL, we include relocations but |
| 1850 | 1895 | we may patch them */ |
| 1851 | 1896 | if (file_type == TCC_OUTPUT_DLL |
| 1897 | + /* Do not include dwarf relocatable sections. */ | |
| 1898 | + && !DWARF_DEBUG(s1->sections[s->sh_info]->name) | |
| 1852 | 1899 | && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) { |
| 1853 | 1900 | int count = prepare_dynamic_rel(s1, s); |
| 1854 | 1901 | if (count) { |
| @@ -2963,8 +3010,7 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 1108 unmodified lines | ||
| 2963 | 3010 | strcmp(strsec + sh->sh_name, ".stabstr") |
| 2964 | 3011 | ) |
| 2965 | 3012 | continue; |
| 2966 | − if (seencompressed | |
| 2967 | − && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1)) | |
| 3013 | + if (seencompressed && DWARF_DEBUG(strsec + sh->sh_name)) | |
| 2968 | 3014 | continue; |
| 2969 | 3015 | |
| 2970 | 3016 | sh = &shdr[i]; |
| @@ -142,52 +142,56 @@ static void init_prec(void); · 141 unmodified lines | ||
| 142 | 142 | |
| 143 | 143 | static const struct { |
| 144 | 144 | int type; |
| 145 | + int size; | |
| 146 | + int encoding; | |
| 145 | 147 | const char *name; |
| 146 | 148 | } default_debug[] = { |
| 147 | − { VT_INT, "int:t1=r1;-2147483648;2147483647;" }, | |
| 148 | − { VT_BYTE, "char:t2=r2;0;127;" }, | |
| 149 | + { VT_INT, 4, DW_ATE_signed, "int:t1=r1;-2147483648;2147483647;" }, | |
| 150 | + { VT_BYTE, 1, DW_ATE_signed_char, "char:t2=r2;0;127;" }, | |
| 149 | 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 | 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 | 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 | 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 | 159 | #else |
| 158 | 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 | 162 | #endif |
| 161 | − { VT_QLONG, "__int128:t6=r6;0;-1;" }, | |
| 162 | − { VT_QLONG | VT_UNSIGNED, "__int128 unsigned:t7=r7;0;-1;" }, | |
| 163 | − { VT_LLONG, "long long int:t8=r8;-9223372036854775808;9223372036854775807;" }, | |
| 164 | − { VT_LLONG | VT_UNSIGNED, "long long unsigned int:t9=r9;0;01777777777777777777777;" }, | |
| 165 | − { VT_SHORT, "short int:t10=r10;-32768;32767;" }, | |
| 166 | − { VT_SHORT | VT_UNSIGNED, "short unsigned int:t11=r11;0;65535;" }, | |
| 167 | − { VT_BYTE | VT_DEFSIGN, "signed char:t12=r12;-128;127;" }, | |
| 168 | − { VT_BYTE | VT_DEFSIGN | VT_UNSIGNED, "unsigned char:t13=r13;0;255;" }, | |
| 169 | − { VT_FLOAT, "float:t14=r1;4;0;" }, | |
| 170 | − { VT_DOUBLE, "double:t15=r1;8;0;" }, | |
| 163 | + { VT_QLONG, 16, DW_ATE_signed, "__int128:t6=r6;0;-1;" }, | |
| 164 | + { VT_QLONG | VT_UNSIGNED, 16, DW_ATE_unsigned, "__int128 unsigned:t7=r7;0;-1;" }, | |
| 165 | + { VT_LLONG, 8, DW_ATE_signed, "long long int:t8=r8;-9223372036854775808;9223372036854775807;" }, | |
| 166 | + { VT_LLONG | VT_UNSIGNED, 8, DW_ATE_unsigned, "long long unsigned int:t9=r9;0;01777777777777777777777;" }, | |
| 167 | + { VT_SHORT, 2, DW_ATE_signed, "short int:t10=r10;-32768;32767;" }, | |
| 168 | + { VT_SHORT | VT_UNSIGNED, 2, DW_ATE_unsigned, "short unsigned int:t11=r11;0;65535;" }, | |
| 169 | + { VT_BYTE | VT_DEFSIGN, 1, DW_ATE_signed_char, "signed char:t12=r12;-128;127;" }, | |
| 170 | + { VT_BYTE | VT_DEFSIGN | VT_UNSIGNED, 1, DW_ATE_unsigned_char, "unsigned char:t13=r13;0;255;" }, | |
| 171 | + { VT_FLOAT, 4, DW_ATE_float, "float:t14=r1;4;0;" }, | |
| 172 | + { VT_DOUBLE, 8, DW_ATE_float, "double:t15=r1;8;0;" }, | |
| 171 | 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 | 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 | 177 | #endif |
| 176 | − { -1, "_Float32:t17=r1;4;0;" }, | |
| 177 | − { -1, "_Float64:t18=r1;8;0;" }, | |
| 178 | − { -1, "_Float128:t19=r1;16;0;" }, | |
| 179 | − { -1, "_Float32x:t20=r1;8;0;" }, | |
| 180 | − { -1, "_Float64x:t21=r1;16;0;" }, | |
| 181 | − { -1, "_Decimal32:t22=r1;4;0;" }, | |
| 182 | − { -1, "_Decimal64:t23=r1;8;0;" }, | |
| 183 | − { -1, "_Decimal128:t24=r1;16;0;" }, | |
| 178 | + { -1, -1, -1, "_Float32:t17=r1;4;0;" }, | |
| 179 | + { -1, -1, -1, "_Float64:t18=r1;8;0;" }, | |
| 180 | + { -1, -1, -1, "_Float128:t19=r1;16;0;" }, | |
| 181 | + { -1, -1, -1, "_Float32x:t20=r1;8;0;" }, | |
| 182 | + { -1, -1, -1, "_Float64x:t21=r1;16;0;" }, | |
| 183 | + { -1, -1, -1, "_Decimal32:t22=r1;4;0;" }, | |
| 184 | + { -1, -1, -1, "_Decimal64:t23=r1;8;0;" }, | |
| 185 | + { -1, -1, -1, "_Decimal128:t24=r1;16;0;" }, | |
| 184 | 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 | 188 | /* boolean type */ |
| 187 | − { VT_BOOL, "bool:t26=r26;0;255;" }, | |
| 188 | − { VT_VOID, "void:t27=27" }, | |
| 189 | + { VT_BOOL, 1, DW_ATE_unsigned_char, "bool:t26=r26;0;255;" }, | |
| 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 | 195 | static int debug_next_type; |
| 192 | 196 | |
| 193 | 197 | static struct debug_hash { |
| @@ -207,10 +211,231 @@ static struct debug_info { · 13 unmodified lines | ||
| 207 | 211 | char *str; |
| 208 | 212 | Section *sec; |
| 209 | 213 | int sym_index; |
| 214 | + int info; | |
| 215 | + int file; | |
| 216 | + int line; | |
| 210 | 217 | } *sym; |
| 211 | 218 | struct debug_info *child, *next, *last, *parent; |
| 212 | 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 | 439 | static struct { |
| 215 | 440 | unsigned long offset; |
| 216 | 441 | unsigned long last_file_name; |
| @@ -404,36 +629,323 @@ void pv (const char *lbl, int a, int b) · 187 unmodified lines | ||
| 404 | 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 | 811 | /* start of translation unit info */ |
| 408 | 812 | ST_FUNC void tcc_debug_start(TCCState *s1) |
| 409 | 813 | { |
| 410 | 814 | if (s1->do_debug) { |
| 411 | 815 | int i; |
| 816 | + char *filename = file->prev ? file->prev->filename : file->filename; | |
| 412 | 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 | 819 | getcwd(buf, sizeof(buf)); |
| 419 | 820 | #ifdef _WIN32 |
| 420 | 821 | normalize_slashes(buf); |
| 421 | 822 | #endif |
| 422 | 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 | 944 | new_file = last_line_num = 0; |
| 432 | 945 | func_ind = -1; |
| 433 | − debug_next_type = sizeof(default_debug) / sizeof(default_debug[0]); | |
| 946 | + debug_next_type = N_DEFAULT_DEBUG; | |
| 434 | 947 | debug_hash = NULL; |
| 435 | 948 | n_debug_hash = 0; |
| 436 | − | |
| 437 | 949 | /* we're currently 'including' the <command line> */ |
| 438 | 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 | 963 | if (!s1->do_debug) |
| 452 | 964 | return; |
| 453 | − put_stabs_r(s1, NULL, N_SO, 0, 0, | |
| 454 | − text_section->data_offset, text_section, section_sym); | |
| 965 | + if (s1->dwarf) { | |
| 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 | 1070 | tcc_free(debug_hash); |
| 456 | 1071 | } |
| 457 | 1072 | |
| @@ -462,8 +1077,10 @@ static BufferedFile* put_new_file(TCCState *s1) · 4 unmodified lines | ||
| 462 | 1077 | if (f->filename[0] == ':') |
| 463 | 1078 | f = f->prev; |
| 464 | 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 | 1082 | new_file = last_line_num = 0; |
| 1083 | + dwarf_file(s1); | |
| 467 | 1084 | } |
| 468 | 1085 | return f; |
| 469 | 1086 | } |
| @@ -475,6 +1092,7 @@ ST_FUNC void tcc_debug_putfile(TCCState *s1, const char *filename) · 5 unmodified lines | ||
| 475 | 1092 | return; |
| 476 | 1093 | pstrcpy(file->filename, sizeof(file->filename), filename); |
| 477 | 1094 | new_file = 1; |
| 1095 | + dwarf_file(s1); | |
| 478 | 1096 | } |
| 479 | 1097 | |
| 480 | 1098 | /* begin of #include */ |
| @@ -482,8 +1100,53 @@ ST_FUNC void tcc_debug_bincl(TCCState *s1) · 1 unmodified line | ||
| 482 | 1100 | { |
| 483 | 1101 | if (!s1->do_debug) |
| 484 | 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 | 1148 | new_file = 1; |
| 1149 | + dwarf_file(s1); | |
| 487 | 1150 | } |
| 488 | 1151 | |
| 489 | 1152 | /* end of #include */ |
| @@ -491,30 +1154,73 @@ ST_FUNC void tcc_debug_eincl(TCCState *s1) · 1 unmodified line | ||
| 491 | 1154 | { |
| 492 | 1155 | if (!s1->do_debug) |
| 493 | 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 | 1159 | new_file = 1; |
| 1160 | + dwarf_file(s1); | |
| 496 | 1161 | } |
| 497 | 1162 | |
| 498 | 1163 | /* generate line number info */ |
| 499 | 1164 | static void tcc_debug_line(TCCState *s1) |
| 500 | 1165 | { |
| 501 | 1166 | BufferedFile *f; |
| 1167 | + | |
| 502 | 1168 | if (!s1->do_debug |
| 503 | 1169 | || cur_text_section != text_section |
| 504 | 1170 | || !(f = put_new_file(s1)) |
| 505 | 1171 | || last_line_num == f->line_num) |
| 506 | 1172 | return; |
| 507 | − if (func_ind != -1) { | |
| 508 | − put_stabn(s1, N_SLINE, 0, f->line_num, ind - func_ind); | |
| 509 | − } else { | |
| 510 | − /* from tcc_assemble */ | |
| 511 | − put_stabs_r(s1, NULL, N_SLINE, 0, f->line_num, ind, text_section, section_sym); | |
| 1173 | + if (s1->dwarf) { | |
| 1174 | + int len_pc = (ind - dwarf_line.last_pc) / DWARF_MIN_INSTR_LEN; | |
| 1175 | + int len_line = f->line_num - dwarf_line.last_line; | |
| 1176 | + int n = len_pc * DWARF_LINE_RANGE + len_line + DWARF_OPCODE_BASE - DWARF_LINE_BASE; | |
| 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 | 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 | 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 | 1235 | s->str = tcc_strdup(str); |
| 530 | 1236 | s->sec = sec; |
| 531 | 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 | 1242 | else if (sec) |
| 534 | 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 | 1313 | static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) |
| 571 | 1314 | { |
| 572 | 1315 | int type; |
| @@ -585,22 +1328,12 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 12 unmodified lines | ||
| 585 | 1328 | break; |
| 586 | 1329 | } |
| 587 | 1330 | if ((type & VT_BTYPE) == VT_STRUCT) { |
| 588 | − int i; | |
| 1331 | + Sym *e = t; | |
| 589 | 1332 | |
| 590 | 1333 | t = t->type.ref; |
| 591 | − for (i = 0; i < n_debug_hash; i++) { | |
| 592 | − if (t == debug_hash[i].type) { | |
| 593 | − debug_type = debug_hash[i].debug_type; | |
| 594 | − break; | |
| 595 | − } | |
| 596 | − } | |
| 1334 | + debug_type = tcc_debug_find(t); | |
| 597 | 1335 | if (debug_type == -1) { |
| 598 | − debug_type = ++debug_next_type; | |
| 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; | |
| 1336 | + debug_type = tcc_debug_add(t, 0); | |
| 604 | 1337 | cstr_new (&str); |
| 605 | 1338 | cstr_printf (&str, "%s:T%d=%c%d", |
| 606 | 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 | 1360 | cstr_printf (&str, ",%d,%d;", pos, size); |
| 628 | 1361 | } |
| 629 | 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 | 1364 | cstr_free (&str); |
| 1365 | + if (debug_info) | |
| 1366 | + tcc_debug_remove(e); | |
| 632 | 1367 | } |
| 633 | 1368 | } |
| 634 | 1369 | else if (IS_ENUM(type)) { |
| 635 | 1370 | Sym *e = t = t->type.ref; |
| 636 | 1371 | |
| 637 | − debug_type = ++debug_next_type; | |
| 638 | − cstr_new (&str); | |
| 639 | − cstr_printf (&str, "%s:T%d=e", | |
| 640 | − (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM | |
| 641 | − ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL), | |
| 642 | − debug_type); | |
| 643 | − while (t->next) { | |
| 644 | − t = t->next; | |
| 645 | − cstr_printf (&str, "%s:", | |
| 646 | − (t->v & ~SYM_FIELD) >= SYM_FIRST_ANOM | |
| 647 | − ? "" : get_tok_str(t->v & ~SYM_FIELD, NULL)); | |
| 648 | − cstr_printf (&str, e->type.t & VT_UNSIGNED ? "%u," : "%d,", | |
| 649 | − (int)t->enum_val); | |
| 650 | − } | |
| 651 | − cstr_printf (&str, ";"); | |
| 652 | − tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0); | |
| 653 | − cstr_free (&str); | |
| 1372 | + debug_type = tcc_debug_find(t); | |
| 1373 | + if (debug_type == -1) { | |
| 1374 | + debug_type = tcc_debug_add(t, 0); | |
| 1375 | + cstr_new (&str); | |
| 1376 | + cstr_printf (&str, "%s:T%d=e", | |
| 1377 | + (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM | |
| 1378 | + ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL), | |
| 1379 | + debug_type); | |
| 1380 | + while (t->next) { | |
| 1381 | + t = t->next; | |
| 1382 | + cstr_printf (&str, "%s:", | |
| 1383 | + (t->v & ~SYM_FIELD) >= SYM_FIRST_ANOM | |
| 1384 | + ? "" : get_tok_str(t->v & ~SYM_FIELD, NULL)); | |
| 1385 | + cstr_printf (&str, e->type.t & VT_UNSIGNED ? "%u," : "%d,", | |
| 1386 | + (int)t->enum_val); | |
| 1387 | + } | |
| 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 | 1395 | else if ((type & VT_BTYPE) != VT_FUNC) { |
| 656 | 1396 | type &= ~VT_STRUCT_MASK; |
| 657 | − for (debug_type = 1; | |
| 658 | − debug_type <= sizeof(default_debug) / sizeof(default_debug[0]); | |
| 659 | − debug_type++) | |
| 1397 | + for (debug_type = 1; debug_type <= N_DEFAULT_DEBUG; debug_type++) | |
| 660 | 1398 | if (default_debug[debug_type - 1].type == type) |
| 661 | 1399 | break; |
| 662 | − if (debug_type > sizeof(default_debug) / sizeof(default_debug[0])) | |
| 1400 | + if (debug_type > N_DEFAULT_DEBUG) | |
| 663 | 1401 | return; |
| 664 | 1402 | } |
| 665 | 1403 | if (n > 0) |
| @@ -686,8 +1424,263 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 20 unmodified lines | ||
| 686 | 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 | 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 | 1684 | while (cur) { |
| 692 | 1685 | int i; |
| 693 | 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 | 1713 | for (; s != e; s = s->prev) { |
| 721 | 1714 | if (!s->v || (s->r & VT_VALMASK) != VT_LOCAL) |
| 722 | 1715 | continue; |
| 723 | − cstr_reset (&debug_str); | |
| 724 | − cstr_printf (&debug_str, "%s:%s", get_tok_str(s->v, NULL), param ? "p" : ""); | |
| 725 | − tcc_get_debug_info(s1, s, &debug_str); | |
| 726 | − tcc_debug_stabs(s1, debug_str.data, param ? N_PSYM : N_LSYM, s->c, NULL, 0); | |
| 1716 | + if (s1->dwarf) { | |
| 1717 | + tcc_debug_stabs(s1, get_tok_str(s->v, NULL), | |
| 1718 | + 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 | 1730 | cstr_free (&debug_str); |
| 729 | 1731 | } |
| @@ -739,23 +1741,83 @@ static void tcc_debug_funcstart(TCCState *s1, Sym *sym) · 9 unmodified lines | ||
| 739 | 1741 | debug_info = NULL; |
| 740 | 1742 | tcc_debug_stabn(s1, N_LBRAC, ind - func_ind); |
| 741 | 1743 | if (!(f = put_new_file(s1))) |
| 742 | − 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 | − | |
| 1744 | + return; | |
| 749 | 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 | 1768 | /* put function size */ |
| 753 | 1769 | static void tcc_debug_funcend(TCCState *s1, int size) |
| 754 | 1770 | { |
| 1771 | + int func_sib = 0; | |
| 1772 | + | |
| 755 | 1773 | if (!s1->do_debug) |
| 756 | 1774 | return; |
| 1775 | + tcc_debug_line(s1); | |
| 757 | 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 | 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 | 1831 | if (sym_type == STT_FUNC || sym->v >= SYM_FIRST_ANOM) |
| 770 | 1832 | return; |
| 771 | 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 | 1860 | cstr_new (&str); |
| 774 | 1861 | cstr_printf (&str, "%s:%c", |
| 775 | − get_tok_str(sym->v, NULL), | |
| 776 | − sym_bind == STB_GLOBAL ? 'G' : local_scope ? 'V' : 'S' | |
| 777 | − ); | |
| 1862 | + get_tok_str(sym->v, NULL), | |
| 1863 | + sym_bind == STB_GLOBAL ? 'G' : local_scope ? 'V' : 'S' | |
| 1864 | + ); | |
| 778 | 1865 | tcc_get_debug_info(s1, sym, &str); |
| 779 | 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 | 1868 | else |
| 782 | 1869 | tcc_debug_stabs(s1, str.data, |
| 783 | 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 | 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 | 1879 | if (!s1->do_debug) |
| 793 | 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 | 1894 | cstr_new (&str); |
| 795 | 1895 | cstr_printf (&str, "%s:t", |
| 796 | 1896 | (sym->v & ~SYM_FIELD) >= SYM_FIRST_ANOM |
| 797 | 1897 | ? "" : get_tok_str(sym->v & ~SYM_FIELD, NULL)); |
| 798 | 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 | 1900 | cstr_free (&str); |
| 801 | 1901 | } |
| 802 | 1902 | |
| @@ -973,7 +2073,7 @@ ST_FUNC int tccgen_compile(TCCState *s1) · 170 unmodified lines | ||
| 973 | 2073 | const_wanted = 0; |
| 974 | 2074 | nocode_wanted = 0x80000000; |
| 975 | 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 | 2078 | tcc_debug_start(s1); |
| 979 | 2079 | tcc_tcov_start (); |
| @@ -27,8 +27,16 @@ · 26 unmodified lines | ||
| 27 | 27 | typedef struct rt_context |
| 28 | 28 | { |
| 29 | 29 | /* --> tccelf.c:tcc_add_btstub wants those below in that order: */ |
| 30 | − Stab_Sym *stab_sym, *stab_sym_end; | |
| 31 | − char *stab_str; | |
| 30 | + union { | |
| 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 | 40 | ElfW(Sym) *esym_start, *esym_end; |
| 33 | 41 | char *elf_str; |
| 34 | 42 | addr_t prog_base; |
| @@ -169,9 +177,18 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 134 unmodified lines | ||
| 169 | 177 | memset(rc, 0, sizeof *rc); |
| 170 | 178 | if (s1->do_debug) { |
| 171 | 179 | void *p; |
| 172 | − rc->stab_sym = (Stab_Sym *)stab_section->data; | |
| 173 | − rc->stab_sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset); | |
| 174 | − rc->stab_str = (char *)stab_section->link->data; | |
| 180 | + if (s1->dwarf) { | |
| 181 | + rc->dwarf_line = dwarf_line_section->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 | 192 | rc->esym_start = (ElfW(Sym) *)(symtab_section->data); |
| 176 | 193 | rc->esym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset); |
| 177 | 194 | rc->elf_str = (char *)symtab_section->link->data; |
| @@ -571,6 +588,337 @@ found: · 393 unmodified lines | ||
| 571 | 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 | 922 | static int rt_get_caller_pc(addr_t *paddr, rt_context *rc, int level); |
| 575 | 923 | |
| 576 | 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 | 951 | ret = rt_get_caller_pc(&pc, rc, i); |
| 604 | 952 | a = "%s"; |
| 605 | 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 | 958 | if (pc == (addr_t)-1) |
| 608 | 959 | continue; |
| 609 | 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 | 58 | SKIP += 114_bound_signal.test # libc problem signal/fork |
| 59 | 59 | SKIP += 116_bound_setjmp2.test # No TLS_FUNC/TLS_VAR in bcheck.c |
| 60 | 60 | endif |
| 61 | +ifneq (,$(filter Darwin,$(TARGETOS))) | |
| 62 | + SKIP += 126_bound_global.test # bt-exe.c problem on apple | |
| 63 | +endif | |
| 61 | 64 | |
| 62 | 65 | # Some tests might need arguments |
| 63 | 66 | ARGS = |
| @@ -100,7 +103,7 @@ GEN-ALWAYS = · 36 unmodified lines | ||
| 100 | 103 | 108_constructor.test: NORUN = true |
| 101 | 104 | |
| 102 | 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 | 107 | -e 's;[0-9A-Fa-fx]\{5,\};........;g' \ |
| 105 | 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 | 125 | endif |
| 123 | 126 | 125_atomic_misc.test: FLAGS += -dt |
| 124 | 127 | 124_atomic_counter.test: FLAGS += -pthread |
| 128 | +126_bound_global.test: FLAGS += -b | |
| 129 | +126_bound_global.test: NORUN = true | |
| 125 | 130 | |
| 126 | 131 | # Filter source directory in warnings/errors (out-of-tree builds) |
| 127 | 132 | FILTER = 2>&1 | sed -e 's,$(SRC)/,,g' |
| @@ -701,7 +701,7 @@ static void gen_bounds_epilog(void) · 700 unmodified lines | ||
| 701 | 701 | *bounds_ptr = 0; |
| 702 | 702 | |
| 703 | 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 | 706 | /* generate bound local allocation */ |
| 707 | 707 | if (offset_modified) { |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | /* relocation type for 32 bit data relocation */ |
| 6 | 6 | #define R_DATA_32 R_X86_64_32S |
| 7 | +#define R_DATA_32U R_X86_64_32 | |
| 7 | 8 | #define R_DATA_PTR R_X86_64_64 |
| 8 | 9 | #define R_JMP_SLOT R_X86_64_JUMP_SLOT |
| 9 | 10 | #define R_GLOB_DAT R_X86_64_GLOB_DAT |