forked from KolibriOS/kolibrios
Add KX extension to tcc (autoload w/import table support), phase 1
git-svn-id: svn://kolibrios.org@9284 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
ff850a3614
commit
664e46d057
@ -71,6 +71,9 @@ ST_DATA struct TCCState *tcc_state;
|
|||||||
#ifdef TCC_TARGET_MEOS
|
#ifdef TCC_TARGET_MEOS
|
||||||
#include "tccmeos.c"
|
#include "tccmeos.c"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef TCC_TARGET_KX
|
||||||
|
#include "tcckx.c"
|
||||||
|
#endif
|
||||||
#ifdef TCC_TARGET_MEOS_LINUX
|
#ifdef TCC_TARGET_MEOS_LINUX
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#endif
|
#endif
|
||||||
@ -1461,8 +1464,10 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags,
|
|||||||
}
|
}
|
||||||
#endif
|
#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);
|
ret = pe_load_file(s1, filename, fd);
|
||||||
|
#elif defined(TCC_TARGET_KX)
|
||||||
|
ret = pe_load_def(s1, fd);
|
||||||
#else
|
#else
|
||||||
/* as GNU ld, consider it is an ld script if not recognized */
|
/* as GNU ld, consider it is an ld script if not recognized */
|
||||||
ret = tcc_load_ldscript(s1);
|
ret = tcc_load_ldscript(s1);
|
||||||
@ -2125,7 +2130,9 @@ static const TCCOption tcc_options[] = {
|
|||||||
{ "MF", TCC_OPTION_MF, TCC_OPTION_HAS_ARG },
|
{ "MF", TCC_OPTION_MF, TCC_OPTION_HAS_ARG },
|
||||||
{ "x", TCC_OPTION_x, TCC_OPTION_HAS_ARG },
|
{ "x", TCC_OPTION_x, TCC_OPTION_HAS_ARG },
|
||||||
{ "stack", TCC_OPTION_stack, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP},
|
{ "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 },
|
{ "nobss", TCC_OPTION_nobss, 0 },
|
||||||
|
#endif
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2458,9 +2465,11 @@ ST_FUNC int tcc_parse_args1(TCCState *s, int argc, char **argv)
|
|||||||
s->pe_stack_size = strtoul(optarg+1, NULL, 10);
|
s->pe_stack_size = strtoul(optarg+1, NULL, 10);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
#if defined(TCC_TARGET_MEOS) && !defined (TCC_TARGET_KX)
|
||||||
case TCC_OPTION_nobss:
|
case TCC_OPTION_nobss:
|
||||||
s->nobss = 1;
|
s->nobss = 1;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
if (s->warn_unsupported) {
|
if (s->warn_unsupported) {
|
||||||
unsupported_option:
|
unsupported_option:
|
||||||
|
@ -128,8 +128,10 @@ static void help(void)
|
|||||||
" -Bdir use 'dir' as tcc internal library and include path\n"
|
" -Bdir use 'dir' as tcc internal library and include path\n"
|
||||||
" -MD generate target dependencies for make\n"
|
" -MD generate target dependencies for make\n"
|
||||||
" -MF depfile put generated dependencies here\n"
|
" -MF depfile put generated dependencies here\n"
|
||||||
|
#if defined(TCC_TARGET_MEOS) && !defined (TCC_TARGET_KX)
|
||||||
"For KolibriOS only:\n"
|
"For KolibriOS only:\n"
|
||||||
" -nobss do not emit BSS section into file\n"
|
" -nobss do not emit BSS section into file\n"
|
||||||
|
#endif
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +43,12 @@
|
|||||||
#define TCC_ASSERT(ex)
|
#define TCC_ASSERT(ex)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef TCC_TARGET_KX
|
||||||
|
#ifndef TCC_TARGET_MEOS
|
||||||
|
#define TCC_TARGET_MEOS
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
# include <sys/time.h>
|
# include <sys/time.h>
|
||||||
@ -871,7 +877,9 @@ struct TCCState {
|
|||||||
int do_bench; /* option -bench */
|
int do_bench; /* option -bench */
|
||||||
int gen_deps; /* option -MD */
|
int gen_deps; /* option -MD */
|
||||||
char *deps_outfile; /* option -MF */
|
char *deps_outfile; /* option -MF */
|
||||||
|
#if defined(TCC_TARGET_MEOS) && !defined (TCC_TARGET_KX)
|
||||||
int nobss; /* option -nobss, omit BSS section (KolibriOS-only) */
|
int nobss; /* option -nobss, omit BSS section (KolibriOS-only) */
|
||||||
|
#endif
|
||||||
ParseArgsState *parse_args_state;
|
ParseArgsState *parse_args_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
272
programs/develop/ktcc/trunk/source/tcckx.c
Normal file
272
programs/develop/ktcc/trunk/source/tcckx.c
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
* TCCMEOS.C - KolibriOS/MenuetOS file output for the TinyC Compiler
|
* TCCMEOS.C - KolibriOS/MenuetOS file output for the TinyC Compiler
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006 Andrey Khalyavin
|
* Copyright (c) 2006 Andrey Khalyavin
|
||||||
|
* Copyright (c) 2021 Coldy (KX extension)
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef TCC_TARGET_KX
|
||||||
int undef_sym_flag=0;
|
int undef_sym_flag=0;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char magic[8];
|
char magic[8];
|
||||||
@ -37,14 +40,32 @@ typedef struct _meos_section_info{
|
|||||||
int sec_num;
|
int sec_num;
|
||||||
struct _meos_section_info* next;
|
struct _meos_section_info* next;
|
||||||
} meos_section_info;
|
} meos_section_info;
|
||||||
|
#ifdef TCC_TARGET_KX
|
||||||
|
typedef struct {
|
||||||
|
void* data;
|
||||||
|
int data_size;
|
||||||
|
} kx_import_table;
|
||||||
|
#endif
|
||||||
typedef struct {
|
typedef struct {
|
||||||
TCCState* s1;
|
TCCState* s1;
|
||||||
IMAGE_MEOS_FILE_HEADER header;
|
IMAGE_MEOS_FILE_HEADER header;
|
||||||
meos_section_info* code_sections;
|
meos_section_info* code_sections;
|
||||||
meos_section_info* data_sections;
|
meos_section_info* data_sections;
|
||||||
|
#ifdef TCC_TARGET_KX
|
||||||
|
kx_import_table* imp_table;
|
||||||
|
#endif
|
||||||
meos_section_info* bss_sections;
|
meos_section_info* bss_sections;
|
||||||
} me_info;
|
} 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);
|
int tcc_output_dbgme(const char *filename, me_info* me);
|
||||||
|
|
||||||
|
|
||||||
@ -100,20 +121,38 @@ void build_reloc(me_info* me)
|
|||||||
continue;
|
continue;
|
||||||
Elf32_Sym* esym = ((Elf32_Sym *)symtab_section->data)+sym;
|
Elf32_Sym* esym = ((Elf32_Sym *)symtab_section->data)+sym;
|
||||||
int sect=esym->st_shndx;
|
int sect=esym->st_shndx;
|
||||||
|
int sh_addr;
|
||||||
ss=findsection(me,sect);
|
ss=findsection(me,sect);
|
||||||
if (ss==0)
|
if (ss==0)
|
||||||
{
|
{
|
||||||
const char *sym_name = strtab_section->data + esym->st_name;
|
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;
|
undef_sym_flag=1;
|
||||||
tcc_error_noabort("undefined symbol '%s'", sym_name);
|
#endif
|
||||||
|
tcc_error_noabort("undefined symbol '%s'", sym_name);
|
||||||
continue;
|
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)
|
if (rel->r_offset>s->data_size)
|
||||||
continue;
|
continue;
|
||||||
if (type==R_386_PC32)
|
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)
|
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_;
|
rel=rel_;
|
||||||
s=s->next;
|
s=s->next;
|
||||||
@ -168,6 +207,9 @@ void assign_addresses(me_info* me)
|
|||||||
}
|
}
|
||||||
int addr;
|
int addr;
|
||||||
addr=sizeof(IMAGE_MEOS_FILE_HEADER);
|
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)
|
for (si=me->code_sections;si;si=si->next)
|
||||||
{
|
{
|
||||||
si->sh_addr=addr;
|
si->sh_addr=addr;
|
||||||
@ -179,6 +221,10 @@ void assign_addresses(me_info* me)
|
|||||||
addr+=si->data_size;
|
addr+=si->data_size;
|
||||||
}
|
}
|
||||||
me->header.image_size=addr;
|
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)
|
for (si=me->bss_sections;si;si=si->next)
|
||||||
{
|
{
|
||||||
si->sh_addr=addr;
|
si->sh_addr=addr;
|
||||||
@ -253,12 +299,16 @@ int tcc_output_me(TCCState* s1,const char *filename)
|
|||||||
//printf("%d\n",s1->nb_sections);
|
//printf("%d\n",s1->nb_sections);
|
||||||
memset(&me,0,sizeof(me));
|
memset(&me,0,sizeof(me));
|
||||||
me.s1=s1;
|
me.s1=s1;
|
||||||
|
#ifdef TCC_TARGET_KX
|
||||||
|
kx_init(&me);
|
||||||
|
#endif
|
||||||
relocate_common_syms();
|
relocate_common_syms();
|
||||||
assign_addresses(&me);
|
assign_addresses(&me);
|
||||||
|
#ifndef TCC_TARGET_KX
|
||||||
if(undef_sym_flag){
|
if(undef_sym_flag){
|
||||||
tcc_error("Linker error!");
|
tcc_error("Linker error!");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (s1->do_debug)
|
if (s1->do_debug)
|
||||||
tcc_output_dbgme(filename, &me);
|
tcc_output_dbgme(filename, &me);
|
||||||
@ -274,11 +324,18 @@ int tcc_output_me(TCCState* s1,const char *filename)
|
|||||||
for (i=0;i<8;i++)
|
for (i=0;i<8;i++)
|
||||||
me.header.magic[i]=me_magic[i];
|
me.header.magic[i]=me_magic[i];
|
||||||
fwrite(&me.header,1,sizeof(IMAGE_MEOS_FILE_HEADER),f);
|
fwrite(&me.header,1,sizeof(IMAGE_MEOS_FILE_HEADER),f);
|
||||||
|
#ifdef TCC_TARGET_KX
|
||||||
|
kx_write_header(&me, f);
|
||||||
|
#endif
|
||||||
meos_section_info* si;
|
meos_section_info* si;
|
||||||
for(si=me.code_sections;si;si=si->next)
|
for(si=me.code_sections;si;si=si->next)
|
||||||
fwrite(si->data,1,si->data_size,f);
|
fwrite(si->data,1,si->data_size,f);
|
||||||
for (si=me.data_sections;si;si=si->next)
|
for (si=me.data_sections;si;si=si->next)
|
||||||
fwrite(si->data,1,si->data_size,f);
|
fwrite(si->data,1,si->data_size,f);
|
||||||
|
#ifdef TCC_TARGET_KX
|
||||||
|
kx_write_imports(&me, f);
|
||||||
|
kx_free(&me);
|
||||||
|
#else
|
||||||
if (!s1->nobss)
|
if (!s1->nobss)
|
||||||
{
|
{
|
||||||
for (si=me.bss_sections;si;si=si->next)
|
for (si=me.bss_sections;si;si=si->next)
|
||||||
@ -297,6 +354,7 @@ int tcc_output_me(TCCState* s1,const char *filename)
|
|||||||
tcc_error_noabort("We lose .BSS section when linking KOS32 executable");
|
tcc_error_noabort("We lose .BSS section when linking KOS32 executable");
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
#endif
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1564,14 +1564,18 @@ quit:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
#ifndef TCC_TARGET_MEOS
|
#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;
|
||||||
char line[400], dllname[80], *p, *x;
|
char line[400], dllname[80], *p, *x;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
|
#ifdef TCC_TARGET_KX
|
||||||
|
fp = fopen(file->filename, "rb");
|
||||||
|
#else
|
||||||
fp = fdopen(dup(fd), "rb");
|
fp = fdopen(dup(fd), "rb");
|
||||||
|
#endif
|
||||||
while (fgets(line, sizeof line, fp))
|
while (fgets(line, sizeof line, fp))
|
||||||
{
|
{
|
||||||
p = trimfront(trimback(line, strchr(line, 0)));
|
p = trimfront(trimback(line, strchr(line, 0)));
|
||||||
|
Loading…
Reference in New Issue
Block a user