+VERSION := $(shell cat version)
SUBDIRS = klibc
all:
+rpmbuild = $(shell which rpmbuild 2>/dev/null || which rpm)
+
+klibc.spec: klibc.spec.in version
+ sed -e 's/@@VERSION@@/$(VERSION)/g' < $< > $@
+
+.PHONY: rpm
+rpm: klibc.spec
+ +$(rpmbuild) -bb klibc.spec
+
%:
@set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
+
+clean:
+ @set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
+
+spotless:
+ @set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
+ rm -f klibc.spec *~ tags
tests/%.o : tests/%.c
$(CC) $(CFLAGS) -c -o $@ $<
+# This particular file uses a bunch of formats gcc don't know of, in order
+# to test the full range of our vsnprintf() function. This outputs a bunch
+# of useless warnings unless we tell it not to.
+tests/testvsnp.o : tests/testvsnp.c
+ $(CC) $(CFLAGS) -Wno-format -c -o $@ $<
+
tests/% : tests/%.o $(LIB) $(CRT0)
$(LD) $(LDFLAGS) -o $@ $(CRT0) $< $(LIB) $(LIBGCC)
cp $@ $@.stripped
find . \( -name \*~ -o -name '.*.d' \) -not -type d -print0 | \
xargs -0rt rm -f
+bitsize:
+ @echo $(BITSIZE)
+
ifneq ($(wildcard $(DIR)/.*.d),)
include $(wildcard $(DIR)/.*.d)
endif
int chmod(const char *, mode_t)
int mkdir(const char *, mode_t)
int rmdir(const char *)
-<!alpha,mips,mips64> int pipe(int *)
+<!alpha,ia64,mips,mips64> int pipe(int *)
mode_t umask(mode_t)
int chroot(const char *)
int symlink(const char *, const char *)
int uname(struct utsname *)
int setdomainname(const char *, size_t)
int sethostname(const char *, size_t)
-int init_module(const char *, struct module *)
-<!ia64> void * create_module(const char *, size_t)
-int delete_module(const char *)
+long init_module(void *, unsigned long, const char *)
+long delete_module(const char *, unsigned int)
<!ia64> int query_module(const char *, int, void *, size_t, size_t)
int reboot::__reboot(int, int, int, void *)
int syslog::klogctl(int, char *, int)
#ifndef _KLIBC_ARCHSIGNAL_H
#define _KLIBC_ARCHSIGNAL_H
-typedef int sig_atomic_t;
+/* No special stuff for this architecture */
#endif
ARCHOBJS = \
arch/$(ARCH)/vfork.o \
- arch/$(ARCH)/setjmp.o
+ arch/$(ARCH)/setjmp.o \
+ arch/$(ARCH)/pipe.o \
+ libgcc/__divdi3.o \
+ libgcc/__divsi3.o \
+ libgcc/__udivdi3.o \
+ libgcc/__udivsi3.o \
+ libgcc/__umodsi3.o \
+ libgcc/__umoddi3.o \
+ libgcc/__udivmodsi4.o \
+ libgcc/__udivmoddi4.o
ARCHSOOBJS = $(patsubst %o,%.lo,%(ARCHOBJS))
#define sa_handler _u._sa_handler
#define sa_sigaction _u._sa_sigaction
-typedef int sig_atomic_t;
-
#endif
--- /dev/null
+/*
+ * pipe.c
+ */
+
+#include "syscommon.h"
+#include <klibc/archsys.h>
+
+#define ASM_CLOBBERS ,"out2", "out3", "out4", "out5", "out6", "out7", \
+ /* Non-stacked integer registers, minus r8, r9, r10, r15. */ \
+ "r2", "r3", "r11", "r12", "r13", "r14", "r16", "r17", "r18", \
+ "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", \
+ "r28", "r29", "r30", "r31", \
+ /* Predicate registers. */ \
+ "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", \
+ /* Non-rotating fp registers. */ \
+ "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
+ /* Branch registers. */ \
+ "b6", "b7"
+
+int pipe(int *filedes)
+{
+ register long _r8 asm("r8");
+ register long _r9 asm("r9");
+ register long _r10 asm("r10");
+ register long _r15 asm("r15") = __NR_pipe;
+ register long _out0 asm ("out0") = (long)filedes;
+ long _retval;
+ __asm __volatile (__IA64_BREAK
+ : "=r" (_r8), "=r" (_r10), "=r" (_r15),
+ "=r" (_out0)
+ : "2" (_r15), "3" (_out0)
+ : "memory" ASM_CLOBBERS);
+ if (_r10 == -1) {
+ errno = _r8;
+ _retval = -1;
+ } else {
+ filedes[0] = _r8;
+ filedes[1] = _r9;
+ _retval = 0;
+ }
+ return _retval;
+}
#
ARCHOBJS = \
- arch/$(ARCH)/setjmp.o
+ arch/$(ARCH)/setjmp.o \
+ libgcc/__divdi3.o \
+ libgcc/__moddi3.o \
+ libgcc/__udivdi3.o \
+ libgcc/__umoddi3.o \
+ libgcc/__udivmoddi4.o
+
ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS))
#
# arch/ppc/crt0.S
-#
-# void _start(void)
-# {
-# /* Divine up argc, argv, and envp */
-# environ = envp;
-# exit(main(argc, argv, envp));
-# }
#
.text
.type _start,@function
.globl _start
_start:
- lwz 3,0(1)
- addi 4,1,4
- addi 5,1,8
- slwi 0,3,2
- add 5,5,0
- li 0,0
- stwu 0,-16(1)
- lis 9,environ@ha
- stw 5,environ@l(9)
- bl main
- bl exit
+ stwu 1,-16(1)
+ addi 3,1,16
+ /*
+ * the SVR4abippc.pdf specifies r7 as a pointer to
+ * a termination function pointer.
+ * It is unused on Linux.
+ */
+ mr 4,7
+ bl __libc_init
.size _start,.-_start
# accordingly.
#
+ARCHOBJS = \
+ arch/$(ARCH)/setjmp.o
+
+ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS))
+
archclean:
.globl ._start
.type ._start,@function
._start:
- ld 3,0(1)
- ld 4,8(1)
- ld 5,16(1)
- li 0,0
- stdu 0,-64(1)
- ld 9,.LC0@toc(2)
- std 5,0(9)
- bl .main
- nop
- bl .exit
+ stdu %r1,-32(%r1)
+ addi %r3,%r1,32
+ mr %r4,%r7 /* fini */
+ b .__libc_init
nop
.size _start,.-_start
--- /dev/null
+/*
+ * arch/ppc64/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+ unsigned long __r2;
+ unsigned long __sp;
+ unsigned long __lr;
+ unsigned long __cr;
+ unsigned long __r13;
+ unsigned long __r14;
+ unsigned long __r15;
+ unsigned long __r16;
+ unsigned long __r17;
+ unsigned long __r18;
+ unsigned long __r19;
+ unsigned long __r20;
+ unsigned long __r21;
+ unsigned long __r22;
+ unsigned long __r23;
+ unsigned long __r24;
+ unsigned long __r25;
+ unsigned long __r26;
+ unsigned long __r27;
+ unsigned long __r28;
+ unsigned long __r29;
+ unsigned long __r30;
+ unsigned long __r31;
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _SETJMP_H */
--- /dev/null
+#
+# arch/ppc64/setjmp.S
+#
+# Basic setjmp/longjmp implementation
+# This file was derived from the equivalent file in NetBSD
+#
+
+ .text
+ .align 4
+
+ .section ".opd","aw"
+setjmp:
+ .quad .setjmp,.TOC.@tocbase,0
+ .previous
+ .size setjmp,24
+ .type .setjmp,@function
+ .globl setjmp
+ .globl .setjmp
+.setjmp:
+ mflr %r11 /* save return address */
+ mfcr %r12 /* save condition register */
+ mr %r10,%r1 /* save stack pointer */
+ mr %r9,%r2 /* save GPR2 (not needed) */
+ stmw %r9,0(%r3) /* save r9..r31 */
+ li %r3,0 /* indicate success */
+ blr /* return */
+
+ .size .setjmp,.-.setjmp
+ .section ".opd","aw"
+longjmp:
+ .quad .longjmp,.TOC.@tocbase,0
+ .previous
+ .size longjmp,24
+ .type .longjmp,@function
+ .globl longjmp
+ .globl .longjmp
+.longjmp:
+ lmw %r9,0(%r3) /* save r9..r31 */
+ mtlr %r11 /* restore LR */
+ mtcr %r12 /* restore CR */
+ mr %r2,%r9 /* restore GPR2 (not needed) */
+ mr %r1,%r10 /* restore stack */
+ mr %r3,%r4 /* get return value */
+ blr /* return */
+
+ .size .longjmp,.-.longjmp
#
ARCHOBJS = \
- arch/$(ARCH)/setjmp.o
+ arch/$(ARCH)/setjmp.o \
+ libgcc/__divdi3.o \
+ libgcc/__moddi3.o \
+ libgcc/__udivdi3.o \
+ libgcc/__umoddi3.o \
+ libgcc/__udivmoddi4.o
ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS))
# define __unlikely(x) (x)
#endif
+/* Possibly unused function */
+#ifdef __GNUC__
+# define __unusedfunc __attribute__((unused))
+#else
+# define __unusedfunc
+#endif
+
#endif
#include <klibc/archsignal.h>
+/* glibc seems to use sig_atomic_t as "int" pretty much on all architectures.
+ Do the same, but allow the architecture to override. */
+#ifdef _KLIBC_HAS_ARCH_SIG_ATOMIC_T
+typedef int sig_atomic_t;
+#endif
+
/* Some architectures don't define these */
#ifndef SA_RESETHAND
# define SA_RESETHAND SA_ONESHOT
__extern size_t _fwrite(const void *, size_t, FILE *);
#ifndef __NO_FREAD_FWRITE_INLINES
-static __inline__ size_t
+extern __inline__ size_t
fread(void *__p, size_t __s, size_t __n, FILE *__f)
{
return _fread(__p, __s*__n, __f)/__s;
}
-static __inline__ size_t
+
+extern __inline__ size_t
fwrite(void *__p, size_t __s, size_t __n, FILE *__f)
{
return _fwrite(__p, __s*__n, __f)/__s;
+++ /dev/null
-/*
- * sys/module.h
- *
- * This is a bastardized version of linux/module.h, since the latter
- * doesn't have __KERNEL__ guards where it needs them...
- */
-
-#ifndef _SYS_MODULE_H
-#define _SYS_MODULE_H
-
-/*
- * Dynamic loading of modules into the kernel.
- *
- * Rewritten by Richard Henderson <rth@tamu.edu> Dec 1996
- */
-
-#include <asm/atomic.h>
-
-/* Don't need to bring in all of uaccess.h just for this decl. */
-struct exception_table_entry;
-
-/* Used by get_kernel_syms, which is obsolete. */
-struct kernel_sym
-{
- unsigned long value;
- char name[60]; /* should have been 64-sizeof(long); oh well */
-};
-
-struct module_symbol
-{
- unsigned long value;
- const char *name;
-};
-
-struct module_ref
-{
- struct module *dep; /* "parent" pointer */
- struct module *ref; /* "child" pointer */
- struct module_ref *next_ref;
-};
-
-/* TBD */
-struct module_persist;
-
-struct module
-{
- unsigned long size_of_struct; /* == sizeof(module) */
- struct module *next;
- const char *name;
- unsigned long size;
-
- union
- {
- atomic_t usecount;
- long pad;
- } uc; /* Needs to keep its size - so says rth */
-
- unsigned long flags; /* AUTOCLEAN et al */
-
- unsigned nsyms;
- unsigned ndeps;
-
- struct module_symbol *syms;
- struct module_ref *deps;
- struct module_ref *refs;
- int (*init)(void);
- void (*cleanup)(void);
- const struct exception_table_entry *ex_table_start;
- const struct exception_table_entry *ex_table_end;
-#ifdef __alpha__
- unsigned long gp;
-#endif
- /* Members past this point are extensions to the basic
- module support and are optional. Use mod_member_present()
- to examine them. */
- const struct module_persist *persist_start;
- const struct module_persist *persist_end;
- int (*can_unload)(void);
- int runsize; /* In modutils, not currently used */
- const char *kallsyms_start; /* All symbols for kernel debugging */
- const char *kallsyms_end;
- const char *archdata_start; /* arch specific data for module */
- const char *archdata_end;
- const char *kernel_data; /* Reserved for kernel internal use */
-};
-
-struct module_info
-{
- unsigned long addr;
- unsigned long size;
- unsigned long flags;
- long usecount;
-};
-
-/* Bits of module.flags. */
-
-#define MOD_UNINITIALIZED 0
-#define MOD_RUNNING 1
-#define MOD_DELETED 2
-#define MOD_AUTOCLEAN 4
-#define MOD_VISITED 8
-#define MOD_USED_ONCE 16
-#define MOD_JUST_FREED 32
-#define MOD_INITIALIZING 64
-
-/* Values for query_module's which. */
-
-#define QM_MODULES 1
-#define QM_DEPS 2
-#define QM_REFS 3
-#define QM_SYMBOLS 4
-#define QM_INFO 5
-
-/* Can the module be queried? */
-#define MOD_CAN_QUERY(mod) (((mod)->flags & (MOD_RUNNING | MOD_INITIALIZING)) && !((mod)->flags & MOD_DELETED))
-
-/* When struct module is extended, we must test whether the new member
- is present in the header received from insmod before we can use it.
- This function returns true if the member is present. */
-
-#define mod_member_present(mod,member) \
- ((unsigned long)(&((struct module *)0L)->member + 1) \
- <= (mod)->size_of_struct)
-
-/*
- * Ditto for archdata. Assumes mod->archdata_start and mod->archdata_end
- * are validated elsewhere.
- */
-#define mod_archdata_member_present(mod, type, member) \
- (((unsigned long)(&((type *)0L)->member) + \
- sizeof(((type *)0L)->member)) <= \
- ((mod)->archdata_end - (mod)->archdata_start))
-
-
-/* Check if an address p with number of entries n is within the body of module m */
-#define mod_bound(p, n, m) ((unsigned long)(p) >= ((unsigned long)(m) + ((m)->size_of_struct)) && \
- (unsigned long)((p)+(n)) <= (unsigned long)(m) + (m)->size)
-
-/* Backwards compatibility definition. */
-
-#define GET_USE_COUNT(module) (atomic_read(&(module)->uc.usecount))
-
-/* Poke the use count of a module. */
-
-#define __MOD_INC_USE_COUNT(mod) \
- (atomic_inc(&(mod)->uc.usecount), (mod)->flags |= MOD_VISITED|MOD_USED_ONCE)
-#define __MOD_DEC_USE_COUNT(mod) \
- (atomic_dec(&(mod)->uc.usecount), (mod)->flags |= MOD_VISITED)
-#define __MOD_IN_USE(mod) \
- (mod_member_present((mod), can_unload) && (mod)->can_unload \
- ? (mod)->can_unload() : atomic_read(&(mod)->uc.usecount))
-
-/* Indirect stringification. */
-
-#define __MODULE_STRING_1(x) #x
-#define __MODULE_STRING(x) __MODULE_STRING_1(x)
-
-#endif /* _SYS_MODULE_H */
for (i = 0; i < NUM_PORTS; i++, port++) {
sin->sin_port = htons(port);
- if ((ret = bind(sd, sin, sizeof(*sin))) != -1)
+ if ((ret = bind(sd, (struct sockaddr *)&sin, sizeof(*sin))) != -1)
break;
if (port == END_PORT)
port = START_PORT;
* Prefer mmap2() over mmap(), except on the architectures listed
*/
-#if defined(__NR_mmap2) && !defined(__sparc__) && !defined(__ia64__)
+#if defined(__NR_mmap2) && !defined(__sparc__) && !defined(__ia64__) && !defined(__powerpc64__)
/* This architecture uses mmap2() */
/*
* strcasecmp.c
- *
*/
#include <string.h>
int strcasecmp(const char *s1, const char *s2)
{
- char *n1, *n2;
- int i, retval;
+ const unsigned char *c1 = s1, *c2 = s2;
+ unsigned char ch;
+ int d = 0;
- n1 = strdup(s1);
- n2 = strdup(s2);
+ while ( 1 ) {
+ /* toupper() expects an unsigned char (implicitly cast to int)
+ as input, and returns an int, which is exactly what we want. */
+ d = toupper(ch = *c1++) - toupper(*c2++);
+ if ( d || !ch )
+ break;
+ }
- for (i = 0; i < strlen(n1); i++)
- n1[i] = toupper(n1[i]);
- for (i = 0; i < strlen(n2); i++)
- n2[i] = toupper(n2[i]);
- retval = strcmp(n1, n2);
- free(n1);
- free(n2);
- return retval;
+ return d;
}
char numbuf[32];
char *p;
- int len;
p = numbuf+sizeof numbuf;
*--p = '\0';
int strncasecmp(const char *s1, const char *s2, size_t n)
{
- char *n1, *n2;
- int i, retval;
+ const unsigned char *c1 = s1, *c2 = s2;
+ unsigned char ch;
+ int d = 0;
- n1 = strndup(s1, n);
- n2 = strndup(s2, n);
+ while ( n-- ) {
+ /* toupper() expects an unsigned char (implicitly cast to int)
+ as input, and returns an int, which is exactly what we want. */
+ d = toupper(ch = *c1++) - toupper(*c2++);
+ if ( d || !ch )
+ break;
+ }
- for (i = 0; i < strlen(n1); i++)
- n1[i] = toupper(n1[i]);
- for (i = 0; i < strlen(n2); i++)
- n2[i] = toupper(n2[i]);
- retval = strcmp(n1, n2);
- free(n1);
- free(n2);
- return retval;
+ return d;
}
int d = 0;
while ( n-- ) {
- d = (int)*c2++ - (int)(ch = *c1++);
+ d = (int)(ch = *c1++) - (int)*c2++;
if ( d || !ch )
break;
}
#include <sys/dirent.h>
#include <sys/klog.h>
#include <sys/mman.h>
-#include <sys/module.h>
#include <sys/resource.h>
#include <sys/select.h>
#include <sys/stat.h>
int i;
int r;
- for(i = 0; i < sizeof(t1); i++)
+ for(i = 0; i < (int)sizeof(t1); i++)
t1[i] = t2[i] = (unsigned char)i;
r = memcmp(t1, t2, sizeof(t1));
r = memcmp(t1, t2, sizeof(t1));
printf("memcmp r = %d\n", r);
- for (i = 0; i < sizeof(t1); i++)
+ for (i = 0; i < (int)sizeof(t1); i++)
t1[i] = 0xaa;
memset(t2, 0xaa, sizeof(t2));
r = memcmp(t1, t2, sizeof(t1));
);
break;
default:
+ break;
}
if(show_args) printf(" [%s]\n", P_cmd);
else printf(" %s\n", P_cmd);