521 lines
9.6 KiB
Markdown
521 lines
9.6 KiB
Markdown
|
|
# Portable Stack Manipulation
|
|||
|
|
|
|||
|
|
This crate provides very portable functions to control the stack pointer and inspect the properties
|
|||
|
|
of the stack. This crate does not attempt to provide safe abstractions to any operations, the
|
|||
|
|
only goals are correctness, portability and efficiency (in that exact order). As a consequence most
|
|||
|
|
functions you’ll see in this crate are unsafe.
|
|||
|
|
|
|||
|
|
Unless you’re writing a safe abstraction over stack manipulation, this is not the crate you
|
|||
|
|
want. Instead consider one of the safe abstractions over this crate. A good place to look at is
|
|||
|
|
the crates.io’s reverse dependency list.
|
|||
|
|
|
|||
|
|
# Platform support
|
|||
|
|
|
|||
|
|
The following table lists supported targets and architectures with notes on the level of current
|
|||
|
|
support and knowledge about the target. The three columns “Available”, “Tested” and “Callstack”
|
|||
|
|
imply an increasingly high level of support.
|
|||
|
|
|
|||
|
|
* “Available” basically means that the code builds and the assembly files have been written for the
|
|||
|
|
target;
|
|||
|
|
* “Tested” means that the assembly code has been tested or otherwise verified to be correct. For
|
|||
|
|
most targets it also means that continuous integration is set up;
|
|||
|
|
* “Callstack” means that the assembly code has been written with due care to support unwinding the
|
|||
|
|
stack and displaying the call frames (i.e. `gdb backtrace` works as expected).
|
|||
|
|
|
|||
|
|
<table>
|
|||
|
|
<tr>
|
|||
|
|
<th rowspan="1" colspan="2">Target</th>
|
|||
|
|
<th colspan="3">Support</th>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<th rowspan="2">Architecture</th>
|
|||
|
|
<th rowspan="2">OS</th>
|
|||
|
|
<th>Available</th>
|
|||
|
|
<th>Tested</th>
|
|||
|
|
<th>Callstack</th>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<th colspan="3">Notes</th>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="6">x86_64</td>
|
|||
|
|
<td rowspan="2">apple-ios</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
Target has been tested locally.
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">windows</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes, but disabled</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
Stacks allocated the usual way are not valid to be used on Windows and the functions to allocate a
|
|||
|
|
stack in a proper way is a Windows implementation detail. As a (unnecessarily slow and inflexible)
|
|||
|
|
alternative use [Fibers][fibers].
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">*</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td></td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="8">i686<br>i586<br>i386</td>
|
|||
|
|
<td rowspan="2">apple-ios</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">linux-android</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
The assembly files are available, but the target hasn’t been verified to build
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">windows</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
The code technically works on my local machine, but exception handling does not correctly work on
|
|||
|
|
appveyor, which makes me unwilling to mark this as working yet.
|
|||
|
|
|
|||
|
|
Stacks allocated the usual way are not valid to be used on Windows and the functions to allocate a
|
|||
|
|
stack in a proper way is a Windows implementation detail. As a (unnecessarily slow and inflexible)
|
|||
|
|
alternative use [Fibers][fibers].
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">*</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="8">aarch64</td>
|
|||
|
|
<td rowspan="2">apple-ios</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
aarch64-apple-ios has not been tested. iOS hardware is necessary to run these tests.
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">fuchsia<br>unknown-cloudabi</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">windows</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
Stacks allocated the usual way are not valid to be used on Windows and the functions to allocate a
|
|||
|
|
stack in a proper way is a Windows implementation detail. As a (unnecessarily slow and inflexible)
|
|||
|
|
alternative use [Fibers][fibers].
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">*</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="6">arm<br>armv7</td>
|
|||
|
|
<td rowspan="2">apple-ios</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
armv7-apple-ios has not been tested. iOS hardware is necessary to run these tests.
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">windows</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
Stacks allocated the usual way are not valid to be used on Windows and the functions to allocate a
|
|||
|
|
stack in a proper way is a Windows implementation detail. As a (unnecessarily slow and inflexible)
|
|||
|
|
alternative use [Fibers][fibers].
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">*</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">armv5te</td>
|
|||
|
|
<td rowspan="2">*</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">thumbv6<br>thumbv7</td>
|
|||
|
|
<td rowspan="2">*</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">mips<br>mipsel</td>
|
|||
|
|
<td rowspan="2">linux</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
Only the o32 ABI is supported and will be used for all 32-bit MIPS targets.
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">mips64<br>mips64el</td>
|
|||
|
|
<td rowspan="2">linux</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">powerpc</td>
|
|||
|
|
<td rowspan="2">linux</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
Callstack generation may fail at certain well defined ranges of the program, although the usual
|
|||
|
|
compiler-generated code fails at similar points itself.
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="4">powerpc64</td>
|
|||
|
|
<td rowspan="2">linux</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
Callstack generation may fail at certain well defined ranges of the program, although the usual
|
|||
|
|
compiler-generated code fails at similar points itself.
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">AIX</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">powerpc64le</td>
|
|||
|
|
<td rowspan="2">linux</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
Callstack generation may fail at certain well defined ranges of the program, although the usual
|
|||
|
|
compiler-generated code fails at similar points itself.
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">s390x</td>
|
|||
|
|
<td rowspan="2">linux</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Locally</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
Test runner on CI hangs, local verification has been done on a qemu-system-s390x VM. It may be
|
|||
|
|
possible to add CI testing in the future via qemu’s full-system emulation.
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">sparc</td>
|
|||
|
|
<td rowspan="2">linux</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
A Rust target for 32-bit SPARC exists, but no Linux distributions actually have a 32-bit SPARC
|
|||
|
|
distribution, so verification is infeasible.
|
|||
|
|
|
|||
|
|
The actual assembly code has been written conservatively, modelled after the 64-bit SPARC code.
|
|||
|
|
and so has a non-zero chance of working.
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">sparc64</td>
|
|||
|
|
<td rowspan="2">linux</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Locally</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
Has been manually verified to work on the [GCC Farm Project] machines. It may be possible to
|
|||
|
|
add CI testing in the future via qemu’s full-system emulation.
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">sparc9</td>
|
|||
|
|
<td rowspan="2">solaris</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
Uses the same assembly as the sparc64-linux-gnu target. This target has no rustc builds and
|
|||
|
|
therefore the correct operation of this target could not be verified at the moment.
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">wasm</td>
|
|||
|
|
<td rowspan="2">*</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
This library is not applicable to the target. WASM hasn’t a specified C ABI, the callstack is
|
|||
|
|
not even in an address space and does not appear to be manipulatable.
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">asmjs</td>
|
|||
|
|
<td rowspan="2">*</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
Feasibility/necessity hasn’t been acertained.
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">nvptx</td>
|
|||
|
|
<td rowspan="2">*</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
Feasibility/necessity hasn’t been acertained.
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">msp430</td>
|
|||
|
|
<td rowspan="2">*</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
Haven’t gotten to it yet...
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">riscv32</td>
|
|||
|
|
<td rowspan="2">*</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>No</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
Although the assembly code has not been tested, it is a straightforward copy of the 64-bit version.
|
|||
|
|
Unless there is a non-obvious mistake, this should work fine.
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">riscv64</td>
|
|||
|
|
<td rowspan="2">*</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Locally</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
The assembly code for riscv64 has been tested locally with a C caller.
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
|
|||
|
|
<tr>
|
|||
|
|
<td rowspan="2">loongarch64</td>
|
|||
|
|
<td rowspan="2">*</td>
|
|||
|
|
<td>Yes</td>
|
|||
|
|
<td>Locally</td>
|
|||
|
|
<td>Unknown</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td colspan="3">
|
|||
|
|
|
|||
|
|
The assembly code for loongarch64 has been tested locally with a C caller.
|
|||
|
|
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
</table>
|
|||
|
|
|
|||
|
|
[GCC Farm Project]: https://cfarm.tetaneutral.net/
|
|||
|
|
[fibers]: https://docs.microsoft.com/en-gb/windows/desktop/ProcThread/fibers
|
|||
|
|
|
|||
|
|
# License
|
|||
|
|
|
|||
|
|
PSM is licensed under either of
|
|||
|
|
|
|||
|
|
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
|||
|
|
https://www.apache.org/licenses/LICENSE-2.0)
|
|||
|
|
* MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
|||
|
|
https://opensource.org/licenses/MIT)
|
|||
|
|
|
|||
|
|
at your option.
|