Source file src/pkg/cmd/link/internal/loadelf/ldelf.go
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/sym"
14 "debug/elf"
15 "encoding/binary"
16 "fmt"
17 "io"
18 "log"
19 "sort"
20 "strings"
21 )
22
23
49 const (
50 ElfClassNone = 0
51 ElfClass32 = 1
52 ElfClass64 = 2
53 )
54
55 const (
56 ElfDataNone = 0
57 ElfDataLsb = 1
58 ElfDataMsb = 2
59 )
60
61 const (
62 ElfTypeNone = 0
63 ElfTypeRelocatable = 1
64 ElfTypeExecutable = 2
65 ElfTypeSharedObject = 3
66 ElfTypeCore = 4
67 )
68
69 const (
70 ElfMachNone = 0
71 ElfMach32100 = 1
72 ElfMachSparc = 2
73 ElfMach386 = 3
74 ElfMach68000 = 4
75 ElfMach88000 = 5
76 ElfMach486 = 6
77 ElfMach860 = 7
78 ElfMachMips = 8
79 ElfMachS370 = 9
80 ElfMachMipsLe = 10
81 ElfMachParisc = 15
82 ElfMachVpp500 = 17
83 ElfMachSparc32Plus = 18
84 ElfMach960 = 19
85 ElfMachPower = 20
86 ElfMachPower64 = 21
87 ElfMachS390 = 22
88 ElfMachV800 = 36
89 ElfMachFr20 = 37
90 ElfMachRh32 = 38
91 ElfMachRce = 39
92 ElfMachArm = 40
93 ElfMachAlpha = 41
94 ElfMachSH = 42
95 ElfMachSparc9 = 43
96 ElfMachAmd64 = 62
97 ElfMachArm64 = 183
98 )
99
100 const (
101 ElfAbiNone = 0
102 ElfAbiSystemV = 0
103 ElfAbiHPUX = 1
104 ElfAbiNetBSD = 2
105 ElfAbiLinux = 3
106 ElfAbiSolaris = 6
107 ElfAbiAix = 7
108 ElfAbiIrix = 8
109 ElfAbiFreeBSD = 9
110 ElfAbiTru64 = 10
111 ElfAbiModesto = 11
112 ElfAbiOpenBSD = 12
113 ElfAbiARM = 97
114 ElfAbiEmbedded = 255
115 )
116
117 const (
118 ElfSectNone = 0
119 ElfSectProgbits = 1
120 ElfSectSymtab = 2
121 ElfSectStrtab = 3
122 ElfSectRela = 4
123 ElfSectHash = 5
124 ElfSectDynamic = 6
125 ElfSectNote = 7
126 ElfSectNobits = 8
127 ElfSectRel = 9
128 ElfSectShlib = 10
129 ElfSectDynsym = 11
130 ElfSectFlagWrite = 0x1
131 ElfSectFlagAlloc = 0x2
132 ElfSectFlagExec = 0x4
133 )
134
135 const (
136 ElfSymBindLocal = 0
137 ElfSymBindGlobal = 1
138 ElfSymBindWeak = 2
139 )
140
141 const (
142 ElfSymTypeNone = 0
143 ElfSymTypeObject = 1
144 ElfSymTypeFunc = 2
145 ElfSymTypeSection = 3
146 ElfSymTypeFile = 4
147 ElfSymTypeCommon = 5
148 ElfSymTypeTLS = 6
149 )
150
151 const (
152 ElfSymShnNone = 0
153 ElfSymShnAbs = 0xFFF1
154 ElfSymShnCommon = 0xFFF2
155 )
156
157 const (
158 ElfProgNone = 0
159 ElfProgLoad = 1
160 ElfProgDynamic = 2
161 ElfProgInterp = 3
162 ElfProgNote = 4
163 ElfProgShlib = 5
164 ElfProgPhdr = 6
165 ElfProgFlagExec = 0x1
166 ElfProgFlagWrite = 0x2
167 ElfProgFlagRead = 0x4
168 )
169
170 const (
171 ElfNotePrStatus = 1
172 ElfNotePrFpreg = 2
173 ElfNotePrPsinfo = 3
174 ElfNotePrTaskstruct = 4
175 ElfNotePrAuxv = 6
176 ElfNotePrXfpreg = 0x46e62b7f
177 )
178
179
180 const (
181 ELF64SYMSIZE = 24
182 ELF32SYMSIZE = 16
183
184 SHT_ARM_ATTRIBUTES = 0x70000003
185 )
186
187 type ElfHdrBytes struct {
188 Ident [16]uint8
189 Type [2]uint8
190 Machine [2]uint8
191 Version [4]uint8
192 Entry [4]uint8
193 Phoff [4]uint8
194 Shoff [4]uint8
195 Flags [4]uint8
196 Ehsize [2]uint8
197 Phentsize [2]uint8
198 Phnum [2]uint8
199 Shentsize [2]uint8
200 Shnum [2]uint8
201 Shstrndx [2]uint8
202 }
203
204 type ElfSectBytes struct {
205 Name [4]uint8
206 Type [4]uint8
207 Flags [4]uint8
208 Addr [4]uint8
209 Off [4]uint8
210 Size [4]uint8
211 Link [4]uint8
212 Info [4]uint8
213 Align [4]uint8
214 Entsize [4]uint8
215 }
216
217 type ElfProgBytes struct {
218 }
219
220 type ElfSymBytes struct {
221 Name [4]uint8
222 Value [4]uint8
223 Size [4]uint8
224 Info uint8
225 Other uint8
226 Shndx [2]uint8
227 }
228
229 type ElfHdrBytes64 struct {
230 Ident [16]uint8
231 Type [2]uint8
232 Machine [2]uint8
233 Version [4]uint8
234 Entry [8]uint8
235 Phoff [8]uint8
236 Shoff [8]uint8
237 Flags [4]uint8
238 Ehsize [2]uint8
239 Phentsize [2]uint8
240 Phnum [2]uint8
241 Shentsize [2]uint8
242 Shnum [2]uint8
243 Shstrndx [2]uint8
244 }
245
246 type ElfSectBytes64 struct {
247 Name [4]uint8
248 Type [4]uint8
249 Flags [8]uint8
250 Addr [8]uint8
251 Off [8]uint8
252 Size [8]uint8
253 Link [4]uint8
254 Info [4]uint8
255 Align [8]uint8
256 Entsize [8]uint8
257 }
258
259 type ElfProgBytes64 struct {
260 }
261
262 type ElfSymBytes64 struct {
263 Name [4]uint8
264 Info uint8
265 Other uint8
266 Shndx [2]uint8
267 Value [8]uint8
268 Size [8]uint8
269 }
270
271 type ElfSect struct {
272 name string
273 nameoff uint32
274 type_ uint32
275 flags uint64
276 addr uint64
277 off uint64
278 size uint64
279 link uint32
280 info uint32
281 align uint64
282 entsize uint64
283 base []byte
284 sym *sym.Symbol
285 }
286
287 type ElfObj struct {
288 f *bio.Reader
289 base int64
290 length int64
291 is64 int
292 name string
293 e binary.ByteOrder
294 sect []ElfSect
295 nsect uint
296 nsymtab int
297 symtab *ElfSect
298 symstr *ElfSect
299 type_ uint32
300 machine uint32
301 version uint32
302 entry uint64
303 phoff uint64
304 shoff uint64
305 flags uint32
306 ehsize uint32
307 phentsize uint32
308 phnum uint32
309 shentsize uint32
310 shnum uint32
311 shstrndx uint32
312 }
313
314 type ElfSym struct {
315 name string
316 value uint64
317 size uint64
318 bind uint8
319 type_ uint8
320 other uint8
321 shndx uint16
322 sym *sym.Symbol
323 }
324
325 var ElfMagic = [4]uint8{0x7F, 'E', 'L', 'F'}
326
327 const (
328 TagFile = 1
329 TagCPUName = 4
330 TagCPURawName = 5
331 TagCompatibility = 32
332 TagNoDefaults = 64
333 TagAlsoCompatibleWith = 65
334 TagABIVFPArgs = 28
335 )
336
337 type elfAttribute struct {
338 tag uint64
339 sval string
340 ival uint64
341 }
342
343 type elfAttributeList struct {
344 data []byte
345 err error
346 }
347
348 func (a *elfAttributeList) string() string {
349 if a.err != nil {
350 return ""
351 }
352 nul := bytes.IndexByte(a.data, 0)
353 if nul < 0 {
354 a.err = io.EOF
355 return ""
356 }
357 s := string(a.data[:nul])
358 a.data = a.data[nul+1:]
359 return s
360 }
361
362 func (a *elfAttributeList) uleb128() uint64 {
363 if a.err != nil {
364 return 0
365 }
366 v, size := binary.Uvarint(a.data)
367 a.data = a.data[size:]
368 return v
369 }
370
371
372 func (a *elfAttributeList) armAttr() elfAttribute {
373 attr := elfAttribute{tag: a.uleb128()}
374 switch {
375 case attr.tag == TagCompatibility:
376 attr.ival = a.uleb128()
377 attr.sval = a.string()
378
379 case attr.tag == 64:
380
381 case attr.tag == 65:
382
383 attr.sval = a.string()
384
385
386 case attr.tag == TagCPUName || attr.tag == TagCPURawName || (attr.tag >= 32 && attr.tag&1 != 0):
387 attr.sval = a.string()
388
389 default:
390 attr.ival = a.uleb128()
391 }
392 return attr
393 }
394
395 func (a *elfAttributeList) done() bool {
396 if a.err != nil || len(a.data) == 0 {
397 return true
398 }
399 return false
400 }
401
402
403
404
405
406
407
408 func parseArmAttributes(e binary.ByteOrder, data []byte) (found bool, ehdrFlags uint32, err error) {
409 found = false
410 if data[0] != 'A' {
411 return false, 0, fmt.Errorf(".ARM.attributes has unexpected format %c\n", data[0])
412 }
413 data = data[1:]
414 for len(data) != 0 {
415 sectionlength := e.Uint32(data)
416 sectiondata := data[4:sectionlength]
417 data = data[sectionlength:]
418
419 nulIndex := bytes.IndexByte(sectiondata, 0)
420 if nulIndex < 0 {
421 return false, 0, fmt.Errorf("corrupt .ARM.attributes (section name not NUL-terminated)\n")
422 }
423 name := string(sectiondata[:nulIndex])
424 sectiondata = sectiondata[nulIndex+1:]
425
426 if name != "aeabi" {
427 continue
428 }
429 for len(sectiondata) != 0 {
430 subsectiontag, sz := binary.Uvarint(sectiondata)
431 subsectionsize := e.Uint32(sectiondata[sz:])
432 subsectiondata := sectiondata[sz+4 : subsectionsize]
433 sectiondata = sectiondata[subsectionsize:]
434
435 if subsectiontag != TagFile {
436 continue
437 }
438 attrList := elfAttributeList{data: subsectiondata}
439 for !attrList.done() {
440 attr := attrList.armAttr()
441 if attr.tag == TagABIVFPArgs && attr.ival == 1 {
442 found = true
443 ehdrFlags = 0x5000402
444 }
445 }
446 if attrList.err != nil {
447 return false, 0, fmt.Errorf("could not parse .ARM.attributes\n")
448 }
449 }
450 }
451 return found, ehdrFlags, nil
452 }
453
454
455
456
457
458
459
460
461
462 func Load(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length int64, pn string, initEhdrFlags uint32) (textp []*sym.Symbol, ehdrFlags uint32, err error) {
463 errorf := func(str string, args ...interface{}) ([]*sym.Symbol, uint32, error) {
464 return nil, 0, fmt.Errorf("loadelf: %s: %v", pn, fmt.Sprintf(str, args...))
465 }
466
467 localSymVersion := syms.IncVersion()
468 base := f.Offset()
469
470 var hdrbuf [64]uint8
471 if _, err := io.ReadFull(f, hdrbuf[:]); err != nil {
472 return errorf("malformed elf file: %v", err)
473 }
474 hdr := new(ElfHdrBytes)
475 binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr)
476 if string(hdr.Ident[:4]) != "\x7FELF" {
477 return errorf("malformed elf file, bad header")
478 }
479 var e binary.ByteOrder
480 switch hdr.Ident[5] {
481 case ElfDataLsb:
482 e = binary.LittleEndian
483
484 case ElfDataMsb:
485 e = binary.BigEndian
486
487 default:
488 return errorf("malformed elf file, unknown header")
489 }
490
491
492 elfobj := new(ElfObj)
493
494 elfobj.e = e
495 elfobj.f = f
496 elfobj.base = base
497 elfobj.length = length
498 elfobj.name = pn
499
500 is64 := 0
501 if hdr.Ident[4] == ElfClass64 {
502 is64 = 1
503 hdr := new(ElfHdrBytes64)
504 binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr)
505 elfobj.type_ = uint32(e.Uint16(hdr.Type[:]))
506 elfobj.machine = uint32(e.Uint16(hdr.Machine[:]))
507 elfobj.version = e.Uint32(hdr.Version[:])
508 elfobj.phoff = e.Uint64(hdr.Phoff[:])
509 elfobj.shoff = e.Uint64(hdr.Shoff[:])
510 elfobj.flags = e.Uint32(hdr.Flags[:])
511 elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:]))
512 elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:]))
513 elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:]))
514 elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:]))
515 elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:]))
516 elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:]))
517 } else {
518 elfobj.type_ = uint32(e.Uint16(hdr.Type[:]))
519 elfobj.machine = uint32(e.Uint16(hdr.Machine[:]))
520 elfobj.version = e.Uint32(hdr.Version[:])
521 elfobj.entry = uint64(e.Uint32(hdr.Entry[:]))
522 elfobj.phoff = uint64(e.Uint32(hdr.Phoff[:]))
523 elfobj.shoff = uint64(e.Uint32(hdr.Shoff[:]))
524 elfobj.flags = e.Uint32(hdr.Flags[:])
525 elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:]))
526 elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:]))
527 elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:]))
528 elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:]))
529 elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:]))
530 elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:]))
531 }
532
533 elfobj.is64 = is64
534
535 if v := uint32(hdr.Ident[6]); v != elfobj.version {
536 return errorf("malformed elf version: got %d, want %d", v, elfobj.version)
537 }
538
539 if e.Uint16(hdr.Type[:]) != ElfTypeRelocatable {
540 return errorf("elf but not elf relocatable object")
541 }
542
543 switch arch.Family {
544 default:
545 return errorf("elf %s unimplemented", arch.Name)
546
547 case sys.MIPS:
548 if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass32 {
549 return errorf("elf object but not mips")
550 }
551
552 case sys.MIPS64:
553 if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass64 {
554 return errorf("elf object but not mips64")
555 }
556
557 case sys.ARM:
558 if e != binary.LittleEndian || elfobj.machine != ElfMachArm || hdr.Ident[4] != ElfClass32 {
559 return errorf("elf object but not arm")
560 }
561
562 case sys.AMD64:
563 if e != binary.LittleEndian || elfobj.machine != ElfMachAmd64 || hdr.Ident[4] != ElfClass64 {
564 return errorf("elf object but not amd64")
565 }
566
567 case sys.ARM64:
568 if e != binary.LittleEndian || elfobj.machine != ElfMachArm64 || hdr.Ident[4] != ElfClass64 {
569 return errorf("elf object but not arm64")
570 }
571
572 case sys.I386:
573 if e != binary.LittleEndian || elfobj.machine != ElfMach386 || hdr.Ident[4] != ElfClass32 {
574 return errorf("elf object but not 386")
575 }
576
577 case sys.PPC64:
578 if elfobj.machine != ElfMachPower64 || hdr.Ident[4] != ElfClass64 {
579 return errorf("elf object but not ppc64")
580 }
581
582 case sys.S390X:
583 if elfobj.machine != ElfMachS390 || hdr.Ident[4] != ElfClass64 {
584 return errorf("elf object but not s390x")
585 }
586 }
587
588
589 elfobj.sect = make([]ElfSect, elfobj.shnum)
590
591 elfobj.nsect = uint(elfobj.shnum)
592 for i := 0; uint(i) < elfobj.nsect; i++ {
593 f.MustSeek(int64(uint64(base)+elfobj.shoff+uint64(int64(i)*int64(elfobj.shentsize))), 0)
594 sect := &elfobj.sect[i]
595 if is64 != 0 {
596 var b ElfSectBytes64
597
598 if err := binary.Read(f, e, &b); err != nil {
599 return errorf("malformed elf file: %v", err)
600 }
601
602 sect.nameoff = e.Uint32(b.Name[:])
603 sect.type_ = e.Uint32(b.Type[:])
604 sect.flags = e.Uint64(b.Flags[:])
605 sect.addr = e.Uint64(b.Addr[:])
606 sect.off = e.Uint64(b.Off[:])
607 sect.size = e.Uint64(b.Size[:])
608 sect.link = e.Uint32(b.Link[:])
609 sect.info = e.Uint32(b.Info[:])
610 sect.align = e.Uint64(b.Align[:])
611 sect.entsize = e.Uint64(b.Entsize[:])
612 } else {
613 var b ElfSectBytes
614
615 if err := binary.Read(f, e, &b); err != nil {
616 return errorf("malformed elf file: %v", err)
617 }
618
619 sect.nameoff = e.Uint32(b.Name[:])
620 sect.type_ = e.Uint32(b.Type[:])
621 sect.flags = uint64(e.Uint32(b.Flags[:]))
622 sect.addr = uint64(e.Uint32(b.Addr[:]))
623 sect.off = uint64(e.Uint32(b.Off[:]))
624 sect.size = uint64(e.Uint32(b.Size[:]))
625 sect.link = e.Uint32(b.Link[:])
626 sect.info = e.Uint32(b.Info[:])
627 sect.align = uint64(e.Uint32(b.Align[:]))
628 sect.entsize = uint64(e.Uint32(b.Entsize[:]))
629 }
630 }
631
632
633 if elfobj.shstrndx >= uint32(elfobj.nsect) {
634 return errorf("malformed elf file: shstrndx out of range %d >= %d", elfobj.shstrndx, elfobj.nsect)
635 }
636
637 sect := &elfobj.sect[elfobj.shstrndx]
638 if err := elfmap(elfobj, sect); err != nil {
639 return errorf("malformed elf file: %v", err)
640 }
641 for i := 0; uint(i) < elfobj.nsect; i++ {
642 if elfobj.sect[i].nameoff != 0 {
643 elfobj.sect[i].name = cstring(sect.base[elfobj.sect[i].nameoff:])
644 }
645 }
646
647
648 elfobj.symtab = section(elfobj, ".symtab")
649
650 if elfobj.symtab == nil {
651
652 return
653 }
654
655 if elfobj.symtab.link <= 0 || elfobj.symtab.link >= uint32(elfobj.nsect) {
656 return errorf("elf object has symbol table with invalid string table link")
657 }
658
659 elfobj.symstr = &elfobj.sect[elfobj.symtab.link]
660 if is64 != 0 {
661 elfobj.nsymtab = int(elfobj.symtab.size / ELF64SYMSIZE)
662 } else {
663 elfobj.nsymtab = int(elfobj.symtab.size / ELF32SYMSIZE)
664 }
665
666 if err := elfmap(elfobj, elfobj.symtab); err != nil {
667 return errorf("malformed elf file: %v", err)
668 }
669 if err := elfmap(elfobj, elfobj.symstr); err != nil {
670 return errorf("malformed elf file: %v", err)
671 }
672
673
674
675
676
677
678
679 sectsymNames := make(map[string]bool)
680 counter := 0
681 for i := 0; uint(i) < elfobj.nsect; i++ {
682 sect = &elfobj.sect[i]
683 if sect.type_ == SHT_ARM_ATTRIBUTES && sect.name == ".ARM.attributes" {
684 if err := elfmap(elfobj, sect); err != nil {
685 return errorf("%s: malformed elf file: %v", pn, err)
686 }
687
688 if initEhdrFlags == 0x5000002 {
689 ehdrFlags = 0x5000202
690 } else {
691 ehdrFlags = initEhdrFlags
692 }
693 found, newEhdrFlags, err := parseArmAttributes(e, sect.base[:sect.size])
694 if err != nil {
695
696 log.Printf("%s: %v", pn, err)
697 }
698 if found {
699 ehdrFlags = newEhdrFlags
700 }
701 }
702 if (sect.type_ != ElfSectProgbits && sect.type_ != ElfSectNobits) || sect.flags&ElfSectFlagAlloc == 0 {
703 continue
704 }
705 if sect.type_ != ElfSectNobits {
706 if err := elfmap(elfobj, sect); err != nil {
707 return errorf("%s: malformed elf file: %v", pn, err)
708 }
709 }
710
711 name := fmt.Sprintf("%s(%s)", pkg, sect.name)
712 for sectsymNames[name] {
713 counter++
714 name = fmt.Sprintf("%s(%s%d)", pkg, sect.name, counter)
715 }
716 sectsymNames[name] = true
717
718 s := syms.Lookup(name, localSymVersion)
719
720 switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) {
721 default:
722 return errorf("%s: unexpected flags for ELF section %s", pn, sect.name)
723
724 case ElfSectFlagAlloc:
725 s.Type = sym.SRODATA
726
727 case ElfSectFlagAlloc + ElfSectFlagWrite:
728 if sect.type_ == ElfSectNobits {
729 s.Type = sym.SNOPTRBSS
730 } else {
731 s.Type = sym.SNOPTRDATA
732 }
733
734 case ElfSectFlagAlloc + ElfSectFlagExec:
735 s.Type = sym.STEXT
736 }
737
738 if sect.name == ".got" || sect.name == ".toc" {
739 s.Type = sym.SELFGOT
740 }
741 if sect.type_ == ElfSectProgbits {
742 s.P = sect.base
743 s.P = s.P[:sect.size]
744 }
745
746 s.Size = int64(sect.size)
747 s.Align = int32(sect.align)
748 sect.sym = s
749 }
750
751
752
753 symbols := make([]*sym.Symbol, elfobj.nsymtab)
754
755 for i := 1; i < elfobj.nsymtab; i++ {
756 var elfsym ElfSym
757 if err := readelfsym(arch, syms, elfobj, i, &elfsym, 1, localSymVersion); err != nil {
758 return errorf("%s: malformed elf file: %v", pn, err)
759 }
760 symbols[i] = elfsym.sym
761 if elfsym.type_ != ElfSymTypeFunc && elfsym.type_ != ElfSymTypeObject && elfsym.type_ != ElfSymTypeNone && elfsym.type_ != ElfSymTypeCommon {
762 continue
763 }
764 if elfsym.shndx == ElfSymShnCommon || elfsym.type_ == ElfSymTypeCommon {
765 s := elfsym.sym
766 if uint64(s.Size) < elfsym.size {
767 s.Size = int64(elfsym.size)
768 }
769 if s.Type == 0 || s.Type == sym.SXREF {
770 s.Type = sym.SNOPTRBSS
771 }
772 continue
773 }
774
775 if uint(elfsym.shndx) >= elfobj.nsect || elfsym.shndx == 0 {
776 continue
777 }
778
779
780 if elfsym.sym == nil {
781 continue
782 }
783 sect = &elfobj.sect[elfsym.shndx]
784 if sect.sym == nil {
785 if strings.HasPrefix(elfsym.name, ".Linfo_string") {
786 continue
787 }
788
789 if elfsym.name == "" && elfsym.type_ == 0 && sect.name == ".debug_str" {
790
791
792 continue
793 }
794
795 if strings.HasPrefix(elfsym.name, "$d") && elfsym.type_ == 0 && sect.name == ".debug_frame" {
796
797
798
799 continue
800 }
801
802 if strings.HasPrefix(elfsym.name, ".LASF") {
803 continue
804 }
805 return errorf("%v: sym#%d: ignoring symbol in section %d (type %d)", elfsym.sym, i, elfsym.shndx, elfsym.type_)
806 }
807
808 s := elfsym.sym
809 if s.Outer != nil {
810 if s.Attr.DuplicateOK() {
811 continue
812 }
813 return errorf("duplicate symbol reference: %s in both %s and %s", s.Name, s.Outer.Name, sect.sym.Name)
814 }
815
816 s.Sub = sect.sym.Sub
817 sect.sym.Sub = s
818 s.Type = sect.sym.Type
819 s.Attr |= sym.AttrSubSymbol
820 if !s.Attr.CgoExportDynamic() {
821 s.SetDynimplib("")
822 }
823 s.Value = int64(elfsym.value)
824 s.Size = int64(elfsym.size)
825 s.Outer = sect.sym
826 if sect.sym.Type == sym.STEXT {
827 if s.Attr.External() && !s.Attr.DuplicateOK() {
828 return errorf("%v: duplicate symbol definition", s)
829 }
830 s.Attr |= sym.AttrExternal
831 }
832
833 if elfobj.machine == ElfMachPower64 {
834 flag := int(elfsym.other) >> 5
835 if 2 <= flag && flag <= 6 {
836 s.SetLocalentry(1 << uint(flag-2))
837 } else if flag == 7 {
838 return errorf("%v: invalid sym.other 0x%x", s, elfsym.other)
839 }
840 }
841 }
842
843
844
845 for i := uint(0); i < elfobj.nsect; i++ {
846 s := elfobj.sect[i].sym
847 if s == nil {
848 continue
849 }
850 if s.Sub != nil {
851 s.Sub = sym.SortSub(s.Sub)
852 }
853 if s.Type == sym.STEXT {
854 if s.Attr.OnList() {
855 return errorf("symbol %s listed multiple times", s.Name)
856 }
857 s.Attr |= sym.AttrOnList
858 textp = append(textp, s)
859 for s = s.Sub; s != nil; s = s.Sub {
860 if s.Attr.OnList() {
861 return errorf("symbol %s listed multiple times", s.Name)
862 }
863 s.Attr |= sym.AttrOnList
864 textp = append(textp, s)
865 }
866 }
867 }
868
869
870 for i := uint(0); i < elfobj.nsect; i++ {
871 rsect := &elfobj.sect[i]
872 if rsect.type_ != ElfSectRela && rsect.type_ != ElfSectRel {
873 continue
874 }
875 if rsect.info >= uint32(elfobj.nsect) || elfobj.sect[rsect.info].base == nil {
876 continue
877 }
878 sect = &elfobj.sect[rsect.info]
879 if err := elfmap(elfobj, rsect); err != nil {
880 return errorf("malformed elf file: %v", err)
881 }
882 rela := 0
883 if rsect.type_ == ElfSectRela {
884 rela = 1
885 }
886 n := int(rsect.size / uint64(4+4*is64) / uint64(2+rela))
887 r := make([]sym.Reloc, n)
888 p := rsect.base
889 for j := 0; j < n; j++ {
890 var add uint64
891 rp := &r[j]
892 var info uint64
893 if is64 != 0 {
894
895 rp.Off = int32(e.Uint64(p))
896
897 p = p[8:]
898 info = e.Uint64(p)
899 p = p[8:]
900 if rela != 0 {
901 add = e.Uint64(p)
902 p = p[8:]
903 }
904 } else {
905
906 rp.Off = int32(e.Uint32(p))
907
908 p = p[4:]
909 info = uint64(e.Uint32(p))
910 info = info>>8<<32 | info&0xff
911 p = p[4:]
912 if rela != 0 {
913 add = uint64(e.Uint32(p))
914 p = p[4:]
915 }
916 }
917
918 if info&0xffffffff == 0 {
919 j--
920 n--
921 continue
922 }
923
924 if info>>32 == 0 {
925 rp.Sym = nil
926 } else {
927 var elfsym ElfSym
928 if err := readelfsym(arch, syms, elfobj, int(info>>32), &elfsym, 0, 0); err != nil {
929 return errorf("malformed elf file: %v", err)
930 }
931 elfsym.sym = symbols[info>>32]
932 if elfsym.sym == nil {
933 return errorf("malformed elf file: %s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", sect.sym.Name, j, int(info>>32), elfsym.name, elfsym.shndx, elfsym.type_)
934 }
935
936 rp.Sym = elfsym.sym
937 }
938
939 rp.Type = objabi.ElfRelocOffset + objabi.RelocType(info)
940 rp.Siz, err = relSize(arch, pn, uint32(info))
941 if err != nil {
942 return nil, 0, err
943 }
944 if rela != 0 {
945 rp.Add = int64(add)
946 } else {
947
948 if rp.Siz == 4 {
949 rp.Add = int64(e.Uint32(sect.base[rp.Off:]))
950 } else if rp.Siz == 8 {
951 rp.Add = int64(e.Uint64(sect.base[rp.Off:]))
952 } else {
953 return errorf("invalid rela size %d", rp.Siz)
954 }
955 }
956
957 if rp.Siz == 2 {
958 rp.Add = int64(int16(rp.Add))
959 }
960 if rp.Siz == 4 {
961 rp.Add = int64(int32(rp.Add))
962 }
963 }
964
965
966 sort.Sort(sym.RelocByOff(r[:n]))
967
968
969 s := sect.sym
970 s.R = r
971 s.R = s.R[:n]
972 }
973
974 return textp, ehdrFlags, nil
975 }
976
977 func section(elfobj *ElfObj, name string) *ElfSect {
978 for i := 0; uint(i) < elfobj.nsect; i++ {
979 if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name {
980 return &elfobj.sect[i]
981 }
982 }
983 return nil
984 }
985
986 func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) {
987 if sect.base != nil {
988 return nil
989 }
990
991 if sect.off+sect.size > uint64(elfobj.length) {
992 err = fmt.Errorf("elf section past end of file")
993 return err
994 }
995
996 sect.base = make([]byte, sect.size)
997 elfobj.f.MustSeek(int64(uint64(elfobj.base)+sect.off), 0)
998 if _, err := io.ReadFull(elfobj.f, sect.base); err != nil {
999 return fmt.Errorf("short read: %v", err)
1000 }
1001
1002 return nil
1003 }
1004
1005 func readelfsym(arch *sys.Arch, syms *sym.Symbols, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, localSymVersion int) (err error) {
1006 if i >= elfobj.nsymtab || i < 0 {
1007 err = fmt.Errorf("invalid elf symbol index")
1008 return err
1009 }
1010
1011 if i == 0 {
1012 return fmt.Errorf("readym: read null symbol!")
1013 }
1014
1015 if elfobj.is64 != 0 {
1016 b := new(ElfSymBytes64)
1017 binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF64SYMSIZE:(i+1)*ELF64SYMSIZE]), elfobj.e, b)
1018 elfsym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
1019 elfsym.value = elfobj.e.Uint64(b.Value[:])
1020 elfsym.size = elfobj.e.Uint64(b.Size[:])
1021 elfsym.shndx = elfobj.e.Uint16(b.Shndx[:])
1022 elfsym.bind = b.Info >> 4
1023 elfsym.type_ = b.Info & 0xf
1024 elfsym.other = b.Other
1025 } else {
1026 b := new(ElfSymBytes)
1027 binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF32SYMSIZE:(i+1)*ELF32SYMSIZE]), elfobj.e, b)
1028 elfsym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
1029 elfsym.value = uint64(elfobj.e.Uint32(b.Value[:]))
1030 elfsym.size = uint64(elfobj.e.Uint32(b.Size[:]))
1031 elfsym.shndx = elfobj.e.Uint16(b.Shndx[:])
1032 elfsym.bind = b.Info >> 4
1033 elfsym.type_ = b.Info & 0xf
1034 elfsym.other = b.Other
1035 }
1036
1037 var s *sym.Symbol
1038 if elfsym.name == "_GLOBAL_OFFSET_TABLE_" {
1039 elfsym.name = ".got"
1040 }
1041 if elfsym.name == ".TOC." {
1042
1043
1044 elfsym.bind = ElfSymBindLocal
1045 }
1046
1047 switch elfsym.type_ {
1048 case ElfSymTypeSection:
1049 s = elfobj.sect[elfsym.shndx].sym
1050
1051 case ElfSymTypeObject, ElfSymTypeFunc, ElfSymTypeNone, ElfSymTypeCommon:
1052 switch elfsym.bind {
1053 case ElfSymBindGlobal:
1054 if needSym != 0 {
1055 s = syms.Lookup(elfsym.name, 0)
1056
1057
1058
1059
1060
1061
1062
1063
1064 if s != nil && elfsym.other == 2 {
1065 s.Attr |= sym.AttrDuplicateOK | sym.AttrVisibilityHidden
1066 }
1067 }
1068
1069 case ElfSymBindLocal:
1070 if (arch.Family == sys.ARM || arch.Family == sys.ARM64) && (strings.HasPrefix(elfsym.name, "$a") || strings.HasPrefix(elfsym.name, "$d") || strings.HasPrefix(elfsym.name, "$x")) {
1071
1072
1073 break
1074 }
1075
1076 if elfsym.name == ".TOC." {
1077
1078
1079 if needSym != 0 {
1080 s = syms.Lookup(elfsym.name, localSymVersion)
1081 s.Attr |= sym.AttrVisibilityHidden
1082 }
1083
1084 break
1085 }
1086
1087 if needSym != 0 {
1088
1089
1090
1091 s = syms.Newsym(elfsym.name, localSymVersion)
1092
1093 s.Attr |= sym.AttrVisibilityHidden
1094 }
1095
1096 case ElfSymBindWeak:
1097 if needSym != 0 {
1098 s = syms.Lookup(elfsym.name, 0)
1099 if elfsym.other == 2 {
1100 s.Attr |= sym.AttrVisibilityHidden
1101 }
1102
1103
1104 if s.Outer != nil {
1105 s.Attr |= sym.AttrDuplicateOK
1106 }
1107 }
1108
1109 default:
1110 err = fmt.Errorf("%s: invalid symbol binding %d", elfsym.name, elfsym.bind)
1111 return err
1112 }
1113 }
1114
1115
1116
1117 if s != nil && s.Type == 0 && !s.Attr.VisibilityHidden() && elfsym.type_ != ElfSymTypeSection {
1118 s.Type = sym.SXREF
1119 }
1120 elfsym.sym = s
1121
1122 return nil
1123 }
1124
1125 func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) {
1126
1127
1128
1129
1130 const (
1131 AMD64 = uint32(sys.AMD64)
1132 ARM = uint32(sys.ARM)
1133 ARM64 = uint32(sys.ARM64)
1134 I386 = uint32(sys.I386)
1135 PPC64 = uint32(sys.PPC64)
1136 S390X = uint32(sys.S390X)
1137 )
1138
1139 switch uint32(arch.Family) | elftype<<16 {
1140 default:
1141 return 0, fmt.Errorf("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
1142
1143 case S390X | uint32(elf.R_390_8)<<16:
1144 return 1, nil
1145
1146 case PPC64 | uint32(elf.R_PPC64_TOC16)<<16,
1147 PPC64 | uint32(elf.R_PPC64_TOC16_LO)<<16,
1148 PPC64 | uint32(elf.R_PPC64_TOC16_HI)<<16,
1149 PPC64 | uint32(elf.R_PPC64_TOC16_HA)<<16,
1150 PPC64 | uint32(elf.R_PPC64_TOC16_DS)<<16,
1151 PPC64 | uint32(elf.R_PPC64_TOC16_LO_DS)<<16,
1152 PPC64 | uint32(elf.R_PPC64_REL16_LO)<<16,
1153 PPC64 | uint32(elf.R_PPC64_REL16_HI)<<16,
1154 PPC64 | uint32(elf.R_PPC64_REL16_HA)<<16,
1155 S390X | uint32(elf.R_390_16)<<16,
1156 S390X | uint32(elf.R_390_GOT16)<<16,
1157 S390X | uint32(elf.R_390_PC16)<<16,
1158 S390X | uint32(elf.R_390_PC16DBL)<<16,
1159 S390X | uint32(elf.R_390_PLT16DBL)<<16:
1160 return 2, nil
1161
1162 case ARM | uint32(elf.R_ARM_ABS32)<<16,
1163 ARM | uint32(elf.R_ARM_GOT32)<<16,
1164 ARM | uint32(elf.R_ARM_PLT32)<<16,
1165 ARM | uint32(elf.R_ARM_GOTOFF)<<16,
1166 ARM | uint32(elf.R_ARM_GOTPC)<<16,
1167 ARM | uint32(elf.R_ARM_THM_PC22)<<16,
1168 ARM | uint32(elf.R_ARM_REL32)<<16,
1169 ARM | uint32(elf.R_ARM_CALL)<<16,
1170 ARM | uint32(elf.R_ARM_V4BX)<<16,
1171 ARM | uint32(elf.R_ARM_GOT_PREL)<<16,
1172 ARM | uint32(elf.R_ARM_PC24)<<16,
1173 ARM | uint32(elf.R_ARM_JUMP24)<<16,
1174 ARM64 | uint32(elf.R_AARCH64_CALL26)<<16,
1175 ARM64 | uint32(elf.R_AARCH64_ADR_GOT_PAGE)<<16,
1176 ARM64 | uint32(elf.R_AARCH64_LD64_GOT_LO12_NC)<<16,
1177 ARM64 | uint32(elf.R_AARCH64_ADR_PREL_PG_HI21)<<16,
1178 ARM64 | uint32(elf.R_AARCH64_ADD_ABS_LO12_NC)<<16,
1179 ARM64 | uint32(elf.R_AARCH64_LDST8_ABS_LO12_NC)<<16,
1180 ARM64 | uint32(elf.R_AARCH64_LDST32_ABS_LO12_NC)<<16,
1181 ARM64 | uint32(elf.R_AARCH64_LDST64_ABS_LO12_NC)<<16,
1182 ARM64 | uint32(elf.R_AARCH64_LDST128_ABS_LO12_NC)<<16,
1183 ARM64 | uint32(elf.R_AARCH64_PREL32)<<16,
1184 ARM64 | uint32(elf.R_AARCH64_JUMP26)<<16,
1185 AMD64 | uint32(elf.R_X86_64_PC32)<<16,
1186 AMD64 | uint32(elf.R_X86_64_PLT32)<<16,
1187 AMD64 | uint32(elf.R_X86_64_GOTPCREL)<<16,
1188 AMD64 | uint32(elf.R_X86_64_GOTPCRELX)<<16,
1189 AMD64 | uint32(elf.R_X86_64_REX_GOTPCRELX)<<16,
1190 I386 | uint32(elf.R_386_32)<<16,
1191 I386 | uint32(elf.R_386_PC32)<<16,
1192 I386 | uint32(elf.R_386_GOT32)<<16,
1193 I386 | uint32(elf.R_386_PLT32)<<16,
1194 I386 | uint32(elf.R_386_GOTOFF)<<16,
1195 I386 | uint32(elf.R_386_GOTPC)<<16,
1196 I386 | uint32(elf.R_386_GOT32X)<<16,
1197 PPC64 | uint32(elf.R_PPC64_REL24)<<16,
1198 PPC64 | uint32(elf.R_PPC_REL32)<<16,
1199 S390X | uint32(elf.R_390_32)<<16,
1200 S390X | uint32(elf.R_390_PC32)<<16,
1201 S390X | uint32(elf.R_390_GOT32)<<16,
1202 S390X | uint32(elf.R_390_PLT32)<<16,
1203 S390X | uint32(elf.R_390_PC32DBL)<<16,
1204 S390X | uint32(elf.R_390_PLT32DBL)<<16,
1205 S390X | uint32(elf.R_390_GOTPCDBL)<<16,
1206 S390X | uint32(elf.R_390_GOTENT)<<16:
1207 return 4, nil
1208
1209 case AMD64 | uint32(elf.R_X86_64_64)<<16,
1210 AMD64 | uint32(elf.R_X86_64_PC64)<<16,
1211 ARM64 | uint32(elf.R_AARCH64_ABS64)<<16,
1212 ARM64 | uint32(elf.R_AARCH64_PREL64)<<16,
1213 PPC64 | uint32(elf.R_PPC64_ADDR64)<<16,
1214 S390X | uint32(elf.R_390_GLOB_DAT)<<16,
1215 S390X | uint32(elf.R_390_RELATIVE)<<16,
1216 S390X | uint32(elf.R_390_GOTOFF)<<16,
1217 S390X | uint32(elf.R_390_GOTPC)<<16,
1218 S390X | uint32(elf.R_390_64)<<16,
1219 S390X | uint32(elf.R_390_PC64)<<16,
1220 S390X | uint32(elf.R_390_GOT64)<<16,
1221 S390X | uint32(elf.R_390_PLT64)<<16:
1222 return 8, nil
1223 }
1224 }
1225
1226 func cstring(x []byte) string {
1227 i := bytes.IndexByte(x, '\x00')
1228 if i >= 0 {
1229 x = x[:i]
1230 }
1231 return string(x)
1232 }
1233
View as plain text