Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: arm64 r16, r17 register conflict between external linker and duffcopy in latest go release #46924

Jason7602 opened this issue Jun 25, 2021 · 1 comment


Copy link

@Jason7602 Jason7602 commented Jun 25, 2021

What version of Go are you using (go version)?

$ go version
go version go1.16.5 linux/arm64

We build our Go app on arm64. In a recent version, we encountered a segment violation error when it run. The problem is similar to that of #32773, but this time it occurs in different functions. Our product has a problem in runtime·duffcopy.
Here is a brief analysis of the segment error process
This is our product assembly code for a function,

   0x0000000012fe645c <+60>:	ldr	x21, [sp, #16]
   0x0000000012fe6460 <+64>:	str	x21, [sp, #152]
   0x0000000012fe6464 <+68>:	add	x0, x21, #0x38
   0x0000000012fe6468 <+72>:	ldr	x20, [sp, #632]
   0x0000000012fe64a0 <+128>:	add	x14, x21, #0x1c0
   0x0000000012fe64a4 <+132>:	add	x15, x20, #0x1c0
   0x0000000012fe64a8 <+136>:	add	x16, x21, #0x1f8  // put the stack space value to r16 
   0x0000000012fe64ac <+140>:	add	x17, x20, #0x1f8  // put the stack space value to r17 
   0x0000000012fe64b0 <+144>:	add	x19, x21, #0x230
   0x0000000012fe64b4 <+148>:	add	x22, x20, #0x230
   0x0000000012fe6624 <+516>:	mov	x21, x16  // put the x16's value to x21
   0x0000000012fe6628 <+520>:	mov	x20, x17 // put the x17's value to x21
   0x0000000012fe662c <+524>:	adr	x27, 0x12fe662c 
   0x0000000012fe6630 <+528>:	stp	x29, x27, [sp, #-24]
   0x0000000012fe6634 <+532>:	sub	x29, sp, #0x18
   0x0000000012fe6638 <+536>:	bl	0x1387d080 // jump to the duffcopy

then go to the duffcopy assembly code

    1387d080:   58000050        ldr     x16, 1387d088 
    1387d084:   d61f0200        br      x16
    1387d088:   0910a0e8        .inst   0x0910a0e8 ; undefined
    1387d08c:   00000000        .inst   0x00000000 ; undefined

the duffcopy's plan9 assembly code is

TEXT runtime·duffcopy(SB), NOSPLIT|NOFRAME, $0-0
	LDP.P	16(R20), (R26, R27)
	STP.P	(R26, R27), 16(R21)

	LDP.P	16(R20), (R26, R27)
	STP.P	(R26, R27), 16(R21)

so the br x16 will jump into 0x0910a0e8,

     910a0d8:   a8c16e9a        ldp     x26, x27, [x20], #16
     910a0dc:   a8816eba        stp     x26, x27, [x21], #16
     910a0e0:   a8c16e9a        ldp     x26, x27, [x20], #16
     910a0e4:   a8816eba        stp     x26, x27, [x21], #16
     910a0e8:   a8c16e9a        ldp     x26, x27, [x20], #16 
     910a0ec:   a8816eba        stp     x26, x27, [x21], #16 // here encounter panic
     910a0f0:   a8c16e9a        ldp     x26, x27, [x20], #16

So at this time the address in x21 (actually get value from the r16) is the address of the code segment. Then it went wrong
Actually @cherrymui submitted the CL184437 has already fixed this problem to some extend, but this CL still do not backport to the go1.16 or go1.15, so I strongly hope that the CL184437 can backport to the go1.16 version.

Does this issue reproduce with the latest release?


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants