Mail Archives: djgpp/2000/01/06/16:04:49
According to Eli Zaretskii:
>
> On Thu, 6 Jan 100, Martin Str|mberg wrote:
>
> > > Or, better still, don't call any library functions from within the hook;
> > > then you don't need to worry about SS and ESP.
> >
> > Yes, but I need call cputs to get some debug information out.
>
> It should be easy to throw together a function that copies the string
> into a static buffer (together with any attribute byte, to make its tand
> out), then blits it all to video RAM. If you write this in assembly, you
> can forget about the stack.
Well, that's far over my head. I just want to be able to hook INT31
and be able to get out some debug info (so I can see where the real
code goes wrong). So if you have any pointers to such a nice debug
routine I'll very much want to see them (and no, dbgcom.c doesn't help
as it doesn't bother to set up the ss=es=ds thing).
Alternatively perhaps I could use the
__dpmi_simulate_real_mode_... routines and write eveything in C, but
then there's the problem how to make it chain or just return depending
on the outcome in the C routine (whether a reusable selector was found
or not).
Here's the latest incarnation. This just hang after printing "esp =
0x9afb8".
Right,
MartinS
---- Start of simple8.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, org_ss;
unsigned int org_eax, org_esp;
unsigned int my_esp;
__asm__ (".globl _handler
_handler:
/* Save registers. */
pushl %eax
pushl %ds
pushl %es
/* Restore segments to valid DJGPP state. */
pushl %eax
movw %cs:_my_ds, %ax
movw %ax, %ds
popl %eax
movl %eax, _org_eax
movw %ss, %ax
movw %ax, _org_ss
movw _my_ds, %ax
movw %ax, %es
movw %ax, %ss
movl %esp, _org_esp
movl _my_esp, %esp
movl _org_eax, %eax
/* Jump to previous handler. */
chain:
pusha
pushf
pushl $_chain_str
call _cputs
addl $4, %esp
popf
popa
movl _org_esp, %esp
movw _org_ss, %ax
movw %ax, %ss
popl %es
popl %ds
popl %eax
ljmp %cs:_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");
asm("
movl %esp, _my_esp
");
printf("esp = 0x%x.\n", my_esp);
my_esp -= 0x100;
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 simple8 simple8.c"
End:
*/
---- End of simple8.c. -----
- Raw text -