2015-02-27 22:57:28 -05:00
|
|
|
// Copyright 2009 The Go Authors. All rights reserved.
|
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
package ld
|
|
|
|
|
|
|
|
|
|
import (
|
2017-04-18 12:53:25 -07:00
|
|
|
"cmd/internal/objabi"
|
2016-04-06 12:01:40 -07:00
|
|
|
"cmd/internal/sys"
|
2015-05-25 13:59:08 +12:00
|
|
|
"crypto/sha1"
|
2015-03-01 22:02:13 -05:00
|
|
|
"encoding/binary"
|
2016-03-03 22:37:14 -08:00
|
|
|
"encoding/hex"
|
2016-12-05 23:20:20 -05:00
|
|
|
"io"
|
2015-05-25 14:51:02 +12:00
|
|
|
"path/filepath"
|
2015-05-25 13:59:08 +12:00
|
|
|
"sort"
|
2015-05-25 14:51:02 +12:00
|
|
|
"strings"
|
2015-02-27 22:57:28 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Derived from:
|
|
|
|
|
* $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.1 2005/12/30 22:13:58 marcel Exp $
|
|
|
|
|
* $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.1 2005/12/30 22:13:58 marcel Exp $
|
|
|
|
|
* $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.1 2005/12/30 22:13:58 marcel Exp $
|
|
|
|
|
* $FreeBSD: src/sys/alpha/include/elf.h,v 1.14 2003/09/25 01:10:22 peter Exp $
|
|
|
|
|
* $FreeBSD: src/sys/amd64/include/elf.h,v 1.18 2004/08/03 08:21:48 dfr Exp $
|
|
|
|
|
* $FreeBSD: src/sys/arm/include/elf.h,v 1.5.2.1 2006/06/30 21:42:52 cognet Exp $
|
|
|
|
|
* $FreeBSD: src/sys/i386/include/elf.h,v 1.16 2004/08/02 19:12:17 dfr Exp $
|
|
|
|
|
* $FreeBSD: src/sys/powerpc/include/elf.h,v 1.7 2004/11/02 09:47:01 ssouhlal Exp $
|
|
|
|
|
* $FreeBSD: src/sys/sparc64/include/elf.h,v 1.12 2003/09/25 01:10:26 peter Exp $
|
|
|
|
|
*
|
|
|
|
|
* Copyright (c) 1996-1998 John D. Polstra. All rights reserved.
|
|
|
|
|
* Copyright (c) 2001 David E. O'Brien
|
2016-04-10 14:32:26 -07:00
|
|
|
* Portions Copyright 2009 The Go Authors. All rights reserved.
|
2015-02-27 22:57:28 -05:00
|
|
|
*
|
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
|
* are met:
|
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
|
*
|
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ELF definitions that are independent of architecture or word size.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Note header. The ".note" section contains an array of notes. Each
|
|
|
|
|
* begins with this header, aligned to a word boundary. Immediately
|
|
|
|
|
* following the note header is n_namesz bytes of name, padded to the
|
|
|
|
|
* next word boundary. Then comes n_descsz bytes of descriptor, again
|
|
|
|
|
* padded to a word boundary. The values of n_namesz and n_descsz do
|
|
|
|
|
* not include the padding.
|
|
|
|
|
*/
|
2016-08-22 10:33:13 -04:00
|
|
|
type elfNote struct {
|
|
|
|
|
nNamesz uint32
|
|
|
|
|
nDescsz uint32
|
|
|
|
|
nType uint32
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
EI_MAG0 = 0
|
|
|
|
|
EI_MAG1 = 1
|
|
|
|
|
EI_MAG2 = 2
|
|
|
|
|
EI_MAG3 = 3
|
|
|
|
|
EI_CLASS = 4
|
|
|
|
|
EI_DATA = 5
|
|
|
|
|
EI_VERSION = 6
|
|
|
|
|
EI_OSABI = 7
|
|
|
|
|
EI_ABIVERSION = 8
|
|
|
|
|
OLD_EI_BRAND = 8
|
|
|
|
|
EI_PAD = 9
|
|
|
|
|
EI_NIDENT = 16
|
|
|
|
|
ELFMAG0 = 0x7f
|
|
|
|
|
ELFMAG1 = 'E'
|
|
|
|
|
ELFMAG2 = 'L'
|
|
|
|
|
ELFMAG3 = 'F'
|
|
|
|
|
SELFMAG = 4
|
|
|
|
|
EV_NONE = 0
|
|
|
|
|
EV_CURRENT = 1
|
|
|
|
|
ELFCLASSNONE = 0
|
|
|
|
|
ELFCLASS32 = 1
|
|
|
|
|
ELFCLASS64 = 2
|
|
|
|
|
ELFDATANONE = 0
|
|
|
|
|
ELFDATA2LSB = 1
|
|
|
|
|
ELFDATA2MSB = 2
|
|
|
|
|
ELFOSABI_NONE = 0
|
|
|
|
|
ELFOSABI_HPUX = 1
|
|
|
|
|
ELFOSABI_NETBSD = 2
|
|
|
|
|
ELFOSABI_LINUX = 3
|
|
|
|
|
ELFOSABI_HURD = 4
|
|
|
|
|
ELFOSABI_86OPEN = 5
|
|
|
|
|
ELFOSABI_SOLARIS = 6
|
|
|
|
|
ELFOSABI_AIX = 7
|
|
|
|
|
ELFOSABI_IRIX = 8
|
|
|
|
|
ELFOSABI_FREEBSD = 9
|
|
|
|
|
ELFOSABI_TRU64 = 10
|
|
|
|
|
ELFOSABI_MODESTO = 11
|
|
|
|
|
ELFOSABI_OPENBSD = 12
|
|
|
|
|
ELFOSABI_OPENVMS = 13
|
|
|
|
|
ELFOSABI_NSK = 14
|
|
|
|
|
ELFOSABI_ARM = 97
|
|
|
|
|
ELFOSABI_STANDALONE = 255
|
|
|
|
|
ELFOSABI_SYSV = ELFOSABI_NONE
|
|
|
|
|
ELFOSABI_MONTEREY = ELFOSABI_AIX
|
|
|
|
|
ET_NONE = 0
|
|
|
|
|
ET_REL = 1
|
|
|
|
|
ET_EXEC = 2
|
|
|
|
|
ET_DYN = 3
|
|
|
|
|
ET_CORE = 4
|
|
|
|
|
ET_LOOS = 0xfe00
|
|
|
|
|
ET_HIOS = 0xfeff
|
|
|
|
|
ET_LOPROC = 0xff00
|
|
|
|
|
ET_HIPROC = 0xffff
|
|
|
|
|
EM_NONE = 0
|
|
|
|
|
EM_M32 = 1
|
|
|
|
|
EM_SPARC = 2
|
|
|
|
|
EM_386 = 3
|
|
|
|
|
EM_68K = 4
|
|
|
|
|
EM_88K = 5
|
|
|
|
|
EM_860 = 7
|
|
|
|
|
EM_MIPS = 8
|
|
|
|
|
EM_S370 = 9
|
|
|
|
|
EM_MIPS_RS3_LE = 10
|
|
|
|
|
EM_PARISC = 15
|
|
|
|
|
EM_VPP500 = 17
|
|
|
|
|
EM_SPARC32PLUS = 18
|
|
|
|
|
EM_960 = 19
|
|
|
|
|
EM_PPC = 20
|
|
|
|
|
EM_PPC64 = 21
|
|
|
|
|
EM_S390 = 22
|
|
|
|
|
EM_V800 = 36
|
|
|
|
|
EM_FR20 = 37
|
|
|
|
|
EM_RH32 = 38
|
|
|
|
|
EM_RCE = 39
|
|
|
|
|
EM_ARM = 40
|
|
|
|
|
EM_SH = 42
|
|
|
|
|
EM_SPARCV9 = 43
|
|
|
|
|
EM_TRICORE = 44
|
|
|
|
|
EM_ARC = 45
|
|
|
|
|
EM_H8_300 = 46
|
|
|
|
|
EM_H8_300H = 47
|
|
|
|
|
EM_H8S = 48
|
|
|
|
|
EM_H8_500 = 49
|
|
|
|
|
EM_IA_64 = 50
|
|
|
|
|
EM_MIPS_X = 51
|
|
|
|
|
EM_COLDFIRE = 52
|
|
|
|
|
EM_68HC12 = 53
|
|
|
|
|
EM_MMA = 54
|
|
|
|
|
EM_PCP = 55
|
|
|
|
|
EM_NCPU = 56
|
|
|
|
|
EM_NDR1 = 57
|
|
|
|
|
EM_STARCORE = 58
|
|
|
|
|
EM_ME16 = 59
|
|
|
|
|
EM_ST100 = 60
|
|
|
|
|
EM_TINYJ = 61
|
|
|
|
|
EM_X86_64 = 62
|
2015-03-08 14:14:53 +01:00
|
|
|
EM_AARCH64 = 183
|
2015-02-27 22:57:28 -05:00
|
|
|
EM_486 = 6
|
|
|
|
|
EM_MIPS_RS4_BE = 10
|
|
|
|
|
EM_ALPHA_STD = 41
|
|
|
|
|
EM_ALPHA = 0x9026
|
|
|
|
|
SHN_UNDEF = 0
|
|
|
|
|
SHN_LORESERVE = 0xff00
|
|
|
|
|
SHN_LOPROC = 0xff00
|
|
|
|
|
SHN_HIPROC = 0xff1f
|
|
|
|
|
SHN_LOOS = 0xff20
|
|
|
|
|
SHN_HIOS = 0xff3f
|
|
|
|
|
SHN_ABS = 0xfff1
|
|
|
|
|
SHN_COMMON = 0xfff2
|
|
|
|
|
SHN_XINDEX = 0xffff
|
|
|
|
|
SHN_HIRESERVE = 0xffff
|
|
|
|
|
SHT_NULL = 0
|
|
|
|
|
SHT_PROGBITS = 1
|
|
|
|
|
SHT_SYMTAB = 2
|
|
|
|
|
SHT_STRTAB = 3
|
|
|
|
|
SHT_RELA = 4
|
|
|
|
|
SHT_HASH = 5
|
|
|
|
|
SHT_DYNAMIC = 6
|
|
|
|
|
SHT_NOTE = 7
|
|
|
|
|
SHT_NOBITS = 8
|
|
|
|
|
SHT_REL = 9
|
|
|
|
|
SHT_SHLIB = 10
|
|
|
|
|
SHT_DYNSYM = 11
|
|
|
|
|
SHT_INIT_ARRAY = 14
|
|
|
|
|
SHT_FINI_ARRAY = 15
|
|
|
|
|
SHT_PREINIT_ARRAY = 16
|
|
|
|
|
SHT_GROUP = 17
|
|
|
|
|
SHT_SYMTAB_SHNDX = 18
|
|
|
|
|
SHT_LOOS = 0x60000000
|
|
|
|
|
SHT_HIOS = 0x6fffffff
|
|
|
|
|
SHT_GNU_VERDEF = 0x6ffffffd
|
|
|
|
|
SHT_GNU_VERNEED = 0x6ffffffe
|
|
|
|
|
SHT_GNU_VERSYM = 0x6fffffff
|
|
|
|
|
SHT_LOPROC = 0x70000000
|
2015-09-23 15:46:00 +12:00
|
|
|
SHT_ARM_ATTRIBUTES = 0x70000003
|
2015-02-27 22:57:28 -05:00
|
|
|
SHT_HIPROC = 0x7fffffff
|
|
|
|
|
SHT_LOUSER = 0x80000000
|
|
|
|
|
SHT_HIUSER = 0xffffffff
|
|
|
|
|
SHF_WRITE = 0x1
|
|
|
|
|
SHF_ALLOC = 0x2
|
|
|
|
|
SHF_EXECINSTR = 0x4
|
|
|
|
|
SHF_MERGE = 0x10
|
|
|
|
|
SHF_STRINGS = 0x20
|
|
|
|
|
SHF_INFO_LINK = 0x40
|
|
|
|
|
SHF_LINK_ORDER = 0x80
|
|
|
|
|
SHF_OS_NONCONFORMING = 0x100
|
|
|
|
|
SHF_GROUP = 0x200
|
|
|
|
|
SHF_TLS = 0x400
|
|
|
|
|
SHF_MASKOS = 0x0ff00000
|
|
|
|
|
SHF_MASKPROC = 0xf0000000
|
|
|
|
|
PT_NULL = 0
|
|
|
|
|
PT_LOAD = 1
|
|
|
|
|
PT_DYNAMIC = 2
|
|
|
|
|
PT_INTERP = 3
|
|
|
|
|
PT_NOTE = 4
|
|
|
|
|
PT_SHLIB = 5
|
|
|
|
|
PT_PHDR = 6
|
|
|
|
|
PT_TLS = 7
|
|
|
|
|
PT_LOOS = 0x60000000
|
|
|
|
|
PT_HIOS = 0x6fffffff
|
|
|
|
|
PT_LOPROC = 0x70000000
|
|
|
|
|
PT_HIPROC = 0x7fffffff
|
|
|
|
|
PT_GNU_STACK = 0x6474e551
|
2016-09-06 08:02:30 -04:00
|
|
|
PT_GNU_RELRO = 0x6474e552
|
2015-02-27 22:57:28 -05:00
|
|
|
PT_PAX_FLAGS = 0x65041580
|
2016-06-15 13:44:03 -07:00
|
|
|
PT_SUNWSTACK = 0x6ffffffb
|
2015-02-27 22:57:28 -05:00
|
|
|
PF_X = 0x1
|
|
|
|
|
PF_W = 0x2
|
|
|
|
|
PF_R = 0x4
|
|
|
|
|
PF_MASKOS = 0x0ff00000
|
|
|
|
|
PF_MASKPROC = 0xf0000000
|
|
|
|
|
DT_NULL = 0
|
|
|
|
|
DT_NEEDED = 1
|
|
|
|
|
DT_PLTRELSZ = 2
|
|
|
|
|
DT_PLTGOT = 3
|
|
|
|
|
DT_HASH = 4
|
|
|
|
|
DT_STRTAB = 5
|
|
|
|
|
DT_SYMTAB = 6
|
|
|
|
|
DT_RELA = 7
|
|
|
|
|
DT_RELASZ = 8
|
|
|
|
|
DT_RELAENT = 9
|
|
|
|
|
DT_STRSZ = 10
|
|
|
|
|
DT_SYMENT = 11
|
|
|
|
|
DT_INIT = 12
|
|
|
|
|
DT_FINI = 13
|
|
|
|
|
DT_SONAME = 14
|
|
|
|
|
DT_RPATH = 15
|
|
|
|
|
DT_SYMBOLIC = 16
|
|
|
|
|
DT_REL = 17
|
|
|
|
|
DT_RELSZ = 18
|
|
|
|
|
DT_RELENT = 19
|
|
|
|
|
DT_PLTREL = 20
|
|
|
|
|
DT_DEBUG = 21
|
|
|
|
|
DT_TEXTREL = 22
|
|
|
|
|
DT_JMPREL = 23
|
|
|
|
|
DT_BIND_NOW = 24
|
|
|
|
|
DT_INIT_ARRAY = 25
|
|
|
|
|
DT_FINI_ARRAY = 26
|
|
|
|
|
DT_INIT_ARRAYSZ = 27
|
|
|
|
|
DT_FINI_ARRAYSZ = 28
|
|
|
|
|
DT_RUNPATH = 29
|
|
|
|
|
DT_FLAGS = 30
|
|
|
|
|
DT_ENCODING = 32
|
|
|
|
|
DT_PREINIT_ARRAY = 32
|
|
|
|
|
DT_PREINIT_ARRAYSZ = 33
|
|
|
|
|
DT_LOOS = 0x6000000d
|
|
|
|
|
DT_HIOS = 0x6ffff000
|
|
|
|
|
DT_LOPROC = 0x70000000
|
|
|
|
|
DT_HIPROC = 0x7fffffff
|
|
|
|
|
DT_VERNEED = 0x6ffffffe
|
|
|
|
|
DT_VERNEEDNUM = 0x6fffffff
|
|
|
|
|
DT_VERSYM = 0x6ffffff0
|
|
|
|
|
DT_PPC64_GLINK = DT_LOPROC + 0
|
|
|
|
|
DT_PPC64_OPT = DT_LOPROC + 3
|
|
|
|
|
DF_ORIGIN = 0x0001
|
|
|
|
|
DF_SYMBOLIC = 0x0002
|
|
|
|
|
DF_TEXTREL = 0x0004
|
|
|
|
|
DF_BIND_NOW = 0x0008
|
|
|
|
|
DF_STATIC_TLS = 0x0010
|
|
|
|
|
NT_PRSTATUS = 1
|
|
|
|
|
NT_FPREGSET = 2
|
|
|
|
|
NT_PRPSINFO = 3
|
|
|
|
|
STB_LOCAL = 0
|
|
|
|
|
STB_GLOBAL = 1
|
|
|
|
|
STB_WEAK = 2
|
|
|
|
|
STB_LOOS = 10
|
|
|
|
|
STB_HIOS = 12
|
|
|
|
|
STB_LOPROC = 13
|
|
|
|
|
STB_HIPROC = 15
|
|
|
|
|
STT_NOTYPE = 0
|
|
|
|
|
STT_OBJECT = 1
|
|
|
|
|
STT_FUNC = 2
|
|
|
|
|
STT_SECTION = 3
|
|
|
|
|
STT_FILE = 4
|
|
|
|
|
STT_COMMON = 5
|
|
|
|
|
STT_TLS = 6
|
|
|
|
|
STT_LOOS = 10
|
|
|
|
|
STT_HIOS = 12
|
|
|
|
|
STT_LOPROC = 13
|
|
|
|
|
STT_HIPROC = 15
|
|
|
|
|
STV_DEFAULT = 0x0
|
|
|
|
|
STV_INTERNAL = 0x1
|
|
|
|
|
STV_HIDDEN = 0x2
|
|
|
|
|
STV_PROTECTED = 0x3
|
|
|
|
|
STN_UNDEF = 0
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
/* For accessing the fields of r_info. */
|
|
|
|
|
|
|
|
|
|
/* For constructing r_info from field values. */
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Relocation types.
|
|
|
|
|
*/
|
|
|
|
|
const (
|
2015-10-31 14:44:48 -07:00
|
|
|
R_X86_64_NONE = 0
|
|
|
|
|
R_X86_64_64 = 1
|
|
|
|
|
R_X86_64_PC32 = 2
|
|
|
|
|
R_X86_64_GOT32 = 3
|
|
|
|
|
R_X86_64_PLT32 = 4
|
|
|
|
|
R_X86_64_COPY = 5
|
|
|
|
|
R_X86_64_GLOB_DAT = 6
|
|
|
|
|
R_X86_64_JMP_SLOT = 7
|
|
|
|
|
R_X86_64_RELATIVE = 8
|
|
|
|
|
R_X86_64_GOTPCREL = 9
|
|
|
|
|
R_X86_64_32 = 10
|
|
|
|
|
R_X86_64_32S = 11
|
|
|
|
|
R_X86_64_16 = 12
|
|
|
|
|
R_X86_64_PC16 = 13
|
|
|
|
|
R_X86_64_8 = 14
|
|
|
|
|
R_X86_64_PC8 = 15
|
|
|
|
|
R_X86_64_DTPMOD64 = 16
|
|
|
|
|
R_X86_64_DTPOFF64 = 17
|
|
|
|
|
R_X86_64_TPOFF64 = 18
|
|
|
|
|
R_X86_64_TLSGD = 19
|
|
|
|
|
R_X86_64_TLSLD = 20
|
|
|
|
|
R_X86_64_DTPOFF32 = 21
|
|
|
|
|
R_X86_64_GOTTPOFF = 22
|
|
|
|
|
R_X86_64_TPOFF32 = 23
|
|
|
|
|
R_X86_64_PC64 = 24
|
|
|
|
|
R_X86_64_GOTOFF64 = 25
|
|
|
|
|
R_X86_64_GOTPC32 = 26
|
|
|
|
|
R_X86_64_GOT64 = 27
|
|
|
|
|
R_X86_64_GOTPCREL64 = 28
|
|
|
|
|
R_X86_64_GOTPC64 = 29
|
|
|
|
|
R_X86_64_GOTPLT64 = 30
|
|
|
|
|
R_X86_64_PLTOFF64 = 31
|
|
|
|
|
R_X86_64_SIZE32 = 32
|
|
|
|
|
R_X86_64_SIZE64 = 33
|
|
|
|
|
R_X86_64_GOTPC32_TLSDEC = 34
|
|
|
|
|
R_X86_64_TLSDESC_CALL = 35
|
|
|
|
|
R_X86_64_TLSDESC = 36
|
|
|
|
|
R_X86_64_IRELATIVE = 37
|
|
|
|
|
R_X86_64_PC32_BND = 40
|
|
|
|
|
R_X86_64_GOTPCRELX = 41
|
|
|
|
|
R_X86_64_REX_GOTPCRELX = 42
|
2015-08-11 14:10:03 +12:00
|
|
|
|
2015-10-28 15:27:51 +13:00
|
|
|
R_AARCH64_ABS64 = 257
|
|
|
|
|
R_AARCH64_ABS32 = 258
|
|
|
|
|
R_AARCH64_CALL26 = 283
|
|
|
|
|
R_AARCH64_ADR_PREL_PG_HI21 = 275
|
|
|
|
|
R_AARCH64_ADD_ABS_LO12_NC = 277
|
2015-08-27 21:09:46 +12:00
|
|
|
R_AARCH64_LDST8_ABS_LO12_NC = 278
|
|
|
|
|
R_AARCH64_LDST16_ABS_LO12_NC = 284
|
|
|
|
|
R_AARCH64_LDST32_ABS_LO12_NC = 285
|
|
|
|
|
R_AARCH64_LDST64_ABS_LO12_NC = 286
|
|
|
|
|
R_AARCH64_ADR_GOT_PAGE = 311
|
|
|
|
|
R_AARCH64_LD64_GOT_LO12_NC = 312
|
2015-10-28 15:27:51 +13:00
|
|
|
R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 = 541
|
|
|
|
|
R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC = 542
|
|
|
|
|
R_AARCH64_TLSLE_MOVW_TPREL_G0 = 547
|
2015-08-11 14:10:03 +12:00
|
|
|
|
|
|
|
|
R_ALPHA_NONE = 0
|
|
|
|
|
R_ALPHA_REFLONG = 1
|
|
|
|
|
R_ALPHA_REFQUAD = 2
|
|
|
|
|
R_ALPHA_GPREL32 = 3
|
|
|
|
|
R_ALPHA_LITERAL = 4
|
|
|
|
|
R_ALPHA_LITUSE = 5
|
|
|
|
|
R_ALPHA_GPDISP = 6
|
|
|
|
|
R_ALPHA_BRADDR = 7
|
|
|
|
|
R_ALPHA_HINT = 8
|
|
|
|
|
R_ALPHA_SREL16 = 9
|
|
|
|
|
R_ALPHA_SREL32 = 10
|
|
|
|
|
R_ALPHA_SREL64 = 11
|
|
|
|
|
R_ALPHA_OP_PUSH = 12
|
|
|
|
|
R_ALPHA_OP_STORE = 13
|
|
|
|
|
R_ALPHA_OP_PSUB = 14
|
|
|
|
|
R_ALPHA_OP_PRSHIFT = 15
|
|
|
|
|
R_ALPHA_GPVALUE = 16
|
|
|
|
|
R_ALPHA_GPRELHIGH = 17
|
|
|
|
|
R_ALPHA_GPRELLOW = 18
|
|
|
|
|
R_ALPHA_IMMED_GP_16 = 19
|
|
|
|
|
R_ALPHA_IMMED_GP_HI32 = 20
|
|
|
|
|
R_ALPHA_IMMED_SCN_HI32 = 21
|
|
|
|
|
R_ALPHA_IMMED_BR_HI32 = 22
|
|
|
|
|
R_ALPHA_IMMED_LO32 = 23
|
|
|
|
|
R_ALPHA_COPY = 24
|
|
|
|
|
R_ALPHA_GLOB_DAT = 25
|
|
|
|
|
R_ALPHA_JMP_SLOT = 26
|
|
|
|
|
R_ALPHA_RELATIVE = 27
|
|
|
|
|
|
|
|
|
|
R_ARM_NONE = 0
|
|
|
|
|
R_ARM_PC24 = 1
|
|
|
|
|
R_ARM_ABS32 = 2
|
|
|
|
|
R_ARM_REL32 = 3
|
|
|
|
|
R_ARM_PC13 = 4
|
|
|
|
|
R_ARM_ABS16 = 5
|
|
|
|
|
R_ARM_ABS12 = 6
|
|
|
|
|
R_ARM_THM_ABS5 = 7
|
|
|
|
|
R_ARM_ABS8 = 8
|
|
|
|
|
R_ARM_SBREL32 = 9
|
|
|
|
|
R_ARM_THM_PC22 = 10
|
|
|
|
|
R_ARM_THM_PC8 = 11
|
|
|
|
|
R_ARM_AMP_VCALL9 = 12
|
|
|
|
|
R_ARM_SWI24 = 13
|
|
|
|
|
R_ARM_THM_SWI8 = 14
|
|
|
|
|
R_ARM_XPC25 = 15
|
|
|
|
|
R_ARM_THM_XPC22 = 16
|
|
|
|
|
R_ARM_COPY = 20
|
|
|
|
|
R_ARM_GLOB_DAT = 21
|
|
|
|
|
R_ARM_JUMP_SLOT = 22
|
|
|
|
|
R_ARM_RELATIVE = 23
|
|
|
|
|
R_ARM_GOTOFF = 24
|
|
|
|
|
R_ARM_GOTPC = 25
|
|
|
|
|
R_ARM_GOT32 = 26
|
|
|
|
|
R_ARM_PLT32 = 27
|
|
|
|
|
R_ARM_CALL = 28
|
|
|
|
|
R_ARM_JUMP24 = 29
|
|
|
|
|
R_ARM_V4BX = 40
|
|
|
|
|
R_ARM_GOT_PREL = 96
|
|
|
|
|
R_ARM_GNU_VTENTRY = 100
|
|
|
|
|
R_ARM_GNU_VTINHERIT = 101
|
|
|
|
|
R_ARM_TLS_IE32 = 107
|
|
|
|
|
R_ARM_TLS_LE32 = 108
|
|
|
|
|
R_ARM_RSBREL32 = 250
|
|
|
|
|
R_ARM_THM_RPC22 = 251
|
|
|
|
|
R_ARM_RREL32 = 252
|
|
|
|
|
R_ARM_RABS32 = 253
|
|
|
|
|
R_ARM_RPC24 = 254
|
|
|
|
|
R_ARM_RBASE = 255
|
|
|
|
|
|
2015-10-31 14:44:48 -07:00
|
|
|
R_386_NONE = 0
|
|
|
|
|
R_386_32 = 1
|
|
|
|
|
R_386_PC32 = 2
|
|
|
|
|
R_386_GOT32 = 3
|
|
|
|
|
R_386_PLT32 = 4
|
|
|
|
|
R_386_COPY = 5
|
|
|
|
|
R_386_GLOB_DAT = 6
|
|
|
|
|
R_386_JMP_SLOT = 7
|
|
|
|
|
R_386_RELATIVE = 8
|
|
|
|
|
R_386_GOTOFF = 9
|
|
|
|
|
R_386_GOTPC = 10
|
|
|
|
|
R_386_TLS_TPOFF = 14
|
|
|
|
|
R_386_TLS_IE = 15
|
|
|
|
|
R_386_TLS_GOTIE = 16
|
|
|
|
|
R_386_TLS_LE = 17
|
|
|
|
|
R_386_TLS_GD = 18
|
|
|
|
|
R_386_TLS_LDM = 19
|
|
|
|
|
R_386_TLS_GD_32 = 24
|
|
|
|
|
R_386_TLS_GD_PUSH = 25
|
|
|
|
|
R_386_TLS_GD_CALL = 26
|
|
|
|
|
R_386_TLS_GD_POP = 27
|
|
|
|
|
R_386_TLS_LDM_32 = 28
|
|
|
|
|
R_386_TLS_LDM_PUSH = 29
|
|
|
|
|
R_386_TLS_LDM_CALL = 30
|
|
|
|
|
R_386_TLS_LDM_POP = 31
|
|
|
|
|
R_386_TLS_LDO_32 = 32
|
|
|
|
|
R_386_TLS_IE_32 = 33
|
|
|
|
|
R_386_TLS_LE_32 = 34
|
|
|
|
|
R_386_TLS_DTPMOD32 = 35
|
|
|
|
|
R_386_TLS_DTPOFF32 = 36
|
|
|
|
|
R_386_TLS_TPOFF32 = 37
|
|
|
|
|
R_386_TLS_GOTDESC = 39
|
|
|
|
|
R_386_TLS_DESC_CALL = 40
|
|
|
|
|
R_386_TLS_DESC = 41
|
|
|
|
|
R_386_IRELATIVE = 42
|
|
|
|
|
R_386_GOT32X = 43
|
2015-08-11 14:10:03 +12:00
|
|
|
|
2016-04-27 22:18:09 -04:00
|
|
|
R_MIPS_NONE = 0
|
|
|
|
|
R_MIPS_16 = 1
|
|
|
|
|
R_MIPS_32 = 2
|
|
|
|
|
R_MIPS_REL32 = 3
|
|
|
|
|
R_MIPS_26 = 4
|
|
|
|
|
R_MIPS_HI16 = 5
|
|
|
|
|
R_MIPS_LO16 = 6
|
|
|
|
|
R_MIPS_GPREL16 = 7
|
|
|
|
|
R_MIPS_LITERAL = 8
|
|
|
|
|
R_MIPS_GOT16 = 9
|
|
|
|
|
R_MIPS_PC16 = 10
|
|
|
|
|
R_MIPS_CALL16 = 11
|
|
|
|
|
R_MIPS_GPREL32 = 12
|
|
|
|
|
R_MIPS_SHIFT5 = 16
|
|
|
|
|
R_MIPS_SHIFT6 = 17
|
|
|
|
|
R_MIPS_64 = 18
|
|
|
|
|
R_MIPS_GOT_DISP = 19
|
|
|
|
|
R_MIPS_GOT_PAGE = 20
|
|
|
|
|
R_MIPS_GOT_OFST = 21
|
|
|
|
|
R_MIPS_GOT_HI16 = 22
|
|
|
|
|
R_MIPS_GOT_LO16 = 23
|
|
|
|
|
R_MIPS_SUB = 24
|
|
|
|
|
R_MIPS_INSERT_A = 25
|
|
|
|
|
R_MIPS_INSERT_B = 26
|
|
|
|
|
R_MIPS_DELETE = 27
|
|
|
|
|
R_MIPS_HIGHER = 28
|
|
|
|
|
R_MIPS_HIGHEST = 29
|
|
|
|
|
R_MIPS_CALL_HI16 = 30
|
|
|
|
|
R_MIPS_CALL_LO16 = 31
|
|
|
|
|
R_MIPS_SCN_DISP = 32
|
|
|
|
|
R_MIPS_REL16 = 33
|
|
|
|
|
R_MIPS_ADD_IMMEDIATE = 34
|
|
|
|
|
R_MIPS_PJUMP = 35
|
|
|
|
|
R_MIPS_RELGOT = 36
|
|
|
|
|
R_MIPS_JALR = 37
|
|
|
|
|
R_MIPS_TLS_DTPMOD32 = 38
|
|
|
|
|
R_MIPS_TLS_DTPREL32 = 39
|
|
|
|
|
R_MIPS_TLS_DTPMOD64 = 40
|
|
|
|
|
R_MIPS_TLS_DTPREL64 = 41
|
|
|
|
|
R_MIPS_TLS_GD = 42
|
|
|
|
|
R_MIPS_TLS_LDM = 43
|
|
|
|
|
R_MIPS_TLS_DTPREL_HI16 = 44
|
|
|
|
|
R_MIPS_TLS_DTPREL_LO16 = 45
|
|
|
|
|
R_MIPS_TLS_GOTTPREL = 46
|
|
|
|
|
R_MIPS_TLS_TPREL32 = 47
|
|
|
|
|
R_MIPS_TLS_TPREL64 = 48
|
|
|
|
|
R_MIPS_TLS_TPREL_HI16 = 49
|
|
|
|
|
R_MIPS_TLS_TPREL_LO16 = 50
|
|
|
|
|
|
2015-08-11 14:10:03 +12:00
|
|
|
R_PPC_NONE = 0
|
|
|
|
|
R_PPC_ADDR32 = 1
|
|
|
|
|
R_PPC_ADDR24 = 2
|
|
|
|
|
R_PPC_ADDR16 = 3
|
|
|
|
|
R_PPC_ADDR16_LO = 4
|
|
|
|
|
R_PPC_ADDR16_HI = 5
|
|
|
|
|
R_PPC_ADDR16_HA = 6
|
|
|
|
|
R_PPC_ADDR14 = 7
|
|
|
|
|
R_PPC_ADDR14_BRTAKEN = 8
|
|
|
|
|
R_PPC_ADDR14_BRNTAKEN = 9
|
|
|
|
|
R_PPC_REL24 = 10
|
|
|
|
|
R_PPC_REL14 = 11
|
|
|
|
|
R_PPC_REL14_BRTAKEN = 12
|
|
|
|
|
R_PPC_REL14_BRNTAKEN = 13
|
|
|
|
|
R_PPC_GOT16 = 14
|
|
|
|
|
R_PPC_GOT16_LO = 15
|
|
|
|
|
R_PPC_GOT16_HI = 16
|
|
|
|
|
R_PPC_GOT16_HA = 17
|
|
|
|
|
R_PPC_PLTREL24 = 18
|
|
|
|
|
R_PPC_COPY = 19
|
|
|
|
|
R_PPC_GLOB_DAT = 20
|
|
|
|
|
R_PPC_JMP_SLOT = 21
|
|
|
|
|
R_PPC_RELATIVE = 22
|
|
|
|
|
R_PPC_LOCAL24PC = 23
|
|
|
|
|
R_PPC_UADDR32 = 24
|
|
|
|
|
R_PPC_UADDR16 = 25
|
|
|
|
|
R_PPC_REL32 = 26
|
|
|
|
|
R_PPC_PLT32 = 27
|
|
|
|
|
R_PPC_PLTREL32 = 28
|
|
|
|
|
R_PPC_PLT16_LO = 29
|
|
|
|
|
R_PPC_PLT16_HI = 30
|
|
|
|
|
R_PPC_PLT16_HA = 31
|
|
|
|
|
R_PPC_SDAREL16 = 32
|
|
|
|
|
R_PPC_SECTOFF = 33
|
|
|
|
|
R_PPC_SECTOFF_LO = 34
|
|
|
|
|
R_PPC_SECTOFF_HI = 35
|
|
|
|
|
R_PPC_SECTOFF_HA = 36
|
|
|
|
|
R_PPC_TLS = 67
|
|
|
|
|
R_PPC_DTPMOD32 = 68
|
|
|
|
|
R_PPC_TPREL16 = 69
|
|
|
|
|
R_PPC_TPREL16_LO = 70
|
|
|
|
|
R_PPC_TPREL16_HI = 71
|
|
|
|
|
R_PPC_TPREL16_HA = 72
|
|
|
|
|
R_PPC_TPREL32 = 73
|
|
|
|
|
R_PPC_DTPREL16 = 74
|
|
|
|
|
R_PPC_DTPREL16_LO = 75
|
|
|
|
|
R_PPC_DTPREL16_HI = 76
|
|
|
|
|
R_PPC_DTPREL16_HA = 77
|
|
|
|
|
R_PPC_DTPREL32 = 78
|
|
|
|
|
R_PPC_GOT_TLSGD16 = 79
|
|
|
|
|
R_PPC_GOT_TLSGD16_LO = 80
|
|
|
|
|
R_PPC_GOT_TLSGD16_HI = 81
|
|
|
|
|
R_PPC_GOT_TLSGD16_HA = 82
|
|
|
|
|
R_PPC_GOT_TLSLD16 = 83
|
|
|
|
|
R_PPC_GOT_TLSLD16_LO = 84
|
|
|
|
|
R_PPC_GOT_TLSLD16_HI = 85
|
|
|
|
|
R_PPC_GOT_TLSLD16_HA = 86
|
|
|
|
|
R_PPC_GOT_TPREL16 = 87
|
|
|
|
|
R_PPC_GOT_TPREL16_LO = 88
|
|
|
|
|
R_PPC_GOT_TPREL16_HI = 89
|
|
|
|
|
R_PPC_GOT_TPREL16_HA = 90
|
|
|
|
|
R_PPC_EMB_NADDR32 = 101
|
|
|
|
|
R_PPC_EMB_NADDR16 = 102
|
|
|
|
|
R_PPC_EMB_NADDR16_LO = 103
|
|
|
|
|
R_PPC_EMB_NADDR16_HI = 104
|
|
|
|
|
R_PPC_EMB_NADDR16_HA = 105
|
|
|
|
|
R_PPC_EMB_SDAI16 = 106
|
|
|
|
|
R_PPC_EMB_SDA2I16 = 107
|
|
|
|
|
R_PPC_EMB_SDA2REL = 108
|
|
|
|
|
R_PPC_EMB_SDA21 = 109
|
|
|
|
|
R_PPC_EMB_MRKREF = 110
|
|
|
|
|
R_PPC_EMB_RELSEC16 = 111
|
|
|
|
|
R_PPC_EMB_RELST_LO = 112
|
|
|
|
|
R_PPC_EMB_RELST_HI = 113
|
|
|
|
|
R_PPC_EMB_RELST_HA = 114
|
|
|
|
|
R_PPC_EMB_BIT_FLD = 115
|
|
|
|
|
R_PPC_EMB_RELSDA = 116
|
|
|
|
|
|
2015-10-16 21:15:18 +13:00
|
|
|
R_PPC64_ADDR32 = R_PPC_ADDR32
|
|
|
|
|
R_PPC64_ADDR16_LO = R_PPC_ADDR16_LO
|
|
|
|
|
R_PPC64_ADDR16_HA = R_PPC_ADDR16_HA
|
|
|
|
|
R_PPC64_REL24 = R_PPC_REL24
|
|
|
|
|
R_PPC64_GOT16_HA = R_PPC_GOT16_HA
|
|
|
|
|
R_PPC64_JMP_SLOT = R_PPC_JMP_SLOT
|
|
|
|
|
R_PPC64_TPREL16 = R_PPC_TPREL16
|
|
|
|
|
R_PPC64_ADDR64 = 38
|
|
|
|
|
R_PPC64_TOC16 = 47
|
|
|
|
|
R_PPC64_TOC16_LO = 48
|
|
|
|
|
R_PPC64_TOC16_HI = 49
|
|
|
|
|
R_PPC64_TOC16_HA = 50
|
|
|
|
|
R_PPC64_ADDR16_LO_DS = 57
|
|
|
|
|
R_PPC64_GOT16_LO_DS = 59
|
|
|
|
|
R_PPC64_TOC16_DS = 63
|
|
|
|
|
R_PPC64_TOC16_LO_DS = 64
|
|
|
|
|
R_PPC64_TLS = 67
|
|
|
|
|
R_PPC64_GOT_TPREL16_LO_DS = 88
|
|
|
|
|
R_PPC64_GOT_TPREL16_HA = 90
|
|
|
|
|
R_PPC64_REL16_LO = 250
|
|
|
|
|
R_PPC64_REL16_HI = 251
|
|
|
|
|
R_PPC64_REL16_HA = 252
|
2015-08-11 14:10:03 +12:00
|
|
|
|
|
|
|
|
R_SPARC_NONE = 0
|
|
|
|
|
R_SPARC_8 = 1
|
|
|
|
|
R_SPARC_16 = 2
|
|
|
|
|
R_SPARC_32 = 3
|
|
|
|
|
R_SPARC_DISP8 = 4
|
|
|
|
|
R_SPARC_DISP16 = 5
|
|
|
|
|
R_SPARC_DISP32 = 6
|
|
|
|
|
R_SPARC_WDISP30 = 7
|
|
|
|
|
R_SPARC_WDISP22 = 8
|
|
|
|
|
R_SPARC_HI22 = 9
|
|
|
|
|
R_SPARC_22 = 10
|
|
|
|
|
R_SPARC_13 = 11
|
|
|
|
|
R_SPARC_LO10 = 12
|
|
|
|
|
R_SPARC_GOT10 = 13
|
|
|
|
|
R_SPARC_GOT13 = 14
|
|
|
|
|
R_SPARC_GOT22 = 15
|
|
|
|
|
R_SPARC_PC10 = 16
|
|
|
|
|
R_SPARC_PC22 = 17
|
|
|
|
|
R_SPARC_WPLT30 = 18
|
|
|
|
|
R_SPARC_COPY = 19
|
|
|
|
|
R_SPARC_GLOB_DAT = 20
|
|
|
|
|
R_SPARC_JMP_SLOT = 21
|
|
|
|
|
R_SPARC_RELATIVE = 22
|
|
|
|
|
R_SPARC_UA32 = 23
|
|
|
|
|
R_SPARC_PLT32 = 24
|
|
|
|
|
R_SPARC_HIPLT22 = 25
|
|
|
|
|
R_SPARC_LOPLT10 = 26
|
|
|
|
|
R_SPARC_PCPLT32 = 27
|
|
|
|
|
R_SPARC_PCPLT22 = 28
|
|
|
|
|
R_SPARC_PCPLT10 = 29
|
|
|
|
|
R_SPARC_10 = 30
|
|
|
|
|
R_SPARC_11 = 31
|
|
|
|
|
R_SPARC_64 = 32
|
|
|
|
|
R_SPARC_OLO10 = 33
|
|
|
|
|
R_SPARC_HH22 = 34
|
|
|
|
|
R_SPARC_HM10 = 35
|
|
|
|
|
R_SPARC_LM22 = 36
|
|
|
|
|
R_SPARC_PC_HH22 = 37
|
|
|
|
|
R_SPARC_PC_HM10 = 38
|
|
|
|
|
R_SPARC_PC_LM22 = 39
|
|
|
|
|
R_SPARC_WDISP16 = 40
|
|
|
|
|
R_SPARC_WDISP19 = 41
|
|
|
|
|
R_SPARC_GLOB_JMP = 42
|
|
|
|
|
R_SPARC_7 = 43
|
|
|
|
|
R_SPARC_5 = 44
|
|
|
|
|
R_SPARC_6 = 45
|
|
|
|
|
R_SPARC_DISP64 = 46
|
|
|
|
|
R_SPARC_PLT64 = 47
|
|
|
|
|
R_SPARC_HIX22 = 48
|
|
|
|
|
R_SPARC_LOX10 = 49
|
|
|
|
|
R_SPARC_H44 = 50
|
|
|
|
|
R_SPARC_M44 = 51
|
|
|
|
|
R_SPARC_L44 = 52
|
|
|
|
|
R_SPARC_REGISTER = 53
|
|
|
|
|
R_SPARC_UA64 = 54
|
|
|
|
|
R_SPARC_UA16 = 55
|
|
|
|
|
|
2016-03-18 16:57:54 -04:00
|
|
|
R_390_NONE = 0
|
|
|
|
|
R_390_8 = 1
|
|
|
|
|
R_390_12 = 2
|
|
|
|
|
R_390_16 = 3
|
|
|
|
|
R_390_32 = 4
|
|
|
|
|
R_390_PC32 = 5
|
|
|
|
|
R_390_GOT12 = 6
|
|
|
|
|
R_390_GOT32 = 7
|
|
|
|
|
R_390_PLT32 = 8
|
|
|
|
|
R_390_COPY = 9
|
|
|
|
|
R_390_GLOB_DAT = 10
|
|
|
|
|
R_390_JMP_SLOT = 11
|
|
|
|
|
R_390_RELATIVE = 12
|
|
|
|
|
R_390_GOTOFF = 13
|
|
|
|
|
R_390_GOTPC = 14
|
|
|
|
|
R_390_GOT16 = 15
|
|
|
|
|
R_390_PC16 = 16
|
|
|
|
|
R_390_PC16DBL = 17
|
|
|
|
|
R_390_PLT16DBL = 18
|
|
|
|
|
R_390_PC32DBL = 19
|
|
|
|
|
R_390_PLT32DBL = 20
|
|
|
|
|
R_390_GOTPCDBL = 21
|
|
|
|
|
R_390_64 = 22
|
|
|
|
|
R_390_PC64 = 23
|
|
|
|
|
R_390_GOT64 = 24
|
|
|
|
|
R_390_PLT64 = 25
|
|
|
|
|
R_390_GOTENT = 26
|
|
|
|
|
R_390_GOTOFF16 = 27
|
|
|
|
|
R_390_GOTOFF64 = 28
|
|
|
|
|
R_390_GOTPLT12 = 29
|
|
|
|
|
R_390_GOTPLT16 = 30
|
|
|
|
|
R_390_GOTPLT32 = 31
|
|
|
|
|
R_390_GOTPLT64 = 32
|
|
|
|
|
R_390_GOTPLTENT = 33
|
|
|
|
|
R_390_GOTPLTOFF16 = 34
|
|
|
|
|
R_390_GOTPLTOFF32 = 35
|
|
|
|
|
R_390_GOTPLTOFF64 = 36
|
|
|
|
|
R_390_TLS_LOAD = 37
|
|
|
|
|
R_390_TLS_GDCALL = 38
|
|
|
|
|
R_390_TLS_LDCALL = 39
|
|
|
|
|
R_390_TLS_GD32 = 40
|
|
|
|
|
R_390_TLS_GD64 = 41
|
|
|
|
|
R_390_TLS_GOTIE12 = 42
|
|
|
|
|
R_390_TLS_GOTIE32 = 43
|
|
|
|
|
R_390_TLS_GOTIE64 = 44
|
|
|
|
|
R_390_TLS_LDM32 = 45
|
|
|
|
|
R_390_TLS_LDM64 = 46
|
|
|
|
|
R_390_TLS_IE32 = 47
|
|
|
|
|
R_390_TLS_IE64 = 48
|
|
|
|
|
R_390_TLS_IEENT = 49
|
|
|
|
|
R_390_TLS_LE32 = 50
|
|
|
|
|
R_390_TLS_LE64 = 51
|
|
|
|
|
R_390_TLS_LDO32 = 52
|
|
|
|
|
R_390_TLS_LDO64 = 53
|
|
|
|
|
R_390_TLS_DTPMOD = 54
|
|
|
|
|
R_390_TLS_DTPOFF = 55
|
|
|
|
|
R_390_TLS_TPOFF = 56
|
|
|
|
|
R_390_20 = 57
|
|
|
|
|
R_390_GOT20 = 58
|
|
|
|
|
R_390_GOTPLT20 = 59
|
|
|
|
|
R_390_TLS_GOTIE20 = 60
|
|
|
|
|
|
2015-08-11 14:10:03 +12:00
|
|
|
ARM_MAGIC_TRAMP_NUMBER = 0x5c000003
|
2015-02-27 22:57:28 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Symbol table entries.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* For accessing the fields of st_info. */
|
|
|
|
|
|
|
|
|
|
/* For constructing st_info from field values. */
|
|
|
|
|
|
|
|
|
|
/* For accessing the fields of st_other. */
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ELF header.
|
|
|
|
|
*/
|
|
|
|
|
type ElfEhdr struct {
|
|
|
|
|
ident [EI_NIDENT]uint8
|
|
|
|
|
type_ uint16
|
|
|
|
|
machine uint16
|
|
|
|
|
version uint32
|
|
|
|
|
entry uint64
|
|
|
|
|
phoff uint64
|
|
|
|
|
shoff uint64
|
|
|
|
|
flags uint32
|
|
|
|
|
ehsize uint16
|
|
|
|
|
phentsize uint16
|
|
|
|
|
phnum uint16
|
|
|
|
|
shentsize uint16
|
|
|
|
|
shnum uint16
|
|
|
|
|
shstrndx uint16
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Section header.
|
|
|
|
|
*/
|
|
|
|
|
type ElfShdr struct {
|
|
|
|
|
name uint32
|
|
|
|
|
type_ uint32
|
|
|
|
|
flags uint64
|
|
|
|
|
addr uint64
|
|
|
|
|
off uint64
|
|
|
|
|
size uint64
|
|
|
|
|
link uint32
|
|
|
|
|
info uint32
|
|
|
|
|
addralign uint64
|
|
|
|
|
entsize uint64
|
|
|
|
|
shnum int
|
2016-08-19 11:35:54 -04:00
|
|
|
secsym *Symbol
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Program header.
|
|
|
|
|
*/
|
|
|
|
|
type ElfPhdr struct {
|
|
|
|
|
type_ uint32
|
|
|
|
|
flags uint32
|
|
|
|
|
off uint64
|
|
|
|
|
vaddr uint64
|
|
|
|
|
paddr uint64
|
|
|
|
|
filesz uint64
|
|
|
|
|
memsz uint64
|
|
|
|
|
align uint64
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* For accessing the fields of r_info. */
|
|
|
|
|
|
|
|
|
|
/* For constructing r_info from field values. */
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Symbol table entries.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* For accessing the fields of st_info. */
|
|
|
|
|
|
|
|
|
|
/* For constructing st_info from field values. */
|
|
|
|
|
|
|
|
|
|
/* For accessing the fields of st_other. */
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Go linker interface
|
|
|
|
|
*/
|
|
|
|
|
const (
|
|
|
|
|
ELF64HDRSIZE = 64
|
|
|
|
|
ELF64PHDRSIZE = 56
|
|
|
|
|
ELF64SHDRSIZE = 64
|
|
|
|
|
ELF64RELSIZE = 16
|
|
|
|
|
ELF64RELASIZE = 24
|
|
|
|
|
ELF64SYMSIZE = 24
|
|
|
|
|
ELF32HDRSIZE = 52
|
|
|
|
|
ELF32PHDRSIZE = 32
|
|
|
|
|
ELF32SHDRSIZE = 40
|
|
|
|
|
ELF32SYMSIZE = 16
|
|
|
|
|
ELF32RELSIZE = 8
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The interface uses the 64-bit structures always,
|
|
|
|
|
* to avoid code duplication. The writers know how to
|
|
|
|
|
* marshal a 32-bit representation from the 64-bit structure.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
var Elfstrdat []byte
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Total amount of space to reserve at the start of the file
|
|
|
|
|
* for Header, PHeaders, SHeaders, and interp.
|
|
|
|
|
* May waste some.
|
|
|
|
|
* On FreeBSD, cannot be larger than a page.
|
|
|
|
|
*/
|
|
|
|
|
const (
|
2015-07-30 16:30:54 -04:00
|
|
|
ELFRESERVE = 4096
|
2015-02-27 22:57:28 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* We use the 64-bit data structures on both 32- and 64-bit machines
|
|
|
|
|
* in order to write the code just once. The 64-bit data structure is
|
|
|
|
|
* written in the 32-bit format on the 32-bit machines.
|
|
|
|
|
*/
|
|
|
|
|
const (
|
2016-08-25 11:07:33 -05:00
|
|
|
NSECT = 400
|
2015-02-27 22:57:28 -05:00
|
|
|
)
|
|
|
|
|
|
2016-04-03 19:32:31 +12:00
|
|
|
var (
|
|
|
|
|
Iself bool
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-04-03 19:32:31 +12:00
|
|
|
Nelfsym int = 1
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-04-03 19:32:31 +12:00
|
|
|
elf64 bool
|
|
|
|
|
// Either ".rel" or ".rela" depending on which type of relocation the
|
|
|
|
|
// target platform uses.
|
|
|
|
|
elfRelType string
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-04-03 19:32:31 +12:00
|
|
|
ehdr ElfEhdr
|
|
|
|
|
phdr [NSECT]*ElfPhdr
|
|
|
|
|
shdr [NSECT]*ElfShdr
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-04-03 19:32:31 +12:00
|
|
|
interp string
|
|
|
|
|
)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
type Elfstring struct {
|
|
|
|
|
s string
|
|
|
|
|
off int
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var elfstr [100]Elfstring
|
|
|
|
|
|
|
|
|
|
var nelfstr int
|
|
|
|
|
|
|
|
|
|
var buildinfo []byte
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Initialize the global variable that describes the ELF header. It will be updated as
|
|
|
|
|
we write section and prog headers.
|
|
|
|
|
*/
|
2016-08-19 22:40:38 -04:00
|
|
|
func Elfinit(ctxt *Link) {
|
2015-02-27 22:57:28 -05:00
|
|
|
Iself = true
|
|
|
|
|
|
2017-09-30 21:10:49 +00:00
|
|
|
if ctxt.Arch.InFamily(sys.AMD64, sys.ARM64, sys.MIPS64, sys.PPC64, sys.S390X) {
|
2016-04-03 19:32:31 +12:00
|
|
|
elfRelType = ".rela"
|
2016-04-06 12:01:40 -07:00
|
|
|
} else {
|
2016-04-03 19:32:31 +12:00
|
|
|
elfRelType = ".rel"
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-30 21:10:49 +00:00
|
|
|
switch ctxt.Arch.Family {
|
2015-02-27 22:57:28 -05:00
|
|
|
// 64-bit architectures
|
2016-04-06 12:01:40 -07:00
|
|
|
case sys.PPC64, sys.S390X:
|
2016-08-19 22:40:38 -04:00
|
|
|
if ctxt.Arch.ByteOrder == binary.BigEndian {
|
2015-02-27 22:57:28 -05:00
|
|
|
ehdr.flags = 1 /* Version 1 ABI */
|
|
|
|
|
} else {
|
|
|
|
|
ehdr.flags = 2 /* Version 2 ABI */
|
|
|
|
|
}
|
|
|
|
|
fallthrough
|
2016-04-06 12:01:40 -07:00
|
|
|
case sys.AMD64, sys.ARM64, sys.MIPS64:
|
2017-09-30 21:10:49 +00:00
|
|
|
if ctxt.Arch.Family == sys.MIPS64 {
|
2017-05-04 16:13:24 -04:00
|
|
|
ehdr.flags = 0x20000004 /* MIPS 3 CPIC */
|
2015-09-10 11:32:49 -04:00
|
|
|
}
|
2015-04-08 08:44:08 -07:00
|
|
|
elf64 = true
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
ehdr.phoff = ELF64HDRSIZE /* Must be be ELF64HDRSIZE: first PHdr must follow ELF header */
|
|
|
|
|
ehdr.shoff = ELF64HDRSIZE /* Will move as we add PHeaders */
|
|
|
|
|
ehdr.ehsize = ELF64HDRSIZE /* Must be ELF64HDRSIZE */
|
|
|
|
|
ehdr.phentsize = ELF64PHDRSIZE /* Must be ELF64PHDRSIZE */
|
|
|
|
|
ehdr.shentsize = ELF64SHDRSIZE /* Must be ELF64SHDRSIZE */
|
|
|
|
|
|
|
|
|
|
// 32-bit architectures
|
2016-10-18 23:50:45 +02:00
|
|
|
case sys.ARM, sys.MIPS:
|
2017-09-30 21:10:49 +00:00
|
|
|
if ctxt.Arch.Family == sys.ARM {
|
2016-10-18 23:50:45 +02:00
|
|
|
// we use EABI on linux/arm, freebsd/arm, netbsd/arm.
|
2017-04-18 12:53:25 -07:00
|
|
|
if Headtype == objabi.Hlinux || Headtype == objabi.Hfreebsd || Headtype == objabi.Hnetbsd {
|
2016-10-18 23:50:45 +02:00
|
|
|
// We set a value here that makes no indication of which
|
|
|
|
|
// float ABI the object uses, because this is information
|
|
|
|
|
// used by the dynamic linker to compare executables and
|
|
|
|
|
// shared libraries -- so it only matters for cgo calls, and
|
|
|
|
|
// the information properly comes from the object files
|
|
|
|
|
// produced by the host C compiler. parseArmAttributes in
|
|
|
|
|
// ldelf.go reads that information and updates this field as
|
|
|
|
|
// appropriate.
|
|
|
|
|
ehdr.flags = 0x5000002 // has entry point, Version5 EABI
|
|
|
|
|
}
|
2017-09-30 21:10:49 +00:00
|
|
|
} else if ctxt.Arch.Family == sys.MIPS {
|
2016-12-13 21:23:39 +01:00
|
|
|
ehdr.flags = 0x50001004 /* MIPS 32 CPIC O32*/
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
fallthrough
|
|
|
|
|
default:
|
|
|
|
|
ehdr.phoff = ELF32HDRSIZE
|
|
|
|
|
/* Must be be ELF32HDRSIZE: first PHdr must follow ELF header */
|
|
|
|
|
ehdr.shoff = ELF32HDRSIZE /* Will move as we add PHeaders */
|
|
|
|
|
ehdr.ehsize = ELF32HDRSIZE /* Must be ELF32HDRSIZE */
|
|
|
|
|
ehdr.phentsize = ELF32PHDRSIZE /* Must be ELF32PHDRSIZE */
|
|
|
|
|
ehdr.shentsize = ELF32SHDRSIZE /* Must be ELF32SHDRSIZE */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-15 19:24:44 +02:00
|
|
|
// Make sure PT_LOAD is aligned properly and
|
|
|
|
|
// that there is no gap,
|
|
|
|
|
// correct ELF loaders will do this implicitly,
|
|
|
|
|
// but buggy ELF loaders like the one in some
|
|
|
|
|
// versions of QEMU and UPX won't.
|
|
|
|
|
func fixElfPhdr(e *ElfPhdr) {
|
|
|
|
|
frag := int(e.vaddr & (e.align - 1))
|
|
|
|
|
|
|
|
|
|
e.off -= uint64(frag)
|
|
|
|
|
e.vaddr -= uint64(frag)
|
|
|
|
|
e.paddr -= uint64(frag)
|
|
|
|
|
e.filesz += uint64(frag)
|
|
|
|
|
e.memsz += uint64(frag)
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
func elf64phdr(out *OutBuf, e *ElfPhdr) {
|
2016-01-15 19:24:44 +02:00
|
|
|
if e.type_ == PT_LOAD {
|
|
|
|
|
fixElfPhdr(e)
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
out.Write32(e.type_)
|
|
|
|
|
out.Write32(e.flags)
|
|
|
|
|
out.Write64(e.off)
|
|
|
|
|
out.Write64(e.vaddr)
|
|
|
|
|
out.Write64(e.paddr)
|
|
|
|
|
out.Write64(e.filesz)
|
|
|
|
|
out.Write64(e.memsz)
|
|
|
|
|
out.Write64(e.align)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
func elf32phdr(out *OutBuf, e *ElfPhdr) {
|
2015-02-27 22:57:28 -05:00
|
|
|
if e.type_ == PT_LOAD {
|
2016-01-15 19:24:44 +02:00
|
|
|
fixElfPhdr(e)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
out.Write32(e.type_)
|
|
|
|
|
out.Write32(uint32(e.off))
|
|
|
|
|
out.Write32(uint32(e.vaddr))
|
|
|
|
|
out.Write32(uint32(e.paddr))
|
|
|
|
|
out.Write32(uint32(e.filesz))
|
|
|
|
|
out.Write32(uint32(e.memsz))
|
|
|
|
|
out.Write32(e.flags)
|
|
|
|
|
out.Write32(uint32(e.align))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
func elf64shdr(out *OutBuf, e *ElfShdr) {
|
|
|
|
|
out.Write32(e.name)
|
|
|
|
|
out.Write32(e.type_)
|
|
|
|
|
out.Write64(e.flags)
|
|
|
|
|
out.Write64(e.addr)
|
|
|
|
|
out.Write64(e.off)
|
|
|
|
|
out.Write64(e.size)
|
|
|
|
|
out.Write32(e.link)
|
|
|
|
|
out.Write32(e.info)
|
|
|
|
|
out.Write64(e.addralign)
|
|
|
|
|
out.Write64(e.entsize)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
func elf32shdr(out *OutBuf, e *ElfShdr) {
|
|
|
|
|
out.Write32(e.name)
|
|
|
|
|
out.Write32(e.type_)
|
|
|
|
|
out.Write32(uint32(e.flags))
|
|
|
|
|
out.Write32(uint32(e.addr))
|
|
|
|
|
out.Write32(uint32(e.off))
|
|
|
|
|
out.Write32(uint32(e.size))
|
|
|
|
|
out.Write32(e.link)
|
|
|
|
|
out.Write32(e.info)
|
|
|
|
|
out.Write32(uint32(e.addralign))
|
|
|
|
|
out.Write32(uint32(e.entsize))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
func elfwriteshdrs(out *OutBuf) uint32 {
|
2015-04-08 08:44:08 -07:00
|
|
|
if elf64 {
|
2015-03-02 12:35:15 -05:00
|
|
|
for i := 0; i < int(ehdr.shnum); i++ {
|
2017-10-01 02:37:20 +00:00
|
|
|
elf64shdr(out, shdr[i])
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
return uint32(ehdr.shnum) * ELF64SHDRSIZE
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
for i := 0; i < int(ehdr.shnum); i++ {
|
2017-10-01 02:37:20 +00:00
|
|
|
elf32shdr(out, shdr[i])
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
return uint32(ehdr.shnum) * ELF32SHDRSIZE
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
func elfsetstring(s *Symbol, str string, off int) {
|
2015-02-27 22:57:28 -05:00
|
|
|
if nelfstr >= len(elfstr) {
|
2016-09-17 09:39:33 -04:00
|
|
|
Errorf(s, "too many elf strings")
|
2015-04-09 07:37:17 -04:00
|
|
|
errorexit()
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
elfstr[nelfstr].s = str
|
2015-02-27 22:57:28 -05:00
|
|
|
elfstr[nelfstr].off = off
|
|
|
|
|
nelfstr++
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
func elfwritephdrs(out *OutBuf) uint32 {
|
2015-04-08 08:44:08 -07:00
|
|
|
if elf64 {
|
2015-03-02 12:35:15 -05:00
|
|
|
for i := 0; i < int(ehdr.phnum); i++ {
|
2017-10-01 02:37:20 +00:00
|
|
|
elf64phdr(out, phdr[i])
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
return uint32(ehdr.phnum) * ELF64PHDRSIZE
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
for i := 0; i < int(ehdr.phnum); i++ {
|
2017-10-01 02:37:20 +00:00
|
|
|
elf32phdr(out, phdr[i])
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
return uint32(ehdr.phnum) * ELF32PHDRSIZE
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
func newElfPhdr() *ElfPhdr {
|
2015-03-02 12:35:15 -05:00
|
|
|
e := new(ElfPhdr)
|
2015-02-27 22:57:28 -05:00
|
|
|
if ehdr.phnum >= NSECT {
|
2016-09-17 09:39:33 -04:00
|
|
|
Errorf(nil, "too many phdrs")
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
|
|
|
|
phdr[ehdr.phnum] = e
|
|
|
|
|
ehdr.phnum++
|
|
|
|
|
}
|
2015-04-08 08:44:08 -07:00
|
|
|
if elf64 {
|
2015-02-27 22:57:28 -05:00
|
|
|
ehdr.shoff += ELF64PHDRSIZE
|
|
|
|
|
} else {
|
|
|
|
|
ehdr.shoff += ELF32PHDRSIZE
|
|
|
|
|
}
|
|
|
|
|
return e
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
func newElfShdr(name int64) *ElfShdr {
|
2015-03-02 12:35:15 -05:00
|
|
|
e := new(ElfShdr)
|
2015-02-27 22:57:28 -05:00
|
|
|
e.name = uint32(name)
|
|
|
|
|
e.shnum = int(ehdr.shnum)
|
|
|
|
|
if ehdr.shnum >= NSECT {
|
2016-09-17 09:39:33 -04:00
|
|
|
Errorf(nil, "too many shdrs")
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
|
|
|
|
shdr[ehdr.shnum] = e
|
|
|
|
|
ehdr.shnum++
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return e
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getElfEhdr() *ElfEhdr {
|
|
|
|
|
return &ehdr
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
func elf64writehdr(out *OutBuf) uint32 {
|
|
|
|
|
out.Write(ehdr.ident[:])
|
|
|
|
|
out.Write16(ehdr.type_)
|
|
|
|
|
out.Write16(ehdr.machine)
|
|
|
|
|
out.Write32(ehdr.version)
|
|
|
|
|
out.Write64(ehdr.entry)
|
|
|
|
|
out.Write64(ehdr.phoff)
|
|
|
|
|
out.Write64(ehdr.shoff)
|
|
|
|
|
out.Write32(ehdr.flags)
|
|
|
|
|
out.Write16(ehdr.ehsize)
|
|
|
|
|
out.Write16(ehdr.phentsize)
|
|
|
|
|
out.Write16(ehdr.phnum)
|
|
|
|
|
out.Write16(ehdr.shentsize)
|
|
|
|
|
out.Write16(ehdr.shnum)
|
|
|
|
|
out.Write16(ehdr.shstrndx)
|
2015-02-27 22:57:28 -05:00
|
|
|
return ELF64HDRSIZE
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
func elf32writehdr(out *OutBuf) uint32 {
|
|
|
|
|
out.Write(ehdr.ident[:])
|
|
|
|
|
out.Write16(ehdr.type_)
|
|
|
|
|
out.Write16(ehdr.machine)
|
|
|
|
|
out.Write32(ehdr.version)
|
|
|
|
|
out.Write32(uint32(ehdr.entry))
|
|
|
|
|
out.Write32(uint32(ehdr.phoff))
|
|
|
|
|
out.Write32(uint32(ehdr.shoff))
|
|
|
|
|
out.Write32(ehdr.flags)
|
|
|
|
|
out.Write16(ehdr.ehsize)
|
|
|
|
|
out.Write16(ehdr.phentsize)
|
|
|
|
|
out.Write16(ehdr.phnum)
|
|
|
|
|
out.Write16(ehdr.shentsize)
|
|
|
|
|
out.Write16(ehdr.shnum)
|
|
|
|
|
out.Write16(ehdr.shstrndx)
|
2015-02-27 22:57:28 -05:00
|
|
|
return ELF32HDRSIZE
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
func elfwritehdr(out *OutBuf) uint32 {
|
2015-04-08 08:44:08 -07:00
|
|
|
if elf64 {
|
2017-10-01 02:37:20 +00:00
|
|
|
return elf64writehdr(out)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-10-01 02:37:20 +00:00
|
|
|
return elf32writehdr(out)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Taken directly from the definition document for ELF64 */
|
2016-03-02 14:29:44 -08:00
|
|
|
func elfhash(name string) uint32 {
|
|
|
|
|
var h uint32
|
|
|
|
|
for i := 0; i < len(name); i++ {
|
|
|
|
|
h = (h << 4) + uint32(name[i])
|
|
|
|
|
if g := h & 0xf0000000; g != 0 {
|
2015-02-27 22:57:28 -05:00
|
|
|
h ^= g >> 24
|
|
|
|
|
}
|
|
|
|
|
h &= 0x0fffffff
|
|
|
|
|
}
|
|
|
|
|
return h
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
func Elfwritedynent(ctxt *Link, s *Symbol, tag int, val uint64) {
|
2015-04-08 08:44:08 -07:00
|
|
|
if elf64 {
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint64(ctxt.Arch, uint64(tag))
|
|
|
|
|
s.AddUint64(ctxt.Arch, val)
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint32(ctxt.Arch, uint32(tag))
|
|
|
|
|
s.AddUint32(ctxt.Arch, uint32(val))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
func elfwritedynentsym(ctxt *Link, s *Symbol, tag int, t *Symbol) {
|
|
|
|
|
Elfwritedynentsymplus(ctxt, s, tag, t, 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
func Elfwritedynentsymplus(ctxt *Link, s *Symbol, tag int, t *Symbol, add int64) {
|
2015-04-08 08:44:08 -07:00
|
|
|
if elf64 {
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint64(ctxt.Arch, uint64(tag))
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint32(ctxt.Arch, uint32(tag))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddAddrPlus(ctxt.Arch, t, add)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
func elfwritedynentsymsize(ctxt *Link, s *Symbol, tag int, t *Symbol) {
|
2015-04-08 08:44:08 -07:00
|
|
|
if elf64 {
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint64(ctxt.Arch, uint64(tag))
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint32(ctxt.Arch, uint32(tag))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddSize(ctxt.Arch, t)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func elfinterp(sh *ElfShdr, startva uint64, resoff uint64, p string) int {
|
|
|
|
|
interp = p
|
2015-03-02 12:35:15 -05:00
|
|
|
n := len(interp) + 1
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.addr = startva + resoff - uint64(n)
|
|
|
|
|
sh.off = resoff - uint64(n)
|
|
|
|
|
sh.size = uint64(n)
|
|
|
|
|
|
|
|
|
|
return n
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
func elfwriteinterp(out *OutBuf) int {
|
2016-09-17 09:39:33 -04:00
|
|
|
sh := elfshname(".interp")
|
2017-10-01 02:37:20 +00:00
|
|
|
out.SeekSet(int64(sh.off))
|
|
|
|
|
out.WriteString(interp)
|
|
|
|
|
out.Write8(0)
|
2015-02-27 22:57:28 -05:00
|
|
|
return int(sh.size)
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-29 22:58:52 +12:00
|
|
|
func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sz int, alloc bool) int {
|
2015-03-02 12:35:15 -05:00
|
|
|
n := 3*4 + uint64(sz) + resoff%4
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
sh.type_ = SHT_NOTE
|
2015-04-29 22:58:52 +12:00
|
|
|
if alloc {
|
|
|
|
|
sh.flags = SHF_ALLOC
|
|
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.addralign = 4
|
|
|
|
|
sh.addr = startva + resoff - n
|
|
|
|
|
sh.off = resoff - n
|
|
|
|
|
sh.size = n - resoff%4
|
|
|
|
|
|
|
|
|
|
return int(n)
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
func elfwritenotehdr(out *OutBuf, str string, namesz uint32, descsz uint32, tag uint32) *ElfShdr {
|
2016-09-17 09:39:33 -04:00
|
|
|
sh := elfshname(str)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// Write Elf_Note header.
|
2017-10-01 02:37:20 +00:00
|
|
|
out.SeekSet(int64(sh.off))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
out.Write32(namesz)
|
|
|
|
|
out.Write32(descsz)
|
|
|
|
|
out.Write32(tag)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
return sh
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NetBSD Signature (as per sys/exec_elf.h)
|
|
|
|
|
const (
|
|
|
|
|
ELF_NOTE_NETBSD_NAMESZ = 7
|
|
|
|
|
ELF_NOTE_NETBSD_DESCSZ = 4
|
|
|
|
|
ELF_NOTE_NETBSD_TAG = 1
|
2015-03-05 13:57:36 -05:00
|
|
|
ELF_NOTE_NETBSD_VERSION = 599000000 /* NetBSD 5.99 */
|
2015-02-27 22:57:28 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var ELF_NOTE_NETBSD_NAME = []byte("NetBSD\x00")
|
|
|
|
|
|
|
|
|
|
func elfnetbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
|
2015-03-02 12:35:15 -05:00
|
|
|
n := int(Rnd(ELF_NOTE_NETBSD_NAMESZ, 4) + Rnd(ELF_NOTE_NETBSD_DESCSZ, 4))
|
2015-04-29 22:58:52 +12:00
|
|
|
return elfnote(sh, startva, resoff, n, true)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
func elfwritenetbsdsig(out *OutBuf) int {
|
2015-02-27 22:57:28 -05:00
|
|
|
// Write Elf_Note header.
|
2017-10-01 02:37:20 +00:00
|
|
|
sh := elfwritenotehdr(out, ".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
if sh == nil {
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Followed by NetBSD string and version.
|
2017-10-01 02:37:20 +00:00
|
|
|
out.Write(ELF_NOTE_NETBSD_NAME)
|
|
|
|
|
out.Write8(0)
|
|
|
|
|
out.Write32(ELF_NOTE_NETBSD_VERSION)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
return int(sh.size)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// OpenBSD Signature
|
|
|
|
|
const (
|
|
|
|
|
ELF_NOTE_OPENBSD_NAMESZ = 8
|
|
|
|
|
ELF_NOTE_OPENBSD_DESCSZ = 4
|
|
|
|
|
ELF_NOTE_OPENBSD_TAG = 1
|
|
|
|
|
ELF_NOTE_OPENBSD_VERSION = 0
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var ELF_NOTE_OPENBSD_NAME = []byte("OpenBSD\x00")
|
|
|
|
|
|
|
|
|
|
func elfopenbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
|
2015-03-02 12:35:15 -05:00
|
|
|
n := ELF_NOTE_OPENBSD_NAMESZ + ELF_NOTE_OPENBSD_DESCSZ
|
2015-04-29 22:58:52 +12:00
|
|
|
return elfnote(sh, startva, resoff, n, true)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
func elfwriteopenbsdsig(out *OutBuf) int {
|
2015-02-27 22:57:28 -05:00
|
|
|
// Write Elf_Note header.
|
2017-10-01 02:37:20 +00:00
|
|
|
sh := elfwritenotehdr(out, ".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
if sh == nil {
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Followed by OpenBSD string and version.
|
2017-10-01 02:37:20 +00:00
|
|
|
out.Write(ELF_NOTE_OPENBSD_NAME)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
out.Write32(ELF_NOTE_OPENBSD_VERSION)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
return int(sh.size)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func addbuildinfo(val string) {
|
2016-03-03 22:37:14 -08:00
|
|
|
if !strings.HasPrefix(val, "0x") {
|
2015-04-09 07:37:17 -04:00
|
|
|
Exitf("-B argument must start with 0x: %s", val)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
ov := val
|
2015-02-27 22:57:28 -05:00
|
|
|
val = val[2:]
|
|
|
|
|
|
2016-03-03 22:37:14 -08:00
|
|
|
const maxLen = 32
|
|
|
|
|
if hex.DecodedLen(len(val)) > maxLen {
|
|
|
|
|
Exitf("-B option too long (max %d digits): %s", maxLen, ov)
|
|
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-03-03 22:37:14 -08:00
|
|
|
b, err := hex.DecodeString(val)
|
|
|
|
|
if err != nil {
|
|
|
|
|
if err == hex.ErrLength {
|
|
|
|
|
Exitf("-B argument must have even number of digits: %s", ov)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2016-03-03 22:37:14 -08:00
|
|
|
if inv, ok := err.(hex.InvalidByteError); ok {
|
|
|
|
|
Exitf("-B argument contains invalid hex digit %c: %s", byte(inv), ov)
|
|
|
|
|
}
|
|
|
|
|
Exitf("-B argument contains invalid hex: %s", ov)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-03-03 22:37:14 -08:00
|
|
|
buildinfo = b
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Build info note
|
|
|
|
|
const (
|
|
|
|
|
ELF_NOTE_BUILDINFO_NAMESZ = 4
|
|
|
|
|
ELF_NOTE_BUILDINFO_TAG = 3
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var ELF_NOTE_BUILDINFO_NAME = []byte("GNU\x00")
|
|
|
|
|
|
|
|
|
|
func elfbuildinfo(sh *ElfShdr, startva uint64, resoff uint64) int {
|
2015-03-02 12:35:15 -05:00
|
|
|
n := int(ELF_NOTE_BUILDINFO_NAMESZ + Rnd(int64(len(buildinfo)), 4))
|
2015-04-29 22:58:52 +12:00
|
|
|
return elfnote(sh, startva, resoff, n, true)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2015-06-04 14:31:05 -04:00
|
|
|
func elfgobuildid(sh *ElfShdr, startva uint64, resoff uint64) int {
|
2016-08-21 18:34:24 -04:00
|
|
|
n := len(ELF_NOTE_GO_NAME) + int(Rnd(int64(len(*flagBuildid)), 4))
|
2015-06-04 14:31:05 -04:00
|
|
|
return elfnote(sh, startva, resoff, n, true)
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
func elfwritebuildinfo(out *OutBuf) int {
|
|
|
|
|
sh := elfwritenotehdr(out, ".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, uint32(len(buildinfo)), ELF_NOTE_BUILDINFO_TAG)
|
2015-02-27 22:57:28 -05:00
|
|
|
if sh == nil {
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
out.Write(ELF_NOTE_BUILDINFO_NAME)
|
|
|
|
|
out.Write(buildinfo)
|
2015-02-27 22:57:28 -05:00
|
|
|
var zero = make([]byte, 4)
|
2017-10-01 02:37:20 +00:00
|
|
|
out.Write(zero[:int(Rnd(int64(len(buildinfo)), 4)-int64(len(buildinfo)))])
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
return int(sh.size)
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
func elfwritegobuildid(out *OutBuf) int {
|
|
|
|
|
sh := elfwritenotehdr(out, ".note.go.buildid", uint32(len(ELF_NOTE_GO_NAME)), uint32(len(*flagBuildid)), ELF_NOTE_GOBUILDID_TAG)
|
2015-06-04 14:31:05 -04:00
|
|
|
if sh == nil {
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
out.Write(ELF_NOTE_GO_NAME)
|
|
|
|
|
out.Write([]byte(*flagBuildid))
|
2015-06-04 14:31:05 -04:00
|
|
|
var zero = make([]byte, 4)
|
2017-10-01 02:37:20 +00:00
|
|
|
out.Write(zero[:int(Rnd(int64(len(*flagBuildid)), 4)-int64(len(*flagBuildid)))])
|
2015-06-04 14:31:05 -04:00
|
|
|
|
|
|
|
|
return int(sh.size)
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-25 13:59:08 +12:00
|
|
|
// Go specific notes
|
2015-04-29 22:58:52 +12:00
|
|
|
const (
|
|
|
|
|
ELF_NOTE_GOPKGLIST_TAG = 1
|
2015-05-25 13:59:08 +12:00
|
|
|
ELF_NOTE_GOABIHASH_TAG = 2
|
2015-05-25 14:51:02 +12:00
|
|
|
ELF_NOTE_GODEPS_TAG = 3
|
2015-06-04 14:31:05 -04:00
|
|
|
ELF_NOTE_GOBUILDID_TAG = 4
|
2015-04-29 22:58:52 +12:00
|
|
|
)
|
|
|
|
|
|
2015-06-04 14:27:39 -04:00
|
|
|
var ELF_NOTE_GO_NAME = []byte("Go\x00\x00")
|
2015-04-29 22:58:52 +12:00
|
|
|
|
2015-02-27 22:57:28 -05:00
|
|
|
var elfverneed int
|
|
|
|
|
|
|
|
|
|
type Elfaux struct {
|
|
|
|
|
next *Elfaux
|
|
|
|
|
num int
|
|
|
|
|
vers string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Elflib struct {
|
|
|
|
|
next *Elflib
|
|
|
|
|
aux *Elfaux
|
|
|
|
|
file string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func addelflib(list **Elflib, file string, vers string) *Elfaux {
|
|
|
|
|
var lib *Elflib
|
|
|
|
|
|
|
|
|
|
for lib = *list; lib != nil; lib = lib.next {
|
|
|
|
|
if lib.file == file {
|
|
|
|
|
goto havelib
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
lib = new(Elflib)
|
|
|
|
|
lib.next = *list
|
|
|
|
|
lib.file = file
|
|
|
|
|
*list = lib
|
|
|
|
|
|
|
|
|
|
havelib:
|
2015-03-02 12:35:15 -05:00
|
|
|
for aux := lib.aux; aux != nil; aux = aux.next {
|
2015-02-27 22:57:28 -05:00
|
|
|
if aux.vers == vers {
|
2015-03-02 12:35:15 -05:00
|
|
|
return aux
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
2015-03-02 12:35:15 -05:00
|
|
|
aux := new(Elfaux)
|
2015-02-27 22:57:28 -05:00
|
|
|
aux.next = lib.aux
|
|
|
|
|
aux.vers = vers
|
|
|
|
|
lib.aux = aux
|
|
|
|
|
|
|
|
|
|
return aux
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
func elfdynhash(ctxt *Link) {
|
2015-02-27 22:57:28 -05:00
|
|
|
if !Iself {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
nsym := Nelfsym
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s := ctxt.Syms.Lookup(".hash", 0)
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SELFROSECT
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrReachable
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
i := nsym
|
|
|
|
|
nbucket := 1
|
2015-02-27 22:57:28 -05:00
|
|
|
for i > 0 {
|
|
|
|
|
nbucket++
|
|
|
|
|
i >>= 1
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-02 14:22:05 -05:00
|
|
|
var needlib *Elflib
|
2015-03-02 12:35:15 -05:00
|
|
|
need := make([]*Elfaux, nsym)
|
|
|
|
|
chain := make([]uint32, nsym)
|
|
|
|
|
buckets := make([]uint32, nbucket)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-09-20 14:59:39 +12:00
|
|
|
for _, sy := range ctxt.Syms.Allsym {
|
2015-02-27 22:57:28 -05:00
|
|
|
if sy.Dynid <= 0 {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if sy.Dynimpvers != "" {
|
|
|
|
|
need[sy.Dynid] = addelflib(&needlib, sy.Dynimplib, sy.Dynimpvers)
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-02 15:59:38 -05:00
|
|
|
name := sy.Extname
|
2016-03-02 14:29:44 -08:00
|
|
|
hc := elfhash(name)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-10-01 14:39:04 +11:00
|
|
|
b := hc % uint32(nbucket)
|
2015-02-27 22:57:28 -05:00
|
|
|
chain[sy.Dynid] = buckets[b]
|
|
|
|
|
buckets[b] = uint32(sy.Dynid)
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-18 16:57:54 -04:00
|
|
|
// s390x (ELF64) hash table entries are 8 bytes
|
2017-09-30 21:10:49 +00:00
|
|
|
if ctxt.Arch.Family == sys.S390X {
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint64(ctxt.Arch, uint64(nbucket))
|
|
|
|
|
s.AddUint64(ctxt.Arch, uint64(nsym))
|
2016-03-18 16:57:54 -04:00
|
|
|
for i := 0; i < nbucket; i++ {
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint64(ctxt.Arch, uint64(buckets[i]))
|
2016-03-18 16:57:54 -04:00
|
|
|
}
|
|
|
|
|
for i := 0; i < nsym; i++ {
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint64(ctxt.Arch, uint64(chain[i]))
|
2016-03-18 16:57:54 -04:00
|
|
|
}
|
|
|
|
|
} else {
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint32(ctxt.Arch, uint32(nbucket))
|
|
|
|
|
s.AddUint32(ctxt.Arch, uint32(nsym))
|
2016-03-18 16:57:54 -04:00
|
|
|
for i := 0; i < nbucket; i++ {
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint32(ctxt.Arch, buckets[i])
|
2016-03-18 16:57:54 -04:00
|
|
|
}
|
|
|
|
|
for i := 0; i < nsym; i++ {
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint32(ctxt.Arch, chain[i])
|
2016-03-18 16:57:54 -04:00
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// version symbols
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
dynstr := ctxt.Syms.Lookup(".dynstr", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s = ctxt.Syms.Lookup(".gnu.version_r", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
i = 2
|
2015-03-02 12:35:15 -05:00
|
|
|
nfile := 0
|
|
|
|
|
for l := needlib; l != nil; l = l.next {
|
2015-02-27 22:57:28 -05:00
|
|
|
nfile++
|
|
|
|
|
|
|
|
|
|
// header
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint16(ctxt.Arch, 1) // table version
|
2017-10-01 14:39:04 +11:00
|
|
|
j := 0
|
|
|
|
|
for x := l.aux; x != nil; x = x.next {
|
2015-02-27 22:57:28 -05:00
|
|
|
j++
|
|
|
|
|
}
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint16(ctxt.Arch, uint16(j)) // aux count
|
|
|
|
|
s.AddUint32(ctxt.Arch, uint32(Addstring(dynstr, l.file))) // file string offset
|
|
|
|
|
s.AddUint32(ctxt.Arch, 16) // offset from header to first aux
|
2015-02-27 22:57:28 -05:00
|
|
|
if l.next != nil {
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint32(ctxt.Arch, 16+uint32(j)*16) // offset from this header to next
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint32(ctxt.Arch, 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-10-01 14:39:04 +11:00
|
|
|
for x := l.aux; x != nil; x = x.next {
|
2015-02-27 22:57:28 -05:00
|
|
|
x.num = i
|
|
|
|
|
i++
|
|
|
|
|
|
|
|
|
|
// aux struct
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint32(ctxt.Arch, elfhash(x.vers)) // hash
|
|
|
|
|
s.AddUint16(ctxt.Arch, 0) // flags
|
|
|
|
|
s.AddUint16(ctxt.Arch, uint16(x.num)) // other - index we refer to this by
|
|
|
|
|
s.AddUint32(ctxt.Arch, uint32(Addstring(dynstr, x.vers))) // version string offset
|
2015-02-27 22:57:28 -05:00
|
|
|
if x.next != nil {
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint32(ctxt.Arch, 16) // offset from this aux to next
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint32(ctxt.Arch, 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// version references
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s = ctxt.Syms.Lookup(".gnu.version", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
for i := 0; i < nsym; i++ {
|
2015-02-27 22:57:28 -05:00
|
|
|
if i == 0 {
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint16(ctxt.Arch, 0) // first entry - no symbol
|
2015-02-27 22:57:28 -05:00
|
|
|
} else if need[i] == nil {
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint16(ctxt.Arch, 1) // global
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint16(ctxt.Arch, uint16(need[i].num))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s = ctxt.Syms.Lookup(".dynamic", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
elfverneed = nfile
|
|
|
|
|
if elfverneed != 0 {
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
elfwritedynentsym(ctxt, s, DT_VERNEED, ctxt.Syms.Lookup(".gnu.version_r", 0))
|
2016-08-19 22:40:38 -04:00
|
|
|
Elfwritedynent(ctxt, s, DT_VERNEEDNUM, uint64(nfile))
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
elfwritedynentsym(ctxt, s, DT_VERSYM, ctxt.Syms.Lookup(".gnu.version", 0))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
sy := ctxt.Syms.Lookup(elfRelType+".plt", 0)
|
2016-04-03 19:32:31 +12:00
|
|
|
if sy.Size > 0 {
|
|
|
|
|
if elfRelType == ".rela" {
|
2016-08-19 22:40:38 -04:00
|
|
|
Elfwritedynent(ctxt, s, DT_PLTREL, DT_RELA)
|
2016-04-03 19:32:31 +12:00
|
|
|
} else {
|
2016-08-19 22:40:38 -04:00
|
|
|
Elfwritedynent(ctxt, s, DT_PLTREL, DT_REL)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2016-08-19 22:40:38 -04:00
|
|
|
elfwritedynentsymsize(ctxt, s, DT_PLTRELSZ, sy)
|
|
|
|
|
elfwritedynentsym(ctxt, s, DT_JMPREL, sy)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
Elfwritedynent(ctxt, s, DT_NULL, 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-09-20 15:57:53 +12:00
|
|
|
func elfphload(seg *Segment) *ElfPhdr {
|
2016-09-17 09:39:33 -04:00
|
|
|
ph := newElfPhdr()
|
2015-02-27 22:57:28 -05:00
|
|
|
ph.type_ = PT_LOAD
|
|
|
|
|
if seg.Rwx&4 != 0 {
|
|
|
|
|
ph.flags |= PF_R
|
|
|
|
|
}
|
|
|
|
|
if seg.Rwx&2 != 0 {
|
|
|
|
|
ph.flags |= PF_W
|
|
|
|
|
}
|
|
|
|
|
if seg.Rwx&1 != 0 {
|
|
|
|
|
ph.flags |= PF_X
|
|
|
|
|
}
|
|
|
|
|
ph.vaddr = seg.Vaddr
|
|
|
|
|
ph.paddr = seg.Vaddr
|
|
|
|
|
ph.memsz = seg.Length
|
|
|
|
|
ph.off = seg.Fileoff
|
|
|
|
|
ph.filesz = seg.Filelen
|
2016-08-21 18:34:24 -04:00
|
|
|
ph.align = uint64(*FlagRound)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
return ph
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-20 15:57:53 +12:00
|
|
|
func elfphrelro(seg *Segment) {
|
2016-09-17 09:39:33 -04:00
|
|
|
ph := newElfPhdr()
|
2016-09-06 08:02:30 -04:00
|
|
|
ph.type_ = PT_GNU_RELRO
|
|
|
|
|
ph.vaddr = seg.Vaddr
|
|
|
|
|
ph.paddr = seg.Vaddr
|
|
|
|
|
ph.memsz = seg.Length
|
|
|
|
|
ph.off = seg.Fileoff
|
|
|
|
|
ph.filesz = seg.Filelen
|
|
|
|
|
ph.align = uint64(*FlagRound)
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
func elfshname(name string) *ElfShdr {
|
2015-03-02 12:35:15 -05:00
|
|
|
for i := 0; i < nelfstr; i++ {
|
2015-02-27 22:57:28 -05:00
|
|
|
if name == elfstr[i].s {
|
2017-10-01 14:39:04 +11:00
|
|
|
off := elfstr[i].off
|
2015-03-02 12:35:15 -05:00
|
|
|
for i = 0; i < int(ehdr.shnum); i++ {
|
2017-10-01 14:39:04 +11:00
|
|
|
sh := shdr[i]
|
2015-03-02 12:35:15 -05:00
|
|
|
if sh.name == uint32(off) {
|
|
|
|
|
return sh
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-10-01 14:39:04 +11:00
|
|
|
return newElfShdr(int64(off))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
2016-09-17 09:39:33 -04:00
|
|
|
Exitf("cannot find elf name %s", name)
|
2015-02-27 22:57:28 -05:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-25 11:07:33 -05:00
|
|
|
// Create an ElfShdr for the section with name.
|
|
|
|
|
// Create a duplicate if one already exists with that name
|
|
|
|
|
func elfshnamedup(name string) *ElfShdr {
|
|
|
|
|
for i := 0; i < nelfstr; i++ {
|
|
|
|
|
if name == elfstr[i].s {
|
2017-10-01 14:39:04 +11:00
|
|
|
off := elfstr[i].off
|
|
|
|
|
return newElfShdr(int64(off))
|
2016-08-25 11:07:33 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Errorf(nil, "cannot find elf name %s", name)
|
|
|
|
|
errorexit()
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
func elfshalloc(sect *Section) *ElfShdr {
|
|
|
|
|
sh := elfshname(sect.Name)
|
2015-02-27 22:57:28 -05:00
|
|
|
sect.Elfsect = sh
|
|
|
|
|
return sh
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
func elfshbits(sect *Section) *ElfShdr {
|
2016-08-25 11:07:33 -05:00
|
|
|
var sh *ElfShdr
|
|
|
|
|
|
|
|
|
|
if sect.Name == ".text" {
|
|
|
|
|
if sect.Elfsect == nil {
|
|
|
|
|
sect.Elfsect = elfshnamedup(sect.Name)
|
|
|
|
|
}
|
|
|
|
|
sh = sect.Elfsect
|
|
|
|
|
} else {
|
|
|
|
|
sh = elfshalloc(sect)
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-25 13:59:08 +12:00
|
|
|
// If this section has already been set up as a note, we assume type_ and
|
|
|
|
|
// flags are already correct, but the other fields still need filling in.
|
|
|
|
|
if sh.type_ == SHT_NOTE {
|
|
|
|
|
if Linkmode != LinkExternal {
|
|
|
|
|
// TODO(mwhudson): the approach here will work OK when
|
|
|
|
|
// linking internally for notes that we want to be included
|
|
|
|
|
// in a loadable segment (e.g. the abihash note) but not for
|
|
|
|
|
// notes that we do not want to be mapped (e.g. the package
|
|
|
|
|
// list note). The real fix is probably to define new values
|
2016-08-22 10:27:20 +12:00
|
|
|
// for Symbol.Type corresponding to mapped and unmapped notes
|
2015-05-25 13:59:08 +12:00
|
|
|
// and handle them in dodata().
|
2016-09-17 09:39:33 -04:00
|
|
|
Errorf(nil, "sh.type_ == SHT_NOTE in elfshbits when linking internally")
|
2015-05-25 13:59:08 +12:00
|
|
|
}
|
|
|
|
|
sh.addralign = uint64(sect.Align)
|
|
|
|
|
sh.size = sect.Length
|
|
|
|
|
sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr
|
|
|
|
|
return sh
|
|
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
if sh.type_ > 0 {
|
|
|
|
|
return sh
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if sect.Vaddr < sect.Seg.Vaddr+sect.Seg.Filelen {
|
|
|
|
|
sh.type_ = SHT_PROGBITS
|
|
|
|
|
} else {
|
|
|
|
|
sh.type_ = SHT_NOBITS
|
|
|
|
|
}
|
|
|
|
|
sh.flags = SHF_ALLOC
|
|
|
|
|
if sect.Rwx&1 != 0 {
|
|
|
|
|
sh.flags |= SHF_EXECINSTR
|
|
|
|
|
}
|
|
|
|
|
if sect.Rwx&2 != 0 {
|
|
|
|
|
sh.flags |= SHF_WRITE
|
|
|
|
|
}
|
|
|
|
|
if sect.Name == ".tbss" {
|
2015-09-02 11:23:15 +12:00
|
|
|
sh.flags |= SHF_TLS
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.type_ = SHT_NOBITS
|
|
|
|
|
}
|
2016-03-14 09:23:04 -07:00
|
|
|
if strings.HasPrefix(sect.Name, ".debug") {
|
|
|
|
|
sh.flags = 0
|
|
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
if Linkmode != LinkExternal {
|
|
|
|
|
sh.addr = sect.Vaddr
|
|
|
|
|
}
|
|
|
|
|
sh.addralign = uint64(sect.Align)
|
|
|
|
|
sh.size = sect.Length
|
2015-09-02 11:23:15 +12:00
|
|
|
if sect.Name != ".tbss" {
|
2015-08-11 12:29:00 +12:00
|
|
|
sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr
|
|
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
return sh
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-30 21:10:49 +00:00
|
|
|
func elfshreloc(arch *sys.Arch, sect *Section) *ElfShdr {
|
2015-02-27 22:57:28 -05:00
|
|
|
// If main section is SHT_NOBITS, nothing to relocate.
|
2015-05-25 13:59:08 +12:00
|
|
|
// Also nothing to relocate in .shstrtab or notes.
|
2015-02-27 22:57:28 -05:00
|
|
|
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
if sect.Name == ".shstrtab" || sect.Name == ".tbss" {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2015-05-25 13:59:08 +12:00
|
|
|
if sect.Elfsect.type_ == SHT_NOTE {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
var typ int
|
2016-04-03 19:32:31 +12:00
|
|
|
if elfRelType == ".rela" {
|
2015-02-27 22:57:28 -05:00
|
|
|
typ = SHT_RELA
|
2016-04-03 19:32:31 +12:00
|
|
|
} else {
|
2015-02-27 22:57:28 -05:00
|
|
|
typ = SHT_REL
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
sh := elfshname(elfRelType + sect.Name)
|
2016-08-25 11:07:33 -05:00
|
|
|
// There could be multiple text sections but each needs
|
|
|
|
|
// its own .rela.text.
|
|
|
|
|
|
|
|
|
|
if sect.Name == ".text" {
|
|
|
|
|
if sh.info != 0 && sh.info != uint32(sect.Elfsect.shnum) {
|
|
|
|
|
sh = elfshnamedup(elfRelType + sect.Name)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.type_ = uint32(typ)
|
2017-09-30 21:10:49 +00:00
|
|
|
sh.entsize = uint64(arch.RegSize) * 2
|
2015-02-27 22:57:28 -05:00
|
|
|
if typ == SHT_RELA {
|
2017-09-30 21:10:49 +00:00
|
|
|
sh.entsize += uint64(arch.RegSize)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2016-09-17 09:39:33 -04:00
|
|
|
sh.link = uint32(elfshname(".symtab").shnum)
|
2015-05-27 12:04:25 +12:00
|
|
|
sh.info = uint32(sect.Elfsect.shnum)
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.off = sect.Reloff
|
|
|
|
|
sh.size = sect.Rellen
|
2017-09-30 21:10:49 +00:00
|
|
|
sh.addralign = uint64(arch.RegSize)
|
2015-02-27 22:57:28 -05:00
|
|
|
return sh
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
func elfrelocsect(ctxt *Link, sect *Section, syms []*Symbol) {
|
2015-02-27 22:57:28 -05:00
|
|
|
// If main section is SHT_NOBITS, nothing to relocate.
|
|
|
|
|
// Also nothing to relocate in .shstrtab.
|
|
|
|
|
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if sect.Name == ".shstrtab" {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
sect.Reloff = uint64(ctxt.Out.Offset())
|
2016-04-18 14:50:14 -04:00
|
|
|
for i, s := range syms {
|
|
|
|
|
if !s.Attr.Reachable() {
|
2015-02-27 22:57:28 -05:00
|
|
|
continue
|
|
|
|
|
}
|
2016-04-18 14:50:14 -04:00
|
|
|
if uint64(s.Value) >= sect.Vaddr {
|
|
|
|
|
syms = syms[i:]
|
2015-02-27 22:57:28 -05:00
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
eaddr := int32(sect.Vaddr + sect.Length)
|
2016-04-18 14:50:14 -04:00
|
|
|
for _, sym := range syms {
|
2016-03-02 07:59:49 -05:00
|
|
|
if !sym.Attr.Reachable() {
|
2015-02-27 22:57:28 -05:00
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if sym.Value >= int64(eaddr) {
|
|
|
|
|
break
|
|
|
|
|
}
|
2016-04-20 10:36:27 -04:00
|
|
|
for ri := 0; ri < len(sym.R); ri++ {
|
|
|
|
|
r := &sym.R[ri]
|
2017-08-27 22:00:00 +09:00
|
|
|
if r.Done {
|
2015-02-27 22:57:28 -05:00
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if r.Xsym == nil {
|
[dev.debug] cmd/compile: better DWARF with optimizations on
Debuggers use DWARF information to find local variables on the
stack and in registers. Prior to this CL, the DWARF information for
functions claimed that all variables were on the stack at all times.
That's incorrect when optimizations are enabled, and results in
debuggers showing data that is out of date or complete gibberish.
After this CL, the compiler is capable of representing variable
locations more accurately, and attempts to do so. Due to limitations of
the SSA backend, it's not possible to be completely correct.
There are a number of problems in the current design. One of the easier
to understand is that variable names currently must be attached to an
SSA value, but not all assignments in the source code actually result
in machine code. For example:
type myint int
var a int
b := myint(int)
and
b := (*uint64)(unsafe.Pointer(a))
don't generate machine code because the underlying representation is the
same, so the correct value of b will not be set when the user would
expect.
Generating the more precise debug information is behind a flag,
dwarflocationlists. Because of the issues described above, setting the
flag may not make the debugging experience much better, and may actually
make it worse in cases where the variable actually is on the stack and
the more complicated analysis doesn't realize it.
A number of changes are included:
- Add a new pseudo-instruction, RegKill, which indicates that the value
in the register has been clobbered.
- Adjust regalloc to emit RegKills in the right places. Significantly,
this means that phis are mixed with StoreReg and RegKills after
regalloc.
- Track variable decomposition in ssa.LocalSlots.
- After the SSA backend is done, analyze the result and build location
lists for each LocalSlot.
- After assembly is done, update the location lists with the assembled
PC offsets, recompose variables, and build DWARF location lists. Emit the
list as a new linker symbol, one per function.
- In the linker, aggregate the location lists into a .debug_loc section.
TODO:
- currently disabled for non-X86/AMD64 because there are no data tables.
go build -toolexec 'toolstash -cmp' -a std succeeds.
With -dwarflocationlists false:
before: f02812195637909ff675782c0b46836a8ff01976
after: 06f61e8112a42ac34fb80e0c818b3cdb84a5e7ec
benchstat -geomean /tmp/220352263 /tmp/621364410
completed 15 of 15, estimated time remaining 0s (eta 3:52PM)
name old time/op new time/op delta
Template 199ms ± 3% 198ms ± 2% ~ (p=0.400 n=15+14)
Unicode 96.6ms ± 5% 96.4ms ± 5% ~ (p=0.838 n=15+15)
GoTypes 653ms ± 2% 647ms ± 2% ~ (p=0.102 n=15+14)
Flate 133ms ± 6% 129ms ± 3% -2.62% (p=0.041 n=15+15)
GoParser 164ms ± 5% 159ms ± 3% -3.05% (p=0.000 n=15+15)
Reflect 428ms ± 4% 422ms ± 3% ~ (p=0.156 n=15+13)
Tar 123ms ±10% 124ms ± 8% ~ (p=0.461 n=15+15)
XML 228ms ± 3% 224ms ± 3% -1.57% (p=0.045 n=15+15)
[Geo mean] 206ms 377ms +82.86%
name old user-time/op new user-time/op delta
Template 292ms ±10% 301ms ±12% ~ (p=0.189 n=15+15)
Unicode 166ms ±37% 158ms ±14% ~ (p=0.418 n=15+14)
GoTypes 962ms ± 6% 963ms ± 7% ~ (p=0.976 n=15+15)
Flate 207ms ±19% 200ms ±14% ~ (p=0.345 n=14+15)
GoParser 246ms ±22% 240ms ±15% ~ (p=0.587 n=15+15)
Reflect 611ms ±13% 587ms ±14% ~ (p=0.085 n=15+13)
Tar 211ms ±12% 217ms ±14% ~ (p=0.355 n=14+15)
XML 335ms ±15% 320ms ±18% ~ (p=0.169 n=15+15)
[Geo mean] 317ms 583ms +83.72%
name old alloc/op new alloc/op delta
Template 40.2MB ± 0% 40.2MB ± 0% -0.15% (p=0.000 n=14+15)
Unicode 29.2MB ± 0% 29.3MB ± 0% ~ (p=0.624 n=15+15)
GoTypes 114MB ± 0% 114MB ± 0% -0.15% (p=0.000 n=15+14)
Flate 25.7MB ± 0% 25.6MB ± 0% -0.18% (p=0.000 n=13+15)
GoParser 32.2MB ± 0% 32.2MB ± 0% -0.14% (p=0.003 n=15+15)
Reflect 77.8MB ± 0% 77.9MB ± 0% ~ (p=0.061 n=15+15)
Tar 27.1MB ± 0% 27.0MB ± 0% -0.11% (p=0.029 n=15+15)
XML 42.7MB ± 0% 42.5MB ± 0% -0.29% (p=0.000 n=15+15)
[Geo mean] 42.1MB 75.0MB +78.05%
name old allocs/op new allocs/op delta
Template 402k ± 1% 398k ± 0% -0.91% (p=0.000 n=15+15)
Unicode 344k ± 1% 344k ± 0% ~ (p=0.715 n=15+14)
GoTypes 1.18M ± 0% 1.17M ± 0% -0.91% (p=0.000 n=15+14)
Flate 243k ± 0% 240k ± 1% -1.05% (p=0.000 n=13+15)
GoParser 327k ± 1% 324k ± 1% -0.96% (p=0.000 n=15+15)
Reflect 984k ± 1% 982k ± 0% ~ (p=0.050 n=15+15)
Tar 261k ± 1% 259k ± 1% -0.77% (p=0.000 n=15+15)
XML 411k ± 0% 404k ± 1% -1.55% (p=0.000 n=15+15)
[Geo mean] 439k 755k +72.01%
name old text-bytes new text-bytes delta
HelloSize 694kB ± 0% 694kB ± 0% -0.00% (p=0.000 n=15+15)
name old data-bytes new data-bytes delta
HelloSize 5.55kB ± 0% 5.55kB ± 0% ~ (all equal)
name old bss-bytes new bss-bytes delta
HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal)
name old exe-bytes new exe-bytes delta
HelloSize 1.04MB ± 0% 1.04MB ± 0% ~ (all equal)
Change-Id: I991fc553ef175db46bb23b2128317bbd48de70d8
Reviewed-on: https://go-review.googlesource.com/41770
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
2017-07-21 18:30:19 -04:00
|
|
|
Errorf(sym, "missing xsym in relocation %#v %#v", r.Sym.Name, sym)
|
2015-02-27 22:57:28 -05:00
|
|
|
continue
|
|
|
|
|
}
|
2015-10-29 12:17:43 +13:00
|
|
|
if r.Xsym.ElfsymForReloc() == 0 {
|
2017-09-30 21:10:49 +00:00
|
|
|
Errorf(sym, "reloc %d (%s) to non-elf symbol %s (outer=%s) %d (%s)", r.Type, RelocName(ctxt.Arch, r.Type), r.Sym.Name, r.Xsym.Name, r.Sym.Type, r.Sym.Type)
|
2016-09-17 09:39:33 -04:00
|
|
|
}
|
|
|
|
|
if !r.Xsym.Attr.Reachable() {
|
2017-09-30 21:10:49 +00:00
|
|
|
Errorf(sym, "unreachable reloc %d (%s) target %v", r.Type, RelocName(ctxt.Arch, r.Type), r.Xsym.Name)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-08-27 22:00:00 +09:00
|
|
|
if !Thearch.Elfreloc1(ctxt, r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) {
|
2017-09-30 21:10:49 +00:00
|
|
|
Errorf(sym, "unsupported obj reloc %d (%s)/%d to %s", r.Type, RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.Name)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
func Elfemitreloc(ctxt *Link) {
|
2017-10-01 02:37:20 +00:00
|
|
|
for ctxt.Out.Offset()&7 != 0 {
|
|
|
|
|
ctxt.Out.Write8(0)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segtext.Sections {
|
2016-08-25 11:07:33 -05:00
|
|
|
if sect.Name == ".text" {
|
|
|
|
|
elfrelocsect(ctxt, sect, ctxt.Textp)
|
|
|
|
|
} else {
|
|
|
|
|
elfrelocsect(ctxt, sect, datap)
|
|
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2016-08-25 11:07:33 -05:00
|
|
|
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segrodata.Sections {
|
2016-08-19 22:40:38 -04:00
|
|
|
elfrelocsect(ctxt, sect, datap)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segrelrodata.Sections {
|
2016-09-05 23:29:16 -04:00
|
|
|
elfrelocsect(ctxt, sect, datap)
|
|
|
|
|
}
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segdata.Sections {
|
2016-08-19 22:40:38 -04:00
|
|
|
elfrelocsect(ctxt, sect, datap)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segdwarf.Sections {
|
2016-04-22 10:31:14 +12:00
|
|
|
elfrelocsect(ctxt, sect, dwarfp)
|
2016-03-14 09:23:04 -07:00
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
func addgonote(ctxt *Link, sectionName string, tag uint32, desc []byte) {
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s := ctxt.Syms.Lookup(sectionName, 0)
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrReachable
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SELFROSECT
|
2015-05-25 13:59:08 +12:00
|
|
|
// namesz
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint32(ctxt.Arch, uint32(len(ELF_NOTE_GO_NAME)))
|
2015-05-25 13:59:08 +12:00
|
|
|
// descsz
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint32(ctxt.Arch, uint32(len(desc)))
|
2015-05-25 13:59:08 +12:00
|
|
|
// tag
|
2017-09-30 15:06:44 +00:00
|
|
|
s.AddUint32(ctxt.Arch, tag)
|
2015-05-25 13:59:08 +12:00
|
|
|
// name + padding
|
|
|
|
|
s.P = append(s.P, ELF_NOTE_GO_NAME...)
|
|
|
|
|
for len(s.P)%4 != 0 {
|
|
|
|
|
s.P = append(s.P, 0)
|
|
|
|
|
}
|
|
|
|
|
// desc + padding
|
|
|
|
|
s.P = append(s.P, desc...)
|
|
|
|
|
for len(s.P)%4 != 0 {
|
|
|
|
|
s.P = append(s.P, 0)
|
|
|
|
|
}
|
|
|
|
|
s.Size = int64(len(s.P))
|
2017-08-23 17:44:51 -07:00
|
|
|
s.Align = 4
|
2015-05-25 13:59:08 +12:00
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
func (ctxt *Link) doelf() {
|
2015-02-27 22:57:28 -05:00
|
|
|
if !Iself {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* predefine strings we need for section headers */
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
shstrtab := ctxt.Syms.Lookup(".shstrtab", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-04-19 15:15:35 +12:00
|
|
|
shstrtab.Type = SELFROSECT
|
2016-03-02 07:59:49 -05:00
|
|
|
shstrtab.Attr |= AttrReachable
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(shstrtab, "")
|
|
|
|
|
Addstring(shstrtab, ".text")
|
|
|
|
|
Addstring(shstrtab, ".noptrdata")
|
|
|
|
|
Addstring(shstrtab, ".data")
|
|
|
|
|
Addstring(shstrtab, ".bss")
|
|
|
|
|
Addstring(shstrtab, ".noptrbss")
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-04-12 01:10:01 +10:00
|
|
|
// generate .tbss section for dynamic internal linker or external
|
|
|
|
|
// linking, so that various binutils could correctly calculate
|
|
|
|
|
// PT_TLS size. See https://golang.org/issue/5200.
|
|
|
|
|
if !*FlagD || Linkmode == LinkExternal {
|
|
|
|
|
Addstring(shstrtab, ".tbss")
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 12:53:25 -07:00
|
|
|
if Headtype == objabi.Hnetbsd {
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(shstrtab, ".note.netbsd.ident")
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 12:53:25 -07:00
|
|
|
if Headtype == objabi.Hopenbsd {
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(shstrtab, ".note.openbsd.ident")
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
if len(buildinfo) > 0 {
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(shstrtab, ".note.gnu.build-id")
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2016-08-21 18:34:24 -04:00
|
|
|
if *flagBuildid != "" {
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(shstrtab, ".note.go.buildid")
|
2015-06-04 14:31:05 -04:00
|
|
|
}
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(shstrtab, ".elfdata")
|
|
|
|
|
Addstring(shstrtab, ".rodata")
|
2015-05-21 13:07:19 +12:00
|
|
|
// See the comment about data.rel.ro.FOO section names in data.go.
|
|
|
|
|
relro_prefix := ""
|
|
|
|
|
if UseRelro() {
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(shstrtab, ".data.rel.ro")
|
2015-05-21 13:07:19 +12:00
|
|
|
relro_prefix = ".data.rel.ro"
|
|
|
|
|
}
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(shstrtab, relro_prefix+".typelink")
|
|
|
|
|
Addstring(shstrtab, relro_prefix+".itablink")
|
|
|
|
|
Addstring(shstrtab, relro_prefix+".gosymtab")
|
|
|
|
|
Addstring(shstrtab, relro_prefix+".gopclntab")
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
if Linkmode == LinkExternal {
|
2016-08-21 18:34:24 -04:00
|
|
|
*FlagD = true
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(shstrtab, elfRelType+".text")
|
|
|
|
|
Addstring(shstrtab, elfRelType+".rodata")
|
|
|
|
|
Addstring(shstrtab, elfRelType+relro_prefix+".typelink")
|
|
|
|
|
Addstring(shstrtab, elfRelType+relro_prefix+".itablink")
|
|
|
|
|
Addstring(shstrtab, elfRelType+relro_prefix+".gosymtab")
|
|
|
|
|
Addstring(shstrtab, elfRelType+relro_prefix+".gopclntab")
|
|
|
|
|
Addstring(shstrtab, elfRelType+".noptrdata")
|
|
|
|
|
Addstring(shstrtab, elfRelType+".data")
|
2016-04-03 19:32:31 +12:00
|
|
|
if UseRelro() {
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(shstrtab, elfRelType+".data.rel.ro")
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// add a .note.GNU-stack section to mark the stack as non-executable
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(shstrtab, ".note.GNU-stack")
|
2015-05-25 13:59:08 +12:00
|
|
|
|
|
|
|
|
if Buildmode == BuildmodeShared {
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(shstrtab, ".note.go.abihash")
|
|
|
|
|
Addstring(shstrtab, ".note.go.pkg-list")
|
|
|
|
|
Addstring(shstrtab, ".note.go.deps")
|
2015-05-25 13:59:08 +12:00
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-08-21 18:34:24 -04:00
|
|
|
hasinitarr := *FlagLinkshared
|
2015-04-01 14:17:43 +13:00
|
|
|
|
|
|
|
|
/* shared library initializer */
|
2015-04-09 10:44:05 -04:00
|
|
|
switch Buildmode {
|
2016-08-25 21:58:45 -04:00
|
|
|
case BuildmodeCArchive, BuildmodeCShared, BuildmodeShared, BuildmodePlugin:
|
2015-04-01 14:17:43 +13:00
|
|
|
hasinitarr = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if hasinitarr {
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(shstrtab, ".init_array")
|
|
|
|
|
Addstring(shstrtab, elfRelType+".init_array")
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-08-21 18:34:24 -04:00
|
|
|
if !*FlagS {
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(shstrtab, ".symtab")
|
|
|
|
|
Addstring(shstrtab, ".strtab")
|
2016-08-19 22:40:38 -04:00
|
|
|
dwarfaddshstrings(ctxt, shstrtab)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(shstrtab, ".shstrtab")
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-08-21 18:34:24 -04:00
|
|
|
if !*FlagD { /* -d suppresses dynamic loader format */
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(shstrtab, ".interp")
|
|
|
|
|
Addstring(shstrtab, ".hash")
|
|
|
|
|
Addstring(shstrtab, ".got")
|
2017-09-30 21:10:49 +00:00
|
|
|
if ctxt.Arch.Family == sys.PPC64 {
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(shstrtab, ".glink")
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(shstrtab, ".got.plt")
|
|
|
|
|
Addstring(shstrtab, ".dynamic")
|
|
|
|
|
Addstring(shstrtab, ".dynsym")
|
|
|
|
|
Addstring(shstrtab, ".dynstr")
|
|
|
|
|
Addstring(shstrtab, elfRelType)
|
|
|
|
|
Addstring(shstrtab, elfRelType+".plt")
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(shstrtab, ".plt")
|
|
|
|
|
Addstring(shstrtab, ".gnu.version")
|
|
|
|
|
Addstring(shstrtab, ".gnu.version_r")
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
/* dynamic symbol table - first entry all zeros */
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s := ctxt.Syms.Lookup(".dynsym", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SELFROSECT
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrReachable
|
2016-04-05 23:01:10 -07:00
|
|
|
if elf64 {
|
2015-02-27 22:57:28 -05:00
|
|
|
s.Size += ELF64SYMSIZE
|
2016-04-05 23:01:10 -07:00
|
|
|
} else {
|
2015-02-27 22:57:28 -05:00
|
|
|
s.Size += ELF32SYMSIZE
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* dynamic string table */
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s = ctxt.Syms.Lookup(".dynstr", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SELFROSECT
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrReachable
|
2015-02-27 22:57:28 -05:00
|
|
|
if s.Size == 0 {
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(s, "")
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2015-03-02 12:35:15 -05:00
|
|
|
dynstr := s
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
/* relocation table */
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s = ctxt.Syms.Lookup(elfRelType, 0)
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrReachable
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SELFROSECT
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
/* global offset table */
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s = ctxt.Syms.Lookup(".got", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrReachable
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SELFGOT // writable
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
/* ppc64 glink resolver */
|
2017-09-30 21:10:49 +00:00
|
|
|
if ctxt.Arch.Family == sys.PPC64 {
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s := ctxt.Syms.Lookup(".glink", 0)
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrReachable
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SELFRXSECT
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* hash */
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s = ctxt.Syms.Lookup(".hash", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrReachable
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SELFROSECT
|
2015-02-27 22:57:28 -05:00
|
|
|
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s = ctxt.Syms.Lookup(".got.plt", 0)
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrReachable
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SELFSECT // writable
|
2015-02-27 22:57:28 -05:00
|
|
|
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s = ctxt.Syms.Lookup(".plt", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrReachable
|
2017-09-30 21:10:49 +00:00
|
|
|
if ctxt.Arch.Family == sys.PPC64 {
|
2015-02-27 22:57:28 -05:00
|
|
|
// In the ppc64 ABI, .plt is a data section
|
|
|
|
|
// written by the dynamic linker.
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SELFSECT
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SELFRXSECT
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-08-21 13:52:23 -04:00
|
|
|
Thearch.Elfsetupplt(ctxt)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s = ctxt.Syms.Lookup(elfRelType+".plt", 0)
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrReachable
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SELFROSECT
|
2015-02-27 22:57:28 -05:00
|
|
|
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s = ctxt.Syms.Lookup(".gnu.version", 0)
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrReachable
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SELFROSECT
|
2015-02-27 22:57:28 -05:00
|
|
|
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s = ctxt.Syms.Lookup(".gnu.version_r", 0)
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrReachable
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SELFROSECT
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
/* define dynamic elf table */
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s = ctxt.Syms.Lookup(".dynamic", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrReachable
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SELFSECT // writable
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* .dynamic table
|
|
|
|
|
*/
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
elfwritedynentsym(ctxt, s, DT_HASH, ctxt.Syms.Lookup(".hash", 0))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
elfwritedynentsym(ctxt, s, DT_SYMTAB, ctxt.Syms.Lookup(".dynsym", 0))
|
2016-04-05 23:01:10 -07:00
|
|
|
if elf64 {
|
2016-08-19 22:40:38 -04:00
|
|
|
Elfwritedynent(ctxt, s, DT_SYMENT, ELF64SYMSIZE)
|
2016-04-05 23:01:10 -07:00
|
|
|
} else {
|
2016-08-19 22:40:38 -04:00
|
|
|
Elfwritedynent(ctxt, s, DT_SYMENT, ELF32SYMSIZE)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
elfwritedynentsym(ctxt, s, DT_STRTAB, ctxt.Syms.Lookup(".dynstr", 0))
|
|
|
|
|
elfwritedynentsymsize(ctxt, s, DT_STRSZ, ctxt.Syms.Lookup(".dynstr", 0))
|
2016-04-03 19:32:31 +12:00
|
|
|
if elfRelType == ".rela" {
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
elfwritedynentsym(ctxt, s, DT_RELA, ctxt.Syms.Lookup(".rela", 0))
|
|
|
|
|
elfwritedynentsymsize(ctxt, s, DT_RELASZ, ctxt.Syms.Lookup(".rela", 0))
|
2016-08-19 22:40:38 -04:00
|
|
|
Elfwritedynent(ctxt, s, DT_RELAENT, ELF64RELASIZE)
|
2016-04-03 19:32:31 +12:00
|
|
|
} else {
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
elfwritedynentsym(ctxt, s, DT_REL, ctxt.Syms.Lookup(".rel", 0))
|
|
|
|
|
elfwritedynentsymsize(ctxt, s, DT_RELSZ, ctxt.Syms.Lookup(".rel", 0))
|
2016-08-19 22:40:38 -04:00
|
|
|
Elfwritedynent(ctxt, s, DT_RELENT, ELF32RELSIZE)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2015-04-12 02:31:28 +02:00
|
|
|
if rpath.val != "" {
|
2016-09-20 15:31:26 +12:00
|
|
|
Elfwritedynent(ctxt, s, DT_RUNPATH, uint64(Addstring(dynstr, rpath.val)))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-09-30 21:10:49 +00:00
|
|
|
if ctxt.Arch.Family == sys.PPC64 {
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".plt", 0))
|
2017-09-30 21:10:49 +00:00
|
|
|
} else if ctxt.Arch.Family == sys.S390X {
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".got", 0))
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".got.plt", 0))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-09-30 21:10:49 +00:00
|
|
|
if ctxt.Arch.Family == sys.PPC64 {
|
2016-08-19 22:40:38 -04:00
|
|
|
Elfwritedynent(ctxt, s, DT_PPC64_OPT, 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Solaris dynamic linker can't handle an empty .rela.plt if
|
|
|
|
|
// DT_JMPREL is emitted so we have to defer generation of DT_PLTREL,
|
|
|
|
|
// DT_PLTRELSZ, and DT_JMPREL dynamic entries until after we know the
|
|
|
|
|
// size of .rel(a).plt section.
|
2016-08-19 22:40:38 -04:00
|
|
|
Elfwritedynent(ctxt, s, DT_DEBUG, 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2015-05-25 13:59:08 +12:00
|
|
|
|
|
|
|
|
if Buildmode == BuildmodeShared {
|
|
|
|
|
// The go.link.abihashbytes symbol will be pointed at the appropriate
|
|
|
|
|
// part of the .note.go.abihash section in data.go:func address().
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrLocal
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SRODATA
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrSpecial
|
|
|
|
|
s.Attr |= AttrReachable
|
2015-05-25 13:59:08 +12:00
|
|
|
s.Size = int64(sha1.Size)
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
sort.Sort(byPkg(ctxt.Library))
|
2015-05-25 13:59:08 +12:00
|
|
|
h := sha1.New()
|
2016-08-19 22:40:38 -04:00
|
|
|
for _, l := range ctxt.Library {
|
2016-12-05 23:20:20 -05:00
|
|
|
io.WriteString(h, l.hash)
|
2015-05-25 13:59:08 +12:00
|
|
|
}
|
2016-08-19 22:40:38 -04:00
|
|
|
addgonote(ctxt, ".note.go.abihash", ELF_NOTE_GOABIHASH_TAG, h.Sum([]byte{}))
|
|
|
|
|
addgonote(ctxt, ".note.go.pkg-list", ELF_NOTE_GOPKGLIST_TAG, pkglistfornote)
|
2015-05-25 14:51:02 +12:00
|
|
|
var deplist []string
|
2016-08-19 22:40:38 -04:00
|
|
|
for _, shlib := range ctxt.Shlibs {
|
2015-05-25 14:51:02 +12:00
|
|
|
deplist = append(deplist, filepath.Base(shlib.Path))
|
|
|
|
|
}
|
2016-08-19 22:40:38 -04:00
|
|
|
addgonote(ctxt, ".note.go.deps", ELF_NOTE_GODEPS_TAG, []byte(strings.Join(deplist, "\n")))
|
2015-05-25 13:59:08 +12:00
|
|
|
}
|
2015-06-04 14:31:05 -04:00
|
|
|
|
2016-08-21 18:34:24 -04:00
|
|
|
if Linkmode == LinkExternal && *flagBuildid != "" {
|
|
|
|
|
addgonote(ctxt, ".note.go.buildid", ELF_NOTE_GOBUILDID_TAG, []byte(*flagBuildid))
|
2015-06-04 14:31:05 -04:00
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Do not write DT_NULL. elfdynhash will finish it.
|
2016-09-20 15:57:53 +12:00
|
|
|
func shsym(sh *ElfShdr, s *Symbol) {
|
2016-09-17 09:39:33 -04:00
|
|
|
addr := Symaddr(s)
|
2015-02-27 22:57:28 -05:00
|
|
|
if sh.flags&SHF_ALLOC != 0 {
|
|
|
|
|
sh.addr = uint64(addr)
|
|
|
|
|
}
|
2016-09-17 09:39:33 -04:00
|
|
|
sh.off = uint64(datoff(s, addr))
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.size = uint64(s.Size)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func phsh(ph *ElfPhdr, sh *ElfShdr) {
|
|
|
|
|
ph.vaddr = sh.addr
|
|
|
|
|
ph.paddr = ph.vaddr
|
|
|
|
|
ph.off = sh.off
|
|
|
|
|
ph.filesz = sh.size
|
|
|
|
|
ph.memsz = sh.size
|
|
|
|
|
ph.align = sh.addralign
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-20 15:57:53 +12:00
|
|
|
func Asmbelfsetup() {
|
2015-02-27 22:57:28 -05:00
|
|
|
/* This null SHdr must appear before all others */
|
2016-09-17 09:39:33 -04:00
|
|
|
elfshname("")
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segtext.Sections {
|
2016-08-25 11:07:33 -05:00
|
|
|
// There could be multiple .text sections. Instead check the Elfsect
|
|
|
|
|
// field to determine if already has an ElfShdr and if not, create one.
|
|
|
|
|
if sect.Name == ".text" {
|
|
|
|
|
if sect.Elfsect == nil {
|
|
|
|
|
sect.Elfsect = elfshnamedup(sect.Name)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
elfshalloc(sect)
|
|
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segrodata.Sections {
|
2016-09-17 09:39:33 -04:00
|
|
|
elfshalloc(sect)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segrelrodata.Sections {
|
2016-09-17 09:39:33 -04:00
|
|
|
elfshalloc(sect)
|
2016-09-05 23:29:16 -04:00
|
|
|
}
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segdata.Sections {
|
2016-09-17 09:39:33 -04:00
|
|
|
elfshalloc(sect)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segdwarf.Sections {
|
2016-09-17 09:39:33 -04:00
|
|
|
elfshalloc(sect)
|
2016-03-14 09:23:04 -07:00
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
func Asmbelf(ctxt *Link, symo int64) {
|
2015-03-02 12:35:15 -05:00
|
|
|
eh := getElfEhdr()
|
2017-09-30 21:10:49 +00:00
|
|
|
switch ctxt.Arch.Family {
|
2015-02-27 22:57:28 -05:00
|
|
|
default:
|
2017-09-30 21:10:49 +00:00
|
|
|
Exitf("unknown architecture in asmbelf: %v", ctxt.Arch.Family)
|
2016-10-18 23:50:47 +02:00
|
|
|
case sys.MIPS, sys.MIPS64:
|
2015-09-10 11:32:49 -04:00
|
|
|
eh.machine = EM_MIPS
|
2016-04-06 12:01:40 -07:00
|
|
|
case sys.ARM:
|
2015-02-27 22:57:28 -05:00
|
|
|
eh.machine = EM_ARM
|
2016-04-06 12:01:40 -07:00
|
|
|
case sys.AMD64:
|
2015-02-27 22:57:28 -05:00
|
|
|
eh.machine = EM_X86_64
|
2016-04-06 12:01:40 -07:00
|
|
|
case sys.ARM64:
|
2015-03-08 14:14:53 +01:00
|
|
|
eh.machine = EM_AARCH64
|
2016-04-06 12:01:40 -07:00
|
|
|
case sys.I386:
|
2015-02-27 22:57:28 -05:00
|
|
|
eh.machine = EM_386
|
2016-04-06 12:01:40 -07:00
|
|
|
case sys.PPC64:
|
2015-02-27 22:57:28 -05:00
|
|
|
eh.machine = EM_PPC64
|
2016-04-06 12:01:40 -07:00
|
|
|
case sys.S390X:
|
2016-03-18 16:57:54 -04:00
|
|
|
eh.machine = EM_S390
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2015-05-05 14:17:07 +12:00
|
|
|
elfreserve := int64(ELFRESERVE)
|
2016-08-25 11:07:33 -05:00
|
|
|
|
|
|
|
|
numtext := int64(0)
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segtext.Sections {
|
2016-08-25 11:07:33 -05:00
|
|
|
if sect.Name == ".text" {
|
|
|
|
|
numtext++
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If there are multiple text sections, extra space is needed
|
|
|
|
|
// in the elfreserve for the additional .text and .rela.text
|
|
|
|
|
// section headers. It can handle 4 extra now. Headers are
|
|
|
|
|
// 64 bytes.
|
|
|
|
|
|
|
|
|
|
if numtext > 4 {
|
|
|
|
|
elfreserve += elfreserve + numtext*64*2
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-21 18:34:24 -04:00
|
|
|
startva := *FlagTextAddr - int64(HEADR)
|
2015-05-05 14:17:07 +12:00
|
|
|
resoff := elfreserve
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2015-03-02 14:22:05 -05:00
|
|
|
var pph *ElfPhdr
|
2015-03-02 12:35:15 -05:00
|
|
|
var pnote *ElfPhdr
|
2015-02-27 22:57:28 -05:00
|
|
|
if Linkmode == LinkExternal {
|
|
|
|
|
/* skip program headers */
|
|
|
|
|
eh.phoff = 0
|
|
|
|
|
|
|
|
|
|
eh.phentsize = 0
|
2015-04-29 22:58:52 +12:00
|
|
|
|
|
|
|
|
if Buildmode == BuildmodeShared {
|
2016-09-17 09:39:33 -04:00
|
|
|
sh := elfshname(".note.go.pkg-list")
|
2015-05-25 13:59:08 +12:00
|
|
|
sh.type_ = SHT_NOTE
|
2016-09-17 09:39:33 -04:00
|
|
|
sh = elfshname(".note.go.abihash")
|
2015-05-25 13:59:08 +12:00
|
|
|
sh.type_ = SHT_NOTE
|
|
|
|
|
sh.flags = SHF_ALLOC
|
2016-09-17 09:39:33 -04:00
|
|
|
sh = elfshname(".note.go.deps")
|
2015-05-25 14:51:02 +12:00
|
|
|
sh.type_ = SHT_NOTE
|
2015-04-29 22:58:52 +12:00
|
|
|
}
|
2015-06-04 14:31:05 -04:00
|
|
|
|
2016-08-21 18:34:24 -04:00
|
|
|
if *flagBuildid != "" {
|
2016-09-17 09:39:33 -04:00
|
|
|
sh := elfshname(".note.go.buildid")
|
2015-06-04 14:31:05 -04:00
|
|
|
sh.type_ = SHT_NOTE
|
|
|
|
|
sh.flags = SHF_ALLOC
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-27 22:57:28 -05:00
|
|
|
goto elfobj
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* program header info */
|
2016-09-17 09:39:33 -04:00
|
|
|
pph = newElfPhdr()
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
pph.type_ = PT_PHDR
|
|
|
|
|
pph.flags = PF_R
|
|
|
|
|
pph.off = uint64(eh.ehsize)
|
2016-08-21 18:34:24 -04:00
|
|
|
pph.vaddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.off
|
|
|
|
|
pph.paddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.off
|
|
|
|
|
pph.align = uint64(*FlagRound)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* PHDR must be in a loaded segment. Adjust the text
|
|
|
|
|
* segment boundaries downwards to include it.
|
|
|
|
|
* Except on NaCl where it must not be loaded.
|
|
|
|
|
*/
|
2017-04-18 12:53:25 -07:00
|
|
|
if Headtype != objabi.Hnacl {
|
2015-03-02 12:35:15 -05:00
|
|
|
o := int64(Segtext.Vaddr - pph.vaddr)
|
2015-02-27 22:57:28 -05:00
|
|
|
Segtext.Vaddr -= uint64(o)
|
|
|
|
|
Segtext.Length += uint64(o)
|
|
|
|
|
o = int64(Segtext.Fileoff - pph.off)
|
|
|
|
|
Segtext.Fileoff -= uint64(o)
|
|
|
|
|
Segtext.Filelen += uint64(o)
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-21 18:34:24 -04:00
|
|
|
if !*FlagD { /* -d suppresses dynamic loader format */
|
2015-02-27 22:57:28 -05:00
|
|
|
/* interpreter */
|
2016-09-17 09:39:33 -04:00
|
|
|
sh := elfshname(".interp")
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
sh.type_ = SHT_PROGBITS
|
|
|
|
|
sh.flags = SHF_ALLOC
|
|
|
|
|
sh.addralign = 1
|
2016-08-22 22:29:24 -07:00
|
|
|
if interpreter == "" {
|
2016-09-09 06:20:44 -04:00
|
|
|
switch Headtype {
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hlinux:
|
2016-08-22 22:29:24 -07:00
|
|
|
interpreter = Thearch.Linuxdynld
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hfreebsd:
|
2016-08-22 22:29:24 -07:00
|
|
|
interpreter = Thearch.Freebsddynld
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hnetbsd:
|
2016-08-22 22:29:24 -07:00
|
|
|
interpreter = Thearch.Netbsddynld
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hopenbsd:
|
2016-08-22 22:29:24 -07:00
|
|
|
interpreter = Thearch.Openbsddynld
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hdragonfly:
|
2016-08-22 22:29:24 -07:00
|
|
|
interpreter = Thearch.Dragonflydynld
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hsolaris:
|
2016-08-22 22:29:24 -07:00
|
|
|
interpreter = Thearch.Solarisdynld
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-22 22:29:24 -07:00
|
|
|
resoff -= int64(elfinterp(sh, uint64(startva), uint64(resoff), interpreter))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
ph := newElfPhdr()
|
2015-02-27 22:57:28 -05:00
|
|
|
ph.type_ = PT_INTERP
|
|
|
|
|
ph.flags = PF_R
|
|
|
|
|
phsh(ph, sh)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pnote = nil
|
2017-04-18 12:53:25 -07:00
|
|
|
if Headtype == objabi.Hnetbsd || Headtype == objabi.Hopenbsd {
|
2015-03-02 14:22:05 -05:00
|
|
|
var sh *ElfShdr
|
2016-09-09 06:20:44 -04:00
|
|
|
switch Headtype {
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hnetbsd:
|
2016-09-17 09:39:33 -04:00
|
|
|
sh = elfshname(".note.netbsd.ident")
|
2015-02-27 22:57:28 -05:00
|
|
|
resoff -= int64(elfnetbsdsig(sh, uint64(startva), uint64(resoff)))
|
|
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hopenbsd:
|
2016-09-17 09:39:33 -04:00
|
|
|
sh = elfshname(".note.openbsd.ident")
|
2015-02-27 22:57:28 -05:00
|
|
|
resoff -= int64(elfopenbsdsig(sh, uint64(startva), uint64(resoff)))
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
pnote = newElfPhdr()
|
2015-02-27 22:57:28 -05:00
|
|
|
pnote.type_ = PT_NOTE
|
|
|
|
|
pnote.flags = PF_R
|
|
|
|
|
phsh(pnote, sh)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(buildinfo) > 0 {
|
2016-09-17 09:39:33 -04:00
|
|
|
sh := elfshname(".note.gnu.build-id")
|
2015-02-27 22:57:28 -05:00
|
|
|
resoff -= int64(elfbuildinfo(sh, uint64(startva), uint64(resoff)))
|
|
|
|
|
|
|
|
|
|
if pnote == nil {
|
2016-09-17 09:39:33 -04:00
|
|
|
pnote = newElfPhdr()
|
2015-02-27 22:57:28 -05:00
|
|
|
pnote.type_ = PT_NOTE
|
|
|
|
|
pnote.flags = PF_R
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
phsh(pnote, sh)
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-21 18:34:24 -04:00
|
|
|
if *flagBuildid != "" {
|
2016-09-17 09:39:33 -04:00
|
|
|
sh := elfshname(".note.go.buildid")
|
2015-06-04 14:31:05 -04:00
|
|
|
resoff -= int64(elfgobuildid(sh, uint64(startva), uint64(resoff)))
|
|
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
pnote := newElfPhdr()
|
2015-06-04 14:31:05 -04:00
|
|
|
pnote.type_ = PT_NOTE
|
|
|
|
|
pnote.flags = PF_R
|
|
|
|
|
phsh(pnote, sh)
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-27 22:57:28 -05:00
|
|
|
// Additions to the reserved area must be above this line.
|
|
|
|
|
|
2016-09-20 15:57:53 +12:00
|
|
|
elfphload(&Segtext)
|
2017-04-18 21:52:06 +12:00
|
|
|
if len(Segrodata.Sections) > 0 {
|
2016-09-20 15:57:53 +12:00
|
|
|
elfphload(&Segrodata)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 21:52:06 +12:00
|
|
|
if len(Segrelrodata.Sections) > 0 {
|
2016-09-20 15:57:53 +12:00
|
|
|
elfphload(&Segrelrodata)
|
|
|
|
|
elfphrelro(&Segrelrodata)
|
2016-09-05 23:29:16 -04:00
|
|
|
}
|
2016-09-20 15:57:53 +12:00
|
|
|
elfphload(&Segdata)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
/* Dynamic linking sections */
|
2016-08-21 18:34:24 -04:00
|
|
|
if !*FlagD {
|
2016-09-17 09:39:33 -04:00
|
|
|
sh := elfshname(".dynsym")
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.type_ = SHT_DYNSYM
|
|
|
|
|
sh.flags = SHF_ALLOC
|
2015-04-08 08:44:08 -07:00
|
|
|
if elf64 {
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.entsize = ELF64SYMSIZE
|
|
|
|
|
} else {
|
|
|
|
|
sh.entsize = ELF32SYMSIZE
|
|
|
|
|
}
|
2017-09-30 21:10:49 +00:00
|
|
|
sh.addralign = uint64(ctxt.Arch.RegSize)
|
2016-09-17 09:39:33 -04:00
|
|
|
sh.link = uint32(elfshname(".dynstr").shnum)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// sh->info = index of first non-local symbol (number of local symbols)
|
2016-09-20 15:57:53 +12:00
|
|
|
shsym(sh, ctxt.Syms.Lookup(".dynsym", 0))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
sh = elfshname(".dynstr")
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.type_ = SHT_STRTAB
|
|
|
|
|
sh.flags = SHF_ALLOC
|
|
|
|
|
sh.addralign = 1
|
2016-09-20 15:57:53 +12:00
|
|
|
shsym(sh, ctxt.Syms.Lookup(".dynstr", 0))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
if elfverneed != 0 {
|
2016-09-17 09:39:33 -04:00
|
|
|
sh := elfshname(".gnu.version")
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.type_ = SHT_GNU_VERSYM
|
|
|
|
|
sh.flags = SHF_ALLOC
|
|
|
|
|
sh.addralign = 2
|
2016-09-17 09:39:33 -04:00
|
|
|
sh.link = uint32(elfshname(".dynsym").shnum)
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.entsize = 2
|
2016-09-20 15:57:53 +12:00
|
|
|
shsym(sh, ctxt.Syms.Lookup(".gnu.version", 0))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
sh = elfshname(".gnu.version_r")
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.type_ = SHT_GNU_VERNEED
|
|
|
|
|
sh.flags = SHF_ALLOC
|
2017-09-30 21:10:49 +00:00
|
|
|
sh.addralign = uint64(ctxt.Arch.RegSize)
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.info = uint32(elfverneed)
|
2016-09-17 09:39:33 -04:00
|
|
|
sh.link = uint32(elfshname(".dynstr").shnum)
|
2016-09-20 15:57:53 +12:00
|
|
|
shsym(sh, ctxt.Syms.Lookup(".gnu.version_r", 0))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-04-03 19:32:31 +12:00
|
|
|
if elfRelType == ".rela" {
|
2016-09-17 09:39:33 -04:00
|
|
|
sh := elfshname(".rela.plt")
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.type_ = SHT_RELA
|
|
|
|
|
sh.flags = SHF_ALLOC
|
|
|
|
|
sh.entsize = ELF64RELASIZE
|
2017-09-30 21:10:49 +00:00
|
|
|
sh.addralign = uint64(ctxt.Arch.RegSize)
|
2016-09-17 09:39:33 -04:00
|
|
|
sh.link = uint32(elfshname(".dynsym").shnum)
|
|
|
|
|
sh.info = uint32(elfshname(".plt").shnum)
|
2016-09-20 15:57:53 +12:00
|
|
|
shsym(sh, ctxt.Syms.Lookup(".rela.plt", 0))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
sh = elfshname(".rela")
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.type_ = SHT_RELA
|
|
|
|
|
sh.flags = SHF_ALLOC
|
|
|
|
|
sh.entsize = ELF64RELASIZE
|
|
|
|
|
sh.addralign = 8
|
2016-09-17 09:39:33 -04:00
|
|
|
sh.link = uint32(elfshname(".dynsym").shnum)
|
2016-09-20 15:57:53 +12:00
|
|
|
shsym(sh, ctxt.Syms.Lookup(".rela", 0))
|
2016-04-03 19:32:31 +12:00
|
|
|
} else {
|
2016-09-17 09:39:33 -04:00
|
|
|
sh := elfshname(".rel.plt")
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.type_ = SHT_REL
|
|
|
|
|
sh.flags = SHF_ALLOC
|
|
|
|
|
sh.entsize = ELF32RELSIZE
|
|
|
|
|
sh.addralign = 4
|
2016-09-17 09:39:33 -04:00
|
|
|
sh.link = uint32(elfshname(".dynsym").shnum)
|
2016-09-20 15:57:53 +12:00
|
|
|
shsym(sh, ctxt.Syms.Lookup(".rel.plt", 0))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
sh = elfshname(".rel")
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.type_ = SHT_REL
|
|
|
|
|
sh.flags = SHF_ALLOC
|
|
|
|
|
sh.entsize = ELF32RELSIZE
|
|
|
|
|
sh.addralign = 4
|
2016-09-17 09:39:33 -04:00
|
|
|
sh.link = uint32(elfshname(".dynsym").shnum)
|
2016-09-20 15:57:53 +12:00
|
|
|
shsym(sh, ctxt.Syms.Lookup(".rel", 0))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if eh.machine == EM_PPC64 {
|
2016-09-17 09:39:33 -04:00
|
|
|
sh := elfshname(".glink")
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.type_ = SHT_PROGBITS
|
|
|
|
|
sh.flags = SHF_ALLOC + SHF_EXECINSTR
|
|
|
|
|
sh.addralign = 4
|
2016-09-20 15:57:53 +12:00
|
|
|
shsym(sh, ctxt.Syms.Lookup(".glink", 0))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
sh = elfshname(".plt")
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.type_ = SHT_PROGBITS
|
|
|
|
|
sh.flags = SHF_ALLOC + SHF_EXECINSTR
|
|
|
|
|
if eh.machine == EM_X86_64 {
|
|
|
|
|
sh.entsize = 16
|
2016-03-18 16:57:54 -04:00
|
|
|
} else if eh.machine == EM_S390 {
|
|
|
|
|
sh.entsize = 32
|
2015-02-27 22:57:28 -05:00
|
|
|
} else if eh.machine == EM_PPC64 {
|
|
|
|
|
// On ppc64, this is just a table of addresses
|
|
|
|
|
// filled by the dynamic linker
|
|
|
|
|
sh.type_ = SHT_NOBITS
|
|
|
|
|
|
|
|
|
|
sh.flags = SHF_ALLOC + SHF_WRITE
|
|
|
|
|
sh.entsize = 8
|
|
|
|
|
} else {
|
|
|
|
|
sh.entsize = 4
|
|
|
|
|
}
|
|
|
|
|
sh.addralign = sh.entsize
|
2016-09-20 15:57:53 +12:00
|
|
|
shsym(sh, ctxt.Syms.Lookup(".plt", 0))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// On ppc64, .got comes from the input files, so don't
|
|
|
|
|
// create it here, and .got.plt is not used.
|
|
|
|
|
if eh.machine != EM_PPC64 {
|
2016-09-17 09:39:33 -04:00
|
|
|
sh := elfshname(".got")
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.type_ = SHT_PROGBITS
|
|
|
|
|
sh.flags = SHF_ALLOC + SHF_WRITE
|
2017-09-30 21:10:49 +00:00
|
|
|
sh.entsize = uint64(ctxt.Arch.RegSize)
|
|
|
|
|
sh.addralign = uint64(ctxt.Arch.RegSize)
|
2016-09-20 15:57:53 +12:00
|
|
|
shsym(sh, ctxt.Syms.Lookup(".got", 0))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
sh = elfshname(".got.plt")
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.type_ = SHT_PROGBITS
|
|
|
|
|
sh.flags = SHF_ALLOC + SHF_WRITE
|
2017-09-30 21:10:49 +00:00
|
|
|
sh.entsize = uint64(ctxt.Arch.RegSize)
|
|
|
|
|
sh.addralign = uint64(ctxt.Arch.RegSize)
|
2016-09-20 15:57:53 +12:00
|
|
|
shsym(sh, ctxt.Syms.Lookup(".got.plt", 0))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
sh = elfshname(".hash")
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.type_ = SHT_HASH
|
|
|
|
|
sh.flags = SHF_ALLOC
|
|
|
|
|
sh.entsize = 4
|
2017-09-30 21:10:49 +00:00
|
|
|
sh.addralign = uint64(ctxt.Arch.RegSize)
|
2016-09-17 09:39:33 -04:00
|
|
|
sh.link = uint32(elfshname(".dynsym").shnum)
|
2016-09-20 15:57:53 +12:00
|
|
|
shsym(sh, ctxt.Syms.Lookup(".hash", 0))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
/* sh and PT_DYNAMIC for .dynamic section */
|
2016-09-17 09:39:33 -04:00
|
|
|
sh = elfshname(".dynamic")
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
sh.type_ = SHT_DYNAMIC
|
|
|
|
|
sh.flags = SHF_ALLOC + SHF_WRITE
|
2017-09-30 21:10:49 +00:00
|
|
|
sh.entsize = 2 * uint64(ctxt.Arch.RegSize)
|
|
|
|
|
sh.addralign = uint64(ctxt.Arch.RegSize)
|
2016-09-17 09:39:33 -04:00
|
|
|
sh.link = uint32(elfshname(".dynstr").shnum)
|
2016-09-20 15:57:53 +12:00
|
|
|
shsym(sh, ctxt.Syms.Lookup(".dynamic", 0))
|
2016-09-17 09:39:33 -04:00
|
|
|
ph := newElfPhdr()
|
2015-02-27 22:57:28 -05:00
|
|
|
ph.type_ = PT_DYNAMIC
|
|
|
|
|
ph.flags = PF_R + PF_W
|
|
|
|
|
phsh(ph, sh)
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Thread-local storage segment (really just size).
|
|
|
|
|
*/
|
2017-04-12 01:10:01 +10:00
|
|
|
tlssize := uint64(0)
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segdata.Sections {
|
2017-04-12 01:10:01 +10:00
|
|
|
if sect.Name == ".tbss" {
|
|
|
|
|
tlssize = sect.Length
|
2015-08-11 12:29:00 +12:00
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-12 01:10:01 +10:00
|
|
|
if tlssize != 0 {
|
|
|
|
|
ph := newElfPhdr()
|
|
|
|
|
ph.type_ = PT_TLS
|
|
|
|
|
ph.flags = PF_R
|
|
|
|
|
ph.memsz = tlssize
|
2017-09-30 21:10:49 +00:00
|
|
|
ph.align = uint64(ctxt.Arch.RegSize)
|
2017-04-12 01:10:01 +10:00
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
if Headtype == objabi.Hlinux {
|
2016-09-17 09:39:33 -04:00
|
|
|
ph := newElfPhdr()
|
2015-02-27 22:57:28 -05:00
|
|
|
ph.type_ = PT_GNU_STACK
|
|
|
|
|
ph.flags = PF_W + PF_R
|
2017-09-30 21:10:49 +00:00
|
|
|
ph.align = uint64(ctxt.Arch.RegSize)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
ph = newElfPhdr()
|
2015-02-27 22:57:28 -05:00
|
|
|
ph.type_ = PT_PAX_FLAGS
|
|
|
|
|
ph.flags = 0x2a00 // mprotect, randexec, emutramp disabled
|
2017-09-30 21:10:49 +00:00
|
|
|
ph.align = uint64(ctxt.Arch.RegSize)
|
2017-04-18 12:53:25 -07:00
|
|
|
} else if Headtype == objabi.Hsolaris {
|
2016-06-15 13:44:03 -07:00
|
|
|
ph := newElfPhdr()
|
|
|
|
|
ph.type_ = PT_SUNWSTACK
|
|
|
|
|
ph.flags = PF_W + PF_R
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
elfobj:
|
2016-09-17 09:39:33 -04:00
|
|
|
sh := elfshname(".shstrtab")
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.type_ = SHT_STRTAB
|
|
|
|
|
sh.addralign = 1
|
2016-09-20 15:57:53 +12:00
|
|
|
shsym(sh, ctxt.Syms.Lookup(".shstrtab", 0))
|
2015-02-27 22:57:28 -05:00
|
|
|
eh.shstrndx = uint16(sh.shnum)
|
|
|
|
|
|
|
|
|
|
// put these sections early in the list
|
2016-08-21 18:34:24 -04:00
|
|
|
if !*FlagS {
|
2016-09-17 09:39:33 -04:00
|
|
|
elfshname(".symtab")
|
|
|
|
|
elfshname(".strtab")
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segtext.Sections {
|
2016-09-17 09:39:33 -04:00
|
|
|
elfshbits(sect)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segrodata.Sections {
|
2016-09-17 09:39:33 -04:00
|
|
|
elfshbits(sect)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segrelrodata.Sections {
|
2016-09-17 09:39:33 -04:00
|
|
|
elfshbits(sect)
|
2016-09-05 23:29:16 -04:00
|
|
|
}
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segdata.Sections {
|
2016-09-17 09:39:33 -04:00
|
|
|
elfshbits(sect)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segdwarf.Sections {
|
2016-09-17 09:39:33 -04:00
|
|
|
elfshbits(sect)
|
2016-03-14 09:23:04 -07:00
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
if Linkmode == LinkExternal {
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segtext.Sections {
|
2017-09-30 21:10:49 +00:00
|
|
|
elfshreloc(ctxt.Arch, sect)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segrodata.Sections {
|
2017-09-30 21:10:49 +00:00
|
|
|
elfshreloc(ctxt.Arch, sect)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segrelrodata.Sections {
|
2017-09-30 21:10:49 +00:00
|
|
|
elfshreloc(ctxt.Arch, sect)
|
2016-09-05 23:29:16 -04:00
|
|
|
}
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segdata.Sections {
|
2017-09-30 21:10:49 +00:00
|
|
|
elfshreloc(ctxt.Arch, sect)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2016-04-22 10:31:14 +12:00
|
|
|
for _, s := range dwarfp {
|
[dev.debug] cmd/compile: better DWARF with optimizations on
Debuggers use DWARF information to find local variables on the
stack and in registers. Prior to this CL, the DWARF information for
functions claimed that all variables were on the stack at all times.
That's incorrect when optimizations are enabled, and results in
debuggers showing data that is out of date or complete gibberish.
After this CL, the compiler is capable of representing variable
locations more accurately, and attempts to do so. Due to limitations of
the SSA backend, it's not possible to be completely correct.
There are a number of problems in the current design. One of the easier
to understand is that variable names currently must be attached to an
SSA value, but not all assignments in the source code actually result
in machine code. For example:
type myint int
var a int
b := myint(int)
and
b := (*uint64)(unsafe.Pointer(a))
don't generate machine code because the underlying representation is the
same, so the correct value of b will not be set when the user would
expect.
Generating the more precise debug information is behind a flag,
dwarflocationlists. Because of the issues described above, setting the
flag may not make the debugging experience much better, and may actually
make it worse in cases where the variable actually is on the stack and
the more complicated analysis doesn't realize it.
A number of changes are included:
- Add a new pseudo-instruction, RegKill, which indicates that the value
in the register has been clobbered.
- Adjust regalloc to emit RegKills in the right places. Significantly,
this means that phis are mixed with StoreReg and RegKills after
regalloc.
- Track variable decomposition in ssa.LocalSlots.
- After the SSA backend is done, analyze the result and build location
lists for each LocalSlot.
- After assembly is done, update the location lists with the assembled
PC offsets, recompose variables, and build DWARF location lists. Emit the
list as a new linker symbol, one per function.
- In the linker, aggregate the location lists into a .debug_loc section.
TODO:
- currently disabled for non-X86/AMD64 because there are no data tables.
go build -toolexec 'toolstash -cmp' -a std succeeds.
With -dwarflocationlists false:
before: f02812195637909ff675782c0b46836a8ff01976
after: 06f61e8112a42ac34fb80e0c818b3cdb84a5e7ec
benchstat -geomean /tmp/220352263 /tmp/621364410
completed 15 of 15, estimated time remaining 0s (eta 3:52PM)
name old time/op new time/op delta
Template 199ms ± 3% 198ms ± 2% ~ (p=0.400 n=15+14)
Unicode 96.6ms ± 5% 96.4ms ± 5% ~ (p=0.838 n=15+15)
GoTypes 653ms ± 2% 647ms ± 2% ~ (p=0.102 n=15+14)
Flate 133ms ± 6% 129ms ± 3% -2.62% (p=0.041 n=15+15)
GoParser 164ms ± 5% 159ms ± 3% -3.05% (p=0.000 n=15+15)
Reflect 428ms ± 4% 422ms ± 3% ~ (p=0.156 n=15+13)
Tar 123ms ±10% 124ms ± 8% ~ (p=0.461 n=15+15)
XML 228ms ± 3% 224ms ± 3% -1.57% (p=0.045 n=15+15)
[Geo mean] 206ms 377ms +82.86%
name old user-time/op new user-time/op delta
Template 292ms ±10% 301ms ±12% ~ (p=0.189 n=15+15)
Unicode 166ms ±37% 158ms ±14% ~ (p=0.418 n=15+14)
GoTypes 962ms ± 6% 963ms ± 7% ~ (p=0.976 n=15+15)
Flate 207ms ±19% 200ms ±14% ~ (p=0.345 n=14+15)
GoParser 246ms ±22% 240ms ±15% ~ (p=0.587 n=15+15)
Reflect 611ms ±13% 587ms ±14% ~ (p=0.085 n=15+13)
Tar 211ms ±12% 217ms ±14% ~ (p=0.355 n=14+15)
XML 335ms ±15% 320ms ±18% ~ (p=0.169 n=15+15)
[Geo mean] 317ms 583ms +83.72%
name old alloc/op new alloc/op delta
Template 40.2MB ± 0% 40.2MB ± 0% -0.15% (p=0.000 n=14+15)
Unicode 29.2MB ± 0% 29.3MB ± 0% ~ (p=0.624 n=15+15)
GoTypes 114MB ± 0% 114MB ± 0% -0.15% (p=0.000 n=15+14)
Flate 25.7MB ± 0% 25.6MB ± 0% -0.18% (p=0.000 n=13+15)
GoParser 32.2MB ± 0% 32.2MB ± 0% -0.14% (p=0.003 n=15+15)
Reflect 77.8MB ± 0% 77.9MB ± 0% ~ (p=0.061 n=15+15)
Tar 27.1MB ± 0% 27.0MB ± 0% -0.11% (p=0.029 n=15+15)
XML 42.7MB ± 0% 42.5MB ± 0% -0.29% (p=0.000 n=15+15)
[Geo mean] 42.1MB 75.0MB +78.05%
name old allocs/op new allocs/op delta
Template 402k ± 1% 398k ± 0% -0.91% (p=0.000 n=15+15)
Unicode 344k ± 1% 344k ± 0% ~ (p=0.715 n=15+14)
GoTypes 1.18M ± 0% 1.17M ± 0% -0.91% (p=0.000 n=15+14)
Flate 243k ± 0% 240k ± 1% -1.05% (p=0.000 n=13+15)
GoParser 327k ± 1% 324k ± 1% -0.96% (p=0.000 n=15+15)
Reflect 984k ± 1% 982k ± 0% ~ (p=0.050 n=15+15)
Tar 261k ± 1% 259k ± 1% -0.77% (p=0.000 n=15+15)
XML 411k ± 0% 404k ± 1% -1.55% (p=0.000 n=15+15)
[Geo mean] 439k 755k +72.01%
name old text-bytes new text-bytes delta
HelloSize 694kB ± 0% 694kB ± 0% -0.00% (p=0.000 n=15+15)
name old data-bytes new data-bytes delta
HelloSize 5.55kB ± 0% 5.55kB ± 0% ~ (all equal)
name old bss-bytes new bss-bytes delta
HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal)
name old exe-bytes new exe-bytes delta
HelloSize 1.04MB ± 0% 1.04MB ± 0% ~ (all equal)
Change-Id: I991fc553ef175db46bb23b2128317bbd48de70d8
Reviewed-on: https://go-review.googlesource.com/41770
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
2017-07-21 18:30:19 -04:00
|
|
|
if len(s.R) > 0 || s.Type == SDWARFINFO || s.Type == SDWARFLOC {
|
2017-09-30 21:10:49 +00:00
|
|
|
elfshreloc(ctxt.Arch, s.Sect)
|
2016-03-14 09:23:04 -07:00
|
|
|
}
|
|
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
// add a .note.GNU-stack section to mark the stack as non-executable
|
2016-09-17 09:39:33 -04:00
|
|
|
sh := elfshname(".note.GNU-stack")
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
sh.type_ = SHT_PROGBITS
|
|
|
|
|
sh.addralign = 1
|
|
|
|
|
sh.flags = 0
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-21 18:34:24 -04:00
|
|
|
if !*FlagS {
|
2016-09-17 09:39:33 -04:00
|
|
|
sh := elfshname(".symtab")
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.type_ = SHT_SYMTAB
|
|
|
|
|
sh.off = uint64(symo)
|
|
|
|
|
sh.size = uint64(Symsize)
|
2017-09-30 21:10:49 +00:00
|
|
|
sh.addralign = uint64(ctxt.Arch.RegSize)
|
|
|
|
|
sh.entsize = 8 + 2*uint64(ctxt.Arch.RegSize)
|
2016-09-17 09:39:33 -04:00
|
|
|
sh.link = uint32(elfshname(".strtab").shnum)
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.info = uint32(elfglobalsymndx)
|
|
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
sh = elfshname(".strtab")
|
2015-02-27 22:57:28 -05:00
|
|
|
sh.type_ = SHT_STRTAB
|
|
|
|
|
sh.off = uint64(symo) + uint64(Symsize)
|
|
|
|
|
sh.size = uint64(len(Elfstrdat))
|
|
|
|
|
sh.addralign = 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Main header */
|
|
|
|
|
eh.ident[EI_MAG0] = '\177'
|
|
|
|
|
|
|
|
|
|
eh.ident[EI_MAG1] = 'E'
|
|
|
|
|
eh.ident[EI_MAG2] = 'L'
|
|
|
|
|
eh.ident[EI_MAG3] = 'F'
|
2017-04-18 12:53:25 -07:00
|
|
|
if Headtype == objabi.Hfreebsd {
|
2015-02-27 22:57:28 -05:00
|
|
|
eh.ident[EI_OSABI] = ELFOSABI_FREEBSD
|
2017-04-18 12:53:25 -07:00
|
|
|
} else if Headtype == objabi.Hnetbsd {
|
2015-02-27 22:57:28 -05:00
|
|
|
eh.ident[EI_OSABI] = ELFOSABI_NETBSD
|
2017-04-18 12:53:25 -07:00
|
|
|
} else if Headtype == objabi.Hopenbsd {
|
2015-02-27 22:57:28 -05:00
|
|
|
eh.ident[EI_OSABI] = ELFOSABI_OPENBSD
|
2017-04-18 12:53:25 -07:00
|
|
|
} else if Headtype == objabi.Hdragonfly {
|
2015-02-27 22:57:28 -05:00
|
|
|
eh.ident[EI_OSABI] = ELFOSABI_NONE
|
|
|
|
|
}
|
2015-04-08 08:44:08 -07:00
|
|
|
if elf64 {
|
2015-02-27 22:57:28 -05:00
|
|
|
eh.ident[EI_CLASS] = ELFCLASS64
|
|
|
|
|
} else {
|
|
|
|
|
eh.ident[EI_CLASS] = ELFCLASS32
|
|
|
|
|
}
|
2016-08-19 22:40:38 -04:00
|
|
|
if ctxt.Arch.ByteOrder == binary.BigEndian {
|
2015-02-27 22:57:28 -05:00
|
|
|
eh.ident[EI_DATA] = ELFDATA2MSB
|
|
|
|
|
} else {
|
|
|
|
|
eh.ident[EI_DATA] = ELFDATA2LSB
|
|
|
|
|
}
|
|
|
|
|
eh.ident[EI_VERSION] = EV_CURRENT
|
|
|
|
|
|
|
|
|
|
if Linkmode == LinkExternal {
|
|
|
|
|
eh.type_ = ET_REL
|
2016-09-06 08:05:19 -04:00
|
|
|
} else if Buildmode == BuildmodePIE {
|
|
|
|
|
eh.type_ = ET_DYN
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
|
|
|
|
eh.type_ = ET_EXEC
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if Linkmode != LinkExternal {
|
2016-08-19 22:40:38 -04:00
|
|
|
eh.entry = uint64(Entryvalue(ctxt))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
eh.version = EV_CURRENT
|
|
|
|
|
|
|
|
|
|
if pph != nil {
|
|
|
|
|
pph.filesz = uint64(eh.phnum) * uint64(eh.phentsize)
|
|
|
|
|
pph.memsz = pph.filesz
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.SeekSet(0)
|
2015-03-02 12:35:15 -05:00
|
|
|
a := int64(0)
|
2017-10-01 02:37:20 +00:00
|
|
|
a += int64(elfwritehdr(ctxt.Out))
|
|
|
|
|
a += int64(elfwritephdrs(ctxt.Out))
|
|
|
|
|
a += int64(elfwriteshdrs(ctxt.Out))
|
2016-08-21 18:34:24 -04:00
|
|
|
if !*FlagD {
|
2017-10-01 02:37:20 +00:00
|
|
|
a += int64(elfwriteinterp(ctxt.Out))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
if Linkmode != LinkExternal {
|
2017-04-18 12:53:25 -07:00
|
|
|
if Headtype == objabi.Hnetbsd {
|
2017-10-01 02:37:20 +00:00
|
|
|
a += int64(elfwritenetbsdsig(ctxt.Out))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 12:53:25 -07:00
|
|
|
if Headtype == objabi.Hopenbsd {
|
2017-10-01 02:37:20 +00:00
|
|
|
a += int64(elfwriteopenbsdsig(ctxt.Out))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
if len(buildinfo) > 0 {
|
2017-10-01 02:37:20 +00:00
|
|
|
a += int64(elfwritebuildinfo(ctxt.Out))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2016-08-21 18:34:24 -04:00
|
|
|
if *flagBuildid != "" {
|
2017-10-01 02:37:20 +00:00
|
|
|
a += int64(elfwritegobuildid(ctxt.Out))
|
2015-06-04 14:31:05 -04:00
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2015-05-05 14:17:07 +12:00
|
|
|
if a > elfreserve {
|
2016-08-25 11:07:33 -05:00
|
|
|
Errorf(nil, "ELFRESERVE too small: %d > %d with %d text sections", a, elfreserve, numtext)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-28 14:57:47 +09:00
|
|
|
func elfadddynsym(ctxt *Link, s *Symbol) {
|
2015-05-12 15:59:15 +12:00
|
|
|
if elf64 {
|
|
|
|
|
s.Dynid = int32(Nelfsym)
|
|
|
|
|
Nelfsym++
|
|
|
|
|
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
d := ctxt.Syms.Lookup(".dynsym", 0)
|
2015-05-12 15:59:15 +12:00
|
|
|
|
|
|
|
|
name := s.Extname
|
2017-09-30 15:06:44 +00:00
|
|
|
d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
|
2015-05-12 15:59:15 +12:00
|
|
|
|
|
|
|
|
/* type */
|
|
|
|
|
t := STB_GLOBAL << 4
|
|
|
|
|
|
2017-04-19 15:15:35 +12:00
|
|
|
if s.Attr.CgoExport() && s.Type&SMASK == STEXT {
|
2015-05-12 15:59:15 +12:00
|
|
|
t |= STT_FUNC
|
|
|
|
|
} else {
|
|
|
|
|
t |= STT_OBJECT
|
|
|
|
|
}
|
2017-09-30 15:06:44 +00:00
|
|
|
d.AddUint8(uint8(t))
|
2015-05-12 15:59:15 +12:00
|
|
|
|
|
|
|
|
/* reserved */
|
2017-09-30 15:06:44 +00:00
|
|
|
d.AddUint8(0)
|
2015-05-12 15:59:15 +12:00
|
|
|
|
|
|
|
|
/* section where symbol is defined */
|
2017-04-19 15:15:35 +12:00
|
|
|
if s.Type == SDYNIMPORT {
|
2017-09-30 15:06:44 +00:00
|
|
|
d.AddUint16(ctxt.Arch, SHN_UNDEF)
|
2015-05-12 15:59:15 +12:00
|
|
|
} else {
|
2017-09-30 15:06:44 +00:00
|
|
|
d.AddUint16(ctxt.Arch, 1)
|
2015-05-12 15:59:15 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* value */
|
2017-04-19 15:15:35 +12:00
|
|
|
if s.Type == SDYNIMPORT {
|
2017-09-30 15:06:44 +00:00
|
|
|
d.AddUint64(ctxt.Arch, 0)
|
2015-05-12 15:59:15 +12:00
|
|
|
} else {
|
2017-09-30 15:06:44 +00:00
|
|
|
d.AddAddr(ctxt.Arch, s)
|
2015-05-12 15:59:15 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* size of object */
|
2017-09-30 15:06:44 +00:00
|
|
|
d.AddUint64(ctxt.Arch, uint64(s.Size))
|
2015-05-12 15:59:15 +12:00
|
|
|
|
2017-09-30 21:10:49 +00:00
|
|
|
if ctxt.Arch.Family == sys.AMD64 && !s.Attr.CgoExportDynamic() && s.Dynimplib != "" && !seenlib[s.Dynimplib] {
|
2016-09-20 15:31:26 +12:00
|
|
|
Elfwritedynent(ctxt, ctxt.Syms.Lookup(".dynamic", 0), DT_NEEDED, uint64(Addstring(ctxt.Syms.Lookup(".dynstr", 0), s.Dynimplib)))
|
2015-05-12 15:59:15 +12:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
s.Dynid = int32(Nelfsym)
|
|
|
|
|
Nelfsym++
|
|
|
|
|
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
d := ctxt.Syms.Lookup(".dynsym", 0)
|
2015-05-12 15:59:15 +12:00
|
|
|
|
|
|
|
|
/* name */
|
|
|
|
|
name := s.Extname
|
|
|
|
|
|
2017-09-30 15:06:44 +00:00
|
|
|
d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
|
2015-05-12 15:59:15 +12:00
|
|
|
|
|
|
|
|
/* value */
|
2017-04-19 15:15:35 +12:00
|
|
|
if s.Type == SDYNIMPORT {
|
2017-09-30 15:06:44 +00:00
|
|
|
d.AddUint32(ctxt.Arch, 0)
|
2015-05-12 15:59:15 +12:00
|
|
|
} else {
|
2017-09-30 15:06:44 +00:00
|
|
|
d.AddAddr(ctxt.Arch, s)
|
2015-05-12 15:59:15 +12:00
|
|
|
}
|
|
|
|
|
|
2016-05-08 01:27:45 +10:00
|
|
|
/* size of object */
|
2017-09-30 15:06:44 +00:00
|
|
|
d.AddUint32(ctxt.Arch, uint32(s.Size))
|
2015-05-12 15:59:15 +12:00
|
|
|
|
|
|
|
|
/* type */
|
|
|
|
|
t := STB_GLOBAL << 4
|
|
|
|
|
|
2016-12-08 22:15:40 +00:00
|
|
|
// TODO(mwhudson): presumably the behavior should actually be the same on both arm and 386.
|
2017-09-30 21:10:49 +00:00
|
|
|
if ctxt.Arch.Family == sys.I386 && s.Attr.CgoExport() && s.Type&SMASK == STEXT {
|
2015-05-12 15:59:15 +12:00
|
|
|
t |= STT_FUNC
|
2017-09-30 21:10:49 +00:00
|
|
|
} else if ctxt.Arch.Family == sys.ARM && s.Attr.CgoExportDynamic() && s.Type&SMASK == STEXT {
|
2015-05-12 15:59:15 +12:00
|
|
|
t |= STT_FUNC
|
|
|
|
|
} else {
|
|
|
|
|
t |= STT_OBJECT
|
|
|
|
|
}
|
2017-09-30 15:06:44 +00:00
|
|
|
d.AddUint8(uint8(t))
|
|
|
|
|
d.AddUint8(0)
|
2015-05-12 15:59:15 +12:00
|
|
|
|
|
|
|
|
/* shndx */
|
2017-04-19 15:15:35 +12:00
|
|
|
if s.Type == SDYNIMPORT {
|
2017-09-30 15:06:44 +00:00
|
|
|
d.AddUint16(ctxt.Arch, SHN_UNDEF)
|
2015-05-12 15:59:15 +12:00
|
|
|
} else {
|
2017-09-30 15:06:44 +00:00
|
|
|
d.AddUint16(ctxt.Arch, 1)
|
2015-05-12 15:59:15 +12:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-27 22:57:28 -05:00
|
|
|
func ELF32_R_SYM(info uint32) uint32 {
|
|
|
|
|
return info >> 8
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ELF32_R_TYPE(info uint32) uint32 {
|
|
|
|
|
return uint32(uint8(info))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ELF32_R_INFO(sym uint32, type_ uint32) uint32 {
|
|
|
|
|
return sym<<8 | type_
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ELF32_ST_BIND(info uint8) uint8 {
|
|
|
|
|
return info >> 4
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ELF32_ST_TYPE(info uint8) uint8 {
|
|
|
|
|
return info & 0xf
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ELF32_ST_INFO(bind uint8, type_ uint8) uint8 {
|
|
|
|
|
return bind<<4 | type_&0xf
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ELF32_ST_VISIBILITY(oth uint8) uint8 {
|
|
|
|
|
return oth & 3
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ELF64_R_SYM(info uint64) uint32 {
|
|
|
|
|
return uint32(info >> 32)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ELF64_R_TYPE(info uint64) uint32 {
|
|
|
|
|
return uint32(info)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ELF64_R_INFO(sym uint32, type_ uint32) uint64 {
|
|
|
|
|
return uint64(sym)<<32 | uint64(type_)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ELF64_ST_BIND(info uint8) uint8 {
|
|
|
|
|
return info >> 4
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ELF64_ST_TYPE(info uint8) uint8 {
|
|
|
|
|
return info & 0xf
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ELF64_ST_INFO(bind uint8, type_ uint8) uint8 {
|
|
|
|
|
return bind<<4 | type_&0xf
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ELF64_ST_VISIBILITY(oth uint8) uint8 {
|
|
|
|
|
return oth & 3
|
|
|
|
|
}
|