Home | History | Annotate | Download | only in ld
      1 package ld
      2 
      3 import (
      4 	"bytes"
      5 	"cmd/internal/bio"
      6 	"cmd/internal/obj"
      7 	"cmd/internal/sys"
      8 	"encoding/binary"
      9 	"fmt"
     10 	"io"
     11 	"log"
     12 	"sort"
     13 	"strings"
     14 )
     15 
     16 /*
     17 Derived from Plan 9 from User Space's src/libmach/elf.h, elf.c
     18 http://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 
     24 Permission is hereby granted, free of charge, to any person obtaining a copy
     25 of this software and associated documentation files (the "Software"), to deal
     26 in the Software without restriction, including without limitation the rights
     27 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     28 copies of the Software, and to permit persons to whom the Software is
     29 furnished to do so, subject to the following conditions:
     30 
     31 The above copyright notice and this permission notice shall be included in
     32 all copies or substantial portions of the Software.
     33 
     34 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     35 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     36 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
     37 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     38 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     39 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     40 THE SOFTWARE.
     41 */
     42 const (
     43 	ElfClassNone = 0
     44 	ElfClass32   = 1
     45 	ElfClass64   = 2
     46 )
     47 
     48 const (
     49 	ElfDataNone = 0
     50 	ElfDataLsb  = 1
     51 	ElfDataMsb  = 2
     52 )
     53 
     54 const (
     55 	ElfTypeNone         = 0
     56 	ElfTypeRelocatable  = 1
     57 	ElfTypeExecutable   = 2
     58 	ElfTypeSharedObject = 3
     59 	ElfTypeCore         = 4
     60 )
     61 
     62 const (
     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 
     93 const (
     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 
    110 const (
    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 
    128 const (
    129 	ElfSymBindLocal  = 0
    130 	ElfSymBindGlobal = 1
    131 	ElfSymBindWeak   = 2
    132 )
    133 
    134 const (
    135 	ElfSymTypeNone    = 0
    136 	ElfSymTypeObject  = 1
    137 	ElfSymTypeFunc    = 2
    138 	ElfSymTypeSection = 3
    139 	ElfSymTypeFile    = 4
    140 	ElfSymTypeCommon  = 5
    141 	ElfSymTypeTLS     = 6
    142 )
    143 
    144 const (
    145 	ElfSymShnNone   = 0
    146 	ElfSymShnAbs    = 0xFFF1
    147 	ElfSymShnCommon = 0xFFF2
    148 )
    149 
    150 const (
    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 
    163 const (
    164 	ElfNotePrStatus     = 1
    165 	ElfNotePrFpreg      = 2
    166 	ElfNotePrPsinfo     = 3
    167 	ElfNotePrTaskstruct = 4
    168 	ElfNotePrAuxv       = 6
    169 	ElfNotePrXfpreg     = 0x46e62b7f
    170 )
    171 
    172 type 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 
    189 type 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 
    202 type ElfProgBytes struct {
    203 }
    204 
    205 type 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 
    214 type 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 
    231 type 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 
    244 type ElfProgBytes64 struct {
    245 }
    246 
    247 type 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 
    256 type 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 
    272 type 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 
    300 type 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 
    311 var ElfMagic = [4]uint8{0x7F, 'E', 'L', 'F'}
    312 
    313 const (
    314 	TagFile               = 1
    315 	TagCPUName            = 4
    316 	TagCPURawName         = 5
    317 	TagCompatibility      = 32
    318 	TagNoDefaults         = 64
    319 	TagAlsoCompatibleWith = 65
    320 	TagABIVFPArgs         = 28
    321 )
    322 
    323 type elfAttribute struct {
    324 	tag  uint64
    325 	sval string
    326 	ival uint64
    327 }
    328 
    329 type elfAttributeList struct {
    330 	data []byte
    331 	err  error
    332 }
    333 
    334 func (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 
    348 func (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.
    358 func (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 
    381 func (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.
    394 func 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 
    445 func 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", obj.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 err error
    457 	var flag int
    458 	var hdr *ElfHdrBytes
    459 	var hdrbuf [64]uint8
    460 	var info uint64
    461 	var is64 int
    462 	var j int
    463 	var n int
    464 	var name string
    465 	var p []byte
    466 	var r []Reloc
    467 	var rela int
    468 	var rp *Reloc
    469 	var rsect *ElfSect
    470 	var s *Symbol
    471 	var sect *ElfSect
    472 	var sym ElfSym
    473 	var symbols []*Symbol
    474 	if _, err := io.ReadFull(f, hdrbuf[:]); err != nil {
    475 		goto bad
    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 		goto bad
    481 	}
    482 	switch hdr.Ident[5] {
    483 	case ElfDataLsb:
    484 		e = binary.LittleEndian
    485 
    486 	case ElfDataMsb:
    487 		e = binary.BigEndian
    488 
    489 	default:
    490 		goto bad
    491 	}
    492 
    493 	// read header
    494 	elfobj = new(ElfObj)
    495 
    496 	elfobj.e = e
    497 	elfobj.f = f
    498 	elfobj.base = base
    499 	elfobj.length = length
    500 	elfobj.name = pn
    501 
    502 	is64 = 0
    503 	if hdr.Ident[4] == ElfClass64 {
    504 		is64 = 1
    505 		hdr := new(ElfHdrBytes64)
    506 		binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter
    507 		elfobj.type_ = uint32(e.Uint16(hdr.Type[:]))
    508 		elfobj.machine = uint32(e.Uint16(hdr.Machine[:]))
    509 		elfobj.version = e.Uint32(hdr.Version[:])
    510 		elfobj.phoff = e.Uint64(hdr.Phoff[:])
    511 		elfobj.shoff = e.Uint64(hdr.Shoff[:])
    512 		elfobj.flags = e.Uint32(hdr.Flags[:])
    513 		elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:]))
    514 		elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:]))
    515 		elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:]))
    516 		elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:]))
    517 		elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:]))
    518 		elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:]))
    519 	} else {
    520 		elfobj.type_ = uint32(e.Uint16(hdr.Type[:]))
    521 		elfobj.machine = uint32(e.Uint16(hdr.Machine[:]))
    522 		elfobj.version = e.Uint32(hdr.Version[:])
    523 		elfobj.entry = uint64(e.Uint32(hdr.Entry[:]))
    524 		elfobj.phoff = uint64(e.Uint32(hdr.Phoff[:]))
    525 		elfobj.shoff = uint64(e.Uint32(hdr.Shoff[:]))
    526 		elfobj.flags = e.Uint32(hdr.Flags[:])
    527 		elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:]))
    528 		elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:]))
    529 		elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:]))
    530 		elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:]))
    531 		elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:]))
    532 		elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:]))
    533 	}
    534 
    535 	elfobj.is64 = is64
    536 
    537 	if uint32(hdr.Ident[6]) != elfobj.version {
    538 		goto bad
    539 	}
    540 
    541 	if e.Uint16(hdr.Type[:]) != ElfTypeRelocatable {
    542 		Errorf(nil, "%s: elf but not elf relocatable object", pn)
    543 		return
    544 	}
    545 
    546 	switch SysArch.Family {
    547 	default:
    548 		Errorf(nil, "%s: elf %s unimplemented", pn, SysArch.Name)
    549 		return
    550 
    551 	case sys.MIPS:
    552 		if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass32 {
    553 			Errorf(nil, "%s: elf object but not mips", pn)
    554 			return
    555 		}
    556 
    557 	case sys.MIPS64:
    558 		if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass64 {
    559 			Errorf(nil, "%s: elf object but not mips64", pn)
    560 			return
    561 		}
    562 
    563 	case sys.ARM:
    564 		if e != binary.LittleEndian || elfobj.machine != ElfMachArm || hdr.Ident[4] != ElfClass32 {
    565 			Errorf(nil, "%s: elf object but not arm", pn)
    566 			return
    567 		}
    568 
    569 	case sys.AMD64:
    570 		if e != binary.LittleEndian || elfobj.machine != ElfMachAmd64 || hdr.Ident[4] != ElfClass64 {
    571 			Errorf(nil, "%s: elf object but not amd64", pn)
    572 			return
    573 		}
    574 
    575 	case sys.ARM64:
    576 		if e != binary.LittleEndian || elfobj.machine != ElfMachArm64 || hdr.Ident[4] != ElfClass64 {
    577 			Errorf(nil, "%s: elf object but not arm64", pn)
    578 			return
    579 		}
    580 
    581 	case sys.I386:
    582 		if e != binary.LittleEndian || elfobj.machine != ElfMach386 || hdr.Ident[4] != ElfClass32 {
    583 			Errorf(nil, "%s: elf object but not 386", pn)
    584 			return
    585 		}
    586 
    587 	case sys.PPC64:
    588 		if elfobj.machine != ElfMachPower64 || hdr.Ident[4] != ElfClass64 {
    589 			Errorf(nil, "%s: elf object but not ppc64", pn)
    590 			return
    591 		}
    592 
    593 	case sys.S390X:
    594 		if elfobj.machine != ElfMachS390 || hdr.Ident[4] != ElfClass64 {
    595 			Errorf(nil, "%s: elf object but not s390x", pn)
    596 			return
    597 		}
    598 	}
    599 
    600 	// load section list into memory.
    601 	elfobj.sect = make([]ElfSect, elfobj.shnum)
    602 
    603 	elfobj.nsect = uint(elfobj.shnum)
    604 	for i := 0; uint(i) < elfobj.nsect; i++ {
    605 		if f.Seek(int64(uint64(base)+elfobj.shoff+uint64(int64(i)*int64(elfobj.shentsize))), 0) < 0 {
    606 			goto bad
    607 		}
    608 		sect = &elfobj.sect[i]
    609 		if is64 != 0 {
    610 			var b ElfSectBytes64
    611 
    612 			if err = binary.Read(f, e, &b); err != nil {
    613 				goto bad
    614 			}
    615 
    616 			sect.nameoff = e.Uint32(b.Name[:])
    617 			sect.type_ = e.Uint32(b.Type[:])
    618 			sect.flags = e.Uint64(b.Flags[:])
    619 			sect.addr = e.Uint64(b.Addr[:])
    620 			sect.off = e.Uint64(b.Off[:])
    621 			sect.size = e.Uint64(b.Size[:])
    622 			sect.link = e.Uint32(b.Link[:])
    623 			sect.info = e.Uint32(b.Info[:])
    624 			sect.align = e.Uint64(b.Align[:])
    625 			sect.entsize = e.Uint64(b.Entsize[:])
    626 		} else {
    627 			var b ElfSectBytes
    628 
    629 			if err = binary.Read(f, e, &b); err != nil {
    630 				goto bad
    631 			}
    632 
    633 			sect.nameoff = e.Uint32(b.Name[:])
    634 			sect.type_ = e.Uint32(b.Type[:])
    635 			sect.flags = uint64(e.Uint32(b.Flags[:]))
    636 			sect.addr = uint64(e.Uint32(b.Addr[:]))
    637 			sect.off = uint64(e.Uint32(b.Off[:]))
    638 			sect.size = uint64(e.Uint32(b.Size[:]))
    639 			sect.link = e.Uint32(b.Link[:])
    640 			sect.info = e.Uint32(b.Info[:])
    641 			sect.align = uint64(e.Uint32(b.Align[:]))
    642 			sect.entsize = uint64(e.Uint32(b.Entsize[:]))
    643 		}
    644 	}
    645 
    646 	// read section string table and translate names
    647 	if elfobj.shstrndx >= uint32(elfobj.nsect) {
    648 		err = fmt.Errorf("shstrndx out of range %d >= %d", elfobj.shstrndx, elfobj.nsect)
    649 		goto bad
    650 	}
    651 
    652 	sect = &elfobj.sect[elfobj.shstrndx]
    653 	if err = elfmap(elfobj, sect); err != nil {
    654 		goto bad
    655 	}
    656 	for i := 0; uint(i) < elfobj.nsect; i++ {
    657 		if elfobj.sect[i].nameoff != 0 {
    658 			elfobj.sect[i].name = cstring(sect.base[elfobj.sect[i].nameoff:])
    659 		}
    660 	}
    661 
    662 	// load string table for symbols into memory.
    663 	elfobj.symtab = section(elfobj, ".symtab")
    664 
    665 	if elfobj.symtab == nil {
    666 		// our work is done here - no symbols means nothing can refer to this file
    667 		return
    668 	}
    669 
    670 	if elfobj.symtab.link <= 0 || elfobj.symtab.link >= uint32(elfobj.nsect) {
    671 		Errorf(nil, "%s: elf object has symbol table with invalid string table link", pn)
    672 		return
    673 	}
    674 
    675 	elfobj.symstr = &elfobj.sect[elfobj.symtab.link]
    676 	if is64 != 0 {
    677 		elfobj.nsymtab = int(elfobj.symtab.size / ELF64SYMSIZE)
    678 	} else {
    679 		elfobj.nsymtab = int(elfobj.symtab.size / ELF32SYMSIZE)
    680 	}
    681 
    682 	if err = elfmap(elfobj, elfobj.symtab); err != nil {
    683 		goto bad
    684 	}
    685 	if err = elfmap(elfobj, elfobj.symstr); err != nil {
    686 		goto bad
    687 	}
    688 
    689 	// load text and data segments into memory.
    690 	// they are not as small as the section lists, but we'll need
    691 	// the memory anyway for the symbol images, so we might
    692 	// as well use one large chunk.
    693 
    694 	// create symbols for elfmapped sections
    695 	for i := 0; uint(i) < elfobj.nsect; i++ {
    696 		sect = &elfobj.sect[i]
    697 		if sect.type_ == SHT_ARM_ATTRIBUTES && sect.name == ".ARM.attributes" {
    698 			if err = elfmap(elfobj, sect); err != nil {
    699 				goto bad
    700 			}
    701 			parseArmAttributes(ctxt, e, sect.base[:sect.size])
    702 		}
    703 		if (sect.type_ != ElfSectProgbits && sect.type_ != ElfSectNobits) || sect.flags&ElfSectFlagAlloc == 0 {
    704 			continue
    705 		}
    706 		if sect.type_ != ElfSectNobits {
    707 			if err = elfmap(elfobj, sect); err != nil {
    708 				goto bad
    709 			}
    710 		}
    711 
    712 		name = fmt.Sprintf("%s(%s)", pkg, sect.name)
    713 		s = ctxt.Syms.Lookup(name, localSymVersion)
    714 
    715 		switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) {
    716 		default:
    717 			err = fmt.Errorf("unexpected flags for ELF section %s", sect.name)
    718 			goto bad
    719 
    720 		case ElfSectFlagAlloc:
    721 			s.Type = obj.SRODATA
    722 
    723 		case ElfSectFlagAlloc + ElfSectFlagWrite:
    724 			if sect.type_ == ElfSectNobits {
    725 				s.Type = obj.SNOPTRBSS
    726 			} else {
    727 				s.Type = obj.SNOPTRDATA
    728 			}
    729 
    730 		case ElfSectFlagAlloc + ElfSectFlagExec:
    731 			s.Type = obj.STEXT
    732 		}
    733 
    734 		if sect.name == ".got" || sect.name == ".toc" {
    735 			s.Type = obj.SELFGOT
    736 		}
    737 		if sect.type_ == ElfSectProgbits {
    738 			s.P = sect.base
    739 			s.P = s.P[:sect.size]
    740 		}
    741 
    742 		s.Size = int64(sect.size)
    743 		s.Align = int32(sect.align)
    744 		sect.sym = s
    745 	}
    746 
    747 	// enter sub-symbols into symbol table.
    748 	// symbol 0 is the null symbol.
    749 	symbols = make([]*Symbol, elfobj.nsymtab)
    750 
    751 	for i := 1; i < elfobj.nsymtab; i++ {
    752 		if err = readelfsym(ctxt, elfobj, i, &sym, 1, localSymVersion); err != nil {
    753 			goto bad
    754 		}
    755 		symbols[i] = sym.sym
    756 		if sym.type_ != ElfSymTypeFunc && sym.type_ != ElfSymTypeObject && sym.type_ != ElfSymTypeNone && sym.type_ != ElfSymTypeCommon {
    757 			continue
    758 		}
    759 		if sym.shndx == ElfSymShnCommon || sym.type_ == ElfSymTypeCommon {
    760 			s = sym.sym
    761 			if uint64(s.Size) < sym.size {
    762 				s.Size = int64(sym.size)
    763 			}
    764 			if s.Type == 0 || s.Type == obj.SXREF {
    765 				s.Type = obj.SNOPTRBSS
    766 			}
    767 			continue
    768 		}
    769 
    770 		if uint(sym.shndx) >= elfobj.nsect || sym.shndx == 0 {
    771 			continue
    772 		}
    773 
    774 		// even when we pass needSym == 1 to readelfsym, it might still return nil to skip some unwanted symbols
    775 		if sym.sym == nil {
    776 			continue
    777 		}
    778 		sect = &elfobj.sect[sym.shndx]
    779 		if sect.sym == nil {
    780 			if strings.HasPrefix(sym.name, ".Linfo_string") { // clang does this
    781 				continue
    782 			}
    783 
    784 			if sym.name == "" && sym.type_ == 0 && sect.name == ".debug_str" {
    785 				// This reportedly happens with clang 3.7 on ARM.
    786 				// See issue 13139.
    787 				continue
    788 			}
    789 
    790 			if strings.HasPrefix(sym.name, ".LASF") { // gcc on s390x does this
    791 				continue
    792 			}
    793 			Errorf(sym.sym, "%s: sym#%d: ignoring symbol in section %d (type %d)", pn, i, sym.shndx, sym.type_)
    794 			continue
    795 		}
    796 
    797 		s = sym.sym
    798 		if s.Outer != nil {
    799 			if s.Attr.DuplicateOK() {
    800 				continue
    801 			}
    802 			Exitf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name)
    803 		}
    804 
    805 		s.Sub = sect.sym.Sub
    806 		sect.sym.Sub = s
    807 		s.Type = sect.sym.Type | s.Type&^obj.SMASK | obj.SSUB
    808 		if !s.Attr.CgoExportDynamic() {
    809 			s.Dynimplib = "" // satisfy dynimport
    810 		}
    811 		s.Value = int64(sym.value)
    812 		s.Size = int64(sym.size)
    813 		s.Outer = sect.sym
    814 		if sect.sym.Type == obj.STEXT {
    815 			if s.Attr.External() && !s.Attr.DuplicateOK() {
    816 				Errorf(s, "%s: duplicate symbol definition", pn)
    817 			}
    818 			s.Attr |= AttrExternal
    819 		}
    820 
    821 		if elfobj.machine == ElfMachPower64 {
    822 			flag = int(sym.other) >> 5
    823 			if 2 <= flag && flag <= 6 {
    824 				s.Localentry = 1 << uint(flag-2)
    825 			} else if flag == 7 {
    826 				Errorf(s, "%s: invalid sym.other 0x%x", pn, sym.other)
    827 			}
    828 		}
    829 	}
    830 
    831 	// Sort outer lists by address, adding to textp.
    832 	// This keeps textp in increasing address order.
    833 	for i := 0; uint(i) < elfobj.nsect; i++ {
    834 		s = elfobj.sect[i].sym
    835 		if s == nil {
    836 			continue
    837 		}
    838 		if s.Sub != nil {
    839 			s.Sub = listsort(s.Sub)
    840 		}
    841 		if s.Type == obj.STEXT {
    842 			if s.Attr.OnList() {
    843 				log.Fatalf("symbol %s listed multiple times", s.Name)
    844 			}
    845 			s.Attr |= AttrOnList
    846 			ctxt.Textp = append(ctxt.Textp, s)
    847 			for s = s.Sub; s != nil; s = s.Sub {
    848 				if s.Attr.OnList() {
    849 					log.Fatalf("symbol %s listed multiple times", s.Name)
    850 				}
    851 				s.Attr |= AttrOnList
    852 				ctxt.Textp = append(ctxt.Textp, s)
    853 			}
    854 		}
    855 	}
    856 
    857 	// load relocations
    858 	for i := 0; uint(i) < elfobj.nsect; i++ {
    859 		rsect = &elfobj.sect[i]
    860 		if rsect.type_ != ElfSectRela && rsect.type_ != ElfSectRel {
    861 			continue
    862 		}
    863 		if rsect.info >= uint32(elfobj.nsect) || elfobj.sect[rsect.info].base == nil {
    864 			continue
    865 		}
    866 		sect = &elfobj.sect[rsect.info]
    867 		if err = elfmap(elfobj, rsect); err != nil {
    868 			goto bad
    869 		}
    870 		rela = 0
    871 		if rsect.type_ == ElfSectRela {
    872 			rela = 1
    873 		}
    874 		n = int(rsect.size / uint64(4+4*is64) / uint64(2+rela))
    875 		r = make([]Reloc, n)
    876 		p = rsect.base
    877 		for j = 0; j < n; j++ {
    878 			add = 0
    879 			rp = &r[j]
    880 			if is64 != 0 {
    881 				// 64-bit rel/rela
    882 				rp.Off = int32(e.Uint64(p))
    883 
    884 				p = p[8:]
    885 				info = e.Uint64(p)
    886 				p = p[8:]
    887 				if rela != 0 {
    888 					add = e.Uint64(p)
    889 					p = p[8:]
    890 				}
    891 			} else {
    892 				// 32-bit rel/rela
    893 				rp.Off = int32(e.Uint32(p))
    894 
    895 				p = p[4:]
    896 				info = uint64(e.Uint32(p))
    897 				info = info>>8<<32 | info&0xff // convert to 64-bit info
    898 				p = p[4:]
    899 				if rela != 0 {
    900 					add = uint64(e.Uint32(p))
    901 					p = p[4:]
    902 				}
    903 			}
    904 
    905 			if info&0xffffffff == 0 { // skip R_*_NONE relocation
    906 				j--
    907 				n--
    908 				continue
    909 			}
    910 
    911 			if info>>32 == 0 { // absolute relocation, don't bother reading the null symbol
    912 				rp.Sym = nil
    913 			} else {
    914 				if err = readelfsym(ctxt, elfobj, int(info>>32), &sym, 0, 0); err != nil {
    915 					goto bad
    916 				}
    917 				sym.sym = symbols[info>>32]
    918 				if sym.sym == nil {
    919 					err = fmt.Errorf("%s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", sect.sym.Name, j, int(info>>32), sym.name, sym.shndx, sym.type_)
    920 					goto bad
    921 				}
    922 
    923 				rp.Sym = sym.sym
    924 			}
    925 
    926 			rp.Type = 256 + obj.RelocType(info)
    927 			rp.Siz = relSize(ctxt, pn, uint32(info))
    928 			if rela != 0 {
    929 				rp.Add = int64(add)
    930 			} else {
    931 				// load addend from image
    932 				if rp.Siz == 4 {
    933 					rp.Add = int64(e.Uint32(sect.base[rp.Off:]))
    934 				} else if rp.Siz == 8 {
    935 					rp.Add = int64(e.Uint64(sect.base[rp.Off:]))
    936 				} else {
    937 					Errorf(nil, "invalid rela size %d", rp.Siz)
    938 				}
    939 			}
    940 
    941 			if rp.Siz == 2 {
    942 				rp.Add = int64(int16(rp.Add))
    943 			}
    944 			if rp.Siz == 4 {
    945 				rp.Add = int64(int32(rp.Add))
    946 			}
    947 		}
    948 
    949 		//print("rel %s %d %d %s %#llx\n", sect->sym->name, rp->type, rp->siz, rp->sym->name, rp->add);
    950 		sort.Sort(rbyoff(r[:n]))
    951 		// just in case
    952 
    953 		s = sect.sym
    954 		s.R = r
    955 		s.R = s.R[:n]
    956 	}
    957 
    958 	return
    959 
    960 bad:
    961 	Errorf(nil, "%s: malformed elf file: %v", pn, err)
    962 }
    963 
    964 func section(elfobj *ElfObj, name string) *ElfSect {
    965 	for i := 0; uint(i) < elfobj.nsect; i++ {
    966 		if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name {
    967 			return &elfobj.sect[i]
    968 		}
    969 	}
    970 	return nil
    971 }
    972 
    973 func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) {
    974 	if sect.base != nil {
    975 		return nil
    976 	}
    977 
    978 	if sect.off+sect.size > uint64(elfobj.length) {
    979 		err = fmt.Errorf("elf section past end of file")
    980 		return err
    981 	}
    982 
    983 	sect.base = make([]byte, sect.size)
    984 	if elfobj.f.Seek(int64(uint64(elfobj.base)+sect.off), 0) < 0 {
    985 		return fmt.Errorf("short read: seek not successful")
    986 	}
    987 	if _, err := io.ReadFull(elfobj.f, sect.base); err != nil {
    988 		return fmt.Errorf("short read: %v", err)
    989 	}
    990 
    991 	return nil
    992 }
    993 
    994 func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int, localSymVersion int) (err error) {
    995 	if i >= elfobj.nsymtab || i < 0 {
    996 		err = fmt.Errorf("invalid elf symbol index")
    997 		return err
    998 	}
    999 
   1000 	if i == 0 {
   1001 		Errorf(nil, "readym: read null symbol!")
   1002 	}
   1003 
   1004 	if elfobj.is64 != 0 {
   1005 		b := new(ElfSymBytes64)
   1006 		binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF64SYMSIZE:(i+1)*ELF64SYMSIZE]), elfobj.e, b)
   1007 		sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
   1008 		sym.value = elfobj.e.Uint64(b.Value[:])
   1009 		sym.size = elfobj.e.Uint64(b.Size[:])
   1010 		sym.shndx = elfobj.e.Uint16(b.Shndx[:])
   1011 		sym.bind = b.Info >> 4
   1012 		sym.type_ = b.Info & 0xf
   1013 		sym.other = b.Other
   1014 	} else {
   1015 		b := new(ElfSymBytes)
   1016 		binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF32SYMSIZE:(i+1)*ELF32SYMSIZE]), elfobj.e, b)
   1017 		sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
   1018 		sym.value = uint64(elfobj.e.Uint32(b.Value[:]))
   1019 		sym.size = uint64(elfobj.e.Uint32(b.Size[:]))
   1020 		sym.shndx = elfobj.e.Uint16(b.Shndx[:])
   1021 		sym.bind = b.Info >> 4
   1022 		sym.type_ = b.Info & 0xf
   1023 		sym.other = b.Other
   1024 	}
   1025 
   1026 	var s *Symbol
   1027 	if sym.name == "_GLOBAL_OFFSET_TABLE_" {
   1028 		sym.name = ".got"
   1029 	}
   1030 	if sym.name == ".TOC." {
   1031 		// Magic symbol on ppc64.  Will be set to this object
   1032 		// file's .got+0x8000.
   1033 		sym.bind = ElfSymBindLocal
   1034 	}
   1035 
   1036 	switch sym.type_ {
   1037 	case ElfSymTypeSection:
   1038 		s = elfobj.sect[sym.shndx].sym
   1039 
   1040 	case ElfSymTypeObject, ElfSymTypeFunc, ElfSymTypeNone, ElfSymTypeCommon:
   1041 		switch sym.bind {
   1042 		case ElfSymBindGlobal:
   1043 			if needSym != 0 {
   1044 				s = ctxt.Syms.Lookup(sym.name, 0)
   1045 
   1046 				// for global scoped hidden symbols we should insert it into
   1047 				// symbol hash table, but mark them as hidden.
   1048 				// __i686.get_pc_thunk.bx is allowed to be duplicated, to
   1049 				// workaround that we set dupok.
   1050 				// TODO(minux): correctly handle __i686.get_pc_thunk.bx without
   1051 				// set dupok generally. See http://codereview.appspot.com/5823055/
   1052 				// comment #5 for details.
   1053 				if s != nil && sym.other == 2 {
   1054 					s.Type |= obj.SHIDDEN
   1055 					s.Attr |= AttrDuplicateOK
   1056 				}
   1057 			}
   1058 
   1059 		case ElfSymBindLocal:
   1060 			if SysArch.Family == sys.ARM && (strings.HasPrefix(sym.name, "$a") || strings.HasPrefix(sym.name, "$d")) {
   1061 				// binutils for arm generate these mapping
   1062 				// symbols, ignore these
   1063 				break
   1064 			}
   1065 
   1066 			if sym.name == ".TOC." {
   1067 				// We need to be able to look this up,
   1068 				// so put it in the hash table.
   1069 				if needSym != 0 {
   1070 					s = ctxt.Syms.Lookup(sym.name, localSymVersion)
   1071 					s.Type |= obj.SHIDDEN
   1072 				}
   1073 
   1074 				break
   1075 			}
   1076 
   1077 			if needSym != 0 {
   1078 				// local names and hidden global names are unique
   1079 				// and should only be referenced by their index, not name, so we
   1080 				// don't bother to add them into the hash table
   1081 				s = ctxt.Syms.newsym(sym.name, localSymVersion)
   1082 
   1083 				s.Type |= obj.SHIDDEN
   1084 			}
   1085 
   1086 		case ElfSymBindWeak:
   1087 			if needSym != 0 {
   1088 				s = ctxt.Syms.Lookup(sym.name, 0)
   1089 				if sym.other == 2 {
   1090 					s.Type |= obj.SHIDDEN
   1091 				}
   1092 			}
   1093 
   1094 		default:
   1095 			err = fmt.Errorf("%s: invalid symbol binding %d", sym.name, sym.bind)
   1096 			return err
   1097 		}
   1098 	}
   1099 
   1100 	if s != nil && s.Type == 0 && sym.type_ != ElfSymTypeSection {
   1101 		s.Type = obj.SXREF
   1102 	}
   1103 	sym.sym = s
   1104 
   1105 	return nil
   1106 }
   1107 
   1108 type rbyoff []Reloc
   1109 
   1110 func (x rbyoff) Len() int {
   1111 	return len(x)
   1112 }
   1113 
   1114 func (x rbyoff) Swap(i, j int) {
   1115 	x[i], x[j] = x[j], x[i]
   1116 }
   1117 
   1118 func (x rbyoff) Less(i, j int) bool {
   1119 	a := &x[i]
   1120 	b := &x[j]
   1121 	if a.Off < b.Off {
   1122 		return true
   1123 	}
   1124 	if a.Off > b.Off {
   1125 		return false
   1126 	}
   1127 	return false
   1128 }
   1129 
   1130 func relSize(ctxt *Link, pn string, elftype uint32) uint8 {
   1131 	// TODO(mdempsky): Replace this with a struct-valued switch statement
   1132 	// once golang.org/issue/15164 is fixed or found to not impair cmd/link
   1133 	// performance.
   1134 
   1135 	const (
   1136 		AMD64 = uint32(sys.AMD64)
   1137 		ARM   = uint32(sys.ARM)
   1138 		I386  = uint32(sys.I386)
   1139 		PPC64 = uint32(sys.PPC64)
   1140 		S390X = uint32(sys.S390X)
   1141 	)
   1142 
   1143 	switch uint32(SysArch.Family) | elftype<<24 {
   1144 	default:
   1145 		Errorf(nil, "%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
   1146 		fallthrough
   1147 
   1148 	case S390X | R_390_8<<24:
   1149 		return 1
   1150 
   1151 	case PPC64 | R_PPC64_TOC16<<24,
   1152 		PPC64 | R_PPC64_TOC16_LO<<24,
   1153 		PPC64 | R_PPC64_TOC16_HI<<24,
   1154 		PPC64 | R_PPC64_TOC16_HA<<24,
   1155 		PPC64 | R_PPC64_TOC16_DS<<24,
   1156 		PPC64 | R_PPC64_TOC16_LO_DS<<24,
   1157 		PPC64 | R_PPC64_REL16_LO<<24,
   1158 		PPC64 | R_PPC64_REL16_HI<<24,
   1159 		PPC64 | R_PPC64_REL16_HA<<24,
   1160 		S390X | R_390_16<<24,
   1161 		S390X | R_390_GOT16<<24,
   1162 		S390X | R_390_PC16<<24,
   1163 		S390X | R_390_PC16DBL<<24,
   1164 		S390X | R_390_PLT16DBL<<24:
   1165 		return 2
   1166 
   1167 	case ARM | R_ARM_ABS32<<24,
   1168 		ARM | R_ARM_GOT32<<24,
   1169 		ARM | R_ARM_PLT32<<24,
   1170 		ARM | R_ARM_GOTOFF<<24,
   1171 		ARM | R_ARM_GOTPC<<24,
   1172 		ARM | R_ARM_THM_PC22<<24,
   1173 		ARM | R_ARM_REL32<<24,
   1174 		ARM | R_ARM_CALL<<24,
   1175 		ARM | R_ARM_V4BX<<24,
   1176 		ARM | R_ARM_GOT_PREL<<24,
   1177 		ARM | R_ARM_PC24<<24,
   1178 		ARM | R_ARM_JUMP24<<24,
   1179 		AMD64 | R_X86_64_PC32<<24,
   1180 		AMD64 | R_X86_64_PLT32<<24,
   1181 		AMD64 | R_X86_64_GOTPCREL<<24,
   1182 		AMD64 | R_X86_64_GOTPCRELX<<24,
   1183 		AMD64 | R_X86_64_REX_GOTPCRELX<<24,
   1184 		I386 | R_386_32<<24,
   1185 		I386 | R_386_PC32<<24,
   1186 		I386 | R_386_GOT32<<24,
   1187 		I386 | R_386_PLT32<<24,
   1188 		I386 | R_386_GOTOFF<<24,
   1189 		I386 | R_386_GOTPC<<24,
   1190 		I386 | R_386_GOT32X<<24,
   1191 		PPC64 | R_PPC64_REL24<<24,
   1192 		PPC64 | R_PPC_REL32<<24,
   1193 		S390X | R_390_32<<24,
   1194 		S390X | R_390_PC32<<24,
   1195 		S390X | R_390_GOT32<<24,
   1196 		S390X | R_390_PLT32<<24,
   1197 		S390X | R_390_PC32DBL<<24,
   1198 		S390X | R_390_PLT32DBL<<24,
   1199 		S390X | R_390_GOTPCDBL<<24,
   1200 		S390X | R_390_GOTENT<<24:
   1201 		return 4
   1202 
   1203 	case AMD64 | R_X86_64_64<<24,
   1204 		PPC64 | R_PPC64_ADDR64<<24,
   1205 		S390X | R_390_GLOB_DAT<<24,
   1206 		S390X | R_390_RELATIVE<<24,
   1207 		S390X | R_390_GOTOFF<<24,
   1208 		S390X | R_390_GOTPC<<24,
   1209 		S390X | R_390_64<<24,
   1210 		S390X | R_390_PC64<<24,
   1211 		S390X | R_390_GOT64<<24,
   1212 		S390X | R_390_PLT64<<24:
   1213 		return 8
   1214 	}
   1215 }
   1216