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