/programs/develop/libraries/newlib/crt/assert.c |
---|
0,0 → 1,74 |
/* |
FUNCTION |
<<assert>>---macro for debugging diagnostics |
INDEX |
assert |
ANSI_SYNOPSIS |
#include <assert.h> |
void assert(int <[expression]>); |
DESCRIPTION |
Use this macro to embed debuggging diagnostic statements in |
your programs. The argument <[expression]> should be an |
expression which evaluates to true (nonzero) when your program |
is working as you intended. |
When <[expression]> evaluates to false (zero), <<assert>> |
calls <<abort>>, after first printing a message showing what |
failed and where: |
. Assertion failed: <[expression]>, file <[filename]>, line <[lineno]>, function: <[func]> |
If the name of the current function is not known (for example, |
when using a C89 compiler that does not understand __func__), |
the function location is omitted. |
The macro is defined to permit you to turn off all uses of |
<<assert>> at compile time by defining <<NDEBUG>> as a |
preprocessor variable. If you do this, the <<assert>> macro |
expands to |
. (void(0)) |
RETURNS |
<<assert>> does not return a value. |
PORTABILITY |
The <<assert>> macro is required by ANSI, as is the behavior |
when <<NDEBUG>> is defined. |
Supporting OS subroutines required (only if enabled): <<close>>, <<fstat>>, |
<<getpid>>, <<isatty>>, <<kill>>, <<lseek>>, <<read>>, <<sbrk>>, <<write>>. |
*/ |
#include <assert.h> |
#include <stdlib.h> |
#include <stdio.h> |
/* func can be NULL, in which case no function information is given. */ |
void |
_DEFUN (__assert_func, (file, line, func, failedexpr), |
const char *file _AND |
int line _AND |
const char *func _AND |
const char *failedexpr) |
{ |
fiprintf(stderr, |
"assertion \"%s\" failed: file \"%s\", line %d%s%s\n", |
failedexpr, file, line, |
func ? ", function: " : "", func ? func : ""); |
abort(); |
/* NOTREACHED */ |
} |
void |
_DEFUN (_assert, (file, line, failedexpr), |
const char *file _AND |
int line _AND |
const char *failedexpr) |
{ |
__assert_func (file, line, NULL, failedexpr); |
/* NOTREACHED */ |
} |
/programs/develop/libraries/newlib/crt/chkstk.S |
---|
4,7 → 4,6 |
.section .text |
.align 4 |
___chkstk: |
__alloca: |
pushl %ecx /* save temp */ |
27,3 → 26,4 |
int3 #trap to debugger |
.ascii "Stack overflow" |
/programs/develop/libraries/newlib/crt/crt1.c |
---|
16,6 → 16,9 |
#include <stdint.h> |
#include <stdlib.h> |
#include <string.h> |
#include <stdio.h> |
#include <sys/kos_io.h> |
#include "cpu_features.h" |
51,8 → 54,6 |
} |
void __main (){}; |
void init_reent(); |
void __attribute__((noreturn)) |
73,11 → 74,26 |
_exit(retval); |
}; |
struct app_hdr |
{ |
char banner[8]; |
int version; |
int start; |
int iend; |
int memsize; |
int stacktop; |
char *cmdline; |
char *path; |
}; |
void __attribute__((noreturn)) |
__crt_startup (void) |
{ |
int nRet; |
struct app_hdr *header; |
init_reent(); |
/* |
89,12 → 105,12 |
__initPOSIXHandles(); |
__appcwdlen = strrchr(&__pgmname, '/') - &__pgmname + 1; |
__appcwdlen = __appcwdlen > 1023 ? 1023 : __appcwdlen; |
strncpy(__appcwd, &__pgmname, __appcwdlen); |
memcpy(__appcwd, &__pgmname, __appcwdlen); |
__appcwd[__appcwdlen] = 0; |
set_cwd(__appcwd); |
arg[0] = &__pgmname; |
if( __cmdline != 0) |
113,6 → 129,7 |
*/ |
// _mingw32_init_fmode (); |
nRet = main (_argc, _argv, NULL); |
/* |
119,7 → 136,7 |
* Perform exit processing for the C library. This means |
* flushing output and calling 'atexit' registered functions. |
*/ |
_exit (nRet); |
exit (nRet); |
} |
/programs/develop/libraries/newlib/crt/crt_amz.S |
---|
0,0 → 1,15 |
.section .text |
.global __start |
.global ___main |
.align 4 |
__start: |
jmp _main |
.align 4 |
___main: |
ret |
/programs/develop/libraries/newlib/crt/crtdll.c |
---|
0,0 → 1,144 |
#include <_ansi.h> |
#include <reent.h> |
#include <stdint.h> |
#include <stdlib.h> |
#include <string.h> |
#include <stdio.h> |
#include <unistd.h> |
#include <setjmp.h> |
#include <sys/kos_io.h> |
struct app_hdr |
{ |
char banner[8]; |
int version; |
int start; |
int iend; |
int memsize; |
int stacktop; |
char *cmdline; |
char *path; |
}; |
int _argc; |
char **_argv; |
void __fastcall init_loader(void *libc_image); |
void* __fastcall create_image(void *raw); |
int __fastcall link_image(void *img_base); |
void* get_entry_point(void *raw); |
int (*entry)(int, char **, char **); |
void init_reent(); |
jmp_buf loader_env; |
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:4 \n\t" // use TLS |
"movl %1, %%fs:8 \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; |
} |
char __appcwd[1024]; |
int __appcwdlen; |
char* __appenv; |
int __appenv_size; |
void __attribute__((noreturn)) |
crt_startup (void *libc_base, void *obj_base, uint32_t *params) |
{ |
struct app_hdr *header; |
char *arg[2]; |
int len; |
char *p; |
void *my_app; |
int retval = 0; |
// user_free(obj_base); |
init_reent(); |
__initPOSIXHandles(); |
__appenv = load_file("/sys/system.env", &__appenv_size); |
init_loader(libc_base); |
my_app = create_image((void*)(params[0])); |
if( link_image(my_app)==0) |
goto done; |
header = (struct app_hdr*)NULL; |
__appcwdlen = strrchr(header->path, '/') - header->path; |
__appcwdlen = __appcwdlen > 1022 ? 1022 : __appcwdlen; |
memcpy(__appcwd, header->path, __appcwdlen); |
set_cwd(__appcwd); |
#ifdef BRAVE_NEW_WORLD |
len = strlen(header->path); |
p = alloca(len+1); |
memcpy(p, header->path, len); |
p[len]=0; |
arg[0] = p; |
#else |
arg[0] = header->path; |
#endif |
_argc = 1; |
if( header->cmdline != 0) |
{ |
#ifdef BRAVE_NEW_WORLD |
len = strlen(header->cmdline); |
if(len) |
{ |
p = alloca(len+1); |
memcpy(p, header->cmdline, len); |
p[len]=0; |
_argc = 2; |
arg[1] = p; |
}; |
#else |
_argc = 2; |
arg[1] = header->cmdline; |
#endif |
}; |
_argv = arg; |
entry = get_entry_point(my_app); |
// __asm__ __volatile__("int3"); |
retval = entry(_argc, _argv, NULL); |
done: |
exit (retval); |
} |
/programs/develop/libraries/newlib/crt/emutls.c |
---|
0,0 → 1,218 |
/* TLS emulation. |
Copyright (C) 2006, 2008, 2009 Free Software Foundation, Inc. |
Contributed by Jakub Jelinek <jakub@redhat.com>. |
This file is part of GCC. |
GCC is free software; you can redistribute it and/or modify it under |
the terms of the GNU General Public License as published by the Free |
Software Foundation; either version 3, or (at your option) any later |
version. |
GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
WARRANTY; without even the implied warranty of MERCHANTABILITY or |
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
for more details. |
Under Section 7 of GPL version 3, you are granted additional |
permissions described in the GCC Runtime Library Exception, version |
3.1, as published by the Free Software Foundation. |
You should have received a copy of the GNU General Public License and |
a copy of the GCC Runtime Library Exception along with this program; |
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
<http://www.gnu.org/licenses/>. */ |
#include <stdlib.h> |
#include <memory.h> |
#include <malloc.h> |
#include <errno.h> |
#include <gthr.h> |
void *tls_alloc(void); |
void __mutex_lock(volatile int *val); |
static inline void yield(void) |
{ |
__asm__ __volatile__( |
"int $0x40" |
::"a"(68), "b"(1)); |
}; |
int __gthread_once (__gthread_once_t *once, void (*func) (void)) |
{ |
if (once == NULL || func == NULL) |
return EINVAL; |
if (! once->done) |
{ |
if(++once->started == 0) |
{ |
(*func) (); |
once->done = 1; |
} |
else |
{ |
/* Another thread is currently executing the code, so wait for it |
to finish; yield the CPU in the meantime. If performance |
does become an issue, the solution is to use an Event that |
we wait on here (and set above), but that implies a place to |
create the event before this routine is called. */ |
while (! once->done) |
yield(); |
} |
} |
return 0; |
} |
#define __GTHREAD_ONCE_INIT {0, -1} |
typedef unsigned int word __attribute__((mode(word))); |
typedef unsigned int pointer __attribute__((mode(pointer))); |
struct __emutls_object |
{ |
word size; |
word align; |
union { |
pointer offset; |
void *ptr; |
} loc; |
void *templ; |
}; |
struct __emutls_array |
{ |
pointer size; |
void **data[]; |
}; |
void *__emutls_get_address (struct __emutls_object *); |
void __emutls_register_common (struct __emutls_object *, word, word, void *); |
static __gthread_mutex_t emutls_mutex; |
static __gthread_key_t emutls_key; |
static pointer emutls_size; |
static void emutls_destroy (void *ptr) |
{ |
struct __emutls_array *arr = ptr; |
pointer size = arr->size; |
pointer i; |
for (i = 0; i < size; ++i) |
{ |
if (arr->data[i]) |
free (arr->data[i][-1]); |
} |
free (ptr); |
}; |
static void emutls_init (void) |
{ |
if (__gthread_key_create (&emutls_key, emutls_destroy) != 0) |
abort (); |
} |
static void *emutls_alloc (struct __emutls_object *obj) |
{ |
void *ptr; |
void *ret; |
/* We could use here posix_memalign if available and adjust |
emutls_destroy accordingly. */ |
if (obj->align <= sizeof (void *)) |
{ |
ptr = malloc (obj->size + sizeof (void *)); |
if (ptr == NULL) |
abort (); |
((void **) ptr)[0] = ptr; |
ret = ptr + sizeof (void *); |
} |
else |
{ |
ptr = malloc (obj->size + sizeof (void *) + obj->align - 1); |
if (ptr == NULL) |
abort (); |
ret = (void *) (((pointer) (ptr + sizeof (void *) + obj->align - 1)) |
& ~(pointer)(obj->align - 1)); |
((void **) ret)[-1] = ptr; |
} |
if (obj->templ) |
memcpy (ret, obj->templ, obj->size); |
else |
memset (ret, 0, obj->size); |
return ret; |
} |
void * __emutls_get_address (struct __emutls_object *obj) |
{ |
pointer offset = obj->loc.offset; |
if (__builtin_expect (offset == 0, 0)) |
{ |
static __gthread_once_t once = __GTHREAD_ONCE_INIT; |
__gthread_once (&once, emutls_init); |
__gthread_mutex_lock (&emutls_mutex); |
offset = obj->loc.offset; |
if (offset == 0) |
{ |
offset = ++emutls_size; |
obj->loc.offset = offset; |
} |
__gthread_mutex_unlock (&emutls_mutex); |
} |
struct __emutls_array *arr = __gthread_getspecific (emutls_key); |
if (__builtin_expect (arr == NULL, 0)) |
{ |
pointer size = offset + 32; |
arr = calloc (size + 1, sizeof (void *)); |
if (arr == NULL) |
abort (); |
arr->size = size; |
__gthread_setspecific (emutls_key, (void *) arr); |
} |
else if (__builtin_expect (offset > arr->size, 0)) |
{ |
pointer orig_size = arr->size; |
pointer size = orig_size * 2; |
if (offset > size) |
size = offset + 32; |
arr = realloc (arr, (size + 1) * sizeof (void *)); |
if (arr == NULL) |
abort (); |
arr->size = size; |
memset (arr->data + orig_size, 0, |
(size - orig_size) * sizeof (void *)); |
__gthread_setspecific (emutls_key, (void *) arr); |
} |
void *ret = arr->data[offset - 1]; |
if (__builtin_expect (ret == NULL, 0)) |
{ |
ret = emutls_alloc (obj); |
arr->data[offset - 1] = ret; |
} |
return ret; |
} |
void __emutls_register_common (struct __emutls_object *obj, |
word size, word align, void *templ) |
{ |
if (obj->size < size) |
{ |
obj->size = size; |
obj->templ = NULL; |
} |
if (obj->align < align) |
obj->align = align; |
if (templ && size == obj->size) |
obj->templ = templ; |
} |
/programs/develop/libraries/newlib/crt/exit.S |
---|
0,0 → 1,20 |
.section .text |
.global __exit |
.global __Exit |
.align 4 |
__exit: |
__Exit: |
movl 4(%esp), %edx #store exit code |
movl $68, %eax |
movl $13, %ebx |
movl %fs:4, %ecx |
int $0x40 #destroy stack |
movl $-1, %eax |
int $0x40 #terminate thread |
/programs/develop/libraries/newlib/crt/i386mach.h |
---|
0,0 → 1,76 |
/* This file was based on the modified setjmp.S performed by |
* Joel Sherill (joel@OARcorp.com) which specified the use |
* of the __USER_LABEL_PREFIX__ and __REGISTER_PREFIX__ macros. |
** |
** This file is distributed WITHOUT ANY WARRANTY; without even the implied |
** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
*/ |
/* These are predefined by new versions of GNU cpp. */ |
#ifndef __USER_LABEL_PREFIX__ |
#define __USER_LABEL_PREFIX__ _ |
#endif |
#define __REG_PREFIX__ % |
/* ANSI concatenation macros. */ |
#define CONCAT1(a, b) CONCAT2(a, b) |
#define CONCAT2(a, b) a##b |
/* Use the right prefix for global labels. */ |
#define SYM(x) CONCAT1(__USER_LABEL_PREFIX__, x) |
/* Use the right prefix for registers. */ |
#define REG(x) CONCAT1(__REG_PREFIX__, x) |
#define eax REG(eax) |
#define ebx REG(ebx) |
#define ecx REG(ecx) |
#define edx REG(edx) |
#define esi REG(esi) |
#define edi REG(edi) |
#define ebp REG(ebp) |
#define esp REG(esp) |
#define st0 REG(st) |
#define st1 REG(st(1)) |
#define st2 REG(st(2)) |
#define st3 REG(st(3)) |
#define st4 REG(st(4)) |
#define st5 REG(st(5)) |
#define st6 REG(st(6)) |
#define st7 REG(st(7)) |
#define ax REG(ax) |
#define bx REG(bx) |
#define cx REG(cx) |
#define dx REG(dx) |
#define ah REG(ah) |
#define bh REG(bh) |
#define ch REG(ch) |
#define dh REG(dh) |
#define al REG(al) |
#define bl REG(bl) |
#define cl REG(cl) |
#define dl REG(dl) |
#define mm1 REG(mm1) |
#define mm2 REG(mm2) |
#define mm3 REG(mm3) |
#define mm4 REG(mm4) |
#define mm5 REG(mm5) |
#define mm6 REG(mm6) |
#define mm7 REG(mm7) |
#ifdef _I386MACH_NEED_SOTYPE_FUNCTION |
#define SOTYPE_FUNCTION(sym) .type SYM(sym),@function |
#else |
#define SOTYPE_FUNCTION(sym) |
#endif |
/programs/develop/libraries/newlib/crt/pseudo-reloc.S |
---|
0,0 → 1,26 |
.global __pei386_runtime_relocator |
.text |
__pei386_runtime_relocator: |
# movl $___RUNTIME_PSEUDO_RELOC_LIST__, %ecx |
# pushl %ebp |
# cmpl $___RUNTIME_PSEUDO_RELOC_LIST_END__, %ecx |
# movl %esp, %ebp |
# jnb .L2 |
#.L1: |
# movl (%ecx), %eax |
# movl 4(%ecx), %edx |
# addl $8, %ecx |
# addl %eax, __image_base__(%edx) |
# cmpl $___RUNTIME_PSEUDO_RELOC_LIST_END__, %ecx |
# jb .L1 |
#.L2: |
# popl %ebp |
ret |
/programs/develop/libraries/newlib/crt/setjmp.S |
---|
0,0 → 1,89 |
/* This is file is a merger of SETJMP.S and LONGJMP.S */ |
/* |
* This file was modified to use the __USER_LABEL_PREFIX__ and |
* __REGISTER_PREFIX__ macros defined by later versions of GNU cpp by |
* Joel Sherrill (joel@OARcorp.com) |
* Slight change: now includes i386mach.h for this (Werner Almesberger) |
* |
* Copyright (C) 1991 DJ Delorie |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms is permitted |
* provided that the above copyright notice and following paragraph are |
* duplicated in all such forms. |
* |
* This file is distributed WITHOUT ANY WARRANTY; without even the implied |
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
*/ |
/* |
** jmp_buf: |
** eax ebx ecx edx esi edi ebp esp eip |
** 0 4 8 12 16 20 24 28 32 |
*/ |
#include "i386mach.h" |
.global SYM (setjmp) |
.global SYM (longjmp) |
SOTYPE_FUNCTION(setjmp) |
SOTYPE_FUNCTION(longjmp) |
.def _setjmp; .scl 2; .type 32; .endef |
SYM (setjmp): |
pushl ebp |
movl esp,ebp |
pushl edi |
movl 8 (ebp),edi |
movl eax,0 (edi) |
movl ebx,4 (edi) |
movl ecx,8 (edi) |
movl edx,12 (edi) |
movl esi,16 (edi) |
movl -4 (ebp),eax |
movl eax,20 (edi) |
movl 0 (ebp),eax |
movl eax,24 (edi) |
movl esp,eax |
addl $12,eax |
movl eax,28 (edi) |
movl 4 (ebp),eax |
movl eax,32 (edi) |
popl edi |
movl $0,eax |
leave |
ret |
.def _longjmp; .scl 2; .type 32; .endef |
SYM (longjmp): |
pushl ebp |
movl esp,ebp |
movl 8(ebp),edi /* get jmp_buf */ |
movl 12(ebp),eax /* store retval in j->eax */ |
movl eax,0(edi) |
movl 24(edi),ebp |
movl 28(edi),esp |
pushl 32(edi) |
movl 0(edi),eax |
movl 4(edi),ebx |
movl 8(edi),ecx |
movl 12(edi),edx |
movl 16(edi),esi |
movl 20(edi),edi |
ret |
/programs/develop/libraries/newlib/crt/start.S |
---|
2,8 → 2,6 |
.section .init |
.global __start |
.global __exit |
.global __Exit |
.align 4 |
__start: |
20,21 → 18,30 |
movl %eax, %fs:4 |
movl %ecx, %fs:8 #save stack base - low limit |
#save stack top - high limit |
movl %ecx, %esp |
jmp ___crt_startup #reload stack |
movl %ecx, %esp #reload stack |
subl $1024, %esp |
movl $9, %eax |
movl %esp, %ebx |
movl $-1, %ecx |
int $0x40 |
movl 30(%ebx), %eax |
movl %eax, %fs:0 #save pid |
movl $__tls_map, %edi #init TLS |
movl $32, %ecx |
xorl %eax, %eax |
notl %eax |
rep |
stosl |
movb $0xF0, __tls_map |
jmp ___crt_startup |
1: |
int3 #trap to debugger |
.ascii "No enough memory for stack allocation" |
.align 4 |
__exit: |
__Exit: |
movl 4(%esp), %edx #store exit code |
movl $68, %eax |
movl $13, %ebx |
movl %fs:4, %ecx |
int $0x40 #destroy stack |
movl $-1, %eax |
int $0x40 #terminate thread |
/programs/develop/libraries/newlib/crt/tls.S |
---|
0,0 → 1,48 |
.section .text |
.global _tls_alloc |
.global __tls_map |
.align 4 |
_tls_alloc: |
pushl $tls_mutex |
call ___mutex_lock |
popl %eax |
movl tls_map_start, %edx |
.align 4 |
.test: |
bsfl (%edx), %eax |
jnz .done |
add $4, %edx |
cmpl $128+__tls_map, %edx |
jb .test |
xorl %eax, %eax |
mov %eax, tls_mutex |
ret |
.done: |
btrl %eax, (%edx) |
movl %edx, tls_map_start |
movl $0, tls_mutex |
subl $__tls_map, %edx |
leal (%eax, %edx, 8), %eax |
shll $2, %eax |
ret |
.section .data |
tls_mutex: .long(0) |
tls_map_start: .long(__tls_map) |
.section .bss |
.align 16 |
__tls_map: .space 128 |