------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             G N A T L I N K                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1996-2021, Free Software Foundation, Inc.         --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

--  Gnatlink usage: please consult the gnat documentation

with ALI;      use ALI;
with Csets;
with Gnatvsn;  use Gnatvsn;
with Indepsw;  use Indepsw;
with Namet;    use Namet;
with Opt;
with Osint;    use Osint;
with Output;   use Output;
with Snames;
with Switch;   use Switch;
with System;   use System;
with Table;
with Targparm;
with Types;

with Ada.Command_Line; use Ada.Command_Line;
with Ada.Exceptions;   use Ada.Exceptions;

with System.OS_Lib; use System.OS_Lib;
with System.CRTL;

with Interfaces.C_Streams; use Interfaces.C_Streams;
with Interfaces.C.Strings; use Interfaces.C.Strings;

procedure Gnatlink is
   pragma Ident (Gnatvsn.Gnat_Static_Version_String);

   Shared_Libgcc_String : constant String := "-shared-libgcc";
   Shared_Libgcc        : constant String_Access :=
                            new String'(Shared_Libgcc_String);
   --  Used to invoke gcc when the binder is invoked with -shared

   Static_Libgcc_String : constant String := "-static-libgcc";
   Static_Libgcc        : constant String_Access :=
                            new String'(Static_Libgcc_String);
   --  Used to invoke gcc when shared libs are not used

   package Gcc_Linker_Options is new Table.Table (
     Table_Component_Type => String_Access,
     Table_Index_Type     => Integer,
     Table_Low_Bound      => 1,
     Table_Initial        => 20,
     Table_Increment      => 100,
     Table_Name           => "Gnatlink.Gcc_Linker_Options");
   --  Options to be passed to the gcc linker

   package Libpath is new Table.Table (
     Table_Component_Type => Character,
     Table_Index_Type     => Integer,
     Table_Low_Bound      => 1,
     Table_Initial        => 4096,
     Table_Increment      => 100,
     Table_Name           => "Gnatlink.Libpath");
   --  Library search path

   package Linker_Options is new Table.Table (
     Table_Component_Type => String_Access,
     Table_Index_Type     => Integer,
     Table_Low_Bound      => 1,
     Table_Initial        => 20,
     Table_Increment      => 100,
     Table_Name           => "Gnatlink.Linker_Options");
   --  Options to be passed to gnatlink

   package Linker_Objects is new Table.Table (
     Table_Component_Type => String_Access,
     Table_Index_Type     => Integer,
     Table_Low_Bound      => 1,
     Table_Initial        => 20,
     Table_Increment      => 100,
     Table_Name           => "Gnatlink.Linker_Objects");
   --  This table collects the objects file to be passed to the linker. In the
   --  case where the linker command line is too long then programs objects
   --  are put on the Response_File_Objects table. Note that the binder object
   --  file and the user's objects remain in this table. This is very
   --  important because on the GNU linker command line the -L switch is not
   --  used to look for objects files but -L switch is used to look for
   --  objects listed in the response file. This is not a problem with the
   --  applications objects as they are specified with a full name.

   package Response_File_Objects is new Table.Table (
     Table_Component_Type => String_Access,
     Table_Index_Type     => Integer,
     Table_Low_Bound      => 1,
     Table_Initial        => 20,
     Table_Increment      => 100,
     Table_Name           => "Gnatlink.Response_File_Objects");
   --  This table collects the objects file that are to be put in the response
   --  file. Only application objects are collected there (see details in
   --  Linker_Objects table comments)

   package Binder_Options_From_ALI is new Table.Table (
     Table_Component_Type => String_Access,
     Table_Index_Type     => Integer,
     Table_Low_Bound      => 1, -- equals low bound of Argument_List for Spawn
     Table_Initial        => 20,
     Table_Increment      => 100,
     Table_Name           => "Gnatlink.Binder_Options_From_ALI");
   --  This table collects the switches from the ALI file of the main
   --  subprogram.

   package Binder_Options is new Table.Table (
     Table_Component_Type => String_Access,
     Table_Index_Type     => Integer,
     Table_Low_Bound      => 1, -- equals low bound of Argument_List for Spawn
     Table_Initial        => 20,
     Table_Increment      => 100,
     Table_Name           => "Gnatlink.Binder_Options");
   --  This table collects the arguments to be passed to compile the binder
   --  generated file.

   Gcc : String_Access := Program_Name ("gcc", "gnatlink");

   Read_Mode : constant String := "r" & ASCII.NUL;

   Begin_Info : constant String := "--  BEGIN Object file/option list";
   End_Info   : constant String := "--  END Object file/option list   ";

   Gcc_Path             : String_Access;
   Linker_Path          : String_Access;
   Output_File_Name     : String_Access;
   Ali_File_Name        : String_Access;
   Binder_Spec_Src_File : String_Access;
   Binder_Body_Src_File : String_Access;
   Binder_Ali_File      : String_Access;
   Binder_Obj_File      : String_Access;

   Base_Command_Name    : String_Access;

   Target_Debuggable_Suffix : String_Access;

   Tname    : Temp_File_Name;
   Tname_FD : File_Descriptor := Invalid_FD;
   --  Temporary file used by linker to pass list of object files on
   --  certain systems with limitations on size of arguments.

   Debug_Flag_Present : Boolean := False;
   Verbose_Mode       : Boolean := False;
   Very_Verbose_Mode  : Boolean := False;

   Standard_Gcc : Boolean := True;

   Compile_Bind_File : Boolean := True;
   --  Set to False if bind file is not to be compiled

   Create_Map_File : Boolean := False;
   --  Set to True by switch -M. The map file name is derived from
   --  the ALI file name (mainprog.ali => mainprog.map).

   Object_List_File_Supported : Boolean;
   for Object_List_File_Supported'Size use Character'Size;
   pragma Import
     (C, Object_List_File_Supported, "__gnat_objlist_file_supported");
   --  Predicate indicating whether the linker has an option whereby the
   --  names of object files can be passed to the linker in a file.

   Object_File_Option_Ptr : Interfaces.C.Strings.chars_ptr;
   pragma Import (C, Object_File_Option_Ptr, "__gnat_object_file_option");
   --  Pointer to a string representing the linker option which specifies
   --  the response file.

   Object_File_Option : constant String := Value (Object_File_Option_Ptr);
   --  The linker option which specifies the response file as a string

   Using_GNU_response_file : constant Boolean :=
     Object_File_Option'Length > 0
       and then Object_File_Option (Object_File_Option'Last) = '@';
   --  Whether a GNU response file is used

   Object_List_File_Required : Boolean := False;
   --  Set to True to force generation of a response file

   Shared_Libgcc_Default : Character;
   for Shared_Libgcc_Default'Size use Character'Size;
   pragma Import
     (C, Shared_Libgcc_Default, "__gnat_shared_libgcc_default");
   --  Indicates wether libgcc should be statically linked (use 'T') or
   --  dynamically linked (use 'H') by default.

   Link_Max : Integer;
   pragma Import (C, Link_Max, "__gnat_link_max");
   --  Maximum number of bytes on the command line supported by the OS
   --  linker. Passed this limit the response file mechanism must be used
   --  if supported.

   Run_Path_Option_Ptr : Interfaces.C.Strings.chars_ptr;
   pragma Import (C, Run_Path_Option_Ptr, "__gnat_run_path_option");
   --  Pointer to string representing the native linker option which
   --  specifies the path where the dynamic loader should find shared
   --  libraries. Equal to null string if this system doesn't support it.

   Libgcc_Subdir_Ptr : Interfaces.C.Strings.chars_ptr;
   pragma Import (C, Libgcc_Subdir_Ptr, "__gnat_default_libgcc_subdir");
   --  Pointer to string indicating the installation subdirectory where
   --  a default shared libgcc might be found.

   Object_Library_Ext_Ptr : Interfaces.C.Strings.chars_ptr;
   pragma Import
     (C, Object_Library_Ext_Ptr, "__gnat_object_library_extension");
   --  Pointer to string specifying the default extension for
   --  object libraries, e.g. Unix uses ".a".

   Separate_Run_Path_Options : Boolean;
   for Separate_Run_Path_Options'Size use Character'Size;
   pragma Import
     (C, Separate_Run_Path_Options, "__gnat_separate_run_path_options");
   --  Whether separate rpath options should be emitted for each directory

   function Get_Maximum_File_Name_Length return Integer;
   pragma Import (C, Get_Maximum_File_Name_Length,
                     "__gnat_get_maximum_file_name_length");

   function Base_Name (File_Name : String) return String;
   --  Return just the file name part without the extension (if present)

   procedure Check_Existing_Executable (File_Name : String);
   --  Delete any existing executable to avoid accidentally updating the target
   --  of a symbolic link, but produce a Fatal_Error if File_Name matches any
   --  of the source file names. This avoids overwriting of extensionless
   --  source files by accident on systems where executables do not have
   --  extensions.

   procedure Delete (Name : String);
   --  Wrapper to unlink as status is ignored by this application

   procedure Error_Msg (Message : String);
   --  Output the error or warning Message

   procedure Exit_With_Error (Error : String);
   --  Output Error and exit program with a fatal condition

   procedure Process_Args;
   --  Go through all the arguments and build option tables

   procedure Process_Binder_File (Name : String);
   --  Reads the binder file and extracts linker arguments

   function Index (S, Pattern : String) return Natural;
   --  Return the last occurrence of Pattern in S, or 0 if none

   procedure Search_Library_Path
     (Next_Line   : String;
      Nfirst      : Integer;
      Nlast       : Integer;
      Last        : Integer;
      GNAT_Static : Boolean;
      GNAT_Shared : Boolean);
   --  Given a Gnat standard library, search the library path to find the
   --  library location. Parameters are documented in Process_Binder_File.

   procedure Usage;
   --  Display usage

   procedure Write_Header;
   --  Show user the program name, version and copyright

   procedure Write_Usage;
   --  Show user the program options

   ---------------
   -- Base_Name --
   ---------------

   function Base_Name (File_Name : String) return String is
      Findex1 : Natural;
      Findex2 : Natural;

   begin
      Findex1 := File_Name'First;

      --  The file might be specified by a full path name. However,
      --  we want the path to be stripped away.

      for J in reverse File_Name'Range loop
         if Is_Directory_Separator (File_Name (J)) then
            Findex1 := J + 1;
            exit;
         end if;
      end loop;

      Findex2 := File_Name'Last;
      while Findex2 > Findex1 and then File_Name (Findex2) /=  '.' loop
         Findex2 := Findex2 - 1;
      end loop;

      if Findex2 = Findex1 then
         Findex2 := File_Name'Last + 1;
      end if;

      return File_Name (Findex1 .. Findex2 - 1);
   end Base_Name;

   -------------------------------
   -- Check_Existing_Executable --
   -------------------------------

   procedure Check_Existing_Executable (File_Name : String) is
      Ename : String := File_Name;
      Efile : File_Name_Type;
      Sfile : File_Name_Type;

   begin
      Canonical_Case_File_Name (Ename);
      Name_Len := 0;
      Add_Str_To_Name_Buffer (Ename);
      Efile := Name_Find;

      for J in Units.Table'First .. Units.Last loop
         Sfile := Units.Table (J).Sfile;
         if Sfile = Efile then
            Exit_With_Error
              ("executable name """ & File_Name & """ matches "
               & "source file name """ & Get_Name_String (Sfile) & """");
         end if;
      end loop;

      Delete (File_Name);
   end Check_Existing_Executable;

   ------------
   -- Delete --
   ------------

   procedure Delete (Name : String) is
      Status : int;
      pragma Unreferenced (Status);
   begin
      Status := unlink (Name'Address);
   end Delete;

   ---------------
   -- Error_Msg --
   ---------------

   procedure Error_Msg (Message : String) is
   begin
      Write_Str (Base_Command_Name.all);
      Write_Str (": ");
      Write_Str (Message);
      Write_Eol;
   end Error_Msg;

   ---------------------
   -- Exit_With_Error --
   ---------------------

   procedure Exit_With_Error (Error : String) is
   begin
      Error_Msg (Error);
      Exit_Program (E_Fatal);
   end Exit_With_Error;

   -----------
   -- Index --
   -----------

   function Index (S, Pattern : String) return Natural is
      Len : constant Natural := Pattern'Length;

   begin
      for J in reverse S'First .. S'Last - Len + 1 loop
         if Pattern = S (J .. J + Len - 1) then
            return J;
         end if;
      end loop;

      return 0;
   end Index;

   ------------------
   -- Process_Args --
   ------------------

   procedure Process_Args is
      Next_Arg : Integer;

      Skip_Next : Boolean := False;
      --  Set to true if the next argument is to be added into the list of
      --  linker's argument without parsing it.

      procedure Check_Version_And_Help is new Check_Version_And_Help_G (Usage);

      --  Start of processing for Process_Args

   begin
      --  First, check for --version and --help

      Check_Version_And_Help ("GNATLINK", "1996");

      --  Loop through arguments of gnatlink command

      Next_Arg := 1;
      loop
         exit when Next_Arg > Argument_Count;

         Process_One_Arg : declare
            Arg : constant String := Argument (Next_Arg);

         begin
            --  This argument must not be parsed, just add it to the list of
            --  linker's options.

            if Skip_Next then

               Skip_Next := False;

               Linker_Options.Increment_Last;
               Linker_Options.Table (Linker_Options.Last) :=
                 new String'(Arg);

            --  Case of argument which is a switch

            elsif Arg'Length /= 0 and then Arg (1) = '-' then
               if Arg'Length > 4 and then Arg (2 .. 5) = "gnat" then
                  Exit_With_Error
                    ("invalid switch: """ & Arg & """ (gnat not needed here)");
               end if;

               if Arg = "-Xlinker" then

                  --  Next argument should be sent directly to the linker.
                  --  We do not want to parse it here.

                  Skip_Next := True;

                  Linker_Options.Increment_Last;
                  Linker_Options.Table (Linker_Options.Last) :=
                    new String'(Arg);

               elsif Arg (2) = 'g'
                 and then (Arg'Length < 5 or else Arg (2 .. 5) /= "gnat")
               then
                  Debug_Flag_Present := True;

                  Linker_Options.Increment_Last;
                  Linker_Options.Table (Linker_Options.Last) :=
                   new String'(Arg);

                  Binder_Options.Increment_Last;
                  Binder_Options.Table (Binder_Options.Last) :=
                    Linker_Options.Table (Linker_Options.Last);

               elsif Arg'Length >= 3 and then Arg (2) = 'M' then
                  declare
                     Switches : String_List_Access;

                  begin
                     Convert (Map_File, Arg (3 .. Arg'Last), Switches);

                     if Switches /= null then
                        for J in Switches'Range loop
                           Linker_Options.Increment_Last;
                           Linker_Options.Table (Linker_Options.Last) :=
                             Switches (J);
                        end loop;
                     end if;
                  end;

               elsif Arg'Length = 2 then
                  case Arg (2) is
                     when 'f' =>
                        if Object_List_File_Supported then
                           Object_List_File_Required := True;
                        else
                           Exit_With_Error
                             ("Object list file not supported on this target");
                        end if;

                     when 'M' =>
                        Create_Map_File := True;

                     when 'n' =>
                        Compile_Bind_File := False;

                     when 'o' =>
                        Next_Arg := Next_Arg + 1;

                        if Next_Arg > Argument_Count then
                           Exit_With_Error ("Missing argument for -o");
                        end if;

                        Output_File_Name :=
                          new String'(Executable_Name
                                        (Argument (Next_Arg),
                                         Only_If_No_Suffix => True));

                     when 'P' =>
                        Opt.CodePeer_Mode := True;

                     when 'R' =>
                        Opt.Run_Path_Option := False;

                     when 'v' =>

                        --  Support "double" verbose mode. Second -v
                        --  gets sent to the linker and binder phases.

                        if Verbose_Mode then
                           Very_Verbose_Mode := True;

                           Linker_Options.Increment_Last;
                           Linker_Options.Table (Linker_Options.Last) :=
                            new String'(Arg);

                           Binder_Options.Increment_Last;
                           Binder_Options.Table (Binder_Options.Last) :=
                             Linker_Options.Table (Linker_Options.Last);

                        else
                           Verbose_Mode := True;

                        end if;

                     when others =>
                        Linker_Options.Increment_Last;
                        Linker_Options.Table (Linker_Options.Last) :=
                         new String'(Arg);

                  end case;

               elsif Arg (2) = 'B' then
                  Linker_Options.Increment_Last;
                  Linker_Options.Table (Linker_Options.Last) :=
                    new String'(Arg);

                  Binder_Options.Increment_Last;
                  Binder_Options.Table (Binder_Options.Last) :=
                    Linker_Options.Table (Linker_Options.Last);

               elsif Arg'Length >= 7 and then Arg (1 .. 7) = "--LINK=" then
                  if Arg'Length = 7 then
                     Exit_With_Error ("Missing argument for --LINK=");
                  end if;

                  declare
                     L_Args : constant Argument_List_Access :=
                               Argument_String_To_List (Arg (8 .. Arg'Last));
                  begin
                     --  The linker program is the first argument

                     Linker_Path :=
                      System.OS_Lib.Locate_Exec_On_Path (L_Args.all (1).all);

                     if Linker_Path = null then
                        Exit_With_Error
                          ("Could not locate linker: " & L_Args.all (1).all);
                     end if;

                     --  The other arguments are passed as-is to the linker and
                     --  override those coming from --GCC= if any.

                     if L_Args.all'Last >= 2 then
                        Gcc_Linker_Options.Set_Last (0);
                     end if;

                     for J in 2 .. L_Args.all'Last loop
                        Gcc_Linker_Options.Increment_Last;
                        Gcc_Linker_Options.Table
                          (Gcc_Linker_Options.Last) :=
                                             new String'(L_Args.all (J).all);
                     end loop;
                  end;

               elsif Arg'Length >= 6 and then Arg (1 .. 6) = "--GCC=" then
                  if Arg'Length = 6 then
                     Exit_With_Error ("Missing argument for --GCC=");
                  end if;

                  declare
                     Program_Args : constant Argument_List_Access :=
                                      Argument_String_To_List
                                                 (Arg (7 .. Arg'Last));

                  begin
                     if Program_Args.all (1).all /= Gcc.all then
                        Gcc := new String'(Program_Args.all (1).all);
                        Standard_Gcc := False;
                     end if;

                     --  Set appropriate flags for switches passed

                     for J in 2 .. Program_Args.all'Last loop
                        declare
                           Arg : constant String := Program_Args.all (J).all;
                           AF  : constant Integer := Arg'First;

                        begin
                           if Arg'Length /= 0 and then Arg (AF) = '-' then
                              if Arg (AF + 1) = 'g'
                                and then (Arg'Length = 2
                                  or else Arg (AF + 2) in '0' .. '3'
                                  or else Arg (AF + 2 .. Arg'Last) = "coff")
                              then
                                 Debug_Flag_Present := True;
                              end if;
                           end if;

                           --  Add directory to source search dirs so that
                           --  Get_Target_Parameters can find system.ads

                           if Arg (AF .. AF + 1) = "-I"
                             and then Arg'Length > 2
                           then
                              Add_Src_Search_Dir (Arg (AF + 2 .. Arg'Last));
                           end if;

                           --  Pass to gcc for compiling binder generated file
                           --  No use passing libraries, it will just generate
                           --  a warning

                           if not (Arg (AF .. AF + 1) = "-l"
                             or else Arg (AF .. AF + 1) = "-L")
                           then
                              Binder_Options.Increment_Last;
                              Binder_Options.Table (Binder_Options.Last) :=
                                new String'(Arg);
                           end if;

                           --  Pass to gcc for linking program

                           Gcc_Linker_Options.Increment_Last;
                           Gcc_Linker_Options.Table
                             (Gcc_Linker_Options.Last) := new String'(Arg);
                        end;
                     end loop;
                  end;

               --  Send all multi-character switches not recognized as
               --  a special case by gnatlink to the linker/loader stage.

               else
                  Linker_Options.Increment_Last;
                  Linker_Options.Table (Linker_Options.Last) :=
                    new String'(Arg);
               end if;

            --  Here if argument is a file name rather than a switch

            else
               --  If explicit ali file, capture it

               if Arg'Length > 4
                 and then Arg (Arg'Last - 3 .. Arg'Last) = ".ali"
               then
                  if Ali_File_Name = null then
                     Ali_File_Name := new String'(Arg);
                  else
                     Exit_With_Error ("cannot handle more than one ALI file");
                  end if;

               --  If target object file, record object file

               elsif Arg'Length > Get_Target_Object_Suffix.all'Length
                 and then Arg
                   (Arg'Last -
                    Get_Target_Object_Suffix.all'Length + 1 .. Arg'Last)
                   = Get_Target_Object_Suffix.all
               then
                  Linker_Objects.Increment_Last;
                  Linker_Objects.Table (Linker_Objects.Last) :=
                    new String'(Arg);

               --  If host object file, record object file

               elsif Arg'Length > Get_Object_Suffix.all'Length
                 and then Arg
                   (Arg'Last - Get_Object_Suffix.all'Length + 1 .. Arg'Last)
                                                = Get_Object_Suffix.all
               then
                  Linker_Objects.Increment_Last;
                  Linker_Objects.Table (Linker_Objects.Last) :=
                    new String'(Arg);

               --  If corresponding ali file exists, capture it

               elsif Ali_File_Name = null
                 and then Is_Regular_File (Arg & ".ali")
               then
                  Ali_File_Name := new String'(Arg & ".ali");

               --  Otherwise assume this is a linker options entry, but
               --  see below for interesting adjustment to this assumption.

               else
                  Linker_Options.Increment_Last;
                  Linker_Options.Table (Linker_Options.Last) :=
                    new String'(Arg);
               end if;
            end if;
         end Process_One_Arg;

         Next_Arg := Next_Arg + 1;
      end loop;

      --  Compile the bind file with warnings suppressed, because
      --  otherwise the with of the main program may cause junk warnings.

      Binder_Options.Increment_Last;
      Binder_Options.Table (Binder_Options.Last) := new String'("-gnatws");

      --  If we did not get an ali file at all, and we had at least one
      --  linker option, then assume that was the intended ali file after
      --  all, so that we get a nicer message later on.

      if Ali_File_Name = null
        and then Linker_Options.Last >= Linker_Options.First
      then
         Ali_File_Name :=
           new String'(Linker_Options.Table (Linker_Options.First).all
                       & ".ali");
      end if;
   end Process_Args;

   -------------------------
   -- Process_Binder_File --
   -------------------------

   procedure Process_Binder_File (Name : String) is
      Fd : FILEs;
      --  Binder file's descriptor

      Link_Bytes : Integer := 0;
      --  Projected number of bytes for the linker command line

      Next_Line : String (1 .. 1000);
      --  Current line value

      Nlast  : Integer;
      Nfirst : Integer;
      --  Current line slice (the slice does not contain line terminator)

      Last : Integer;
      --  Current line last character for shared libraries (without version)

      Objs_Begin : Integer := 0;
      --  First object file index in Linker_Objects table

      Objs_End : Integer := 0;
      --  Last object file index in Linker_Objects table

      Status : int;
      pragma Warnings (Off, Status);
      --  Used for various Interfaces.C_Streams calls

      Closing_Status : Boolean;
      pragma Warnings (Off, Closing_Status);
      --  For call to Close

      GNAT_Static : Boolean := False;
      --  Save state of -static option

      GNAT_Shared : Boolean := False;
      --  Save state of -shared option

      Xlinker_Was_Previous : Boolean := False;
      --  Indicate that "-Xlinker" was the option preceding the current option.
      --  If True, then the current option is never suppressed.

      --  Rollback data

      --  These data items are used to store current binder file context. The
      --  context is composed of the file descriptor position and the current
      --  line together with the slice indexes (first and last position) for
      --  this line. The rollback data are used by the Store_File_Context and
      --  Rollback_File_Context routines below. The file context mechanism
      --  interact only with the Get_Next_Line call. For example:

      --     Store_File_Context;
      --     Get_Next_Line;
      --     Rollback_File_Context;
      --     Get_Next_Line;

      --  Both Get_Next_Line calls above will read the exact same data from
      --  the file. In other words, Next_Line, Nfirst and Nlast variables
      --  will be set with the exact same values.

      RB_File_Pos  : long;                -- File position
      RB_Next_Line : String (1 .. 1000);  -- Current line content
      RB_Nlast     : Integer;             -- Slice last index
      RB_Nfirst    : Integer;             -- Slice first index

      procedure Get_Next_Line;
      --  Read the next line from the binder file without the line
      --  terminator.

      procedure Store_File_Context;
      --  Store current file context, Fd position and current line data.
      --  The file context is stored into the rollback data above (RB_*).
      --  Store_File_Context can be called at any time, only the last call
      --  will be used (i.e. this routine overwrites the file context).

      procedure Rollback_File_Context;
      --  Restore file context from rollback data. This routine must be called
      --  after Store_File_Context. The binder file context will be restored
      --  with the data stored by the last Store_File_Context call.

      procedure Write_RF (S : String);
      --  Write a string to the response file and check if it was successful.
      --  Fail the program if it was not successful (disk full).

      -------------------
      -- Get_Next_Line --
      -------------------

      procedure Get_Next_Line is
         Fchars : chars;

      begin
         Fchars := fgets (Next_Line'Address, Next_Line'Length, Fd);

         if Fchars = System.Null_Address then
            Exit_With_Error ("Error reading binder output");
         end if;

         Nfirst := Next_Line'First;
         Nlast := Nfirst;
         while Nlast <= Next_Line'Last
           and then Next_Line (Nlast) /= ASCII.LF
           and then Next_Line (Nlast) /= ASCII.CR
         loop
            Nlast := Nlast + 1;
         end loop;

         Nlast := Nlast - 1;
      end Get_Next_Line;

      ---------------------------
      -- Rollback_File_Context --
      ---------------------------

      procedure Rollback_File_Context is
      begin
         Next_Line := RB_Next_Line;
         Nfirst    := RB_Nfirst;
         Nlast     := RB_Nlast;
         Status    := fseek (Fd, RB_File_Pos, Interfaces.C_Streams.SEEK_SET);

         if Status = -1 then
            Exit_With_Error ("Error setting file position");
         end if;
      end Rollback_File_Context;

      ------------------------
      -- Store_File_Context --
      ------------------------

      procedure Store_File_Context is
         use type System.CRTL.long;

      begin
         RB_Next_Line := Next_Line;
         RB_Nfirst    := Nfirst;
         RB_Nlast     := Nlast;
         RB_File_Pos  := ftell (Fd);

         if RB_File_Pos = -1 then
            Exit_With_Error ("Error getting file position");
         end if;
      end Store_File_Context;

      --------------
      -- Write_RF --
      --------------

      procedure Write_RF (S : String) is
         Success    : Boolean            := True;
         Back_Slash : constant Character := '\';

      begin
         --  If a GNU response file is used, space and backslash need to be
         --  escaped because they are interpreted as a string separator and
         --  an escape character respectively by the underlying mechanism.
         --  On the other hand, quote and double-quote are not escaped since
         --  they are interpreted as string delimiters on both sides.

         if Using_GNU_response_file then
            for J in S'Range loop
               if S (J) = ' ' or else S (J) = '\' then
                  if Write (Tname_FD, Back_Slash'Address, 1) /= 1 then
                     Success := False;
                  end if;
               end if;

               if Write (Tname_FD, S (J)'Address, 1) /= 1 then
                  Success := False;
               end if;
            end loop;

         else
            if Write (Tname_FD, S'Address, S'Length) /= S'Length then
               Success := False;
            end if;
         end if;

         if Write (Tname_FD, ASCII.LF'Address, 1) /= 1 then
            Success := False;
         end if;

         if not Success then
            Exit_With_Error ("Error generating response file: disk full");
         end if;
      end Write_RF;

   --  Start of processing for Process_Binder_File

   begin
      Fd := fopen (Name'Address, Read_Mode'Address);

      if Fd = NULL_Stream then
         Exit_With_Error ("Failed to open binder output");
      end if;

      --  Skip up to the Begin Info line

      loop
         Get_Next_Line;
         exit when Next_Line (Nfirst .. Nlast) = Begin_Info;
      end loop;

      loop
         Get_Next_Line;

         --  Go to end when end line is reached (this will happen in
         --  High_Integrity_Mode where no -L switches are generated)

         exit when Next_Line (Nfirst .. Nlast) = End_Info;

         Next_Line (Nfirst .. Nlast - 8) := Next_Line (Nfirst + 8 .. Nlast);
         Nlast := Nlast - 8;

         --  Go to next section when switches are reached

         exit when Next_Line (1) = '-';

         --  Otherwise we have another object file to collect

         Linker_Objects.Increment_Last;

         --  Mark the positions of first and last object files in case they
         --  need to be placed with a named file on systems having linker
         --  line limitations.

         if Objs_Begin = 0 then
            Objs_Begin := Linker_Objects.Last;
         end if;

         Linker_Objects.Table (Linker_Objects.Last) :=
           new String'(Next_Line (Nfirst .. Nlast));

         --  Nlast - Nfirst + 1, for the size, plus one for the space between
         --  each arguments.

         Link_Bytes := Link_Bytes + Nlast - Nfirst + 2;
      end loop;

      Objs_End := Linker_Objects.Last;

      --  Continue to compute the Link_Bytes, the linker options are part of
      --  command line length.

      Store_File_Context;

      while Next_Line (Nfirst .. Nlast) /= End_Info loop
         Link_Bytes := Link_Bytes + Nlast - Nfirst + 2;
         Get_Next_Line;
      end loop;

      Rollback_File_Context;

      --  On systems that have limitations on handling very long linker lines
      --  we make use of the system linker option which takes a list of object
      --  file names from a file instead of the command line itself. What we do
      --  is to replace the list of object files by the special linker option
      --  which then reads the object file list from a file instead. The option
      --  to read from a file instead of the command line is only triggered if
      --  a conservative threshold is passed.

      if Object_List_File_Required
        or else (Object_List_File_Supported
                   and then Link_Bytes > Link_Max)
      then
         --  Create a temporary file containing the Ada user object files
         --  needed by the link. This list is taken from the bind file and is
         --  output one object per line for maximal compatibility with linkers
         --  supporting this option.

         Create_Temp_File (Tname_FD, Tname);

         --  ??? File descriptor should be checked to not be Invalid_FD.
         --  Status of Write and Close operations should be checked, and
         --  failure should occur if a status is wrong.

         for J in Objs_Begin .. Objs_End loop
            Write_RF (Linker_Objects.Table (J).all);

            Response_File_Objects.Increment_Last;
            Response_File_Objects.Table (Response_File_Objects.Last) :=
              Linker_Objects.Table (J);
         end loop;

         Close (Tname_FD, Closing_Status);

         --  Add the special objects list file option together with the name
         --  of the temporary file (removing the null character) to the objects
         --  file table.

         Linker_Objects.Table (Objs_Begin) :=
           new String'(Object_File_Option &
                       Tname (Tname'First .. Tname'Last - 1));

         --  The slots containing these object file names are then removed
         --  from the objects table so they do not appear in the link. They are
         --  removed by moving up the linker options and non-Ada object files
         --  appearing after the Ada object list in the table.

         declare
            N : Integer;

         begin
            N := Objs_End - Objs_Begin + 1;

            for J in Objs_End + 1 .. Linker_Objects.Last loop
               Linker_Objects.Table (J - N + 1) := Linker_Objects.Table (J);
            end loop;

            Linker_Objects.Set_Last (Linker_Objects.Last - N + 1);
         end;
      end if;

      --  Process switches and options

      if Next_Line (Nfirst .. Nlast) /= End_Info then
         Xlinker_Was_Previous := False;

         loop
            if Xlinker_Was_Previous
              or else Next_Line (Nfirst .. Nlast) = "-Xlinker"
            then
               Linker_Options.Increment_Last;
               Linker_Options.Table (Linker_Options.Last) :=
                 new String'(Next_Line (Nfirst .. Nlast));

            elsif Next_Line (Nfirst .. Nlast) = "-static" then
               GNAT_Static := True;

            elsif Next_Line (Nfirst .. Nlast) = "-shared" then
               GNAT_Shared := True;

            --  Add binder options only if not already set on the command line.
            --  This rule is a way to control the linker options order.

            else
               if Nlast > Nfirst + 2 and then
                 Next_Line (Nfirst .. Nfirst + 1) = "-L"
               then
                  --  Construct a library search path for use later to locate
                  --  static gnatlib libraries.

                  if Libpath.Last > 1 then
                     Libpath.Increment_Last;
                     Libpath.Table (Libpath.Last) := Path_Separator;
                  end if;

                  for I in Nfirst + 2 .. Nlast loop
                     Libpath.Increment_Last;
                     Libpath.Table (Libpath.Last) := Next_Line (I);
                  end loop;

                  Linker_Options.Increment_Last;

                  Linker_Options.Table (Linker_Options.Last) :=
                    new String'(Next_Line (Nfirst .. Nlast));

               elsif Next_Line (Nfirst .. Nlast) = "-lgnarl"
                 or else Next_Line (Nfirst .. Nlast) = "-lgnat"
                 or else
                   Next_Line
                     (1 .. Natural'Min (Nlast, 8 + Library_Version'Length)) =
                       Shared_Lib ("gnarl")
                 or else
                   Next_Line
                     (1 .. Natural'Min (Nlast, 7 + Library_Version'Length)) =
                       Shared_Lib ("gnat")
               then
                  --  If it is a shared library, remove the library version.
                  --  We will be looking for the static version of the library
                  --  as it is in the same directory as the shared version.

                  if Nlast >= Library_Version'Length
                    and then
                      Next_Line (Nlast - Library_Version'Length + 1 .. Nlast) =
                        Library_Version
                  then
                     --  Set Last to point to last character before the
                     --  library version.

                     Last := Nlast - Library_Version'Length - 1;
                  else
                     Last := Nlast;
                  end if;

                  Search_Library_Path
                    (Next_Line   => Next_Line,
                     Nfirst      => Nfirst,
                     Nlast       => Nlast,
                     Last        => Last,
                     GNAT_Static => GNAT_Static,
                     GNAT_Shared => GNAT_Shared);

               else
                  Linker_Options.Increment_Last;
                  Linker_Options.Table (Linker_Options.Last) :=
                    new String'(Next_Line (Nfirst .. Nlast));
               end if;
            end if;

            Xlinker_Was_Previous := Next_Line (Nfirst .. Nlast) = "-Xlinker";

            Get_Next_Line;
            exit when Next_Line (Nfirst .. Nlast) = End_Info;

            Next_Line (Nfirst .. Nlast - 8) := Next_Line (Nfirst + 8 .. Nlast);
            Nlast := Nlast - 8;
         end loop;
      end if;

      --  If -shared was specified, invoke gcc with -shared-libgcc

      if GNAT_Shared then
         Linker_Options.Increment_Last;
         Linker_Options.Table (Linker_Options.Last) := Shared_Libgcc;
      end if;

      Status := fclose (Fd);
   end Process_Binder_File;

   -------------------------
   -- Search_Library_Path --
   -------------------------

   procedure Search_Library_Path
     (Next_Line   : String;
      Nfirst      : Integer;
      Nlast       : Integer;
      Last        : Integer;
      GNAT_Static : Boolean;
      GNAT_Shared : Boolean)
   is
      File_Path : String_Access;

      Object_Lib_Extension : constant String :=
        Value (Object_Library_Ext_Ptr);

      File_Name : constant String := "lib" &
        Next_Line (Nfirst + 2 .. Last) & Object_Lib_Extension;

      Run_Path_Opt : constant String :=
        Value (Run_Path_Option_Ptr);

      GCC_Index          : Natural;
      Run_Path_Opt_Index : Natural := 0;

   begin
      File_Path :=
        Locate_Regular_File (File_Name,
          String (Libpath.Table (1 .. Libpath.Last)));

      if File_Path /= null then
         if GNAT_Static then

            --  If static gnatlib found, explicitly specify to overcome
            --  possible linker default usage of shared version.

            Linker_Options.Increment_Last;

            Linker_Options.Table (Linker_Options.Last) :=
              new String'(File_Path.all);

         elsif GNAT_Shared then
            if Opt.Run_Path_Option then

               --  If shared gnatlib desired, add appropriate system specific
               --  switch so that it can be located at runtime.

               if Run_Path_Opt'Length /= 0 then

                  --  Output the system specific linker command that allows the
                  --  image activator to find the shared library at
                  --  runtime. Also add path to find libgcc_s.so, if relevant.

                  declare
                     Path : String (1 .. File_Path'Length + 15);

                     Path_Last : constant Natural := File_Path'Length;

                  begin
                     Path (1 .. File_Path'Length) := File_Path.all;

                  --  To find the location of the shared version of libgcc, we
                  --  look for "gcc-lib" in the path of the library. However,
                  --  this subdirectory is no longer present in recent versions
                  --  of GCC. So, we look for the last subdirectory "lib" in
                  --  the path.

                     GCC_Index := Index (Path (1 .. Path_Last), "gcc-lib");

                     if GCC_Index /= 0 then

                        --  The shared version of libgcc is located in the
                        --  parent directory.

                        GCC_Index := GCC_Index - 1;

                     else
                        GCC_Index := Index (Path (1 .. Path_Last), "/lib/");

                        if GCC_Index = 0 then
                           GCC_Index :=
                             Index (Path (1 .. Path_Last),
                                    Directory_Separator & "lib"
                                    & Directory_Separator);
                        end if;

                        --  If we have found a "lib" subdir in the path to
                        --  libgnat, the possible shared libgcc of interest by
                        --  default is in libgcc_subdir at the same level.

                        if GCC_Index /= 0 then
                           declare
                              Subdir : constant String :=
                                Value (Libgcc_Subdir_Ptr);

                           begin
                              Path (GCC_Index + 1 .. GCC_Index + Subdir'Length)
                                := Subdir;
                              GCC_Index := GCC_Index + Subdir'Length;
                           end;
                        end if;
                     end if;

                  --  Look for an eventual run_path_option in
                  --  the linker switches.

                     if Separate_Run_Path_Options then
                        Linker_Options.Increment_Last;
                        Linker_Options.Table
                          (Linker_Options.Last) :=
                            new String'
                              (Run_Path_Opt
                               & File_Path
                                 (1 .. File_Path'Length
                                  - File_Name'Length));

                        if GCC_Index /= 0 then
                           Linker_Options.Increment_Last;
                           Linker_Options.Table (Linker_Options.Last) :=
                             new String'
                               (Run_Path_Opt
                                & Path (1 .. GCC_Index));
                        end if;

                     else
                        for J in reverse 1 .. Linker_Options.Last loop
                           if Linker_Options.Table (J) /= null
                             and then
                               Linker_Options.Table (J)'Length
                                         > Run_Path_Opt'Length
                             and then
                               Linker_Options.Table (J)
                                 (1 .. Run_Path_Opt'Length) =
                                                  Run_Path_Opt
                           then
                              --  We have found an already specified
                              --  run_path_option: we will add to this switch,
                              --  because only one run_path_option should be
                              --  specified.

                              Run_Path_Opt_Index := J;
                              exit;
                           end if;
                        end loop;

                        --  If there is no run_path_option, we need to add one.

                        if Run_Path_Opt_Index = 0 then
                           Linker_Options.Increment_Last;
                        end if;

                        if GCC_Index = 0 then
                           if Run_Path_Opt_Index = 0 then
                              Linker_Options.Table
                                (Linker_Options.Last) :=
                                  new String'
                                    (Run_Path_Opt
                                     & File_Path
                                       (1 .. File_Path'Length
                                        - File_Name'Length));

                           else
                              Linker_Options.Table
                                (Run_Path_Opt_Index) :=
                                  new String'
                                    (Linker_Options.Table
                                      (Run_Path_Opt_Index).all
                                     & Path_Separator
                                     & File_Path
                                       (1 .. File_Path'Length
                                        - File_Name'Length));
                           end if;

                        else
                           if Run_Path_Opt_Index = 0 then
                              Linker_Options.Table
                                (Linker_Options.Last) :=
                                  new String'
                                    (Run_Path_Opt
                                     & File_Path
                                       (1 .. File_Path'Length
                                        - File_Name'Length)
                                     & Path_Separator
                                     & Path (1 .. GCC_Index));

                           else
                              Linker_Options.Table
                                (Run_Path_Opt_Index) :=
                                  new String'
                                    (Linker_Options.Table
                                      (Run_Path_Opt_Index).all
                                     & Path_Separator
                                     & File_Path
                                       (1 .. File_Path'Length
                                        - File_Name'Length)
                                     & Path_Separator
                                     & Path (1 .. GCC_Index));
                           end if;
                        end if;
                     end if;
                  end;
               end if;
            end if;

            --  Then we add the appropriate -l switch

            Linker_Options.Increment_Last;
            Linker_Options.Table (Linker_Options.Last) :=
              new String'(Next_Line (Nfirst .. Nlast));
         end if;

      else
         --  If gnatlib library not found, then add it anyway in
         --  case some other mechanism may find it.

         Linker_Options.Increment_Last;
         Linker_Options.Table (Linker_Options.Last) :=
           new String'(Next_Line (Nfirst .. Nlast));
      end if;
   end Search_Library_Path;

   -----------
   -- Usage --
   -----------

   procedure Usage is
   begin
      Write_Str ("Usage: ");
      Write_Str (Base_Command_Name.all);
      Write_Str (" switches mainprog.ali [non-Ada-objects] [linker-options]");
      Write_Eol;
      Write_Eol;
      Write_Line ("  mainprog.ali   the ALI file of the main program");
      Write_Eol;
      Write_Eol;
      Display_Usage_Version_And_Help;
      Write_Line ("  -f    Force object file list to be generated");
      Write_Line ("  -g    Compile binder source file with debug information");
      Write_Line ("  -n    Do not compile the binder source file");
      Write_Line ("  -P    Process files for use by CodePeer");
      Write_Line ("  -R    Do not use a run_path_option");
      Write_Line ("  -v    Verbose mode");
      Write_Line ("  -v -v Very verbose mode");
      Write_Eol;
      Write_Line ("  -o nam     Use 'nam' as the name of the executable");
      Write_Line ("  -Bdir      Load compiler executables from dir");

      if Is_Supported (Map_File) then
         Write_Line ("  -Mmap      Create map file map");
         Write_Line ("  -M         Create map file mainprog.map");
      end if;

      Write_Line ("  --GCC=comp Use 'comp' as the compiler rather than 'gcc'");
      Write_Line ("  --LINK=lnk Use 'lnk' as the linker rather than 'gcc'");
      Write_Eol;
      Write_Line ("  [non-Ada-objects]  list of non Ada object files");
      Write_Line ("  [linker-options]   other options for the linker");
   end Usage;

   ------------------
   -- Write_Header --
   ------------------

   procedure Write_Header is
   begin
      if Verbose_Mode then
         Write_Eol;
         Display_Version ("GNATLINK", "1995");
      end if;
   end Write_Header;

   -----------------
   -- Write_Usage --
   -----------------

   procedure Write_Usage is
   begin
      Write_Header;
      Usage;
   end Write_Usage;

--  Start of processing for Gnatlink

begin
   --  Add the directory where gnatlink is invoked in front of the path, if
   --  gnatlink is invoked with directory information.

   declare
      Command : constant String := Command_Name;
   begin
      for Index in reverse Command'Range loop
         if Command (Index) = Directory_Separator then
            declare
               Absolute_Dir : constant String :=
                 Normalize_Pathname
                   (Command (Command'First .. Index));

               PATH : constant String :=
                 Absolute_Dir &
                 Path_Separator &
                 Getenv ("PATH").all;

            begin
               Setenv ("PATH", PATH);
            end;

            exit;
         end if;
      end loop;
   end;

   Base_Command_Name := new String'(Base_Name (Command_Name));
   Process_Args;

   if Argument_Count = 0
     or else (Verbose_Mode and then Argument_Count = 1)
   then
      Write_Usage;
      Exit_Program (E_Fatal);
   end if;

   --  Initialize packages to be used

   Csets.Initialize;
   Snames.Initialize;

   --  We always compile with -c

   Binder_Options_From_ALI.Increment_Last;
   Binder_Options_From_ALI.Table (Binder_Options_From_ALI.Last) :=
     new String'("-c");

   if Ali_File_Name = null then
      Exit_With_Error ("no ali file given for link");
   end if;

   if not Is_Regular_File (Ali_File_Name.all) then
      Exit_With_Error (Ali_File_Name.all & " not found");
   end if;

   --  Read the ALI file of the main subprogram if the binder generated file
   --  needs to be compiled and no --GCC= switch has been specified. Fetch the
   --  back end switches from this ALI file and use these switches to compile
   --  the binder generated file

   if Compile_Bind_File and then Standard_Gcc then
      Initialize_ALI;
      Name_Len := Ali_File_Name'Length;
      Name_Buffer (1 .. Name_Len) := Ali_File_Name.all;

      declare
         use Types;
         F : constant File_Name_Type := Name_Find;
         T : Text_Buffer_Ptr;
         A : ALI_Id;

      begin
         --  Load the ALI file

         T := Read_Library_Info (F, True);

         --  Read it. Note that we ignore errors, since we only want very
         --  limited information from the ali file, and likely a slightly
         --  wrong version will be just fine, though in normal operation
         --  we don't expect this to happen.

         A := Scan_ALI
               (F,
                T,
                Err           => False,
                Ignore_Errors => True);

         if A /= No_ALI_Id then
            for
              Index in Units.Table (ALIs.Table (A).First_Unit).First_Arg ..
                       Units.Table (ALIs.Table (A).First_Unit).Last_Arg
            loop
               --  Do not compile with the front end switches. However, --RTS
               --  is to be dealt with specially because it needs to be passed
               --  to compile the file generated by the binder.

               declare
                  Arg : String_Ptr renames Args.Table (Index);
               begin
                  if not Is_Front_End_Switch (Arg.all) then
                     Binder_Options_From_ALI.Increment_Last;
                     Binder_Options_From_ALI.Table
                       (Binder_Options_From_ALI.Last) := String_Access (Arg);

                     --  GNAT doesn't support GCC's multilib mechanism when it
                     --  is configured with --disable-libada. This means that,
                     --  when a multilib switch is used to request a particular
                     --  compilation mode, the corresponding --RTS switch must
                     --  also be specified. It is convenient to eliminate the
                     --  redundancy by keying the compilation mode on a single
                     --  switch, namely --RTS, and have the compiler reinstate
                     --  the multilib switch (see gcc-interface/lang-specs.h).
                     --  This switch must be passed to the driver at link time.

                     if Arg'Length = 5
                       and then Arg (Arg'First + 1 .. Arg'First + 4) = "mrtp"
                     then
                        Linker_Options.Increment_Last;
                        Linker_Options.Table
                          (Linker_Options.Last) := String_Access (Arg);
                     end if;

                  elsif Arg'Length > 5
                    and then Arg (Arg'First + 2 .. Arg'First + 5) = "RTS="
                  then
                     Binder_Options_From_ALI.Increment_Last;
                     Binder_Options_From_ALI.Table
                       (Binder_Options_From_ALI.Last) := String_Access (Arg);

                     --  Set the RTS_*_Path_Name variables, so that
                     --  the correct directories will be set when
                     --  Osint.Add_Default_Search_Dirs will be called later.

                     Opt.RTS_Src_Path_Name :=
                       Get_RTS_Search_Dir
                         (Arg (Arg'First + 6 .. Arg'Last), Include);

                     Opt.RTS_Lib_Path_Name :=
                       Get_RTS_Search_Dir
                         (Arg (Arg'First + 6 .. Arg'Last), Objects);
                  end if;
               end;
            end loop;
         end if;
      end;
   end if;

   --  Get target parameters

   Osint.Add_Default_Search_Dirs;
   Targparm.Get_Target_Parameters;

   --  Compile the bind file with the following switches:

   --    -gnatA   stops reading gnat.adc, since we don't know what
   --             pragmas would work, and we do not need it anyway.

   --    -gnatWb  allows brackets coding for wide characters

   --    -gnatiw  allows wide characters in identifiers. This is needed
   --             because bindgen uses brackets encoding for all upper
   --             half and wide characters in identifier names.

   --  In addition, in CodePeer mode compile with -x adascil -gnatcC

   Binder_Options_From_ALI.Increment_Last;
   Binder_Options_From_ALI.Table (Binder_Options_From_ALI.Last) :=
        new String'("-gnatA");
   Binder_Options_From_ALI.Increment_Last;
   Binder_Options_From_ALI.Table (Binder_Options_From_ALI.Last) :=
        new String'("-gnatWb");
   Binder_Options_From_ALI.Increment_Last;
   Binder_Options_From_ALI.Table (Binder_Options_From_ALI.Last) :=
        new String'("-gnatiw");

   if Opt.CodePeer_Mode then
      Binder_Options_From_ALI.Increment_Last;
      Binder_Options_From_ALI.Table (Binder_Options_From_ALI.Last) :=
        new String'("-x");
      Binder_Options_From_ALI.Increment_Last;
      Binder_Options_From_ALI.Table (Binder_Options_From_ALI.Last) :=
        new String'("adascil");
      Binder_Options_From_ALI.Increment_Last;
      Binder_Options_From_ALI.Table (Binder_Options_From_ALI.Last) :=
        new String'("-gnatcC");
   end if;

   --  Locate all the necessary programs and verify required files are present

   Gcc_Path := System.OS_Lib.Locate_Exec_On_Path (Gcc.all);

   if Gcc_Path = null then
      Exit_With_Error ("Couldn't locate " & Gcc.all);
   end if;

   if Linker_Path = null then
      Linker_Path := Gcc_Path;
   end if;

   Write_Header;

   Target_Debuggable_Suffix := Get_Target_Debuggable_Suffix;

   --  If no output name specified, then use the base name of .ali file name

   if Output_File_Name = null then
      Output_File_Name :=
        new String'(Base_Name (Ali_File_Name.all)
                      & Target_Debuggable_Suffix.all);
   end if;

   Linker_Options.Increment_Last;
   Linker_Options.Table (Linker_Options.Last) := new String'("-o");

   Linker_Options.Increment_Last;
   Linker_Options.Table (Linker_Options.Last) :=
     new String'(Output_File_Name.all);

   Check_Existing_Executable (Output_File_Name.all);

   --  Warn if main program is called "test", as that may be a built-in command
   --  on Unix. On non-Unix systems executables have a suffix, so the warning
   --  will not appear. However, do not warn in the case of a cross compiler.

   --  Assume this is a cross tool if the executable name is not gnatlink.
   --  Note that the executable name is also gnatlink on windows, but in that
   --  case the output file name will be test.exe rather than test.

   if Base_Command_Name.all = "gnatlink"
     and then Output_File_Name.all = "test"
   then
      Error_Msg ("warning: executable name """ & Output_File_Name.all
                 & """ may conflict with shell command");
   end if;

   --  Special warnings for worrisome file names on windows

   --  Recent versions of Windows by default cause privilege escalation if an
   --  executable file name contains substrings "install", "setup", "update"
   --  or "patch". A console application will typically fail to load as a
   --  result, so we should warn the user.

   Bad_File_Names_On_Windows : declare
      FN : String := Output_File_Name.all;

      procedure Check_File_Name (S : String);
      --  Warn if file name has the substring S

      procedure Check_File_Name (S : String) is
      begin
         for J in 1 .. FN'Length - (S'Length - 1) loop
            if FN (J .. J + (S'Length - 1)) = S then
               Error_Msg
                 ("warning: executable file name """ & Output_File_Name.all
                  & """ contains substring """ & S & '"');
               Error_Msg
                 ("admin privileges may be required to run this file");
            end if;
         end loop;
      end Check_File_Name;

   --  Start of processing for Bad_File_Names_On_Windows

   begin
      for J in FN'Range loop
            FN (J) := Csets.Fold_Lower (FN (J));
      end loop;

      --  For now we detect Windows by its executable suffix of .exe

      if Target_Debuggable_Suffix.all = ".exe" then
         Check_File_Name ("install");
         Check_File_Name ("setup");
         Check_File_Name ("update");
         Check_File_Name ("patch");
      end if;
   end Bad_File_Names_On_Windows;

   --  If -M switch was specified, add the switches to create the map file

   if Create_Map_File then
      declare
         Map_Name : constant String := Base_Name (Ali_File_Name.all) & ".map";
         Switches : String_List_Access;

      begin
         Convert (Map_File, Map_Name, Switches);

         if Switches /= null then
            for J in Switches'Range loop
               Linker_Options.Increment_Last;
               Linker_Options.Table (Linker_Options.Last) := Switches (J);
            end loop;
         end if;
      end;
   end if;

   --  Perform consistency checks

   --  Transform the .ali file name into the binder output file name

   Make_Binder_File_Names : declare
      Fname     : constant String  := Base_Name (Ali_File_Name.all);
      Fname_Len : Integer := Fname'Length;

      Maximum_File_Name_Length : constant Integer :=
                                   Get_Maximum_File_Name_Length;

      Bind_File_Prefix : Types.String_Ptr;
      --  Contains prefix used for bind files

   begin
      --  Set prefix

      Bind_File_Prefix := new String'("b~");

      --  If the length of the binder file becomes too long due to
      --  the addition of the "b?" prefix, then truncate it.

      if Maximum_File_Name_Length > 0 then
         while Fname_Len >
                 Maximum_File_Name_Length - Bind_File_Prefix.all'Length
         loop
            Fname_Len := Fname_Len - 1;
         end loop;
      end if;

      declare
         Fnam : constant String :=
                  Bind_File_Prefix.all &
                    Fname (Fname'First .. Fname'First + Fname_Len - 1);

      begin
         Binder_Spec_Src_File := new String'(Fnam & ".ads");
         Binder_Body_Src_File := new String'(Fnam & ".adb");
         Binder_Ali_File      := new String'(Fnam & ".ali");

         Binder_Obj_File := new String'(Fnam & Get_Target_Object_Suffix.all);
      end;

      if Fname_Len /= Fname'Length then
         Binder_Options.Increment_Last;
         Binder_Options.Table (Binder_Options.Last) := new String'("-o");
         Binder_Options.Increment_Last;
         Binder_Options.Table (Binder_Options.Last) := Binder_Obj_File;
      end if;
   end Make_Binder_File_Names;

   Process_Binder_File (Binder_Body_Src_File.all & ASCII.NUL);

   --  Compile the binder file. This is fast, so we always do it, unless
   --  specifically told not to by the -n switch

   if Compile_Bind_File then
      Bind_Step : declare
         Success : Boolean;

         Args : Argument_List
                 (1 .. Binder_Options_From_ALI.Last + Binder_Options.Last + 1);

      begin
         for J in 1 .. Binder_Options_From_ALI.Last loop
            Args (J) := Binder_Options_From_ALI.Table (J);
         end loop;

         for J in 1 .. Binder_Options.Last loop
            Args (Binder_Options_From_ALI.Last + J) :=
              Binder_Options.Table (J);
         end loop;

         --  Use the full path of the binder generated source, so that it is
         --  guaranteed that the debugger will find this source, even with
         --  STABS.

         Args (Args'Last) :=
           new String'(Normalize_Pathname (Binder_Body_Src_File.all));

         if Verbose_Mode then
            Write_Str (Base_Name (Gcc_Path.all));

            for J in Args'Range loop
               Write_Str (" ");
               Write_Str (Args (J).all);
            end loop;

            Write_Eol;
         end if;

         System.OS_Lib.Spawn (Gcc_Path.all, Args, Success);

         if not Success then
            Exit_Program (E_Fatal);
         end if;
      end Bind_Step;
   end if;

   --  In CodePeer mode, there's nothing left to do after the binder file has
   --  been compiled.

   if Opt.CodePeer_Mode then
      if Tname_FD /= Invalid_FD then
         Delete (Tname);
      end if;

      return;
   end if;

   --  Now, actually link the program

   Link_Step : declare
      Num_Args : Natural :=
        (Linker_Options.Last - Linker_Options.First + 1) +
        (Gcc_Linker_Options.Last - Gcc_Linker_Options.First + 1) +
        (Linker_Objects.Last - Linker_Objects.First + 1);
      Stack_Op : Boolean := False;

   begin
      --  Remove duplicate stack size setting from the Linker_Options table.
      --  The stack setting option "-Xlinker --stack=R,C" can be found
      --  in one line when set by a pragma Linker_Options or in two lines
      --  ("-Xlinker" then "--stack=R,C") when set on the command line. We
      --  also check for the "-Wl,--stack=R" style option.

      --  We must remove the second stack setting option instance because
      --  the one on the command line will always be the first one. And any
      --  subsequent stack setting option will overwrite the previous one.
      --  This is done especially for GNAT/NT where we set the stack size
      --  for tasking programs by a pragma in the NT specific tasking
      --  package System.Task_Primitives.Operations.

      --  Note: This is not a FOR loop that runs from Linker_Options.First
      --  to Linker_Options.Last, since operations within the loop can
      --  modify the length of the table.

      Clean_Link_Option_Set : declare
         J                  : Natural;
         Shared_Libgcc_Seen : Boolean := False;
         Static_Libgcc_Seen : Boolean := False;

      begin
         J := Linker_Options.First;
         while J <= Linker_Options.Last loop
            if Linker_Options.Table (J).all = "-Xlinker"
              and then J < Linker_Options.Last
              and then Linker_Options.Table (J + 1)'Length > 8
              and then Linker_Options.Table (J + 1) (1 .. 8) = "--stack="
            then
               if Stack_Op then
                  Linker_Options.Table (J .. Linker_Options.Last - 2) :=
                    Linker_Options.Table (J + 2 .. Linker_Options.Last);
                  Linker_Options.Decrement_Last;
                  Linker_Options.Decrement_Last;
                  Num_Args := Num_Args - 2;

               else
                  Stack_Op := True;
               end if;
            end if;

            --  Remove duplicate -shared-libgcc switches

            if Linker_Options.Table (J).all = Shared_Libgcc_String then
               if Shared_Libgcc_Seen then
                  Linker_Options.Table (J .. Linker_Options.Last - 1) :=
                    Linker_Options.Table (J + 1 .. Linker_Options.Last);
                  Linker_Options.Decrement_Last;
                  Num_Args := Num_Args - 1;

               else
                  Shared_Libgcc_Seen := True;
               end if;
            end if;

            --  Remove duplicate -static-libgcc switches

            if Linker_Options.Table (J).all = Static_Libgcc_String then
               if Static_Libgcc_Seen then
                  Linker_Options.Table (J .. Linker_Options.Last - 1) :=
                    Linker_Options.Table (J + 1 .. Linker_Options.Last);
                  Linker_Options.Decrement_Last;
                  Num_Args := Num_Args - 1;

               else
                  Static_Libgcc_Seen := True;
               end if;
            end if;

            --  Here we just check for a canonical form that matches the
            --  pragma Linker_Options set in the NT runtime.

            if (Linker_Options.Table (J)'Length > 17
                and then Linker_Options.Table (J) (1 .. 17) =
                  "-Xlinker --stack=")
              or else
                (Linker_Options.Table (J)'Length > 12
                 and then Linker_Options.Table (J) (1 .. 12) =
                       "-Wl,--stack=")
            then
               if Stack_Op then
                  Linker_Options.Table (J .. Linker_Options.Last - 1) :=
                    Linker_Options.Table (J + 1 .. Linker_Options.Last);
                  Linker_Options.Decrement_Last;
                  Num_Args := Num_Args - 1;

               else
                  Stack_Op := True;
               end if;
            end if;

            J := J + 1;
         end loop;

         if Linker_Path = Gcc_Path then

            --  For systems where the default is to link statically with
            --  libgcc, if gcc is not called with -shared-libgcc, call it
            --  with -static-libgcc, as there are some platforms where one
            --  of these two switches is compulsory to link.
            --  Don't push extra switches if we already saw one.

            if Shared_Libgcc_Default = 'T'
              and then not Shared_Libgcc_Seen
              and then not Static_Libgcc_Seen
            then
               Linker_Options.Increment_Last;
               Linker_Options.Table (Linker_Options.Last) := Static_Libgcc;
               Num_Args := Num_Args + 1;
            end if;

            --  Likewise, the reverse.

            if Shared_Libgcc_Default = 'H'
              and then not Static_Libgcc_Seen
              and then not Shared_Libgcc_Seen
            then
               Linker_Options.Increment_Last;
               Linker_Options.Table (Linker_Options.Last) := Shared_Libgcc;
               Num_Args := Num_Args + 1;
            end if;
         end if;
      end Clean_Link_Option_Set;

      --  Prepare arguments for call to linker

      Call_Linker : declare
         Success  : Boolean;
         Args     : Argument_List (1 .. Num_Args + 1);
         Index    : Integer := Args'First;

      begin
         Args (Index) := Binder_Obj_File;

         --  Add the object files and any -largs libraries

         for J in Linker_Objects.First .. Linker_Objects.Last loop
            Index := Index + 1;
            Args (Index) := Linker_Objects.Table (J);
         end loop;

         --  Add the linker options from the binder file

         for J in Linker_Options.First .. Linker_Options.Last loop
            Index := Index + 1;
            Args (Index) := Linker_Options.Table (J);
         end loop;

         --  Finally add the libraries from the --GCC= switch

         for J in Gcc_Linker_Options.First .. Gcc_Linker_Options.Last loop
            Index := Index + 1;
            Args (Index) := Gcc_Linker_Options.Table (J);
         end loop;

         if Verbose_Mode then
            Write_Str (Linker_Path.all);

            for J in Args'Range loop
               Write_Str (" ");
               Write_Str (Args (J).all);
            end loop;

            Write_Eol;

            --  If we are on very verbose mode (-v -v) and a response file
            --  is used we display its content.

            if Very_Verbose_Mode and then Tname_FD /= Invalid_FD then
               Write_Eol;
               Write_Str ("Response file (" &
                            Tname (Tname'First .. Tname'Last - 1) &
                            ") content : ");
               Write_Eol;

               for J in
                 Response_File_Objects.First .. Response_File_Objects.Last
               loop
                  Write_Str (Response_File_Objects.Table (J).all);
                  Write_Eol;
               end loop;

               Write_Eol;
            end if;
         end if;

         System.OS_Lib.Spawn (Linker_Path.all, Args, Success);

         --  Delete the temporary file used in conjunction with linking if one
         --  was created. See Process_Bind_File for details.

         if Tname_FD /= Invalid_FD then
            Delete (Tname);
         end if;

         if not Success then
            Error_Msg ("error when calling " & Linker_Path.all);
            Exit_Program (E_Fatal);
         end if;
      end Call_Linker;
   end Link_Step;

   --  Only keep the binder output file and it's associated object
   --  file if compiling with the -g option. These files are only
   --  useful if debugging.

   if not Debug_Flag_Present then
      Delete (Binder_Ali_File.all & ASCII.NUL);
      Delete (Binder_Spec_Src_File.all & ASCII.NUL);
      Delete (Binder_Body_Src_File.all & ASCII.NUL);
      Delete (Binder_Obj_File.all & ASCII.NUL);
   end if;

   Exit_Program (E_Success);

exception
   when X : others =>
      Write_Line (Exception_Information (X));
      Exit_With_Error ("INTERNAL ERROR. Please report");
end Gnatlink;
