Bug#1067453: gnat: Ada.Calendar.Clock crashes on time_t64 architectures

2024-04-25 Thread Nicolas Boulenguez
Source: gcc-13
Followup-For: Bug #1067453

The gettimeofday import issue seems specific to the time_t 64
transition in Debian.

When building C on armhf, a #define replaces gettimeofday with
__gettimeofday64 so the linker finds the 64 bits version in the libc.

When linking Ada code, the linker searches for the gettimeofday symbol
and links with the 32 bits version, as demonstrated by the reproducer
script below.  Here is the output.

./c_part
 timeval size: 128
 tv_sec   offset: 0   size: 64   value: 662A7756
 tv_usec   offset: 8   size: 64   value: 1C54
 56 77 2A 66 00 00 00 00 54 1C 00 00 00 00 00 00
./ada_part
 timeval size: 128
  tv_sec offset: 0   size: 64   value:16#27A9662A7756#
  tv_usec offset: 8   size: 64 value:-16#80B1C0708345E00#
 56 77 2A 66 A9 27 00 00 00 A2 CB F7 F8 E3 F4 F7

Changing the External_Name from "gettimeofday" to "__gettimeofday64"
fixes the mismatch (except for the lower microseconds of course).

./c_part
 81 76 2A 66 00 00 00 00 0F E2 0C 00 00 00 00 00
./ada_part
 81 76 2A 66 00 00 00 00 CB EC 0C 00 00 00 00 00

So we have two possible work-arounds.

 * build a C source with a __gnat_gettimeofday wrapper.
   This option, implemented by my last commit, patches
 gcc/ada/Makefile.rtl
 gcc/ada/cal.c
 gcc/ada/gcc-interface/Makefile.in
 gcc/ada/libgnat-s-osprim__posix.adb
   and interfers with the previous commit.

 * simply patch gcc/ada/libgnat/s-osprim__posix.adb with
-  pragma Import (C, gettimeofday, "gettimeofday");
+  pragma Import (C, gettimeofday, "__gettimeofday64");
  This seems better, but must only be applied on targets affected by
  the t64 transition.

I do not know which one is the best, but at least the second one
explains why the first one did work.

Just in case, here is the reproducer script:

--
#!/bin/sh
set -efuv

cat > hexdump.h < hexdump.c <
#include "hexdump.h"
void hexdump(char* p, int length)
{
  while (length--)
  {
printf(" %02hhX", *p++);
  }
  printf("\n");
}
EOF

cat > c_part.c <
#include 
#include 
#include 
#include "hexdump.h"
int main(int argc, const char* argv[]) {
  struct timeval tv;
  if (argc == 1)
  {
printf(" gettimeofday returned %i\n", gettimeofday(, NULL));
printf(" timeval size: %lli\n", (long long int)( CHAR_BIT * sizeof(tv)));
printf(" tv_sec");
printf("   offset: %lli", (long long int)((char*)(&(tv.tv_sec)) - 
(char*)()));
printf("   size: %lli",   (long long int)(CHAR_BIT * sizeof(tv.tv_sec)));
printf("   value: %llX",  (long long int)tv.tv_sec);
printf("\n");
printf(" tv_usec");
printf("   offset: %lli", (long long int)((char*)(&(tv.tv_usec)) - 
(char*)()));
printf("   size: %lli",   (long long int)(CHAR_BIT * sizeof(tv.tv_usec)));
printf("   value: %llX",  (long long int)tv.tv_usec);
printf("\n");
hexdump((char*)(), sizeof(tv));
  }
  else
  {
printf("   time_t_bits  : constant := %lli;\n",
   (long long int)(CHAR_BIT * sizeof(tv.tv_sec)));
printf("   suseconds_t_bits : constant := %lli;\n",
   (long long int)( CHAR_BIT * sizeof(tv.tv_usec)));
  }
  return EXIT_SUCCESS;
}
EOF

cat > ada_part.adb < C;
   type suseconds_t is range -2**(suseconds_t_bits - 1) ..
  2**(suseconds_t_bits - 1) - 1
 with Convention => C;
   type timeval is record
  tv_sec  : time_t;
  tv_usec : suseconds_t;
   end record with Convention => C;
   function gettimeofday (tv : access timeval; tz : Address) return int
 with Import, Convention => C,
  External_Name => "gettimeofday"; --  Here
   Tv : aliased timeval;
   function Offset (A, B : Address) return String is
 (Long_Long_Integer'Image (Long_Long_Integer'Value (A'Img)
 - Long_Long_Integer'Value (B'Img)));
   I : constant int := gettimeofday(Tv'Access, Null_Address);
   procedure hexdump(p : Address; count : Integer)
 with Import, Convention => C, External_Name => "hexdump";
begin
  Put_Line (" gettimeofday returned" & I'Img);
  Put_Line (" timeval size:" & Integer'Image (Tv'Size));
  Put ("  tv_sec offset:" & Offset (Tv.tv_sec'Address, Tv'Address)
   & "   size:" & Integer'Image (Tv.tv_sec'Size)
   & "   value:");
  Put (Long_Long_Integer (Tv.tv_sec), Width => 0, Base => 16);
  New_Line;
  Put ("  tv_usec offset:" & Offset (Tv.tv_usec'Address, Tv'Address)
   & "   size:" & Integer'Image (Tv.tv_usec'Size)
   & " value:");
  Put (Long_Long_Integer (Tv.tv_usec), Width => 0, Base => 16);
  New_Line;
  hexdump (Tv'Address, Tv'Size / 8);
end Ada_Part;
EOF

gcc -c -Wall -Wextra hexdump.c -o hexdump.o
gcc -Wall -Wextra c_part.c hexdump.o -o c_part
gnatmake -gnat2022 -gnatwa -gnatya ada_part.adb -largs hexdump.o

