adds x86 stack pointer handling for external calls #955
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
For x86 and x86_64 ABI it is the responsibility of the callee to pop the return address from the stack pointer and increase the stack pointer. Since the code of external functions is not present in the binary, every time an external function is called, the stack grows without being corrected. In case if the base pointer is not used (e.g., in optimized code, or if the no-frame-pointer option was specified) this will also lead to the stack corruption as all variables will shift. This corruption results in an incorrect interpretation of a program and in case of taint analysis will introduce aliasing between neighboring stack variables.
The solution is to appropriately increase the stack pointer every time we return from a call from the Lisp Machine back to the Primus Machine. This will correctly handle three cases:
In the latter will work correctly, because all external functions that are not linked explicitly, are implicitly linked to a special function __primus_linker_unresolved_call, which in turn is overridden by the primus:handle-unresolved-names function, therefore an unlinked external function will still end up with a Lisp machine call. The same is true, if a function is overridden without using the Lisp Machine, directly from the Linker.
Obviously, this patch relies on the presence of the Lisp machine and if the Lisp Machine is not loaded, the stack pointer will not be corrected.
This patch will also misbehave, if a local static function that is not ABI comformant is overridden by a Lisp stub. In that case it is the responsibility of the Lisp stub to properly correct the stack pointer.
A better solution is still being sought, but so far this is the best option we have.
Resolves #879