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
This commit is contained in:
Coldy 2021-11-24 18:13:35 +00:00
parent 3b314ebaf8
commit 7aed43b0ca
9 changed files with 412 additions and 39 deletions

View File

@ -0,0 +1,9 @@
LIBRARY http.obj
EXPORTS prefix
http_get
http_head
http_post
http_receive
http_send
http_free

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,6 +1,7 @@
#define TCC_VERSION "0.9.26" #define TCC_VERSION "0.9.26"
#define CONFIG_TCC_STATIC #define CONFIG_TCC_STATIC
#define TCC_TARGET_MEOS #define TCC_TARGET_KX
//#define TCC_TARGET_MEOS
#define TCC_TARGET_I386 #define TCC_TARGET_I386
#define ONE_SOURCE #define ONE_SOURCE

View File

@ -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); 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 #else
tcc_define_symbol(s, "__unix__", NULL); tcc_define_symbol(s, "__unix__", NULL);
tcc_define_symbol(s, "__unix", NULL); tcc_define_symbol(s, "__unix", NULL);

View File

@ -58,6 +58,9 @@ static void display_info(TCCState *s, int what)
" Windows" " Windows"
#elif defined TCC_TARGET_MEOS #elif defined TCC_TARGET_MEOS
" KolibriOS" " KolibriOS"
#ifdef TCC_TARGET_KX
"/KX extension"
#endif
#else #else
" Linux" " Linux"
#endif #endif

View File

@ -26,10 +26,10 @@ typedef struct {
static kx_header __kx_header = { 'K','X',0, 0, 0x40, 0 }; static kx_header __kx_header = { 'K','X',0, 0, 0x40, 0 };
typedef struct LibraryEntry { typedef struct {
uint32_t ImportEntry; uint32_t ImportEntry;
uint32_t LibraryName; uint32_t LibraryName;
}; } LibraryEntry;
/*union ImportEntry { /*union ImportEntry {
uint32_t ImportStr; uint32_t ImportStr;
@ -43,7 +43,8 @@ static kx_header __kx_header = { 'K','X',0, 0, 0x40, 0 };
ElfW(Sym) *sym; ElfW(Sym) *sym;
int sym_index, sym_end; int sym_index, sym_end;
sym_end = symtab_section->data_offset / sizeof(ElfW(Sym)); 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 nlib = 0;
int i; int i;
@ -51,15 +52,10 @@ static kx_header __kx_header = { 'K','X',0, 0, 0x40, 0 };
return; return;
str_arr = tcc_malloc(sizeof(CString) * me->s1->nb_loaded_dlls); 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); len_arr = tcc_malloc(sizeof(CString)* me->s1->nb_loaded_dlls);
if (len_arr == 0) {
tcc_free(str_arr); sym_arr = tcc_malloc(sizeof(CString)* me->s1->nb_loaded_dlls);
return;
}
for (sym_index = 1; sym_index < sym_end; ++sym_index) { for (sym_index = 1; sym_index < sym_end; ++sym_index) {
sym = (ElfW(Sym) *)symtab_section->data + sym_index; sym = (ElfW(Sym) *)symtab_section->data + sym_index;
@ -79,16 +75,18 @@ static kx_header __kx_header = { 'K','X',0, 0, 0x40, 0 };
// KOS support 32 bit only // KOS support 32 bit only
Elf32_Sym* dyn_sym = &((ElfW(Sym) *)me->s1->dynsymtab_section->data)[dynsym_index]; Elf32_Sym* dyn_sym = &((ElfW(Sym) *)me->s1->dynsymtab_section->data)[dynsym_index];
DLLReference **dllref = me->s1->loaded_dlls; DLLReference **dllref = me->s1->loaded_dlls;
char* dll_name;
i = dyn_sym->st_size - 1; i = dyn_sym->st_size - 1;
// TCC store dll index in dyn_sym->st_size field // TCC store dll index in dyn_sym->st_size field
if (dllref[i]->level != -1) { if (dllref[i]->level != -1) {
char* dll_name = dllref[i]->name; dll_name = dllref[i]->name;
char dll_len = strlen(dll_name) + 1; dll_len = strlen(dll_name) + 1;
nlib++; nlib++;
cstr_new(&str_arr[i]); cstr_new(&str_arr[i]);
cstr_new(&len_arr[i]); cstr_new(&len_arr[i]);
cstr_new(&sym_arr[i]);
cstr_ccat(&len_arr[i], dll_len); cstr_ccat(&len_arr[i], dll_len);
cstr_cat(&str_arr[i], dll_name, dll_len); cstr_cat(&str_arr[i], dll_name, dll_len);
@ -96,6 +94,13 @@ static kx_header __kx_header = { 'K','X',0, 0, 0x40, 0 };
dllref[i]->level = -1; 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; char name_len = strlen(name) + 1;
cstr_ccat(&len_arr[i], name_len); cstr_ccat(&len_arr[i], name_len);
cstr_cat(&str_arr[i], name, name_len); cstr_cat(&str_arr[i], name, name_len);
@ -127,12 +132,12 @@ static kx_header __kx_header = { 'K','X',0, 0, 0x40, 0 };
imp_sect->data_size = 0; imp_sect->data_size = 0;
//imp_sect->sh_addr = me->header.image_size;// +1; //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 // Strings
i = 0; i = 0;
do { 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_data += str_arr[i].size;
imp_sect->data_size += 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);*/ 0, SHN_ABS, __kx_import_table_sym);*/
__kx_header.i_ptr = me->header.image_size + imp_sect->data_size; __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.ImportEntry = me->header.image_size + imp_sect->data_size + (nlib * 8) + 4;
lib.LibraryName = me->header.image_size + 0; lib.LibraryName = me->header.image_size + 0;
// LibraryEntry // LibraryEntry
memcpy(imp_data, &lib, sizeof(struct LibraryEntry)); memcpy((void*)imp_data, &lib, sizeof(LibraryEntry));
if (nlib > 1) { if (nlib > 1) {
int prev_sum = 0;
int prev = 0; int prev = 0;
i = 1; i = 1;
do { do {
lib.ImportEntry += (len_arr[prev].size - 2) * 4 + 4; //TODO: check that +4 is correct 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; prev_sum += str_arr[prev].size;
imp_data += sizeof(struct LibraryEntry); lib.LibraryName = me->header.image_size + prev_sum; // FIXED (was BUG#10)
imp_sect->data_size += sizeof(struct LibraryEntry); imp_data += sizeof(LibraryEntry);
memcpy(imp_data, &lib, sizeof(struct LibraryEntry)); imp_sect->data_size += sizeof(LibraryEntry);
memcpy((void*)imp_data, &lib, sizeof(LibraryEntry));
prev++; prev++;
i++; i++;
@ -176,44 +183,44 @@ static kx_header __kx_header = { 'K','X',0, 0, 0x40, 0 };
} }
// End of LibraryEntry // End of LibraryEntry
imp_data += sizeof(struct LibraryEntry) + 4; imp_data += sizeof(LibraryEntry) + 4;
imp_sect->data_size += sizeof(struct LibraryEntry) + 4; imp_sect->data_size += sizeof(LibraryEntry) + 4;
const char *sym_name;
char name_len; char name_len;
long l, nl; long len_sum;
l = me->header.image_size; len_sum = me->header.image_size;
i = 0; i = 0;
do { do {
char* len_data = len_arr[i].data; char* len_data = len_arr[i].data;
long* sym_data = sym_arr[i].data;
name_len = *len_data++; // Skip library name name_len = *len_data++; // Skip library name
nl = name_len;
do { do {
const char *name = (const char *)str_arr[i].data + nl;
memcpy(&sym_name, sym_data++, 4);
add_elf_sym( add_elf_sym(
me->s1->dynsymtab_section, me->s1->dynsymtab_section,
me->header.image_size + imp_sect->data_size, me->header.image_size + imp_sect->data_size,
0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE),
0, SHN_ABS, name); 0, SHN_ABS, sym_name);
l += name_len; len_sum += name_len;
memcpy(imp_data, &l, 4); memcpy((void*)imp_data, &len_sum, 4);
imp_data += 4; imp_data += 4;
imp_sect->data_size += 4; imp_sect->data_size += 4;
name_len = */*++*/len_data/*++*/; //(was BUG#3) name_len = */*++*/len_data/*++*/; //(was BUG#3)
nl = nl + name_len;
} while (/*name_len*/*(++len_data) > 0); } while (/*name_len*/*(++len_data) > 0);
imp_data += 4; imp_data += 4;
imp_sect->data_size += 4; imp_sect->data_size += 4;
l += name_len; len_sum += name_len;
i++; i++;
} while (i < nlib); } while (i < nlib);
@ -223,6 +230,7 @@ static kx_header __kx_header = { 'K','X',0, 0, 0x40, 0 };
tcc_free(str_arr); tcc_free(str_arr);
tcc_free(len_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) { long kx_get_header_length(me_info* me) {
if (me->header.version = 2) if (me->header.version == 2)
return sizeof(kx_header); return sizeof(kx_header);
return 0; return 0;
} }
void kx_write_header(me_info* me, FILE* f) { 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); fwrite(&__kx_header, 1, sizeof(kx_header), f);
} }

