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:
parent
73fdb3cb47
commit
0b1b135336
@ -26,7 +26,13 @@ STATIC_SRCS:= \
|
|||||||
crt/crt1.c \
|
crt/crt1.c \
|
||||||
crt/crt2.c \
|
crt/crt2.c \
|
||||||
crt/chkstk.S \
|
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
|
pe/crtloader.c
|
||||||
|
|
||||||
LIBDLL_SRCS:= \
|
LIBDLL_SRCS:= \
|
||||||
@ -39,21 +45,16 @@ LIBDLL_SRCS:= \
|
|||||||
|
|
||||||
LIBCDLL_SRCS:= \
|
LIBCDLL_SRCS:= \
|
||||||
crt/crtdll.c \
|
crt/crtdll.c \
|
||||||
|
crt/crt2.c \
|
||||||
crt/pseudo-reloc.c \
|
crt/pseudo-reloc.c \
|
||||||
crt/chkstk.S \
|
crt/chkstk.S \
|
||||||
crt/exit.S \
|
crt/exit.S \
|
||||||
pe/loader.c
|
pe/loader.c
|
||||||
|
|
||||||
LIBCRT_SRCS:= \
|
|
||||||
crt/start.S \
|
|
||||||
crt/chkstk.S \
|
|
||||||
crt/crt3.c \
|
|
||||||
crt/pseudo-reloc.c \
|
|
||||||
pe/crtloader.c
|
|
||||||
|
|
||||||
CORE_SRCS:= \
|
CORE_SRCS:= \
|
||||||
argz/buf_findstr.c \
|
argz/buf_findstr.c \
|
||||||
argz/envz_get.c \
|
argz/envz_get.c \
|
||||||
|
crt/console.asm \
|
||||||
crt/emutls.c \
|
crt/emutls.c \
|
||||||
crt/thread.S \
|
crt/thread.S \
|
||||||
crt/tls.S \
|
crt/tls.S \
|
||||||
@ -119,6 +120,7 @@ CORE_SRCS:= \
|
|||||||
signal/signal.c \
|
signal/signal.c \
|
||||||
sys/access.c \
|
sys/access.c \
|
||||||
sys/close.c \
|
sys/close.c \
|
||||||
|
sys/conio.c \
|
||||||
sys/create.c \
|
sys/create.c \
|
||||||
sys/errno.c \
|
sys/errno.c \
|
||||||
sys/finfo.c \
|
sys/finfo.c \
|
||||||
|
271
contrib/sdk/sources/newlib/libc/crt/console.asm
Normal file
271
contrib/sdk/sources/newlib/libc/crt/console.asm
Normal 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
|
@ -19,39 +19,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/kos_io.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
|
struct app_hdr
|
||||||
{
|
{
|
||||||
char banner[8];
|
char banner[8];
|
||||||
@ -64,64 +31,171 @@ struct app_hdr
|
|||||||
char *path;
|
char *path;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*ctp)();
|
extern int main (int, char **, char **);
|
||||||
static void __do_global_ctors ()
|
|
||||||
|
/* 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__;
|
return NULL;
|
||||||
int *c = &__CTOR_LIST__;
|
|
||||||
c++;
|
|
||||||
while (*c)
|
|
||||||
{
|
|
||||||
ctp d = (ctp)*c;
|
|
||||||
(d)();
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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))
|
void __attribute__((noreturn))
|
||||||
__crt_startup (void)
|
__crt_startup (void)
|
||||||
{
|
{
|
||||||
int nRet;
|
struct app_hdr *header = NULL;
|
||||||
struct app_hdr *header;
|
int retval = 0;
|
||||||
|
|
||||||
|
char **argv;
|
||||||
|
int argc;
|
||||||
|
|
||||||
|
memset(_tls_map, 0xFF, 32*4);
|
||||||
|
_tls_map[0] = 0xE0;
|
||||||
|
init_reent();
|
||||||
|
init_stdio();
|
||||||
|
|
||||||
|
|
||||||
init_global_reent();
|
if( header->cmdline[0] != 0)
|
||||||
|
|
||||||
/*
|
|
||||||
* 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)
|
|
||||||
{
|
{
|
||||||
_argc = 2;
|
argc = split_cmdline(header->cmdline, NULL) + 1;
|
||||||
arg[1] = &__cmdline[0];
|
argv = alloca((argc+1)*sizeof(char*));
|
||||||
} else _argc = 1;
|
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;
|
||||||
|
|
||||||
/*
|
retval = main(argc, argv, NULL);
|
||||||
* Sets the default file mode.
|
done:
|
||||||
* If _CRT_fmode is set, also set mode for stdin, stdout
|
exit (retval);
|
||||||
* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
void init_reent();
|
void init_reent();
|
||||||
|
|
||||||
|
void _exit(int __status) __attribute__((noreturn));
|
||||||
|
|
||||||
void __attribute__((noreturn))
|
void __attribute__((noreturn))
|
||||||
__thread_startup (int (*entry)(void*), void *param,
|
__thread_startup (int (*entry)(void*), void *param,
|
||||||
void *stacklow, void *stackhigh)
|
void *stacklow, void *stackhigh)
|
||||||
|
@ -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
|
|
||||||
|
|
||||||
|
|
@ -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 <_ansi.h>
|
||||||
#include <reent.h>
|
#include <reent.h>
|
||||||
@ -38,26 +48,6 @@ int __appenv_size;
|
|||||||
|
|
||||||
extern char _tls_map[128];
|
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)
|
char * __libc_getenv(const char *name)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -192,6 +182,7 @@ libc_crt_startup (void *libc_base)
|
|||||||
_tls_map[0] = 0xE0;
|
_tls_map[0] = 0xE0;
|
||||||
init_reent();
|
init_reent();
|
||||||
init_stdio();
|
init_stdio();
|
||||||
|
__do_global_ctors();
|
||||||
|
|
||||||
// __appenv = load_file("/sys/system.env", &__appenv_size);
|
// __appenv = load_file("/sys/system.env", &__appenv_size);
|
||||||
|
|
||||||
@ -221,4 +212,3 @@ done:
|
|||||||
exit (retval);
|
exit (retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,16 +1,106 @@
|
|||||||
#ifndef __LBSYNC_H__
|
#ifndef __LBSYNC_H__
|
||||||
#define __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
|
typedef struct
|
||||||
{
|
{
|
||||||
volatile int lock;
|
volatile int lock;
|
||||||
unsigned int handle;
|
int handle;
|
||||||
}mutex_t;
|
}mutex_t;
|
||||||
|
|
||||||
int __fastcall mutex_init(mutex_t *mutex);
|
static inline int mutex_init(mutex_t *mutex)
|
||||||
int __fastcall mutex_destroy(mutex_t *mutex);
|
{
|
||||||
void __fastcall mutex_lock(mutex_t *mutex);
|
int handle;
|
||||||
int __fastcall mutex_trylock (mutex_t *mutex);
|
|
||||||
void __fastcall mutex_unlock(mutex_t *mutex);
|
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
|
#endif
|
||||||
|
301
contrib/sdk/sources/newlib/libc/proc32.inc
Normal file
301
contrib/sdk/sources/newlib/libc/proc32.inc
Normal 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 }
|
@ -22,6 +22,8 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "local.h"
|
#include "local.h"
|
||||||
|
|
||||||
|
int __gui_mode;
|
||||||
|
|
||||||
int
|
int
|
||||||
_DEFUN(_printf_r, (ptr, fmt),
|
_DEFUN(_printf_r, (ptr, fmt),
|
||||||
struct _reent *ptr _AND
|
struct _reent *ptr _AND
|
||||||
@ -55,3 +57,11 @@ _DEFUN(printf, (fmt),
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif /* ! _REENT_ONLY */
|
#endif /* ! _REENT_ONLY */
|
||||||
|
|
||||||
|
extern int __gui_mode;
|
||||||
|
|
||||||
|
extern void __attribute__ ((constructor)) __init_conio();
|
||||||
|
static void __attribute__ ((constructor)) init_printf()
|
||||||
|
{
|
||||||
|
__gui_mode = (int)&__init_conio;
|
||||||
|
}
|
||||||
|
@ -139,3 +139,12 @@ _DEFUN(puts, (s),
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern int __gui_mode;
|
||||||
|
|
||||||
|
extern void __attribute__ ((constructor)) __init_conio();
|
||||||
|
static void __attribute__ ((constructor)) init_puts()
|
||||||
|
{
|
||||||
|
__gui_mode = (int)&__init_conio;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -550,14 +550,14 @@ __LOCK_INIT_RECURSIVE(static, malloc_global_mutex);
|
|||||||
|
|
||||||
#define CORRUPTION_ERROR_ACTION(m) \
|
#define CORRUPTION_ERROR_ACTION(m) \
|
||||||
do { \
|
do { \
|
||||||
printf("%s malloc heap corrupted\n",__FUNCTION__); \
|
/*printf("%s malloc heap corrupted\n",__FUNCTION__); */\
|
||||||
__asm__("int3"); \
|
__asm__("int3"); \
|
||||||
}while(0) \
|
}while(0) \
|
||||||
|
|
||||||
|
|
||||||
#define USAGE_ERROR_ACTION(m, p) \
|
#define USAGE_ERROR_ACTION(m, p) \
|
||||||
do { \
|
do { \
|
||||||
printf("%s malloc heap corrupted\n",__FUNCTION__); \
|
/*printf("%s malloc heap corrupted\n",__FUNCTION__); */\
|
||||||
__asm__("int3"); \
|
__asm__("int3"); \
|
||||||
}while(0) \
|
}while(0) \
|
||||||
|
|
||||||
|
43
contrib/sdk/sources/newlib/libc/sys/conio.c
Normal file
43
contrib/sdk/sources/newlib/libc/sys/conio.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
118
contrib/sdk/sources/newlib/static.lds
Normal file
118
contrib/sdk/sources/newlib/static.lds
Normal 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user