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
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(lookup(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 }
540
541 sb.SetSize(int64(sect.size))
542 sb.SetAlign(int32(sect.align))
543 sb.SetReadOnly(sect.readOnlyMem)
544
545 sect.sym = sb.Sym()
546 }
547
548
549
550 symbols := make([]loader.Sym, elfobj.nsymtab)
551
552 for i := 1; i < elfobj.nsymtab; i++ {
553 var elfsym ElfSym
554 if err := readelfsym(newSym, lookup, l, arch, elfobj, i, &elfsym, 1, localSymVersion); err != nil {
555 return errorf("%s: malformed elf file: %v", pn, err)
556 }
557 symbols[i] = elfsym.sym
558 if elfsym.type_ != elf.STT_FUNC && elfsym.type_ != elf.STT_OBJECT && elfsym.type_ != elf.STT_NOTYPE && elfsym.type_ != elf.STT_COMMON {
559 continue
560 }
561 if elfsym.shndx == elf.SHN_COMMON || elfsym.type_ == elf.STT_COMMON {
562 sb := l.MakeSymbolUpdater(elfsym.sym)
563 if uint64(sb.Size()) < elfsym.size {
564 sb.SetSize(int64(elfsym.size))
565 }
566 if sb.Type() == 0 || sb.Type() == sym.SXREF {
567 sb.SetType(sym.SNOPTRBSS)
568 }
569 continue
570 }
571
572 if uint(elfsym.shndx) >= elfobj.nsect || elfsym.shndx == 0 {
573 continue
574 }
575
576
577 if elfsym.sym == 0 {
578 continue
579 }
580 sect = &elfobj.sect[elfsym.shndx]
581 if sect.sym == 0 {
582 if strings.HasPrefix(elfsym.name, ".Linfo_string") {
583 continue
584 }
585
586 if elfsym.name == "" && elfsym.type_ == 0 && sect.name == ".debug_str" {
587
588
589 continue
590 }
591
592 if strings.HasPrefix(elfsym.name, "$d") && elfsym.type_ == 0 && sect.name == ".debug_frame" {
593
594
595
596 continue
597 }
598
599 if strings.HasPrefix(elfsym.name, ".LASF") {
600 continue
601 }
602 return errorf("%v: sym#%d (%s): ignoring symbol in section %d (type %d)", elfsym.sym, i, elfsym.name, elfsym.shndx, elfsym.type_)
603 }
604
605 s := elfsym.sym
606 if l.OuterSym(s) != 0 {
607 if l.AttrDuplicateOK(s) {
608 continue
609 }
610 return errorf("duplicate symbol reference: %s in both %s and %s",
611 l.SymName(s), l.SymName(l.OuterSym(s)), l.SymName(sect.sym))
612 }
613
614 sectsb := l.MakeSymbolUpdater(sect.sym)
615 sb := l.MakeSymbolUpdater(s)
616
617 sb.SetType(sectsb.Type())
618 sectsb.AddInteriorSym(s)
619 if !l.AttrCgoExportDynamic(s) {
620 sb.SetDynimplib("")
621 }
622 sb.SetValue(int64(elfsym.value))
623 sb.SetSize(int64(elfsym.size))
624 if sectsb.Type() == sym.STEXT {
625 if l.AttrExternal(s) && !l.AttrDuplicateOK(s) {
626 return errorf("%s: duplicate symbol definition", sb.Name())
627 }
628 l.SetAttrExternal(s, true)
629 }
630
631 if elf.Machine(elfobj.machine) == elf.EM_PPC64 {
632 flag := int(elfsym.other) >> 5
633 if 2 <= flag && flag <= 6 {
634 l.SetSymLocalentry(s, 1<<uint(flag-2))
635 } else if flag == 7 {
636 return errorf("%s: invalid sym.other 0x%x", sb.Name(), elfsym.other)
637 }
638 }
639 }
640
641
642
643 for i := uint(0); i < elfobj.nsect; i++ {
644 s := elfobj.sect[i].sym
645 if s == 0 {
646 continue
647 }
648 sb := l.MakeSymbolUpdater(s)
649 if l.SubSym(s) != 0 {
650 sb.SortSub()
651 }
652 if sb.Type() == sym.STEXT {
653 if l.AttrOnList(s) {
654 return errorf("symbol %s listed multiple times",
655 l.SymName(s))
656 }
657 l.SetAttrOnList(s, true)
658 textp = append(textp, s)
659 for ss := l.SubSym(s); ss != 0; ss = l.SubSym(ss) {
660 if l.AttrOnList(ss) {
661 return errorf("symbol %s listed multiple times",
662 l.SymName(ss))
663 }
664 l.SetAttrOnList(ss, true)
665 textp = append(textp, ss)
666 }
667 }
668 }
669
670
671 for i := uint(0); i < elfobj.nsect; i++ {
672 rsect := &elfobj.sect[i]
673 if rsect.type_ != elf.SHT_RELA && rsect.type_ != elf.SHT_REL {
674 continue
675 }
676 if rsect.info >= uint32(elfobj.nsect) || elfobj.sect[rsect.info].base == nil {
677 continue
678 }
679 sect = &elfobj.sect[rsect.info]
680 if err := elfmap(elfobj, rsect); err != nil {
681 return errorf("malformed elf file: %v", err)
682 }
683 rela := 0
684 if rsect.type_ == elf.SHT_RELA {
685 rela = 1
686 }
687 n := int(rsect.size / uint64(4+4*is64) / uint64(2+rela))
688 p := rsect.base
689 sb := l.MakeSymbolUpdater(sect.sym)
690 for j := 0; j < n; j++ {
691 var add uint64
692 var symIdx int
693 var relocType uint64
694 var rOff int32
695 var rAdd int64
696 var rSym loader.Sym
697
698 if is64 != 0 {
699
700 rOff = int32(e.Uint64(p))
701
702 p = p[8:]
703 switch arch.Family {
704 case sys.MIPS64:
705
706
707 symIdx = int(e.Uint32(p))
708 relocType = uint64(p[7])
709 default:
710 info := e.Uint64(p)
711 relocType = info & 0xffffffff
712 symIdx = int(info >> 32)
713 }
714 p = p[8:]
715 if rela != 0 {
716 add = e.Uint64(p)
717 p = p[8:]
718 }
719 } else {
720
721 rOff = int32(e.Uint32(p))
722
723 p = p[4:]
724 info := e.Uint32(p)
725 relocType = uint64(info & 0xff)
726 symIdx = int(info >> 8)
727 p = p[4:]
728 if rela != 0 {
729 add = uint64(e.Uint32(p))
730 p = p[4:]
731 }
732 }
733
734 if relocType == 0 {
735 j--
736 n--
737 continue
738 }
739
740 if symIdx == 0 {
741 rSym = 0
742 } else {
743 var elfsym ElfSym
744 if err := readelfsym(newSym, lookup, l, arch, elfobj, int(symIdx), &elfsym, 0, 0); err != nil {
745 return errorf("malformed elf file: %v", err)
746 }
747 elfsym.sym = symbols[symIdx]
748 if elfsym.sym == 0 {
749 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_)
750 }
751
752 rSym = elfsym.sym
753 }
754
755 rType := objabi.ElfRelocOffset + objabi.RelocType(relocType)
756 rSize, addendSize, err := relSize(arch, pn, uint32(relocType))
757 if err != nil {
758 return nil, 0, err
759 }
760 if rela != 0 {
761 rAdd = int64(add)
762 } else {
763
764 if rSize == 4 {
765 rAdd = int64(e.Uint32(sect.base[rOff:]))
766 } else if rSize == 8 {
767 rAdd = int64(e.Uint64(sect.base[rOff:]))
768 } else {
769 return errorf("invalid rela size %d", rSize)
770 }
771 }
772
773 if addendSize == 2 {
774 rAdd = int64(int16(rAdd))
775 }
776 if addendSize == 4 {
777 rAdd = int64(int32(rAdd))
778 }
779
780 r, _ := sb.AddRel(rType)
781 r.SetOff(rOff)
782 r.SetSiz(rSize)
783 r.SetSym(rSym)
784 r.SetAdd(rAdd)
785 }
786
787 sb.SortRelocs()
788 }
789
790 return textp, ehdrFlags, nil
791 }
792
793 func section(elfobj *ElfObj, name string) *ElfSect {
794 for i := 0; uint(i) < elfobj.nsect; i++ {
795 if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name {
796 return &elfobj.sect[i]
797 }
798 }
799 return nil
800 }
801
802 func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) {
803 if sect.base != nil {
804 return nil
805 }
806
807 if sect.off+sect.size > uint64(elfobj.length) {
808 err = fmt.Errorf("elf section past end of file")
809 return err
810 }
811
812 elfobj.f.MustSeek(int64(uint64(elfobj.base)+sect.off), 0)
813 sect.base, sect.readOnlyMem, err = elfobj.f.Slice(uint64(sect.size))
814 if err != nil {
815 return fmt.Errorf("short read: %v", err)
816 }
817
818 return nil
819 }
820
821 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) {
822 if i >= elfobj.nsymtab || i < 0 {
823 err = fmt.Errorf("invalid elf symbol index")
824 return err
825 }
826
827 if i == 0 {
828 return fmt.Errorf("readym: read null symbol!")
829 }
830
831 if elfobj.is64 != 0 {
832 b := new(elf.Sym64)
833 binary.Read(bytes.NewReader(elfobj.symtab.base[i*elf.Sym64Size:(i+1)*elf.Sym64Size]), elfobj.e, b)
834 elfsym.name = cstring(elfobj.symstr.base[b.Name:])
835 elfsym.value = b.Value
836 elfsym.size = b.Size
837 elfsym.shndx = elf.SectionIndex(b.Shndx)
838 elfsym.bind = elf.ST_BIND(b.Info)
839 elfsym.type_ = elf.ST_TYPE(b.Info)
840 elfsym.other = b.Other
841 } else {
842 b := new(elf.Sym32)
843 binary.Read(bytes.NewReader(elfobj.symtab.base[i*elf.Sym32Size:(i+1)*elf.Sym32Size]), elfobj.e, b)
844 elfsym.name = cstring(elfobj.symstr.base[b.Name:])
845 elfsym.value = uint64(b.Value)
846 elfsym.size = uint64(b.Size)
847 elfsym.shndx = elf.SectionIndex(b.Shndx)
848 elfsym.bind = elf.ST_BIND(b.Info)
849 elfsym.type_ = elf.ST_TYPE(b.Info)
850 elfsym.other = b.Other
851 }
852
853 var s loader.Sym
854
855 if elfsym.name == "_GLOBAL_OFFSET_TABLE_" {
856 elfsym.name = ".got"
857 }
858 if elfsym.name == ".TOC." {
859
860
861 elfsym.bind = elf.STB_LOCAL
862 }
863
864 switch elfsym.type_ {
865 case elf.STT_SECTION:
866 s = elfobj.sect[elfsym.shndx].sym
867
868 case elf.STT_OBJECT, elf.STT_FUNC, elf.STT_NOTYPE, elf.STT_COMMON:
869 switch elfsym.bind {
870 case elf.STB_GLOBAL:
871 if needSym != 0 {
872 s = lookup(elfsym.name, 0)
873
874
875
876
877
878
879
880
881 if s != 0 && elfsym.other == 2 {
882 if !l.IsExternal(s) {
883 l.MakeSymbolUpdater(s)
884 }
885 l.SetAttrDuplicateOK(s, true)
886 l.SetAttrVisibilityHidden(s, true)
887 }
888 }
889
890 case elf.STB_LOCAL:
891 if (arch.Family == sys.ARM || arch.Family == sys.ARM64) && (strings.HasPrefix(elfsym.name, "$a") || strings.HasPrefix(elfsym.name, "$d") || strings.HasPrefix(elfsym.name, "$x")) {
892
893
894 break
895 }
896
897 if elfsym.name == ".TOC." {
898
899
900 if needSym != 0 {
901 s = lookup(elfsym.name, localSymVersion)
902 l.SetAttrVisibilityHidden(s, true)
903 }
904 break
905 }
906
907 if needSym != 0 {
908
909
910
911
912
913
914 s = newSym(elfsym.name, localSymVersion)
915 l.SetAttrVisibilityHidden(s, true)
916 }
917
918 case elf.STB_WEAK:
919 if needSym != 0 {
920 s = lookup(elfsym.name, 0)
921 if elfsym.other == 2 {
922 l.SetAttrVisibilityHidden(s, true)
923 }
924
925
926 if l.OuterSym(s) != 0 {
927 l.SetAttrDuplicateOK(s, true)
928 }
929 }
930
931 default:
932 err = fmt.Errorf("%s: invalid symbol binding %d", elfsym.name, elfsym.bind)
933 return err
934 }
935 }
936
937
938
939 if s != 0 && l.SymType(s) == 0 && !l.AttrVisibilityHidden(s) && elfsym.type_ != elf.STT_SECTION {
940 sb := l.MakeSymbolUpdater(s)
941 sb.SetType(sym.SXREF)
942 }
943 elfsym.sym = s
944
945 return nil
946 }
947
948
949
950
951 func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, uint8, error) {
952
953
954
955
956 const (
957 AMD64 = uint32(sys.AMD64)
958 ARM = uint32(sys.ARM)
959 ARM64 = uint32(sys.ARM64)
960 I386 = uint32(sys.I386)
961 MIPS = uint32(sys.MIPS)
962 MIPS64 = uint32(sys.MIPS64)
963 PPC64 = uint32(sys.PPC64)
964 RISCV64 = uint32(sys.RISCV64)
965 S390X = uint32(sys.S390X)
966 )
967
968 switch uint32(arch.Family) | elftype<<16 {
969 default:
970 return 0, 0, fmt.Errorf("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
971
972 case MIPS | uint32(elf.R_MIPS_HI16)<<16,
973 MIPS | uint32(elf.R_MIPS_LO16)<<16,
974 MIPS | uint32(elf.R_MIPS_GOT16)<<16,
975 MIPS | uint32(elf.R_MIPS_GOT_HI16)<<16,
976 MIPS | uint32(elf.R_MIPS_GOT_LO16)<<16,
977 MIPS | uint32(elf.R_MIPS_GPREL16)<<16,
978 MIPS | uint32(elf.R_MIPS_GOT_PAGE)<<16,
979 MIPS | uint32(elf.R_MIPS_JALR)<<16,
980 MIPS | uint32(elf.R_MIPS_GOT_OFST)<<16,
981 MIPS64 | uint32(elf.R_MIPS_HI16)<<16,
982 MIPS64 | uint32(elf.R_MIPS_LO16)<<16,
983 MIPS64 | uint32(elf.R_MIPS_GOT16)<<16,
984 MIPS64 | uint32(elf.R_MIPS_GOT_HI16)<<16,
985 MIPS64 | uint32(elf.R_MIPS_GOT_LO16)<<16,
986 MIPS64 | uint32(elf.R_MIPS_GPREL16)<<16,
987 MIPS64 | uint32(elf.R_MIPS_GOT_PAGE)<<16,
988 MIPS64 | uint32(elf.R_MIPS_JALR)<<16,
989 MIPS64 | uint32(elf.R_MIPS_GOT_OFST)<<16,
990 MIPS64 | uint32(elf.R_MIPS_CALL16)<<16,
991 MIPS64 | uint32(elf.R_MIPS_GPREL32)<<16,
992 MIPS64 | uint32(elf.R_MIPS_64)<<16,
993 MIPS64 | uint32(elf.R_MIPS_GOT_DISP)<<16:
994 return 4, 4, nil
995
996 case S390X | uint32(elf.R_390_8)<<16:
997 return 1, 1, nil
998
999 case PPC64 | uint32(elf.R_PPC64_TOC16)<<16,
1000 S390X | uint32(elf.R_390_16)<<16,
1001 S390X | uint32(elf.R_390_GOT16)<<16,
1002 S390X | uint32(elf.R_390_PC16)<<16,
1003 S390X | uint32(elf.R_390_PC16DBL)<<16,
1004 S390X | uint32(elf.R_390_PLT16DBL)<<16:
1005 return 2, 2, nil
1006
1007 case ARM | uint32(elf.R_ARM_ABS32)<<16,
1008 ARM | uint32(elf.R_ARM_GOT32)<<16,
1009 ARM | uint32(elf.R_ARM_PLT32)<<16,
1010 ARM | uint32(elf.R_ARM_GOTOFF)<<16,
1011 ARM | uint32(elf.R_ARM_GOTPC)<<16,
1012 ARM | uint32(elf.R_ARM_THM_PC22)<<16,
1013 ARM | uint32(elf.R_ARM_REL32)<<16,
1014 ARM | uint32(elf.R_ARM_CALL)<<16,
1015 ARM | uint32(elf.R_ARM_V4BX)<<16,
1016 ARM | uint32(elf.R_ARM_GOT_PREL)<<16,
1017 ARM | uint32(elf.R_ARM_PC24)<<16,
1018 ARM | uint32(elf.R_ARM_JUMP24)<<16,
1019 ARM64 | uint32(elf.R_AARCH64_CALL26)<<16,
1020 ARM64 | uint32(elf.R_AARCH64_ADR_GOT_PAGE)<<16,
1021 ARM64 | uint32(elf.R_AARCH64_LD64_GOT_LO12_NC)<<16,
1022 ARM64 | uint32(elf.R_AARCH64_ADR_PREL_PG_HI21)<<16,
1023 ARM64 | uint32(elf.R_AARCH64_ADD_ABS_LO12_NC)<<16,
1024 ARM64 | uint32(elf.R_AARCH64_LDST8_ABS_LO12_NC)<<16,
1025 ARM64 | uint32(elf.R_AARCH64_LDST16_ABS_LO12_NC)<<16,
1026 ARM64 | uint32(elf.R_AARCH64_LDST32_ABS_LO12_NC)<<16,
1027 ARM64 | uint32(elf.R_AARCH64_LDST64_ABS_LO12_NC)<<16,
1028 ARM64 | uint32(elf.R_AARCH64_LDST128_ABS_LO12_NC)<<16,
1029 ARM64 | uint32(elf.R_AARCH64_PREL32)<<16,
1030 ARM64 | uint32(elf.R_AARCH64_JUMP26)<<16,
1031 AMD64 | uint32(elf.R_X86_64_PC32)<<16,
1032 AMD64 | uint32(elf.R_X86_64_PLT32)<<16,
1033 AMD64 | uint32(elf.R_X86_64_GOTPCREL)<<16,
1034 AMD64 | uint32(elf.R_X86_64_GOTPCRELX)<<16,
1035 AMD64 | uint32(elf.R_X86_64_REX_GOTPCRELX)<<16,
1036 I386 | uint32(elf.R_386_32)<<16,
1037 I386 | uint32(elf.R_386_PC32)<<16,
1038 I386 | uint32(elf.R_386_GOT32)<<16,
1039 I386 | uint32(elf.R_386_PLT32)<<16,
1040 I386 | uint32(elf.R_386_GOTOFF)<<16,
1041 I386 | uint32(elf.R_386_GOTPC)<<16,
1042 I386 | uint32(elf.R_386_GOT32X)<<16,
1043 PPC64 | uint32(elf.R_PPC64_REL24)<<16,
1044 PPC64 | uint32(elf.R_PPC_REL32)<<16,
1045 S390X | uint32(elf.R_390_32)<<16,
1046 S390X | uint32(elf.R_390_PC32)<<16,
1047 S390X | uint32(elf.R_390_GOT32)<<16,
1048 S390X | uint32(elf.R_390_PLT32)<<16,
1049 S390X | uint32(elf.R_390_PC32DBL)<<16,
1050 S390X | uint32(elf.R_390_PLT32DBL)<<16,
1051 S390X | uint32(elf.R_390_GOTPCDBL)<<16,
1052 S390X | uint32(elf.R_390_GOTENT)<<16:
1053 return 4, 4, nil
1054
1055 case AMD64 | uint32(elf.R_X86_64_64)<<16,
1056 AMD64 | uint32(elf.R_X86_64_PC64)<<16,
1057 ARM64 | uint32(elf.R_AARCH64_ABS64)<<16,
1058 ARM64 | uint32(elf.R_AARCH64_PREL64)<<16,
1059 PPC64 | uint32(elf.R_PPC64_ADDR64)<<16,
1060 S390X | uint32(elf.R_390_GLOB_DAT)<<16,
1061 S390X | uint32(elf.R_390_RELATIVE)<<16,
1062 S390X | uint32(elf.R_390_GOTOFF)<<16,
1063 S390X | uint32(elf.R_390_GOTPC)<<16,
1064 S390X | uint32(elf.R_390_64)<<16,
1065 S390X | uint32(elf.R_390_PC64)<<16,
1066 S390X | uint32(elf.R_390_GOT64)<<16,
1067 S390X | uint32(elf.R_390_PLT64)<<16:
1068 return 8, 8, nil
1069
1070 case RISCV64 | uint32(elf.R_RISCV_RVC_BRANCH)<<16,
1071 RISCV64 | uint32(elf.R_RISCV_RVC_JUMP)<<16:
1072 return 2, 2, nil
1073
1074 case RISCV64 | uint32(elf.R_RISCV_32)<<16,
1075 RISCV64 | uint32(elf.R_RISCV_BRANCH)<<16,
1076 RISCV64 | uint32(elf.R_RISCV_HI20)<<16,
1077 RISCV64 | uint32(elf.R_RISCV_LO12_I)<<16,
1078 RISCV64 | uint32(elf.R_RISCV_LO12_S)<<16,
1079 RISCV64 | uint32(elf.R_RISCV_GOT_HI20)<<16,
1080 RISCV64 | uint32(elf.R_RISCV_PCREL_HI20)<<16,
1081 RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_I)<<16,
1082 RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_S)<<16,
1083 RISCV64 | uint32(elf.R_RISCV_RELAX)<<16:
1084 return 4, 4, nil
1085
1086 case RISCV64 | uint32(elf.R_RISCV_64)<<16,
1087 RISCV64 | uint32(elf.R_RISCV_CALL)<<16,
1088 RISCV64 | uint32(elf.R_RISCV_CALL_PLT)<<16:
1089 return 8, 8, nil
1090
1091 case PPC64 | uint32(elf.R_PPC64_TOC16_LO)<<16,
1092 PPC64 | uint32(elf.R_PPC64_TOC16_HI)<<16,
1093 PPC64 | uint32(elf.R_PPC64_TOC16_HA)<<16,
1094 PPC64 | uint32(elf.R_PPC64_TOC16_DS)<<16,
1095 PPC64 | uint32(elf.R_PPC64_TOC16_LO_DS)<<16,
1096 PPC64 | uint32(elf.R_PPC64_REL16_LO)<<16,
1097 PPC64 | uint32(elf.R_PPC64_REL16_HI)<<16,
1098 PPC64 | uint32(elf.R_PPC64_REL16_HA)<<16:
1099 return 2, 4, nil
1100 }
1101 }
1102
1103 func cstring(x []byte) string {
1104 i := bytes.IndexByte(x, '\x00')
1105 if i >= 0 {
1106 x = x[:i]
1107 }
1108 return string(x)
1109 }
1110
View as plain text