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)