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 l := off + int64(siz)
80 s.Grow(l)
81 if l > s.Size {
82 s.Size = l
83 }
84 }
85
86
87 func (s *LSym) WriteFloat32(ctxt *Link, off int64, f float32) {
88 s.prepwrite(ctxt, off, 4)
89 ctxt.Arch.ByteOrder.PutUint32(s.P[off:], math.Float32bits(f))
90 }
91
92
93 func (s *LSym) WriteFloat64(ctxt *Link, off int64, f float64) {
94 s.prepwrite(ctxt, off, 8)
95 ctxt.Arch.ByteOrder.PutUint64(s.P[off:], math.Float64bits(f))
96 }
97
98
99 func (s *LSym) WriteInt(ctxt *Link, off int64, siz int, i int64) {
100 s.prepwrite(ctxt, off, siz)
101 switch siz {
102 default:
103 ctxt.Diag("WriteInt: bad integer size: %d", siz)
104 case 1:
105 s.P[off] = byte(i)
106 case 2:
107 ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(i))
108 case 4:
109 ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(i))
110 case 8:
111 ctxt.Arch.ByteOrder.PutUint64(s.P[off:], uint64(i))
112 }
113 }
114
115 func (s *LSym) writeAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64, rtype objabi.RelocType) {
116
117 if siz != ctxt.Arch.PtrSize && siz != 4 {
118 ctxt.Diag("WriteAddr: bad address size %d in %s", siz, s.Name)
119 }
120 s.prepwrite(ctxt, off, siz)
121 r := Addrel(s)
122 r.Off = int32(off)
123 if int64(r.Off) != off {
124 ctxt.Diag("WriteAddr: off overflow %d in %s", off, s.Name)
125 }
126 r.Siz = uint8(siz)
127 r.Sym = rsym
128 r.Type = rtype
129 r.Add = roff
130 }
131
132
133
134 func (s *LSym) WriteAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64) {
135 s.writeAddr(ctxt, off, siz, rsym, roff, objabi.R_ADDR)
136 }
137
138
139
140
141 func (s *LSym) WriteWeakAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64) {
142 s.writeAddr(ctxt, off, siz, rsym, roff, objabi.R_WEAKADDR)
143 }
144
145
146
147
148
149 func (s *LSym) WriteCURelativeAddr(ctxt *Link, off int64, rsym *LSym, roff int64) {
150 s.writeAddr(ctxt, off, ctxt.Arch.PtrSize, rsym, roff, objabi.R_ADDRCUOFF)
151 }
152
153
154
155
156 func (s *LSym) WriteOff(ctxt *Link, off int64, rsym *LSym, roff int64) {
157 s.prepwrite(ctxt, off, 4)
158 r := Addrel(s)
159 r.Off = int32(off)
160 if int64(r.Off) != off {
161 ctxt.Diag("WriteOff: off overflow %d in %s", off, s.Name)
162 }
163 r.Siz = 4
164 r.Sym = rsym
165 r.Type = objabi.R_ADDROFF
166 r.Add = roff
167 }
168
169
170
171
172 func (s *LSym) WriteWeakOff(ctxt *Link, off int64, rsym *LSym, roff int64) {
173 s.prepwrite(ctxt, off, 4)
174 r := Addrel(s)
175 r.Off = int32(off)
176 if int64(r.Off) != off {
177 ctxt.Diag("WriteOff: off overflow %d in %s", off, s.Name)
178 }
179 r.Siz = 4
180 r.Sym = rsym
181 r.Type = objabi.R_WEAKADDROFF
182 r.Add = roff
183 }
184
185
186 func (s *LSym) WriteString(ctxt *Link, off int64, siz int, str string) {
187 if siz < len(str) {
188 ctxt.Diag("WriteString: bad string size: %d < %d", siz, len(str))
189 }
190 s.prepwrite(ctxt, off, siz)
191 copy(s.P[off:off+int64(siz)], str)
192 }
193
194
195 func (s *LSym) WriteBytes(ctxt *Link, off int64, b []byte) int64 {
196 s.prepwrite(ctxt, off, len(b))
197 copy(s.P[off:], b)
198 return off + int64(len(b))
199 }
200
201 func Addrel(s *LSym) *Reloc {
202 if s.R == nil {
203 s.R = make([]Reloc, 0, 4)
204 }
205 s.R = append(s.R, Reloc{})
206 return &s.R[len(s.R)-1]
207 }
208
View as plain text