Warning, cross-references for /libc/src/stdio.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #include "stdio.h"
0024 #include "stdlib.h"
0025 #include "buffer.h"
0026 #include "time.h"
0027
0028 #define ALIGN 8
0029
0030 #define ceil(size, align) (( size ) + ( align ) - 1 ) / ( align )
0031 #define rdtsc(x) __asm__ __volatile__("rdtsc \n\t" : "=A" (*(x)))
0032
0033 static frec_p frhead;
0034 static frec_p frecs;
0035
0036 static void MergeRecords (frec_p frp);
0037 static void DelRecord (frec_p prev_frp, frec_p frp);
0038
0039
0040
0041
0042 void itoa (char *buf, int base, int d)
0043 {
0044 char *p = buf;
0045 char *p1, *p2;
0046 unsigned long ud = d;
0047 int divisor = 10;
0048
0049
0050 if (base == 'd' && d < 0)
0051 {
0052 *p++ = '-';
0053 buf++;
0054 ud = -d;
0055 }
0056 else if (base == 'x')
0057 divisor = 16;
0058
0059
0060 do
0061 {
0062 int remainder = ud % divisor;
0063
0064 *p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10;
0065 }
0066 while (ud /= divisor);
0067
0068
0069 *p = 0;
0070
0071
0072 p1 = buf;
0073 p2 = p - 1;
0074 while (p1 < p2)
0075 {
0076 char tmp = *p1;
0077 *p1 = *p2;
0078 *p2 = tmp;
0079 p1++;
0080 p2--;
0081 }
0082 }
0083
0084
0085 int printf (const char *format, ...) {
0086 char **arg = (char **) &format;
0087 int c;
0088 char buf[20];
0089 int count = 0;
0090
0091 arg++;
0092
0093 while ((c = *format++) != 0)
0094 {
0095 if (c != '%') {
0096 putchar (c);
0097 count++;
0098 }
0099 else
0100 {
0101 char *p;
0102
0103 c = *format++;
0104 switch (c)
0105 {
0106 case 'd':
0107 case 'u':
0108 case 'x':
0109 itoa (buf, c, *((int *) arg++));
0110 p = buf;
0111 goto string;
0112 break;
0113
0114 case 's':
0115 p = *arg++;
0116 if (! p)
0117 p = "(null)";
0118
0119 string:
0120 while (*p) {
0121 putchar (*p++);
0122 count++;
0123 }
0124 break;
0125
0126 default:
0127 putchar (*((int *) arg++));
0128 count++;
0129 break;
0130 }
0131 }
0132 }
0133 return count;
0134 }
0135
0136
0137 int sprintf (char *str, const char *format, ...) {
0138 char **arg = (char **) &format;
0139 int c;
0140 char buf[20];
0141 int count = 0;
0142
0143 arg++;
0144
0145 while ((c = *format++) != 0)
0146 {
0147 if (c != '%') {
0148 *str++ = c;
0149 count++;
0150 }
0151 else
0152 {
0153 char *p;
0154
0155 c = *format++;
0156 switch (c)
0157 {
0158 case 'd':
0159 case 'u':
0160 case 'x':
0161 itoa (buf, c, *((int *) arg++));
0162 p = buf;
0163 goto string;
0164 break;
0165
0166 case 's':
0167 p = *arg++;
0168 if (! p)
0169 p = "(null)";
0170
0171 string:
0172 while (*p) {
0173 *str++ = *p++;
0174 count++;
0175 }
0176 break;
0177
0178 default:
0179 *str++ = (*((int *) arg++));
0180 count++;
0181 break;
0182 }
0183 }
0184 }
0185
0186 *str = '\0';
0187
0188 return count;
0189 }
0190
0191
0192 static char arena[1000000];
0193
0194 void mem_init ( void ) {
0195 void *memset( void *p, int ch, size_t cb );
0196 addrs_t baseptr;
0197 frec_p frp;
0198
0199 int size = 800000;
0200
0201 memset(arena, 0, 1000000);
0202
0203 baseptr = arena;
0204 frhead = (frec_p)(baseptr + size);
0205
0206 for (frp = frhead; frp < frhead + MAXBLKS; frp++)
0207 frp->next = frp + 1;
0208
0209 frhead->next = NULL;
0210 (frhead + MAXBLKS - 1)->next = NULL;
0211 frecs = frhead + 1;
0212 frhead->fbp = baseptr;
0213 frhead->size = size;
0214 }
0215
0216
0217 void *malloc (size_t size) {
0218
0219 frec_p frp, prev_frp;
0220 addrs_t frstart;
0221
0222 size += 8;
0223
0224
0225 prev_frp = frp = frhead;
0226
0227 while (frp) {
0228 if (frp->size >= (int)(ALIGN * ceil(size, ALIGN))) {
0229
0230
0231 frstart = frp->fbp;
0232 frp->fbp += (int)(ALIGN * ceil(size, ALIGN));
0233 frp->size -= (int)(ALIGN * ceil(size, ALIGN));
0234 *((int *)frstart) = size;
0235
0236
0237 if (frp->size)
0238 return (frstart+8);
0239
0240
0241 DelRecord (prev_frp, frp);
0242 return (frstart+8);
0243
0244 }
0245 prev_frp = frp;
0246 frp = frp->next;
0247 }
0248 return NULL;
0249 }
0250
0251
0252 static void DelRecord (frec_p prev_frp, frec_p frp) {
0253
0254 if (frp == frhead)
0255 frhead = frp->next;
0256 else
0257 prev_frp->next = frp->next;
0258
0259 frp->next = frecs;
0260 frecs = frp;
0261 }
0262
0263
0264 void free (void *addr) {
0265
0266 frec_p frp, new_frp, prev_frp;
0267 size_t size;
0268
0269 addr -= 8;
0270
0271 size = *((int *) addr );
0272
0273 if ((new_frp = frecs) == NULL) {
0274
0275 exit (1);
0276 }
0277
0278 new_frp->fbp = (addrs_t) addr;
0279 new_frp->size = (int)(ALIGN * ceil(size, ALIGN));
0280 frecs = new_frp->next;
0281 frp = frhead;
0282
0283
0284
0285
0286
0287 if (frp == NULL || (addrs_t)addr <= frp->fbp) {
0288 new_frp->next = frp;
0289 frhead = new_frp;
0290 MergeRecords (new_frp);
0291 return;
0292 }
0293
0294
0295
0296 while (frp && (addrs_t)addr > frp->fbp) {
0297 prev_frp = frp;
0298 frp = frp->next;
0299 }
0300
0301 new_frp->next = prev_frp->next;
0302 prev_frp->next = new_frp;
0303 MergeRecords (prev_frp);
0304 }
0305
0306
0307 static void MergeRecords (frec_p frp) {
0308
0309 frec_p next_frp;
0310
0311
0312
0313 if ((next_frp = frp->next) == NULL)
0314 return;
0315
0316 if (frp->fbp + frp->size == next_frp->fbp) {
0317 frp->size += next_frp->size;
0318 DelRecord (frp, next_frp);
0319 }
0320 else
0321 frp = next_frp;
0322
0323 if ((next_frp = frp->next) == NULL)
0324 return;
0325
0326 if (frp->fbp + frp->size == next_frp->fbp) {
0327 frp->size += next_frp->size;
0328 DelRecord (frp, next_frp);
0329 }
0330 }
0331
0332 __attribute__((noreturn)) void exit( int status ) {
0333
0334
0335
0336
0337
0338 _exit( status );
0339
0340 }
0341
0342
0343 static unsigned long int next = 1;
0344
0345 int rand(void) {
0346
0347 next = next * 1103515245 + 12345;
0348 return (unsigned int)(next/65536) % 32768;
0349 }
0350
0351 void srand(unsigned int seed) {
0352 next = seed;
0353 }
0354
0355
0356 int atoi(const char *nptr) {
0357
0358 return -1;
0359 }
0360
0361
0362 clock_t clock( void ) {
0363
0364 return( time() * 10000 );
0365 }
0366
0367 size_t strlen( const char *s ) {
0368
0369 int i;
0370
0371 i = 0;
0372 while( s[i] != '\0' )
0373 ++i;
0374 return i;
0375
0376 }
0377
0378
0379 char *strcpy( char *s1, const char *s2 ) {
0380
0381 while( *s1++ = *s2++ );
0382
0383 return s1;
0384 }
0385
0386
0387 char *strncpy( char *s1, const char *s2, int length ) {
0388
0389 while( ( length-- ) && ( *s1++ = *s2++ ) );
0390
0391 if( length < 0 )
0392 *(s1-1) = '\0';
0393
0394 return s1;
0395 }
0396
0397
0398 int strcmp(const char *s1, const char *s2) {
0399
0400 for( ; *s1 == *s2; s1++, s2++ )
0401 if( *s1 == '\0' )
0402 return 0;
0403 return *s1 - *s2;
0404
0405 }
0406
0407
0408 void *memset( void *p, int ch, size_t cb ) {
0409
0410 asm volatile( "rep stosb" : : "D" (p), "a" (ch), "c" (cb) );
0411 return p;
0412 }
0413
0414
0415 void *memcpy( void *pDest, const void *pSrc, size_t cb ) {
0416
0417 asm volatile( "rep movsb" : : "D" (pDest), "S" (pSrc), "c" (cb) );
0418 return pDest;
0419 }
0420
0421
0422 int memcmp( const void *p1, const void *p2, size_t cb ) {
0423
0424 const char *s1 = p1, *s2 = p2;
0425
0426 for( ; cb && *s1 == *s2; s1++, s2++, cb-- );
0427 if( !cb )
0428 return 0;
0429
0430 return *s1 - *s2;
0431 }
0432
0433
0434
0435 static int fp;
0436 static int filesize;
0437 static char tmp_buf[8192];
0438
0439 size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) {
0440
0441
0442 if( size * nmemb + fp > filesize )
0443 nmemb = ( filesize - fp ) / size;
0444
0445 memcpy( ptr, tmp_buf + fp, size * nmemb );
0446 fp += size * nmemb;
0447
0448 return nmemb;
0449 }
0450
0451
0452
0453 FILE *fopen(const char *path, const char *mode) {
0454
0455 static FILE f;
0456
0457 if( ( filesize = open( path, 0 ) ) < 0 )
0458 return NULL;
0459 read( (char *)path, tmp_buf, filesize );
0460 fp = 0;
0461
0462 return &f;
0463
0464 }
0465
0466
0467
0468 size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
0469
0470
0471 return 0;
0472 }
0473
0474
0475
0476 int fclose(FILE *stream) {
0477
0478 return 0;
0479 }
0480
0481
0482
0483 int fprintf(FILE *stream, const char *format, ...) {
0484
0485 }
0486
0487
0488 int puts(const char *s) {
0489
0490 while( *s )
0491 putchar( *s++ );
0492
0493 putchar( '\n' );
0494
0495 return( 1 );
0496 }
0497
0498
0499 void _start ( int argc, char *argv[] ) {
0500
0501 mem_init();
0502 exit ( main( argc, argv ) );
0503 }
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514