[go] internal/bytealg: add MTE-safe IndexByte implementation for ARM64 iOS

8 views
Skip to first unread message

Gopher Robot (Gerrit)

unread,
Mar 3, 2026, 5:52:11 AMMar 3
to Gerrit Bot, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Gopher Robot added 1 comment

Patchset-level comments
File-level comment, Patchset 1 (Latest):
Gopher Robot . unresolved

I spotted some possible problems with your PR:

  1. You have a long 147 character line in the commit message body. Please add line breaks to long lines that should be wrapped. Lines in the commit message body should be wrapped at ~76 characters unless needed for things like URLs or tables. (Note: GitHub might render long lines as soft-wrapped, so double-check in the Gerrit commit message shown above.)
2. You usually need to reference a bug number for all but trivial or cosmetic fixes. For this repo, the format is usually 'Fixes #12345' or 'Updates #12345' at the end of the commit message. Should you have a bug reference?

Please address any problems by updating the GitHub PR.

When complete, mark this comment as 'Done' and click the [blue 'Reply' button](https://go.dev/wiki/GerritBot#i-left-a-reply-to-a-comment-in-gerrit-but-no-one-but-me-can-see-it) above. These findings are based on heuristics; if a finding does not apply, briefly reply here saying so.

To update the commit title or commit message body shown here in Gerrit, you must edit the GitHub PR title and PR description (the first comment) in the GitHub web interface using the 'Edit' button or 'Edit' menu entry there. Note: pushing a new commit to the PR will not automatically update the commit message used by Gerrit.

For more details, see:

(In general for Gerrit code reviews, the change author is expected to [log in to Gerrit](https://go-review.googlesource.com/login/) with a Gmail or other Google account and then close out each piece of feedback by marking it as 'Done' if implemented as suggested or otherwise reply to each review comment. See the [Review](https://go.dev/doc/contribute#review) section of the Contributing Guide for details.)

Open in Gerrit

Related details

Attention set is empty
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I64631f1c4980d81f9ede305bff63918169792ca4
Gerrit-Change-Number: 751000
Gerrit-PatchSet: 1
Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
Gerrit-CC: Gopher Robot <go...@golang.org>
Gerrit-Comment-Date: Tue, 03 Mar 2026 10:52:07 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
unsatisfied_requirement
open
diffy

Gerrit Bot (Gerrit)

unread,
Mar 3, 2026, 5:52:11 AMMar 3
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Gerrit Bot has uploaded the change for review

Commit message

internal/bytealg: add MTE-safe IndexByte implementation for ARM64 iOS

Add optimized ARM64 implementation of IndexByte and IndexByteString for iOS that never reads before string start or beyond end, making it MTE-safe.

Also extend the findnull fallback to iOS since it
may use ARM64 with restrictions similar to Plan 9.

Includes comprehensive tests for different SIMD code paths and alignments.

This PR will be imported into Gerrit with the title and first
comment (this text) used to generate the subject and body of
the Gerrit change.
Change-Id: I64631f1c4980d81f9ede305bff63918169792ca4
GitHub-Last-Rev: 9f82e662b9880f828856f2a92af9f9f842a69cfd
GitHub-Pull-Request: golang/go#77915

Change diff

diff --git a/src/bytes/bytes_test.go b/src/bytes/bytes_test.go
index 891aef2..c5b0051 100644
--- a/src/bytes/bytes_test.go
+++ b/src/bytes/bytes_test.go
@@ -435,6 +435,93 @@
}
}

+// TestIndexByteSIMDPaths tests edge cases for SIMD implementations of IndexByte,
+// specifically targeting the different code paths: unaligned prefix, 32-byte chunks,
+// 16-byte chunks, and scalar tail handling. This is particularly relevant for
+// ARM64 MTE-safe implementations.
+func TestIndexByteSIMDPaths(t *testing.T) {
+ // Test various sizes that exercise different SIMD code paths
+ sizes := []int{
+ 0, 1, 2, 7, 8, 15, 16, 17, 31, 32, 33, 47, 48, 49,
+ 63, 64, 65, 95, 96, 97, 127, 128, 129, 255, 256, 257,
+ }
+
+ for _, size := range sizes {
+ b := make([]byte, size)
+ // Fill with non-target byte
+ for i := range b {
+ b[i] = 'a'
+ }
+
+ // Test 1: Target byte not present
+ if got := IndexByte(b, 'x'); got != -1 {
+ t.Errorf("IndexByte(size=%d, no match) = %d; want -1", size, got)
+ }
+
+ // Test 2: Target byte at each position
+ for pos := 0; pos < size; pos++ {
+ b[pos] = 'x'
+ if got := IndexByte(b, 'x'); got != pos {
+ t.Errorf("IndexByte(size=%d, pos=%d) = %d; want %d", size, pos, got, pos)
+ }
+ b[pos] = 'a'
+ }
+ }
+}
+
+// TestIndexByteUnaligned tests IndexByte with slices starting at various
+// alignments. This tests the unaligned prefix handling in SIMD implementations.
+func TestIndexByteUnaligned(t *testing.T) {
+ // Create a large buffer and test slices at different offsets
+ const bufSize = 512
+ buf := make([]byte, bufSize)
+ for i := range buf {
+ buf[i] = 'a'
+ }
+
+ // Test with different starting offsets (0 to 63 to cover 32-byte alignment cases)
+ for offset := 0; offset < 64 && offset < bufSize; offset++ {
+ // Test with different lengths from this offset
+ for length := 1; length <= bufSize-offset && length <= 256; length++ {
+ slice := buf[offset : offset+length]
+
+ // Reset slice
+ for i := range slice {
+ slice[i] = 'a'
+ }
+
+ // Test: no match
+ if got := IndexByte(slice, 'x'); got != -1 {
+ t.Errorf("IndexByte(offset=%d, len=%d, no match) = %d; want -1", offset, length, got)
+ }
+
+ // Test: match at first position
+ slice[0] = 'x'
+ if got := IndexByte(slice, 'x'); got != 0 {
+ t.Errorf("IndexByte(offset=%d, len=%d, pos=0) = %d; want 0", offset, length, got)
+ }
+ slice[0] = 'a'
+
+ // Test: match at last position
+ slice[length-1] = 'x'
+ if got := IndexByte(slice, 'x'); got != length-1 {
+ t.Errorf("IndexByte(offset=%d, len=%d, pos=%d) = %d; want %d", offset, length, length-1, got, length-1)
+ }
+ slice[length-1] = 'a'
+
+ // Test: match in middle (if length > 2)
+ if length > 2 {
+ mid := length / 2
+ slice[mid] = 'x'
+ if got := IndexByte(slice, 'x'); got != mid {
+ t.Errorf("IndexByte(offset=%d, len=%d, pos=%d) = %d; want %d", offset, length, mid, got, mid)
+ }
+ slice[mid] = 'a'
+ }
+ }
+ }
+}
+
func TestIndexRune(t *testing.T) {
tests := []struct {
in string
diff --git a/src/internal/bytealg/indexbyte_arm64.s b/src/internal/bytealg/indexbyte_arm64.s
index 1101122ec..b35ca3a 100644
--- a/src/internal/bytealg/indexbyte_arm64.s
+++ b/src/internal/bytealg/indexbyte_arm64.s
@@ -4,6 +4,152 @@

#include "textflag.h"

+#ifdef GOOS_ios
+// func IndexByte(b []byte, c byte) int
+// input:
+// R0: b ptr
+// R1: b len
+// R2: b cap (unused)
+// R3: c byte to search
+// return
+// R0: result
+TEXT ·IndexByte<ABIInternal>(SB),NOSPLIT,$0-40
+ MOVD R3, R2
+ B ·IndexByteString<ABIInternal>(SB)
+
+// func IndexByteString(s string, c byte) int
+// input:
+// R0: s ptr
+// R1: s len
+// R2: c byte to search
+// return
+// R0: result
+TEXT ·IndexByteString<ABIInternal>(SB),NOSPLIT,$0-32
+ // MTE-safe implementation: never reads before start or beyond end.
+ // For each 32-byte chunk we calculate a 64-bit syndrome value,
+ // with two bits per byte. Bit 0 is set if the relevant byte
+ // matched the requested character. Counting trailing zeros
+ // identifies which byte matched.
+
+ CBZ R1, fail
+ MOVD R0, R11 // Save original pointer
+ ADD R0, R1, R4 // R4 = end pointer
+
+ // Setup SIMD constants
+ // Magic constant 0x40100401 allows us to identify which lane matches.
+ // 0x40100401 = ((1<<0) + (4<<8) + (16<<16) + (64<<24))
+ VMOV R2, V0.B16 // Broadcast search byte to all lanes
+ MOVD $0x40100401, R5
+ VMOV R5, V5.S4
+
+ // Check alignment - process unaligned prefix byte-by-byte
+ // This avoids reading before the string start (MTE violation)
+ ANDS $0x1f, R0, R9
+ BEQ aligned_start
+
+unaligned_loop:
+ MOVBU (R0), R5
+ CMP R2, R5
+ BEQ found_scalar
+ ADD $1, R0
+ CMP R0, R4
+ BEQ fail
+ TST $0x1f, R0
+ BNE unaligned_loop
+
+aligned_start:
+ // Check if we have at least 32 bytes remaining BEFORE loading
+ SUB R0, R4, R5 // R5 = remaining bytes
+ CMP $32, R5
+ BLO tail16_check
+
+loop32:
+ // Load 32 aligned bytes - safe because we verified 32+ bytes remain
+ VLD1.P 32(R0), [V1.B16, V2.B16]
+
+ // Compare both vectors against search byte
+ VCMEQ V0.B16, V1.B16, V3.B16
+ VCMEQ V0.B16, V2.B16, V4.B16
+
+ // Quick check: any matches in either vector?
+ VORR V4.B16, V3.B16, V6.B16
+ VADDP V6.D2, V6.D2, V6.D2
+ VMOV V6.D[0], R6
+ CBNZ R6, found32
+
+ // Check bounds BEFORE next iteration
+ SUB R0, R4, R5
+ CMP $32, R5
+ BHS loop32
+
+tail16_check:
+ // Try 16-byte chunks if available
+ CMP $16, R5
+ BLO tail_scalar
+
+loop16:
+ // Load 16 aligned bytes
+ VLD1.P 16(R0), [V1.B16]
+
+ VCMEQ V0.B16, V1.B16, V3.B16
+ VAND V5.B16, V3.B16, V3.B16
+ VADDP V3.B16, V3.B16, V3.B16 // 128->64
+ VADDP V3.B16, V3.B16, V3.B16 // 64->32
+ VMOV V3.S[0], R6
+ CBNZ R6, found16
+
+ // Check bounds BEFORE next iteration
+ SUB R0, R4, R5
+ CMP $16, R5
+ BHS loop16
+
+tail_scalar:
+ // Handle remaining bytes one at a time (always safe)
+ CMP R0, R4
+ BEQ fail
+
+tail_loop:
+ MOVBU (R0), R5
+ CMP R2, R5
+ BEQ found_scalar
+ ADD $1, R0
+ CMP R0, R4
+ BNE tail_loop
+ B fail
+
+found32:
+ // Calculate full syndrome for precise position
+ VAND V5.B16, V3.B16, V3.B16
+ VAND V5.B16, V4.B16, V4.B16
+ VADDP V4.B16, V3.B16, V6.B16 // 256->128
+ VADDP V6.B16, V6.B16, V6.B16 // 128->64
+ VMOV V6.D[0], R6
+
+ RBIT R6, R6
+ SUB $32, R0, R0 // Compensate post-increment
+ CLZ R6, R6
+ ADD R6>>1, R0, R0 // R6 is twice the byte offset
+ SUB R11, R0, R0
+ RET
+
+found16:
+ RBIT R6, R6
+ SUB $16, R0, R0 // Compensate post-increment
+ CLZ R6, R6
+ ADD R6>>1, R0, R0 // R6 is twice the byte offset
+ SUB R11, R0, R0
+ RET
+
+found_scalar:
+ SUB R11, R0, R0
+ RET
+
+fail:
+ MOVD $-1, R0
+ RET
+
+#else
+
// func IndexByte(b []byte, c byte) int
// input:
// R0: b ptr
@@ -143,3 +289,5 @@
fail:
MOVD $-1, R0
RET
+
+#endif
diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go
index bc471e5..477b7ff 100644
--- a/src/runtime/export_test.go
+++ b/src/runtime/export_test.go
@@ -228,6 +228,15 @@
return
}

+// Findnull is an entry point for testing findnull.
+// It returns the index of the first NUL byte in a NUL-terminated byte slice.
+func Findnull(s []byte) int {
+ if len(s) == 0 {
+ return 0
+ }
+ return findnull(&s[0])
+}
+
var Open = open
var Close = closefd
var Read = read
diff --git a/src/runtime/string.go b/src/runtime/string.go
index 7207f83..8c01082 100644
--- a/src/runtime/string.go
+++ b/src/runtime/string.go
@@ -493,7 +493,7 @@
// Avoid IndexByteString on Plan 9 because it uses SSE instructions
// on x86 machines, and those are classified as floating point instructions,
// which are illegal in a note handler.
- if GOOS == "plan9" {
+ if GOOS == "plan9" || GOOS == "ios" {
p := (*[maxAlloc/2 - 1]byte)(unsafe.Pointer(s))
l := 0
for p[l] != 0 {
diff --git a/src/runtime/string_test.go b/src/runtime/string_test.go
index 942e7ac..9de8931 100644
--- a/src/runtime/string_test.go
+++ b/src/runtime/string_test.go
@@ -214,6 +214,57 @@
}
}

+// TestFindnull tests the findnull function which finds the index of the
+// first NUL byte in a NUL-terminated byte slice. This tests the byte-by-byte
+// fallback path used on Plan 9 and iOS
+func TestFindnull(t *testing.T) {
+ // Test various sizes that might exercise different code paths
+ sizes := []int{
+ 0, 1, 2, 7, 8, 15, 16, 17, 31, 32, 33, 47, 48, 49,
+ 63, 64, 65, 127, 128, 129, 255, 256, 257, 1023, 1024, 1025,
+ }
+
+ for _, size := range sizes {
+ // Create a NUL-terminated byte slice
+ b := make([]byte, size+1) // +1 for NUL terminator
+ for i := 0; i < size; i++ {
+ b[i] = 'a'
+ }
+ b[size] = 0
+
+ got := runtime.Findnull(b)
+ if got != size {
+ t.Errorf("Findnull(size=%d) = %d; want %d", size, got, size)
+ }
+ }
+
+ // Test with NUL at various positions
+ for _, total := range []int{64, 128, 256} {
+ for pos := 0; pos < total; pos++ {
+ b := make([]byte, total+1)
+ for i := 0; i < total; i++ {
+ b[i] = 'a'
+ }
+ b[pos] = 0 // Place NUL at position pos
+ b[total] = 0
+
+ got := runtime.Findnull(b)
+ if got != pos {
+ t.Errorf("Findnull(total=%d, nul_at=%d) = %d; want %d", total, pos, got, pos)
+ }
+
+ // Restore for next iteration
+ b[pos] = 'a'
+ }
+ }
+
+ // Test empty slice (nil pointer behavior)
+ got := runtime.Findnull(nil)
+ if got != 0 {
+ t.Errorf("Findnull(nil) = %d; want 0", got)
+ }
+}
+
func TestLargeStringConcat(t *testing.T) {
output := runTestProg(t, "testprog", "stringconcat")
want := "panic: " + strings.Repeat("0", 1<<10) + strings.Repeat("1", 1<<10) +
diff --git a/src/strings/strings_test.go b/src/strings/strings_test.go
index edfeb0e..62fe1ec 100644
--- a/src/strings/strings_test.go
+++ b/src/strings/strings_test.go
@@ -266,6 +266,100 @@
}
}

+// TestIndexByteSIMDPaths tests edge cases for SIMD implementations of IndexByte,
+// specifically targeting the different code paths: unaligned prefix, 32-byte chunks,
+// 16-byte chunks, and scalar tail handling. This is particularly relevant for
+// ARM64 MTE-safe implementations.
+func TestIndexByteSIMDPaths(t *testing.T) {
+ // Test various sizes that exercise different SIMD code paths
+ sizes := []int{
+ 0, 1, 2, 7, 8, 15, 16, 17, 31, 32, 33, 47, 48, 49,
+ 63, 64, 65, 95, 96, 97, 127, 128, 129, 255, 256, 257,
+ }
+
+ for _, size := range sizes {
+ // Create a string of the given size
+ b := make([]byte, size)
+ for i := range b {
+ b[i] = 'a'
+ }
+ s := string(b)
+
+ // Test 1: Target byte not present
+ if got := IndexByte(s, 'x'); got != -1 {
+ t.Errorf("IndexByte(size=%d, no match) = %d; want -1", size, got)
+ }
+
+ // Test 2: Target byte at each position
+ for pos := 0; pos < size; pos++ {
+ b[pos] = 'x'
+ s = string(b)
+ if got := IndexByte(s, 'x'); got != pos {
+ t.Errorf("IndexByte(size=%d, pos=%d) = %d; want %d", size, pos, got, pos)
+ }
+ b[pos] = 'a'
+ }
+ }
+}
+
+// TestIndexByteStringUnaligned tests IndexByte with strings created from
+// slices at various alignments. This tests the unaligned prefix handling
+// in SIMD implementations.
+func TestIndexByteStringUnaligned(t *testing.T) {
+ // Create a large buffer and test strings at different offsets
+ const bufSize = 512
+ buf := make([]byte, bufSize)
+ for i := range buf {
+ buf[i] = 'a'
+ }
+
+ // Test with different starting offsets (0 to 63 to cover 32-byte alignment cases)
+ for offset := 0; offset < 64 && offset < bufSize; offset++ {
+ // Test with different lengths from this offset
+ for length := 1; length <= bufSize-offset && length <= 256; length++ {
+ slice := buf[offset : offset+length]
+
+ // Reset slice
+ for i := range slice {
+ slice[i] = 'a'
+ }
+ s := string(slice)
+
+ // Test: no match
+ if got := IndexByte(s, 'x'); got != -1 {
+ t.Errorf("IndexByte(offset=%d, len=%d, no match) = %d; want -1", offset, length, got)
+ }
+
+ // Test: match at first position
+ slice[0] = 'x'
+ s = string(slice)
+ if got := IndexByte(s, 'x'); got != 0 {
+ t.Errorf("IndexByte(offset=%d, len=%d, pos=0) = %d; want 0", offset, length, got)
+ }
+ slice[0] = 'a'
+
+ // Test: match at last position
+ slice[length-1] = 'x'
+ s = string(slice)
+ if got := IndexByte(s, 'x'); got != length-1 {
+ t.Errorf("IndexByte(offset=%d, len=%d, pos=%d) = %d; want %d", offset, length, length-1, got, length-1)
+ }
+ slice[length-1] = 'a'
+
+ // Test: match in middle (if length > 2)
+ if length > 2 {
+ mid := length / 2
+ slice[mid] = 'x'
+ s = string(slice)
+ if got := IndexByte(s, 'x'); got != mid {
+ t.Errorf("IndexByte(offset=%d, len=%d, pos=%d) = %d; want %d", offset, length, mid, got, mid)
+ }
+ slice[mid] = 'a'
+ }
+ }
+ }
+}
+
func simpleIndex(s, sep string) int {
n := len(sep)
for i := n; i <= len(s); i++ {

Change information

Files:
  • M src/bytes/bytes_test.go
  • M src/internal/bytealg/indexbyte_arm64.s
  • M src/runtime/export_test.go
  • M src/runtime/string.go
  • M src/runtime/string_test.go
  • M src/strings/strings_test.go
Change size: L
Delta: 6 files changed, 390 insertions(+), 1 deletion(-)
Open in Gerrit

Related details

Attention set is empty
Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    • requirement is not satisfiedTryBots-Pass
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: newchange
    unsatisfied_requirement
    satisfied_requirement
    open
    diffy

    Gopher Robot (Gerrit)

    unread,
    Mar 3, 2026, 5:55:06 AMMar 3
    to Gerrit Bot, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

    Message from Gopher Robot

    Congratulations on opening your first change. Thank you for your contribution!

    Next steps:
    A maintainer will review your change and provide feedback. See
    https://go.dev/doc/contribute#review for more info and tips to get your
    patch through code review.

    Most changes in the Go project go through a few rounds of revision. This can be
    surprising to people new to the project. The careful, iterative review process
    is our way of helping mentor contributors and ensuring that their contributions
    have a lasting impact.

    During May-July and Nov-Jan the Go project is in a code freeze, during which
    little code gets reviewed or merged. If a reviewer responds with a comment like
    R=go1.11 or adds a tag like "wait-release", it means that this CL will be
    reviewed as part of the next development cycle. See https://go.dev/s/release
    for more details.

    Open in Gerrit

    Related details

    Attention set is empty
    Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement is not satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: go
      Gerrit-Branch: master
      Gerrit-Change-Id: I64631f1c4980d81f9ede305bff63918169792ca4
      Gerrit-Change-Number: 751000
      Gerrit-PatchSet: 1
      Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
      Gerrit-CC: Gopher Robot <go...@golang.org>
      Gerrit-Comment-Date: Tue, 03 Mar 2026 10:55:00 +0000
      Gerrit-HasComments: No
      Gerrit-Has-Labels: No
      unsatisfied_requirement
      open
      diffy

      Gerrit Bot (Gerrit)

      unread,
      Mar 3, 2026, 10:16:48 AMMar 3
      to Marco, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
      Attention needed from Ian Lance Taylor, Keith Randall and Michael Pratt

      Gerrit Bot uploaded new patchset

      Gerrit Bot uploaded patch set #2 to this change.
      Open in Gerrit

      Related details

      Attention is currently required from:
      • Ian Lance Taylor
      • Keith Randall
      • Michael Pratt
      Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement is not satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: newpatchset
      Gerrit-Project: go
      Gerrit-Branch: master
      Gerrit-Change-Id: I64631f1c4980d81f9ede305bff63918169792ca4
      Gerrit-Change-Number: 751000
      Gerrit-PatchSet: 2
      Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
      Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
      Gerrit-Reviewer: Keith Randall <k...@golang.org>
      Gerrit-Reviewer: Michael Pratt <mpr...@google.com>
      Gerrit-CC: Gopher Robot <go...@golang.org>
      Gerrit-CC: Marco <m479...@gmail.com>
      Gerrit-Attention: Keith Randall <k...@golang.org>
      Gerrit-Attention: Ian Lance Taylor <ia...@golang.org>
      Gerrit-Attention: Michael Pratt <mpr...@google.com>
      unsatisfied_requirement
      open
      diffy

      Keith Randall (Gerrit)

      unread,
      Mar 3, 2026, 12:54:20 PMMar 3
      to Marco, Gerrit Bot, goph...@pubsubhelper.golang.org, Ian Lance Taylor, Keith Randall, Michael Pratt, Gopher Robot, golang-co...@googlegroups.com
      Attention needed from Ian Lance Taylor and Michael Pratt

      Keith Randall added 1 comment

      Patchset-level comments
      File-level comment, Patchset 2 (Latest):
      Keith Randall . unresolved

      I think I fixed the immediate problem of triggering MTE with CL 751020.
      Let me know if that fixes it for you.

      The non-assembly parts of this CL are probably still needed (or at least, should be considered). The iOS conditioning, and the set of tests (thanks for those!).

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Ian Lance Taylor
      • Michael Pratt
      Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement is not satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: go
      Gerrit-Branch: master
      Gerrit-Change-Id: I64631f1c4980d81f9ede305bff63918169792ca4
      Gerrit-Change-Number: 751000
      Gerrit-PatchSet: 2
      Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
      Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
      Gerrit-Reviewer: Keith Randall <k...@golang.org>
      Gerrit-Reviewer: Michael Pratt <mpr...@google.com>
      Gerrit-CC: Gopher Robot <go...@golang.org>
      Gerrit-CC: Marco <m479...@gmail.com>
      Gerrit-Attention: Ian Lance Taylor <ia...@golang.org>
      Gerrit-Attention: Michael Pratt <mpr...@google.com>
      Gerrit-Comment-Date: Tue, 03 Mar 2026 17:54:16 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: No
      unsatisfied_requirement
      open
      diffy

      Marco (Gerrit)

      unread,
      Mar 6, 2026, 5:50:21 AM (13 days ago) Mar 6
      to Gerrit Bot, goph...@pubsubhelper.golang.org, Ian Lance Taylor, Keith Randall, Michael Pratt, Gopher Robot, golang-co...@googlegroups.com
      Attention needed from Ian Lance Taylor and Michael Pratt

      Marco added 1 comment

      Patchset-level comments
      File-level comment, Patchset 1:
      Gopher Robot . resolved

      I spotted some possible problems with your PR:

        1. You have a long 147 character line in the commit message body. Please add line breaks to long lines that should be wrapped. Lines in the commit message body should be wrapped at ~76 characters unless needed for things like URLs or tables. (Note: GitHub might render long lines as soft-wrapped, so double-check in the Gerrit commit message shown above.)
      2. You usually need to reference a bug number for all but trivial or cosmetic fixes. For this repo, the format is usually 'Fixes #12345' or 'Updates #12345' at the end of the commit message. Should you have a bug reference?

      Please address any problems by updating the GitHub PR.

      When complete, mark this comment as 'Done' and click the [blue 'Reply' button](https://go.dev/wiki/GerritBot#i-left-a-reply-to-a-comment-in-gerrit-but-no-one-but-me-can-see-it) above. These findings are based on heuristics; if a finding does not apply, briefly reply here saying so.

      To update the commit title or commit message body shown here in Gerrit, you must edit the GitHub PR title and PR description (the first comment) in the GitHub web interface using the 'Edit' button or 'Edit' menu entry there. Note: pushing a new commit to the PR will not automatically update the commit message used by Gerrit.

      For more details, see:

      (In general for Gerrit code reviews, the change author is expected to [log in to Gerrit](https://go-review.googlesource.com/login/) with a Gmail or other Google account and then close out each piece of feedback by marking it as 'Done' if implemented as suggested or otherwise reply to each review comment. See the [Review](https://go.dev/doc/contribute#review) section of the Contributing Guide for details.)

      Marco

      Done

      Gerrit-Comment-Date: Fri, 06 Mar 2026 10:50:14 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: No
      Comment-In-Reply-To: Gopher Robot <go...@golang.org>
      unsatisfied_requirement
      open
      diffy

      Marco (Gerrit)

      unread,
      Mar 6, 2026, 5:53:10 AM (13 days ago) Mar 6
      to Gerrit Bot, goph...@pubsubhelper.golang.org, Ian Lance Taylor, Keith Randall, Michael Pratt, Gopher Robot, golang-co...@googlegroups.com
      Attention needed from Ian Lance Taylor and Michael Pratt

      Marco added 1 comment

      Patchset-level comments
      Keith Randall . unresolved

      I think I fixed the immediate problem of triggering MTE with CL 751020.
      Let me know if that fixes it for you.

      The non-assembly parts of this CL are probably still needed (or at least, should be considered). The iOS conditioning, and the set of tests (thanks for those!).

      Marco

      For me it was necessary to update the assembly code section in order to make the application run. With only the go code, it started but then closes on splash-screen when MTE was enabled. After the updated assembly section, no more crashes were seen

      Gerrit-Comment-Date: Fri, 06 Mar 2026 10:53:03 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: No
      Comment-In-Reply-To: Keith Randall <k...@golang.org>
      unsatisfied_requirement
      open
      diffy

      Marco (Gerrit)

      unread,
      Mar 6, 2026, 5:57:53 AM (13 days ago) Mar 6
      to Gerrit Bot, goph...@pubsubhelper.golang.org, Ian Lance Taylor, Keith Randall, Michael Pratt, Gopher Robot, golang-co...@googlegroups.com
      Attention needed from Ian Lance Taylor, Keith Randall and Michael Pratt

      Marco added 1 comment

      Patchset-level comments
      Keith Randall . resolved

      I think I fixed the immediate problem of triggering MTE with CL 751020.
      Let me know if that fixes it for you.

      The non-assembly parts of this CL are probably still needed (or at least, should be considered). The iOS conditioning, and the set of tests (thanks for those!).

      Marco

      For me it was necessary to update the assembly code section in order to make the application run. With only the go code, it started but then closes on splash-screen when MTE was enabled. After the updated assembly section, no more crashes were seen

      Marco

      Done

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Ian Lance Taylor
      • Keith Randall
      • Michael Pratt
      Submit Requirements:
        • requirement is not satisfiedCode-Review
        • requirement satisfiedNo-Unresolved-Comments
        • requirement is not satisfiedReview-Enforcement
        • requirement is not satisfiedTryBots-Pass
        Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
        Gerrit-MessageType: comment
        Gerrit-Project: go
        Gerrit-Branch: master
        Gerrit-Change-Id: I64631f1c4980d81f9ede305bff63918169792ca4
        Gerrit-Change-Number: 751000
        Gerrit-PatchSet: 2
        Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
        Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
        Gerrit-Reviewer: Keith Randall <k...@golang.org>
        Gerrit-Reviewer: Michael Pratt <mpr...@google.com>
        Gerrit-CC: Gopher Robot <go...@golang.org>
        Gerrit-CC: Marco <m479...@gmail.com>
        Gerrit-Attention: Keith Randall <k...@golang.org>
        Gerrit-Attention: Ian Lance Taylor <ia...@golang.org>
        Gerrit-Attention: Michael Pratt <mpr...@google.com>
        Gerrit-Comment-Date: Fri, 06 Mar 2026 10:57:47 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: No
        Comment-In-Reply-To: Keith Randall <k...@golang.org>
        Comment-In-Reply-To: Marco <m479...@gmail.com>
        unsatisfied_requirement
        satisfied_requirement
        open
        diffy

        Keith Randall (Gerrit)

        unread,
        Mar 6, 2026, 10:43:39 AM (12 days ago) Mar 6
        to Marco, Gerrit Bot, goph...@pubsubhelper.golang.org, Ian Lance Taylor, Keith Randall, Michael Pratt, Gopher Robot, golang-co...@googlegroups.com
        Attention needed from Ian Lance Taylor, Marco and Michael Pratt

        Keith Randall added 1 comment

        Patchset-level comments
        Keith Randall . resolved

        I think I fixed the immediate problem of triggering MTE with CL 751020.
        Let me know if that fixes it for you.

        The non-assembly parts of this CL are probably still needed (or at least, should be considered). The iOS conditioning, and the set of tests (thanks for those!).

        Marco

        For me it was necessary to update the assembly code section in order to make the application run. With only the go code, it started but then closes on splash-screen when MTE was enabled. After the updated assembly section, no more crashes were seen

        Marco

        Done

        Keith Randall

        Where does it crash? Do you have a stack trace, or even just a PC where the application was aborted?

        Did you add iOS to the ifdefs? The MTE compatibility code that is checked in is just enabled on android currently.

        Open in Gerrit

        Related details

        Attention is currently required from:
        • Ian Lance Taylor
        • Marco
        • Michael Pratt
        Submit Requirements:
        • requirement is not satisfiedCode-Review
        • requirement satisfiedNo-Unresolved-Comments
        • requirement is not satisfiedReview-Enforcement
        • requirement is not satisfiedTryBots-Pass
        Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
        Gerrit-MessageType: comment
        Gerrit-Project: go
        Gerrit-Branch: master
        Gerrit-Change-Id: I64631f1c4980d81f9ede305bff63918169792ca4
        Gerrit-Change-Number: 751000
        Gerrit-PatchSet: 2
        Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
        Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
        Gerrit-Reviewer: Keith Randall <k...@golang.org>
        Gerrit-Reviewer: Michael Pratt <mpr...@google.com>
        Gerrit-CC: Gopher Robot <go...@golang.org>
        Gerrit-CC: Marco <m479...@gmail.com>
        Gerrit-Attention: Ian Lance Taylor <ia...@golang.org>
        Gerrit-Attention: Michael Pratt <mpr...@google.com>
        Gerrit-Attention: Marco <m479...@gmail.com>
        Gerrit-Comment-Date: Fri, 06 Mar 2026 15:43:33 +0000
        unsatisfied_requirement
        satisfied_requirement
        open
        diffy

        Marco (Gerrit)

        unread,
        Mar 6, 2026, 10:54:53 AM (12 days ago) Mar 6
        to Gerrit Bot, goph...@pubsubhelper.golang.org, Ian Lance Taylor, Keith Randall, Michael Pratt, Gopher Robot, golang-co...@googlegroups.com
        Attention needed from Ian Lance Taylor and Michael Pratt

        Marco added 1 comment

        Patchset-level comments
        Keith Randall . unresolved

        I think I fixed the immediate problem of triggering MTE with CL 751020.
        Let me know if that fixes it for you.

        The non-assembly parts of this CL are probably still needed (or at least, should be considered). The iOS conditioning, and the set of tests (thanks for those!).

        Marco

        For me it was necessary to update the assembly code section in order to make the application run. With only the go code, it started but then closes on splash-screen when MTE was enabled. After the updated assembly section, no more crashes were seen

        Marco

        Done

        Keith Randall

        Where does it crash? Do you have a stack trace, or even just a PC where the application was aborted?

        Did you add iOS to the ifdefs? The MTE compatibility code that is checked in is just enabled on android currently.

        Marco

        Here goes the stack trace, obtained before my assembly section proposal

        internal/bytealg.IndexByteString (indexbyte_arm64.s:54)
        runtime.findnull (string.go:520)

        Open in Gerrit

        Related details

        Attention is currently required from:
        • Ian Lance Taylor
        • Michael Pratt
        Submit Requirements:
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement is not satisfiedReview-Enforcement
          • requirement is not satisfiedTryBots-Pass
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: comment
          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-Change-Id: I64631f1c4980d81f9ede305bff63918169792ca4
          Gerrit-Change-Number: 751000
          Gerrit-PatchSet: 2
          Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
          Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
          Gerrit-Reviewer: Keith Randall <k...@golang.org>
          Gerrit-Reviewer: Michael Pratt <mpr...@google.com>
          Gerrit-CC: Gopher Robot <go...@golang.org>
          Gerrit-CC: Marco <m479...@gmail.com>
          Gerrit-Attention: Ian Lance Taylor <ia...@golang.org>
          Gerrit-Attention: Michael Pratt <mpr...@google.com>
          Gerrit-Comment-Date: Fri, 06 Mar 2026 15:54:47 +0000
          unsatisfied_requirement
          open
          diffy

          Keith Randall (Gerrit)

          unread,
          Mar 6, 2026, 11:15:32 AM (12 days ago) Mar 6
          to Marco, Gerrit Bot, goph...@pubsubhelper.golang.org, Ian Lance Taylor, Keith Randall, Michael Pratt, Gopher Robot, golang-co...@googlegroups.com
          Attention needed from Ian Lance Taylor and Michael Pratt

          Keith Randall added 1 comment

          Patchset-level comments
          Keith Randall . unresolved

          I think I fixed the immediate problem of triggering MTE with CL 751020.
          Let me know if that fixes it for you.

          The non-assembly parts of this CL are probably still needed (or at least, should be considered). The iOS conditioning, and the set of tests (thanks for those!).

          Marco

          For me it was necessary to update the assembly code section in order to make the application run. With only the go code, it started but then closes on splash-screen when MTE was enabled. After the updated assembly section, no more crashes were seen

          Marco

          Done

          Keith Randall

          Where does it crash? Do you have a stack trace, or even just a PC where the application was aborted?

          Did you add iOS to the ifdefs? The MTE compatibility code that is checked in is just enabled on android currently.

          Marco

          Here goes the stack trace, obtained before my assembly section proposal

          internal/bytealg.IndexByteString (indexbyte_arm64.s:54)
          runtime.findnull (string.go:520)

          Keith Randall

          Hm, there's no instruction at that line in the assembly.

          Just to be clear do:

          1. sync to tip
          2. Add `|| GOOS_ios` to the three ifdefs in indexbyte_arm64.s
          3. Change the line at runtime/string.go:511 to
          ```
          const pageSize = 4096*(1-(goos.IsAndroid | goos.IsIos)) + 16*(goos.IsAndroid | goos.IsIos)
          ```

          Does it crash then, and if so, where?

          Gerrit-Comment-Date: Fri, 06 Mar 2026 16:15:28 +0000
          unsatisfied_requirement
          open
          diffy

          Marco (Gerrit)

          unread,
          Mar 12, 2026, 3:14:08 AM (7 days ago) Mar 12
          to Gerrit Bot, goph...@pubsubhelper.golang.org, Ian Lance Taylor, Keith Randall, Michael Pratt, Gopher Robot, golang-co...@googlegroups.com
          Attention needed from Ian Lance Taylor and Michael Pratt

          Marco added 1 comment

          Patchset-level comments
          Marco

          Good morning,
          Regarding the fact that there are no instructions on that line of the assembly file, comments are stripped from the final build file, so that line does in fact contain instructions.
          Changing the pagesize value for iOS to 16 (at runtime/string.go:511) has no effect because in this PR proposal the previous if statement has been modified to include iOS

          (if GOOS == ‘plan9’ || GOOS == ‘ios’)

          so the if statement on line 511 is not reached.

          In any case, as reported, WITHOUT modifying the assembly section for iOS, where a conservative and MTE-safe implementation is made that always checks the limits before loading data (first processes unaligned bytes, then 32/16 byte chunks, and finally single bytes), the iOS application crashes when run on iPhone 17 with MTE enabled, at line 54 of the indexbyte_arm64 file, as previously mentioned.

          Therefore, I request a review of the content of this PR to make GO available for use in an iOS context with MTE enabled on iPhone 17 devices, which involves changes to both the assembly file and the src/runtime/string.go file.

          Thank you.

          Gerrit-Comment-Date: Thu, 12 Mar 2026 07:14:00 +0000
          unsatisfied_requirement
          open
          diffy

          Keith Randall (Gerrit)

          unread,
          Mar 12, 2026, 12:37:14 PM (6 days ago) Mar 12
          to Marco, Gerrit Bot, goph...@pubsubhelper.golang.org, Ian Lance Taylor, Keith Randall, Michael Pratt, Gopher Robot, golang-co...@googlegroups.com
          Attention needed from Ian Lance Taylor and Michael Pratt

          Keith Randall added 1 comment

          Patchset-level comments
          Keith Randall

          Regarding the fact that there are no instructions on that line of the assembly file, comments are stripped from the final build file, so that line does in fact contain instructions.

          What is stripping comments? The Go build system doesn't do that.

          In any case, I need to know which instruction in asm_arm64.s is triggering MTE. Is it the 54th non-comment line? Does that skip empty lines also?
          A disassemble listing pointing to the triggering instruction would also work.

          Changing the pagesize value for iOS to 16 (at runtime/string.go:511) has no effect because in this PR proposal the previous if statement has been modified to include iOS

          (if GOOS == ‘plan9’ || GOOS == ‘ios’)
          > so the if statement on line 511 is not reached.

          I mean, do this experiment *without this CL*:

          Just to be clear do:

          1. sync to tip
          2. Add || GOOS_ios to the three ifdefs in indexbyte_arm64.s
          3. Change the line at runtime/string.go:511 to
          ```
          const pageSize = 4096*(1-(goos.IsAndroid | goos.IsIos)) + 16*(goos.IsAndroid | goos.IsIos)
          ```
          Does it crash then, and if so, where?

          Gerrit-Comment-Date: Thu, 12 Mar 2026 16:37:09 +0000
          unsatisfied_requirement
          open
          diffy

          Marco (Gerrit)

          unread,
          6:26 AM (14 hours ago) 6:26 AM
          to Gerrit Bot, goph...@pubsubhelper.golang.org, Ian Lance Taylor, Keith Randall, Michael Pratt, Gopher Robot, golang-co...@googlegroups.com
          Attention needed from Ian Lance Taylor and Michael Pratt

          Marco added 1 comment

          Patchset-level comments
          Marco

          Hi @k...@golang.org,

          I have done the tests you asked me.

          First of all, I have tried the exact same test you suggested me (sync - GOOS_ios on assembly file - updating line 511 of string go, all without my CL), and the result is that the iOS application crashes at splash-screen at this instruction:

          0x10482978c <+44>: ld1.16b { v1 }, [x3], #16
          of internal/bytealg.IndexByteString
          for this cause: "Thread 3: Heap buffer underflow by 16 bytes", when MTE is enabled on iPhone 17.

          Note aside: I have also did the exact same test, but this time removing all comments from bytealg/indexbyte_arm64.s. 
          The result is exactly the same as the one above, 0x10482978c <+44>: ld1.16b { v1 }, [x3], #16 is the instruction that causes the crash.

          So apparently comments are not taken into account on how to determinate which line is involved in the crash that is occurring, at least for golang dependencies made for final iOS applications.
          Gerrit-Comment-Date: Wed, 18 Mar 2026 10:26:33 +0000
          unsatisfied_requirement
          open
          diffy

          Keith Randall (Gerrit)

          unread,
          12:09 PM (8 hours ago) 12:09 PM
          to Marco, Gerrit Bot, goph...@pubsubhelper.golang.org, Ian Lance Taylor, Keith Randall, Michael Pratt, Gopher Robot, golang-co...@googlegroups.com
          Attention needed from Ian Lance Taylor and Michael Pratt

          Keith Randall added 1 comment

          Patchset-level comments
          Keith Randall

          0x10482978c <+44>: ld1.16b { v1 }, [x3], #16

          That instruction is not at tip. That looks like the one that was fixed by https://go-review.googlesource.com/c/go/+/751020

          Gerrit-Comment-Date: Wed, 18 Mar 2026 16:09:38 +0000
          unsatisfied_requirement
          open
          diffy
          Reply all
          Reply to author
          Forward
          0 new messages