X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f X-Recipient: djgpp AT delorie DOT com X-Recipient: dj AT delorie DOT com X-Original-DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=References:Subject:In-Reply-To:To:From:Date: mime-version; bh=8Z1HBwarYNvEmf50zhtlJ7xL6JCleJZhEvgLWGDwDLQ=; b=Pvs37ue0+7mb zBoT2Mrc8kxx94NsDnknzqxCHYKBfFPa3JEzlAJdFdMh6UWb81K1yZJnX63jbaU4At33KEFJPOBoL unmkaTOGFUHLLPKQsR3hHkJPe7erWqbYGbS9sG1X1E5822yR0MPm9M5o4UsiPCd8KPkHaIXNU2VA4 6AS038ej1TXTh+NQO/5f8Pqz8adz9xYRiKkKqZ0uHUPVx06lHugCV2ejp9dybA6Eu864c+rNU0xu5 2O2MdN5Ds9kyQiYT29zF+pDZ/3VtdE719aJ/kJfyuPta3PBTHmB1kmmd8Ojr9r0oFhAGZvXSgqyk4 63wxjCFg/xOZeZoLhoz0Cw==; Date: Fri, 12 Apr 2024 16:37:47 +0300 Message-Id: <86frvqsnv8.fsf@gnu.org> From: "Eli Zaretskii (eliz AT gnu DOT org) [via djgpp AT delorie DOT com]" To: Pali Cc: cwsdpmi AT earthlink DOT net, dj AT delorie DOT com, sezeroz AT gmail DOT com, djgpp AT delorie DOT com In-Reply-To: <20240321174923.hc5xu6iulkakf54w@pali> (message from Pali on Thu, 21 Mar 2024 18:49:23 +0100) Subject: Re: Error handling in __djgpp_nearptr_enable() References: <20240309111216 DOT fetp6m34nbe6u63y AT pali> <20240320203330 DOT clmkn2s4rr4obq4u AT pali> <86plvo2j0r DOT fsf AT gnu DOT org> <20240321174923 DOT hc5xu6iulkakf54w AT pali> Reply-To: djgpp AT delorie DOT com Errors-To: nobody AT delorie DOT com X-Mailing-List: djgpp AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk > Date: Thu, 21 Mar 2024 18:49:23 +0100 > From: Pali > Cc: Charles Sandmann , dj AT delorie DOT com, > sezeroz AT gmail DOT com, djgpp AT delorie DOT com > > On Thursday 21 March 2024 08:31:16 Eli Zaretskii wrote: > > > Hello, I observed strange issue that __djgpp_nearptr_enable() function > > > when running in NTVDM on Windows XP, on failure let segment limit in > > > some undefined/intermediate state. > > > > > > Test case: > > > > > > #include > > > #include > > > #include > > > #include > > > #include > > > > > > int main() { > > > unsigned long addr; > > > if (__dpmi_get_segment_base_address(_my_ds(), &addr) == 0) > > > printf("OLD BASE: 0x%lx\n", addr); > > > printf("OLD LIMIT: 0x%lx\n", __dpmi_get_segment_limit(_my_ds())); > > > printf("CALLING __djgpp_nearptr_enable()\n"); > > > if (__djgpp_nearptr_enable()) > > > printf("SUCCESS\n"); > > > else > > > printf("FAILED\n"); > > > if (__dpmi_get_segment_base_address(_my_ds(), &addr) == 0) > > > printf("NEW BASE: 0x%lx\n", addr); > > > printf("NEW LIMIT: 0x%lx\n", __dpmi_get_segment_limit(_my_ds())); > > > return 0; > > > } > > > > > > It prints: > > > > > > OLD BASE: 0x29e0000 > > > OLD LIMIT: 0x9ffff > > > CALLING __djgpp_nearptr_enable() > > > FAILED > > > NEW BASE: 0x29e0000 > > > NEW LIMIT: 0x7d60ffff > > > > > > I know that Windows NT kernel does not allow userspace to create a > > > segment with access to kernel memory space (above 0x7fff0000 limit). > > > So failure from the __djgpp_nearptr_enable() call in NTVDM is expected. > > > But I was not expecting that DJGPP in some cases may let segment limit > > > in some intermediate state. > > > > > > What about following DJGPP change? I think it can improve failure > > > behavior of __djgpp_nearptr_enable() when 4 GB DS limit is not allowed. > > > > > > --- src/libc/pc_hw/nearptr/nearptr.c > > > +++ src/libc/pc_hw/nearptr/nearptr.c > > > @@ -14,7 +14,10 @@ int __djgpp_nearptr_enable(void) > > > { > > > if(!__dpmi_set_segment_limit(_my_ds(), 0xffffffffU)) { > > > if(__dpmi_get_segment_limit(_my_ds()) != 0xffffffffU) > > > + { > > > + __dpmi_set_segment_limit(_my_ds(), __djgpp_selector_limit | 0xfff); > > > return 0; /* We set it but DPMI ignored/truncated it */ > > > + } > > > __dpmi_set_segment_limit(__djgpp_ds_alias, 0xffffffffU); > > > __dpmi_set_segment_limit(_my_cs(), 0xffffffffU); > > > _crt0_startup_flags |= _CRT0_FLAG_NEARPTR; > > > > What are the implications of this change, in plain English, in > > particular for DPMI hosts other than NTVDM? > > __djgpp_nearptr_enable() first tries to change DS limit to 4GB. If it > fails then function returns error back to the client. If it success then > it checks if DS limit is really set to 4GB. If the DS limit is not 4GB > then function returns error back to the client (return 0; in above > snipped). > > My change above does following: If DS limit is not 4GB then it is reset > back to the previous value (used before trying to change it to 4GB) and > after that returns error back to the client (return 0;). > > > (It would be best to > > actually test this with at least the popular hosts, including CWSDPMI > > and perhaps also versions of Windows newer than XP that still support > > DPMI in a reasonable enough manner that allows running |DJGPP > > programs.) > > This change does not affect CWSDPMI, because CWSDPMI supports setting DS > limit to 4GB and hence this code path is not executed. > > Also it does not affect any other DPMI host which return failure "on > failure" and success "on success". > > Normally DPMI host should return error if it reject request for changing > DS limit. But NTVDM is somehow special there, it neither reject request, > nor accept it. Instead it changes DS limit to the value which is below > the linear address 0x7fff0000; and returns success to the client. This > is a reason why DJGPP here has that check if DS limit was really set to > 4GB. > > My change improve the situation here, independently of the failure > reason (either __dpmi_set_segment_limit() failed or DPMI host returned > success but not set limit to 4GB), the previous DS limit is not > modified when function fails. > > So if application calls __djgpp_nearptr_enable(), it can ensure that on > success the limit is 4GB and on failure the limit is not changed at all. > > > I'm CC'ing Charles, in the hope that he is available and can comment > > on this. > > > > Btw, the DJGPP FAQ explicitly says that __djgpp_nearptr_enable fails > > on Windows NT family (i.e. with NTVDM). So strictly speaking, a > > program that calls __djgpp_nearptr_enable in that case is shooting > > itself in the foot... > > The NTVDM behavior is well documented and it is known that it does not > allow to access linear memory above 0x7fff0000. And application does > not know if is running under NTVDM or other DPMI host. OK, I've now installed this.