Print this page
patch feedback

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libc/i386/gen/makectxt.c
          +++ new/usr/src/lib/libc/i386/gen/makectxt.c
↓ open down ↓ 41 lines elided ↑ open up ↑
  42   42   * When makecontext() returns, the ucontext_t will be set to run the
  43   43   * given function with the given parameters on the stack specified by
  44   44   * uc_stack, and which will return to the ucontext_t specified by uc_link.
  45   45   */
  46   46  
  47   47  /*
  48   48   * The original i386 ABI said that the stack pointer need be only 4-byte
  49   49   * aligned before a function call (STACK_ALIGN == 4).  The ABI supplement
  50   50   * version 1.0 changed the required alignment to 16-byte for the benefit of
  51   51   * floating point code compiled using sse2.  The compiler assumes this
  52      - * alignment and maintains it for calls made from that function.  If the
  53      - * stack is initially properly aligned, it will continue to be so aligned.
  54      - * If it is not initially so aligned, it will never become so aligned.
       52 + * alignment and maintains it for calls it generates.  If the stack is
       53 + * initially properly aligned, it will continue to be so aligned.  If it is
       54 + * not initially so aligned, it will never become so aligned.
  55   55   *
  56   56   * One slightly confusing detail to keep in mind is that the 16-byte
  57   57   * alignment (%esp & 0xf == 0) is true just *before* the call instruction.
  58   58   * The call instruction will then push a return value, decrementing %esp by
  59   59   * 4.  Therefore, if one dumps %esp at the at the very first instruction in
  60   60   * a function, it will end with a 0xc.  The compiler expects this and
  61   61   * compensates for it properly.
  62   62   *
  63   63   * Note: If you change this value, you need to change it in the following
  64   64   * files as well:
↓ open down ↓ 15 lines elided ↑ open up ↑
  80   80          va_list ap;
  81   81          size_t size;
  82   82  
  83   83          ucp->uc_mcontext.gregs[EIP] = (greg_t)func;
  84   84  
  85   85          size = sizeof (long) * (argc + 1);
  86   86  
  87   87          tsp = (long *)(((uintptr_t)ucp->uc_stack.ss_sp +
  88   88              ucp->uc_stack.ss_size - size) & ~(STACK_ALIGN - 1));
  89   89  
       90 +        /*
       91 +         * Since we're emulating the call instruction, we must push the
       92 +         * return address (which involves adjusting the stack pointer to
       93 +         * have the proper 4-byte bias).
       94 +         */
  90   95          sp = tsp - 1;
  91   96  
  92      -        va_start(ap, argc);
  93      -
  94      -        while (argc-- > 0) {
  95      -                *tsp++ = va_arg(ap, long);
  96      -        }
  97      -
  98      -        va_end(ap);
  99      -
 100   97          *sp = (long)resumecontext;              /* return address */
 101   98  
 102   99          ucp->uc_mcontext.gregs[UESP] = (greg_t)sp;
      100 +
      101 +        /*
      102 +         * "push" all the arguments
      103 +         */
      104 +        va_start(ap, argc);
      105 +        while (argc-- > 0)
      106 +                *tsp++ = va_arg(ap, long);
      107 +        va_end(ap);
 103  108  }
 104  109  
 105  110  
 106  111  static void
 107  112  resumecontext(void)
 108  113  {
 109  114          ucontext_t uc;
 110  115  
 111  116          (void) getcontext(&uc);
 112  117          (void) setcontext(uc.uc_link);
 113  118  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX