// 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")
import (
_ "crypto/internal/fips/check"
+ "runtime"
_ "unsafe" // go:linkname
)
var BSS *int
func TEXT() {}
+
+var (
+ globl12 [12]byte
+ globl8 [8]byte
+)
+
+func init() {
+ globl8 = [8]byte{1, 2, 3, 4, 5, 6, 7, 8}
+ globl12 = [12]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
+ runtime.Gosched()
+
+ sum := byte(0)
+ for _, x := range globl12 {
+ sum += x
+ }
+ if sum != 78 {
+ panic("globl12 did not sum properly")
+ }
+
+ sum = byte(0)
+ for _, x := range globl8 {
+ sum += x
+ }
+ if sum != 36 {
+ panic("globl8 did not sum properly")
+ }
+}