public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/m2link] Support library C files changed to C++ with dynamic scaffold signature.
@ 2022-06-29  0:43 Gaius Mulley
  0 siblings, 0 replies; only message in thread
From: Gaius Mulley @ 2022-06-29  0:43 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:56ec5f3245333e2dea1afc721bf2c8bd4a8bb27e

commit 56ec5f3245333e2dea1afc721bf2c8bd4a8bb27e
Author: Gaius Mulley <gaius.mulley@southwales.ac.uk>
Date:   Wed Jun 29 01:02:40 2022 +0100

    Support library C files changed to C++ with dynamic scaffold signature.
    
    This patch moves more of the C support files in the modula-2 library
    into C++ files with a dynamic scaffold signature.  It also tidied
    up the interface to UnixArgs and required a rebuild of the bootstrap
    tool mc.
    
    2022-06-29  Gaius Mulley  <gaius.mulley@southwales.ac.uk>
    
    gcc/m2/ChangeLog:
    
            * bnf/gm2l.bnf (BlockInfoPtr): Capitalized comment starts.
            * gm2-libs-ch/UnixArgs.cc: Rewritten from UnixArgs.c in C++
            with ctor scaffold.
            * gm2-libs-ch/dtoa.cc (M2_dtoa_init): Added correct argc,
            argv, envp parameters.  (M2_dtoa_finish) Added correct argc,
            argv, envp parameters.  (M2_dtoa_dep) New function.
            (M2_dtoa_ctor) New function.
            * gm2-libs-ch/ldtoa.cc (M2_ldtoa_init): Added correct argc,
            argv, envp parameters.  (M2_ldtoa_finish) Added correct argc,
            argv, envp parameters.  (M2_ldtoa_dep) New function.
            (M2_ldtoa_ctor) New function.
            * gm2-libs-iso/ProgramArgs.mod: Changed to use GetArgC and
            GetArgV.
            * gm2-libs/Args.def: Renamed parameter name from i to n.
            * gm2-libs/Args.mod: Changed to use GetArgC and
            GetArgV.
            * gm2-libs/SArgs.def: Renamed parameter name from i to n.
            * gm2-libs/SArgs.mod: Changed to use GetArgC and
            GetArgV.
            * gm2-libs/UnixArgs.def: Rewritten to export GetArgC, GetArgV
            and GetEnvV.
            * init/mcinit: Commented out M2Dependent.
            * mc-boot-ch/GM2LINK.c: Include cstddef.h and declare
            ForcedModuleInitOrder.
            * mc-boot-ch/GUnixArgs.cc: Rewritten in C++ from GUnixArgs.c.
            * mc-boot/GArgs.c: Rebuilt.
            * mc-boot/GArgs.h: Rebuilt.
            * mc-boot/GM2RTS.c: Rebuilt.
            * mc-boot/GM2RTS.h: Rebuilt.
            * mc-boot/GSArgs.c: Rebuilt.
            * mc-boot/GSArgs.h: Rebuilt.
            * mc-boot/GUnixArgs.h: Rebuilt.
            * mc-boot/Gdecl.c: Rebuilt.
            * mc/mc.flex: Rebuilt.
    
    libgm2/ChangeLog:
    
            * libm2pim/Makefile.am (libm2pim_la_SOURCES): UnixArgs.c
            removed UnixArgs.cc added.  (libm2pim_la_SOURCES) sckt.c
            removed sckt.cc added.  (libm2pim_la_SOURCES) dtoa.c
            removed dtoa.cc added.  (libm2pim_la_SOURCES) ldtoa.c
            removed ldtoa.cc added.  (libm2pim_la_SOURCES) Selective.c
            removed Selective.cc added.
            * libm2pim/UnixArgs.cc: Rewritten in C++.
            * libm2pim/dtoa.cc: Rewritten in C++.
            * libm2pim/ldtoa.cc: Rewritten in C++.
            * libm2pim/sckt.cc: Rewritten in C++.
    
    Signed-off-by: Gaius Mulley <gaius.mulley@southwales.ac.uk>

Diff:
---
 gcc/m2/bnf/gm2l.bnf                           |  12 +-
 gcc/m2/gm2-libs-ch/UnixArgs.c                 |  71 ++-
 gcc/m2/gm2-libs-ch/dtoa.c                     |  31 +-
 gcc/m2/gm2-libs-ch/ldtoa.c                    |  25 +-
 gcc/m2/gm2-libs-iso/ProgramArgs.mod           |  17 +-
 gcc/m2/gm2-libs/Args.def                      |   2 +-
 gcc/m2/gm2-libs/Args.mod                      |  14 +-
 gcc/m2/gm2-libs/SArgs.def                     |   2 +-
 gcc/m2/gm2-libs/SArgs.mod                     |  12 +-
 gcc/m2/gm2-libs/UnixArgs.def                  |  11 +-
 gcc/m2/init/mcinit                            |   1 +
 gcc/m2/mc-boot-ch/GM2LINK.c                   |   3 +
 gcc/m2/mc-boot-ch/GUnixArgs.c                 |  44 --
 gcc/m2/mc-boot/GArgs.c                        |  14 +-
 gcc/m2/mc-boot/GArgs.h                        |   2 +-
 gcc/m2/mc-boot/GM2RTS.c                       | 822 ++------------------------
 gcc/m2/mc-boot/GM2RTS.h                       |  14 +-
 gcc/m2/mc-boot/GSArgs.c                       |  12 +-
 gcc/m2/mc-boot/GSArgs.h                       |   2 +-
 gcc/m2/mc-boot/GUnixArgs.h                    |   7 +-
 gcc/m2/mc-boot/Gdecl.c                        |   2 +-
 gcc/m2/mc/mc.flex                             |   3 +
 libgm2/libm2pim/Makefile.am                   |   8 +-
 libgm2/libm2pim/{Selective.c => Selective.cc} |  76 ++-
 libgm2/libm2pim/{UnixArgs.c => UnixArgs.cc}   |  65 +-
 libgm2/libm2pim/{dtoa.c => dtoa.cc}           |  39 +-
 libgm2/libm2pim/{ldtoa.c => ldtoa.cc}         |  37 +-
 libgm2/libm2pim/{sckt.c => sckt.cc}           |  54 +-
 28 files changed, 431 insertions(+), 971 deletions(-)

diff --git a/gcc/m2/bnf/gm2l.bnf b/gcc/m2/bnf/gm2l.bnf
index 88cbb1ddc62..633a85c3cd9 100644
--- a/gcc/m2/bnf/gm2l.bnf
+++ b/gcc/m2/bnf/gm2l.bnf
@@ -109,8 +109,8 @@ TYPE
                        END ;
 
    BlockInfoPtr = POINTER TO RECORD
-                                LocalModules,                (* locally declared modules at the current level  *)
-                                ImportedModules: List ;      (* current list of imports for the scanned module *)
+                                LocalModules,                (* Locally declared modules at the current level  *)
+                                ImportedModules: List ;      (* Current list of imports for the scanned module *)
                                 Prev           : BlockInfoPtr ;
                              END ;
 
@@ -120,9 +120,9 @@ VAR
    LastIdent,
    MainSrc,
    MainName       : Name ;
-   Head, Tail     : Source ;    (* head source list *)
-   IncludeM2RTS   : BOOLEAN ;   (* do we automatically include M2RTS into the top module? *)
-   pSource        : Source ;    (* current module being parsed *)
+   Head, Tail     : Source ;    (* Head source list *)
+   IncludeM2RTS   : BOOLEAN ;   (* Do we automatically include M2RTS into the top module? *)
+   pSource        : Source ;    (* Current module being parsed *)
    CommentChar    : CHAR ;
    pBlock         : BlockInfoPtr ;
 
@@ -134,7 +134,7 @@ VAR
 PROCEDURE ExamineCompilationUnit (VAR name: Name; VAR isdefimp: BOOLEAN) ;
 BEGIN
    isdefimp := FALSE ;   (* default to program module *)
-   (* stop if we see eof, ';' or '[' *)
+   (* Stop if we see eof, ';' or '[' *)
    WHILE (currenttoken # eoftok) AND (currenttoken # semicolontok) AND (currenttoken # lsbratok) DO
       IF (currenttoken = implementationtok) OR (currenttoken = definitiontok)
       THEN
diff --git a/gcc/m2/gm2-libs-ch/UnixArgs.c b/gcc/m2/gm2-libs-ch/UnixArgs.c
index 137df05a252..1180f351b24 100644
--- a/gcc/m2/gm2-libs-ch/UnixArgs.c
+++ b/gcc/m2/gm2-libs-ch/UnixArgs.c
@@ -1,7 +1,7 @@
-/* UnixArgs.c provide access to the underlying argv, argc.
+/* UnixArgs.cc record argc, argv as global variables.
 
-Copyright (C) 2010-2022 Free Software Foundation, Inc.
-Contributed by Gaius Mulley <gaius@glam.ac.uk>.
+Copyright (C) 2009-2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
 
 This file is part of GNU Modula-2.
 
@@ -24,25 +24,68 @@ a copy of the GCC Runtime Library Exception along with this program;
 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 <http://www.gnu.org/licenses/>.  */
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include <config.h>
+#include "m2rts.h"
 
-int UnixArgs_ArgC;
-char **UnixArgs_ArgV;
 
-void
-_M2_UnixArgs_init (int argc, char *argv[])
+extern "C" int UnixArgs_GetArgC (void);
+extern "C" char **UnixArgs_GetArgV (void);
+extern "C" char **UnixArgs_GetEnvV (void);
+
+static int UnixArgs_ArgC;
+static char **UnixArgs_ArgV;
+static char **UnixArgs_EnvV;
+
+
+/* GetArgC returns argc.  */
+
+extern "C" int
+UnixArgs_GetArgC (void)
+{
+  return UnixArgs_ArgC;
+}
+
+
+/* GetArgV returns argv.  */
+
+extern "C" char **
+UnixArgs_GetArgV (void)
+{
+  return UnixArgs_ArgV;
+}
+
+
+/* GetEnvV returns envv.  */
+
+extern "C" char **
+UnixArgs_GetEnvV (void)
+{
+  return UnixArgs_EnvV;
+}
+
+
+extern "C" void
+_M2_UnixArgs_init (int argc, char *argv[], char *envp[])
 {
   UnixArgs_ArgC = argc;
   UnixArgs_ArgV = argv;
+  UnixArgs_EnvV = envp;
 }
 
-void
-_M2_UnixArgs_finish (int argc, char *argv[])
+extern "C" void
+_M2_UnixArgs_finish (int argc, char *argv[], char *envp[])
 {
 }
 
-#ifdef __cplusplus
+extern "C" void
+_M2_UnixArgs_dep (void)
+{
+}
+
+struct _M2_UnixArgs_ctor { _M2_UnixArgs_ctor (); } _M2_UnixArgs_ctor;
+
+_M2_UnixArgs_ctor::_M2_UnixArgs_ctor (void)
+{
+  M2RTS_RegisterModule ("UnixArgs", _M2_UnixArgs_init, _M2_UnixArgs_finish,
+			_M2_UnixArgs_dep);
 }
-#endif
diff --git a/gcc/m2/gm2-libs-ch/dtoa.c b/gcc/m2/gm2-libs-ch/dtoa.c
index 193aed9a42c..57317588ba1 100644
--- a/gcc/m2/gm2-libs-ch/dtoa.c
+++ b/gcc/m2/gm2-libs-ch/dtoa.c
@@ -29,7 +29,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #include "ansidecl.h"
 
 #include "gm2-libs-host.h"
-
+#include "m2rts.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -172,14 +172,35 @@ dtoa_dtoa (double d, int mode, int ndigits, int *decpt, int *sign)
 /* GNU Modula-2 hooks */
 
 void
-_M2_dtoa_init (void)
+_M2_dtoa_init (int, char **, char **)
 {
 }
 
 void
-_M2_dtoa_finish (void)
+_M2_dtoa_finish (int, char **, char **)
 {
 }
-#   ifdef __cplusplus
+
+void
+_M2_dtoa_dep (void)
+{
 }
-#   endif
+
+#ifdef __cplusplus
+}
+
+struct _M2_dtoa_ctor { _M2_dtoa_ctor (); } _M2_dtoa_ctor;
+
+_M2_dtoa_ctor::_M2_dtoa_ctor (void)
+{
+  M2RTS_RegisterModule ("dtoa", _M2_dtoa_init, _M2_dtoa_finish,
+			_M2_dtoa_dep);
+}
+
+#else
+void
+_M2_dtoa_ctor (void)
+{
+}
+
+#endif
diff --git a/gcc/m2/gm2-libs-ch/ldtoa.c b/gcc/m2/gm2-libs-ch/ldtoa.c
index 6209f1bc260..ac14297ec24 100644
--- a/gcc/m2/gm2-libs-ch/ldtoa.c
+++ b/gcc/m2/gm2-libs-ch/ldtoa.c
@@ -29,6 +29,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #include "ansidecl.h"
 
 #include "gm2-libs-host.h"
