Old Friends

ucontext_t is an old friend of mine. Although it's "layout" is simple enough at first glance, an attempt to probe further will be soon met with increasing complexity. It's defined this way:

struct  ucontext {
        ulong_t         uc_flags;
        ucontext_t      \*uc_link;
        sigset_t        uc_sigmask;
        stack_t         uc_stack;
        mcontext_t      uc_mcontext;
        long            uc_filler[23];
};

And if you go after mcontext_t, it looks like:

typedef struct {
        gregset_t       gregs;
        gwindows_t      \*gwins;
        fpregset_t      fpregs;
        xrs_t           xrs;
        long            filler[19];
} mcontext_t;

So you start wondering about gregset_t, gwindows_t, and fpregset_t etc. and soon:

typedef int     greg_t;
typedef greg_t  gregset_t[19 ];

struct  rwindow {
        greg_t  rw_local[8];
        greg_t  rw_in[8];
};
struct gwindows {
        int             wbcnt;
        int             \*spbuf[31 ];
        struct rwindow  wbuf[31 ];
};
typedef struct gwindows gwindows_t;


struct fpu {
        union {
                unsigned        fpu_regs[32];
                double          fpu_dregs[16];
        } fpu_fr;
        struct fq       \*fpu_q;
        unsigned        fpu_fsr;
        unsigned char   fpu_qcnt;
        unsigned char   fpu_q_entrysize;
        unsigned char   fpu_en;
};
typedef struct fpu      fpregset_t;

typedef struct {
        unsigned int            xrs_id;
        caddr_t                 xrs_ptr;
} xrs_t;

Whew that kinda completes the puzzle. it wasn't long before i threw away this whole mess and put some time into "leaning out" the whole thing. In the end, i could simplify it down to this, for sparc:

struct ucontext {
        unsigned int uu1[6];
        unsigned int uc_sp;
        unsigned int uc_sp_size;
        unsigned int uu2[2];
        unsigned int psw;
        unsigned int pc;
        unsigned int npc;
        unsigned int uu3[2];
        unsigned int g2;
        unsigned int g3;
        unsigned int g4;
        unsigned int g5;
        unsigned int g6;
        unsigned int g7;
        unsigned uu4[6];
        unsigned int esp;
        unsigned uu5[84];
};

And for x86:

struct ucontext {
        unsigned int uu1[6];
        unsigned int uc_sp;
        unsigned int uc_sp_size;
        unsigned int uu2[7];
        unsigned int ebp;
        unsigned int uu3[7];
        unsigned int pc;
        unsigned int uu4;
        unsigned int psw;
        unsigned int esp;
        unsigned int uu5[8];
        unsigned int g2;
        unsigned int g3;
        unsigned int uu6[3];
        unsigned int g4;
        unsigned int g5;
        unsigned int uu7[3];
        unsigned int g6;
        unsigned int g7;
        unsigned int uu8[3];
        unsigned int g8;
        unsigned int g9;
        unsigned uu9[76];
};

The uu signifies "UnUsed" - of course, for me, for that project.

Of course, there are no gx registers on x86; the pair of gx registers above - g2 & g3, g4 & g5 etc - stand for each of the mmx registers.

And yes, the rest of the gang - setcontext, getcontext, makecontext, and swapcontext. Sweet stuff, and works great. At least on Solaris, that is. Last time i checked, they sulk a lot on Linux.

Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

user13334066

Search

Archives
« prill 2014
DieHënMarMërEnjPreSht
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today