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, 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
361 out.Write16(uint16(v))
362
363 return true
364 }
365
366
367 func signext24(x int64) int32 {
368 return (int32(x) << 8) >> 8
369 }
370
371
372 func immrot(v uint32) uint32 {
373 for i := 0; i < 16; i++ {
374 if v&^0xff == 0 {
375 return uint32(i<<8) | v | 1<<25
376 }
377 v = v<<2 | v>>30
378 }
379 return 0
380 }
381
382
383 func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) {
384 relocs := ldr.Relocs(s)
385 r := relocs.At(ri)
386 switch r.Type() {
387 case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_CALL),
388 objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_PC24),
389 objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_JUMP24):
390
391
392 fallthrough
393 case objabi.R_CALLARM:
394 var t int64
395
396
397
398 if ldr.SymValue(rs) != 0 {
399
400
401 t = (ldr.SymValue(rs) + int64(signext24(r.Add()&0xffffff)*4) - (ldr.SymValue(s) + int64(r.Off()))) / 4
402 }
403 if t > 0x7fffff || t < -0x800000 || ldr.SymValue(rs) == 0 || (*ld.FlagDebugTramp > 1 && ldr.SymPkg(s) != ldr.SymPkg(rs)) {
404
405
406
407 offset := (signext24(r.Add()&0xffffff) + 2) * 4
408 var tramp loader.Sym
409 for i := 0; ; i++ {
410 oName := ldr.SymName(rs)
411 name := oName + fmt.Sprintf("%+d-tramp%d", offset, i)
412 tramp = ldr.LookupOrCreateSym(name, int(ldr.SymVersion(rs)))
413 ldr.SetAttrReachable(tramp, true)
414 if ldr.SymType(tramp) == sym.SDYNIMPORT {
415
416 continue
417 }
418 if oName == "runtime.deferreturn" {
419 ldr.SetIsDeferReturnTramp(tramp, true)
420 }
421 if ldr.SymValue(tramp) == 0 {
422
423
424
425 break
426 }
427
428 t = (ldr.SymValue(tramp) - 8 - (ldr.SymValue(s) + int64(r.Off()))) / 4
429 if t >= -0x800000 && t < 0x7fffff {
430
431
432 break
433 }
434 }
435 if ldr.SymType(tramp) == 0 {
436
437 trampb := ldr.MakeSymbolUpdater(tramp)
438 ctxt.AddTramp(trampb)
439 if ctxt.DynlinkingGo() || ldr.SymType(rs) == sym.SDYNIMPORT {
440 if immrot(uint32(offset)) == 0 {
441 ctxt.Errorf(s, "odd offset in dynlink direct call: %v+%d", ldr.SymName(rs), offset)
442 }
443 gentrampdyn(ctxt.Arch, trampb, rs, int64(offset))
444 } else if ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE {
445 gentramppic(ctxt.Arch, trampb, rs, int64(offset))
446 } else {
447 gentramp(ctxt.Arch, ctxt.LinkMode, ldr, trampb, rs, int64(offset))
448 }
449 }
450
451 sb := ldr.MakeSymbolUpdater(s)
452 relocs := sb.Relocs()
453 r := relocs.At(ri)
454 r.SetSym(tramp)
455 r.SetAdd(r.Add()&0xff000000 | 0xfffffe)
456 }
457 default:
458 ctxt.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type(), sym.RelocName(ctxt.Arch, r.Type()))
459 }
460 }
461
462
463 func gentramp(arch *sys.Arch, linkmode ld.LinkMode, ldr *loader.Loader, tramp *loader.SymbolBuilder, target loader.Sym, offset int64) {
464 tramp.SetSize(12)
465 P := make([]byte, tramp.Size())
466 t := ldr.SymValue(target) + offset
467 o1 := uint32(0xe5900000 | 12<<12 | 15<<16)
468 o2 := uint32(0xe12fff10 | 12)
469 o3 := uint32(t)
470 arch.ByteOrder.PutUint32(P, o1)
471 arch.ByteOrder.PutUint32(P[4:], o2)
472 arch.ByteOrder.PutUint32(P[8:], o3)
473 tramp.SetData(P)
474
475 if linkmode == ld.LinkExternal || ldr.SymValue(target) == 0 {
476 r, _ := tramp.AddRel(objabi.R_ADDR)
477 r.SetOff(8)
478 r.SetSiz(4)
479 r.SetSym(target)
480 r.SetAdd(offset)
481 }
482 }
483
484
485 func gentramppic(arch *sys.Arch, tramp *loader.SymbolBuilder, target loader.Sym, offset int64) {
486 tramp.SetSize(16)
487 P := make([]byte, tramp.Size())
488 o1 := uint32(0xe5900000 | 12<<12 | 15<<16 | 4)
489 o2 := uint32(0xe0800000 | 12<<12 | 15<<16 | 12)
490 o3 := uint32(0xe12fff10 | 12)
491 o4 := uint32(0)
492 arch.ByteOrder.PutUint32(P, o1)
493 arch.ByteOrder.PutUint32(P[4:], o2)
494 arch.ByteOrder.PutUint32(P[8:], o3)
495 arch.ByteOrder.PutUint32(P[12:], o4)
496 tramp.SetData(P)
497
498 r, _ := tramp.AddRel(objabi.R_PCREL)
499 r.SetOff(12)
500 r.SetSiz(4)
501 r.SetSym(target)
502 r.SetAdd(offset + 4)
503 }
504
505
506 func gentrampdyn(arch *sys.Arch, tramp *loader.SymbolBuilder, target loader.Sym, offset int64) {
507 tramp.SetSize(20)
508 o1 := uint32(0xe5900000 | 12<<12 | 15<<16 | 8)
509 o2 := uint32(0xe0800000 | 12<<12 | 15<<16 | 12)
510 o3 := uint32(0xe5900000 | 12<<12 | 12<<16)
511 o4 := uint32(0xe12fff10 | 12)
512 o5 := uint32(0)
513 o6 := uint32(0)
514 if offset != 0 {
515
516 tramp.SetSize(24)
517 o6 = o5
518 o5 = o4
519 o4 = 0xe2800000 | 12<<12 | 12<<16 | immrot(uint32(offset))
520 o1 = uint32(0xe5900000 | 12<<12 | 15<<16 | 12)
521 }
522 P := make([]byte, tramp.Size())
523 arch.ByteOrder.PutUint32(P, o1)
524 arch.ByteOrder.PutUint32(P[4:], o2)
525 arch.ByteOrder.PutUint32(P[8:], o3)
526 arch.ByteOrder.PutUint32(P[12:], o4)
527 arch.ByteOrder.PutUint32(P[16:], o5)
528 if offset != 0 {
529 arch.ByteOrder.PutUint32(P[20:], o6)
530 }
531 tramp.SetData(P)
532
533 r, _ := tramp.AddRel(objabi.R_GOTPCREL)
534 r.SetOff(16)
535 r.SetSiz(4)
536 r.SetSym(target)
537 r.SetAdd(8)
538 if offset != 0 {
539
540 r.SetOff(20)
541 r.SetAdd(12)
542 }
543 }
544
545 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) {
546 rs := r.Sym()
547 if target.IsExternal() {
548 switch r.Type() {
549 case objabi.R_CALLARM:
550
551 _, off := ld.FoldSubSymbolOffset(ldr, rs)
552 xadd := int64(signext24(r.Add()&0xffffff))*4 + off
553 if xadd/4 > 0x7fffff || xadd/4 < -0x800000 {
554 ldr.Errorf(s, "direct call too far %d", xadd/4)
555 }
556 return int64(braddoff(int32(0xff000000&uint32(r.Add())), int32(0xffffff&uint32(xadd/4)))), 1, true
557 }
558 return -1, 0, false
559 }
560
561 const isOk = true
562 const noExtReloc = 0
563 switch r.Type() {
564
565
566 case objabi.R_PLT0:
567 if ldr.SymValue(syms.GOTPLT) < ldr.SymValue(syms.PLT) {
568 ldr.Errorf(s, ".got.plt should be placed after .plt section.")
569 }
570 return 0xe28fc600 + (0xff & (int64(uint32(ldr.SymValue(rs)-(ldr.SymValue(syms.PLT)+int64(r.Off()))+r.Add())) >> 20)), noExtReloc, isOk
571 case objabi.R_PLT1:
572 return 0xe28cca00 + (0xff & (int64(uint32(ldr.SymValue(rs)-(ldr.SymValue(syms.PLT)+int64(r.Off()))+r.Add()+4)) >> 12)), noExtReloc, isOk
573 case objabi.R_PLT2:
574 return 0xe5bcf000 + (0xfff & int64(uint32(ldr.SymValue(rs)-(ldr.SymValue(syms.PLT)+int64(r.Off()))+r.Add()+8))), noExtReloc, isOk
575 case objabi.R_CALLARM:
576
577
578 t := (ldr.SymValue(rs) + int64(signext24(r.Add()&0xffffff)*4) - (ldr.SymValue(s) + int64(r.Off()))) / 4
579 if t > 0x7fffff || t < -0x800000 {
580 ldr.Errorf(s, "direct call too far: %s %x", ldr.SymName(rs), t)
581 }
582 return int64(braddoff(int32(0xff000000&uint32(r.Add())), int32(0xffffff&t))), noExtReloc, isOk
583 }
584
585 return val, 0, false
586 }
587
588 func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant, loader.Sym, int64, []byte) int64 {
589 log.Fatalf("unexpected relocation variant")
590 return -1
591 }
592
593 func extreloc(target *ld.Target, ldr *loader.Loader, r loader.Reloc, s loader.Sym) (loader.ExtReloc, bool) {
594 rs := r.Sym()
595 var rr loader.ExtReloc
596 switch r.Type() {
597 case objabi.R_CALLARM:
598
599 rs, off := ld.FoldSubSymbolOffset(ldr, rs)
600 rr.Xadd = int64(signext24(r.Add()&0xffffff))*4 + off
601 rst := ldr.SymType(rs)
602 if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && rst != sym.SUNDEFEXT && ldr.SymSect(rs) == nil {
603 ldr.Errorf(s, "missing section for %s", ldr.SymName(rs))
604 }
605 rr.Xsym = rs
606 rr.Type = r.Type()
607 rr.Size = r.Siz()
608 return rr, true
609 }
610 return rr, false
611 }
612
613 func addpltreloc(ldr *loader.Loader, plt *loader.SymbolBuilder, got *loader.SymbolBuilder, s loader.Sym, typ objabi.RelocType) {
614 r, _ := plt.AddRel(typ)
615 r.SetSym(got.Sym())
616 r.SetOff(int32(plt.Size()))
617 r.SetSiz(4)
618 r.SetAdd(int64(ldr.SymGot(s)) - 8)
619
620 plt.SetReachable(true)
621 plt.SetSize(plt.Size() + 4)
622 plt.Grow(plt.Size())
623 }
624
625 func addpltsym(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
626 if ldr.SymPlt(s) >= 0 {
627 return
628 }
629
630 ld.Adddynsym(ldr, target, syms, s)
631
632 if target.IsElf() {
633 plt := ldr.MakeSymbolUpdater(syms.PLT)
634 got := ldr.MakeSymbolUpdater(syms.GOTPLT)
635 rel := ldr.MakeSymbolUpdater(syms.RelPLT)
636 if plt.Size() == 0 {
637 panic("plt is not set up")
638 }
639
640
641 ldr.SetGot(s, int32(got.Size()))
642
643
644
645
646 got.AddAddrPlus(target.Arch, plt.Sym(), 0)
647
648
649 ldr.SetPlt(s, int32(plt.Size()))
650
651 addpltreloc(ldr, plt, got, s, objabi.R_PLT0)
652 addpltreloc(ldr, plt, got, s, objabi.R_PLT1)
653 addpltreloc(ldr, plt, got, s, objabi.R_PLT2)
654
655
656 rel.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s)))
657
658 rel.AddUint32(target.Arch, elf.R_INFO32(uint32(ldr.SymDynid(s)), uint32(elf.R_ARM_JUMP_SLOT)))
659 } else {
660 ldr.Errorf(s, "addpltsym: unsupported binary format")
661 }
662 }
663
664 func addgotsyminternal(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
665 if ldr.SymGot(s) >= 0 {
666 return
667 }
668
669 got := ldr.MakeSymbolUpdater(syms.GOT)
670 ldr.SetGot(s, int32(got.Size()))
671 got.AddAddrPlus(target.Arch, s, 0)
672
673 if target.IsElf() {
674 } else {
675 ldr.Errorf(s, "addgotsyminternal: unsupported binary format")
676 }
677 }
678
View as plain text