Re: [PATCH 0/5] newlib: m68k-atari-dev fixes.
<[email protected]> Wed, 03 Dec 2025 17:00:07 +0100
| Newsgroups | gmane.comp.lib.newlib |
|---|---|
| Message-ID | <1764777607237.7.40924@webmail-backend-production-5fcf5bc65c-hz6fx> |
Hi Jeff, I fixed the issue with macro names and did a git rebase, so here are a new set of patches that replaces the ones I previously mailed. And as previously mentioned, they will only affect the m68k-atari-elf target. /Mikael. Den måndag 17 november 2025 kl. 21:50:59 +01:00, skrev <[email protected]>: > Hi Jeff, > > The value is correct, but the name of the define is wrong. > SEC_1900_TO_1980 should be named SEC_1970_TO_1980. > And the same goes for SEC_1900_TO_MAX. > > I can fix it and mail another patch. > > Good catch by the way. > > /Mikael. > > > > > > Den måndag 17 november 2025 kl. 18:54:53 +01:00, skrev Jeff Johnston <[email protected]>: > > > Hi Micael, > > > > Sorry for the delay. There appears to be something wrong with your change to the seconds from 1900-1980 value. According to a simple web search, it should be close to the original value (10 digits) while the new updated value is only 9 digits. Can you explain this? > > > > -- Jeff J. > > > > > > > > > > On Mon, Nov 17, 2025 at 4:15 AM <<[email protected]>> wrote: > > > > > BUMP > > > > > > Also, I wrote wrong below: The only target affected whould be "m68k-atari-elf". > > > > > > /Mikael Hildenborg. > > > > > > > > > Den måndag 29 september 2025 kl. 08:57:59 +02:00, skrev <<[email protected]>>: > > > > > > > Collection of bugfixes after feedback from community. > > > > Should only affect the target: m68k-atari-dev. > > > > > > > > Mikael Hildenborg (5): > > > > m68k-atari-elf: fixed wrong number of seconds between 1900 and 1980. > > > > m68k-atari-elf: changed stack and heap handling to mimic mintlib. > > > > m68k-atari-elf: updated readme > > > > m68k-atari-elf: proper setup of environment variables and program > > > > arguments. > > > > m68k-atari-elf: specs file declares environ as undefined. > > > > > > > > libgloss/m68k/atari/README | 26 +-- > > > > libgloss/m68k/atari/atari-crt0.S | 55 +----- > > > > libgloss/m68k/atari/atari-crti.S | 123 +++++++++---- > > > > libgloss/m68k/atari/atari-environ.c | 267 +++++++++++++++++++++++++++- > > > > libgloss/m68k/atari/atari-gettod.c | 2 +- > > > > libgloss/m68k/atari/atari-sbrk.c | 18 +- > > > > libgloss/m68k/atari/atari-tos.specs | 2 +- > > > > 7 files changed, 389 insertions(+), 104 deletions(-) > > > > > > > > -- > > > > 2.43.0 > > > > > > > > > > > >
0001-m68k-atari-elf-fixed-wrong-number-of-seconds-between.patch
(text/x-patch, 1.8 KB)
From 514b75fe92455ccaf82ee39b09d0e2766e9abba0 Mon Sep 17 00:00:00 2001 From: Mikael Hildenborg <[email protected]> Date: Sun, 10 Aug 2025 08:49:23 +0200 Subject: [PATCH 1/5] m68k-atari-elf: fixed wrong number of seconds between 1900 and 1980. --- libgloss/m68k/atari/atari-gettod.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libgloss/m68k/atari/atari-gettod.c b/libgloss/m68k/atari/atari-gettod.c index 5477916a2..c8227ae5e 100644 --- a/libgloss/m68k/atari/atari-gettod.c +++ b/libgloss/m68k/atari/atari-gettod.c @@ -14,8 +14,8 @@ The code below uses that limitation to simplify the code. */ -#define SEC_1900_TO_1980 2524521600 -#define SEC_1900_TO_MAX 0x7fffffff +#define SEC_1970_TO_1980 315529200 +#define SEC_1970_TO_MAX 0x7fffffff #define SECONDS_IN_A_DAY (24 * 60 * 60) #define SEC_JAN_AND_FEB ((31 + 29) * SECONDS_IN_A_DAY) // In a leap year #define SECONDS_IN_A_YEAR (365 * SECONDS_IN_A_DAY) @@ -59,7 +59,7 @@ int gettimeofday(struct timeval* tv, void* __tz) } // Add it all together - tv->tv_sec = (((((days * 24) + hour) * 60) + min) * 60) + sec + SEC_1900_TO_1980; + tv->tv_sec = (((((days * 24) + hour) * 60) + min) * 60) + sec + SEC_1970_TO_1980; tv->tv_usec = 0; } return 0; @@ -70,14 +70,14 @@ int settimeofday(const struct timeval* tv, const struct timezone* tz) // Support for timezone have been removed from linux glibc, so we just ignore it. if (tv != 0) { - if (tv->tv_sec < SEC_1900_TO_1980 || tv->tv_sec >= SEC_1900_TO_MAX) + if (tv->tv_sec < SEC_1970_TO_1980 || tv->tv_sec >= SEC_1970_TO_MAX) { // Outside the ranges we can handle. gem_error_to_errno(GEM_EBADRQ); return -1; } - time_t seconds = tv->tv_sec - SEC_1900_TO_1980; + time_t seconds = tv->tv_sec - SEC_1970_TO_1980; int year = 0; time_t ysec = SECONDS_IN_A_YEAR; do -- 2.43.0
0002-m68k-atari-elf-changed-stack-and-heap-handling-to-mi.patch
(text/x-patch, 3.9 KB)
From ec250d128e15d9bd601a149cc1269cadc22a8c71 Mon Sep 17 00:00:00 2001 From: Mikael Hildenborg <[email protected]> Date: Wed, 13 Aug 2025 18:15:34 +0200 Subject: [PATCH 2/5] m68k-atari-elf: changed stack and heap handling to mimic mintlib. --- libgloss/m68k/atari/atari-crti.S | 83 +++++++++++++++++++++----------- libgloss/m68k/atari/atari-sbrk.c | 18 +++++-- 2 files changed, 70 insertions(+), 31 deletions(-) diff --git a/libgloss/m68k/atari/atari-crti.S b/libgloss/m68k/atari/atari-crti.S index 5e4c13b0e..e11c51cba 100644 --- a/libgloss/m68k/atari/atari-crti.S +++ b/libgloss/m68k/atari/atari-crti.S @@ -8,14 +8,12 @@ #define _fini __libc_fini_array #endif - .equ DEFAULT_STACK, 2000 + .equ MINKEEP, 0x10000 .global _BasePage - .weak _STACK_SIZE - .weak _HEAP_SIZE + .weak _stksize .global _HeapPtr - .global _HeapBottom - .global _HeapTop + .global _heapbase .global _atari_4ba_at_prg_start .global __BSS_SEGMENT_END @@ -26,32 +24,62 @@ _init: move.l 4(a7),a0 move.l a0, _BasePage - | Init stack +/* + Init stack and heap. + The size of the stack and heap together is specified in _stksize. + The stack is set to point at the top of the reserved memory. + The heap is set to point at the bottom of the reserved memory. + Usage of _stksize (mintlib functionally compatible): + if _stksize is undefined, then all available memory is used. + if _stksize is 0, then MINKEEP memory is used. + if _stksize > 0 && < 4, then _stksize/4 of all memory is used. + if _stksize >= 4, then use that much memory. + if _stksize == -1, then all available memory is used. + if _stksize < -1, then use -_stksize memory. +*/ lea __BSS_SEGMENT_END, a2 - lea _STACK_SIZE, a1 + move.l a2, _heapbase + move.l a2, _HeapPtr + + move.l 4(a0), d1 | mem top + sub.l a2, d1 | free mem + lea _stksize, a1 cmpa.w #0, a1 - jeq default_stack_size - add.l (a1), a2 - jra stack_size_selected -default_stack_size: - lea DEFAULT_STACK(a2), a2 -stack_size_selected: - move.l a2, a7 + jeq stksize_selected + move.l (a1), d0 + jeq stksize_zero + jmi stksize_negative +stksize_positive: + moveq #4, d2 + cmp.l d2, d0 + jpl stksize_above_three +stksize_one_to_three: + lsr.l #2, d1 + move.l d1, d2 +1: + subq.w #1, d0 + jeq stksize_selected + add.l d2, d1 + jra 1b +stksize_zero: + move.l #MINKEEP, d1 + jra stksize_selected +stksize_negative: + not.l d0 + jeq stksize_selected | -1 + addq.l #1, d0 | d0 = -_stksize +stksize_above_three: + move.l d0, d1 +stksize_selected: - | Init heap - move.l a7, d0 - move.l d0, _HeapBottom - move.l d0, _HeapPtr - move.l 4(a0), _HeapTop + add.l a2, d1 + bclr #0, d1 | even address. + move.l d1, a7 - lea _HEAP_SIZE, a1 - cmpa.w #0, a1 - jeq heap_setup_done - add.l (a1), d0 - sub.l (a0), d0 | d0 is now the TPA size + sub.l a0, d1 | mem from basepage to top. - | Program do not want all memory, so we shrink it. - move.l d0, -(a7) + | Shrink mem. + move.l d1, -(a7) move.l a0, -(a7) clr.w -(a7) move.w #0x4a, -(a7) | Mshrink() @@ -84,7 +112,6 @@ heap_setup_done: .bss .lcomm _BasePage, 4 .lcomm _HeapPtr, 4 - .lcomm _HeapBottom, 4 - .lcomm _HeapTop, 4 + .lcomm _heapbase, 4 .lcomm _atari_4ba_at_prg_start, 4 .even \ No newline at end of file diff --git a/libgloss/m68k/atari/atari-sbrk.c b/libgloss/m68k/atari/atari-sbrk.c index 8839cc742..535395f3e 100644 --- a/libgloss/m68k/atari/atari-sbrk.c +++ b/libgloss/m68k/atari/atari-sbrk.c @@ -7,13 +7,25 @@ #include <_ansi.h> extern char *_HeapPtr; -extern char *_HeapBottom; -extern char *_HeapTop; +extern char *_heapbase; char *sbrk(int nbytes) { char *newheap = _HeapPtr + nbytes; - if (newheap > _HeapTop) + + /* + The user stack pointer is the top heap. + The behaviour is undefined if we are in supervisor mode. + But memory allocations in supervisor mode feels like a bad idea anyway. + */ + char *heaptop; + __asm__ volatile ( + "move.l %%a7, %0\n\t" + : "=g" (heaptop) + : + :); + + if (newheap > heaptop) { errno = ENOMEM; return ((char *)-1); -- 2.43.0
0003-m68k-atari-elf-updated-readme.patch
(text/x-patch, 2.2 KB)
From 72232188a99320237b1b5edeb96bb561835a646d Mon Sep 17 00:00:00 2001 From: Mikael Hildenborg <[email protected]> Date: Fri, 15 Aug 2025 17:31:13 +0200 Subject: [PATCH 3/5] m68k-atari-elf: updated readme --- libgloss/m68k/atari/README | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/libgloss/m68k/atari/README b/libgloss/m68k/atari/README index 24d2a6ea6..20283dd44 100644 --- a/libgloss/m68k/atari/README +++ b/libgloss/m68k/atari/README @@ -4,19 +4,19 @@ SPDX-License-Identifier: BSD-2-Clause Atari 16/32 bit TOS (not MINT) target. Target name: m68k-atari-elf. -Stack size: -The default stack size is set at 2000 bytes. -To change stack size, add the following line to your C/C++ code: -unsigned int _STACK_SIZE = *WANTED_STACK_SIZE*; -Where "*WANTED_STACK_SIZE*" is the size in bytes you want to allocate for stack space. -Do not use odd size! - -Heap size: -The default heap size is to use all available memory. -If you want to leave memory for other programs to use, then add the following line to your C/C++ code: -unsigned int _HEAP_SIZE = *WANTED_HEAP_SIZE*; -Where "*WANTED_HEAP_SIZE*" is the size in bytes you want to allocate for heap space. -Do not use odd size! +Stack and heap size: +The symbol: "_stksize" defines how much memory that is reserved for stack and heap using the following scheme: +1. If "_stksize" is undefined, then all available memory is reserved. +2. If `int _stksize = SIZE;` is defined anywhere in the code, then "SIZE" is used in this way: + * SIZE == 0: then MINKEEP (64KB) memory is reserved. + * SIZE == 1: then 1/4 of all memory is reserved. + * SIZE == 2: then 2/4 of all memory is reserved. + * SIZE == 3: then 3/4 of all memory is reserved. + * SIZE >= 4: then SIZE memory is reserved. + * SIZE == -1, then all available memory is reserved (for mintlib compatibillity). + * SIZE < -1, then -SIZE memory is reserved (for mintlib compatibillity). +The heap starts at the bottom of the shared memory and the stack starts at the top, and they grow towards eachother. +A safety check for memory allocations is done to make sure that memory is not allocated and overwriting the stack. Program base page: A pointer to the program base page is stored at: _BasePage -- 2.43.0
0004-m68k-atari-elf-proper-setup-of-environment-variables.patch
(text/x-patch, 11.9 KB)
From 7ff5870d9de04bcbb5f06026ed4a1b3c6b5124e0 Mon Sep 17 00:00:00 2001 From: Mikael Hildenborg <[email protected]> Date: Fri, 22 Aug 2025 08:13:39 +0200 Subject: [PATCH 4/5] m68k-atari-elf: proper setup of environment variables and program arguments. --- libgloss/m68k/atari/atari-crt0.S | 55 +----- libgloss/m68k/atari/atari-crti.S | 36 +++- libgloss/m68k/atari/atari-environ.c | 267 +++++++++++++++++++++++++++- 3 files changed, 302 insertions(+), 56 deletions(-) diff --git a/libgloss/m68k/atari/atari-crt0.S b/libgloss/m68k/atari/atari-crt0.S index 6d1bbd1d9..882be54b0 100644 --- a/libgloss/m68k/atari/atari-crt0.S +++ b/libgloss/m68k/atari/atari-crt0.S @@ -4,55 +4,20 @@ */ .global exit + .global _atari_argv | in atari-environ.c + .global _atari_argc | in atari-environ.c .section ".init" .global __call_main_with_argc_argv .type __call_main_with_argc_argv,#function __call_main_with_argc_argv: -/* - Need to implement "The Atari Extended Argument Specification". - Also, there is no guarantee that the command line is zero terminated. -*/ | this occurs after crtbegin.o have done all global constructors etc. - - move.l a7, a6 - moveq #0, d0 - moveq #0, d2 - movea.l _BasePage, a0 - lea 128(a0), a0 | add offset to the cmdline - lea _cmdline, a1 - move.b (a0)+, d2 | d2 contains number of bytes in command line (max 127) - beq.s 3f - clr.b (a1, d2.w) | end our decoded args with a zero. - bra.s 2f -1: - move.b (a0, d2.w), d1 - cmp.b #' ', d1 - bne.s 4f - moveq #0, d1 - lea 1(a1, d2.w), a2 - tst.b (a2) - beq.s 4f - move.l a2, -(a7) - addq.w #1, d0 -4: - move.b d1, (a1, d2.w) -2: - subq.w #1, d2 - bcc.s 1b - move.l a1, -(a7) - addq.w #1, d0 -3: - pea _procname | first argument is always the proc name. That we do not know... - addq.w #1, d0 - move.l a7, a5 - move.l a6, -(a7) | To know where to move it back again. - - move.l a5, -(a7) | argv - move.l d0, -(a7) | argc + | atari-crti.S have already set up _atari_argc, _atari_argv + move.l _atari_argv, -(a7) + move.l _atari_argc, -(a7) jsr main - move.l 8(a7), a7 | move it back. + addq.l #8, a7 move.l d0, -(a7) jsr exit | not expected to return illegal @@ -64,11 +29,3 @@ _exit: move.w d0, _program_return_code | crtend.o follows here with global destructors etc. - .data -_procname: - .asciz "yourapp.lol" - .even - - .bss - .lcomm _cmdline, 128 - .even diff --git a/libgloss/m68k/atari/atari-crti.S b/libgloss/m68k/atari/atari-crti.S index e11c51cba..caecacef0 100644 --- a/libgloss/m68k/atari/atari-crti.S +++ b/libgloss/m68k/atari/atari-crti.S @@ -15,6 +15,7 @@ .global _HeapPtr .global _heapbase .global _atari_4ba_at_prg_start + .global _atari_4be_at_prg_start .global __BSS_SEGMENT_END .section ".init" @@ -24,6 +25,21 @@ _init: move.l 4(a7),a0 move.l a0, _BasePage +/* + First do a quick jump into supervisor mode to get some needed pointers. +*/ + move.l #super_init, -(a7) + move.w #0x26, -(a7) + trap #14 + addq.l #6, a7 + +/* + Make an estimate for how much memory we need to reserve for environment and arguments. +*/ + jsr estimate_env_and_args_memory | in atari-environ.c + | d0 contains the number of bytes we need to reserve for environment and arguments. + move.l d0, d7 + /* Init stack and heap. The size of the stack and heap together is specified in _stksize. @@ -38,11 +54,14 @@ _init: if _stksize < -1, then use -_stksize memory. */ lea __BSS_SEGMENT_END, a2 + add.l d7, a2 | environment and arguments move.l a2, _heapbase move.l a2, _HeapPtr + move.l _BasePage, a0 move.l 4(a0), d1 | mem top sub.l a2, d1 | free mem + move.l d1, d6 lea _stksize, a1 cmpa.w #0, a1 jeq stksize_selected @@ -72,6 +91,13 @@ stksize_above_three: move.l d0, d1 stksize_selected: + | adjust for memory needed for environment and arguments + add.l d7, d1 + cmp.l d1, d6 + jpl 1f + move.l d6, d1 +1: + add.l a2, d1 bclr #0, d1 | even address. move.l d1, a7 @@ -94,12 +120,13 @@ stksize_selected: super_init: | Init stuff that needs supervisor mode set. move.l 0x4ba, _atari_4ba_at_prg_start + move.l 0x4be, _atari_4be_at_prg_start rts heap_setup_done: - move.l #super_init, -(a7) - move.w #0x26, -(a7) - trap #14 - addq.l #6, a7 + + pea __BSS_SEGMENT_END | storage space for environment and arguments + jsr setup_env_and_args | in atari-environ.c + | crtbegin.o follows here with global constructors etc. init. @@ -114,4 +141,5 @@ heap_setup_done: .lcomm _HeapPtr, 4 .lcomm _heapbase, 4 .lcomm _atari_4ba_at_prg_start, 4 + .lcomm _atari_4be_at_prg_start, 4 .even \ No newline at end of file diff --git a/libgloss/m68k/atari/atari-environ.c b/libgloss/m68k/atari/atari-environ.c index 3f4970733..5588c2885 100644 --- a/libgloss/m68k/atari/atari-environ.c +++ b/libgloss/m68k/atari/atari-environ.c @@ -3,6 +3,267 @@ SPDX-License-Identifier: BSD-2-Clause */ -// Should point to a list of global environment variables. -char *__env[1] = { 0 }; -char **environ = __env; \ No newline at end of file +#include "atari-gem_basepage.h" + +/* + The functions: + void setup_env_and_args(void *mem_ptr) + int estimate_env_and_args_memory(void) + are called from atari-crti.S and should be handled with care. +*/ + +extern char **environ; // setup_env_and_args will set this up. + +// Atari TOS do not supply any method of finding out the name of the application that is running. +// So we default a name here to have a proper arg1. +const char _proc_name[] = "_undefin.ed_"; + +extern const char* _atari_4be_at_prg_start; // Global environment +const char **_atari_argv; +int _atari_argc; + +// If storage_list is 0, then vars is only counted. +// If argv_arg is not 0, then the value of ARGV= is stored there if found. +int extract_env_vars(const char* env, const char** storage_list, const char** argv_arg) +{ + int num = 0; + if (env != 0) + { + // If we find a double null without a previous '=', then the string from the last var + // up to the double null must be discarded (aes bug). + while (env[0] != 0) // loop until double null (string beginning with null) + { + const char* cvar = env; + short found_equal = 0; + short len_since_equal = 0; + while (env[0] != 0) + { + if (found_equal != 0) {++len_since_equal;} + if (env[0] == '=') {found_equal = 1;} + ++env; + } + ++env; + if (found_equal == 0 || len_since_equal == 0) + { + // This string is not valid, we should ignore it. + if (env[0] == 0) + { + // Double null after invalid string, ignore it. + ++env; + } + } + else + { + if (argv_arg != 0 && (env - cvar) > 5 && + (cvar[0] == 'A' && cvar[1] == 'R' && cvar[2] == 'G' && cvar[3] == 'V' && cvar[4] == '=')) + { + *argv_arg = cvar + 5; + // We do not count ARGV as it is a part of command line. + } + else + { + if (storage_list != 0) + { + storage_list[num] = cvar; + } + ++num; + } + } + } + } + return num; +} + +int extract_cmd_args(const char* prg_cmd_line, const char* argv_arg, int* cmd_line_chars, const char** storage_list, char* cmd_line_out) +{ + int num = 0; + if (storage_list != 0) + { + storage_list[num] = _proc_name; + } + ++num; + + int cmd_line_len = ((const unsigned char*)prg_cmd_line)[0]; + cmd_line_chars[0] = 0; + if (cmd_line_len == 0) + { + return num; + } + if (cmd_line_len != 127) + { + // Only use ARGV if length is 127 + argv_arg = 0; + } + + const char* cmdline = prg_cmd_line + 1; + char expect = 0; + char *arg_start = cmd_line_out; + int arglen = 0; + while (cmdline != 0) + { + char c; + while ((c = *cmdline++) != 0) + { + if (c == '\\' && expect == 0) + { + // Next char will be escaped. + expect = '\\'; + } + else if ((c == '\'' || c == '\"') && (expect == c || expect == 0)) + { + // chars between "" or '' should not be escaped nor spaces split into args. + expect ^= c; + } + else if (c == ' ' && expect == 0) + { + if (arglen != 0) + { + // found one arg + if (cmd_line_out != 0) {*cmd_line_out++ = 0;} + cmd_line_chars[0]++; + if (storage_list != 0) + { + storage_list[num] = arg_start; + } + ++num; + arglen = 0; // Next arg + arg_start = cmd_line_out; + } + } + else + { + if (expect == '\\') + { + // Only escape one char. + expect = 0; + } + if (cmd_line_out != 0) {*cmd_line_out++ = c;} + cmd_line_chars[0]++; + ++arglen; + } + } + + // Continue with extended command line if we have one. + cmdline = argv_arg; + argv_arg = 0; // To end loop + } + if (arglen != 0) + { + if (cmd_line_out != 0) {*cmd_line_out++ = 0;} + cmd_line_chars[0]++; + if (storage_list != 0) + { + storage_list[num] = arg_start; + } + ++num; + } + return num; +} + +/* +prg_cmd_line: + First byte = length of prg_cmd_line. + If length == 127 then "ARGV=" in prg_env contains a string that should be appended to prg_cmd_line. +prg_env: + Contains a set of null terminated strings. + Double null ends set. +global_env: + Contains a set of null terminated strings. + Double null ends set. + AES versions >= 1.4 may multi-args (PATH) with ',', before it was only ';' + A bug in AES can cause strings like: "PATH=[nul]A:\[nul][nul]". They should be ignored. + +Due to how existing software sets up environment variables on Atari, global_env and prg_env can +contain duplicates. +So duplicates will be discarded with prg_env having higher priority than global_env. +*/ +void setup_env_and_args(void *mem_ptr) +{ + /* + mem_ptr is guaranteed have the number of bytes reserved that function + estimate_env_and_args_memory calculates. + */ + const char* argv_arg = 0; + const char* prg_cmd_line = _BasePage->p_cmdlin; + const char* prg_env = _BasePage->p_env; + const char* global_env = _atari_4be_at_prg_start; + + // Collect all environment variables. + environ = (char**)mem_ptr; + int num_env_args = extract_env_vars(prg_env, (const char**)environ, &argv_arg); + num_env_args += extract_env_vars(global_env, (const char**)environ, 0); + /* + Remove duplicates. + Not fun as we cannot use any library functions here. + */ + for (int i = 0; i < num_env_args; ++i) + { + char* vari = environ[i]; + if (vari != 0) + { + for (int j = i + 1; j < num_env_args; ++j) + { + char* varj = environ[j]; + if (varj != 0) + { + char* tvari = vari; + while (*tvari == *varj && *tvari != 0 && *tvari != '=') + { + ++tvari; + ++varj; + } + if (*tvari == '=' && *varj == '=') + { + // Found duplicate, clear it with a null pointer. + environ[j] = 0; + } + } + } + } + } + // Remove all null variables. + int new_num_env_args = 0; + for (int i = 0; i < num_env_args; ++i) + { + if (environ[i] != 0) + { + environ[new_num_env_args++] = environ[i]; + } + } + environ[new_num_env_args++] = 0; + + // Count command line args + int cmd_line_chars = 0; + int num_cmd_args = extract_cmd_args(prg_cmd_line, argv_arg, &cmd_line_chars, 0, 0); + + _atari_argv = (const char**)environ + new_num_env_args; + char* cmd_line_out = (char*)(_atari_argv + num_cmd_args + 1); + // Collect all command line args. + _atari_argc = extract_cmd_args(prg_cmd_line, argv_arg, &cmd_line_chars, _atari_argv, cmd_line_out); + _atari_argv[_atari_argc] = 0; +} + +int estimate_env_and_args_memory(void) +{ + /* + Stack and heap are not properly set up when this function is called. + NO memory allocations or large stack usage allowed! + */ + const char* argv_arg = 0; + const char* prg_cmd_line = _BasePage->p_cmdlin; + const char* prg_env = _BasePage->p_env; + const char* global_env = _atari_4be_at_prg_start; + + int num_env_args = extract_env_vars(prg_env, 0, &argv_arg); + num_env_args += extract_env_vars(global_env, 0, 0); + int cmd_line_chars = 0; + int num_cmd_args = extract_cmd_args(prg_cmd_line, argv_arg, &cmd_line_chars, 0, 0); + + int bytes_to_reserve = (num_env_args + 1) * 4; + bytes_to_reserve += (num_cmd_args + 1) * 4; + bytes_to_reserve += cmd_line_chars; + + // This is the number of bytes of heap space that will be reserved before + // stack and heap is initialized. + return bytes_to_reserve; +} \ No newline at end of file -- 2.43.0
0005-m68k-atari-elf-specs-file-declares-environ-as-undefi.patch
(text/x-patch, 847 B)
From 0171328334f09f319e89a5077350e4bcad08b917 Mon Sep 17 00:00:00 2001 From: Mikael Hildenborg <[email protected]> Date: Fri, 26 Sep 2025 08:47:21 +0200 Subject: [PATCH 5/5] m68k-atari-elf: specs file declares environ as undefined. --- libgloss/m68k/atari/atari-tos.specs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libgloss/m68k/atari/atari-tos.specs b/libgloss/m68k/atari/atari-tos.specs index 00781c4fc..02037132c 100644 --- a/libgloss/m68k/atari/atari-tos.specs +++ b/libgloss/m68k/atari/atari-tos.specs @@ -4,7 +4,7 @@ # Atari gcc specs *link: -+ --emit-relocs --no-warn-rwx-segments -static --no-warn-execstack --undefined=__errno -T atari-tos.ld ++ --emit-relocs --no-warn-rwx-segments -static --no-warn-execstack --undefined=environ --undefined=__errno -T atari-tos.ld *lib: + -latari-tos -- 2.43.0