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 arm
32
33 import (
34 "cmd/internal/objabi"
35 "cmd/internal/sys"
36 "cmd/link/internal/ld"
37 "cmd/link/internal/loader"
38 "cmd/link/internal/sym"
39 "debug/elf"
40 "fmt"
41 "log"
42 )
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 func gentext(ctxt *ld.Link, ldr *loader.Loader) {
66 initfunc, addmoduledata := ld.PrepareAddmoduledata(ctxt)
67 if initfunc == nil {
68 return
69 }
70
71 o := func(op uint32) {
72 initfunc.AddUint32(ctxt.Arch, op)
73 }
74 o(0xe59f0004)
75 o(0xe08f0000)
76
77 o(0xeafffffe)
78 rel, _ := initfunc.AddRel(objabi.R_CALLARM)
79 rel.SetOff(8)
80 rel.SetSiz(4)
81 rel.SetSym(addmoduledata)
82 rel.SetAdd(0xeafffffe)
83
84 o(0x00000000)
85
86 rel2, _ := initfunc.AddRel(objabi.R_PCREL)
87 rel2.SetOff(12)
88 rel2.SetSiz(4)
89 rel2.SetSym(ctxt.Moduledata)
90 rel2.SetAdd(4)
91 }
92
93
94
95 func braddoff(a int32, b int32) int32 {
96 return int32((uint32(a))&0xff000000 | 0x00ffffff&uint32(a+b))
97 }
98
99 func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc, rIdx int) bool {
100
101 targ := r.Sym()
102 var targType sym.SymKind
103 if targ != 0 {
104 targType = ldr.SymType(targ)
105 }
106
107 switch r.Type() {
108 default:
109 if r.Type() >= objabi.ElfRelocOffset {
110 ldr.Errorf(s, "unexpected relocation type %d (%s)", r.Type(), sym.RelocName(target.Arch, r.Type()))
111 return false
112 }
113
114
115 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_PLT32):
116 su := ldr.MakeSymbolUpdater(s)
117 su.SetRelocType(rIdx, objabi.R_CALLARM)
118
119 if targType == sym.SDYNIMPORT {
120 addpltsym(target, ldr, syms, targ)
121 su.SetRelocSym(rIdx, syms.PLT)
122 su.SetRelocAdd(rIdx, int64(braddoff(int32(r.Add()), ldr.SymPlt(targ)/4)))
123 }
124
125 return true
126
127 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_THM_PC22):
128 ld.Exitf("R_ARM_THM_CALL, are you using -marm?")
129 return false
130
131 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOT32):
132 if targType != sym.SDYNIMPORT {
133 addgotsyminternal(target, ldr, syms, targ)
134 } else {
135 ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_ARM_GLOB_DAT))
136 }
137
138 su := ldr.MakeSymbolUpdater(s)
139 su.SetRelocType(rIdx, objabi.R_CONST)
140 su.SetRelocSym(rIdx, 0)
141 su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ)))
142 return true
143
144 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOT_PREL):
145 if targType != sym.SDYNIMPORT {
146 addgotsyminternal(target, ldr, syms, targ)
147 } else {
148 ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_ARM_GLOB_DAT))
149 }
150 su := ldr.MakeSymbolUpdater(s)
151 su.SetRelocType(rIdx, objabi.R_PCREL)
152 su.SetRelocSym(rIdx, syms.GOT)
153 su.SetRelocAdd(rIdx, r.Add()+4+int64(ldr.SymGot(targ)))
154 return true
155
156 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOTOFF):
157 su := ldr.MakeSymbolUpdater(s)
158 su.SetRelocType(rIdx, objabi.R_GOTOFF)
159 return true
160
161 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOTPC):
162 su := ldr.MakeSymbolUpdater(s)
163 su.SetRelocType(rIdx, objabi.R_PCREL)
164 su.SetRelocSym(rIdx, syms.GOT)
165 su.SetRelocAdd(rIdx, r.Add()+4)
166 return true
167
168 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_CALL):
169 su := ldr.MakeSymbolUpdater(s)
170 su.SetRelocType(rIdx, objabi.R_CALLARM)
171 if targType == sym.SDYNIMPORT {
172 addpltsym(target, ldr, syms, targ)
173 su.SetRelocSym(rIdx, syms.PLT)
174 su.SetRelocAdd(rIdx, int64(braddoff(int32(r.Add()), ldr.SymPlt(targ)/4)))
175 }
176 return true
177
178 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_REL32):
179 su := ldr.MakeSymbolUpdater(s)
180 su.SetRelocType(rIdx, objabi.R_PCREL)
181 su.SetRelocAdd(rIdx, r.Add()+4)
182 return true
183
184 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_ABS32):
185 if targType == sym.SDYNIMPORT {
186 ldr.Errorf(s, "unexpected R_ARM_ABS32 relocation for dynamic symbol %s", ldr.SymName(targ))
187 }
188 su := ldr.MakeSymbolUpdater(s)
189 su.SetRelocType(rIdx, objabi.R_ADDR)
190 return true
191
192 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_PC24),
193 objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_JUMP24):
194 su := ldr.MakeSymbolUpdater(s)
195 su.SetRelocType(rIdx, objabi.R_CALLARM)
196 if targType == sym.SDYNIMPORT {
197 addpltsym(target, ldr, syms, targ)
198 su.SetRelocSym(rIdx, syms.PLT)
199 su.SetRelocAdd(rIdx, int64(braddoff(int32(r.Add()), ldr.SymPlt(targ)/4)))
200 }
201
202 return true
203 }
204
205
206 if targType != sym.SDYNIMPORT {
207 return true
208 }
209
210
211 relocs := ldr.Relocs(s)
212 r = relocs.At(rIdx)
213
214 switch r.Type() {
215 case objabi.R_CALLARM:
216 if target.IsExternal() {
217
218 return true
219 }
220 addpltsym(target, ldr, syms, targ)
221 su := ldr.MakeSymbolUpdater(s)
222 su.SetRelocSym(rIdx, syms.PLT)
223 su.SetRelocAdd(rIdx, int64(braddoff(int32(r.Add()), ldr.SymPlt(targ)/4)))
224 return true
225
226 case objabi.R_ADDR:
227 if ldr.SymType(s) != sym.SDATA {
228 break
229 }
230 if target.IsElf() {
231 ld.Adddynsym(ldr, target, syms, targ)
232 rel := ldr.MakeSymbolUpdater(syms.Rel)
233 rel.AddAddrPlus(target.Arch, s, int64(r.Off()))
234 rel.AddUint32(target.Arch, elf.R_INFO32(uint32(ldr.SymDynid(targ)), uint32(elf.R_ARM_GLOB_DAT)))
235 su := ldr.MakeSymbolUpdater(s)
236 su.SetRelocType(rIdx, objabi.R_CONST)
237 su.SetRelocSym(rIdx, 0)
238 return true
239 }
240
241 case objabi.R_GOTPCREL:
242 if target.IsExternal() {
243
244 return true
245 }
246 if targType != sym.SDYNIMPORT {
247 ldr.Errorf(s, "R_GOTPCREL target is not SDYNIMPORT symbol: %v", ldr.SymName(targ))
248 }
249 ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_ARM_GLOB_DAT))
250 su := ldr.MakeSymbolUpdater(s)
251 su.SetRelocType(rIdx, objabi.R_PCREL)
252 su.SetRelocSym(rIdx, syms.GOT)
253 su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ)))
254 return true
255 }
256
257 return false
258 }
259
260 func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtReloc, ri int, sectoff int64) bool {
261 out.Write32(uint32(sectoff))
262
263 elfsym := ld.ElfSymForReloc(ctxt, r.Xsym)
264 siz := r.Size
265 switch r.Type {
266 default:
267 return false
268 case objabi.R_ADDR, objabi.R_DWARFSECREF:
269 if siz == 4 {
270 out.Write32(uint32(elf.R_ARM_ABS32) | uint32(elfsym)<<8)
271 } else {
272 return false
273 }
274 case objabi.R_PCREL:
275 if siz == 4 {
276 out.Write32(uint32(elf.R_ARM_REL32) | uint32(elfsym)<<8)
277 } else {
278 return false
279 }
280 case objabi.R_CALLARM:
281 if siz == 4 {
282 relocs := ldr.Relocs(s)
283 r := relocs.At(ri)
284 if r.Add()&0xff000000 == 0xeb000000 {
285 out.Write32(uint32(elf.R_ARM_CALL) | uint32(elfsym)<<8)
286 } else {
287 out.Write32(uint32(elf.R_ARM_JUMP24) | uint32(elfsym)<<8)
288 }
289 } else {
290 return false
291 }
292 case objabi.R_TLS_LE:
293 out.Write32(uint32(elf.R_ARM_TLS_LE32) | uint32(elfsym)<<8)
294 case objabi.R_TLS_IE:
295 out.Write32(uint32(elf.R_ARM_TLS_IE32) | uint32(elfsym)<<8)
296 case objabi.R_GOTPCREL:
297 if siz == 4 {
298 out.Write32(uint32(elf.R_ARM_GOT_PREL) | uint32(elfsym)<<8)
299 } else {
300 return false
301 }
302 }
303
304 return true
305 }
306
307 func elfsetupplt(ctxt *ld.Link, ldr *loader.Loader, plt, got *loader.SymbolBuilder, dynamic loader.Sym) {
308 if plt.Size() == 0 {
309
310 plt.AddUint32(ctxt.Arch, 0xe52de004)
311
312
313 plt.AddUint32(ctxt.Arch, 0xe59fe004)
314
315
316 plt.AddUint32(ctxt.Arch, 0xe08fe00e)
317
318
319 plt.AddUint32(ctxt.Arch, 0xe5bef008)
320
321
322 plt.AddPCRelPlus(ctxt.Arch, got.Sym(), 4)
323
324
325 got.AddUint32(ctxt.Arch, 0)
326
327 got.AddUint32(ctxt.Arch, 0)
328 got.AddUint32(ctxt.Arch, 0)
329 }
330 }
331
332 func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int64) bool {
333 return false
334 }
335
336 func pereloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtReloc, sectoff int64) bool {
337 rs := r.Xsym
338 rt := r.Type
339
340 if ldr.SymDynid(rs) < 0 {
341 ldr.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymType(rs), ldr.SymType(rs))
342 return false
343 }
344
345 out.Write32(uint32(sectoff))
346 out.Write32(uint32(ldr.SymDynid(rs)))
347
348 var v uint32
349 switch rt {
350 default:
351
352 return false
353
354 case objabi.R_DWARFSECREF:
355 v = ld.IMAGE_REL_ARM_SECREL
356
357 case objabi.R_ADDR:
358 v = ld.IMAGE_REL_ARM_ADDR32
359
360 case objabi.R_PEIMAGEOFF:
361 v = ld.IMAGE_REL_ARM_ADDR32NB
362 }
363
364 out.Write16(uint16(v))
365
366 return true
367 }
368
369
370 func signext24(x int64) int32 {
371 return (int32(x) << 8) >> 8
372 }
373
374
375 func immrot(v uint32) uint32 {
376 for i := 0; i < 16; i++ {
377 if v&^0xff == 0 {
378 return uint32(i<<8) | v | 1<<25
379 }
380 v = v<<2 | v>>30
381 }
382 return 0
383 }
384
385
386 func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) {
387 relocs := ldr.Relocs(s)
388 r := relocs.At(ri)
389 switch r.Type() {
390 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_CALL),
391 objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_PC24),
392 objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_JUMP24):
393
394
395 fallthrough
396 case objabi.R_CALLARM:
397 var t int64
398
399
400
401 if ldr.SymValue(rs) != 0 {
402
403
404
405
406
407
408
409
410
411
412
413
414
415 if ctxt.IsExternal() {
416 t = (ldr.SymValue(rs) - (ldr.SymValue(s) + int64(r.Off()))) / 4
417 } else {
418
419
420 t = (ldr.SymValue(rs) + int64(signext24(r.Add()&0xffffff)*4) - (ldr.SymValue(s) + int64(r.Off()))) / 4
421 }
422 }
423 if t > 0x7fffff || t <= -0x800000 || ldr.SymValue(rs) == 0 || (*ld.FlagDebugTramp > 1 && ldr.SymPkg(s) != ldr.SymPkg(rs)) {
424
425
426
427 offset := (signext24(r.Add()&0xffffff) + 2) * 4
428 var tramp loader.Sym
429 for i := 0; ; i++ {
430 oName := ldr.SymName(rs)
431 name := oName + fmt.Sprintf("%+d-tramp%d", offset, i)
432 tramp = ldr.LookupOrCreateSym(name, int(ldr.SymVersion(rs)))
433 ldr.SetAttrReachable(tramp, true)
434 if ldr.SymType(tramp) == sym.SDYNIMPORT {
435
436 continue
437 }
438 if oName == "runtime.deferreturn" {
439 ldr.SetIsDeferReturnTramp(tramp, true)
440 }
441 if ldr.SymValue(tramp) == 0 {
442
443
444
445 break
446 }
447
448 t = (ldr.SymValue(tramp) - 8 - (ldr.SymValue(s) + int64(r.Off()))) / 4
449 if t >= -0x800000 && t < 0x7fffff {
450
451
452 break
453 }
454 }
455 if ldr.SymType(tramp) == 0 {
456
457 trampb := ldr.MakeSymbolUpdater(tramp)
458 ctxt.AddTramp(trampb)
459 if ctxt.DynlinkingGo() || ldr.SymType(rs) == sym.SDYNIMPORT {
460 if immrot(uint32(offset)) == 0 {
461 ctxt.Errorf(s, "odd offset in dynlink direct call: %v+%d", ldr.SymName(rs), offset)
462 }
463 gentrampdyn(ctxt.Arch, trampb, rs, int64(offset))
464 } else if ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE {
465 gentramppic(ctxt.Arch, trampb, rs, int64(offset))
466 } else {
467 gentramp(ctxt.Arch, ctxt.LinkMode, ldr, trampb, rs, int64(offset))
468 }
469 }
470
471 sb := ldr.MakeSymbolUpdater(s)
472 relocs := sb.Relocs()
473 r := relocs.At(ri)
474 r.SetSym(tramp)
475 r.SetAdd(r.Add()&0xff000000 | 0xfffffe)
476 }
477 default:
478 ctxt.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type(), sym.RelocName(ctxt.Arch, r.Type()))
479 }
480 }
481
482
483 func gentramp(arch *sys.Arch, linkmode ld.LinkMode, ldr *loader.Loader, tramp *loader.SymbolBuilder, target loader.Sym, offset int64) {
484 tramp.SetSize(12)
485 P := make([]byte, tramp.Size())
486 t := ldr.SymValue(target) + offset
487 o1 := uint32(0xe5900000 | 12<<12 | 15<<16)
488 o2 := uint32(0xe12fff10 | 12)
489 o3 := uint32(t)
490 arch.ByteOrder.PutUint32(P, o1)
491 arch.ByteOrder.PutUint32(P[4:], o2)
492 arch.ByteOrder.PutUint32(P[8:], o3)
493 tramp.SetData(P)
494
495 if linkmode == ld.LinkExternal || ldr.SymValue(target) == 0 {
496 r, _ := tramp.AddRel(objabi.R_ADDR)
497 r.SetOff(8)
498 r.SetSiz(4)
499 r.SetSym(target)
500 r.SetAdd(offset)
501 }
502 }
503
504
505 func gentramppic(arch *sys.Arch, tramp *loader.SymbolBuilder, target loader.Sym, offset int64) {
506 tramp.SetSize(16)
507 P := make([]byte, tramp.Size())
508 o1 := uint32(0xe5900000 | 12<<12 | 15<<16 | 4)
509 o2 := uint32(0xe0800000 | 12<<12 | 15<<16 | 12)
510 o3 := uint32(0xe12fff10 | 12)
511 o4 := uint32(0)
512 arch.ByteOrder.PutUint32(P, o1)
513 arch.ByteOrder.PutUint32(P[4:], o2)
514 arch.ByteOrder.PutUint32(P[8:], o3)
515 arch.ByteOrder.PutUint32(P[12:], o4)
516 tramp.SetData(P)
517
518 r, _ := tramp.AddRel(objabi.R_PCREL)
519 r.SetOff(12)
520 r.SetSiz(4)
521 r.SetSym(target)
522 r.SetAdd(offset + 4)
523 }
524
525
526 func gentrampdyn(arch *sys.Arch, tramp *loader.SymbolBuilder, target loader.Sym, offset int64) {
527 tramp.SetSize(20)
528 o1 := uint32(0xe5900000 | 12<<12 | 15<<16 | 8)
529 o2 := uint32(0xe0800000 | 12<<12 | 15<<16 | 12)
530 o3 := uint32(0xe5900000 | 12<<12 | 12<<16)
531 o4 := uint32(0xe12fff10 | 12)
532 o5 := uint32(0)
533 o6 := uint32(0)
534 if offset != 0 {
535
536 tramp.SetSize(24)
537 o6 = o5
538 o5 = o4
539 o4 = 0xe2800000 | 12<<12 | 12<<16 | immrot(uint32(offset))
540 o1 = uint32(0xe5900000 | 12<<12 | 15<<16 | 12)
541 }
542 P := make([]byte, tramp.Size())
543 arch.ByteOrder.PutUint32(P, o1)
544 arch.ByteOrder.PutUint32(P[4:], o2)
545 arch.ByteOrder.PutUint32(P[8:], o3)
546 arch.ByteOrder.PutUint32(P[12:], o4)
547 arch.ByteOrder.PutUint32(P[16:], o5)
548 if offset != 0 {
549 arch.ByteOrder.PutUint32(P[20:], o6)
550 }
551 tramp.SetData(P)
552
553 r, _ := tramp.AddRel(objabi.R_GOTPCREL)
554 r.SetOff(16)
555 r.SetSiz(4)
556 r.SetSym(target)
557 r.SetAdd(8)
558 if offset != 0 {
559
560 r.SetOff(20)
561 r.SetAdd(12)
562 }
563 }
564
565 func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc, s loader.Sym, val int64) (o int64, nExtReloc int, ok bool) {
566 rs := r.Sym()
567 if target.IsExternal() {
568 switch r.Type() {
569 case objabi.R_CALLARM:
570
571 _, off := ld.FoldSubSymbolOffset(ldr, rs)
572 xadd := int64(signext24(r.Add()&0xffffff))*4 + off
573 if xadd/4 > 0x7fffff || xadd/4 < -0x800000 {
574 ldr.Errorf(s, "direct call too far %d", xadd/4)
575 }
576 return int64(braddoff(int32(0xff000000&uint32(r.Add())), int32(0xffffff&uint32(xadd/4)))), 1, true
577 }
578 return -1, 0, false
579 }
580
581 const isOk = true
582 const noExtReloc = 0
583 switch r.Type() {
584
585
586 case objabi.R_PLT0:
587 if ldr.SymValue(syms.GOTPLT) < ldr.SymValue(syms.PLT) {
588 ldr.Errorf(s, ".got.plt should be placed after .plt section.")
589 }
590 return 0xe28fc600 + (0xff & (int64(uint32(ldr.SymValue(rs)-(ldr.SymValue(syms.PLT)+int64(r.Off()))+r.Add())) >> 20)), noExtReloc, isOk
591 case objabi.R_PLT1:
592 return 0xe28cca00 + (0xff & (int64(uint32(ldr.SymValue(rs)-(ldr.SymValue(syms.PLT)+int64(r.Off()))+r.Add()+4)) >> 12)), noExtReloc, isOk
593 case objabi.R_PLT2:
594 return 0xe5bcf000 + (0xfff & int64(uint32(ldr.SymValue(rs)-(ldr.SymValue(syms.PLT)+int64(r.Off()))+r.Add()+8))), noExtReloc, isOk
595 case objabi.R_CALLARM:
596
597
598 t := (ldr.SymValue(rs) + int64(signext24(r.Add()&0xffffff)*4) - (ldr.SymValue(s) + int64(r.Off()))) / 4
599 if t > 0x7fffff || t < -0x800000 {
600 ldr.Errorf(s, "direct call too far: %s %x", ldr.SymName(rs), t)
601 }
602 return int64(braddoff(int32(0xff000000&uint32(r.Add())), int32(0xffffff&t))), noExtReloc, isOk
603 }
604
605 return val, 0, false
606 }
607
608 func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant, loader.Sym, int64, []byte) int64 {
609 log.Fatalf("unexpected relocation variant")
610 return -1
611 }
612
613 func extreloc(target *ld.Target, ldr *loader.Loader, r loader.Reloc, s loader.Sym) (loader.ExtReloc, bool) {
614 rs := r.Sym()
615 var rr loader.ExtReloc
616 switch r.Type() {
617 case objabi.R_CALLARM:
618
619 rs, off := ld.FoldSubSymbolOffset(ldr, rs)
620 rr.Xadd = int64(signext24(r.Add()&0xffffff))*4 + off
621 rst := ldr.SymType(rs)
622 if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && rst != sym.SUNDEFEXT && ldr.SymSect(rs) == nil {
623 ldr.Errorf(s, "missing section for %s", ldr.SymName(rs))
624 }
625 rr.Xsym = rs
626 rr.Type = r.Type()
627 rr.Size = r.Siz()
628 return rr, true
629 }
630 return rr, false
631 }
632
633 func addpltreloc(ldr *loader.Loader, plt *loader.SymbolBuilder, got *loader.SymbolBuilder, s loader.Sym, typ objabi.RelocType) {
634 r, _ := plt.AddRel(typ)
635 r.SetSym(got.Sym())
636 r.SetOff(int32(plt.Size()))
637 r.SetSiz(4)
638 r.SetAdd(int64(ldr.SymGot(s)) - 8)
639
640 plt.SetReachable(true)
641 plt.SetSize(plt.Size() + 4)
642 plt.Grow(plt.Size())
643 }
644
645 func addpltsym(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
646 if ldr.SymPlt(s) >= 0 {
647 return
648 }
649
650 ld.Adddynsym(ldr, target, syms, s)
651
652 if target.IsElf() {
653 plt := ldr.MakeSymbolUpdater(syms.PLT)
654 got := ldr.MakeSymbolUpdater(syms.GOTPLT)
655 rel := ldr.MakeSymbolUpdater(syms.RelPLT)
656 if plt.Size() == 0 {
657 panic("plt is not set up")
658 }
659
660
661 ldr.SetGot(s, int32(got.Size()))
662
663
664
665
666 got.AddAddrPlus(target.Arch, plt.Sym(), 0)
667
668
669 ldr.SetPlt(s, int32(plt.Size()))
670
671 addpltreloc(ldr, plt, got, s, objabi.R_PLT0)
672 addpltreloc(ldr, plt, got, s, objabi.R_PLT1)
673 addpltreloc(ldr, plt, got, s, objabi.R_PLT2)
674
675
676 rel.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s)))
677
678 rel.AddUint32(target.Arch, elf.R_INFO32(uint32(ldr.SymDynid(s)), uint32(elf.R_ARM_JUMP_SLOT)))
679 } else {
680 ldr.Errorf(s, "addpltsym: unsupported binary format")
681 }
682 }
683
684 func addgotsyminternal(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
685 if ldr.SymGot(s) >= 0 {
686 return
687 }
688
689 got := ldr.MakeSymbolUpdater(syms.GOT)
690 ldr.SetGot(s, int32(got.Size()))
691 got.AddAddrPlus(target.Arch, s, 0)
692
693 if target.IsElf() {
694 } else {
695 ldr.Errorf(s, "addgotsyminternal: unsupported binary format")
696 }
697 }
698
View as plain text