I created a path to add debug type information (see attachment).

The patch only supports basic types and array/ptr types of them.

So:
int main(int argc, char *argv[])

is supported.

Other things like structs/unions/enums/bitfields are all translated to void.
This should probably change in the future.

I also generate a new type whenever I see a pointer or array.
This creates a lot of types but gdb seems happy with it.
If I compile tcc with bounds-checking I see 1473 types.
In the future types should be optimized.

Can I apply this patch?

Regards,

    Herman
diff --git a/tccgen.c b/tccgen.c
index 71d3d04..9cf488d 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -120,6 +120,47 @@ static struct scope {
     Sym *lstk, *llstk;
 } *cur_scope, *loop_scope, *root_scope;
 
+static struct {
+  int type;
+  const char *name;
+} default_debug[] = {
+    {   VT_INT, "int:t1=r1;-2147483648;2147483647;", },
+    {   VT_BYTE, "char:t2=r2;0;127;", },
+#if LONG_SIZE == 4
+    {   VT_LLONG, "long int:t3=r3;-2147483648;2147483647;", },
+#else
+    {   VT_LLONG, "long int:t3=r3;-9223372036854775808;9223372036854775807;", 
},
+#endif
+    {   VT_INT | VT_UNSIGNED, "unsigned int:t4=r4;0;4294967295;", },
+#if LONG_SIZE == 4
+    {   VT_LLONG | VT_UNSIGNED, "long unsigned int:t5=r5;0;4294967295;", },
+#else
+    {   VT_LLONG | VT_UNSIGNED, "long unsigned int:t5=r5;0;-1;", },
+#endif
+    {   VT_QLONG, "__int128:t6=r6;0;-1;", },
+    {   VT_QLONG | VT_UNSIGNED, "__int128 unsigned:t7=r7;0;-1;", },
+    {   VT_LLONG, "long long 
int:t8=r8;-9223372036854775808;9223372036854775807;", },
+    {   VT_LLONG | VT_UNSIGNED, "long long unsigned int:t9=r9;0;-1;", },
+    {   VT_SHORT, "short int:t10=r10;-32768;32767;", },
+    {   VT_SHORT | VT_UNSIGNED, "short unsigned int:t11=r11;0;65535;", },
+    {   VT_BYTE | VT_DEFSIGN, "signed char:t12=r12;-128;127;", },
+    {   VT_BYTE | VT_UNSIGNED, "unsigned char:t13=r13;0;255;", },
+    {   VT_FLOAT, "float:t14=r1;4;0;", },
+    {   VT_DOUBLE, "double:t15=r1;8;0;", },
+    {   VT_LDOUBLE, "long double:t16=r1;16;0;", },
+    {   -1, "_Float32:t17=r1;4;0;", },
+    {   -1, "_Float64:t18=r1;8;0;", },
+    {   -1, "_Float128:t19=r1;16;0;", },
+    {   -1, "_Float32x:t20=r1;8;0;", },
+    {   -1, "_Float64x:t21=r1;16;0;", },
+    {   -1, "_Decimal32:t22=r1;4;0;", },
+    {   -1, "_Decimal64:t23=r1;8;0;", },
+    {   -1, "_Decimal128:t24=r1;16;0;", },
+    {   VT_VOID, "void:t25=25", },
+};
+
+static int next_type = sizeof(default_debug) / sizeof(default_debug[0]);
+
 /********************************************************/
 #ifndef CONFIG_TCC_ASM
 ST_FUNC void asm_instr(void)
@@ -321,6 +362,7 @@ void pv (const char *lbl, int a, int b)
 ST_FUNC void tcc_debug_start(TCCState *s1)
 {
     if (s1->do_debug) {
+        int i;
         char buf[512];
 
         /* file info: full path + filename */
@@ -336,6 +378,8 @@ ST_FUNC void tcc_debug_start(TCCState *s1)
                     text_section->data_offset, text_section, section_sym);
         put_stabs_r(s1, file->prev->filename, N_SO, 0, 0,
                     text_section->data_offset, text_section, section_sym);
+        for (i = 0; i < sizeof (default_debug) / sizeof (default_debug[0]); 
i++)
+            put_stabs(s1, default_debug[i].name, N_LSYM, 0, 0, 0);
         new_file = last_line_num = 0;
         func_ind = -1;
         /* we're currently 'including' the <command line> */
@@ -349,6 +393,66 @@ ST_FUNC void tcc_debug_start(TCCState *s1)
                 SHN_ABS, file->filename);
 }
 
