clangupc / clang-upc

Clang UPC Front-End
https://clangupc.github.io/
Other
16 stars 5 forks source link

"random" relocation with cupc+upcr on OpenBSD w/ struct-PTS #71

Closed PHHargrove closed 10 years ago

PHHargrove commented 10 years ago

Tests of clang-upc with upcr on OpenBSD and configured for the struct PTS representation is failing bug3079 from the Berkeley test suite.

That test exercises the bupc_inverse_cast() extension in UPCR. This extension takes a pointer-to-private referencing a UPC shared object (with affinity to the calling thread or any other that is addressable by load/store) and converts it to a pointer-to-shared. This operation is sensitive to the actual addresses of the shared heap, while virtually everything else in the system works from offsets which can be more or less arbitrary.

The problem (as best as I can tell) is that OpenBSD is using PIE (position independent executable) as its default ABI. This is resulting in the symbol __upc_shared_start being assigned a random address, and breaking the implementation of bupc_inverse_cast().

I am experimenting now to see if disabling the linker script helps, or if there is a way to disable PIE that could fix the problem. If necessary, I may be able to solve this from the UPCR side by changing the implementation with PIE is in use.

PHHargrove commented 10 years ago

Experiments with disabling the linker script or passing -nopie to the linker didn't work. I won't go into the details here (at least not now).

I believe that the proper solution is probably a more robust implementation of bupc_inverse_cast() in UPCR, one that is as insensitive to the offsets as the reset of the system.

PHHargrove commented 10 years ago

If I both disable the linker script and link with -nopie then at least some initial tests appear to pass. Since linker script was generated with PIE enabled, it appears one needs to make both changes. However, I suspect that passing -nopie while generating the linker script might resolve everything in one step.

PHHargrove commented 10 years ago

This appears to be a problem with UPCR's implementation of bupc_inverse_cast() which cannot currently handle the case of an arbitrary upcri_linksegstart. The code attempts to determine if the pointer-to-local argument references a shared heap location by computing the addrfield and bounds checking against the range [0,heap size). Since the addrfield is offset by upcri_linksegstart this works for segment starts of 0 (and for PAGE_SIZE except for arguments in the last page of the heap), but does NOT work for the present case of an arbitrarily large offset.

While this has turned out to be a UPCR bug, I am leaving the tracking here.

PHHargrove commented 10 years ago

Fix in UPCR (on the 'develop' branch) in 4bf413f.