1------------------------------------------------------------------------------
2--                                                                          --
3--                         GNAT COMPILER COMPONENTS                         --
4--                                                                          --
5--                              B I N D G E N                               --
6--                                                                          --
7--                                 B o d y                                  --
8--                                                                          --
9--          Copyright (C) 1992-2019, Free Software Foundation, Inc.         --
10--                                                                          --
11-- GNAT is free software;  you can  redistribute it  and/or modify it under --
12-- terms of the  GNU General Public License as published  by the Free Soft- --
13-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
14-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
17-- for  more details.  You should have  received  a copy of the GNU General --
18-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
19-- http://www.gnu.org/licenses for a complete copy of the license.          --
20--                                                                          --
21-- GNAT was originally developed  by the GNAT team at  New York University. --
22-- Extensive contributions were provided by Ada Core Technologies Inc.      --
23--                                                                          --
24------------------------------------------------------------------------------
25
26with Casing;   use Casing;
27with Fname;    use Fname;
28with Gnatvsn;  use Gnatvsn;
29with Hostparm;
30with Namet;    use Namet;
31with Opt;      use Opt;
32with Osint;    use Osint;
33with Osint.B;  use Osint.B;
34with Output;   use Output;
35with Rident;   use Rident;
36with Stringt;  use Stringt;
37with Table;
38with Targparm; use Targparm;
39with Types;    use Types;
40
41with System.OS_Lib;
42with System.WCh_Con; use System.WCh_Con;
43
44with GNAT.Heap_Sort_A; use GNAT.Heap_Sort_A;
45with GNAT.HTable;
46
47package body Bindgen is
48   Statement_Buffer : String (1 .. 1000);
49   --  Buffer used for constructing output statements
50
51   Stm_Last : Natural := 0;
52   --  Stm_Last location in Statement_Buffer currently set
53
54   With_GNARL : Boolean := False;
55   --  Flag which indicates whether the program uses the GNARL library
56   --  (presence of the unit System.OS_Interface)
57
58   Num_Elab_Calls : Nat := 0;
59   --  Number of generated calls to elaboration routines
60
61   Num_Primary_Stacks : Int := 0;
62   --  Number of default-sized primary stacks the binder needs to allocate for
63   --  task objects declared in the program.
64
65   Num_Sec_Stacks : Int := 0;
66   --  Number of default-sized primary stacks the binder needs to allocate for
67   --  task objects declared in the program.
68
69   System_Restrictions_Used : Boolean := False;
70   --  Flag indicating whether the unit System.Restrictions is in the closure
71   --  of the partition. This is set by Resolve_Binder_Options, and is used
72   --  to determine whether or not to initialize the restrictions information
73   --  in the body of the binder generated file (we do not want to do this
74   --  unconditionally, since it drags in the System.Restrictions unit
75   --  unconditionally, which is unpleasand, especially for ZFP etc.)
76
77   Dispatching_Domains_Used : Boolean := False;
78   --  Flag indicating whether multiprocessor dispatching domains are used in
79   --  the closure of the partition. This is set by Resolve_Binder_Options, and
80   --  is used to call the routine to disallow the creation of new dispatching
81   --  domains just before calling the main procedure from the environment
82   --  task.
83
84   System_Secondary_Stack_Package_In_Closure : Boolean := False;
85   --  Flag indicating whether the unit System.Secondary_Stack is in the
86   --  closure of the partition. This is set by Resolve_Binder_Options, and
87   --  is used to initialize the package in cases where the run-time brings
88   --  in package but the secondary stack is not used.
89
90   System_Tasking_Restricted_Stages_Used : Boolean := False;
91   --  Flag indicating whether the unit System.Tasking.Restricted.Stages is in
92   --  the closure of the partition. This is set by Resolve_Binder_Options,
93   --  and it used to call a routine to active all the tasks at the end of
94   --  the elaboration when partition elaboration policy is sequential.
95
96   System_Interrupts_Used : Boolean := False;
97   --  Flag indicating whether the unit System.Interrups is in the closure of
98   --  the partition. This is set by Resolve_Binder_Options, and it used to
99   --  attach interrupt handlers at the end of the elaboration when partition
100   --  elaboration policy is sequential.
101
102   System_BB_CPU_Primitives_Multiprocessors_Used : Boolean := False;
103   --  Flag indicating whether unit System.BB.CPU_Primitives.Multiprocessors
104   --  is in the closure of the partition. This is set by procedure
105   --  Resolve_Binder_Options, and it is used to call a procedure that starts
106   --  slave processors.
107
108   System_Version_Control_Used : Boolean := False;
109   --  Flag indicating whether unit System.Version_Control is in the closure.
110   --  This unit is implicitly withed by the compiler when Version or
111   --  Body_Version attributes are used. If the package is not in the closure,
112   --  the version definitions can be removed.
113
114   Lib_Final_Built : Boolean := False;
115   --  Flag indicating whether the finalize_library rountine has been built
116
117   Bind_Env_String_Built : Boolean := False;
118   --  Flag indicating whether a bind environment string has been built
119
120   CodePeer_Wrapper_Name : constant String := "call_main_subprogram";
121   --  For CodePeer, introduce a wrapper subprogram which calls the
122   --  user-defined main subprogram.
123
124   ----------------------------------
125   -- Interface_State Pragma Table --
126   ----------------------------------
127
128   --  This table assembles the interface state pragma information from
129   --  all the units in the partition. Note that Bcheck has already checked
130   --  that the information is consistent across units. The entries
131   --  in this table are n/u/r/s for not set/user/runtime/system.
132
133   package IS_Pragma_Settings is new Table.Table
134     (Table_Component_Type => Character,
135      Table_Index_Type     => Int,
136      Table_Low_Bound      => 0,
137      Table_Initial        => 100,
138      Table_Increment      => 200,
139      Table_Name           => "IS_Pragma_Settings");
140
141   --  This table assembles the Priority_Specific_Dispatching pragma
142   --  information from all the units in the partition. Note that Bcheck has
143   --  already checked that the information is consistent across units.
144   --  The entries in this table are the upper case first character of the
145   --  policy name, e.g. 'F' for FIFO_Within_Priorities.
146
147   package PSD_Pragma_Settings is new Table.Table
148     (Table_Component_Type => Character,
149      Table_Index_Type     => Int,
150      Table_Low_Bound      => 0,
151      Table_Initial        => 100,
152      Table_Increment      => 200,
153      Table_Name           => "PSD_Pragma_Settings");
154
155   ----------------------------
156   -- Bind_Environment Table --
157   ----------------------------
158
159   subtype Header_Num is Int range 0 .. 36;
160
161   function Hash (Nam : Name_Id) return Header_Num;
162
163   package Bind_Environment is new GNAT.HTable.Simple_HTable
164     (Header_Num => Header_Num,
165      Element    => Name_Id,
166      No_Element => No_Name,
167      Key        => Name_Id,
168      Hash       => Hash,
169      Equal      => "=");
170
171   ----------------------
172   -- Run-Time Globals --
173   ----------------------
174
175   --  This section documents the global variables that are set from the
176   --  generated binder file.
177
178   --     Main_Priority                 : Integer;
179   --     Time_Slice_Value              : Integer;
180   --     Heap_Size                     : Natural;
181   --     WC_Encoding                   : Character;
182   --     Locking_Policy                : Character;
183   --     Queuing_Policy                : Character;
184   --     Task_Dispatching_Policy       : Character;
185   --     Priority_Specific_Dispatching : System.Address;
186   --     Num_Specific_Dispatching      : Integer;
187   --     Restrictions                  : System.Address;
188   --     Interrupt_States              : System.Address;
189   --     Num_Interrupt_States          : Integer;
190   --     Unreserve_All_Interrupts      : Integer;
191   --     Exception_Tracebacks          : Integer;
192   --     Exception_Tracebacks_Symbolic : Integer;
193   --     Detect_Blocking               : Integer;
194   --     Default_Stack_Size            : Integer;
195   --     Default_Secondary_Stack_Size  : System.Parameters.Size_Type;
196   --     Leap_Seconds_Support          : Integer;
197   --     Main_CPU                      : Integer;
198   --     Default_Sized_SS_Pool         : System.Address;
199   --     Binder_Sec_Stacks_Count       : Natural;
200
201   --  Main_Priority is the priority value set by pragma Priority in the main
202   --  program. If no such pragma is present, the value is -1.
203
204   --  Time_Slice_Value is the time slice value set by pragma Time_Slice in the
205   --  main program, or by the use of a -Tnnn parameter for the binder (if both
206   --  are present, the binder value overrides). The value is in milliseconds.
207   --  A value of zero indicates that time slicing should be suppressed. If no
208   --  pragma is present, and no -T switch was used, the value is -1.
209
210   --  WC_Encoding shows the wide character encoding method used for the main
211   --  program. This is one of the encoding letters defined in
212   --  System.WCh_Con.WC_Encoding_Letters.
213
214   --  Locking_Policy is a space if no locking policy was specified for the
215   --  partition. If a locking policy was specified, the value is the upper
216   --  case first character of the locking policy name, for example, 'C' for
217   --  Ceiling_Locking.
218
219   --  Queuing_Policy is a space if no queuing policy was specified for the
220   --  partition. If a queuing policy was specified, the value is the upper
221   --  case first character of the queuing policy name for example, 'F' for
222   --  FIFO_Queuing.
223
224   --  Task_Dispatching_Policy is a space if no task dispatching policy was
225   --  specified for the partition. If a task dispatching policy was specified,
226   --  the value is the upper case first character of the policy name, e.g. 'F'
227   --  for FIFO_Within_Priorities.
228
229   --  Priority_Specific_Dispatching is the address of a string used to store
230   --  the task dispatching policy specified for the different priorities in
231   --  the partition. The length of this string is determined by the last
232   --  priority for which such a pragma applies (the string will be a null
233   --  string if no specific dispatching policies were used). If pragma were
234   --  present, the entries apply to the priorities in sequence from the first
235   --  priority. The value stored is the upper case first character of the
236   --  policy name, or 'F' (for FIFO_Within_Priorities) as the default value
237   --  for those priority ranges not specified.
238
239   --  Num_Specific_Dispatching is length of the Priority_Specific_Dispatching
240   --  string. It will be set to zero if no Priority_Specific_Dispatching
241   --  pragmas are present.
242
243   --  Restrictions is the address of a null-terminated string specifying the
244   --  restrictions information for the partition. The format is identical to
245   --  that of the parameter string found on R lines in ali files (see Lib.Writ
246   --  spec in lib-writ.ads for full details). The difference is that in this
247   --  context the values are the cumulative ones for the entire partition.
248
249   --  Interrupt_States is the address of a string used to specify the
250   --  cumulative results of Interrupt_State pragmas used in the partition.
251   --  The length of this string is determined by the last interrupt for which
252   --  such a pragma is given (the string will be a null string if no pragmas
253   --  were used). If pragma were present the entries apply to the interrupts
254   --  in sequence from the first interrupt, and are set to one of four
255   --  possible settings: 'n' for not specified, 'u' for user, 'r' for run
256   --  time, 's' for system, see description of Interrupt_State pragma for
257   --  further details.
258
259   --  Num_Interrupt_States is the length of the Interrupt_States string. It
260   --  will be set to zero if no Interrupt_State pragmas are present.
261
262   --  Unreserve_All_Interrupts is set to one if at least one unit in the
263   --  partition had a pragma Unreserve_All_Interrupts, and zero otherwise.
264
265   --  Exception_Tracebacks is set to one if the -Ea or -E parameter was
266   --  present in the bind and to zero otherwise. Note that on some targets
267   --  exception tracebacks are provided by default, so a value of zero for
268   --  this parameter does not necessarily mean no trace backs are available.
269
270   --  Exception_Tracebacks_Symbolic is set to one if the -Es parameter was
271   --  present in the bind and to zero otherwise.
272
273   --  Detect_Blocking indicates whether pragma Detect_Blocking is active or
274   --  not. A value of zero indicates that the pragma is not present, while a
275   --  value of 1 signals its presence in the partition.
276
277   --  Default_Stack_Size is the default stack size used when creating an Ada
278   --  task with no explicit Storage_Size clause.
279
280   --  Default_Secondary_Stack_Size is the default secondary stack size used
281   --  when creating an Ada task with no explicit Secondary_Stack_Size clause.
282
283   --  Leap_Seconds_Support denotes whether leap seconds have been enabled or
284   --  disabled. A value of zero indicates that leap seconds are turned "off",
285   --  while a value of one signifies "on" status.
286
287   --  Main_CPU is the processor set by pragma CPU in the main program. If no
288   --  such pragma is present, the value is -1.
289
290   --  Default_Sized_SS_Pool is set to the address of the default-sized
291   --  secondary stacks array generated by the binder. This pool of stacks is
292   --  generated when either the restriction No_Implicit_Heap_Allocations
293   --  or No_Implicit_Task_Allocations is active.
294
295   --  Binder_Sec_Stacks_Count is the number of generated secondary stacks in
296   --  the Default_Sized_SS_Pool.
297
298   procedure WBI (Info : String) renames Osint.B.Write_Binder_Info;
299   --  Convenient shorthand used throughout
300
301   -----------------------
302   -- Local Subprograms --
303   -----------------------
304
305   procedure Gen_Adainit (Elab_Order : Unit_Id_Array);
306   --  Generates the Adainit procedure
307
308   procedure Gen_Adafinal;
309   --  Generate the Adafinal procedure
310
311   procedure Gen_Bind_Env_String;
312   --  Generate the bind environment buffer
313
314   procedure Gen_CodePeer_Wrapper;
315   --  For CodePeer, generate wrapper which calls user-defined main subprogram
316
317   procedure Gen_Elab_Calls (Elab_Order : Unit_Id_Array);
318   --  Generate sequence of elaboration calls
319
320   procedure Gen_Elab_Externals (Elab_Order : Unit_Id_Array);
321   --  Generate sequence of external declarations for elaboration
322
323   procedure Gen_Elab_Order (Elab_Order : Unit_Id_Array);
324   --  Generate comments showing elaboration order chosen
325
326   procedure Gen_Finalize_Library (Elab_Order : Unit_Id_Array);
327   --  Generate a sequence of finalization calls to elaborated packages
328
329   procedure Gen_Main;
330   --  Generate procedure main
331
332   procedure Gen_Object_Files_Options (Elab_Order : Unit_Id_Array);
333   --  Output comments containing a list of the full names of the object
334   --  files to be linked and the list of linker options supplied by
335   --  Linker_Options pragmas in the source.
336
337   procedure Gen_Output_File_Ada
338     (Filename   : String;
339      Elab_Order : Unit_Id_Array);
340   --  Generate Ada output file
341
342   procedure Gen_Restrictions;
343   --  Generate initialization of restrictions variable
344
345   procedure Gen_Versions;
346   --  Output series of definitions for unit versions
347
348   function Get_Ada_Main_Name return String;
349   --  This function is used for the Ada main output to compute a usable name
350   --  for the generated main program. The normal main program name is
351   --  Ada_Main, but this won't work if the user has a unit with this name.
352   --  This function tries Ada_Main first, and if there is such a clash, then
353   --  it tries Ada_Name_01, Ada_Name_02 ... Ada_Name_99 in sequence.
354
355   function Get_Main_Unit_Name (S : String) return String;
356   --  Return the main unit name corresponding to S by replacing '.' with '_'
357
358   function Get_Main_Name return String;
359   --  This function is used in the main output case to compute the correct
360   --  external main program. It is "main" by default, unless the flag
361   --  Use_Ada_Main_Program_Name_On_Target is set, in which case it is the name
362   --  of the Ada main name without the "_ada". This default can be overridden
363   --  explicitly using the -Mname binder switch.
364
365   function Get_WC_Encoding return Character;
366   --  Return wide character encoding method to set as WC_Encoding in output.
367   --  If -W has been used, returns the specified encoding, otherwise returns
368   --  the encoding method used for the main program source. If there is no
369   --  main program source (-z switch used), returns brackets ('b').
370
371   function Has_Finalizer (Elab_Order : Unit_Id_Array) return Boolean;
372   --  Determine whether the current unit has at least one library-level
373   --  finalizer.
374
375   function Lt_Linker_Option (Op1 : Natural; Op2 : Natural) return Boolean;
376   --  Compare linker options, when sorting, first according to
377   --  Is_Internal_File (internal files come later) and then by
378   --  elaboration order position (latest to earliest).
379
380   procedure Move_Linker_Option (From : Natural; To : Natural);
381   --  Move routine for sorting linker options
382
383   procedure Resolve_Binder_Options (Elab_Order : Unit_Id_Array);
384   --  Set the value of With_GNARL
385
386   procedure Set_Char (C : Character);
387   --  Set given character in Statement_Buffer at the Stm_Last + 1 position
388   --  and increment Stm_Last by one to reflect the stored character.
389
390   procedure Set_Int (N : Int);
391   --  Set given value in decimal in Statement_Buffer with no spaces starting
392   --  at the Stm_Last + 1 position, and updating Stm_Last past the value. A
393   --  minus sign is output for a negative value.
394
395   procedure Set_Boolean (B : Boolean);
396   --  Set given boolean value in Statement_Buffer at the Stm_Last + 1 position
397   --  and update Stm_Last past the value.
398
399   procedure Set_IS_Pragma_Table;
400   --  Initializes contents of IS_Pragma_Settings table from ALI table
401
402   procedure Set_Main_Program_Name;
403   --  Given the main program name in Name_Buffer (length in Name_Len) generate
404   --  the name of the routine to be used in the call. The name is generated
405   --  starting at Stm_Last + 1, and Stm_Last is updated past it.
406
407   procedure Set_Name_Buffer;
408   --  Set the value stored in positions 1 .. Name_Len of the Name_Buffer
409
410   procedure Set_PSD_Pragma_Table;
411   --  Initializes contents of PSD_Pragma_Settings table from ALI table
412
413   procedure Set_String (S : String);
414   --  Sets characters of given string in Statement_Buffer, starting at the
415   --  Stm_Last + 1 position, and updating last past the string value.
416
417   procedure Set_String_Replace (S : String);
418   --  Replaces the last S'Length characters in the Statement_Buffer with the
419   --  characters of S. The caller must ensure that these characters do in fact
420   --  exist in the Statement_Buffer.
421
422   procedure Set_Unit_Name;
423   --  Given a unit name in the Name_Buffer, copy it into Statement_Buffer,
424   --  starting at the Stm_Last + 1 position and update Stm_Last past the
425   --  value. Each dot (.) will be qualified into double underscores (__).
426
427   procedure Set_Unit_Number (U : Unit_Id);
428   --  Sets unit number (first unit is 1, leading zeroes output to line up all
429   --  output unit numbers nicely as required by the value, and by the total
430   --  number of units.
431
432   procedure Write_Statement_Buffer;
433   --  Write out contents of statement buffer up to Stm_Last, and reset
434   --  Stm_Last to 0.
435
436   procedure Write_Statement_Buffer (S : String);
437   --  First writes its argument (using Set_String (S)), then writes out the
438   --  contents of statement buffer up to Stm_Last, and resets Stm_Last to 0.
439
440   procedure Write_Bind_Line (S : String);
441   --  Write S (an LF-terminated string) to the binder file (for use with
442   --  Set_Special_Output).
443
444   ------------------
445   -- Gen_Adafinal --
446   ------------------
447
448   procedure Gen_Adafinal is
449   begin
450      WBI ("   procedure " & Ada_Final_Name.all & " is");
451
452      --  Call s_stalib_adafinal to await termination of tasks and so on. We
453      --  want to do this if there is a main program, either in Ada or in some
454      --  other language. (Note that Bind_Main_Program is True for Ada mains,
455      --  but False for mains in other languages.) We do not want to do this if
456      --  we're binding a library.
457
458      if not Bind_For_Library and not CodePeer_Mode then
459         WBI ("      procedure s_stalib_adafinal;");
460         Set_String ("      pragma Import (C, s_stalib_adafinal, ");
461         Set_String ("""system__standard_library__adafinal"");");
462         Write_Statement_Buffer;
463      end if;
464
465      WBI ("");
466      WBI ("      procedure Runtime_Finalize;");
467      WBI ("      pragma Import (C, Runtime_Finalize, " &
468             """__gnat_runtime_finalize"");");
469      WBI ("");
470      WBI ("   begin");
471
472      if not CodePeer_Mode then
473         WBI ("      if not Is_Elaborated then");
474         WBI ("         return;");
475         WBI ("      end if;");
476         WBI ("      Is_Elaborated := False;");
477      end if;
478
479      WBI ("      Runtime_Finalize;");
480
481      --  By default (real targets), finalization is done differently depending
482      --  on whether this is the main program or a library.
483
484      if not CodePeer_Mode then
485         if not Bind_For_Library then
486            WBI ("      s_stalib_adafinal;");
487         elsif Lib_Final_Built then
488            WBI ("      finalize_library;");
489         else
490            WBI ("      null;");
491         end if;
492
493      --  Pragma Import C cannot be used on virtual targets, therefore call the
494      --  runtime finalization routine directly in CodePeer mode, where
495      --  imported functions are ignored.
496
497      else
498         WBI ("      System.Standard_Library.Adafinal;");
499      end if;
500
501      WBI ("   end " & Ada_Final_Name.all & ";");
502      WBI ("");
503   end Gen_Adafinal;
504
505   -----------------
506   -- Gen_Adainit --
507   -----------------
508
509   procedure Gen_Adainit (Elab_Order : Unit_Id_Array) is
510      Main_Priority : Int renames ALIs.Table (ALIs.First).Main_Priority;
511      Main_CPU      : Int renames ALIs.Table (ALIs.First).Main_CPU;
512
513   begin
514      --  Declare the access-to-subprogram type used for initialization of
515      --  of __gnat_finalize_library_objects. This is declared at library
516      --  level for compatibility with the type used in System.Soft_Links.
517      --  The import of the soft link which performs library-level object
518      --  finalization does not work for CodePeer, so regular Ada is used in
519      --  that case. For restricted run-time libraries (ZFP and Ravenscar)
520      --  tasks are non-terminating, so we do not want finalization.
521
522      if not Suppress_Standard_Library_On_Target
523        and then not CodePeer_Mode
524        and then not Configurable_Run_Time_On_Target
525      then
526         WBI ("   type No_Param_Proc is access procedure;");
527         WBI ("   pragma Favor_Top_Level (No_Param_Proc);");
528         WBI ("");
529      end if;
530
531      WBI ("   procedure " & Ada_Init_Name.all & " is");
532
533      --  In CodePeer mode, simplify adainit procedure by only calling
534      --  elaboration procedures.
535
536      if CodePeer_Mode then
537         WBI ("   begin");
538
539      --  If the standard library is suppressed, then the only global variables
540      --  that might be needed (by the Ravenscar profile) are the priority and
541      --  the processor for the environment task.
542
543      elsif Suppress_Standard_Library_On_Target then
544         if Main_Priority /= No_Main_Priority then
545            WBI ("      Main_Priority : Integer;");
546            WBI ("      pragma Import (C, Main_Priority," &
547                 " ""__gl_main_priority"");");
548            WBI ("");
549         end if;
550
551         if Main_CPU /= No_Main_CPU then
552            WBI ("      Main_CPU : Integer;");
553            WBI ("      pragma Import (C, Main_CPU," &
554                 " ""__gl_main_cpu"");");
555            WBI ("");
556         end if;
557
558         if System_Interrupts_Used
559           and then Partition_Elaboration_Policy_Specified = 'S'
560         then
561            WBI ("      procedure Install_Restricted_Handlers_Sequential;");
562            WBI ("      pragma Import (C," &
563                 "Install_Restricted_Handlers_Sequential," &
564                 " ""__gnat_attach_all_handlers"");");
565            WBI ("");
566         end if;
567
568         if System_Tasking_Restricted_Stages_Used
569           and then Partition_Elaboration_Policy_Specified = 'S'
570         then
571            WBI ("      Partition_Elaboration_Policy : Character;");
572            WBI ("      pragma Import (C, Partition_Elaboration_Policy," &
573                 " ""__gnat_partition_elaboration_policy"");");
574            WBI ("");
575            WBI ("      procedure Activate_All_Tasks_Sequential;");
576            WBI ("      pragma Import (C, Activate_All_Tasks_Sequential," &
577                 " ""__gnat_activate_all_tasks"");");
578            WBI ("");
579         end if;
580
581         if System_BB_CPU_Primitives_Multiprocessors_Used then
582            WBI ("      procedure Start_Slave_CPUs;");
583            WBI ("      pragma Import (C, Start_Slave_CPUs," &
584                 " ""__gnat_start_slave_cpus"");");
585            WBI ("");
586         end if;
587
588         if System_Secondary_Stack_Package_In_Closure then
589            --  System.Secondary_Stack is in the closure of the program
590            --  because the program uses the secondary stack or the restricted
591            --  run-time is unconditionally calling SS_Init. In both cases,
592            --  SS_Init needs to know the number of secondary stacks created by
593            --  the binder.
594
595            WBI ("      Binder_Sec_Stacks_Count : Natural;");
596            WBI ("      pragma Import (Ada, Binder_Sec_Stacks_Count, " &
597                 """__gnat_binder_ss_count"");");
598            WBI ("");
599
600            --  Import secondary stack pool variables if the secondary stack
601            --  used. They are not referenced otherwise.
602
603            if Sec_Stack_Used then
604               WBI ("      Default_Secondary_Stack_Size : " &
605                    "System.Parameters.Size_Type;");
606               WBI ("      pragma Import (C, Default_Secondary_Stack_Size, " &
607                    """__gnat_default_ss_size"");");
608
609               WBI ("      Default_Sized_SS_Pool : System.Address;");
610               WBI ("      pragma Import (Ada, Default_Sized_SS_Pool, " &
611                    """__gnat_default_ss_pool"");");
612
613               WBI ("");
614            end if;
615         end if;
616
617         WBI ("   begin");
618
619         if Main_Priority /= No_Main_Priority then
620            Set_String ("      Main_Priority := ");
621            Set_Int    (Main_Priority);
622            Set_Char   (';');
623            Write_Statement_Buffer;
624         end if;
625
626         if Main_CPU /= No_Main_CPU then
627            Set_String ("      Main_CPU := ");
628            Set_Int    (Main_CPU);
629            Set_Char   (';');
630            Write_Statement_Buffer;
631         end if;
632
633         if System_Tasking_Restricted_Stages_Used
634           and then Partition_Elaboration_Policy_Specified = 'S'
635         then
636            Set_String ("      Partition_Elaboration_Policy := '");
637            Set_Char   (Partition_Elaboration_Policy_Specified);
638            Set_String ("';");
639            Write_Statement_Buffer;
640         end if;
641
642         if Main_Priority = No_Main_Priority
643           and then Main_CPU = No_Main_CPU
644           and then not System_Tasking_Restricted_Stages_Used
645         then
646            WBI ("      null;");
647         end if;
648
649         --  Generate the default-sized secondary stack pool if the secondary
650         --  stack is used by the program.
651
652         if System_Secondary_Stack_Package_In_Closure then
653            if Sec_Stack_Used then
654               --  Elaborate the body of the binder to initialize the default-
655               --  sized secondary stack pool.
656
657               WBI ("");
658               WBI ("      " & Get_Ada_Main_Name & "'Elab_Body;");
659
660               --  Generate the default-sized secondary stack pool and set the
661               --  related secondary stack globals.
662
663               Set_String ("      Default_Secondary_Stack_Size := ");
664
665               if Opt.Default_Sec_Stack_Size /= Opt.No_Stack_Size then
666                  Set_Int (Opt.Default_Sec_Stack_Size);
667               else
668                  Set_String
669                    ("System.Parameters.Runtime_Default_Sec_Stack_Size");
670               end if;
671
672               Set_Char (';');
673               Write_Statement_Buffer;
674
675               Set_String ("      Binder_Sec_Stacks_Count := ");
676               Set_Int (Num_Sec_Stacks);
677               Set_Char (';');
678               Write_Statement_Buffer;
679
680               WBI ("      Default_Sized_SS_Pool := " &
681                      "Sec_Default_Sized_Stacks'Address;");
682               WBI ("");
683
684            else
685               --  The presence of System.Secondary_Stack in the closure of the
686               --  program implies the restricted run-time is unconditionally
687               --  calling SS_Init. Let SS_Init know that no stacks were
688               --  created.
689
690               WBI ("      Binder_Sec_Stacks_Count := 0;");
691            end if;
692         end if;
693
694      --  Normal case (standard library not suppressed). Set all global values
695      --  used by the run time.
696
697      else
698         WBI ("      Main_Priority : Integer;");
699         WBI ("      pragma Import (C, Main_Priority, " &
700              """__gl_main_priority"");");
701         WBI ("      Time_Slice_Value : Integer;");
702         WBI ("      pragma Import (C, Time_Slice_Value, " &
703              """__gl_time_slice_val"");");
704         WBI ("      WC_Encoding : Character;");
705         WBI ("      pragma Import (C, WC_Encoding, ""__gl_wc_encoding"");");
706         WBI ("      Locking_Policy : Character;");
707         WBI ("      pragma Import (C, Locking_Policy, " &
708              """__gl_locking_policy"");");
709         WBI ("      Queuing_Policy : Character;");
710         WBI ("      pragma Import (C, Queuing_Policy, " &
711              """__gl_queuing_policy"");");
712         WBI ("      Task_Dispatching_Policy : Character;");
713         WBI ("      pragma Import (C, Task_Dispatching_Policy, " &
714              """__gl_task_dispatching_policy"");");
715         WBI ("      Priority_Specific_Dispatching : System.Address;");
716         WBI ("      pragma Import (C, Priority_Specific_Dispatching, " &
717              """__gl_priority_specific_dispatching"");");
718         WBI ("      Num_Specific_Dispatching : Integer;");
719         WBI ("      pragma Import (C, Num_Specific_Dispatching, " &
720              """__gl_num_specific_dispatching"");");
721         WBI ("      Main_CPU : Integer;");
722         WBI ("      pragma Import (C, Main_CPU, " &
723              """__gl_main_cpu"");");
724
725         WBI ("      Interrupt_States : System.Address;");
726         WBI ("      pragma Import (C, Interrupt_States, " &
727              """__gl_interrupt_states"");");
728         WBI ("      Num_Interrupt_States : Integer;");
729         WBI ("      pragma Import (C, Num_Interrupt_States, " &
730              """__gl_num_interrupt_states"");");
731         WBI ("      Unreserve_All_Interrupts : Integer;");
732         WBI ("      pragma Import (C, Unreserve_All_Interrupts, " &
733              """__gl_unreserve_all_interrupts"");");
734
735         if Exception_Tracebacks or Exception_Tracebacks_Symbolic then
736            WBI ("      Exception_Tracebacks : Integer;");
737            WBI ("      pragma Import (C, Exception_Tracebacks, " &
738                 """__gl_exception_tracebacks"");");
739
740            if Exception_Tracebacks_Symbolic then
741               WBI ("      Exception_Tracebacks_Symbolic : Integer;");
742               WBI ("      pragma Import (C, Exception_Tracebacks_Symbolic, " &
743                    """__gl_exception_tracebacks_symbolic"");");
744            end if;
745         end if;
746
747         WBI ("      Detect_Blocking : Integer;");
748         WBI ("      pragma Import (C, Detect_Blocking, " &
749              """__gl_detect_blocking"");");
750         WBI ("      Default_Stack_Size : Integer;");
751         WBI ("      pragma Import (C, Default_Stack_Size, " &
752              """__gl_default_stack_size"");");
753
754         if Sec_Stack_Used then
755            WBI ("      Default_Secondary_Stack_Size : " &
756                 "System.Parameters.Size_Type;");
757            WBI ("      pragma Import (C, Default_Secondary_Stack_Size, " &
758                 """__gnat_default_ss_size"");");
759         end if;
760
761         WBI ("      Leap_Seconds_Support : Integer;");
762         WBI ("      pragma Import (C, Leap_Seconds_Support, " &
763              """__gl_leap_seconds_support"");");
764         WBI ("      Bind_Env_Addr : System.Address;");
765         WBI ("      pragma Import (C, Bind_Env_Addr, " &
766              """__gl_bind_env_addr"");");
767
768         --  Import entry point for elaboration time signal handler
769         --  installation, and indication of if it's been called previously.
770
771         WBI ("");
772         WBI ("      procedure Runtime_Initialize " &
773              "(Install_Handler : Integer);");
774         WBI ("      pragma Import (C, Runtime_Initialize, " &
775              """__gnat_runtime_initialize"");");
776
777         --  Import handlers attach procedure for sequential elaboration policy
778
779         if System_Interrupts_Used
780           and then Partition_Elaboration_Policy_Specified = 'S'
781         then
782            WBI ("      procedure Install_Restricted_Handlers_Sequential;");
783            WBI ("      pragma Import (C," &
784                 "Install_Restricted_Handlers_Sequential," &
785                 " ""__gnat_attach_all_handlers"");");
786            WBI ("");
787         end if;
788
789         --  Import task activation procedure for sequential elaboration
790         --  policy.
791
792         if System_Tasking_Restricted_Stages_Used
793           and then Partition_Elaboration_Policy_Specified = 'S'
794         then
795            WBI ("      Partition_Elaboration_Policy : Character;");
796            WBI ("      pragma Import (C, Partition_Elaboration_Policy," &
797                 " ""__gnat_partition_elaboration_policy"");");
798            WBI ("");
799            WBI ("      procedure Activate_All_Tasks_Sequential;");
800            WBI ("      pragma Import (C, Activate_All_Tasks_Sequential," &
801                 " ""__gnat_activate_all_tasks"");");
802         end if;
803
804         --  Import procedure to start slave cpus for bareboard runtime
805
806         if System_BB_CPU_Primitives_Multiprocessors_Used then
807            WBI ("      procedure Start_Slave_CPUs;");
808            WBI ("      pragma Import (C, Start_Slave_CPUs," &
809                 " ""__gnat_start_slave_cpus"");");
810         end if;
811
812         --  For restricted run-time libraries (ZFP and Ravenscar)
813         --  tasks are non-terminating, so we do not want finalization.
814
815         if not Configurable_Run_Time_On_Target then
816            WBI ("");
817            WBI ("      Finalize_Library_Objects : No_Param_Proc;");
818            WBI ("      pragma Import (C, Finalize_Library_Objects, " &
819                 """__gnat_finalize_library_objects"");");
820         end if;
821
822         --  Initialize stack limit variable of the environment task if the
823         --  stack check method is stack limit and stack check is enabled.
824
825         if Stack_Check_Limits_On_Target
826           and then (Stack_Check_Default_On_Target or Stack_Check_Switch_Set)
827         then
828            WBI ("");
829            WBI ("      procedure Initialize_Stack_Limit;");
830            WBI ("      pragma Import (C, Initialize_Stack_Limit, " &
831                 """__gnat_initialize_stack_limit"");");
832         end if;
833
834         --  When dispatching domains are used then we need to signal it
835         --  before calling the main procedure.
836
837         if Dispatching_Domains_Used then
838            WBI ("      procedure Freeze_Dispatching_Domains;");
839            WBI ("      pragma Import");
840            WBI ("        (Ada, Freeze_Dispatching_Domains, "
841                 & """__gnat_freeze_dispatching_domains"");");
842         end if;
843
844         --  Secondary stack global variables
845
846         WBI ("      Binder_Sec_Stacks_Count : Natural;");
847         WBI ("      pragma Import (Ada, Binder_Sec_Stacks_Count, " &
848              """__gnat_binder_ss_count"");");
849
850         WBI ("      Default_Sized_SS_Pool : System.Address;");
851         WBI ("      pragma Import (Ada, Default_Sized_SS_Pool, " &
852              """__gnat_default_ss_pool"");");
853
854         WBI ("");
855
856         --  Start of processing for Adainit
857
858         WBI ("   begin");
859         WBI ("      if Is_Elaborated then");
860         WBI ("         return;");
861         WBI ("      end if;");
862         WBI ("      Is_Elaborated := True;");
863
864         --  Call System.Elaboration_Allocators.Mark_Start_Of_Elaboration if
865         --  restriction No_Standard_Allocators_After_Elaboration is active.
866
867         if Cumulative_Restrictions.Set
868              (No_Standard_Allocators_After_Elaboration)
869         then
870            WBI ("      System.Elaboration_Allocators."
871                 & "Mark_Start_Of_Elaboration;");
872         end if;
873
874         --  Generate assignments to initialize globals
875
876         Set_String ("      Main_Priority := ");
877         Set_Int    (Main_Priority);
878         Set_Char   (';');
879         Write_Statement_Buffer;
880
881         Set_String ("      Time_Slice_Value := ");
882
883         if Task_Dispatching_Policy_Specified = 'F'
884           and then ALIs.Table (ALIs.First).Time_Slice_Value = -1
885         then
886            Set_Int (0);
887         else
888            Set_Int (ALIs.Table (ALIs.First).Time_Slice_Value);
889         end if;
890
891         Set_Char   (';');
892         Write_Statement_Buffer;
893
894         Set_String ("      WC_Encoding := '");
895         Set_Char   (Get_WC_Encoding);
896
897         Set_String ("';");
898         Write_Statement_Buffer;
899
900         Set_String ("      Locking_Policy := '");
901         Set_Char   (Locking_Policy_Specified);
902         Set_String ("';");
903         Write_Statement_Buffer;
904
905         Set_String ("      Queuing_Policy := '");
906         Set_Char   (Queuing_Policy_Specified);
907         Set_String ("';");
908         Write_Statement_Buffer;
909
910         Set_String ("      Task_Dispatching_Policy := '");
911         Set_Char   (Task_Dispatching_Policy_Specified);
912         Set_String ("';");
913         Write_Statement_Buffer;
914
915         if System_Tasking_Restricted_Stages_Used
916           and then Partition_Elaboration_Policy_Specified = 'S'
917         then
918            Set_String ("      Partition_Elaboration_Policy := '");
919            Set_Char   (Partition_Elaboration_Policy_Specified);
920            Set_String ("';");
921            Write_Statement_Buffer;
922         end if;
923
924         Gen_Restrictions;
925
926         WBI ("      Priority_Specific_Dispatching :=");
927         WBI ("        Local_Priority_Specific_Dispatching'Address;");
928
929         Set_String ("      Num_Specific_Dispatching := ");
930         Set_Int (PSD_Pragma_Settings.Last + 1);
931         Set_Char (';');
932         Write_Statement_Buffer;
933
934         Set_String ("      Main_CPU := ");
935         Set_Int    (Main_CPU);
936         Set_Char   (';');
937         Write_Statement_Buffer;
938
939         WBI ("      Interrupt_States := Local_Interrupt_States'Address;");
940
941         Set_String ("      Num_Interrupt_States := ");
942         Set_Int (IS_Pragma_Settings.Last + 1);
943         Set_Char (';');
944         Write_Statement_Buffer;
945
946         Set_String ("      Unreserve_All_Interrupts := ");
947
948         if Unreserve_All_Interrupts_Specified then
949            Set_String ("1");
950         else
951            Set_String ("0");
952         end if;
953
954         Set_Char (';');
955         Write_Statement_Buffer;
956
957         if Exception_Tracebacks or Exception_Tracebacks_Symbolic then
958            WBI ("      Exception_Tracebacks := 1;");
959
960            if Exception_Tracebacks_Symbolic then
961               WBI ("      Exception_Tracebacks_Symbolic := 1;");
962            end if;
963         end if;
964
965         Set_String ("      Detect_Blocking := ");
966
967         if Detect_Blocking then
968            Set_Int (1);
969         else
970            Set_Int (0);
971         end if;
972
973         Set_String (";");
974         Write_Statement_Buffer;
975
976         Set_String ("      Default_Stack_Size := ");
977         Set_Int (Default_Stack_Size);
978         Set_String (";");
979         Write_Statement_Buffer;
980
981         Set_String ("      Leap_Seconds_Support := ");
982
983         if Leap_Seconds_Support then
984            Set_Int (1);
985         else
986            Set_Int (0);
987         end if;
988
989         Set_String (";");
990         Write_Statement_Buffer;
991
992         if Bind_Env_String_Built then
993            WBI ("      Bind_Env_Addr := Bind_Env'Address;");
994         end if;
995
996         WBI ("");
997
998         --  Generate default-sized secondary stack pool and set secondary
999         --  stack globals.
1000
1001         if Sec_Stack_Used then
1002
1003            --  Elaborate the body of the binder to initialize the default-
1004            --  sized secondary stack pool.
1005
1006            WBI ("      " & Get_Ada_Main_Name & "'Elab_Body;");
1007
1008            --  Generate the default-sized secondary stack pool and set the
1009            --  related secondary stack globals.
1010
1011            Set_String ("      Default_Secondary_Stack_Size := ");
1012
1013            if Opt.Default_Sec_Stack_Size /= Opt.No_Stack_Size then
1014               Set_Int (Opt.Default_Sec_Stack_Size);
1015            else
1016               Set_String ("System.Parameters.Runtime_Default_Sec_Stack_Size");
1017            end if;
1018
1019            Set_Char (';');
1020            Write_Statement_Buffer;
1021
1022            Set_String ("      Binder_Sec_Stacks_Count := ");
1023            Set_Int (Num_Sec_Stacks);
1024            Set_Char (';');
1025            Write_Statement_Buffer;
1026
1027            Set_String ("      Default_Sized_SS_Pool := ");
1028
1029            if Num_Sec_Stacks > 0 then
1030               Set_String ("Sec_Default_Sized_Stacks'Address;");
1031            else
1032               Set_String ("System.Null_Address;");
1033            end if;
1034
1035            Write_Statement_Buffer;
1036            WBI ("");
1037         end if;
1038
1039         --  Generate call to Runtime_Initialize
1040
1041         WBI ("      Runtime_Initialize (1);");
1042      end if;
1043
1044      --  Generate call to set Initialize_Scalar values if active
1045
1046      if Initialize_Scalars_Used then
1047         WBI ("");
1048         Set_String ("      System.Scalar_Values.Initialize ('");
1049         Set_Char (Initialize_Scalars_Mode1);
1050         Set_String ("', '");
1051         Set_Char (Initialize_Scalars_Mode2);
1052         Set_String ("');");
1053         Write_Statement_Buffer;
1054      end if;
1055
1056      --  Initialize stack limit variable of the environment task if the stack
1057      --  check method is stack limit and stack check is enabled.
1058
1059      if Stack_Check_Limits_On_Target
1060        and then (Stack_Check_Default_On_Target or Stack_Check_Switch_Set)
1061      then
1062         WBI ("");
1063         WBI ("      Initialize_Stack_Limit;");
1064      end if;
1065
1066      --  On CodePeer, the finalization of library objects is not relevant
1067
1068      if CodePeer_Mode then
1069         null;
1070
1071      --  If this is the main program case, attach finalize_library to the soft
1072      --  link. Do it only when not using a restricted run time, in which case
1073      --  tasks are non-terminating, so we do not want library-level
1074      --  finalization.
1075
1076      elsif not Bind_For_Library
1077        and then not Configurable_Run_Time_On_Target
1078        and then not Suppress_Standard_Library_On_Target
1079      then
1080         WBI ("");
1081
1082         if Lib_Final_Built then
1083            Set_String ("      Finalize_Library_Objects := ");
1084            Set_String ("finalize_library'access;");
1085         else
1086            Set_String ("      Finalize_Library_Objects := null;");
1087         end if;
1088
1089         Write_Statement_Buffer;
1090      end if;
1091
1092      --  Generate elaboration calls
1093
1094      if not CodePeer_Mode then
1095         WBI ("");
1096      end if;
1097
1098      Gen_Elab_Calls (Elab_Order);
1099
1100      if not CodePeer_Mode then
1101
1102         --  Call System.Elaboration_Allocators.Mark_Start_Of_Elaboration if
1103         --  restriction No_Standard_Allocators_After_Elaboration is active.
1104
1105         if Cumulative_Restrictions.Set
1106              (No_Standard_Allocators_After_Elaboration)
1107         then
1108            WBI
1109              ("      System.Elaboration_Allocators.Mark_End_Of_Elaboration;");
1110         end if;
1111
1112         --  From this point, no new dispatching domain can be created
1113
1114         if Dispatching_Domains_Used then
1115            WBI ("      Freeze_Dispatching_Domains;");
1116         end if;
1117
1118         --  Sequential partition elaboration policy
1119
1120         if Partition_Elaboration_Policy_Specified = 'S' then
1121            if System_Interrupts_Used then
1122               WBI ("      Install_Restricted_Handlers_Sequential;");
1123            end if;
1124
1125            if System_Tasking_Restricted_Stages_Used then
1126               WBI ("      Activate_All_Tasks_Sequential;");
1127            end if;
1128         end if;
1129
1130         if System_BB_CPU_Primitives_Multiprocessors_Used then
1131            WBI ("      Start_Slave_CPUs;");
1132         end if;
1133      end if;
1134
1135      WBI ("   end " & Ada_Init_Name.all & ";");
1136      WBI ("");
1137   end Gen_Adainit;
1138
1139   -------------------------
1140   -- Gen_Bind_Env_String --
1141   -------------------------
1142
1143   procedure Gen_Bind_Env_String is
1144      procedure Write_Name_With_Len (Nam : Name_Id);
1145      --  Write Nam as a string literal, prefixed with one
1146      --  character encoding Nam's length.
1147
1148      -------------------------
1149      -- Write_Name_With_Len --
1150      -------------------------
1151
1152      procedure Write_Name_With_Len (Nam : Name_Id) is
1153      begin
1154         Get_Name_String (Nam);
1155
1156         Start_String;
1157         Store_String_Char (Character'Val (Name_Len));
1158         Store_String_Chars (Name_Buffer (1 .. Name_Len));
1159
1160         Write_String_Table_Entry (End_String);
1161      end Write_Name_With_Len;
1162
1163      --  Local variables
1164
1165      Amp : Character;
1166      KN  : Name_Id := No_Name;
1167      VN  : Name_Id := No_Name;
1168
1169   --  Start of processing for Gen_Bind_Env_String
1170
1171   begin
1172      Bind_Environment.Get_First (KN, VN);
1173
1174      if VN = No_Name then
1175         return;
1176      end if;
1177
1178      Set_Special_Output (Write_Bind_Line'Access);
1179
1180      WBI ("   Bind_Env : aliased constant String :=");
1181      Amp := ' ';
1182      while VN /= No_Name loop
1183         Write_Str ("     " & Amp & ' ');
1184         Write_Name_With_Len (KN);
1185         Write_Str (" & ");
1186         Write_Name_With_Len (VN);
1187         Write_Eol;
1188
1189         Bind_Environment.Get_Next (KN, VN);
1190         Amp := '&';
1191      end loop;
1192      WBI ("     & ASCII.NUL;");
1193
1194      Cancel_Special_Output;
1195
1196      Bind_Env_String_Built := True;
1197   end Gen_Bind_Env_String;
1198
1199   --------------------------
1200   -- Gen_CodePeer_Wrapper --
1201   --------------------------
1202
1203   procedure Gen_CodePeer_Wrapper is
1204      Callee_Name : constant String := "Ada_Main_Program";
1205
1206   begin
1207      if ALIs.Table (ALIs.First).Main_Program = Proc then
1208         WBI ("   procedure " & CodePeer_Wrapper_Name & " is ");
1209         WBI ("   begin");
1210         WBI ("      " & Callee_Name & ";");
1211
1212      else
1213         WBI ("   function " & CodePeer_Wrapper_Name & " return Integer is");
1214         WBI ("   begin");
1215         WBI ("      return " & Callee_Name & ";");
1216      end if;
1217
1218      WBI ("   end " & CodePeer_Wrapper_Name & ";");
1219      WBI ("");
1220   end Gen_CodePeer_Wrapper;
1221
1222   --------------------
1223   -- Gen_Elab_Calls --
1224   --------------------
1225
1226   procedure Gen_Elab_Calls (Elab_Order : Unit_Id_Array) is
1227      Check_Elab_Flag : Boolean;
1228
1229   begin
1230      --  Loop through elaboration order entries
1231
1232      for E in Elab_Order'Range loop
1233         declare
1234            Unum : constant Unit_Id := Elab_Order (E);
1235            U    : Unit_Record renames Units.Table (Unum);
1236
1237            Unum_Spec : Unit_Id;
1238            --  This is the unit number of the spec that corresponds to
1239            --  this entry. It is the same as Unum except when the body
1240            --  and spec are different and we are currently processing
1241            --  the body, in which case it is the spec (Unum + 1).
1242
1243         begin
1244            if U.Utype = Is_Body then
1245               Unum_Spec := Unum + 1;
1246            else
1247               Unum_Spec := Unum;
1248            end if;
1249
1250            --  Nothing to do if predefined unit in no run time mode
1251
1252            if No_Run_Time_Mode and then Is_Predefined_File_Name (U.Sfile) then
1253               null;
1254
1255            --  Likewise if this is an interface to a stand alone library
1256
1257            elsif U.SAL_Interface then
1258               null;
1259
1260            --  Case of no elaboration code
1261
1262            elsif U.No_Elab
1263
1264              --  In CodePeer mode, we special case subprogram bodies which
1265              --  are handled in the 'else' part below, and lead to a call
1266              --  to <subp>'Elab_Subp_Body.
1267
1268              and then (not CodePeer_Mode
1269
1270                         --  Test for spec
1271
1272                         or else U.Utype = Is_Spec
1273                         or else U.Utype = Is_Spec_Only
1274                         or else U.Unit_Kind /= 's')
1275            then
1276               --  In the case of a body with a separate spec, where the
1277               --  separate spec has an elaboration entity defined, this is
1278               --  where we increment the elaboration entity if one exists.
1279
1280               --  Likewise for lone specs with an elaboration entity defined
1281               --  despite No_Elaboration_Code, e.g. when requested to preserve
1282               --  control flow.
1283
1284               if (U.Utype = Is_Body or else U.Utype = Is_Spec_Only)
1285                 and then Units.Table (Unum_Spec).Set_Elab_Entity
1286                 and then not CodePeer_Mode
1287               then
1288                  Set_String ("      E");
1289                  Set_Unit_Number (Unum_Spec);
1290                  Set_String (" := E");
1291                  Set_Unit_Number (Unum_Spec);
1292                  Set_String (" + 1;");
1293                  Write_Statement_Buffer;
1294               end if;
1295
1296            --  Here if elaboration code is present. If binding a library
1297            --  or if there is a non-Ada main subprogram then we generate:
1298
1299            --    if uname_E = 0 then
1300            --       uname'elab_[spec|body];
1301            --    end if;
1302            --    uname_E := uname_E + 1;
1303
1304            --  Otherwise, elaboration routines are called unconditionally:
1305
1306            --    uname'elab_[spec|body];
1307            --    uname_E := uname_E + 1;
1308
1309            --  The uname_E increment is skipped if this is a separate spec,
1310            --  since it will be done when we process the body.
1311
1312            --  In CodePeer mode, we do not generate any reference to xxx_E
1313            --  variables, only calls to 'Elab* subprograms.
1314
1315            else
1316               --  Check incompatibilities with No_Multiple_Elaboration
1317
1318               if not CodePeer_Mode
1319                 and then Cumulative_Restrictions.Set (No_Multiple_Elaboration)
1320               then
1321                  --  Force_Checking_Of_Elaboration_Flags (-F) not allowed
1322
1323                  if Force_Checking_Of_Elaboration_Flags then
1324                     Osint.Fail
1325                       ("-F (force elaboration checks) switch not allowed "
1326                        & "with restriction No_Multiple_Elaboration active");
1327
1328                  --  Interfacing of libraries not allowed
1329
1330                  elsif Interface_Library_Unit then
1331                     Osint.Fail
1332                       ("binding of interfaced libraries not allowed "
1333                        & "with restriction No_Multiple_Elaboration active");
1334
1335                  --  Non-Ada main program not allowed
1336
1337                  elsif not Bind_Main_Program then
1338                     Osint.Fail
1339                       ("non-Ada main program not allowed "
1340                        & "with restriction No_Multiple_Elaboration active");
1341                  end if;
1342               end if;
1343
1344               --  OK, see if we need to test elaboration flag
1345
1346               Check_Elab_Flag :=
1347                 Units.Table (Unum_Spec).Set_Elab_Entity
1348                   and then not CodePeer_Mode
1349                   and then (Force_Checking_Of_Elaboration_Flags
1350                              or Interface_Library_Unit
1351                              or not Bind_Main_Program);
1352
1353               if Check_Elab_Flag then
1354                  Set_String ("      if E");
1355                  Set_Unit_Number (Unum_Spec);
1356                  Set_String (" = 0 then");
1357                  Write_Statement_Buffer;
1358                  Set_String ("   ");
1359               end if;
1360
1361               Set_String ("      ");
1362               Get_Decoded_Name_String_With_Brackets (U.Uname);
1363
1364               if Name_Buffer (Name_Len) = 's' then
1365                  Name_Buffer (Name_Len - 1 .. Name_Len + 8) :=
1366                    "'elab_spec";
1367                  Name_Len := Name_Len + 8;
1368
1369               --  Special case in CodePeer mode for subprogram bodies
1370               --  which correspond to CodePeer 'Elab_Subp_Body special
1371               --  init procedure.
1372
1373               elsif U.Unit_Kind = 's' and CodePeer_Mode then
1374                  Name_Buffer (Name_Len - 1 .. Name_Len + 13) :=
1375                    "'elab_subp_body";
1376                  Name_Len := Name_Len + 13;
1377
1378               else
1379                  Name_Buffer (Name_Len - 1 .. Name_Len + 8) :=
1380                    "'elab_body";
1381                  Name_Len := Name_Len + 8;
1382               end if;
1383
1384               Set_Casing (U.Icasing);
1385               Set_Name_Buffer;
1386               Set_Char (';');
1387               Write_Statement_Buffer;
1388
1389               if Check_Elab_Flag then
1390                  WBI ("      end if;");
1391               end if;
1392
1393               if U.Utype /= Is_Spec
1394                 and then not CodePeer_Mode
1395                 and then Units.Table (Unum_Spec).Set_Elab_Entity
1396               then
1397                  Set_String ("      E");
1398                  Set_Unit_Number (Unum_Spec);
1399                  Set_String (" := E");
1400                  Set_Unit_Number (Unum_Spec);
1401                  Set_String (" + 1;");
1402                  Write_Statement_Buffer;
1403               end if;
1404            end if;
1405         end;
1406      end loop;
1407   end Gen_Elab_Calls;
1408
1409   ------------------------
1410   -- Gen_Elab_Externals --
1411   ------------------------
1412
1413   procedure Gen_Elab_Externals (Elab_Order : Unit_Id_Array) is
1414   begin
1415      if CodePeer_Mode then
1416         return;
1417      end if;
1418
1419      for E in Elab_Order'Range loop
1420         declare
1421            Unum : constant Unit_Id := Elab_Order (E);
1422            U    : Unit_Record renames Units.Table (Unum);
1423
1424         begin
1425            --  Check for Elab_Entity to be set for this unit
1426
1427            if U.Set_Elab_Entity
1428
1429              --  Don't generate reference for stand alone library
1430
1431              and then not U.SAL_Interface
1432
1433              --  Don't generate reference for predefined file in No_Run_Time
1434              --  mode, since we don't include the object files in this case
1435
1436              and then not
1437                (No_Run_Time_Mode
1438                  and then Is_Predefined_File_Name (U.Sfile))
1439            then
1440               Get_Name_String (U.Sfile);
1441               Set_String ("   ");
1442               Set_String ("E");
1443               Set_Unit_Number (Unum);
1444               Set_String (" : Short_Integer; pragma Import (Ada, E");
1445               Set_Unit_Number (Unum);
1446               Set_String (", """);
1447               Get_Name_String (U.Uname);
1448               Set_Unit_Name;
1449               Set_String ("_E"");");
1450               Write_Statement_Buffer;
1451            end if;
1452         end;
1453      end loop;
1454
1455      WBI ("");
1456   end Gen_Elab_Externals;
1457
1458   --------------------
1459   -- Gen_Elab_Order --
1460   --------------------
1461
1462   procedure Gen_Elab_Order (Elab_Order : Unit_Id_Array) is
1463   begin
1464      WBI ("");
1465      WBI ("   --  BEGIN ELABORATION ORDER");
1466
1467      for J in Elab_Order'Range loop
1468         Set_String ("   --  ");
1469         Get_Name_String (Units.Table (Elab_Order (J)).Uname);
1470         Set_Name_Buffer;
1471         Write_Statement_Buffer;
1472      end loop;
1473
1474      WBI ("   --  END ELABORATION ORDER");
1475   end Gen_Elab_Order;
1476
1477   --------------------------
1478   -- Gen_Finalize_Library --
1479   --------------------------
1480
1481   procedure Gen_Finalize_Library (Elab_Order : Unit_Id_Array) is
1482      procedure Gen_Header;
1483      --  Generate the header of the finalization routine
1484
1485      ----------------
1486      -- Gen_Header --
1487      ----------------
1488
1489      procedure Gen_Header is
1490      begin
1491         WBI ("   procedure finalize_library is");
1492         WBI ("   begin");
1493      end Gen_Header;
1494
1495      --  Local variables
1496
1497      Count : Int := 1;
1498      U     : Unit_Record;
1499      Uspec : Unit_Record;
1500      Unum  : Unit_Id;
1501
1502   --  Start of processing for Gen_Finalize_Library
1503
1504   begin
1505      if CodePeer_Mode then
1506         return;
1507      end if;
1508
1509      for E in reverse Elab_Order'Range loop
1510         Unum := Elab_Order (E);
1511         U    := Units.Table (Unum);
1512
1513         --  Dealing with package bodies is a little complicated. In such
1514         --  cases we must retrieve the package spec since it contains the
1515         --  spec of the body finalizer.
1516
1517         if U.Utype = Is_Body then
1518            Unum  := Unum + 1;
1519            Uspec := Units.Table (Unum);
1520         else
1521            Uspec := U;
1522         end if;
1523
1524         Get_Name_String (Uspec.Uname);
1525
1526         --  We are only interested in non-generic packages
1527
1528         if U.Unit_Kind /= 'p' or else U.Is_Generic then
1529            null;
1530
1531         --  That aren't an interface to a stand alone library
1532
1533         elsif U.SAL_Interface then
1534            null;
1535
1536         --  Case of no finalization
1537
1538         elsif not U.Has_Finalizer then
1539
1540            --  The only case in which we have to do something is if this
1541            --  is a body, with a separate spec, where the separate spec
1542            --  has a finalizer. In that case, this is where we decrement
1543            --  the elaboration entity.
1544
1545            if U.Utype = Is_Body and then Uspec.Has_Finalizer then
1546               if not Lib_Final_Built then
1547                  Gen_Header;
1548                  Lib_Final_Built := True;
1549               end if;
1550
1551               Set_String ("      E");
1552               Set_Unit_Number (Unum);
1553               Set_String (" := E");
1554               Set_Unit_Number (Unum);
1555               Set_String (" - 1;");
1556               Write_Statement_Buffer;
1557            end if;
1558
1559         else
1560            if not Lib_Final_Built then
1561               Gen_Header;
1562               Lib_Final_Built := True;
1563            end if;
1564
1565            --  Generate:
1566            --    declare
1567            --       procedure F<Count>;
1568
1569            Set_String ("      declare");
1570            Write_Statement_Buffer;
1571
1572            Set_String ("         procedure F");
1573            Set_Int    (Count);
1574            Set_Char   (';');
1575            Write_Statement_Buffer;
1576
1577            --  Generate:
1578            --    pragma Import (Ada, F<Count>,
1579            --                  "xx__yy__finalize_[body|spec]");
1580
1581            Set_String ("         pragma Import (Ada, F");
1582            Set_Int (Count);
1583            Set_String (", """);
1584
1585            --  Perform name construction
1586
1587            Set_Unit_Name;
1588            Set_String ("__finalize_");
1589
1590            --  Package spec processing
1591
1592            if U.Utype = Is_Spec
1593              or else U.Utype = Is_Spec_Only
1594            then
1595               Set_String ("spec");
1596
1597            --  Package body processing
1598
1599            else
1600               Set_String ("body");
1601            end if;
1602
1603            Set_String (""");");
1604            Write_Statement_Buffer;
1605
1606            --  If binding a library or if there is a non-Ada main subprogram
1607            --  then we generate:
1608
1609            --    begin
1610            --       uname_E := uname_E - 1;
1611            --       if uname_E = 0 then
1612            --          F<Count>;
1613            --       end if;
1614            --    end;
1615
1616            --  Otherwise, finalization routines are called unconditionally:
1617
1618            --    begin
1619            --       uname_E := uname_E - 1;
1620            --       F<Count>;
1621            --    end;
1622
1623            --  The uname_E decrement is skipped if this is a separate spec,
1624            --  since it will be done when we process the body.
1625
1626            WBI ("      begin");
1627
1628            if U.Utype /= Is_Spec then
1629               Set_String ("         E");
1630               Set_Unit_Number (Unum);
1631               Set_String (" := E");
1632               Set_Unit_Number (Unum);
1633               Set_String (" - 1;");
1634               Write_Statement_Buffer;
1635            end if;
1636
1637            if Interface_Library_Unit or not Bind_Main_Program then
1638               Set_String ("         if E");
1639               Set_Unit_Number (Unum);
1640               Set_String (" = 0 then");
1641               Write_Statement_Buffer;
1642               Set_String ("   ");
1643            end if;
1644
1645            Set_String ("         F");
1646            Set_Int    (Count);
1647            Set_Char   (';');
1648            Write_Statement_Buffer;
1649
1650            if Interface_Library_Unit or not Bind_Main_Program then
1651               WBI ("         end if;");
1652            end if;
1653
1654            WBI ("      end;");
1655
1656            Count := Count + 1;
1657         end if;
1658      end loop;
1659
1660      if Lib_Final_Built then
1661
1662         --  It is possible that the finalization of a library-level object
1663         --  raised an exception. In that case import the actual exception
1664         --  and the routine necessary to raise it.
1665
1666         WBI ("      declare");
1667         WBI ("         procedure Reraise_Library_Exception_If_Any;");
1668
1669         Set_String ("            pragma Import (Ada, ");
1670         Set_String ("Reraise_Library_Exception_If_Any, ");
1671         Set_String ("""__gnat_reraise_library_exception_if_any"");");
1672         Write_Statement_Buffer;
1673
1674         WBI ("      begin");
1675         WBI ("         Reraise_Library_Exception_If_Any;");
1676         WBI ("      end;");
1677         WBI ("   end finalize_library;");
1678         WBI ("");
1679      end if;
1680   end Gen_Finalize_Library;
1681
1682   --------------
1683   -- Gen_Main --
1684   --------------
1685
1686   procedure Gen_Main is
1687   begin
1688      if not No_Main_Subprogram then
1689
1690         --  To call the main program, we declare it using a pragma Import
1691         --  Ada with the right link name.
1692
1693         --  It might seem more obvious to "with" the main program, and call
1694         --  it in the normal Ada manner. We do not do this for three
1695         --  reasons:
1696
1697         --    1. It is more efficient not to recompile the main program
1698         --    2. We are not entitled to assume the source is accessible
1699         --    3. We don't know what options to use to compile it
1700
1701         --  It is really reason 3 that is most critical (indeed we used
1702         --  to generate the "with", but several regression tests failed).
1703
1704         if ALIs.Table (ALIs.First).Main_Program = Func then
1705            WBI ("   function Ada_Main_Program return Integer;");
1706         else
1707            WBI ("   procedure Ada_Main_Program;");
1708         end if;
1709
1710         Set_String ("   pragma Import (Ada, Ada_Main_Program, """);
1711         Get_Name_String (Units.Table (First_Unit_Entry).Uname);
1712         Set_Main_Program_Name;
1713         Set_String (""");");
1714
1715         Write_Statement_Buffer;
1716         WBI ("");
1717
1718         --  For CodePeer, declare a wrapper for the user-defined main program
1719
1720         if CodePeer_Mode then
1721            Gen_CodePeer_Wrapper;
1722         end if;
1723      end if;
1724
1725      if Exit_Status_Supported_On_Target then
1726         Set_String ("   function ");
1727      else
1728         Set_String ("   procedure ");
1729      end if;
1730
1731      Set_String (Get_Main_Name);
1732
1733      if Command_Line_Args_On_Target then
1734         Write_Statement_Buffer;
1735         WBI ("     (argc : Integer;");
1736         WBI ("      argv : System.Address;");
1737         WBI ("      envp : System.Address)");
1738
1739         if Exit_Status_Supported_On_Target then
1740            WBI ("      return Integer");
1741         end if;
1742
1743         WBI ("   is");
1744
1745      else
1746         if Exit_Status_Supported_On_Target then
1747            Set_String (" return Integer is");
1748         else
1749            Set_String (" is");
1750         end if;
1751
1752         Write_Statement_Buffer;
1753      end if;
1754
1755      if Opt.Default_Exit_Status /= 0
1756        and then Bind_Main_Program
1757        and then not Configurable_Run_Time_Mode
1758      then
1759         WBI ("      procedure Set_Exit_Status (Status : Integer);");
1760         WBI ("      pragma Import (C, Set_Exit_Status, " &
1761                     """__gnat_set_exit_status"");");
1762         WBI ("");
1763      end if;
1764
1765      --  Initialize and Finalize
1766
1767      if not CodePeer_Mode
1768        and then not Cumulative_Restrictions.Set (No_Finalization)
1769      then
1770         WBI ("      procedure Initialize (Addr : System.Address);");
1771         WBI ("      pragma Import (C, Initialize, ""__gnat_initialize"");");
1772         WBI ("");
1773         WBI ("      procedure Finalize;");
1774         WBI ("      pragma Import (C, Finalize, ""__gnat_finalize"");");
1775      end if;
1776
1777      --  If we want to analyze the stack, we must import corresponding symbols
1778
1779      if Dynamic_Stack_Measurement then
1780         WBI ("");
1781         WBI ("      procedure Output_Results;");
1782         WBI ("      pragma Import (C, Output_Results, " &
1783              """__gnat_stack_usage_output_results"");");
1784
1785         WBI ("");
1786         WBI ("      " &
1787              "procedure Initialize_Stack_Analysis (Buffer_Size : Natural);");
1788         WBI ("      pragma Import (C, Initialize_Stack_Analysis, " &
1789              """__gnat_stack_usage_initialize"");");
1790      end if;
1791
1792      --  Deal with declarations for main program case
1793
1794      if not No_Main_Subprogram then
1795         if ALIs.Table (ALIs.First).Main_Program = Func then
1796            WBI ("      Result : Integer;");
1797            WBI ("");
1798         end if;
1799
1800         if Bind_Main_Program
1801           and not Suppress_Standard_Library_On_Target
1802           and not CodePeer_Mode
1803         then
1804            WBI ("      SEH : aliased array (1 .. 2) of Integer;");
1805            WBI ("");
1806         end if;
1807      end if;
1808
1809      --  Generate a reference to Ada_Main_Program_Name. This symbol is not
1810      --  referenced elsewhere in the generated program, but is needed by
1811      --  the debugger (that's why it is generated in the first place). The
1812      --  reference stops Ada_Main_Program_Name from being optimized away by
1813      --  smart linkers.
1814
1815      --  Because this variable is unused, we make this variable "aliased"
1816      --  with a pragma Volatile in order to tell the compiler to preserve
1817      --  this variable at any level of optimization.
1818
1819      --  CodePeer and CCG do not need this extra code. The code is also not
1820      --  needed if the binder is in "Minimal Binder" mode.
1821
1822      if Bind_Main_Program
1823        and then not Minimal_Binder
1824        and then not CodePeer_Mode
1825        and then not Generate_C_Code
1826      then
1827         WBI ("      Ensure_Reference : aliased System.Address := " &
1828              "Ada_Main_Program_Name'Address;");
1829         WBI ("      pragma Volatile (Ensure_Reference);");
1830         WBI ("");
1831      end if;
1832
1833      WBI ("   begin");
1834
1835      --  Acquire command-line arguments if present on target
1836
1837      if CodePeer_Mode then
1838         null;
1839
1840      elsif Command_Line_Args_On_Target then
1841
1842         --  Initialize gnat_argc/gnat_argv only if not already initialized,
1843         --  to avoid losing the result of any command-line processing done by
1844         --  earlier GNAT run-time initialization.
1845
1846         WBI ("      if gnat_argc = 0 then");
1847         WBI ("         gnat_argc := argc;");
1848         WBI ("         gnat_argv := argv;");
1849         WBI ("      end if;");
1850         WBI ("      gnat_envp := envp;");
1851         WBI ("");
1852
1853      --  If configurable run-time and no command-line args, then nothing needs
1854      --  to be done since the gnat_argc/argv/envp variables are suppressed in
1855      --  this case.
1856
1857      elsif Configurable_Run_Time_On_Target then
1858         null;
1859
1860      --  Otherwise set dummy values (to be filled in by some other unit?)
1861
1862      else
1863         WBI ("      gnat_argc := 0;");
1864         WBI ("      gnat_argv := System.Null_Address;");
1865         WBI ("      gnat_envp := System.Null_Address;");
1866      end if;
1867
1868      if Opt.Default_Exit_Status /= 0
1869        and then Bind_Main_Program
1870        and then not Configurable_Run_Time_Mode
1871      then
1872         Set_String ("      Set_Exit_Status (");
1873         Set_Int (Opt.Default_Exit_Status);
1874         Set_String (");");
1875         Write_Statement_Buffer;
1876      end if;
1877
1878      if Dynamic_Stack_Measurement then
1879         Set_String ("      Initialize_Stack_Analysis (");
1880         Set_Int (Dynamic_Stack_Measurement_Array_Size);
1881         Set_String (");");
1882         Write_Statement_Buffer;
1883      end if;
1884
1885      if not Cumulative_Restrictions.Set (No_Finalization)
1886        and then not CodePeer_Mode
1887      then
1888         if not No_Main_Subprogram
1889           and then Bind_Main_Program
1890           and then not Suppress_Standard_Library_On_Target
1891         then
1892            WBI ("      Initialize (SEH'Address);");
1893         else
1894            WBI ("      Initialize (System.Null_Address);");
1895         end if;
1896      end if;
1897
1898      WBI ("      " & Ada_Init_Name.all & ";");
1899
1900      if not No_Main_Subprogram then
1901         if CodePeer_Mode then
1902            if ALIs.Table (ALIs.First).Main_Program = Proc then
1903               WBI ("      " & CodePeer_Wrapper_Name & ";");
1904            else
1905               WBI ("      Result := " & CodePeer_Wrapper_Name & ";");
1906            end if;
1907
1908         elsif ALIs.Table (ALIs.First).Main_Program = Proc then
1909            WBI ("      Ada_Main_Program;");
1910
1911         else
1912            WBI ("      Result := Ada_Main_Program;");
1913         end if;
1914      end if;
1915
1916      --  Adafinal call is skipped if no finalization
1917
1918      if not Cumulative_Restrictions.Set (No_Finalization) then
1919         WBI ("      adafinal;");
1920      end if;
1921
1922      --  Prints the result of static stack analysis
1923
1924      if Dynamic_Stack_Measurement then
1925         WBI ("      Output_Results;");
1926      end if;
1927
1928      --  Finalize is only called if we have a run time
1929
1930      if not Cumulative_Restrictions.Set (No_Finalization)
1931        and then not CodePeer_Mode
1932      then
1933         WBI ("      Finalize;");
1934      end if;
1935
1936      --  Return result
1937
1938      if Exit_Status_Supported_On_Target then
1939         if No_Main_Subprogram
1940           or else ALIs.Table (ALIs.First).Main_Program = Proc
1941         then
1942            WBI ("      return (gnat_exit_status);");
1943         else
1944            WBI ("      return (Result);");
1945         end if;
1946      end if;
1947
1948      WBI ("   end;");
1949      WBI ("");
1950   end Gen_Main;
1951
1952   ------------------------------
1953   -- Gen_Object_Files_Options --
1954   ------------------------------
1955
1956   procedure Gen_Object_Files_Options (Elab_Order : Unit_Id_Array) is
1957      Lgnat : Natural;
1958      --  This keeps track of the position in the sorted set of entries in the
1959      --  Linker_Options table of where the first entry from an internal file
1960      --  appears.
1961
1962      Linker_Option_List_Started : Boolean := False;
1963      --  Set to True when "LINKER OPTION LIST" is displayed
1964
1965      procedure Write_Linker_Option;
1966      --  Write binder info linker option
1967
1968      -------------------------
1969      -- Write_Linker_Option --
1970      -------------------------
1971
1972      procedure Write_Linker_Option is
1973         Start : Natural;
1974         Stop  : Natural;
1975
1976      begin
1977         --  Loop through string, breaking at null's
1978
1979         Start := 1;
1980         while Start < Name_Len loop
1981
1982            --  Find null ending this section
1983
1984            Stop := Start + 1;
1985            while Name_Buffer (Stop) /= ASCII.NUL
1986              and then Stop <= Name_Len loop
1987               Stop := Stop + 1;
1988            end loop;
1989
1990            --  Process section if non-null
1991
1992            if Stop > Start then
1993               if Output_Linker_Option_List then
1994                  if not Zero_Formatting then
1995                     if not Linker_Option_List_Started then
1996                        Linker_Option_List_Started := True;
1997                        Write_Eol;
1998                        Write_Str ("     LINKER OPTION LIST");
1999                        Write_Eol;
2000                        Write_Eol;
2001                     end if;
2002
2003                     Write_Str ("   ");
2004                  end if;
2005
2006                  Write_Str (Name_Buffer (Start .. Stop - 1));
2007                  Write_Eol;
2008               end if;
2009               WBI ("   --   " & Name_Buffer (Start .. Stop - 1));
2010            end if;
2011
2012            Start := Stop + 1;
2013         end loop;
2014      end Write_Linker_Option;
2015
2016   --  Start of processing for Gen_Object_Files_Options
2017
2018   begin
2019      WBI ("--  BEGIN Object file/option list");
2020
2021      if Object_List_Filename /= null then
2022         Set_List_File (Object_List_Filename.all);
2023      end if;
2024
2025      for E in Elab_Order'Range loop
2026
2027         --  If not spec that has an associated body, then generate a comment
2028         --  giving the name of the corresponding object file.
2029
2030         if not Units.Table (Elab_Order (E)).SAL_Interface
2031           and then Units.Table (Elab_Order (E)).Utype /= Is_Spec
2032         then
2033            Get_Name_String
2034              (ALIs.Table
2035                (Units.Table (Elab_Order (E)).My_ALI).Ofile_Full_Name);
2036
2037            --  If the presence of an object file is necessary or if it exists,
2038            --  then use it.
2039
2040            if not Hostparm.Exclude_Missing_Objects
2041              or else
2042                System.OS_Lib.Is_Regular_File (Name_Buffer (1 .. Name_Len))
2043            then
2044               WBI ("   --   " & Name_Buffer (1 .. Name_Len));
2045
2046               if Output_Object_List then
2047                  Write_Str (Name_Buffer (1 .. Name_Len));
2048                  Write_Eol;
2049               end if;
2050            end if;
2051         end if;
2052      end loop;
2053
2054      if Object_List_Filename /= null then
2055         Close_List_File;
2056      end if;
2057
2058      --  Add a "-Ldir" for each directory in the object path
2059
2060      for J in 1 .. Nb_Dir_In_Obj_Search_Path loop
2061         declare
2062            Dir : constant String_Ptr := Dir_In_Obj_Search_Path (J);
2063
2064         begin
2065            Name_Len := 0;
2066            Add_Str_To_Name_Buffer ("-L");
2067            Add_Str_To_Name_Buffer (Dir.all);
2068            Write_Linker_Option;
2069         end;
2070      end loop;
2071
2072      if not (Opt.No_Run_Time_Mode or Opt.No_Stdlib) then
2073         Name_Len := 0;
2074
2075         if Opt.Shared_Libgnat then
2076            Add_Str_To_Name_Buffer ("-shared");
2077         else
2078            Add_Str_To_Name_Buffer ("-static");
2079         end if;
2080
2081         --  Write directly to avoid inclusion in -K output as -static and
2082         --  -shared are not usually specified linker options.
2083
2084         WBI ("   --   " & Name_Buffer (1 .. Name_Len));
2085      end if;
2086
2087      --  Sort linker options
2088
2089      --  This sort accomplishes two important purposes:
2090
2091      --    a) All application files are sorted to the front, and all GNAT
2092      --       internal files are sorted to the end. This results in a well
2093      --       defined dividing line between the two sets of files, for the
2094      --       purpose of inserting certain standard library references into
2095      --       the linker arguments list.
2096
2097      --    b) Given two different units, we sort the linker options so that
2098      --       those from a unit earlier in the elaboration order comes later
2099      --       in the list. This is a heuristic designed to create a more
2100      --       friendly order of linker options when the operations appear in
2101      --       separate units. The idea is that if unit A must be elaborated
2102      --       before unit B, then it is more likely that B references
2103      --       libraries included by A, than vice versa, so we want libraries
2104      --       included by A to come after libraries included by B.
2105
2106      --  These two criteria are implemented by function Lt_Linker_Option. Note
2107      --  that a special case of b) is that specs are elaborated before bodies,
2108      --  so linker options from specs come after linker options for bodies,
2109      --  and again, the assumption is that libraries used by the body are more
2110      --  likely to reference libraries used by the spec, than vice versa.
2111
2112      Sort
2113        (Linker_Options.Last,
2114         Move_Linker_Option'Access,
2115         Lt_Linker_Option'Access);
2116
2117      --  Write user linker options, i.e. the set of linker options that come
2118      --  from all files other than GNAT internal files, Lgnat is left set to
2119      --  point to the first entry from a GNAT internal file, or past the end
2120      --  of the entries if there are no internal files.
2121
2122      Lgnat := Linker_Options.Last + 1;
2123
2124      for J in 1 .. Linker_Options.Last loop
2125         if not Linker_Options.Table (J).Internal_File then
2126            Get_Name_String (Linker_Options.Table (J).Name);
2127            Write_Linker_Option;
2128         else
2129            Lgnat := J;
2130            exit;
2131         end if;
2132      end loop;
2133
2134      --  Now we insert standard linker options that must appear after the
2135      --  entries from user files, and before the entries from GNAT run-time
2136      --  files. The reason for this decision is that libraries referenced
2137      --  by internal routines may reference these standard library entries.
2138
2139      --  Note that we do not insert anything when pragma No_Run_Time has
2140      --  been specified or when the standard libraries are not to be used,
2141      --  otherwise on some platforms, we may get duplicate symbols when
2142      --  linking (not clear if this is still the case, but it is harmless).
2143
2144      if not (Opt.No_Run_Time_Mode or else Opt.No_Stdlib) then
2145         if With_GNARL then
2146            Name_Len := 0;
2147
2148            if Opt.Shared_Libgnat then
2149               Add_Str_To_Name_Buffer (Shared_Lib ("gnarl"));
2150            else
2151               Add_Str_To_Name_Buffer ("-lgnarl");
2152            end if;
2153
2154            Write_Linker_Option;
2155         end if;
2156
2157         Name_Len := 0;
2158
2159         if Opt.Shared_Libgnat then
2160            Add_Str_To_Name_Buffer (Shared_Lib ("gnat"));
2161         else
2162            Add_Str_To_Name_Buffer ("-lgnat");
2163         end if;
2164
2165         Write_Linker_Option;
2166      end if;
2167
2168      --  Write linker options from all internal files
2169
2170      for J in Lgnat .. Linker_Options.Last loop
2171         Get_Name_String (Linker_Options.Table (J).Name);
2172         Write_Linker_Option;
2173      end loop;
2174
2175      if Output_Linker_Option_List and then not Zero_Formatting then
2176         Write_Eol;
2177      end if;
2178
2179      WBI ("--  END Object file/option list   ");
2180   end Gen_Object_Files_Options;
2181
2182   ---------------------
2183   -- Gen_Output_File --
2184   ---------------------
2185
2186   procedure Gen_Output_File
2187     (Filename   : String;
2188      Elab_Order : Unit_Id_Array)
2189   is
2190   begin
2191      --  Acquire settings for Interrupt_State pragmas
2192
2193      Set_IS_Pragma_Table;
2194
2195      --  Acquire settings for Priority_Specific_Dispatching pragma
2196
2197      Set_PSD_Pragma_Table;
2198
2199      --  Override time slice value if -T switch is set
2200
2201      if Time_Slice_Set then
2202         ALIs.Table (ALIs.First).Time_Slice_Value := Opt.Time_Slice_Value;
2203      end if;
2204
2205      --  Count number of elaboration calls
2206
2207      for E in Elab_Order'Range loop
2208         if Units.Table (Elab_Order (E)).No_Elab then
2209            null;
2210         else
2211            Num_Elab_Calls := Num_Elab_Calls + 1;
2212         end if;
2213      end loop;
2214
2215      --  Count the number of statically allocated stacks to be generated by
2216      --  the binder. If the user has specified the number of default-sized
2217      --  secondary stacks, use that number. Otherwise start the count at one
2218      --  as the binder is responsible for creating a secondary stack for the
2219      --  main task.
2220
2221      if Opt.Quantity_Of_Default_Size_Sec_Stacks /= -1 then
2222         Num_Sec_Stacks := Quantity_Of_Default_Size_Sec_Stacks;
2223      elsif Sec_Stack_Used then
2224         Num_Sec_Stacks := 1;
2225      end if;
2226
2227      for J in Units.First .. Units.Last loop
2228         Num_Primary_Stacks :=
2229           Num_Primary_Stacks + Units.Table (J).Primary_Stack_Count;
2230
2231         Num_Sec_Stacks :=
2232           Num_Sec_Stacks + Units.Table (J).Sec_Stack_Count;
2233      end loop;
2234
2235      --  Generate output file in appropriate language
2236
2237      Gen_Output_File_Ada (Filename, Elab_Order);
2238   end Gen_Output_File;
2239
2240   -------------------------
2241   -- Gen_Output_File_Ada --
2242   -------------------------
2243
2244   procedure Gen_Output_File_Ada
2245     (Filename : String; Elab_Order : Unit_Id_Array)
2246   is
2247      Ada_Main : constant String := Get_Ada_Main_Name;
2248      --  Name to be used for generated Ada main program. See the body of
2249      --  function Get_Ada_Main_Name for details on the form of the name.
2250
2251      Needs_Library_Finalization : constant Boolean :=
2252        not Configurable_Run_Time_On_Target
2253        and then Has_Finalizer (Elab_Order);
2254      --  For restricted run-time libraries (ZFP and Ravenscar) tasks are
2255      --  non-terminating, so we do not want finalization.
2256
2257      Bfiles : Name_Id;
2258      --  Name of generated bind file (spec)
2259
2260      Bfileb : Name_Id;
2261      --  Name of generated bind file (body)
2262
2263   begin
2264      --  Create spec first
2265
2266      Create_Binder_Output (Filename, 's', Bfiles);
2267
2268      --  We always compile the binder file in Ada 95 mode so that we properly
2269      --  handle use of Ada 2005 keywords as identifiers in Ada 95 mode. None
2270      --  of the Ada 2005 or Ada 2012 constructs are needed by the binder file.
2271
2272      WBI ("pragma Warnings (Off);");
2273      WBI ("pragma Ada_95;");
2274
2275      --  If we are operating in Restrictions (No_Exception_Handlers) mode,
2276      --  then we need to make sure that the binder program is compiled with
2277      --  the same restriction, so that no exception tables are generated.
2278
2279      if Cumulative_Restrictions.Set (No_Exception_Handlers) then
2280         WBI ("pragma Restrictions (No_Exception_Handlers);");
2281      end if;
2282
2283      --  Same processing for Restrictions (No_Exception_Propagation)
2284
2285      if Cumulative_Restrictions.Set (No_Exception_Propagation) then
2286         WBI ("pragma Restrictions (No_Exception_Propagation);");
2287      end if;
2288
2289      --  Same processing for pragma No_Run_Time
2290
2291      if No_Run_Time_Mode then
2292         WBI ("pragma No_Run_Time;");
2293      end if;
2294
2295      --  Generate with of System so we can reference System.Address
2296
2297      WBI ("with System;");
2298
2299      --  Generate with of System.Initialize_Scalars if active
2300
2301      if Initialize_Scalars_Used then
2302         WBI ("with System.Scalar_Values;");
2303      end if;
2304
2305      --  Generate withs of System.Secondary_Stack and System.Parameters to
2306      --  allow the generation of the default-sized secondary stack pool.
2307
2308      if Sec_Stack_Used then
2309         WBI ("with System.Parameters;");
2310         WBI ("with System.Secondary_Stack;");
2311      end if;
2312
2313      Resolve_Binder_Options (Elab_Order);
2314
2315      --  Generate standard with's
2316
2317      if not Suppress_Standard_Library_On_Target then
2318         if CodePeer_Mode then
2319            WBI ("with System.Standard_Library;");
2320         end if;
2321      end if;
2322
2323      WBI ("package " & Ada_Main & " is");
2324
2325      --  Main program case
2326
2327      if Bind_Main_Program then
2328         --  Generate argc/argv stuff unless suppressed
2329
2330         if Command_Line_Args_On_Target
2331           or not Configurable_Run_Time_On_Target
2332         then
2333            WBI ("");
2334            WBI ("   gnat_argc : Integer;");
2335            WBI ("   gnat_argv : System.Address;");
2336            WBI ("   gnat_envp : System.Address;");
2337
2338            --  If the standard library is not suppressed, these variables
2339            --  are in the run-time data area for easy run time access.
2340
2341            if not Suppress_Standard_Library_On_Target then
2342               WBI ("");
2343               WBI ("   pragma Import (C, gnat_argc);");
2344               WBI ("   pragma Import (C, gnat_argv);");
2345               WBI ("   pragma Import (C, gnat_envp);");
2346            end if;
2347         end if;
2348
2349         --  Define exit status. Again in normal mode, this is in the run-time
2350         --  library, and is initialized there, but in the configurable
2351         --  run-time case, the variable is declared and initialized in this
2352         --  file.
2353
2354         WBI ("");
2355
2356         if Configurable_Run_Time_Mode then
2357            if Exit_Status_Supported_On_Target then
2358               WBI ("   gnat_exit_status : Integer := 0;");
2359            end if;
2360
2361         else
2362            WBI ("   gnat_exit_status : Integer;");
2363            WBI ("   pragma Import (C, gnat_exit_status);");
2364         end if;
2365
2366         --  Generate the GNAT_Version and Ada_Main_Program_Name info only for
2367         --  the main program. Otherwise, it can lead under some circumstances
2368         --  to a symbol duplication during the link (for instance when a C
2369         --  program uses two Ada libraries). Also zero terminate the string
2370         --  so that its end can be found reliably at run time.
2371
2372         if not Minimal_Binder then
2373            WBI ("");
2374            WBI ("   GNAT_Version : constant String :=");
2375            WBI ("                    """ & Ver_Prefix &
2376                                      Gnat_Version_String &
2377                                      """ & ASCII.NUL;");
2378            WBI ("   pragma Export (C, GNAT_Version, ""__gnat_version"");");
2379
2380            WBI ("");
2381            Set_String ("   Ada_Main_Program_Name : constant String := """);
2382            Get_Name_String (Units.Table (First_Unit_Entry).Uname);
2383
2384            Set_Main_Program_Name;
2385            Set_String (""" & ASCII.NUL;");
2386
2387            Write_Statement_Buffer;
2388
2389            WBI
2390              ("   pragma Export (C, Ada_Main_Program_Name, " &
2391               """__gnat_ada_main_program_name"");");
2392         end if;
2393      end if;
2394
2395      WBI ("");
2396      WBI ("   procedure " & Ada_Init_Name.all & ";");
2397      WBI ("   pragma Export (C, " & Ada_Init_Name.all & ", """ &
2398           Ada_Init_Name.all & """);");
2399
2400      --  If -a has been specified use pragma Linker_Constructor for the init
2401      --  procedure and pragma Linker_Destructor for the final procedure.
2402
2403      if Use_Pragma_Linker_Constructor then
2404         WBI ("   pragma Linker_Constructor (" & Ada_Init_Name.all & ");");
2405      end if;
2406
2407      if not Cumulative_Restrictions.Set (No_Finalization) then
2408         WBI ("");
2409         WBI ("   procedure " & Ada_Final_Name.all & ";");
2410         WBI ("   pragma Export (C, " & Ada_Final_Name.all & ", """ &
2411              Ada_Final_Name.all & """);");
2412
2413         if Use_Pragma_Linker_Constructor then
2414            WBI ("   pragma Linker_Destructor (" & Ada_Final_Name.all & ");");
2415         end if;
2416      end if;
2417
2418      if Bind_Main_Program then
2419
2420         WBI ("");
2421
2422         if Exit_Status_Supported_On_Target then
2423            Set_String ("   function ");
2424         else
2425            Set_String ("   procedure ");
2426         end if;
2427
2428         Set_String (Get_Main_Name);
2429
2430         --  Generate argument list if present
2431
2432         if Command_Line_Args_On_Target then
2433            Write_Statement_Buffer;
2434            WBI ("     (argc : Integer;");
2435            WBI ("      argv : System.Address;");
2436            Set_String
2437                ("      envp : System.Address)");
2438
2439            if Exit_Status_Supported_On_Target then
2440               Write_Statement_Buffer;
2441               WBI ("      return Integer;");
2442            else
2443               Write_Statement_Buffer (";");
2444            end if;
2445
2446         else
2447            if Exit_Status_Supported_On_Target then
2448               Write_Statement_Buffer (" return Integer;");
2449            else
2450               Write_Statement_Buffer (";");
2451            end if;
2452         end if;
2453
2454         WBI ("   pragma Export (C, " & Get_Main_Name & ", """ &
2455           Get_Main_Name & """);");
2456      end if;
2457
2458      --  Generate version numbers for units, only if needed. Be very safe on
2459      --  the condition.
2460
2461      if not Configurable_Run_Time_On_Target
2462        or else System_Version_Control_Used
2463        or else not Bind_Main_Program
2464      then
2465         Gen_Versions;
2466      end if;
2467
2468      Gen_Elab_Order (Elab_Order);
2469
2470      --  Spec is complete
2471
2472      WBI ("");
2473      WBI ("end " & Ada_Main & ";");
2474      Close_Binder_Output;
2475
2476      --  Prepare to write body
2477
2478      Create_Binder_Output (Filename, 'b', Bfileb);
2479
2480      --  We always compile the binder file in Ada 95 mode so that we properly
2481      --  handle use of Ada 2005 keywords as identifiers in Ada 95 mode. None
2482      --  of the Ada 2005/2012 constructs are needed by the binder file.
2483
2484      WBI ("pragma Warnings (Off);");
2485      WBI ("pragma Ada_95;");
2486
2487      --  Output Source_File_Name pragmas which look like
2488
2489      --    pragma Source_File_Name (Ada_Main, Spec_File_Name => "sss");
2490      --    pragma Source_File_Name (Ada_Main, Body_File_Name => "bbb");
2491
2492      --  where sss/bbb are the spec/body file names respectively
2493
2494      Get_Name_String (Bfiles);
2495      Name_Buffer (Name_Len + 1 .. Name_Len + 3) := """);";
2496
2497      WBI ("pragma Source_File_Name (" &
2498           Ada_Main &
2499           ", Spec_File_Name => """ &
2500           Name_Buffer (1 .. Name_Len + 3));
2501
2502      Get_Name_String (Bfileb);
2503      Name_Buffer (Name_Len + 1 .. Name_Len + 3) := """);";
2504
2505      WBI ("pragma Source_File_Name (" &
2506           Ada_Main &
2507           ", Body_File_Name => """ &
2508           Name_Buffer (1 .. Name_Len + 3));
2509
2510      --  Generate pragma Suppress (Overflow_Check). This is needed for recent
2511      --  versions of the compiler which have overflow checks on by default.
2512      --  We do not want overflow checking enabled for the increments of the
2513      --  elaboration variables (since this can cause an unwanted reference to
2514      --  the last chance exception handler for limited run-times).
2515
2516      WBI ("pragma Suppress (Overflow_Check);");
2517
2518      --  Generate with of System.Restrictions to initialize
2519      --  Run_Time_Restrictions.
2520
2521      if System_Restrictions_Used
2522        and not Suppress_Standard_Library_On_Target
2523      then
2524         WBI ("");
2525         WBI ("with System.Restrictions;");
2526      end if;
2527
2528      --  Generate with of Ada.Exceptions if needs library finalization
2529
2530      if Needs_Library_Finalization then
2531         WBI ("with Ada.Exceptions;");
2532      end if;
2533
2534      --  Generate with of System.Elaboration_Allocators if the restriction
2535      --  No_Standard_Allocators_After_Elaboration was present.
2536
2537      if Cumulative_Restrictions.Set
2538           (No_Standard_Allocators_After_Elaboration)
2539      then
2540         WBI ("with System.Elaboration_Allocators;");
2541      end if;
2542
2543      --  Generate start of package body
2544
2545      WBI ("");
2546      WBI ("package body " & Ada_Main & " is");
2547      WBI ("");
2548
2549      --  Generate externals for elaboration entities
2550
2551      Gen_Elab_Externals (Elab_Order);
2552
2553      --  Generate default-sized secondary stacks pool. At least one stack is
2554      --  created and assigned to the environment task if secondary stacks are
2555      --  used by the program.
2556
2557      if Sec_Stack_Used then
2558         Set_String ("   Sec_Default_Sized_Stacks");
2559         Set_String (" : array (1 .. ");
2560         Set_Int (Num_Sec_Stacks);
2561         Set_String (") of aliased System.Secondary_Stack.SS_Stack (");
2562
2563         if Opt.Default_Sec_Stack_Size /= No_Stack_Size then
2564            Set_Int (Opt.Default_Sec_Stack_Size);
2565         else
2566            Set_String ("System.Parameters.Runtime_Default_Sec_Stack_Size");
2567         end if;
2568
2569         Set_String (");");
2570         Write_Statement_Buffer;
2571         WBI ("");
2572      end if;
2573
2574      --  Generate reference
2575
2576      if not CodePeer_Mode then
2577         if not Suppress_Standard_Library_On_Target then
2578
2579            --  Generate Priority_Specific_Dispatching pragma string
2580
2581            Set_String
2582              ("   Local_Priority_Specific_Dispatching : " &
2583               "constant String := """);
2584
2585            for J in 0 .. PSD_Pragma_Settings.Last loop
2586               Set_Char (PSD_Pragma_Settings.Table (J));
2587            end loop;
2588
2589            Set_String (""";");
2590            Write_Statement_Buffer;
2591
2592            --  Generate Interrupt_State pragma string
2593
2594            Set_String ("   Local_Interrupt_States : constant String := """);
2595
2596            for J in 0 .. IS_Pragma_Settings.Last loop
2597               Set_Char (IS_Pragma_Settings.Table (J));
2598            end loop;
2599
2600            Set_String (""";");
2601            Write_Statement_Buffer;
2602            WBI ("");
2603         end if;
2604
2605         if not Suppress_Standard_Library_On_Target then
2606
2607            --  The B.1(39) implementation advice says that the adainit and
2608            --  adafinal routines should be idempotent. Generate a flag to
2609            --  ensure that. This is not needed if we are suppressing the
2610            --  standard library since it would never be referenced.
2611
2612            WBI ("   Is_Elaborated : Boolean := False;");
2613
2614            --  Generate bind environment string
2615
2616            Gen_Bind_Env_String;
2617         end if;
2618
2619         WBI ("");
2620      end if;
2621
2622      --  Generate the adafinal routine unless there is no finalization to do
2623
2624      if not Cumulative_Restrictions.Set (No_Finalization) then
2625         if Needs_Library_Finalization then
2626            Gen_Finalize_Library (Elab_Order);
2627         end if;
2628
2629         Gen_Adafinal;
2630      end if;
2631
2632      Gen_Adainit (Elab_Order);
2633
2634      if Bind_Main_Program then
2635         Gen_Main;
2636      end if;
2637
2638      --  Output object file list and the Ada body is complete
2639
2640      Gen_Object_Files_Options (Elab_Order);
2641
2642      WBI ("");
2643      WBI ("end " & Ada_Main & ";");
2644
2645      Close_Binder_Output;
2646   end Gen_Output_File_Ada;
2647
2648   ----------------------
2649   -- Gen_Restrictions --
2650   ----------------------
2651
2652   procedure Gen_Restrictions is
2653      Count : Integer;
2654
2655   begin
2656      if Suppress_Standard_Library_On_Target
2657        or not System_Restrictions_Used
2658      then
2659         return;
2660      end if;
2661
2662      WBI ("      System.Restrictions.Run_Time_Restrictions :=");
2663      WBI ("        (Set =>");
2664      Set_String      ("          (");
2665
2666      Count := 0;
2667
2668      for J in Cumulative_Restrictions.Set'Range loop
2669         Set_Boolean (Cumulative_Restrictions.Set (J));
2670         Set_String (", ");
2671         Count := Count + 1;
2672
2673         if J /= Cumulative_Restrictions.Set'Last and then Count = 8 then
2674            Write_Statement_Buffer;
2675            Set_String ("           ");
2676            Count := 0;
2677         end if;
2678      end loop;
2679
2680      Set_String_Replace ("),");
2681      Write_Statement_Buffer;
2682      Set_String ("         Value => (");
2683
2684      for J in Cumulative_Restrictions.Value'Range loop
2685         Set_Int (Int (Cumulative_Restrictions.Value (J)));
2686         Set_String (", ");
2687      end loop;
2688
2689      Set_String_Replace ("),");
2690      Write_Statement_Buffer;
2691      WBI ("         Violated =>");
2692      Set_String ("          (");
2693      Count := 0;
2694
2695      for J in Cumulative_Restrictions.Violated'Range loop
2696         Set_Boolean (Cumulative_Restrictions.Violated (J));
2697         Set_String (", ");
2698         Count := Count + 1;
2699
2700         if J /= Cumulative_Restrictions.Set'Last and then Count = 8 then
2701            Write_Statement_Buffer;
2702            Set_String ("           ");
2703            Count := 0;
2704         end if;
2705      end loop;
2706
2707      Set_String_Replace ("),");
2708      Write_Statement_Buffer;
2709      Set_String ("         Count => (");
2710
2711      for J in Cumulative_Restrictions.Count'Range loop
2712         Set_Int (Int (Cumulative_Restrictions.Count (J)));
2713         Set_String (", ");
2714      end loop;
2715
2716      Set_String_Replace ("),");
2717      Write_Statement_Buffer;
2718      Set_String ("         Unknown => (");
2719
2720      for J in Cumulative_Restrictions.Unknown'Range loop
2721         Set_Boolean (Cumulative_Restrictions.Unknown (J));
2722         Set_String (", ");
2723      end loop;
2724
2725      Set_String_Replace ("))");
2726      Set_String (";");
2727      Write_Statement_Buffer;
2728   end Gen_Restrictions;
2729
2730   ------------------
2731   -- Gen_Versions --
2732   ------------------
2733
2734   --  This routine generates lines such as:
2735
2736   --    unnnnn : constant Integer := 16#hhhhhhhh#;
2737   --    pragma Export (C, unnnnn, unam);
2738
2739   --  for each unit, where unam is the unit name suffixed by either B or S for
2740   --  body or spec, with dots replaced by double underscores, and hhhhhhhh is
2741   --  the version number, and nnnnn is a 5-digits serial number.
2742
2743   procedure Gen_Versions is
2744      Ubuf : String (1 .. 6) := "u00000";
2745
2746      procedure Increment_Ubuf;
2747      --  Little procedure to increment the serial number
2748
2749      --------------------
2750      -- Increment_Ubuf --
2751      --------------------
2752
2753      procedure Increment_Ubuf is
2754      begin
2755         for J in reverse Ubuf'Range loop
2756            Ubuf (J) := Character'Succ (Ubuf (J));
2757            exit when Ubuf (J) <= '9';
2758            Ubuf (J) := '0';
2759         end loop;
2760      end Increment_Ubuf;
2761
2762   --  Start of processing for Gen_Versions
2763
2764   begin
2765      WBI ("");
2766
2767      WBI ("   type Version_32 is mod 2 ** 32;");
2768      for U in Units.First .. Units.Last loop
2769         if not Units.Table (U).SAL_Interface
2770           and then (not Bind_For_Library
2771                      or else Units.Table (U).Directly_Scanned)
2772         then
2773            Increment_Ubuf;
2774            WBI ("   " & Ubuf & " : constant Version_32 := 16#" &
2775                 Units.Table (U).Version & "#;");
2776            Set_String ("   pragma Export (C, ");
2777            Set_String (Ubuf);
2778            Set_String (", """);
2779
2780            Get_Name_String (Units.Table (U).Uname);
2781
2782            for K in 1 .. Name_Len loop
2783               if Name_Buffer (K) = '.' then
2784                  Set_Char ('_');
2785                  Set_Char ('_');
2786
2787               elsif Name_Buffer (K) = '%' then
2788                  exit;
2789
2790               else
2791                  Set_Char (Name_Buffer (K));
2792               end if;
2793            end loop;
2794
2795            if Name_Buffer (Name_Len) = 's' then
2796               Set_Char ('S');
2797            else
2798               Set_Char ('B');
2799            end if;
2800
2801            Set_String (""");");
2802            Write_Statement_Buffer;
2803         end if;
2804      end loop;
2805   end Gen_Versions;
2806
2807   ------------------------
2808   -- Get_Main_Unit_Name --
2809   ------------------------
2810
2811   function Get_Main_Unit_Name (S : String) return String is
2812      Result : String := S;
2813
2814   begin
2815      for J in S'Range loop
2816         if Result (J) = '.' then
2817            Result (J) := '_';
2818         end if;
2819      end loop;
2820
2821      return Result;
2822   end Get_Main_Unit_Name;
2823
2824   -----------------------
2825   -- Get_Ada_Main_Name --
2826   -----------------------
2827
2828   function Get_Ada_Main_Name return String is
2829      Suffix : constant String := "_00";
2830      Name   : String (1 .. Opt.Ada_Main_Name.all'Length + Suffix'Length) :=
2831                 Opt.Ada_Main_Name.all & Suffix;
2832      Nlen   : Natural;
2833
2834   begin
2835      --  For CodePeer, we want reproducible names (independent of other mains
2836      --  that may or may not be present) that don't collide when analyzing
2837      --  multiple mains and which are easily recognizable as "ada_main" names.
2838
2839      if CodePeer_Mode then
2840         Get_Name_String (Units.Table (First_Unit_Entry).Uname);
2841
2842         return
2843           "ada_main_for_" &
2844             Get_Main_Unit_Name (Name_Buffer (1 .. Name_Len - 2));
2845      end if;
2846
2847      --  This loop tries the following possibilities in order
2848      --    <Ada_Main>
2849      --    <Ada_Main>_01
2850      --    <Ada_Main>_02
2851      --    ..
2852      --    <Ada_Main>_99
2853      --  where <Ada_Main> is equal to Opt.Ada_Main_Name. By default,
2854      --  it is set to 'ada_main'.
2855
2856      for J in 0 .. 99 loop
2857         if J = 0 then
2858            Nlen := Name'Length - Suffix'Length;
2859         else
2860            Nlen := Name'Length;
2861            Name (Name'Last) := Character'Val (J mod 10 + Character'Pos ('0'));
2862            Name (Name'Last - 1) :=
2863              Character'Val (J /   10 + Character'Pos ('0'));
2864         end if;
2865
2866         for K in ALIs.First .. ALIs.Last loop
2867            for L in ALIs.Table (K).First_Unit .. ALIs.Table (K).Last_Unit loop
2868
2869               --  Get unit name, removing %b or %e at end
2870
2871               Get_Name_String (Units.Table (L).Uname);
2872               Name_Len := Name_Len - 2;
2873
2874               if Name_Buffer (1 .. Name_Len) = Name (1 .. Nlen) then
2875                  goto Continue;
2876               end if;
2877            end loop;
2878         end loop;
2879
2880         return Name (1 .. Nlen);
2881
2882      <<Continue>>
2883         null;
2884      end loop;
2885
2886      --  If we fall through, just use a peculiar unlikely name
2887
2888      return ("Qwertyuiop");
2889   end Get_Ada_Main_Name;
2890
2891   -------------------
2892   -- Get_Main_Name --
2893   -------------------
2894
2895   function Get_Main_Name return String is
2896   begin
2897      --  Explicit name given with -M switch
2898
2899      if Bind_Alternate_Main_Name then
2900         return Alternate_Main_Name.all;
2901
2902      --  Case of main program name to be used directly
2903
2904      elsif Use_Ada_Main_Program_Name_On_Target then
2905
2906         --  Get main program name
2907
2908         Get_Name_String (Units.Table (First_Unit_Entry).Uname);
2909
2910         --  If this is a child name, return only the name of the child, since
2911         --  we can't have dots in a nested program name. Note that we do not
2912         --  include the %b at the end of the unit name.
2913
2914         for J in reverse 1 .. Name_Len - 2 loop
2915            if J = 1 or else Name_Buffer (J - 1) = '.' then
2916               return Name_Buffer (J .. Name_Len - 2);
2917            end if;
2918         end loop;
2919
2920         raise Program_Error; -- impossible exit
2921
2922      --  Case where "main" is to be used as default
2923
2924      else
2925         return "main";
2926      end if;
2927   end Get_Main_Name;
2928
2929   ---------------------
2930   -- Get_WC_Encoding --
2931   ---------------------
2932
2933   function Get_WC_Encoding return Character is
2934   begin
2935      --  If encoding method specified by -W switch, then return it
2936
2937      if Wide_Character_Encoding_Method_Specified then
2938         return WC_Encoding_Letters (Wide_Character_Encoding_Method);
2939
2940      --  If no main program, and not specified, set brackets, we really have
2941      --  no better choice. If some other encoding is required when there is
2942      --  no main, it must be set explicitly using -Wx.
2943
2944      --  Note: if the ALI file always passed the wide character encoding of
2945      --  every file, then we could use the encoding of the initial specified
2946      --  file, but this information is passed only for potential main
2947      --  programs. We could fix this sometime, but it is a very minor point
2948      --  (wide character default encoding for [Wide_[Wide_]]Text_IO when there
2949      --  is no main program).
2950
2951      elsif No_Main_Subprogram then
2952         return 'b';
2953
2954      --  Otherwise if there is a main program, take encoding from it
2955
2956      else
2957         return ALIs.Table (ALIs.First).WC_Encoding;
2958      end if;
2959   end Get_WC_Encoding;
2960
2961   -------------------
2962   -- Has_Finalizer --
2963   -------------------
2964
2965   function Has_Finalizer (Elab_Order : Unit_Id_Array) return Boolean is
2966      U     : Unit_Record;
2967      Unum  : Unit_Id;
2968
2969   begin
2970      for E in reverse Elab_Order'Range loop
2971         Unum := Elab_Order (E);
2972         U    := Units.Table (Unum);
2973
2974         --  We are only interested in non-generic packages
2975
2976         if U.Unit_Kind = 'p'
2977           and then U.Has_Finalizer
2978           and then not U.Is_Generic
2979           and then not U.No_Elab
2980         then
2981            return True;
2982         end if;
2983      end loop;
2984
2985      return False;
2986   end Has_Finalizer;
2987
2988   ----------
2989   -- Hash --
2990   ----------
2991
2992   function Hash (Nam : Name_Id) return Header_Num is
2993   begin
2994      return Int (Nam - Names_Low_Bound) rem Header_Num'Last;
2995   end Hash;
2996
2997   ----------------------
2998   -- Lt_Linker_Option --
2999   ----------------------
3000
3001   function Lt_Linker_Option (Op1 : Natural; Op2 : Natural) return Boolean is
3002   begin
3003      --  Sort internal files last
3004
3005      if Linker_Options.Table (Op1).Internal_File
3006           /=
3007         Linker_Options.Table (Op2).Internal_File
3008      then
3009         --  Note: following test uses False < True
3010
3011         return Linker_Options.Table (Op1).Internal_File
3012                  <
3013                Linker_Options.Table (Op2).Internal_File;
3014
3015      --  If both internal or both non-internal, sort according to the
3016      --  elaboration position. A unit that is elaborated later should come
3017      --  earlier in the linker options list.
3018
3019      else
3020         return Units.Table (Linker_Options.Table (Op1).Unit).Elab_Position
3021                  >
3022                Units.Table (Linker_Options.Table (Op2).Unit).Elab_Position;
3023      end if;
3024   end Lt_Linker_Option;
3025
3026   ------------------------
3027   -- Move_Linker_Option --
3028   ------------------------
3029
3030   procedure Move_Linker_Option (From : Natural; To : Natural) is
3031   begin
3032      Linker_Options.Table (To) := Linker_Options.Table (From);
3033   end Move_Linker_Option;
3034
3035   ----------------------------
3036   -- Resolve_Binder_Options --
3037   ----------------------------
3038
3039   procedure Resolve_Binder_Options (Elab_Order : Unit_Id_Array) is
3040      procedure Check_Package (Var : in out Boolean; Name : String);
3041      --  Set Var to true iff the current identifier in Namet is Name. Do
3042      --  nothing if it doesn't match. This procedure is just a helper to
3043      --  avoid explicitly dealing with length.
3044
3045      -------------------
3046      -- Check_Package --
3047      -------------------
3048
3049      procedure Check_Package (Var : in out Boolean; Name : String) is
3050      begin
3051         if Name_Len = Name'Length
3052           and then Name_Buffer (1 .. Name_Len) = Name
3053         then
3054            Var := True;
3055         end if;
3056      end Check_Package;
3057
3058   --  Start of processing for Resolve_Binder_Options
3059
3060   begin
3061      for E in Elab_Order'Range loop
3062         Get_Name_String (Units.Table (Elab_Order (E)).Uname);
3063
3064         --  This is not a perfect approach, but is the current protocol
3065         --  between the run-time and the binder to indicate that tasking is
3066         --  used: System.OS_Interface should always be used by any tasking
3067         --  application.
3068
3069         Check_Package (With_GNARL, "system.os_interface%s");
3070
3071         --  Ditto for the use of restricted tasking
3072
3073         Check_Package
3074           (System_Tasking_Restricted_Stages_Used,
3075            "system.tasking.restricted.stages%s");
3076
3077         --  Ditto for the use of interrupts
3078
3079         Check_Package (System_Interrupts_Used, "system.interrupts%s");
3080
3081         --  Ditto for the use of dispatching domains
3082
3083         Check_Package
3084           (Dispatching_Domains_Used,
3085            "system.multiprocessors.dispatching_domains%s");
3086
3087         --  Ditto for the use of restrictions
3088
3089         Check_Package (System_Restrictions_Used, "system.restrictions%s");
3090
3091         --  Ditto for the use of System.Secondary_Stack
3092
3093         Check_Package
3094           (System_Secondary_Stack_Package_In_Closure,
3095            "system.secondary_stack%s");
3096
3097         --  Ditto for use of an SMP bareboard runtime
3098
3099         Check_Package (System_BB_CPU_Primitives_Multiprocessors_Used,
3100                        "system.bb.cpu_primitives.multiprocessors%s");
3101
3102         --  Ditto for System.Version_Control, which is used for Version and
3103         --  Body_Version attributes.
3104
3105         Check_Package (System_Version_Control_Used,
3106                        "system.version_control%s");
3107      end loop;
3108   end Resolve_Binder_Options;
3109
3110   ------------------
3111   -- Set_Bind_Env --
3112   ------------------
3113
3114   procedure Set_Bind_Env (Key, Value : String) is
3115   begin
3116      --  The lengths of Key and Value are stored as single bytes
3117
3118      if Key'Length > 255 then
3119         Osint.Fail ("bind environment key """ & Key & """ too long");
3120      end if;
3121
3122      if Value'Length > 255 then
3123         Osint.Fail ("bind environment value """ & Value & """ too long");
3124      end if;
3125
3126      Bind_Environment.Set (Name_Find (Key), Name_Find (Value));
3127   end Set_Bind_Env;
3128
3129   -----------------
3130   -- Set_Boolean --
3131   -----------------
3132
3133   procedure Set_Boolean (B : Boolean) is
3134      False_Str : constant String := "False";
3135      True_Str  : constant String := "True";
3136
3137   begin
3138      if B then
3139         Statement_Buffer (Stm_Last + 1 .. Stm_Last + True_Str'Length) :=
3140           True_Str;
3141         Stm_Last := Stm_Last + True_Str'Length;
3142      else
3143         Statement_Buffer (Stm_Last + 1 .. Stm_Last + False_Str'Length) :=
3144           False_Str;
3145         Stm_Last := Stm_Last + False_Str'Length;
3146      end if;
3147   end Set_Boolean;
3148
3149   --------------
3150   -- Set_Char --
3151   --------------
3152
3153   procedure Set_Char (C : Character) is
3154   begin
3155      Stm_Last := Stm_Last + 1;
3156      Statement_Buffer (Stm_Last) := C;
3157   end Set_Char;
3158
3159   -------------
3160   -- Set_Int --
3161   -------------
3162
3163   procedure Set_Int (N : Int) is
3164   begin
3165      if N < 0 then
3166         Set_String ("-");
3167         Set_Int (-N);
3168
3169      else
3170         if N > 9 then
3171            Set_Int (N / 10);
3172         end if;
3173
3174         Stm_Last := Stm_Last + 1;
3175         Statement_Buffer (Stm_Last) :=
3176           Character'Val (N mod 10 + Character'Pos ('0'));
3177      end if;
3178   end Set_Int;
3179
3180   -------------------------
3181   -- Set_IS_Pragma_Table --
3182   -------------------------
3183
3184   procedure Set_IS_Pragma_Table is
3185   begin
3186      for F in ALIs.First .. ALIs.Last loop
3187         for K in ALIs.Table (F).First_Interrupt_State ..
3188                  ALIs.Table (F).Last_Interrupt_State
3189         loop
3190            declare
3191               Inum : constant Int :=
3192                        Interrupt_States.Table (K).Interrupt_Id;
3193               Stat : constant Character :=
3194                        Interrupt_States.Table (K).Interrupt_State;
3195
3196            begin
3197               while IS_Pragma_Settings.Last < Inum loop
3198                  IS_Pragma_Settings.Append ('n');
3199               end loop;
3200
3201               IS_Pragma_Settings.Table (Inum) := Stat;
3202            end;
3203         end loop;
3204      end loop;
3205   end Set_IS_Pragma_Table;
3206
3207   ---------------------------
3208   -- Set_Main_Program_Name --
3209   ---------------------------
3210
3211   procedure Set_Main_Program_Name is
3212   begin
3213      --  Note that name has %b on the end which we ignore
3214
3215      --  First we output the initial _ada_ since we know that the main program
3216      --  is a library level subprogram.
3217
3218      Set_String ("_ada_");
3219
3220      --  Copy name, changing dots to double underscores
3221
3222      for J in 1 .. Name_Len - 2 loop
3223         if Name_Buffer (J) = '.' then
3224            Set_String ("__");
3225         else
3226            Set_Char (Name_Buffer (J));
3227         end if;
3228      end loop;
3229   end Set_Main_Program_Name;
3230
3231   ---------------------
3232   -- Set_Name_Buffer --
3233   ---------------------
3234
3235   procedure Set_Name_Buffer is
3236   begin
3237      for J in 1 .. Name_Len loop
3238         Set_Char (Name_Buffer (J));
3239      end loop;
3240   end Set_Name_Buffer;
3241
3242   -------------------------
3243   -- Set_PSD_Pragma_Table --
3244   -------------------------
3245
3246   procedure Set_PSD_Pragma_Table is
3247   begin
3248      for F in ALIs.First .. ALIs.Last loop
3249         for K in ALIs.Table (F).First_Specific_Dispatching ..
3250                  ALIs.Table (F).Last_Specific_Dispatching
3251         loop
3252            declare
3253               DTK : Specific_Dispatching_Record
3254                       renames Specific_Dispatching.Table (K);
3255
3256            begin
3257               while PSD_Pragma_Settings.Last < DTK.Last_Priority loop
3258                  PSD_Pragma_Settings.Append ('F');
3259               end loop;
3260
3261               for Prio in DTK.First_Priority .. DTK.Last_Priority loop
3262                  PSD_Pragma_Settings.Table (Prio) := DTK.Dispatching_Policy;
3263               end loop;
3264            end;
3265         end loop;
3266      end loop;
3267   end Set_PSD_Pragma_Table;
3268
3269   ----------------
3270   -- Set_String --
3271   ----------------
3272
3273   procedure Set_String (S : String) is
3274   begin
3275      Statement_Buffer (Stm_Last + 1 .. Stm_Last + S'Length) := S;
3276      Stm_Last := Stm_Last + S'Length;
3277   end Set_String;
3278
3279   ------------------------
3280   -- Set_String_Replace --
3281   ------------------------
3282
3283   procedure Set_String_Replace (S : String) is
3284   begin
3285      Statement_Buffer (Stm_Last - S'Length + 1 .. Stm_Last) := S;
3286   end Set_String_Replace;
3287
3288   -------------------
3289   -- Set_Unit_Name --
3290   -------------------
3291
3292   procedure Set_Unit_Name is
3293   begin
3294      for J in 1 .. Name_Len - 2 loop
3295         if Name_Buffer (J) = '.' then
3296            Set_String ("__");
3297         else
3298            Set_Char (Name_Buffer (J));
3299         end if;
3300      end loop;
3301   end Set_Unit_Name;
3302
3303   ---------------------
3304   -- Set_Unit_Number --
3305   ---------------------
3306
3307   procedure Set_Unit_Number (U : Unit_Id) is
3308      Num_Units : constant Nat := Nat (Units.Last) - Nat (Unit_Id'First);
3309      Unum      : constant Nat := Nat (U) - Nat (Unit_Id'First);
3310
3311   begin
3312      if Num_Units >= 10 and then Unum < 10 then
3313         Set_Char ('0');
3314      end if;
3315
3316      if Num_Units >= 100 and then Unum < 100 then
3317         Set_Char ('0');
3318      end if;
3319
3320      Set_Int (Unum);
3321   end Set_Unit_Number;
3322
3323   ---------------------
3324   -- Write_Bind_Line --
3325   ---------------------
3326
3327   procedure Write_Bind_Line (S : String) is
3328   begin
3329      --  Need to strip trailing LF from S
3330
3331      WBI (S (S'First .. S'Last - 1));
3332   end Write_Bind_Line;
3333
3334   ----------------------------
3335   -- Write_Statement_Buffer --
3336   ----------------------------
3337
3338   procedure Write_Statement_Buffer is
3339   begin
3340      WBI (Statement_Buffer (1 .. Stm_Last));
3341      Stm_Last := 0;
3342   end Write_Statement_Buffer;
3343
3344   procedure Write_Statement_Buffer (S : String) is
3345   begin
3346      Set_String (S);
3347      Write_Statement_Buffer;
3348   end Write_Statement_Buffer;
3349
3350end Bindgen;
3351