aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2006-06-10 11:15:19 -0700
committerH. Peter Anvin <hpa@zytor.com>2006-06-10 11:15:19 -0700
commitde6f630e6be90d6d32d8bf2fed3f856b0c32f7ba (patch)
tree7b093d5ec68a2bf5553cc5b1d26f640daa1a0a41
parent034c1a00496805534c988398b7bf55e6aa68e2f6 (diff)
downloadklibc-de6f630e6be90d6d32d8bf2fed3f856b0c32f7ba.tar.gz
[klibc] Detect the sizes of various types, and make available to sysstub.ph.
This additional code effectively queries the C compiler for the sizes of various types, and makes an associative array %typesize available to sysstub.ph. This is currently not used, but it's expected that some architectures, e.g. s390, will need this to determine which registers go where, and how many registers are needed. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--usr/klibc/syscalls.pl125
-rw-r--r--usr/klibc/syscalls/Kbuild42
-rw-r--r--usr/klibc/syscalls/syscommon.h (renamed from usr/klibc/syscommon.h)1
3 files changed, 147 insertions, 21 deletions
diff --git a/usr/klibc/syscalls.pl b/usr/klibc/syscalls.pl
index c425137c24850..92f430683ab61 100644
--- a/usr/klibc/syscalls.pl
+++ b/usr/klibc/syscalls.pl
@@ -2,15 +2,24 @@
#
# Script to parse the SYSCALLS file and generate appropriate
# stubs.
+#
+# Pass 1: generate the C array of sizes
+# Pass 2: generate the syscall stubs and other output
+#
$v = $ENV{'KBUILD_VERBOSE'};
-$quiet = defined($v) ? !$v : 0;
+$quiet = defined($v) && ($v == 0) ? 1 : undef;
@args = ();
+undef $pass;
for $arg ( @ARGV ) {
if ( $arg =~ /^-/ ) {
if ( $arg eq '-q' ) {
$quiet = 1;
+ } elsif ( $arg eq '-v' ) {
+ $quiet = 0;
+ } elsif ( $arg =~ /\-([0-9]+)$/ ) {
+ $pass = $1+0;
} else {
die "$0: Unknown option: $arg\n";
}
@@ -18,7 +27,14 @@ for $arg ( @ARGV ) {
push(@args, $arg);
}
}
-($file, $sysstub, $arch, $bits, $unistd, $outputdir, $havesyscall) = @args;
+($file, $sysstub, $arch, $bits, $unistd, $outputdir,
+ $havesyscall, $typesize) = @args;
+
+if (!$pass) {
+ die "$0: Need to specify pass\n";
+}
+
+$quiet = ($pass != 2) unless defined($quiet);
require "$sysstub";
@@ -36,18 +52,66 @@ while ( defined($line = <UNISTD>) ) {
}
close(UNISTD);
-if (!open(HAVESYS, '>', $havesyscall)) {
- die "$0: $havesyscall: $!\n";
+if ($pass == 2) {
+ use bytes;
+
+ if (!open(TYPESIZE, '<', $typesize)) {
+ die "$0: $typesize: $!\n";
+ }
+
+ binmode TYPESIZE;
+
+ $len = -s TYPESIZE;
+ if (read(TYPESIZE, $typebin, $len) != $len) {
+ die "$0: $typesize: short read: $!\n";
+ }
+ close(TYPESIZE);
+
+ $ix = index($typebin, "\x7a\xc8\xdb\x4e\x97\xb4\xc9\x19");
+ if ($ix < 0) {
+ die "$0: $typesize: magic number not found\n";
+ }
+
+ # Remove magic number and bytes before it
+ $typebin = substr($typebin, $ix+8);
+
+ @size_table = unpack("C*", $typebin);
}
-print HAVESYS "#ifndef _KLIBC_HAVESYSCALL_H\n";
-print HAVESYS "#define _KLIBC_HAVESYSCALL_H 1\n\n";
+if ($pass == 2) {
+ if (!open(HAVESYS, '>', $havesyscall)) {
+ die "$0: $havesyscall: $!\n";
+ }
+
+ print HAVESYS "#ifndef _KLIBC_HAVESYSCALL_H\n";
+ print HAVESYS "#define _KLIBC_HAVESYSCALL_H 1\n\n";
+}
if (!open(FILE, '<', $file)) {
die "$0: $file: $!\n";
}
-print "syscall-objs := ";
+
+if ($pass == 2) {
+ print "syscall-objs := ";
+}
+
+
+# List here any types which should be sized even if they never occur
+# in any system calls at all.
+@type_list = ('int', 'long', 'void *', 'intptr_t', 'uintptr_t',
+ 'intmax_t', 'uintmax_t');
+
+%type_index = ();
+%typesize = ();
+$n = 0;
+foreach $t (@type_list) {
+ $type_index{$t} = $n;
+ if ($pass == 2) {
+ $typesize{$t} = $size_table[$n];
+ }
+ $n++;
+}
while ( defined($line = <FILE>) ) {
chomp $line;
@@ -106,15 +170,50 @@ while ( defined($line = <FILE>) ) {
@args = split(/\s*\,\s*/, $argv);
- print HAVESYS "#define _KLIBC_HAVE_SYSCALL_${fname} ${sname}\n";
- print " \\\n\t${fname}.o";
- make_sysstub($outputdir, $fname, $type, $sname, $stype, @args);
+ # Assign types indexes in order of appearance, so that in pass 2
+ # we know where to find it.
+ foreach $a (@args) {
+ if (!defined($type_index{$a})) {
+ $a_index = scalar(@type_list);
+ push(@type_list, $a);
+ $type_index{$a} = $a_index;
+ if ($pass == 2) {
+ $typesize{$a} = $size_table[$a_index];
+ }
+ }
+ if ($pass == 2) {
+ print STDERR "sizeof($a) = ", $typesize{$a}, "\n";
+ }
+ }
+
+ if ($pass == 2) {
+ print HAVESYS "#define _KLIBC_HAVE_SYSCALL_${fname} ${sname}\n";
+ print " \\\n\t${fname}.o";
+ make_sysstub($outputdir, $fname, $type, $sname, $stype, @args);
+ }
} else {
die "$file:$.: Could not parse input: \"$line\"\n";
}
}
-print "\n";
+if ($pass == 1) {
+ if (!open(TYPESIZE, '>', $typesize)) {
+ die "$0: cannot create file: $typesize: $!\n";
+ }
+
+ print TYPESIZE "#include \"syscommon.h\"\n";
+ print TYPESIZE "\n";
+ print TYPESIZE "const unsigned char type_sizes[] = {\n";
+ print TYPESIZE "\t0x7a,0xc8,0xdb,0x4e,0x97,0xb4,0xc9,0x19, /* magic */\n";
+ foreach $t (@type_list) {
+ print TYPESIZE "\tsizeof($t),\n";
+ }
+ print TYPESIZE "};\n";
+ close(TYPESIZE);
+} else {
+ print "\n";
+
+ print HAVESYS "\n#endif\n";
+ close(HAVESYS);
+}
-print HAVESYS "\n#endif\n";
-close(HAVESYS);
diff --git a/usr/klibc/syscalls/Kbuild b/usr/klibc/syscalls/Kbuild
index 487ebf7b52f9b..d9c7e4429c8d4 100644
--- a/usr/klibc/syscalls/Kbuild
+++ b/usr/klibc/syscalls/Kbuild
@@ -25,7 +25,7 @@ targets += $(syscall-objs)
clean-files += $(objtree)/$(KLIBCINC)/klibc/havesyscall.h
clean-files += $(KLIBCINC)/klibc/havesyscall.h
# All the syscall stubs
-clean-files += *.o *.S *.c *.list
+clean-files += *.o *.S *.c *.list *.bin
quiet_cmd_makelist = LIST $@
cmd_makelist = echo '$(filter-out FORCE,$^)' > $@
@@ -48,19 +48,45 @@ quiet_cmd_syscall.nrs = GEN $@
$(obj)/syscalls.nrs: $(KLIBCINC)/sys/syscall.h FORCE
$(call if_changed_dep,syscall.nrs)
+# Generate typesize.c
+quiet_cmd_syscalsz = GEN $@
+ cmd_syscalsz = mkdir -p $(KLIBCINC)/klibc/; \
+ $(PERL) $(KLIBCSRC)/syscalls.pl -1 $(obj)/SYSCALLS.i \
+ $(KLIBCSRC)/arch/$(KLIBCARCHDIR)/sysstub.ph \
+ $(KLIBCARCH) $(KLIBCBITSIZE) $(obj)/syscalls.nrs \
+ $(obj) \
+ $(KLIBCINC)/klibc/havesyscall.h \
+ $(obj)/typesize.c > $@ \
+ || rm -f $@
+
+$(obj)/typesize.c: $(KLIBCSRC)/syscalls.pl $(obj)/SYSCALLS.i \
+ $(KLIBCSRC)/arch/$(KLIBCARCHDIR)/sysstub.ph \
+ $(call objectify, $(syscall-objs:.o=.S)) \
+ $(src)/syscommon.h $(obj)/syscalls.nrs
+ $(call cmd,syscalsz)
+
+# Convert typesize.o to typesize.bin
+quiet_cmd_mkbin = OBJCOPY $@
+ cmd_mkbin = $(KLIBCOBJCOPY) -O binary $< $@
+
+$(obj)/typesize.bin: $(obj)/typesize.o
+ $(call cmd,mkbin)
+
# Generate $(KLIBINC)/klibc/havesyscall.h + makefile fragment
# Using sysstub.pl in arch dir generate all .S files
quiet_cmd_syscalls = GEN $@
cmd_syscalls = mkdir -p $(KLIBCINC)/klibc/; \
- $(PERL) $(KLIBCSRC)/syscalls.pl $(obj)/SYSCALLS.i \
- $(KLIBCSRC)/arch/$(KLIBCARCHDIR)/sysstub.ph \
- $(KLIBCARCH) $(KLIBCBITSIZE) $(obj)/syscalls.nrs \
+ $(PERL) $(KLIBCSRC)/syscalls.pl -2 $(obj)/SYSCALLS.i \
+ $(KLIBCSRC)/arch/$(KLIBCARCHDIR)/sysstub.ph \
+ $(KLIBCARCH) $(KLIBCBITSIZE) $(obj)/syscalls.nrs \
$(obj) \
- $(KLIBCINC)/klibc/havesyscall.h > $@ \
+ $(KLIBCINC)/klibc/havesyscall.h \
+ $(obj)/typesize.bin > $@ \
|| rm -f $@
$(obj)/syscalls.mk: $(KLIBCSRC)/syscalls.pl $(obj)/SYSCALLS.i \
- $(KLIBCSRC)/arch/$(KLIBCARCHDIR)/sysstub.ph \
- $(call objectify, $(syscall-objs:.o=.S)) \
- $(KLIBCSRC)/syscommon.h $(obj)/syscalls.nrs
+ $(KLIBCSRC)/arch/$(KLIBCARCHDIR)/sysstub.ph \
+ $(call objectify, $(syscall-objs:.o=.S)) \
+ $(src)/syscommon.h $(obj)/syscalls.nrs \
+ $(obj)/typesize.bin
$(call cmd,syscalls)
diff --git a/usr/klibc/syscommon.h b/usr/klibc/syscalls/syscommon.h
index 429025279eb22..0acae125e3053 100644
--- a/usr/klibc/syscommon.h
+++ b/usr/klibc/syscalls/syscommon.h
@@ -17,6 +17,7 @@
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/select.h>
+#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/times.h>