public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/modula-2] Integration of gm2l into cc1gm2 and a rewrite of gm2spec.cc.
@ 2022-07-24 20:32 Gaius Mulley
  0 siblings, 0 replies; only message in thread
From: Gaius Mulley @ 2022-07-24 20:32 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:57900dd7f9af9a22b8ada2d95c6fd6e72ebed21b

commit 57900dd7f9af9a22b8ada2d95c6fd6e72ebed21b
Author: Gaius Mulley <gaius.mulley@southwales.ac.uk>
Date:   Sun Jul 24 21:30:49 2022 +0100

    Integration of gm2l into cc1gm2 and a rewrite of gm2spec.cc.
    
    This patch integrates the functionality of the gm2l tool into cc1gm2.
    The gm2 driver has been rewritten.  New small project tests have
    been added to the testsuite to ensure that ISO and PIM linking works.
    
    gcc/ChangeLog:
    
            * doc/gm2.texi (-fuselist): Removed option.  (-fuse-list=) New
            option.  (-Wstudents) Replaced by (-Wstyle).
            (-Wpedantic-param-names) improved explaination.  (-Wpedantic-cast)
            improved explaination.  (Linking) New node.
            * gcc/gcc.cc (print_option): Removed line break after printing
            errors.
    
    gcc/m2/ChangeLog:
    
            * m2/Make-lang.in (m2/gm2-compiler/m2flex.c): Add
            insn-attr-common.h as a dependent.
            * bnf/m2-3.bnf (ProgramModule): Correct token location.
            (ImplementationModule) Correct token location.
            * bnf/m2.bnf (DefinitionModule): RegisterDefinitionModule
            is now called with parameter forC.
            * gm2-compiler/M2Base.mod (SymbolTable): Import list inserted identifier
            PutModuleBuiltin.  (InitBase) _BaseTypes now recorded as a builtin
            module.  Spelling changes and formatting changes.
            * gm2-compiler/M2Batch.def (GetModuleNo): Renamed parameter n to
            nth.
            * gm2-compiler/M2Batch.mod (GetModuleNo): Renamed parameter n to
            nth.  Renamed DoneQueue to SeenList.
            * gm2-compiler/M2Code.mod (M2Options): Import list replaced identifiers
            StudentChecking with StyleChecking.
            * gm2-compiler/M2Comp.mod (M2Options): Import list added identifier
            GenModuleList.  (SymbolTable) Import PutModLink, IsDefLink,
            IsModLink.  Added descriptive text "(for C)" and "(linking)" when
            a module is parsed.  Record modules only parsed to obtain module
            dependencies using PutModLink.
            * gm2-compiler/M2GCCDeclare.mod (SymbolTable): Import list replaced
            identifiers IsCtor, IsExtern and IsPublic.
            (DeclareProcedureToGccSeparateProgram) Add IsExtern.
            (PrintScope) Improved information about the scope.
            * gm2-compiler/M2GenGCC.mod:  Corrected indent for trace print.
            * gm2-compiler/M2Options.def: Export list replaced
            identifiers SetStudents with SetStyle.  Added GetUselistFilename,
            StudentChecking, StyleChecking, GetRuntimeModuleOverride,
            GenModuleList, GetGenModuleFilename and SetGenModuleList.
            * gm2-compiler/M2Options.mod (DynamicStrings): Import list inserted
            identifiers GenModuleListFilename, GenModuleListFlag and
            UselistFlag.  (SetUselist) Extra parameter value.
            (GetUselist) return UselistFlag.  (GetUselistFilename)
            Return UselistFilename.  Replace Students with Style.
            (SetGenModuleList) New procedure.  (GetGenModuleFilename)
            New procedure.
            * gm2-compiler/M2Quads.mod (BuildM2LinkFunction): Rewritten.
            * gm2-compiler/M2Scaffold.def (ctorArray): Declared.
            * gm2-compiler/M2Scaffold.mod (SymbolTable): Import list added
            identifiers ForeachModuleDo, IsDefImp, IsDefinitionForC, IsModule and
            IsModuleBuiltin.  (AddEntry) New procedure.  (AddModuleToCtor)
            New procedure.  (WriteCtorList) New procedure.
            (CreateCtorListFromImports) New procedure.  (CreateCtorList)
            New procedure.  (DeclareScaffoldFunctions) Add warning note
            if attempting to use dynamic linking without a module ctor list.
            * gm2-compiler/M2Students.mod (M2Options): Replaced Students with
            Style.
            * gm2-compiler/P0SymBuild.def (RegisterDefinitionModule): Added
            parameter forC.
            * gm2-compiler/P0SymBuild.mod: Import list includes
            PutDefinitionForC.  (RegisterDefinitionModule) Added
            parameter forC and implemented by calling PutDefinitionForC.
            * gm2-compiler/SymbolTable.def: Import list added identifiers
            PutDefLink, PutModLink, PutModuleBuiltin, IsDefLink, IsModLink and
            IsModuleBuiltin.
            * gm2-compiler/SymbolTable.mod (PutDefLink): New procedure.
            (PutModLink) New procedure.  (PutModuleBuiltin) New procedure.
            (IsDefLink) New procedure function.  (IsModLink) New procedure function.
            and (IsModuleBuiltin) New procedure function.  New field for
            Module and DefImp to determine if the module was necessary for
            linking only.
            * gcc-gm2/m2options.h (SetUselist): Added parameter.  Replace
            Students with Style.  (SetGenModuleList) New procedure.
            * gm2-lang.cc (gm2_langhook_handle_option): Added
            fgen_module_list.  Replaced students with style.  fuselist changed
            to fuselist=_.  fno-pthread changed to fpthread.
            * gm2-libs-iso/COROUTINES.mod: Corrected comment by removing libpth.
            (localInit) call Init.
            * gm2-libs-iso/RTentity.mod: Introduced many asserts.
            (Initialize) New boolean.
            * gm2-libs-iso/Storage.mod (Initialize): New boolean.  All
            exported procedures check Initialize and call Init if required.
            * gm2-libs/COROUTINES.def: Added FOR "C".
            * gm2-libs/M2Dependent.mod (ForceDependencies): Set forced
            to TRUE.
            * gm2spec.cc: Rewritten heavily using the fortran and c++ spec
            code.
            * tools-src/makeSystem: Add ${MINIMAL} to the flags list.
    
    gcc/testsuite/gm2/ChangeLog:
    
            * calling-c/datatypes/unbounded/run/pass/calling-c-datatypes-unbounded-run-pass.exp:
            Use new library abbreviations and gm2_link_lib.
            * calling-c/datatypes/unbounded/run/pass/m.mod: Use new library
            abbreviations and gm2_link_lib.
            * complex/run/pass/complex-run-pass.exp: Use new library
            abbreviations and gm2_link_lib.
            * complex/run/pass/main.c: Use new library abbreviations and
            gm2_link_lib.
            * coroutines/pim/run/pass/coroutines-pim-run-pass.exp: Use new
            library abbreviations and gm2_link_lib.
            * examples/callingC/run/pass/examples-callingC-run-pass.exp: Use
            new library abbreviations and gm2_link_lib.
            * exceptions/run/pass/cpp.cpp: Use new library abbreviations and
            gm2_link_lib.
            * exceptions/run/pass/exceptions-run-pass.exp: Use new library
            abbreviations and gm2_link_lib.
            * exceptions/run/pass/m2test.mod: Use new library abbreviations
            and gm2_link_lib.
            * exceptions/run/pass/mycpp.cpp: Use new library abbreviations and
            gm2_link_lib.
            * extensions/run/pass/extensions-run-pass.exp: Use new library
            abbreviations and gm2_link_lib.
            * imports/run/pass/imports-run-pass.exp: Use new library
            abbreviations and gm2_link_lib.
            * iso/run/pass/iso-run-pass.exp: Use new library abbreviations and
            gm2_link_lib.
            * link/externalscaffold/pass/link-externalscaffold-pass.exp: Use
            new library abbreviations and gm2_link_lib.
            * linking/libarchive/pass/linking-libarchive-pass.exp: Use new
            library abbreviations and gm2_link_lib.
            * pim/no-options/run/pass/pim-no-options-run-pass.exp: Use new
            library abbreviations and gm2_link_lib.
            * pim/options/optimize/run/pass/pim-options-optimize-run-pass.exp:
            Use new library abbreviations and gm2_link_lib.
            * pim/run/fail/pim-run-fail.exp: Use new library abbreviations and
            gm2_link_lib.
            * pim/run/pass/pim-run-pass.exp: Use new library abbreviations and
            gm2_link_lib.
            * pimcoroutines/run/pass/pimcoroutines-run-pass.exp: Use new
            library abbreviations and gm2_link_lib.
            * pimlib/logitech/run/pass/pimlib-logitech-run-pass.exp: Use new
            library abbreviations and gm2_link_lib.
            * pimlib/run/pass/pimlib-run-pass.exp: Use new library
            abbreviations and gm2_link_lib.
            * projects/README: (New file).
            * projects/iso/run/pass/halma/halma.mod: (New file).
            * projects/iso/run/pass/halma/projects-iso-run-pass-halma.exp:
            (New file).
            * projects/iso/run/pass/hello/hello.mod: (New file).
            * projects/iso/run/pass/hello/projects-iso-run-pass-hello.exp:
            (New file).
            * projects/log/run/pass/hello/hello.mod: (New file).
            * projects/log/run/pass/hello/projects-log-run-pass-hello.exp:
            (New file).
            * testsuite/gm2/projects/pim/run/pass/hello/hello.mod: (New file).
            * testsuite/gm2/projects/pim/run/pass/hello/projects-pim-run-pass-hello.exp:
            (New file).
            * projects/pim/run/pass/random/AdvMap.def: (New file).
            * projects/pim/run/pass/random/AdvMap.mod: (New file).
            * projects/pim/run/pass/random/BoxMap.def: (New file).
            * projects/pim/run/pass/random/BoxMap.mod: (New file).
            * projects/pim/run/pass/random/Chance.def: (New file).
            * projects/pim/run/pass/random/Chance.mod: (New file).
            * projects/pim/run/pass/random/Geometry.def: (New file).
            * projects/pim/run/pass/random/Geometry.mod: (New file).
            * projects/pim/run/pass/random/MakeBoxes.def: (New file).
            * projects/pim/run/pass/random/MakeBoxes.mod: (New file).
            * projects/pim/run/pass/random/Map.mod: (New file).
            * projects/pim/run/pass/random/MapOptions.def: (New file).
            * projects/pim/run/pass/random/MapOptions.mod: (New file).
            * projects/pim/run/pass/random/Options.def: (New file).
            * projects/pim/run/pass/random/Options.mod: (New file).
            * projects/pim/run/pass/random/RoomMap.def: (New file).
            * projects/pim/run/pass/random/RoomMap.mod: (New file).
            * projects/pim/run/pass/random/StoreCoords.def: (New file).
            * projects/pim/run/pass/random/StoreCoords.mod: (New file).
            * projects/pim/run/pass/random/WriteMap.def: (New file).
            * projects/pim/run/pass/random/WriteMap.mod: (New file).
            * sets/run/pass/sets-run-pass.exp: Use new library abbreviations
            and gm2_link_lib.
            * switches/check-all/run/fail/switches-check-all-run-fail.exp: Use
            new library abbreviations and gm2_link_lib.
            * switches/none/run/pass/gm2-none.exp: Use new library
            abbreviations and gm2_link_lib.
            * switches/optimization/run/pass/switches-optimization-run-pass.exp:
            Use new library abbreviations and gm2_link_lib.
            * switches/pic/run/pass/switches-pic-run-pass.exp: Use new library
            abbreviations and gm2_link_lib.
            * switches/pim3/run/pass/switches-pim3-run-pass.exp: Use new
            library abbreviations and gm2_link_lib.
            * switches/pim4/run/pass/switches-pim4-run-pass.exp: Use new
            library abbreviations and gm2_link_lib.
            * switches/whole-program/pass/run/switches-whole-program-pass-run.exp:
            Use new library abbreviations and gm2_link_lib.
            * types/run/pass/types-run-pass.exp: Use new library abbreviations
            and gm2_link_lib.
    
    gcc/testsuite/ChangeLog:
    
            * testsuite/lib/gm2-simple.exp: Use new library abbreviations and
            gm2_link_lib.
            * testsuite/lib/gm2-torture.exp: Use new library abbreviations and
            gm2_link_lib.
            * testsuite/lib/gm2.exp: Use new library abbreviations and
            gm2_link_lib.
    
    libgm2/ChangeLog:
    
            * libm2cor/KeyBoardLEDs.cc: Add ctor.  Change parameters for init
            and finish to int, char *[], char *[].
            * libm2cor/Makefile.am: Add rules to compile .cc files.
            * libm2iso/Makefile.am: Install m2rts.h.
            * libm2iso/RTco.cc: Corrected spacing.
            * libm2pim/Makefile.am (M2MODS): Remove COROUTINES.mod.
            * libm2pim/cgetopt.cc: Added ctor/dep/init/finish functions.
            Ensure all external functions are extern "C".
            * libm2pim/wrapc.c (_M2_wrap_ctor): Added.
    
    Signed-off-by: Gaius Mulley <gaius.mulley@southwales.ac.uk>

Diff:
---
 gcc/doc/gm2.texi                                   | 102 ++-
 gcc/gcc.cc                                         |   4 +-
 gcc/m2/Make-lang.in                                |   2 +-
 gcc/m2/bnf/m2-3.bnf                                |   8 +-
 gcc/m2/bnf/m2.bnf                                  |   9 +-
 gcc/m2/gm2-compiler/M2Base.mod                     |  16 +-
 gcc/m2/gm2-compiler/M2Batch.def                    |   4 +-
 gcc/m2/gm2-compiler/M2Batch.mod                    | 100 ++-
 gcc/m2/gm2-compiler/M2Code.mod                     |   4 +-
 gcc/m2/gm2-compiler/M2Comp.mod                     |  67 +-
 gcc/m2/gm2-compiler/M2GCCDeclare.mod               |  88 ++-
 gcc/m2/gm2-compiler/M2GenGCC.mod                   |   2 +-
 gcc/m2/gm2-compiler/M2Options.def                  |  49 +-
 gcc/m2/gm2-compiler/M2Options.mod                  |  72 +-
 gcc/m2/gm2-compiler/M2Quads.mod                    |  35 +-
 gcc/m2/gm2-compiler/M2Scaffold.def                 |   1 +
 gcc/m2/gm2-compiler/M2Scaffold.mod                 | 156 +++-
 gcc/m2/gm2-compiler/M2Students.mod                 |   6 +-
 gcc/m2/gm2-compiler/P0SymBuild.def                 |   2 +-
 gcc/m2/gm2-compiler/P0SymBuild.mod                 |  12 +-
 gcc/m2/gm2-compiler/SymbolTable.def                |  49 ++
 gcc/m2/gm2-compiler/SymbolTable.mod                | 187 ++++-
 gcc/m2/gm2-gcc/m2options.h                         |   5 +-
 gcc/m2/gm2-lang.cc                                 |  15 +-
 gcc/m2/gm2-libs-iso/COROUTINES.mod                 |  10 +-
 gcc/m2/gm2-libs-iso/RTentity.mod                   |  33 +-
 gcc/m2/gm2-libs-iso/Storage.mod                    |  44 +-
 gcc/m2/gm2-libs/COROUTINES.def                     |   2 +-
 gcc/m2/gm2-libs/M2Dependent.mod                    |   3 +
 gcc/m2/gm2-libs/Storage.mod                        |   8 +-
 gcc/m2/gm2spec.cc                                  | 857 +++++++++++++--------
 gcc/m2/lang.opt                                    | 320 ++++----
 gcc/m2/m2.flex                                     |  50 +-
 gcc/m2/tools-src/makeSystem                        |   2 +-
 .../calling-c-datatypes-unbounded-run-pass.exp     |   3 +-
 .../calling-c/datatypes/unbounded/run/pass/m.mod   |   2 +-
 .../gm2/complex/run/pass/complex-run-pass.exp      |   2 +
 .../pim/run/pass/coroutines-pim-run-pass.exp       |   1 -
 .../run/pass/examples-callingC-run-pass.exp        |   2 +-
 gcc/testsuite/gm2/exceptions/run/pass/cpp.cpp      |   1 +
 .../exceptions/run/pass/exceptions-run-pass.exp    |  10 +-
 gcc/testsuite/gm2/exceptions/run/pass/m2test.mod   |   2 +-
 gcc/testsuite/gm2/exceptions/run/pass/mycpp.cpp    |   4 +
 .../extensions/run/pass/extensions-run-pass.exp    |   2 +-
 .../gm2/imports/run/pass/imports-run-pass.exp      |   5 +-
 gcc/testsuite/gm2/iso/run/pass/iso-run-pass.exp    |   3 +-
 .../pass/link-externalscaffold-pass.exp            |   3 +-
 .../libarchive/pass/linking-libarchive-pass.exp    |   8 +-
 .../run/pass/pim-no-options-run-pass.exp           |   1 -
 .../run/pass/pim-options-optimize-run-pass.exp     |  91 +--
 gcc/testsuite/gm2/pim/run/fail/pim-run-fail.exp    |   1 -
 gcc/testsuite/gm2/pim/run/pass/pim-run-pass.exp    |   3 +-
 .../run/pass/pimcoroutines-run-pass.exp            |   2 -
 .../logitech/run/pass/pimlib-logitech-run-pass.exp |   3 +-
 .../gm2/pimlib/run/pass/pimlib-run-pass.exp        |   2 +-
 gcc/testsuite/gm2/sets/run/pass/sets-run-pass.exp  |   1 +
 .../run/fail/switches-check-all-run-fail.exp       |   2 +-
 .../gm2/switches/none/run/pass/gm2-none.exp        |   2 +-
 .../run/pass/switches-optimization-run-pass.exp    |   1 -
 .../pic/run/pass/switches-pic-run-pass.exp         |   3 +-
 .../pim3/run/pass/switches-pim3-run-pass.exp       |   1 -
 .../pim4/run/pass/switches-pim4-run-pass.exp       |   1 -
 .../pass/run/switches-whole-program-pass-run.exp   |   1 -
 .../gm2/types/run/pass/types-run-pass.exp          |   2 +-
 gcc/testsuite/lib/gm2-simple.exp                   |  11 +-
 gcc/testsuite/lib/gm2-torture.exp                  |  38 +-
 gcc/testsuite/lib/gm2.exp                          |  60 +-
 libgm2/libm2cor/KeyBoardLEDs.c                     | 139 ----
 libgm2/libm2cor/Makefile.am                        |   8 +-
 libgm2/libm2iso/Makefile.am                        |  10 +
 libgm2/libm2iso/RTco.cc                            |   7 +-
 libgm2/libm2pim/Makefile.am                        |   8 +-
 libgm2/libm2pim/{cgetopt.c => cgetopt.cc}          |  46 +-
 libgm2/libm2pim/wrapc.c                            |   5 +
 74 files changed, 1780 insertions(+), 1041 deletions(-)

diff --git a/gcc/doc/gm2.texi b/gcc/doc/gm2.texi
index 84791e9ba4a..5053b1957c5 100644
--- a/gcc/doc/gm2.texi
+++ b/gcc/doc/gm2.texi
@@ -719,11 +719,18 @@ embedded systems.  By default GNU Modula-2 uses the GCC pthread
 libraries to implement coroutines (see the SYSTEM implementation
 module).
 
-@item -fuselist=@file{filename}
+@item -fuse-list=@file{filename}
 if @samp{-fscaffold-static} is enabled then use the file
 @file{filename} for the initialization order of modules.  Whereas if
 @samp{-fscaffold-dynamic} is enabled then use this file to force
 linking of all module ctors.
+This option cannot be used if @samp{-fgen-module-list=} is enabled.
+
+@item -fgen-module-list=@file{filename}
+attempt to find all modules when linking and generate a module list.
+If the @file{filename} is @samp{-} then the contents are not written
+and only used to force the linking of all module ctors.
+This option cannot be used if @samp{-fuse-list=} is enabled.
 
 @item -fscaffold-static
 the option ensures that @samp{gm2} will generate a static scaffold
@@ -792,6 +799,8 @@ going to the first in the list.  It is not necessary to use -flibs=m2pim or
 -flibs=m2iso if you also specify -fpim, -fpim2, -fpim3, -fpim4 or
 -fiso.  Unless you are using -flibs=m2min you should include m2pim as
 the they provide the base modules which all other dialects utilize.
+The option @samp{-fno-libs=-} disables the @samp{gm2} driver from
+modifying the search and library paths.
 
 @item -fextended-opaque
 allows opaque types to be implemented as any type. This is a GNU
@@ -841,8 +850,8 @@ inform the user which non @code{VAR} unbounded parameters will be
 passed by reference.  This only produces output if the option
 @samp{-funbounded-by-reference} is also supplied on the command line.
 
-@item -Wstudents
-checks for bad programming style. This option is aimed at new users of
+@item -Wstyle
+checks for poor programming style.  This option is aimed at new users of
 Modula-2 in that it checks for situations which might cause confusion
 and thus mistakes.  It checks whether variables of the same name are
 declared in different scopes and whether variables look like keywords.
@@ -861,14 +870,12 @@ outside the end of this loop without being reset.
 @item -Wpedantic-param-names
 procedure parameter names are checked in the definition module
 against their implementation module counterpart.  This is not
-necessary in ISO or PIM versions of Modula-2, but it can be
-extremely useful, as long as code is intentionally
-written in this way.
+necessary in ISO or PIM versions of Modula-2.
 
 @item -Wpedantic-cast
 warns if the ISO system function is used and if the size of
-the variable is different from that of the type. This is legal
-in ISO Modula-2, however it can be dangerous. Some users may prefer
+the variable is different from that of the type.  This is legal
+in ISO Modula-2, however it can be dangerous.  Some users may prefer
 to use @code{VAL} instead in these situations and use @code{CAST}
 exclusively for changes in type on objects which have the same size.
 
@@ -1973,6 +1980,85 @@ and @code{f} are type compatible and will produce runtime checking
 code to test whether the address range of their respective contents
 intersect.
 
+@node Linking, Building a shared library, Unbounded by reference, Using
+
+This section describes the linking related options.  There are three
+linking strategies available which are dynamic scaffold, static
+scaffold and user defined.  The dynamic scaffold is enabled by default
+and each module will register itself to the runtime @samp{M2RTS} via
+a constructor.  The static scaffold mechanism will invoke each modules
+@samp{_init} and @samp{_finish} function in turn via a sequence of
+calls from within @samp{main}.  Lastly the user defined strategy
+can be implemented by turning off the dynamic and static options via
+@samp{-fno-scaffold-dynamic} and @samp{-fno-scaffold-static}.
+
+In the simple test below:
+
+@example
+$ gm2 hello.mod
+@end example
+
+the driver will add the options @samp{-fscaffold-dynamic} and
+@samp{-fgen-module-list=-} which generate a list of application
+modules and also creates the @samp{main} function with calls to
+@samp{M2RTS}.  It can be useful to add the option @samp{-fsources}
+which displays the source files as they are parsed and summarizes
+whether the source file is required for compilation or linking.
+
+If you wish to split the above command line into a compile and link
+then you could use these steps:
+
+@example
+$ gm2 -c -fscaffold-main hello.mod
+$ gm2 hello.o
+@end example
+
+The @samp{-fscaffold-main} informs the compiler to generate the
+@samp{main} function and scaffold.  You can enable the environment
+variable @samp{GCC_M2LINK_RTFLAG} to trace the construction and
+destruction of the application.  The values for
+@samp{GCC_M2LINK_RTFLAG} are shown in the table below:
+
+@example
+value   | meaning
+=================
+all     | turn on all flags below
+module  | trace modules as they register themselves
+pre     | generate module list prior to dependency resolution
+dep     | trace module dependency resolution
+post    | generate module list after dependency resolution
+force   | generate a module list after dependency and forced
+        | ordering is complete
+@end example
+
+The values can be combined using a comma separated list.
+
+One of the advantages of the dynamic scaffold is that the driver
+behaves in a similar way to the other front end drivers.
+For example consider a small project consisting of 4 definition
+implementation modules (@samp{a.def}, @samp{a.mod}, @samp{b.def},
+@samp{b.mod}, @samp{c.def}, @samp{c.mod}, @samp{d.def}, @samp{d.mod})
+and a program module @samp{program.mod}.
+
+To link this project we could:
+
+@example
+$ gm2 -g -c a.mod
+$ gm2 -g -c b.mod
+$ gm2 -g -c c.mod
+$ gm2 -g -c d.mod
+$ gm2 -g program.mod a.o b.o c.o d.o
+@end example
+
+The module initialization sequence is defined by the ISO standard to
+follow the import graph traversal.  The initialization order is the
+order in which the corresponding separate modules finish the
+processing of their import lists.
+
+However, if required, you can override this using
+@samp{-fruntime-modules=a,b,c,d} for example which forces the
+initialization sequence to @samp{a}, @samp{b}, @samp{c} and @samp{d}.
+
 @node Building a shared library, Interface for Python, Unbounded by reference, Using
 @section Building a shared library
 
diff --git a/gcc/gcc.cc b/gcc/gcc.cc
index a15f811ed61..63acae5bc3b 100644
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -4801,7 +4801,9 @@ print_option (const char *desc, unsigned int i,
           in_decoded_options[i].orig_option_with_args_text);
   /* On some hosts value is declared as a long long int.  */
   printf (" value [%ld]", (long int)in_decoded_options[i].value);
-  printf (" error [%d]\n", in_decoded_options[i].errors);
+  printf (" error [%d]", in_decoded_options[i].errors);
+  printf (" canonical_option_num_elements [%ld]\n",
+	  in_decoded_options[i].canonical_option_num_elements);
 }
 
 /* print_options display all options with a leading string desc.  */
