Unified · Split
| @@ -82,7 +82,7 @@ ST_FUNC void asm_global_instr(void) · 81 unmodified lines | ||
| 82 | 82 | |
| 83 | 83 | /********************************************************/ |
| 84 | 84 | #ifdef _WIN32 |
| 85 | −static char *normalize_slashes(char *path) | |
| 85 | +ST_FUNC char *normalize_slashes(char *path) | |
| 86 | 86 | { |
| 87 | 87 | char *p; |
| 88 | 88 | for (p = path; *p; ++p) |
| @@ -116,13 +116,6 @@ static void tcc_add_systemdir(TCCState *s) · 27 unmodified lines | ||
| 116 | 116 | } |
| 117 | 117 | #endif |
| 118 | 118 | |
| 119 | −#if defined TCC_IS_NATIVE | |
| 120 | −static void dlclose(void *p) | |
| 121 | −{ | |
| 122 | − FreeLibrary((HMODULE)p); | |
| 123 | −} | |
| 124 | −#endif | |
| 125 | − | |
| 126 | 119 | #ifdef LIBTCC_AS_DLL |
| 127 | 120 | BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) |
| 128 | 121 | { |
| @@ -492,239 +485,6 @@ static void tcc_split_path(TCCState *s, void ***p_ary, int *p_nb_ary, const char · 363 unmodified lines | ||
| 492 | 485 | |
| 493 | 486 | /********************************************************/ |
| 494 | 487 | |
| 495 | −ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags) | |
| 496 | −{ | |
| 497 | − Section *sec; | |
| 498 | − | |
| 499 | − sec = tcc_mallocz(sizeof(Section) + strlen(name)); | |
| 500 | − strcpy(sec->name, name); | |
| 501 | − sec->sh_type = sh_type; | |
| 502 | − sec->sh_flags = sh_flags; | |
| 503 | − switch(sh_type) { | |
| 504 | − case SHT_HASH: | |
| 505 | − case SHT_REL: | |
| 506 | − case SHT_RELA: | |
| 507 | − case SHT_DYNSYM: | |
| 508 | − case SHT_SYMTAB: | |
| 509 | − case SHT_DYNAMIC: | |
| 510 | − sec->sh_addralign = 4; | |
| 511 | − break; | |
| 512 | − case SHT_STRTAB: | |
| 513 | − sec->sh_addralign = 1; | |
| 514 | − break; | |
| 515 | − default: | |
| 516 | − sec->sh_addralign = PTR_SIZE; /* gcc/pcc default aligment */ | |
| 517 | − break; | |
| 518 | − } | |
| 519 | − | |
| 520 | − if (sh_flags & SHF_PRIVATE) { | |
| 521 | − dynarray_add((void ***)&s1->priv_sections, &s1->nb_priv_sections, sec); | |
| 522 | − } else { | |
| 523 | − sec->sh_num = s1->nb_sections; | |
| 524 | − dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec); | |
| 525 | − } | |
| 526 | − | |
| 527 | − return sec; | |
| 528 | −} | |
| 529 | − | |
| 530 | −static void free_section(Section *s) | |
| 531 | −{ | |
| 532 | − tcc_free(s->data); | |
| 533 | −} | |
| 534 | − | |
| 535 | −/* realloc section and set its content to zero */ | |
| 536 | −ST_FUNC void section_realloc(Section *sec, unsigned long new_size) | |
| 537 | −{ | |
| 538 | − unsigned long size; | |
| 539 | − unsigned char *data; | |
| 540 | − | |
| 541 | − size = sec->data_allocated; | |
| 542 | − if (size == 0) | |
| 543 | − size = 1; | |
| 544 | − while (size < new_size) | |
| 545 | − size = size * 2; | |
| 546 | − data = tcc_realloc(sec->data, size); | |
| 547 | − memset(data + sec->data_allocated, 0, size - sec->data_allocated); | |
| 548 | − sec->data = data; | |
| 549 | − sec->data_allocated = size; | |
| 550 | −} | |
| 551 | − | |
| 552 | −/* reserve at least 'size' bytes in section 'sec' from | |
| 553 | − sec->data_offset. */ | |
| 554 | −ST_FUNC void *section_ptr_add(Section *sec, addr_t size) | |
| 555 | −{ | |
| 556 | − size_t offset, offset1; | |
| 557 | − | |
| 558 | − offset = sec->data_offset; | |
| 559 | − offset1 = offset + size; | |
| 560 | − if (offset1 > sec->data_allocated) | |
| 561 | − section_realloc(sec, offset1); | |
| 562 | − sec->data_offset = offset1; | |
| 563 | − return sec->data + offset; | |
| 564 | −} | |
| 565 | − | |
| 566 | −/* reserve at least 'size' bytes from section start */ | |
| 567 | −ST_FUNC void section_reserve(Section *sec, unsigned long size) | |
| 568 | −{ | |
| 569 | − if (size > sec->data_allocated) | |
| 570 | − section_realloc(sec, size); | |
| 571 | − if (size > sec->data_offset) | |
| 572 | − sec->data_offset = size; | |
| 573 | −} | |
| 574 | − | |
| 575 | −/* return a reference to a section, and create it if it does not | |
| 576 | − exists */ | |
| 577 | −ST_FUNC Section *find_section(TCCState *s1, const char *name) | |
| 578 | −{ | |
| 579 | − Section *sec; | |
| 580 | − int i; | |
| 581 | − for(i = 1; i < s1->nb_sections; i++) { | |
| 582 | − sec = s1->sections[i]; | |
| 583 | − if (!strcmp(name, sec->name)) | |
| 584 | − return sec; | |
| 585 | − } | |
| 586 | − /* sections are created as PROGBITS */ | |
| 587 | − return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC); | |
| 588 | −} | |
| 589 | − | |
| 590 | −/* update sym->c so that it points to an external symbol in section | |
| 591 | − 'section' with value 'value' */ | |
| 592 | −ST_FUNC void put_extern_sym2(Sym *sym, Section *section, | |
| 593 | − addr_t value, unsigned long size, | |
| 594 | − int can_add_underscore) | |
| 595 | −{ | |
| 596 | − int sym_type, sym_bind, sh_num, info, other; | |
| 597 | − ElfW(Sym) *esym; | |
| 598 | − const char *name; | |
| 599 | − char buf1[256]; | |
| 600 | − | |
| 601 | −#ifdef CONFIG_TCC_BCHECK | |
| 602 | − char buf[32]; | |
| 603 | −#endif | |
| 604 | − | |
| 605 | − if (section == NULL) | |
| 606 | − sh_num = SHN_UNDEF; | |
| 607 | − else if (section == SECTION_ABS) | |
| 608 | − sh_num = SHN_ABS; | |
| 609 | − else | |
| 610 | − sh_num = section->sh_num; | |
| 611 | − | |
| 612 | − if ((sym->type.t & VT_BTYPE) == VT_FUNC) { | |
| 613 | − sym_type = STT_FUNC; | |
| 614 | − } else if ((sym->type.t & VT_BTYPE) == VT_VOID) { | |
| 615 | − sym_type = STT_NOTYPE; | |
| 616 | − } else { | |
| 617 | − sym_type = STT_OBJECT; | |
| 618 | − } | |
| 619 | − | |
| 620 | − if (sym->type.t & VT_STATIC) | |
| 621 | − sym_bind = STB_LOCAL; | |
| 622 | − else { | |
| 623 | − if (sym->type.t & VT_WEAK) | |
| 624 | − sym_bind = STB_WEAK; | |
| 625 | − else | |
| 626 | − sym_bind = STB_GLOBAL; | |
| 627 | − } | |
| 628 | − | |
| 629 | − if (!sym->c) { | |
| 630 | − name = get_tok_str(sym->v, NULL); | |
| 631 | −#ifdef CONFIG_TCC_BCHECK | |
| 632 | − if (tcc_state->do_bounds_check) { | |
| 633 | − /* XXX: avoid doing that for statics ? */ | |
| 634 | − /* if bound checking is activated, we change some function | |
| 635 | − names by adding the "__bound" prefix */ | |
| 636 | − switch(sym->v) { | |
| 637 | −#ifdef TCC_TARGET_PE | |
| 638 | − /* XXX: we rely only on malloc hooks */ | |
| 639 | − case TOK_malloc: | |
| 640 | − case TOK_free: | |
| 641 | − case TOK_realloc: | |
| 642 | − case TOK_memalign: | |
| 643 | − case TOK_calloc: | |
| 644 | −#endif | |
| 645 | − case TOK_memcpy: | |
| 646 | − case TOK_memmove: | |
| 647 | − case TOK_memset: | |
| 648 | − case TOK_strlen: | |
| 649 | − case TOK_strcpy: | |
| 650 | − case TOK_alloca: | |
| 651 | − strcpy(buf, "__bound_"); | |
| 652 | − strcat(buf, name); | |
| 653 | − name = buf; | |
| 654 | − break; | |
| 655 | − } | |
| 656 | − } | |
| 657 | −#endif | |
| 658 | − other = 0; | |
| 659 | − | |
| 660 | −#ifdef TCC_TARGET_PE | |
| 661 | − if (sym->type.t & VT_EXPORT) | |
| 662 | − other |= ST_PE_EXPORT; | |
| 663 | − if (sym_type == STT_FUNC && sym->type.ref) { | |
| 664 | − Sym *ref = sym->type.ref; | |
| 665 | − if (ref->a.func_export) | |
| 666 | − other |= ST_PE_EXPORT; | |
| 667 | − if (ref->a.func_call == FUNC_STDCALL && can_add_underscore) { | |
| 668 | − sprintf(buf1, "_%s@%d", name, ref->a.func_args * PTR_SIZE); | |
| 669 | − name = buf1; | |
| 670 | − other |= ST_PE_STDCALL; | |
| 671 | − can_add_underscore = 0; | |
| 672 | − } | |
| 673 | − } else { | |
| 674 | − if (find_elf_sym(tcc_state->dynsymtab_section, name)) | |
| 675 | − other |= ST_PE_IMPORT; | |
| 676 | − if (sym->type.t & VT_IMPORT) | |
| 677 | − other |= ST_PE_IMPORT; | |
| 678 | − } | |
| 679 | −#else | |
| 680 | − if (! (sym->type.t & VT_STATIC)) | |
| 681 | − other = (sym->type.t & VT_VIS_MASK) >> VT_VIS_SHIFT; | |
| 682 | −#endif | |
| 683 | − if (tcc_state->leading_underscore && can_add_underscore) { | |
| 684 | − buf1[0] = '_'; | |
| 685 | − pstrcpy(buf1 + 1, sizeof(buf1) - 1, name); | |
| 686 | − name = buf1; | |
| 687 | − } | |
| 688 | − if (sym->asm_label) { | |
| 689 | − name = get_tok_str(sym->asm_label, NULL); | |
| 690 | − } | |
| 691 | − info = ELFW(ST_INFO)(sym_bind, sym_type); | |
| 692 | − sym->c = add_elf_sym(symtab_section, value, size, info, other, sh_num, name); | |
| 693 | − } else { | |
| 694 | − esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; | |
| 695 | − esym->st_value = value; | |
| 696 | − esym->st_size = size; | |
| 697 | − esym->st_shndx = sh_num; | |
| 698 | − } | |
| 699 | −} | |
| 700 | − | |
| 701 | −ST_FUNC void put_extern_sym(Sym *sym, Section *section, | |
| 702 | − addr_t value, unsigned long size) | |
| 703 | −{ | |
| 704 | − put_extern_sym2(sym, section, value, size, 1); | |
| 705 | −} | |
| 706 | − | |
| 707 | −/* add a new relocation entry to symbol 'sym' in section 's' */ | |
| 708 | −ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, | |
| 709 | − addr_t addend) | |
| 710 | −{ | |
| 711 | − int c = 0; | |
| 712 | − if (sym) { | |
| 713 | − if (0 == sym->c) | |
| 714 | − put_extern_sym(sym, NULL, 0, 0); | |
| 715 | − c = sym->c; | |
| 716 | − } | |
| 717 | − /* now we can add ELF relocation info */ | |
| 718 | − put_elf_reloca(symtab_section, s, offset, type, c, addend); | |
| 719 | −} | |
| 720 | − | |
| 721 | −ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type) | |
| 722 | −{ | |
| 723 | − greloca(s, sym, offset, type, 0); | |
| 724 | −} | |
| 725 | − | |
| 726 | −/********************************************************/ | |
| 727 | − | |
| 728 | 488 | static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap) |
| 729 | 489 | { |
| 730 | 490 | int len; |
| @@ -886,79 +646,18 @@ ST_FUNC int tcc_open(TCCState *s1, const char *filename) · 155 unmodified lines | ||
| 886 | 646 | static int tcc_compile(TCCState *s1) |
| 887 | 647 | { |
| 888 | 648 | Sym *define_start; |
| 889 | − char buf[512]; | |
| 890 | − volatile int section_sym; | |
| 891 | 649 | |
| 892 | −#ifdef INC_DEBUG | |
| 893 | − printf("%s: **** new file\n", file->filename); | |
| 894 | −#endif | |
| 895 | 650 | preprocess_init(s1); |
| 896 | − | |
| 897 | − cur_text_section = NULL; | |
| 898 | − funcname = ""; | |
| 899 | − anon_sym = SYM_FIRST_ANOM; | |
| 900 | − | |
| 901 | − /* file info: full path + filename */ | |
| 902 | − section_sym = 0; /* avoid warning */ | |
| 903 | − if (s1->do_debug) { | |
| 904 | − section_sym = put_elf_sym(symtab_section, 0, 0, | |
| 905 | − ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0, | |
| 906 | − text_section->sh_num, NULL); | |
| 907 | − getcwd(buf, sizeof(buf)); | |
| 908 | −#ifdef _WIN32 | |
| 909 | − normalize_slashes(buf); | |
| 910 | −#endif | |
| 911 | − pstrcat(buf, sizeof(buf), "/"); | |
| 912 | − put_stabs_r(buf, N_SO, 0, 0, | |
| 913 | − text_section->data_offset, text_section, section_sym); | |
| 914 | − put_stabs_r(file->filename, N_SO, 0, 0, | |
| 915 | − text_section->data_offset, text_section, section_sym); | |
| 916 | − } | |
| 917 | − /* an elf symbol of type STT_FILE must be put so that STB_LOCAL | |
| 918 | − symbols can be safely used */ | |
| 919 | − put_elf_sym(symtab_section, 0, 0, | |
| 920 | − ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0, | |
| 921 | − SHN_ABS, file->filename); | |
| 922 | − | |
| 923 | − /* define some often used types */ | |
| 924 | − int_type.t = VT_INT; | |
| 925 | − | |
| 926 | − char_pointer_type.t = VT_BYTE; | |
| 927 | − mk_pointer(&char_pointer_type); | |
| 928 | − | |
| 929 | −#if PTR_SIZE == 4 | |
| 930 | − size_type.t = VT_INT; | |
| 931 | −#else | |
| 932 | − size_type.t = VT_LLONG; | |
| 933 | −#endif | |
| 934 | − | |
| 935 | − func_old_type.t = VT_FUNC; | |
| 936 | − func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD); | |
| 937 | −#ifdef TCC_TARGET_ARM | |
| 938 | − arm_init(s1); | |
| 939 | −#endif | |
| 940 | − | |
| 941 | −#if 0 | |
| 942 | − /* define 'void *alloca(unsigned int)' builtin function */ | |
| 943 | − { | |
| 944 | − Sym *s1; | |
| 945 | − | |
| 946 | − p = anon_sym++; | |
| 947 | − sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW); | |
| 948 | − s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0); | |
| 949 | − s1->next = NULL; | |
| 950 | − sym->next = s1; | |
| 951 | − sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0); | |
| 952 | − } | |
| 953 | −#endif | |
| 954 | − | |
| 955 | 651 | define_start = define_stack; |
| 956 | − nocode_wanted = 1; | |
| 957 | 652 | |
| 958 | 653 | if (setjmp(s1->error_jmp_buf) == 0) { |
| 959 | 654 | s1->nb_errors = 0; |
| 960 | 655 | s1->error_set_jmp_enabled = 1; |
| 961 | 656 | |
| 657 | + tccgen_start(s1); | |
| 658 | +#ifdef INC_DEBUG | |
| 659 | + printf("%s: **** new file\n", file->filename); | |
| 660 | +#endif | |
| 962 | 661 | ch = file->buf_ptr[0]; |
| 963 | 662 | tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; |
| 964 | 663 | parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR; |
| @@ -967,12 +666,7 @@ static int tcc_compile(TCCState *s1) · 2 unmodified lines | ||
| 967 | 666 | if (tok != TOK_EOF) |
| 968 | 667 | expect("declaration"); |
| 969 | 668 | gen_inline_functions(); |
| 970 | − check_vstack(); | |
| 971 | − /* end of translation unit info */ | |
| 972 | − if (s1->do_debug) { | |
| 973 | − put_stabs_r(NULL, N_SO, 0, 0, | |
| 974 | − text_section->data_offset, text_section, section_sym); | |
| 975 | − } | |
| 669 | + tccgen_end(s1); | |
| 976 | 670 | } |
| 977 | 671 | |
| 978 | 672 | s1->error_set_jmp_enabled = 0; |
| @@ -1049,21 +743,37 @@ static void tcc_cleanup(void) · 70 unmodified lines | ||
| 1049 | 743 | LIBTCCAPI TCCState *tcc_new(void) |
| 1050 | 744 | { |
| 1051 | 745 | TCCState *s; |
| 1052 | − char buffer[100]; | |
| 1053 | − int a,b,c; | |
| 1054 | − | |
| 1055 | 746 | tcc_cleanup(); |
| 1056 | 747 | |
| 1057 | 748 | s = tcc_mallocz(sizeof(TCCState)); |
| 1058 | 749 | if (!s) |
| 1059 | 750 | return NULL; |
| 1060 | 751 | tcc_state = s; |
| 752 | + | |
| 753 | + s->alacarte_link = 1; | |
| 754 | + s->nocommon = 1; | |
| 755 | + s->warn_implicit_function_declaration = 1; | |
| 756 | + | |
| 757 | +#ifdef CHAR_IS_UNSIGNED | |
| 758 | + s->char_is_unsigned = 1; | |
| 759 | +#endif | |
| 760 | +#ifdef TCC_TARGET_I386 | |
| 761 | + s->seg_size = 32; | |
| 762 | +#endif | |
| 763 | +#ifdef TCC_IS_NATIVE | |
| 764 | + s->runtime_main = "main"; | |
| 765 | +#endif | |
| 766 | + /* enable this if you want symbols with leading underscore on windows: */ | |
| 767 | +#if 0 /* def TCC_TARGET_PE */ | |
| 768 | + s->leading_underscore = 1; | |
| 769 | +#endif | |
| 1061 | 770 | #ifdef _WIN32 |
| 1062 | 771 | tcc_set_lib_path_w32(s); |
| 1063 | 772 | #else |
| 1064 | 773 | tcc_set_lib_path(s, CONFIG_TCCDIR); |
| 1065 | 774 | #endif |
| 1066 | 775 | |
| 776 | + tccelf_new(s); | |
| 1067 | 777 | preprocess_new(); |
| 1068 | 778 | s->include_stack_ptr = s->include_stack; |
| 1069 | 779 | |
| @@ -1073,11 +783,13 @@ LIBTCCAPI TCCState *tcc_new(void) · 3 unmodified lines | ||
| 1073 | 783 | define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL); |
| 1074 | 784 | define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL); |
| 1075 | 785 | define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL); |
| 1076 | − | |
| 1077 | − /* define __TINYC__ 92X */ | |
| 1078 | − sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c); | |
| 1079 | − sprintf(buffer, "%d", a*10000 + b*100 + c); | |
| 1080 | − tcc_define_symbol(s, "__TINYC__", buffer); | |
| 786 | + { | |
| 787 | + /* define __TINYC__ 92X */ | |
| 788 | + char buffer[32]; int a,b,c; | |
| 789 | + sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c); | |
| 790 | + sprintf(buffer, "%d", a*10000 + b*100 + c); | |
| 791 | + tcc_define_symbol(s, "__TINYC__", buffer); | |
| 792 | + } | |
| 1081 | 793 | |
| 1082 | 794 | /* standard defines */ |
| 1083 | 795 | tcc_define_symbol(s, "__STDC__", NULL); |
| @@ -1178,82 +890,22 @@ LIBTCCAPI TCCState *tcc_new(void) · 94 unmodified lines | ||
| 1178 | 890 | #else |
| 1179 | 891 | tcc_define_symbol(s, "__WINT_TYPE__", "unsigned int"); |
| 1180 | 892 | #endif |
| 1181 | −#endif | |
| 1182 | − | |
| 1183 | −#ifndef TCC_TARGET_PE | |
| 1184 | 893 | /* glibc defines */ |
| 1185 | 894 | tcc_define_symbol(s, "__REDIRECT(name, proto, alias)", "name proto __asm__ (#alias)"); |
| 1186 | 895 | tcc_define_symbol(s, "__REDIRECT_NTH(name, proto, alias)", "name proto __asm__ (#alias) __THROW"); |
| 1187 | − /* paths for crt objects */ | |
| 1188 | − tcc_split_path(s, (void ***)&s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX); | |
| 1189 | 896 | #endif |
| 1190 | 897 | |
| 1191 | − /* no section zero */ | |
| 1192 | − dynarray_add((void ***)&s->sections, &s->nb_sections, NULL); | |
| 1193 | − | |
| 1194 | − /* create standard sections */ | |
| 1195 | − text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR); | |
| 1196 | − data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); | |
| 1197 | − bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); | |
| 1198 | − | |
| 1199 | − /* symbols are always generated for linking stage */ | |
| 1200 | − symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0, | |
| 1201 | − ".strtab", | |
| 1202 | − ".hashtab", SHF_PRIVATE); | |
| 1203 | − strtab_section = symtab_section->link; | |
| 1204 | − s->symtab = symtab_section; | |
| 1205 | − | |
| 1206 | − /* private symbol table for dynamic symbols */ | |
| 1207 | − s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE, | |
| 1208 | − ".dynstrtab", | |
| 1209 | − ".dynhashtab", SHF_PRIVATE); | |
| 1210 | − s->alacarte_link = 1; | |
| 1211 | − s->nocommon = 1; | |
| 1212 | − s->warn_implicit_function_declaration = 1; | |
| 1213 | − | |
| 1214 | −#ifdef CHAR_IS_UNSIGNED | |
| 1215 | − s->char_is_unsigned = 1; | |
| 1216 | −#endif | |
| 1217 | − /* enable this if you want symbols with leading underscore on windows: */ | |
| 1218 | −#if 0 /* def TCC_TARGET_PE */ | |
| 1219 | − s->leading_underscore = 1; | |
| 1220 | −#endif | |
| 1221 | −#ifdef TCC_TARGET_I386 | |
| 1222 | − s->seg_size = 32; | |
| 1223 | −#endif | |
| 1224 | −#ifdef TCC_IS_NATIVE | |
| 1225 | − s->runtime_main = "main"; | |
| 1226 | −#endif | |
| 1227 | 898 | return s; |
| 1228 | 899 | } |
| 1229 | 900 | |
| 1230 | 901 | LIBTCCAPI void tcc_delete(TCCState *s1) |
| 1231 | 902 | { |
| 1232 | − int i; | |
| 1233 | 903 | int bench = s1->do_bench; |
| 1234 | 904 | |
| 1235 | 905 | tcc_cleanup(); |
| 1236 | 906 | |
| 1237 | − /* free all sections */ | |
| 1238 | − for(i = 1; i < s1->nb_sections; i++) | |
| 1239 | − free_section(s1->sections[i]); | |
| 1240 | − dynarray_reset(&s1->sections, &s1->nb_sections); | |
| 1241 | − | |
| 1242 | − for(i = 0; i < s1->nb_priv_sections; i++) | |
| 1243 | − free_section(s1->priv_sections[i]); | |
| 1244 | − dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections); | |
| 1245 | − | |
| 1246 | − /* free any loaded DLLs */ | |
| 1247 | −#ifdef TCC_IS_NATIVE | |
| 1248 | − for ( i = 0; i < s1->nb_loaded_dlls; i++) { | |
| 1249 | − DLLReference *ref = s1->loaded_dlls[i]; | |
| 1250 | − if ( ref->handle ) | |
| 1251 | − dlclose(ref->handle); | |
| 1252 | − } | |
| 1253 | −#endif | |
| 1254 | − | |
| 1255 | − /* free loaded dlls array */ | |
| 1256 | − dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls); | |
| 907 | + /* free sections */ | |
| 908 | + tccelf_delete(s1); | |
| 1257 | 909 | |
| 1258 | 910 | /* free library paths */ |
| 1259 | 911 | dynarray_reset(&s1->library_paths, &s1->nb_library_paths); |
| @@ -1289,6 +941,68 @@ LIBTCCAPI void tcc_delete(TCCState *s1) · 29 unmodified lines | ||
| 1289 | 941 | tcc_memstats(bench); |
| 1290 | 942 | } |
| 1291 | 943 | |
| 944 | +LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) | |
| 945 | +{ | |
| 946 | + s->output_type = output_type; | |
| 947 | + | |
| 948 | + /* always elf for objects */ | |
| 949 | + if (output_type == TCC_OUTPUT_OBJ) | |
| 950 | + s->output_format = TCC_OUTPUT_FORMAT_ELF; | |
| 951 | + | |
| 952 | + if (s->char_is_unsigned) | |
| 953 | + tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL); | |
| 954 | + | |
| 955 | + if (!s->nostdinc) { | |
| 956 | + /* default include paths */ | |
| 957 | + /* -isystem paths have already been handled */ | |
| 958 | + tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS); | |
| 959 | + } | |
| 960 | + | |
| 961 | +#ifdef CONFIG_TCC_BCHECK | |
| 962 | + /* if bound checking, then add corresponding sections */ | |
| 963 | + if (s->do_bounds_check) { | |
| 964 | + /* define symbol */ | |
| 965 | + tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL); | |
| 966 | + /* create bounds sections */ | |
| 967 | + bounds_section = new_section(s, ".bounds", | |
| 968 | + SHT_PROGBITS, SHF_ALLOC); | |
| 969 | + lbounds_section = new_section(s, ".lbounds", | |
| 970 | + SHT_PROGBITS, SHF_ALLOC); | |
| 971 | + } | |
| 972 | +#endif | |
| 973 | + /* add debug sections */ | |
| 974 | + if (s->do_debug) { | |
| 975 | + /* stab symbols */ | |
| 976 | + stab_section = new_section(s, ".stab", SHT_PROGBITS, 0); | |
| 977 | + stab_section->sh_entsize = sizeof(Stab_Sym); | |
| 978 | + stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0); | |
| 979 | + put_elf_str(stabstr_section, ""); | |
| 980 | + stab_section->link = stabstr_section; | |
| 981 | + /* put first entry */ | |
| 982 | + put_stabs("", 0, 0, 0, 0); | |
| 983 | + } | |
| 984 | + | |
| 985 | + tcc_add_library_path(s, CONFIG_TCC_LIBPATHS); | |
| 986 | + | |
| 987 | +#ifdef TCC_TARGET_PE | |
| 988 | +# ifdef _WIN32 | |
| 989 | + if (!s->nostdlib && output_type != TCC_OUTPUT_OBJ) | |
| 990 | + tcc_add_systemdir(s); | |
| 991 | +# endif | |
| 992 | +#else | |
| 993 | + /* paths for crt objects */ | |
| 994 | + tcc_split_path(s, (void ***)&s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX); | |
| 995 | + /* add libc crt1/crti objects */ | |
| 996 | + if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) && | |
| 997 | + !s->nostdlib) { | |
| 998 | + if (output_type != TCC_OUTPUT_DLL) | |
| 999 | + tcc_add_crt(s, "crt1.o"); | |
| 1000 | + tcc_add_crt(s, "crti.o"); | |
| 1001 | + } | |
| 1002 | +#endif | |
| 1003 | + return 0; | |
| 1004 | +} | |
| 1005 | + | |
| 1292 | 1006 | LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname) |
| 1293 | 1007 | { |
| 1294 | 1008 | tcc_split_path(s, (void ***)&s->include_paths, &s->nb_include_paths, pathname); |
| @@ -1503,66 +1217,6 @@ LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val) · 208 unmodified lines | ||
| 1503 | 1217 | return 0; |
| 1504 | 1218 | } |
| 1505 | 1219 | |
| 1506 | −LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) | |
| 1507 | −{ | |
| 1508 | − s->output_type = output_type; | |
| 1509 | − | |
| 1510 | − /* always elf for objects */ | |
| 1511 | − if (output_type == TCC_OUTPUT_OBJ) | |
| 1512 | − s->output_format = TCC_OUTPUT_FORMAT_ELF; | |
| 1513 | − | |
| 1514 | − if (s->char_is_unsigned) | |
| 1515 | − tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL); | |
| 1516 | − | |
| 1517 | − if (!s->nostdinc) { | |
| 1518 | − /* default include paths */ | |
| 1519 | − /* -isystem paths have already been handled */ | |
| 1520 | − tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS); | |
| 1521 | − } | |
| 1522 | − | |
| 1523 | −#ifdef CONFIG_TCC_BCHECK | |
| 1524 | − /* if bound checking, then add corresponding sections */ | |
| 1525 | − if (s->do_bounds_check) { | |
| 1526 | − /* define symbol */ | |
| 1527 | − tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL); | |
| 1528 | − /* create bounds sections */ | |
| 1529 | − bounds_section = new_section(s, ".bounds", | |
| 1530 | − SHT_PROGBITS, SHF_ALLOC); | |
| 1531 | − lbounds_section = new_section(s, ".lbounds", | |
| 1532 | − SHT_PROGBITS, SHF_ALLOC); | |
| 1533 | − } | |
| 1534 | −#endif | |
| 1535 | − /* add debug sections */ | |
| 1536 | − if (s->do_debug) { | |
| 1537 | − /* stab symbols */ | |
| 1538 | − stab_section = new_section(s, ".stab", SHT_PROGBITS, 0); | |
| 1539 | − stab_section->sh_entsize = sizeof(Stab_Sym); | |
| 1540 | − stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0); | |
| 1541 | − put_elf_str(stabstr_section, ""); | |
| 1542 | − stab_section->link = stabstr_section; | |
| 1543 | − /* put first entry */ | |
| 1544 | − put_stabs("", 0, 0, 0, 0); | |
| 1545 | − } | |
| 1546 | − | |
| 1547 | − tcc_add_library_path(s, CONFIG_TCC_LIBPATHS); | |
| 1548 | − | |
| 1549 | −#ifdef TCC_TARGET_PE | |
| 1550 | −# ifdef _WIN32 | |
| 1551 | − if (!s->nostdlib && output_type != TCC_OUTPUT_OBJ) | |
| 1552 | − tcc_add_systemdir(s); | |
| 1553 | −# endif | |
| 1554 | −#else | |
| 1555 | − /* add libc crt1/crti objects */ | |
| 1556 | − if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) && | |
| 1557 | − !s->nostdlib) { | |
| 1558 | − if (output_type != TCC_OUTPUT_DLL) | |
| 1559 | − tcc_add_crt(s, "crt1.o"); | |
| 1560 | − tcc_add_crt(s, "crti.o"); | |
| 1561 | − } | |
| 1562 | −#endif | |
| 1563 | − return 0; | |
| 1564 | −} | |
| 1565 | − | |
| 1566 | 1220 | LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path) |
| 1567 | 1221 | { |
| 1568 | 1222 | tcc_free(s->tcc_lib_path); |
| @@ -1095,17 +1095,6 @@ ST_FUNC void cstr_new(CString *cstr); · 1094 unmodified lines | ||
| 1095 | 1095 | ST_FUNC void cstr_free(CString *cstr); |
| 1096 | 1096 | ST_FUNC void cstr_reset(CString *cstr); |
| 1097 | 1097 | |
| 1098 | −ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags); | |
| 1099 | −ST_FUNC void section_realloc(Section *sec, unsigned long new_size); | |
| 1100 | −ST_FUNC void *section_ptr_add(Section *sec, addr_t size); | |
| 1101 | −ST_FUNC void section_reserve(Section *sec, unsigned long size); | |
| 1102 | −ST_FUNC Section *find_section(TCCState *s1, const char *name); | |
| 1103 | − | |
| 1104 | −ST_FUNC void put_extern_sym2(Sym *sym, Section *section, addr_t value, unsigned long size, int can_add_underscore); | |
| 1105 | −ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size); | |
| 1106 | −ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type); | |
| 1107 | −ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, addr_t addend); | |
| 1108 | − | |
| 1109 | 1098 | ST_INLN void sym_free(Sym *sym); |
| 1110 | 1099 | ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c); |
| 1111 | 1100 | ST_FUNC Sym *sym_find2(Sym *s, int v); |
| @@ -1151,6 +1140,9 @@ PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f); · 39 unmodified lines | ||
| 1151 | 1140 | PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time); |
| 1152 | 1141 | PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv); |
| 1153 | 1142 | PUB_FUNC void tcc_set_environment(TCCState *s); |
| 1143 | +#ifdef _WIN32 | |
| 1144 | +ST_FUNC char *normalize_slashes(char *path); | |
| 1145 | +#endif | |
| 1154 | 1146 | |
| 1155 | 1147 | /* ------------ tccpp.c ------------ */ |
| 1156 | 1148 | |
| @@ -1232,21 +1224,6 @@ static inline int toup(int c) { · 75 unmodified lines | ||
| 1232 | 1224 | |
| 1233 | 1225 | /* ------------ tccgen.c ------------ */ |
| 1234 | 1226 | |
| 1235 | −ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */ | |
| 1236 | −ST_DATA Section *cur_text_section; /* current section where function code is generated */ | |
| 1237 | −#ifdef CONFIG_TCC_ASM | |
| 1238 | −ST_DATA Section *last_text_section; /* to handle .previous asm directive */ | |
| 1239 | −#endif | |
| 1240 | −#ifdef CONFIG_TCC_BCHECK | |
| 1241 | −/* bound check related sections */ | |
| 1242 | −ST_DATA Section *bounds_section; /* contains global data bound description */ | |
| 1243 | −ST_DATA Section *lbounds_section; /* contains local data bound description */ | |
| 1244 | −#endif | |
| 1245 | −/* symbol sections */ | |
| 1246 | −ST_DATA Section *symtab_section, *strtab_section; | |
| 1247 | −/* debug sections */ | |
| 1248 | −ST_DATA Section *stab_section, *stabstr_section; | |
| 1249 | − | |
| 1250 | 1227 | #define SYM_POOL_NB (8192 / sizeof(Sym)) |
| 1251 | 1228 | ST_DATA Sym *sym_free_first; |
| 1252 | 1229 | ST_DATA void **sym_pools; |
| @@ -1271,6 +1248,9 @@ ST_DATA int func_vc; · 18 unmodified lines | ||
| 1271 | 1248 | ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */ |
| 1272 | 1249 | ST_DATA const char *funcname; |
| 1273 | 1250 | |
| 1251 | +ST_FUNC void tccgen_start(TCCState *s1); | |
| 1252 | +ST_FUNC void tccgen_end(TCCState *s1); | |
| 1253 | + | |
| 1274 | 1254 | ST_FUNC void check_vstack(void); |
| 1275 | 1255 | ST_INLN int is_float(int t); |
| 1276 | 1256 | ST_FUNC int ieee_finite(double d); |
| @@ -1335,8 +1315,35 @@ typedef struct { · 58 unmodified lines | ||
| 1335 | 1315 | unsigned int n_value; /* value of symbol */ |
| 1336 | 1316 | } Stab_Sym; |
| 1337 | 1317 | |
| 1318 | +ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */ | |
| 1319 | +ST_DATA Section *cur_text_section; /* current section where function code is generated */ | |
| 1320 | +#ifdef CONFIG_TCC_ASM | |
| 1321 | +ST_DATA Section *last_text_section; /* to handle .previous asm directive */ | |
| 1322 | +#endif | |
| 1323 | +#ifdef CONFIG_TCC_BCHECK | |
| 1324 | +/* bound check related sections */ | |
| 1325 | +ST_DATA Section *bounds_section; /* contains global data bound description */ | |
| 1326 | +ST_DATA Section *lbounds_section; /* contains local data bound description */ | |
| 1327 | +#endif | |
| 1328 | +/* symbol sections */ | |
| 1329 | +ST_DATA Section *symtab_section, *strtab_section; | |
| 1330 | +/* debug sections */ | |
| 1331 | +ST_DATA Section *stab_section, *stabstr_section; | |
| 1332 | + | |
| 1333 | +ST_FUNC void tccelf_new(TCCState *s); | |
| 1334 | +ST_FUNC void tccelf_delete(TCCState *s); | |
| 1335 | +ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags); | |
| 1336 | +ST_FUNC void section_realloc(Section *sec, unsigned long new_size); | |
| 1337 | +ST_FUNC void *section_ptr_add(Section *sec, addr_t size); | |
| 1338 | +ST_FUNC void section_reserve(Section *sec, unsigned long size); | |
| 1339 | +ST_FUNC Section *find_section(TCCState *s1, const char *name); | |
| 1338 | 1340 | ST_FUNC Section *new_symtab(TCCState *s1, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags); |
| 1339 | 1341 | |
| 1342 | +ST_FUNC void put_extern_sym2(Sym *sym, Section *section, addr_t value, unsigned long size, int can_add_underscore); | |
| 1343 | +ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size); | |
| 1344 | +ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type); | |
| 1345 | +ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, addr_t addend); | |
| 1346 | + | |
| 1340 | 1347 | ST_FUNC int put_elf_str(Section *s, const char *sym); |
| 1341 | 1348 | ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name); |
| 1342 | 1349 | ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int sh_num, const char *name); |
| @@ -23,9 +23,178 @@ · 22 unmodified lines | ||
| 23 | 23 | /* Define this to get some debug output during relocation processing. */ |
| 24 | 24 | #undef DEBUG_RELOC |
| 25 | 25 | |
| 26 | +/********************************************************/ | |
| 27 | +/* global variables */ | |
| 28 | + | |
| 29 | +ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */ | |
| 30 | +ST_DATA Section *cur_text_section; /* current section where function code is generated */ | |
| 31 | +#ifdef CONFIG_TCC_ASM | |
| 32 | +ST_DATA Section *last_text_section; /* to handle .previous asm directive */ | |
| 33 | +#endif | |
| 34 | +#ifdef CONFIG_TCC_BCHECK | |
| 35 | +/* bound check related sections */ | |
| 36 | +ST_DATA Section *bounds_section; /* contains global data bound description */ | |
| 37 | +ST_DATA Section *lbounds_section; /* contains local data bound description */ | |
| 38 | +#endif | |
| 39 | +/* symbol sections */ | |
| 40 | +ST_DATA Section *symtab_section, *strtab_section; | |
| 41 | +/* debug sections */ | |
| 42 | +ST_DATA Section *stab_section, *stabstr_section; | |
| 43 | + | |
| 26 | 44 | /* XXX: avoid static variable */ |
| 27 | 45 | static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */ |
| 28 | 46 | |
| 47 | +/* ------------------------------------------------------------------------- */ | |
| 48 | + | |
| 49 | +ST_FUNC void tccelf_new(TCCState *s) | |
| 50 | +{ | |
| 51 | + /* no section zero */ | |
| 52 | + dynarray_add((void ***)&s->sections, &s->nb_sections, NULL); | |
| 53 | + | |
| 54 | + /* create standard sections */ | |
| 55 | + text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR); | |
| 56 | + data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); | |
| 57 | + bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); | |
| 58 | + | |
| 59 | + /* symbols are always generated for linking stage */ | |
| 60 | + symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0, | |
| 61 | + ".strtab", | |
| 62 | + ".hashtab", SHF_PRIVATE); | |
| 63 | + strtab_section = symtab_section->link; | |
| 64 | + s->symtab = symtab_section; | |
| 65 | + | |
| 66 | + /* private symbol table for dynamic symbols */ | |
| 67 | + s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE, | |
| 68 | + ".dynstrtab", | |
| 69 | + ".dynhashtab", SHF_PRIVATE); | |
| 70 | +} | |
| 71 | + | |
| 72 | +static void free_section(Section *s) | |
| 73 | +{ | |
| 74 | + tcc_free(s->data); | |
| 75 | +} | |
| 76 | + | |
| 77 | +ST_FUNC void tccelf_delete(TCCState *s1) | |
| 78 | +{ | |
| 79 | + int i; | |
| 80 | + | |
| 81 | + /* free all sections */ | |
| 82 | + for(i = 1; i < s1->nb_sections; i++) | |
| 83 | + free_section(s1->sections[i]); | |
| 84 | + dynarray_reset(&s1->sections, &s1->nb_sections); | |
| 85 | + | |
| 86 | + for(i = 0; i < s1->nb_priv_sections; i++) | |
| 87 | + free_section(s1->priv_sections[i]); | |
| 88 | + dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections); | |
| 89 | + | |
| 90 | + /* free any loaded DLLs */ | |
| 91 | +#ifdef TCC_IS_NATIVE | |
| 92 | + for ( i = 0; i < s1->nb_loaded_dlls; i++) { | |
| 93 | + DLLReference *ref = s1->loaded_dlls[i]; | |
| 94 | + if ( ref->handle ) | |
| 95 | +# ifdef _WIN32 | |
| 96 | + FreeLibrary((HMODULE)ref->handle); | |
| 97 | +# else | |
| 98 | + dlclose(ref->handle); | |
| 99 | +# endif | |
| 100 | + } | |
| 101 | +#endif | |
| 102 | + /* free loaded dlls array */ | |
| 103 | + dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls); | |
| 104 | +} | |
| 105 | + | |
| 106 | +ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags) | |
| 107 | +{ | |
| 108 | + Section *sec; | |
| 109 | + | |
| 110 | + sec = tcc_mallocz(sizeof(Section) + strlen(name)); | |
| 111 | + strcpy(sec->name, name); | |
| 112 | + sec->sh_type = sh_type; | |
| 113 | + sec->sh_flags = sh_flags; | |
| 114 | + switch(sh_type) { | |
| 115 | + case SHT_HASH: | |
| 116 | + case SHT_REL: | |
| 117 | + case SHT_RELA: | |
| 118 | + case SHT_DYNSYM: | |
| 119 | + case SHT_SYMTAB: | |
| 120 | + case SHT_DYNAMIC: | |
| 121 | + sec->sh_addralign = 4; | |
| 122 | + break; | |
| 123 | + case SHT_STRTAB: | |
| 124 | + sec->sh_addralign = 1; | |
| 125 | + break; | |
| 126 | + default: | |
| 127 | + sec->sh_addralign = PTR_SIZE; /* gcc/pcc default aligment */ | |
| 128 | + break; | |
| 129 | + } | |
| 130 | + | |
| 131 | + if (sh_flags & SHF_PRIVATE) { | |
| 132 | + dynarray_add((void ***)&s1->priv_sections, &s1->nb_priv_sections, sec); | |
| 133 | + } else { | |
| 134 | + sec->sh_num = s1->nb_sections; | |
| 135 | + dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec); | |
| 136 | + } | |
| 137 | + | |
| 138 | + return sec; | |
| 139 | +} | |
| 140 | + | |
| 141 | +/* realloc section and set its content to zero */ | |
| 142 | +ST_FUNC void section_realloc(Section *sec, unsigned long new_size) | |
| 143 | +{ | |
| 144 | + unsigned long size; | |
| 145 | + unsigned char *data; | |
| 146 | + | |
| 147 | + size = sec->data_allocated; | |
| 148 | + if (size == 0) | |
| 149 | + size = 1; | |
| 150 | + while (size < new_size) | |
| 151 | + size = size * 2; | |
| 152 | + data = tcc_realloc(sec->data, size); | |
| 153 | + memset(data + sec->data_allocated, 0, size - sec->data_allocated); | |
| 154 | + sec->data = data; | |
| 155 | + sec->data_allocated = size; | |
| 156 | +} | |
| 157 | + | |
| 158 | +/* reserve at least 'size' bytes in section 'sec' from | |
| 159 | + sec->data_offset. */ | |
| 160 | +ST_FUNC void *section_ptr_add(Section *sec, addr_t size) | |
| 161 | +{ | |
| 162 | + size_t offset, offset1; | |
| 163 | + | |
| 164 | + offset = sec->data_offset; | |
| 165 | + offset1 = offset + size; | |
| 166 | + if (offset1 > sec->data_allocated) | |
| 167 | + section_realloc(sec, offset1); | |
| 168 | + sec->data_offset = offset1; | |
| 169 | + return sec->data + offset; | |
| 170 | +} | |
| 171 | + | |
| 172 | +/* reserve at least 'size' bytes from section start */ | |
| 173 | +ST_FUNC void section_reserve(Section *sec, unsigned long size) | |
| 174 | +{ | |
| 175 | + if (size > sec->data_allocated) | |
| 176 | + section_realloc(sec, size); | |
| 177 | + if (size > sec->data_offset) | |
| 178 | + sec->data_offset = size; | |
| 179 | +} | |
| 180 | + | |
| 181 | +/* return a reference to a section, and create it if it does not | |
| 182 | + exists */ | |
| 183 | +ST_FUNC Section *find_section(TCCState *s1, const char *name) | |
| 184 | +{ | |
| 185 | + Section *sec; | |
| 186 | + int i; | |
| 187 | + for(i = 1; i < s1->nb_sections; i++) { | |
| 188 | + sec = s1->sections[i]; | |
| 189 | + if (!strcmp(name, sec->name)) | |
| 190 | + return sec; | |
| 191 | + } | |
| 192 | + /* sections are created as PROGBITS */ | |
| 193 | + return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC); | |
| 194 | +} | |
| 195 | + | |
| 196 | +/* ------------------------------------------------------------------------- */ | |
| 197 | + | |
| 29 | 198 | ST_FUNC int put_elf_str(Section *s, const char *sym) |
| 30 | 199 | { |
| 31 | 200 | int offset, len; |
| @@ -30,20 +30,6 @@ · 29 unmodified lines | ||
| 30 | 30 | */ |
| 31 | 31 | ST_DATA int rsym, anon_sym, ind, loc; |
| 32 | 32 | |
| 33 | −ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */ | |
| 34 | −ST_DATA Section *cur_text_section; /* current section where function code is generated */ | |
| 35 | −#ifdef CONFIG_TCC_ASM | |
| 36 | −ST_DATA Section *last_text_section; /* to handle .previous asm directive */ | |
| 37 | −#endif | |
| 38 | −#ifdef CONFIG_TCC_BCHECK | |
| 39 | −/* bound check related sections */ | |
| 40 | −ST_DATA Section *bounds_section; /* contains global data bound description */ | |
| 41 | −ST_DATA Section *lbounds_section; /* contains local data bound description */ | |
| 42 | −#endif | |
| 43 | −/* symbol sections */ | |
| 44 | −ST_DATA Section *symtab_section, *strtab_section; | |
| 45 | −/* debug sections */ | |
| 46 | −ST_DATA Section *stab_section, *stabstr_section; | |
| 47 | 33 | ST_DATA Sym *sym_free_first; |
| 48 | 34 | ST_DATA void **sym_pools; |
| 49 | 35 | ST_DATA int nb_sym_pools; |
| @@ -55,6 +41,7 @@ ST_DATA Sym *global_label_stack; · 5 unmodified lines | ||
| 55 | 41 | ST_DATA Sym *local_label_stack; |
| 56 | 42 | static int local_scope; |
| 57 | 43 | static int in_sizeof; |
| 44 | +static int section_sym; | |
| 58 | 45 | |
| 59 | 46 | ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */ |
| 60 | 47 | ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */ |
| @@ -148,6 +135,217 @@ void pv (const char *lbl, int a, int b) · 87 unmodified lines | ||
| 148 | 135 | } |
| 149 | 136 | #endif |
| 150 | 137 | |
| 138 | +/* ------------------------------------------------------------------------- */ | |
| 139 | +ST_FUNC void tccgen_start(TCCState *s1) | |
| 140 | +{ | |
| 141 | + cur_text_section = NULL; | |
| 142 | + funcname = ""; | |
| 143 | + anon_sym = SYM_FIRST_ANOM; | |
| 144 | + section_sym = 0; | |
| 145 | + nocode_wanted = 1; | |
| 146 | + | |
| 147 | + /* define some often used types */ | |
| 148 | + int_type.t = VT_INT; | |
| 149 | + char_pointer_type.t = VT_BYTE; | |
| 150 | + mk_pointer(&char_pointer_type); | |
| 151 | +#if PTR_SIZE == 4 | |
| 152 | + size_type.t = VT_INT; | |
| 153 | +#else | |
| 154 | + size_type.t = VT_LLONG; | |
| 155 | +#endif | |
| 156 | + func_old_type.t = VT_FUNC; | |
| 157 | + func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD); | |
| 158 | + | |
| 159 | + if (s1->do_debug) { | |
| 160 | + char buf[512]; | |
| 161 | + | |
| 162 | + /* file info: full path + filename */ | |
| 163 | + section_sym = put_elf_sym(symtab_section, 0, 0, | |
| 164 | + ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0, | |
| 165 | + text_section->sh_num, NULL); | |
| 166 | + getcwd(buf, sizeof(buf)); | |
| 167 | +#ifdef _WIN32 | |
| 168 | + normalize_slashes(buf); | |
| 169 | +#endif | |
| 170 | + pstrcat(buf, sizeof(buf), "/"); | |
| 171 | + put_stabs_r(buf, N_SO, 0, 0, | |
| 172 | + text_section->data_offset, text_section, section_sym); | |
| 173 | + put_stabs_r(file->filename, N_SO, 0, 0, | |
| 174 | + text_section->data_offset, text_section, section_sym); | |
| 175 | + } | |
| 176 | + /* an elf symbol of type STT_FILE must be put so that STB_LOCAL | |
| 177 | + symbols can be safely used */ | |
| 178 | + put_elf_sym(symtab_section, 0, 0, | |
| 179 | + ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0, | |
| 180 | + SHN_ABS, file->filename); | |
| 181 | + | |
| 182 | +#ifdef TCC_TARGET_ARM | |
| 183 | + arm_init(s1); | |
| 184 | +#endif | |
| 185 | + | |
| 186 | +#if 0 | |
| 187 | + /* define 'void *alloca(unsigned int)' builtin function */ | |
| 188 | + { | |
| 189 | + Sym *s1; | |
| 190 | + | |
| 191 | + p = anon_sym++; | |
| 192 | + sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW); | |
| 193 | + s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0); | |
| 194 | + s1->next = NULL; | |
| 195 | + sym->next = s1; | |
| 196 | + sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0); | |
| 197 | + } | |
| 198 | +#endif | |
| 199 | +} | |
| 200 | + | |
| 201 | +ST_FUNC void tccgen_end(TCCState *s1) | |
| 202 | +{ | |
| 203 | + check_vstack(); | |
| 204 | + /* end of translation unit info */ | |
| 205 | + if (s1->do_debug) { | |
| 206 | + put_stabs_r(NULL, N_SO, 0, 0, | |
| 207 | + text_section->data_offset, text_section, section_sym); | |
| 208 | + } | |
| 209 | +} | |
| 210 | + | |
| 211 | +/* ------------------------------------------------------------------------- */ | |
| 212 | +/* update sym->c so that it points to an external symbol in section | |
| 213 | + 'section' with value 'value' */ | |
| 214 | + | |
| 215 | +ST_FUNC void put_extern_sym2(Sym *sym, Section *section, | |
| 216 | + addr_t value, unsigned long size, | |
| 217 | + int can_add_underscore) | |
| 218 | +{ | |
| 219 | + int sym_type, sym_bind, sh_num, info, other; | |
| 220 | + ElfW(Sym) *esym; | |
| 221 | + const char *name; | |
| 222 | + char buf1[256]; | |
| 223 | + | |
| 224 | +#ifdef CONFIG_TCC_BCHECK | |
| 225 | + char buf[32]; | |
| 226 | +#endif | |
| 227 | + | |
| 228 | + if (section == NULL) | |
| 229 | + sh_num = SHN_UNDEF; | |
| 230 | + else if (section == SECTION_ABS) | |
| 231 | + sh_num = SHN_ABS; | |
| 232 | + else | |
| 233 | + sh_num = section->sh_num; | |
| 234 | + | |
| 235 | + if ((sym->type.t & VT_BTYPE) == VT_FUNC) { | |
| 236 | + sym_type = STT_FUNC; | |
| 237 | + } else if ((sym->type.t & VT_BTYPE) == VT_VOID) { | |
| 238 | + sym_type = STT_NOTYPE; | |
| 239 | + } else { | |
| 240 | + sym_type = STT_OBJECT; | |
| 241 | + } | |
| 242 | + | |
| 243 | + if (sym->type.t & VT_STATIC) | |
| 244 | + sym_bind = STB_LOCAL; | |
| 245 | + else { | |
| 246 | + if (sym->type.t & VT_WEAK) | |
| 247 | + sym_bind = STB_WEAK; | |
| 248 | + else | |
| 249 | + sym_bind = STB_GLOBAL; | |
| 250 | + } | |
| 251 | + | |
| 252 | + if (!sym->c) { | |
| 253 | + name = get_tok_str(sym->v, NULL); | |
| 254 | +#ifdef CONFIG_TCC_BCHECK | |
| 255 | + if (tcc_state->do_bounds_check) { | |
| 256 | + /* XXX: avoid doing that for statics ? */ | |
| 257 | + /* if bound checking is activated, we change some function | |
| 258 | + names by adding the "__bound" prefix */ | |
| 259 | + switch(sym->v) { | |
| 260 | +#ifdef TCC_TARGET_PE | |
| 261 | + /* XXX: we rely only on malloc hooks */ | |
| 262 | + case TOK_malloc: | |
| 263 | + case TOK_free: | |
| 264 | + case TOK_realloc: | |
| 265 | + case TOK_memalign: | |
| 266 | + case TOK_calloc: | |
| 267 | +#endif | |
| 268 | + case TOK_memcpy: | |
| 269 | + case TOK_memmove: | |
| 270 | + case TOK_memset: | |
| 271 | + case TOK_strlen: | |
| 272 | + case TOK_strcpy: | |
| 273 | + case TOK_alloca: | |
| 274 | + strcpy(buf, "__bound_"); | |
| 275 | + strcat(buf, name); | |
| 276 | + name = buf; | |
| 277 | + break; | |
| 278 | + } | |
| 279 | + } | |
| 280 | +#endif | |
| 281 | + other = 0; | |
| 282 | + | |
| 283 | +#ifdef TCC_TARGET_PE | |
| 284 | + if (sym->type.t & VT_EXPORT) | |
| 285 | + other |= ST_PE_EXPORT; | |
| 286 | + if (sym_type == STT_FUNC && sym->type.ref) { | |
| 287 | + Sym *ref = sym->type.ref; | |
| 288 | + if (ref->a.func_export) | |
| 289 | + other |= ST_PE_EXPORT; | |
| 290 | + if (ref->a.func_call == FUNC_STDCALL && can_add_underscore) { | |
| 291 | + sprintf(buf1, "_%s@%d", name, ref->a.func_args * PTR_SIZE); | |
| 292 | + name = buf1; | |
| 293 | + other |= ST_PE_STDCALL; | |
| 294 | + can_add_underscore = 0; | |
| 295 | + } | |
| 296 | + } else { | |
| 297 | + if (find_elf_sym(tcc_state->dynsymtab_section, name)) | |
| 298 | + other |= ST_PE_IMPORT; | |
| 299 | + if (sym->type.t & VT_IMPORT) | |
| 300 | + other |= ST_PE_IMPORT; | |
| 301 | + } | |
| 302 | +#else | |
| 303 | + if (! (sym->type.t & VT_STATIC)) | |
| 304 | + other = (sym->type.t & VT_VIS_MASK) >> VT_VIS_SHIFT; | |
| 305 | +#endif | |
| 306 | + if (tcc_state->leading_underscore && can_add_underscore) { | |
| 307 | + buf1[0] = '_'; | |
| 308 | + pstrcpy(buf1 + 1, sizeof(buf1) - 1, name); | |
| 309 | + name = buf1; | |
| 310 | + } | |
| 311 | + if (sym->asm_label) { | |
| 312 | + name = get_tok_str(sym->asm_label, NULL); | |
| 313 | + } | |
| 314 | + info = ELFW(ST_INFO)(sym_bind, sym_type); | |
| 315 | + sym->c = add_elf_sym(symtab_section, value, size, info, other, sh_num, name); | |
| 316 | + } else { | |
| 317 | + esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; | |
| 318 | + esym->st_value = value; | |
| 319 | + esym->st_size = size; | |
| 320 | + esym->st_shndx = sh_num; | |
| 321 | + } | |
| 322 | +} | |
| 323 | + | |
| 324 | +ST_FUNC void put_extern_sym(Sym *sym, Section *section, | |
| 325 | + addr_t value, unsigned long size) | |
| 326 | +{ | |
| 327 | + put_extern_sym2(sym, section, value, size, 1); | |
| 328 | +} | |
| 329 | + | |
| 330 | +/* add a new relocation entry to symbol 'sym' in section 's' */ | |
| 331 | +ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, | |
| 332 | + addr_t addend) | |
| 333 | +{ | |
| 334 | + int c = 0; | |
| 335 | + if (sym) { | |
| 336 | + if (0 == sym->c) | |
| 337 | + put_extern_sym(sym, NULL, 0, 0); | |
| 338 | + c = sym->c; | |
| 339 | + } | |
| 340 | + /* now we can add ELF relocation info */ | |
| 341 | + put_elf_reloca(symtab_section, s, offset, type, c, addend); | |
| 342 | +} | |
| 343 | + | |
| 344 | +ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type) | |
| 345 | +{ | |
| 346 | + greloca(s, sym, offset, type, 0); | |
| 347 | +} | |
| 348 | + | |
| 151 | 349 | /* ------------------------------------------------------------------------- */ |
| 152 | 350 | /* symbol allocator */ |
| 153 | 351 | static Sym *__sym_malloc(void) |
| @@ -6607,3 +6805,5 @@ ST_FUNC void decl(int l) · 6453 unmodified lines | ||
| 6607 | 6805 | { |
| 6608 | 6806 | decl0(l, 0); |
| 6609 | 6807 | } |
| 6808 | + | |
| 6809 | +/* ------------------------------------------------------------------------- */ | |