delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2001/04/24/07:49:06

X-Authentication-Warning: acp3bf.physik.rwth-aachen.de: broeker owned process doing -bs
Date: Tue, 24 Apr 2001 13:48:49 +0200 (MET DST)
From: Hans-Bernhard Broeker <broeker AT physik DOT rwth-aachen DOT de>
X-Sender: broeker AT acp3bf
To: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
cc: djgpp-workers AT delorie DOT com, Charles Sandmann <sandmann AT clio DOT rice DOT edu>,
n_abing AT ns DOT roxas-online DOT net DOT ph
Subject: Re: Fixed core dumper in dpmiexcp.c
In-Reply-To: <Pine.SUN.3.91.1010424141701.11737G-100000@is>
Message-ID: <Pine.LNX.4.10.10104241337420.5316-100000@acp3bf>
MIME-Version: 1.0
Reply-To: djgpp-workers AT delorie DOT com
Errors-To: nobody AT delorie DOT com
X-Mailing-List: djgpp-workers AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

On Tue, 24 Apr 2001, Eli Zaretskii wrote:

> On Tue, 24 Apr 2001, Hans-Bernhard Broeker wrote:

> > So yes, it may well be that the code computing the actual size of
> > individual memory blocks is wrong, and thus tries to dump unmapped memory.
> > As far as I understand the code, it assumes that the whole address range
> > spanned __djgpp_memory_handle_list[] is mapped, up to
> > __djgpp_selector_limit, with no holes.
> 
> I don't have the code handy: does each handle in the list specify its 
> starting address and its size?  

No. Quoting include/crt0.h:

typedef struct {
  long handle;
  unsigned address;
  } __djgpp_sbrk_handle;

extern __djgpp_sbrk_handle __djgpp_memory_handle_list[256];

No size or end address is kept in the __djgpp_memory_handle_list.  In
principle, the DPMI call mentioned below should be able to retreive the
size --- but it's a 1.0-only call :-(

For reference, here's the actual code from the core-dumping version of
dpmiexcp.c (slightly reindented for mailing):

static int make_decent_memory_block_list(void)
{
  int i, j;

  /* Get the base addresses, fill in a maximum size */
  for (i = 0; (i < 256) && __djgpp_memory_handle_list[i].handle; i++)
  {
    mem_block_list[i].address = __djgpp_memory_handle_list[i].address;
    mem_block_list[i].size = __djgpp_selector_limit + 1 -
	mem_block_list[i].address;
    mem_block_list[i].chunks = 0;
  }
  num_mem_blocks = i;
        
  /* First reduce the sizes, using the fact that blocks can't overlap */
  for (i = 0; i < num_mem_blocks; i++)
    for (j = 0; j < num_mem_blocks; j++)
      if (j != i)
        if (mem_block_list[j].address > mem_block_list[i].address)
          if (mem_block_list[j].address - mem_block_list[i].address <
		mem_block_list[i].size)
            mem_block_list[i].size = mem_block_list[j].address -
	             mem_block_list[i].address;
        
   /* Now try the DPMI call; if it works, we can override the previous 
    * data; however, I have yet to find a DPMI server that supports it
    */
   for (i = 0; i < num_mem_blocks; i++)
   {
     __dpmi_meminfo info = { 0, 0, 0 };
     info.handle = __djgpp_memory_handle_list[i].handle;
     if (__dpmi_get_memory_block_size_and_base (&info) != -1)
       if (info.size) mem_block_list[i].size = info.size;
   }

> If so, then why does the code need an 
> assumption about the selector limit?  If the handles don't specify their 
> actual size, how in tghe world can _any_ code know which pages are and 
> which aren't mapped into the program's address space?

Well --- maybe it can't, and that's the heart of our dilemma. Or maybe it
shouldn't have to, if we were to assume that the whole arena (from
0x000000000 to __djgpp_selector_limit) is always mapped, without holes.

> It is also possible that the bug is not in the core dumper, but in sbrk, 
> where the handle list is maintained.  Wrapping around unisgned values is 
> notorious for concealing subtle bugs ;-)

IIRC, none of the linear address was in actual danger of wrapping around
at 4GB, here. DS base plus __djgpp_selector_limit was a lot smaller than
4GB. Somewhere safely between 0x8000000 and 0xA000000. So if there's any
overflow or wrapping, it'd have to be signed overflow (all relevant
addresses > INT_MAX, here).

> > It computes sizes of individual
> > blocks by their distance from the block with the next highest start
> > address.
> 
> Is this the answer to my question above (about the use of selector 
> limit)?  

I think so, yes.

> If so, this computation needs to be refined.  But the first 
> thing I'd suggest to make sure is that the crashes all happen when a 
> block whose ``next highest start address'' suffers from the 4GB 
> wrap-around.

If I don't totally misremeber the figures, none of them did.

-- 
Hans-Bernhard Broeker (broeker AT physik DOT rwth-aachen DOT de)
Even if all the snow were burnt, ashes would remain.

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019