Unified · Split
| @@ -82,7 +82,7 @@ ST_FUNC void asm_global_instr(void) · 81 unmodified lines | |||
| 82 | 82 | ||
| 83 | /********************************************************/ | 83 | /********************************************************/ |
| 84 | #ifdef _WIN32 | 84 | #ifdef _WIN32 |
| 85 | static char *normalize_slashes(char *path) | 85 | ST_FUNC char *normalize_slashes(char *path) |
| 86 | { | 86 | { |
| 87 | char *p; | 87 | char *p; |
| 88 | for (p = path; *p; ++p) | 88 | for (p = path; *p; ++p) |
| @@ -116,13 +116,6 @@ static void tcc_add_systemdir(TCCState *s) · 27 unmodified lines | |||
| 116 | } | 116 | } |
| 117 | #endif | 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 | #ifdef LIBTCC_AS_DLL | 119 | #ifdef LIBTCC_AS_DLL |
| 127 | BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) | 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 | static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap) | 488 | static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap) |
| 729 | { | 489 | { |
| 730 | int len; | 490 | int len; |
| @@ -886,79 +646,18 @@ ST_FUNC int tcc_open(TCCState *s1, const char *filename) · 155 unmodified lines | |||
| 886 | static int tcc_compile(TCCState *s1) | 646 | static int tcc_compile(TCCState *s1) |
| 887 | { | 647 | { |
| 888 | Sym *define_start; | 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 | preprocess_init(s1); | 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 | define_start = define_stack; | 651 | define_start = define_stack; |
| 956 | nocode_wanted = 1; | ||
| 957 | 652 | ||
| 958 | if (setjmp(s1->error_jmp_buf) == 0) { | 653 | if (setjmp(s1->error_jmp_buf) == 0) { |
| 959 | s1->nb_errors = 0; | 654 | s1->nb_errors = 0; |
| 960 | s1->error_set_jmp_enabled = 1; | 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 | ch = file->buf_ptr[0]; | 661 | ch = file->buf_ptr[0]; |
| 963 | tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; | 662 | tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; |
| 964 | parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR; | 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 | if (tok != TOK_EOF) | 666 | if (tok != TOK_EOF) |
| 968 | expect("declaration"); | 667 | expect("declaration"); |
| 969 | gen_inline_functions(); | 668 | gen_inline_functions(); |
| 970 | check_vstack(); | 669 | tccgen_end(s1); |
| 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 | } | ||
| 976 | } | 670 | } |
| 977 | 671 | ||
| 978 | s1->error_set_jmp_enabled = 0; | 672 | s1->error_set_jmp_enabled = 0; |
| @@ -1049,21 +743,37 @@ static void tcc_cleanup(void) · 70 unmodified lines | |||
| 1049 | LIBTCCAPI TCCState *tcc_new(void) | 743 | LIBTCCAPI TCCState *tcc_new(void) |
| 1050 | { | 744 | { |
| 1051 | TCCState *s; | 745 | TCCState *s; |
| 1052 | char buffer[100]; | ||
| 1053 | int a,b,c; | ||
| 1054 | |||
| 1055 | tcc_cleanup(); | 746 | tcc_cleanup(); |
| 1056 | 747 | ||
| 1057 | s = tcc_mallocz(sizeof(TCCState)); | 748 | s = tcc_mallocz(sizeof(TCCState)); |
| 1058 | if (!s) | 749 | if (!s) |
| 1059 | return NULL; | 750 | return NULL; |
| 1060 | tcc_state = s; | 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 | #ifdef _WIN32 | 770 | #ifdef _WIN32 |
| 1062 | tcc_set_lib_path_w32(s); | 771 | tcc_set_lib_path_w32(s); |
| 1063 | #else | 772 | #else |
| 1064 | tcc_set_lib_path(s, CONFIG_TCCDIR); | 773 | tcc_set_lib_path(s, CONFIG_TCCDIR); |
| 1065 | #endif | 774 | #endif |
| 1066 | 775 | ||
| 776 | tccelf_new(s); | ||
| 1067 | preprocess_new(); | 777 | preprocess_new(); |
| 1068 | s->include_stack_ptr = s->include_stack; | 778 | s->include_stack_ptr = s->include_stack; |
| 1069 | 779 | ||
| @@ -1073,11 +783,13 @@ LIBTCCAPI TCCState *tcc_new(void) · 3 unmodified lines | |||
| 1073 | define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL); | 783 | define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL); |
| 1074 | define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL); | 784 | define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL); |
| 1075 | define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL); | 785 | define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL); |
| 1076 | 786 | { | |
| 1077 | /* define __TINYC__ 92X */ | 787 | /* define __TINYC__ 92X */ |
| 1078 | sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c); | 788 | char buffer[32]; int a,b,c; |
| 1079 | sprintf(buffer, "%d", a*10000 + b*100 + c); | 789 | sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c); |
| 1080 | tcc_define_symbol(s, "__TINYC__", buffer); | 790 | sprintf(buffer, "%d", a*10000 + b*100 + c); |
| 791 | tcc_define_symbol(s, "__TINYC__", buffer); | ||
| 792 | } | ||
| 1081 | 793 | ||
| 1082 | /* standard defines */ | 794 | /* standard defines */ |
| 1083 | tcc_define_symbol(s, "__STDC__", NULL); | 795 | tcc_define_symbol(s, "__STDC__", NULL); |
| @@ -1178,82 +890,22 @@ LIBTCCAPI TCCState *tcc_new(void) · 94 unmodified lines | |||
| 1178 | #else | 890 | #else |
| 1179 | tcc_define_symbol(s, "__WINT_TYPE__", "unsigned int"); | 891 | tcc_define_symbol(s, "__WINT_TYPE__", "unsigned int"); |
| 1180 | #endif | 892 | #endif |
| 1181 | #endif | ||
| 1182 | |||
| 1183 | #ifndef TCC_TARGET_PE | ||
| 1184 | /* glibc defines */ | 893 | /* glibc defines */ |
| 1185 | tcc_define_symbol(s, "__REDIRECT(name, proto, alias)", "name proto __asm__ (#alias)"); | 894 | tcc_define_symbol(s, "__REDIRECT(name, proto, alias)", "name proto __asm__ (#alias)"); |
| 1186 | tcc_define_symbol(s, "__REDIRECT_NTH(name, proto, alias)", "name proto __asm__ (#alias) __THROW"); | 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 | #endif | 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 | return s; | 898 | return s; |
| 1228 | } | 899 | } |
| 1229 | 900 | ||
| 1230 | LIBTCCAPI void tcc_delete(TCCState *s1) | 901 | LIBTCCAPI void tcc_delete(TCCState *s1) |
| 1231 | { | 902 | { |
| 1232 | int i; | ||
| 1233 | int bench = s1->do_bench; | 903 | int bench = s1->do_bench; |
| 1234 | 904 | ||
| 1235 | tcc_cleanup(); | 905 | tcc_cleanup(); |
| 1236 | 906 | ||
| 1237 | /* free all sections */ | 907 | /* free sections */ |
| 1238 | for(i = 1; i < s1->nb_sections; i++) | 908 | tccelf_delete(s1); |
| 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); | ||
| 1257 | 909 | ||
| 1258 | /* free library paths */ | 910 | /* free library paths */ |
| 1259 | dynarray_reset(&s1->library_paths, &s1->nb_library_paths); | 911 | dynarray_reset(&s1->library_paths, &s1->nb_library_paths); |
| @@ -1289,6 +941,68 @@ LIBTCCAPI void tcc_delete(TCCState *s1) · 29 unmodified lines | |||
| 1289 | tcc_memstats(bench); | 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 | LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname) | 1006 | LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname) |
| 1293 | { | 1007 | { |
| 1294 | tcc_split_path(s, (void ***)&s->include_paths, &s->nb_include_paths, pathname); | 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 | return 0; | 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 | LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path) | 1220 | LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path) |
| 1567 | { | 1221 | { |
| 1568 | tcc_free(s->tcc_lib_path); | 1222 | tcc_free(s->tcc_lib_path); |
| @@ -1095,17 +1095,6 @@ ST_FUNC void cstr_new(CString *cstr); · 1094 unmodified lines | |||
| 1095 | ST_FUNC void cstr_free(CString *cstr); | 1095 | ST_FUNC void cstr_free(CString *cstr); |
| 1096 | ST_FUNC void cstr_reset(CString *cstr); | 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 | ST_INLN void sym_free(Sym *sym); | 1098 | ST_INLN void sym_free(Sym *sym); |
| 1110 | ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c); | 1099 | ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c); |
| 1111 | ST_FUNC Sym *sym_find2(Sym *s, int v); | 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 | PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time); | 1140 | PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time); |
| 1152 | PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv); | 1141 | PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv); |
| 1153 | PUB_FUNC void tcc_set_environment(TCCState *s); | 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 | /* ------------ tccpp.c ------------ */ | 1147 | /* ------------ tccpp.c ------------ */ |
| 1156 | 1148 | ||
| @@ -1232,21 +1224,6 @@ static inline int toup(int c) { · 75 unmodified lines | |||
| 1232 | 1224 | ||
| 1233 | /* ------------ tccgen.c ------------ */ | 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 | #define SYM_POOL_NB (8192 / sizeof(Sym)) | 1227 | #define SYM_POOL_NB (8192 / sizeof(Sym)) |
| 1251 | ST_DATA Sym *sym_free_first; | 1228 | ST_DATA Sym *sym_free_first; |
| 1252 | ST_DATA void **sym_pools; | 1229 | ST_DATA void **sym_pools; |
| @@ -1271,6 +1248,9 @@ ST_DATA int func_vc; · 18 unmodified lines | |||
| 1271 | ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */ | 1248 | ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */ |
| 1272 | ST_DATA const char *funcname; | 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 | ST_FUNC void check_vstack(void); | 1254 | ST_FUNC void check_vstack(void); |
| 1275 | ST_INLN int is_float(int t); | 1255 | ST_INLN int is_float(int t); |
| 1276 | ST_FUNC int ieee_finite(double d); | 1256 | ST_FUNC int ieee_finite(double d); |
| @@ -1335,8 +1315,35 @@ typedef struct { · 58 unmodified lines | |||
| 1335 | unsigned int n_value; /* value of symbol */ | 1315 | unsigned int n_value; /* value of symbol */ |
| 1336 | } Stab_Sym; | 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 | 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); | 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 | ST_FUNC int put_elf_str(Section *s, const char *sym); | 1347 | ST_FUNC int put_elf_str(Section *s, const char *sym); |
| 1341 | ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name); | 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 | ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int sh_num, const char *name); | 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 | /* Define this to get some debug output during relocation processing. */ | 23 | /* Define this to get some debug output during relocation processing. */ |
| 24 | #undef DEBUG_RELOC | 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 | /* XXX: avoid static variable */ | 44 | /* XXX: avoid static variable */ |
| 27 | static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */ | 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 | ST_FUNC int put_elf_str(Section *s, const char *sym) | 198 | ST_FUNC int put_elf_str(Section *s, const char *sym) |
| 30 | { | 199 | { |
| 31 | int offset, len; | 200 | int offset, len; |
| @@ -30,20 +30,6 @@ · 29 unmodified lines | |||
| 30 | */ | 30 | */ |
| 31 | ST_DATA int rsym, anon_sym, ind, loc; | 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 | ST_DATA Sym *sym_free_first; | 33 | ST_DATA Sym *sym_free_first; |
| 48 | ST_DATA void **sym_pools; | 34 | ST_DATA void **sym_pools; |
| 49 | ST_DATA int nb_sym_pools; | 35 | ST_DATA int nb_sym_pools; |
| @@ -55,6 +41,7 @@ ST_DATA Sym *global_label_stack; · 5 unmodified lines | |||
| 55 | ST_DATA Sym *local_label_stack; | 41 | ST_DATA Sym *local_label_stack; |
| 56 | static int local_scope; | 42 | static int local_scope; |
| 57 | static int in_sizeof; | 43 | static int in_sizeof; |
| 44 | static int section_sym; | ||
| 58 | 45 | ||
| 59 | ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */ | 46 | ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */ |
| 60 | ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */ | 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 | #endif | 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 | /* symbol allocator */ | 350 | /* symbol allocator */ |
| 153 | static Sym *__sym_malloc(void) | 351 | static Sym *__sym_malloc(void) |
| @@ -6607,3 +6805,5 @@ ST_FUNC void decl(int l) · 6453 unmodified lines | |||
| 6607 | { | 6805 | { |
| 6608 | decl0(l, 0); | 6806 | decl0(l, 0); |
| 6609 | } | 6807 | } |
| 6808 | |||
| 6809 | /* ------------------------------------------------------------------------- */ | ||