1package ld
2
3import (
4	"bytes"
5	"cmd/internal/bio"
6	"cmd/internal/objabi"
7	"cmd/internal/sys"
8	"encoding/binary"
9	"fmt"
10	"io"
11	"log"
12	"sort"
13	"strings"
14)
15
16/*
17Derived from Plan 9 from User Space's src/libmach/elf.h, elf.c
18http://code.swtch.com/plan9port/src/tip/src/libmach/
19
20	Copyright © 2004 Russ Cox.
21	Portions Copyright © 2008-2010 Google Inc.
22	Portions Copyright © 2010 The Go Authors.
23
24Permission is hereby granted, free of charge, to any person obtaining a copy
25of this software and associated documentation files (the "Software"), to deal
26in the Software without restriction, including without limitation the rights
27to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
28copies of the Software, and to permit persons to whom the Software is
29furnished to do so, subject to the following conditions:
30
31The above copyright notice and this permission notice shall be included in
32all copies or substantial portions of the Software.
33
34THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
37AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
38LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
39OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
40THE SOFTWARE.
41*/
42const (
43	ElfClassNone = 0
44	ElfClass32   = 1
45	ElfClass64   = 2
46)
47
48const (
49	ElfDataNone = 0
50	ElfDataLsb  = 1
51	ElfDataMsb  = 2
52)
53
54const (
55	ElfTypeNone         = 0
56	ElfTypeRelocatable  = 1
57	ElfTypeExecutable   = 2
58	ElfTypeSharedObject = 3
59	ElfTypeCore         = 4
60)
61
62const (
63	ElfMachNone        = 0
64	ElfMach32100       = 1
65	ElfMachSparc       = 2
66	ElfMach386         = 3
67	ElfMach68000       = 4
68	ElfMach88000       = 5
69	ElfMach486         = 6
70	ElfMach860         = 7
71	ElfMachMips        = 8
72	ElfMachS370        = 9
73	ElfMachMipsLe      = 10
74	ElfMachParisc      = 15
75	ElfMachVpp500      = 17
76	ElfMachSparc32Plus = 18
77	ElfMach960         = 19
78	ElfMachPower       = 20
79	ElfMachPower64     = 21
80	ElfMachS390        = 22
81	ElfMachV800        = 36
82	ElfMachFr20        = 37
83	ElfMachRh32        = 38
84	ElfMachRce         = 39
85	ElfMachArm         = 40
86	ElfMachAlpha       = 41
87	ElfMachSH          = 42
88	ElfMachSparc9      = 43
89	ElfMachAmd64       = 62
90	ElfMachArm64       = 183
91)
92
93const (
94	ElfAbiNone     = 0
95	ElfAbiSystemV  = 0
96	ElfAbiHPUX     = 1
97	ElfAbiNetBSD   = 2
98	ElfAbiLinux    = 3
99	ElfAbiSolaris  = 6
100	ElfAbiAix      = 7
101	ElfAbiIrix     = 8
102	ElfAbiFreeBSD  = 9
103	ElfAbiTru64    = 10
104	ElfAbiModesto  = 11
105	ElfAbiOpenBSD  = 12
106	ElfAbiARM      = 97
107	ElfAbiEmbedded = 255
108)
109
110const (
111	ElfSectNone      = 0
112	ElfSectProgbits  = 1
113	ElfSectSymtab    = 2
114	ElfSectStrtab    = 3
115	ElfSectRela      = 4
116	ElfSectHash      = 5
117	ElfSectDynamic   = 6
118	ElfSectNote      = 7
119	ElfSectNobits    = 8
120	ElfSectRel       = 9
121	ElfSectShlib     = 10
122	ElfSectDynsym    = 11
123	ElfSectFlagWrite = 0x1
124	ElfSectFlagAlloc = 0x2
125	ElfSectFlagExec  = 0x4
126)
127
128const (
129	ElfSymBindLocal  = 0
130	ElfSymBindGlobal = 1
131	ElfSymBindWeak   = 2
132)
133
134const (
135	ElfSymTypeNone    = 0
136	ElfSymTypeObject  = 1
137	ElfSymTypeFunc    = 2
138	ElfSymTypeSection = 3
139	ElfSymTypeFile    = 4
140	ElfSymTypeCommon  = 5
141	ElfSymTypeTLS     = 6
142)
143
144const (
145	ElfSymShnNone   = 0
146	ElfSymShnAbs    = 0xFFF1
147	ElfSymShnCommon = 0xFFF2
148)
149
150const (
151	ElfProgNone      = 0
152	ElfProgLoad      = 1
153	ElfProgDynamic   = 2
154	ElfProgInterp    = 3
155	ElfProgNote      = 4
156	ElfProgShlib     = 5
157	ElfProgPhdr      = 6
158	ElfProgFlagExec  = 0x1
159	ElfProgFlagWrite = 0x2
160	ElfProgFlagRead  = 0x4
161)
162
163const (
164	ElfNotePrStatus     = 1
165	ElfNotePrFpreg      = 2
166	ElfNotePrPsinfo     = 3
167	ElfNotePrTaskstruct = 4
168	ElfNotePrAuxv       = 6
169	ElfNotePrXfpreg     = 0x46e62b7f
170)
171
172type ElfHdrBytes struct {
173	Ident     [16]uint8
174	Type      [2]uint8
175	Machine   [2]uint8
176	Version   [4]uint8
177	Entry     [4]uint8
178	Phoff     [4]uint8
179	Shoff     [4]uint8
180	Flags     [4]uint8
181	Ehsize    [2]uint8
182	Phentsize [2]uint8
183	Phnum     [2]uint8
184	Shentsize [2]uint8
185	Shnum     [2]uint8
186	Shstrndx  [2]uint8
187}
188
189type ElfSectBytes struct {
190	Name    [4]uint8
191	Type    [4]uint8
192	Flags   [4]uint8
193	Addr    [4]uint8
194	Off     [4]uint8
195	Size    [4]uint8
196	Link    [4]uint8
197	Info    [4]uint8
198	Align   [4]uint8
199	Entsize [4]uint8
200}
201
202type ElfProgBytes struct {
203}
204
205type ElfSymBytes struct {
206	Name  [4]uint8
207	Value [4]uint8
208	Size  [4]uint8
209	Info  uint8
210	Other uint8
211	Shndx [2]uint8
212}
213
214type ElfHdrBytes64 struct {
215	Ident     [16]uint8
216	Type      [2]uint8
217	Machine   [2]uint8
218	Version   [4]uint8
219	Entry     [8]uint8
220	Phoff     [8]uint8
221	Shoff     [8]uint8
222	Flags     [4]uint8
223	Ehsize    [2]uint8
224	Phentsize [2]uint8
225	Phnum     [2]uint8
226	Shentsize [2]uint8
227	Shnum     [2]uint8
228	Shstrndx  [2]uint8
229}
230
231type ElfSectBytes64 struct {
232	Name    [4]uint8
233	Type    [4]uint8
234	Flags   [8]uint8
235	Addr    [8]uint8
236	Off     [8]uint8
237	Size    [8]uint8
238	Link    [4]uint8
239	Info    [4]uint8
240	Align   [8]uint8
241	Entsize [8]uint8
242}
243
244type ElfProgBytes64 struct {
245}
246
247type ElfSymBytes64 struct {
248	Name  [4]uint8
249	Info  uint8
250	Other uint8
251	Shndx [2]uint8
252	Value [8]uint8
253	Size  [8]uint8
254}
255
256type ElfSect struct {
257	name    string
258	nameoff uint32
259	type_   uint32
260	flags   uint64
261	addr    uint64
262	off     uint64
263	size    uint64
264	link    uint32
265	info    uint32
266	align   uint64
267	entsize uint64
268	base    []byte
269	sym     *Symbol
270}
271
272type ElfObj struct {
273	f         *bio.Reader
274	base      int64 // offset in f where ELF begins
275	length    int64 // length of ELF
276	is64      int
277	name      string
278	e         binary.ByteOrder
279	sect      []ElfSect
280	nsect     uint
281	shstrtab  string
282	nsymtab   int
283	symtab    *ElfSect
284	symstr    *ElfSect
285	type_     uint32
286	machine   uint32
287	version   uint32
288	entry     uint64
289	phoff     uint64
290	shoff     uint64
291	flags     uint32
292	ehsize    uint32
293	phentsize uint32
294	phnum     uint32
295	shentsize uint32
296	shnum     uint32
297	shstrndx  uint32
298}
299
300type ElfSym struct {
301	name  string
302	value uint64
303	size  uint64
304	bind  uint8
305	type_ uint8
306	other uint8
307	shndx uint16
308	sym   *Symbol
309}
310
311var ElfMagic = [4]uint8{0x7F, 'E', 'L', 'F'}
312
313const (
314	TagFile               = 1
315	TagCPUName            = 4
316	TagCPURawName         = 5
317	TagCompatibility      = 32
318	TagNoDefaults         = 64
319	TagAlsoCompatibleWith = 65
320	TagABIVFPArgs         = 28
321)
322
323type elfAttribute struct {
324	tag  uint64
325	sval string
326	ival uint64
327}
328
329type elfAttributeList struct {
330	data []byte
331	err  error
332}
333
334func (a *elfAttributeList) string() string {
335	if a.err != nil {
336		return ""
337	}
338	nul := bytes.IndexByte(a.data, 0)
339	if nul < 0 {
340		a.err = io.EOF
341		return ""
342	}
343	s := string(a.data[:nul])
344	a.data = a.data[nul+1:]
345	return s
346}
347
348func (a *elfAttributeList) uleb128() uint64 {
349	if a.err != nil {
350		return 0
351	}
352	v, size := binary.Uvarint(a.data)
353	a.data = a.data[size:]
354	return v
355}
356
357// Read an elfAttribute from the list following the rules used on ARM systems.
358func (a *elfAttributeList) armAttr() elfAttribute {
359	attr := elfAttribute{tag: a.uleb128()}
360	switch {
361	case attr.tag == TagCompatibility:
362		attr.ival = a.uleb128()
363		attr.sval = a.string()
364
365	case attr.tag == 64: // Tag_nodefaults has no argument
366
367	case attr.tag == 65: // Tag_also_compatible_with
368		// Not really, but we don't actually care about this tag.
369		attr.sval = a.string()
370
371	// Tag with string argument
372	case attr.tag == TagCPUName || attr.tag == TagCPURawName || (attr.tag >= 32 && attr.tag&1 != 0):
373		attr.sval = a.string()
374
375	default: // Tag with integer argument
376		attr.ival = a.uleb128()
377	}
378	return attr
379}
380
381func (a *elfAttributeList) done() bool {
382	if a.err != nil || len(a.data) == 0 {
383		return true
384	}
385	return false
386}
387
388// Look for the attribute that indicates the object uses the hard-float ABI (a
389// file-level attribute with tag Tag_VFP_arch and value 1). Unfortunately the
390// format used means that we have to parse all of the file-level attributes to
391// find the one we are looking for. This format is slightly documented in "ELF
392// for the ARM Architecture" but mostly this is derived from reading the source
393// to gold and readelf.
394func parseArmAttributes(ctxt *Link, e binary.ByteOrder, data []byte) {
395	// We assume the soft-float ABI unless we see a tag indicating otherwise.
396	if ehdr.flags == 0x5000002 {
397		ehdr.flags = 0x5000202
398	}
399	if data[0] != 'A' {
400		// TODO(dfc) should this be ctxt.Diag ?
401		ctxt.Logf(".ARM.attributes has unexpected format %c\n", data[0])
402		return
403	}
404	data = data[1:]
405	for len(data) != 0 {
406		sectionlength := e.Uint32(data)
407		sectiondata := data[4:sectionlength]
408		data = data[sectionlength:]
409
410		nulIndex := bytes.IndexByte(sectiondata, 0)
411		if nulIndex < 0 {
412			// TODO(dfc) should this be ctxt.Diag ?
413			ctxt.Logf("corrupt .ARM.attributes (section name not NUL-terminated)\n")
414			return
415		}
416		name := string(sectiondata[:nulIndex])
417		sectiondata = sectiondata[nulIndex+1:]
418
419		if name != "aeabi" {
420			continue
421		}
422		for len(sectiondata) != 0 {
423			subsectiontag, sz := binary.Uvarint(sectiondata)
424			subsectionsize := e.Uint32(sectiondata[sz:])
425			subsectiondata := sectiondata[sz+4 : subsectionsize]
426			sectiondata = sectiondata[subsectionsize:]
427
428			if subsectiontag == TagFile {
429				attrList := elfAttributeList{data: subsectiondata}
430				for !attrList.done() {
431					attr := attrList.armAttr()
432					if attr.tag == TagABIVFPArgs && attr.ival == 1 {
433						ehdr.flags = 0x5000402 // has entry point, Version5 EABI, hard-float ABI
434					}
435				}
436				if attrList.err != nil {
437					// TODO(dfc) should this be ctxt.Diag ?
438					ctxt.Logf("could not parse .ARM.attributes\n")
439				}
440			}
441		}
442	}
443}
444
445func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
446	if ctxt.Debugvlog != 0 {
447		ctxt.Logf("%5.2f ldelf %s\n", Cputime(), pn)
448	}
449
450	localSymVersion := ctxt.Syms.IncVersion()
451	base := f.Offset()
452
453	var add uint64
454	var e binary.ByteOrder
455	var elfobj *ElfObj
456	var flag int
457	var hdr *ElfHdrBytes
458	var hdrbuf [64]uint8
459	var info uint64
460	var is64 int
461	var j int
462	var n int
463	var name string
464	var p []byte
465	var r []Reloc
466	var rela int
467	var rp *Reloc
468	var rsect *ElfSect
469	var s *Symbol
470	var sect *ElfSect
471	var sym ElfSym
472	var symbols []*Symbol
473	if _, err := io.ReadFull(f, hdrbuf[:]); err != nil {
474		Errorf(nil, "%s: malformed elf file: %v", pn, err)
475		return
476	}
477	hdr = new(ElfHdrBytes)
478	binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter
479	if string(hdr.Ident[:4]) != "\x7FELF" {
480		Errorf(nil, "%s: malformed elf file", pn)
481		return
482	}
483	switch hdr.Ident[5] {
484	case ElfDataLsb:
485		e = binary.LittleEndian
486
487	case ElfDataMsb:
488		e = binary.BigEndian
489
490	default:
491		Errorf(nil, "%s: malformed elf file", pn)
492		return
493	}
494
495	// read header
496	elfobj = new(ElfObj)
497
498	elfobj.e = e
499	elfobj.f = f
500	elfobj.base = base
501	elfobj.length = length
502	elfobj.name = pn
503
504	is64 = 0
505	if hdr.Ident[4] == ElfClass64 {
506		is64 = 1
507		hdr := new(ElfHdrBytes64)
508		binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter
509		elfobj.type_ = uint32(e.Uint16(hdr.Type[:]))
510		elfobj.machine = uint32(e.Uint16(hdr.Machine[:]))
511		elfobj.version = e.Uint32(hdr.Version[:])
512		elfobj.phoff = e.Uint64(hdr.Phoff[:])
513		elfobj.shoff = e.Uint64(hdr.Shoff[:])
514		elfobj.flags = e.Uint32(hdr.Flags[:])
515		elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:]))
516		elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:]))
517		elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:]))
518		elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:]))
519		elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:]))
520		elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:]))
521	} else {
522		elfobj.type_ = uint32(e.Uint16(hdr.Type[:]))
523		elfobj.machine = uint32(e.Uint16(hdr.Machine[:]))
524		elfobj.version = e.Uint32(hdr.Version[:])
525		elfobj.entry = uint64(e.Uint32(hdr.Entry[:]))
526		elfobj.phoff = uint64(e.Uint32(hdr.Phoff[:]))
527		elfobj.shoff = uint64(e.Uint32(hdr.Shoff[:]))
528		elfobj.flags = e.Uint32(hdr.Flags[:])
529		elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:]))
530		elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:]))
531		elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:]))
532		elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:]))
533		elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:]))
534		elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:]))
535	}
536
537	elfobj.is64 = is64
538
539	if v := uint32(hdr.Ident[6]); v != elfobj.version {
540		Errorf(nil, "%s: malformed elf version: got %d, want %d", pn, v, elfobj.version)
541		return
542	}
543
544	if e.Uint16(hdr.Type[:]) != ElfTypeRelocatable {
545		Errorf(nil, "%s: elf but not elf relocatable object", pn)
546		return
547	}
548
549	switch SysArch.Family {
550	default:
551		Errorf(nil, "%s: elf %s unimplemented", pn, SysArch.Name)
552		return
553
554	case sys.MIPS:
555		if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass32 {
556			Errorf(nil, "%s: elf object but not mips", pn)
557			return
558		}
559
560	case sys.MIPS64:
561		if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass64 {
562			Errorf(nil, "%s: elf object but not mips64", pn)
563			return
564		}
565
566	case sys.ARM:
567		if e != binary.LittleEndian || elfobj.machine != ElfMachArm || hdr.Ident[4] != ElfClass32 {
568			Errorf(nil, "%s: elf object but not arm", pn)
569			return
570		}
571
572	case sys.AMD64:
573		if e != binary.LittleEndian || elfobj.machine != ElfMachAmd64 || hdr.Ident[4] != ElfClass64 {
574			Errorf(nil, "%s: elf object but not amd64", pn)
575			return
576		}
577
578	case sys.ARM64:
579		if e != binary.LittleEndian || elfobj.machine != ElfMachArm64 || hdr.Ident[4] != ElfClass64 {
580			Errorf(nil, "%s: elf object but not arm64", pn)
581			return
582		}
583
584	case sys.I386:
585		if e != binary.LittleEndian || elfobj.machine != ElfMach386 || hdr.Ident[4] != ElfClass32 {
586			Errorf(nil, "%s: elf object but not 386", pn)
587			return
588		}
589
590	case sys.PPC64:
591		if elfobj.machine != ElfMachPower64 || hdr.Ident[4] != ElfClass64 {
592			Errorf(nil, "%s: elf object but not ppc64", pn)
593			return
594		}
595
596	case sys.S390X:
597		if elfobj.machine != ElfMachS390 || hdr.Ident[4] != ElfClass64 {
598			Errorf(nil, "%s: elf object but not s390x", pn)
599			return
600		}
601	}
602
603	// load section list into memory.
604	elfobj.sect = make([]ElfSect, elfobj.shnum)
605
606	elfobj.nsect = uint(elfobj.shnum)
607	for i := 0; uint(i) < elfobj.nsect; i++ {
608		if f.Seek(int64(uint64(base)+elfobj.shoff+uint64(int64(i)*int64(elfobj.shentsize))), 0) < 0 {
609			Errorf(nil, "%s: malformed elf file", pn)
610			return
611		}
612		sect = &elfobj.sect[i]
613		if is64 != 0 {
614			var b ElfSectBytes64
615
616			if err := binary.Read(f, e, &b); err != nil {
617				Errorf(nil, "%s: malformed elf file: %v", pn, err)
618				return
619			}
620
621			sect.nameoff = e.Uint32(b.Name[:])
622			sect.type_ = e.Uint32(b.Type[:])
623			sect.flags = e.Uint64(b.Flags[:])
624			sect.addr = e.Uint64(b.Addr[:])
625			sect.off = e.Uint64(b.Off[:])
626			sect.size = e.Uint64(b.Size[:])
627			sect.link = e.Uint32(b.Link[:])
628			sect.info = e.Uint32(b.Info[:])
629			sect.align = e.Uint64(b.Align[:])
630			sect.entsize = e.Uint64(b.Entsize[:])
631		} else {
632			var b ElfSectBytes
633
634			if err := binary.Read(f, e, &b); err != nil {
635				Errorf(nil, "%s: malformed elf file: %v", pn, err)
636				return
637			}
638
639			sect.nameoff = e.Uint32(b.Name[:])
640			sect.type_ = e.Uint32(b.Type[:])
641			sect.flags = uint64(e.Uint32(b.Flags[:]))
642			sect.addr = uint64(e.Uint32(b.Addr[:]))
643			sect.off = uint64(e.Uint32(b.Off[:]))
644			sect.size = uint64(e.Uint32(b.Size[:]))
645			sect.link = e.Uint32(b.Link[:])
646			sect.info = e.Uint32(b.Info[:])
647			sect.align = uint64(e.Uint32(b.Align[:]))
648			sect.entsize = uint64(e.Uint32(b.Entsize[:]))
649		}
650	}
651
652	// read section string table and translate names
653	if elfobj.shstrndx >= uint32(elfobj.nsect) {
654		Errorf(nil, "%s: malformed elf file: shstrndx out of range %d >= %d", pn, elfobj.shstrndx, elfobj.nsect)
655		return
656	}
657
658	sect = &elfobj.sect[elfobj.shstrndx]
659	if err := elfmap(elfobj, sect); err != nil {
660		Errorf(nil, "%s: malformed elf file: %v", pn, err)
661		return
662	}
663	for i := 0; uint(i) < elfobj.nsect; i++ {
664		if elfobj.sect[i].nameoff != 0 {
665			elfobj.sect[i].name = cstring(sect.base[elfobj.sect[i].nameoff:])
666		}
667	}
668
669	// load string table for symbols into memory.
670	elfobj.symtab = section(elfobj, ".symtab")
671
672	if elfobj.symtab == nil {
673		// our work is done here - no symbols means nothing can refer to this file
674		return
675	}
676
677	if elfobj.symtab.link <= 0 || elfobj.symtab.link >= uint32(elfobj.nsect) {
678		Errorf(nil, "%s: elf object has symbol table with invalid string table link", pn)
679		return
680	}
681
682	elfobj.symstr = &elfobj.sect[elfobj.symtab.link]
683	if is64 != 0 {
684		elfobj.nsymtab = int(elfobj.symtab.size / ELF64SYMSIZE)
685	} else {
686		elfobj.nsymtab = int(elfobj.symtab.size / ELF32SYMSIZE)
687	}
688
689	if err := elfmap(elfobj, elfobj.symtab); err != nil {
690		Errorf(nil, "%s: malformed elf file: %v", pn, err)
691		return
692	}
693	if err := elfmap(elfobj, elfobj.symstr); err != nil {
694		Errorf(nil, "%s: malformed elf file: %v", pn, err)
695		return
696	}
697
698	// load text and data segments into memory.
699	// they are not as small as the section lists, but we'll need
700	// the memory anyway for the symbol images, so we might
701	// as well use one large chunk.
702
703	// create symbols for elfmapped sections
704	for i := 0; uint(i) < elfobj.nsect; i++ {
705		sect = &elfobj.sect[i]
706		if sect.type_ == SHT_ARM_ATTRIBUTES && sect.name == ".ARM.attributes" {
707			if err := elfmap(elfobj, sect); err != nil {
708				Errorf(nil, "%s: malformed elf file: %v", pn, err)
709				return
710			}
711			parseArmAttributes(ctxt, e, sect.base[:sect.size])
712		}
713		if (sect.type_ != ElfSectProgbits && sect.type_ != ElfSectNobits) || sect.flags&ElfSectFlagAlloc == 0 {
714			continue
715		}
716		if sect.type_ != ElfSectNobits {
717			if err := elfmap(elfobj, sect); err != nil {
718				Errorf(nil, "%s: malformed elf file: %v", pn, err)
719				return
720			}
721		}
722
723		name = fmt.Sprintf("%s(%s)", pkg, sect.name)
724		s = ctxt.Syms.Lookup(name, localSymVersion)
725
726		switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) {
727		default:
728			Errorf(nil, "%s: unexpected flags for ELF section %s", pn, sect.name)
729			return
730
731		case ElfSectFlagAlloc:
732			s.Type = SRODATA
733
734		case ElfSectFlagAlloc + ElfSectFlagWrite:
735			if sect.type_ == ElfSectNobits {
736				s.Type = SNOPTRBSS
737			} else {
738				s.Type = SNOPTRDATA
739			}
740
741		case ElfSectFlagAlloc + ElfSectFlagExec:
742			s.Type = STEXT
743		}
744
745		if sect.name == ".got" || sect.name == ".toc" {
746			s.Type = SELFGOT
747		}
748		if sect.type_ == ElfSectProgbits {
749			s.P = sect.base
750			s.P = s.P[:sect.size]
751		}
752
753		s.Size = int64(sect.size)
754		s.Align = int32(sect.align)
755		sect.sym = s
756	}
757
758	// enter sub-symbols into symbol table.
759	// symbol 0 is the null symbol.
760	symbols = make([]*Symbol, elfobj.nsymtab)
761
762	for i := 1; i < elfobj.nsymtab; i++ {
763		if err := readelfsym(ctxt, elfobj, i, &sym, 1, localSymVersion); err != nil {
764			Errorf(nil, "%s: malformed elf file: %v", pn, err)
765			return
766		}
767		symbols[i] = sym.sym
768		if sym.type_ != ElfSymTypeFunc && sym.type_ != ElfSymTypeObject && sym.type_ != ElfSymTypeNone && sym.type_ != ElfSymTypeCommon {
769			continue
770		}
771		if sym.shndx == ElfSymShnCommon || sym.type_ == ElfSymTypeCommon {
772			s = sym.sym
773			if uint64(s.Size) < sym.size {
774				s.Size = int64(sym.size)
775			}
776			if s.Type == 0 || s.Type == SXREF {
777				s.Type = SNOPTRBSS
778			}
779			continue
780		}
781
782		if uint(sym.shndx) >= elfobj.nsect || sym.shndx == 0 {
783			continue
784		}
785
786		// even when we pass needSym == 1 to readelfsym, it might still return nil to skip some unwanted symbols
787		if sym.sym == nil {
788			continue
789		}
790		sect = &elfobj.sect[sym.shndx]
791		if sect.sym == nil {
792			if strings.HasPrefix(sym.name, ".Linfo_string") { // clang does this
793				continue
794			}
795
796			if sym.name == "" && sym.type_ == 0 && sect.name == ".debug_str" {
797				// This reportedly happens with clang 3.7 on ARM.
798				// See issue 13139.
799				continue
800			}
801
802			if strings.HasPrefix(sym.name, ".LASF") { // gcc on s390x does this
803				continue
804			}
805			Errorf(sym.sym, "%s: sym#%d: ignoring symbol in section %d (type %d)", pn, i, sym.shndx, sym.type_)
806			continue
807		}
808
809		s = sym.sym
810		if s.Outer != nil {
811			if s.Attr.DuplicateOK() {
812				continue
813			}
814			Exitf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name)
815		}
816
817		s.Sub = sect.sym.Sub
818		sect.sym.Sub = s
819		s.Type = sect.sym.Type | s.Type&^SMASK | SSUB
820		if !s.Attr.CgoExportDynamic() {
821			s.Dynimplib = "" // satisfy dynimport
822		}
823		s.Value = int64(sym.value)
824		s.Size = int64(sym.size)
825		s.Outer = sect.sym
826		if sect.sym.Type == STEXT {
827			if s.Attr.External() && !s.Attr.DuplicateOK() {
828				Errorf(s, "%s: duplicate symbol definition", pn)
829			}
830			s.Attr |= AttrExternal
831		}
832
833		if elfobj.machine == ElfMachPower64 {
834			flag = int(sym.other) >> 5
835			if 2 <= flag && flag <= 6 {
836				s.Localentry = 1 << uint(flag-2)
837			} else if flag == 7 {
838				Errorf(s, "%s: invalid sym.other 0x%x", pn, sym.other)
839			}
840		}
841	}
842
843	// Sort outer lists by address, adding to textp.
844	// This keeps textp in increasing address order.
845	for i := 0; uint(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 = listsort(s.Sub)
852		}
853		if s.Type == STEXT {
854			if s.Attr.OnList() {
855				log.Fatalf("symbol %s listed multiple times", s.Name)
856			}
857			s.Attr |= AttrOnList
858			ctxt.Textp = append(ctxt.Textp, s)
859			for s = s.Sub; s != nil; s = s.Sub {
860				if s.Attr.OnList() {
861					log.Fatalf("symbol %s listed multiple times", s.Name)
862				}
863				s.Attr |= AttrOnList
864				ctxt.Textp = append(ctxt.Textp, s)
865			}
866		}
867	}
868
869	// load relocations
870	for i := 0; uint(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			Errorf(nil, "%s: malformed elf file: %v", pn, err)
881			return
882		}
883		rela = 0
884		if rsect.type_ == ElfSectRela {
885			rela = 1
886		}
887		n = int(rsect.size / uint64(4+4*is64) / uint64(2+rela))
888		r = make([]Reloc, n)
889		p = rsect.base
890		for j = 0; j < n; j++ {
891			add = 0
892			rp = &r[j]
893			if is64 != 0 {
894				// 64-bit rel/rela
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				// 32-bit rel/rela
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 // convert to 64-bit info
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 { // skip R_*_NONE relocation
919				j--
920				n--
921				continue
922			}
923
924			if info>>32 == 0 { // absolute relocation, don't bother reading the null symbol
925				rp.Sym = nil
926			} else {
927				if err := readelfsym(ctxt, elfobj, int(info>>32), &sym, 0, 0); err != nil {
928					Errorf(nil, "%s: malformed elf file: %v", pn, err)
929					return
930				}
931				sym.sym = symbols[info>>32]
932				if sym.sym == nil {
933					Errorf(nil, "%s: malformed elf file: %s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", pn, sect.sym.Name, j, int(info>>32), sym.name, sym.shndx, sym.type_)
934					return
935				}
936
937				rp.Sym = sym.sym
938			}
939
940			rp.Type = 256 + objabi.RelocType(info)
941			rp.Siz = relSize(ctxt, pn, uint32(info))
942			if rela != 0 {
943				rp.Add = int64(add)
944			} else {
945				// load addend from image
946				if rp.Siz == 4 {
947					rp.Add = int64(e.Uint32(sect.base[rp.Off:]))
948				} else if rp.Siz == 8 {
949					rp.Add = int64(e.Uint64(sect.base[rp.Off:]))
950				} else {
951					Errorf(nil, "invalid rela size %d", rp.Siz)
952				}
953			}
954
955			if rp.Siz == 2 {
956				rp.Add = int64(int16(rp.Add))
957			}
958			if rp.Siz == 4 {
959				rp.Add = int64(int32(rp.Add))
960			}
961		}
962
963		//print("rel %s %d %d %s %#llx\n", sect->sym->name, rp->type, rp->siz, rp->sym->name, rp->add);
964		sort.Sort(rbyoff(r[:n]))
965		// just in case
966
967		s = sect.sym
968		s.R = r
969		s.R = s.R[:n]
970	}
971}
972
973func section(elfobj *ElfObj, name string) *ElfSect {
974	for i := 0; uint(i) < elfobj.nsect; i++ {
975		if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name {
976			return &elfobj.sect[i]
977		}
978	}
979	return nil
980}
981
982func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) {
983	if sect.base != nil {
984		return nil
985	}
986
987	if sect.off+sect.size > uint64(elfobj.length) {
988		err = fmt.Errorf("elf section past end of file")
989		return err
990	}
991
992	sect.base = make([]byte, sect.size)
993	if elfobj.f.Seek(int64(uint64(elfobj.base)+sect.off), 0) < 0 {
994		return fmt.Errorf("short read: seek not successful")
995	}
996	if _, err := io.ReadFull(elfobj.f, sect.base); err != nil {
997		return fmt.Errorf("short read: %v", err)
998	}
999
1000	return nil
1001}
1002
1003func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int, localSymVersion int) (err error) {
1004	if i >= elfobj.nsymtab || i < 0 {
1005		err = fmt.Errorf("invalid elf symbol index")
1006		return err
1007	}
1008
1009	if i == 0 {
1010		Errorf(nil, "readym: read null symbol!")
1011	}
1012
1013	if elfobj.is64 != 0 {
1014		b := new(ElfSymBytes64)
1015		binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF64SYMSIZE:(i+1)*ELF64SYMSIZE]), elfobj.e, b)
1016		sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
1017		sym.value = elfobj.e.Uint64(b.Value[:])
1018		sym.size = elfobj.e.Uint64(b.Size[:])
1019		sym.shndx = elfobj.e.Uint16(b.Shndx[:])
1020		sym.bind = b.Info >> 4
1021		sym.type_ = b.Info & 0xf
1022		sym.other = b.Other
1023	} else {
1024		b := new(ElfSymBytes)
1025		binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF32SYMSIZE:(i+1)*ELF32SYMSIZE]), elfobj.e, b)
1026		sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
1027		sym.value = uint64(elfobj.e.Uint32(b.Value[:]))
1028		sym.size = uint64(elfobj.e.Uint32(b.Size[:]))
1029		sym.shndx = elfobj.e.Uint16(b.Shndx[:])
1030		sym.bind = b.Info >> 4
1031		sym.type_ = b.Info & 0xf
1032		sym.other = b.Other
1033	}
1034
1035	var s *Symbol
1036	if sym.name == "_GLOBAL_OFFSET_TABLE_" {
1037		sym.name = ".got"
1038	}
1039	if sym.name == ".TOC." {
1040		// Magic symbol on ppc64.  Will be set to this object
1041		// file's .got+0x8000.
1042		sym.bind = ElfSymBindLocal
1043	}
1044
1045	switch sym.type_ {
1046	case ElfSymTypeSection:
1047		s = elfobj.sect[sym.shndx].sym
1048
1049	case ElfSymTypeObject, ElfSymTypeFunc, ElfSymTypeNone, ElfSymTypeCommon:
1050		switch sym.bind {
1051		case ElfSymBindGlobal:
1052			if needSym != 0 {
1053				s = ctxt.Syms.Lookup(sym.name, 0)
1054
1055				// for global scoped hidden symbols we should insert it into
1056				// symbol hash table, but mark them as hidden.
1057				// __i686.get_pc_thunk.bx is allowed to be duplicated, to
1058				// workaround that we set dupok.
1059				// TODO(minux): correctly handle __i686.get_pc_thunk.bx without
1060				// set dupok generally. See http://codereview.appspot.com/5823055/
1061				// comment #5 for details.
1062				if s != nil && sym.other == 2 {
1063					s.Type |= SHIDDEN
1064					s.Attr |= AttrDuplicateOK
1065				}
1066			}
1067
1068		case ElfSymBindLocal:
1069			if SysArch.Family == sys.ARM && (strings.HasPrefix(sym.name, "$a") || strings.HasPrefix(sym.name, "$d")) {
1070				// binutils for arm generate these mapping
1071				// symbols, ignore these
1072				break
1073			}
1074
1075			if sym.name == ".TOC." {
1076				// We need to be able to look this up,
1077				// so put it in the hash table.
1078				if needSym != 0 {
1079					s = ctxt.Syms.Lookup(sym.name, localSymVersion)
1080					s.Type |= SHIDDEN
1081				}
1082
1083				break
1084			}
1085
1086			if needSym != 0 {
1087				// local names and hidden global names are unique
1088				// and should only be referenced by their index, not name, so we
1089				// don't bother to add them into the hash table
1090				s = ctxt.Syms.newsym(sym.name, localSymVersion)
1091
1092				s.Type |= SHIDDEN
1093			}
1094
1095		case ElfSymBindWeak:
1096			if needSym != 0 {
1097				s = ctxt.Syms.Lookup(sym.name, 0)
1098				if sym.other == 2 {
1099					s.Type |= SHIDDEN
1100				}
1101			}
1102
1103		default:
1104			err = fmt.Errorf("%s: invalid symbol binding %d", sym.name, sym.bind)
1105			return err
1106		}
1107	}
1108
1109	if s != nil && s.Type == 0 && sym.type_ != ElfSymTypeSection {
1110		s.Type = SXREF
1111	}
1112	sym.sym = s
1113
1114	return nil
1115}
1116
1117type rbyoff []Reloc
1118
1119func (x rbyoff) Len() int {
1120	return len(x)
1121}
1122
1123func (x rbyoff) Swap(i, j int) {
1124	x[i], x[j] = x[j], x[i]
1125}
1126
1127func (x rbyoff) Less(i, j int) bool {
1128	a := &x[i]
1129	b := &x[j]
1130	if a.Off < b.Off {
1131		return true
1132	}
1133	if a.Off > b.Off {
1134		return false
1135	}
1136	return false
1137}
1138
1139func relSize(ctxt *Link, pn string, elftype uint32) uint8 {
1140	// TODO(mdempsky): Replace this with a struct-valued switch statement
1141	// once golang.org/issue/15164 is fixed or found to not impair cmd/link
1142	// performance.
1143
1144	const (
1145		AMD64 = uint32(sys.AMD64)
1146		ARM   = uint32(sys.ARM)
1147		I386  = uint32(sys.I386)
1148		PPC64 = uint32(sys.PPC64)
1149		S390X = uint32(sys.S390X)
1150	)
1151
1152	switch uint32(SysArch.Family) | elftype<<24 {
1153	default:
1154		Errorf(nil, "%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
1155		fallthrough
1156
1157	case S390X | R_390_8<<24:
1158		return 1
1159
1160	case PPC64 | R_PPC64_TOC16<<24,
1161		PPC64 | R_PPC64_TOC16_LO<<24,
1162		PPC64 | R_PPC64_TOC16_HI<<24,
1163		PPC64 | R_PPC64_TOC16_HA<<24,
1164		PPC64 | R_PPC64_TOC16_DS<<24,
1165		PPC64 | R_PPC64_TOC16_LO_DS<<24,
1166		PPC64 | R_PPC64_REL16_LO<<24,
1167		PPC64 | R_PPC64_REL16_HI<<24,
1168		PPC64 | R_PPC64_REL16_HA<<24,
1169		S390X | R_390_16<<24,
1170		S390X | R_390_GOT16<<24,
1171		S390X | R_390_PC16<<24,
1172		S390X | R_390_PC16DBL<<24,
1173		S390X | R_390_PLT16DBL<<24:
1174		return 2
1175
1176	case ARM | R_ARM_ABS32<<24,
1177		ARM | R_ARM_GOT32<<24,
1178		ARM | R_ARM_PLT32<<24,
1179		ARM | R_ARM_GOTOFF<<24,
1180		ARM | R_ARM_GOTPC<<24,
1181		ARM | R_ARM_THM_PC22<<24,
1182		ARM | R_ARM_REL32<<24,
1183		ARM | R_ARM_CALL<<24,
1184		ARM | R_ARM_V4BX<<24,
1185		ARM | R_ARM_GOT_PREL<<24,
1186		ARM | R_ARM_PC24<<24,
1187		ARM | R_ARM_JUMP24<<24,
1188		AMD64 | R_X86_64_PC32<<24,
1189		AMD64 | R_X86_64_PLT32<<24,
1190		AMD64 | R_X86_64_GOTPCREL<<24,
1191		AMD64 | R_X86_64_GOTPCRELX<<24,
1192		AMD64 | R_X86_64_REX_GOTPCRELX<<24,
1193		I386 | R_386_32<<24,
1194		I386 | R_386_PC32<<24,
1195		I386 | R_386_GOT32<<24,
1196		I386 | R_386_PLT32<<24,
1197		I386 | R_386_GOTOFF<<24,
1198		I386 | R_386_GOTPC<<24,
1199		I386 | R_386_GOT32X<<24,
1200		PPC64 | R_PPC64_REL24<<24,
1201		PPC64 | R_PPC_REL32<<24,
1202		S390X | R_390_32<<24,
1203		S390X | R_390_PC32<<24,
1204		S390X | R_390_GOT32<<24,
1205		S390X | R_390_PLT32<<24,
1206		S390X | R_390_PC32DBL<<24,
1207		S390X | R_390_PLT32DBL<<24,
1208		S390X | R_390_GOTPCDBL<<24,
1209		S390X | R_390_GOTENT<<24:
1210		return 4
1211
1212	case AMD64 | R_X86_64_64<<24,
1213		PPC64 | R_PPC64_ADDR64<<24,
1214		S390X | R_390_GLOB_DAT<<24,
1215		S390X | R_390_RELATIVE<<24,
1216		S390X | R_390_GOTOFF<<24,
1217		S390X | R_390_GOTPC<<24,
1218		S390X | R_390_64<<24,
1219		S390X | R_390_PC64<<24,
1220		S390X | R_390_GOT64<<24,
1221		S390X | R_390_PLT64<<24:
1222		return 8
1223	}
1224}
1225