Skip to content

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

@Jason7602

Description

@Jason7602

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?

Yes

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions