]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Ada: Link with PIC static Ada runtime when -pie is specified
authorEric Botcazou <ebotcazou@adacore.com>
Fri, 1 May 2026 10:54:38 +0000 (12:54 +0200)
committerEric Botcazou <ebotcazou@adacore.com>
Fri, 1 May 2026 10:59:01 +0000 (12:59 +0200)
This changes gnatlink to append _pic to the name of the static Ada runtime
when -pie is passed on the command line.

gcc/ada/
PR ada/87936
* gnatlink.adb (Gnatlink): Rename local variable and add Output_PIE
local variable; when it is set, compile the binder file with -fPIE.
(Process_Args): Set Output_PIE upon seeing -pie.
(Process_Binder_File): Append "_pic" to the name of the static Ada
runtime if Output_PIE is set.

gcc/testsuite/
* gnat.dg/pie1.adb: New file.

gcc/ada/gnatlink.adb
gcc/testsuite/gnat.dg/pie1.adb [new file with mode: 0644]

index 6a53d550470a86a3e8babdd7ea01133c2f6cd511..85517bf3318dc9e66fc5f4b39491af8267f1055a 100644 (file)
@@ -166,8 +166,6 @@ procedure Gnatlink is
    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
 
@@ -175,6 +173,12 @@ procedure Gnatlink is
    --  Set to True by switch -M. The map file name is derived from
    --  the ALI file name (mainprog.ali => mainprog.map).
 
+   Output_PIE : Boolean := False;
+   --  Set to True if -pie is specified on the command line
+
+   Standard_GCC : Boolean := True;
+   --  Set to False if --GCC is specified on the command line
+
    Object_List_File_Supported : Boolean;
    for Object_List_File_Supported'Size use Character'Size;
    pragma Import
@@ -568,6 +572,13 @@ procedure Gnatlink is
                   Binder_Options.Table (Binder_Options.Last) :=
                     Linker_Options.Table (Linker_Options.Last);
 
+               elsif Arg'Length = 4 and then Arg (2 .. 4) = "pie" then
+                  Output_PIE := True;
+
+                  Linker_Options.Increment_Last;
+                  Linker_Options.Table (Linker_Options.Last) :=
+                    new String'(Arg);
+
                elsif Arg'Length >= 7 and then Arg (1 .. 7) = "--LINK=" then
                   if Arg'Length = 7 then
                      Exit_With_Error ("Missing argument for --LINK=");
@@ -615,7 +626,7 @@ procedure Gnatlink is
                   begin
                      if Program_Args.all (1).all /= Gcc.all then
                         Gcc := new String'(Program_Args.all (1).all);
-                        Standard_Gcc := False;
+                        Standard_GCC := False;
                      end if;
 
                      --  Set appropriate flags for switches passed
@@ -1114,10 +1125,28 @@ procedure Gnatlink is
 
                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")
+               then
+                  if Output_PIE and then GNAT_Static then
+                     Search_Library_Path
+                       (Next_Line   => Next_Line (Nfirst .. Nlast) & "_pic",
+                        Nfirst      => Nfirst,
+                        Nlast       => Nlast + 4,
+                        Last        => Nlast + 4,
+                        GNAT_Static => True,
+                        GNAT_Shared => GNAT_Shared);
+                  else
+                     Search_Library_Path
+                       (Next_Line   => Next_Line,
+                        Nfirst      => Nfirst,
+                        Nlast       => Nlast,
+                        Last        => Nlast,
+                        GNAT_Static => GNAT_Static,
+                        GNAT_Shared => GNAT_Shared);
+                  end if;
+
+               elsif 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)) =
@@ -1518,7 +1547,7 @@ begin
    --  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
+   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;
@@ -1621,8 +1650,6 @@ begin
    --             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");
@@ -1633,6 +1660,8 @@ begin
    Binder_Options_From_ALI.Table (Binder_Options_From_ALI.Last) :=
         new String'("-gnatiw");
 
+   --  In addition, in CodePeer mode compile with -x adascil -gnatcC
+
    if Opt.CodePeer_Mode then
       Binder_Options_From_ALI.Increment_Last;
       Binder_Options_From_ALI.Table (Binder_Options_From_ALI.Last) :=
@@ -1645,6 +1674,14 @@ begin
         new String'("-gnatcC");
    end if;
 
+   --  Moreover, if -pie is specified, make sure that -fPIE is passed
+
+   if Output_PIE then
+      Binder_Options_From_ALI.Increment_Last;
+      Binder_Options_From_ALI.Table (Binder_Options_From_ALI.Last) :=
+        new String'("-fPIE");
+   end if;
+
    --  Locate all the necessary programs and verify required files are present
 
    Gcc_Path := System.OS_Lib.Locate_Exec_On_Path (Gcc.all);
diff --git a/gcc/testsuite/gnat.dg/pie1.adb b/gcc/testsuite/gnat.dg/pie1.adb
new file mode 100644 (file)
index 0000000..5d79206
--- /dev/null
@@ -0,0 +1,9 @@
+-- { dg-do link }
+-- { dg-options "-fPIE -largs -pie" { target pie } }
+
+with Ada.Text_IO; use Ada.Text_IO;
+
+procedure PIE1 is
+begin
+  Put_Line ("Hello PIE World!");
+end;