/programs/develop/ktcc/trunk/source/libtcc.c |
---|
71,6 → 71,9 |
#ifdef TCC_TARGET_MEOS |
#include "tccmeos.c" |
#endif |
#ifdef TCC_TARGET_KX |
#include "tcckx.c" |
#endif |
#ifdef TCC_TARGET_MEOS_LINUX |
#include <libgen.h> |
#endif |
1461,8 → 1464,10 |
} |
#endif |
#if defined(TCC_TARGET_PE) || defined(TCC_TARGET_MEOS) |
#if defined (TCC_TARGET_PE) || (defined(TCC_TARGET_MEOS) && !defined(TCC_TARGET_KX)) |
ret = pe_load_file(s1, filename, fd); |
#elif defined(TCC_TARGET_KX) |
ret = pe_load_def(s1, fd); |
#else |
/* as GNU ld, consider it is an ld script if not recognized */ |
ret = tcc_load_ldscript(s1); |
2125,7 → 2130,9 |
{ "MF", TCC_OPTION_MF, TCC_OPTION_HAS_ARG }, |
{ "x", TCC_OPTION_x, TCC_OPTION_HAS_ARG }, |
{ "stack", TCC_OPTION_stack, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP}, |
#if defined(TCC_TARGET_MEOS) && !defined (TCC_TARGET_KX) |
{ "nobss", TCC_OPTION_nobss, 0 }, |
#endif |
{ NULL, 0, 0 }, |
}; |
2458,9 → 2465,11 |
s->pe_stack_size = strtoul(optarg+1, NULL, 10); |
#endif |
break; |
#if defined(TCC_TARGET_MEOS) && !defined (TCC_TARGET_KX) |
case TCC_OPTION_nobss: |
s->nobss = 1; |
break; |
#endif |
default: |
if (s->warn_unsupported) { |
unsupported_option: |
/programs/develop/ktcc/trunk/source/tcc.c |
---|
128,8 → 128,10 |
" -Bdir use 'dir' as tcc internal library and include path\n" |
" -MD generate target dependencies for make\n" |
" -MF depfile put generated dependencies here\n" |
#if defined(TCC_TARGET_MEOS) && !defined (TCC_TARGET_KX) |
"For KolibriOS only:\n" |
" -nobss do not emit BSS section into file\n" |
#endif |
); |
} |
/programs/develop/ktcc/trunk/source/tcc.h |
---|
43,6 → 43,12 |
#define TCC_ASSERT(ex) |
#endif |
#ifdef TCC_TARGET_KX |
#ifndef TCC_TARGET_MEOS |
#define TCC_TARGET_MEOS |
#endif |
#endif |
#ifndef _WIN32 |
# include <unistd.h> |
# include <sys/time.h> |
871,7 → 877,9 |
int do_bench; /* option -bench */ |
int gen_deps; /* option -MD */ |
char *deps_outfile; /* option -MF */ |
#if defined(TCC_TARGET_MEOS) && !defined (TCC_TARGET_KX) |
int nobss; /* option -nobss, omit BSS section (KolibriOS-only) */ |
#endif |
ParseArgsState *parse_args_state; |
}; |
/programs/develop/ktcc/trunk/source/tcckx.c |
---|
0,0 → 1,272 |
/* |
* TCCKX.C - KolibriOS/KX file output for the TinyC Compiler |
* |
* Copyright (c) 2021 Coldy |
* |
* This library is free software; you can redistribute it and/or |
* modify it under the terms of the GNU Lesser General Public |
* License as published by the Free Software Foundation; either |
* version 2 of the License, or (at your option) any later version. |
* |
* This library is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
* Lesser General Public License for more details. |
* |
* You should have received a copy of the GNU Lesser General Public |
* License along with this library; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
*/ |
typedef struct { |
char magic[4]; |
long flags; |
long i_ptr; |
} kx_header; |
static kx_header __kx_header = { 'K','X',0, 0, 0x40, 0 }; |
typedef struct LibraryEntry { |
uint32_t ImportEntry; |
uint32_t LibraryName; |
}; |
/*union ImportEntry { |
uint32_t ImportStr; |
uint32_t ImportPrt; |
};*/ |
//static char __kx_import_table_sym[] = "__i_ptr__"; |
void kx_build_imports(me_info* me) { |
ElfW(Sym) *sym; |
int sym_index, sym_end; |
sym_end = symtab_section->data_offset / sizeof(ElfW(Sym)); |
CString *str_arr, *len_arr; |
int nlib = 0; |
int i; |
if (me->header.version != 2) |
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; |
} |
for (sym_index = 1; sym_index < sym_end; ++sym_index) { |
sym = (ElfW(Sym) *)symtab_section->data + sym_index; |
if (sym->st_shndx == SHN_UNDEF) { |
const char *name = symtab_section->link->data + sym->st_name; |
int dynsym_index = find_elf_sym(me->s1->dynsymtab_section, name); |
if (dynsym_index == 0) { |
//if (strcmp(name, __kx_import_table_sym) != 0) { |
tcc_error/*_noabort*/("undefined symbol '%s'", name); |
//continue; // FIXME: stop compile! |
//} |
//continue; |
} |
// KOS support 32 bit only |
Elf32_Sym* dyn_sym = &((ElfW(Sym) *)me->s1->dynsymtab_section->data)[dynsym_index]; |
DLLReference **dllref = me->s1->loaded_dlls; |
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; |
nlib++; |
cstr_new(&str_arr[i]); |
cstr_new(&len_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; |
} |
char name_len = strlen(name) + 1; |
cstr_ccat(&len_arr[i], name_len); |
cstr_cat(&str_arr[i], name, name_len); |
} |
} |
/*if (len_arr[0].size == 0) |
{ |
//tcc_error(""); |
return; |
}*/ |
// Zero terminate of ptr (was BUG#3) |
i = 0; |
do { |
cstr_ccat(&len_arr[i], 0); |
i++; |
} while (i < nlib); |
kx_import_table* imp_sect; |
imp_sect = tcc_mallocz(sizeof(kx_import_table)); |
imp_sect->data = tcc_mallocz(1024); // FIXME!!! |
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? |
// Strings |
i = 0; |
do { |
memcpy(imp_data, str_arr[i].data, str_arr[i].size); |
imp_data += str_arr[i].size; |
imp_sect->data_size += str_arr[i].size; |
i++; |
} while (i < nlib); |
// Align pad (check algorithm!) |
int align = 4 - (me->header.image_size + imp_sect->data_size) % 4; |
imp_data += align; |
imp_sect->data_size += align; |
/*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, __kx_import_table_sym);*/ |
__kx_header.i_ptr = me->header.image_size + imp_sect->data_size; |
struct 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)); |
if (nlib > 1) { |
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++; |
i++; |
} while (i < nlib); |
} |
// End of LibraryEntry |
imp_data += sizeof(struct LibraryEntry) + 4; |
imp_sect->data_size += sizeof(struct LibraryEntry) + 4; |
char name_len; |
long l, nl; |
l = me->header.image_size; |
i = 0; |
do { |
char* len_data = len_arr[i].data; |
name_len = *len_data++; // Skip library name |
nl = name_len; |
do { |
const char *name = (const char *)str_arr[i].data + nl; |
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); |
l += name_len; |
memcpy(imp_data, &l, 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; |
i++; |
} while (i < nlib); |
me->header.image_size += imp_sect->data_size; |
me->imp_table = imp_sect; |
tcc_free(str_arr); |
tcc_free(len_arr); |
} |
void kx_init(me_info* me) { |
ElfW(Sym) *sym; |
int sym_index = 1, sym_end = symtab_section->data_offset / sizeof(ElfW(Sym)); |
// Check that we have at last one import... |
for (; sym_index < sym_end; ++sym_index) { |
sym = (ElfW(Sym) *)symtab_section->data + sym_index; |
if (sym->st_shndx == SHN_UNDEF) |
break; |
} |
if ((sym_index < sym_end) && |
// ... and user attached at last one *.def |
(me->s1->nb_loaded_dlls)) |
me->header.version = 2; |
//tcc_add_crt(me->s1, "start1.o"); |
} |
long kx_get_header_length(me_info* me) { |
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) |
fwrite(&__kx_header, 1, sizeof(kx_header), f); |
} |
void kx_write_imports(me_info* me, FILE* f) { |
if (me->imp_table) |
fwrite(me->imp_table->data, 1, me->imp_table->data_size, f); |
} |
void kx_free(me_info* me) { |
kx_import_table* imp = me->imp_table; |
if (imp){ |
tcc_free(imp->data); |
tcc_free(imp); |
} |
} |
/programs/develop/ktcc/trunk/source/tccmeos.c |
---|
2,6 → 2,7 |
* TCCMEOS.C - KolibriOS/MenuetOS file output for the TinyC Compiler |
* |
* Copyright (c) 2006 Andrey Khalyavin |
* Copyright (c) 2021 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 |
18,7 → 19,9 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
*/ |
#ifndef TCC_TARGET_KX |
int undef_sym_flag=0; |
#endif |
typedef struct { |
char magic[8]; |
37,14 → 40,32 |
int sec_num; |
struct _meos_section_info* next; |
} meos_section_info; |
#ifdef TCC_TARGET_KX |
typedef struct { |
void* data; |
int data_size; |
} kx_import_table; |
#endif |
typedef struct { |
TCCState* s1; |
IMAGE_MEOS_FILE_HEADER header; |
meos_section_info* code_sections; |
meos_section_info* data_sections; |
#ifdef TCC_TARGET_KX |
kx_import_table* imp_table; |
#endif |
meos_section_info* bss_sections; |
} me_info; |
#ifdef TCC_TARGET_KX |
void kx_init(me_info* me); |
void kx_build_imports(me_info* me); |
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); |
void kx_free(me_info* me); |
#endif |
int tcc_output_dbgme(const char *filename, me_info* me); |
100,20 → 121,38 |
continue; |
Elf32_Sym* esym = ((Elf32_Sym *)symtab_section->data)+sym; |
int sect=esym->st_shndx; |
int sh_addr; |
ss=findsection(me,sect); |
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; |
if (sym_index == 0) { |
#else |
undef_sym_flag=1; |
#endif |
tcc_error_noabort("undefined 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); |
continue; |
} |
#endif |
} |
else |
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)+=/*ss->*/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)+=/*ss->*/sh_addr+esym->st_value; |
} |
rel=rel_; |
s=s->next; |
168,6 → 207,9 |
} |
int addr; |
addr=sizeof(IMAGE_MEOS_FILE_HEADER); |
#ifdef TCC_TARGET_KX |
addr += kx_get_header_length(me); |
#endif |
for (si=me->code_sections;si;si=si->next) |
{ |
si->sh_addr=addr; |
179,6 → 221,10 |
addr+=si->data_size; |
} |
me->header.image_size=addr; |
#ifdef TCC_TARGET_KX |
kx_build_imports(me); |
addr = me->header.image_size; |
#endif |
for (si=me->bss_sections;si;si=si->next) |
{ |
si->sh_addr=addr; |
253,12 → 299,16 |
//printf("%d\n",s1->nb_sections); |
memset(&me,0,sizeof(me)); |
me.s1=s1; |
#ifdef TCC_TARGET_KX |
kx_init(&me); |
#endif |
relocate_common_syms(); |
assign_addresses(&me); |
#ifndef TCC_TARGET_KX |
if(undef_sym_flag){ |
tcc_error("Linker error!"); |
} |
#endif |
if (s1->do_debug) |
tcc_output_dbgme(filename, &me); |
274,11 → 324,18 |
for (i=0;i<8;i++) |
me.header.magic[i]=me_magic[i]; |
fwrite(&me.header,1,sizeof(IMAGE_MEOS_FILE_HEADER),f); |
#ifdef TCC_TARGET_KX |
kx_write_header(&me, f); |
#endif |
meos_section_info* si; |
for(si=me.code_sections;si;si=si->next) |
fwrite(si->data,1,si->data_size,f); |
for (si=me.data_sections;si;si=si->next) |
fwrite(si->data,1,si->data_size,f); |
#ifdef TCC_TARGET_KX |
kx_write_imports(&me, f); |
kx_free(&me); |
#else |
if (!s1->nobss) |
{ |
for (si=me.bss_sections;si;si=si->next) |
297,6 → 354,7 |
tcc_error_noabort("We lose .BSS section when linking KOS32 executable"); |
} |
*/ |
#endif |
fclose(f); |
return 0; |
} |
/programs/develop/ktcc/trunk/source/tccpe.c |
---|
1564,7 → 1564,7 |
} |
/* ------------------------------------------------------------- */ |
#ifndef TCC_TARGET_MEOS |
#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; |
1571,7 → 1571,11 |
char line[400], dllname[80], *p, *x; |
FILE *fp; |
#ifdef TCC_TARGET_KX |
fp = fopen(file->filename, "rb"); |
#else |
fp = fdopen(dup(fd), "rb"); |
#endif |
while (fgets(line, sizeof line, fp)) |
{ |
p = trimfront(trimback(line, strchr(line, 0))); |