diff options
author | Gaius Mulley <gaius.mulley@southwales.ac.uk> | 2022-06-29 01:37:38 +0100 |
---|---|---|
committer | Gaius Mulley <gaius.mulley@southwales.ac.uk> | 2022-06-29 01:37:38 +0100 |
commit | 6d1cdc565aed63b651280885b7096db895ef474d (patch) | |
tree | 25b3699f00806132b87d8f2003dafcdeaf4a8864 | |
parent | 56ec5f3245333e2dea1afc721bf2c8bd4a8bb27e (diff) |
Renamed files from .c to .cc and added new support header files.
This patch also includes a mc-boot translated copy of the
module M2Dependent.
gcc/m2/ChangeLog:
* gm2-libs-ch/UnixArgs.cc: Renamed from gm2-libs-ch/UnixArgs.c.
* gm2-libs-ch/dtoa.cc: Renamed from gm2-libs-ch/dtoa.c.
* gm2-libs-ch/ldtoa.cc: Renamed from gm2-libs-ch/ldtoa.c.
* gm2-libs-ch/m2rts.h: New file.
* mc-boot-ch/GUnixArgs.cc: New file.
* mc-boot-ch/m2rts.h: New file.
* mc-boot/GM2Dependent.c: New file.
* mc-boot/GM2Dependent.h: New file.
Signed-off-by: Gaius Mulley <gaius.mulley@southwales.ac.uk>
-rw-r--r-- | gcc/m2/gm2-libs-ch/UnixArgs.cc (renamed from gcc/m2/gm2-libs-ch/UnixArgs.c) | 0 | ||||
-rw-r--r-- | gcc/m2/gm2-libs-ch/dtoa.cc (renamed from gcc/m2/gm2-libs-ch/dtoa.c) | 0 | ||||
-rw-r--r-- | gcc/m2/gm2-libs-ch/ldtoa.cc (renamed from gcc/m2/gm2-libs-ch/ldtoa.c) | 0 | ||||
-rw-r--r-- | gcc/m2/gm2-libs-ch/m2rts.h | 41 | ||||
-rw-r--r-- | gcc/m2/mc-boot-ch/GUnixArgs.cc | 91 | ||||
-rw-r--r-- | gcc/m2/mc-boot-ch/m2rts.h | 41 | ||||
-rw-r--r-- | gcc/m2/mc-boot/GM2Dependent.c | 1113 | ||||
-rw-r--r-- | gcc/m2/mc-boot/GM2Dependent.h | 78 |
8 files changed, 1364 insertions, 0 deletions
diff --git a/gcc/m2/gm2-libs-ch/UnixArgs.c b/gcc/m2/gm2-libs-ch/UnixArgs.cc index 1180f351b24..1180f351b24 100644 --- a/gcc/m2/gm2-libs-ch/UnixArgs.c +++ b/gcc/m2/gm2-libs-ch/UnixArgs.cc diff --git a/gcc/m2/gm2-libs-ch/dtoa.c b/gcc/m2/gm2-libs-ch/dtoa.cc index 57317588ba1..57317588ba1 100644 --- a/gcc/m2/gm2-libs-ch/dtoa.c +++ b/gcc/m2/gm2-libs-ch/dtoa.cc diff --git a/gcc/m2/gm2-libs-ch/ldtoa.c b/gcc/m2/gm2-libs-ch/ldtoa.cc index ac14297ec24..ac14297ec24 100644 --- a/gcc/m2/gm2-libs-ch/ldtoa.c +++ b/gcc/m2/gm2-libs-ch/ldtoa.cc diff --git a/gcc/m2/gm2-libs-ch/m2rts.h b/gcc/m2/gm2-libs-ch/m2rts.h new file mode 100644 index 00000000000..57e6e90d94d --- /dev/null +++ b/gcc/m2/gm2-libs-ch/m2rts.h @@ -0,0 +1,41 @@ +/* m2rts.h provides a C interface to M2RTS.mod. + +Copyright (C) 2019-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/>. */ + + +typedef void (*proc_con) (int, char **, char **); +typedef void (*proc_dep) (void); + +extern "C" void M2RTS_RequestDependant (const char *modulename, const char *dependancy); +extern "C" void M2RTS_RegisterModule (const char *modulename, + proc_con init, proc_con fini, proc_dep dependencies); +extern "C" void _M2_M2RTS_init (void); + +extern "C" void M2RTS_ConstructModules (const char *, + int argc, char *argv[], char *envp[]); +extern "C" void M2RTS_Terminate (void); +extern "C" void M2RTS_DeconstructModules (void); + +extern "C" void M2RTS_Halt (const char *, int, const char *, const char *) __attribute__ ((noreturn)); diff --git a/gcc/m2/mc-boot-ch/GUnixArgs.cc b/gcc/m2/mc-boot-ch/GUnixArgs.cc new file mode 100644 index 00000000000..1180f351b24 --- /dev/null +++ b/gcc/m2/mc-boot-ch/GUnixArgs.cc @@ -0,0 +1,91 @@ +/* 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>. + +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 "m2rts.h" + + +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; +} + +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/gcc/m2/mc-boot-ch/m2rts.h b/gcc/m2/mc-boot-ch/m2rts.h new file mode 100644 index 00000000000..57e6e90d94d --- /dev/null +++ b/gcc/m2/mc-boot-ch/m2rts.h @@ -0,0 +1,41 @@ +/* m2rts.h provides a C interface to M2RTS.mod. + +Copyright (C) 2019-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/>. */ + + +typedef void (*proc_con) (int, char **, char **); +typedef void (*proc_dep) (void); + +extern "C" void M2RTS_RequestDependant (const char *modulename, const char *dependancy); +extern "C" void M2RTS_RegisterModule (const char *modulename, + proc_con init, proc_con fini, proc_dep dependencies); +extern "C" void _M2_M2RTS_init (void); + +extern "C" void M2RTS_ConstructModules (const char *, + int argc, char *argv[], char *envp[]); +extern "C" void M2RTS_Terminate (void); +extern "C" void M2RTS_DeconstructModules (void); + +extern "C" void M2RTS_Halt (const char *, int, const char *, const char *) __attribute__ ((noreturn)); diff --git a/gcc/m2/mc-boot/GM2Dependent.c b/gcc/m2/mc-boot/GM2Dependent.c new file mode 100644 index 00000000000..d677798962e --- /dev/null +++ b/gcc/m2/mc-boot/GM2Dependent.c @@ -0,0 +1,1113 @@ +/* do not edit automatically generated by mc from M2Dependent. */ +/* 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/>. */ + +#include "config.h" +#include "system.h" +# if !defined (PROC_D) +# define PROC_D + typedef void (*PROC_t) (void); + typedef struct { PROC_t proc; } PROC; +# endif + +# if !defined (TRUE) +# define TRUE (1==1) +# endif + +# if !defined (FALSE) +# define FALSE (1==0) +# endif + +# include "GStorage.h" +#if defined(__cplusplus) +# undef NULL +# define NULL 0 +#endif +#define _M2Dependent_H +#define _M2Dependent_C + +# include "Glibc.h" +# include "GM2LINK.h" +# include "GASCII.h" +# include "GSYSTEM.h" +# include "GStorage.h" +# include "GStrLib.h" +# include "GM2RTS.h" + +typedef struct M2Dependent_ArgCVEnvP_p M2Dependent_ArgCVEnvP; + +typedef struct DependencyList_r DependencyList; + +typedef struct _T2_r _T2; + +typedef _T2 *ModuleChain; + +typedef struct _T3_a _T3; + +typedef enum {unregistered, unordered, started, ordered, user} DependencyState; + +typedef void (*M2Dependent_ArgCVEnvP_t) (int, void *, void *); +struct M2Dependent_ArgCVEnvP_p { M2Dependent_ArgCVEnvP_t proc; }; + +struct DependencyList_r { + PROC proc; + unsigned int forced; + unsigned int forc; + unsigned int appl; + DependencyState state; + }; + +struct _T3_a { ModuleChain array[user-unregistered+1]; }; +struct _T2_r { + void *name; + M2Dependent_ArgCVEnvP init; + M2Dependent_ArgCVEnvP fini; + DependencyList dependency; + ModuleChain prev; + ModuleChain next; + }; + +static _T3 Modules; +static unsigned int Initialized; +static unsigned int ModuleTrace; +static unsigned int DependencyTrace; +static unsigned int PreTrace; +static unsigned int PostTrace; +static unsigned int ForceTrace; + +/* + ConstructModules - resolve dependencies and then call each + module constructor in turn. +*/ + +extern "C" void M2Dependent_ConstructModules (void * applicationmodule, int argc, void * argv, void * envp); + +/* + DeconstructModules - resolve dependencies and then call each + module constructor in turn. +*/ + +extern "C" void M2Dependent_DeconstructModules (void * applicationmodule, int argc, void * argv, void * envp); + +/* + RegisterModule - adds module name to the list of outstanding + modules which need to have their dependencies + explored to determine initialization order. +*/ + +extern "C" void M2Dependent_RegisterModule (void * name, M2Dependent_ArgCVEnvP init, M2Dependent_ArgCVEnvP fini, PROC dependencies); + +/* + RequestDependant - used to specify that modulename is dependant upon + module dependantmodule. It only takes effect + if we are not using StaticInitialization. +*/ + +extern "C" void M2Dependent_RequestDependant (void * modulename, void * dependantmodule); + +/* + CreateModule - creates a new module entry and returns the + ModuleChain. +*/ + +static ModuleChain CreateModule (void * name, M2Dependent_ArgCVEnvP init, M2Dependent_ArgCVEnvP fini, PROC dependencies); + +/* + AppendModule - append chain to end of the list. +*/ + +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); + +/* + LookupModuleN - lookup module from the state list. The string is limited + to nchar. +*/ + +static ModuleChain LookupModuleN (DependencyState state, void * name, unsigned int nchar); + +/* + 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 0 if both strings are equal. + We cannot use Builtins.def during bootstrap. +*/ + +static int strcmp (M2LINK_PtrToChar a, M2LINK_PtrToChar b); + +/* + strncmp - return 0 if both strings are equal. + We cannot use Builtins.def during bootstrap. +*/ + +static int strncmp (M2LINK_PtrToChar a, M2LINK_PtrToChar b, unsigned int n); + +/* + strlen - returns the length of string. +*/ + +static int strlen_ (M2LINK_PtrToChar string); + +/* + 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 - resolve dependencies for currentmodule. +*/ + +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); + +/* + 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. +*/ + +static void combine (DependencyState src, DependencyState dest); + +/* + ForceDependencies - if the user has specified a forced order then we override + the dynamic ordering with the preference. +*/ + +static void ForceDependencies (void); + +/* + 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 dynamically. + force generate a list of all modules seen after having + their dependancies resolved and forced. +*/ + +static void SetupDebugFlags (void); + +/* + Init - initialize the debug flags and set all lists to NIL. +*/ + +static void Init (void); + +/* + 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 CheckInitialized (void); + + +/* + CreateModule - creates a new module entry and returns the + ModuleChain. +*/ + +static ModuleChain CreateModule (void * name, M2Dependent_ArgCVEnvP init, M2Dependent_ArgCVEnvP fini, PROC dependencies) +{ + ModuleChain mptr; + + Storage_ALLOCATE ((void **) &mptr, sizeof (_T2)); + 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 end of the list. +*/ + +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 list. */ + chain->prev = (*head)->prev; /* Add Item to the end of list. */ + (*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 (); +} + + +/* + LookupModuleN - lookup module from the state list. The string is limited + to nchar. +*/ + +static ModuleChain LookupModuleN (DependencyState state, void * name, unsigned int nchar) +{ + ModuleChain ptr; + + if (Modules.array[state-unregistered] != NULL) + { + ptr = Modules.array[state-unregistered]; + do { + if ((strncmp (reinterpret_cast<M2LINK_PtrToChar> (ptr->name), reinterpret_cast<M2LINK_PtrToChar> (name), nchar)) == 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 (); +} + + +/* + LookupModule - lookup and return the ModuleChain pointer containing + module name from a particular list. +*/ + +static ModuleChain LookupModule (DependencyState state, void * name) +{ + return LookupModuleN (state, name, static_cast<unsigned int> (strlen_ (reinterpret_cast<M2LINK_PtrToChar> (name)))); + /* 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 0 if both strings are equal. + We cannot use Builtins.def during bootstrap. +*/ + +static int strcmp (M2LINK_PtrToChar a, M2LINK_PtrToChar b) +{ + if ((a != NULL) && (b != NULL)) + { + /* avoid gcc warning by using compound statement even if not strictly necessary. */ + if (a == b) + { + return 0; + } + else + { + while ((*a) == (*b)) + { + if ((*a) == ASCII_nul) + { + return 0; + } + a += 1; + b += 1; + } + } + } + return 1; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + strncmp - return 0 if both strings are equal. + We cannot use Builtins.def during bootstrap. +*/ + +static int strncmp (M2LINK_PtrToChar a, M2LINK_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 0; + } + else + { + while (((*a) == (*b)) && (n > 0)) + { + if (((*a) == ASCII_nul) || (n == 1)) + { + return 0; + } + a += 1; + b += 1; + n -= 1; + } + } + } + return 1; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + strlen - returns the length of string. +*/ + +static int strlen_ (M2LINK_PtrToChar string) +{ + int count; + + if (string == NULL) + { + return 0; + } + else + { + count = 0; + while ((*string) != ASCII_nul) + { + string += 1; + count += 1; + } + return count; + } + /* 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. +*/ + +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); +} + + +/* + ResolveDependant - +*/ + +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. */ + moveTo (ordered, mptr); + } + } +} + + +/* + 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; + + traceprintf2 (DependencyTrace, (const char *) " module %s", 11, modulename); + if (dependantmodule == NULL) + { + /* avoid dangling else. */ + traceprintf2 (DependencyTrace, (const char *) " has finished its import graph\\n", 32, modulename); + mptr = LookupModule (unordered, modulename); + if (mptr != NULL) + { + traceprintf2 (DependencyTrace, (const char *) " module %s is now ordered\\n", 28, modulename); + moveTo (ordered, mptr); + } + } + else + { + traceprintf2 (DependencyTrace, (const char *) " imports from %s\\n", 18, dependantmodule); + mptr = LookupModule (ordered, dependantmodule); + if (mptr == NULL) + { + traceprintf2 (DependencyTrace, (const char *) " module %s is not ordered\\n", 28, dependantmodule); + mptr = LookupModule (unordered, dependantmodule); + if (mptr == NULL) + { + traceprintf2 (DependencyTrace, (const char *) " module %s is not unordered\\n", 30, dependantmodule); + mptr = LookupModule (started, dependantmodule); + if (mptr == NULL) + { + traceprintf2 (DependencyTrace, (const char *) " module %s has not started\\n", 29, dependantmodule); + traceprintf2 (DependencyTrace, (const char *) " module %s attempting to import from", 37, modulename); + traceprintf2 (DependencyTrace, (const char *) " %s which has not registered itself via a constructor\\n", 55, dependantmodule); + } + else + { + traceprintf2 (DependencyTrace, (const char *) " module %s has registered itself and has started\\n", 51, dependantmodule); + } + } + else + { + traceprintf2 (DependencyTrace, (const char *) " module %s resolving\\n", 23, dependantmodule); + ResolveDependant (mptr, dependantmodule); + } + } + else + { + traceprintf2 (DependencyTrace, (const char *) " module %s ", 12, modulename); + traceprintf2 (DependencyTrace, (const char *) " dependant %s is ordered\\n", 26, dependantmodule); + } + } +} + + +/* + ResolveDependencies - resolve dependencies for currentmodule. +*/ + +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.appl) + { + libc_printf ((const char *) " application", 12); + } + 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); + } +} + + +/* + 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. +*/ + +static void combine (DependencyState src, DependencyState dest) +{ + ModuleChain last; + + while (Modules.array[src-unregistered] != NULL) + { + last = Modules.array[src-unregistered]->prev; + moveTo (ordered, last); + Modules.array[dest-unregistered] = last; /* New item is at the head. */ + } +} + + +/* + ForceDependencies - if the user has specified a forced order then we override + the dynamic ordering with the preference. +*/ + +static void ForceDependencies (void) +{ + ModuleChain mptr; + ModuleChain userChain; + unsigned int count; + M2LINK_PtrToChar pc; + M2LINK_PtrToChar start; + + if (M2LINK_ForcedModuleInitOrder != NULL) + { + userChain = NULL; + pc = M2LINK_ForcedModuleInitOrder; + start = pc; + count = 0; + while ((*pc) != ASCII_nul) + { + if ((*pc) == ',') + { + mptr = LookupModuleN (ordered, reinterpret_cast<void *> (start), count); + if (mptr != NULL) + { + moveTo (user, mptr); + } + pc += 1; + start = pc; + count = 0; + } + else + { + pc += 1; + count += 1; + } + } + if (start != pc) + { + mptr = LookupModuleN (ordered, reinterpret_cast<void *> (start), count); + if (mptr != NULL) + { + moveTo (user, mptr); + } + } + combine (user, ordered); + } +} + + +/* + equal - return TRUE if C string cstr is equal to str. +*/ + +static unsigned int equal (void * cstr, 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); + + return (strncmp (reinterpret_cast<M2LINK_PtrToChar> (cstr), reinterpret_cast<M2LINK_PtrToChar> (&str), StrLib_StrLen ((const char *) str, _str_high))) == 0; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + 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. +*/ + +static void SetupDebugFlags (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 (equal (reinterpret_cast<void *> (pc), (const char *) "all", 3)) + { + ModuleTrace = TRUE; + DependencyTrace = TRUE; + PreTrace = TRUE; + PostTrace = TRUE; + ForceTrace = 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; + } + } +} + + +/* + Init - initialize the debug flags and set all lists to NIL. +*/ + +static void Init (void) +{ + DependencyState state; + + SetupDebugFlags (); + for (state=unregistered; state<=user; state= static_cast<DependencyState>(static_cast<int>(state+1))) + { + Modules.array[state-unregistered] = NULL; + } +} + + +/* + 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 CheckInitialized (void) +{ + if (! Initialized) + { + Initialized = TRUE; + Init (); + } +} + + +/* + ConstructModules - resolve dependencies and then call each + module constructor in turn. +*/ + +extern "C" void M2Dependent_ConstructModules (void * applicationmodule, int argc, void * argv, void * envp) +{ + ModuleChain mptr; + M2Dependent_ArgCVEnvP nulp; + + CheckInitialized (); + traceprintf2 (ModuleTrace, (const char *) "application module: %s\\n", 24, applicationmodule); + mptr = LookupModule (unordered, applicationmodule); + if (mptr != NULL) + { + mptr->dependency.appl = TRUE; + } + traceprintf (PreTrace, (const char *) "Pre resolving dependents\\n", 26); + DumpModuleData (PreTrace); + ResolveDependencies (applicationmodule); + traceprintf (PreTrace, (const char *) "Post resolving dependents\\n", 27); + DumpModuleData (PostTrace); + ForceDependencies (); + traceprintf (ForceTrace, (const char *) "After user forcing ordering\\n", 29); + 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); + } + if (mptr->dependency.appl) + { + traceprintf2 (ModuleTrace, (const char *) "application module: %s\\n", 24, mptr->name); + traceprintf (ModuleTrace, (const char *) " calling M2RTS_ExecuteInitialProcedures\\n", 42); + M2RTS_ExecuteInitialProcedures (); + traceprintf (ModuleTrace, (const char *) " calling application module\\n", 30); + } + (*mptr->init.proc) (argc, argv, envp); + mptr = mptr->next; + } while (! (mptr == Modules.array[ordered-unregistered])); + } +} + + +/* + DeconstructModules - resolve dependencies and then call each + module constructor in turn. +*/ + +extern "C" void M2Dependent_DeconstructModules (void * applicationmodule, int argc, void * argv, void * envp) +{ + ModuleChain mptr; + + traceprintf2 (ModuleTrace, (const char *) "application module finishing: %s\\n", 34, applicationmodule); + if (Modules.array[ordered-unregistered] == NULL) + { + traceprintf (ModuleTrace, (const char *) " no ordered modules found during finishing\\n", 45); + } + else + { + traceprintf (ModuleTrace, (const char *) "ExecuteTerminationProcedures\\n", 30); + M2RTS_ExecuteTerminationProcedures (); + traceprintf (ModuleTrace, (const char *) "terminating modules in sequence\\n", 33); + mptr = Modules.array[ordered-unregistered]->prev; + do { + if (mptr->dependency.forc) + { + traceprintf2 (ModuleTrace, (const char *) "finalizing module: %s for C\\n", 29, mptr->name); + } + else + { + traceprintf2 (ModuleTrace, (const char *) "finalizing module: %s\\n", 23, mptr->name); + } + (*mptr->fini.proc) (argc, argv, envp); + mptr = mptr->prev; + } while (! (mptr == Modules.array[ordered-unregistered]->prev)); + } +} + + +/* + RegisterModule - adds module name to the list of outstanding + modules which need to have their dependencies + explored to determine initialization order. +*/ + +extern "C" void M2Dependent_RegisterModule (void * name, M2Dependent_ArgCVEnvP init, M2Dependent_ArgCVEnvP fini, PROC dependencies) +{ + CheckInitialized (); + if (! M2LINK_StaticInitialization) + { + traceprintf2 (ModuleTrace, (const char *) "module: %s registering\\n", 24, name); + moveTo (unordered, CreateModule (name, init, fini, dependencies)); + } +} + + +/* + RequestDependant - used to specify that modulename is dependant upon + module dependantmodule. It only takes effect + if we are not using StaticInitialization. +*/ + +extern "C" void M2Dependent_RequestDependant (void * modulename, void * dependantmodule) +{ + CheckInitialized (); + if (! M2LINK_StaticInitialization) + { + PerformRequestDependant (modulename, dependantmodule); + } +} + +extern "C" void _M2_M2Dependent_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[]) +{ + CheckInitialized (); +} + +extern "C" void _M2_M2Dependent_finish (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[]) +{ +} diff --git a/gcc/m2/mc-boot/GM2Dependent.h b/gcc/m2/mc-boot/GM2Dependent.h new file mode 100644 index 00000000000..7cdbee63d26 --- /dev/null +++ b/gcc/m2/mc-boot/GM2Dependent.h @@ -0,0 +1,78 @@ +/* do not edit automatically generated by mc from M2Dependent. */ +/* 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/>. */ + + +#if !defined (_M2Dependent_H) +# define _M2Dependent_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 + +# include "GSYSTEM.h" + +# if defined (_M2Dependent_C) +# define EXTERN +# else +# define EXTERN extern +# endif + +typedef struct M2Dependent_ArgCVEnvP_p M2Dependent_ArgCVEnvP; + +typedef void (*M2Dependent_ArgCVEnvP_t) (int, void *, void *); +struct M2Dependent_ArgCVEnvP_p { M2Dependent_ArgCVEnvP_t proc; }; + +EXTERN void M2Dependent_ConstructModules (void * applicationmodule, int argc, void * argv, void * envp); +EXTERN void M2Dependent_DeconstructModules (void * applicationmodule, int argc, void * argv, void * envp); + +/* + RegisterModule - adds module name to the list of outstanding + modules which need to have their dependencies + explored to determine initialization order. +*/ + +EXTERN void M2Dependent_RegisterModule (void * name, M2Dependent_ArgCVEnvP init, M2Dependent_ArgCVEnvP fini, PROC dependencies); + +/* + RequestDependant - used to specify that modulename is dependant upon + module dependantmodule. +*/ + +EXTERN void M2Dependent_RequestDependant (void * modulename, void * dependantmodule); +# ifdef __cplusplus +} +# endif + +# undef EXTERN +#endif |