newlib: 1)native console support for printf.c() and puts.c()

2)static libc and linking against static libraries

git-svn-id: svn://kolibrios.org@6068 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2016-01-18 02:22:44 +00:00
parent 73fdb3cb47
commit 0b1b135336
13 changed files with 1028 additions and 142 deletions

View File

@ -26,7 +26,13 @@ STATIC_SRCS:= \
crt/crt1.c \
crt/crt2.c \
crt/chkstk.S \
crt/exit.S \
crt/exit.S
LIBCRT_SRCS:= \
crt/start.S \
crt/crt3.c \
crt/chkstk.S \
crt/pseudo-reloc.c \
pe/crtloader.c
LIBDLL_SRCS:= \
@ -39,21 +45,16 @@ LIBDLL_SRCS:= \
LIBCDLL_SRCS:= \
crt/crtdll.c \
crt/crt2.c \
crt/pseudo-reloc.c \
crt/chkstk.S \
crt/exit.S \
pe/loader.c
LIBCRT_SRCS:= \
crt/start.S \
crt/chkstk.S \
crt/crt3.c \
crt/pseudo-reloc.c \
pe/crtloader.c
CORE_SRCS:= \
argz/buf_findstr.c \
argz/envz_get.c \
crt/console.asm \
crt/emutls.c \
crt/thread.S \
crt/tls.S \
@ -119,6 +120,7 @@ CORE_SRCS:= \
signal/signal.c \
sys/access.c \
sys/close.c \
sys/conio.c \
sys/create.c \
sys/errno.c \
sys/finfo.c \

View File

@ -0,0 +1,271 @@
include '../proc32.inc'
format MS COFF
public _load_libconsole
public _con_init@20
public _con_exit@4
public _con_get_flags
public _con_set_flags@4
public _con_cls
public _con_write_string@8
section '.text' align 16
;void* __fastcall getprocaddr(export, name)
align 4
getprocaddress:
push esi
push edi
xor eax, eax
test ecx, ecx ; If hlib = 0 then goto .end
jz .end
.next:
cmp [ecx], dword 0 ; If end of export table then goto .end
jz .end
xor eax, eax
mov esi, [ecx]
mov edi, edx ; name
.next_:
lodsb
scasb
jne .fail
or al, al
jnz .next_
jmp .ok
.fail:
add ecx, 8
jmp .next
.ok:
mov eax, [ecx + 4] ; return address
.end:
pop edi
pop esi
ret
;void fastcall dll_link(export, import)
align 4
dll_link:
push esi
push ecx
mov esi, edx
test esi, esi
jz .done
.next:
mov edx, [esi]
test edx, edx
jz .done
mov ecx, [esp]
call getprocaddress
test eax, eax
jz .done
mov [esi], eax
add esi, 4
jmp .next
.done:
pop ecx
pop esi
ret
align 4
dll_load:
push ebp
push ebx
push esi
push edi
mov ebp, [esp+20]
.next_lib:
mov edx, [ebp]
test edx, edx
jz .exit
mov esi, [ebp+4]
mov edi, s_libdir.fname
@@:
lodsb
stosb
test al, al
jnz @b
mov eax, 68
mov ebx, 19
mov ecx, s_libdir
int 0x40
test eax, eax
jz .fail
mov ecx, eax
call dll_link
mov eax, [ecx]
cmp dword[eax], 'lib_'
jnz @f
mov esi, [ecx+4]
pushad
mov eax, mem.Alloc
mov ebx, mem.Free
mov ecx, mem.ReAlloc
mov edx, dll_load
call esi
popad
@@:
add ebp, 8
jmp .next_lib
.exit:
pop edi
pop esi
pop ebx
pop ebp
xor eax, eax
ret 4
.fail:
pop edi
pop esi
pop ebx
pop ebp
inc eax
ret 4
align 4
_load_libconsole:
push ebx
mov eax, 40
mov ebx, 1 shl 8
int 0x40
pop ebx
push @IMPORT
call dll_load
test eax, eax
jnz .fail
push 1
call [con_start]
xor eax, eax
.fail:
ret
align 4
_con_init@20:
jmp [con_init]
align 4
_con_exit@4:
jmp [con_exit]
align 4
_con_write_string@8:
jmp [con_write_string]
_con_get_flags:
_con_set_flags@4:
_con_cls:
ret
proc mem.Alloc, size
push ebx ecx
mov ecx, [size]
mov eax, 68
mov ebx, 12
int 0x40
pop ecx ebx
ret
endp
;-----------------------------------------------------------------------------
proc mem.ReAlloc, mptr, size
push ebx ecx edx
mov ecx, [size]
test ecx, ecx
jz @f
@@:
mov edx, [mptr]
test edx, edx
jz @f
@@:
mov eax, 68
mov ebx, 20
int 0x40
test eax, eax
jz @f
@@:
pop edx ecx ebx
ret
endp
;-----------------------------------------------------------------------------
proc mem.Free, mptr
push ebx ecx
mov ecx,[mptr]
test ecx,ecx
jz @f
@@:
mov eax, 68
mov ebx, 13
int 0x40
pop ecx ebx
ret
endp
;section '.ctors' align 4
;align 4
;dd _load_libconsole
section '.data' align 16
; -------------------------
macro library [lname,fname]
{
forward
dd __#lname#_library_table__,__#lname#_library_name__
common
dd 0
forward
align 4
__#lname#_library_name__ db fname,0
}
macro import lname,[name,sname]
{
common
align 4
__#lname#_library_table__:
forward
if used name
name dd __#name#_import_name__
end if
common
dd 0
forward
if used name
align 4
__#name#_import_name__ db sname,0
end if
}
align 4
@IMPORT:
library console, 'console.obj'
import console, \
con_start, 'START', \
con_init, 'con_init', \
con_exit, 'con_exit', \
con_gets, 'con_gets', \
con_cls, 'con_cls', \
con_getch2, 'con_getch2', \
con_set_cursor_pos, 'con_set_cursor_pos',\
con_write_string, 'con_write_string',\
con_get_flags, 'con_get_flags', \
con_set_flags, 'con_set_flags'
s_libdir:
db '/sys/lib/'
.fname rb 32

