Fix bitfield long types for stabs/dwarf
[tinycc.git] / tccdbg.c
blob914ddb9ac2247ea96d63918842a40b9862fbe23f
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
396 || s1->output_type == TCC_OUTPUT_DLL)
398 shf = SHF_ALLOC | SHF_WRITE; // SHF_WRITE needed for musl/SELINUX
399 #endif
400 if (s1->dwarf) {
401 s1->dwlo = s1->nb_sections;
402 dwarf_info_section =
403 new_section(s1, ".debug_info", SHT_PROGBITS, shf);
404 dwarf_abbrev_section =
405 new_section(s1, ".debug_abbrev", SHT_PROGBITS, shf);
406 dwarf_line_section =
407 new_section(s1, ".debug_line", SHT_PROGBITS, shf);
408 dwarf_aranges_section =
409 new_section(s1, ".debug_aranges", SHT_PROGBITS, shf);
410 shf |= SHF_MERGE | SHF_STRINGS;
411 dwarf_str_section =
412 new_section(s1, ".debug_str", SHT_PROGBITS, shf);
413 dwarf_str_section->sh_entsize = 1;
414 dwarf_info_section->sh_addralign =
415 dwarf_abbrev_section->sh_addralign =
416 dwarf_line_section->sh_addralign =
417 dwarf_aranges_section->sh_addralign =
418 dwarf_str_section->sh_addralign = 1;
419 if (s1->dwarf >= 5) {
420 dwarf_line_str_section =
421 new_section(s1, ".debug_line_str", SHT_PROGBITS, shf);
422 dwarf_line_str_section->sh_entsize = 1;
423 dwarf_line_str_section->sh_addralign = 1;
425 s1->dwhi = s1->nb_sections;
427 else
429 stab_section = new_section(s1, ".stab", SHT_PROGBITS, shf);
430 stab_section->sh_entsize = sizeof(Stab_Sym);
431 stab_section->sh_addralign = sizeof ((Stab_Sym*)0)->n_value;
432 stab_section->link = new_section(s1, ".stabstr", SHT_STRTAB, shf);
433 /* put first entry */
434 put_stabs(s1, "", 0, 0, 0, 0);
438 /* put stab debug information */
439 static void put_stabs(TCCState *s1, const char *str, int type, int other, int desc,
440 unsigned long value)
442 Stab_Sym *sym;
444 unsigned offset;
445 if (type == N_SLINE
446 && (offset = stab_section->data_offset)
447 && (sym = (Stab_Sym*)(stab_section->data + offset) - 1)
448 && sym->n_type == type
449 && sym->n_value == value) {
450 /* just update line_number in previous entry */
451 sym->n_desc = desc;
452 return;
455 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
456 if (str) {
457 sym->n_strx = put_elf_str(stab_section->link, str);
458 } else {
459 sym->n_strx = 0;
461 sym->n_type = type;
462 sym->n_other = other;
463 sym->n_desc = desc;
464 sym->n_value = value;
467 static void put_stabs_r(TCCState *s1, const char *str, int type, int other, int desc,
468 unsigned long value, Section *sec, int sym_index)
470 put_elf_reloc(symtab_section, stab_section,
471 stab_section->data_offset + 8,
472 sizeof ((Stab_Sym*)0)->n_value == PTR_SIZE ? R_DATA_PTR : R_DATA_32,
473 sym_index);
474 put_stabs(s1, str, type, other, desc, value);
477 static void put_stabn(TCCState *s1, int type, int other, int desc, int value)
479 put_stabs(s1, NULL, type, other, desc, value);
482 /* ------------------------------------------------------------------------- */
483 #define dwarf_data1(s,data) \
484 { unsigned char *p = section_ptr_add((s), 1); *p = (data); }
485 #define dwarf_data2(s,data) \
486 write16le(section_ptr_add((s), 2), (data))
487 #define dwarf_data4(s,data) \
488 write32le(section_ptr_add((s), 4), (data))
489 #define dwarf_data8(s,data) \
490 write64le(section_ptr_add((s), 8), (data))
492 static int dwarf_get_section_sym(Section *s)
494 TCCState *s1 = s->s1;
495 return put_elf_sym(symtab_section, 0, 0,
496 ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
497 s->sh_num, NULL);
500 static void dwarf_reloc(Section *s, int sym, int rel)
502 TCCState *s1 = s->s1;
503 put_elf_reloca(symtab_section, s, s->data_offset, rel, sym, 0);
506 static void dwarf_string(Section *s, Section *dw, int sym, const char *str)
508 TCCState *s1 = s->s1;
509 int offset, len;
510 char *ptr;
512 len = strlen(str) + 1;
513 offset = dw->data_offset;
514 ptr = section_ptr_add(dw, len);
515 memmove(ptr, str, len);
516 put_elf_reloca(symtab_section, s, s->data_offset, R_DATA_32DW, sym,
517 PTR_SIZE == 4 ? 0 : offset);
518 dwarf_data4(s, PTR_SIZE == 4 ? offset : 0);
521 static void dwarf_strp(Section *s, const char *str)
523 TCCState *s1 = s->s1;
524 dwarf_string(s, dwarf_str_section, dwarf_sym.str, str);
527 static void dwarf_line_strp(Section *s, const char *str)
529 TCCState *s1 = s->s1;
530 dwarf_string(s, dwarf_line_str_section, dwarf_sym.line_str, str);
533 static void dwarf_line_op(TCCState *s1, unsigned char op)
535 if (dwarf_line.line_size >= dwarf_line.line_max_size) {
536 dwarf_line.line_max_size += 1024;
537 dwarf_line.line_data =
538 (unsigned char *)tcc_realloc(dwarf_line.line_data,
539 dwarf_line.line_max_size);
541 dwarf_line.line_data[dwarf_line.line_size++] = op;
544 static void dwarf_file(TCCState *s1)
546 int i;
547 char *filename;
549 filename = strrchr(file->filename, '/');
550 if (filename == NULL) {
551 for (i = 0; i < dwarf_line.filename_size; i++)
552 if (dwarf_line.filename_table[i].dir_entry == 0 &&
553 strcmp(dwarf_line.filename_table[i].name,
554 file->filename) == 0) {
555 dwarf_line.cur_file = i;
556 return;
559 else {
560 int j;
561 char *undo = filename;
563 *filename++ = '\0';
564 for (i = 0; i < dwarf_line.dir_size; i++)
565 if (strcmp(dwarf_line.dir_table[i], file->filename) == 0)
566 for (j = 1; j < dwarf_line.filename_size; j++)
567 if (dwarf_line.filename_table[j].dir_entry == i &&
568 strcmp(dwarf_line.filename_table[j].name,
569 filename) == 0) {
570 *undo = '/';
571 dwarf_line.cur_file = j;
572 return;
574 *undo = '/';
576 return;
579 #if 0
580 static int dwarf_uleb128_size (unsigned long long value)
582 int size = 0;
584 do {
585 value >>= 7;
586 size++;
587 } while (value != 0);
588 return size;
590 #endif
592 static int dwarf_sleb128_size (long long value)
594 int size = 0;
595 long long end = value >> 63;
596 unsigned char last = end & 0x40;
597 unsigned char byte;
599 do {
600 byte = value & 0x7f;
601 value >>= 7;
602 size++;
603 } while (value != end || (byte & 0x40) != last);
604 return size;
607 static void dwarf_uleb128 (Section *s, unsigned long long value)
609 do {
610 unsigned char byte = value & 0x7f;
612 value >>= 7;
613 dwarf_data1(s, byte | (value ? 0x80 : 0));
614 } while (value != 0);
617 static void dwarf_sleb128 (Section *s, long long value)
619 int more;
620 long long end = value >> 63;
621 unsigned char last = end & 0x40;
623 do {
624 unsigned char byte = value & 0x7f;
626 value >>= 7;
627 more = value != end || (byte & 0x40) != last;
628 dwarf_data1(s, byte | (0x80 * more));
629 } while (more);
632 static void dwarf_uleb128_op (TCCState *s1, unsigned long long value)
634 do {
635 unsigned char byte = value & 0x7f;
637 value >>= 7;
638 dwarf_line_op(s1, byte | (value ? 0x80 : 0));
639 } while (value != 0);
642 static void dwarf_sleb128_op (TCCState *s1, long long value)
644 int more;
645 long long end = value >> 63;
646 unsigned char last = end & 0x40;
648 do {
649 unsigned char byte = value & 0x7f;
651 value >>= 7;
652 more = value != end || (byte & 0x40) != last;
653 dwarf_line_op(s1, byte | (0x80 * more));
654 } while (more);
657 /* start of translation unit info */
658 ST_FUNC void tcc_debug_start(TCCState *s1)
660 int i;
661 char buf[512];
662 char *filename;
664 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
665 symbols can be safely used */
666 filename = file->prev ? file->prev->filename : file->filename;
667 put_elf_sym(symtab_section, 0, 0,
668 ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
669 SHN_ABS, filename);
671 if (s1->do_debug) {
673 new_file = last_line_num = 0;
674 debug_next_type = N_DEFAULT_DEBUG;
675 debug_hash = NULL;
676 debug_anon_hash = NULL;
677 n_debug_hash = 0;
678 n_debug_anon_hash = 0;
680 getcwd(buf, sizeof(buf));
681 #ifdef _WIN32
682 normalize_slashes(buf);
683 #endif
685 if (s1->dwarf) {
686 int start_abbrev;
687 unsigned char *ptr;
688 char *undo;
690 /* dwarf_abbrev */
691 start_abbrev = dwarf_abbrev_section->data_offset;
692 ptr = section_ptr_add(dwarf_abbrev_section, sizeof(dwarf_abbrev_init));
693 memcpy(ptr, dwarf_abbrev_init, sizeof(dwarf_abbrev_init));
695 if (s1->dwarf < 5) {
696 while (*ptr) {
697 ptr += 3;
698 while (*ptr) {
699 if (ptr[1] == DW_FORM_line_strp)
700 ptr[1] = DW_FORM_strp;
701 if (s1->dwarf < 4) {
702 /* These are compatable for DW_TAG_compile_unit
703 DW_AT_stmt_list. */
704 if (ptr[1] == DW_FORM_sec_offset)
705 ptr[1] = DW_FORM_data4;
706 /* This code uses only size < 0x80 so these are
707 compatible. */
708 if (ptr[1] == DW_FORM_exprloc)
709 ptr[1] = DW_FORM_block1;
711 ptr += 2;
713 ptr += 2;
717 dwarf_sym.info = dwarf_get_section_sym(dwarf_info_section);
718 dwarf_sym.abbrev = dwarf_get_section_sym(dwarf_abbrev_section);
719 dwarf_sym.line = dwarf_get_section_sym(dwarf_line_section);
720 dwarf_sym.str = dwarf_get_section_sym(dwarf_str_section);
721 if (tcc_state->dwarf >= 5)
722 dwarf_sym.line_str = dwarf_get_section_sym(dwarf_line_str_section);
723 else {
724 dwarf_line_str_section = dwarf_str_section;
725 dwarf_sym.line_str = dwarf_sym.str;
727 section_sym = dwarf_get_section_sym(text_section);
729 /* dwarf_info */
730 dwarf_info.start = dwarf_info_section->data_offset;
731 dwarf_data4(dwarf_info_section, 0); // size
732 dwarf_data2(dwarf_info_section, s1->dwarf); // version
733 if (s1->dwarf >= 5) {
734 dwarf_data1(dwarf_info_section, DW_UT_compile); // unit type
735 dwarf_data1(dwarf_info_section, PTR_SIZE);
736 dwarf_reloc(dwarf_info_section, dwarf_sym.abbrev, R_DATA_32DW);
737 dwarf_data4(dwarf_info_section, start_abbrev);
739 else {
740 dwarf_reloc(dwarf_info_section, dwarf_sym.abbrev, R_DATA_32DW);
741 dwarf_data4(dwarf_info_section, start_abbrev);
742 dwarf_data1(dwarf_info_section, PTR_SIZE);
745 dwarf_data1(dwarf_info_section, DWARF_ABBREV_COMPILE_UNIT);
746 dwarf_strp(dwarf_info_section, "tcc " TCC_VERSION);
747 dwarf_data1(dwarf_info_section, DW_LANG_C11);
748 dwarf_line_strp(dwarf_info_section, filename);
749 dwarf_line_strp(dwarf_info_section, buf);
750 dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR);
751 #if PTR_SIZE == 4
752 dwarf_data4(dwarf_info_section, ind); // low pc
753 dwarf_data4(dwarf_info_section, 0); // high pc
754 #else
755 dwarf_data8(dwarf_info_section, ind); // low pc
756 dwarf_data8(dwarf_info_section, 0); // high pc
757 #endif
758 dwarf_reloc(dwarf_info_section, dwarf_sym.line, R_DATA_32DW);
759 dwarf_data4(dwarf_info_section, dwarf_line_section->data_offset); // stmt_list
761 /* dwarf_line */
762 dwarf_line.start = dwarf_line_section->data_offset;
763 dwarf_data4(dwarf_line_section, 0); // length
764 dwarf_data2(dwarf_line_section, s1->dwarf); // version
765 if (s1->dwarf >= 5) {
766 dwarf_data1(dwarf_line_section, PTR_SIZE); // address size
767 dwarf_data1(dwarf_line_section, 0); // segment selector
769 dwarf_data4(dwarf_line_section, 0); // prologue Length
770 dwarf_data1(dwarf_line_section, DWARF_MIN_INSTR_LEN);
771 if (s1->dwarf >= 4)
772 dwarf_data1(dwarf_line_section, 1); // maximum ops per instruction
773 dwarf_data1(dwarf_line_section, 1); // Initial value of 'is_stmt'
774 dwarf_data1(dwarf_line_section, DWARF_LINE_BASE);
775 dwarf_data1(dwarf_line_section, DWARF_LINE_RANGE);
776 dwarf_data1(dwarf_line_section, DWARF_OPCODE_BASE);
777 ptr = section_ptr_add(dwarf_line_section, sizeof(dwarf_line_opcodes));
778 memcpy(ptr, dwarf_line_opcodes, sizeof(dwarf_line_opcodes));
779 undo = strrchr(filename, '/');
780 if (undo)
781 *undo = 0;
782 dwarf_line.dir_size = 1 + (undo != NULL);
783 dwarf_line.dir_table = (char **) tcc_malloc(sizeof (char *) *
784 dwarf_line.dir_size);
785 dwarf_line.dir_table[0] = tcc_strdup(buf);
786 if (undo)
787 dwarf_line.dir_table[1] = tcc_strdup(filename);
788 dwarf_line.filename_size = 2;
789 dwarf_line.filename_table =
790 (struct dwarf_filename_struct *)
791 tcc_malloc(2*sizeof (struct dwarf_filename_struct));
792 dwarf_line.filename_table[0].dir_entry = 0;
793 if (undo) {
794 dwarf_line.filename_table[0].name = tcc_strdup(filename);
795 dwarf_line.filename_table[1].dir_entry = 1;
796 dwarf_line.filename_table[1].name = tcc_strdup(undo + 1);
797 *undo = '/';
798 dwarf_line.filename_table[0].name = tcc_strdup(filename);
800 else {
801 dwarf_line.filename_table[0].name = tcc_strdup(filename);
802 dwarf_line.filename_table[1].dir_entry = 0;
803 dwarf_line.filename_table[1].name = tcc_strdup(filename);
805 dwarf_line.line_size = dwarf_line.line_max_size = 0;
806 dwarf_line.line_data = NULL;
807 dwarf_line.cur_file = 1;
808 dwarf_line.last_file = 0;
809 dwarf_line.last_pc = 0;
810 dwarf_line.last_line = 1;
811 dwarf_line_op(s1, 0); // extended
812 dwarf_uleb128_op(s1, 1 + PTR_SIZE); // extended size
813 dwarf_line_op(s1, DW_LNE_set_address);
814 for (i = 0; i < PTR_SIZE; i++)
815 dwarf_line_op(s1, 0);
816 memset(&dwarf_info.base_type_used, 0, sizeof(dwarf_info.base_type_used));
818 else
820 /* file info: full path + filename */
821 pstrcat(buf, sizeof(buf), "/");
822 section_sym = put_elf_sym(symtab_section, 0, 0,
823 ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
824 text_section->sh_num, NULL);
825 put_stabs_r(s1, buf, N_SO, 0, 0,
826 text_section->data_offset, text_section, section_sym);
827 put_stabs_r(s1, filename, N_SO, 0, 0,
828 text_section->data_offset, text_section, section_sym);
829 for (i = 0; i < N_DEFAULT_DEBUG; i++)
830 put_stabs(s1, default_debug[i].name, N_LSYM, 0, 0, 0);
832 /* we're currently 'including' the <command line> */
833 tcc_debug_bincl(s1);
837 /* put end of translation unit info */
838 ST_FUNC void tcc_debug_end(TCCState *s1)
840 if (!s1->do_debug)
841 return;
842 if (s1->dwarf) {
843 int i, j;
844 int start_aranges;
845 unsigned char *ptr;
846 int text_size = text_section->data_offset;
848 /* dwarf_info */
849 for (i = 0; i < n_debug_anon_hash; i++) {
850 Sym *t = debug_anon_hash[i].type;
851 int pos = dwarf_info_section->data_offset;
853 dwarf_data1(dwarf_info_section,
854 IS_UNION (t->type.t) ? DWARF_ABBREV_UNION_TYPE
855 : DWARF_ABBREV_STRUCTURE_TYPE);
856 dwarf_strp(dwarf_info_section,
857 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
858 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL));
859 dwarf_uleb128(dwarf_info_section, 0);
860 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
861 dwarf_uleb128(dwarf_info_section, file->line_num);
862 j = dwarf_info_section->data_offset + 5 - dwarf_info.start;
863 dwarf_data4(dwarf_info_section, j);
864 dwarf_data1(dwarf_info_section, 0);
865 for (j = 0; j < debug_anon_hash[i].n_debug_type; j++)
866 write32le(dwarf_info_section->data +
867 debug_anon_hash[i].debug_type[j],
868 pos - dwarf_info.start);
869 tcc_free (debug_anon_hash[i].debug_type);
871 tcc_free (debug_anon_hash);
872 dwarf_data1(dwarf_info_section, 0);
873 ptr = dwarf_info_section->data + dwarf_info.start;
874 write32le(ptr, dwarf_info_section->data_offset - dwarf_info.start - 4);
875 write32le(ptr + 25 + (s1->dwarf >= 5) + PTR_SIZE, text_size);
877 /* dwarf_aranges */
878 start_aranges = dwarf_aranges_section->data_offset;
879 dwarf_data4(dwarf_aranges_section, 0); // size
880 dwarf_data2(dwarf_aranges_section, 2); // version
881 dwarf_reloc(dwarf_aranges_section, dwarf_sym.info, R_DATA_32DW);
882 dwarf_data4(dwarf_aranges_section, 0); // dwarf_info
883 #if PTR_SIZE == 4
884 dwarf_data1(dwarf_aranges_section, 4); // address size
885 #else
886 dwarf_data1(dwarf_aranges_section, 8); // address size
887 #endif
888 dwarf_data1(dwarf_aranges_section, 0); // segment selector size
889 dwarf_data4(dwarf_aranges_section, 0); // padding
890 dwarf_reloc(dwarf_aranges_section, section_sym, R_DATA_PTR);
891 #if PTR_SIZE == 4
892 dwarf_data4(dwarf_aranges_section, 0); // Begin
893 dwarf_data4(dwarf_aranges_section, text_size); // End
894 dwarf_data4(dwarf_aranges_section, 0); // End list
895 dwarf_data4(dwarf_aranges_section, 0); // End list
896 #else
897 dwarf_data8(dwarf_aranges_section, 0); // Begin
898 dwarf_data8(dwarf_aranges_section, text_size); // End
899 dwarf_data8(dwarf_aranges_section, 0); // End list
900 dwarf_data8(dwarf_aranges_section, 0); // End list
901 #endif
902 ptr = dwarf_aranges_section->data + start_aranges;
903 write32le(ptr, dwarf_aranges_section->data_offset - start_aranges - 4);
905 /* dwarf_line */
906 if (s1->dwarf >= 5) {
907 dwarf_data1(dwarf_line_section, 1); /* col */
908 dwarf_uleb128(dwarf_line_section, DW_LNCT_path);
909 dwarf_uleb128(dwarf_line_section, DW_FORM_line_strp);
910 dwarf_uleb128(dwarf_line_section, dwarf_line.dir_size);
911 for (i = 0; i < dwarf_line.dir_size; i++)
912 dwarf_line_strp(dwarf_line_section, dwarf_line.dir_table[i]);
913 dwarf_data1(dwarf_line_section, 2); /* col */
914 dwarf_uleb128(dwarf_line_section, DW_LNCT_path);
915 dwarf_uleb128(dwarf_line_section, DW_FORM_line_strp);
916 dwarf_uleb128(dwarf_line_section, DW_LNCT_directory_index);
917 dwarf_uleb128(dwarf_line_section, DW_FORM_udata);
918 dwarf_uleb128(dwarf_line_section, dwarf_line.filename_size);
919 for (i = 0; i < dwarf_line.filename_size; i++) {
920 dwarf_line_strp(dwarf_line_section,
921 dwarf_line.filename_table[i].name);
922 dwarf_uleb128(dwarf_line_section,
923 dwarf_line.filename_table[i].dir_entry);
926 else {
927 int len;
929 for (i = 0; i < dwarf_line.dir_size; i++) {
930 len = strlen(dwarf_line.dir_table[i]) + 1;
931 ptr = section_ptr_add(dwarf_line_section, len);
932 memmove(ptr, dwarf_line.dir_table[i], len);
934 dwarf_data1(dwarf_line_section, 0); /* end dir */
935 for (i = 0; i < dwarf_line.filename_size; i++) {
936 len = strlen(dwarf_line.filename_table[i].name) + 1;
937 ptr = section_ptr_add(dwarf_line_section, len);
938 memmove(ptr, dwarf_line.filename_table[i].name, len);
939 dwarf_uleb128(dwarf_line_section,
940 dwarf_line.filename_table[i].dir_entry);
941 dwarf_uleb128(dwarf_line_section, 0); /* time */
942 dwarf_uleb128(dwarf_line_section, 0); /* size */
944 dwarf_data1(dwarf_line_section, 0); /* end file */
946 for (i = 0; i < dwarf_line.dir_size; i++)
947 tcc_free(dwarf_line.dir_table[i]);
948 tcc_free(dwarf_line.dir_table);
949 for (i = 0; i < dwarf_line.filename_size; i++)
950 tcc_free(dwarf_line.filename_table[i].name);
951 tcc_free(dwarf_line.filename_table);
953 dwarf_line_op(s1, 0); // extended
954 dwarf_uleb128_op(s1, 1); // extended size
955 dwarf_line_op(s1, DW_LNE_end_sequence);
956 i = (s1->dwarf >= 5) * 2;
957 write32le(&dwarf_line_section->data[dwarf_line.start + 6 + i],
958 dwarf_line_section->data_offset - dwarf_line.start - (10 + i));
959 section_ptr_add(dwarf_line_section, 3);
960 dwarf_reloc(dwarf_line_section, section_sym, R_DATA_PTR);
961 ptr = section_ptr_add(dwarf_line_section, dwarf_line.line_size - 3);
962 memmove(ptr - 3, dwarf_line.line_data, dwarf_line.line_size);
963 tcc_free(dwarf_line.line_data);
964 write32le(dwarf_line_section->data + dwarf_line.start,
965 dwarf_line_section->data_offset - dwarf_line.start - 4);
967 else
969 put_stabs_r(s1, NULL, N_SO, 0, 0,
970 text_section->data_offset, text_section, section_sym);
972 tcc_free(debug_hash);
975 static BufferedFile* put_new_file(TCCState *s1)
977 BufferedFile *f = file;
978 /* use upper file if from inline ":asm:" */
979 if (f->filename[0] == ':')
980 f = f->prev;
981 if (f && new_file) {
982 new_file = last_line_num = 0;
983 if (s1->dwarf)
984 dwarf_file(s1);
985 else
986 put_stabs_r(s1, f->filename, N_SOL, 0, 0, ind, text_section, section_sym);
988 return f;
991 /* put alternative filename */
992 ST_FUNC void tcc_debug_putfile(TCCState *s1, const char *filename)
994 if (0 == strcmp(file->filename, filename))
995 return;
996 pstrcpy(file->filename, sizeof(file->filename), filename);
997 if (!s1->do_debug)
998 return;
999 if (s1->dwarf)
1000 dwarf_file(s1);
1001 new_file = 1;
1004 /* begin of #include */
1005 ST_FUNC void tcc_debug_bincl(TCCState *s1)
1007 if (!s1->do_debug)
1008 return;
1009 if (s1->dwarf) {
1010 int i, j;
1011 char *filename = strrchr(file->filename, '/');
1012 char *dir;
1014 if (filename == NULL) {
1015 filename = file->filename;
1016 i = 0;
1018 else {
1019 char *undo = filename;
1021 *filename++ = '\0';
1022 dir = file->filename;
1023 for (i = 0; i < dwarf_line.dir_size; i++)
1024 if (strcmp (dwarf_line.dir_table[i], dir) == 0)
1025 break;
1026 if (i == dwarf_line.dir_size) {
1027 dwarf_line.dir_size++;
1028 dwarf_line.dir_table =
1029 (char **) tcc_realloc(dwarf_line.dir_table,
1030 dwarf_line.dir_size *
1031 sizeof (char *));
1032 dwarf_line.dir_table[i] = tcc_strdup(dir);
1034 *undo = '/';
1036 if (strcmp(filename, "<command line>")) {
1037 for (j = 0; j < dwarf_line.filename_size; j++)
1038 if (dwarf_line.filename_table[j].dir_entry == i &&
1039 strcmp (dwarf_line.filename_table[j].name, filename) == 0)
1040 break;
1041 if (j == dwarf_line.filename_size) {
1042 dwarf_line.filename_table =
1043 (struct dwarf_filename_struct *)
1044 tcc_realloc(dwarf_line.filename_table,
1045 (dwarf_line.filename_size + 1) *
1046 sizeof (struct dwarf_filename_struct));
1047 dwarf_line.filename_table[dwarf_line.filename_size].dir_entry = i;
1048 dwarf_line.filename_table[dwarf_line.filename_size++].name =
1049 tcc_strdup(filename);
1052 dwarf_file(s1);
1054 else
1056 put_stabs(s1, file->filename, N_BINCL, 0, 0, 0);
1058 new_file = 1;
1061 /* end of #include */
1062 ST_FUNC void tcc_debug_eincl(TCCState *s1)
1064 if (!s1->do_debug)
1065 return;
1066 if (s1->dwarf)
1067 dwarf_file(s1);
1068 else
1069 put_stabn(s1, N_EINCL, 0, 0, 0);
1070 new_file = 1;
1073 /* generate line number info */
1074 ST_FUNC void tcc_debug_line(TCCState *s1)
1076 BufferedFile *f;
1078 if (!s1->do_debug)
1079 return;
1080 if (cur_text_section != text_section)
1081 return;
1082 f = put_new_file(s1);
1083 if (!f)
1084 return;
1085 if (last_line_num == f->line_num)
1086 return;
1087 last_line_num = f->line_num;
1089 if (s1->dwarf) {
1090 int len_pc = (ind - dwarf_line.last_pc) / DWARF_MIN_INSTR_LEN;
1091 int len_line = f->line_num - dwarf_line.last_line;
1092 int n = len_pc * DWARF_LINE_RANGE + len_line + DWARF_OPCODE_BASE - DWARF_LINE_BASE;
1094 if (dwarf_line.cur_file != dwarf_line.last_file) {
1095 dwarf_line.last_file = dwarf_line.cur_file;
1096 dwarf_line_op(s1, DW_LNS_set_file);
1097 dwarf_uleb128_op(s1, dwarf_line.cur_file);
1099 if (len_pc &&
1100 len_line >= DWARF_LINE_BASE && len_line <= (DWARF_OPCODE_BASE + DWARF_LINE_BASE) &&
1101 n >= DWARF_OPCODE_BASE && n <= 255)
1102 dwarf_line_op(s1, n);
1103 else {
1104 if (len_pc) {
1105 n = len_pc * DWARF_LINE_RANGE + 0 + DWARF_OPCODE_BASE - DWARF_LINE_BASE;
1106 if (n >= DWARF_OPCODE_BASE && n <= 255)
1107 dwarf_line_op(s1, n);
1108 else {
1109 dwarf_line_op(s1, DW_LNS_advance_pc);
1110 dwarf_uleb128_op(s1, len_pc);
1113 if (len_line) {
1114 n = 0 * DWARF_LINE_RANGE + len_line + DWARF_OPCODE_BASE - DWARF_LINE_BASE;
1115 if (len_line >= DWARF_LINE_BASE && len_line <= (DWARF_OPCODE_BASE + DWARF_LINE_BASE) &&
1116 n >= DWARF_OPCODE_BASE && n <= 255)
1117 dwarf_line_op(s1, n);
1118 else {
1119 dwarf_line_op(s1, DW_LNS_advance_line);
1120 dwarf_sleb128_op(s1, len_line);
1124 dwarf_line.last_pc = ind;
1125 dwarf_line.last_line = f->line_num;
1127 else
1129 if (func_ind != -1) {
1130 put_stabn(s1, N_SLINE, 0, f->line_num, ind - func_ind);
1131 } else {
1132 /* from tcc_assemble */
1133 put_stabs_r(s1, NULL, N_SLINE, 0, f->line_num, ind, text_section, section_sym);
1138 static void tcc_debug_stabs (TCCState *s1, const char *str, int type, unsigned long value,
1139 Section *sec, int sym_index, int info)
1141 struct debug_sym *s;
1143 if (debug_info) {
1144 debug_info->sym =
1145 (struct debug_sym *)tcc_realloc (debug_info->sym,
1146 sizeof(struct debug_sym) *
1147 (debug_info->n_sym + 1));
1148 s = debug_info->sym + debug_info->n_sym++;
1149 s->type = type;
1150 s->value = value;
1151 s->str = tcc_strdup(str);
1152 s->sec = sec;
1153 s->sym_index = sym_index;
1154 s->info = info;
1155 s->file = dwarf_line.cur_file;
1156 s->line = file->line_num;
1158 else if (sec)
1159 put_stabs_r (s1, str, type, 0, 0, value, sec, sym_index);
1160 else
1161 put_stabs (s1, str, type, 0, 0, value);
1164 ST_FUNC void tcc_debug_stabn(TCCState *s1, int type, int value)
1166 if (!s1->do_debug)
1167 return;
1168 if (type == N_LBRAC) {
1169 struct _debug_info *info =
1170 (struct _debug_info *) tcc_mallocz(sizeof (*info));
1172 info->start = value;
1173 info->parent = debug_info;
1174 if (debug_info) {
1175 if (debug_info->child) {
1176 if (debug_info->child->last)
1177 debug_info->child->last->next = info;
1178 else
1179 debug_info->child->next = info;
1180 debug_info->child->last = info;
1182 else
1183 debug_info->child = info;
1185 else
1186 debug_info_root = info;
1187 debug_info = info;
1189 else {
1190 debug_info->end = value;
1191 debug_info = debug_info->parent;
1195 static int tcc_debug_find(TCCState *s1, Sym *t, int dwarf)
1197 int i;
1199 if (!debug_info && dwarf &&
1200 (t->type.t & VT_BTYPE) == VT_STRUCT && t->c == -1) {
1201 for (i = 0; i < n_debug_anon_hash; i++)
1202 if (t == debug_anon_hash[i].type)
1203 return 0;
1204 debug_anon_hash = (struct _debug_anon_hash *)
1205 tcc_realloc (debug_anon_hash,
1206 (n_debug_anon_hash + 1) * sizeof(*debug_anon_hash));
1207 debug_anon_hash[n_debug_anon_hash].n_debug_type = 0;
1208 debug_anon_hash[n_debug_anon_hash].debug_type = NULL;
1209 debug_anon_hash[n_debug_anon_hash++].type = t;
1210 return 0;
1212 for (i = 0; i < n_debug_hash; i++)
1213 if (t == debug_hash[i].type)
1214 return debug_hash[i].debug_type;
1215 return -1;
1218 static int tcc_get_dwarf_info(TCCState *s1, Sym *s);
1220 static void tcc_debug_check_anon(TCCState *s1, Sym *t, int debug_type)
1222 int i;
1224 if (!debug_info && (t->type.t & VT_BTYPE) == VT_STRUCT && t->type.ref->c == -1)
1225 for (i = 0; i < n_debug_anon_hash; i++)
1226 if (t->type.ref == debug_anon_hash[i].type) {
1227 debug_anon_hash[i].debug_type =
1228 tcc_realloc(debug_anon_hash[i].debug_type,
1229 (debug_anon_hash[i].n_debug_type + 1) * sizeof(int));
1230 debug_anon_hash[i].debug_type[debug_anon_hash[i].n_debug_type++] =
1231 debug_type;
1235 ST_FUNC void tcc_debug_fix_anon(TCCState *s1, CType *t)
1237 int i, j, debug_type;
1239 if (!s1->do_debug || !s1->dwarf || debug_info)
1240 return;
1241 if ((t->t & VT_BTYPE) == VT_STRUCT && t->ref->c != -1)
1242 for (i = 0; i < n_debug_anon_hash; i++)
1243 if (t->ref == debug_anon_hash[i].type) {
1244 Sym sym = {0}; sym .type = *t ;
1246 /* Trick to not hash this struct */
1247 debug_info = (struct _debug_info *) t;
1248 debug_type = tcc_get_dwarf_info(s1, &sym);
1249 debug_info = NULL;
1250 for (j = 0; j < debug_anon_hash[i].n_debug_type; j++)
1251 write32le(dwarf_info_section->data +
1252 debug_anon_hash[i].debug_type[j],
1253 debug_type - dwarf_info.start);
1254 tcc_free(debug_anon_hash[i].debug_type);
1255 n_debug_anon_hash--;
1256 for (; i < n_debug_anon_hash; i++)
1257 debug_anon_hash[i] = debug_anon_hash[i + 1];
1261 static int tcc_debug_add(TCCState *s1, Sym *t, int dwarf)
1263 int offset = dwarf ? dwarf_info_section->data_offset : ++debug_next_type;
1264 debug_hash = (struct _debug_hash *)
1265 tcc_realloc (debug_hash,
1266 (n_debug_hash + 1) * sizeof(*debug_hash));
1267 debug_hash[n_debug_hash].debug_type = offset;
1268 debug_hash[n_debug_hash++].type = t;
1269 return offset;
1272 static void tcc_debug_remove(TCCState *s1, Sym *t)
1274 int i;
1276 for (i = 0; i < n_debug_hash; i++)
1277 if (t == debug_hash[i].type) {
1278 n_debug_hash--;
1279 for (; i < n_debug_hash; i++)
1280 debug_hash[i] = debug_hash[i+1];
1284 static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result)
1286 int type;
1287 int n = 0;
1288 int debug_type = -1;
1289 Sym *t = s;
1290 CString str;
1292 for (;;) {
1293 type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE | VT_VLA);
1294 if ((type & VT_BTYPE) != VT_BYTE)
1295 type &= ~VT_DEFSIGN;
1296 if (type == VT_PTR || type == (VT_PTR | VT_ARRAY))
1297 n++, t = t->type.ref;
1298 else
1299 break;
1301 if ((type & VT_BTYPE) == VT_STRUCT) {
1302 Sym *e = t;
1304 t = t->type.ref;
1305 debug_type = tcc_debug_find(s1, t, 0);
1306 if (debug_type == -1) {
1307 debug_type = tcc_debug_add(s1, t, 0);
1308 cstr_new (&str);
1309 cstr_printf (&str, "%s:T%d=%c%d",
1310 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
1311 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL),
1312 debug_type,
1313 IS_UNION (t->type.t) ? 'u' : 's',
1314 t->c);
1315 while (t->next) {
1316 int pos, size, align;
1318 t = t->next;
1319 cstr_printf (&str, "%s:",
1320 (t->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
1321 ? "" : get_tok_str(t->v & ~SYM_FIELD, NULL));
1322 tcc_get_debug_info (s1, t, &str);
1323 if (t->type.t & VT_BITFIELD) {
1324 pos = t->c * 8 + BIT_POS(t->type.t);
1325 size = BIT_SIZE(t->type.t);
1327 else {
1328 pos = t->c * 8;
1329 size = type_size(&t->type, &align) * 8;
1331 cstr_printf (&str, ",%d,%d;", pos, size);
1333 cstr_printf (&str, ";");
1334 tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0);
1335 cstr_free (&str);
1336 if (debug_info)
1337 tcc_debug_remove(s1, e);
1340 else if (IS_ENUM(type)) {
1341 Sym *e = t = t->type.ref;
1343 debug_type = tcc_debug_find(s1, t, 0);
1344 if (debug_type == -1) {
1345 debug_type = tcc_debug_add(s1, t, 0);
1346 cstr_new (&str);
1347 cstr_printf (&str, "%s:T%d=e",
1348 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
1349 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL),
1350 debug_type);
1351 while (t->next) {
1352 t = t->next;
1353 cstr_printf (&str, "%s:",
1354 (t->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
1355 ? "" : get_tok_str(t->v & ~SYM_FIELD, NULL));
1356 cstr_printf (&str, e->type.t & VT_UNSIGNED ? "%u," : "%d,",
1357 (int)t->enum_val);
1359 cstr_printf (&str, ";");
1360 tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0);
1361 cstr_free (&str);
1362 if (debug_info)
1363 tcc_debug_remove(s1, e);
1366 else if ((type & VT_BTYPE) != VT_FUNC) {
1367 type &= ~VT_STRUCT_MASK;
1368 for (debug_type = 1; debug_type <= N_DEFAULT_DEBUG; debug_type++)
1369 if (default_debug[debug_type - 1].type == type)
1370 break;
1371 if (debug_type > N_DEFAULT_DEBUG)
1372 return;
1374 if (n > 0)
1375 cstr_printf (result, "%d=", ++debug_next_type);
1376 t = s;
1377 for (;;) {
1378 type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE | VT_VLA);
1379 if ((type & VT_BTYPE) != VT_BYTE)
1380 type &= ~VT_DEFSIGN;
1381 if (type == VT_PTR)
1382 cstr_printf (result, "%d=*", ++debug_next_type);
1383 else if (type == (VT_PTR | VT_ARRAY))
1384 cstr_printf (result, "%d=ar1;0;%d;",
1385 ++debug_next_type, t->type.ref->c - 1);
1386 else if (type == VT_FUNC) {
1387 cstr_printf (result, "%d=f", ++debug_next_type);
1388 tcc_get_debug_info (s1, t->type.ref, result);
1389 return;
1391 else
1392 break;
1393 t = t->type.ref;
1395 cstr_printf (result, "%d", debug_type);
1398 static int tcc_get_dwarf_info(TCCState *s1, Sym *s)
1400 int type;
1401 int debug_type = -1;
1402 Sym *e, *t = s;
1403 int i;
1404 int last_pos = -1;
1405 int retval;
1407 if (new_file)
1408 put_new_file(s1);
1409 for (;;) {
1410 type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE | VT_VLA);
1411 if ((type & VT_BTYPE) != VT_BYTE)
1412 type &= ~VT_DEFSIGN;
1413 if (type == VT_PTR || type == (VT_PTR | VT_ARRAY))
1414 t = t->type.ref;
1415 else
1416 break;
1418 if ((type & VT_BTYPE) == VT_STRUCT) {
1419 t = t->type.ref;
1420 debug_type = tcc_debug_find(s1, t, 1);
1421 if (debug_type == -1) {
1422 int pos_sib, i, *pos_type;
1424 debug_type = tcc_debug_add(s1, t, 1);
1425 e = t;
1426 i = 0;
1427 while (e->next) {
1428 e = e->next;
1429 i++;
1431 pos_type = (int *) tcc_malloc(i * sizeof(int));
1432 dwarf_data1(dwarf_info_section,
1433 IS_UNION (t->type.t) ? DWARF_ABBREV_UNION_TYPE
1434 : DWARF_ABBREV_STRUCTURE_TYPE);
1435 dwarf_strp(dwarf_info_section,
1436 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
1437 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL));
1438 dwarf_uleb128(dwarf_info_section, t->c);
1439 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
1440 dwarf_uleb128(dwarf_info_section, file->line_num);
1441 pos_sib = dwarf_info_section->data_offset;
1442 dwarf_data4(dwarf_info_section, 0);
1443 e = t;
1444 i = 0;
1445 while (e->next) {
1446 e = e->next;
1447 dwarf_data1(dwarf_info_section,
1448 e->type.t & VT_BITFIELD ? DWARF_ABBREV_MEMBER_BF
1449 : DWARF_ABBREV_MEMBER);
1450 dwarf_strp(dwarf_info_section,
1451 (e->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
1452 ? "" : get_tok_str(e->v & ~SYM_FIELD, NULL));
1453 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
1454 dwarf_uleb128(dwarf_info_section, file->line_num);
1455 pos_type[i++] = dwarf_info_section->data_offset;
1456 dwarf_data4(dwarf_info_section, 0);
1457 if (e->type.t & VT_BITFIELD) {
1458 int pos = e->c * 8 + BIT_POS(e->type.t);
1459 int size = BIT_SIZE(e->type.t);
1461 dwarf_uleb128(dwarf_info_section, size);
1462 dwarf_uleb128(dwarf_info_section, pos);
1464 else
1465 dwarf_uleb128(dwarf_info_section, e->c);
1467 dwarf_data1(dwarf_info_section, 0);
1468 write32le(dwarf_info_section->data + pos_sib,
1469 dwarf_info_section->data_offset - dwarf_info.start);
1470 e = t;
1471 i = 0;
1472 while (e->next) {
1473 e = e->next;
1474 type = tcc_get_dwarf_info(s1, e);
1475 tcc_debug_check_anon(s1, e, pos_type[i]);
1476 write32le(dwarf_info_section->data + pos_type[i++],
1477 type - dwarf_info.start);
1479 tcc_free(pos_type);
1480 if (debug_info)
1481 tcc_debug_remove(s1, t);
1484 else if (IS_ENUM(type)) {
1485 t = t->type.ref;
1486 debug_type = tcc_debug_find(s1, t, 1);
1487 if (debug_type == -1) {
1488 int pos_sib, pos_type;
1489 Sym sym = {0}; sym.type.t = VT_INT | (type & VT_UNSIGNED);
1491 pos_type = tcc_get_dwarf_info(s1, &sym);
1492 debug_type = tcc_debug_add(s1, t, 1);
1493 dwarf_data1(dwarf_info_section, DWARF_ABBREV_ENUMERATION_TYPE);
1494 dwarf_strp(dwarf_info_section,
1495 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
1496 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL));
1497 dwarf_data1(dwarf_info_section,
1498 type & VT_UNSIGNED ? DW_ATE_unsigned : DW_ATE_signed );
1499 dwarf_data1(dwarf_info_section, 4);
1500 dwarf_data4(dwarf_info_section, pos_type - dwarf_info.start);
1501 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
1502 dwarf_uleb128(dwarf_info_section, file->line_num);
1503 pos_sib = dwarf_info_section->data_offset;
1504 dwarf_data4(dwarf_info_section, 0);
1505 e = t;
1506 while (e->next) {
1507 e = e->next;
1508 dwarf_data1(dwarf_info_section,
1509 type & VT_UNSIGNED ? DWARF_ABBREV_ENUMERATOR_UNSIGNED
1510 : DWARF_ABBREV_ENUMERATOR_SIGNED);
1511 dwarf_strp(dwarf_info_section,
1512 (e->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
1513 ? "" : get_tok_str(e->v & ~SYM_FIELD, NULL));
1514 if (type & VT_UNSIGNED)
1515 dwarf_uleb128(dwarf_info_section, e->enum_val);
1516 else
1517 dwarf_sleb128(dwarf_info_section, e->enum_val);
1519 dwarf_data1(dwarf_info_section, 0);
1520 write32le(dwarf_info_section->data + pos_sib,
1521 dwarf_info_section->data_offset - dwarf_info.start);
1522 if (debug_info)
1523 tcc_debug_remove(s1, t);
1526 else if ((type & VT_BTYPE) != VT_FUNC) {
1527 type &= ~VT_STRUCT_MASK;
1528 for (i = 1; i <= N_DEFAULT_DEBUG; i++)
1529 if (default_debug[i - 1].type == type)
1530 break;
1531 if (i > N_DEFAULT_DEBUG)
1532 return 0;
1533 debug_type = dwarf_info.base_type_used[i - 1];
1534 if (debug_type == 0) {
1535 char name[100];
1537 debug_type = dwarf_info_section->data_offset;
1538 dwarf_data1(dwarf_info_section, DWARF_ABBREV_BASE_TYPE);
1539 dwarf_uleb128(dwarf_info_section, default_debug[i - 1].size);
1540 dwarf_data1(dwarf_info_section, default_debug[i - 1].encoding);
1541 strncpy(name, default_debug[i - 1].name, sizeof(name) -1);
1542 *strchr(name, ':') = 0;
1543 dwarf_strp(dwarf_info_section, name);
1544 dwarf_info.base_type_used[i - 1] = debug_type;
1547 retval = debug_type;
1548 e = NULL;
1549 t = s;
1550 for (;;) {
1551 type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE | VT_VLA);
1552 if ((type & VT_BTYPE) != VT_BYTE)
1553 type &= ~VT_DEFSIGN;
1554 if (type == VT_PTR) {
1555 i = dwarf_info_section->data_offset;
1556 if (retval == debug_type)
1557 retval = i;
1558 dwarf_data1(dwarf_info_section, DWARF_ABBREV_POINTER);
1559 dwarf_data1(dwarf_info_section, PTR_SIZE);
1560 if (last_pos != -1) {
1561 tcc_debug_check_anon(s1, e, last_pos);
1562 write32le(dwarf_info_section->data + last_pos,
1563 i - dwarf_info.start);
1565 last_pos = dwarf_info_section->data_offset;
1566 e = t->type.ref;
1567 dwarf_data4(dwarf_info_section, 0);
1569 else if (type == (VT_PTR | VT_ARRAY)) {
1570 int sib_pos, sub_type;
1571 #if LONG_SIZE == 4
1572 Sym sym = {0}; sym.type.t = VT_LONG | VT_INT | VT_UNSIGNED;
1573 #else
1574 Sym sym = {0}; sym.type.t = VT_LLONG | VT_LONG | VT_UNSIGNED;
1575 #endif
1577 sub_type = tcc_get_dwarf_info(s1, &sym);
1578 i = dwarf_info_section->data_offset;
1579 if (retval == debug_type)
1580 retval = i;
1581 dwarf_data1(dwarf_info_section, DWARF_ABBREV_ARRAY_TYPE);
1582 if (last_pos != -1) {
1583 tcc_debug_check_anon(s1, e, last_pos);
1584 write32le(dwarf_info_section->data + last_pos,
1585 i - dwarf_info.start);
1587 last_pos = dwarf_info_section->data_offset;
1588 e = t->type.ref;
1589 dwarf_data4(dwarf_info_section, 0);
1590 sib_pos = dwarf_info_section->data_offset;
1591 dwarf_data4(dwarf_info_section, 0);
1592 for (;;) {
1593 dwarf_data1(dwarf_info_section, DWARF_ABBREV_SUBRANGE_TYPE);
1594 dwarf_data4(dwarf_info_section, sub_type - dwarf_info.start);
1595 dwarf_uleb128(dwarf_info_section, t->type.ref->c - 1);
1596 s = t->type.ref;
1597 type = s->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE);
1598 if (type != (VT_PTR | VT_ARRAY))
1599 break;
1600 t = s;
1602 dwarf_data1(dwarf_info_section, 0);
1603 write32le(dwarf_info_section->data + sib_pos,
1604 dwarf_info_section->data_offset - dwarf_info.start);
1606 else if (type == VT_FUNC) {
1607 int sib_pos, *pos_type;
1608 Sym *f;
1610 i = dwarf_info_section->data_offset;
1611 debug_type = tcc_get_dwarf_info(s1, t->type.ref);
1612 if (retval == debug_type)
1613 retval = i;
1614 dwarf_data1(dwarf_info_section, DWARF_ABBREV_SUBROUTINE_TYPE);
1615 if (last_pos != -1) {
1616 tcc_debug_check_anon(s1, e, last_pos);
1617 write32le(dwarf_info_section->data + last_pos,
1618 i - dwarf_info.start);
1620 last_pos = dwarf_info_section->data_offset;
1621 e = t->type.ref;
1622 dwarf_data4(dwarf_info_section, 0);
1623 sib_pos = dwarf_info_section->data_offset;
1624 dwarf_data4(dwarf_info_section, 0);
1625 f = t->type.ref;
1626 i = 0;
1627 while (f->next) {
1628 f = f->next;
1629 i++;
1631 pos_type = (int *) tcc_malloc(i * sizeof(int));
1632 f = t->type.ref;
1633 i = 0;
1634 while (f->next) {
1635 f = f->next;
1636 dwarf_data1(dwarf_info_section, DWARF_ABBREV_FORMAL_PARAMETER2);
1637 pos_type[i++] = dwarf_info_section->data_offset;
1638 dwarf_data4(dwarf_info_section, 0);
1640 dwarf_data1(dwarf_info_section, 0);
1641 write32le(dwarf_info_section->data + sib_pos,
1642 dwarf_info_section->data_offset - dwarf_info.start);
1643 f = t->type.ref;
1644 i = 0;
1645 while (f->next) {
1646 f = f->next;
1647 type = tcc_get_dwarf_info(s1, f);
1648 tcc_debug_check_anon(s1, f, pos_type[i]);
1649 write32le(dwarf_info_section->data + pos_type[i++],
1650 type - dwarf_info.start);
1652 tcc_free(pos_type);
1654 else {
1655 if (last_pos != -1) {
1656 tcc_debug_check_anon(s1, e, last_pos);
1657 write32le(dwarf_info_section->data + last_pos,
1658 debug_type - dwarf_info.start);
1660 break;
1662 t = t->type.ref;
1664 return retval;
1667 static void tcc_debug_finish (TCCState *s1, struct _debug_info *cur)
1669 while (cur) {
1670 struct _debug_info *next = cur->next;
1671 int i;
1673 if (s1->dwarf) {
1675 for (i = cur->n_sym - 1; i >= 0; i--) {
1676 struct debug_sym *s = &cur->sym[i];
1678 dwarf_data1(dwarf_info_section,
1679 s->type == N_PSYM
1680 ? DWARF_ABBREV_FORMAL_PARAMETER
1681 : s->type == N_GSYM
1682 ? DWARF_ABBREV_VARIABLE_EXTERNAL
1683 : s->type == N_STSYM
1684 ? DWARF_ABBREV_VARIABLE_STATIC
1685 : DWARF_ABBREV_VARIABLE_LOCAL);
1686 dwarf_strp(dwarf_info_section, s->str);
1687 if (s->type == N_GSYM || s->type == N_STSYM) {
1688 dwarf_uleb128(dwarf_info_section, s->file);
1689 dwarf_uleb128(dwarf_info_section, s->line);
1691 dwarf_data4(dwarf_info_section, s->info - dwarf_info.start);
1692 if (s->type == N_GSYM || s->type == N_STSYM) {
1693 /* global/static */
1694 if (s->type == N_GSYM)
1695 dwarf_data1(dwarf_info_section, 1);
1696 dwarf_data1(dwarf_info_section, PTR_SIZE + 1);
1697 dwarf_data1(dwarf_info_section, DW_OP_addr);
1698 if (s->type == N_STSYM)
1699 dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR);
1700 #if PTR_SIZE == 4
1701 dwarf_data4(dwarf_info_section, s->value);
1702 #else
1703 dwarf_data8(dwarf_info_section, s->value);
1704 #endif
1706 else {
1707 /* param/local */
1708 dwarf_data1(dwarf_info_section, dwarf_sleb128_size(s->value) + 1);
1709 dwarf_data1(dwarf_info_section, DW_OP_fbreg);
1710 dwarf_sleb128(dwarf_info_section, s->value);
1712 tcc_free (s->str);
1714 tcc_free (cur->sym);
1715 dwarf_data1(dwarf_info_section, DWARF_ABBREV_LEXICAL_BLOCK);
1716 dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR);
1717 #if PTR_SIZE == 4
1718 dwarf_data4(dwarf_info_section, func_ind + cur->start);
1719 dwarf_data4(dwarf_info_section, cur->end - cur->start);
1720 #else
1721 dwarf_data8(dwarf_info_section, func_ind + cur->start);
1722 dwarf_data8(dwarf_info_section, cur->end - cur->start);
1723 #endif
1724 tcc_debug_finish (s1, cur->child);
1725 dwarf_data1(dwarf_info_section, 0);
1727 else
1729 for (i = 0; i < cur->n_sym; i++) {
1730 struct debug_sym *s = &cur->sym[i];
1732 if (s->sec)
1733 put_stabs_r(s1, s->str, s->type, 0, 0, s->value,
1734 s->sec, s->sym_index);
1735 else
1736 put_stabs(s1, s->str, s->type, 0, 0, s->value);
1737 tcc_free (s->str);
1739 tcc_free (cur->sym);
1740 put_stabn(s1, N_LBRAC, 0, 0, cur->start);
1741 tcc_debug_finish (s1, cur->child);
1742 put_stabn(s1, N_RBRAC, 0, 0, cur->end);
1744 tcc_free (cur);
1745 cur = next;
1749 ST_FUNC void tcc_add_debug_info(TCCState *s1, int param, Sym *s, Sym *e)
1751 CString debug_str;
1752 if (!s1->do_debug)
1753 return;
1754 cstr_new (&debug_str);
1755 for (; s != e; s = s->prev) {
1756 if (!s->v || (s->r & VT_VALMASK) != VT_LOCAL)
1757 continue;
1758 if (s1->dwarf) {
1759 tcc_debug_stabs(s1, get_tok_str(s->v, NULL),
1760 param ? N_PSYM : N_LSYM, s->c, NULL, 0,
1761 tcc_get_dwarf_info(s1, s));
1763 else
1765 cstr_reset (&debug_str);
1766 cstr_printf (&debug_str, "%s:%s", get_tok_str(s->v, NULL),
1767 param ? "p" : "");
1768 tcc_get_debug_info(s1, s, &debug_str);
1769 tcc_debug_stabs(s1, debug_str.data, param ? N_PSYM : N_LSYM,
1770 s->c, NULL, 0, 0);
1773 cstr_free (&debug_str);
1776 /* put function symbol */
1777 ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym)
1779 CString debug_str;
1780 BufferedFile *f;
1782 if (!s1->do_debug)
1783 return;
1784 debug_info_root = NULL;
1785 debug_info = NULL;
1786 tcc_debug_stabn(s1, N_LBRAC, ind - func_ind);
1787 f = put_new_file(s1);
1788 if (!f)
1789 return;
1791 if (s1->dwarf) {
1792 tcc_debug_line(s1);
1793 dwarf_line_op(s1, DW_LNS_copy);
1794 dwarf_info.func = sym;
1795 dwarf_info.line = file->line_num;
1796 if (s1->do_backtrace) {
1797 int i, len;
1799 dwarf_line_op(s1, 0); // extended
1800 dwarf_uleb128_op(s1, strlen(funcname) + 2);
1801 dwarf_line_op(s1, DW_LNE_hi_user - 1);
1802 len = strlen(funcname) + 1;
1803 for (i = 0; i < len; i++)
1804 dwarf_line_op(s1, funcname[i]);
1807 else
1809 cstr_new (&debug_str);
1810 cstr_printf(&debug_str, "%s:%c", funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
1811 tcc_get_debug_info(s1, sym->type.ref, &debug_str);
1812 put_stabs_r(s1, debug_str.data, N_FUN, 0, f->line_num, 0, cur_text_section, sym->c);
1813 cstr_free (&debug_str);
1814 tcc_debug_line(s1);
1818 /* put function size */
1819 ST_FUNC void tcc_debug_funcend(TCCState *s1, int size)
1821 if (!s1->do_debug)
1822 return;
1823 tcc_debug_line(s1);
1824 tcc_debug_stabn(s1, N_RBRAC, size);
1825 if (s1->dwarf) {
1826 int func_sib = 0;
1827 Sym *sym = dwarf_info.func;
1828 int n_debug_info = tcc_get_dwarf_info(s1, sym->type.ref);
1830 dwarf_data1(dwarf_info_section,
1831 sym->type.t & VT_STATIC ? DWARF_ABBREV_SUBPROGRAM_STATIC
1832 : DWARF_ABBREV_SUBPROGRAM_EXTERNAL);
1833 if ((sym->type.t & VT_STATIC) == 0)
1834 dwarf_data1(dwarf_info_section, 1);
1835 dwarf_strp(dwarf_info_section, funcname);
1836 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
1837 dwarf_uleb128(dwarf_info_section, dwarf_info.line);
1838 tcc_debug_check_anon(s1, sym->type.ref, dwarf_info_section->data_offset);
1839 dwarf_data4(dwarf_info_section, n_debug_info - dwarf_info.start);
1840 dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR);
1841 #if PTR_SIZE == 4
1842 dwarf_data4(dwarf_info_section, func_ind); // low_pc
1843 dwarf_data4(dwarf_info_section, size); // high_pc
1844 #else
1845 dwarf_data8(dwarf_info_section, func_ind); // low_pc
1846 dwarf_data8(dwarf_info_section, size); // high_pc
1847 #endif
1848 func_sib = dwarf_info_section->data_offset;
1849 dwarf_data4(dwarf_info_section, 0); // sibling
1850 dwarf_data1(dwarf_info_section, 1);
1851 #if defined(TCC_TARGET_I386)
1852 dwarf_data1(dwarf_info_section, DW_OP_reg5); // ebp
1853 #elif defined(TCC_TARGET_X86_64)
1854 dwarf_data1(dwarf_info_section, DW_OP_reg6); // rbp
1855 #elif defined TCC_TARGET_ARM
1856 dwarf_data1(dwarf_info_section, DW_OP_reg13); // sp
1857 #elif defined TCC_TARGET_ARM64
1858 dwarf_data1(dwarf_info_section, DW_OP_reg29); // reg 29
1859 #elif defined TCC_TARGET_RISCV64
1860 dwarf_data1(dwarf_info_section, DW_OP_reg8); // r8(s0)
1861 #else
1862 dwarf_data1(dwarf_info_section, DW_OP_call_frame_cfa);
1863 #endif
1864 tcc_debug_finish (s1, debug_info_root);
1865 dwarf_data1(dwarf_info_section, 0);
1866 write32le(dwarf_info_section->data + func_sib,
1867 dwarf_info_section->data_offset - dwarf_info.start);
1869 else
1871 tcc_debug_finish (s1, debug_info_root);
1876 ST_FUNC void tcc_debug_extern_sym(TCCState *s1, Sym *sym, int sh_num, int sym_bind, int sym_type)
1878 if (!s1->do_debug)
1879 return;
1880 if (sym_type == STT_FUNC || sym->v >= SYM_FIRST_ANOM)
1881 return;
1882 if (s1->dwarf) {
1883 int debug_type;
1885 debug_type = tcc_get_dwarf_info(s1, sym);
1886 dwarf_data1(dwarf_info_section,
1887 sym_bind == STB_GLOBAL
1888 ? DWARF_ABBREV_VARIABLE_EXTERNAL
1889 : DWARF_ABBREV_VARIABLE_STATIC);
1890 dwarf_strp(dwarf_info_section, get_tok_str(sym->v, NULL));
1891 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
1892 dwarf_uleb128(dwarf_info_section, file->line_num);
1893 tcc_debug_check_anon(s1, sym, dwarf_info_section->data_offset);
1894 dwarf_data4(dwarf_info_section, debug_type - dwarf_info.start);
1895 if (sym_bind == STB_GLOBAL)
1896 dwarf_data1(dwarf_info_section, 1);
1897 dwarf_data1(dwarf_info_section, PTR_SIZE + 1);
1898 dwarf_data1(dwarf_info_section, DW_OP_addr);
1899 greloca(dwarf_info_section, sym, dwarf_info_section->data_offset,
1900 R_DATA_PTR, 0);
1901 #if PTR_SIZE == 4
1902 dwarf_data4(dwarf_info_section, 0);
1903 #else
1904 dwarf_data8(dwarf_info_section, 0);
1905 #endif
1907 else
1909 Section *s = s1->sections[sh_num];
1910 CString str;
1912 cstr_new (&str);
1913 cstr_printf (&str, "%s:%c",
1914 get_tok_str(sym->v, NULL),
1915 sym_bind == STB_GLOBAL ? 'G' : func_ind != -1 ? 'V' : 'S'
1917 tcc_get_debug_info(s1, sym, &str);
1918 if (sym_bind == STB_GLOBAL)
1919 tcc_debug_stabs(s1, str.data, N_GSYM, 0, NULL, 0, 0);
1920 else
1921 tcc_debug_stabs(s1, str.data,
1922 (sym->type.t & VT_STATIC) && data_section == s
1923 ? N_STSYM : N_LCSYM, 0, s, sym->c, 0);
1924 cstr_free (&str);
1928 ST_FUNC void tcc_debug_typedef(TCCState *s1, Sym *sym)
1930 if (!s1->do_debug)
1931 return;
1932 if (s1->dwarf) {
1933 int debug_type;
1935 debug_type = tcc_get_dwarf_info(s1, sym);
1936 if (debug_type != -1) {
1937 dwarf_data1(dwarf_info_section, DWARF_ABBREV_TYPEDEF);
1938 dwarf_strp(dwarf_info_section, get_tok_str(sym->v & ~SYM_FIELD, NULL));
1939 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
1940 dwarf_uleb128(dwarf_info_section, file->line_num);
1941 tcc_debug_check_anon(s1, sym, dwarf_info_section->data_offset);
1942 dwarf_data4(dwarf_info_section, debug_type - dwarf_info.start);
1945 else
1947 CString str;
1948 cstr_new (&str);
1949 cstr_printf (&str, "%s:t",
1950 (sym->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
1951 ? "" : get_tok_str(sym->v & ~SYM_FIELD, NULL));
1952 tcc_get_debug_info(s1, sym, &str);
1953 tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0);
1954 cstr_free (&str);
1958 /* ------------------------------------------------------------------------- */
1959 /* for section layout see lib/tcov.c */
1961 ST_FUNC void tcc_tcov_block_end(TCCState *s1, int line);
1963 ST_FUNC void tcc_tcov_block_begin(TCCState *s1)
1965 SValue sv;
1966 void *ptr;
1967 unsigned long last_offset = tcov_data.offset;
1969 tcc_tcov_block_end (tcc_state, 0);
1970 if (s1->test_coverage == 0 || nocode_wanted)
1971 return;
1973 if (tcov_data.last_file_name == 0 ||
1974 strcmp ((const char *)(tcov_section->data + tcov_data.last_file_name),
1975 file->true_filename) != 0) {
1976 char wd[1024];
1977 CString cstr;
1979 if (tcov_data.last_func_name)
1980 section_ptr_add(tcov_section, 1);
1981 if (tcov_data.last_file_name)
1982 section_ptr_add(tcov_section, 1);
1983 tcov_data.last_func_name = 0;
1984 cstr_new (&cstr);
1985 if (file->true_filename[0] == '/') {
1986 tcov_data.last_file_name = tcov_section->data_offset;
1987 cstr_printf (&cstr, "%s", file->true_filename);
1989 else {
1990 getcwd (wd, sizeof(wd));
1991 tcov_data.last_file_name = tcov_section->data_offset + strlen(wd) + 1;
1992 cstr_printf (&cstr, "%s/%s", wd, file->true_filename);
1994 ptr = section_ptr_add(tcov_section, cstr.size + 1);
1995 strcpy((char *)ptr, cstr.data);
1996 #ifdef _WIN32
1997 normalize_slashes((char *)ptr);
1998 #endif
1999 cstr_free (&cstr);
2001 if (tcov_data.last_func_name == 0 ||
2002 strcmp ((const char *)(tcov_section->data + tcov_data.last_func_name),
2003 funcname) != 0) {
2004 size_t len;
2006 if (tcov_data.last_func_name)
2007 section_ptr_add(tcov_section, 1);
2008 tcov_data.last_func_name = tcov_section->data_offset;
2009 len = strlen (funcname);
2010 ptr = section_ptr_add(tcov_section, len + 1);
2011 strcpy((char *)ptr, funcname);
2012 section_ptr_add(tcov_section, -tcov_section->data_offset & 7);
2013 ptr = section_ptr_add(tcov_section, 8);
2014 write64le (ptr, file->line_num);
2016 if (ind == tcov_data.ind && tcov_data.line == file->line_num)
2017 tcov_data.offset = last_offset;
2018 else {
2019 Sym label = {0};
2020 label.type.t = VT_LLONG | VT_STATIC;
2022 ptr = section_ptr_add(tcov_section, 16);
2023 tcov_data.line = file->line_num;
2024 write64le (ptr, (tcov_data.line << 8) | 0xff);
2025 put_extern_sym(&label, tcov_section,
2026 ((unsigned char *)ptr - tcov_section->data) + 8, 0);
2027 sv.type = label.type;
2028 sv.r = VT_SYM | VT_LVAL | VT_CONST;
2029 sv.r2 = VT_CONST;
2030 sv.c.i = 0;
2031 sv.sym = &label;
2032 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || \
2033 defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64 || \
2034 defined TCC_TARGET_RISCV64
2035 gen_increment_tcov (&sv);
2036 #else
2037 vpushv(&sv);
2038 inc(0, TOK_INC);
2039 vpop();
2040 #endif
2041 tcov_data.offset = (unsigned char *)ptr - tcov_section->data;
2042 tcov_data.ind = ind;
2046 ST_FUNC void tcc_tcov_block_end(TCCState *s1, int line)
2048 if (s1->test_coverage == 0)
2049 return;
2050 if (line == -1)
2051 line = tcov_data.line;
2052 if (tcov_data.offset) {
2053 void *ptr = tcov_section->data + tcov_data.offset;
2054 unsigned long long nline = line ? line : file->line_num;
2056 write64le (ptr, (read64le (ptr) & 0xfffffffffull) | (nline << 36));
2057 tcov_data.offset = 0;
2061 ST_FUNC void tcc_tcov_check_line(TCCState *s1, int start)
2063 if (s1->test_coverage == 0)
2064 return;
2065 if (tcov_data.line != file->line_num) {
2066 if ((tcov_data.line + 1) != file->line_num) {
2067 tcc_tcov_block_end (s1, -1);
2068 if (start)
2069 tcc_tcov_block_begin (s1);
2071 else
2072 tcov_data.line = file->line_num;
2076 ST_FUNC void tcc_tcov_start(TCCState *s1)
2078 if (s1->test_coverage == 0)
2079 return;
2080 if (!s1->dState)
2081 s1->dState = tcc_mallocz(sizeof *s1->dState);
2082 memset (&tcov_data, 0, sizeof (tcov_data));
2083 if (tcov_section == NULL) {
2084 tcov_section = new_section(tcc_state, ".tcov", SHT_PROGBITS,
2085 SHF_ALLOC | SHF_WRITE);
2086 section_ptr_add(tcov_section, 4); // pointer to executable name
2090 ST_FUNC void tcc_tcov_end(TCCState *s1)
2092 if (s1->test_coverage == 0)
2093 return;
2094 if (tcov_data.last_func_name)
2095 section_ptr_add(tcov_section, 1);
2096 if (tcov_data.last_file_name)
2097 section_ptr_add(tcov_section, 1);
2100 ST_FUNC void tcc_tcov_reset_ind(TCCState *s1)
2102 tcov_data.ind = 0;
2105 /* ------------------------------------------------------------------------- */
2106 #undef last_line_num
2107 #undef new_file
2108 #undef section_sym
2109 #undef debug_next_type
2110 #undef debug_hash
2111 #undef n_debug_hash
2112 #undef debug_anon_hash
2113 #undef n_debug_anon_hash
2114 #undef debug_info
2115 #undef debug_info_root
2116 #undef dwarf_sym
2117 #undef dwarf_line
2118 #undef dwarf_info
2119 #undef tcov_data