diff mbox series

[COMMITTED] ada: Fix LTO type mismatches in GNAT.Sockets.Thin

Message ID 20240507080011.37124-1-poulhies@adacore.com
State New
Headers show
Series [COMMITTED] ada: Fix LTO type mismatches in GNAT.Sockets.Thin | expand

Commit Message

Marc Poulhiès May 7, 2024, 8 a.m. UTC
From: Eric Botcazou <ebotcazou@adacore.com>

The default implementation of GNAT.Sockets.Thin is mainly used on Linux and
the socklen_t type used in various routines of the BSD sockets C API is a
typedef for unsigned int there, so importing it as Interface.C.int will be
flagged as a type mismatch during LTO compilation.

gcc/ada/

	* libgnat/g-socthi.ads (C_Bind): Turn into inline function.
	(C_Getpeername): Likewise.
	(C_Getsockname): Likewise.
	(C_Getsockopt): Likewise.
	(C_Setsockopt): Likewise.
	(Nonreentrant_Gethostbyaddr): Likewise.
	* libgnat/g-socthi.adb (Syscall_Accept): Adjust profile.
	(Syscall_Connect): Likewise.
	(Syscall_Recvfrom): Likewise.
	(Syscall_Sendto): Likewise.
	(C_Bind): New function.
	(C_Accept): Adjust to above change for profiles.
	(C_Connect): Likewise.
	(C_Getpeername): New function.
	(C_Getsockname): Likewise.
	(C_Getsockopt): Likewise.
	(C_Recvfrom):  Adjust to above change for profiles.
	(C_Setsockopt): New function.
	(Nonreentrant_Gethostbyaddr): Likewise.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/libgnat/g-socthi.adb | 176 ++++++++++++++++++++++++++++++++---
 gcc/ada/libgnat/g-socthi.ads |  12 +--
 2 files changed, 170 insertions(+), 18 deletions(-)
diff mbox series

Patch

diff --git a/gcc/ada/libgnat/g-socthi.adb b/gcc/ada/libgnat/g-socthi.adb
index dce2717cda3..f8ddcc7fca6 100644
--- a/gcc/ada/libgnat/g-socthi.adb
+++ b/gcc/ada/libgnat/g-socthi.adb
@@ -62,13 +62,13 @@  package body GNAT.Sockets.Thin is
    function Syscall_Accept
      (S       : C.int;
       Addr    : System.Address;
-      Addrlen : not null access C.int) return C.int;
+      Addrlen : not null access C.unsigned) return C.int;
    pragma Import (C, Syscall_Accept, "accept");
 
    function Syscall_Connect
      (S       : C.int;
       Name    : System.Address;
-      Namelen : C.int) return C.int;
+      Namelen : C.unsigned) return C.int;
    pragma Import (C, Syscall_Connect, "connect");
 
    function Syscall_Recv
@@ -84,7 +84,7 @@  package body GNAT.Sockets.Thin is
       Len     : C.size_t;
       Flags   : C.int;
       From    : System.Address;
-      Fromlen : not null access C.int) return System.CRTL.ssize_t;
+      Fromlen : not null access C.unsigned) return System.CRTL.ssize_t;
    pragma Import (C, Syscall_Recvfrom, "recvfrom");
 
    function Syscall_Recvmsg
@@ -105,7 +105,7 @@  package body GNAT.Sockets.Thin is
       Len   : C.size_t;
       Flags : C.int;
       To    : System.Address;
-      Tolen : C.int) return System.CRTL.ssize_t;
+      Tolen : C.unsigned) return System.CRTL.ssize_t;
    pragma Import (C, Syscall_Sendto, "sendto");
 
    function Syscall_Socket
@@ -125,6 +125,25 @@  package body GNAT.Sockets.Thin is
    function Non_Blocking_Socket (S : C.int) return Boolean;
    procedure Set_Non_Blocking_Socket (S : C.int; V : Boolean);
 
+   ------------
+   -- C_Bind --
+   ------------
+
+   function C_Bind
+     (S       : C.int;
+      Name    : System.Address;
+      Namelen : C.int) return C.int
+   is
+      function Bind
+        (S       : C.int;
+         Name    : System.Address;
+         Namelen : C.unsigned) return C.int
+      with Import, Convention => C, External_Name => "bind";
+
+   begin
+      return Bind (S, Name, C.unsigned (Namelen));
+   end C_Bind;
+
    --------------
    -- C_Accept --
    --------------
@@ -134,15 +153,18 @@  package body GNAT.Sockets.Thin is
       Addr    : System.Address;
       Addrlen : not null access C.int) return C.int
    is
