| @@ -122,7 +122,10 @@ static struct scope { · 121 unmodified lines |
| 122 | 122 | Sym *lstk, *llstk; |
| 123 | 123 | } *cur_scope, *loop_scope, *root_scope; |
| 124 | 124 | |
| 125 | | −static struct { |
| 125 | +/********************************************************/ |
| 126 | +/* stab debug support */ |
| 127 | + |
| 128 | +static const struct { |
| 126 | 129 | int type; |
| 127 | 130 | const char *name; |
| 128 | 131 | } default_debug[] = { |
| @@ -184,8 +187,6 @@ static struct debug_info { · 55 unmodified lines |
| 184 | 187 | struct debug_info *child, *next, *last, *parent; |
| 185 | 188 | } *debug_info, *debug_info_root; |
| 186 | 189 | |
| 187 | | −static CString debug_str; |
| 188 | | − |
| 189 | 190 | /********************************************************/ |
| 190 | 191 | #if 1 |
| 191 | 192 | #define precedence_parser |
| @@ -404,15 +405,19 @@ ST_FUNC void tcc_debug_start(TCCState *s1) · 212 unmodified lines |
| 404 | 405 | normalize_slashes(buf); |
| 405 | 406 | #endif |
| 406 | 407 | pstrcat(buf, sizeof(buf), "/"); |
| 407 | | − debug_next_type = sizeof(default_debug) / sizeof(default_debug[0]); |
| 408 | 408 | put_stabs_r(s1, buf, N_SO, 0, 0, |
| 409 | 409 | text_section->data_offset, text_section, section_sym); |
| 410 | 410 | put_stabs_r(s1, file->prev->filename, N_SO, 0, 0, |
| 411 | 411 | text_section->data_offset, text_section, section_sym); |
| 412 | 412 | for (i = 0; i < sizeof (default_debug) / sizeof (default_debug[0]); i++) |
| 413 | 413 | put_stabs(s1, default_debug[i].name, N_LSYM, 0, 0, 0); |
| 414 | + |
| 414 | 415 | new_file = last_line_num = 0; |
| 415 | 416 | func_ind = -1; |
| 417 | + debug_next_type = sizeof(default_debug) / sizeof(default_debug[0]); |
| 418 | + debug_hash = NULL; |
| 419 | + n_debug_hash = 0; |
| 420 | + |
| 416 | 421 | /* we're currently 'including' the <command line> */ |
| 417 | 422 | tcc_debug_bincl(s1); |
| 418 | 423 | } |
| @@ -424,7 +429,7 @@ ST_FUNC void tcc_debug_start(TCCState *s1) · 5 unmodified lines |
| 424 | 429 | SHN_ABS, file->filename); |
| 425 | 430 | } |
| 426 | 431 | |
| 427 | | −static void tcc_debug_stabs (const char *str, int type, unsigned long value, |
| 432 | +static void tcc_debug_stabs (TCCState *s1, const char *str, int type, unsigned long value, |
| 428 | 433 | Section *sec, int sym_index) |
| 429 | 434 | { |
| 430 | 435 | struct debug_sym *s; |
| @@ -442,15 +447,13 @@ static void tcc_debug_stabs (const char *str, int type, unsigned long value, · 11 unmodified lines |
| 442 | 447 | s->sym_index = sym_index; |
| 443 | 448 | } |
| 444 | 449 | else if (sec) |
| 445 | | − put_stabs_r (tcc_state, str, type, 0, 0, value, sec, sym_index); |
| 450 | + put_stabs_r (s1, str, type, 0, 0, value, sec, sym_index); |
| 446 | 451 | else |
| 447 | | − put_stabs (tcc_state, str, type, 0, 0, value); |
| 452 | + put_stabs (s1, str, type, 0, 0, value); |
| 448 | 453 | } |
| 449 | 454 | |
| 450 | 455 | static void tcc_debug_stabn(int type, int value) |
| 451 | 456 | { |
| 452 | | − if (!tcc_state->do_debug) |
| 453 | | − return; |
| 454 | 457 | if (type == N_LBRAC) { |
| 455 | 458 | struct debug_info *info = |
| 456 | 459 | (struct debug_info *) tcc_mallocz(sizeof (*info)); |
| @@ -478,7 +481,7 @@ static void tcc_debug_stabn(int type, int value) · 21 unmodified lines |
| 478 | 481 | } |
| 479 | 482 | } |
| 480 | 483 | |
| 481 | | −static void tcc_get_debug_info(Sym *s, CString *result) |
| 484 | +static void tcc_get_debug_info(TCCState *s1, Sym *s, CString *result) |
| 482 | 485 | { |
| 483 | 486 | int type; |
| 484 | 487 | int n = 0; |
| @@ -526,7 +529,7 @@ static void tcc_get_debug_info(Sym *s, CString *result) · 41 unmodified lines |
| 526 | 529 | cstr_printf (&str, "%s:", |
| 527 | 530 | (t->v & ~SYM_FIELD) >= SYM_FIRST_ANOM |
| 528 | 531 | ? "" : get_tok_str(t->v & ~SYM_FIELD, NULL)); |
| 529 | | − tcc_get_debug_info (t, &str); |
| 532 | + tcc_get_debug_info (s1, t, &str); |
| 530 | 533 | if (t->type.t & VT_BITFIELD) { |
| 531 | 534 | pos = t->c * 8 + BIT_POS(t->type.t); |
| 532 | 535 | size = BIT_SIZE(t->type.t); |
| @@ -538,7 +541,7 @@ static void tcc_get_debug_info(Sym *s, CString *result) · 5 unmodified lines |
| 538 | 541 | cstr_printf (&str, ",%d,%d;", pos, size); |
| 539 | 542 | } |
| 540 | 543 | cstr_printf (&str, ";"); |
| 541 | | − tcc_debug_stabs(str.data, N_LSYM, 0, NULL, 0); |
| 544 | + tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0); |
| 542 | 545 | cstr_free (&str); |
| 543 | 546 | } |
| 544 | 547 | } |
| @@ -556,11 +559,11 @@ static void tcc_get_debug_info(Sym *s, CString *result) · 11 unmodified lines |
| 556 | 559 | cstr_printf (&str, "%s:", |
| 557 | 560 | (t->v & ~SYM_FIELD) >= SYM_FIRST_ANOM |
| 558 | 561 | ? "" : get_tok_str(t->v & ~SYM_FIELD, NULL)); |
| 559 | | − cstr_printf (&str, e->type.t & VT_UNSIGNED ? "%llu," : "%lld,", |
| 560 | | − t->enum_val); |
| 562 | + cstr_printf (&str, e->type.t & VT_UNSIGNED ? "%u," : "%d,", |
| 563 | + (int)t->enum_val); |
| 561 | 564 | } |
| 562 | 565 | cstr_printf (&str, ";"); |
| 563 | | − tcc_debug_stabs(str.data, N_LSYM, 0, NULL, 0); |
| 566 | + tcc_debug_stabs(s1, str.data, N_LSYM, 0, NULL, 0); |
| 564 | 567 | cstr_free (&str); |
| 565 | 568 | } |
| 566 | 569 | else { |
| @@ -592,7 +595,7 @@ static void tcc_get_debug_info(Sym *s, CString *result) · 25 unmodified lines |
| 592 | 595 | cstr_printf (result, "%d", debug_type); |
| 593 | 596 | } |
| 594 | 597 | |
| 595 | | −static void tcc_debug_finish (struct debug_info *cur) |
| 598 | +static void tcc_debug_finish (TCCState *s1, struct debug_info *cur) |
| 596 | 599 | { |
| 597 | 600 | while (cur) { |
| 598 | 601 | int i; |
| @@ -602,33 +605,54 @@ static void tcc_debug_finish (struct debug_info *cur) · 3 unmodified lines |
| 602 | 605 | struct debug_sym *s = &cur->sym[i]; |
| 603 | 606 | |
| 604 | 607 | if (s->sec) |
| 605 | | − put_stabs_r(tcc_state, s->str, s->type, 0, 0, s->value, |
| 608 | + put_stabs_r(s1, s->str, s->type, 0, 0, s->value, |
| 606 | 609 | s->sec, s->sym_index); |
| 607 | 610 | else |
| 608 | | − put_stabs(tcc_state, s->str, s->type, 0, 0, s->value); |
| 611 | + put_stabs(s1, s->str, s->type, 0, 0, s->value); |
| 609 | 612 | tcc_free (s->str); |
| 610 | 613 | } |
| 611 | 614 | tcc_free (cur->sym); |
| 612 | | − put_stabn(tcc_state, N_LBRAC, 0, 0, cur->start); |
| 613 | | − tcc_debug_finish (cur->child); |
| 614 | | − put_stabn(tcc_state, N_RBRAC, 0, 0, cur->end); |
| 615 | + put_stabn(s1, N_LBRAC, 0, 0, cur->start); |
| 616 | + tcc_debug_finish (s1, cur->child); |
| 617 | + put_stabn(s1, N_RBRAC, 0, 0, cur->end); |
| 615 | 618 | tcc_free (cur); |
| 616 | 619 | cur = next; |
| 617 | 620 | } |
| 618 | 621 | } |
| 619 | 622 | |
| 620 | | −static void tcc_add_debug_info(int param, Sym *s, Sym *e) |
| 623 | +static void tcc_add_debug_info(TCCState *s1, int param, Sym *s, Sym *e) |
| 621 | 624 | { |
| 622 | | − if (!tcc_state->do_debug) |
| 623 | | − return; |
| 625 | + CString debug_str; |
| 626 | + cstr_new (&debug_str); |
| 624 | 627 | for (; s != e; s = s->prev) { |
| 625 | 628 | if (!s->v || (s->r & VT_VALMASK) != VT_LOCAL) |
| 626 | 629 | continue; |
| 627 | 630 | cstr_reset (&debug_str); |
| 628 | 631 | cstr_printf (&debug_str, "%s:%s", get_tok_str(s->v, NULL), param ? "p" : ""); |
| 629 | | − tcc_get_debug_info(s, &debug_str); |
| 630 | | − tcc_debug_stabs(debug_str.data, param ? N_PSYM : N_LSYM, s->c, NULL, 0); |
| 632 | + tcc_get_debug_info(s1, s, &debug_str); |
| 633 | + tcc_debug_stabs(s1, debug_str.data, param ? N_PSYM : N_LSYM, s->c, NULL, 0); |
| 631 | 634 | } |
| 635 | + cstr_free (&debug_str); |
| 636 | +} |
| 637 | + |
| 638 | +static void tcc_debug_extern_sym(TCCState *s1, Sym *sym, int sh_num, int sym_bind) |
| 639 | +{ |
| 640 | + Section *s = s1->sections[sh_num]; |
| 641 | + CString str; |
| 642 | + |
| 643 | + cstr_new (&str); |
| 644 | + cstr_printf (&str, "%s:%c", |
| 645 | + get_tok_str(sym->v, NULL), |
| 646 | + sym_bind == STB_GLOBAL ? 'G' : local_scope ? 'V' : 'S' |
| 647 | + ); |
| 648 | + tcc_get_debug_info(s1, sym, &str); |
| 649 | + if (sym_bind == STB_GLOBAL) |
| 650 | + tcc_debug_stabs(s1, str.data, N_GSYM, 0, NULL, 0); |
| 651 | + else |
| 652 | + tcc_debug_stabs(s1, str.data, |
| 653 | + (sym->type.t & VT_STATIC) && data_section == s |
| 654 | + ? N_STSYM : N_LCSYM, 0, s, sym->c); |
| 655 | + cstr_free (&str); |
| 632 | 656 | } |
| 633 | 657 | |
| 634 | 658 | /* put end of translation unit info */ |
| @@ -639,8 +663,6 @@ ST_FUNC void tcc_debug_end(TCCState *s1) · 4 unmodified lines |
| 639 | 663 | put_stabs_r(s1, NULL, N_SO, 0, 0, |
| 640 | 664 | text_section->data_offset, text_section, section_sym); |
| 641 | 665 | tcc_free(debug_hash); |
| 642 | | − debug_hash = NULL; |
| 643 | | − n_debug_hash = 0; |
| 644 | 666 | } |
| 645 | 667 | |
| 646 | 668 | static BufferedFile* put_new_file(TCCState *s1) |
| @@ -677,14 +699,21 @@ ST_FUNC void tcc_debug_line(TCCState *s1) · 30 unmodified lines |
| 677 | 699 | /* put function symbol */ |
| 678 | 700 | ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym) |
| 679 | 701 | { |
| 702 | + CString debug_str; |
| 680 | 703 | BufferedFile *f; |
| 681 | | − if (!s1->do_debug || !(f = put_new_file(s1))) |
| 704 | + if (!s1->do_debug) |
| 682 | 705 | return; |
| 706 | + debug_info_root = NULL; |
| 707 | + debug_info = NULL; |
| 683 | 708 | tcc_debug_stabn(N_LBRAC, ind - func_ind); |
| 684 | | − cstr_reset (&debug_str); |
| 709 | + if (!(f = put_new_file(s1))) |
| 710 | + return; |
| 711 | + cstr_new (&debug_str); |
| 685 | 712 | cstr_printf(&debug_str, "%s:%c", funcname, sym->type.t & VT_STATIC ? 'f' : 'F'); |
| 686 | | − tcc_get_debug_info(sym->type.ref, &debug_str); |
| 713 | + tcc_get_debug_info(s1, sym->type.ref, &debug_str); |
| 687 | 714 | put_stabs_r(s1, debug_str.data, N_FUN, 0, f->line_num, 0, cur_text_section, sym->c); |
| 715 | + cstr_free (&debug_str); |
| 716 | + |
| 688 | 717 | tcc_debug_line(s1); |
| 689 | 718 | } |
| 690 | 719 | |
| @@ -694,10 +723,7 @@ ST_FUNC void tcc_debug_funcend(TCCState *s1, int size) · 3 unmodified lines |
| 694 | 723 | if (!s1->do_debug) |
| 695 | 724 | return; |
| 696 | 725 | tcc_debug_stabn(N_RBRAC, size); |
| 697 | | − tcc_debug_finish (debug_info_root); |
| 698 | | − debug_info_root = NULL; |
| 699 | | − debug_info = NULL; |
| 700 | | − cstr_free (&debug_str); |
| 726 | + tcc_debug_finish (s1, debug_info_root); |
| 701 | 727 | } |
| 702 | 728 | |
| 703 | 729 | /* put alternative filename */ |
| @@ -926,25 +952,12 @@ ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, · 222 unmodified lines |
| 926 | 952 | name = get_tok_str(sym->asm_label, NULL); |
| 927 | 953 | info = ELFW(ST_INFO)(sym_bind, sym_type); |
| 928 | 954 | sym->c = put_elf_sym(symtab_section, value, size, info, other, sh_num, name); |
| 929 | | − if (tcc_state->do_debug && sym_type != STT_FUNC && sym->v < SYM_FIRST_ANOM) { |
| 930 | | − CString str; |
| 931 | 955 | |
| 932 | | − cstr_new (&str); |
| 933 | | − cstr_printf (&str, "%s:%c", get_tok_str(sym->v, NULL), |
| 934 | | − debug_info ? 'V' : sym_bind == STB_GLOBAL ? 'G' : 'S'); |
| 935 | | − tcc_get_debug_info(sym, &str); |
| 936 | | − if (sym_bind == STB_GLOBAL) |
| 937 | | − tcc_debug_stabs(str.data, N_GSYM, 0, NULL, 0); |
| 938 | | − else |
| 939 | | − tcc_debug_stabs(str.data, |
| 940 | | − (t & VT_STATIC) && data_section->sh_num == sh_num |
| 941 | | − ? N_STSYM : N_LCSYM, 0, |
| 942 | | − data_section->sh_num == sh_num ? data_section : |
| 943 | | − bss_section->sh_num == sh_num ? bss_section : |
| 944 | | − common_section->sh_num == sh_num ? common_section : |
| 945 | | − text_section, sym->c); |
| 946 | | − cstr_free (&str); |
| 947 | | − } |
| 956 | + if (tcc_state->do_debug |
| 957 | + && sym_type != STT_FUNC |
| 958 | + && sym->v < SYM_FIRST_ANOM) |
| 959 | + tcc_debug_extern_sym(tcc_state, sym, sh_num, sym_bind); |
| 960 | + |
| 948 | 961 | } else { |
| 949 | 962 | esym = elfsym(sym); |
| 950 | 963 | esym->st_value = value; |
| @@ -1920,13 +1933,14 @@ static void add_local_bounds(Sym *s, Sym *e) · 969 unmodified lines |
| 1920 | 1933 | #endif |
| 1921 | 1934 | |
| 1922 | 1935 | /* Wrapper around sym_pop, that potentially also registers local bounds. */ |
| 1923 | | −static void pop_local_syms(int param, Sym **ptop, Sym *b, int keep, int ellipsis) |
| 1936 | +static void pop_local_syms(Sym **ptop, Sym *b, int keep, int ellipsis) |
| 1924 | 1937 | { |
| 1925 | 1938 | #ifdef CONFIG_TCC_BCHECK |
| 1926 | | − if (!ellipsis && !keep && tcc_state->do_bounds_check) |
| 1939 | + if (tcc_state->do_bounds_check && !ellipsis && !keep) |
| 1927 | 1940 | add_local_bounds(*ptop, b); |
| 1928 | 1941 | #endif |
| 1929 | | − tcc_add_debug_info (param, *ptop, b); |
| 1942 | + if (tcc_state->do_debug) |
| 1943 | + tcc_add_debug_info (tcc_state, !local_scope, *ptop, b); |
| 1930 | 1944 | sym_pop(ptop, b, keep); |
| 1931 | 1945 | } |
| 1932 | 1946 | |
| @@ -6717,7 +6731,9 @@ void new_scope(struct scope *o) · 4784 unmodified lines |
| 6717 | 6731 | o->llstk = local_label_stack; |
| 6718 | 6732 | |
| 6719 | 6733 | ++local_scope; |
| 6720 | | − tcc_debug_stabn(N_LBRAC, ind - func_ind); |
| 6734 | + |
| 6735 | + if (tcc_state->do_debug) |
| 6736 | + tcc_debug_stabn(N_LBRAC, ind - func_ind); |
| 6721 | 6737 | } |
| 6722 | 6738 | |
| 6723 | 6739 | void prev_scope(struct scope *o, int is_expr) |
| @@ -6739,12 +6755,12 @@ void prev_scope(struct scope *o, int is_expr) · 15 unmodified lines |
| 6739 | 6755 | tables, though. sym_pop will do that. */ |
| 6740 | 6756 | |
| 6741 | 6757 | /* pop locally defined symbols */ |
| 6742 | | − pop_local_syms(0, &local_stack, o->lstk, is_expr, 0); |
| 6743 | | − |
| 6744 | | − tcc_debug_stabn(N_RBRAC, ind - func_ind); |
| 6745 | | − |
| 6758 | + pop_local_syms(&local_stack, o->lstk, is_expr, 0); |
| 6746 | 6759 | cur_scope = o->prev; |
| 6747 | 6760 | --local_scope; |
| 6761 | + |
| 6762 | + if (tcc_state->do_debug) |
| 6763 | + tcc_debug_stabn(N_RBRAC, ind - func_ind); |
| 6748 | 6764 | } |
| 6749 | 6765 | |
| 6750 | 6766 | /* leave a scope via break/continue(/goto) */ |
| @@ -7952,8 +7968,12 @@ static void gen_function(Sym *sym) · 1201 unmodified lines |
| 7952 | 7968 | add_array (tcc_state, ".init_array", sym->c); |
| 7953 | 7969 | if (sym->type.ref->f.func_dtor) |
| 7954 | 7970 | add_array (tcc_state, ".fini_array", sym->c); |
| 7971 | + |
| 7955 | 7972 | funcname = get_tok_str(sym->v, NULL); |
| 7956 | 7973 | func_ind = ind; |
| 7974 | + func_vt = sym->type.ref->type; |
| 7975 | + func_var = sym->type.ref->f.func_type == FUNC_ELLIPSIS; |
| 7976 | + |
| 7957 | 7977 | /* put debug symbol */ |
| 7958 | 7978 | tcc_debug_funcstart(tcc_state, sym); |
| 7959 | 7979 | /* push a dummy symbol to enable local sym storage */ |
| @@ -7967,8 +7987,7 @@ static void gen_function(Sym *sym) · 7 unmodified lines |
| 7967 | 7987 | gsym(rsym); |
| 7968 | 7988 | nocode_wanted = 0; |
| 7969 | 7989 | /* reset local stack */ |
| 7970 | | − pop_local_syms(1, &local_stack, NULL, 0, |
| 7971 | | − sym->type.ref->f.func_type == FUNC_ELLIPSIS); |
| 7990 | + pop_local_syms(&local_stack, NULL, 0, func_var); |
| 7972 | 7991 | gfunc_epilog(); |
| 7973 | 7992 | cur_text_section->data_offset = ind; |
| 7974 | 7993 | local_scope = 0; |