$(INSTALL_DATA) klcc.1 $(INSTALLROOT)$(mandir)/man1/$(KCROSS)klcc.1
$(INSTALL_EXEC) $(KCROSS)klcc $(INSTALLROOT)$(bindir)
+# This does all the prep work needed to turn a freshly exported git repository
+# into a release tarball tree
+release: klibc.spec
+ rm -f maketar.sh
+
-include MCONFIG
--- /dev/null
+#include <linux/if_packet.h>
__extern int sigprocmask(int, const sigset_t *, sigset_t *);
__extern int sigpending(sigset_t *);
__extern int sigsuspend(const sigset_t *);
-__extern int rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t);
-__extern int rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t);
-__extern int rt_sigpending(sigset_t *, size_t);
-__extern int rt_sigsuspend(const sigset_t *, size_t);
__extern int raise(int);
__extern int kill(pid_t, int);
-.\" $Id: klcc.1,v 1.2 2005/03/02 02:24:17 hpa Exp $
+.\" $Id: klcc.1,v 1.3 2005/04/19 23:27:46 hpa Exp $
.\" -----------------------------------------------------------------------
.\"
.\" Copyright 2005 H. Peter Anvin - All Rights Reserved
.B klcc
is a wrapper around
.BR gcc (1)
-to compile a program against the
+and
+.BR ld (1)
+which compiles and links a program against the
.B klibc
tiny C library. It supports most
.B gcc
option to use the default optimization level; this will generally
result in the smallest binaries. You may want to use
.B \-s
-when linking, however.
+when linking, however. Use
+.B \-O0
+to compile without any optimization whatsoever; this may not work depending
+on the version of
+.B gcc
+used.
.PP
Use the
.B \-shared
option to compile for and link against shared or static klibc. Note
that shared klibc only supports running against the exact same klibc
binary as the binary was linked with.
+.PP
+In addition to standard
+.B gcc
+options,
+.B klcc
+supports options of the form \fB\-print-klibc-\fP\fIoption\fP,
+which prints the corresponding klibc configuration option.
.SH AUTHOR
Written by H. Peter Anvin <hpa@zytor.com>.
.SH COPYRIGHT
-Copyright \(co 2005 H. Peter Anvin.
+Copyright \(co 2005 H. Peter Anvin \- All Rights Reserved
+.PP
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following
+conditions:
+.PP
+The above copyright notice and this permission notice shall
+be included in all copies or substantial portions of the Software.
+.PP
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
.SH "SEE ALSO"
.BR gcc (1)
# -*- perl -*-
+use IPC::Open3;
+
# Standard includes
@includes = ("-I${prefix}/${KCROSS}include/arch/${ARCH}",
"-I${prefix}/${KCROSS}include/bits${BITSIZE}",
# Skip object files
if ( $need ne 'obj' ) {
- unless ( $xopt eq $need ) {
+ unless ( $xopt eq $need || $need eq 'stdin') {
push(@as, '-x', $need);
$xopt = $need;
}
# Run a program; printing out the command line if $verbose is set
sub mysystem(@) {
print STDERR join(' ', @_), "\n" if ( $verbose );
- return system(@_);
+ my $cmd = shift;
+ open(INPUT, "<&STDIN"); # dup STDIN filehandle to INPUT
+ my $childpid = open3("<&INPUT", ">&STDOUT", ">&STDERR", $cmd, @_);
+ waitpid ($childpid, 0);
+ return $?;
}
#
# Not an option. Must be a filename then.
push(@files, $a);
$flang{$a} = $lang || filename2lang($a);
+ } elsif ( $a eq '-' ) {
+ # gcc gets its input from stdin
+ push(@files, $a);
+ # prevent setting -x
+ $flang{$a} = 'stdin'
} elsif ( $a =~ /^-print-klibc-(.*)$/ ) {
# This test must precede -print
if ( defined($conf{$1}) ) {
;
; Signal operations
;
-int kill(pid_t, int)
; We really should get rid of the non-rt_* of these, but that takes
-; sanitizing <signal.h> for all architectures, sigh...
-<?> int sigaction(int, const struct sigaction *, struct sigaction *)
-<?> int sigsuspend(const sigset_t *)
-<?> int sigpending(sigset_t *)
-<?> int sigprocmask(int, const sigset_t *, sigset_t *)
-int rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t)
-int rt_sigsuspend(const sigset_t *, size_t)
-int rt_sigpending(sigset_t *, size_t)
-int rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t)
+; sanitizing <signal.h> for all architectures, sigh.
+#ifdef __NR_sigaction
+int sigaction::__sigaction(int, const struct sigaction *, struct sigaction *)
+#else
+int rt_sigaction::__rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t)
+#endif
+#ifdef __NR_sigsuspend
+int sigsuspend(const sigset_t *)
+#else
+int rt_sigsuspend::__rt_sigsuspend(const sigset_t *, size_t)
+#endif
+#ifdef __NR_sigpending
+int sigpending(sigset_t *)
+#else
+int rt_sigpending::__rt_sigpending(sigset_t *, size_t)
+#endif
+#ifdef __NR_sigprocmask
+int sigprocmask(int, const sigset_t *, sigset_t *)
+#else
+int rt_sigprocmask::__rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t)
+#endif
+int kill(pid_t, int)
<?> unsigned int alarm(unsigned int)
int getitimer(int, struct itimerval *)
int setitimer(int, const struct itimerval *, struct itimerval *)
arch/$(ARCH)/setjmp.o \
arch/$(ARCH)/syscall.o \
arch/$(ARCH)/open.o \
+ arch/$(ARCH)/sigreturn.o \
arch/$(ARCH)/libgcc/__ashldi3.o \
arch/$(ARCH)/libgcc/__ashrdi3.o \
arch/$(ARCH)/libgcc/__lshrdi3.o \
# debugging using gdb.
#
ARCHREQFLAGS = -m64
+ifeq ($(DEBUG),y)
+OPTFLAGS = -Os -fomit-frame-pointer \
+ -falign-functions=0 -falign-jumps=0 -falign-loops=0
+else
OPTFLAGS = -Os -fno-asynchronous-unwind-tables -fomit-frame-pointer \
-falign-functions=0 -falign-jumps=0 -falign-loops=0
+endif
BITSIZE = 64
LDFLAGS = -m elf_x86_64
ARCHOBJS = \
arch/$(ARCH)/exits.o \
arch/$(ARCH)/setjmp.o \
- arch/$(ARCH)/syscall.o
+ arch/$(ARCH)/syscall.o \
+ arch/$(ARCH)/sigreturn.o
ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS))
syscall
cmpq $-4095,%rax
- jb 1f
+ jnb 1f
+ ret
# Error return, must set errno
+1:
negl %eax
movl %eax,errno(%rip) # errno is type int, so 32 bits
orq $-1,%rax # orq $-1 smaller than movq $-1
-
-1:
ret
.size __syscall_common,.-__syscall_common
return NULL;
}
*p++ = ch;
+ n--;
if ( ch == '\n' )
break;
}
#include <signal.h>
#include <sys/syscall.h>
-#ifndef __NR_sigaction
+__extern void __sigreturn(void);
+__extern int __sigaction(int, const struct sigaction *, struct sigaction *);
+__extern int __rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t);
int sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
{
- return rt_sigaction(sig, act, oact, sizeof(sigset_t));
-}
+ int rv;
+
+#if defined(__i386__) || defined(__x86_64__)
+ /* x86-64, and the Fedora i386 kernel, are broken without SA_RESTORER */
+ struct sigaction sa;
+
+ if ( act && !(act->sa_flags & SA_RESTORER) ) {
+ sa = *act;
+ act = &sa;
+
+ /* The kernel can't be trusted to have a valid default restorer */
+ sa.sa_flags |= SA_RESTORER;
+ sa.sa_restorer = &__sigreturn;
+ }
+#endif
+#ifdef __NR_sigaction
+ rv = __sigaction(sig, act, oact);
+#else
+ rv = __rt_sigaction(sig, act, oact, sizeof(sigset_t));
#endif
+
+
+#if defined(__i386__) || defined(__x86_64__)
+ if ( oact && (oact->sa_restorer == &__sigreturn) ) {
+ oact->sa_flags &= ~SA_RESTORER;
+ }
+#endif
+
+ return rv;
+}
#ifndef __NR_sigpending
+__extern __rt_sigpending(sigset_t *, size_t);
+
int sigpending(sigset_t *set)
{
- return rt_sigpending(set, sizeof(sigset_t));
+ return __rt_sigpending(set, sizeof(sigset_t));
}
#endif
#ifndef __NR_sigprocmask
+__extern __rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t);
+
int sigprocmask(int how, const sigset_t *set, sigset_t *oset)
{
- return rt_sigprocmask(how, set, oset, sizeof(sigset_t));
+ return __rt_sigprocmask(how, set, oset, sizeof(sigset_t));
}
#endif
#ifndef __NR_sigsuspend
+__extern int __rt_sigsuspend(const sigset_t *, size_t);
+
int sigsuspend(const sigset_t *mask)
{
- return rt_sigsuspend(mask, sizeof *mask);
+ return __rt_sigsuspend(mask, sizeof *mask);
}
#endif
}
/* Single optional + or - */
- if ( n && *nptr == '-' ) {
- minus = 1;
- nptr++;
- n--;
- } else if ( n && *nptr == '+' ) {
- nptr++;
+ if ( n ) {
+ char c = *nptr;
+ if ( c == '-' || c == '+' ) {
+ minus = (c == '-');
+ nptr++;
+ n--;
+ }
}
if ( base == 0 ) {