static struct import_symbol *pe_add_import(struct pe_info *pe, int sym_index) { int i; int dll_index; struct pe_import_info *p; struct import_symbol *s; dll_index = ((Elf32_Sym *) pe->s1->dynsymtab_section->data + sym_index)->st_value; if (dll_index == 0) return NULL; i = dynarray_assoc((void **) pe->imp_info, pe->imp_count, dll_index); if (i != -1) { p = pe->imp_info[i]; goto found_dll; } p = tcc_mallocz(sizeof *p); p->dll_index = dll_index; dynarray_add((void ***) &pe->imp_info, &pe->imp_count, p); found_dll: i = dynarray_assoc((void **) p->symbols, p->sym_count, sym_index); if (i != -1) return p->symbols[i]; s = tcc_mallocz(sizeof *s); dynarray_add((void ***) &p->symbols, &p->sym_count, s); s->sym_index = sym_index; return s; }
/* ------------------------------------------------------------- */ PUB_FN int pe_load_def_file(TCCState *s1, int fd) { DLLReference *dllref; int state = 0, ret = -1; char line[400], dllname[80], *p; FILE *fp = fdopen(dup(fd), "rb"); if (NULL == fp) goto quit; for (;;) { p = get_line(line, sizeof line, fp); if (NULL == p) break; if (0 == *p || ';' == *p) continue; switch (state) { case 0: if (0 != strnicmp(p, "LIBRARY", 7)) goto quit; strcpy(dllname, trimfront(p+7)); ++state; continue; case 1: if (0 != stricmp(p, "EXPORTS")) goto quit; ++state; continue; case 2: dllref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname)); strcpy(dllref->name, dllname); dynarray_add((void ***) &s1->loaded_dlls, &s1->nb_loaded_dlls, dllref); ++state; default: add_elf_sym(s1->dynsymtab_section, s1->nb_loaded_dlls, 0, ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), 0, text_section->sh_num, p); continue; } } ret = 0; quit: if (fp) fclose(fp); if (ret) error_noabort("unrecognized export definition file format"); return ret; }
static int pe_assign_addresses(struct pe_info *pe) { int i, k, o, c; DWORD addr; int *section_order; struct section_info *si; struct section_info *merged_text; struct section_info *merged_data; Section *s; // pe->thunk = new_section(pe->s1, ".iedat", SHT_PROGBITS, SHF_ALLOC); section_order = tcc_malloc(pe->s1->nb_sections * sizeof (int)); for (o = k = 0 ; k < sec_last; ++k) { for (i = 1; i < pe->s1->nb_sections; ++i) { s = pe->s1->sections[i]; if (k == pe_section_class(s)) { s->sh_addr = pe->imagebase; section_order[o++] = i; } } } pe->sec_info = tcc_mallocz(o * sizeof (struct section_info)); addr = pe->imagebase + 1; merged_text = NULL; merged_data = NULL; for (i = 0; i < o; ++i) { k = section_order[i]; s = pe->s1->sections[k]; c = pe_section_class(s); si = &pe->sec_info[pe->sec_count]; #ifdef PE_MERGE_DATA if (c == sec_data && merged_data == NULL) { merged_data = si; } if (c == sec_bss && merged_data != NULL) { // Append .bss to .data s->sh_addr = addr = ((addr - 1) | 15) + 1; addr += s->data_offset; merged_data->sh_size = addr - merged_data->sh_addr; merged_data->last->next = s; merged_data->last = s; continue; } #endif if (c == sec_text) { if (s->unused) continue; if (merged_text) { merged_text->sh_size = align(merged_text->sh_size, s->sh_addralign); s->sh_addr = merged_text->sh_addr + merged_text->sh_size; merged_text->sh_size += s->data_offset; addr = merged_text->sh_addr + merged_text->sh_size; merged_text->last->next = s; merged_text->last = s; continue; } else { merged_text = si; } } strcpy(si->name, c == sec_text ? ".text" : s->name); si->cls = c; si->ord = k; si->sh_addr = s->sh_addr = addr = pe_virtual_align(addr); si->sh_flags = s->sh_flags; si->first = si->last = s; if (c == sec_data && pe->thunk == NULL) { pe->thunk = s; } if (s == pe->thunk) { pe_build_imports(pe); pe_build_exports(pe); } if (c == sec_reloc) { pe_build_reloc(pe); } if (s->data_offset) { si->sh_size = s->data_offset; addr += s->data_offset; pe->sec_count++; } } tcc_free(section_order); return 0; }
ST_FN int pe_assign_addresses (struct pe_info *pe) { int i, k, o, c; DWORD addr; int *section_order; struct section_info *si; Section *s; // pe->thunk = new_section(pe->s1, ".iedat", SHT_PROGBITS, SHF_ALLOC); section_order = tcc_malloc(pe->s1->nb_sections * sizeof (int)); for (o = k = 0 ; k < sec_last; ++k) { for (i = 1; i < pe->s1->nb_sections; ++i) { s = pe->s1->sections[i]; if (k == pe_section_class(s)) { // printf("%s %d\n", s->name, k); s->sh_addr = pe->imagebase; section_order[o++] = i; } } } pe->sec_info = tcc_mallocz(o * sizeof (struct section_info)); addr = pe->imagebase + 1; for (i = 0; i < o; ++i) { k = section_order[i]; s = pe->s1->sections[k]; c = pe_section_class(s); si = &pe->sec_info[pe->sec_count]; #ifdef PE_MERGE_DATA if (c == sec_bss && pe->sec_count && si[-1].cls == sec_data) { /* append .bss to .data */ s->sh_addr = addr = ((addr-1) | 15) + 1; addr += s->data_offset; si[-1].sh_size = addr - si[-1].sh_addr; continue; } #endif strcpy(si->name, s->name); si->cls = c; si->ord = k; si->sh_addr = s->sh_addr = addr = pe_virtual_align(addr); si->sh_flags = s->sh_flags; if (c == sec_data && NULL == pe->thunk) pe->thunk = s; if (s == pe->thunk) { pe_build_imports(pe); pe_build_exports(pe); } if (c == sec_reloc) pe_build_reloc (pe); if (s->data_offset) { if (s->sh_type != SHT_NOBITS) { si->data = s->data; si->data_size = s->data_offset; } addr += s->data_offset; si->sh_size = s->data_offset; ++pe->sec_count; } // printf("%08x %05x %s\n", si->sh_addr, si->sh_size, si->name); } #if 0 for (i = 1; i < pe->s1->nb_sections; ++i) { Section *s = pe->s1->sections[i]; int type = s->sh_type; int flags = s->sh_flags; printf("section %-16s %-10s %5x %s,%s,%s\n", s->name, type == SHT_PROGBITS ? "progbits" : type == SHT_NOBITS ? "nobits" : type == SHT_SYMTAB ? "symtab" : type == SHT_STRTAB ? "strtab" : type == SHT_REL ? "rel" : "???", s->data_offset, flags & SHF_ALLOC ? "alloc" : "", flags & SHF_WRITE ? "write" : "", flags & SHF_EXECINSTR ? "exec" : "" ); } pe->s1->verbose = 2; #endif tcc_free(section_order); return 0; }
longjmp(env, val); } extern "C" void *tcc_mallocz(unsigned long size); void Service::start() { std::string code = R"VR( int test() { return 1; } )VR"; debug2("Before tcc_new()\n"); void* test = tcc_mallocz(64); printf("tcc internal malloc: %p\n", test); //tcc_set_lib_path(s, CONFIG_TCCDIR); TCCState* s; s = tcc_new(); debug2("After tcc_new()\n"); assert(s != nullptr); // I'll let someone else handle this part--- printf ("Well, it starts.. GL!\n"); }
LIBTCCAPI TCCState *tcc_new(const char *arch, int bits, const char *os) { TCCState *s; char buffer[100]; int a, b, c; if (!arch || !os) { return NULL; } tcc_cleanup (); s = tcc_mallocz (sizeof(TCCState)); if (!s) { return NULL; } tcc_state = s; s->arch = strdup (arch); s->bits = bits; s->os = strdup (os); s->output_type = TCC_OUTPUT_MEMORY; preprocess_new (); s->include_stack_ptr = s->include_stack; /* we add dummy defines for some special macros to speed up tests and to have working defined() */ define_push (TOK___LINE__, MACRO_OBJ, NULL, NULL); define_push (TOK___FILE__, MACRO_OBJ, NULL, NULL); define_push (TOK___DATE__, MACRO_OBJ, NULL, NULL); define_push (TOK___TIME__, MACRO_OBJ, NULL, NULL); /* define __TINYC__ 92X */ sscanf (TCC_VERSION, "%d.%d.%d", &a, &b, &c); sprintf (buffer, "%d", a * 10000 + b * 100 + c); tcc_define_symbol (s, "__TINYC__", buffer); tcc_define_symbol (s, "__R2TINYC__", buffer); /* standard defines */ tcc_define_symbol (s, "__STDC__", NULL); tcc_define_symbol (s, "__STDC_VERSION__", "199901L"); tcc_define_symbol (s, "__STDC_HOSTED__", NULL); /* target defines */ if (!strncmp (arch, "x86", 3)) { if (bits == 32 || bits == 16) { tcc_define_symbol (s, "__i386__", NULL); tcc_define_symbol (s, "__i386", NULL); tcc_define_symbol (s, "i386", NULL); } else { tcc_define_symbol (s, "__x86_64__", NULL); } } else if (!strncmp (arch, "arm", 3)) { tcc_define_symbol (s, "__ARM_ARCH_4__", NULL); tcc_define_symbol (s, "__arm_elf__", NULL); tcc_define_symbol (s, "__arm_elf", NULL); tcc_define_symbol (s, "arm_elf", NULL); tcc_define_symbol (s, "__arm__", NULL); tcc_define_symbol (s, "__arm", NULL); tcc_define_symbol (s, "arm", NULL); tcc_define_symbol (s, "__APCS_32__", NULL); } // TODO: Add other architectures // TODO: Move that in SDB if (!strncmp (os, "windows", 7)) { tcc_define_symbol (s, "__WINDOWS__", NULL); if (bits == 64) { tcc_define_symbol (s, "_WIN64", NULL); } } else { tcc_define_symbol (s, "__unix__", NULL); tcc_define_symbol (s, "__unix", NULL); tcc_define_symbol (s, "unix", NULL); if (!strncmp (os, "linux", 5)) { tcc_define_symbol (s, "__linux__", NULL); tcc_define_symbol (s, "__linux", NULL); } #define str(s) #s if (!strncmp (os, "freebsd", 7)) { tcc_define_symbol (s, "__FreeBSD__", str ( __FreeBSD__)); } #undef str } /* TinyCC & gcc defines */ if (!strncmp (os, "windows", 7) && (bits == 64)) { tcc_define_symbol (s, "__SIZE_TYPE__", "unsigned long long"); tcc_define_symbol (s, "__PTRDIFF_TYPE__", "long long"); } else { tcc_define_symbol (s, "__SIZE_TYPE__", "unsigned long"); tcc_define_symbol (s, "__PTRDIFF_TYPE__", "long"); } if (!strncmp (os, "windows", 7)) { tcc_define_symbol (s, "__WCHAR_TYPE__", "unsigned short"); } else { tcc_define_symbol (s, "__WCHAR_TYPE__", "int"); /* glibc defines */ tcc_define_symbol (s, "__REDIRECT(name, proto, alias)", "name proto __asm__(#alias)"); tcc_define_symbol (s, "__REDIRECT_NTH(name, proto, alias)", "name proto __asm__(#alias) __THROW"); } s->alacarte_link = 1; s->nocommon = 1; #ifdef CHAR_IS_UNSIGNED s->char_is_unsigned = 1; #endif /* enable this if you want symbols with leading underscore on windows: */ #if 0 /* def TCC_TARGET_PE */ s->leading_underscore = 1; #endif if (!strncmp (arch, "x86", 3)) { // TODO: Set it to 16 for 16bit x86 if (bits == 32 || bits == 16) { s->seg_size = 32; } } return s; }