1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package obj
33
34 import (
35 "cmd/internal/objabi"
36 "log"
37 "math"
38 )
39
40
41 func (s *LSym) Grow(lsiz int64) {
42 siz := int(lsiz)
43 if int64(siz) != lsiz {
44 log.Fatalf("LSym.Grow size %d too long", lsiz)
45 }
46 if len(s.P) >= siz {
47 return
48 }
49 s.P = append(s.P, make([]byte, siz-len(s.P))...)
50 }
51
52
53 func (s *LSym) GrowCap(c int64) {
54 if int64(cap(s.P)) >= c {
55 return
56 }
57 if s.P == nil {
58 s.P = make([]byte, 0, c)
59 return
60 }
61 b := make([]byte, len(s.P), c)
62 copy(b, s.P)
63 s.P = b
64 }
65
66
67 func (s *LSym) prepwrite(ctxt *Link, off int64, siz int) {
68 if off < 0 || siz < 0 || off >= 1<<30 {
69 ctxt.Diag("prepwrite: bad off=%d siz=%d s=%v", off, siz, s)
70 }
71 switch s.Type {
72 case objabi.Sxxx, objabi.SBSS:
73 s.Type = objabi.SDATA
74 case objabi.SNOPTRBSS:
75 s.Type = objabi.SNOPTRDATA
76 case objabi.STLSBSS:
77 ctxt.Diag("cannot supply data for %v var %v", s.Type, s.Name)
78 }
79 s.setFIPSType(ctxt)
80 l := off + int64(siz)
81 s.Grow(l)
82 if l > s.Size {
83 s.Size = l
84 }
85 }
86
87
88 func (s *LSym) WriteFloat32(ctxt *Link, off int64, f float32) {
89 s.prepwrite(ctxt, off, 4)
90 ctxt.Arch.ByteOrder.PutUint32(s.P[off:], math.Float32bits(f))
91 }
92
93
94 func (s *LSym) WriteFloat64(ctxt *Link, off int64, f float64) {
95 s.prepwrite(ctxt, off, 8)
96 ctxt.Arch.ByteOrder.PutUint64(s.P[off:], math.Float64bits(f))
97 }
98
99
100 func (s *LSym) WriteInt(ctxt *Link, off int64, siz int, i int64) {
101 s.prepwrite(ctxt, off, siz)
102 switch siz {
103 default:
104 ctxt.Diag("WriteInt: bad integer size: %d", siz)
105 case 1:
106 s.P[off] = byte(i)
107 case 2:
108 ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(i))
109 case 4:
110 ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(i))
111 case 8:
112 ctxt.Arch.ByteOrder.PutUint64(s.P[off:], uint64(i))
113 }
114 }
115
116 func (s *LSym) writeAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64, rtype objabi.RelocType) {
117
118 if siz != ctxt.Arch.PtrSize && siz != 4 {
119 ctxt.Diag("WriteAddr: bad address size %d in %s", siz, s.Name)
120 }
121 s.prepwrite(ctxt, off, siz)
122 if int64(int32(off)) != off {
123 ctxt.Diag("WriteAddr: off overflow %d in %s", off, s.Name)
124 }
125 s.AddRel(ctxt, Reloc{
126 Type: rtype,
127 Off: int32(off),
128 Siz: uint8(siz),
129 Sym: rsym,
130 Add: roff,
131 })
132 }
133
134
135
136 func (s *LSym) WriteAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64) {
137 s.writeAddr(ctxt, off, siz, rsym, roff, objabi.R_ADDR)
138 }
139
140
141
142
143 func (s *LSym) WriteWeakAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64) {
144 s.writeAddr(ctxt, off, siz, rsym, roff, objabi.R_WEAKADDR)
145 }
146
147
148
149
150
151 func (s *LSym) WriteCURelativeAddr(ctxt *Link, off int64, rsym *LSym, roff int64) {
152 s.writeAddr(ctxt, off, ctxt.Arch.PtrSize, rsym, roff, objabi.R_ADDRCUOFF)
153 }
154
155
156
157
158 func (s *LSym) WriteOff(ctxt *Link, off int64, rsym *LSym, roff int64) {
159 s.prepwrite(ctxt, off, 4)
160 if int64(int32(off)) != off {
161 ctxt.Diag("WriteOff: off overflow %d in %s", off, s.Name)
162 }
163 s.AddRel(ctxt, Reloc{
164 Type: objabi.R_ADDROFF,
165 Off: int32(off),
166 Siz: 4,
167 Sym: rsym,
168 Add: roff,
169 })
170 }
171
172
173
174
175 func (s *LSym) WriteWeakOff(ctxt *Link, off int64, rsym *LSym, roff int64) {
176 s.prepwrite(ctxt, off, 4)
177 if int64(int32(off)) != off {
178 ctxt.Diag("WriteWeakOff: off overflow %d in %s", off, s.Name)
179 }
180 s.AddRel(ctxt, Reloc{
181 Type: objabi.R_WEAKADDROFF,
182 Off: int32(off),
183 Siz: 4,
184 Sym: rsym,
185 Add: roff,
186 })
187 }
188
189
190 func (s *LSym) WriteString(ctxt *Link, off int64, siz int, str string) {
191 if siz < len(str) {
192 ctxt.Diag("WriteString: bad string size: %d < %d", siz, len(str))
193 }
194 s.prepwrite(ctxt, off, siz)
195 copy(s.P[off:off+int64(siz)], str)
196 }
197
198
199 func (s *LSym) WriteBytes(ctxt *Link, off int64, b []byte) int64 {
200 s.prepwrite(ctxt, off, len(b))
201 copy(s.P[off:], b)
202 return off + int64(len(b))
203 }
204
205
206 func (s *LSym) AddRel(ctxt *Link, rel Reloc) {
207 if s.Type.IsFIPS() {
208 s.checkFIPSReloc(ctxt, rel)
209 }
210 s.R = append(s.R, rel)
211 }
212
213
214
215
216
217
218 func (s *LSym) WriteDwTxtAddrx(ctxt *Link, off int64, rsym *LSym, maxFuncs int) {
219 rtype, sz := objabi.FuncCountToDwTxtAddrFlavor(maxFuncs)
220 s.prepwrite(ctxt, off, sz)
221 if int64(int32(off)) != off {
222 ctxt.Diag("WriteDwTxtAddrx: off overflow %d in %s", off, s.Name)
223 }
224 s.AddRel(ctxt, Reloc{
225 Type: rtype,
226 Off: int32(off),
227 Siz: uint8(sz),
228 Sym: rsym,
229 })
230 }
231
View as plain text