internal/fakecgo: remove runtime.load_g references (#456)
Go 1.27 (golang/go@aee6009) enforces stricter checklinkname for assembly symbols. runtime.load_g is now //go:linknamestd (std-only), causing linker errors for non-std packages that reference it. In crosscall2, the load_g call is unnecessary because runtime.cgocallback already calls load_g internally. Remove it from all 6 architectures that had it (arm, arm64, loong64, ppc64le, riscv64, s390x). The amd64 and 386 variants already did not call it. In setg_trampoline on ppc64le, replace the load_g call with a direct assignment to the g register from the saved newg argument, since setg_gcc has already stored it into TLS. This resolves the runtime.load_g linker error. The runtime.cgocallback reference remains and will need an upstream Go change or the -ldflags='-checklinkname=0' workaround until then. Updates #455
- commit
- 1512f327e9958354283654ee4497800e33a7b838
- author
- George Adams · · 2026-05-27 13:07 UTC
- committer
- GitHub · · 2026-05-27 13:07 UTC
- parent
- 11272d2
- signature
- GPG Unverified
B5690EEEBB952194The key is unknown
7 files · +6 -14
M internal/fakecgo/asm_arm.s +0 -2
| @@ -32,8 +32,6 @@ TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0 | |||
| 32 | 32 | MOVD F14, (13*4+8*7)(R13) | |
| 33 | 33 | MOVD F15, (13*4+8*8)(R13) | |
| 34 | 34 | ||
| 35 | - | BL runtime·load_g(SB) | |
| 36 | - | ||
| 37 | 35 | // We set up the arguments to cgocallback when saving registers above. | |
| 38 | 36 | BL runtime·cgocallback(SB) | |
| 39 | 37 | ||
| @@ -32,8 +32,6 @@ TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0 | |||||
| 32 | MOVD F14, (13*4+8*7)(R13) | 32 | MOVD F14, (13*4+8*7)(R13) | ||
| 33 | MOVD F15, (13*4+8*8)(R13) | 33 | MOVD F15, (13*4+8*8)(R13) | ||
| 34 | 34 | ||||
| 35 | - | BL runtime·load_g(SB) | |||
| 36 | - | ||||
| 37 | // We set up the arguments to cgocallback when saving registers above. | 35 | // We set up the arguments to cgocallback when saving registers above. | ||
| 38 | BL runtime·cgocallback(SB) | 36 | BL runtime·cgocallback(SB) | ||
| 39 | 37 | ||||
M internal/fakecgo/asm_arm64.s +0 -1
| @@ -25,7 +25,6 @@ TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0 | |||
| 25 | 25 | STP (R29, R30), (8*22)(RSP) | |
| 26 | 26 | ||
| 27 | 27 | // Initialize Go ABI environment | |
| 28 | - | BL runtime·load_g(SB) | |
| 29 | 28 | BL runtime·cgocallback(SB) | |
| 30 | 29 | ||
| 31 | 30 | RESTORE_R19_TO_R28(8*4) | |
| @@ -25,7 +25,6 @@ TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0 | |||||
| 25 | STP (R29, R30), (8*22)(RSP) | 25 | STP (R29, R30), (8*22)(RSP) | ||
| 26 | 26 | ||||
| 27 | // Initialize Go ABI environment | 27 | // Initialize Go ABI environment | ||
| 28 | - | BL runtime·load_g(SB) | |||
| 29 | BL runtime·cgocallback(SB) | 28 | BL runtime·cgocallback(SB) | ||
| 30 | 29 | ||||
| 31 | RESTORE_R19_TO_R28(8*4) | 30 | RESTORE_R19_TO_R28(8*4) | ||
M internal/fakecgo/asm_loong64.s +0 -2
| @@ -27,8 +27,6 @@ TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0 | |||
| 27 | 27 | MOVV R1, (22*8)(R3) | |
| 28 | 28 | ||
| 29 | 29 | // Initialize Go ABI environment | |
| 30 | - | JAL runtime·load_g(SB) | |
| 31 | - | ||
| 32 | 30 | JAL runtime·cgocallback(SB) | |
| 33 | 31 | ||
| 34 | 32 | RESTORE_R22_TO_R31((4*8)) | |
| @@ -27,8 +27,6 @@ TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0 | |||||
| 27 | MOVV R1, (22*8)(R3) | 27 | MOVV R1, (22*8)(R3) | ||
| 28 | 28 | ||||
| 29 | // Initialize Go ABI environment | 29 | // Initialize Go ABI environment | ||
| 30 | - | JAL runtime·load_g(SB) | |||
| 31 | - | ||||
| 32 | JAL runtime·cgocallback(SB) | 30 | JAL runtime·cgocallback(SB) | ||
| 33 | 31 | ||||
| 34 | RESTORE_R22_TO_R31((4*8)) | 32 | RESTORE_R22_TO_R31((4*8)) | ||
M internal/fakecgo/asm_ppc64le.s +0 -3
| @@ -50,9 +50,6 @@ TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0 | |||
| 50 | 50 | // Initialize R0 to 0 as expected by Go | |
| 51 | 51 | MOVD $0, R0 | |
| 52 | 52 | ||
| 53 | - | // Load the current g. | |
| 54 | - | BL runtime·load_g(SB) | |
| 55 | - | ||
| 56 | 53 | // Set up arguments for cgocallback | |
| 57 | 54 | MOVD R3, FIXED_FRAME+0(R1) // fn unsafe.Pointer | |
| 58 | 55 | MOVD R4, FIXED_FRAME+8(R1) // a unsafe.Pointer | |
| @@ -50,9 +50,6 @@ TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0 | |||||
| 50 | // Initialize R0 to 0 as expected by Go | 50 | // Initialize R0 to 0 as expected by Go | ||
| 51 | MOVD $0, R0 | 51 | MOVD $0, R0 | ||
| 52 | 52 | ||||
| 53 | - | // Load the current g. | |||
| 54 | - | BL runtime·load_g(SB) | |||
| 55 | - | ||||
| 56 | // Set up arguments for cgocallback | 53 | // Set up arguments for cgocallback | ||
| 57 | MOVD R3, FIXED_FRAME+0(R1) // fn unsafe.Pointer | 54 | MOVD R3, FIXED_FRAME+0(R1) // fn unsafe.Pointer | ||
| 58 | MOVD R4, FIXED_FRAME+8(R1) // a unsafe.Pointer | 55 | MOVD R4, FIXED_FRAME+8(R1) // a unsafe.Pointer | ||
M internal/fakecgo/asm_riscv64.s +0 -1
| @@ -25,7 +25,6 @@ TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0 | |||
| 25 | 25 | SAVE_FPR((8*17)) | |
| 26 | 26 | ||
| 27 | 27 | // Initialize Go ABI environment | |
| 28 | - | CALL runtime·load_g(SB) | |
| 29 | 28 | CALL runtime·cgocallback(SB) | |
| 30 | 29 | ||
| 31 | 30 | RESTORE_GPR((8*4)) | |
| @@ -25,7 +25,6 @@ TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0 | |||||
| 25 | SAVE_FPR((8*17)) | 25 | SAVE_FPR((8*17)) | ||
| 26 | 26 | ||||
| 27 | // Initialize Go ABI environment | 27 | // Initialize Go ABI environment | ||
| 28 | - | CALL runtime·load_g(SB) | |||
| 29 | CALL runtime·cgocallback(SB) | 28 | CALL runtime·cgocallback(SB) | ||
| 30 | 29 | ||||
| 31 | RESTORE_GPR((8*4)) | 30 | RESTORE_GPR((8*4)) | ||
M internal/fakecgo/asm_s390x.s +0 -3
| @@ -27,9 +27,6 @@ TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0 | |||
| 27 | 27 | FMOVD F14, 80(R15) | |
| 28 | 28 | FMOVD F15, 88(R15) | |
| 29 | 29 | ||
| 30 | - | // Initialize Go ABI environment. | |
| 31 | - | BL runtime·load_g(SB) | |
| 32 | - | ||
| 33 | 30 | MOVD R2, 8(R15) // fn unsafe.Pointer | |
| 34 | 31 | MOVD R3, 16(R15) // a unsafe.Pointer | |
| 35 | 32 | ||
| @@ -27,9 +27,6 @@ TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0 | |||||
| 27 | FMOVD F14, 80(R15) | 27 | FMOVD F14, 80(R15) | ||
| 28 | FMOVD F15, 88(R15) | 28 | FMOVD F15, 88(R15) | ||
| 29 | 29 | ||||
| 30 | - | // Initialize Go ABI environment. | |||
| 31 | - | BL runtime·load_g(SB) | |||
| 32 | - | ||||
| 33 | MOVD R2, 8(R15) // fn unsafe.Pointer | 30 | MOVD R2, 8(R15) // fn unsafe.Pointer | ||
| 34 | MOVD R3, 16(R15) // a unsafe.Pointer | 31 | MOVD R3, 16(R15) // a unsafe.Pointer | ||
| 35 | 32 | ||||
M internal/fakecgo/trampolines_ppc64le.s +6 -2
| @@ -47,15 +47,19 @@ TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0-0 | |||
| 47 | 47 | ||
| 48 | 48 | // func setg_trampoline(setg uintptr, g uintptr) | |
| 49 | 49 | TEXT ·setg_trampoline(SB), NOSPLIT, $16-16 | |
| 50 | - | MOVD R31, 8(R1) // save R31 (load_g clobbers it) | |
| 50 | + | MOVD R31, 8(R1) // save R31 | |
| 51 | 51 | ||
| 52 | 52 | MOVD setg+0(FP), R12 | |
| 53 | 53 | MOVD newg+8(FP), R3 | |
| 54 | 54 | ||
| 55 | + | MOVD R3, 16(R1) // save newg before call | |
| 56 | + | ||
| 55 | 57 | MOVD R12, CTR | |
| 56 | 58 | CALL CTR | |
| 57 | 59 | ||
| 58 | - | CALL runtime·load_g(SB) | |
| 60 | + | // Assign g directly instead of calling runtime·load_g | |
| 61 | + | // setg_gcc has already stored newg into TLS; put it in the g register too. | |
| 62 | + | MOVD 16(R1), g | |
| 59 | 63 | ||
| 60 | 64 | MOVD 8(R1), R31 | |
| 61 | 65 | XOR R0, R0, R0 | |
| @@ -47,15 +47,19 @@ TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0-0 | |||||
| 47 | 47 | ||||
| 48 | // func setg_trampoline(setg uintptr, g uintptr) | 48 | // func setg_trampoline(setg uintptr, g uintptr) | ||
| 49 | TEXT ·setg_trampoline(SB), NOSPLIT, $16-16 | 49 | TEXT ·setg_trampoline(SB), NOSPLIT, $16-16 | ||
| 50 | - | MOVD R31, 8(R1) // save R31 (load_g clobbers it) | 50 | + | MOVD R31, 8(R1) // save R31 |
| 51 | 51 | ||||
| 52 | MOVD setg+0(FP), R12 | 52 | MOVD setg+0(FP), R12 | ||
| 53 | MOVD newg+8(FP), R3 | 53 | MOVD newg+8(FP), R3 | ||
| 54 | 54 | ||||
| 55 | + | MOVD R3, 16(R1) // save newg before call | |||
| 56 | + | ||||
| 55 | MOVD R12, CTR | 57 | MOVD R12, CTR | ||
| 56 | CALL CTR | 58 | CALL CTR | ||
| 57 | 59 | ||||
| 58 | - | CALL runtime·load_g(SB) | 60 | + | // Assign g directly instead of calling runtime·load_g |
| 61 | + | // setg_gcc has already stored newg into TLS; put it in the g register too. | |||
| 62 | + | MOVD 16(R1), g | |||
| 59 | 63 | ||||
| 60 | MOVD 8(R1), R31 | 64 | MOVD 8(R1), R31 | ||
| 61 | XOR R0, R0, R0 | 65 | XOR R0, R0, R0 | ||