1// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package loadelf implements an ELF file reader.
6package loadelf
7
8import (
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/*
24Derived from Plan 9 from User Space's src/libmach/elf.h, elf.c
25https://github.com/9fans/plan9port/tree/master/src/libmach/
26
27	Copyright © 2004 Russ Cox.
28	Portions Copyright © 2008-2010 Google Inc.
29	Portions Copyright © 2010 The Go Authors.
30
31Permission is hereby granted, free of charge, to any person obtaining a copy
32of this software and associated documentation files (the "Software"), to deal
33in the Software without restriction, including without limitation the rights
34to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
35copies of the Software, and to permit persons to whom the Software is
36furnished to do so, subject to the following conditions:
37
38The above copyright notice and this permission notice shall be included in
39all copies or substantial portions of the Software.
40
41THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
44AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
46OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
47THE SOFTWARE.
48*/
49
50const (
51	SHT_ARM_ATTRIBUTES = 0x70000003
52)
53
54type 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 // Is this section in readonly memory?
68	sym         loader.Sym
69}
70
71type ElfObj struct {
72	f         *bio.Reader
73	base      int64 // offset in f where ELF begins
74	length    int64 // length of ELF
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
98type 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
109const (
110	TagFile               = 1
111	TagCPUName            = 4
112	TagCPURawName         = 5
113	TagCompatibility      = 32
114	TagNoDefaults         = 64
115	TagAlsoCompatibleWith = 65
116	TagABIVFPArgs         = 28
117)
118
119type elfAttribute struct {
120	tag  uint64
121	sval string
122	ival uint64
123}
124
125type elfAttributeList struct {
126	data []byte
127	err  error
128}
129
130func (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
144func (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// Read an elfAttribute from the list following the rules used on ARM systems.
154func (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: // Tag_nodefaults has no argument
162
163	case attr.tag == TagAlsoCompatibleWith:
164		// Not really, but we don't actually care about this tag.
165		attr.sval = a.string()
166
167	// Tag with string argument
168	case attr.tag == TagCPUName || attr.tag == TagCPURawName || (attr.tag >= 32 && attr.tag&1 != 0):
169		attr.sval = a.string()
170
171	default: // Tag with integer argument
172		attr.ival = a.uleb128()
173	}
174	return attr
175}
176
177func (a *elfAttributeList) done() bool {
178	if a.err != nil || len(a.data) == 0 {
179		return true
180	}
181	return false
182}
183
184// Look for the attribute that indicates the object uses the hard-float ABI (a
185// file-level attribute with tag Tag_VFP_arch and value 1). Unfortunately the
186// format used means that we have to parse all of the file-level attributes to
187// find the one we are looking for. This format is slightly documented in "ELF
188// for the ARM Architecture" but mostly this is derived from reading the source
189// to gold and readelf.
190func 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 // has entry point, Version5 EABI, hard-float ABI
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// Load loads the ELF file pn from f.
237// Symbols are installed into the loader, and a slice of the text symbols is returned.
238//
239// On ARM systems, Load will attempt to determine what ELF header flags to
240// emit by scanning the attributes in the ELF file being loaded. The
241// parameter initEhdrFlags contains the current header flags for the output
242// object, and the returned ehdrFlags contains what this Load function computes.
243// TODO: find a better place for this logic.
244func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader, pkg string, length int64, pn string, initEhdrFlags uint32) (textp []loader.Sym, ehdrFlags uint32, err error) {
245	errorf := func(str string, args ...interface{}) ([]loader.Sym, uint32, error) {
246		return nil, 0, fmt.Errorf("loadelf: %s: %v", pn, fmt.Sprintf(str, args...))
247	}
248
249	ehdrFlags = initEhdrFlags
250
251	base := f.Offset()
252
253	var hdrbuf [64]byte
254	if _, err := io.ReadFull(f, hdrbuf[:]); err != nil {
255		return errorf("malformed elf file: %v", err)
256	}
257
258	var e binary.ByteOrder
259	switch elf.Data(hdrbuf[elf.EI_DATA]) {
260	case elf.ELFDATA2LSB:
261		e = binary.LittleEndian
262
263	case elf.ELFDATA2MSB:
264		e = binary.BigEndian
265
266	default:
267		return errorf("malformed elf file, unknown header")
268	}
269
270	hdr := new(elf.Header32)
271	binary.Read(bytes.NewReader(hdrbuf[:]), e, hdr)
272
273	if string(hdr.Ident[:elf.EI_CLASS]) != elf.ELFMAG {
274		return errorf("malformed elf file, bad header")
275	}
276
277	// read header
278	elfobj := new(ElfObj)
279
280	elfobj.e = e
281	elfobj.f = f
282	elfobj.base = base
283	elfobj.length = length
284	elfobj.name = pn
285
286	is64 := 0
287	class := elf.Class(hdrbuf[elf.EI_CLASS])
288	if class == elf.ELFCLASS64 {
289		is64 = 1
290		hdr := new(elf.Header64)
291		binary.Read(bytes.NewReader(hdrbuf[:]), e, hdr)
292		elfobj.type_ = uint32(hdr.Type)
293		elfobj.machine = uint32(hdr.Machine)
294		elfobj.version = hdr.Version
295		elfobj.entry = hdr.Entry
296		elfobj.phoff = hdr.Phoff
297		elfobj.shoff = hdr.Shoff
298		elfobj.flags = hdr.Flags
299		elfobj.ehsize = uint32(hdr.Ehsize)
300		elfobj.phentsize = uint32(hdr.Phentsize)
301		elfobj.phnum = uint32(hdr.Phnum)
302		elfobj.shentsize = uint32(hdr.Shentsize)
303		elfobj.shnum = uint32(hdr.Shnum)
304		elfobj.shstrndx = uint32(hdr.Shstrndx)
305	} else {
306		elfobj.type_ = uint32(hdr.Type)
307		elfobj.machine = uint32(hdr.Machine)
308		elfobj.version = hdr.Version
309		elfobj.entry = uint64(hdr.Entry)
310		elfobj.phoff = uint64(hdr.Phoff)
311		elfobj.shoff = uint64(hdr.Shoff)
312		elfobj.flags = hdr.Flags
313		elfobj.ehsize = uint32(hdr.Ehsize)
314		elfobj.phentsize = uint32(hdr.Phentsize)
315		elfobj.phnum = uint32(hdr.Phnum)
316		elfobj.shentsize = uint32(hdr.Shentsize)
317		elfobj.shnum = uint32(hdr.Shnum)
318		elfobj.shstrndx = uint32(hdr.Shstrndx)
319	}
320
321	elfobj.is64 = is64
322
323	if v := uint32(hdrbuf[elf.EI_VERSION]); v != elfobj.version {
324		return errorf("malformed elf version: got %d, want %d", v, elfobj.version)
325	}
326
327	if elf.Type(elfobj.type_) != elf.ET_REL {
328		return errorf("elf but not elf relocatable object")
329	}
330
331	mach := elf.Machine(elfobj.machine)
332	switch arch.Family {
333	default:
334		return errorf("elf %s unimplemented", arch.Name)
335
336	case sys.MIPS:
337		if mach != elf.EM_MIPS || class != elf.ELFCLASS32 {
338			return errorf("elf object but not mips")
339		}
340
341	case sys.MIPS64:
342		if mach != elf.EM_MIPS || class != elf.ELFCLASS64 {
343			return errorf("elf object but not mips64")
344		}
345	case sys.Loong64:
346		if mach != elf.EM_LOONGARCH || class != elf.ELFCLASS64 {
347			return errorf("elf object but not loong64")
348		}
349
350	case sys.ARM:
351		if e != binary.LittleEndian || mach != elf.EM_ARM || class != elf.ELFCLASS32 {
352			return errorf("elf object but not arm")
353		}
354
355	case sys.AMD64:
356		if e != binary.LittleEndian || mach != elf.EM_X86_64 || class != elf.ELFCLASS64 {
357			return errorf("elf object but not amd64")
358		}
359
360	case sys.ARM64:
361		if e != binary.LittleEndian || mach != elf.EM_AARCH64 || class != elf.ELFCLASS64 {
362			return errorf("elf object but not arm64")
363		}
364
365	case sys.I386:
366		if e != binary.LittleEndian || mach != elf.EM_386 || class != elf.ELFCLASS32 {
367			return errorf("elf object but not 386")
368		}
369
370	case sys.PPC64:
371		if mach != elf.EM_PPC64 || class != elf.ELFCLASS64 {
372			return errorf("elf object but not ppc64")
373		}
374
375	case sys.RISCV64:
376		if mach != elf.EM_RISCV || class != elf.ELFCLASS64 {
377			return errorf("elf object but not riscv64")
378		}
379
380	case sys.S390X:
381		if mach != elf.EM_S390 || class != elf.ELFCLASS64 {
382			return errorf("elf object but not s390x")
383		}
384	}
385
386	// load section list into memory.
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	// read section string table and translate names
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	// load string table for symbols into memory.
444	elfobj.symtab = section(elfobj, ".symtab")
445
446	if elfobj.symtab == nil {
447		// our work is done here - no symbols means nothing can refer to this file
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	// load text and data segments into memory.
470	// they are not as small as the section lists, but we'll need
471	// the memory anyway for the symbol images, so we might
472	// as well use one large chunk.
473
474	// create symbols for elfmapped sections
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			// We assume the soft-float ABI unless we see a tag indicating otherwise.
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				// TODO(dfc) should this return an error?
492				log.Printf("%s: %v", pn, err)
493			}
494			if found {
495				ehdrFlags = newEhdrFlags
496			}
497		}
498		if (sect.type_ != elf.SHT_PROGBITS && sect.type_ != elf.SHT_NOBITS) || sect.flags&elf.SHF_ALLOC == 0 {
499			continue
500		}
501		if sect.type_ != elf.SHT_NOBITS {
502			if err := elfmap(elfobj, sect); err != nil {
503				return errorf("%s: malformed elf file: %v", pn, err)
504			}
505		}
506
507		name := fmt.Sprintf("%s(%s)", pkg, sect.name)
508		for sectsymNames[name] {
509			counter++
510			name = fmt.Sprintf("%s(%s%d)", pkg, sect.name, counter)
511		}
512		sectsymNames[name] = true
513
514		sb := l.MakeSymbolUpdater(l.LookupOrCreateCgoExport(name, localSymVersion))
515
516		switch sect.flags & (elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_EXECINSTR) {
517		default:
518			return errorf("%s: unexpected flags for ELF section %s", pn, sect.name)
519
520		case elf.SHF_ALLOC:
521			sb.SetType(sym.SRODATA)
522
523		case elf.SHF_ALLOC + elf.SHF_WRITE:
524			if sect.type_ == elf.SHT_NOBITS {
525				sb.SetType(sym.SNOPTRBSS)
526			} else {
527				sb.SetType(sym.SNOPTRDATA)
528			}
529
530		case elf.SHF_ALLOC + elf.SHF_EXECINSTR:
531			sb.SetType(sym.STEXT)
532		}
533
534		if sect.name == ".got" || sect.name == ".toc" {
535			sb.SetType(sym.SELFGOT)
536		}
537		if sect.type_ == elf.SHT_PROGBITS {
538			sb.SetData(sect.base[:sect.size])
539			sb.SetExternal(true)
540		}
541
542		sb.SetSize(int64(sect.size))
543		sb.SetAlign(int32(sect.align))
544		sb.SetReadOnly(sect.readOnlyMem)
545
546		sect.sym = sb.Sym()
547	}
548
549	// enter sub-symbols into symbol table.
550	// symbol 0 is the null symbol.
551	symbols := make([]loader.Sym, elfobj.nsymtab)
552
553	for i := 1; i < elfobj.nsymtab; i++ {
554		var elfsym ElfSym
555		if err := readelfsym(l, arch, elfobj, i, &elfsym, 1, localSymVersion); err != nil {
556			return errorf("%s: malformed elf file: %v", pn, err)
557		}
558		symbols[i] = elfsym.sym
559		if elfsym.type_ != elf.STT_FUNC && elfsym.type_ != elf.STT_OBJECT && elfsym.type_ != elf.STT_NOTYPE && elfsym.type_ != elf.STT_COMMON {
560			continue
561		}
562		if elfsym.shndx == elf.SHN_COMMON || elfsym.type_ == elf.STT_COMMON {
563			sb := l.MakeSymbolUpdater(elfsym.sym)
564			if uint64(sb.Size()) < elfsym.size {
565				sb.SetSize(int64(elfsym.size))
566			}
567			if sb.Type() == 0 || sb.Type() == sym.SXREF {
568				sb.SetType(sym.SNOPTRBSS)
569			}
570			continue
571		}
572
573		if uint(elfsym.shndx) >= elfobj.nsect || elfsym.shndx == 0 {
574			continue
575		}
576
577		// even when we pass needSym == 1 to readelfsym, it might still return nil to skip some unwanted symbols
578		if elfsym.sym == 0 {
579			continue
580		}
581		sect = &elfobj.sect[elfsym.shndx]
582		if sect.sym == 0 {
583			if elfsym.type_ == 0 {
584				if strings.HasPrefix(sect.name, ".debug_") && elfsym.name == "" {
585					// clang on arm and riscv64.
586					// This reportedly happens with clang 3.7 on ARM.
587					// See issue 13139.
588					continue
589				}
590				if strings.HasPrefix(elfsym.name, ".Ldebug_") || elfsym.name == ".L0 " {
591					// gcc on riscv64.
592					continue
593				}
594				if elfsym.name == ".Lline_table_start0" {
595					// clang on riscv64.
596					continue
597				}
598
599				if strings.HasPrefix(elfsym.name, "$d") && sect.name == ".debug_frame" {
600					// "$d" is a marker, not a real symbol.
601					// This happens with gcc on ARM64.
602					// See https://sourceware.org/bugzilla/show_bug.cgi?id=21809
603					continue
604				}
605			}
606
607			if strings.HasPrefix(elfsym.name, ".Linfo_string") {
608				// clang does this
609				continue
610			}
611
612			if strings.HasPrefix(elfsym.name, ".LASF") || strings.HasPrefix(elfsym.name, ".LLRL") || strings.HasPrefix(elfsym.name, ".LLST") {
613				// gcc on s390x and riscv64 does this.
614				continue
615			}
616
617			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_)
618		}
619
620		s := elfsym.sym
621		if l.OuterSym(s) != 0 {
622			if l.AttrDuplicateOK(s) {
623				continue
624			}
625			return errorf("duplicate symbol reference: %s in both %s and %s",
626				l.SymName(s), l.SymName(l.OuterSym(s)), l.SymName(sect.sym))
627		}
628
629		sectsb := l.MakeSymbolUpdater(sect.sym)
630		sb := l.MakeSymbolUpdater(s)
631
632		sb.SetType(sectsb.Type())
633		sectsb.AddInteriorSym(s)
634		if !l.AttrCgoExportDynamic(s) {
635			sb.SetDynimplib("") // satisfy dynimport
636		}
637		sb.SetValue(int64(elfsym.value))
638		sb.SetSize(int64(elfsym.size))
639		if sectsb.Type() == sym.STEXT {
640			if l.AttrExternal(s) && !l.AttrDuplicateOK(s) {
641				return errorf("%s: duplicate symbol definition", sb.Name())
642			}
643			l.SetAttrExternal(s, true)
644		}
645
646		if elf.Machine(elfobj.machine) == elf.EM_PPC64 {
647			flag := int(elfsym.other) >> 5
648			switch flag {
649			case 0:
650				// No local entry. R2 is preserved.
651			case 1:
652				// This is kind of a hack, but pass the hint about this symbol's
653				// usage of R2 (R2 is a caller-save register not a TOC pointer, and
654				// this function does not have a distinct local entry) by setting
655				// its SymLocalentry to 1.
656				l.SetSymLocalentry(s, 1)
657			case 7:
658				return errorf("%s: invalid sym.other 0x%x", sb.Name(), elfsym.other)
659			default:
660				// Convert the word sized offset into bytes.
661				l.SetSymLocalentry(s, 4<<uint(flag-2))
662			}
663		}
664	}
665
666	// Sort outer lists by address, adding to textp.
667	// This keeps textp in increasing address order.
668	for i := uint(0); i < elfobj.nsect; i++ {
669		s := elfobj.sect[i].sym
670		if s == 0 {
671			continue
672		}
673		sb := l.MakeSymbolUpdater(s)
674		if l.SubSym(s) != 0 {
675			sb.SortSub()
676		}
677		if sb.Type() == sym.STEXT {
678			if l.AttrOnList(s) {
679				return errorf("symbol %s listed multiple times",
680					l.SymName(s))
681			}
682			l.SetAttrOnList(s, true)
683			textp = append(textp, s)
684			for ss := l.SubSym(s); ss != 0; ss = l.SubSym(ss) {
685				if l.AttrOnList(ss) {
686					return errorf("symbol %s listed multiple times",
687						l.SymName(ss))
688				}
689				l.SetAttrOnList(ss, true)
690				textp = append(textp, ss)
691			}
692		}
693	}
694
695	// load relocations
696	for i := uint(0); i < elfobj.nsect; i++ {
697		rsect := &elfobj.sect[i]
698		if rsect.type_ != elf.SHT_RELA && rsect.type_ != elf.SHT_REL {
699			continue
700		}
701		if rsect.info >= uint32(elfobj.nsect) || elfobj.sect[rsect.info].base == nil {
702			continue
703		}
704		sect = &elfobj.sect[rsect.info]
705		if err := elfmap(elfobj, rsect); err != nil {
706			return errorf("malformed elf file: %v", err)
707		}
708		rela := 0
709		if rsect.type_ == elf.SHT_RELA {
710			rela = 1
711		}
712		n := int(rsect.size / uint64(4+4*is64) / uint64(2+rela))
713		p := rsect.base
714		sb := l.MakeSymbolUpdater(sect.sym)
715		for j := 0; j < n; j++ {
716			var add uint64
717			var symIdx int
718			var relocType uint64
719			var rOff int32
720			var rAdd int64
721			var rSym loader.Sym
722
723			if is64 != 0 {
724				// 64-bit rel/rela
725				rOff = int32(e.Uint64(p))
726
727				p = p[8:]
728				switch arch.Family {
729				case sys.MIPS64:
730					// https://www.linux-mips.org/pub/linux/mips/doc/ABI/elf64-2.4.pdf
731					// The doc shows it's different with general Linux ELF
732					symIdx = int(e.Uint32(p))
733					relocType = uint64(p[7])
734				default:
735					info := e.Uint64(p)
736					relocType = info & 0xffffffff
737					symIdx = int(info >> 32)
738				}
739				p = p[8:]
740				if rela != 0 {
741					add = e.Uint64(p)
742					p = p[8:]
743				}
744			} else {
745				// 32-bit rel/rela
746				rOff = int32(e.Uint32(p))
747
748				p = p[4:]
749				info := e.Uint32(p)
750				relocType = uint64(info & 0xff)
751				symIdx = int(info >> 8)
752				p = p[4:]
753				if rela != 0 {
754					add = uint64(e.Uint32(p))
755					p = p[4:]
756				}
757			}
758
759			if relocType == 0 { // skip R_*_NONE relocation
760				j--
761				n--
762				continue
763			}
764
765			if symIdx == 0 { // absolute relocation, don't bother reading the null symbol
766				rSym = 0
767			} else {
768				var elfsym ElfSym
769				if err := readelfsym(l, arch, elfobj, int(symIdx), &elfsym, 0, 0); err != nil {
770					return errorf("malformed elf file: %v", err)
771				}
772				elfsym.sym = symbols[symIdx]
773				if elfsym.sym == 0 {
774					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_)
775				}
776
777				rSym = elfsym.sym
778			}
779
780			rType := objabi.ElfRelocOffset + objabi.RelocType(relocType)
781			rSize, addendSize, err := relSize(arch, pn, uint32(relocType))
782			if err != nil {
783				return nil, 0, err
784			}
785			if rela != 0 {
786				rAdd = int64(add)
787			} else {
788				// load addend from image
789				if rSize == 4 {
790					rAdd = int64(e.Uint32(sect.base[rOff:]))
791				} else if rSize == 8 {
792					rAdd = int64(e.Uint64(sect.base[rOff:]))
793				} else {
794					return errorf("invalid rela size %d", rSize)
795				}
796			}
797
798			if addendSize == 2 {
799				rAdd = int64(int16(rAdd))
800			}
801			if addendSize == 4 {
802				rAdd = int64(int32(rAdd))
803			}
804
805			r, _ := sb.AddRel(rType)
806			r.SetOff(rOff)
807			r.SetSiz(rSize)
808			r.SetSym(rSym)
809			r.SetAdd(rAdd)
810		}
811
812		sb.SortRelocs() // just in case
813	}
814
815	return textp, ehdrFlags, nil
816}
817
818func section(elfobj *ElfObj, name string) *ElfSect {
819	for i := 0; uint(i) < elfobj.nsect; i++ {
820		if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name {
821			return &elfobj.sect[i]
822		}
823	}
824	return nil
825}
826
827func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) {
828	if sect.base != nil {
829		return nil
830	}
831
832	if sect.off+sect.size > uint64(elfobj.length) {
833		err = fmt.Errorf("elf section past end of file")
834		return err
835	}
836
837	elfobj.f.MustSeek(int64(uint64(elfobj.base)+sect.off), 0)
838	sect.base, sect.readOnlyMem, err = elfobj.f.Slice(uint64(sect.size))
839	if err != nil {
840		return fmt.Errorf("short read: %v", err)
841	}
842
843	return nil
844}
845
846func readelfsym(l *loader.Loader, arch *sys.Arch, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, localSymVersion int) (err error) {
847	if i >= elfobj.nsymtab || i < 0 {
848		err = fmt.Errorf("invalid elf symbol index")
849		return err
850	}
851
852	if i == 0 {
853		return fmt.Errorf("readym: read null symbol!")
854	}
855
856	if elfobj.is64 != 0 {
857		b := new(elf.Sym64)
858		binary.Read(bytes.NewReader(elfobj.symtab.base[i*elf.Sym64Size:(i+1)*elf.Sym64Size]), elfobj.e, b)
859		elfsym.name = cstring(elfobj.symstr.base[b.Name:])
860		elfsym.value = b.Value
861		elfsym.size = b.Size
862		elfsym.shndx = elf.SectionIndex(b.Shndx)
863		elfsym.bind = elf.ST_BIND(b.Info)
864		elfsym.type_ = elf.ST_TYPE(b.Info)
865		elfsym.other = b.Other
866	} else {
867		b := new(elf.Sym32)
868		binary.Read(bytes.NewReader(elfobj.symtab.base[i*elf.Sym32Size:(i+1)*elf.Sym32Size]), elfobj.e, b)
869		elfsym.name = cstring(elfobj.symstr.base[b.Name:])
870		elfsym.value = uint64(b.Value)
871		elfsym.size = uint64(b.Size)
872		elfsym.shndx = elf.SectionIndex(b.Shndx)
873		elfsym.bind = elf.ST_BIND(b.Info)
874		elfsym.type_ = elf.ST_TYPE(b.Info)
875		elfsym.other = b.Other
876	}
877
878	var s loader.Sym
879
880	if elfsym.name == "_GLOBAL_OFFSET_TABLE_" {
881		elfsym.name = ".got"
882	}
883	if elfsym.name == ".TOC." {
884		// Magic symbol on ppc64.  Will be set to this object
885		// file's .got+0x8000.
886		elfsym.bind = elf.STB_LOCAL
887	}
888
889	switch elfsym.type_ {
890	case elf.STT_SECTION:
891		s = elfobj.sect[elfsym.shndx].sym
892
893	case elf.STT_OBJECT, elf.STT_FUNC, elf.STT_NOTYPE, elf.STT_COMMON:
894		switch elfsym.bind {
895		case elf.STB_GLOBAL:
896			if needSym != 0 {
897				s = l.LookupOrCreateCgoExport(elfsym.name, 0)
898
899				// for global scoped hidden symbols we should insert it into
900				// symbol hash table, but mark them as hidden.
901				// __i686.get_pc_thunk.bx is allowed to be duplicated, to
902				// workaround that we set dupok.
903				// TODO(minux): correctly handle __i686.get_pc_thunk.bx without
904				// set dupok generally. See https://golang.org/cl/5823055
905				// comment #5 for details.
906				if s != 0 && elfsym.other == 2 {
907					if !l.IsExternal(s) {
908						l.MakeSymbolUpdater(s)
909					}
910					l.SetAttrDuplicateOK(s, true)
911					l.SetAttrVisibilityHidden(s, true)
912				}
913			}
914
915		case elf.STB_LOCAL:
916			if (arch.Family == sys.ARM || arch.Family == sys.ARM64) && (strings.HasPrefix(elfsym.name, "$a") || strings.HasPrefix(elfsym.name, "$d") || strings.HasPrefix(elfsym.name, "$x")) {
917				// binutils for arm and arm64 generate these mapping
918				// symbols, ignore these
919				break
920			}
921
922			if elfsym.name == ".TOC." {
923				// We need to be able to look this up,
924				// so put it in the hash table.
925				if needSym != 0 {
926					s = l.LookupOrCreateCgoExport(elfsym.name, localSymVersion)
927					l.SetAttrVisibilityHidden(s, true)
928				}
929				break
930			}
931
932			if needSym != 0 {
933				// local names and hidden global names are unique
934				// and should only be referenced by their index, not name, so we
935				// don't bother to add them into the hash table
936				// FIXME: pass empty string here for name? This would
937				// reduce mem use, but also (possibly) make it harder
938				// to debug problems.
939				s = l.CreateStaticSym(elfsym.name)
940				l.SetAttrVisibilityHidden(s, true)
941			}
942
943		case elf.STB_WEAK:
944			if needSym != 0 {
945				s = l.LookupOrCreateCgoExport(elfsym.name, 0)
946				if elfsym.other == 2 {
947					l.SetAttrVisibilityHidden(s, true)
948				}
949
950				// Allow weak symbols to be duplicated when already defined.
951				if l.OuterSym(s) != 0 {
952					l.SetAttrDuplicateOK(s, true)
953				}
954			}
955
956		default:
957			err = fmt.Errorf("%s: invalid symbol binding %d", elfsym.name, elfsym.bind)
958			return err
959		}
960	}
961
962	if s != 0 && l.SymType(s) == 0 && elfsym.type_ != elf.STT_SECTION {
963		sb := l.MakeSymbolUpdater(s)
964		sb.SetType(sym.SXREF)
965	}
966	elfsym.sym = s
967
968	return nil
969}
970
971// Return the size of the relocated field, and the size of the addend as the first
972// and second values. Note, the addend may be larger than the relocation field in
973// some cases when a relocated value is split across multiple relocations.
974func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, uint8, error) {
975	// TODO(mdempsky): Replace this with a struct-valued switch statement
976	// once golang.org/issue/15164 is fixed or found to not impair cmd/link
977	// performance.
978
979	const (
980		AMD64   = uint32(sys.AMD64)
981		ARM     = uint32(sys.ARM)
982		ARM64   = uint32(sys.ARM64)
983		I386    = uint32(sys.I386)
984		LOONG64 = uint32(sys.Loong64)
985		MIPS    = uint32(sys.MIPS)
986		MIPS64  = uint32(sys.MIPS64)
987		PPC64   = uint32(sys.PPC64)
988		RISCV64 = uint32(sys.RISCV64)
989		S390X   = uint32(sys.S390X)
990	)
991
992	switch uint32(arch.Family) | elftype<<16 {
993	default:
994		return 0, 0, fmt.Errorf("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
995
996	case MIPS | uint32(elf.R_MIPS_HI16)<<16,
997		MIPS | uint32(elf.R_MIPS_LO16)<<16,
998		MIPS | uint32(elf.R_MIPS_GOT16)<<16,
999		MIPS | uint32(elf.R_MIPS_GOT_HI16)<<16,
1000		MIPS | uint32(elf.R_MIPS_GOT_LO16)<<16,
1001		MIPS | uint32(elf.R_MIPS_GPREL16)<<16,
1002		MIPS | uint32(elf.R_MIPS_GOT_PAGE)<<16,
1003		MIPS | uint32(elf.R_MIPS_JALR)<<16,
1004		MIPS | uint32(elf.R_MIPS_GOT_OFST)<<16,
1005		MIPS64 | uint32(elf.R_MIPS_HI16)<<16,
1006		MIPS64 | uint32(elf.R_MIPS_LO16)<<16,
1007		MIPS64 | uint32(elf.R_MIPS_GOT16)<<16,
1008		MIPS64 | uint32(elf.R_MIPS_GOT_HI16)<<16,
1009		MIPS64 | uint32(elf.R_MIPS_GOT_LO16)<<16,
1010		MIPS64 | uint32(elf.R_MIPS_GPREL16)<<16,
1011		MIPS64 | uint32(elf.R_MIPS_GOT_PAGE)<<16,
1012		MIPS64 | uint32(elf.R_MIPS_JALR)<<16,
1013		MIPS64 | uint32(elf.R_MIPS_GOT_OFST)<<16,
1014		MIPS64 | uint32(elf.R_MIPS_CALL16)<<16,
1015		MIPS64 | uint32(elf.R_MIPS_GPREL32)<<16,
1016		MIPS64 | uint32(elf.R_MIPS_64)<<16,
1017		MIPS64 | uint32(elf.R_MIPS_GOT_DISP)<<16,
1018		MIPS64 | uint32(elf.R_MIPS_PC32)<<16:
1019		return 4, 4, nil
1020
1021	case LOONG64 | uint32(elf.R_LARCH_ADD8)<<16,
1022		LOONG64 | uint32(elf.R_LARCH_SUB8)<<16:
1023		return 1, 1, nil
1024
1025	case LOONG64 | uint32(elf.R_LARCH_ADD16)<<16,
1026		LOONG64 | uint32(elf.R_LARCH_SUB16)<<16:
1027		return 2, 2, nil
1028
1029	case LOONG64 | uint32(elf.R_LARCH_SOP_PUSH_PCREL)<<16,
1030		LOONG64 | uint32(elf.R_LARCH_SOP_PUSH_GPREL)<<16,
1031		LOONG64 | uint32(elf.R_LARCH_SOP_PUSH_ABSOLUTE)<<16,
1032		LOONG64 | uint32(elf.R_LARCH_MARK_LA)<<16,
1033		LOONG64 | uint32(elf.R_LARCH_SOP_POP_32_S_0_10_10_16_S2)<<16,
1034		LOONG64 | uint32(elf.R_LARCH_MARK_PCREL)<<16,
1035		LOONG64 | uint32(elf.R_LARCH_ADD24)<<16,
1036		LOONG64 | uint32(elf.R_LARCH_ADD32)<<16,
1037		LOONG64 | uint32(elf.R_LARCH_SUB24)<<16,
1038		LOONG64 | uint32(elf.R_LARCH_SUB32)<<16,
1039		LOONG64 | uint32(elf.R_LARCH_B26)<<16,
1040		LOONG64 | uint32(elf.R_LARCH_32_PCREL)<<16:
1041		return 4, 4, nil
1042
1043	case LOONG64 | uint32(elf.R_LARCH_64)<<16,
1044		LOONG64 | uint32(elf.R_LARCH_ADD64)<<16,
1045		LOONG64 | uint32(elf.R_LARCH_SUB64)<<16,
1046		LOONG64 | uint32(elf.R_LARCH_64_PCREL)<<16:
1047		return 8, 8, nil
1048
1049	case S390X | uint32(elf.R_390_8)<<16:
1050		return 1, 1, nil
1051
1052	case PPC64 | uint32(elf.R_PPC64_TOC16)<<16,
1053		S390X | uint32(elf.R_390_16)<<16,
1054		S390X | uint32(elf.R_390_GOT16)<<16,
1055		S390X | uint32(elf.R_390_PC16)<<16,
1056		S390X | uint32(elf.R_390_PC16DBL)<<16,
1057		S390X | uint32(elf.R_390_PLT16DBL)<<16:
1058		return 2, 2, nil
1059
1060	case ARM | uint32(elf.R_ARM_ABS32)<<16,
1061		ARM | uint32(elf.R_ARM_GOT32)<<16,
1062		ARM | uint32(elf.R_ARM_PLT32)<<16,
1063		ARM | uint32(elf.R_ARM_GOTOFF)<<16,
1064		ARM | uint32(elf.R_ARM_GOTPC)<<16,
1065		ARM | uint32(elf.R_ARM_THM_PC22)<<16,
1066		ARM | uint32(elf.R_ARM_REL32)<<16,
1067		ARM | uint32(elf.R_ARM_CALL)<<16,
1068		ARM | uint32(elf.R_ARM_V4BX)<<16,
1069		ARM | uint32(elf.R_ARM_GOT_PREL)<<16,
1070		ARM | uint32(elf.R_ARM_PC24)<<16,
1071		ARM | uint32(elf.R_ARM_JUMP24)<<16,
1072		ARM64 | uint32(elf.R_AARCH64_CALL26)<<16,
1073		ARM64 | uint32(elf.R_AARCH64_ADR_GOT_PAGE)<<16,
1074		ARM64 | uint32(elf.R_AARCH64_LD64_GOT_LO12_NC)<<16,
1075		ARM64 | uint32(elf.R_AARCH64_ADR_PREL_PG_HI21)<<16,
1076		ARM64 | uint32(elf.R_AARCH64_ADD_ABS_LO12_NC)<<16,
1077		ARM64 | uint32(elf.R_AARCH64_LDST8_ABS_LO12_NC)<<16,
1078		ARM64 | uint32(elf.R_AARCH64_LDST16_ABS_LO12_NC)<<16,
1079		ARM64 | uint32(elf.R_AARCH64_LDST32_ABS_LO12_NC)<<16,
1080		ARM64 | uint32(elf.R_AARCH64_LDST64_ABS_LO12_NC)<<16,
1081		ARM64 | uint32(elf.R_AARCH64_LDST128_ABS_LO12_NC)<<16,
1082		ARM64 | uint32(elf.R_AARCH64_PREL32)<<16,
1083		ARM64 | uint32(elf.R_AARCH64_JUMP26)<<16,
1084		AMD64 | uint32(elf.R_X86_64_PC32)<<16,
1085		AMD64 | uint32(elf.R_X86_64_PLT32)<<16,
1086		AMD64 | uint32(elf.R_X86_64_GOTPCREL)<<16,
1087		AMD64 | uint32(elf.R_X86_64_GOTPCRELX)<<16,
1088		AMD64 | uint32(elf.R_X86_64_REX_GOTPCRELX)<<16,
1089		I386 | uint32(elf.R_386_32)<<16,
1090		I386 | uint32(elf.R_386_PC32)<<16,
1091		I386 | uint32(elf.R_386_GOT32)<<16,
1092		I386 | uint32(elf.R_386_PLT32)<<16,
1093		I386 | uint32(elf.R_386_GOTOFF)<<16,
1094		I386 | uint32(elf.R_386_GOTPC)<<16,
1095		I386 | uint32(elf.R_386_GOT32X)<<16,
1096		PPC64 | uint32(elf.R_PPC64_REL24)<<16,
1097		PPC64 | uint32(elf.R_PPC64_REL24_NOTOC)<<16,
1098		PPC64 | uint32(elf.R_PPC64_REL24_P9NOTOC)<<16,
1099		PPC64 | uint32(elf.R_PPC_REL32)<<16,
1100		S390X | uint32(elf.R_390_32)<<16,
1101		S390X | uint32(elf.R_390_PC32)<<16,
1102		S390X | uint32(elf.R_390_GOT32)<<16,
1103		S390X | uint32(elf.R_390_PLT32)<<16,
1104		S390X | uint32(elf.R_390_PC32DBL)<<16,
1105		S390X | uint32(elf.R_390_PLT32DBL)<<16,
1106		S390X | uint32(elf.R_390_GOTPCDBL)<<16,
1107		S390X | uint32(elf.R_390_GOTENT)<<16:
1108		return 4, 4, nil
1109
1110	case AMD64 | uint32(elf.R_X86_64_64)<<16,
1111		AMD64 | uint32(elf.R_X86_64_PC64)<<16,
1112		ARM64 | uint32(elf.R_AARCH64_ABS64)<<16,
1113		ARM64 | uint32(elf.R_AARCH64_PREL64)<<16,
1114		PPC64 | uint32(elf.R_PPC64_ADDR64)<<16,
1115		PPC64 | uint32(elf.R_PPC64_PCREL34)<<16,
1116		PPC64 | uint32(elf.R_PPC64_GOT_PCREL34)<<16,
1117		PPC64 | uint32(elf.R_PPC64_PLT_PCREL34_NOTOC)<<16,
1118		S390X | uint32(elf.R_390_GLOB_DAT)<<16,
1119		S390X | uint32(elf.R_390_RELATIVE)<<16,
1120		S390X | uint32(elf.R_390_GOTOFF)<<16,
1121		S390X | uint32(elf.R_390_GOTPC)<<16,
1122		S390X | uint32(elf.R_390_64)<<16,
1123		S390X | uint32(elf.R_390_PC64)<<16,
1124		S390X | uint32(elf.R_390_GOT64)<<16,
1125		S390X | uint32(elf.R_390_PLT64)<<16:
1126		return 8, 8, nil
1127
1128	case RISCV64 | uint32(elf.R_RISCV_SET6)<<16,
1129		RISCV64 | uint32(elf.R_RISCV_SUB6)<<16,
1130		RISCV64 | uint32(elf.R_RISCV_SET8)<<16,
1131		RISCV64 | uint32(elf.R_RISCV_SUB8)<<16:
1132		return 1, 1, nil
1133
1134	case RISCV64 | uint32(elf.R_RISCV_RVC_BRANCH)<<16,
1135		RISCV64 | uint32(elf.R_RISCV_RVC_JUMP)<<16,
1136		RISCV64 | uint32(elf.R_RISCV_SET16)<<16,
1137		RISCV64 | uint32(elf.R_RISCV_SUB16)<<16:
1138		return 2, 2, nil
1139
1140	case RISCV64 | uint32(elf.R_RISCV_32)<<16,
1141		RISCV64 | uint32(elf.R_RISCV_BRANCH)<<16,
1142		RISCV64 | uint32(elf.R_RISCV_HI20)<<16,
1143		RISCV64 | uint32(elf.R_RISCV_LO12_I)<<16,
1144		RISCV64 | uint32(elf.R_RISCV_LO12_S)<<16,
1145		RISCV64 | uint32(elf.R_RISCV_GOT_HI20)<<16,
1146		RISCV64 | uint32(elf.R_RISCV_PCREL_HI20)<<16,
1147		RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_I)<<16,
1148		RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_S)<<16,
1149		RISCV64 | uint32(elf.R_RISCV_ADD32)<<16,
1150		RISCV64 | uint32(elf.R_RISCV_SET32)<<16,
1151		RISCV64 | uint32(elf.R_RISCV_SUB32)<<16,
1152		RISCV64 | uint32(elf.R_RISCV_32_PCREL)<<16,
1153		RISCV64 | uint32(elf.R_RISCV_RELAX)<<16:
1154		return 4, 4, nil
1155
1156	case RISCV64 | uint32(elf.R_RISCV_64)<<16,
1157		RISCV64 | uint32(elf.R_RISCV_CALL)<<16,
1158		RISCV64 | uint32(elf.R_RISCV_CALL_PLT)<<16:
1159		return 8, 8, nil
1160
1161	case PPC64 | uint32(elf.R_PPC64_TOC16_LO)<<16,
1162		PPC64 | uint32(elf.R_PPC64_TOC16_HI)<<16,
1163		PPC64 | uint32(elf.R_PPC64_TOC16_HA)<<16,
1164		PPC64 | uint32(elf.R_PPC64_TOC16_DS)<<16,
1165		PPC64 | uint32(elf.R_PPC64_TOC16_LO_DS)<<16,
1166		PPC64 | uint32(elf.R_PPC64_REL16_LO)<<16,
1167		PPC64 | uint32(elf.R_PPC64_REL16_HI)<<16,
1168		PPC64 | uint32(elf.R_PPC64_REL16_HA)<<16,
1169		PPC64 | uint32(elf.R_PPC64_PLT16_HA)<<16,
1170		PPC64 | uint32(elf.R_PPC64_PLT16_LO_DS)<<16:
1171		return 2, 4, nil
1172
1173	// PPC64 inline PLT sequence hint relocations (-fno-plt)
1174	// These are informational annotations to assist linker optimizations.
1175	case PPC64 | uint32(elf.R_PPC64_PLTSEQ)<<16,
1176		PPC64 | uint32(elf.R_PPC64_PLTCALL)<<16,
1177		PPC64 | uint32(elf.R_PPC64_PLTCALL_NOTOC)<<16,
1178		PPC64 | uint32(elf.R_PPC64_PLTSEQ_NOTOC)<<16:
1179		return 0, 0, nil
1180
1181	}
1182}
1183
1184func cstring(x []byte) string {
1185	i := bytes.IndexByte(x, '\x00')
1186	if i >= 0 {
1187		x = x[:i]
1188	}
1189	return string(x)
1190}
1191