delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2019/06/22/02:49:08

X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f
From: Rod Pemberton <invalid AT lkntrgzxc DOT com>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: malloc() returns pointer to already allocated memory
Date: Sat, 22 Jun 2019 02:36:14 -0400
Organization: Aioe.org NNTP Server
Lines: 196
Message-ID: <qeki3s$qpt$1@gioia.aioe.org>
References: <158e5d20-0a90-4beb-de48-da328379d8fb AT gmail DOT com>
<qe76u1$1kj8$1 AT gioia DOT aioe DOT org>
<f0b68226-f6f4-244a-6dd5-a8ecbabb584b AT gmail DOT com>
<qe79eb$1urs$1 AT gioia DOT aioe DOT org>
<qe7ar9$52r$1 AT gioia DOT aioe DOT org>
<qe7avt$52r$2 AT gioia DOT aioe DOT org>
<qe7bve$9ti$1 AT gioia DOT aioe DOT org>
<qe7f8g$oak$1 AT gioia DOT aioe DOT org>
<b035cc97-1261-e26e-2d3c-b3672928c9af AT gmail DOT com>
<qec3qv$1hdk$1 AT gioia DOT aioe DOT org>
<64786234-be30-3862-b2ee-133d2c49fb1a AT gmail DOT com>
<qefq2m$1o7d$1 AT gioia DOT aioe DOT org>
<19ff3320-4068-663e-ca70-d3e4dc459ba7 AT gmail DOT com>
<qehvr7$1fra$1 AT gioia DOT aioe DOT org>
<5038b8a2-cd29-01f8-f825-dead031f8361 AT gmail DOT com>
NNTP-Posting-Host: +15yR2JuBIwiofOqK4kSZw.user.gioia.aioe.org
Mime-Version: 1.0
X-Complaints-To: abuse AT aioe DOT org
X-Notice: Filtered by postfilter v. 0.9.2
Bytes: 7165
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

On Fri, 21 Jun 2019 09:44:34 +0200
"Gisle Vanem (gisle DOT vanem AT gmail DOT com) [via djgpp AT delorie DOT com]"
<djgpp AT delorie DOT com> wrote:

> Rod Pemberton wrote:

> > Of course, not saving/restoring C/C++ code's in-use registers does
> > much the same thing.  Certain registers must be preserved and can't
> > be clobbered.  These can also be referred to as callee-savee or
> > caller-saved registers.  For DJGPP, my notes say that EBX, EDI, ESI,
> > EBP, DS, ES, SS registers must preserved.  I.e., check your inlined
> > assembly's clobber list.  
> 
> And the GS, FS registers too. These are *not* preserved in a
> real-mode callback (RMCB) like
> '_go32_dpmi_allocate_real_mode_callback_retf()' Not sure about
> '_dpmi_allocate_real_mode_callback()'
> 
> Ref: <djgpp_root>/src/LIBC/GO32/gormcb.c
> 
> I figured this after similar bugs in the network-driver
> call-back in Watt-32 tcp/ip stack.

Thank you.

I made some notes on what each does and when to use them, e.g.,
(some lines wrapped, so double spaced ...)

__dpmi_int() preferred method in DJGPP for calling ints (vs. int86)

__dpmi_int calls Int in RM by using the DPMI host

__dpmi_allocate_real_mode_callback  (for assembly code in PM)

_go32_dpmi_allocate_real_mode_callback_iret  (for C code on RM int)

_go32_dpmi_allocate_real_mode_callback_retf  (for C code on RM far jump)

_go32_dpmi_allocate_iret_wrapper   (for C code on PM int)

_go32_dpmi_chain_protected_mode_interrupt_vector  (for C code on PM int
which chains to old PM int)


Also other interrupt calling functions,

int86() via _int86() calls Int in PM which is then reflected to RM by
DPMI host - except for a few Int 0x21 functions (extended) which call
__dpmi_int()

int86x() calls Int in PM

_int86() calls Int in PM

int386() same as int86() - dos.h

int386x() same as int86x() - dos.h

intdos() same as int86() for Int 0x21 - dos.h

intdosx() same as int86x() for int 0x21 - dos.h - intdosx.c

bdosptr() same as bdos() - dos.h - bdosptr.S

