History

tccgen/tccelf: move code from libtcc.c

grischka committed 10 years ago

Commit 4d247c01 parent 3e324794 files · +512 −482Browse files

Unified · Split

4 files
  1. libtcc.c +96 −442
  2. tcc.h +33 −26
  3. tccelf.c +169 −0
  4. tccgen.c +214 −14
libtcc.c+96−442
@@ -82,7 +82,7 @@ ST_FUNC void asm_global_instr(void) · 81 unmodified lines
8282
8383 /********************************************************/
8484 #ifdef _WIN32
85−static char *normalize_slashes(char *path)
85+ST_FUNC char *normalize_slashes(char *path)
8686 {
8787 char *p;
8888 for (p = path; *p; ++p)
@@ -116,13 +116,6 @@ static void tcc_add_systemdir(TCCState *s) · 27 unmodified lines
116116 }
117117 #endif
118118
119−#if defined TCC_IS_NATIVE
120−static void dlclose(void *p)
121−{
122− FreeLibrary((HMODULE)p);
123−}
124−#endif
125−
126119 #ifdef LIBTCC_AS_DLL
127120 BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved)
128121 {
@@ -492,239 +485,6 @@ static void tcc_split_path(TCCState *s, void ***p_ary, int *p_nb_ary, const char · 363 unmodified lines
492485
493486 /********************************************************/
494487
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−
728488 static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
729489 {
730490 int len;
@@ -886,79 +646,18 @@ ST_FUNC int tcc_open(TCCState *s1, const char *filename) · 155 unmodified lines
886646 static int tcc_compile(TCCState *s1)
887647 {
888648 Sym *define_start;
889− char buf[512];
890− volatile int section_sym;
891649
892−#ifdef INC_DEBUG
893− printf("%s: **** new file\n", file->filename);
894−#endif
895650 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−
955651 define_start = define_stack;
956− nocode_wanted = 1;
957652
958653 if (setjmp(s1->error_jmp_buf) == 0) {
959654 s1->nb_errors = 0;
960655 s1->error_set_jmp_enabled = 1;
961656
657+ tccgen_start(s1);
658+#ifdef INC_DEBUG
659+ printf("%s: **** new file\n", file->filename);
660+#endif
962661 ch = file->buf_ptr[0];
963662 tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
964663 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
967666 if (tok != TOK_EOF)
968667 expect("declaration");
969668 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);
976670 }
977671
978672 s1->error_set_jmp_enabled = 0;
@@ -1049,21 +743,37 @@ static void tcc_cleanup(void) · 70 unmodified lines
1049743 LIBTCCAPI TCCState *tcc_new(void)
1050744 {
1051745 TCCState *s;
1052− char buffer[100];
1053− int a,b,c;
1054−
1055746 tcc_cleanup();
1056747
1057748 s = tcc_mallocz(sizeof(TCCState));
1058749 if (!s)
1059750 return NULL;
1060751 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
1061770 #ifdef _WIN32
1062771 tcc_set_lib_path_w32(s);
1063772 #else
1064773 tcc_set_lib_path(s, CONFIG_TCCDIR);
1065774 #endif
1066775
776+ tccelf_new(s);
1067777 preprocess_new();
1068778 s->include_stack_ptr = s->include_stack;
1069779
@@ -1073,11 +783,13 @@ LIBTCCAPI TCCState *tcc_new(void) · 3 unmodified lines
1073783 define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
1074784 define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
1075785 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+ }
1081793
1082794 /* standard defines */
1083795 tcc_define_symbol(s, "__STDC__", NULL);
@@ -1178,82 +890,22 @@ LIBTCCAPI TCCState *tcc_new(void) · 94 unmodified lines
1178890 #else
1179891 tcc_define_symbol(s, "__WINT_TYPE__", "unsigned int");
1180892 #endif
1181−#endif
1182−
1183−#ifndef TCC_TARGET_PE
1184893 /* glibc defines */
1185894 tcc_define_symbol(s, "__REDIRECT(name, proto, alias)", "name proto __asm__ (#alias)");
1186895 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);
1189896 #endif
1190897
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
1227898 return s;
1228899 }
1229900
1230901 LIBTCCAPI void tcc_delete(TCCState *s1)
1231902 {
1232− int i;
1233903 int bench = s1->do_bench;
1234904
1235905 tcc_cleanup();
1236906
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);
1257909
1258910 /* free library paths */
1259911 dynarray_reset(&s1->library_paths, &s1->nb_library_paths);
@@ -1289,6 +941,68 @@ LIBTCCAPI void tcc_delete(TCCState *s1) · 29 unmodified lines
1289941 tcc_memstats(bench);
1290942 }
1291943
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+
12921006 LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname)
12931007 {
12941008 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
15031217 return 0;
15041218 }
15051219
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−
15661220 LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path)
15671221 {
15681222 tcc_free(s->tcc_lib_path);
tcc.h+33−26
@@ -1095,17 +1095,6 @@ ST_FUNC void cstr_new(CString *cstr); · 1094 unmodified lines
10951095 ST_FUNC void cstr_free(CString *cstr);
10961096 ST_FUNC void cstr_reset(CString *cstr);
10971097
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−
11091098 ST_INLN void sym_free(Sym *sym);
11101099 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c);
11111100 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
11511140 PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time);
11521141 PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv);
11531142 PUB_FUNC void tcc_set_environment(TCCState *s);
1143+#ifdef _WIN32
1144+ST_FUNC char *normalize_slashes(char *path);
1145+#endif
11541146
11551147 /* ------------ tccpp.c ------------ */
11561148
@@ -1232,21 +1224,6 @@ static inline int toup(int c) { · 75 unmodified lines
12321224
12331225 /* ------------ tccgen.c ------------ */
12341226
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−
12501227 #define SYM_POOL_NB (8192 / sizeof(Sym))
12511228 ST_DATA Sym *sym_free_first;
12521229 ST_DATA void **sym_pools;
@@ -1271,6 +1248,9 @@ ST_DATA int func_vc; · 18 unmodified lines
12711248 ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
12721249 ST_DATA const char *funcname;
12731250
1251+ST_FUNC void tccgen_start(TCCState *s1);
1252+ST_FUNC void tccgen_end(TCCState *s1);
1253+
12741254 ST_FUNC void check_vstack(void);
12751255 ST_INLN int is_float(int t);
12761256 ST_FUNC int ieee_finite(double d);
@@ -1335,8 +1315,35 @@ typedef struct { · 58 unmodified lines
13351315 unsigned int n_value; /* value of symbol */
13361316 } Stab_Sym;
13371317
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);
13381340 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);
13391341
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+
13401347 ST_FUNC int put_elf_str(Section *s, const char *sym);
13411348 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);
13421349 ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int sh_num, const char *name);
tccelf.c+169−0
@@ -23,9 +23,178 @@ · 22 unmodified lines
2323 /* Define this to get some debug output during relocation processing. */
2424 #undef DEBUG_RELOC
2525
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+
2644 /* XXX: avoid static variable */
2745 static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */
2846
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+
29198 ST_FUNC int put_elf_str(Section *s, const char *sym)
30199 {
31200 int offset, len;
tccgen.c+214−14
@@ -30,20 +30,6 @@ · 29 unmodified lines
3030 */
3131 ST_DATA int rsym, anon_sym, ind, loc;
3232
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;
4733 ST_DATA Sym *sym_free_first;
4834 ST_DATA void **sym_pools;
4935 ST_DATA int nb_sym_pools;
@@ -55,6 +41,7 @@ ST_DATA Sym *global_label_stack; · 5 unmodified lines
5541 ST_DATA Sym *local_label_stack;
5642 static int local_scope;
5743 static int in_sizeof;
44+static int section_sym;
5845
5946 ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */
6047 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
148135 }
149136 #endif
150137
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+
151349 /* ------------------------------------------------------------------------- */
152350 /* symbol allocator */
153351 static Sym *__sym_malloc(void)
@@ -6607,3 +6805,5 @@ ST_FUNC void decl(int l) · 6453 unmodified lines
66076805 {
66086806 decl0(l, 0);
66096807 }
6808+
6809+/* ------------------------------------------------------------------------- */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t