Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ia64: fix small struct return #407

Merged
merged 2 commits into from
Mar 11, 2018
Merged

ia64: fix small struct return #407

merged 2 commits into from
Mar 11, 2018

Conversation

trofi
Copy link
Contributor

@trofi trofi commented Feb 17, 2018

No description provided.

Sergei Trofimovich added 2 commits February 17, 2018 18:53
The bug originally was discovered in https://bugs.gentoo.org/634190
where complicated callback was returning invalid data on ia64.

This change adds minimal reproducer that fails only on ia64 as:

FAIL: libffi.call/struct10.c -W -Wall -Wno-psabi -O0 execution test
FAIL: libffi.call/struct10.c -W -Wall -Wno-psabi -O2 execution test
FAIL: libffi.call/struct10.c -W -Wall -Wno-psabi -O3 execution test
FAIL: libffi.call/struct10.c -W -Wall -Wno-psabi -Os execution test

Test passes on amd64. The fix is in the following commit.

Bug: https://bugs.gentoo.org/634190
Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
This change fixes libffi.call/struct10.c failure on ia64:
FAIL: libffi.call/struct10.c -W -Wall -Wno-psabi -O0 execution test

.Lst_small_struct handles returns for structs less than 32 bytes
(following ia64 return value ABI [1]). Subroutine does roughly the
following:

```
    mov [sp+0]  = r8
    mov [sp+8]  = r9
    mov [sp+16] = r10
    mov [sp+24] = r11
    memcpy(destination, source=sp, 12);
```

The problem: ia64 ABI guarantees that top 16 bytes of stack are
scratch space for callee function. Thus it can clobber it. [1]
says (7.1 Procedure Frames):
"""
* Scratch area. This 16-byte region is provided as scratch storage
  for procedures that are called by the current procedure. Leaf
  procedures do not need to allocate this region. A procedure may
  use the 16 bytes at the top of its own frame as scratch memory,
  but the contents of this area are not preserved by a procedure call.
"""

In our case 16 top bytes are clobbered by a PLT resolver when memcpy()
is called for the first time. As a result memcpy implementation reads
already clobbered data frop top of stack.

The fix is simple: allocate 16 bytes of scrats space prior to memcpy()
call.

[1]: https://www.intel.com/content/dam/www/public/us/en/documents/guides/itanium-software-runtime-architecture-guide.pdf

Bug: https://bugs.gentoo.org/634190
Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
gentoo-bot pushed a commit to gentoo/gentoo that referenced this pull request Feb 17, 2018
@atgreen atgreen merged commit 83d9aba into libffi:master Mar 11, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants