|  | /* do not edit automatically generated by mc from SysStorage.  */ | 
|  | /* SysStorage.mod provides dynamic allocation for the system components. | 
|  |  | 
|  | Copyright (C) 2001-2025 Free Software Foundation, Inc. | 
|  | Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>. | 
|  |  | 
|  | This file is part of GNU Modula-2. | 
|  |  | 
|  | GNU Modula-2 is free software; you can redistribute it and/or modify | 
|  | it under the terms of the GNU General Public License as published by | 
|  | the Free Software Foundation; either version 3, or (at your option) | 
|  | any later version. | 
|  |  | 
|  | GNU Modula-2 is distributed in the hope that it will be useful, but | 
|  | WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|  | General Public License for more details. | 
|  |  | 
|  | 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/>.  */ | 
|  |  | 
|  | #include "config.h" | 
|  | #include "system.h" | 
|  | #include <stdbool.h> | 
|  | #   if !defined (PROC_D) | 
|  | #      define PROC_D | 
|  | typedef void (*PROC_t) (void); | 
|  | typedef struct { PROC_t proc; } PROC; | 
|  | #   endif | 
|  |  | 
|  | #   if !defined (TRUE) | 
|  | #      define TRUE (1==1) | 
|  | #   endif | 
|  |  | 
|  | #   if !defined (FALSE) | 
|  | #      define FALSE (1==0) | 
|  | #   endif | 
|  |  | 
|  | #if defined(__cplusplus) | 
|  | #   undef NULL | 
|  | #   define NULL 0 | 
|  | #endif | 
|  | #define _SysStorage_C | 
|  |  | 
|  | #include "GSysStorage.h" | 
|  | #   include "Glibc.h" | 
|  | #   include "GDebug.h" | 
|  | #   include "GSYSTEM.h" | 
|  |  | 
|  | #   define enableDeallocation true | 
|  | #   define enableZero true | 
|  | #   define enableTrace false | 
|  | static unsigned int callno; | 
|  | static bool zero; | 
|  | static bool trace; | 
|  | extern "C" void SysStorage_ALLOCATE (void * *a, unsigned int size); | 
|  | extern "C" void SysStorage_DEALLOCATE (void * *a, unsigned int size); | 
|  |  | 
|  | /* | 
|  | REALLOCATE - attempts to reallocate storage. The address, | 
|  | a, should either be NIL in which case ALLOCATE | 
|  | is called, or alternatively it should have already | 
|  | been initialized by ALLOCATE. The allocated storage | 
|  | is resized accordingly. | 
|  | */ | 
|  |  | 
|  | extern "C" void SysStorage_REALLOCATE (void * *a, unsigned int size); | 
|  |  | 
|  | /* | 
|  | REALLOCATE - attempts to reallocate storage. The address, | 
|  | a, should either be NIL in which case ALLOCATE | 
|  | is called, or alternatively it should have already | 
|  | been initialized by ALLOCATE. The allocated storage | 
|  | is resized accordingly. | 
|  | */ | 
|  |  | 
|  | extern "C" bool SysStorage_Available (unsigned int size); | 
|  |  | 
|  | /* | 
|  | Init - initializes the heap.  This does nothing on a GNU/Linux system. | 
|  | But it remains here since it might be used in an embedded system. | 
|  | */ | 
|  |  | 
|  | extern "C" void SysStorage_Init (void); | 
|  |  | 
|  | extern "C" void SysStorage_ALLOCATE (void * *a, unsigned int size) | 
|  | { | 
|  | (*a) = libc_malloc (static_cast<size_t> (size)); | 
|  | if ((*a) == NULL) | 
|  | { | 
|  | Debug_Halt ((const char *) "out of memory error", 19, (const char *) "../../gcc/m2/gm2-libs/SysStorage.mod", 36, (const char *) "ALLOCATE", 8, 51); | 
|  | } | 
|  | if (enableTrace && trace) | 
|  | { | 
|  | libc_printf ((const char *) "<DEBUG-CALL> %d SysStorage.ALLOCATE (0x%x, %d bytes)\\n", 54, callno, (*a), size); | 
|  | libc_printf ((const char *) "<MEM-ALLOC> %ld %d\\n", 20, (*a), size); | 
|  | callno += 1; | 
|  | } | 
|  | } | 
|  |  | 
|  | extern "C" void SysStorage_DEALLOCATE (void * *a, unsigned int size) | 
|  | { | 
|  | if (enableTrace && trace) | 
|  | { | 
|  | libc_printf ((const char *) "<DEBUG-CALL> %d SysStorage.DEALLOCATE (0x%x, %d bytes)\\n", 56, callno, (*a), size); | 
|  | callno += 1; | 
|  | } | 
|  | if (enableZero && zero) | 
|  | { | 
|  | if (enableTrace && trace) | 
|  | { | 
|  | libc_printf ((const char *) "  memset (0x%x, 0, %d bytes)\\n", 30, (*a), size); | 
|  | } | 
|  | if ((libc_memset ((*a), 0, static_cast<size_t> (size))) != (*a)) | 
|  | { | 
|  | Debug_Halt ((const char *) "memset should have returned the first parameter", 47, (const char *) "../../gcc/m2/gm2-libs/SysStorage.mod", 36, (const char *) "DEALLOCATE", 10, 78); | 
|  | } | 
|  | } | 
|  | if (enableDeallocation) | 
|  | { | 
|  | if (enableTrace && trace) | 
|  | { | 
|  | libc_printf ((const char *) "  free (0x%x)   %d bytes\\n", 26, (*a), size); | 
|  | libc_printf ((const char *) "<MEM-FREE> %ld %d\\n", 19, (*a), size); | 
|  | } | 
|  | libc_free ((*a)); | 
|  | } | 
|  | (*a) = NULL; | 
|  | } | 
|  |  | 
|  |  | 
|  | /* | 
|  | REALLOCATE - attempts to reallocate storage. The address, | 
|  | a, should either be NIL in which case ALLOCATE | 
|  | is called, or alternatively it should have already | 
|  | been initialized by ALLOCATE. The allocated storage | 
|  | is resized accordingly. | 
|  | */ | 
|  |  | 
|  | extern "C" void SysStorage_REALLOCATE (void * *a, unsigned int size) | 
|  | { | 
|  | if ((*a) == NULL) | 
|  | { | 
|  | SysStorage_ALLOCATE (a, size); | 
|  | } | 
|  | else | 
|  | { | 
|  | if (enableTrace && trace) | 
|  | { | 
|  | libc_printf ((const char *) "<DEBUG-CALL> %d SysStorage.REALLOCATE (0x%x, %d bytes)\\n", 56, callno, (*a), size); | 
|  | callno += 1; | 
|  | } | 
|  | if (enableTrace && trace) | 
|  | { | 
|  | libc_printf ((const char *) "  realloc (0x%x, %d bytes)  ->  ", 32, (*a), size); | 
|  | libc_printf ((const char *) "<MEM-FREE> %ld %d\\n", 19, (*a), size); | 
|  | } | 
|  | (*a) = libc_realloc ((*a), static_cast<size_t> (size)); | 
|  | if ((*a) == NULL) | 
|  | { | 
|  | Debug_Halt ((const char *) "out of memory error", 19, (const char *) "../../gcc/m2/gm2-libs/SysStorage.mod", 36, (const char *) "REALLOCATE", 10, 122); | 
|  | } | 
|  | if (enableTrace && trace) | 
|  | { | 
|  | libc_printf ((const char *) "<MEM-ALLOC> %ld %d\\n", 20, (*a), size); | 
|  | libc_printf ((const char *) "  0x%x  %d bytes\\n", 18, (*a), size); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | /* | 
|  | REALLOCATE - attempts to reallocate storage. The address, | 
|  | a, should either be NIL in which case ALLOCATE | 
|  | is called, or alternatively it should have already | 
|  | been initialized by ALLOCATE. The allocated storage | 
|  | is resized accordingly. | 
|  | */ | 
|  |  | 
|  | extern "C" bool SysStorage_Available (unsigned int size) | 
|  | { | 
|  | void * a; | 
|  |  | 
|  | if (enableTrace && trace) | 
|  | { | 
|  | libc_printf ((const char *) "<DEBUG-CALL> %d SysStorage.Available (%d bytes)\\n", 49, callno, size); | 
|  | callno += 1; | 
|  | } | 
|  | a = libc_malloc (static_cast<size_t> (size)); | 
|  | if (a == NULL) | 
|  | { | 
|  | if (enableTrace && trace) | 
|  | { | 
|  | libc_printf ((const char *) "   no\\n", 7, size); | 
|  | } | 
|  | return false; | 
|  | } | 
|  | else | 
|  | { | 
|  | if (enableTrace && trace) | 
|  | { | 
|  | libc_printf ((const char *) "   yes\\n", 8, size); | 
|  | } | 
|  | libc_free (a); | 
|  | return true; | 
|  | } | 
|  | /* static analysis guarentees a RETURN statement will be used before here.  */ | 
|  | __builtin_unreachable (); | 
|  | } | 
|  |  | 
|  |  | 
|  | /* | 
|  | Init - initializes the heap.  This does nothing on a GNU/Linux system. | 
|  | But it remains here since it might be used in an embedded system. | 
|  | */ | 
|  |  | 
|  | extern "C" void SysStorage_Init (void) | 
|  | { | 
|  | } | 
|  |  | 
|  | extern "C" void _M2_SysStorage_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[]) | 
|  | { | 
|  | callno = 0; | 
|  | if (enableTrace) | 
|  | { | 
|  | trace = (libc_getenv (const_cast<void*> (static_cast<const void*>("M2DEBUG_SYSSTORAGE_trace")))) != NULL; | 
|  | } | 
|  | else | 
|  | { | 
|  | trace = false; | 
|  | } | 
|  | if (enableZero) | 
|  | { | 
|  | zero = (libc_getenv (const_cast<void*> (static_cast<const void*>("M2DEBUG_SYSSTORAGE_zero")))) != NULL; | 
|  | } | 
|  | else | 
|  | { | 
|  | zero = false; | 
|  | } | 
|  | } | 
|  |  | 
|  | extern "C" void _M2_SysStorage_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[]) | 
|  | { | 
|  | } |