View File

@ -19,39 +19,6 @@
#include <stdio.h>
#include <sys/kos_io.h>
#include "cpu_features.h"
/* NOTE: The code for initializing the _argv, _argc, and environ variables
* has been moved to a separate .c file which is included in both
* crt1.c and dllcrt1.c. This means changes in the code don't have to
* be manually synchronized, but it does lead to this not-generally-
* a-good-idea use of include. */
extern char __cmdline[];
extern char __pgmname[];
extern int main (int, char **, char **);
int _errno;
int _fmode;
int _argc;
char **_argv;
static char *arg[2];
void _exit(int __status) __attribute__((noreturn));
char * __libc_getenv(const char *name)
{
return NULL;
}
void __main (){};
struct app_hdr
{
char banner[8];
@ -64,64 +31,171 @@ struct app_hdr
char *path;
};
typedef void (*ctp)();
static void __do_global_ctors ()
extern int main (int, char **, char **);
/* NOTE: The code for initializing the _argv, _argc, and environ variables
* has been moved to a separate .c file which is included in both
* crt1.c and dllcrt1.c. This means changes in the code don't have to
* be manually synchronized, but it does lead to this not-generally-
* a-good-idea use of include. */
char* __appenv;
int __appenv_size;
extern char _tls_map[128];
char * __libc_getenv(const char *name)
{
extern int __CTOR_LIST__;
int *c = &__CTOR_LIST__;
c++;
while (*c)
{
ctp d = (ctp)*c;
(d)();
c++;
}
return NULL;
}
static int split_cmdline(char *cmdline, char **argv)
{
enum quote_state
{
QUOTE_NONE, /* no " active in current parm */
QUOTE_DELIMITER, /* " was first char and must be last */
QUOTE_STARTED /* " was seen, look for a match */
};
enum quote_state state;
unsigned int argc;
char *p = cmdline;
char *new_arg, *start;
argc = 0;
for(;;)
{
/* skip over spaces and tabs */
if ( *p )
{
while (*p == ' ' || *p == '\t')
++p;
}
if (*p == '\0')
break;
state = QUOTE_NONE;
if( *p == '\"' )
{
p++;
state = QUOTE_DELIMITER;
}
new_arg = start = p;
for (;;)
{
if( *p == '\"' )
{
p++;
if( state == QUOTE_NONE )
{
state = QUOTE_STARTED;
}
else
{
state = QUOTE_NONE;
}
continue;
}
if( *p == ' ' || *p == '\t' )
{
if( state == QUOTE_NONE )
{
break;
}
}
if( *p == '\0' )
break;
if( *p == '\\' )
{
if( p[1] == '\"' )
{
++p;
if( p[-2] == '\\' )
{
continue;
}
}
}
if( argv )
{
*(new_arg++) = *p;
}
++p;
};
if( argv )
{
argv[ argc ] = start;
++argc;
/*
The *new = '\0' is req'd in case there was a \" to "
translation. It must be after the *p check against
'\0' because new and p could point to the same char
in which case the scan would be terminated too soon.
*/
if( *p == '\0' )
{
*new_arg = '\0';
break;
}
*new_arg = '\0';
++p;
}
else
{
++argc;
if( *p == '\0' )
{
break;
}
++p;
}
}
return argc;
};
void __attribute__((noreturn))
__crt_startup (void)
{
int nRet;
struct app_hdr *header;
struct app_hdr *header = NULL;
int retval = 0;
char **argv;
int argc;
memset(_tls_map, 0xFF, 32*4);
_tls_map[0] = 0xE0;
init_reent();
init_stdio();
init_global_reent();
/*
* Initialize floating point unit.
*/
__cpu_features_init (); /* Do we have SSE, etc.*/
// _fpreset (); /* Supplied by the runtime library. */
__do_global_ctors();
arg[0] = &__pgmname[0];
if( __cmdline[0] != 0)
if( header->cmdline[0] != 0)
{
_argc = 2;
arg[1] = &__cmdline[0];
} else _argc = 1;
argc = split_cmdline(header->cmdline, NULL) + 1;
argv = alloca((argc+1)*sizeof(char*));
argv[0] = header->path;
_argv = arg;
split_cmdline(header->cmdline, argv + 1);
}
else
{
argc = 1;
argv = alloca((argc+1)*sizeof(char*));
argv[0] = header->path;
}
argv[argc] = NULL;
/*
* Sets the default file mode.
* If _CRT_fmode is set, also set mode for stdin, stdout
* and stderr, as well
* NOTE: DLLs don't do this because that would be rude!
*/
// _mingw32_init_fmode ();
nRet = main (_argc, _argv, NULL);
/*
* Perform exit processing for the C library. This means
* flushing output and calling 'atexit' registered functions.
*/
exit (nRet);
retval = main(argc, argv, NULL);
done:
exit (retval);
}