-      R   : C.int;
-      Val : aliased C.int := 1;
+      R         : C.int;
+      U_Addrlen : aliased C.unsigned;
+      Val       : aliased C.int := 1;
 
       Discard : C.int;
       pragma Warnings (Off, Discard);
 
    begin
+      U_Addrlen := C.unsigned (Addrlen.all);
+
       loop
-         R := Syscall_Accept (S, Addr, Addrlen);
+         R := Syscall_Accept (S, Addr, U_Addrlen'Unchecked_Access);
          exit when SOSC.Thread_Blocking_IO
            or else R /= Failure
            or else Non_Blocking_Socket (S)
@@ -150,6 +172,8 @@  package body GNAT.Sockets.Thin is
          delay Quantum;
       end loop;
 
+      Addrlen.all := C.int (U_Addrlen);
+
       if not SOSC.Thread_Blocking_IO
         and then R /= Failure
       then
@@ -177,7 +201,7 @@  package body GNAT.Sockets.Thin is
       Res : C.int;
 
    begin
-      Res := Syscall_Connect (S, Name, Namelen);
+      Res := Syscall_Connect (S, Name, C.unsigned (Namelen));
 
       if SOSC.Thread_Blocking_IO
         or else Res /= Failure
@@ -215,7 +239,7 @@  package body GNAT.Sockets.Thin is
          end loop;
       end;
 
-      Res := Syscall_Connect (S, Name, Namelen);
+      Res := Syscall_Connect (S, Name, C.unsigned (Namelen));
 
       if Res = Failure
         and then Errno = SOSC.EISCONN
@@ -226,6 +250,85 @@  package body GNAT.Sockets.Thin is
       end if;
    end C_Connect;
 
+   -------------------
+   -- C_Getpeername --
+   -------------------
+
+   function C_Getpeername
+     (S       : C.int;
+      Name    : System.Address;
+      Namelen : not null access C.int) return C.int
+   is
+      function Getpeername
+        (S       : C.int;
+         Name    : System.Address;
+         Namelen : not null access C.unsigned) return C.int
+      with Import, Convention => C, External_Name => "getpeername";
+
+      U_Namelen : aliased C.unsigned;
+      Val       : C.int;
+
+   begin
+      U_Namelen := C.unsigned (Namelen.all);
+      Val := Getpeername (S, Name, U_Namelen'Unchecked_Access);
+      Namelen.all := C.int (U_Namelen);
+      return Val;
+   end C_Getpeername;
+
+   -------------------
+   -- C_Getsockname --
+   -------------------
+
+   function C_Getsockname
+     (S       : C.int;
+      Name    : System.Address;
+      Namelen : not null access C.int) return C.int
+   is
+      function Getsockname
+        (S       : C.int;
+         Name    : System.Address;
+         Namelen : not null access C.unsigned) return C.int
+      with Import, Convention => C, External_Name => "getsockname";
+
+      U_Namelen : aliased C.unsigned;
+      Val       : C.int;
+
+   begin
+      U_Namelen := C.unsigned (Namelen.all);
+      Val := Getsockname (S, Name, U_Namelen'Unchecked_Access);
+      Namelen.all := C.int (U_Namelen);
+      return Val;
+   end C_Getsockname;
+
+   -------------------
+   --  C_Getsockopt --
+   -------------------
+
+   function C_Getsockopt
+     (S       : C.int;
+      Level   : C.int;
+      Optname : C.int;
+      Optval  : System.Address;
+      Optlen  : not null access C.int) return C.int
+   is
+      function Getsockopt
+        (S       : C.int;
+         Level   : C.int;
+         Optname : C.int;
+         Optval  : System.Address;
+         Optlen  : not null access C.unsigned) return C.int
+      with Import, Convention => C, External_Name => "getsockopt";
+
+      U_Optlen : aliased C.unsigned;
+      Val      : C.int;
+
+   begin
+      U_Optlen := C.unsigned (Optlen.all);
+      Val := Getsockopt (S, Level, Optname, Optval, U_Optlen'Unchecked_Access);
+      Optlen.all := C.int (U_Optlen);
+      return Val;
+   end C_Getsockopt;
+
    ------------------
    -- Socket_Ioctl --
    ------------------
@@ -282,11 +385,15 @@  package body GNAT.Sockets.Thin is
       From    : System.Address;
       Fromlen : not null access C.int) return C.int
    is
-      Res : C.int;
+      Res       : C.int;
+      U_Fromlen : aliased C.unsigned;
 
    begin
+      U_Fromlen := C.unsigned (Fromlen.all);
+
       loop
-         Res := C.int (Syscall_Recvfrom (S, Msg, Len, Flags, From, Fromlen));
+         Res := C.int (Syscall_Recvfrom (S, Msg, Len, Flags, From,
+                                                  U_Fromlen'Unchecked_Access));
          exit when SOSC.Thread_Blocking_IO
            or else Res /= Failure
            or else Non_Blocking_Socket (S)
@@ -294,6 +401,8 @@  package body GNAT.Sockets.Thin is
          delay Quantum;
       end loop;
 
+      Fromlen.all := C.int (U_Fromlen);
+
       return Res;
    end C_Recvfrom;
 
@@ -361,7 +470,8 @@  package body GNAT.Sockets.Thin is
 
    begin
       loop
-         Res := C.int (Syscall_Sendto (S, Msg, Len, Flags, To, Tolen));
+         Res := C.int (Syscall_Sendto (S, Msg, Len, Flags, To,
+                                                          C.unsigned (Tolen)));
          exit when SOSC.Thread_Blocking_IO
            or else Res /= Failure
            or else Non_Blocking_Socket (S)
@@ -372,6 +482,29 @@  package body GNAT.Sockets.Thin is
       return Res;
    end C_Sendto;
 
+   ------------------
+   -- C_Setsockopt --
+   ------------------
+
+   function C_Setsockopt
+     (S       : C.int;
+      Level   : C.int;
+      Optname : C.int;
+      Optval  : System.Address;
+      Optlen  : C.int) return C.int
+   is
+      function Setsockopt
+        (S       : C.int;
+         Level   : C.int;
+         Optname : C.int;
+         Optval  : System.Address;
+         Optlen  : C.unsigned) return C.int
+      with Import, Convention => C, External_Name => "setsockopt";
+
+   begin
+      return Setsockopt  (S, Level, Optname, Optval, C.unsigned (Optlen));
+   end C_Setsockopt;
+
    --------------
    -- C_Socket --
    --------------
@@ -457,6 +590,25 @@  package body GNAT.Sockets.Thin is
       Task_Lock.Unlock;
    end Set_Non_Blocking_Socket;
 
+   --------------------------------
+   -- Nonreentrant_Gethostbyaddr --
+   --------------------------------
+
+   function Nonreentrant_Gethostbyaddr
+     (Addr      : System.Address;
+      Addr_Len  : C.int;
+      Addr_Type : C.int) return Hostent_Access
+   is
+      function Gethostbyaddr
+        (Addr      : System.Address;
+         Addr_Len  : C.unsigned;
+         Addr_Type : C.int) return Hostent_Access
+      with Import, Convention => C, External_Name => "gethostbyaddr";
+
+   begin
+      return Gethostbyaddr (Addr, C.unsigned (Addr_Len), Addr_Type);
+   end Nonreentrant_Gethostbyaddr;
+
    --------------------
    -- Signalling_Fds --
    --------------------
diff --git a/gcc/ada/libgnat/g-socthi.ads b/gcc/ada/libgnat/g-socthi.ads
index ef53e0414b0..b759c7e1eb1 100644
--- a/gcc/ada/libgnat/g-socthi.ads
+++ b/gcc/ada/libgnat/g-socthi.ads
@@ -249,21 +249,21 @@  package GNAT.Sockets.Thin is
    procedure Finalize;
 
 private
-   pragma Import (C, C_Bind, "bind");
+   pragma Inline (C_Bind);
    pragma Import (C, C_Close, "close");
    pragma Import (C, C_Gethostname, "gethostname");
-   pragma Import (C, C_Getpeername, "getpeername");
-   pragma Import (C, C_Getsockname, "getsockname");
-   pragma Import (C, C_Getsockopt, "getsockopt");
+   pragma Inline (C_Getpeername);
+   pragma Inline (C_Getsockname);
+   pragma Inline (C_Getsockopt);
    pragma Import (C, C_Listen, "listen");
    pragma Import (C, C_Select, "select");
-   pragma Import (C, C_Setsockopt, "setsockopt");
+   pragma Inline (C_Setsockopt);
    pragma Import (C, C_Shutdown, "shutdown");
    pragma Import (C, C_Socketpair, "socketpair");
    pragma Import (C, C_System, "system");
 
    pragma Import (C, Nonreentrant_Gethostbyname, "gethostbyname");
-   pragma Import (C, Nonreentrant_Gethostbyaddr, "gethostbyaddr");
+   pragma Inline (Nonreentrant_Gethostbyaddr);
    pragma Import (C, Nonreentrant_Getservbyname, "getservbyname");
    pragma Import (C, Nonreentrant_Getservbyport, "getservbyport");