View File

@ -1493,7 +1493,10 @@ ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t va
dllindex, /* st_size */ dllindex, /* st_size */
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE),
0, 0,
value ? SHN_ABS : SHN_UNDEF, #ifndef TCC_TARGET_KX
value ? SHN_ABS :
#endif
SHN_UNDEF,
name name
); );
} }
@ -1567,7 +1570,7 @@ quit:
#if !defined(TCC_TARGET_MEOS) || defined (TCC_TARGET_KX) #if !defined(TCC_TARGET_MEOS) || defined (TCC_TARGET_KX)
static int pe_load_def(TCCState *s1, int fd) 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; char line[400], dllname[80], *p, *x;
FILE *fp; FILE *fp;
@ -1591,6 +1594,15 @@ static int pe_load_def(TCCState *s1, int fd)
continue; continue;
case 1: 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")) if (0 != stricmp(p, "EXPORTS"))
goto quit; goto quit;
++state; ++state;
@ -1599,10 +1611,22 @@ static int pe_load_def(TCCState *s1, int fd)
case 2: case 2:
dllindex = add_dllref(s1, dllname); dllindex = add_dllref(s1, dllname);
++state; ++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 */ /* fall through */
default: 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 */ /* get ordinal and will store in sym->st_value */
ord = 0; //ord = 0; // ord is assign in begining of function
x = strchr(p, ' '); x = strchr(p, ' ');
if (x) { if (x) {
*x = 0, x = strrchr(x + 1, '@'); *x = 0, x = strrchr(x + 1, '@');
@ -1613,6 +1637,7 @@ static int pe_load_def(TCCState *s1, int fd)
ord = 0; ord = 0;
} }
} }
#endif
pe_putimport(s1, dllindex, p, ord); pe_putimport(s1, dllindex, p, ord);
continue; continue;
} }