[SLOF] [PATCH] slof: Change call_c() function to a proper assembler function

Thomas Huth thuth at redhat.com
Tue Sep 15 18:36:21 AEST 2015


Using inline assembly for the call_c() function does not work
properly: Recent versions of the GCC compiler save some registers
to negative offsets on the stack before executing the inline
assembler code (to the so-called "red zone", which is OK according
to the ABI), since the compiler does not know that this assembler
code jumps to another function. However that other function might
also put some values on the stack, which can destroy the saved
values, causing weird effects or crashes.
To be on the save side, move the jump code to a proper assembler
file instead, so we do not have to make any bogus assumptions
for the inline assembly anymore.
This fixes the issue with "Cannot open file : fbuffer.fs" etc.
messages that occured with GCC versions >= 4.9

Signed-off-by: Thomas Huth <thuth at redhat.com>
---
 slof/entry.S |  9 +++++++++
 slof/ppc64.c | 19 +------------------
 2 files changed, 10 insertions(+), 18 deletions(-)

diff --git a/slof/entry.S b/slof/entry.S
index dcff57b..d3d29f8 100644
--- a/slof/entry.S
+++ b/slof/entry.S
@@ -207,4 +207,13 @@ call_client:
 	li 3, -1 # client app return
 	blr
 
+
+	# Call another function via pointer in r6
+	# (arguments can be provided in r3 to r5)
+	# Destination function should jump back to lr
+C_ENTRY(call_c)
+	mtctr	r6
+	bctr
+
+
 	.lcomm	the_system_stack, STACKSIZE, 16
diff --git a/slof/ppc64.c b/slof/ppc64.c
index 20d9270..619d95e 100644
--- a/slof/ppc64.c
+++ b/slof/ppc64.c
@@ -42,24 +42,7 @@ cell *the_heap_start = &the_heap[0];
 cell *the_heap_end = &the_heap[HEAP_SIZE / CELLSIZE];
 
 extern void io_putchar(unsigned char);
-
-
-static unsigned long __attribute__((noinline))
-call_c(cell arg0, cell arg1, cell arg2, cell entry)
-{
-	register unsigned long r3 asm("r3") = arg0.u;
-	register unsigned long r4 asm("r4") = arg1.u;
-	register unsigned long r5 asm("r5") = arg2.u;
-	register unsigned long r6 = entry.u         ;
-
-	asm volatile("mflr 31 ; mtctr %4 ; bctrl ; mtlr 31"
-		     : "=r" (r3)
-		     : "r" (r3), "r" (r4), "r" (r5), "r" (r6)
-		     : "ctr", "r6", "r7", "r8", "r9", "r10", "r11",
-		       "r12", "r13", "r31", "lr", "cc");
-
-	return r3;
-}
+extern unsigned long call_c(cell arg0, cell arg1, cell arg2, cell entry);
 
 
 long
-- 
1.8.3.1



More information about the SLOF mailing list