This is gnat_ugn.info, produced by makeinfo version 7.1 from gnat_ugn.texi. GNAT User's Guide for Native Platforms , Dec 21, 2023 AdaCore Copyright © 2008-2024, Free Software Foundation INFO-DIR-SECTION GNU Ada Tools START-INFO-DIR-ENTRY * gnat_ugn: (gnat_ugn.info). gnat_ugn END-INFO-DIR-ENTRY Generated by Sphinx 5.3.0.  File: gnat_ugn.info, Node: Passive Task Optimization, Prev: Atomic Variables and Optimization, Up: Performance Considerations 6.3.1.12 Passive Task Optimization .................................. A passive task is one which is sufficiently simple that in theory a compiler could recognize it an implement it efficiently without creating a new thread. The original design of Ada 83 had in mind this kind of passive task optimization, but only a few Ada 83 compilers attempted it. The problem was that it was difficult to determine the exact conditions under which the optimization was possible. The result is a very fragile optimization where a very minor change in the program can suddenly silently make a task non-optimizable. With the revisiting of this issue in Ada 95, there was general agreement that this approach was fundamentally flawed, and the notion of protected types was introduced. When using protected types, the restrictions are well defined, and you KNOW that the operations will be optimized, and furthermore this optimized performance is fully portable. Although it would theoretically be possible for GNAT to attempt to do this optimization, but it really doesn’t make sense in the context of Ada 95, and none of the Ada 95 compilers implement this optimization as far as we know. In particular GNAT never attempts to perform this optimization. In any new Ada 95 code that is written, you should always use protected types in place of tasks that might be able to be optimized in this manner. Of course this does not help if you have legacy Ada 83 code that depends on this optimization, but it is unusual to encounter a case where the performance gains from this optimization are significant. Your program should work correctly without this optimization. If you have performance problems, then the most practical approach is to figure out exactly where these performance problems arise, and update those particular tasks to be protected types. Note that typically clients of the tasks who call entries, will not have to be modified, only the task definition itself.  File: gnat_ugn.info, Node: Text_IO Suggestions, Next: Reducing Size of Executables with Unused Subprogram/Data Elimination, Prev: Performance Considerations, Up: Improving Performance 6.3.2 ‘Text_IO’ Suggestions --------------------------- The ‘Ada.Text_IO’ package has fairly high overheads due in part to the requirement of maintaining page and line counts. If performance is critical, a recommendation is to use ‘Stream_IO’ instead of ‘Text_IO’ for volume output, since this package has less overhead. If ‘Text_IO’ must be used, note that by default output to the standard output and standard error files is unbuffered (this provides better behavior when output statements are used for debugging, or if the progress of a program is observed by tracking the output, e.g. by using the Unix 'tail -f' command to watch redirected output). If you are generating large volumes of output with ‘Text_IO’ and performance is an important factor, use a designated file instead of the standard output file, or change the standard output file to be buffered using ‘Interfaces.C_Streams.setvbuf’.  File: gnat_ugn.info, Node: Reducing Size of Executables with Unused Subprogram/Data Elimination, Prev: Text_IO Suggestions, Up: Improving Performance 6.3.3 Reducing Size of Executables with Unused Subprogram/Data Elimination -------------------------------------------------------------------------- This section describes how you can eliminate unused subprograms and data from your executable just by setting options at compilation time. * Menu: * About unused subprogram/data elimination:: * Compilation options:: * Example of unused subprogram/data elimination::  File: gnat_ugn.info, Node: About unused subprogram/data elimination, Next: Compilation options, Up: Reducing Size of Executables with Unused Subprogram/Data Elimination 6.3.3.1 About unused subprogram/data elimination ................................................ By default, an executable contains all code and data of its composing objects (directly linked or coming from statically linked libraries), even data or code never used by this executable. This feature will allow you to eliminate such unused code from your executable, making it smaller (in disk and in memory). This functionality is available on all Linux platforms except for the IA-64 architecture and on all cross platforms using the ELF binary file format. In both cases GNU binutils version 2.16 or later are required to enable it.  File: gnat_ugn.info, Node: Compilation options, Next: Example of unused subprogram/data elimination, Prev: About unused subprogram/data elimination, Up: Reducing Size of Executables with Unused Subprogram/Data Elimination 6.3.3.2 Compilation options ........................... The operation of eliminating the unused code and data from the final executable is directly performed by the linker. In order to do this, it has to work with objects compiled with the following options: ‘-ffunction-sections’ ‘-fdata-sections’. These options are usable with C and Ada files. They will place respectively each function or data in a separate section in the resulting object file. Once the objects and static libraries are created with these options, the linker can perform the dead code elimination. You can do this by setting the ‘-Wl,--gc-sections’ option to gcc command or in the ‘-largs’ section of ‘gnatmake’. This will perform a garbage collection of code and data never referenced. If the linker performs a partial link (‘-r’ linker option), then you will need to provide the entry point using the ‘-e’ / ‘--entry’ linker option. Note that objects compiled without the ‘-ffunction-sections’ and ‘-fdata-sections’ options can still be linked with the executable. However, no dead code elimination will be performed on those objects (they will be linked as is). The GNAT static library is now compiled with -ffunction-sections and -fdata-sections on some platforms. This allows you to eliminate the unused code and data of the GNAT library from your executable.  File: gnat_ugn.info, Node: Example of unused subprogram/data elimination, Prev: Compilation options, Up: Reducing Size of Executables with Unused Subprogram/Data Elimination 6.3.3.3 Example of unused subprogram/data elimination ..................................................... Here is a simple example: with Aux; procedure Test is begin Aux.Used (10); end Test; package Aux is Used_Data : Integer; Unused_Data : Integer; procedure Used (Data : Integer); procedure Unused (Data : Integer); end Aux; package body Aux is procedure Used (Data : Integer) is begin Used_Data := Data; end Used; procedure Unused (Data : Integer) is begin Unused_Data := Data; end Unused; end Aux; ‘Unused’ and ‘Unused_Data’ are never referenced in this code excerpt, and hence they may be safely removed from the final executable. $ gnatmake test $ nm test | grep used 020015f0 T aux__unused 02005d88 B aux__unused_data 020015cc T aux__used 02005d84 B aux__used_data $ gnatmake test -cargs -fdata-sections -ffunction-sections \\ -largs -Wl,--gc-sections $ nm test | grep used 02005350 T aux__used 0201ffe0 B aux__used_data It can be observed that the procedure ‘Unused’ and the object ‘Unused_Data’ are removed by the linker when using the appropriate options.  File: gnat_ugn.info, Node: Overflow Check Handling in GNAT, Next: Performing Dimensionality Analysis in GNAT, Prev: Improving Performance, Up: GNAT and Program Execution 6.4 Overflow Check Handling in GNAT =================================== This section explains how to control the handling of overflow checks. * Menu: * Background:: * Management of Overflows in GNAT:: * Specifying the Desired Mode:: * Default Settings:: * Implementation Notes::  File: gnat_ugn.info, Node: Background, Next: Management of Overflows in GNAT, Up: Overflow Check Handling in GNAT 6.4.1 Background ---------------- Overflow checks are checks that the compiler may make to ensure that intermediate results are not out of range. For example: A : Integer; ... A := A + 1; If ‘A’ has the value ‘Integer'Last’, then the addition may cause overflow since the result is out of range of the type ‘Integer’. In this case ‘Constraint_Error’ will be raised if checks are enabled. A trickier situation arises in examples like the following: A, C : Integer; ... A := (A + 1) + C; where ‘A’ is ‘Integer'Last’ and ‘C’ is ‘-1’. Now the final result of the expression on the right hand side is ‘Integer'Last’ which is in range, but the question arises whether the intermediate addition of ‘(A + 1)’ raises an overflow error. The (perhaps surprising) answer is that the Ada language definition does not answer this question. Instead it leaves it up to the implementation to do one of two things if overflow checks are enabled. * raise an exception (‘Constraint_Error’), or * yield the correct mathematical result which is then used in subsequent operations. If the compiler chooses the first approach, then the assignment of this example will indeed raise ‘Constraint_Error’ if overflow checking is enabled, or result in erroneous execution if overflow checks are suppressed. But if the compiler chooses the second approach, then it can perform both additions yielding the correct mathematical result, which is in range, so no exception will be raised, and the right result is obtained, regardless of whether overflow checks are suppressed. Note that in the first example an exception will be raised in either case, since if the compiler gives the correct mathematical result for the addition, it will be out of range of the target type of the assignment, and thus fails the range check. This lack of specified behavior in the handling of overflow for intermediate results is a source of non-portability, and can thus be problematic when programs are ported. Most typically this arises in a situation where the original compiler did not raise an exception, and then the application is moved to a compiler where the check is performed on the intermediate result and an unexpected exception is raised. Furthermore, when using Ada 2012’s preconditions and other assertion forms, another issue arises. Consider: procedure P (A, B : Integer) with Pre => A + B <= Integer'Last; One often wants to regard arithmetic in a context like this from a mathematical point of view. So for example, if the two actual parameters for a call to ‘P’ are both ‘Integer'Last’, then the precondition should be regarded as False. If we are executing in a mode with run-time checks enabled for preconditions, then we would like this precondition to fail, rather than raising an exception because of the intermediate overflow. However, the language definition leaves the specification of whether the above condition fails (raising ‘Assert_Error’) or causes an intermediate overflow (raising ‘Constraint_Error’) up to the implementation. The situation is worse in a case such as the following: procedure Q (A, B, C : Integer) with Pre => A + B + C <= Integer'Last; Consider the call Q (A => Integer'Last, B => 1, C => -1); From a mathematical point of view the precondition is True, but at run time we may (but are not guaranteed to) get an exception raised because of the intermediate overflow (and we really would prefer this precondition to be considered True at run time).  File: gnat_ugn.info, Node: Management of Overflows in GNAT, Next: Specifying the Desired Mode, Prev: Background, Up: Overflow Check Handling in GNAT 6.4.2 Management of Overflows in GNAT ------------------------------------- To deal with the portability issue, and with the problem of mathematical versus run-time interpretation of the expressions in assertions, GNAT provides comprehensive control over the handling of intermediate overflow. GNAT can operate in three modes, and furthermore, permits separate selection of operating modes for the expressions within assertions (here the term ‘assertions’ is used in the technical sense, which includes preconditions and so forth) and for expressions appearing outside assertions. The three modes are: * 'Use base type for intermediate operations' (‘STRICT’) In this mode, all intermediate results for predefined arithmetic operators are computed using the base type, and the result must be in range of the base type. If this is not the case then either an exception is raised (if overflow checks are enabled) or the execution is erroneous (if overflow checks are suppressed). This is the normal default mode. * 'Most intermediate overflows avoided' (‘MINIMIZED’) In this mode, the compiler attempts to avoid intermediate overflows by using a larger integer type, typically ‘Long_Long_Integer’, as the type in which arithmetic is performed for predefined arithmetic operators. This may be slightly more expensive at run time (compared to suppressing intermediate overflow checks), though the cost is negligible on modern 64-bit machines. For the examples given earlier, no intermediate overflows would have resulted in exceptions, since the intermediate results are all in the range of ‘Long_Long_Integer’ (typically 64-bits on nearly all implementations of GNAT). In addition, if checks are enabled, this reduces the number of checks that must be made, so this choice may actually result in an improvement in space and time behavior. However, there are cases where ‘Long_Long_Integer’ is not large enough, consider the following example: procedure R (A, B, C, D : Integer) with Pre => (A**2 * B**2) / (C**2 * D**2) <= 10; where ‘A’ = ‘B’ = ‘C’ = ‘D’ = ‘Integer'Last’. Now the intermediate results are out of the range of ‘Long_Long_Integer’ even though the final result is in range and the precondition is True (from a mathematical point of view). In such a case, operating in this mode, an overflow occurs for the intermediate computation (which is why this mode says 'most' intermediate overflows are avoided). In this case, an exception is raised if overflow checks are enabled, and the execution is erroneous if overflow checks are suppressed. * 'All intermediate overflows avoided' (‘ELIMINATED’) In this mode, the compiler avoids all intermediate overflows by using arbitrary precision arithmetic as required. In this mode, the above example with ‘A**2 * B**2’ would not cause intermediate overflow, because the intermediate result would be evaluated using sufficient precision, and the result of evaluating the precondition would be True. This mode has the advantage of avoiding any intermediate overflows, but at the expense of significant run-time overhead, including the use of a library (included automatically in this mode) for multiple-precision arithmetic. This mode provides cleaner semantics for assertions, since now the run-time behavior emulates true arithmetic behavior for the predefined arithmetic operators, meaning that there is never a conflict between the mathematical view of the assertion, and its run-time behavior. Note that in this mode, the behavior is unaffected by whether or not overflow checks are suppressed, since overflow does not occur. It is possible for gigantic intermediate expressions to raise ‘Storage_Error’ as a result of attempting to compute the results of such expressions (e.g. ‘Integer'Last ** Integer'Last’) but overflow is impossible. Note that these modes apply only to the evaluation of predefined arithmetic, membership, and comparison operators for signed integer arithmetic. For fixed-point arithmetic, checks can be suppressed. But if checks are enabled then fixed-point values are always checked for overflow against the base type for intermediate expressions (that is such checks always operate in the equivalent of ‘STRICT’ mode). For floating-point, on nearly all architectures, ‘Machine_Overflows’ is False, and IEEE infinities are generated, so overflow exceptions are never raised. If you want to avoid infinities, and check that final results of expressions are in range, then you can declare a constrained floating-point type, and range checks will be carried out in the normal manner (with infinite values always failing all range checks).  File: gnat_ugn.info, Node: Specifying the Desired Mode, Next: Default Settings, Prev: Management of Overflows in GNAT, Up: Overflow Check Handling in GNAT 6.4.3 Specifying the Desired Mode --------------------------------- The desired mode of for handling intermediate overflow can be specified using either the ‘Overflow_Mode’ pragma or an equivalent compiler switch. The pragma has the form pragma Overflow_Mode ([General =>] MODE [, [Assertions =>] MODE]); where ‘MODE’ is one of * ‘STRICT’: intermediate overflows checked (using base type) * ‘MINIMIZED’: minimize intermediate overflows * ‘ELIMINATED’: eliminate intermediate overflows The case is ignored, so ‘MINIMIZED’, ‘Minimized’ and ‘minimized’ all have the same effect. If only the ‘General’ parameter is present, then the given ‘MODE’ applies to expressions both within and outside assertions. If both arguments are present, then ‘General’ applies to expressions outside assertions, and ‘Assertions’ applies to expressions within assertions. For example: pragma Overflow_Mode (General => Minimized, Assertions => Eliminated); specifies that general expressions outside assertions be evaluated in ‘minimize intermediate overflows’ mode, and expressions within assertions be evaluated in ‘eliminate intermediate overflows’ mode. This is often a reasonable choice, avoiding excessive overhead outside assertions, but assuring a high degree of portability when importing code from another compiler, while incurring the extra overhead for assertion expressions to ensure that the behavior at run time matches the expected mathematical behavior. The ‘Overflow_Mode’ pragma has the same scoping and placement rules as pragma ‘Suppress’, so it can occur either as a configuration pragma, specifying a default for the whole program, or in a declarative scope, where it applies to the remaining declarations and statements in that scope. Note that pragma ‘Overflow_Mode’ does not affect whether overflow checks are enabled or suppressed. It only controls the method used to compute intermediate values. To control whether overflow checking is enabled or suppressed, use pragma ‘Suppress’ or ‘Unsuppress’ in the usual manner. Additionally, a compiler switch ‘-gnato?’ or ‘-gnato??’ can be used to control the checking mode default (which can be subsequently overridden using pragmas). Here ‘?’ is one of the digits ‘1’ through ‘3’: ‘1’ use base type for intermediate operations (‘STRICT’) ‘2’ minimize intermediate overflows (‘MINIMIZED’) ‘3’ eliminate intermediate overflows (‘ELIMINATED’) As with the pragma, if only one digit appears then it applies to all cases; if two digits are given, then the first applies outside assertions, and the second within assertions. Thus the equivalent of the example pragma above would be ‘-gnato23’. If no digits follow the ‘-gnato’, then it is equivalent to ‘-gnato11’, causing all intermediate operations to be computed using the base type (‘STRICT’ mode).  File: gnat_ugn.info, Node: Default Settings, Next: Implementation Notes, Prev: Specifying the Desired Mode, Up: Overflow Check Handling in GNAT 6.4.4 Default Settings ---------------------- The default mode for overflow checks is General => Strict which causes all computations both inside and outside assertions to use the base type, and is equivalent to ‘-gnato’ (with no digits following). The pragma ‘Suppress (Overflow_Check)’ disables overflow checking, but it has no effect on the method used for computing intermediate results. The pragma ‘Unsuppress (Overflow_Check)’ enables overflow checking, but it has no effect on the method used for computing intermediate results.  File: gnat_ugn.info, Node: Implementation Notes, Prev: Default Settings, Up: Overflow Check Handling in GNAT 6.4.5 Implementation Notes -------------------------- In practice on typical 64-bit machines, the ‘MINIMIZED’ mode is reasonably efficient, and can be generally used. It also helps to ensure compatibility with code imported from some other compiler to GNAT. Setting all intermediate overflows checking (‘STRICT’ mode) makes sense if you want to make sure that your code is compatible with any other possible Ada implementation. This may be useful in ensuring portability for code that is to be exported to some other compiler than GNAT. The Ada standard allows the reassociation of expressions at the same precedence level if no parentheses are present. For example, ‘A+B+C’ parses as though it were ‘(A+B)+C’, but the compiler can reintepret this as ‘A+(B+C)’, possibly introducing or eliminating an overflow exception. The GNAT compiler never takes advantage of this freedom, and the expression ‘A+B+C’ will be evaluated as ‘(A+B)+C’. If you need the other order, you can write the parentheses explicitly ‘A+(B+C)’ and GNAT will respect this order. The use of ‘ELIMINATED’ mode will cause the compiler to automatically include an appropriate arbitrary precision integer arithmetic package. The compiler will make calls to this package, though only in cases where it cannot be sure that ‘Long_Long_Integer’ is sufficient to guard against intermediate overflows. This package does not use dynamic allocation, but it does use the secondary stack, so an appropriate secondary stack package must be present (this is always true for standard full Ada, but may require specific steps for restricted run times such as ZFP). Although ‘ELIMINATED’ mode causes expressions to use arbitrary precision arithmetic, avoiding overflow, the final result must be in an appropriate range. This is true even if the final result is of type ‘[Long_[Long_]]Integer'Base’, which still has the same bounds as its associated constrained type at run-time. Currently, the ‘ELIMINATED’ mode is only available on target platforms for which ‘Long_Long_Integer’ is 64-bits (nearly all GNAT platforms).  File: gnat_ugn.info, Node: Performing Dimensionality Analysis in GNAT, Next: Stack Related Facilities, Prev: Overflow Check Handling in GNAT, Up: GNAT and Program Execution 6.5 Performing Dimensionality Analysis in GNAT ============================================== The GNAT compiler supports dimensionality checking. The user can specify physical units for objects, and the compiler will verify that uses of these objects are compatible with their dimensions, in a fashion that is familiar to engineering practice. The dimensions of algebraic expressions (including powers with static exponents) are computed from their constituents. This feature depends on Ada 2012 aspect specifications, and is available from version 7.0.1 of GNAT onwards. The GNAT-specific aspect ‘Dimension_System’ allows you to define a system of units; the aspect ‘Dimension’ then allows the user to declare dimensioned quantities within a given system. (These aspects are described in the 'Implementation Defined Aspects' chapter of the 'GNAT Reference Manual'). The major advantage of this model is that it does not require the declaration of multiple operators for all possible combinations of types: it is only necessary to use the proper subtypes in object declarations. The simplest way to impose dimensionality checking on a computation is to make use of one of the instantiations of the package ‘System.Dim.Generic_Mks’, which are part of the GNAT library. This generic package defines a floating-point type ‘MKS_Type’, for which a sequence of dimension names are specified, together with their conventional abbreviations. The following should be read together with the full specification of the package, in file ‘s-digemk.ads’. type Mks_Type is new Float_Type with Dimension_System => ( (Unit_Name => Meter, Unit_Symbol => 'm', Dim_Symbol => 'L'), (Unit_Name => Kilogram, Unit_Symbol => "kg", Dim_Symbol => 'M'), (Unit_Name => Second, Unit_Symbol => 's', Dim_Symbol => 'T'), (Unit_Name => Ampere, Unit_Symbol => 'A', Dim_Symbol => 'I'), (Unit_Name => Kelvin, Unit_Symbol => 'K', Dim_Symbol => "Theta"), (Unit_Name => Mole, Unit_Symbol => "mol", Dim_Symbol => 'N'), (Unit_Name => Candela, Unit_Symbol => "cd", Dim_Symbol => 'J')); The package then defines a series of subtypes that correspond to these conventional units. For example: subtype Length is Mks_Type with Dimension => (Symbol => 'm', Meter => 1, others => 0); and similarly for ‘Mass’, ‘Time’, ‘Electric_Current’, ‘Thermodynamic_Temperature’, ‘Amount_Of_Substance’, and ‘Luminous_Intensity’ (the standard set of units of the SI system). The package also defines conventional names for values of each unit, for example: m : constant Length := 1.0; kg : constant Mass := 1.0; s : constant Time := 1.0; A : constant Electric_Current := 1.0; as well as useful multiples of these units: cm : constant Length := 1.0E-02; g : constant Mass := 1.0E-03; min : constant Time := 60.0; day : constant Time := 60.0 * 24.0 * min; ... There are three instantiations of ‘System.Dim.Generic_Mks’ defined in the GNAT library: * ‘System.Dim.Float_Mks’ based on ‘Float’ defined in ‘s-diflmk.ads’. * ‘System.Dim.Long_Mks’ based on ‘Long_Float’ defined in ‘s-dilomk.ads’. * ‘System.Dim.Mks’ based on ‘Long_Long_Float’ defined in ‘s-dimmks.ads’. Using one of these packages, you can then define a derived unit by providing the aspect that specifies its dimensions within the MKS system, as well as the string to be used for output of a value of that unit: subtype Acceleration is Mks_Type with Dimension => ("m/sec^2", Meter => 1, Second => -2, others => 0); Here is a complete example of use: with System.Dim.MKS; use System.Dim.Mks; with System.Dim.Mks_IO; use System.Dim.Mks_IO; with Text_IO; use Text_IO; procedure Free_Fall is subtype Acceleration is Mks_Type with Dimension => ("m/sec^2", 1, 0, -2, others => 0); G : constant acceleration := 9.81 * m / (s ** 2); T : Time := 10.0*s; Distance : Length; begin Put ("Gravitational constant: "); Put (G, Aft => 2, Exp => 0); Put_Line (""); Distance := 0.5 * G * T ** 2; Put ("distance travelled in 10 seconds of free fall "); Put (Distance, Aft => 2, Exp => 0); Put_Line (""); end Free_Fall; Execution of this program yields: Gravitational constant: 9.81 m/sec^2 distance travelled in 10 seconds of free fall 490.50 m However, incorrect assignments such as: Distance := 5.0; Distance := 5.0 * kg; are rejected with the following diagnoses: Distance := 5.0; >>> dimensions mismatch in assignment >>> left-hand side has dimension [L] >>> right-hand side is dimensionless Distance := 5.0 * kg: >>> dimensions mismatch in assignment >>> left-hand side has dimension [L] >>> right-hand side has dimension [M] The dimensions of an expression are properly displayed, even if there is no explicit subtype for it. If we add to the program: Put ("Final velocity: "); Put (G * T, Aft =>2, Exp =>0); Put_Line (""); then the output includes: Final velocity: 98.10 m.s**(-1) The type ‘Mks_Type’ is said to be a 'dimensionable type' since it has a ‘Dimension_System’ aspect, and the subtypes ‘Length’, ‘Mass’, etc., are said to be 'dimensioned subtypes' since each one has a ‘Dimension’ aspect. The ‘Dimension’ aspect of a dimensioned subtype ‘S’ defines a mapping from the base type’s Unit_Names to integer (or, more generally, rational) values. This mapping is the 'dimension vector' (also referred to as the 'dimensionality') for that subtype, denoted by ‘DV(S)’, and thus for each object of that subtype. Intuitively, the value specified for each ‘Unit_Name’ is the exponent associated with that unit; a zero value means that the unit is not used. For example: declare Acc : Acceleration; ... begin ... end; Here ‘DV(Acc)’ = ‘DV(Acceleration)’ = ‘(Meter=>1, Kilogram=>0, Second=>-2, Ampere=>0, Kelvin=>0, Mole=>0, Candela=>0)’. Symbolically, we can express this as ‘Meter / Second**2’. The dimension vector of an arithmetic expression is synthesized from the dimension vectors of its components, with compile-time dimensionality checks that help prevent mismatches such as using an ‘Acceleration’ where a ‘Length’ is required. The dimension vector of the result of an arithmetic expression 'expr', or ‘DV(EXPR)’, is defined as follows, assuming conventional mathematical definitions for the vector operations that are used: * If 'expr' is of the type 'universal_real', or is not of a dimensioned subtype, then 'expr' is dimensionless; ‘DV(EXPR)’ is the empty vector. * ‘DV(OP EXPR)’, where 'op' is a unary operator, is ‘DV(EXPR)’ * ‘DV(EXPR1 OP EXPR2)’ where 'op' is “+” or “-” is ‘DV(EXPR1)’ provided that ‘DV(EXPR1)’ = ‘DV(EXPR2)’. If this condition is not met then the construct is illegal. * ‘DV(EXPR1 * EXPR2)’ is ‘DV(EXPR1)’ + ‘DV(EXPR2)’, and ‘DV(EXPR1 / EXPR2)’ = ‘DV(EXPR1)’ - ‘DV(EXPR2)’. In this context if one of the 'expr's is dimensionless then its empty dimension vector is treated as ‘(others => 0)’. * ‘DV(EXPR ** POWER)’ is 'power' * ‘DV(EXPR)’, provided that 'power' is a static rational value. If this condition is not met then the construct is illegal. Note that, by the above rules, it is illegal to use binary “+” or “-” to combine a dimensioned and dimensionless value. Thus an expression such as ‘acc-10.0’ is illegal, where ‘acc’ is an object of subtype ‘Acceleration’. The dimensionality checks for relationals use the same rules as for “+” and “-”, except when comparing to a literal; thus acc > len is equivalent to acc-len > 0.0 and is thus illegal, but acc > 10.0 is accepted with a warning. Analogously a conditional expression requires the same dimension vector for each branch (with no exception for literals). The dimension vector of a type conversion ‘T(EXPR)’ is defined as follows, based on the nature of ‘T’: * If ‘T’ is a dimensioned subtype then ‘DV(T(EXPR))’ is ‘DV(T)’ provided that either 'expr' is dimensionless or ‘DV(T)’ = ‘DV(EXPR)’. The conversion is illegal if 'expr' is dimensioned and ‘DV(EXPR)’ /= ‘DV(T)’. Note that vector equality does not require that the corresponding Unit_Names be the same. As a consequence of the above rule, it is possible to convert between different dimension systems that follow the same international system of units, with the seven physical components given in the standard order (length, mass, time, etc.). Thus a length in meters can be converted to a length in inches (with a suitable conversion factor) but cannot be converted, for example, to a mass in pounds. * If ‘T’ is the base type for 'expr' (and the dimensionless root type of the dimension system), then ‘DV(T(EXPR))’ is ‘DV(expr)’. Thus, if 'expr' is of a dimensioned subtype of ‘T’, the conversion may be regarded as a “view conversion” that preserves dimensionality. This rule makes it possible to write generic code that can be instantiated with compatible dimensioned subtypes. The generic unit will contain conversions that will consequently be present in instantiations, but conversions to the base type will preserve dimensionality and make it possible to write generic code that is correct with respect to dimensionality. * Otherwise (i.e., ‘T’ is neither a dimensioned subtype nor a dimensionable base type), ‘DV(T(EXPR))’ is the empty vector. Thus a dimensioned value can be explicitly converted to a non-dimensioned subtype, which of course then escapes dimensionality analysis. The dimension vector for a type qualification ‘T'(EXPR)’ is the same as for the type conversion ‘T(EXPR)’. An assignment statement Source := Target; requires ‘DV(Source)’ = ‘DV(Target)’, and analogously for parameter passing (the dimension vector for the actual parameter must be equal to the dimension vector for the formal parameter). When using dimensioned types with elementary functions it is necessary to instantiate the ‘Ada.Numerics.Generic_Elementary_Functions’ package using the ‘Mks_Type’ and not any of the derived subtypes such as ‘Distance’. For functions such as ‘Sqrt’ the dimensional analysis will fail when using the subtypes because both the parameter and return are of the same type. An example instantiation package Mks_Numerics is new Ada.Numerics.Generic_Elementary_Functions (System.Dim.Mks.Mks_Type);  File: gnat_ugn.info, Node: Stack Related Facilities, Next: Memory Management Issues, Prev: Performing Dimensionality Analysis in GNAT, Up: GNAT and Program Execution 6.6 Stack Related Facilities ============================ This section describes some useful tools associated with stack checking and analysis. In particular, it deals with dynamic and static stack usage measurements. * Menu: * Stack Overflow Checking:: * Static Stack Usage Analysis:: * Dynamic Stack Usage Analysis::  File: gnat_ugn.info, Node: Stack Overflow Checking, Next: Static Stack Usage Analysis, Up: Stack Related Facilities 6.6.1 Stack Overflow Checking ----------------------------- For most operating systems, ‘gcc’ does not perform stack overflow checking by default. This means that if the main environment task or some other task exceeds the available stack space, then unpredictable behavior will occur. Most native systems offer some level of protection by adding a guard page at the end of each task stack. This mechanism is usually not enough for dealing properly with stack overflow situations because a large local variable could “jump” above the guard page. Furthermore, when the guard page is hit, there may not be any space left on the stack for executing the exception propagation code. Enabling stack checking avoids such situations. To activate stack checking, compile all units with the ‘gcc’ option ‘-fstack-check’. For example: $ gcc -c -fstack-check package1.adb Units compiled with this option will generate extra instructions to check that any use of the stack (for procedure calls or for declaring local variables in declare blocks) does not exceed the available stack space. If the space is exceeded, then a ‘Storage_Error’ exception is raised. For declared tasks, the default stack size is defined by the GNAT runtime, whose size may be modified at bind time through the ‘-d’ bind switch (*note Switches for gnatbind: 112.). Task specific stack sizes may be set using the ‘Storage_Size’ pragma. For the environment task, the stack size is determined by the operating system. Consequently, to modify the size of the environment task please refer to your operating system documentation.  File: gnat_ugn.info, Node: Static Stack Usage Analysis, Next: Dynamic Stack Usage Analysis, Prev: Stack Overflow Checking, Up: Stack Related Facilities 6.6.2 Static Stack Usage Analysis --------------------------------- A unit compiled with ‘-fstack-usage’ will generate an extra file that specifies the maximum amount of stack used, on a per-function basis. The file has the same basename as the target object file with a ‘.su’ extension. Each line of this file is made up of three fields: * The name of the function. * A number of bytes. * One or more qualifiers: ‘static’, ‘dynamic’, ‘bounded’. The second field corresponds to the size of the known part of the function frame. The qualifier ‘static’ means that the function frame size is purely static. It usually means that all local variables have a static size. In this case, the second field is a reliable measure of the function stack utilization. The qualifier ‘dynamic’ means that the function frame size is not static. It happens mainly when some local variables have a dynamic size. When this qualifier appears alone, the second field is not a reliable measure of the function stack analysis. When it is qualified with ‘bounded’, it means that the second field is a reliable maximum of the function stack utilization. A unit compiled with ‘-Wstack-usage’ will issue a warning for each subprogram whose stack usage might be larger than the specified amount of bytes. The wording is in keeping with the qualifier documented above.  File: gnat_ugn.info, Node: Dynamic Stack Usage Analysis, Prev: Static Stack Usage Analysis, Up: Stack Related Facilities 6.6.3 Dynamic Stack Usage Analysis ---------------------------------- It is possible to measure the maximum amount of stack used by a task, by adding a switch to ‘gnatbind’, as: $ gnatbind -u0 file With this option, at each task termination, its stack usage is output on ‘stderr’. Note that this switch is not compatible with tools like Valgrind and DrMemory; they will report errors. It is not always convenient to output the stack usage when the program is still running. Hence, it is possible to delay this output until program termination. for a given number of tasks specified as the argument of the ‘-u’ option. For instance: $ gnatbind -u100 file will buffer the stack usage information of the first 100 tasks to terminate and output this info at program termination. Results are displayed in four columns: Index | Task Name | Stack Size | Stack Usage where: * 'Index' is a number associated with each task. * 'Task Name' is the name of the task analyzed. * 'Stack Size' is the maximum size for the stack. * 'Stack Usage' is the measure done by the stack analyzer. In order to prevent overflow, the stack is not entirely analyzed, and it’s not possible to know exactly how much has actually been used. By default the environment task stack, the stack that contains the main unit, is not processed. To enable processing of the environment task stack, the environment variable GNAT_STACK_LIMIT needs to be set to the maximum size of the environment task stack. This amount is given in kilobytes. For example: $ set GNAT_STACK_LIMIT 1600 would specify to the analyzer that the environment task stack has a limit of 1.6 megabytes. Any stack usage beyond this will be ignored by the analysis. The package ‘GNAT.Task_Stack_Usage’ provides facilities to get stack-usage reports at run time. See its body for the details.  File: gnat_ugn.info, Node: Memory Management Issues, Prev: Stack Related Facilities, Up: GNAT and Program Execution 6.7 Memory Management Issues ============================ This section describes some useful memory pools provided in the GNAT library and in particular the GNAT Debug Pool facility, which can be used to detect incorrect uses of access values (including ‘dangling references’). * Menu: * Some Useful Memory Pools:: * The GNAT Debug Pool Facility::  File: gnat_ugn.info, Node: Some Useful Memory Pools, Next: The GNAT Debug Pool Facility, Up: Memory Management Issues 6.7.1 Some Useful Memory Pools ------------------------------ The ‘System.Pool_Global’ package offers the Unbounded_No_Reclaim_Pool storage pool. Allocations use the standard system call ‘malloc’ while deallocations use the standard system call ‘free’. No reclamation is performed when the pool goes out of scope. For performance reasons, the standard default Ada allocators/deallocators do not use any explicit storage pools but if they did, they could use this storage pool without any change in behavior. That is why this storage pool is used when the user manages to make the default implicit allocator explicit as in this example: type T1 is access Something; -- no Storage pool is defined for T2 type T2 is access Something_Else; for T2'Storage_Pool use T1'Storage_Pool; -- the above is equivalent to for T2'Storage_Pool use System.Pool_Global.Global_Pool_Object; The ‘System.Pool_Local’ package offers the ‘Unbounded_Reclaim_Pool’ storage pool. The allocation strategy is similar to ‘Pool_Local’ except that the all storage allocated with this pool is reclaimed when the pool object goes out of scope. This pool provides a explicit mechanism similar to the implicit one provided by several Ada 83 compilers for allocations performed through a local access type and whose purpose was to reclaim memory when exiting the scope of a given local access. As an example, the following program does not leak memory even though it does not perform explicit deallocation: with System.Pool_Local; procedure Pooloc1 is procedure Internal is type A is access Integer; X : System.Pool_Local.Unbounded_Reclaim_Pool; for A'Storage_Pool use X; v : A; begin for I in 1 .. 50 loop v := new Integer; end loop; end Internal; begin for I in 1 .. 100 loop Internal; end loop; end Pooloc1; The ‘System.Pool_Size’ package implements the ‘Stack_Bounded_Pool’ used when ‘Storage_Size’ is specified for an access type. The whole storage for the pool is allocated at once, usually on the stack at the point where the access type is elaborated. It is automatically reclaimed when exiting the scope where the access type is defined. This package is not intended to be used directly by the user and it is implicitly used for each such declaration: type T1 is access Something; for T1'Storage_Size use 10_000;  File: gnat_ugn.info, Node: The GNAT Debug Pool Facility, Prev: Some Useful Memory Pools, Up: Memory Management Issues 6.7.2 The GNAT Debug Pool Facility ---------------------------------- The use of unchecked deallocation and unchecked conversion can easily lead to incorrect memory references. The problems generated by such references are usually difficult to tackle because the symptoms can be very remote from the origin of the problem. In such cases, it is very helpful to detect the problem as early as possible. This is the purpose of the Storage Pool provided by ‘GNAT.Debug_Pools’. In order to use the GNAT specific debugging pool, the user must associate a debug pool object with each of the access types that may be related to suspected memory problems. See Ada Reference Manual 13.11. type Ptr is access Some_Type; Pool : GNAT.Debug_Pools.Debug_Pool; for Ptr'Storage_Pool use Pool; ‘GNAT.Debug_Pools’ is derived from a GNAT-specific kind of pool: the ‘Checked_Pool’. Such pools, like standard Ada storage pools, allow the user to redefine allocation and deallocation strategies. They also provide a checkpoint for each dereference, through the use of the primitive operation ‘Dereference’ which is implicitly called at each dereference of an access value. Once an access type has been associated with a debug pool, operations on values of the type may raise four distinct exceptions, which correspond to four potential kinds of memory corruption: * ‘GNAT.Debug_Pools.Accessing_Not_Allocated_Storage’ * ‘GNAT.Debug_Pools.Accessing_Deallocated_Storage’ * ‘GNAT.Debug_Pools.Freeing_Not_Allocated_Storage’ * ‘GNAT.Debug_Pools.Freeing_Deallocated_Storage’ For types associated with a Debug_Pool, dynamic allocation is performed using the standard GNAT allocation routine. References to all allocated chunks of memory are kept in an internal dictionary. Several deallocation strategies are provided, whereupon the user can choose to release the memory to the system, keep it allocated for further invalid access checks, or fill it with an easily recognizable pattern for debug sessions. The memory pattern is the old IBM hexadecimal convention: ‘16#DEADBEEF#’. See the documentation in the file g-debpoo.ads for more information on the various strategies. Upon each dereference, a check is made that the access value denotes a properly allocated memory location. Here is a complete example of use of ‘Debug_Pools’, that includes typical instances of memory corruption: with GNAT.IO; use GNAT.IO; with Ada.Unchecked_Deallocation; with Ada.Unchecked_Conversion; with GNAT.Debug_Pools; with System.Storage_Elements; with Ada.Exceptions; use Ada.Exceptions; procedure Debug_Pool_Test is type T is access Integer; type U is access all T; P : GNAT.Debug_Pools.Debug_Pool; for T'Storage_Pool use P; procedure Free is new Ada.Unchecked_Deallocation (Integer, T); function UC is new Ada.Unchecked_Conversion (U, T); A, B : aliased T; procedure Info is new GNAT.Debug_Pools.Print_Info(Put_Line); begin Info (P); A := new Integer; B := new Integer; B := A; Info (P); Free (A); begin Put_Line (Integer'Image(B.all)); exception when E : others => Put_Line ("raised: " & Exception_Name (E)); end; begin Free (B); exception when E : others => Put_Line ("raised: " & Exception_Name (E)); end; B := UC(A'Access); begin Put_Line (Integer'Image(B.all)); exception when E : others => Put_Line ("raised: " & Exception_Name (E)); end; begin Free (B); exception when E : others => Put_Line ("raised: " & Exception_Name (E)); end; Info (P); end Debug_Pool_Test; The debug pool mechanism provides the following precise diagnostics on the execution of this erroneous program: Debug Pool info: Total allocated bytes : 0 Total deallocated bytes : 0 Current Water Mark: 0 High Water Mark: 0 Debug Pool info: Total allocated bytes : 8 Total deallocated bytes : 0 Current Water Mark: 8 High Water Mark: 8 raised: GNAT.DEBUG_POOLS.ACCESSING_DEALLOCATED_STORAGE raised: GNAT.DEBUG_POOLS.FREEING_DEALLOCATED_STORAGE raised: GNAT.DEBUG_POOLS.ACCESSING_NOT_ALLOCATED_STORAGE raised: GNAT.DEBUG_POOLS.FREEING_NOT_ALLOCATED_STORAGE Debug Pool info: Total allocated bytes : 8 Total deallocated bytes : 4 Current Water Mark: 4 High Water Mark: 8  File: gnat_ugn.info, Node: Platform-Specific Information, Next: Example of Binder Output File, Prev: GNAT and Program Execution, Up: Top 7 Platform-Specific Information ******************************* This appendix contains information relating to the implementation of run-time libraries on various platforms and also covers topics related to the GNAT implementation on specific Operating Systems. * Menu: * Run-Time Libraries:: * Specifying a Run-Time Library:: * GNU/Linux Topics:: * Microsoft Windows Topics:: * Mac OS Topics::  File: gnat_ugn.info, Node: Run-Time Libraries, Next: Specifying a Run-Time Library, Up: Platform-Specific Information 7.1 Run-Time Libraries ====================== The GNAT run-time implementation may vary with respect to both the underlying threads library and the exception-handling scheme. For threads support, the default run-time will bind to the thread package of the underlying operating system. For exception handling, either or both of two models are supplied: * 'Zero-Cost Exceptions' (“ZCX”), which uses binder-generated tables that are interrogated at run time to locate a handler. * 'setjmp / longjmp' (‘SJLJ’), which uses dynamically-set data to establish the set of handlers Most programs should experience a substantial speed improvement by being compiled with a ZCX run-time. This is especially true for tasking applications or applications with many exception handlers. Note however that the ZCX run-time does not support asynchronous abort of tasks (‘abort’ and ‘select-then-abort’ constructs) and will instead implement abort by polling points in the runtime. You can also add additional polling points explicitly if needed in your application via ‘pragma Abort_Defer’. This section summarizes which combinations of threads and exception support are supplied on various GNAT platforms. * Menu: * Summary of Run-Time Configurations::  File: gnat_ugn.info, Node: Summary of Run-Time Configurations, Up: Run-Time Libraries 7.1.1 Summary of Run-Time Configurations ---------------------------------------- Platform Run-Time Tasking Exceptions ---------------------------------------------------------------------------------------- GNU/Linux rts-native pthread library ZCX (default) rts-sjlj pthread library SJLJ Windows rts-native native Win32 threads ZCX (default) rts-sjlj native Win32 SJLJ threads Mac OS rts-native pthread library ZCX  File: gnat_ugn.info, Node: Specifying a Run-Time Library, Next: GNU/Linux Topics, Prev: Run-Time Libraries, Up: Platform-Specific Information 7.2 Specifying a Run-Time Library ================================= The ‘adainclude’ subdirectory containing the sources of the GNAT run-time library, and the ‘adalib’ subdirectory containing the ‘ALI’ files and the static and/or shared GNAT library, are located in the gcc target-dependent area: target=$prefix/lib/gcc/gcc-*dumpmachine*/gcc-*dumpversion*/ As indicated above, on some platforms several run-time libraries are supplied. These libraries are installed in the target dependent area and contain a complete source and binary subdirectory. The detailed description below explains the differences between the different libraries in terms of their thread support. The default run-time library (when GNAT is installed) is 'rts-native'. This default run-time is selected by the means of soft links. For example on x86-linux: $(target-dir) __/ / \ \___ _______/ / \ \_________________ / / \ \ / / \ \ ADAINCLUDE ADALIB rts-native rts-sjlj : : / \ / \ : : / \ / \ : : / \ / \ : : / \ / \ +-------------> adainclude adalib adainclude adalib : ^ : : +---------------------+ Run-Time Library Directory Structure (Upper-case names and dotted/dashed arrows represent soft links) If the 'rts-sjlj' library is to be selected on a permanent basis, these soft links can be modified with the following commands: $ cd $target $ rm -f adainclude adalib $ ln -s rts-sjlj/adainclude adainclude $ ln -s rts-sjlj/adalib adalib Alternatively, you can specify ‘rts-sjlj/adainclude’ in the file ‘$target/ada_source_path’ and ‘rts-sjlj/adalib’ in ‘$target/ada_object_path’. Selecting another run-time library temporarily can be achieved by using the ‘--RTS’ switch, e.g., ‘--RTS=sjlj’ * Menu: * Choosing the Scheduling Policy::  File: gnat_ugn.info, Node: Choosing the Scheduling Policy, Up: Specifying a Run-Time Library 7.2.1 Choosing the Scheduling Policy ------------------------------------ When using a POSIX threads implementation, you have a choice of several scheduling policies: ‘SCHED_FIFO’, ‘SCHED_RR’ and ‘SCHED_OTHER’. Typically, the default is ‘SCHED_OTHER’, while using ‘SCHED_FIFO’ or ‘SCHED_RR’ requires special (e.g., root) privileges. By default, GNAT uses the ‘SCHED_OTHER’ policy. To specify ‘SCHED_FIFO’, you can use one of the following: * ‘pragma Time_Slice (0.0)’ * the corresponding binder option ‘-T0’ * ‘pragma Task_Dispatching_Policy (FIFO_Within_Priorities)’ To specify ‘SCHED_RR’, you should use ‘pragma Time_Slice’ with a value greater than 0.0, or else use the corresponding ‘-T’ binder option. To make sure a program is running as root, you can put something like this in a library package body in your application: function geteuid return Integer; pragma Import (C, geteuid, "geteuid"); Ignore : constant Boolean := (if geteuid = 0 then True else raise Program_Error with "must be root"); It gets the effective user id, and if it’s not 0 (i.e. root), it raises Program_Error. Note that if you re running the code in a container, this may not be sufficient, as you may have sufficient priviledge on the container, but not on the host machine running the container, so check that you also have sufficient priviledge for running the container image.  File: gnat_ugn.info, Node: GNU/Linux Topics, Next: Microsoft Windows Topics, Prev: Specifying a Run-Time Library, Up: Platform-Specific Information 7.3 GNU/Linux Topics ==================== This section describes topics that are specific to GNU/Linux platforms. * Menu: * Required Packages on GNU/Linux:: * Position Independent Executable (PIE) Enabled by Default on Linux: Position Independent Executable PIE Enabled by Default on Linux. * A GNU/Linux Debug Quirk::  File: gnat_ugn.info, Node: Required Packages on GNU/Linux, Next: Position Independent Executable PIE Enabled by Default on Linux, Up: GNU/Linux Topics 7.3.1 Required Packages on GNU/Linux ------------------------------------ GNAT requires the C library developer’s package to be installed. The name of of that package depends on your GNU/Linux distribution: * RedHat, SUSE: ‘glibc-devel’; * Debian, Ubuntu: ‘libc6-dev’ (normally installed by default). If using the 32-bit version of GNAT on a 64-bit version of GNU/Linux, you’ll need the 32-bit version of the following packages: * RedHat, SUSE: ‘glibc.i686’, ‘glibc-devel.i686’, ‘ncurses-libs.i686’ * SUSE: ‘glibc-locale-base-32bit’ * Debian, Ubuntu: ‘libc6:i386’, ‘libc6-dev:i386’, ‘lib32ncursesw5’ Other GNU/Linux distributions might be choosing a different name for those packages.  File: gnat_ugn.info, Node: Position Independent Executable PIE Enabled by Default on Linux, Next: A GNU/Linux Debug Quirk, Prev: Required Packages on GNU/Linux, Up: GNU/Linux Topics 7.3.2 Position Independent Executable (PIE) Enabled by Default on Linux ----------------------------------------------------------------------- GNAT generates Position Independent Executable (PIE) code by default. PIE binaries are loaded into random memory locations, introducing an additional layer of protection against attacks. Building PIE binaries requires that all of their dependencies also be built as Position Independent. If the link of your project fails with an error like: /[...]/ld: /path/to/object/file: relocation R_X86_64_32S against symbol `symbol name' can not be used when making a PIE object; recompile with -fPIE it means the identified object file has not been built as Position Independent. If you are not interested in building PIE binaries, you can simply turn this feature off by first compiling your code with ‘-fno-pie’ and then by linking with ‘-no-pie’ (note the subtle but important difference in the names of the options – the linker option does 'not' have an ‘f’ after the dash!). When using gprbuild, this is achieved by updating the 'Required_Switches' attribute in package ‘Compiler’ and, depending on your type of project, either attribute 'Switches' or attribute 'Library_Options' in package ‘Linker’. On the other hand, if you would like to build PIE binaries and you are getting the error above, a quick and easy workaround to allow linking to succeed again is to disable PIE during the link, thus temporarily lifting the requirement that all dependencies also be Position Independent code. To do so, you simply need to add ‘-no-pie’ to the list of switches passed to the linker. As part of this workaround, there is no need to adjust the compiler switches. From there, to be able to link your binaries with PIE and therefore drop the ‘-no-pie’ workaround, you’ll need to get the identified dependencies rebuilt with PIE enabled (compiled with ‘-fPIE’ and linked with ‘-pie’).  File: gnat_ugn.info, Node: A GNU/Linux Debug Quirk, Prev: Position Independent Executable PIE Enabled by Default on Linux, Up: GNU/Linux Topics 7.3.3 A GNU/Linux Debug Quirk ----------------------------- On SuSE 15, some kernels have a defect causing issues when debugging programs using threads or Ada tasks. Due to the lack of documentation found regarding this kernel issue, we can only provide limited information about which kernels are impacted: kernel version 5.3.18 is known to be impacted, and kernels in the 5.14 range or newer are believed to fix this problem. The bug affects the debugging of 32-bit processes on a 64-bit system. Symptoms can vary: Unexpected ‘SIGABRT’ signals being received by the program, “The futex facility returned an unexpected error code” error message, and inferior programs hanging indefinitely range among the symptoms most commonly observed.  File: gnat_ugn.info, Node: Microsoft Windows Topics, Next: Mac OS Topics, Prev: GNU/Linux Topics, Up: Platform-Specific Information 7.4 Microsoft Windows Topics ============================ This section describes topics that are specific to the Microsoft Windows platforms. * Menu: * Using GNAT on Windows:: * Using a network installation of GNAT:: * CONSOLE and WINDOWS subsystems:: * Temporary Files:: * Disabling Command Line Argument Expansion:: * Windows Socket Timeouts:: * Mixed-Language Programming on Windows:: * Windows Specific Add-Ons::  File: gnat_ugn.info, Node: Using GNAT on Windows, Next: Using a network installation of GNAT, Up: Microsoft Windows Topics 7.4.1 Using GNAT on Windows --------------------------- One of the strengths of the GNAT technology is that its tool set (‘gcc’, ‘gnatbind’, ‘gnatlink’, ‘gnatmake’, the ‘gdb’ debugger, etc.) is used in the same way regardless of the platform. On Windows this tool set is complemented by a number of Microsoft-specific tools that have been provided to facilitate interoperability with Windows when this is required. With these tools: * You can build applications using the ‘CONSOLE’ or ‘WINDOWS’ subsystems. * You can use any Dynamically Linked Library (DLL) in your Ada code (both relocatable and non-relocatable DLLs are supported). * You can build Ada DLLs for use in other applications. These applications can be written in a language other than Ada (e.g., C, C++, etc). Again both relocatable and non-relocatable Ada DLLs are supported. * You can include Windows resources in your Ada application. * You can use or create COM/DCOM objects. Immediately below are listed all known general GNAT-for-Windows restrictions. Other restrictions about specific features like Windows Resources and DLLs are listed in separate sections below. * It is not possible to use ‘GetLastError’ and ‘SetLastError’ when tasking, protected records, or exceptions are used. In these cases, in order to implement Ada semantics, the GNAT run-time system calls certain Win32 routines that set the last error variable to 0 upon success. It should be possible to use ‘GetLastError’ and ‘SetLastError’ when tasking, protected record, and exception features are not used, but it is not guaranteed to work. * It is not possible to link against Microsoft C++ libraries except for import libraries. Interfacing must be done by the mean of DLLs. * It is possible to link against Microsoft C libraries. Yet the preferred solution is to use C/C++ compiler that comes with GNAT, since it doesn’t require having two different development environments and makes the inter-language debugging experience smoother. * When the compilation environment is located on FAT32 drives, users may experience recompilations of the source files that have not changed if Daylight Saving Time (DST) state has changed since the last time files were compiled. NTFS drives do not have this problem. * No components of the GNAT toolset use any entries in the Windows registry. The only entries that can be created are file associations and PATH settings, provided the user has chosen to create them at installation time, as well as some minimal book-keeping information needed to correctly uninstall or integrate different GNAT products.  File: gnat_ugn.info, Node: Using a network installation of GNAT, Next: CONSOLE and WINDOWS subsystems, Prev: Using GNAT on Windows, Up: Microsoft Windows Topics 7.4.2 Using a network installation of GNAT ------------------------------------------ Make sure the system on which GNAT is installed is accessible from the current machine, i.e., the install location is shared over the network. Shared resources are accessed on Windows by means of UNC paths, which have the format ‘\\\\server\\sharename\\path’ In order to use such a network installation, simply add the UNC path of the ‘bin’ directory of your GNAT installation in front of your PATH. For example, if GNAT is installed in ‘\GNAT’ directory of a share location called ‘c-drive’ on a machine ‘LOKI’, the following command will make it available: $ path \\loki\c-drive\gnat\bin;%path%` Be aware that every compilation using the network installation results in the transfer of large amounts of data across the network and will likely cause serious performance penalty.  File: gnat_ugn.info, Node: CONSOLE and WINDOWS subsystems, Next: Temporary Files, Prev: Using a network installation of GNAT, Up: Microsoft Windows Topics 7.4.3 CONSOLE and WINDOWS subsystems ------------------------------------ There are two main subsystems under Windows. The ‘CONSOLE’ subsystem (which is the default subsystem) will always create a console when launching the application. This is not something desirable when the application has a Windows GUI. To get rid of this console the application must be using the ‘WINDOWS’ subsystem. To do so the ‘-mwindows’ linker option must be specified. $ gnatmake winprog -largs -mwindows  File: gnat_ugn.info, Node: Temporary Files, Next: Disabling Command Line Argument Expansion, Prev: CONSOLE and WINDOWS subsystems, Up: Microsoft Windows Topics 7.4.4 Temporary Files --------------------- It is possible to control where temporary files gets created by setting the ‘TMP’ environment variable. The file will be created: * Under the directory pointed to by the ‘TMP’ environment variable if this directory exists. * Under ‘c:\temp’, if the ‘TMP’ environment variable is not set (or not pointing to a directory) and if this directory exists. * Under the current working directory otherwise. This allows you to determine exactly where the temporary file will be created. This is particularly useful in networked environments where you may not have write access to some directories.  File: gnat_ugn.info, Node: Disabling Command Line Argument Expansion, Next: Windows Socket Timeouts, Prev: Temporary Files, Up: Microsoft Windows Topics 7.4.5 Disabling Command Line Argument Expansion ----------------------------------------------- By default, an executable compiled for the Windows platform will do the following postprocessing on the arguments passed on the command line: * If the argument contains the characters ‘*’ and/or ‘?’, then file expansion will be attempted. For example, if the current directory contains ‘a.txt’ and ‘b.txt’, then when calling: $ my_ada_program *.txt The following arguments will effectively be passed to the main program (for example when using ‘Ada.Command_Line.Argument’): Ada.Command_Line.Argument (1) -> "a.txt" Ada.Command_Line.Argument (2) -> "b.txt" * Filename expansion can be disabled for a given argument by using single quotes. Thus, calling: $ my_ada_program '*.txt' will result in: Ada.Command_Line.Argument (1) -> "*.txt" Note that if the program is launched from a shell such as Cygwin Bash then quote removal might be performed by the shell. In some contexts it might be useful to disable this feature (for example if the program performs its own argument expansion). In order to do this, a C symbol needs to be defined and set to ‘0’. You can do this by adding the following code fragment in one of your Ada units: Do_Argv_Expansion : Integer := 0; pragma Export (C, Do_Argv_Expansion, "__gnat_do_argv_expansion"); The results of previous examples will be respectively: Ada.Command_Line.Argument (1) -> "*.txt" and: Ada.Command_Line.Argument (1) -> "'*.txt'"  File: gnat_ugn.info, Node: Windows Socket Timeouts, Next: Mixed-Language Programming on Windows, Prev: Disabling Command Line Argument Expansion, Up: Microsoft Windows Topics 7.4.6 Windows Socket Timeouts ----------------------------- Microsoft Windows desktops older than ‘8.0’ and Microsoft Windows Servers older than ‘2019’ set a socket timeout 500 milliseconds longer than the value set by setsockopt with ‘SO_RCVTIMEO’ and ‘SO_SNDTIMEO’ options. The GNAT runtime makes a correction for the difference in the corresponding Windows versions. For Windows Server starting with version ‘2019’, the user must provide a manifest file for the GNAT runtime to be able to recognize that the Windows version does not need the timeout correction. The manifest file should be located in the same directory as the executable file, and its file name must match the executable name suffixed by ‘.manifest’. For example, if the executable name is ‘sock_wto.exe’, then the manifest file name has to be ‘sock_wto.exe.manifest’. The manifest file must contain at least the following data: Without the manifest file, the socket timeout is going to be overcorrected on these Windows Server versions and the actual time is going to be 500 milliseconds shorter than what was set with GNAT.Sockets.Set_Socket_Option. Note that on Microsoft Windows versions where correction is necessary, there is no way to set a socket timeout shorter than 500 ms. If a socket timeout shorter than 500 ms is needed on these Windows versions, a call to Check_Selector should be added before any socket read or write operations.  File: gnat_ugn.info, Node: Mixed-Language Programming on Windows, Next: Windows Specific Add-Ons, Prev: Windows Socket Timeouts, Up: Microsoft Windows Topics 7.4.7 Mixed-Language Programming on Windows ------------------------------------------- Developing pure Ada applications on Windows is no different than on other GNAT-supported platforms. However, when developing or porting an application that contains a mix of Ada and C/C++, the choice of your Windows C/C++ development environment conditions your overall interoperability strategy. If you use ‘gcc’ or Microsoft C to compile the non-Ada part of your application, there are no Windows-specific restrictions that affect the overall interoperability with your Ada code. If you do want to use the Microsoft tools for your C++ code, you have two choices: * Encapsulate your C++ code in a DLL to be linked with your Ada application. In this case, use the Microsoft or whatever environment to build the DLL and use GNAT to build your executable (*note Using DLLs with GNAT: 1d3.). * Or you can encapsulate your Ada code in a DLL to be linked with the other part of your application. In this case, use GNAT to build the DLL (*note Building DLLs with GNAT Project files: 1d4.) and use the Microsoft or whatever environment to build your executable. In addition to the description about C main in *note Mixed Language Programming: 2c. section, if the C main uses a stand-alone library it is required on x86-windows to setup the SEH context. For this the C main must looks like this: /* main.c */ extern void adainit (void); extern void adafinal (void); extern void __gnat_initialize(void*); extern void call_to_ada (void); int main (int argc, char *argv[]) { int SEH [2]; /* Initialize the SEH context */ __gnat_initialize (&SEH); adainit(); /* Then call Ada services in the stand-alone library */ call_to_ada(); adafinal(); } Note that this is not needed on x86_64-windows where the Windows native SEH support is used. * Menu: * Windows Calling Conventions:: * Introduction to Dynamic Link Libraries (DLLs): Introduction to Dynamic Link Libraries DLLs. * Using DLLs with GNAT:: * Building DLLs with GNAT Project files:: * Building DLLs with GNAT:: * Building DLLs with gnatdll:: * Ada DLLs and Finalization:: * Creating a Spec for Ada DLLs:: * GNAT and Windows Resources:: * Using GNAT DLLs from Microsoft Visual Studio Applications:: * Debugging a DLL:: * Setting Stack Size from gnatlink:: * Setting Heap Size from gnatlink::  File: gnat_ugn.info, Node: Windows Calling Conventions, Next: Introduction to Dynamic Link Libraries DLLs, Up: Mixed-Language Programming on Windows 7.4.7.1 Windows Calling Conventions ................................... This section pertain only to Win32. On Win64 there is a single native calling convention. All convention specifiers are ignored on this platform. When a subprogram ‘F’ (caller) calls a subprogram ‘G’ (callee), there are several ways to push ‘G’‘s parameters on the stack and there are several possible scenarios to clean up the stack upon ‘G’‘s return. A calling convention is an agreed upon software protocol whereby the responsibilities between the caller (‘F’) and the callee (‘G’) are clearly defined. Several calling conventions are available for Windows: * ‘C’ (Microsoft defined) * ‘Stdcall’ (Microsoft defined) * ‘Win32’ (GNAT specific) * ‘DLL’ (GNAT specific) * Menu: * C Calling Convention:: * Stdcall Calling Convention:: * Win32 Calling Convention:: * DLL Calling Convention::  File: gnat_ugn.info, Node: C Calling Convention, Next: Stdcall Calling Convention, Up: Windows Calling Conventions 7.4.7.2 ‘C’ Calling Convention .............................. This is the default calling convention used when interfacing to C/C++ routines compiled with either ‘gcc’ or Microsoft Visual C++. In the ‘C’ calling convention subprogram parameters are pushed on the stack by the caller from right to left. The caller itself is in charge of cleaning up the stack after the call. In addition, the name of a routine with ‘C’ calling convention is mangled by adding a leading underscore. The name to use on the Ada side when importing (or exporting) a routine with ‘C’ calling convention is the name of the routine. For instance the C function: int get_val (long); should be imported from Ada as follows: function Get_Val (V : Interfaces.C.long) return Interfaces.C.int; pragma Import (C, Get_Val, External_Name => "get_val"); Note that in this particular case the ‘External_Name’ parameter could have been omitted since, when missing, this parameter is taken to be the name of the Ada entity in lower case. When the ‘Link_Name’ parameter is missing, as in the above example, this parameter is set to be the ‘External_Name’ with a leading underscore. When importing a variable defined in C, you should always use the ‘C’ calling convention unless the object containing the variable is part of a DLL (in which case you should use the ‘Stdcall’ calling convention, *note Stdcall Calling Convention: 1d9.).  File: gnat_ugn.info, Node: Stdcall Calling Convention, Next: Win32 Calling Convention, Prev: C Calling Convention, Up: Windows Calling Conventions 7.4.7.3 ‘Stdcall’ Calling Convention .................................... This convention, which was the calling convention used for Pascal programs, is used by Microsoft for all the routines in the Win32 API for efficiency reasons. It must be used to import any routine for which this convention was specified. In the ‘Stdcall’ calling convention subprogram parameters are pushed on the stack by the caller from right to left. The callee (and not the caller) is in charge of cleaning the stack on routine exit. In addition, the name of a routine with ‘Stdcall’ calling convention is mangled by adding a leading underscore (as for the ‘C’ calling convention) and a trailing ‘@NN’, where ‘nn’ is the overall size (in bytes) of the parameters passed to the routine. The name to use on the Ada side when importing a C routine with a ‘Stdcall’ calling convention is the name of the C routine. The leading underscore and trailing ‘@NN’ are added automatically by the compiler. For instance the Win32 function: APIENTRY int get_val (long); should be imported from Ada as follows: function Get_Val (V : Interfaces.C.long) return Interfaces.C.int; pragma Import (Stdcall, Get_Val); -- On the x86 a long is 4 bytes, so the Link_Name is "_get_val@4" As for the ‘C’ calling convention, when the ‘External_Name’ parameter is missing, it is taken to be the name of the Ada entity in lower case. If instead of writing the above import pragma you write: function Get_Val (V : Interfaces.C.long) return Interfaces.C.int; pragma Import (Stdcall, Get_Val, External_Name => "retrieve_val"); then the imported routine is ‘_retrieve_val@4’. However, if instead of specifying the ‘External_Name’ parameter you specify the ‘Link_Name’ as in the following example: function Get_Val (V : Interfaces.C.long) return Interfaces.C.int; pragma Import (Stdcall, Get_Val, Link_Name => "retrieve_val"); then the imported routine is ‘retrieve_val’, that is, there is no decoration at all. No leading underscore and no Stdcall suffix ‘@NN’. This is especially important as in some special cases a DLL’s entry point name lacks a trailing ‘@NN’ while the exported name generated for a call has it. It is also possible to import variables defined in a DLL by using an import pragma for a variable. As an example, if a DLL contains a variable defined as: int my_var; then, to access this variable from Ada you should write: My_Var : Interfaces.C.int; pragma Import (Stdcall, My_Var); Note that to ease building cross-platform bindings this convention will be handled as a ‘C’ calling convention on non-Windows platforms.  File: gnat_ugn.info, Node: Win32 Calling Convention, Next: DLL Calling Convention, Prev: Stdcall Calling Convention, Up: Windows Calling Conventions 7.4.7.4 ‘Win32’ Calling Convention .................................. This convention, which is GNAT-specific is fully equivalent to the ‘Stdcall’ calling convention described above.  File: gnat_ugn.info, Node: DLL Calling Convention, Prev: Win32 Calling Convention, Up: Windows Calling Conventions 7.4.7.5 ‘DLL’ Calling Convention ................................ This convention, which is GNAT-specific is fully equivalent to the ‘Stdcall’ calling convention described above.  File: gnat_ugn.info, Node: Introduction to Dynamic Link Libraries DLLs, Next: Using DLLs with GNAT, Prev: Windows Calling Conventions, Up: Mixed-Language Programming on Windows 7.4.7.6 Introduction to Dynamic Link Libraries (DLLs) ..................................................... A Dynamically Linked Library (DLL) is a library that can be shared by several applications running under Windows. A DLL can contain any number of routines and variables. One advantage of DLLs is that you can change and enhance them without forcing all the applications that depend on them to be relinked or recompiled. However, you should be aware than all calls to DLL routines are slower since, as you will understand below, such calls are indirect. To illustrate the remainder of this section, suppose that an application wants to use the services of a DLL ‘API.dll’. To use the services provided by ‘API.dll’ you must statically link against the DLL or an import library which contains a jump table with an entry for each routine and variable exported by the DLL. In the Microsoft world this import library is called ‘API.lib’. When using GNAT this import library is called either ‘libAPI.dll.a’, ‘libapi.dll.a’, ‘libAPI.a’ or ‘libapi.a’ (names are case insensitive). After you have linked your application with the DLL or the import library and you run your application, here is what happens: * Your application is loaded into memory. * The DLL ‘API.dll’ is mapped into the address space of your application. This means that: - The DLL will use the stack of the calling thread. - The DLL will use the virtual address space of the calling process. - The DLL will allocate memory from the virtual address space of the calling process. - Handles (pointers) can be safely exchanged between routines in the DLL routines and routines in the application using the DLL. * The entries in the jump table (from the import library ‘libAPI.dll.a’ or ‘API.lib’ or automatically created when linking against a DLL) which is part of your application are initialized with the addresses of the routines and variables in ‘API.dll’. * If present in ‘API.dll’, routines ‘DllMain’ or ‘DllMainCRTStartup’ are invoked. These routines typically contain the initialization code needed for the well-being of the routines and variables exported by the DLL. There is an additional point which is worth mentioning. In the Windows world there are two kind of DLLs: relocatable and non-relocatable DLLs. Non-relocatable DLLs can only be loaded at a very specific address in the target application address space. If the addresses of two non-relocatable DLLs overlap and these happen to be used by the same application, a conflict will occur and the application will run incorrectly. Hence, when possible, it is always preferable to use and build relocatable DLLs. Both relocatable and non-relocatable DLLs are supported by GNAT. Note that the ‘-s’ linker option (see GNU Linker User’s Guide) removes the debugging symbols from the DLL but the DLL can still be relocated. As a side note, an interesting difference between Microsoft DLLs and Unix shared libraries, is the fact that on most Unix systems all public routines are exported by default in a Unix shared library, while under Windows it is possible (but not required) to list exported routines in a definition file (see *note The Definition File: 1e1.).  File: gnat_ugn.info, Node: Using DLLs with GNAT, Next: Building DLLs with GNAT Project files, Prev: Introduction to Dynamic Link Libraries DLLs, Up: Mixed-Language Programming on Windows 7.4.7.7 Using DLLs with GNAT ............................ To use the services of a DLL, say ‘API.dll’, in your Ada application you must have: * The Ada spec for the routines and/or variables you want to access in ‘API.dll’. If not available this Ada spec must be built from the C/C++ header files provided with the DLL. * The import library (‘libAPI.dll.a’ or ‘API.lib’). As previously mentioned an import library is a statically linked library containing the import table which will be filled at load time to point to the actual ‘API.dll’ routines. Sometimes you don’t have an import library for the DLL you want to use. The following sections will explain how to build one. Note that this is optional. * The actual DLL, ‘API.dll’. Once you have all the above, to compile an Ada application that uses the services of ‘API.dll’ and whose main subprogram is ‘My_Ada_App’, you simply issue the command $ gnatmake my_ada_app -largs -lAPI The argument ‘-largs -lAPI’ at the end of the ‘gnatmake’ command tells the GNAT linker to look for an import library. The linker will look for a library name in this specific order: * ‘libAPI.dll.a’ * ‘API.dll.a’ * ‘libAPI.a’ * ‘API.lib’ * ‘libAPI.dll’ * ‘API.dll’ The first three are the GNU style import libraries. The third is the Microsoft style import libraries. The last two are the actual DLL names. Note that if the Ada package spec for ‘API.dll’ contains the following pragma pragma Linker_Options ("-lAPI"); you do not have to add ‘-largs -lAPI’ at the end of the ‘gnatmake’ command. If any one of the items above is missing you will have to create it yourself. The following sections explain how to do so using as an example a fictitious DLL called ‘API.dll’. * Menu: * Creating an Ada Spec for the DLL Services:: * Creating an Import Library::  File: gnat_ugn.info, Node: Creating an Ada Spec for the DLL Services, Next: Creating an Import Library, Up: Using DLLs with GNAT 7.4.7.8 Creating an Ada Spec for the DLL Services ................................................. A DLL typically comes with a C/C++ header file which provides the definitions of the routines and variables exported by the DLL. The Ada equivalent of this header file is a package spec that contains definitions for the imported entities. If the DLL you intend to use does not come with an Ada spec you have to generate one such spec yourself. For example if the header file of ‘API.dll’ is a file ‘api.h’ containing the following two definitions: int some_var; int get (char *); then the equivalent Ada spec could be: with Interfaces.C.Strings; package API is use Interfaces; Some_Var : C.int; function Get (Str : C.Strings.Chars_Ptr) return C.int; private pragma Import (C, Get); pragma Import (DLL, Some_Var); end API;  File: gnat_ugn.info, Node: Creating an Import Library, Prev: Creating an Ada Spec for the DLL Services, Up: Using DLLs with GNAT 7.4.7.9 Creating an Import Library .................................. If a Microsoft-style import library ‘API.lib’ or a GNAT-style import library ‘libAPI.dll.a’ or ‘libAPI.a’ is available with ‘API.dll’ you can skip this section. You can also skip this section if ‘API.dll’ or ‘libAPI.dll’ is built with GNU tools as in this case it is possible to link directly against the DLL. Otherwise read on. The Definition File ................... As previously mentioned, and unlike Unix systems, the list of symbols that are exported from a DLL must be provided explicitly in Windows. The main goal of a definition file is precisely that: list the symbols exported by a DLL. A definition file (usually a file with a ‘.def’ suffix) has the following structure: [LIBRARY ``name``] [DESCRIPTION ``string``] EXPORTS ``symbol1`` ``symbol2`` ... 'LIBRARY name' This section, which is optional, gives the name of the DLL. 'DESCRIPTION string' This section, which is optional, gives a description string that will be embedded in the import library. 'EXPORTS' This section gives the list of exported symbols (procedures, functions or variables). For instance in the case of ‘API.dll’ the ‘EXPORTS’ section of ‘API.def’ looks like: EXPORTS some_var get Note that you must specify the correct suffix (‘@NN’) (see *note Windows Calling Conventions: 1d6.) for a Stdcall calling convention function in the exported symbols list. There can actually be other sections in a definition file, but these sections are not relevant to the discussion at hand. Creating a Definition File Automatically ........................................ You can automatically create the definition file ‘API.def’ (see *note The Definition File: 1e1.) from a DLL. For that use the ‘dlltool’ program as follows: $ dlltool API.dll -z API.def --export-all-symbols Note that if some routines in the DLL have the ‘Stdcall’ convention (*note Windows Calling Conventions: 1d6.) with stripped ‘@NN’ suffix then you’ll have to edit ‘api.def’ to add it, and specify ‘-k’ to ‘gnatdll’ when creating the import library. Here are some hints to find the right ‘@NN’ suffix. - If you have the Microsoft import library (.lib), it is possible to get the right symbols by using Microsoft ‘dumpbin’ tool (see the corresponding Microsoft documentation for further details). $ dumpbin /exports api.lib - If you have a message about a missing symbol at link time the compiler tells you what symbol is expected. You just have to go back to the definition file and add the right suffix. GNAT-Style Import Library ......................... To create a static import library from ‘API.dll’ with the GNAT tools you should create the .def file, then use ‘gnatdll’ tool (see *note Using gnatdll: 1e9.) as follows: $ gnatdll -e API.def -d API.dll ‘gnatdll’ takes as input a definition file ‘API.def’ and the name of the DLL containing the services listed in the definition file ‘API.dll’. The name of the static import library generated is computed from the name of the definition file as follows: if the definition file name is ‘xyz.def’, the import library name will be ‘libxyz.a’. Note that in the previous example option ‘-e’ could have been removed because the name of the definition file (before the ‘.def’ suffix) is the same as the name of the DLL (*note Using gnatdll: 1e9. for more information about ‘gnatdll’). Microsoft-Style Import Library .............................. A Microsoft import library is needed only if you plan to make an Ada DLL available to applications developed with Microsoft tools (*note Mixed-Language Programming on Windows: 1d2.). To create a Microsoft-style import library for ‘API.dll’ you should create the .def file, then build the actual import library using Microsoft’s ‘lib’ utility: $ lib -machine:IX86 -def:API.def -out:API.lib If you use the above command the definition file ‘API.def’ must contain a line giving the name of the DLL: LIBRARY "API" See the Microsoft documentation for further details about the usage of ‘lib’.  File: gnat_ugn.info, Node: Building DLLs with GNAT Project files, Next: Building DLLs with GNAT, Prev: Using DLLs with GNAT, Up: Mixed-Language Programming on Windows 7.4.7.10 Building DLLs with GNAT Project files .............................................. There is nothing specific to Windows in the build process. See the 'Library Projects' section in the 'GNAT Project Manager' chapter of the 'GPRbuild User’s Guide'. Due to a system limitation, it is not possible under Windows to create threads when inside the ‘DllMain’ routine which is used for auto-initialization of shared libraries, so it is not possible to have library level tasks in SALs.  File: gnat_ugn.info, Node: Building DLLs with GNAT, Next: Building DLLs with gnatdll, Prev: Building DLLs with GNAT Project files, Up: Mixed-Language Programming on Windows 7.4.7.11 Building DLLs with GNAT ................................ This section explain how to build DLLs using the GNAT built-in DLL support. With the following procedure it is straight forward to build and use DLLs with GNAT. * Building object files. The first step is to build all objects files that are to be included into the DLL. This is done by using the standard ‘gnatmake’ tool. * Building the DLL. To build the DLL you must use the ‘gcc’ ‘-shared’ and ‘-shared-libgcc’ options. It is quite simple to use this method: $ gcc -shared -shared-libgcc -o api.dll obj1.o obj2.o ... It is important to note that in this case all symbols found in the object files are automatically exported. It is possible to restrict the set of symbols to export by passing to ‘gcc’ a definition file (see *note The Definition File: 1e1.). For example: $ gcc -shared -shared-libgcc -o api.dll api.def obj1.o obj2.o ... If you use a definition file you must export the elaboration procedures for every package that required one. Elaboration procedures are named using the package name followed by “_E”. * Preparing DLL to be used. For the DLL to be used by client programs the bodies must be hidden from it and the .ali set with read-only attribute. This is very important otherwise GNAT will recompile all packages and will not actually use the code in the DLL. For example: $ mkdir apilib $ copy *.ads *.ali api.dll apilib $ attrib +R apilib\\*.ali At this point it is possible to use the DLL by directly linking against it. Note that you must use the GNAT shared runtime when using GNAT shared libraries. This is achieved by using the ‘-shared’ binder option. $ gnatmake main -Iapilib -bargs -shared -largs -Lapilib -lAPI  File: gnat_ugn.info, Node: Building DLLs with gnatdll, Next: Ada DLLs and Finalization, Prev: Building DLLs with GNAT, Up: Mixed-Language Programming on Windows 7.4.7.12 Building DLLs with gnatdll ................................... Note that it is preferred to use GNAT Project files (*note Building DLLs with GNAT Project files: 1d4.) or the built-in GNAT DLL support (*note Building DLLs with GNAT: 1ec.) or to build DLLs. This section explains how to build DLLs containing Ada code using ‘gnatdll’. These DLLs will be referred to as Ada DLLs in the remainder of this section. The steps required to build an Ada DLL that is to be used by Ada as well as non-Ada applications are as follows: * You need to mark each Ada entity exported by the DLL with a ‘C’ or ‘Stdcall’ calling convention to avoid any Ada name mangling for the entities exported by the DLL (see *note Exporting Ada Entities: 1f0.). You can skip this step if you plan to use the Ada DLL only from Ada applications. * Your Ada code must export an initialization routine which calls the routine ‘adainit’ generated by ‘gnatbind’ to perform the elaboration of the Ada code in the DLL (*note Ada DLLs and Elaboration: 1f1.). The initialization routine exported by the Ada DLL must be invoked by the clients of the DLL to initialize the DLL. * When useful, the DLL should also export a finalization routine which calls routine ‘adafinal’ generated by ‘gnatbind’ to perform the finalization of the Ada code in the DLL (*note Ada DLLs and Finalization: 1f2.). The finalization routine exported by the Ada DLL must be invoked by the clients of the DLL when the DLL services are no further needed. * You must provide a spec for the services exported by the Ada DLL in each of the programming languages to which you plan to make the DLL available. * You must provide a definition file listing the exported entities (*note The Definition File: 1e1.). * Finally you must use ‘gnatdll’ to produce the DLL and the import library (*note Using gnatdll: 1e9.). Note that a relocatable DLL stripped using the ‘strip’ binutils tool will not be relocatable anymore. To build a DLL without debug information pass ‘-largs -s’ to ‘gnatdll’. This restriction does not apply to a DLL built using a Library Project. See the 'Library Projects' section in the 'GNAT Project Manager' chapter of the 'GPRbuild User’s Guide'. * Menu: * Limitations When Using Ada DLLs from Ada:: * Exporting Ada Entities:: * Ada DLLs and Elaboration::  File: gnat_ugn.info, Node: Limitations When Using Ada DLLs from Ada, Next: Exporting Ada Entities, Up: Building DLLs with gnatdll 7.4.7.13 Limitations When Using Ada DLLs from Ada ................................................. When using Ada DLLs from Ada applications there is a limitation users should be aware of. Because on Windows the GNAT run-time is not in a DLL of its own, each Ada DLL includes a part of the GNAT run-time. Specifically, each Ada DLL includes the services of the GNAT run-time that are necessary to the Ada code inside the DLL. As a result, when an Ada program uses an Ada DLL there are two independent GNAT run-times: one in the Ada DLL and one in the main program. It is therefore not possible to exchange GNAT run-time objects between the Ada DLL and the main Ada program. Example of GNAT run-time objects are file handles (e.g., ‘Text_IO.File_Type’), tasks types, protected objects types, etc. It is completely safe to exchange plain elementary, array or record types, Windows object handles, etc.  File: gnat_ugn.info, Node: Exporting Ada Entities, Next: Ada DLLs and Elaboration, Prev: Limitations When Using Ada DLLs from Ada, Up: Building DLLs with gnatdll 7.4.7.14 Exporting Ada Entities ............................... Building a DLL is a way to encapsulate a set of services usable from any application. As a result, the Ada entities exported by a DLL should be exported with the ‘C’ or ‘Stdcall’ calling conventions to avoid any Ada name mangling. As an example here is an Ada package ‘API’, spec and body, exporting two procedures, a function, and a variable: with Interfaces.C; use Interfaces; package API is Count : C.int := 0; function Factorial (Val : C.int) return C.int; procedure Initialize_API; procedure Finalize_API; -- Initialization & Finalization routines. More in the next section. private pragma Export (C, Initialize_API); pragma Export (C, Finalize_API); pragma Export (C, Count); pragma Export (C, Factorial); end API; package body API is function Factorial (Val : C.int) return C.int is Fact : C.int := 1; begin Count := Count + 1; for K in 1 .. Val loop Fact := Fact * K; end loop; return Fact; end Factorial; procedure Initialize_API is procedure Adainit; pragma Import (C, Adainit); begin Adainit; end Initialize_API; procedure Finalize_API is procedure Adafinal; pragma Import (C, Adafinal); begin Adafinal; end Finalize_API; end API; If the Ada DLL you are building will only be used by Ada applications you do not have to export Ada entities with a ‘C’ or ‘Stdcall’ convention. As an example, the previous package could be written as follows: package API is Count : Integer := 0; function Factorial (Val : Integer) return Integer; procedure Initialize_API; procedure Finalize_API; -- Initialization and Finalization routines. end API; package body API is function Factorial (Val : Integer) return Integer is Fact : Integer := 1; begin Count := Count + 1; for K in 1 .. Val loop Fact := Fact * K; end loop; return Fact; end Factorial; ... -- The remainder of this package body is unchanged. end API; Note that if you do not export the Ada entities with a ‘C’ or ‘Stdcall’ convention you will have to provide the mangled Ada names in the definition file of the Ada DLL (*note Creating the Definition File: 1f5.).  File: gnat_ugn.info, Node: Ada DLLs and Elaboration, Prev: Exporting Ada Entities, Up: Building DLLs with gnatdll 7.4.7.15 Ada DLLs and Elaboration ................................. The DLL that you are building contains your Ada code as well as all the routines in the Ada library that are needed by it. The first thing a user of your DLL must do is elaborate the Ada code (*note Elaboration Order Handling in GNAT: f.). To achieve this you must export an initialization routine (‘Initialize_API’ in the previous example), which must be invoked before using any of the DLL services. This elaboration routine must call the Ada elaboration routine ‘adainit’ generated by the GNAT binder (*note Binding with Non-Ada Main Programs: 7e.). See the body of ‘Initialize_Api’ for an example. Note that the GNAT binder is automatically invoked during the DLL build process by the ‘gnatdll’ tool (*note Using gnatdll: 1e9.). When a DLL is loaded, Windows systematically invokes a routine called ‘DllMain’. It would therefore be possible to call ‘adainit’ directly from ‘DllMain’ without having to provide an explicit initialization routine. Unfortunately, it is not possible to call ‘adainit’ from the ‘DllMain’ if your program has library level tasks because access to the ‘DllMain’ entry point is serialized by the system (that is, only a single thread can execute ‘through’ it at a time), which means that the GNAT run-time will deadlock waiting for the newly created task to complete its initialization.  File: gnat_ugn.info, Node: Ada DLLs and Finalization, Next: Creating a Spec for Ada DLLs, Prev: Building DLLs with gnatdll, Up: Mixed-Language Programming on Windows 7.4.7.16 Ada DLLs and Finalization .................................. When the services of an Ada DLL are no longer needed, the client code should invoke the DLL finalization routine, if available. The DLL finalization routine is in charge of releasing all resources acquired by the DLL. In the case of the Ada code contained in the DLL, this is achieved by calling routine ‘adafinal’ generated by the GNAT binder (*note Binding with Non-Ada Main Programs: 7e.). See the body of ‘Finalize_Api’ for an example. As already pointed out the GNAT binder is automatically invoked during the DLL build process by the ‘gnatdll’ tool (*note Using gnatdll: 1e9.).  File: gnat_ugn.info, Node: Creating a Spec for Ada DLLs, Next: GNAT and Windows Resources, Prev: Ada DLLs and Finalization, Up: Mixed-Language Programming on Windows 7.4.7.17 Creating a Spec for Ada DLLs ..................................... To use the services exported by the Ada DLL from another programming language (e.g., C), you have to translate the specs of the exported Ada entities in that language. For instance in the case of ‘API.dll’, the corresponding C header file could look like: extern int *_imp__count; #define count (*_imp__count) int factorial (int); It is important to understand that when building an Ada DLL to be used by other Ada applications, you need two different specs for the packages contained in the DLL: one for building the DLL and the other for using the DLL. This is because the ‘DLL’ calling convention is needed to use a variable defined in a DLL, but when building the DLL, the variable must have either the ‘Ada’ or ‘C’ calling convention. As an example consider a DLL comprising the following package ‘API’: package API is Count : Integer := 0; ... -- Remainder of the package omitted. end API; After producing a DLL containing package ‘API’, the spec that must be used to import ‘API.Count’ from Ada code outside of the DLL is: package API is Count : Integer; pragma Import (DLL, Count); end API; * Menu: * Creating the Definition File:: * Using gnatdll::  File: gnat_ugn.info, Node: Creating the Definition File, Next: Using gnatdll, Up: Creating a Spec for Ada DLLs 7.4.7.18 Creating the Definition File ..................................... The definition file is the last file needed to build the DLL. It lists the exported symbols. As an example, the definition file for a DLL containing only package ‘API’ (where all the entities are exported with a ‘C’ calling convention) is: EXPORTS count factorial finalize_api initialize_api If the ‘C’ calling convention is missing from package ‘API’, then the definition file contains the mangled Ada names of the above entities, which in this case are: EXPORTS api__count api__factorial api__finalize_api api__initialize_api  File: gnat_ugn.info, Node: Using gnatdll, Prev: Creating the Definition File, Up: Creating a Spec for Ada DLLs 7.4.7.19 Using ‘gnatdll’ ........................ ‘gnatdll’ is a tool to automate the DLL build process once all the Ada and non-Ada sources that make up your DLL have been compiled. ‘gnatdll’ is actually in charge of two distinct tasks: build the static import library for the DLL and the actual DLL. The form of the ‘gnatdll’ command is $ gnatdll [ switches ] list-of-files [ -largs opts ] where ‘list-of-files’ is a list of ALI and object files. The object file list must be the exact list of objects corresponding to the non-Ada sources whose services are to be included in the DLL. The ALI file list must be the exact list of ALI files for the corresponding Ada sources whose services are to be included in the DLL. If ‘list-of-files’ is missing, only the static import library is generated. You may specify any of the following switches to ‘gnatdll’: ‘-a[`address']’ Build a non-relocatable DLL at ‘address’. If ‘address’ is not specified the default address ‘0x11000000’ will be used. By default, when this switch is missing, ‘gnatdll’ builds relocatable DLL. We advise the reader to build relocatable DLL. ‘-b `address'’ Set the relocatable DLL base address. By default the address is ‘0x11000000’. ‘-bargs `opts'’ Binder options. Pass ‘opts’ to the binder. ‘-d `dllfile'’ ‘dllfile’ is the name of the DLL. This switch must be present for ‘gnatdll’ to do anything. The name of the generated import library is obtained algorithmically from ‘dllfile’ as shown in the following example: if ‘dllfile’ is ‘xyz.dll’, the import library name is ‘libxyz.dll.a’. The name of the definition file to use (if not specified by option ‘-e’) is obtained algorithmically from ‘dllfile’ as shown in the following example: if ‘dllfile’ is ‘xyz.dll’, the definition file used is ‘xyz.def’. ‘-e `deffile'’ ‘deffile’ is the name of the definition file. ‘-g’ Generate debugging information. This information is stored in the object file and copied from there to the final DLL file by the linker, where it can be read by the debugger. You must use the ‘-g’ switch if you plan on using the debugger or the symbolic stack traceback. ‘-h’ Help mode. Displays ‘gnatdll’ switch usage information. ‘-I`dir'’ Direct ‘gnatdll’ to search the ‘dir’ directory for source and object files needed to build the DLL. (*note Search Paths and the Run-Time Library (RTL): 73.). ‘-k’ Removes the ‘@NN’ suffix from the import library’s exported names, but keeps them for the link names. You must specify this option if you want to use a ‘Stdcall’ function in a DLL for which the ‘@NN’ suffix has been removed. This is the case for most of the Windows NT DLL for example. This option has no effect when ‘-n’ option is specified. ‘-l `file'’ The list of ALI and object files used to build the DLL are listed in ‘file’, instead of being given in the command line. Each line in ‘file’ contains the name of an ALI or object file. ‘-n’ No Import. Do not create the import library. ‘-q’ Quiet mode. Do not display unnecessary messages. ‘-v’ Verbose mode. Display extra information. ‘-largs `opts'’ Linker options. Pass ‘opts’ to the linker. ‘gnatdll’ Example ................. As an example the command to build a relocatable DLL from ‘api.adb’ once ‘api.adb’ has been compiled and ‘api.def’ created is $ gnatdll -d api.dll api.ali The above command creates two files: ‘libapi.dll.a’ (the import library) and ‘api.dll’ (the actual DLL). If you want to create only the DLL, just type: $ gnatdll -d api.dll -n api.ali Alternatively if you want to create just the import library, type: $ gnatdll -d api.dll ‘gnatdll’ behind the Scenes ........................... This section details the steps involved in creating a DLL. ‘gnatdll’ does these steps for you. Unless you are interested in understanding what goes on behind the scenes, you should skip this section. We use the previous example of a DLL containing the Ada package ‘API’, to illustrate the steps necessary to build a DLL. The starting point is a set of objects that will make up the DLL and the corresponding ALI files. In the case of this example this means that ‘api.o’ and ‘api.ali’ are available. To build a relocatable DLL, ‘gnatdll’ does the following: * ‘gnatdll’ builds the base file (‘api.base’). A base file gives the information necessary to generate relocation information for the DLL. $ gnatbind -n api $ gnatlink api -o api.jnk -mdll -Wl,--base-file,api.base In addition to the base file, the ‘gnatlink’ command generates an output file ‘api.jnk’ which can be discarded. The ‘-mdll’ switch asks ‘gnatlink’ to generate the routines ‘DllMain’ and ‘DllMainCRTStartup’ that are called by the Windows loader when the DLL is loaded into memory. * ‘gnatdll’ uses ‘dlltool’ (see *note Using dlltool: 1fc.) to build the export table (‘api.exp’). The export table contains the relocation information in a form which can be used during the final link to ensure that the Windows loader is able to place the DLL anywhere in memory. $ dlltool --dllname api.dll --def api.def --base-file api.base \\ --output-exp api.exp * ‘gnatdll’ builds the base file using the new export table. Note that ‘gnatbind’ must be called once again since the binder generated file has been deleted during the previous call to ‘gnatlink’. $ gnatbind -n api $ gnatlink api -o api.jnk api.exp -mdll -Wl,--base-file,api.base * ‘gnatdll’ builds the new export table using the new base file and generates the DLL import library ‘libAPI.dll.a’. $ dlltool --dllname api.dll --def api.def --base-file api.base \\ --output-exp api.exp --output-lib libAPI.a * Finally ‘gnatdll’ builds the relocatable DLL using the final export table. $ gnatbind -n api $ gnatlink api api.exp -o api.dll -mdll Using ‘dlltool’ ............... ‘dlltool’ is the low-level tool used by ‘gnatdll’ to build DLLs and static import libraries. This section summarizes the most common ‘dlltool’ switches. The form of the ‘dlltool’ command is $ dlltool [`switches`] ‘dlltool’ switches include: ‘--base-file `basefile'’ Read the base file ‘basefile’ generated by the linker. This switch is used to create a relocatable DLL. ‘--def `deffile'’ Read the definition file. ‘--dllname `name'’ Gives the name of the DLL. This switch is used to embed the name of the DLL in the static import library generated by ‘dlltool’ with switch ‘--output-lib’. ‘-k’ Kill ‘@NN’ from exported names (*note Windows Calling Conventions: 1d6. for a discussion about ‘Stdcall’-style symbols). ‘--help’ Prints the ‘dlltool’ switches with a concise description. ‘--output-exp `exportfile'’ Generate an export file ‘exportfile’. The export file contains the export table (list of symbols in the DLL) and is used to create the DLL. ‘--output-lib `libfile'’ Generate a static import library ‘libfile’. ‘-v’ Verbose mode. ‘--as `assembler-name'’ Use ‘assembler-name’ as the assembler. The default is ‘as’.  File: gnat_ugn.info, Node: GNAT and Windows Resources, Next: Using GNAT DLLs from Microsoft Visual Studio Applications, Prev: Creating a Spec for Ada DLLs, Up: Mixed-Language Programming on Windows 7.4.7.20 GNAT and Windows Resources ................................... Resources are an easy way to add Windows specific objects to your application. The objects that can be added as resources include: * menus * accelerators * dialog boxes * string tables * bitmaps * cursors * icons * fonts * version information For example, a version information resource can be defined as follow and embedded into an executable or DLL: A version information resource can be used to embed information into an executable or a DLL. These information can be viewed using the file properties from the Windows Explorer. Here is an example of a version information resource: 1 VERSIONINFO FILEVERSION 1,0,0,0 PRODUCTVERSION 1,0,0,0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "080904E4" BEGIN VALUE "CompanyName", "My Company Name" VALUE "FileDescription", "My application" VALUE "FileVersion", "1.0" VALUE "InternalName", "my_app" VALUE "LegalCopyright", "My Name" VALUE "OriginalFilename", "my_app.exe" VALUE "ProductName", "My App" VALUE "ProductVersion", "1.0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x809, 1252 END END The value ‘0809’ (langID) is for the U.K English language and ‘04E4’ (charsetID), which is equal to ‘1252’ decimal, for multilingual. This section explains how to build, compile and use resources. Note that this section does not cover all resource objects, for a complete description see the corresponding Microsoft documentation. * Menu: * Building Resources:: * Compiling Resources:: * Using Resources::  File: gnat_ugn.info, Node: Building Resources, Next: Compiling Resources, Up: GNAT and Windows Resources 7.4.7.21 Building Resources ........................... A resource file is an ASCII file. By convention resource files have an ‘.rc’ extension. The easiest way to build a resource file is to use Microsoft tools such as ‘imagedit.exe’ to build bitmaps, icons and cursors and ‘dlgedit.exe’ to build dialogs. It is always possible to build an ‘.rc’ file yourself by writing a resource script. It is not our objective to explain how to write a resource file. A complete description of the resource script language can be found in the Microsoft documentation.  File: gnat_ugn.info, Node: Compiling Resources, Next: Using Resources, Prev: Building Resources, Up: GNAT and Windows Resources 7.4.7.22 Compiling Resources ............................ This section describes how to build a GNAT-compatible (COFF) object file containing the resources. This is done using the Resource Compiler ‘windres’ as follows: $ windres -i myres.rc -o myres.o By default ‘windres’ will run ‘gcc’ to preprocess the ‘.rc’ file. You can specify an alternate preprocessor (usually named ‘cpp.exe’) using the ‘windres’ ‘--preprocessor’ parameter. A list of all possible options may be obtained by entering the command ‘windres’ ‘--help’. It is also possible to use the Microsoft resource compiler ‘rc.exe’ to produce a ‘.res’ file (binary resource file). See the corresponding Microsoft documentation for further details. In this case you need to use ‘windres’ to translate the ‘.res’ file to a GNAT-compatible object file as follows: $ windres -i myres.res -o myres.o  File: gnat_ugn.info, Node: Using Resources, Prev: Compiling Resources, Up: GNAT and Windows Resources 7.4.7.23 Using Resources ........................ To include the resource file in your program just add the GNAT-compatible object file for the resource(s) to the linker arguments. With ‘gnatmake’ this is done by using the ‘-largs’ option: $ gnatmake myprog -largs myres.o  File: gnat_ugn.info, Node: Using GNAT DLLs from Microsoft Visual Studio Applications, Next: Debugging a DLL, Prev: GNAT and Windows Resources, Up: Mixed-Language Programming on Windows 7.4.7.24 Using GNAT DLLs from Microsoft Visual Studio Applications .................................................................. This section describes a common case of mixed GNAT/Microsoft Visual Studio application development, where the main program is developed using MSVS, and is linked with a DLL developed using GNAT. Such a mixed application should be developed following the general guidelines outlined above; below is the cookbook-style sequence of steps to follow: 1. First develop and build the GNAT shared library using a library project (let’s assume the project is ‘mylib.gpr’, producing the library ‘libmylib.dll’): $ gprbuild -p mylib.gpr 2. Produce a .def file for the symbols you need to interface with, either by hand or automatically with possibly some manual adjustments (see *note Creating Definition File Automatically: 1e7.): $ dlltool libmylib.dll -z libmylib.def --export-all-symbols 3. Make sure that MSVS command-line tools are accessible on the path. 4. Create the Microsoft-style import library (see *note MSVS-Style Import Library: 1ea.): $ lib -machine:IX86 -def:libmylib.def -out:libmylib.lib If you are using a 64-bit toolchain, the above becomes… $ lib -machine:X64 -def:libmylib.def -out:libmylib.lib 5. Build the C main $ cl /O2 /MD main.c libmylib.lib 6. Before running the executable, make sure you have set the PATH to the DLL, or copy the DLL into into the directory containing the .exe.  File: gnat_ugn.info, Node: Debugging a DLL, Next: Setting Stack Size from gnatlink, Prev: Using GNAT DLLs from Microsoft Visual Studio Applications, Up: Mixed-Language Programming on Windows 7.4.7.25 Debugging a DLL ........................ Debugging a DLL is similar to debugging a standard program. But we have to deal with two different executable parts: the DLL and the program that uses it. We have the following four possibilities: * The program and the DLL are built with GCC/GNAT. * The program is built with foreign tools and the DLL is built with GCC/GNAT. * The program is built with GCC/GNAT and the DLL is built with foreign tools. In this section we address only cases one and two above. There is no point in trying to debug a DLL with GNU/GDB, if there is no GDB-compatible debugging information in it. To do so you must use a debugger compatible with the tools suite used to build the DLL. * Menu: * Program and DLL Both Built with GCC/GNAT:: * Program Built with Foreign Tools and DLL Built with GCC/GNAT::  File: gnat_ugn.info, Node: Program and DLL Both Built with GCC/GNAT, Next: Program Built with Foreign Tools and DLL Built with GCC/GNAT, Up: Debugging a DLL 7.4.7.26 Program and DLL Both Built with GCC/GNAT ................................................. This is the simplest case. Both the DLL and the program have ‘GDB’ compatible debugging information. It is then possible to break anywhere in the process. Let’s suppose here that the main procedure is named ‘ada_main’ and that in the DLL there is an entry point named ‘ada_dll’. The DLL (*note Introduction to Dynamic Link Libraries (DLLs): 1e0.) and program must have been built with the debugging information (see GNAT -g switch). Here are the step-by-step instructions for debugging it: * Launch ‘GDB’ on the main program. $ gdb -nw ada_main * Start the program and stop at the beginning of the main procedure (gdb) start This step is required to be able to set a breakpoint inside the DLL. As long as the program is not run, the DLL is not loaded. This has the consequence that the DLL debugging information is also not loaded, so it is not possible to set a breakpoint in the DLL. * Set a breakpoint inside the DLL (gdb) break ada_dll (gdb) cont At this stage a breakpoint is set inside the DLL. From there on you can use the standard approach to debug the whole program (*note Running and Debugging Ada Programs: 14f.).  File: gnat_ugn.info, Node: Program Built with Foreign Tools and DLL Built with GCC/GNAT, Prev: Program and DLL Both Built with GCC/GNAT, Up: Debugging a DLL 7.4.7.27 Program Built with Foreign Tools and DLL Built with GCC/GNAT ..................................................................... In this case things are slightly more complex because it is not possible to start the main program and then break at the beginning to load the DLL and the associated DLL debugging information. It is not possible to break at the beginning of the program because there is no ‘GDB’ debugging information, and therefore there is no direct way of getting initial control. This section addresses this issue by describing some methods that can be used to break somewhere in the DLL to debug it. First suppose that the main procedure is named ‘main’ (this is for example some C code built with Microsoft Visual C) and that there is a DLL named ‘test.dll’ containing an Ada entry point named ‘ada_dll’. The DLL (see *note Introduction to Dynamic Link Libraries (DLLs): 1e0.) must have been built with debugging information (see the GNAT ‘-g’ option). Debugging the DLL Directly .......................... * Find out the executable starting address $ objdump --file-header main.exe The starting address is reported on the last line. For example: main.exe: file format pei-i386 architecture: i386, flags 0x0000010a: EXEC_P, HAS_DEBUG, D_PAGED start address 0x00401010 * Launch the debugger on the executable. $ gdb main.exe * Set a breakpoint at the starting address, and launch the program. $ (gdb) break *0x00401010 $ (gdb) run The program will stop at the given address. * Set a breakpoint on a DLL subroutine. (gdb) break ada_dll.adb:45 Or if you want to break using a symbol on the DLL, you need first to select the Ada language (language used by the DLL). (gdb) set language ada (gdb) break ada_dll * Continue the program. (gdb) cont This will run the program until it reaches the breakpoint that has been set. From that point you can use the standard way to debug a program as described in (*note Running and Debugging Ada Programs: 14f.). It is also possible to debug the DLL by attaching to a running process. Attaching to a Running Process .............................. With ‘GDB’ it is always possible to debug a running process by attaching to it. It is possible to debug a DLL this way. The limitation of this approach is that the DLL must run long enough to perform the attach operation. It may be useful for instance to insert a time wasting loop in the code of the DLL to meet this criterion. * Launch the main program ‘main.exe’. $ main * Use the Windows 'Task Manager' to find the process ID. Let’s say that the process PID for ‘main.exe’ is 208. * Launch gdb. $ gdb * Attach to the running process to be debugged. (gdb) attach 208 * Load the process debugging information. (gdb) symbol-file main.exe * Break somewhere in the DLL. (gdb) break ada_dll * Continue process execution. (gdb) cont This last step will resume the process execution, and stop at the breakpoint we have set. From there you can use the standard approach to debug a program as described in *note Running and Debugging Ada Programs: 14f.  File: gnat_ugn.info, Node: Setting Stack Size from gnatlink, Next: Setting Heap Size from gnatlink, Prev: Debugging a DLL, Up: Mixed-Language Programming on Windows 7.4.7.28 Setting Stack Size from ‘gnatlink’ ........................................... It is possible to specify the program stack size at link time. On modern versions of Windows, starting with XP, this is mostly useful to set the size of the main stack (environment task). The other task stacks are set with pragma Storage_Size or with the 'gnatbind -d' command. Since older versions of Windows (2000, NT4, etc.) do not allow setting the reserve size of individual tasks, the link-time stack size applies to all tasks, and pragma Storage_Size has no effect. In particular, Stack Overflow checks are made against this link-time specified size. This setting can be done with ‘gnatlink’ using either of the following: * ‘-Xlinker’ linker option $ gnatlink hello -Xlinker --stack=0x10000,0x1000 This sets the stack reserve size to 0x10000 bytes and the stack commit size to 0x1000 bytes. * ‘-Wl’ linker option $ gnatlink hello -Wl,--stack=0x1000000 This sets the stack reserve size to 0x1000000 bytes. Note that with ‘-Wl’ option it is not possible to set the stack commit size because the comma is a separator for this option.  File: gnat_ugn.info, Node: Setting Heap Size from gnatlink, Prev: Setting Stack Size from gnatlink, Up: Mixed-Language Programming on Windows 7.4.7.29 Setting Heap Size from ‘gnatlink’ .......................................... Under Windows systems, it is possible to specify the program heap size from ‘gnatlink’ using either of the following: * ‘-Xlinker’ linker option $ gnatlink hello -Xlinker --heap=0x10000,0x1000 This sets the heap reserve size to 0x10000 bytes and the heap commit size to 0x1000 bytes. * ‘-Wl’ linker option $ gnatlink hello -Wl,--heap=0x1000000 This sets the heap reserve size to 0x1000000 bytes. Note that with ‘-Wl’ option it is not possible to set the heap commit size because the comma is a separator for this option.  File: gnat_ugn.info, Node: Windows Specific Add-Ons, Prev: Mixed-Language Programming on Windows, Up: Microsoft Windows Topics 7.4.8 Windows Specific Add-Ons ------------------------------ This section describes the Windows specific add-ons. * Menu: * Win32Ada:: * wPOSIX::  File: gnat_ugn.info, Node: Win32Ada, Next: wPOSIX, Up: Windows Specific Add-Ons 7.4.8.1 Win32Ada ................ Win32Ada is a binding for the Microsoft Win32 API. This binding can be easily installed from the provided installer. To use the Win32Ada binding you need to use a project file, and adding a single with_clause will give you full access to the Win32Ada binding sources and ensure that the proper libraries are passed to the linker. with "win32ada"; project P is for Sources use ...; end P; To build the application you just need to call gprbuild for the application’s project, here p.gpr: gprbuild p.gpr  File: gnat_ugn.info, Node: wPOSIX, Prev: Win32Ada, Up: Windows Specific Add-Ons 7.4.8.2 wPOSIX .............. wPOSIX is a minimal POSIX binding whose goal is to help with building cross-platforms applications. This binding is not complete though, as the Win32 API does not provide the necessary support for all POSIX APIs. To use the wPOSIX binding you need to use a project file, and adding a single with_clause will give you full access to the wPOSIX binding sources and ensure that the proper libraries are passed to the linker. with "wposix"; project P is for Sources use ...; end P; To build the application you just need to call gprbuild for the application’s project, here p.gpr: gprbuild p.gpr  File: gnat_ugn.info, Node: Mac OS Topics, Prev: Microsoft Windows Topics, Up: Platform-Specific Information 7.5 Mac OS Topics ================= This section describes topics that are specific to Apple’s OS X platform. * Menu: * Codesigning the Debugger::  File: gnat_ugn.info, Node: Codesigning the Debugger, Up: Mac OS Topics 7.5.1 Codesigning the Debugger ------------------------------ The Darwin Kernel requires the debugger to have special permissions before it is allowed to control other processes. These permissions are granted by codesigning the GDB executable. Without these permissions, the debugger will report error messages such as: Starting program: /x/y/foo Unable to find Mach task port for process-id 28885: (os/kern) failure (0x5). (please check gdb is codesigned - see taskgated(8)) Codesigning requires a certificate. The following procedure explains how to create one: * Start the Keychain Access application (in /Applications/Utilities/Keychain Access.app) * Select the Keychain Access -> Certificate Assistant -> Create a Certificate… menu * Then: * Choose a name for the new certificate (this procedure will use “gdb-cert” as an example) * Set “Identity Type” to “Self Signed Root” * Set “Certificate Type” to “Code Signing” * Activate the “Let me override defaults” option * Click several times on “Continue” until the “Specify a Location For The Certificate” screen appears, then set “Keychain” to “System” * Click on “Continue” until the certificate is created * Finally, in the view, double-click on the new certificate, and set “When using this certificate” to “Always Trust” * Exit the Keychain Access application and restart the computer (this is unfortunately required) Once a certificate has been created, the debugger can be codesigned as follow. In a Terminal, run the following command: $ codesign -f -s "gdb-cert" /bin/gdb where “gdb-cert” should be replaced by the actual certificate name chosen above, and should be replaced by the location where you installed GNAT. Also, be sure that users are in the Unix group ‘_developer’.  File: gnat_ugn.info, Node: Example of Binder Output File, Next: Elaboration Order Handling in GNAT, Prev: Platform-Specific Information, Up: Top 8 Example of Binder Output File ******************************* This Appendix displays the source code for the output file generated by 'gnatbind' for a simple ‘Hello World’ program. Comments have been added for clarification purposes. -- The package is called Ada_Main unless this name is actually used -- as a unit name in the partition, in which case some other unique -- name is used. pragma Ada_95; with System; package ada_main is pragma Warnings (Off); -- The main program saves the parameters (argument count, -- argument values, environment pointer) in global variables -- for later access by other units including -- Ada.Command_Line. gnat_argc : Integer; gnat_argv : System.Address; gnat_envp : System.Address; -- The actual variables are stored in a library routine. This -- is useful for some shared library situations, where there -- are problems if variables are not in the library. pragma Import (C, gnat_argc); pragma Import (C, gnat_argv); pragma Import (C, gnat_envp); -- The exit status is similarly an external location gnat_exit_status : Integer; pragma Import (C, gnat_exit_status); GNAT_Version : constant String := "GNAT Version: Pro 7.4.0w (20141119-49)" & ASCII.NUL; pragma Export (C, GNAT_Version, "__gnat_version"); Ada_Main_Program_Name : constant String := "_ada_hello" & ASCII.NUL; pragma Export (C, Ada_Main_Program_Name, "__gnat_ada_main_program_name"); -- This is the generated adainit routine that performs -- initialization at the start of execution. In the case -- where Ada is the main program, this main program makes -- a call to adainit at program startup. procedure adainit; pragma Export (C, adainit, "adainit"); -- This is the generated adafinal routine that performs -- finalization at the end of execution. In the case where -- Ada is the main program, this main program makes a call -- to adafinal at program termination. procedure adafinal; pragma Export (C, adafinal, "adafinal"); -- This routine is called at the start of execution. It is -- a dummy routine that is used by the debugger to breakpoint -- at the start of execution. -- This is the actual generated main program (it would be -- suppressed if the no main program switch were used). As -- required by standard system conventions, this program has -- the external name main. function main (argc : Integer; argv : System.Address; envp : System.Address) return Integer; pragma Export (C, main, "main"); -- The following set of constants give the version -- identification values for every unit in the bound -- partition. This identification is computed from all -- dependent semantic units, and corresponds to the -- string that would be returned by use of the -- Body_Version or Version attributes. -- The following Export pragmas export the version numbers -- with symbolic names ending in B (for body) or S -- (for spec) so that they can be located in a link. The -- information provided here is sufficient to track down -- the exact versions of units used in a given build. type Version_32 is mod 2 ** 32; u00001 : constant Version_32 := 16#8ad6e54a#; pragma Export (C, u00001, "helloB"); u00002 : constant Version_32 := 16#fbff4c67#; pragma Export (C, u00002, "system__standard_libraryB"); u00003 : constant Version_32 := 16#1ec6fd90#; pragma Export (C, u00003, "system__standard_libraryS"); u00004 : constant Version_32 := 16#3ffc8e18#; pragma Export (C, u00004, "adaS"); u00005 : constant Version_32 := 16#28f088c2#; pragma Export (C, u00005, "ada__text_ioB"); u00006 : constant Version_32 := 16#f372c8ac#; pragma Export (C, u00006, "ada__text_ioS"); u00007 : constant Version_32 := 16#2c143749#; pragma Export (C, u00007, "ada__exceptionsB"); u00008 : constant Version_32 := 16#f4f0cce8#; pragma Export (C, u00008, "ada__exceptionsS"); u00009 : constant Version_32 := 16#a46739c0#; pragma Export (C, u00009, "ada__exceptions__last_chance_handlerB"); u00010 : constant Version_32 := 16#3aac8c92#; pragma Export (C, u00010, "ada__exceptions__last_chance_handlerS"); u00011 : constant Version_32 := 16#1d274481#; pragma Export (C, u00011, "systemS"); u00012 : constant Version_32 := 16#a207fefe#; pragma Export (C, u00012, "system__soft_linksB"); u00013 : constant Version_32 := 16#467d9556#; pragma Export (C, u00013, "system__soft_linksS"); u00014 : constant Version_32 := 16#b01dad17#; pragma Export (C, u00014, "system__parametersB"); u00015 : constant Version_32 := 16#630d49fe#; pragma Export (C, u00015, "system__parametersS"); u00016 : constant Version_32 := 16#b19b6653#; pragma Export (C, u00016, "system__secondary_stackB"); u00017 : constant Version_32 := 16#b6468be8#; pragma Export (C, u00017, "system__secondary_stackS"); u00018 : constant Version_32 := 16#39a03df9#; pragma Export (C, u00018, "system__storage_elementsB"); u00019 : constant Version_32 := 16#30e40e85#; pragma Export (C, u00019, "system__storage_elementsS"); u00020 : constant Version_32 := 16#41837d1e#; pragma Export (C, u00020, "system__stack_checkingB"); u00021 : constant Version_32 := 16#93982f69#; pragma Export (C, u00021, "system__stack_checkingS"); u00022 : constant Version_32 := 16#393398c1#; pragma Export (C, u00022, "system__exception_tableB"); u00023 : constant Version_32 := 16#b33e2294#; pragma Export (C, u00023, "system__exception_tableS"); u00024 : constant Version_32 := 16#ce4af020#; pragma Export (C, u00024, "system__exceptionsB"); u00025 : constant Version_32 := 16#75442977#; pragma Export (C, u00025, "system__exceptionsS"); u00026 : constant Version_32 := 16#37d758f1#; pragma Export (C, u00026, "system__exceptions__machineS"); u00027 : constant Version_32 := 16#b895431d#; pragma Export (C, u00027, "system__exceptions_debugB"); u00028 : constant Version_32 := 16#aec55d3f#; pragma Export (C, u00028, "system__exceptions_debugS"); u00029 : constant Version_32 := 16#570325c8#; pragma Export (C, u00029, "system__img_intB"); u00030 : constant Version_32 := 16#1ffca443#; pragma Export (C, u00030, "system__img_intS"); u00031 : constant Version_32 := 16#b98c3e16#; pragma Export (C, u00031, "system__tracebackB"); u00032 : constant Version_32 := 16#831a9d5a#; pragma Export (C, u00032, "system__tracebackS"); u00033 : constant Version_32 := 16#9ed49525#; pragma Export (C, u00033, "system__traceback_entriesB"); u00034 : constant Version_32 := 16#1d7cb2f1#; pragma Export (C, u00034, "system__traceback_entriesS"); u00035 : constant Version_32 := 16#8c33a517#; pragma Export (C, u00035, "system__wch_conB"); u00036 : constant Version_32 := 16#065a6653#; pragma Export (C, u00036, "system__wch_conS"); u00037 : constant Version_32 := 16#9721e840#; pragma Export (C, u00037, "system__wch_stwB"); u00038 : constant Version_32 := 16#2b4b4a52#; pragma Export (C, u00038, "system__wch_stwS"); u00039 : constant Version_32 := 16#92b797cb#; pragma Export (C, u00039, "system__wch_cnvB"); u00040 : constant Version_32 := 16#09eddca0#; pragma Export (C, u00040, "system__wch_cnvS"); u00041 : constant Version_32 := 16#6033a23f#; pragma Export (C, u00041, "interfacesS"); u00042 : constant Version_32 := 16#ece6fdb6#; pragma Export (C, u00042, "system__wch_jisB"); u00043 : constant Version_32 := 16#899dc581#; pragma Export (C, u00043, "system__wch_jisS"); u00044 : constant Version_32 := 16#10558b11#; pragma Export (C, u00044, "ada__streamsB"); u00045 : constant Version_32 := 16#2e6701ab#; pragma Export (C, u00045, "ada__streamsS"); u00046 : constant Version_32 := 16#db5c917c#; pragma Export (C, u00046, "ada__io_exceptionsS"); u00047 : constant Version_32 := 16#12c8cd7d#; pragma Export (C, u00047, "ada__tagsB"); u00048 : constant Version_32 := 16#ce72c228#; pragma Export (C, u00048, "ada__tagsS"); u00049 : constant Version_32 := 16#c3335bfd#; pragma Export (C, u00049, "system__htableB"); u00050 : constant Version_32 := 16#99e5f76b#; pragma Export (C, u00050, "system__htableS"); u00051 : constant Version_32 := 16#089f5cd0#; pragma Export (C, u00051, "system__string_hashB"); u00052 : constant Version_32 := 16#3bbb9c15#; pragma Export (C, u00052, "system__string_hashS"); u00053 : constant Version_32 := 16#807fe041#; pragma Export (C, u00053, "system__unsigned_typesS"); u00054 : constant Version_32 := 16#d27be59e#; pragma Export (C, u00054, "system__val_lluB"); u00055 : constant Version_32 := 16#fa8db733#; pragma Export (C, u00055, "system__val_lluS"); u00056 : constant Version_32 := 16#27b600b2#; pragma Export (C, u00056, "system__val_utilB"); u00057 : constant Version_32 := 16#b187f27f#; pragma Export (C, u00057, "system__val_utilS"); u00058 : constant Version_32 := 16#d1060688#; pragma Export (C, u00058, "system__case_utilB"); u00059 : constant Version_32 := 16#392e2d56#; pragma Export (C, u00059, "system__case_utilS"); u00060 : constant Version_32 := 16#84a27f0d#; pragma Export (C, u00060, "interfaces__c_streamsB"); u00061 : constant Version_32 := 16#8bb5f2c0#; pragma Export (C, u00061, "interfaces__c_streamsS"); u00062 : constant Version_32 := 16#6db6928f#; pragma Export (C, u00062, "system__crtlS"); u00063 : constant Version_32 := 16#4e6a342b#; pragma Export (C, u00063, "system__file_ioB"); u00064 : constant Version_32 := 16#ba56a5e4#; pragma Export (C, u00064, "system__file_ioS"); u00065 : constant Version_32 := 16#b7ab275c#; pragma Export (C, u00065, "ada__finalizationB"); u00066 : constant Version_32 := 16#19f764ca#; pragma Export (C, u00066, "ada__finalizationS"); u00067 : constant Version_32 := 16#95817ed8#; pragma Export (C, u00067, "system__finalization_rootB"); u00068 : constant Version_32 := 16#52d53711#; pragma Export (C, u00068, "system__finalization_rootS"); u00069 : constant Version_32 := 16#769e25e6#; pragma Export (C, u00069, "interfaces__cB"); u00070 : constant Version_32 := 16#4a38bedb#; pragma Export (C, u00070, "interfaces__cS"); u00071 : constant Version_32 := 16#07e6ee66#; pragma Export (C, u00071, "system__os_libB"); u00072 : constant Version_32 := 16#d7b69782#; pragma Export (C, u00072, "system__os_libS"); u00073 : constant Version_32 := 16#1a817b8e#; pragma Export (C, u00073, "system__stringsB"); u00074 : constant Version_32 := 16#639855e7#; pragma Export (C, u00074, "system__stringsS"); u00075 : constant Version_32 := 16#e0b8de29#; pragma Export (C, u00075, "system__file_control_blockS"); u00076 : constant Version_32 := 16#b5b2aca1#; pragma Export (C, u00076, "system__finalization_mastersB"); u00077 : constant Version_32 := 16#69316dc1#; pragma Export (C, u00077, "system__finalization_mastersS"); u00078 : constant Version_32 := 16#57a37a42#; pragma Export (C, u00078, "system__address_imageB"); u00079 : constant Version_32 := 16#bccbd9bb#; pragma Export (C, u00079, "system__address_imageS"); u00080 : constant Version_32 := 16#7268f812#; pragma Export (C, u00080, "system__img_boolB"); u00081 : constant Version_32 := 16#e8fe356a#; pragma Export (C, u00081, "system__img_boolS"); u00082 : constant Version_32 := 16#d7aac20c#; pragma Export (C, u00082, "system__ioB"); u00083 : constant Version_32 := 16#8365b3ce#; pragma Export (C, u00083, "system__ioS"); u00084 : constant Version_32 := 16#6d4d969a#; pragma Export (C, u00084, "system__storage_poolsB"); u00085 : constant Version_32 := 16#e87cc305#; pragma Export (C, u00085, "system__storage_poolsS"); u00086 : constant Version_32 := 16#e34550ca#; pragma Export (C, u00086, "system__pool_globalB"); u00087 : constant Version_32 := 16#c88d2d16#; pragma Export (C, u00087, "system__pool_globalS"); u00088 : constant Version_32 := 16#9d39c675#; pragma Export (C, u00088, "system__memoryB"); u00089 : constant Version_32 := 16#445a22b5#; pragma Export (C, u00089, "system__memoryS"); u00090 : constant Version_32 := 16#6a859064#; pragma Export (C, u00090, "system__storage_pools__subpoolsB"); u00091 : constant Version_32 := 16#e3b008dc#; pragma Export (C, u00091, "system__storage_pools__subpoolsS"); u00092 : constant Version_32 := 16#63f11652#; pragma Export (C, u00092, "system__storage_pools__subpools__finalizationB"); u00093 : constant Version_32 := 16#fe2f4b3a#; pragma Export (C, u00093, "system__storage_pools__subpools__finalizationS"); -- BEGIN ELABORATION ORDER -- ada%s -- interfaces%s -- system%s -- system.case_util%s -- system.case_util%b -- system.htable%s -- system.img_bool%s -- system.img_bool%b -- system.img_int%s -- system.img_int%b -- system.io%s -- system.io%b -- system.parameters%s -- system.parameters%b -- system.crtl%s -- interfaces.c_streams%s -- interfaces.c_streams%b -- system.standard_library%s -- system.exceptions_debug%s -- system.exceptions_debug%b -- system.storage_elements%s -- system.storage_elements%b -- system.stack_checking%s -- system.stack_checking%b -- system.string_hash%s -- system.string_hash%b -- system.htable%b -- system.strings%s -- system.strings%b -- system.os_lib%s -- system.traceback_entries%s -- system.traceback_entries%b -- ada.exceptions%s -- system.soft_links%s -- system.unsigned_types%s -- system.val_llu%s -- system.val_util%s -- system.val_util%b -- system.val_llu%b -- system.wch_con%s -- system.wch_con%b -- system.wch_cnv%s -- system.wch_jis%s -- system.wch_jis%b -- system.wch_cnv%b -- system.wch_stw%s -- system.wch_stw%b -- ada.exceptions.last_chance_handler%s -- ada.exceptions.last_chance_handler%b -- system.address_image%s -- system.exception_table%s -- system.exception_table%b -- ada.io_exceptions%s -- ada.tags%s -- ada.streams%s -- ada.streams%b -- interfaces.c%s -- system.exceptions%s -- system.exceptions%b -- system.exceptions.machine%s -- system.finalization_root%s -- system.finalization_root%b -- ada.finalization%s -- ada.finalization%b -- system.storage_pools%s -- system.storage_pools%b -- system.finalization_masters%s -- system.storage_pools.subpools%s -- system.storage_pools.subpools.finalization%s -- system.storage_pools.subpools.finalization%b -- system.memory%s -- system.memory%b -- system.standard_library%b -- system.pool_global%s -- system.pool_global%b -- system.file_control_block%s -- system.file_io%s -- system.secondary_stack%s -- system.file_io%b -- system.storage_pools.subpools%b -- system.finalization_masters%b -- interfaces.c%b -- ada.tags%b -- system.soft_links%b -- system.os_lib%b -- system.secondary_stack%b -- system.address_image%b -- system.traceback%s -- ada.exceptions%b -- system.traceback%b -- ada.text_io%s -- ada.text_io%b -- hello%b -- END ELABORATION ORDER end ada_main; pragma Ada_95; -- The following source file name pragmas allow the generated file -- names to be unique for different main programs. They are needed -- since the package name will always be Ada_Main. pragma Source_File_Name (ada_main, Spec_File_Name => "b~hello.ads"); pragma Source_File_Name (ada_main, Body_File_Name => "b~hello.adb"); pragma Suppress (Overflow_Check); with Ada.Exceptions; -- Generated package body for Ada_Main starts here package body ada_main is pragma Warnings (Off); -- These values are reference counter associated to units which have -- been elaborated. It is also used to avoid elaborating the -- same unit twice. E72 : Short_Integer; pragma Import (Ada, E72, "system__os_lib_E"); E13 : Short_Integer; pragma Import (Ada, E13, "system__soft_links_E"); E23 : Short_Integer; pragma Import (Ada, E23, "system__exception_table_E"); E46 : Short_Integer; pragma Import (Ada, E46, "ada__io_exceptions_E"); E48 : Short_Integer; pragma Import (Ada, E48, "ada__tags_E"); E45 : Short_Integer; pragma Import (Ada, E45, "ada__streams_E"); E70 : Short_Integer; pragma Import (Ada, E70, "interfaces__c_E"); E25 : Short_Integer; pragma Import (Ada, E25, "system__exceptions_E"); E68 : Short_Integer; pragma Import (Ada, E68, "system__finalization_root_E"); E66 : Short_Integer; pragma Import (Ada, E66, "ada__finalization_E"); E85 : Short_Integer; pragma Import (Ada, E85, "system__storage_pools_E"); E77 : Short_Integer; pragma Import (Ada, E77, "system__finalization_masters_E"); E91 : Short_Integer; pragma Import (Ada, E91, "system__storage_pools__subpools_E"); E87 : Short_Integer; pragma Import (Ada, E87, "system__pool_global_E"); E75 : Short_Integer; pragma Import (Ada, E75, "system__file_control_block_E"); E64 : Short_Integer; pragma Import (Ada, E64, "system__file_io_E"); E17 : Short_Integer; pragma Import (Ada, E17, "system__secondary_stack_E"); E06 : Short_Integer; pragma Import (Ada, E06, "ada__text_io_E"); Local_Priority_Specific_Dispatching : constant String := ""; Local_Interrupt_States : constant String := ""; Is_Elaborated : Boolean := False; procedure finalize_library is begin E06 := E06 - 1; declare procedure F1; pragma Import (Ada, F1, "ada__text_io__finalize_spec"); begin F1; end; E77 := E77 - 1; E91 := E91 - 1; declare procedure F2; pragma Import (Ada, F2, "system__file_io__finalize_body"); begin E64 := E64 - 1; F2; end; declare procedure F3; pragma Import (Ada, F3, "system__file_control_block__finalize_spec"); begin E75 := E75 - 1; F3; end; E87 := E87 - 1; declare procedure F4; pragma Import (Ada, F4, "system__pool_global__finalize_spec"); begin F4; end; declare procedure F5; pragma Import (Ada, F5, "system__storage_pools__subpools__finalize_spec"); begin F5; end; declare procedure F6; pragma Import (Ada, F6, "system__finalization_masters__finalize_spec"); begin F6; end; declare procedure Reraise_Library_Exception_If_Any; pragma Import (Ada, Reraise_Library_Exception_If_Any, "__gnat_reraise_library_exception_if_any"); begin Reraise_Library_Exception_If_Any; end; end finalize_library; ------------- -- adainit -- ------------- procedure adainit is Main_Priority : Integer; pragma Import (C, Main_Priority, "__gl_main_priority"); Time_Slice_Value : Integer; pragma Import (C, Time_Slice_Value, "__gl_time_slice_val"); WC_Encoding : Character; pragma Import (C, WC_Encoding, "__gl_wc_encoding"); Locking_Policy : Character; pragma Import (C, Locking_Policy, "__gl_locking_policy"); Queuing_Policy : Character; pragma Import (C, Queuing_Policy, "__gl_queuing_policy"); Task_Dispatching_Policy : Character; pragma Import (C, Task_Dispatching_Policy, "__gl_task_dispatching_policy"); Priority_Specific_Dispatching : System.Address; pragma Import (C, Priority_Specific_Dispatching, "__gl_priority_specific_dispatching"); Num_Specific_Dispatching : Integer; pragma Import (C, Num_Specific_Dispatching, "__gl_num_specific_dispatching"); Main_CPU : Integer; pragma Import (C, Main_CPU, "__gl_main_cpu"); Interrupt_States : System.Address; pragma Import (C, Interrupt_States, "__gl_interrupt_states"); Num_Interrupt_States : Integer; pragma Import (C, Num_Interrupt_States, "__gl_num_interrupt_states"); Unreserve_All_Interrupts : Integer; pragma Import (C, Unreserve_All_Interrupts, "__gl_unreserve_all_interrupts"); Detect_Blocking : Integer; pragma Import (C, Detect_Blocking, "__gl_detect_blocking"); Default_Stack_Size : Integer; pragma Import (C, Default_Stack_Size, "__gl_default_stack_size"); Leap_Seconds_Support : Integer; pragma Import (C, Leap_Seconds_Support, "__gl_leap_seconds_support"); procedure Runtime_Initialize; pragma Import (C, Runtime_Initialize, "__gnat_runtime_initialize"); Finalize_Library_Objects : No_Param_Proc; pragma Import (C, Finalize_Library_Objects, "__gnat_finalize_library_objects"); -- Start of processing for adainit begin -- Record various information for this partition. The values -- are derived by the binder from information stored in the ali -- files by the compiler. if Is_Elaborated then return; end if; Is_Elaborated := True; Main_Priority := -1; Time_Slice_Value := -1; WC_Encoding := 'b'; Locking_Policy := ' '; Queuing_Policy := ' '; Task_Dispatching_Policy := ' '; Priority_Specific_Dispatching := Local_Priority_Specific_Dispatching'Address; Num_Specific_Dispatching := 0; Main_CPU := -1; Interrupt_States := Local_Interrupt_States'Address; Num_Interrupt_States := 0; Unreserve_All_Interrupts := 0; Detect_Blocking := 0; Default_Stack_Size := -1; Leap_Seconds_Support := 0; Runtime_Initialize; Finalize_Library_Objects := finalize_library'access; -- Now we have the elaboration calls for all units in the partition. -- The Elab_Spec and Elab_Body attributes generate references to the -- implicit elaboration procedures generated by the compiler for -- each unit that requires elaboration. Increment a counter of -- reference for each unit. System.Soft_Links'Elab_Spec; System.Exception_Table'Elab_Body; E23 := E23 + 1; Ada.Io_Exceptions'Elab_Spec; E46 := E46 + 1; Ada.Tags'Elab_Spec; Ada.Streams'Elab_Spec; E45 := E45 + 1; Interfaces.C'Elab_Spec; System.Exceptions'Elab_Spec; E25 := E25 + 1; System.Finalization_Root'Elab_Spec; E68 := E68 + 1; Ada.Finalization'Elab_Spec; E66 := E66 + 1; System.Storage_Pools'Elab_Spec; E85 := E85 + 1; System.Finalization_Masters'Elab_Spec; System.Storage_Pools.Subpools'Elab_Spec; System.Pool_Global'Elab_Spec; E87 := E87 + 1; System.File_Control_Block'Elab_Spec; E75 := E75 + 1; System.File_Io'Elab_Body; E64 := E64 + 1; E91 := E91 + 1; System.Finalization_Masters'Elab_Body; E77 := E77 + 1; E70 := E70 + 1; Ada.Tags'Elab_Body; E48 := E48 + 1; System.Soft_Links'Elab_Body; E13 := E13 + 1; System.Os_Lib'Elab_Body; E72 := E72 + 1; System.Secondary_Stack'Elab_Body; E17 := E17 + 1; Ada.Text_Io'Elab_Spec; Ada.Text_Io'Elab_Body; E06 := E06 + 1; end adainit; -------------- -- adafinal -- -------------- procedure adafinal is procedure s_stalib_adafinal; pragma Import (C, s_stalib_adafinal, "system__standard_library__adafinal"); procedure Runtime_Finalize; pragma Import (C, Runtime_Finalize, "__gnat_runtime_finalize"); begin if not Is_Elaborated then return; end if; Is_Elaborated := False; Runtime_Finalize; s_stalib_adafinal; end adafinal; -- We get to the main program of the partition by using -- pragma Import because if we try to with the unit and -- call it Ada style, then not only do we waste time -- recompiling it, but also, we don't really know the right -- switches (e.g.@: identifier character set) to be used -- to compile it. procedure Ada_Main_Program; pragma Import (Ada, Ada_Main_Program, "_ada_hello"); ---------- -- main -- ---------- -- main is actually a function, as in the ANSI C standard, -- defined to return the exit status. The three parameters -- are the argument count, argument values and environment -- pointer. function main (argc : Integer; argv : System.Address; envp : System.Address) return Integer is -- The initialize routine performs low level system -- initialization using a standard library routine which -- sets up signal handling and performs any other -- required setup. The routine can be found in file -- a-init.c. procedure initialize; pragma Import (C, initialize, "__gnat_initialize"); -- The finalize routine performs low level system -- finalization using a standard library routine. The -- routine is found in file a-final.c and in the standard -- distribution is a dummy routine that does nothing, so -- really this is a hook for special user finalization. procedure finalize; pragma Import (C, finalize, "__gnat_finalize"); -- The following is to initialize the SEH exceptions SEH : aliased array (1 .. 2) of Integer; Ensure_Reference : aliased System.Address := Ada_Main_Program_Name'Address; pragma Volatile (Ensure_Reference); -- Start of processing for main begin -- Save global variables gnat_argc := argc; gnat_argv := argv; gnat_envp := envp; -- Call low level system initialization Initialize (SEH'Address); -- Call our generated Ada initialization routine adainit; -- Now we call the main program of the partition Ada_Main_Program; -- Perform Ada finalization adafinal; -- Perform low level system finalization Finalize; -- Return the proper exit status return (gnat_exit_status); end; -- This section is entirely comments, so it has no effect on the -- compilation of the Ada_Main package. It provides the list of -- object files and linker options, as well as some standard -- libraries needed for the link. The gnatlink utility parses -- this b~hello.adb file to read these comment lines to generate -- the appropriate command line arguments for the call to the -- system linker. The BEGIN/END lines are used for sentinels for -- this parsing operation. -- The exact file names will of course depend on the environment, -- host/target and location of files on the host system. -- BEGIN Object file/option list -- ./hello.o -- -L./ -- -L/usr/local/gnat/lib/gcc-lib/i686-pc-linux-gnu/2.8.1/adalib/ -- /usr/local/gnat/lib/gcc-lib/i686-pc-linux-gnu/2.8.1/adalib/libgnat.a -- END Object file/option list end ada_main; The Ada code in the above example is exactly what is generated by the binder. We have added comments to more clearly indicate the function of each part of the generated ‘Ada_Main’ package. The code is standard Ada in all respects, and can be processed by any tools that handle Ada. In particular, it is possible to use the debugger in Ada mode to debug the generated ‘Ada_Main’ package. For example, suppose that for reasons that you do not understand, your program is crashing during elaboration of the body of ‘Ada.Text_IO’. To locate this bug, you can place a breakpoint on the call: Ada.Text_Io'Elab_Body; and trace the elaboration routine for this package to find out where the problem might be (more usually of course you would be debugging elaboration code in your own application).  File: gnat_ugn.info, Node: Elaboration Order Handling in GNAT, Next: Inline Assembler, Prev: Example of Binder Output File, Up: Top 9 Elaboration Order Handling in GNAT ************************************ This appendix describes the handling of elaboration code in Ada and GNAT, and discusses how the order of elaboration of program units can be controlled in GNAT, either automatically or with explicit programming features. * Menu: * Elaboration Code:: * Elaboration Order:: * Checking the Elaboration Order:: * Controlling the Elaboration Order in Ada:: * Controlling the Elaboration Order in GNAT:: * Mixing Elaboration Models:: * ABE Diagnostics:: * SPARK Diagnostics:: * Elaboration Circularities:: * Resolving Elaboration Circularities:: * Elaboration-related Compiler Switches:: * Summary of Procedures for Elaboration Control:: * Inspecting the Chosen Elaboration Order::  File: gnat_ugn.info, Node: Elaboration Code, Next: Elaboration Order, Up: Elaboration Order Handling in GNAT 9.1 Elaboration Code ==================== Ada defines the term 'execution' as the process by which a construct achieves its run-time effect. This process is also referred to as 'elaboration' for declarations and 'evaluation' for expressions. The execution model in Ada allows for certain sections of an Ada program to be executed prior to execution of the program itself, primarily with the intent of initializing data. These sections are referred to as 'elaboration code'. Elaboration code is executed as follows: * All partitions of an Ada program are executed in parallel with one another, possibly in a separate address space, and possibly on a separate computer. * The execution of a partition involves running the environment task for that partition. * The environment task executes all elaboration code (if available) for all units within that partition. This code is said to be executed at 'elaboration time'. * The environment task executes the Ada program (if available) for that partition. In addition to the Ada terminology, this appendix defines the following terms: * 'Invocation' The act of calling a subprogram, instantiating a generic, or activating a task. * 'Scenario' A construct that is elaborated or invoked by elaboration code is referred to as an 'elaboration scenario' or simply a 'scenario'. GNAT recognizes the following scenarios: - ‘'Access’ of entries, operators, and subprograms - Activation of tasks - Calls to entries, operators, and subprograms - Instantiations of generic templates * 'Target' A construct elaborated by a scenario is referred to as 'elaboration target' or simply 'target'. GNAT recognizes the following targets: - For ‘'Access’ of entries, operators, and subprograms, the target is the entry, operator, or subprogram being aliased. - For activation of tasks, the target is the task body - For calls to entries, operators, and subprograms, the target is the entry, operator, or subprogram being invoked. - For instantiations of generic templates, the target is the generic template being instantiated. Elaboration code may appear in two distinct contexts: * 'Library level' A scenario appears at the library level when it is encapsulated by a package [body] compilation unit, ignoring any other package [body] declarations in between. with Server; package Client is procedure Proc; package Nested is Val : ... := Server.Func; end Nested; end Client; In the example above, the call to ‘Server.Func’ is an elaboration scenario because it appears at the library level of package ‘Client’. Note that the declaration of package ‘Nested’ is ignored according to the definition given above. As a result, the call to ‘Server.Func’ will be invoked when the spec of unit ‘Client’ is elaborated. * 'Package body statements' A scenario appears within the statement sequence of a package body when it is bounded by the region starting from the ‘begin’ keyword of the package body and ending at the ‘end’ keyword of the package body. package body Client is procedure Proc is begin ... end Proc; begin Proc; end Client; In the example above, the call to ‘Proc’ is an elaboration scenario because it appears within the statement sequence of package body ‘Client’. As a result, the call to ‘Proc’ will be invoked when the body of ‘Client’ is elaborated.  File: gnat_ugn.info, Node: Elaboration Order, Next: Checking the Elaboration Order, Prev: Elaboration Code, Up: Elaboration Order Handling in GNAT 9.2 Elaboration Order ===================== The sequence by which the elaboration code of all units within a partition is executed is referred to as 'elaboration order'. Within a single unit, elaboration code is executed in sequential order. package body Client is Result : ... := Server.Func; procedure Proc is package Inst is new Server.Gen; begin Inst.Eval (Result); end Proc; begin Proc; end Client; In the example above, the elaboration order within package body ‘Client’ is as follows: 1. The object declaration of ‘Result’ is elaborated. * Function ‘Server.Func’ is invoked. 2. The subprogram body of ‘Proc’ is elaborated. 3. Procedure ‘Proc’ is invoked. * Generic unit ‘Server.Gen’ is instantiated as ‘Inst’. * Instance ‘Inst’ is elaborated. * Procedure ‘Inst.Eval’ is invoked. The elaboration order of all units within a partition depends on the following factors: * 'with'ed units * parent units * purity of units * preelaborability of units * presence of elaboration-control pragmas * invocations performed in elaboration code A program may have several elaboration orders depending on its structure. package Server is function Func (Index : Integer) return Integer; end Server; package body Server is Results : array (1 .. 5) of Integer := (1, 2, 3, 4, 5); function Func (Index : Integer) return Integer is begin return Results (Index); end Func; end Server; with Server; package Client is Val : constant Integer := Server.Func (3); end Client; with Client; procedure Main is begin null; end Main; The following elaboration order exhibits a fundamental problem referred to as 'access-before-elaboration' or simply 'ABE'. spec of Server spec of Client body of Server body of Main The elaboration of ‘Server’’s spec materializes function ‘Func’, making it callable. The elaboration of ‘Client’’s spec elaborates the declaration of ‘Val’. This invokes function ‘Server.Func’, however the body of ‘Server.Func’ has not been elaborated yet because ‘Server’’s body comes after ‘Client’’s spec in the elaboration order. As a result, the value of constant ‘Val’ is now undefined. Without any guarantees from the language, an undetected ABE problem may hinder proper initialization of data, which in turn may lead to undefined behavior at run time. To prevent such ABE problems, Ada employs dynamic checks in the same vein as index or null exclusion checks. A failed ABE check raises exception ‘Program_Error’. The following elaboration order avoids the ABE problem and the program can be successfully elaborated. spec of Server body of Server spec of Client body of Main Ada states that a total elaboration order must exist, but it does not define what this order is. A compiler is thus tasked with choosing a suitable elaboration order which satisfies the dependencies imposed by 'with' clauses, unit categorization, elaboration-control pragmas, and invocations performed in elaboration code. Ideally an order that avoids ABE problems should be chosen, however a compiler may not always find such an order due to complications with respect to control and data flow.  File: gnat_ugn.info, Node: Checking the Elaboration Order, Next: Controlling the Elaboration Order in Ada, Prev: Elaboration Order, Up: Elaboration Order Handling in GNAT 9.3 Checking the Elaboration Order ================================== To avoid placing the entire elaboration-order burden on the programmer, Ada provides three lines of defense: * 'Static semantics' Static semantic rules restrict the possible choice of elaboration order. For instance, if unit Client 'with's unit Server, then the spec of Server is always elaborated prior to Client. The same principle applies to child units - the spec of a parent unit is always elaborated prior to the child unit. * 'Dynamic semantics' Dynamic checks are performed at run time, to ensure that a target is elaborated prior to a scenario that invokes it, thus avoiding ABE problems. A failed run-time check raises exception ‘Program_Error’. The following restrictions apply: - 'Restrictions on calls' An entry, operator, or subprogram can be called from elaboration code only when the corresponding body has been elaborated. - 'Restrictions on instantiations' A generic unit can be instantiated by elaboration code only when the corresponding body has been elaborated. - 'Restrictions on task activation' A task can be activated by elaboration code only when the body of the associated task type has been elaborated. The restrictions above can be summarized by the following rule: 'If a target has a body, then this body must be elaborated prior to the scenario that invokes the target.' * 'Elaboration control' Pragmas are provided for the programmer to specify the desired elaboration order.  File: gnat_ugn.info, Node: Controlling the Elaboration Order in Ada, Next: Controlling the Elaboration Order in GNAT, Prev: Checking the Elaboration Order, Up: Elaboration Order Handling in GNAT 9.4 Controlling the Elaboration Order in Ada ============================================ Ada provides several idioms and pragmas to aid the programmer with specifying the desired elaboration order and avoiding ABE problems altogether. * 'Packages without a body' A library package which does not require a completing body does not suffer from ABE problems. package Pack is generic type Element is private; package Containers is type Element_Array is array (1 .. 10) of Element; end Containers; end Pack; In the example above, package ‘Pack’ does not require a body because it does not contain any constructs which require completion in a body. As a result, generic ‘Pack.Containers’ can be instantiated without encountering any ABE problems. * 'pragma Pure' Pragma ‘Pure’ places sufficient restrictions on a unit to guarantee that no scenario within the unit can result in an ABE problem. * 'pragma Preelaborate' Pragma ‘Preelaborate’ is slightly less restrictive than pragma ‘Pure’, but still strong enough to prevent ABE problems within a unit. * 'pragma Elaborate_Body' Pragma ‘Elaborate_Body’ requires that the body of a unit is elaborated immediately after its spec. This restriction guarantees that no client scenario can invoke a server target before the target body has been elaborated because the spec and body are effectively “glued” together. package Server is pragma Elaborate_Body; function Func return Integer; end Server; package body Server is function Func return Integer is begin ... end Func; end Server; with Server; package Client is Val : constant Integer := Server.Func; end Client; In the example above, pragma ‘Elaborate_Body’ guarantees the following elaboration order: spec of Server body of Server spec of Client because the spec of ‘Server’ must be elaborated prior to ‘Client’ by virtue of the 'with' clause, and in addition the body of ‘Server’ must be elaborated immediately after the spec of ‘Server’. Removing pragma ‘Elaborate_Body’ could result in the following incorrect elaboration order: spec of Server spec of Client body of Server where ‘Client’ invokes ‘Server.Func’, but the body of ‘Server.Func’ has not been elaborated yet. The pragmas outlined above allow a server unit to guarantee safe elaboration use by client units. Thus it is a good rule to mark units as ‘Pure’ or ‘Preelaborate’, and if this is not possible, mark them as ‘Elaborate_Body’. There are however situations where ‘Pure’, ‘Preelaborate’, and ‘Elaborate_Body’ are not applicable. Ada provides another set of pragmas for use by client units to help ensure the elaboration safety of server units they depend on. * 'pragma Elaborate (Unit)' Pragma ‘Elaborate’ can be placed in the context clauses of a unit, after a 'with' clause. It guarantees that both the spec and body of its argument will be elaborated prior to the unit with the pragma. Note that other unrelated units may be elaborated in between the spec and the body. package Server is function Func return Integer; end Server; package body Server is function Func return Integer is begin ... end Func; end Server; with Server; pragma Elaborate (Server); package Client is Val : constant Integer := Server.Func; end Client; In the example above, pragma ‘Elaborate’ guarantees the following elaboration order: spec of Server body of Server spec of Client Removing pragma ‘Elaborate’ could result in the following incorrect elaboration order: spec of Server spec of Client body of Server where ‘Client’ invokes ‘Server.Func’, but the body of ‘Server.Func’ has not been elaborated yet. * 'pragma Elaborate_All (Unit)' Pragma ‘Elaborate_All’ is placed in the context clauses of a unit, after a 'with' clause. It guarantees that both the spec and body of its argument will be elaborated prior to the unit with the pragma, as well as all units 'with'ed by the spec and body of the argument, recursively. Note that other unrelated units may be elaborated in between the spec and the body. package Math is function Factorial (Val : Natural) return Natural; end Math; package body Math is function Factorial (Val : Natural) return Natural is begin ...; end Factorial; end Math; package Computer is type Operation_Kind is (None, Op_Factorial); function Compute (Val : Natural; Op : Operation_Kind) return Natural; end Computer; with Math; package body Computer is function Compute (Val : Natural; Op : Operation_Kind) return Natural is if Op = Op_Factorial then return Math.Factorial (Val); end if; return 0; end Compute; end Computer; with Computer; pragma Elaborate_All (Computer); package Client is Val : constant Natural := Computer.Compute (123, Computer.Op_Factorial); end Client; In the example above, pragma ‘Elaborate_All’ can result in the following elaboration order: spec of Math body of Math spec of Computer body of Computer spec of Client Note that there are several allowable suborders for the specs and bodies of ‘Math’ and ‘Computer’, but the point is that these specs and bodies will be elaborated prior to ‘Client’. Removing pragma ‘Elaborate_All’ could result in the following incorrect elaboration order: spec of Math spec of Computer body of Computer spec of Client body of Math where ‘Client’ invokes ‘Computer.Compute’, which in turn invokes ‘Math.Factorial’, but the body of ‘Math.Factorial’ has not been elaborated yet. All pragmas shown above can be summarized by the following rule: 'If a client unit elaborates a server target directly or indirectly, then if the server unit requires a body and does not have pragma Pure, Preelaborate, or Elaborate_Body, then the client unit should have pragma Elaborate or Elaborate_All for the server unit.' If the rule outlined above is not followed, then a program may fall in one of the following states: * 'No elaboration order exists' In this case a compiler must diagnose the situation, and refuse to build an executable program. * 'One or more incorrect elaboration orders exist' In this case a compiler can build an executable program, but ‘Program_Error’ will be raised when the program is run. * 'Several elaboration orders exist, some correct, some incorrect' In this case the programmer has not controlled the elaboration order. As a result, a compiler may or may not pick one of the correct orders, and the program may or may not raise ‘Program_Error’ when it is run. This is the worst possible state because the program may fail on another compiler, or even another version of the same compiler. * 'One or more correct orders exist' In this case a compiler can build an executable program, and the program is run successfully. This state may be guaranteed by following the outlined rules, or may be the result of good program architecture. Note that one additional advantage of using ‘Elaborate’ and ‘Elaborate_All’ is that the program continues to stay in the last state (one or more correct orders exist) even if maintenance changes the bodies of targets.  File: gnat_ugn.info, Node: Controlling the Elaboration Order in GNAT, Next: Mixing Elaboration Models, Prev: Controlling the Elaboration Order in Ada, Up: Elaboration Order Handling in GNAT 9.5 Controlling the Elaboration Order in GNAT ============================================= In addition to Ada semantics and rules synthesized from them, GNAT offers three elaboration models to aid the programmer with specifying the correct elaboration order and to diagnose elaboration problems. * 'Dynamic elaboration model' This is the most permissive of the three elaboration models and emulates the behavior specified by the Ada Reference Manual. When the dynamic model is in effect, GNAT makes the following assumptions: - All code within all units in a partition is considered to be elaboration code. - Some of the invocations in elaboration code may not take place at run time due to conditional execution. GNAT performs extensive diagnostics on a unit-by-unit basis for all scenarios that invoke internal targets. In addition, GNAT generates run-time checks for all external targets and for all scenarios that may exhibit ABE problems. The elaboration order is obtained by honoring all 'with' clauses, purity and preelaborability of units, and elaboration-control pragmas. The dynamic model attempts to take all invocations in elaboration code into account. If an invocation leads to a circularity, GNAT ignores the invocation based on the assumptions stated above. An order obtained using the dynamic model may fail an ABE check at run time when GNAT ignored an invocation. The dynamic model is enabled with compiler switch ‘-gnatE’. * 'Static elaboration model' This is the middle ground of the three models. When the static model is in effect, GNAT makes the following assumptions: - Only code at the library level and in package body statements within all units in a partition is considered to be elaboration code. - All invocations in elaboration will take place at run time, regardless of conditional execution. GNAT performs extensive diagnostics on a unit-by-unit basis for all scenarios that invoke internal targets. In addition, GNAT generates run-time checks for all external targets and for all scenarios that may exhibit ABE problems. The elaboration order is obtained by honoring all 'with' clauses, purity and preelaborability of units, presence of elaboration-control pragmas, and all invocations in elaboration code. An order obtained using the static model is guaranteed to be ABE problem-free, excluding dispatching calls and access-to-subprogram types. The static model is the default model in GNAT. * 'SPARK elaboration model' This is the most conservative of the three models and enforces the SPARK rules of elaboration as defined in the SPARK Reference Manual, section 7.7. The SPARK model is in effect only when a scenario and a target reside in a region subject to ‘SPARK_Mode On’, otherwise the dynamic or static model is in effect. The SPARK model is enabled with compiler switch ‘-gnatd.v’. * 'Legacy elaboration models' In addition to the three elaboration models outlined above, GNAT provides the following legacy models: - ‘Legacy elaboration-checking model’ available in pre-18.x versions of GNAT. This model is enabled with compiler switch ‘-gnatH’. - ‘Legacy elaboration-order model’ available in pre-20.x versions of GNAT. This model is enabled with binder switch ‘-H’. The dynamic, legacy, and static models can be relaxed using compiler switch ‘-gnatJ’, making them more permissive. Note that in this mode, GNAT may not diagnose certain elaboration issues or install run-time checks.  File: gnat_ugn.info, Node: Mixing Elaboration Models, Next: ABE Diagnostics, Prev: Controlling the Elaboration Order in GNAT, Up: Elaboration Order Handling in GNAT 9.6 Mixing Elaboration Models ============================= It is possible to mix units compiled with a different elaboration model, however the following rules must be observed: * A client unit compiled with the dynamic model can only 'with' a server unit that meets at least one of the following criteria: - The server unit is compiled with the dynamic model. - The server unit is a GNAT implementation unit from the ‘Ada’, ‘GNAT’, ‘Interfaces’, or ‘System’ hierarchies. - The server unit has pragma ‘Pure’ or ‘Preelaborate’. - The client unit has an explicit ‘Elaborate_All’ pragma for the server unit. These rules ensure that elaboration checks are not omitted. If the rules are violated, the binder emits a warning: warning: "x.ads" has dynamic elaboration checks and with's warning: "y.ads" which has static elaboration checks The warnings can be suppressed by binder switch ‘-ws’.  File: gnat_ugn.info, Node: ABE Diagnostics, Next: SPARK Diagnostics, Prev: Mixing Elaboration Models, Up: Elaboration Order Handling in GNAT 9.7 ABE Diagnostics =================== GNAT performs extensive diagnostics on a unit-by-unit basis for all scenarios that invoke internal targets, regardless of whether the dynamic, SPARK, or static model is in effect. Note that GNAT emits warnings rather than hard errors whenever it encounters an elaboration problem. This is because the elaboration model in effect may be too conservative, or a particular scenario may not be invoked due conditional execution. The warnings can be suppressed selectively with ‘pragma Warnings (Off)’ or globally with compiler switch ‘-gnatwL’. A 'guaranteed ABE' arises when the body of a target is not elaborated early enough, and causes 'all' scenarios that directly invoke the target to fail. package body Guaranteed_ABE is function ABE return Integer; Val : constant Integer := ABE; function ABE return Integer is begin ... end ABE; end Guaranteed_ABE; In the example above, the elaboration of ‘Guaranteed_ABE’’s body elaborates the declaration of ‘Val’. This invokes function ‘ABE’, however the body of ‘ABE’ has not been elaborated yet. GNAT emits the following diagnostic: 4. Val : constant Integer := ABE; | >>> warning: cannot call "ABE" before body seen >>> warning: Program_Error will be raised at run time A 'conditional ABE' arises when the body of a target is not elaborated early enough, and causes 'some' scenarios that directly invoke the target to fail. 1. package body Conditional_ABE is 2. procedure Force_Body is null; 3. 4. generic 5. with function Func return Integer; 6. package Gen is 7. Val : constant Integer := Func; 8. end Gen; 9. 10. function ABE return Integer; 11. 12. function Cause_ABE return Boolean is 13. package Inst is new Gen (ABE); 14. begin 15. ... 16. end Cause_ABE; 17. 18. Val : constant Boolean := Cause_ABE; 19. 20. function ABE return Integer is 21. begin 22. ... 23. end ABE; 24. 25. Safe : constant Boolean := Cause_ABE; 26. end Conditional_ABE; In the example above, the elaboration of package body ‘Conditional_ABE’ elaborates the declaration of ‘Val’. This invokes function ‘Cause_ABE’, which instantiates generic unit ‘Gen’ as ‘Inst’. The elaboration of ‘Inst’ invokes function ‘ABE’, however the body of ‘ABE’ has not been elaborated yet. GNAT emits the following diagnostic: 13. package Inst is new Gen (ABE); | >>> warning: in instantiation at line 7 >>> warning: cannot call "ABE" before body seen >>> warning: Program_Error may be raised at run time >>> warning: body of unit "Conditional_ABE" elaborated >>> warning: function "Cause_ABE" called at line 18 >>> warning: function "ABE" called at line 7, instance at line 13 Note that the same ABE problem does not occur with the elaboration of declaration ‘Safe’ because the body of function ‘ABE’ has already been elaborated at that point.  File: gnat_ugn.info, Node: SPARK Diagnostics, Next: Elaboration Circularities, Prev: ABE Diagnostics, Up: Elaboration Order Handling in GNAT 9.8 SPARK Diagnostics ===================== GNAT enforces the SPARK rules of elaboration as defined in the SPARK Reference Manual section 7.7 when compiler switch ‘-gnatd.v’ is in effect. Note that GNAT emits hard errors whenever it encounters a violation of the SPARK rules. 1. with Server; 2. package body SPARK_Diagnostics with SPARK_Mode is 3. Val : constant Integer := Server.Func; | >>> call to "Func" during elaboration in SPARK >>> unit "SPARK_Diagnostics" requires pragma "Elaborate_All" for "Server" >>> body of unit "SPARK_Model" elaborated >>> function "Func" called at line 3 4. end SPARK_Diagnostics;  File: gnat_ugn.info, Node: Elaboration Circularities, Next: Resolving Elaboration Circularities, Prev: SPARK Diagnostics, Up: Elaboration Order Handling in GNAT 9.9 Elaboration Circularities ============================= An 'elaboration circularity' occurs whenever the elaboration of a set of units enters a deadlocked state, where each unit is waiting for another unit to be elaborated. This situation may be the result of improper use of 'with' clauses, elaboration-control pragmas, or invocations in elaboration code. The following example exhibits an elaboration circularity. with B; pragma Elaborate (B); package A is end A; package B is procedure Force_Body; end B; with C; package body B is procedure Force_Body is null; Elab : constant Integer := C.Func; end B; package C is function Func return Integer; end C; with A; package body C is function Func return Integer is begin ... end Func; end C; The binder emits the following diagnostic: error: Elaboration circularity detected info: info: Reason: info: info: unit "a (spec)" depends on its own elaboration info: info: Circularity: info: info: unit "a (spec)" has with clause and pragma Elaborate for unit "b (spec)" info: unit "b (body)" is in the closure of pragma Elaborate info: unit "b (body)" invokes a construct of unit "c (body)" at elaboration time info: unit "c (body)" has with clause for unit "a (spec)" info: info: Suggestions: info: info: remove pragma Elaborate for unit "b (body)" in unit "a (spec)" info: use the dynamic elaboration model (compiler switch -gnatE) The diagnostic consist of the following sections: * Reason This section provides a short explanation describing why the set of units could not be ordered. * Circularity This section enumerates the units comprising the deadlocked set, along with their interdependencies. * Suggestions This section enumerates various tactics for eliminating the circularity.  File: gnat_ugn.info, Node: Resolving Elaboration Circularities, Next: Elaboration-related Compiler Switches, Prev: Elaboration Circularities, Up: Elaboration Order Handling in GNAT 9.10 Resolving Elaboration Circularities ======================================== The most desirable option from the point of view of long-term maintenance is to rearrange the program so that the elaboration problems are avoided. One useful technique is to place the elaboration code into separate child packages. Another is to move some of the initialization code to explicitly invoked subprograms, where the program controls the order of initialization explicitly. Although this is the most desirable option, it may be impractical and involve too much modification, especially in the case of complex legacy code. When faced with an elaboration circularity, the programmer should also consider the tactics given in the suggestions section of the circularity diagnostic. Depending on the units involved in the circularity, their 'with' clauses, purity, preelaborability, presence of elaboration-control pragmas and invocations at elaboration time, the binder may suggest one or more of the following tactics to eliminate the circularity: * Pragma Elaborate elimination remove pragma Elaborate for unit "..." in unit "..." This tactic is suggested when the binder has determined that pragma ‘Elaborate’: - Prevents a set of units from being elaborated. - The removal of the pragma will not eliminate the semantic effects of the pragma. In other words, the argument of the pragma will still be elaborated prior to the unit containing the pragma. - The removal of the pragma will enable the successful ordering of the units. The programmer should remove the pragma as advised, and rebuild the program. * Pragma Elaborate_All elimination remove pragma Elaborate_All for unit "..." in unit "..." This tactic is suggested when the binder has determined that pragma ‘Elaborate_All’: - Prevents a set of units from being elaborated. - The removal of the pragma will not eliminate the semantic effects of the pragma. In other words, the argument of the pragma along with its 'with' closure will still be elaborated prior to the unit containing the pragma. - The removal of the pragma will enable the successful ordering of the units. The programmer should remove the pragma as advised, and rebuild the program. * Pragma Elaborate_All downgrade change pragma Elaborate_All for unit "..." to Elaborate in unit "..." This tactic is always suggested with the pragma ‘Elaborate_All’ elimination tactic. It offers a different alternative of guaranteeing that the argument of the pragma will still be elaborated prior to the unit containing the pragma. The programmer should update the pragma as advised, and rebuild the program. * Pragma Elaborate_Body elimination remove pragma Elaborate_Body in unit "..." This tactic is suggested when the binder has determined that pragma ‘Elaborate_Body’: - Prevents a set of units from being elaborated. - The removal of the pragma will enable the successful ordering of the units. Note that the binder cannot determine whether the pragma is required for other purposes, such as guaranteeing the initialization of a variable declared in the spec by elaboration code in the body. The programmer should remove the pragma as advised, and rebuild the program. * Use of pragma Restrictions use pragma Restrictions (No_Entry_Calls_In_Elaboration_Code) This tactic is suggested when the binder has determined that a task activation at elaboration time: - Prevents a set of units from being elaborated. Note that the binder cannot determine with certainty whether the task will block at elaboration time. The programmer should create a configuration file, place the pragma within, update the general compilation arguments, and rebuild the program. * Use of dynamic elaboration model use the dynamic elaboration model (compiler switch -gnatE) This tactic is suggested when the binder has determined that an invocation at elaboration time: - Prevents a set of units from being elaborated. - The use of the dynamic model will enable the successful ordering of the units. The programmer has two options: - Determine the units involved in the invocation using the detailed invocation information, and add compiler switch ‘-gnatE’ to the compilation arguments of selected files only. This approach will yield safer elaboration orders compared to the other option because it will minimize the opportunities presented to the dynamic model for ignoring invocations. - Add compiler switch ‘-gnatE’ to the general compilation arguments. * Use of detailed invocation information use detailed invocation information (compiler switch -gnatd_F) This tactic is always suggested with the use of the dynamic model tactic. It causes the circularity section of the circularity diagnostic to describe the flow of elaboration code from a unit to a unit, enumerating all such paths in the process. The programmer should analyze this information to determine which units should be compiled with the dynamic model. * Forced-dependency elimination remove the dependency of unit "..." on unit "..." from the argument of switch -f This tactic is suggested when the binder has determined that a dependency present in the forced-elaboration-order file indicated by binder switch ‘-f’: - Prevents a set of units from being elaborated. - The removal of the dependency will enable the successful ordering of the units. The programmer should edit the forced-elaboration-order file, remove the dependency, and rebind the program. * All forced-dependency elimination remove switch -f This tactic is suggested in case editing the forced-elaboration-order file is not an option. The programmer should remove binder switch ‘-f’ from the binder arguments, and rebind. * Multiple-circularities diagnostic diagnose all circularities (binder switch -d_C) By default, the binder will diagnose only the highest-precedence circularity. If the program contains multiple circularities, the binder will suggest the use of binder switch ‘-d_C’ in order to obtain the diagnostics of all circularities. The programmer should add binder switch ‘-d_C’ to the binder arguments, and rebind. If none of the tactics suggested by the binder eliminate the elaboration circularity, the programmer should consider using one of the legacy elaboration models, in the following order: * Use the pre-20.x legacy elaboration-order model, with binder switch ‘-H’. * Use both pre-18.x and pre-20.x legacy elaboration models, with compiler switch ‘-gnatH’ and binder switch ‘-H’. * Use the relaxed static-elaboration model, with compiler switches ‘-gnatH’ ‘-gnatJ’ and binder switch ‘-H’. * Use the relaxed dynamic-elaboration model, with compiler switches ‘-gnatH’ ‘-gnatJ’ ‘-gnatE’ and binder switch ‘-H’.  File: gnat_ugn.info, Node: Elaboration-related Compiler Switches, Next: Summary of Procedures for Elaboration Control, Prev: Resolving Elaboration Circularities, Up: Elaboration Order Handling in GNAT 9.11 Elaboration-related Compiler Switches ========================================== GNAT has several switches that affect the elaboration model and consequently the elaboration order chosen by the binder. ‘-gnatE’ Dynamic elaboration checking mode enabled When this switch is in effect, GNAT activates the dynamic model. ‘-gnatel’ Turn on info messages on generated Elaborate[_All] pragmas This switch is only applicable to the pre-20.x legacy elaboration models. The post-20.x elaboration model no longer relies on implicitly generated ‘Elaborate’ and ‘Elaborate_All’ pragmas to order units. When this switch is in effect, GNAT will emit the following supplementary information depending on the elaboration model in effect. - 'Dynamic model' GNAT will indicate missing ‘Elaborate’ and ‘Elaborate_All’ pragmas for all library-level scenarios within the partition. - 'Static model' GNAT will indicate all scenarios invoked during elaboration. In addition, it will provide detailed traceback when an implicit ‘Elaborate’ or ‘Elaborate_All’ pragma is generated. - 'SPARK model' GNAT will indicate how an elaboration requirement is met by the context of a unit. This diagnostic requires compiler switch ‘-gnatd.v’. 1. with Server; pragma Elaborate_All (Server); 2. package Client with SPARK_Mode is 3. Val : constant Integer := Server.Func; | >>> info: call to "Func" during elaboration in SPARK >>> info: "Elaborate_All" requirement for unit "Server" met by pragma at line 1 4. end Client; ‘-gnatH’ Legacy elaboration checking mode enabled When this switch is in effect, GNAT will utilize the pre-18.x elaboration model. ‘-gnatJ’ Relaxed elaboration checking mode enabled When this switch is in effect, GNAT will not process certain scenarios, resulting in a more permissive elaboration model. Note that this may eliminate some diagnostics and run-time checks. ‘-gnatw.f’ Turn on warnings for suspicious Subp’Access When this switch is in effect, GNAT will treat ‘'Access’ of an entry, operator, or subprogram as a potential call to the target and issue warnings: 1. package body Attribute_Call is 2. function Func return Integer; 3. type Func_Ptr is access function return Integer; 4. 5. Ptr : constant Func_Ptr := Func'Access; | >>> warning: "Access" attribute of "Func" before body seen >>> warning: possible Program_Error on later references >>> warning: body of unit "Attribute_Call" elaborated >>> warning: "Access" of "Func" taken at line 5 6. 7. function Func return Integer is 8. begin 9. ... 10. end Func; 11. end Attribute_Call; In the example above, the elaboration of declaration ‘Ptr’ is assigned ‘Func'Access’ before the body of ‘Func’ has been elaborated. ‘-gnatwl’ Turn on warnings for elaboration problems When this switch is in effect, GNAT emits diagnostics in the form of warnings concerning various elaboration problems. The warnings are enabled by default. The switch is provided in case all warnings are suppressed, but elaboration warnings are still desired. ‘-gnatwL’ Turn off warnings for elaboration problems When this switch is in effect, GNAT no longer emits any diagnostics in the form of warnings. Selective suppression of elaboration problems is possible using ‘pragma Warnings (Off)’. 1. package body Selective_Suppression is 2. function ABE return Integer; 3. 4. Val_1 : constant Integer := ABE; | >>> warning: cannot call "ABE" before body seen >>> warning: Program_Error will be raised at run time 5. 6. pragma Warnings (Off); 7. Val_2 : constant Integer := ABE; 8. pragma Warnings (On); 9. 10. function ABE return Integer is 11. begin 12. ... 13. end ABE; 14. end Selective_Suppression; Note that suppressing elaboration warnings does not eliminate run-time checks. The example above will still fail at run time with an ABE.  File: gnat_ugn.info, Node: Summary of Procedures for Elaboration Control, Next: Inspecting the Chosen Elaboration Order, Prev: Elaboration-related Compiler Switches, Up: Elaboration Order Handling in GNAT 9.12 Summary of Procedures for Elaboration Control ================================================== A programmer should first compile the program with the default options, using none of the binder or compiler switches. If the binder succeeds in finding an elaboration order, then apart from possible cases involving dispatching calls and access-to-subprogram types, the program is free of elaboration errors. If it is important for the program to be portable to compilers other than GNAT, then the programmer should use compiler switch ‘-gnatel’ and consider the messages about missing or implicitly created ‘Elaborate’ and ‘Elaborate_All’ pragmas. If the binder reports an elaboration circularity, the programmer has several options: * Ensure that elaboration warnings are enabled. This will allow the static model to output trace information of elaboration issues. The trace information could shed light on previously unforeseen dependencies, as well as their origins. Elaboration warnings are enabled with compiler switch ‘-gnatwl’. * Cosider the tactics given in the suggestions section of the circularity diagnostic. * If none of the steps outlined above resolve the circularity, use a more permissive elaboration model, in the following order: - Use the pre-20.x legacy elaboration-order model, with binder switch ‘-H’. - Use both pre-18.x and pre-20.x legacy elaboration models, with compiler switch ‘-gnatH’ and binder switch ‘-H’. - Use the relaxed static elaboration model, with compiler switches ‘-gnatH’ ‘-gnatJ’ and binder switch ‘-H’. - Use the relaxed dynamic elaboration model, with compiler switches ‘-gnatH’ ‘-gnatJ’ ‘-gnatE’ and binder switch ‘-H’.  File: gnat_ugn.info, Node: Inspecting the Chosen Elaboration Order, Prev: Summary of Procedures for Elaboration Control, Up: Elaboration Order Handling in GNAT 9.13 Inspecting the Chosen Elaboration Order ============================================ To see the elaboration order chosen by the binder, inspect the contents of file ‘b~xxx.adb’. On certain targets, this file appears as ‘b_xxx.adb’. The elaboration order appears as a sequence of calls to ‘Elab_Body’ and ‘Elab_Spec’, interspersed with assignments to ‘Exxx’ which indicates that a particular unit is elaborated. For example: System.Soft_Links'Elab_Body; E14 := True; System.Secondary_Stack'Elab_Body; E18 := True; System.Exception_Table'Elab_Body; E24 := True; Ada.Io_Exceptions'Elab_Spec; E67 := True; Ada.Tags'Elab_Spec; Ada.Streams'Elab_Spec; E43 := True; Interfaces.C'Elab_Spec; E69 := True; System.Finalization_Root'Elab_Spec; E60 := True; System.Os_Lib'Elab_Body; E71 := True; System.Finalization_Implementation'Elab_Spec; System.Finalization_Implementation'Elab_Body; E62 := True; Ada.Finalization'Elab_Spec; E58 := True; Ada.Finalization.List_Controller'Elab_Spec; E76 := True; System.File_Control_Block'Elab_Spec; E74 := True; System.File_Io'Elab_Body; E56 := True; Ada.Tags'Elab_Body; E45 := True; Ada.Text_Io'Elab_Spec; Ada.Text_Io'Elab_Body; E07 := True; Note also binder switch ‘-l’, which outputs the chosen elaboration order and provides a more readable form of the above: ada (spec) interfaces (spec) system (spec) system.case_util (spec) system.case_util (body) system.concat_2 (spec) system.concat_2 (body) system.concat_3 (spec) system.concat_3 (body) system.htable (spec) system.parameters (spec) system.parameters (body) system.crtl (spec) interfaces.c_streams (spec) interfaces.c_streams (body) system.restrictions (spec) system.restrictions (body) system.standard_library (spec) system.exceptions (spec) system.exceptions (body) system.storage_elements (spec) system.storage_elements (body) system.secondary_stack (spec) system.stack_checking (spec) system.stack_checking (body) system.string_hash (spec) system.string_hash (body) system.htable (body) system.strings (spec) system.strings (body) system.traceback (spec) system.traceback (body) system.traceback_entries (spec) system.traceback_entries (body) ada.exceptions (spec) ada.exceptions.last_chance_handler (spec) system.soft_links (spec) system.soft_links (body) ada.exceptions.last_chance_handler (body) system.secondary_stack (body) system.exception_table (spec) system.exception_table (body) ada.io_exceptions (spec) ada.tags (spec) ada.streams (spec) interfaces.c (spec) interfaces.c (body) system.finalization_root (spec) system.finalization_root (body) system.memory (spec) system.memory (body) system.standard_library (body) system.os_lib (spec) system.os_lib (body) system.unsigned_types (spec) system.stream_attributes (spec) system.stream_attributes (body) system.finalization_implementation (spec) system.finalization_implementation (body) ada.finalization (spec) ada.finalization (body) ada.finalization.list_controller (spec) ada.finalization.list_controller (body) system.file_control_block (spec) system.file_io (spec) system.file_io (body) system.val_uns (spec) system.val_util (spec) system.val_util (body) system.val_uns (body) system.wch_con (spec) system.wch_con (body) system.wch_cnv (spec) system.wch_jis (spec) system.wch_jis (body) system.wch_cnv (body) system.wch_stw (spec) system.wch_stw (body) ada.tags (body) ada.exceptions (body) ada.text_io (spec) ada.text_io (body) text_io (spec) gdbstr (body)  File: gnat_ugn.info, Node: Inline Assembler, Next: GNU Free Documentation License, Prev: Elaboration Order Handling in GNAT, Up: Top 10 Inline Assembler ******************* If you need to write low-level software that interacts directly with the hardware, Ada provides two ways to incorporate assembly language code into your program. First, you can import and invoke external routines written in assembly language, an Ada feature fully supported by GNAT. However, for small sections of code it may be simpler or more efficient to include assembly language statements directly in your Ada source program, using the facilities of the implementation-defined package ‘System.Machine_Code’, which incorporates the gcc Inline Assembler. The Inline Assembler approach offers a number of advantages, including the following: * No need to use non-Ada tools * Consistent interface over different targets * Automatic usage of the proper calling conventions * Access to Ada constants and variables * Definition of intrinsic routines * Possibility of inlining a subprogram comprising assembler code * Code optimizer can take Inline Assembler code into account This appendix presents a series of examples to show you how to use the Inline Assembler. Although it focuses on the Intel x86, the general approach applies also to other processors. It is assumed that you are familiar with Ada and with assembly language programming. * Menu: * Basic Assembler Syntax:: * A Simple Example of Inline Assembler:: * Output Variables in Inline Assembler:: * Input Variables in Inline Assembler:: * Inlining Inline Assembler Code:: * Other Asm Functionality::  File: gnat_ugn.info, Node: Basic Assembler Syntax, Next: A Simple Example of Inline Assembler, Up: Inline Assembler 10.1 Basic Assembler Syntax =========================== The assembler used by GNAT and gcc is based not on the Intel assembly language, but rather on a language that descends from the AT&T Unix assembler ‘as’ (and which is often referred to as ‘AT&T syntax’). The following table summarizes the main features of ‘as’ syntax and points out the differences from the Intel conventions. See the gcc ‘as’ and ‘gas’ (an ‘as’ macro pre-processor) documentation for further information. 'Register names' gcc / ‘as’: Prefix with ‘%’; for example ‘%eax’ Intel: No extra punctuation; for example ‘eax’ 'Immediate operand' gcc / ‘as’: Prefix with ‘$’; for example ‘$4’ Intel: No extra punctuation; for example ‘4’ 'Address' gcc / ‘as’: Prefix with ‘$’; for example ‘$loc’ Intel: No extra punctuation; for example ‘loc’ 'Memory contents' gcc / ‘as’: No extra punctuation; for example ‘loc’ Intel: Square brackets; for example ‘[loc]’ 'Register contents' gcc / ‘as’: Parentheses; for example ‘(%eax)’ Intel: Square brackets; for example ‘[eax]’ 'Hexadecimal numbers' gcc / ‘as’: Leading ‘0x’ (C language syntax); for example ‘0xA0’ Intel: Trailing ‘h’; for example ‘A0h’ 'Operand size' gcc / ‘as’: Explicit in op code; for example ‘movw’ to move a 16-bit word Intel: Implicit, deduced by assembler; for example ‘mov’ 'Instruction repetition' gcc / ‘as’: Split into two lines; for example ‘rep’ ‘stosl’ Intel: Keep on one line; for example ‘rep stosl’ 'Order of operands' gcc / ‘as’: Source first; for example ‘movw $4, %eax’ Intel: Destination first; for example ‘mov eax, 4’  File: gnat_ugn.info, Node: A Simple Example of Inline Assembler, Next: Output Variables in Inline Assembler, Prev: Basic Assembler Syntax, Up: Inline Assembler 10.2 A Simple Example of Inline Assembler ========================================= The following example will generate a single assembly language statement, ‘nop’, which does nothing. Despite its lack of run-time effect, the example will be useful in illustrating the basics of the Inline Assembler facility. with System.Machine_Code; use System.Machine_Code; procedure Nothing is begin Asm ("nop"); end Nothing; ‘Asm’ is a procedure declared in package ‘System.Machine_Code’; here it takes one parameter, a 'template string' that must be a static expression and that will form the generated instruction. ‘Asm’ may be regarded as a compile-time procedure that parses the template string and additional parameters (none here), from which it generates a sequence of assembly language instructions. The examples in this chapter will illustrate several of the forms for invoking ‘Asm’; a complete specification of the syntax is found in the ‘Machine_Code_Insertions’ section of the ‘GNAT Reference Manual’. Under the standard GNAT conventions, the ‘Nothing’ procedure should be in a file named ‘nothing.adb’. You can build the executable in the usual way: $ gnatmake nothing However, the interesting aspect of this example is not its run-time behavior but rather the generated assembly code. To see this output, invoke the compiler as follows: $ gcc -c -S -fomit-frame-pointer -gnatp nothing.adb where the options are: * ‘-c’ compile only (no bind or link) * ‘-S’ generate assembler listing * ‘-fomit-frame-pointer’ do not set up separate stack frames * ‘-gnatp’ do not add runtime checks This gives a human-readable assembler version of the code. The resulting file will have the same name as the Ada source file, but with a ‘.s’ extension. In our example, the file ‘nothing.s’ has the following contents: .file "nothing.adb" gcc2_compiled.: ___gnu_compiled_ada: .text .align 4 .globl __ada_nothing __ada_nothing: #APP nop #NO_APP jmp L1 .align 2,0x90 L1: ret The assembly code you included is clearly indicated by the compiler, between the ‘#APP’ and ‘#NO_APP’ delimiters. The character before the ‘APP’ and ‘NOAPP’ can differ on different targets. For example, GNU/Linux uses ‘#APP’ while on NT you will see ‘/APP’. If you make a mistake in your assembler code (such as using the wrong size modifier, or using a wrong operand for the instruction) GNAT will report this error in a temporary file, which will be deleted when the compilation is finished. Generating an assembler file will help in such cases, since you can assemble this file separately using the ‘as’ assembler that comes with gcc. Assembling the file using the command $ as nothing.s will give you error messages whose lines correspond to the assembler input file, so you can easily find and correct any mistakes you made. If there are no errors, ‘as’ will generate an object file ‘nothing.out’.  File: gnat_ugn.info, Node: Output Variables in Inline Assembler, Next: Input Variables in Inline Assembler, Prev: A Simple Example of Inline Assembler, Up: Inline Assembler 10.3 Output Variables in Inline Assembler ========================================= The examples in this section, showing how to access the processor flags, illustrate how to specify the destination operands for assembly language statements. with Interfaces; use Interfaces; with Ada.Text_IO; use Ada.Text_IO; with System.Machine_Code; use System.Machine_Code; procedure Get_Flags is Flags : Unsigned_32; use ASCII; begin Asm ("pushfl" & LF & HT & -- push flags on stack "popl %%eax" & LF & HT & -- load eax with flags "movl %%eax, %0", -- store flags in variable Outputs => Unsigned_32'Asm_Output ("=g", Flags)); Put_Line ("Flags register:" & Flags'Img); end Get_Flags; In order to have a nicely aligned assembly listing, we have separated multiple assembler statements in the Asm template string with linefeed (ASCII.LF) and horizontal tab (ASCII.HT) characters. The resulting section of the assembly output file is: #APP pushfl popl %eax movl %eax, -40(%ebp) #NO_APP It would have been legal to write the Asm invocation as: Asm ("pushfl popl %%eax movl %%eax, %0") but in the generated assembler file, this would come out as: #APP pushfl popl %eax movl %eax, -40(%ebp) #NO_APP which is not so convenient for the human reader. We use Ada comments at the end of each line to explain what the assembler instructions actually do. This is a useful convention. When writing Inline Assembler instructions, you need to precede each register and variable name with a percent sign. Since the assembler already requires a percent sign at the beginning of a register name, you need two consecutive percent signs for such names in the Asm template string, thus ‘%%eax’. In the generated assembly code, one of the percent signs will be stripped off. Names such as ‘%0’, ‘%1’, ‘%2’, etc., denote input or output variables: operands you later define using ‘Input’ or ‘Output’ parameters to ‘Asm’. An output variable is illustrated in the third statement in the Asm template string: movl %%eax, %0 The intent is to store the contents of the eax register in a variable that can be accessed in Ada. Simply writing ‘movl %%eax, Flags’ would not necessarily work, since the compiler might optimize by using a register to hold Flags, and the expansion of the ‘movl’ instruction would not be aware of this optimization. The solution is not to store the result directly but rather to advise the compiler to choose the correct operand form; that is the purpose of the ‘%0’ output variable. Information about the output variable is supplied in the ‘Outputs’ parameter to ‘Asm’: Outputs => Unsigned_32'Asm_Output ("=g", Flags)); The output is defined by the ‘Asm_Output’ attribute of the target type; the general format is Type'Asm_Output (constraint_string, variable_name) The constraint string directs the compiler how to store/access the associated variable. In the example Unsigned_32'Asm_Output ("=m", Flags); the ‘"m"’ (memory) constraint tells the compiler that the variable ‘Flags’ should be stored in a memory variable, thus preventing the optimizer from keeping it in a register. In contrast, Unsigned_32'Asm_Output ("=r", Flags); uses the ‘"r"’ (register) constraint, telling the compiler to store the variable in a register. If the constraint is preceded by the equal character ‘=’, it tells the compiler that the variable will be used to store data into it. In the ‘Get_Flags’ example, we used the ‘"g"’ (global) constraint, allowing the optimizer to choose whatever it deems best. There are a fairly large number of constraints, but the ones that are most useful (for the Intel x86 processor) are the following: '=' output constraint 'g' global (i.e., can be stored anywhere) 'm' in memory 'I' a constant 'a' use eax 'b' use ebx 'c' use ecx 'd' use edx 'S' use esi 'D' use edi 'r' use one of eax, ebx, ecx or edx 'q' use one of eax, ebx, ecx, edx, esi or edi The full set of constraints is described in the gcc and ‘as’ documentation; note that it is possible to combine certain constraints in one constraint string. You specify the association of an output variable with an assembler operand through the ‘%N’ notation, where 'n' is a non-negative integer. Thus in Asm ("pushfl" & LF & HT & -- push flags on stack "popl %%eax" & LF & HT & -- load eax with flags "movl %%eax, %0", -- store flags in variable Outputs => Unsigned_32'Asm_Output ("=g", Flags)); ‘%0’ will be replaced in the expanded code by the appropriate operand, whatever the compiler decided for the ‘Flags’ variable. In general, you may have any number of output variables: * Count the operands starting at 0; thus ‘%0’, ‘%1’, etc. * Specify the ‘Outputs’ parameter as a parenthesized comma-separated list of ‘Asm_Output’ attributes For example: Asm ("movl %%eax, %0" & LF & HT & "movl %%ebx, %1" & LF & HT & "movl %%ecx, %2", Outputs => (Unsigned_32'Asm_Output ("=g", Var_A), -- %0 = Var_A Unsigned_32'Asm_Output ("=g", Var_B), -- %1 = Var_B Unsigned_32'Asm_Output ("=g", Var_C))); -- %2 = Var_C where ‘Var_A’, ‘Var_B’, and ‘Var_C’ are variables in the Ada program. As a variation on the ‘Get_Flags’ example, we can use the constraints string to direct the compiler to store the eax register into the ‘Flags’ variable, instead of including the store instruction explicitly in the ‘Asm’ template string: with Interfaces; use Interfaces; with Ada.Text_IO; use Ada.Text_IO; with System.Machine_Code; use System.Machine_Code; procedure Get_Flags_2 is Flags : Unsigned_32; use ASCII; begin Asm ("pushfl" & LF & HT & -- push flags on stack "popl %%eax", -- save flags in eax Outputs => Unsigned_32'Asm_Output ("=a", Flags)); Put_Line ("Flags register:" & Flags'Img); end Get_Flags_2; The ‘"a"’ constraint tells the compiler that the ‘Flags’ variable will come from the eax register. Here is the resulting code: #APP pushfl popl %eax #NO_APP movl %eax,-40(%ebp) The compiler generated the store of eax into Flags after expanding the assembler code. Actually, there was no need to pop the flags into the eax register; more simply, we could just pop the flags directly into the program variable: with Interfaces; use Interfaces; with Ada.Text_IO; use Ada.Text_IO; with System.Machine_Code; use System.Machine_Code; procedure Get_Flags_3 is Flags : Unsigned_32; use ASCII; begin Asm ("pushfl" & LF & HT & -- push flags on stack "pop %0", -- save flags in Flags Outputs => Unsigned_32'Asm_Output ("=g", Flags)); Put_Line ("Flags register:" & Flags'Img); end Get_Flags_3;  File: gnat_ugn.info, Node: Input Variables in Inline Assembler, Next: Inlining Inline Assembler Code, Prev: Output Variables in Inline Assembler, Up: Inline Assembler 10.4 Input Variables in Inline Assembler ======================================== The example in this section illustrates how to specify the source operands for assembly language statements. The program simply increments its input value by 1: with Interfaces; use Interfaces; with Ada.Text_IO; use Ada.Text_IO; with System.Machine_Code; use System.Machine_Code; procedure Increment is function Incr (Value : Unsigned_32) return Unsigned_32 is Result : Unsigned_32; begin Asm ("incl %0", Outputs => Unsigned_32'Asm_Output ("=a", Result), Inputs => Unsigned_32'Asm_Input ("a", Value)); return Result; end Incr; Value : Unsigned_32; begin Value := 5; Put_Line ("Value before is" & Value'Img); Value := Incr (Value); Put_Line ("Value after is" & Value'Img); end Increment; The ‘Outputs’ parameter to ‘Asm’ specifies that the result will be in the eax register and that it is to be stored in the ‘Result’ variable. The ‘Inputs’ parameter looks much like the ‘Outputs’ parameter, but with an ‘Asm_Input’ attribute. The ‘"="’ constraint, indicating an output value, is not present. You can have multiple input variables, in the same way that you can have more than one output variable. The parameter count (%0, %1) etc, still starts at the first output statement, and continues with the input statements. Just as the ‘Outputs’ parameter causes the register to be stored into the target variable after execution of the assembler statements, so does the ‘Inputs’ parameter cause its variable to be loaded into the register before execution of the assembler statements. Thus the effect of the ‘Asm’ invocation is: * load the 32-bit value of ‘Value’ into eax * execute the ‘incl %eax’ instruction * store the contents of eax into the ‘Result’ variable The resulting assembler file (with ‘-O2’ optimization) contains: _increment__incr.1: subl $4,%esp movl 8(%esp),%eax #APP incl %eax #NO_APP movl %eax,%edx movl %ecx,(%esp) addl $4,%esp ret  File: gnat_ugn.info, Node: Inlining Inline Assembler Code, Next: Other Asm Functionality, Prev: Input Variables in Inline Assembler, Up: Inline Assembler 10.5 Inlining Inline Assembler Code =================================== For a short subprogram such as the ‘Incr’ function in the previous section, the overhead of the call and return (creating / deleting the stack frame) can be significant, compared to the amount of code in the subprogram body. A solution is to apply Ada’s ‘Inline’ pragma to the subprogram, which directs the compiler to expand invocations of the subprogram at the point(s) of call, instead of setting up a stack frame for out-of-line calls. Here is the resulting program: with Interfaces; use Interfaces; with Ada.Text_IO; use Ada.Text_IO; with System.Machine_Code; use System.Machine_Code; procedure Increment_2 is function Incr (Value : Unsigned_32) return Unsigned_32 is Result : Unsigned_32; begin Asm ("incl %0", Outputs => Unsigned_32'Asm_Output ("=a", Result), Inputs => Unsigned_32'Asm_Input ("a", Value)); return Result; end Incr; pragma Inline (Increment); Value : Unsigned_32; begin Value := 5; Put_Line ("Value before is" & Value'Img); Value := Increment (Value); Put_Line ("Value after is" & Value'Img); end Increment_2; Compile the program with both optimization (‘-O2’) and inlining (‘-gnatn’) enabled. The ‘Incr’ function is still compiled as usual, but at the point in ‘Increment’ where our function used to be called: pushl %edi call _increment__incr.1 the code for the function body directly appears: movl %esi,%eax #APP incl %eax #NO_APP movl %eax,%edx thus saving the overhead of stack frame setup and an out-of-line call.  File: gnat_ugn.info, Node: Other Asm Functionality, Prev: Inlining Inline Assembler Code, Up: Inline Assembler 10.6 Other ‘Asm’ Functionality ============================== This section describes two important parameters to the ‘Asm’ procedure: ‘Clobber’, which identifies register usage; and ‘Volatile’, which inhibits unwanted optimizations. * Menu: * The Clobber Parameter:: * The Volatile Parameter::  File: gnat_ugn.info, Node: The Clobber Parameter, Next: The Volatile Parameter, Up: Other Asm Functionality 10.6.1 The ‘Clobber’ Parameter ------------------------------ One of the dangers of intermixing assembly language and a compiled language such as Ada is that the compiler needs to be aware of which registers are being used by the assembly code. In some cases, such as the earlier examples, the constraint string is sufficient to indicate register usage (e.g., ‘"a"’ for the eax register). But more generally, the compiler needs an explicit identification of the registers that are used by the Inline Assembly statements. Using a register that the compiler doesn’t know about could be a side effect of an instruction (like ‘mull’ storing its result in both eax and edx). It can also arise from explicit register usage in your assembly code; for example: Asm ("movl %0, %%ebx" & LF & HT & "movl %%ebx, %1", Outputs => Unsigned_32'Asm_Output ("=g", Var_Out), Inputs => Unsigned_32'Asm_Input ("g", Var_In)); where the compiler (since it does not analyze the ‘Asm’ template string) does not know you are using the ebx register. In such cases you need to supply the ‘Clobber’ parameter to ‘Asm’, to identify the registers that will be used by your assembly code: Asm ("movl %0, %%ebx" & LF & HT & "movl %%ebx, %1", Outputs => Unsigned_32'Asm_Output ("=g", Var_Out), Inputs => Unsigned_32'Asm_Input ("g", Var_In), Clobber => "ebx"); The Clobber parameter is a static string expression specifying the register(s) you are using. Note that register names are 'not' prefixed by a percent sign. Also, if more than one register is used then their names are separated by commas; e.g., ‘"eax, ebx"’ The ‘Clobber’ parameter has several additional uses: * Use ‘register’ name ‘cc’ to indicate that flags might have changed * Use ‘register’ name ‘memory’ if you changed a memory location  File: gnat_ugn.info, Node: The Volatile Parameter, Prev: The Clobber Parameter, Up: Other Asm Functionality 10.6.2 The ‘Volatile’ Parameter ------------------------------- Compiler optimizations in the presence of Inline Assembler may sometimes have unwanted effects. For example, when an ‘Asm’ invocation with an input variable is inside a loop, the compiler might move the loading of the input variable outside the loop, regarding it as a one-time initialization. If this effect is not desired, you can disable such optimizations by setting the ‘Volatile’ parameter to ‘True’; for example: Asm ("movl %0, %%ebx" & LF & HT & "movl %%ebx, %1", Outputs => Unsigned_32'Asm_Output ("=g", Var_Out), Inputs => Unsigned_32'Asm_Input ("g", Var_In), Clobber => "ebx", Volatile => True); By default, ‘Volatile’ is set to ‘False’ unless there is no ‘Outputs’ parameter. Although setting ‘Volatile’ to ‘True’ prevents unwanted optimizations, it will also disable other optimizations that might be important for efficiency. In general, you should set ‘Volatile’ to ‘True’ only if the compiler’s optimizations have created problems.  File: gnat_ugn.info, Node: GNU Free Documentation License, Next: Index, Prev: Inline Assembler, Up: Top 11 GNU Free Documentation License ********************************* Version 1.3, 3 November 2008 Copyright 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc ‘https://fsf.org/’ Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 'Preamble' The purpose of this License is to make a manual, textbook, or other functional and useful document “free” in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others. This License is a kind of “copyleft”, which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software. We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference. '1. APPLICABILITY AND DEFINITIONS' This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The 'Document', below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as “'you'”. You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law. A “'Modified Version'” of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language. A “'Secondary Section'” is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document’s overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them. The “'Invariant Sections'” are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none. The “'Cover Texts'” are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words. A “'Transparent'” copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not “Transparent” is called 'Opaque'. Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only. The “'Title Page'” means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, “Title Page” means the text near the most prominent appearance of the work’s title, preceding the beginning of the body of the text. The “'publisher'” means any person or entity that distributes copies of the Document to the public. A section “'Entitled XYZ'” means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as “'Acknowledgements'”, “'Dedications'”, “'Endorsements'”, or “'History'”.) To “'Preserve the Title'” of such a section when you modify the Document means that it remains a section “Entitled XYZ” according to this definition. The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License. '2. VERBATIM COPYING' You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3. You may also lend copies, under the same conditions stated above, and you may publicly display copies. '3. COPYING IN QUANTITY' If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document’s license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects. If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages. If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public. It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document. '4. MODIFICATIONS' You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version: A. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission. B. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement. C. State on the Title page the name of the publisher of the Modified Version, as the publisher. D. Preserve all the copyright notices of the Document. E. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices. F. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below. G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document’s license notice. H. Include an unaltered copy of this License. I. Preserve the section Entitled “History”, Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled “History” in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence. J. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the “History” section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission. K. For any section Entitled “Acknowledgements” or “Dedications”, Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein. L. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles. M. Delete any section Entitled “Endorsements”. Such a section may not be included in the Modified Version. N. Do not retitle any existing section to be Entitled “Endorsements” or to conflict in title with any Invariant Section. O. Preserve any Warranty Disclaimers. If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version’s license notice. These titles must be distinct from any other section titles. You may add a section Entitled “Endorsements”, provided it contains nothing but endorsements of your Modified Version by various parties—for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard. You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one. The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version. '5. COMBINING DOCUMENTS' You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers. The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work. In the combination, you must combine any sections Entitled “History” in the various original documents, forming one section Entitled “History”; likewise combine any sections Entitled “Acknowledgements”, and any sections Entitled “Dedications”. You must delete all sections Entitled “Endorsements”. '6. COLLECTIONS OF DOCUMENTS' You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects. You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document. '7. AGGREGATION WITH INDEPENDENT WORKS' A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an “aggregate” if the copyright resulting from the compilation is not used to limit the legal rights of the compilation’s users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document. If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document’s Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate. '8. TRANSLATION' Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail. If a section in the Document is Entitled “Acknowledgements”, “Dedications”, or “History”, the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title. '9. TERMINATION' You may not copy, modify, sublicense, or distribute the Document except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, or distribute it is void, and will automatically terminate your rights under this License. However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, receipt of a copy of some or all of the same material does not give you any rights to use it. '10. FUTURE REVISIONS OF THIS LICENSE' The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See ‘https://www.gnu.org/copyleft/’. Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License “or any later version” applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation. If the Document specifies that a proxy can decide which future versions of this License can be used, that proxy’s public statement of acceptance of a version permanently authorizes you to choose that version for the Document. '11. RELICENSING' “Massive Multiauthor Collaboration Site” (or “MMC Site”) means any World Wide Web server that publishes copyrightable works and also provides prominent facilities for anybody to edit those works. A public wiki that anybody can edit is an example of such a server. A “Massive Multiauthor Collaboration” (or “MMC”) contained in the site means any set of copyrightable works thus published on the MMC site. “CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 license published by Creative Commons Corporation, a not-for-profit corporation with a principal place of business in San Francisco, California, as well as future copyleft versions of that license published by that same organization. “Incorporate” means to publish or republish a Document, in whole or in part, as part of another Document. An MMC is “eligible for relicensing” if it is licensed under this License, and if all works that were first published under this License somewhere other than this MMC, and subsequently incorporated in whole or in part into the MMC, (1) had no cover texts or invariant sections, and (2) were thus incorporated prior to November 1, 2008. The operator of an MMC Site may republish an MMC contained in the site under CC-BY-SA on the same site at any time before August 1, 2009, provided the MMC is eligible for relicensing. 'ADDENDUM: How to use this License for your documents' To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page: Copyright © YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled “GNU Free Documentation License”. If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the “with … Texts.” line with this: with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation. If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.  File: gnat_ugn.info, Node: Index, Prev: GNU Free Documentation License, Up: Top Index ***** [index] * Menu: * __gnat_malloc: Switches for gnatbind. (line 137) * -a (gnatbind): Switches for gnatbind. (line 19) * -A (gnatbind): Switches for gnatbind. (line 34) * -a (gnatdll): Using gnatdll. (line 23) * -a (gnatls): Switches for gnatls. (line 18) * -a (gnatmake): Switches for gnatmake. (line 116) * -A (gnatmake): Switches for gnatmake. (line 464) * -aI (gnatbind): Switches for gnatbind. (line 30) * -aI (gnatbind) <1>: Search Paths for gnatbind. (line 38) * -aI (gnatls): Switches for gnatls. (line 50) * -aI (gnatmake): Switches for gnatmake. (line 439) * -aL (gnatmake): Switches for gnatmake. (line 445) * -aO (gnatbind): Switches for gnatbind. (line 26) * -aO (gnatbind) <1>: Search Paths for gnatbind. (line 38) * -aO (gnatclean): Switches for gnatclean. (line 97) * -aO (gnatls): Switches for gnatls. (line 50) * -aO (gnatmake): Switches for gnatmake. (line 458) * -aP (gnatls): Switches for gnatls. (line 55) * -as (dlltool): Using gnatdll. (line 227) * -b (gcc): Alphabetical List of All Switches. (line 6) * -B (gcc): Alphabetical List of All Switches. (line 12) * -b (gnatbind): Switches for gnatbind. (line 38) * -b (gnatbind) <1>: Binder Error Message Control. (line 17) * -b (gnatdll): Using gnatdll. (line 30) * -B (gnatlink): Switches for gnatlink. (line 61) * -b (gnatmake): Switches for gnatmake. (line 136) * -b (gnatprep): Switches for gnatprep. (line 16) * -bargs (gnatdll): Using gnatdll. (line 35) * -bargs (gnatmake): Mode Switches for gnatmake. (line 19) * -base-file (dlltool): Using gnatdll. (line 189) * -C (gcc): Switches. (line 21) * -c (gcc): Alphabetical List of All Switches. (line 21) * -c (gnatbind): Switches for gnatbind. (line 42) * -c (gnatbind) <1>: Output Control. (line 9) * -c (gnatchop): Switches for gnatchop. (line 18) * -c (gnatclean): Switches for gnatclean. (line 30) * -c (gnatmake): Switches for gnatmake. (line 146) * -C (gnatmake): Switches for gnatmake. (line 155) * -c (gnatname): Switches for gnatname. (line 33) * -c (gnatprep): Switches for gnatprep. (line 22) * -C (gnatprep): Switches for gnatprep. (line 29) * -C= (gnatmake): Switches for gnatmake. (line 170) * -cargs (gnatmake): Mode Switches for gnatmake. (line 13) * -create-missing-dirs (gnatmake): Switches for gnatmake. (line 72) * -D (gnatbind): Switches for gnatbind. (line 58) * -D (gnatclean): Switches for gnatclean. (line 37) * -d (gnatdll): Using gnatdll. (line 39) * -d (gnatls): Switches for gnatls. (line 23) * -d (gnatmake): Switches for gnatmake. (line 179) * -D (gnatmake): Switches for gnatmake. (line 190) * -d (gnatname): Switches for gnatname. (line 42) * -D (gnatname): Switches for gnatname. (line 59) * -D (gnatprep): Switches for gnatprep. (line 40) * -def (dlltool): Using gnatdll. (line 194) * -demangle (gprof): Running gprof. (line 24) * -dllname (dlltool): Using gnatdll. (line 198) * -dnn[k|m] (gnatbind): Switches for gnatbind. (line 46) * -e (gnatbind): Switches for gnatbind. (line 83) * -E (gnatbind): Switches for gnatbind. (line 102) * -e (gnatbind) <1>: Output Control. (line 15) * -e (gnatdll): Using gnatdll. (line 50) * -e (gprof): Running gprof. (line 34) * -E (gprof): Running gprof. (line 43) * -Ea (gnatbind): Switches for gnatbind. (line 87) * -eI (gnatmake): Switches for gnatmake. (line 198) * -eL (gnatmake): Switches for gnatmake. (line 205) * -Es (gnatbind): Switches for gnatbind. (line 97) * -eS (gnatmake): Switches for gnatmake. (line 221) * -f (gnatbind): Switches for gnatbind. (line 106) * -F (gnatbind): Switches for gnatbind. (line 111) * -f (gnatbind) <1>: Elaboration Control. (line 10) * -F (gnatclean): Switches for gnatclean. (line 42) * -f (gnatlink): Switches for gnatlink. (line 18) * -f (gnatmake): Switches for gnatmake. (line 226) * -F (gnatmake): Switches for gnatmake. (line 233) * -f (gnatname): Switches for gnatname. (line 72) * -f (gprof): Running gprof. (line 51) * -F (gprof): Running gprof. (line 58) * -fada-spec-parent (gcc): Switches. (line 16) * -fcallgraph-info (gcc): Alphabetical List of All Switches. (line 31) * -fdata-sections (gcc): Compilation options. (line 9) * -fdiagnostics-format (gcc): Alphabetical List of All Switches. (line 42) * -fdump-ada-spec (gcc): Switches. (line 6) * -fdump-ada-spec-slim (gcc): Switches. (line 11) * -fdump-scos (gcc): Alphabetical List of All Switches. (line 49) * -ffunction-sections (gcc): Compilation options. (line 9) * -fgnat-encodings (gcc): Alphabetical List of All Switches. (line 56) * -fgnat-encodings (gcc) <1>: Debugging Control. (line 250) * -files (gnatls): Switches for gnatls. (line 43) * -flto (gcc): Alphabetical List of All Switches. (line 61) * -fno-inline (gcc): Alphabetical List of All Switches. (line 82) * -fno-inline (gcc) <1>: Inlining of Subprograms. (line 72) * -fno-inline-functions (gcc): Alphabetical List of All Switches. (line 89) * -fno-inline-functions (gcc) <1>: Inlining of Subprograms. (line 78) * -fno-inline-functions-called-once (gcc): Alphabetical List of All Switches. (line 99) * -fno-inline-functions-called-once (gcc) <1>: Inlining of Subprograms. (line 84) * -fno-inline-small-functions (gcc): Alphabetical List of All Switches. (line 94) * -fno-inline-small-functions (gcc) <1>: Inlining of Subprograms. (line 81) * -fno-ivopts (gcc): Alphabetical List of All Switches. (line 104) * -fno-strict-aliasing (gcc): Alphabetical List of All Switches. (line 113) * -fno-strict-overflow (gcc): Alphabetical List of All Switches. (line 119) * -fstack-check (gcc): Alphabetical List of All Switches. (line 129) * -fstack-check (gcc) <1>: Run-Time Checks. (line 137) * -fstack-check (gcc) <2>: Stack Overflow Checking. (line 6) * -fstack-usage: Static Stack Usage Analysis. (line 6) * -fstack-usage (gcc): Alphabetical List of All Switches. (line 134) * -fuse-ld=name: Linker Switches. (line 8) * -fverbose-asm (gcc): Alphabetical List of All Switches. (line 917) * -g (gcc): Alphabetical List of All Switches. (line 140) * -g (gcc) <1>: Debugging Optimized Code. (line 14) * -g (gnatdll): Using gnatdll. (line 54) * -g (gnatlink): Switches for gnatlink. (line 27) * -g (gnatmake): Switches for gnatmake. (line 240) * -GCC= (gnatchop): Switches for gnatchop. (line 98) * -GCC=compiler_name (gnatlink): Switches for gnatlink. (line 80) * -GCC=compiler_name (gnatmake): Switches for gnatmake. (line 24) * -gnat-p (gcc): Alphabetical List of All Switches. (line 758) * -gnat-p (gcc) <1>: Run-Time Checks. (line 60) * -gnat05 (gcc): Alphabetical List of All Switches. (line 147) * -gnat05 (gcc) <1>: Compiling Different Versions of Ada. (line 49) * -gnat12 (gcc): Alphabetical List of All Switches. (line 151) * -gnat12 (gcc) <1>: Compiling Different Versions of Ada. (line 58) * -gnat2005 (gcc): Alphabetical List of All Switches. (line 155) * -gnat2005 (gcc) <1>: Compiling Different Versions of Ada. (line 49) * -gnat2012 (gcc): Alphabetical List of All Switches. (line 159) * -gnat2012 (gcc) <1>: Compiling Different Versions of Ada. (line 58) * -gnat2022 (gcc): Alphabetical List of All Switches. (line 163) * -gnat2022 (gcc) <1>: Compiling Different Versions of Ada. (line 67) * -gnat83 (gcc): Alphabetical List of All Switches. (line 155) * -gnat83 (gcc) <1>: Compiling Different Versions of Ada. (line 11) * -gnat95 (gcc): Alphabetical List of All Switches. (line 171) * -gnat95 (gcc) <1>: Compiling Different Versions of Ada. (line 35) * -gnata (gcc): Alphabetical List of All Switches. (line 183) * -gnatA (gcc): Alphabetical List of All Switches. (line 200) * -gnata (gcc) <1>: Debugging and Assertion Control. (line 6) * -gnata switch: Debugging - A Special Case. (line 45) * -gnatb (gcc): Alphabetical List of All Switches. (line 205) * -gnatB (gcc): Alphabetical List of All Switches. (line 209) * -gnatb (gcc) <1>: Output and Error Message Control. (line 101) * -GNATBIND=binder_name (gnatmake): Switches for gnatmake. (line 40) * -gnatc (gcc): Alphabetical List of All Switches. (line 214) * -gnatC (gcc): Alphabetical List of All Switches. (line 226) * -gnatc (gcc) <1>: Using gcc for Semantic Checking. (line 6) * -gnatd (gcc): Alphabetical List of All Switches. (line 235) * -gnatd (gcc) <1>: Debugging Control. (line 6) * -gnatD (gcc): Debugging Control. (line 142) * -gnatD[nn] (gcc): Alphabetical List of All Switches. (line 245) * -gnatdc switch: GNAT Abnormal Termination or Failure to Terminate. (line 33) * -gnatE (gcc): Alphabetical List of All Switches. (line 564) * -gnatE (gcc) <1>: Run-Time Checks. (line 129) * -gnatE (gnat): Elaboration-related Compiler Switches. (line 9) * -gnateA (gcc): Alphabetical List of All Switches. (line 253) * -gnateb (gcc): Alphabetical List of All Switches. (line 287) * -gnatec (gcc): Alphabetical List of All Switches. (line 294) * -gnateC (gcc): Alphabetical List of All Switches. (line 299) * -gnateD (gcc): Integrated Preprocessing. (line 162) * -gnated (gcc): Alphabetical List of All Switches. (line 305) * -gnateD (gcc) <1>: Alphabetical List of All Switches. (line 309) * -gnateE (gcc): Alphabetical List of All Switches. (line 314) * -gnatef (gcc): Alphabetical List of All Switches. (line 323) * -gnateF (gcc): Alphabetical List of All Switches. (line 328) * -gnateg (gcc): Alphabetical List of All Switches. (line 334) * -gnateG (gcc): Alphabetical List of All Switches. (line 341) * -gnateH (gcc): Alphabetical List of All Switches. (line 345) * -gnatei (gcc): Alphabetical List of All Switches. (line 351) * -gnateI (gcc): Alphabetical List of All Switches. (line 358) * -gnatel (gcc): Alphabetical List of All Switches. (line 364) * -gnatel (gcc) <1>: Alphabetical List of All Switches. (line 375) * -gnatel (gnat): Elaboration-related Compiler Switches. (line 15) * -gnatem (gcc): Alphabetical List of All Switches. (line 380) * -gnatem (gcc) <1>: Units to Sources Mapping Files. (line 6) * -gnatep (gcc): Integrated Preprocessing. (line 46) * -gnatep (gcc) <1>: Alphabetical List of All Switches. (line 385) * -gnateP (gcc): Alphabetical List of All Switches. (line 390) * -gnateS (gcc): Alphabetical List of All Switches. (line 400) * -gnateT (gcc): Alphabetical List of All Switches. (line 409) * -gnatet=file (gcc): Alphabetical List of All Switches. (line 404) * -gnateu (gcc): Alphabetical List of All Switches. (line 543) * -gnateV (gcc): Alphabetical List of All Switches. (line 551) * -gnateY (gcc): Alphabetical List of All Switches. (line 557) * -gnatf (gcc): Alphabetical List of All Switches. (line 569) * -gnatF (gcc): Alphabetical List of All Switches. (line 574) * -gnatf (gcc) <1>: Output and Error Message Control. (line 129) * -gnatg (gcc): Alphabetical List of All Switches. (line 578) * -gnatG (gcc): Debugging Control. (line 15) * -gnatG[nn] (gcc): Alphabetical List of All Switches. (line 587) * -gnath (gcc): Alphabetical List of All Switches. (line 591) * -gnatH (gcc): Alphabetical List of All Switches. (line 595) * -gnatH (gnat): Elaboration-related Compiler Switches. (line 54) * -gnati (gcc): Alphabetical List of All Switches. (line 602) * -gnatI (gcc): Alphabetical List of All Switches. (line 608) * -gnati (gcc) <1>: Character Set Control. (line 6) * -gnatJ (gcc): Alphabetical List of All Switches. (line 627) * -gnatJ (gnat): Elaboration-related Compiler Switches. (line 61) * -gnatjnn (gcc): Alphabetical List of All Switches. (line 623) * -gnatjnn (gcc) <1>: Output and Error Message Control. (line 159) * -gnatk (gcc): Alphabetical List of All Switches. (line 658) * -gnatk (gcc) <1>: File Naming Control. (line 6) * -gnatl (gcc): Alphabetical List of All Switches. (line 662) * -gnatL (gcc): Alphabetical List of All Switches. (line 666) * -gnatl (gcc) <1>: Output and Error Message Control. (line 36) * -gnatL (gcc) <1>: Debugging Control. (line 44) * -gnatL (gcc) <2>: Debugging Control. (line 163) * -gnatl=fname (gcc): Output and Error Message Control. (line 84) * -GNATLINK=linker_name (gnatmake): Switches for gnatmake. (line 51) * -gnatm (gcc): Alphabetical List of All Switches. (line 672) * -gnatm (gcc) <1>: Output and Error Message Control. (line 108) * -gnatn (gcc): Alphabetical List of All Switches. (line 683) * -gnatN (gcc): Alphabetical List of All Switches. (line 692) * -gnatn (gcc) <1>: Subprogram Inlining Control. (line 6) * -gnatN (gcc) <1>: Subprogram Inlining Control. (line 35) * -gnatn switch: Source Dependencies. (line 27) * -gnatN switch: Source Dependencies. (line 34) * -gnato (gcc): Controlling Run-Time Checks. (line 11) * -gnato? (gcc): Specifying the Desired Mode. (line 52) * -gnato?? (gcc): Alphabetical List of All Switches. (line 710) * -gnato?? (gcc) <1>: Run-Time Checks. (line 64) * -gnato?? (gcc) <2>: Specifying the Desired Mode. (line 52) * -gnato0 (gcc): Alphabetical List of All Switches. (line 703) * -gnatp (gcc): Alphabetical List of All Switches. (line 752) * -gnatp (gcc) <1>: Run-Time Checks. (line 12) * -gnatp (gcc) <2>: Controlling Run-Time Checks. (line 11) * -gnatq (gcc): Alphabetical List of All Switches. (line 762) * -gnatQ (gcc): Alphabetical List of All Switches. (line 766) * -gnatq (gcc) <1>: Output and Error Message Control. (line 174) * -gnatQ (gcc) <1>: Output and Error Message Control. (line 186) * -gnatr (gcc): Alphabetical List of All Switches. (line 772) * -gnatR (gcc): Alphabetical List of All Switches. (line 776) * -gnatr (gcc) <1>: Debugging Control. (line 172) * -gnatR (gcc) <1>: Debugging Control. (line 182) * -gnats (gcc): Alphabetical List of All Switches. (line 783) * -gnatS (gcc): Alphabetical List of All Switches. (line 787) * -gnats (gcc) <1>: Using gcc for Syntax Checking. (line 6) * -gnatS (gcc) <1>: Debugging Control. (line 232) * -gnatT (gcc): Alphabetical List of All Switches. (line 791) * -gnatu (gcc): Alphabetical List of All Switches. (line 795) * -gnatU (gcc): Alphabetical List of All Switches. (line 799) * -gnatU (gcc) <1>: Output and Error Message Control. (line 94) * -gnatu (gcc) <1>: Auxiliary Output Control. (line 6) * -gnatv (gcc): Alphabetical List of All Switches. (line 803) * -gnatV (gcc): Alphabetical List of All Switches. (line 807) * -gnatv (gcc) <1>: Output and Error Message Control. (line 19) * -gnatVa (gcc): Validity Checking. (line 50) * -gnatVc (gcc): Validity Checking. (line 57) * -gnatVd (gcc): Validity Checking. (line 64) * -gnatVe (gcc): Validity Checking. (line 84) * -gnatVf (gcc): Validity Checking. (line 94) * -gnatVi (gcc): Validity Checking. (line 115) * -gnatVm (gcc): Validity Checking. (line 122) * -gnatVn (gcc): Validity Checking. (line 134) * -gnatVo (gcc): Validity Checking. (line 144) * -gnatVp (gcc): Validity Checking. (line 157) * -gnatVr (gcc): Validity Checking. (line 173) * -gnatVs (gcc): Validity Checking. (line 180) * -gnatVt (gcc): Validity Checking. (line 189) * -gnatw (gcc): Alphabetical List of All Switches. (line 811) * -gnatW (gcc): Alphabetical List of All Switches. (line 817) * -gnatW (gcc) <1>: Character Set Control. (line 51) * -gnatw_a: Warning Message Control. (line 217) * -gnatw_A: Warning Message Control. (line 226) * -gnatw_c (gcc): Warning Message Control. (line 320) * -gnatw_C (gcc): Warning Message Control. (line 328) * -gnatw_p (gcc): Warning Message Control. (line 794) * -gnatw_P (gcc): Warning Message Control. (line 805) * -gnatw_q (gcc): Warning Message Control. (line 880) * -gnatw_Q (gcc): Warning Message Control. (line 894) * -gnatw_r (gcc): Warning Message Control. (line 950) * -gnatw_R (gcc): Warning Message Control. (line 959) * -gnatw_s (gcc): Warning Message Control. (line 998) * -gnatw_S (gcc): Warning Message Control. (line 1006) * -gnatw.a (gcc): Warning Message Control. (line 201) * -gnatw.A (gcc): Warning Message Control. (line 210) * -gnatw.b (gcc): Warning Message Control. (line 253) * -gnatw.c (gcc): Warning Message Control. (line 304) * -gnatw.C (gcc): Warning Message Control. (line 313) * -gnatw.d (gcc): Warning Message Control. (line 355) * -gnatw.d (gcc) <1>: Warning Message Control. (line 386) * -gnatw.e (gcc): Warning Message Control. (line 406) * -gnatw.f (gnat): Elaboration-related Compiler Switches. (line 69) * -gnatw.g (gcc): Warning Message Control. (line 460) * -gnatw.h (gcc): Warning Message Control. (line 485) * -gnatw.H (gcc): Warning Message Control. (line 499) * -gnatw.i (gcc): Warning Message Control. (line 526) * -gnatw.I (gcc): Warning Message Control. (line 535) * -gnatw.j (gcc): Warning Message Control. (line 572) * -gnatw.J (gcc): Warning Message Control. (line 579) * -gnatw.k (gcc): Warning Message Control. (line 601) * -gnatw.l (gcc): Warning Message Control. (line 636) * -gnatw.L (gcc): Warning Message Control. (line 645) * -gnatw.m (gcc): Warning Message Control. (line 669) * -gnatw.M (gcc): Warning Message Control. (line 684) * -gnatw.n (gcc): Warning Message Control. (line 701) * -gnatw.N (gcc): Warning Message Control. (line 709) * -gnatw.o (gcc): Warning Message Control. (line 733) * -gnatw.O (gcc): Warning Message Control. (line 747) * -gnatw.p (gcc): Warning Message Control. (line 775) * -gnatw.P (gcc): Warning Message Control. (line 787) * -gnatw.q (gcc): Warning Message Control. (line 832) * -gnatw.Q (gcc): Warning Message Control. (line 873) * -gnatw.r (gcc): Warning Message Control. (line 935) * -gnatw.R (gcc): Warning Message Control. (line 944) * -gnatw.s (gcc): Warning Message Control. (line 979) * -gnatw.S (gcc): Warning Message Control. (line 990) * -gnatw.t (gcc): Warning Message Control. (line 1031) * -gnatw.T (gcc): Warning Message Control. (line 1049) * -gnatw.u (gcc): Warning Message Control. (line 1082) * -gnatw.U (gcc): Warning Message Control. (line 1097) * -gnatw.v (gcc): Warning Message Control. (line 1125) * -gnatw.V (gcc): Warning Message Control. (line 1137) * -gnatw.w (gcc): Warning Message Control. (line 1169) * -gnatw.W (gcc): Warning Message Control. (line 1182) * -gnatw.x (gcc): Warning Message Control. (line 1209) * -gnatw.y (gcc): Warning Message Control. (line 1247) * -gnatw.Y (gcc): Warning Message Control. (line 1259) * -gnatw.z (gcc): Warning Message Control. (line 1283) * -gnatw.Z (gcc): Warning Message Control. (line 1293) * -gnatwa (gcc): Warning Message Control. (line 134) * -gnatwA (gcc): Warning Message Control. (line 185) * -gnatwb (gcc): Warning Message Control. (line 233) * -gnatwB (gcc): Warning Message Control. (line 246) * -gnatwB (gcc) <1>: Warning Message Control. (line 263) * -gnatwc (gcc): Warning Message Control. (line 270) * -gnatwC (gcc): Warning Message Control. (line 297) * -gnatwd (gcc): Warning Message Control. (line 336) * -gnatwD (gcc): Warning Message Control. (line 348) * -gnatwe (gcc): Warning Message Control. (line 394) * -gnatwE (gcc): Warning Message Control. (line 419) * -gnatwf (gcc): Warning Message Control. (line 426) * -gnatwF (gcc): Warning Message Control. (line 435) * -gnatwg (gcc): Warning Message Control. (line 444) * -gnatwG (gcc): Warning Message Control. (line 454) * -gnatwh (gcc): Warning Message Control. (line 469) * -gnatwH (gcc): Warning Message Control. (line 479) * -gnatwi (gcc): Warning Message Control. (line 507) * -gnatwI (gcc): Warning Message Control. (line 519) * -gnatwj (gcc): Warning Message Control. (line 541) * -gnatwJ (gcc): Warning Message Control. (line 566) * -gnatwk (gcc): Warning Message Control. (line 586) * -gnatwK (gcc): Warning Message Control. (line 594) * -gnatwK (gcc) <1>: Warning Message Control. (line 612) * -gnatwl (gcc): Warning Message Control. (line 619) * -gnatwL (gcc): Warning Message Control. (line 630) * -gnatwl (gnat): Elaboration-related Compiler Switches. (line 99) * -gnatwm (gcc): Warning Message Control. (line 651) * -gnatwM (gcc): Warning Message Control. (line 662) * -gnatwn (gcc): Warning Message Control. (line 690) * -gnatwo (gcc): Warning Message Control. (line 716) * -gnatwO (gcc): Warning Message Control. (line 725) * -gnatwp (gcc): Warning Message Control. (line 755) * -gnatwP (gcc): Warning Message Control. (line 767) * -gnatwq (gcc): Warning Message Control. (line 811) * -gnatwQ (gcc): Warning Message Control. (line 825) * -gnatwr (gcc): Warning Message Control. (line 898) * -gnatwR (gcc): Warning Message Control. (line 929) * -gnatws (gcc): Warning Message Control. (line 963) * -gnatwt (gcc): Warning Message Control. (line 1014) * -gnatwT (gcc): Warning Message Control. (line 1024) * -gnatwu (gcc): Warning Message Control. (line 1055) * -gnatwU (gcc): Warning Message Control. (line 1074) * -gnatwv (gcc): Warning Message Control. (line 1105) * -gnatwV (gcc): Warning Message Control. (line 1118) * -gnatww (gcc): Warning Message Control. (line 1145) * -gnatwW (gcc): Warning Message Control. (line 1155) * -gnatwx (gcc): Warning Message Control. (line 1189) * -gnatwX (gcc): Warning Message Control. (line 1200) * -gnatwy (gcc): Warning Message Control. (line 1227) * -gnatwY (gcc): Warning Message Control. (line 1240) * -gnatwz (gcc): Warning Message Control. (line 1266) * -gnatwZ (gcc): Warning Message Control. (line 1275) * -gnatx (gcc): Alphabetical List of All Switches. (line 821) * -gnatX (gcc): Alphabetical List of All Switches. (line 825) * -gnatX (gcc) <1>: Compiling Different Versions of Ada. (line 80) * -gnatx (gcc) <1>: Debugging Control. (line 242) * -gnatX0 (gcc): Alphabetical List of All Switches. (line 829) * -gnatX0 (gcc) <1>: Compiling Different Versions of Ada. (line 72) * -gnaty (gcc): Alphabetical List of All Switches. (line 833) * -gnaty (gcc) <1>: Style Checking. (line 6) * -gnaty- (gcc): Style Checking. (line 454) * -gnaty[0-9] (gcc): Style Checking. (line 25) * -gnaty+ (gcc): Style Checking. (line 466) * -gnatya (gcc): Style Checking. (line 51) * -gnatyA (gcc): Style Checking. (line 60) * -gnatyb (gcc): Style Checking. (line 68) * -gnatyB (gcc): Style Checking. (line 77) * -gnatyc (gcc): Style Checking. (line 86) * -gnatyC (gcc): Style Checking. (line 129) * -gnatyd (gcc): Style Checking. (line 136) * -gnatyD (gcc): Style Checking. (line 143) * -gnatye (gcc): Style Checking. (line 151) * -gnatyf (gcc): Style Checking. (line 158) * -gnatyg (gcc): Style Checking. (line 165) * -gnatyh (gcc): Style Checking. (line 175) * -gnatyi (gcc): Style Checking. (line 183) * -gnatyI (gcc): Style Checking. (line 191) * -gnatyk (gcc): Style Checking. (line 198) * -gnatyl (gcc): Style Checking. (line 207) * -gnatyLnnn (gcc): Style Checking. (line 272) * -gnatym (gcc): Style Checking. (line 280) * -gnatyMnnn (gcc): Style Checking. (line 293) * -gnatyn (gcc): Style Checking. (line 303) * -gnatyN (gcc): Style Checking. (line 311) * -gnatyo (gcc): Style Checking. (line 317) * -gnatyO (gcc): Style Checking. (line 327) * -gnatyp (gcc): Style Checking. (line 339) * -gnatyr (gcc): Style Checking. (line 348) * -gnatys (gcc): Style Checking. (line 357) * -gnatyS (gcc): Style Checking. (line 367) * -gnatyt (gcc): Style Checking. (line 376) * -gnatyu (gcc): Style Checking. (line 422) * -gnatyx (gcc): Style Checking. (line 430) * -gnatyy (gcc): Style Checking. (line 438) * -gnatyz (gcc): Style Checking. (line 447) * -gnatz (gcc): Alphabetical List of All Switches. (line 837) * -h (gnatbind): Switches for gnatbind. (line 122) * -H (gnatbind): Switches for gnatbind. (line 126) * -h (gnatbind) <1>: Output Control. (line 22) * -h (gnatclean): Switches for gnatclean. (line 49) * -h (gnatdll): Using gnatdll. (line 62) * -h (gnatls): Switches for gnatls. (line 27) * -h (gnatname): Switches for gnatname. (line 84) * -H32 (gnatbind): Switches for gnatbind. (line 131) * -H64 (gnatbind): Switches for gnatbind. (line 137) * -help (dlltool): Using gnatdll. (line 209) * -help (gnatbind): Switches for gnatbind. (line 14) * -help (gnatchop): Switches for gnatchop. (line 13) * -help (gnatclean): Switches for gnatclean. (line 13) * -help (gnatlink): Switches for gnatlink. (line 13) * -help (gnatls): Switches for gnatls. (line 13) * -help (gnatmake): Switches for gnatmake. (line 13) * -help (gnatname): Switches for gnatname. (line 15) * -help (gnatprep): Switches for gnatprep. (line 11) * -I (gcc): Alphabetical List of All Switches. (line 842) * -I (gnatbind): Switches for gnatbind. (line 143) * -I (gnatbind) <1>: Search Paths for gnatbind. (line 38) * -I (gnatclean): Switches for gnatclean. (line 101) * -I (gnatdll): Using gnatdll. (line 66) * -I (gnatls): Switches for gnatls. (line 50) * -i (gnatmake): Switches for gnatmake. (line 245) * -I (gnatmake): Switches for gnatmake. (line 468) * -I- (gcc): Alphabetical List of All Switches. (line 848) * -I- (gnatbind): Switches for gnatbind. (line 147) * -I- (gnatclean): Switches for gnatclean. (line 105) * -I- (gnatls): Switches for gnatls. (line 50) * -I- (gnatmake): Switches for gnatmake. (line 472) * -j (gnatmake): Switches for gnatmake. (line 264) * -k (dlltool): Using gnatdll. (line 204) * -k (gnatbind): Switches for gnatbind. (line 153) * -K (gnatbind): Switches for gnatbind. (line 161) * -K (gnatbind) <1>: Output Control. (line 26) * -k (gnatchop): Switches for gnatchop. (line 36) * -k (gnatdll): Using gnatdll. (line 72) * -k (gnatmake): Switches for gnatmake. (line 275) * -l (gnatbind): Switches for gnatbind. (line 165) * -L (gnatbind): Switches for gnatbind. (line 169) * -l (gnatbind) <1>: Output Control. (line 32) * -l (gnatdll): Using gnatdll. (line 81) * -l (gnatmake): Switches for gnatmake. (line 287) * -L (gnatmake): Switches for gnatmake. (line 478) * -largs (gnatdll): Using gnatdll. (line 99) * -largs (gnatmake): Mode Switches for gnatmake. (line 25) * -LINK= (gnatlink): Switches for gnatlink. (line 101) * -M (gnatbind): Switches for gnatbind. (line 176) * -m (gnatbind): Switches for gnatbind. (line 181) * -m (gnatbind) <1>: Binder Error Message Control. (line 22) * -M (gnatbind) <1>: Binder Error Message Control. (line 28) * -M (gnatlink): Switches for gnatlink. (line 70) * -m (gnatmake): Switches for gnatmake. (line 298) * -M (gnatmake): Switches for gnatmake. (line 313) * -M= (gnatlink): Switches for gnatlink. (line 75) * -margs (gnatmake): Mode Switches for gnatmake. (line 31) * -minimal (gnatbind): Switches for gnatbind. (line 191) * -mwindows: CONSOLE and WINDOWS subsystems. (line 6) * -n (gnatbind): Switches for gnatbind. (line 206) * -n (gnatbind) <1>: Binding with Non-Ada Main Programs. (line 14) * -n (gnatbind) <2>: Binding with Non-Ada Main Programs. (line 45) * -n (gnatclean): Switches for gnatclean. (line 53) * -n (gnatdll): Using gnatdll. (line 87) * -n (gnatlink): Switches for gnatlink. (line 35) * -n (gnatmake): Switches for gnatmake. (line 329) * -nostdinc (gcc): Alphabetical List of All Switches. (line 862) * -nostdinc (gnatbind): Switches for gnatbind. (line 210) * -nostdinc (gnatmake): Switches for gnatmake. (line 485) * -nostdlib (gcc): Alphabetical List of All Switches. (line 867) * -nostdlib (gnatbind): Switches for gnatbind. (line 214) * -nostdlib (gnatmake): Switches for gnatmake. (line 489) * -o (gcc): Alphabetical List of All Switches. (line 855) * -O (gcc): Alphabetical List of All Switches. (line 872) * -O (gcc) <1>: Optimization Levels. (line 6) * -o (gnatbind): Switches for gnatbind. (line 224) * -O (gnatbind): Switches for gnatbind. (line 230) * -O (gnatbind) <1>: Output Control. (line 37) * -o (gnatbind) <1>: Output Control. (line 47) * -o (gnatbind) <2>: Binding with Non-Ada Main Programs. (line 56) * -o (gnatlink): Switches for gnatlink. (line 54) * -o (gnatls): Switches for gnatls. (line 31) * -o (gnatmake): Switches for gnatmake. (line 337) * -output-exp (dlltool): Using gnatdll. (line 213) * -output-lib (dlltool): Using gnatdll. (line 219) * -p (gnatbind): Switches for gnatbind. (line 234) * -P (gnatbind): Switches for gnatbind. (line 238) * -p (gnatbind) <1>: Elaboration Control. (line 49) * -p (gnatchop): Switches for gnatchop. (line 47) * -P (gnatclean): Switches for gnatclean. (line 59) * -P (gnatmake): Switches for gnatmake. (line 18) * -p (gnatmake): Switches for gnatmake. (line 347) * -P (gnatname): Switches for gnatname. (line 89) * -pass-exit-codes (gcc): Alphabetical List of All Switches. (line 899) * -pass-exit-codes (gcc) <1>: Auxiliary Output Control. (line 12) * -pg (gcc): Compilation for profiling. (line 6) * -pg (gnatlink): Compilation for profiling. (line 6) * -Q (gnatbind): Switches for gnatbind. (line 242) * -q (gnatchop): Switches for gnatchop. (line 55) * -q (gnatclean): Switches for gnatclean. (line 67) * -q (gnatdll): Using gnatdll. (line 91) * -q (gnatmake): Switches for gnatmake. (line 351) * -R (gnatbind): Switches for gnatbind. (line 258) * -r (gnatbind): Output Control. (line 55) * -r (gnatchop): Switches for gnatchop. (line 61) * -r (gnatclean): Switches for gnatclean. (line 73) * -r (gnatprep): Switches for gnatprep. (line 46) * -Ra (gnatbind): Switches for gnatbind. (line 263) * -RTS (gcc): Alphabetical List of All Switches. (line 904) * -RTS (gnatbind): Switches for gnatbind. (line 218) * -RTS (gnatls): Switches for gnatls. (line 59) * -RTS (gnatmake): Switches for gnatmake. (line 493) * -RTS option: Specifying a Run-Time Library. (line 53) * -RTS=sjlj (gnatmake): Exception Handling Control. (line 29) * -RTS=zcx (gnatmake): Exception Handling Control. (line 40) * -S (gcc): Alphabetical List of All Switches. (line 910) * -s (gnatbind): Switches for gnatbind. (line 267) * -S (gnatbind): Switches for gnatbind. (line 271) * -s (gnatbind) <1>: Consistency-Checking Modes. (line 10) * -s (gnatls): Switches for gnatls. (line 35) * -s (gnatmake): Switches for gnatmake. (line 356) * -s (gnatprep): Switches for gnatprep. (line 61) * -shared (gnatbind): Switches for gnatbind. (line 327) * -static (gnatbind): Switches for gnatbind. (line 323) * -t (gnatbind): Switches for gnatbind. (line 331) * -T (gnatbind): Switches for gnatbind. (line 335) * -t (gnatbind) <1>: Binder Error Message Control. (line 43) * -T (gnatprep): Switches for gnatprep. (line 66) * -T0 option: Choosing the Scheduling Policy. (line 12) * -u (gnatbind): Switches for gnatbind. (line 350) * -u (gnatls): Switches for gnatls. (line 39) * -u (gnatmake): Switches for gnatmake. (line 367) * -U (gnatmake): Switches for gnatmake. (line 374) * -u (gnatprep): Switches for gnatprep. (line 72) * -v -v (gnatlink): Switches for gnatlink. (line 48) * -v -v (gnatname): Switches for gnatname. (line 109) * -v (dlltool): Using gnatdll. (line 223) * -v (gcc): Alphabetical List of All Switches. (line 923) * -V (gcc): Alphabetical List of All Switches. (line 929) * -v (gnatbind): Switches for gnatbind. (line 359) * -V (gnatbind): Switches for gnatbind. (line 364) * -v (gnatbind) <1>: Binder Error Message Control. (line 9) * -v (gnatchop): Switches for gnatchop. (line 83) * -v (gnatclean): Switches for gnatclean. (line 81) * -v (gnatdll): Using gnatdll. (line 95) * -v (gnatlink): Switches for gnatlink. (line 41) * -v (gnatls): Switches for gnatls. (line 65) * -v (gnatmake): Switches for gnatmake. (line 382) * -v (gnatname): Switches for gnatname. (line 101) * -v (gnatprep): Switches for gnatprep. (line 79) * -version (gnatbind): Switches for gnatbind. (line 9) * -version (gnatchop): Switches for gnatchop. (line 8) * -version (gnatclean): Switches for gnatclean. (line 8) * -version (gnatlink): Switches for gnatlink. (line 8) * -version (gnatls): Switches for gnatls. (line 8) * -version (gnatmake): Switches for gnatmake. (line 8) * -version (gnatname): Switches for gnatname. (line 10) * -version (gnatprep): Switches for gnatprep. (line 6) * -vl (gnatmake): Switches for gnatmake. (line 387) * -vm (gnatmake): Switches for gnatmake. (line 391) * -vm (gnatmake) <1>: Switches for gnatmake. (line 396) * -vP (gnatclean): Switches for gnatclean. (line 85) * -w (gcc): Alphabetical List of All Switches. (line 934) * -w (gcc) <1>: Warning Message Control. (line 1331) * -w (gnatbind): Switches for gnatbind. (line 370) * -w (gnatchop): Switches for gnatchop. (line 89) * -Wall (gcc): Warning Message Control. (line 1322) * -we (gnatbind): Binder Error Message Control. (line 39) * -Werror (gcc): Warning Message Control. (line 1337) * -ws (gnatbind): Binder Error Message Control. (line 35) * -Wstack-usage (gcc): Warning Message Control. (line 1317) * -Wuninitialized (gcc): Warning Message Control. (line 1311) * -Wunused (gcc): Warning Message Control. (line 1303) * -Wx (gnatbind): Switches for gnatbind. (line 374) * -Wx (gnatbind) <1>: Consistency-Checking Modes. (line 18) * -x (gnatbind): Switches for gnatbind. (line 379) * -x (gnatbind) <1>: Consistency-Checking Modes. (line 28) * -X (gnatclean): Switches for gnatclean. (line 90) * -x (gnatmake): Switches for gnatmake. (line 405) * -x (gnatname): Switches for gnatname. (line 116) * -xdr (gnatbind): Switches for gnatbind. (line 383) * -Xnnn (gnatbind): Switches for gnatbind. (line 392) * -y (gnatbind): Switches for gnatbind. (line 396) * -z (gnatbind): Switches for gnatbind. (line 400) * -z (gnatbind) <1>: Binding Programs with No Main Subprogram. (line 12) * -z (gnatmake): Switches for gnatmake. (line 423) * Abnormal Termination or Failure to Terminate: Remote Debugging with gdbserver. (line 46) * Access before elaboration: Run-Time Checks. (line 6) * access before elaboration: Run-Time Checks. (line 6) * activate every optional warning: Warning Message Control. (line 410) * ACVC: Compiling Different Versions of Ada. (line 11) * Ada: Search Paths for gnatbind. (line 45) * Ada 2005 Language Reference Manual: What You Should Know before Reading This Guide. (line 6) * Ada 2005 mode: Compiling Different Versions of Ada. (line 49) * Ada 2012 mode: Compiling Different Versions of Ada. (line 58) * Ada 2022 mode: Compiling Different Versions of Ada. (line 67) * Ada 83 mode: Compiling Different Versions of Ada. (line 11) * Ada 83 tests: Compiling Different Versions of Ada. (line 11) * Ada 95 Language Reference Manual: What You Should Know before Reading This Guide. (line 6) * Ada 95 mode: Compiling Different Versions of Ada. (line 35) * Ada compatibility issues warnings: Warning Message Control. (line 1227) * Ada compatibility issues warnings <1>: Warning Message Control. (line 1240) * Ada expressions (in gdb): Using Ada Expressions. (line 6) * Ada language extensions: Compiling Different Versions of Ada. (line 72) * Ada language extensions <1>: Compiling Different Versions of Ada. (line 80) * Ada Library Information files: The Ada Library Information Files. (line 6) * ADA_INCLUDE_PATH: Using a library. (line 54) * ADA_INCLUDE_PATH <1>: Search Paths and the Run-Time Library RTL. (line 28) * ADA_INCLUDE_PATH <2>: Search Paths and the Run-Time Library RTL. (line 28) * ADA_OBJECTS_PATH: Using a library. (line 58) * ADA_OBJECTS_PATH <1>: Search Paths for gnatbind. (line 27) * ADA_OBJECTS_PATH <2>: Search Paths for gnatbind. (line 27) * ADA_PRJ_INCLUDE_FILE: Search Paths and the Run-Time Library RTL. (line 22) * ADA_PRJ_INCLUDE_FILE <1>: Search Paths and the Run-Time Library RTL. (line 23) * ADA_PRJ_INCLUDE_FILE <2>: Search Paths and the Run-Time Library RTL. (line 23) * ADA_PRJ_OBJECTS_FILE: Search Paths for gnatbind. (line 20) * ADA_PRJ_OBJECTS_FILE <1>: Search Paths for gnatbind. (line 21) * ADA_PRJ_OBJECTS_FILE <2>: Search Paths for gnatbind. (line 23) * ADA_PROJECT_PATH: Installing a library. (line 6) * Ada.Characters.Latin_1: Latin-1. (line 13) * adafinal: Binding with Non-Ada Main Programs. (line 38) * adainit: Binding with Non-Ada Main Programs. (line 22) * Address Clauses: Warning Message Control. (line 716) * ALI files: The Ada Library Information Files. (line 6) * Aliasing: Optimization and Strict Aliasing. (line 6) * Aliasing <1>: Aliased Variables and Optimization. (line 6) * alternative: Alternative File Naming Schemes. (line 6) * Annex A (in Ada Reference Manual): Naming Conventions for GNAT Source Files. (line 45) * Annex B (in Ada reference Manual): Naming Conventions for GNAT Source Files. (line 48) * Anonymous allocators: Warning Message Control. (line 221) * Anonymous allocators <1>: Warning Message Control. (line 230) * APIENTRY: Windows Calling Conventions. (line 6) * Asm: Calling Conventions. (line 48) * Assert: Debugging and Assertion Control. (line 8) * Assert failures: Warning Message Control. (line 205) * Assert failures <1>: Warning Message Control. (line 214) * Assertions: Debugging and Assertion Control. (line 8) * Atomic: Atomic Variables and Optimization. (line 6) * Atomic Synchronization: Warning Message Control. (line 701) * Atomic Synchronization <1>: Warning Message Control. (line 713) * attach to process: Program Built with Foreign Tools and DLL Built with GCC/GNAT. (line 71) * Bad fixed values: Warning Message Control. (line 237) * Biased representation: Warning Message Control. (line 257) * Binder: Binding with Non-Ada Main Programs. (line 45) * Binder consistency checks: Binder Error Message Control. (line 43) * Binder output (example): Example of Binder Output File. (line 6) * Binder output file: Interfacing to C. (line 83) * Binding generation (for Ada specs): Generating C Headers for Ada Specifications. (line 6) * Binding generation (for C and C++ headers): Generating Ada Bindings for C and C++ headers. (line 6) * BINUTILS_ROOT: Linking a Mixed C++ & Ada Program. (line 29) * bit order warnings: Warning Message Control. (line 1125) * Breakpoints and tasks: Ada Tasks. (line 26) * building: Building DLLs with GNAT Project files. (line 6) * building <1>: Building DLLs with GNAT. (line 6) * building <2>: Building DLLs with gnatdll. (line 6) * building <3>: Building Resources. (line 6) * Building the GNAT Run-Time Library: Rebuilding the GNAT Run-Time Library. (line 6) * C: Calling Conventions. (line 57) * C headers (binding generation): Generating Ada Bindings for C and C++ headers. (line 6) * C headers (binding generation) <1>: Generating C Headers for Ada Specifications. (line 6) * C varargs function: Calling Conventions. (line 64) * C_INCLUDE_PATH: Linking a Mixed C++ & Ada Program. (line 28) * C++: Calling Conventions. (line 89) * C++ headers (binding generation): Generating Ada Bindings for C and C++ headers. (line 6) * Calling Conventions: Calling Conventions. (line 6) * cannot generate code: Compiling Programs. (line 29) * Check: Run-Time Checks. (line 64) * Check <1>: Run-Time Checks. (line 129) * Checks: Run-Time Checks. (line 6) * Checks <1>: Run-Time Checks. (line 6) * Checks <2>: Run-Time Checks. (line 6) * Checks <3>: Run-Time Checks. (line 14) * Checks <4>: Run-Time Checks. (line 60) * Checks <5>: Run-Time Checks. (line 137) * Checks <6>: Controlling Run-Time Checks. (line 31) * Checks (overflow): Example of unused subprogram/data elimination. (line 56) * COBOL: Calling Conventions. (line 52) * code page 437 (IBM PC): Other 8-Bit Codes. (line 33) * code page 850 (IBM PC): Other 8-Bit Codes. (line 42) * Combining GNAT switches: Alphabetical List of All Switches. (line 941) * Command Line Argument Expansion: Disabling Command Line Argument Expansion. (line 6) * Command line length: Switches for gnatlink. (line 18) * Compatibility with Ada 83: Compiling Different Versions of Ada. (line 11) * compilation (definition): Source Representation. (line 43) * Compilation model: The GNAT Compilation Model. (line 6) * Compile_Time_Error: Warning Message Control. (line 324) * Compile_Time_Warning: Warning Message Control. (line 324) * compiling: Compiling Resources. (line 6) * Component clause: Warning Message Control. (line 308) * Conditional compilation: Rebuilding the GNAT Run-Time Library. (line 22) * Conditional compilation <1>: Conditional Compilation. (line 9) * Conditionals: Warning Message Control. (line 274) * configuration: Configuration Pragmas. (line 6) * Configuration pragmas: Configuration Pragmas. (line 6) * Consistency checks: Binder Error Message Control. (line 43) * CONSOLE Subsystem: CONSOLE and WINDOWS subsystems. (line 6) * constant: Warning Message Control. (line 274) * Convention Ada: Calling Conventions. (line 10) * Convention Asm: Calling Conventions. (line 48) * Convention Assembler: Calling Conventions. (line 42) * Convention C: Calling Conventions. (line 57) * Convention C++: Calling Conventions. (line 89) * Convention COBOL: Calling Conventions. (line 52) * Convention Default: Calling Conventions. (line 81) * Convention DLL: Calling Conventions. (line 160) * Convention External: Calling Conventions. (line 85) * Convention Fortran: Calling Conventions. (line 95) * Convention Stdcall: Calling Conventions. (line 152) * Convention Stubbed: Calling Conventions. (line 168) * Convention Win32: Calling Conventions. (line 164) * Conventions: Conventions. (line 6) * CR: Source Representation. (line 6) * Cyrillic: Other 8-Bit Codes. (line 23) * Deactivated code: Warning Message Control. (line 1014) * Debug: Debugging and Assertion Control. (line 8) * Debug Pool: The GNAT Debug Pool Facility. (line 6) * Debugger: Running and Debugging Ada Programs. (line 24) * Debugging: Running and Debugging Ada Programs. (line 6) * Debugging Generic Units: Ada Tasks. (line 56) * Debugging information: Switches for gnatlink. (line 27) * Debugging optimized code: Debugging Optimized Code. (line 6) * Debugging options: Debugging Control. (line 6) * Default: Calling Conventions. (line 81) * Definition file: Creating an Import Library. (line 12) * Deleted code: Warning Message Control. (line 1014) * Dependencies: Switches for gnatmake. (line 313) * Dependency rules (compilation): Building with gnatmake. (line 19) * Dereferencing: Warning Message Control. (line 352) * Dimension aspect: Performing Dimensionality Analysis in GNAT. (line 13) * Dimension aspect <1>: Performing Dimensionality Analysis in GNAT. (line 153) * Dimension Vector (for a dimensioned subtype): Performing Dimensionality Analysis in GNAT. (line 153) * Dimension_System aspect: Performing Dimensionality Analysis in GNAT. (line 13) * Dimension_System aspect <1>: Performing Dimensionality Analysis in GNAT. (line 153) * Dimensionable type: Performing Dimensionality Analysis in GNAT. (line 148) * Dimensionality analysis: Performing Dimensionality Analysis in GNAT. (line 6) * Dimensioned subtype: Performing Dimensionality Analysis in GNAT. (line 148) * Division by zero: Run-Time Checks. (line 6) * division by zero: Run-Time Checks. (line 6) * DLL: Calling Conventions. (line 160) * DLL <1>: Introduction to Dynamic Link Libraries DLLs. (line 6) * DLL debugging: Debugging a DLL. (line 6) * DLL debugging <1>: Program Built with Foreign Tools and DLL Built with GCC/GNAT. (line 71) * DLLs: Building DLLs with GNAT Project files. (line 6) * DLLs <1>: Building DLLs with GNAT. (line 6) * DLLs <2>: Building DLLs with gnatdll. (line 6) * DLLs and elaboration: Ada DLLs and Elaboration. (line 6) * DLLs and finalization: Ada DLLs and Finalization. (line 6) * Dynamic elaboration model: Controlling the Elaboration Order in GNAT. (line 10) * Elaboration: Warning Message Control. (line 623) * elaboration: Run-Time Checks. (line 129) * Elaboration checks: Run-Time Checks. (line 129) * Elaboration control: Elaboration Order Handling in GNAT. (line 6) * Elaboration order control: Comparison between GNAT and C/C++ Compilation Models. (line 24) * End of source file; Source file, end: Source Representation. (line 37) * environment variable; ADA_INCLUDE_PATH: Using a library. (line 54) * environment variable; ADA_INCLUDE_PATH <1>: Search Paths and the Run-Time Library RTL. (line 28) * environment variable; ADA_OBJECTS_PATH: Using a library. (line 58) * environment variable; ADA_OBJECTS_PATH <1>: Search Paths for gnatbind. (line 27) * environment variable; ADA_PRJ_INCLUDE_FILE: Search Paths and the Run-Time Library RTL. (line 23) * environment variable; ADA_PRJ_INCLUDE_FILE <1>: Search Paths and the Run-Time Library RTL. (line 23) * environment variable; ADA_PRJ_OBJECTS_FILE: Search Paths for gnatbind. (line 21) * environment variable; ADA_PRJ_OBJECTS_FILE <1>: Search Paths for gnatbind. (line 23) * environment variable; BINUTILS_ROOT: Linking a Mixed C++ & Ada Program. (line 29) * environment variable; C_INCLUDE_PATH: Linking a Mixed C++ & Ada Program. (line 28) * environment variable; GCC_EXEC_PREFIX: Linking a Mixed C++ & Ada Program. (line 29) * environment variable; GCC_ROOT: Linking a Mixed C++ & Ada Program. (line 29) * environment variable; PATH: Linking a Mixed C++ & Ada Program. (line 27) * environment variable; PATH <1>: Search Paths and the Run-Time Library RTL. (line 30) * environment variable; PATH <2>: Search Paths for gnatbind. (line 29) * environment variable; TMP: Temporary Files. (line 7) * environment variable; TMP <1>: Temporary Files. (line 9) * environment variable; TMP <2>: Temporary Files. (line 12) * Error messages: Output and Error Message Control. (line 131) * EUC Coding: Wide_Character Encodings. (line 40) * Exceptions (in gdb): Stopping When Ada Exceptions Are Raised. (line 6) * Export table: Exporting Ada Entities. (line 6) * Export/Import pragma warnings: Warning Message Control. (line 1189) * External: Calling Conventions. (line 85) * Features: Warning Message Control. (line 545) * FF: Source Representation. (line 6) * File cleanup tool: The File Cleanup Utility gnatclean. (line 6) * File names: Using Other File Names. (line 6) * File names <1>: Alternative File Naming Schemes. (line 6) * File Naming Conventions: Handling Arbitrary File Naming Conventions with gnatname. (line 6) * File naming schemes: Alternative File Naming Schemes. (line 6) * Fixed-point Small value: Warning Message Control. (line 237) * Floating-Point Operations: Floating Point Operations. (line 6) * for gnatmake: Switches for gnatmake. (line 464) * for profiling: Compilation for profiling. (line 6) * for profiling <1>: Compilation for profiling. (line 6) * Foreign Languages: Calling Conventions. (line 6) * Formals: Warning Message Control. (line 430) * Fortran: Calling Conventions. (line 95) * GCC_EXEC_PREFIX: Linking a Mixed C++ & Ada Program. (line 29) * GCC_ROOT: Linking a Mixed C++ & Ada Program. (line 29) * gdb: Running and Debugging Ada Programs. (line 24) * Generic formal parameters: Compiling Different Versions of Ada. (line 25) * Generics: Generating Object Files. (line 32) * Generics <1>: Ada Tasks. (line 55) * GNAT: Search Paths for gnatbind. (line 45) * GNAT (package): Naming Conventions for GNAT Source Files. (line 54) * GNAT compilation model: The GNAT Compilation Model. (line 6) * GNAT extensions: Compiling Different Versions of Ada. (line 72) * GNAT extensions <1>: Compiling Different Versions of Ada. (line 80) * GNAT library: Comparison between GNAT and Conventional Ada Library Models. (line 10) * GNAT Run-Time Library: Rebuilding the GNAT Run-Time Library. (line 6) * gnat_argc: Command-Line Access. (line 13) * gnat_argv: Command-Line Access. (line 13) * GNAT_INIT_SCALARS: Switches for gnatbind. (line 316) * gnat.adc: Using Other File Names. (line 35) * gnat.adc <1>: The Configuration Pragmas Files. (line 6) * gnat1: Compiling Programs. (line 64) * gnatbind: Binding with gnatbind. (line 6) * gnatchop: Renaming Files with gnatchop. (line 6) * gnatclean: The File Cleanup Utility gnatclean. (line 6) * gnatdll: Using gnatdll. (line 6) * gnatkr: File Name Krunching with gnatkr. (line 6) * gnatlink: Linking with gnatlink. (line 6) * gnatls: The GNAT Library Browser gnatls. (line 6) * gnatmake: Building with gnatmake. (line 6) * gnatname: Alternative File Naming Schemes. (line 117) * gnatprep: Preprocessing. (line 17) * gnatprep <1>: Preprocessing with gnatprep. (line 6) * GNU make: Using the GNU make Utility. (line 6) * GNU/Linux: Choosing the Scheduling Policy. (line 38) * GPR_PROJECT_PATH: Installing a library. (line 6) * gprof: Profiling. (line 9) * Hiding of Declarations: Warning Message Control. (line 473) * HT: Source Representation. (line 6) * implicit: Warning Message Control. (line 352) * Implicit dereferencing: Warning Message Control. (line 352) * Import library: Creating an Import Library. (line 6) * Improving performance: Improving Performance. (line 6) * in binder: Binder Error Message Control. (line 43) * in binder <1>: Binder Error Message Control. (line 43) * including: Switches for gnatlink. (line 27) * Inline: Source Dependencies. (line 27) * Inline <1>: Inlining of Subprograms. (line 15) * Inline Assembler: Inline Assembler. (line 6) * Inlining: Comparison between GNAT and Conventional Ada Library Models. (line 35) * Inlining <1>: Warning Message Control. (line 755) * Interfaces: Search Paths for gnatbind. (line 45) * Interfacing to Ada: Calling Conventions. (line 10) * Interfacing to Assembly: Calling Conventions. (line 42) * Interfacing to C: Calling Conventions. (line 57) * Interfacing to C varargs function: Calling Conventions. (line 64) * Interfacing to C++: Calling Conventions. (line 89) * Interfacing to COBOL: Calling Conventions. (line 52) * Interfacing to Fortran: Calling Conventions. (line 95) * ISO 8859-15: Other 8-Bit Codes. (line 28) * ISO 8859-2: Other 8-Bit Codes. (line 8) * ISO 8859-3: Other 8-Bit Codes. (line 13) * ISO 8859-4: Other 8-Bit Codes. (line 18) * ISO 8859-5: Other 8-Bit Codes. (line 23) * Latin-1: Source Representation. (line 6) * Latin-1 <1>: Latin-1. (line 6) * Latin-2: Other 8-Bit Codes. (line 8) * Latin-3: Other 8-Bit Codes. (line 13) * Latin-4: Other 8-Bit Codes. (line 18) * Latin-9: Other 8-Bit Codes. (line 28) * Layout: Warning Message Control. (line 832) * Legacy elaboration models: Controlling the Elaboration Order in GNAT. (line 74) * LF: Source Representation. (line 6) * Library browser: The GNAT Library Browser gnatls. (line 6) * Library building and using: GNAT and Libraries. (line 6) * Linker libraries: Switches for gnatmake. (line 478) * Linux: Choosing the Scheduling Policy. (line 39) * Machine_Overflows: Run-Time Checks. (line 109) * make (GNU): Using the GNU make Utility. (line 6) * memory corruption: The GNAT Debug Pool Facility. (line 6) * Memory Pool: Some Useful Memory Pools. (line 6) * Microsoft Visual Studio: Using GNAT DLLs from Microsoft Visual Studio Applications. (line 6) * missing: Warning Message Control. (line 308) * Mixed Language Programming: Mixed Language Programming. (line 6) * MKS_Type type: Performing Dimensionality Analysis in GNAT. (line 26) * multiple input files: Binding with Non-Ada Main Programs. (line 45) * Multiple units: Using gcc for Syntax Checking. (line 37) * naming scheme: Switches for gnatmake. (line 211) * No information messages for why package spec needs body: Warning Message Control. (line 1259) * No_Strict_Aliasing: Optimization and Strict Aliasing. (line 6) * non-symbolic: Stack Traceback. (line 21) * obsolescent: Warning Message Control. (line 545) * Obsolescent features: Warning Message Control. (line 545) * Optimization and debugging: Debugging Optimized Code. (line 6) * Optimization Switches: Vectorization of loops. (line 6) * Optimization Switches <1>: Other Optimization Switches. (line 6) * Order of elaboration: Elaboration Order Handling in GNAT. (line 6) * OS X: Mac OS Topics. (line 6) * Other Ada compilers: Calling Conventions. (line 10) * overflow: Run-Time Checks. (line 64) * overflow <1>: Controlling Run-Time Checks. (line 31) * Overflow checks: Run-Time Checks. (line 64) * Overflow checks <1>: Controlling Run-Time Checks. (line 31) * Overflow checks <2>: Example of unused subprogram/data elimination. (line 57) * Overflow mode: Run-Time Checks. (line 64) * Package spec needing body: Warning Message Control. (line 1247) * Parallel make: Switches for gnatmake. (line 264) * Parameter order: Warning Message Control. (line 775) * Parentheses: Warning Message Control. (line 811) * Passive Task: Passive Task Optimization. (line 6) * PATH: Linking a Mixed C++ & Ada Program. (line 27) * PATH <1>: Search Paths and the Run-Time Library RTL. (line 30) * PATH <2>: Search Paths for gnatbind. (line 29) * pool: Some Useful Memory Pools. (line 6) * pool <1>: The GNAT Debug Pool Facility. (line 6) * Postcondition: Debugging and Assertion Control. (line 8) * pragma Assert: Debugging - A Special Case. (line 22) * pragma Assertion_Policy: Debugging - A Special Case. (line 42) * pragma Debug: Debugging - A Special Case. (line 49) * pragma Debug_Policy: Debugging - A Special Case. (line 65) * pragma Elaborate (Unit): Controlling the Elaboration Order in Ada. (line 96) * pragma Elaborate_All (Unit): Controlling the Elaboration Order in Ada. (line 138) * pragma Elaborate_Body: Controlling the Elaboration Order in Ada. (line 39) * pragma Export: The External Symbol Naming Scheme of GNAT. (line 20) * pragma Inline: Inlining of Subprograms. (line 15) * pragma Overflow_Mode: Specifying the Desired Mode. (line 6) * pragma Preelaborate: Controlling the Elaboration Order in Ada. (line 33) * pragma Pure: Controlling the Elaboration Order in Ada. (line 28) * pragma Restrictions: Debugging Control. (line 172) * pragma Suppress: Controlling Run-Time Checks. (line 31) * pragma Task_Dispatching_Policy: Choosing the Scheduling Policy. (line 12) * pragma Time_Slice: Choosing the Scheduling Policy. (line 12) * pragma Unsuppress: Controlling Run-Time Checks. (line 31) * Pragmas: Configuration Pragmas. (line 6) * Pragmas <1>: Warning Message Control. (line 448) * Precondition: Debugging and Assertion Control. (line 8) * Preprocessing: Preprocessing. (line 6) * Preprocessing (gnatprep): Preprocessing with gnatprep. (line 6) * Preprocessors (contrasted with conditional compilation): Use of Boolean Constants. (line 23) * producing list: Switches for gnatmake. (line 313) * Profiling: Pretty-Printers for the GNAT runtime. (line 80) * Profiling <1>: Profiling. (line 9) * rc: Compiling Resources. (line 6) * rebuilding: Rebuilding the GNAT Run-Time Library. (line 6) * rebuilding <1>: Rebuilding the GNAT Run-Time Library. (line 6) * Rebuilding the GNAT Run-Time Library: Rebuilding the GNAT Run-Time Library. (line 6) * Recompilation (by gnatmake): Notes on the Command Line. (line 9) * Record Representation (component sizes): Warning Message Control. (line 979) * Record Representation (gaps): Warning Message Control. (line 489) * Relaxed elaboration mode: Controlling the Elaboration Order in GNAT. (line 87) * Remote Debugging with gdbserver: Debugging Generic Units. (line 47) * Resources: GNAT and Windows Resources. (line 6) * Resources <1>: Building Resources. (line 6) * Resources <2>: Compiling Resources. (line 6) * Resources <3>: Using Resources. (line 6) * RTL: Alphabetical List of All Switches. (line 844) * RTL <1>: Alphabetical List of All Switches. (line 850) * Run-time libraries (platform-specific information): Run-Time Libraries. (line 6) * Run-Time Library: Rebuilding the GNAT Run-Time Library. (line 6) * s-digemk.ads file: Performing Dimensionality Analysis in GNAT. (line 34) * SCHED_FIFO scheduling policy: Specifying a Run-Time Library. (line 54) * SCHED_OTHER scheduling policy: Specifying a Run-Time Library. (line 56) * SCHED_RR scheduling policy: Specifying a Run-Time Library. (line 56) * Search paths: Switches for gnatmake. (line 464) * setjmp/longjmp Exception Model: Run-Time Libraries. (line 16) * Shift JIS Coding: Wide_Character Encodings. (line 31) * Size/Alignment warnings: Warning Message Control. (line 1283) * Size/Alignment warnings <1>: Warning Message Control. (line 1293) * SJLJ (setjmp/longjmp Exception Model): Run-Time Libraries. (line 16) * Small value: Warning Message Control. (line 237) * Source files: Switches for gnatmake. (line 472) * Source files <1>: Running gnatbind. (line 29) * Source files <2>: Switches for gnatclean. (line 105) * Source_File_Name pragma: Using Other File Names. (line 12) * Source_File_Name pragma <1>: Alternative File Naming Schemes. (line 12) * Source_Reference pragmas: Switches for gnatchop. (line 61) * SPARK elaboration model: Controlling the Elaboration Order in GNAT. (line 64) * spec (definition): Source Representation. (line 43) * stack overflow checking: Run-Time Checks. (line 6) * Stack Overflow Checking: Run-Time Checks. (line 137) * stack overflow checking <1>: Run-Time Checks. (line 137) * Stack Overflow Checking <1>: Stack Overflow Checking. (line 6) * stack traceback: Getting Internal Debugging Information. (line 22) * stack unwinding: Getting Internal Debugging Information. (line 21) * Stand-alone libraries: Stand-alone Ada Libraries. (line 6) * Static elaboration model: Controlling the Elaboration Order in GNAT. (line 38) * Static Stack Usage Analysis: Static Stack Usage Analysis. (line 6) * Stdcall: Calling Conventions. (line 152) * Stdcall <1>: Windows Calling Conventions. (line 6) * stderr: Output and Error Message Control. (line 6) * storage: Some Useful Memory Pools. (line 6) * storage <1>: The GNAT Debug Pool Facility. (line 6) * Strict Aliasing: Optimization and Strict Aliasing. (line 6) * String indexing warnings: Warning Message Control. (line 1145) * Stubbed: Calling Conventions. (line 168) * Style checking: Style Checking. (line 6) * SUB (control character): Source Representation. (line 37) * Subtype predicates: Debugging and Assertion Control. (line 8) * Subunits: Generating Object Files. (line 24) * Subunits (and conditional compilation): Use of Alternative Implementations. (line 21) * Suppress: Run-Time Checks. (line 60) * Suppress <1>: Controlling Run-Time Checks. (line 31) * suppressing: Output and Error Message Control. (line 131) * suppressing <1>: Run-Time Checks. (line 14) * suppressing <2>: Run-Time Checks. (line 60) * Suppressing checks: Run-Time Checks. (line 14) * Suppressing checks <1>: Run-Time Checks. (line 60) * suppressing search: Switches for gnatmake. (line 472) * suppressing search <1>: Switches for gnatclean. (line 105) * symbolic: Non-Symbolic Traceback. (line 262) * symbolic links: Switches for gnatmake. (line 205) * syntax checking: Using gcc for Syntax Checking. (line 37) * System: Search Paths for gnatbind. (line 45) * System (package in Ada Reference Manual): Naming Conventions for GNAT Source Files. (line 51) * System.Dim.Mks package (GNAT library): Performing Dimensionality Analysis in GNAT. (line 26) * System.IO: Search Paths and the Run-Time Library RTL. (line 53) * Task switching (in gdb): Ada Tasks. (line 45) * Tasking and threads libraries: Run-Time Libraries. (line 6) * Tasks (in gdb): Stopping When Ada Exceptions Are Raised. (line 35) * Temporary files: Temporary Files. (line 6) * Text_IO and performance: Text_IO Suggestions. (line 6) * Threads libraries and tasking: Run-Time Libraries. (line 6) * Time stamp checks: Binder Error Message Control. (line 43) * TMP: Temporary Files. (line 7) * TMP <1>: Temporary Files. (line 9) * TMP <2>: Temporary Files. (line 12) * traceback: Getting Internal Debugging Information. (line 22) * traceback <1>: Stack Traceback. (line 21) * traceback <2>: Non-Symbolic Traceback. (line 263) * treat as error: Warning Message Control. (line 394) * treat as error <1>: Warning Message Control. (line 419) * Type invariants: Debugging and Assertion Control. (line 8) * typographical: Conventions. (line 6) * Typographical conventions: Conventions. (line 6) * Unassigned variable warnings: Warning Message Control. (line 1105) * Unchecked_Conversion warnings: Warning Message Control. (line 1266) * unrecognized: Warning Message Control. (line 448) * unreferenced: Warning Message Control. (line 430) * Unsuppress: Run-Time Checks. (line 142) * Unsuppress <1>: Controlling Run-Time Checks. (line 31) * Upper-Half Coding: Wide_Character Encodings. (line 22) * use by binder: Running gnatbind. (line 29) * use with GNAT DLLs: Using GNAT DLLs from Microsoft Visual Studio Applications. (line 6) * using: Using Resources. (line 6) * Uunused subprogram/data elimination: Reducing Size of Executables with Unused Subprogram/Data Elimination. (line 6) * Validity Checking: Validity Checking. (line 6) * varargs function interfaces: Calling Conventions. (line 64) * Version skew (avoided by ''gnatmake''): Running a Simple Ada Program. (line 58) * Volatile parameter: The Volatile Parameter. (line 6) * VT: Source Representation. (line 6) * Warning messages: Warning Message Control. (line 6) * Warnings: Warning Message Control. (line 394) * Warnings <1>: Warning Message Control. (line 410) * Warnings <2>: Warning Message Control. (line 419) * warnings: Warning Message Control. (line 623) * warnings <1>: Warning Message Control. (line 701) * warnings <2>: Warning Message Control. (line 713) * warnings <3>: Warning Message Control. (line 716) * warnings <4>: Warning Message Control. (line 755) * warnings <5>: Warning Message Control. (line 775) * warnings <6>: Warning Message Control. (line 811) * warnings <7>: Warning Message Control. (line 832) * Warnings <3>: Warning Message Control. (line 998) * warnings <8>: Warning Message Control. (line 1014) * warnings <9>: Warning Message Control. (line 1014) * Warnings <4>: Binder Error Message Control. (line 35) * Warnings Off control: Warning Message Control. (line 1169) * Win32: Calling Conventions. (line 164) * Windows: A GNU/Linux Debug Quirk. (line 18) * windows: GNAT and Windows Resources. (line 6) * WINDOWS Subsystem: CONSOLE and WINDOWS subsystems. (line 6) * windres: Compiling Resources. (line 6) * ZCX (Zero-Cost Exceptions): Run-Time Libraries. (line 13) * Zero Cost Exceptions: Exception Handling Control. (line 40) * Zero-Cost Exceptions: Run-Time Libraries. (line 13)