From: m DOT gregory AT rmit DOT edu DOT au (Mark A Gregory) Subject: RE: Need help with some missing functions 28 May 1997 12:15:58 -0700 Approved: cygnus DOT gnu-win32 AT cygnus DOT com Distribution: cygnus Message-ID: <01BC6BB2.E2619D10.cygnus.gnu-win32@rem18.co.rmit.edu.au> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="---- =_NextPart_000_01BC6BB2.E268C900" Original-To: "'Sergey Okhapkin'" Original-Cc: "'gnu-win32 AT cygnus DOT com'" Original-Sender: owner-gnu-win32 AT cygnus DOT com ------ =_NextPart_000_01BC6BB2.E268C900 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Hi Sergey, I have sorted out many problems thanks to your help. I have one more question that I hope you can answer. I have attached a file called arch.c and I need to choose between one of the many options for lwpInitContext. It seems they are architecture dependent. Which would you choose to work with the gnu-win32 tools? thank you Mark ------ =_NextPart_000_01BC6BB2.E268C900 Content-Type: text/plain; name="arch.c" Content-Transfer-Encoding: 7bit /* * arch.c * * architecture-dependent process context code * */ #ifndef AIX32 #include "lwp.h" #include "lwpint.h" #if defined(hpc) static struct lwpProc *tempcontext; struct lwpProc *initcontext=NULL; int startpoint; startcontext() { int space[10000]; int x; startpoint = (void *) &x; if (!setjmp(initcontext->context)) longjmp(tempcontext->context,1); if (!setjmp(tempcontext->context)) longjmp(LwpCurrent->context,1); lwpEntryPoint(); } void lwpInitContext(newp, sp) struct lwpProc *newp; void *sp; { struct lwpProc holder; int endpoint; if (initcontext == NULL) { initcontext = (struct lwpProc *) malloc (sizeof(struct lwpProc)); tempcontext = &holder; if (!setjmp(tempcontext->context)) startcontext(); } tempcontext = newp; endpoint = &endpoint; if (endpoint < startpoint) { if (!setjmp(LwpCurrent->context)) longjmp(initcontext->context,1); } else { LwpCurrent->size = endpoint - startpoint; LwpCurrent->sbtm = realloc(LwpCurrent->sbtm, LwpCurrent->size); memcpy(LwpCurrent->sbtm, startpoint, LwpCurrent->size); if (!setjmp(LwpCurrent->context)) longjmp(initcontext->context,1); memcpy(startpoint, LwpCurrent->sbtm, LwpCurrent->size); } } #elif defined(hpux) void lwpInitContext(newp, sp) volatile struct lwpProc *volatile newp; void *sp; { static jmp_buf *cpp; extern struct lwpProc *LwpCurrent; if (!lwpSave(LwpCurrent->context)) { cpp = (jmp_buf *)&newp->context; asm volatile ("ldw %0, %%sp": : "o" (sp)); if (!lwpSave(*cpp)) lwpRestore(LwpCurrent->context); lwpEntryPoint(); } } int lwpSave(jb) jmp_buf jb; { /* save stack pointer and return program counter */ asm ("stw %sp, 4(%arg0)"); asm ("stw %rp, 8(%arg0)"); /* save "callee save" registers */ asm ("stw %r3, 12(%arg0)"); asm ("stw %r4, 16(%arg0)"); asm ("stw %r5, 20(%arg0)"); asm ("stw %r6, 24(%arg0)"); asm ("stw %r7, 28(%arg0)"); asm ("stw %r8, 32(%arg0)"); asm ("stw %r9, 36(%arg0)"); asm ("stw %r10, 40(%arg0)"); asm ("stw %r11, 44(%arg0)"); asm ("stw %r12, 48(%arg0)"); asm ("stw %r13, 52(%arg0)"); asm ("stw %r14, 56(%arg0)"); asm ("stw %r15, 60(%arg0)"); asm ("stw %r16, 64(%arg0)"); asm ("stw %r17, 68(%arg0)"); asm ("stw %r18, 72(%arg0)"); /* save "callee save" space register */ asm volatile ("mfsp %sr3, %r1"); asm ("stw %r1, 0(%arg0)"); /* indicate "true return" from saved() */ asm ("ldi 0, %ret0"); asm (".LABEL _comefrom_"); } void lwpRestore(jb) jmp_buf jb; { /* restore stack pointer and program counter */ asm volatile ("ldw 4(%arg0), %sp"); asm volatile ("ldw 8(%arg0), %rp"); /* restore "callee save" space register */ asm volatile ("ldw 0(%arg0), %r1"); asm volatile ("mtsp %r1, %sr3"); /* restore "callee save" registers */ asm volatile ("ldw 12(%arg0), %r3"); asm volatile ("ldw 16(%arg0), %r4"); asm volatile ("ldw 20(%arg0), %r5"); asm volatile ("ldw 24(%arg0), %r6"); asm volatile ("ldw 28(%arg0), %r7"); asm volatile ("ldw 32(%arg0), %r8"); asm volatile ("ldw 36(%arg0), %r9"); asm volatile ("ldw 40(%arg0), %r10"); asm volatile ("ldw 44(%arg0), %r11"); asm volatile ("ldw 48(%arg0), %r12"); asm volatile ("ldw 52(%arg0), %r13"); asm volatile ("ldw 56(%arg0), %r14"); asm volatile ("ldw 60(%arg0), %r15"); asm volatile ("ldw 64(%arg0), %r16"); asm volatile ("ldw 68(%arg0), %r17"); asm volatile ("ldw 72(%arg0), %r18"); /* warp to saved() to unwind the frame correctly */ asm volatile ("bl _comefrom_, %r0"); asm volatile ("ldi 1, %ret0"); } #elif defined(BSD386) void lwpInitContext(newp, sp) struct lwpProc *newp; void *sp; { newp->context[2] = (int)sp; newp->context[0] = (int)lwpEntryPoint; } #elif defined(FBSD) void lwpInitContext(newp, sp) struct lwpProc *newp; void *sp; { setjmp (newp->context); newp->context->_jb[2] = (int)sp; newp->context->_jb[3] = (int)sp; newp->context->_jb[0] = (int)lwpEntryPoint; } #elif defined(__linux__) void lwpInitContext(newp, sp) struct lwpProc *newp; void *sp; { newp->context->__sp = sp; newp->context->__bp = sp; newp->context->__pc = (void *)lwpEntryPoint; } #elif defined(SUN3) void lwpInitContext(newp, sp) struct lwpProc *newp; void *sp; { newp->context[2] = (int)sp; newp->context[3] = (int)lwpEntryPoint; } #elif defined(SUN4) void lwpInitContext(newp, sp) struct lwpProc *newp; void *sp; { static jmp_buf *cpp; extern struct lwpProc *LwpCurrent; bzero(newp->context, sizeof(newp->context)); newp->context[0] = (int)sp; /* preserve cpp for new context */ cpp = (jmp_buf *)&newp->context; if (!_setjmp(LwpCurrent->context)) { /* create new context */ /* flush registers */ asm ("ta 0x03"); /* %o0 <- newp */ asm ("ld [%fp+0x44], %o0"); /* %o1 <- newp->context[0] */ asm ("ld [%o0], %o1"); /* create min frame on new stack */ asm ("save %o1,-96, %sp"); if (!_setjmp(*cpp)) _longjmp(LwpCurrent->context, 1); lwpEntryPoint(); } } #elif defined(__USLC__) && defined(i386) /* USL/Unixware on an Intel 386/486/... processor. * Tested on Unixware v1.1.2, based on SYSV R4.2 */ /* As per normal empire documentation, there is none. * * But, what we are attempting to do here is set up a longjump * context buffer so that the lwpEntryPoint is called when * the thread starts. * * I.E., what a setjmp/longjmp call set would do. * * How to figure this out? Well, without the setjmp code, you * need to reverse engineer it by printing out the context buffer * and the processor registers, and mapping which ones need * to be set. * * Alternatively, you can single instruction step through the longjmp * function, and figure out the offsets that it uses. * * Using offsets in bytes, * context + 0x04 [1] -> esi (general purpose reg) * context + 0x08 [2] -> edi (general purpose reg) * context + 0x0C [3] -> ebp (general purpose or parameter passing) * context + 0x10 [4] -> esp (stack) * context + 0x14 [5] -> jump location for return */ void lwpInitContext(newp, sp) struct lwpProc *newp; void *sp; { newp->context[4] = (int)sp; newp->context[5] = (int)lwpEntryPoint; } #elif defined UCONTEXT /* * Alternate aproach using setcontext en getcontext in stead of setjmp and * longjump. This should work on any SVr4 machine independant of * architecture. Unfortunaltely some changes are still nessesary in lwp.c. * Tested on IRIX 5.3 */ void lwpInitContext(newp, spp) struct lwpProc *newp; stack_t *spp; { getcontext (&(newp->context)); newp->context.uc_stack.ss_sp = spp->ss_sp; newp->context.uc_stack.ss_size = spp->ss_size; makecontext (&(newp->context), lwpEntryPoint, 0); } #elif defined(ALPHA) #include void lwpInitContext(newp, sp) struct lwpProc *newp; void *sp; { extern long *_gp; /* register values obtained from setjmp.h */ _setjmp(newp->context); newp->context[2] = (long)lwpEntryPoint; /* program counter */ newp->context[30] = (long)lwpEntryPoint; /* return address */ newp->context[31] = (long)lwpEntryPoint; /* fake program value (!) */ newp->context[34] = (long)sp; /* stack pointer */ } int lwpSave(jb) jmp_buf jb; { return _setjmp(jb); } void lwpRestore(jb) jmp_buf jb; { /* resume, but get the pv from the jmp_buf */ asm("ldq %pv, 248(%a0)"); asm("stq %a0, 16(%sp)"); /* generates a warning, but functions just fine */ asm("bsr %ra, __longjump_resume"); } #endif #endif ------ =_NextPart_000_01BC6BB2.E268C900-- - For help on using this list (especially unsubscribing), send a message to "gnu-win32-request AT cygnus DOT com" with one line of text: "help".