View File

@ -2,6 +2,8 @@
void init_reent();
void _exit(int __status) __attribute__((noreturn));
void __attribute__((noreturn))
__thread_startup (int (*entry)(void*), void *param,
void *stacklow, void *stackhigh)

View File

@ -1,24 +0,0 @@
.global __start
.global ___main
.global _DllMainCRTStartup
.section .init
.def __start; .scl 2; .type 32; .endef
.def _DllMainCRTStartup; .scl 2; .type 32; .endef
.align 4
__start:
_DllMainCRTStartup:
call __pei386_runtime_relocator
jmp _main
.align 4
___main:
ret

View File

@ -1,3 +1,13 @@
/*
* crtdll.c
* This file has no copyright assigned and is placed in the Public Domain.
* This file is a part of the mingw-runtime package.
* No warranty is given; refer to the file DISCLAIMER within the package.
*
* Source code for the shared libc startup proceedures. This code is compiled
* to make libc.dll, which should be located in the library path.
*
*/
#include <_ansi.h>
#include <reent.h>
@ -38,26 +48,6 @@ int __appenv_size;
extern char _tls_map[128];
void __attribute__((noreturn))
__thread_startup (int (*entry)(void*), void *param,
void *stacklow, void *stackhigh)
{
int retval;
// asm volatile ( "xchgw %bx, %bx");
__asm__ __volatile__( // save stack limits
"movl %0, %%fs:8 \n\t" // use TLS
"movl %1, %%fs:12 \n\t"
::"r"(stacklow), "r"(stackhigh));
init_reent(); // initialize thread reentry structure
retval = entry(param); // call user thread function
_exit(retval);
};
char * __libc_getenv(const char *name)
{
return NULL;
@ -192,6 +182,7 @@ libc_crt_startup (void *libc_base)
_tls_map[0] = 0xE0;
init_reent();
init_stdio();
__do_global_ctors();
// __appenv = load_file("/sys/system.env", &__appenv_size);
@ -221,4 +212,3 @@ done:
exit (retval);
}

