[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