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
--
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org