Mail Archives: cygwin/1997/05/28/12:15:58
------ =_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 <c_asm.h>
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".
- Raw text -