1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2009 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.opensource.org/licenses/cpl1.0.txt * 11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * Glenn Fowler <gsf@research.att.com> * 18 * David Korn <dgk@research.att.com> * 19 * Phong Vo <kpv@research.att.com> * 20 * * 21 ***********************************************************************/ 22 #ifndef _VMHDR_H 23 #define _VMHDR_H 1 24 #ifndef _BLD_vmalloc 25 #define _BLD_vmalloc 1 26 #endif 27 28 /* Common types, and macros for vmalloc functions. 29 ** 30 ** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94. 31 */ 32 33 #ifndef __STD_C /* this is normally in vmalloc.h but it's included late here */ 34 #ifdef __STDC__ 35 #define __STD_C 1 36 #else 37 #if __cplusplus || c_plusplus 38 #define __STD_C 1 39 #else 40 #define __STD_C 0 41 #endif /*__cplusplus*/ 42 #endif /*__STDC__*/ 43 #endif /*__STD_C*/ 44 45 #if _PACKAGE_ast 46 47 #if !_UWIN 48 #define getpagesize ______getpagesize 49 #define _npt_getpagesize 1 50 #define brk ______brk 51 #define sbrk ______sbrk 52 #define _npt_sbrk 1 53 #endif 54 55 #include <ast.h> 56 57 #if _npt_getpagesize 58 #undef getpagesize 59 #endif 60 #if _npt_sbrk 61 #undef brk 62 #undef sbrk 63 #endif 64 65 #else 66 67 #include <ast_common.h> 68 69 #if !_UWIN 70 #define _npt_getpagesize 1 71 #define _npt_sbrk 1 72 #endif 73 74 #endif /*_PACKAGE_ast*/ 75 76 #include "FEATURE/vmalloc" 77 78 #include <setjmp.h> 79 80 /* the below macros decide which combinations of sbrk() or mmap() to used */ 81 #if defined(_WIN32) 82 #define _mem_win32 1 83 #undef _mem_sbrk 84 #undef _mem_mmap_anon 85 #undef _mem_mmap_zero 86 #endif 87 88 #if _mem_mmap_anon 89 #undef _mem_mmap_zero 90 #endif 91 92 #if !_mem_win32 && !_mem_sbrk && !_mem_mmap_anon && !_mem_mmap_zero 93 #undef _std_malloc 94 #define _std_malloc 1 /* do not define malloc/free/realloc */ 95 #endif 96 97 typedef unsigned char Vmuchar_t; 98 typedef unsigned long Vmulong_t; 99 100 typedef union _head_u Head_t; 101 typedef union _body_u Body_t; 102 typedef struct _block_s Block_t; 103 typedef struct _seg_s Seg_t; 104 typedef struct _pfobj_s Pfobj_t; 105 106 #if !_typ_ssize_t 107 typedef int ssize_t; 108 #endif 109 110 #define NIL(t) ((t)0) 111 #define reg register 112 #if __STD_C 113 #define NOTUSED(x) (void)(x) 114 #else 115 #define NOTUSED(x) (&x,1) 116 #endif 117 118 /* convert an address to an integral value */ 119 #define VLONG(addr) ((Vmulong_t)((char*)(addr) - (char*)0) ) 120 121 /* Round x up to a multiple of y. ROUND2 does powers-of-2 and ROUNDX does others */ 122 #define ROUND2(x,y) (((x) + ((y)-1)) & ~((y)-1)) 123 #define ROUNDX(x,y) ((((x) + ((y)-1)) / (y)) * (y)) 124 #define ROUND(x,y) (((y)&((y)-1)) ? ROUNDX((x),(y)) : ROUND2((x),(y)) ) 125 126 /* compute a value that is a common multiple of x and y */ 127 #define MULTIPLE(x,y) ((x)%(y) == 0 ? (x) : (y)%(x) == 0 ? (y) : (y)*(x)) 128 129 #define VM_check 0x0001 /* enable detailed checks */ 130 #define VM_abort 0x0002 /* abort() on assertion failure */ 131 #define VM_region 0x0004 /* enable region segment checks */ 132 #define VM_mmap 0x0010 /* favor mmap allocation */ 133 #define VM_init 0x8000 /* VMCHECK env var checked */ 134 135 #if _UWIN 136 #include <ast_windows.h> 137 #endif 138 139 #ifndef DEBUG 140 #ifdef _BLD_DEBUG 141 #define DEBUG 1 142 #endif /*_BLD_DEBUG*/ 143 #endif /*DEBUG*/ 144 #if DEBUG 145 extern void _vmmessage _ARG_((const char*, long, const char*, long)); 146 #define ABORT() (_Vmassert & VM_abort) 147 #define CHECK() (_Vmassert & VM_check) 148 #define ASSERT(p) ((p) ? 0 : (MESSAGE("Assertion failed"), ABORT() ? (abort(),0) : 0)) 149 #define COUNT(n) ((n) += 1) 150 #define MESSAGE(s) _vmmessage(__FILE__,__LINE__,s,0) 151 #else 152 #define ABORT() (0) 153 #define ASSERT(p) 154 #define CHECK() (0) 155 #define COUNT(n) 156 #define MESSAGE(s) (0) 157 #endif /*DEBUG*/ 158 159 #define VMPAGESIZE 8192 160 161 #if _AST_PAGESIZE > VMPAGESIZE 162 #undef VMPAGESIZE 163 #define VMPAGESIZE _AST_PAGESIZE 164 #endif 165 166 #if _lib_getpagesize && !defined(_AST_PAGESIZE) 167 #define GETPAGESIZE(x) ((x) ? (x) : \ 168 (((x)=getpagesize()) < VMPAGESIZE ? ((x)=VMPAGESIZE) : (x)) ) 169 #else 170 #define GETPAGESIZE(x) ((x) = VMPAGESIZE) 171 #endif 172 173 #ifdef _AST_PAGESIZE 174 #define VMHEAPINCR (_Vmpagesize*1) 175 #else 176 #define VMHEAPINCR (_Vmpagesize*4) 177 #endif 178 179 /* Blocks are allocated such that their sizes are 0%(BITS+1) 180 ** This frees up enough low order bits to store state information 181 */ 182 #define BUSY (01) /* block is busy */ 183 #define PFREE (02) /* preceding block is free */ 184 #define JUNK (04) /* marked as freed but not yet processed */ 185 #define BITS (07) /* (BUSY|PFREE|JUNK) */ 186 #define ALIGNB (8) /* size must be a multiple of BITS+1 */ 187 188 #define ISBITS(w) ((w) & BITS) 189 #define CLRBITS(w) ((w) &= ~BITS) 190 #define CPYBITS(w,f) ((w) |= ((f)&BITS) ) 191 192 #define ISBUSY(w) ((w) & BUSY) 193 #define SETBUSY(w) ((w) |= BUSY) 194 #define CLRBUSY(w) ((w) &= ~BUSY) 195 196 #define ISPFREE(w) ((w) & PFREE) 197 #define SETPFREE(w) ((w) |= PFREE) 198 #define CLRPFREE(w) ((w) &= ~PFREE) 199 200 #define ISJUNK(w) ((w) & JUNK) 201 #define SETJUNK(w) ((w) |= JUNK) 202 #define CLRJUNK(w) ((w) &= ~JUNK) 203 204 #define OFFSET(t,e) ((size_t)(&(((t*)0)->e)) ) 205 206 /* these bits share the "mode" field with the public bits */ 207 #define VM_AGAIN 0010000 /* research the arena for space */ 208 #define VM_LOCK 0020000 /* region is locked */ 209 #define VM_LOCAL 0040000 /* local call, bypass lock */ 210 #define VM_INUSE 0004000 /* some operation is running */ 211 #define VM_UNUSED 0100060 212 #define VMETHOD(vd) ((vd)->mode&VM_METHODS) 213 214 /* test/set/clear lock state */ 215 #define SETINUSE(vd,iu) (((iu) = (vd)->mode&VM_INUSE), ((vd)->mode |= VM_INUSE) ) 216 #define CLRINUSE(vd,iu) ((iu) ? 0 : ((vd)->mode &= ~VM_INUSE) ) 217 #define SETLOCAL(vd) ((vd)->mode |= VM_LOCAL) 218 #define GETLOCAL(vd,l) (((l) = (vd)->mode&VM_LOCAL), ((vd)->mode &= ~VM_LOCAL) ) 219 #define ISLOCK(vd,l) ((l) ? 0 : ((vd)->mode & VM_LOCK) ) 220 #define SETLOCK(vd,l) ((l) ? 0 : ((vd)->mode |= VM_LOCK) ) 221 #define CLRLOCK(vd,l) ((l) ? 0 : ((vd)->mode &= ~VM_LOCK) ) 222 223 /* announcing entry/exit of allocation calls */ 224 #define ANNOUNCE(lc, vm,ev,dt,dc) \ 225 (( ((lc)&VM_LOCAL) || !(dc) || !(dc)->exceptf ) ? 0 : \ 226 (*(dc)->exceptf)((vm), (ev), (Void_t*)(dt), (dc)) ) 227 228 229 /* local calls */ 230 #define KPVALLOC(vm,sz,func) (SETLOCAL((vm)->data), func((vm),(sz)) ) 231 #define KPVALIGN(vm,sz,al,func) (SETLOCAL((vm)->data), func((vm),(sz),(al)) ) 232 #define KPVFREE(vm,d,func) (SETLOCAL((vm)->data), func((vm),(d)) ) 233 #define KPVRESIZE(vm,d,sz,mv,func) (SETLOCAL((vm)->data), func((vm),(d),(sz),(mv)) ) 234 #define KPVADDR(vm,addr,func) (SETLOCAL((vm)->data), func((vm),(addr)) ) 235 #define KPVCOMPACT(vm,func) (SETLOCAL((vm)->data), func((vm)) ) 236 237 /* ALIGN is chosen so that a block can store all primitive types. 238 ** It should also be a multiple of ALIGNB==(BITS+1) so the size field 239 ** of Block_t will always be 0%(BITS+1) as noted above. 240 ** Of paramount importance is the ALIGNA macro below. If the local compile 241 ** environment is strange enough that the below method does not calculate 242 ** ALIGNA right, then the code below should be commented out and ALIGNA 243 ** redefined to the appropriate requirement. 244 */ 245 union _align_u 246 { char c, *cp; 247 int i, *ip; 248 long l, *lp; 249 double d, *dp, ***dppp[8]; 250 size_t s, *sp; 251 void(* fn)(); 252 union _align_u* align; 253 Head_t* head; 254 Body_t* body; 255 Block_t* block; 256 Vmuchar_t a[ALIGNB]; 257 _ast_fltmax_t ld, *ldp; 258 jmp_buf jmp; 259 }; 260 struct _a_s 261 { char c; 262 union _align_u a; 263 }; 264 #define ALIGNA (sizeof(struct _a_s) - sizeof(union _align_u)) 265 struct _align_s 266 { char data[MULTIPLE(ALIGNA,ALIGNB)]; 267 }; 268 #undef ALIGN /* bsd sys/param.h defines this */ 269 #define ALIGN sizeof(struct _align_s) 270 271 /* make sure that the head of a block is a multiple of ALIGN */ 272 struct _head_s 273 { union 274 { Seg_t* seg; /* the containing segment */ 275 Block_t* link; /* possible link list usage */ 276 Pfobj_t* pf; /* profile structure pointer */ 277 char* file; /* for file name in Vmdebug */ 278 } seg; 279 union 280 { size_t size; /* size of data area in bytes */ 281 Block_t* link; /* possible link list usage */ 282 int line; /* for line number in Vmdebug */ 283 } size; 284 }; 285 #define HEADSIZE ROUND(sizeof(struct _head_s),ALIGN) 286 union _head_u 287 { Vmuchar_t data[HEADSIZE]; /* to standardize size */ 288 struct _head_s head; 289 }; 290 291 /* now make sure that the body of a block is a multiple of ALIGN */ 292 struct _body_s 293 { Block_t* link; /* next in link list */ 294 Block_t* left; /* left child in free tree */ 295 Block_t* right; /* right child in free tree */ 296 Block_t** self; /* self pointer when free */ 297 }; 298 #define BODYSIZE ROUND(sizeof(struct _body_s),ALIGN) 299 union _body_u 300 { Vmuchar_t data[BODYSIZE]; /* to standardize size */ 301 struct _body_s body; 302 }; 303 304 /* After all the songs and dances, we should now have: 305 ** sizeof(Head_t)%ALIGN == 0 306 ** sizeof(Body_t)%ALIGN == 0 307 ** and sizeof(Block_t) = sizeof(Head_t)+sizeof(Body_t) 308 */ 309 struct _block_s 310 { Head_t head; 311 Body_t body; 312 }; 313 314 /* requirements for smallest block type */ 315 struct _tiny_s 316 { Block_t* link; 317 Block_t* self; 318 }; 319 #define TINYSIZE ROUND(sizeof(struct _tiny_s),ALIGN) 320 #define S_TINY 1 /* # of tiny blocks */ 321 #define MAXTINY (S_TINY*ALIGN + TINYSIZE) 322 #define TLEFT(b) ((b)->head.head.seg.link) /* instead of LEFT */ 323 #define TINIEST(b) (SIZE(b) == TINYSIZE) /* this type uses TLEFT */ 324 325 #define DIV(x,y) ((y) == 8 ? ((x)>>3) : (x)/(y) ) 326 #define INDEX(s) DIV((s)-TINYSIZE,ALIGN) 327 328 /* small block types kept in separate caches for quick allocation */ 329 #define S_CACHE 6 /* # of types of small blocks to be cached */ 330 #define N_CACHE 32 /* on allocation, create this many at a time */ 331 #define MAXCACHE (S_CACHE*ALIGN + TINYSIZE) 332 #define C_INDEX(s) (s < MAXCACHE ? INDEX(s) : S_CACHE) 333 334 #define TINY(vd) ((vd)->tiny) 335 #define CACHE(vd) ((vd)->cache) 336 337 typedef struct _vmdata_s 338 { int mode; /* current mode for region */ 339 size_t incr; /* allocate in multiple of this */ 340 size_t pool; /* size of an elt in a Vmpool region */ 341 Seg_t* seg; /* list of segments */ 342 Block_t* free; /* most recent free block */ 343 Block_t* wild; /* wilderness block */ 344 Block_t* root; /* root of free tree */ 345 Block_t* tiny[S_TINY]; /* small blocks */ 346 Block_t* cache[S_CACHE+1]; /* delayed free blocks */ 347 } Vmdata_t; 348 349 /* private parts of Vmalloc_t */ 350 #define _VM_PRIVATE_ \ 351 Vmdisc_t* disc; /* discipline to get space */ \ 352 Vmdata_t* data; /* the real region data */ \ 353 Vmalloc_t* next; /* linked list of regions */ 354 355 #include "vmalloc.h" 356 357 #if !_PACKAGE_ast 358 /* we don't use these here and they interfere with some local names */ 359 #undef malloc 360 #undef free 361 #undef realloc 362 #endif 363 364 /* segment structure */ 365 struct _seg_s 366 { Vmalloc_t* vm; /* the region that holds this */ 367 Seg_t* next; /* next segment */ 368 Void_t* addr; /* starting segment address */ 369 size_t extent; /* extent of segment */ 370 Vmuchar_t* baddr; /* bottom of usable memory */ 371 size_t size; /* allocable size */ 372 Block_t* free; /* recent free blocks */ 373 Block_t* last; /* Vmlast last-allocated block */ 374 }; 375 376 /* starting block of a segment */ 377 #define SEGBLOCK(s) ((Block_t*)(((Vmuchar_t*)(s)) + ROUND(sizeof(Seg_t),ALIGN))) 378 379 /* short-hands for block data */ 380 #define SEG(b) ((b)->head.head.seg.seg) 381 #define SEGLINK(b) ((b)->head.head.seg.link) 382 #define SIZE(b) ((b)->head.head.size.size) 383 #define SIZELINK(b) ((b)->head.head.size.link) 384 #define LINK(b) ((b)->body.body.link) 385 #define LEFT(b) ((b)->body.body.left) 386 #define RIGHT(b) ((b)->body.body.right) 387 #define VM(b) (SEG(b)->vm) 388 389 #define DATA(b) ((Void_t*)((b)->body.data) ) 390 #define BLOCK(d) ((Block_t*)((char*)(d) - sizeof(Head_t)) ) 391 #define SELF(b) ((Block_t**)((b)->body.data + SIZE(b) - sizeof(Block_t*)) ) 392 #define LAST(b) (*((Block_t**)(((char*)(b)) - sizeof(Block_t*)) ) ) 393 #define NEXT(b) ((Block_t*)((b)->body.data + SIZE(b)) ) 394 395 /* functions to manipulate link lists of elts of the same size */ 396 #define SETLINK(b) (RIGHT(b) = (b) ) 397 #define ISLINK(b) (RIGHT(b) == (b) ) 398 #define UNLINK(vd,b,i,t) \ 399 ((((t) = LINK(b)) ? (LEFT(t) = LEFT(b)) : NIL(Block_t*) ), \ 400 (((t) = LEFT(b)) ? (LINK(t) = LINK(b)) : (TINY(vd)[i] = LINK(b)) ) ) 401 402 /* delete a block from a link list or the free tree. 403 ** The test in the below macro is worth scratching your head a bit. 404 ** Even though tiny blocks (size < BODYSIZE) are kept in separate lists, 405 ** only the TINIEST ones require TLEFT(b) for the back link. Since this 406 ** destroys the SEG(b) pointer, it must be carefully restored in bestsearch(). 407 ** Other tiny blocks have enough space to use the usual LEFT(b). 408 ** In this case, I have also carefully arranged so that RIGHT(b) and 409 ** SELF(b) can be overlapped and the test ISLINK() will go through. 410 */ 411 #define REMOVE(vd,b,i,t,func) \ 412 ((!TINIEST(b) && ISLINK(b)) ? UNLINK((vd),(b),(i),(t)) : \ 413 func((vd),SIZE(b),(b)) ) 414 415 /* see if a block is the wilderness block */ 416 #define SEGWILD(b) (((b)->body.data+SIZE(b)+sizeof(Head_t)) >= SEG(b)->baddr) 417 #define VMWILD(vd,b) (((b)->body.data+SIZE(b)+sizeof(Head_t)) >= vd->seg->baddr) 418 419 #define VMFLF(vm,fi,ln,fn) ((fi) = (vm)->file, (vm)->file = NIL(char*), \ 420 (ln) = (vm)->line, (vm)->line = 0 , \ 421 (fn) = (vm)->func, (vm)->func = NIL(Void_t*) ) 422 423 /* The lay-out of a Vmprofile block is this: 424 ** seg_ size ----data---- _pf_ size 425 ** _________ ____________ _________ 426 ** seg_, size: header required by Vmbest. 427 ** data: actual data block. 428 ** _pf_: pointer to the corresponding Pfobj_t struct 429 ** size: the true size of the block. 430 ** So each block requires an extra Head_t. 431 */ 432 #define PF_EXTRA sizeof(Head_t) 433 #define PFDATA(d) ((Head_t*)((Vmuchar_t*)(d)+(SIZE(BLOCK(d))&~BITS)-sizeof(Head_t)) ) 434 #define PFOBJ(d) (PFDATA(d)->head.seg.pf) 435 #define PFSIZE(d) (PFDATA(d)->head.size.size) 436 437 /* The lay-out of a block allocated by Vmdebug is this: 438 ** seg_ size file size seg_ magi ----data---- --magi-- magi line 439 ** --------- --------- --------- ------------ -------- --------- 440 ** seg_,size: header required by Vmbest management. 441 ** file: the file where it was created. 442 ** size: the true byte count of the block 443 ** seg_: should be the same as the previous seg_. 444 ** This allows the function vmregion() to work. 445 ** magi: magic bytes to detect overwrites. 446 ** data: the actual data block. 447 ** magi: more magic bytes. 448 ** line: the line number in the file where it was created. 449 ** So for each allocated block, we'll need 3 extra Head_t. 450 */ 451 452 /* convenient macros for accessing the above fields */ 453 #define DB_HEAD (2*sizeof(Head_t)) 454 #define DB_TAIL (2*sizeof(Head_t)) 455 #define DB_EXTRA (DB_HEAD+DB_TAIL) 456 #define DBBLOCK(d) ((Block_t*)((Vmuchar_t*)(d) - 3*sizeof(Head_t)) ) 457 #define DBBSIZE(d) (SIZE(DBBLOCK(d)) & ~BITS) 458 #define DBSEG(d) (((Head_t*)((Vmuchar_t*)(d) - sizeof(Head_t)))->head.seg.seg ) 459 #define DBSIZE(d) (((Head_t*)((Vmuchar_t*)(d) - 2*sizeof(Head_t)))->head.size.size ) 460 #define DBFILE(d) (((Head_t*)((Vmuchar_t*)(d) - 2*sizeof(Head_t)))->head.seg.file ) 461 #define DBLN(d) (((Head_t*)((Vmuchar_t*)DBBLOCK(d)+DBBSIZE(d)))->head.size.line ) 462 #define DBLINE(d) (DBLN(d) < 0 ? -DBLN(d) : DBLN(d)) 463 464 /* forward/backward translation for addresses between Vmbest and Vmdebug */ 465 #define DB2BEST(d) ((Vmuchar_t*)(d) - 2*sizeof(Head_t)) 466 #define DB2DEBUG(b) ((Vmuchar_t*)(b) + 2*sizeof(Head_t)) 467 468 /* set file and line number, note that DBLN > 0 so that DBISBAD will work */ 469 #define DBSETFL(d,f,l) (DBFILE(d) = (f), DBLN(d) = (f) ? (l) : 1) 470 471 /* set and test the state of known to be corrupted */ 472 #define DBSETBAD(d) (DBLN(d) > 0 ? (DBLN(d) = -DBLN(d)) : -1) 473 #define DBISBAD(d) (DBLN(d) <= 0) 474 475 #define DB_MAGIC 0255 /* 10101101 */ 476 477 /* compute the bounds of the magic areas */ 478 #define DBHEAD(d,begp,endp) \ 479 (((begp) = (Vmuchar_t*)(&DBSEG(d)) + sizeof(Seg_t*)), ((endp) = (d)) ) 480 #define DBTAIL(d,begp,endp) \ 481 (((begp) = (Vmuchar_t*)(d)+DBSIZE(d)), ((endp) = (Vmuchar_t*)(&DBLN(d))) ) 482 483 /* external symbols for internal use by vmalloc */ 484 typedef Block_t* (*Vmsearch_f)_ARG_((Vmdata_t*, size_t, Block_t*)); 485 typedef struct _vmextern_ 486 { Block_t* (*vm_extend)_ARG_((Vmalloc_t*, size_t, Vmsearch_f )); 487 ssize_t (*vm_truncate)_ARG_((Vmalloc_t*, Seg_t*, size_t, int)); 488 size_t vm_pagesize; 489 char* (*vm_strcpy)_ARG_((char*, const char*, int)); 490 char* (*vm_itoa)_ARG_((Vmulong_t, int)); 491 void (*vm_trace)_ARG_((Vmalloc_t*, 492 Vmuchar_t*, Vmuchar_t*, size_t, size_t)); 493 void (*vm_pfclose)_ARG_((Vmalloc_t*)); 494 int vm_assert; 495 } Vmextern_t; 496 497 #define _Vmextend (_Vmextern.vm_extend) 498 #define _Vmtruncate (_Vmextern.vm_truncate) 499 #define _Vmpagesize (_Vmextern.vm_pagesize) 500 #define _Vmstrcpy (_Vmextern.vm_strcpy) 501 #define _Vmitoa (_Vmextern.vm_itoa) 502 #define _Vmtrace (_Vmextern.vm_trace) 503 #define _Vmpfclose (_Vmextern.vm_pfclose) 504 #define _Vmassert (_Vmextern.vm_assert) 505 506 extern int _vmbestcheck _ARG_((Vmdata_t*, Block_t*)); 507 508 _BEGIN_EXTERNS_ 509 510 extern Vmextern_t _Vmextern; 511 512 #if _PACKAGE_ast 513 514 #if _npt_getpagesize 515 extern int getpagesize _ARG_((void)); 516 #endif 517 #if _npt_sbrk 518 extern int brk _ARG_(( void* )); 519 extern Void_t* sbrk _ARG_(( ssize_t )); 520 #endif 521 522 #else 523 524 #if _hdr_unistd 525 #include <unistd.h> 526 #else 527 extern void abort _ARG_(( void )); 528 extern ssize_t write _ARG_(( int, const void*, size_t )); 529 extern int getpagesize _ARG_((void)); 530 extern Void_t* sbrk _ARG_((ssize_t)); 531 #endif 532 533 #if !__STDC__ && !_hdr_stdlib 534 extern size_t strlen _ARG_(( const char* )); 535 extern char* strcpy _ARG_(( char*, const char* )); 536 extern int strcmp _ARG_(( const char*, const char* )); 537 extern int atexit _ARG_(( void(*)(void) )); 538 extern char* getenv _ARG_(( const char* )); 539 extern Void_t* memcpy _ARG_(( Void_t*, const Void_t*, size_t )); 540 extern Void_t* memset _ARG_(( Void_t*, int, size_t )); 541 #else 542 #include <stdlib.h> 543 #include <string.h> 544 #endif 545 546 /* for vmexit.c */ 547 extern int onexit _ARG_(( void(*)(void) )); 548 extern void _exit _ARG_(( int )); 549 extern void _cleanup _ARG_(( void )); 550 551 #endif /*_PACKAGE_ast*/ 552 553 _END_EXTERNS_ 554 555 #if _UWIN 556 #define abort() (DebugBreak(),abort()) 557 #endif 558 559 #endif /* _VMHDR_H */ 560