+#include "m2rts.h"
 
 #   ifdef __cplusplus
 extern "C" {
@@ -100,15 +101,35 @@ ldtoa_ldtoa (long double d, int mode, int ndigits, int *decpt, int *sign)
 /* GNU Modula-2 hooks */
 
 void
-_M2_ldtoa_init (void)
+_M2_ldtoa_init (int, char **, char **)
 {
 }
 
 void
-_M2_ldtoa_finish (void)
+_M2_ldtoa_finish (int, char **, char **)
+{
+}
+
+void
+_M2_ldtoa_dep (void)
 {
 }
 
 #   ifdef __cplusplus
 }
+
+struct _M2_ldtoa_ctor { _M2_ldtoa_ctor (); } _M2_ldtoa_ctor;
+
+_M2_ldtoa_ctor::_M2_ldtoa_ctor (void)
+{
+  M2RTS_RegisterModule ("ldtoa", _M2_ldtoa_init, _M2_ldtoa_finish,
+			_M2_ldtoa_dep);
+}
+
+#else
+void
+_M2_ldtoa_ctor (void)
+{
+}
+
 #   endif
diff --git a/gcc/m2/gm2-libs-iso/ProgramArgs.mod b/gcc/m2/gm2-libs-iso/ProgramArgs.mod
index cc270166719..f25e1e92578 100644
--- a/gcc/m2/gm2-libs-iso/ProgramArgs.mod
+++ b/gcc/m2/gm2-libs-iso/ProgramArgs.mod
@@ -30,7 +30,7 @@ FROM RTgen IMPORT ChanDev, InitChanDev, DeviceType, doLook, doSkip, doSkipLook,
                   doReadText, doReadLocs ;
 
 FROM SYSTEM IMPORT ADDRESS, ADR ;
-FROM UnixArgs IMPORT ArgC, ArgV ;
+FROM UnixArgs IMPORT GetArgC, GetArgV ;
 FROM RTgenif IMPORT GenDevIF, InitGenDevIF ;
 FROM RTdata IMPORT ModuleId, MakeModuleId, InitData, GetData ;
 FROM IOLink IMPORT DeviceId, DeviceTablePtr, DeviceTablePtrValue, AllocateDeviceId, MakeChan, RAISEdevException ;
@@ -127,7 +127,7 @@ BEGIN
       currentPos := 0 ;
       currentArg := 0 ;
       argLength := strlen(currentPtr)+1 ;
-      argc := ArgC
+      argc := GetArgC ()
    END
 END reset ;
 
@@ -382,15 +382,16 @@ END NextArg ;
 
 PROCEDURE collectArgs ;
 VAR
-   i, n: CARDINAL ;
+   i   : INTEGER ;
+   n   : CARDINAL ;
    pp  : POINTER TO PtrToChar ;
    p, q: PtrToChar ;
 BEGIN
    (* count the number of bytes necessary to remember all arg data *)
    n := 0 ;
    i := 0 ;
-   pp := ArgV ;
-   WHILE i<ArgC DO
+   pp := GetArgV () ;
+   WHILE i < GetArgC () DO
       p := pp^ ;
       WHILE p^#nul DO
          INC(p) ;
@@ -404,9 +405,9 @@ BEGIN
    (* now allocate correct amount of memory and copy the data *)
    ALLOCATE(ArgData, ArgLength) ;
    i := 0 ;
-   pp := ArgV ;
+   pp := GetArgV () ;
    q := ArgData ;
-   WHILE i<ArgC DO
+   WHILE i < GetArgC () DO
       p := pp^ ;
       WHILE p^#nul DO
          q^ := p^ ;
@@ -450,7 +451,7 @@ BEGIN
       currentPos := 0 ;
       currentArg := 0 ;
       argLength := strlen(currentPtr)+1 ;
-      argc := ArgC
+      argc := GetArgC ()
    END ;
    d := DeviceTablePtrValue(cid, did) ;
    InitData(d, mid, a, freeData) ;
diff --git a/gcc/m2/gm2-libs/Args.def b/gcc/m2/gm2-libs/Args.def
index e576670fb6a..b252d428122 100644
--- a/gcc/m2/gm2-libs/Args.def
+++ b/gcc/m2/gm2-libs/Args.def
@@ -34,7 +34,7 @@ EXPORT QUALIFIED GetArg, Narg ;
             The success of the operation is returned.
 *)
 
-PROCEDURE GetArg (VAR a: ARRAY OF CHAR; i: CARDINAL) : BOOLEAN ;
+PROCEDURE GetArg (VAR a: ARRAY OF CHAR; n: CARDINAL) : BOOLEAN ;
 
 
 (*
diff --git a/gcc/m2/gm2-libs/Args.mod b/gcc/m2/gm2-libs/Args.mod
index 62d8a376974..2b8dc03335e 100644
--- a/gcc/m2/gm2-libs/Args.mod
+++ b/gcc/m2/gm2-libs/Args.mod
@@ -27,7 +27,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 IMPLEMENTATION MODULE Args ;
 
 
-FROM UnixArgs IMPORT ArgC, ArgV ;
+FROM UnixArgs IMPORT GetArgC, GetArgV ;
 FROM ASCII IMPORT nul ;
 
 
@@ -50,16 +50,18 @@ VAR
             The success of the operation is returned.
 *)
 
-PROCEDURE GetArg (VAR a: ARRAY OF CHAR; i: CARDINAL) : BOOLEAN ;
+PROCEDURE GetArg (VAR a: ARRAY OF CHAR; n: CARDINAL) : BOOLEAN ;
 VAR
+   i   : INTEGER ;
    High,
    j   : CARDINAL ;
 BEGIN
+   i := VAL (INTEGER, n) ;
    j := 0 ;
    High := HIGH(a) ;
-   IF i<ArgC
+   IF i < GetArgC ()
    THEN
-      Source := ArgV ;
+      Source := GetArgV () ;
       WHILE (Source^[i]^[j]#nul) AND (j<High) DO
          a[j] := Source^[i]^[j] ;
          INC(j)
@@ -69,7 +71,7 @@ BEGIN
    THEN
       a[j] := nul
    END ;
-   RETURN( i<ArgC )
+   RETURN i < GetArgC ()
 END GetArg ;
 
 
@@ -80,7 +82,7 @@ END GetArg ;
 
 PROCEDURE Narg () : CARDINAL ;
 BEGIN
-   RETURN( ArgC )
+   RETURN GetArgC ()
 END Narg ;
 
 
diff --git a/gcc/m2/gm2-libs/SArgs.def b/gcc/m2/gm2-libs/SArgs.def
index 404bee3bd94..cf8164ff905 100644
--- a/gcc/m2/gm2-libs/SArgs.def
+++ b/gcc/m2/gm2-libs/SArgs.def
@@ -37,7 +37,7 @@ EXPORT QUALIFIED GetArg, Narg ;
             new string, otherwise s is set to NIL.
 *)
 
-PROCEDURE GetArg (VAR s: String ; i: CARDINAL) : BOOLEAN ;
+PROCEDURE GetArg (VAR s: String ; n: CARDINAL) : BOOLEAN ;
 
 
 (*
diff --git a/gcc/m2/gm2-libs/SArgs.mod b/gcc/m2/gm2-libs/SArgs.mod
index 3f8bcaebd45..3e167bf6736 100644
--- a/gcc/m2/gm2-libs/SArgs.mod
+++ b/gcc/m2/gm2-libs/SArgs.mod
@@ -27,7 +27,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 IMPLEMENTATION MODULE SArgs ;
 
 FROM SYSTEM IMPORT TSIZE, ADDRESS ;
-FROM UnixArgs IMPORT ArgC, ArgV ;
+FROM UnixArgs IMPORT GetArgC, GetArgV ;
 
 FROM DynamicStrings IMPORT InitStringCharStar,
                            InitStringDB, InitStringCharStarDB,
@@ -57,14 +57,16 @@ if defined(GM2_DEBUG_SARGS)
             new string, otherwise s is set to NIL.
 *)
 
-PROCEDURE GetArg (VAR s: String; i: CARDINAL) : BOOLEAN ;
+PROCEDURE GetArg (VAR s: String; n: CARDINAL) : BOOLEAN ;
 VAR
+   i  : INTEGER ;
    ppc: PtrToPtrToChar ;
 BEGIN
-   IF i < ArgC
+   i := VAL (INTEGER, n) ;
+   IF i < GetArgC ()
    THEN
       (* ppc := ADDRESS (VAL (PtrToPtrToChar, ArgV) + (i * CARDINAL (TSIZE(PtrToChar)))) ; *)
-      ppc := ADDRESS (PtrToChar (ArgV) + (i * TSIZE (PtrToChar))) ;
+      ppc := ADDRESS (PtrToChar (GetArgV ()) + (n * TSIZE (PtrToChar))) ;
       s   := InitStringCharStar (ppc^) ;
 
       RETURN TRUE
@@ -82,7 +84,7 @@ END GetArg ;
 
 PROCEDURE Narg () : CARDINAL ;
 BEGIN
-   RETURN( ArgC )
+   RETURN GetArgC ()
 END Narg ;
 
 
