LIBTCCAPI tcc_relocate(s) : REMOVED 2nd argument
[tinycc.git] / tccdbg.c
blob483afe5ef023b90f764926b67b59a78d3c89dad4
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_STRUCTURE_EMPTY_TYPE 17
115 #define DWARF_ABBREV_UNION_TYPE 18
116 #define DWARF_ABBREV_UNION_EMPTY_TYPE 19
117 #define DWARF_ABBREV_SUBPROGRAM_EXTERNAL 20
118 #define DWARF_ABBREV_SUBPROGRAM_STATIC 21
119 #define DWARF_ABBREV_LEXICAL_BLOCK 22
120 #define DWARF_ABBREV_LEXICAL_EMPTY_BLOCK 23
121 #define DWARF_ABBREV_SUBROUTINE_TYPE 24
122 #define DWARF_ABBREV_SUBROUTINE_EMPTY_TYPE 25
123 #define DWARF_ABBREV_FORMAL_PARAMETER2 26
125 /* all entries should have been generated with dwarf_uleb128 except
126 has_children. All values are currently below 128 so this currently
127 works. */
128 static const unsigned char dwarf_abbrev_init[] = {
129 DWARF_ABBREV_COMPILE_UNIT, DW_TAG_compile_unit, 1,
130 DW_AT_producer, DW_FORM_strp,
131 DW_AT_language, DW_FORM_data1,
132 DW_AT_name, DW_FORM_line_strp,
133 DW_AT_comp_dir, DW_FORM_line_strp,
134 DW_AT_low_pc, DW_FORM_addr,
135 #if PTR_SIZE == 4
136 DW_AT_high_pc, DW_FORM_data4,
137 #else
138 DW_AT_high_pc, DW_FORM_data8,
139 #endif
140 DW_AT_stmt_list, DW_FORM_sec_offset,
141 0, 0,
142 DWARF_ABBREV_BASE_TYPE, DW_TAG_base_type, 0,
143 DW_AT_byte_size, DW_FORM_udata,
144 DW_AT_encoding, DW_FORM_data1,
145 DW_AT_name, DW_FORM_strp,
146 0, 0,
147 DWARF_ABBREV_VARIABLE_EXTERNAL, DW_TAG_variable, 0,
148 DW_AT_name, DW_FORM_strp,
149 DW_AT_decl_file, DW_FORM_udata,
150 DW_AT_decl_line, DW_FORM_udata,
151 DW_AT_type, DW_FORM_ref4,
152 DW_AT_external, DW_FORM_flag,
153 DW_AT_location, DW_FORM_exprloc,
154 0, 0,
155 DWARF_ABBREV_VARIABLE_STATIC, DW_TAG_variable, 0,
156 DW_AT_name, DW_FORM_strp,
157 DW_AT_decl_file, DW_FORM_udata,
158 DW_AT_decl_line, DW_FORM_udata,
159 DW_AT_type, DW_FORM_ref4,
160 DW_AT_location, DW_FORM_exprloc,
161 0, 0,
162 DWARF_ABBREV_VARIABLE_LOCAL, DW_TAG_variable, 0,
163 DW_AT_name, DW_FORM_strp,
164 DW_AT_type, DW_FORM_ref4,
165 DW_AT_location, DW_FORM_exprloc,
166 0, 0,
167 DWARF_ABBREV_FORMAL_PARAMETER, DW_TAG_formal_parameter, 0,
168 DW_AT_name, DW_FORM_strp,
169 DW_AT_type, DW_FORM_ref4,
170 DW_AT_location, DW_FORM_exprloc,
171 0, 0,
172 DWARF_ABBREV_POINTER, DW_TAG_pointer_type, 0,
173 DW_AT_byte_size, DW_FORM_data1,
174 DW_AT_type, DW_FORM_ref4,
175 0, 0,
176 DWARF_ABBREV_ARRAY_TYPE, DW_TAG_array_type, 1,
177 DW_AT_type, DW_FORM_ref4,
178 DW_AT_sibling, DW_FORM_ref4,
179 0, 0,
180 DWARF_ABBREV_SUBRANGE_TYPE, DW_TAG_subrange_type, 0,
181 DW_AT_type, DW_FORM_ref4,
182 DW_AT_upper_bound, DW_FORM_udata,
183 0, 0,
184 DWARF_ABBREV_TYPEDEF, DW_TAG_typedef, 0,
185 DW_AT_name, DW_FORM_strp,
186 DW_AT_decl_file, DW_FORM_udata,
187 DW_AT_decl_line, DW_FORM_udata,
188 DW_AT_type, DW_FORM_ref4,
189 0, 0,
190 DWARF_ABBREV_ENUMERATOR_SIGNED, DW_TAG_enumerator, 0,
191 DW_AT_name, DW_FORM_strp,
192 DW_AT_const_value, DW_FORM_sdata,
193 0, 0,
194 DWARF_ABBREV_ENUMERATOR_UNSIGNED, DW_TAG_enumerator, 0,
195 DW_AT_name, DW_FORM_strp,
196 DW_AT_const_value, DW_FORM_udata,
197 0, 0,
198 DWARF_ABBREV_ENUMERATION_TYPE, DW_TAG_enumeration_type, 1,
199 DW_AT_name, DW_FORM_strp,
200 DW_AT_encoding, DW_FORM_data1,
201 DW_AT_byte_size, DW_FORM_data1,
202 DW_AT_type, DW_FORM_ref4,
203 DW_AT_decl_file, DW_FORM_udata,
204 DW_AT_decl_line, DW_FORM_udata,
205 DW_AT_sibling, DW_FORM_ref4,
206 0, 0,
207 DWARF_ABBREV_MEMBER, DW_TAG_member, 0,
208 DW_AT_name, DW_FORM_strp,
209 DW_AT_decl_file, DW_FORM_udata,
210 DW_AT_decl_line, DW_FORM_udata,
211 DW_AT_type, DW_FORM_ref4,
212 DW_AT_data_member_location, DW_FORM_udata,
213 0, 0,
214 DWARF_ABBREV_MEMBER_BF, DW_TAG_member, 0,
215 DW_AT_name, DW_FORM_strp,
216 DW_AT_decl_file, DW_FORM_udata,
217 DW_AT_decl_line, DW_FORM_udata,
218 DW_AT_type, DW_FORM_ref4,
219 DW_AT_bit_size, DW_FORM_udata,
220 DW_AT_data_bit_offset, DW_FORM_udata,
221 0, 0,
222 DWARF_ABBREV_STRUCTURE_TYPE, DW_TAG_structure_type, 1,
223 DW_AT_name, DW_FORM_strp,
224 DW_AT_byte_size, DW_FORM_udata,
225 DW_AT_decl_file, DW_FORM_udata,
226 DW_AT_decl_line, DW_FORM_udata,
227 DW_AT_sibling, DW_FORM_ref4,
228 0, 0,
229 DWARF_ABBREV_STRUCTURE_EMPTY_TYPE, DW_TAG_structure_type, 0,
230 DW_AT_name, DW_FORM_strp,
231 DW_AT_byte_size, DW_FORM_udata,
232 DW_AT_decl_file, DW_FORM_udata,
233 DW_AT_decl_line, DW_FORM_udata,
234 0, 0,
235 DWARF_ABBREV_UNION_TYPE, DW_TAG_union_type, 1,
236 DW_AT_name, DW_FORM_strp,
237 DW_AT_byte_size, DW_FORM_udata,
238 DW_AT_decl_file, DW_FORM_udata,
239 DW_AT_decl_line, DW_FORM_udata,
240 DW_AT_sibling, DW_FORM_ref4,
241 0, 0,
242 DWARF_ABBREV_UNION_EMPTY_TYPE, DW_TAG_union_type, 0,
243 DW_AT_name, DW_FORM_strp,
244 DW_AT_byte_size, DW_FORM_udata,
245 DW_AT_decl_file, DW_FORM_udata,
246 DW_AT_decl_line, DW_FORM_udata,
247 0, 0,
248 DWARF_ABBREV_SUBPROGRAM_EXTERNAL, DW_TAG_subprogram, 1,
249 DW_AT_external, DW_FORM_flag,
250 DW_AT_name, DW_FORM_strp,
251 DW_AT_decl_file, DW_FORM_udata,
252 DW_AT_decl_line, DW_FORM_udata,
253 DW_AT_type, DW_FORM_ref4,
254 DW_AT_low_pc, DW_FORM_addr,
255 #if PTR_SIZE == 4
256 DW_AT_high_pc, DW_FORM_data4,
257 #else
258 DW_AT_high_pc, DW_FORM_data8,
259 #endif
260 DW_AT_sibling, DW_FORM_ref4,
261 DW_AT_frame_base, DW_FORM_exprloc,
262 0, 0,
263 DWARF_ABBREV_SUBPROGRAM_STATIC, DW_TAG_subprogram, 1,
264 DW_AT_name, DW_FORM_strp,
265 DW_AT_decl_file, DW_FORM_udata,
266 DW_AT_decl_line, DW_FORM_udata,
267 DW_AT_type, DW_FORM_ref4,
268 DW_AT_low_pc, DW_FORM_addr,
269 #if PTR_SIZE == 4
270 DW_AT_high_pc, DW_FORM_data4,
271 #else
272 DW_AT_high_pc, DW_FORM_data8,
273 #endif
274 DW_AT_sibling, DW_FORM_ref4,
275 DW_AT_frame_base, DW_FORM_exprloc,
276 0, 0,
277 DWARF_ABBREV_LEXICAL_BLOCK, DW_TAG_lexical_block, 1,
278 DW_AT_low_pc, DW_FORM_addr,
279 #if PTR_SIZE == 4
280 DW_AT_high_pc, DW_FORM_data4,
281 #else
282 DW_AT_high_pc, DW_FORM_data8,
283 #endif
284 0, 0,
285 DWARF_ABBREV_LEXICAL_EMPTY_BLOCK, DW_TAG_lexical_block, 0,
286 DW_AT_low_pc, DW_FORM_addr,
287 #if PTR_SIZE == 4
288 DW_AT_high_pc, DW_FORM_data4,
289 #else
290 DW_AT_high_pc, DW_FORM_data8,
291 #endif
292 0, 0,
293 DWARF_ABBREV_SUBROUTINE_TYPE, DW_TAG_subroutine_type, 1,
294 DW_AT_type, DW_FORM_ref4,
295 DW_AT_sibling, DW_FORM_ref4,
296 0, 0,
297 DWARF_ABBREV_SUBROUTINE_EMPTY_TYPE, DW_TAG_subroutine_type, 0,
298 DW_AT_type, DW_FORM_ref4,
299 0, 0,
300 DWARF_ABBREV_FORMAL_PARAMETER2, DW_TAG_formal_parameter, 0,
301 DW_AT_type, DW_FORM_ref4,
302 0, 0,
306 static const unsigned char dwarf_line_opcodes[] = {
307 0 ,1 ,1 ,1 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,1
310 /* ------------------------------------------------------------------------- */
311 /* debug state */
313 struct _tccdbg {
315 int last_line_num, new_file;
316 int section_sym;
318 int debug_next_type;
320 struct _debug_hash {
321 int debug_type;
322 Sym *type;
323 } *debug_hash;
325 struct _debug_anon_hash {
326 Sym *type;
327 int n_debug_type;
328 int *debug_type;
329 } *debug_anon_hash;
331 int n_debug_hash;
332 int n_debug_anon_hash;
334 struct _debug_info {
335 int start;
336 int end;
337 int n_sym;
338 struct debug_sym {
339 int type;
340 unsigned long value;
341 char *str;
342 Section *sec;
343 int sym_index;
344 int info;
345 int file;
346 int line;
347 } *sym;
348 struct _debug_info *child, *next, *last, *parent;
349 } *debug_info, *debug_info_root;
351 struct {
352 int info;
353 int abbrev;
354 int line;
355 int str;
356 int line_str;
357 } dwarf_sym;
359 struct {
360 int start;
361 int dir_size;
362 char **dir_table;
363 int filename_size;
364 struct dwarf_filename_struct {
365 int dir_entry;
366 char *name;
367 } *filename_table;
368 int line_size;
369 int line_max_size;
370 unsigned char *line_data;
371 int cur_file;
372 int last_file;
373 int last_pc;
374 int last_line;
375 } dwarf_line;
377 struct {
378 int start;
379 Sym *func;
380 int line;
381 int base_type_used[N_DEFAULT_DEBUG];
382 } dwarf_info;
384 /* test coverage */
385 struct {
386 unsigned long offset;
387 unsigned long last_file_name;
388 unsigned long last_func_name;
389 int ind;
390 int line;
391 } tcov_data;
395 #define last_line_num s1->dState->last_line_num
396 #define new_file s1->dState->new_file
397 #define section_sym s1->dState->section_sym
398 #define debug_next_type s1->dState->debug_next_type
399 #define debug_hash s1->dState->debug_hash
400 #define debug_anon_hash s1->dState->debug_anon_hash
401 #define n_debug_hash s1->dState->n_debug_hash
402 #define n_debug_anon_hash s1->dState->n_debug_anon_hash
403 #define debug_info s1->dState->debug_info
404 #define debug_info_root s1->dState->debug_info_root
405 #define dwarf_sym s1->dState->dwarf_sym
406 #define dwarf_line s1->dState->dwarf_line
407 #define dwarf_info s1->dState->dwarf_info
408 #define tcov_data s1->dState->tcov_data
410 /* ------------------------------------------------------------------------- */
411 static void put_stabs(TCCState *s1, const char *str, int type, int other,
412 int desc, unsigned long value);
414 ST_FUNC void tcc_debug_new(TCCState *s1)
416 int shf = 0;
417 if (!s1->dState)
418 s1->dState = tcc_mallocz(sizeof *s1->dState);
419 #ifdef CONFIG_TCC_BACKTRACE
420 /* include stab info with standalone backtrace support */
421 if (s1->do_backtrace
422 && (s1->output_type & (TCC_OUTPUT_EXE | TCC_OUTPUT_DLL)))
423 shf = SHF_ALLOC | SHF_WRITE; // SHF_WRITE needed for musl/SELINUX
424 #endif
425 if (s1->dwarf) {
426 s1->dwlo = s1->nb_sections;
427 dwarf_info_section =
428 new_section(s1, ".debug_info", SHT_PROGBITS, shf);
429 dwarf_abbrev_section =
430 new_section(s1, ".debug_abbrev", SHT_PROGBITS, shf);
431 dwarf_line_section =
432 new_section(s1, ".debug_line", SHT_PROGBITS, shf);
433 dwarf_aranges_section =
434 new_section(s1, ".debug_aranges", SHT_PROGBITS, shf);
435 shf |= SHF_MERGE | SHF_STRINGS;
436 dwarf_str_section =
437 new_section(s1, ".debug_str", SHT_PROGBITS, shf);
438 dwarf_str_section->sh_entsize = 1;
439 dwarf_info_section->sh_addralign =
440 dwarf_abbrev_section->sh_addralign =
441 dwarf_line_section->sh_addralign =
442 dwarf_aranges_section->sh_addralign =
443 dwarf_str_section->sh_addralign = 1;
444 if (s1->dwarf >= 5) {
445 dwarf_line_str_section =
446 new_section(s1, ".debug_line_str", SHT_PROGBITS, shf);
447 dwarf_line_str_section->sh_entsize = 1;
448 dwarf_line_str_section->sh_addralign = 1;
450 s1->dwhi = s1->nb_sections;
452 else
454 stab_section = new_section(s1, ".stab", SHT_PROGBITS, shf);
455 stab_section->sh_entsize = sizeof(Stab_Sym);
456 stab_section->sh_addralign = sizeof ((Stab_Sym*)0)->n_value;
457 stab_section->link = new_section(s1, ".stabstr", SHT_STRTAB, shf);
458 /* put first entry */
459 put_stabs(s1, "", 0, 0, 0, 0);
463 /* put stab debug information */
464 static void put_stabs(TCCState *s1, const char *str, int type, int other, int desc,
465 unsigned long value)
467 Stab_Sym *sym;
469 unsigned offset;
470 if (type == N_SLINE
471 && (offset = stab_section->data_offset)
472 && (sym = (Stab_Sym*)(stab_section->data + offset) - 1)
473 && sym->n_type == type
474 && sym->n_value == value) {
475 /* just update line_number in previous entry */
476 sym->n_desc = desc;
477 return;
480 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
481 if (str) {
482 sym->n_strx = put_elf_str(stab_section->link, str);
483 } else {
484 sym->n_strx = 0;
486 sym->n_type = type;
487 sym->n_other = other;
488 sym->n_desc = desc;
489 sym->n_value = value;
492 static void put_stabs_r(TCCState *s1, const char *str, int type, int other, int desc,
493 unsigned long value, Section *sec, int sym_index)
495 put_elf_reloc(symtab_section, stab_section,
496 stab_section->data_offset + 8,
497 sizeof ((Stab_Sym*)0)->n_value == PTR_SIZE ? R_DATA_PTR : R_DATA_32,
498 sym_index);
499 put_stabs(s1, str, type, other, desc, value);
502 static void put_stabn(TCCState *s1, int type, int other, int desc, int value)
504 put_stabs(s1, NULL, type, other, desc, value);
507 /* ------------------------------------------------------------------------- */
508 #define dwarf_data1(s,data) \
509 { unsigned char *p = section_ptr_add((s), 1); *p = (data); }
510 #define dwarf_data2(s,data) \
511 write16le(section_ptr_add((s), 2), (data))
512 #define dwarf_data4(s,data) \
513 write32le(section_ptr_add((s), 4), (data))
514 #define dwarf_data8(s,data) \
515 write64le(section_ptr_add((s), 8), (data))
517 static int dwarf_get_section_sym(Section *s)
519 TCCState *s1 = s->s1;
520 return put_elf_sym(symtab_section, 0, 0,
521 ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
522 s->sh_num, NULL);
525 static void dwarf_reloc(Section *s, int sym, int rel)
527 TCCState *s1 = s->s1;
528 put_elf_reloca(symtab_section, s, s->data_offset, rel, sym, 0);
531 static void dwarf_string(Section *s, Section *dw, int sym, const char *str)
533 TCCState *s1 = s->s1;
534 int offset, len;
535 char *ptr;
537 len = strlen(str) + 1;
538 offset = dw->data_offset;
539 ptr = section_ptr_add(dw, len);
540 memmove(ptr, str, len);
541 put_elf_reloca(symtab_section, s, s->data_offset, R_DATA_32DW, sym,
542 PTR_SIZE == 4 ? 0 : offset);
543 dwarf_data4(s, PTR_SIZE == 4 ? offset : 0);
546 static void dwarf_strp(Section *s, const char *str)
548 TCCState *s1 = s->s1;
549 dwarf_string(s, dwarf_str_section, dwarf_sym.str, str);
552 static void dwarf_line_strp(Section *s, const char *str)
554 TCCState *s1 = s->s1;
555 dwarf_string(s, dwarf_line_str_section, dwarf_sym.line_str, str);
558 static void dwarf_line_op(TCCState *s1, unsigned char op)
560 if (dwarf_line.line_size >= dwarf_line.line_max_size) {
561 dwarf_line.line_max_size += 1024;
562 dwarf_line.line_data =
563 (unsigned char *)tcc_realloc(dwarf_line.line_data,
564 dwarf_line.line_max_size);
566 dwarf_line.line_data[dwarf_line.line_size++] = op;
569 static void dwarf_file(TCCState *s1)
571 int i, j;
572 char *filename;
573 int index_offset = s1->dwarf < 5;
575 if (!strcmp(file->filename, "<command line>")) {
576 dwarf_line.cur_file = 1;
577 return;
579 filename = strrchr(file->filename, '/');
580 if (filename == NULL) {
581 for (i = 1; i < dwarf_line.filename_size; i++)
582 if (dwarf_line.filename_table[i].dir_entry == 0 &&
583 strcmp(dwarf_line.filename_table[i].name,
584 file->filename) == 0) {
585 dwarf_line.cur_file = i + index_offset;
586 return;
588 i = -index_offset;
589 filename = file->filename;
591 else {
592 char *undo = filename;
593 char *dir = file->filename;
595 *filename++ = '\0';
596 for (i = 0; i < dwarf_line.dir_size; i++)
597 if (strcmp(dwarf_line.dir_table[i], dir) == 0) {
598 for (j = 1; j < dwarf_line.filename_size; j++)
599 if (dwarf_line.filename_table[j].dir_entry - index_offset
600 == i &&
601 strcmp(dwarf_line.filename_table[j].name,
602 filename) == 0) {
603 *undo = '/';
604 dwarf_line.cur_file = j + index_offset;
605 return;
607 break;
609 if (i == dwarf_line.dir_size) {
610 dwarf_line.dir_size++;
611 dwarf_line.dir_table =
612 (char **) tcc_realloc(dwarf_line.dir_table,
613 dwarf_line.dir_size *
614 sizeof (char *));
615 dwarf_line.dir_table[i] = tcc_strdup(dir);
617 *undo = '/';
619 dwarf_line.filename_table =
620 (struct dwarf_filename_struct *)
621 tcc_realloc(dwarf_line.filename_table,
622 (dwarf_line.filename_size + 1) *
623 sizeof (struct dwarf_filename_struct));
624 dwarf_line.filename_table[dwarf_line.filename_size].dir_entry =
625 i + index_offset;
626 dwarf_line.filename_table[dwarf_line.filename_size].name =
627 tcc_strdup(filename);
628 dwarf_line.cur_file = dwarf_line.filename_size++ + index_offset;
629 return;
632 #if 0
633 static int dwarf_uleb128_size (unsigned long long value)
635 int size = 0;
637 do {
638 value >>= 7;
639 size++;
640 } while (value != 0);
641 return size;
643 #endif
645 static int dwarf_sleb128_size (long long value)
647 int size = 0;
648 long long end = value >> 63;
649 unsigned char last = end & 0x40;
650 unsigned char byte;
652 do {
653 byte = value & 0x7f;
654 value >>= 7;
655 size++;
656 } while (value != end || (byte & 0x40) != last);
657 return size;
660 static void dwarf_uleb128 (Section *s, unsigned long long value)
662 do {
663 unsigned char byte = value & 0x7f;
665 value >>= 7;
666 dwarf_data1(s, byte | (value ? 0x80 : 0));
667 } while (value != 0);
670 static void dwarf_sleb128 (Section *s, long long value)
672 int more;
673 long long end = value >> 63;
674 unsigned char last = end & 0x40;
676 do {
677 unsigned char byte = value & 0x7f;
679 value >>= 7;
680 more = value != end || (byte & 0x40) != last;
681 dwarf_data1(s, byte | (0x80 * more));
682 } while (more);
685 static void dwarf_uleb128_op (TCCState *s1, unsigned long long value)
687 do {
688 unsigned char byte = value & 0x7f;
690 value >>= 7;
691 dwarf_line_op(s1, byte | (value ? 0x80 : 0));
692 } while (value != 0);
695 static void dwarf_sleb128_op (TCCState *s1, long long value)
697 int more;
698 long long end = value >> 63;
699 unsigned char last = end & 0x40;
701 do {
702 unsigned char byte = value & 0x7f;
704 value >>= 7;
705 more = value != end || (byte & 0x40) != last;
706 dwarf_line_op(s1, byte | (0x80 * more));
707 } while (more);
710 /* start of translation unit info */
711 ST_FUNC void tcc_debug_start(TCCState *s1)
713 int i;
714 char buf[512];
715 char *filename;
717 /* we might currently #include the <command-line> */
718 filename = file->prev ? file->prev->filename : file->filename;
720 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
721 symbols can be safely used */
722 put_elf_sym(symtab_section, 0, 0,
723 ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
724 SHN_ABS, filename);
726 if (s1->do_debug) {
728 new_file = last_line_num = 0;
729 debug_next_type = N_DEFAULT_DEBUG;
730 debug_hash = NULL;
731 debug_anon_hash = NULL;
732 n_debug_hash = 0;
733 n_debug_anon_hash = 0;
735 getcwd(buf, sizeof(buf));
736 #ifdef _WIN32
737 normalize_slashes(buf);
738 #endif
740 if (s1->dwarf) {
741 int start_abbrev;
742 unsigned char *ptr;
743 char *undo;
745 /* dwarf_abbrev */
746 start_abbrev = dwarf_abbrev_section->data_offset;
747 ptr = section_ptr_add(dwarf_abbrev_section, sizeof(dwarf_abbrev_init));
748 memcpy(ptr, dwarf_abbrev_init, sizeof(dwarf_abbrev_init));
750 if (s1->dwarf < 5) {
751 while (*ptr) {
752 ptr += 3;
753 while (*ptr) {
754 if (ptr[1] == DW_FORM_line_strp)
755 ptr[1] = DW_FORM_strp;
756 if (s1->dwarf < 4) {
757 /* These are compatable for DW_TAG_compile_unit
758 DW_AT_stmt_list. */
759 if (ptr[1] == DW_FORM_sec_offset)
760 ptr[1] = DW_FORM_data4;
761 /* This code uses only size < 0x80 so these are
762 compatible. */
763 if (ptr[1] == DW_FORM_exprloc)
764 ptr[1] = DW_FORM_block1;
766 ptr += 2;
768 ptr += 2;
772 dwarf_sym.info = dwarf_get_section_sym(dwarf_info_section);
773 dwarf_sym.abbrev = dwarf_get_section_sym(dwarf_abbrev_section);
774 dwarf_sym.line = dwarf_get_section_sym(dwarf_line_section);
775 dwarf_sym.str = dwarf_get_section_sym(dwarf_str_section);
776 if (tcc_state->dwarf >= 5)
777 dwarf_sym.line_str = dwarf_get_section_sym(dwarf_line_str_section);
778 else {
779 dwarf_line_str_section = dwarf_str_section;
780 dwarf_sym.line_str = dwarf_sym.str;
782 section_sym = dwarf_get_section_sym(text_section);
784 /* dwarf_info */
785 dwarf_info.start = dwarf_info_section->data_offset;
786 dwarf_data4(dwarf_info_section, 0); // size
787 dwarf_data2(dwarf_info_section, s1->dwarf); // version
788 if (s1->dwarf >= 5) {
789 dwarf_data1(dwarf_info_section, DW_UT_compile); // unit type
790 dwarf_data1(dwarf_info_section, PTR_SIZE);
791 dwarf_reloc(dwarf_info_section, dwarf_sym.abbrev, R_DATA_32DW);
792 dwarf_data4(dwarf_info_section, start_abbrev);
794 else {
795 dwarf_reloc(dwarf_info_section, dwarf_sym.abbrev, R_DATA_32DW);
796 dwarf_data4(dwarf_info_section, start_abbrev);
797 dwarf_data1(dwarf_info_section, PTR_SIZE);
800 dwarf_data1(dwarf_info_section, DWARF_ABBREV_COMPILE_UNIT);
801 dwarf_strp(dwarf_info_section, "tcc " TCC_VERSION);
802 dwarf_data1(dwarf_info_section, DW_LANG_C11);
803 dwarf_line_strp(dwarf_info_section, filename);
804 dwarf_line_strp(dwarf_info_section, buf);
805 dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR);
806 #if PTR_SIZE == 4
807 dwarf_data4(dwarf_info_section, ind); // low pc
808 dwarf_data4(dwarf_info_section, 0); // high pc
809 #else
810 dwarf_data8(dwarf_info_section, ind); // low pc
811 dwarf_data8(dwarf_info_section, 0); // high pc
812 #endif
813 dwarf_reloc(dwarf_info_section, dwarf_sym.line, R_DATA_32DW);
814 dwarf_data4(dwarf_info_section, dwarf_line_section->data_offset); // stmt_list
816 /* dwarf_line */
817 dwarf_line.start = dwarf_line_section->data_offset;
818 dwarf_data4(dwarf_line_section, 0); // length
819 dwarf_data2(dwarf_line_section, s1->dwarf); // version
820 if (s1->dwarf >= 5) {
821 dwarf_data1(dwarf_line_section, PTR_SIZE); // address size
822 dwarf_data1(dwarf_line_section, 0); // segment selector
824 dwarf_data4(dwarf_line_section, 0); // prologue Length
825 dwarf_data1(dwarf_line_section, DWARF_MIN_INSTR_LEN);
826 if (s1->dwarf >= 4)
827 dwarf_data1(dwarf_line_section, 1); // maximum ops per instruction
828 dwarf_data1(dwarf_line_section, 1); // Initial value of 'is_stmt'
829 dwarf_data1(dwarf_line_section, DWARF_LINE_BASE);
830 dwarf_data1(dwarf_line_section, DWARF_LINE_RANGE);
831 dwarf_data1(dwarf_line_section, DWARF_OPCODE_BASE);
832 ptr = section_ptr_add(dwarf_line_section, sizeof(dwarf_line_opcodes));
833 memcpy(ptr, dwarf_line_opcodes, sizeof(dwarf_line_opcodes));
834 undo = strrchr(filename, '/');
835 if (undo)
836 *undo = 0;
837 dwarf_line.dir_size = 1 + (undo != NULL);
838 dwarf_line.dir_table = (char **) tcc_malloc(sizeof (char *) *
839 dwarf_line.dir_size);
840 dwarf_line.dir_table[0] = tcc_strdup(buf);
841 if (undo)
842 dwarf_line.dir_table[1] = tcc_strdup(filename);
843 dwarf_line.filename_size = 2;
844 dwarf_line.filename_table =
845 (struct dwarf_filename_struct *)
846 tcc_malloc(2*sizeof (struct dwarf_filename_struct));
847 dwarf_line.filename_table[0].dir_entry = 0;
848 if (undo) {
849 dwarf_line.filename_table[0].name = tcc_strdup(undo + 1);
850 dwarf_line.filename_table[1].dir_entry = 1;
851 dwarf_line.filename_table[1].name = tcc_strdup(undo + 1);
852 *undo = '/';
854 else {
855 dwarf_line.filename_table[0].name = tcc_strdup(filename);
856 dwarf_line.filename_table[1].dir_entry = 0;
857 dwarf_line.filename_table[1].name = tcc_strdup(filename);
859 dwarf_line.line_size = dwarf_line.line_max_size = 0;
860 dwarf_line.line_data = NULL;
861 dwarf_line.cur_file = 1;
862 dwarf_line.last_file = 0;
863 dwarf_line.last_pc = 0;
864 dwarf_line.last_line = 1;
865 dwarf_line_op(s1, 0); // extended
866 dwarf_uleb128_op(s1, 1 + PTR_SIZE); // extended size
867 dwarf_line_op(s1, DW_LNE_set_address);
868 for (i = 0; i < PTR_SIZE; i++)
869 dwarf_line_op(s1, 0);
870 memset(&dwarf_info.base_type_used, 0, sizeof(dwarf_info.base_type_used));
872 else
874 /* file info: full path + filename */
875 pstrcat(buf, sizeof(buf), "/");
876 section_sym = put_elf_sym(symtab_section, 0, 0,
877 ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
878 text_section->sh_num, NULL);
879 put_stabs_r(s1, buf, N_SO, 0, 0,
880 text_section->data_offset, text_section, section_sym);
881 put_stabs_r(s1, filename, N_SO, 0, 0,
882 text_section->data_offset, text_section, section_sym);
883 for (i = 0; i < N_DEFAULT_DEBUG; i++)
884 put_stabs(s1, default_debug[i].name, N_LSYM, 0, 0, 0);
886 /* we're currently 'including' the <command line> */
887 tcc_debug_bincl(s1);
891 /* put end of translation unit info */
892 ST_FUNC void tcc_debug_end(TCCState *s1)
894 if (!s1->do_debug || debug_next_type == 0)
895 return;
897 if (debug_info_root)
898 tcc_debug_funcend(s1, 0); /* free stuff in case of errors */
900 if (s1->dwarf) {
901 int i, j;
902 int start_aranges;
903 unsigned char *ptr;
904 int text_size = text_section->data_offset;
906 /* dwarf_info */
907 for (i = 0; i < n_debug_anon_hash; i++) {
908 Sym *t = debug_anon_hash[i].type;
909 int pos = dwarf_info_section->data_offset;
911 dwarf_data1(dwarf_info_section,
912 IS_UNION (t->type.t) ? DWARF_ABBREV_UNION_EMPTY_TYPE
913 : DWARF_ABBREV_STRUCTURE_EMPTY_TYPE);
914 dwarf_strp(dwarf_info_section,
915 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
916 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL));
917 dwarf_uleb128(dwarf_info_section, 0);
918 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
919 dwarf_uleb128(dwarf_info_section, file->line_num);
920 for (j = 0; j < debug_anon_hash[i].n_debug_type; j++)
921 write32le(dwarf_info_section->data +
922 debug_anon_hash[i].debug_type[j],
923 pos - dwarf_info.start);
924 tcc_free (debug_anon_hash[i].debug_type);
926 tcc_free (debug_anon_hash);
927 dwarf_data1(dwarf_info_section, 0);
928 ptr = dwarf_info_section->data + dwarf_info.start;
929 write32le(ptr, dwarf_info_section->data_offset - dwarf_info.start - 4);
930 write32le(ptr + 25 + (s1->dwarf >= 5) + PTR_SIZE, text_size);
932 /* dwarf_aranges */
933 start_aranges = dwarf_aranges_section->data_offset;
934 dwarf_data4(dwarf_aranges_section, 0); // size
935 dwarf_data2(dwarf_aranges_section, 2); // version
936 dwarf_reloc(dwarf_aranges_section, dwarf_sym.info, R_DATA_32DW);
937 dwarf_data4(dwarf_aranges_section, 0); // dwarf_info
938 #if PTR_SIZE == 4
939 dwarf_data1(dwarf_aranges_section, 4); // address size
940 #else
941 dwarf_data1(dwarf_aranges_section, 8); // address size
942 #endif
943 dwarf_data1(dwarf_aranges_section, 0); // segment selector size
944 dwarf_data4(dwarf_aranges_section, 0); // padding
945 dwarf_reloc(dwarf_aranges_section, section_sym, R_DATA_PTR);
946 #if PTR_SIZE == 4
947 dwarf_data4(dwarf_aranges_section, 0); // Begin
948 dwarf_data4(dwarf_aranges_section, text_size); // End
949 dwarf_data4(dwarf_aranges_section, 0); // End list
950 dwarf_data4(dwarf_aranges_section, 0); // End list
951 #else
952 dwarf_data8(dwarf_aranges_section, 0); // Begin
953 dwarf_data8(dwarf_aranges_section, text_size); // End
954 dwarf_data8(dwarf_aranges_section, 0); // End list
955 dwarf_data8(dwarf_aranges_section, 0); // End list
956 #endif
957 ptr = dwarf_aranges_section->data + start_aranges;
958 write32le(ptr, dwarf_aranges_section->data_offset - start_aranges - 4);
960 /* dwarf_line */
961 if (s1->dwarf >= 5) {
962 dwarf_data1(dwarf_line_section, 1); /* col */
963 dwarf_uleb128(dwarf_line_section, DW_LNCT_path);
964 dwarf_uleb128(dwarf_line_section, DW_FORM_line_strp);
965 dwarf_uleb128(dwarf_line_section, dwarf_line.dir_size);
966 for (i = 0; i < dwarf_line.dir_size; i++)
967 dwarf_line_strp(dwarf_line_section, dwarf_line.dir_table[i]);
968 dwarf_data1(dwarf_line_section, 2); /* col */
969 dwarf_uleb128(dwarf_line_section, DW_LNCT_path);
970 dwarf_uleb128(dwarf_line_section, DW_FORM_line_strp);
971 dwarf_uleb128(dwarf_line_section, DW_LNCT_directory_index);
972 dwarf_uleb128(dwarf_line_section, DW_FORM_udata);
973 dwarf_uleb128(dwarf_line_section, dwarf_line.filename_size);
974 for (i = 0; i < dwarf_line.filename_size; i++) {
975 dwarf_line_strp(dwarf_line_section,
976 dwarf_line.filename_table[i].name);
977 dwarf_uleb128(dwarf_line_section,
978 dwarf_line.filename_table[i].dir_entry);
981 else {
982 int len;
984 for (i = 0; i < dwarf_line.dir_size; i++) {
985 len = strlen(dwarf_line.dir_table[i]) + 1;
986 ptr = section_ptr_add(dwarf_line_section, len);
987 memmove(ptr, dwarf_line.dir_table[i], len);
989 dwarf_data1(dwarf_line_section, 0); /* end dir */
990 for (i = 0; i < dwarf_line.filename_size; i++) {
991 len = strlen(dwarf_line.filename_table[i].name) + 1;
992 ptr = section_ptr_add(dwarf_line_section, len);
993 memmove(ptr, dwarf_line.filename_table[i].name, len);
994 dwarf_uleb128(dwarf_line_section,
995 dwarf_line.filename_table[i].dir_entry);
996 dwarf_uleb128(dwarf_line_section, 0); /* time */
997 dwarf_uleb128(dwarf_line_section, 0); /* size */
999 dwarf_data1(dwarf_line_section, 0); /* end file */
1001 for (i = 0; i < dwarf_line.dir_size; i++)
1002 tcc_free(dwarf_line.dir_table[i]);
1003 tcc_free(dwarf_line.dir_table);
1004 for (i = 0; i < dwarf_line.filename_size; i++)
1005 tcc_free(dwarf_line.filename_table[i].name);
1006 tcc_free(dwarf_line.filename_table);
1008 dwarf_line_op(s1, 0); // extended
1009 dwarf_uleb128_op(s1, 1); // extended size
1010 dwarf_line_op(s1, DW_LNE_end_sequence);
1011 i = (s1->dwarf >= 5) * 2;
1012 write32le(&dwarf_line_section->data[dwarf_line.start + 6 + i],
1013 dwarf_line_section->data_offset - dwarf_line.start - (10 + i));
1014 section_ptr_add(dwarf_line_section, 3);
1015 dwarf_reloc(dwarf_line_section, section_sym, R_DATA_PTR);
1016 ptr = section_ptr_add(dwarf_line_section, dwarf_line.line_size - 3);
1017 memmove(ptr - 3, dwarf_line.line_data, dwarf_line.line_size);
1018 tcc_free(dwarf_line.line_data);
1019 write32le(dwarf_line_section->data + dwarf_line.start,
1020 dwarf_line_section->data_offset - dwarf_line.start - 4);
1022 else
1024 put_stabs_r(s1, NULL, N_SO, 0, 0,
1025 text_section->data_offset, text_section, section_sym);
1027 tcc_free(debug_hash);
1028 debug_next_type = 0;
1031 static BufferedFile* put_new_file(TCCState *s1)
1033 BufferedFile *f = file;
1034 /* use upper file if from inline ":asm:" */
1035 if (f->filename[0] == ':')
1036 f = f->prev;
1037 if (f && new_file) {
1038 new_file = last_line_num = 0;
1039 if (s1->dwarf)
1040 dwarf_file(s1);
1041 else
1042 put_stabs_r(s1, f->filename, N_SOL, 0, 0, ind, text_section, section_sym);
1044 return f;
1047 /* put alternative filename */
1048 ST_FUNC void tcc_debug_putfile(TCCState *s1, const char *filename)
1050 if (0 == strcmp(file->filename, filename))
1051 return;
1052 pstrcpy(file->filename, sizeof(file->filename), filename);
1053 if (!s1->do_debug)
1054 return;
1055 if (s1->dwarf)
1056 dwarf_file(s1);
1057 new_file = 1;
1060 /* begin of #include */
1061 ST_FUNC void tcc_debug_bincl(TCCState *s1)
1063 if (!s1->do_debug)
1064 return;
1065 if (s1->dwarf)
1066 dwarf_file(s1);
1067 else
1068 put_stabs(s1, file->filename, N_BINCL, 0, 0, 0);
1069 new_file = 1;
1072 /* end of #include */
1073 ST_FUNC void tcc_debug_eincl(TCCState *s1)
1075 if (!s1->do_debug)
1076 return;
1077 if (s1->dwarf)
1078 dwarf_file(s1);
1079 else
1080 put_stabn(s1, N_EINCL, 0, 0, 0);
1081 new_file = 1;
1084 /* generate line number info */
1085 ST_FUNC void tcc_debug_line(TCCState *s1)
1087 BufferedFile *f;
1089 if (!s1->do_debug)
1090 return;
1091 if (cur_text_section != text_section || nocode_wanted)
1092 return;
1093 f = put_new_file(s1);
1094 if (!f)
1095 return;
1096 if (last_line_num == f->line_num)
1097 return;
1098 last_line_num = f->line_num;
1100 if (s1->dwarf) {
1101 int len_pc = (ind - dwarf_line.last_pc) / DWARF_MIN_INSTR_LEN;
1102 int len_line = f->line_num - dwarf_line.last_line;
1103 int n = len_pc * DWARF_LINE_RANGE + len_line + DWARF_OPCODE_BASE - DWARF_LINE_BASE;
1105 if (dwarf_line.cur_file != dwarf_line.last_file) {
1106 dwarf_line.last_file = dwarf_line.cur_file;
1107 dwarf_line_op(s1, DW_LNS_set_file);
1108 dwarf_uleb128_op(s1, dwarf_line.cur_file);
1110 if (len_pc &&
1111 len_line >= DWARF_LINE_BASE && len_line <= (DWARF_OPCODE_BASE + DWARF_LINE_BASE) &&
1112 n >= DWARF_OPCODE_BASE && n <= 255)
1113 dwarf_line_op(s1, n);
1114 else {
1115 if (len_pc) {
1116 n = len_pc * DWARF_LINE_RANGE + 0 + DWARF_OPCODE_BASE - DWARF_LINE_BASE;
1117 if (n >= DWARF_OPCODE_BASE && n <= 255)
1118 dwarf_line_op(s1, n);
1119 else {
1120 dwarf_line_op(s1, DW_LNS_advance_pc);
1121 dwarf_uleb128_op(s1, len_pc);
1124 if (len_line) {
1125 n = 0 * DWARF_LINE_RANGE + len_line + DWARF_OPCODE_BASE - DWARF_LINE_BASE;
1126 if (len_line >= DWARF_LINE_BASE && len_line <= (DWARF_OPCODE_BASE + DWARF_LINE_BASE) &&
1127 n >= DWARF_OPCODE_BASE && n <= 255)
1128 dwarf_line_op(s1, n);
1129 else {
1130 dwarf_line_op(s1, DW_LNS_advance_line);
1131 dwarf_sleb128_op(s1, len_line);
1135 dwarf_line.last_pc = ind;
1136 dwarf_line.last_line = f->line_num;
1138 else
1140 if (func_ind != -1) {
1141 put_stabn(s1, N_SLINE, 0, f->line_num, ind - func_ind);
1142 } else {
1143 /* from tcc_assemble */
1144 put_stabs_r(s1, NULL, N_SLINE, 0, f->line_num, ind, text_section, section_sym);
1149 static void tcc_debug_stabs (TCCState *s1, const char *str, int type, unsigned long value,
1150 Section *sec, int sym_index, int info)
1152 struct debug_sym *s;
1154 if (debug_info) {
1155 debug_info->sym =
1156 (struct debug_sym *)tcc_realloc (debug_info->sym,
1157 sizeof(struct debug_sym) *
1158 (debug_info->n_sym + 1));
1159 s = debug_info->sym + debug_info->n_sym++;
1160 s->type = type;
1161 s->value = value;
1162 s->str = tcc_strdup(str);
1163 s->sec = sec;
1164 s->sym_index = sym_index;
1165 s->info = info;
1166 s->file = dwarf_line.cur_file;
1167 s->line = file->line_num;
1169 else if (sec)
1170 put_stabs_r (s1, str, type, 0, 0, value, sec, sym_index);
1171 else
1172 put_stabs (s1, str, type, 0, 0, value);
1175 ST_FUNC void tcc_debug_stabn(TCCState *s1, int type, int value)
1177 if (!s1->do_debug)
1178 return;
1179 if (type == N_LBRAC) {
1180 struct _debug_info *info =
1181 (struct _debug_info *) tcc_mallocz(sizeof (*info));
1183 info->start = value;
1184 info->parent = debug_info;
1185 if (debug_info) {
1186 if (debug_info->child) {
1187 if (debug_info->child->last)
1188 debug_info->child->last->next = info;
1189 else
1190 debug_info->child->next = info;
1191 debug_info->child->last = info;
1193 else
1194 debug_info->child = info;
1196 else
1197 debug_info_root = info;
1198 debug_info = info;
1200 else {
1201 debug_info->end = value;
1202 debug_info = debug_info->parent;
1206 static int tcc_debug_find(TCCState *s1, Sym *t, int dwarf)
1208 int i;
1210 if (!debug_info && dwarf &&
1211 (t->type.t & VT_BTYPE) == VT_STRUCT && t->c == -1) {
1212 for (i = 0; i < n_debug_anon_hash; i++)
1213 if (t == debug_anon_hash[i].type)
1214 return 0;
1215 debug_anon_hash = (struct _debug_anon_hash *)
1216 tcc_realloc (debug_anon_hash,
1217 (n_debug_anon_hash + 1) * sizeof(*debug_anon_hash));
1218 debug_anon_hash[n_debug_anon_hash].n_debug_type = 0;
1219 debug_anon_hash[n_debug_anon_hash].debug_type = NULL;
1220 debug_anon_hash[n_debug_anon_hash++].type = t;
1221 return 0;
1223 for (i = 0; i < n_debug_hash; i++)
1224 if (t == debug_hash[i].type)
1225 return debug_hash[i].debug_type;
1226 return -1;
1229 static int tcc_get_dwarf_info(TCCState *s1, Sym *s);
1231 static void tcc_debug_check_anon(TCCState *s1, Sym *t, int debug_type)
1233 int i;
1235 if (!debug_info && (t->type.t & VT_BTYPE) == VT_STRUCT && t->type.ref->c == -1)
1236 for (i = 0; i < n_debug_anon_hash; i++)
1237 if (t->type.ref == debug_anon_hash[i].type) {
1238 debug_anon_hash[i].debug_type =
1239 tcc_realloc(debug_anon_hash[i].debug_type,
1240 (debug_anon_hash[i].n_debug_type + 1) * sizeof(int));
1241 debug_anon_hash[i].debug_type[debug_anon_hash[i].n_debug_type++] =
1242 debug_type;
1246 ST_FUNC void tcc_debug_fix_anon(TCCState *s1, CType *t)
1248 int i, j, debug_type;
1250 if (!(s1->do_debug & 2) || !s1->dwarf || debug_info)
1251 return;
1253 if ((t->t & VT_BTYPE) == VT_STRUCT && t->ref->c != -1)
1254 for (i = 0; i < n_debug_anon_hash; i++)
1255 if (t->ref == debug_anon_hash[i].type) {
1256 Sym sym = {0}; sym .type = *t ;
1258 /* Trick to not hash this struct */
1259 debug_info = (struct _debug_info *) t;
1260 debug_type = tcc_get_dwarf_info(s1, &sym);
1261 debug_info = NULL;
1262 for (j = 0; j < debug_anon_hash[i].n_debug_type; j++)
1263 write32le(dwarf_info_section->data +
1264 debug_anon_hash[i].debug_type[j],
1265 debug_type - dwarf_info.start);
1266 tcc_free(debug_anon_hash[i].debug_type);
1267 n_debug_anon_hash--;
1268 for (; i < n_debug_anon_hash; i++)
1269 debug_anon_hash[i] = debug_anon_hash[i + 1];
1273 static int tcc_debug_add(TCCState *s1, Sym *t, int dwarf)
1275 int offset = dwarf ? dwarf_info_section->data_offset : ++debug_next_type;
1276 debug_hash = (struct _debug_hash *)
1277 tcc_realloc (debug_hash,
1278 (n_debug_hash + 1) * sizeof(*debug_hash));
1279 debug_hash[n_debug_hash].debug_type = offset;
1280 debug_hash[n_debug_hash++].type = t;
1281 return offset;
1284 static void tcc_debug_remove(TCCState *s1, Sym *t)
1286 int i;
1288 for (i = 0; i < n_debug_hash; i++)
1289 if (t == debug_hash[i].type) {
1290 n_debug_hash--;
1291 for (; i < n_debug_hash; i++)
1292 debug_hash[i] = debug_hash[i+1];
1296 #define STRUCT_NODEBUG(s) \
1297 (s->a.nodebug || \
1298 ((s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM && \
1299 ((s->type.t & VT_BTYPE) == VT_BYTE || \
1300 (s->type.t & VT_BTYPE) == VT_BOOL || \
1301 (s->type.t & VT_BTYPE) == VT_SHORT || \
1302 (s->type.t & VT_BTYPE) == VT_INT || \
1303 (s->type.t & VT_BTYPE) == VT_LLONG)))
1305 static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result)
1307 int type;
1308 int n = 0;
1309 int debug_type = -1;
1310 Sym *t = s;
1311 CString str;
1313 for (;;) {
1314 type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE | VT_VLA);
1315 if ((type & VT_BTYPE) != VT_BYTE)
1316 type &= ~VT_DEFSIGN;
1317 if (type == VT_PTR || type == (VT_PTR | VT_ARRAY))
1318 n++, t = t->type.ref;
1319 else
1320 break;
1322 if ((type & VT_BTYPE) == VT_STRUCT) {
1323 Sym *e = t;
1325 t = t->type.ref;
1326 debug_type = tcc_debug_find(s1, t, 0);
1327 if (debug_type == -1) {
1328 debug_type = tcc_debug_add(s1, t, 0);
1329 cstr_new (&str);
1330 cstr_printf (&str, "%s:T%d=%c%d",
1331 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
1332 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL),
1333 debug_type,
1334 IS_UNION (t->type.t) ? 'u' : 's',
1335 t->c);
1336 while (t->next) {
1337 int pos, size, align;
1339 t = t->next;
1340 if (STRUCT_NODEBUG(t))
1341 continue;
1342 cstr_printf (&str, "%s:",
1343 get_tok_str(t->v & ~SYM_FIELD, NULL));
1344 tcc_get_debug_info (s1, t, &str);
1345 if (t->type.t & VT_BITFIELD) {
1346 pos = t->c * 8 + BIT_POS(t->type.t);
1347 size = BIT_SIZE(t->type.t);
1349 else {
1350 pos = t->c * 8;
1351 size = type_size(&t->type, &align) * 8;
1353 cstr_printf (&str, ",%d,%d;", pos, size);
1355 cstr_printf (&str, ";");
1356 tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0);
1357 cstr_free (&str);
1358 if (debug_info)
1359 tcc_debug_remove(s1, e);
1362 else if (IS_ENUM(type)) {
1363 Sym *e = t = t->type.ref;
1365 debug_type = tcc_debug_find(s1, t, 0);
1366 if (debug_type == -1) {
1367 debug_type = tcc_debug_add(s1, t, 0);
1368 cstr_new (&str);
1369 cstr_printf (&str, "%s:T%d=e",
1370 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
1371 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL),
1372 debug_type);
1373 while (t->next) {
1374 t = t->next;
1375 cstr_printf (&str, "%s:",
1376 (t->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
1377 ? "" : get_tok_str(t->v & ~SYM_FIELD, NULL));
1378 cstr_printf (&str, e->type.t & VT_UNSIGNED ? "%u," : "%d,",
1379 (int)t->enum_val);
1381 cstr_printf (&str, ";");
1382 tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0);
1383 cstr_free (&str);
1384 if (debug_info)
1385 tcc_debug_remove(s1, e);
1388 else if ((type & VT_BTYPE) != VT_FUNC) {
1389 type &= ~VT_STRUCT_MASK;
1390 for (debug_type = 1; debug_type <= N_DEFAULT_DEBUG; debug_type++)
1391 if (default_debug[debug_type - 1].type == type)
1392 break;
1393 if (debug_type > N_DEFAULT_DEBUG)
1394 return;
1396 if (n > 0)
1397 cstr_printf (result, "%d=", ++debug_next_type);
1398 t = s;
1399 for (;;) {
1400 type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE | VT_VLA);
1401 if ((type & VT_BTYPE) != VT_BYTE)
1402 type &= ~VT_DEFSIGN;
1403 if (type == VT_PTR)
1404 cstr_printf (result, "%d=*", ++debug_next_type);
1405 else if (type == (VT_PTR | VT_ARRAY))
1406 cstr_printf (result, "%d=ar1;0;%d;",
1407 ++debug_next_type, t->type.ref->c - 1);
1408 else if (type == VT_FUNC) {
1409 cstr_printf (result, "%d=f", ++debug_next_type);
1410 tcc_get_debug_info (s1, t->type.ref, result);
1411 return;
1413 else
1414 break;
1415 t = t->type.ref;
1417 cstr_printf (result, "%d", debug_type);
1420 static int tcc_get_dwarf_info(TCCState *s1, Sym *s)
1422 int type;
1423 int debug_type = -1;
1424 Sym *e, *t = s;
1425 int i;
1426 int last_pos = -1;
1427 int retval;
1429 if (new_file)
1430 put_new_file(s1);
1431 for (;;) {
1432 type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE | VT_VLA);
1433 if ((type & VT_BTYPE) != VT_BYTE)
1434 type &= ~VT_DEFSIGN;
1435 if (type == VT_PTR || type == (VT_PTR | VT_ARRAY))
1436 t = t->type.ref;
1437 else
1438 break;
1440 if ((type & VT_BTYPE) == VT_STRUCT) {
1441 t = t->type.ref;
1442 debug_type = tcc_debug_find(s1, t, 1);
1443 if (debug_type == -1) {
1444 int pos_sib = 0, i, *pos_type;
1446 debug_type = tcc_debug_add(s1, t, 1);
1447 e = t;
1448 i = 0;
1449 while (e->next) {
1450 e = e->next;
1451 if (STRUCT_NODEBUG(e))
1452 continue;
1453 i++;
1455 pos_type = (int *) tcc_malloc(i * sizeof(int));
1456 dwarf_data1(dwarf_info_section,
1457 IS_UNION (t->type.t)
1458 ? t->next ? DWARF_ABBREV_UNION_TYPE
1459 : DWARF_ABBREV_UNION_EMPTY_TYPE
1460 : t->next ? DWARF_ABBREV_STRUCTURE_TYPE
1461 : DWARF_ABBREV_STRUCTURE_EMPTY_TYPE);
1462 dwarf_strp(dwarf_info_section,
1463 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
1464 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL));
1465 dwarf_uleb128(dwarf_info_section, t->c);
1466 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
1467 dwarf_uleb128(dwarf_info_section, file->line_num);
1468 if (t->next) {
1469 pos_sib = dwarf_info_section->data_offset;
1470 dwarf_data4(dwarf_info_section, 0);
1472 e = t;
1473 i = 0;
1474 while (e->next) {
1475 e = e->next;
1476 if (STRUCT_NODEBUG(e))
1477 continue;
1478 dwarf_data1(dwarf_info_section,
1479 e->type.t & VT_BITFIELD ? DWARF_ABBREV_MEMBER_BF
1480 : DWARF_ABBREV_MEMBER);
1481 dwarf_strp(dwarf_info_section,
1482 get_tok_str(e->v & ~SYM_FIELD, NULL));
1483 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
1484 dwarf_uleb128(dwarf_info_section, file->line_num);
1485 pos_type[i++] = dwarf_info_section->data_offset;
1486 dwarf_data4(dwarf_info_section, 0);
1487 if (e->type.t & VT_BITFIELD) {
1488 int pos = e->c * 8 + BIT_POS(e->type.t);
1489 int size = BIT_SIZE(e->type.t);
1491 dwarf_uleb128(dwarf_info_section, size);
1492 dwarf_uleb128(dwarf_info_section, pos);
1494 else
1495 dwarf_uleb128(dwarf_info_section, e->c);
1497 if (t->next) {
1498 dwarf_data1(dwarf_info_section, 0);
1499 write32le(dwarf_info_section->data + pos_sib,
1500 dwarf_info_section->data_offset - dwarf_info.start);
1502 e = t;
1503 i = 0;
1504 while (e->next) {
1505 e = e->next;
1506 if (STRUCT_NODEBUG(e))
1507 continue;
1508 type = tcc_get_dwarf_info(s1, e);
1509 tcc_debug_check_anon(s1, e, pos_type[i]);
1510 write32le(dwarf_info_section->data + pos_type[i++],
1511 type - dwarf_info.start);
1513 tcc_free(pos_type);
1514 if (debug_info)
1515 tcc_debug_remove(s1, t);
1518 else if (IS_ENUM(type)) {
1519 t = t->type.ref;
1520 debug_type = tcc_debug_find(s1, t, 1);
1521 if (debug_type == -1) {
1522 int pos_sib, pos_type;
1523 Sym sym = {0}; sym.type.t = VT_INT | (type & VT_UNSIGNED);
1525 pos_type = tcc_get_dwarf_info(s1, &sym);
1526 debug_type = tcc_debug_add(s1, t, 1);
1527 dwarf_data1(dwarf_info_section, DWARF_ABBREV_ENUMERATION_TYPE);
1528 dwarf_strp(dwarf_info_section,
1529 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
1530 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL));
1531 dwarf_data1(dwarf_info_section,
1532 type & VT_UNSIGNED ? DW_ATE_unsigned : DW_ATE_signed );
1533 dwarf_data1(dwarf_info_section, 4);
1534 dwarf_data4(dwarf_info_section, pos_type - dwarf_info.start);
1535 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
1536 dwarf_uleb128(dwarf_info_section, file->line_num);
1537 pos_sib = dwarf_info_section->data_offset;
1538 dwarf_data4(dwarf_info_section, 0);
1539 e = t;
1540 while (e->next) {
1541 e = e->next;
1542 dwarf_data1(dwarf_info_section,
1543 type & VT_UNSIGNED ? DWARF_ABBREV_ENUMERATOR_UNSIGNED
1544 : DWARF_ABBREV_ENUMERATOR_SIGNED);
1545 dwarf_strp(dwarf_info_section,
1546 (e->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
1547 ? "" : get_tok_str(e->v & ~SYM_FIELD, NULL));
1548 if (type & VT_UNSIGNED)
1549 dwarf_uleb128(dwarf_info_section, e->enum_val);
1550 else
1551 dwarf_sleb128(dwarf_info_section, e->enum_val);
1553 dwarf_data1(dwarf_info_section, 0);
1554 write32le(dwarf_info_section->data + pos_sib,
1555 dwarf_info_section->data_offset - dwarf_info.start);
1556 if (debug_info)
1557 tcc_debug_remove(s1, t);
1560 else if ((type & VT_BTYPE) != VT_FUNC) {
1561 type &= ~VT_STRUCT_MASK;
1562 for (i = 1; i <= N_DEFAULT_DEBUG; i++)
1563 if (default_debug[i - 1].type == type)
1564 break;
1565 if (i > N_DEFAULT_DEBUG)
1566 return 0;
1567 debug_type = dwarf_info.base_type_used[i - 1];
1568 if (debug_type == 0) {
1569 char name[100];
1571 debug_type = dwarf_info_section->data_offset;
1572 dwarf_data1(dwarf_info_section, DWARF_ABBREV_BASE_TYPE);
1573 dwarf_uleb128(dwarf_info_section, default_debug[i - 1].size);
1574 dwarf_data1(dwarf_info_section, default_debug[i - 1].encoding);
1575 strncpy(name, default_debug[i - 1].name, sizeof(name) -1);
1576 *strchr(name, ':') = 0;
1577 dwarf_strp(dwarf_info_section, name);
1578 dwarf_info.base_type_used[i - 1] = debug_type;
1581 retval = debug_type;
1582 e = NULL;
1583 t = s;
1584 for (;;) {
1585 type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE | VT_VLA);
1586 if ((type & VT_BTYPE) != VT_BYTE)
1587 type &= ~VT_DEFSIGN;
1588 if (type == VT_PTR) {
1589 i = dwarf_info_section->data_offset;
1590 if (retval == debug_type)
1591 retval = i;
1592 dwarf_data1(dwarf_info_section, DWARF_ABBREV_POINTER);
1593 dwarf_data1(dwarf_info_section, PTR_SIZE);
1594 if (last_pos != -1) {
1595 tcc_debug_check_anon(s1, e, last_pos);
1596 write32le(dwarf_info_section->data + last_pos,
1597 i - dwarf_info.start);
1599 last_pos = dwarf_info_section->data_offset;
1600 e = t->type.ref;
1601 dwarf_data4(dwarf_info_section, 0);
1603 else if (type == (VT_PTR | VT_ARRAY)) {
1604 int sib_pos, sub_type;
1605 #if LONG_SIZE == 4
1606 Sym sym = {0}; sym.type.t = VT_LONG | VT_INT | VT_UNSIGNED;
1607 #else
1608 Sym sym = {0}; sym.type.t = VT_LLONG | VT_LONG | VT_UNSIGNED;
1609 #endif
1611 sub_type = tcc_get_dwarf_info(s1, &sym);
1612 i = dwarf_info_section->data_offset;
1613 if (retval == debug_type)
1614 retval = i;
1615 dwarf_data1(dwarf_info_section, DWARF_ABBREV_ARRAY_TYPE);
1616 if (last_pos != -1) {
1617 tcc_debug_check_anon(s1, e, last_pos);
1618 write32le(dwarf_info_section->data + last_pos,
1619 i - dwarf_info.start);
1621 last_pos = dwarf_info_section->data_offset;
1622 e = t->type.ref;
1623 dwarf_data4(dwarf_info_section, 0);
1624 sib_pos = dwarf_info_section->data_offset;
1625 dwarf_data4(dwarf_info_section, 0);
1626 for (;;) {
1627 dwarf_data1(dwarf_info_section, DWARF_ABBREV_SUBRANGE_TYPE);
1628 dwarf_data4(dwarf_info_section, sub_type - dwarf_info.start);
1629 dwarf_uleb128(dwarf_info_section, t->type.ref->c - 1);
1630 s = t->type.ref;
1631 type = s->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE);
1632 if (type != (VT_PTR | VT_ARRAY))
1633 break;
1634 t = s;
1636 dwarf_data1(dwarf_info_section, 0);
1637 write32le(dwarf_info_section->data + sib_pos,
1638 dwarf_info_section->data_offset - dwarf_info.start);
1640 else if (type == VT_FUNC) {
1641 int sib_pos = 0, *pos_type;
1642 Sym *f;
1644 i = dwarf_info_section->data_offset;
1645 debug_type = tcc_get_dwarf_info(s1, t->type.ref);
1646 if (retval == debug_type)
1647 retval = i;
1648 dwarf_data1(dwarf_info_section,
1649 t->type.ref->next ? DWARF_ABBREV_SUBROUTINE_TYPE
1650 : DWARF_ABBREV_SUBROUTINE_EMPTY_TYPE);
1651 if (last_pos != -1) {
1652 tcc_debug_check_anon(s1, e, last_pos);
1653 write32le(dwarf_info_section->data + last_pos,
1654 i - dwarf_info.start);
1656 last_pos = dwarf_info_section->data_offset;
1657 e = t->type.ref;
1658 dwarf_data4(dwarf_info_section, 0);
1659 if (t->type.ref->next) {
1660 sib_pos = dwarf_info_section->data_offset;
1661 dwarf_data4(dwarf_info_section, 0);
1663 f = t->type.ref;
1664 i = 0;
1665 while (f->next) {
1666 f = f->next;
1667 i++;
1669 pos_type = (int *) tcc_malloc(i * sizeof(int));
1670 f = t->type.ref;
1671 i = 0;
1672 while (f->next) {
1673 f = f->next;
1674 dwarf_data1(dwarf_info_section, DWARF_ABBREV_FORMAL_PARAMETER2);
1675 pos_type[i++] = dwarf_info_section->data_offset;
1676 dwarf_data4(dwarf_info_section, 0);
1678 if (t->type.ref->next) {
1679 dwarf_data1(dwarf_info_section, 0);
1680 write32le(dwarf_info_section->data + sib_pos,
1681 dwarf_info_section->data_offset - dwarf_info.start);
1683 f = t->type.ref;
1684 i = 0;
1685 while (f->next) {
1686 f = f->next;
1687 type = tcc_get_dwarf_info(s1, f);
1688 tcc_debug_check_anon(s1, f, pos_type[i]);
1689 write32le(dwarf_info_section->data + pos_type[i++],
1690 type - dwarf_info.start);
1692 tcc_free(pos_type);
1694 else {
1695 if (last_pos != -1) {
1696 tcc_debug_check_anon(s1, e, last_pos);
1697 write32le(dwarf_info_section->data + last_pos,
1698 debug_type - dwarf_info.start);
1700 break;
1702 t = t->type.ref;
1704 return retval;
1707 static void tcc_debug_finish (TCCState *s1, struct _debug_info *cur)
1709 while (cur) {
1710 struct _debug_info *next = cur->next;
1711 int i;
1713 if (s1->dwarf) {
1715 for (i = cur->n_sym - 1; i >= 0; i--) {
1716 struct debug_sym *s = &cur->sym[i];
1718 dwarf_data1(dwarf_info_section,
1719 s->type == N_PSYM
1720 ? DWARF_ABBREV_FORMAL_PARAMETER
1721 : s->type == N_GSYM
1722 ? DWARF_ABBREV_VARIABLE_EXTERNAL
1723 : s->type == N_STSYM
1724 ? DWARF_ABBREV_VARIABLE_STATIC
1725 : DWARF_ABBREV_VARIABLE_LOCAL);
1726 dwarf_strp(dwarf_info_section, s->str);
1727 if (s->type == N_GSYM || s->type == N_STSYM) {
1728 dwarf_uleb128(dwarf_info_section, s->file);
1729 dwarf_uleb128(dwarf_info_section, s->line);
1731 dwarf_data4(dwarf_info_section, s->info - dwarf_info.start);
1732 if (s->type == N_GSYM || s->type == N_STSYM) {
1733 /* global/static */
1734 if (s->type == N_GSYM)
1735 dwarf_data1(dwarf_info_section, 1);
1736 dwarf_data1(dwarf_info_section, PTR_SIZE + 1);
1737 dwarf_data1(dwarf_info_section, DW_OP_addr);
1738 if (s->type == N_STSYM)
1739 dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR);
1740 #if PTR_SIZE == 4
1741 dwarf_data4(dwarf_info_section, s->value);
1742 #else
1743 dwarf_data8(dwarf_info_section, s->value);
1744 #endif
1746 else {
1747 /* param/local */
1748 dwarf_data1(dwarf_info_section, dwarf_sleb128_size(s->value) + 1);
1749 dwarf_data1(dwarf_info_section, DW_OP_fbreg);
1750 dwarf_sleb128(dwarf_info_section, s->value);
1752 tcc_free (s->str);
1754 tcc_free (cur->sym);
1755 dwarf_data1(dwarf_info_section,
1756 cur->child ? DWARF_ABBREV_LEXICAL_BLOCK
1757 : DWARF_ABBREV_LEXICAL_EMPTY_BLOCK);
1758 dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR);
1759 #if PTR_SIZE == 4
1760 dwarf_data4(dwarf_info_section, func_ind + cur->start);
1761 dwarf_data4(dwarf_info_section, cur->end - cur->start);
1762 #else
1763 dwarf_data8(dwarf_info_section, func_ind + cur->start);
1764 dwarf_data8(dwarf_info_section, cur->end - cur->start);
1765 #endif
1766 tcc_debug_finish (s1, cur->child);
1767 if (cur->child)
1768 dwarf_data1(dwarf_info_section, 0);
1770 else
1772 for (i = 0; i < cur->n_sym; i++) {
1773 struct debug_sym *s = &cur->sym[i];
1775 if (s->sec)
1776 put_stabs_r(s1, s->str, s->type, 0, 0, s->value,
1777 s->sec, s->sym_index);
1778 else
1779 put_stabs(s1, s->str, s->type, 0, 0, s->value);
1780 tcc_free (s->str);
1782 tcc_free (cur->sym);
1783 put_stabn(s1, N_LBRAC, 0, 0, cur->start);
1784 tcc_debug_finish (s1, cur->child);
1785 put_stabn(s1, N_RBRAC, 0, 0, cur->end);
1787 tcc_free (cur);
1788 cur = next;
1792 ST_FUNC void tcc_add_debug_info(TCCState *s1, int param, Sym *s, Sym *e)
1794 CString debug_str;
1796 if (!(s1->do_debug & 2))
1797 return;
1799 cstr_new (&debug_str);
1800 for (; s != e; s = s->prev) {
1801 if (!s->v || (s->r & VT_VALMASK) != VT_LOCAL)
1802 continue;
1803 if (s1->dwarf) {
1804 tcc_debug_stabs(s1, get_tok_str(s->v, NULL),
1805 param ? N_PSYM : N_LSYM, s->c, NULL, 0,
1806 tcc_get_dwarf_info(s1, s));
1808 else
1810 cstr_reset (&debug_str);
1811 cstr_printf (&debug_str, "%s:%s", get_tok_str(s->v, NULL),
1812 param ? "p" : "");
1813 tcc_get_debug_info(s1, s, &debug_str);
1814 tcc_debug_stabs(s1, debug_str.data, param ? N_PSYM : N_LSYM,
1815 s->c, NULL, 0, 0);
1818 cstr_free (&debug_str);
1821 /* put function symbol */
1822 ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym)
1824 CString debug_str;
1825 BufferedFile *f;
1827 if (!s1->do_debug)
1828 return;
1829 debug_info_root = NULL;
1830 debug_info = NULL;
1831 tcc_debug_stabn(s1, N_LBRAC, ind - func_ind);
1832 f = put_new_file(s1);
1833 if (!f)
1834 return;
1836 if (s1->dwarf) {
1837 tcc_debug_line(s1);
1838 dwarf_info.func = sym;
1839 dwarf_info.line = file->line_num;
1840 if (s1->do_backtrace) {
1841 int i, len;
1843 dwarf_line_op(s1, 0); // extended
1844 dwarf_uleb128_op(s1, strlen(funcname) + 2);
1845 dwarf_line_op(s1, DW_LNE_hi_user - 1);
1846 len = strlen(funcname) + 1;
1847 for (i = 0; i < len; i++)
1848 dwarf_line_op(s1, funcname[i]);
1851 else
1853 cstr_new (&debug_str);
1854 cstr_printf(&debug_str, "%s:%c", funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
1855 tcc_get_debug_info(s1, sym->type.ref, &debug_str);
1856 put_stabs_r(s1, debug_str.data, N_FUN, 0, f->line_num, 0, cur_text_section, sym->c);
1857 cstr_free (&debug_str);
1858 tcc_debug_line(s1);
1862 ST_FUNC void tcc_debug_prolog_epilog(TCCState *s1, int value)
1864 if (!s1->do_debug)
1865 return;
1866 if (s1->dwarf) {
1867 dwarf_line_op(s1, value == 0 ? DW_LNS_set_prologue_end
1868 : DW_LNS_set_epilogue_begin);
1872 /* put function size */
1873 ST_FUNC void tcc_debug_funcend(TCCState *s1, int size)
1875 /* lldb does not like function end and next function start at same pc */
1876 int min_instr_len;
1878 if (!s1->do_debug)
1879 return;
1880 min_instr_len = dwarf_line.last_pc == ind ? 0 : DWARF_MIN_INSTR_LEN;
1881 ind -= min_instr_len;
1882 tcc_debug_line(s1);
1883 ind += min_instr_len;
1884 tcc_debug_stabn(s1, N_RBRAC, size);
1885 if (s1->dwarf) {
1886 int func_sib = 0;
1887 Sym *sym = dwarf_info.func;
1888 int n_debug_info = tcc_get_dwarf_info(s1, sym->type.ref);
1890 dwarf_data1(dwarf_info_section,
1891 sym->type.t & VT_STATIC ? DWARF_ABBREV_SUBPROGRAM_STATIC
1892 : DWARF_ABBREV_SUBPROGRAM_EXTERNAL);
1893 if ((sym->type.t & VT_STATIC) == 0)
1894 dwarf_data1(dwarf_info_section, 1);
1895 dwarf_strp(dwarf_info_section, funcname);
1896 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
1897 dwarf_uleb128(dwarf_info_section, dwarf_info.line);
1898 tcc_debug_check_anon(s1, sym->type.ref, dwarf_info_section->data_offset);
1899 dwarf_data4(dwarf_info_section, n_debug_info - dwarf_info.start);
1900 dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR);
1901 #if PTR_SIZE == 4
1902 dwarf_data4(dwarf_info_section, func_ind); // low_pc
1903 dwarf_data4(dwarf_info_section, size); // high_pc
1904 #else
1905 dwarf_data8(dwarf_info_section, func_ind); // low_pc
1906 dwarf_data8(dwarf_info_section, size); // high_pc
1907 #endif
1908 func_sib = dwarf_info_section->data_offset;
1909 dwarf_data4(dwarf_info_section, 0); // sibling
1910 dwarf_data1(dwarf_info_section, 1);
1911 #if defined(TCC_TARGET_I386)
1912 dwarf_data1(dwarf_info_section, DW_OP_reg5); // ebp
1913 #elif defined(TCC_TARGET_X86_64)
1914 dwarf_data1(dwarf_info_section, DW_OP_reg6); // rbp
1915 #elif defined TCC_TARGET_ARM
1916 dwarf_data1(dwarf_info_section, DW_OP_reg13); // sp
1917 #elif defined TCC_TARGET_ARM64
1918 dwarf_data1(dwarf_info_section, DW_OP_reg29); // reg 29
1919 #elif defined TCC_TARGET_RISCV64
1920 dwarf_data1(dwarf_info_section, DW_OP_reg8); // r8(s0)
1921 #else
1922 dwarf_data1(dwarf_info_section, DW_OP_call_frame_cfa);
1923 #endif
1924 tcc_debug_finish (s1, debug_info_root);
1925 dwarf_data1(dwarf_info_section, 0);
1926 write32le(dwarf_info_section->data + func_sib,
1927 dwarf_info_section->data_offset - dwarf_info.start);
1929 else
1931 tcc_debug_finish (s1, debug_info_root);
1933 debug_info_root = 0;
1937 ST_FUNC void tcc_debug_extern_sym(TCCState *s1, Sym *sym, int sh_num, int sym_bind, int sym_type)
1939 if (!(s1->do_debug & 2))
1940 return;
1942 if (sym_type == STT_FUNC || sym->v >= SYM_FIRST_ANOM)
1943 return;
1944 if (s1->dwarf) {
1945 int debug_type;
1947 debug_type = tcc_get_dwarf_info(s1, sym);
1948 dwarf_data1(dwarf_info_section,
1949 sym_bind == STB_GLOBAL
1950 ? DWARF_ABBREV_VARIABLE_EXTERNAL
1951 : DWARF_ABBREV_VARIABLE_STATIC);
1952 dwarf_strp(dwarf_info_section, get_tok_str(sym->v, NULL));
1953 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
1954 dwarf_uleb128(dwarf_info_section, file->line_num);
1955 tcc_debug_check_anon(s1, sym, dwarf_info_section->data_offset);
1956 dwarf_data4(dwarf_info_section, debug_type - dwarf_info.start);
1957 if (sym_bind == STB_GLOBAL)
1958 dwarf_data1(dwarf_info_section, 1);
1959 dwarf_data1(dwarf_info_section, PTR_SIZE + 1);
1960 dwarf_data1(dwarf_info_section, DW_OP_addr);
1961 greloca(dwarf_info_section, sym, dwarf_info_section->data_offset,
1962 R_DATA_PTR, 0);
1963 #if PTR_SIZE == 4
1964 dwarf_data4(dwarf_info_section, 0);
1965 #else
1966 dwarf_data8(dwarf_info_section, 0);
1967 #endif
1969 else
1971 Section *s = sh_num == SHN_COMMON ? common_section
1972 : s1->sections[sh_num];
1973 CString str;
1975 cstr_new (&str);
1976 cstr_printf (&str, "%s:%c",
1977 get_tok_str(sym->v, NULL),
1978 sym_bind == STB_GLOBAL ? 'G' : func_ind != -1 ? 'V' : 'S'
1980 tcc_get_debug_info(s1, sym, &str);
1981 if (sym_bind == STB_GLOBAL)
1982 tcc_debug_stabs(s1, str.data, N_GSYM, 0, NULL, 0, 0);
1983 else
1984 tcc_debug_stabs(s1, str.data,
1985 (sym->type.t & VT_STATIC) && data_section == s
1986 ? N_STSYM : N_LCSYM, 0, s, sym->c, 0);
1987 cstr_free (&str);
1991 ST_FUNC void tcc_debug_typedef(TCCState *s1, Sym *sym)
1993 if (!(s1->do_debug & 2))
1994 return;
1996 if (s1->dwarf) {
1997 int debug_type;
1999 debug_type = tcc_get_dwarf_info(s1, sym);
2000 if (debug_type != -1) {
2001 dwarf_data1(dwarf_info_section, DWARF_ABBREV_TYPEDEF);
2002 dwarf_strp(dwarf_info_section, get_tok_str(sym->v & ~SYM_FIELD, NULL));
2003 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
2004 dwarf_uleb128(dwarf_info_section, file->line_num);
2005 tcc_debug_check_anon(s1, sym, dwarf_info_section->data_offset);
2006 dwarf_data4(dwarf_info_section, debug_type - dwarf_info.start);
2009 else
2011 CString str;
2012 cstr_new (&str);
2013 cstr_printf (&str, "%s:t",
2014 (sym->v & ~SYM_FIELD) >= SYM_FIRST_ANOM
2015 ? "" : get_tok_str(sym->v & ~SYM_FIELD, NULL));
2016 tcc_get_debug_info(s1, sym, &str);
2017 tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0);
2018 cstr_free (&str);
2022 /* ------------------------------------------------------------------------- */
2023 /* for section layout see lib/tcov.c */
2025 ST_FUNC void tcc_tcov_block_end(TCCState *s1, int line);
2027 ST_FUNC void tcc_tcov_block_begin(TCCState *s1)
2029 SValue sv;
2030 void *ptr;
2031 unsigned long last_offset = tcov_data.offset;
2033 tcc_tcov_block_end (tcc_state, 0);
2034 if (s1->test_coverage == 0 || nocode_wanted)
2035 return;
2037 if (tcov_data.last_file_name == 0 ||
2038 strcmp ((const char *)(tcov_section->data + tcov_data.last_file_name),
2039 file->true_filename) != 0) {
2040 char wd[1024];
2041 CString cstr;
2043 if (tcov_data.last_func_name)
2044 section_ptr_add(tcov_section, 1);
2045 if (tcov_data.last_file_name)
2046 section_ptr_add(tcov_section, 1);
2047 tcov_data.last_func_name = 0;
2048 cstr_new (&cstr);
2049 if (file->true_filename[0] == '/') {
2050 tcov_data.last_file_name = tcov_section->data_offset;
2051 cstr_printf (&cstr, "%s", file->true_filename);
2053 else {
2054 getcwd (wd, sizeof(wd));
2055 tcov_data.last_file_name = tcov_section->data_offset + strlen(wd) + 1;
2056 cstr_printf (&cstr, "%s/%s", wd, file->true_filename);
2058 ptr = section_ptr_add(tcov_section, cstr.size + 1);
2059 strcpy((char *)ptr, cstr.data);
2060 #ifdef _WIN32
2061 normalize_slashes((char *)ptr);
2062 #endif
2063 cstr_free (&cstr);
2065 if (tcov_data.last_func_name == 0 ||
2066 strcmp ((const char *)(tcov_section->data + tcov_data.last_func_name),
2067 funcname) != 0) {
2068 size_t len;
2070 if (tcov_data.last_func_name)
2071 section_ptr_add(tcov_section, 1);
2072 tcov_data.last_func_name = tcov_section->data_offset;
2073 len = strlen (funcname);
2074 ptr = section_ptr_add(tcov_section, len + 1);
2075 strcpy((char *)ptr, funcname);
2076 section_ptr_add(tcov_section, -tcov_section->data_offset & 7);
2077 ptr = section_ptr_add(tcov_section, 8);
2078 write64le (ptr, file->line_num);
2080 if (ind == tcov_data.ind && tcov_data.line == file->line_num)
2081 tcov_data.offset = last_offset;
2082 else {
2083 Sym label = {0};
2084 label.type.t = VT_LLONG | VT_STATIC;
2086 ptr = section_ptr_add(tcov_section, 16);
2087 tcov_data.line = file->line_num;
2088 write64le (ptr, (tcov_data.line << 8) | 0xff);
2089 put_extern_sym(&label, tcov_section,
2090 ((unsigned char *)ptr - tcov_section->data) + 8, 0);
2091 sv.type = label.type;
2092 sv.r = VT_SYM | VT_LVAL | VT_CONST;
2093 sv.r2 = VT_CONST;
2094 sv.c.i = 0;
2095 sv.sym = &label;
2096 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || \
2097 defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64 || \
2098 defined TCC_TARGET_RISCV64
2099 gen_increment_tcov (&sv);
2100 #else
2101 vpushv(&sv);
2102 inc(0, TOK_INC);
2103 vpop();
2104 #endif
2105 tcov_data.offset = (unsigned char *)ptr - tcov_section->data;
2106 tcov_data.ind = ind;
2110 ST_FUNC void tcc_tcov_block_end(TCCState *s1, int line)
2112 if (s1->test_coverage == 0)
2113 return;
2114 if (line == -1)
2115 line = tcov_data.line;
2116 if (tcov_data.offset) {
2117 void *ptr = tcov_section->data + tcov_data.offset;
2118 unsigned long long nline = line ? line : file->line_num;
2120 write64le (ptr, (read64le (ptr) & 0xfffffffffull) | (nline << 36));
2121 tcov_data.offset = 0;
2125 ST_FUNC void tcc_tcov_check_line(TCCState *s1, int start)
2127 if (s1->test_coverage == 0)
2128 return;
2129 if (tcov_data.line != file->line_num) {
2130 if ((tcov_data.line + 1) != file->line_num) {
2131 tcc_tcov_block_end (s1, -1);
2132 if (start)
2133 tcc_tcov_block_begin (s1);
2135 else
2136 tcov_data.line = file->line_num;
2140 ST_FUNC void tcc_tcov_start(TCCState *s1)
2142 if (s1->test_coverage == 0)
2143 return;
2144 if (!s1->dState)
2145 s1->dState = tcc_mallocz(sizeof *s1->dState);
2146 memset (&tcov_data, 0, sizeof (tcov_data));
2147 if (tcov_section == NULL) {
2148 tcov_section = new_section(tcc_state, ".tcov", SHT_PROGBITS,
2149 SHF_ALLOC | SHF_WRITE);
2150 section_ptr_add(tcov_section, 4); // pointer to executable name
2154 ST_FUNC void tcc_tcov_end(TCCState *s1)
2156 if (s1->test_coverage == 0)
2157 return;
2158 if (tcov_data.last_func_name)
2159 section_ptr_add(tcov_section, 1);
2160 if (tcov_data.last_file_name)
2161 section_ptr_add(tcov_section, 1);
2164 ST_FUNC void tcc_tcov_reset_ind(TCCState *s1)
2166 tcov_data.ind = 0;
2169 /* ------------------------------------------------------------------------- */
2170 #undef last_line_num
2171 #undef new_file
2172 #undef section_sym
2173 #undef debug_next_type
2174 #undef debug_hash
2175 #undef n_debug_hash
2176 #undef debug_anon_hash
2177 #undef n_debug_anon_hash
2178 #undef debug_info
2179 #undef debug_info_root
2180 #undef dwarf_sym
2181 #undef dwarf_line
2182 #undef dwarf_info
2183 #undef tcov_data