From 0630024b2bfb0724598a8dbccc5aa568b4379311 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Mon, 2 Aug 2021 09:34:49 +0200 Subject: [PATCH] switch from assembly stubs to go:linkname comment The go:linkname way works with Go 1.17 (with regabi), too. Upstream did this in 2015 in https://github.com/golang/go/commit/0b8d583320b2f6247669ef0bb1ba011054ca1c88 See also https://sitano.github.io/2016/04/28/golang-private/ for more background about both techniques. --- internal/buffer/out_message.go | 6 +-- internal/buffer/out_message_test.go | 2 +- internal/buffer/runtime.go | 6 ++- internal/buffer/runtime_go1.8.s | 40 ------------------- .../buffer/{runtime_other.s => runtimestub.s} | 30 ++------------ 5 files changed, 12 insertions(+), 72 deletions(-) delete mode 100644 internal/buffer/runtime_go1.8.s rename internal/buffer/{runtime_other.s => runtimestub.s} (53%) diff --git a/internal/buffer/out_message.go b/internal/buffer/out_message.go index 3c821f6..7e89afb 100644 --- a/internal/buffer/out_message.go +++ b/internal/buffer/out_message.go @@ -70,7 +70,7 @@ func (m *OutMessage) OutHeader() *fusekernel.OutHeader { func (m *OutMessage) Grow(n int) unsafe.Pointer { p := m.GrowNoZero(n) if p != nil { - memclr(p, uintptr(n)) + jacobsa_fuse_memclr(p, uintptr(n)) } return p @@ -113,7 +113,7 @@ func (m *OutMessage) Append(src []byte) { } sh := (*reflect.SliceHeader)(unsafe.Pointer(&src)) - memmove(p, unsafe.Pointer(sh.Data), uintptr(sh.Len)) + jacobsa_fuse_memmove(p, unsafe.Pointer(sh.Data), uintptr(sh.Len)) return } @@ -126,7 +126,7 @@ func (m *OutMessage) AppendString(src string) { } sh := (*reflect.StringHeader)(unsafe.Pointer(&src)) - memmove(p, unsafe.Pointer(sh.Data), uintptr(sh.Len)) + jacobsa_fuse_memmove(p, unsafe.Pointer(sh.Data), uintptr(sh.Len)) return } diff --git a/internal/buffer/out_message_test.go b/internal/buffer/out_message_test.go index dbdb96a..6292794 100644 --- a/internal/buffer/out_message_test.go +++ b/internal/buffer/out_message_test.go @@ -80,7 +80,7 @@ func TestMemclr(t *testing.T) { p = unsafe.Pointer(&b[0]) } - memclr(p, uintptr(len(b))) + jacobsa_fuse_memclr(p, uintptr(len(b))) // Check if i := findNonZero(p, len(b)); i != len(b) { diff --git a/internal/buffer/runtime.go b/internal/buffer/runtime.go index c0806fb..dc89115 100644 --- a/internal/buffer/runtime.go +++ b/internal/buffer/runtime.go @@ -21,9 +21,11 @@ import "unsafe" // Zero the n bytes starting at p. // // REQUIRES: the region does not contain any Go pointers. -func memclr(p unsafe.Pointer, n uintptr) +//go:linkname jacobsa_fuse_memclr runtime.memclrNoHeapPointers +func jacobsa_fuse_memclr(p unsafe.Pointer, n uintptr) //go:noescape // Copy from src to dst, allowing overlap. -func memmove(dst unsafe.Pointer, src unsafe.Pointer, n uintptr) +//go:linkname jacobsa_fuse_memmove runtime.memmove +func jacobsa_fuse_memmove(dst unsafe.Pointer, src unsafe.Pointer, n uintptr) diff --git a/internal/buffer/runtime_go1.8.s b/internal/buffer/runtime_go1.8.s deleted file mode 100644 index 01d34e9..0000000 --- a/internal/buffer/runtime_go1.8.s +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2015 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// +build amd64 arm64 ppc64 ppc64le arm -// +build go1.8 - -// Assembly code isn't subject to visibility restrictions, so we can jump -// directly into package runtime. -// -// Technique copied from here: -// https://github.com/golang/go/blob/d8c6dac/src/os/signal/sig.s - -#include "textflag.h" - -#ifdef GOARCH_arm -#define JMP B -#endif -#ifdef GOARCH_ppc64 -#define JMP BR -#endif -#ifdef GOARCH_ppc64le -#define JMP BR -#endif - -TEXT ·memclr(SB),NOSPLIT,$0-16 - JMP runtime·memclrNoHeapPointers(SB) - -TEXT ·memmove(SB),NOSPLIT,$0-24 - JMP runtime·memmove(SB) diff --git a/internal/buffer/runtime_other.s b/internal/buffer/runtimestub.s similarity index 53% rename from internal/buffer/runtime_other.s rename to internal/buffer/runtimestub.s index 980f64e..8a51f52 100644 --- a/internal/buffer/runtime_other.s +++ b/internal/buffer/runtimestub.s @@ -12,29 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build amd64 arm64 ppc64 ppc64le arm -// +build !go1.8 - -// Assembly code isn't subject to visibility restrictions, so we can jump -// directly into package runtime. -// -// Technique copied from here: -// https://github.com/golang/go/blob/d8c6dac/src/os/signal/sig.s - -#include "textflag.h" - -#ifdef GOARCH_arm -#define JMP B -#endif -#ifdef GOARCH_ppc64 -#define JMP BR -#endif -#ifdef GOARCH_ppc64le -#define JMP BR -#endif - -TEXT ·memclr(SB),NOSPLIT,$0-16 - JMP runtime·memclr(SB) - -TEXT ·memmove(SB),NOSPLIT,$0-24 - JMP runtime·memmove(SB) +// The buffer package uses //go:linkname to push a few functions into this +// package but we still need a .s file so the Go tool does not pass -complete +// to the go tool compile so the latter does not complain about Go functions +// with no bodies.