| @@ -310,6 +310,14 @@ static const unsigned char dwarf_line_opcodes[] = { · 309 unmodified lines |
| 310 | 310 | /* ------------------------------------------------------------------------- */ |
| 311 | 311 | /* debug state */ |
| 312 | 312 | |
| 313 | +#define N_STR_HASH (251) |
| 314 | + |
| 315 | +struct dwarf_str_hash { |
| 316 | + int len; |
| 317 | + unsigned long data_offset; |
| 318 | + struct dwarf_str_hash *next; |
| 319 | +}; |
| 320 | + |
| 313 | 321 | struct _tccdbg { |
| 314 | 322 | |
| 315 | 323 | int last_line_num, new_file; |
| @@ -320,20 +328,25 @@ struct _tccdbg { · 4 unmodified lines |
| 320 | 328 | struct _debug_hash { |
| 321 | 329 | int debug_type; |
| 322 | 330 | Sym *type; |
| 323 | | − } *debug_hash; |
| 331 | + } *debug_hash_global, *debug_hash_local; |
| 324 | 332 | |
| 325 | | − struct _debug_anon_hash { |
| 333 | + /* store forward structure/unions types */ |
| 334 | + struct _debug_forw_hash { |
| 326 | 335 | Sym *type; |
| 327 | 336 | int n_debug_type; |
| 328 | 337 | int *debug_type; |
| 329 | | − } *debug_anon_hash; |
| 338 | + } *debug_forw_hash_global, *debug_forw_hash_local; |
| 330 | 339 | |
| 331 | | − int n_debug_hash; |
| 332 | | − int n_debug_anon_hash; |
| 340 | + int n_debug_hash_global; |
| 341 | + int n_debug_hash_local; |
| 342 | + int n_debug_forw_hash_global; |
| 343 | + int n_debug_forw_hash_local; |
| 333 | 344 | |
| 334 | 345 | struct _debug_info { |
| 335 | 346 | int start; |
| 336 | 347 | int end; |
| 348 | + int last_debug_hash; |
| 349 | + int last_debug_forw_hash; |
| 337 | 350 | int n_sym; |
| 338 | 351 | struct debug_sym { |
| 339 | 352 | int type; |
| @@ -381,6 +394,9 @@ struct _tccdbg { · 41 unmodified lines |
| 381 | 394 | int base_type_used[N_DEFAULT_DEBUG]; |
| 382 | 395 | } dwarf_info; |
| 383 | 396 | |
| 397 | + struct dwarf_str_hash *dwarf_str[N_STR_HASH]; |
| 398 | + struct dwarf_str_hash *dwarf_line_str[N_STR_HASH]; |
| 399 | + |
| 384 | 400 | /* test coverage */ |
| 385 | 401 | struct { |
| 386 | 402 | unsigned long offset; |
| @@ -389,23 +405,28 @@ struct _tccdbg { · 2 unmodified lines |
| 389 | 405 | int ind; |
| 390 | 406 | int line; |
| 391 | 407 | } tcov_data; |
| 392 | | − |
| 393 | 408 | }; |
| 394 | 409 | |
| 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 | +#define last_line_num s1->dState->last_line_num |
| 411 | +#define new_file s1->dState->new_file |
| 412 | +#define section_sym s1->dState->section_sym |
| 413 | +#define debug_next_type s1->dState->debug_next_type |
| 414 | +#define debug_hash_global s1->dState->debug_hash_global |
| 415 | +#define debug_hash_local s1->dState->debug_hash_local |
| 416 | +#define debug_forw_hash_global s1->dState->debug_forw_hash_global |
| 417 | +#define debug_forw_hash_local s1->dState->debug_forw_hash_local |
| 418 | +#define n_debug_hash_global s1->dState->n_debug_hash_global |
| 419 | +#define n_debug_hash_local s1->dState->n_debug_hash_local |
| 420 | +#define n_debug_forw_hash_global s1->dState->n_debug_forw_hash_global |
| 421 | +#define n_debug_forw_hash_local s1->dState->n_debug_forw_hash_local |
| 422 | +#define debug_info s1->dState->debug_info |
| 423 | +#define debug_info_root s1->dState->debug_info_root |
| 424 | +#define dwarf_sym s1->dState->dwarf_sym |
| 425 | +#define dwarf_line s1->dState->dwarf_line |
| 426 | +#define dwarf_info s1->dState->dwarf_info |
| 427 | +#define dwarf_str s1->dState->dwarf_str |
| 428 | +#define dwarf_line_str s1->dState->dwarf_line_str |
| 429 | +#define tcov_data s1->dState->tcov_data |
| 409 | 430 | |
| 410 | 431 | #define FDE_ENCODING (DW_EH_PE_udata4 | DW_EH_PE_signed | DW_EH_PE_pcrel) |
| 411 | 432 | |
| @@ -533,19 +554,46 @@ static void dwarf_reloc(Section *s, int sym, int rel) · 121 unmodified lines |
| 533 | 554 | put_elf_reloca(symtab_section, s, s->data_offset, rel, sym, 0); |
| 534 | 555 | } |
| 535 | 556 | |
| 557 | +static unsigned str_hash(const char *s) |
| 558 | +{ |
| 559 | + unsigned h = 5381; |
| 560 | + |
| 561 | + while (*s) |
| 562 | + h += (*s++ & 0xffu) + h * 31; |
| 563 | + return h; |
| 564 | +} |
| 565 | + |
| 536 | 566 | static void dwarf_string(Section *s, Section *dw, int sym, const char *str) |
| 537 | 567 | { |
| 538 | 568 | TCCState *s1 = s->s1; |
| 539 | | − int offset, len; |
| 569 | + int len, hash = str_hash(str) % N_STR_HASH; |
| 540 | 570 | char *ptr; |
| 571 | + struct dwarf_str_hash *new_hash; |
| 572 | + struct dwarf_str_hash **dw_hash = |
| 573 | + dw == dwarf_str_section ? dwarf_str : dwarf_line_str; |
| 541 | 574 | |
| 542 | 575 | len = strlen(str) + 1; |
| 543 | | − offset = dw->data_offset; |
| 544 | | − ptr = section_ptr_add(dw, len); |
| 545 | | − memmove(ptr, str, len); |
| 576 | + new_hash = dw_hash[hash]; |
| 577 | + while (new_hash) { |
| 578 | + if (new_hash->len == len && |
| 579 | + !memcmp(str, dw->data + new_hash->data_offset, len)) |
| 580 | + break; |
| 581 | + new_hash = new_hash->next; |
| 582 | + } |
| 583 | + if (new_hash == NULL) { |
| 584 | + new_hash = (struct dwarf_str_hash *) |
| 585 | + tcc_malloc(sizeof(struct dwarf_str_hash)); |
| 586 | + new_hash->len = len; |
| 587 | + new_hash->data_offset = dw->data_offset; |
| 588 | + new_hash->next = dw_hash[hash]; |
| 589 | + dw_hash[hash] = new_hash; |
| 590 | + ptr = section_ptr_add(dw, len); |
| 591 | + memmove(ptr, str, len); |
| 592 | + } |
| 593 | + else |
| 546 | 594 | put_elf_reloca(symtab_section, s, s->data_offset, R_DATA_32DW, sym, |
| 547 | | − PTR_SIZE == 4 ? 0 : offset); |
| 548 | | − dwarf_data4(s, PTR_SIZE == 4 ? offset : 0); |
| 595 | + PTR_SIZE == 4 ? 0 : new_hash->data_offset); |
| 596 | + dwarf_data4(s, PTR_SIZE == 4 ? new_hash->data_offset : 0); |
| 549 | 597 | } |
| 550 | 598 | |
| 551 | 599 | static void dwarf_strp(Section *s, const char *str) |
| @@ -1031,10 +1079,14 @@ ST_FUNC void tcc_debug_start(TCCState *s1) · 479 unmodified lines |
| 1031 | 1079 | |
| 1032 | 1080 | new_file = last_line_num = 0; |
| 1033 | 1081 | debug_next_type = N_DEFAULT_DEBUG; |
| 1034 | | − debug_hash = NULL; |
| 1035 | | − debug_anon_hash = NULL; |
| 1036 | | − n_debug_hash = 0; |
| 1037 | | − n_debug_anon_hash = 0; |
| 1082 | + debug_hash_global = NULL; |
| 1083 | + debug_hash_local = NULL; |
| 1084 | + debug_forw_hash_global = NULL; |
| 1085 | + debug_forw_hash_local = NULL; |
| 1086 | + n_debug_hash_global = 0; |
| 1087 | + n_debug_hash_local = 0; |
| 1088 | + n_debug_forw_hash_global = 0; |
| 1089 | + n_debug_forw_hash_local = 0; |
| 1038 | 1090 | |
| 1039 | 1091 | getcwd(buf, sizeof(buf)); |
| 1040 | 1092 | #ifdef _WIN32 |
| @@ -1192,9 +1244,13 @@ ST_FUNC void tcc_debug_start(TCCState *s1) · 151 unmodified lines |
| 1192 | 1244 | } |
| 1193 | 1245 | } |
| 1194 | 1246 | |
| 1247 | +static void fix_debug_forw_hash(TCCState *s1, int global, int start); |
| 1248 | + |
| 1195 | 1249 | /* put end of translation unit info */ |
| 1196 | 1250 | ST_FUNC void tcc_debug_end(TCCState *s1) |
| 1197 | 1251 | { |
| 1252 | + int i; |
| 1253 | + |
| 1198 | 1254 | if (!s1->do_debug || debug_next_type == 0) |
| 1199 | 1255 | return; |
| 1200 | 1256 | |
| @@ -1202,32 +1258,13 @@ ST_FUNC void tcc_debug_end(TCCState *s1) · 1 unmodified line |
| 1202 | 1258 | tcc_debug_funcend(s1, 0); /* free stuff in case of errors */ |
| 1203 | 1259 | |
| 1204 | 1260 | if (s1->dwarf) { |
| 1205 | | − int i, j; |
| 1206 | 1261 | int start_aranges; |
| 1207 | 1262 | unsigned char *ptr; |
| 1208 | 1263 | int text_size = text_section->data_offset; |
| 1209 | 1264 | |
| 1210 | 1265 | /* dwarf_info */ |
| 1211 | | − for (i = 0; i < n_debug_anon_hash; i++) { |
| 1212 | | − Sym *t = debug_anon_hash[i].type; |
| 1213 | | − int pos = dwarf_info_section->data_offset; |
| 1214 | | − |
| 1215 | | − dwarf_data1(dwarf_info_section, |
| 1216 | | − IS_UNION (t->type.t) ? DWARF_ABBREV_UNION_EMPTY_TYPE |
| 1217 | | − : DWARF_ABBREV_STRUCTURE_EMPTY_TYPE); |
| 1218 | | − dwarf_strp(dwarf_info_section, |
| 1219 | | − (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM |
| 1220 | | − ? "" : get_tok_str(t->v, NULL)); |
| 1221 | | − dwarf_uleb128(dwarf_info_section, 0); |
| 1222 | | − dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file); |
| 1223 | | − dwarf_uleb128(dwarf_info_section, file->line_num); |
| 1224 | | − for (j = 0; j < debug_anon_hash[i].n_debug_type; j++) |
| 1225 | | − write32le(dwarf_info_section->data + |
| 1226 | | − debug_anon_hash[i].debug_type[j], |
| 1227 | | − pos - dwarf_info.start); |
| 1228 | | − tcc_free (debug_anon_hash[i].debug_type); |
| 1229 | | − } |
| 1230 | | − tcc_free (debug_anon_hash); |
| 1266 | + fix_debug_forw_hash(s1, 0, 0); |
| 1267 | + fix_debug_forw_hash(s1, 1, 0); |
| 1231 | 1268 | dwarf_data1(dwarf_info_section, 0); |
| 1232 | 1269 | ptr = dwarf_info_section->data + dwarf_info.start; |
| 1233 | 1270 | write32le(ptr, dwarf_info_section->data_offset - dwarf_info.start - 4); |
| @@ -1328,7 +1365,22 @@ ST_FUNC void tcc_debug_end(TCCState *s1) · 94 unmodified lines |
| 1328 | 1365 | put_stabs_r(s1, NULL, N_SO, 0, 0, |
| 1329 | 1366 | text_section->data_offset, text_section, section_sym); |
| 1330 | 1367 | } |
| 1331 | | − tcc_free(debug_hash); |
| 1368 | + for (i = 0; i < N_STR_HASH; i++) { |
| 1369 | + while (dwarf_str[i]) { |
| 1370 | + struct dwarf_str_hash *next = dwarf_str[i]->next; |
| 1371 | + tcc_free(dwarf_str[i]); |
| 1372 | + dwarf_str[i] = next; |
| 1373 | + } |
| 1374 | + while (dwarf_line_str[i]) { |
| 1375 | + struct dwarf_str_hash *next = dwarf_line_str[i]->next; |
| 1376 | + tcc_free(dwarf_line_str[i]); |
| 1377 | + dwarf_line_str[i] = next; |
| 1378 | + } |
| 1379 | + } |
| 1380 | + tcc_free (debug_forw_hash_global); |
| 1381 | + tcc_free (debug_forw_hash_local); |
| 1382 | + tcc_free(debug_hash_global); |
| 1383 | + tcc_free(debug_hash_local); |
| 1332 | 1384 | debug_next_type = 0; |
| 1333 | 1385 | } |
| 1334 | 1386 | |
| @@ -1473,6 +1525,36 @@ static void tcc_debug_stabs (TCCState *s1, const char *str, int type, unsigned l · 138 unmodified lines |
| 1473 | 1525 | put_stabs (s1, str, type, 0, 0, value); |
| 1474 | 1526 | } |
| 1475 | 1527 | |
| 1528 | +static void fix_debug_forw_hash(TCCState *s1, int global, int start) |
| 1529 | +{ |
| 1530 | + if (s1->dwarf) { |
| 1531 | + int i, j, n_hash = global |
| 1532 | + ? n_debug_forw_hash_global : n_debug_forw_hash_local; |
| 1533 | + struct _debug_forw_hash *hash = global |
| 1534 | + ? debug_forw_hash_global : debug_forw_hash_local; |
| 1535 | + |
| 1536 | + for (i = start; i < n_hash; i++) { |
| 1537 | + Sym *t = hash[i].type; |
| 1538 | + int pos = dwarf_info_section->data_offset; |
| 1539 | + |
| 1540 | + dwarf_data1(dwarf_info_section, |
| 1541 | + IS_UNION (t->type.t) ? DWARF_ABBREV_UNION_EMPTY_TYPE |
| 1542 | + : DWARF_ABBREV_STRUCTURE_EMPTY_TYPE); |
| 1543 | + dwarf_strp(dwarf_info_section, |
| 1544 | + (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM |
| 1545 | + ? "" : get_tok_str(t->v, NULL)); |
| 1546 | + dwarf_uleb128(dwarf_info_section, 0); |
| 1547 | + dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file); |
| 1548 | + dwarf_uleb128(dwarf_info_section, file->line_num); |
| 1549 | + for (j = 0; j < hash[i].n_debug_type; j++) |
| 1550 | + write32le(dwarf_info_section->data + |
| 1551 | + hash[i].debug_type[j], |
| 1552 | + pos - dwarf_info.start); |
| 1553 | + tcc_free (hash[i].debug_type); |
| 1554 | + } |
| 1555 | + } |
| 1556 | +} |
| 1557 | + |
| 1476 | 1558 | ST_FUNC void tcc_debug_stabn(TCCState *s1, int type, int value) |
| 1477 | 1559 | { |
| 1478 | 1560 | if (!s1->do_debug) |
| @@ -1482,6 +1564,8 @@ ST_FUNC void tcc_debug_stabn(TCCState *s1, int type, int value) · 3 unmodified lines |
| 1482 | 1564 | (struct _debug_info *) tcc_mallocz(sizeof (*info)); |
| 1483 | 1565 | |
| 1484 | 1566 | info->start = value; |
| 1567 | + info->last_debug_hash = n_debug_hash_local; |
| 1568 | + info->last_debug_forw_hash = n_debug_forw_hash_local; |
| 1485 | 1569 | info->parent = debug_info; |
| 1486 | 1570 | if (debug_info) { |
| 1487 | 1571 | if (debug_info->child) { |
| @@ -1499,101 +1583,127 @@ ST_FUNC void tcc_debug_stabn(TCCState *s1, int type, int value) · 11 unmodified lines |
| 1499 | 1583 | debug_info = info; |
| 1500 | 1584 | } |
| 1501 | 1585 | else { |
| 1586 | + fix_debug_forw_hash(s1, 0, debug_info->last_debug_forw_hash); |
| 1587 | + n_debug_hash_local = debug_info->last_debug_hash; |
| 1588 | + n_debug_forw_hash_local = debug_info->last_debug_forw_hash; |
| 1502 | 1589 | debug_info->end = value; |
| 1503 | 1590 | debug_info = debug_info->parent; |
| 1504 | 1591 | } |
| 1505 | 1592 | } |
| 1506 | 1593 | |
| 1507 | | −static int tcc_debug_find(TCCState *s1, Sym *t, int dwarf) |
| 1594 | +static int check_global(Sym *t) |
| 1508 | 1595 | { |
| 1509 | | − int i; |
| 1596 | + Sym *g = local_stack; |
| 1510 | 1597 | |
| 1511 | | − if (!debug_info && dwarf && |
| 1512 | | − (t->type.t & VT_BTYPE) == VT_STRUCT && t->c == -1) { |
| 1513 | | − for (i = 0; i < n_debug_anon_hash; i++) |
| 1514 | | − if (t == debug_anon_hash[i].type) |
| 1598 | + while (g) { |
| 1599 | + if (t == g) |
| 1600 | + return 0; |
| 1601 | + g = g->prev; |
| 1602 | + } |
| 1603 | + return 1; |
| 1604 | +} |
| 1605 | + |
| 1606 | +static int tcc_debug_find(TCCState *s1, Sym *t, int dwarf) |
| 1607 | +{ |
| 1608 | + int i , g = check_global(t); |
| 1609 | + int n_hash, *n_forw_hash; |
| 1610 | + struct _debug_hash *hash; |
| 1611 | + struct _debug_forw_hash **forw_hash; |
| 1612 | + |
| 1613 | + if ((t->type.t & VT_BTYPE) == VT_STRUCT && t->c == -1) { |
| 1614 | + forw_hash = g ? &debug_forw_hash_global : &debug_forw_hash_local; |
| 1615 | + n_forw_hash = g ? &n_debug_forw_hash_global : &n_debug_forw_hash_local; |
| 1616 | + for (i = 0; i < *n_forw_hash; i++) |
| 1617 | + if (t == (*forw_hash)[i].type) |
| 1515 | 1618 | return 0; |
| 1516 | | − debug_anon_hash = (struct _debug_anon_hash *) |
| 1517 | | − tcc_realloc (debug_anon_hash, |
| 1518 | | − (n_debug_anon_hash + 1) * sizeof(*debug_anon_hash)); |
| 1519 | | − debug_anon_hash[n_debug_anon_hash].n_debug_type = 0; |
| 1520 | | − debug_anon_hash[n_debug_anon_hash].debug_type = NULL; |
| 1521 | | − debug_anon_hash[n_debug_anon_hash++].type = t; |
| 1619 | + *forw_hash = (struct _debug_forw_hash *) |
| 1620 | + tcc_realloc (*forw_hash, |
| 1621 | + (*n_forw_hash + 1) * sizeof(**forw_hash)); |
| 1622 | + (*forw_hash)[*n_forw_hash].n_debug_type = 0; |
| 1623 | + (*forw_hash)[*n_forw_hash].debug_type = NULL; |
| 1624 | + (*forw_hash)[(*n_forw_hash)++].type = t; |
| 1522 | 1625 | return 0; |
| 1523 | 1626 | } |
| 1524 | | − for (i = 0; i < n_debug_hash; i++) |
| 1525 | | − if (t == debug_hash[i].type) |
| 1526 | | − return debug_hash[i].debug_type; |
| 1627 | + hash = g ? debug_hash_global : debug_hash_local; |
| 1628 | + n_hash = g ? n_debug_hash_global : n_debug_hash_local; |
| 1629 | + for (i = 0; i < n_hash; i++) |
| 1630 | + if (t == hash[i].type) |
| 1631 | + return hash[i].debug_type; |
| 1527 | 1632 | return -1; |
| 1528 | 1633 | } |
| 1529 | 1634 | |
| 1530 | 1635 | static int tcc_get_dwarf_info(TCCState *s1, Sym *s); |
| 1531 | 1636 | |
| 1532 | | −static void tcc_debug_check_anon(TCCState *s1, Sym *t, int debug_type) |
| 1637 | +static void tcc_debug_check_forw(TCCState *s1, Sym *t, int debug_type) |
| 1533 | 1638 | { |
| 1534 | | − int i; |
| 1535 | | − |
| 1536 | | − if (!debug_info && (t->type.t & VT_BTYPE) == VT_STRUCT && t->type.ref->c == -1) |
| 1537 | | − for (i = 0; i < n_debug_anon_hash; i++) |
| 1538 | | − if (t->type.ref == debug_anon_hash[i].type) { |
| 1539 | | − debug_anon_hash[i].debug_type = |
| 1540 | | − tcc_realloc(debug_anon_hash[i].debug_type, |
| 1541 | | − (debug_anon_hash[i].n_debug_type + 1) * sizeof(int)); |
| 1542 | | − debug_anon_hash[i].debug_type[debug_anon_hash[i].n_debug_type++] = |
| 1543 | | − debug_type; |
| 1544 | | − } |
| 1639 | + if ((t->type.t & VT_BTYPE) == VT_STRUCT && t->type.ref->c == -1) { |
| 1640 | + int i, j, g = check_global(t); |
| 1641 | + int n_forw_hash; |
| 1642 | + struct _debug_forw_hash **forw_hash; |
| 1643 | + |
| 1644 | + for (i = g; i <= 1; i++) { |
| 1645 | + forw_hash = i ? &debug_forw_hash_global : &debug_forw_hash_local; |
| 1646 | + n_forw_hash = i ? n_debug_forw_hash_global : n_debug_forw_hash_local; |
| 1647 | + for (j = 0; j < n_forw_hash; j++) |
| 1648 | + if (t->type.ref == (*forw_hash)[j].type) { |
| 1649 | + (*forw_hash)[j].debug_type = |
| 1650 | + tcc_realloc((*forw_hash)[j].debug_type, |
| 1651 | + ((*forw_hash)[j].n_debug_type + 1) * sizeof(int)); |
| 1652 | + (*forw_hash)[j].debug_type[(*forw_hash)[j].n_debug_type++] = |
| 1653 | + debug_type; |
| 1654 | + return; |
| 1655 | + } |
| 1656 | + } |
| 1657 | + } |
| 1545 | 1658 | } |
| 1546 | 1659 | |
| 1547 | | −ST_FUNC void tcc_debug_fix_anon(TCCState *s1, CType *t) |
| 1660 | +ST_FUNC void tcc_debug_fix_forw(TCCState *s1, CType *t) |
| 1548 | 1661 | { |
| 1549 | | − int i, j, debug_type; |
| 1550 | | − |
| 1551 | | − if (!(s1->do_debug & 2) || !s1->dwarf || debug_info) |
| 1662 | + if (!(s1->do_debug & 2)) |
| 1552 | 1663 | return; |
| 1553 | 1664 | |
| 1554 | | − if ((t->t & VT_BTYPE) == VT_STRUCT && t->ref->c != -1) |
| 1555 | | − for (i = 0; i < n_debug_anon_hash; i++) |
| 1556 | | − if (t->ref == debug_anon_hash[i].type) { |
| 1557 | | − Sym sym = {0}; sym .type = *t ; |
| 1558 | | − |
| 1559 | | − /* Trick to not hash this struct */ |
| 1560 | | − debug_info = (struct _debug_info *) t; |
| 1561 | | − debug_type = tcc_get_dwarf_info(s1, &sym); |
| 1562 | | − debug_info = NULL; |
| 1563 | | − for (j = 0; j < debug_anon_hash[i].n_debug_type; j++) |
| 1564 | | − write32le(dwarf_info_section->data + |
| 1565 | | − debug_anon_hash[i].debug_type[j], |
| 1566 | | − debug_type - dwarf_info.start); |
| 1567 | | − tcc_free(debug_anon_hash[i].debug_type); |
| 1568 | | − n_debug_anon_hash--; |
| 1569 | | − for (; i < n_debug_anon_hash; i++) |
| 1570 | | − debug_anon_hash[i] = debug_anon_hash[i + 1]; |
| 1665 | + if ((t->t & VT_BTYPE) == VT_STRUCT && t->ref->c != -1) { |
| 1666 | + int i, j, debug_type, g = check_global(t->ref); |
| 1667 | + int *n_forw_hash; |
| 1668 | + struct _debug_forw_hash **forw_hash; |
| 1669 | + |
| 1670 | + forw_hash = g ? &debug_forw_hash_global : &debug_forw_hash_local; |
| 1671 | + n_forw_hash = g ? &n_debug_forw_hash_global : &n_debug_forw_hash_local; |
| 1672 | + for (i = 0; i < *n_forw_hash; i++) |
| 1673 | + if (t->ref == (*forw_hash)[i].type) { |
| 1674 | + if (s1->dwarf) { |
| 1675 | + Sym sym = {0}; sym .type = *t ; |
| 1676 | + |
| 1677 | + debug_type = tcc_get_dwarf_info(s1, &sym); |
| 1678 | + for (j = 0; j < (*forw_hash)[i].n_debug_type; j++) |
| 1679 | + write32le(dwarf_info_section->data + |
| 1680 | + (*forw_hash)[i].debug_type[j], |
| 1681 | + debug_type - dwarf_info.start); |
| 1682 | + tcc_free((*forw_hash)[i].debug_type); |
| 1683 | + } |
| 1684 | + (*n_forw_hash)--; |
| 1685 | + for (; i < *n_forw_hash; i++) |
| 1686 | + (*forw_hash)[i] = (*forw_hash)[i + 1]; |
| 1571 | 1687 | } |
| 1688 | + } |
| 1572 | 1689 | } |
| 1573 | 1690 | |
| 1574 | 1691 | static int tcc_debug_add(TCCState *s1, Sym *t, int dwarf) |
| 1575 | 1692 | { |
| 1576 | 1693 | int offset = dwarf ? dwarf_info_section->data_offset : ++debug_next_type; |
| 1577 | | − debug_hash = (struct _debug_hash *) |
| 1578 | | − tcc_realloc (debug_hash, |
| 1579 | | − (n_debug_hash + 1) * sizeof(*debug_hash)); |
| 1580 | | − debug_hash[n_debug_hash].debug_type = offset; |
| 1581 | | − debug_hash[n_debug_hash++].type = t; |
| 1694 | + int *n_hash, g = check_global(t); |
| 1695 | + struct _debug_hash **hash; |
| 1696 | + |
| 1697 | + hash = g ? &debug_hash_global : &debug_hash_local; |
| 1698 | + n_hash = g ? &n_debug_hash_global : &n_debug_hash_local; |
| 1699 | + *hash = (struct _debug_hash *) |
| 1700 | + tcc_realloc (*hash, |
| 1701 | + (*n_hash + 1) * sizeof(**hash)); |
| 1702 | + (*hash)[*n_hash].debug_type = offset; |
| 1703 | + (*hash)[(*n_hash)++].type = t; |
| 1582 | 1704 | return offset; |
| 1583 | 1705 | } |
| 1584 | 1706 | |
| 1585 | | −static void tcc_debug_remove(TCCState *s1, Sym *t) |
| 1586 | | −{ |
| 1587 | | − int i; |
| 1588 | | − |
| 1589 | | − for (i = 0; i < n_debug_hash; i++) |
| 1590 | | − if (t == debug_hash[i].type) { |
| 1591 | | − n_debug_hash--; |
| 1592 | | − for (; i < n_debug_hash; i++) |
| 1593 | | − debug_hash[i] = debug_hash[i+1]; |
| 1594 | | − } |
| 1595 | | −} |
| 1596 | | − |
| 1597 | 1707 | #define STRUCT_NODEBUG(s) \ |
| 1598 | 1708 | (s->a.nodebug || \ |
| 1599 | 1709 | ((s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM && \ |
| @@ -1621,11 +1731,9 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 21 unmodified lines |
| 1621 | 1731 | break; |
| 1622 | 1732 | } |
| 1623 | 1733 | if ((type & VT_BTYPE) == VT_STRUCT) { |
| 1624 | | − Sym *e = t; |
| 1625 | | − |
| 1626 | 1734 | t = t->type.ref; |
| 1627 | 1735 | debug_type = tcc_debug_find(s1, t, 0); |
| 1628 | | − if (debug_type == -1 && t->c >= 0) { |
| 1736 | + if (debug_type == -1) { |
| 1629 | 1737 | debug_type = tcc_debug_add(s1, t, 0); |
| 1630 | 1738 | cstr_new (&str); |
| 1631 | 1739 | cstr_printf (&str, "%s:T%d=%c%d", |
| @@ -1640,6 +1748,7 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 8 unmodified lines |
| 1640 | 1748 | t = t->next; |
| 1641 | 1749 | if (STRUCT_NODEBUG(t)) |
| 1642 | 1750 | continue; |
| 1751 | + tcc_debug_check_forw(s1, t, -1); |
| 1643 | 1752 | cstr_printf (&str, "%s:", |
| 1644 | 1753 | get_tok_str(t->v, NULL)); |
| 1645 | 1754 | tcc_get_debug_info (s1, t, &str); |
| @@ -1656,15 +1765,13 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 10 unmodified lines |
| 1656 | 1765 | cstr_printf (&str, ";"); |
| 1657 | 1766 | tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0); |
| 1658 | 1767 | cstr_free (&str); |
| 1659 | | − if (debug_info) |
| 1660 | | − tcc_debug_remove(s1, e); |
| 1661 | 1768 | } |
| 1662 | 1769 | } |
| 1663 | 1770 | else if (IS_ENUM(type)) { |
| 1664 | 1771 | Sym *e = t = t->type.ref; |
| 1665 | 1772 | |
| 1666 | 1773 | debug_type = tcc_debug_find(s1, t, 0); |
| 1667 | | − if (debug_type == -1 && t->c >= 0) { |
| 1774 | + if (debug_type == -1) { |
| 1668 | 1775 | debug_type = tcc_debug_add(s1, t, 0); |
| 1669 | 1776 | cstr_new (&str); |
| 1670 | 1777 | cstr_printf (&str, "%s:T%d=e", |
| @@ -1682,8 +1789,6 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 11 unmodified lines |
| 1682 | 1789 | cstr_printf (&str, ";"); |
| 1683 | 1790 | tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0); |
| 1684 | 1791 | cstr_free (&str); |
| 1685 | | − if (debug_info) |
| 1686 | | − tcc_debug_remove(s1, e); |
| 1687 | 1792 | } |
| 1688 | 1793 | } |
| 1689 | 1794 | else if ((type & VT_BTYPE) != VT_FUNC) { |
| @@ -1713,6 +1818,7 @@ static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) · 23 unmodified lines |
| 1713 | 1818 | } |
| 1714 | 1819 | else |
| 1715 | 1820 | break; |
| 1821 | + tcc_debug_check_forw(s1, t, -1); |
| 1716 | 1822 | t = t->type.ref; |
| 1717 | 1823 | } |
| 1718 | 1824 | cstr_printf (result, "%d", debug_type); |
| @@ -1741,7 +1847,7 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s) · 22 unmodified lines |
| 1741 | 1847 | if ((type & VT_BTYPE) == VT_STRUCT) { |
| 1742 | 1848 | t = t->type.ref; |
| 1743 | 1849 | debug_type = tcc_debug_find(s1, t, 1); |
| 1744 | | − if (debug_type == -1 && t->c >= 0) { |
| 1850 | + if (debug_type == -1) { |
| 1745 | 1851 | int pos_sib = 0, i, *pos_type; |
| 1746 | 1852 | |
| 1747 | 1853 | debug_type = tcc_debug_add(s1, t, 1); |
| @@ -1807,19 +1913,17 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s) · 59 unmodified lines |
| 1807 | 1913 | if (STRUCT_NODEBUG(e)) |
| 1808 | 1914 | continue; |
| 1809 | 1915 | type = tcc_get_dwarf_info(s1, e); |
| 1810 | | − tcc_debug_check_anon(s1, e, pos_type[i]); |
| 1916 | + tcc_debug_check_forw(s1, e, pos_type[i]); |
| 1811 | 1917 | write32le(dwarf_info_section->data + pos_type[i++], |
| 1812 | 1918 | type - dwarf_info.start); |
| 1813 | 1919 | } |
| 1814 | 1920 | tcc_free(pos_type); |
| 1815 | | − if (debug_info) |
| 1816 | | − tcc_debug_remove(s1, t); |
| 1817 | 1921 | } |
| 1818 | 1922 | } |
| 1819 | 1923 | else if (IS_ENUM(type)) { |
| 1820 | 1924 | t = t->type.ref; |
| 1821 | 1925 | debug_type = tcc_debug_find(s1, t, 1); |
| 1822 | | − if (debug_type == -1 && t->c >= 0) { |
| 1926 | + if (debug_type == -1) { |
| 1823 | 1927 | int pos_sib, pos_type; |
| 1824 | 1928 | Sym sym = {0}; sym.type.t = VT_INT | (type & VT_UNSIGNED); |
| 1825 | 1929 | |
| @@ -1854,8 +1958,6 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s) · 28 unmodified lines |
| 1854 | 1958 | dwarf_data1(dwarf_info_section, 0); |
| 1855 | 1959 | write32le(dwarf_info_section->data + pos_sib, |
| 1856 | 1960 | dwarf_info_section->data_offset - dwarf_info.start); |
| 1857 | | − if (debug_info) |
| 1858 | | − tcc_debug_remove(s1, t); |
| 1859 | 1961 | } |
| 1860 | 1962 | } |
| 1861 | 1963 | else if ((type & VT_BTYPE) != VT_FUNC) { |
| @@ -1893,7 +1995,7 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s) · 31 unmodified lines |
| 1893 | 1995 | dwarf_data1(dwarf_info_section, DWARF_ABBREV_POINTER); |
| 1894 | 1996 | dwarf_data1(dwarf_info_section, PTR_SIZE); |
| 1895 | 1997 | if (last_pos != -1) { |
| 1896 | | − tcc_debug_check_anon(s1, e, last_pos); |
| 1998 | + tcc_debug_check_forw(s1, e, last_pos); |
| 1897 | 1999 | write32le(dwarf_info_section->data + last_pos, |
| 1898 | 2000 | i - dwarf_info.start); |
| 1899 | 2001 | } |
| @@ -1915,7 +2017,7 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s) · 15 unmodified lines |
| 1915 | 2017 | retval = i; |
| 1916 | 2018 | dwarf_data1(dwarf_info_section, DWARF_ABBREV_ARRAY_TYPE); |
| 1917 | 2019 | if (last_pos != -1) { |
| 1918 | | − tcc_debug_check_anon(s1, e, last_pos); |
| 2020 | + tcc_debug_check_forw(s1, e, last_pos); |
| 1919 | 2021 | write32le(dwarf_info_section->data + last_pos, |
| 1920 | 2022 | i - dwarf_info.start); |
| 1921 | 2023 | } |
| @@ -1950,7 +2052,7 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s) · 28 unmodified lines |
| 1950 | 2052 | t->type.ref->next ? DWARF_ABBREV_SUBROUTINE_TYPE |
| 1951 | 2053 | : DWARF_ABBREV_SUBROUTINE_EMPTY_TYPE); |
| 1952 | 2054 | if (last_pos != -1) { |
| 1953 | | − tcc_debug_check_anon(s1, e, last_pos); |
| 2055 | + tcc_debug_check_forw(s1, e, last_pos); |
| 1954 | 2056 | write32le(dwarf_info_section->data + last_pos, |
| 1955 | 2057 | i - dwarf_info.start); |
| 1956 | 2058 | } |
| @@ -1986,7 +2088,7 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s) · 29 unmodified lines |
| 1986 | 2088 | while (f->next) { |
| 1987 | 2089 | f = f->next; |
| 1988 | 2090 | type = tcc_get_dwarf_info(s1, f); |
| 1989 | | − tcc_debug_check_anon(s1, f, pos_type[i]); |
| 2091 | + tcc_debug_check_forw(s1, f, pos_type[i]); |
| 1990 | 2092 | write32le(dwarf_info_section->data + pos_type[i++], |
| 1991 | 2093 | type - dwarf_info.start); |
| 1992 | 2094 | } |
| @@ -1994,7 +2096,7 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s) · 1 unmodified line |
| 1994 | 2096 | } |
| 1995 | 2097 | else { |
| 1996 | 2098 | if (last_pos != -1) { |
| 1997 | | − tcc_debug_check_anon(s1, e, last_pos); |
| 2099 | + tcc_debug_check_forw(s1, e, last_pos); |
| 1998 | 2100 | write32le(dwarf_info_section->data + last_pos, |
| 1999 | 2101 | debug_type - dwarf_info.start); |
| 2000 | 2102 | } |
| @@ -2201,7 +2303,7 @@ ST_FUNC void tcc_debug_funcend(TCCState *s1, int size) · 200 unmodified lines |
| 2201 | 2303 | dwarf_strp(dwarf_info_section, funcname); |
| 2202 | 2304 | dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file); |
| 2203 | 2305 | dwarf_uleb128(dwarf_info_section, dwarf_info.line); |
| 2204 | | − tcc_debug_check_anon(s1, sym->type.ref, dwarf_info_section->data_offset); |
| 2306 | + tcc_debug_check_forw(s1, sym->type.ref, dwarf_info_section->data_offset); |
| 2205 | 2307 | dwarf_data4(dwarf_info_section, n_debug_info - dwarf_info.start); |
| 2206 | 2308 | dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR); |
| 2207 | 2309 | #if PTR_SIZE == 4 |
| @@ -2258,7 +2360,7 @@ ST_FUNC void tcc_debug_extern_sym(TCCState *s1, Sym *sym, int sh_num, int sym_bi · 50 unmodified lines |
| 2258 | 2360 | dwarf_strp(dwarf_info_section, get_tok_str(sym->v, NULL)); |
| 2259 | 2361 | dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file); |
| 2260 | 2362 | dwarf_uleb128(dwarf_info_section, file->line_num); |
| 2261 | | − tcc_debug_check_anon(s1, sym, dwarf_info_section->data_offset); |
| 2363 | + tcc_debug_check_forw(s1, sym, dwarf_info_section->data_offset); |
| 2262 | 2364 | dwarf_data4(dwarf_info_section, debug_type - dwarf_info.start); |
| 2263 | 2365 | if (sym_bind == STB_GLOBAL) |
| 2264 | 2366 | dwarf_data1(dwarf_info_section, 1); |
| @@ -2284,6 +2386,7 @@ ST_FUNC void tcc_debug_extern_sym(TCCState *s1, Sym *sym, int sh_num, int sym_bi · 19 unmodified lines |
| 2284 | 2386 | sym_bind == STB_GLOBAL ? 'G' : func_ind != -1 ? 'V' : 'S' |
| 2285 | 2387 | ); |
| 2286 | 2388 | tcc_get_debug_info(s1, sym, &str); |
| 2389 | + tcc_debug_check_forw(s1, sym, -1); |
| 2287 | 2390 | if (sym_bind == STB_GLOBAL) |
| 2288 | 2391 | tcc_debug_stabs(s1, str.data, N_GSYM, 0, NULL, 0, 0); |
| 2289 | 2392 | else |
| @@ -2308,7 +2411,7 @@ ST_FUNC void tcc_debug_typedef(TCCState *s1, Sym *sym) · 18 unmodified lines |
| 2308 | 2411 | dwarf_strp(dwarf_info_section, get_tok_str(sym->v, NULL)); |
| 2309 | 2412 | dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file); |
| 2310 | 2413 | dwarf_uleb128(dwarf_info_section, file->line_num); |
| 2311 | | − tcc_debug_check_anon(s1, sym, dwarf_info_section->data_offset); |
| 2414 | + tcc_debug_check_forw(s1, sym, dwarf_info_section->data_offset); |
| 2312 | 2415 | dwarf_data4(dwarf_info_section, debug_type - dwarf_info.start); |
| 2313 | 2416 | } |
| 2314 | 2417 | } |
| @@ -2320,6 +2423,7 @@ ST_FUNC void tcc_debug_typedef(TCCState *s1, Sym *sym) · 5 unmodified lines |
| 2320 | 2423 | (sym->v & ~SYM_FIELD) >= SYM_FIRST_ANOM |
| 2321 | 2424 | ? "" : get_tok_str(sym->v, NULL)); |
| 2322 | 2425 | tcc_get_debug_info(s1, sym, &str); |
| 2426 | + tcc_debug_check_forw(s1, sym, -1); |
| 2323 | 2427 | tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0, 0); |
| 2324 | 2428 | cstr_free (&str); |
| 2325 | 2429 | } |
| @@ -2477,13 +2581,19 @@ ST_FUNC void tcc_tcov_reset_ind(TCCState *s1) · 151 unmodified lines |
| 2477 | 2581 | #undef new_file |
| 2478 | 2582 | #undef section_sym |
| 2479 | 2583 | #undef debug_next_type |
| 2480 | | −#undef debug_hash |
| 2481 | | −#undef n_debug_hash |
| 2482 | | −#undef debug_anon_hash |
| 2483 | | −#undef n_debug_anon_hash |
| 2584 | +#undef debug_hash_global |
| 2585 | +#undef debug_hash_local |
| 2586 | +#undef n_debug_hash_global |
| 2587 | +#undef n_debug_hash_local |
| 2588 | +#undef debug_forw_hash_global |
| 2589 | +#undef debug_forw_hash_local |
| 2590 | +#undef n_debug_forw_hash_global |
| 2591 | +#undef n_debug_forw_hash_local |
| 2484 | 2592 | #undef debug_info |
| 2485 | 2593 | #undef debug_info_root |
| 2486 | 2594 | #undef dwarf_sym |
| 2487 | 2595 | #undef dwarf_line |
| 2488 | 2596 | #undef dwarf_info |
| 2597 | +#undef dwarf_str |
| 2598 | +#undef dwarf_line_str |
| 2489 | 2599 | #undef tcov_data |