public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/m2link] New files implementing the scaffold at compile/runtime.
@ 2022-06-20 23:31 Gaius Mulley
0 siblings, 0 replies; only message in thread
From: Gaius Mulley @ 2022-06-20 23:31 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:5ceb82c64ed01a53c34708d285643308305a06d7
commit 5ceb82c64ed01a53c34708d285643308305a06d7
Author: Gaius Mulley <gaius.mulley@southwales.ac.uk>
Date: Tue Jun 21 00:26:46 2022 +0100
New files implementing the scaffold at compile/runtime.
gcc/m2/ChangeLog:
* gm2-compiler/M2Scaffold.def (New file).
* gm2-compiler/M2Scaffold.mod (New file).
* gm2-libs-ch/M2LINK.c (New file).
* gm2-libs/M2Dependent.def (New file).
* gm2-libs/M2Dependent.mod (New file).
* gm2-libs/M2LINK.def (New file).
* m2-link-support.h (Removed file).
* mc-boot-ch/GM2LINK.c (New file).
* mc-boot/GM2LINK.h (New file).
Signed-off-by: Gaius Mulley <gaius.mulley@southwales.ac.uk>
Diff:
---
gcc/m2/gm2-compiler/M2Scaffold.def | 45 +++
gcc/m2/gm2-compiler/M2Scaffold.mod | 113 ++++++
gcc/m2/gm2-libs-ch/M2LINK.c | 44 +++
gcc/m2/gm2-libs/M2Dependent.def | 62 +++
gcc/m2/gm2-libs/M2Dependent.mod | 791 +++++++++++++++++++++++++++++++++++++
gcc/m2/gm2-libs/M2LINK.def | 41 ++
gcc/m2/m2-link-support.h | 197 ---------
gcc/m2/mc-boot-ch/GM2LINK.c | 24 ++
gcc/m2/mc-boot/GM2LINK.h | 59 +++
9 files changed, 1179 insertions(+), 197 deletions(-)
diff --git a/gcc/m2/gm2-compiler/M2Scaffold.def b/gcc/m2/gm2-compiler/M2Scaffold.def
new file mode 100644
index 00000000000..f16575f6eb3
--- /dev/null
+++ b/gcc/m2/gm2-compiler/M2Scaffold.def
@@ -0,0 +1,45 @@
+(* M2Scaffold.def declare and create scaffold entities.
+
+Copyright (C) 2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.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/>. *)
+
+DEFINITION MODULE M2Scaffold ;
+
+
+VAR
+ finiFunction,
+ initFunction,
+ mainFunction: CARDINAL ;
+
+
+(*
+ DeclareScaffold - declare scaffold related entities.
+*)
+
+PROCEDURE DeclareScaffold (tokno: CARDINAL) ;
+
+
+(*
+ DeclareArgEnvParams - declares (int argc, void *argv, void *envp)
+*)
+
+PROCEDURE DeclareArgEnvParams (tokno: CARDINAL; proc: CARDINAL) ;
+
+
+END M2Scaffold.
diff --git a/gcc/m2/gm2-compiler/M2Scaffold.mod b/gcc/m2/gm2-compiler/M2Scaffold.mod
new file mode 100644
index 00000000000..e27ccf26c36
--- /dev/null
+++ b/gcc/m2/gm2-compiler/M2Scaffold.mod
@@ -0,0 +1,113 @@
+(* M2Scaffold.mod declare and create scaffold entities.
+
+Copyright (C) 2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.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/>. *)
+
+IMPLEMENTATION MODULE M2Scaffold ;
+
+FROM SymbolTable IMPORT NulSym, MakeProcedure, PutFunction,
+ PutPublic, PutCtor, PutParam, IsProcedure,
+ StartScope,
+ EndScope ;
+
+FROM NameKey IMPORT MakeKey ;
+FROM M2Base IMPORT Integer ;
+FROM M2System IMPORT Address ;
+FROM M2LexBuf IMPORT GetTokenNo ;
+FROM Assertion IMPORT Assert ;
+
+
+(* The dynamic scaffold takes the form:
+
+static void _M2_init (int argc, char *argv[], char *envp[])
+{
+ M2RTS_ConstructModules (module_name, argc, argv, envp);
+}
+
+
+static void _M2_finish (int argc, char *argv[], char *envp[])
+{
+ M2RTS_Terminate ();
+ M2RTS_DeconstructModules (module_name, argc, argv, envp);
+}
+
+
+int
+main (int argc, char *argv[], char *envp[])
+{
+ init (argc, argv, envp);
+ finish ();
+ return (0);
+} *)
+
+
+(*
+ DeclareScaffoldFunctions - declare main, _M2_init,_M2_finish
+ and _M2_DependencyGraph to the modula-2
+ front end.
+*)
+
+PROCEDURE DeclareScaffoldFunctions (tokenno: CARDINAL) ;
+BEGIN
+ mainFunction := MakeProcedure (tokenno, MakeKey ("main")) ;
+ StartScope (mainFunction) ;
+ PutFunction (mainFunction, Integer) ;
+ DeclareArgEnvParams (tokenno, mainFunction) ;
+ PutPublic (mainFunction, TRUE) ;
+ EndScope ;
+
+ initFunction := MakeProcedure (tokenno, MakeKey ("_M2_init")) ;
+ DeclareArgEnvParams (tokenno, initFunction) ;
+
+ finiFunction := MakeProcedure (tokenno, MakeKey ("_M2_finish")) ;
+ DeclareArgEnvParams (tokenno, finiFunction)
+END DeclareScaffoldFunctions ;
+
+
+(*
+ DeclareArgEnvParams - declares (int argc, void *argv, void *envp)
+*)
+
+PROCEDURE DeclareArgEnvParams (tokno: CARDINAL; proc: CARDINAL) ;
+BEGIN
+ Assert (IsProcedure (proc)) ;
+ StartScope (proc) ;
+ Assert (PutParam (tokno, proc, 1, MakeKey ("argc"), Integer, FALSE)) ;
+ Assert (PutParam (tokno, proc, 2, MakeKey ("argv"), Address, FALSE)) ;
+ Assert (PutParam (tokno, proc, 3, MakeKey ("envp"), Address, FALSE)) ;
+ EndScope
+END DeclareArgEnvParams ;
+
+
+
+(*
+ DeclareScaffold - declare scaffold related entities.
+*)
+
+PROCEDURE DeclareScaffold (tokno: CARDINAL) ;
+BEGIN
+ DeclareScaffoldFunctions (tokno)
+END DeclareScaffold ;
+
+
+BEGIN
+ finiFunction := NulSym ;
+ initFunction := NulSym ;
+ mainFunction := NulSym
+END M2Scaffold.
diff --git a/gcc/m2/gm2-libs-ch/M2LINK.c b/gcc/m2/gm2-libs-ch/M2LINK.c
new file mode 100644
index 00000000000..70b4c3d889a
--- /dev/null
+++ b/gcc/m2/gm2-libs-ch/M2LINK.c
@@ -0,0 +1,44 @@
+/* M2LINK.c provide a bootstrap minimal definitions.
+
+Copyright (C) 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+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/>. */
+
+#include "config.h"
+#include "system.h"
+#include "ansidecl.h"
+#include "math.h"
+
+#include "gm2-libs-host.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* These definitions are only used during bootstrap to disable the dynamic
+ initialization features of M2RTS. */
+
+ char *M2LINK_ForcedModuleInitOrder = NULL;
+ int M2LINK_StaticInitialization = 1;
+
+}
diff --git a/gcc/m2/gm2-libs/M2Dependent.def b/gcc/m2/gm2-libs/M2Dependent.def
new file mode 100644
index 00000000000..a7c18159b12
--- /dev/null
+++ b/gcc/m2/gm2-libs/M2Dependent.def
@@ -0,0 +1,62 @@
+(* M2Dependent.def defines the run time module dependencies interface.
+
+Copyright (C) 2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+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/>. *)
+
+DEFINITION MODULE M2Dependent ;
+
+FROM SYSTEM IMPORT ADDRESS ;
+
+
+TYPE
+ ArgCVEnvP = PROCEDURE (INTEGER, ADDRESS, ADDRESS) ;
+
+
+PROCEDURE ConstructModules (applicationmodule: ADDRESS;
+ argc: INTEGER; argv, envp: ADDRESS) ;
+
+PROCEDURE DeconstructModules (applicationmodule: ADDRESS;
+ argc: INTEGER; argv, envp: ADDRESS) ;
+
+
+(*
+ RegisterModule - adds module name to the list of outstanding
+ modules which need to have their dependencies
+ explored to determine initialization order.
+*)
+
+PROCEDURE RegisterModule (name: ADDRESS;
+ init, fini: ArgCVEnvP;
+ dependencies: PROC) ;
+
+
+(*
+ RequestDependant - used to specify that modulename is dependant upon
+ module dependantmodule.
+*)
+
+PROCEDURE RequestDependant (modulename, dependantmodule: ADDRESS) ;
+
+
+END M2Dependent.
diff --git a/gcc/m2/gm2-libs/M2Dependent.mod b/gcc/m2/gm2-libs/M2Dependent.mod
new file mode 100644
index 00000000000..3780cdb33bd
--- /dev/null
+++ b/gcc/m2/gm2-libs/M2Dependent.mod
@@ -0,0 +1,791 @@
+(* M2Dependent.mod implements the run time module dependencies.
+
+Copyright (C) 2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+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/>. *)
+
+IMPLEMENTATION MODULE M2Dependent ;
+
+
+FROM libc IMPORT abort, exit, write, getenv, printf ;
+(* FROM Builtins IMPORT strncmp, strcmp ; not available during bootstrap. *)
+FROM M2LINK IMPORT ForcedModuleInitOrder, StaticInitialization, PtrToChar ;
+FROM ASCII IMPORT nul, nl ;
+FROM SYSTEM IMPORT ADR ;
+FROM Storage IMPORT ALLOCATE ;
+FROM StrLib IMPORT StrCopy, StrLen, StrEqual ;
+
+IMPORT M2RTS ;
+
+
+TYPE
+ DependencyState = (unregistered, unordered, started, ordered, user) ;
+
+ DependencyList = RECORD
+ proc : PROC ;
+ (* Has this module order been forced by the user? *)
+ forced,
+ (* Is the module a definition module for C? *)
+ forc : BOOLEAN ;
+ appl : BOOLEAN ; (* The application module? *)
+ state : DependencyState ;
+ END ;
+
+ ModuleChain = POINTER TO RECORD
+ name : ADDRESS ;
+ init,
+ fini : ArgCVEnvP ;
+ dependency: DependencyList ;
+ prev,
+ next : ModuleChain ;
+ END ;
+
+VAR
+ Modules : ARRAY DependencyState OF ModuleChain ;
+ Initialized,
+ ModuleTrace,
+ DependencyTrace,
+ PreTrace,
+ PostTrace,
+ ForceTrace : BOOLEAN ;
+
+
+(*
+ CreateModule - creates a new module entry and returns the
+ ModuleChain.
+*)
+
+PROCEDURE CreateModule (name: ADDRESS;
+ init, fini: ArgCVEnvP;
+ dependencies: PROC) : ModuleChain ;
+VAR
+ mptr: ModuleChain ;
+BEGIN
+ NEW (mptr) ;
+ mptr^.name := name ;
+ mptr^.init := init ;
+ mptr^.fini := fini ;
+ mptr^.dependency.proc := dependencies ;
+ mptr^.dependency.state := unregistered ;
+ mptr^.prev := NIL ;
+ mptr^.next := NIL ;
+ RETURN mptr
+END CreateModule ;
+
+
+(*
+ AppendModule - append chain to end of the list.
+*)
+
+PROCEDURE AppendModule (VAR head: ModuleChain; chain: ModuleChain) ;
+BEGIN
+ IF head = NIL
+ THEN
+ head := chain ;
+ chain^.prev := chain ;
+ chain^.next := chain
+ ELSE
+ chain^.next := head ; (* Add Item to the end of list. *)
+ chain^.prev := head^.prev ;
+ head^.prev^.next := chain ;
+ head^.prev := chain
+ END
+END AppendModule ;
+
+
+(*
+ RemoveModule - remove chain from double linked list head.
+*)
+
+PROCEDURE RemoveModule (VAR head: ModuleChain; chain: ModuleChain) ;
+BEGIN
+ IF (chain^.next=head) AND (chain=head)
+ THEN
+ head := NIL
+ ELSE
+ IF head=chain
+ THEN
+ head := head^.next
+ END ;
+ chain^.prev^.next := chain^.next ;
+ chain^.next^.prev := chain^.prev
+ END
+END RemoveModule ;
+
+
+(*
+ onChain - returns TRUE if mptr is on the Modules[state] list.
+*)
+
+PROCEDURE onChain (state: DependencyState; mptr: ModuleChain) : BOOLEAN ;
+VAR
+ ptr: ModuleChain ;
+BEGIN
+ IF Modules[state] # NIL
+ THEN
+ ptr := Modules[state] ;
+ REPEAT
+ IF ptr = mptr
+ THEN
+ RETURN TRUE
+ END ;
+ ptr := ptr^.next
+ UNTIL ptr=Modules[state]
+ END ;
+ RETURN FALSE
+END onChain ;
+
+
+(*
+ LookupModuleN - lookup module from the state list. The string is limited
+ to nchar.
+*)
+
+PROCEDURE LookupModuleN (state: DependencyState;
+ name: ADDRESS; nchar: CARDINAL) : ModuleChain ;
+VAR
+ ptr: ModuleChain ;
+BEGIN
+ IF Modules[state] # NIL
+ THEN
+ ptr := Modules[state] ;
+ REPEAT
+ IF strncmp (ptr^.name, name, nchar) = 0
+ THEN
+ RETURN ptr
+ END ;
+ ptr := ptr^.next
+ UNTIL ptr = Modules[state]
+ END ;
+ RETURN NIL
+END LookupModuleN ;
+
+
+(*
+ LookupModule - lookup and return the ModuleChain pointer containing
+ module name from a particular list.
+*)
+
+PROCEDURE LookupModule (state: DependencyState; name: ADDRESS) : ModuleChain ;
+BEGIN
+ RETURN LookupModuleN (state, name, strlen (name))
+END LookupModule ;
+
+
+(*
+ toCString - replace any character sequence \n into a newline.
+*)
+
+PROCEDURE toCString (VAR str: ARRAY OF CHAR) ;
+VAR
+ high, i, j: CARDINAL ;
+BEGIN
+ i := 0 ;
+ high := HIGH (str) ;
+ WHILE i < high DO
+ IF (str[i] = "\") AND (i < high)
+ THEN
+ IF str[i+1] = "n"
+ THEN
+ str[i] := nl ;
+ j := i+1 ;
+ WHILE j < high DO
+ str[j] := str[j+1] ;
+ INC (j)
+ END
+ END
+ END ;
+ INC (i)
+ END
+END toCString ;
+
+
+(*
+ strcmp - return 0 if both strings are equal.
+ We cannot use Builtins.def during bootstrap.
+*)
+
+PROCEDURE strcmp (a, b: PtrToChar) : INTEGER ;
+BEGIN
+ IF (a # NIL) AND (b # NIL)
+ THEN
+ IF a = b
+ THEN
+ RETURN 0
+ ELSE
+ WHILE a^ = b^ DO
+ IF a^ = nul
+ THEN
+ RETURN 0
+ END ;
+ INC (a) ;
+ INC (b)
+ END
+ END
+ END ;
+ RETURN 1
+END strcmp ;
+
+
+(*
+ strncmp - return 0 if both strings are equal.
+ We cannot use Builtins.def during bootstrap.
+*)
+
+PROCEDURE strncmp (a, b: PtrToChar; n: CARDINAL) : INTEGER ;
+BEGIN
+ IF (a # NIL) AND (b # NIL) AND (n > 0)
+ THEN
+ IF a = b
+ THEN
+ RETURN 0
+ ELSE
+ WHILE (a^ = b^) AND (n > 0) DO
+ IF (a^ = nul) OR (n = 1)
+ THEN
+ RETURN 0
+ END ;
+ INC (a) ;
+ INC (b) ;
+ DEC (n)
+ END
+ END
+ END ;
+ RETURN 1
+END strncmp ;
+
+
+(*
+ strlen - returns the length of string.
+*)
+
+PROCEDURE strlen (string: PtrToChar) : INTEGER ;
+VAR
+ count: INTEGER ;
+BEGIN
+ IF string = NIL
+ THEN
+ RETURN 0
+ ELSE
+ count := 0 ;
+ WHILE string^ # nul DO
+ INC (string) ;
+ INC (count)
+ END ;
+ RETURN count
+ END
+END strlen ;
+
+
+(*
+ traceprintf - wrap printf with a boolean flag.
+*)
+
+PROCEDURE traceprintf (flag: BOOLEAN; str: ARRAY OF CHAR) ;
+BEGIN
+ IF flag
+ THEN
+ toCString (str) ;
+ printf (str)
+ END
+END traceprintf ;
+
+
+(*
+ traceprintf2 - wrap printf with a boolean flag.
+*)
+
+PROCEDURE traceprintf2 (flag: BOOLEAN; str: ARRAY OF CHAR; arg: ADDRESS) ;
+BEGIN
+ IF flag
+ THEN
+ toCString (str) ;
+ printf (str, arg)
+ END
+END traceprintf2 ;
+
+
+(*
+ moveTo - moves mptr to the new list determined by newstate.
+ It updates the mptr state appropriately.
+*)
+
+PROCEDURE moveTo (newstate: DependencyState; mptr: ModuleChain) ;
+BEGIN
+ IF onChain (mptr^.dependency.state, mptr)
+ THEN
+ RemoveModule (Modules[mptr^.dependency.state], mptr)
+ END ;
+ mptr^.dependency.state := newstate ;
+ AppendModule (Modules[mptr^.dependency.state], mptr)
+END moveTo ;
+
+
+(*
+ ResolveDependant -
+*)
+
+PROCEDURE ResolveDependant (mptr: ModuleChain; currentmodule: ADDRESS) ;
+BEGIN
+ IF mptr = NIL
+ THEN
+ traceprintf (DependencyTrace, " module has not been registered via a global constructor\n");
+ ELSE
+ IF onChain (started, mptr)
+ THEN
+ traceprintf (DependencyTrace, " processing...\n");
+ ELSE
+ moveTo (started, mptr) ;
+ traceprintf2 (DependencyTrace, " starting: %s\n",
+ currentmodule);
+ mptr^.dependency.proc ; (* Invoke and process the dependency graph. *)
+ traceprintf2 (DependencyTrace, " finished: %s\n",
+ currentmodule);
+ moveTo (ordered, mptr)
+ END
+ END
+END ResolveDependant ;
+
+
+(*
+ RequestDependant - used to specify that modulename is dependant upon
+ module dependantmodule. It only takes effect
+ if we are not using StaticInitialization.
+*)
+
+PROCEDURE RequestDependant (modulename, dependantmodule: ADDRESS) ;
+BEGIN
+ CheckInitialized ;
+ IF NOT StaticInitialization
+ THEN
+ PerformRequestDependant (modulename, dependantmodule)
+ END
+END RequestDependant ;
+
+
+(*
+ PerformRequestDependant - the current modulename has a dependancy upon
+ dependantmodule. If dependantmodule is NIL then
+ modulename has no further dependants and it can be
+ resolved.
+*)
+
+PROCEDURE PerformRequestDependant (modulename, dependantmodule: ADDRESS) ;
+VAR
+ mptr: ModuleChain ;
+BEGIN
+ traceprintf2 (DependencyTrace, " module %s", modulename) ;
+ IF dependantmodule = NIL
+ THEN
+ traceprintf2 (DependencyTrace, " has finished its import graph\n", modulename) ;
+ mptr := LookupModule (unordered, modulename) ;
+ IF mptr # NIL
+ THEN
+ traceprintf2 (DependencyTrace, " module %s is now ordered\n", modulename) ;
+ moveTo (ordered, mptr)
+ END
+ ELSE
+ traceprintf2 (DependencyTrace, " imports from %s\n", dependantmodule) ;
+ mptr := LookupModule (ordered, dependantmodule) ;
+ IF mptr = NIL
+ THEN
+ traceprintf2 (DependencyTrace, " module %s is not ordered\n", dependantmodule) ;
+ mptr := LookupModule (unordered, dependantmodule) ;
+ IF mptr = NIL
+ THEN
+ traceprintf2 (DependencyTrace, " module %s is not unordered\n", dependantmodule) ;
+ mptr := LookupModule (started, dependantmodule) ;
+ IF mptr = NIL
+ THEN
+ traceprintf2 (DependencyTrace, " module %s has not started\n", dependantmodule) ;
+ traceprintf2 (DependencyTrace, " module %s attempting to import from",
+ modulename) ;
+ traceprintf2 (DependencyTrace, " %s which has not registered itself via a constructor\n",
+ dependantmodule)
+ ELSE
+ traceprintf2 (DependencyTrace, " module %s has registered itself and has started\n", dependantmodule)
+ END
+ ELSE
+ traceprintf2 (DependencyTrace, " module %s resolving\n", dependantmodule) ;
+ ResolveDependant (mptr, dependantmodule)
+ END
+ ELSE
+ traceprintf2 (DependencyTrace, " module %s ", modulename) ;
+ traceprintf2 (DependencyTrace, " dependant %s is ordered\n", dependantmodule)
+ END
+ END
+END PerformRequestDependant ;
+
+
+(*
+ ResolveDependencies - resolve dependencies for currentmodule.
+*)
+
+PROCEDURE ResolveDependencies (currentmodule: ADDRESS) ;
+VAR
+ mptr: ModuleChain ;
+BEGIN
+ mptr := LookupModule (unordered, currentmodule) ;
+ WHILE mptr # NIL DO
+ traceprintf2 (DependencyTrace, " attempting to resolve the dependants for %s\n",
+ currentmodule);
+ ResolveDependant (mptr, currentmodule) ;
+ mptr := Modules[unordered]
+ END
+END ResolveDependencies ;
+
+
+(*
+ DisplayModuleInfo - displays all module in the state.
+*)
+
+PROCEDURE DisplayModuleInfo (state: DependencyState; name: ARRAY OF CHAR) ;
+VAR
+ mptr: ModuleChain ;
+BEGIN
+ IF Modules[state] # NIL
+ THEN
+ printf ("%s modules\n", ADR (name)) ;
+ mptr := Modules[state] ;
+ REPEAT
+ printf (" %s", mptr^.name) ;
+ IF mptr^.dependency.appl
+ THEN
+ printf (" application")
+ END ;
+ IF mptr^.dependency.forc
+ THEN
+ printf (" for C")
+ END ;
+ IF mptr^.dependency.forced
+ THEN
+ printf (" forced ordering")
+ END ;
+ printf ("\n") ;
+ mptr := mptr^.next ;
+ UNTIL mptr = Modules[state]
+ END
+END DisplayModuleInfo ;
+
+
+(*
+ DumpModuleData -
+*)
+
+PROCEDURE DumpModuleData (flag: BOOLEAN) ;
+VAR
+ mptr: ModuleChain ;
+BEGIN
+ IF flag
+ THEN
+ DisplayModuleInfo (unregistered, "unregistered") ;
+ DisplayModuleInfo (unordered, "unordered") ;
+ DisplayModuleInfo (started, "started") ;
+ DisplayModuleInfo (ordered, "ordered") ;
+ END
+END DumpModuleData ;
+
+
+(*
+ combine - dest := src + dest. Places src at the front of list dest.
+ Pre condition: src, dest are lists.
+ Post condition : dest := src + dest
+ src := NIL.
+*)
+
+PROCEDURE combine (src, dest: DependencyState) ;
+VAR
+ last: ModuleChain ;
+BEGIN
+ WHILE Modules[src] # NIL DO
+ last := Modules[src]^.prev ;
+ moveTo (ordered, last) ;
+ Modules[dest] := last (* New item is at the head. *)
+ END
+END combine ;
+
+
+(*
+ ForceDependencies - if the user has specified a forced order then we override
+ the dynamic ordering with the preference.
+*)
+
+PROCEDURE ForceDependencies ;
+VAR
+ mptr,
+ userChain: ModuleChain ;
+ count : CARDINAL ;
+ pc, start: PtrToChar ;
+BEGIN
+ IF ForcedModuleInitOrder # NIL
+ THEN
+ userChain := NIL ;
+ pc := ForcedModuleInitOrder ;
+ start := pc ;
+ count := 0 ;
+ WHILE pc^ # nul DO
+ IF pc^ = ','
+ THEN
+ mptr := LookupModuleN (ordered, start, count) ;
+ IF mptr # NIL
+ THEN
+ moveTo (user, mptr)
+ END ;
+ INC (pc) ;
+ start := pc ;
+ count := 0
+ ELSE
+ INC (pc) ;
+ INC (count)
+ END
+ END ;
+ IF start # pc
+ THEN
+ mptr := LookupModuleN (ordered, start, count) ;
+ IF mptr # NIL
+ THEN
+ moveTo (user, mptr)
+ END
+ END ;
+ combine (user, ordered)
+ END
+END ForceDependencies ;
+
+
+(*
+ ConstructModules - resolve dependencies and then call each
+ module constructor in turn.
+*)
+
+PROCEDURE ConstructModules (applicationmodule: ADDRESS;
+ argc: INTEGER; argv, envp: ADDRESS) ;
+VAR
+ mptr: ModuleChain ;
+ nulp: ArgCVEnvP ;
+BEGIN
+ CheckInitialized ;
+ traceprintf2 (ModuleTrace, "application module: %s\n", applicationmodule);
+ mptr := LookupModule (unordered, applicationmodule) ;
+ IF mptr # NIL
+ THEN
+ mptr^.dependency.appl := TRUE
+ END ;
+ traceprintf (PreTrace, "Pre resolving dependents\n");
+ DumpModuleData (PreTrace) ;
+ ResolveDependencies (applicationmodule) ;
+ traceprintf (PreTrace, "Post resolving dependents\n");
+ DumpModuleData (PostTrace) ;
+ ForceDependencies ;
+ traceprintf (ForceTrace, "After user forcing ordering\n");
+ DumpModuleData (ForceTrace) ;
+ IF Modules[ordered] = NIL
+ THEN
+ traceprintf2 (ModuleTrace, " module: %s has not registered itself using a global constructor\n", applicationmodule);
+ traceprintf2 (ModuleTrace, " hint try compile and linking using: gm2 %s.mod\n", applicationmodule);
+ traceprintf2 (ModuleTrace, " or try using: gm2 -fscaffold-static %s.mod\n",
+ applicationmodule);
+ ELSE
+ mptr := Modules[ordered] ;
+ REPEAT
+ IF mptr^.dependency.forc
+ THEN
+ traceprintf2 (ModuleTrace, "initializing module: %s for C\n", mptr^.name);
+ ELSE
+ traceprintf2 (ModuleTrace, "initializing module: %s\n", mptr^.name);
+ END ;
+ IF mptr^.dependency.appl
+ THEN
+ traceprintf2 (ModuleTrace, "application module: %s\n", mptr^.name);
+ traceprintf (ModuleTrace, " calling M2RTS_ExecuteInitialProcedures\n");
+ M2RTS.ExecuteInitialProcedures ;
+ traceprintf (ModuleTrace, " calling application module\n");
+ END ;
+ mptr^.init (argc, argv, envp) ;
+ mptr := mptr^.next
+ UNTIL mptr = Modules[ordered]
+ END
+END ConstructModules ;
+
+
+(*
+ DeconstructModules - resolve dependencies and then call each
+ module constructor in turn.
+*)
+
+PROCEDURE DeconstructModules (applicationmodule: ADDRESS;
+ argc: INTEGER; argv, envp: ADDRESS) ;
+VAR
+ mptr: ModuleChain ;
+BEGIN
+ traceprintf2 (ModuleTrace, "application module finishing: %s\n", applicationmodule);
+ IF Modules[ordered] = NIL
+ THEN
+ traceprintf (ModuleTrace, " no ordered modules found during finishing\n")
+ ELSE
+ traceprintf (ModuleTrace, "ExecuteTerminationProcedures\n") ;
+ M2RTS.ExecuteTerminationProcedures ;
+ traceprintf (ModuleTrace, "terminating modules in sequence\n") ;
+ mptr := Modules[ordered]^.prev ;
+ REPEAT
+ IF mptr^.dependency.forc
+ THEN
+ traceprintf2 (ModuleTrace, "finalizing module: %s for C\n", mptr^.name);
+ ELSE
+ traceprintf2 (ModuleTrace, "finalizing module: %s\n", mptr^.name);
+ END ;
+ mptr^.fini (argc, argv, envp) ;
+ mptr := mptr^.prev
+ UNTIL mptr = Modules[ordered]^.prev
+ END
+END DeconstructModules ;
+
+
+(*
+ RegisterModule - adds module name to the list of outstanding
+ modules which need to have their dependencies
+ explored to determine initialization order.
+*)
+
+PROCEDURE RegisterModule (name: ADDRESS;
+ init, fini: ArgCVEnvP;
+ dependencies: PROC) ;
+BEGIN
+ CheckInitialized ;
+ IF NOT StaticInitialization
+ THEN
+ traceprintf2 (ModuleTrace, "module: %s registering\n",
+ name);
+ moveTo (unordered,
+ CreateModule (name, init, fini, dependencies))
+ END
+END RegisterModule ;
+
+
+(*
+ equal - return TRUE if C string cstr is equal to str.
+*)
+
+PROCEDURE equal (cstr: ADDRESS; str: ARRAY OF CHAR) : BOOLEAN ;
+BEGIN
+ RETURN strncmp (cstr, ADR (str), StrLen (str)) = 0
+END equal ;
+
+
+(*
+ 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 dynamically.
+ force generate a list of all modules seen after having
+ their dependancies resolved and forced.
+*)
+
+PROCEDURE SetupDebugFlags ;
+VAR
+ pc: POINTER TO CHAR ;
+BEGIN
+ ModuleTrace := FALSE ;
+ DependencyTrace := FALSE ;
+ PostTrace := FALSE ;
+ PreTrace := FALSE ;
+ pc := getenv (ADR ("GCC_M2LINK_RTFLAG")) ;
+ WHILE (pc # NIL) AND (pc^ # nul) DO
+ IF equal (pc, "all")
+ THEN
+ ModuleTrace := TRUE ;
+ DependencyTrace := TRUE ;
+ PreTrace := TRUE ;
+ PostTrace := TRUE ;
+ ForceTrace := TRUE ;
+ INC (pc, 3)
+ ELSIF equal (pc, "module")
+ THEN
+ ModuleTrace := TRUE ;
+ INC (pc, 6)
+ ELSIF equal (pc, "dep")
+ THEN
+ DependencyTrace := TRUE ;
+ INC (pc, 3)
+ ELSIF equal (pc, "pre")
+ THEN
+ PreTrace := TRUE ;
+ INC (pc, 3)
+ ELSIF equal (pc, "post")
+ THEN
+ PostTrace := TRUE ;
+ INC (pc, 4)
+ ELSIF equal (pc, "force")
+ THEN
+ ForceTrace := TRUE ;
+ INC (pc, 5)
+ ELSE
+ INC (pc)
+ END
+ END
+END SetupDebugFlags ;
+
+
+(*
+ Init - initialize the debug flags and set all lists to NIL.
+*)
+
+PROCEDURE Init ;
+VAR
+ state: DependencyState ;
+BEGIN
+ SetupDebugFlags ;
+ FOR state := MIN (DependencyState) TO MAX (DependencyState) DO
+ Modules[state] := NIL
+ END
+END Init ;
+
+
+(*
+ 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.
+*)
+
+PROCEDURE CheckInitialized ;
+BEGIN
+ IF NOT Initialized
+ THEN
+ Initialized := TRUE ;
+ Init
+ END
+END CheckInitialized ;
+
+
+BEGIN
+ CheckInitialized
+END M2Dependent.
diff --git a/gcc/m2/gm2-libs/M2LINK.def b/gcc/m2/gm2-libs/M2LINK.def
new file mode 100644
index 00000000000..409142a2af5
--- /dev/null
+++ b/gcc/m2/gm2-libs/M2LINK.def
@@ -0,0 +1,41 @@
+(* M2LINK.def defines the linking mode used in Modula-2.
+
+Copyright (C) 2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+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/>. *)
+
+DEFINITION MODULE FOR "C" M2LINK ;
+
+
+TYPE
+ PtrToChar = POINTER TO CHAR ;
+
+(* These variables are set by the compiler in the program module
+ according to linking command line options. *)
+
+VAR
+ ForcedModuleInitOrder: PtrToChar ;
+ StaticInitialization : BOOLEAN ;
+
+
+END M2LINK.
diff --git a/gcc/m2/m2-link-support.h b/gcc/m2/m2-link-support.h
deleted file mode 100644
index a68b3c9cdc3..00000000000
--- a/gcc/m2/m2-link-support.h
+++ /dev/null
@@ -1,197 +0,0 @@
-/* Link support specs for GNU Modula-2.
- Copyright (C) 2019-2022 Free Software Foundation, Inc.
- Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
-
-This file is part of GCC.
-
-GCC 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.
-
-GCC 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 GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-/* The subprograms used by Modula-2 to facilitate linking are:
- gm2l - parses the top level module and all other dependent
- modules. It creates a dependency tree and emits a list
- of dependent modules.
- gm2lcc - generates a link command for all dependent modules or
- display module object filesystem location.
- gm2m - parses the top level module and all other dependent
- module and generates a Makefile from the import tree.
- gm2lgen - generate a C or C++ scaffold from the list of modules.
- gm2lorder - manipulate the dependent list of modules to force
- critcal runtime modules to be initialized at the
- beginning of the init sequence. */
-
-/* AS run the assembler with default options. */
-
-#define AS(INPUT,OUTPUT) "as %a %Y " INPUT " -o " OUTPUT
-
-/* GM2CC_OPTIONS a list of all CC options used by gm2 during the
- link scaffold generation. */
-
-#define GM2CC_OPTIONS "%{i*} %{v*} %{m*} %{g*} %{O*} %{fPIC} %{fpic} \
- %{+e*} %{I*} %{MD} %{MMD} %{M} %{MM} %{MA} \
- %{MT*} %{MF*} -quiet "
-
-/* SCAFFOLDNAME is the basename of the scaffold C or C++ program
- which may be automatically generated by the linking process. */
-
-#define SCAFFOLDNAME "%b_m2"
-
-/* RM_IF_NOSAVETEMP remove the next file if save-temps is absent. */
-
-#define RM_IF_NOSAVETEMP "%{!save-temps*:%d}"
-
-/* GM2CC compile the link scaffold either with the C or C++
- compiler. */
-
-#define GM2CC(INPUT,OUTPUT) \
- "%{!fno-exceptions:cc1plus;:cc1} %1" GM2CC_OPTIONS " " INPUT " \
- -o " RM_IF_NOSAVETEMP SCAFFOLDNAME ".s \n\
- " AS(SCAFFOLDNAME ".s",OUTPUT) " "
-
-/* GM2LCC invoke the sub program gm2lcc with the object path options
- and user supplied objects. It will search for Modula-2 object
- if they are not already present on the command line. The
- current module is contained in OBJECT and LST is a list of all
- the dependant modules. */
-
-#define GM2LCC(OBJECT,LST) \
- "gm2lcc %{fshared} %{fpic} %{fPIC} %{B*} %{L*} %{ftarget-ar=*} \
- %{ftarget-ranlib=*} \
- %{fobject-path=*} %{v} --exec --startup \
- " SCAFFOLDNAME "%O \
- %{!fshared:--ar %:objects() %:noobjects() -o " \
- RM_IF_NOSAVETEMP "%w%g.a } \
- " OBJECT " \
- %{fshared:%w%{o:%{o*}}%:nolink() %:objects() %:noobjects() \
- %:linkargs() } " LST " "
-
-/* GM2LORDER run the gm2lorder sub program. It generates a module
- list LST by parsing INPUT and all dependant modules. */
-
-#define GM2LORDER(INPUT,LST) \
- "gm2lorder %{fruntime-modules=*} " INPUT " -o " LST " \n"
-
-/* GM2LGEN run the gm2lgen sub program which generates a C or C++
- scaffold (SCAFFOLDSRC). It then compiles SCAFFOLDSRC and links
- it with all dependant modules in LST. MAINOBJECT is the main
- module object name containing the scaffold. */
-
-#define GM2LGEN(LST,SCAFFOLDSRC,MAINOBJECT) \
- "gm2lgen %{fshared} %{fshared:--terminate --exit} \
- %{!fno-exceptions:-fcpp} " LST " -o " SCAFFOLDSRC " \n\
- " GM2L_COMBINE(LST,SCAFFOLDSRC,MAINOBJECT)
-
-/* GM2L_COMBINE compiles the scaffold SCAFFOLDSRC and links all dependant
- modules in LST. MAINOBJECT is the main module object containing
- the scaffold. */
-
-#define GM2L_COMBINE(LST,SCAFFOLDSRC,MAINOBJECT) \
- GM2CC(SCAFFOLDSRC,MAINOBJECT) " \n\
- rm -f %w%d%g.a \n\
- " GM2LCC("--mainobject " MAINOBJECT,LST)
-
-/* Pass the preprocessor options on the command line together with
- the exec prefix. */
-
-#define M2CPP "%{fcpp:-fcppbegin %:exec_prefix(cc1)" \
- " -E -lang-asm -traditional-cpp " \
- " %(cpp_unique_options) -fcppend}"
-
-/* Generate a list of topologically sorted dependent modules. */
-
-#define GM2L(INPUT,OUTPUT) \
- "gm2l %{v} " M2CPP " %{I*} %{fdef=*} %{fmod=*} " OUTPUT " " INPUT " "
-
-/* General GNU options. */
-
-#define GENERAL_OPTIONS "%{i*} %{f*} %{+e*} %{I*} %{MD} %{MMD} %{M} \
- %{MM} %{MA} %{MT*} %{MF*} %V"
-
-/* Run the compiler using standard GNU options. */
-
-#define CC1GM2 "cc1gm2 " M2CPP " %(cc1_options) " GENERAL_OPTIONS
-
-/* Generate a swig interface file and exit. */
-
-#define SWIG "%{fswig:" CC1GM2 "%i \n\
- %:exit()}"
-
-/* Generate a basename.lst containing a list of all dependent modules
- for the project and exit. */
-
-#define MAKELIST "%{fmakelist:" GM2L("%i","%{!pipe:-o %g.l}") " |\n\
- gm2lorder %{fruntime-modules=*} %{!pipe:%g.l} \
- -o %b.lst \n\
- %:exit()}"
-
-/* Generate a scaffold from basename.lst and store the output source
- into SCAFFOLDNAME.cpp and exit. */
-
-#define MAKEINIT "%{fmakeinit:gm2lgen %{fshared} \
- %{fshared:--terminate --exit} \
- %{!fno-exceptions:-fcpp} %b.lst -o " \
- SCAFFOLDNAME ".cpp \n\
- %:exit()}"
-
-/* Display the filesystem location of the all object files in the
- project list. */
-
-#define REPORT_OBJECTS "gm2lcc %{fshared} %{fpic} %{fPIC} %{B*} %{L*} \
- %{ftarget-ar=*} %{ftarget-ranlib=*} \
- %{fobject-path=*} %{v} -c "
-
-/* Generate a list of modules used within a project and report the
- object file location and exit. */
-
-#define MODULES \
- "%{fmodules:%{fuselist:" REPORT_OBJECTS " %b.lst}" \
- "%{!fuselist:" GM2L("%i","%{!pipe:-o %g.l}") " |\n\
- gm2lorder %{fruntime-modules=*} \
- %{!pipe:%g.l} -o %g.lst \n\
- " REPORT_OBJECTS " %g.lst} \n\
- %:exit()}"
-
-/* MODULA_PROJECT_SUPPORT contains a list of all project support
- sub components. */
-
-#define MODULA_PROJECT_SUPPORT SWIG MAKELIST MAKEINIT MODULES
-
-/* GM2 invoke cc1gm2 placing assembler output into OUTPUT given
- source file, INPUT. */
-
-#define GM2(INPUT,OUTPUT) CC1GM2 " -o " OUTPUT " " INPUT
-
-/* GEN_SCAFFOLD_SRC generates the string SCAFFOLDNAME ".cpp"
- marking it for deletion if -fmakeinit is absent. */
-
-#define GEN_SCAFFOLD_SRC \
- "%{fmakeinit:" SCAFFOLDNAME ".cpp;:" \
- RM_IF_NOSAVETEMP SCAFFOLDNAME ".cpp}"
-
-/* M2LINK compile main module (providing absense of -fonlylink)
- and link all project dependent modules. */
-
-#define M2LINK \
- "%{!S:%{!gm2gcc:%{!fonlylink:" GM2("%i",RM_IF_NOSAVETEMP "%g.s") " \n\
- " AS("%g.s","%w%b%O") " } \n\
- %{!fuselist:" GM2L("%i"," -o %g.l ") " \n\
- " GM2LORDER("%g.l","%g.lst") " \n\
- " GM2LGEN("%{fuselist:%b.lst;:%g.lst}",\
- GEN_SCAFFOLD_SRC,\
- RM_IF_NOSAVETEMP SCAFFOLDNAME "%O") "}}\n\
- }"
-
-/* MODULA_LINK_SUPPORT only invoke link subprocesses if no -c option. */
-
-#define MODULA_LINK_SUPPORT "%{!c:" M2LINK "}"
diff --git a/gcc/m2/mc-boot-ch/GM2LINK.c b/gcc/m2/mc-boot-ch/GM2LINK.c
new file mode 100644
index 00000000000..2d293fd5a7d
--- /dev/null
+++ b/gcc/m2/mc-boot-ch/GM2LINK.c
@@ -0,0 +1,24 @@
+/* GM2LINK.c a handwritten module for mc.
+
+Copyright (C) 2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaiusmod2@gmail.com>.
+
+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/>. */
+
+/* mc currently is built using a static scaffold. */
+
+int M2LINK_StaticInitialization = 1;
diff --git a/gcc/m2/mc-boot/GM2LINK.h b/gcc/m2/mc-boot/GM2LINK.h
new file mode 100644
index 00000000000..9807ab19d7e
--- /dev/null
+++ b/gcc/m2/mc-boot/GM2LINK.h
@@ -0,0 +1,59 @@
+/* do not edit automatically generated by mc from M2LINK. */
+/* M2LINK.def defines the linking mode used in Modula-2.
+
+Copyright (C) 2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+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/>. */
+
+
+#if !defined (_M2LINK_H)
+# define _M2LINK_H
+
+#include "config.h"
+#include "system.h"
+# ifdef __cplusplus
+extern "C" {
+# endif
+# if !defined (PROC_D)
+# define PROC_D
+ typedef void (*PROC_t) (void);
+ typedef struct { PROC_t proc; } PROC;
+# endif
+
+
+# if defined (_M2LINK_C)
+# define EXTERN
+# else
+# define EXTERN extern
+# endif
+
+typedef char *M2LINK_PtrToChar;
+
+EXTERN M2LINK_PtrToChar M2LINK_ForcedModuleInitOrder;
+EXTERN unsigned int M2LINK_StaticInitialization;
+# ifdef __cplusplus
+}
+# endif
+
+# undef EXTERN
+#endif
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-06-20 23:31 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-20 23:31 [gcc/devel/m2link] New files implementing the scaffold at compile/runtime 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).