aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gnatlink.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/gnatlink.adb')
-rw-r--r--gcc/ada/gnatlink.adb137
1 files changed, 66 insertions, 71 deletions
diff --git a/gcc/ada/gnatlink.adb b/gcc/ada/gnatlink.adb
index 09ce5bb0f5d..d6834ab5ae2 100644
--- a/gcc/ada/gnatlink.adb
+++ b/gcc/ada/gnatlink.adb
@@ -178,6 +178,19 @@ procedure Gnatlink is
-- 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
@@ -760,28 +773,12 @@ procedure Gnatlink is
-- Pointer to string specifying the default extension for
-- object libraries, e.g. Unix uses ".a", VMS uses ".olb".
- 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.
-
- Using_GNU_Linker : Boolean;
- for Using_GNU_Linker'Size use Character'Size;
- pragma Import (C, Using_GNU_Linker, "__gnat_using_gnu_linker");
- -- 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
- -- is used.
-
procedure Get_Next_Line;
-- Read the next line from the binder file without the line
-- terminator.
@@ -804,6 +801,10 @@ procedure Gnatlink is
-- 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 --
-------------------
@@ -897,6 +898,46 @@ procedure Gnatlink is
end if;
end Store_File_Context;
+ --------------
+ -- Write_RF --
+ --------------
+
+ procedure Write_RF (S : String) is
+ Success : Boolean := True;
+ 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 I in S'Range loop
+ if S (I) = ' ' or else S (I) = '\' then
+ if Write (Tname_FD, ASCII.BACK_SLASH'Address, 1) /= 1 then
+ Success := False;
+ end if;
+ end if;
+
+ if Write (Tname_FD, S (I)'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
@@ -985,61 +1026,14 @@ procedure Gnatlink is
-- ??? Status of Write and Close operations should be checked, and
-- failure should occur if a status is wrong.
- -- If target is using the GNU linker we must add a special header
- -- and footer in the response file.
-
- -- The syntax is : INPUT (object1.o object2.o ... )
-
- -- Because the GNU linker does not like name with characters such
- -- as '!', we must put the object paths between double quotes.
-
- if Using_GNU_Linker then
- declare
- GNU_Header : aliased constant String := "INPUT (";
-
- begin
- Status := Write (Tname_FD, GNU_Header'Address,
- GNU_Header'Length);
- end;
- end if;
-
for J in Objs_Begin .. Objs_End loop
-
- -- Opening quote for GNU linker
-
- if Using_GNU_Linker then
- Status := Write (Tname_FD, Opening'Address, 1);
- end if;
-
- Status := Write (Tname_FD, Linker_Objects.Table (J).all'Address,
- Linker_Objects.Table (J).all'Length);
-
- -- Closing quote for GNU linker
-
- if Using_GNU_Linker then
- Status := Write (Tname_FD, Closing'Address, 2);
-
- else
- Status := Write (Tname_FD, ASCII.LF'Address, 1);
- end if;
+ 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;
- -- Handle GNU linker response file footer
-
- if Using_GNU_Linker then
- declare
- GNU_Footer : aliased constant String := ")";
-
- begin
- Status := Write (Tname_FD, GNU_Footer'Address,
- GNU_Footer'Length);
- end;
- end if;
-
Close (Tname_FD, Closing_Status);
-- Add the special objects list file option together with the name
@@ -1047,7 +1041,7 @@ procedure Gnatlink is
-- file table.
Linker_Objects.Table (Objs_Begin) :=
- new String'(Value (Object_File_Option_Ptr) &
+ new String'(Object_File_Option &
Tname (Tname'First .. Tname'Last - 1));
-- The slots containing these object file names are then removed
@@ -2213,14 +2207,15 @@ begin
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 Success then
+ -- 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 Tname_FD /= Invalid_FD then
+ Delete (Tname);
+ end if;
- if not Success then
+ else
Error_Msg ("error when calling " & Linker_Path.all);
Exit_Program (E_Fatal);
end if;