From 7aed43b0ca574484e7cea93a0007b9559b9eddc6 Mon Sep 17 00:00:00 2001 From: Coldy Date: Wed, 24 Nov 2021 18:13:35 +0000 Subject: [PATCH] Add KX extension to tcc (autoload w/import table support), phase 2.1 Fixed bugs Add new features (name prefix to conflicts solve, display version, __KX__ macro) Added kx folder with new crt0.o (crt.asm), some *.def and libtcc.a git-svn-id: svn://kolibrios.org@9305 a494cfbc-eb01-0410-851d-a64ba20cac60 --- .../develop/ktcc/trunk/kx/bin/lib/http.def | 9 + .../develop/ktcc/trunk/kx/bin/lib/img.def | 20 ++ .../develop/ktcc/trunk/kx/bin/lib/libc.def | 177 ++++++++++++++++++ .../develop/ktcc/trunk/kx/src/crt/crt0.asm | 127 +++++++++++++ programs/develop/ktcc/trunk/source/config.h | 3 +- programs/develop/ktcc/trunk/source/libtcc.c | 3 + programs/develop/ktcc/trunk/source/tcc.c | 3 + programs/develop/ktcc/trunk/source/tcckx.c | 78 ++++---- programs/develop/ktcc/trunk/source/tccpe.c | 31 ++- 9 files changed, 412 insertions(+), 39 deletions(-) create mode 100644 programs/develop/ktcc/trunk/kx/bin/lib/http.def create mode 100644 programs/develop/ktcc/trunk/kx/bin/lib/img.def create mode 100644 programs/develop/ktcc/trunk/kx/bin/lib/libc.def create mode 100644 programs/develop/ktcc/trunk/kx/src/crt/crt0.asm diff --git a/programs/develop/ktcc/trunk/kx/bin/lib/http.def b/programs/develop/ktcc/trunk/kx/bin/lib/http.def new file mode 100644 index 0000000000..cdb14b8f1e --- /dev/null +++ b/programs/develop/ktcc/trunk/kx/bin/lib/http.def @@ -0,0 +1,9 @@ +LIBRARY http.obj + +EXPORTS prefix +http_get +http_head +http_post +http_receive +http_send +http_free diff --git a/programs/develop/ktcc/trunk/kx/bin/lib/img.def b/programs/develop/ktcc/trunk/kx/bin/lib/img.def new file mode 100644 index 0000000000..857a64cd0f --- /dev/null +++ b/programs/develop/ktcc/trunk/kx/bin/lib/img.def @@ -0,0 +1,20 @@ +LIBRARY libimg.obj + +EXPORTS +img_blend +img_convert +img_count +img_create +img_decode +img_destroy +img_destroy_layer +img_draw +img_encode +img_flip +img_flip_layer +img_resize_data +img_rotate +img_rotate_layer +img_scale +img_to_rgb +img_to_rgb2 \ No newline at end of file diff --git a/programs/develop/ktcc/trunk/kx/bin/lib/libc.def b/programs/develop/ktcc/trunk/kx/bin/lib/libc.def new file mode 100644 index 0000000000..c36e2999fd --- /dev/null +++ b/programs/develop/ktcc/trunk/kx/bin/lib/libc.def @@ -0,0 +1,177 @@ +LIBRARY libc.obj + +EXPORTS +;____STDIO______ +clearerr +debug_printf +fclose +feof +ferror +fflush +fgetc +fgetpos +fgets +fopen +fprintf +fputc +fputs +fread +freopen +fscanf +fseek +fsetpos +ftell +fwrite +getchar +gets +perror +printf +puts +remove +rename +rewind +scanf +setbuf +setvbuf +snprintf +sprintf +sscanf +tmpfile +tmpnam +vfscanf +vprintf +vfscanf +vsprintf +vsnprintf +vsscanf +ungetc +;____STDLIB____ +abs +atoi +atol +atoll +atof +calloc +exit +free +itoa +labs +llabs +malloc +realloc +strtol +srand +rand +qsort +strtod +__assert_fail +;____STRING____ +;memcpy +memchr +memcmp +!memmove +!memset +strncat +strchr +strcat +strcmp +strcoll +strcpy +strcspn +strdup +strerror +strlen +strncat +strncmp +strncpy +strrchr +strrev +strspn +strstr +strtok +strxfrm +_errno +;____SYS____ +closedir +opendir +readdir +rewinddir +seekdir +telldir +getcwd +mkdir +rmdir +setcwd +getcwd +;____SOCKET____ +socket +close +bind +listen +connect +accept +send +recv +setsockopt +socketpair +;____UNISTD____ +;____MATH____ +acosh +asinh +atanh +acosh +frexp +hypot +ldexp +sinh +tanh +acos +asin +atan +atan2 +ceil +cos +exp +fabs +floor +fmod +log +modf +modfl +pow +pow2 +pow10 +;____LONGJMP____ +longjmp +setjmp +;____CTYPE____ +__is +tolower +toupper +;___CONIO___ +con_set_title +con_init +con_init_opt +con_write_asciiz +con_write_string +con_printf +con_exit +con_get_flags +con_set_flags +con_kbhit +con_getch +con_getch2 +con_gets +con_gets2 +con_get_font_height +con_get_cursor_height +con_set_cursor_height +con_cls +con_get_cursor_pos +con_set_cursor_pos +;____TIME____ +mktime +time +localtime +asctime +difftime diff --git a/programs/develop/ktcc/trunk/kx/src/crt/crt0.asm b/programs/develop/ktcc/trunk/kx/src/crt/crt0.asm new file mode 100644 index 0000000000..55bf4f6f69 --- /dev/null +++ b/programs/develop/ktcc/trunk/kx/src/crt/crt0.asm @@ -0,0 +1,127 @@ +; +; 2021, Edited by Coldy +; +; This module same as original crt0.asm, but cut: +; 1. virtual header block (hparams change to __app_params, hpath change to __app_path) +; 2. init heap of memory - not needed because 68.18 (68.19) init heap implicitly +; (it is does dll.obj) +; 3. loader (he lives in dll.obj) +; + +format ELF +section '.text' executable +public start +public start as '_start' + +extrn main +;include 'debug2.inc' +include '/../../../../../../proc32.inc' +include '/../../../../../../macros.inc' +__DEBUG__ = 0 + +__app_params equ 0x1C ; Pointer to program arguments +;__app_path equ 0x20 ; Pointer to program path + +start: +;DEBUGF 'Start programm\n' + + mov [argc], 0 + mov eax, [__app_params] + test eax, eax + jz .without_path + mov eax, path + cmp word ptr eax, 32fh ; '/#3' UTF8 + jne .without_path + mov word ptr eax, 12fh ; '/#1' fix to CP866 +.without_path: + mov esi, eax + call push_param +; retrieving parameters + mov esi, params + xor edx, edx ; dl - идёт параметр(1) или разделители(0) + ; dh - символ с которого начался параметр (1 кавычки, 0 остальное) + mov ecx, 1 ; cl = 1 + ; ch = 0 просто ноль +.parse: + lodsb + test al, al + jz .run + test dl, dl + jnz .findendparam + ;{если был разделитель + cmp al, ' ' + jz .parse ;загружен пробел, грузим следующий символ + mov dl, cl ;начинается параметр + cmp al, '"' + jz @f ;загружены кавычки + mov dh, ch ;параметр без кавычек + dec esi + call push_param + inc esi + jmp .parse + + @@: + mov dh, cl ;параметр в кавычеках + call push_param ;если не пробел значит начинается какой то параметр + jmp .parse ;если был разделитель} + +.findendparam: + test dh, dh + jz @f ; без кавычек + cmp al, '"' + jz .clear + jmp .parse + @@: + cmp al, ' ' + jnz .parse + +.clear: + lea ebx, [esi - 1] + mov [ebx], ch + mov dl, ch + jmp .parse + +.run: + push argv + push [argc] + call main +.exit: + xor eax,eax + dec eax + int 0x40 + dd -1 +.crash: + jmp .exit +;============================ +push_param: +;============================ +;parameters +; esi - pointer +;description +; procedure increase argc +; and add pointer to array argv +; procedure changes ebx + mov ebx, [argc] + cmp ebx, max_parameters + jae .dont_add + mov [argv+4*ebx], esi + inc [argc] +.dont_add: + ret + + +;============================== +public argc as '__argc' +public params as '__argv' +public path as '__path' + +section '.bss' +buf_len = 0x400 +max_parameters=0x20 +argc rd 1 +argv rd max_parameters +path rb buf_len +params rb buf_len + +;section '.data' +;include_debug_strings ; ALWAYS present in data section diff --git a/programs/develop/ktcc/trunk/source/config.h b/programs/develop/ktcc/trunk/source/config.h index 6750a92f5d..4f31d2e081 100644 --- a/programs/develop/ktcc/trunk/source/config.h +++ b/programs/develop/ktcc/trunk/source/config.h @@ -1,6 +1,7 @@ #define TCC_VERSION "0.9.26" #define CONFIG_TCC_STATIC -#define TCC_TARGET_MEOS +#define TCC_TARGET_KX +//#define TCC_TARGET_MEOS #define TCC_TARGET_I386 #define ONE_SOURCE diff --git a/programs/develop/ktcc/trunk/source/libtcc.c b/programs/develop/ktcc/trunk/source/libtcc.c index 0e8db555b3..23a3ff3846 100644 --- a/programs/develop/ktcc/trunk/source/libtcc.c +++ b/programs/develop/ktcc/trunk/source/libtcc.c @@ -1181,6 +1181,9 @@ LIBTCCAPI TCCState *tcc_new(void) tcc_define_symbol(s, "KOLIBRI", NULL); tcc_define_symbol(s, "_KOLIBRI", NULL); tcc_define_symbol(s, "_KOLIBRI_",NULL); +#ifdef TCC_TARGET_KX + tcc_define_symbol(s, "__KX__", NULL); +#endif #else tcc_define_symbol(s, "__unix__", NULL); tcc_define_symbol(s, "__unix", NULL); diff --git a/programs/develop/ktcc/trunk/source/tcc.c b/programs/develop/ktcc/trunk/source/tcc.c index 3df048afca..67fe90fa10 100644 --- a/programs/develop/ktcc/trunk/source/tcc.c +++ b/programs/develop/ktcc/trunk/source/tcc.c @@ -58,6 +58,9 @@ static void display_info(TCCState *s, int what) " Windows" #elif defined TCC_TARGET_MEOS " KolibriOS" +#ifdef TCC_TARGET_KX + "/KX extension" +#endif #else " Linux" #endif diff --git a/programs/develop/ktcc/trunk/source/tcckx.c b/programs/develop/ktcc/trunk/source/tcckx.c index c3e0a187cb..d64841d4f7 100644 --- a/programs/develop/ktcc/trunk/source/tcckx.c +++ b/programs/develop/ktcc/trunk/source/tcckx.c @@ -26,10 +26,10 @@ typedef struct { static kx_header __kx_header = { 'K','X',0, 0, 0x40, 0 }; - typedef struct LibraryEntry { +typedef struct { uint32_t ImportEntry; uint32_t LibraryName; - }; + } LibraryEntry; /*union ImportEntry { uint32_t ImportStr; @@ -43,7 +43,8 @@ static kx_header __kx_header = { 'K','X',0, 0, 0x40, 0 }; ElfW(Sym) *sym; int sym_index, sym_end; sym_end = symtab_section->data_offset / sizeof(ElfW(Sym)); - CString *str_arr, *len_arr; + CString *str_arr, *len_arr, *sym_arr; + char dll_len; int nlib = 0; int i; @@ -51,15 +52,10 @@ static kx_header __kx_header = { 'K','X',0, 0, 0x40, 0 }; return; str_arr = tcc_malloc(sizeof(CString) * me->s1->nb_loaded_dlls); - if (str_arr == 0) { - return; - } len_arr = tcc_malloc(sizeof(CString)* me->s1->nb_loaded_dlls); - if (len_arr == 0) { - tcc_free(str_arr); - return; - } + + sym_arr = tcc_malloc(sizeof(CString)* me->s1->nb_loaded_dlls); for (sym_index = 1; sym_index < sym_end; ++sym_index) { sym = (ElfW(Sym) *)symtab_section->data + sym_index; @@ -79,22 +75,31 @@ static kx_header __kx_header = { 'K','X',0, 0, 0x40, 0 }; // KOS support 32 bit only Elf32_Sym* dyn_sym = &((ElfW(Sym) *)me->s1->dynsymtab_section->data)[dynsym_index]; DLLReference **dllref = me->s1->loaded_dlls; + char* dll_name; i = dyn_sym->st_size - 1; // TCC store dll index in dyn_sym->st_size field if (dllref[i]->level != -1) { - char* dll_name = dllref[i]->name; - char dll_len = strlen(dll_name) + 1; + dll_name = dllref[i]->name; + dll_len = strlen(dll_name) + 1; nlib++; cstr_new(&str_arr[i]); cstr_new(&len_arr[i]); + cstr_new(&sym_arr[i]); cstr_ccat(&len_arr[i], dll_len); cstr_cat(&str_arr[i], dll_name, dll_len); //Mark dll as already used dllref[i]->level = -1; } + + cstr_wccat(&sym_arr[i], (int)name); + + // Export defined with prefix? + if (dyn_sym->st_value == -1){ + name += (dll_len - 4); // skip prefix_ + } char name_len = strlen(name) + 1; cstr_ccat(&len_arr[i], name_len); @@ -127,12 +132,12 @@ static kx_header __kx_header = { 'K','X',0, 0, 0x40, 0 }; imp_sect->data_size = 0; //imp_sect->sh_addr = me->header.image_size;// +1; - long imp_data = imp_sect->data; //FIXME change to long for gcc compatible? + long imp_data = (long)imp_sect->data; //FIXED changed to long for gcc compatible // Strings i = 0; do { - memcpy(imp_data, str_arr[i].data, str_arr[i].size); + memcpy((void*)imp_data, str_arr[i].data, str_arr[i].size); imp_data += str_arr[i].size; imp_sect->data_size += str_arr[i].size; @@ -152,22 +157,24 @@ static kx_header __kx_header = { 'K','X',0, 0, 0x40, 0 }; 0, SHN_ABS, __kx_import_table_sym);*/ __kx_header.i_ptr = me->header.image_size + imp_sect->data_size; - struct LibraryEntry lib; + LibraryEntry lib; lib.ImportEntry = me->header.image_size + imp_sect->data_size + (nlib * 8) + 4; lib.LibraryName = me->header.image_size + 0; // LibraryEntry - memcpy(imp_data, &lib, sizeof(struct LibraryEntry)); + memcpy((void*)imp_data, &lib, sizeof(LibraryEntry)); if (nlib > 1) { + int prev_sum = 0; int prev = 0; i = 1; do { lib.ImportEntry += (len_arr[prev].size - 2) * 4 + 4; //TODO: check that +4 is correct - lib.LibraryName = me->header.image_size + str_arr[prev].size; - imp_data += sizeof(struct LibraryEntry); - imp_sect->data_size += sizeof(struct LibraryEntry); - memcpy(imp_data, &lib, sizeof(struct LibraryEntry)); + prev_sum += str_arr[prev].size; + lib.LibraryName = me->header.image_size + prev_sum; // FIXED (was BUG#10) + imp_data += sizeof(LibraryEntry); + imp_sect->data_size += sizeof(LibraryEntry); + memcpy((void*)imp_data, &lib, sizeof(LibraryEntry)); prev++; i++; @@ -176,44 +183,44 @@ static kx_header __kx_header = { 'K','X',0, 0, 0x40, 0 }; } // End of LibraryEntry - imp_data += sizeof(struct LibraryEntry) + 4; - imp_sect->data_size += sizeof(struct LibraryEntry) + 4; + imp_data += sizeof(LibraryEntry) + 4; + imp_sect->data_size += sizeof(LibraryEntry) + 4; - char name_len; - long l, nl; + const char *sym_name; + char name_len; + long len_sum; - l = me->header.image_size; + len_sum = me->header.image_size; i = 0; do { char* len_data = len_arr[i].data; + long* sym_data = sym_arr[i].data; name_len = *len_data++; // Skip library name - nl = name_len; do { - const char *name = (const char *)str_arr[i].data + nl; + + memcpy(&sym_name, sym_data++, 4); add_elf_sym( me->s1->dynsymtab_section, me->header.image_size + imp_sect->data_size, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), - 0, SHN_ABS, name); + 0, SHN_ABS, sym_name); - l += name_len; - memcpy(imp_data, &l, 4); + len_sum += name_len; + memcpy((void*)imp_data, &len_sum, 4); imp_data += 4; imp_sect->data_size += 4; name_len = */*++*/len_data/*++*/; //(was BUG#3) - nl = nl + name_len; - } while (/*name_len*/*(++len_data) > 0); imp_data += 4; imp_sect->data_size += 4; - l += name_len; + len_sum += name_len; i++; } while (i < nlib); @@ -223,6 +230,7 @@ static kx_header __kx_header = { 'K','X',0, 0, 0x40, 0 }; tcc_free(str_arr); tcc_free(len_arr); + tcc_free(sym_arr); } @@ -246,14 +254,14 @@ static kx_header __kx_header = { 'K','X',0, 0, 0x40, 0 }; } long kx_get_header_length(me_info* me) { - if (me->header.version = 2) + if (me->header.version == 2) return sizeof(kx_header); return 0; } void kx_write_header(me_info* me, FILE* f) { - if (me->header.version = 2) + if (me->header.version == 2) fwrite(&__kx_header, 1, sizeof(kx_header), f); } diff --git a/programs/develop/ktcc/trunk/source/tccpe.c b/programs/develop/ktcc/trunk/source/tccpe.c index 0412d308ed..b3bbba35d8 100644 --- a/programs/develop/ktcc/trunk/source/tccpe.c +++ b/programs/develop/ktcc/trunk/source/tccpe.c @@ -1493,7 +1493,10 @@ ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t va dllindex, /* st_size */ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, - value ? SHN_ABS : SHN_UNDEF, +#ifndef TCC_TARGET_KX + value ? SHN_ABS : +#endif + SHN_UNDEF, name ); } @@ -1567,7 +1570,7 @@ quit: #if !defined(TCC_TARGET_MEOS) || defined (TCC_TARGET_KX) static int pe_load_def(TCCState *s1, int fd) { - int state = 0, ret = -1, dllindex = 0, ord; + int state = 0, ret = -1, dllindex = 0, ord = 0; char line[400], dllname[80], *p, *x; FILE *fp; @@ -1591,6 +1594,15 @@ static int pe_load_def(TCCState *s1, int fd) continue; case 1: +#ifdef TCC_TARGET_KX + { + char* p1 = strstr(p, "prefix"); + if (p1) { + p[p1 - p - 1] = 0; + ord = -1; // All exports used prefix + } + } +#endif if (0 != stricmp(p, "EXPORTS")) goto quit; ++state; @@ -1599,10 +1611,22 @@ static int pe_load_def(TCCState *s1, int fd) case 2: dllindex = add_dllref(s1, dllname); ++state; +#ifdef TCC_TARGET_KX + if (ord == - 1) { + char* tmp = strchr(dllname, '.'); + int n = tmp - dllname; + dllname[n] = '_'; + dllname[n + 1] = 0; + } +#endif /* fall through */ default: +#ifdef TCC_TARGET_KX + if ((ord == -1) && p != strstr(p, dllname)) + tcc_error_noabort("Wrong prefix for %s", p); +#else /* get ordinal and will store in sym->st_value */ - ord = 0; + //ord = 0; // ord is assign in begining of function x = strchr(p, ' '); if (x) { *x = 0, x = strrchr(x + 1, '@'); @@ -1613,6 +1637,7 @@ static int pe_load_def(TCCState *s1, int fd) ord = 0; } } +#endif pe_putimport(s1, dllindex, p, ord); continue; }