diff options
Diffstat (limited to 'src/cmd/compile')
| -rw-r--r-- | src/cmd/compile/internal/base/debug.go | 1 | ||||
| -rw-r--r-- | src/cmd/compile/internal/base/flag.go | 1 | ||||
| -rw-r--r-- | src/cmd/compile/internal/staticinit/sched.go | 44 | ||||
| -rw-r--r-- | src/cmd/compile/internal/walk/complit.go | 5 | ||||
| -rw-r--r-- | src/cmd/compile/internal/walk/order.go | 7 |
5 files changed, 53 insertions, 5 deletions
diff --git a/src/cmd/compile/internal/base/debug.go b/src/cmd/compile/internal/base/debug.go index 05da3efe48..d42e11b2fa 100644 --- a/src/cmd/compile/internal/base/debug.go +++ b/src/cmd/compile/internal/base/debug.go @@ -30,6 +30,7 @@ type DebugFlags struct { DwarfInl int `help:"print information about DWARF inlined function creation"` EscapeMutationsCalls int `help:"print extra escape analysis diagnostics about mutations and calls" concurrent:"ok"` Export int `help:"print export data"` + FIPSHash string `help:"hash value for FIPS debugging" concurrent:"ok"` Fmahash string `help:"hash value for use in debugging platform-dependent multiply-add use" concurrent:"ok"` GCAdjust int `help:"log adjustments to GOGC" concurrent:"ok"` GCCheck int `help:"check heap/gc use by compiler" concurrent:"ok"` diff --git a/src/cmd/compile/internal/base/flag.go b/src/cmd/compile/internal/base/flag.go index b296f3666c..31ea8622b9 100644 --- a/src/cmd/compile/internal/base/flag.go +++ b/src/cmd/compile/internal/base/flag.go @@ -206,6 +206,7 @@ func ParseFlags() { if Debug.Gossahash != "" { hashDebug = NewHashDebug("gossahash", Debug.Gossahash, nil) } + obj.SetFIPSDebugHash(Debug.FIPSHash) // Compute whether we're compiling the runtime from the package path. Test // code can also use the flag to set this explicitly. diff --git a/src/cmd/compile/internal/staticinit/sched.go b/src/cmd/compile/internal/staticinit/sched.go index 0e2f7119c6..e013823ee7 100644 --- a/src/cmd/compile/internal/staticinit/sched.go +++ b/src/cmd/compile/internal/staticinit/sched.go @@ -279,6 +279,14 @@ func (s *Schedule) staticcopy(l *ir.Name, loff int64, rn *ir.Name, typ *types.Ty } func (s *Schedule) StaticAssign(l *ir.Name, loff int64, r ir.Node, typ *types.Type) bool { + // If we're building for FIPS, avoid global data relocations + // by treating all address-of operations as non-static. + // See ../../../internal/obj/fips.go for more context. + // We do this even in non-PIE mode to avoid generating + // static temporaries that would go into SRODATAFIPS + // but need relocations. We can't handle that in the verification. + disableGlobalAddrs := base.Ctxt.IsFIPS() + if r == nil { // No explicit initialization value. Either zero or supplied // externally. @@ -304,10 +312,16 @@ func (s *Schedule) StaticAssign(l *ir.Name, loff int64, r ir.Node, typ *types.Ty switch r.Op() { case ir.ONAME: + if disableGlobalAddrs { + return false + } r := r.(*ir.Name) return s.staticcopy(l, loff, r, typ) case ir.OMETHEXPR: + if disableGlobalAddrs { + return false + } r := r.(*ir.SelectorExpr) return s.staticcopy(l, loff, r.FuncName(), typ) @@ -322,6 +336,9 @@ func (s *Schedule) StaticAssign(l *ir.Name, loff int64, r ir.Node, typ *types.Ty return true case ir.OADDR: + if disableGlobalAddrs { + return false + } r := r.(*ir.AddrExpr) if name, offset, ok := StaticLoc(r.X); ok && name.Class == ir.PEXTERN { staticdata.InitAddrOffset(l, loff, name.Linksym(), offset) @@ -330,6 +347,9 @@ func (s *Schedule) StaticAssign(l *ir.Name, loff int64, r ir.Node, typ *types.Ty fallthrough case ir.OPTRLIT: + if disableGlobalAddrs { + return false + } r := r.(*ir.AddrExpr) switch r.X.Op() { case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT, ir.OSTRUCTLIT: @@ -346,6 +366,9 @@ func (s *Schedule) StaticAssign(l *ir.Name, loff int64, r ir.Node, typ *types.Ty //dump("not static ptrlit", r); case ir.OSTR2BYTES: + if disableGlobalAddrs { + return false + } r := r.(*ir.ConvExpr) if l.Class == ir.PEXTERN && r.X.Op() == ir.OLITERAL { sval := ir.StringVal(r.X) @@ -354,6 +377,9 @@ func (s *Schedule) StaticAssign(l *ir.Name, loff int64, r ir.Node, typ *types.Ty } case ir.OSLICELIT: + if disableGlobalAddrs { + return false + } r := r.(*ir.CompLitExpr) s.initplan(r) // Init slice. @@ -374,7 +400,7 @@ func (s *Schedule) StaticAssign(l *ir.Name, loff int64, r ir.Node, typ *types.Ty p := s.Plans[r] for i := range p.E { e := &p.E[i] - if e.Expr.Op() == ir.OLITERAL || e.Expr.Op() == ir.ONIL { + if e.Expr.Op() == ir.OLITERAL && !disableGlobalAddrs || e.Expr.Op() == ir.ONIL { staticdata.InitConst(l, loff+e.Xoffset, e.Expr, int(e.Expr.Type().Size())) continue } @@ -388,6 +414,9 @@ func (s *Schedule) StaticAssign(l *ir.Name, loff int64, r ir.Node, typ *types.Ty break case ir.OCLOSURE: + if disableGlobalAddrs { + return false + } r := r.(*ir.ClosureExpr) if !r.Func.IsClosure() { if base.Debug.Closure > 0 { @@ -405,6 +434,10 @@ func (s *Schedule) StaticAssign(l *ir.Name, loff int64, r ir.Node, typ *types.Ty // This logic is mirrored in isStaticCompositeLiteral. // If you change something here, change it there, and vice versa. + if disableGlobalAddrs { + return false + } + // Determine the underlying concrete type and value we are converting from. r := r.(*ir.ConvExpr) val := ir.Node(r) @@ -460,6 +493,9 @@ func (s *Schedule) StaticAssign(l *ir.Name, loff int64, r ir.Node, typ *types.Ty return true case ir.OINLCALL: + if disableGlobalAddrs { + return false + } r := r.(*ir.InlinedCallExpr) return s.staticAssignInlinedCall(l, loff, r, typ) } @@ -728,10 +764,12 @@ func (s *Schedule) staticAssignInlinedCall(l *ir.Name, loff int64, call *ir.Inli var statuniqgen int // name generator for static temps // StaticName returns a name backed by a (writable) static data symbol. -// Use readonlystaticname for read-only node. func StaticName(t *types.Type) *ir.Name { // Don't use LookupNum; it interns the resulting string, but these are all unique. - sym := typecheck.Lookup(fmt.Sprintf("%s%d", obj.StaticNamePref, statuniqgen)) + sym := typecheck.Lookup(fmt.Sprintf("%s%d", obj.StaticNamePrefix, statuniqgen)) + if sym.Name == ".stmp_0" && sym.Pkg.Path == "crypto/internal/fips/check" { + panic("bad") + } statuniqgen++ n := ir.NewNameAt(base.Pos, sym, t) diff --git a/src/cmd/compile/internal/walk/complit.go b/src/cmd/compile/internal/walk/complit.go index cfdc8becfe..70750ab037 100644 --- a/src/cmd/compile/internal/walk/complit.go +++ b/src/cmd/compile/internal/walk/complit.go @@ -153,7 +153,10 @@ func isStaticCompositeLiteral(n ir.Node) bool { case ir.OLITERAL, ir.ONIL: return true case ir.OCONVIFACE: - // See staticassign's OCONVIFACE case for comments. + // See staticinit.Schedule.StaticAssign's OCONVIFACE case for comments. + if base.Ctxt.IsFIPS() && base.Ctxt.Flag_shared { + return false + } n := n.(*ir.ConvExpr) val := ir.Node(n) for val.Op() == ir.OCONVIFACE { diff --git a/src/cmd/compile/internal/walk/order.go b/src/cmd/compile/internal/walk/order.go index 896088901e..613edf497b 100644 --- a/src/cmd/compile/internal/walk/order.go +++ b/src/cmd/compile/internal/walk/order.go @@ -220,7 +220,12 @@ func (o *orderState) safeExpr(n ir.Node) ir.Node { // // n.Left = o.addrTemp(n.Left) func (o *orderState) addrTemp(n ir.Node) ir.Node { - if n.Op() == ir.OLITERAL || n.Op() == ir.ONIL { + // Note: Avoid addrTemp with static assignment for literal strings + // when compiling FIPS packages. + // The problem is that panic("foo") ends up creating a static RODATA temp + // for the implicit conversion of "foo" to any, and we can't handle + // the relocations in that temp. + if n.Op() == ir.ONIL || (n.Op() == ir.OLITERAL && !base.Ctxt.IsFIPS()) { // TODO: expand this to all static composite literal nodes? n = typecheck.DefaultLit(n, nil) types.CalcSize(n.Type()) |
