diff options
-rw-r--r-- | hurd/Makefile | 49 | ||||
-rw-r--r-- | hurd/gensym.awk | 78 | ||||
-rw-r--r-- | hurd/ioctl-decode.h | 15 | ||||
-rw-r--r-- | hurd/ioctl-tmpl.sym | 13 | ||||
-rw-r--r-- | hurd/ioctl.awk | 127 |
5 files changed, 280 insertions, 2 deletions
diff --git a/hurd/Makefile b/hurd/Makefile index 53436d87..1b133aaa 100644 --- a/hurd/Makefile +++ b/hurd/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation +# Copyright (C) 1993, 94, 95, 96, 99 Free Software Foundation # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -19,7 +19,7 @@ dir := hurd makemode := misc hdrs = $(wildcard $(srcdir)/*.defs $(srcdir)/*.h) -DIST_FILES = subsystems $(notdir $(hdrs)) +DIST_FILES = subsystems $(notdir $(hdrs)) ioctl-tmpl.sym ioctl.awk gensym.awk INSTHDRS = hurd_types.h ioctl_types.h paths.h shared.h \ $(notdir $(wildcard $(srcdir)/*.defs)) @@ -32,3 +32,48 @@ install-headers install: $(includedir)/hurd \ $(includedir)/hurd/%: $(srcdir)/%; $(INSTALL_DATA) $< $@ $(includedir)/hurd:;mkdir -p $@ + + + +# +# The following rules assist in creating an `Xioctl.defs' file +# to define RPCs that are sent primarily by ioctl commands. +# To use them, write a file `Xioctl-headers.h', e.g. for `mioctl-headers.h': +# #include <sys/mtio.h> +# with an #include for each header that defines ioctl request macros +# using _IO('X') et al. Then `make Xioctl-proto.defs' will create +# a prototype file for you to hand-edit into `Xioctl.defs'. + +# Building foo.h from foo.sym: +%.symc: %.sym + $(AWK) -f $(srcdir)/gensym.awk $< >$*.symc +%.symc.o: %.symc + $(CC) -S $(CPPFLAGS) $(CFLAGS) $(CPPFLAGS-$@) -x c -o $@ $< +%.h: %.symc.o + sed <$< -e 's/^[^*].*$$//' | \ + sed -e 's/^[*]/#define/' -e 's/mAgIc[^-0-9]*//' -e '/^ *$$/d' >$@ + +%-ioctls.sym: tmpl-ioctls.sym + sed 's|HEADER|<$(subst +,/,$*)>|' $< > $@ + +cpp = $(CC) $(CPPFLAGS) $(CFLAGS) $(CPPFLAGS-$@) -E -x c + +%ioctl-requests.list: %ioctl-headers.h + $(cpp) $< | sed -n 's/^#.*"\([^"]*\)".*$$/\1/p' | sort | uniq | \ + while read f; do \ + sed -n 's/^[ ]*#[ ]*define[ ]*\([A-Z0-9_]*\)[^A-Z0-9_][^A-Z0-9_]*_IO.*'\'$*\'.*$$'/\1/p' $$f; \ + done | sort | uniq > $@ + +%ioctl.defs: %ioctl.sym + +%ioctl-values.sym: %ioctl-headers.h %ioctl-requests.list ioctl-tmpl.sym + (sed 's%@HEADER_LIST@%$<%;s/@GROUP@/$*/g' < $(filter %.sym,$^); \ + while read r; do \ + for x in CMD SUBID INOUT TYPE \ + TYPE0 TYPE1 TYPE2 COUNT0 COUNT1 COUNT2; do \ + echo "expr $${x}($${r}) $${r}_$${x}"; \ + done; \ + done < $(filter %.list,$^)) > $@ + +%ioctl-proto.defs: %ioctl-values.h ioctl.awk + sed 's/^#define//;s/_/ /g' $< | $(AWK) -f $(filter %.awk,$^) > $@ diff --git a/hurd/gensym.awk b/hurd/gensym.awk new file mode 100644 index 00000000..21283214 --- /dev/null +++ b/hurd/gensym.awk @@ -0,0 +1,78 @@ +# +# Copyright (c) 1994 The University of Utah and +# the Computer Systems Laboratory (CSL). All rights reserved. +# +# Permission to use, copy, modify and distribute this software and its +# documentation is hereby granted, provided that both the copyright +# notice and this permission notice appear in all copies of the +# software, derivative works or modified versions, and any portions +# thereof, and that both notices appear in supporting documentation. +# +# THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS +# IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF +# ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. +# +# CSL requests users of this software to return to csl-dist@cs.utah.edu any +# improvements that they make and grant CSL redistribution rights. +# +# Author: Bryan Ford, University of Utah CSL +# + +BEGIN { + bogus_printed = "no" +} + +# Start the bogus function just before the first sym directive, +# so that any #includes higher in the file don't get stuffed inside it. +/^[a-z]/ { + if (bogus_printed == "no") + { + print "void bogus() {"; + bogus_printed = "yes"; + } +} + +# Take an arbitrarily complex C symbol or expression and constantize it. +/^expr/ { + print "__asm (\""; + if ($3 == "") + printf "* %s mAgIc%%0\" : : \"i\" (%s));\n", $2, $2; + else + printf "* %s mAgIc%%0\" : : \"i\" (%s));\n", $3, $2; +} + +# Output a symbol defining the size of a C structure. +/^size/ { + print "__asm (\""; + if ($4 == "") + printf "* %s_SIZE mAgIc%%0\" : : \"i\" (sizeof(struct %s)));\n", + toupper($3), $2; + else + printf "* %s mAgIc%%0\" : : \"i\" (sizeof(struct %s)));\n", + $4, $2; +} + +# Output a symbol defining the byte offset of an element of a C structure. +/^offset/ { + print "__asm (\""; + if ($5 == "") + { + printf "* %s_%s mAgIc%%0\" : : \"i\" (&((struct %s*)0)->%s));\n", + toupper($3), toupper($4), $2, $4; + } + else + { + printf "* %s mAgIc%%0\" : : \"i\" (&((struct %s*)0)->%s));\n", + toupper($5), $2, $4; + } +} + +# Copy through all preprocessor directives. +/^#/ { + print +} + +END { + print "}" +} + diff --git a/hurd/ioctl-decode.h b/hurd/ioctl-decode.h new file mode 100644 index 00000000..f65880cf --- /dev/null +++ b/hurd/ioctl-decode.h @@ -0,0 +1,15 @@ +/* This file is used by the Makefile rules for generating + Xioctl-proto.defs, see Makefile for details. */ + +#define CMD(request) _IOC_COMMAND (request) +#define TYPE(request) _IOC_TYPE (request) +#define INOUT(request) _IOC_INOUT (request) + +#define SUBID(request) IOC_COMMAND_SUBID (_IOC_COMMAND (request)) + +#define TYPE0(request) _IOT_TYPE0 (_IOC_TYPE (request)) +#define TYPE1(request) _IOT_TYPE1 (_IOC_TYPE (request)) +#define TYPE2(request) _IOT_TYPE2 (_IOC_TYPE (request)) +#define COUNT0(request) _IOT_COUNT0 (_IOC_TYPE (request)) +#define COUNT1(request) _IOT_COUNT1 (_IOC_TYPE (request)) +#define COUNT2(request) _IOT_COUNT2 (_IOC_TYPE (request)) diff --git a/hurd/ioctl-tmpl.sym b/hurd/ioctl-tmpl.sym new file mode 100644 index 00000000..8029ec00 --- /dev/null +++ b/hurd/ioctl-tmpl.sym @@ -0,0 +1,13 @@ +/* This file is used by the Makefile rules for generating + Xioctl-proto.defs, see Makefile for details. */ + +#include <sys/ioctl.h> +#include <hurd/ioctls.defs> + +#include "ioctl-decode.h" + +#include "@HEADER_LIST@" +#define GROUPCHAR '@GROUP@' + +expr GROUPCHAR GROUP +expr IOC_GROUP_SUBSYSTEM(GROUPCHAR) SUBSYSTEM diff --git a/hurd/ioctl.awk b/hurd/ioctl.awk new file mode 100644 index 00000000..289a9ab9 --- /dev/null +++ b/hurd/ioctl.awk @@ -0,0 +1,127 @@ +# +# This awk script is used by the Makefile rules for generating +# Xioctl-proto.defs, see Makefile for details. +# + +$1 == "SUBSYSTEM" { subsystem = $2 + 0; next } +$1 == "GROUP" { groupchar = $2; next } + +$2 == "CMD" { cmd[tolower($1)] = $3; + c = $3 + 0; + if (c > highcmd) highcmd = c; + icmd[c] = tolower($1); + next } +$2 == "SUBID" { subid[tolower($1)] = $3; + c = $3 + 0; + if (c > highid) highid = c; + id2cmdname[c] = tolower($1); + next } +$2 == "TYPE" { type[tolower($1)] = $3; next } +$2 == "INOUT" { inout[tolower($1)] = $3; next } +$2 == "TYPE0" { type0[tolower($1)] = $3; next } +$2 == "TYPE1" { type1[tolower($1)] = $3; next } +$2 == "TYPE2" { type2[tolower($1)] = $3; next } +$2 == "COUNT0" { count0[tolower($1)] = $3; next } +$2 == "COUNT1" { count1[tolower($1)] = $3; next } +$2 == "COUNT2" { count2[tolower($1)] = $3; next } + +END { + group = sprintf("%cioctl", groupchar); + + printf "subsystem %s %d; /* see ioctls.defs for calculation */\n\n", \ + group, subsystem; + + typemap[0] = "char"; + typemap[1] = "char"; + typemap[2] = "short"; + typemap[3] = "int"; + typemap[4] = "???64 bits???"; + inoutmap[1] = "out"; + inoutmap[2] = "in"; + inoutmap[3] = "inout"; + + print ""; + for (cmdname in type0) { + if (count0[cmdname] > 1) { + typecount = type0[cmdname] "," count0[cmdname]; + if (!tc[typecount]) { + tc[typecount] = typemap[type0[cmdname]] "array_" count0[cmdname] "_t"; + print "type", tc[typecount], "=", ("array[" count0[cmdname] "]"), \ + "of", (typemap[type0[cmdname]] ";"), "/* XXX rename this! */"; + } + argtype["0," cmdname] = tc[typecount]; + } + else if (count0[cmdname] == 1) { + argtype["0," cmdname] = typemap[type0[cmdname]] + } + } + + for (cmdname in type1) { + if (count1[cmdname] > 1) { + typecount = type1[cmdname] "," count1[cmdname]; + if (!tc[typecount]) { + tc[typecount] = typemap[type1[cmdname]] "array_" count1[cmdname] "_t"; + print "type", tc[typecount], "=", ("array[" count1[cmdname] "]"), \ + "of", (typemap[type1[cmdname]] ";"), "/* XXX rename this! */"; + } + argtype["1," cmdname] = tc[typecount]; + } + else if (count1[cmdname] == 1) { + argtype["1," cmdname] = typemap[type1[cmdname]] + } + } + + for (cmdname in type2) { + if (count2[cmdname] > 1) { + typecount = type2[cmdname] "," count2[cmdname]; + if (!tc[typecount]) { + tc[typecount] = typemap[type2[cmdname]] "array_" count2[cmdname] "_t"; + print "type", tc[typecount], "=", ("array[" count2[cmdname] "]"), \ + "of", (typemap[type2[cmdname]] ";"), "/* XXX rename this! */"; + } + argtype["2," cmdname] = tc[typecount]; + } + else if (count2[cmdname] == 1) { + argtype["2," cmdname] = typemap[type2[cmdname]] + } + } + print ""; + + lastid = -1; + for (i = 0; i <= highid; ++i) + if (id2cmdname[i]) { + cmdname = id2cmdname[i]; + + if (lastid < 100 && i > 100) { + if (lastid == 98) + print "\nskip; /* 99 unused */" + else + printf "\nskip %d; /* %d-99 unused */\n", 100 - lastid, lastid + 1; + print "\n\ +/* Because MiG defines reply ports as 100 more than request ports, we\n\ + have to leave one hundred empty RPC's here. */\n\ +skip 100;"; + lastid = 199; + } + + if (i == lastid + 2) + print "\nskip; /*", lastid + 1, "unused */"; + else if (i != lastid + 1) + printf "\nskip %d; /* %d-%d unused */\n", \ + i - lastid - 1, lastid + 1, i - 1; + lastid = i; + print "\n/*", i, toupper(cmdname), "*/"; + printf "routine %s_%s (\n\treqport: io_t", group, cmdname; + if (inout[cmdname]) { + io = inoutmap[inout[cmdname]]; + for (argidx = 0; argidx <= 2; ++argidx) + if (argtype[argidx "," cmdname]) + printf ";\n\t%s\targ%d: %s", \ + io, argidx, argtype[argidx "," cmdname]; + } + else { + printf ";\n\tin\trequest: int"; + } + print ");" + } +} |