aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/internal/obj/link.go
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2017-04-18 12:53:25 -0700
committerMatthew Dempsky <mdempsky@google.com>2017-04-19 00:00:09 +0000
commit1e3570ac86f6aeb7f8ce70b5ad236a5dd92ec804 (patch)
tree6bb1e704f068dee9f7e95eb0d1b5ed1829441c8b /src/cmd/internal/obj/link.go
parentf71f32e5e155ae5b7f60005c939746637086f30e (diff)
downloadgo-1e3570ac86f6aeb7f8ce70b5ad236a5dd92ec804.tar.xz
cmd/internal/objabi: extract shared functionality from obj
Now only cmd/asm and cmd/compile depend on cmd/internal/obj. Changing the assembler backends no longer requires reinstalling cmd/link or cmd/addr2line. There's also now one canonical definition of the object file format in cmd/internal/objabi/doc.go, with a warning to update all three implementations. objabi is still something of a grab bag of unrelated code (e.g., flag and environment variable handling probably belong in a separate "tool" package), but this is still progress. Fixes #15165. Fixes #20026. Change-Id: Ic4b92fac7d0d35438e0d20c9579aad4085c5534c Reviewed-on: https://go-review.googlesource.com/40972 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Diffstat (limited to 'src/cmd/internal/obj/link.go')
-rw-r--r--src/cmd/internal/obj/link.go359
1 files changed, 4 insertions, 355 deletions
diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go
index 568abd58ef..840df52256 100644
--- a/src/cmd/internal/obj/link.go
+++ b/src/cmd/internal/obj/link.go
@@ -33,6 +33,7 @@ package obj
import (
"bufio"
"cmd/internal/dwarf"
+ "cmd/internal/objabi"
"cmd/internal/src"
"cmd/internal/sys"
"fmt"
@@ -308,7 +309,7 @@ const (
// An LSym is the sort of symbol that is written to an object file.
type LSym struct {
Name string
- Type SymKind
+ Type objabi.SymKind
Version int16
Attribute
@@ -447,289 +448,14 @@ type Pcln struct {
InlTree InlTree // per-function inlining tree extracted from the global tree
}
-// A SymKind describes the kind of memory represented by a symbol.
-type SymKind int16
-
-// Defined SymKind values.
-//
-// TODO(rsc): Give idiomatic Go names.
-// TODO(rsc): Reduce the number of symbol types in the object files.
-//go:generate stringer -type=SymKind
-const (
- Sxxx SymKind = iota
- STEXT
- SELFRXSECT
-
- // Read-only sections.
- STYPE
- SSTRING
- SGOSTRING
- SGOFUNC
- SGCBITS
- SRODATA
- SFUNCTAB
-
- SELFROSECT
- SMACHOPLT
-
- // Read-only sections with relocations.
- //
- // Types STYPE-SFUNCTAB above are written to the .rodata section by default.
- // When linking a shared object, some conceptually "read only" types need to
- // be written to by relocations and putting them in a section called
- // ".rodata" interacts poorly with the system linkers. The GNU linkers
- // support this situation by arranging for sections of the name
- // ".data.rel.ro.XXX" to be mprotected read only by the dynamic linker after
- // relocations have applied, so when the Go linker is creating a shared
- // object it checks all objects of the above types and bumps any object that
- // has a relocation to it to the corresponding type below, which are then
- // written to sections with appropriate magic names.
- STYPERELRO
- SSTRINGRELRO
- SGOSTRINGRELRO
- SGOFUNCRELRO
- SGCBITSRELRO
- SRODATARELRO
- SFUNCTABRELRO
-
- // Part of .data.rel.ro if it exists, otherwise part of .rodata.
- STYPELINK
- SITABLINK
- SSYMTAB
- SPCLNTAB
-
- // Writable sections.
- SELFSECT
- SMACHO
- SMACHOGOT
- SWINDOWS
- SELFGOT
- SNOPTRDATA
- SINITARR
- SDATA
- SBSS
- SNOPTRBSS
- STLSBSS
- SXREF
- SMACHOSYMSTR
- SMACHOSYMTAB
- SMACHOINDIRECTPLT
- SMACHOINDIRECTGOT
- SFILE
- SFILEPATH
- SCONST
- SDYNIMPORT
- SHOSTOBJ
- SDWARFSECT
- SDWARFINFO
- SSUB = SymKind(1 << 8)
- SMASK = SymKind(SSUB - 1)
- SHIDDEN = SymKind(1 << 9)
- SCONTAINER = SymKind(1 << 10) // has a sub-symbol
-)
-
-// ReadOnly are the symbol kinds that form read-only sections. In some
-// cases, if they will require relocations, they are transformed into
-// rel-ro sections using RelROMap.
-var ReadOnly = []SymKind{
- STYPE,
- SSTRING,
- SGOSTRING,
- SGOFUNC,
- SGCBITS,
- SRODATA,
- SFUNCTAB,
-}
-
-// RelROMap describes the transformation of read-only symbols to rel-ro
-// symbols.
-var RelROMap = map[SymKind]SymKind{
- STYPE: STYPERELRO,
- SSTRING: SSTRINGRELRO,
- SGOSTRING: SGOSTRINGRELRO,
- SGOFUNC: SGOFUNCRELRO,
- SGCBITS: SGCBITSRELRO,
- SRODATA: SRODATARELRO,
- SFUNCTAB: SFUNCTABRELRO,
-}
-
type Reloc struct {
Off int32
Siz uint8
- Type RelocType
+ Type objabi.RelocType
Add int64
Sym *LSym
}
-type RelocType int32
-
-//go:generate stringer -type=RelocType
-const (
- R_ADDR RelocType = 1 + iota
- // R_ADDRPOWER relocates a pair of "D-form" instructions (instructions with 16-bit
- // immediates in the low half of the instruction word), usually addis followed by
- // another add or a load, inserting the "high adjusted" 16 bits of the address of
- // the referenced symbol into the immediate field of the first instruction and the
- // low 16 bits into that of the second instruction.
- R_ADDRPOWER
- // R_ADDRARM64 relocates an adrp, add pair to compute the address of the
- // referenced symbol.
- R_ADDRARM64
- // R_ADDRMIPS (only used on mips/mips64) resolves to the low 16 bits of an external
- // address, by encoding it into the instruction.
- R_ADDRMIPS
- // R_ADDROFF resolves to a 32-bit offset from the beginning of the section
- // holding the data being relocated to the referenced symbol.
- R_ADDROFF
- // R_WEAKADDROFF resolves just like R_ADDROFF but is a weak relocation.
- // A weak relocation does not make the symbol it refers to reachable,
- // and is only honored by the linker if the symbol is in some other way
- // reachable.
- R_WEAKADDROFF
- R_SIZE
- R_CALL
- R_CALLARM
- R_CALLARM64
- R_CALLIND
- R_CALLPOWER
- // R_CALLMIPS (only used on mips64) resolves to non-PC-relative target address
- // of a CALL (JAL) instruction, by encoding the address into the instruction.
- R_CALLMIPS
- R_CONST
- R_PCREL
- // R_TLS_LE, used on 386, amd64, and ARM, resolves to the offset of the
- // thread-local symbol from the thread local base and is used to implement the
- // "local exec" model for tls access (r.Sym is not set on intel platforms but is
- // set to a TLS symbol -- runtime.tlsg -- in the linker when externally linking).
- R_TLS_LE
- // R_TLS_IE, used 386, amd64, and ARM resolves to the PC-relative offset to a GOT
- // slot containing the offset from the thread-local symbol from the thread local
- // base and is used to implemented the "initial exec" model for tls access (r.Sym
- // is not set on intel platforms but is set to a TLS symbol -- runtime.tlsg -- in
- // the linker when externally linking).
- R_TLS_IE
- R_GOTOFF
- R_PLT0
- R_PLT1
- R_PLT2
- R_USEFIELD
- // R_USETYPE resolves to an *rtype, but no relocation is created. The
- // linker uses this as a signal that the pointed-to type information
- // should be linked into the final binary, even if there are no other
- // direct references. (This is used for types reachable by reflection.)
- R_USETYPE
- // R_METHODOFF resolves to a 32-bit offset from the beginning of the section
- // holding the data being relocated to the referenced symbol.
- // It is a variant of R_ADDROFF used when linking from the uncommonType of a
- // *rtype, and may be set to zero by the linker if it determines the method
- // text is unreachable by the linked program.
- R_METHODOFF
- R_POWER_TOC
- R_GOTPCREL
- // R_JMPMIPS (only used on mips64) resolves to non-PC-relative target address
- // of a JMP instruction, by encoding the address into the instruction.
- // The stack nosplit check ignores this since it is not a function call.
- R_JMPMIPS
- // R_DWARFREF resolves to the offset of the symbol from its section.
- R_DWARFREF
-
- // Platform dependent relocations. Architectures with fixed width instructions
- // have the inherent issue that a 32-bit (or 64-bit!) displacement cannot be
- // stuffed into a 32-bit instruction, so an address needs to be spread across
- // several instructions, and in turn this requires a sequence of relocations, each
- // updating a part of an instruction. This leads to relocation codes that are
- // inherently processor specific.
-
- // Arm64.
-
- // Set a MOV[NZ] immediate field to bits [15:0] of the offset from the thread
- // local base to the thread local variable defined by the referenced (thread
- // local) symbol. Error if the offset does not fit into 16 bits.
- R_ARM64_TLS_LE
-
- // Relocates an ADRP; LD64 instruction sequence to load the offset between
- // the thread local base and the thread local variable defined by the
- // referenced (thread local) symbol from the GOT.
- R_ARM64_TLS_IE
-
- // R_ARM64_GOTPCREL relocates an adrp, ld64 pair to compute the address of the GOT
- // slot of the referenced symbol.
- R_ARM64_GOTPCREL
-
- // PPC64.
-
- // R_POWER_TLS_LE is used to implement the "local exec" model for tls
- // access. It resolves to the offset of the thread-local symbol from the
- // thread pointer (R13) and inserts this value into the low 16 bits of an
- // instruction word.
- R_POWER_TLS_LE
-
- // R_POWER_TLS_IE is used to implement the "initial exec" model for tls access. It
- // relocates a D-form, DS-form instruction sequence like R_ADDRPOWER_DS. It
- // inserts to the offset of GOT slot for the thread-local symbol from the TOC (the
- // GOT slot is filled by the dynamic linker with the offset of the thread-local
- // symbol from the thread pointer (R13)).
- R_POWER_TLS_IE
-
- // R_POWER_TLS marks an X-form instruction such as "MOVD 0(R13)(R31*1), g" as
- // accessing a particular thread-local symbol. It does not affect code generation
- // but is used by the system linker when relaxing "initial exec" model code to
- // "local exec" model code.
- R_POWER_TLS
-
- // R_ADDRPOWER_DS is similar to R_ADDRPOWER above, but assumes the second
- // instruction is a "DS-form" instruction, which has an immediate field occupying
- // bits [15:2] of the instruction word. Bits [15:2] of the address of the
- // relocated symbol are inserted into this field; it is an error if the last two
- // bits of the address are not 0.
- R_ADDRPOWER_DS
-
- // R_ADDRPOWER_PCREL relocates a D-form, DS-form instruction sequence like
- // R_ADDRPOWER_DS but inserts the offset of the GOT slot for the referenced symbol
- // from the TOC rather than the symbol's address.
- R_ADDRPOWER_GOT
-
- // R_ADDRPOWER_PCREL relocates two D-form instructions like R_ADDRPOWER, but
- // inserts the displacement from the place being relocated to the address of the
- // the relocated symbol instead of just its address.
- R_ADDRPOWER_PCREL
-
- // R_ADDRPOWER_TOCREL relocates two D-form instructions like R_ADDRPOWER, but
- // inserts the offset from the TOC to the address of the relocated symbol
- // rather than the symbol's address.
- R_ADDRPOWER_TOCREL
-
- // R_ADDRPOWER_TOCREL relocates a D-form, DS-form instruction sequence like
- // R_ADDRPOWER_DS but inserts the offset from the TOC to the address of the the
- // relocated symbol rather than the symbol's address.
- R_ADDRPOWER_TOCREL_DS
-
- // R_PCRELDBL relocates s390x 2-byte aligned PC-relative addresses.
- // TODO(mundaym): remove once variants can be serialized - see issue 14218.
- R_PCRELDBL
-
- // R_ADDRMIPSU (only used on mips/mips64) resolves to the sign-adjusted "upper" 16
- // bits (bit 16-31) of an external address, by encoding it into the instruction.
- R_ADDRMIPSU
- // R_ADDRMIPSTLS (only used on mips64) resolves to the low 16 bits of a TLS
- // address (offset from thread pointer), by encoding it into the instruction.
- R_ADDRMIPSTLS
-)
-
-// IsDirectJump returns whether r is a relocation for a direct jump.
-// A direct jump is a CALL or JMP instruction that takes the target address
-// as immediate. The address is embedded into the instruction, possibly
-// with limited width.
-// An indirect jump is a CALL or JMP instruction that takes the target address
-// in register or memory.
-func (r RelocType) IsDirectJump() bool {
- switch r {
- case R_CALL, R_CALLARM, R_CALLARM64, R_CALLPOWER, R_CALLMIPS, R_JMPMIPS:
- return true
- }
- return false
-}
-
type Auto struct {
Asym *LSym
Aoffset int32
@@ -737,12 +463,6 @@ type Auto struct {
Gotype *LSym
}
-// Auto.name
-const (
- A_AUTO = 1 + iota
- A_PARAM
-)
-
type Pcdata struct {
P []byte
}
@@ -750,7 +470,7 @@ type Pcdata struct {
// Link holds the context for writing object code from a compiler
// to be linker input or for reading that input into the linker.
type Link struct {
- Headtype HeadType
+ Headtype objabi.HeadType
Arch *LinkArch
Debugasm bool
Debugvlog bool
@@ -816,74 +536,3 @@ type LinkArch struct {
Progedit func(*Link, *Prog, ProgAlloc)
UnaryDst map[As]bool // Instruction takes one operand, a destination.
}
-
-// HeadType is the executable header type.
-type HeadType uint8
-
-const (
- Hunknown HeadType = iota
- Hdarwin
- Hdragonfly
- Hfreebsd
- Hlinux
- Hnacl
- Hnetbsd
- Hopenbsd
- Hplan9
- Hsolaris
- Hwindows
-)
-
-func (h *HeadType) Set(s string) error {
- switch s {
- case "darwin":
- *h = Hdarwin
- case "dragonfly":
- *h = Hdragonfly
- case "freebsd":
- *h = Hfreebsd
- case "linux", "android":
- *h = Hlinux
- case "nacl":
- *h = Hnacl
- case "netbsd":
- *h = Hnetbsd
- case "openbsd":
- *h = Hopenbsd
- case "plan9":
- *h = Hplan9
- case "solaris":
- *h = Hsolaris
- case "windows":
- *h = Hwindows
- default:
- return fmt.Errorf("invalid headtype: %q", s)
- }
- return nil
-}
-
-func (h *HeadType) String() string {
- switch *h {
- case Hdarwin:
- return "darwin"
- case Hdragonfly:
- return "dragonfly"
- case Hfreebsd:
- return "freebsd"
- case Hlinux:
- return "linux"
- case Hnacl:
- return "nacl"
- case Hnetbsd:
- return "netbsd"
- case Hopenbsd:
- return "openbsd"
- case Hplan9:
- return "plan9"
- case Hsolaris:
- return "solaris"
- case Hwindows:
- return "windows"
- }
- return fmt.Sprintf("HeadType(%d)", *h)
-}