Subject: bin/2586: dynamically linked functions returning structures will not work
To: None <gnats-bugs@NetBSD.ORG>
From: None <Juergen.Fluk@lrz.tu-muenchen.de>
List: netbsd-bugs
Date: 07/01/1996 14:03:31
>Number:         2586
>Category:       bin
>Synopsis:       dynamically linked functions returning structures will not work
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jul  1 08:35:06 1996
>Last-Modified:
>Originator:     Matthias Pfaller
>Organization:
	marco GmbH, Dachau, Germany
>Release:        1.2_ALPHA
>Environment:
	<machine, os, target, libraries (multiple lines)>
System: NetBSD klondike 1.2_ALPHA NetBSD 1.2_ALPHA (KLONDIKE) #9: Sun Jun 23 01:24:08 MET DST 1996 leo@klondike:/usr/src/sys/arch/pc532/compile/KLONDIKE pc532


>Description:
	The code in src/gnu/usr.bin/ld/ns32k/mdprologue.S:binder_entry
	does not preserve the compiler scratch registers r1 and r2.
	When a function returns a structure, gcc uses r2 to pass the
	address of the destination structure. This information gets
	destroyed when the function is called through binder_entry.
	r1 may be used to pass the static chain information and should
	be preserved as well. I think this fix should go into NetBSD-1.2.
	BTW, binder was called from binder_entry in the form
		binder(PLTslot, index)
	From reading src/gnu/usr.bin/ld/rtld/rtld.c, the binder function
	does not seem to need the index argument. I have removed this
	additional push from the ns32k version. The i386, m68k and sparc
	versions of mdprologue.S all do this push. Should this get removed
	there as well?
>How-To-Repeat:
>Fix:
--- src/gnu/usr.bin/ld/ns32k/mdprologue.S.ORIG	Sat Oct 14 01:33:25 1995
+++ src/gnu/usr.bin/ld/ns32k/mdprologue.S	Sat Jun 29 23:08:35 1996
@@ -64,11 +64,13 @@
  */
 
 _binder_entry:
-	movd	tos,r1			/* grab return address (within PLT) */
-	movd	r0,tos			/* save r0 (for cerror)		*/
-	movzwd	0(r1),tos		/* get function index		*/
-	addr	-6(r1),tos		/* point to PLT slot		*/
+	save	[r0,r1,r2]		/* preserve scratch registers	*/
+					/* save r0 (for cerror) 	*/
+					/* save r1 (maybe static chain) */
+					/* save r2 (maybe struct addr)	*/
+	addr	-6(12(sp)),tos		/* push address of PLT slot	*/
 	bsr	_binder			/* relocate function address	*/
-	movd	r0,tos			/* prepare for jump		*/
-	movd	12(sp),r0		/* restore r0			*/
-	ret	12			/* jump into function		*/
+	cmpqd	0,tos
+	movd	r0,12(sp)		/* prepare for jump		*/
+	restore	[r0,r1,r2]		/* restore scratch registers	*/
+	ret	0			/* jump into function		*/

>Audit-Trail:
>Unformatted: