[klibc] [PATCH] ppc64: ELFv2: Load TOC value in system call stub
Mauricio Faria de Oliveira
mauricfo at linux.vnet.ibm.com
Tue Sep 9 15:26:32 PDT 2014
On 09/09/2014 07:17 PM, Mauricio Faria de Oliveira wrote:
> This fixes a segmentation fault in the system call's error handling path with
> dynamically-linked binaries on PowerPC64 little endian. The system call stub
> wasn't loading up r2 with the appropriate TOC value in its global entry point.
Test results on Debian ppc64el. Probably too detailed, but documented.
Before:
-------
Test-case:
'stat.shared' segfaults with a non-existing file
$ rm -f no-file
$ usr/klibc/tests/stat no-file
no-file: No such file or directory
$ usr/klibc/tests/stat.shared no-file
Segmentation fault
Test-suite:
Comparing statically- vs. dinamically-linked binaries.
One difference: fcntl's return code.
$ find usr/klibc/tests/ -type f -executable -not -name '*.g' -not -name
'*.shared' \
| while read test; do $test >/dev/null 2>&1; rc=$?; [ $rc -ne 0 ]
&& echo "failed: $test (rc: $rc)"; done | sort
failed: usr/klibc/tests/fcntl (rc: 1)
failed: usr/klibc/tests/fnmatch (rc: 139)
failed: usr/klibc/tests/testrand48 (rc: 1)
$ find usr/klibc/tests/ -type f -executable -not -name '*.g' -name
'*.shared' \
| while read test; do $test >/dev/null 2>&1; rc=$?; [ $rc -ne 0 ]
&& echo "failed: $test (rc: $rc)"; done | sort
failed: usr/klibc/tests/fcntl.shared (rc: 139)
failed: usr/klibc/tests/fnmatch.shared (rc: 139)
failed: usr/klibc/tests/testrand48.shared (rc: 1)
Generated instructions:
No r2 setup before branch to local entry point (+8 offset).
(gdb) disass
Dump of assembler code for function stat:
=> 0x000000000f007854 <+0>: li r0,106
0x000000000f007858 <+4>: sc
0x000000000f00785c <+8>: bnslr
0x000000000f007860 <+12>: b 0xf012cb4 <__syscall_error+8>
End of assembler dump.
After:
-----
Test-case:
'stat.shared' no longer segfaults with a non-existing file
$ rm -f no-file
$ usr/klibc/tests/stat no-file
no-file: No such file or directory
$ usr/klibc/tests/stat.shared no-file
no-file: No such file or directory
Test-suite:
No regressions introduced.
No differences between statically- vs. dynamically-linked binaries.
$ find usr/klibc/tests/ -type f -executable -not -name '*.g' -not -name
'*.shared' | while read test; do $test >/dev/null 2>&1; rc=$?; [ $rc -ne
0 ] && echo "failed: $test (rc: $rc)"; done | sort
failed: usr/klibc/tests/fcntl (rc: 1)
failed: usr/klibc/tests/fnmatch (rc: 139)
failed: usr/klibc/tests/testrand48 (rc: 1)
$ find usr/klibc/tests/ -type f -executable -not -name '*.g' -name
'*.shared' | while read test; do $test >/dev/null 2>&1; rc=$?; [ $rc -ne
0 ] && echo "failed: $test (rc: $rc)"; done | sort
failed: usr/klibc/tests/fcntl.shared (rc: 1)
failed: usr/klibc/tests/fnmatch.shared (rc: 139)
failed: usr/klibc/tests/testrand48.shared (rc: 1)
Generated instructions
Now r2 _is_ setup before branch to local entry point (+8 offset).
(gdb) disass
Dump of assembler code for function stat:
=> 0x000000000f007a84 <+0>: lis r2,3843
0x000000000f007a88 <+4>: addi r2,r2,-3816
0x000000000f007a8c <+8>: li r0,106
0x000000000f007a90 <+12>: sc
0x000000000f007a94 <+16>: bnslr
0x000000000f007a98 <+20>: b 0xf0131cc <__syscall_error+8>
End of assembler dump.
--
Mauricio Faria de Oliveira
IBM Linux Technology Center
More information about the klibc
mailing list