1
2
3
4
5 package pkginit
6
7 import (
8 "cmd/compile/internal/base"
9 "cmd/compile/internal/ir"
10 "cmd/compile/internal/noder"
11 "cmd/compile/internal/objw"
12 "cmd/compile/internal/staticinit"
13 "cmd/compile/internal/typecheck"
14 "cmd/compile/internal/types"
15 "cmd/internal/obj"
16 "cmd/internal/objabi"
17 "cmd/internal/src"
18 )
19
20
21
22
23
24
25
26 func MakeTask() {
27 var deps []*obj.LSym
28 var fns []*obj.LSym
29
30
31 for _, pkg := range typecheck.Target.Imports {
32 n, ok := pkg.Lookup(".inittask").Def.(*ir.Name)
33 if !ok {
34 continue
35 }
36 if n.Op() != ir.ONAME || n.Class != ir.PEXTERN {
37 base.Fatalf("bad inittask: %v", n)
38 }
39 deps = append(deps, n.Linksym())
40 }
41 if base.Flag.ASan {
42
43
44
45
46
47
48
49
50
51 for _, n := range typecheck.Target.Externs {
52 if canInstrumentGlobal(n) {
53 name := n.Sym().Name
54 InstrumentGlobalsMap[name] = n
55 InstrumentGlobalsSlice = append(InstrumentGlobalsSlice, n)
56 }
57 }
58 ni := len(InstrumentGlobalsMap)
59 if ni != 0 {
60
61 pos := base.AutogeneratedPos
62 base.Pos = pos
63
64 sym := noder.Renameinit()
65 fnInit := ir.NewFunc(pos, pos, sym, types.NewSignature(nil, nil, nil))
66 typecheck.DeclFunc(fnInit)
67
68
69 globals := instrumentGlobals(fnInit)
70
71
72
73 asancall := ir.NewCallExpr(base.Pos, ir.OCALL, typecheck.LookupRuntime("asanregisterglobals"), nil)
74 asancall.Args.Append(typecheck.ConvNop(typecheck.NodAddr(
75 ir.NewIndexExpr(base.Pos, globals, ir.NewInt(base.Pos, 0))), types.Types[types.TUNSAFEPTR]))
76 asancall.Args.Append(typecheck.DefaultLit(ir.NewInt(base.Pos, int64(ni)), types.Types[types.TUINTPTR]))
77
78 fnInit.Body.Append(asancall)
79 typecheck.FinishFuncBody()
80 ir.CurFunc = fnInit
81 typecheck.Stmts(fnInit.Body)
82 ir.CurFunc = nil
83
84 typecheck.Target.Inits = append(typecheck.Target.Inits, fnInit)
85 }
86 }
87
88
89 for _, fn := range typecheck.Target.Inits {
90 if fn.Sym().Name == "init" {
91
92
93
94 s := staticinit.Schedule{
95 Plans: make(map[ir.Node]*staticinit.Plan),
96 Temps: make(map[ir.Node]*ir.Name),
97 }
98 for _, n := range fn.Body {
99 s.StaticInit(n)
100 }
101 fn.Body = s.Out
102 ir.WithFunc(fn, func() {
103 typecheck.Stmts(fn.Body)
104 })
105
106 if len(fn.Body) == 0 {
107 fn.Body = []ir.Node{ir.NewBlockStmt(src.NoXPos, nil)}
108 }
109 }
110
111
112 if len(fn.Body) == 1 {
113 if stmt := fn.Body[0]; stmt.Op() == ir.OBLOCK && len(stmt.(*ir.BlockStmt).List) == 0 {
114 continue
115 }
116 }
117 fns = append(fns, fn.Nname.Linksym())
118 }
119
120 if len(deps) == 0 && len(fns) == 0 && types.LocalPkg.Path != "main" && types.LocalPkg.Path != "runtime" {
121 return
122 }
123
124
125 sym := typecheck.Lookup(".inittask")
126 task := ir.NewNameAt(base.Pos, sym, types.Types[types.TUINT8])
127 task.Class = ir.PEXTERN
128 sym.Def = task
129 lsym := task.Linksym()
130 ot := 0
131 ot = objw.Uint32(lsym, ot, 0)
132 ot = objw.Uint32(lsym, ot, uint32(len(fns)))
133 for _, f := range fns {
134 ot = objw.SymPtr(lsym, ot, f, 0)
135 }
136
137
138
139
140 for _, d := range deps {
141 lsym.AddRel(base.Ctxt, obj.Reloc{Type: objabi.R_INITORDER, Sym: d})
142 }
143
144
145 objw.Global(lsym, int32(ot), obj.NOPTR)
146 }
147
View as plain text