Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bug 1238661 - fix mozilla::SignalTrampoline to work properly with cla…
…ng; r=darchons mozilla::SignalTrampoline is designed to work around a bug in older ARM kernels; it constructs a trampoline function with a NOP slide and then calls a specified function. This feat is accomplished using inline assembly and naked functions, which is a GCC extension where you get to write the entire body of your function using GCC inline assembly. Unfortunately, the particular implementation that it uses requires the specified function's address to be loaded into a register. GCC permits this and we use input arguments to the assembly statement to ensure that GCC knows it shouldn't clobber the incoming argument registers when trying to load the function's address. clang, however, complains about the use of input parameters in naked functions. So we need to find something that will work on both GCC and clang. The trick is to realize that we're a) tail-calling the specified function and b) we don't have to worry about calling a fully-general function. We just have to worry about calling a function inside libxul, and we can therefore "assume" that the offset between the branch and the called function fits into the immediate field of a Thumb (or ARM) branch instruction. (This assumption is not strictly true; the branch range is +/-16MB or so and libxul is actually quite a bit bigger than that. But it works in practice, and the linker will insert branch stubs if necessary to make things work out OK.) The upshot is that we can use a "b" instruction instead of a "bx" instruction, and this makes clang much happier. As a small bonus, the stub gets ever-so-much-more efficient, which is probably the least-significant micro-optimization ever.
- Loading branch information