[rt.cpan.org #77677] x64 asm is broken for ::API, >4 param crash

[email protected] ("bulk88 via RT")
Newsgroups perl.libwin32
Message-ID <[email protected]>
Wed Jun 06 19:35:56 2012: Request 77677 was acted upon.
Transaction: Ticket created by bulk88.
       Queue: Win32-API
     Subject: x64 asm is broken for ::API, >4 param crash
   Broken in: 0.68
    Severity: Normal
       Owner: Nobody
  Requestors: [email protected]
      Status: new
 Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=77677 >


If there are over 4 parameters on x64 with GCC, there is a crash.
Remember every function on x64 has 4 parameters without exception. RSI
and R10 is filled with garbage with the 2 POPs at the end. The stack
pusher loop is broken. RSI in Call_asm is the retval struct pointer on
-O2 (strawberry perl's default). On -O0 it doesn't crash, IDK and don't
care why.
________________________

.globl Call_x64_real
Call_x64_real:

	pushq	%rbp
	movq	%rsp,%rbp
	subq	$32,%rsp	# keep space for 4 64bit params

ADD 32 to RSP A FIXED AMOUNT

	# Store register parameters 
	movq    %rcx,16(%rbp)	# ApiFunction
	movq    %rdx,24(%rbp)	# int_registers
	movq    %r8,32(%rbp)	# float_registers
	movq    %r9,40(%rbp)	# stack

	# Save regs we are gonna use
	pushq	%rsi
ADD 8 to RSP A FIXED AMOUNT
	pushq	%r10
ADD 8 to RSP A FIXED AMOUNT

	# Load up integer registers first... 
	movq    24(%rbp),%rax	# rax = int_registers
	movq    (%rax),%rcx
	movq    8(%rax),%rdx
	movq    16(%rax),%r8
	movq    24(%rax),%r9

	# Now floating-point registers 
	movq	32(%rbp),%rax	# rax = float_registers
	movsd	(%rax),%xmm0
	movsd	8(%rax),%xmm1
	movsd	16(%rax),%xmm2
	movsd	24(%rax),%xmm3

	# Now the stack 
	movq	40(%rbp),%rsi	# rsi = stack
	movq	48(%rbp),%rax	# rax = nstack
NSTACK IS NUMBER OF STACK PARAMS
FROM Call_asm
	required_stack = nparams > 4 ? nparams - 4 : 0;
NSTACK IS required_stack IN THE CALLER Call_asm
END COMMENT

	# Except not if there isn't any 
	testq	%rax,%rax
	je	docall

copystack:
	subq	$1,%rax
	movq	(%rsi,%rax,8),%r10
	pushq	%r10
ADD MANY 8s TO RSP THIS IS A LOOP VARIABLE AMOUNT
	testq	%rax,%rax
	jne	copystack

docall:
	# And call
	movq	16(%rbp),%r10   # r10 = ApiFunction
	subq	$32,%rsp	# Microsoft x64 calling convention - allocate 32 bytes of
"shadow space" on the stack

ADD 32 TO RSP, A FIXED AMOUNT

	callq	*%r10
	addq	$32,%rsp	# restore stack

REMOVE 32 FROM RSP, A FIXED AMOUNT

	# Store return value
	movq	56(%rbp),%r10	# r10 = iret
	movq	%rax,(%r10)
	movq	64(%rbp),%r10	# r10 = dret
	movsd	%xmm0,(%r10)
 
	# Restore regs
	popq	%r10
REMOVE 8 FROM RSP, A FIXED AMOUNT
	popq	%rsi
REMOVE 8 FROM RSP, A FIXED AMOUNT
	movq	%rbp,%rsp
	popq	%rbp
	retq
____________________________________________
This bug is in the public 0.68, and my personal API versions
(0.69/0.70). Its only on x64 and on GCC Perl. I'll investigate whether
the same bug is in MSVC x64 side.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.