summaryrefslogtreecommitdiff
path: root/gcc/ada/s-mmap.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/s-mmap.adb')
-rw-r--r--gcc/ada/s-mmap.adb576
1 files changed, 0 insertions, 576 deletions
diff --git a/gcc/ada/s-mmap.adb b/gcc/ada/s-mmap.adb
deleted file mode 100644
index aee0ebeaad0..00000000000
--- a/gcc/ada/s-mmap.adb
+++ /dev/null
@@ -1,576 +0,0 @@
-------------------------------------------------------------------------------
--- --
--- GNAT RUN-TIME COMPONENTS --
--- --
--- S Y S T E M . M M A P --
--- --
--- B o d y --
--- --
--- Copyright (C) 2007-2016, AdaCore --
--- --
--- This library is free software; you can redistribute it and/or modify it --
--- under terms of the GNU General Public License as published by the Free --
--- Software Foundation; either version 3, or (at your option) any later --
--- version. This library is distributed in the hope that it will be useful, --
--- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- --
--- TABILITY or FITNESS FOR A PARTICULAR PURPOSE. --
--- --
--- As a special exception under Section 7 of GPL version 3, you are granted --
--- additional permissions described in the GCC Runtime Library Exception, --
--- version 3.1, as published by the Free Software Foundation. --
--- --
--- You should have received a copy of the GNU General Public License and --
--- a copy of the GCC Runtime Library Exception along with this program; --
--- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
--- <http://www.gnu.org/licenses/>. --
--- --
--- GNAT was originally developed by the GNAT team at New York University. --
--- Extensive contributions were provided by Ada Core Technologies Inc. --
--- --
-------------------------------------------------------------------------------
-
-with Ada.IO_Exceptions;
-with Ada.Unchecked_Conversion;
-with Ada.Unchecked_Deallocation;
-
-with System.Strings; use System.Strings;
-
-with System.Mmap.OS_Interface; use System.Mmap.OS_Interface;
-
-package body System.Mmap is
-
- type Mapped_File_Record is record
- Current_Region : Mapped_Region;
- -- The legacy API enables only one region to be mapped, directly
- -- associated with the mapped file. This references this region.
-
- File : System_File;
- -- Underlying OS-level file
- end record;
-
- type Mapped_Region_Record is record
- File : Mapped_File;
- -- The file this region comes from. Be careful: for reading file, it is
- -- valid to have it closed before one of its regions is free'd.
-
- Write : Boolean;
- -- Whether the file this region comes from is open for writing.
-
- Data : Str_Access;
- -- Unbounded access to the mapped content.
-
- System_Offset : File_Size;
- -- Position in the file of the first byte actually mapped in memory
-
- User_Offset : File_Size;
- -- Position in the file of the first byte requested by the user
-
- System_Size : File_Size;
- -- Size of the region actually mapped in memory
-
- User_Size : File_Size;
- -- Size of the region requested by the user
-
- Mapped : Boolean;
- -- Whether this region is actually memory mapped
-
- Mutable : Boolean;
- -- If the file is opened for reading, wheter this region is writable
-
- Buffer : System.Strings.String_Access;
- -- When this region is not actually memory mapped, contains the
- -- requested bytes.
-
- Mapping : System_Mapping;
- -- Underlying OS-level data for the mapping, if any
- end record;
-
- Invalid_Mapped_Region_Record : constant Mapped_Region_Record :=
- (null, False, null, 0, 0, 0, 0, False, False, null,
- Invalid_System_Mapping);
- Invalid_Mapped_File_Record : constant Mapped_File_Record :=
- (Invalid_Mapped_Region, Invalid_System_File);
-
- Empty_String : constant String := "";
- -- Used to provide a valid empty Data for empty files, for instanc.
-
- procedure Dispose is new Ada.Unchecked_Deallocation
- (Mapped_File_Record, Mapped_File);
- procedure Dispose is new Ada.Unchecked_Deallocation
- (Mapped_Region_Record, Mapped_Region);
-
- function Convert is new Ada.Unchecked_Conversion
- (Standard.System.Address, Str_Access);
-
- procedure Compute_Data (Region : Mapped_Region);
- -- Fill the Data field according to system and user offsets. The region
- -- must actually be mapped or bufferized.
-
- procedure From_Disk (Region : Mapped_Region);
- -- Read a region of some file from the disk
-
- procedure To_Disk (Region : Mapped_Region);
- -- Write the region of the file back to disk if necessary, and free memory
-
- ----------------------------
- -- Open_Read_No_Exception --
- ----------------------------
-
- function Open_Read_No_Exception
- (Filename : String;
- Use_Mmap_If_Available : Boolean := True) return Mapped_File
- is
- File : constant System_File :=
- Open_Read (Filename, Use_Mmap_If_Available);
- begin
- if File = Invalid_System_File then
- return Invalid_Mapped_File;
- end if;
-
- return new Mapped_File_Record'
- (Current_Region => Invalid_Mapped_Region,
- File => File);
- end Open_Read_No_Exception;
-
- ---------------
- -- Open_Read --
- ---------------
-
- function Open_Read
- (Filename : String;
- Use_Mmap_If_Available : Boolean := True) return Mapped_File
- is
- Res : constant Mapped_File :=
- Open_Read_No_Exception (Filename, Use_Mmap_If_Available);
- begin
- if Res = Invalid_Mapped_File then
- raise Ada.IO_Exceptions.Name_Error
- with "Cannot open " & Filename;
- else
- return Res;
- end if;
- end Open_Read;
-
- ----------------
- -- Open_Write --
- ----------------
-
- function Open_Write
- (Filename : String;
- Use_Mmap_If_Available : Boolean := True) return Mapped_File
- is
- File : constant System_File :=
- Open_Write (Filename, Use_Mmap_If_Available);
- begin
- if File = Invalid_System_File then
- raise Ada.IO_Exceptions.Name_Error
- with "Cannot open " & Filename;
- else
- return new Mapped_File_Record'
- (Current_Region => Invalid_Mapped_Region,
- File => File);
- end if;
- end Open_Write;
-
- -----------
- -- Close --
- -----------
-
- procedure Close (File : in out Mapped_File) is
- begin
- -- Closing a closed file is allowed and should do nothing
-
- if File = Invalid_Mapped_File then
- return;
- end if;
-
- if File.Current_Region /= null then
- Free (File.Current_Region);
- end if;
-
- if File.File /= Invalid_System_File then
- Close (File.File);
- end if;
-
- Dispose (File);
- end Close;
-
- ----------
- -- Free --
- ----------
-
- procedure Free (Region : in out Mapped_Region) is
- Ignored : Integer;
- pragma Unreferenced (Ignored);
- begin
- -- Freeing an already free'd file is allowed and should do nothing
-
- if Region = Invalid_Mapped_Region then
- return;
- end if;
-
- if Region.Mapping /= Invalid_System_Mapping then
- Dispose_Mapping (Region.Mapping);
- end if;
- To_Disk (Region);
- Dispose (Region);
- end Free;
-
- ----------
- -- Read --
- ----------
-
- procedure Read
- (File : Mapped_File;
- Region : in out Mapped_Region;
- Offset : File_Size := 0;
- Length : File_Size := 0;
- Mutable : Boolean := False)
- is
- File_Length : constant File_Size := Mmap.Length (File);
-
- Req_Offset : constant File_Size := Offset;
- Req_Length : File_Size := Length;
- -- Offset and Length of the region to map, used to adjust mapping
- -- bounds, reflecting what the user will see.
-
- Region_Allocated : Boolean := False;
- begin
- -- If this region comes from another file, or simply if the file is
- -- writeable, we cannot re-use this mapping: free it first.
-
- if Region /= Invalid_Mapped_Region
- and then
- (Region.File /= File or else File.File.Write)
- then
- Free (Region);
- end if;
-
- if Region = Invalid_Mapped_Region then
- Region := new Mapped_Region_Record'(Invalid_Mapped_Region_Record);
- Region_Allocated := True;
- end if;
-
- Region.File := File;
-
- if Req_Offset >= File_Length then
- -- If the requested offset goes beyond file size, map nothing
-
- Req_Length := 0;
-
- elsif Length = 0
- or else
- Length > File_Length - Req_Offset
- then
- -- If Length is 0 or goes beyond file size, map till end of file
-
- Req_Length := File_Length - Req_Offset;
-
- else
- Req_Length := Length;
- end if;
-
- -- Past this point, the offset/length the user will see is fixed. On the
- -- other hand, the system offset/length is either already defined, from
- -- a previous mapping, or it is set to 0. In the latter case, the next
- -- step will set them according to the mapping.
-
- Region.User_Offset := Req_Offset;
- Region.User_Size := Req_Length;
-
- -- If the requested region is inside an already mapped region, adjust
- -- user-requested data and do nothing else.
-
- if (File.File.Write or else Region.Mutable = Mutable)
- and then
- Req_Offset >= Region.System_Offset
- and then
- (Req_Offset + Req_Length
- <= Region.System_Offset + Region.System_Size)
- then
- Region.User_Offset := Req_Offset;
- Compute_Data (Region);
- return;
-
- elsif Region.Buffer /= null then
- -- Otherwise, as we are not going to re-use the buffer, free it
-
- System.Strings.Free (Region.Buffer);
- Region.Buffer := null;
-
- elsif Region.Mapping /= Invalid_System_Mapping then
- -- Otherwise, there is a memory mapping that we need to unmap.
- Dispose_Mapping (Region.Mapping);
- end if;
-
- -- mmap() will sometimes return NULL when the file exists but is empty,
- -- which is not what we want, so in the case of a zero length file we
- -- fall back to read(2)/write(2)-based mode.
-
- if File_Length > 0 and then File.File.Mapped then
-
- Region.System_Offset := Req_Offset;
- Region.System_Size := Req_Length;
- Create_Mapping
- (File.File,
- Region.System_Offset, Region.System_Size,
- Mutable,
- Region.Mapping);
- Region.Mapped := True;
- Region.Mutable := Mutable;
-
- else
- -- There is no alignment requirement when manually reading the file.
-
- Region.System_Offset := Req_Offset;
- Region.System_Size := Req_Length;
- Region.Mapped := False;
- Region.Mutable := True;
- From_Disk (Region);
- end if;
-
- Region.Write := File.File.Write;
- Compute_Data (Region);
-
- exception
- when others =>
- -- Before propagating any exception, free any region we allocated
- -- here.
-
- if Region_Allocated then
- Dispose (Region);
- end if;
- raise;
- end Read;
-
- ----------
- -- Read --
- ----------
-
- procedure Read
- (File : Mapped_File;
- Offset : File_Size := 0;
- Length : File_Size := 0;
- Mutable : Boolean := False)
- is
- begin
- Read (File, File.Current_Region, Offset, Length, Mutable);
- end Read;
-
- ----------
- -- Read --
- ----------
-
- function Read
- (File : Mapped_File;
- Offset : File_Size := 0;
- Length : File_Size := 0;
- Mutable : Boolean := False) return Mapped_Region
- is
- Region : Mapped_Region := Invalid_Mapped_Region;
- begin
- Read (File, Region, Offset, Length, Mutable);
- return Region;
- end Read;
-
- ------------
- -- Length --
- ------------
-
- function Length (File : Mapped_File) return File_Size is
- begin
- return File.File.Length;
- end Length;
-
- ------------
- -- Offset --
- ------------
-
- function Offset (Region : Mapped_Region) return File_Size is
- begin
- return Region.User_Offset;
- end Offset;
-
- ------------
- -- Offset --
- ------------
-
- function Offset (File : Mapped_File) return File_Size is
- begin
- return Offset (File.Current_Region);
- end Offset;
-
- ----------
- -- Last --
- ----------
-
- function Last (Region : Mapped_Region) return Integer is
- begin
- return Integer (Region.User_Size);
- end Last;
-
- ----------
- -- Last --
- ----------
-
- function Last (File : Mapped_File) return Integer is
- begin
- return Last (File.Current_Region);
- end Last;
-
- -------------------
- -- To_Str_Access --
- -------------------
-
- function To_Str_Access
- (Str : System.Strings.String_Access) return Str_Access is
- begin
- if Str = null then
- return null;
- else
- return Convert (Str.all'Address);
- end if;
- end To_Str_Access;
-
- ----------
- -- Data --
- ----------
-
- function Data (Region : Mapped_Region) return Str_Access is
- begin
- return Region.Data;
- end Data;
-
- ----------
- -- Data --
- ----------
-
- function Data (File : Mapped_File) return Str_Access is
- begin
- return Data (File.Current_Region);
- end Data;
-
- ----------------
- -- Is_Mutable --
- ----------------
-
- function Is_Mutable (Region : Mapped_Region) return Boolean is
- begin
- return Region.Mutable or Region.Write;
- end Is_Mutable;
-
- ----------------
- -- Is_Mmapped --
- ----------------
-
- function Is_Mmapped (File : Mapped_File) return Boolean is
- begin
- return File.File.Mapped;
- end Is_Mmapped;
-
- -------------------
- -- Get_Page_Size --
- -------------------
-
- function Get_Page_Size return Integer is
- Result : constant File_Size := Get_Page_Size;
- begin
- return Integer (Result);
- end Get_Page_Size;
-
- ---------------------
- -- Read_Whole_File --
- ---------------------
-
- function Read_Whole_File
- (Filename : String;
- Empty_If_Not_Found : Boolean := False)
- return System.Strings.String_Access
- is
- File : Mapped_File := Open_Read (Filename);
- Region : Mapped_Region renames File.Current_Region;
- Result : String_Access;
- begin
- Read (File);
-
- if Region.Data /= null then
- Result := new String'(String
- (Region.Data (1 .. Last (Region))));
-
- elsif Region.Buffer /= null then
- Result := Region.Buffer;
- Region.Buffer := null; -- So that it is not deallocated
- end if;
-
- Close (File);
-
- return Result;
-
- exception
- when Ada.IO_Exceptions.Name_Error =>
- if Empty_If_Not_Found then
- return new String'("");
- else
- return null;
- end if;
-
- when others =>
- Close (File);
- return null;
- end Read_Whole_File;
-
- ---------------
- -- From_Disk --
- ---------------
-
- procedure From_Disk (Region : Mapped_Region) is
- begin
- pragma Assert (Region.File.all /= Invalid_Mapped_File_Record);
- pragma Assert (Region.Buffer = null);
-
- Region.Buffer := Read_From_Disk
- (Region.File.File, Region.User_Offset, Region.User_Size);
- Region.Mapped := False;
- end From_Disk;
-
- -------------
- -- To_Disk --
- -------------
-
- procedure To_Disk (Region : Mapped_Region) is
- begin
- if Region.Write and then Region.Buffer /= null then
- pragma Assert (Region.File.all /= Invalid_Mapped_File_Record);
- Write_To_Disk
- (Region.File.File,
- Region.User_Offset, Region.User_Size,
- Region.Buffer);
- end if;
-
- System.Strings.Free (Region.Buffer);
- Region.Buffer := null;
- end To_Disk;
-
- ------------------
- -- Compute_Data --
- ------------------
-
- procedure Compute_Data (Region : Mapped_Region) is
- Base_Data : Str_Access;
- -- Address of the first byte actually mapped in memory
-
- Data_Shift : constant Integer :=
- Integer (Region.User_Offset - Region.System_Offset);
- begin
- if Region.User_Size = 0 then
- Region.Data := Convert (Empty_String'Address);
- return;
- elsif Region.Mapped then
- Base_Data := Convert (Region.Mapping.Address);
- else
- Base_Data := Convert (Region.Buffer.all'Address);
- end if;
- Region.Data := Convert (Base_Data (Data_Shift + 1)'Address);
- end Compute_Data;
-
-end System.Mmap;