libtcc: Activate DWARF debug infos with tcc -gdwarf ...
[tinycc.git] / tccdbg.c
blob6cea40c9ad1b1082603daf57de2457f09cb06dee
1 /*
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
21 #include "tcc.h"
23 /* stab debug support */
25 static const struct {
26 int type;
27 int size;
28 int encoding;
29 const char *name;
30 } default_debug[] = {
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;" },
33 #if LONG_SIZE == 4
34 { VT_LONG | VT_INT, 4, DW_ATE_signed, "long int:t3=r3;-2147483648;2147483647;" },
35 #else
36 { VT_LLONG | VT_LONG, 8, DW_ATE_signed, "long int:t3=r3;-9223372036854775808;9223372036854775807;" },
37 #endif
38 { VT_INT | VT_UNSIGNED, 4, DW_ATE_unsigned, "unsigned int:t4=r4;0;037777777777;" },
39 #if LONG_SIZE == 4
40 { VT_LONG | VT_INT | VT_UNSIGNED, 4, DW_ATE_unsigned, "long unsigned int:t5=r5;0;037777777777;" },
41 #else
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;" },
44 #endif
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;" },
57 #else
58 { VT_LDOUBLE, 16, DW_ATE_float, "long double:t16=r1;16;0;" },
59 #endif
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;" },
70 /* boolean type */
71 { VT_BOOL, 1, DW_ATE_boolean, "bool:t26=r26;0;255;" },
72 #if LONG_SIZE == 4
73 { VT_VOID, 1, DW_ATE_unsigned_char, "void:t27=27" },
74 #else
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" },
79 #endif
82 #define N_DEFAULT_DEBUG (sizeof (default_debug) / sizeof (default_debug[0]))
84 /* dwarf debug */
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
94 #else
95 #define DWARF_MIN_INSTR_LEN 1
96 #endif
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_UNION_TYPE 17
115 #define DWARF_ABBREV_SUBPROGRAM_EXTERNAL 18
116 #define DWARF_ABBREV_SUBPROGRAM_STATIC 19
117 #define DWARF_ABBREV_LEXICAL_BLOCK 20
118 #define DWARF_ABBREV_SUBROUTINE_TYPE 21
119 #define DWARF_ABBREV_FORMAL_PARAMETER2 22
121 /* all entries should have been generated with dwarf_uleb128 except
122 has_children. All values are currently below 128 so this currently
123 works. */
124 static const unsigned char dwarf_abbrev_init[] = {
125 DWARF_ABBREV_COMPILE_UNIT, DW_TAG_compile_unit, 1,
126 DW_AT_producer, DW_FORM_strp,
127 DW_AT_language, DW_FORM_data1,
128 DW_AT_name, DW_FORM_line_strp,
129 DW_AT_comp_dir, DW_FORM_line_strp,
130 DW_AT_low_pc, DW_FORM_addr,
131 #if PTR_SIZE == 4
132 DW_AT_high_pc, DW_FORM_data4,
133 #else
134 DW_AT_high_pc, DW_FORM_data8,
135 #endif
136 DW_AT_stmt_list, DW_FORM_sec_offset,
137 0, 0,
138 DWARF_ABBREV_BASE_TYPE, DW_TAG_base_type, 0,
139 DW_AT_byte_size, DW_FORM_udata,
140 DW_AT_encoding, DW_FORM_data1,
141 DW_AT_name, DW_FORM_strp,
142 0, 0,
143 DWARF_ABBREV_VARIABLE_EXTERNAL, DW_TAG_variable, 0,
144 DW_AT_name, DW_FORM_strp,
145 DW_AT_decl_file, DW_FORM_udata,
146 DW_AT_decl_line, DW_FORM_udata,
147 DW_AT_type, DW_FORM_ref4,
148 DW_AT_external, DW_FORM_flag,
149 DW_AT_location, DW_FORM_exprloc,
150 0, 0,
151 DWARF_ABBREV_VARIABLE_STATIC, DW_TAG_variable, 0,
152 DW_AT_name, DW_FORM_strp,
153 DW_AT_decl_file, DW_FORM_udata,
154 DW_AT_decl_line, DW_FORM_udata,
155 DW_AT_type, DW_FORM_ref4,
156 DW_AT_location, DW_FORM_exprloc,
157 0, 0,
158 DWARF_ABBREV_VARIABLE_LOCAL, DW_TAG_variable, 0,
159 DW_AT_name, DW_FORM_strp,
160 DW_AT_type, DW_FORM_ref4,
161 DW_AT_location, DW_FORM_exprloc,
162 0, 0,
163 DWARF_ABBREV_FORMAL_PARAMETER, DW_TAG_formal_parameter, 0,
164 DW_AT_name, DW_FORM_strp,
165 DW_AT_type, DW_FORM_ref4,
166 DW_AT_location, DW_FORM_exprloc,
167 0, 0,
168 DWARF_ABBREV_POINTER, DW_TAG_pointer_type, 0,
169 DW_AT_byte_size, DW_FORM_data1,
170 DW_AT_type, DW_FORM_ref4,
171 0, 0,
172 DWARF_ABBREV_ARRAY_TYPE, DW_TAG_array_type, 1,
173 DW_AT_type, DW_FORM_ref4,
174 DW_AT_sibling, DW_FORM_ref4,
175 0, 0,
176 DWARF_ABBREV_SUBRANGE_TYPE, DW_TAG_subrange_type, 0,
177 DW_AT_type, DW_FORM_ref4,
178 DW_AT_upper_bound, DW_FORM_udata,
179 0, 0,
180 DWARF_ABBREV_TYPEDEF, DW_TAG_typedef, 0,
181 DW_AT_name, DW_FORM_strp,
182 DW_AT_decl_file, DW_FORM_udata,
183 DW_AT_decl_line, DW_FORM_udata,
184 DW_AT_type, DW_FORM_ref4,
185 0, 0,
186 DWARF_ABBREV_ENUMERATOR_SIGNED, DW_TAG_enumerator, 0,
187 DW_AT_name, DW_FORM_strp,
188 DW_AT_const_value, DW_FORM_sdata,
189 0, 0,
190 DWARF_ABBREV_ENUMERATOR_UNSIGNED, DW_TAG_enumerator, 0,
191 DW_AT_name, DW_FORM_strp,
192 DW_AT_const_value, DW_FORM_udata,
193 0, 0,
194 DWARF_ABBREV_ENUMERATION_TYPE, DW_TAG_enumeration_type, 1,
195 DW_AT_name, DW_FORM_strp,
196 DW_AT_encoding, DW_FORM_data1,
197 DW_AT_byte_size, DW_FORM_data1,
198 DW_AT_type, DW_FORM_ref4,
199 DW_AT_decl_file, DW_FORM_udata,
200 DW_AT_decl_line, DW_FORM_udata,
201 DW_AT_sibling, DW_FORM_ref4,
202 0, 0,
203 DWARF_ABBREV_MEMBER, DW_TAG_member, 0,
204 DW_AT_name, DW_FORM_strp,
205 DW_AT_decl_file, DW_FORM_udata,
206 DW_AT_decl_line, DW_FORM_udata,
207 DW_AT_type, DW_FORM_ref4,
208 DW_AT_data_member_location, DW_FORM_udata,
209 0, 0,
210 DWARF_ABBREV_MEMBER_BF, DW_TAG_member, 0,
211 DW_AT_name, DW_FORM_strp,
212 DW_AT_decl_file, DW_FORM_udata,
213 DW_AT_decl_line, DW_FORM_udata,
214 DW_AT_type, DW_FORM_ref4,
215 DW_AT_bit_size, DW_FORM_udata,
216 DW_AT_data_bit_offset, DW_FORM_udata,
217 0, 0,
218 DWARF_ABBREV_STRUCTURE_TYPE, DW_TAG_structure_type, 1,
219 DW_AT_name, DW_FORM_strp,
220 DW_AT_byte_size, DW_FORM_udata,
221 DW_AT_decl_file, DW_FORM_udata,
222 DW_AT_decl_line, DW_FORM_udata,
223 DW_AT_sibling, DW_FORM_ref4,
224 0, 0,
225 DWARF_ABBREV_UNION_TYPE, DW_TAG_union_type, 1,
226 DW_AT_name, DW_FORM_strp,
227 DW_AT_byte_size, DW_FORM_udata,
228 DW_AT_decl_file, DW_FORM_udata,
229 DW_AT_decl_line, DW_FORM_udata,
230 DW_AT_sibling, DW_FORM_ref4,
231 0, 0,
232 DWARF_ABBREV_SUBPROGRAM_EXTERNAL, DW_TAG_subprogram, 1,
233 DW_AT_external, DW_FORM_flag,
234 DW_AT_name, DW_FORM_strp,
235 DW_AT_decl_file, DW_FORM_udata,
236 DW_AT_decl_line, DW_FORM_udata,
237 DW_AT_type, DW_FORM_ref4,
238 DW_AT_low_pc, DW_FORM_addr,
239 #if PTR_SIZE == 4
240 DW_AT_high_pc, DW_FORM_data4,
241 #else
242 DW_AT_high_pc, DW_FORM_data8,
243 #endif
244 DW_AT_sibling, DW_FORM_ref4,
245 DW_AT_frame_base, DW_FORM_exprloc,
246 0, 0,
247 DWARF_ABBREV_SUBPROGRAM_STATIC, DW_TAG_subprogram, 1,
248 DW_AT_name, DW_FORM_strp,
249 DW_AT_decl_file, DW_FORM_udata,
250 DW_AT_decl_line, DW_FORM_udata,
251 DW_AT_type, DW_FORM_ref4,
252 DW_AT_low_pc, DW_FORM_addr,
253 #if PTR_SIZE == 4
254 DW_AT_high_pc, DW_FORM_data4,
255 #else
256 DW_AT_high_pc, DW_FORM_data8,
257 #endif
258 DW_AT_sibling, DW_FORM_ref4,
259 DW_AT_frame_base, DW_FORM_exprloc,
260 0, 0,
261 DWARF_ABBREV_LEXICAL_BLOCK, DW_TAG_lexical_block, 1,
262 DW_AT_low_pc, DW_FORM_addr,
263 #if PTR_SIZE == 4
264 DW_AT_high_pc, DW_FORM_data4,
265 #else
266 DW_AT_high_pc, DW_FORM_data8,
267 #endif
268 0, 0,
269 DWARF_ABBREV_SUBROUTINE_TYPE, DW_TAG_subroutine_type, 1,
270 DW_AT_type, DW_FORM_ref4,
271 DW_AT_sibling, DW_FORM_ref4,
272 0, 0,
273 DWARF_ABBREV_FORMAL_PARAMETER2, DW_TAG_formal_parameter, 0,
274 DW_AT_type, DW_FORM_ref4,
275 0, 0,
279 static const unsigned char dwarf_line_opcodes[] = {
280 0 ,1 ,1 ,1 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,1
283 /* ------------------------------------------------------------------------- */
284 /* debug state */
286 struct _tccdbg {
288 int last_line_num, new_file;
289 int section_sym;
291 int debug_next_type;
293 struct _debug_hash {
294 int debug_type;
295 Sym *type;
296 } *debug_hash;
298 struct _debug_anon_hash {
299 Sym *type;
300 int n_debug_type;
301 int *debug_type;
302 } *debug_anon_hash;
304 int n_debug_hash;
305 int n_debug_anon_hash;
307 struct _debug_info {
308 int start;
309 int end;
310 int n_sym;
311 struct debug_sym {
312 int type;
313 unsigned long value;
314 char *str;
315 Section *sec;
316 int sym_index;
317 int info;
318 int file;
319 int line;
320 } *sym;
321 struct _debug_info *child, *next, *last, *parent;
322 } *debug_info, *debug_info_root;
324 struct {
325 int info;
326 int abbrev;
327 int line;
328 int str;
329 int line_str;
330 } dwarf_sym;
332 struct {
333 int start;
334 int dir_size;
335 char **dir_table;
336 int filename_size;
337 struct dwarf_filename_struct {
338 int dir_entry;
339 char *name;
340 } *filename_table;
341 int line_size;
342 int line_max_size;
343 unsigned char *line_data;
344 int cur_file;
345 int last_file;
346 int last_pc;
347 int last_line;
348 } dwarf_line;
350 struct {
351 int start;
352 Sym *func;
353 int line;
354 int base_type_used[N_DEFAULT_DEBUG];
355 } dwarf_info;
357 /* test coverage */
358 struct {
359 unsigned long offset;
360 unsigned long last_file_name;
361 unsigned long last_func_name;
362 int ind;
363 int line;
364 } tcov_data;
368 #define last_line_num s1->dState->last_line_num
369 #define new_file s1->dState->new_file
370 #define section_sym s1->dState->section_sym
371 #define debug_next_type s1->dState->debug_next_type
372 #define debug_hash s1->dState->debug_hash
373 #define debug_anon_hash s1->dState->debug_anon_hash
374 #define n_debug_hash s1->dState->n_debug_hash
375 #define n_debug_anon_hash s1->dState->n_debug_anon_hash
376 #define debug_info s1->dState->debug_info
377 #define debug_info_root s1->dState->debug_info_root
378 #define dwarf_sym s1->dState->dwarf_sym
379 #define dwarf_line s1->dState->dwarf_line
380 #define dwarf_info s1->dState->dwarf_info
381 #define tcov_data s1->dState->tcov_data
383 /* ------------------------------------------------------------------------- */
384 static void put_stabs(TCCState *s1, const char *str, int type, int other,
385 int desc, unsigned long value);
387 ST_FUNC void tcc_debug_new(TCCState *s1)
389 int shf = 0;
390 if (!s1->dState)
391 s1->dState = tcc_mallocz(sizeof *s1->dState);
392 #ifdef CONFIG_TCC_BACKTRACE
393 /* include stab info with standalone backtrace support */
394 if (s1->do_backtrace
395 && (s1->output_type & (TCC_OUTPUT_EXE | TCC_OUTPUT_DLL)))
396 shf = SHF_ALLOC | SHF_WRITE; // SHF_WRITE needed for musl/SELINUX
397 #endif
398 if (s1->dwarf) {
399 s1->dwlo = s1->nb_sections;
400 dwarf_info_section =
401 new_section(s1, ".debug_info", SHT_PROGBITS, shf);
402 dwarf_abbrev_section =
403 new_section(s1, ".debug_abbrev", SHT_PROGBITS, shf);
404 dwarf_line_section =
405 new_section(s1, ".debug_line", SHT_PROGBITS, shf);
406 dwarf_aranges_section =
407 new_section(s1, ".debug_aranges", SHT_PROGBITS, shf);
408 shf |= SHF_MERGE | SHF_STRINGS;
409 dwarf_str_section =
410 new_section(s1, ".debug_str", SHT_PROGBITS, shf);
411 dwarf_str_section->sh_entsize = 1;
412 dwarf_info_section->sh_addralign =
413 dwarf_abbrev_section->sh_addralign =
414 dwarf_line_section->sh_addralign =
415 dwarf_aranges_section->sh_addralign =
416 dwarf_str_section->sh_addralign = 1;
417 if (s1->dwarf >= 5) {
418 dwarf_line_str_section =
419 new_section(s1, ".debug_line_str", SHT_PROGBITS, shf);
420 dwarf_line_str_section->sh_entsize = 1;
421 dwarf_line_str_section->sh_addralign = 1;
423 s1->dwhi = s1->nb_sections;
425 else
427 stab_section = new_section(s1, ".stab", SHT_PROGBITS, shf);
428 stab_section->sh_entsize = sizeof(Stab_Sym);
429 stab_section->sh_addralign = sizeof ((Stab_Sym*)0)->n_value;
430 stab_section->link = new_section(s1, ".stabstr", SHT_STRTAB, shf);
431 /* put first entry */
432 put_stabs(s1, "", 0, 0, 0, 0);
436 /* put stab debug information */
437 static void put_stabs(TCCState *s1, const char *str, int type, int other, int desc,
438 unsigned long value)
440 Stab_Sym *sym;
442 unsigned offset;
443 if (type == N_SLINE
444 && (offset = stab_section->data_offset)
445 && (sym = (Stab_Sym*)(stab_section->data + offset) - 1)
446 && sym->n_type == type
447 && sym->n_value == value) {
448 /* just update line_number in previous entry */
449 sym->n_desc = desc;
450 return;
453 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
454 if (str) {
455 sym->n_strx = put_elf_str(stab_section->link, str);
456 } else {
457 sym->n_strx = 0;
459 sym->n_type = type;
460 sym->n_other = other;
461 sym->n_desc = desc;
462 sym->n_value = value;
465 static void put_stabs_r(TCCState *s1, const char *str, int type, int other, int desc,
466 unsigned long value, Section *sec, int sym_index)
468 put_elf_reloc(symtab_section, stab_section,
469 stab_section->data_offset + 8,
470 sizeof ((Stab_Sym*)0)->n_value == PTR_SIZE ? R_DATA_PTR : R_DATA_32,
471 sym_index);
472 put_stabs(s1, str, type, other, desc, value);
475 static void put_stabn(TCCState *s1, int type, int other, int desc, int value)
477 put_stabs(s1, NULL, type, other, desc, value);
480 /* ------------------------------------------------------------------------- */
481 #define dwarf_data1(s,data) \
482 { unsigned char *p = section_ptr_add((s), 1); *p = (data); }
483 #define dwarf_data2(s,data) \
484 write16le(section_ptr_add((s), 2), (data))
485 #define dwarf_data4(s,data) \
486 write32le(section_ptr_add((s), 4), (data))
487 #define dwarf_data8(s,data) \
488 write64le(section_ptr_add((s), 8), (data))
490 static int dwarf_get_section_sym(Section *s)
492 TCCState *s1 = s->s1;
493 return put_elf_sym(symtab_section, 0, 0,
494 ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
495 s->sh_num, NULL);
498 static void dwarf_reloc(Section *s, int sym, int rel)
500 TCCState *s1 = s->s1;
501 put_elf_reloca(symtab_section, s, s->data_offset, rel, sym, 0);
504 static void dwarf_string(Section *s, Section *dw, int sym, const char *str)
506 TCCState *s1 = s->s1;
507 int offset, len;
508 char *ptr;
510 len = strlen(str) + 1;
511 offset = dw->data_offset;
512 ptr = section_ptr_add(dw, len);
513 memmove(ptr, str, len);
514 put_elf_reloca(symtab_section, s, s->data_offset, R_DATA_32DW, sym,
515 PTR_SIZE == 4 ? 0 : offset);
516 dwarf_data4(s, PTR_SIZE == 4 ? offset : 0);
519 static void dwarf_strp(Section *s, const char *str)
521 TCCState *s1 = s->s1;
522 dwarf_string(s, dwarf_str_section, dwarf_sym.str, str);
525 static void dwarf_line_strp(Section *s, const char *str)
527 TCCState *s1 = s->s1;
528 dwarf_string(s, dwarf_line_str_section, dwarf_sym.line_str, str);
531 static void dwarf_line_op(TCCState *s1, unsigned char op)
533 if (dwarf_line.line_size >= dwarf_line.line_max_size) {
534 dwarf_line.line_max_size += 1024;
535 dwarf_line.line_data =
536 (unsigned char *)tcc_realloc(dwarf_line.line_data,
537 dwarf_line.line_max_size);
539 dwarf_line.line_data[dwarf_line.line_size++] = op;
542 static void dwarf_file(TCCState *s1)
544 int i;
545 char *filename;
547 filename = strrchr(file->filename, '/');
548 if (filename == NULL) {
549 for (i = 0; i < dwarf_line.filename_size; i++)
550 if (dwarf_line.filename_table[i].dir_entry == 0 &&
551 strcmp(dwarf_line.filename_table[i].name,
552 file->filename) == 0) {
553 dwarf_line.cur_file = i;
554 return;
557 else {
558 int j;
559 char *undo = filename;
561 *filename++ = '\0';
562 for (i = 0; i < dwarf_line.dir_size; i++)
563 if (strcmp(dwarf_line.dir_table[i], file->filename) == 0)
564 for (j = 1; j < dwarf_line.filename_size; j++)
565 if (dwarf_line.filename_table[j].dir_entry == i &&
566 strcmp(dwarf_line.filename_table[j].name,
567 filename) == 0) {
568 *undo = '/';
569 dwarf_line.cur_file = j;
570 return;
572 *undo = '/';
574 return;
577 #if 0
578 static int dwarf_uleb128_size (unsigned long long value)
580 int size = 0;
582 do {
583 value >>= 7;
584 size++;
585 } while (value != 0);
586 return size;
588 #endif
590 static int dwarf_sleb128_size (long long value)
592 int size = 0;
593 long long end = value >> 63;
594 unsigned char last = end & 0x40;
595 unsigned char byte;
597 do {
598 byte = value & 0x7f;
599 value >>= 7;
600 size++;
601 } while (value != end || (byte & 0x40) != last);
602 return size;
605 static void dwarf_uleb128 (Section *s, unsigned long long value)
607 do {
608 unsigned char byte = value & 0x7f;
610 value >>= 7;
611 dwarf_data1(s, byte | (value ? 0x80 : 0));
612 } while (value != 0);
615 static void dwarf_sleb128 (Section *s, long long value)
617 int more;
618 long long end = value >> 63;
619 unsigned char last = end & 0x40;
621 do {
622 unsigned char byte = value & 0x7f;
624 value >>= 7;
625 more = value != end || (byte & 0x40) != last;
626 dwarf_data1(s, byte | (0x80 * more));
627 } while (more);
630 static void dwarf_uleb128_op (TCCState *s1, unsigned long long value)
632 do {
633 unsigned char byte = value & 0x7f;
635 value >>= 7;
636 dwarf_line_op(s1, byte | (value ? 0x80 : 0));
637 } while (value != 0);
640 static void dwarf_sleb128_op (TCCState *s1, long long value)
642 int more;
643 long long end = value >> 63;
644 unsigned char last = end & 0x40;
646 do {
647 unsigned char byte = value & 0x7f;
649 value >>= 7;
650 more = value != end || (byte & 0x40) != last;
651 dwarf_line_op(s1, byte | (0x80 * more));
652 } while (more);
655 /* start of translation unit info */
656 ST_FUNC void tcc_debug_start(TCCState *s1)
658 int i;
659 char buf[512];
660 char *filename;
662 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
663 symbols can be safely used */
664 filename = file->prev ? file->prev->filename : file->filename;
665 put_elf_sym(symtab_section, 0, 0,
666 ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
667 SHN_ABS, filename);
669 if (s1->dState) {
671 new_file = last_line_num = 0;
672 debug_next_type = N_DEFAULT_DEBUG;
673 debug_hash = NULL;
674 debug_anon_hash = NULL;
675 n_debug_hash = 0;
676 n_debug_anon_hash = 0;
678 getcwd(buf, sizeof(buf));
679 #ifdef _WIN32
680 normalize_slashes(buf);
681 #endif
683 if (s1->dwarf) {
684 int start_abbrev;
685 unsigned char *ptr;
686 char *undo;
688 /* dwarf_abbrev */
689 start_abbrev = dwarf_abbrev_section->data_offset;
690 ptr = section_ptr_add(dwarf_abbrev_section, sizeof(dwarf_abbrev_init));
691 memcpy(ptr, dwarf_abbrev_init, sizeof(dwarf_abbrev_init));
693 if (s1->dwarf < 5) {
694 while (*ptr) {
695 ptr += 3;
696 while (*ptr) {
697 if (ptr[1] == DW_FORM_line_strp)
698 ptr[1] = DW_FORM_strp;
699 if (s1->dwarf < 4) {
700 /* These are compatable for DW_TAG_compile_unit
701 DW_AT_stmt_list. */
702 if (ptr[1] == DW_FORM_sec_offset)
703 ptr[1] = DW_FORM_data4;
704 /* This code uses only size < 0x80 so these are
705 compatible. */
706 if (ptr[1] == DW_FORM_exprloc)
707 ptr[1] = DW_FORM_block1;
709 ptr += 2;
711 ptr += 2;
715 dwarf_sym.info = dwarf_get_section_sym(dwarf_info_section);
716 dwarf_sym.abbrev = dwarf_get_section_sym(dwarf_abbrev_section);
717 dwarf_sym.line = dwarf_get_section_sym(dwarf_line_section);
718 dwarf_sym.str = dwarf_get_section_sym(dwarf_str_section);
719 if (tcc_state->dwarf >= 5)
720 dwarf_sym.line_str = dwarf_get_section_sym(dwarf_line_str_section);
721 else {
722 dwarf_line_str_section = dwarf_str_section;
723 dwarf_sym.line_str = dwarf_sym.str;
725 section_sym = dwarf_get_section_sym(text_section);
727 /* dwarf_info */
728 dwarf_info.start = dwarf_info_section->data_offset;
729 dwarf_data4(dwarf_info_section, 0); // size
730 dwarf_data2(dwarf_info_section, s1->dwarf); // version
731 if (s1->dwarf >= 5) {
732 dwarf_data1(dwarf_info_section, DW_UT_compile); // unit type
733 dwarf_data1(dwarf_info_section, PTR_SIZE);
734 dwarf_reloc(dwarf_info_section, dwarf_sym.abbrev, R_DATA_32DW);
735 dwarf_data4(dwarf_info_section, start_abbrev);
737 else {
738 dwarf_reloc(dwarf_info_section, dwarf_sym.abbrev, R_DATA_32DW);
739 dwarf_data4(dwarf_info_section, start_abbrev);
740 dwarf_data1(dwarf_info_section, PTR_SIZE);
743 dwarf_data1(dwarf_info_section, DWARF_ABBREV_COMPILE_UNIT);
744 dwarf_strp(dwarf_info_section, "tcc " TCC_VERSION);
745 dwarf_data1(dwarf_info_section, DW_LANG_C11);
746 dwarf_line_strp(dwarf_info_section, filename);
747 dwarf_line_strp(dwarf_info_section, buf);
748 dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR);
749 #if PTR_SIZE == 4
750 dwarf_data4(dwarf_info_section, ind); // low pc
751 dwarf_data4(dwarf_info_section, 0); // high pc
752 #else
753 dwarf_data8(dwarf_info_section, ind); // low pc
754 dwarf_data8(dwarf_info_section, 0); // high pc
755 #endif
756 dwarf_reloc(dwarf_info_section, dwarf_sym.line, R_DATA_32DW);
757 dwarf_data4(dwarf_info_section, dwarf_line_section->data_offset); // stmt_list
759 /* dwarf_line */
760 dwarf_line.start = dwarf_line_section->data_offset;
761 dwarf_data4(dwarf_line_section, 0); // length
762 dwarf_data2(dwarf_line_section, s1->dwarf); // version
763 if (s1->dwarf >= 5) {
764 dwarf_data1(dwarf_line_section, PTR_SIZE); // address size
765 dwarf_data1(dwarf_line_section, 0); // segment selector
767 dwarf_data4(dwarf_line_section, 0); // prologue Length
768 dwarf_data1(dwarf_line_section, DWARF_MIN_INSTR_LEN);
769 if (s1->dwarf >= 4)
770 dwarf_data1(dwarf_line_section, 1); // maximum ops per instruction
771 dwarf_data1(dwarf_line_section, 1); // Initial value of 'is_stmt'
772 dwarf_data1(dwarf_line_section, DWARF_LINE_BASE);
773 dwarf_data1(dwarf_line_section, DWARF_LINE_RANGE);
774 dwarf_data1(dwarf_line_section, DWARF_OPCODE_BASE);
775 ptr = section_ptr_add(dwarf_line_section, sizeof(dwarf_line_opcodes));
776 memcpy(ptr, dwarf_line_opcodes, sizeof(dwarf_line_opcodes));
777 undo = strrchr(filename, '/');
778 if (undo)
779 *undo = 0;
780 dwarf_line.dir_size = 1 + (undo != NULL);
781 dwarf_line.dir_table = (char **) tcc_malloc(sizeof (char *) *
782 dwarf_line.dir_size);
783 dwarf_line.dir_table[0] = tcc_strdup(buf);
784 if (undo)
785 dwarf_line.dir_table[1] = tcc_strdup(filename);
786 dwarf_line.filename_size = 2;
787 dwarf_line.filename_table =
788 (struct dwarf_filename_struct *)
789 tcc_malloc(2*sizeof (struct dwarf_filename_struct));
790 dwarf_line.filename_table[0].dir_entry = 0;
791 if (undo) {
792 dwarf_line.filename_table[0].name = tcc_strdup(filename);
793 dwarf_line.filename_table[1].dir_entry = 1;
794 dwarf_line.filename_table[1].name = tcc_strdup(undo + 1);
795 *undo = '/';
796 dwarf_line.filename_table[0].name = tcc_strdup(filename);
798 else {
799 dwarf_line.filename_table[0].name = tcc_strdup(filename);
800 dwarf_line.filename_table[1].dir_entry = 0;
801 dwarf_line.filename_table[1].name = tcc_strdup(filename);
803 dwarf_line.line_size = dwarf_line.line_max_size = 0;
804 dwarf_line.line_data = NULL;
805 dwarf_line.cur_file = 1;
806 dwarf_line.last_file = 0;
807 dwarf_line.last_pc = 0;
808 dwarf_line.last_line = 1;
809 dwarf_line_op(s1, 0); // extended
810 dwarf_uleb128_op(s1, 1 + PTR_SIZE); // extended size
811 dwarf_line_op(s1, DW_LNE_set_address);
812 for (i = 0; i < PTR_SIZE; i++)
813 dwarf_line_op(s1, 0);
814 memset(&dwarf_info.base_type_used, 0, sizeof(dwarf_info.base_type_used));
816 else
818 /* file info: full path + filename */
819 pstrcat(buf, sizeof(buf), "/");
820 section_sym = put_elf_sym(symtab_section, 0, 0,
821 ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
822 text_section->sh_num, NULL);
823 put_stabs_r(s1, buf, N_SO, 0, 0,
824 text_section->data_offset, text_section, section_sym);
825 put_stabs_r(s1, filename, N_SO, 0, 0,
826 text_section->data_offset, text_section, section_sym);
827 for (i = 0; i < N_DEFAULT_DEBUG; i++)
828 put_stabs(s1, default_debug[i].name, N_LSYM, 0, 0, 0);
830 /* we're currently 'including' the <command line> */
831 tcc_debug_bincl(s1);
835 /* put end of translation unit info */
836 ST_FUNC void tcc_debug_end(TCCState *s1)
838 if (!s1->dState)
839 return;
840 if (s1->dwarf) {
841 int i, j;
842 int start_aranges;
843 unsigned char *ptr;
844 int text_size = text_section->data_offset;
846 /* dwarf_info */
847 for (i = 0; i < n_debug_anon_hash; i++) {
848 Sym *t = debug_anon_hash[i].type;
849 int pos = dwarf_info_section->data_offset;
851 dwarf_data1(dwarf_info_section,
852 IS_UNION (t->type.t) ? DWARF_ABBREV_UNION_TYPE
853 : DWARF_ABBREV_STRUCTURE_TYPE);
854 dwarf_strp(dwarf_info_section,
855 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
856 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL));
857 dwarf_uleb128(dwarf_info_section, 0);
858 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
859 dwarf_uleb128(dwarf_info_section, file->line_num);
860 j = dwarf_info_section->data_offset + 5 - dwarf_info.start;
861 dwarf_data4(dwarf_info_section, j);
862 dwarf_data1(dwarf_info_section, 0);
863 for (j = 0; j < debug_anon_hash[i].n_debug_type; j++)
864 write32le(dwarf_info_section->data +
865 debug_anon_hash[i].debug_type[j],
866 pos - dwarf_info.start);
867 tcc_free (debug_anon_hash[i].debug_type);
869 tcc_free (debug_anon_hash);
870 dwarf_data1(dwarf_info_section, 0);
871 ptr = dwarf_info_section->data + dwarf_info.start;
872 write32le(ptr, dwarf_info_section->data_offset - dwarf_info.start - 4);
873 write32le(ptr + 25 + (s1->dwarf >= 5) + PTR_SIZE, text_size);
875 /* dwarf_aranges */
876 start_aranges = dwarf_aranges_section->data_offset;
877 dwarf_data4(dwarf_aranges_section, 0); // size
878 dwarf_data2(dwarf_aranges_section, 2); // version
879 dwarf_reloc(dwarf_aranges_section, dwarf_sym.info, R_DATA_32DW);
880 dwarf_data4(dwarf_aranges_section, 0); // dwarf_info
881 #if PTR_SIZE == 4
882 dwarf_data1(dwarf_aranges_section, 4); // address size
883 #else
884 dwarf_data1(dwarf_aranges_section, 8); // address size
885 #endif
886 dwarf_data1(dwarf_aranges_section, 0); // segment selector size
887 dwarf_data4(dwarf_aranges_section, 0); // padding
888 dwarf_reloc(dwarf_aranges_section, section_sym, R_DATA_PTR);
889 #if PTR_SIZE == 4
890 dwarf_data4(dwarf_aranges_section, 0); // Begin
891 dwarf_data4(dwarf_aranges_section, text_size); // End
892 dwarf_data4(dwarf_aranges_section, 0); // End list
893 dwarf_data4(dwarf_aranges_section, 0); // End list
894 #else
895 dwarf_data8(dwarf_aranges_section, 0); // Begin
896 dwarf_data8(dwarf_aranges_section, text_size); // End
897 dwarf_data8(dwarf_aranges_section, 0); // End list
898 dwarf_data8(dwarf_aranges_section, 0); // End list
899 #endif
900 ptr = dwarf_aranges_section->data + start_aranges;
901 write32le(ptr, dwarf_aranges_section->data_offset - start_aranges - 4);
903 /* dwarf_line */
904 if (s1->dwarf >= 5) {
905 dwarf_data1(dwarf_line_section, 1); /* col */
906 dwarf_uleb128(dwarf_line_section, DW_LNCT_path);
907 dwarf_uleb128(dwarf_line_section, DW_FORM_line_strp);
908 dwarf_uleb128(dwarf_line_section, dwarf_line.dir_size);
909 for (i = 0; i < dwarf_line.dir_size; i++)
910 dwarf_line_strp(dwarf_line_section, dwarf_line.dir_table[i]);
911 dwarf_data1(dwarf_line_section, 2); /* col */
912 dwarf_uleb128(dwarf_line_section, DW_LNCT_path);
913 dwarf_uleb128(dwarf_line_section, DW_FORM_line_strp);
914 dwarf_uleb128(dwarf_line_section, DW_LNCT_directory_index);
915 dwarf_uleb128(dwarf_line_section, DW_FORM_udata);
916 dwarf_uleb128(dwarf_line_section, dwarf_line.filename_size);
917 for (i = 0; i < dwarf_line.filename_size; i++) {
918 dwarf_line_strp(dwarf_line_section,
919 dwarf_line.filename_table[i].name);
920 dwarf_uleb128(dwarf_line_section,
921 dwarf_line.filename_table[i].dir_entry);
924 else {
925 int len;
927 for (i = 0; i < dwarf_line.dir_size; i++) {
928 len = strlen(dwarf_line.dir_table[i]) + 1;
929 ptr = section_ptr_add(dwarf_line_section, len);
930 memmove(ptr, dwarf_line.dir_table[i], len);
932 dwarf_data1(dwarf_line_section, 0); /* end dir */
933 for (i = 0; i < dwarf_line.filename_size; i++) {
934 len = strlen(dwarf_line.filename_table[i].name) + 1;
935 ptr = section_ptr_add(dwarf_line_section, len);
936 memmove(ptr, dwarf_line.filename_table[i].name, len);
937 dwarf_uleb128(dwarf_line_section,
938 dwarf_line.filename_table[i].dir_entry);
939 dwarf_uleb128(dwarf_line_section, 0); /* time */
940 dwarf_uleb128(dwarf_line_section, 0); /* size */
942 dwarf_data1(dwarf_line_section, 0); /* end file */
944 for (i = 0; i < dwarf_line.dir_size; i++)
945 tcc_free(dwarf_line.dir_table[i]);
946 tcc_free(dwarf_line.dir_table);
947 for (i = 0; i < dwarf_line.filename_size; i++)
948 tcc_free(dwarf_line.filename_table[i].name);
949 tcc_free(dwarf_line.filename_table);
951 dwarf_line_op(s1, 0); // extended
952 dwarf_uleb128_op(s1, 1); // extended size
953 dwarf_line_op(s1, DW_LNE_end_sequence);
954 i = (s1->dwarf >= 5) * 2;
955 write32le(&dwarf_line_section->data[dwarf_line.start + 6 + i],
956 dwarf_line_section->data_offset - dwarf_line.start - (10 + i));
957 section_ptr_add(dwarf_line_section, 3);
958 dwarf_reloc(dwarf_line_section, section_sym, R_DATA_PTR);
959 ptr = section_ptr_add(dwarf_line_section, dwarf_line.line_size - 3);
960 memmove(ptr - 3, dwarf_line.line_data, dwarf_line.line_size);
961 tcc_free(dwarf_line.line_data);
962 write32le(dwarf_line_section->data + dwarf_line.start,
963 dwarf_line_section->data_offset - dwarf_line.start - 4);
965 else
967 put_stabs_r(s1, NULL, N_SO, 0, 0,
968 text_section->data_offset, text_section, section_sym);
970 tcc_free(debug_hash);
973 static BufferedFile* put_new_file(TCCState *s1)
975 BufferedFile *f = file;
976 /* use upper file if from inline ":asm:" */
977 if (f->filename[0] == ':')
978 f = f->prev;
979 if (f && new_file) {
980 new_file = last_line_num = 0;
981 if (s1->dwarf)
982 dwarf_file(s1);
983 else
984 put_stabs_r(s1, f->filename, N_SOL, 0, 0, ind, text_section, section_sym);
986 return f;
989 /* put alternative filename */
990 ST_FUNC void tcc_debug_putfile(TCCState *s1, const char *filename)
992 if (0 == strcmp(file->filename, filename))
993 return;
994 pstrcpy(file->filename, sizeof(file->filename), filename);
995 if (!s1->dState)
996 return;
997 if (s1->dwarf)
998 dwarf_file(s1);
999 new_file = 1;
1002 /* begin of #include */
1003 ST_FUNC void tcc_debug_bincl(TCCState *s1)
1005 if (!s1->dState)
1006 return;
1007 if (s1->dwarf) {
1008 int i, j;
1009 char *filename = strrchr(file->filename, '/');
1010 char *dir;
1012 if (filename == NULL) {
1013 filename = file->filename;
1014 i = 0;
1016 else {
1017 char *undo = filename;
1019 *filename++ = '\0';
1020 dir = file->filename;
1021 for (i = 0; i < dwarf_line.dir_size; i++)
1022 if (strcmp (dwarf_line.dir_table[i], dir) == 0)
1023 break;
1024 if (i == dwarf_line.dir_size) {
1025 dwarf_line.dir_size++;
1026 dwarf_line.dir_table =
1027 (char **) tcc_realloc(dwarf_line.dir_table,
1028 dwarf_line.dir_size *
1029 sizeof (char *));
1030 dwarf_line.dir_table[i] = tcc_strdup(dir);
1032 *undo = '/';
1034 if (strcmp(filename, "<command line>")) {
1035 for (j = 0; j < dwarf_line.filename_size; j++)
1036 if (dwarf_line.filename_table[j].dir_entry == i &&
1037 strcmp (dwarf_line.filename_table[j].name, filename) == 0)
1038 break;
1039 if (j == dwarf_line.filename_size) {
1040 dwarf_line.filename_table =
1041 (struct dwarf_filename_struct *)
1042 tcc_realloc(dwarf_line.filename_table,
1043 (dwarf_line.filename_size + 1) *
1044 sizeof (struct dwarf_filename_struct));
1045 dwarf_line.filename_table[dwarf_line.filename_size].dir_entry = i;
1046 dwarf_line.filename_table[dwarf_line.filename_size++].name =
1047 tcc_strdup(filename);
1050 dwarf_file(s1);
1052 else
1054 put_stabs(s1, file->filename, N_BINCL, 0, 0, 0);
1056 new_file = 1;
1059 /* end of #include */
1060 ST_FUNC void tcc_debug_eincl(TCCState *s1)
1062 if (!s1->dState)
1063 return;
1064 if (s1->dwarf)
1065 dwarf_file(s1);
1066 else
1067 put_stabn(s1, N_EINCL, 0, 0, 0);
1068 new_file = 1;
1071 /* generate line number info */
1072 ST_FUNC void tcc_debug_line(TCCState *s1)
1074 BufferedFile *f;
1076 if (!s1->dState)
1077 return;
1078 if (cur_text_section != text_section)
1079 return;
1080 f = put_new_file(s1);
1081 if (!f)
1082 return;
1083 if (last_line_num == f->line_num)
1084 return;
1085 last_line_num = f->line_num;
1087 if (s1->dwarf) {
1088 int len_pc = (ind - dwarf_line.last_pc) / DWARF_MIN_INSTR_LEN;
1089 int len_line = f->line_num - dwarf_line.last_line;
1090 int n = len_pc * DWARF_LINE_RANGE + len_line + DWARF_OPCODE_BASE - DWARF_LINE_BASE;
1092 if (dwarf_line.cur_file != dwarf_line.last_file) {
1093 dwarf_line.last_file = dwarf_line.cur_file;
1094 dwarf_line_op(s1, DW_LNS_set_file);
1095 dwarf_uleb128_op(s1, dwarf_line.cur_file);
1097 if (len_pc &&
1098 len_line >= DWARF_LINE_BASE && len_line <= (DWARF_OPCODE_BASE + DWARF_LINE_BASE) &&
1099 n >= DWARF_OPCODE_BASE && n <= 255)
1100 dwarf_line_op(s1, n);
1101 else {
1102 if (len_pc) {
1103 n = len_pc * DWARF_LINE_RANGE + 0 + DWARF_OPCODE_BASE - DWARF_LINE_BASE;
1104 if (n >= DWARF_OPCODE_BASE && n <= 255)
1105 dwarf_line_op(s1, n);
1106 else {
1107 dwarf_line_op(s1, DW_LNS_advance_pc);
1108 dwarf_uleb128_op(s1, len_pc);
1111 if (len_line) {
1112 n = 0 * DWARF_LINE_RANGE + len_line + DWARF_OPCODE_BASE - DWARF_LINE_BASE;
1113 if (len_line >= DWARF_LINE_BASE && len_line <= (DWARF_OPCODE_BASE + DWARF_LINE_BASE) &&
1114 n >= DWARF_OPCODE_BASE && n <= 255)
1115 dwarf_line_op(s1, n);
1116 else {
1117 dwarf_line_op(s1, DW_LNS_advance_line);
1118 dwarf_sleb128_op(s1, len_line);
1122 dwarf_line.last_pc = ind;
1123 dwarf_line.last_line = f->line_num;
1125 else
1127 if (func_ind != -1) {
1128 put_stabn(s1, N_SLINE, 0, f->line_num, ind - func_ind);
1129 } else {
1130 /* from tcc_assemble */
1131 put_stabs_r(s1, NULL, N_SLINE, 0, f->line_num, ind, text_section, section_sym);
1136 static void tcc_debug_stabs (TCCState *s1, const char *str, int type, unsigned long value,
1137 Section *sec, int sym_index, int info)
1139 struct debug_sym *s;
1141 if (debug_info) {
1142 debug_info->sym =
1143 (struct debug_sym *)tcc_realloc (debug_info->sym,
1144 sizeof(struct debug_sym) *
1145 (debug_info->n_sym + 1));
1146 s = debug_info->sym + debug_info->n_sym++;
1147 s->type = type;
1148 s->value = value;
1149 s->str = tcc_strdup(str);
1150 s->sec = sec;
1151 s->sym_index = sym_index;
1152 s->info = info;
1153 s->file = dwarf_line.cur_file;
1154 s->line = file->line_num;
1156 else if (sec)
1157 put_stabs_r (s1, str, type, 0, 0, value, sec, sym_index);
1158 else
1159 put_stabs (s1, str, type, 0, 0, value);
1162 ST_FUNC void tcc_debug_stabn(TCCState *s1, int type, int value)
1164 if (!s1->dState)
1165 return;
1166 if (type == N_LBRAC) {
1167 struct _debug_info *info =
1168 (struct _debug_info *) tcc_mallocz(sizeof (*info));
1170 info->start = value;
1171 info->parent = debug_info;
1172 if (debug_info) {
1173 if (debug_info->child) {
1174 if (debug_info->child->last)
1175 debug_info->child->last->next = info;
1176 else
1177 debug_info->child->next = info;
1178 debug_info->child->last = info;
1180 else
1181 debug_info->child = info;
1183 else
1184 debug_info_root = info;
1185 debug_info = info;
1187 else {
1188 debug_info->end = value;
1189 debug_info = debug_info->parent;
1193 static int tcc_debug_find(TCCState *s1, Sym *t, int dwarf)
1195 int i;
1197 if (!debug_info && dwarf &&
1198 (t->type.t & VT_BTYPE) == VT_STRUCT && t->c == -1) {
1199 for (i = 0; i < n_debug_anon_hash; i++)
1200 if (t == debug_anon_hash[i].type)
1201 return 0;
1202 debug_anon_hash = (struct _debug_anon_hash *)
1203 tcc_realloc (debug_anon_hash,
1204 (n_debug_anon_hash + 1) * sizeof(*debug_anon_hash));
1205 debug_anon_hash[n_debug_anon_hash].n_debug_type = 0;
1206 debug_anon_hash[n_debug_anon_hash].debug_type = NULL;
1207 debug_anon_hash[n_debug_anon_hash++].type = t;
1208 return 0;
1210 for (i = 0; i < n_debug_hash; i++)
1211 if (t == debug_hash[i].type)
1212 return debug_hash[i].debug_type;
1213 return -1;
1216 static int tcc_get_dwarf_info(TCCState *s1, Sym *s);
1218 static void tcc_debug_check_anon(TCCState *s1, Sym *t, int debug_type)
1220 int i;
1222 if (!debug_info && (t->type.t & VT_BTYPE) == VT_STRUCT && t->type.ref->c == -1)
1223 for (i = 0; i < n_debug_anon_hash; i++)
1224 if (t->type.ref == debug_anon_hash[i].type) {
1225 debug_anon_hash[i].debug_type =
1226 tcc_realloc(debug_anon_hash[i].debug_type,
1227 (debug_anon_hash[i].n_debug_type + 1) * sizeof(int));
1228 debug_anon_hash[i].debug_type[debug_anon_hash[i].n_debug_type++] =
1229 debug_type;
1233 ST_FUNC void tcc_debug_fix_anon(TCCState *s1, CType *t)
1235 int i, j, debug_type;
1237 if (!s1->dState || !s1->dwarf || debug_info)
1238 return;
1239 if ((t->t & VT_BTYPE) == VT_STRUCT && t->ref->c != -1)
1240 for (i = 0; i < n_debug_anon_hash; i++)
1241 if (t->ref == debug_anon_hash[i].type) {
1242 Sym sym = {0}; sym .type = *t ;
1244 /* Trick to not hash this struct */
1245 debug_info = (struct _debug_info *) t;
1246 debug_type = tcc_get_dwarf_info(s1, &sym);
1247 debug_info = NULL;
1248 for (j = 0; j < debug_anon_hash[i].n_debug_type; j++)
1249 write32le(dwarf_info_section->data +
1250 debug_anon_hash[i].debug_type[j],
1251 debug_type - dwarf_info.start);
1252 tcc_free(debug_anon_hash[i].debug_type);
1253 n_debug_anon_hash--;
1254 for (; i < n_debug_anon_hash; i++)
1255 debug_anon_hash[i] = debug_anon_hash[i + 1];
1259 static int tcc_debug_add(TCCState *s1, Sym *t, int dwarf)
1261 int offset = dwarf ? dwarf_info_section->data_offset : ++debug_next_type;
1262 debug_hash = (struct _debug_hash *)
1263 tcc_realloc (debug_hash,
1264 (n_debug_hash + 1) * sizeof(*debug_hash));
1265 debug_hash[n_debug_hash].debug_type = offset;
1266 debug_hash[n_debug_hash++].type = t;
1267 return offset;
1270 static void tcc_debug_remove(TCCState *s1, Sym *t)
1272 int i;
1274 for (i = 0; i < n_debug_hash; i++)
1275 if (t == debug_hash[i].type) {
1276 n_debug_hash--;
1277 for (; i < n_debug_hash; i++)
1278 debug_hash[i] = debug_hash[i+1];
1282 static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result)
1284 int type;
1285 int n = 0;
1286 int debug_type = -1;
1287 Sym *t = s;
1288 CString str;
1290 for (;;) {
1291 type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE | VT_VLA);
1292 if ((type & VT_BTYPE) != VT_BYTE)
1293 type &= ~VT_DEFSIGN;
1294 if (type == VT_PTR || type == (VT_PTR | VT_ARRAY))
1295 n++, t = t->type.ref;
1296 else
1297 break;
1299 if ((type & VT_BTYPE) == VT_STRUCT) {
1300 Sym *e = t;
1302 t = t->type.ref;
1303 debug_type = tcc_debug_find(s1, t, 0);
1304 if (debug_type == -1) {
1305 debug_type = tcc_debug_add(s1, t, 0);
1306 cstr_new (&str);
1307 cstr_printf (&str, "%s:T%d=%c%d",
1308 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
1309 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL),
1310 debug_type,
1311 IS_UNION (t->type.t) ? 'u' : 's',
1312 t->c);
1313 while (t->next) {
1314 int pos, size, align;
1316 t = t->next;
1317 cstr_printf (&str, "%s:",
1318 (t->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
1319 ? "" : get_tok_str(t->v & ~SYM_FIELD, NULL));
1320 tcc_get_debug_info (s1, t, &str);
1321 if (t->type.t & VT_BITFIELD) {
1322 pos = t->c * 8 + BIT_POS(t->type.t);
1323 size = BIT_SIZE(t->type.t);
1325 else {
1326 pos = t->c * 8;
1327 size = type_size(&t->type, &align) * 8;
1329 cstr_printf (&str, ",%d,%d;", pos, size);
1331 cstr_printf (&str, ";");
1332 tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0);
1333 cstr_free (&str);
1334 if (debug_info)
1335 tcc_debug_remove(s1, e);
1338 else if (IS_ENUM(type)) {
1339 Sym *e = t = t->type.ref;
1341 debug_type = tcc_debug_find(s1, t, 0);
1342 if (debug_type == -1) {
1343 debug_type = tcc_debug_add(s1, t, 0);
1344 cstr_new (&str);
1345 cstr_printf (&str, "%s:T%d=e",
1346 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
1347 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL),
1348 debug_type);
1349 while (t->next) {
1350 t = t->next;
1351 cstr_printf (&str, "%s:",
1352 (t->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
1353 ? "" : get_tok_str(t->v & ~SYM_FIELD, NULL));
1354 cstr_printf (&str, e->type.t & VT_UNSIGNED ? "%u," : "%d,",
1355 (int)t->enum_val);
1357 cstr_printf (&str, ";");
1358 tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0);
1359 cstr_free (&str);
1360 if (debug_info)
1361 tcc_debug_remove(s1, e);
1364 else if ((type & VT_BTYPE) != VT_FUNC) {
1365 type &= ~VT_STRUCT_MASK;
1366 for (debug_type = 1; debug_type <= N_DEFAULT_DEBUG; debug_type++)
1367 if (default_debug[debug_type - 1].type == type)
1368 break;
1369 if (debug_type > N_DEFAULT_DEBUG)
1370 return;
1372 if (n > 0)
1373 cstr_printf (result, "%d=", ++debug_next_type);
1374 t = s;
1375 for (;;) {
1376 type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE | VT_VLA);
1377 if ((type & VT_BTYPE) != VT_BYTE)
1378 type &= ~VT_DEFSIGN;
1379 if (type == VT_PTR)
1380 cstr_printf (result, "%d=*", ++debug_next_type);
1381 else if (type == (VT_PTR | VT_ARRAY))
1382 cstr_printf (result, "%d=ar1;0;%d;",
1383 ++debug_next_type, t->type.ref->c - 1);
1384 else if (type == VT_FUNC) {
1385 cstr_printf (result, "%d=f", ++debug_next_type);
1386 tcc_get_debug_info (s1, t->type.ref, result);
1387 return;
1389 else
1390 break;
1391 t = t->type.ref;
1393 cstr_printf (result, "%d", debug_type);
1396 static int tcc_get_dwarf_info(TCCState *s1, Sym *s)
1398 int type;
1399 int debug_type = -1;
1400 Sym *e, *t = s;
1401 int i;
1402 int last_pos = -1;
1403 int retval;
1405 if (new_file)
1406 put_new_file(s1);
1407 for (;;) {
1408 type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE | VT_VLA);
1409 if ((type & VT_BTYPE) != VT_BYTE)
1410 type &= ~VT_DEFSIGN;
1411 if (type == VT_PTR || type == (VT_PTR | VT_ARRAY))
1412 t = t->type.ref;
1413 else
1414 break;
1416 if ((type & VT_BTYPE) == VT_STRUCT) {
1417 t = t->type.ref;
1418 debug_type = tcc_debug_find(s1, t, 1);
1419 if (debug_type == -1) {
1420 int pos_sib, i, *pos_type;
1422 debug_type = tcc_debug_add(s1, t, 1);
1423 e = t;
1424 i = 0;
1425 while (e->next) {
1426 e = e->next;
1427 i++;
1429 pos_type = (int *) tcc_malloc(i * sizeof(int));
1430 dwarf_data1(dwarf_info_section,
1431 IS_UNION (t->type.t) ? DWARF_ABBREV_UNION_TYPE
1432 : DWARF_ABBREV_STRUCTURE_TYPE);
1433 dwarf_strp(dwarf_info_section,
1434 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
1435 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL));
1436 dwarf_uleb128(dwarf_info_section, t->c);
1437 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
1438 dwarf_uleb128(dwarf_info_section, file->line_num);
1439 pos_sib = dwarf_info_section->data_offset;
1440 dwarf_data4(dwarf_info_section, 0);
1441 e = t;
1442 i = 0;
1443 while (e->next) {
1444 e = e->next;
1445 dwarf_data1(dwarf_info_section,
1446 e->type.t & VT_BITFIELD ? DWARF_ABBREV_MEMBER_BF
1447 : DWARF_ABBREV_MEMBER);
1448 dwarf_strp(dwarf_info_section,
1449 (e->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
1450 ? "" : get_tok_str(e->v & ~SYM_FIELD, NULL));
1451 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
1452 dwarf_uleb128(dwarf_info_section, file->line_num);
1453 pos_type[i++] = dwarf_info_section->data_offset;
1454 dwarf_data4(dwarf_info_section, 0);
1455 if (e->type.t & VT_BITFIELD) {
1456 int pos = e->c * 8 + BIT_POS(e->type.t);
1457 int size = BIT_SIZE(e->type.t);
1459 dwarf_uleb128(dwarf_info_section, size);
1460 dwarf_uleb128(dwarf_info_section, pos);
1462 else
1463 dwarf_uleb128(dwarf_info_section, e->c);
1465 dwarf_data1(dwarf_info_section, 0);
1466 write32le(dwarf_info_section->data + pos_sib,
1467 dwarf_info_section->data_offset - dwarf_info.start);
1468 e = t;
1469 i = 0;
1470 while (e->next) {
1471 e = e->next;
1472 type = tcc_get_dwarf_info(s1, e);
1473 tcc_debug_check_anon(s1, e, pos_type[i]);
1474 write32le(dwarf_info_section->data + pos_type[i++],
1475 type - dwarf_info.start);
1477 tcc_free(pos_type);
1478 if (debug_info)
1479 tcc_debug_remove(s1, t);
1482 else if (IS_ENUM(type)) {
1483 t = t->type.ref;
1484 debug_type = tcc_debug_find(s1, t, 1);
1485 if (debug_type == -1) {
1486 int pos_sib, pos_type;
1487 Sym sym = {0}; sym.type.t = VT_INT | (type & VT_UNSIGNED);
1489 pos_type = tcc_get_dwarf_info(s1, &sym);
1490 debug_type = tcc_debug_add(s1, t, 1);
1491 dwarf_data1(dwarf_info_section, DWARF_ABBREV_ENUMERATION_TYPE);
1492 dwarf_strp(dwarf_info_section,
1493 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
1494 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL));
1495 dwarf_data1(dwarf_info_section,
1496 type & VT_UNSIGNED ? DW_ATE_unsigned : DW_ATE_signed );
1497 dwarf_data1(dwarf_info_section, 4);
1498 dwarf_data4(dwarf_info_section, pos_type - dwarf_info.start);
1499 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
1500 dwarf_uleb128(dwarf_info_section, file->line_num);
1501 pos_sib = dwarf_info_section->data_offset;
1502 dwarf_data4(dwarf_info_section, 0);
1503 e = t;
1504 while (e->next) {
1505 e = e->next;
1506 dwarf_data1(dwarf_info_section,
1507 type & VT_UNSIGNED ? DWARF_ABBREV_ENUMERATOR_UNSIGNED
1508 : DWARF_ABBREV_ENUMERATOR_SIGNED);
1509 dwarf_strp(dwarf_info_section,
1510 (e->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
1511 ? "" : get_tok_str(e->v & ~SYM_FIELD, NULL));
1512 if (type & VT_UNSIGNED)
1513 dwarf_uleb128(dwarf_info_section, e->enum_val);
1514 else
1515 dwarf_sleb128(dwarf_info_section, e->enum_val);
1517 dwarf_data1(dwarf_info_section, 0);
1518 write32le(dwarf_info_section->data + pos_sib,
1519 dwarf_info_section->data_offset - dwarf_info.start);
1520 if (debug_info)
1521 tcc_debug_remove(s1, t);
1524 else if ((type & VT_BTYPE) != VT_FUNC) {
1525 type &= ~VT_STRUCT_MASK;
1526 for (i = 1; i <= N_DEFAULT_DEBUG; i++)
1527 if (default_debug[i - 1].type == type)
1528 break;
1529 if (i > N_DEFAULT_DEBUG)
1530 return 0;
1531 debug_type = dwarf_info.base_type_used[i - 1];
1532 if (debug_type == 0) {
1533 char name[100];
1535 debug_type = dwarf_info_section->data_offset;
1536 dwarf_data1(dwarf_info_section, DWARF_ABBREV_BASE_TYPE);
1537 dwarf_uleb128(dwarf_info_section, default_debug[i - 1].size);
1538 dwarf_data1(dwarf_info_section, default_debug[i - 1].encoding);
1539 strncpy(name, default_debug[i - 1].name, sizeof(name) -1);
1540 *strchr(name, ':') = 0;
1541 dwarf_strp(dwarf_info_section, name);
1542 dwarf_info.base_type_used[i - 1] = debug_type;
1545 retval = debug_type;
1546 e = NULL;
1547 t = s;
1548 for (;;) {
1549 type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE | VT_VLA);
1550 if ((type & VT_BTYPE) != VT_BYTE)
1551 type &= ~VT_DEFSIGN;
1552 if (type == VT_PTR) {
1553 i = dwarf_info_section->data_offset;
1554 if (retval == debug_type)
1555 retval = i;
1556 dwarf_data1(dwarf_info_section, DWARF_ABBREV_POINTER);
1557 dwarf_data1(dwarf_info_section, PTR_SIZE);
1558 if (last_pos != -1) {
1559 tcc_debug_check_anon(s1, e, last_pos);
1560 write32le(dwarf_info_section->data + last_pos,
1561 i - dwarf_info.start);
1563 last_pos = dwarf_info_section->data_offset;
1564 e = t->type.ref;
1565 dwarf_data4(dwarf_info_section, 0);
1567 else if (type == (VT_PTR | VT_ARRAY)) {
1568 int sib_pos, sub_type;
1569 #if LONG_SIZE == 4
1570 Sym sym = {0}; sym.type.t = VT_LONG | VT_INT | VT_UNSIGNED;
1571 #else
1572 Sym sym = {0}; sym.type.t = VT_LLONG | VT_LONG | VT_UNSIGNED;
1573 #endif
1575 sub_type = tcc_get_dwarf_info(s1, &sym);
1576 i = dwarf_info_section->data_offset;
1577 if (retval == debug_type)
1578 retval = i;
1579 dwarf_data1(dwarf_info_section, DWARF_ABBREV_ARRAY_TYPE);
1580 if (last_pos != -1) {
1581 tcc_debug_check_anon(s1, e, last_pos);
1582 write32le(dwarf_info_section->data + last_pos,
1583 i - dwarf_info.start);
1585 last_pos = dwarf_info_section->data_offset;
1586 e = t->type.ref;
1587 dwarf_data4(dwarf_info_section, 0);
1588 sib_pos = dwarf_info_section->data_offset;
1589 dwarf_data4(dwarf_info_section, 0);
1590 for (;;) {
1591 dwarf_data1(dwarf_info_section, DWARF_ABBREV_SUBRANGE_TYPE);
1592 dwarf_data4(dwarf_info_section, sub_type - dwarf_info.start);
1593 dwarf_uleb128(dwarf_info_section, t->type.ref->c - 1);
1594 s = t->type.ref;
1595 type = s->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE);
1596 if (type != (VT_PTR | VT_ARRAY))
1597 break;
1598 t = s;
1600 dwarf_data1(dwarf_info_section, 0);
1601 write32le(dwarf_info_section->data + sib_pos,
1602 dwarf_info_section->data_offset - dwarf_info.start);
1604 else if (type == VT_FUNC) {
1605 int sib_pos, *pos_type;
1606 Sym *f;
1608 i = dwarf_info_section->data_offset;
1609 debug_type = tcc_get_dwarf_info(s1, t->type.ref);
1610 if (retval == debug_type)
1611 retval = i;
1612 dwarf_data1(dwarf_info_section, DWARF_ABBREV_SUBROUTINE_TYPE);
1613 if (last_pos != -1) {
1614 tcc_debug_check_anon(s1, e, last_pos);
1615 write32le(dwarf_info_section->data + last_pos,
1616 i - dwarf_info.start);
1618 last_pos = dwarf_info_section->data_offset;
1619 e = t->type.ref;
1620 dwarf_data4(dwarf_info_section, 0);
1621 sib_pos = dwarf_info_section->data_offset;
1622 dwarf_data4(dwarf_info_section, 0);
1623 f = t->type.ref;
1624 i = 0;
1625 while (f->next) {
1626 f = f->next;
1627 i++;
1629 pos_type = (int *) tcc_malloc(i * sizeof(int));
1630 f = t->type.ref;
1631 i = 0;
1632 while (f->next) {
1633 f = f->next;
1634 dwarf_data1(dwarf_info_section, DWARF_ABBREV_FORMAL_PARAMETER2);
1635 pos_type[i++] = dwarf_info_section->data_offset;
1636 dwarf_data4(dwarf_info_section, 0);
1638 dwarf_data1(dwarf_info_section, 0);
1639 write32le(dwarf_info_section->data + sib_pos,
1640 dwarf_info_section->data_offset - dwarf_info.start);
1641 f = t->type.ref;
1642 i = 0;
1643 while (f->next) {
1644 f = f->next;
1645 type = tcc_get_dwarf_info(s1, f);
1646 tcc_debug_check_anon(s1, f, pos_type[i]);
1647 write32le(dwarf_info_section->data + pos_type[i++],
1648 type - dwarf_info.start);
1650 tcc_free(pos_type);
1652 else {
1653 if (last_pos != -1) {
1654 tcc_debug_check_anon(s1, e, last_pos);
1655 write32le(dwarf_info_section->data + last_pos,
1656 debug_type - dwarf_info.start);
1658 break;
1660 t = t->type.ref;
1662 return retval;
1665 static void tcc_debug_finish (TCCState *s1, struct _debug_info *cur)
1667 while (cur) {
1668 struct _debug_info *next = cur->next;
1669 int i;
1671 if (s1->dwarf) {
1673 for (i = cur->n_sym - 1; i >= 0; i--) {
1674 struct debug_sym *s = &cur->sym[i];
1676 dwarf_data1(dwarf_info_section,
1677 s->type == N_PSYM
1678 ? DWARF_ABBREV_FORMAL_PARAMETER
1679 : s->type == N_GSYM
1680 ? DWARF_ABBREV_VARIABLE_EXTERNAL
1681 : s->type == N_STSYM
1682 ? DWARF_ABBREV_VARIABLE_STATIC
1683 : DWARF_ABBREV_VARIABLE_LOCAL);
1684 dwarf_strp(dwarf_info_section, s->str);
1685 if (s->type == N_GSYM || s->type == N_STSYM) {
1686 dwarf_uleb128(dwarf_info_section, s->file);
1687 dwarf_uleb128(dwarf_info_section, s->line);
1689 dwarf_data4(dwarf_info_section, s->info - dwarf_info.start);
1690 if (s->type == N_GSYM || s->type == N_STSYM) {
1691 /* global/static */
1692 if (s->type == N_GSYM)
1693 dwarf_data1(dwarf_info_section, 1);
1694 dwarf_data1(dwarf_info_section, PTR_SIZE + 1);
1695 dwarf_data1(dwarf_info_section, DW_OP_addr);
1696 if (s->type == N_STSYM)
1697 dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR);
1698 #if PTR_SIZE == 4
1699 dwarf_data4(dwarf_info_section, s->value);
1700 #else
1701 dwarf_data8(dwarf_info_section, s->value);
1702 #endif
1704 else {
1705 /* param/local */
1706 dwarf_data1(dwarf_info_section, dwarf_sleb128_size(s->value) + 1);
1707 dwarf_data1(dwarf_info_section, DW_OP_fbreg);
1708 dwarf_sleb128(dwarf_info_section, s->value);
1710 tcc_free (s->str);
1712 tcc_free (cur->sym);
1713 dwarf_data1(dwarf_info_section, DWARF_ABBREV_LEXICAL_BLOCK);
1714 dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR);
1715 #if PTR_SIZE == 4
1716 dwarf_data4(dwarf_info_section, func_ind + cur->start);
1717 dwarf_data4(dwarf_info_section, cur->end - cur->start);
1718 #else
1719 dwarf_data8(dwarf_info_section, func_ind + cur->start);
1720 dwarf_data8(dwarf_info_section, cur->end - cur->start);
1721 #endif
1722 tcc_debug_finish (s1, cur->child);
1723 dwarf_data1(dwarf_info_section, 0);
1725 else
1727 for (i = 0; i < cur->n_sym; i++) {
1728 struct debug_sym *s = &cur->sym[i];
1730 if (s->sec)
1731 put_stabs_r(s1, s->str, s->type, 0, 0, s->value,
1732 s->sec, s->sym_index);
1733 else
1734 put_stabs(s1, s->str, s->type, 0, 0, s->value);
1735 tcc_free (s->str);
1737 tcc_free (cur->sym);
1738 put_stabn(s1, N_LBRAC, 0, 0, cur->start);
1739 tcc_debug_finish (s1, cur->child);
1740 put_stabn(s1, N_RBRAC, 0, 0, cur->end);
1742 tcc_free (cur);
1743 cur = next;
1747 ST_FUNC void tcc_add_debug_info(TCCState *s1, int param, Sym *s, Sym *e)
1749 CString debug_str;
1750 if (!s1->dState)
1751 return;
1752 cstr_new (&debug_str);
1753 for (; s != e; s = s->prev) {
1754 if (!s->v || (s->r & VT_VALMASK) != VT_LOCAL)
1755 continue;
1756 if (s1->dwarf) {
1757 tcc_debug_stabs(s1, get_tok_str(s->v, NULL),
1758 param ? N_PSYM : N_LSYM, s->c, NULL, 0,
1759 tcc_get_dwarf_info(s1, s));
1761 else
1763 cstr_reset (&debug_str);
1764 cstr_printf (&debug_str, "%s:%s", get_tok_str(s->v, NULL),
1765 param ? "p" : "");
1766 tcc_get_debug_info(s1, s, &debug_str);
1767 tcc_debug_stabs(s1, debug_str.data, param ? N_PSYM : N_LSYM,
1768 s->c, NULL, 0, 0);
1771 cstr_free (&debug_str);
1774 /* put function symbol */
1775 ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym)
1777 CString debug_str;
1778 BufferedFile *f;
1780 if (!s1->dState)
1781 return;
1782 debug_info_root = NULL;
1783 debug_info = NULL;
1784 tcc_debug_stabn(s1, N_LBRAC, ind - func_ind);
1785 f = put_new_file(s1);
1786 if (!f)
1787 return;
1789 if (s1->dwarf) {
1790 tcc_debug_line(s1);
1791 dwarf_line_op(s1, DW_LNS_copy);
1792 dwarf_info.func = sym;
1793 dwarf_info.line = file->line_num;
1794 if (s1->do_backtrace) {
1795 int i, len;
1797 dwarf_line_op(s1, 0); // extended
1798 dwarf_uleb128_op(s1, strlen(funcname) + 2);
1799 dwarf_line_op(s1, DW_LNE_hi_user - 1);
1800 len = strlen(funcname) + 1;
1801 for (i = 0; i < len; i++)
1802 dwarf_line_op(s1, funcname[i]);
1805 else
1807 cstr_new (&debug_str);
1808 cstr_printf(&debug_str, "%s:%c", funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
1809 tcc_get_debug_info(s1, sym->type.ref, &debug_str);
1810 put_stabs_r(s1, debug_str.data, N_FUN, 0, f->line_num, 0, cur_text_section, sym->c);
1811 cstr_free (&debug_str);
1812 tcc_debug_line(s1);
1816 /* put function size */
1817 ST_FUNC void tcc_debug_funcend(TCCState *s1, int size)
1819 if (!s1->dState)
1820 return;
1821 tcc_debug_line(s1);
1822 tcc_debug_stabn(s1, N_RBRAC, size);
1823 if (s1->dwarf) {
1824 int func_sib = 0;
1825 Sym *sym = dwarf_info.func;
1826 int n_debug_info = tcc_get_dwarf_info(s1, sym->type.ref);
1828 dwarf_data1(dwarf_info_section,
1829 sym->type.t & VT_STATIC ? DWARF_ABBREV_SUBPROGRAM_STATIC
1830 : DWARF_ABBREV_SUBPROGRAM_EXTERNAL);
1831 if ((sym->type.t & VT_STATIC) == 0)
1832 dwarf_data1(dwarf_info_section, 1);
1833 dwarf_strp(dwarf_info_section, funcname);
1834 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
1835 dwarf_uleb128(dwarf_info_section, dwarf_info.line);
1836 tcc_debug_check_anon(s1, sym->type.ref, dwarf_info_section->data_offset);
1837 dwarf_data4(dwarf_info_section, n_debug_info - dwarf_info.start);
1838 dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR);
1839 #if PTR_SIZE == 4
1840 dwarf_data4(dwarf_info_section, func_ind); // low_pc
1841 dwarf_data4(dwarf_info_section, size); // high_pc
1842 #else
1843 dwarf_data8(dwarf_info_section, func_ind); // low_pc
1844 dwarf_data8(dwarf_info_section, size); // high_pc
1845 #endif
1846 func_sib = dwarf_info_section->data_offset;
1847 dwarf_data4(dwarf_info_section, 0); // sibling
1848 dwarf_data1(dwarf_info_section, 1);
1849 #if defined(TCC_TARGET_I386)
1850 dwarf_data1(dwarf_info_section, DW_OP_reg5); // ebp
1851 #elif defined(TCC_TARGET_X86_64)
1852 dwarf_data1(dwarf_info_section, DW_OP_reg6); // rbp
1853 #elif defined TCC_TARGET_ARM
1854 dwarf_data1(dwarf_info_section, DW_OP_reg13); // sp
1855 #elif defined TCC_TARGET_ARM64
1856 dwarf_data1(dwarf_info_section, DW_OP_reg29); // reg 29
1857 #elif defined TCC_TARGET_RISCV64
1858 dwarf_data1(dwarf_info_section, DW_OP_reg8); // r8(s0)
1859 #else
1860 dwarf_data1(dwarf_info_section, DW_OP_call_frame_cfa);
1861 #endif
1862 tcc_debug_finish (s1, debug_info_root);
1863 dwarf_data1(dwarf_info_section, 0);
1864 write32le(dwarf_info_section->data + func_sib,
1865 dwarf_info_section->data_offset - dwarf_info.start);
1867 else
1869 tcc_debug_finish (s1, debug_info_root);
1874 ST_FUNC void tcc_debug_extern_sym(TCCState *s1, Sym *sym, int sh_num, int sym_bind, int sym_type)
1876 if (!s1->dState)
1877 return;
1878 if (sym_type == STT_FUNC || sym->v >= SYM_FIRST_ANOM)
1879 return;
1880 if (s1->dwarf) {
1881 int debug_type;
1883 debug_type = tcc_get_dwarf_info(s1, sym);
1884 dwarf_data1(dwarf_info_section,
1885 sym_bind == STB_GLOBAL
1886 ? DWARF_ABBREV_VARIABLE_EXTERNAL
1887 : DWARF_ABBREV_VARIABLE_STATIC);
1888 dwarf_strp(dwarf_info_section, get_tok_str(sym->v, NULL));
1889 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
1890 dwarf_uleb128(dwarf_info_section, file->line_num);
1891 tcc_debug_check_anon(s1, sym, dwarf_info_section->data_offset);
1892 dwarf_data4(dwarf_info_section, debug_type - dwarf_info.start);
1893 if (sym_bind == STB_GLOBAL)
1894 dwarf_data1(dwarf_info_section, 1);
1895 dwarf_data1(dwarf_info_section, PTR_SIZE + 1);
1896 dwarf_data1(dwarf_info_section, DW_OP_addr);
1897 greloca(dwarf_info_section, sym, dwarf_info_section->data_offset,
1898 R_DATA_PTR, 0);
1899 #if PTR_SIZE == 4
1900 dwarf_data4(dwarf_info_section, 0);
1901 #else
1902 dwarf_data8(dwarf_info_section, 0);
1903 #endif
1905 else
1907 Section *s = s1->sections[sh_num];
1908 CString str;
1910 cstr_new (&str);
1911 cstr_printf (&str, "%s:%c",
1912 get_tok_str(sym->v, NULL),
1913 sym_bind == STB_GLOBAL ? 'G' : func_ind != -1 ? 'V' : 'S'
1915 tcc_get_debug_info(s1, sym, &str);
1916 if (sym_bind == STB_GLOBAL)
1917 tcc_debug_stabs(s1, str.data, N_GSYM, 0, NULL, 0, 0);
1918 else
1919 tcc_debug_stabs(s1, str.data,
1920 (sym->type.t & VT_STATIC) && data_section == s
1921 ? N_STSYM : N_LCSYM, 0, s, sym->c, 0);
1922 cstr_free (&str);
1926 ST_FUNC void tcc_debug_typedef(TCCState *s1, Sym *sym)
1928 if (!s1->dState)
1929 return;
1930 if (s1->dwarf) {
1931 int debug_type;
1933 debug_type = tcc_get_dwarf_info(s1, sym);
1934 if (debug_type != -1) {
1935 dwarf_data1(dwarf_info_section, DWARF_ABBREV_TYPEDEF);
1936 dwarf_strp(dwarf_info_section, get_tok_str(sym->v & ~SYM_FIELD, NULL));
1937 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
1938 dwarf_uleb128(dwarf_info_section, file->line_num);
1939 tcc_debug_check_anon(s1, sym, dwarf_info_section->data_offset);
1940 dwarf_data4(dwarf_info_section, debug_type - dwarf_info.start);
1943 else
1945 CString str;
1946 cstr_new (&str);
1947 cstr_printf (&str, "%s:t",
1948 (sym->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
1949 ? "" : get_tok_str(sym->v & ~SYM_FIELD, NULL));
1950 tcc_get_debug_info(s1, sym, &str);
1951 tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0);
1952 cstr_free (&str);
1956 /* ------------------------------------------------------------------------- */
1957 /* for section layout see lib/tcov.c */
1959 ST_FUNC void tcc_tcov_block_end(TCCState *s1, int line);
1961 ST_FUNC void tcc_tcov_block_begin(TCCState *s1)
1963 SValue sv;
1964 void *ptr;
1965 unsigned long last_offset = tcov_data.offset;
1967 tcc_tcov_block_end (tcc_state, 0);
1968 if (s1->test_coverage == 0 || nocode_wanted)
1969 return;
1971 if (tcov_data.last_file_name == 0 ||
1972 strcmp ((const char *)(tcov_section->data + tcov_data.last_file_name),
1973 file->true_filename) != 0) {
1974 char wd[1024];
1975 CString cstr;
1977 if (tcov_data.last_func_name)
1978 section_ptr_add(tcov_section, 1);
1979 if (tcov_data.last_file_name)
1980 section_ptr_add(tcov_section, 1);
1981 tcov_data.last_func_name = 0;
1982 cstr_new (&cstr);
1983 if (file->true_filename[0] == '/') {
1984 tcov_data.last_file_name = tcov_section->data_offset;
1985 cstr_printf (&cstr, "%s", file->true_filename);
1987 else {
1988 getcwd (wd, sizeof(wd));
1989 tcov_data.last_file_name = tcov_section->data_offset + strlen(wd) + 1;
1990 cstr_printf (&cstr, "%s/%s", wd, file->true_filename);
1992 ptr = section_ptr_add(tcov_section, cstr.size + 1);
1993 strcpy((char *)ptr, cstr.data);
1994 #ifdef _WIN32
1995 normalize_slashes((char *)ptr);
1996 #endif
1997 cstr_free (&cstr);
1999 if (tcov_data.last_func_name == 0 ||
2000 strcmp ((const char *)(tcov_section->data + tcov_data.last_func_name),
2001 funcname) != 0) {
2002 size_t len;
2004 if (tcov_data.last_func_name)
2005 section_ptr_add(tcov_section, 1);
2006 tcov_data.last_func_name = tcov_section->data_offset;
2007 len = strlen (funcname);
2008 ptr = section_ptr_add(tcov_section, len + 1);
2009 strcpy((char *)ptr, funcname);
2010 section_ptr_add(tcov_section, -tcov_section->data_offset & 7);
2011 ptr = section_ptr_add(tcov_section, 8);
2012 write64le (ptr, file->line_num);
2014 if (ind == tcov_data.ind && tcov_data.line == file->line_num)
2015 tcov_data.offset = last_offset;
2016 else {
2017 Sym label = {0};
2018 label.type.t = VT_LLONG | VT_STATIC;
2020 ptr = section_ptr_add(tcov_section, 16);
2021 tcov_data.line = file->line_num;
2022 write64le (ptr, (tcov_data.line << 8) | 0xff);
2023 put_extern_sym(&label, tcov_section,
2024 ((unsigned char *)ptr - tcov_section->data) + 8, 0);
2025 sv.type = label.type;
2026 sv.r = VT_SYM | VT_LVAL | VT_CONST;
2027 sv.r2 = VT_CONST;
2028 sv.c.i = 0;
2029 sv.sym = &label;
2030 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || \
2031 defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64 || \
2032 defined TCC_TARGET_RISCV64
2033 gen_increment_tcov (&sv);
2034 #else
2035 vpushv(&sv);
2036 inc(0, TOK_INC);
2037 vpop();
2038 #endif
2039 tcov_data.offset = (unsigned char *)ptr - tcov_section->data;
2040 tcov_data.ind = ind;
2044 ST_FUNC void tcc_tcov_block_end(TCCState *s1, int line)
2046 if (s1->test_coverage == 0)
2047 return;
2048 if (line == -1)
2049 line = tcov_data.line;
2050 if (tcov_data.offset) {
2051 void *ptr = tcov_section->data + tcov_data.offset;
2052 unsigned long long nline = line ? line : file->line_num;
2054 write64le (ptr, (read64le (ptr) & 0xfffffffffull) | (nline << 36));
2055 tcov_data.offset = 0;
2059 ST_FUNC void tcc_tcov_check_line(TCCState *s1, int start)
2061 if (s1->test_coverage == 0)
2062 return;
2063 if (tcov_data.line != file->line_num) {
2064 if ((tcov_data.line + 1) != file->line_num) {
2065 tcc_tcov_block_end (s1, -1);
2066 if (start)
2067 tcc_tcov_block_begin (s1);
2069 else
2070 tcov_data.line = file->line_num;
2074 ST_FUNC void tcc_tcov_start(TCCState *s1)
2076 if (s1->test_coverage == 0)
2077 return;
2078 if (!s1->dState)
2079 s1->dState = tcc_mallocz(sizeof *s1->dState);
2080 memset (&tcov_data, 0, sizeof (tcov_data));
2081 if (tcov_section == NULL) {
2082 tcov_section = new_section(tcc_state, ".tcov", SHT_PROGBITS,
2083 SHF_ALLOC | SHF_WRITE);
2084 section_ptr_add(tcov_section, 4); // pointer to executable name
2088 ST_FUNC void tcc_tcov_end(TCCState *s1)
2090 if (s1->test_coverage == 0)
2091 return;
2092 if (tcov_data.last_func_name)
2093 section_ptr_add(tcov_section, 1);
2094 if (tcov_data.last_file_name)
2095 section_ptr_add(tcov_section, 1);
2098 ST_FUNC void tcc_tcov_reset_ind(TCCState *s1)
2100 tcov_data.ind = 0;
2103 /* ------------------------------------------------------------------------- */
2104 #undef last_line_num
2105 #undef new_file
2106 #undef section_sym
2107 #undef debug_next_type
2108 #undef debug_hash
2109 #undef n_debug_hash
2110 #undef debug_anon_hash
2111 #undef n_debug_anon_hash
2112 #undef debug_info
2113 #undef debug_info_root
2114 #undef dwarf_sym
2115 #undef dwarf_line
2116 #undef dwarf_info
2117 #undef tcov_data