diff --git a/gcc/m2/Make-lang.in b/gcc/m2/Make-lang.in
index 616f7917be2..e7e7215f24b 100644
--- a/gcc/m2/Make-lang.in
+++ b/gcc/m2/Make-lang.in
@@ -1105,7 +1105,7 @@ m2/gm2-compiler-boot/cflex.o: m2/gm2-compiler/cflex.c m2/gm2-compiler-boot/$(SRC
           $(GM2GCC) $(INCLUDES) -I$(srcdir)/m2 \
           -Im2 -Im2/gm2-compiler-boot -Im2/gm2-libs-boot $< -o $@
 
-m2/gm2-compiler/m2flex.c: $(srcdir)/m2/m2.flex $(TIMEVAR_H)
+m2/gm2-compiler/m2flex.c: $(srcdir)/m2/m2.flex $(TIMEVAR_H) insn-attr-common.h
 	flex -t $< | sed -e 's/ malloc/ xmalloc/' | sed -e 's/ realloc/ xrealloc/' > $@
 
 m2/gm2-compiler/cflex.c: $(srcdir)/m2/c.flex
diff --git a/gcc/m2/bnf/m2-3.bnf b/gcc/m2/bnf/m2-3.bnf
index ae93beecc8f..5cb5e286a02 100644
--- a/gcc/m2/bnf/m2-3.bnf
+++ b/gcc/m2/bnf/m2-3.bnf
@@ -575,13 +575,15 @@ FileUnit :=                                                                % Pus
 
 ProgramModule := "MODULE"                                                  % M2Error.DefaultProgramModule %
                                                                            % PushAutoOn %
+                                                                           % VAR tokno: CARDINAL ; %
+                                                                           % tokno := GetTokenNo () %
                   Ident                                                    % P3StartBuildProgModule %
                                                                            % StartBuildModFile %
                                                                            % BuildModuleStart %
                                                                            % PushAutoOff %
                   [ Priority
                   ]
-                  ";"                                                      % BuildScaffold (GetTokenNo () -1,
+                  ";"                                                      % BuildScaffold (tokno,
                                                                                             GetCurrentModule ()) %
                   { Import }
                   Block                                                    % PushAutoOn %
@@ -592,12 +594,14 @@ ProgramModule := "MODULE"                                                  % M2E
 
 ImplementationModule := "IMPLEMENTATION"                                   % M2Error.DefaultImplementationModule %
                                          "MODULE"                          % PushAutoOn %
+                                                                           % VAR tokno: CARDINAL ; %
+                                                                           % tokno := GetTokenNo () %
                          Ident                                             % StartBuildModFile %
                                                                            % P3StartBuildImpModule %
                                                                            % BuildModuleStart %
                                                                            % PushAutoOff %
                          [ Priority
-                         ] ";"                                             % BuildScaffold (GetTokenNo () -1,
+                         ] ";"                                             % BuildScaffold (tokno,
                                                                                             GetCurrentModule ()) %
                          { Import }
                          Block                                             % PushAutoOn %
diff --git a/gcc/m2/bnf/m2.bnf b/gcc/m2/bnf/m2.bnf
index a00f7589b9a..8697755a8e3 100644
--- a/gcc/m2/bnf/m2.bnf
+++ b/gcc/m2/bnf/m2.bnf
@@ -886,9 +886,12 @@ Import :=  "FROM" Ident "IMPORT" IdentList ";" |
                                                                              (* determines whether Ident or Module *) %
             IdentList ";" =:
 
-DefinitionModule := "DEFINITION"                                           % M2Error.DefaultDefinitionModule %
-                                 "MODULE" [ "FOR"  string ]                % PushAutoOn %
-                    Ident                                                  % RegisterDefinitionModule %
+DefinitionModule :=                                                        % VAR forC: BOOLEAN ; %
+                                                                           % forC := FALSE %
+                    "DEFINITION"                                           % M2Error.DefaultDefinitionModule %
+                                 "MODULE" [ "FOR"  string                  % forC := TRUE %
+                                                          ]                % PushAutoOn %
+                    Ident                                                  % RegisterDefinitionModule (forC) %
                     ";"
                     { Import                                               % RegisterImports %
                              }                                             % PushAutoOff %
diff --git a/gcc/m2/gm2-compiler/M2Base.mod b/gcc/m2/gm2-compiler/M2Base.mod
index e4610447146..7e7dd01724f 100644
--- a/gcc/m2/gm2-compiler/M2Base.mod
+++ b/gcc/m2/gm2-compiler/M2Base.mod
@@ -56,6 +56,7 @@ FROM SymbolTable IMPORT ModeOfAddr,
                         MakeTemporary,
                         MakeVar, PutVar,
                         MakeSubrange, PutSubrange, IsSubrange,
+                        PutModuleBuiltin,
                         IsEnumeration, IsSet, IsPointer, IsType, IsUnknown,
                         IsHiddenType, IsProcType,
                         GetType, GetLowestType, GetDeclaredMod, SkipType,
@@ -186,7 +187,7 @@ VAR
 BEGIN
    IF DebugBuiltins
    THEN
-      (* we will need to parse this module as functions alloca/memcpy will be used *)
+      (* We will need to parse this module as functions alloca/memcpy will be used.  *)
       builtins := MakeDefinitionSource (BuiltinTokenNo, MakeKey ('Builtins')) ;
       IF builtins = NulSym
       THEN
@@ -203,17 +204,18 @@ END InitBuiltins ;
 
 PROCEDURE InitBase (location: location_t; VAR sym: CARDINAL) ;
 BEGIN
-   sym := MakeModule(BuiltinTokenNo, MakeKey('_BaseTypes')) ;
-   SetCurrentModule(sym) ;
-   StartScope(sym) ;
+   sym := MakeModule (BuiltinTokenNo, MakeKey ('_BaseTypes')) ;
+   PutModuleBuiltin (sym, TRUE) ;
+   SetCurrentModule (sym) ;
+   StartScope (sym) ;
 
-   InitBaseSimpleTypes(location) ;
+   InitBaseSimpleTypes (location) ;
 
-   (* Initialise the SYSTEM module before we ADDRESS.  *)
+   (* Initialize the SYSTEM module before we ADDRESS.  *)
    InitSystem ;
 
    MakeBitset ;  (* We do this after SYSTEM has been created as BITSET
-                    is dependant upon WORD *)
+                    is dependant upon WORD.  *)
 
    InitBaseConstants ;
    InitBaseFunctions ;
diff --git a/gcc/m2/gm2-compiler/M2Batch.def b/gcc/m2/gm2-compiler/M2Batch.def
index be11532ad54..ff4ae85e3d4 100644
--- a/gcc/m2/gm2-compiler/M2Batch.def
+++ b/gcc/m2/gm2-compiler/M2Batch.def
@@ -93,11 +93,11 @@ PROCEDURE GetSource () : CARDINAL ;
 
 (*
    GetModuleNo - returns with symbol number of the module which was
-                 the n th module to be read in Pass 1.
+                 the nth module to be read in Pass 1.
                  The modules are numbered from 1..n
 *)
 
-PROCEDURE GetModuleNo (n: CARDINAL) : CARDINAL ;
+PROCEDURE GetModuleNo (nth: CARDINAL) : CARDINAL ;
 
 
 (*
diff --git a/gcc/m2/gm2-compiler/M2Batch.mod b/gcc/m2/gm2-compiler/M2Batch.mod
index 35b65040003..b0168a1a921 100644
--- a/gcc/m2/gm2-compiler/M2Batch.mod
+++ b/gcc/m2/gm2-compiler/M2Batch.mod
@@ -37,8 +37,7 @@ FROM M2Pass IMPORT IsPass1, IsPass2, IsPass3, IsPassC ;
 
 
 TYPE
-   Module = POINTER TO module ;
-   module =            RECORD
+   Module = POINTER TO RECORD
                           SymNo  : CARDINAL ;
                           Key    : Name ;
                           DefFile,
@@ -46,7 +45,7 @@ TYPE
                        END ;
 
 VAR
-   DoneQueue   : Index ;
+   SeenList    : Index ;
    PendingQueue: List ;
 
 
@@ -119,7 +118,7 @@ BEGIN
    Sym := Get (n) ;
    IF Sym = NulSym
    THEN
-      Assert ((NOT IsPass1()) AND (NOT IsPass2()) AND (NOT IsPass3()) AND (NOT IsPassC())) ;
+      Assert ((NOT IsPass1 ()) AND (NOT IsPass2 ()) AND (NOT IsPass3 ()) AND (NOT IsPassC ())) ;
       (* Neither been compiled or on the Pending Queue *)
       Sym := MakeDefImp (tok, n) ;
       Put (Sym, n) ;
@@ -144,14 +143,14 @@ END GetSource ;
    GetModuleNo - returns with symbol number of the nth module read during Pass 1.
 *)
 
-PROCEDURE GetModuleNo (n: CARDINAL) : CARDINAL ;
+PROCEDURE GetModuleNo (nth: CARDINAL) : CARDINAL ;
 VAR
    m: Module ;
 BEGIN
-   Assert (n#0) ;
-   IF InBounds (DoneQueue, n)
+   Assert (nth#0) ;
+   IF InBounds (SeenList, nth)
    THEN
-      m := GetIndice (DoneQueue, n) ;
+      m := GetIndice (SeenList, nth) ;
       RETURN m^.SymNo
    ELSE
       RETURN NulSym
@@ -160,7 +159,7 @@ END GetModuleNo ;
 
 
 (*
-   IsModuleKnown - returns TRUE if the Name, n, matches a module.
+   IsModuleKnown - returns TRUE if the Name n matches a module.
 *)
 
 PROCEDURE IsModuleKnown (n: Name) : BOOLEAN ;
@@ -170,7 +169,7 @@ END IsModuleKnown ;
 
 
 (*
-   Get - returns the module symbol matching name, n.
+   Get - returns the module symbol matching name n.
 *)
 
 PROCEDURE Get (n: Name) : CARDINAL ;
@@ -179,9 +178,9 @@ VAR
    m    : Module ;
 BEGIN
    i := 1 ;
-   no := HighIndice (DoneQueue) ;
+   no := HighIndice (SeenList) ;
    WHILE i <= no DO
-      m := GetIndice (DoneQueue, i) ;
+      m := GetIndice (SeenList, i) ;
       WITH m^ DO
          IF Key = n
          THEN
@@ -200,7 +199,7 @@ VAR
    m: Module ;
 BEGIN
    NEW (m) ;
-   IncludeIndiceIntoIndex (DoneQueue, m) ;
+   IncludeIndiceIntoIndex (SeenList, m) ;
    WITH m^ DO
       SymNo   := Sym ;
       Key     := n ;
@@ -234,7 +233,7 @@ END Pop ;
 
 
 (*
-   DisplayModules - a debugging routine to textually emit the names of modules in the DoneQ.
+   DisplayModules - a debugging routine to textually emit the names of modules in the SeenList.
 *)
 
 PROCEDURE DisplayModules ;
@@ -243,13 +242,13 @@ VAR
    n, i: CARDINAL ;
 BEGIN
    i := 1 ;
-   n := HighIndice(DoneQueue) ;
+   n := HighIndice (SeenList) ;
    WHILE i<=n DO
-      m := GetIndice(DoneQueue, i) ;
+      m := GetIndice (SeenList, i) ;
       WITH m^ DO
-         printf2('Module %a %d\n', Key, i)
+         printf2 ('Module %a %d\n', Key, i)
       END ;
-      INC(i)
+      INC (i)
    END
 END DisplayModules ;
 
@@ -265,16 +264,16 @@ VAR
    m    : Module ;
 BEGIN
    i := 1 ;
-   no := HighIndice(DoneQueue) ;
-   WHILE i<=no DO
-      m := GetIndice(DoneQueue, i) ;
+   no := HighIndice (SeenList) ;
+   WHILE i <= no DO
+      m := GetIndice (SeenList, i) ;
       WITH m^ DO
-         IF SymNo=Sym
+         IF SymNo = Sym
          THEN
             DefFile := filename ;
-            RETURN( filename )
+            RETURN filename
          ELSE
-            INC(i)
+            INC (i)
          END
       END
    END ;
@@ -293,19 +292,19 @@ VAR
    m    : Module ;
 BEGIN
    i := 1 ;
-   no := HighIndice(DoneQueue) ;
-   WHILE i<=no DO
-      m := GetIndice(DoneQueue, i) ;
+   no := HighIndice (SeenList) ;
+   WHILE i <= no DO
+      m := GetIndice (SeenList, i) ;
       WITH m^ DO
-         IF SymNo=Sym
+         IF SymNo = Sym
          THEN
-            RETURN( DefFile )
+            RETURN DefFile
          ELSE
-            INC(i)
+            INC (i)
          END
       END
    END ;
-   RETURN( NIL )
+   RETURN NIL
 END GetDefinitionModuleFile ;
 
 
@@ -320,16 +319,16 @@ VAR
    m    : Module ;
 BEGIN
    i := 1 ;
-   no := HighIndice(DoneQueue) ;
+   no := HighIndice (SeenList) ;
    WHILE i<=no DO
-      m := GetIndice(DoneQueue, i) ;
+      m := GetIndice (SeenList, i) ;
       WITH m^ DO
-         IF SymNo=Sym
+         IF SymNo = Sym
          THEN
             ModFile := filename ;
-            RETURN( filename )
+            RETURN filename
          ELSE
-            INC(i)
+            INC (i)
          END
       END
    END ;
@@ -348,25 +347,24 @@ VAR
    m    : Module ;
 BEGIN
    i := 1 ;
-   no := HighIndice(DoneQueue) ;
-   WHILE i<=no DO
-      m := GetIndice(DoneQueue, i) ;
+   no := HighIndice (SeenList) ;
+   WHILE i <= no DO
+      m := GetIndice (SeenList, i) ;
       WITH m^ DO
-         IF SymNo=Sym
+         IF SymNo = Sym
          THEN
-            RETURN( ModFile )
+            RETURN ModFile
          ELSE
-            INC(i)
+            INC (i)
          END
       END
    END ;
-   RETURN( NIL )
+   RETURN NIL
 END GetModuleFile ;
 
 
 (*
-   ForeachSourceModuleDo - call each procedure, p, for which there is a known
-                           source file.
+   ForeachSourceModuleDo - for each source file call procedure, p.
 *)
 
 PROCEDURE ForeachSourceModuleDo (p: DoProcedure) ;
@@ -375,16 +373,16 @@ VAR
    m    : Module ;
 BEGIN
    i := 1 ;
-   no := HighIndice(DoneQueue) ;
+   no := HighIndice (SeenList) ;
    WHILE i<=no DO
-      m := GetIndice(DoneQueue, i) ;
+      m := GetIndice (SeenList, i) ;
       WITH m^ DO
-         IF ModFile#NIL
+         IF ModFile # NIL
          THEN
-            p(SymNo)
+            p (SymNo)
          END
       END ;
-      INC(i)
+      INC (i)
    END
 END ForeachSourceModuleDo ;
 
@@ -467,5 +465,5 @@ END LookupOuterModule ;
 
 BEGIN
    InitList (PendingQueue) ;
-   DoneQueue := InitIndex (1)
+   SeenList := InitIndex (1)
 END M2Batch.
diff --git a/gcc/m2/gm2-compiler/M2Code.mod b/gcc/m2/gm2-compiler/M2Code.mod
index 345d616dedd..1d0c3304d7f 100644
--- a/gcc/m2/gm2-compiler/M2Code.mod
+++ b/gcc/m2/gm2-compiler/M2Code.mod
@@ -25,7 +25,7 @@ IMPLEMENTATION MODULE M2Code ;
 FROM SYSTEM IMPORT WORD ;
 FROM M2Options IMPORT Statistics, DisplayQuadruples, OptimizeUncalledProcedures,
                       (* OptimizeDynamic, *) OptimizeCommonSubExpressions,
-                      StudentChecking, Optimizing, WholeProgram ;
+                      StyleChecking, Optimizing, WholeProgram ;
 
 FROM M2Error IMPORT InternalError ;
 FROM M2Students IMPORT StudentVariableCheck ;
@@ -243,7 +243,7 @@ BEGIN
    (* now is a suitable time to check for student errors as *)
    (* we know all the front end symbols must be resolved.   *)
 
-   IF StudentChecking
+   IF StyleChecking
    THEN
       StudentVariableCheck
    END ;
diff --git a/gcc/m2/gm2-compiler/M2Comp.mod b/gcc/m2/gm2-compiler/M2Comp.mod
index 09adf680617..c3fc02dc541 100644
--- a/gcc/m2/gm2-compiler/M2Comp.mod
+++ b/gcc/m2/gm2-compiler/M2Comp.mod
@@ -22,7 +22,7 @@ along with GNU Modula-2; see the file COPYING3.  If not see
 IMPLEMENTATION MODULE M2Comp ;
 
 
-FROM M2Options IMPORT Statistics, Quiet, WholeProgram, ExtendedOpaque ;
+FROM M2Options IMPORT Statistics, Quiet, WholeProgram, ExtendedOpaque, GenModuleList ;
 
 FROM M2Pass IMPORT SetPassToPass0, SetPassToPass1, SetPassToPass2, SetPassToPassC, SetPassToPass3,
                    SetPassToNoPass, SetPassToPassHidden ;
@@ -58,7 +58,7 @@ FROM M2Batch IMPORT GetSource, GetModuleNo, GetDefinitionModuleFile, GetModuleFi
 FROM SymbolTable IMPORT GetSymName, IsDefImp, NulSym,
                         IsHiddenTypeDeclared, GetFirstUsed, GetMainModule, SetMainModule,
                         ResolveConstructorTypes, SanityCheckConstants, IsDefinitionForC,
-                        IsBuiltinInModule ;
+                        IsBuiltinInModule, PutModLink, IsDefLink, IsModLink ;
 
 FROM FIO IMPORT StdErr ;
 FROM NameKey IMPORT Name, GetKey, KeyToCharStar, makekey ;
@@ -119,7 +119,7 @@ END NeedToParseImplementation ;
 
 
 (*
-   Compile - compile file, s, using a 6 pass technique.
+   Compile - compile file, s, using a 5 pass technique.
 *)
 
 PROCEDURE Compile (s: String) ;
@@ -242,7 +242,6 @@ BEGIN
       THEN
          IF FindSourceDefFile(SymName, FileName)
          THEN
-            qprintf2('   Module %-20s : %s\n', SymName, FileName) ;
             ModuleType := Definition ;
             IF OpenSource(AssociateDefinition(PreprocessModule(FileName), Sym))
             THEN
@@ -252,6 +251,16 @@ BEGIN
                   CloseSource ;
                   RETURN
                END ;
+               qprintf2 ('   Module %-20s : %s', SymName, FileName) ;
+               IF IsDefinitionForC (Sym)
+               THEN
+                  qprintf0 (' (for C)')
+               END ;
+               IF IsDefLink (Sym)
+               THEN
+                  qprintf0 (' (linking)')
+               END ;
+               qprintf0 ('\n') ;
                CloseSource
             ELSE
                MetaErrorString1 (Sprintf1 (InitString ('file {%%1EUF%s} containing module {%%1a} cannot be found'), FileName), Sym) ;
@@ -276,26 +285,32 @@ BEGIN
          THEN
             FileName := Dup(s)
          ELSE
-            IF FindSourceModFile(SymName, FileName)
+            IF FindSourceModFile (SymName, FileName)
             THEN
             END
          END ;
          IF FileName#NIL
          THEN
-            qprintf2('   Module %-20s : %s\n', SymName, FileName) ;
-            IF OpenSource(AssociateModule(PreprocessModule(FileName), Sym))
+            IF OpenSource (AssociateModule (PreprocessModule (FileName), Sym))
             THEN
                IF NOT P0SyntaxCheck.CompilationUnit()
                THEN
-                  WriteFormat0('compilation failed') ;
+                  WriteFormat0 ('compilation failed') ;
                   CloseSource ;
                   RETURN
                END ;
+               qprintf2 ('   Module %-20s : %s', SymName, FileName) ;
+               IF IsModLink (Sym)
+               THEN
+                  qprintf0 (' (linking)')
+               END ;
+               qprintf0 ('\n') ;
                CloseSource
             ELSE
-               (* quite legitimate to implement a module in C (and pretend it was a M2 implementation
-                  providing that it is not the main program module and the definition module does not
-                 imply that the implementation defines hidden types.  *)
+               (* It is quite legitimate to implement a module in C (and pretend it was a M2
+                  implementation) providing that it is not the main program module and the
+                  definition module do not declare a hidden type when -fextended-opaque
+                  is used.  *)
                IF (NOT WholeProgram) OR (Sym=Main) OR IsHiddenTypeDeclared(Sym)
                THEN
                   MetaErrorString1 (Sprintf1 (InitString ('file {%%1EUF%s} containing module {%%1a} cannot be found'), FileName), Sym) ;
@@ -304,11 +319,33 @@ BEGIN
                END
             END
          END
+      ELSIF GenModuleList
+      THEN
+         IF NOT IsDefinitionForC (Sym)
+         THEN
+            (* The implementation is only useful if -fgen-module-list= is
+               used and we do not insist upon it.  *)
+            IF FindSourceModFile (SymName, FileName)
+            THEN
+               qprintf2 ('   Module %-20s : %s (linking)\n', SymName, FileName) ;
+               IF OpenSource (AssociateModule (PreprocessModule (FileName), Sym))
+               THEN
+                  PutModLink (Sym, TRUE) ;   (* This source is only used to determine link time info.  *)
+                  IF NOT P0SyntaxCheck.CompilationUnit ()
+                  THEN
+                     WriteFormat0 ('compilation failed') ;
+                     CloseSource ;
+                     RETURN
+                  END ;
+                  CloseSource
+               END
+            END
+         END
       END ;
-      SymName := KillString(SymName) ;
-      FileName := KillString(FileName) ;
-      INC(i) ;
-      Sym := GetModuleNo(i)
+      SymName := KillString (SymName) ;
+      FileName := KillString (FileName) ;
+      INC (i) ;
+      Sym := GetModuleNo (i)
    END ;
    SetPassToNoPass
 END DoPass0 ;
diff --git a/gcc/m2/gm2-compiler/M2GCCDeclare.mod b/gcc/m2/gm2-compiler/M2GCCDeclare.mod
index 799a704533f..bcef0f8be56 100644
--- a/gcc/m2/gm2-compiler/M2GCCDeclare.mod
+++ b/gcc/m2/gm2-compiler/M2GCCDeclare.mod
@@ -96,7 +96,7 @@ FROM SymbolTable IMPORT NulSym,
                         IsGnuAsm, IsGnuAsmVolatile, IsObject, IsTuple,
                         IsError, IsHiddenType,
                         IsDefinitionForC, IsHiddenTypeDeclared,
-                        IsComponent,
+                        IsComponent, IsPublic, IsExtern, IsCtor,
       	       	     	GetMainModule, GetBaseModule, GetModule, GetLocalSym,
                         PutModuleFinallyFunction,
                         GetProcedureScope, GetProcedureQuads,
@@ -2408,6 +2408,7 @@ END DeclareProcedureToGccWholeProgram ;
 
 PROCEDURE DeclareProcedureToGccSeparateProgram (Sym: CARDINAL) ;
 VAR
+   returnType,
    GccParam  : Tree ;
    scope,
    Son,
@@ -2420,10 +2421,11 @@ BEGIN
    tok := GetDeclaredMod(Sym) ;
    IF (NOT GccKnowsAbout(Sym)) AND (NOT IsPseudoProcFunc(Sym)) AND
       (IsEffectivelyImported(GetMainModule(), Sym) OR
-       (GetModuleWhereDeclared(Sym)=GetMainModule()) OR
-       IsNeededAtRunTime(tok, Sym) OR
-       IsImported(GetBaseModule(), Sym) OR
-       IsExported(GetModuleWhereDeclared(Sym), Sym))
+       (GetModuleWhereDeclared (Sym) = GetMainModule()) OR
+       IsNeededAtRunTime (tok, Sym) OR
+       IsImported (GetBaseModule (), Sym) OR
+       IsExported(GetModuleWhereDeclared (Sym), Sym) OR
+       IsExtern (Sym))
    THEN
       Assert(PushParametersLeftToRight) ;
       BuildStartFunctionDeclaration(UsesVarArgs(Sym)) ;
@@ -2460,20 +2462,17 @@ BEGIN
       PushBinding(scope) ;
       IF GetSType(Sym)=NulSym
       THEN
-         PreAddModGcc(Sym, BuildEndFunctionDeclaration(begin, end,
-                                                       KeyToCharStar(GetFullSymName(Sym)),
-                                                       NIL,
-                                                       IsExternal(Sym),
-                                                       IsProcedureGccNested(Sym),
-                                                       IsExported(GetModuleWhereDeclared(Sym), Sym)))
+         returnType := NIL
       ELSE
-         PreAddModGcc(Sym, BuildEndFunctionDeclaration(begin, end,
-                                                       KeyToCharStar(GetFullSymName(Sym)),
-                                                       Mod2Gcc(GetSType(Sym)),
-                                                       IsExternal(Sym),
-                                                       IsProcedureGccNested(Sym),
-                                                       IsExported(GetModuleWhereDeclared(Sym), Sym)))
+         returnType := Mod2Gcc(GetSType(Sym))
       END ;
+      PreAddModGcc (Sym, BuildEndFunctionDeclaration (begin, end,
+                                                      KeyToCharStar (GetFullSymName (Sym)),
+                                                      returnType,
+                                                      IsExternal (Sym),  (* Extern relative to the main module.  *)
+                                                      IsProcedureGccNested (Sym),
+                                                      (* Exported from the module where it was declared.  *)
+                                                      IsExported (GetModuleWhereDeclared (Sym), Sym) OR IsExtern (Sym))) ;
       PopBinding(scope) ;
       WatchRemoveList(Sym, todolist) ;
       WatchIncludeList(Sym, fullydeclared)
@@ -3709,15 +3708,48 @@ END PrintDecl ;
 
 PROCEDURE PrintScope (sym: CARDINAL) ;
 VAR
-   name: Name ;
-   line: CARDINAL ;
+   name : Name ;
+   scope,
+   line : CARDINAL ;
 BEGIN
    line := TokenToLineNo (GetDeclaredMod (sym), 0) ;
-   name := GetSymName (GetScope (sym)) ;
-   printf2 ('scope %a:%d\n', name, line)
+   scope := GetScope (sym) ;
+   name := GetSymName (scope) ;
+   printf3 (' scope %a:%d %d', name, line, scope)
 END PrintScope ;
 
 
+(*
+   PrintProcedure -
+*)
+
+PROCEDURE PrintProcedure (sym: CARDINAL) ;
+VAR
+   n: Name ;
+BEGIN
+   n := GetSymName (sym) ;
+   printf2('sym %d IsProcedure (%a)', sym, n);
+   IF IsProcedureReachable(sym)
+   THEN
+      printf0(' IsProcedureReachable')
+   END ;
+   PrintScope (sym) ;
+   IF IsExtern (sym)
+   THEN
+      printf0 (' extern')
+   END ;
+   IF IsPublic (sym)
+   THEN
+      printf0 (' public')
+   END ;
+   IF IsCtor (sym)
+   THEN
+      printf0 (' ctor')
+   END ;
+   PrintDeclared(sym)
+END PrintProcedure ;
+
+
 (*
    PrintVerboseFromList - prints the, i, th element in the list, l.
 *)
@@ -3727,8 +3759,8 @@ VAR
    type,
    low,
    high,
-   sym  : CARDINAL ;
-   n, n2: Name ;
+   sym   : CARDINAL ;
+   n, n2 : Name ;
 BEGIN
    sym := GetItemFromList(l, i) ;
    n := GetSymName(sym) ;
@@ -3745,7 +3777,8 @@ BEGIN
       IF IsHiddenTypeDeclared(sym)
       THEN
          printf0(' IsHiddenTypeDeclared')
-      END
+      END ;
+      ForeachProcedureDo (sym, PrintProcedure)
    ELSIF IsModule(sym)
    THEN
       printf2('sym %d IsModule (%a)', sym, n) ;
@@ -3766,12 +3799,7 @@ BEGIN
       PrintAlignment(sym)
    ELSIF IsProcedure(sym)
    THEN
-      printf2('sym %d IsProcedure (%a)', sym, n);
-      IF IsProcedureReachable(sym)
-      THEN
-         printf0(' and IsProcedureReachable')
-      END ;
-      PrintDeclared(sym)
+      PrintProcedure (sym)
    ELSIF IsParameter(sym)
    THEN
       printf2('sym %d IsParameter (%a)', sym, n) ;
diff --git a/gcc/m2/gm2-compiler/M2GenGCC.mod b/gcc/m2/gm2-compiler/M2GenGCC.mod
index fd7d7fb75bb..44f83ddd21e 100644
--- a/gcc/m2/gm2-compiler/M2GenGCC.mod
+++ b/gcc/m2/gm2-compiler/M2GenGCC.mod
@@ -1160,7 +1160,7 @@ BEGIN
             (ScaffoldDynamic OR ScaffoldStatic OR ScaffoldMain) AND
             (moduleSym = GetMainModule ())
          THEN
-            qprintf0 ("generating scaffold m2link information\n");
+            qprintf0 ("        generating scaffold m2link information\n");
             DeclareM2linkGlobals (location, VAL (INTEGER, ScaffoldStatic), GetRuntimeModuleOverride ())
          END
       END
diff --git a/gcc/m2/gm2-compiler/M2Options.def b/gcc/m2/gm2-compiler/M2Options.def
index ab16cf64c38..0a60b7194a3 100644
--- a/gcc/m2/gm2-compiler/M2Options.def
+++ b/gcc/m2/gm2-compiler/M2Options.def
@@ -40,7 +40,7 @@ EXPORT QUALIFIED SetReturnCheck, SetNilCheck, SetCaseCheck,
                  SetUnboundedByReference,
                  SetSearchPath, SetISO, SetPIM, SetPIM2, SetPIM3, SetPIM4,
                  SetPositiveModFloor, SetCompilerDebugging, SetExceptions,
-                 SetStudents, SetPedantic, SetPedanticParamNames, SetPedanticCast,
+                 SetStyle, SetPedantic, SetPedanticParamNames, SetPedanticCast,
                  SetExtendedOpaque, SetXCode, SetQuadDebugging, SetSources,
                  SetDumpSystemExports,
                  SetSwig, DisplayVersion, SetOptimizing, SetForcedLocation,
@@ -52,7 +52,7 @@ EXPORT QUALIFIED SetReturnCheck, SetNilCheck, SetCaseCheck,
 		 SetWholeValueCheck, GetWholeValueCheck,
                  SetLowerCaseKeywords,
                  SetIndex, SetRange, SetWholeDiv, SetStrictTypeChecking,
-                 Setc, Getc, SetUselist, GetUselist,
+                 Setc, Getc, SetUselist, GetUselist, GetUselisrFilename,
 
                  Iso, Pim, Pim2, Pim3, Pim4,
                  cflag,
@@ -62,7 +62,7 @@ EXPORT QUALIFIED SetReturnCheck, SetNilCheck, SetCaseCheck,
                  Profiling, Coding, Optimizing,
                  OptimizeBasicBlock, OptimizeUncalledProcedures,
                  OptimizeCommonSubExpressions,
-                 StudentChecking, WholeProgram,
+                 StyleChecking, WholeProgram,
                  NilChecking,
                  WholeDivChecking, WholeValueChecking,
                  IndexChecking, RangeChecking,
@@ -81,14 +81,15 @@ EXPORT QUALIFIED SetReturnCheck, SetNilCheck, SetCaseCheck,
                  OverrideLocation, FinaliseOptions,
                  DebugBuiltins, setdefextension, setmodextension,
                  SetStatistics, SetWall, SetSaveTemps, SetSaveTempsDir,
-                 SaveTemps,
+                 SaveTemps, GenModuleList,
                  CppProg, CppArg, CppCommandLine, CppRemember,
 		 SetDebugFunctionLineNumbers, DebugFunctionLineNumbers,
 		 SetGenerateStatementNote, GenerateStatementNote,
                  ScaffoldDynamic, ScaffoldStatic,
                  SetScaffoldDynamic, SetScaffoldStatic,
                  SetScaffoldMain, ScaffoldMain,
-                 SetRuntimeModuleOverride, GetRuntimeModuleOverride ;
+                 SetRuntimeModuleOverride, GetRuntimeModuleOverride,
+                 SetGenModuleList, GetGenModuleFilename ;
 
 
 VAR
@@ -109,7 +110,7 @@ VAR
    PedanticParamNames,           (* -Wpedantic-param-names                   *)
    PedanticCast,                 (* -Wpedantic-cast warns if sizes differ.   *)
    Statistics,                   (* -fstatistics information about code      *)
-   StudentChecking,              (* -Wstudents checks for common student errs*)
+   StyleChecking,                (* -Wstudents checks for common student errs*)
    DisplayQuadruples,            (* -Wq option will display quadruples.      *)
    UnboundedByReference,         (* -funbounded-by-reference                 *)
    VerboseUnbounded,             (* -Wverbose-unbounded                      *)
@@ -158,6 +159,8 @@ VAR
    ScaffoldDynamic,              (* Should we generate a dynamic scaffold?   *)
    ScaffoldStatic,               (* Should we generate a static scaffold?    *)
    ScaffoldMain,                 (* Should we generate a main function?      *)
+   GenModuleList,                (* Should the compiler generate a list of   *)
+                                 (* all modules used?                        *)
    ForcedLocation,
    DebugFunctionLineNumbers,
    GenerateStatementNote,
@@ -240,17 +243,24 @@ PROCEDURE GetRuntimeModuleOverride () : ADDRESS ;
 
 
 (*
-   SetUselist - set the uselist to filename.
+   SetUselist - set the uselist flag to value and remember the filename.
 *)
 
-PROCEDURE SetUselist (filename: ADDRESS) ;
+PROCEDURE SetUselist (value: BOOLEAN; filename: ADDRESS) ;
 
 
 (*
-   GetUselist - return the uselist filename as a String.
+   GetUselist - return the uselist flag.
 *)
 
-PROCEDURE GetUselist () : String ;
+PROCEDURE GetUselist () : BOOLEAN ;
+
+
+(*
+   GetUselistFilename - return the uselist filename as a String.
+*)
+
+PROCEDURE GetUselistFilename () : String ;
 
 
 (*
@@ -460,10 +470,10 @@ PROCEDURE SetExceptions (value: BOOLEAN) ;
 
 
 (*
-   SetStudents -
+   SetStyle -
 *)
 
-PROCEDURE SetStudents (value: BOOLEAN) ;
+PROCEDURE SetStyle (value: BOOLEAN) ;
 
 
 (*
@@ -762,6 +772,21 @@ PROCEDURE SetSaveTemps (value: BOOLEAN) ;
 PROCEDURE SetSaveTempsDir (arg: ADDRESS) ;
 
 
+(*
+   SetGenModuleList - set the GenModuleList flag to value and pass
+                      set GenModuleListFilename to filename.
+*)
+
+PROCEDURE SetGenModuleList (value: BOOLEAN; filename: ADDRESS) ;
+
+
+(*
+   GetGenModuleFilename - returns the filename set by SetGenModuleList.
+*)
+
+PROCEDURE GetGenModuleFilename () : String ;
+
+
 (*
    FinaliseOptions - once all options have been parsed we set any inferred
                      values.
diff --git a/gcc/m2/gm2-compiler/M2Options.mod b/gcc/m2/gm2-compiler/M2Options.mod
index aef709bb3d2..5c0fb179c5e 100644
--- a/gcc/m2/gm2-compiler/M2Options.mod
+++ b/gcc/m2/gm2-compiler/M2Options.mod
@@ -51,10 +51,13 @@ CONST
    Debugging = FALSE ;
 
 VAR
+   GenModuleListFilename,
    UselistFilename,
    RuntimeModuleOverride,
    CppProgram,
    CppArgs              : String ;
+   UselistFlag,
+   GenModuleListFlag,
    CC1Quiet,
    SeenSources          : BOOLEAN ;
    ForcedLocationValue  : location_t ;
@@ -404,25 +407,40 @@ END Getc ;
 
 
 (*
-   SetUselist - set the uselist to filename.
+   SetUselist - set the uselist flag to value and remember the filename.
 *)
 
-PROCEDURE SetUselist (filename: ADDRESS) ;
+PROCEDURE SetUselist (value: BOOLEAN; filename: ADDRESS) ;
 BEGIN
-   UselistFilename := InitStringCharStar (filename)
+   UselistFlag := value ;
+   UselistFilename := KillString (UselistFilename) ;
+   IF filename # NIL
+   THEN
+      UselistFilename := InitStringCharStar (filename)
+   END
 END SetUselist ;
 
 
 (*
-   GetUselist - return the uselist filename as a String.
+   GetUselist - return the uselist flag.
 *)
 
-PROCEDURE GetUselist () : String ;
+PROCEDURE GetUselist () : BOOLEAN ;
 BEGIN
-   RETURN UselistFilename
+   RETURN UselistFlag
 END GetUselist ;
 
 
+(*
+   GetUselistFilename - return the uselist filename as a String.
+*)
+
+PROCEDURE GetUselistFilename () : String ;
+BEGIN
+   RETURN UselistFilename
+END GetUselistFilename ;
+
+
 (*
    SetM2g - set GenerateStatementNote to value and return value.
             Corresponds to the -fm2-g flag.
@@ -654,13 +672,13 @@ END SetExceptions ;
 
 
 (*
-   SetStudents -
+   SetStyle -
 *)
 
-PROCEDURE SetStudents (value: BOOLEAN) ;
+PROCEDURE SetStyle (value: BOOLEAN) ;
 BEGIN
-   StudentChecking := value
-END SetStudents ;
+   StyleChecking := value
+END SetStyle ;
 
 
 (*
@@ -1034,7 +1052,7 @@ BEGIN
    UnusedParameterChecking := value ;
    PedanticCast := value ;
    PedanticParamNames := value ;
-   StudentChecking := value
+   StyleChecking := value
 END SetWall ;
 
 
@@ -1140,6 +1158,32 @@ BEGIN
 END GetRuntimeModuleOverride ;
 
 
+(*
+   SetGenModuleList - set the GenModuleList flag to true and pass
+                      set GenModuleListFilename to filename.
+*)
+
+PROCEDURE SetGenModuleList (value: BOOLEAN; filename: ADDRESS) ;
+BEGIN
+   GenModuleListFilename := KillString (GenModuleListFilename) ;
+   IF filename # NIL
+   THEN
+      GenModuleListFilename := InitStringCharStar (filename)
+   END ;
+   GenModuleList := value
+END SetGenModuleList ;
+
+
+(*
+   GetGenModuleFilename - returns the filename set by SetGenModuleList.
+*)
+
+PROCEDURE GetGenModuleFilename () : String ;
+BEGIN
+   RETURN GenModuleListFilename
+END GetGenModuleFilename ;
+
+
 BEGIN
    cflag                        := FALSE ;  (* -c.  *)
    RuntimeModuleOverride        := NIL ;
@@ -1153,7 +1197,7 @@ BEGIN
    Iso                          := FALSE ;
    SeenSources                  := FALSE ;
    Statistics                   := FALSE ;
-   StudentChecking              := FALSE ;
+   StyleChecking                := FALSE ;
    CompilerDebugging            := FALSE ;
    GenerateDebugging            := FALSE ;
    Optimizing                   := FALSE ;
@@ -1201,5 +1245,7 @@ BEGIN
    ScaffoldDynamic              := TRUE ;
    ScaffoldStatic               := FALSE ;
    ScaffoldMain                 := FALSE ;
-   UselistFilename              := NIL
+   UselistFilename              := NIL ;
+   GenModuleList                := FALSE ;
+   GenModuleListFilename        := NIL
 END M2Options.
diff --git a/gcc/m2/gm2-compiler/M2Quads.mod b/gcc/m2/gm2-compiler/M2Quads.mod
index 0c7ae8a7ce4..3cd9801fbee 100644
--- a/gcc/m2/gm2-compiler/M2Quads.mod
+++ b/gcc/m2/gm2-compiler/M2Quads.mod
@@ -2359,23 +2359,26 @@ END BuildM2DepFunction ;
 
 PROCEDURE BuildM2LinkFunction (tokno: CARDINAL; modulesym: CARDINAL) ;
 BEGIN
-   IF ScaffoldDynamic AND (linkFunction # NulSym)
+   IF ScaffoldDynamic
    THEN
-      (* void
-         _M2_link (void)
-         {
-            for each module in uselist do
-               PROC foo_%d = _M2_module_ctor
-            done
-         }.  *)
-      PushT (linkFunction) ;
-      BuildProcedureStart ;
-      BuildProcedureBegin ;
-      StartScope (linkFunction) ;
-      PopulateCtorArray (tokno) ;
-      EndScope ;
-      BuildProcedureEnd ;
-      PopN (1)
+      IF linkFunction # NulSym
+      THEN
+         (* void
+           _M2_link (void)
+           {
+              for each module in uselist do
+                 PROC foo_%d = _M2_module_ctor
+              done
+           }.  *)
+         PushT (linkFunction) ;
+         BuildProcedureStart ;
+         BuildProcedureBegin ;
+         StartScope (linkFunction) ;
+         PopulateCtorArray (tokno) ;
+         EndScope ;
+         BuildProcedureEnd ;
+         PopN (1)
+      END
    END
 END BuildM2LinkFunction ;
 
diff --git a/gcc/m2/gm2-compiler/M2Scaffold.def b/gcc/m2/gm2-compiler/M2Scaffold.def
index f99efbc1656..48a47c5e0dc 100644
--- a/gcc/m2/gm2-compiler/M2Scaffold.def
+++ b/gcc/m2/gm2-compiler/M2Scaffold.def
@@ -23,6 +23,7 @@ DEFINITION MODULE M2Scaffold ;
 
 
 VAR
+   ctorArray,
    linkFunction,
    finiFunction,
    initFunction,
diff --git a/gcc/m2/gm2-compiler/M2Scaffold.mod b/gcc/m2/gm2-compiler/M2Scaffold.mod
index 47ada7b5a98..ed39be3e98a 100644
--- a/gcc/m2/gm2-compiler/M2Scaffold.mod
+++ b/gcc/m2/gm2-compiler/M2Scaffold.mod
@@ -28,7 +28,9 @@ FROM SymbolTable IMPORT NulSym, MakeProcedure, PutFunction,
                         MakeSubscript, PutSubscript, PutArraySubscript,
                         MakeVar, PutVar, MakeProcedureCtorExtern,
                         GetMainModule, GetModuleCtors, MakeDefImp,
-                        PutModuleCtorExtern,
+                        PutModuleCtorExtern, IsDefinitionForC,
+                        ForeachModuleDo, IsDefImp, IsModule,
+                        IsModuleBuiltin,
                         GetSymName, StartScope, EndScope ;
 
 FROM NameKey IMPORT NulName, Name, MakeKey, makekey, KeyToCharStar ;
@@ -37,21 +39,26 @@ FROM M2System IMPORT Address ;
 FROM M2LexBuf IMPORT GetTokenNo ;
 FROM Assertion IMPORT Assert ;
 FROM Lists IMPORT List, InitList, IncludeItemIntoList, NoOfItemsInList, GetItemFromList ;
-FROM M2MetaError IMPORT MetaErrorT0 ;
+FROM M2MetaError IMPORT MetaErrorT0, MetaErrorStringT0 ;
 
 FROM SFIO IMPORT OpenToWrite, WriteS, ReadS, OpenToRead, Exists ;
 FROM FIO IMPORT File, EOF, IsNoError, Close ;
-FROM M2Options IMPORT GetUselist, ScaffoldStatic ;
+
+FROM M2Options IMPORT GetUselist, ScaffoldStatic, ScaffoldDynamic, GenModuleList,
+                      GetGenModuleFilename, GetUselistFilename, GetUselist, cflag ;
+
 FROM M2Base IMPORT Proc ;
 
 FROM M2Quads IMPORT PushTFtok, PushTtok, PushT, BuildDesignatorArray, BuildAssignment,
                     BuildProcedureCall ;
 
 FROM M2Batch IMPORT IsModuleKnown, Get ;
+FROM M2Printf IMPORT printf0, printf1, printf2, printf3, printf4 ;
+FROM FormatStrings IMPORT HandleEscape ;
 
 FROM DynamicStrings IMPORT String, InitString, KillString, ConCat, RemoveWhitePrefix,
                     EqualArray, Mark, Assign, Fin, InitStringChar, Length, Slice, Equal,
-                    RemoveComment, string ;
+                    RemoveComment, string, InitStringCharStar ;
 
 CONST
    Comment = '#'  ; (* Comment leader      *)
@@ -60,7 +67,6 @@ VAR
    uselistModules,
    ctorModules,
    ctorGlobals   : List ;
-   ctorArray,
    ctorArrayType : CARDINAL ;
 
 
@@ -244,14 +250,24 @@ END LookupModuleSym ;
 
 
 (*
-   ReadModules - populate ctorGlobals with the modules specified by -fuselist=filename.
+   AddEntry - adds an entry to the ctorGlobals and uselistModules.
+*)
+
+PROCEDURE AddEntry (tok: CARDINAL; name: Name) ;
+BEGIN
+   IncludeItemIntoList (ctorGlobals, name) ;
+   IncludeItemIntoList (uselistModules, LookupModuleSym (tok, name))
+END AddEntry ;
+
+
+(*
+   ReadModules - populate ctorGlobals with the modules specified by -fuse-list=filename.
 *)
 
 PROCEDURE ReadModules (tok: CARDINAL; filename: String) ;
 VAR
-   f   : File ;
-   s   : String ;
-   name: Name ;
+   f: File ;
+   s: String ;
 BEGIN
    InitList (ctorGlobals) ;
    InitList (uselistModules) ;
@@ -263,9 +279,7 @@ BEGIN
                      Mark (Slice (s, 0, Length (Mark (InitStringChar (Comment)))-1)))) AND
          (NOT EqualArray (s, ''))
       THEN
-         name := makekey (string (s)) ;
-         IncludeItemIntoList (ctorGlobals, name) ;
-         IncludeItemIntoList (uselistModules, LookupModuleSym (tok, name))
+         AddEntry (tok, makekey (string (s)))
       END ;
       s := KillString (s)
    END ;
@@ -273,29 +287,116 @@ BEGIN
 END ReadModules ;
 
 
+VAR
+   ctorTok: CARDINAL ;
+
+
 (*
-   CreateCtorList - uses GetUselist as the filename and then reads the list of modules.
+   AddModuleToCtor - adds moduleSym to the ctorGlobals and uselistModules.
 *)
 
-PROCEDURE CreateCtorList (tok: CARDINAL) : BOOLEAN ;
+PROCEDURE AddModuleToCtor (moduleSym: CARDINAL) ;
+BEGIN
+   IF IsModule (moduleSym) OR (NOT IsDefinitionForC (moduleSym))
+   THEN
+      IF (moduleSym # GetMainModule ()) AND (NOT IsModuleBuiltin (moduleSym))
+      THEN
+         PutModuleCtorExtern (ctorTok, moduleSym) ;
+         IncludeItemIntoList (ctorGlobals, GetSymName (moduleSym)) ;
+         IncludeItemIntoList (uselistModules, moduleSym)
+      END
+   END
+END AddModuleToCtor ;
+
+
+(*
+   WriteCtorList - writes the ctor list to GetGenModuleFilename
+                   providing the filename is not NIL and not '-'.
+*)
+
+PROCEDURE WriteCtorList (tok: CARDINAL) ;
 VAR
-   filename: String ;
+   fo  : File ;
+   name: Name ;
+   i, n: CARDINAL ;
+   s   : String ;
 BEGIN
-   filename := GetUselist () ;
-   IF filename = NIL
+   IF (GetGenModuleFilename () # NIL) AND (NOT EqualArray (GetGenModuleFilename (), '-'))
    THEN
-      RETURN FALSE
-   ELSE
-      IF Exists (filename)
+      fo := OpenToWrite (GetGenModuleFilename ()) ;
+      IF IsNoError (fo)
       THEN
-         ReadModules (tok, filename)
+         i := 1 ;
+         n := NoOfItemsInList (ctorGlobals) ;
+         WHILE i <= n DO
+            name := GetItemFromList (ctorGlobals, i) ;
+            s := InitStringCharStar (KeyToCharStar (name)) ;
+            s := ConCat (s, Mark (InitString ('\n'))) ;
+            s := HandleEscape (s) ;
+            s := WriteS (fo, s) ;
+            s := KillString (s) ;
+            INC (i)
+         END ;
+         Close (fo)
       ELSE
-         MetaErrorT0 (tok,
-                      '{%E}the filename specified by the -fuselist= option does not exist') ;
-         RETURN FALSE
+         s := InitString ("unable to create file containing ctor module list: ") ;
+         s := ConCat (s, GetGenModuleFilename ()) ;
+         MetaErrorStringT0 (tok, s)
       END
+   END
+END WriteCtorList ;
+
+
+(*
+   CreateCtorListFromImports - if GenModuleList then populate
+                               the ctor list from all modules which are
+                               not FOR 'C'.
+*)
+
+PROCEDURE CreateCtorListFromImports (tok: CARDINAL) : BOOLEAN ;
+BEGIN
+   IF GenModuleList
+   THEN
+      InitList (ctorGlobals) ;
+      InitList (uselistModules) ;
+      ctorTok := tok ;
+      ForeachModuleDo (AddModuleToCtor) ;
+      WriteCtorList (tok) ;
+      RETURN TRUE
    END ;
-   RETURN TRUE
+   RETURN FALSE
+END CreateCtorListFromImports ;
+
+
+(*
+   CreateCtorList - uses GetUselistFilename and then reads the list of modules.
+*)
+
+PROCEDURE CreateCtorList (tok: CARDINAL) : BOOLEAN ;
+VAR
+   filename: String ;
+BEGIN
+   IF GetUselist ()
+   THEN
+      filename := GetUselistFilename () ;
+      IF filename # NIL
+      THEN
+         IF Exists (filename)
+         THEN
+            ReadModules (tok, filename) ;
+            RETURN TRUE
+         ELSE
+            IF NOT EqualArray (filename, '-')
+            THEN
+               MetaErrorT0 (tok,
+                            '{%E}the filename specified by the -fuse-list= option does not exist') ;
+            END
+         END
+      END ;
+      RETURN FALSE
+   ELSE
+      RETURN CreateCtorListFromImports (tok)
+   END
 END CreateCtorList ;
 
 
@@ -342,6 +443,10 @@ BEGIN
       DeclareCtorGlobal (tokenno) ;
       DeclareModuleExtern (tokenno) ;
       linkFunction := MakeProcedure (tokenno, MakeKey ("_M2_link"))
+   ELSIF ScaffoldDynamic AND (NOT cflag)
+   THEN
+      MetaErrorT0 (tokenno,
+                   '{%O}dynamic linking enabled but no module ctor list has been created, hint use -fuse-list=filename or -fgen-module-list=-')
    END ;
 
    mainFunction := MakeProcedure (tokenno, MakeKey ("main")) ;
@@ -389,6 +494,7 @@ BEGIN
    initFunction := NulSym ;
    mainFunction := NulSym ;
    linkFunction := NulSym ;
+   ctorArray := NulSym ;
    ctorGlobals := NIL ;
    ctorModules := NIL ;
    uselistModules := NIL
diff --git a/gcc/m2/gm2-compiler/M2Students.mod b/gcc/m2/gm2-compiler/M2Students.mod
index 16e60250a55..20e375f1d3b 100644
--- a/gcc/m2/gm2-compiler/M2Students.mod
+++ b/gcc/m2/gm2-compiler/M2Students.mod
@@ -32,7 +32,7 @@ FROM DynamicStrings IMPORT String, InitString, KillString, ToUpper, InitStringCh
 FROM FormatStrings IMPORT Sprintf0, Sprintf1, Sprintf2 ;
 FROM M2LexBuf IMPORT GetTokenNo ;
 FROM ASCII IMPORT nul ;
-FROM M2Options IMPORT StudentChecking ;
+FROM M2Options IMPORT StyleChecking ;
 
 
 VAR
@@ -80,7 +80,7 @@ END IsNotADuplicateName ;
 
 PROCEDURE CheckForVariableThatLooksLikeKeyword (name: Name) ;
 BEGIN
-   IF StudentChecking
+   IF StyleChecking
    THEN
       PerformVariableKeywordCheck (name)
    END
@@ -154,7 +154,7 @@ VAR
 BEGIN
    IF p#NulSym
    THEN
-      i := 1 ;   (* I would have used NoOfParam(p)+1 but Stuart wants parameters checked as well - maybe he is right *)
+      i := 1 ;   (* I would have used NoOfParam(p)+1 but Stuart wants parameters checked as well - maybe he is right.  *)
       REPEAT
          n1 := GetNth(p, i) ;
          IF n1#NulSym
diff --git a/gcc/m2/gm2-compiler/P0SymBuild.def b/gcc/m2/gm2-compiler/P0SymBuild.def
index 97db3a88165..c7cfb4800b3 100644
--- a/gcc/m2/gm2-compiler/P0SymBuild.def
+++ b/gcc/m2/gm2-compiler/P0SymBuild.def
@@ -69,7 +69,7 @@ PROCEDURE RegisterImplementationModule ;
                               It starts a new module scope.
 *)
 
-PROCEDURE RegisterDefinitionModule ;
+PROCEDURE RegisterDefinitionModule (forC: BOOLEAN) ;
 
 
 (*
diff --git a/gcc/m2/gm2-compiler/P0SymBuild.mod b/gcc/m2/gm2-compiler/P0SymBuild.mod
index 93543705c55..e3025ebc564 100644
--- a/gcc/m2/gm2-compiler/P0SymBuild.mod
+++ b/gcc/m2/gm2-compiler/P0SymBuild.mod
@@ -25,7 +25,7 @@ FROM Storage IMPORT ALLOCATE, DEALLOCATE ;
 FROM M2Printf IMPORT printf0, printf1, printf2 ;
 FROM Lists IMPORT List, InitList, KillList, IncludeItemIntoList, RemoveItemFromList, NoOfItemsInList, GetItemFromList, IsItemInList ;
 FROM M2Batch IMPORT MakeDefinitionSource, MakeProgramSource, MakeImplementationSource ;
-FROM SymbolTable IMPORT NulSym, MakeInnerModule, SetCurrentModule, SetFileModule, MakeError ;
+FROM SymbolTable IMPORT NulSym, MakeInnerModule, SetCurrentModule, SetFileModule, MakeError, PutDefinitionForC ;
 FROM NameKey IMPORT Name, NulName ;
 FROM M2Quads IMPORT PushT, PushTF, PopT, PopTF, PopN, OperandT, PopTtok, PushTtok ;
 FROM M2Reserved IMPORT ImportTok ;
@@ -420,19 +420,23 @@ END RegisterImplementationModule ;
    RegisterDefinitionModule - register the top of stack as a definition module.
 *)
 
-PROCEDURE RegisterDefinitionModule ;
+PROCEDURE RegisterDefinitionModule (forC: BOOLEAN) ;
 VAR
    n  : Name ;
    sym: CARDINAL ;
    tok: CARDINAL ;
 BEGIN
-   Assert(Level=0) ;
-   INC(Level) ;
+   Assert (Level=0) ;
+   INC (Level) ;
    PopTtok (n, tok) ;
    PushTtok (n, tok) ;
    sym := MakeDefinitionSource (tok, n) ;
    SetCurrentModule (sym) ;
    SetFileModule (sym) ;
+   IF forC
+   THEN
+      PutDefinitionForC (sym)
+   END ;
    BeginBlock (n, defimp, sym, tok) ;
    M2Error.EnterDefinitionScope (n)
 END RegisterDefinitionModule ;
diff --git a/gcc/m2/gm2-compiler/SymbolTable.def b/gcc/m2/gm2-compiler/SymbolTable.def
index 70a4f79b765..12270ed0289 100644
--- a/gcc/m2/gm2-compiler/SymbolTable.def
+++ b/gcc/m2/gm2-compiler/SymbolTable.def
@@ -154,6 +154,9 @@ EXPORT QUALIFIED NulSym,
                  GetVarWritten,
                  PutConst,
                  PutConstString,
+                 PutDefLink,
+                 PutModLink,
+                 PutModuleBuiltin,
 
                  PutConstSet,
                  PutConstructor,
@@ -252,6 +255,9 @@ EXPORT QUALIFIED NulSym,
                  IsModuleWithinProcedure,
                  IsVariableAtAddress,
                  IsReturnOptional,
+                 IsDefLink,
+                 IsModLink,
+                 IsModuleBuiltin,
 
                  ForeachProcedureDo,
                  ProcedureParametersDefined,
@@ -3442,4 +3448,47 @@ PROCEDURE AppendModuleImportStatement (module, statement: CARDINAL) ;
 PROCEDURE AppendModuleOnImportStatement (module, import: CARDINAL) ;
 
 
+(*
+   PutModLink - assigns link to module sym.
+*)
+
+PROCEDURE PutModLink (sym: CARDINAL; link: BOOLEAN) ;
+
+
+(*
+   IsModLink - returns the ModLink value associated with the module symbol.
+*)
+
+PROCEDURE IsModLink (sym: CARDINAL) : BOOLEAN ;
+
+
+(*
+   PutDefLink - assigns link to the definition module sym.
+*)
+
+PROCEDURE PutDefLink (sym: CARDINAL; link: BOOLEAN) ;
+
+
+(*
+   IsDefLink - returns the DefLink value associated with the definition module symbol.
+*)
+
+PROCEDURE IsDefLink (sym: CARDINAL) : BOOLEAN ;
+
+
+(*
+   IsModuleBuiltin - returns TRUE if the module is a builtin module.
+                     (For example _BaseTypes).
+*)
+
+PROCEDURE IsModuleBuiltin (sym: CARDINAL) : BOOLEAN ;
+
+
+(*
+   PutModuleBuiltin - sets the Builtin flag to value.
+*)
+
+PROCEDURE PutModuleBuiltin (sym: CARDINAL; value: BOOLEAN) ;
+
+
 END SymbolTable.
diff --git a/gcc/m2/gm2-compiler/SymbolTable.mod b/gcc/m2/gm2-compiler/SymbolTable.mod
index 6c1cce8ef5d..320bf675393 100644
--- a/gcc/m2/gm2-compiler/SymbolTable.mod
+++ b/gcc/m2/gm2-compiler/SymbolTable.mod
@@ -689,6 +689,9 @@ TYPE
                                             (* builtin procedure?            *)
                ForC          : BOOLEAN ;    (* Is it a definition for "C"    *)
                NeedExportList: BOOLEAN ;    (* Must user supply export list? *)
+               ModLink,                     (* Is the Def/Mod module parsed  *)
+               DefLink       : BOOLEAN ;    (* for linkage only?             *)
+               Builtin       : BOOLEAN ;    (* Is the module builtin?        *)
                ListOfVars    : List ;       (* List of variables in this     *)
                                             (* scope.                        *)
                ListOfProcs   : List ;       (* List of all procedures        *)
@@ -754,6 +757,9 @@ TYPE
                FinallyFunction: Tree ;      (* The GCC function for finally  *)
                ExceptionFinally,
                ExceptionBlock: BOOLEAN ;    (* does it have an exception?    *)
+               ModLink       : BOOLEAN ;    (* Is the module parsed for      *)
+                                            (* linkage only?                 *)
+               Builtin       : BOOLEAN ;    (* Is the module builtin?        *)
                ListOfVars    : List ;       (* List of variables in this     *)
                                             (* scope.                        *)
                ListOfProcs   : List ;       (* List of all procedures        *)
@@ -3223,6 +3229,8 @@ BEGIN
          FinallyFunction := NIL ;           (* The GCC function for finally  *)
          ExceptionFinally := FALSE ;        (* does it have an exception?    *)
          ExceptionBlock := FALSE ;          (* does it have an exception?    *)
+         ModLink := GetLink () ;            (* Is this parsed for linkage?   *)
+         Builtin := FALSE ;                 (* Is the module builtin?        *)
          InitList(ListOfVars) ;             (* List of variables in this     *)
                                             (* scope.                        *)
          InitList(ListOfProcs) ;            (* List of all procedures        *)
@@ -3241,10 +3249,179 @@ BEGIN
       END
    END ;
    PutSymKey(ModuleTree, ModuleName, Sym) ;
-   RETURN( Sym )
+   RETURN Sym
 END MakeModule ;
 
 
+(*
+   PutModLink - assigns link to module sym.
+*)
+
+PROCEDURE PutModLink (sym: CARDINAL; link: BOOLEAN) ;
+VAR
+   pSym: PtrToSymbol ;
+BEGIN
+   IF IsModule (sym)
+   THEN
+      pSym := GetPsym (sym) ;
+      pSym^.Module.ModLink := link
+   ELSIF IsDefImp (sym)
+   THEN
+      pSym := GetPsym (sym) ;
+      pSym^.DefImp.ModLink := link
+   ELSE
+      InternalError ('expecting a DefImp or Module symbol')
+   END
+END PutModLink ;
+
+
+(*
+   IsModLink - returns the ModLink value associated with the module symbol.
+*)
+
+PROCEDURE IsModLink (sym: CARDINAL) : BOOLEAN ;
+VAR
+   pSym: PtrToSymbol ;
+BEGIN
+   IF IsModule (sym)
+   THEN
+      pSym := GetPsym (sym) ;
+      RETURN pSym^.Module.ModLink
+   ELSIF IsDefImp (sym)
+   THEN
+      pSym := GetPsym (sym) ;
+      RETURN pSym^.DefImp.ModLink
+   ELSE
+      InternalError ('expecting a DefImp or Module symbol')
+   END
+END IsModLink ;
+
+
+(*
+   PutDefLink - assigns link to the definition module sym.
+*)
+
+PROCEDURE PutDefLink (sym: CARDINAL; link: BOOLEAN) ;
+VAR
+   pSym: PtrToSymbol ;
+BEGIN
+   IF IsDefImp (sym)
+   THEN
+      pSym := GetPsym (sym) ;
+      pSym^.DefImp.DefLink := link
+   ELSE
+      InternalError ('expecting a DefImp symbol')
+   END
+END PutDefLink ;
+
+
+(*
+   IsDefLink - returns the DefLink value associated with the definition module symbol.
+*)
+
+PROCEDURE IsDefLink (sym: CARDINAL) : BOOLEAN ;
+VAR
+   pSym: PtrToSymbol ;
+BEGIN
+   IF IsDefImp (sym)
+   THEN
+      pSym := GetPsym (sym) ;
+      RETURN pSym^.DefImp.DefLink
+   ELSE
+      InternalError ('expecting a DefImp symbol')
+   END
+END IsDefLink ;
+
+
+(*
+   GetOuterModule - returns the outer module or NulSym if there
+                    is no module being compiled.
+*)
+
+PROCEDURE GetOuterModule () : CARDINAL ;
+VAR
+   OuterModule: CARDINAL ;
+BEGIN
+   OuterModule := GetCurrentModule () ;
+   IF OuterModule # NulSym
+   THEN
+      WHILE GetScope (OuterModule) # NulSym DO
+         OuterModule := GetScope (OuterModule)
+      END
+   END ;
+   RETURN OuterModule
+END GetOuterModule ;
+
+
+(*
+   GetLink - returns TRUE if the current module is only used for linkage.
+*)
+
+PROCEDURE GetLink () : BOOLEAN ;
+VAR
+   OuterModule: CARDINAL ;
+BEGIN
+   OuterModule := GetCurrentModule () ;
+   IF OuterModule # NulSym
+   THEN
+      IF CompilingDefinitionModule ()
+      THEN
+         RETURN IsDefLink (OuterModule)
+      ELSE
+         RETURN IsModLink (OuterModule)
+      END
+   END ;
+   (* Default is that the module is for compiling.  *)
+   RETURN FALSE
+END GetLink ;
+
+
+(*
+   IsModuleBuiltin - returns TRUE if the module is a builtin module.
+                     (For example _BaseTypes).
+*)
+
+PROCEDURE IsModuleBuiltin (sym: CARDINAL) : BOOLEAN ;
+VAR
+   pSym: PtrToSymbol ;
+BEGIN
+   IF IsDefImp (sym)
+   THEN
+      pSym := GetPsym (sym) ;
+      RETURN pSym^.DefImp.Builtin
+   ELSIF IsModule (sym)
+   THEN
+      pSym := GetPsym (sym) ;
+      RETURN pSym^.Module.Builtin
+   END ;
+   RETURN FALSE
+END IsModuleBuiltin ;
+
+
+(*
+   PutModuleBuiltin - sets the Builtin flag to value.
+                      Currently the procedure expects sym to be a DefImp
+                      module only.
+*)
+
+PROCEDURE PutModuleBuiltin (sym: CARDINAL; value: BOOLEAN) ;
+VAR
+   pSym: PtrToSymbol ;
+BEGIN
+   IF IsDefImp (sym)
+   THEN
+      pSym := GetPsym (sym) ;
+      pSym^.DefImp.Builtin := value
+   ELSIF IsModule (sym)
+   THEN
+      pSym := GetPsym (sym) ;
+      pSym^.Module.Builtin := value
+   ELSE
+      InternalError ('expecting Module or DefImp symbol')
+   END
+END PutModuleBuiltin ;
+
+
 (*
    AddModuleToParent - adds symbol, Sym, to module, Parent.
 *)
@@ -3336,6 +3513,7 @@ BEGIN
             FinallyFunction := NIL ;        (* The GCC function for finally  *)
             ExceptionFinally := FALSE ;     (* does it have an exception?    *)
             ExceptionBlock := FALSE ;       (* does it have an exception?    *)
+            ModLink := GetLink () ;         (* Is this parsed for linkage?   *)
             InitList(ListOfVars) ;          (* List of variables in this     *)
                                             (* scope.                        *)
             InitList(ListOfProcs) ;         (* List of all procedures        *)
@@ -3465,6 +3643,9 @@ BEGIN
                                       (* procedure?                    *)
          ForC := FALSE ;              (* Is it a definition for "C"    *)
          NeedExportList := FALSE ;    (* Must user supply export list? *)
+         DefLink := GetLink () ;      (* Is the def/mod file only      *)
+         ModLink := GetLink () ;      (* parsed for linkage?           *)
+         Builtin := FALSE ;           (* Is the module builtin?        *)
          InitList(ListOfVars) ;       (* List of variables in this     *)
                                       (* scope.                        *)
          InitList(ListOfProcs) ;      (* List of all procedures        *)
@@ -8746,7 +8927,7 @@ END RemoveExportUndeclared ;
 
 PROCEDURE CheckForExportedDeclaration (Sym: CARDINAL) ;
 BEGIN
-   IF CompilingDefinitionModule()
+   IF CompilingDefinitionModule ()
    THEN
       RemoveExportUndeclared(GetCurrentModule(), Sym)
    END
@@ -12932,7 +13113,7 @@ END ForeachInnerModuleDo ;
 
 PROCEDURE ForeachModuleDo (P: PerformOperation) ;
 BEGIN
-   ForeachNodeDo(ModuleTree, P)
+   ForeachNodeDo (ModuleTree, P)
 END ForeachModuleDo ;
 
 
diff --git a/gcc/m2/gm2-gcc/m2options.h b/gcc/m2/gm2-gcc/m2options.h
index c5ed3bdb271..34f28976b8c 100644
--- a/gcc/m2/gm2-gcc/m2options.h
+++ b/gcc/m2/gm2-gcc/m2options.h
@@ -63,7 +63,7 @@ EXTERN int M2Options_GetWholeValueCheck (void);
 EXTERN void M2Options_Setc (int value);
 EXTERN int M2Options_Getc (void);
 
-EXTERN void M2Options_SetUselist (const char *filename);
+EXTERN void M2Options_SetUselist (int value, const char *filename);
 EXTERN void M2Options_SetAutoInit (int value);
 EXTERN void M2Options_SetPositiveModFloor (int value);
 EXTERN void M2Options_SetNilCheck (int value);
@@ -74,7 +74,7 @@ EXTERN void M2Options_SetReturnCheck (int value);
 EXTERN void M2Options_SetCaseCheck (int value);
 EXTERN void M2Options_SetCheckAll (int value);
 EXTERN void M2Options_SetExceptions (int value);
-EXTERN void M2Options_SetStudents (int value);
+EXTERN void M2Options_SetStyle (int value);
 EXTERN void M2Options_SetPedantic (int value);
 EXTERN void M2Options_SetPedanticParamNames (int value);
 EXTERN void M2Options_SetPedanticCast (int value);
@@ -118,6 +118,7 @@ EXTERN void M2Options_SetScaffoldStatic (int value);
 EXTERN void M2Options_SetScaffoldDynamic (int value);
 EXTERN void M2Options_SetScaffoldMain (int value);
 EXTERN void M2Options_SetRuntimeModuleOverride (const char *override);
+EXTERN void M2Options_SetGenModuleList (int value, const char *filename);
 
 #undef EXTERN
 #endif /* m2options_h.  */
diff --git a/gcc/m2/gm2-lang.cc b/gcc/m2/gm2-lang.cc
index 5b1021b7950..07ae5ed5860 100644
--- a/gcc/m2/gm2-lang.cc
+++ b/gcc/m2/gm2-lang.cc
@@ -238,6 +238,9 @@ gm2_langhook_handle_option (
     case OPT_flibs_:
       /* handled in the gm2 driver.  */
       return 1;
+    case OPT_fgen_module_list_:
+      M2Options_SetGenModuleList (value, arg);
+      return 1;
     case OPT_fnil:
       M2Options_SetNilCheck (value);
       return 1;
@@ -283,8 +286,8 @@ gm2_langhook_handle_option (
     case OPT_fexceptions:
       M2Options_SetExceptions (value);
       return 1;
-    case OPT_Wstudents:
-      M2Options_SetStudents (value);
+    case OPT_Wstyle:
+      M2Options_SetStyle (value);
       return 1;
     case OPT_Wpedantic:
       M2Options_SetPedantic (value);
@@ -319,16 +322,16 @@ gm2_langhook_handle_option (
     case OPT_fm2_lower_case:
       M2Options_SetLowerCaseKeywords (value);
       return 1;
-    case OPT_fuselist_:
-      M2Options_SetUselist (arg);
+    case OPT_fuse_list_:
+      M2Options_SetUselist (value, arg);
       return 1;
     case OPT_fruntime_modules_:
       M2Options_SetRuntimeModuleOverride (arg);
       return 1;
-    case OPT_fno_pthread:
+    case OPT_fpthread:
       /* handled in the driver.  */
       return 1;
-    case OPT_fno_m2_plugin:
+    case OPT_fm2_plugin:
       /* handled in the driver.  */
       return 1;
     case OPT_fscaffold_dynamic:
diff --git a/gcc/m2/gm2-libs-iso/COROUTINES.mod b/gcc/m2/gm2-libs-iso/COROUTINES.mod
index 754531298b0..d3b4afcf80e 100644
--- a/gcc/m2/gm2-libs-iso/COROUTINES.mod
+++ b/gcc/m2/gm2-libs-iso/COROUTINES.mod
@@ -215,20 +215,21 @@ END localMain ;
 
 
 (*
-   localInit - checks to see whether we need to initialize libpth.
+   localInit - checks to see whether we need to initialize our interface to pthreads.
 *)
 
 PROCEDURE localInit ;
 BEGIN
    IF NOT initCo
    THEN
+      Init ;
       IF init () # 0
       THEN
          Halt (__FILE__, __LINE__, __FUNCTION__,
                'failed to initialize RTco')
       END ;
       RTint.Init ;
-      initCo := TRUE ;
+      initCo := TRUE
    END ;
    localMain
 END localInit ;
@@ -585,18 +586,15 @@ END TurnInterrupts ;
 
 
 (*
-   Init -
+   Init - initialize the global data structures.
 *)
 
 PROCEDURE Init ;
 BEGIN
    freeList := NIL ;
-   initCo := FALSE ;
    initMain := FALSE ;
    currentCoRoutine := NIL
 END Init ;
 
 
-BEGIN
-   Init
 END COROUTINES.
diff --git a/gcc/m2/gm2-libs-iso/RTentity.mod b/gcc/m2/gm2-libs-iso/RTentity.mod
index 5d952656f81..b304e27e8b9 100644
--- a/gcc/m2/gm2-libs-iso/RTentity.mod
+++ b/gcc/m2/gm2-libs-iso/RTentity.mod
@@ -42,7 +42,7 @@ PROCEDURE InitGroup () : Group ;
 VAR
    g: Group ;
 BEGIN
-   checkInitialised ;
+   checkInitialized ;
    wait (mutex) ;
    g := malloc (SIZE (g^)) ;
    WITH g^ DO
@@ -89,6 +89,7 @@ VAR
    parent,
    child : Group ;
 BEGIN
+   assert (initialized) ;
    wait (mutex) ;
    findChildAndParent (g, a, child, parent) ;
    signal (mutex) ;
@@ -106,6 +107,7 @@ VAR
    parent,
    child : Group ;
 BEGIN
+   assert (initialized) ;
    wait (mutex) ;
    findChildAndParent (g, a, child, parent) ;
    IF child = NIL
@@ -146,6 +148,7 @@ PROCEDURE IsIn (g: Group; a: SYSTEM.ADDRESS) : BOOLEAN ;
 VAR
    child, parent: Group ;
 BEGIN
+   assert (initialized) ;
    wait (mutex) ;
    findChildAndParent (g, a, child, parent) ;
    signal (mutex) ;
@@ -165,6 +168,7 @@ PROCEDURE DelKey (g: Group; a: SYSTEM.ADDRESS) ;
 VAR
    i, child, parent: Group ;
 BEGIN
+   assert (initialized) ;
    wait (mutex) ;
    (* find parent and child of the node *)
    findChildAndParent (g, a, child, parent) ;
@@ -194,7 +198,7 @@ BEGIN
          END ;
          free (child)
       ELSE
-         (* Assert that parent^.left=child will always be true *)
+         (* assert that parent^.left=child will always be true *)
          (* Perform exactly the mirror image of the above code *)
 
          (* Connect child^.right onto the parent^.left.        *)
@@ -259,10 +263,24 @@ END findChildAndParent ;
 
 
 (*
-   checkInitialised -
+   assert - simple assertion procedure.
 *)
 
-PROCEDURE checkInitialised ;
+PROCEDURE assert (condition: BOOLEAN) ;
+BEGIN
+   IF NOT condition
+   THEN
+      Halt (__FILE__, __LINE__, __FUNCTION__,
+            'internal runtime error, RTentity is either corrupt or the module storage has not been initialized yet')
+   END
+END assert ;
+
+
+(*
+   checkInitialized -
+*)
+
+PROCEDURE checkInitialized ;
 VAR
    result: INTEGER ;
 BEGIN
@@ -272,12 +290,11 @@ BEGIN
       result := init () ;
       mutex := initSemaphore (1)
    END
-END checkInitialised ;
+END checkInitialized ;
 
 
 VAR
-   initialized: BOOLEAN ;
+   initialized: BOOLEAN ;  (* Set to FALSE when the bss is created.  *)
    mutex      : INTEGER ;
-BEGIN
-   initialized := FALSE
+
 END RTentity.
diff --git a/gcc/m2/gm2-libs-iso/Storage.mod b/gcc/m2/gm2-libs-iso/Storage.mod
index eeac85b6615..abf49bcbea7 100644
--- a/gcc/m2/gm2-libs-iso/Storage.mod
+++ b/gcc/m2/gm2-libs-iso/Storage.mod
@@ -40,6 +40,7 @@ FROM EXCEPTIONS IMPORT ExceptionNumber, RAISE,
 
 PROCEDURE ALLOCATE (VAR addr: SYSTEM.ADDRESS; amount: CARDINAL) ;
 BEGIN
+   Init ;
    addr := malloc (amount) ;
    IF addr#NIL
    THEN
@@ -50,6 +51,7 @@ END ALLOCATE ;
 
 PROCEDURE DEALLOCATE (VAR addr: SYSTEM.ADDRESS; amount: CARDINAL) ;
 BEGIN
+   assert (initialized) ;
    IF VerifyDeallocate (addr, amount)
    THEN
       free (addr) ;
@@ -68,7 +70,8 @@ VAR
    newa: SYSTEM.ADDRESS ;
    n   : CARDINAL ;
 BEGIN
-   IF NOT IsIn(storageTree, addr)
+   assert (initialized) ;
+   IF NOT IsIn (storageTree, addr)
    THEN
       RAISE (storageException, ORD(pointerToUnallocatedStorage),
              'trying to reallocate memory which has never been allocated') ;
@@ -88,17 +91,19 @@ END REALLOCATE ;
 
 PROCEDURE IsStorageException () : BOOLEAN;
 BEGIN
+   Init ;
    RETURN( IsCurrentSource (storageException) )
 END IsStorageException ;
 
 
 PROCEDURE StorageException () : StorageExceptions ;
 BEGIN
+   Init ;
    IF NOT IsExceptionalExecution ()
    THEN
       RAISE (storageException, ORD (functionException), 'no storage exception raised')
    END ;
-   RETURN (currentException)
+   RETURN currentException
 END StorageException ;
 
 
@@ -110,36 +115,55 @@ PROCEDURE VerifyDeallocate (addr: SYSTEM.ADDRESS; amount: CARDINAL) : BOOLEAN ;
 VAR
    a: CARDINAL ;
 BEGIN
+
    IF addr=NIL
    THEN
       RAISE (storageException, ORD(nilDeallocation), 'deallocating pointer whose value is NIL') ;
-      RETURN (FALSE)
+      RETURN FALSE
    ELSE
       IF NOT IsIn(storageTree, addr)
       THEN
          RAISE (storageException, ORD(pointerToUnallocatedStorage), 'trying to deallocate memory which has never been allocated') ;
-         RETURN (FALSE)
+         RETURN FALSE
       END ;
       a := GetKey (storageTree, addr) ;
       IF a#amount
       THEN
          RAISE (storageException, ORD(wrongStorageToUnallocate), 'wrong amount of storage being deallocated') ;
-         RETURN (FALSE)
+         RETURN FALSE
       END
    END ;
    DelKey (storageTree, addr) ;
-   RETURN (TRUE)
+   RETURN TRUE
 END VerifyDeallocate ;
 
 
+(*
+   assert - simple assertion procedure.
+*)
+
+PROCEDURE assert (condition: BOOLEAN) ;
+BEGIN
+   IF NOT condition
+   THEN
+      Halt (__FILE__, __LINE__, __FUNCTION__,
+            'internal runtime error, module Storage has not been initialized yet')
+   END
+END assert ;
+
+
 (*
    Init -
 *)
 
 PROCEDURE Init ;
 BEGIN
-   storageTree := InitGroup () ;
-   AllocateSource (storageException)
+   IF NOT initialized
+   THEN
+      initialized := TRUE ;
+      storageTree := InitGroup () ;
+      AllocateSource (storageException)
+   END
 END Init ;
 
 
@@ -147,6 +171,6 @@ VAR
    storageException: ExceptionSource ;
    currentException: StorageExceptions ;
    storageTree     : Group ;
-BEGIN
-   Init
+   initialized     : BOOLEAN ;  (* Set to FALSE when the bss is created.  *)
+
 END Storage.
diff --git a/gcc/m2/gm2-libs/COROUTINES.def b/gcc/m2/gm2-libs/COROUTINES.def
index 3098f1ad750..d7b7dc857df 100644
--- a/gcc/m2/gm2-libs/COROUTINES.def
+++ b/gcc/m2/gm2-libs/COROUTINES.def
@@ -24,7 +24,7 @@ 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 COROUTINES;
+DEFINITION MODULE FOR "C" COROUTINES ;
 
 CONST
    UnassignedPriority = 0 ;
diff --git a/gcc/m2/gm2-libs/M2Dependent.mod b/gcc/m2/gm2-libs/M2Dependent.mod
index 3780cdb33bd..a37d6892406 100644
--- a/gcc/m2/gm2-libs/M2Dependent.mod
+++ b/gcc/m2/gm2-libs/M2Dependent.mod
@@ -549,6 +549,7 @@ BEGIN
             mptr := LookupModuleN (ordered, start, count) ;
             IF mptr # NIL
             THEN
+               mptr^.dependency.forced := TRUE ;
                moveTo (user, mptr)
             END ;
             INC (pc) ;
@@ -564,6 +565,7 @@ BEGIN
          mptr := LookupModuleN (ordered, start, count) ;
          IF mptr # NIL
          THEN
+            mptr^.dependency.forced := TRUE ;
             moveTo (user, mptr)
          END
       END ;
@@ -717,6 +719,7 @@ BEGIN
    DependencyTrace := FALSE ;
    PostTrace := FALSE ;
    PreTrace := FALSE ;
+   ForceTrace := FALSE ;
    pc := getenv (ADR ("GCC_M2LINK_RTFLAG")) ;
    WHILE (pc # NIL) AND (pc^ # nul) DO
       IF equal (pc, "all")
diff --git a/gcc/m2/gm2-libs/Storage.mod b/gcc/m2/gm2-libs/Storage.mod
index b840bf32e91..78556d2d76d 100644
--- a/gcc/m2/gm2-libs/Storage.mod
+++ b/gcc/m2/gm2-libs/Storage.mod
@@ -32,25 +32,25 @@ IMPORT SysStorage ;
 
 PROCEDURE ALLOCATE (VAR a: ADDRESS ; Size: CARDINAL) ;
 BEGIN
-   SysStorage.ALLOCATE(a, Size)
+   SysStorage.ALLOCATE (a, Size)
 END ALLOCATE ;
 
 
 PROCEDURE DEALLOCATE (VAR a: ADDRESS; Size: CARDINAL);
 BEGIN
-   SysStorage.DEALLOCATE(a, Size)
+   SysStorage.DEALLOCATE (a, Size)
 END DEALLOCATE ;
 
 
 PROCEDURE REALLOCATE (VAR a: ADDRESS; Size: CARDINAL);
 BEGIN
-   SysStorage.REALLOCATE(a, Size)
+   SysStorage.REALLOCATE (a, Size)
 END REALLOCATE ;
 
 
 PROCEDURE Available (Size: CARDINAL) : BOOLEAN;
 BEGIN
-   RETURN( SysStorage.Available(Size) )
+   RETURN SysStorage.Available (Size)
 END Available ;
 
 
diff --git a/gcc/m2/gm2spec.cc b/gcc/m2/gm2spec.cc
index 3b36afaa839..55a6991f48a 100644
--- a/gcc/m2/gm2spec.cc
+++ b/gcc/m2/gm2spec.cc
@@ -19,6 +19,13 @@ 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/>.  */
 
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "opts.h"
+
+#if 1
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
@@ -30,6 +37,7 @@ along with GNU Modula-2; see the file COPYING3.  If not see
 #include "opt-suggestions.h"
 #include "gcc.h"
 #include "opts.h"
+#endif
 #include "vec.h"
 
 #include "m2/gm2version.h"
@@ -49,37 +57,59 @@ along with GNU Modula-2; see the file COPYING3.  If not see
 #endif
 #endif
 
+/* This bit is set if we saw a `-xfoo' language specification.  */
+#define LANGSPEC	(1<<1)
+/* This bit is set if they did `-lm' or `-lmath'.  */
+#define MATHLIB		(1<<2)
+/* This bit is set if they did `-lc'.  */
+#define WITHLIBC	(1<<3)
+/* Skip this option.  */
+#define SKIPOPT		(1<<4)
+
 #ifndef MATH_LIBRARY
 #define MATH_LIBRARY "m"
 #endif
+#ifndef MATH_LIBRARY_PROFILE
+#define MATH_LIBRARY_PROFILE MATH_LIBRARY
+#endif
 
 #ifndef LIBSTDCXX
 #define LIBSTDCXX "stdc++"
 #endif
-
-#ifndef DIR_SEPARATOR
-#define DIR_SEPARATOR '/'
+#ifndef LIBSTDCXX_PROFILE
+#define LIBSTDCXX_PROFILE LIBSTDCXX
 #endif
-
-/* Most every one is fine with LIBRARY_PATH.  For some, it conflicts.  */
-#ifndef LIBRARY_PATH_ENV
-#define LIBRARY_PATH_ENV "LIBRARY_PATH"
+#ifndef LIBSTDCXX_STATIC
+#define LIBSTDCXX_STATIC NULL
 #endif
 
-int lang_specific_extra_outfiles = 0;
+#ifndef LIBCXX
+#define LIBCXX "c++"
+#endif
+#ifndef LIBCXX_PROFILE
+#define LIBCXX_PROFILE LIBCXX
+#endif
+#ifndef LIBCXX_STATIC
+#define LIBCXX_STATIC NULL
+#endif
 
-/* DEBUGGING will print all the options at various stages with their
-   error code, full name etc.  */
-#undef DEBUGGING
+#ifndef LIBCXXABI
+#define LIBCXXABI "c++abi"
+#endif
+#ifndef LIBCXXABI_PROFILE
+#define LIBCXXABI_PROFILE LIBCXXABI
+#endif
+#ifndef LIBCXXABI_STATIC
+#define LIBCXXABI_STATIC NULL
+#endif
 
-/* LOCAL_DEBUGGING allows the compiler driver to automatically set a -B
-   prefix (assuming one it not user supplied).  It sets the -Bprefix with
-   the given path to argv[0].  This allows subprograms to be found in the
-   build tree (without having to be installed).  It is only meant as an
-   aid to development, not a user feature :-).  It allows developers to
-   lazily type:  ./gm2 -c hello.c rather than ./gm2 -B./ -c hello.c
-   or /somedirectory/development/build/gcc/gm2 -c hello.c.  */
-#undef LOCAL_DEBUGGING
+/* The values used here must match those of the stdlib_kind enumeration
+   in c.opt.  */
+enum stdcxxlib_kind
+{
+  USE_LIBSTDCXX = 1,
+  USE_LIBCXX = 2
+};
 
 #define DEFAULT_DIALECT "pim"
 
@@ -106,31 +136,108 @@ static const char *library_abbrev[maxlib]
    -flibs=m2pim,m2iso respectively.  This provides a match between
    the dialect of Modula-2 and the library set.  */
 
-int lang_specific_pre_link (void);
-static void add_lib (size_t opt_index, const char *lib, int joined);
+
 static const char *add_include (const char *libpath, const char *library);
-static void insert_option (unsigned int *in_decoded_options_count,
-                           struct cl_decoded_option **in_decoded_options,
-                           unsigned int position);
-static const char *gen_link_path (const char *libpath, const char *dialect);
-static const char *add_exec_dir (int argc, const char *argv[]);
-static const char *gen_gm2_libexec (const char *path);
 
 static bool seen_scaffold_static = false;
 static bool seen_scaffold_dynamic = false;
 static bool scaffold_static = false;
 static bool scaffold_dynamic = true;  // Default uses -fscaffold-dynamic.
+static bool seen_gen_module_list = false;
+static bool seen_uselist = false;
+static bool uselist = false;
+static bool gen_module_list = true;  // Default uses -fgen-module-list=-.
+static const char *gen_module_filename = "-";
 static bool seen_B = false;
 static const char *B_path = NULL;
 static const char *multilib_dir = NULL;
+/* The original argument list and related info is copied here.  */
+static unsigned int gm2_xargc;
+static const struct cl_decoded_option *gm2_x_decoded_options;
+static void append_arg (const struct cl_decoded_option *);
 
-/* By default the suffix for target object files is ".o".  */
-#ifdef TARGET_OBJECT_SUFFIX
-#define HAVE_TARGET_OBJECT_SUFFIX
-#else
-#define TARGET_OBJECT_SUFFIX ".o"
-#endif
+/* The new argument list will be built here.  */
+static unsigned int gm2_newargc;
+static struct cl_decoded_option *gm2_new_decoded_options;
+
+
+/* Return whether strings S1 and S2 are both NULL or both the same
+   string.  */
+
+static bool
+strings_same (const char *s1, const char *s2)
+{
+  return s1 == s2 || (s1 != NULL && s2 != NULL && strcmp (s1, s2) == 0);
+}
+
+#if 1
+bool
+options_same (const struct cl_decoded_option *opt1,
+	      const struct cl_decoded_option *opt2)
+{
+  return (opt1->opt_index == opt2->opt_index
+	  && strings_same (opt1->arg, opt2->arg)
+	  && strings_same (opt1->orig_option_with_args_text,
+			   opt2->orig_option_with_args_text)
+	  && strings_same (opt1->canonical_option[0],
+			   opt2->canonical_option[0])
+	  && strings_same (opt1->canonical_option[1],
+			   opt2->canonical_option[1])
+	  && strings_same (opt1->canonical_option[2],
+			   opt2->canonical_option[2])
+	  && strings_same (opt1->canonical_option[3],
+			   opt2->canonical_option[3])
+	  && (opt1->canonical_option_num_elements
+	      == opt2->canonical_option_num_elements)
+	  && opt1->value == opt2->value
+	  && opt1->errors == opt2->errors);
+}
 
+/* Append another argument to the list being built.  */
+
+static void
+append_arg (const struct cl_decoded_option *arg)
+{
+  static unsigned int newargsize;
+
+  if (gm2_new_decoded_options == gm2_x_decoded_options
+      && gm2_newargc < gm2_xargc
+      && options_same (arg, &gm2_x_decoded_options[gm2_newargc]))
+    {
+      ++gm2_newargc;
+      return;			/* Nothing new here.  */
+    }
+
+  if (gm2_new_decoded_options == gm2_x_decoded_options)
+    {				/* Make new arglist.  */
+      unsigned int i;
+
+      newargsize = (gm2_xargc << 2) + 20;	/* This should handle all.  */
+      gm2_new_decoded_options = XNEWVEC (struct cl_decoded_option, newargsize);
+
+      /* Copy what has been done so far.  */
+      for (i = 0; i < gm2_newargc; ++i)
+	gm2_new_decoded_options[i] = gm2_x_decoded_options[i];
+    }
+
+  if (gm2_newargc == newargsize)
+    fatal_error (input_location, "overflowed output argument list for %qs",
+		 arg->orig_option_with_args_text);
+
+  gm2_new_decoded_options[gm2_newargc++] = *arg;
+}
+
+/* Append an option described by OPT_INDEX, ARG and VALUE to the list
+   being built.  */
+static void
+append_option (size_t opt_index, const char *arg, int value)
+{
+  struct cl_decoded_option decoded;
+
+  generate_option (opt_index, arg, value, CL_DRIVER, &decoded);
+  append_arg (&decoded);
+}
+#endif
 
 /* gen_gm2_libexec, return a libexec string.  */
 
@@ -186,105 +293,7 @@ add_exec_dir (int argc, const char *argv[])
   return "-fcpp-prog=none";
 }
 
-/* fe_generate_option wrap up arg and pass it to fe_save_switch.  */
-
-static void
-fe_generate_option (size_t opt_index, const char *arg, bool joined)
-{
-  const struct cl_option *option = &cl_options[opt_index];
-  char *opt;
-
-  if (joined)
-    {
-      const char *old = option->opt_text;
-      opt = (char *)xmalloc (strlen (old) + strlen (arg) + 1);
-      strcpy (opt, old);
-      strcat (opt, arg);
-    }
-  else
-    opt = xstrdup (option->opt_text);
-
-  if (arg == NULL || joined)
-    fe_save_switch (opt, 0, NULL, true, false);
-  else
-    {
-      const char **x = (const char **)XCNEWVEC (const char **, 2);
-
-      x[0] = xstrdup (arg);
-      x[1] = NULL;
-
-      gcc_assert (opt_index != OPT_l);
-      fe_save_switch (opt, 1, x, true, false);
-    }
-}
-
-/* add_lib add lib to the end of the command line.  */
-
-static void
-add_lib (size_t opt_index, const char *lib, int joined)
-{
-  if (lib == NULL || (strcmp (lib, "") == 0))
-    return;
-
-  fe_generate_option (opt_index, lib, joined);
-}
-
-/* insert_option inserts an option at position index on the command line.  */
-
-static void
-insert_option (unsigned int *in_decoded_options_count,
-               struct cl_decoded_option **in_decoded_options,
-               unsigned int position)
-{
-  struct cl_decoded_option *new_decoded_options;
-  unsigned int i;
-
-  (*in_decoded_options_count)++;
-
-  gcc_assert (position <= (*in_decoded_options_count));
-
-  new_decoded_options
-      = XNEWVEC (struct cl_decoded_option, (*in_decoded_options_count) + 1);
-  for (i = 0; i < position; i++)
-    new_decoded_options[i] = (*in_decoded_options)[i];
-  memset (&new_decoded_options[position], 0,
-          sizeof (struct cl_decoded_option));
-
-  for (i = position; i < (*in_decoded_options_count) - 1; i++)
-    new_decoded_options[i + 1] = (*in_decoded_options)[i];
-  *in_decoded_options = new_decoded_options;
-}
-
-/* add_library adds a library to the command line at arg position.  It
-   returns the number of arguments added.  If libraryname is NULL or
-   empty then zero is returned.  */
-
-static int
-add_library (const char *libraryname, unsigned int *in_decoded_options_count,
-             struct cl_decoded_option **in_decoded_options,
-             unsigned int position)
-{
-  if (libraryname == NULL || (strcmp (libraryname, "") == 0))
-    return 0;
-
-  insert_option (in_decoded_options_count, in_decoded_options, position);
-
-#if defined(DEBUGGING)
-  printf ("going to add -l%s at position=%d  count=%d\n", libraryname,
-            position, *in_decoded_options_count);
-  print_options ("before add_library", *in_decoded_options_count, *in_decoded_options);
-#endif
-
-  generate_option (OPT_l, libraryname, 1, CL_DRIVER,
-                   &(*in_decoded_options)[position]);
-
-#if defined(DEBUGGING)
-  print_options ("after add_library", *in_decoded_options_count, *in_decoded_options);
-#endif
-  return 1;
-}
-
-/* build_archive_path returns a string containing the a path to the
+/* build_archive_path returns a string containing the path to the
    archive defined by libpath and dialectLib.  */
 
 static const char *
@@ -341,68 +350,48 @@ safe_strdup (const char *s)
 /* add_default_combination adds the correct link path and then the
    library name.  */
 
-static void
-add_default_combination (const char *libpath, const char *library,
-                         unsigned int *in_decoded_options_count,
-                         struct cl_decoded_option **in_decoded_options,
-                         unsigned int position)
+static bool
+add_default_combination (const char *libpath, const char *library)
 {
   if (library != NULL)
     {
-      add_lib (OPT_L, build_archive_path (libpath, library), true);
-      add_library (safe_strdup (library), in_decoded_options_count,
-                   in_decoded_options, position);
+      append_option (OPT_L, build_archive_path (libpath, library), 1);
+      append_option (OPT_l, safe_strdup (library), 1);
+      return true;
     }
-}
-
-/* gen_link_path generates a link path for the chosen dialect.  */
-
-static const char *
-gen_link_path (const char *libpath, const char *dialect)
-{
-  return add_include (libpath, dialect);
+  return false;
 }
 
 /* add_default_archives adds the default archives to the end of the
    current command line.  */
 
 static int
-add_default_archives (const char *libpath, const char *libraries,
-                      unsigned int *in_decoded_options_count,
-                      struct cl_decoded_option **in_decoded_options,
-                      unsigned int position)
+add_default_archives (const char *libpath, const char *libraries)
 {
-  const char *prev;
   const char *l = libraries;
   const char *e;
-  char *c;
+  char *libname;
   unsigned int libcount = 0;
 
   do
     {
-      if (libpath == NULL)
-        prev = NULL;
-      else
-        prev = xstrdup (libpath);
-
       e = index (l, ',');
       if (e == NULL)
         {
-          c = xstrdup (l);
+          libname = xstrdup (l);
           l = NULL;
+	  if (add_default_combination (libpath, libname))
+	    libcount++;
+	  free (libname);
         }
       else
         {
-          c = xstrndup (l, e - l);
+          libname = xstrndup (l, e - l);
           l = e + 1;
+	  if (add_default_combination (libpath, libname))
+	    libcount++;
+	  free (libname);
         }
-      add_default_combination (libpath, c, in_decoded_options_count,
-                               in_decoded_options, position + libcount);
-      libcount++;
-      prev = gen_link_path (libpath, c);
-
-      fe_generate_option (OPT_L, prev, true);
-      free (c);
     }
   while ((l != NULL) && (l[0] != (char)0));
   return libcount;
@@ -481,34 +470,11 @@ add_default_includes (const char *libpath, const char *libraries)
           l = e + 1;
         }
       path = add_include (libpath, c);
-      fe_generate_option (OPT_I, path, true);
+      append_option (OPT_I, path, 1);
     }
   while ((l != NULL) && (l[0] != (char)0));
 }
 
-/* purge_include_options remove any -I option found from
-   in_decoded_options.  */
-
-static void
-purge_include_options (unsigned int *in_decoded_options_count,
-                       struct cl_decoded_option **in_decoded_options)
-{
-  struct cl_decoded_option *decoded_options = *in_decoded_options;
-  unsigned int i, j;
-
-  for (i = 0; i < *in_decoded_options_count; i++)
-    {
-      size_t opt = decoded_options[i].opt_index;
-
-      if (opt == OPT_I)
-        {
-          for (j = i; j + 1 < *in_decoded_options_count; j++)
-            decoded_options[j] = decoded_options[j + 1];
-          (*in_decoded_options_count)--;
-        }
-    }
-}
-
 /* library_installed returns true if directory library is found under
    libpath.  */
 
@@ -580,7 +546,6 @@ check_valid_list (const char *libpath, const char *libraries)
   return true;
 }
 
-
 /* add_word returns a new string which has the contents of lib
    appended to list.  If list is NULL then lib is duplicated and
    returned otherwise the list is appended by "," and the contents of
@@ -644,82 +609,264 @@ convert_abbreviations (const char *libraries)
   return full_libraries;
 }
 
-/* lang_specific_driver is invoked if we are compiling/linking a
-   Modula-2 file.  It checks for module paths and linking requirements
-   which are language specific.  */
+
+
+void stop (void) {}
 
 void
 lang_specific_driver (struct cl_decoded_option **in_decoded_options,
-                      unsigned int *in_decoded_options_count,
-                      int *in_added_libraries)
+		      unsigned int *in_decoded_options_count,
+		      int *in_added_libraries)
 {
+  unsigned int argc = *in_decoded_options_count;
+  struct cl_decoded_option *decoded_options = *in_decoded_options;
   unsigned int i;
 
-  /* Nonzero if we saw a `-xfoo' language specification on the command
+  /* True if we saw a `-xfoo' language specification on the command
      line.  This function will add a -xmodula-2 if the user has not
      already placed one onto the command line.  */
   bool seen_x_flag = false;
   const char *language = NULL;
 
+  /* If nonzero, the user gave us the `-p' or `-pg' flag.  */
+  int saw_profile_flag = 0;
+
+  /* What action to take for the c++ runtime library:
+    -1  means we should not link it in.
+     0  means we should link it if it is needed.
+     1  means it is needed and should be linked in.
+     2  means it is needed but should be linked statically.  */
+  int library = 0;
+
+  /* Which c++ runtime library to link.  */
+  stdcxxlib_kind which_library = USE_LIBSTDCXX;
+
   const char *libraries = NULL;
   const char *dialect = DEFAULT_DIALECT;
+  const char *libpath = LIBSUBDIR;
+
+  /* An array used to flag each argument that needs a bit set for
+     LANGSPEC, MATHLIB, or WITHLIBC.  */
+  int *args;
+
+  /* Have we seen -fmod=?  */
+  bool seen_module_extension = false;
 
-  bool seen_module_extension = -1;
+  /* Should the driver perform a linl?  */
   bool linking = true;
-  bool seen_fexceptions = true;
-  const char *libpath;
 
-  /* By default, we add the math library if we have one.  */
-  bool need_math = (strcmp (MATH_LIBRARY, "") == 0);
+  /* "-lm" or "-lmath" if it appears on the command line.  */
+  const struct cl_decoded_option *saw_math = NULL;
+
+  /* "-lc" if it appears on the command line.  */
+  const struct cl_decoded_option *saw_libc = NULL;
+
+  /* By default, we throw on the math library if we have one.  */
+  int need_math = (MATH_LIBRARY[0] != '\0');
+
+  /* 1 if we should add -lpthread to the command-line.  */
+  int need_pthread = 1;
+
+  /* True if we saw -static.  */
+  int static_link = 0;
+
+  /* True if we should add -shared-libgcc to the command-line.  */
+  int shared_libgcc = 1;
+
+  /* Have we seen the -v flag?  */
+  bool verbose = false;
 
-  /* True if we should add -lpthread to the command-line.  */
-  bool need_pthread = true;
+  /* The number of libraries added in.  */
+  int added_libraries;
 
   /* True if we should add -fplugin=m2rte to the command-line.  */
   bool need_plugin = true;
 
-  /* True if we should add -shared-libgcc to the command-line.  */
-  bool shared_libgcc = true;
+  /* True if we should set up include paths and library paths.  */
+  bool allow_libraries = true;
 
-  /* The total number of arguments with the new stuff.  */
-  unsigned int argc = *in_decoded_options_count;
+#if 0
+  stop ();
+  printf ("argc = %d\n", argc);
+  fprintf (stderr, "Incoming:");
+  for (i = 0; i < argc; i++)
+    fprintf (stderr, " %s", decoded_options[i].orig_option_with_args_text);
+  fprintf (stderr, "\n");
+#endif
+
+  gm2_xargc = argc;
+  gm2_x_decoded_options = decoded_options;
+  gm2_newargc = 0;
+  gm2_new_decoded_options = decoded_options;
+  added_libraries = *in_added_libraries;
+  args = XCNEWVEC (int, argc);
+
+  /* First pass through arglist.
+
+     If -nostdlib or a "turn-off-linking" option is anywhere in the
+     command line, don't do any library-option processing (except
+     relating to -x).  */
 
-  /* Initially scan the options for key values.  */
   for (i = 1; i < argc; i++)
     {
-      if ((*in_decoded_options)[i].errors & CL_ERR_MISSING_ARG)
-        continue;  /* Avoid examining arguments of options missing them.  */
-      switch ((*in_decoded_options)[i].opt_index)
-        {
+      const char *arg = decoded_options[i].arg;
+      args[i] = 0;
+#if 0
+      printf ("1st pass: %s\n",
+	      decoded_options[i].orig_option_with_args_text);
+#endif
+#if 0
+      if (decoded_options[i].errors & CL_ERR_MISSING_ARG)
+	continue; /* Avoid examining arguments of options missing them.  */
+#endif
+
+      switch (decoded_options[i].opt_index)
+	{
+	case OPT_fiso:
+	  dialect = "iso";
+	  break;
+	case OPT_fpim2:
+	  dialect = "pim2";
+	  break;
+	case OPT_fpim3:
+	  dialect = "pim3";
+	  break;
+	case OPT_fpim4:
+	  dialect = "pim4";
+	  break;
+	case OPT_fpim:
+	  dialect = "pim";
+	  break;
+	case OPT_flibs_:
+	  libraries = xstrdup (arg);
+	  allow_libraries = decoded_options[i].value;
+	  break;
+	case OPT_fmod_:
+	  seen_module_extension = true;
+	  break;
+	case OPT_version:
+	  gm2_version (true);
+	  break;
+	case OPT_fm2_version:
+	  gm2_version (false);
+	  break;
+
+#if 0
         case OPT_fexceptions:
-          seen_fexceptions = ((*in_decoded_options)[i].value);
+          seen_fexceptions = decoded_options[i].value;
           break;
+#endif
         case OPT_B:
           seen_B = true;
-          B_path = (*in_decoded_options)[i].arg;
+          B_path = decoded_options[i].arg;
           break;
-        case OPT_fno_pthread:
-          need_pthread = false;
+        case OPT_fpthread:
+          need_pthread = decoded_options[i].value;
           break;
-        case OPT_fno_m2_plugin:
-          need_plugin = false;
+        case OPT_fm2_plugin:
+          need_plugin = decoded_options[i].value;
           break;
 	case OPT_fscaffold_dynamic:
 	  seen_scaffold_dynamic = true;
-	  scaffold_dynamic = (*in_decoded_options)[i].value;
+	  scaffold_dynamic = decoded_options[i].value;
 	  break;
 	case OPT_fscaffold_static:
 	  seen_scaffold_static = true;
-	  scaffold_static = (*in_decoded_options)[i].value;
+	  scaffold_static = decoded_options[i].value;
+	  break;
+	case OPT_fgen_module_list_:
+	  seen_gen_module_list = true;
+	  gen_module_list = decoded_options[i].value;
+	  if (gen_module_list)
+	    gen_module_filename = decoded_options[i].arg;
+	  break;
+	case OPT_fuse_list_:
+	  seen_uselist = true;
+	  uselist = decoded_options[i].value;
+	  break;
+	  ///////
+
+	case OPT_nostdlib:
+	case OPT_nostdlib__:
+	case OPT_nodefaultlibs:
+	  library = -1;
+	  break;
+
+	case OPT_l:
+	  if (strcmp (arg, MATH_LIBRARY) == 0)
+	    {
+	      args[i] |= MATHLIB;
+	      need_math = 0;
+	    }
+	  else if (strcmp (arg, "c") == 0)
+	    args[i] |= WITHLIBC;
+	  else
+	    /* Unrecognized libraries (e.g. -lfoo) may require libstdc++.  */
+	    library = (library == 0) ? 1 : library;
 	  break;
+
+	case OPT_pg:
+	case OPT_p:
+	  saw_profile_flag++;
+	  break;
+
+	case OPT_x:
+          seen_x_flag = true;
+          language = arg;
+	  break;
+
+	case OPT_v:
+	  verbose = true;
+	  break;
+
+	case OPT_Xlinker:
+	case OPT_Wl_:
+	  /* Arguments that go directly to the linker might be .o files,
+	     or something, and so might cause libstdc++ to be needed.  */
+	  if (library == 0)
+	    library = 1;
+	  break;
+
+	case OPT_c:
+	case OPT_r:
+	case OPT_S:
+	case OPT_E:
+	case OPT_M:
+	case OPT_MM:
+	case OPT_fsyntax_only:
+	  /* Don't specify libraries if we won't link, since that would
+	     cause a warning.  */
+	  linking = false;
+	  library = -1;
+	  break;
+
+	case OPT_static:
+	  static_link = 1;
+	  break;
+
+	case OPT_static_libgcc:
+	  shared_libgcc = 0;
+	  break;
+
+	case OPT_static_libstdc__:
+	  library = library >= 0 ? 2 : library;
+	  args[i] |= SKIPOPT;
+	  break;
+
+	case OPT_stdlib_:
+	  which_library = (stdcxxlib_kind) decoded_options[i].value;
+	  break;
+
 	default:
-	  if (((*in_decoded_options)[i].orig_option_with_args_text != NULL)
-	      && (strncmp ((*in_decoded_options)[i].orig_option_with_args_text,
+	  if ((decoded_options[i].orig_option_with_args_text != NULL)
+	      && (strncmp (decoded_options[i].orig_option_with_args_text,
 			   "-m", 2) == 0))
-	    multilib_dir = xstrdup ((*in_decoded_options)[i].orig_option_with_args_text
+	    multilib_dir = xstrdup (decoded_options[i].orig_option_with_args_text
 				    + 2);
 	}
     }
+  if (language != NULL && (strcmp (language, "modula-2") != 0))
+    return;
 
   if (scaffold_static && scaffold_dynamic)
     {
@@ -729,139 +876,183 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
 	error ("%qs and %qs cannot both be enabled",
 	       "-fscaffold-dynamic", "-fscaffold-static");
     }
-  libpath = fe_getenv (LIBRARY_PATH_ENV);
-  if (libpath == NULL || (strcmp (libpath, "") == 0))
-    libpath = LIBSUBDIR;
+  if (uselist && gen_module_list)
+    {
+      if (! seen_gen_module_list)
+	gen_module_list = false;
+      if (uselist && gen_module_list)
+	error ("%qs and %qs cannot both be enabled",
+	       "-fgen-module-list=", "-fuse-list=");
+    }
+
 
-#if defined(DEBUGGING)
-  print_options ("after scaffold checking", *in_decoded_options_count, *in_decoded_options);
+  /* There's no point adding -shared-libgcc if we don't have a shared
+     libgcc.  */
+#ifndef ENABLE_SHARED_LIBGCC
+  shared_libgcc = 0;
 #endif
-  i = 1;
-  for (i = 1; i < *in_decoded_options_count; i++)
+
+  /* For libc++, on most platforms, the ABI library (usually called libc++abi)
+     is provided as a separate DSO, which we must also append.
+     However, a platform might have the ability to forward the ABI library
+     from libc++, or combine it in some other way; in that case, LIBCXXABI
+     should be set to NULL to signal that it need not be appended.
+
+     remove this...
+ */
+
+  /* Second pass through arglist, transforming arguments as appropriate.  */
+
+  append_arg (&decoded_options[0]); /* Start with command name, of course.  */
+  for (i = 1; i < argc; ++i)
     {
-      const char *arg = (*in_decoded_options)[i].arg;
-      size_t opt = (*in_decoded_options)[i].opt_index;
+#if 0
+      printf ("2nd pass: %s\n",
+	      decoded_options[i].orig_option_with_args_text);
+#endif
 
-#if defined(DEBUGGING)
-      print_option ("in for", i, *in_decoded_options);
-      printf ("argument: %s, %ld\n", arg, opt);
+      if ((args[i] & SKIPOPT) == 0)
+	{
+	  append_arg (&decoded_options[i]);
+	  /* Make sure -lstdc++ is before the math library, since libstdc++
+	     itself uses those math routines.  */
+	  if (!saw_math && (args[i] & MATHLIB) && library > 0)
+	    saw_math = &decoded_options[i];
+
+	  if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
+	    saw_libc = &decoded_options[i];
+	}
+#if 0
+      else
+	printf ("skipping: %s\n",
+		decoded_options[i].orig_option_with_args_text);
 #endif
-      if ((opt == OPT_c) || (opt == OPT_S))
-        linking = false;
-      if (opt == OPT_I)
-	fe_generate_option (OPT_I, arg, true);
-      if (opt == OPT_fiso)
-        dialect = "iso";
-      if (opt == OPT_fpim2)
-        dialect = "pim2";
-      if (opt == OPT_fpim3)
-        dialect = "pim3";
-      if (opt == OPT_fpim4)
-        dialect = "pim4";
-      if (opt == OPT_fpim)
-        dialect = "pim";
-      if (opt == OPT_flibs_)
-        libraries = xstrdup (arg);
-      if (opt == OPT_fmod_)
-        seen_module_extension = true;
-      if (opt == OPT_version)
-        gm2_version (true);
-      if (opt == OPT_fm2_version)
-        gm2_version (false);
-      if (opt == OPT_x)
-        {
-          seen_x_flag = true;
-          language = arg;
-        }
     }
-  if (language != NULL && (strcmp (language, "modula-2") != 0))
-    return;
-#if defined(DEBUGGING)
-  print_options ("after dialect detection", *in_decoded_options_count, *in_decoded_options);
-#endif
 
-  /* If the libraries have not been specified by the user and the
-     dialect has been specified then select the appropriate libraries.  */
+  /* We now add in extra arguments to facilitate a successful
+     compile or link.  For example include paths for dialect of Modula-2,
+     library paths and default scaffold linking options.  */
 
-  if (libraries == NULL)
+#if 1
+  /* If we have not seen either uselist or gen_module_list and we need
+     to link then we turn on -fgen_module_list=- as the default.  */
+  if ((! (seen_uselist || seen_gen_module_list)) && linking)
+    append_option (OPT_fgen_module_list_, "-", 1);
+#endif
+
+  if (allow_libraries)
     {
-      if (strcmp (dialect, "iso") == 0)
-        libraries = xstrdup ("m2iso,m2pim");
-      else
-        libraries = xstrdup ("m2pim");  /* Default to pim libraries if none specified.  */
-    }
+      /* If the libraries have not been specified by the user and the
+	 dialect has been specified then select the appropriate libraries.  */
 
-  libraries = convert_abbreviations (libraries);
-  if (! check_valid_list (libpath, libraries))
-    return;
+      if (libraries == NULL)
+	{
+	  if (strcmp (dialect, "iso") == 0)
+	    libraries = xstrdup ("m2iso,m2pim");
+	  else
+	    libraries = xstrdup ("m2pim");  /* Default to pim libraries if none
+					       specified.  */
+	}
 
-  add_default_includes (libpath, libraries);
-  if ((!seen_x_flag) && seen_module_extension)
-    fe_generate_option (OPT_x, "modula-2", false);
+      libraries = convert_abbreviations (libraries);
+      if (! check_valid_list (libpath, libraries))
+	return;
+
+#if 1
+      add_default_includes (libpath, libraries);
+    }
+  if ((! seen_x_flag) && seen_module_extension)
+    append_option (OPT_x, "modula-2", 1);
 
   if (need_plugin)
-    fe_generate_option (OPT_fplugin_, "m2rte", true);
+    append_option (OPT_fplugin_, "m2rte", 1);
+#endif
 
   if (linking)
     {
-      if (strcmp (dialect, "iso") == 0)
-	/* We need the pim libraries even if using iso.  */
-        (*in_added_libraries)
-            += add_library ("m2pim", in_decoded_options_count,
-                            in_decoded_options, *in_decoded_options_count);
-
-      (*in_added_libraries) += add_default_archives (
-        libpath, libraries, in_decoded_options_count, in_decoded_options,
-	*in_decoded_options_count);
-
-      if (need_math)
-        (*in_added_libraries)
-            += add_library (MATH_LIBRARY, in_decoded_options_count,
-                            in_decoded_options, *in_decoded_options_count);
-
-      if (need_pthread)
-        (*in_added_libraries)
-            += add_library ("pthread", in_decoded_options_count,
-                            in_decoded_options, *in_decoded_options_count);
-
-      if (seen_fexceptions)
-        (*in_added_libraries)
-            += add_library (LIBSTDCXX, in_decoded_options_count,
-                            in_decoded_options, *in_decoded_options_count);
-
-      /* There is no point adding -shared-libgcc if we don't have a shared
-	 libgcc.  */
-#if !defined(ENABLE_SHARED_LIBGCC)
-      shared_libgcc = false;
+#if 1
+      if (allow_libraries)
+	add_default_archives (libpath, libraries);
 #endif
-      if (shared_libgcc)
-        {
-          fe_generate_option (OPT_shared_libgcc, NULL, false);
-          (*in_added_libraries)
-              += add_library ("gcc_eh", in_decoded_options_count,
-                              in_decoded_options, *in_decoded_options_count);
-        }
-    }
-#if defined(DEBUGGING)
-  print_options ("before include options purge", *in_decoded_options_count, *in_decoded_options);
+      /* Add `-lstdc++' if we haven't already done so.  */
+#ifdef HAVE_LD_STATIC_DYNAMIC
+      if (library > 1 && !static_link)
+	append_option (OPT_Wl_, LD_STATIC_OPTION, 1);
 #endif
-  purge_include_options (in_decoded_options_count, in_decoded_options);
-#if defined(DEBUGGING)
-  print_options ("after include options purge", *in_decoded_options_count, *in_decoded_options);
+      if (which_library == USE_LIBCXX)
+	{
+	  append_option (OPT_l, saw_profile_flag ? LIBCXX_PROFILE : LIBCXX, 1);
+	  added_libraries++;
+	  if (LIBCXXABI != NULL)
+	    {
+	      append_option (OPT_l, saw_profile_flag ? LIBCXXABI_PROFILE
+			     : LIBCXXABI, 1);
+	      added_libraries++;
+	    }
+	}
+      else
+	{
+	  append_option (OPT_l, saw_profile_flag ? LIBSTDCXX_PROFILE
+			 : LIBSTDCXX, 1);
+	  added_libraries++;
+	}
+      /* Add target-dependent static library, if necessary.  */
+      if ((static_link || library > 1) && LIBSTDCXX_STATIC != NULL)
+	{
+	  append_option (OPT_l, LIBSTDCXX_STATIC, 1);
+	  added_libraries++;
+	}
+#ifdef HAVE_LD_STATIC_DYNAMIC
+      if (library > 1 && !static_link)
+	append_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1);
+#endif
+    }
+  if (need_math)
+    {
+      append_option (OPT_l, saw_profile_flag ? MATH_LIBRARY_PROFILE :
+		     MATH_LIBRARY, 1);
+      added_libraries++;
+    }
+  if (need_pthread)
+    {
+      append_option (OPT_l, "pthread", 1);
+      added_libraries++;
+    }
+#if 0
+  if (saw_time)
+    new_decoded_options[j++] = *saw_time;
+  if (saw_libc)
+    new_decoded_options[j++] = *saw_libc;
 #endif
+  if (shared_libgcc && !static_link)
+    append_option (OPT_shared_libgcc, NULL, 1);
+
+  if (verbose && gm2_new_decoded_options != gm2_x_decoded_options)
+    {
+      fprintf (stderr, _("Driving:"));
+      for (i = 0; i < gm2_newargc; i++)
+	fprintf (stderr, " %s",
+		 gm2_new_decoded_options[i].orig_option_with_args_text);
+      fprintf (stderr, "\n");
+      fprintf (stderr, "new argc = %d, added_libraries = %d\n",
+	       gm2_newargc, added_libraries);
+    }
+
+  *in_decoded_options_count = gm2_newargc;
+  *in_decoded_options = gm2_new_decoded_options;
+  *in_added_libraries = added_libraries;
 }
 
-/* lang_specific_pre_link - does nothing.  */
-// --fixme-- remove lang_specific_pre_link here and all other drivers.
-int
-lang_specific_pre_link (void)
+/* Called before linking.  Returns 0 on success and -1 on failure.  */
+int lang_specific_pre_link (void)  /* Not used for C++.  */
 {
   return 0;
 }
 
-/* lang_register_spec_functions register the Modula-2 associated spec
-   functions.  */
+/* Number of extra output files that lang_specific_pre_link may generate.  */
+int lang_specific_extra_outfiles = 0;  /* --fixme-- remove me.  */
 
+/* lang_register_spec_functions.   --fixme-- remove me.  */
 void
 lang_register_spec_functions (void)
 {
diff --git a/gcc/m2/lang.opt b/gcc/m2/lang.opt
index 14176fa6039..b46b6b05325 100644
--- a/gcc/m2/lang.opt
+++ b/gcc/m2/lang.opt
@@ -26,6 +26,14 @@
 Language
 Modula-2
 
+D
+Modula-2
+; Documented in c.opt
+
+E
+Modula-2
+; Documented in c.opt (passed to the preprocessor if -fcpp is used)
+
 I
 Modula-2 Joined Separate
 ; Documented in c.opt
@@ -42,269 +50,269 @@ O
 Modula-2
 ; Documented in c.opt
 
-c
+Wall
 Modula-2
 ; Documented in c.opt
 
-fiso
+Wpedantic
 Modula-2
-use ISO dialect of Modula-2
+; Documented in common.opt
 
-fpim
+Wpedantic-param-names
 Modula-2
-use PIM [234] dialect of Modula-2
+compiler checks to force definition module procedure parameter names with their implementation module counterpart
 
-fpim2
+Wpedantic-cast
 Modula-2
-use PIM 2 dialect of Modula-2
+compiler warns if a cast is being used on types of differing sizes
 
-fpim3
+Wverbose-unbounded
 Modula-2
-use PIM 3 dialect of Modula-2
+inform user which parameters will be passed by reference
 
-fpim4
+Wstyle
 Modula-2
-use PIM 4 dialect of Modula-2
+extra compile time semantic checking, typically tries to catch poor programming style
 
-fpositive-mod-floor-div
+Wunused-variable
 Modula-2
-force positive result from MOD and DIV result floor
+; Documented in c.opt
 
-flibs=
-Modula-2 Joined
-specify the library order, currently legal entries include: log, min, pim, iso or their directory name equivalent m2log, m2min, m2pim, m2iso.
+Wunused-parameter
+Modula-2
+; Documented in c.opt
+
+c
+Modula-2
+; Documented in c.opt
 
 fauto-init
 Modula-2
 automatically initializes all pointers to NIL
 
-flocation=
-Modula-2 Joined
-set all location values to a specific value (internal switch)
-
 fbounds
 Modula-2
 turns on runtime subrange, array index and indirection via NIL pointer checking
 
-freturn
+fcase
 Modula-2
-turns on runtime checking for functions which finish without executing a RETURN statement
+turns on runtime checking to check whether a CASE statement requires an ELSE clause when on was not specified
 
-fnil
+fobjc-std=objc1
 Modula-2
-turns on runtime checking to detect accessing data through a NIL value pointer
+; Documented in c.opt
 
-fcase
+fcpp
 Modula-2
-turns on runtime checking to check whether a CASE statement requires an ELSE clause when on was not specified
+use cpp to preprocess the module
 
-ffloatvalue
+fcpp-end
 Modula-2
-turns on runtime checking to check whether a floating point number is about to exceed range
+passed to the preprocessor if -fcpp is used (internal switch)
 
-fwholevalue
+fcpp-begin
 Modula-2
-turns on runtime checking to check whether a whole number is about to exceed range
+passed to the preprocessor if -fcpp is used (internal switch)
 
-fsoft-check-all
+fcpp-prog=
+Modula-2 Joined
+passed to the preprocessor if -fcpp is used (internal switch)
+
+fdebug-builtins
 Modula-2
-turns on all software runtime checking (an abbreviation for -fnil -frange -findex -fwholediv -fcase -freturn -fwholediv -ffloatvalue)
+call a real function, rather than the builtin equivalent
 
-frange
+fdump-system-exports
 Modula-2
-turns on all range checking for numerical values
+display all inbuilt system items
 
-findex
+fd
 Modula-2
-turns on all range checking for numerical values
+turn on internal debugging of the compiler
 
-fwholediv
+fdebug-trace-quad
 Modula-2
-turns on all division and modulus by zero checking for ordinal values
+turn on quadruple tracing (internal switch)
 
-fexceptions
+fdebug-trace-api
 Modula-2
-; Documented in common.opt
+turn on the Modula-2 api tracing (internal switch)
 
-fextended-opaque
+fdebug-function-line-numbers
 Modula-2
-allows opaque types to be implemented as any type (a GNU Modula-2 extension)
+turn on the Modula-2 function line number generation (internal switch)
 
-fuselist=
+fdef=
 Modula-2 Joined
-orders the initialization/finalializations for scaffold-static or force linking of modules if scaffold-dynamic
+recognise the specified suffix as a definition module filename
 
-fno-pthread
+fexceptions
 Modula-2
-do not link against the pthread library
+; Documented in common.opt
 
-fm2-plugin
+fextended-opaque
 Modula-2
-insert plugin to identify runtime errors at compiletime
+allows opaque types to be implemented as any type (a GNU Modula-2 extension)
 
-fno-m2-plugin
+ffloatvalue
 Modula-2
-do not insert plugin to identify runtime errors at compiletime
+turns on runtime checking to check whether a floating point number is about to exceed range
 
-fscaffold-static
-Modula-2
-generate static scaffold initialization and finalization for every module inside main
+fgen-module-list=
+Modula-2 Joined
+create a topologically sorted module list from all dependent modules used in the application
 
-fscaffold-dynamic
+findex
 Modula-2
-the modules initialization order is dynamically determined by M2RTS and application dependancies
+turns on all range checking for numerical values
 
-fscaffold-c
+fiso
 Modula-2
-generate a C source scaffold for the current module being compiled
+use ISO dialect of Modula-2
 
-fscaffold-c++
-Modula-2
-generate a C++ source scaffold for the current module being compiled
+flibs=
+Modula-2 Joined
+specify the library order, currently legal entries include: log, min, pim, iso or their directory name equivalent m2log, m2min, m2pim, m2iso.
 
-fscaffold-main
+flocation=
+Modula-2 Joined
+set all location values to a specific value (internal switch)
+
+fm2-g
 Modula-2
-generate the main function
+generate extra nops to improve debugging, producing an instruction for every code related keyword
 
-fruntime-modules=
-Modula-2 Joined
-specify the list of runtime modules and their initialization order
+fm2-lower-case
+Modula-2
+generate error messages which render keywords in lower case
 
-fcpp
+fm2-plugin
 Modula-2
-use cpp to preprocess the module
+insert plugin to identify runtime errors at compiletime (default on)
 
-fq
+fm2-statistics
 Modula-2
-internal compiler debugging information, dump the list of quadruples
+display statistics about the amount of source lines compiled and symbols used
 
-fsources
+fm2-strict-type
 Modula-2
-display the location of module source files as they are compiled
+experimental flag to turn on the new strict type checker
 
-funbounded-by-reference
+fm2-version
 Modula-2
-optimize non var unbounded parameters by passing it by reference, providing it is not written to within the callee procedure.
+display the GNU Modula-2 version
 
-fdef=
-Modula-2 Joined
-recognise the specified suffix as a definition module filename
+fm2-whole-program
+Modula-2
+compile all implementation modules and program module at once
 
 fmod=
 Modula-2 Joined
 recognise the specified suffix as implementation and module filenames
 
-fxcode
-Modula-2
-issue all errors and warnings in the Xcode format
-
-fdebug-builtins
-Modula-2
-call a real function, rather than the builtin equivalent
-
-fdump-system-exports
+fnil
 Modula-2
-display all inbuilt system items
+turns on runtime checking to detect accessing data through a NIL value pointer
 
-fd
+fpim
 Modula-2
-turn on internal debugging of the compiler
+use PIM [234] dialect of Modula-2
 
-fdebug-trace-quad
+fpim2
 Modula-2
-turn on quadruple tracing (internal switch)
+use PIM 2 dialect of Modula-2
 
-fdebug-trace-api
+fpim3
 Modula-2
-turn on the Modula-2 api tracing (internal switch)
+use PIM 3 dialect of Modula-2
 
-fdebug-function-line-numbers
+fpim4
 Modula-2
-turn on the Modula-2 function line number generation (internal switch)
+use PIM 4 dialect of Modula-2
 
-fm2-statistics
+fpositive-mod-floor-div
 Modula-2
-display statistics about the amount of source lines compiled and symbols used
+force positive result from MOD and DIV result floor
 
-fm2-g
+fpthread
 Modula-2
-generate extra nops to improve debugging, producing an instruction for every code related keyword
+link against the pthread library (default on)
 
-fm2-lower-case
+fq
 Modula-2
-generate error messages which render keywords in lower case
+internal compiler debugging information, dump the list of quadruples
 
-fm2-strict-type
+frange
 Modula-2
-experimental flag to turn on the new strict type checker
+turns on all range checking for numerical values
 
-fswig
+freturn
 Modula-2
-create a swig interface file for the module
+turns on runtime checking for functions which finish without executing a RETURN statement
 
-fshared
-Modula-2
-generate a shared library from the module
+fruntime-modules=
+Modula-2 Joined
+specify the list of runtime modules and their initialization order
 
-fm2-whole-program
+fscaffold-static
 Modula-2
-compile all implementation modules and program module at once
+generate static scaffold initialization and finalization for every module inside main
 
-fversion
+fscaffold-dynamic
 Modula-2
-; Documented in common.opt
+the modules initialization order is dynamically determined by M2RTS and application dependancies
 
-fm2-version
+fscaffold-c
 Modula-2
-display the GNU Modula-2 version
+generate a C source scaffold for the current module being compiled
 
-Wstudents
+fscaffold-c++
 Modula-2
-extra compile time semantic checking, typically tries to catch bad style
+generate a C++ source scaffold for the current module being compiled
 
-Wpedantic
+fscaffold-main
 Modula-2
-; Documented in common.opt
+generate the main function
 
-Wpedantic-param-names
+fshared
 Modula-2
-compiler checks to force definition module procedure parameter names with their implementation module counterpart
+generate a shared library from the module
 
-Wpedantic-cast
+fsoft-check-all
 Modula-2
-compiler warns if a cast is being used on types of differing sizes
+turns on all software runtime checking (an abbreviation for -fnil -frange -findex -fwholediv -fcase -freturn -fwholediv -ffloatvalue)
 
-Wverbose-unbounded
+fsources
 Modula-2
-inform user which parameters will be passed by reference
+display the location of module source files as they are compiled
 
-Wall
+fswig
 Modula-2
-; Documented in c.opt
+create a swig interface file for the module
 
-Wunused-variable
+funbounded-by-reference
 Modula-2
-; Documented in c.opt
+optimize non var unbounded parameters by passing it by reference, providing it is not written to within the callee procedure.
 
-Wunused-parameter
-Modula-2
-; Documented in c.opt
+fuse-list=
+Modula-2 Joined
+orders the initialization/finalializations for scaffold-static or force linking of modules if scaffold-dynamic
 
-version
+fversion
 Modula-2
-; Documented in c.opt
+; Documented in common.opt
 
-v
+fwholediv
 Modula-2
-; Documented in c.opt
+turns on all division and modulus by zero checking for ordinal values
 
-lang-asm
+fwholevalue
 Modula-2
-; Documented in c.opt
+turns on runtime checking to check whether a whole number is about to exceed range
 
-traditional-cpp
+fxcode
 Modula-2
-; Documented in c.opt
+issue all errors and warnings in the Xcode format
 
 iprefix
 Modula-2
@@ -322,43 +330,35 @@ imultilib
 Modula-2
 ; Documented in c.opt
 
-fobjc-std=objc1
+lang-asm
 Modula-2
 ; Documented in c.opt
 
-fcpp-end
-Modula-2
-passed to the preprocessor if -fcpp is used (internal switch)
+-save-temps
+Modula-2 Alias(save-temps)
 
-fcpp-begin
+save-temps
 Modula-2
-passed to the preprocessor if -fcpp is used (internal switch)
+save temporary preprocessed files
 
-fcpp-prog=
+save-temps=
 Modula-2 Joined
-passed to the preprocessor if -fcpp is used (internal switch)
+save temporary preprocessed files
 
-E
+traditional-cpp
 Modula-2
-; Documented in c.opt (passed to the preprocessor if -fcpp is used)
+; Documented in c.opt
 
-D
+v
 Modula-2
 ; Documented in c.opt
 
-x
-Modula-2 Joined
-specify the language from the compiler driver
-
--save-temps
-Modula-2 Alias(save-temps)
-
-save-temps
+version
 Modula-2
-save temporary preprocessed files
+; Documented in c.opt
 
-save-temps=
+x
 Modula-2 Joined
-save temporary preprocessed files
+specify the language from the compiler driver
 
 ; This comment is to ensure we retain the blank line above.
diff --git a/gcc/m2/m2.flex b/gcc/m2/m2.flex
index ed3721533b6..0709aae8e25 100644
--- a/gcc/m2/m2.flex
+++ b/gcc/m2/m2.flex
@@ -66,7 +66,7 @@ along with GNU Modula-2; see the file COPYING3.  If not see
     int              tokenpos;         /* start position of token within line */
     int              toklen;           /* a copy of yylen (length of token) */
     int              nextpos;          /* position after token */
-    int              actualline;       /* line number of this line */
+    int              lineno;           /* line number of this line */
     int              column;           /* first column number of token on this line */
     int              inuse;            /* do we need to keep this line info? */
     location_t       location;         /* the corresponding gcc location_t */
@@ -301,7 +301,7 @@ VOLATILE                   { updatepos(); M2LexBuf_AddTok(M2Reserved_volatiletok
 [0-9]+B                    { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
 [0-9]+C                    { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
 [0-9A-F]+H                 { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
-[\t\r ]+                   { currentLine->tokenpos += yyleng;  /* ignore whitespace */; }
+[\t\r ]+                   { currentLine->tokenpos += yyleng;  /* Ignore space.  */; }
 .                          { updatepos(); m2flex_M2Error("unrecognised symbol"); skippos(); }
 
 %%
@@ -457,15 +457,15 @@ EXTERN void m2flex_M2Error (const char *s)
   if (currentLine->linebuf != NULL) {
     int i=1;
 
-    printf("%s:%d:%s\n", filename, currentLine->actualline, currentLine->linebuf);
-    printf("%s:%d:%*s", filename, currentLine->actualline, 1+currentLine->tokenpos, "^");
+    printf("%s:%d:%s\n", filename, currentLine->lineno, currentLine->linebuf);
+    printf("%s:%d:%*s", filename, currentLine->lineno, 1+currentLine->tokenpos, "^");
     while (i<currentLine->toklen) {
       putchar('^');
       i++;
     }
     putchar('\n');
   }
-  printf("%s:%d:%s\n", filename, currentLine->actualline, s);
+  printf("%s:%d:%s\n", filename, currentLine->lineno, s);
 }
 
 static void poperrorskip (const char *s)
@@ -495,7 +495,7 @@ static void consumeLine (void)
   strcpy(currentLine->linebuf, yytext+1);  /* copy all except the initial \n */
   lineno++;
   totalLines++;
-  currentLine->actualline = lineno;
+  currentLine->lineno = lineno;
   currentLine->tokenpos=0;
   currentLine->nextpos=0;
   currentLine->column=0;
@@ -508,7 +508,7 @@ static void assert_location (location_t location ATTRIBUTE_UNUSED)
 #if 0
   if ((location != BUILTINS_LOCATION) && (location != UNKNOWN_LOCATION) && (! M2Options_GetCpp ())) {
      expanded_location xl = expand_location (location);
-     if (xl.line != currentLine->actualline) {
+     if (xl.line != currentLine->lineno) {
        m2flex_M2Error ("mismatched gcc location and front end token number");
      }
   }
@@ -582,7 +582,7 @@ static void initLine (void)
   currentLine->tokenpos   = 0;
   currentLine->toklen     = 0;
   currentLine->nextpos    = 0;
-  currentLine->actualline = lineno;
+  currentLine->lineno = lineno;
   currentLine->column     = 0;
   currentLine->inuse      = TRUE;
   currentLine->next       = NULL;
@@ -609,7 +609,7 @@ static void pushLine (void)
       l->tokenpos   = currentLine->tokenpos;
       l->toklen     = currentLine->toklen;
       l->nextpos    = currentLine->nextpos;
-      l->actualline = currentLine->actualline;
+      l->lineno = currentLine->lineno;
       l->column     = currentLine->column;
       l->next       = currentLine;
       currentLine   = l;
@@ -678,7 +678,7 @@ EXTERN void m2flex_CloseSource (void)
 }
 
 /*
- *  OpenSource - returns TRUE if file, s, can be opened and
+ *  OpenSource - returns TRUE if file s can be opened and
  *               all tokens are taken from this file.
  */
 
@@ -690,20 +690,24 @@ EXTERN int m2flex_OpenSource (char *s)
     return( FALSE );
   else {
     isDefinitionModule = FALSE;
-    while (currentFunction != NULL) {
-      struct functionInfo *f = currentFunction;
-      currentFunction = f->next;
-      if (f->name != NULL)
-	free(f->name);
-      free(f);
-    }
-    yy_delete_buffer(YY_CURRENT_BUFFER);
-    yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
-    filename = xstrdup(s);
+    while (currentFunction != NULL)
+      {
+	struct functionInfo *f = currentFunction;
+        currentFunction = f->next;
+        if (f->name != NULL)
+  	  free(f->name);
+      	free(f);
+      }
+    yy_delete_buffer (YY_CURRENT_BUFFER);
+    yy_switch_to_buffer (yy_create_buffer(f, YY_BUF_SIZE));
+    filename = xstrdup (s);
     lineno = 1;
-    if (currentLine != NULL)
-      currentLine->actualline = lineno;
+    if (currentLine == NULL)
+      pushLine ();
+    else
+      currentLine->lineno = lineno;
     START_FILE (filename, lineno);
+    BEGIN INITIAL; resetpos ();
     return TRUE;
   }
 }
@@ -715,7 +719,7 @@ EXTERN int m2flex_OpenSource (char *s)
 EXTERN int m2flex_GetLineNo (void)
 {
   if (currentLine != NULL)
-    return currentLine->actualline;
+    return currentLine->lineno;
   else
     return 0;
 }
diff --git a/gcc/m2/tools-src/makeSystem b/gcc/m2/tools-src/makeSystem
index 2ff23336d8b..4ff8603d1ed 100755
--- a/gcc/m2/tools-src/makeSystem
+++ b/gcc/m2/tools-src/makeSystem
@@ -94,7 +94,7 @@ MINIMAL="-fno-scaffold-main -fno-scaffold-dynamic -fno-scaffold-static -fno-m2-p
 rm -f ${OUTPUTFILE}
 if ${COMPILER} ${DIALECT} ${LIBRARY} ${MINIMAL} \
 	       -c -fdump-system-exports ${SYSTEMMOD} -o /dev/null 2>&1 > /dev/null ; then
-    types=`${COMPILER} ${DIALECT} ${LIBRARY} -fno-m2-plugin -c -fdump-system-exports ${SYSTEMMOD} -o /dev/null | cut -f5 -d' '`
+    types=`${COMPILER} ${DIALECT} ${LIBRARY} ${MINIMAL} -fno-m2-plugin -c -fdump-system-exports ${SYSTEMMOD} -o /dev/null | cut -f5 -d' '`
     touch ${OUTPUTFILE}
     displayStart
     displayExportedTypes
diff --git a/gcc/testsuite/gm2/calling-c/datatypes/unbounded/run/pass/calling-c-datatypes-unbounded-run-pass.exp b/gcc/testsuite/gm2/calling-c/datatypes/unbounded/run/pass/calling-c-datatypes-unbounded-run-pass.exp
index c526f40db05..ba2231e5f62 100644
--- a/gcc/testsuite/gm2/calling-c/datatypes/unbounded/run/pass/calling-c-datatypes-unbounded-run-pass.exp
+++ b/gcc/testsuite/gm2/calling-c/datatypes/unbounded/run/pass/calling-c-datatypes-unbounded-run-pass.exp
@@ -29,7 +29,7 @@ load_lib gm2-torture.exp
 set gm2src ${srcdir}/../m2
 
 gm2_init_pim "${srcdir}/gm2/calling-c/datatypes/unbounded/run/pass"
-gm2_link_with "c.o -lm2pim -lm2iso -lpthread"
+gm2_link_obj "c.o"
 
 set output [target_compile $srcdir/$subdir/c.c c.o object "-g"]
 
@@ -39,6 +39,5 @@ foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
 	continue
     }
 
-    gm2_target_compile $srcdir/$subdir/m.mod m.o object "-g"
     gm2-torture-execute $testcase "" "pass"
 }
diff --git a/gcc/testsuite/gm2/calling-c/datatypes/unbounded/run/pass/m.mod b/gcc/testsuite/gm2/calling-c/datatypes/unbounded/run/pass/m.mod
index 29806e3f74f..45be253692d 100644
--- a/gcc/testsuite/gm2/calling-c/datatypes/unbounded/run/pass/m.mod
+++ b/gcc/testsuite/gm2/calling-c/datatypes/unbounded/run/pass/m.mod
@@ -38,5 +38,5 @@ END farrayofchar ;
 
 
 BEGIN
-   farrayofchar('hello')
+   farrayofchar ('hello')
 END m.
diff --git a/gcc/testsuite/gm2/complex/run/pass/complex-run-pass.exp b/gcc/testsuite/gm2/complex/run/pass/complex-run-pass.exp
index c8fe55265a1..081061c7148 100644
--- a/gcc/testsuite/gm2/complex/run/pass/complex-run-pass.exp
+++ b/gcc/testsuite/gm2/complex/run/pass/complex-run-pass.exp
@@ -27,8 +27,10 @@ load_lib gm2-torture.exp
 
 set gm2src ${srcdir}/../gm2
 
+gm2_link_lib "m2iso m2pim"
 gm2_init_iso "${srcdir}/gm2/complex/run/pass"
 
+
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
     # If we're only testing specific files and this isn't one of them, skip it.
     if ![runtest_file_p $runtests $testcase] then {
diff --git a/gcc/testsuite/gm2/coroutines/pim/run/pass/coroutines-pim-run-pass.exp b/gcc/testsuite/gm2/coroutines/pim/run/pass/coroutines-pim-run-pass.exp
index e7f5b9563bd..ec4bb0d7875 100644
--- a/gcc/testsuite/gm2/coroutines/pim/run/pass/coroutines-pim-run-pass.exp
+++ b/gcc/testsuite/gm2/coroutines/pim/run/pass/coroutines-pim-run-pass.exp
@@ -28,7 +28,6 @@ load_lib gm2-torture.exp
 set gm2src ${srcdir}/../gm2
 
 gm2_init_cor
-gm2_link_with "-lm2cor -lm2pim -lm2iso"
 
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
     # If we're only testing specific files and this isn't one of them, skip it.
diff --git a/gcc/testsuite/gm2/examples/callingC/run/pass/examples-callingC-run-pass.exp b/gcc/testsuite/gm2/examples/callingC/run/pass/examples-callingC-run-pass.exp
index 976c23ae0e9..04afa7c2621 100644
--- a/gcc/testsuite/gm2/examples/callingC/run/pass/examples-callingC-run-pass.exp
+++ b/gcc/testsuite/gm2/examples/callingC/run/pass/examples-callingC-run-pass.exp
@@ -28,7 +28,7 @@ load_lib gm2-torture.exp
 set gm2src ${srcdir}/../m2
 
 gm2_init_iso "$srcdir/$subdir"
-gm2_link_with "c.o"
+gm2_link_obj "c.o"
 
 set output [target_compile $srcdir/$subdir/c.c c.o object "-g"]
 
diff --git a/gcc/testsuite/gm2/exceptions/run/pass/cpp.cpp b/gcc/testsuite/gm2/exceptions/run/pass/cpp.cpp
index b318bc4c2b6..bc0d5838db4 100644
--- a/gcc/testsuite/gm2/exceptions/run/pass/cpp.cpp
+++ b/gcc/testsuite/gm2/exceptions/run/pass/cpp.cpp
@@ -6,5 +6,6 @@ extern "C" void cpp_mytry (void)
   throw (int)9;
 }
 
+extern "C" void _M2_cpp_ctor (void) {}
 extern "C" void _M2_cpp_init (void) {}
 extern "C" void _M2_cpp_finish (void) {}
diff --git a/gcc/testsuite/gm2/exceptions/run/pass/exceptions-run-pass.exp b/gcc/testsuite/gm2/exceptions/run/pass/exceptions-run-pass.exp
index 9616ff11c06..7b3d898c0a5 100644
--- a/gcc/testsuite/gm2/exceptions/run/pass/exceptions-run-pass.exp
+++ b/gcc/testsuite/gm2/exceptions/run/pass/exceptions-run-pass.exp
@@ -29,6 +29,7 @@ load_lib gm2-torture.exp
 
 
 set output [target_compile $srcdir/$subdir/cpp.cpp cpp.o object "-g"]
+set output [target_compile $srcdir/$subdir/mycpp.cpp mycpp.o object "-g"]
 
 #
 #  notice this uses PIM libraries with exceptions - this is a useful test.
@@ -38,13 +39,16 @@ set output [target_compile $srcdir/$subdir/cpp.cpp cpp.o object "-g"]
 set gm2src ${srcdir}/../m2
 
 gm2_init_pim "${srcdir}/gm2/exceptions/run/pass"
-gm2_link_with "cpp.o"
+set output [gm2_target_compile $srcdir/$subdir/m2test.mod m2test.o object "-g"]
+
+gm2_link_obj "cpp.o mycpp.o m2test.o"
 
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
     # If we're only testing specific files and this isn't one of them, skip it.
     if ![runtest_file_p $runtests $testcase] then {
 	continue
     }
-
-    gm2-torture-execute $testcase "" "pass"
+    if { $testcase ne "$srcdir/$subdir/m2test.mod" } {
+	gm2-torture-execute $testcase "" "pass"
+    }
 }
diff --git a/gcc/testsuite/gm2/exceptions/run/pass/m2test.mod b/gcc/testsuite/gm2/exceptions/run/pass/m2test.mod
index 24e6ef22941..be46b4ded2b 100644
--- a/gcc/testsuite/gm2/exceptions/run/pass/m2test.mod
+++ b/gcc/testsuite/gm2/exceptions/run/pass/m2test.mod
@@ -22,7 +22,7 @@ IMPORT mycpp ;
 
 PROCEDURE try ;
 BEGIN
-   THROW(1)
+   THROW (1)
 END try ;
 
 END m2test.
diff --git a/gcc/testsuite/gm2/exceptions/run/pass/mycpp.cpp b/gcc/testsuite/gm2/exceptions/run/pass/mycpp.cpp
index 1baf922b6e8..30178908803 100644
--- a/gcc/testsuite/gm2/exceptions/run/pass/mycpp.cpp
+++ b/gcc/testsuite/gm2/exceptions/run/pass/mycpp.cpp
@@ -47,3 +47,7 @@ extern "C" void _M2_mycpp_init (void)
 extern "C" void _M2_mycpp_finish (void)
 {
 }
+
+extern "C" void _M2_mycpp_ctor (void)
+{
+}
diff --git a/gcc/testsuite/gm2/extensions/run/pass/extensions-run-pass.exp b/gcc/testsuite/gm2/extensions/run/pass/extensions-run-pass.exp
index 40d40fb6e50..24e8f3ea45f 100644
--- a/gcc/testsuite/gm2/extensions/run/pass/extensions-run-pass.exp
+++ b/gcc/testsuite/gm2/extensions/run/pass/extensions-run-pass.exp
@@ -28,7 +28,7 @@ load_lib gm2-torture.exp
 set gm2src ${srcdir}/../m2
 
 gm2_init_pim "${srcdir}/gm2/extensions/run/pass" -fsoft-check-all
-gm2_link_with "cvararg.o"
+gm2_link_obj "cvararg.o"
 
 set output [target_compile $srcdir/$subdir/cvararg.c cvararg.o object "-g"]
 
diff --git a/gcc/testsuite/gm2/imports/run/pass/imports-run-pass.exp b/gcc/testsuite/gm2/imports/run/pass/imports-run-pass.exp
index 10b471f9e0a..f47d4fa82d9 100644
--- a/gcc/testsuite/gm2/imports/run/pass/imports-run-pass.exp
+++ b/gcc/testsuite/gm2/imports/run/pass/imports-run-pass.exp
@@ -28,6 +28,7 @@ load_lib gm2-torture.exp
 set gm2src ${srcdir}/../m2
 
 gm2_init_pim "${srcdir}/gm2/imports/run/pass"
+gm2_link_obj "c.o"
 
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
     set output [gm2_target_compile ${srcdir}/${subdir}/c.mod c.o object "-g -I${gccpath}/libgm2/libpim:${gm2src}/gm2-libs:${srcdir}/${subdir} -fpim"]
@@ -37,5 +38,7 @@ foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
 	continue
     }
 
-    gm2-torture-execute $testcase "" "pass"
+    if { $testcase ne "$srcdir/$subdir/c.mod" } {
+	gm2-torture-execute $testcase "" "pass"
+    }
 }
diff --git a/gcc/testsuite/gm2/iso/run/pass/iso-run-pass.exp b/gcc/testsuite/gm2/iso/run/pass/iso-run-pass.exp
index ec9a473fbef..443c28d60fb 100644
--- a/gcc/testsuite/gm2/iso/run/pass/iso-run-pass.exp
+++ b/gcc/testsuite/gm2/iso/run/pass/iso-run-pass.exp
@@ -24,8 +24,9 @@ if $tracelevel then {
 # load support procs
 load_lib gm2-torture.exp
 
+gm2_link_lib "m2iso m2pim"
 gm2_init_iso "${srcdir}/gm2/iso/run/pass" -fsoft-check-all
-gm2_link_with fileio.o
+gm2_link_obj fileio.o
 
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
     # If we're only testing specific files and this isn't one of them, skip it.
diff --git a/gcc/testsuite/gm2/link/externalscaffold/pass/link-externalscaffold-pass.exp b/gcc/testsuite/gm2/link/externalscaffold/pass/link-externalscaffold-pass.exp
index 7b221b4ac28..2df83e4bc50 100644
--- a/gcc/testsuite/gm2/link/externalscaffold/pass/link-externalscaffold-pass.exp
+++ b/gcc/testsuite/gm2/link/externalscaffold/pass/link-externalscaffold-pass.exp
@@ -25,8 +25,9 @@ if $tracelevel then {
 # load support procs
 load_lib gm2-torture.exp
 
+gm2_link_lib "m2pim"
 gm2_init_pim "${srcdir}/gm2/pim/pass" -fscaffold-main -fno-scaffold-dynamic
-gm2_link_with scaffold.o
+gm2_link_obj scaffold.o
 set output [target_compile $srcdir/$subdir/scaffold.c scaffold.o object "-g"]
 
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
diff --git a/gcc/testsuite/gm2/linking/libarchive/pass/linking-libarchive-pass.exp b/gcc/testsuite/gm2/linking/libarchive/pass/linking-libarchive-pass.exp
index d1137cc82eb..2ca30e84fb0 100644
--- a/gcc/testsuite/gm2/linking/libarchive/pass/linking-libarchive-pass.exp
+++ b/gcc/testsuite/gm2/linking/libarchive/pass/linking-libarchive-pass.exp
@@ -29,7 +29,7 @@ set gm2src ${srcdir}/../gm2
 
 gm2_init_iso "${srcdir}/gm2/linking/libarchive/pass"
 
-gm2_link_with c.o
+gm2_link_obj "c.o m.o"
 set output [target_compile $srcdir/$subdir/c.c c.o object "-g"]
 
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
@@ -38,6 +38,8 @@ foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
 	continue
     }
 
-    gm2_target_compile $srcdir/$subdir/m.mod m.o object "-g"
-    gm2-torture-execute $testcase "" "pass"
+    if { $testcase ne "$srcdir/$subdir/m.mod" } {
+	gm2_target_compile $srcdir/$subdir/m.mod m.o object "-g"
+	gm2-torture-execute $testcase "" "pass"
+    }
 }
diff --git a/gcc/testsuite/gm2/pim/no-options/run/pass/pim-no-options-run-pass.exp b/gcc/testsuite/gm2/pim/no-options/run/pass/pim-no-options-run-pass.exp
index 321b2c6ffb6..31cb0ed738e 100644
--- a/gcc/testsuite/gm2/pim/no-options/run/pass/pim-no-options-run-pass.exp
+++ b/gcc/testsuite/gm2/pim/no-options/run/pass/pim-no-options-run-pass.exp
@@ -27,7 +27,6 @@ load_lib gm2-torture.exp
 set gm2src ${srcdir}/../m2
 
 gm2_init_pim "${srcdir}/gm2/pim/no-options/run/pass/" -g
-gm2_link_with "-lm2pim -lm2iso -lpthread"
 
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
     # If we're only testing specific files and this isn't one of them, skip it.
diff --git a/gcc/testsuite/gm2/pim/options/optimize/run/pass/pim-options-optimize-run-pass.exp b/gcc/testsuite/gm2/pim/options/optimize/run/pass/pim-options-optimize-run-pass.exp
index 8f77e9c3909..1a4ad54ed50 100644
--- a/gcc/testsuite/gm2/pim/options/optimize/run/pass/pim-options-optimize-run-pass.exp
+++ b/gcc/testsuite/gm2/pim/options/optimize/run/pass/pim-options-optimize-run-pass.exp
@@ -22,88 +22,35 @@ if $tracelevel then {
 }
 
 # load support procs
-load_lib gm2-torture.exp
-
-gm2_set_compile_method "options_optimize"
-
-#
-# gm2_target_compile_options_optimize -- (overload the library function with our local
-#                                         copy, compile a source file)
-#
-
-proc gm2_target_compile_options_optimize { source dest type options } {
-    global srcdir;
-    global subdir;
-    global tmpdir;
-    global gluefile wrap_flags;
-    global GCC_UNDER_TEST
-    global TOOL_OPTIONS
-
-    send_log "successfully overloaded gm2_target_compile source = $source dest = $dest type = $type options = $options\n"
-    if {[target_info needs_status_wrapper] != "" && \
-	    [target_info needs_status_wrapper] != "0" && \
-	    [info exists gluefile] } {
-	lappend options "libs=${gluefile}"
-	lappend options "ldflags=$wrap_flags"
-    }
-
-    if [target_info exists gcc,stack_size] {
-	lappend options "additional_flags=-DSTACK_SIZE=[target_info gcc,stack_size]"
-    }
-    if [target_info exists gcc,no_trampolines] {
-	lappend options "additional_flags=-DNO_TRAMPOLINES"
-    }
-    if [target_info exists gcc,no_label_values] {
-	lappend options "additional_flags=-DNO_LABEL_VALUES"
-    }
-    if [info exists TOOL_OPTIONS] {
-	lappend options "additional_flags=$TOOL_OPTIONS"
-    }
-    if [target_info exists gcc,timeout] {
-	lappend options "timeout=[target_info gcc,timeout]"
-    }
-    lappend options "compiler=$GCC_UNDER_TEST"
 
-    # firstly we compile the library file
-    send_log "about to call target_compile with ${srcdir}/gm2/pim/options/optimize/run/pass/addition.mod dest = $dest type = object options = $options\n"
-
-    set comp_output [target_compile "${srcdir}/gm2/pim/options/optimize/run/pass/addition.mod" addition.o object "$options"]
-    gm2_check_compile "${srcdir}/gm2/pim/options/optimize/run/pass/addition.mod compilation" "$options" "addition.o" $comp_output
-    send_log "$comp_output\n"
-    set comp_output [exec file addition.o]
-    send_log "$comp_output\n"
-
-    # now compile the main source file
-
-    send_log "about to call target_compile with $source $dest $type $options\n"
-    return [target_compile $source $dest $type $options]
-}
+load_lib gm2-torture.exp
 
 set gm2src ${srcdir}/../m2
 
-gm2_init_pim "${srcdir}/gm2/pim/options/optimize/run/pass"
-gm2_link_with "addition.o"
+gm2_init_pim "${srcdir}/gm2/pim/options/optimize/run/pass/"
 
-#
-#  compile library file
-#
+set copy_gm2_link_path ${gm2_link_path};
+set copy_gm2_link_objects ${gm2_link_objects};
+set gm2_link_objects "";
+set gm2_link_path "";
 
-verbose "option=$option" 1
+foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
+    global gm2_link_objects;
+    global gm2_link_path;
 
-
-#
-#  now compile test cases and link to library file
-#
-
-foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/testadd.mod]] {
     # If we're only testing specific files and this isn't one of them, skip it.
     if ![runtest_file_p $runtests $testcase] then {
 	continue
     }
 
-    set output [exec rm -f addition.o]
-    gm2-torture-execute $testcase "" "pass"
-    set output [exec rm -f addition.o]
+    if { $testcase ne "$srcdir/$subdir/addition.mod" } {
+	set output [exec rm -f addition.o];
+	set gm2_link_objects "";
+	set gm2_link_path "";
+	set output [gm2_target_compile $srcdir/$subdir/addition.mod addition.o object "-g"]
+	set gm2_link_path ${copy_gm2_link_path};
+	# set gm2_link_objects
+	gm2_link_obj "addition.o"
+	gm2-torture-execute $testcase "" "pass"
+    }
 }
-
-gm2_set_compile_method "default"
diff --git a/gcc/testsuite/gm2/pim/run/fail/pim-run-fail.exp b/gcc/testsuite/gm2/pim/run/fail/pim-run-fail.exp
index aef2ab85f58..652b5484210 100644
--- a/gcc/testsuite/gm2/pim/run/fail/pim-run-fail.exp
+++ b/gcc/testsuite/gm2/pim/run/fail/pim-run-fail.exp
@@ -27,7 +27,6 @@ load_lib gm2-torture.exp
 set gm2src ${srcdir}/../m2
 
 gm2_init_pim "${srcdir}../gm2/pim/run/fail" -fsoft-check-all -fno-m2-plugin
-gm2_link_with "-lm2pim -lm2iso -lpthread"
 
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
     # If we're only testing specific files and this isn't one of them, skip it.
diff --git a/gcc/testsuite/gm2/pim/run/pass/pim-run-pass.exp b/gcc/testsuite/gm2/pim/run/pass/pim-run-pass.exp
index 329af84abd2..578533d376d 100644
--- a/gcc/testsuite/gm2/pim/run/pass/pim-run-pass.exp
+++ b/gcc/testsuite/gm2/pim/run/pass/pim-run-pass.exp
@@ -27,7 +27,8 @@ load_lib gm2-torture.exp
 set gm2src ${srcdir}/../m2
 
 gm2_init_pim "${srcdir}/gm2/pim/run/pass"
-gm2_link_with sys.o
+gm2_link_obj "sys.o"
+
 
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
     set output [gm2_target_compile $srcdir/$subdir/sys.mod sys.o object "-g -I$srcdir/../m2/gm2-libs -I$srcdir/$subdir -I$srcdir/../m2/gm2-compiler -I../m2/gm2-libs -I../m2/gm2-compiler -fpim"]
diff --git a/gcc/testsuite/gm2/pimcoroutines/run/pass/pimcoroutines-run-pass.exp b/gcc/testsuite/gm2/pimcoroutines/run/pass/pimcoroutines-run-pass.exp
index 15498a32173..f04f8285fb0 100644
--- a/gcc/testsuite/gm2/pimcoroutines/run/pass/pimcoroutines-run-pass.exp
+++ b/gcc/testsuite/gm2/pimcoroutines/run/pass/pimcoroutines-run-pass.exp
@@ -27,8 +27,6 @@ load_lib gm2-torture.exp
 set gm2src ${srcdir}/../m2
 
 gm2_init_cor "${srcdir}/gm2/pim/run/pass"
-# gm2_link_with "-flibs=cor,pim,iso"
-gm2_link_with "-lm2cor -lm2pim -lm2iso"
 
 
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
diff --git a/gcc/testsuite/gm2/pimlib/logitech/run/pass/pimlib-logitech-run-pass.exp b/gcc/testsuite/gm2/pimlib/logitech/run/pass/pimlib-logitech-run-pass.exp
index 1a10a77cd72..4136d9e0ca3 100644
--- a/gcc/testsuite/gm2/pimlib/logitech/run/pass/pimlib-logitech-run-pass.exp
+++ b/gcc/testsuite/gm2/pimlib/logitech/run/pass/pimlib-logitech-run-pass.exp
@@ -27,10 +27,9 @@ load_lib gm2-torture.exp
 
 set gm2src ${srcdir}/../m2
 
+gm2_link_lib "m2log m2pim m2iso"
 gm2_init_log
 
-gm2_link_with "-lm2log"
-
 
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
     # If we're only testing specific files and this isn't one of them, skip it.
diff --git a/gcc/testsuite/gm2/pimlib/run/pass/pimlib-run-pass.exp b/gcc/testsuite/gm2/pimlib/run/pass/pimlib-run-pass.exp
index b2078c62d05..d88caa2d3e6 100644
--- a/gcc/testsuite/gm2/pimlib/run/pass/pimlib-run-pass.exp
+++ b/gcc/testsuite/gm2/pimlib/run/pass/pimlib-run-pass.exp
@@ -27,9 +27,9 @@ load_lib gm2-torture.exp
 
 set gm2src ${srcdir}/../m2
 
+gm2_link_lib "m2pim m2log m2iso"
 gm2_init_log
 
-gm2_link_with "-lm2log"
 
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
     # If we're only testing specific files and this isn't one of them, skip it.
diff --git a/gcc/testsuite/gm2/sets/run/pass/sets-run-pass.exp b/gcc/testsuite/gm2/sets/run/pass/sets-run-pass.exp
index 96670450fc9..d952ac8fb5d 100644
--- a/gcc/testsuite/gm2/sets/run/pass/sets-run-pass.exp
+++ b/gcc/testsuite/gm2/sets/run/pass/sets-run-pass.exp
@@ -27,6 +27,7 @@ load_lib gm2-torture.exp
 
 set gm2src ${srcdir}/../m2
 
+gm2_link_lib "m2iso m2pim"
 gm2_init_iso "${srcdir}/gm2/sets/run/pass/"
 
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
diff --git a/gcc/testsuite/gm2/switches/check-all/run/fail/switches-check-all-run-fail.exp b/gcc/testsuite/gm2/switches/check-all/run/fail/switches-check-all-run-fail.exp
index 2bdd9ddd974..05e5708c09f 100644
--- a/gcc/testsuite/gm2/switches/check-all/run/fail/switches-check-all-run-fail.exp
+++ b/gcc/testsuite/gm2/switches/check-all/run/fail/switches-check-all-run-fail.exp
@@ -34,7 +34,7 @@ gm2_init_pim "${srcdir}/gm2/switches/check-all/run/fail" -fsoft-check-all -fno-m
 #
 
 gm2_target_compile $srcdir/$subdir/rangesupport.mod rangesupport.o object "-g -I$srcdir/$subdir/"
-gm2_link_with rangesupport.o
+gm2_link_obj rangesupport.o
 
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
     # If we're only testing specific files and this isn't one of them, skip it.
diff --git a/gcc/testsuite/gm2/switches/none/run/pass/gm2-none.exp b/gcc/testsuite/gm2/switches/none/run/pass/gm2-none.exp
index 40280b1c1b5..f16709b35ea 100644
--- a/gcc/testsuite/gm2/switches/none/run/pass/gm2-none.exp
+++ b/gcc/testsuite/gm2/switches/none/run/pass/gm2-none.exp
@@ -26,8 +26,8 @@ load_lib gm2-simple.exp
 
 set gm2src ${srcdir}/../m2
 
+gm2_link_lib "m2pim m2iso"
 gm2_init_pim
-gm2_link_with "-lm2pim -lm2iso -lpthread"
 
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
     # If we're only testing specific files and this isn't one of them, skip it.
diff --git a/gcc/testsuite/gm2/switches/optimization/run/pass/switches-optimization-run-pass.exp b/gcc/testsuite/gm2/switches/optimization/run/pass/switches-optimization-run-pass.exp
index d26cd9144a1..d5c132f178f 100644
--- a/gcc/testsuite/gm2/switches/optimization/run/pass/switches-optimization-run-pass.exp
+++ b/gcc/testsuite/gm2/switches/optimization/run/pass/switches-optimization-run-pass.exp
@@ -26,7 +26,6 @@ if $tracelevel then {
 load_lib gm2-torture.exp
 
 gm2_init_pim "${srcdir}/gm2/switches/optimization/run/pass" -O3
-gm2_link_with "-lgm2 -liso -lpthread"
 
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
     # If we're only testing specific files and this isn't one of them, skip it.
diff --git a/gcc/testsuite/gm2/switches/pic/run/pass/switches-pic-run-pass.exp b/gcc/testsuite/gm2/switches/pic/run/pass/switches-pic-run-pass.exp
index 441ea1df7ab..70ecbfd0bf0 100644
--- a/gcc/testsuite/gm2/switches/pic/run/pass/switches-pic-run-pass.exp
+++ b/gcc/testsuite/gm2/switches/pic/run/pass/switches-pic-run-pass.exp
@@ -26,8 +26,9 @@ load_lib gm2-torture.exp
 
 set gm2src ${srcdir}/../m2
 
+gm2_link_lib "m2pim m2iso"
 gm2_init_pim "${srcdir}/gm2/switches/pic/run/pass" -fPIC
-gm2_link_with "-lm2pim -lm2iso -lpthread"
+
 
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
     # If we're only testing specific files and this isn't one of them, skip it.
diff --git a/gcc/testsuite/gm2/switches/pim3/run/pass/switches-pim3-run-pass.exp b/gcc/testsuite/gm2/switches/pim3/run/pass/switches-pim3-run-pass.exp
index e84d0523cac..7bece9ec6b6 100644
--- a/gcc/testsuite/gm2/switches/pim3/run/pass/switches-pim3-run-pass.exp
+++ b/gcc/testsuite/gm2/switches/pim3/run/pass/switches-pim3-run-pass.exp
@@ -27,7 +27,6 @@ load_lib gm2-torture.exp
 set gm2src ${srcdir}/../m2
 
 gm2_init_pim3 "${srcdir}/gm2/switches/pim3/run/pass"
-gm2_link_with "-lm2pim -lm2iso -lpthread"
 
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
     # If we're only testing specific files and this isn't one of them, skip it.
diff --git a/gcc/testsuite/gm2/switches/pim4/run/pass/switches-pim4-run-pass.exp b/gcc/testsuite/gm2/switches/pim4/run/pass/switches-pim4-run-pass.exp
index b6f4e958538..43ed368a95a 100644
--- a/gcc/testsuite/gm2/switches/pim4/run/pass/switches-pim4-run-pass.exp
+++ b/gcc/testsuite/gm2/switches/pim4/run/pass/switches-pim4-run-pass.exp
@@ -27,7 +27,6 @@ load_lib gm2-torture.exp
 set gm2src ${srcdir}/../m2
 
 gm2_init_pim4 "${srcdir}/gm2/switches/pim4/run/pass"
-gm2_link_with "-lm2pim -lm2iso -lpthread"
 
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
     # If we're only testing specific files and this isn't one of them, skip it.
diff --git a/gcc/testsuite/gm2/switches/whole-program/pass/run/switches-whole-program-pass-run.exp b/gcc/testsuite/gm2/switches/whole-program/pass/run/switches-whole-program-pass-run.exp
index 74b554194af..4622103a1b7 100644
--- a/gcc/testsuite/gm2/switches/whole-program/pass/run/switches-whole-program-pass-run.exp
+++ b/gcc/testsuite/gm2/switches/whole-program/pass/run/switches-whole-program-pass-run.exp
@@ -25,7 +25,6 @@ if $tracelevel then {
 load_lib gm2-torture.exp
 
 gm2_init_pim "${srcdir}/gm2/switches/whole-program/run/pass" -fm2-whole-program
-gm2_link_with "-lm2pim -lm2iso -lpthread"
 
 foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] {
     # If we're only testing specific files and this isn't one of them, skip it.
diff --git a/gcc/testsuite/gm2/types/run/pass/types-run-pass.exp b/gcc/testsuite/gm2/types/run/pass/types-run-pass.exp
index 375c7012e7d..48b2aa11f06 100644
--- a/gcc/testsuite/gm2/types/run/pass/types-run-pass.exp
+++ b/gcc/testsuite/gm2/types/run/pass/types-run-pass.exp
@@ -28,7 +28,7 @@ load_lib gm2-torture.exp
 set gm2src ${srcdir}/../m2
 
 gm2_init_pim "${srcdir}/gm2/types/run/pass"
-gm2_link_with "d.o"
+gm2_link_obj "d.o"
 
 set output [target_compile $srcdir/$subdir/d.c d.o object "-g"]
 
diff --git a/gcc/testsuite/lib/gm2-simple.exp b/gcc/testsuite/lib/gm2-simple.exp
index d7603e98657..3ba1ae50c00 100644
--- a/gcc/testsuite/lib/gm2-simple.exp
+++ b/gcc/testsuite/lib/gm2-simple.exp
@@ -69,6 +69,7 @@ proc gm2-simple-execute { sources args option } {
     global tmpdir tool srcdir output compiler_conditional_xfail_data;
     global gm2_link_libraries;
     global gm2_link_path;
+    global gm2_link_objects;
 
     # Use the first source filename given as the filename under test.
     set src [lindex $sources 0];
@@ -105,10 +106,14 @@ proc gm2-simple-execute { sources args option } {
     remote_file build delete $execname;
     verbose "Testing $testcase, $option" 1
 
-    lappend option "libs=${gm2_link_libraries}";
-    lappend option "ldflags=${gm2_link_path}";
+    # start by setting options with option
+    set options [concat "{additional_flags=$gm2_link_objects} " $option]
+    # now append path -fno-libs=- and objects
+    set options [concat "{additional_flags=$gm2_link_path} " $options]
+    set options [concat "{additional_flags=-fno-libs=-} " $options]
+    set options [concat "{additional_flags=$gm2_link_objects} " $options]
 
-    set comp_output [gm2_target_compile "${sources}" "${execname}" executable ${option}];
+    set comp_output [gm2_target_compile "${sources}" "${execname}" executable ${options}];
 
     if ![gm2_check_compile "${testcase} compilation" ${option} ${execname} $comp_output] {
 	unresolved "${testcase} execution, ${option}"
diff --git a/gcc/testsuite/lib/gm2-torture.exp b/gcc/testsuite/lib/gm2-torture.exp
index 907174e72be..1783260270f 100644
--- a/gcc/testsuite/lib/gm2-torture.exp
+++ b/gcc/testsuite/lib/gm2-torture.exp
@@ -211,6 +211,7 @@ proc gm2-torture-execute { sources args success } {
     global tmpdir tool srcdir output compiler_conditional_xfail_data;
     global TORTURE_OPTIONS;
     global gm2_link_libraries;
+    global gm2_link_objects;
     global gm2_link_path;
 
     # Use the first source filename given as the filename under test.
@@ -280,10 +281,12 @@ proc gm2-torture-execute { sources args success } {
 
 	if ![gm2_check_compile "$testcase compilation" ${options} $objectfile $comp_output] {
 	    unresolved "$testcase execution, ${options}"
+	    send_log "compile failed not attempting link\n"
 	    remote_file build delete $objectfile
 	    continue
 	}
 
+	send_log "finished compile now attempting link\n"
 	# now link the test
 	set options ${option};
 
@@ -291,13 +294,43 @@ proc gm2-torture-execute { sources args success } {
 	    lappend options "additional_flags=[lindex ${args} 0]"
 	}
 
-	lappend options "libs=${gm2_link_libraries}";
-	lappend options "ldflags=${gm2_link_path}";
+	lappend options " additional_flags=${gm2_link_path}"
+
+	if {$gm2_link_path != ""} {
+	    lappend options " ldflags=$gm2_link_path"
+	}
+
+	if {$gm2_link_libraries != ""} {
+	    lappend options " ldflags=$gm2_link_libraries"
+	}
+
+#	lappend options "ldflags=/home/gaius/GM2/graft-combine/build-devel-modula2-enabled/x86_64-pc-linux-gnu/libgm2/libm2pim/.libs/libm2pim.a"
+#	lappend options "ldflags=/home/gaius/GM2/graft-combine/build-devel-modula2-enabled/x86_64-pc-linux-gnu/libgm2/libm2iso/.libs/libm2iso.a"
+#	lappend options "ldflags=-lm2pim -lm2iso"
+#
+	if {$gm2_link_objects != ""} {
+	    lappend options " additional_flags=${gm2_link_objects}"
+	}
+	if {$gm2_link_path != ""} {
+	    lappend options " additional_flags=${gm2_link_path}"
+	}
+
+	# lappend options " additional_flags=${gm2_link_objects}"
+	# lappend options " additional_flags=${gm2_link_path}"
+	# lappend options " additional_flags=${gm2_link_libraries}"
+	set options [concat "{additional_flags=$gm2_link_path} " $options]
+	set options [concat "{additional_flags=-fno-libs=-} " $options]
+	set options [concat "{additional_flags=$gm2_link_objects} " $options]
+	# set options [concat "{additional_flags=$gm2_link_libraries} " $options]
+
+	send_log "gm2_link_path = $gm2_link_path\n"
+	send_log "attempting link\n"
 	set comp_output [gm2_target_compile "${sources}" "${execname}" executable ${options}];
 	# puts "Link libraries are: ${gm2_link_libraries}"
 	# puts "Link path is      : ${gm2_link_path}"
 
 	if ![gm2_check_compile "${testcase} compilation" ${option} ${execname} ${comp_output}] {
+	    send_log "unsuccessful link\n"
 	    unresolved "${testcase} execution, ${option} (link failed)"
             verbose "tried to link ${testcase} ${sources} ${execname} executable ${options}" 1
 	    verbose "Link libraries are: ${gm2_link_libraries}" 1
@@ -316,6 +349,7 @@ proc gm2-torture-execute { sources args success } {
 	    continue
 	}
 
+	send_log "successful link\n"
 	# See if this source file uses "long long" types, if it does, and
 	# no_long_long is set, skip execution of the test.
 	if [target_info exists no_long_long] then {
diff --git a/gcc/testsuite/lib/gm2.exp b/gcc/testsuite/lib/gm2.exp
index 9506c3b7187..450cb4c2d35 100644
--- a/gcc/testsuite/lib/gm2.exp
+++ b/gcc/testsuite/lib/gm2.exp
@@ -81,7 +81,8 @@ proc gcc_version { } {
 set gm2_initialized 0;
 set gm2_compile_method "default";
 set gm2_link_path "";
-
+set gm2_link_libraries "m2pim m2iso";
+set gm2_link_objects "";
 
 proc gm2_set_compile_method { arg } {
     global gm2_compile_method;
@@ -104,13 +105,13 @@ proc gm2_init { args } {
     global GCC_UNDER_TEST;
     global TOOL_EXECUTABLE;
     global gm2_link_libraries;
+    global gm2_link_objects;
     global gm2_link_path;
     global HAVE_LIBSTDCXX_V3;
 
-
     if { $gm2_initialized == 1 } { return; }
 
-    set gm2_link_libraries "";
+    set gm2_link_objects "";
     set GCC_UNDER_TEST [lookfor_file $rootme gm2];
     append GCC_UNDER_TEST " " -B[file dirname $rootme]/gcc " " ${args};
     append GCC_UNDER_TEST " " -fno-diagnostics-show-caret
@@ -135,6 +136,7 @@ proc gm2_init { args } {
     }
 
     set gm2_link_path "[gm2_link_flags [get_multilibs]]";
+    verbose $gm2_link_path 1
 }
 
 #
@@ -146,6 +148,9 @@ proc gm2_target_compile_default { source dest type options } {
     global GCC_UNDER_TEST
     global TOOL_OPTIONS
     global TEST_ALWAYS_FLAGS
+    global gm2_link_objects
+    global gm2_link_libraries
+    global gm2_link_path
 
     if {[target_info needs_status_wrapper] != "" && \
 	    [target_info needs_status_wrapper] != "0" && \
@@ -161,6 +166,11 @@ proc gm2_target_compile_default { source dest type options } {
 	set options [concat "{additional_flags=$TEST_ALWAYS_FLAGS}" $options]
     }
 
+    global TEST_EXTRA_LIBS
+    if [info exists TEST_EXTRA_LIBS] {
+	lappend options "ldflags=$TEST_EXTRA_LIBS"
+    }
+
     if [target_info exists gcc,stack_size] {
 	lappend options "additional_flags=-DSTACK_SIZE=[target_info gcc,stack_size]"
     }
@@ -194,16 +204,28 @@ proc gm2_target_compile { source dest type options } {
 }
 
 #
-#  gm2_link_with - allows tests to specify link arguments, libraries and object files.
+#  gm2_link_lib - allows tests to specify link libraries.
+#                  This _must_ be called before gm2_init.
 #
 
-proc gm2_link_with { libraries } {
+proc gm2_link_lib { libraries } {
     global gm2_link_libraries;
 
     set gm2_link_libraries $libraries;
 }
 
 
+#
+#  gm2_link_obj - allows tests to specify link with objects.
+#
+
+proc gm2_link_obj { objects } {
+    global gm2_link_objects;
+
+    set gm2_link_objects $objects;
+}
+
+
 #
 #  gm2_link_flags - detects the whereabouts of libraries (-lstdc++).
 #
@@ -211,7 +233,8 @@ proc gm2_link_with { libraries } {
 proc gm2_link_flags { paths } {
     global srcdir;
     global ld_library_path;
-    global gccpath
+    global gccpath;
+    global gm2_link_libraries;
 
     set gccpath ${paths}
     set libio_dir ""
@@ -247,20 +270,22 @@ proc gm2_link_flags { paths } {
 	    append ld_library_path ":${gccpath}/libstdc++-v3/src/.libs"
 	}
 
-	foreach d [list libm2min libm2pim libm2cor libm2log libm2iso] {
+	# puts stderr "${gm2_link_libraries}  before foreach"
+	foreach d [list {*}${gm2_link_libraries}] {
+	    # puts stderr "${d}  XXXX"
 	    send_log "ld_library_path was ${ld_library_path}\n"
-	    send_log "looking for ${gccpath}/${d}/.libs/${d}.a\n"
-	    if [file exists "${gccpath}/libgm2/${d}/.libs/${d}.a"] {
-		send_log "good found ${gccpath}/libgm2/${d}/.libs/${d}.a\n"
-		append flags " -L${gccpath}/libgm2/${d}/.libs "
-		append ld_library_path ":${gccpath}/libgm2/${d}/.libs"
+	    send_log "looking for ${gccpath}/lib${d}/.libs/lib${d}.a\n"
+	    if [file exists "${gccpath}/libgm2/lib${d}/.libs/lib${d}.a"] {
+		send_log "good found ${gccpath}/libgm2/lib${d}/.libs/lib${d}.a\n"
+		# append flags " -L${gccpath}/libgm2/lib${d}/.libs -l${d}"
+		append flags " ${gccpath}/libgm2/lib${d}/.libs/lib${d}.a"
+		append ld_library_path ":${gccpath}/libgm2/lib${d}/.libs"
 	    }
 	    send_log "ld_library_path is ${ld_library_path}\n"
 	}
     }
 
     set_ld_library_path_env_vars
-
     return "$flags"
 }
 
@@ -294,7 +319,6 @@ proc gm2_init_pimx { dialect {path ""} args } {
 	append theIpath " -I"
 	append theIpath ${path}
     }
-
     gm2_init {*}${theIpath} {*}${dialect} {*}${theLpath} {*}${args};
 }
 
@@ -418,7 +442,10 @@ proc gm2_init_log { {path ""} args } {
     set pimIpath "${gccpath}/libgm2/libm2pim:${gm2src}/gm2-libs";
     set pimLpath "${gccpath}/libgm2/libm2pim/.libs";
 
-    set theIpath "-I${logIpath} -I${pimIpath}";
+    set isoIpath "${gccpath}/libgm2/libm2iso:${gm2src}/gm2-libs-iso";
+    set pimIpath "${gccpath}/libgm2/libm2pim:${gm2src}/gm2-libs";
+
+    set theIpath "-I${logIpath} -I${pimIpath} -I${isoIpath}";
     set theLpath "-L${logLpath} -L${pimLpath}";
 
     if { $path != "" } then {
@@ -426,6 +453,7 @@ proc gm2_init_log { {path ""} args } {
 	append theIpath ${path}
     }
 
+    gm2_link_lib "m2log m2pim m2iso"
     gm2_init {*}${theIpath} -fpim {*}${theLpath} {*}${args};
 }
 
@@ -437,6 +465,7 @@ proc gm2_init_log { {path ""} args } {
 proc gm2_init_cor { {path ""} args } {
     global srcdir;
     global gccpath;
+    global gm2_link_libraries;
 
     set gm2src ${srcdir}/../m2;
 
@@ -464,5 +493,6 @@ proc gm2_init_cor { {path ""} args } {
 	append theIpath ${path}
     }
 
+    gm2_link_lib "m2cor m2pim m2iso"
     gm2_init {*}${theIpath} -fpim {*}${theLpath} {*}${args};
 }
diff --git a/libgm2/libm2cor/KeyBoardLEDs.c b/libgm2/libm2cor/KeyBoardLEDs.c
deleted file mode 100644
index 2fa0b23a2ea..00000000000
--- a/libgm2/libm2cor/KeyBoardLEDs.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/* KeyBoardLEDs.c provide access to the keyboard LEDs.
-
-Copyright (C) 2005-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(linux)
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <linux/kd.h>
-#include <sys/ioctl.h>
-#include <stdio.h>
-
-#if !defined(TRUE)
-#   define TRUE (1==1)
-#endif
-#if !defined(FALSE)
-#   define FALSE (1==0)
-#endif
-
-#include <stdlib.h>
-
-static int fd;
-static int initialized = FALSE;
-
-
-void
-KeyBoardLEDs_SwitchScroll (int scrolllock)
-{
-  unsigned char leds;
-  int r = ioctl (fd, KDGETLED, &leds);
-  if (scrolllock)
-    leds = leds | LED_SCR;
-  else
-    leds = leds & (~ LED_SCR);
-  r = ioctl (fd, KDSETLED, leds);
-}
-
-void
-KeyBoardLEDs_SwitchNum (int numlock)
-{
-  unsigned char leds;
-  int r = ioctl (fd, KDGETLED, &leds);
-  if (numlock)
-    leds = leds | LED_NUM;
-  else
-    leds = leds & (~ LED_NUM);
-  r = ioctl (fd, KDSETLED, leds);
-}
-
-void
-KeyBoardLEDs_SwitchCaps (int capslock)
-{
-  unsigned char leds;
-  int r = ioctl (fd, KDGETLED, &leds);
-  if (capslock)
-    leds = leds | LED_CAP;
-  else
-    leds = leds & (~ LED_CAP);
-  r = ioctl (fd, KDSETLED, leds);
-}
-
-void
-KeyBoardLEDs_SwitchLeds (int numlock, int capslock, int scrolllock)
-{
-  KeyBoardLEDs_SwitchScroll (scrolllock);
-  KeyBoardLEDs_SwitchNum (numlock);
-  KeyBoardLEDs_SwitchCaps (capslock);
-}
-
-void
-_M2_KeyBoardLEDs_init (void)
-{
-  if (! initialized)
-    {
-      initialized = TRUE;
-      fd = open ("/dev/tty", O_RDONLY);
-      if (fd == -1)
-	{
-	  perror ("unable to open /dev/tty");
-	  exit (1);
-	}
-    }
-}
-
-#else
-void
-KeyBoardLEDs_SwitchLeds (int numlock, int capslock, int scrolllock)
-{
-}
-
-void
-KeyBoardLEDs_SwitchScroll (int scrolllock)
-{
-}
-
-void
-KeyBoardLEDs_SwitchNum (int numlock)
-{
-}
-
-void
-KeyBoardLEDs_SwitchCaps (int capslock)
-{
-}
-
-void
-_M2_KeyBoardLEDs_init (void)
-{
-}
-
-#endif
-
-void
-_M2_KeyBoardLEDs_finish (void)
-{
-}
diff --git a/libgm2/libm2cor/Makefile.am b/libgm2/libm2cor/Makefile.am
index 55d67550157..d1983e4b3ea 100644
--- a/libgm2/libm2cor/Makefile.am
+++ b/libgm2/libm2cor/Makefile.am
@@ -15,7 +15,7 @@
 # along with this program; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
-SUFFIXES = .c .mod .def .o .obj .lo .a .la
+SUFFIXES = .c .cc .mod .def .o .obj .lo .a .la
 
 ACLOCAL_AMFLAGS = -I . -I .. -I ../config
 
@@ -107,12 +107,13 @@ M2MODS = Debug.mod  Executive.mod \
 
 toolexeclib_LTLIBRARIES = libm2cor.la
 
-libm2cor_la_SOURCES = $(M2MODS) KeyBoardLEDs.c
+libm2cor_la_SOURCES = $(M2MODS) KeyBoardLEDs.cc
 
 nodist_EXTRA_libm2cor_la_SOURCES = dummy.c  ## forces automake to generate the LINK definition
 
 libm2cordir = libm2cor
 libm2cor_la_DEPENDENCIES = SYSTEM.def $(addsuffix .lo, $(basename $(libm2cor_la_SOURCES)))
+libm2cor_la_CFLAGS = -I. -I.. -I$(GM2_SRC)/gm2-libs -I$(GM2_SRC)/gm2-libs-iso -DBUILD_GM2_LIBS -I@srcdir@/../  -I@srcdir@/../libm2iso
 libm2cor_la_M2FLAGS = -I. -I$(GM2_SRC)/gm2-libs-coroutines -I$(GM2_SRC)/gm2-libs -I$(GM2_SRC)/gm2-libs-iso -fm2-g -g
 libm2cor_la_LINK = $(LINK) -version-info $(libtool_VERSION)
 BUILT_SOURCES = SYSTEM.def
@@ -130,6 +131,9 @@ SYSTEM.def: Makefile
 .mod.lo:
 	$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(GM2_FOR_TARGET) -c $(CFLAGS_FOR_TARGET) $(LIBCFLAGS) $(libm2cor_la_M2FLAGS) $< -o $@
 
+.cc.lo:
+	$(LIBTOOL) --tag=CXX --mode=compile $(CXX) -c -I$(srcdir) $(CXXFLAGS) $(LIBCFLAGS) $(libm2cor_la_CFLAGS) $< -o $@
+
 install-data-local: force
 	mkdir -p $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)
 	$(INSTALL_DATA) .libs/libm2cor.la $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)
diff --git a/libgm2/libm2iso/Makefile.am b/libgm2/libm2iso/Makefile.am
index fa546172b4e..2c955f708b5 100644
--- a/libgm2/libm2iso/Makefile.am
+++ b/libgm2/libm2iso/Makefile.am
@@ -194,6 +194,8 @@ BUILT_SOURCES = SYSTEM.def
 
 M2LIBDIR = /m2/m2iso/
 
+M2HEADER_FILES = m2rts.h
+
 SYSTEM.def: Makefile
 	bash $(GM2_SRC)/tools-src/makeSystem -fiso \
              $(GM2_SRC)/gm2-libs-iso/SYSTEM.def \
@@ -229,6 +231,14 @@ install-data-local: force
            fi ; \
            chmod 644 $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)$$i ; \
 	done
+	for i in $(M2HEADER_FILES) ; do \
+           if [ -f @srcdir@/$$i ] ; then \
+              $(INSTALL_DATA) @srcdir@/$$i '$(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)'; \
+           else \
+              echo "cannot find $$i" ; exit 1 ; \
+           fi ; \
+           chmod 644 $(DESTDIR)$(inst_libdir)/$(MULTIDIR)$(M2LIBDIR)$$i ; \
+	done
 
 force:
 
diff --git a/libgm2/libm2iso/RTco.cc b/libgm2/libm2iso/RTco.cc
index 9aad1561b0c..54c5078f03f 100644
--- a/libgm2/libm2iso/RTco.cc
+++ b/libgm2/libm2iso/RTco.cc
@@ -426,6 +426,7 @@ RTco_transfer (int *p1, int p2)
 extern "C" int
 RTco_select (int p1, fd_set *p2, fd_set *p3, fd_set *p4, const timespec *p5)
 {
+  RTco_init ();
   tprintf ("[%x]  RTco.select (...)\n", pthread_self ());
   return pselect (p1, p2, p3, p4, p5, NULL);
 }
@@ -433,7 +434,7 @@ RTco_select (int p1, fd_set *p2, fd_set *p3, fd_set *p4, const timespec *p5)
 extern "C" int
 RTco_init (void)
 {
-  if (!initialized)
+  if (! initialized)
     {
       int tid;
 
@@ -444,13 +445,13 @@ RTco_init (void)
       threadArray = (threadCB *)malloc (sizeof (threadCB) * THREAD_POOL);
       semArray = (threadSem **)malloc (sizeof (threadSem *) * SEM_POOL);
 #endif
-      tid = newThread (); /* For the current initial thread.  */
+      tid = newThread ();  /* For the current initial thread.  */
       threadArray[tid].tid = tid;
       threadArray[tid].execution = initSemaphore (0);
       threadArray[tid].p = pthread_self ();
       threadArray[tid].interruptLevel = 0;
       threadArray[tid].proc
-          = never; /* This shouldn't happen as we are already running.  */
+          = never;  /* This shouldn't happen as we are already running.  */
       initialized = TRUE;
       tprintf ("RTco initialized completed\n");
       signalSem (&lock);
diff --git a/libgm2/libm2pim/Makefile.am b/libgm2/libm2pim/Makefile.am
index 7a7acda7239..abbea35ff8a 100644
--- a/libgm2/libm2pim/Makefile.am
+++ b/libgm2/libm2pim/Makefile.am
@@ -118,15 +118,17 @@ M2MODS = ASCII.mod IO.mod \
        Builtins.mod MathLib0.mod \
        M2EXCEPTION.mod RTExceptions.mod \
        SMathLib0.mod RTint.mod \
-       COROUTINES.mod Indexing.mod \
+       Indexing.mod \
        LMathLib0.mod LegacyReal.mod \
        MemUtils.mod gdbif.mod \
        GetOpt.mod OptLib.mod
 
+# COROUTINES.mod has been removed as it is implemented in ../libm2iso.
+
 M2DEFS = Args.def   ASCII.def \
          Assertion.def  Break.def \
          Builtins.def  cbuiltin.def \
-         CmdArgs.def  COROUTINES.def \
+         CmdArgs.def COROUTINES.def \
          cxxabi.def  Debug.def \
          dtoa.def  DynamicStrings.def \
          Environment.def  errno.def \
@@ -162,7 +164,7 @@ libm2pim_la_SOURCES = $(M2MODS) \
                       errno.cc dtoa.cc \
                       ldtoa.cc termios.cc \
                       SysExceptions.cc target.c \
-                      wrapc.c cgetopt.c
+                      wrapc.c cgetopt.cc
 
 libm2pimdir = libm2pim
 libm2pim_la_DEPENDENCIES = SYSTEM.def $(addsuffix .lo, $(basename $(libm2pim_la_SOURCES)))
diff --git a/libgm2/libm2pim/cgetopt.c b/libgm2/libm2pim/cgetopt.cc
similarity index 81%
rename from libgm2/libm2pim/cgetopt.c
rename to libgm2/libm2pim/cgetopt.cc
index 001d151348f..fba20fccd22 100644
--- a/libgm2/libm2pim/cgetopt.c
+++ b/libgm2/libm2pim/cgetopt.cc
@@ -1,4 +1,4 @@
-/* getopt.c provide access to the C getopt library.
+/* cgetopt.cc provide access to the C getopt library.
 
 Copyright (C) 2009-2022 Free Software Foundation, Inc.
 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
@@ -27,13 +27,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #include <unistd.h>
 #include <stdlib.h>
 #include <getopt.h>
+#include <m2rts.h>
 
-char *cgetopt_optarg;
-int cgetopt_optind;
-int cgetopt_opterr;
-int cgetopt_optopt;
+extern "C" {char *cgetopt_optarg;}
+extern "C" {int cgetopt_optind;}
+extern "C" {int cgetopt_opterr;}
+extern "C" {int cgetopt_optopt;}
 
-char
+extern "C" char
 cgetopt_getopt (int argc, char *argv[], char *optstring)
 {
   char r = getopt (argc, argv, optstring);
@@ -48,7 +49,7 @@ cgetopt_getopt (int argc, char *argv[], char *optstring)
   return r;
 }
 
-int
+extern "C" int
 cgetopt_getopt_long (int argc, char *argv[], char *optstring,
                     const struct option *longopts, int *longindex)
 {
@@ -62,7 +63,7 @@ cgetopt_getopt_long (int argc, char *argv[], char *optstring,
   return r;
 }
 
-int
+extern "C" int
 cgetopt_getopt_long_only (int argc, char *argv[], char *optstring,
                          const struct option *longopts, int *longindex)
 {
@@ -84,7 +85,7 @@ typedef struct cgetopt_Options_s
 
 /* InitOptions a constructor for Options.  */
 
-cgetopt_Options *
+extern "C" cgetopt_Options *
 cgetopt_InitOptions (void)
 {
   cgetopt_Options *o = (cgetopt_Options *)malloc (sizeof (cgetopt_Options));
@@ -96,7 +97,7 @@ cgetopt_InitOptions (void)
 /* KillOptions a deconstructor for Options.  Returns NULL after freeing
    up all allocated memory associated with o.  */
 
-cgetopt_Options *
+extern "C" cgetopt_Options *
 cgetopt_KillOptions (cgetopt_Options *o)
 {
   free (o->cinfo);
@@ -106,7 +107,7 @@ cgetopt_KillOptions (cgetopt_Options *o)
 
 /* SetOption set option[index] with {name, has_arg, flag, val}.  */
 
-void
+extern "C" void
 cgetopt_SetOption (cgetopt_Options *o, unsigned int index, char *name,
  		   unsigned int has_arg, int *flag, int val)
 {
@@ -125,7 +126,7 @@ cgetopt_SetOption (cgetopt_Options *o, unsigned int index, char *name,
 /* GetLongOptionArray returns a pointer to the C array containing all
    long options.  */
 
-struct option *
+extern "C" struct option *
 cgetopt_GetLongOptionArray (cgetopt_Options *o)
 {
   return o->cinfo;
@@ -133,12 +134,25 @@ cgetopt_GetLongOptionArray (cgetopt_Options *o)
 
 /* GNU Modula-2 linking fodder.  */
 
-void
-_M2_cgetopt_init (void)
+extern "C" void
+_M2_cgetopt_init (int, char *argv[], char *env[])
 {
 }
 
-void
-_M2_cgetopt_finish (void)
+extern "C" void
+_M2_cgetopt_fini (int, char *argv[], char *env[])
 {
 }
+
+extern "C" void
+_M2_cgetopt_dep (void)
+{
+}
+
+struct _M2_cgetopt_ctor { _M2_cgetopt_ctor (); } _M2_cgetopt_ctor;
+
+_M2_cgetopt_ctor::_M2_cgetopt_ctor (void)
+{
+  M2RTS_RegisterModule ("cgetopt", _M2_cgetopt_init, _M2_cgetopt_fini,
+			_M2_cgetopt_dep);
+}
diff --git a/libgm2/libm2pim/wrapc.c b/libgm2/libm2pim/wrapc.c
index 524ecff6832..e5e0357c565 100644
--- a/libgm2/libm2pim/wrapc.c
+++ b/libgm2/libm2pim/wrapc.c
@@ -286,3 +286,8 @@ void
 _M2_wrapc_finish ()
 {
 }
+
+void
+_M2_wrapc_ctor ()
+{
+}


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

only message in thread, other threads:[~2022-07-24 20:32 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-24 20:32 [gcc/devel/modula-2] Integration of gm2l into cc1gm2 and a rewrite of gm2spec.cc 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).