The debugger is incorporated into the library "$(M2LIB)libm2dlib.a" / "$(M2LIB)libm2dlibcarbon.a".
The manual call of this procedure (e. g. for standalone code or language mixing) is described in section 4.4.2.2.
The main entry point ("_main")—the address where program execution starts—for each Modula-2 program is the initialization procedure of the runtime kernel. After some global initializations (see above) the module body of the main module ("M2_MAIN_MODULE") is executed.
To be able to conform to the rules laid down by the standard the initialization sequence is finally established at run time. For this purpose the compiler places a call to the module body of each imported module at the beginning of the initialization part of every module.
During the initialization a linked list of the module descriptors of all the initialized modules is built up. This list is used internally by the Modula-2 debugger.
Not only those error conditions which the standard demands be detected, but also all others (like address error, bus error etc.) are intercepted and set up for processing by the program. All the various error conditions are described in detail in sections 2.11.3 (Predefined Exception Conditions) and in the "Library" part of the manual (SysExceptions).
In case (b) the tools continues with the according exception handler.
In case (c) the tools is terminated with with exit code 1 unless the user specified an other exit code by a call to SYSTEM.SETEXITCODE (cf. 4.1.4).
Attention: a debugger for applications is not available in the current release.
In cases (a) and (c) a window of the following form normally appears (cf. Part 3 "Utilities", section 1.3):
Besides the error text, the name of the Modula-2 module, the procedure number and the program counter (PC) relative to the start of the procedure are shown in this dialog. The buttons "up" and "down" can be used to inspect the entire hierarchy of calls. The module name "????" signifies a departure from the Modula-2 environment.
Depending on the type of error and its circumstances not all buttons are always enabled. If "BREAK" is called, or a break point has been reached, the "Handler" button is disabled because no exception condition prevails. In cases of serious errors the "Resume" button cannot be used. The "M2 Debugger" button is only enabled if the debugger is actually present.
Calls to routines from SysExceptions (cf. "Library", section 2.3.4) can be used to control whether or not the dialog should appear in cases (b) and (c). A special debugger dialog (cf. "Utilities", section 1.5.4) controls whether or not it should appear in case (a).
SP0: | immediately before the procedure is called |
SP: | before executing the first statement of the procedure |
FP: | frame pointer of the procedure |
In all the following diagrams memory addresses increase towards the top.
| | |-----------------------------------|<-*--------------* | | \ \ | Parameter area | Caller (not in register) / / SP0 ------------> |-----------------------------------|<-*--------------* <- 16-Byte-Grenze | Saved ret adr (x30) | |-----------------------------------| | Saved FP (x29) | FP ------------> |-----------------------------------| | Saved GP (x28) | |-----------------------------------| | Saved SL (x27) | used in static chain, to be resored in exception handler |-----------------------------------| | Saved SE (x26) | |-----------------------------------| | (Memoryresultadresse) | if needed, passed in x8 | - - - - - - - - - - - -| | (parameter registers) | | - - - - - - - - - - - -| | | | kopierte Ref-Params | | | | - - - - - - - - - - - -| | | | lokale Variablen | | und Hilfsplätze | | | |-----------------------------------|<-* | Einsprungadresse Terminationrout. | \ |-----------------------------------| Nur bei globalen Moduln mit "FINAL"-Part | Terminationlink | / |-----------------------------------|<-* | return-adr fuer Exception-Part. | \ |-----------------------------------| Nur bei Moduln mit Exceptionhandling | retry-adr fuer Exception-Part. | / |-----------------------------------|<-* | saveFP | \ |-----------------------------------| \ | saveBP (empty for Arm) | \ |-----------------------------------| \ | aktMessage | \ |-----------------------------------| \ | aktNumber | \ |-----------------------------------| \ | aktSource | Nur bei Exceptionhandler |-----------------------------------| / | saveInfo | / |-----------------------------------| / | SP | / |-----------------------------------| / | Einsprungadresse Exceptionhandler | / |-----------------------------------| / | Exceptionlink | / |-----------------------------------|<-* <- 16-Byte-Grenze | | | Gesicherte Register | | r19-r25, v8 - v15 | | | |-----------------------------------|<-* <- 16-Byte-Grenze | | | Kopien von dynamischen Parametern | | | |-----------------------------------| | | | Zwischenergebnisse | | | | | |-----------------------------------|<-*--------------* | | \ \ | Parameter area | Callee / | | / SP -------------> |-----------------------------------|<-*--------------* <- 16-Byte-Grenze
FP: | frame pointer after the procedure prolog is executed |
SP: | stack pointer before the call to another procedure |
In all the following diagrams memory addresses increase towards the top.
| | |-----------------------------------|<-*--------------* | | \ \ | Parameter area | Caller / / |-----------------------------------|<-*--------------* <- 16-byte-boundary | Saved ret adr | |-----------------------------------| | Saved FP (%ebp) | FP ------------> |-----------------------------------| | Saved GP (%r15) | |-----------------------------------| | Saved SE (%r14) | |-----------------------------------| | Saved SL (%r13) | |-----------------------------------| | Saved %r12 | |-----------------------------------| | Saved PB (%ebx) | |-----------------------------------| | Saved outer SL | Only for nested procedures |-----------------------------------| | | | local variables | Including parameters passed in registers | | |-----------------------------------|<-* | entry point termination procedure | \ |-----------------------------------| Only global modules with "FINAL"-part | termination link | / |-----------------------------------|<-* | return-addr for Exception-Part. | \ |-----------------------------------| Only modules with exception handling | retry-addr for Exception-Part. | / |-----------------------------------|<-* | saveFP | \ |-----------------------------------| \ | saveBP | \ |-----------------------------------| \ | actMessage | \ |-----------------------------------| \ | actNumber | \ |-----------------------------------| \ | actSource | Only with exception handler |-----------------------------------| / | saveInfo | / |-----------------------------------| / | SP | / |-----------------------------------| / | entry point exception handler | / |-----------------------------------| / | exception link | / |-----------------------------------|<-* <- 16-byte-boundary | | | copies of reference parameters | | | |-----------------------------------| | | | intermediate results | | | | | |-----------------------------------|<-*--------------* | | \ \ | Parameter area | Callee / | | / SP -------------> |-----------------------------------|<-*--------------* <- 16-byte-boundary
The "GP" is loaded by every procedure that is callable from outside the module. Procedures which are exported explicitly or used in an expression (e.g. passed as an actual parameter or assigned to a variable) are considered callable from outside.
If global variables are not used in a procedure (including its local procedures) and only procedures which load the GP themselves are called, or if a module does not have any global variables, the GP is not loaded. r31 is then available for other use; edi/r15 may be used locally.
The module descriptor which the compiler creates for each module is also accessible via the GP. The following diagram depicts the structure of a module descriptor.
64-bit +---------------------+ | constant area | -24 addresse of constants table +---------------------+ | module chain | -16 +---------------------+ | data size | -8 size of global variables +---------------------+ | compiler version | -4 version number in hexadecimal | number | (1000H for V10.0) +---------------------+ | initialization flag | -2 0 = not yet initialized +---------------------+<--------------- global linker symbol | global variables |For every module descriptor the compiler generates a global linker symbol to permit access to the descriptor by other modules. For the program module this symbol always has the name "M2_MAIN_MODULE", while every other module's symbol name is made up from the module's name and the module key. As the module descriptor is referenced by all importing modules, version incompatibilities lead to linker errors (see also 1.6). Within a global data area the individual global variables are found at positive offsets to the area's base address (GP).
Note:
The exported variables of a foreign module are referenced via their names as in other
languages.
64-bit +---------------------+ | | address of the run-time system's +- defaultHandler -+ 48 default exception handler | | +---------------------+ | actProtection | 42 protection level +- isTerm -+ 41 process is terminating | hasHaltet | 40 HALT has been called +---------------------+ | | +- actHandler -+ 32 active exception handler | | +---------------------+ | | +- nextTerm -+ 24 next termination routine | | +---------------------+ | | +- nextHandler -+ 16 next exception handler | | +---------------------+ | | +- stackLow -+ 8 lower limit for stack check | | +---------------------+ | | when a process switch occurs the +- savePtr -+ 0 stack pointer (pointing to the | | saved registers) is written here +---------------------+A global variable points to the process descriptor of the active process at all times. Another holds a copy of the stack's lower limit from the current process descriptor.
UNSAFEGUARDED DEFINITION MODULE Mod; CLASS Class1; VAR attrib11, attrib12: CARDINAL; END Class1; CLASS Class2; INHERIT Class1; VAR attrib21, attrib22: CARDINAL; END Class2; END Mod. UNSAFEGUARDED IMPLEMENTATION MODULE Mod; CLASS Class1; VAR attrib13, attrib14: CARDINAL; END Class1; CLASS Class2; VAR attrib23, attrib24: CARDINAL; END Class2; END Mod.The object looks like:
Ref -> |-----------------------------------| | MethTabRef | |-----------------------------------| | attrib11 | |-----------------------------------| | attrib12 | |-----------------------------------| | Offs1 | ---------+ |-----------------------------------| | | attrib21 | | |-----------------------------------| | | attrib22 | | |-----------------------------------| | | Offs2 | ---+ | | | | | | | | | |-----------------------------------| | | | attrib23 | <--+ | |-----------------------------------| | | attrib24 | | |-----------------------------------| | | attrib13 | <--------+ |-----------------------------------| | attrib14 | |-----------------------------------|The method dispatch table starts with a pointer to the table of the father class (or "0"). The second entry specifies the size of an object of this class (statically this variable is set to "0", as the size cannot be determined until runtime). Next follow the method references, local methods (declared in the declaration part only) are dispatched by auxiliary tables.
+---------------------+ | | 0 +- total size -+ | | +---------------------+ | | 8 +- high 1 -+ high index of 1st dimension | | +---------------------+ | | | | +---------------------+ | | n * 8 +- high n -+ high index of n-th dimension | | +---------------------+ | | n * 8 + 8 +- data -+ arrays data | |
chapter 5 (compiler) | start page | appendix (compiler) |