History

Add dwarf support

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

herman ten brugge committed 4 years ago

Commit 2f2708a1 parent d3e940c26 files · +2754 −144Browse files

Unified · Split

26 files
  1. .gitignore +1 −0
  2. arm-gen.c +1 −1
  3. arm-link.c +1 −0
  4. arm64-gen.c +1 −1
  5. arm64-link.c +1 −0
  6. c67-link.c +1 −0
  7. configure +5 −0
  8. dwarf.h +1046 −0
  9. i386-gen.c +1 −1
  10. i386-link.c +1 −0
  11. lib/Makefile +1 −1
  12. lib/bt-exe.c +4 −0
  13. libtcc.c +16 −3
  14. riscv64-gen.c +1 −1
  15. riscv64-link.c +1 −0
  16. tcc-doc.texi +5 −2
  17. tcc.c +2 −1
  18. tcc.h +14 −0
  19. tccelf.c +63 −17
  20. tccgen.c +1208 −108
  21. tccrun.c +357 −6
  22. tests/tests2/126_bound_global.c +13 −0
  23. tests/tests2/126_bound_global.expect +2 −0
  24. tests/tests2/Makefile +6 −1
  25. x86_64-gen.c +1 −1
  26. x86_64-link.c +1 −0
.gitignore+1−0
@@ -24,6 +24,7 @@ config*.h · 23 unmodified lines
2424 config*.mak
2525 config.texi
2626 conftest*
27+c2str
2728 tags
2829 TAGS
2930 tcc.1
arm-gen.c+1−1
@@ -866,7 +866,7 @@ static void gen_bounds_epilog(void) · 865 unmodified lines
866866 *bounds_ptr = 0;
867867
868868 sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
869− func_bound_offset, lbounds_section->data_offset);
869+ func_bound_offset, PTR_SIZE);
870870
871871 /* generate bound local allocation */
872872 if (offset_modified) {
arm-link.c+1−0
@@ -4,6 +4,7 @@ · 3 unmodified lines
44
55 /* relocation type for 32 bit data relocation */
66 #define R_DATA_32 R_ARM_ABS32
7+#define R_DATA_32U R_ARM_ABS32
78 #define R_DATA_PTR R_ARM_ABS32
89 #define R_JMP_SLOT R_ARM_JUMP_SLOT
910 #define R_GLOB_DAT R_ARM_GLOB_DAT
arm64-gen.c+1−1
@@ -710,7 +710,7 @@ static void gen_bounds_epilog(void) · 709 unmodified lines
710710 *bounds_ptr = 0;
711711
712712 sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
713− func_bound_offset, lbounds_section->data_offset);
713+ func_bound_offset, PTR_SIZE);
714714
715715 /* generate bound local allocation */
716716 if (offset_modified) {
arm64-link.c+1−0
@@ -3,6 +3,7 @@ · 2 unmodified lines
33 #define EM_TCC_TARGET EM_AARCH64
44
55 #define R_DATA_32 R_AARCH64_ABS32
6+#define R_DATA_32U R_AARCH64_ABS32
67 #define R_DATA_PTR R_AARCH64_ABS64
78 #define R_JMP_SLOT R_AARCH64_JUMP_SLOT
89 #define R_GLOB_DAT R_AARCH64_GLOB_DAT
c67-link.c+1−0
@@ -4,6 +4,7 @@ · 3 unmodified lines
44
55 /* relocation type for 32 bit data relocation */
66 #define R_DATA_32 R_C60_32
7+#define R_DATA_32U R_C60_32
78 #define R_DATA_PTR R_C60_32
89 #define R_JMP_SLOT R_C60_JMP_SLOT
910 #define R_GLOB_DAT R_C60_GLOB_DAT
configure+5−0
@@ -51,6 +51,7 @@ ar_set= · 50 unmodified lines
5151 darwin=
5252 cpu=
5353 cpuver=
54+dwarf=
5455
5556 # OS specific
5657 cpu_sys=`uname -m`
@@ -136,6 +137,8 @@ for opt do · 79 unmodified lines
136137 ;;
137138 --cpu=*) cpu=`echo $opt | cut -d '=' -f 2-`
138139 ;;
140+ --dwarf=*) dwarf=`echo $opt | cut -d '=' -f 2-`
141+ ;;
139142 --enable-cross) confvars="$confvars cross"
140143 ;;
141144 --disable-static) confvars="$confvars static=no"
@@ -328,6 +331,7 @@ Advanced options (experts only): · 186 unmodified lines
328331 --config-backtrace=no disable stack backtraces (with -run or -bt)
329332 --config-bcheck=no disable bounds checker (-b)
330333 --config-predefs=no do not compile tccdefs.h, instead just include
334+ --dwarf=x Use dwarf debug info instead of stabs (x=2..5)
331335 EOF
332336 exit 1
333337 fi
@@ -493,6 +497,7 @@ print_mak CONFIG_TCC_ELFINTERP "$tcc_elfinterp" · 159 unmodified lines
493497 print_mak CONFIG_LDDIR "$tcc_lddir"
494498 print_mak CONFIG_TRIPLET "$triplet"
495499 print_mak TCC_CPU_VERSION "$cpuver" num
500+print_mak CONFIG_DWARF "$dwarf"
496501
497502 echo "ARCH=$cpu" >> config.mak
498503 echo "TARGETOS=$targetos" >> config.mak
dwarf.h+1046−0
@@ -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 */
i386-gen.c+1−1
@@ -1071,7 +1071,7 @@ static void gen_bounds_epilog(void) · 1070 unmodified lines
10711071 *bounds_ptr = 0;
10721072
10731073 sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
1074− func_bound_offset, lbounds_section->data_offset);
1074+ func_bound_offset, PTR_SIZE);
10751075
10761076 /* generate bound local allocation */
10771077 if (offset_modified) {
i386-link.c+1−0
@@ -4,6 +4,7 @@ · 3 unmodified lines
44
55 /* relocation type for 32 bit data relocation */
66 #define R_DATA_32 R_386_32
7+#define R_DATA_32U R_386_32
78 #define R_DATA_PTR R_386_32
89 #define R_JMP_SLOT R_386_JMP_SLOT
910 #define R_GLOB_DAT R_386_GLOB_DAT
lib/Makefile+1−1
@@ -27,7 +27,7 @@ arm-libtcc1-usegcc ?= no · 26 unmodified lines
2727 ifeq "$($(T)-libtcc1-usegcc)" "yes"
2828 XCC = $(CC)
2929 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
3131 endif
3232
3333 ifneq ($(CONFIG_backtrace),no)
lib/bt-exe.c+4−0
@@ -18,6 +18,10 @@ void __bt_init(rt_context *p, int num_callers) · 17 unmodified lines
1818 __attribute__((weak)) void __bound_init(void*, int);
1919 struct rt_context *rc = &g_rtctxt;
2020 //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);
2125 if (num_callers) {
2226 memcpy(rc, p, offsetof(rt_context, next));
2327 rc->num_callers = num_callers - 1;
libtcc.c+16−3
@@ -1722,6 +1722,12 @@ static void args_parser_listfile(TCCState *s, · 1721 unmodified lines
17221722 *pargc = s->argc = argc, *pargv = s->argv = argv;
17231723 }
17241724
1725+#ifdef CONFIG_DWARF
1726+#define DWARF_VERSION atoi(CONFIG_DWARF)
1727+#else
1728+#define DWARF_VERSION 0
1729+#endif
1730+
17251731 PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind)
17261732 {
17271733 TCCState *s1 = s;
@@ -1819,6 +1825,7 @@ reparse: · 91 unmodified lines
18191825 s->rt_num_callers = atoi(optarg);
18201826 s->do_backtrace = 1;
18211827 s->do_debug = 1;
1828+ s->dwarf = DWARF_VERSION;
18221829 break;
18231830 #endif
18241831 #ifdef CONFIG_TCC_BCHECK
@@ -1826,16 +1833,22 @@ reparse: · 1 unmodified line
18261833 s->do_bounds_check = 1;
18271834 s->do_backtrace = 1;
18281835 s->do_debug = 1;
1836+ s->dwarf = DWARF_VERSION;
18291837 break;
18301838 #endif
18311839 case TCC_OPTION_g:
18321840 /* Use "-g" as alias for "-g1". Use "-g0" to disable debug */
18331841 /* Other common used values: "-g0", "-g1", "-g2" and "-g3" */
18341842 /* 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))
18361851 s->do_debug = atoi(optarg);
1837− else
1838− s->do_debug = 1;
18391852 break;
18401853 case TCC_OPTION_c:
18411854 x = TCC_OUTPUT_OBJ;
riscv64-gen.c+1−1
@@ -471,7 +471,7 @@ static void gen_bounds_epilog(void) · 470 unmodified lines
471471 *bounds_ptr = 0;
472472
473473 sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
474− func_bound_offset, lbounds_section->data_offset);
474+ func_bound_offset, PTR_SIZE);
475475
476476 label.type.t = VT_VOID | VT_STATIC;
477477 /* generate bound local allocation */
riscv64-link.c+1−0
@@ -3,6 +3,7 @@ · 2 unmodified lines
33 #define EM_TCC_TARGET EM_RISCV
44
55 #define R_DATA_32 R_RISCV_32
6+#define R_DATA_32U R_RISCV_32
67 #define R_DATA_PTR R_RISCV_64
78 #define R_JMP_SLOT R_RISCV_JUMP_SLOT
89 #define R_GLOB_DAT R_RISCV_64
tcc-doc.texi+5−2
@@ -349,12 +349,15 @@ Turn on/off linking of all objects in archives. · 348 unmodified lines
349349 Debugger options:
350350
351351 @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
354354 error messages: @code{ test.c:68: in function 'test5()': dereferencing
355355 invalid pointer} instead of the laconic @code{Segmentation
356356 fault}.
357357
358+@item -gdwarf[-x]
359+Generate run time dwarf debug information instead of stab debug information.
360+
358361 @item -b
359362 Generate additional support code to check memory allocations and array/pointer
360363 bounds (@pxref{Bounds}). @option{-g} is implied.
tcc.c+2−1
@@ -58,7 +58,8 @@ static const char help[] = · 57 unmodified lines
5858 " -soname set name for shared library to be used at runtime\n"
5959 " -Wl,-opt[=val] set linker option (see tcc -hh)\n"
6060 "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"
6263 #ifdef CONFIG_TCC_BCHECK
6364 " -b compile with built-in memory and bounds checker (implies -g)\n"
6465 #endif
tcc.h+14−0
@@ -368,6 +368,7 @@ extern long double strtold (const char *__nptr, char **__endptr); · 367 unmodified lines
368368 #include "libtcc.h"
369369 #include "elf.h"
370370 #include "stab.h"
371+#include "dwarf.h"
371372
372373 /* -------------------------------------------- */
373374
@@ -792,6 +793,7 @@ struct TCCState { · 418 unmodified lines
792793
793794 /* compile with debug symbol (and use them if error during execution) */
794795 unsigned char do_debug;
796+ unsigned char dwarf;
795797 unsigned char do_backtrace;
796798 #ifdef CONFIG_TCC_BCHECK
797799 /* compile with built-in memory and bounds checker */
@@ -922,6 +924,12 @@ struct TCCState { · 124 unmodified lines
922924 Section *symtab_section;
923925 /* debug sections */
924926 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;
925933 /* Is there a new undefined sym since last new_undef_sym() */
926934 int new_undef_sym;
927935
@@ -1822,6 +1830,12 @@ ST_FUNC void post_sem(TCCSem *p); · 894 unmodified lines
18221830 #define symtab_section TCC_STATE_VAR(symtab_section)
18231831 #define stab_section TCC_STATE_VAR(stab_section)
18241832 #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)
18251839 #define gnu_ext TCC_STATE_VAR(gnu_ext)
18261840 #define tcc_error_noabort TCC_SET_STATE(_tcc_error_noabort)
18271841 #define tcc_error TCC_SET_STATE(_tcc_error)
tccelf.c+63−17
@@ -47,6 +47,8 @@ struct sym_version { · 46 unmodified lines
4747 /* section is dynsymtab_section */
4848 #define SHF_DYNSYM 0x40000000
4949
50+#define DWARF_DEBUG(s) (!strncmp((s), ".debug_", sizeof(".debug_")-1))
51+
5052 /* ------------------------------------------------------------------------- */
5153
5254 ST_FUNC void tccelf_new(TCCState *s)
@@ -102,12 +104,39 @@ ST_FUNC void tccelf_stab_new(TCCState *s) · 49 unmodified lines
102104 if (s->do_backtrace && s->output_type != TCC_OUTPUT_MEMORY)
103105 shf = SHF_ALLOC | SHF_WRITE; // SHF_WRITE needed for musl/SELINUX
104106 #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+ }
111140 }
112141
113142 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
944973 sym->st_value = 0;
945974 else
946975 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))) {
948980 /* add section base */
949981 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
950982 }
@@ -1330,7 +1362,7 @@ ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t · 379 unmodified lines
13301362 if (sec && offs == -1)
13311363 offs = sec->data_offset;
13321364 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);
13341366 }
13351367
13361368 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
13951427 }
13961428
13971429 #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)
13991431 {
14001432 int c;
1401− c = set_global_sym(s1, NULL, s, offs);
1433+ c = set_global_sym(s1, name, s, offs);
14021434 s = data_section;
14031435 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
14041436 section_ptr_add(s, PTR_SIZE);
@@ -1415,16 +1447,29 @@ ST_FUNC void tcc_add_btstub(TCCState *s1) · 10 unmodified lines
14151447 section_ptr_add(s, -s->data_offset & (PTR_SIZE - 1));
14161448 o = s->data_offset;
14171449 /* 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) */
14211466 section_ptr_add(s, 3 * PTR_SIZE);
14221467 /* prog_base : local nameless symbol with offset 0 at SHN_ABS */
1423− put_ptr(s1, NULL, 0);
1468+ put_ptr(s1, NULL, 0, NULL);
14241469 n = 2 * PTR_SIZE;
14251470 #ifdef CONFIG_TCC_BCHECK
14261471 if (s1->do_bounds_check) {
1427− put_ptr(s1, bounds_section, 0);
1472+ put_ptr(s1, bounds_section, 0, NULL);
14281473 n -= PTR_SIZE;
14291474 }
14301475 #endif
@@ -1849,6 +1894,8 @@ static int set_sec_sizes(TCCState *s1) · 418 unmodified lines
18491894 /* when generating a DLL, we include relocations but
18501895 we may patch them */
18511896 if (file_type == TCC_OUTPUT_DLL
1897+ /* Do not include dwarf relocatable sections. */
1898+ && !DWARF_DEBUG(s1->sections[s->sh_info]->name)
18521899 && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) {
18531900 int count = prepare_dynamic_rel(s1, s);
18541901 if (count) {
@@ -2963,8 +3010,7 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 1108 unmodified lines
29633010 strcmp(strsec + sh->sh_name, ".stabstr")
29643011 )
29653012 continue;
2966− if (seencompressed
2967− && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1))
3013+ if (seencompressed && DWARF_DEBUG(strsec + sh->sh_name))
29683014 continue;
29693015
29703016 sh = &shdr[i];
tccgen.c+1208−108
@@ -142,52 +142,56 @@ static void init_prec(void); · 141 unmodified lines
142142
143143 static const struct {
144144 int type;
145+ int size;
146+ int encoding;
145147 const char *name;
146148 } 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;" },
149151 #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;" },
151153 #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;" },
153155 #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;" },
155157 #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;" },
157159 #else
158160 /* 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;" },
160162 #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;" },
171173 #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;" },
173175 #else
174− { VT_LDOUBLE, "long double:t16=r1;16;0;" },
176+ { VT_LDOUBLE, 16, DW_ATE_float, "long double:t16=r1;16;0;" },
175177 #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;" },
184186 /* 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;" },
186188 /* 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" },
189191 };
190192
193+#define N_DEFAULT_DEBUG (sizeof (default_debug) / sizeof (default_debug[0]))
194+
191195 static int debug_next_type;
192196
193197 static struct debug_hash {
@@ -207,10 +211,231 @@ static struct debug_info { · 13 unmodified lines
207211 char *str;
208212 Section *sec;
209213 int sym_index;
214+ int info;
215+ int file;
216+ int line;
210217 } *sym;
211218 struct debug_info *child, *next, *last, *parent;
212219 } *debug_info, *debug_info_root;
213220
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+
214439 static struct {
215440 unsigned long offset;
216441 unsigned long last_file_name;
@@ -404,36 +629,323 @@ void pv (const char *lbl, int a, int b) · 187 unmodified lines
404629 #endif
405630
406631 /* ------------------------------------------------------------------------- */
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+
407811 /* start of translation unit info */
408812 ST_FUNC void tcc_debug_start(TCCState *s1)
409813 {
410814 if (s1->do_debug) {
411815 int i;
816+ char *filename = file->prev ? file->prev->filename : file->filename;
412817 char buf[512];
413818
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);
418819 getcwd(buf, sizeof(buf));
419820 #ifdef _WIN32
420821 normalize_slashes(buf);
421822 #endif
422823 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);
430824
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+ }
431944 new_file = last_line_num = 0;
432945 func_ind = -1;
433− debug_next_type = sizeof(default_debug) / sizeof(default_debug[0]);
946+ debug_next_type = N_DEFAULT_DEBUG;
434947 debug_hash = NULL;
435948 n_debug_hash = 0;
436−
437949 /* we're currently 'including' the <command line> */
438950 tcc_debug_bincl(s1);
439951 }
@@ -450,8 +962,111 @@ ST_FUNC void tcc_debug_end(TCCState *s1) · 10 unmodified lines
450962 {
451963 if (!s1->do_debug)
452964 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);
4551070 tcc_free(debug_hash);
4561071 }
4571072
@@ -462,8 +1077,10 @@ static BufferedFile* put_new_file(TCCState *s1) · 4 unmodified lines
4621077 if (f->filename[0] == ':')
4631078 f = f->prev;
4641079 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);
4661082 new_file = last_line_num = 0;
1083+ dwarf_file(s1);
4671084 }
4681085 return f;
4691086 }
@@ -475,6 +1092,7 @@ ST_FUNC void tcc_debug_putfile(TCCState *s1, const char *filename) · 5 unmodified lines
4751092 return;
4761093 pstrcpy(file->filename, sizeof(file->filename), filename);
4771094 new_file = 1;
1095+ dwarf_file(s1);
4781096 }
4791097
4801098 /* begin of #include */
@@ -482,8 +1100,53 @@ ST_FUNC void tcc_debug_bincl(TCCState *s1) · 1 unmodified line
4821100 {
4831101 if (!s1->do_debug)
4841102 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);
4861148 new_file = 1;
1149+ dwarf_file(s1);
4871150 }
4881151
4891152 /* end of #include */
@@ -491,30 +1154,73 @@ ST_FUNC void tcc_debug_eincl(TCCState *s1) · 1 unmodified line
4911154 {
4921155 if (!s1->do_debug)
4931156 return;
494− put_stabn(s1, N_EINCL, 0, 0, 0);
1157+ if (!s1->dwarf)
1158+ put_stabn(s1, N_EINCL, 0, 0, 0);
4951159 new_file = 1;
1160+ dwarf_file(s1);
4961161 }
4971162
4981163 /* generate line number info */
4991164 static void tcc_debug_line(TCCState *s1)
5001165 {
5011166 BufferedFile *f;
1167+
5021168 if (!s1->do_debug
5031169 || cur_text_section != text_section
5041170 || !(f = put_new_file(s1))
5051171 || last_line_num == f->line_num)
5061172 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;
5121219 }
513− last_line_num = f->line_num;
5141220 }
5151221
5161222 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)
5181224 {
5191225 struct debug_sym *s;
5201226
@@ -529,6 +1235,9 @@ static void tcc_debug_stabs (TCCState *s1, const char *str, int type, unsigned l · 8 unmodified lines
5291235 s->str = tcc_strdup(str);
5301236 s->sec = sec;
5311237 s->sym_index = sym_index;
1238+ s->info = info;
1239+ s->file = dwarf_line.cur_file;
1240+ s->line = file->line_num;
5321241 }
5331242 else if (sec)
5341243 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
5671276 }
5681277 }
5691278
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+
5701313 static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result)
5711314 {
5721315 int type;
@@ -585,22 +1328,12 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 12 unmodified lines
5851328 break;
5861329 }
5871330 if ((type & VT_BTYPE) == VT_STRUCT) {
588− int i;
1331+ Sym *e = t;
5891332
5901333 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);
5971335 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);
6041337 cstr_new (&str);
6051338 cstr_printf (&str, "%s:T%d=%c%d",
6061339 (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
6271360 cstr_printf (&str, ",%d,%d;", pos, size);
6281361 }
6291362 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);
6311364 cstr_free (&str);
1365+ if (debug_info)
1366+ tcc_debug_remove(e);
6321367 }
6331368 }
6341369 else if (IS_ENUM(type)) {
6351370 Sym *e = t = t->type.ref;
6361371
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+ }
6541394 }
6551395 else if ((type & VT_BTYPE) != VT_FUNC) {
6561396 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++)
6601398 if (default_debug[debug_type - 1].type == type)
6611399 break;
662− if (debug_type > sizeof(default_debug) / sizeof(default_debug[0]))
1400+ if (debug_type > N_DEFAULT_DEBUG)
6631401 return;
6641402 }
6651403 if (n > 0)
@@ -686,8 +1424,263 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 20 unmodified lines
6861424 cstr_printf (result, "%d", debug_type);
6871425 }
6881426
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+
6891622 static void tcc_debug_finish (TCCState *s1, struct debug_info *cur)
6901623 {
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+ }
6911684 while (cur) {
6921685 int i;
6931686 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
7201713 for (; s != e; s = s->prev) {
7211714 if (!s->v || (s->r & VT_VALMASK) != VT_LOCAL)
7221715 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+ }
7271729 }
7281730 cstr_free (&debug_str);
7291731 }
@@ -739,23 +1741,83 @@ static void tcc_debug_funcstart(TCCState *s1, Sym *sym) · 9 unmodified lines
7391741 debug_info = NULL;
7401742 tcc_debug_stabn(s1, N_LBRAC, ind - func_ind);
7411743 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;
7491745 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+ }
7501766 }
7511767
7521768 /* put function size */
7531769 static void tcc_debug_funcend(TCCState *s1, int size)
7541770 {
1771+ int func_sib = 0;
1772+
7551773 if (!s1->do_debug)
7561774 return;
1775+ tcc_debug_line(s1);
7571776 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+ }
7581815 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+ }
7591821 }
7601822
7611823
@@ -769,19 +1831,44 @@ static void tcc_debug_extern_sym(TCCState *s1, Sym *sym, int sh_num, int sym_bin · 7 unmodified lines
7691831 if (sym_type == STT_FUNC || sym->v >= SYM_FIRST_ANOM)
7701832 return;
7711833 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+ }
7721859
7731860 cstr_new (&str);
7741861 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+ );
7781865 tcc_get_debug_info(s1, sym, &str);
7791866 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);
7811868 else
7821869 tcc_debug_stabs(s1, str.data,
7831870 (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);
7851872 cstr_free (&str);
7861873 }
7871874
@@ -791,12 +1878,25 @@ static void tcc_debug_typedef(TCCState *s1, Sym *sym) · 3 unmodified lines
7911878
7921879 if (!s1->do_debug)
7931880 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+ }
7941894 cstr_new (&str);
7951895 cstr_printf (&str, "%s:t",
7961896 (sym->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
7971897 ? "" : get_tok_str(sym->v & ~SYM_FIELD, NULL));
7981898 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);
8001900 cstr_free (&str);
8011901 }
8021902
@@ -973,7 +2073,7 @@ ST_FUNC int tccgen_compile(TCCState *s1) · 170 unmodified lines
9732073 const_wanted = 0;
9742074 nocode_wanted = 0x80000000;
9752075 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;
9772077
9782078 tcc_debug_start(s1);
9792079 tcc_tcov_start ();
tccrun.c+357−6
@@ -27,8 +27,16 @@ · 26 unmodified lines
2727 typedef struct rt_context
2828 {
2929 /* --> 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+ };
3240 ElfW(Sym) *esym_start, *esym_end;
3341 char *elf_str;
3442 addr_t prog_base;
@@ -169,9 +177,18 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 134 unmodified lines
169177 memset(rc, 0, sizeof *rc);
170178 if (s1->do_debug) {
171179 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+ }
175192 rc->esym_start = (ElfW(Sym) *)(symtab_section->data);
176193 rc->esym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
177194 rc->elf_str = (char *)symtab_section->link->data;
@@ -571,6 +588,337 @@ found: · 393 unmodified lines
571588 return func_addr;
572589 }
573590
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+
574922 static int rt_get_caller_pc(addr_t *paddr, rt_context *rc, int level);
575923
576924 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
603951 ret = rt_get_caller_pc(&pc, rc, i);
604952 a = "%s";
605953 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);
607958 if (pc == (addr_t)-1)
608959 continue;
609960 a = ": %s";
tests/tests2/126_bound_global.c+13−0
@@ -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+}
tests/tests2/126_bound_global.expect+2−0
@@ -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
tests/tests2/Makefile+6−1
@@ -58,6 +58,9 @@ ifneq (,$(filter OpenBSD FreeBSD NetBSD,$(TARGETOS))) · 57 unmodified lines
5858 SKIP += 114_bound_signal.test # libc problem signal/fork
5959 SKIP += 116_bound_setjmp2.test # No TLS_FUNC/TLS_VAR in bcheck.c
6060 endif
61+ifneq (,$(filter Darwin,$(TARGETOS)))
62+ SKIP += 126_bound_global.test # bt-exe.c problem on apple
63+endif
6164
6265 # Some tests might need arguments
6366 ARGS =
@@ -100,7 +103,7 @@ GEN-ALWAYS = · 36 unmodified lines
100103 108_constructor.test: NORUN = true
101104
102105 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 += \
104107 -e 's;[0-9A-Fa-fx]\{5,\};........;g' \
105108 -e 's;0x[0-9A-Fa-f]\{1,\};0x?;g'
106109
@@ -122,6 +125,8 @@ ifneq ($(CONFIG_bcheck),no) · 15 unmodified lines
122125 endif
123126 125_atomic_misc.test: FLAGS += -dt
124127 124_atomic_counter.test: FLAGS += -pthread
128+126_bound_global.test: FLAGS += -b
129+126_bound_global.test: NORUN = true
125130
126131 # Filter source directory in warnings/errors (out-of-tree builds)
127132 FILTER = 2>&1 | sed -e 's,$(SRC)/,,g'
x86_64-gen.c+1−1
@@ -701,7 +701,7 @@ static void gen_bounds_epilog(void) · 700 unmodified lines
701701 *bounds_ptr = 0;
702702
703703 sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
704− func_bound_offset, lbounds_section->data_offset);
704+ func_bound_offset, PTR_SIZE);
705705
706706 /* generate bound local allocation */
707707 if (offset_modified) {
x86_64-link.c+1−0
@@ -4,6 +4,7 @@ · 3 unmodified lines
44
55 /* relocation type for 32 bit data relocation */
66 #define R_DATA_32 R_X86_64_32S
7+#define R_DATA_32U R_X86_64_32
78 #define R_DATA_PTR R_X86_64_64
89 #define R_JMP_SLOT R_X86_64_JUMP_SLOT
910 #define R_GLOB_DAT R_X86_64_GLOB_DAT

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t