This is the mail archive of the glibc-bugs@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libc/612] makecontext broken on powerpc-linux


------- Additional Comments From sjmunroe at us dot ibm dot com  2004-12-20 21:13 -------
This is a bad testcase coupled with internal changes to PPC ucontext_t to 
maintian backward compat and accomadate VMX (Altivec) which requires stonger 
alignment then the base ucontext_t.

>From the IEEE Std 1003.1, 2004:

"The uc_link member is used to determine the context that shall be resumed 
when the context being modified by makecontext() returns. The application 
shall ensure that the uc_link member is initialized prior to the call to 
makecontext().

The swapcontext() function shall save the current context in the context 
structure pointed to by oucp and shall set the context to the context 
structure pointed to by ucp."

If they had used swapcontext as suggested to create the resume context (oucp) 
it would have worked. Instead they used getcontext then made a copy (via 
memcpy) to another ucontext_t for the resume context (oucp) pointed to by the 
uc_link. 

This works on some architecture but the PPC ucontext_t contains internal 
pointers. From ucontext.h:

     * Different versions of the kernel have stored the registers on
     * signal delivery at different offsets from the ucontext struct.
     * Programs should thus use the uc_mcontext.uc_regs pointer to
     * find where the registers are actually stored.  The registers
     * will be stored within the ucontext_t struct but not necessarily
     * at a fixed address.  As a side-effect, this lets us achieve
     * 16-byte alignment for the register storage space if the
     * Altivec registers are to be saved, without requiring 16-byte
     * alignment on the whole ucontext_t.

So when the 1st ucontext_t (ucp) was copied to the 2nd ucontext_t (oucp) the 
uc_mcontext.uc_regs pointer still pointed back into the 1st ucontext_t. Then 
makecontext(ucp, ...) modified (ucp) to dispatch t1_func() (which effectively 
changes both contexts!)

When t1_func() returns, it branches to code in makecontext which follows 
uc_link to get the address of the resume context. Makecontext then calls 
setcontext to dispatch the resume context. But as the resume context (oucp) 
contains a uc_regs that points back into the context modified by makecontext 
we have an infinite loop (makecontaxt resume, setcontext, t1_func, ...)

Net you can't JUST COPY ucontexts on PPC because of the uc_regs pointer. PPC64 
does not fail in this case becuase gregset_t is at a fixed offset. But VMX 
registers (if used) are accessed via an internal mcontext.v_regs pointer 
(allows for internal quadword allignment). So a PPC64 testcase programmed this 
way and dependent on VMX state might also fail. Net any platform where the 
ucontext_t contains internal pointers is likely to fail this testcase.

But if the testcase did not copy the ucontext and instead used swapcontext to 
create the resume context call platforms should work.



-- 


http://sources.redhat.com/bugzilla/show_bug.cgi?id=612

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]