1
2
3
4
5
6 package loadelf
7
8 import (
9 "bytes"
10 "cmd/internal/bio"
11 "cmd/internal/objabi"
12 "cmd/internal/sys"
13 "cmd/link/internal/loader"
14 "cmd/link/internal/sym"
15 "debug/elf"
16 "encoding/binary"
17 "fmt"
18 "io"
19 "log"
20 "strings"
21 )
22
23
49
50 const (
51 SHT_ARM_ATTRIBUTES = 0x70000003
52 )
53
54 type ElfSect struct {
55 name string
56 nameoff uint32
57 type_ elf.SectionType
58 flags elf.SectionFlag
59 addr uint64
60 off uint64
61 size uint64
62 link uint32
63 info uint32
64 align uint64
65 entsize uint64
66 base []byte
67 readOnlyMem bool
68 sym loader.Sym
69 }
70
71 type ElfObj struct {
72 f *bio.Reader
73 base int64
74 length int64
75 is64 int
76 name string
77 e binary.ByteOrder
78 sect []ElfSect
79 nsect uint
80 nsymtab int
81 symtab *ElfSect
82 symstr *ElfSect
83 type_ uint32
84 machine uint32
85 version uint32
86 entry uint64
87 phoff uint64
88 shoff uint64
89 flags uint32
90 ehsize uint32
91 phentsize uint32
92 phnum uint32
93 shentsize uint32
94 shnum uint32
95 shstrndx uint32
96 }
97
98 type ElfSym struct {
99 name string
100 value uint64
101 size uint64
102 bind elf.SymBind
103 type_ elf.SymType
104 other uint8
105 shndx elf.SectionIndex
106 sym loader.Sym
107 }
108
109 const (
110 TagFile = 1
111 TagCPUName = 4
112 TagCPURawName = 5
113 TagCompatibility = 32
114 TagNoDefaults = 64
115 TagAlsoCompatibleWith = 65
116 TagABIVFPArgs = 28
117 )
118
119 type elfAttribute struct {
120 tag uint64
121 sval string
122 ival uint64
123 }
124
125 type elfAttributeList struct {
126 data []byte
127 err error
128 }
129
130 func (a *elfAttributeList) string() string {
131 if a.err != nil {
132 return ""
133 }
134 nul := bytes.IndexByte(a.data, 0)
135 if nul < 0 {
136 a.err = io.EOF
137 return ""
138 }
139 s := string(a.data[:nul])
140 a.data = a.data[nul+1:]
141 return s
142 }
143
144 func (a *elfAttributeList) uleb128() uint64 {
145 if a.err != nil {
146 return 0
147 }
148 v, size := binary.Uvarint(a.data)
149 a.data = a.data[size:]
150 return v
151 }
152
153
154 func (a *elfAttributeList) armAttr() elfAttribute {
155 attr := elfAttribute{tag: a.uleb128()}
156 switch {
157 case attr.tag == TagCompatibility:
158 attr.ival = a.uleb128()
159 attr.sval = a.string()
160
161 case attr.tag == TagNoDefaults:
162
163 case attr.tag == TagAlsoCompatibleWith:
164
165 attr.sval = a.string()
166
167
168 case attr.tag == TagCPUName || attr.tag == TagCPURawName || (attr.tag >= 32 && attr.tag&1 != 0):
169 attr.sval = a.string()
170
171 default:
172 attr.ival = a.uleb128()
173 }
174 return attr
175 }
176
177 func (a *elfAttributeList) done() bool {
178 if a.err != nil || len(a.data) == 0 {
179 return true
180 }
181 return false
182 }
183
184
185
186
187
188
189
190 func parseArmAttributes(e binary.ByteOrder, data []byte) (found bool, ehdrFlags uint32, err error) {
191 found = false
192 if data[0] != 'A' {
193 return false, 0, fmt.Errorf(".ARM.attributes has unexpected format %c\n", data[0])
194 }
195 data = data[1:]
196 for len(data) != 0 {
197 sectionlength := e.Uint32(data)
198 sectiondata := data[4:sectionlength]
199 data = data[sectionlength:]
200
201 nulIndex := bytes.IndexByte(sectiondata, 0)
202 if nulIndex < 0 {
203 return false, 0, fmt.Errorf("corrupt .ARM.attributes (section name not NUL-terminated)\n")
204 }
205 name := string(sectiondata[:nulIndex])
206 sectiondata = sectiondata[nulIndex+1:]
207
208 if name != "aeabi" {
209 continue
210 }
211 for len(sectiondata) != 0 {
212 subsectiontag, sz := binary.Uvarint(sectiondata)
213 subsectionsize := e.Uint32(sectiondata[sz:])
214 subsectiondata := sectiondata[sz+4 : subsectionsize]
215 sectiondata = sectiondata[subsectionsize:]
216
217 if subsectiontag != TagFile {
218 continue
219 }
220 attrList := elfAttributeList{data: subsectiondata}
221 for !attrList.done() {
222 attr := attrList.armAttr()
223 if attr.tag == TagABIVFPArgs && attr.ival == 1 {
224 found = true
225 ehdrFlags = 0x5000402
226 }
227 }
228 if attrList.err != nil {
229 return false, 0, fmt.Errorf("could not parse .ARM.attributes\n")
230 }
231 }
232 }
233 return found, ehdrFlags, nil
234 }
235
236
237
238
239
240
241
242
243
244 func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader, pkg string, length int64, pn string, initEhdrFlags uint32) (textp []loader.Sym, ehdrFlags uint32, err error) {
245 errorf := func(str string, args ...interface{}) ([]loader.Sym, uint32, error) {
246 return nil, 0, fmt.Errorf("loadelf: %s: %v", pn, fmt.Sprintf(str, args...))
247 }
248
249 ehdrFlags = initEhdrFlags
250
251 base := f.Offset()
252
253 var hdrbuf [64]byte
254 if _, err := io.ReadFull(f, hdrbuf[:]); err != nil {
255 return errorf("malformed elf file: %v", err)
256 }
257
258 var e binary.ByteOrder
259 switch elf.Data(hdrbuf[elf.EI_DATA]) {
260 case elf.ELFDATA2LSB:
261 e = binary.LittleEndian
262
263 case elf.ELFDATA2MSB:
264 e = binary.BigEndian
265
266 default:
267 return errorf("malformed elf file, unknown header")
268 }
269
270 hdr := new(elf.Header32)
271 binary.Read(bytes.NewReader(hdrbuf[:]), e, hdr)
272
273 if string(hdr.Ident[:elf.EI_CLASS]) != elf.ELFMAG {
274 return errorf("malformed elf file, bad header")
275 }
276
277
278 elfobj := new(ElfObj)
279
280 elfobj.e = e
281 elfobj.f = f
282 elfobj.base = base
283 elfobj.length = length
284 elfobj.name = pn
285
286 is64 := 0
287 class := elf.Class(hdrbuf[elf.EI_CLASS])
288 if class == elf.ELFCLASS64 {
289 is64 = 1
290 hdr := new(elf.Header64)
291 binary.Read(bytes.NewReader(hdrbuf[:]), e, hdr)
292 elfobj.type_ = uint32(hdr.Type)
293 elfobj.machine = uint32(hdr.Machine)
294 elfobj.version = hdr.Version
295 elfobj.entry = hdr.Entry
296 elfobj.phoff = hdr.Phoff
297 elfobj.shoff = hdr.Shoff
298 elfobj.flags = hdr.Flags
299 elfobj.ehsize = uint32(hdr.Ehsize)
300 elfobj.phentsize = uint32(hdr.Phentsize)
301 elfobj.phnum = uint32(hdr.Phnum)
302 elfobj.shentsize = uint32(hdr.Shentsize)
303 elfobj.shnum = uint32(hdr.Shnum)
304 elfobj.shstrndx = uint32(hdr.Shstrndx)
305 } else {
306 elfobj.type_ = uint32(hdr.Type)
307 elfobj.machine = uint32(hdr.Machine)
308 elfobj.version = hdr.Version
309 elfobj.entry = uint64(hdr.Entry)
310 elfobj.phoff = uint64(hdr.Phoff)
311 elfobj.shoff = uint64(hdr.Shoff)
312 elfobj.flags = hdr.Flags
313 elfobj.ehsize = uint32(hdr.Ehsize)
314 elfobj.phentsize = uint32(hdr.Phentsize)
315 elfobj.phnum = uint32(hdr.Phnum)
316 elfobj.shentsize = uint32(hdr.Shentsize)
317 elfobj.shnum = uint32(hdr.Shnum)
318 elfobj.shstrndx = uint32(hdr.Shstrndx)
319 }
320
321 elfobj.is64 = is64
322
323 if v := uint32(hdrbuf[elf.EI_VERSION]); v != elfobj.version {
324 return errorf("malformed elf version: got %d, want %d", v, elfobj.version)
325 }
326
327 if elf.Type(elfobj.type_) != elf.ET_REL {
328 return errorf("elf but not elf relocatable object")
329 }
330
331 mach := elf.Machine(elfobj.machine)
332 switch arch.Family {
333 default:
334 return errorf("elf %s unimplemented", arch.Name)
335
336 case sys.MIPS:
337 if mach != elf.EM_MIPS || class != elf.ELFCLASS32 {
338 return errorf("elf object but not mips")
339 }
340
341 case sys.MIPS64:
342 if mach != elf.EM_MIPS || class != elf.ELFCLASS64 {
343 return errorf("elf object but not mips64")
344 }
345 case sys.Loong64:
346 if mach != elf.EM_LOONGARCH || class != elf.ELFCLASS64 {
347 return errorf("elf object but not loong64")
348 }
349
350 case sys.ARM:
351 if e != binary.LittleEndian || mach != elf.EM_ARM || class != elf.ELFCLASS32 {
352 return errorf("elf object but not arm")
353 }
354
355 case sys.AMD64:
356 if e != binary.LittleEndian || mach != elf.EM_X86_64 || class != elf.ELFCLASS64 {
357 return errorf("elf object but not amd64")
358 }
359
360 case sys.ARM64:
361 if e != binary.LittleEndian || mach != elf.EM_AARCH64 || class != elf.ELFCLASS64 {
362 return errorf("elf object but not arm64")
363 }
364
365 case sys.I386:
366 if e != binary.LittleEndian || mach != elf.EM_386 || class != elf.ELFCLASS32 {
367 return errorf("elf object but not 386")
368 }
369
370 case sys.PPC64:
371 if mach != elf.EM_PPC64 || class != elf.ELFCLASS64 {
372 return errorf("elf object but not ppc64")
373 }
374
375 case sys.RISCV64:
376 if mach != elf.EM_RISCV || class != elf.ELFCLASS64 {
377 return errorf("elf object but not riscv64")
378 }
379
380 case sys.S390X:
381 if mach != elf.EM_S390 || class != elf.ELFCLASS64 {
382 return errorf("elf object but not s390x")
383 }
384 }
385
386
387 elfobj.sect = make([]ElfSect, elfobj.shnum)
388
389 elfobj.nsect = uint(elfobj.shnum)
390 for i := 0; uint(i) < elfobj.nsect; i++ {
391 f.MustSeek(int64(uint64(base)+elfobj.shoff+uint64(int64(i)*int64(elfobj.shentsize))), 0)
392 sect := &elfobj.sect[i]
393 if is64 != 0 {
394 var b elf.Section64
395 if err := binary.Read(f, e, &b); err != nil {
396 return errorf("malformed elf file: %v", err)
397 }
398
399 sect.nameoff = b.Name
400 sect.type_ = elf.SectionType(b.Type)
401 sect.flags = elf.SectionFlag(b.Flags)
402 sect.addr = b.Addr
403 sect.off = b.Off
404 sect.size = b.Size
405 sect.link = b.Link
406 sect.info = b.Info
407 sect.align = b.Addralign
408 sect.entsize = b.Entsize
409 } else {
410 var b elf.Section32
411
412 if err := binary.Read(f, e, &b); err != nil {
413 return errorf("malformed elf file: %v", err)
414 }
415 sect.nameoff = b.Name
416 sect.type_ = elf.SectionType(b.Type)
417 sect.flags = elf.SectionFlag(b.Flags)
418 sect.addr = uint64(b.Addr)
419 sect.off = uint64(b.Off)
420 sect.size = uint64(b.Size)
421 sect.link = b.Link
422 sect.info = b.Info
423 sect.align = uint64(b.Addralign)
424 sect.entsize = uint64(b.Entsize)
425 }
426 }
427
428
429 if elfobj.shstrndx >= uint32(elfobj.nsect) {
430 return errorf("malformed elf file: shstrndx out of range %d >= %d", elfobj.shstrndx, elfobj.nsect)
431 }
432
433 sect := &elfobj.sect[elfobj.shstrndx]
434 if err := elfmap(elfobj, sect); err != nil {
435 return errorf("malformed elf file: %v", err)
436 }
437 for i := 0; uint(i) < elfobj.nsect; i++ {
438 if elfobj.sect[i].nameoff != 0 {
439 elfobj.sect[i].name = cstring(sect.base[elfobj.sect[i].nameoff:])
440 }
441 }
442
443
444 elfobj.symtab = section(elfobj, ".symtab")
445
446 if elfobj.symtab == nil {
447
448 return
449 }
450
451 if elfobj.symtab.link <= 0 || elfobj.symtab.link >= uint32(elfobj.nsect) {
452 return errorf("elf object has symbol table with invalid string table link")
453 }
454
455 elfobj.symstr = &elfobj.sect[elfobj.symtab.link]
456 if is64 != 0 {
457 elfobj.nsymtab = int(elfobj.symtab.size / elf.Sym64Size)
458 } else {
459 elfobj.nsymtab = int(elfobj.symtab.size / elf.Sym32Size)
460 }
461
462 if err := elfmap(elfobj, elfobj.symtab); err != nil {
463 return errorf("malformed elf file: %v", err)
464 }
465 if err := elfmap(elfobj, elfobj.symstr); err != nil {
466 return errorf("malformed elf file: %v", err)
467 }
468
469
470
471
472
473
474
475 sectsymNames := make(map[string]bool)
476 counter := 0
477 for i := 0; uint(i) < elfobj.nsect; i++ {
478 sect = &elfobj.sect[i]
479 if sect.type_ == SHT_ARM_ATTRIBUTES && sect.name == ".ARM.attributes" {
480 if err := elfmap(elfobj, sect); err != nil {
481 return errorf("%s: malformed elf file: %v", pn, err)
482 }
483
484 if initEhdrFlags == 0x5000002 {
485 ehdrFlags = 0x5000202
486 } else {
487 ehdrFlags = initEhdrFlags
488 }
489 found, newEhdrFlags, err := parseArmAttributes(e, sect.base[:sect.size])
490 if err != nil {
491
492 log.Printf("%s: %v", pn, err)
493 }
494 if found {
495 ehdrFlags = newEhdrFlags
496 }
497 }
498 if (sect.type_ != elf.SHT_PROGBITS && sect.type_ != elf.SHT_NOBITS) || sect.flags&elf.SHF_ALLOC == 0 {
499 continue
500 }
501 if sect.type_ != elf.SHT_NOBITS {
502 if err := elfmap(elfobj, sect); err != nil {
503 return errorf("%s: malformed elf file: %v", pn, err)
504 }
505 }
506
507 name := fmt.Sprintf("%s(%s)", pkg, sect.name)
508 for sectsymNames[name] {
509 counter++
510 name = fmt.Sprintf("%s(%s%d)", pkg, sect.name, counter)
511 }
512 sectsymNames[name] = true
513
514 sb := l.MakeSymbolUpdater(l.LookupOrCreateCgoExport(name, localSymVersion))
515
516 switch sect.flags & (elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_EXECINSTR) {
517 default:
518 return errorf("%s: unexpected flags for ELF section %s", pn, sect.name)
519
520 case elf.SHF_ALLOC:
521 sb.SetType(sym.SRODATA)
522
523 case elf.SHF_ALLOC + elf.SHF_WRITE:
524 if sect.type_ == elf.SHT_NOBITS {
525 sb.SetType(sym.SNOPTRBSS)
526 } else {
527 sb.SetType(sym.SNOPTRDATA)
528 }
529
530 case elf.SHF_ALLOC + elf.SHF_EXECINSTR:
531 sb.SetType(sym.STEXT)
532 }
533
534 if sect.name == ".got" || sect.name == ".toc" {
535 sb.SetType(sym.SELFGOT)
536 }
537 if sect.type_ == elf.SHT_PROGBITS {
538 sb.SetData(sect.base[:sect.size])
539 sb.SetExternal(true)
540 }
541
542 sb.SetSize(int64(sect.size))
543 sb.SetAlign(int32(sect.align))
544 sb.SetReadOnly(sect.readOnlyMem)
545
546 sect.sym = sb.Sym()
547 }
548
549
550
551 symbols := make([]loader.Sym, elfobj.nsymtab)
552
553 for i := 1; i < elfobj.nsymtab; i++ {
554 var elfsym ElfSym
555 if err := readelfsym(l, arch, elfobj, i, &elfsym, 1, localSymVersion); err != nil {
556 return errorf("%s: malformed elf file: %v", pn, err)
557 }
558 symbols[i] = elfsym.sym
559 if elfsym.type_ != elf.STT_FUNC && elfsym.type_ != elf.STT_OBJECT && elfsym.type_ != elf.STT_NOTYPE && elfsym.type_ != elf.STT_COMMON {
560 continue
561 }
562 if elfsym.shndx == elf.SHN_COMMON || elfsym.type_ == elf.STT_COMMON {
563 sb := l.MakeSymbolUpdater(elfsym.sym)
564 if uint64(sb.Size()) < elfsym.size {
565 sb.SetSize(int64(elfsym.size))
566 }
567 if sb.Type() == 0 || sb.Type() == sym.SXREF {
568 sb.SetType(sym.SNOPTRBSS)
569 }
570 continue
571 }
572
573 if uint(elfsym.shndx) >= elfobj.nsect || elfsym.shndx == 0 {
574 continue
575 }
576
577
578 if elfsym.sym == 0 {
579 continue
580 }
581 sect = &elfobj.sect[elfsym.shndx]
582 if sect.sym == 0 {
583 if elfsym.type_ == 0 {
584 if strings.HasPrefix(sect.name, ".debug_") && elfsym.name == "" {
585
586
587
588 continue
589 }
590 if strings.HasPrefix(elfsym.name, ".Ldebug_") || elfsym.name == ".L0 " {
591
592 continue
593 }
594 if elfsym.name == ".Lline_table_start0" {
595
596 continue
597 }
598
599 if strings.HasPrefix(elfsym.name, "$d") && sect.name == ".debug_frame" {
600
601
602
603 continue
604 }
605 }
606
607 if strings.HasPrefix(elfsym.name, ".Linfo_string") {
608
609 continue
610 }
611
612 if strings.HasPrefix(elfsym.name, ".LASF") || strings.HasPrefix(elfsym.name, ".LLRL") || strings.HasPrefix(elfsym.name, ".LLST") {
613
614 continue
615 }
616
617 return errorf("%v: sym#%d (%q): ignoring symbol in section %d (%q) (type %d)", elfsym.sym, i, elfsym.name, elfsym.shndx, sect.name, elfsym.type_)
618 }
619
620 s := elfsym.sym
621 if l.OuterSym(s) != 0 {
622 if l.AttrDuplicateOK(s) {
623 continue
624 }
625 return errorf("duplicate symbol reference: %s in both %s and %s",
626 l.SymName(s), l.SymName(l.OuterSym(s)), l.SymName(sect.sym))
627 }
628
629 sectsb := l.MakeSymbolUpdater(sect.sym)
630 sb := l.MakeSymbolUpdater(s)
631
632 sb.SetType(sectsb.Type())
633 sectsb.AddInteriorSym(s)
634 if !l.AttrCgoExportDynamic(s) {
635 sb.SetDynimplib("")
636 }
637 sb.SetValue(int64(elfsym.value))
638 sb.SetSize(int64(elfsym.size))
639 if sectsb.Type().IsText() {
640 if l.AttrExternal(s) && !l.AttrDuplicateOK(s) {
641 return errorf("%s: duplicate symbol definition", sb.Name())
642 }
643 l.SetAttrExternal(s, true)
644 }
645
646 if elf.Machine(elfobj.machine) == elf.EM_PPC64 {
647 flag := int(elfsym.other) >> 5
648 switch flag {
649 case 0:
650
651 case 1:
652
653
654
655
656 l.SetSymLocalentry(s, 1)
657 case 7:
658 return errorf("%s: invalid sym.other 0x%x", sb.Name(), elfsym.other)
659 default:
660
661 l.SetSymLocalentry(s, 4<<uint(flag-2))
662 }
663 }
664 }
665
666
667
668 for i := uint(0); i < elfobj.nsect; i++ {
669 s := elfobj.sect[i].sym
670 if s == 0 {
671 continue
672 }
673 sb := l.MakeSymbolUpdater(s)
674 if l.SubSym(s) != 0 {
675 sb.SortSub()
676 }
677 if sb.Type().IsText() {
678 if l.AttrOnList(s) {
679 return errorf("symbol %s listed multiple times",
680 l.SymName(s))
681 }
682 l.SetAttrOnList(s, true)
683 textp = append(textp, s)
684 for ss := l.SubSym(s); ss != 0; ss = l.SubSym(ss) {
685 if l.AttrOnList(ss) {
686 return errorf("symbol %s listed multiple times",
687 l.SymName(ss))
688 }
689 l.SetAttrOnList(ss, true)
690 textp = append(textp, ss)
691 }
692 }
693 }
694
695
696 for i := uint(0); i < elfobj.nsect; i++ {
697 rsect := &elfobj.sect[i]
698 if rsect.type_ != elf.SHT_RELA && rsect.type_ != elf.SHT_REL {
699 continue
700 }
701 if rsect.info >= uint32(elfobj.nsect) || elfobj.sect[rsect.info].base == nil {
702 continue
703 }
704 sect = &elfobj.sect[rsect.info]
705 if err := elfmap(elfobj, rsect); err != nil {
706 return errorf("malformed elf file: %v", err)
707 }
708 rela := 0
709 if rsect.type_ == elf.SHT_RELA {
710 rela = 1
711 }
712 n := int(rsect.size / uint64(4+4*is64) / uint64(2+rela))
713 p := rsect.base
714 sb := l.MakeSymbolUpdater(sect.sym)
715 for j := 0; j < n; j++ {
716 var add uint64
717 var symIdx int
718 var relocType uint64
719 var rOff int32
720 var rAdd int64
721 var rSym loader.Sym
722
723 if is64 != 0 {
724
725 rOff = int32(e.Uint64(p))
726
727 p = p[8:]
728 switch arch.Family {
729 case sys.MIPS64:
730
731
732 symIdx = int(e.Uint32(p))
733 relocType = uint64(p[7])
734 default:
735 info := e.Uint64(p)
736 relocType = info & 0xffffffff
737 symIdx = int(info >> 32)
738 }
739 p = p[8:]
740 if rela != 0 {
741 add = e.Uint64(p)
742 p = p[8:]
743 }
744 } else {
745
746 rOff = int32(e.Uint32(p))
747
748 p = p[4:]
749 info := e.Uint32(p)
750 relocType = uint64(info & 0xff)
751 symIdx = int(info >> 8)
752 p = p[4:]
753 if rela != 0 {
754 add = uint64(e.Uint32(p))
755 p = p[4:]
756 }
757 }
758
759 if relocType == 0 {
760 j--
761 n--
762 continue
763 }
764
765 if symIdx == 0 {
766 rSym = 0
767 } else {
768 var elfsym ElfSym
769 if err := readelfsym(l, arch, elfobj, int(symIdx), &elfsym, 0, 0); err != nil {
770 return errorf("malformed elf file: %v", err)
771 }
772 elfsym.sym = symbols[symIdx]
773 if elfsym.sym == 0 {
774 return errorf("malformed elf file: %s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", l.SymName(sect.sym), j, int(symIdx), elfsym.name, elfsym.shndx, elfsym.type_)
775 }
776
777 rSym = elfsym.sym
778 }
779
780 rType := objabi.ElfRelocOffset + objabi.RelocType(relocType)
781 rSize, addendSize, err := relSize(arch, pn, uint32(relocType))
782 if err != nil {
783 return nil, 0, err
784 }
785 if rela != 0 {
786 rAdd = int64(add)
787 } else {
788
789 if rSize == 4 {
790 rAdd = int64(e.Uint32(sect.base[rOff:]))
791 } else if rSize == 8 {
792 rAdd = int64(e.Uint64(sect.base[rOff:]))
793 } else {
794 return errorf("invalid rela size %d", rSize)
795 }
796 }
797
798 if addendSize == 2 {
799 rAdd = int64(int16(rAdd))
800 }
801 if addendSize == 4 {
802 rAdd = int64(int32(rAdd))
803 }
804
805 r, _ := sb.AddRel(rType)
806 r.SetOff(rOff)
807 r.SetSiz(rSize)
808 r.SetSym(rSym)
809 r.SetAdd(rAdd)
810 }
811
812 sb.SortRelocs()
813 }
814
815 return textp, ehdrFlags, nil
816 }
817
818 func section(elfobj *ElfObj, name string) *ElfSect {
819 for i := 0; uint(i) < elfobj.nsect; i++ {
820 if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name {
821 return &elfobj.sect[i]
822 }
823 }
824 return nil
825 }
826
827 func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) {
828 if sect.base != nil {
829 return nil
830 }
831
832 if sect.off+sect.size > uint64(elfobj.length) {
833 err = fmt.Errorf("elf section past end of file")
834 return err
835 }
836
837 elfobj.f.MustSeek(int64(uint64(elfobj.base)+sect.off), 0)
838 sect.base, sect.readOnlyMem, err = elfobj.f.Slice(uint64(sect.size))
839 if err != nil {
840 return fmt.Errorf("short read: %v", err)
841 }
842
843 return nil
844 }
845
846 func readelfsym(l *loader.Loader, arch *sys.Arch, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, localSymVersion int) (err error) {
847 if i >= elfobj.nsymtab || i < 0 {
848 err = fmt.Errorf("invalid elf symbol index")
849 return err
850 }
851
852 if i == 0 {
853 return fmt.Errorf("readym: read null symbol!")
854 }
855
856 if elfobj.is64 != 0 {
857 b := new(elf.Sym64)
858 binary.Read(bytes.NewReader(elfobj.symtab.base[i*elf.Sym64Size:(i+1)*elf.Sym64Size]), elfobj.e, b)
859 elfsym.name = cstring(elfobj.symstr.base[b.Name:])
860 elfsym.value = b.Value
861 elfsym.size = b.Size
862 elfsym.shndx = elf.SectionIndex(b.Shndx)
863 elfsym.bind = elf.ST_BIND(b.Info)
864 elfsym.type_ = elf.ST_TYPE(b.Info)
865 elfsym.other = b.Other
866 } else {
867 b := new(elf.Sym32)
868 binary.Read(bytes.NewReader(elfobj.symtab.base[i*elf.Sym32Size:(i+1)*elf.Sym32Size]), elfobj.e, b)
869 elfsym.name = cstring(elfobj.symstr.base[b.Name:])
870 elfsym.value = uint64(b.Value)
871 elfsym.size = uint64(b.Size)
872 elfsym.shndx = elf.SectionIndex(b.Shndx)
873 elfsym.bind = elf.ST_BIND(b.Info)
874 elfsym.type_ = elf.ST_TYPE(b.Info)
875 elfsym.other = b.Other
876 }
877
878 var s loader.Sym
879
880 if elfsym.name == "_GLOBAL_OFFSET_TABLE_" {
881 elfsym.name = ".got"
882 }
883 if elfsym.name == ".TOC." {
884
885
886 elfsym.bind = elf.STB_LOCAL
887 }
888
889 switch elfsym.type_ {
890 case elf.STT_SECTION:
891 s = elfobj.sect[elfsym.shndx].sym
892
893 case elf.STT_OBJECT, elf.STT_FUNC, elf.STT_NOTYPE, elf.STT_COMMON:
894 switch elfsym.bind {
895 case elf.STB_GLOBAL:
896 if needSym != 0 {
897 s = l.LookupOrCreateCgoExport(elfsym.name, 0)
898
899
900
901
902
903
904
905
906 if s != 0 && elfsym.other == 2 {
907 if !l.IsExternal(s) {
908 l.MakeSymbolUpdater(s)
909 }
910 l.SetAttrDuplicateOK(s, true)
911 l.SetAttrVisibilityHidden(s, true)
912 }
913 }
914
915 case elf.STB_LOCAL:
916 if (arch.Family == sys.ARM || arch.Family == sys.ARM64) && (strings.HasPrefix(elfsym.name, "$a") || strings.HasPrefix(elfsym.name, "$d") || strings.HasPrefix(elfsym.name, "$x")) {
917
918
919 break
920 }
921
922 if elfsym.name == ".TOC." {
923
924
925 if needSym != 0 {
926 s = l.LookupOrCreateCgoExport(elfsym.name, localSymVersion)
927 l.SetAttrVisibilityHidden(s, true)
928 }
929 break
930 }
931
932 if needSym != 0 {
933
934
935
936
937
938
939 s = l.CreateStaticSym(elfsym.name)
940 l.SetAttrVisibilityHidden(s, true)
941 }
942
943 case elf.STB_WEAK:
944 if needSym != 0 {
945 s = l.LookupOrCreateCgoExport(elfsym.name, 0)
946 if elfsym.other == 2 {
947 l.SetAttrVisibilityHidden(s, true)
948 }
949
950
951 if l.OuterSym(s) != 0 {
952 l.SetAttrDuplicateOK(s, true)
953 }
954 }
955
956 default:
957 err = fmt.Errorf("%s: invalid symbol binding %d", elfsym.name, elfsym.bind)
958 return err
959 }
960 }
961
962 if s != 0 && l.SymType(s) == 0 && elfsym.type_ != elf.STT_SECTION {
963 sb := l.MakeSymbolUpdater(s)
964 sb.SetType(sym.SXREF)
965 }
966 elfsym.sym = s
967
968 return nil
969 }
970
971
972
973
974 func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, uint8, error) {
975
976
977
978
979 const (
980 AMD64 = uint32(sys.AMD64)
981 ARM = uint32(sys.ARM)
982 ARM64 = uint32(sys.ARM64)
983 I386 = uint32(sys.I386)
984 LOONG64 = uint32(sys.Loong64)
985 MIPS = uint32(sys.MIPS)
986 MIPS64 = uint32(sys.MIPS64)
987 PPC64 = uint32(sys.PPC64)
988 RISCV64 = uint32(sys.RISCV64)
989 S390X = uint32(sys.S390X)
990 )
991
992 switch uint32(arch.Family) | elftype<<16 {
993 default:
994 return 0, 0, fmt.Errorf("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
995
996 case MIPS | uint32(elf.R_MIPS_HI16)<<16,
997 MIPS | uint32(elf.R_MIPS_LO16)<<16,
998 MIPS | uint32(elf.R_MIPS_GOT16)<<16,
999 MIPS | uint32(elf.R_MIPS_GOT_HI16)<<16,
1000 MIPS | uint32(elf.R_MIPS_GOT_LO16)<<16,
1001 MIPS | uint32(elf.R_MIPS_GPREL16)<<16,
1002 MIPS | uint32(elf.R_MIPS_GOT_PAGE)<<16,
1003 MIPS | uint32(elf.R_MIPS_JALR)<<16,
1004 MIPS | uint32(elf.R_MIPS_GOT_OFST)<<16,
1005 MIPS64 | uint32(elf.R_MIPS_HI16)<<16,
1006 MIPS64 | uint32(elf.R_MIPS_LO16)<<16,
1007 MIPS64 | uint32(elf.R_MIPS_GOT16)<<16,
1008 MIPS64 | uint32(elf.R_MIPS_GOT_HI16)<<16,
1009 MIPS64 | uint32(elf.R_MIPS_GOT_LO16)<<16,
1010 MIPS64 | uint32(elf.R_MIPS_GPREL16)<<16,
1011 MIPS64 | uint32(elf.R_MIPS_GOT_PAGE)<<16,
1012 MIPS64 | uint32(elf.R_MIPS_JALR)<<16,
1013 MIPS64 | uint32(elf.R_MIPS_GOT_OFST)<<16,
1014 MIPS64 | uint32(elf.R_MIPS_CALL16)<<16,
1015 MIPS64 | uint32(elf.R_MIPS_GPREL32)<<16,
1016 MIPS64 | uint32(elf.R_MIPS_64)<<16,
1017 MIPS64 | uint32(elf.R_MIPS_GOT_DISP)<<16,
1018 MIPS64 | uint32(elf.R_MIPS_PC32)<<16:
1019 return 4, 4, nil
1020
1021 case LOONG64 | uint32(elf.R_LARCH_ADD8)<<16,
1022 LOONG64 | uint32(elf.R_LARCH_SUB8)<<16:
1023 return 1, 1, nil
1024
1025 case LOONG64 | uint32(elf.R_LARCH_ADD16)<<16,
1026 LOONG64 | uint32(elf.R_LARCH_SUB16)<<16:
1027 return 2, 2, nil
1028
1029 case LOONG64 | uint32(elf.R_LARCH_MARK_LA)<<16,
1030 LOONG64 | uint32(elf.R_LARCH_MARK_PCREL)<<16,
1031 LOONG64 | uint32(elf.R_LARCH_ADD24)<<16,
1032 LOONG64 | uint32(elf.R_LARCH_ADD32)<<16,
1033 LOONG64 | uint32(elf.R_LARCH_SUB24)<<16,
1034 LOONG64 | uint32(elf.R_LARCH_SUB32)<<16,
1035 LOONG64 | uint32(elf.R_LARCH_B26)<<16,
1036 LOONG64 | uint32(elf.R_LARCH_32_PCREL)<<16:
1037 return 4, 4, nil
1038
1039 case LOONG64 | uint32(elf.R_LARCH_64)<<16,
1040 LOONG64 | uint32(elf.R_LARCH_ADD64)<<16,
1041 LOONG64 | uint32(elf.R_LARCH_SUB64)<<16,
1042 LOONG64 | uint32(elf.R_LARCH_64_PCREL)<<16:
1043 return 8, 8, nil
1044
1045 case S390X | uint32(elf.R_390_8)<<16:
1046 return 1, 1, nil
1047
1048 case PPC64 | uint32(elf.R_PPC64_TOC16)<<16,
1049 S390X | uint32(elf.R_390_16)<<16,
1050 S390X | uint32(elf.R_390_GOT16)<<16,
1051 S390X | uint32(elf.R_390_PC16)<<16,
1052 S390X | uint32(elf.R_390_PC16DBL)<<16,
1053 S390X | uint32(elf.R_390_PLT16DBL)<<16:
1054 return 2, 2, nil
1055
1056 case ARM | uint32(elf.R_ARM_ABS32)<<16,
1057 ARM | uint32(elf.R_ARM_GOT32)<<16,
1058 ARM | uint32(elf.R_ARM_PLT32)<<16,
1059 ARM | uint32(elf.R_ARM_GOTOFF)<<16,
1060 ARM | uint32(elf.R_ARM_GOTPC)<<16,
1061 ARM | uint32(elf.R_ARM_THM_PC22)<<16,
1062 ARM | uint32(elf.R_ARM_REL32)<<16,
1063 ARM | uint32(elf.R_ARM_CALL)<<16,
1064 ARM | uint32(elf.R_ARM_V4BX)<<16,
1065 ARM | uint32(elf.R_ARM_GOT_PREL)<<16,
1066 ARM | uint32(elf.R_ARM_PC24)<<16,
1067 ARM | uint32(elf.R_ARM_JUMP24)<<16,
1068 ARM64 | uint32(elf.R_AARCH64_CALL26)<<16,
1069 ARM64 | uint32(elf.R_AARCH64_ADR_GOT_PAGE)<<16,
1070 ARM64 | uint32(elf.R_AARCH64_LD64_GOT_LO12_NC)<<16,
1071 ARM64 | uint32(elf.R_AARCH64_ADR_PREL_PG_HI21)<<16,
1072 ARM64 | uint32(elf.R_AARCH64_ADD_ABS_LO12_NC)<<16,
1073 ARM64 | uint32(elf.R_AARCH64_LDST8_ABS_LO12_NC)<<16,
1074 ARM64 | uint32(elf.R_AARCH64_LDST16_ABS_LO12_NC)<<16,
1075 ARM64 | uint32(elf.R_AARCH64_LDST32_ABS_LO12_NC)<<16,
1076 ARM64 | uint32(elf.R_AARCH64_LDST64_ABS_LO12_NC)<<16,
1077 ARM64 | uint32(elf.R_AARCH64_LDST128_ABS_LO12_NC)<<16,
1078 ARM64 | uint32(elf.R_AARCH64_PREL32)<<16,
1079 ARM64 | uint32(elf.R_AARCH64_JUMP26)<<16,
1080 AMD64 | uint32(elf.R_X86_64_PC32)<<16,
1081 AMD64 | uint32(elf.R_X86_64_PLT32)<<16,
1082 AMD64 | uint32(elf.R_X86_64_GOTPCREL)<<16,
1083 AMD64 | uint32(elf.R_X86_64_GOTPCRELX)<<16,
1084 AMD64 | uint32(elf.R_X86_64_REX_GOTPCRELX)<<16,
1085 I386 | uint32(elf.R_386_32)<<16,
1086 I386 | uint32(elf.R_386_PC32)<<16,
1087 I386 | uint32(elf.R_386_GOT32)<<16,
1088 I386 | uint32(elf.R_386_PLT32)<<16,
1089 I386 | uint32(elf.R_386_GOTOFF)<<16,
1090 I386 | uint32(elf.R_386_GOTPC)<<16,
1091 I386 | uint32(elf.R_386_GOT32X)<<16,
1092 PPC64 | uint32(elf.R_PPC64_REL24)<<16,
1093 PPC64 | uint32(elf.R_PPC64_REL24_NOTOC)<<16,
1094 PPC64 | uint32(elf.R_PPC64_REL24_P9NOTOC)<<16,
1095 PPC64 | uint32(elf.R_PPC_REL32)<<16,
1096 S390X | uint32(elf.R_390_32)<<16,
1097 S390X | uint32(elf.R_390_PC32)<<16,
1098 S390X | uint32(elf.R_390_GOT32)<<16,
1099 S390X | uint32(elf.R_390_PLT32)<<16,
1100 S390X | uint32(elf.R_390_PC32DBL)<<16,
1101 S390X | uint32(elf.R_390_PLT32DBL)<<16,
1102 S390X | uint32(elf.R_390_GOTPCDBL)<<16,
1103 S390X | uint32(elf.R_390_GOTENT)<<16:
1104 return 4, 4, nil
1105
1106 case AMD64 | uint32(elf.R_X86_64_64)<<16,
1107 AMD64 | uint32(elf.R_X86_64_PC64)<<16,
1108 ARM64 | uint32(elf.R_AARCH64_ABS64)<<16,
1109 ARM64 | uint32(elf.R_AARCH64_PREL64)<<16,
1110 PPC64 | uint32(elf.R_PPC64_ADDR64)<<16,
1111 PPC64 | uint32(elf.R_PPC64_PCREL34)<<16,
1112 PPC64 | uint32(elf.R_PPC64_GOT_PCREL34)<<16,
1113 PPC64 | uint32(elf.R_PPC64_PLT_PCREL34_NOTOC)<<16,
1114 S390X | uint32(elf.R_390_GLOB_DAT)<<16,
1115 S390X | uint32(elf.R_390_RELATIVE)<<16,
1116 S390X | uint32(elf.R_390_GOTOFF)<<16,
1117 S390X | uint32(elf.R_390_GOTPC)<<16,
1118 S390X | uint32(elf.R_390_64)<<16,
1119 S390X | uint32(elf.R_390_PC64)<<16,
1120 S390X | uint32(elf.R_390_GOT64)<<16,
1121 S390X | uint32(elf.R_390_PLT64)<<16:
1122 return 8, 8, nil
1123
1124 case RISCV64 | uint32(elf.R_RISCV_SET6)<<16,
1125 RISCV64 | uint32(elf.R_RISCV_SUB6)<<16,
1126 RISCV64 | uint32(elf.R_RISCV_SET8)<<16,
1127 RISCV64 | uint32(elf.R_RISCV_SUB8)<<16:
1128 return 1, 1, nil
1129
1130 case RISCV64 | uint32(elf.R_RISCV_RVC_BRANCH)<<16,
1131 RISCV64 | uint32(elf.R_RISCV_RVC_JUMP)<<16,
1132 RISCV64 | uint32(elf.R_RISCV_SET16)<<16,
1133 RISCV64 | uint32(elf.R_RISCV_SUB16)<<16:
1134 return 2, 2, nil
1135
1136 case RISCV64 | uint32(elf.R_RISCV_32)<<16,
1137 RISCV64 | uint32(elf.R_RISCV_BRANCH)<<16,
1138 RISCV64 | uint32(elf.R_RISCV_HI20)<<16,
1139 RISCV64 | uint32(elf.R_RISCV_LO12_I)<<16,
1140 RISCV64 | uint32(elf.R_RISCV_LO12_S)<<16,
1141 RISCV64 | uint32(elf.R_RISCV_GOT_HI20)<<16,
1142 RISCV64 | uint32(elf.R_RISCV_PCREL_HI20)<<16,
1143 RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_I)<<16,
1144 RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_S)<<16,
1145 RISCV64 | uint32(elf.R_RISCV_ADD32)<<16,
1146 RISCV64 | uint32(elf.R_RISCV_SET32)<<16,
1147 RISCV64 | uint32(elf.R_RISCV_SUB32)<<16,
1148 RISCV64 | uint32(elf.R_RISCV_32_PCREL)<<16,
1149 RISCV64 | uint32(elf.R_RISCV_RELAX)<<16:
1150 return 4, 4, nil
1151
1152 case RISCV64 | uint32(elf.R_RISCV_64)<<16,
1153 RISCV64 | uint32(elf.R_RISCV_CALL)<<16,
1154 RISCV64 | uint32(elf.R_RISCV_CALL_PLT)<<16:
1155 return 8, 8, nil
1156
1157 case PPC64 | uint32(elf.R_PPC64_TOC16_LO)<<16,
1158 PPC64 | uint32(elf.R_PPC64_TOC16_HI)<<16,
1159 PPC64 | uint32(elf.R_PPC64_TOC16_HA)<<16,
1160 PPC64 | uint32(elf.R_PPC64_TOC16_DS)<<16,
1161 PPC64 | uint32(elf.R_PPC64_TOC16_LO_DS)<<16,
1162 PPC64 | uint32(elf.R_PPC64_REL16_LO)<<16,
1163 PPC64 | uint32(elf.R_PPC64_REL16_HI)<<16,
1164 PPC64 | uint32(elf.R_PPC64_REL16_HA)<<16,
1165 PPC64 | uint32(elf.R_PPC64_PLT16_HA)<<16,
1166 PPC64 | uint32(elf.R_PPC64_PLT16_LO_DS)<<16:
1167 return 2, 4, nil
1168
1169
1170
1171 case PPC64 | uint32(elf.R_PPC64_PLTSEQ)<<16,
1172 PPC64 | uint32(elf.R_PPC64_PLTCALL)<<16,
1173 PPC64 | uint32(elf.R_PPC64_PLTCALL_NOTOC)<<16,
1174 PPC64 | uint32(elf.R_PPC64_PLTSEQ_NOTOC)<<16:
1175 return 0, 0, nil
1176
1177 }
1178 }
1179
1180 func cstring(x []byte) string {
1181 i := bytes.IndexByte(x, '\x00')
1182 if i >= 0 {
1183 x = x[:i]
1184 }
1185 return string(x)
1186 }
1187
View as plain text