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 if arch.Family == sys.RISCV64 &&
607 (strings.HasPrefix(elfsym.name, "$d") || strings.HasPrefix(elfsym.name, "$x")) {
608
609
610
611 continue
612 }
613
614 if arch.Family == sys.Loong64 && (strings.HasPrefix(elfsym.name, ".L") || elfsym.name == "L0\001") {
615
616 continue
617 }
618 }
619
620 if strings.HasPrefix(elfsym.name, ".Linfo_string") {
621
622 continue
623 }
624
625 if strings.HasPrefix(elfsym.name, ".LASF") || strings.HasPrefix(elfsym.name, ".LLRL") || strings.HasPrefix(elfsym.name, ".LLST") || strings.HasPrefix(elfsym.name, ".LVUS") {
626
627 continue
628 }
629
630 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_)
631 }
632
633 s := elfsym.sym
634 if l.OuterSym(s) != 0 {
635 if l.AttrDuplicateOK(s) {
636 continue
637 }
638 return errorf("duplicate symbol reference: %s in both %s and %s",
639 l.SymName(s), l.SymName(l.OuterSym(s)), l.SymName(sect.sym))
640 }
641
642 sectsb := l.MakeSymbolUpdater(sect.sym)
643 sb := l.MakeSymbolUpdater(s)
644
645 sb.SetType(sectsb.Type())
646 sectsb.AddInteriorSym(s)
647 if !l.AttrCgoExportDynamic(s) {
648 sb.SetDynimplib("")
649 }
650 sb.SetValue(int64(elfsym.value))
651 sb.SetSize(int64(elfsym.size))
652 if sectsb.Type().IsText() {
653 if l.AttrExternal(s) && !l.AttrDuplicateOK(s) {
654 return errorf("%s: duplicate symbol definition", sb.Name())
655 }
656 l.SetAttrExternal(s, true)
657 }
658
659 if elf.Machine(elfobj.machine) == elf.EM_PPC64 {
660 flag := int(elfsym.other) >> 5
661 switch flag {
662 case 0:
663
664 case 1:
665
666
667
668
669 l.SetSymLocalentry(s, 1)
670 case 7:
671 return errorf("%s: invalid sym.other 0x%x", sb.Name(), elfsym.other)
672 default:
673
674 l.SetSymLocalentry(s, 4<<uint(flag-2))
675 }
676 }
677 }
678
679
680
681 for i := uint(0); i < elfobj.nsect; i++ {
682 s := elfobj.sect[i].sym
683 if s == 0 {
684 continue
685 }
686 sb := l.MakeSymbolUpdater(s)
687 if l.SubSym(s) != 0 {
688 sb.SortSub()
689 }
690 if sb.Type().IsText() {
691 if l.AttrOnList(s) {
692 return errorf("symbol %s listed multiple times",
693 l.SymName(s))
694 }
695 l.SetAttrOnList(s, true)
696 textp = append(textp, s)
697 for ss := l.SubSym(s); ss != 0; ss = l.SubSym(ss) {
698 if arch.Family == sys.Loong64 && (strings.HasPrefix(l.SymName(ss), ".L") || l.SymName(ss) == "L0\001") {
699
700
701
702 continue
703 }
704 if l.AttrOnList(ss) {
705 return errorf("symbol %s listed multiple times",
706 l.SymName(ss))
707 }
708 l.SetAttrOnList(ss, true)
709 textp = append(textp, ss)
710 }
711 }
712 }
713
714
715 for i := uint(0); i < elfobj.nsect; i++ {
716 rsect := &elfobj.sect[i]
717 if rsect.type_ != elf.SHT_RELA && rsect.type_ != elf.SHT_REL {
718 continue
719 }
720 if rsect.info >= uint32(elfobj.nsect) || elfobj.sect[rsect.info].base == nil {
721 continue
722 }
723 sect = &elfobj.sect[rsect.info]
724 if err := elfmap(elfobj, rsect); err != nil {
725 return errorf("malformed elf file: %v", err)
726 }
727 rela := 0
728 if rsect.type_ == elf.SHT_RELA {
729 rela = 1
730 }
731 n := int(rsect.size / uint64(4+4*is64) / uint64(2+rela))
732 p := rsect.base
733 sb := l.MakeSymbolUpdater(sect.sym)
734 for j := 0; j < n; j++ {
735 var add uint64
736 var symIdx int
737 var relocType uint64
738 var rOff int32
739 var rAdd int64
740 var rSym loader.Sym
741
742 if is64 != 0 {
743
744 rOff = int32(e.Uint64(p))
745
746 p = p[8:]
747 switch arch.Family {
748 case sys.MIPS64:
749
750
751 symIdx = int(e.Uint32(p))
752 relocType = uint64(p[7])
753 default:
754 info := e.Uint64(p)
755 relocType = info & 0xffffffff
756 symIdx = int(info >> 32)
757 }
758 p = p[8:]
759 if rela != 0 {
760 add = e.Uint64(p)
761 p = p[8:]
762 }
763 } else {
764
765 rOff = int32(e.Uint32(p))
766
767 p = p[4:]
768 info := e.Uint32(p)
769 relocType = uint64(info & 0xff)
770 symIdx = int(info >> 8)
771 p = p[4:]
772 if rela != 0 {
773 add = uint64(e.Uint32(p))
774 p = p[4:]
775 }
776 }
777
778 if relocType == 0 {
779 j--
780 n--
781 continue
782 }
783
784 if symIdx == 0 {
785 rSym = 0
786 } else {
787 var elfsym ElfSym
788 if err := readelfsym(l, arch, elfobj, int(symIdx), &elfsym, 0, 0); err != nil {
789 return errorf("malformed elf file: %v", err)
790 }
791 elfsym.sym = symbols[symIdx]
792 if elfsym.sym == 0 {
793 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_)
794 }
795
796 rSym = elfsym.sym
797 }
798
799 rType := objabi.ElfRelocOffset + objabi.RelocType(relocType)
800 rSize, addendSize, err := relSize(arch, pn, uint32(relocType))
801 if err != nil {
802 return nil, 0, err
803 }
804 if rela != 0 {
805 rAdd = int64(add)
806 } else {
807
808 if rSize == 4 {
809 rAdd = int64(e.Uint32(sect.base[rOff:]))
810 } else if rSize == 8 {
811 rAdd = int64(e.Uint64(sect.base[rOff:]))
812 } else {
813 return errorf("invalid rela size %d", rSize)
814 }
815 }
816
817 if addendSize == 2 {
818 rAdd = int64(int16(rAdd))
819 }
820 if addendSize == 4 {
821 rAdd = int64(int32(rAdd))
822 }
823
824 r, _ := sb.AddRel(rType)
825 r.SetOff(rOff)
826 r.SetSiz(rSize)
827 r.SetSym(rSym)
828 r.SetAdd(rAdd)
829 }
830
831 sb.SortRelocs()
832 }
833
834 return textp, ehdrFlags, nil
835 }
836
837 func section(elfobj *ElfObj, name string) *ElfSect {
838 for i := 0; uint(i) < elfobj.nsect; i++ {
839 if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name {
840 return &elfobj.sect[i]
841 }
842 }
843 return nil
844 }
845
846 func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) {
847 if sect.base != nil {
848 return nil
849 }
850
851 if sect.off+sect.size > uint64(elfobj.length) {
852 err = fmt.Errorf("elf section past end of file")
853 return err
854 }
855
856 elfobj.f.MustSeek(int64(uint64(elfobj.base)+sect.off), 0)
857 sect.base, sect.readOnlyMem, err = elfobj.f.Slice(uint64(sect.size))
858 if err != nil {
859 return fmt.Errorf("short read: %v", err)
860 }
861
862 return nil
863 }
864
865 func readelfsym(l *loader.Loader, arch *sys.Arch, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, localSymVersion int) (err error) {
866 if i >= elfobj.nsymtab || i < 0 {
867 err = fmt.Errorf("invalid elf symbol index")
868 return err
869 }
870
871 if i == 0 {
872 return fmt.Errorf("readym: read null symbol!")
873 }
874
875 if elfobj.is64 != 0 {
876 b := new(elf.Sym64)
877 binary.Read(bytes.NewReader(elfobj.symtab.base[i*elf.Sym64Size:(i+1)*elf.Sym64Size]), elfobj.e, b)
878 elfsym.name = cstring(elfobj.symstr.base[b.Name:])
879 elfsym.value = b.Value
880 elfsym.size = b.Size
881 elfsym.shndx = elf.SectionIndex(b.Shndx)
882 elfsym.bind = elf.ST_BIND(b.Info)
883 elfsym.type_ = elf.ST_TYPE(b.Info)
884 elfsym.other = b.Other
885 } else {
886 b := new(elf.Sym32)
887 binary.Read(bytes.NewReader(elfobj.symtab.base[i*elf.Sym32Size:(i+1)*elf.Sym32Size]), elfobj.e, b)
888 elfsym.name = cstring(elfobj.symstr.base[b.Name:])
889 elfsym.value = uint64(b.Value)
890 elfsym.size = uint64(b.Size)
891 elfsym.shndx = elf.SectionIndex(b.Shndx)
892 elfsym.bind = elf.ST_BIND(b.Info)
893 elfsym.type_ = elf.ST_TYPE(b.Info)
894 elfsym.other = b.Other
895 }
896
897 var s loader.Sym
898
899 if elfsym.name == "_GLOBAL_OFFSET_TABLE_" {
900 elfsym.name = ".got"
901 }
902 if elfsym.name == ".TOC." {
903
904
905 elfsym.bind = elf.STB_LOCAL
906 }
907
908 switch elfsym.type_ {
909 case elf.STT_SECTION:
910 s = elfobj.sect[elfsym.shndx].sym
911
912 case elf.STT_OBJECT, elf.STT_FUNC, elf.STT_NOTYPE, elf.STT_COMMON:
913 switch elfsym.bind {
914 case elf.STB_GLOBAL:
915 if needSym != 0 {
916 s = l.LookupOrCreateCgoExport(elfsym.name, 0)
917
918
919
920
921
922
923
924
925 if s != 0 && elfsym.other == 2 {
926 if !l.IsExternal(s) {
927 l.MakeSymbolUpdater(s)
928 }
929 l.SetAttrDuplicateOK(s, true)
930 l.SetAttrVisibilityHidden(s, true)
931 }
932 }
933
934 case elf.STB_LOCAL:
935 if (arch.Family == sys.ARM || arch.Family == sys.ARM64) && (strings.HasPrefix(elfsym.name, "$a") || strings.HasPrefix(elfsym.name, "$d") || strings.HasPrefix(elfsym.name, "$x")) {
936
937
938 break
939 }
940
941 if elfsym.name == ".TOC." {
942
943
944 if needSym != 0 {
945 s = l.LookupOrCreateCgoExport(elfsym.name, localSymVersion)
946 l.SetAttrVisibilityHidden(s, true)
947 }
948 break
949 }
950
951 if needSym != 0 {
952
953
954
955
956
957
958 s = l.CreateStaticSym(elfsym.name)
959 l.SetAttrVisibilityHidden(s, true)
960 }
961
962 case elf.STB_WEAK:
963 if needSym != 0 {
964 s = l.LookupOrCreateCgoExport(elfsym.name, 0)
965 if elfsym.other == 2 {
966 l.SetAttrVisibilityHidden(s, true)
967 }
968
969
970 if l.OuterSym(s) != 0 {
971 l.SetAttrDuplicateOK(s, true)
972 }
973 }
974
975 default:
976 err = fmt.Errorf("%s: invalid symbol binding %d", elfsym.name, elfsym.bind)
977 return err
978 }
979 }
980
981 if s != 0 && l.SymType(s) == 0 && elfsym.type_ != elf.STT_SECTION {
982 sb := l.MakeSymbolUpdater(s)
983 sb.SetType(sym.SXREF)
984 }
985 elfsym.sym = s
986
987 return nil
988 }
989
990
991
992
993 func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, uint8, error) {
994
995
996
997
998 const (
999 AMD64 = uint32(sys.AMD64)
1000 ARM = uint32(sys.ARM)
1001 ARM64 = uint32(sys.ARM64)
1002 I386 = uint32(sys.I386)
1003 LOONG64 = uint32(sys.Loong64)
1004 MIPS = uint32(sys.MIPS)
1005 MIPS64 = uint32(sys.MIPS64)
1006 PPC64 = uint32(sys.PPC64)
1007 RISCV64 = uint32(sys.RISCV64)
1008 S390X = uint32(sys.S390X)
1009 )
1010
1011 switch uint32(arch.Family) | elftype<<16 {
1012 default:
1013 return 0, 0, fmt.Errorf("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
1014
1015 case MIPS | uint32(elf.R_MIPS_HI16)<<16,
1016 MIPS | uint32(elf.R_MIPS_LO16)<<16,
1017 MIPS | uint32(elf.R_MIPS_GOT16)<<16,
1018 MIPS | uint32(elf.R_MIPS_GOT_HI16)<<16,
1019 MIPS | uint32(elf.R_MIPS_GOT_LO16)<<16,
1020 MIPS | uint32(elf.R_MIPS_GPREL16)<<16,
1021 MIPS | uint32(elf.R_MIPS_GOT_PAGE)<<16,
1022 MIPS | uint32(elf.R_MIPS_JALR)<<16,
1023 MIPS | uint32(elf.R_MIPS_GOT_OFST)<<16,
1024 MIPS64 | uint32(elf.R_MIPS_HI16)<<16,
1025 MIPS64 | uint32(elf.R_MIPS_LO16)<<16,
1026 MIPS64 | uint32(elf.R_MIPS_GOT16)<<16,
1027 MIPS64 | uint32(elf.R_MIPS_GOT_HI16)<<16,
1028 MIPS64 | uint32(elf.R_MIPS_GOT_LO16)<<16,
1029 MIPS64 | uint32(elf.R_MIPS_GPREL16)<<16,
1030 MIPS64 | uint32(elf.R_MIPS_GOT_PAGE)<<16,
1031 MIPS64 | uint32(elf.R_MIPS_JALR)<<16,
1032 MIPS64 | uint32(elf.R_MIPS_GOT_OFST)<<16,
1033 MIPS64 | uint32(elf.R_MIPS_CALL16)<<16,
1034 MIPS64 | uint32(elf.R_MIPS_GPREL32)<<16,
1035 MIPS64 | uint32(elf.R_MIPS_64)<<16,
1036 MIPS64 | uint32(elf.R_MIPS_GOT_DISP)<<16,
1037 MIPS64 | uint32(elf.R_MIPS_PC32)<<16:
1038 return 4, 4, nil
1039
1040
1041 case LOONG64 | uint32(elf.R_LARCH_ALIGN)<<16,
1042 LOONG64 | uint32(elf.R_LARCH_RELAX)<<16:
1043 return 0, 0, nil
1044
1045 case LOONG64 | uint32(elf.R_LARCH_ADD8)<<16,
1046 LOONG64 | uint32(elf.R_LARCH_ADD6)<<16,
1047 LOONG64 | uint32(elf.R_LARCH_SUB6)<<16,
1048 LOONG64 | uint32(elf.R_LARCH_SUB8)<<16:
1049 return 1, 1, nil
1050
1051 case LOONG64 | uint32(elf.R_LARCH_ADD16)<<16,
1052 LOONG64 | uint32(elf.R_LARCH_SUB16)<<16:
1053 return 2, 2, nil
1054
1055 case LOONG64 | uint32(elf.R_LARCH_MARK_LA)<<16,
1056 LOONG64 | uint32(elf.R_LARCH_MARK_PCREL)<<16,
1057 LOONG64 | uint32(elf.R_LARCH_ADD24)<<16,
1058 LOONG64 | uint32(elf.R_LARCH_ADD32)<<16,
1059 LOONG64 | uint32(elf.R_LARCH_SUB24)<<16,
1060 LOONG64 | uint32(elf.R_LARCH_SUB32)<<16,
1061 LOONG64 | uint32(elf.R_LARCH_B16)<<16,
1062 LOONG64 | uint32(elf.R_LARCH_B21)<<16,
1063 LOONG64 | uint32(elf.R_LARCH_B26)<<16,
1064 LOONG64 | uint32(elf.R_LARCH_PCALA_HI20)<<16,
1065 LOONG64 | uint32(elf.R_LARCH_PCALA_LO12)<<16,
1066 LOONG64 | uint32(elf.R_LARCH_GOT_PC_HI20)<<16,
1067 LOONG64 | uint32(elf.R_LARCH_GOT_PC_LO12)<<16,
1068 LOONG64 | uint32(elf.R_LARCH_32_PCREL)<<16:
1069 return 4, 4, nil
1070
1071 case LOONG64 | uint32(elf.R_LARCH_64)<<16,
1072 LOONG64 | uint32(elf.R_LARCH_ADD64)<<16,
1073 LOONG64 | uint32(elf.R_LARCH_SUB64)<<16,
1074 LOONG64 | uint32(elf.R_LARCH_64_PCREL)<<16:
1075 return 8, 8, nil
1076
1077 case S390X | uint32(elf.R_390_8)<<16:
1078 return 1, 1, nil
1079
1080 case PPC64 | uint32(elf.R_PPC64_TOC16)<<16,
1081 S390X | uint32(elf.R_390_16)<<16,
1082 S390X | uint32(elf.R_390_GOT16)<<16,
1083 S390X | uint32(elf.R_390_PC16)<<16,
1084 S390X | uint32(elf.R_390_PC16DBL)<<16,
1085 S390X | uint32(elf.R_390_PLT16DBL)<<16:
1086 return 2, 2, nil
1087
1088 case ARM | uint32(elf.R_ARM_ABS32)<<16,
1089 ARM | uint32(elf.R_ARM_GOT32)<<16,
1090 ARM | uint32(elf.R_ARM_PLT32)<<16,
1091 ARM | uint32(elf.R_ARM_GOTOFF)<<16,
1092 ARM | uint32(elf.R_ARM_GOTPC)<<16,
1093 ARM | uint32(elf.R_ARM_THM_PC22)<<16,
1094 ARM | uint32(elf.R_ARM_REL32)<<16,
1095 ARM | uint32(elf.R_ARM_CALL)<<16,
1096 ARM | uint32(elf.R_ARM_V4BX)<<16,
1097 ARM | uint32(elf.R_ARM_GOT_PREL)<<16,
1098 ARM | uint32(elf.R_ARM_PC24)<<16,
1099 ARM | uint32(elf.R_ARM_JUMP24)<<16,
1100 ARM64 | uint32(elf.R_AARCH64_CALL26)<<16,
1101 ARM64 | uint32(elf.R_AARCH64_ADR_GOT_PAGE)<<16,
1102 ARM64 | uint32(elf.R_AARCH64_LD64_GOT_LO12_NC)<<16,
1103 ARM64 | uint32(elf.R_AARCH64_ADR_PREL_PG_HI21)<<16,
1104 ARM64 | uint32(elf.R_AARCH64_ADD_ABS_LO12_NC)<<16,
1105 ARM64 | uint32(elf.R_AARCH64_LDST8_ABS_LO12_NC)<<16,
1106 ARM64 | uint32(elf.R_AARCH64_LDST16_ABS_LO12_NC)<<16,
1107 ARM64 | uint32(elf.R_AARCH64_LDST32_ABS_LO12_NC)<<16,
1108 ARM64 | uint32(elf.R_AARCH64_LDST64_ABS_LO12_NC)<<16,
1109 ARM64 | uint32(elf.R_AARCH64_LDST128_ABS_LO12_NC)<<16,
1110 ARM64 | uint32(elf.R_AARCH64_PREL32)<<16,
1111 ARM64 | uint32(elf.R_AARCH64_JUMP26)<<16,
1112 AMD64 | uint32(elf.R_X86_64_PC32)<<16,
1113 AMD64 | uint32(elf.R_X86_64_PLT32)<<16,
1114 AMD64 | uint32(elf.R_X86_64_GOTPCREL)<<16,
1115 AMD64 | uint32(elf.R_X86_64_GOTPCRELX)<<16,
1116 AMD64 | uint32(elf.R_X86_64_REX_GOTPCRELX)<<16,
1117 I386 | uint32(elf.R_386_32)<<16,
1118 I386 | uint32(elf.R_386_PC32)<<16,
1119 I386 | uint32(elf.R_386_GOT32)<<16,
1120 I386 | uint32(elf.R_386_PLT32)<<16,
1121 I386 | uint32(elf.R_386_GOTOFF)<<16,
1122 I386 | uint32(elf.R_386_GOTPC)<<16,
1123 I386 | uint32(elf.R_386_GOT32X)<<16,
1124 PPC64 | uint32(elf.R_PPC64_REL24)<<16,
1125 PPC64 | uint32(elf.R_PPC64_REL24_NOTOC)<<16,
1126 PPC64 | uint32(elf.R_PPC64_REL24_P9NOTOC)<<16,
1127 PPC64 | uint32(elf.R_PPC_REL32)<<16,
1128 S390X | uint32(elf.R_390_32)<<16,
1129 S390X | uint32(elf.R_390_PC32)<<16,
1130 S390X | uint32(elf.R_390_GOT32)<<16,
1131 S390X | uint32(elf.R_390_PLT32)<<16,
1132 S390X | uint32(elf.R_390_PC32DBL)<<16,
1133 S390X | uint32(elf.R_390_PLT32DBL)<<16,
1134 S390X | uint32(elf.R_390_GOTPCDBL)<<16,
1135 S390X | uint32(elf.R_390_GOTENT)<<16:
1136 return 4, 4, nil
1137
1138 case AMD64 | uint32(elf.R_X86_64_64)<<16,
1139 AMD64 | uint32(elf.R_X86_64_PC64)<<16,
1140 ARM64 | uint32(elf.R_AARCH64_ABS64)<<16,
1141 ARM64 | uint32(elf.R_AARCH64_PREL64)<<16,
1142 PPC64 | uint32(elf.R_PPC64_ADDR64)<<16,
1143 PPC64 | uint32(elf.R_PPC64_PCREL34)<<16,
1144 PPC64 | uint32(elf.R_PPC64_GOT_PCREL34)<<16,
1145 PPC64 | uint32(elf.R_PPC64_PLT_PCREL34_NOTOC)<<16,
1146 S390X | uint32(elf.R_390_GLOB_DAT)<<16,
1147 S390X | uint32(elf.R_390_RELATIVE)<<16,
1148 S390X | uint32(elf.R_390_GOTOFF)<<16,
1149 S390X | uint32(elf.R_390_GOTPC)<<16,
1150 S390X | uint32(elf.R_390_64)<<16,
1151 S390X | uint32(elf.R_390_PC64)<<16,
1152 S390X | uint32(elf.R_390_GOT64)<<16,
1153 S390X | uint32(elf.R_390_PLT64)<<16:
1154 return 8, 8, nil
1155
1156 case RISCV64 | uint32(elf.R_RISCV_SET6)<<16,
1157 RISCV64 | uint32(elf.R_RISCV_SUB6)<<16,
1158 RISCV64 | uint32(elf.R_RISCV_SET8)<<16,
1159 RISCV64 | uint32(elf.R_RISCV_SUB8)<<16:
1160 return 1, 1, nil
1161
1162 case RISCV64 | uint32(elf.R_RISCV_RVC_BRANCH)<<16,
1163 RISCV64 | uint32(elf.R_RISCV_RVC_JUMP)<<16,
1164 RISCV64 | uint32(elf.R_RISCV_SET16)<<16,
1165 RISCV64 | uint32(elf.R_RISCV_SUB16)<<16:
1166 return 2, 2, nil
1167
1168 case RISCV64 | uint32(elf.R_RISCV_32)<<16,
1169 RISCV64 | uint32(elf.R_RISCV_BRANCH)<<16,
1170 RISCV64 | uint32(elf.R_RISCV_HI20)<<16,
1171 RISCV64 | uint32(elf.R_RISCV_LO12_I)<<16,
1172 RISCV64 | uint32(elf.R_RISCV_LO12_S)<<16,
1173 RISCV64 | uint32(elf.R_RISCV_GOT_HI20)<<16,
1174 RISCV64 | uint32(elf.R_RISCV_PCREL_HI20)<<16,
1175 RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_I)<<16,
1176 RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_S)<<16,
1177 RISCV64 | uint32(elf.R_RISCV_ADD32)<<16,
1178 RISCV64 | uint32(elf.R_RISCV_SET32)<<16,
1179 RISCV64 | uint32(elf.R_RISCV_SUB32)<<16,
1180 RISCV64 | uint32(elf.R_RISCV_32_PCREL)<<16,
1181 RISCV64 | uint32(elf.R_RISCV_RELAX)<<16:
1182 return 4, 4, nil
1183
1184 case RISCV64 | uint32(elf.R_RISCV_64)<<16,
1185 RISCV64 | uint32(elf.R_RISCV_CALL)<<16,
1186 RISCV64 | uint32(elf.R_RISCV_CALL_PLT)<<16:
1187 return 8, 8, nil
1188
1189 case PPC64 | uint32(elf.R_PPC64_TOC16_LO)<<16,
1190 PPC64 | uint32(elf.R_PPC64_TOC16_HI)<<16,
1191 PPC64 | uint32(elf.R_PPC64_TOC16_HA)<<16,
1192 PPC64 | uint32(elf.R_PPC64_TOC16_DS)<<16,
1193 PPC64 | uint32(elf.R_PPC64_TOC16_LO_DS)<<16,
1194 PPC64 | uint32(elf.R_PPC64_REL16_LO)<<16,
1195 PPC64 | uint32(elf.R_PPC64_REL16_HI)<<16,
1196 PPC64 | uint32(elf.R_PPC64_REL16_HA)<<16,
1197 PPC64 | uint32(elf.R_PPC64_PLT16_HA)<<16,
1198 PPC64 | uint32(elf.R_PPC64_PLT16_LO_DS)<<16:
1199 return 2, 4, nil
1200
1201
1202
1203 case PPC64 | uint32(elf.R_PPC64_PLTSEQ)<<16,
1204 PPC64 | uint32(elf.R_PPC64_PLTCALL)<<16,
1205 PPC64 | uint32(elf.R_PPC64_PLTCALL_NOTOC)<<16,
1206 PPC64 | uint32(elf.R_PPC64_PLTSEQ_NOTOC)<<16:
1207 return 0, 0, nil
1208
1209 }
1210 }
1211
1212 func cstring(x []byte) string {
1213 i := bytes.IndexByte(x, '\x00')
1214 if i >= 0 {
1215 x = x[:i]
1216 }
1217 return string(x)
1218 }
1219
View as plain text