bdos() - bdos.c - calls Int 0x21 with func=AH, AL, DX - bdosptr uses DX
as pointer to buffer - calls int86() with 0x21

__dpmi_int() - d0300_z.S - calls DPMI via PM Int 0x31 which calls RM
Int - ss, e sp, flags are 'automatically' taken care of - certain Int
0x21 int_86() calls redirected to __dpmi_int() by int_86()

__dpmi_simulate_real_mode_interrupt() - d0300.S - calls DPMI via PM Int
0x31 which calls RM Int - same as __dpmi_int() without saving/restoring
ss,sp,flags


Also, some go32 to DPMI mappings, 

__go32_dpmi_simulate_int -> ___dpmi_simulate_real_mode_interrupt in
godefv1.S

__go32_dpmi_simulate_fcall -> ___dpmi_simulate_real_mode_procedure_retf
in godefv1.S

__go32_dpmi_simulate_fcall_iret ->
___dpmi_simulate_real_mode_procedure_iret in godefv1.S

_go32_dpmi_simulate_int -> __dpmi_simulate_real_mode_interrupt in dpmi.h

_go32_dpmi_simulate_fcall -> __dpmi_simulate_real_mode_procedure_retf
in dpmi.h

_go32_dpmi_simulate_fcall_iret ->
__dpmi_simulate_real_mode_procedure_iret in dpmi.h


> I'm not sure how/where FS/GS are used; I suspect a modern gcc uses
> those in e.g. built-in functions etc. 
> 

DJGPP uses fs for far pointers (farpeek, farpoke)
DJGPP uses gs for dos segment via _dos_ds and within libc


For reference on DJGPP's various selectors, some info I extracted:
(some lines wrapped, so double spaced ... from v2.03)

cs               selector for code segment, _my_cs(), _go32_my_cs()

ds  data for cs  selector for data segment used by gcc, _my_ds(),
_go32_my_ds()

ss  same as ds   selector for stack segment, _my_ss(), _go32_my_ss()

es  same as ds   selector for psp segment used by gcc

fs               selector unused, but used for farptrs (farpeek,farpoke)

gs               selector for dos segment (1M+64k), and used by libc

dsa alias for ds __djgpp_ds_alias, mirrors ds, used for rmcb's

dsl is gs        __djgpp_dos_sel

dds is gs        _dos_ds, _go32_info_ block+26,
_go32_info_block.selector_for_linear_memory 

cms is gs        _go32_conventional_mem_selector()

_my_cs() - returns cs

_my_ds() - returns ds (and also ss, es, dsa)

_my_ss() - returns ss (and also ds, es, dsa)

_dos_ds  - is gs (and also dsl, cms)

_farsetsel - set fs to another selector e.g., _dos_ds, _my_ds() for use
with farpeek, farpoke etc.


For adjusting segment limit's, 

__djgpp_nearptr_enable() can be used to boost the segment limit to 4Gb
for cs, ds, es, ss, and dsa

__dpmi_set_segment_limit(_selector_, 0xFFFFFFFFU) can be used to boost
the segment limit to 4Gb for _dos_ds, etc.


For wrapped memory addressing,

DJGPP defines two offsets in <sys\nearptr.h>:
  __djgpp_conventional_base   (which is a #define)
  __djgpp_base_address        (which is an int)

They are related by the following define:
   #define __djgpp_conventional_base (-__djgpp_base_address)


For DJGPP's transfer buffer, i.e., calling RM DOS or BIOS functions,

__tb is a linear address:
   for RM, segment:offset is       __tb>>4:0
   for RM, segment:offset is  __tb_segment:__tb_offset
   for PM, selector:offset is      _dos_ds:__tb
   for PM to RM, segment:offset is __tb>>4:0
    (tb is paragraph aligned for PM)

__tb is          _go32_info_block+12,
_go32_info_block.linear_address_of_transfer_buffer

__tb is          _stubinfo->ds_segment * 16

__tb_segment is  __tb >> 4

__tb_offset is   0

__tb size is
_go32_info_block.size_of_transfer_buffer,_go32_info_block+16

__tb size is     _stubinfo->minkeep

__tb size is     04000h (16384 bytes)



HTH,


Rod Pemberton

-- 
Once upon a time, many decades ago in a place far away, humble people
sought their freedom, and lost. "Ideas are bulletproof."

- Raw text -


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