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