Source file src/pkg/cmd/link/internal/mips64/asm.go
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 package mips64
32
33 import (
34 "cmd/internal/objabi"
35 "cmd/internal/sys"
36 "cmd/link/internal/ld"
37 "cmd/link/internal/sym"
38 "debug/elf"
39 "fmt"
40 "log"
41 )
42
43 func gentext(ctxt *ld.Link) {}
44
45 func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
46 log.Fatalf("adddynrel not implemented")
47 return false
48 }
49
50 func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
51
52
53
54
55
56
57
58
59
60 ctxt.Out.Write64(uint64(sectoff))
61
62 elfsym := r.Xsym.ElfsymForReloc()
63 ctxt.Out.Write32(uint32(elfsym))
64 ctxt.Out.Write8(0)
65 ctxt.Out.Write8(0)
66 ctxt.Out.Write8(0)
67 switch r.Type {
68 default:
69 return false
70 case objabi.R_ADDR:
71 switch r.Siz {
72 case 4:
73 ctxt.Out.Write8(uint8(elf.R_MIPS_32))
74 case 8:
75 ctxt.Out.Write8(uint8(elf.R_MIPS_64))
76 default:
77 return false
78 }
79 case objabi.R_ADDRMIPS:
80 ctxt.Out.Write8(uint8(elf.R_MIPS_LO16))
81 case objabi.R_ADDRMIPSU:
82 ctxt.Out.Write8(uint8(elf.R_MIPS_HI16))
83 case objabi.R_ADDRMIPSTLS:
84 ctxt.Out.Write8(uint8(elf.R_MIPS_TLS_TPREL_LO16))
85 case objabi.R_CALLMIPS,
86 objabi.R_JMPMIPS:
87 ctxt.Out.Write8(uint8(elf.R_MIPS_26))
88 }
89 ctxt.Out.Write64(uint64(r.Xadd))
90
91 return true
92 }
93
94 func elfsetupplt(ctxt *ld.Link) {
95 return
96 }
97
98 func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
99 return false
100 }
101
102 func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
103 if ctxt.LinkMode == ld.LinkExternal {
104 switch r.Type {
105 default:
106 return val, false
107 case objabi.R_ADDRMIPS,
108 objabi.R_ADDRMIPSU:
109 r.Done = false
110
111
112 rs := r.Sym
113 r.Xadd = r.Add
114 for rs.Outer != nil {
115 r.Xadd += ld.Symaddr(rs) - ld.Symaddr(rs.Outer)
116 rs = rs.Outer
117 }
118
119 if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
120 ld.Errorf(s, "missing section for %s", rs.Name)
121 }
122 r.Xsym = rs
123
124 return val, true
125 case objabi.R_ADDRMIPSTLS,
126 objabi.R_CALLMIPS,
127 objabi.R_JMPMIPS:
128 r.Done = false
129 r.Xsym = r.Sym
130 r.Xadd = r.Add
131 return val, true
132 }
133 }
134
135 switch r.Type {
136 case objabi.R_CONST:
137 return r.Add, true
138 case objabi.R_GOTOFF:
139 return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
140 case objabi.R_ADDRMIPS,
141 objabi.R_ADDRMIPSU:
142 t := ld.Symaddr(r.Sym) + r.Add
143 o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:])
144 if r.Type == objabi.R_ADDRMIPS {
145 return int64(o1&0xffff0000 | uint32(t)&0xffff), true
146 }
147 return int64(o1&0xffff0000 | uint32((t+1<<15)>>16)&0xffff), true
148 case objabi.R_ADDRMIPSTLS:
149
150 t := ld.Symaddr(r.Sym) + r.Add - 0x7000
151 if t < -32768 || t >= 32678 {
152 ld.Errorf(s, "TLS offset out of range %d", t)
153 }
154 o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:])
155 return int64(o1&0xffff0000 | uint32(t)&0xffff), true
156 case objabi.R_CALLMIPS,
157 objabi.R_JMPMIPS:
158
159 t := ld.Symaddr(r.Sym) + r.Add
160 o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:])
161 return int64(o1&0xfc000000 | uint32(t>>2)&^0xfc000000), true
162 }
163
164 return val, false
165 }
166
167 func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
168 return -1
169 }
170
171 func asmb(ctxt *ld.Link) {
172 if ctxt.Debugvlog != 0 {
173 ctxt.Logf("%5.2f asmb\n", ld.Cputime())
174 }
175
176 if ctxt.IsELF {
177 ld.Asmbelfsetup()
178 }
179
180 sect := ld.Segtext.Sections[0]
181 ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
182 ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
183 for _, sect = range ld.Segtext.Sections[1:] {
184 ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
185 ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
186 }
187
188 if ld.Segrodata.Filelen > 0 {
189 if ctxt.Debugvlog != 0 {
190 ctxt.Logf("%5.2f rodatblk\n", ld.Cputime())
191 }
192 ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
193 ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
194 }
195 if ld.Segrelrodata.Filelen > 0 {
196 if ctxt.Debugvlog != 0 {
197 ctxt.Logf("%5.2f rodatblk\n", ld.Cputime())
198 }
199 ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
200 ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
201 }
202
203 if ctxt.Debugvlog != 0 {
204 ctxt.Logf("%5.2f datblk\n", ld.Cputime())
205 }
206
207 ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
208 ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
209
210 ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
211 ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
212 }
213
214 func asmb2(ctxt *ld.Link) {
215
216 ld.Symsize = 0
217
218 ld.Lcsize = 0
219 symo := uint32(0)
220 if !*ld.FlagS {
221
222 if ctxt.Debugvlog != 0 {
223 ctxt.Logf("%5.2f sym\n", ld.Cputime())
224 }
225 switch ctxt.HeadType {
226 default:
227 if ctxt.IsELF {
228 symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
229 symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
230 }
231
232 case objabi.Hplan9:
233 symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
234 }
235
236 ctxt.Out.SeekSet(int64(symo))
237 switch ctxt.HeadType {
238 default:
239 if ctxt.IsELF {
240 if ctxt.Debugvlog != 0 {
241 ctxt.Logf("%5.2f elfsym\n", ld.Cputime())
242 }
243 ld.Asmelfsym(ctxt)
244 ctxt.Out.Flush()
245 ctxt.Out.Write(ld.Elfstrdat)
246
247 if ctxt.LinkMode == ld.LinkExternal {
248 ld.Elfemitreloc(ctxt)
249 }
250 }
251
252 case objabi.Hplan9:
253 ld.Asmplan9sym(ctxt)
254 ctxt.Out.Flush()
255
256 sym := ctxt.Syms.Lookup("pclntab", 0)
257 if sym != nil {
258 ld.Lcsize = int32(len(sym.P))
259 ctxt.Out.Write(sym.P)
260 ctxt.Out.Flush()
261 }
262 }
263 }
264
265 if ctxt.Debugvlog != 0 {
266 ctxt.Logf("%5.2f header\n", ld.Cputime())
267 }
268 ctxt.Out.SeekSet(0)
269 switch ctxt.HeadType {
270 default:
271 case objabi.Hplan9:
272 magic := uint32(4*18*18 + 7)
273 if ctxt.Arch == sys.ArchMIPS64LE {
274 magic = uint32(4*26*26 + 7)
275 }
276 ctxt.Out.Write32(magic)
277 ctxt.Out.Write32(uint32(ld.Segtext.Filelen))
278 ctxt.Out.Write32(uint32(ld.Segdata.Filelen))
279 ctxt.Out.Write32(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
280 ctxt.Out.Write32(uint32(ld.Symsize))
281 ctxt.Out.Write32(uint32(ld.Entryvalue(ctxt)))
282 ctxt.Out.Write32(0)
283 ctxt.Out.Write32(uint32(ld.Lcsize))
284
285 case objabi.Hlinux,
286 objabi.Hfreebsd,
287 objabi.Hnetbsd,
288 objabi.Hopenbsd,
289 objabi.Hnacl:
290 ld.Asmbelf(ctxt, int64(symo))
291 }
292
293 ctxt.Out.Flush()
294 if *ld.FlagC {
295 fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
296 fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
297 fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen)
298 fmt.Printf("symsize=%d\n", ld.Symsize)
299 fmt.Printf("lcsize=%d\n", ld.Lcsize)
300 fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize))
301 }
302 }
303
View as plain text