There are errors in the .COM loader. Under some circumstances it allocates not 
enough memory. There is an issue at Github [1].

a) needed size is not rounded up to paragraph, but rounded DOWN.
b) the loader allocates a maximum of ff0h paragraphs, but inclusive PSP 1000h 
paragraphs may be needed if the maximum number of bytes (ff00h are read from 
the .COM file).

As DOS allocates as much memory as it can get for the .COM file, in 99.9% this 
will not be an issue. But it nevertheless seems to be a bug.

As I am not sure that my fix is correct and respects all possible edge cases, I 
publish it here for review.

Btw I saw there is a kernel mailinglist. Should I publish such things to the 
kernel list, or is it dead?

[1]: https://github.com/FDOS/kernel/issues/207

Bernd


diff --git a/kernel/task.c b/kernel/task.c
index 8ddb6e3..d3b6511 100644
--- a/kernel/task.c
+++ b/kernel/task.c
@@ -465,12 +465,11 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk * exp, 
COUNT mode, COUNT fd)
   UWORD env, asize = 0;
   
   {
-    UWORD com_size;
+    UWORD alloc_size;
     {
       ULONG com_size_long = SftGetFsize(fd);
-      /* maximally 64k - 256 bytes stack -
-         256 bytes psp */
-      com_size = ((UWORD)min(com_size_long, 0xfe00u) >> 4) + 0x10;
+      /* maximally 64k inclusive 256 bytes psp, rounded up to paragraph */
+      alloc_size = (UWORD)(min(com_size_long + sizeof(psp) + 15, 0x10000ul) >> 
4);
     }
 
     if ((mode & 0x7f) != OVERLAY)
@@ -494,7 +493,7 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk * exp, COUNT 
mode, COUNT fd)
       /* yes, see RBIL, int21/ah=48 -- Bart */
 
       if (rc == SUCCESS)
-        rc = ExecMemLargest(&asize, com_size);
+        rc = ExecMemLargest(&asize, alloc_size);
       
       if (rc == SUCCESS)
         /* Allocate our memory and pass back any errors         */
@@ -513,7 +512,7 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk * exp, COUNT 
mode, COUNT fd)
       if (rc != SUCCESS)
         return rc;
 
-      ++mem;
+      ++mem;  /* skip MCB paragraph */
     }
     else
       mem = exp->load.load_seg;



_______________________________________________
Freedos-devel mailing list
Freedos-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freedos-devel

Reply via email to