Mail Archives: djgpp/2000/03/14/10:26:18
Eli Zaretskii wrote:
>
> On Mon, 13 Mar 2000, Michael Tippach wrote:
>
> > IIRC even FPU exception handling is done using the segment limit
> > alteration kludge.
>
> That's correct.
>
> > A way that would also work under NT is to make the
> > IRQ 13 handler just set the EM bit in CR0 by trying both, DPMI function
> > 0xE01 and direct writes to CR0.
>
> I'm not sure I understand what problem does this solve. Currently,
> the EM bit is set by calling function 0E01h at startup.
Setting the EM bit TEMPORARILY from within the IRQ 0x13 interrupt
handler to cause a single INT 0x7 upon the next FPU instruction.
Exceptions are good, because we can use them to make a context switch.
NOT: setting the EM bit permanently to emulate a non-existant FPU. That
is something different.
>
> > Under a CPL 0 host, conditionally setting the NE bit (just once
> > at startup) allows for exception 16 instead of involving the interrupt
> > controller.
>
> This still doesn't solve the problem of converting an exception to a
> signal.
It does. Read on...
> Signal handlers are (almost) normal C functions, so they
> cannot be run from an exception handler. The issue at hand is how to
> pull this conversion trick safely and portably, not how to generate
> the exception.
Once you are in the context of a DPMI exception handler, you can
continue execution wherever you desire. IOW: as opposed to a hardware
interrupt handler where that isn't possible, one can do a complete
context switch from within an exception handler. That is, BTW what DJGPP
does when it receives the GPF or stack fault or whatever would be the
outcome of the segment limit alteration thing. As soon as an IRQ is
converted into a DPMI exception, the problem is essentially solved.
>
> Besides, CPL 0 host is not so interesting for DJGPP, which is mostly a
> CPL 3 environment for writing ``normal'' application programs.
> Writing low-level stuff like OS kernels is not something DJGPP is
> meant to be well suited for.
I meant a DPMI host that runs the client at ring 0 for convenience
reasons. In a non- multitasking, non- VM- environment there is very
little reason left to maintain all that ring switching overhead.
>
> > CTRL-C and friends are a bit trickier.
> >
> > One possibility would be to conditionally alter the CS limit instead,
> > _IF_ the DPMI host is CPL0 OR NTVDM (should work with both).
>
> Not good. CPL 0 and NT are among the least interesting DJGPP targets.
This discussion started with someone complaining about NTVDM screwing up
DJGPP signal handling.
Despite working in above mentioned environments, it wouldn't break any
other environment, if used only where appropriate (CPL0 and NT). It
takes 3 lines of assembly code to detect CPL0 and it takes 3 more lines
of assembly code to detect NT.
> Futzing with the CS selector is among the most dangerous things in
> general, AFAIK.
Not as dangerous as SS ("Stack Suicide") in these environments. It would
always fault at the IRET when the DPMI host finally returns from the
interrupt handling code. If the IRET would have been a ring transition,
this would be no good, I suppose. For, a DPMI host running its client at
ring 3 would not really be prepared to convert exceptions occuring in
ring 0 into DPMI compliant ones at ring 3 (something to try out,
really). Then again, if the IRET does NOT cause a ring transition, the
DPMI host would have very little interest in looking at the source of
the exception. Business as usual, in that case.
I think that would be the easiest way to fix the NT signal problem,
because it can be implemented at very little cost (few lines of code)
without breaking any existing code I could think of.
>
> > OR,
> > have the run time environment maintain SS as a mere alias to DS.
>
> Will this work with the -fomit-frame-pointer switch to GCC?
Yes. If the descriptors for SS and DS are identical, SS and DS would
always point to the same location in memory. The sbrk(sp?) helper would
need to be modified to also move the base address of the app default SS
(like this is done with CS and DS) after resizing the DPMI memory block.
>
> In any case, if SS is a different selector, SIGINT won't be generated
> until the program touches some *global* or static variable.
True. But, if applied to non time- critical things, such as CTRL-C, that
wouldn't make much of a difference, especially if local variables are
addressed using DS, e.g.
lea eax, [esp + 16]
push eax
call _doSomething
How often, on average are local variables passed by reference as opposed
to situations where they are passed by value?
> Touching
> an automatic variable won't produce SIGINT.
Not always true, as explained above.
> Since global and static
> variables are used much less than local ones, this might mean
> deferring the signal much more than it is today.
Depending on the actual situation, it could indeed defer the delivery of
a signal _somewhat_. For user- generated ones this does not matter. The
DJGPP signal handling, as is, is playing dice anyway.
>
> > OR,
> > one somewhat more memory intense, albeit pretty generic approach would
> > be to let the interrupt handler make a copy of the code section
>
> ALL of the code section? That might be megabytes to move inside an
> interrupt handler, right?
Very few applications contain megabytes of code. Initialized data is
what makes applications fat.
>
> Please note that this mechanism is also used by the timer interrupt
> handler (to produce SIGPROF and SIGALRM), so it must be fast enough to
> allow a program sustain an interrupt every 55 msec and still have
> enough CPU cycles left to do something useful.
Use CS- method above and the response will be immediate in cases where
the program would have crashed in the past and it will be the same as it
used to be in cases where it did not crash in the past.
>
> Moving the code also makes debug support next to impossible (if you
> want to debug programs which install signal handlers).
Different issue, admittedly. Just another approach that might have been
worth giving it a thought.
Regards,
Michael Tippach
- Raw text -