OSDN Git Service

2009-08-17 Thomas Quinot <quinot@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / gnatlink.adb
index 9d79b0a..eb255d9 100644 (file)
@@ -6,18 +6,17 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1996-2007, Free Software Foundation, Inc.         --
+--          Copyright (C) 1996-2009, 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 2,  or (at your option) any later ver- --
+-- 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 COPYING.  If not, write --
--- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
--- Boston, MA 02110-1301, USA.                                              --
+-- 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.      --
@@ -105,7 +104,7 @@ procedure Gnatlink is
    --  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 fullname.
+   --  applications objects as they are specified with a full name.
 
    package Response_File_Objects is new Table.Table (
      Table_Component_Type => String_Access,
@@ -138,9 +137,9 @@ procedure Gnatlink is
    --  This table collects the arguments to be passed to compile the binder
    --  generated file.
 
-   Gcc : String_Access := Program_Name ("gcc");
+   Gcc : String_Access := Program_Name ("gcc", "gnatlink");
 
-   Read_Mode  : constant String := "r" & ASCII.Nul;
+   Read_Mode : constant String := "r" & ASCII.NUL;
 
    Begin_Info : String := "--  BEGIN Object file/option list";
    End_Info   : String := "--  END Object file/option list   ";
@@ -148,7 +147,6 @@ procedure Gnatlink is
 
    Gcc_Path             : String_Access;
    Linker_Path          : String_Access;
-
    Output_File_Name     : String_Access;
    Ali_File_Name        : String_Access;
    Binder_Spec_Src_File : String_Access;
@@ -161,6 +159,10 @@ procedure Gnatlink is
    --  Temporary file used by linker to pass list of object files on
    --  certain systems with limitations on size of arguments.
 
+   Lname : String_Access := null;
+   --  File used by linker for CLI target, used to concatenate all .il files
+   --  when the command line passed to ilasm is too long
+
    Debug_Flag_Present : Boolean := False;
    Verbose_Mode       : Boolean := False;
    Very_Verbose_Mode  : Boolean := False;
@@ -168,7 +170,7 @@ procedure Gnatlink is
    Ada_Bind_File : Boolean := True;
    --  Set to True if bind file is generated in Ada
 
-   Standard_Gcc  : Boolean := True;
+   Standard_Gcc : Boolean := True;
 
    Compile_Bind_File : Boolean := True;
    --  Set to False if bind file is not to be compiled
@@ -205,6 +207,9 @@ procedure Gnatlink is
    procedure Process_Binder_File (Name : String);
    --  Reads the binder file and extracts linker arguments
 
+   procedure Usage;
+   --  Display usage
+
    procedure Write_Header;
    --  Show user the program name, version and copyright
 
@@ -290,7 +295,15 @@ procedure Gnatlink is
       --  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", "1995");
+
       --  Loop through arguments of gnatlink command
 
       Next_Arg := 1;
@@ -508,8 +521,10 @@ procedure Gnatlink is
                                                  (Arg (7 .. Arg'Last));
 
                   begin
-                     Gcc := new String'(Program_Args.all (1).all);
-                     Standard_Gcc := False;
+                     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
 
@@ -686,6 +701,7 @@ procedure Gnatlink is
       --  Used for various Interfaces.C_Streams calls
 
       Closing_Status : Boolean;
+      pragma Warnings (Off, Closing_Status);
       --  For call to Close
 
       GNAT_Static : Boolean := False;
@@ -745,6 +761,12 @@ procedure Gnatlink is
       --  Predicate indicating whether this target uses the GNU linker. In
       --  this case we must output a GNU linker compatible response file.
 
+      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
+
       Opening : aliased constant String := """";
       Closing : aliased constant String := '"' & ASCII.LF;
       --  Needed to quote object paths in object list files when GNU linker
@@ -921,14 +943,13 @@ procedure Gnatlink is
 
       Objs_End := Linker_Objects.Last;
 
-      --  Let's continue to compute the Link_Bytes, the linker options are
-      --  part of command line length.
+      --  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;
-         --  See comment above
          Get_Next_Line;
       end loop;
 
@@ -942,7 +963,42 @@ procedure Gnatlink is
       --  to read from a file instead of the command line is only triggered if
       --  a conservative threshold is passed.
 
-      if Object_List_File_Required
+      if VM_Target = CLI_Target
+        and then Link_Bytes > Link_Max
+      then
+         Lname := new String'("l~" & Base_Name (Ali_File_Name.all) & ".il");
+
+         for J in Objs_Begin .. Objs_End loop
+            Copy_File (Linker_Objects.Table (J).all, Lname.all,
+                       Success => Closing_Status,
+                       Mode    => Append);
+         end loop;
+
+         --  Add the special objects list file option together with the name
+         --  of the temporary file to the objects file table.
+
+         Linker_Objects.Table (Objs_Begin) :=
+           new String'(Value (Object_File_Option_Ptr) & Lname.all);
+
+         --  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;
+
+      elsif Object_List_File_Required
         or else (Object_List_File_Supported
                    and then Link_Bytes > Link_Max)
       then
@@ -1205,78 +1261,101 @@ procedure Gnatlink is
                                  --  Look for an eventual run_path_option in
                                  --  the linker switches.
 
-                                 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 a 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
+                                 if Separate_Run_Path_Options then
                                     Linker_Options.Increment_Last;
-                                 end if;
+                                    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
-                                    if Run_Path_Opt_Index = 0 then
+                                    if GCC_Index /= 0 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));
-
-                                    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));
+                                         new String'
+                                           (Run_Path_Opt
+                                            & File_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 a 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.Table
-                                         (Linker_Options.Last) :=
-                                           new String'(Run_Path_Opt
-                                             & File_Path
+                                       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)
-                                             & Path_Separator
-                                             & File_Path (1 .. GCC_Index));
+                                                  - File_Name'Length));
+                                       end if;
 
                                     else
-                                       Linker_Options.Table
-                                         (Run_Path_Opt_Index) :=
-                                           new String'
-                                            (Linker_Options.Table
-                                                (Run_Path_Opt_Index).all
-                                             & Path_Separator
-                                             & File_Path
+                                       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
+                                              & File_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
-                                             & File_Path (1 .. GCC_Index));
+                                                  - File_Name'Length)
+                                               & Path_Separator
+                                               & File_Path (1 .. GCC_Index));
+                                       end if;
                                     end if;
                                  end if;
                               end if;
@@ -1292,7 +1371,7 @@ procedure Gnatlink is
                      else
                         --  If gnatlib library not found, then
                         --  add it anyway in case some other
-                        --  mechanimsm may find it.
+                        --  mechanism may find it.
 
                         Linker_Options.Increment_Last;
                         Linker_Options.Table (Linker_Options.Last) :=
@@ -1329,32 +1408,12 @@ procedure Gnatlink is
       Status := fclose (Fd);
    end Process_Binder_File;
 
-   ------------------
-   -- Write_Header --
-   ------------------
+   -----------
+   -- Usage --
+   -----------
 
-   procedure Write_Header is
+   procedure Usage is
    begin
-      if Verbose_Mode then
-         Write_Eol;
-         Write_Str ("GNATLINK ");
-         Write_Str (Gnat_Version_String);
-         Write_Eol;
-         Write_Str ("Copyright 1995-" &
-                    Current_Year &
-                    ", Free Software Foundation, Inc");
-         Write_Eol;
-      end if;
-   end Write_Header;
-
-   -----------------
-   -- Write_Usage --
-   -----------------
-
-   procedure Write_Usage is
-   begin
-      Write_Header;
-
       Write_Str ("Usage: ");
       Write_Str (Base_Name (Command_Name));
       Write_Str (" switches mainprog.ali [non-Ada-objects] [linker-options]");
@@ -1385,6 +1444,28 @@ procedure Gnatlink is
       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
@@ -1432,25 +1513,11 @@ begin
       Exit_Program (E_Fatal);
    end if;
 
-   --  Get target parameters
+   --  Initialize packages to be used
 
    Namet.Initialize;
    Csets.Initialize;
    Snames.Initialize;
-   Osint.Add_Default_Search_Dirs;
-   Targparm.Get_Target_Parameters;
-
-   if VM_Target /= No_VM then
-      case VM_Target is
-         when JVM_Target => Gcc := new String'("jgnat");
-         when CLI_Target => Gcc := new String'("dotnet-gnatcompile");
-         when No_VM      => raise Program_Error;
-      end case;
-
-      Ada_Bind_File := True;
-      Begin_Info := "--  BEGIN Object file/option list";
-      End_Info   := "--  END Object file/option list   ";
-   end if;
 
    --  We always compile with -c
 
@@ -1458,50 +1525,6 @@ begin
    Binder_Options_From_ALI.Table (Binder_Options_From_ALI.Last) :=
      new String'("-c");
 
-   --  If the main program is in Ada it is compiled with the following
-   --  switches:
-
-   --    -gnatA   stops reading gnat.adc, since we don't know what
-   --             pagmas 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.
-
-   if Ada_Bind_File then
-      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");
-   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
-      if VM_Target = CLI_Target then
-         Linker_Path := System.OS_Lib.Locate_Exec_On_Path ("ilasm");
-
-         if Linker_Path = null then
-            Exit_With_Error ("Couldn't locate ilasm");
-         end if;
-      else
-         Linker_Path := Gcc_Path;
-      end if;
-   end if;
-
    if Ali_File_Name = null then
       Exit_With_Error ("no ali file given for link");
    end if;
@@ -1572,6 +1595,18 @@ begin
                             := String_Access (Arg);
                      end if;
 
+                     --  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);
+
                      --  GNAT doesn't support the GCC multilib mechanism.
                      --  This means that, when a multilib switch is used
                      --  to request a particular compilation mode, the
@@ -1581,20 +1616,18 @@ begin
                      --  convenient to eliminate the redundancy by keying the
                      --  compilation mode on a single switch, namely --RTS.
 
-                     --  Pass -mrtp to the linker if --RTS=rtp was passed.
+                     --  Pass -mrtp to the linker if --RTS=rtp was passed
 
-                     if Linker_Path = Gcc_Path
-                       and then Arg'Length > 8
+                     if Arg'Length > 8
                        and then Arg (Arg'First + 6 .. Arg'First + 8) = "rtp"
                      then
                         Linker_Options.Increment_Last;
                         Linker_Options.Table (Linker_Options.Last) :=
                           new String'("-mrtp");
 
-                     --  Pass -fsjlj to the linker if --RTS=sjlj was passed.
+                     --  Pass -fsjlj to the linker if --RTS=sjlj was passed
 
-                     elsif Linker_Path = Gcc_Path
-                       and then Arg'Length > 9
+                     elsif Arg'Length > 9
                        and then Arg (Arg'First + 6 .. Arg'First + 9) = "sjlj"
                      then
                         Linker_Options.Increment_Last;
@@ -1608,6 +1641,78 @@ begin
       end;
    end if;
 
+   --  Get target parameters
+
+   Osint.Add_Default_Search_Dirs;
+   Targparm.Get_Target_Parameters;
+
+   if VM_Target /= No_VM then
+      case VM_Target is
+         when JVM_Target => Gcc := new String'("jvm-gnatcompile");
+         when CLI_Target => Gcc := new String'("dotnet-gnatcompile");
+         when No_VM      => raise Program_Error;
+      end case;
+
+      Ada_Bind_File := True;
+      Begin_Info := "--  BEGIN Object file/option list";
+      End_Info   := "--  END Object file/option list   ";
+   end if;
+
+   --  If the main program is in Ada it is compiled 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.
+
+   if Ada_Bind_File then
+      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");
+   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
+      if VM_Target = CLI_Target then
+         Linker_Path := System.OS_Lib.Locate_Exec_On_Path ("ilasm");
+
+         if Linker_Path = null then
+            Exit_With_Error ("Couldn't locate ilasm");
+         end if;
+
+      elsif RTX_RTSS_Kernel_Module_On_Target then
+
+         --  Use Microsoft linker for RTSS modules
+
+         Linker_Path := System.OS_Lib.Locate_Exec_On_Path ("link");
+
+         if Linker_Path = null then
+            Exit_With_Error ("Couldn't locate link");
+         end if;
+
+      else
+         Linker_Path := Gcc_Path;
+      end if;
+   end if;
+
    Write_Header;
 
    --  If no output name specified, then use the base name of .ali file name
@@ -1628,6 +1733,11 @@ begin
          Linker_Options.Table (Linker_Options.Last) :=
            new String'("/OUTPUT=" & Output_File_Name.all);
 
+      elsif RTX_RTSS_Kernel_Module_On_Target then
+         Linker_Options.Increment_Last;
+         Linker_Options.Table (Linker_Options.Last) :=
+           new String'("/OUT:" & Output_File_Name.all);
+
       else
          Linker_Options.Increment_Last;
          Linker_Options.Table (Linker_Options.Last) := new String'("-o");
@@ -1756,7 +1866,12 @@ begin
               Binder_Options.Table (J);
          end loop;
 
-         Args (Args'Last) := Binder_Body_Src_File;
+         --  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));
@@ -1812,6 +1927,120 @@ begin
                   Num_Args := Num_Args - 1;
                end if;
             end loop;
+
+         elsif RTX_RTSS_Kernel_Module_On_Target then
+
+            --  Remove flags not relevant for Microsoft linker and adapt some
+            --  others.
+
+            for J in reverse Linker_Options.First .. Linker_Options.Last loop
+
+               --  Remove flags that are not accepted
+               if Linker_Options.Table (J)'Length = 0
+                 or else Linker_Options.Table (J) (1 .. 2) = "-l"
+                 or else Linker_Options.Table (J) (1 .. 3) = "-Wl"
+                 or else Linker_Options.Table (J) (1 .. 3) = "-sh"
+                 or else Linker_Options.Table (J) (1 .. 8) = "-Xlinker"
+                 or else Linker_Options.Table (J) (1 .. 9) = "-mthreads"
+               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;
+
+               --  Replace "-L" by its counterpart "/LIBPATH:" and UNIX "/" by
+               --  Windows "\".
+               elsif Linker_Options.Table (J) (1 .. 2) = "-L" then
+                  declare
+                     Libpath_Option : constant String_Access := new String'
+                       ("/LIBPATH:" &
+                        Linker_Options.Table (J)
+                          (3 .. Linker_Options.Table (J).all'Last));
+                  begin
+                     for Index in 10 .. Libpath_Option'Last loop
+                        if Libpath_Option (Index) = '/' then
+                           Libpath_Option (Index) := '\';
+                        end if;
+                     end loop;
+
+                     Linker_Options.Table (J) := Libpath_Option;
+                  end;
+
+               --  Replace "-g" by "/DEBUG"
+               elsif Linker_Options.Table (J) (1 .. 2) = "-g" then
+                  Linker_Options.Table (J) := new String'("/DEBUG");
+
+               --  Replace "-o" by "/OUT:"
+               elsif Linker_Options.Table (J) (1 .. 2) = "-o" then
+                  Linker_Options.Table (J + 1) := new String'
+                    ("/OUT:" & Linker_Options.Table (J + 1).all);
+
+                  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;
+
+               --  Replace "--stack=" by "/STACK:"
+               elsif Linker_Options.Table (J) (1 .. 8) = "--stack=" then
+                  Linker_Options.Table (J) := new String'
+                    ("/STACK:" &
+                     Linker_Options.Table (J)
+                       (9 .. Linker_Options.Table (J).all'Last));
+
+               --  Replace "-v" by its counterpart "/VERBOSE"
+               elsif Linker_Options.Table (J) (1 .. 2) = "-v" then
+                  Linker_Options.Table (J) := new String'("/VERBOSE");
+               end if;
+            end loop;
+
+            --  Add some required flags to create RTSS modules
+
+            declare
+               Flags_For_Linker : constant array (1 .. 17) of String_Access :=
+                 (new String'("/NODEFAULTLIB"),
+                  new String'("/INCREMENTAL:NO"),
+                  new String'("/NOLOGO"),
+                  new String'("/DRIVER"),
+                  new String'("/ALIGN:0x20"),
+                  new String'("/SUBSYSTEM:NATIVE"),
+                  new String'("/ENTRY:_RtapiProcessEntryCRT@8"),
+                  new String'("/RELEASE"),
+                  new String'("startupCRT.obj"),
+                  new String'("rtxlibcmt.lib"),
+                  new String'("oldnames.lib"),
+                  new String'("rtapi_rtss.lib"),
+                  new String'("Rtx_Rtss.lib"),
+                  new String'("libkernel32.a"),
+                  new String'("libws2_32.a"),
+                  new String'("libmswsock.a"),
+                  new String'("libadvapi32.a"));
+               --  These flags need to be passed to Microsoft linker. They
+               --  come from the RTX documentation.
+
+               Gcc_Lib_Path : constant String_Access := new String'
+                 ("/LIBPATH:" & Include_Dir_Default_Prefix & "\..\");
+               --  Place to look for gcc related libraries, such as libgcc
+
+            begin
+               --  Replace UNIX "/" by Windows "\" in the path
+
+               for Index in 10 .. Gcc_Lib_Path.all'Last loop
+                  if Gcc_Lib_Path (Index) = '/' then
+                     Gcc_Lib_Path (Index) := '\';
+                  end if;
+               end loop;
+
+               Linker_Options.Increment_Last;
+               Linker_Options.Table (Linker_Options.Last) := Gcc_Lib_Path;
+               Num_Args := Num_Args + 1;
+
+               for Index in Flags_For_Linker'Range loop
+                  Linker_Options.Increment_Last;
+                  Linker_Options.Table (Linker_Options.Last) :=
+                    Flags_For_Linker (Index);
+                  Num_Args := Num_Args + 1;
+               end loop;
+            end;
          end if;
 
          --  Remove duplicate stack size setting from the Linker_Options
@@ -1825,7 +2054,7 @@ begin
          --  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.Oparations.
+         --  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
@@ -1921,6 +2150,15 @@ begin
                   Linker_Options.Table (Linker_Options.Last) := Static_Libgcc;
                   Num_Args := Num_Args + 1;
                end if;
+
+            elsif RTX_RTSS_Kernel_Module_On_Target then
+
+               --  Force the use of the static libgcc for RTSS modules
+
+               Linker_Options.Increment_Last;
+               Linker_Options.Table (Linker_Options.Last) :=
+                 new String'("libgcc.a");
+               Num_Args := Num_Args + 1;
             end if;
 
          end Clean_Link_Option_Set;
@@ -1990,13 +2228,17 @@ begin
 
             System.OS_Lib.Spawn (Linker_Path.all, Args, Success);
 
-            --  Delete the temporary file used in conjuction with linking if
+            --  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 Lname /= null then
+               Delete (Lname.all & ASCII.NUL);
+            end if;
+
             if not Success then
                Error_Msg ("error when calling " & Linker_Path.all);
                Exit_Program (E_Fatal);