Build NetBSD libc library in world in ELF mode.

3 sets of libraries are built now:
  . ack: all libraries that ack can compile (/usr/lib/i386/)
  . clang+elf: all libraries with minix headers (/usr/lib/)
  . clang+elf: all libraries with netbsd headers (/usr/netbsd/)

Once everything can be compiled with netbsd libraries and headers, the
/usr/netbsd hierarchy will be obsolete and its libraries compiled with
netbsd headers will be installed in /usr/lib, and its headers
in /usr/include. (i.e. minix libc and current minix headers set
will be gone.)

To use the NetBSD libc system (libraries + headers) before
it is the default libc, see:
   http://wiki.minix3.org/en/DevelopersGuide/UsingNetBSDCode
This wiki page also documents the maintenance of the patch
files of minix-specific changes to imported NetBSD code.

Changes in this commit:
  . libsys: Add NBSD compilation and create a safe NBSD-based libc.
  . Port rest of libraries (except libddekit) to new header system.
  . Enable compilation of libddekit with new headers.
  . Enable kernel compilation with new headers.
  . Enable drivers compilation with new headers.
  . Port legacy commands to new headers and libc.
  . Port servers to new headers.
  . Add <sys/sigcontext.h> in compat library.
  . Remove dependency file in tree.
  . Enable compilation of common/lib/libc/atomic in libsys
  . Do not generate RCSID strings in libc.
  . Temporarily disable zoneinfo as they are incompatible with NetBSD format
  . obj-nbsd for .gitignore
  . Procfs: use only integer arithmetic. (Antoine Leca)
  . Increase ramdisk size to create NBSD-based images.
  . Remove INCSYMLINKS handling hack.
  . Add nbsd_include/sys/exec_elf.h
  . Enable ELF compilation with NBSD libc.
  . Add 'make nbsdsrc' in tools to download reference NetBSD sources.
  . Automate minix-port.patch creation.
  . Avoid using fstavfs() as it is *extremely* slow and unneeded.
  . Set err() as PRIVATE to avoid name clash with libc.
  . [NBSD] servers/vm: remove compilation warnings.
  . u32 is not a long in NBSD headers.
  . UPDATING info on netbsd hierarchy
  . commands fixes for netbsd libc
