Update dwarf2 support
tccgen.c: - add anon support. So tcc_state in tcc works now. - add function pointer support - remove DW_FORM_implicit_const from DW_TAG_pointer_type tccrun.c: - set initial file name - correctly use pc in DW_LNE_set_address (see lib/bt-exe.c) - add DW_LNE_define_file support (even if it is deprecated) tccelf.c - do not include debug/test_coverage information for stub functions lib/bt-exe.c - use num_callers=-1 to mark dll
This commit is contained in:
parent
f0df48fcdd
commit
18808e325f
4 changed files with 224 additions and 23 deletions
|
|
@ -29,6 +29,7 @@ void __bt_init(rt_context *p, int num_callers)
|
||||||
__rt_error = _rt_error;
|
__rt_error = _rt_error;
|
||||||
set_exception_handler();
|
set_exception_handler();
|
||||||
} else {
|
} else {
|
||||||
|
p->num_callers = -1;
|
||||||
p->next = rc->next, rc->next = p;
|
p->next = rc->next, rc->next = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
17
tccelf.c
17
tccelf.c
|
|
@ -1426,6 +1426,19 @@ static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* avoid generating debug/test_coverage code for stub functions */
|
||||||
|
static void tcc_compile_string_no_debug(TCCState *s, const char *str)
|
||||||
|
{
|
||||||
|
int save_do_debug = s->do_debug;
|
||||||
|
int save_test_coverage = s->test_coverage;
|
||||||
|
|
||||||
|
s->do_debug = 0;
|
||||||
|
s->test_coverage = 0;
|
||||||
|
tcc_compile_string(s, str);
|
||||||
|
s->do_debug = save_do_debug;
|
||||||
|
s->test_coverage = save_test_coverage;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_TCC_BACKTRACE
|
#ifdef CONFIG_TCC_BACKTRACE
|
||||||
static void put_ptr(TCCState *s1, Section *s, int offs, const char *name)
|
static void put_ptr(TCCState *s1, Section *s, int offs, const char *name)
|
||||||
{
|
{
|
||||||
|
|
@ -1489,7 +1502,7 @@ ST_FUNC void tcc_add_btstub(TCCState *s1)
|
||||||
#endif
|
#endif
|
||||||
cstr_printf(&cstr, "__bt_init(__rt_info,%d);}",
|
cstr_printf(&cstr, "__bt_init(__rt_info,%d);}",
|
||||||
s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
|
s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
|
||||||
tcc_compile_string(s1, cstr.data);
|
tcc_compile_string_no_debug(s1, cstr.data);
|
||||||
cstr_free(&cstr);
|
cstr_free(&cstr);
|
||||||
set_local_sym(s1, &"___rt_info"[!s1->leading_underscore], s, o);
|
set_local_sym(s1, &"___rt_info"[!s1->leading_underscore], s, o);
|
||||||
}
|
}
|
||||||
|
|
@ -1528,7 +1541,7 @@ static void tcc_tcov_add_file(TCCState *s1, const char *filename)
|
||||||
"__attribute__((destructor)) static void __tcov_exit() {"
|
"__attribute__((destructor)) static void __tcov_exit() {"
|
||||||
"__store_test_coverage(__tcov_data);"
|
"__store_test_coverage(__tcov_data);"
|
||||||
"}");
|
"}");
|
||||||
tcc_compile_string(s1, cstr.data);
|
tcc_compile_string_no_debug(s1, cstr.data);
|
||||||
cstr_free(&cstr);
|
cstr_free(&cstr);
|
||||||
set_local_sym(s1, &"___tcov_data"[!s1->leading_underscore], tcov_section, 0);
|
set_local_sym(s1, &"___tcov_data"[!s1->leading_underscore], tcov_section, 0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
204
tccgen.c
204
tccgen.c
|
|
@ -187,7 +187,7 @@ static const struct {
|
||||||
{ VT_BYTE | VT_UNSIGNED, 1, DW_ATE_unsigned_char, "unsigned char:t25=r25;0;255;" },
|
{ VT_BYTE | VT_UNSIGNED, 1, DW_ATE_unsigned_char, "unsigned char:t25=r25;0;255;" },
|
||||||
/* boolean type */
|
/* boolean type */
|
||||||
{ VT_BOOL, 1, DW_ATE_unsigned_char, "bool:t26=r26;0;255;" },
|
{ VT_BOOL, 1, DW_ATE_unsigned_char, "bool:t26=r26;0;255;" },
|
||||||
{ VT_VOID, 1, DW_ATE_void, "void:t27=27" },
|
{ VT_VOID, 1, DW_ATE_unsigned_char, "void:t27=27" },
|
||||||
};
|
};
|
||||||
|
|
||||||
#define N_DEFAULT_DEBUG (sizeof (default_debug) / sizeof (default_debug[0]))
|
#define N_DEFAULT_DEBUG (sizeof (default_debug) / sizeof (default_debug[0]))
|
||||||
|
|
@ -199,7 +199,14 @@ static struct debug_hash {
|
||||||
Sym *type;
|
Sym *type;
|
||||||
} *debug_hash;
|
} *debug_hash;
|
||||||
|
|
||||||
|
static struct debug_anon_hash {
|
||||||
|
Sym *type;
|
||||||
|
int n_debug_type;
|
||||||
|
int *debug_type;
|
||||||
|
} *debug_anon_hash;
|
||||||
|
|
||||||
static int n_debug_hash;
|
static int n_debug_hash;
|
||||||
|
static int n_debug_anon_hash;
|
||||||
|
|
||||||
static struct debug_info {
|
static struct debug_info {
|
||||||
int start;
|
int start;
|
||||||
|
|
@ -251,7 +258,12 @@ static struct debug_info {
|
||||||
#define DWARF_ABBREV_SUBPROGRAM_EXTERNAL 17
|
#define DWARF_ABBREV_SUBPROGRAM_EXTERNAL 17
|
||||||
#define DWARF_ABBREV_SUBPROGRAM_STATIC 18
|
#define DWARF_ABBREV_SUBPROGRAM_STATIC 18
|
||||||
#define DWARF_ABBREV_LEXICAL_BLOCK 19
|
#define DWARF_ABBREV_LEXICAL_BLOCK 19
|
||||||
|
#define DWARF_ABBREV_SUBROUTINE_TYPE 20
|
||||||
|
#define DWARF_ABBREV_FORMAL_PARAMETER2 21
|
||||||
|
|
||||||
|
/* all entries should have been generated with dwarf_uleb128 except
|
||||||
|
has_children. All values are currently below 128 so this currently
|
||||||
|
works. */
|
||||||
static const unsigned char dwarf_abbrev_init[] = {
|
static const unsigned char dwarf_abbrev_init[] = {
|
||||||
DWARF_ABBREV_COMPILE_UNIT, DW_TAG_compile_unit, 1,
|
DWARF_ABBREV_COMPILE_UNIT, DW_TAG_compile_unit, 1,
|
||||||
DW_AT_producer, DW_FORM_strp,
|
DW_AT_producer, DW_FORM_strp,
|
||||||
|
|
@ -298,7 +310,6 @@ static const unsigned char dwarf_abbrev_init[] = {
|
||||||
0, 0,
|
0, 0,
|
||||||
DWARF_ABBREV_POINTER, DW_TAG_pointer_type, 0,
|
DWARF_ABBREV_POINTER, DW_TAG_pointer_type, 0,
|
||||||
DW_AT_byte_size, DW_FORM_data1,
|
DW_AT_byte_size, DW_FORM_data1,
|
||||||
DW_AT_byte_size, DW_FORM_implicit_const, 8,
|
|
||||||
DW_AT_type, DW_FORM_ref4,
|
DW_AT_type, DW_FORM_ref4,
|
||||||
0, 0,
|
0, 0,
|
||||||
DWARF_ABBREV_ARRAY_TYPE, DW_TAG_array_type, 1,
|
DWARF_ABBREV_ARRAY_TYPE, DW_TAG_array_type, 1,
|
||||||
|
|
@ -394,6 +405,13 @@ static const unsigned char dwarf_abbrev_init[] = {
|
||||||
DW_AT_high_pc, DW_FORM_data8,
|
DW_AT_high_pc, DW_FORM_data8,
|
||||||
#endif
|
#endif
|
||||||
0, 0,
|
0, 0,
|
||||||
|
DWARF_ABBREV_SUBROUTINE_TYPE, DW_TAG_subroutine_type, 1,
|
||||||
|
DW_AT_type, DW_FORM_ref4,
|
||||||
|
DW_AT_sibling, DW_FORM_ref4,
|
||||||
|
0, 0,
|
||||||
|
DWARF_ABBREV_FORMAL_PARAMETER2, DW_TAG_formal_parameter, 0,
|
||||||
|
DW_AT_type, DW_FORM_ref4,
|
||||||
|
0, 0,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -945,7 +963,9 @@ ST_FUNC void tcc_debug_start(TCCState *s1)
|
||||||
func_ind = -1;
|
func_ind = -1;
|
||||||
debug_next_type = N_DEFAULT_DEBUG;
|
debug_next_type = N_DEFAULT_DEBUG;
|
||||||
debug_hash = NULL;
|
debug_hash = NULL;
|
||||||
|
debug_anon_hash = NULL;
|
||||||
n_debug_hash = 0;
|
n_debug_hash = 0;
|
||||||
|
n_debug_anon_hash = 0;
|
||||||
/* we're currently 'including' the <command line> */
|
/* we're currently 'including' the <command line> */
|
||||||
tcc_debug_bincl(s1);
|
tcc_debug_bincl(s1);
|
||||||
}
|
}
|
||||||
|
|
@ -963,12 +983,35 @@ ST_FUNC void tcc_debug_end(TCCState *s1)
|
||||||
if (!s1->do_debug)
|
if (!s1->do_debug)
|
||||||
return;
|
return;
|
||||||
if (s1->dwarf) {
|
if (s1->dwarf) {
|
||||||
int i;
|
int i, j;
|
||||||
int start_aranges;
|
int start_aranges;
|
||||||
unsigned char *ptr;
|
unsigned char *ptr;
|
||||||
int text_size = text_section->data_offset;
|
int text_size = text_section->data_offset;
|
||||||
|
|
||||||
/* dwarf_info */
|
/* 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_TYPE
|
||||||
|
: DWARF_ABBREV_STRUCTURE_TYPE);
|
||||||
|
dwarf_strp(dwarf_info_section,
|
||||||
|
(t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
|
||||||
|
? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL));
|
||||||
|
dwarf_uleb128(dwarf_info_section, 0);
|
||||||
|
dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
|
||||||
|
dwarf_uleb128(dwarf_info_section, file->line_num);
|
||||||
|
j = dwarf_info_section->data_offset + 5 - dwarf_info.start;
|
||||||
|
dwarf_data4(dwarf_info_section, j);
|
||||||
|
dwarf_data1(dwarf_info_section, 0);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
tcc_free (debug_anon_hash);
|
||||||
dwarf_data1(dwarf_info_section, 0);
|
dwarf_data1(dwarf_info_section, 0);
|
||||||
ptr = dwarf_info_section->data + dwarf_info.start;
|
ptr = dwarf_info_section->data + dwarf_info.start;
|
||||||
write32le(ptr, dwarf_info_section->data_offset - dwarf_info.start - 4);
|
write32le(ptr, dwarf_info_section->data_offset - dwarf_info.start - 4);
|
||||||
|
|
@ -1276,16 +1319,69 @@ static void tcc_debug_stabn(TCCState *s1, int type, int value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tcc_debug_find(Sym *t)
|
static int tcc_get_dwarf_info(TCCState *s1, Sym *s);
|
||||||
|
|
||||||
|
static int tcc_debug_find(Sym *t, int dwarf)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (!debug_info && dwarf &&
|
||||||
|
(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;
|
||||||
|
debug_anon_hash = (struct debug_anon_hash *)
|
||||||
|
tcc_realloc (debug_anon_hash,
|
||||||
|
(n_debug_anon_hash + 1) * sizeof(*debug_anon_hash));
|
||||||
|
debug_anon_hash[n_debug_anon_hash].n_debug_type = 0;
|
||||||
|
debug_anon_hash[n_debug_anon_hash].debug_type = NULL;
|
||||||
|
debug_anon_hash[n_debug_anon_hash++].type = t;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
for (i = 0; i < n_debug_hash; i++)
|
for (i = 0; i < n_debug_hash; i++)
|
||||||
if (t == debug_hash[i].type)
|
if (t == debug_hash[i].type)
|
||||||
return debug_hash[i].debug_type;
|
return debug_hash[i].debug_type;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tcc_debug_check_anon(Sym *t, int debug_type)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!debug_info && (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 =
|
||||||
|
tcc_realloc(debug_anon_hash[i].debug_type,
|
||||||
|
(debug_anon_hash[i].n_debug_type + 1) * sizeof(int));
|
||||||
|
debug_anon_hash[i].debug_type[debug_anon_hash[i].n_debug_type++] =
|
||||||
|
debug_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tcc_debug_fix_anon(CType *t)
|
||||||
|
{
|
||||||
|
int i, j, debug_type;
|
||||||
|
TCCState *s1 = tcc_state;
|
||||||
|
|
||||||
|
if (!s1->do_debug || !s1->dwarf || debug_info)
|
||||||
|
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 = { .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);
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int tcc_debug_add(Sym *t, int dwarf)
|
static int tcc_debug_add(Sym *t, int dwarf)
|
||||||
{
|
{
|
||||||
int offset = dwarf ? dwarf_info_section->data_offset : ++debug_next_type;
|
int offset = dwarf ? dwarf_info_section->data_offset : ++debug_next_type;
|
||||||
|
|
@ -1331,7 +1427,7 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result)
|
||||||
Sym *e = t;
|
Sym *e = t;
|
||||||
|
|
||||||
t = t->type.ref;
|
t = t->type.ref;
|
||||||
debug_type = tcc_debug_find(t);
|
debug_type = tcc_debug_find(t, 0);
|
||||||
if (debug_type == -1) {
|
if (debug_type == -1) {
|
||||||
debug_type = tcc_debug_add(t, 0);
|
debug_type = tcc_debug_add(t, 0);
|
||||||
cstr_new (&str);
|
cstr_new (&str);
|
||||||
|
|
@ -1369,7 +1465,7 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result)
|
||||||
else if (IS_ENUM(type)) {
|
else if (IS_ENUM(type)) {
|
||||||
Sym *e = t = t->type.ref;
|
Sym *e = t = t->type.ref;
|
||||||
|
|
||||||
debug_type = tcc_debug_find(t);
|
debug_type = tcc_debug_find(t, 0);
|
||||||
if (debug_type == -1) {
|
if (debug_type == -1) {
|
||||||
debug_type = tcc_debug_add(t, 0);
|
debug_type = tcc_debug_add(t, 0);
|
||||||
cstr_new (&str);
|
cstr_new (&str);
|
||||||
|
|
@ -1430,6 +1526,8 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s)
|
||||||
int debug_type = -1;
|
int debug_type = -1;
|
||||||
Sym *e, *t = s;
|
Sym *e, *t = s;
|
||||||
int i;
|
int i;
|
||||||
|
int last_pos = -1;
|
||||||
|
int retval;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE);
|
type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE);
|
||||||
|
|
@ -1442,7 +1540,7 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s)
|
||||||
}
|
}
|
||||||
if ((type & VT_BTYPE) == VT_STRUCT) {
|
if ((type & VT_BTYPE) == VT_STRUCT) {
|
||||||
t = t->type.ref;
|
t = t->type.ref;
|
||||||
debug_type = tcc_debug_find(t);
|
debug_type = tcc_debug_find(t, 1);
|
||||||
if (debug_type == -1) {
|
if (debug_type == -1) {
|
||||||
int pos_sib, i, *pos_type;
|
int pos_sib, i, *pos_type;
|
||||||
|
|
||||||
|
|
@ -1504,6 +1602,7 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s)
|
||||||
while (e->next) {
|
while (e->next) {
|
||||||
e = e->next;
|
e = e->next;
|
||||||
type = tcc_get_dwarf_info(s1, e);
|
type = tcc_get_dwarf_info(s1, e);
|
||||||
|
tcc_debug_check_anon(e, pos_type[i]);
|
||||||
write32le(dwarf_info_section->data + pos_type[i++],
|
write32le(dwarf_info_section->data + pos_type[i++],
|
||||||
type - dwarf_info.start);
|
type - dwarf_info.start);
|
||||||
}
|
}
|
||||||
|
|
@ -1514,7 +1613,7 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s)
|
||||||
}
|
}
|
||||||
else if (IS_ENUM(type)) {
|
else if (IS_ENUM(type)) {
|
||||||
t = t->type.ref;
|
t = t->type.ref;
|
||||||
debug_type = tcc_debug_find(t);
|
debug_type = tcc_debug_find(t, 1);
|
||||||
if (debug_type == -1) {
|
if (debug_type == -1) {
|
||||||
int pos_sib, pos_type;
|
int pos_sib, pos_type;
|
||||||
CType ct = { VT_INT | (type & VT_UNSIGNED) , NULL };
|
CType ct = { VT_INT | (type & VT_UNSIGNED) , NULL };
|
||||||
|
|
@ -1569,8 +1668,9 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s)
|
||||||
*strchr(name, ':') = 0;
|
*strchr(name, ':') = 0;
|
||||||
dwarf_strp(dwarf_info_section, name);
|
dwarf_strp(dwarf_info_section, name);
|
||||||
dwarf_info.base_type_used[i - 1] = debug_type;
|
dwarf_info.base_type_used[i - 1] = debug_type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
retval = debug_type;
|
||||||
t = s;
|
t = s;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE);
|
type = t->type.t & ~(VT_STORAGE | VT_CONSTANT | VT_VOLATILE);
|
||||||
|
|
@ -1578,10 +1678,18 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s)
|
||||||
type &= ~VT_DEFSIGN;
|
type &= ~VT_DEFSIGN;
|
||||||
if (type == VT_PTR) {
|
if (type == VT_PTR) {
|
||||||
i = dwarf_info_section->data_offset;
|
i = dwarf_info_section->data_offset;
|
||||||
|
if (retval == debug_type)
|
||||||
|
retval = i;
|
||||||
dwarf_data1(dwarf_info_section, DWARF_ABBREV_POINTER);
|
dwarf_data1(dwarf_info_section, DWARF_ABBREV_POINTER);
|
||||||
dwarf_data1(dwarf_info_section, PTR_SIZE);
|
dwarf_data1(dwarf_info_section, PTR_SIZE);
|
||||||
dwarf_data4(dwarf_info_section, debug_type - dwarf_info.start);
|
if (last_pos != -1) {
|
||||||
debug_type = i;
|
tcc_debug_check_anon(e, last_pos);
|
||||||
|
write32le(dwarf_info_section->data + last_pos,
|
||||||
|
i - dwarf_info.start);
|
||||||
|
}
|
||||||
|
last_pos = dwarf_info_section->data_offset;
|
||||||
|
e = t->type.ref;
|
||||||
|
dwarf_data4(dwarf_info_section, 0);
|
||||||
}
|
}
|
||||||
else if (type == (VT_PTR | VT_ARRAY)) {
|
else if (type == (VT_PTR | VT_ARRAY)) {
|
||||||
int sib_pos, sub_type;
|
int sib_pos, sub_type;
|
||||||
|
|
@ -1590,8 +1698,17 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s)
|
||||||
|
|
||||||
sub_type = tcc_get_dwarf_info(s1, &sym);
|
sub_type = tcc_get_dwarf_info(s1, &sym);
|
||||||
i = dwarf_info_section->data_offset;
|
i = dwarf_info_section->data_offset;
|
||||||
|
if (retval == debug_type)
|
||||||
|
retval = i;
|
||||||
dwarf_data1(dwarf_info_section, DWARF_ABBREV_ARRAY_TYPE);
|
dwarf_data1(dwarf_info_section, DWARF_ABBREV_ARRAY_TYPE);
|
||||||
dwarf_data4(dwarf_info_section, debug_type - dwarf_info.start);
|
if (last_pos != -1) {
|
||||||
|
tcc_debug_check_anon(e, last_pos);
|
||||||
|
write32le(dwarf_info_section->data + last_pos,
|
||||||
|
i - dwarf_info.start);
|
||||||
|
}
|
||||||
|
last_pos = dwarf_info_section->data_offset;
|
||||||
|
e = t->type.ref;
|
||||||
|
dwarf_data4(dwarf_info_section, 0);
|
||||||
sib_pos = dwarf_info_section->data_offset;
|
sib_pos = dwarf_info_section->data_offset;
|
||||||
dwarf_data4(dwarf_info_section, 0);
|
dwarf_data4(dwarf_info_section, 0);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
@ -1607,16 +1724,66 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s)
|
||||||
dwarf_data1(dwarf_info_section, 0);
|
dwarf_data1(dwarf_info_section, 0);
|
||||||
write32le(dwarf_info_section->data + sib_pos,
|
write32le(dwarf_info_section->data + sib_pos,
|
||||||
dwarf_info_section->data_offset - dwarf_info.start);
|
dwarf_info_section->data_offset - dwarf_info.start);
|
||||||
debug_type = i;
|
|
||||||
}
|
}
|
||||||
else if (type == VT_FUNC) {
|
else if (type == VT_FUNC) {
|
||||||
return tcc_get_dwarf_info (s1, t->type.ref);
|
int sib_pos, *pos_type;
|
||||||
|
Sym *f;
|
||||||
|
|
||||||
|
i = dwarf_info_section->data_offset;
|
||||||
|
debug_type = tcc_get_dwarf_info(s1, t->type.ref);
|
||||||
|
if (retval == debug_type)
|
||||||
|
retval = i;
|
||||||
|
dwarf_data1(dwarf_info_section, DWARF_ABBREV_SUBROUTINE_TYPE);
|
||||||
|
if (last_pos != -1) {
|
||||||
|
tcc_debug_check_anon(e, last_pos);
|
||||||
|
write32le(dwarf_info_section->data + last_pos,
|
||||||
|
i - dwarf_info.start);
|
||||||
|
}
|
||||||
|
last_pos = dwarf_info_section->data_offset;
|
||||||
|
e = t->type.ref;
|
||||||
|
dwarf_data4(dwarf_info_section, 0);
|
||||||
|
sib_pos = dwarf_info_section->data_offset;
|
||||||
|
dwarf_data4(dwarf_info_section, 0);
|
||||||
|
f = t->type.ref;
|
||||||
|
i = 0;
|
||||||
|
while (f->next) {
|
||||||
|
f = f->next;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
pos_type = (int *) tcc_malloc(i * sizeof(int));
|
||||||
|
f = t->type.ref;
|
||||||
|
i = 0;
|
||||||
|
while (f->next) {
|
||||||
|
f = f->next;
|
||||||
|
dwarf_data1(dwarf_info_section, DWARF_ABBREV_FORMAL_PARAMETER2);
|
||||||
|
pos_type[i++] = dwarf_info_section->data_offset;
|
||||||
|
dwarf_data4(dwarf_info_section, 0);
|
||||||
|
}
|
||||||
|
dwarf_data1(dwarf_info_section, 0);
|
||||||
|
write32le(dwarf_info_section->data + sib_pos,
|
||||||
|
dwarf_info_section->data_offset - dwarf_info.start);
|
||||||
|
f = t->type.ref;
|
||||||
|
i = 0;
|
||||||
|
while (f->next) {
|
||||||
|
f = f->next;
|
||||||
|
type = tcc_get_dwarf_info(s1, f);
|
||||||
|
tcc_debug_check_anon(f, pos_type[i]);
|
||||||
|
write32le(dwarf_info_section->data + pos_type[i++],
|
||||||
|
type - dwarf_info.start);
|
||||||
|
}
|
||||||
|
tcc_free(pos_type);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
|
if (last_pos != -1) {
|
||||||
|
tcc_debug_check_anon(e, last_pos);
|
||||||
|
write32le(dwarf_info_section->data + last_pos,
|
||||||
|
debug_type - dwarf_info.start);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
t = t->type.ref;
|
t = t->type.ref;
|
||||||
}
|
}
|
||||||
return debug_type;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcc_debug_finish (TCCState *s1, struct debug_info *cur)
|
static void tcc_debug_finish (TCCState *s1, struct debug_info *cur)
|
||||||
|
|
@ -1787,6 +1954,7 @@ static void tcc_debug_funcend(TCCState *s1, int size)
|
||||||
dwarf_strp(dwarf_info_section, funcname);
|
dwarf_strp(dwarf_info_section, funcname);
|
||||||
dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
|
dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
|
||||||
dwarf_uleb128(dwarf_info_section, dwarf_info.line);
|
dwarf_uleb128(dwarf_info_section, dwarf_info.line);
|
||||||
|
tcc_debug_check_anon(sym->type.ref, dwarf_info_section->data_offset);
|
||||||
dwarf_data4(dwarf_info_section, debug_info - dwarf_info.start);
|
dwarf_data4(dwarf_info_section, debug_info - dwarf_info.start);
|
||||||
dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR);
|
dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR);
|
||||||
#if PTR_SIZE == 4
|
#if PTR_SIZE == 4
|
||||||
|
|
@ -1843,6 +2011,7 @@ static void tcc_debug_extern_sym(TCCState *s1, Sym *sym, int sh_num, int sym_bin
|
||||||
dwarf_strp(dwarf_info_section, get_tok_str(sym->v, NULL));
|
dwarf_strp(dwarf_info_section, get_tok_str(sym->v, NULL));
|
||||||
dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
|
dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
|
||||||
dwarf_uleb128(dwarf_info_section, file->line_num);
|
dwarf_uleb128(dwarf_info_section, file->line_num);
|
||||||
|
tcc_debug_check_anon(sym, dwarf_info_section->data_offset);
|
||||||
dwarf_data4(dwarf_info_section, debug_type - dwarf_info.start);
|
dwarf_data4(dwarf_info_section, debug_type - dwarf_info.start);
|
||||||
if (sym_bind == STB_GLOBAL)
|
if (sym_bind == STB_GLOBAL)
|
||||||
dwarf_data1(dwarf_info_section, 1);
|
dwarf_data1(dwarf_info_section, 1);
|
||||||
|
|
@ -1888,6 +2057,7 @@ static void tcc_debug_typedef(TCCState *s1, Sym *sym)
|
||||||
dwarf_strp(dwarf_info_section, get_tok_str(sym->v & ~SYM_FIELD, NULL));
|
dwarf_strp(dwarf_info_section, get_tok_str(sym->v & ~SYM_FIELD, NULL));
|
||||||
dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
|
dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
|
||||||
dwarf_uleb128(dwarf_info_section, file->line_num);
|
dwarf_uleb128(dwarf_info_section, file->line_num);
|
||||||
|
tcc_debug_check_anon(sym, dwarf_info_section->data_offset);
|
||||||
dwarf_data4(dwarf_info_section, debug_type - dwarf_info.start);
|
dwarf_data4(dwarf_info_section, debug_type - dwarf_info.start);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
@ -6106,6 +6276,8 @@ do_decl:
|
||||||
check_fields(type, 1);
|
check_fields(type, 1);
|
||||||
check_fields(type, 0);
|
check_fields(type, 0);
|
||||||
struct_layout(type, &ad);
|
struct_layout(type, &ad);
|
||||||
|
if (debug_modes)
|
||||||
|
tcc_debug_fix_anon(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
25
tccrun.c
25
tccrun.c
|
|
@ -754,14 +754,14 @@ next:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
while ((i = DW_GETC(ln, end))) {
|
while ((DW_GETC(ln, end))) {
|
||||||
#if 0
|
#if 0
|
||||||
if (++dir_size < DIR_TABLE_SIZE)
|
if (++dir_size < DIR_TABLE_SIZE)
|
||||||
dirs[dir_size - 1] = (char *)ln - 1;
|
dirs[dir_size - 1] = (char *)ln - 1;
|
||||||
#endif
|
#endif
|
||||||
while (DW_GETC(ln, end)) {}
|
while (DW_GETC(ln, end)) {}
|
||||||
}
|
}
|
||||||
while ((i = DW_GETC(ln, end))) {
|
while ((DW_GETC(ln, end))) {
|
||||||
if (++filename_size < FILE_TABLE_SIZE) {
|
if (++filename_size < FILE_TABLE_SIZE) {
|
||||||
filename_table[filename_size - 1].name = (char *)ln - 1;
|
filename_table[filename_size - 1].name = (char *)ln - 1;
|
||||||
while (DW_GETC(ln, end)) {}
|
while (DW_GETC(ln, end)) {}
|
||||||
|
|
@ -776,6 +776,8 @@ next:
|
||||||
dwarf_read_uleb128(&ln, end); // size
|
dwarf_read_uleb128(&ln, end); // size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (filename_size >= 2)
|
||||||
|
filename = filename_table[1].name;
|
||||||
while (ln < end) {
|
while (ln < end) {
|
||||||
last_pc = pc;
|
last_pc = pc;
|
||||||
switch (DW_GETC(ln, end)) {
|
switch (DW_GETC(ln, end)) {
|
||||||
|
|
@ -790,14 +792,27 @@ next:
|
||||||
goto next_line;
|
goto next_line;
|
||||||
case DW_LNE_set_address:
|
case DW_LNE_set_address:
|
||||||
#if PTR_SIZE == 4
|
#if PTR_SIZE == 4
|
||||||
dwarf_read_32(&cp, end);
|
pc = dwarf_read_32(&cp, end);
|
||||||
#else
|
#else
|
||||||
dwarf_read_64(&cp, end);
|
pc = dwarf_read_64(&cp, end);
|
||||||
#endif
|
#endif
|
||||||
pc = rc->dwarf_text;
|
if (rc->num_callers < 0)
|
||||||
|
pc = rc->dwarf_text; /* dll */
|
||||||
opindex = 0;
|
opindex = 0;
|
||||||
break;
|
break;
|
||||||
case DW_LNE_define_file: /* deprecated */
|
case DW_LNE_define_file: /* deprecated */
|
||||||
|
if (++filename_size < FILE_TABLE_SIZE) {
|
||||||
|
filename_table[filename_size - 1].name = (char *)ln - 1;
|
||||||
|
while (DW_GETC(ln, end)) {}
|
||||||
|
filename_table[filename_size - 1].dir_entry =
|
||||||
|
dwarf_read_uleb128(&ln, end);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while (DW_GETC(ln, end)) {}
|
||||||
|
dwarf_read_uleb128(&ln, end);
|
||||||
|
}
|
||||||
|
dwarf_read_uleb128(&ln, end); // time
|
||||||
|
dwarf_read_uleb128(&ln, end); // size
|
||||||
break;
|
break;
|
||||||
case DW_LNE_set_discriminator:
|
case DW_LNE_set_discriminator:
|
||||||
dwarf_read_uleb128(&cp, end);
|
dwarf_read_uleb128(&cp, end);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue