aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2024-11-17 11:51:52 -0500
committerGopher Robot <gobot@golang.org>2024-11-19 18:21:27 +0000
commitfd0294b99c2def6a5def7fde9793c2e57ca04240 (patch)
tree958894294d8b61c8f1f72953df20d3894f491a62 /src/cmd
parenteeddabcadb06a2161c379954e31ccfad6a75fc86 (diff)
downloadgo-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')
-rw-r--r--src/cmd/internal/obj/arm64/asm7.go38
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")