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 newSym := func(name string, version int) loader.Sym {
246 return l.CreateStaticSym(name)
247 }
248 lookup := l.LookupOrCreateCgoExport
249 errorf := func(str string, args ...interface{}) ([]loader.Sym, uint32, error) {
250 return nil, 0, fmt.Errorf("loadelf: %s: %v", pn, fmt.Sprintf(str, args...))
251 }
252
253 ehdrFlags = initEhdrFlags
254
255 base := f.Offset()
256
257 var hdrbuf [64]byte
258 if _, err := io.ReadFull(f, hdrbuf[:]); err != nil {
259 return errorf("malformed elf file: %v", err)
260 }
261
262 var e binary.ByteOrder
263 switch elf.Data(hdrbuf[elf.EI_DATA]) {
264 case elf.ELFDATA2LSB:
265 e = binary.LittleEndian
266
267 case elf.ELFDATA2MSB:
268 e = binary.BigEndian
269
270 default:
271 return errorf("malformed elf file, unknown header")
272 }
273
274 hdr := new(elf.Header32)
275 binary.Read(bytes.NewReader(hdrbuf[:]), e, hdr)
276
277 if string(hdr.Ident[:elf.EI_CLASS]) != elf.ELFMAG {
278 return errorf("malformed elf file, bad header")
279 }
280
281
282 elfobj := new(ElfObj)
283
284 elfobj.e = e
285 elfobj.f = f
286 elfobj.base = base
287 elfobj.length = length
288 elfobj.name = pn
289
290 is64 := 0
291 class := elf.Class(hdrbuf[elf.EI_CLASS])
292 if class == elf.ELFCLASS64 {
293 is64 = 1
294 hdr := new(elf.Header64)
295 binary.Read(bytes.NewReader(hdrbuf[:]), e, hdr)
296 elfobj.type_ = uint32(hdr.Type)
297 elfobj.machine = uint32(hdr.Machine)
298 elfobj.version = hdr.Version
299 elfobj.entry = hdr.Entry
300 elfobj.phoff = hdr.Phoff
301 elfobj.shoff = hdr.Shoff
302 elfobj.flags = hdr.Flags
303 elfobj.ehsize = uint32(hdr.Ehsize)
304 elfobj.phentsize = uint32(hdr.Phentsize)
305 elfobj.phnum = uint32(hdr.Phnum)
306 elfobj.shentsize = uint32(hdr.Shentsize)
307 elfobj.shnum = uint32(hdr.Shnum)
308 elfobj.shstrndx = uint32(hdr.Shstrndx)
309 } else {
310 elfobj.type_ = uint32(hdr.Type)
311 elfobj.machine = uint32(hdr.Machine)
312 elfobj.version = hdr.Version
313 elfobj.entry = uint64(hdr.Entry)
314 elfobj.phoff = uint64(hdr.Phoff)
315 elfobj.shoff = uint64(hdr.Shoff)
316 elfobj.flags = hdr.Flags
317 elfobj.ehsize = uint32(hdr.Ehsize)
318 elfobj.phentsize = uint32(hdr.Phentsize)
319 elfobj.phnum = uint32(hdr.Phnum)
320 elfobj.shentsize = uint32(hdr.Shentsize)
321 elfobj.shnum = uint32(hdr.Shnum)
322 elfobj.shstrndx = uint32(hdr.Shstrndx)
323 }
324
325 elfobj.is64 = is64
326
327 if v := uint32(hdrbuf[elf.EI_VERSION]); v != elfobj.version {
328 return errorf("malformed elf version: got %d, want %d", v, elfobj.version)
329 }
330
331 if elf.Type(elfobj.type_) != elf.ET_REL {
332 return errorf("elf but not elf relocatable object")
333 }
334
335 mach := elf.Machine(elfobj.machine)
336 switch arch.Family {
337 default:
338 return errorf("elf %s unimplemented", arch.Name)
339
340 case sys.MIPS:
341 if mach != elf.EM_MIPS || class != elf.ELFCLASS32 {
342 return errorf("elf object but not mips")
343 }
344
345 case sys.MIPS64:
346 if mach != elf.EM_MIPS || class != elf.ELFCLASS64 {
347 return errorf("elf object but not mips64")
348 }
349 case sys.Loong64:
350 if mach != elf.EM_LOONGARCH || class != elf.ELFCLASS64 {
351 return errorf("elf object but not loong64")
352 }
353
354 case sys.ARM:
355 if e != binary.LittleEndian || mach != elf.EM_ARM || class != elf.ELFCLASS32 {
356 return errorf("elf object but not arm")
357 }
358
359 case sys.AMD64:
360 if e != binary.LittleEndian || mach != elf.EM_X86_64 || class != elf.ELFCLASS64 {
361 return errorf("elf object but not amd64")
362 }
363
364 case sys.ARM64:
365 if e != binary.LittleEndian || mach != elf.EM_AARCH64 || class != elf.ELFCLASS64 {
366 return errorf("elf object but not arm64")
367 }
368
369 case sys.I386:
370 if e != binary.LittleEndian || mach != elf.EM_386 || class != elf.ELFCLASS32 {
371 return errorf("elf object but not 386")
372 }
373
374 case sys.PPC64:
375 if mach != elf.EM_PPC64 || class != elf.ELFCLASS64 {
376 return errorf("elf object but not ppc64")
377 }
378
379 case sys.RISCV64:
380 if mach != elf.EM_RISCV || class != elf.ELFCLASS64 {
381 return errorf("elf object but not riscv64")
382 }
383
384 case sys.S390X:
385 if mach != elf.EM_S390 || class != elf.ELFCLASS64 {
386 return errorf("elf object but not s390x")
387 }
388 }
389
390
391 elfobj.sect = make([]ElfSect, elfobj.shnum)
392
393 elfobj.nsect = uint(elfobj.shnum)
394 for i := 0; uint(i) < elfobj.nsect; i++ {
395 f.MustSeek(int64(uint64(base)+elfobj.shoff+uint64(int64(i)*int64(elfobj.shentsize))), 0)
396 sect := &elfobj.sect[i]
397 if is64 != 0 {
398 var b elf.Section64
399 if err := binary.Read(f, e, &b); err != nil {
400 return errorf("malformed elf file: %v", err)
401 }
402
403 sect.nameoff = b.Name
404 sect.type_ = elf.SectionType(b.Type)
405 sect.flags = elf.SectionFlag(b.Flags)
406 sect.addr = b.Addr
407 sect.off = b.Off
408 sect.size = b.Size
409 sect.link = b.Link
410 sect.info = b.Info
411 sect.align = b.Addralign
412 sect.entsize = b.Entsize
413 } else {
414 var b elf.Section32
415
416 if err := binary.Read(f, e, &b); err != nil {
417 return errorf("malformed elf file: %v", err)
418 }
419 sect.nameoff = b.Name
420 sect.type_ = elf.SectionType(b.Type)
421 sect.flags = elf.SectionFlag(b.Flags)
422 sect.addr = uint64(b.Addr)
423 sect.off = uint64(b.Off)
424 sect.size = uint64(b.Size)
425 sect.link = b.Link
426 sect.info = b.Info
427 sect.align = uint64(b.Addralign)
428 sect.entsize = uint64(b.Entsize)
429 }
430 }
431
432
433 if elfobj.shstrndx >= uint32(elfobj.nsect) {
434 return errorf("malformed elf file: shstrndx out of range %d >= %d", elfobj.shstrndx, elfobj.nsect)
435 }
436
437 sect := &elfobj.sect[elfobj.shstrndx]
438 if err := elfmap(elfobj, sect); err != nil {
439 return errorf("malformed elf file: %v", err)
440 }
441 for i := 0; uint(i) < elfobj.nsect; i++ {
442 if elfobj.sect[i].nameoff != 0 {
443 elfobj.sect[i].name = cstring(sect.base[elfobj.sect[i].nameoff:])
444 }
445 }
446
447
448 elfobj.symtab = section(elfobj, ".symtab")
449
450 if elfobj.symtab == nil {
451
452 return
453 }
454
455 if elfobj.symtab.link <= 0 || elfobj.symtab.link >= uint32(elfobj.nsect) {
456 return errorf("elf object has symbol table with invalid string table link")
457 }
458
459 elfobj.symstr = &elfobj.sect[elfobj.symtab.link]
460 if is64 != 0 {
461 elfobj.nsymtab = int(elfobj.symtab.size / elf.Sym64Size)
462 } else {
463 elfobj.nsymtab = int(elfobj.symtab.size / elf.Sym32Size)
464 }
465
466 if err := elfmap(elfobj, elfobj.symtab); err != nil {
467 return errorf("malformed elf file: %v", err)
468 }
469 if err := elfmap(elfobj, elfobj.symstr); err != nil {
470 return errorf("malformed elf file: %v", err)
471 }
472
473
474
475
476
477
478
479 sectsymNames := make(map[string]bool)
480 counter := 0
481 for i := 0; uint(i) < elfobj.nsect; i++ {
482 sect = &elfobj.sect[i]
483 if sect.type_ == SHT_ARM_ATTRIBUTES && sect.name == ".ARM.attributes" {
484 if err := elfmap(elfobj, sect); err != nil {
485 return errorf("%s: malformed elf file: %v", pn, err)
486 }
487
488 if initEhdrFlags == 0x5000002 {
489 ehdrFlags = 0x5000202
490 } else {
491 ehdrFlags = initEhdrFlags
492 }
493 found, newEhdrFlags, err := parseArmAttributes(e, sect.base[:sect.size])
494 if err != nil {
495
496 log.Printf("%s: %v", pn, err)
497 }
498 if found {
499 ehdrFlags = newEhdrFlags
500 }
501 }
502 if (sect.type_ != elf.SHT_PROGBITS && sect.type_ != elf.SHT_NOBITS) || sect.flags&elf.SHF_ALLOC == 0 {
503 continue
504 }
505 if sect.type_ != elf.SHT_NOBITS {
506 if err := elfmap(elfobj, sect); err != nil {
507 return errorf("%s: malformed elf file: %v", pn, err)
508 }
509 }
510
511 name := fmt.Sprintf("%s(%s)", pkg, sect.name)
512 for sectsymNames[name] {
513 counter++
514 name = fmt.Sprintf("%s(%s%d)", pkg, sect.name, counter)
515 }
516 sectsymNames[name] = true
517
518 sb := l.MakeSymbolUpdater(lookup(name, localSymVersion))
519
520 switch sect.flags & (elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_EXECINSTR) {
521 default:
522 return errorf("%s: unexpected flags for ELF section %s", pn, sect.name)
523
524 case elf.SHF_ALLOC:
525 sb.SetType(sym.SRODATA)
526
527 case elf.SHF_ALLOC + elf.SHF_WRITE:
528 if sect.type_ == elf.SHT_NOBITS {
529 sb.SetType(sym.SNOPTRBSS)
530 } else {
531 sb.SetType(sym.SNOPTRDATA)
532 }
533
534 case elf.SHF_ALLOC + elf.SHF_EXECINSTR:
535 sb.SetType(sym.STEXT)
536 }
537
538 if sect.name == ".got" || sect.name == ".toc" {
539 sb.SetType(sym.SELFGOT)
540 }
541 if sect.type_ == elf.SHT_PROGBITS {
542 sb.SetData(sect.base[:sect.size])
543 sb.SetExternal(true)
544 }
545
546 sb.SetSize(int64(sect.size))
547 sb.SetAlign(int32(sect.align))
548 sb.SetReadOnly(sect.readOnlyMem)
549
550 sect.sym = sb.Sym()
551 }
552
553
554
555 symbols := make([]loader.Sym, elfobj.nsymtab)
556
557 for i := 1; i < elfobj.nsymtab; i++ {
558 var elfsym ElfSym
559 if err := readelfsym(newSym, lookup, l, arch, elfobj, i, &elfsym, 1, localSymVersion); err != nil {
560 return errorf("%s: malformed elf file: %v", pn, err)
561 }
562 symbols[i] = elfsym.sym
563 if elfsym.type_ != elf.STT_FUNC && elfsym.type_ != elf.STT_OBJECT && elfsym.type_ != elf.STT_NOTYPE && elfsym.type_ != elf.STT_COMMON {
564 continue
565 }
566 if elfsym.shndx == elf.SHN_COMMON || elfsym.type_ == elf.STT_COMMON {
567 sb := l.MakeSymbolUpdater(elfsym.sym)
568 if uint64(sb.Size()) < elfsym.size {
569 sb.SetSize(int64(elfsym.size))
570 }
571 if sb.Type() == 0 || sb.Type() == sym.SXREF {
572 sb.SetType(sym.SNOPTRBSS)
573 }
574 continue
575 }
576
577 if uint(elfsym.shndx) >= elfobj.nsect || elfsym.shndx == 0 {
578 continue
579 }
580
581
582 if elfsym.sym == 0 {
583 continue
584 }
585 sect = &elfobj.sect[elfsym.shndx]
586 if sect.sym == 0 {
587 if elfsym.type_ == 0 {
588 if strings.HasPrefix(sect.name, ".debug_") && elfsym.name == "" {
589
590
591
592 continue
593 }
594 if strings.HasPrefix(elfsym.name, ".Ldebug_") || elfsym.name == ".L0 " {
595
596 continue
597 }
598 if elfsym.name == ".Lline_table_start0" {
599
600 continue
601 }
602
603 if strings.HasPrefix(elfsym.name, "$d") && sect.name == ".debug_frame" {
604
605
606
607 continue
608 }
609 }
610
611 if strings.HasPrefix(elfsym.name, ".Linfo_string") {
612
613 continue
614 }
615
616 if strings.HasPrefix(elfsym.name, ".LASF") || strings.HasPrefix(elfsym.name, ".LLRL") || strings.HasPrefix(elfsym.name, ".LLST") {
617
618 continue
619 }
620
621 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_)
622 }
623
624 s := elfsym.sym
625 if l.OuterSym(s) != 0 {
626 if l.AttrDuplicateOK(s) {
627 continue
628 }
629 return errorf("duplicate symbol reference: %s in both %s and %s",
630 l.SymName(s), l.SymName(l.OuterSym(s)), l.SymName(sect.sym))
631 }
632
633 sectsb := l.MakeSymbolUpdater(sect.sym)
634 sb := l.MakeSymbolUpdater(s)
635
636 sb.SetType(sectsb.Type())
637 sectsb.AddInteriorSym(s)
638 if !l.AttrCgoExportDynamic(s) {
639 sb.SetDynimplib("")
640 }
641 sb.SetValue(int64(elfsym.value))
642 sb.SetSize(int64(elfsym.size))
643 if sectsb.Type() == sym.STEXT {
644 if l.AttrExternal(s) && !l.AttrDuplicateOK(s) {
645 return errorf("%s: duplicate symbol definition", sb.Name())
646 }
647 l.SetAttrExternal(s, true)
648 }
649
650 if elf.Machine(elfobj.machine) == elf.EM_PPC64 {
651 flag := int(elfsym.other) >> 5
652 switch flag {
653 case 0:
654
655 case 1:
656
657
658
659
660 l.SetSymLocalentry(s, 1)
661 case 7:
662 return errorf("%s: invalid sym.other 0x%x", sb.Name(), elfsym.other)
663 default:
664
665 l.SetSymLocalentry(s, 4<<uint(flag-2))
666 }
667 }
668 }
669
670
671
672 for i := uint(0); i < elfobj.nsect; i++ {
673 s := elfobj.sect[i].sym
674 if s == 0 {
675 continue
676 }
677 sb := l.MakeSymbolUpdater(s)
678 if l.SubSym(s) != 0 {
679 sb.SortSub()
680 }
681 if sb.Type() == sym.STEXT {
682 if l.AttrOnList(s) {
683 return errorf("symbol %s listed multiple times",
684 l.SymName(s))
685 }
686 l.SetAttrOnList(s, true)
687 textp = append(textp, s)
688 for ss := l.SubSym(s); ss != 0; ss = l.SubSym(ss) {
689 if l.AttrOnList(ss) {
690 return errorf("symbol %s listed multiple times",
691 l.SymName(ss))
692 }
693 l.SetAttrOnList(ss, true)
694 textp = append(textp, ss)
695 }
696 }
697 }
698
699
700 for i := uint(0); i < elfobj.nsect; i++ {
701 rsect := &elfobj.sect[i]
702 if rsect.type_ != elf.SHT_RELA && rsect.type_ != elf.SHT_REL {
703 continue
704 }
705 if rsect.info >= uint32(elfobj.nsect) || elfobj.sect[rsect.info].base == nil {
706 continue
707 }
708 sect = &elfobj.sect[rsect.info]
709 if err := elfmap(elfobj, rsect); err != nil {
710 return errorf("malformed elf file: %v", err)
711 }
712 rela := 0
713 if rsect.type_ == elf.SHT_RELA {
714 rela = 1
715 }
716 n := int(rsect.size / uint64(4+4*is64) / uint64(2+rela))
717 p := rsect.base
718 sb := l.MakeSymbolUpdater(sect.sym)
719 for j := 0; j < n; j++ {
720 var add uint64
721 var symIdx int
722 var relocType uint64
723 var rOff int32
724 var rAdd int64
725 var rSym loader.Sym
726
727 if is64 != 0 {
728
729 rOff = int32(e.Uint64(p))
730
731 p = p[8:]
732 switch arch.Family {
733 case sys.MIPS64:
734
735
736 symIdx = int(e.Uint32(p))
737 relocType = uint64(p[7])
738 default:
739 info := e.Uint64(p)
740 relocType = info & 0xffffffff
741 symIdx = int(info >> 32)
742 }
743 p = p[8:]
744 if rela != 0 {
745 add = e.Uint64(p)
746 p = p[8:]
747 }
748 } else {
749
750 rOff = int32(e.Uint32(p))
751
752 p = p[4:]
753 info := e.Uint32(p)
754 relocType = uint64(info & 0xff)
755 symIdx = int(info >> 8)
756 p = p[4:]
757 if rela != 0 {
758 add = uint64(e.Uint32(p))
759 p = p[4:]
760 }
761 }
762
763 if relocType == 0 {
764 j--
765 n--
766 continue
767 }
768
769 if symIdx == 0 {
770 rSym = 0
771 } else {
772 var elfsym ElfSym
773 if err := readelfsym(newSym, lookup, l, arch, elfobj, int(symIdx), &elfsym, 0, 0); err != nil {
774 return errorf("malformed elf file: %v", err)
775 }
776 elfsym.sym = symbols[symIdx]
777 if elfsym.sym == 0 {
778 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_)
779 }
780
781 rSym = elfsym.sym
782 }
783
784 rType := objabi.ElfRelocOffset + objabi.RelocType(relocType)
785 rSize, addendSize, err := relSize(arch, pn, uint32(relocType))
786 if err != nil {
787 return nil, 0, err
788 }
789 if rela != 0 {
790 rAdd = int64(add)
791 } else {
792
793 if rSize == 4 {
794 rAdd = int64(e.Uint32(sect.base[rOff:]))
795 } else if rSize == 8 {
796 rAdd = int64(e.Uint64(sect.base[rOff:]))
797 } else {
798 return errorf("invalid rela size %d", rSize)
799 }
800 }
801
802 if addendSize == 2 {
803 rAdd = int64(int16(rAdd))
804 }
805 if addendSize == 4 {
806 rAdd = int64(int32(rAdd))
807 }
808
809 r, _ := sb.AddRel(rType)
810 r.SetOff(rOff)
811 r.SetSiz(rSize)
812 r.SetSym(rSym)
813 r.SetAdd(rAdd)
814 }
815
816 sb.SortRelocs()
817 }
818
819 return textp, ehdrFlags, nil
820 }
821
822 func section(elfobj *ElfObj, name string) *ElfSect {
823 for i := 0; uint(i) < elfobj.nsect; i++ {
824 if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name {
825 return &elfobj.sect[i]
826 }
827 }
828 return nil
829 }
830
831 func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) {
832 if sect.base != nil {
833 return nil
834 }
835
836 if sect.off+sect.size > uint64(elfobj.length) {
837 err = fmt.Errorf("elf section past end of file")
838 return err
839 }
840
841 elfobj.f.MustSeek(int64(uint64(elfobj.base)+sect.off), 0)
842 sect.base, sect.readOnlyMem, err = elfobj.f.Slice(uint64(sect.size))
843 if err != nil {
844 return fmt.Errorf("short read: %v", err)
845 }
846
847 return nil
848 }
849
850 func readelfsym(newSym, lookup func(string, int) loader.Sym, l *loader.Loader, arch *sys.Arch, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, localSymVersion int) (err error) {
851 if i >= elfobj.nsymtab || i < 0 {
852 err = fmt.Errorf("invalid elf symbol index")
853 return err
854 }
855
856 if i == 0 {
857 return fmt.Errorf("readym: read null symbol!")
858 }
859
860 if elfobj.is64 != 0 {
861 b := new(elf.Sym64)
862 binary.Read(bytes.NewReader(elfobj.symtab.base[i*elf.Sym64Size:(i+1)*elf.Sym64Size]), elfobj.e, b)
863 elfsym.name = cstring(elfobj.symstr.base[b.Name:])
864 elfsym.value = b.Value
865 elfsym.size = b.Size
866 elfsym.shndx = elf.SectionIndex(b.Shndx)
867 elfsym.bind = elf.ST_BIND(b.Info)
868 elfsym.type_ = elf.ST_TYPE(b.Info)
869 elfsym.other = b.Other
870 } else {
871 b := new(elf.Sym32)
872 binary.Read(bytes.NewReader(elfobj.symtab.base[i*elf.Sym32Size:(i+1)*elf.Sym32Size]), elfobj.e, b)
873 elfsym.name = cstring(elfobj.symstr.base[b.Name:])
874 elfsym.value = uint64(b.Value)
875 elfsym.size = uint64(b.Size)
876 elfsym.shndx = elf.SectionIndex(b.Shndx)
877 elfsym.bind = elf.ST_BIND(b.Info)
878 elfsym.type_ = elf.ST_TYPE(b.Info)
879 elfsym.other = b.Other
880 }
881
882 var s loader.Sym
883
884 if elfsym.name == "_GLOBAL_OFFSET_TABLE_" {
885 elfsym.name = ".got"
886 }
887 if elfsym.name == ".TOC." {
888
889
890 elfsym.bind = elf.STB_LOCAL
891 }
892
893 switch elfsym.type_ {
894 case elf.STT_SECTION:
895 s = elfobj.sect[elfsym.shndx].sym
896
897 case elf.STT_OBJECT, elf.STT_FUNC, elf.STT_NOTYPE, elf.STT_COMMON:
898 switch elfsym.bind {
899 case elf.STB_GLOBAL:
900 if needSym != 0 {
901 s = lookup(elfsym.name, 0)
902
903
904
905
906
907
908
909
910 if s != 0 && elfsym.other == 2 {
911 if !l.IsExternal(s) {
912 l.MakeSymbolUpdater(s)
913 }
914 l.SetAttrDuplicateOK(s, true)
915 l.SetAttrVisibilityHidden(s, true)
916 }
917 }
918
919 case elf.STB_LOCAL:
920 if (arch.Family == sys.ARM || arch.Family == sys.ARM64) && (strings.HasPrefix(elfsym.name, "$a") || strings.HasPrefix(elfsym.name, "$d") || strings.HasPrefix(elfsym.name, "$x")) {
921
922
923 break
924 }
925
926 if elfsym.name == ".TOC." {
927
928
929 if needSym != 0 {
930 s = lookup(elfsym.name, localSymVersion)
931 l.SetAttrVisibilityHidden(s, true)
932 }
933 break
934 }
935
936 if needSym != 0 {
937
938
939
940
941
942
943 s = newSym(elfsym.name, localSymVersion)
944 l.SetAttrVisibilityHidden(s, true)
945 }
946
947 case elf.STB_WEAK:
948 if needSym != 0 {
949 s = lookup(elfsym.name, 0)
950 if elfsym.other == 2 {
951 l.SetAttrVisibilityHidden(s, true)
952 }
953
954
955 if l.OuterSym(s) != 0 {
956 l.SetAttrDuplicateOK(s, true)
957 }
958 }
959
960 default:
961 err = fmt.Errorf("%s: invalid symbol binding %d", elfsym.name, elfsym.bind)
962 return err
963 }
964 }
965
966 if s != 0 && l.SymType(s) == 0 && elfsym.type_ != elf.STT_SECTION {
967 sb := l.MakeSymbolUpdater(s)
968 sb.SetType(sym.SXREF)
969 }
970 elfsym.sym = s
971
972 return nil
973 }
974
975
976
977
978 func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, uint8, error) {
979
980
981
982
983 const (
984 AMD64 = uint32(sys.AMD64)
985 ARM = uint32(sys.ARM)
986 ARM64 = uint32(sys.ARM64)
987 I386 = uint32(sys.I386)
988 LOONG64 = uint32(sys.Loong64)
989 MIPS = uint32(sys.MIPS)
990 MIPS64 = uint32(sys.MIPS64)
991 PPC64 = uint32(sys.PPC64)
992 RISCV64 = uint32(sys.RISCV64)
993 S390X = uint32(sys.S390X)
994 )
995
996 switch uint32(arch.Family) | elftype<<16 {
997 default:
998 return 0, 0, fmt.Errorf("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
999
1000 case MIPS | uint32(elf.R_MIPS_HI16)<<16,
1001 MIPS | uint32(elf.R_MIPS_LO16)<<16,
1002 MIPS | uint32(elf.R_MIPS_GOT16)<<16,
1003 MIPS | uint32(elf.R_MIPS_GOT_HI16)<<16,
1004 MIPS | uint32(elf.R_MIPS_GOT_LO16)<<16,
1005 MIPS | uint32(elf.R_MIPS_GPREL16)<<16,
1006 MIPS | uint32(elf.R_MIPS_GOT_PAGE)<<16,
1007 MIPS | uint32(elf.R_MIPS_JALR)<<16,
1008 MIPS | uint32(elf.R_MIPS_GOT_OFST)<<16,
1009 MIPS64 | uint32(elf.R_MIPS_HI16)<<16,
1010 MIPS64 | uint32(elf.R_MIPS_LO16)<<16,
1011 MIPS64 | uint32(elf.R_MIPS_GOT16)<<16,
1012 MIPS64 | uint32(elf.R_MIPS_GOT_HI16)<<16,
1013 MIPS64 | uint32(elf.R_MIPS_GOT_LO16)<<16,
1014 MIPS64 | uint32(elf.R_MIPS_GPREL16)<<16,
1015 MIPS64 | uint32(elf.R_MIPS_GOT_PAGE)<<16,
1016 MIPS64 | uint32(elf.R_MIPS_JALR)<<16,
1017 MIPS64 | uint32(elf.R_MIPS_GOT_OFST)<<16,
1018 MIPS64 | uint32(elf.R_MIPS_CALL16)<<16,
1019 MIPS64 | uint32(elf.R_MIPS_GPREL32)<<16,
1020 MIPS64 | uint32(elf.R_MIPS_64)<<16,
1021 MIPS64 | uint32(elf.R_MIPS_GOT_DISP)<<16,
1022 MIPS64 | uint32(elf.R_MIPS_PC32)<<16:
1023 return 4, 4, nil
1024
1025 case LOONG64 | uint32(elf.R_LARCH_ADD8)<<16,
1026 LOONG64 | uint32(elf.R_LARCH_SUB8)<<16:
1027 return 1, 1, nil
1028
1029 case LOONG64 | uint32(elf.R_LARCH_ADD16)<<16,
1030 LOONG64 | uint32(elf.R_LARCH_SUB16)<<16:
1031 return 2, 2, nil
1032
1033 case LOONG64 | uint32(elf.R_LARCH_SOP_PUSH_PCREL)<<16,
1034 LOONG64 | uint32(elf.R_LARCH_SOP_PUSH_GPREL)<<16,
1035 LOONG64 | uint32(elf.R_LARCH_SOP_PUSH_ABSOLUTE)<<16,
1036 LOONG64 | uint32(elf.R_LARCH_MARK_LA)<<16,
1037 LOONG64 | uint32(elf.R_LARCH_SOP_POP_32_S_0_10_10_16_S2)<<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