2 * TCC - Tiny C Compiler
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 /* stab debug support */
31 { VT_INT
, 4, DW_ATE_signed
, "int:t1=r1;-2147483648;2147483647;" },
32 { VT_BYTE
, 1, DW_ATE_signed_char
, "char:t2=r2;0;127;" },
34 { VT_LONG
| VT_INT
, 4, DW_ATE_signed
, "long int:t3=r3;-2147483648;2147483647;" },
36 { VT_LLONG
| VT_LONG
, 8, DW_ATE_signed
, "long int:t3=r3;-9223372036854775808;9223372036854775807;" },
38 { VT_INT
| VT_UNSIGNED
, 4, DW_ATE_unsigned
, "unsigned int:t4=r4;0;037777777777;" },
40 { VT_LONG
| VT_INT
| VT_UNSIGNED
, 4, DW_ATE_unsigned
, "long unsigned int:t5=r5;0;037777777777;" },
42 /* use octal instead of -1 so size_t works (-gstabs+ in gcc) */
43 { VT_LLONG
| VT_LONG
| VT_UNSIGNED
, 8, DW_ATE_unsigned
, "long unsigned int:t5=r5;0;01777777777777777777777;" },
45 { VT_QLONG
, 16, DW_ATE_signed
, "__int128:t6=r6;0;-1;" },
46 { VT_QLONG
| VT_UNSIGNED
, 16, DW_ATE_unsigned
, "__int128 unsigned:t7=r7;0;-1;" },
47 { VT_LLONG
, 8, DW_ATE_signed
, "long long int:t8=r8;-9223372036854775808;9223372036854775807;" },
48 { VT_LLONG
| VT_UNSIGNED
, 8, DW_ATE_unsigned
, "long long unsigned int:t9=r9;0;01777777777777777777777;" },
49 { VT_SHORT
, 2, DW_ATE_signed
, "short int:t10=r10;-32768;32767;" },
50 { VT_SHORT
| VT_UNSIGNED
, 2, DW_ATE_unsigned
, "short unsigned int:t11=r11;0;65535;" },
51 { VT_BYTE
| VT_DEFSIGN
, 1, DW_ATE_signed_char
, "signed char:t12=r12;-128;127;" },
52 { VT_BYTE
| VT_DEFSIGN
| VT_UNSIGNED
, 1, DW_ATE_unsigned_char
, "unsigned char:t13=r13;0;255;" },
53 { VT_FLOAT
, 4, DW_ATE_float
, "float:t14=r1;4;0;" },
54 { VT_DOUBLE
, 8, DW_ATE_float
, "double:t15=r1;8;0;" },
55 #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
56 { VT_DOUBLE
| VT_LONG
, 8, DW_ATE_float
, "long double:t16=r1;8;0;" },
58 { VT_LDOUBLE
, 16, DW_ATE_float
, "long double:t16=r1;16;0;" },
60 { -1, -1, -1, "_Float32:t17=r1;4;0;" },
61 { -1, -1, -1, "_Float64:t18=r1;8;0;" },
62 { -1, -1, -1, "_Float128:t19=r1;16;0;" },
63 { -1, -1, -1, "_Float32x:t20=r1;8;0;" },
64 { -1, -1, -1, "_Float64x:t21=r1;16;0;" },
65 { -1, -1, -1, "_Decimal32:t22=r1;4;0;" },
66 { -1, -1, -1, "_Decimal64:t23=r1;8;0;" },
67 { -1, -1, -1, "_Decimal128:t24=r1;16;0;" },
68 /* if default char is unsigned */
69 { VT_BYTE
| VT_UNSIGNED
, 1, DW_ATE_unsigned_char
, "unsigned char:t25=r25;0;255;" },
71 { VT_BOOL
, 1, DW_ATE_boolean
, "bool:t26=r26;0;255;" },
73 { VT_VOID
, 1, DW_ATE_unsigned_char
, "void:t27=27" },
75 /* bitfields use these */
76 { VT_LONG
| VT_INT
, 8, DW_ATE_signed
, "long int:t27=r27;-9223372036854775808;9223372036854775807;" },
77 { VT_LONG
| VT_INT
| VT_UNSIGNED
, 8, DW_ATE_unsigned
, "long unsigned int:t28=r28;0;01777777777777777777777;" },
78 { VT_VOID
, 1, DW_ATE_unsigned_char
, "void:t29=29" },
82 #define N_DEFAULT_DEBUG (sizeof (default_debug) / sizeof (default_debug[0]))
86 #define DWARF_LINE_BASE -5
87 #define DWARF_LINE_RANGE 14
88 #define DWARF_OPCODE_BASE 13
90 #if defined TCC_TARGET_ARM64
91 #define DWARF_MIN_INSTR_LEN 4
92 #elif defined TCC_TARGET_ARM
93 #define DWARF_MIN_INSTR_LEN 2
95 #define DWARF_MIN_INSTR_LEN 1
98 #define DWARF_ABBREV_COMPILE_UNIT 1
99 #define DWARF_ABBREV_BASE_TYPE 2
100 #define DWARF_ABBREV_VARIABLE_EXTERNAL 3
101 #define DWARF_ABBREV_VARIABLE_STATIC 4
102 #define DWARF_ABBREV_VARIABLE_LOCAL 5
103 #define DWARF_ABBREV_FORMAL_PARAMETER 6
104 #define DWARF_ABBREV_POINTER 7
105 #define DWARF_ABBREV_ARRAY_TYPE 8
106 #define DWARF_ABBREV_SUBRANGE_TYPE 9
107 #define DWARF_ABBREV_TYPEDEF 10
108 #define DWARF_ABBREV_ENUMERATOR_SIGNED 11
109 #define DWARF_ABBREV_ENUMERATOR_UNSIGNED 12
110 #define DWARF_ABBREV_ENUMERATION_TYPE 13
111 #define DWARF_ABBREV_MEMBER 14
112 #define DWARF_ABBREV_MEMBER_BF 15
113 #define DWARF_ABBREV_STRUCTURE_TYPE 16
114 #define DWARF_ABBREV_STRUCTURE_EMPTY_TYPE 17
115 #define DWARF_ABBREV_UNION_TYPE 18
116 #define DWARF_ABBREV_UNION_EMPTY_TYPE 19
117 #define DWARF_ABBREV_SUBPROGRAM_EXTERNAL 20
118 #define DWARF_ABBREV_SUBPROGRAM_STATIC 21
119 #define DWARF_ABBREV_LEXICAL_BLOCK 22
120 #define DWARF_ABBREV_LEXICAL_EMPTY_BLOCK 23
121 #define DWARF_ABBREV_SUBROUTINE_TYPE 24
122 #define DWARF_ABBREV_SUBROUTINE_EMPTY_TYPE 25
123 #define DWARF_ABBREV_FORMAL_PARAMETER2 26
125 /* all entries should have been generated with dwarf_uleb128 except
126 has_children. All values are currently below 128 so this currently
128 static const unsigned char dwarf_abbrev_init
[] = {
129 DWARF_ABBREV_COMPILE_UNIT
, DW_TAG_compile_unit
, 1,
130 DW_AT_producer
, DW_FORM_strp
,
131 DW_AT_language
, DW_FORM_data1
,
132 DW_AT_name
, DW_FORM_line_strp
,
133 DW_AT_comp_dir
, DW_FORM_line_strp
,
134 DW_AT_low_pc
, DW_FORM_addr
,
136 DW_AT_high_pc
, DW_FORM_data4
,
138 DW_AT_high_pc
, DW_FORM_data8
,
140 DW_AT_stmt_list
, DW_FORM_sec_offset
,
142 DWARF_ABBREV_BASE_TYPE
, DW_TAG_base_type
, 0,
143 DW_AT_byte_size
, DW_FORM_udata
,
144 DW_AT_encoding
, DW_FORM_data1
,
145 DW_AT_name
, DW_FORM_strp
,
147 DWARF_ABBREV_VARIABLE_EXTERNAL
, DW_TAG_variable
, 0,
148 DW_AT_name
, DW_FORM_strp
,
149 DW_AT_decl_file
, DW_FORM_udata
,
150 DW_AT_decl_line
, DW_FORM_udata
,
151 DW_AT_type
, DW_FORM_ref4
,
152 DW_AT_external
, DW_FORM_flag
,
153 DW_AT_location
, DW_FORM_exprloc
,
155 DWARF_ABBREV_VARIABLE_STATIC
, DW_TAG_variable
, 0,
156 DW_AT_name
, DW_FORM_strp
,
157 DW_AT_decl_file
, DW_FORM_udata
,
158 DW_AT_decl_line
, DW_FORM_udata
,
159 DW_AT_type
, DW_FORM_ref4
,
160 DW_AT_location
, DW_FORM_exprloc
,
162 DWARF_ABBREV_VARIABLE_LOCAL
, DW_TAG_variable
, 0,
163 DW_AT_name
, DW_FORM_strp
,
164 DW_AT_type
, DW_FORM_ref4
,
165 DW_AT_location
, DW_FORM_exprloc
,
167 DWARF_ABBREV_FORMAL_PARAMETER
, DW_TAG_formal_parameter
, 0,
168 DW_AT_name
, DW_FORM_strp
,
169 DW_AT_type
, DW_FORM_ref4
,
170 DW_AT_location
, DW_FORM_exprloc
,
172 DWARF_ABBREV_POINTER
, DW_TAG_pointer_type
, 0,
173 DW_AT_byte_size
, DW_FORM_data1
,
174 DW_AT_type
, DW_FORM_ref4
,
176 DWARF_ABBREV_ARRAY_TYPE
, DW_TAG_array_type
, 1,
177 DW_AT_type
, DW_FORM_ref4
,
178 DW_AT_sibling
, DW_FORM_ref4
,
180 DWARF_ABBREV_SUBRANGE_TYPE
, DW_TAG_subrange_type
, 0,
181 DW_AT_type
, DW_FORM_ref4
,
182 DW_AT_upper_bound
, DW_FORM_udata
,
184 DWARF_ABBREV_TYPEDEF
, DW_TAG_typedef
, 0,
185 DW_AT_name
, DW_FORM_strp
,
186 DW_AT_decl_file
, DW_FORM_udata
,
187 DW_AT_decl_line
, DW_FORM_udata
,
188 DW_AT_type
, DW_FORM_ref4
,
190 DWARF_ABBREV_ENUMERATOR_SIGNED
, DW_TAG_enumerator
, 0,
191 DW_AT_name
, DW_FORM_strp
,
192 DW_AT_const_value
, DW_FORM_sdata
,
194 DWARF_ABBREV_ENUMERATOR_UNSIGNED
, DW_TAG_enumerator
, 0,
195 DW_AT_name
, DW_FORM_strp
,
196 DW_AT_const_value
, DW_FORM_udata
,
198 DWARF_ABBREV_ENUMERATION_TYPE
, DW_TAG_enumeration_type
, 1,
199 DW_AT_name
, DW_FORM_strp
,
200 DW_AT_encoding
, DW_FORM_data1
,
201 DW_AT_byte_size
, DW_FORM_data1
,
202 DW_AT_type
, DW_FORM_ref4
,
203 DW_AT_decl_file
, DW_FORM_udata
,
204 DW_AT_decl_line
, DW_FORM_udata
,
205 DW_AT_sibling
, DW_FORM_ref4
,
207 DWARF_ABBREV_MEMBER
, DW_TAG_member
, 0,
208 DW_AT_name
, DW_FORM_strp
,
209 DW_AT_decl_file
, DW_FORM_udata
,
210 DW_AT_decl_line
, DW_FORM_udata
,
211 DW_AT_type
, DW_FORM_ref4
,
212 DW_AT_data_member_location
, DW_FORM_udata
,
214 DWARF_ABBREV_MEMBER_BF
, DW_TAG_member
, 0,
215 DW_AT_name
, DW_FORM_strp
,
216 DW_AT_decl_file
, DW_FORM_udata
,
217 DW_AT_decl_line
, DW_FORM_udata
,
218 DW_AT_type
, DW_FORM_ref4
,
219 DW_AT_bit_size
, DW_FORM_udata
,
220 DW_AT_data_bit_offset
, DW_FORM_udata
,
222 DWARF_ABBREV_STRUCTURE_TYPE
, DW_TAG_structure_type
, 1,
223 DW_AT_name
, DW_FORM_strp
,
224 DW_AT_byte_size
, DW_FORM_udata
,
225 DW_AT_decl_file
, DW_FORM_udata
,
226 DW_AT_decl_line
, DW_FORM_udata
,
227 DW_AT_sibling
, DW_FORM_ref4
,
229 DWARF_ABBREV_STRUCTURE_EMPTY_TYPE
, DW_TAG_structure_type
, 0,
230 DW_AT_name
, DW_FORM_strp
,
231 DW_AT_byte_size
, DW_FORM_udata
,
232 DW_AT_decl_file
, DW_FORM_udata
,
233 DW_AT_decl_line
, DW_FORM_udata
,
235 DWARF_ABBREV_UNION_TYPE
, DW_TAG_union_type
, 1,
236 DW_AT_name
, DW_FORM_strp
,
237 DW_AT_byte_size
, DW_FORM_udata
,
238 DW_AT_decl_file
, DW_FORM_udata
,
239 DW_AT_decl_line
, DW_FORM_udata
,
240 DW_AT_sibling
, DW_FORM_ref4
,
242 DWARF_ABBREV_UNION_EMPTY_TYPE
, DW_TAG_union_type
, 0,
243 DW_AT_name
, DW_FORM_strp
,
244 DW_AT_byte_size
, DW_FORM_udata
,
245 DW_AT_decl_file
, DW_FORM_udata
,
246 DW_AT_decl_line
, DW_FORM_udata
,
248 DWARF_ABBREV_SUBPROGRAM_EXTERNAL
, DW_TAG_subprogram
, 1,
249 DW_AT_external
, DW_FORM_flag
,
250 DW_AT_name
, DW_FORM_strp
,
251 DW_AT_decl_file
, DW_FORM_udata
,
252 DW_AT_decl_line
, DW_FORM_udata
,
253 DW_AT_type
, DW_FORM_ref4
,
254 DW_AT_low_pc
, DW_FORM_addr
,
256 DW_AT_high_pc
, DW_FORM_data4
,
258 DW_AT_high_pc
, DW_FORM_data8
,
260 DW_AT_sibling
, DW_FORM_ref4
,
261 DW_AT_frame_base
, DW_FORM_exprloc
,
263 DWARF_ABBREV_SUBPROGRAM_STATIC
, DW_TAG_subprogram
, 1,
264 DW_AT_name
, DW_FORM_strp
,
265 DW_AT_decl_file
, DW_FORM_udata
,
266 DW_AT_decl_line
, DW_FORM_udata
,
267 DW_AT_type
, DW_FORM_ref4
,
268 DW_AT_low_pc
, DW_FORM_addr
,
270 DW_AT_high_pc
, DW_FORM_data4
,
272 DW_AT_high_pc
, DW_FORM_data8
,
274 DW_AT_sibling
, DW_FORM_ref4
,
275 DW_AT_frame_base
, DW_FORM_exprloc
,
277 DWARF_ABBREV_LEXICAL_BLOCK
, DW_TAG_lexical_block
, 1,
278 DW_AT_low_pc
, DW_FORM_addr
,
280 DW_AT_high_pc
, DW_FORM_data4
,
282 DW_AT_high_pc
, DW_FORM_data8
,
285 DWARF_ABBREV_LEXICAL_EMPTY_BLOCK
, DW_TAG_lexical_block
, 0,
286 DW_AT_low_pc
, DW_FORM_addr
,
288 DW_AT_high_pc
, DW_FORM_data4
,
290 DW_AT_high_pc
, DW_FORM_data8
,
293 DWARF_ABBREV_SUBROUTINE_TYPE
, DW_TAG_subroutine_type
, 1,
294 DW_AT_type
, DW_FORM_ref4
,
295 DW_AT_sibling
, DW_FORM_ref4
,
297 DWARF_ABBREV_SUBROUTINE_EMPTY_TYPE
, DW_TAG_subroutine_type
, 0,
298 DW_AT_type
, DW_FORM_ref4
,
300 DWARF_ABBREV_FORMAL_PARAMETER2
, DW_TAG_formal_parameter
, 0,
301 DW_AT_type
, DW_FORM_ref4
,
306 static const unsigned char dwarf_line_opcodes
[] = {
307 0 ,1 ,1 ,1 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,1
310 /* ------------------------------------------------------------------------- */
315 int last_line_num
, new_file
;
325 struct _debug_anon_hash
{
332 int n_debug_anon_hash
;
348 struct _debug_info
*child
, *next
, *last
, *parent
;
349 } *debug_info
, *debug_info_root
;
364 struct dwarf_filename_struct
{
370 unsigned char *line_data
;
381 int base_type_used
[N_DEFAULT_DEBUG
];
386 unsigned long offset
;
387 unsigned long last_file_name
;
388 unsigned long last_func_name
;
395 #define last_line_num s1->dState->last_line_num
396 #define new_file s1->dState->new_file
397 #define section_sym s1->dState->section_sym
398 #define debug_next_type s1->dState->debug_next_type
399 #define debug_hash s1->dState->debug_hash
400 #define debug_anon_hash s1->dState->debug_anon_hash
401 #define n_debug_hash s1->dState->n_debug_hash
402 #define n_debug_anon_hash s1->dState->n_debug_anon_hash
403 #define debug_info s1->dState->debug_info
404 #define debug_info_root s1->dState->debug_info_root
405 #define dwarf_sym s1->dState->dwarf_sym
406 #define dwarf_line s1->dState->dwarf_line
407 #define dwarf_info s1->dState->dwarf_info
408 #define tcov_data s1->dState->tcov_data
410 /* ------------------------------------------------------------------------- */
411 static void put_stabs(TCCState
*s1
, const char *str
, int type
, int other
,
412 int desc
, unsigned long value
);
414 ST_FUNC
void tcc_debug_new(TCCState
*s1
)
418 s1
->dState
= tcc_mallocz(sizeof *s1
->dState
);
419 #ifdef CONFIG_TCC_BACKTRACE
420 /* include stab info with standalone backtrace support */
422 && (s1
->output_type
& (TCC_OUTPUT_EXE
| TCC_OUTPUT_DLL
)))
423 shf
= SHF_ALLOC
| SHF_WRITE
; // SHF_WRITE needed for musl/SELINUX
426 s1
->dwlo
= s1
->nb_sections
;
428 new_section(s1
, ".debug_info", SHT_PROGBITS
, shf
);
429 dwarf_abbrev_section
=
430 new_section(s1
, ".debug_abbrev", SHT_PROGBITS
, shf
);
432 new_section(s1
, ".debug_line", SHT_PROGBITS
, shf
);
433 dwarf_aranges_section
=
434 new_section(s1
, ".debug_aranges", SHT_PROGBITS
, shf
);
435 shf
|= SHF_MERGE
| SHF_STRINGS
;
437 new_section(s1
, ".debug_str", SHT_PROGBITS
, shf
);
438 dwarf_str_section
->sh_entsize
= 1;
439 dwarf_info_section
->sh_addralign
=
440 dwarf_abbrev_section
->sh_addralign
=
441 dwarf_line_section
->sh_addralign
=
442 dwarf_aranges_section
->sh_addralign
=
443 dwarf_str_section
->sh_addralign
= 1;
444 if (s1
->dwarf
>= 5) {
445 dwarf_line_str_section
=
446 new_section(s1
, ".debug_line_str", SHT_PROGBITS
, shf
);
447 dwarf_line_str_section
->sh_entsize
= 1;
448 dwarf_line_str_section
->sh_addralign
= 1;
450 s1
->dwhi
= s1
->nb_sections
;
454 stab_section
= new_section(s1
, ".stab", SHT_PROGBITS
, shf
);
455 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
456 stab_section
->sh_addralign
= sizeof ((Stab_Sym
*)0)->n_value
;
457 stab_section
->link
= new_section(s1
, ".stabstr", SHT_STRTAB
, shf
);
458 /* put first entry */
459 put_stabs(s1
, "", 0, 0, 0, 0);
463 /* put stab debug information */
464 static void put_stabs(TCCState
*s1
, const char *str
, int type
, int other
, int desc
,
471 && (offset
= stab_section
->data_offset
)
472 && (sym
= (Stab_Sym
*)(stab_section
->data
+ offset
) - 1)
473 && sym
->n_type
== type
474 && sym
->n_value
== value
) {
475 /* just update line_number in previous entry */
480 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
482 sym
->n_strx
= put_elf_str(stab_section
->link
, str
);
487 sym
->n_other
= other
;
489 sym
->n_value
= value
;
492 static void put_stabs_r(TCCState
*s1
, const char *str
, int type
, int other
, int desc
,
493 unsigned long value
, Section
*sec
, int sym_index
)
495 put_elf_reloc(symtab_section
, stab_section
,
496 stab_section
->data_offset
+ 8,
497 sizeof ((Stab_Sym
*)0)->n_value
== PTR_SIZE
? R_DATA_PTR
: R_DATA_32
,
499 put_stabs(s1
, str
, type
, other
, desc
, value
);
502 static void put_stabn(TCCState
*s1
, int type
, int other
, int desc
, int value
)
504 put_stabs(s1
, NULL
, type
, other
, desc
, value
);
507 /* ------------------------------------------------------------------------- */
508 #define dwarf_data1(s,data) \
509 { unsigned char *p = section_ptr_add((s), 1); *p = (data); }
510 #define dwarf_data2(s,data) \
511 write16le(section_ptr_add((s), 2), (data))
512 #define dwarf_data4(s,data) \
513 write32le(section_ptr_add((s), 4), (data))
514 #define dwarf_data8(s,data) \
515 write64le(section_ptr_add((s), 8), (data))
517 static int dwarf_get_section_sym(Section
*s
)
519 TCCState
*s1
= s
->s1
;
520 return put_elf_sym(symtab_section
, 0, 0,
521 ELFW(ST_INFO
)(STB_LOCAL
, STT_SECTION
), 0,
525 static void dwarf_reloc(Section
*s
, int sym
, int rel
)
527 TCCState
*s1
= s
->s1
;
528 put_elf_reloca(symtab_section
, s
, s
->data_offset
, rel
, sym
, 0);
531 static void dwarf_string(Section
*s
, Section
*dw
, int sym
, const char *str
)
533 TCCState
*s1
= s
->s1
;
537 len
= strlen(str
) + 1;
538 offset
= dw
->data_offset
;
539 ptr
= section_ptr_add(dw
, len
);
540 memmove(ptr
, str
, len
);
541 put_elf_reloca(symtab_section
, s
, s
->data_offset
, R_DATA_32DW
, sym
,
542 PTR_SIZE
== 4 ? 0 : offset
);
543 dwarf_data4(s
, PTR_SIZE
== 4 ? offset
: 0);
546 static void dwarf_strp(Section
*s
, const char *str
)
548 TCCState
*s1
= s
->s1
;
549 dwarf_string(s
, dwarf_str_section
, dwarf_sym
.str
, str
);
552 static void dwarf_line_strp(Section
*s
, const char *str
)
554 TCCState
*s1
= s
->s1
;
555 dwarf_string(s
, dwarf_line_str_section
, dwarf_sym
.line_str
, str
);
558 static void dwarf_line_op(TCCState
*s1
, unsigned char op
)
560 if (dwarf_line
.line_size
>= dwarf_line
.line_max_size
) {
561 dwarf_line
.line_max_size
+= 1024;
562 dwarf_line
.line_data
=
563 (unsigned char *)tcc_realloc(dwarf_line
.line_data
,
564 dwarf_line
.line_max_size
);
566 dwarf_line
.line_data
[dwarf_line
.line_size
++] = op
;
569 static void dwarf_file(TCCState
*s1
)
573 int index_offset
= s1
->dwarf
< 5;
575 if (!strcmp(file
->filename
, "<command line>")) {
576 dwarf_line
.cur_file
= 1;
579 filename
= strrchr(file
->filename
, '/');
580 if (filename
== NULL
) {
581 for (i
= 1; i
< dwarf_line
.filename_size
; i
++)
582 if (dwarf_line
.filename_table
[i
].dir_entry
== 0 &&
583 strcmp(dwarf_line
.filename_table
[i
].name
,
584 file
->filename
) == 0) {
585 dwarf_line
.cur_file
= i
+ index_offset
;
589 filename
= file
->filename
;
592 char *undo
= filename
;
593 char *dir
= file
->filename
;
596 for (i
= 0; i
< dwarf_line
.dir_size
; i
++)
597 if (strcmp(dwarf_line
.dir_table
[i
], dir
) == 0) {
598 for (j
= 1; j
< dwarf_line
.filename_size
; j
++)
599 if (dwarf_line
.filename_table
[j
].dir_entry
- index_offset
601 strcmp(dwarf_line
.filename_table
[j
].name
,
604 dwarf_line
.cur_file
= j
+ index_offset
;
609 if (i
== dwarf_line
.dir_size
) {
610 dwarf_line
.dir_size
++;
611 dwarf_line
.dir_table
=
612 (char **) tcc_realloc(dwarf_line
.dir_table
,
613 dwarf_line
.dir_size
*
615 dwarf_line
.dir_table
[i
] = tcc_strdup(dir
);
619 dwarf_line
.filename_table
=
620 (struct dwarf_filename_struct
*)
621 tcc_realloc(dwarf_line
.filename_table
,
622 (dwarf_line
.filename_size
+ 1) *
623 sizeof (struct dwarf_filename_struct
));
624 dwarf_line
.filename_table
[dwarf_line
.filename_size
].dir_entry
=
626 dwarf_line
.filename_table
[dwarf_line
.filename_size
].name
=
627 tcc_strdup(filename
);
628 dwarf_line
.cur_file
= dwarf_line
.filename_size
++ + index_offset
;
633 static int dwarf_uleb128_size (unsigned long long value
)
640 } while (value
!= 0);
645 static int dwarf_sleb128_size (long long value
)
648 long long end
= value
>> 63;
649 unsigned char last
= end
& 0x40;
656 } while (value
!= end
|| (byte
& 0x40) != last
);
660 static void dwarf_uleb128 (Section
*s
, unsigned long long value
)
663 unsigned char byte
= value
& 0x7f;
666 dwarf_data1(s
, byte
| (value
? 0x80 : 0));
667 } while (value
!= 0);
670 static void dwarf_sleb128 (Section
*s
, long long value
)
673 long long end
= value
>> 63;
674 unsigned char last
= end
& 0x40;
677 unsigned char byte
= value
& 0x7f;
680 more
= value
!= end
|| (byte
& 0x40) != last
;
681 dwarf_data1(s
, byte
| (0x80 * more
));
685 static void dwarf_uleb128_op (TCCState
*s1
, unsigned long long value
)
688 unsigned char byte
= value
& 0x7f;
691 dwarf_line_op(s1
, byte
| (value
? 0x80 : 0));
692 } while (value
!= 0);
695 static void dwarf_sleb128_op (TCCState
*s1
, long long value
)
698 long long end
= value
>> 63;
699 unsigned char last
= end
& 0x40;
702 unsigned char byte
= value
& 0x7f;
705 more
= value
!= end
|| (byte
& 0x40) != last
;
706 dwarf_line_op(s1
, byte
| (0x80 * more
));
710 /* start of translation unit info */
711 ST_FUNC
void tcc_debug_start(TCCState
*s1
)
717 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
718 symbols can be safely used */
719 filename
= file
->prev
? file
->prev
->filename
: file
->filename
;
720 put_elf_sym(symtab_section
, 0, 0,
721 ELFW(ST_INFO
)(STB_LOCAL
, STT_FILE
), 0,
726 new_file
= last_line_num
= 0;
727 debug_next_type
= N_DEFAULT_DEBUG
;
729 debug_anon_hash
= NULL
;
731 n_debug_anon_hash
= 0;
733 getcwd(buf
, sizeof(buf
));
735 normalize_slashes(buf
);
744 start_abbrev
= dwarf_abbrev_section
->data_offset
;
745 ptr
= section_ptr_add(dwarf_abbrev_section
, sizeof(dwarf_abbrev_init
));
746 memcpy(ptr
, dwarf_abbrev_init
, sizeof(dwarf_abbrev_init
));
752 if (ptr
[1] == DW_FORM_line_strp
)
753 ptr
[1] = DW_FORM_strp
;
755 /* These are compatable for DW_TAG_compile_unit
757 if (ptr
[1] == DW_FORM_sec_offset
)
758 ptr
[1] = DW_FORM_data4
;
759 /* This code uses only size < 0x80 so these are
761 if (ptr
[1] == DW_FORM_exprloc
)
762 ptr
[1] = DW_FORM_block1
;
770 dwarf_sym
.info
= dwarf_get_section_sym(dwarf_info_section
);
771 dwarf_sym
.abbrev
= dwarf_get_section_sym(dwarf_abbrev_section
);
772 dwarf_sym
.line
= dwarf_get_section_sym(dwarf_line_section
);
773 dwarf_sym
.str
= dwarf_get_section_sym(dwarf_str_section
);
774 if (tcc_state
->dwarf
>= 5)
775 dwarf_sym
.line_str
= dwarf_get_section_sym(dwarf_line_str_section
);
777 dwarf_line_str_section
= dwarf_str_section
;
778 dwarf_sym
.line_str
= dwarf_sym
.str
;
780 section_sym
= dwarf_get_section_sym(text_section
);
783 dwarf_info
.start
= dwarf_info_section
->data_offset
;
784 dwarf_data4(dwarf_info_section
, 0); // size
785 dwarf_data2(dwarf_info_section
, s1
->dwarf
); // version
786 if (s1
->dwarf
>= 5) {
787 dwarf_data1(dwarf_info_section
, DW_UT_compile
); // unit type
788 dwarf_data1(dwarf_info_section
, PTR_SIZE
);
789 dwarf_reloc(dwarf_info_section
, dwarf_sym
.abbrev
, R_DATA_32DW
);
790 dwarf_data4(dwarf_info_section
, start_abbrev
);
793 dwarf_reloc(dwarf_info_section
, dwarf_sym
.abbrev
, R_DATA_32DW
);
794 dwarf_data4(dwarf_info_section
, start_abbrev
);
795 dwarf_data1(dwarf_info_section
, PTR_SIZE
);
798 dwarf_data1(dwarf_info_section
, DWARF_ABBREV_COMPILE_UNIT
);
799 dwarf_strp(dwarf_info_section
, "tcc " TCC_VERSION
);
800 dwarf_data1(dwarf_info_section
, DW_LANG_C11
);
801 dwarf_line_strp(dwarf_info_section
, filename
);
802 dwarf_line_strp(dwarf_info_section
, buf
);
803 dwarf_reloc(dwarf_info_section
, section_sym
, R_DATA_PTR
);
805 dwarf_data4(dwarf_info_section
, ind
); // low pc
806 dwarf_data4(dwarf_info_section
, 0); // high pc
808 dwarf_data8(dwarf_info_section
, ind
); // low pc
809 dwarf_data8(dwarf_info_section
, 0); // high pc
811 dwarf_reloc(dwarf_info_section
, dwarf_sym
.line
, R_DATA_32DW
);
812 dwarf_data4(dwarf_info_section
, dwarf_line_section
->data_offset
); // stmt_list
815 dwarf_line
.start
= dwarf_line_section
->data_offset
;
816 dwarf_data4(dwarf_line_section
, 0); // length
817 dwarf_data2(dwarf_line_section
, s1
->dwarf
); // version
818 if (s1
->dwarf
>= 5) {
819 dwarf_data1(dwarf_line_section
, PTR_SIZE
); // address size
820 dwarf_data1(dwarf_line_section
, 0); // segment selector
822 dwarf_data4(dwarf_line_section
, 0); // prologue Length
823 dwarf_data1(dwarf_line_section
, DWARF_MIN_INSTR_LEN
);
825 dwarf_data1(dwarf_line_section
, 1); // maximum ops per instruction
826 dwarf_data1(dwarf_line_section
, 1); // Initial value of 'is_stmt'
827 dwarf_data1(dwarf_line_section
, DWARF_LINE_BASE
);
828 dwarf_data1(dwarf_line_section
, DWARF_LINE_RANGE
);
829 dwarf_data1(dwarf_line_section
, DWARF_OPCODE_BASE
);
830 ptr
= section_ptr_add(dwarf_line_section
, sizeof(dwarf_line_opcodes
));
831 memcpy(ptr
, dwarf_line_opcodes
, sizeof(dwarf_line_opcodes
));
832 undo
= strrchr(filename
, '/');
835 dwarf_line
.dir_size
= 1 + (undo
!= NULL
);
836 dwarf_line
.dir_table
= (char **) tcc_malloc(sizeof (char *) *
837 dwarf_line
.dir_size
);
838 dwarf_line
.dir_table
[0] = tcc_strdup(buf
);
840 dwarf_line
.dir_table
[1] = tcc_strdup(filename
);
841 dwarf_line
.filename_size
= 2;
842 dwarf_line
.filename_table
=
843 (struct dwarf_filename_struct
*)
844 tcc_malloc(2*sizeof (struct dwarf_filename_struct
));
845 dwarf_line
.filename_table
[0].dir_entry
= 0;
847 dwarf_line
.filename_table
[0].name
= tcc_strdup(undo
+ 1);
848 dwarf_line
.filename_table
[1].dir_entry
= 1;
849 dwarf_line
.filename_table
[1].name
= tcc_strdup(undo
+ 1);
853 dwarf_line
.filename_table
[0].name
= tcc_strdup(filename
);
854 dwarf_line
.filename_table
[1].dir_entry
= 0;
855 dwarf_line
.filename_table
[1].name
= tcc_strdup(filename
);
857 dwarf_line
.line_size
= dwarf_line
.line_max_size
= 0;
858 dwarf_line
.line_data
= NULL
;
859 dwarf_line
.cur_file
= 1;
860 dwarf_line
.last_file
= 0;
861 dwarf_line
.last_pc
= 0;
862 dwarf_line
.last_line
= 1;
863 dwarf_line_op(s1
, 0); // extended
864 dwarf_uleb128_op(s1
, 1 + PTR_SIZE
); // extended size
865 dwarf_line_op(s1
, DW_LNE_set_address
);
866 for (i
= 0; i
< PTR_SIZE
; i
++)
867 dwarf_line_op(s1
, 0);
868 memset(&dwarf_info
.base_type_used
, 0, sizeof(dwarf_info
.base_type_used
));
872 /* file info: full path + filename */
873 pstrcat(buf
, sizeof(buf
), "/");
874 section_sym
= put_elf_sym(symtab_section
, 0, 0,
875 ELFW(ST_INFO
)(STB_LOCAL
, STT_SECTION
), 0,
876 text_section
->sh_num
, NULL
);
877 put_stabs_r(s1
, buf
, N_SO
, 0, 0,
878 text_section
->data_offset
, text_section
, section_sym
);
879 put_stabs_r(s1
, filename
, N_SO
, 0, 0,
880 text_section
->data_offset
, text_section
, section_sym
);
881 for (i
= 0; i
< N_DEFAULT_DEBUG
; i
++)
882 put_stabs(s1
, default_debug
[i
].name
, N_LSYM
, 0, 0, 0);
884 /* we're currently 'including' the <command line> */
889 /* put end of translation unit info */
890 ST_FUNC
void tcc_debug_end(TCCState
*s1
)
892 if (!s1
->do_debug
|| debug_next_type
== 0)
896 tcc_debug_funcend(s1
, 0); /* free stuff in case of errors */
902 int text_size
= text_section
->data_offset
;
905 for (i
= 0; i
< n_debug_anon_hash
; i
++) {
906 Sym
*t
= debug_anon_hash
[i
].type
;
907 int pos
= dwarf_info_section
->data_offset
;
909 dwarf_data1(dwarf_info_section
,
910 IS_UNION (t
->type
.t
) ? DWARF_ABBREV_UNION_EMPTY_TYPE
911 : DWARF_ABBREV_STRUCTURE_EMPTY_TYPE
);
912 dwarf_strp(dwarf_info_section
,
913 (t
->v
& ~SYM_STRUCT
) >= SYM_FIRST_ANOM
914 ? "" : get_tok_str(t
->v
& ~SYM_STRUCT
, NULL
));
915 dwarf_uleb128(dwarf_info_section
, 0);
916 dwarf_uleb128(dwarf_info_section
, dwarf_line
.cur_file
);
917 dwarf_uleb128(dwarf_info_section
, file
->line_num
);
918 for (j
= 0; j
< debug_anon_hash
[i
].n_debug_type
; j
++)
919 write32le(dwarf_info_section
->data
+
920 debug_anon_hash
[i
].debug_type
[j
],
921 pos
- dwarf_info
.start
);
922 tcc_free (debug_anon_hash
[i
].debug_type
);
924 tcc_free (debug_anon_hash
);
925 dwarf_data1(dwarf_info_section
, 0);
926 ptr
= dwarf_info_section
->data
+ dwarf_info
.start
;
927 write32le(ptr
, dwarf_info_section
->data_offset
- dwarf_info
.start
- 4);
928 write32le(ptr
+ 25 + (s1
->dwarf
>= 5) + PTR_SIZE
, text_size
);
931 start_aranges
= dwarf_aranges_section
->data_offset
;
932 dwarf_data4(dwarf_aranges_section
, 0); // size
933 dwarf_data2(dwarf_aranges_section
, 2); // version
934 dwarf_reloc(dwarf_aranges_section
, dwarf_sym
.info
, R_DATA_32DW
);
935 dwarf_data4(dwarf_aranges_section
, 0); // dwarf_info
937 dwarf_data1(dwarf_aranges_section
, 4); // address size
939 dwarf_data1(dwarf_aranges_section
, 8); // address size
941 dwarf_data1(dwarf_aranges_section
, 0); // segment selector size
942 dwarf_data4(dwarf_aranges_section
, 0); // padding
943 dwarf_reloc(dwarf_aranges_section
, section_sym
, R_DATA_PTR
);
945 dwarf_data4(dwarf_aranges_section
, 0); // Begin
946 dwarf_data4(dwarf_aranges_section
, text_size
); // End
947 dwarf_data4(dwarf_aranges_section
, 0); // End list
948 dwarf_data4(dwarf_aranges_section
, 0); // End list
950 dwarf_data8(dwarf_aranges_section
, 0); // Begin
951 dwarf_data8(dwarf_aranges_section
, text_size
); // End
952 dwarf_data8(dwarf_aranges_section
, 0); // End list
953 dwarf_data8(dwarf_aranges_section
, 0); // End list
955 ptr
= dwarf_aranges_section
->data
+ start_aranges
;
956 write32le(ptr
, dwarf_aranges_section
->data_offset
- start_aranges
- 4);
959 if (s1
->dwarf
>= 5) {
960 dwarf_data1(dwarf_line_section
, 1); /* col */
961 dwarf_uleb128(dwarf_line_section
, DW_LNCT_path
);
962 dwarf_uleb128(dwarf_line_section
, DW_FORM_line_strp
);
963 dwarf_uleb128(dwarf_line_section
, dwarf_line
.dir_size
);
964 for (i
= 0; i
< dwarf_line
.dir_size
; i
++)
965 dwarf_line_strp(dwarf_line_section
, dwarf_line
.dir_table
[i
]);
966 dwarf_data1(dwarf_line_section
, 2); /* col */
967 dwarf_uleb128(dwarf_line_section
, DW_LNCT_path
);
968 dwarf_uleb128(dwarf_line_section
, DW_FORM_line_strp
);
969 dwarf_uleb128(dwarf_line_section
, DW_LNCT_directory_index
);
970 dwarf_uleb128(dwarf_line_section
, DW_FORM_udata
);
971 dwarf_uleb128(dwarf_line_section
, dwarf_line
.filename_size
);
972 for (i
= 0; i
< dwarf_line
.filename_size
; i
++) {
973 dwarf_line_strp(dwarf_line_section
,
974 dwarf_line
.filename_table
[i
].name
);
975 dwarf_uleb128(dwarf_line_section
,
976 dwarf_line
.filename_table
[i
].dir_entry
);
982 for (i
= 0; i
< dwarf_line
.dir_size
; i
++) {
983 len
= strlen(dwarf_line
.dir_table
[i
]) + 1;
984 ptr
= section_ptr_add(dwarf_line_section
, len
);
985 memmove(ptr
, dwarf_line
.dir_table
[i
], len
);
987 dwarf_data1(dwarf_line_section
, 0); /* end dir */
988 for (i
= 0; i
< dwarf_line
.filename_size
; i
++) {
989 len
= strlen(dwarf_line
.filename_table
[i
].name
) + 1;
990 ptr
= section_ptr_add(dwarf_line_section
, len
);
991 memmove(ptr
, dwarf_line
.filename_table
[i
].name
, len
);
992 dwarf_uleb128(dwarf_line_section
,
993 dwarf_line
.filename_table
[i
].dir_entry
);
994 dwarf_uleb128(dwarf_line_section
, 0); /* time */
995 dwarf_uleb128(dwarf_line_section
, 0); /* size */
997 dwarf_data1(dwarf_line_section
, 0); /* end file */
999 for (i
= 0; i
< dwarf_line
.dir_size
; i
++)
1000 tcc_free(dwarf_line
.dir_table
[i
]);
1001 tcc_free(dwarf_line
.dir_table
);
1002 for (i
= 0; i
< dwarf_line
.filename_size
; i
++)
1003 tcc_free(dwarf_line
.filename_table
[i
].name
);
1004 tcc_free(dwarf_line
.filename_table
);
1006 dwarf_line_op(s1
, 0); // extended
1007 dwarf_uleb128_op(s1
, 1); // extended size
1008 dwarf_line_op(s1
, DW_LNE_end_sequence
);
1009 i
= (s1
->dwarf
>= 5) * 2;
1010 write32le(&dwarf_line_section
->data
[dwarf_line
.start
+ 6 + i
],
1011 dwarf_line_section
->data_offset
- dwarf_line
.start
- (10 + i
));
1012 section_ptr_add(dwarf_line_section
, 3);
1013 dwarf_reloc(dwarf_line_section
, section_sym
, R_DATA_PTR
);
1014 ptr
= section_ptr_add(dwarf_line_section
, dwarf_line
.line_size
- 3);
1015 memmove(ptr
- 3, dwarf_line
.line_data
, dwarf_line
.line_size
);
1016 tcc_free(dwarf_line
.line_data
);
1017 write32le(dwarf_line_section
->data
+ dwarf_line
.start
,
1018 dwarf_line_section
->data_offset
- dwarf_line
.start
- 4);
1022 put_stabs_r(s1
, NULL
, N_SO
, 0, 0,
1023 text_section
->data_offset
, text_section
, section_sym
);
1025 tcc_free(debug_hash
);
1026 debug_next_type
= 0;
1029 static BufferedFile
* put_new_file(TCCState
*s1
)
1031 BufferedFile
*f
= file
;
1032 /* use upper file if from inline ":asm:" */
1033 if (f
->filename
[0] == ':')
1035 if (f
&& new_file
) {
1036 new_file
= last_line_num
= 0;
1040 put_stabs_r(s1
, f
->filename
, N_SOL
, 0, 0, ind
, text_section
, section_sym
);
1045 /* put alternative filename */
1046 ST_FUNC
void tcc_debug_putfile(TCCState
*s1
, const char *filename
)
1048 if (0 == strcmp(file
->filename
, filename
))
1050 pstrcpy(file
->filename
, sizeof(file
->filename
), filename
);
1058 /* begin of #include */
1059 ST_FUNC
void tcc_debug_bincl(TCCState
*s1
)
1066 put_stabs(s1
, file
->filename
, N_BINCL
, 0, 0, 0);
1070 /* end of #include */
1071 ST_FUNC
void tcc_debug_eincl(TCCState
*s1
)
1078 put_stabn(s1
, N_EINCL
, 0, 0, 0);
1082 /* generate line number info */
1083 ST_FUNC
void tcc_debug_line(TCCState
*s1
)
1089 if (cur_text_section
!= text_section
|| nocode_wanted
)
1091 f
= put_new_file(s1
);
1094 if (last_line_num
== f
->line_num
)
1096 last_line_num
= f
->line_num
;
1099 int len_pc
= (ind
- dwarf_line
.last_pc
) / DWARF_MIN_INSTR_LEN
;
1100 int len_line
= f
->line_num
- dwarf_line
.last_line
;
1101 int n
= len_pc
* DWARF_LINE_RANGE
+ len_line
+ DWARF_OPCODE_BASE
- DWARF_LINE_BASE
;
1103 if (dwarf_line
.cur_file
!= dwarf_line
.last_file
) {
1104 dwarf_line
.last_file
= dwarf_line
.cur_file
;
1105 dwarf_line_op(s1
, DW_LNS_set_file
);
1106 dwarf_uleb128_op(s1
, dwarf_line
.cur_file
);
1109 len_line
>= DWARF_LINE_BASE
&& len_line
<= (DWARF_OPCODE_BASE
+ DWARF_LINE_BASE
) &&
1110 n
>= DWARF_OPCODE_BASE
&& n
<= 255)
1111 dwarf_line_op(s1
, n
);
1114 n
= len_pc
* DWARF_LINE_RANGE
+ 0 + DWARF_OPCODE_BASE
- DWARF_LINE_BASE
;
1115 if (n
>= DWARF_OPCODE_BASE
&& n
<= 255)
1116 dwarf_line_op(s1
, n
);
1118 dwarf_line_op(s1
, DW_LNS_advance_pc
);
1119 dwarf_uleb128_op(s1
, len_pc
);
1123 n
= 0 * DWARF_LINE_RANGE
+ len_line
+ DWARF_OPCODE_BASE
- DWARF_LINE_BASE
;
1124 if (len_line
>= DWARF_LINE_BASE
&& len_line
<= (DWARF_OPCODE_BASE
+ DWARF_LINE_BASE
) &&
1125 n
>= DWARF_OPCODE_BASE
&& n
<= 255)
1126 dwarf_line_op(s1
, n
);
1128 dwarf_line_op(s1
, DW_LNS_advance_line
);
1129 dwarf_sleb128_op(s1
, len_line
);
1133 dwarf_line
.last_pc
= ind
;
1134 dwarf_line
.last_line
= f
->line_num
;
1138 if (func_ind
!= -1) {
1139 put_stabn(s1
, N_SLINE
, 0, f
->line_num
, ind
- func_ind
);
1141 /* from tcc_assemble */
1142 put_stabs_r(s1
, NULL
, N_SLINE
, 0, f
->line_num
, ind
, text_section
, section_sym
);
1147 static void tcc_debug_stabs (TCCState
*s1
, const char *str
, int type
, unsigned long value
,
1148 Section
*sec
, int sym_index
, int info
)
1150 struct debug_sym
*s
;
1154 (struct debug_sym
*)tcc_realloc (debug_info
->sym
,
1155 sizeof(struct debug_sym
) *
1156 (debug_info
->n_sym
+ 1));
1157 s
= debug_info
->sym
+ debug_info
->n_sym
++;
1160 s
->str
= tcc_strdup(str
);
1162 s
->sym_index
= sym_index
;
1164 s
->file
= dwarf_line
.cur_file
;
1165 s
->line
= file
->line_num
;
1168 put_stabs_r (s1
, str
, type
, 0, 0, value
, sec
, sym_index
);
1170 put_stabs (s1
, str
, type
, 0, 0, value
);
1173 ST_FUNC
void tcc_debug_stabn(TCCState
*s1
, int type
, int value
)
1177 if (type
== N_LBRAC
) {
1178 struct _debug_info
*info
=
1179 (struct _debug_info
*) tcc_mallocz(sizeof (*info
));
1181 info
->start
= value
;
1182 info
->parent
= debug_info
;
1184 if (debug_info
->child
) {
1185 if (debug_info
->child
->last
)
1186 debug_info
->child
->last
->next
= info
;
1188 debug_info
->child
->next
= info
;
1189 debug_info
->child
->last
= info
;
1192 debug_info
->child
= info
;
1195 debug_info_root
= info
;
1199 debug_info
->end
= value
;
1200 debug_info
= debug_info
->parent
;
1204 static int tcc_debug_find(TCCState
*s1
, Sym
*t
, int dwarf
)
1208 if (!debug_info
&& dwarf
&&
1209 (t
->type
.t
& VT_BTYPE
) == VT_STRUCT
&& t
->c
== -1) {
1210 for (i
= 0; i
< n_debug_anon_hash
; i
++)
1211 if (t
== debug_anon_hash
[i
].type
)
1213 debug_anon_hash
= (struct _debug_anon_hash
*)
1214 tcc_realloc (debug_anon_hash
,
1215 (n_debug_anon_hash
+ 1) * sizeof(*debug_anon_hash
));
1216 debug_anon_hash
[n_debug_anon_hash
].n_debug_type
= 0;
1217 debug_anon_hash
[n_debug_anon_hash
].debug_type
= NULL
;
1218 debug_anon_hash
[n_debug_anon_hash
++].type
= t
;
1221 for (i
= 0; i
< n_debug_hash
; i
++)
1222 if (t
== debug_hash
[i
].type
)
1223 return debug_hash
[i
].debug_type
;
1227 static int tcc_get_dwarf_info(TCCState
*s1
, Sym
*s
);
1229 static void tcc_debug_check_anon(TCCState
*s1
, Sym
*t
, int debug_type
)
1233 if (!debug_info
&& (t
->type
.t
& VT_BTYPE
) == VT_STRUCT
&& t
->type
.ref
->c
== -1)
1234 for (i
= 0; i
< n_debug_anon_hash
; i
++)
1235 if (t
->type
.ref
== debug_anon_hash
[i
].type
) {
1236 debug_anon_hash
[i
].debug_type
=
1237 tcc_realloc(debug_anon_hash
[i
].debug_type
,
1238 (debug_anon_hash
[i
].n_debug_type
+ 1) * sizeof(int));
1239 debug_anon_hash
[i
].debug_type
[debug_anon_hash
[i
].n_debug_type
++] =
1244 ST_FUNC
void tcc_debug_fix_anon(TCCState
*s1
, CType
*t
)
1246 int i
, j
, debug_type
;
1248 if (!(s1
->do_debug
& 2) || !s1
->dwarf
|| debug_info
)
1251 if ((t
->t
& VT_BTYPE
) == VT_STRUCT
&& t
->ref
->c
!= -1)
1252 for (i
= 0; i
< n_debug_anon_hash
; i
++)
1253 if (t
->ref
== debug_anon_hash
[i
].type
) {
1254 Sym sym
= {0}; sym
.type
= *t
;
1256 /* Trick to not hash this struct */
1257 debug_info
= (struct _debug_info
*) t
;
1258 debug_type
= tcc_get_dwarf_info(s1
, &sym
);
1260 for (j
= 0; j
< debug_anon_hash
[i
].n_debug_type
; j
++)
1261 write32le(dwarf_info_section
->data
+
1262 debug_anon_hash
[i
].debug_type
[j
],
1263 debug_type
- dwarf_info
.start
);
1264 tcc_free(debug_anon_hash
[i
].debug_type
);
1265 n_debug_anon_hash
--;
1266 for (; i
< n_debug_anon_hash
; i
++)
1267 debug_anon_hash
[i
] = debug_anon_hash
[i
+ 1];
1271 static int tcc_debug_add(TCCState
*s1
, Sym
*t
, int dwarf
)
1273 int offset
= dwarf
? dwarf_info_section
->data_offset
: ++debug_next_type
;
1274 debug_hash
= (struct _debug_hash
*)
1275 tcc_realloc (debug_hash
,
1276 (n_debug_hash
+ 1) * sizeof(*debug_hash
));
1277 debug_hash
[n_debug_hash
].debug_type
= offset
;
1278 debug_hash
[n_debug_hash
++].type
= t
;
1282 static void tcc_debug_remove(TCCState
*s1
, Sym
*t
)
1286 for (i
= 0; i
< n_debug_hash
; i
++)
1287 if (t
== debug_hash
[i
].type
) {
1289 for (; i
< n_debug_hash
; i
++)
1290 debug_hash
[i
] = debug_hash
[i
+1];
1294 #define STRUCT_NODEBUG(s) \
1296 ((s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM && \
1297 ((s->type.t & VT_BTYPE) == VT_BYTE || \
1298 (s->type.t & VT_BTYPE) == VT_BOOL || \
1299 (s->type.t & VT_BTYPE) == VT_SHORT || \
1300 (s->type.t & VT_BTYPE) == VT_INT || \
1301 (s->type.t & VT_BTYPE) == VT_LLONG)))
1303 static void tcc_get_debug_info(TCCState
*s1
, Sym
*s
, CString
*result
)
1307 int debug_type
= -1;
1312 type
= t
->type
.t
& ~(VT_STORAGE
| VT_CONSTANT
| VT_VOLATILE
| VT_VLA
);
1313 if ((type
& VT_BTYPE
) != VT_BYTE
)
1314 type
&= ~VT_DEFSIGN
;
1315 if (type
== VT_PTR
|| type
== (VT_PTR
| VT_ARRAY
))
1316 n
++, t
= t
->type
.ref
;
1320 if ((type
& VT_BTYPE
) == VT_STRUCT
) {
1324 debug_type
= tcc_debug_find(s1
, t
, 0);
1325 if (debug_type
== -1) {
1326 debug_type
= tcc_debug_add(s1
, t
, 0);
1328 cstr_printf (&str
, "%s:T%d=%c%d",
1329 (t
->v
& ~SYM_STRUCT
) >= SYM_FIRST_ANOM
1330 ? "" : get_tok_str(t
->v
& ~SYM_STRUCT
, NULL
),
1332 IS_UNION (t
->type
.t
) ? 'u' : 's',
1335 int pos
, size
, align
;
1338 if (STRUCT_NODEBUG(t
))
1340 cstr_printf (&str
, "%s:",
1341 get_tok_str(t
->v
& ~SYM_FIELD
, NULL
));
1342 tcc_get_debug_info (s1
, t
, &str
);
1343 if (t
->type
.t
& VT_BITFIELD
) {
1344 pos
= t
->c
* 8 + BIT_POS(t
->type
.t
);
1345 size
= BIT_SIZE(t
->type
.t
);
1349 size
= type_size(&t
->type
, &align
) * 8;
1351 cstr_printf (&str
, ",%d,%d;", pos
, size
);
1353 cstr_printf (&str
, ";");
1354 tcc_debug_stabs(s1
, str
.data
, N_LSYM
, 0, NULL
, 0, 0);
1357 tcc_debug_remove(s1
, e
);
1360 else if (IS_ENUM(type
)) {
1361 Sym
*e
= t
= t
->type
.ref
;
1363 debug_type
= tcc_debug_find(s1
, t
, 0);
1364 if (debug_type
== -1) {
1365 debug_type
= tcc_debug_add(s1
, t
, 0);
1367 cstr_printf (&str
, "%s:T%d=e",
1368 (t
->v
& ~SYM_STRUCT
) >= SYM_FIRST_ANOM
1369 ? "" : get_tok_str(t
->v
& ~SYM_STRUCT
, NULL
),
1373 cstr_printf (&str
, "%s:",
1374 (t
->v
& ~SYM_FIELD
) >= SYM_FIRST_ANOM
1375 ? "" : get_tok_str(t
->v
& ~SYM_FIELD
, NULL
));
1376 cstr_printf (&str
, e
->type
.t
& VT_UNSIGNED
? "%u," : "%d,",
1379 cstr_printf (&str
, ";");
1380 tcc_debug_stabs(s1
, str
.data
, N_LSYM
, 0, NULL
, 0, 0);
1383 tcc_debug_remove(s1
, e
);
1386 else if ((type
& VT_BTYPE
) != VT_FUNC
) {
1387 type
&= ~VT_STRUCT_MASK
;
1388 for (debug_type
= 1; debug_type
<= N_DEFAULT_DEBUG
; debug_type
++)
1389 if (default_debug
[debug_type
- 1].type
== type
)
1391 if (debug_type
> N_DEFAULT_DEBUG
)
1395 cstr_printf (result
, "%d=", ++debug_next_type
);
1398 type
= t
->type
.t
& ~(VT_STORAGE
| VT_CONSTANT
| VT_VOLATILE
| VT_VLA
);
1399 if ((type
& VT_BTYPE
) != VT_BYTE
)
1400 type
&= ~VT_DEFSIGN
;
1402 cstr_printf (result
, "%d=*", ++debug_next_type
);
1403 else if (type
== (VT_PTR
| VT_ARRAY
))
1404 cstr_printf (result
, "%d=ar1;0;%d;",
1405 ++debug_next_type
, t
->type
.ref
->c
- 1);
1406 else if (type
== VT_FUNC
) {
1407 cstr_printf (result
, "%d=f", ++debug_next_type
);
1408 tcc_get_debug_info (s1
, t
->type
.ref
, result
);
1415 cstr_printf (result
, "%d", debug_type
);
1418 static int tcc_get_dwarf_info(TCCState
*s1
, Sym
*s
)
1421 int debug_type
= -1;
1430 type
= t
->type
.t
& ~(VT_STORAGE
| VT_CONSTANT
| VT_VOLATILE
| VT_VLA
);
1431 if ((type
& VT_BTYPE
) != VT_BYTE
)
1432 type
&= ~VT_DEFSIGN
;
1433 if (type
== VT_PTR
|| type
== (VT_PTR
| VT_ARRAY
))
1438 if ((type
& VT_BTYPE
) == VT_STRUCT
) {
1440 debug_type
= tcc_debug_find(s1
, t
, 1);
1441 if (debug_type
== -1) {
1442 int pos_sib
= 0, i
, *pos_type
;
1444 debug_type
= tcc_debug_add(s1
, t
, 1);
1449 if (STRUCT_NODEBUG(e
))
1453 pos_type
= (int *) tcc_malloc(i
* sizeof(int));
1454 dwarf_data1(dwarf_info_section
,
1455 IS_UNION (t
->type
.t
)
1456 ? t
->next
? DWARF_ABBREV_UNION_TYPE
1457 : DWARF_ABBREV_UNION_EMPTY_TYPE
1458 : t
->next
? DWARF_ABBREV_STRUCTURE_TYPE
1459 : DWARF_ABBREV_STRUCTURE_EMPTY_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
);
1467 pos_sib
= dwarf_info_section
->data_offset
;
1468 dwarf_data4(dwarf_info_section
, 0);
1474 if (STRUCT_NODEBUG(e
))
1476 dwarf_data1(dwarf_info_section
,
1477 e
->type
.t
& VT_BITFIELD
? DWARF_ABBREV_MEMBER_BF
1478 : DWARF_ABBREV_MEMBER
);
1479 dwarf_strp(dwarf_info_section
,
1480 get_tok_str(e
->v
& ~SYM_FIELD
, NULL
));
1481 dwarf_uleb128(dwarf_info_section
, dwarf_line
.cur_file
);
1482 dwarf_uleb128(dwarf_info_section
, file
->line_num
);
1483 pos_type
[i
++] = dwarf_info_section
->data_offset
;
1484 dwarf_data4(dwarf_info_section
, 0);
1485 if (e
->type
.t
& VT_BITFIELD
) {
1486 int pos
= e
->c
* 8 + BIT_POS(e
->type
.t
);
1487 int size
= BIT_SIZE(e
->type
.t
);
1489 dwarf_uleb128(dwarf_info_section
, size
);
1490 dwarf_uleb128(dwarf_info_section
, pos
);
1493 dwarf_uleb128(dwarf_info_section
, e
->c
);
1496 dwarf_data1(dwarf_info_section
, 0);
1497 write32le(dwarf_info_section
->data
+ pos_sib
,
1498 dwarf_info_section
->data_offset
- dwarf_info
.start
);
1504 if (STRUCT_NODEBUG(e
))
1506 type
= tcc_get_dwarf_info(s1
, e
);
1507 tcc_debug_check_anon(s1
, e
, pos_type
[i
]);
1508 write32le(dwarf_info_section
->data
+ pos_type
[i
++],
1509 type
- dwarf_info
.start
);
1513 tcc_debug_remove(s1
, t
);
1516 else if (IS_ENUM(type
)) {
1518 debug_type
= tcc_debug_find(s1
, t
, 1);
1519 if (debug_type
== -1) {
1520 int pos_sib
, pos_type
;
1521 Sym sym
= {0}; sym
.type
.t
= VT_INT
| (type
& VT_UNSIGNED
);
1523 pos_type
= tcc_get_dwarf_info(s1
, &sym
);
1524 debug_type
= tcc_debug_add(s1
, 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);
1540 dwarf_data1(dwarf_info_section
,
1541 type
& VT_UNSIGNED
? DWARF_ABBREV_ENUMERATOR_UNSIGNED
1542 : DWARF_ABBREV_ENUMERATOR_SIGNED
);
1543 dwarf_strp(dwarf_info_section
,
1544 (e
->v
& ~SYM_FIELD
) >= SYM_FIRST_ANOM
1545 ? "" : get_tok_str(e
->v
& ~SYM_FIELD
, NULL
));
1546 if (type
& VT_UNSIGNED
)
1547 dwarf_uleb128(dwarf_info_section
, e
->enum_val
);
1549 dwarf_sleb128(dwarf_info_section
, e
->enum_val
);
1551 dwarf_data1(dwarf_info_section
, 0);
1552 write32le(dwarf_info_section
->data
+ pos_sib
,
1553 dwarf_info_section
->data_offset
- dwarf_info
.start
);
1555 tcc_debug_remove(s1
, t
);
1558 else if ((type
& VT_BTYPE
) != VT_FUNC
) {
1559 type
&= ~VT_STRUCT_MASK
;
1560 for (i
= 1; i
<= N_DEFAULT_DEBUG
; i
++)
1561 if (default_debug
[i
- 1].type
== type
)
1563 if (i
> N_DEFAULT_DEBUG
)
1565 debug_type
= dwarf_info
.base_type_used
[i
- 1];
1566 if (debug_type
== 0) {
1569 debug_type
= dwarf_info_section
->data_offset
;
1570 dwarf_data1(dwarf_info_section
, DWARF_ABBREV_BASE_TYPE
);
1571 dwarf_uleb128(dwarf_info_section
, default_debug
[i
- 1].size
);
1572 dwarf_data1(dwarf_info_section
, default_debug
[i
- 1].encoding
);
1573 strncpy(name
, default_debug
[i
- 1].name
, sizeof(name
) -1);
1574 *strchr(name
, ':') = 0;
1575 dwarf_strp(dwarf_info_section
, name
);
1576 dwarf_info
.base_type_used
[i
- 1] = debug_type
;
1579 retval
= debug_type
;
1583 type
= t
->type
.t
& ~(VT_STORAGE
| VT_CONSTANT
| VT_VOLATILE
| VT_VLA
);
1584 if ((type
& VT_BTYPE
) != VT_BYTE
)
1585 type
&= ~VT_DEFSIGN
;
1586 if (type
== VT_PTR
) {
1587 i
= dwarf_info_section
->data_offset
;
1588 if (retval
== debug_type
)
1590 dwarf_data1(dwarf_info_section
, DWARF_ABBREV_POINTER
);
1591 dwarf_data1(dwarf_info_section
, PTR_SIZE
);
1592 if (last_pos
!= -1) {
1593 tcc_debug_check_anon(s1
, e
, last_pos
);
1594 write32le(dwarf_info_section
->data
+ last_pos
,
1595 i
- dwarf_info
.start
);
1597 last_pos
= dwarf_info_section
->data_offset
;
1599 dwarf_data4(dwarf_info_section
, 0);
1601 else if (type
== (VT_PTR
| VT_ARRAY
)) {
1602 int sib_pos
, sub_type
;
1604 Sym sym
= {0}; sym
.type
.t
= VT_LONG
| VT_INT
| VT_UNSIGNED
;
1606 Sym sym
= {0}; sym
.type
.t
= VT_LLONG
| VT_LONG
| VT_UNSIGNED
;
1609 sub_type
= tcc_get_dwarf_info(s1
, &sym
);
1610 i
= dwarf_info_section
->data_offset
;
1611 if (retval
== debug_type
)
1613 dwarf_data1(dwarf_info_section
, DWARF_ABBREV_ARRAY_TYPE
);
1614 if (last_pos
!= -1) {
1615 tcc_debug_check_anon(s1
, e
, last_pos
);
1616 write32le(dwarf_info_section
->data
+ last_pos
,
1617 i
- dwarf_info
.start
);
1619 last_pos
= dwarf_info_section
->data_offset
;
1621 dwarf_data4(dwarf_info_section
, 0);
1622 sib_pos
= dwarf_info_section
->data_offset
;
1623 dwarf_data4(dwarf_info_section
, 0);
1625 dwarf_data1(dwarf_info_section
, DWARF_ABBREV_SUBRANGE_TYPE
);
1626 dwarf_data4(dwarf_info_section
, sub_type
- dwarf_info
.start
);
1627 dwarf_uleb128(dwarf_info_section
, t
->type
.ref
->c
- 1);
1629 type
= s
->type
.t
& ~(VT_STORAGE
| VT_CONSTANT
| VT_VOLATILE
);
1630 if (type
!= (VT_PTR
| VT_ARRAY
))
1634 dwarf_data1(dwarf_info_section
, 0);
1635 write32le(dwarf_info_section
->data
+ sib_pos
,
1636 dwarf_info_section
->data_offset
- dwarf_info
.start
);
1638 else if (type
== VT_FUNC
) {
1639 int sib_pos
= 0, *pos_type
;
1642 i
= dwarf_info_section
->data_offset
;
1643 debug_type
= tcc_get_dwarf_info(s1
, t
->type
.ref
);
1644 if (retval
== debug_type
)
1646 dwarf_data1(dwarf_info_section
,
1647 t
->type
.ref
->next
? DWARF_ABBREV_SUBROUTINE_TYPE
1648 : DWARF_ABBREV_SUBROUTINE_EMPTY_TYPE
);
1649 if (last_pos
!= -1) {
1650 tcc_debug_check_anon(s1
, e
, last_pos
);
1651 write32le(dwarf_info_section
->data
+ last_pos
,
1652 i
- dwarf_info
.start
);
1654 last_pos
= dwarf_info_section
->data_offset
;
1656 dwarf_data4(dwarf_info_section
, 0);
1657 if (t
->type
.ref
->next
) {
1658 sib_pos
= dwarf_info_section
->data_offset
;
1659 dwarf_data4(dwarf_info_section
, 0);
1667 pos_type
= (int *) tcc_malloc(i
* sizeof(int));
1672 dwarf_data1(dwarf_info_section
, DWARF_ABBREV_FORMAL_PARAMETER2
);
1673 pos_type
[i
++] = dwarf_info_section
->data_offset
;
1674 dwarf_data4(dwarf_info_section
, 0);
1676 if (t
->type
.ref
->next
) {
1677 dwarf_data1(dwarf_info_section
, 0);
1678 write32le(dwarf_info_section
->data
+ sib_pos
,
1679 dwarf_info_section
->data_offset
- dwarf_info
.start
);
1685 type
= tcc_get_dwarf_info(s1
, f
);
1686 tcc_debug_check_anon(s1
, f
, pos_type
[i
]);
1687 write32le(dwarf_info_section
->data
+ pos_type
[i
++],
1688 type
- dwarf_info
.start
);
1693 if (last_pos
!= -1) {
1694 tcc_debug_check_anon(s1
, e
, last_pos
);
1695 write32le(dwarf_info_section
->data
+ last_pos
,
1696 debug_type
- dwarf_info
.start
);
1705 static void tcc_debug_finish (TCCState
*s1
, struct _debug_info
*cur
)
1708 struct _debug_info
*next
= cur
->next
;
1713 for (i
= cur
->n_sym
- 1; i
>= 0; i
--) {
1714 struct debug_sym
*s
= &cur
->sym
[i
];
1716 dwarf_data1(dwarf_info_section
,
1718 ? DWARF_ABBREV_FORMAL_PARAMETER
1720 ? DWARF_ABBREV_VARIABLE_EXTERNAL
1721 : s
->type
== N_STSYM
1722 ? DWARF_ABBREV_VARIABLE_STATIC
1723 : DWARF_ABBREV_VARIABLE_LOCAL
);
1724 dwarf_strp(dwarf_info_section
, s
->str
);
1725 if (s
->type
== N_GSYM
|| s
->type
== N_STSYM
) {
1726 dwarf_uleb128(dwarf_info_section
, s
->file
);
1727 dwarf_uleb128(dwarf_info_section
, s
->line
);
1729 dwarf_data4(dwarf_info_section
, s
->info
- dwarf_info
.start
);
1730 if (s
->type
== N_GSYM
|| s
->type
== N_STSYM
) {
1732 if (s
->type
== N_GSYM
)
1733 dwarf_data1(dwarf_info_section
, 1);
1734 dwarf_data1(dwarf_info_section
, PTR_SIZE
+ 1);
1735 dwarf_data1(dwarf_info_section
, DW_OP_addr
);
1736 if (s
->type
== N_STSYM
)
1737 dwarf_reloc(dwarf_info_section
, section_sym
, R_DATA_PTR
);
1739 dwarf_data4(dwarf_info_section
, s
->value
);
1741 dwarf_data8(dwarf_info_section
, s
->value
);
1746 dwarf_data1(dwarf_info_section
, dwarf_sleb128_size(s
->value
) + 1);
1747 dwarf_data1(dwarf_info_section
, DW_OP_fbreg
);
1748 dwarf_sleb128(dwarf_info_section
, s
->value
);
1752 tcc_free (cur
->sym
);
1753 dwarf_data1(dwarf_info_section
,
1754 cur
->child
? DWARF_ABBREV_LEXICAL_BLOCK
1755 : DWARF_ABBREV_LEXICAL_EMPTY_BLOCK
);
1756 dwarf_reloc(dwarf_info_section
, section_sym
, R_DATA_PTR
);
1758 dwarf_data4(dwarf_info_section
, func_ind
+ cur
->start
);
1759 dwarf_data4(dwarf_info_section
, cur
->end
- cur
->start
);
1761 dwarf_data8(dwarf_info_section
, func_ind
+ cur
->start
);
1762 dwarf_data8(dwarf_info_section
, cur
->end
- cur
->start
);
1764 tcc_debug_finish (s1
, cur
->child
);
1766 dwarf_data1(dwarf_info_section
, 0);
1770 for (i
= 0; i
< cur
->n_sym
; i
++) {
1771 struct debug_sym
*s
= &cur
->sym
[i
];
1774 put_stabs_r(s1
, s
->str
, s
->type
, 0, 0, s
->value
,
1775 s
->sec
, s
->sym_index
);
1777 put_stabs(s1
, s
->str
, s
->type
, 0, 0, s
->value
);
1780 tcc_free (cur
->sym
);
1781 put_stabn(s1
, N_LBRAC
, 0, 0, cur
->start
);
1782 tcc_debug_finish (s1
, cur
->child
);
1783 put_stabn(s1
, N_RBRAC
, 0, 0, cur
->end
);
1790 ST_FUNC
void tcc_add_debug_info(TCCState
*s1
, int param
, Sym
*s
, Sym
*e
)
1794 if (!(s1
->do_debug
& 2))
1797 cstr_new (&debug_str
);
1798 for (; s
!= e
; s
= s
->prev
) {
1799 if (!s
->v
|| (s
->r
& VT_VALMASK
) != VT_LOCAL
)
1802 tcc_debug_stabs(s1
, get_tok_str(s
->v
, NULL
),
1803 param
? N_PSYM
: N_LSYM
, s
->c
, NULL
, 0,
1804 tcc_get_dwarf_info(s1
, s
));
1808 cstr_reset (&debug_str
);
1809 cstr_printf (&debug_str
, "%s:%s", get_tok_str(s
->v
, NULL
),
1811 tcc_get_debug_info(s1
, s
, &debug_str
);
1812 tcc_debug_stabs(s1
, debug_str
.data
, param
? N_PSYM
: N_LSYM
,
1816 cstr_free (&debug_str
);
1819 /* put function symbol */
1820 ST_FUNC
void tcc_debug_funcstart(TCCState
*s1
, Sym
*sym
)
1827 debug_info_root
= NULL
;
1829 tcc_debug_stabn(s1
, N_LBRAC
, ind
- func_ind
);
1830 f
= put_new_file(s1
);
1836 dwarf_info
.func
= sym
;
1837 dwarf_info
.line
= file
->line_num
;
1838 if (s1
->do_backtrace
) {
1841 dwarf_line_op(s1
, 0); // extended
1842 dwarf_uleb128_op(s1
, strlen(funcname
) + 2);
1843 dwarf_line_op(s1
, DW_LNE_hi_user
- 1);
1844 len
= strlen(funcname
) + 1;
1845 for (i
= 0; i
< len
; i
++)
1846 dwarf_line_op(s1
, funcname
[i
]);
1851 cstr_new (&debug_str
);
1852 cstr_printf(&debug_str
, "%s:%c", funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
1853 tcc_get_debug_info(s1
, sym
->type
.ref
, &debug_str
);
1854 put_stabs_r(s1
, debug_str
.data
, N_FUN
, 0, f
->line_num
, 0, cur_text_section
, sym
->c
);
1855 cstr_free (&debug_str
);
1860 ST_FUNC
void tcc_debug_prolog_epilog(TCCState
*s1
, int value
)
1865 dwarf_line_op(s1
, value
== 0 ? DW_LNS_set_prologue_end
1866 : DW_LNS_set_epilogue_begin
);
1870 /* put function size */
1871 ST_FUNC
void tcc_debug_funcend(TCCState
*s1
, int size
)
1873 /* lldb does not like function end and next function start at same pc */
1878 min_instr_len
= dwarf_line
.last_pc
== ind
? 0 : DWARF_MIN_INSTR_LEN
;
1879 ind
-= min_instr_len
;
1881 ind
+= min_instr_len
;
1882 tcc_debug_stabn(s1
, N_RBRAC
, size
);
1885 Sym
*sym
= dwarf_info
.func
;
1886 int n_debug_info
= tcc_get_dwarf_info(s1
, sym
->type
.ref
);
1888 dwarf_data1(dwarf_info_section
,
1889 sym
->type
.t
& VT_STATIC
? DWARF_ABBREV_SUBPROGRAM_STATIC
1890 : DWARF_ABBREV_SUBPROGRAM_EXTERNAL
);
1891 if ((sym
->type
.t
& VT_STATIC
) == 0)
1892 dwarf_data1(dwarf_info_section
, 1);
1893 dwarf_strp(dwarf_info_section
, funcname
);
1894 dwarf_uleb128(dwarf_info_section
, dwarf_line
.cur_file
);
1895 dwarf_uleb128(dwarf_info_section
, dwarf_info
.line
);
1896 tcc_debug_check_anon(s1
, sym
->type
.ref
, dwarf_info_section
->data_offset
);
1897 dwarf_data4(dwarf_info_section
, n_debug_info
- dwarf_info
.start
);
1898 dwarf_reloc(dwarf_info_section
, section_sym
, R_DATA_PTR
);
1900 dwarf_data4(dwarf_info_section
, func_ind
); // low_pc
1901 dwarf_data4(dwarf_info_section
, size
); // high_pc
1903 dwarf_data8(dwarf_info_section
, func_ind
); // low_pc
1904 dwarf_data8(dwarf_info_section
, size
); // high_pc
1906 func_sib
= dwarf_info_section
->data_offset
;
1907 dwarf_data4(dwarf_info_section
, 0); // sibling
1908 dwarf_data1(dwarf_info_section
, 1);
1909 #if defined(TCC_TARGET_I386)
1910 dwarf_data1(dwarf_info_section
, DW_OP_reg5
); // ebp
1911 #elif defined(TCC_TARGET_X86_64)
1912 dwarf_data1(dwarf_info_section
, DW_OP_reg6
); // rbp
1913 #elif defined TCC_TARGET_ARM
1914 dwarf_data1(dwarf_info_section
, DW_OP_reg13
); // sp
1915 #elif defined TCC_TARGET_ARM64
1916 dwarf_data1(dwarf_info_section
, DW_OP_reg29
); // reg 29
1917 #elif defined TCC_TARGET_RISCV64
1918 dwarf_data1(dwarf_info_section
, DW_OP_reg8
); // r8(s0)
1920 dwarf_data1(dwarf_info_section
, DW_OP_call_frame_cfa
);
1922 tcc_debug_finish (s1
, debug_info_root
);
1923 dwarf_data1(dwarf_info_section
, 0);
1924 write32le(dwarf_info_section
->data
+ func_sib
,
1925 dwarf_info_section
->data_offset
- dwarf_info
.start
);
1929 tcc_debug_finish (s1
, debug_info_root
);
1931 debug_info_root
= 0;
1935 ST_FUNC
void tcc_debug_extern_sym(TCCState
*s1
, Sym
*sym
, int sh_num
, int sym_bind
, int sym_type
)
1937 if (!(s1
->do_debug
& 2))
1940 if (sym_type
== STT_FUNC
|| sym
->v
>= SYM_FIRST_ANOM
)
1945 debug_type
= tcc_get_dwarf_info(s1
, sym
);
1946 dwarf_data1(dwarf_info_section
,
1947 sym_bind
== STB_GLOBAL
1948 ? DWARF_ABBREV_VARIABLE_EXTERNAL
1949 : DWARF_ABBREV_VARIABLE_STATIC
);
1950 dwarf_strp(dwarf_info_section
, get_tok_str(sym
->v
, NULL
));
1951 dwarf_uleb128(dwarf_info_section
, dwarf_line
.cur_file
);
1952 dwarf_uleb128(dwarf_info_section
, file
->line_num
);
1953 tcc_debug_check_anon(s1
, sym
, dwarf_info_section
->data_offset
);
1954 dwarf_data4(dwarf_info_section
, debug_type
- dwarf_info
.start
);
1955 if (sym_bind
== STB_GLOBAL
)
1956 dwarf_data1(dwarf_info_section
, 1);
1957 dwarf_data1(dwarf_info_section
, PTR_SIZE
+ 1);
1958 dwarf_data1(dwarf_info_section
, DW_OP_addr
);
1959 greloca(dwarf_info_section
, sym
, dwarf_info_section
->data_offset
,
1962 dwarf_data4(dwarf_info_section
, 0);
1964 dwarf_data8(dwarf_info_section
, 0);
1969 Section
*s
= sh_num
== SHN_COMMON
? common_section
1970 : s1
->sections
[sh_num
];
1974 cstr_printf (&str
, "%s:%c",
1975 get_tok_str(sym
->v
, NULL
),
1976 sym_bind
== STB_GLOBAL
? 'G' : func_ind
!= -1 ? 'V' : 'S'
1978 tcc_get_debug_info(s1
, sym
, &str
);
1979 if (sym_bind
== STB_GLOBAL
)
1980 tcc_debug_stabs(s1
, str
.data
, N_GSYM
, 0, NULL
, 0, 0);
1982 tcc_debug_stabs(s1
, str
.data
,
1983 (sym
->type
.t
& VT_STATIC
) && data_section
== s
1984 ? N_STSYM
: N_LCSYM
, 0, s
, sym
->c
, 0);
1989 ST_FUNC
void tcc_debug_typedef(TCCState
*s1
, Sym
*sym
)
1991 if (!(s1
->do_debug
& 2))
1997 debug_type
= tcc_get_dwarf_info(s1
, sym
);
1998 if (debug_type
!= -1) {
1999 dwarf_data1(dwarf_info_section
, DWARF_ABBREV_TYPEDEF
);
2000 dwarf_strp(dwarf_info_section
, get_tok_str(sym
->v
& ~SYM_FIELD
, NULL
));
2001 dwarf_uleb128(dwarf_info_section
, dwarf_line
.cur_file
);
2002 dwarf_uleb128(dwarf_info_section
, file
->line_num
);
2003 tcc_debug_check_anon(s1
, sym
, dwarf_info_section
->data_offset
);
2004 dwarf_data4(dwarf_info_section
, debug_type
- dwarf_info
.start
);
2011 cstr_printf (&str
, "%s:t",
2012 (sym
->v
& ~SYM_FIELD
) >= SYM_FIRST_ANOM
2013 ? "" : get_tok_str(sym
->v
& ~SYM_FIELD
, NULL
));
2014 tcc_get_debug_info(s1
, sym
, &str
);
2015 tcc_debug_stabs(s1
, str
.data
, N_LSYM
, 0, NULL
, 0, 0);
2020 /* ------------------------------------------------------------------------- */
2021 /* for section layout see lib/tcov.c */
2023 ST_FUNC
void tcc_tcov_block_end(TCCState
*s1
, int line
);
2025 ST_FUNC
void tcc_tcov_block_begin(TCCState
*s1
)
2029 unsigned long last_offset
= tcov_data
.offset
;
2031 tcc_tcov_block_end (tcc_state
, 0);
2032 if (s1
->test_coverage
== 0 || nocode_wanted
)
2035 if (tcov_data
.last_file_name
== 0 ||
2036 strcmp ((const char *)(tcov_section
->data
+ tcov_data
.last_file_name
),
2037 file
->true_filename
) != 0) {
2041 if (tcov_data
.last_func_name
)
2042 section_ptr_add(tcov_section
, 1);
2043 if (tcov_data
.last_file_name
)
2044 section_ptr_add(tcov_section
, 1);
2045 tcov_data
.last_func_name
= 0;
2047 if (file
->true_filename
[0] == '/') {
2048 tcov_data
.last_file_name
= tcov_section
->data_offset
;
2049 cstr_printf (&cstr
, "%s", file
->true_filename
);
2052 getcwd (wd
, sizeof(wd
));
2053 tcov_data
.last_file_name
= tcov_section
->data_offset
+ strlen(wd
) + 1;
2054 cstr_printf (&cstr
, "%s/%s", wd
, file
->true_filename
);
2056 ptr
= section_ptr_add(tcov_section
, cstr
.size
+ 1);
2057 strcpy((char *)ptr
, cstr
.data
);
2059 normalize_slashes((char *)ptr
);
2063 if (tcov_data
.last_func_name
== 0 ||
2064 strcmp ((const char *)(tcov_section
->data
+ tcov_data
.last_func_name
),
2068 if (tcov_data
.last_func_name
)
2069 section_ptr_add(tcov_section
, 1);
2070 tcov_data
.last_func_name
= tcov_section
->data_offset
;
2071 len
= strlen (funcname
);
2072 ptr
= section_ptr_add(tcov_section
, len
+ 1);
2073 strcpy((char *)ptr
, funcname
);
2074 section_ptr_add(tcov_section
, -tcov_section
->data_offset
& 7);
2075 ptr
= section_ptr_add(tcov_section
, 8);
2076 write64le (ptr
, file
->line_num
);
2078 if (ind
== tcov_data
.ind
&& tcov_data
.line
== file
->line_num
)
2079 tcov_data
.offset
= last_offset
;
2082 label
.type
.t
= VT_LLONG
| VT_STATIC
;
2084 ptr
= section_ptr_add(tcov_section
, 16);
2085 tcov_data
.line
= file
->line_num
;
2086 write64le (ptr
, (tcov_data
.line
<< 8) | 0xff);
2087 put_extern_sym(&label
, tcov_section
,
2088 ((unsigned char *)ptr
- tcov_section
->data
) + 8, 0);
2089 sv
.type
= label
.type
;
2090 sv
.r
= VT_SYM
| VT_LVAL
| VT_CONST
;
2094 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || \
2095 defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64 || \
2096 defined TCC_TARGET_RISCV64
2097 gen_increment_tcov (&sv
);
2103 tcov_data
.offset
= (unsigned char *)ptr
- tcov_section
->data
;
2104 tcov_data
.ind
= ind
;
2108 ST_FUNC
void tcc_tcov_block_end(TCCState
*s1
, int line
)
2110 if (s1
->test_coverage
== 0)
2113 line
= tcov_data
.line
;
2114 if (tcov_data
.offset
) {
2115 void *ptr
= tcov_section
->data
+ tcov_data
.offset
;
2116 unsigned long long nline
= line
? line
: file
->line_num
;
2118 write64le (ptr
, (read64le (ptr
) & 0xfffffffffull
) | (nline
<< 36));
2119 tcov_data
.offset
= 0;
2123 ST_FUNC
void tcc_tcov_check_line(TCCState
*s1
, int start
)
2125 if (s1
->test_coverage
== 0)
2127 if (tcov_data
.line
!= file
->line_num
) {
2128 if ((tcov_data
.line
+ 1) != file
->line_num
) {
2129 tcc_tcov_block_end (s1
, -1);
2131 tcc_tcov_block_begin (s1
);
2134 tcov_data
.line
= file
->line_num
;
2138 ST_FUNC
void tcc_tcov_start(TCCState
*s1
)
2140 if (s1
->test_coverage
== 0)
2143 s1
->dState
= tcc_mallocz(sizeof *s1
->dState
);
2144 memset (&tcov_data
, 0, sizeof (tcov_data
));
2145 if (tcov_section
== NULL
) {
2146 tcov_section
= new_section(tcc_state
, ".tcov", SHT_PROGBITS
,
2147 SHF_ALLOC
| SHF_WRITE
);
2148 section_ptr_add(tcov_section
, 4); // pointer to executable name
2152 ST_FUNC
void tcc_tcov_end(TCCState
*s1
)
2154 if (s1
->test_coverage
== 0)
2156 if (tcov_data
.last_func_name
)
2157 section_ptr_add(tcov_section
, 1);
2158 if (tcov_data
.last_file_name
)
2159 section_ptr_add(tcov_section
, 1);
2162 ST_FUNC
void tcc_tcov_reset_ind(TCCState
*s1
)
2167 /* ------------------------------------------------------------------------- */
2168 #undef last_line_num
2171 #undef debug_next_type
2174 #undef debug_anon_hash
2175 #undef n_debug_anon_hash
2177 #undef debug_info_root