./c_part
./ada_part



Bug#1067453: gnat: Ada.Calendar.Clock crashes on time_t64 architectures

2024-04-06 Thread Nicolas Boulenguez
Source: gcc-13
Followup-For: Bug #1067453

Sorry for the poor summary. Here is what I have built and tested.
 * native build on ppc46el (not amd64)
 * gcc-source 13.2.0-19 from Debian
 * libgnat-timet64.diff unapplied
   (pr114065-proposed.diff should be unapplied for -20 and later)
 * commits 1/8 to 8/8 from bug114065attempt3.tar.gz applied
   (Debian only needs 1-3, 4-8 should only affect style).
 * ada-lib-info-source-date-epoch.diff adapted as described in #1067453
   (disabling it for a while is also an option)
 * debian/rules binary-arch

cat > demo.adb <

Bug#1067453: gnat: Ada.Calendar.Clock crashes on time_t64 architectures

2024-04-06 Thread Matthias Klose

Nicolas,

which package version are you working with?

On 05.04.24 18:45, Nicolas Boulenguez wrote:

Source: gcc-13
Followup-For: Bug #1067453

Hello.

In case anyone tries to build attempt3 at
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114065
in Debian, please:
  * disable debian/patches/libgnat-time64.diff in debian/rules.patch


this has been replaced in -23 with
https://salsa.debian.org/toolchain-team/gcc/-/blob/gcc-13-debian/debian/patches/pr114065-proposed.diff

what Eric Botcazou suggested to do.


  * adapt the current ada-lib-info-source-date-epoch.diff


without the first patch in pr114065, that will ftbfs on armhf.

or are you suggesting any further patches?

thanks, Matthias



Bug#1067453: gnat: Ada.Calendar.Clock crashes on time_t64 architectures

2024-04-05 Thread Nicolas Boulenguez
Source: gcc-13
Followup-For: Bug #1067453

Hello.

In case anyone tries to build attempt3 at
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114065
in Debian, please:
 * disable debian/patches/libgnat-time64.diff in debian/rules.patch
 * adapt the current ada-lib-info-source-date-epoch.diff

--- a/debian/patches/ada-lib-info-source-date-epoch.diff
+++ b/debian/patches/ada-lib-info-source-date-epoch.diff
@@ -62,24 +62,26 @@ Author: Nicolas Boulenguez 
 end File_Stamp;
  
 function File_Stamp (Name : Path_Name_Type) return Time_Stamp_Type is
-@@ -3261,4 +3276,28 @@ begin
+@@ -3261,4 +3276,30 @@ begin
Osint.Initialize;
 end Initialization;
  
 +   Set_Source_Date_Epoch : declare
++  --  See comments in OS_Time_To_GNAT_Time.
++  use type CRTL.int64;
++  function To_Ada is new Ada.Unchecked_Conversion (CRTL.int64, OS_Time);
 +  Env_Var : String_Access := Getenv ("SOURCE_DATE_EPOCH");
-+  Epoch   : time_t range 0 .. time_t'Last := 0;
-+  Digit   : time_t range 0 .. 9;
++  Epoch   : CRTL.int64 range 0 .. CRTL.int64'Last := 0;
++  Digit   : CRTL.int64 range 0 .. 9;
 +   begin
 +  if 0 < Env_Var.all'Length then
 + --  Calling System.Val_LLI breaks the bootstrap sequence.
-+ --  First convert to time_t because OS_Time is private.
 + for C of Env_Var.all loop
 +if C not in '0' .. '9' then
 +   goto Finally;
 +end if;
-+Digit := time_t (Character'Pos (C) - Character'Pos ('0'));
-+if (time_t'Last - Digit) / 10 < Epoch then
++Digit := CRTL.int64 (Character'Pos (C) - Character'Pos ('0'));
++if (CRTL.int64'Last - Digit) / 10 < Epoch then
 +   goto Finally;
 +end if;
 +Epoch := Epoch * 10 + Digit;



Bug#1067453: gnat: Ada.Calendar.Clock crashes on time_t64 architectures

2024-03-21 Thread Matthias Klose

Control: forwarded -1 https://gcc.gnu.org/PR114424



Bug#1067453: gnat: Ada.Calendar.Clock crashes on time_t64 architectures

2024-03-21 Thread Nicolas Boulenguez
Package: gnat-13
Version: 13.2.0-19
Severity: normal
X-Debbugs-Cc: lbre...@debian.org
Control: affects -1 pcscada libalog dbusada anet ahven libgmpada libgtkada 
libgnatcoll-db libncursesada libaunit adacgi liblog4ada libtexttools 
libtemplates-parser libxmlezout libgnatcoll-bindings libgnatcoll gprbuild

Hello.

Most Ada packages randomly FTBFS on 32 bit architectures with
gprbuild: raised CONSTRAINT_ERROR : a-calend.adb:371 overflow check failed

The problem originates in the gcc-13 switch to time_t64.
gcc/ada/libgnat/s-os_prim__posix.adb is affected by two apparently
distinct issues.

* s-os_prim.adb allocates 3Long_Integer=3void*=3*32 bits for the
  timeval C struct, while 2*64bits = 2Long_Long_Integer are now needed.

  This issue affects other files, but is easy to find and fix.

* The switch breaks the call from Ada to the C gettimeofday function.

  Can anyone explain this, and ideally provide a real fix instead of
  the ugly work-around below?

cat > mycal.c <
int mygettimeofday(struct timeval *restrict tv,
   struct timezone *restrict tz) {
  return gettimeofday(tv, tz);
}
EOF

cat > foo.adb <