Op 21-08-2025 om 08:16 schreef Herman ten Brugge:
Op 19-08-2025 om 23:32 schreef grischka:
On 19.08.2025 11:35, Herman ten Brugge via Tinycc-devel wrote:
As to the debug problem:
I tested stabs and did 'p *s' in tcc.exe:main() to see TCCState,
nothing. So it turned out that because TCCState is typedef'd in
libtcc.h first, it is in stabs with no members and a size of -1
and won't be added later because it already was.
Dwarf seems to have another problem though that in a case with some
mutually linked structures, it would quickly eat up 2GB -> memory full.
Which is why I added -g1dwarf switch so I can compile that project.
Seems that stabs works because the tcc_debug_remove(s1, e); doesn't
work ('e' was never added). Whereas with dwarf 't' is removed but
the code never stops.
Why should it output the same structure more than once anyway ?
I debugged this and for stabs and dwarf it is used to register anon
structs
(struct with no definition):
The is for example the case in __locale_t.h on my distrubution:
struct __locale_struct
{
struct __locale_data *__locales[13];
...
};
The __locale_data struct is never defined so I create a anon type for it.
If it is later defined I will replace this with the correct type in
dwarf code.
I cannot do this for stabs but still need to do this because otherwise I
create illegal stabs code.
If I compile tcc with your patch the stab is only 42 lines shorter
(0.03%) (objdump -G) because
no anons are output. The dwarf output is 259 lines shorter (0.03%)
(objdump -W).
I fix the anons at the end of the dwarf output with dummy types. This
is where the 0xffffffff
comes from when I do not do this.
I debugged the code some more and found that I did not handle file scope
correctly.
I created indeed multiple copies of same types if they are present
inside the function code.
I created a patch (see attachment) to fix this.
Herman
diff --git a/tccdbg.c b/tccdbg.c
index 4fd0150..27a8200 100644
--- a/tccdbg.c
+++ b/tccdbg.c
@@ -334,6 +334,8 @@ struct _tccdbg {
struct _debug_info {
int start;
int end;
+ int last_debug_hash;
+ int last_debug_anon_hash;
int n_sym;
struct debug_sym {
int type;
@@ -1192,6 +1194,8 @@ ST_FUNC void tcc_debug_start(TCCState *s1)
}
}
+static void fix_debug_anon_hash(TCCState *s1, int start);
+
/* put end of translation unit info */
ST_FUNC void tcc_debug_end(TCCState *s1)
{
@@ -1202,31 +1206,13 @@ ST_FUNC void tcc_debug_end(TCCState *s1)
tcc_debug_funcend(s1, 0); /* free stuff in case of errors */
if (s1->dwarf) {
- int i, j;
+ int i;
int start_aranges;
unsigned char *ptr;
int text_size = text_section->data_offset;
/* dwarf_info */
- for (i = 0; i < n_debug_anon_hash; i++) {
- Sym *t = debug_anon_hash[i].type;
- int pos = dwarf_info_section->data_offset;
-
- dwarf_data1(dwarf_info_section,
- IS_UNION (t->type.t) ? DWARF_ABBREV_UNION_EMPTY_TYPE
- :
DWARF_ABBREV_STRUCTURE_EMPTY_TYPE);
- dwarf_strp(dwarf_info_section,
- (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
- ? "" : get_tok_str(t->v, NULL));
- dwarf_uleb128(dwarf_info_section, 0);
- dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
- dwarf_uleb128(dwarf_info_section, file->line_num);
- for (j = 0; j < debug_anon_hash[i].n_debug_type; j++)
- write32le(dwarf_info_section->data +
- debug_anon_hash[i].debug_type[j],
- pos - dwarf_info.start);
- tcc_free (debug_anon_hash[i].debug_type);
- }
+ fix_debug_anon_hash(s1, 0);
tcc_free (debug_anon_hash);
dwarf_data1(dwarf_info_section, 0);
ptr = dwarf_info_section->data + dwarf_info.start;
@@ -1325,6 +1311,7 @@ ST_FUNC void tcc_debug_end(TCCState *s1)
}
else
{
+ tcc_free (debug_anon_hash);
put_stabs_r(s1, NULL, N_SO, 0, 0,
text_section->data_offset, text_section, section_sym);
}
@@ -1473,6 +1460,33 @@ static void tcc_debug_stabs (TCCState *s1, const char
*str, int type, unsigned l
put_stabs (s1, str, type, 0, 0, value);
}
+static void fix_debug_anon_hash(TCCState *s1, int start)
+{
+ if (s1->dwarf) {
+ int i, j;
+
+ for (i = start; i < n_debug_anon_hash; i++) {
+ Sym *t = debug_anon_hash[i].type;
+ int pos = dwarf_info_section->data_offset;
+
+ dwarf_data1(dwarf_info_section,
+ IS_UNION (t->type.t) ? DWARF_ABBREV_UNION_EMPTY_TYPE
+ :
DWARF_ABBREV_STRUCTURE_EMPTY_TYPE);
+ dwarf_strp(dwarf_info_section,
+ (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
+ ? "" : get_tok_str(t->v, NULL));
+ dwarf_uleb128(dwarf_info_section, 0);
+ dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
+ dwarf_uleb128(dwarf_info_section, file->line_num);
+ for (j = 0; j < debug_anon_hash[i].n_debug_type; j++)
+ write32le(dwarf_info_section->data +
+ debug_anon_hash[i].debug_type[j],
+ pos - dwarf_info.start);
+ tcc_free (debug_anon_hash[i].debug_type);
+ }
+ }
+}
+
ST_FUNC void tcc_debug_stabn(TCCState *s1, int type, int value)
{
if (!s1->do_debug)
@@ -1482,6 +1496,8 @@ ST_FUNC void tcc_debug_stabn(TCCState *s1, int type, int
value)
(struct _debug_info *) tcc_mallocz(sizeof (*info));
info->start = value;
+ info->last_debug_hash = n_debug_hash;
+ info->last_debug_anon_hash = n_debug_anon_hash;
info->parent = debug_info;
if (debug_info) {
if (debug_info->child) {
@@ -1499,6 +1515,9 @@ ST_FUNC void tcc_debug_stabn(TCCState *s1, int type, int
value)
debug_info = info;
}
else {
+ fix_debug_anon_hash(s1, debug_info->last_debug_anon_hash);
+ n_debug_hash = debug_info->last_debug_hash;
+ n_debug_anon_hash = debug_info->last_debug_anon_hash;
debug_info->end = value;
debug_info = debug_info->parent;
}
@@ -1508,8 +1527,7 @@ static int tcc_debug_find(TCCState *s1, Sym *t, int dwarf)
{
int i;
- if (!debug_info && dwarf &&
- (t->type.t & VT_BTYPE) == VT_STRUCT && t->c == -1) {
+ if ((t->type.t & VT_BTYPE) == VT_STRUCT && t->c == -1) {
for (i = 0; i < n_debug_anon_hash; i++)
if (t == debug_anon_hash[i].type)
return 0;
@@ -1533,7 +1551,7 @@ static void tcc_debug_check_anon(TCCState *s1, Sym *t,
int debug_type)
{
int i;
- if (!debug_info && (t->type.t & VT_BTYPE) == VT_STRUCT && t->type.ref->c
== -1)
+ if ((t->type.t & VT_BTYPE) == VT_STRUCT && t->type.ref->c == -1)
for (i = 0; i < n_debug_anon_hash; i++)
if (t->type.ref == debug_anon_hash[i].type) {
debug_anon_hash[i].debug_type =
@@ -1548,23 +1566,22 @@ ST_FUNC void tcc_debug_fix_anon(TCCState *s1, CType *t)
{
int i, j, debug_type;
- if (!(s1->do_debug & 2) || !s1->dwarf || debug_info)
+ if (!(s1->do_debug & 2))
return;
if ((t->t & VT_BTYPE) == VT_STRUCT && t->ref->c != -1)
for (i = 0; i < n_debug_anon_hash; i++)
if (t->ref == debug_anon_hash[i].type) {
- Sym sym = {0}; sym .type = *t ;
-
- /* Trick to not hash this struct */
- debug_info = (struct _debug_info *) t;
- debug_type = tcc_get_dwarf_info(s1, &sym);
- debug_info = NULL;
- for (j = 0; j < debug_anon_hash[i].n_debug_type; j++)
- write32le(dwarf_info_section->data +
- debug_anon_hash[i].debug_type[j],
- debug_type - dwarf_info.start);
- tcc_free(debug_anon_hash[i].debug_type);
+ if (s1->dwarf) {
+ Sym sym = {0}; sym .type = *t ;
+
+ debug_type = tcc_get_dwarf_info(s1, &sym);
+ for (j = 0; j < debug_anon_hash[i].n_debug_type; j++)
+ write32le(dwarf_info_section->data +
+ debug_anon_hash[i].debug_type[j],
+ debug_type - dwarf_info.start);
+ tcc_free(debug_anon_hash[i].debug_type);
+ }
n_debug_anon_hash--;
for (; i < n_debug_anon_hash; i++)
debug_anon_hash[i] = debug_anon_hash[i + 1];
@@ -1582,18 +1599,6 @@ static int tcc_debug_add(TCCState *s1, Sym *t, int dwarf)
return offset;
}
-static void tcc_debug_remove(TCCState *s1, Sym *t)
-{
- int i;
-
- for (i = 0; i < n_debug_hash; i++)
- if (t == debug_hash[i].type) {
- n_debug_hash--;
- for (; i < n_debug_hash; i++)
- debug_hash[i] = debug_hash[i+1];
- }
-}
-
#define STRUCT_NODEBUG(s) \
(s->a.nodebug || \
((s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM && \
@@ -1621,11 +1626,9 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s,
CString *result)
break;
}
if ((type & VT_BTYPE) == VT_STRUCT) {
- Sym *e = t;
-
t = t->type.ref;
debug_type = tcc_debug_find(s1, t, 0);
- if (debug_type == -1 && t->c >= 0) {
+ if (debug_type == -1) {
debug_type = tcc_debug_add(s1, t, 0);
cstr_new (&str);
cstr_printf (&str, "%s:T%d=%c%d",
@@ -1656,15 +1659,13 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s,
CString *result)
cstr_printf (&str, ";");
tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0);
cstr_free (&str);
- if (debug_info)
- tcc_debug_remove(s1, e);
}
}
else if (IS_ENUM(type)) {
Sym *e = t = t->type.ref;
debug_type = tcc_debug_find(s1, t, 0);
- if (debug_type == -1 && t->c >= 0) {
+ if (debug_type == -1) {
debug_type = tcc_debug_add(s1, t, 0);
cstr_new (&str);
cstr_printf (&str, "%s:T%d=e",
@@ -1682,8 +1683,6 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s,
CString *result)
cstr_printf (&str, ";");
tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0);
cstr_free (&str);
- if (debug_info)
- tcc_debug_remove(s1, e);
}
}
else if ((type & VT_BTYPE) != VT_FUNC) {
@@ -1741,7 +1740,7 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s)
if ((type & VT_BTYPE) == VT_STRUCT) {
t = t->type.ref;
debug_type = tcc_debug_find(s1, t, 1);
- if (debug_type == -1 && t->c >= 0) {
+ if (debug_type == -1) {
int pos_sib = 0, i, *pos_type;
debug_type = tcc_debug_add(s1, t, 1);
@@ -1812,14 +1811,12 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s)
type - dwarf_info.start);
}
tcc_free(pos_type);
- if (debug_info)
- tcc_debug_remove(s1, t);
}
}
else if (IS_ENUM(type)) {
t = t->type.ref;
debug_type = tcc_debug_find(s1, t, 1);
- if (debug_type == -1 && t->c >= 0) {
+ if (debug_type == -1) {
int pos_sib, pos_type;
Sym sym = {0}; sym.type.t = VT_INT | (type & VT_UNSIGNED);
@@ -1854,8 +1851,6 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s)
dwarf_data1(dwarf_info_section, 0);
write32le(dwarf_info_section->data + pos_sib,
dwarf_info_section->data_offset - dwarf_info.start);
- if (debug_info)
- tcc_debug_remove(s1, t);
}
}
else if ((type & VT_BTYPE) != VT_FUNC) {
_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel