l4-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Patch for idl4


From: ness
Subject: Re: Patch for idl4
Date: Wed, 07 Sep 2005 19:04:47 +0200
User-agent: Mozilla Thunderbird 1.0.6 (X11/20050813)

I have written a new set of patches. It basically ports task and physmem
to use idl4-generated interfaces, but there are other enhancements, too
(see logs [not in patches]). There is a little mess with my patch names,
as sometimes newer versions replace older onces and sometimes they only
enhance them. The order of applying patches is:

patch.idl4-v3 (to the idl4-1.0.2 source)
patch.hurd-l4 (from my prior post, to the plain cvs source)
patch.hurd-l4-v2
patch.ruth-example (from my prior post)
patch.ruth-example-v2
patch.task
patch.physmem

The files ruth/task-user.c, deva/task-user.c and
libhurd-mm/physmem-user.c can be deleted

summary of enhancements:
-generated interfaces (*_client.h) are linked to include/hurd/interfaces
-if the source file (*.idl) isn't listed in the nonpublic_interfaces
  variable
-physmem exports and is (mostly) called through generated interfaces
-task exports and is called through generated interfaces
-ruth has an up-to-date interface, but doesn't export it

about the map stub exported by physmem:
As the map stub actually has a variable number of parameters, it can't be described properly using CORBA. This implicitly means, the idl4 generated interface will never be correct. That shows why I always encourage people to wrap generated stubs into other headers. This allows us here to overwrite the generated stub by a hand-written one. Actually, even the definition of the hand-written stub is embedded into #if/#endif commands, as map is very special. E.g. in wortel/startup.c, we use an other definition.

TODO:
-transfering error values doesn't work.

logs:
Changelog:
2005-09-07  Tom Bachmann  <address@hidden>
         * configure.ac: add check for ln -s, add task header linking
         * Makefile.idl4: add support for IDL4_LOCALFLAGS,
           linking of generated interfaces and nonpublic_interfaces
         * Makefile.am: change order of building (as libhurd-mm now
           depends on physmem)

ruth/ChangeLog:
2005-09-07  Tom Bachmann  <address@hidden>
         * Makefile.am: remove task-user from ruth_SOURCES (no longer
           needed), mark test.idl as non-public
         * ruth-class.c: changed due to changes in idl4
         * ruth.c: call_ruth_class: changed due to changes in idl4
           main: changed to test transfer of return values
         * task-user.h: use interface stub exported by task
         * ia32-cmain: include task-user.h (as task_thread alloc is
           now inline)

deva/ChangeLog
2005-09-07  Tom Bachmann  <address@hidden>
         * Makefile.am: remove task-user from deva_SOURCES (no longer
           needed
         * task-user.h: use interface stub exported by task
         * ia32-cmain: include task-user.h (as task_thread alloc is
           now inline)


task/ChangeLog
2005-09-07  Tom Bachmann  <address@hidden>
         * Makefile.am: task_SOURCES: add task.idl
           BUILT_SOURCES: create (needed to build the interface)
           include Makefile.idl4
         * task.idl: create
         * task.c: task_server, main: rename task_server to
           task_server_pth
         * task-class.c: change to export the serverside interfaces
           expected by idl4 generated stubs
         * task_public.h: create (not much more then dummy for now)
         * headers.m4: create (link task_public.h to
           include/hurd/task.h)

physmem/ChangeLog
2005-09-07  Tom Bachmann  <address@hidden>
         * Makefile.am: physmem_SOURCES: add physmem.idl
           BUILT_SOURCES: create (needed to build the interface)
           IDL4_LOCALFLAGS: create
           include Makefile.idl4
         * physmem.idl: create
         * container.c: change to export the serverside interfaces
           expected by idl4 generated stubs
         * physmem.h: remove unneded rpc identifiers
           include interface stubs and overwrite map if !IN_PHYSMEM
         * priv.h: define IN_PHYSMEM to 1 before including physmem.h

libhurd-mm/ChangeLog
2005-09-07  Tom Bachmann  <address@hidden>
         * Makefile.am: remove physmem-user.c from SOURCES
         * physmem-user.h: change to use interface stubs exported by
           physmem

wortel/ChangeLog
2005-09-07  Tom Bachmann  <address@hidden>
         * startup.c: use interface stubs exported by physmem

--
-ness-

--- hurd-l4-idl4/configure.ac   2005-09-07 17:01:22.028946464 +0200
+++ hurd-l4-idl4-new/configure.ac       2005-09-07 15:53:13.086431384 +0200
@@ -34,6 +34,7 @@
 
 # Checks for programs.
 AC_PROG_CC
+AC_PROG_LN_S
 
 #Find idl4-config. We need this here, since it gives
 #us some CFLAGS
@@ -189,6 +190,7 @@
 m4_include([libpthread/headers.m4])
 m4_include([wortel/headers.m4])
 m4_include([physmem/headers.m4])
+m4_include([task/headers.m4])
 
 # Check for libc and components using it.
 
--- hurd-l4-idl4/Makefile.idl4  2005-09-07 17:01:22.028946464 +0200
+++ hurd-l4-idl4-new/Makefile.idl4      2005-09-07 16:59:15.983360032 +0200
@@ -1,8 +1,12 @@
 %_client.h: %.idl
-       $(IDL4) $(IDL4FLAGS) -c $<
+       $(IDL4) $(IDL4FLAGS) $(IDL4_LOCALFLAGS) -c $<
+       if test ! -d $(top_srcdir)/include/hurd/interfaces;then mkdir 
$(top_srcdir)/include/hurd/interfaces;fi
+       rm -f $(top_srcdir)/include/hurd/interfaces/$@
+       if test "$(filter $<,$(nonpublic_interfaces))" != "$<";then $(LN_S) 
`pwd`\/$@ $(top_srcdir)/include/hurd/interfaces/$@;fi
 
 %_server.h: %.idl
-       $(IDL4) $(IDL4FLAGS) -s $<
+       $(IDL4) $(IDL4FLAGS) $(IDL4_LOCALFLAGS) -s $<
 
 clean-local:
+       find . -maxdepth 1 -iname '*_client.h' -exec rm -f 
'$(top_srcdir)/include/hurd/interfaces/{}' ';'
        rm -f *_server.h *_client.h

diff -Naur idl4-old/AUTHORS idl4-new/AUTHORS
--- idl4-old/AUTHORS    2002-05-21 10:07:38.000000000 +0200
+++ idl4-new/AUTHORS    2005-09-06 20:54:25.983815536 +0200
@@ -1,3 +1,6 @@
 Andreas Haeberlen originally designed and implemented IDL4.
 
 Espen Skoglund added the autoconf-based build process.
+
+Tom Bachmann did some bugfix and added V4_GNU backend aswell
+as the options -M -C and -T.
diff -Naur idl4-old/ChangeLog idl4-new/ChangeLog
--- idl4-old/ChangeLog  2002-05-17 14:58:14.000000000 +0200
+++ idl4-new/ChangeLog  2005-09-06 21:00:17.069442408 +0200
@@ -0,0 +1,61 @@
+06/09/05, by Tom Bachmann aka ness <address@hidden>
+  lots, mostly in arch/v4_gnu
+    Larger changes at the V4_GNU interface.
+
+15/08/05,by Tom Bachmann aka ness <address@hidden>
+  be/types/pointer.cc
+     Slight misstake corrected (related to declaratorless calls
+     of buildDeclaration
+12/07/05, by Tom Bachmann aka ness <address@hidden>
+  base/tools.cc
+     Small bug fixed (related to errors while compiling the
+     temporary file resulting in incomplete/no output)
+10/07/2005, by Tom Bachmann aka ness <address@hidden>
+  base/main.cc
+    - implemented -M and -C to create make compliant
+      dependencies
+      NOTE: I used printf, since I got errors if I included
+      iostream
+
+  lots, e.g. base/main.cc, base/tools.cc, fe/idl/parser.yy,
+  ...
+    - implemented options -T to use the compiler to determine
+      the size of userdefined types. The main problem for me
+      was, that the C/C++ parser reported errors where the
+      compiler couldn't find any. Second, the C/C++ parser will
+      never be perfect, since the standard gives some freedom
+      to the compilers (e.g. padding, non standardized
+      extensions, ...) and because of that it would be extremely
+      much work to emulate all the differences of different gcc
+      branches (who says we only want to support gcc?). But only
+      making (and keeping) the parser standard compliant would be
+      hard. I added new CAoiUserType and CBEUserType classes
+      and extended the visitors to support them. There are also
+      significant extensions for global_t.
+      NOTE: There is still a lot of work needed, e.g. extend
+            parser.yy to accept user defined structs. This
+            (and all my other code, but especially this)
+            has to be tested!!!
+
+09/07/2005, by Tom Bachmann aka ness <address@hidden>
+  lots of files, mostly arch/v4_gnu/* include/arch/v4_gnu,
+  base/main.cc
+    - new virtual functions in base classes, some functiones
+      changed to virtual
+    - some *_gnu classes
+    -> a new interface called V4_GNU for use with the GNU
+       Hurd/L4 and the optional argument
+       -l (SMALL L) to build cap_class stubs
+
+
+03/07/2005, by Tom Bachmann aka ness <address@hidden>
+  base/version.cc, arch/v4/ia32/ms.cc, cast/cast.cc,
+  be/scope.cc, include/user/idl4/glue/v4-ia32/runtime.h
+    - repaired broken ia32 optimization on V4
+    - changed the order of printing stuff in
+      CASTDeclarator::write (to make gcc understand
+      attributes in function definitions).
+    - changed CBERootScope::buildServerTemplate to
+      add a better default include (more or less bad
+      hack)
+    - changed extern inline directives into always inline,
diff -Naur idl4-old/configure.in idl4-new/configure.in
--- idl4-old/configure.in       2003-11-03 22:31:05.000000000 +0100
+++ idl4-new/configure.in       2005-09-06 20:54:25.984815384 +0200
@@ -176,6 +176,7 @@
 src/arch/v4/Makefile
 src/arch/v4/ia32/Makefile
 src/arch/v4/ia64/Makefile
+src/arch/v4_gnu/Makefile
 src/arch/x0/Makefile
 src/arch/x0/ia32/Makefile
 src/base/Makefile
diff -Naur idl4-old/NEWS idl4-new/NEWS
--- idl4-old/NEWS       2002-07-31 15:54:12.000000000 +0200
+++ idl4-new/NEWS       2005-09-06 20:54:26.011811280 +0200
@@ -1,3 +1,48 @@
+patch by ness
+  - BE    : new CBEInterface_gnu and CBEOperation_gnu
+            with some overwritten virtual functions,
+            a new cross visitor (everything needed for
+            V4_GNU)
+  - V4_GNU: new interface (for use with GNU Hurd/L4)
+            This is very rudimentary. No exceptions are
+            supported, no data larger then 32 bit (shouldn't
+            be hard to change), no strings, no fpages, no ...
+            I skipped the implicit _env parameter, since
+            the implementation doesn't use it.
+            I added a new implicit parameter _cap, because of
+            every IPC uses capabilities in hurd.
+  - command line options:
+    --make-depend [-M]: create make compliant dependencies
+                        using the compiler (this creates a
+                        temporary file including all imported
+                        files and calls the compiler -MM,
+                        afterwards the temporary file is
+                        deleted)
+    --compiler [-C]   : allws to specify the compiler command
+                        (standard is gcc if mapping is C, g++
+                        if mapping is C++). All include options
+                        given to idl4 are given to the compiler
+                        call (as -I...), too (anything else
+                        wouldn't make sense, IMHO)
+    --user-types [-T] : in principle this an other way to handle
+                        import directives in the .idl files. See
+                        the CHangeLog for longer explination of
+                        why I implemented that. Here I'll list
+                        the issues:
+                          - all types are assumed to be trans-
+                            fered by copying them
+                          - parser.yy is not yet hacked to accept
+                            imported structures (shouldn't be hard
+                            to change [only enlarge the point
+                            structures [struct ...] are parsed to
+                            let them look up (see scoped_name, or
+                            so)], but I'm not a yacc/bison geek)
+                        This creates a temporary file that includes
+                        all imported files and (as compiled binary)
+                        prints size an alignment of the unknown
+                        types. This file is compiled and executed
+                        and it's output is parsed.
+
 0.9.1
   - BE: Visual debugging
   - V4: New backend
diff -Naur idl4-old/src/aoi/aoi.cc idl4-new/src/aoi/aoi.cc
--- idl4-old/src/aoi/aoi.cc     2003-04-08 15:54:09.000000000 +0200
+++ idl4-new/src/aoi/aoi.cc     2005-09-06 20:54:20.693619768 +0200
@@ -2,6 +2,7 @@
 #include <string.h>
 
 #include "aoi.h"
+#include <ms.h>
 
 int semanticErrors = 0;
 
@@ -157,7 +158,6 @@
   tmp = localLookup(identifier, symbolType);
   if ((!tmp) && parent)
     tmp = ((CAoiScope*)parent)->lookupSymbol(identifier, symbolType);
-    
   return tmp;  
 }
 
@@ -199,7 +199,7 @@
     
   switch (symbolType)
     {
-      case SYM_TYPE      : return types->getByName(identifier);
+      case SYM_TYPE:   return types->getByName(identifier);
       case SYM_CONSTANT  : return constants->getByName(identifier);
       case SYM_OPERATION : return operations->getByName(identifier);
       case SYM_ATTRIBUTE : return attributes->getByName(identifier);
diff -Naur idl4-old/src/aoi/check.cc idl4-new/src/aoi/check.cc
--- idl4-old/src/aoi/check.cc   2003-02-14 16:01:41.000000000 +0100
+++ idl4-new/src/aoi/check.cc   2005-09-06 20:54:20.693619768 +0200
@@ -407,3 +407,11 @@
   assert(peer->lineNo>=0);
   assert(peer->pos>=0);
 }
+
+void CAoiCheckVisitor::visit(CAoiUserType *peer)
+{
+       //printf("%s\n",peer->name);
+       assert(peer->name);
+       assert(globals.types[peer->name]->getSize()!=0);
+       assert(globals.types[peer->name]->getAlign()!=0);
+}
diff -Naur idl4-old/src/aoi/dump.cc idl4-new/src/aoi/dump.cc
--- idl4-old/src/aoi/dump.cc    2003-02-14 16:01:41.000000000 +0100
+++ idl4-new/src/aoi/dump.cc    2005-09-06 20:54:20.695619464 +0200
@@ -408,3 +408,8 @@
 {
   println("CAoiCustomType: %s", peer->name);
 }
+
+void CAoiDumpVisitor::visit(CAoiUserType *peer)
+{
+  println("CAoiUserType: %s,%i", 
peer->name,globals.types[peer->name]->getSize());
+}
diff -Naur idl4-old/src/aoi/visitor.cc idl4-new/src/aoi/visitor.cc
--- idl4-old/src/aoi/visitor.cc 2002-10-30 12:25:23.000000000 +0100
+++ idl4-new/src/aoi/visitor.cc 2005-09-06 20:54:20.695619464 +0200
@@ -83,7 +83,13 @@
 {
   worker->visit(this);
 }
+
+void CAoiUserType::accept(CAoiVisitor *worker)
+{
+  worker->visit(this);
+}
   
+
 void CAoiUnionType::accept(CAoiVisitor *worker)
 
 {
diff -Naur idl4-old/src/arch/Makefile.am idl4-new/src/arch/Makefile.am
--- idl4-old/src/arch/Makefile.am       2002-07-22 15:58:21.000000000 +0200
+++ idl4-new/src/arch/Makefile.am       2005-09-06 20:54:21.979424296 +0200
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in
 
-SUBDIRS=               v2 v4 x0
+SUBDIRS=               v2 v4 x0 v4_gnu
 
 noinst_LIBRARIES=      libarch.a
 libarch_a_SOURCES=     dummy.cc list.cc tools.cc
diff -Naur idl4-old/src/arch/v4/ia32/ms.cc idl4-new/src/arch/v4/ia32/ms.cc
--- idl4-old/src/arch/v4/ia32/ms.cc     2003-11-07 01:00:49.000000000 +0100
+++ idl4-new/src/arch/v4/ia32/ms.cc     2005-09-06 20:54:21.056564592 +0200
@@ -376,3 +376,16 @@
   
   return result;
 }
+
+//change by ness
+CASTBase *CMSConnectionI4::buildServerWrapper(CASTIdentifier *key, 
CASTCompoundStatement *compound)
+{
+  CASTIdentifier *wrapperIdentifier = key->clone();
+  wrapperIdentifier->addPrefix("service_");
+  
+  return getWrapperReturnType()->buildDeclaration( 
+    new CASTDeclarator(wrapperIdentifier, 
+      buildWrapperParams(key), NULL, NULL, NULL, buildWrapperAttributes()),
+    compound
+  );
+};
diff -Naur idl4-old/src/arch/v4_gnu/be.cc idl4-new/src/arch/v4_gnu/be.cc
--- idl4-old/src/arch/v4_gnu/be.cc      1970-01-01 01:00:00.000000000 +0100
+++ idl4-new/src/arch/v4_gnu/be.cc      2005-09-06 20:54:22.012419280 +0200
@@ -0,0 +1,915 @@
+#include <arch/v4_gnu.h>
+
+#include "be.h"
+#include "ops.h"
+#define dprintln(a...) do { if (debug_mode&DEBUG_GENERATOR) println(a); } 
while (0)
+#define prependStatement(a, b) do { CASTStatement *pre = (b); addTo(pre, (a)); 
(a) = (pre); } while (0)
+
+static char contractBuffer[20000];
+
+CASTStatement *CBEInterface_gnu::buildReferenceDefinition()
+{    
+  return NULL;
+}
+
+//################################################################################
+//################################################################################
+//################################################################################
+CASTStatement *CBEOperation_gnu::buildClientHeader()
+{
+       dprintln("*** Building client header for %s", aoi->name);
+
+       assert(connection);
+
+       forAll(aoi->exceptions,
+               warning("Not implemented: Exceptions")
+       );
+
+       /* Build a list of all parameters, including the implicit ones */
+       
+       CASTDeclaration *parameters = NULL;
+       
+       bool hasImplicitHandle = false;
+       forAll(aoi->parameters, 
+       if (getParameter(item)->getFirstMemberWithProperty("handle")) 
+               hasImplicitHandle = true
+       );
+       
+       if (!hasImplicitHandle)
+       addTo(parameters, new CASTDeclaration(
+               new CASTTypeSpecifier(new CASTIdentifier("idl4_thread_id_t")),
+               knitDeclarator("_server"))
+       );
+    
+       
+       addTo(parameters,new CASTDeclaration(
+               new CASTTypeSpecifier(new CASTIdentifier("idl4_cap_handle_t")),
+                       knitDeclarator("_cap"))
+       );
+       
+       if(!aoi->returnType->isVoid())
+       {
+               CASTDeclarator *rv = new CASTDeclarator(new 
CASTIdentifier("_ret"));
+               
rv->addIndir(getType(aoi->returnType)->getArgIndirLevel(RETVAL)+1);
+               CASTDeclaration *dclr = 
getType(aoi->returnType)->buildDeclaration(rv);
+               addTo(parameters, dclr);
+       }
+       
+       forAll(aoi->parameters, addTo(parameters, 
getParameter(item)->buildDeclaration()));
+       
+       dprintln(" +  Declaring transfer buffer");
+
+       /* Declare local variables and the transfer buffer */
+
+       CASTStatement *declStatements = NULL;
+
+       CBEVarSource *varSource = new CBEVarSource();
+       forAllOps(marshalOps, item->buildClientDeclarations(varSource));
+       if (returnOp)
+               returnOp->buildClientDeclarations(varSource);
+       addTo(declStatements, varSource->declareAll());
+
+       dprintln(" +  Declaring client variables");
+  
+       addTo(declStatements, 
connection->buildClientLocalVars(buildIdentifier()));
+       {
+               CASTDeclarator *rv = new CASTDeclarator(new 
CASTIdentifier("__retval"));
+               
rv->addIndir(getType(aoi->returnType)->getArgIndirLevel(RETVAL));
+               CASTDeclaration *dclr = new CASTDeclaration(new 
CASTTypeSpecifier(new CASTIdentifier("error_t")), rv);
+               addTo(declStatements, new CASTDeclarationStatement(dclr));
+       }
+
+       /* Translate all marshal operations (they were collected during 
+        the marshal phase) */
+       
+       dprintln(" +  Translating marshal operartions");
+
+       CASTStatement *marshalStatements = NULL;  
+       forAllOps(marshalOps, addTo(marshalStatements, 
item->buildClientMarshal()));
+       prependStatement(marshalStatements, connection->buildClientInit());
+       if (marshalStatements)
+               prependStatement(marshalStatements, new 
CASTBlockComment("marshal"));
+
+       /* Translate all unmarshal operations (see above) */
+       
+       dprintln(" +  Translating unmarshal operations");
+       
+       /*CASTStatement *setExceptionStatements = new CASTIfStatement(
+               new CASTBinaryOp("!=",
+                       new CASTIdentifier("_env"),
+                       new CASTIntegerConstant(0)),
+               connection->buildClientResultAssignment(
+                       new CASTIdentifier("_env"),
+         (aoi->flags&FLAG_ONEWAY) ? (CASTExpression*)new 
CASTIntegerConstant(0) : (CASTExpression*)new CASTIdentifier("_exception"))
+       );*/
+
+       CASTStatement *unmarshalStatements = NULL;  
+       forAllOps(marshalOps, addTo(unmarshalStatements, 
item->buildClientUnmarshal()));
+       addTo(unmarshalStatements, connection->buildClientFinish());
+  
+       CASTStatement *getStatusStatements = NULL;
+       
+       addTo(getStatusStatements,new CASTExpressionStatement(new 
CASTBinaryOp("=",
+               new CASTIdentifier("__retval"),
+               connection->buildLabelExpr())));
+               
+       /*if (!(aoi->flags&FLAG_ONEWAY))
+               addTo(getStatusStatements, 
connection->assignFCCDataFromBuffer(CHANNEL_OUT, 0, new 
CASTIdentifier("_exception")));*/
+
+       
+
+       if (unmarshalStatements)
+       {
+               prependStatement(unmarshalStatements, new 
CASTBlockComment("unmarshal"));
+               unmarshalStatements = new CASTIfStatement(
+                       new CASTBinaryOp("&&",
+                               new CASTFunctionOp(
+                                       new CASTIdentifier("IDL4_EXPECT_TRUE"), 
                        
+                                       connection->buildClientCallSucceeded()),
+                               new CASTBinaryOp("==",
+                                       new CASTIdentifier("__retval"),
+                                       new CASTIdentifier("0"))),
+                       new CASTCompoundStatement(
+                               unmarshalStatements));
+       }   
+
+  /* Return normally */
+
+       CASTStatement *returnStatements = NULL;
+       if(returnOp)
+               addTo(returnStatements, returnOp->buildClientUnmarshal());
+       addTo(returnStatements, new CASTReturnStatement(new 
CASTIdentifier("__retval")));
+
+  if (returnStatements)
+    prependStatement(returnStatements, new CASTBlockComment("return 
normally"));
+
+  /* Construct the IPC invocation. Note that both marshal and unmarshal
+     operations have to be constructed before this point, because the
+     CMSConnection needs to know what will go into the registers! */
+
+  CAoiInterface *parent = (CAoiInterface*)aoi->parent;
+  int fid = getID();
+  
+  assert(fid!=UNKNOWN);
+  assert(parent);
+  assert(parent->iid!=UNKNOWN);
+  
+  CASTExpression *pathToHandle = new CASTIdentifier("_service");
+  forAll(aoi->parameters, 
+    {
+      CBEParameter *param = getParameter(item);
+      if (param->getFirstMemberWithProperty("handle"))
+        {
+          pathToHandle = param->buildIdentifier();
+          for (int i=0;i<param->getArgIndirLevel();i++)
+            pathToHandle = new CASTUnaryOp("*", pathToHandle);
+            
+          while (param!=param->getFirstMemberWithProperty("handle"))
+            {
+              param = param->getFirstMemberWithProperty("handle");
+              pathToHandle = new CASTBinaryOp(".", pathToHandle, 
param->buildIdentifier());
+            }
+        }
+    }
+  );
+  
+  CASTStatement *invocationStatements = connection->buildClientCall(
+    pathToHandle,
+    new CASTIdentifier("_env")
+  );
+  
+  if (globals.pre_call_code)
+    prependStatement(invocationStatements, new CASTExpressionStatement(
+      new CASTIdentifier(globals.pre_call_code))
+    );
+  if (globals.post_call_code)
+    addTo(invocationStatements, new CASTExpressionStatement(
+      new CASTIdentifier(globals.post_call_code))
+    );
+  
+  prependStatement(invocationStatements, new CASTBlockComment("invoke IPC"));
+
+  /* Insert all those statements into the stub */
+
+  CASTStatement *statements = NULL;
+  addWithTrailingSpacerTo(statements, declStatements);
+  addWithTrailingSpacerTo(statements, marshalStatements);
+  addTo(statements, invocationStatements);
+  addWithLeadingSpacerTo(statements, getStatusStatements);
+  addWithLeadingSpacerTo(statements, unmarshalStatements);
+  //addWithLeadingSpacerTo(statements, setExceptionStatements);
+  addWithLeadingSpacerTo(statements, returnStatements);
+
+  /* From the pieces collected above, build the stub declaration */
+
+  CASTCompoundStatement *compound = new CASTCompoundStatement(statements);
+
+  CASTDeclarator *declarator = new CASTDeclarator(buildIdentifier(), 
parameters);
+  declarator->addIndir(getType(aoi->returnType)->getArgIndirLevel(RETVAL));
+  CASTDeclaration *declaration =       
//getType(aoi->returnType)->buildDeclaration(declarator, compound);
+                                                                               
                        new CASTDeclaration(new CASTTypeSpecifier(new 
CASTIdentifier("error_t")), declarator, compound);
+  declaration->addSpecifier(new CASTStorageClassSpecifier("inline"));
+  declaration->addSpecifier(new CASTStorageClassSpecifier("static"));
+
+  /* Build a comment with the transfer contract */
+  
+  enableStringMode(contractBuffer, sizeof(contractBuffer)-1);
+  connection->dump();
+  disableStringMode();
+ 
+  /* Return the whole thing */
+  
+  CASTIdentifier *defName = buildIdentifier();
+  defName->addPrefix("_funcdef___");
+  
+  CASTStatement *funcDef = NULL;
+  addTo(funcDef, new CASTPreprocDefine(defName, ANONYMOUS));
+  addTo(funcDef, new CASTDeclarationStatement(declaration));
+  
+  CASTStatement *result = NULL;
+  if (contractBuffer[0])
+    addTo(result, new CASTComment(mprintf(contractBuffer)));
+  
+  addTo(result, new CASTPreprocConditional(
+    new CASTUnaryOp("!", new CASTFunctionOp(new CASTIdentifier("defined"), 
defName->clone())), funcDef)
+  );
+
+  addTo(result, new CASTSpacer());
+
+  dprintln("Completed client header for %s", aoi->name);
+ 
+  return result;
+}
+
+void CBEOperation_gnu::marshal(CMSService *service)
+{
+  int exceptionCount = 0;
+
+  assert(!connection);
+  assert(!marshalOps);
+
+  dprintln("Marshalling %s::%s", ((CAoiScope*)aoi->parent)->scopedName, 
aoi->name);
+
+  forAll(aoi->exceptions, exceptionCount++);
+
+  CAoiInterface *parent = (CAoiInterface*)aoi->parent;
+  assert(getID()!=UNKNOWN && parent->iid != UNKNOWN);
+
+  this->connection = service->getConnection(2 + exceptionCount, getID(), 
(aoi->flags & FLAG_KERNELMSG) ? IID_KERNEL : parent->iid);
+  if (aoi->flags&FLAG_ONEWAY)
+    this->connection->setOption(OPTION_ONEWAY);
+  if (aoi->flags&FLAG_LOCAL)
+    this->connection->setOption(OPTION_LOCAL);
+  if (globals.flags&FLAG_FASTCALL)
+    this->connection->setOption(OPTION_FASTCALL);
+
+  /* Add the exception chunk */
+  
+  if (!(aoi->flags&FLAG_ONEWAY))
+    connection->getFixedCopyChunk(CHANNEL_ALL_OUT, 4, "__eid", 
msFactory->getMachineWordType());
+
+  /* Marshal all parameters */
+
+  forAll(aoi->parameters, getParameter(item)->marshalled = false);
+
+  forAllBEReverse(getOperation(aoi)->sortedParams, 
+    addTo(marshalOps, ((CBEParameter*)item)->buildMarshalOps(connection, 
OP_PROVIDEBUFFER))
+  );
+
+  forAll(aoi->parameters, assert(getParameter(item)->marshalled));
+
+  /* If there is a return value, marshal it */
+
+  if (!aoi->returnType->isVoid())
+    returnOp = getType(aoi->returnType)->buildMarshalOps(connection, 
CHANNEL_MASK(CHANNEL_OUT), new CASTIdentifier("*_ret"), "__retval", 
getType(aoi->returnType), NULL, 0);
+
+  connection->optimize();
+}
+
+//################################################################################
+//################################################################################
+//################################################################################
+CASTStatement *CBEOperation_gnu::buildServerHeader()
+{
+       if(aoi->flags&FLAG_ONEWAY)
+               panic("Oneway functions aren't supported yet!");
+       CASTStatement *result = NULL;
+
+       assert(connection);
+
+       /* Declare the necessary types */
+
+       addWithTrailingSpacerTo(result, 
+               connection->buildServerDeclarations(buildIdentifier())
+       );
+
+       /* Generate a forward declaration for the implementation function */
+       
+       CASTDeclaration *parameters = NULL;
+       addTo(parameters, new CASTDeclaration(
+               new CASTTypeSpecifier(new 
CASTIdentifier("idl4_cap_rpc_context_t")),
+               knitDeclarator("_ctx"))
+       );
+    
+       if(!aoi->returnType->isVoid())
+       {
+               CASTDeclarator *rv = new CASTDeclarator(new 
CASTIdentifier("_ret"));
+               
rv->addIndir(getType(aoi->returnType)->getArgIndirLevel(RETVAL)+1);
+               CASTDeclaration *dclr = 
getType(aoi->returnType)->buildDeclaration(rv);
+               addTo(parameters, dclr);
+       }
+       
+       forAll(aoi->parameters, addTo(parameters, 
getParameter(item)->buildDeclaration()));
+       
+       //We dont' need..
+       /*addTo(parameters, new CASTDeclaration(
+       new CASTTypeSpecifier(new CASTIdentifier("idl4_server_environment")),
+       new CASTDeclarator(new CASTIdentifier("_env"), new CASTPointer(1)))
+       );*/
+
+       CASTIdentifier *implementationName = buildIdentifier();
+       implementationName->addPostfix("_implementation");
+       
+       CASTDeclarator *declarator = new CASTDeclarator(implementationName, 
parameters);
+       
declarator->addIndir(getType(aoi->returnType)->getArgIndirLevel(RETVAL));
+       
+       CASTDeclaration *declaration = new CASTDeclaration(new 
CASTTypeSpecifier(new CASTIdentifier("error_t")),declarator);
+       declaration->addSpecifier(new CASTStorageClassSpecifier("inline"));
+       
+       addWithTrailingSpacerTo(result, new 
CASTDeclarationStatement(declaration));
+
+       /* Add a description of the buffer layout to the header file */
+       
+       enableStringMode(contractBuffer, sizeof(contractBuffer)-1);
+       connection->dump();
+       disableStringMode();
+       addTo(result, new CASTComment(mprintf(contractBuffer)));
+  
+  /* Create the declaration macro */
+  
+  addTo(result, new CASTPreprocDefine(
+    new CASTFunctionOp(
+      buildWrapperName(true),
+      new CASTIdentifier("_func")),
+    connection->buildServerWrapper(buildIdentifier(), buildServerStub()))
+  );  
+  
+  /* Better support for CPP magic (the Neal macro) */
+  
+  addWithLeadingSpacerTo(result, new CASTPreprocDefine(
+    buildWrapperName(false),
+    buildWrapperName(true))
+  );
+     
+  return result;
+}  
+
+//################################################################################
+//################################################################################
+//################################################################################
+CASTCompoundStatement *CBEOperation_gnu::buildServerStub()
+{
+       /* Translate all marshal operations (they were collected during 
+        the marshal phase) */
+       
+       assert(connection);
+       
+       dprintln("Building server stub for %s", aoi->name);
+       
+       CASTStatement *declStatements = NULL;
+       CASTStatement *unmarshalStatements = NULL;  
+       CBEVarSource *varSource = new CBEVarSource();
+  
+       forAllOps(marshalOps, 
+       {
+         item->buildServerDeclarations(varSource);
+         addTo(unmarshalStatements, item->buildServerUnmarshal());
+       });
+       
+       CASTDeclarator *rv = new CASTDeclarator(new CASTIdentifier("__retval"));
+       CASTDeclaration *dclr = new CASTDeclaration(new CASTTypeSpecifier(new 
CASTIdentifier("error_t")),rv);
+       addTo(declStatements, new CASTDeclarationStatement(dclr));
+       
+       if (returnOp)
+         returnOp->buildServerDeclarations(varSource);
+       
+       if (unmarshalStatements)
+               prependStatement(unmarshalStatements, new 
CASTBlockComment("unmarshal"));
+
+  /************************************************************************/
+
+  CASTStatement *positionCheckStatements = NULL;
+
+  if (debug_mode & DEBUG_TESTSUITE)
+    {
+      positionCheckStatements = connection->buildServerTestStructural();
+      if (positionCheckStatements)
+        prependStatement(positionCheckStatements, new 
CASTBlockComment("position check"));
+    }
+
+  /************************************************************************/
+
+  /*CASTStatement *envInitStatements = NULL;
+  
+  addTo(envInitStatements, new CASTExpressionStatement(
+    new CASTBinaryOp("=",
+      new CASTBinaryOp(".",
+        new CASTIdentifier("_env"),
+        new CASTIdentifier("_action")),
+      new CASTIntegerConstant(0)))
+  );  */
+
+  /************************************************************************/
+  
+  CASTStatement *invocationStatements = NULL;
+  CASTStatement *debugOutStatements = NULL;
+  CASTStatement *debugInStatements = NULL;
+  CASTStatement *itransStatements = NULL;
+  CASTStatement *otransStatements = NULL;
+  CASTExpression *arguments = NULL;
+  bool transUsed = false;
+  
+  addTo(arguments, connection->buildServerCallerID());
+  
+  if(!aoi->returnType->isVoid())
+       addTo(arguments, new CASTUnaryOp("&", new 
CASTIdentifier("_pack._out.__retval")));              //XXX REALLY HACKISH
+  
+  forAll(aoi->parameters,
+    {
+      CAoiParameter *thisParam = (CAoiParameter*)item;
+      CBEMarshalOp *thisOp = marshalOps;
+      bool found = false;
+      
+      assert(thisOp); // we seem to have parameters, after all
+      do {
+           if (thisOp->isResponsibleFor(getParameter(thisParam)))
+             { 
+               found = true;
+               break;
+             }
+           thisOp = thisOp->next;
+         } while (thisOp!=marshalOps);
+      if (!found)
+        panic("Marshal operation not found for parameter: %s", 
thisParam->name);
+      
+      CASTExpression *thisArg = 
thisOp->buildServerArg(getParameter(thisParam));
+      assert(thisArg);
+      
+      if ((debug_mode & DEBUG_VISUAL) && (thisParam->flags & FLAG_IN))
+        addTo(debugInStatements,
+          getParameter(thisParam)->buildTestDisplayStmt(buildTestKeyPrefix(), 
varSource, thisArg->clone())
+        );
+        
+      if ((debug_mode & DEBUG_VISUAL) && (thisParam->flags & FLAG_OUT))
+        addTo(debugOutStatements,
+          getParameter(thisParam)->buildTestDisplayStmt(buildTestKeyPrefix(), 
varSource, thisArg->clone())
+        );
+          
+      for (int i=0;i<getParameter(thisParam)->getArgIndirLevel();i++)
+        thisArg = new CASTUnaryOp("&", thisArg);
+        
+      addTo(arguments, thisArg);
+      
+      CAoiProperty *itrans = thisParam->getProperty("itrans");
+      CAoiProperty *otrans = thisParam->getProperty("otrans");
+
+      if (itrans)
+        {
+          assert(itrans->refValue);
+          CASTStatement *itransInvocation = new CASTExpressionStatement(
+            new CASTFunctionOp(
+              new CASTIdentifier(itrans->refValue),
+              knitExprList(
+                connection->buildServerCallerID(),
+                thisArg->clone(),
+                new CASTUnaryOp("&",
+                  new CASTIdentifier("_env"))
+                ))
+          );
+          
+          if (transUsed)
+            itransInvocation = new CASTIfStatement(
+              new CASTFunctionOp(
+                new CASTIdentifier("IDL4_EXPECT_TRUE"),
+                new CASTBinaryOp("==",
+                  new CASTBinaryOp(".",
+                    new CASTIdentifier("_env"),
+                    new CASTIdentifier("_action")),
+                  new CASTIntegerConstant(0))),
+              itransInvocation
+            );
+            
+          addTo(itransStatements, itransInvocation);
+          transUsed = true;
+        }  
+
+      if (otrans)
+        {
+          assert(otrans->refValue);
+          CASTStatement *otransInvocation = new CASTExpressionStatement(
+            new CASTFunctionOp(
+              new CASTIdentifier(otrans->refValue),
+              knitExprList(
+                connection->buildServerCallerID(),
+                thisArg->clone(),
+                new CASTUnaryOp("&",
+                  new CASTIdentifier("_env"))
+                ))
+          );
+          
+          otransInvocation = new CASTIfStatement(
+            new CASTFunctionOp(
+              new CASTIdentifier("IDL4_EXPECT_TRUE"),
+              new CASTBinaryOp("==",
+                new CASTBinaryOp(".",
+                  new CASTIdentifier("_env"),
+                  new CASTIdentifier("_action")),
+                new CASTIntegerConstant(0))),
+            otransInvocation
+          );
+            
+          addTo(otransStatements, otransInvocation);
+        }  
+    }
+  );
+  //addTo(arguments, new CASTUnaryOp("&", new CASTIdentifier("_env")));
+
+  if (itransStatements)
+    prependStatement(itransStatements, new CASTBlockComment("apply input 
translations"));
+    
+  if (otransStatements)
+    prependStatement(otransStatements, new CASTBlockComment("apply output 
translations"));
+
+  if (globals.pre_call_code)
+    addTo(itransStatements, new CASTExpressionStatement(
+      new CASTIdentifier(globals.pre_call_code))
+    );
+  if (globals.post_call_code)
+    prependStatement(otransStatements, new CASTExpressionStatement(
+      new CASTIdentifier(globals.post_call_code))
+    );
+
+  CASTExpression *invocation = new CASTFunctionOp(new CASTIdentifier("_func"), 
arguments);
+  invocation = new CASTBinaryOp("=",
+        new CASTIdentifier("__retval"),
+        invocation
+      );
+
+  addTo(invocationStatements, new CASTBlockComment(mprintf("invoke 
service")));  
+  addTo(declStatements, varSource->declareAll());
+  
+  if (debug_mode&DEBUG_VISUAL)
+    {
+      addTo(invocationStatements, new CASTExpressionStatement(
+        new CASTFunctionOp(
+          new CASTIdentifier("printf"),
+          knitExprList(
+            new CASTStringConstant(false, mprintf("*** Servicing call from %%X 
to %s::%s\\n", ((CAoiScope*)aoi->parent)->scopedName, aoi->name)),
+            new CASTFunctionOp(
+              new CASTIdentifier("idl4_raw_fpage"),
+              connection->buildServerCallerID()
+            ))))
+      );
+      addTo(invocationStatements, debugInStatements);
+      addTo(invocationStatements, new CASTSpacer());
+    }
+
+  CASTStatement *invocationTemp = new CASTExpressionStatement(invocation);
+  if (transUsed)
+    invocationTemp = new CASTIfStatement(
+      new CASTFunctionOp(
+        new CASTIdentifier("IDL4_EXPECT_TRUE"),
+          new CASTBinaryOp("==",
+          new CASTBinaryOp(".",
+            new CASTIdentifier("_env"),
+            new CASTIdentifier("_action")),
+          new CASTIntegerConstant(0))),
+      invocationTemp
+    );
+  
+  addTo(invocationStatements, invocationTemp);
+  
+  if (debug_mode&DEBUG_VISUAL)
+    {
+      addTo(invocationStatements, new CASTSpacer());
+      addTo(invocationStatements, new CASTExpressionStatement(
+        new CASTFunctionOp(
+          new CASTIdentifier("printf"),
+          knitExprList(
+            new CASTStringConstant(false, "--- Return code is %d\\n"),
+              new CASTBinaryOp(".",
+                new CASTIdentifier("_env"),
+                new CASTIdentifier("_action"))
+            )))
+      );
+      addTo(invocationStatements, debugOutStatements);
+    }
+  
+  addTo(invocationStatements, connection->buildServerMarshalInit());
+
+  /************************************************************************/
+
+  CASTStatement *marshalStatements = NULL;
+  if (!(aoi->flags & FLAG_ONEWAY))
+    {
+      //forAllOps(marshalOps, addTo(marshalStatements, 
item->buildServerMarshal()));
+      //if (!aoi->returnType->isVoid())
+      //  addTo(marshalStatements, returnOp->buildServerMarshal());
+      if (marshalStatements)
+        prependStatement(marshalStatements, new CASTBlockComment("marshal"));
+    
+      //addWithLeadingSpacerTo(marshalStatements, new CASTBlockComment("jump 
back"));
+      //addTo(marshalStatements, connection->buildServerBackjump(CHANNEL_OUT, 
new CASTIdentifier("_env")));
+  
+      /*marshalStatements = new CASTIfStatement(
+        new CASTFunctionOp(
+          new CASTIdentifier("IDL4_EXPECT_TRUE"),
+          new CASTBinaryOp("==",
+            new CASTBinaryOp(".",
+              new CASTIdentifier("_env"),
+              new CASTIdentifier("_action")),
+            new CASTIntegerConstant(0))),
+        new CASTCompoundStatement(
+          marshalStatements)
+      );*/
+    }
+
+  /************************************************************************/
+
+  CASTStatement *exceptionStatements = NULL;
+  int channelID = CHANNEL_OUT + 1;
+  
+  forAll(aoi->exceptions,
+    {
+      CBEExceptionType *bExc = getException(((CAoiRef*)item)->ref);
+      CASTStatement *backjump;
+
+      connection->reset();
+      backjump = connection->buildServerBackjump(channelID++, new 
CASTIdentifier("_env"));
+      if (backjump->next != backjump)
+        backjump = new CASTCompoundStatement(backjump);
+      
+      CASTStatement *newBackjump = new CASTIfStatement(
+        new CASTBinaryOp("==",
+          new CASTBinaryOp(".",
+            new CASTIdentifier("_env"),
+            new CASTIdentifier("_action")),
+          new CASTBinaryOp("+",
+            new CASTIdentifier("CORBA_USER_EXCEPTION"),
+            new CASTBinaryOp("<<",
+              bExc->buildID(),
+              new CASTIntegerConstant(8)))),
+        backjump
+      );
+      addWithLeadingSpacerTo(exceptionStatements, newBackjump);
+    }
+  );
+
+  if (exceptionStatements)
+    prependStatement(exceptionStatements, new CASTBlockComment("handle 
exceptions"));
+
+  /************************************************************************/
+
+  /* This must be done last, because the backend might need to allocate
+     additional buffers during marshalling */
+     
+  addTo(declStatements, connection->buildServerLocalVars(buildIdentifier()));
+
+  /************************************************************************/
+
+  
+  CASTStatement *stub = NULL;
+  addWithTrailingSpacerTo(stub, declStatements);
+  //addWithTrailingSpacerTo(stub, envInitStatements);
+  addWithTrailingSpacerTo(stub,connection->buildServerStoreData("_ctx->msg"));
+  addWithTrailingSpacerTo(stub, positionCheckStatements);
+  addWithTrailingSpacerTo(stub, unmarshalStatements);
+  addWithTrailingSpacerTo(stub, itransStatements);
+  addTo(stub, invocationStatements);
+  addWithLeadingSpacerTo(stub, otransStatements);
+  addWithLeadingSpacerTo(stub,connection->buildServerAppendData("_ctx->msg"));
+  addWithLeadingSpacerTo(stub, marshalStatements);
+  //addWithLeadingSpacerTo(stub, exceptionStatements);
+  //addWithLeadingSpacerTo(stub, connection->buildServerAbort());              
//we don't abort, if we're here, everything is OK
+  addWithLeadingSpacerTo(stub,new CASTReturnStatement(new 
CASTIdentifier("__retval")));
+  
+  return new CASTCompoundStatement(stub);
+}
+
+//################################################################################
+//################################################################################
+//################################################################################
+CASTStatement *CBEInterface_gnu::buildServerDefinitions()
+{
+  CAoiScope *definitionScope = NULL;
+  CASTStatement *subtree = NULL;
+
+  CASTDeclarator *serverLoopDeclarator = new CASTDeclarator(
+    buildServerFuncName(),
+       new CASTDeclaration(
+               new CASTTypeSpecifier(new CASTIdentifier("idl4_cap_bucket_t")),
+               knitDeclarator("_bucket"))
+  );
+
+  /* We should not assume that server loops can _never_ return */
+  if (debug_mode & DEBUG_TESTSUITE)
+    serverLoopDeclarator->setAttributes(
+      new CASTAttributeSpecifier(
+        new CASTIdentifier("noreturn"))
+    );
+
+  addTo(subtree, new CASTDeclarationStatement(
+    getType(aoiRoot->lookupSymbol("#void", SYM_TYPE))->buildDeclaration(
+      serverLoopDeclarator))
+  );
+    
+  CASTIdentifier *discardFuncName = buildIdentifier();
+  discardFuncName->addPostfix("_discard");
+
+       addTo(subtree, 
+       new CASTDeclarationStatement(
+               new CASTDeclaration(
+                       new CASTTypeSpecifier(new CASTIdentifier("error_t")),
+                       new CASTDeclarator(
+                               discardFuncName,
+                               new CASTDeclaration(
+                                       new CASTTypeSpecifier(new 
CASTIdentifier("idl4_cap_rpc_context_t")),
+                                       knitDeclarator("_ctx")))))
+       );        
+  
+  CASTDeclarator *serverDemDeclarator = new CASTDeclarator(
+    buildServerDemuxerName(),
+       new CASTDeclaration(
+               new CASTTypeSpecifier(new 
CASTIdentifier("idl4_cap_rpc_context_t")),
+               knitDeclarator("_ctx"))
+  );
+  
+  addTo(subtree, new CASTDeclarationStatement(
+    (new CBEOpaqueType("error_t",globals.word_size, globals.word_size, 
true))->buildDeclaration(
+      serverDemDeclarator))
+  );
+  /***************************************************************************/
+    if(globals.with_cap_class)
+       {
+               CASTIdentifier *class_init= buildIdentifier();
+               class_init->addPostfix("_init");
+               addTo(subtree, new CASTDeclarationStatement(
+                       new CASTDeclaration(
+                               new CASTTypeSpecifier(new 
CASTIdentifier("error_t")),
+                               new CASTDeclarator(
+                                       class_init,
+                                       new CASTEmptyDeclaration())))
+               );
+         
+               CASTIdentifier *class_alloc= buildIdentifier();
+               class_alloc->addPostfix("_alloc");
+               CASTStatement* class_alloc_statement=NULL;
+               addTo(class_alloc_statement,new CASTBlockComment("do necessary 
changes"));
+               addTo(class_alloc_statement,new CASTReturnStatement(new 
CASTFunctionOp(
+                       new CASTIdentifier("idl4_cap_class_alloc"),
+                       knitExprList(
+                               new CASTUnaryOp("&",buildIdentifier()),
+                               new CASTIdentifier("_r_obj")))
+               ));
+               CASTDeclaration *class_alloc_parameters = NULL;
+               addTo(class_alloc_parameters,new CASTDeclaration(
+                       new CASTTypeSpecifier(new 
CASTIdentifier("idl4_cap_obj_t*")),
+                               knitDeclarator("_r_obj"))
+               );
+       
+  addTo(subtree, new CASTDeclarationStatement(
+               new CASTDeclaration(
+                       new CASTTypeSpecifier(new CASTIdentifier("error_t")),
+                       new CASTDeclarator(
+                               class_alloc,
+                               class_alloc_parameters)))
+       );
+       };      
+  /***************************************************************************/
+  addTo(subtree, new CASTSpacer());  
+
+  /* Collect the function pointers. For each ID, we ask the superclasses 
+     for a pointer; it nothing is returned, we insert the discard function */
+  
+  int numVtableElements, iidMin, iidMax, fidMin, fidMax, kidMin, kidMax;
+  numVtableElements = getVtableSize();
+  getIDRange(&iidMin, &iidMax, &fidMin, &fidMax, &kidMin, &kidMax);
+
+  for (int iid=iidMin;iid<=iidMax;iid++)
+    {
+      bool foundFuncWithThisIID = false;
+      definitionScope = NULL;
+      
+      for (int fid=fidMin;fid<=fidMax;fid++)
+        if (getFunctionForID(fid, iid, &definitionScope))
+          foundFuncWithThisIID = true;
+
+      if (foundFuncWithThisIID || (iidMin==iidMax))
+        {
+          CASTExpression *functionPointers = NULL;
+          for (int fid=0;fid<numVtableElements;fid++)
+            {
+              CAoiOperation *thisFunc;
+              CASTExpression *newElement;
+              
+              definitionScope = NULL;
+              thisFunc = getFunctionForID(fid, iid, &definitionScope);
+              if (thisFunc != NULL)
+                {
+                  CASTIdentifier *funcName = buildIdentifier();
+                  funcName->addPrefix("service_");
+                  funcName->addPostfix("_");
+                  funcName->addPostfix(thisFunc->name);
+                  newElement = funcName;
+                } else newElement = discardFuncName->clone();
+                
+              if (globals.mapping == MAPPING_CXX)
+                newElement = new CASTUnaryOp("(void*)&", newElement);
+              
+              addTo(functionPointers, newElement);
+            }
+            
+         addTo(subtree, new CASTPreprocDefine(
+           (iidMin==iidMax) ? buildDefaultVtableName() : buildVtableName(iid), 
+           new CASTArrayInitializer(functionPointers))
+         );  
+        }
+    }
+    
+  if (iidMin!=iidMax)
+    {
+      CASTExpression *functionPointers = NULL;
+      for (int fid=0;fid<numVtableElements;fid++)
+        addTo(functionPointers, new CASTUnaryOp("(void*)&", 
discardFuncName->clone()));
+        
+      addTo(subtree, new CASTPreprocDefine(
+        buildVtableName(UNKNOWN),
+        new CASTArrayInitializer(functionPointers))
+      );
+    }
+    
+  CASTIdentifier *vtableSizeMacro = buildIdentifier();
+  vtableSizeMacro->capitalize();
+  vtableSizeMacro->addPostfix("_DEFAULT_VTABLE_SIZE");
+  addTo(subtree, new CASTPreprocDefine(
+    vtableSizeMacro,
+    new CASTIntegerConstant(getVtableSize()))
+  );
+
+  CASTIdentifier *maxFidMacro = buildIdentifier();
+  maxFidMacro->capitalize();
+  maxFidMacro->addPostfix("_MAX_FID");
+  addTo(subtree, new CASTPreprocDefine(
+    maxFidMacro,
+    new CASTIntegerConstant(fidMax))
+  );
+
+  if ((kidMin!=kidMax) || getFunctionForID(kidMin, IID_KERNEL, 
&definitionScope))
+    {
+      CASTExpression *functionPointers = NULL;
+      int maxKid = getKtableSize();
+      
+      for (int kid=0;kid<maxKid;kid++)
+        {
+          CASTExpression *newElement;
+          CAoiOperation *thisFunc;
+          thisFunc = getFunctionForID(kid, IID_KERNEL, &definitionScope);
+          if (thisFunc != NULL)
+            {
+              CASTIdentifier *funcName = buildIdentifier();
+              funcName->addPrefix("service_");
+              funcName->addPostfix("_");
+              funcName->addPostfix(thisFunc->name);
+              newElement = funcName;
+            } else newElement = discardFuncName->clone();
+            
+          if (globals.mapping == MAPPING_CXX)
+            newElement = new CASTUnaryOp("(void*)&", newElement);
+            

+          addTo(functionPointers, newElement);
+        }
+            
+      addTo(subtree, new CASTPreprocDefine(
+        buildKtableName(), 
+        new CASTArrayInitializer(functionPointers))
+      );  
+
+      CASTIdentifier *ktableSizeMacro = buildIdentifier();
+      ktableSizeMacro->capitalize();
+      ktableSizeMacro->addPostfix("_DEFAULT_KTABLE_SIZE");
+      addTo(subtree, new CASTPreprocDefine(
+        ktableSizeMacro,
+        new CASTIntegerConstant(getKtableSize()))
+      );
+    }
+
+  return subtree;      
+}
+
+CASTIdentifier *CBEInterface_gnu::buildServerDemuxerName()
+{
+  CASTIdentifier *serverFuncName = buildIdentifier();
+  serverFuncName->addPostfix("_demuxer");
+  
+  return serverFuncName;
+}
diff -Naur idl4-old/src/arch/v4_gnu/client.cc idl4-new/src/arch/v4_gnu/client.cc
--- idl4-old/src/arch/v4_gnu/client.cc  1970-01-01 01:00:00.000000000 +0100
+++ idl4-new/src/arch/v4_gnu/client.cc  2005-09-06 20:54:22.031416392 +0200
@@ -0,0 +1,207 @@
+#include <arch/v4_gnu.h>
+CASTStatement *CMSConnection4_gnu::buildClientLocalVars(CASTIdentifier *key)
+{
+       CASTDeclarationStatement *result = buildClientStandardVars();
+       
+       addTo(result, new CASTDeclarationStatement(
+       new CASTDeclaration(
+         new CASTTypeSpecifier(
+               new CASTIdentifier("l4_msg_tag_t")),
+         new CASTDeclarator(
+               new CASTIdentifier("_tag"))))
+       );
+       
+       addTo(result, new CASTDeclarationStatement(
+       new CASTDeclaration(
+         new CASTTypeSpecifier(
+               new CASTIdentifier("l4_msg_t")),
+         new CASTDeclarator(
+               new CASTIdentifier("_msg"))))
+       );
+       CASTDeclarationSpecifier* p=buildClientMsgBuf();
+       if(p)
+               addTo(result, new CASTDeclarationStatement(
+               new CASTDeclaration(
+                 p,
+                 new CASTDeclarator(
+                       new CASTIdentifier("_pack"))))
+               );
+       
+       return result;
+}
+
+CASTStatement *CMSConnection4_gnu::buildClientCall(CASTExpression *target, 
CASTExpression *env)
+{
+       if(options & OPTION_ONEWAY)
+               panic("Oneway functions aren't supported yet!");
+       CASTStatement *result = NULL;
+
+       /*addTo(result, buildMemMsgSetup(CHANNEL_IN));
+       addTo(result, new CASTExpressionStatement(
+       new CASTBinaryOp("=",
+         new CASTBinaryOp(".",
+               buildSourceBufferRvalue(CHANNEL_IN),
+               new CASTIdentifier("_msgtag")),
+         buildMsgTag(CHANNEL_IN)))
+       );*/
+       
+       addTo(result,new GNU_CALL_FN_NAME("l4_msg_clear","_msg"));
+       addTo(result,new GNU_CALL_FN(new 
CASTIdentifier("l4_set_msg_label"),knitExprList(
+               new CASTIdentifier("_msg"),buildMsgTag(CHANNEL_IN)))
+       );
+       
+       //add data to message
+       
+       addTo(result,new GNU_CALL_FN(new CASTIdentifier("l4_msg_append_word"),
+               knitExprList(new CASTIdentifier("_msg"),new CASTCastOp(new 
CASTDeclaration(
+                                       new CASTTypeSpecifier("l4_word_t"),
+                                       NULL),
+                               new CASTIdentifier("_cap"),
+                               CASTStandardCast)))
+       );
+       
+       
if(!mem_fixed[CHANNEL_IN]->isEmpty()||!mem_variable[CHANNEL_IN]->isEmpty()||!strings[CHANNEL_IN]->isEmpty()||
+               
!fpages[CHANNEL_IN]->isEmpty()||!special[CHANNEL_IN]->isEmpty()||!reg_variable[CHANNEL_IN]->isEmpty())
+               panic("Unsupported datatypes: strings,fpages");         //WHAT 
ARE THE OTHERS?
+               forAllMS(reg_fixed[CHANNEL_IN],
+               {
+                       CMSChunk4* chunk=(CMSChunk4*)item;
+                       if(strcasecmp(chunk->name,"_msgtag"))           //HOW 
TO DO THIS CLEARLY?
+                               
addTo(result,appendRegFixedToMsg(CHANNEL_IN,chunk,"_msg"));
+               };);
+       
+       addTo(result, new CASTExpressionStatement(
+               new CASTFunctionOp(
+                       new CASTIdentifier("l4_msg_load"),
+                       new CASTIdentifier("_msg")))
+       );
+       
+  //fpages aren't supported yet
+  /*bool hasOutFpages = false;
+  for (int i=1;i<numChannels;i++)
+    if (!fpages[i]->isEmpty())
+      hasOutFpages = true;
+  
+  if (hasOutFpages)
+    addTo(result, new CASTExpressionStatement(
+      new CASTFunctionOp(
+        new CASTIdentifier("L4_Accept"),
+        new CASTBinaryOp("->",
+          env->clone(),
+          new CASTIdentifier("_rcv_window"))))
+    );*/
+
+       addTo(result, new CASTExpressionStatement(
+               new CASTBinaryOp("=",
+                       new CASTIdentifier("_tag"),
+                       new CASTFunctionOp(
+                               new CASTIdentifier("l4_call"),
+                               new CASTIdentifier("_server"))))
+       );
+       if (!(options & OPTION_ONEWAY))
+               addTo(result, new CASTExpressionStatement(
+                       new CASTFunctionOp(
+                               new CASTIdentifier("l4_msg_store"),
+                               knitExprList(
+                                       new CASTIdentifier("_tag"),
+                                       new CASTIdentifier("_msg"))))
+               );
+       unsigned i=0;
+       //store data in message
+       
if(!mem_fixed[CHANNEL_OUT]->isEmpty()||!mem_variable[CHANNEL_OUT]->isEmpty()||!strings[CHANNEL_OUT]->isEmpty()||
+               
!fpages[CHANNEL_OUT]->isEmpty()||!special[CHANNEL_OUT]->isEmpty()||!reg_variable[CHANNEL_OUT]->isEmpty())
+               panic("Unsupported datatypes: strings,fpages");         //WHAT 
ARE THE OTHERS?
+               forAllMS(reg_fixed[CHANNEL_OUT],
+               {
+                       CMSChunk4* chunk=(CMSChunk4*)item;
+                       if(strcasecmp(chunk->name,"_msgtag"))           //HOW 
TO DO THIS CLEARLY?
+                               
addTo(result,storeRegFixedFromMsg(CHANNEL_OUT,chunk,i++,"_msg"));
+               };);
+       
+  addTo(result, buildClientUnmarshalStart());
+  
+  return result;    
+}
+
+CASTExpression* CMSConnection4_gnu::buildClientCallSucceeded()
+{
+       return new CASTFunctionOp(
+               new CASTIdentifier("l4_ipc_succeeded"),
+               new CASTIdentifier("_tag")
+       );
+};
+
+CASTExpression *CMSConnection4_gnu::buildMsgTag(int channel)
+
+{
+  /* Find out how many typed elements we have. Note that if a memory message
+     is to be used, we need an additional StringItem. */
+
+  int typedMRs = 0;
+  forAllMS(strings[channel], 
+    if (((CMSChunk4*)item)->flags & CHUNK_XFER_COPY)
+      typedMRs+=2
+  );
+  forAllMS(fpages[channel], typedMRs+=2);
+  if (!mem_fixed[channel]->isEmpty() || !mem_variable[channel]->isEmpty())
+    typedMRs += 2;
+
+  /* Build the ID part of the message tag. For normal RPCs, this is 
+     composed of the function ID (FID) and the interface ID (IID). 
+     There are two special cases:
+        1) Kernel messages have negative FIDs
+        2) Some kernel messages have arguments embedded in the FID */
+
+  int xfid = fid + (iid<<FID_SIZE);
+  if (iid == IID_KERNEL)
+    {
+      if (fid!=0)
+        xfid = (0xFFF - (fid-1))<<4;
+        else xfid = 0; /* startup */
+    }
+
+  CASTExpression *xfidExpr = new CASTIntegerConstant(xfid, true);
+  forAllMS(special[channel],
+    {
+      CMSChunk4 *chunk = (CMSChunk4*)item;
+      if (chunk->specialPos == POS_PRIVILEGES)
+        {
+          assert(chunk->cachedInExpr);
+          xfidExpr = new CASTBinaryOp("+",
+            xfidExpr,
+            new CASTBinaryOp("&",
+              chunk->cachedInExpr->clone(),
+              new CASTIntegerConstant(7))
+          );
+        }
+    }
+  );
+
+  /* Assemble the message tag */
+
+  CASTExpression *msgTag;
+       
+  int maxUntypedWords = getMaxUntypedWordsInChannel(channel);
+  if (channel == CHANNEL_IN)
+    msgTag = xfidExpr;
+  else
+    msgTag = new CASTIntegerConstant(maxUntypedWords);
+  /*
+  if (channel == CHANNEL_IN)
+    msgTag = new CASTBinaryOp("+",
+      msgTag,
+      new CASTBinaryOp("<<",
+        new CASTBrackets(xfidExpr),
+        new CASTIntegerConstant(9))
+    );
+  
+  if (typedMRs)
+    msgTag = new CASTBinaryOp("+",
+      msgTag,
+      new CASTBinaryOp("<<",
+        new CASTIntegerConstant(typedMRs),
+        new CASTIntegerConstant(6))
+    );*/
+    
+  return msgTag;
+}
diff -Naur idl4-old/src/arch/v4_gnu/cross.cc idl4-new/src/arch/v4_gnu/cross.cc
--- idl4-old/src/arch/v4_gnu/cross.cc   1970-01-01 01:00:00.000000000 +0100
+++ idl4-new/src/arch/v4_gnu/cross.cc   2005-09-06 20:54:22.040415024 +0200
@@ -0,0 +1,64 @@
+#include <arch/v4_gnu.h>
+void CAoiCrossVisitor_gnu::visit(CAoiInterface *aoi)
+{
+  if (!aoi->peer)
+    {
+      CAoiList *singleSuperclasses = aoi->getAllSuperclasses();
+      CBEList *inheritedOps = new CBEList();
+      
+      forAll(singleSuperclasses, 
+        {
+          CAoiInterface *superclass = (CAoiInterface*)((CAoiRef*)item)->ref;
+          CAoiOperation *op = 
(CAoiOperation*)superclass->operations->getFirstElement();
+          
+          if (superclass != aoi)
+            while (!op->isEndOfList())
+              {
+                inheritedOps->add(new CBEInheritedOperation(op, aoi));
+                op = (CAoiOperation*)op->next;
+              }
+        }
+      );
+
+      aoi->peer = new CBEInterface_gnu(aoi, inheritedOps);
+    }  
+
+  aoi->constants->accept(this);
+  aoi->types->accept(this);
+  aoi->attributes->accept(this);
+  aoi->exceptions->accept(this);
+  aoi->operations->accept(this);
+  aoi->submodules->accept(this);
+  aoi->interfaces->accept(this);
+  aoi->superclasses->accept(this);
+}
+
+void CAoiCrossVisitor_gnu::visit(CAoiOperation *aoi)
+{
+  if (!aoi->peer)
+    {
+      aoi->peer = new CBEOperation_gnu(aoi);
+      aoi->returnType->accept(this);
+      aoi->parameters->accept(this);
+      aoi->exceptions->accept(this);
+      
+      CBEDependencyList *depList = new CBEDependencyList();
+      forAll(aoi->parameters, 
getParameter(item)->registerDependencies(depList));
+      if (!depList->commit())
+        semanticError(aoi->context, "circular dependency between parameters");
+        
+      int maxPrio = 0;
+      forAll(aoi->parameters, 
+        if (getParameter(item)->priority>maxPrio)
+          maxPrio = getParameter(item)->priority;
+      );
+      
+      CBEList *sortedParams = getOperation(aoi)->sortedParams;
+      assert(sortedParams->isEmpty());
+      for (int i=0;i<=maxPrio;i++)
+        forAll(aoi->parameters,
+          if (getParameter(item)->priority == i)
+            sortedParams->add(getParameter(item));
+        );  
+    }  
+}
diff -Naur idl4-old/src/arch/v4_gnu/Makefile.am 
idl4-new/src/arch/v4_gnu/Makefile.am
--- idl4-old/src/arch/v4_gnu/Makefile.am        1970-01-01 01:00:00.000000000 
+0100
+++ idl4-new/src/arch/v4_gnu/Makefile.am        2005-09-06 20:54:22.040415024 
+0200
@@ -0,0 +1,6 @@
+## Process this file with automake to produce Makefile.in
+
+SUBDIRS=
+
+noinst_LIBRARIES=      libv4_gnu.a
+libv4_gnu_a_SOURCES=   template.cc server.cc client.cc stuff.cc be.cc cross.cc
diff -Naur idl4-old/src/arch/v4_gnu/server.cc idl4-new/src/arch/v4_gnu/server.cc
--- idl4-old/src/arch/v4_gnu/server.cc  1970-01-01 01:00:00.000000000 +0100
+++ idl4-new/src/arch/v4_gnu/server.cc  2005-09-06 20:54:22.041414872 +0200
@@ -0,0 +1,94 @@
+#include <arch/v4_gnu.h>
+CASTStatement *CMSConnection4_gnu::buildServerDeclarations(CASTIdentifier *key)
+{
+  CASTStatement *result=NULL; //= buildServerStandardDecls(key);               
//We don't want those
+  
+  CASTIdentifier *wrapperIdentifier = key->clone();
+  wrapperIdentifier->addPrefix("service_");
+  
+  CASTDeclarationStatement *wrapperDecl = new CASTDeclarationStatement(
+    getWrapperReturnType()->buildDeclaration( 
+      new CASTDeclarator(
+        wrapperIdentifier,
+        buildWrapperParams(key),
+        NULL, 
+        NULL, 
+        NULL, 
+        buildWrapperAttributes()))
+  );
+  
+  addWithLeadingSpacerTo(result, wrapperDecl);
+
+  return result;  
+}
+
+CASTDeclaration *CMSConnection4_gnu::buildWrapperParams(CASTIdentifier *key)
+{
+       CASTDeclaration *wrapperParams = NULL;
+       
+       addTo(wrapperParams,new CASTDeclaration(
+               new CASTTypeSpecifier(new 
CASTIdentifier("idl4_cap_rpc_context_t")),
+                       knitDeclarator("_ctx"))
+       );
+       
+       return wrapperParams;
+}
+
+CASTStatement *CMSConnection4_gnu::buildServerLocalVars(CASTIdentifier *key)
+
+{
+       CASTDeclarationStatement *result = NULL;
+       
+       CASTDeclarationSpecifier* p=buildClientMsgBuf();
+       if(p)
+               addTo(result, new CASTDeclarationStatement(
+               new CASTDeclaration(
+                 p,
+                 new CASTDeclarator(
+                       new CASTIdentifier("_pack"))))
+               );
+       
+       return result;
+}
+
+CBEType *CMSConnection4_gnu::getWrapperReturnType()
+{
+  return new CBEOpaqueType("error_t", globals.word_size, globals.word_size);
+}
+
+CASTStatement* CMSConnection4_gnu::buildServerStoreData(const char* msg)
+{
+       CASTStatement* result=NULL;
+       unsigned i=1;
+       
if(!mem_fixed[CHANNEL_IN]->isEmpty()||!mem_variable[CHANNEL_IN]->isEmpty()||!strings[CHANNEL_IN]->isEmpty()||
+               
!fpages[CHANNEL_IN]->isEmpty()||!special[CHANNEL_IN]->isEmpty()||!reg_variable[CHANNEL_IN]->isEmpty())
+               panic("Unsupported datatypes: strings,fpages");         //WHAT 
ARE THE OTHERS?
+       forAllMS(reg_fixed[CHANNEL_IN],
+       {
+               CMSChunk4* chunk=(CMSChunk4*)item;
+                       if(strcasecmp(chunk->name,"_msgtag"))           //HOW 
TO DO THIS CLEARLY?
+                               
addTo(result,storeRegFixedFromMsg(CHANNEL_IN,chunk,i++,msg));
+       };);
+       return result;
+};
+
+CASTStatement* CMSConnection4_gnu::buildServerAppendData(const char* msg)
+{
+       CASTStatement* result=NULL;
+       addTo(result,new GNU_CALL_FN_NAME("l4_msg_clear",msg));
+       
if(!mem_fixed[CHANNEL_OUT]->isEmpty()||!mem_variable[CHANNEL_OUT]->isEmpty()||!strings[CHANNEL_OUT]->isEmpty()||
+               
!fpages[CHANNEL_OUT]->isEmpty()||!special[CHANNEL_OUT]->isEmpty()||!reg_variable[CHANNEL_OUT]->isEmpty())
+               panic("Unsupported datatypes: strings,fpages");         //WHAT 
ARE THE OTHERS?
+               forAllMS(reg_fixed[CHANNEL_OUT],
+               {
+                       CMSChunk4* chunk=(CMSChunk4*)item;
+                       if(strcasecmp(chunk->name,"_msgtag"))           //HOW 
TO DO THIS CLEARLY?
+                               
addTo(result,appendRegFixedToMsg(CHANNEL_OUT,chunk,msg));
+               };);
+       return result;
+};
+
+CASTExpression *CMSConnection4_gnu::buildServerCallerID()
+{
+  return new CASTIdentifier("_ctx");
+}
diff -Naur idl4-old/src/arch/v4_gnu/stuff.cc idl4-new/src/arch/v4_gnu/stuff.cc
--- idl4-old/src/arch/v4_gnu/stuff.cc   1970-01-01 01:00:00.000000000 +0100
+++ idl4-new/src/arch/v4_gnu/stuff.cc   2005-09-06 20:54:22.041414872 +0200
@@ -0,0 +1,161 @@
+#include <arch/v4_gnu.h>
+void CMSFactory4_gnu::initRootScope(CAoiRootScope *rootScope)
+{
+  CAoiModule *idl4 = getBuiltinScope(rootScope, "idl4");
+  rootScope->submodules->add(idl4);
+  idl4->constants->add(getBuiltinConstant(rootScope, idl4, "startup", 0));
+  idl4->constants->add(getBuiltinConstant(rootScope, idl4, "interrupt", 1));
+  idl4->constants->add(getBuiltinConstant(rootScope, idl4, "pagefault", 2));
+  idl4->constants->add(getBuiltinConstant(rootScope, idl4, "preemption", 3));
+  idl4->constants->add(getBuiltinConstant(rootScope, idl4, "sysexc", 4));
+  idl4->constants->add(getBuiltinConstant(rootScope, idl4, "archexc", 5));
+  idl4->constants->add(getBuiltinConstant(rootScope, idl4, "sigma0rpc", 6));
+}
+
+CASTDeclarationStatement *CMSConnection4_gnu::buildMessageMembers(int channel)
+{
+       CASTDeclarationStatement *members = NULL;
+       
+       forAllMS(reg_fixed[channel], 
+       {
+               CMSChunk4 *chunk = (CMSChunk4*)item;
+               if(strcasecmp(chunk->name,"_msgtag"))           //HOW TO DO 
THIS CLEARLY?
+                       addTo(members, chunk->buildDeclarationStatement());
+       }    
+       );
+  
+  if (!mem_fixed[channel]->isEmpty() || !mem_variable[channel]->isEmpty())
+    addTo(members, new CASTDeclarationStatement(
+      new CASTDeclaration(
+        new CASTTypeSpecifier(
+          new CASTIdentifier("idl4_stringitem")),
+        new CASTDeclarator(
+          new CASTIdentifier("_memmsg"))))
+    );
+    
+  forAllMS(strings[channel], 
+    if (((CMSChunk4*)item)->flags & CHUNK_XFER_COPY)
+      addTo(members, new CASTDeclarationStatement(
+        new CASTDeclaration(
+          new CASTTypeSpecifier(
+            new CASTIdentifier("idl4_stringitem")),
+          new CASTDeclarator(
+            new CASTIdentifier(item->name))))
+      )
+  );
+    
+  forAllMS(fpages[channel], 
+    addTo(members, new CASTDeclarationStatement(
+      new CASTDeclaration(
+        new CASTTypeSpecifier(
+          new CASTIdentifier("idl4_mapitem")),
+        new CASTDeclarator(
+          new CASTIdentifier(item->name))))
+    )
+  );
+    
+  return members;  
+}
+
+CASTExpression *CMSConnection4_gnu::buildLabelExpr()
+{
+  return new CASTFunctionOp(
+    new CASTIdentifier("l4_label"),
+    new CASTIdentifier("_tag")
+  );
+}
+
+CASTExpression *CMSConnection4_gnu::buildSourceBufferRvalue(int channel)
+{
+       CASTIdentifier *bufferName;
+       
+       bufferName = new CASTIdentifier("_pack");
+       
+       return new CASTBinaryOp(".",
+               bufferName,
+               buildChannelIdentifier(channel));
+}
+
+CASTExpression *CMSConnection4_gnu::buildTargetBufferRvalue(int channel)
+{
+       return buildSourceBufferRvalue(channel);
+}
+
+CASTExpression *CMSConnection4_gnu::buildFCCDataSourceExpr(int channel, 
ChunkID chunkID)
+{
+  CMSChunk4 *chunk;
+
+  chunk = findChunk(reg_fixed[channel], chunkID);
+  if (chunk)
+    {
+      return new CASTBinaryOp(".",
+        new CASTBinaryOp(".",
+          new CASTIdentifier("_pack"), 
+          buildChannelIdentifier(channel)),
+        new CASTIdentifier(chunk->name)
+      );    
+    }
+
+  chunk = findChunk(mem_fixed[channel], chunkID);
+  if (chunk)
+    {
+      return new CASTBinaryOp(".",
+        new CASTBinaryOp("->",
+          new CASTIdentifier("_memmsg"), 
+          buildChannelIdentifier(channel)),
+        new CASTIdentifier(chunk->name)
+      );    
+    }
+
+  chunk = findChunk(strings[channel], chunkID);
+  if (chunk)
+    {
+      return new CASTUnaryOp("*",
+        chunk->contentType->buildTypeCast(1, 
+          new CASTBinaryOp(".",
+            new CASTBinaryOp(".",
+              new CASTBinaryOp(".",
+                new CASTIdentifier("_pack"),
+                new CASTIdentifier("_buf")),
+              new CASTIndexOp(
+                new CASTIdentifier("_str"),
+                new CASTIntegerConstant(15 - chunk->bufferIndex))),
+              new CASTIdentifier("ptr")))
+      );    
+    }
+    
+  panic("Cannot build FCC source expression (chunk %d in channel %d)", 
chunkID, channel);
+  return NULL;
+}
+
+CASTStatement* CMSConnection4_gnu::appendRegFixedToMsg(int channel,CMSChunk4* 
chunk,const char* msg)
+{
+       m_assert(chunk->size<=globals.word_size,"So big data isn't supported 
yet!");
+       return new GNU_CALL_FN(
+               new CASTIdentifier("l4_msg_append_word"),
+               knitExprList(
+                       new CASTIdentifier(msg),
+                       new CASTCastOp(
+                               new CASTDeclaration(
+                                       new CASTTypeSpecifier("l4_word_t"),
+                                       NULL),
+                               new CASTBinaryOp(".",
+                                       buildSourceBufferRvalue(channel),
+                                       new CASTIdentifier(chunk->name)),
+                               CASTStandardCast)));
+};
+
+CASTStatement* CMSConnection4_gnu::storeRegFixedFromMsg(int channel,CMSChunk4* 
chunk,unsigned nr,const char* msg)
+{
+       m_assert(chunk->size<=globals.word_size,"So big data isn't supported 
yet!");
+       return new CASTExpressionStatement(new CASTBinaryOp("=",
+               new CASTBinaryOp(".",
+                       buildTargetBufferRvalue(channel),
+                       new CASTIdentifier(chunk->name)),
+               chunk->contentType->buildTypeCast(0,
+                       new CASTFunctionOp(
+                               new CASTIdentifier("l4_msg_word"),
+                               knitExprList(
+                                       new CASTIdentifier(msg),
+                                       new 
CASTIdentifier(mprintf("%i",nr)))))));      //WHAT IS WITH THE DEALLOCATION OF 
THIS STRINGS?
+};
diff -Naur idl4-old/src/arch/v4_gnu/template.cc 
idl4-new/src/arch/v4_gnu/template.cc
--- idl4-old/src/arch/v4_gnu/template.cc        1970-01-01 01:00:00.000000000 
+0100
+++ idl4-new/src/arch/v4_gnu/template.cc        2005-09-06 20:54:22.041414872 
+0200
@@ -0,0 +1,273 @@
+#include <arch/v4_gnu.h>
+
+#include "be.h"
+#include "ops.h"
+#define dprintln(a...) do { if (debug_mode&DEBUG_GENERATOR) println(a); } 
while (0)
+#define prependStatement(a, b) do { CASTStatement *pre = (b); addTo(pre, (a)); 
(a) = (pre); } while (0)
+
+static char contractBuffer[20000];
+CASTStatement *CMSService4_gnu::buildServerLoop(CASTIdentifier *prefix, 
CASTExpression *utableRef, CASTExpression *ktableRef, bool useItable, bool 
hasKernelMessages)
+{
+         return new 
GNU_CALL_FN_NAME("hurd_cap_bucket_manage_mt","_bucket,NULL,0,0");
+}
+
+CASTStatement *CBEInterface_gnu::buildServerTemplate()
+{
+  CASTStatement *subtree = NULL;
+
+  if ((globals.flags & FLAG_MODULESONLY) && ((aoi->parent)->parent == 0))
+    return NULL;
+
+  int iidMin, iidMax, fidMin, fidMax, kidMin, kidMax;
+  getIDRange(&iidMin, &iidMax, &fidMin, &fidMax, &kidMin, &kidMax);
+
+  if (!(globals.flags & FLAG_LOOPONLY))
+    {
+      addTo(subtree, buildTitleComment());
+      forAll(aoi->operations, 
+        {
+          addTo(subtree, getOperation(item)->buildServerTemplate());
+          if (debug_mode&DEBUG_TESTSUITE)
+            addTo(subtree, getOperation(item)->buildTestFunction());
+        }
+      );    
+      forAllBE(inheritedOps, 
+        addTo(subtree, ((CBEInheritedOperation*)item)->buildServerTemplate())
+      );
+      forAll(aoi->interfaces, 
+        addTo(subtree, getInterface(item)->buildServerTemplate())
+      );
+    }
+
+  addTo(subtree, buildVtableDeclaration());
+
+  /* As a special optimization, we do not use uTables when only kernel
+     messages need to be dispatched */
+
+  CASTIdentifier *utableRef = NULL;
+  if (containsUserMessages() || !containsKernelMessages())
+    {
+      utableRef = buildIdentifier();
+      utableRef->addPostfix((iidMin==iidMax) ? "_vtable" : "_itable");
+    }  
+
+  CASTIdentifier *ktableRef = NULL;
+  if (containsKernelMessages())
+    {
+      ktableRef = buildIdentifier();
+      ktableRef->addPostfix("_ktable");
+    }  
+
+  CASTIdentifier *prefix = buildIdentifier();
+  prefix->capitalize();  
+  addTo(subtree, new CASTDeclarationStatement(
+    new CASTDeclaration(
+      new CASTTypeSpecifier(new CASTIdentifier("void")),
+      new CASTDeclarator(
+        buildServerFuncName(),
+        new CASTDeclaration(
+                       new CASTTypeSpecifier(new 
CASTIdentifier("idl4_cap_bucket_t")),
+                       
knitDeclarator(service->getServerTemplateBucketName()))),
+      new CASTCompoundStatement(service->buildServerLoop(prefix, utableRef, 
ktableRef, (iidMin!=iidMax), containsKernelMessages()))))
+  );
+  addTo(subtree, new CASTSpacer());
+  
+  /***************************************************************************/
+
+  if (!(globals.flags & FLAG_LOOPONLY))  
+    {
+      CASTIdentifier *discardFuncName = buildIdentifier();
+      discardFuncName->addPostfix("_discard");
+
+      CASTStatement *discardFunction = NULL;
+      if (debug_mode&DEBUG_TESTSUITE)
+        addTo(discardFunction, new CASTExpressionStatement(
+          new CASTFunctionOp(
+            new CASTIdentifier("enter_kdebug"),
+            new CASTStringConstant(false, mprintf("Discarding request for 
interface %s", aoi->scopedName))))
+        );
+         addTo(discardFunction,new CASTReturnStatement(new 
CASTIdentifier("0")));
+      addWithTrailingSpacerTo(subtree, new CASTDeclarationStatement(
+        new CASTDeclaration(
+          new CASTTypeSpecifier(mprintf("error_t")),
+          new CASTDeclarator(
+            discardFuncName,
+            new CASTDeclaration(
+                               new CASTTypeSpecifier(new 
CASTIdentifier("idl4_cap_rpc_context_t")),
+                               knitDeclarator("_ctx"))),
+          new CASTCompoundStatement(discardFunction)))
+      );
+    }
+  
+  /***************************************************************************/
+       
+       CASTIdentifier *demuxer= buildIdentifier();
+       demuxer->addPostfix("_demuxer");
+       
+       addWithTrailingSpacerTo(subtree, new CASTDeclarationStatement(
+               new CASTDeclaration(
+                       new CASTTypeSpecifier(mprintf("error_t")),
+                       new CASTDeclarator(
+                               demuxer,
+                               new CASTDeclaration(
+                                       new CASTTypeSpecifier(new 
CASTIdentifier("idl4_cap_rpc_context_t")),
+                                       knitDeclarator("_ctx"))),
+               new 
CASTCompoundStatement(service->buildServerDemuxer("_ctx",prefix, utableRef, 
ktableRef, (iidMin!=iidMax), containsKernelMessages()))))
+       );
+         
+  /***************************************************************************/
+       if(globals.with_cap_class)
+       {
+               addWithTrailingSpacerTo(subtree,new CASTDeclarationStatement(
+                       new CASTDeclaration(
+                               new CASTTypeSpecifier(new 
CASTIdentifier("static idl4_cap_class")),                     //FIXME
+                               new CASTDeclarator(
+                                       buildIdentifier())))
+               );
+               
+               CASTIdentifier *class_init= buildIdentifier();
+               CASTStatement* class_init_statement=NULL;
+               addTo(class_init_statement,new CASTBlockComment("do necessary 
changes"));
+               addTo(class_init_statement,new CASTReturnStatement(new 
CASTFunctionOp(
+                       new CASTIdentifier("idl4_cap_class_init"),
+                       knitExprList(
+                               new CASTUnaryOp("&",buildIdentifier()),
+                               new CASTIdentifier("int*"),
+                               knitExprList(
+                                       new CASTIdentifier("NULL"),new 
CASTIdentifier("NULL"),
+                                       new CASTIdentifier("NULL"),new 
CASTIdentifier("NULL"),
+                                       demuxer->clone())))
+               ));
+               class_init->addPostfix("_init");
+               addWithTrailingSpacerTo(subtree, new CASTDeclarationStatement(
+                       new CASTDeclaration(
+                               new CASTTypeSpecifier(new 
CASTIdentifier("error_t")),
+                               new CASTDeclarator(
+                                       class_init,
+                                       new CASTEmptyDeclaration()),
+                               new 
CASTCompoundStatement(class_init_statement)))
+               );
+               
+               CASTIdentifier *class_alloc= buildIdentifier();
+               class_alloc->addPostfix("_alloc");
+               CASTStatement* class_alloc_statement=NULL;
+               addTo(class_alloc_statement,new CASTBlockComment("do necessary 
changes"));
+               addTo(class_alloc_statement,new CASTReturnStatement(new 
CASTFunctionOp(
+                       new CASTIdentifier("idl4_cap_class_alloc"),
+                       knitExprList(
+                               new CASTUnaryOp("&",buildIdentifier()),
+                               new CASTIdentifier("_r_obj")))
+               ));
+               CASTDeclaration *class_alloc_parameters = NULL;
+               addTo(class_alloc_parameters,new CASTDeclaration(
+                       new CASTTypeSpecifier(new 
CASTIdentifier("idl4_cap_obj_t*")),
+                               knitDeclarator("_r_obj"))
+               );
+               addWithTrailingSpacerTo(subtree, new CASTDeclarationStatement(
+                       new CASTDeclaration(
+                               new CASTTypeSpecifier(new 
CASTIdentifier("error_t")),
+                               new CASTDeclarator(
+                                       class_alloc,
+                                       class_alloc_parameters),
+                               new 
CASTCompoundStatement(class_alloc_statement)))
+               );
+       };
+       
+  return subtree;
+}
+
+CASTStatement *CBEOperation_gnu::buildServerTemplate()
+{
+  CASTStatement *result = NULL;
+  CASTDeclaration *parameters = NULL;
+  
+  assert(connection);
+  
+  dprintln("*** Building server template for %s", aoi->name);
+
+  addTo(parameters, new CASTDeclaration(
+    new CASTTypeSpecifier(new CASTIdentifier("idl4_cap_rpc_context_t")),
+    knitDeclarator("_ctx"))
+  );
+       
+       if(!aoi->returnType->isVoid())
+       {
+               CASTDeclarator *rv = new CASTDeclarator(new 
CASTIdentifier("_ret"));
+               
rv->addIndir(getType(aoi->returnType)->getArgIndirLevel(RETVAL)+1);
+               CASTDeclaration *dclr = 
getType(aoi->returnType)->buildDeclaration(rv);
+               addTo(parameters, dclr);
+       }
+    
+  forAll(aoi->parameters, addTo(parameters, 
getParameter(item)->buildDeclaration()));
+
+  CASTIdentifier *implementationName = buildIdentifier();
+  implementationName->addPostfix("_implementation");
+
+  CBEVarSource *varSource = new CBEVarSource();
+  CASTStatement *localVars = NULL;
+  CASTStatement *statements = NULL;
+
+  if (debug_mode&DEBUG_TESTSUITE)
+    addTo(statements, buildTestClientCode(varSource));
+    else addTo(statements, new CASTBlockComment(mprintf("implementation of 
%s::%s", ((CAoiInterface*)aoi->parent)->scopedName, aoi->name)));
+
+  dprintln(" +  Marshalling return value");
+  
+  addTo(localVars, varSource->declareAll());
+  CASTDeclarator *rv = new CASTDeclarator(new CASTIdentifier("__retval"), 
NULL, NULL, new CASTIntegerConstant(0));
+  addTo(localVars, new CASTDeclarationStatement(
+       new CASTDeclaration(new CASTTypeSpecifier(new 
CASTIdentifier("error_t")),rv))
+  );
+
+  addTo(statements, new CASTReturnStatement(
+       new CASTIdentifier("__retval")));
+
+  CASTStatement *compound = NULL;
+  addWithTrailingSpacerTo(compound, localVars);
+  addTo(compound, statements);
+  
+  CASTDeclarator *declarator = new CASTDeclarator(implementationName, 
parameters);
+  CASTDeclaration *declaration = new CASTDeclaration(new CASTTypeSpecifier(new 
CASTIdentifier("error_t")),
+                                                                               
                                                                                
        declarator, new CASTCompoundStatement(compound));
+  declaration->addSpecifier(new 
CASTStorageClassSpecifier(mprintf("IDL4_INLINE")));
+  
+  addWithTrailingSpacerTo(result, new CASTDeclarationStatement(declaration));
+
+  addWithTrailingSpacerTo(result, new CASTExpressionStatement(
+    new CASTFunctionOp(
+      buildWrapperName(true),
+      implementationName->clone()))
+  );
+  
+  return result;
+}
+
+CASTStatement* CMSService4_gnu::buildServerDemuxer(const char* 
ctx,CASTIdentifier *prefix, CASTExpression *utableRef,
+                                                                               
                                                                        
CASTExpression *ktableRef, bool useItable, bool hasKernelMessages)
+{
+       CASTIdentifier *fidMask = prefix->clone();      
+       fidMask->addPostfix("_FID_MASK");
+       
+       CASTStatement* r=NULL;
+       
+
+       if(hasKernelMessages)
+               panic("Kernel messages not implemented!");
+       if(useItable)
+               panic("Multiple interfaces not implemented!");
+  
+       addTo(r,new CASTReturnStatement(new CASTFunctionOp(new 
CASTFunctionOp(new CASTIdentifier(""),
+               new CASTUnaryOp("*",
+                       new CASTFunctionOp(
+                               new 
CASTIdentifier("(error_t(*)(idl4_cap_rpc_context_t))"),
+                               new CASTIndexOp(
+                                       utableRef,
+                                       new CASTBinaryOp("&",
+                                         new CASTFunctionOp(
+                                               new 
CASTIdentifier("idl4_get_function_id"),
+                                               new 
CASTIdentifier("idl4_msg_label(_ctx->msg)")),
+                                         fidMask))))),
+               new CASTIdentifier("_ctx"))));
+  
+  return r;
+};
diff -Naur idl4-old/src/base/main.cc idl4-new/src/base/main.cc
--- idl4-old/src/base/main.cc   2003-08-25 06:34:52.000000000 +0200
+++ idl4-new/src/base/main.cc   2005-09-06 20:54:20.564639376 +0200
@@ -8,6 +8,9 @@
 #include <stdlib.h>
 #include <time.h>
 
+#include <fstream>
+#include <vector>
+
 #ifdef HAVE_GETOPT_LONG
 #include <getopt.h>
 #else
@@ -29,6 +32,7 @@
 #include "arch/dummy.h"
 #include "arch/v2.h"
 #include "arch/v4.h"
+#include "arch/v4_gnu.h"
 
 #define dprintln(fmt...) do { if 
(debug_mode&(~(DEBUG_TESTSUITE+DEBUG_PARANOID))) printf(fmt); } while (0)
 #define OPTION(sopt, lopt, arg, expl) printf("  -%c%-21s%s\n", sopt, (lopt[0]) 
? mprintf(", --%s%s%s", lopt, (arg[0] ? "=" : " "), arg) : "", expl)
@@ -59,6 +63,11 @@
   OPTION('p',"platform" ,"SPEC","specify platform (ia32, arm)");
   OPTION('i',"interface","SPEC","choose kernel interface (V2, X0, V4)");
   OPTION('m',"mapping"  ,"SPEC","use specific mapping (C)");
+  OPTION('l',"class"  ,"","add cap-class stubs (very rudimentary, better use 
wrapping for headers)");
+  OPTION('M',"make-depend"  ,"","build make compliant dependencies");
+  OPTION('C',"compiler"  ,"","specifiy the compiler (and the flags) to use 
[gcc/g++]");
+  OPTION('T',"user-types"  ,"","use the compiler to find out align and size of 
unknown types");
+  OPTION('N',"no-erase"  ,"","don't erase temporary files");
   printf("\n");
   exit(1);
 }
@@ -74,7 +83,7 @@
 
 {
   char optch;
-  static char stropts[] = "stco:h:d::vp:i:m:f:D:I:W:w:";
+  static char stropts[] = "NMTC:lstco:h:d::vp:i:m:f:D:I:W:w:";
   int optidx;
   static struct option longopts[] = 
     { { "debug",     optional_argument, 0, 'd' },
@@ -90,6 +99,11 @@
       { "pre-call",  required_argument, 0, 4   },
       { "post-call", required_argument, 0, 5   },
       { "help",      no_argument,       0, 1   },
+         { "class",     optional_argument, 0, 'l' },
+         { "compiler",     optional_argument, 0, 'C' },
+         { "make-depend",     optional_argument, 0, 'M' },
+         { "user-types",     optional_argument, 0, 'T' },
+         { "no-erase",     optional_argument, 0, 'N' },
       { 0,           0,                 0, 0   } };
 
   for (int i=0;i<MAX_OPTIONS;i++)
@@ -100,16 +114,21 @@
 
   for (int i=0;i<MAX_OPTIONS;i++)
     globals.preproc_defines[i] = getBuiltinMacro(i);
-
+  globals.no_erase=false;
   while ((optch=getopt_long(argc, argv, stropts, longopts, &optidx))!=EOF)
     switch (optch)
       {
         case 's' : globals.output_type = OUTPUT_SERVER; break;
+               case 'N' : globals.no_erase=true;break;
         case 't' : globals.output_type = OUTPUT_TEMPLATE; break;
         case 'c' : globals.output_type = OUTPUT_CLIENT; break;
         case 'o' : strncpy(globals.outfile_name, optarg, FILENAME_MAX);break;
         case 'h' : strncpy(globals.header_name, optarg, FILENAME_MAX);break;
+        case 'l' : globals.with_cap_class=true;break;
         case 'v' : version();break;
+        case 'M' : globals.make_depend=true;break;
+        case 'T' : globals.user_types=true;break;
+        case 'C' : if(optarg)globals.cc=optarg;else panic("said to give 
compiler but no compiler given");break;
         case 'd' : if (optarg)
                      { 
                        if (!strcasecmp(optarg, "test"))
@@ -219,6 +238,7 @@
         case 'i' : if (!strcasecmp(optarg,"V2")) globals.interface = 
INTERFACE_V2; else
                    if (!strcasecmp(optarg,"X0")) globals.interface = 
INTERFACE_X0; else
                    if (!strcasecmp(optarg,"V4")) globals.interface = 
INTERFACE_V4; else
+                   if (!strcasecmp(optarg,"V4_GNU")) globals.interface = 
INTERFACE_V4_GNU; else
                      {
                        printf("Unknown kernel interface: %s\n", optarg);
                        exit(1);
@@ -265,7 +285,20 @@
 
   if (argc==optind)
     help();
-
+  
+  if(globals.user_types&&globals.cc=="")
+         switch (globals.mapping)
+         {
+                 case MAPPING_CXX:
+                               globals.cc="g++";
+                               break;
+                 case MAPPING_C:
+                               globals.cc="gcc";
+                               break;
+                 default:
+                               panic("can't guess the compiler - unknown 
mapping");
+         };
+  
   dprintln("Debug mode set to %d\n", debug_mode);
     
   strncpy(globals.infile_name, argv[optind], FILENAME_MAX);
@@ -291,11 +324,124 @@
     } else strcpy(globals.prefix_path, "");
 }
 
+int make_depend()
+{
+       std::ifstream in(globals.infile_name);
+       if(!in)
+       {
+               panic("inputfile doesn't exist");
+               return 1;
+       };
+       std::string s;
+       std::string::iterator i;
+       std::string::size_type c;
+       std::vector<std::string> v;
+       while(getline(in,s))
+       {
+               if((c=s.find("import"))==std::string::npos)
+                       continue;
+               const unsigned skip=6;
+               if((c==0||(s[c-1]==' 
'||s[c-1]=='\t'))&&(s.size()>(c+skip))&&(s[c+skip]==' '||s[c+skip]=='\t'))      
           //make sure it's really a keyword (and not within an identifier)
+               {
+                       std::string::iterator j=s.begin()+c+skip;
+                       for(;*j!='\"'&&j!=s.end();++j);
+                       if(j==s.end())
+                               panic("malformed import directive");
+                       ++j;
+                       std::string::iterator k=j;
+                       for(;*k!='\"'&&k!=s.end();++k);
+                       if(k==s.end())
+                               panic("malformed import directive");
+                       std::string::iterator l=k;
+                       for(;*l!=';'&&l!=s.end();++l);
+                       if(l==s.end())
+                               panic("malformed import directive");
+                       //printf("%s\n",std::string(j,k).c_str());
+                       v.push_back(std::string(j,k));
+               };
+       };
+       
+       printf("%s: %s ",globals.header_name,globals.infile_name);
+       if(v.size())
+       {
+               std::string ccopt;
+               char buffer[MAX_PATH];
+               getcwd(buffer,MAX_OPTIONS);
+               ccopt+=std::string("-I")+buffer+" ";
+               for(const char** 
cpp=globals.preproc_includes;*cpp&&cpp<(globals.preproc_includes+MAX_OPTIONS+1);++cpp)
+                       ccopt+=(std::string("-I")+*cpp)+" ";
+               for(const char** 
cpp=globals.preproc_options;*cpp&&cpp<(globals.preproc_options+MAX_OPTIONS+1);++cpp)
+                       ccopt+=(std::string("-")+*cpp)+" ";
+               for(const char** 
cpp=globals.preproc_defines;*cpp&&cpp<(globals.preproc_defines+MAX_OPTIONS+1);++cpp)
+                       ccopt+=(std::string("-D")+*cpp)+" ";
+               
+               std::string r("/tmp/");
+               for(unsigned i=0;i<15;++i)
+                       r+=(rand()%26+'a');
+               if(globals.mapping==MAPPING_C)
+                       r+=".c";
+               else if(globals.mapping==MAPPING_CXX)
+                       r+="cc";
+               else
+                       panic("unsupported mapping");
+               //printf("%s\n",r.c_str());
+               std::string r2("/tmp/");
+               for(unsigned i=0;i<15;++i)
+                       r2+=(rand()%26+'a');
+               //printf("%s\n",r2.c_str());
+               
+               std::ofstream f(r.c_str());
+               for(unsigned i=0;i<v.size();++i)
+               {
+                       f<<"#include <"<<v[i]<<'>'<<std::endl;
+               };
+               f.close();
+               system((globals.cc+" -MM "+ccopt+r+" > "+r2).c_str());
+               
+               std::ifstream f2(r2.c_str());
+               if(f2)
+               {
+                       getline(f2,s);
+                       if(f2)
+                       {
+                               i=s.begin();
+                               for(;*i!=':'&&i!=s.end();++i);
+                               for(;*i!='.'&&i!=s.end();++i);
+                               for(;*i!=' '&&*i!='\t'&&i!=s.end();++i);
+                               for(;(*i==' '||*i=='\t')&&i!=s.end();++i);
+                               for(;i!=s.end();++i)
+                                       printf("%c",*i);
+                               printf("\n");
+                               while(getline(f2,s))
+                                       printf("%s\n",s.c_str());
+                       }
+                       else
+                       {
+                               f2.close();
+                               remove(r.c_str());
+                               remove(r2.c_str());
+                               panic("confused (by compiler errors?)");
+                       };
+               }
+               f2.close();
+               remove(r.c_str());
+               remove(r2.c_str());
+       }
+       else
+               printf("\n");
+       
+       return 0;
+};
+
 int main(int argc, char *argv[])
 
 {
+  srand(time(0));
   parse_args(argc, argv);
-
+  
+  if(globals.make_depend)
+         return make_depend();
+       
   if (globals.interface == INTERFACE_X0)
     {
       switch (globals.platform)
@@ -326,7 +472,16 @@
           case PLATFORM_DUMMY   : msFactory = new CMSFactoryDummy();break;
           default               : panic("V4 platforms: generic, ia32, dummy");
         }
-    } else panic("Unsupported interface");
+    } else 
+  if (globals.interface == INTERFACE_V4_GNU)
+    {
+      switch (globals.platform)
+        {
+          case PLATFORM_GENERIC : msFactory = new CMSFactory4_gnu();break;
+          case PLATFORM_DUMMY   : msFactory = new CMSFactoryDummy();break;
+          default               : panic("V4_GNU platforms: generic, dummy");
+        }
+    }else panic("Unsupported interface");
 
   if (globals.mapping == MAPPING_CXX)
     CASTBase::setCXXMode(true);
@@ -349,6 +504,9 @@
     panic("%s: %i Error(s) and %i Warning(s)", globals.infile_name,
           mainFile->getErrorCount(), mainFile->getWarningCount());
 
+  if(globals.user_types)
+         make_user_types();
+  
   if (debug_mode & DEBUG_AOI)
     aoiRoot->accept(new CAoiDumpVisitor());  
 
@@ -358,7 +516,10 @@
   if ((globals.mapping == MAPPING_C) || (globals.mapping == MAPPING_CXX))
     {
       dprintln("transforming...\n");
-      aoiRoot->accept(new CAoiCrossVisitor());
+      if(globals.interface==INTERFACE_V4_GNU)
+        aoiRoot->accept(new CAoiCrossVisitor_gnu());
+      else
+        aoiRoot->accept(new CAoiCrossVisitor());
 
       CBERootScope *beRoot = (CBERootScope*)aoiRoot->peer;
       CBEIDSource *idSource = new CBEIDSource();
diff -Naur idl4-old/src/base/tools.cc idl4-new/src/base/tools.cc
--- idl4-old/src/base/tools.cc  2003-03-12 14:05:44.000000000 +0100
+++ idl4-new/src/base/tools.cc  2005-09-06 20:54:20.565639224 +0200
@@ -2,9 +2,13 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <fstream>
+#include <unistd.h>
+#include <string>
+
 #include "globals.h"
 #include "base.h"
-
+#include <aoi.h>
 char *getDefaultFilename(int number, int mode)
 
 {
@@ -62,3 +66,103 @@
 
   return version_string;
 }
+
+void make_user_types()
+{
+       std::string ccopt;
+       char buffer[MAX_PATH];
+       getcwd(buffer,MAX_PATH);
+       ccopt+=std::string("-I")+buffer+" ";
+       for(const char** 
cpp=globals.preproc_includes;*cpp&&cpp<(globals.preproc_includes+MAX_OPTIONS+1);++cpp)
+               ccopt+=(std::string("-I")+*cpp)+" ";
+       for(const char** 
cpp=globals.preproc_options;*cpp&&cpp<(globals.preproc_options+MAX_OPTIONS+1);++cpp)
+               ccopt+=(std::string("-")+*cpp)+" ";
+       for(const char** 
cpp=globals.preproc_defines;*cpp&&cpp<(globals.preproc_defines+MAX_OPTIONS+1);++cpp)
+               ccopt+=(std::string("-D")+*cpp)+" ";
+
+       std::string r1("/tmp/");        
+       for(unsigned i=0;i<15;++i)
+               r1+=(rand()%26+'a');
+       std::string r2=r1;
+       if(globals.mapping==MAPPING_C)
+               r1+=".c";
+       else if(globals.mapping==MAPPING_CXX)
+               r1+="cc";
+       else
+               panic("unsupported mapping");
+       std::string r3("/tmp/");
+       for(unsigned i=0;i<15;++i)
+               r3+=(rand()%26+'a');
+       //printf("%s\n",r1.c_str());
+       //printf("%s\n",r2.c_str());    
+       //printf("%s\n",r3.c_str());    
+       std::ofstream cfile(r1.c_str());
+       assert(cfile);
+       
+       cfile<<"#if HAVE_CONFIG_H\n#include <config.h>\n#endif"<<std::endl;
+       forAll(aoiRoot->includes,
+       {
+               cfile<<"#include 
<"<<((CAoiConstString*)item)->value<<'>'<<std::endl;
+       };);
+       cfile<<"#include <stdlib.h>"<<std::endl;
+       cfile<<"#include <stdio.h>"<<std::endl;
+       cfile<<"int main()"<<std::endl<<'{'<<std::endl; 
+       for(std::map<std::string,CAoiUserType*>::iterator 
i=globals.types.begin();i!=globals.types.end();++i)
+               cfile<<"printf(\"%i 
%i"<<'\\'<<'n'<<"\",sizeof("<<i->first<<"),__alignof("<<i->first<<"));"<<std::endl;
+       cfile<<"exit(0);"<<std::endl<<'}'<<std::endl;
+       
+       system((globals.cc+" "+ccopt+"-o "+r2+" "+r1).c_str());
+       system((r2+" > "+r3).c_str());  
+       
+       std::ifstream ifile(r3.c_str());
+       if(!ifile)
+               if(!globals.no_erase)
+               {
+                       cfile.close();
+                       ifile.close();
+                       remove(r1.c_str());
+                       remove(r2.c_str());
+                       remove(r3.c_str());
+                       assert(false);
+               };
+       
+       unsigned tmp;
+       for(std::map<std::string,CAoiUserType*>::iterator 
i=globals.types.begin();i!=globals.types.end();++i)
+       {
+               ifile>>tmp;
+               if(!ifile)
+                       if(!globals.no_erase)
+                       {
+                               cfile.close();
+                               ifile.close();
+                               remove(r1.c_str());
+                               remove(r2.c_str());
+                               remove(r3.c_str());
+                               assert(false);
+                       };
+               i->second->setSize(tmp);
+               if(!ifile)
+                       if(!globals.no_erase)
+                       {
+                               cfile.close();
+                               ifile.close();
+                               remove(r1.c_str());
+                               remove(r2.c_str());
+                               remove(r3.c_str());
+                               assert(false);
+                       };
+               i->second->setAlign(tmp);
+       };
+       
+       //for(std::map<std::string,CAoiUserType*>::iterator 
i=globals.types.begin();i!=globals.types.end();++i)
+       //      printf("%s: 
%i,%i\n",i->first.c_str(),i->second->getSize(),i->second->getAlign());
+               
+       if(!globals.no_erase)
+       {
+               cfile.close();
+               ifile.close();
+               remove(r1.c_str());
+               remove(r2.c_str());
+               remove(r3.c_str());
+       };
+};
diff -Naur idl4-old/src/base/version.cc idl4-new/src/base/version.cc
--- idl4-old/src/base/version.cc        2003-03-29 20:40:46.000000000 +0100
+++ idl4-new/src/base/version.cc        2005-09-06 20:54:20.573638008 +0200
@@ -1,6 +1,6 @@
 #include <config.h>
 
-const char* idl4_version = VERSION " (roadrunner)";
+const char* idl4_version = VERSION " (patch by ness <address@hidden>)";
 const char* idl4_build   = __DATE__ " " __TIME__;
 const char* idl4_user    = __USER__;
 const char* idl4_gcc     = __GCCVERSION__;
diff -Naur idl4-old/src/be/cross.cc idl4-new/src/be/cross.cc
--- idl4-old/src/be/cross.cc    2002-10-30 17:08:55.000000000 +0100
+++ idl4-new/src/be/cross.cc    2005-09-06 20:54:22.978272448 +0200
@@ -307,3 +307,10 @@
         } else panic("Unknown custom type: %s", aoi->identifier);
     }  
 }
+
+void CAoiCrossVisitor::visit(CAoiUserType *aoi)
+{
+       assert(globals.user_types);
+       if(!aoi->peer)
+               aoi->peer=new CBEUserType(aoi);
+};
diff -Naur idl4-old/src/be/scope.cc idl4-new/src/be/scope.cc
--- idl4-old/src/be/scope.cc    2003-02-26 15:51:00.000000000 +0100
+++ idl4-new/src/be/scope.cc    2005-09-06 20:54:22.978272448 +0200
@@ -259,8 +259,17 @@
       addWithTrailingSpacerTo(result, msFactory->buildTestIncludes());
       addTo(result, new CASTPreprocInclude(new 
CASTIdentifier(getDefaultFilename(FILE_HEADER, OUTPUT_CLIENT))));
     }
-
-  addWithTrailingSpacerTo(result, new CASTPreprocInclude(new 
CASTIdentifier(getDefaultFilename(FILE_HEADER, OUTPUT_SERVER))));
+       
+  //edit by ness
+  char* s=getDefaultFilename(FILE_HEADER, OUTPUT_SERVER);
+  unsigned i;
+  for(i=strlen(s)-1;(i>0)&&s[i]!='_';--i);
+  unsigned j;
+  for(j=i-1;(i>0)&&s[j]!='_';--j);
+  for(;s[i]!='\0';++i,++j)s[j]=s[i];
+  s[j]='\0';
+  
+  addWithTrailingSpacerTo(result, new CASTPreprocInclude(new 
CASTIdentifier(s)));
   
   if (debug_mode&DEBUG_TESTSUITE)
     addTo(result, buildTestDeclarations());
diff -Naur idl4-old/src/be/types/Makefile.am idl4-new/src/be/types/Makefile.am
--- idl4-old/src/be/types/Makefile.am   2002-10-30 17:10:53.000000000 +0100
+++ idl4-new/src/be/types/Makefile.am   2005-09-06 20:54:22.652322000 +0200
@@ -3,4 +3,4 @@
 noinst_LIBRARIES=      libtypes.a
 libtypes_a_SOURCES=    alias.cc enum.cc float.cc fpage.cc integer.cc \
                        object.cc opaque.cc pointer.cc sequence.cc string.cc \
-                       struct.cc union.cc
+                       struct.cc union.cc usertype.cc
diff -Naur idl4-old/src/be/types/pointer.cc idl4-new/src/be/types/pointer.cc
--- idl4-old/src/be/types/pointer.cc    2003-04-08 15:57:01.000000000 +0200
+++ idl4-new/src/be/types/pointer.cc    2005-09-06 20:54:22.651322152 +0200
@@ -22,8 +22,9 @@
       addTo(specifiers, new CASTTypeSpecifier(buildIdentifier()));
       return new CASTDeclaration(specifiers, decl, compound);
     }
- 
   CASTDeclaration *subdecl = getType(aoi->ref)->buildDeclaration(decl, 
compound);
+  if(!subdecl->declarators)
+    subdecl->declarators=new CASTDeclarator((CASTIdentifier*)0);
   subdecl->declarators->addIndir(1);
   return subdecl;
 }
diff -Naur idl4-old/src/be/types/usertype.cc idl4-new/src/be/types/usertype.cc
--- idl4-old/src/be/types/usertype.cc   1970-01-01 01:00:00.000000000 +0100
+++ idl4-new/src/be/types/usertype.cc   2005-09-06 20:54:22.652322000 +0200
@@ -0,0 +1,45 @@
+#include "ops.h"
+#include <cast.h>
+#define dprintln(a...) do { if (debug_mode&DEBUG_MARSHAL) println(a); } while 
(0)
+
+CBEMarshalOp *CBEUserType::buildMarshalOps(CMSConnection *connection, int 
channels, CASTExpression *rvalue, const char *name, CBEType *originalType, 
CBEParameter *param, int flags)
+{
+       CBEMarshalOp *result;
+       
+       dprintln("Marshalling %s (%s)", name, aoi->name);
+       indent(+1);
+       
+       result = new CBEOpSimpleCopy(connection, channels, rvalue, 
originalType, aoi->getAlign(), name, param, flags);
+       
+       indent(-1);
+       
+       return result;
+}
+
+CASTDeclaration *CBEUserType::buildDeclaration(CASTDeclarator *decl, 
CASTCompoundStatement *compound)
+{
+       return new CASTDeclaration(new CASTTypeSpecifier(new 
CASTIdentifier(aoi->name)), decl, compound);
+}
+
+int CBEUserType::getArgIndirLevel(CBEDeclType declType)
+{ 
+       if ((declType==INOUT) || (declType==OUT))
+               return 1;
+       
+       return 0;
+}
+
+CASTExpression *CBEUserType::buildBufferAllocation(CASTExpression *elements)
+{
+       //dummy:
+       return new CASTFunctionOp(
+    new 
CASTIdentifier("im_only_a_dummy_for_CBEUserType::buildBufferAllocation"),
+    new CASTUnaryOp("(unsigned)", 
+      elements)
+  );
+}
+
+CASTExpression *CBEUserType::buildDefaultValue()
+{
+       return new CASTIdentifier("{0,}");
+}
diff -Naur idl4-old/src/cast/cast.cc idl4-new/src/cast/cast.cc
--- idl4-old/src/cast/cast.cc   2003-08-25 06:41:22.000000000 +0200
+++ idl4-new/src/cast/cast.cc   2005-09-06 20:54:23.304222896 +0200
@@ -351,6 +351,7 @@
      } while (iterator!=this);     
 }
 
+//change by ness: print the atts before the identifier
 void CASTDeclarator::write()
 
 {
@@ -362,9 +363,17 @@
   if (qualifiers)
     {
       qualifiers->writeAll(" ");
-      if (identifier)
+      if (attributes)
         print(" ");
     }  
+       
+  if (attributes)
+    {
+      print(" ");
+      attributes->writeAll(" ");
+      if(identifier)
+        print(" ");
+    }
 
   if (identifier) 
     identifier->write();
@@ -406,12 +415,6 @@
       print(" : ");
       bitSize->write();
     }
-
-  if (attributes)
-    {
-      print(" ");
-      attributes->writeAll(" ");
-    }
     
   if (initializer)
     {
@@ -1532,4 +1535,3 @@
   
   leaveMajor("#undef");
 }
-  
diff -Naur idl4-old/src/fe/idl/parser.yy idl4-new/src/fe/idl/parser.yy
--- idl4-old/src/fe/idl/parser.yy       2003-03-27 09:59:17.000000000 +0100
+++ idl4-new/src/fe/idl/parser.yy       2005-09-06 20:54:23.607176840 +0200
@@ -331,18 +331,23 @@
 import         : IMPORT filenames {
                     while (!$2->isEmpty())
                       {
-                        CAoiConstString *thisFile = 
(CAoiConstString*)($2->removeFirstElement());
-                        CAoiList *importedTypes = importTypes(thisFile->value, 
getContext());
-                        if (importedTypes)
-                          {
-                            while (!importedTypes->isEmpty())
-                              {
-                                CAoiType *element = 
(CAoiType*)importedTypes->removeFirstElement();
-                                element->parentScope = currentScope;
-                                currentScope->types->add(element);
-                              }
-                            aoiRoot->includes->add(thisFile);
-                          } else ParseError(ERR_PARS_IMPORT_FAILED, 
thisFile->value);  
+                                                 if(globals.user_types)
+                                                         
aoiRoot->includes->add((CAoiConstString*)($2->removeFirstElement()));
+                                                 else
+                                                 {
+                                                       CAoiConstString 
*thisFile = (CAoiConstString*)($2->removeFirstElement());
+                                                       CAoiList *importedTypes 
= importTypes(thisFile->value, getContext());
+                                                       if (importedTypes)
+                                                         {
+                                                               while 
(!importedTypes->isEmpty())
+                                                                 {
+                                                                       
CAoiType *element = (CAoiType*)importedTypes->removeFirstElement();
+                                                                       
element->parentScope = currentScope;
+                                                                       
currentScope->types->add(element);
+                                                                 }
+                                                               
aoiRoot->includes->add(thisFile);
+                                                         } else 
ParseError(ERR_PARS_IMPORT_FAILED, thisFile->value);  
+                                                 }
                       }
                   }
                 | INCLUDE filenames {
@@ -408,8 +413,13 @@
                     CAoiBase *ref = currentScope->lookupSymbol($1, SYM_ANY);
                     if (!ref)
                       {
-                        GrammarError(ERR_PARS_REFERENCE_UNDEFINED);
-                        $$ = NULL;
+                        if(globals.user_types)
+                                                       $$ = 
aoiFactory->buildUserType($1,getContext());
+                                               else
+                                               {
+                                                       
GrammarError(ERR_PARS_REFERENCE_UNDEFINED);
+                                                       $$=0;
+                                               };
                       } else $$ = aoiFactory->buildRef(ref, getContext());
                   }   
                | SCOPE id {
diff -Naur idl4-old/src/include/aoi.h idl4-new/src/include/aoi.h
--- idl4-old/src/include/aoi.h  2002-10-30 17:15:04.000000000 +0100
+++ idl4-new/src/include/aoi.h  2005-09-06 20:54:20.426660352 +0200
@@ -79,6 +79,7 @@
   virtual bool isConstBase() { return false; };
   virtual bool isProperty() { return false; };
   virtual bool isParameter() { return false; };
+  virtual bool isUserType(){return false;};
 };
 
 class CAoiList : public CAoiBase
@@ -291,6 +292,21 @@
   virtual bool isVoid() { return false; };
 };
 
+class CAoiUserType : public CAoiType
+{
+protected:
+       unsigned size,align;
+public:
+       virtual bool isUserType(){return true;};
+       virtual void accept(CAoiVisitor *worker);
+       CAoiUserType(const char* ident,CAoiScope *parentScope, CAoiContext 
*context)
+               :CAoiType(ident, parentScope, context){};
+       unsigned getSize()const{return size;};
+       unsigned getAlign()const{return align;};        
+       void setAlign(unsigned a){align=a;};
+       void setSize(unsigned a){size=a;};
+};
+
 class CAoiStructType : public CAoiType
 
 {
@@ -549,6 +565,8 @@
 
 {
 public:
+  virtual CAoiRef* buildUserType(const char* id,CAoiContext *ctx)
+       {if(globals.types[id]==0)globals.types[id]=new 
CAoiUserType(id,aoiRoot,ctx);return buildRef(globals.types[id],ctx);};
   virtual CAoiRootScope *getRootScope()
     { return new CAoiRootScope(); };
   virtual CAoiModule *buildModule(CAoiScope *parentScope, const char 
*identifier, CAoiContext *context) 
@@ -655,6 +673,8 @@
   virtual void visit(CAoiProperty *peer) { assert(false); };
   virtual void visit(CAoiOperation *peer) { assert(false); };
   virtual void visit(CAoiAttribute *peer) { assert(false); };
+  
+  virtual void visit(CAoiUserType *peer) { assert(false); };
 };
 
 #endif
diff -Naur idl4-old/src/include/arch/v4_gnu.h idl4-new/src/include/arch/v4_gnu.h
--- idl4-old/src/include/arch/v4_gnu.h  1970-01-01 01:00:00.000000000 +0100
+++ idl4-new/src/include/arch/v4_gnu.h  2005-09-06 20:54:19.749763256 +0200
@@ -0,0 +1,123 @@
+#ifndef ARCH_V4_GNU_H
+#define ARCH_V4_GNU_H ARCH_V4_GNU_H
+#include "v4.h"
+#include <be.h>
+#include <cross.h>
+#ifndef NDEBUG
+#define m_assert(a,b) if(!(a))panic(b)
+#else
+#define m_assert(a,b) if(0)
+#endif
+
+#define GNU_CALL_FN(name,par)\
+CASTExpressionStatement(\
+               new CASTFunctionOp(\
+                       name,\
+                       par))
+
+#define GNU_CALL_FN_NAME(name,par)\
+CASTExpressionStatement(\
+               new CASTFunctionOp(\
+                       new CASTIdentifier(name),\
+                       new CASTIdentifier(par)))
+
+class CMSConnection4_gnu
+       :public CMSConnection4
+{
+public:
+       CMSConnection4_gnu(CMSService4 *service, int numChannels, int fid, int 
iid, int bitsPerWord)
+               :CMSConnection4(service, numChannels, fid, iid, bitsPerWord) {};
+                       
+       virtual void dump(){};
+                       
+       virtual CASTStatement* buildClientLocalVars(CASTIdentifier* key);
+       virtual CASTDeclarationStatement* buildMessageMembers(int channel);
+       virtual CASTExpression *buildLabelExpr();
+       virtual CASTStatement *buildClientCall(CASTExpression *target, 
CASTExpression *env);
+       virtual CASTStatement *buildServerDeclarations(CASTIdentifier *key);
+       virtual CASTDeclaration *buildWrapperParams(CASTIdentifier *key);
+       virtual CASTStatement *buildServerLocalVars(CASTIdentifier *key);
+       virtual CBEType *getWrapperReturnType();
+       virtual CASTExpression *buildServerCallerID();
+               
+       virtual CASTExpression *buildSourceBufferRvalue(int channel);
+       virtual CASTExpression *buildTargetBufferRvalue(int channel);
+       virtual CASTExpression *buildFCCDataSourceExpr(int channel, ChunkID 
chunk);
+               
+       virtual CASTStatement* buildServerAppendData(const char* msg);
+       virtual CASTStatement* buildServerStoreData(const char* msg);
+               
+       virtual CASTStatement* appendRegFixedToMsg(int channel,CMSChunk4* 
chunk,const char* msg);
+       virtual CASTStatement* storeRegFixedFromMsg(int channel,CMSChunk4* 
chunk,unsigned nr,const char* msg);
+       virtual CASTExpression *buildClientCallSucceeded();
+       
+       virtual CASTExpression *buildMsgTag(int channel);
+};
+
+class CMSService4_gnu
+       :public CMSService4
+{
+public:
+       virtual CMSConnection *buildConnection(int numChannels, int fid, int 
iid)
+               {return new CMSConnection4_gnu(this, numChannels, fid, iid, 
32);};
+       virtual CASTStatement *buildServerLoop(CASTIdentifier *prefix, 
CASTExpression *utableRef, CASTExpression *ktableRef, bool useItable, bool 
hasKernelMessages);
+       virtual const char* getServerTemplateBucketName(){static const char* 
s="_bucket";return s;};
+       virtual CASTStatement* buildServerDemuxer       (const char* 
ctx,CASTIdentifier *prefix, CASTExpression *utableRef,
+                                                                               
                                                                        
CASTExpression *ktableRef, bool useItable, bool hasKernelMessages);
+};
+
+class CMSFactory4_gnu
+       :public CMSFactory
+{
+private:
+       CBEType *mw_type, *tid_type;
+protected:
+       CMSFactory4_gnu(CBEType* t1,CBEType* t2)
+               :mw_type(t1),tid_type(t2){};
+public:
+       CMSFactory4_gnu()
+               :       mw_type(new CBEOpaqueType("l4_word_t", 
globals.word_size, globals.word_size, true)),
+                       tid_type(new CBEOpaqueType("l4_thread_id_t", 
globals.word_size, globals.word_size, true)){}
+       virtual CMSService *getService() { return new CMSService4_gnu(); };
+       virtual CMSService *getLocalService() { return new CMSService4_gnu(); };
+       virtual const char *getInterfaceName() { return "V4_GNU"; };
+       virtual const char *getPlatformName() { return "Generic"; };
+       virtual CBEType *getMachineWordType() { return mw_type; };
+       virtual CBEType *getThreadIDType() { return tid_type; };
+       virtual void initRootScope(CAoiRootScope *rootScope);
+};
+
+class CBEInterface_gnu
+       :public CBEInterface
+{
+public:
+       CBEInterface_gnu(CAoiInterface *aoi, CBEList *inheritedOps) : 
CBEInterface(aoi,inheritedOps){};
+               
+       virtual CASTStatement *buildReferenceDefinition();
+       virtual CASTStatement *buildServerDefinitions();
+       virtual CASTIdentifier *buildServerDemuxerName();
+       virtual CASTStatement *buildServerTemplate();
+};
+
+class CBEOperation_gnu
+       :public CBEOperation
+{
+public:
+       CBEOperation_gnu(CAoiOperation *aoi)
+               :CBEOperation(aoi){};
+       virtual CASTStatement *buildClientHeader();
+       virtual CASTStatement *buildServerHeader();
+       virtual CASTCompoundStatement* buildServerStub();
+       virtual CASTStatement *buildServerTemplate();
+       virtual void marshal(CMSService *service);
+};
+
+class CAoiCrossVisitor_gnu
+       :public CAoiCrossVisitor
+{
+public:
+       virtual void visit(CAoiInterface *aoi);
+       virtual void visit(CAoiOperation *aoi);
+};
+
+#endif //ARCH_V4_GNU_H
diff -Naur idl4-old/src/include/arch/v4.h idl4-new/src/include/arch/v4.h
--- idl4-old/src/include/arch/v4.h      2003-03-29 20:57:19.000000000 +0100
+++ idl4-new/src/include/arch/v4.h      2005-09-06 20:54:19.749763256 +0200
@@ -107,13 +107,14 @@
   virtual CASTStatement *buildServerReplyDeclarations(CASTIdentifier *key);
   virtual CASTStatement *buildServerReply();
 
-  CASTDeclarationStatement *buildMessageMembers(int channel);
+  virtual CASTDeclarationStatement *buildMessageMembers(int channel);
+  
   CASTIdentifier *buildChannelIdentifier(int channel);
   virtual CASTExpression *buildSourceBufferRvalue(int channel);
   virtual CASTExpression *buildTargetBufferRvalue(int channel);
   CASTExpression *buildMemmsgRvalue(int channel, bool isServer);
   CASTAggregateSpecifier *buildMemmsgUnion(bool isServerSide);
-  CASTExpression *buildMsgTag(int channel);
+  virtual CASTExpression *buildMsgTag(int channel);
   CASTStatement *buildMemMsgSetup(int channel);
   CASTExpression *buildMemMsgSize(int channel);
   CASTDeclarationStatement *buildClientStandardVars();
@@ -196,6 +197,9 @@
   virtual CASTStatement *buildServerBackjump(int channel, CASTExpression 
*environment);
   virtual CASTStatement *buildServerReplyDeclarations(CASTIdentifier *key);
   virtual CASTStatement *buildServerReply();
+         
+  //change by ness
+  virtual CASTBase *buildServerWrapper(CASTIdentifier *key, 
CASTCompoundStatement *compound);
 };
 
 class CMSServiceI4 : public CMSService4
diff -Naur idl4-old/src/include/base.h idl4-new/src/include/base.h
--- idl4-old/src/include/base.h 2003-03-12 14:11:14.000000000 +0100
+++ idl4-new/src/include/base.h 2005-09-06 20:54:20.431659592 +0200
@@ -54,5 +54,6 @@
 char *aprintf(const char *fmt, ...);
 void mfree(char *fmt);
 const char *getBuiltinMacro(int nr);
+void make_user_types();
 
 #endif
diff -Naur idl4-old/src/include/be.h idl4-new/src/include/be.h
--- idl4-old/src/include/be.h   2003-04-08 15:57:19.000000000 +0200
+++ idl4-new/src/include/be.h   2005-09-06 20:54:20.434659136 +0200
@@ -330,7 +330,7 @@
 class CBEInterface : public CBEScope
 
 {
-private: 
+protected: 
   CAoiInterface *aoi;
   CMSService *service;
   CBEList *inheritedOps;
@@ -343,12 +343,12 @@
   virtual void marshal();
   
   CASTStatement *buildTitleComment();
-  CASTStatement *buildReferenceDefinition();
-  CASTStatement *buildServerDefinitions();
+  virtual CASTStatement *buildReferenceDefinition();
+  virtual CASTStatement *buildServerDefinitions();
   CASTIdentifier *buildIdentifier();
   CASTStatement *buildClientHeader();
   CASTStatement *buildServerHeader();
-  CASTStatement *buildServerTemplate();
+  virtual CASTStatement *buildServerTemplate();
   CASTStatement *buildTestInvocation();
   CASTIdentifier *buildServerFuncName();
   CASTStatement *buildServerLoop();
@@ -497,6 +497,37 @@
   CASTStatement *buildTestServerCheckGeneric(CASTExpression *globalPath, 
CASTExpression *localPath, const char *text);
 };
 
+class CBEUserType : public CBEType
+{
+private: 
+  CAoiUserType *aoi;
+
+public: 
+  CBEUserType(CAoiUserType *aoi) : CBEType(aoi) { this->aoi = aoi; };
+  virtual CASTDeclaration *buildDeclaration(CASTDeclarator *decl, 
CASTCompoundStatement *compound = NULL);
+  virtual CASTStatement *buildDefinition() { return NULL; };
+  virtual CBEMarshalOp *buildMarshalOps(CMSConnection *connection, int 
channels, CASTExpression *rvalue, const char *name, CBEType *originalType, 
CBEParameter *param, int flags);
+  virtual CASTExpression *buildBufferAllocation(CASTExpression *elements);
+  virtual CASTExpression *buildDefaultValue();
+
+  virtual CASTStatement *buildTestClientInit(CASTExpression *globalPath, 
CASTExpression *localPath, CBEVarSource *varSource, CBEDeclType type, 
CBEParameter *param){panic("not implemented: 
CBEUserType::buildTestClientInit");};
+  virtual CASTStatement *buildTestClientCheck(CASTExpression *globalPath, 
CASTExpression *localPath, CBEVarSource *varSource, CBEDeclType 
type){panic("not implemented: CBEUserType::buildTestClientCheck");};
+  virtual CASTStatement *buildTestClientPost(CASTExpression *globalPath, 
CASTExpression *localPath, CBEVarSource *varSource, CBEDeclType 
type){panic("not implemented: CBEUserType::buildTestClientPost");};
+  virtual CASTStatement *buildTestClientCleanup(CASTExpression *globalPath, 
CASTExpression *localPath, CBEVarSource *varSource, CBEDeclType 
type){panic("not implemented: CBEUserType::buildTestClientCleanup");};
+  virtual CASTStatement *buildTestServerInit(CASTExpression *globalPath, 
CASTExpression *localPath, CBEVarSource *varSource, CBEDeclType type, 
CBEParameter *param, bool bufferAvailable){panic("not implemented: 
CBEUserType::buildTestServerInit");};
+  virtual CASTStatement *buildTestServerCheck(CASTExpression *globalPath, 
CASTExpression *localPath, CBEVarSource *varSource, CBEDeclType 
type){panic("not implemented: CBEUserType::buildTestServerCheck");};
+  virtual CASTStatement *buildTestServerRecheck(CASTExpression *globalPath, 
CASTExpression *localPath, CBEVarSource *varSource, CBEDeclType 
type){panic("not implemented: CBEUserType::buildTestServerRecheck");};
+  virtual CASTStatement *buildTestDisplayStmt(CASTExpression *globalPath, 
CASTExpression *localPath, CBEVarSource *varSource, CBEDeclType type, 
CASTExpression *value){panic("not implemented: 
CBEUserType::buildTestDisplayStmt");};;
+
+  virtual bool needsSpecialHandling() { return false; };
+  virtual bool needsDirectCopy() { return true; };
+  virtual int getArgIndirLevel(CBEDeclType type);
+  virtual int getFlatSize() { return aoi->getSize(); };
+  virtual int getAlignment(){ return aoi->getAlign(); };
+  virtual bool isScalar() { return false; };
+  virtual bool involvesMapping() { return false; };
+};
+
 class CBEFloatType : public CBEType
 
 {
diff -Naur idl4-old/src/include/check.h idl4-new/src/include/check.h
--- idl4-old/src/include/check.h        2002-10-30 17:16:57.000000000 +0100
+++ idl4-new/src/include/check.h        2005-09-06 20:54:20.434659136 +0200
@@ -71,6 +71,7 @@
   virtual void visit(CAoiOperation *peer);
   virtual void visit(CAoiAttribute *peer);
   virtual void visit(CAoiContext *peer);
+  virtual void visit(CAoiUserType *peer);
 };
 
 #endif
diff -Naur idl4-old/src/include/cross.h idl4-new/src/include/cross.h
--- idl4-old/src/include/cross.h        2002-10-30 17:16:57.000000000 +0100
+++ idl4-new/src/include/cross.h        2005-09-06 20:54:20.434659136 +0200
@@ -36,6 +36,8 @@
   virtual void visit(CAoiUnionElement *aoi);
   virtual void visit(CAoiOperation *aoi);
   virtual void visit(CAoiAttribute *aoi);
+  
+  virtual void visit(CAoiUserType *peer);
 };
 
 #endif
diff -Naur idl4-old/src/include/dump.h idl4-new/src/include/dump.h
--- idl4-old/src/include/dump.h 2002-10-30 17:16:57.000000000 +0100
+++ idl4-new/src/include/dump.h 2005-09-06 20:54:20.444657616 +0200
@@ -41,6 +41,8 @@
   virtual void visit(CAoiProperty *peer);
   virtual void visit(CAoiOperation *peer);
   virtual void visit(CAoiAttribute *peer);
+  
+  virtual void visit(CAoiUserType *peer);
 };
 
 #endif
diff -Naur idl4-old/src/include/globals.h idl4-new/src/include/globals.h
--- idl4-old/src/include/globals.h      2003-04-08 15:57:36.000000000 +0200
+++ idl4-new/src/include/globals.h      2005-09-06 20:54:20.450656704 +0200
@@ -3,6 +3,8 @@
 
 #include <stdio.h>
 #include <time.h>
+#include <string>
+#include <map>
 
 #define PARSER_ALLOW_UNBOUNDED
 #undef  PARSER_STRICT
@@ -31,6 +33,7 @@
 #define INTERFACE_X0 0
 #define INTERFACE_V4 1
 #define INTERFACE_V2 2
+#define INTERFACE_V4_GNU 3
 
 #define MAPPING_C 0
 #define MAPPING_CXX 1
@@ -50,6 +53,10 @@
 #define FLAG_LOOPONLY          (1<<6)
 #define FLAG_MODULESONLY       (1<<7)
 
+#define MAX_PATH 1024
+
+class CAoiUserType;
+       
 typedef struct {
                  char outfile_name[FILENAME_MAX];
                  char header_name[FILENAME_MAX];
@@ -70,6 +77,12 @@
                  int warnings;
                  int word_size;
                  struct tm time;
+                 bool with_cap_class;
+                                bool make_depend;
+                                std::string cc;
+                                bool user_types;
+                                std::map<std::string,CAoiUserType*> types;
+                                bool no_erase;
                } global_t;
 
 class CAoiRootScope;
diff -Naur idl4-old/src/include/ms.h idl4-new/src/include/ms.h
--- idl4-old/src/include/ms.h   2003-04-08 15:57:51.000000000 +0200
+++ idl4-new/src/include/ms.h   2005-09-06 20:54:20.450656704 +0200
@@ -168,6 +168,10 @@
   virtual CASTStatement *buildServerTestStructural() { panic("Not implemented: 
channel::buildServerTestStructural"); return NULL; };
   virtual CASTStatement *buildServerReplyDeclarations(CASTIdentifier *key) { 
panic("Not implemented: channel::buildServerReplyDeclarations"); return NULL; };
   virtual CASTStatement *buildServerReply() { panic("Not implemented: 
channel::buildServerReply"); return NULL; };
+
+  virtual CASTExpression *buildLabelExpr(){panic("Not implemented: 
channel::buildLabelExpr"); return NULL; };
+  virtual CASTStatement* buildServerStoreData(const char* msg){panic("Not 
implemented: channel::buildServerStoreData"); return NULL; };
+  virtual CASTStatement* buildServerAppendData(const char* msg){panic("Not 
implemented: channel::buildServerAppendData"); return NULL; };
 };
 
 class CMSService : public CMSBase
@@ -180,6 +184,8 @@
   virtual CASTStatement *buildServerLoop(CASTIdentifier *prefix, 
CASTExpression *utableRef, CASTExpression *ktableRef, bool useItable, bool 
hasKernelMessages) { panic("Not implemented: service::buildServerLoop"); return 
NULL; };
   virtual CMSConnection *getConnection(int numChannels, int fid, int iid) { 
panic("Not implemented: service::getConnection"); return NULL; };
   virtual void finalize() { panic("Not implemented: service::finalize()"); };
+  virtual const char* getServerTemplateBucketName(){panic("Not implemented: 
service::getServerTemplateBucketName()");};
+  virtual CASTStatement* buildServerDemuxer(const char* ctx,CASTIdentifier 
*prefix, CASTExpression *utableRef, CASTExpression *ktableRef, bool useItable, 
bool hasKernelMessages){panic("Not implemented: 
service::buildServerDemuxer()");};
 };
 
 class CMSFactory
diff -Naur idl4-old/src/include/user/idl4/api/v4_gnu/interface.h 
idl4-new/src/include/user/idl4/api/v4_gnu/interface.h
--- idl4-old/src/include/user/idl4/api/v4_gnu/interface.h       1970-01-01 
01:00:00.000000000 +0100
+++ idl4-new/src/include/user/idl4/api/v4_gnu/interface.h       2005-09-06 
20:54:19.966730272 +0200
@@ -0,0 +1,139 @@
+#ifndef __idl4_api_v4_gnu_interface_h__
+#define __idl4_api_v4_gnu_interface_h__
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#define IDL4_ERROR_LABEL ((uint16_t) INT16_MIN)
+
+#include <l4.h>
+#include <hurd/cap-server.h>
+
+#define IDL4_FID_BITS 6
+#define IDL4_IID_BITS 10
+
+typedef l4_thread_id_t idl4_thread_id_t;
+typedef hurd_cap_handle_t idl4_cap_handle_t;
+typedef hurd_cap_rpc_context_t idl4_cap_rpc_context_t;
+typedef hurd_cap_bucket_t idl4_cap_bucket_t;
+typedef struct hurd_cap_class idl4_cap_class;
+typedef hurd_cap_class_t idl4_cap_class_t;
+typedef hurd_cap_obj_t idl4_cap_obj_t;
+
+#define IDL4_L4_ERROR_LABEL ((uint16_t) INT16_MIN)
+
+#define idl4_cap_class_init(a,b,c,d,e,f,g) hurd_cap_class_init(a,b,c,d,e,f,g)
+#define idl4_cap_class_alloc(a,b) hurd_cap_class_alloc(a,b)
+
+#define IDL4_PERM_READ                 4
+#define IDL4_PERM_WRITE        2
+#define IDL4_PERM_EXECUTE      1
+#define IDL4_PERM_FULL          7
+
+#define IDL4_MODE_MAP          0
+#define IDL4_MODE_GRANT                2
+
+typedef struct
+{
+       l4_word_t base;
+       l4_fpage_t fpage;
+} idl4_fpage_t;
+
+typedef struct
+{
+       l4_msg_t ibuf;
+       l4_msg_t obuf;
+       unsigned long rbuf[34];
+} idl4_msgbuf_t;
+
+typedef idl4_fpage_t idl4_mapitem;
+
+typedef struct
+{
+       unsigned long len;
+       void *ptr;
+} idl4_stringitem;
+
+typedef struct
+{
+       void *ptr;
+       unsigned long len;
+} idl4_inverse_stringitem;
+
+static inline void idl4_fpage_set_base(idl4_fpage_t *fpage, unsigned long base)
+{
+       fpage->base = (fpage->base & 2) + (base & 0xFFFFFC00u) + 8;
+}
+
+static inline unsigned idl4_fpage_get_base(idl4_fpage_t fpage)
+{
+       return fpage.base & (~0x3FFu);
+}
+
+static inline void idl4_fpage_set_page(idl4_fpage_t *fpage, l4_fpage_t p)
+{
+       fpage->fpage = (fpage->fpage&7) + (p&(~3u));
+}
+
+static inline l4_word_t idl4_msg_label(l4_msg_t msg)
+{
+       return l4_msg_label(msg);
+};
+
+static inline l4_fpage_t idl4_fpage_get_page(idl4_fpage_t fpage)
+{
+       l4_fpage_t result;
+       result = fpage.fpage&(~3u);
+       return result;
+}
+
+static inline void idl4_fpage_set_permissions(idl4_fpage_t *fpage, unsigned 
permissions)
+{
+       fpage->fpage = (fpage->fpage&(~7u)) + (permissions&7);
+}
+
+static inline unsigned idl4_fpage_get_permissions(idl4_fpage_t fpage)
+{
+       return fpage.fpage & 7;
+}
+
+static inline void idl4_fpage_set_mode(idl4_fpage_t *fpage, unsigned mode)
+{
+       fpage->base = (fpage->base&(~2u)) + (mode&2);
+}
+
+static inline unsigned idl4_fpage_get_mode(idl4_fpage_t fpage)
+{
+       return fpage.base&2;
+}
+
+static inline int idl4_is_kernel_message(l4_msg_tag_t msgtag)
+{
+       return ((l4_label(msgtag)&0xFF00) == 0xFF00);
+}
+
+static inline unsigned idl4_get_kernel_message_id(l4_msg_tag_t msgtag)
+{
+  return ((unsigned)-((l4_label(msgtag))>>4));
+}
+
+static inline unsigned idl4_get_function_id(l4_word_t msg)
+{
+       return msg;
+}
+
+static inline unsigned idl4_get_interface_id(l4_msg_tag_t *msgtag)
+{
+       return ((l4_label(*msgtag)>>IDL4_FID_BITS) & ((1<<IDL4_IID_BITS)-1));
+}
+
+static inline unsigned idl4_is_error(l4_msg_tag_t *msgtag)
+{
+       return (l4_label(*msgtag)& 8);
+}
+
+#endif /* __idl4_api_v4_gnu_interface_h__ */
diff -Naur idl4-old/src/include/user/idl4/glue/v4_gnu-generic/runtime.h 
idl4-new/src/include/user/idl4/glue/v4_gnu-generic/runtime.h
--- idl4-old/src/include/user/idl4/glue/v4_gnu-generic/runtime.h        
1970-01-01 01:00:00.000000000 +0100
+++ idl4-new/src/include/user/idl4/glue/v4_gnu-generic/runtime.h        
2005-09-06 20:54:20.325675704 +0200
@@ -0,0 +1,9 @@
+#ifndef __idl4_glue_v4_generic_runtime_h__
+#define __idl4_glue_v4_generic_runtime_h__
+
+#include IDL4_INC_ARCH(helpers.h)
+#include IDL4_INC_API(interface.h)
+
+#define IDL4_INLINE inline
+
+#endif /* !defined(__idl4_glue_v4_generic_runtime_h__) */
diff -Naur idl4-old/src/include/user/idl4/glue/v4-ia32/runtime.h 
idl4-new/src/include/user/idl4/glue/v4-ia32/runtime.h
--- idl4-old/src/include/user/idl4/glue/v4-ia32/runtime.h       2003-11-07 
01:01:43.000000000 +0100
+++ idl4-new/src/include/user/idl4/glue/v4-ia32/runtime.h       2005-09-06 
20:54:20.230690144 +0200
@@ -5,10 +5,11 @@
 #include IDL4_INC_API(interface.h)
 
 #define IDL4_INLINE inline
+#define _IDL4_ALWAYS_INLINE inline __attribute__((always_inline)) 
 
 #define IDL4_IPC_ENTRY "__L4_Ipc"
  
-extern inline void *MyUTCB(void)
+_IDL4_ALWAYS_INLINE void *MyUTCB(void)
 
 {
   void *result;
@@ -18,13 +19,13 @@
   return result;
 }
 
-extern inline void *idl4_get_buffer_addr(unsigned int index)
+_IDL4_ALWAYS_INLINE void *idl4_get_buffer_addr(unsigned int index)
 
 {
   return ((void**)MyUTCB())[-(18+(index*2))];
 }
 
-extern inline int ErrorCode(void)
+_IDL4_ALWAYS_INLINE int ErrorCode(void)
 
 {
   int result;
@@ -38,7 +39,7 @@
   return result;
 }
 
-extern inline void idl4_process_request(L4_ThreadId_t *partner, L4_MsgTag_t 
*msgtag, idl4_msgbuf_t *msgbuf, long *cnt, void *func)
+_IDL4_ALWAYS_INLINE void idl4_process_request(L4_ThreadId_t *partner, 
L4_MsgTag_t *msgtag, idl4_msgbuf_t *msgbuf, long *cnt, void *func)
 
 {
   unsigned dummy;
@@ -54,7 +55,7 @@
                );
 }
 
-extern inline void idl4_reply_and_wait(L4_ThreadId_t *partner, L4_MsgTag_t 
*msgtag, idl4_msgbuf_t *msgbuf, long *cnt)
+_IDL4_ALWAYS_INLINE void idl4_reply_and_wait(L4_ThreadId_t *partner, 
L4_MsgTag_t *msgtag, idl4_msgbuf_t *msgbuf, long *cnt)
 
 {
   unsigned dummy;
@@ -90,7 +91,7 @@
                );
 }               
 
-extern inline void idl4_set_counter(unsigned value)
+_IDL4_ALWAYS_INLINE void idl4_set_counter(unsigned value)
 
 {
   asm volatile (
@@ -102,7 +103,7 @@
   );
 }
 
-extern inline void idl4_set_counter_minimum(unsigned value)
+_IDL4_ALWAYS_INLINE void idl4_set_counter_minimum(unsigned value)
 
 {
   asm volatile (
@@ -114,7 +115,7 @@
   );
 }
 
-extern inline void idl4_msgbuf_sync(idl4_msgbuf_t *msgbuf)
+_IDL4_ALWAYS_INLINE void idl4_msgbuf_sync(idl4_msgbuf_t *msgbuf)
 
 {
   unsigned dummy;
@@ -137,21 +138,21 @@
   );
 }
 
-extern inline void idl4_msgbuf_init(idl4_msgbuf_t *msgbuf)
+_IDL4_ALWAYS_INLINE void idl4_msgbuf_init(idl4_msgbuf_t *msgbuf)
 
 {
   msgbuf->rbuf[32] = 0;
   idl4_set_counter(1);
 }
 
-extern inline void idl4_msgbuf_set_rcv_window(idl4_msgbuf_t *msgbuf, 
L4_Fpage_t wnd)
+_IDL4_ALWAYS_INLINE void idl4_msgbuf_set_rcv_window(idl4_msgbuf_t *msgbuf, 
L4_Fpage_t wnd)
 
 {
   msgbuf->rbuf[32] = (msgbuf->rbuf[32]&1) + (wnd.raw & 0xFFFFFFF0u);
   idl4_set_counter_minimum(1);
 }
 
-extern inline void idl4_msgbuf_add_buffer(idl4_msgbuf_t *msgbuf, void *buf, 
unsigned len)
+_IDL4_ALWAYS_INLINE void idl4_msgbuf_add_buffer(idl4_msgbuf_t *msgbuf, void 
*buf, unsigned len)
 
 {
   int i=32;
diff -Naur idl4-old/src/include/user/idl4/Makefile.am 
idl4-new/src/include/user/idl4/Makefile.am
--- idl4-old/src/include/user/idl4/Makefile.am  2003-03-29 20:57:34.000000000 
+0100
+++ idl4-new/src/include/user/idl4/Makefile.am  2005-09-06 20:54:20.340673424 
+0200
@@ -21,6 +21,8 @@
                 glue/x0-generic/runtime.h \
                 glue/x0-ia32/runtime.h \
                 glue/x0-arm/runtime.h \
+               glue/v4_gnu-generic/runtime.h \
                 api/v2/interface.h \
                 api/x0/interface.h \
-                api/v4/interface.h
+                api/v4/interface.h \
+               api/v4_gnu/interface.h
diff -Naur idl4-old/src/Makefile.am idl4-new/src/Makefile.am
--- idl4-old/src/Makefile.am    2003-08-25 06:32:26.000000000 +0200
+++ idl4-new/src/Makefile.am    2005-09-06 20:54:24.687012680 +0200
@@ -9,6 +9,7 @@
                $(top_builddir)/src/arch/v4/libv4.a \
                $(top_builddir)/src/arch/v4/ia32/libv4i.a \
                $(top_builddir)/src/arch/v4/ia64/libv4m.a \
+                $(top_builddir)/src/arch/v4_gnu/libv4_gnu.a \
                $(top_builddir)/src/arch/x0/libx0.a \
                $(top_builddir)/src/arch/x0/ia32/libx0i.a \
                $(top_builddir)/src/base/libui.a \
@@ -39,6 +40,7 @@
                -L$(top_builddir)/src/arch/v4 -lv4 \
                -L$(top_builddir)/src/arch/v4/ia32 -lv4i \
                -L$(top_builddir)/src/arch/v4/ia64 -lv4m \
+                -L$(top_builddir)/src/arch/v4_gnu -lv4_gnu \
                -L$(top_builddir)/src/arch -larch \
                -L$(top_builddir)/src/be/types -ltypes \
                -L$(top_builddir)/src/be/ops -lops -lstdc++
diff -Naur idl4-old/TODO idl4-new/TODO
--- idl4-old/TODO       1970-01-01 01:00:00.000000000 +0100
+++ idl4-new/TODO       2005-09-06 20:54:26.038807176 +0200
@@ -0,0 +1,13 @@
+*There seems to be a problem transfering pointers?
+*in V4_GNU backend: don't transfer return values in labels
+ since hurd seems to use this to indicate internal errors
+*in V4_GNU backend: handle hurd internal errors (se above)
+*handle casts for return values  and return values that
+ can't be given through labels
+*remove all my hacks
+*cleanup the code
+*implement missing features
+*rewrite everything in (maybye a template-based completely static
+ variant and in) good C++ (use STL, no C-style casts,
+ no reinterpret_casts at all, no typeless (void*) data, no
+ C prefix, no global variables, no/very less makros).

XXX The file libhurd-mm/physmem--user.c can be deleted
--- hurd-l4-idl4-old/physmem/physmem.idl        1970-01-01 01:00:00.000000000 
+0100
+++ hurd-l4-idl4-new/physmem/physmem.idl        2005-09-06 16:33:21.198212392 
+0200
@@ -0,0 +1,16 @@
+import "stdint.h";
+import "sys/types.h";
+import "l4.h";
+import "hurd/types.h";
+import "hurd/physmem.h";
+
+interface hurd_pm_container
+{
+       hurd_pm_container_t create();
+       hurd_pm_container_t share();
+       void allocate(in l4_word_t start, in l4_word_t size,in l4_word_t flags, 
out l4_word_t amount);
+       void deallocate(in uintptr_t start, in size_t size, out size_t amount);
+       void map(in l4_word_t index, in size_t size, in uintptr_t vaddr, in 
l4_word_t flags, out size_t amount);        //this has to be treated in a 
special way
+                                                                               
                                                                                
                                                                                
                                                                                
        //(read: stuff has to be written by hand)
+       void copy(in uintptr_t src_start, in hurd_pm_container_t 
dest_container, in uintptr_t dest_start, in size_t count, in uintptr_t flags, 
out size_t amount);
+};
--- hurd-l4-idl4-old/physmem/Makefile.am        2005-09-03 08:40:54.418879944 
+0200
+++ hurd-l4-idl4-new/physmem/Makefile.am        2005-09-06 17:24:25.412315328 
+0200
@@ -31,7 +31,8 @@
 physmem_SOURCES = $(ARCH_SOURCES)                              \
        output.h output.c                                       \
        zalloc.h zalloc.c mmap.c malloc-wrap.c                  \
-       physmem.h physmem.c container.c frame-entry.c frame.c
+       physmem.h physmem.c container.c frame-entry.c frame.c \
+       physmem.idl
 
 # Doug Lea's malloc is included by malloc-wrap.c.
 EXTRA_physmem_SOURCES = malloc.c
@@ -39,9 +40,16 @@
 physmem_LDFLAGS = -u_start -e_start -N -nostdlib \
        address@hidden@
 
+BUILT_SOURCES = physmem_client.h physmem_server.h
+
 physmem_LDADD = ../libhurd-cap-server/libhurd-cap-server.a     \
        ../libhurd-slab/libhurd-slab.a                          \
        ../libpthread/libpthread.a                              \
        ../libhurd-ihash/libhurd-ihash.a                        \
        ../libhurd-btree/libhurd-btree.a                        \
        ../libc-parts/libc-parts.a -lgcc
+
+IDL4_LOCALFLAGS = "-DIN_PHYSMEM=1"
+
+#include the idl suffix rules
+include $(top_srcdir)/Makefile.idl4
--- hurd-l4-idl4-old/physmem/container.c        2005-09-03 08:40:54.431877968 
+0200
+++ hurd-l4-idl4-new/physmem/container.c        2005-09-06 21:21:15.055364832 
+0200
@@ -37,6 +37,8 @@
 #include "physmem.h"
 #include "zalloc.h"
 
+#include "physmem_server.h"
+
 #include "output.h"
 
 
@@ -82,9 +84,9 @@
   hurd_btree_frame_entry_detach (&cont->frame_entries, frame_entry);
 }
 
+
 /* CTX->obj should be a memory control object, not a container.  */
-static error_t
-container_create (hurd_cap_rpc_context_t ctx)
+IDL4_INLINE error_t 
hurd_pm_container_create_implementation(idl4_cap_rpc_context_t ctx, 
hurd_pm_container_t *ret)
 {
   error_t err;
   hurd_cap_obj_t obj;
@@ -108,25 +110,31 @@
   /* The reply message consists of a single word, a capability handle
      which the client can use to refer to the container.  */
 
-  l4_msg_append_word (ctx->msg, handle);
+  *ret= handle;
 
   return 0;
 }
 
-static error_t
-container_share (hurd_cap_rpc_context_t ctx)
+IDL4_PUBLISH_HURD_PM_CONTAINER_CREATE(hurd_pm_container_create_implementation);
+
+
+IDL4_INLINE error_t 
hurd_pm_container_share_implementation(idl4_cap_rpc_context_t _ctx, 
hurd_pm_container_t *_ret)
 {
   return EOPNOTSUPP;
 }
 
-static error_t
-container_allocate (hurd_cap_rpc_context_t ctx)
+IDL4_PUBLISH_HURD_PM_CONTAINER_SHARE(hurd_pm_container_share_implementation);
+
+
+IDL4_INLINE error_t
+hurd_pm_container_allocate_implementation      (idl4_cap_rpc_context_t ctx, 
const l4_word_t start_, const l4_word_t size_,
+                                                                               
                                                                const l4_word_t 
flags_, l4_word_t *amount_)
 {
   error_t err;
   struct container *cont = hurd_cap_obj_to_user (struct container *, ctx->obj);
-  l4_word_t flags = l4_msg_word (ctx->msg, 1);
-  uintptr_t start = l4_msg_word (ctx->msg, 2);
-  size_t size = l4_msg_word (ctx->msg, 3);
+  l4_word_t flags = (l4_word_t) flags_;
+  uintptr_t start = (l4_word_t) start_;
+  size_t size = (l4_word_t) size_;
   size_t amount;
   int i;
 
@@ -151,11 +159,13 @@
       /* FIXME: Check to make sure that the memory control object that
         this container refers to has enough memory to do each
         allocation.  */
+               
       struct frame_entry *fe = frame_entry_alloc ();
       assert (fe);
-
+         
       err = frame_entry_create (cont, fe, start + l4_address (fpages[i]),
                                l4_size (fpages[i]));
+         
       if (err)
        {
          frame_entry_free (fe);
@@ -172,19 +182,19 @@
 
   pthread_mutex_unlock (&cont->lock);
 
-  l4_msg_clear (ctx->msg);
-  l4_msg_append_word (ctx->msg, amount);
+  *amount_ = amount;
 
   return err;
 }
 
-static error_t
-container_deallocate (hurd_cap_rpc_context_t ctx)
+IDL4_PUBLISH_HURD_PM_CONTAINER_ALLOCATE(hurd_pm_container_allocate_implementation);
+
+
+IDL4_INLINE error_t 
hurd_pm_container_deallocate_implementation(idl4_cap_rpc_context_t ctx, const 
uintptr_t start_, const size_t size,  size_t *amount)
 {
   error_t err = 0;
   struct container *cont = hurd_cap_obj_to_user (struct container *, ctx->obj);
-  uintptr_t start = l4_msg_word (ctx->msg, 1);
-  const size_t size = l4_msg_word (ctx->msg, 2);
+  uintptr_t start = (uintptr_t) start_;
   size_t remaining = size;
 
   /* We require two arguments (in addition to the cap id): the start
@@ -258,13 +268,22 @@
           "left to deallocate!\n", start, cont, remaining);
 
   /* Return the amount actually deallocated.  */
-  l4_msg_append_word (ctx->msg, size - remaining);
+  *amount = size - remaining;
 
   return err;
 }
 
-static error_t
-container_map (hurd_cap_rpc_context_t ctx)
+IDL4_PUBLISH_HURD_PM_CONTAINER_DEALLOCATE(hurd_pm_container_deallocate_implementation);
+
+/* not necessary, but that makes it IMHO clearer */
+#undef IDL4_PUBLISH_HURD_PM_CONTAINER_MAP
+
+/* be VERY careful!
+   this stuff is hand written!
+   the parameters are in the original order, NOT in that prefered by idl4 */
+
+error_t
+service_hurd_pm_container_map (hurd_cap_rpc_context_t ctx)
 {
   error_t err = 0;
   struct container *cont = hurd_cap_obj_to_user (struct container *, ctx->obj);
@@ -288,13 +307,14 @@
   printf ("container_map (index:%x, size:%x, vaddr:%x, flags: %x)\n",
          index, size, vaddr, flags);
 #endif
-
+       
   /* SIZE must be a multiple of the minimum page size and VADDR must
      be aligned on a base page boundary.  */
+       
   if ((size & (L4_MIN_PAGE_SIZE - 1)) != 0
       || (vaddr & (L4_MIN_PAGE_SIZE - 1)) != 0)
     return EINVAL;
-
+  
   pthread_mutex_lock (&cont->lock);
 
   struct frame_entry *fe;
@@ -346,8 +366,10 @@
   return err;
 }
 
-static error_t
-container_copy (hurd_cap_rpc_context_t ctx)
+
+IDL4_INLINE error_t
+hurd_pm_container_copy_implementation          (idl4_cap_rpc_context_t ctx, 
const uintptr_t src_start_, const hurd_pm_container_t dest_container,
+                                                                               
                                                        const uintptr_t 
dest_start_, const size_t count_, const uintptr_t flags_, size_t *amount)
 {
   error_t err = 0;
   struct hurd_cap_ctx_cap_use *cap_use;
@@ -356,17 +378,17 @@
 
   /* SRC_START will move as we copy data; SRC_START_ORIG stays
      constant so that we can figure out how much we have copied.  */
-  uintptr_t src_start = l4_msg_word (ctx->msg, 1);
+  uintptr_t src_start = (uintptr_t) src_start_;
   const uintptr_t src_start_orig = src_start;
 
-  l4_word_t dest_cont_handle = l4_msg_word (ctx->msg, 2);
+  l4_word_t dest_cont_handle = (l4_word_t) dest_container;
   hurd_cap_obj_t dest_cap;
   struct container *dest_cont;
 
-  uintptr_t dest_start = l4_msg_word (ctx->msg, 3);
+  uintptr_t dest_start = (uintptr_t) dest_start_;
 
-  size_t count = l4_msg_word (ctx->msg, 4);
-  size_t flags = l4_msg_word (ctx->msg, 5);
+  size_t count = (size_t) count_;
+  size_t flags = (size_t) flags_;
 
   struct frame_entry *sfe_next;
   int nr_fpages;
@@ -566,56 +588,26 @@
   return err;
 }
 
-error_t
-container_demuxer (hurd_cap_rpc_context_t ctx)
-{
-  error_t err = 0;
-
-  switch (l4_msg_label (ctx->msg))
-    {
-    case hurd_pm_container_create_id:
-      err = container_create (ctx);
-      break;
-
-    case hurd_pm_container_share_id:
-      err = container_share (ctx);
-      break;
-
-    case hurd_pm_container_allocate_id:
-      err = container_allocate (ctx);
-      break;
-
-    case hurd_pm_container_deallocate_id:
-      err = container_deallocate (ctx);
-      break;
-
-    case 128: /* The old container map implementation.  */
-    case hurd_pm_container_map_id:
-      err = container_map (ctx);
-      break;
+IDL4_PUBLISH_HURD_PM_CONTAINER_COPY(hurd_pm_container_copy_implementation);
 
-    case hurd_pm_container_copy_id:
-      err = container_copy (ctx);
-      break;
 
-    default:
-      err = EOPNOTSUPP;
-    }
-
-  /* If the stub returns EOPNOTSUPP then we clear the message buffer,
-     otherwise we assume that the message buffer contains a valid
-     reply message and in which case we set the error code returned by
-     the stub and have the demuxer succeed.  */
-  if (EXPECT_FALSE (err == EOPNOTSUPP))
-    l4_msg_clear (ctx->msg);
-
-  l4_set_msg_label (ctx->msg, err);
+void *hurd_pm_container_vtable[HURD_PM_CONTAINER_DEFAULT_VTABLE_SIZE] = 
HURD_PM_CONTAINER_DEFAULT_VTABLE;
 
-  if (err)
-    debug ("%s: Returning %d to %x\n", __FUNCTION__, err, ctx->from);
+void hurd_pm_container_server(idl4_cap_bucket_t _bucket)
+{
+  hurd_cap_bucket_manage_mt(_bucket,NULL,0,0);
+}
 
+error_t hurd_pm_container_discard(idl4_cap_rpc_context_t _ctx)
+{
   return 0;
 }
+
+error_t hurd_pm_container_demuxer(idl4_cap_rpc_context_t _ctx)
+{
+  return 
(*(error_t(*)(idl4_cap_rpc_context_t))(hurd_pm_container_vtable[idl4_get_function_id(idl4_msg_label(_ctx->msg))
 & HURD_PM_CONTAINER_FID_MASK]))(_ctx);
+}
+
 
 error_t
 container_alloc (l4_word_t nr_fpages, l4_word_t *fpages,
@@ -714,5 +706,5 @@
 {
   return hurd_cap_class_init (&container_class, struct container *,
                              container_init, NULL, container_reinit, NULL,
-                             container_demuxer);
+                             hurd_pm_container_demuxer);
 }
--- hurd-l4-idl4-old/libhurd-mm/physmem-user.h  2005-09-03 08:40:51.797278488 
+0200
+++ hurd-l4-idl4-new/libhurd-mm/physmem-user.h  2005-09-06 21:22:44.682739400 
+0200
@@ -26,17 +26,21 @@
 #include <sys/types.h>
 #include <l4.h>
 #include <hurd/types.h>
+
 #include <hurd/physmem.h>
 
+/* Initialized by the machine-specific startup-code.  */
+extern struct hurd_startup_data *__hurd_startup_data;
+       
 /* Create a container in *CONTAINER managed by the physical memory
    server from the contol memory capability CONTROL.  */
-extern error_t hurd_pm_container_create (hurd_pm_control_t control,
-                                        hurd_pm_container_t *container);
+#define hurd_pm_container_create(control,container)\
+hurd_pm_container_create(__hurd_startup_data->image.server,control,container)
 
 /* Create a limited access capability for container CONTAINER, return
    in *ACCESS.  */
-extern error_t hurd_pm_container_share (hurd_pm_container_t container,
-                                       hurd_pm_container_t *access);
+#define hurd_pm_container_share(container,access)\
+hurd_pm_container_share(__hurd_startup_data->image.server,container,access)
 
 /* Allocate SIZE bytes of physical memory (which must be a multiple of
    the page size) according to the flags FLAGS into container
@@ -52,9 +56,8 @@
    frames, an 8k frame and a 4k frame.  If for some reason you need
    only 4k frames, then you must call this function multiple
    times.  */
-extern error_t hurd_pm_container_allocate (hurd_pm_container_t container,
-                                          l4_word_t start, l4_word_t size,
-                                          l4_word_t flags, l4_word_t *amount);
+#define hurd_pm_container_allocate(container,start,size,flags,amount)\
+hurd_pm_container_allocate(__hurd_startup_data->image.server,container,start,size,flags,amount)
 
 /* Deallocate SIZE bytes of physical memory starting at offset START
    in container CONTAINER.  This implicitly unmaps any extant mappings
@@ -66,8 +69,8 @@
    an allocation may also be deallocated.  Any part of the region
    without a valid mapping will be ignored (and no error
    returned).  */
-extern error_t hurd_pm_container_deallocate (hurd_pm_container_t container,
-                                            uintptr_t start, uintptr_t size);
+#define hurd_pm_container_deallocate(container,start,size)\
+hurd_pm_container_deallocate(__hurd_startup_data->image.server,container,start,size,({size_t
 t;&t;}))
                                             
 /* Map the COUNT bytes of physical memory in container CONTAINER
    starting at byte INDEX at virtual memory address VADDR of the
@@ -83,10 +86,8 @@
 
    If AMOUNT is not-NULL, *AMOUNT is set to the number of bytes
    actually mapped.  */
-extern error_t hurd_pm_container_map (hurd_pm_container_t container,
-                                     l4_word_t index, size_t size,
-                                     uintptr_t vaddr, l4_word_t flags,
-                                     size_t *amount);
+#define hurd_pm_container_map(container,index,size,vaddr,flags,amount)\
+hurd_pm_container_map(__hurd_startup_data->image.server,container,index,size,vaddr,flags,amount)
 
 /* Logically copy COUNT bytes from container SRC_CONTAINER starting at
    byte SRC_START to container DEST_CONTAINER starting at byte
@@ -106,11 +107,7 @@
 
    *AMOUNT will always contain a number of bytes which is a multiple
    of the base page size.  */
-extern error_t hurd_pm_container_copy (hurd_pm_container_t src_container,
-                                      uintptr_t src_start,
-                                      hurd_pm_container_t dest_container,
-                                      uintptr_t dest_start,
-                                      size_t count,
-                                      uintptr_t flags,
-                                      size_t *amount);
+#define 
hurd_pm_container_copy(src_container,src_start,dest_container,dest_start,count,flags,amount)\
+hurd_pm_container_copy(__hurd_startup_data->image.server,src_container,src_start,dest_container,dest_start,count,flags,amount)
+                                          
 #endif /* HURD_PHYSMEM_USER_H */
--- hurd-l4-idl4-old/physmem/physmem.h  2005-09-03 08:40:54.447875536 +0200
+++ hurd-l4-idl4-new/physmem/physmem.h  2005-09-06 21:24:10.269728200 +0200
@@ -54,16 +54,9 @@
 /* Only allocate frames suitable for DMA.  */
 #define HURD_PM_CONT_ALLOC_DMA         (1 << 11)
 
-/* RPC Identifiers.  */
-enum
-  {
-    hurd_pm_container_create_id = 130,
-    hurd_pm_container_share_id,
-    hurd_pm_container_allocate_id,
-    hurd_pm_container_deallocate_id,
-    hurd_pm_container_map_id,
-    hurd_pm_container_copy_id
-  };
+/* hard coded id  */
+#define hurd_pm_container_map_id 4u
+
 
 #include <hurd/types.h>
 
@@ -73,4 +66,56 @@
 /* Container.  */
 typedef hurd_cap_handle_t hurd_pm_container_t;
 
+#if !IN_PHYSMEM
+#define _funcdef___hurd_pm_container_map                       /* 
hurd_pm_container_map has to be writen by hand */
+#include <hurd/interfaces/physmem_client.h>
+
+#if !HAVE_OWN_hurd_pm_container_map
+static inline error_t
+hurd_pm_container_map (l4_thread_id_t physmem,hurd_pm_container_t container,
+                      l4_word_t index, size_t count,
+                      uintptr_t vaddr, l4_word_t flags,
+                      size_t *amountp)
+{
+  l4_msg_t msg;
+  l4_msg_tag_t tag;
+  int i;
+  size_t amount;
+
+  /* Let physmem take over the address space completely.  */
+  l4_accept (l4_map_grant_items (L4_COMPLETE_ADDRESS_SPACE));
+
+  l4_msg_clear (msg);
+  l4_set_msg_label (msg, hurd_pm_container_map_id);
+  l4_msg_append_word (msg, container);
+  l4_msg_append_word (msg, flags);
+  l4_msg_append_word (msg, vaddr);
+  l4_msg_append_word (msg, index);
+  l4_msg_append_word (msg, count);
+  l4_msg_load (msg);
+
+  tag = l4_call (physmem);
+  l4_msg_store (tag, msg);
+
+  if (amountp)
+    {
+      for (i = 0, amount = 0;
+          i < l4_typed_words (tag);
+          i += sizeof (l4_map_item_t) / sizeof (l4_word_t))
+       {
+         l4_map_item_t mi;
+         l4_msg_get_map_item (msg, i, &mi);
+         assert (l4_is_map_item (mi));
+         amount += l4_size (l4_map_item_snd_fpage (mi));
+       }
+
+      *amountp = amount;
+    }
+
+  return l4_msg_label (msg);
+}
+#endif
+
+#endif
+  
 #endif /* HURD_PHYSMEM_H */
--- hurd-l4-idl4-old/Makefile.am        2005-09-03 08:40:49.033698616 +0200
+++ hurd-l4-idl4-new/Makefile.am        2005-09-06 16:23:34.297434872 +0200
@@ -27,8 +27,8 @@
 SUBDIRS = libl4 platform                               \
        hurd libhurd-ihash libhurd-btree libhurd-slab   \
        libhurd-cap libhurd-cap-server                  \
-       libhurd-mm                                      \
        libpthread                                      \
-       libc-parts laden wortel physmem task deva ruth  \
+       libc-parts physmem libhurd-mm                   \
+       laden wortel task deva ruth                     \
        $(LIBC_SUBDIRS)                                 \
        doc
--- hurd-l4-idl4-old/wortel/startup.c   2005-09-03 08:40:55.600700280 +0200
+++ hurd-l4-idl4-new/wortel/startup.c   2005-09-06 16:15:05.056851208 +0200
@@ -31,6 +31,9 @@
 
 #include <hurd/types.h>
 #include <hurd/startup.h>
+
+#define HAVE_OWN_hurd_pm_container_map 1
+
 #include <hurd/physmem.h>
 
 
@@ -42,24 +45,7 @@
          l4_fpage_t start, l4_word_t size,
          l4_word_t flags, l4_word_t *amount)
 {
-  l4_msg_t msg;
-  l4_msg_tag_t tag;
-
-  l4_msg_clear (msg);
-  l4_set_msg_label (msg, hurd_pm_container_allocate_id);
-  l4_msg_append_word (msg, container);
-  l4_msg_append_word (msg, flags);
-  l4_msg_append_word (msg, start);
-  l4_msg_append_word (msg, size);
-
-  l4_msg_load (msg);
-
-  tag = l4_call (server);
-  l4_msg_store (tag, msg);
-
-  *amount = l4_msg_word (msg, 0);
-
-  return l4_msg_label (msg);
+  return hurd_pm_container_allocate(server,container,start,size,flags,amount);
 }
 
 /* Map the memory at offset OFFSET with size SIZE at address VADDR
--- hurd-l4-idl4-old/physmem/priv.h     2005-09-03 08:40:54.447875536 +0200
+++ hurd-l4-idl4-new/physmem/priv.h     2005-09-05 21:48:59.584096136 +0200
@@ -34,6 +34,8 @@
 
 #define BUG_ADDRESS    "<address@hidden>"
 
+#define IN_PHYSMEM 1
+
 int main (int argc, char *argv[]);
 
 
--- hurd-l4-idl4-old/libhurd-mm/Makefile.am     2005-09-03 08:40:51.763283656 
+0200
+++ hurd-l4-idl4-new/libhurd-mm/Makefile.am     2005-09-06 15:34:16.697055328 
+0200
@@ -34,4 +34,4 @@
        pager.c                                 \
        core.c                                  \
        anonymous.c anonymous.h                 \
-       physmem-user.h physmem-user.c
+       physmem-user.h

--- hurd-l4-idl4-old/ruth/ruth.c        2005-09-03 08:41:43.567408232 +0200
+++ hurd-l4-idl4-new/ruth/ruth.c        2005-09-02 15:33:02.358424360 +0200
@@ -184,10 +184,12 @@
          tag = l4_call (deva_id);
 };
 
-void call_ruth_class()
+error_t call_ruth_class()
 {
        error_t e;
-       ruth_class_test(ttid,ruth_cap,&e);
+       int r;
+       ruth_class_test(ttid,ruth_cap,&r,&e);
+       return r;
 };
 
 
@@ -237,8 +239,8 @@
        
        while(lock);
        printf("in ruth::main\n");
-       call_ruth_class();
-       printf("in ruth::main\n");
+       error_t foo = call_ruth_class();
+       printf("in ruth::main %i\n",foo);
        
 #if 0
   err = ruth_class_init ();
--- hurd-l4-idl4-old/ruth/ruth-class.c  2005-09-03 08:41:43.566408384 +0200
+++ hurd-l4-idl4-new/ruth/ruth-class.c  2005-09-02 15:32:53.358792512 +0200
@@ -9,13 +9,15 @@
 #include "output.h"
 #include "test_server.h"
 
-IDL4_INLINE CORBA_long ruth_class_test_implementation(idl4_cap_rpc_context_t 
_ctx, error_t *e)
+IDL4_INLINE error_t ruth_class_test_implementation(idl4_cap_rpc_context_t 
_ctx, CORBA_long* ret, error_t *e)
 
 {
-  CORBA_long __retval = 0;
+  error_t __retval = 0;
 
-  printf("in ruth_class_test\n");
+  debug("in ruth_class_test\n");
   
+  *ret = 5;
+       
   return __retval;
 }
 
@@ -29,16 +31,16 @@
   hurd_cap_bucket_manage_mt(_bucket,NULL,0,0);
 }
 
-void ruth_class_discard(idl4_cap_rpc_context_t _ctx)
+error_t ruth_class_discard(idl4_cap_rpc_context_t _ctx)
 
 {
+       return 0;
 }
 
 error_t ruth_class_demuxer(idl4_cap_rpc_context_t _ctx)
 
 {
-  
(*(void(*)(idl4_cap_rpc_context_t))(ruth_class_vtable[idl4_get_function_id(idl4_msg_label(_ctx->msg))
 & RUTH_CLASS_FID_MASK]))(_ctx);
-  return 0;
+  return 
(*(error_t(*)(idl4_cap_rpc_context_t))(ruth_class_vtable[idl4_get_function_id(idl4_msg_label(_ctx->msg))
 & RUTH_CLASS_FID_MASK]))(_ctx);
 }
 
 static struct hurd_cap_class ruth_class;
--- hurd-l4-idl4/ruth/Makefile.am       2005-09-07 17:11:25.573193792 +0200
+++ hurd-l4-idl42/ruth/Makefile.am      2005-09-07 17:10:27.450029856 +0200
@@ -50,5 +50,7 @@
        ../libhurd-btree/libhurd-btree.a                        \
        ../libc-parts/libc-parts.a -lgcc
 
+nonpublic_interfaces = test.idl
+
 #include the idl suffix rules
 include $(top_srcdir)/Makefile.idl4

XXX the files ruth/task-user.c and deva/task-user.c can be deleted!!

--- hurd-l4-idl4-old/task/Makefile.am   2005-09-03 08:40:55.339739952 +0200
+++ hurd-l4-idl4-new/task/Makefile.am   2005-08-29 15:51:03.674763568 +0200
@@ -31,13 +31,16 @@
 task_SOURCES = $(ARCH_SOURCES)                                 \
        output.h output.c                                       \
        mmap.c malloc-wrap.c                                    \
-       task.h task.c task-class.c task-id.c thread.c
+       task.h task.c task-class.c task-id.c thread.c           \
+       task.idl
 
 # Doug Lea's malloc is included by malloc-wrap.c.
 EXTRA_task_SOURCES = malloc.c
 
 task_LDFLAGS = -u_start -e_start -nostdlib
 
+BUILT_SOURCES = task_client.h task_server.h
+
 task_LDADD = ../libhurd-cap-server/libhurd-cap-server.a                \
        ../libhurd-mm/libhurd-mm.a                              \
        ../libhurd-slab/libhurd-slab.a                          \
@@ -45,3 +48,6 @@
        ../libhurd-ihash/libhurd-ihash.a                        \
        ../libhurd-btree/libhurd-btree.a                        \
        ../libc-parts/libc-parts.a -lgcc
+
+#include the idl suffix rules
+include $(top_srcdir)/Makefile.idl4
--- hurd-l4-idl4-old/task/task.idl      1970-01-01 01:00:00.000000000 +0100
+++ hurd-l4-idl4-new/task/task.idl      2005-09-02 15:12:48.359980176 +0200
@@ -0,0 +1,6 @@
+import "l4/types.h";
+
+interface task
+{
+       void thread_alloc(in void* utcb,out l4_thread_id_t tid);
+};
--- hurd-l4-idl4-old/task/task.c        2005-09-03 08:40:55.362736456 +0200
+++ hurd-l4-idl4-new/task/task.c        2005-08-29 16:29:45.343886216 +0200
@@ -204,7 +204,7 @@
 
 
 void *
-task_server (void *arg)
+task_server_pth (void *arg)
 {
   hurd_cap_bucket_t bucket = (hurd_cap_bucket_t) arg;
   error_t err;
@@ -264,7 +264,7 @@
 
   /* Create the server thread and start serving RPC requests.  */
   err = pthread_create_from_l4_tid_np (&manager, NULL, server_thread,
-                                      task_server, bucket);
+                                      task_server_pth, bucket);
 
   if (err)
     panic ("pthread_create_from_l4_tid_np: %i", err);
--- hurd-l4-idl4-old/task/task-class.c  2005-09-03 08:40:55.360736760 +0200
+++ hurd-l4-idl4-new/task/task-class.c  2005-09-02 15:25:37.064119384 +0200
@@ -54,9 +54,12 @@
      allocation.  */
 }
 
-
-error_t
-task_thread_alloc (hurd_cap_rpc_context_t ctx)
+#include "task_server.h"
+
+/* Interface task */
+
+IDL4_INLINE error_t task_thread_alloc_implementation(idl4_cap_rpc_context_t 
ctx, const void *_utcb, l4_thread_id_t *tid)
+
 {
   task_t task = hurd_cap_obj_to_user (task_t, ctx->obj);
   error_t err;
@@ -65,7 +68,7 @@
   l4_word_t result;
 
   /* Does not need to be checked.  */
-  utcb = (void *) l4_msg_word (ctx->msg, 1);
+  utcb = (void *) _utcb;
 
   err = thread_alloc (&thread);
   if (err)
@@ -89,33 +92,32 @@
   task->threads = thread;
   task->nr_threads++;
 
-  /* Prepare reply message.  */
-  l4_msg_clear (ctx->msg);
-  l4_msg_append_word (ctx->msg, thread->thread_id);
+  *tid = thread->thread_id;
 
   return 0;
 }
 
+IDL4_PUBLISH_TASK_THREAD_ALLOC(task_thread_alloc_implementation);
 
-error_t
-task_demuxer (hurd_cap_rpc_context_t ctx)
-{
-  error_t err = 0;
+void *task_vtable[TASK_DEFAULT_VTABLE_SIZE] = TASK_DEFAULT_VTABLE;
 
-  switch (l4_msg_label (ctx->msg))
-    {
-      /* TASK_THREAD_ALLOC */
-    case 512:
-      err = task_thread_alloc (ctx);
-      break;
+void task_server(idl4_cap_bucket_t _bucket)
 
-    default:
-      err = EOPNOTSUPP;
-    }
+{
+  hurd_cap_bucket_manage_mt(_bucket,NULL,0,0);
+}
+
+error_t task_discard(idl4_cap_rpc_context_t _ctx)
 
-  return err;
+{
+       return 0;
 }
 
+error_t task_demuxer(idl4_cap_rpc_context_t _ctx)
+
+{
+  return 
(*(error_t(*)(idl4_cap_rpc_context_t))(task_vtable[idl4_get_function_id(idl4_msg_label(_ctx->msg))
 & TASK_FID_MASK]))(_ctx);
+}
 
 
 static struct hurd_cap_class task_class;
--- hurd-l4-idl4-old/deva/Makefile.am   2005-09-03 08:40:49.331653320 +0200
+++ hurd-l4-idl4-new/deva/Makefile.am   2005-08-29 16:57:41.300102144 +0200
@@ -31,7 +31,7 @@
 deva_SOURCES = $(ARCH_SOURCES)                                 \
        output.h output.c                                       \
        mmap.c malloc-wrap.c                                    \
-       task-user.h task-user.c                                 \
+       task-user.h \
        deva.h deva.c                                           \
        device.h device.c device-console.c device-serial.c
 
--- hurd-l4-idl4-old/deva/task-user.h   2005-09-03 08:40:49.339652104 +0200
+++ hurd-l4-idl4-new/deva/task-user.h   2005-08-29 16:59:06.642128184 +0200
@@ -28,10 +28,6 @@
 
 #include <hurd/types.h>
 
-
-/* Allocate a new thread for the task TASK, and return its thread ID
-   in THREAD_ID.  */
-error_t task_thread_alloc (l4_thread_id_t task_server, hurd_cap_handle_t task,
-                          void *utcb, l4_thread_id_t *thread_id);
+#include <hurd/task.h>
 
 #endif /* HURD_TASK_USER_H */
--- hurd-l4-idl4-old/ruth/task-user.h   2005-09-03 08:40:55.222757736 +0200
+++ hurd-l4-idl4-new/ruth/task-user.h   2005-08-29 16:58:12.263395008 +0200
@@ -28,10 +28,6 @@
 
 #include <hurd/types.h>
 
-
-/* Allocate a new thread for the task TASK, and return its thread ID
-   in THREAD_ID.  */
-error_t task_thread_alloc (l4_thread_id_t task_server, hurd_cap_handle_t task,
-                          void *utcb, l4_thread_id_t *thread_id);
+#include <hurd/task.h>
 
 #endif /* HURD_TASK_USER_H */
--- hurd-l4-idl4-old/ruth/ia32-cmain.c  2005-09-03 08:40:55.176764728 +0200
+++ hurd-l4-idl4-new/ruth/ia32-cmain.c  2005-09-04 13:14:08.396435728 +0200
@@ -31,6 +31,7 @@
 #include <l4/stubs-init.h>
 
 #include "ruth.h"
+#include "task-user.h"
 
 #include <hurd/wortel.h>
 #include <hurd/startup.h>
--- hurd-l4-idl4-old/deva/ia32-cmain.c  2005-09-03 08:40:49.226669280 +0200
+++ hurd-l4-idl4-new/deva/ia32-cmain.c  2005-09-04 13:09:44.819680520 +0200
@@ -31,6 +31,7 @@
 #include <l4/stubs-init.h>
 
 #include "deva.h"
+#include "task-user.h"
 
 #include <hurd/wortel.h>
 #include <hurd/startup.h>
--- hurd-l4-idl4/ruth/Makefile.am       2005-09-07 17:12:53.547819616 +0200
+++ hurd-l4-idl4-new/ruth/Makefile.am   2005-09-07 16:46:41.787015304 +0200
@@ -31,7 +31,7 @@
 ruth_SOURCES = $(ARCH_SOURCES)                                 \
        output.h output.c                                       \
        mmap.c malloc-wrap.c                                    \
-       task-user.h task-user.c                                 \
+       task-user.h \
        ruth.h ruth.c                                           \
        ruth-class.c test.idl
 
--- /dev/null   2005-09-07 17:39:14.902798592 +0200
+++ hurd-l4-idl4-new/task/task_public.h 2005-09-06 20:51:24.530400648 +0200
@@ -0,0 +1,30 @@
+/* task_public.h/task.h - Interfaces exported by task.
+   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+   Written by Tom Bachmann <address@hidden>.
+
+   This file is part of the GNU Hurd.
+
+   The GNU Hurd is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+   
+   The GNU Hurd is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with the GNU Hurd; see the file COPYING.  If not, write to
+   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
+   USA.  */
+#ifndef HURD_TASK_TASK_PUBLIC_H
+#define HURD_TASK_TASK_PUBLIC_H HURD_TASK_TASK_PUBLIC_H
+
+#if !IN_TASK
+
+#include <hurd/interfaces/task_client.h>
+
+#endif //IN_TASK
+
+#endif HURD_TASK_TASK_PUBLIC_H
--- /dev/null   2005-09-07 17:39:14.902798592 +0200
+++ hurd-l4-idl4-new/task/headers.m4    2005-09-07 15:48:54.325768984 +0200
@@ -0,0 +1,13 @@
+# headers.m4 - Autoconf snippets to install links for header files.
+# Copyright 2005 Free Software Foundation, Inc.
+# Written by Tom Bachmann <address@hidden>.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This file is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+AC_CONFIG_LINKS([include/hurd/task.h:task/task_public.h])

reply via email to

[Prev in Thread] Current Thread [Next in Thread]