mirror of
https://github.com/KolibriOS/kolibrios.git
synced 2024-11-23 09:21:23 +03:00
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/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 \
|
||||
|
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 <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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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 <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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
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 "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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) \
|
||||
|
||||
|
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