This commit is contained in:
Gianluca Guida
2011-06-24 11:46:30 +02:00
committed by Ben Gras
parent e3f68488ee
commit cc17b27a2b
136 changed files with 3567 additions and 470 deletions
+5
View File
@@ -1,4 +1,5 @@
# Makefile for libsys
.include <bsd.own.mk>
LIB= sys
@@ -128,4 +129,8 @@ SRCS= \
CPPFLAGS.sched_start.c+= -I${MINIXSRCDIR}
.if (${NBSD_LIBC} != "no")
.include "Makefile.libc.inc"
.endif
.include <bsd.lib.mk>
+136
View File
@@ -0,0 +1,136 @@
#
# Minimal libc for servers and drivers.
#
LIBCSRCDIR=${MINIXSRCDIR}/lib/nbsd_libc
.if (${NBSD_LIBC} != "no")
MACHINE_ARCH=${MACHINE}
#
# Shared libc with userspace (/common/lib/libc)
#
.include "${MINIXSRCDIR}/common/lib/libc/Makefile.inc"
.include "${.CURDIR}/arch/${MACHINE}/Makefile.libc.inc"
.if empty(SRCS:Mbyte_swap_8.*)
SRCS+= bswap64.c
.endif
.if (${MACHINE_ARCH} != "alpha") && \
(${MACHINE_ARCH} != "mips64eb") && \
(${MACHINE_ARCH} != "mips64el") && \
(${MACHINE_ARCH} != "powerpc64") && \
(${MACHINE_ARCH} != "sparc64") && \
(${MACHINE_ARCH} != "x86_64")
# Quad support
SRCS+= adddi3.c anddi3.c ashldi3.c ashrdi3.c cmpdi2.c divdi3.c \
iordi3.c lshldi3.c lshrdi3.c moddi3.c muldi3.c negdi2.c \
notdi2.c qdivrem.c subdi3.c ucmpdi2.c udivdi3.c umoddi3.c \
xordi3.c
.endif
.for i in \
random.c strtoll.c strtoul.c strtoull.c strtoumax.c \
memchr.c memcmp.c memcpy.c memmove.c popcount32.c popcount64.c \
strcasecmp.c strcat.c strchr.c strcmp.c strcpy.c strlcat.c \
strlcpy.c strlen.c strncasecmp.c strncmp.c strncpy.c strrchr.c \
strsep.c strstr.c ptree.c rb.c sha1.c sha2.c
SRCS+= ${i}
CPPFLAGS.${i}+= -D_LIBC -I${LIBCSRCDIR}/include
.endfor
.if empty(SRCS:Mmemset2.*)
SRCS+= memset.c
.endif
#
# Customized versions of libc functions.
#
SRCS+= calloc.c malloc.c
SRCS+= fputs.c _stdfile.c
CPPFLAGS.fputs.c+= -I${LIBCSRCDIR}/include
#
# Functions imported directly from the libc.
#
# Import from stdio
.for i in sprintf.c fprintf.c perror.c vsnprintf.c snprintf.c
.PATH.c: ${LIBCSRCDIR}/stdio
CPPFLAGS.${i}= -I${LIBCSRCDIR}/stdio -I${LIBCSRCDIR}/include
SRCS+= ${i}
.endfor
# Import from stdlib
.for i in abort.c atexit.c atoi.c exit.c getenv.c \
getopt.c ldiv.c setenv.c
.PATH.c: ${LIBCSRCDIR}/stdlib
SRCS+= ${i}
CPPFLAGS.${i}+= -I${LIBCSRCDIR}/stdlib -I${LIBCSRCDIR}/include
.endfor
# Import from gen
errlist.c: ${LIBCSRCDIR}/gen/errlist-minix.awk \
${MINIXSRCDIR}/nbsd_include/sys/errno.h
${TOOL_AWK} -f ${.ALLSRC} > ${.TARGET}
.for i in assert.c _errno.c errno.c _env.c errlist.c \
execle.c getprogname.c sleep.c time.c \
ctype_.c isctype.c tolower_.c toupper_.c \
infinityf_ieee754.c infinity_ieee754.c \
fpclassifyf_ieee754.c fpclassifyd_ieee754.c \
isinff_ieee754.c isinfd_ieee754.c \
isnanf_ieee754.c isnand_ieee754.c \
isfinitef_ieee754.c isfinited_ieee754.c \
signbitf_ieee754.c signbitd_ieee754.c \
nanf.c infinityl.c
.PATH.c: ${LIBCSRCDIR}/arch/${MACHINE}/gen ${LIBCSRCDIR}/gen/minix \
${LIBCSRCDIR}/gen ${LIBCSRCDIR}
SRCS+= ${i}
CPPFLAGS.${i}+= -I${LIBCSRCDIR}/include
.endfor
CPPFLAGS.ctype_.c+= -I${LIBCSRCDIR}/locale
CPPFLAGS.isctype.c+= -I${LIBCSRCDIR}/locale
CPPFLAGS.tolower_.c+= -I${LIBCSRCDIR}/locale
CPPFLAGS.toupper_.c+= -I${LIBCSRCDIR}/locale
# Import from regex
.for i in regcomp.c regerror.c regexec.c regfree.c
.PATH.c: ${LIBCSRCDIR}/regex
SRCS+= ${i}
CPPFLAGS.${i}+= -I${LIBCSRCDIR}/include
.endfor
# Import from string
.for i in strcspn.c strerror.c strerror_r.c strtol.c \
bcmp.S bcopy.S bzero.S
.PATH.S: ${LIBCSRCDIR}/arch/${MACHINE}/string
.PATH.c: ${LIBCSRCDIR}/string
SRCS+= ${i}
CPPFLAGS.${i}+= -D_LIBC -I${LIBCSRCDIR}/include
.endfor
CPPFLAGS.strtol.c+= -I${LIBCSRCDIR}/../../common/lib/libc/stdlib
# Import from time
.for i in asctime.c localtime.c strftime.c
.PATH.c: ${LIBCSRCDIR}/time
SRCS+= ${i}
CPPFLAGS.${i}+= -I${LIBCSRCDIR}/include
.endfor
# Import from locale
.for i in _def_time.c
.PATH.c: ${LIBCSRCDIR}/locale
SRCS+= ${i}
CPPFLAGS.${i}+= -I${LIBCSRCDIR}/include -I${LIBCSRCDIR}/locale
.endfor
# Import from sys-minix
.for i in access.c brk.c close.c environ.c execve.c fork.c \
getgid.c getpid.c getuid.c gettimeofday.c loadname.c \
link.c mknod.c mmap.c nanosleep.c open.c read.c sbrk.c \
select.c setuid.c stat.c stime.c syscall.c umask.c \
unlink.c waitpid.c \
brksize.S _ipc.S _senda.S
.PATH.c: ${LIBCSRCDIR}/sys-minix
.PATH.S: ${LIBCSRCDIR}/arch/${MACHINE}/sys-minix
SRCS+= ${i}
CPPFLAGS.${i}+= -I${LIBCSRCDIR}/include
.endfor
CPPFLAGS+= -D_LIBSYS
.endif
+50
View File
@@ -0,0 +1,50 @@
/* $NetBSD: findfp.c,v 1.25 2010/09/06 14:52:55 christos Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stdio.h>
#include <unistd.h>
#define std(flags, file) \
/* p r w flags file bf lfbsize cookie close */ \
{ NULL, 0, 0, flags, file, { NULL, 0 }, 0, __sF + file, NULL, \
/* read seek write ext up */ \
NULL, NULL, NULL, { NULL, 0 }, NULL, \
/* ur ubuf, nbuf lb blksize offset */ \
0, { '\0', '\0', '\0' }, { '\0' }, { NULL, 0 }, 0, (fpos_t)0 }
FILE __sF[3] = {
std(__SRD, STDIN_FILENO), /* stdin */
std(__SWR, STDOUT_FILENO), /* stdout */
std(__SWR|__SNBF, STDERR_FILENO) /* stderr */
};
+7
View File
@@ -0,0 +1,7 @@
#include <stdlib.h>
#include <minix/sysutil.h>
void abort()
{
panic("Abort.");
}
+4
View File
@@ -0,0 +1,4 @@
SRCS+= byte_swap_2.S byte_swap_4.S ffs.S
SRCS+= memchr.S memcmp.S memcpy.S memmove.S memset.S \
strcat.S strchr.S strcmp.S strcpy.S strlen.S \
strncmp.S strrchr.S
+35
View File
@@ -4,6 +4,8 @@
#include <assert.h>
#include <stdio.h>
#ifndef __NBSD_LIBC
#include <minix/config.h>
#include <minix/const.h>
#include <minix/sysutil.h>
@@ -11,3 +13,36 @@
void __bad_assertion(const char *mess) {
panic("%s", mess);
}
#else /* NBSD_LIBC */
#include <sys/types.h>
#include <stdlib.h>
void
__assert13(file, line, function, failedexpr)
const char *file, *function, *failedexpr;
int line;
{
(void)fprintf(stderr,
"assertion \"%s\" failed: file \"%s\", line %d%s%s%s\n",
failedexpr, file, line,
function ? ", function \"" : "",
function ? function : "",
function ? "\"" : "");
abort();
/* NOTREACHED */
}
void
__assert(file, line, failedexpr)
const char *file, *failedexpr;
int line;
{
__assert13(file, line, NULL, failedexpr);
/* NOTREACHED */
}
#endif /* NBSD_LIBC */
+28
View File
@@ -0,0 +1,28 @@
/* $Header$ */
#include <stdlib.h>
/* replace undef by define */
#define ALIGN_EIGHT_BYTES /* Use 8-byte alignment. */
#ifdef ALIGN_EIGHT_BYTES
#define ALIGN_SIZE 8
#else
#define ALIGN_SIZE sizeof(size_t)
#endif
#define ALIGN(x) (((x) + (ALIGN_SIZE - 1)) & ~(ALIGN_SIZE - 1))
void *
calloc(size_t nelem, size_t elsize)
{
register char *p;
register size_t *q;
size_t size = ALIGN(nelem * elsize);
p = malloc(size);
if (p == NULL) return NULL;
q = (size_t *) (p + size);
while ((char *) q > p) *--q = 0;
return p;
}
+125
View File
@@ -0,0 +1,125 @@
/* Automatically generated file; do not edit */
#include <sys/cdefs.h>
__RCSID("$NetBSD: errlist.awk,v 1.4 2010/12/16 22:52:32 joerg Exp $");
#include <errno.h>
static const char *const errlist[] = {
[0] = "Undefined error: 0", /* 0 - ENOERROR */
[99] = "generic error", /* 99 - EGENERIC */
[1] = "operation not permitted", /* 1 - EPERM */
[2] = "no such file or directory", /* 2 - ENOENT */
[3] = "no such process", /* 3 - ESRCH */
[4] = "interrupted function call", /* 4 - EINTR */
[5] = "input/output error", /* 5 - EIO */
[6] = "no such device or address", /* 6 - ENXIO */
[7] = "arg list too long", /* 7 - E2BIG */
[8] = "exec format error", /* 8 - ENOEXEC */
[9] = "bad file descriptor", /* 9 - EBADF */
[10] = "no child process", /* 10 - ECHILD */
[11] = "resource temporarily unavailable", /* 11 - EAGAIN */
[12] = "not enough space", /* 12 - ENOMEM */
[13] = "permission denied", /* 13 - EACCES */
[14] = "bad address", /* 14 - EFAULT */
[15] = "Extension: not a block special file", /* 15 - ENOTBLK */
[16] = "resource busy", /* 16 - EBUSY */
[17] = "file exists", /* 17 - EEXIST */
[18] = "improper link", /* 18 - EXDEV */
[19] = "no such device", /* 19 - ENODEV */
[20] = "not a directory", /* 20 - ENOTDIR */
[21] = "is a directory", /* 21 - EISDIR */
[22] = "invalid argument", /* 22 - EINVAL */
[23] = "too many open files in system", /* 23 - ENFILE */
[24] = "too many open files", /* 24 - EMFILE */
[25] = "inappropriate I/O control operation", /* 25 - ENOTTY */
[26] = "no longer used", /* 26 - ETXTBSY */
[27] = "file too large", /* 27 - EFBIG */
[28] = "no space left on device", /* 28 - ENOSPC */
[29] = "invalid seek", /* 29 - ESPIPE */
[30] = "read-only file system", /* 30 - EROFS */
[31] = "too many links", /* 31 - EMLINK */
[32] = "broken pipe", /* 32 - EPIPE */
[33] = "domain error (from ANSI C std )", /* 33 - EDOM */
[34] = "result too large (from ANSI C std )", /* 34 - ERANGE */
[35] = "resource deadlock avoided", /* 35 - EDEADLK */
[36] = "file name too long", /* 36 - ENAMETOOLONG */
[37] = "no locks available", /* 37 - ENOLCK */
[38] = "function not implemented", /* 38 - ENOSYS */
[39] = "directory not empty", /* 39 - ENOTEMPTY */
[40] = "too many levels of symlinks detected", /* 40 - ELOOP */
[41] = "service restarted", /* 41 - ERESTART */
[43] = "Identifier removed", /* 43 - EIDRM */
[44] = "illegal byte sequence", /* 44 - EILSEQ */
[45] = "No message of desired type", /* 45 - ENOMSG */
[46] = "Value too large to be stored in data type",/* 46 - EOVERFLOW */
[50] = "invalid packet size for some protocol",/* 50 - EPACKSIZE */
[51] = "not enough buffers left", /* 51 - ENOBUFS */
[52] = "illegal ioctl for device", /* 52 - EBADIOCTL */
[53] = "badmode in ioctl", /* 53 - EBADMODE */
[54] = "call would block on nonblocking socket",/* 54 - EWOULDBLOCK */
[55] = "network unreachable", /* 55 - ENETUNREACH */
[56] = "host unreachable", /* 56 - EHOSTUNREACH */
[57] = "already connected", /* 57 - EISCONN */
[58] = "address in use", /* 58 - EADDRINUSE */
[59] = "connection refused", /* 59 - ECONNREFUSED */
[60] = "connection reset", /* 60 - ECONNRESET */
[61] = "connection timed out", /* 61 - ETIMEDOUT */
[62] = "urgent data present", /* 62 - EURG */
[63] = "no urgent data present", /* 63 - ENOURG */
[64] = "no connection (yet or anymore )", /* 64 - ENOTCONN */
[65] = "a write call to a shutdown connection",/* 65 - ESHUTDOWN */
[66] = "no such connection", /* 66 - ENOCONN */
[67] = "address family not supported", /* 67 - EAFNOSUPPORT */
[68] = "protocol not supported by AF", /* 68 - EPROTONOSUPPORT */
[69] = "Protocol wrong type for socket", /* 69 - EPROTOTYPE */
[70] = "Operation now in progress", /* 70 - EINPROGRESS */
[71] = "Can't assign requested address", /* 71 - EADDRNOTAVAIL */
[72] = "Connection already in progress", /* 72 - EALREADY */
[73] = "Message too long", /* 73 - EMSGSIZE */
[74] = "Socket operation on non-socket", /* 74 - ENOTSOCK */
[75] = "Protocol not available", /* 75 - ENOPROTOOPT */
[76] = "Operation not supported", /* 76 - EOPNOTSUPP */
[77] = "network is down", /* 77 - ENETDOWN */
[78] = "Protocol family not supported", /* 78 - EPFNOSUPPORT */
[79] = "Destination address required", /* 79 - EDESTADDRREQ */
[80] = "Host is down", /* 80 - EHOSTDOWN */
[81] = "Network dropped connection on reset", /* 81 - ENETRESET */
[82] = "Socket type not supported", /* 82 - ESOCKTNOSUPPORT */
[83] = "Software caused connection abort", /* 83 - ECONNABORTED */
[84] = "Too many references: can't splice", /* 84 - ETOOMANYREFS */
[101] = "can't send message due to deadlock", /* 101 - ELOCKED */
[102] = "illegal system call number", /* 102 - EBADCALL */
[103] = "bad source or destination process", /* 103 - EBADSRCDST */
[104] = "no permission for system call", /* 104 - ECALLDENIED */
[105] = "source or destination is not alive", /* 105 - EDEADSRCDST */
[106] = "source or destination is not ready", /* 106 - ENOTREADY */
[107] = "destination cannot handle request", /* 107 - EBADREQUEST */
[110] = "IPC trap not allowed", /* 110 - ETRAPDENIED */
[201] = "pseudo-code: don't send a reply", /* 201 - EDONTREPLY */
[150] = "Inappropriate file type or format", /* 150 - EFTYPE */
[151] = "Authentication error", /* 151 - EAUTH */
[152] = "Need authenticator", /* 152 - ENEEDAUTH */
[153] = "Operation canceled", /* 153 - ECANCELED */
[160] = "Stale NFS file handle", /* 160 - ESTALE */
[161] = "Too many levels of remote in path", /* 161 - EREMOTE */
[162] = "RPC struct is bad", /* 162 - EBADRPC */
[163] = "RPC version wrong", /* 163 - ERPCMISMATCH */
[164] = "RPC prog. not avail", /* 164 - EPROGUNAVAIL */
[165] = "Program version wrong", /* 165 - EPROGMISMATCH */
[166] = "Bad procedure for program", /* 166 - EPROCUNAVAIL */
[170] = "Bad or Corrupt message", /* 170 - EBADMSG */
[175] = "Too many processes", /* 175 - EPROCLIM */
[176] = "Too many users", /* 176 - EUSERS */
[177] = "Disc quota exceeded", /* 177 - EDQUOT */
[180] = "Multihop attempted ", /* 180 - EMULTIHOP */
[181] = "Link has been severed", /* 181 - ENOLINK */
[182] = "Protocol error", /* 182 - EPROTO */
[185] = "Attribute not found", /* 185 - ENOATTR */
[190] = "No message available", /* 190 - ENODATA */
[191] = "No STREAM resources", /* 191 - ENOSR */
[192] = "Not a STREAM", /* 192 - ENOSTR */
[193] = "STREAM ioctl timeout", /* 193 - ETIME */
[301] = "specified endpoint is bad", /* 301 - EBADEPT */
[302] = "specified endpoint is not alive", /* 302 - EDEADEPT */
};
const int sys_nerr = sizeof(errlist) / sizeof(errlist[0]);
const char * const *sys_errlist = errlist;
+15
View File
@@ -0,0 +1,15 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <assert.h>
#include <stdio.h>
#ifdef __weak_alias
__weak_alias(fputs, _fputs)
#endif
int fputs(const char *s, FILE *fp)
{
assert(fp == stdout || fp == stderr);
puts(s);
}
+252
View File
@@ -0,0 +1,252 @@
/* $Header$ */
/* replace undef by define */
#define ALIGN_EIGHT_BYTES /* Use 8-byte alignment. */
#define DEBUG /* check assertions */
#undef SLOWDEBUG /* some extra test loops (requires DEBUG) */
#ifndef DEBUG
#define NDEBUG
#endif
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
static int no_debug = -1;
#define CHECK_DBG(statement)
#if _EM_WSIZE == _EM_PSIZE
#define ptrint int
#else
#define ptrint long
#endif
#if _EM_PSIZE == 2
#define BRKSIZE 1024
#else
#define BRKSIZE 4096
#endif
#ifdef ALIGN_EIGHT_BYTES
#define PTRSIZE 8
#else
#define PTRSIZE ((int) sizeof(void *))
#endif
#define Align(x,a) (((x) + (a - 1)) & ~(a - 1))
#define NextSlot(p) (* (void **) ((p) - PTRSIZE))
#define NextFree(p) (* (void **) (p))
/*
* A short explanation of the data structure and algorithms.
* An area returned by malloc() is called a slot. Each slot
* contains the number of bytes requested, but preceeded by
* an extra pointer to the next the slot in memory.
* '_bottom' and '_top' point to the first/last slot.
* More memory is asked for using brk() and appended to top.
* The list of free slots is maintained to keep malloc() fast.
* '_empty' points the the first free slot. Free slots are
* linked together by a pointer at the start of the
* user visable part, so just after the next-slot pointer.
* Free slots are merged together by free().
*
* Since modern processors prefer 8-byte alignment, we now pretend
* our pointers are 8 bytes wide.
*/
extern void *_sbrk(int);
extern int _brk(void *);
static void *_bottom, *_top, *_empty;
static int grow(size_t len)
{
register char *p;
assert(NextSlot((char *)_top) == 0);
if ((char *) _top + len < (char *) _top
|| (p = (char *)Align((ptrint)_top + len, BRKSIZE)) < (char *) _top ) {
errno = ENOMEM;
return(0);
}
if (_brk(p) != 0)
return(0);
NextSlot((char *)_top) = p;
NextSlot(p) = 0;
free(_top);
_top = p;
return 1;
}
void *
malloc(const size_t size)
{
register char *prev, *p, *next, *new;
unsigned ntries;
if (size == 0)
return NULL;
CHECK_DBG(return _dbg_malloc(size));
for (ntries = 0; ntries < 2; ntries++) {
unsigned len = Align(size, PTRSIZE) + PTRSIZE;
if (len < 2 * PTRSIZE) {
errno = ENOMEM;
return NULL;
}
if (_bottom == 0) {
if ((p = _sbrk(2 * PTRSIZE)) == (char *) -1)
return NULL;
p = (char *) Align((ptrint)p, PTRSIZE);
p += PTRSIZE;
_top = _bottom = p;
NextSlot(p) = 0;
}
#ifdef SLOWDEBUG
for (p = _bottom; (next = NextSlot(p)) != 0; p = next)
assert(next > p);
assert(p == _top);
#endif
for (prev = 0, p = _empty; p != 0; prev = p, p = NextFree(p)) {
next = NextSlot(p);
new = p + len; /* easily overflows!! */
if (new > next || new <= p)
continue; /* too small */
if (new + PTRSIZE < next) { /* too big, so split */
/* + PTRSIZE avoids tiny slots on free list */
NextSlot(new) = next;
NextSlot(p) = new;
NextFree(new) = NextFree(p);
NextFree(p) = new;
}
if (prev)
NextFree(prev) = NextFree(p);
else
_empty = NextFree(p);
return p;
}
if (grow(len) == 0)
break;
}
assert(ntries != 2);
return NULL;
}
void *
realloc(void *oldp, size_t size)
{
register char *prev, *p, *next, *new;
char *old = oldp;
register size_t len, n;
if (old == 0)
return malloc(size);
if (size == 0) {
free(old);
return NULL;
}
CHECK_DBG(return _dbg_realloc(oldp, size));
len = Align(size, PTRSIZE) + PTRSIZE;
next = NextSlot(old);
n = (int)(next - old); /* old length */
/*
* extend old if there is any free space just behind it
*/
for (prev = 0, p = _empty; p != 0; prev = p, p = NextFree(p)) {
if (p > next)
break;
if (p == next) { /* 'next' is a free slot: merge */
NextSlot(old) = NextSlot(p);
if (prev)
NextFree(prev) = NextFree(p);
else
_empty = NextFree(p);
next = NextSlot(old);
break;
}
}
new = old + len;
/*
* Can we use the old, possibly extended slot?
*/
if (new <= next && new >= old) { /* it does fit */
if (new + PTRSIZE < next) { /* too big, so split */
/* + PTRSIZE avoids tiny slots on free list */
NextSlot(new) = next;
NextSlot(old) = new;
free(new);
}
return old;
}
if ((new = malloc(size)) == NULL) /* it didn't fit */
return NULL;
memcpy(new, old, n); /* n < size */
free(old);
return new;
}
void
free(void *ptr)
{
register char *prev, *next;
char *p = ptr;
if (p == 0)
return;
CHECK_DBG(_dbg_free(ptr); return);
#ifdef SLOWDEBUG
{
int found;
char *curr;
/* block must be in block list */
assert(_bottom);
found = 0;
for (curr = _bottom; (next = NextSlot(curr)) != 0; curr = next) {
assert(next > curr);
if (curr == p) found = 1;
}
if (curr == p) found = 1;
assert(found);
/* block must not be in free list */
if (_empty) {
found = 0;
for (curr = _empty; (next = NextFree(curr)) != 0; curr = next) {
assert(next > curr);
if (curr == p) found = 1;
}
if (curr == p) found = 1;
assert(!found);
}
}
#endif
assert((char *) NextSlot(p) > p);
for (prev = 0, next = _empty; next != 0; prev = next, next = NextFree(next))
if (p < next)
break;
NextFree(p) = next;
if (prev)
NextFree(prev) = p;
else
_empty = p;
if (next) {
assert((char *) NextSlot(p) <= next);
if (NextSlot(p) == next) { /* merge p and next */
NextSlot(p) = NextSlot(next);
NextFree(p) = NextFree(next);
}
}
if (prev) {
assert((char *) NextSlot(prev) <= p);
if (NextSlot(prev) == p) { /* merge prev and p */
NextSlot(prev) = NextSlot(p);
NextFree(prev) = NextFree(p);
}
}
}
+2
View File
@@ -41,8 +41,10 @@ PUBLIC void panic(const char *fmt, ...)
/* Try exit */
_exit(1);
#ifndef __NBSD_LIBC
/* Try to signal ourself */
abort();
#endif
/* If exiting nicely through PM fails for some reason, try to
* commit suicide. E.g., message to PM might fail due to deadlock.
+48
View File
@@ -7,9 +7,15 @@
/* vprintf() uses kputc() to print characters. */
void kputc(int c);
#ifdef __NBSD_LIBC
#define count_kputc(c) do { charcount++; putf((c), farg); } while(0)
int __fvprintf(void (*putf)(int, void *), const char *fmt, va_list argp, void *farg)
#else /* !NBSD_LIBC */
#define count_kputc(c) do { charcount++; kputc(c); } while(0)
int vprintf(const char *fmt, va_list argp)
#endif /* NBSD_LIBC */
{
int c, charcount = 0;
enum { LEFT, RIGHT } adjust;
@@ -167,10 +173,52 @@ int vprintf(const char *fmt, va_list argp)
}
/* Mark the end with a null (should be something else, like -1). */
#ifdef __NBDS_LIBC
putf(0, farg);
#else
kputc(0);
#endif
return charcount;
}
#ifdef __NBSD_LIBC
#include <sys/cdefs.h>
#include <assert.h>
#include <unistd.h>
#include <stdio.h>
__weak_alias(vprintf, _vprintf)
__weak_alias(vfprintf, _vfprintf)
__strong_alias(__vfprintf_unlocked, _vfprintf)
static void
__xfputc(int c, void *arg)
{
FILE *fp = (FILE *)arg;
if (fp->_flags & __SSTR) {
/* Write to a string. */
if (fp->_w == 0)
return;
memset(fp->_p++, c, 1);
fp->_w -= 1;
return;
}
/* Not a string. Print it. */
kputc(c);
}
int _vprintf(const char *fmt, va_list argp)
{
__fvprintf(__xfputc, fmt, argp, stdout);
}
int _vfprintf(FILE *fp, const char *fmt, va_list argp)
{
__fvprintf(__xfputc, fmt, argp, fp);
}
#endif
/*
* $PchId: kprintf.c,v 1.5 1996/04/11 06:59:05 philip Exp $
*/