View File

@ -1,16 +1,106 @@
#ifndef __LBSYNC_H__
#define __LBSYNC_H__
#define FUTEX_INIT 0
#define FUTEX_DESTROY 1
#define FUTEX_WAIT 2
#define FUTEX_WAKE 3
#define exchange_acquire(ptr, new) \
__atomic_exchange_4((ptr), (new), __ATOMIC_ACQUIRE)
#define exchange_release(ptr, new) \
__atomic_exchange_4((ptr), (new), __ATOMIC_RELEASE)
typedef struct
{
volatile int lock;
unsigned int handle;
int handle;
}mutex_t;
int __fastcall mutex_init(mutex_t *mutex);
int __fastcall mutex_destroy(mutex_t *mutex);
void __fastcall mutex_lock(mutex_t *mutex);
int __fastcall mutex_trylock (mutex_t *mutex);
void __fastcall mutex_unlock(mutex_t *mutex);
static inline int mutex_init(mutex_t *mutex)
{
int handle;
mutex->lock = 0;
asm volatile(
"int $0x40\t"
:"=a"(handle)
:"a"(77),"b"(FUTEX_INIT),"c"(mutex));
mutex->handle = handle;
return handle;
};
static inline int mutex_destroy(mutex_t *mutex)
{
int retval;
asm volatile(
"int $0x40\t"
:"=a"(retval)
:"a"(77),"b"(FUTEX_DESTROY),"c"(mutex->handle));
return retval;
};
static inline void mutex_lock(mutex_t *mutex)
{
int tmp;
if( __sync_fetch_and_add(&mutex->lock, 1) == 0)
return;
while (exchange_acquire (&mutex->lock, 2) != 0)
{
asm volatile(
"int $0x40\t"
:"=a"(tmp)
:"a"(77),"b"(FUTEX_WAIT),
"c"(mutex->handle),"d"(2),"S"(0));
}
};
static inline void mutex_lock_timeout(mutex_t *mutex, int timeout)
{
int tmp;
if( __sync_fetch_and_add(&mutex->lock, 1) == 0)
return;
while (exchange_acquire (&mutex->lock, 2) != 0)
{
asm volatile(
"int $0x40\t"
:"=a"(tmp)
:"a"(77),"b"(FUTEX_WAIT),
"c"(mutex->handle),"d"(2),"S"(timeout));
}
};
static inline int mutex_trylock (mutex_t *mutex)
{
int zero = 0;
return __atomic_compare_exchange_4(&mutex->lock, &zero, 1,0,__ATOMIC_ACQUIRE,__ATOMIC_RELAXED);
};
static inline void mutex_unlock(mutex_t *mutex)
{
int prev;
prev = exchange_release (&mutex->lock, 0);
if (prev != 1)
{
asm volatile(
"int $0x40\t"
:"=a"(prev)
:"a"(77),"b"(FUTEX_WAKE),
"c"(mutex->handle),"d"(1));
};
};
#endif

View File

