------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                       G N A T . D E B U G _ P O O L S                    --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2021, Free Software Foundation, Inc.         --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- 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 GNAT.IO; use GNAT.IO;

with System.CRTL;
with System.Memory;     use System.Memory;
with System.Soft_Links; use System.Soft_Links;

with System.Traceback_Entries;

with GNAT.Debug_Utilities; use GNAT.Debug_Utilities;
with GNAT.HTable;
with GNAT.Traceback; use GNAT.Traceback;

with Ada.Finalization;
with Ada.Unchecked_Conversion;

package body GNAT.Debug_Pools is

   Storage_Alignment : constant := Standard'Maximum_Alignment;
   --  Alignment enforced for all the memory chunks returned by Allocate,
   --  maximized to make sure that it will be compatible with all types.
   --
   --  The addresses returned by the underlying low-level allocator (be it
   --  'new' or a straight 'malloc') aren't guaranteed to be that much aligned
   --  on some targets, so we manage the needed alignment padding ourselves
   --  systematically. Use of a common value for every allocation allows
   --  significant simplifications in the code, nevertheless, for improved
   --  robustness and efficiency overall.

   --  We combine a few internal devices to offer the pool services:
   --
   --  * A management header attached to each allocated memory block, located
   --    right ahead of it, like so:
   --
   --        Storage Address returned by the pool,
   --        aligned on Storage_Alignment
   --                       v
   --      +------+--------+---------------------
   --      | ~~~~ | HEADER | USER DATA ... |
   --      +------+--------+---------------------
   --       <---->
   --       alignment
   --       padding
   --
   --    The alignment padding is required
   --
   --  * A validity bitmap, which holds a validity bit for blocks managed by
   --    the pool. Enforcing Storage_Alignment on those blocks allows efficient
   --    validity management.
   --
   --  * A list of currently used blocks.

   Max_Ignored_Levels : constant Natural := 10;
   --  Maximum number of levels that will be ignored in backtraces. This is so
   --  that we still have enough significant levels in the tracebacks returned
   --  to the user.
   --
   --  The value 10 is chosen as being greater than the maximum callgraph
   --  in this package. Its actual value is not really relevant, as long as it
   --  is high enough to make sure we still have enough frames to return to
   --  the user after we have hidden the frames internal to this package.

   Disable : Boolean := False;
   --  This variable is used to avoid infinite loops, where this package would
   --  itself allocate memory and then call itself recursively, forever. Useful
   --  when System_Memory_Debug_Pool_Enabled is True.

   System_Memory_Debug_Pool_Enabled : Boolean := False;
   --  If True, System.Memory allocation uses Debug_Pool

   Allow_Unhandled_Memory : Boolean := False;
   --  If True, protects Deallocate against releasing memory allocated before
   --  System_Memory_Debug_Pool_Enabled was set.

   Traceback_Count : Byte_Count := 0;
   --  Total number of traceback elements

   ---------------------------
   -- Back Trace Hash Table --
   ---------------------------

   --  This package needs to store one set of tracebacks for each allocation
   --  point (when was it allocated or deallocated). This would use too much
   --  memory,  so the tracebacks are actually stored in a hash table, and
   --  we reference elements in this hash table instead.

   --  This hash-table will remain empty if the discriminant Stack_Trace_Depth
   --  for the pools is set to 0.

   --  This table is a global table, that can be shared among all debug pools
   --  with no problems.

   type Header is range 1 .. 1023;
   --  Number of elements in the hash-table

   type Tracebacks_Array_Access is access Tracebacks_Array;

   type Traceback_Kind is (Alloc, Dealloc, Indirect_Alloc, Indirect_Dealloc);

   type Traceback_Htable_Elem;
   type Traceback_Htable_Elem_Ptr
      is access Traceback_Htable_Elem;

   type Traceback_Htable_Elem is record
      Traceback   : Tracebacks_Array_Access;
      Kind        : Traceback_Kind;
      Count       : Natural;
      --  Size of the memory allocated/freed at Traceback since last Reset call

      Total       : Byte_Count;
      --  Number of chunk of memory allocated/freed at Traceback since last
      --  Reset call.

      Frees       : Natural;
      --  Number of chunk of memory allocated at Traceback, currently freed
      --  since last Reset call. (only for Alloc & Indirect_Alloc elements)

      Total_Frees : Byte_Count;
      --  Size of the memory allocated at Traceback, currently freed since last
      --  Reset call. (only for Alloc & Indirect_Alloc elements)

      Next        : Traceback_Htable_Elem_Ptr;
   end record;

   --  Subprograms used for the Backtrace_Htable instantiation

   procedure Set_Next
     (E    : Traceback_Htable_Elem_Ptr;
      Next : Traceback_Htable_Elem_Ptr);
   pragma Inline (Set_Next);

   function Next
     (E : Traceback_Htable_Elem_Ptr) return Traceback_Htable_Elem_Ptr;
   pragma Inline (Next);

   function Get_Key
     (E : Traceback_Htable_Elem_Ptr) return Tracebacks_Array_Access;
   pragma Inline (Get_Key);

   function Hash (T : Tracebacks_Array_Access) return Header;
   pragma Inline (Hash);

   function Equal (K1, K2 : Tracebacks_Array_Access) return Boolean;
   --  Why is this not inlined???

   --  The hash table for back traces

   package Backtrace_Htable is new GNAT.HTable.Static_HTable
     (Header_Num => Header,
      Element    => Traceback_Htable_Elem,
      Elmt_Ptr   => Traceback_Htable_Elem_Ptr,
      Null_Ptr   => null,
      Set_Next   => Set_Next,
      Next       => Next,
      Key        => Tracebacks_Array_Access,
      Get_Key    => Get_Key,
      Hash       => Hash,
      Equal      => Equal);

   -----------------------
   -- Allocations table --
   -----------------------

   type Allocation_Header;
   type Allocation_Header_Access is access Allocation_Header;

   type Traceback_Ptr_Or_Address is new System.Address;
   --  A type that acts as a C union, and is either a System.Address or a
   --  Traceback_Htable_Elem_Ptr.

   --  The following record stores extra information that needs to be
   --  memorized for each block allocated with the special debug pool.

   type Allocation_Header is record
      Allocation_Address : System.Address;
      --  Address of the block returned by malloc, possibly unaligned

      Block_Size : Storage_Offset;
      --  Needed only for advanced freeing algorithms (traverse all allocated
      --  blocks for potential references). This value is negated when the
      --  chunk of memory has been logically freed by the application. This
      --  chunk has not been physically released yet.

      Alloc_Traceback : Traceback_Htable_Elem_Ptr;
      --  ??? comment required

      Dealloc_Traceback : Traceback_Ptr_Or_Address;
      --  Pointer to the traceback for the allocation (if the memory chunk is
      --  still valid), or to the first deallocation otherwise. Make sure this
      --  is a thin pointer to save space.
      --
      --  Dealloc_Traceback is also for blocks that are still allocated to
      --  point to the previous block in the list. This saves space in this
      --  header, and make manipulation of the lists of allocated pointers
      --  faster.

      Next : System.Address;
      --  Point to the next block of the same type (either allocated or
      --  logically freed) in memory. This points to the beginning of the user
      --  data, and does not include the header of that block.
   end record;

   function Header_Of
     (Address : System.Address) return Allocation_Header_Access;
   pragma Inline (Header_Of);
   --  Return the header corresponding to a previously allocated address

   function To_Address is new Ada.Unchecked_Conversion
     (Traceback_Ptr_Or_Address, System.Address);

   function To_Address is new Ada.Unchecked_Conversion
     (System.Address, Traceback_Ptr_Or_Address);

   function To_Traceback is new Ada.Unchecked_Conversion
     (Traceback_Ptr_Or_Address, Traceback_Htable_Elem_Ptr);

   function To_Traceback is new Ada.Unchecked_Conversion
     (Traceback_Htable_Elem_Ptr, Traceback_Ptr_Or_Address);

   Header_Offset : constant Storage_Count :=
     (Allocation_Header'Object_Size / System.Storage_Unit);
   --  Offset, in bytes, from start of allocation Header to start of User
   --  data.  The start of user data is assumed to be aligned at least as much
   --  as what the header type requires, so applying this offset yields a
   --  suitably aligned address as well.

   Extra_Allocation : constant Storage_Count :=
     (Storage_Alignment - 1 + Header_Offset);
   --  Amount we need to secure in addition to the user data for a given
   --  allocation request: room for the allocation header plus worst-case
   --  alignment padding.

   -----------------------
   -- Local subprograms --
   -----------------------

   function Align (Addr : Integer_Address) return Integer_Address;
   pragma Inline (Align);
   --  Return the next address aligned on Storage_Alignment from Addr.

   function Find_Or_Create_Traceback
     (Pool                : Debug_Pool;
      Kind                : Traceback_Kind;
      Size                : Storage_Count;
      Ignored_Frame_Start : System.Address;
      Ignored_Frame_End   : System.Address) return Traceback_Htable_Elem_Ptr;
   --  Return an element matching the current traceback (omitting the frames
   --  that are in the current package). If this traceback already existed in
   --  the htable, a pointer to this is returned to spare memory. Null is
   --  returned if the pool is set not to store tracebacks. If the traceback
   --  already existed in the table, the count is incremented so that
   --  Dump_Tracebacks returns useful results. All addresses up to, and
   --  including, an address between Ignored_Frame_Start .. Ignored_Frame_End
   --  are ignored.

   function Output_File (Pool : Debug_Pool) return File_Type;
   pragma Inline (Output_File);
   --  Returns file_type on which error messages have to be generated for Pool

   procedure Put_Line
     (File                : File_Type;
      Depth               : Natural;
      Traceback           : Tracebacks_Array_Access;
      Ignored_Frame_Start : System.Address := System.Null_Address;
      Ignored_Frame_End   : System.Address := System.Null_Address);
   --  Print Traceback to File. If Traceback is null, print the call_chain
   --  at the current location, up to Depth levels, ignoring all addresses
   --  up to the first one in the range:
   --    Ignored_Frame_Start .. Ignored_Frame_End

   procedure Stdout_Put (S : String);
   --  Wrapper for Put that ensures we always write to stdout instead of the
   --  current output file defined in GNAT.IO.

   procedure Stdout_Put_Line (S : String);
   --  Wrapper for Put_Line that ensures we always write to stdout instead of
   --  the current output file defined in GNAT.IO.

   procedure Print_Traceback
     (Output_File : File_Type;
      Prefix      : String;
      Traceback   : Traceback_Htable_Elem_Ptr);
   --  Output Prefix & Traceback & EOL. Print nothing if Traceback is null.

   procedure Print_Address (File : File_Type; Addr : Address);
   --  Output System.Address without using secondary stack.
   --  When System.Memory uses Debug_Pool, secondary stack cannot be used
   --  during Allocate calls, as some Allocate calls are done to
   --  register/initialize a secondary stack for a foreign thread.
   --  During these calls, the secondary stack is not available yet.

   package Validity is
      function Is_Handled (Storage : System.Address) return Boolean;
      pragma Inline (Is_Handled);
      --  Return True if Storage is the address of a block that the debug pool
      --  already had under its control. Used to allow System.Memory to use
      --  Debug_Pools

      function Is_Valid (Storage : System.Address) return Boolean;
      pragma Inline (Is_Valid);
      --  Return True if Storage is the address of a block that the debug pool
      --  has under its control, in which case Header_Of may be used to access
      --  the associated allocation header.

      procedure Set_Valid (Storage : System.Address; Value : Boolean);
      pragma Inline (Set_Valid);
      --  Mark the address Storage as being under control of the memory pool
      --  (if Value is True), or not (if Value is False).

      Validity_Count : Byte_Count := 0;
      --  Total number of validity elements

   end Validity;

   use Validity;

   procedure Set_Dead_Beef
     (Storage_Address          : System.Address;
      Size_In_Storage_Elements : Storage_Count);
   --  Set the contents of the memory block pointed to by Storage_Address to
   --  the 16#DEADBEEF# pattern. If Size_In_Storage_Elements is not a multiple
   --  of the length of this pattern, the last instance may be partial.

   procedure Free_Physically (Pool : in out Debug_Pool);
   --  Start to physically release some memory to the system, until the amount
   --  of logically (but not physically) freed memory is lower than the
   --  expected amount in Pool.

   procedure Allocate_End;
   procedure Deallocate_End;
   procedure Dereference_End;
   --  These procedures are used as markers when computing the stacktraces,
   --  so that addresses in the debug pool itself are not reported to the user.

   Code_Address_For_Allocate_End    : System.Address := System.Null_Address;
   Code_Address_For_Deallocate_End  : System.Address;
   Code_Address_For_Dereference_End : System.Address;
   --  Taking the address of the above procedures will not work on some
   --  architectures (HPUX for instance). Thus we do the same thing that
   --  is done in a-except.adb, and get the address of labels instead.

   procedure Skip_Levels
     (Depth               : Natural;
      Trace               : Tracebacks_Array;
      Start               : out Natural;
      Len                 : in out Natural;
      Ignored_Frame_Start : System.Address;
      Ignored_Frame_End   : System.Address);
   --  Set Start .. Len to the range of values from Trace that should be output
   --  to the user. This range of values excludes any address prior to the
   --  first one in Ignored_Frame_Start .. Ignored_Frame_End (basically
   --  addresses internal to this package). Depth is the number of levels that
   --  the user is interested in.

   package STBE renames System.Traceback_Entries;

   function PC_For (TB_Entry : STBE.Traceback_Entry) return System.Address
     renames STBE.PC_For;

   type Scope_Lock is
     new Ada.Finalization.Limited_Controlled with null record;
   --  Used to handle Lock_Task/Unlock_Task calls

   overriding procedure Initialize (This : in out Scope_Lock);
   --  Lock task on initialization

   overriding procedure Finalize   (This : in out Scope_Lock);
   --  Unlock task on finalization

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize (This : in out Scope_Lock) is
      pragma Unreferenced (This);
   begin
      Lock_Task.all;
   end Initialize;

   --------------
   -- Finalize --
   --------------

   procedure Finalize (This : in out Scope_Lock) is
      pragma Unreferenced (This);
   begin
      Unlock_Task.all;
   end Finalize;

   -----------
   -- Align --
   -----------

   function Align (Addr : Integer_Address) return Integer_Address is
      Factor : constant Integer_Address := Storage_Alignment;
   begin
      return ((Addr + Factor - 1) / Factor) * Factor;
   end Align;

   ---------------
   -- Header_Of --
   ---------------

   function Header_Of
     (Address : System.Address) return Allocation_Header_Access
   is
      function Convert is
        new Ada.Unchecked_Conversion
                  (System.Address,
                   Allocation_Header_Access);
   begin
      return Convert (Address - Header_Offset);
   end Header_Of;

   --------------
   -- Set_Next --
   --------------

   procedure Set_Next
     (E    : Traceback_Htable_Elem_Ptr;
      Next : Traceback_Htable_Elem_Ptr)
   is
   begin
      E.Next := Next;
   end Set_Next;

   ----------
   -- Next --
   ----------

   function Next
     (E : Traceback_Htable_Elem_Ptr) return Traceback_Htable_Elem_Ptr
   is
   begin
      return E.Next;
   end Next;

   -----------
   -- Equal --
   -----------

   function Equal (K1, K2 : Tracebacks_Array_Access) return Boolean is
      use type Tracebacks_Array;
   begin
      return K1.all = K2.all;
   end Equal;

   -------------
   -- Get_Key --
   -------------

   function Get_Key
     (E : Traceback_Htable_Elem_Ptr) return Tracebacks_Array_Access
   is
   begin
      return E.Traceback;
   end Get_Key;

   ----------
   -- Hash --
   ----------

   function Hash (T : Tracebacks_Array_Access) return Header is
      Result : Integer_Address := 0;

   begin
      for X in T'Range loop
         Result := Result + To_Integer (PC_For (T (X)));
      end loop;

      return Header (1 + Result mod Integer_Address (Header'Last));
   end Hash;

   -----------------
   -- Output_File --
   -----------------

   function Output_File (Pool : Debug_Pool) return File_Type is
   begin
      if Pool.Errors_To_Stdout then
         return Standard_Output;
      else
         return Standard_Error;
      end if;
   end Output_File;

   -------------------
   -- Print_Address --
   -------------------

   procedure Print_Address (File : File_Type; Addr : Address) is
   begin
      --  Warning: secondary stack cannot be used here. When System.Memory
      --  implementation uses Debug_Pool, Print_Address can be called during
      --  secondary stack creation for foreign threads.

      Put (File, Image_C (Addr));
   end Print_Address;

   --------------
   -- Put_Line --
   --------------

   procedure Put_Line
     (File                : File_Type;
      Depth               : Natural;
      Traceback           : Tracebacks_Array_Access;
      Ignored_Frame_Start : System.Address := System.Null_Address;
      Ignored_Frame_End   : System.Address := System.Null_Address)
   is
      procedure Print (Tr : Tracebacks_Array);
      --  Print the traceback to standard_output

      -----------
      -- Print --
      -----------

      procedure Print (Tr : Tracebacks_Array) is
      begin
         for J in Tr'Range loop
            Print_Address (File, PC_For (Tr (J)));
            Put (File, ' ');
         end loop;
         Put (File, ASCII.LF);
      end Print;

   --  Start of processing for Put_Line

   begin
      if Traceback = null then
         declare
            Len   : Natural;
            Start : Natural;
            Trace : aliased Tracebacks_Array (1 .. Depth + Max_Ignored_Levels);

         begin
            Call_Chain (Trace, Len);
            Skip_Levels
              (Depth               => Depth,
               Trace               => Trace,
               Start               => Start,
               Len                 => Len,
               Ignored_Frame_Start => Ignored_Frame_Start,
               Ignored_Frame_End   => Ignored_Frame_End);
            Print (Trace (Start .. Len));
         end;

      else
         Print (Traceback.all);
      end if;
   end Put_Line;

   -----------------
   -- Skip_Levels --
   -----------------

   procedure Skip_Levels
     (Depth               : Natural;
      Trace               : Tracebacks_Array;
      Start               : out Natural;
      Len                 : in out Natural;
      Ignored_Frame_Start : System.Address;
      Ignored_Frame_End   : System.Address)
   is
   begin
      Start := Trace'First;

      while Start <= Len
        and then (PC_For (Trace (Start)) < Ignored_Frame_Start
                    or else PC_For (Trace (Start)) > Ignored_Frame_End)
      loop
         Start := Start + 1;
      end loop;

      Start := Start + 1;

      --  Just in case: make sure we have a traceback even if Ignore_Till
      --  wasn't found.

      if Start > Len then
         Start := 1;
      end if;

      if Len - Start + 1 > Depth then
         Len := Depth + Start - 1;
      end if;
   end Skip_Levels;

   ------------------------------
   -- Find_Or_Create_Traceback --
   ------------------------------

   function Find_Or_Create_Traceback
     (Pool                : Debug_Pool;
      Kind                : Traceback_Kind;
      Size                : Storage_Count;
      Ignored_Frame_Start : System.Address;
      Ignored_Frame_End   : System.Address) return Traceback_Htable_Elem_Ptr
   is
   begin
      if Pool.Stack_Trace_Depth = 0 then
         return null;
      end if;

      declare
         Disable_Exit_Value : constant Boolean := Disable;

         Elem  : Traceback_Htable_Elem_Ptr;
         Len   : Natural;
         Start : Natural;
         Trace : aliased Tracebacks_Array
                   (1 .. Integer (Pool.Stack_Trace_Depth) +
                      Max_Ignored_Levels);

      begin
         Disable := True;
         Call_Chain (Trace, Len);
         Skip_Levels
           (Depth               => Pool.Stack_Trace_Depth,
            Trace               => Trace,
            Start               => Start,
            Len                 => Len,
            Ignored_Frame_Start => Ignored_Frame_Start,
            Ignored_Frame_End   => Ignored_Frame_End);

         --  Check if the traceback is already in the table

         Elem :=
           Backtrace_Htable.Get (Trace (Start .. Len)'Unrestricted_Access);

         --  If not, insert it

         if Elem = null then
            Elem :=
              new Traceback_Htable_Elem'
                    (Traceback   =>
                       new Tracebacks_Array'(Trace (Start .. Len)),
                     Count       => 1,
                     Kind        => Kind,
                     Total       => Byte_Count (Size),
                     Frees       => 0,
                     Total_Frees => 0,
                     Next        => null);
            Traceback_Count := Traceback_Count + 1;
            Backtrace_Htable.Set (Elem);

         else
            Elem.Count := Elem.Count + 1;
            Elem.Total := Elem.Total + Byte_Count (Size);
         end if;

         Disable := Disable_Exit_Value;
         return Elem;
      exception
         when others =>
            Disable := Disable_Exit_Value;
            raise;
      end;
   end Find_Or_Create_Traceback;

   --------------
   -- Validity --
   --------------

   package body Validity is

      --  The validity bits of the allocated blocks are kept in a has table.
      --  Each component of the hash table contains the validity bits for a
      --  16 Mbyte memory chunk.

      --  The reason the validity bits are kept for chunks of memory rather
      --  than in a big array is that on some 64 bit platforms, it may happen
      --  that two chunk of allocated data are very far from each other.

      Memory_Chunk_Size : constant Integer_Address := 2 ** 24; --  16 MB
      Validity_Divisor  : constant := Storage_Alignment * System.Storage_Unit;

      Max_Validity_Byte_Index : constant :=
                                  Memory_Chunk_Size / Validity_Divisor;

      subtype Validity_Byte_Index is
        Integer_Address range 0 .. Max_Validity_Byte_Index - 1;

      type Byte is mod 2 ** System.Storage_Unit;

      type Validity_Bits_Part is array (Validity_Byte_Index) of Byte;
      type Validity_Bits_Part_Ref is access all Validity_Bits_Part;
      No_Validity_Bits_Part : constant Validity_Bits_Part_Ref := null;

      type Validity_Bits is record
         Valid : Validity_Bits_Part_Ref := No_Validity_Bits_Part;
         --  True if chunk of memory at this address is currently allocated

         Handled : Validity_Bits_Part_Ref := No_Validity_Bits_Part;
         --  True if chunk of memory at this address was allocated once after
         --  Allow_Unhandled_Memory was set to True. Used to know on Deallocate
         --  if chunk of memory should be handled a block allocated by this
         --  package.

      end record;

      type Validity_Bits_Ref is access all Validity_Bits;
      No_Validity_Bits : constant Validity_Bits_Ref := null;

      Max_Header_Num : constant := 1023;

      type Header_Num is range 0 .. Max_Header_Num - 1;

      function Hash (F : Integer_Address) return Header_Num;

      function Is_Valid_Or_Handled
        (Storage : System.Address;
         Valid   : Boolean) return Boolean;
      pragma Inline (Is_Valid_Or_Handled);
      --  Internal implementation of Is_Valid and Is_Handled.
      --  Valid is used to select Valid or Handled arrays.

      package Validy_Htable is new GNAT.HTable.Simple_HTable
        (Header_Num => Header_Num,
         Element    => Validity_Bits_Ref,
         No_Element => No_Validity_Bits,
         Key        => Integer_Address,
         Hash       => Hash,
         Equal      => "=");
      --  Table to keep the validity and handled bit blocks for the allocated
      --  data.

      function To_Pointer is new Ada.Unchecked_Conversion
        (System.Address, Validity_Bits_Part_Ref);

      procedure Memset (A : Address; C : Integer; N : size_t);
      pragma Import (C, Memset, "memset");

      ----------
      -- Hash --
      ----------

      function Hash (F : Integer_Address) return Header_Num is
      begin
         return Header_Num (F mod Max_Header_Num);
      end Hash;

      -------------------------
      -- Is_Valid_Or_Handled --
      -------------------------

      function Is_Valid_Or_Handled
        (Storage : System.Address;
         Valid   : Boolean) return Boolean is
         Int_Storage  : constant Integer_Address := To_Integer (Storage);

      begin
         --  The pool only returns addresses aligned on Storage_Alignment so
         --  anything off cannot be a valid block address and we can return
         --  early in this case. We actually have to since our data structures
         --  map validity bits for such aligned addresses only.

         if Int_Storage mod Storage_Alignment /= 0 then
            return False;
         end if;

         declare
            Block_Number : constant Integer_Address :=
                             Int_Storage /  Memory_Chunk_Size;
            Ptr          : constant Validity_Bits_Ref :=
                             Validy_Htable.Get (Block_Number);
            Offset       : constant Integer_Address :=
                             (Int_Storage -
                               (Block_Number * Memory_Chunk_Size)) /
                                  Storage_Alignment;
            Bit          : constant Byte :=
                             2 ** Natural (Offset mod System.Storage_Unit);
         begin
            if Ptr = No_Validity_Bits then
               return False;
            else
               if Valid then
                  return (Ptr.Valid (Offset / System.Storage_Unit)
                             and Bit) /= 0;
               else
                  if Ptr.Handled = No_Validity_Bits_Part then
                     return False;
                  else
                     return (Ptr.Handled (Offset / System.Storage_Unit)
                                and Bit) /= 0;
                  end if;
               end if;
            end if;
         end;
      end Is_Valid_Or_Handled;

      --------------
      -- Is_Valid --
      --------------

      function Is_Valid (Storage : System.Address) return Boolean is
      begin
         return Is_Valid_Or_Handled (Storage => Storage, Valid => True);
      end Is_Valid;

      -----------------
      -- Is_Handled --
      -----------------

      function Is_Handled (Storage : System.Address) return Boolean is
      begin
         return Is_Valid_Or_Handled (Storage => Storage, Valid => False);
      end Is_Handled;

      ---------------
      -- Set_Valid --
      ---------------

      procedure Set_Valid (Storage : System.Address; Value : Boolean) is
         Int_Storage  : constant Integer_Address := To_Integer (Storage);
         Block_Number : constant Integer_Address :=
                          Int_Storage /  Memory_Chunk_Size;
         Ptr          : Validity_Bits_Ref := Validy_Htable.Get (Block_Number);
         Offset       : constant Integer_Address :=
                          (Int_Storage - (Block_Number * Memory_Chunk_Size)) /
                             Storage_Alignment;
         Bit          : constant Byte :=
                          2 ** Natural (Offset mod System.Storage_Unit);

         procedure Set_Handled;
         pragma Inline (Set_Handled);
         --  if Allow_Unhandled_Memory set Handled bit in table.

         -----------------
         -- Set_Handled --
         -----------------

         procedure Set_Handled is
         begin
            if Allow_Unhandled_Memory then
               if Ptr.Handled = No_Validity_Bits_Part then
                  Ptr.Handled :=
                    To_Pointer (Alloc (size_t (Max_Validity_Byte_Index)));
                  Memset
                    (A => Ptr.Handled.all'Address,
                     C => 0,
                     N => size_t (Max_Validity_Byte_Index));
               end if;

               Ptr.Handled (Offset / System.Storage_Unit) :=
                 Ptr.Handled (Offset / System.Storage_Unit) or Bit;
            end if;
         end Set_Handled;

      --  Start of processing for Set_Valid

      begin
         if Ptr = No_Validity_Bits then

            --  First time in this memory area: allocate a new block and put
            --  it in the table.

            if Value then
               Ptr := new Validity_Bits;
               Validity_Count := Validity_Count + 1;
               Ptr.Valid :=
                 To_Pointer (Alloc (size_t (Max_Validity_Byte_Index)));
               Validy_Htable.Set (Block_Number, Ptr);
               Memset
                 (A => Ptr.Valid.all'Address,
                  C => 0,
                  N => size_t (Max_Validity_Byte_Index));
               Ptr.Valid (Offset / System.Storage_Unit) := Bit;
               Set_Handled;
            end if;

         else
            if Value then
               Ptr.Valid (Offset / System.Storage_Unit) :=
                 Ptr.Valid (Offset / System.Storage_Unit) or Bit;
               Set_Handled;
            else
               Ptr.Valid (Offset / System.Storage_Unit) :=
                 Ptr.Valid (Offset / System.Storage_Unit) and (not Bit);
            end if;
         end if;
      end Set_Valid;
   end Validity;

   --------------
   -- Allocate --
   --------------

   procedure Allocate
     (Pool                     : in out Debug_Pool;
      Storage_Address          : out Address;
      Size_In_Storage_Elements : Storage_Count;
      Alignment                : Storage_Count)
   is
      pragma Unreferenced (Alignment);
      --  Ignored, we always force Storage_Alignment

      type Local_Storage_Array is new Storage_Array
        (1 .. Size_In_Storage_Elements + Extra_Allocation);

      type Ptr is access Local_Storage_Array;
      --  On some systems, we might want to physically protect pages against
      --  writing when they have been freed (of course, this is expensive in
      --  terms of wasted memory). To do that, all we should have to do it to
      --  set the size of this array to the page size. See mprotect().

      Current : Byte_Count;
      P       : Ptr;
      Trace   : Traceback_Htable_Elem_Ptr;

      Reset_Disable_At_Exit : Boolean := False;

      Lock : Scope_Lock;
      pragma Unreferenced (Lock);

   begin
      <<Allocate_Label>>

      if Disable then
         Storage_Address :=
           System.CRTL.malloc (System.CRTL.size_t (Size_In_Storage_Elements));
         return;
      end if;

      Reset_Disable_At_Exit := True;
      Disable := True;

      Pool.Alloc_Count := Pool.Alloc_Count + 1;

      --  If necessary, start physically releasing memory. The reason this is
      --  done here, although Pool.Logically_Deallocated has not changed above,
      --  is so that we do this only after a series of deallocations (e.g loop
      --  that deallocates a big array). If we were doing that in Deallocate,
      --  we might be physically freeing memory several times during the loop,
      --  which is expensive.

      if Pool.Logically_Deallocated >
           Byte_Count (Pool.Maximum_Logically_Freed_Memory)
      then
         Free_Physically (Pool);
      end if;

      --  Use standard (i.e. through malloc) allocations. This automatically
      --  raises Storage_Error if needed. We also try once more to physically
      --  release memory, so that even marked blocks, in the advanced scanning,
      --  are freed. Note that we do not initialize the storage array since it
      --  is not necessary to do so (however this will cause bogus valgrind
      --  warnings, which should simply be ignored).

      begin
         P := new Local_Storage_Array;

      exception
         when Storage_Error =>
            Free_Physically (Pool);
            P := new Local_Storage_Array;
      end;

      --  Compute Storage_Address, aimed at receiving user data. We need room
      --  for the allocation header just ahead of the user data space plus
      --  alignment padding so Storage_Address is aligned on Storage_Alignment,
      --  like so:
      --
      --                         Storage_Address, aligned
      --                         on Storage_Alignment
      --                           v
      --          | ~~~~ | Header | User data ... |
      --                  ^........^
      --                  Header_Offset
      --
      --  Header_Offset is fixed so moving back and forth between user data
      --  and allocation header is straightforward. The value is also such
      --  that the header type alignment is honored when starting from
      --  Default_alignment.

      --  For the purpose of computing Storage_Address, we just do as if the
      --  header was located first, followed by the alignment padding:

      Storage_Address :=
        To_Address (Align (To_Integer (P.all'Address) +
                      Integer_Address (Header_Offset)));
      --  Computation is done in Integer_Address, not Storage_Offset, because
      --  the range of Storage_Offset may not be large enough.

      pragma Assert ((Storage_Address - System.Null_Address)
                     mod Storage_Alignment = 0);
      pragma Assert (Storage_Address + Size_In_Storage_Elements
                     <= P.all'Address + P'Length);

      Trace :=
        Find_Or_Create_Traceback
          (Pool                => Pool,
           Kind                => Alloc,
           Size                => Size_In_Storage_Elements,
           Ignored_Frame_Start => Allocate_Label'Address,
           Ignored_Frame_End   => Code_Address_For_Allocate_End);

      pragma Warnings (Off);
      --  Turn warning on alignment for convert call off. We know that in fact
      --  this conversion is safe since P itself is always aligned on
      --  Storage_Alignment.

      Header_Of (Storage_Address).all :=
        (Allocation_Address => P.all'Address,
         Alloc_Traceback    => Trace,
         Dealloc_Traceback  => To_Traceback (null),
         Next               => Pool.First_Used_Block,
         Block_Size         => Size_In_Storage_Elements);

      pragma Warnings (On);

      --  Link this block in the list of used blocks. This will be used to list
      --  memory leaks in Print_Info, and for the advanced schemes of
      --  Physical_Free, where we want to traverse all allocated blocks and
      --  search for possible references.

      --  We insert in front, since most likely we'll be freeing the most
      --  recently allocated blocks first (the older one might stay allocated
      --  for the whole life of the application).

      if Pool.First_Used_Block /= System.Null_Address then
         Header_Of (Pool.First_Used_Block).Dealloc_Traceback :=
           To_Address (Storage_Address);
      end if;

      Pool.First_Used_Block := Storage_Address;

      --  Mark the new address as valid

      Set_Valid (Storage_Address, True);

      if Pool.Low_Level_Traces then
         Put (Output_File (Pool),
              "info: Allocated"
              & Storage_Count'Image (Size_In_Storage_Elements)
              & " bytes at ");
         Print_Address (Output_File (Pool), Storage_Address);
         Put (Output_File (Pool),
              " (physically:"
              & Storage_Count'Image (Local_Storage_Array'Length)
              & " bytes at ");
         Print_Address (Output_File (Pool), P.all'Address);
         Put (Output_File (Pool),
              "), at ");
         Put_Line (Output_File (Pool), Pool.Stack_Trace_Depth, null,
                   Allocate_Label'Address,
                   Code_Address_For_Deallocate_End);
      end if;

      --  Update internal data

      Pool.Allocated :=
        Pool.Allocated + Byte_Count (Size_In_Storage_Elements);

      Current := Pool.Current_Water_Mark;

      if Current > Pool.High_Water then
         Pool.High_Water := Current;
      end if;

      Disable := False;

   exception
      when others =>
         if Reset_Disable_At_Exit then
            Disable := False;
         end if;
         raise;
   end Allocate;

   ------------------
   -- Allocate_End --
   ------------------

   --  DO NOT MOVE, this must be right after Allocate. This is similar to what
   --  is done in a-except, so that we can hide the traceback frames internal
   --  to this package

   procedure Allocate_End is
   begin
      <<Allocate_End_Label>>
      Code_Address_For_Allocate_End := Allocate_End_Label'Address;
   end Allocate_End;

   -------------------
   -- Set_Dead_Beef --
   -------------------

   procedure Set_Dead_Beef
     (Storage_Address          : System.Address;
      Size_In_Storage_Elements : Storage_Count)
   is
      Dead_Bytes : constant := 4;

      type Data is mod 2 ** (Dead_Bytes * 8);
      for Data'Size use Dead_Bytes * 8;

      Dead : constant Data := 16#DEAD_BEEF#;

      type Dead_Memory is array
        (1 .. Size_In_Storage_Elements / Dead_Bytes) of Data;
      type Mem_Ptr is access Dead_Memory;

      type Byte is mod 2 ** 8;
      for Byte'Size use 8;

      type Dead_Memory_Bytes is array (0 .. 2) of Byte;
      type Dead_Memory_Bytes_Ptr is access Dead_Memory_Bytes;

      function From_Ptr is new Ada.Unchecked_Conversion
        (System.Address, Mem_Ptr);

      function From_Ptr is new Ada.Unchecked_Conversion
        (System.Address, Dead_Memory_Bytes_Ptr);

      M      : constant Mem_Ptr := From_Ptr (Storage_Address);
      M2     : Dead_Memory_Bytes_Ptr;
      Modulo : constant Storage_Count :=
                 Size_In_Storage_Elements mod Dead_Bytes;
   begin
      M.all := (others => Dead);

      --  Any bytes left (up to three of them)

      if Modulo /= 0 then
         M2 := From_Ptr (Storage_Address + M'Length * Dead_Bytes);

         M2 (0) := 16#DE#;
         if Modulo >= 2 then
            M2 (1) := 16#AD#;

            if Modulo >= 3 then
               M2 (2) := 16#BE#;
            end if;
         end if;
      end if;
   end Set_Dead_Beef;

   ---------------------
   -- Free_Physically --
   ---------------------

   procedure Free_Physically (Pool : in out Debug_Pool) is
      type Byte is mod 256;
      type Byte_Access is access Byte;

      function To_Byte is new Ada.Unchecked_Conversion
        (System.Address, Byte_Access);

      type Address_Access is access System.Address;

      function To_Address_Access is new Ada.Unchecked_Conversion
        (System.Address, Address_Access);

      In_Use_Mark : constant Byte := 16#D#;
      Free_Mark   : constant Byte := 16#F#;

      Total_Freed : Storage_Count := 0;

      procedure Reset_Marks;
      --  Unmark all the logically freed blocks, so that they are considered
      --  for physical deallocation

      procedure Mark
        (H : Allocation_Header_Access; A : System.Address; In_Use : Boolean);
      --  Mark the user data block starting at A. For a block of size zero,
      --  nothing is done. For a block with a different size, the first byte
      --  is set to either "D" (in use) or "F" (free).

      function Marked (A : System.Address) return Boolean;
      --  Return true if the user data block starting at A might be in use
      --  somewhere else

      procedure Mark_Blocks;
      --  Traverse all allocated blocks, and search for possible references
      --  to logically freed blocks. Mark them appropriately

      procedure Free_Blocks (Ignore_Marks : Boolean);
      --  Physically release blocks. Only the blocks that haven't been marked
      --  will be released, unless Ignore_Marks is true.

      -----------------
      -- Free_Blocks --
      -----------------

      procedure Free_Blocks (Ignore_Marks : Boolean) is
         Header   : Allocation_Header_Access;
         Tmp      : System.Address := Pool.First_Free_Block;
         Next     : System.Address;
         Previous : System.Address := System.Null_Address;

      begin
         while Tmp /= System.Null_Address
           and then
             not (Total_Freed > Pool.Minimum_To_Free
                   and Pool.Logically_Deallocated <
                         Byte_Count (Pool.Maximum_Logically_Freed_Memory))
         loop
            Header := Header_Of (Tmp);

            --  If we know, or at least assume, the block is no longer
            --  referenced anywhere, we can free it physically.

            if Ignore_Marks or else not Marked (Tmp) then
               declare
                  pragma Suppress (All_Checks);
                  --  Suppress the checks on this section. If they are overflow
                  --  errors, it isn't critical, and we'd rather avoid a
                  --  Constraint_Error in that case.

               begin
                  --  Note that block_size < zero for freed blocks

                  Pool.Physically_Deallocated :=
                    Pool.Physically_Deallocated -
                      Byte_Count (Header.Block_Size);

                  Pool.Logically_Deallocated :=
                    Pool.Logically_Deallocated +
                      Byte_Count (Header.Block_Size);

                  Total_Freed := Total_Freed - Header.Block_Size;
               end;

               Next := Header.Next;

               if Pool.Low_Level_Traces then
                  Put
                    (Output_File (Pool),
                     "info: Freeing physical memory "
                     & Storage_Count'Image
                       ((abs Header.Block_Size) + Extra_Allocation)
                     & " bytes at ");
                  Print_Address (Output_File (Pool),
                                 Header.Allocation_Address);
                  Put_Line (Output_File (Pool), "");
               end if;

               if System_Memory_Debug_Pool_Enabled then
                  System.CRTL.free (Header.Allocation_Address);
               else
                  System.Memory.Free (Header.Allocation_Address);
               end if;

               Set_Valid (Tmp, False);

               --  Remove this block from the list

               if Previous = System.Null_Address then
                  Pool.First_Free_Block := Next;
               else
                  Header_Of (Previous).Next := Next;
               end if;

               Tmp := Next;

            else
               Previous := Tmp;
               Tmp := Header.Next;
            end if;
         end loop;
      end Free_Blocks;

      ----------
      -- Mark --
      ----------

      procedure Mark
        (H      : Allocation_Header_Access;
         A      : System.Address;
         In_Use : Boolean)
      is
      begin
         if H.Block_Size /= 0 then
            To_Byte (A).all := (if In_Use then In_Use_Mark else Free_Mark);
         end if;
      end Mark;

      -----------------
      -- Mark_Blocks --
      -----------------

      procedure Mark_Blocks is
         Tmp      : System.Address := Pool.First_Used_Block;
         Previous : System.Address;
         Last     : System.Address;
         Pointed  : System.Address;
         Header   : Allocation_Header_Access;

      begin
         --  For each allocated block, check its contents. Things that look
         --  like a possible address are used to mark the blocks so that we try
         --  and keep them, for better detection in case of invalid access.
         --  This mechanism is far from being fool-proof: it doesn't check the
         --  stacks of the threads, doesn't check possible memory allocated not
         --  under control of this debug pool. But it should allow us to catch
         --  more cases.

         while Tmp /= System.Null_Address loop
            Previous := Tmp;
            Last     := Tmp + Header_Of (Tmp).Block_Size;
            while Previous < Last loop
               --  ??? Should we move byte-per-byte, or consider that addresses
               --  are always aligned on 4-bytes boundaries ? Let's use the
               --  fastest for now.

               Pointed := To_Address_Access (Previous).all;
               if Is_Valid (Pointed) then
                  Header := Header_Of (Pointed);

                  --  Do not even attempt to mark blocks in use. That would
                  --  screw up the whole application, of course.

                  if Header.Block_Size < 0 then
                     Mark (Header, Pointed, In_Use => True);
                  end if;
               end if;

               Previous := Previous + System.Address'Size;
            end loop;

            Tmp := Header_Of (Tmp).Next;
         end loop;
      end Mark_Blocks;

      ------------
      -- Marked --
      ------------

      function Marked (A : System.Address) return Boolean is
      begin
         return To_Byte (A).all = In_Use_Mark;
      end Marked;

      -----------------
      -- Reset_Marks --
      -----------------

      procedure Reset_Marks is
         Current : System.Address := Pool.First_Free_Block;
         Header  : Allocation_Header_Access;

      begin
         while Current /= System.Null_Address loop
            Header := Header_Of (Current);
            Mark (Header, Current, False);
            Current := Header.Next;
         end loop;
      end Reset_Marks;

      Lock : Scope_Lock;
      pragma Unreferenced (Lock);

   --  Start of processing for Free_Physically

   begin
      if Pool.Advanced_Scanning then

         --  Reset the mark for each freed block

         Reset_Marks;

         Mark_Blocks;
      end if;

      Free_Blocks (Ignore_Marks => not Pool.Advanced_Scanning);

      --  The contract is that we need to free at least Minimum_To_Free bytes,
      --  even if this means freeing marked blocks in the advanced scheme.

      if Total_Freed < Pool.Minimum_To_Free
        and then Pool.Advanced_Scanning
      then
         Pool.Marked_Blocks_Deallocated := True;
         Free_Blocks (Ignore_Marks => True);
      end if;
   end Free_Physically;

   --------------
   -- Get_Size --
   --------------

   procedure Get_Size
     (Storage_Address          : Address;
      Size_In_Storage_Elements : out Storage_Count;
      Valid                    : out Boolean)
   is
      Lock : Scope_Lock;
      pragma Unreferenced (Lock);

   begin
      Valid := Is_Valid (Storage_Address);
      Size_In_Storage_Elements := Storage_Count'First;

      if Is_Valid (Storage_Address) then
         declare
            Header : constant Allocation_Header_Access :=
                       Header_Of (Storage_Address);

         begin
            if Header.Block_Size >= 0 then
               Valid := True;
               Size_In_Storage_Elements := Header.Block_Size;
            else
               Valid := False;
            end if;
         end;
      else
         Valid := False;
      end if;
   end Get_Size;

   ---------------------
   -- Print_Traceback --
   ---------------------

   procedure Print_Traceback
     (Output_File : File_Type;
      Prefix      : String;
      Traceback   : Traceback_Htable_Elem_Ptr)
   is
   begin
      if Traceback /= null then
         Put (Output_File, Prefix);
         Put_Line (Output_File, 0, Traceback.Traceback);
      end if;
   end Print_Traceback;

   ----------------
   -- Deallocate --
   ----------------

   procedure Deallocate
     (Pool                     : in out Debug_Pool;
      Storage_Address          : Address;
      Size_In_Storage_Elements : Storage_Count;
      Alignment                : Storage_Count)
   is
      pragma Unreferenced (Alignment);

      Header   : constant Allocation_Header_Access :=
                   Header_Of (Storage_Address);
      Previous : System.Address;
      Valid    : Boolean;

      Header_Block_Size_Was_Less_Than_0 : Boolean := True;

   begin
      <<Deallocate_Label>>

      declare
         Lock : Scope_Lock;
         pragma Unreferenced (Lock);

      begin
         Valid := Is_Valid (Storage_Address);

         if Valid and then not (Header.Block_Size < 0) then
            Header_Block_Size_Was_Less_Than_0 := False;

            --  Some sort of codegen problem or heap corruption caused the
            --  Size_In_Storage_Elements to be wrongly computed. The code
            --  below is all based on the assumption that Header.all is not
            --  corrupted, such that the error is non-fatal.

            if Header.Block_Size /= Size_In_Storage_Elements and then
              Size_In_Storage_Elements /= Storage_Count'Last
            then
               Put_Line (Output_File (Pool),
                         "error: Deallocate size "
                         & Storage_Count'Image (Size_In_Storage_Elements)
                         & " does not match allocate size "
                         & Storage_Count'Image (Header.Block_Size));
            end if;

            if Pool.Low_Level_Traces then
               Put (Output_File (Pool),
                    "info: Deallocated"
                    & Storage_Count'Image (Header.Block_Size)
                    & " bytes at ");
               Print_Address (Output_File (Pool), Storage_Address);
               Put (Output_File (Pool),
                    " (physically"
                    & Storage_Count'Image
                      (Header.Block_Size + Extra_Allocation)
                    & " bytes at ");
               Print_Address (Output_File (Pool), Header.Allocation_Address);
               Put (Output_File (Pool), "), at ");

               Put_Line (Output_File (Pool), Pool.Stack_Trace_Depth, null,
                         Deallocate_Label'Address,
                         Code_Address_For_Deallocate_End);
               Print_Traceback (Output_File (Pool),
                                "   Memory was allocated at ",
                                Header.Alloc_Traceback);
            end if;

            --  Remove this block from the list of used blocks

            Previous :=
              To_Address (Header.Dealloc_Traceback);

            if Previous = System.Null_Address then
               Pool.First_Used_Block := Header_Of (Pool.First_Used_Block).Next;

               if Pool.First_Used_Block /= System.Null_Address then
                  Header_Of (Pool.First_Used_Block).Dealloc_Traceback :=
                    To_Traceback (null);
               end if;

            else
               Header_Of (Previous).Next := Header.Next;

               if Header.Next /= System.Null_Address then
                  Header_Of
                    (Header.Next).Dealloc_Traceback := To_Address (Previous);
               end if;
            end if;

            --  Update the Alloc_Traceback Frees/Total_Frees members
            --  (if present)

            if Header.Alloc_Traceback /= null then
               Header.Alloc_Traceback.Frees :=
                 Header.Alloc_Traceback.Frees + 1;
               Header.Alloc_Traceback.Total_Frees :=
                 Header.Alloc_Traceback.Total_Frees +
                   Byte_Count (Header.Block_Size);
            end if;

            Pool.Free_Count := Pool.Free_Count + 1;

            --  Update the header

            Header.all :=
              (Allocation_Address => Header.Allocation_Address,
               Alloc_Traceback    => Header.Alloc_Traceback,
               Dealloc_Traceback  => To_Traceback
                 (Find_Or_Create_Traceback
                      (Pool, Dealloc,
                       Header.Block_Size,
                       Deallocate_Label'Address,
                       Code_Address_For_Deallocate_End)),
               Next               => System.Null_Address,
               Block_Size         => -Header.Block_Size);

            if Pool.Reset_Content_On_Free then
               Set_Dead_Beef (Storage_Address, -Header.Block_Size);
            end if;

            Pool.Logically_Deallocated :=
              Pool.Logically_Deallocated + Byte_Count (-Header.Block_Size);

            --  Link this free block with the others (at the end of the list,
            --  so that we can start releasing the older blocks first later on)

            if Pool.First_Free_Block = System.Null_Address then
               Pool.First_Free_Block := Storage_Address;
               Pool.Last_Free_Block := Storage_Address;

            else
               Header_Of (Pool.Last_Free_Block).Next := Storage_Address;
               Pool.Last_Free_Block := Storage_Address;
            end if;

            --  Do not physically release the memory here, but in Alloc.
            --  See comment there for details.
         end if;
      end;

      if not Valid then
         if Storage_Address = System.Null_Address then
            if Pool.Raise_Exceptions and then
              Size_In_Storage_Elements /= Storage_Count'Last
            then
               raise Freeing_Not_Allocated_Storage;
            else
               Put (Output_File (Pool),
                    "error: Freeing Null_Address, at ");
               Put_Line (Output_File (Pool), Pool.Stack_Trace_Depth, null,
                         Deallocate_Label'Address,
                         Code_Address_For_Deallocate_End);
               return;
            end if;
         end if;

         if Allow_Unhandled_Memory
           and then not Is_Handled (Storage_Address)
         then
            System.CRTL.free (Storage_Address);
            return;
         end if;

         if Pool.Raise_Exceptions
           and then Size_In_Storage_Elements /= Storage_Count'Last
         then
            raise Freeing_Not_Allocated_Storage;
         else
            Put (Output_File (Pool),
                 "error: Freeing not allocated storage, at ");
            Put_Line (Output_File (Pool), Pool.Stack_Trace_Depth, null,
                      Deallocate_Label'Address,
                      Code_Address_For_Deallocate_End);
         end if;

      elsif Header_Block_Size_Was_Less_Than_0 then
         if Pool.Raise_Exceptions then
            raise Freeing_Deallocated_Storage;
         else
            Put (Output_File (Pool),
                 "error: Freeing already deallocated storage, at ");
            Put_Line (Output_File (Pool), Pool.Stack_Trace_Depth, null,
                      Deallocate_Label'Address,
                      Code_Address_For_Deallocate_End);
            Print_Traceback (Output_File (Pool),
                             "   Memory already deallocated at ",
                            To_Traceback (Header.Dealloc_Traceback));
            Print_Traceback (Output_File (Pool), "   Memory was allocated at ",
                             Header.Alloc_Traceback);
         end if;
      end if;
   end Deallocate;

   --------------------
   -- Deallocate_End --
   --------------------

   --  DO NOT MOVE, this must be right after Deallocate

   --  See Allocate_End

   --  This is making assumptions about code order that may be invalid ???

   procedure Deallocate_End is
   begin
      <<Deallocate_End_Label>>
      Code_Address_For_Deallocate_End := Deallocate_End_Label'Address;
   end Deallocate_End;

   -----------------
   -- Dereference --
   -----------------

   procedure Dereference
     (Pool                     : in out Debug_Pool;
      Storage_Address          : Address;
      Size_In_Storage_Elements : Storage_Count;
      Alignment                : Storage_Count)
   is
      pragma Unreferenced (Alignment, Size_In_Storage_Elements);

      Valid   : constant Boolean := Is_Valid (Storage_Address);
      Header  : Allocation_Header_Access;

   begin
      --  Locking policy: we do not do any locking in this procedure. The
      --  tables are only read, not written to, and although a problem might
      --  appear if someone else is modifying the tables at the same time, this
      --  race condition is not intended to be detected by this storage_pool (a
      --  now invalid pointer would appear as valid). Instead, we prefer
      --  optimum performance for dereferences.

      <<Dereference_Label>>

      if not Valid then
         if Pool.Raise_Exceptions then
            raise Accessing_Not_Allocated_Storage;
         else
            Put (Output_File (Pool),
                 "error: Accessing not allocated storage, at ");
            Put_Line (Output_File (Pool), Pool.Stack_Trace_Depth, null,
                      Dereference_Label'Address,
                      Code_Address_For_Dereference_End);
         end if;

      else
         Header := Header_Of (Storage_Address);

         if Header.Block_Size < 0 then
            if Pool.Raise_Exceptions then
               raise Accessing_Deallocated_Storage;
            else
               Put (Output_File (Pool),
                    "error: Accessing deallocated storage, at ");
               Put_Line
                 (Output_File (Pool), Pool.Stack_Trace_Depth, null,
                  Dereference_Label'Address,
                  Code_Address_For_Dereference_End);
               Print_Traceback (Output_File (Pool), "  First deallocation at ",
                                To_Traceback (Header.Dealloc_Traceback));
               Print_Traceback (Output_File (Pool), "  Initial allocation at ",
                                Header.Alloc_Traceback);
            end if;
         end if;
      end if;
   end Dereference;

   ---------------------
   -- Dereference_End --
   ---------------------

   --  DO NOT MOVE: this must be right after Dereference

   --  See Allocate_End

   --  This is making assumptions about code order that may be invalid ???

   procedure Dereference_End is
   begin
      <<Dereference_End_Label>>
      Code_Address_For_Dereference_End := Dereference_End_Label'Address;
   end Dereference_End;

   ----------------
   -- Print_Info --
   ----------------

   procedure Print_Info
     (Pool          : Debug_Pool;
      Cumulate      : Boolean := False;
      Display_Slots : Boolean := False;
      Display_Leaks : Boolean := False)
   is
      package Backtrace_Htable_Cumulate is new GNAT.HTable.Static_HTable
        (Header_Num => Header,
         Element    => Traceback_Htable_Elem,
         Elmt_Ptr   => Traceback_Htable_Elem_Ptr,
         Null_Ptr   => null,
         Set_Next   => Set_Next,
         Next       => Next,
         Key        => Tracebacks_Array_Access,
         Get_Key    => Get_Key,
         Hash       => Hash,
         Equal      => Equal);
      --  This needs a comment ??? probably some of the ones below do too???

      Current : System.Address;
      Data    : Traceback_Htable_Elem_Ptr;
      Elem    : Traceback_Htable_Elem_Ptr;
      Header  : Allocation_Header_Access;
      K       : Traceback_Kind;

   begin
      Put_Line
        ("Total allocated bytes : " &
         Byte_Count'Image (Pool.Allocated));

      Put_Line
        ("Total logically deallocated bytes : " &
         Byte_Count'Image (Pool.Logically_Deallocated));

      Put_Line
        ("Total physically deallocated bytes : " &
         Byte_Count'Image (Pool.Physically_Deallocated));

      if Pool.Marked_Blocks_Deallocated then
         Put_Line ("Marked blocks were physically deallocated. This is");
         Put_Line ("potentially dangerous, and you might want to run");
         Put_Line ("again with a lower value of Minimum_To_Free");
      end if;

      Put_Line
        ("Current Water Mark: " &
         Byte_Count'Image (Pool.Current_Water_Mark));

      Put_Line
        ("High Water Mark: " &
          Byte_Count'Image (Pool.High_Water));

      Put_Line ("");

      if Display_Slots then
         Data := Backtrace_Htable.Get_First;
         while Data /= null loop
            if Data.Kind in Alloc .. Dealloc then
               Elem :=
                 new Traceback_Htable_Elem'
                       (Traceback => new Tracebacks_Array'(Data.Traceback.all),
                        Count       => Data.Count,
                        Kind        => Data.Kind,
                        Total       => Data.Total,
                        Frees       => Data.Frees,
                        Total_Frees => Data.Total_Frees,
                        Next        => null);
               Backtrace_Htable_Cumulate.Set (Elem);

               if Cumulate then
                  K := (if Data.Kind = Alloc then Indirect_Alloc
                                             else Indirect_Dealloc);

                  --  Propagate the direct call to all its parents

                  for T in Data.Traceback'First + 1 .. Data.Traceback'Last loop
                     Elem := Backtrace_Htable_Cumulate.Get
                       (Data.Traceback
                          (T .. Data.Traceback'Last)'Unrestricted_Access);

                     --  If not, insert it

                     if Elem = null then
                        Elem :=
                          new Traceback_Htable_Elem'
                                (Traceback =>
                                   new Tracebacks_Array'
                                         (Data.Traceback
                                           (T .. Data.Traceback'Last)),
                                 Count       => Data.Count,
                                 Kind        => K,
                                 Total       => Data.Total,
                                 Frees       => Data.Frees,
                                 Total_Frees => Data.Total_Frees,
                                 Next        => null);
                        Backtrace_Htable_Cumulate.Set (Elem);

                        --  Properly take into account that the subprograms
                        --  indirectly called might be doing either allocations
                        --  or deallocations. This needs to be reflected in the
                        --  counts.

                     else
                        Elem.Count := Elem.Count + Data.Count;

                        if K = Elem.Kind then
                           Elem.Total := Elem.Total + Data.Total;

                        elsif Elem.Total > Data.Total then
                           Elem.Total := Elem.Total - Data.Total;

                        else
                           Elem.Kind  := K;
                           Elem.Total := Data.Total - Elem.Total;
                        end if;
                     end if;
                  end loop;
               end if;

               Data := Backtrace_Htable.Get_Next;
            end if;
         end loop;

         Put_Line ("List of allocations/deallocations: ");

         Data := Backtrace_Htable_Cumulate.Get_First;
         while Data /= null loop
            case Data.Kind is
               when Alloc            => Put ("alloc (count:");
               when Indirect_Alloc   => Put ("indirect alloc (count:");
               when Dealloc          => Put ("free  (count:");
               when Indirect_Dealloc => Put ("indirect free  (count:");
            end case;

            Put (Natural'Image (Data.Count) & ", total:" &
                 Byte_Count'Image (Data.Total) & ") ");

            for T in Data.Traceback'Range loop
               Put (Image_C (PC_For (Data.Traceback (T))) & ' ');
            end loop;

            Put_Line ("");

            Data := Backtrace_Htable_Cumulate.Get_Next;
         end loop;

         Backtrace_Htable_Cumulate.Reset;
      end if;

      if Display_Leaks then
         Put_Line ("");
         Put_Line ("List of not deallocated blocks:");

         --  Do not try to group the blocks with the same stack traces
         --  together. This is done by the gnatmem output.

         Current := Pool.First_Used_Block;
         while Current /= System.Null_Address loop
            Header := Header_Of (Current);

            Put ("Size: " & Storage_Count'Image (Header.Block_Size) & " at: ");

            if Header.Alloc_Traceback /= null then
               for T in Header.Alloc_Traceback.Traceback'Range loop
                  Put (Image_C
                       (PC_For (Header.Alloc_Traceback.Traceback (T))) & ' ');
               end loop;
            end if;

            Put_Line ("");
            Current := Header.Next;
         end loop;
      end if;
   end Print_Info;

   ----------
   -- Dump --
   ----------

   procedure Dump
     (Pool   : Debug_Pool;
      Size   : Positive;
      Report : Report_Type := All_Reports)
   is
      procedure Do_Report (Sort : Report_Type);
      --  Do a specific type of report

      ---------------
      -- Do_Report --
      ---------------

      procedure Do_Report (Sort : Report_Type) is
         Elem        : Traceback_Htable_Elem_Ptr;
         Bigger      : Boolean;
         Grand_Total : Float;

         Max  : array (1 .. Size) of Traceback_Htable_Elem_Ptr :=
           (others => null);
         --  Sorted array for the biggest memory users

         Allocated_In_Pool : Byte_Count;
         --  safe thread Pool.Allocated

         Elem_Safe : Traceback_Htable_Elem;
         --  safe thread current elem.all;

         Max_M_Safe : Traceback_Htable_Elem;
         --  safe thread Max(M).all

      begin
         Put_Line ("");

         case Sort is
            when All_Reports
               | Memory_Usage
            =>
               Put_Line (Size'Img & " biggest memory users at this time:");
               Put_Line ("Results include bytes and chunks still allocated");
               Grand_Total := Float (Pool.Current_Water_Mark);

            when Allocations_Count =>
               Put_Line (Size'Img & " biggest number of live allocations:");
               Put_Line ("Results include bytes and chunks still allocated");
               Grand_Total := Float (Pool.Current_Water_Mark);

            when Sort_Total_Allocs =>
               Put_Line (Size'Img & " biggest number of allocations:");
               Put_Line ("Results include total bytes and chunks allocated,");
               Put_Line ("even if no longer allocated - Deallocations are"
                         & " ignored");

               declare
                  Lock : Scope_Lock;
                  pragma Unreferenced (Lock);
               begin
                  Allocated_In_Pool := Pool.Allocated;
               end;

               Grand_Total := Float (Allocated_In_Pool);

            when Marked_Blocks =>
               Put_Line ("Special blocks marked by Mark_Traceback");
               Grand_Total := 0.0;
         end case;

         declare
            Lock : Scope_Lock;
            pragma Unreferenced (Lock);
         begin
            Elem := Backtrace_Htable.Get_First;
         end;

         while Elem /= null loop
            declare
               Lock : Scope_Lock;
               pragma Unreferenced (Lock);
            begin
               Elem_Safe := Elem.all;
            end;

            --  Handle only alloc elememts
            if Elem_Safe.Kind = Alloc then
               --  Ignore small blocks (depending on the sorting criteria) to
               --  gain speed.

               if (Sort = Memory_Usage
                    and then Elem_Safe.Total - Elem_Safe.Total_Frees >= 1_000)
                 or else (Sort = Allocations_Count
                           and then Elem_Safe.Count - Elem_Safe.Frees >= 1)
                 or else (Sort = Sort_Total_Allocs
                           and then Elem_Safe.Count > 1)
                 or else (Sort = Marked_Blocks
                           and then Elem_Safe.Total = 0)
               then
                  if Sort = Marked_Blocks then
                     Grand_Total := Grand_Total + Float (Elem_Safe.Count);
                  end if;

                  for M in Max'Range loop
                     Bigger := Max (M) = null;
                     if not Bigger then
                        declare
                           Lock : Scope_Lock;
                           pragma Unreferenced (Lock);
                        begin
                           Max_M_Safe := Max (M).all;
                        end;

                        case Sort is
                           when All_Reports
                              | Memory_Usage
                           =>
                              Bigger :=
                                Max_M_Safe.Total - Max_M_Safe.Total_Frees
                                  < Elem_Safe.Total - Elem_Safe.Total_Frees;

                           when Allocations_Count =>
                              Bigger :=
                                Max_M_Safe.Count - Max_M_Safe.Frees
                                  < Elem_Safe.Count - Elem_Safe.Frees;

                           when Marked_Blocks
                              | Sort_Total_Allocs
                           =>
                              Bigger := Max_M_Safe.Count < Elem_Safe.Count;
                        end case;
                     end if;

                     if Bigger then
                        Max (M + 1 .. Max'Last) := Max (M .. Max'Last - 1);
                        Max (M) := Elem;
                        exit;
                     end if;
                  end loop;
               end if;
            end if;

            declare
               Lock : Scope_Lock;
               pragma Unreferenced (Lock);
            begin
               Elem := Backtrace_Htable.Get_Next;
            end;
         end loop;

         if Grand_Total = 0.0 then
            Grand_Total := 1.0;
         end if;

         for M in Max'Range loop
            exit when Max (M) = null;
            declare
               type Percent is delta 0.1 range 0.0 .. 100.0;

               P     : Percent;
               Total : Byte_Count;

            begin
               declare
                  Lock : Scope_Lock;
                  pragma Unreferenced (Lock);
               begin
                  Max_M_Safe := Max (M).all;
               end;

               case Sort is
                  when All_Reports
                     | Allocations_Count
                     | Memory_Usage
                  =>
                     Total := Max_M_Safe.Total - Max_M_Safe.Total_Frees;

                  when Sort_Total_Allocs =>
                     Total := Max_M_Safe.Total;

                  when Marked_Blocks =>
                     Total := Byte_Count (Max_M_Safe.Count);
               end case;

               declare
                  Normalized_Total : constant Float := Float (Total);
                  --  In multi tasking configuration, memory deallocations
                  --  during Do_Report processing can lead to Total >
                  --  Grand_Total. As Percent requires Total <= Grand_Total

               begin
                  if Normalized_Total > Grand_Total then
                     P := 100.0;
                  else
                     P := Percent (100.0 * Normalized_Total / Grand_Total);
                  end if;
               end;

               case Sort is
                  when All_Reports
                     | Allocations_Count
                     | Memory_Usage
                  =>
                     declare
                        Count : constant Natural :=
                          Max_M_Safe.Count - Max_M_Safe.Frees;
                     begin
                        Put (P'Img & "%:" & Total'Img & " bytes in"
                             & Count'Img & " chunks at");
                     end;

                  when Sort_Total_Allocs =>
                     Put (P'Img & "%:" & Total'Img & " bytes in"
                          & Max_M_Safe.Count'Img & " chunks at");

                  when Marked_Blocks =>
                     Put (P'Img & "%:"
                          & Max_M_Safe.Count'Img & " chunks /"
                          & Integer (Grand_Total)'Img & " at");
               end case;
            end;

            for J in Max (M).Traceback'Range loop
               Put (" " & Image_C (PC_For (Max (M).Traceback (J))));
            end loop;

            Put_Line ("");
         end loop;
      end Do_Report;

      --  Local variables

      Total_Freed : Byte_Count;
      --  safe thread pool logically & physically deallocated

      Traceback_Elements_Allocated : Byte_Count;
      --  safe thread Traceback_Count

      Validity_Elements_Allocated : Byte_Count;
      --  safe thread Validity_Count

      Ada_Allocs_Bytes : Byte_Count;
      --  safe thread pool Allocated

      Ada_Allocs_Chunks : Byte_Count;
      --  safe thread pool Alloc_Count

      Ada_Free_Chunks : Byte_Count;
      --  safe thread pool Free_Count

   --  Start of processing for Dump

   begin
      declare
         Lock : Scope_Lock;
         pragma Unreferenced (Lock);
      begin
         Total_Freed :=
           Pool.Logically_Deallocated + Pool.Physically_Deallocated;
         Traceback_Elements_Allocated := Traceback_Count;
         Validity_Elements_Allocated := Validity_Count;
         Ada_Allocs_Bytes := Pool.Allocated;
         Ada_Allocs_Chunks := Pool.Alloc_Count;
         Ada_Free_Chunks := Pool.Free_Count;
      end;

      Put_Line
        ("Traceback elements allocated: " & Traceback_Elements_Allocated'Img);
      Put_Line
        ("Validity elements allocated: " & Validity_Elements_Allocated'Img);
      Put_Line ("");

      Put_Line ("Ada Allocs:" & Ada_Allocs_Bytes'Img
                & " bytes in" & Ada_Allocs_Chunks'Img & " chunks");
      Put_Line ("Ada Free:" & Total_Freed'Img & " bytes in" &
                  Ada_Free_Chunks'Img
                & " chunks");
      Put_Line ("Ada Current watermark: "
                & Byte_Count'Image (Pool.Current_Water_Mark)
                & " in" & Byte_Count'Image (Ada_Allocs_Chunks -
                    Ada_Free_Chunks) & " chunks");
      Put_Line ("Ada High watermark: " & Pool.High_Water_Mark'Img);

      case Report is
         when All_Reports =>
            for Sort in Report_Type loop
               if Sort /= All_Reports then
                  Do_Report (Sort);
               end if;
            end loop;

         when others =>
            Do_Report (Report);
      end case;
   end Dump;

   -----------------
   -- Dump_Stdout --
   -----------------

   procedure Dump_Stdout
     (Pool   : Debug_Pool;
      Size   : Positive;
      Report : Report_Type := All_Reports)
   is
      procedure Internal is new Dump
        (Put_Line => Stdout_Put_Line,
         Put      => Stdout_Put);

   --  Start of processing for Dump_Stdout

   begin
      Internal (Pool, Size, Report);
   end Dump_Stdout;

   -----------
   -- Reset --
   -----------

   procedure Reset is
      Elem : Traceback_Htable_Elem_Ptr;
      Lock : Scope_Lock;
      pragma Unreferenced (Lock);
   begin
      Elem := Backtrace_Htable.Get_First;
      while Elem /= null loop
         Elem.Count := 0;
         Elem.Frees := 0;
         Elem.Total := 0;
         Elem.Total_Frees := 0;
         Elem := Backtrace_Htable.Get_Next;
      end loop;
   end Reset;

   ------------------
   -- Storage_Size --
   ------------------

   function Storage_Size (Pool : Debug_Pool) return Storage_Count is
      pragma Unreferenced (Pool);
   begin
      return Storage_Count'Last;
   end Storage_Size;

   ---------------------
   -- High_Water_Mark --
   ---------------------

   function High_Water_Mark (Pool : Debug_Pool) return Byte_Count is
      Lock : Scope_Lock;
      pragma Unreferenced (Lock);
   begin
      return Pool.High_Water;
   end High_Water_Mark;

   ------------------------
   -- Current_Water_Mark --
   ------------------------

   function Current_Water_Mark (Pool : Debug_Pool) return Byte_Count is
      Lock : Scope_Lock;
      pragma Unreferenced (Lock);
   begin
      return Pool.Allocated - Pool.Logically_Deallocated -
        Pool.Physically_Deallocated;
   end Current_Water_Mark;

   ------------------------------
   -- System_Memory_Debug_Pool --
   ------------------------------

   procedure System_Memory_Debug_Pool
     (Has_Unhandled_Memory : Boolean := True)
   is
      Lock : Scope_Lock;
      pragma Unreferenced (Lock);
   begin
      System_Memory_Debug_Pool_Enabled := True;
      Allow_Unhandled_Memory := Has_Unhandled_Memory;
   end System_Memory_Debug_Pool;

   ---------------
   -- Configure --
   ---------------

   procedure Configure
     (Pool                           : in out Debug_Pool;
      Stack_Trace_Depth              : Natural := Default_Stack_Trace_Depth;
      Maximum_Logically_Freed_Memory : SSC     := Default_Max_Freed;
      Minimum_To_Free                : SSC     := Default_Min_Freed;
      Reset_Content_On_Free          : Boolean := Default_Reset_Content;
      Raise_Exceptions               : Boolean := Default_Raise_Exceptions;
      Advanced_Scanning              : Boolean := Default_Advanced_Scanning;
      Errors_To_Stdout               : Boolean := Default_Errors_To_Stdout;
      Low_Level_Traces               : Boolean := Default_Low_Level_Traces)
   is
      Lock : Scope_Lock;
      pragma Unreferenced (Lock);
   begin
      Pool.Stack_Trace_Depth              := Stack_Trace_Depth;
      Pool.Maximum_Logically_Freed_Memory := Maximum_Logically_Freed_Memory;
      Pool.Reset_Content_On_Free          := Reset_Content_On_Free;
      Pool.Raise_Exceptions               := Raise_Exceptions;
      Pool.Minimum_To_Free                := Minimum_To_Free;
      Pool.Advanced_Scanning              := Advanced_Scanning;
      Pool.Errors_To_Stdout               := Errors_To_Stdout;
      Pool.Low_Level_Traces               := Low_Level_Traces;
   end Configure;

   ----------------
   -- Print_Pool --
   ----------------

   procedure Print_Pool (A : System.Address) is
      Storage : constant Address := A;
      Valid   : constant Boolean := Is_Valid (Storage);
      Header  : Allocation_Header_Access;

   begin
      --  We might get Null_Address if the call from gdb was done incorrectly.
      --  For instance, doing a "print_pool(my_var)" passes 0x0, instead of
      --  passing the value of my_var.

      if A = System.Null_Address then
         Put_Line
            (Standard_Output, "Memory not under control of the storage pool");
         return;
      end if;

      if not Valid then
         Put_Line
            (Standard_Output, "Memory not under control of the storage pool");

      else
         Header := Header_Of (Storage);
         Print_Address (Standard_Output, A);
         Put_Line (Standard_Output, " allocated at:");
         Print_Traceback (Standard_Output, "", Header.Alloc_Traceback);

         if To_Traceback (Header.Dealloc_Traceback) /= null then
            Print_Address (Standard_Output, A);
            Put_Line (Standard_Output,
                      " logically freed memory, deallocated at:");
            Print_Traceback (Standard_Output, "",
                             To_Traceback (Header.Dealloc_Traceback));
         end if;
      end if;
   end Print_Pool;

   -----------------------
   -- Print_Info_Stdout --
   -----------------------

   procedure Print_Info_Stdout
     (Pool          : Debug_Pool;
      Cumulate      : Boolean := False;
      Display_Slots : Boolean := False;
      Display_Leaks : Boolean := False)
   is
      procedure Internal is new Print_Info
        (Put_Line => Stdout_Put_Line,
         Put      => Stdout_Put);

   --  Start of processing for Print_Info_Stdout

   begin
      Internal (Pool, Cumulate, Display_Slots, Display_Leaks);
   end Print_Info_Stdout;

   ------------------
   -- Dump_Gnatmem --
   ------------------

   procedure Dump_Gnatmem (Pool : Debug_Pool; File_Name : String) is
      type File_Ptr is new System.Address;

      function fopen (Path : String; Mode : String) return File_Ptr;
      pragma Import (C, fopen);

      procedure fwrite
        (Ptr    : System.Address;
         Size   : size_t;
         Nmemb  : size_t;
         Stream : File_Ptr);

      procedure fwrite
        (Str    : String;
         Size   : size_t;
         Nmemb  : size_t;
         Stream : File_Ptr);
      pragma Import (C, fwrite);

      procedure fputc (C : Integer; Stream : File_Ptr);
      pragma Import (C, fputc);

      procedure fclose (Stream : File_Ptr);
      pragma Import (C, fclose);

      Address_Size : constant size_t :=
                       System.Address'Max_Size_In_Storage_Elements;
      --  Size in bytes of a pointer

      File        : File_Ptr;
      Current     : System.Address;
      Header      : Allocation_Header_Access;
      Actual_Size : size_t;
      Num_Calls   : Integer;
      Tracebk     : Tracebacks_Array_Access;
      Dummy_Time  : Duration := 1.0;

   begin
      File := fopen (File_Name & ASCII.NUL, "wb" & ASCII.NUL);
      fwrite ("GMEM DUMP" & ASCII.LF, 10, 1, File);

      fwrite
        (Ptr    => Dummy_Time'Address,
         Size   => Duration'Max_Size_In_Storage_Elements,
         Nmemb  => 1,
         Stream => File);

      --  List of not deallocated blocks (see Print_Info)

      Current := Pool.First_Used_Block;
      while Current /= System.Null_Address loop
         Header := Header_Of (Current);

         Actual_Size := size_t (Header.Block_Size);

         if Header.Alloc_Traceback /= null then
            Tracebk   := Header.Alloc_Traceback.Traceback;
            Num_Calls := Tracebk'Length;

            --  (Code taken from memtrack.adb in GNAT's sources)

            --  Logs allocation call using the format:

            --  'A' <mem addr> <size chunk> <len backtrace> <addr1> ... <addrn>

            fputc (Character'Pos ('A'), File);
            fwrite (Current'Address, Address_Size, 1, File);

            fwrite
              (Ptr    => Actual_Size'Address,
               Size   => size_t'Max_Size_In_Storage_Elements,
               Nmemb  => 1,
               Stream => File);

            fwrite
              (Ptr    => Dummy_Time'Address,
               Size   => Duration'Max_Size_In_Storage_Elements,
               Nmemb  => 1,
               Stream => File);

            fwrite
              (Ptr    => Num_Calls'Address,
               Size   => Integer'Max_Size_In_Storage_Elements,
               Nmemb  => 1,
               Stream => File);

            for J in Tracebk'First .. Tracebk'First + Num_Calls - 1 loop
               declare
                  Ptr : System.Address := PC_For (Tracebk (J));
               begin
                  fwrite (Ptr'Address, Address_Size, 1, File);
               end;
            end loop;
         end if;

         Current := Header.Next;
      end loop;

      fclose (File);
   end Dump_Gnatmem;

   ----------------
   -- Stdout_Put --
   ----------------

   procedure Stdout_Put (S : String) is
   begin
      Put (Standard_Output, S);
   end Stdout_Put;

   ---------------------
   -- Stdout_Put_Line --
   ---------------------

   procedure Stdout_Put_Line (S : String) is
   begin
      Put_Line (Standard_Output, S);
   end Stdout_Put_Line;

--  Package initialization

begin
   Allocate_End;
   Deallocate_End;
   Dereference_End;
end GNAT.Debug_Pools;
