From db785142be344463db726eedd3a4d81243cffc72 Mon Sep 17 00:00:00 2001 From: Coldy Date: Sun, 24 Apr 2022 17:28:28 +0000 Subject: [PATCH] ktcc: added __attribute__((dllimport)) support git-svn-id: svn://kolibrios.org@9782 a494cfbc-eb01-0410-851d-a64ba20cac60 --- .../ktcc/trunk/bin/doc/ru/Features.txt | 9 +- .../develop/ktcc/trunk/bin/doc/ru/History.txt | 13 +++ .../ktcc/trunk/bin/doc/ru/How to use.txt | 85 +++++++++++-------- programs/develop/ktcc/trunk/source/i386-gen.c | 8 ++ programs/develop/ktcc/trunk/source/libtcc.c | 9 +- programs/develop/ktcc/trunk/source/tcc.c | 3 +- programs/develop/ktcc/trunk/source/tcc.h | 3 + programs/develop/ktcc/trunk/source/tccgen.c | 2 +- programs/develop/ktcc/trunk/source/tcckx.c | 40 ++++++++- programs/develop/ktcc/trunk/source/tccmeos.c | 34 +++++--- 10 files changed, 148 insertions(+), 58 deletions(-) diff --git a/programs/develop/ktcc/trunk/bin/doc/ru/Features.txt b/programs/develop/ktcc/trunk/bin/doc/ru/Features.txt index 1d7178eaff..15050db83c 100644 --- a/programs/develop/ktcc/trunk/bin/doc/ru/Features.txt +++ b/programs/develop/ktcc/trunk/bin/doc/ru/Features.txt @@ -1,5 +1,5 @@ -Версия расширения KX - 0.4.3 +Версия расширения KX - 0.4.6 Обзор новых возможностей @@ -19,9 +19,10 @@ + Уменьшенный размер образа Поскольку загрузчик библиотек больше не нужно размещать в каждом - приложении, это уменьшает размер образа. Больше не нужен слой C - (C layer), все зависимые библиотеки загружаются, а также инициализируются - автоматически. Также используется компактный формат таблицы импорта. + приложении, это уменьшает размер образа. Больше не нужна фукнция вызова + инициализации библиотек в C layer, все зависимые библиотеки загружаются, + а также инициализируются автоматически. Кроме того используется компактные + формат таблицы импорта, а также вызовы функций из динамических библиотек. + Обратная совместимость Если Вы по каким то причинам не хотите, либо пока не готовы использовать diff --git a/programs/develop/ktcc/trunk/bin/doc/ru/History.txt b/programs/develop/ktcc/trunk/bin/doc/ru/History.txt index 103d0707b9..123ddc33ff 100644 --- a/programs/develop/ktcc/trunk/bin/doc/ru/History.txt +++ b/programs/develop/ktcc/trunk/bin/doc/ru/History.txt @@ -1,3 +1,16 @@ +0.4.6 + + __attribute__((dllimport)) + + + + , + , __attribute__((dllimport)) + + + KX ( -vv) + +0.4.5 + + %ktcc_root%/include tcc.conf + + + + 0.4.4 + diff --git a/programs/develop/ktcc/trunk/bin/doc/ru/How to use.txt b/programs/develop/ktcc/trunk/bin/doc/ru/How to use.txt index fbcb671f07..f2950a16a1 100644 --- a/programs/develop/ktcc/trunk/bin/doc/ru/How to use.txt +++ b/programs/develop/ktcc/trunk/bin/doc/ru/How to use.txt @@ -1,16 +1,29 @@ - KX - tcc.conf tcc - - %ktcc_root%\ %ktcc_root%\kx. - lib - *.def, crt.0 libtcc.a + tcc (. tcc). KX + (*.def) ( *.o, + , - *.o, + ). + + . /samples + + : + -nobss , ( + bss , + + ) + + /lib *.def ( + ), crt0.o ( ) *libtcc.a ( + tcc), *.a. , + tiny.o , + . KX - . , + [++, + ]. , . , @@ -22,14 +35,8 @@ KX *.def - tcc (. tcc) - : - -nobss , ( - bss , - - ) - + KX (*.def). *.def . *.def . @@ -53,13 +60,38 @@ [libname_]entry2 ; + + + : + - ( ). + . + + __attribute__((dllimport)) void foo(int); + + - ( , + ) + + extern int (*foo)(const char*); + + : + + extern , tcc , + + + int (*foo)(const char*); => !!! + + __attribute__((dllimport)) + + + void foo(int); => !!!, . KX + , tcc KX: 1. tcc -v , KX - tcc version 0.9.26 (i386 KolibriOS/KX extension) + tcc version 0.9.26 (i386 KolibriOS/KX extension 0.4.6) 2. __KX__, @@ -74,25 +106,4 @@ , . - . - - - , - KX, , - , - . - KX. - - ... - - #ifdef _C_LAYER - // KX - / - if(!kolibri_libimg_init()){ // libimg.obj - notify_show("Libimg.obj not loaded!' -E"); - exit(0); - } - #endif - - ... - \ No newline at end of file + . \ No newline at end of file diff --git a/programs/develop/ktcc/trunk/source/i386-gen.c b/programs/develop/ktcc/trunk/source/i386-gen.c index 77536f88a8..a682077c46 100644 --- a/programs/develop/ktcc/trunk/source/i386-gen.c +++ b/programs/develop/ktcc/trunk/source/i386-gen.c @@ -353,6 +353,14 @@ static void gen_static_call(int v) static void gcall_or_jmp(int is_jmp) { int r; +#ifdef TCC_TARGET_KX + if (vtop->type.t & VT_IMPORT) { + o(0x15ff); + greloc(cur_text_section, vtop->sym, ind, R_386_32); + gen_le32(0); + return; + } +#endif if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { /* constant case */ if (vtop->r & VT_SYM) { diff --git a/programs/develop/ktcc/trunk/source/libtcc.c b/programs/develop/ktcc/trunk/source/libtcc.c index 73071b0499..82d2c081f6 100644 --- a/programs/develop/ktcc/trunk/source/libtcc.c +++ b/programs/develop/ktcc/trunk/source/libtcc.c @@ -660,7 +660,11 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section, else sh_num = section->sh_num; - if ((sym->type.t & VT_BTYPE) == VT_FUNC) { + if (((sym->type.t & VT_BTYPE) == VT_FUNC +#ifdef TCC_TARGET_KX + ) && ((vtop->type.t & VT_IMPORT) == 0 +#endif + )) { sym_type = STT_FUNC; } else if ((sym->type.t & VT_BTYPE) == VT_VOID) { sym_type = STT_NOTYPE; @@ -859,11 +863,14 @@ PUB_FUNC void tcc_error_noabort(const char *fmt, ...) PUB_FUNC void tcc_error(const char *fmt, ...) { TCCState *s1 = tcc_state; + // { Edit by Coldy + if (fmt) { va_list ap; va_start(ap, fmt); error1(s1, 0, fmt, ap); va_end(ap); + } // } /* better than nothing: in some cases, we accept to handle errors */ if (s1->error_set_jmp_enabled) { longjmp(s1->error_jmp_buf, 1); diff --git a/programs/develop/ktcc/trunk/source/tcc.c b/programs/develop/ktcc/trunk/source/tcc.c index 67fe90fa10..f8ca47ffb2 100644 --- a/programs/develop/ktcc/trunk/source/tcc.c +++ b/programs/develop/ktcc/trunk/source/tcc.c @@ -59,7 +59,8 @@ static void display_info(TCCState *s, int what) #elif defined TCC_TARGET_MEOS " KolibriOS" #ifdef TCC_TARGET_KX - "/KX extension" + "/KX extension " + TCC_KX_VERSION_INFO #endif #else " Linux" diff --git a/programs/develop/ktcc/trunk/source/tcc.h b/programs/develop/ktcc/trunk/source/tcc.h index 16ef960787..e1760f7cb0 100644 --- a/programs/develop/ktcc/trunk/source/tcc.h +++ b/programs/develop/ktcc/trunk/source/tcc.h @@ -1217,6 +1217,9 @@ PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line); #define realloc(p, s) use_tcc_realloc(p, s) #undef strdup #define strdup(s) use_tcc_strdup(s) +// { Added by Coldy +#define tcc_abort() tcc_error(0) +// } PUB_FUNC void tcc_memstats(int bench); PUB_FUNC void tcc_error_noabort(const char *fmt, ...); PUB_FUNC NORETURN void tcc_error(const char *fmt, ...); diff --git a/programs/develop/ktcc/trunk/source/tccgen.c b/programs/develop/ktcc/trunk/source/tccgen.c index fe2db16428..6a6e5e13a7 100644 --- a/programs/develop/ktcc/trunk/source/tccgen.c +++ b/programs/develop/ktcc/trunk/source/tccgen.c @@ -6316,7 +6316,7 @@ static int decl0(int l, int is_for_loop_init) if (ad.a.weak) type.t |= VT_WEAK; -#ifdef TCC_TARGET_PE +#if defined(TCC_TARGET_PE) || defined(TCC_TARGET_KX) if (ad.a.func_import) type.t |= VT_IMPORT; if (ad.a.func_export) diff --git a/programs/develop/ktcc/trunk/source/tcckx.c b/programs/develop/ktcc/trunk/source/tcckx.c index 556a896169..82cfdf2108 100644 --- a/programs/develop/ktcc/trunk/source/tcckx.c +++ b/programs/develop/ktcc/trunk/source/tcckx.c @@ -1,7 +1,7 @@ /* * TCCKX.C - KolibriOS/KX file output for the TinyC Compiler * - * Copyright (c) 2021 Coldy + * Copyright (c) 2021-2022 Coldy * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,6 +17,8 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#define TCC_KX_VERSION_INFO "0.4.6" typedef struct { char magic[4]; @@ -67,7 +69,7 @@ typedef struct { if (dynsym_index == 0) { //if (strcmp(name, __kx_import_table_sym) != 0) { - tcc_error/*_noabort*/("undefined symbol '%s'", name); + tcc_error/*_noabort*/("(kx) undefined symbol '%s'", name); } // KOS support 32 bit only @@ -314,7 +316,39 @@ typedef struct { tcc_free(imp); } } - + + // This routine is called from build_reloc to check the code for incorrect import calls +void kx_check_import_error(int reloc_type, const char* code_base, Elf32_Addr offset, const char* symbol_name) { + + unsigned char fError = 0; + char* p = (char*)(offset + code_base); + + // Hook for "[extern] rtype foo([?])" declaration + if (((unsigned char)*((char*)(p-1))) == 0xe8){ + // call m32 + tcc_error_noabort("import symbol '%s' has direct call (not supported),\n\t use __attribute__((dllimport)) prefix", symbol_name); + fError = 1; + } + + // Hook for MSVC "__declspec(dllimport) rtype(*foo)([?])" + /*if ((((unsigned char)*(p + 4)) == 0xff) && + (((unsigned char)*(p + 5)) == 0x10)) {*/ + if (*((uint16_t*)(p + 4)) == 0x10ff) { + /* + (mov eax [m32]) + call dword[eax] + */ + tcc_error_noabort("import symbol '%s' has unsupported call type", symbol_name); + fError = 1; + } + if (reloc_type == R_386_PC32) { + tcc_error_noabort("incorrect relocation type for import symbol '%s'", symbol_name); + fError = 1; + } + if (fError) + tcc_abort(); +} + #if /*!*/defined(_DEBUG)// && !defined(_WIN32) #define kx_debug_output printf #else diff --git a/programs/develop/ktcc/trunk/source/tccmeos.c b/programs/develop/ktcc/trunk/source/tccmeos.c index d96d4814ba..ccfeb50f27 100644 --- a/programs/develop/ktcc/trunk/source/tccmeos.c +++ b/programs/develop/ktcc/trunk/source/tccmeos.c @@ -2,7 +2,7 @@ * TCCMEOS.C - KolibriOS/MenuetOS file output for the TinyC Compiler * * Copyright (c) 2006 Andrey Khalyavin - * Copyright (c) 2021 Coldy (KX extension) + * Copyright (c) 2021-2022 Coldy (KX extension) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -58,6 +58,7 @@ typedef struct { #ifdef TCC_TARGET_KX void kx_init(me_info* me); void kx_build_imports(me_info* me); + void kx_check_import_error(int reloc_type, const char* code_base, Elf32_Addr offset, const char* symbol_name); long kx_get_header_length(me_info* me); void kx_write_header(me_info* me, FILE* f); void kx_write_imports(me_info* me, FILE* f); @@ -112,8 +113,11 @@ void build_reloc(me_info* me) rel=rel_; int type = ELF32_R_TYPE(rel->r_info); rel_=rel+1; - if (type != R_386_PC32 && type != R_386_32) + if (type != R_386_PC32 && type != R_386_32) { + // gcc (and friends) object files is used? + tcc_error("unsupported relocation type %d", type); continue; + } int sym = ELF32_R_SYM(rel->r_info); if (sym>symtab_section->data_offset/sizeof(Elf32_Sym)) continue; @@ -121,34 +125,42 @@ void build_reloc(me_info* me) int sect=esym->st_shndx; int sh_addr; ss=findsection(me,sect); + const char* sym_name = strtab_section->data + esym->st_name; + int sym_index; + Elf32_Sym* dyn_sym; + // Import has more less priority in relation to local symbols if (ss==0) { - const char *sym_name = strtab_section->data + esym->st_name; #ifdef TCC_TARGET_KX - int sym_index = find_elf_sym(me->s1->dynsymtab_section, sym_name); - Elf32_Sym* dyn_sym; + sym_index = find_elf_sym(me->s1->dynsymtab_section, sym_name); if (sym_index == 0) { #endif - tcc_error_noabort("undefined symbol '%s'", sym_name); - continue; + tcc_error_noabort("undefined import symbol '%s'", sym_name); + continue; #ifdef TCC_TARGET_KX } dyn_sym = &((ElfW(Sym) *)me->s1->dynsymtab_section->data)[sym_index]; sh_addr = dyn_sym->st_value; if (sh_addr == 0) { - tcc_error_noabort("symbol '%s' has zero value", sym_name); + tcc_error_noabort("import symbol '%s' has zero value", sym_name); continue; } + + // Stop linking if incorrect import + kx_check_import_error(type, s->data, rel->r_offset, sym_name); #endif } - else + else { + if (esym->st_shndx == SHN_UNDEF) + tcc_error("unresolved external symbol '%s'", sym_name); sh_addr = ss->sh_addr; + } if (rel->r_offset>s->data_size) continue; if (type==R_386_PC32) - *(int*)(rel->r_offset+s->data)+=/*ss->*/sh_addr+esym->st_value-rel->r_offset-s->sh_addr; + *(int*)(rel->r_offset+s->data)+= sh_addr+esym->st_value-rel->r_offset-s->sh_addr; else if (type==R_386_32) - *(int*)(rel->r_offset+s->data)+=/*ss->*/sh_addr+esym->st_value; + *(int*)(rel->r_offset+s->data)+= sh_addr+esym->st_value; } rel=rel_; s=s->next;