Mail Archives: djgpp/2000/01/05/11:28:42
According to Eli Zaretskii:
> 1) it calls a library function `cputs' without setting up the
> run-time environment expected by code generated by GCC (a valid
> DJGPP selector in DS, DS=ES=SS);
>
> 2) it calls _old_addr without the CS: override, which won't work
> because DS is not guaranteed to be loaded with DJGPP's data
> selector (if you set up the registers as `cputs' requires, this
> problem will go away as well).
Is it ok to just overwrite the values that was in ds, es and ss? I've
tried pushing things to be able to restore them, but then I've got
some _really_ strange crashes (Invalid opcode, Stack fault, EIP
pointing into the middle of an instruction)!
> Oh, we have an Emacs user here ;-)
Of course!
This modified vesion still crashes with:
F:\HACKERY\DPMI_SEL>simple7
cs = a7, ds = af, ss= af.
got interrupt vector
General Protection Fault at eip=142e0; flags=3056
eax=00000008 ebx=00bf00af ecx=00000000 edx=0000000e esi=00000123 edi=0001035c
ebp=000024c0 esp=00001f40 cs=a7 ds=af es=af fs=8f gs=bf ss=33 error=0000
Right,
MarinS
----- Start of simple7.c. -----
#include <dpmi.h>
#include <go32.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <crt0.h>
int _crt0_startup_flags = _CRT0_FLAG_LOCK_MEMORY;
__dpmi_paddr old_addr, new_addr;
void handler (void);
void handler_end (void);
char chain_str[] = "Chaining.\n\r";
unsigned short my_ds, i_ss;
__asm__ (".globl _handler
_handler:
/* Restore segments to valid DJGPP state. */
movw %cs:_my_ds, %ds
movw _my_ds, %es
movw _my_ds, %ss
/* Jump to previous handler. */
chain:
pusha
pushf
pushl $_chain_str
call _cputs
addl $4, %esp
popf
popa
ljmp _old_addr
.globl _handler_end
_handler_end:
nop");
int
main (void)
{
int selector;
__dpmi_paddr tmp_addr;
my_ds = _my_ds();
printf("cs = %hx, ds = %hx, ss= %hx.\n", _my_cs(), _my_ds(), _my_ss());
if (__dpmi_get_protected_mode_interrupt_vector (0x31, &old_addr))
{
fprintf (stderr, "can not get interrupt\n");
exit (EXIT_FAILURE);
}
printf ("got interrupt vector\n");
new_addr.selector = _my_cs ();
new_addr.offset32 = (unsigned long) handler;
if (__dpmi_set_protected_mode_interrupt_vector (0x31, &new_addr))
{
fprintf (stderr, "can not set interrupt\n");
exit (EXIT_FAILURE);
}
printf ("set interrupt vector\n");
selector = __dpmi_allocate_ldt_descriptors (1);
if (selector == -1)
fprintf (stderr, "can not allocate selector\n");
else
__dpmi_free_ldt_descriptor (selector);
printf ("allocated LDT descriptor?\n");
while (__dpmi_get_protected_mode_interrupt_vector (0x31, &tmp_addr)
|| (tmp_addr.selector != new_addr.selector)
|| (tmp_addr.offset32 != new_addr.offset32)
|| __dpmi_set_protected_mode_interrupt_vector (0x31, &old_addr))
{
fprintf (stderr, "can not restore interrupt\n");
system ("");
}
printf ("restored interrupt vector\n");
return EXIT_SUCCESS;
}
/*
Local Variables:
compile-command: "gcc -g -O2 -Wall -o simple7 simple7.c"
End:
*/
----- End of simple7.c. -----
- Raw text -