/programs/develop/metcc/trunk/source/Makefile |
---|
0,0 → 1,4 |
OUTFILE = ktcc.kex |
OBJS = tcc.o console.o |
CGLAGS =-O2 -g -Wall -mpreferred-stack-boundary=2 -march=i386 -falign-functions=0 -fno-strict-aliasing |
include $(MENUETDEV)/makefiles/Makefile_for_program |
/programs/develop/metcc/trunk/source/console.asm |
---|
0,0 → 1,85 |
format ELF |
section '.text' executable |
public console_init |
public console_printf |
public console_exit |
align 4 |
console_init: |
pushad |
mov eax,[console_init_status] |
test eax,eax |
jnz console_initializated |
mov [console_init_status],1 |
mov eax,68 |
mov ebx,19 |
mov ecx,console_path |
int 0x40 |
test eax,eax |
jz console_not_loaded |
mov ebx,[eax+4] |
mov [con_start],ebx |
mov ebx,[eax+4+16] |
mov [con_init],ebx |
mov ebx,[eax+4+32] |
mov [con_printf],ebx |
push 1 |
call [con_start] |
push caption |
push -1 |
push -1 |
push -1 |
push -1 |
call [con_init] |
console_not_loaded: |
console_initializated: |
popad |
ret |
align 4 |
console_printf: |
pop [return_addres] |
call [con_printf] |
;add esp,8 |
push [return_addres] |
ret |
align 4 |
console_exit: |
push 0 |
call [con_exit] |
ret |
;----------------------------- |
console_path db '/sys/dll/console.obj',0 |
caption db 'Console',0 |
align 4 |
con_start rd 1 |
con_init rd 1 |
con_printf rd 1 |
con_exit rd 1 |
console_init_status rd 1 |
return_addres rd 1 |
/programs/develop/metcc/trunk/source/start.asm |
---|
0,0 → 1,136 |
format ELF |
section '.text' executable |
public start |
;extrn mf_init |
extrn main |
;include 'debug2.inc' |
__DEBUG__=0 |
;start_: |
virtual at 0 |
db 'MENUET01' ; 1. Magic number (8 bytes) |
dd 0x01 ; 2. Version of executable file |
dd start ; 3. Start address |
dd 0x0 ; 4. Size of image |
dd 0x100000 ; 5. Size of needed memory |
dd 0x100000 ; 6. Pointer to stack |
hparams dd 0x0 ; 7. Pointer to program arguments |
hpath dd 0x0 ; 8. Pointer to program path |
end virtual |
start: |
;DEBUGF 'Start programm\n' |
;init heap of memory |
mov eax,68 |
mov ebx,11 |
int 0x40 |
;DEBUGF ' path "%s"\n params "%s"\n', .path, .params |
; check for overflow |
mov al, [path+buf_len-1] |
or al, [params+buf_len-1] |
jnz .crash |
; check if path written by OS |
mov eax, [hparams] |
test eax, eax |
jz .without_path |
mov eax, path |
.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: |
;DEBUGF 'call main(%x, %x) with params:\n', [argc], argv |
if __DEBUG__ = 1 |
mov ecx, [argc] |
@@: |
lea esi, [ecx * 4 + argv-4] |
DEBUGF '0x%x) "%s"\n', cx, [esi] |
loop @b |
end if |
push [argc] |
push argv |
call main |
.exit: |
;DEBUGF 'Exit from prog\n'; |
xor eax,eax |
dec eax |
int 0x40 |
dd -1 |
.crash: |
;DEBUGF 'E:buffer overflowed\n' |
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 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 |
/programs/develop/metcc/trunk/source/tcc.c |
---|
31,10 → 31,10 |
#include <stdio.h> |
#include <stdarg.h> |
#include <string.h> |
#include <errno.h> |
//#include <errno.h> |
#include <math.h> |
#include <unistd.h> |
#include <signal.h> |
//#include <signal.h> |
#include <fcntl.h> |
#include <setjmp.h> |
#include <time.h> |
41,10 → 41,11 |
#ifdef WIN32 |
#include <sys/timeb.h> |
#endif |
#ifndef WIN32 |
//#ifndef WIN32 |
#include <sys/time.h> |
#include <sys/ucontext.h> |
#endif |
//#include <sys/ucontext.h> |
//#endif |
#endif /* !CONFIG_TCCBOOT */ |
73,6 → 74,8 |
//#define TCC_TARGET_I386 /* i386 code generator */ |
//#define TCC_TARGET_ARM /* ARMv4 code generator */ |
//#define TCC_TARGET_C67 /* TMS320C67xx code generator */ |
//---------------------------------------------------------------- |
#define TCC_TARGET_MEOS |
/* default target is I386 */ |
#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \ |
718,7 → 721,7 |
#define strtoll (long long)strtol |
#endif |
#elif defined(TCC_UCLIBC) || defined(__FreeBSD__) |
/* currently incorrect */ |
long double strtold(const char *nptr, char **endptr) |
{ |
return (long double)strtod(nptr, endptr); |
727,12 → 730,20 |
{ |
return (float)strtod(nptr, endptr); |
} |
#else |
/* XXX: need to define this to use them in non ISOC99 context */ |
extern float strtof (const char *__nptr, char **__endptr); |
extern long double strtold (const char *__nptr, char **__endptr); |
//extern long long strtoll(const char *__nptr, char **__endptr, int __base) |
#endif |
#define strtold (long double)strtod |
#define strtof (float)strtod |
#define strtoll (long long)strtol |
static char *pstrcpy(char *buf, int buf_size, const char *s); |
static char *pstrcat(char *buf, int buf_size, const char *s); |
static const char *tcc_basename(const char *name); |
924,7 → 935,7 |
static TCCSyms tcc_syms[] = { |
#if !defined(CONFIG_TCCBOOT) |
TCCSYM(printf) |
TCCSYM(fprintf) |
TCCSYM(printf) |
TCCSYM(fopen) |
TCCSYM(fclose) |
#endif |
944,14 → 955,15 |
} |
#elif !defined(WIN32) |
//------------------------------------------------------------------------- |
//#include <dlfcn.h> |
#include <dlfcn.h> |
void *resolve_sym(TCCState *s1, const char *sym, int type) |
{ |
return dlsym(RTLD_DEFAULT, sym); |
return(0); |
//return dlsym(RTLD_DEFAULT, sym); |
} |
//------------------------------------------------------------------------- |
#endif |
/********************************************************/ |
1373,7 → 1385,7 |
if (!s1->error_func) { |
/* default case: stderr */ |
fprintf(stderr, "%s\n", buf); |
printf("%s\n", buf); |
} else { |
s1->error_func(s1->error_opaque, buf); |
} |
1887,7 → 1899,7 |
} |
/* read next char from current input file and handle end of input buffer */ |
static inline void inp(void) |
static inline void input(void) |
{ |
ch = *(++(file->buf_ptr)); |
/* end of buffer/file handling */ |
1899,16 → 1911,16 |
static void handle_stray(void) |
{ |
while (ch == '\\') { |
inp(); |
input(); |
if (ch == '\n') { |
file->line_num++; |
inp(); |
input(); |
} else if (ch == '\r') { |
inp(); |
input(); |
if (ch != '\n') |
goto fail; |
file->line_num++; |
inp(); |
input(); |
} else { |
fail: |
error("stray '\\' in program"); |
1967,7 → 1979,7 |
strings or comments */ |
static void minp(void) |
{ |
inp(); |
input(); |
if (ch == '\\') |
handle_stray(); |
} |
2839,7 → 2851,7 |
/* eat all spaces and comments after include */ |
/* XXX: slightly incorrect */ |
while (ch1 != '\n' && ch1 != CH_EOF) |
inp(); |
input(); |
#endif |
} else { |
/* computed #include : either we have only strings or |
3363,7 → 3375,7 |
} |
*q = '\0'; |
t = toup(ch); |
errno = 0; |
//errno = 0; |
if (t == 'F') { |
ch = *p++; |
tok = TOK_CFLOAT; |
5907,6 → 5919,7 |
{ |
Sym *s; |
int bt; |
int size; |
bt = type->t & VT_BTYPE; |
if (bt == VT_STRUCT) { |
5913,11 → 5926,14 |
/* struct/union */ |
s = type->ref; |
*a = s->r; |
return s->c; |
} else if (bt == VT_PTR) { |
if (type->t & VT_ARRAY) { |
s = type->ref; |
return type_size(&s->type, a) * s->c; |
size=type_size(&s->type, a) * s->c; |
return size;//type_size(&s->type, a) * s->c; |
} else { |
*a = PTR_SIZE; |
return PTR_SIZE; |
6581,9 → 6597,13 |
bit field */ |
if (lbit_pos == 0) { |
if (a == TOK_STRUCT) { |
c = (c + align - 1) & -align; |
//17.09.2007 |
//c = (c + align - 1) & -align; |
offset = c; |
c += size; |
//c += size; |
if (size<=4) {c=c+size;} |
else |
{c=c+align;} |
} else { |
offset = 0; |
if (size > c) |
9332,12 → 9352,12 |
#if defined(TCC_TARGET_PE) || defined(TCC_TARGET_MEOS) |
#include "tccpe.c" |
#endif |
#ifdef TCC_TARGET_MEOS |
#include "tccmeos.c" |
#endif |
#ifdef TCC_TARGET_MEOS |
#include "tccmeos.c" |
#endif |
/* print the position in the source file of PC value 'pc' by reading |
the stabs debug information */ |
static void rt_printline(unsigned long wanted_pc) |
9349,7 → 9369,7 |
int incl_index, len, last_line_num, i; |
const char *str, *p; |
fprintf(stderr, "0x%08lx:", wanted_pc); |
printf("0x%08lx:", wanted_pc); |
func_name[0] = '\0'; |
func_addr = 0; |
9444,20 → 9464,20 |
} |
} |
/* did not find any info: */ |
fprintf(stderr, " ???\n"); |
printf(" ???\n"); |
return; |
found: |
if (last_func_name[0] != '\0') { |
fprintf(stderr, " %s()", last_func_name); |
printf(" %s()", last_func_name); |
} |
if (incl_index > 0) { |
fprintf(stderr, " (%s:%d", |
printf(" (%s:%d", |
incl_files[incl_index - 1], last_line_num); |
for(i = incl_index - 2; i >= 0; i--) |
fprintf(stderr, ", included from %s", incl_files[i]); |
fprintf(stderr, ")"); |
printf(", included from %s", incl_files[i]); |
printf(")"); |
} |
fprintf(stderr, "\n"); |
printf("\n"); |
} |
#if !defined(WIN32) && !defined(CONFIG_TCCBOOT) |
9471,6 → 9491,7 |
#endif |
/* return the PC at frame level 'level'. Return non zero if not found */ |
/* |
static int rt_get_caller_pc(unsigned long *paddr, |
ucontext_t *uc, int level) |
{ |
9495,7 → 9516,7 |
fp = uc->uc_mcontext.gregs[REG_EBP]; |
#endif |
for(i=1;i<level;i++) { |
/* XXX: check address validity with program info */ |
// XXX: check address validity with program info |
if (fp <= 0x1000 || fp >= 0xc0000000) |
return -1; |
fp = ((unsigned long *)fp)[0]; |
9504,18 → 9525,21 |
return 0; |
} |
} |
*/ |
#else |
#warning add arch specific rt_get_caller_pc() |
/* |
static int rt_get_caller_pc(unsigned long *paddr, |
ucontext_t *uc, int level) |
{ |
return -1; |
} |
*/ |
#endif |
/* emit a run time error at position 'pc' */ |
/* |
void rt_error(ucontext_t *uc, const char *fmt, ...) |
{ |
va_list ap; |
9523,16 → 9547,16 |
int i; |
va_start(ap, fmt); |
fprintf(stderr, "Runtime error: "); |
vfprintf(stderr, fmt, ap); |
fprintf(stderr, "\n"); |
printf("Runtime error: "); |
//vfprintf(stderr, fmt, ap); |
printf("\n"); |
for(i=0;i<num_callers;i++) { |
if (rt_get_caller_pc(&pc, uc, i) < 0) |
break; |
if (i == 0) |
fprintf(stderr, "at "); |
printf("at "); |
else |
fprintf(stderr, "by "); |
printf("by "); |
rt_printline(pc); |
} |
exit(255); |
9539,7 → 9563,9 |
va_end(ap); |
} |
*/ |
/* signal handler for fatal errors */ |
/* |
static void sig_error(int signum, siginfo_t *siginf, void *puc) |
{ |
ucontext_t *uc = puc; |
9575,8 → 9601,10 |
} |
exit(255); |
} |
*/ |
#endif |
/* do all relocations (needed before using tcc_get_symbol()) */ |
int tcc_relocate(TCCState *s1) |
{ |
9636,17 → 9664,17 |
#if defined(WIN32) || defined(CONFIG_TCCBOOT) |
error("debug mode currently not available for Windows"); |
#else |
struct sigaction sigact; |
//struct sigaction sigact; |
/* install TCC signal handlers to print debug info on fatal |
runtime errors */ |
sigact.sa_flags = SA_SIGINFO | SA_RESETHAND; |
sigact.sa_sigaction = sig_error; |
sigemptyset(&sigact.sa_mask); |
sigaction(SIGFPE, &sigact, NULL); |
sigaction(SIGILL, &sigact, NULL); |
sigaction(SIGSEGV, &sigact, NULL); |
sigaction(SIGBUS, &sigact, NULL); |
sigaction(SIGABRT, &sigact, NULL); |
//sigact.sa_flags = SA_SIGINFO | SA_RESETHAND; |
//sigact.sa_sigaction = sig_error; |
//sigemptyset(&sigact.sa_mask); |
//sigaction(SIGFPE, &sigact, NULL); |
//sigaction(SIGILL, &sigact, NULL); |
//sigaction(SIGSEGV, &sigact, NULL); |
//sigaction(SIGBUS, &sigact, NULL); |
//sigaction(SIGABRT, &sigact, NULL); |
#endif |
} |
9741,12 → 9769,13 |
snprintf(buf, sizeof(buf), "%s/lib", tcc_lib_path); |
tcc_add_library_path(s, buf); |
} |
#else |
#ifdef TCC_TARGET_MEOS |
#else |
#ifdef TCC_TARGET_MEOS |
tcc_add_library_path(s, ".//lib"); |
#else |
tcc_add_library_path(s, "/usr/local/lib"); |
tcc_add_library_path(s, "/usr/lib"); |
tcc_add_library_path(s, "/lib"); |
tcc_add_library_path(s, "/lib"); |
#endif |
#endif |
10041,6 → 10070,10 |
tcc_add_sysinclude_path(s, "/usr/local/include"); |
tcc_add_sysinclude_path(s, "/usr/include"); |
#endif |
#if defined(TCC_TARGET_MEOS) |
tcc_add_sysinclude_path(s, ".//include"); |
#endif |
snprintf(buf, sizeof(buf), "%s/include", tcc_lib_path); |
tcc_add_sysinclude_path(s, buf); |
#ifdef TCC_TARGET_PE |
10086,10 → 10119,10 |
tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o"); |
tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o"); |
} |
#endif |
#if defined(TCC_TARGET_MEOS) |
if (s->output_type != TCC_OUTPUT_OBJ) |
tcc_add_file(s,".\\start.o"); |
#endif |
#if defined(TCC_TARGET_MEOS) |
if (s->output_type != TCC_OUTPUT_OBJ) |
tcc_add_file(s,".//start.o"); |
#endif |
return 0; |
} |
10229,9 → 10262,6 |
" -r relocatable output\n" |
"Debugger options:\n" |
" -g generate runtime debug info\n" |
#ifdef CONFIG_TCC_BCHECK |
" -b compile with built-in memory and bounds checker (implies -g)\n" |
#endif |
" -bt N show N callers in stack traces\n" |
); |
} |
10351,20 → 10381,30 |
int parse_args(TCCState *s, int argc, char **argv) |
{ |
int optind; |
int i; |
const TCCOption *popt; |
const char *optarg, *p1, *r1; |
char *r; |
/* |
printf("\n%d\n",argc); |
for(i=0;i<argc;i++) |
{ |
printf("\n parameter %d = %s",i+1,argv[i]); |
} |
printf("\n"); |
*/ |
optind = 0; |
while (1) { |
if (optind >= argc) { |
if (nb_files == 0 && !print_search_dirs) |
goto show_help; |
goto show_help; |
else |
break; |
} |
r = argv[optind++]; |
if (r[0] != '-') { |
/* add a new file */ |
dynarray_add((void ***)&files, &nb_files, r); |
if (!multiple_files) { |
10378,7 → 10418,7 |
for(;;) { |
p1 = popt->name; |
if (p1 == NULL) |
error("invalid option -- '%s'", r); |
printf("\n invalid option -- '%s'", r); |
r1 = r + 1; |
for(;;) { |
if (*p1 == '\0') |
10396,7 → 10436,7 |
optarg = r1; |
} else { |
if (optind >= argc) |
error("argument to '%s' is missing", r); |
printf("\n argument to '%s' is missing", r); |
optarg = argv[optind++]; |
} |
} else { |
10412,7 → 10452,7 |
exit(1); |
case TCC_OPTION_I: |
if (tcc_add_include_path(s, optarg) < 0) |
error("too many include paths"); |
printf("\n too many include paths"); |
break; |
case TCC_OPTION_D: |
{ |
10531,10 → 10571,10 |
} else |
#endif |
{ |
error("target %s not found", p); |
printf("\n target %s not found", p); |
} |
} else { |
error("unsupported linker option '%s'", optarg); |
printf("\n unsupported linker option '%s'", optarg); |
} |
} |
break; |
10542,6 → 10582,7 |
if (s->warn_unsupported) { |
unsupported_option: |
warning("unsupported option '%s'", r); |
printf("\n unsupported option '%s'", r); |
} |
break; |
} |
10550,7 → 10591,7 |
return optind; |
} |
int main(int argc, char **argv) |
int app_main(int argc, char **argv) |
{ |
int i; |
TCCState *s; |
10557,7 → 10598,9 |
int nb_objfiles, ret, optind; |
char objfilename[1024]; |
int64_t start_time = 0; |
int bug; |
printf("\nTinyC compiler started.\n "); |
#ifdef WIN32 |
/* on win32, we suppose the lib and includes are at the location |
of 'tcc.exe' */ |
10586,9 → 10629,12 |
nb_libraries = 0; |
reloc_output = 0; |
print_search_dirs = 0; |
printf("TinyC initializated.\n"); |
bug=argc; |
if (bug==0) {bug==1;} |
optind = parse_args(s, bug - 1, argv + 1) + 1; |
printf("\n Arguments parsed.\n"); |
optind = parse_args(s, argc - 1, argv + 1) + 1; |
if (print_search_dirs) { |
/* enough for Linux kernel */ |
printf("install: %s/\n", tcc_lib_path); |
10602,13 → 10648,14 |
if (outfile && output_type == TCC_OUTPUT_MEMORY) |
output_type = TCC_OUTPUT_EXE; |
/* check -c consistency : only single file handled. XXX: checks file type */ |
/* check -c |
consistency : only single file handled. XXX: checks file type */ |
if (output_type == TCC_OUTPUT_OBJ && !reloc_output) { |
/* accepts only a single input file */ |
if (nb_objfiles != 1) |
error("cannot specify multiple files with -c"); |
printf("\n cannot specify multiple files with -c"); |
if (nb_libraries != 0) |
error("cannot specify libraries with -c"); |
printf("\n cannot specify libraries with -c"); |
} |
if (output_type != TCC_OUTPUT_MEMORY) { |
10679,14 → 10726,14 |
#ifdef TCC_TARGET_PE |
if (s->output_type != TCC_OUTPUT_OBJ) { |
ret = tcc_output_pe(s, outfile); |
} else |
#else |
#ifdef TCC_TARGET_MEOS |
} else |
#else |
#ifdef TCC_TARGET_MEOS |
if (s->output_type != TCC_OUTPUT_OBJ) { |
ret = tcc_output_me(s, outfile); |
} else |
} else |
#endif |
#endif |
#endif |
{ |
tcc_output_file(s, outfile); |
10702,6 → 10749,7 |
printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size); |
} |
#endif |
printf("\n TinyC finished work\n"); |
return ret; |
} |
/programs/develop/metcc/trunk/source/tccelf.c |
---|
2224,7 → 2224,7 |
case '\v': |
case '\r': |
case '\n': |
inp(); |
input(); |
goto redo; |
case '/': |
minp(); |
2266,7 → 2266,7 |
break; |
default: |
c = ch; |
inp(); |
input(); |
break; |
} |
#if 0 |
/programs/develop/metcc/trunk/source/tccmeos.c |
---|
16,235 → 16,233 |
* 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[8]; |
int version; |
int entry_point; |
int image_size; |
int memory_size; |
int stack; |
int params; |
int argv; |
} IMAGE_MEOS_FILE_HEADER,*PIMAGE_MEOS_FILE_HEADER; |
typedef struct _meos_section_info{ |
int sh_addr; |
void* data; |
int data_size; |
int sec_num; |
struct _meos_section_info* next; |
} meos_section_info; |
typedef struct { |
TCCState* s1; |
IMAGE_MEOS_FILE_HEADER header; |
meos_section_info* code_sections; |
meos_section_info* data_sections; |
meos_section_info* bss_sections; |
} me_info; |
meos_section_info* findsection(me_info* me,int num) |
{ |
meos_section_info* si; |
for(si=me->code_sections;si;si=si->next) |
{ |
if (si->sec_num==num) |
return si; |
} |
for (si=me->data_sections;si;si=si->next) |
{ |
if (si->sec_num==num) |
return si; |
} |
for (si=me->bss_sections;si;si=si->next) |
{ |
if (si->sec_num==num) |
return si; |
} |
return (meos_section_info*)0; |
} |
void build_reloc(me_info* me) |
{ |
int flag; |
Elf32_Rel *rel, *rel_, *rel_end; |
Section *sr; |
meos_section_info* s; |
meos_section_info* ss; |
s=me->code_sections; |
rel=0; |
rel_end=0; |
flag=0; |
for(;;) |
{ |
sr=me->s1->sections[s->sec_num]->reloc; |
if (sr) |
{ |
*/ |
typedef struct { |
char magic[8]; |
int version; |
int entry_point; |
int image_size; |
int memory_size; |
int stack; |
int params; |
int argv; |
} IMAGE_MEOS_FILE_HEADER,*PIMAGE_MEOS_FILE_HEADER; |
typedef struct _meos_section_info{ |
int sh_addr; |
void* data; |
int data_size; |
int sec_num; |
struct _meos_section_info* next; |
} meos_section_info; |
typedef struct { |
TCCState* s1; |
IMAGE_MEOS_FILE_HEADER header; |
meos_section_info* code_sections; |
meos_section_info* data_sections; |
meos_section_info* bss_sections; |
} me_info; |
meos_section_info* findsection(me_info* me,int num) |
{ |
meos_section_info* si; |
for(si=me->code_sections;si;si=si->next) |
{ |
if (si->sec_num==num) |
return si; |
} |
for (si=me->data_sections;si;si=si->next) |
{ |
if (si->sec_num==num) |
return si; |
} |
for (si=me->bss_sections;si;si=si->next) |
{ |
if (si->sec_num==num) |
return si; |
} |
return (meos_section_info*)0; |
} |
void build_reloc(me_info* me) |
{ |
int flag; |
Elf32_Rel *rel, *rel_, *rel_end; |
Section *sr; |
meos_section_info* s; |
meos_section_info* ss; |
s=me->code_sections; |
rel=0; |
rel_end=0; |
flag=0; |
for(;;) |
{ |
sr=me->s1->sections[s->sec_num]->reloc; |
if (sr) |
{ |
rel = (Elf32_Rel *) sr->data; |
rel_end = (Elf32_Rel *) (sr->data + sr->data_offset); |
} |
rel_=rel; |
while (rel_<rel_end){ |
rel=rel_; |
int type = ELF32_R_TYPE(rel->r_info); |
rel_=rel+1; |
rel_end = (Elf32_Rel *) (sr->data + sr->data_offset); |
} |
rel_=rel; |
while (rel_<rel_end){ |
rel=rel_; |
int type = ELF32_R_TYPE(rel->r_info); |
rel_=rel+1; |
if (type != R_386_PC32 && type != R_386_32) |
continue; |
int sym = ELF32_R_SYM(rel->r_info); |
if (sym>symtab_section->data_offset/sizeof(Elf32_Sym)) |
continue; |
Elf32_Sym* esym = ((Elf32_Sym *)symtab_section->data)+sym; |
int sect=esym->st_shndx; |
ss=findsection(me,sect); |
if (ss==0) |
ss=me->bss_sections; |
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-4; |
else if (type==R_386_32) |
*(int*)(rel->r_offset+s->data)+=ss->sh_addr+esym->st_value; |
} |
rel=rel_; |
s=s->next; |
if (s==0) |
{ |
if (flag) break; |
s=me->data_sections; |
if (s==0) break; |
flag=1; |
continue; |
} |
} |
} |
void assign_addresses(me_info* me) |
{ |
int i; |
meos_section_info* si; |
for (i=1;i<me->s1->nb_sections;i++) |
{ |
Section* s=me->s1->sections[i]; |
if (strcmp(".text",s->name)==0) |
{ |
si=tcc_malloc(sizeof(meos_section_info)); |
si->data=s->data; |
si->data_size=s->data_offset; |
si->next=me->code_sections; |
si->sec_num=i; |
me->code_sections=si; |
continue; |
} |
if (strcmp(".data",s->name)==0) |
{ |
si=tcc_malloc(sizeof(meos_section_info)); |
si->data=s->data; |
si->data_size=s->data_offset; |
si->next=me->data_sections; |
si->sec_num=i; |
me->data_sections=si; |
continue; |
} |
if (strcmp(".bss",s->name)==0) |
{ |
si=tcc_malloc(sizeof(meos_section_info)); |
si->data_size=s->data_offset; |
si->next=me->bss_sections; |
si->sec_num=i; |
me->bss_sections=si; |
continue; |
} |
} |
int addr; |
addr=sizeof(IMAGE_MEOS_FILE_HEADER); |
for (si=me->code_sections;si;si=si->next) |
{ |
si->sh_addr=addr; |
addr+=si->data_size; |
} |
for (si=me->data_sections;si;si=si->next) |
{ |
si->sh_addr=addr; |
addr+=si->data_size; |
} |
me->header.image_size=addr; |
for (si=me->bss_sections;si;si=si->next) |
{ |
si->sh_addr=addr; |
addr+=si->data_size; |
} |
addr+=4096; |
addr=(addr+4)&(~3); |
me->header.stack=addr; |
me->header.memory_size=addr; |
build_reloc(me); |
} |
int tcc_find_symbol_me(me_info* me, const char *sym_name) |
{ |
int i; |
int symtab; |
int strtab; |
symtab=0; |
strtab=0; |
for (i=1;i<me->s1->nb_sections;i++) |
{ |
Section* s; |
s=me->s1->sections[i]; |
if (strcmp(s->name,".symtab")==0) |
{ |
symtab=i; |
} |
if (strcmp(s->name,".strtab")==0) |
{ |
strtab=i; |
} |
} |
if (symtab==0 || strtab==0) |
return 0; |
Elf32_Sym* s,*se; |
char* name; |
s=(Elf32_Sym*)me->s1->sections[symtab]->data; |
se=(Elf32_Sym*)(((void*)s)+me->s1->sections[symtab]->data_offset); |
name=(char*)me->s1->sections[strtab]->data; |
while (s<se) |
{ |
if (strcmp(name+s->st_name,sym_name)==0) |
{ |
return s->st_value+findsection(me,s->st_shndx)->sh_addr; |
} |
s++; |
} |
return 0; |
} |
const char* me_magic="MENUET01"; |
int tcc_output_me(TCCState* s1,const char *filename) |
{ |
me_info me; |
int i; |
FILE* f; |
//printf("%d\n",s1->nb_sections); |
memset(&me,0,sizeof(me)); |
me.s1=s1; |
relocate_common_syms(); |
assign_addresses(&me); |
me.header.version=1; |
me.header.entry_point=tcc_find_symbol_me(&me,"start"); |
me.header.params= tcc_find_symbol_me(&me,"__argv"); // <-- |
me.header.argv= tcc_find_symbol_me(&me,"__path"); // <-- |
f=fopen(filename,"wb"); |
for (i=0;i<8;i++) |
me.header.magic[i]=me_magic[i]; |
/*me.header.magic[0]='M';me.header.magic[1]='E'; |
me.header.magic[2]='N';me.header.magic[3]='U'; |
me.header.magic[4]='E';me.header.magic[5]='T'; |
me.header.magic[6]='0';me.header.magic[7]='1';*/ |
fwrite(&me.header,1,sizeof(IMAGE_MEOS_FILE_HEADER),f); |
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); |
fclose(f); |
return 0; |
} |
continue; |
int sym = ELF32_R_SYM(rel->r_info); |
if (sym>symtab_section->data_offset/sizeof(Elf32_Sym)) |
continue; |
Elf32_Sym* esym = ((Elf32_Sym *)symtab_section->data)+sym; |
int sect=esym->st_shndx; |
ss=findsection(me,sect); |
if (ss==0) continue; |
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; |
else if (type==R_386_32) |
*(int*)(rel->r_offset+s->data)+=ss->sh_addr+esym->st_value; |
} |
rel=rel_; |
s=s->next; |
if (s==0) |
{ |
if (flag) break; |
s=me->data_sections; |
if (s==0) break; |
flag=1; |
continue; |
} |
} |
} |
void assign_addresses(me_info* me) |
{ |
int i; |
meos_section_info* si; |
for (i=1;i<me->s1->nb_sections;i++) |
{ |
Section* s=me->s1->sections[i]; |
if (strcmp(".text",s->name)==0) |
{ |
si=tcc_malloc(sizeof(meos_section_info)); |
si->data=s->data; |
si->data_size=s->data_offset; |
si->next=me->code_sections; |
si->sec_num=i; |
me->code_sections=si; |
continue; |
} |
if (strcmp(".data",s->name)==0) |
{ |
si=tcc_malloc(sizeof(meos_section_info)); |
si->data=s->data; |
si->data_size=s->data_offset; |
si->next=me->data_sections; |
si->sec_num=i; |
me->data_sections=si; |
continue; |
} |
if (strcmp(".bss",s->name)==0) |
{ |
si=tcc_malloc(sizeof(meos_section_info)); |
si->data_size=s->data_offset; |
si->next=me->bss_sections; |
si->sec_num=i; |
me->bss_sections=si; |
continue; |
} |
} |
int addr; |
addr=sizeof(IMAGE_MEOS_FILE_HEADER); |
for (si=me->code_sections;si;si=si->next) |
{ |
si->sh_addr=addr; |
addr+=si->data_size; |
} |
for (si=me->data_sections;si;si=si->next) |
{ |
si->sh_addr=addr; |
addr+=si->data_size; |
} |
me->header.image_size=addr; |
for (si=me->bss_sections;si;si=si->next) |
{ |
si->sh_addr=addr; |
addr+=si->data_size; |
} |
addr+=4096; |
addr=(addr+4)&(~3); |
me->header.stack=addr; |
me->header.memory_size=addr; |
build_reloc(me); |
} |
int tcc_find_symbol_me(me_info* me, const char *sym_name) |
{ |
int i; |
int symtab; |
int strtab; |
symtab=0; |
strtab=0; |
for (i=1;i<me->s1->nb_sections;i++) |
{ |
Section* s; |
s=me->s1->sections[i]; |
if (strcmp(s->name,".symtab")==0) |
{ |
symtab=i; |
} |
if (strcmp(s->name,".strtab")==0) |
{ |
strtab=i; |
} |
} |
if (symtab==0 || strtab==0) |
return 0; |
Elf32_Sym* s,*se; |
char* name; |
s=(Elf32_Sym*)me->s1->sections[symtab]->data; |
se=(Elf32_Sym*)(((void*)s)+me->s1->sections[symtab]->data_offset); |
name=(char*)me->s1->sections[strtab]->data; |
while (s<se) |
{ |
if (strcmp(name+s->st_name,sym_name)==0) |
{ |
return s->st_value+findsection(me,s->st_shndx)->sh_addr; |
} |
s++; |
} |
return 0; |
} |
const char* me_magic="MENUET01"; |
int tcc_output_me(TCCState* s1,const char *filename) |
{ |
me_info me; |
int i; |
FILE* f; |
//printf("%d\n",s1->nb_sections); |
memset(&me,0,sizeof(me)); |
me.s1=s1; |
relocate_common_syms(); |
assign_addresses(&me); |
me.header.entry_point=tcc_find_symbol_me(&me,"start"); |
me.header.params= tcc_find_symbol_me(&me,"__argv"); // <-- |
me.header.argv= tcc_find_symbol_me(&me,"__path"); // <-- |
f=fopen(filename,"wb"); |
for (i=0;i<8;i++) |
me.header.magic[i]=me_magic[i]; |
/*me.header.magic[0]='M';me.header.magic[1]='E'; |
me.header.magic[2]='N';me.header.magic[3]='U'; |
me.header.magic[4]='E';me.header.magic[5]='T'; |
me.header.magic[6]='0';me.header.magic[7]='1';*/ |
fwrite(&me.header,1,sizeof(IMAGE_MEOS_FILE_HEADER),f); |
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); |
fclose(f); |
return 0; |
} |
/programs/develop/metcc/trunk/source/tccpe.c |
---|
1083,7 → 1083,7 |
int f = 0, sym_index; |
char *p, line[120], dllname[40]; |
while (fgets(line, sizeof line, fp)) { |
p = strchr(line, 0); |
//p = strchr(line, 0); |
while (p > line && p[-1] <= ' ') |
--p; |
*p = 0; |
1136,7 → 1136,7 |
{ |
char *ext = strrchr(objfilename, '.'); |
if (NULL == ext) |
ext = strchr(objfilename, 0); |
//ext = strchr(objfilename, 0); |
if (output_type == TCC_OUTPUT_DLL) |
strcpy(ext, ".dll"); |
else |
/programs/develop/metcc/trunk/source/tcctest.c |
---|
138,7 → 138,7 |
void macro_test(void) |
{ |
printf("macro:\n"); |
printf("macro:\n"); |
pf("N=%d\n", N); |
printf("aaa=%d\n", AAA); |
1676,15 → 1676,15 |
{ |
char *str; |
+ |
#if 1 |
pri\ |
-ntf("whitspace:\n"); |
+ntf("whitspace:\n"); |
#endif |
pf("N=%d\n", 2); |
#ifdef CORRECT_CR_HANDLING |
- pri\ |
+ pri\ |
ntf("aaa=%d\n", 3); |
#endif |
@@ -1696,11 +1696,11 @@ |
printf("len1=%d\n", strlen(" |
")); |
#ifdef CORRECT_CR_HANDLING |
- str = " |
+ str = " |
"; |
printf("len1=%d str[0]=%d\n", strlen(str), str[0]); |
#endif |
+ printf("len1=%d\n", strlen(" |
a |
")); |
#endif /* ACCEPT_CR_IN_STRINGS */ |