+static void tcc_get_debug_info(Sym *s, char *result)
+{
+    int i;
+    int n = 0;
+    int type;
+    Sym *t = s;
+
+    if (!tcc_state->do_debug)
+        return;
+    for (;;) {
+        type = t->type.t & ~(VT_EXTERN | VT_STATIC);
+        if (type == VT_PTR || type == (VT_PTR | VT_ARRAY))
+            n++, t = t->type.ref;
+        else
+            break;
+    }
+    for (i = 0; i < sizeof(default_debug) / sizeof(default_debug[0]); i++)
+        if (default_debug[i].type == type)
+            break;
+    if (i == sizeof(default_debug) / sizeof(default_debug[0]))
+#if 0
+        return;
+#else
+        /* XXX: Map Struct/Union/Enum/Bitfield to void */
+        i--; /* last item is void */
+#endif
+    if (n > 0)
+        /* XXX: Optimize. Merge type info */
+       sprintf (&result[strlen(result)], "%d=", ++next_type);
+    t = s;
+    for (;;) {
+       type = t->type.t & ~(VT_EXTERN | VT_STATIC);
+       if (type == VT_PTR)
+           strcat (result, "*");
+       else if (type == (VT_PTR | VT_ARRAY))
+            /* XXX: Optimize. Merge type info */
+           sprintf (&result[strlen(result)], "%d=ar1;0;%d;",
+                    ++next_type, t->type.ref->c - 1);
+       else
+           break;
+       t = t->type.ref;
+    }
+    sprintf (&result[strlen(result)], "%d", i + 1);
+}
+
+static void tcc_add_debug_info(int param, Sym *s, Sym *e)
+{
+    if (!tcc_state->do_debug)
+        return;
+    for (; s != e; s = s->prev) {
+        char str[512];
+
+        if (!s->v || (s->r & VT_VALMASK) != VT_LOCAL)
+            continue;
+        snprintf (str, sizeof(str), "%s:%s", get_tok_str(s->v, NULL), param ? 
"p" : "");
+        tcc_get_debug_info(s, &str[strlen(str)]);
+        put_stabs(tcc_state, str, param ? N_PSYM : N_LSYM, 0, 0, s->c);
+    }
+}
+
 /* put end of translation unit info */
 ST_FUNC void tcc_debug_end(TCCState *s1)
 {
@@ -396,9 +500,9 @@ ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym)
     BufferedFile *f;
     if (!s1->do_debug || !(f = put_new_file(s1)))
         return;
-    /* XXX: we put here a dummy type */
-    snprintf(buf, sizeof(buf), "%s:%c1",
+    snprintf(buf, sizeof(buf), "%s:%c",
              funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
+    tcc_get_debug_info(sym->type.ref, &buf[strlen(buf)]);
     put_stabs_r(s1, buf, N_FUN, 0, f->line_num, 0, cur_text_section, sym->c);
     tcc_debug_line(s1);
 }
@@ -560,6 +664,7 @@ ST_FUNC void put_extern_sym2(Sym *sym, int sh_num,
 #ifdef CONFIG_TCC_BCHECK
     char buf[32];
 #endif
+    char str[512];
 
     if (!sym->c) {
         name = get_tok_str(sym->v, NULL);
@@ -635,6 +740,19 @@ ST_FUNC void put_extern_sym2(Sym *sym, int sh_num,
             name = get_tok_str(sym->asm_label, NULL);
         info = ELFW(ST_INFO)(sym_bind, sym_type);
         sym->c = put_elf_sym(symtab_section, value, size, info, other, sh_num, 
name);
+        if (sym_type != STT_FUNC && sym->v < SYM_FIRST_ANOM) {
+            snprintf (str, sizeof(str), "%s:%c", get_tok_str(sym->v, NULL),
+                      sym_bind == STB_GLOBAL ? 'G' : 'S');
+            tcc_get_debug_info(sym, &str[strlen(str)]);
+            if (sym_bind == STB_GLOBAL)
+                put_stabs(tcc_state, str, N_GSYM, 0, 0, value);
+            else
+                put_stabs_r(tcc_state, str, N_LCSYM, 0, 0, 0,
+                            data_section->sh_num == sh_num ? data_section :
+                            bss_section->sh_num == sh_num ? bss_section :
+                            common_section->sh_num == sh_num ? common_section :
+                            text_section, sym->c);
+        }
     } else {
         esym = elfsym(sym);
         esym->st_value = value;
@@ -1612,12 +1730,13 @@ static void add_local_bounds(Sym *s, Sym *e)
 #endif
 
 /* Wrapper around sym_pop, that potentially also registers local bounds.  */
-static void pop_local_syms(Sym **ptop, Sym *b, int keep, int ellipsis)
+static void pop_local_syms(int param, Sym **ptop, Sym *b, int keep, int 
ellipsis)
 {
 #ifdef CONFIG_TCC_BCHECK
     if (!ellipsis && !keep && tcc_state->do_bounds_check)
         add_local_bounds(*ptop, b);
 #endif
+    tcc_add_debug_info (param, *ptop, b);
     sym_pop(ptop, b, keep);
 }
 
@@ -6409,7 +6528,7 @@ void prev_scope(struct scope *o, int is_expr)
        tables, though.  sym_pop will do that.  */
 
     /* pop locally defined symbols */
-    pop_local_syms(&local_stack, o->lstk, is_expr, 0);
+    pop_local_syms(0, &local_stack, o->lstk, is_expr, 0);
 
     cur_scope = o->prev;
     --local_scope;
@@ -7639,7 +7758,7 @@ static void gen_function(Sym *sym)
     gsym(rsym);
     nocode_wanted = 0;
     /* reset local stack */
-    pop_local_syms(&local_stack, NULL, 0,
+    pop_local_syms(1, &local_stack, NULL, 0,
                    sym->type.ref->f.func_type == FUNC_ELLIPSIS);
     gfunc_epilog();
     cur_text_section->data_offset = ind;
_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to