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