@ -0,0 +1,301 @@
; Macroinstructions for defining and calling procedures
macro stdcall proc,[arg] ; directly call STDCALL procedure
{ common
if ~ arg eq
reverse
pushd arg
common
end if
call proc }
macro invoke proc,[arg] ; indirectly call STDCALL procedure
{ common
if ~ arg eq
reverse
pushd arg
common
end if
call [proc] }
macro ccall proc,[arg] ; directly call CDECL procedure
{ common
size@ccall = 0
if ~ arg eq
reverse
pushd arg
size@ccall = size@ccall+4
common
end if
call proc
if size@ccall
add esp,size@ccall
end if }
macro cinvoke proc,[arg] ; indirectly call CDECL procedure
{ common
size@ccall = 0
if ~ arg eq
reverse
pushd arg
size@ccall = size@ccall+4
common
end if
call [proc]
if size@ccall
add esp,size@ccall
end if }
macro proc [args] ; define procedure
{ common
match name params, args>
\{ define@proc name,<params \} }
prologue@proc equ prologuedef
macro prologuedef procname,flag,parmbytes,localbytes,reglist
{ local loc
loc = (localbytes+3) and (not 3)
parmbase@proc equ ebp+8
localbase@proc equ ebp-loc
if parmbytes | localbytes
push ebp
mov ebp,esp
if localbytes
sub esp,loc
end if
end if
irps reg, reglist \{ push reg \} }
epilogue@proc equ epiloguedef
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
{ irps reg, reglist \{ reverse pop reg \}
if parmbytes | localbytes
leave
end if
if flag and 10000b
retn
else
retn parmbytes
end if }
close@proc equ
macro define@proc name,statement
{ local params,flag,regs,parmbytes,localbytes,current
if used name
name:
match =stdcall args, statement \{ params equ args
flag = 11b \}
match =stdcall, statement \{ params equ
flag = 11b \}
match =c args, statement \{ params equ args
flag = 10001b \}
match =c, statement \{ params equ
flag = 10001b \}
match =params, params \{ params equ statement
flag = 0 \}
match =uses reglist=,args, params \{ regs equ reglist
params equ args \}
match =regs =uses reglist, regs params \{ regs equ reglist
params equ \}
match =regs, regs \{ regs equ \}
match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \}
virtual at parmbase@proc
match =,args, params \{ defargs@proc args \}
match =args@proc args, args@proc params \{ defargs@proc args \}
parmbytes = $-(parmbase@proc)
end virtual
name # % = parmbytes/4
all@vars equ
current = 0
macro locals
\{ virtual at localbase@proc+current
macro label def \\{ match . type,def> \\\{ deflocal@proc .,label,<type \\\} \\}
struc db [val] \\{ \common deflocal@proc .,db,val \\}
struc du [val] \\{ \common deflocal@proc .,du,val \\}
struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
macro endl
\{ purge label
restruc db,du,dw,dp,dd,dt,dq
restruc rb,rw,rp,rd,rt,rq
current = $-(localbase@proc)
end virtual \}
macro ret operand
\{ match any, operand \\{ retn operand \\}
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs> \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
macro finish@proc
\{ localbytes = current
match close:reglist, close@proc:<regs> \\{ close name,flag,parmbytes,localbytes,reglist \\}
end if \} }
macro defargs@proc [arg]
{ common
if ~ arg eq
forward
local ..arg,current@arg
match argname:type, arg
\{ current@arg equ argname
label ..arg type
argname equ ..arg
if qqword eq type
dd ?,?,?,?,?,?,?,?
else if dqword eq type
dd ?,?,?,?
else if tbyte eq type
dd ?,?,?
else if qword eq type | pword eq type
dd ?,?
else
dd ?
end if \}
match =current@arg,current@arg
\{ current@arg equ arg
arg equ ..arg
..arg dd ? \}
common
args@proc equ current@arg
forward
restore current@arg
common
end if }
macro deflocal@proc name,def,[val] { name def val }
macro deflocal@proc name,def,[val]
{ common
match vars, all@vars \{ all@vars equ all@vars, \}
all@vars equ all@vars name
forward
local ..var,..tmp
..var def val
match =?, val \{ ..tmp equ \}
match any =?, val \{ ..tmp equ \}
match any (=?), val \{ ..tmp equ \}
match =label, def \{ ..tmp equ \}
match tmp : value, ..tmp : val
\{ tmp: end virtual
initlocal@proc ..var,def value
virtual at tmp\}
common
match first rest, ..var, \{ name equ first \} }
struc label type { label . type }
macro initlocal@proc name,def
{ virtual at name
def
size@initlocal = $ - name
end virtual
position@initlocal = 0
while size@initlocal > position@initlocal
virtual at name
def
if size@initlocal - position@initlocal < 2
current@initlocal = 1
load byte@initlocal byte from name+position@initlocal
else if size@initlocal - position@initlocal < 4
current@initlocal = 2
load word@initlocal word from name+position@initlocal
else
current@initlocal = 4
load dword@initlocal dword from name+position@initlocal
end if
end virtual
if current@initlocal = 1
mov byte [name+position@initlocal],byte@initlocal
else if current@initlocal = 2
mov word [name+position@initlocal],word@initlocal
else
mov dword [name+position@initlocal],dword@initlocal
end if
position@initlocal = position@initlocal + current@initlocal
end while }
macro endp
{ purge ret,locals,endl
finish@proc
purge finish@proc
restore regs@proc
match all,args@proc \{ restore all \}
restore args@proc
match all,all@vars \{ restore all \} }
macro local [var]
{ common
locals
forward done@local equ
match varname[count]:vartype, var
\{ match =BYTE, vartype \\{ varname rb count
restore done@local \\}
match =WORD, vartype \\{ varname rw count
restore done@local \\}
match =DWORD, vartype \\{ varname rd count
restore done@local \\}
match =PWORD, vartype \\{ varname rp count
restore done@local \\}
match =QWORD, vartype \\{ varname rq count
restore done@local \\}
match =TBYTE, vartype \\{ varname rt count
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
rq count*2
restore done@local \\}
match =QQWORD, vartype \\{ label varname qqword
rq count*4
restore done@local \\}
match =XWORD, vartype \\{ label varname xword
rq count*2
restore done@local \\}
match =YWORD, vartype \\{ label varname yword
rq count*4
restore done@local \\}
match , done@local \\{ virtual
varname vartype
end virtual
rb count*sizeof.\#vartype
restore done@local \\} \}
match :varname:vartype, done@local:var
\{ match =BYTE, vartype \\{ varname db ?
restore done@local \\}
match =WORD, vartype \\{ varname dw ?
restore done@local \\}
match =DWORD, vartype \\{ varname dd ?
restore done@local \\}
match =PWORD, vartype \\{ varname dp ?
restore done@local \\}
match =QWORD, vartype \\{ varname dq ?
restore done@local \\}
match =TBYTE, vartype \\{ varname dt ?
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
dq ?,?
restore done@local \\}
match =QQWORD, vartype \\{ label varname qqword
dq ?,?,?,?
restore done@local \\}
match =XWORD, vartype \\{ label varname xword
dq ?,?
restore done@local \\}
match =YWORD, vartype \\{ label varname yword
dq ?,?,?,?
restore done@local \\}
match , done@local \\{ varname vartype
restore done@local \\} \}
match ,done@local
\{ var
restore done@local \}
common
endl }

View File

@ -22,6 +22,8 @@
#include <stdarg.h>
#include "local.h"
int __gui_mode;
int
_DEFUN(_printf_r, (ptr, fmt),
struct _reent *ptr _AND
@ -55,3 +57,11 @@ _DEFUN(printf, (fmt),
}
#endif /* ! _REENT_ONLY */
extern int __gui_mode;
extern void __attribute__ ((constructor)) __init_conio();
static void __attribute__ ((constructor)) init_printf()
{
__gui_mode = (int)&__init_conio;
}

View File

@ -139,3 +139,12 @@ _DEFUN(puts, (s),
}
#endif
extern int __gui_mode;
extern void __attribute__ ((constructor)) __init_conio();
static void __attribute__ ((constructor)) init_puts()
{
__gui_mode = (int)&__init_conio;
}

View File

@ -550,14 +550,14 @@ __LOCK_INIT_RECURSIVE(static, malloc_global_mutex);
#define CORRUPTION_ERROR_ACTION(m) \
do { \
printf("%s malloc heap corrupted\n",__FUNCTION__); \
/*printf("%s malloc heap corrupted\n",__FUNCTION__); */\
__asm__("int3"); \
}while(0) \
#define USAGE_ERROR_ACTION(m, p) \
do { \
printf("%s malloc heap corrupted\n",__FUNCTION__); \
/*printf("%s malloc heap corrupted\n",__FUNCTION__); */\
__asm__("int3"); \
}while(0) \

View File

@ -0,0 +1,43 @@
#include <_ansi.h>
#include <sys/unistd.h>
#include "io.h"
void load_libconsole();
void __stdcall con_init(unsigned w_w, unsigned w_h, unsigned s_w, unsigned s_h, const char* t);
void __stdcall con_exit(char bCloseWindow);
unsigned __stdcall con_get_flags(void);
unsigned __stdcall con_set_flags(unsigned new_flags);
void __stdcall con_cls(void);
void __stdcall con_write_string(const char* string, unsigned length);
int __gui_mode;
static int console_write(const char *path, const void *buff,
size_t offset, size_t count, size_t *writes)
{
con_write_string(buff, count);
*writes = count;
return count;
};
void __attribute__ ((constructor)) __init_conio()
{
__io_handle *ioh;
load_libconsole();
con_init(80, 25, 80, 250, "Console application");
ioh = &__io_tab[STDOUT_FILENO];
ioh->mode = _WRITE|_ISTTY;
ioh->write = &console_write;
};
static void __attribute__ ((destructor)) __fini_conio()
{
con_exit(0);
}

View File

@ -0,0 +1,118 @@
/*OUTPUT_FORMAT("binary")*/
ENTRY(__start)
SECTIONS
{
.text 0x000000:
{
LONG(0x554e454D);
LONG(0x32305445);
LONG(1);
LONG(__start);
LONG(___iend);
LONG(___memsize);
LONG(___stacktop);
LONG(___cmdline);
LONG(___pgmname); /* full path */
LONG(0); /*FIXME tls data */
*(.init)
*(.text)
*(SORT(.text$*))
*(.text.*)
*(.glue_7t)
*(.glue_7)
___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
LONG (-1);*(.ctors); *(.ctor); *(SORT(.ctors.*)); LONG (0);
___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
LONG (-1); *(.dtors); *(.dtor); *(SORT(.dtors.*)); LONG (0);
*(.fini)
/* ??? Why is .gcc_exc here? */
*(.gcc_exc)
PROVIDE (etext = .);
*(.gcc_except_table)
}
.rdata ALIGN(16) :
{
*(.rdata)
*(SORT(.rdata$*))
___RUNTIME_PSEUDO_RELOC_LIST__ = .;
__RUNTIME_PSEUDO_RELOC_LIST__ = .;
*(.rdata_runtime_pseudo_reloc)
___RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
__RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
}
.CRT ALIGN(16) :
{
___crt_xc_start__ = . ;
*(SORT(.CRT$XC*)) /* C initialization */
___crt_xc_end__ = . ;
___crt_xi_start__ = . ;
*(SORT(.CRT$XI*)) /* C++ initialization */
___crt_xi_end__ = . ;
___crt_xl_start__ = . ;
*(SORT(.CRT$XL*)) /* TLS callbacks */
/* ___crt_xl_end__ is defined in the TLS Directory support code */
___crt_xp_start__ = . ;
*(SORT(.CRT$XP*)) /* Pre-termination */
___crt_xp_end__ = . ;
___crt_xt_start__ = . ;
*(SORT(.CRT$XT*)) /* Termination */
___crt_xt_end__ = . ;
}
.data ALIGN(16) :
{
PROVIDE ( __data_start__ = .) ;
*(.data)
*(.data2)
*(SORT(.data$*))
*(.jcr)
__CRT_MT = .;
LONG(0);
PROVIDE ( __data_end__ = .) ;
*(.data_cygwin_nocopy)
___iend = . ;
}
/* .eh_frame BLOCK(16) :
{
PROVIDE (___EH_FRAME_BEGIN__ = .) ;
*(.eh_frame*)
}
*/
bss ALIGN(16):
{
*(.bss)
*(COMMON)
. = ALIGN(16);
___cmdline = .;
. = . + 256;
___pgmname = .;
. = . + 1024 + 16;
___stacktop = .;
___memsize = . ;
}
/DISCARD/ :
{
*(.debug$S)
*(.debug$T)
*(.debug$F)
*(.drectve)
*(.note.GNU-stack)
*(.comment)
*(.eh_frame)
*(.debug_abbrev)
*(.debug_info)
*(.debug_line)
*(.debug_frame)
*(.debug_loc)
*(.debug_pubnames)
*(.debug_aranges)
*(.debug_ranges)
}
}