From: Martin Str|mberg Message-Id: <200001061735.SAA06841@father.ludd.luth.se> Subject: Re: The endless int31 hooking debugging continued To: eliz AT is DOT elta DOT co DOT il (Eli Zaretskii) Date: Thu, 6 Jan 100 18:35:53 +0100 (MET) Cc: djgpp AT delorie DOT com (DJGPP) In-Reply-To: from Eli Zaretskii at "Jan 6, 0 07:13:42 pm" X-Mailer: ELM [version 2.4ME+ PL15 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Reply-To: djgpp AT delorie DOT com Errors-To: dj-admin AT delorie DOT com X-Mailing-List: djgpp AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk 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 #include #include #include #include #include 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. -----