diff --git a/gcc/m2/gm2-libs/UnixArgs.def b/gcc/m2/gm2-libs/UnixArgs.def
index e1cd3f6cccd..23a21b8ce00 100644
--- a/gcc/m2/gm2-libs/UnixArgs.def
+++ b/gcc/m2/gm2-libs/UnixArgs.def
@@ -1,4 +1,4 @@
-(* UnixArgs.def Implements access to the C arguments argc and argv.
+(* UnixArgs.def Implements access to the arguments argc, argv, envp.
 
 Copyright (C) 2001-2021 Free Software Foundation, Inc.
 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
@@ -28,12 +28,11 @@ DEFINITION MODULE UnixArgs ;
 
 FROM SYSTEM IMPORT ADDRESS ;
 
-EXPORT QUALIFIED ArgC, ArgV ;
+EXPORT QUALIFIED GetArgC, GetArgV, GetEnvV ;
 
-
-VAR
-   ArgC: CARDINAL ;
-   ArgV: ADDRESS ;
+PROCEDURE GetArgC () : INTEGER ;
+PROCEDURE GetArgV () : ADDRESS ;
+PROCEDURE GetEnvV () : ADDRESS ;
 
 
 END UnixArgs.
diff --git a/gcc/m2/init/mcinit b/gcc/m2/init/mcinit
index 88120fdc45c..24730397144 100644
--- a/gcc/m2/init/mcinit
+++ b/gcc/m2/init/mcinit
@@ -20,6 +20,7 @@
 #
 Storage
 SYSTEM
+# M2Dependent
 M2RTS
 RTExceptions
 # SYSTEM    9 /opt/gm2/lib/gcc/x86_64-linux-gnu/4.7.4/m2/pim/SYSTEM.mod
diff --git a/gcc/m2/mc-boot-ch/GM2LINK.c b/gcc/m2/mc-boot-ch/GM2LINK.c
index 2d293fd5a7d..302f219ed5f 100644
--- a/gcc/m2/mc-boot-ch/GM2LINK.c
+++ b/gcc/m2/mc-boot-ch/GM2LINK.c
@@ -21,4 +21,7 @@ along with GNU Modula-2; see the file COPYING3.  If not see
 
 /* mc currently is built using a static scaffold.  */
 
+#include <cstddef>
+
 int M2LINK_StaticInitialization = 1;
+char *M2LINK_ForcedModuleInitOrder = NULL;
diff --git a/gcc/m2/mc-boot-ch/GUnixArgs.c b/gcc/m2/mc-boot-ch/GUnixArgs.c
deleted file mode 100644
index 1f1304c8841..00000000000
--- a/gcc/m2/mc-boot-ch/GUnixArgs.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* GUnixArgs.c handwritten module for mc.
-
-Copyright (C) 2016-2022 Free Software Foundation, Inc.
-Contributed by Gaius Mulley <gaius@glam.ac.uk>.
-
-This file is part of GNU Modula-2.
-
-GNU Modula-2 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 3, or (at your option)
-any later version.
-
-GNU Modula-2 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 GNU Modula-2; see the file COPYING3.  If not see
-<http://www.gnu.org/licenses/>.  */
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-int UnixArgs_ArgC;
-
-char **UnixArgs_ArgV;
-
-void
-_M2_UnixArgs_init (int argc, char *argv[])
-{
-  UnixArgs_ArgC = argc;
-  UnixArgs_ArgV = argv;
-}
-
-void
-_M2_UnixArgs_finish (int argc, char *argv[])
-{
-}
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/gcc/m2/mc-boot/GArgs.c b/gcc/m2/mc-boot/GArgs.c
index d517fac53a2..919182ca511 100644
--- a/gcc/m2/mc-boot/GArgs.c
+++ b/gcc/m2/mc-boot/GArgs.c
@@ -56,7 +56,7 @@ static _T1 Source;
             The success of the operation is returned.
 */
 
-extern "C" unsigned int Args_GetArg (char *a, unsigned int _a_high, unsigned int i);
+extern "C" unsigned int Args_GetArg (char *a, unsigned int _a_high, unsigned int n);
 
 /*
    Narg - returns the number of arguments available from
@@ -71,16 +71,18 @@ extern "C" unsigned int Args_Narg (void);
             The success of the operation is returned.
 */
 
-extern "C" unsigned int Args_GetArg (char *a, unsigned int _a_high, unsigned int i)
+extern "C" unsigned int Args_GetArg (char *a, unsigned int _a_high, unsigned int n)
 {
+  int i;
   unsigned int High;
   unsigned int j;
 
+  i = (int ) (n);
   j = 0;
   High = _a_high;
-  if (i < UnixArgs_ArgC)
+  if (i < (UnixArgs_GetArgC ()))
     {
-      Source = static_cast<_T1> (UnixArgs_ArgV);
+      Source = static_cast<_T1> (UnixArgs_GetArgV ());
       while (((*(*Source).array[i]).array[j] != ASCII_nul) && (j < High))
         {
           a[j] = (*(*Source).array[i]).array[j];
@@ -91,7 +93,7 @@ extern "C" unsigned int Args_GetArg (char *a, unsigned int _a_high, unsigned int
     {
       a[j] = ASCII_nul;
     }
-  return i < UnixArgs_ArgC;
+  return i < (UnixArgs_GetArgC ());
   /* static analysis guarentees a RETURN statement will be used before here.  */
   __builtin_unreachable ();
 }
@@ -104,7 +106,7 @@ extern "C" unsigned int Args_GetArg (char *a, unsigned int _a_high, unsigned int
 
 extern "C" unsigned int Args_Narg (void)
 {
-  return UnixArgs_ArgC;
+  return UnixArgs_GetArgC ();
   /* static analysis guarentees a RETURN statement will be used before here.  */
   __builtin_unreachable ();
 }
diff --git a/gcc/m2/mc-boot/GArgs.h b/gcc/m2/mc-boot/GArgs.h
index 1a15de29dc0..166a49eb91e 100644
--- a/gcc/m2/mc-boot/GArgs.h
+++ b/gcc/m2/mc-boot/GArgs.h
@@ -53,7 +53,7 @@ extern "C" {
             The success of the operation is returned.
 */
 
-EXTERN unsigned int Args_GetArg (char *a, unsigned int _a_high, unsigned int i);
+EXTERN unsigned int Args_GetArg (char *a, unsigned int _a_high, unsigned int n);
 
 /*
    Narg - returns the number of arguments available from
diff --git a/gcc/m2/mc-boot/GM2RTS.c b/gcc/m2/mc-boot/GM2RTS.c
index 4c4dc74bc22..95662017066 100644
--- a/gcc/m2/mc-boot/GM2RTS.c
+++ b/gcc/m2/mc-boot/GM2RTS.c
@@ -50,7 +50,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define _M2RTS_C
 
 #   include "Glibc.h"
-#   include "GM2LINK.h"
 #   include "GNumberIO.h"
 #   include "GStrLib.h"
 #   include "GSYSTEM.h"
@@ -58,6 +57,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #   include "GStorage.h"
 #   include "GRTExceptions.h"
 #   include "GM2EXCEPTION.h"
+#   include "GM2Dependent.h"
 
 typedef struct M2RTS_ArgCVEnvP_p M2RTS_ArgCVEnvP;
 
@@ -65,19 +65,9 @@ typedef struct ProcedureList_r ProcedureList;
 
 typedef char *PtrToChar;
 
-typedef struct DependencyList_r DependencyList;
+typedef struct _T1_r _T1;
 
-typedef struct _T2_r _T2;
-
-typedef _T2 *ProcedureChain;
-
-typedef struct _T3_r _T3;
-
-typedef _T3 *ModuleChain;
-
-typedef struct _T4_a _T4;
-
-typedef enum {unregistered, unordered, started, ordered} DependencyState;
+typedef _T1 *ProcedureChain;
 
 typedef void (*M2RTS_ArgCVEnvP_t) (int, void *, void *);
 struct M2RTS_ArgCVEnvP_p { M2RTS_ArgCVEnvP_t proc; };
@@ -87,40 +77,18 @@ struct ProcedureList_r {
                          ProcedureChain tail;
                        };
 
-struct DependencyList_r {
-                          PROC proc;
-                          unsigned int forced;
-                          unsigned int forc;
-                          DependencyState state;
-                        };
-
-struct _T2_r {
+struct _T1_r {
                PROC p;
                ProcedureChain prev;
                ProcedureChain next;
              };
 
-struct _T4_a { ModuleChain array[ordered-unregistered+1]; };
-struct _T3_r {
-               void *name;
-               M2RTS_ArgCVEnvP init;
-               M2RTS_ArgCVEnvP fini;
-               DependencyList dependency;
-               ModuleChain prev;
-               ModuleChain next;
-             };
-
 static ProcedureList InitialProc;
 static ProcedureList TerminateProc;
 static int ExitValue;
-static _T4 Modules;
 static unsigned int isHalting;
 static unsigned int CallExit;
-static unsigned int ModuleTrace;
-static unsigned int DependencyTrace;
-static unsigned int PreTrace;
-static unsigned int PostTrace;
-static unsigned int ForceTrace;
+static unsigned int Initialized;
 
 /*
    ConstructModules - resolve dependencies and then call each
@@ -146,19 +114,11 @@ extern "C" void M2RTS_RegisterModule (void * name, M2RTS_ArgCVEnvP init, M2RTS_A
 
 /*
    RequestDependant - used to specify that modulename is dependant upon
-                      module dependantmodule.  It only takes effect
-                      if we are not using StaticInitialization.
+                      module dependantmodule.
 */
 
 extern "C" void M2RTS_RequestDependant (void * modulename, void * dependantmodule);
 
-/*
-   ExecuteTerminationProcedures - calls each installed termination procedure
-                                  in reverse order.
-*/
-
-extern "C" void M2RTS_ExecuteTerminationProcedures (void);
-
 /*
    InstallTerminationProcedure - installs a procedure, p, which will
                                  be called when the procedure
@@ -185,7 +145,14 @@ extern "C" void M2RTS_ExecuteInitialProcedures (void);
 extern "C" unsigned int M2RTS_InstallInitialProcedure (PROC p);
 
 /*
-   Terminate - provides compatibility for pim.  It call exit with
+   ExecuteTerminationProcedures - calls each installed termination procedure
+                                  in reverse order.
+*/
+
+extern "C" void M2RTS_ExecuteTerminationProcedures (void);
+
+/*
+   Terminate - provides compatibility for pim.  It calls exit with
                the exitcode provided in a prior call to ExitOnHalt
                (or zero if ExitOnHalt was never called).  It does
                not call ExecuteTerminationProcedures.
@@ -257,117 +224,6 @@ extern "C" void M2RTS_RealValueException (void * filename, unsigned int line, un
 extern "C" void M2RTS_ParameterException (void * filename, unsigned int line, unsigned int column, void * scope, void * message);
 extern "C" void M2RTS_NoException (void * filename, unsigned int line, unsigned int column, void * scope, void * message);
 
-/*
-   CreateModule - creates a new module entry and returns the
-                  ModuleChain.
-*/
-
-static ModuleChain CreateModule (void * name, M2RTS_ArgCVEnvP init, M2RTS_ArgCVEnvP fini, PROC dependencies);
-
-/*
-   AppendModule - append chain to head.
-*/
-
-static void AppendModule (ModuleChain *head, ModuleChain chain);
-
-/*
-   RemoveModule - remove chain from double linked list head.
-*/
-
-static void RemoveModule (ModuleChain *head, ModuleChain chain);
-
-/*
-   onChain - returns TRUE if mptr is on the Modules[state] list.
-*/
-
-static unsigned int onChain (DependencyState state, ModuleChain mptr);
-
-/*
-   LookupModule - lookup and return the ModuleChain pointer containing
-                  module name from a particular list.
-*/
-
-static ModuleChain LookupModule (DependencyState state, void * name);
-
-/*
-   toCString - replace any character sequence
- into a newline.
-*/
-
-static void toCString (char *str, unsigned int _str_high);
-
-/*
-   strcmp - return 1 if both strings are equal.
-            We cannot use Builtins.def during bootstrap.
-*/
-
-static int strcmp (PtrToChar a, PtrToChar b);
-
-/*
-   strncmp - return 1 if both strings are equal.
-             We cannot use Builtins.def during bootstrap.
-*/
-
-static int strncmp (PtrToChar a, PtrToChar b, unsigned int n);
-
-/*
-   traceprintf - wrap printf with a boolean flag.
-*/
-
-static void traceprintf (unsigned int flag, const char *str_, unsigned int _str_high);
-
-/*
-   traceprintf2 - wrap printf with a boolean flag.
-*/
-
-static void traceprintf2 (unsigned int flag, const char *str_, unsigned int _str_high, void * arg);
-
-/*
-   moveTo - moves mptr to the new list determined by newstate.
-            It updates the mptr state appropriately.
-*/
-
-static void moveTo (DependencyState newstate, ModuleChain mptr);
-
-/*
-   ResolveDependant -
-*/
-
-static void ResolveDependant (ModuleChain mptr, void * currentmodule);
-
-/*
-   PerformRequestDependant - the current modulename has a dependancy upon
-                             dependantmodule.  If dependantmodule is NIL then
-                             modulename has no further dependants and it can be
-                             resolved.
-*/
-
-static void PerformRequestDependant (void * modulename, void * dependantmodule);
-
-/*
-   ResolveDependencies -
-*/
-
-static void ResolveDependencies (void * currentmodule);
-
-/*
-   DisplayModuleInfo - displays all module in the state.
-*/
-
-static void DisplayModuleInfo (DependencyState state, const char *name_, unsigned int _name_high);
-
-/*
-   DumpModuleData -
-*/
-
-static void DumpModuleData (unsigned int flag);
-
-/*
-   ForceDependencies -
-*/
-
-static void ForceDependencies (void);
-
 /*
    ExecuteReverse - execute the procedure associated with procptr
                     and then proceed to try and execute all previous
@@ -396,464 +252,19 @@ static void ErrorString (const char *a_, unsigned int _a_high);
 static void InitProcList (ProcedureList *p);
 
 /*
-   equal - return TRUE if C string cstr is equal to str.
-*/
-
-static unsigned int equal (void * cstr, const char *str_, unsigned int _str_high);
-
-/*
-   SetupDebugFlags - By default assigns ModuleTrace, DependencyTrace,
-                     DumpPostInit to FALSE.  It checks the environment
-                     GCC_M2LINK_RTFLAG which can contain
-                     "all,module,pre,post,dep,force".  all turns them all on.
-                     The flag meanings are as follows and flags the are in
-                     execution order.
-
-                     module   generate trace info as the modules are registered.
-                     pre      generate a list of all modules seen prior to having
-                              their dependancies resolved.
-                     dep      display a trace as the modules are resolved.
-                     post     generate a list of all modules seen after having
-                              their dependancies resolved.
-                     force    generate a list of all modules seen after having
-                              their dependancies resolved and forced.
-*/
-
-static void SetupDebugFlags (void);
-
-
-/*
-   CreateModule - creates a new module entry and returns the
-                  ModuleChain.
-*/
-
-static ModuleChain CreateModule (void * name, M2RTS_ArgCVEnvP init, M2RTS_ArgCVEnvP fini, PROC dependencies)
-{
-  ModuleChain mptr;
-
-  Storage_ALLOCATE ((void **) &mptr, sizeof (_T3));
-  mptr->name = name;
-  mptr->init = init;
-  mptr->fini = fini;
-  mptr->dependency.proc = dependencies;
-  mptr->dependency.state = unregistered;
-  mptr->prev = NULL;
-  mptr->next = NULL;
-  return mptr;
-  /* static analysis guarentees a RETURN statement will be used before here.  */
-  __builtin_unreachable ();
-}
-
-
-/*
-   AppendModule - append chain to head.
-*/
-
-static void AppendModule (ModuleChain *head, ModuleChain chain)
-{
-  if ((*head) == NULL)
-    {
-      (*head) = chain;
-      chain->prev = chain;
-      chain->next = chain;
-    }
-  else
-    {
-      chain->next = (*head);  /* Add Item to the end of queue  */
-      chain->prev = (*head)->prev;  /* Add Item to the end of queue  */
-      (*head)->prev->next = chain;
-      (*head)->prev = chain;
-    }
-}
-
-
-/*
-   RemoveModule - remove chain from double linked list head.
-*/
-
-static void RemoveModule (ModuleChain *head, ModuleChain chain)
-{
-  if ((chain->next == (*head)) && (chain == (*head)))
-    {
-      (*head) = NULL;
-    }
-  else
-    {
-      if ((*head) == chain)
-        {
-          (*head) = (*head)->next;
-        }
-      chain->prev->next = chain->next;
-      chain->next->prev = chain->prev;
-    }
-}
-
-
-/*
-   onChain - returns TRUE if mptr is on the Modules[state] list.
-*/
-
-static unsigned int onChain (DependencyState state, ModuleChain mptr)
-{
-  ModuleChain ptr;
-
-  if (Modules.array[state-unregistered] != NULL)
-    {
-      ptr = Modules.array[state-unregistered];
-      do {
-        if (ptr == mptr)
-          {
-            return TRUE;
-          }
-        ptr = ptr->next;
-      } while (! (ptr == Modules.array[state-unregistered]));
-    }
-  return FALSE;
-  /* static analysis guarentees a RETURN statement will be used before here.  */
-  __builtin_unreachable ();
-}
-
-
-/*
-   LookupModule - lookup and return the ModuleChain pointer containing
-                  module name from a particular list.
-*/
-
-static ModuleChain LookupModule (DependencyState state, void * name)
-{
-  ModuleChain ptr;
-
-  if (Modules.array[state-unregistered] != NULL)
-    {
-      ptr = Modules.array[state-unregistered];
-      do {
-        if ((strcmp (reinterpret_cast<PtrToChar> (ptr->name), reinterpret_cast<PtrToChar> (name))) == 0)
-          {
-            return ptr;
-          }
-        ptr = ptr->next;
-      } while (! (ptr == Modules.array[state-unregistered]));
-    }
-  return NULL;
-  /* static analysis guarentees a RETURN statement will be used before here.  */
-  __builtin_unreachable ();
-}
-
-
-/*
-   toCString - replace any character sequence
- into a newline.
-*/
-
-static void toCString (char *str, unsigned int _str_high)
-{
-  unsigned int high;
-  unsigned int i;
-  unsigned int j;
-
-  i = 0;
-  high = _str_high;
-  while (i < high)
-    {
-      if ((str[i] == '\\') && (i < high))
-        {
-          if (str[i+1] == 'n')
-            {
-              str[i] = ASCII_nl;
-              j = i+1;
-              while (j < high)
-                {
-                  str[j] = str[j+1];
-                  j += 1;
-                }
-            }
-        }
-      i += 1;
-    }
-}
-
-
-/*
-   strcmp - return 1 if both strings are equal.
-            We cannot use Builtins.def during bootstrap.
-*/
-
-static int strcmp (PtrToChar a, PtrToChar b)
-{
-  if ((a != NULL) && (b != NULL))
-    {
-      /* avoid gcc warning by using compound statement even if not strictly necessary.  */
-      if (a == b)
-        {
-          return 1;
-        }
-      else
-        {
-          while ((*a) == (*b))
-            {
-              if ((*a) == ASCII_nul)
-                {
-                  return 1;
-                }
-              a += 1;
-              b += 1;
-            }
-        }
-    }
-  return 0;
-  /* static analysis guarentees a RETURN statement will be used before here.  */
-  __builtin_unreachable ();
-}
-
-
-/*
-   strncmp - return 1 if both strings are equal.
-             We cannot use Builtins.def during bootstrap.
-*/
-
-static int strncmp (PtrToChar a, PtrToChar b, unsigned int n)
-{
-  if (((a != NULL) && (b != NULL)) && (n > 0))
-    {
-      /* avoid gcc warning by using compound statement even if not strictly necessary.  */
-      if (a == b)
-        {
-          return 1;
-        }
-      else
-        {
-          while (((*a) == (*b)) && (n > 0))
-            {
-              if ((*a) == ASCII_nul)
-                {
-                  return 1;
-                }
-              a += 1;
-              b += 1;
-              n -= 1;
-            }
-        }
-    }
-  return 0;
-  /* static analysis guarentees a RETURN statement will be used before here.  */
-  __builtin_unreachable ();
-}
-
-
-/*
-   traceprintf - wrap printf with a boolean flag.
-*/
-
-static void traceprintf (unsigned int flag, const char *str_, unsigned int _str_high)
-{
-  char str[_str_high+1];
-
-  /* make a local copy of each unbounded array.  */
-  memcpy (str, str_, _str_high+1);
-
-  if (flag)
-    {
-      toCString ((char *) str, _str_high);
-      libc_printf ((const char *) str, _str_high);
-    }
-}
-
-
-/*
-   traceprintf2 - wrap printf with a boolean flag.
-*/
-
-static void traceprintf2 (unsigned int flag, const char *str_, unsigned int _str_high, void * arg)
-{
-  char str[_str_high+1];
-
-  /* make a local copy of each unbounded array.  */
-  memcpy (str, str_, _str_high+1);
-
-  if (flag)
-    {
-      toCString ((char *) str, _str_high);
-      libc_printf ((const char *) str, _str_high, arg);
-    }
-}
-
-
-/*
-   moveTo - moves mptr to the new list determined by newstate.
-            It updates the mptr state appropriately.
+   Init - initialize the initial, terminate procedure lists and booleans.
 */
 
-static void moveTo (DependencyState newstate, ModuleChain mptr)
-{
-  if (onChain (mptr->dependency.state, mptr))
-    {
-      RemoveModule (&Modules.array[mptr->dependency.state-unregistered], mptr);
-    }
-  mptr->dependency.state = newstate;
-  AppendModule (&Modules.array[mptr->dependency.state-unregistered], mptr);
-}
-
+static void Init (void);
 
 /*
-   ResolveDependant -
+   CheckInitialized - checks to see if this module has been initialized
+                      and if it has not it calls Init.  We need this
+                      approach as this module is called by module ctors
+                      before we reach main.
 */
 
-static void ResolveDependant (ModuleChain mptr, void * currentmodule)
-{
-  if (mptr == NULL)
-    {
-      traceprintf (DependencyTrace, (const char *) "   module has not been registered via a global constructor\\n", 60);
-    }
-  else
-    {
-      if (onChain (started, mptr))
-        {
-          traceprintf (DependencyTrace, (const char *) "   processing...\\n", 18);
-        }
-      else
-        {
-          moveTo (started, mptr);
-          traceprintf2 (DependencyTrace, (const char *) "   starting: %s\\n", 17, currentmodule);
-          (*mptr->dependency.proc.proc) ();  /* Invoke and process the dependency graph.  */
-          traceprintf2 (DependencyTrace, (const char *) "   finished: %s\\n", 17, currentmodule);  /* Invoke and process the dependency graph.  */
-        }
-    }
-}
-
-
-/*
-   PerformRequestDependant - the current modulename has a dependancy upon
-                             dependantmodule.  If dependantmodule is NIL then
-                             modulename has no further dependants and it can be
-                             resolved.
-*/
-
-static void PerformRequestDependant (void * modulename, void * dependantmodule)
-{
-  ModuleChain mptr;
-
-  if (dependantmodule == NULL)
-    {
-      mptr = LookupModule (unordered, modulename);
-      if (mptr == NULL)
-        {
-          traceprintf2 (DependencyTrace, (const char *) "internal error module %s is not in the list of unordered modules\\n", 66, modulename);
-        }
-      else
-        {
-          traceprintf2 (DependencyTrace, (const char *) "  module %s dependants all complete\\n", 37, modulename);
-          moveTo (ordered, mptr);
-        }
-    }
-  else
-    {
-      mptr = LookupModule (ordered, dependantmodule);
-      if (mptr == NULL)
-        {
-          traceprintf2 (DependencyTrace, (const char *) "   module %s ", 13, dependantmodule);
-          mptr = LookupModule (unordered, dependantmodule);
-          if (mptr == NULL)
-            {
-              mptr = LookupModule (started, dependantmodule);
-              if (mptr == NULL)
-                {
-                  traceprintf2 (DependencyTrace, (const char *) "   unknown dependancies in module %s ", 37, modulename);
-                }
-              else
-                {
-                  traceprintf2 (DependencyTrace, (const char *) "   dependant %s started\\n", 25, dependantmodule);
-                }
-            }
-          else
-            {
-              ResolveDependant (mptr, dependantmodule);
-            }
-        }
-      else
-        {
-          traceprintf2 (DependencyTrace, (const char *) "   module %s ", 13, modulename);
-          traceprintf2 (DependencyTrace, (const char *) " dependant upon %s completed\\n", 30, dependantmodule);
-        }
-    }
-}
-
-
-/*
-   ResolveDependencies -
-*/
-
-static void ResolveDependencies (void * currentmodule)
-{
-  ModuleChain mptr;
-
-  mptr = LookupModule (unordered, currentmodule);
-  while (mptr != NULL)
-    {
-      traceprintf2 (DependencyTrace, (const char *) "   attempting to resolve the dependants for %s\\n", 48, currentmodule);
-      ResolveDependant (mptr, currentmodule);
-      mptr = Modules.array[unordered-unregistered];
-    }
-}
-
-
-/*
-   DisplayModuleInfo - displays all module in the state.
-*/
-
-static void DisplayModuleInfo (DependencyState state, const char *name_, unsigned int _name_high)
-{
-  ModuleChain mptr;
-  char name[_name_high+1];
-
-  /* make a local copy of each unbounded array.  */
-  memcpy (name, name_, _name_high+1);
-
-  if (Modules.array[state-unregistered] != NULL)
-    {
-      libc_printf ((const char *) "%s modules\\n", 12, &name);
-      mptr = Modules.array[state-unregistered];
-      do {
-        libc_printf ((const char *) "  %s", 4, mptr->name);
-        if (mptr->dependency.forc)
-          {
-            libc_printf ((const char *) " for C", 6);
-          }
-        if (mptr->dependency.forced)
-          {
-            libc_printf ((const char *) " forced ordering", 16);
-          }
-        libc_printf ((const char *) "\\n", 2);
-        mptr = mptr->next;
-      } while (! (mptr == Modules.array[state-unregistered]));
-    }
-}
-
-
-/*
-   DumpModuleData -
-*/
-
-static void DumpModuleData (unsigned int flag)
-{
-  ModuleChain mptr;
-
-  if (flag)
-    {
-      DisplayModuleInfo (unregistered, (const char *) "unregistered", 12);
-      DisplayModuleInfo (unordered, (const char *) "unordered", 9);
-      DisplayModuleInfo (started, (const char *) "started", 7);
-      DisplayModuleInfo (ordered, (const char *) "ordered", 7);
-    }
-}
-
-
-/*
-   ForceDependencies -
-*/
-
-static void ForceDependencies (void)
-{
-}
+static void CheckInitialized (void);
 
 
 /*
@@ -881,7 +292,7 @@ static unsigned int AppendProc (ProcedureList *proclist, PROC proc)
 {
   ProcedureChain pdes;
 
-  Storage_ALLOCATE ((void **) &pdes, sizeof (_T2));
+  Storage_ALLOCATE ((void **) &pdes, sizeof (_T1));
   pdes->p = proc;
   pdes->prev = (*proclist).tail;
   pdes->next = NULL;
@@ -924,96 +335,32 @@ static void InitProcList (ProcedureList *p)
 
 
 /*
-   equal - return TRUE if C string cstr is equal to str.
+   Init - initialize the initial, terminate procedure lists and booleans.
 */
 
-static unsigned int equal (void * cstr, const char *str_, unsigned int _str_high)
+static void Init (void)
 {
-  char str[_str_high+1];
-
-  /* make a local copy of each unbounded array.  */
-  memcpy (str, str_, _str_high+1);
-
-  return (strncmp (reinterpret_cast<PtrToChar> (cstr), reinterpret_cast<PtrToChar> (&str), StrLib_StrLen ((const char *) str, _str_high))) == 0;
-  /* static analysis guarentees a RETURN statement will be used before here.  */
-  __builtin_unreachable ();
+  InitProcList (&InitialProc);
+  InitProcList (&TerminateProc);
+  ExitValue = 0;
+  isHalting = FALSE;
+  CallExit = FALSE;  /* default by calling abort  */
 }
 
 
 /*
-   SetupDebugFlags - By default assigns ModuleTrace, DependencyTrace,
-                     DumpPostInit to FALSE.  It checks the environment
-                     GCC_M2LINK_RTFLAG which can contain
-                     "all,module,pre,post,dep,force".  all turns them all on.
-                     The flag meanings are as follows and flags the are in
-                     execution order.
-
-                     module   generate trace info as the modules are registered.
-                     pre      generate a list of all modules seen prior to having
-                              their dependancies resolved.
-                     dep      display a trace as the modules are resolved.
-                     post     generate a list of all modules seen after having
-                              their dependancies resolved.
-                     force    generate a list of all modules seen after having
-                              their dependancies resolved and forced.
+   CheckInitialized - checks to see if this module has been initialized
+                      and if it has not it calls Init.  We need this
+                      approach as this module is called by module ctors
+                      before we reach main.
 */
 
-static void SetupDebugFlags (void)
+static void CheckInitialized (void)
 {
-  typedef char *_T1;
-
-  _T1 pc;
-
-  ModuleTrace = FALSE;
-  DependencyTrace = FALSE;
-  PostTrace = FALSE;
-  PreTrace = FALSE;
-  pc = static_cast<_T1> (libc_getenv (const_cast<void*> (reinterpret_cast<const void*>("GCC_M2LINK_RTFLAG"))));
-  while ((pc != NULL) && ((*pc) != ASCII_nul))
+  if (! Initialized)
     {
-      if (equal (reinterpret_cast<void *> (pc), (const char *) "all", 3))
-        {
-          ModuleTrace = TRUE;
-          DependencyTrace = TRUE;
-          PreTrace = TRUE;
-          PostTrace = TRUE;
-          pc += 3;
-        }
-      else if (equal (reinterpret_cast<void *> (pc), (const char *) "module", 6))
-        {
-          /* avoid dangling else.  */
-          ModuleTrace = TRUE;
-          pc += 6;
-        }
-      else if (equal (reinterpret_cast<void *> (pc), (const char *) "dep", 3))
-        {
-          /* avoid dangling else.  */
-          DependencyTrace = TRUE;
-          pc += 3;
-        }
-      else if (equal (reinterpret_cast<void *> (pc), (const char *) "pre", 3))
-        {
-          /* avoid dangling else.  */
-          PreTrace = TRUE;
-          pc += 3;
-        }
-      else if (equal (reinterpret_cast<void *> (pc), (const char *) "post", 4))
-        {
-          /* avoid dangling else.  */
-          PostTrace = TRUE;
-          pc += 4;
-        }
-      else if (equal (reinterpret_cast<void *> (pc), (const char *) "force", 5))
-        {
-          /* avoid dangling else.  */
-          ForceTrace = TRUE;
-          pc += 5;
-        }
-      else
-        {
-          /* avoid dangling else.  */
-          pc += 1;
-        }
+      Initialized = TRUE;
+      Init ();
     }
 }
 
@@ -1025,49 +372,7 @@ static void SetupDebugFlags (void)
 
 extern "C" void M2RTS_ConstructModules (void * applicationmodule, int argc, void * argv, void * envp)
 {
-  ModuleChain mptr;
-  M2RTS_ArgCVEnvP nulp;
-
-  SetupDebugFlags ();
-  traceprintf2 (ModuleTrace, (const char *) "application module: %s\\n", 24, applicationmodule);
-  DumpModuleData (PreTrace);
-  ResolveDependencies (applicationmodule);
-  DumpModuleData (PostTrace);
-  ForceDependencies ();
-  DumpModuleData (ForceTrace);
-  if (Modules.array[ordered-unregistered] == NULL)
-    {
-      traceprintf2 (ModuleTrace, (const char *) "  module: %s has not registered itself using a global constructor\\n", 67, applicationmodule);
-      traceprintf2 (ModuleTrace, (const char *) "  hint try compile and linking using: gm2 %s.mod\\n", 50, applicationmodule);
-      traceprintf2 (ModuleTrace, (const char *) "  or try using: gm2 -fscaffold-static %s.mod\\n", 46, applicationmodule);
-    }
-  else
-    {
-      mptr = Modules.array[ordered-unregistered];
-      do {
-        if (mptr->dependency.forc)
-          {
-            traceprintf2 (ModuleTrace, (const char *) "initializing module: %s for C\\n", 31, mptr->name);
-          }
-        else
-          {
-            traceprintf2 (ModuleTrace, (const char *) "initializing module: %s\\n", 25, mptr->name);
-          }
-        /*
-         nulp := NIL ;
-         IF mptr^.init = nulp
-         THEN
-            traceprintf (ModuleTrace, "   no initialization section, skipping...
-        ")
-         ELSE
-  */
-        (*mptr->init.proc) (argc, argv, envp);
-        /*
-         END ;
-  */
-        mptr = mptr->prev;
-      } while (! (mptr == Modules.array[ordered-unregistered]));
-    }
+  M2Dependent_ConstructModules (applicationmodule, argc, argv, envp);
 }
 
 
@@ -1078,6 +383,7 @@ extern "C" void M2RTS_ConstructModules (void * applicationmodule, int argc, void
 
 extern "C" void M2RTS_DeconstructModules (void * applicationmodule, int argc, void * argv, void * envp)
 {
+  M2Dependent_DeconstructModules (applicationmodule, argc, argv, envp);
 }
 
 
@@ -1089,37 +395,18 @@ extern "C" void M2RTS_DeconstructModules (void * applicationmodule, int argc, vo
 
 extern "C" void M2RTS_RegisterModule (void * name, M2RTS_ArgCVEnvP init, M2RTS_ArgCVEnvP fini, PROC dependencies)
 {
-  if (! M2LINK_StaticInitialization)
-    {
-      traceprintf2 (ModuleTrace, (const char *) "module: %s registering\\n", 24, name);
-      moveTo (unordered, CreateModule (name, init, fini, dependencies));
-    }
+  M2Dependent_RegisterModule (name, (M2Dependent_ArgCVEnvP) {(M2Dependent_ArgCVEnvP_t) init.proc}, (M2Dependent_ArgCVEnvP) {(M2Dependent_ArgCVEnvP_t) fini.proc}, dependencies);
 }
 
 
 /*
    RequestDependant - used to specify that modulename is dependant upon
-                      module dependantmodule.  It only takes effect
-                      if we are not using StaticInitialization.
+                      module dependantmodule.
 */
 
 extern "C" void M2RTS_RequestDependant (void * modulename, void * dependantmodule)
 {
-  if (! M2LINK_StaticInitialization)
-    {
-      PerformRequestDependant (modulename, dependantmodule);
-    }
-}
-
-
-/*
-   ExecuteTerminationProcedures - calls each installed termination procedure
-                                  in reverse order.
-*/
-
-extern "C" void M2RTS_ExecuteTerminationProcedures (void)
-{
-  ExecuteReverse (TerminateProc.tail);
+  M2Dependent_RequestDependant (modulename, dependantmodule);
 }
 
 
@@ -1165,7 +452,18 @@ extern "C" unsigned int M2RTS_InstallInitialProcedure (PROC p)
 
 
 /*
-   Terminate - provides compatibility for pim.  It call exit with
+   ExecuteTerminationProcedures - calls each installed termination procedure
+                                  in reverse order.
+*/
+
+extern "C" void M2RTS_ExecuteTerminationProcedures (void)
+{
+  ExecuteReverse (TerminateProc.tail);
+}
+
+
+/*
+   Terminate - provides compatibility for pim.  It calls exit with
                the exitcode provided in a prior call to ExitOnHalt
                (or zero if ExitOnHalt was never called).  It does
                not call ExecuteTerminationProcedures.
@@ -1255,10 +553,10 @@ extern "C" void M2RTS_ExitOnHalt (int e)
 
 extern "C" void M2RTS_ErrorMessage (const char *message_, unsigned int _message_high, const char *file_, unsigned int _file_high, unsigned int line, const char *function_, unsigned int _function_high)
 {
-  typedef struct _T5_a _T5;
+  typedef struct _T2_a _T2;
 
-  struct _T5_a { char array[10+1]; };
-  _T5 LineNo;
+  struct _T2_a { char array[10+1]; };
+  _T2 LineNo;
   char message[_message_high+1];
   char file[_file_high+1];
   char function[_function_high+1];
@@ -1438,11 +736,7 @@ extern "C" void M2RTS_NoException (void * filename, unsigned int line, unsigned
 
 extern "C" void _M2_M2RTS_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[])
 {
-  InitProcList (&InitialProc);
-  InitProcList (&TerminateProc);
-  ExitValue = 0;
-  isHalting = FALSE;
-  CallExit = FALSE;  /* default by calling abort  */
+  CheckInitialized ();
 }
 
 extern "C" void _M2_M2RTS_finish (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[])
diff --git a/gcc/m2/mc-boot/GM2RTS.h b/gcc/m2/mc-boot/GM2RTS.h
index b8c950ad198..fd0ffa4ccec 100644
--- a/gcc/m2/mc-boot/GM2RTS.h
+++ b/gcc/m2/mc-boot/GM2RTS.h
@@ -71,13 +71,6 @@ EXTERN void M2RTS_RegisterModule (void * name, M2RTS_ArgCVEnvP init, M2RTS_ArgCV
 
 EXTERN void M2RTS_RequestDependant (void * modulename, void * dependantmodule);
 
-/*
-   ExecuteTerminationProcedures - calls each installed termination
-                                  procedure in reverse order.
-*/
-
-EXTERN void M2RTS_ExecuteTerminationProcedures (void);
-
 /*
    InstallTerminationProcedure - installs a procedure, p, which will
                                  be called when the procedure
@@ -103,6 +96,13 @@ EXTERN void M2RTS_ExecuteInitialProcedures (void);
 
 EXTERN unsigned int M2RTS_InstallInitialProcedure (PROC p);
 
+/*
+   ExecuteTerminationProcedures - calls each installed termination procedure
+                                  in reverse order.
+*/
+
+EXTERN void M2RTS_ExecuteTerminationProcedures (void);
+
 /*
    Terminate - provides compatibility for pim.  It call exit with
                the exitcode provided in a prior call to ExitOnHalt
diff --git a/gcc/m2/mc-boot/GSArgs.c b/gcc/m2/mc-boot/GSArgs.c
index d5ed816d746..c2612d66d74 100644
--- a/gcc/m2/mc-boot/GSArgs.c
+++ b/gcc/m2/mc-boot/GSArgs.c
@@ -64,7 +64,7 @@ typedef PtrToChar *PtrToPtrToChar;
             new string, otherwise s is set to NIL.
 */
 
-extern "C" unsigned int SArgs_GetArg (DynamicStrings_String *s, unsigned int i);
+extern "C" unsigned int SArgs_GetArg (DynamicStrings_String *s, unsigned int n);
 
 /*
    Narg - returns the number of arguments available from
@@ -81,14 +81,16 @@ extern "C" unsigned int SArgs_Narg (void);
             new string, otherwise s is set to NIL.
 */
 
-extern "C" unsigned int SArgs_GetArg (DynamicStrings_String *s, unsigned int i)
+extern "C" unsigned int SArgs_GetArg (DynamicStrings_String *s, unsigned int n)
 {
+  int i;
   PtrToPtrToChar ppc;
 
-  if (i < UnixArgs_ArgC)
+  i = (int ) (n);
+  if (i < (UnixArgs_GetArgC ()))
     {
       /* ppc := ADDRESS (VAL (PtrToPtrToChar, ArgV) + (i * CARDINAL (TSIZE(PtrToChar)))) ;  */
-      ppc = static_cast<PtrToPtrToChar> ((void *) (((PtrToChar) (UnixArgs_ArgV))+(i*sizeof (PtrToChar))));
+      ppc = static_cast<PtrToPtrToChar> ((void *) (((PtrToChar) (UnixArgs_GetArgV ()))+(n*sizeof (PtrToChar))));
       (*s) = DynamicStrings_InitStringCharStar (reinterpret_cast<void *> ((*ppc)));
       return TRUE;
     }
@@ -109,7 +111,7 @@ extern "C" unsigned int SArgs_GetArg (DynamicStrings_String *s, unsigned int i)
 
 extern "C" unsigned int SArgs_Narg (void)
 {
-  return UnixArgs_ArgC;
+  return UnixArgs_GetArgC ();
   /* static analysis guarentees a RETURN statement will be used before here.  */
   __builtin_unreachable ();
 }
diff --git a/gcc/m2/mc-boot/GSArgs.h b/gcc/m2/mc-boot/GSArgs.h
index 84927190895..d0fcc3760d3 100644
--- a/gcc/m2/mc-boot/GSArgs.h
+++ b/gcc/m2/mc-boot/GSArgs.h
@@ -56,7 +56,7 @@ extern "C" {
             new string, otherwise s is set to NIL.
 */
 
-EXTERN unsigned int SArgs_GetArg (DynamicStrings_String *s, unsigned int i);
+EXTERN unsigned int SArgs_GetArg (DynamicStrings_String *s, unsigned int n);
 
 /*
    Narg - returns the number of arguments available from
diff --git a/gcc/m2/mc-boot/GUnixArgs.h b/gcc/m2/mc-boot/GUnixArgs.h
index 6c67ea91eba..4960ba0a232 100644
--- a/gcc/m2/mc-boot/GUnixArgs.h
+++ b/gcc/m2/mc-boot/GUnixArgs.h
@@ -1,5 +1,5 @@
 /* do not edit automatically generated by mc from UnixArgs.  */
-/* UnixArgs.def Implements access to the C arguments argc and argv.
+/* UnixArgs.def Implements access to the arguments argc, argv, envp.
 
 Copyright (C) 2001-2021 Free Software Foundation, Inc.
 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
@@ -48,8 +48,9 @@ extern "C" {
 #      define EXTERN extern
 #   endif
 
-EXTERN unsigned int UnixArgs_ArgC;
-EXTERN void * UnixArgs_ArgV;
+EXTERN int UnixArgs_GetArgC (void);
+EXTERN void * UnixArgs_GetArgV (void);
+EXTERN void * UnixArgs_GetEnvV (void);
 #   ifdef __cplusplus
 }
 #   endif
diff --git a/gcc/m2/mc-boot/Gdecl.c b/gcc/m2/mc-boot/Gdecl.c
index 9ce86b01cf8..0da940bca95 100644
--- a/gcc/m2/mc-boot/Gdecl.c
+++ b/gcc/m2/mc-boot/Gdecl.c
@@ -1026,10 +1026,10 @@ extern "C" void M2RTS_ConstructModules (void * applicationmodule, int argc, void
 extern "C" void M2RTS_DeconstructModules (void * applicationmodule, int argc, void * argv, void * envp);
 extern "C" void M2RTS_RegisterModule (void * name, M2RTS_ArgCVEnvP init, M2RTS_ArgCVEnvP fini, PROC dependencies);
 extern "C" void M2RTS_RequestDependant (void * modulename, void * dependantmodule);
-extern "C" void M2RTS_ExecuteTerminationProcedures (void);
 extern "C" unsigned int M2RTS_InstallTerminationProcedure (PROC p);
 extern "C" void M2RTS_ExecuteInitialProcedures (void);
 extern "C" unsigned int M2RTS_InstallInitialProcedure (PROC p);
+extern "C" void M2RTS_ExecuteTerminationProcedures (void);
 extern "C" void M2RTS_Terminate (void) __attribute__ ((noreturn));
 extern "C" void M2RTS_HALT (int exitcode) __attribute__ ((noreturn));
 extern "C" void M2RTS_Halt (const char *file_, unsigned int _file_high, unsigned int line, const char *function_, unsigned int _function_high, const char *description_, unsigned int _description_high) __attribute__ ((noreturn));
diff --git a/gcc/m2/mc/mc.flex b/gcc/m2/mc/mc.flex
index 26dc60ddd47..871dccc37b9 100644
--- a/gcc/m2/mc/mc.flex
+++ b/gcc/m2/mc/mc.flex
@@ -747,3 +747,6 @@ int yywrap (void)
 
 void _M2_mcflex_init (void) {}
 void _M2_mcflex_finish (void) {}
+
+/* This is a gross hack to satisfy linking.  */
+void _M2_mcflex_ctor (void) {}
diff --git a/libgm2/libm2pim/Makefile.am b/libgm2/libm2pim/Makefile.am
index 72cfe19e71a..7a7acda7239 100644
--- a/libgm2/libm2pim/Makefile.am
+++ b/libgm2/libm2pim/Makefile.am
@@ -157,10 +157,10 @@ M2DEFS = Args.def   ASCII.def \
          cgetopt.def
 
 libm2pim_la_SOURCES = $(M2MODS) \
-                      UnixArgs.c \
-                      Selective.c sckt.c \
-                      errno.cc dtoa.c \
-                      ldtoa.c termios.cc \
+                      UnixArgs.cc \
+                      Selective.cc sckt.cc \
+                      errno.cc dtoa.cc \
+                      ldtoa.cc termios.cc \
                       SysExceptions.cc target.c \
                       wrapc.c cgetopt.c
 
diff --git a/libgm2/libm2pim/Selective.c b/libgm2/libm2pim/Selective.cc
similarity index 85%
rename from libgm2/libm2pim/Selective.c
rename to libgm2/libm2pim/Selective.cc
index a08ab8e6ea4..e168e3181a5 100644
--- a/libgm2/libm2pim/Selective.c
+++ b/libgm2/libm2pim/Selective.cc
@@ -25,6 +25,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
+#include <m2rts.h>
 
 #if defined(HAVE_STDDEF_H)
 /* Obtain a definition for NULL.  */
@@ -81,14 +82,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 /* Select wrap a call to the C select.  */
 
 #if defined(HAVE_STRUCT_TIMEVAL)
-int
+extern "C" int
 Selective_Select (int nooffds, fd_set *readfds, fd_set *writefds,
                   fd_set *exceptfds, struct timeval *timeout)
 {
   return select (nooffds, readfds, writefds, exceptfds, timeout);
 }
 #else
-int
+extern "C" int
 Selective_Select (int nooffds, void *readfds, void *writefds, void *exceptfds,
                   void *timeout)
 {
@@ -99,7 +100,7 @@ Selective_Select (int nooffds, void *readfds, void *writefds, void *exceptfds,
 /* InitTime initializes a timeval structure and returns a pointer to it.  */
 
 #if defined(HAVE_STRUCT_TIMEVAL)
-struct timeval *
+extern "C" struct timeval *
 Selective_InitTime (unsigned int sec, unsigned int usec)
 {
   struct timeval *t = (struct timeval *)malloc (sizeof (struct timeval));
@@ -109,14 +110,14 @@ Selective_InitTime (unsigned int sec, unsigned int usec)
   return t;
 }
 
-void
+extern "C" void
 Selective_GetTime (struct timeval *t, unsigned int *sec, unsigned int *usec)
 {
   *sec = (unsigned int)t->tv_sec;
   *usec = (unsigned int)t->tv_usec;
 }
 
-void
+extern "C" void
 Selective_SetTime (struct timeval *t, unsigned int sec, unsigned int usec)
 {
   t->tv_sec = sec;
@@ -125,7 +126,7 @@ Selective_SetTime (struct timeval *t, unsigned int sec, unsigned int usec)
 
 /* KillTime frees the timeval structure and returns NULL.  */
 
-struct timeval *
+extern "C" struct timeval *
 Selective_KillTime (struct timeval *t)
 {
 #if defined(HAVE_STDLIB_H)
@@ -136,7 +137,7 @@ Selective_KillTime (struct timeval *t)
 
 /* InitSet returns a pointer to a FD_SET.  */
 
-FDSET_T *
+extern "C" FDSET_T *
 Selective_InitSet (void)
 {
 #if defined(HAVE_STDLIB_H)
@@ -150,7 +151,7 @@ Selective_InitSet (void)
 
 /* KillSet frees the FD_SET and returns NULL.  */
 
-FDSET_T *
+extern "C" FDSET_T *
 Selective_KillSet (FDSET_T *s)
 {
 #if defined(HAVE_STDLIB_H)
@@ -161,7 +162,7 @@ Selective_KillSet (FDSET_T *s)
 
 /* FdZero generate an empty set.  */
 
-void
+extern "C" void
 Selective_FdZero (FDSET_T *s)
 {
   FD_ZERO (s);
@@ -169,7 +170,7 @@ Selective_FdZero (FDSET_T *s)
 
 /* FS_Set include an element, fd, into set, s.  */
 
-void
+extern "C" void
 Selective_FdSet (int fd, FDSET_T *s)
 {
   FD_SET (fd, s);
@@ -177,7 +178,7 @@ Selective_FdSet (int fd, FDSET_T *s)
 
 /* FdClr exclude an element, fd, from the set, s.  */
 
-void
+extern "C" void
 Selective_FdClr (int fd, FDSET_T *s)
 {
   FD_CLR (fd, s);
@@ -185,7 +186,7 @@ Selective_FdClr (int fd, FDSET_T *s)
 
 /* FdIsSet return TRUE if, fd, is present in set, s.  */
 
-int
+extern "C" int
 Selective_FdIsSet (int fd, FDSET_T *s)
 {
   return FD_ISSET (fd, s);
@@ -195,69 +196,69 @@ Selective_FdIsSet (int fd, FDSET_T *s)
    current system time in seconds and microseconds.
    It returns zero (see man 3p gettimeofday).  */
 
-int
+extern "C" int
 Selective_GetTimeOfDay (struct timeval *t)
 {
   return gettimeofday (t, NULL);
 }
 #else
 
-void *
+extern "C" void *
 Selective_InitTime (unsigned int sec, unsigned int usec)
 {
   return NULL;
 }
 
-void *
+extern "C" void *
 Selective_KillTime (void *t)
 {
   return NULL;
 }
 
-void
+extern "C" void
 Selective_GetTime (void *t, unsigned int *sec, unsigned int *usec)
 {
 }
 
-void
+extern "C" void
 Selective_SetTime (void *t, unsigned int sec, unsigned int usec)
 {
 }
 
-FDSET_T *
+extern "C" FDSET_T *
 Selective_InitSet (void)
 {
   return NULL;
 }
 
-FDSET_T *
+extern "C" FDSET_T *
 Selective_KillSet (void)
 {
   return NULL;
 }
 
-void
+extern "C" void
 Selective_FdZero (void *s)
 {
 }
 
-void
+extern "C" void
 Selective_FdSet (int fd, void *s)
 {
 }
 
-void
+extern "C" void
 Selective_FdClr (int fd, void *s)
 {
 }
 
-int
+extern "C" int
 Selective_FdIsSet (int fd, void *s)
 {
   return 0;
 }
 
-int
+extern "C" int
 Selective_GetTimeOfDay (void *t)
 {
   return -1;
@@ -266,7 +267,7 @@ Selective_GetTimeOfDay (void *t)
 
 /* MaxFdsPlusOne returns max (a + 1, b + 1).  */
 
-int
+extern "C" int
 Selective_MaxFdsPlusOne (int a, int b)
 {
   if (a > b)
@@ -277,7 +278,7 @@ Selective_MaxFdsPlusOne (int a, int b)
 
 /* WriteCharRaw writes a single character to the file descriptor.  */
 
-void
+extern "C" void
 Selective_WriteCharRaw (int fd, char ch)
 {
   write (fd, &ch, 1);
@@ -285,7 +286,7 @@ Selective_WriteCharRaw (int fd, char ch)
 
 /* ReadCharRaw read and return a single char from file descriptor, fd.  */
 
-char
+extern "C" char
 Selective_ReadCharRaw (int fd)
 {
   char ch;
@@ -294,12 +295,25 @@ Selective_ReadCharRaw (int fd)
   return ch;
 }
 
-void
-_M2_Selective_init ()
+extern "C" void
+_M2_Selective_init (int argc, char *argv[], char *envp[])
 {
 }
 
-void
-_M2_Selective_finish ()
+extern "C" void
+_M2_Selective_finish (int argc, char *argv[], char *envp[])
 {
 }
+
+extern "C" void
+_M2_Selective_dep (void)
+{
+}
+
+struct _M2_Selective_ctor { _M2_Selective_ctor (); } _M2_Selective_ctor;
+
+_M2_Selective_ctor::_M2_Selective_ctor (void)
+{
+  M2RTS_RegisterModule ("Selective", _M2_Selective_init, _M2_Selective_finish,
+			_M2_Selective_dep);
+}
diff --git a/libgm2/libm2pim/UnixArgs.c b/libgm2/libm2pim/UnixArgs.cc
similarity index 51%
rename from libgm2/libm2pim/UnixArgs.c
rename to libgm2/libm2pim/UnixArgs.cc
index daede41100f..0d6c76e3bc5 100644
--- a/libgm2/libm2pim/UnixArgs.c
+++ b/libgm2/libm2pim/UnixArgs.cc
@@ -1,4 +1,4 @@
-/* UnixArgs.c record argc, argv as global variables.
+/* UnixArgs.cc record argc, argv as global variables.
 
 Copyright (C) 2009-2022 Free Software Foundation, Inc.
 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
@@ -24,17 +24,68 @@ a copy of the GCC Runtime Library Exception along with this program;
 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 <http://www.gnu.org/licenses/>.  */
 
-int UnixArgs_ArgC;
-char **UnixArgs_ArgV;
+#include <config.h>
+#include <m2rts.h>
 
-void
-_M2_UnixArgs_init (int argc, char *argv[])
+
+extern "C" int UnixArgs_GetArgC (void);
+extern "C" char **UnixArgs_GetArgV (void);
+extern "C" char **UnixArgs_GetEnvV (void);
+
+static int UnixArgs_ArgC;
+static char **UnixArgs_ArgV;
+static char **UnixArgs_EnvV;
+
+
+/* GetArgC returns argc.  */
+
+extern "C" int
+UnixArgs_GetArgC (void)
+{
+  return UnixArgs_ArgC;
+}
+
+
+/* GetArgV returns argv.  */
+
+extern "C" char **
+UnixArgs_GetArgV (void)
+{
+  return UnixArgs_ArgV;
+}
+
+
+/* GetEnvV returns envv.  */
+
+extern "C" char **
+UnixArgs_GetEnvV (void)
+{
+  return UnixArgs_EnvV;
+}
+
+
+extern "C" void
+_M2_UnixArgs_init (int argc, char *argv[], char *envp[])
 {
   UnixArgs_ArgC = argc;
   UnixArgs_ArgV = argv;
+  UnixArgs_EnvV = envp;
 }
 
-void
-_M2_UnixArgs_finish (int argc, char *argv[])
+extern "C" void
+_M2_UnixArgs_finish (int argc, char *argv[], char *envp[])
+{
+}
+
+extern "C" void
+_M2_UnixArgs_dep (void)
+{
+}
+
+struct _M2_UnixArgs_ctor { _M2_UnixArgs_ctor (); } _M2_UnixArgs_ctor;
+
+_M2_UnixArgs_ctor::_M2_UnixArgs_ctor (void)
 {
+  M2RTS_RegisterModule ("UnixArgs", _M2_UnixArgs_init, _M2_UnixArgs_finish,
+			_M2_UnixArgs_dep);
 }
diff --git a/libgm2/libm2pim/dtoa.c b/libgm2/libm2pim/dtoa.cc
similarity index 89%
rename from libgm2/libm2pim/dtoa.c
rename to libgm2/libm2pim/dtoa.cc
index 9038b5acafd..d0ca0b096e9 100644
--- a/libgm2/libm2pim/dtoa.c
+++ b/libgm2/libm2pim/dtoa.cc
@@ -1,4 +1,4 @@
-/* dtoa.c convert double to ascii and visa versa.
+/* dtoa.cc convert double to ascii and visa versa.
 
 Copyright (C) 2009-2022 Free Software Foundation, Inc.
 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
@@ -27,6 +27,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define GM2
 
 #include <config.h>
+#include <m2rts.h>
 
 #if defined(HAVE_STRINGS)
 #include <strings.h>
@@ -104,7 +105,7 @@ typedef enum Mode { maxsignicant, decimaldigits } Mode;
    decimaldigits: return a string produced by fcvt.  The string will
    contain ndigits past the decimal point (ndigits may be negative).  */
 
-double
+extern "C" double
 dtoa_strtod (const char *s, int *error)
 {
   char *endp;
@@ -128,7 +129,7 @@ dtoa_strtod (const char *s, int *error)
 /* dtoa_calcmaxsig calculates the position of the decimal point
    it also removes the decimal point and exponent from string, p.  */
 
-int
+extern "C" int
 dtoa_calcmaxsig (char *p, int ndigits)
 {
   char *e;
@@ -159,7 +160,7 @@ dtoa_calcmaxsig (char *p, int ndigits)
    It truncates the digits in p accordingly to ndigits.
    Ie ndigits is the number of digits after the '.'.  */
 
-int
+extern "C" int
 dtoa_calcdecimal (char *p, int str_size, int ndigits)
 {
   char *e;
@@ -193,7 +194,7 @@ dtoa_calcdecimal (char *p, int str_size, int ndigits)
   return x;
 }
 
-int
+extern "C" int
 dtoa_calcsign (char *p, int str_size)
 {
   if (p[0] == '-')
@@ -205,7 +206,7 @@ dtoa_calcsign (char *p, int str_size)
     return FALSE;
 }
 
-char *
+extern "C" char *
 dtoa_dtoa (double d, int mode, int ndigits, int *decpt, int *sign)
 {
   char format[50];
@@ -216,14 +217,14 @@ dtoa_dtoa (double d, int mode, int ndigits, int *decpt, int *sign)
 
     case maxsignicant:
       ndigits += 20; /* Enough for exponent.  */
-      p = malloc (ndigits);
+      p = (char *) malloc (ndigits);
       snprintf (format, 50, "%s%d%s", "%.", ndigits - 20, "E");
       snprintf (p, ndigits, format, d);
       *sign = dtoa_calcsign (p, ndigits);
       *decpt = dtoa_calcmaxsig (p, ndigits);
       return p;
     case decimaldigits:
-      p = malloc (MAX_FP_DIGITS + 20);
+      p = (char *) malloc (MAX_FP_DIGITS + 20);
       snprintf (format, 50, "%s%d%s", "%.", MAX_FP_DIGITS, "E");
       snprintf (p, MAX_FP_DIGITS + 20, format, d);
       *sign = dtoa_calcsign (p, MAX_FP_DIGITS + 20);
@@ -239,12 +240,26 @@ dtoa_dtoa (double d, int mode, int ndigits, int *decpt, int *sign)
 #if defined(GM2)
 /* GNU Modula-2 linking hooks.  */
 
-void
-_M2_dtoa_init (void)
+extern "C" void
+_M2_dtoa_init (int, char **, char **)
 {
 }
-void
-_M2_dtoa_finish (void)
+
+extern "C" void
+_M2_dtoa_finish (int, char **, char **)
+{
+}
+
+extern "C" void
+_M2_dtoa_dep (void)
+{
+}
+
+struct _M2_dtoa_ctor { _M2_dtoa_ctor (); } _M2_dtoa_ctor;
+
+_M2_dtoa_ctor::_M2_dtoa_ctor (void)
 {
+  M2RTS_RegisterModule ("dtoa", _M2_dtoa_init, _M2_dtoa_finish,
+			_M2_dtoa_dep);
 }
 #endif
diff --git a/libgm2/libm2pim/ldtoa.c b/libgm2/libm2pim/ldtoa.cc
similarity index 84%
rename from libgm2/libm2pim/ldtoa.c
rename to libgm2/libm2pim/ldtoa.cc
index 5e2a42bc515..311126c0146 100644
--- a/libgm2/libm2pim/ldtoa.c
+++ b/libgm2/libm2pim/ldtoa.cc
@@ -27,6 +27,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define GM2
 
 #include <config.h>
+#include <m2rts.h>
 
 #if defined(HAVE_STRINGS)
 #include <strings.h>
@@ -96,9 +97,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 
 typedef enum Mode { maxsignicant, decimaldigits } Mode;
 
-extern int dtoa_calcmaxsig (char *p, int ndigits);
-extern int dtoa_calcdecimal (char *p, int str_size, int ndigits);
-extern int dtoa_calcsign (char *p, int str_size);
+extern "C" int dtoa_calcmaxsig (char *p, int ndigits);
+extern "C" int dtoa_calcdecimal (char *p, int str_size, int ndigits);
+extern "C" int dtoa_calcsign (char *p, int str_size);
 
 /* maxsignicant return a string containing max(1,ndigits) significant
    digits.  The return string contains the string produced by snprintf.
@@ -106,7 +107,7 @@ extern int dtoa_calcsign (char *p, int str_size);
    decimaldigits: return a string produced by fcvt.  The string will
    contain ndigits past the decimal point (ndigits may be negative).  */
 
-long double
+extern "C" long double
 ldtoa_strtold (const char *s, int *error)
 {
   char *endp;
@@ -132,7 +133,7 @@ ldtoa_strtold (const char *s, int *error)
   return d;
 }
 
-char *
+extern "C" char *
 ldtoa_ldtoa (long double d, int mode, int ndigits, int *decpt, int *sign)
 {
   char format[50];
@@ -143,14 +144,14 @@ ldtoa_ldtoa (long double d, int mode, int ndigits, int *decpt, int *sign)
 
     case maxsignicant:
       ndigits += 20; /* Enough for exponent.  */
-      p = malloc (ndigits);
+      p = (char *) malloc (ndigits);
       snprintf (format, 50, "%s%d%s", "%.", ndigits - 20, "LE");
       snprintf (p, ndigits, format, d);
       *sign = dtoa_calcsign (p, ndigits);
       *decpt = dtoa_calcmaxsig (p, ndigits);
       return p;
     case decimaldigits:
-      p = malloc (MAX_FP_DIGITS + 20);
+      p = (char *) malloc (MAX_FP_DIGITS + 20);
       snprintf (format, 50, "%s%d%s", "%.", MAX_FP_DIGITS, "LE");
       snprintf (p, MAX_FP_DIGITS + 20, format, d);
       *sign = dtoa_calcsign (p, MAX_FP_DIGITS + 20);
@@ -164,12 +165,26 @@ ldtoa_ldtoa (long double d, int mode, int ndigits, int *decpt, int *sign)
 #if defined(GM2)
 /* GNU Modula-2 linking hooks.  */
 
-void
-_M2_ldtoa_init (void)
+extern "C" void
+_M2_ldtoa_init (int, char **, char **)
 {
 }
-void
-_M2_ldtoa_finish (void)
+
+extern "C" void
+_M2_ldtoa_finish (int, char **, char **)
+{
+}
+
+extern "C" void
+_M2_ldtoa_dep (void)
+{
+}
+
+struct _M2_ldtoa_ctor { _M2_ldtoa_ctor (); } _M2_ldtoa_ctor;
+
+_M2_ldtoa_ctor::_M2_ldtoa_ctor (void)
 {
+  M2RTS_RegisterModule ("ldtoa", _M2_ldtoa_init, _M2_ldtoa_finish,
+			_M2_ldtoa_dep);
 }
 #endif
diff --git a/libgm2/libm2pim/sckt.c b/libgm2/libm2pim/sckt.cc
similarity index 93%
rename from libgm2/libm2pim/sckt.c
rename to libgm2/libm2pim/sckt.cc
index f4a42ff8864..6c68525acb0 100644
--- a/libgm2/libm2pim/sckt.c
+++ b/libgm2/libm2pim/sckt.cc
@@ -25,6 +25,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
+#include <m2rts.h>
 
 #if defined(HAVE_SYS_TYPES_H)
 #include <sys/types.h>
@@ -123,7 +124,7 @@ localExit (int i)
    information about a socket declared to receive tcp connections.
    This method attempts to use the port specified by the parameter.  */
 
-tcpServerState *
+extern "C" tcpServerState *
 tcpServerEstablishPort (int portNo)
 {
   tcpServerState *s = (tcpServerState *)malloc (sizeof (tcpServerState));
@@ -178,7 +179,7 @@ tcpServerEstablishPort (int portNo)
 /* tcpServerEstablish returns a tcpServerState containing the relevant
    information about a socket declared to receive tcp connections.  */
 
-tcpServerState *
+extern "C" tcpServerState *
 tcpServerEstablish (void)
 {
   return tcpServerEstablishPort (PORTSTART);
@@ -187,10 +188,10 @@ tcpServerEstablish (void)
 /* tcpServerAccept returns a file descriptor once a client has connected and
    been accepted.  */
 
-int
+extern "C" int
 tcpServerAccept (tcpServerState *s)
 {
-  int i = sizeof (s->isa);
+  socklen_t i = sizeof (s->isa);
   int t;
 
 #if defined(DEBUGGING)
@@ -202,7 +203,7 @@ tcpServerAccept (tcpServerState *s)
 
 /* tcpServerPortNo returns the portNo from structure, s.  */
 
-int
+extern "C" int
 tcpServerPortNo (tcpServerState *s)
 {
   return s->portNo;
@@ -210,7 +211,7 @@ tcpServerPortNo (tcpServerState *s)
 
 /* tcpServerSocketFd returns the sockFd from structure, s.  */
 
-int
+extern "C" int
 tcpServerSocketFd (tcpServerState *s)
 {
   return s->sockFd;
@@ -218,7 +219,7 @@ tcpServerSocketFd (tcpServerState *s)
 
 /* getLocalIP returns the IP address of this machine.  */
 
-unsigned int
+extern "C" unsigned int
 getLocalIP (tcpServerState *s)
 {
   char hostname[1024];
@@ -260,7 +261,7 @@ getLocalIP (tcpServerState *s)
 
 /* tcpServerIP returns the IP address from structure s.  */
 
-int
+extern "C" int
 tcpServerIP (tcpServerState *s)
 {
   return *((int *)s->hp->h_addr_list[0]);
@@ -269,7 +270,7 @@ tcpServerIP (tcpServerState *s)
 /* tcpServerClientIP returns the IP address of the client who
    has connected to server s.  */
 
-unsigned int
+extern "C" unsigned int
 tcpServerClientIP (tcpServerState *s)
 {
   unsigned int ip;
@@ -283,7 +284,7 @@ tcpServerClientIP (tcpServerState *s)
 /* tcpServerClientPortNo returns the port number of the client who
    has connected to server s.  */
 
-unsigned int
+extern "C" unsigned int
 tcpServerClientPortNo (tcpServerState *s)
 {
   return s->isa.sin_port;
@@ -307,7 +308,7 @@ typedef struct
 /* tcpClientSocket returns a file descriptor (socket) which has
    connected to, serverName:portNo.  */
 
-tcpClientState *
+extern "C" tcpClientState *
 tcpClientSocket (char *serverName, int portNo)
 {
   tcpClientState *s = (tcpClientState *)malloc (sizeof (tcpClientState));
@@ -340,7 +341,7 @@ tcpClientSocket (char *serverName, int portNo)
 /* tcpClientSocketIP returns a file descriptor (socket) which has
    connected to, ip:portNo.  */
 
-tcpClientState *
+extern "C" tcpClientState *
 tcpClientSocketIP (unsigned int ip, int portNo)
 {
   tcpClientState *s = (tcpClientState *)malloc (sizeof (tcpClientState));
@@ -366,7 +367,7 @@ tcpClientSocketIP (unsigned int ip, int portNo)
 /* tcpClientConnect returns the file descriptor associated with s,
    once a connect has been performed.  */
 
-int
+extern "C" int
 tcpClientConnect (tcpClientState *s)
 {
   if (connect (s->sockFd, (struct sockaddr *)&s->sa, sizeof (s->sa)) < 0)
@@ -377,7 +378,7 @@ tcpClientConnect (tcpClientState *s)
 
 /* tcpClientPortNo returns the portNo from structure s.  */
 
-int
+extern "C" int
 tcpClientPortNo (tcpClientState *s)
 {
   return s->portNo;
@@ -385,7 +386,7 @@ tcpClientPortNo (tcpClientState *s)
 
 /* tcpClientSocketFd returns the sockFd from structure s.  */
 
-int
+extern "C" int
 tcpClientSocketFd (tcpClientState *s)
 {
   return s->sockFd;
@@ -393,7 +394,7 @@ tcpClientSocketFd (tcpClientState *s)
 
 /* tcpClientIP returns the sockFd from structure s.  */
 
-int
+extern "C" int
 tcpClientIP (tcpClientState *s)
 {
 #if defined(DEBUGGING)
@@ -405,12 +406,25 @@ tcpClientIP (tcpClientState *s)
 
 /* GNU Modula-2 link fodder.  */
 
-void
-_M2_sckt_init (void)
+extern "C" void
+_M2_sckt_init (int, char *[], char *[])
 {
 }
 
-void
-_M2_sckt_finish (void)
+extern "C" void
+_M2_sckt_finish (int, char *[], char *[])
+{
+}
+
+extern "C" void
+_M2_sckt_dep (void)
+{
+}
+
+struct _M2_sckt_ctor { _M2_sckt_ctor (); } _M2_sckt_ctor;
+
+_M2_sckt_ctor::_M2_sckt_ctor (void)
 {
+  M2RTS_RegisterModule ("sckt", _M2_sckt_init, _M2_sckt_finish,
+			_M2_sckt_dep);
 }


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-29  0:43 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-29  0:43 [gcc/devel/m2link] Support library C files changed to C++ with dynamic scaffold signature Gaius Mulley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).