OpenBSD Journal

Developer blog: marco

Contributed by marco on from the wait-long-enough-for-someone-else-to-scratch dept.

After a few days of having my house packed with my wife's family I am hoping to get back to hacking. During my absence Miod could no longer help himself and he bailed me out of the hppa rfork agony. I had it mostly working but it was not good enough for commit. The reason was pretty dang simple, I was doing the stack setup wrong. No idea what possessed me to setup the stack first and then call rfork; let me make some random excuse, I'm an idiot! The positive is that I now have a basic understanding of hppa assembly and ABI.

Here is what miod came up with:

ENTRY(rfork_thread, 0) 
        SYSCALL(rfork) 
        comb,<> r0, ret0, 1f 
        nop
 
        /* 
         * In child process: switch stack, invoke function, then exit.
         */ 
 
        /* 
         * PIC code expects 32 bytes of room available below sp.
         * Then the regular procedure invocation requires us to allocate
         * 64 bytes as well. 
         */ 
        copy    arg1, sp 
        ldo     0(sp), r3 
        stw,ma  r0, HPPA_FRAME_SIZE(sp)
        stw     r0, HPPA_FRAME_CRP(sp)
        stw     r0, HPPA_FRAME_PSP(sp)
 
        copy    arg3, arg0              /* arg */
        copy    arg2, t1 
        bl      $$dyncall, r31 
        copy    r31, rp 
 
        copy    r0, arg0 
        SYSCALL(threxit) 
 
1: 
        bv      r0(rp) 
        nop
 
EXIT(rfork_thread) 

A couple of comments here. General purpose register 0 (r0) is hardwired to always return 0x00. The hard part of this code was to call the thread. We had to emulate the $$dyncall (dynamic call) mechanism that is defined in the ABI and used by gcc. There is a downside to this code and that is the offset can not be more than a 256k range. Consensus is that this should be sufficient.

What I was doing wrong was that I was setting up the stackframe *before* rfork and fixing it back in the parent before returning to librthread. Another thing I was doing that was unnecessary was to create an additional stack frame; it didn't matter just an extra step.

A couple of people were involved in making this tiny piece of code work. Credit goes to Miod, Kettenis & Mickey. Amazing how simple things can take so long to get right.

(Comments are closed)


Comments
  1. By Miod Vallat (82.195.186.220) miod@ on

    The $$dyncall invocation allows for a 256MB range, not 256KB...

  2. By ober (67.79.5.180) ober@linbsd.org on www.linbsd.org

    Glad you have HPPA asm down. Going to need assistance on the hppa port of OpenAFS as it's lwps require some to create process.s. I can go over it with you offline.

Latest Articles

Credits

Copyright © - Daniel Hartmeier. All rights reserved. Articles and comments are copyright their respective authors, submission implies license to publish on this web site. Contents of the archive prior to as well as images and HTML templates were copied from the fabulous original deadly.org with Jose's and Jim's kind permission. This journal runs as CGI with httpd(8) on OpenBSD, the source code is BSD licensed. undeadly \Un*dead"ly\, a. Not subject to death; immortal. [Obs.]