[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[MiNT] Pexec(), basepage and command line handling?



Hi,

According to the documentation, basepage size is 256 bytes,
of which latter half, 128 bytes, is supposed to be reserved
for command line.  And of those 128 bytes 125 are actually
supposed to be usable for a command line:
http://toshyp.atari.org/en/005014.html#BASEPAGE
http://toshyp.atari.org/en/00500b.html#Pexec

However, when doing Pexec(), all the TOS versions seem
to read the program file to position basepage + 228 bytes
(at least with the attached program) i.e. program data will
overwrite end of the passed command line starting at
byte 100.


Attached is an test program (with AHCC project file) which
shows its args, and re-executes itself with a 119 chars long
command line.

The output from it is following:
-------
Giving myself command 119 chars long command line...
Loaded, press a key to execute.
Got command line args:
0: <>
1: <-bataritos>
2: <-tos-flags>
3: <7>
4: <-x>
5: <-Bstatic>
6: <-Cvbcc>
7: <-nostdlib>
8: <c:\vbcc\lib\startup.o>
9: <tmp1.o>
10: <-s>
11: <-Lc:\vbcc\l`>
12: <t>
13: <.>
14: <&>
-------

You can see that end of the command line has gotten overwritten
with "garbage".


When tracing what happens at GEMDOS level (with Hatari):
-------
GEMDOS 0x4B Pexec(3, "SYSTEM.TTP", [119]"-bataritos -tos-flags 7 -x -Bstatic 
-Cvbcc -nostdlib c:\vbcc\lib\startup.o "tmp1.o"  -s -Lc:\vbcc\lib -lvc -o 
hello.tos", 0x0)
GEMDOS 0x2F Fgetdta()
GEMDOS 0x4E Fsfirst("SYSTEM.TTP", 0x17)
GEMDOS 0x4F Fsnext()
GEMDOS 0x4B Pexec(5, 0x0, 0x13c0e, 0x0)
GEMDOS 0x3D Fopen("SYSTEM.TTP", read-only)
-> FD 0 (read-only)
GEMDOS 0x3F Fread(64, 28, 0x1545c)
GEMDOS 0x3F Fread(64, 2147483647, 0x15478)
GEMDOS 0x3E Fclose(64)
GEMDOS 0x 9 Cconws(0x13BEB)
Loaded, press a key to execute.
GEMDOS 0x B Cconis()
GEMDOS 0x 1 Cconin()
GEMDOS 0x4B Pexec(4, 0x0, 0x15378, 0x0)
-------

One can see that program's Pexec(3) call is within TOS implemented
using Pexec(5) to create a program basepage, and then loading of
the program binary.

You can also see that TOS does first Fread() to an address that is
offset 228 bytes from the returned basepage address that the program
gives to Pexec(4) after Pexec(3) has finished.

I've verified with a debugger that Pexec(5) actually returned
that address, i.e. program doesn't mangle the returned basepage
address, it's TOS itself that writes over the basepage it created
before returning from Pexec(3).

I've also checked with GEMDOS tracing that same seems to happen
with all TOS versions (including EmuTOS).


Could somebody explain why this happens?


	- Eero

PS. This issue came from Frank Wille, VBCC C-compiler 68k backend
maintainer, who was looking into adding TOS support to VBCC.

I think currently MiNT VBCC is compiled with gcc/MiNTlib, but
Frank would like the compiler to be self-hosting (and MiNTlib
license situation seems a bit of a mess).
/* system.ttp tester for longer command lines
 * that may be passed in system() call
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tos.h>

char args[128] = "\0-bataritos -tos-flags 7 -x -Bstatic -Cvbcc "
                 "-nostdlib c:\\vbcc\\lib\\startup.o \"tmp1.o\"  -s "
                 "-Lc:\\vbcc\\lib -lvc -o hello.tos";

void wait_key(void)
{
	while (Cconis()) {
		Cconin();
	}
	Cconin();
}

int main(int argc,char *argv[])
{
	int i;
	void *basepage;
	puts("Got command line args:");
	for (i = 0; i < argc; i++) {
		printf("%d: <%s>\r\n", i, argv[i]);
	}
	*args = (char)strlen(&args[1]);
	printf("\r\nGiving myself command %d chars long command line...\r\n", *args);
	basepage = (void *)Pexec(3, "SYSTEM.TTP", args, NULL);
	Cconws("Loaded, press a key to execute.\r\n");
	wait_key();
	return Pexec(4, NULL, basepage, NULL);
}
; AHCC project file for system() call cmdline tester
.C [-iinclude]
system.ttp
=
ahcstart.o
system.c
ahccstdi.lib

Attachment: SYSTEM.TTP
Description: Binary data