diff options
| author | Russ Cox <rsc@golang.org> | 2024-11-17 11:51:52 -0500 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2024-11-19 18:21:27 +0000 |
| commit | fd0294b99c2def6a5def7fde9793c2e57ca04240 (patch) | |
| tree | 958894294d8b61c8f1f72953df20d3894f491a62 /src/cmd/internal/obj | |
| parent | eeddabcadb06a2161c379954e31ccfad6a75fc86 (diff) | |
| download | go-fd0294b99c2def6a5def7fde9793c2e57ca04240.tar.xz | |
cmd/internal/obj/arm64: recognize FIPS static temps as unaligned
Code like x := [12]byte{1,2,3,4,5,6,7,8,9,10,11,12} stores x in
a pair of registers and uses MOVD/MOVWU to load the values
from RODATA. The code generator needs to understand not
to use the aligned PC-relative relocation for that sequence.
In non-FIPS modes, more statictemp optimizations can be applied
and this problematic sequence doesn't happen.
Fix the decision about whether to assume alignment to match
the code used by the linker when deciding what to align.
Fixes the linker failure in CL 626437 patch set 5.
Change-Id: Iedad862c6faee758d4a2c5120cab2d329265b134
Reviewed-on: https://go-review.googlesource.com/c/go/+/628835
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Russ Cox <rsc@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Bypass: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/cmd/internal/obj')
| -rw-r--r-- | src/cmd/internal/obj/arm64/asm7.go | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go index 37de7706e8..f8d4c7aa98 100644 --- a/src/cmd/internal/obj/arm64/asm7.go +++ b/src/cmd/internal/obj/arm64/asm7.go @@ -1073,15 +1073,49 @@ func (o *Optab) size(ctxt *obj.Link, p *obj.Prog) int { // 2-byte and 1-byte aligned addresses, so the address of load/store must be aligned. // Also symbols with prefix of "go:string." are Go strings, which will go into // the symbol table, their addresses are not necessary aligned, rule this out. + // + // Note that the code generation routines for these addressing forms call o.size + // to decide whether to use the unaligned/aligned forms, so o.size's result is always + // in sync with the code generation decisions, because it *is* the code generation decision. align := int64(1 << sz) - if o.a1 == C_ADDR && p.From.Offset%align == 0 && !strings.HasPrefix(p.From.Sym.Name, "go:string.") || - o.a4 == C_ADDR && p.To.Offset%align == 0 && !strings.HasPrefix(p.To.Sym.Name, "go:string.") { + if o.a1 == C_ADDR && p.From.Offset%align == 0 && symAlign(p.From.Sym) >= align || + o.a4 == C_ADDR && p.To.Offset%align == 0 && symAlign(p.To.Sym) >= align { return 8 } } return int(o.size_) } +// symAlign returns the expected symbol alignment of the symbol s. +// This must match the linker's own default alignment decisions. +func symAlign(s *obj.LSym) int64 { + name := s.Name + switch { + case strings.HasPrefix(name, "go:string."), + strings.HasPrefix(name, "type:.namedata."), + strings.HasPrefix(name, "type:.importpath."), + strings.HasSuffix(name, ".opendefer"), + strings.HasSuffix(name, ".arginfo0"), + strings.HasSuffix(name, ".arginfo1"), + strings.HasSuffix(name, ".argliveinfo"): + // These are just bytes, or varints. + return 1 + case strings.HasPrefix(name, "gclocals·"): + // It has 32-bit fields. + return 4 + default: + switch { + case s.Size%8 == 0: + return 8 + case s.Size%4 == 0: + return 4 + case s.Size%2 == 0: + return 2 + } + } + return 1 +} + func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { if ctxt.Retpoline { ctxt.Diag("-spectre=ret not supported on arm64") |
