2015-02-27 22:57:28 -05:00
|
|
|
// Inferno utils/8l/asm.c
|
2016-08-28 17:04:46 -07:00
|
|
|
// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/8l/asm.c
|
2015-02-27 22:57:28 -05:00
|
|
|
//
|
|
|
|
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
|
|
|
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
|
|
|
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
|
|
|
|
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
|
|
|
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
|
|
|
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
|
|
|
|
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
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
|
|
|
//
|
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
|
|
|
// in the Software without restriction, including without limitation the rights
|
|
|
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
|
|
|
// furnished to do so, subject to the following conditions:
|
|
|
|
|
//
|
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
|
//
|
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
|
// THE SOFTWARE.
|
|
|
|
|
|
2015-05-21 13:28:10 -04:00
|
|
|
package x86
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
import (
|
2017-04-18 12:53:25 -07:00
|
|
|
"cmd/internal/objabi"
|
2017-09-30 21:10:49 +00:00
|
|
|
"cmd/internal/sys"
|
2015-05-21 13:28:10 -04:00
|
|
|
"cmd/link/internal/ld"
|
2017-10-04 17:54:04 -04:00
|
|
|
"cmd/link/internal/sym"
|
2017-10-06 16:01:02 -04:00
|
|
|
"debug/elf"
|
2015-02-27 22:57:28 -05:00
|
|
|
"log"
|
|
|
|
|
)
|
|
|
|
|
|
2015-10-28 12:15:43 +13:00
|
|
|
// Append 4 bytes to s and create a R_CALL relocation targeting t to fill them in.
|
2017-10-04 17:54:04 -04:00
|
|
|
func addcall(ctxt *ld.Link, s *sym.Symbol, t *sym.Symbol) {
|
|
|
|
|
s.Attr |= sym.AttrReachable
|
2015-10-28 12:15:43 +13:00
|
|
|
i := s.Size
|
|
|
|
|
s.Size += 4
|
2017-09-30 15:06:44 +00:00
|
|
|
s.Grow(s.Size)
|
|
|
|
|
r := s.AddRel()
|
2015-10-28 12:15:43 +13:00
|
|
|
r.Sym = t
|
|
|
|
|
r.Off = int32(i)
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_CALL
|
2015-10-28 12:15:43 +13:00
|
|
|
r.Siz = 4
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-21 13:52:23 -04:00
|
|
|
func gentext(ctxt *ld.Link) {
|
2016-08-25 21:06:10 -04:00
|
|
|
if ctxt.DynlinkingGo() {
|
2016-06-16 12:59:09 -07:00
|
|
|
// We need get_pc_thunk.
|
|
|
|
|
} else {
|
2017-10-05 10:20:17 -04:00
|
|
|
switch ctxt.BuildMode {
|
|
|
|
|
case ld.BuildModeCArchive:
|
2016-06-16 12:59:09 -07:00
|
|
|
if !ld.Iself {
|
|
|
|
|
return
|
|
|
|
|
}
|
2017-10-05 10:20:17 -04:00
|
|
|
case ld.BuildModePIE, ld.BuildModeCShared, ld.BuildModePlugin:
|
2016-06-16 12:59:09 -07:00
|
|
|
// We need get_pc_thunk.
|
|
|
|
|
default:
|
|
|
|
|
return
|
|
|
|
|
}
|
2015-10-28 11:40:22 +13:00
|
|
|
}
|
|
|
|
|
|
[dev.ssa] cmd/compile: fix PIC for SSA-generated code
Access to globals requires a 2-instruction sequence on PIC 386.
MOVL foo(SB), AX
is translated by the obj package into:
CALL getPCofNextInstructionInTempRegister(SB)
MOVL (&foo-&thisInstruction)(tmpReg), AX
The call returns the PC of the next instruction in a register.
The next instruction then offsets from that register to get the
address required. The tricky part is the allocation of the
temp register. The legacy compiler always used CX, and forbid
the register allocator from allocating CX when in PIC mode.
We can't easily do that in SSA because CX is actually a required
register for shift instructions. (I think the old backend got away
with this because the register allocator never uses CX, only
codegen knows that shifts must use CX.)
Instead, we allow the temp register to be anything. When the
destination of the MOV (or LEA) is an integer register, we can
use that register. Otherwise, we make sure to compile the
operation using an LEA to reference the global. So
MOVL AX, foo(SB)
is never generated directly. Instead, SSA generates:
LEAL foo(SB), DX
MOVL AX, (DX)
which is then rewritten by the obj package to:
CALL getPcInDX(SB)
LEAL (&foo-&thisInstruction)(DX), AX
MOVL AX, (DX)
So this CL modifies the obj package to use different thunks
to materialize the pc into different registers. We use the
registers that regalloc chose so that SSA can still allocate
the full set of registers.
Change-Id: Ie095644f7164a026c62e95baf9d18a8bcaed0bba
Reviewed-on: https://go-review.googlesource.com/25442
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
2016-08-03 13:00:49 -07:00
|
|
|
// Generate little thunks that load the PC of the next instruction into a register.
|
2017-10-04 17:54:04 -04:00
|
|
|
thunks := make([]*sym.Symbol, 0, 7+len(ctxt.Textp))
|
[dev.ssa] cmd/compile: fix PIC for SSA-generated code
Access to globals requires a 2-instruction sequence on PIC 386.
MOVL foo(SB), AX
is translated by the obj package into:
CALL getPCofNextInstructionInTempRegister(SB)
MOVL (&foo-&thisInstruction)(tmpReg), AX
The call returns the PC of the next instruction in a register.
The next instruction then offsets from that register to get the
address required. The tricky part is the allocation of the
temp register. The legacy compiler always used CX, and forbid
the register allocator from allocating CX when in PIC mode.
We can't easily do that in SSA because CX is actually a required
register for shift instructions. (I think the old backend got away
with this because the register allocator never uses CX, only
codegen knows that shifts must use CX.)
Instead, we allow the temp register to be anything. When the
destination of the MOV (or LEA) is an integer register, we can
use that register. Otherwise, we make sure to compile the
operation using an LEA to reference the global. So
MOVL AX, foo(SB)
is never generated directly. Instead, SSA generates:
LEAL foo(SB), DX
MOVL AX, (DX)
which is then rewritten by the obj package to:
CALL getPcInDX(SB)
LEAL (&foo-&thisInstruction)(DX), AX
MOVL AX, (DX)
So this CL modifies the obj package to use different thunks
to materialize the pc into different registers. We use the
registers that regalloc chose so that SSA can still allocate
the full set of registers.
Change-Id: Ie095644f7164a026c62e95baf9d18a8bcaed0bba
Reviewed-on: https://go-review.googlesource.com/25442
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
2016-08-03 13:00:49 -07:00
|
|
|
for _, r := range [...]struct {
|
|
|
|
|
name string
|
|
|
|
|
num uint8
|
|
|
|
|
}{
|
|
|
|
|
{"ax", 0},
|
|
|
|
|
{"cx", 1},
|
|
|
|
|
{"dx", 2},
|
|
|
|
|
{"bx", 3},
|
|
|
|
|
// sp
|
|
|
|
|
{"bp", 5},
|
|
|
|
|
{"si", 6},
|
|
|
|
|
{"di", 7},
|
|
|
|
|
} {
|
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
|
|
|
thunkfunc := ctxt.Syms.Lookup("__x86.get_pc_thunk."+r.name, 0)
|
2017-10-04 17:54:04 -04:00
|
|
|
thunkfunc.Type = sym.STEXT
|
|
|
|
|
thunkfunc.Attr |= sym.AttrLocal
|
|
|
|
|
thunkfunc.Attr |= sym.AttrReachable //TODO: remove?
|
[dev.ssa] cmd/compile: fix PIC for SSA-generated code
Access to globals requires a 2-instruction sequence on PIC 386.
MOVL foo(SB), AX
is translated by the obj package into:
CALL getPCofNextInstructionInTempRegister(SB)
MOVL (&foo-&thisInstruction)(tmpReg), AX
The call returns the PC of the next instruction in a register.
The next instruction then offsets from that register to get the
address required. The tricky part is the allocation of the
temp register. The legacy compiler always used CX, and forbid
the register allocator from allocating CX when in PIC mode.
We can't easily do that in SSA because CX is actually a required
register for shift instructions. (I think the old backend got away
with this because the register allocator never uses CX, only
codegen knows that shifts must use CX.)
Instead, we allow the temp register to be anything. When the
destination of the MOV (or LEA) is an integer register, we can
use that register. Otherwise, we make sure to compile the
operation using an LEA to reference the global. So
MOVL AX, foo(SB)
is never generated directly. Instead, SSA generates:
LEAL foo(SB), DX
MOVL AX, (DX)
which is then rewritten by the obj package to:
CALL getPcInDX(SB)
LEAL (&foo-&thisInstruction)(DX), AX
MOVL AX, (DX)
So this CL modifies the obj package to use different thunks
to materialize the pc into different registers. We use the
registers that regalloc chose so that SSA can still allocate
the full set of registers.
Change-Id: Ie095644f7164a026c62e95baf9d18a8bcaed0bba
Reviewed-on: https://go-review.googlesource.com/25442
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
2016-08-03 13:00:49 -07:00
|
|
|
o := func(op ...uint8) {
|
|
|
|
|
for _, op1 := range op {
|
2017-09-30 15:06:44 +00:00
|
|
|
thunkfunc.AddUint8(op1)
|
[dev.ssa] cmd/compile: fix PIC for SSA-generated code
Access to globals requires a 2-instruction sequence on PIC 386.
MOVL foo(SB), AX
is translated by the obj package into:
CALL getPCofNextInstructionInTempRegister(SB)
MOVL (&foo-&thisInstruction)(tmpReg), AX
The call returns the PC of the next instruction in a register.
The next instruction then offsets from that register to get the
address required. The tricky part is the allocation of the
temp register. The legacy compiler always used CX, and forbid
the register allocator from allocating CX when in PIC mode.
We can't easily do that in SSA because CX is actually a required
register for shift instructions. (I think the old backend got away
with this because the register allocator never uses CX, only
codegen knows that shifts must use CX.)
Instead, we allow the temp register to be anything. When the
destination of the MOV (or LEA) is an integer register, we can
use that register. Otherwise, we make sure to compile the
operation using an LEA to reference the global. So
MOVL AX, foo(SB)
is never generated directly. Instead, SSA generates:
LEAL foo(SB), DX
MOVL AX, (DX)
which is then rewritten by the obj package to:
CALL getPcInDX(SB)
LEAL (&foo-&thisInstruction)(DX), AX
MOVL AX, (DX)
So this CL modifies the obj package to use different thunks
to materialize the pc into different registers. We use the
registers that regalloc chose so that SSA can still allocate
the full set of registers.
Change-Id: Ie095644f7164a026c62e95baf9d18a8bcaed0bba
Reviewed-on: https://go-review.googlesource.com/25442
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
2016-08-03 13:00:49 -07:00
|
|
|
}
|
2015-10-28 11:40:22 +13:00
|
|
|
}
|
[dev.ssa] cmd/compile: fix PIC for SSA-generated code
Access to globals requires a 2-instruction sequence on PIC 386.
MOVL foo(SB), AX
is translated by the obj package into:
CALL getPCofNextInstructionInTempRegister(SB)
MOVL (&foo-&thisInstruction)(tmpReg), AX
The call returns the PC of the next instruction in a register.
The next instruction then offsets from that register to get the
address required. The tricky part is the allocation of the
temp register. The legacy compiler always used CX, and forbid
the register allocator from allocating CX when in PIC mode.
We can't easily do that in SSA because CX is actually a required
register for shift instructions. (I think the old backend got away
with this because the register allocator never uses CX, only
codegen knows that shifts must use CX.)
Instead, we allow the temp register to be anything. When the
destination of the MOV (or LEA) is an integer register, we can
use that register. Otherwise, we make sure to compile the
operation using an LEA to reference the global. So
MOVL AX, foo(SB)
is never generated directly. Instead, SSA generates:
LEAL foo(SB), DX
MOVL AX, (DX)
which is then rewritten by the obj package to:
CALL getPcInDX(SB)
LEAL (&foo-&thisInstruction)(DX), AX
MOVL AX, (DX)
So this CL modifies the obj package to use different thunks
to materialize the pc into different registers. We use the
registers that regalloc chose so that SSA can still allocate
the full set of registers.
Change-Id: Ie095644f7164a026c62e95baf9d18a8bcaed0bba
Reviewed-on: https://go-review.googlesource.com/25442
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
2016-08-03 13:00:49 -07:00
|
|
|
// 8b 04 24 mov (%esp),%eax
|
|
|
|
|
// Destination register is in bits 3-5 of the middle byte, so add that in.
|
|
|
|
|
o(0x8b, 0x04+r.num<<3, 0x24)
|
|
|
|
|
// c3 ret
|
|
|
|
|
o(0xc3)
|
2015-10-28 11:40:22 +13:00
|
|
|
|
2016-09-14 14:47:12 -04:00
|
|
|
thunks = append(thunks, thunkfunc)
|
[dev.ssa] cmd/compile: fix PIC for SSA-generated code
Access to globals requires a 2-instruction sequence on PIC 386.
MOVL foo(SB), AX
is translated by the obj package into:
CALL getPCofNextInstructionInTempRegister(SB)
MOVL (&foo-&thisInstruction)(tmpReg), AX
The call returns the PC of the next instruction in a register.
The next instruction then offsets from that register to get the
address required. The tricky part is the allocation of the
temp register. The legacy compiler always used CX, and forbid
the register allocator from allocating CX when in PIC mode.
We can't easily do that in SSA because CX is actually a required
register for shift instructions. (I think the old backend got away
with this because the register allocator never uses CX, only
codegen knows that shifts must use CX.)
Instead, we allow the temp register to be anything. When the
destination of the MOV (or LEA) is an integer register, we can
use that register. Otherwise, we make sure to compile the
operation using an LEA to reference the global. So
MOVL AX, foo(SB)
is never generated directly. Instead, SSA generates:
LEAL foo(SB), DX
MOVL AX, (DX)
which is then rewritten by the obj package to:
CALL getPcInDX(SB)
LEAL (&foo-&thisInstruction)(DX), AX
MOVL AX, (DX)
So this CL modifies the obj package to use different thunks
to materialize the pc into different registers. We use the
registers that regalloc chose so that SSA can still allocate
the full set of registers.
Change-Id: Ie095644f7164a026c62e95baf9d18a8bcaed0bba
Reviewed-on: https://go-review.googlesource.com/25442
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
2016-08-03 13:00:49 -07:00
|
|
|
}
|
2016-09-14 14:47:12 -04:00
|
|
|
ctxt.Textp = append(thunks, ctxt.Textp...) // keep Textp in dependency order
|
2015-10-28 12:15:43 +13: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
|
|
|
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
|
2017-10-05 10:20:17 -04:00
|
|
|
if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
|
2015-10-28 12:15:43 +13:00
|
|
|
// we're linking a module containing the runtime -> no need for
|
|
|
|
|
// an init function
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-04 17:54:04 -04:00
|
|
|
addmoduledata.Attr |= sym.AttrReachable
|
2015-10-28 12:15:43 +13: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
|
|
|
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
|
2017-10-04 17:54:04 -04:00
|
|
|
initfunc.Type = sym.STEXT
|
|
|
|
|
initfunc.Attr |= sym.AttrLocal
|
|
|
|
|
initfunc.Attr |= sym.AttrReachable
|
[dev.ssa] cmd/compile: fix PIC for SSA-generated code
Access to globals requires a 2-instruction sequence on PIC 386.
MOVL foo(SB), AX
is translated by the obj package into:
CALL getPCofNextInstructionInTempRegister(SB)
MOVL (&foo-&thisInstruction)(tmpReg), AX
The call returns the PC of the next instruction in a register.
The next instruction then offsets from that register to get the
address required. The tricky part is the allocation of the
temp register. The legacy compiler always used CX, and forbid
the register allocator from allocating CX when in PIC mode.
We can't easily do that in SSA because CX is actually a required
register for shift instructions. (I think the old backend got away
with this because the register allocator never uses CX, only
codegen knows that shifts must use CX.)
Instead, we allow the temp register to be anything. When the
destination of the MOV (or LEA) is an integer register, we can
use that register. Otherwise, we make sure to compile the
operation using an LEA to reference the global. So
MOVL AX, foo(SB)
is never generated directly. Instead, SSA generates:
LEAL foo(SB), DX
MOVL AX, (DX)
which is then rewritten by the obj package to:
CALL getPcInDX(SB)
LEAL (&foo-&thisInstruction)(DX), AX
MOVL AX, (DX)
So this CL modifies the obj package to use different thunks
to materialize the pc into different registers. We use the
registers that regalloc chose so that SSA can still allocate
the full set of registers.
Change-Id: Ie095644f7164a026c62e95baf9d18a8bcaed0bba
Reviewed-on: https://go-review.googlesource.com/25442
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
2016-08-03 13:00:49 -07:00
|
|
|
o := func(op ...uint8) {
|
2015-10-28 12:15:43 +13:00
|
|
|
for _, op1 := range op {
|
2017-09-30 15:06:44 +00:00
|
|
|
initfunc.AddUint8(op1)
|
2015-10-28 12:15:43 +13:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// go.link.addmoduledata:
|
|
|
|
|
// 53 push %ebx
|
|
|
|
|
// e8 00 00 00 00 call __x86.get_pc_thunk.cx + R_CALL __x86.get_pc_thunk.cx
|
2016-08-21 13:52:23 -04:00
|
|
|
// 8d 81 00 00 00 00 lea 0x0(%ecx), %eax + R_PCREL ctxt.Moduledata
|
2015-10-28 12:15:43 +13:00
|
|
|
// 8d 99 00 00 00 00 lea 0x0(%ecx), %ebx + R_GOTPC _GLOBAL_OFFSET_TABLE_
|
|
|
|
|
// e8 00 00 00 00 call runtime.addmoduledata@plt + R_CALL runtime.addmoduledata
|
|
|
|
|
// 5b pop %ebx
|
|
|
|
|
// c3 ret
|
|
|
|
|
|
|
|
|
|
o(0x53)
|
|
|
|
|
|
|
|
|
|
o(0xe8)
|
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
|
|
|
addcall(ctxt, initfunc, ctxt.Syms.Lookup("__x86.get_pc_thunk.cx", 0))
|
2015-10-28 12:15:43 +13:00
|
|
|
|
|
|
|
|
o(0x8d, 0x81)
|
2017-09-30 15:06:44 +00:00
|
|
|
initfunc.AddPCRelPlus(ctxt.Arch, ctxt.Moduledata, 6)
|
2015-10-28 12:15:43 +13:00
|
|
|
|
|
|
|
|
o(0x8d, 0x99)
|
|
|
|
|
i := initfunc.Size
|
|
|
|
|
initfunc.Size += 4
|
2017-09-30 15:06:44 +00:00
|
|
|
initfunc.Grow(initfunc.Size)
|
|
|
|
|
r := initfunc.AddRel()
|
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
|
|
|
r.Sym = ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
|
2015-10-28 12:15:43 +13:00
|
|
|
r.Off = int32(i)
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_PCREL
|
2015-10-28 12:15:43 +13:00
|
|
|
r.Add = 12
|
|
|
|
|
r.Siz = 4
|
|
|
|
|
|
|
|
|
|
o(0xe8)
|
2016-08-21 13:52:23 -04:00
|
|
|
addcall(ctxt, initfunc, addmoduledata)
|
2015-10-28 12:15:43 +13:00
|
|
|
|
|
|
|
|
o(0x5b)
|
|
|
|
|
|
|
|
|
|
o(0xc3)
|
|
|
|
|
|
2017-10-05 10:20:17 -04:00
|
|
|
if ctxt.BuildMode == ld.BuildModePlugin {
|
2016-08-25 21:58:45 -04:00
|
|
|
ctxt.Textp = append(ctxt.Textp, addmoduledata)
|
|
|
|
|
}
|
2016-09-14 14:47:12 -04:00
|
|
|
ctxt.Textp = append(ctxt.Textp, initfunc)
|
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
|
|
|
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
|
2017-10-04 17:54:04 -04:00
|
|
|
initarray_entry.Attr |= sym.AttrReachable
|
|
|
|
|
initarray_entry.Attr |= sym.AttrLocal
|
|
|
|
|
initarray_entry.Type = sym.SINITARR
|
2017-09-30 15:06:44 +00:00
|
|
|
initarray_entry.AddAddr(ctxt.Arch, initfunc)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-10-04 17:54:04 -04:00
|
|
|
func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
|
2015-03-02 12:35:15 -05:00
|
|
|
targ := r.Sym
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
switch r.Type {
|
|
|
|
|
default:
|
|
|
|
|
if r.Type >= 256 {
|
2017-10-04 17:54:04 -04:00
|
|
|
ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
|
2016-09-05 23:49:53 -04:00
|
|
|
return false
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle relocations found in ELF object files.
|
2017-10-06 16:01:02 -04:00
|
|
|
case 256 + objabi.RelocType(elf.R_386_PC32):
|
2017-10-04 17:54:04 -04:00
|
|
|
if targ.Type == sym.SDYNIMPORT {
|
2016-09-17 09:39:33 -04:00
|
|
|
ld.Errorf(s, "unexpected R_386_PC32 relocation for dynamic symbol %s", targ.Name)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-28 12:43:06 +12:00
|
|
|
// TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
|
|
|
|
|
// sense and should be removed when someone has thought about it properly.
|
|
|
|
|
if (targ.Type == 0 || targ.Type == sym.SXREF) && !targ.Attr.VisibilityHidden() {
|
2016-09-17 09:39:33 -04:00
|
|
|
ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_PCREL
|
2015-02-27 22:57:28 -05:00
|
|
|
r.Add += 4
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-10-06 16:01:02 -04:00
|
|
|
case 256 + objabi.RelocType(elf.R_386_PLT32):
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_PCREL
|
2015-02-27 22:57:28 -05:00
|
|
|
r.Add += 4
|
2017-10-04 17:54:04 -04:00
|
|
|
if targ.Type == sym.SDYNIMPORT {
|
2016-08-21 13:52:23 -04:00
|
|
|
addpltsym(ctxt, targ)
|
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
|
|
|
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
r.Add += int64(targ.Plt)
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-10-06 16:01:02 -04:00
|
|
|
case 256 + objabi.RelocType(elf.R_386_GOT32), 256 + objabi.RelocType(elf.R_386_GOT32X):
|
2017-10-04 17:54:04 -04:00
|
|
|
if targ.Type != sym.SDYNIMPORT {
|
2015-02-27 22:57:28 -05:00
|
|
|
// have symbol
|
|
|
|
|
if r.Off >= 2 && s.P[r.Off-2] == 0x8b {
|
|
|
|
|
// turn MOVL of GOT entry into LEAL of symbol address, relative to GOT.
|
|
|
|
|
s.P[r.Off-2] = 0x8d
|
|
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_GOTOFF
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if r.Off >= 2 && s.P[r.Off-2] == 0xff && s.P[r.Off-1] == 0xb3 {
|
|
|
|
|
// turn PUSHL of GOT entry into PUSHL of symbol itself.
|
|
|
|
|
// use unnecessary SS prefix to keep instruction same length.
|
|
|
|
|
s.P[r.Off-2] = 0x36
|
|
|
|
|
|
|
|
|
|
s.P[r.Off-1] = 0x68
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_ADDR
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-09-17 09:39:33 -04:00
|
|
|
ld.Errorf(s, "unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
|
2016-09-05 23:49:53 -04:00
|
|
|
return false
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-08-21 13:52:23 -04:00
|
|
|
addgotsym(ctxt, targ)
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_CONST // write r->add during relocsym
|
2015-02-27 22:57:28 -05:00
|
|
|
r.Sym = nil
|
|
|
|
|
r.Add += int64(targ.Got)
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-10-06 16:01:02 -04:00
|
|
|
case 256 + objabi.RelocType(elf.R_386_GOTOFF):
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_GOTOFF
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-10-06 16:01:02 -04:00
|
|
|
case 256 + objabi.RelocType(elf.R_386_GOTPC):
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_PCREL
|
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
|
|
|
r.Sym = ctxt.Syms.Lookup(".got", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
r.Add += 4
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-10-06 16:01:02 -04:00
|
|
|
case 256 + objabi.RelocType(elf.R_386_32):
|
2017-10-04 17:54:04 -04:00
|
|
|
if targ.Type == sym.SDYNIMPORT {
|
2016-09-17 09:39:33 -04:00
|
|
|
ld.Errorf(s, "unexpected R_386_32 relocation for dynamic symbol %s", targ.Name)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_ADDR
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
case 512 + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 0:
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_ADDR
|
2017-10-04 17:54:04 -04:00
|
|
|
if targ.Type == sym.SDYNIMPORT {
|
2016-09-17 09:39:33 -04:00
|
|
|
ld.Errorf(s, "unexpected reloc for dynamic symbol %s", targ.Name)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
case 512 + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 1:
|
2017-10-04 17:54:04 -04:00
|
|
|
if targ.Type == sym.SDYNIMPORT {
|
2016-08-21 13:52:23 -04:00
|
|
|
addpltsym(ctxt, targ)
|
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
|
|
|
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
r.Add = int64(targ.Plt)
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_PCREL
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_PCREL
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
case 512 + ld.MACHO_FAKE_GOTPCREL:
|
2017-10-04 17:54:04 -04:00
|
|
|
if targ.Type != sym.SDYNIMPORT {
|
2015-02-27 22:57:28 -05:00
|
|
|
// have symbol
|
|
|
|
|
// turn MOVL of GOT entry into LEAL of symbol itself
|
|
|
|
|
if r.Off < 2 || s.P[r.Off-2] != 0x8b {
|
2016-09-17 09:39:33 -04:00
|
|
|
ld.Errorf(s, "unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
|
2016-09-05 23:49:53 -04:00
|
|
|
return false
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s.P[r.Off-2] = 0x8d
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_PCREL
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-08-21 13:52:23 -04:00
|
|
|
addgotsym(ctxt, targ)
|
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
|
|
|
r.Sym = ctxt.Syms.Lookup(".got", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
r.Add += int64(targ.Got)
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_PCREL
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle references to ELF symbols from our own object files.
|
2017-10-04 17:54:04 -04:00
|
|
|
if targ.Type != sym.SDYNIMPORT {
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
switch r.Type {
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_CALL,
|
|
|
|
|
objabi.R_PCREL:
|
2016-08-21 13:52:23 -04:00
|
|
|
addpltsym(ctxt, targ)
|
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
|
|
|
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
r.Add = int64(targ.Plt)
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_ADDR:
|
2017-10-04 17:54:04 -04:00
|
|
|
if s.Type != sym.SDATA {
|
2015-02-27 22:57:28 -05:00
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
if ld.Iself {
|
2016-08-21 13:52:23 -04:00
|
|
|
ld.Adddynsym(ctxt, targ)
|
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
|
|
|
rel := ctxt.Syms.Lookup(".rel", 0)
|
2017-09-30 15:06:44 +00:00
|
|
|
rel.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
|
2017-10-06 16:01:02 -04:00
|
|
|
rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), uint32(elf.R_386_32)))
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_CONST // write r->add during relocsym
|
2015-02-27 22:57:28 -05:00
|
|
|
r.Sym = nil
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-09-30 21:10:49 +00:00
|
|
|
if ld.Headtype == objabi.Hdarwin && s.Size == int64(ctxt.Arch.PtrSize) && r.Off == 0 {
|
2015-02-27 22:57:28 -05:00
|
|
|
// Mach-O relocations are a royal pain to lay out.
|
|
|
|
|
// They use a compact stateful bytecode representation
|
|
|
|
|
// that is too much bother to deal with.
|
|
|
|
|
// Instead, interpret the C declaration
|
|
|
|
|
// void *_Cvar_stderr = &stderr;
|
|
|
|
|
// as making _Cvar_stderr the name of a GOT entry
|
2016-03-01 23:21:55 +00:00
|
|
|
// for stderr. This is separate from the usual GOT entry,
|
2015-02-27 22:57:28 -05:00
|
|
|
// just in case the C code assigns to the variable,
|
|
|
|
|
// and of course it only works for single pointers,
|
|
|
|
|
// but we only need to support cgo and that's all it needs.
|
2016-08-21 13:52:23 -04:00
|
|
|
ld.Adddynsym(ctxt, targ)
|
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
|
|
|
got := ctxt.Syms.Lookup(".got", 0)
|
2017-10-04 17:54:04 -04:00
|
|
|
s.Type = got.Type | sym.SSUB
|
2015-02-27 22:57:28 -05:00
|
|
|
s.Outer = got
|
|
|
|
|
s.Sub = got.Sub
|
|
|
|
|
got.Sub = s
|
|
|
|
|
s.Value = got.Size
|
2017-09-30 15:06:44 +00:00
|
|
|
got.AddUint32(ctxt.Arch, 0)
|
|
|
|
|
ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(targ.Dynid))
|
2015-02-27 22:57:28 -05:00
|
|
|
r.Type = 256 // ignore during relocsym
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-05 23:49:53 -04:00
|
|
|
return false
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-10-04 17:54:04 -04:00
|
|
|
func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.Write32(uint32(sectoff))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2015-10-29 12:17:43 +13:00
|
|
|
elfsym := r.Xsym.ElfsymForReloc()
|
2015-02-27 22:57:28 -05:00
|
|
|
switch r.Type {
|
|
|
|
|
default:
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_ADDR:
|
2015-02-27 22:57:28 -05:00
|
|
|
if r.Siz == 4 {
|
2017-10-06 16:01:02 -04:00
|
|
|
ctxt.Out.Write32(uint32(elf.R_386_32) | uint32(elfsym)<<8)
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_GOTPCREL:
|
2015-11-18 12:30:23 +13:00
|
|
|
if r.Siz == 4 {
|
2017-10-06 16:01:02 -04:00
|
|
|
ctxt.Out.Write32(uint32(elf.R_386_GOTPC))
|
2015-11-18 12:30:23 +13:00
|
|
|
if r.Xsym.Name != "_GLOBAL_OFFSET_TABLE_" {
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.Write32(uint32(sectoff))
|
2017-10-06 16:01:02 -04:00
|
|
|
ctxt.Out.Write32(uint32(elf.R_386_GOT32) | uint32(elfsym)<<8)
|
2015-11-18 12:30:23 +13:00
|
|
|
}
|
|
|
|
|
} else {
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2015-11-18 12:30:23 +13:00
|
|
|
}
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_CALL:
|
2015-11-18 12:30:23 +13:00
|
|
|
if r.Siz == 4 {
|
2017-10-04 17:54:04 -04:00
|
|
|
if r.Xsym.Type == sym.SDYNIMPORT {
|
2017-10-06 16:01:02 -04:00
|
|
|
ctxt.Out.Write32(uint32(elf.R_386_PLT32) | uint32(elfsym)<<8)
|
2015-11-18 12:30:23 +13:00
|
|
|
} else {
|
2017-10-06 16:01:02 -04:00
|
|
|
ctxt.Out.Write32(uint32(elf.R_386_PC32) | uint32(elfsym)<<8)
|
2015-11-18 12:30:23 +13:00
|
|
|
}
|
|
|
|
|
} else {
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2015-11-18 12:30:23 +13:00
|
|
|
}
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_PCREL:
|
2015-02-27 22:57:28 -05:00
|
|
|
if r.Siz == 4 {
|
2017-10-06 16:01:02 -04:00
|
|
|
ctxt.Out.Write32(uint32(elf.R_386_PC32) | uint32(elfsym)<<8)
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_TLS_LE:
|
2015-02-27 22:57:28 -05:00
|
|
|
if r.Siz == 4 {
|
2017-10-06 16:01:02 -04:00
|
|
|
ctxt.Out.Write32(uint32(elf.R_386_TLS_LE) | uint32(elfsym)<<8)
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_TLS_IE:
|
2015-10-28 11:40:22 +13:00
|
|
|
if r.Siz == 4 {
|
2017-10-06 16:01:02 -04:00
|
|
|
ctxt.Out.Write32(uint32(elf.R_386_GOTPC))
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.Write32(uint32(sectoff))
|
2017-10-06 16:01:02 -04:00
|
|
|
ctxt.Out.Write32(uint32(elf.R_386_TLS_GOTIE) | uint32(elfsym)<<8)
|
2015-10-28 11:40:22 +13:00
|
|
|
} else {
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2015-10-28 11:40:22 +13:00
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-08-27 22:00:00 +09:00
|
|
|
return true
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-10-04 17:54:04 -04:00
|
|
|
func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
|
2015-02-27 22:57:28 -05:00
|
|
|
var v uint32
|
|
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
rs := r.Xsym
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-10-04 17:54:04 -04:00
|
|
|
if rs.Type == sym.SHOSTOBJ {
|
2015-02-27 22:57:28 -05:00
|
|
|
if rs.Dynid < 0 {
|
2017-10-04 17:54:04 -04:00
|
|
|
ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
v = uint32(rs.Dynid)
|
|
|
|
|
v |= 1 << 27 // external relocation
|
|
|
|
|
} else {
|
2015-05-27 12:04:25 +12:00
|
|
|
v = uint32(rs.Sect.Extnum)
|
2015-02-27 22:57:28 -05:00
|
|
|
if v == 0 {
|
2017-10-04 17:54:04 -04:00
|
|
|
ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch r.Type {
|
|
|
|
|
default:
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_ADDR:
|
2015-02-27 22:57:28 -05:00
|
|
|
v |= ld.MACHO_GENERIC_RELOC_VANILLA << 28
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_CALL,
|
|
|
|
|
objabi.R_PCREL:
|
2015-02-27 22:57:28 -05:00
|
|
|
v |= 1 << 24 // pc-relative bit
|
|
|
|
|
v |= ld.MACHO_GENERIC_RELOC_VANILLA << 28
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch r.Siz {
|
|
|
|
|
default:
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2015-02-27 22:57:28 -05:00
|
|
|
case 1:
|
|
|
|
|
v |= 0 << 25
|
|
|
|
|
case 2:
|
|
|
|
|
v |= 1 << 25
|
|
|
|
|
case 4:
|
|
|
|
|
v |= 2 << 25
|
|
|
|
|
case 8:
|
|
|
|
|
v |= 3 << 25
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
out.Write32(uint32(sectoff))
|
|
|
|
|
out.Write32(v)
|
2017-08-27 22:00:00 +09:00
|
|
|
return true
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-10-04 17:54:04 -04:00
|
|
|
func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
|
2015-03-09 03:05:40 -04:00
|
|
|
var v uint32
|
|
|
|
|
|
|
|
|
|
rs := r.Xsym
|
|
|
|
|
|
|
|
|
|
if rs.Dynid < 0 {
|
2017-10-04 17:54:04 -04:00
|
|
|
ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
|
2015-03-09 03:05:40 -04:00
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
out.Write32(uint32(sectoff))
|
|
|
|
|
out.Write32(uint32(rs.Dynid))
|
2015-03-09 03:05:40 -04:00
|
|
|
|
|
|
|
|
switch r.Type {
|
|
|
|
|
default:
|
|
|
|
|
return false
|
|
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_DWARFREF:
|
2017-02-08 12:30:30 +11:00
|
|
|
v = ld.IMAGE_REL_I386_SECREL
|
|
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_ADDR:
|
2015-03-09 03:05:40 -04:00
|
|
|
v = ld.IMAGE_REL_I386_DIR32
|
|
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_CALL,
|
|
|
|
|
objabi.R_PCREL:
|
2015-03-09 03:05:40 -04:00
|
|
|
v = ld.IMAGE_REL_I386_REL32
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
out.Write16(uint16(v))
|
2015-03-09 03:05:40 -04:00
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-04 17:54:04 -04:00
|
|
|
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
|
2017-10-05 10:20:17 -04:00
|
|
|
if ctxt.LinkMode == ld.LinkExternal {
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
switch r.Type {
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_CONST:
|
2015-02-27 22:57:28 -05:00
|
|
|
*val = r.Add
|
2017-08-27 22:00:00 +09:00
|
|
|
return true
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_GOTOFF:
|
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
|
|
|
*val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0))
|
2017-08-27 22:00:00 +09:00
|
|
|
return true
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-10-04 17:54:04 -04:00
|
|
|
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
|
2015-02-27 22:57:28 -05:00
|
|
|
log.Fatalf("unexpected relocation variant")
|
|
|
|
|
return t
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-21 13:52:23 -04:00
|
|
|
func elfsetupplt(ctxt *ld.Link) {
|
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
|
|
|
plt := ctxt.Syms.Lookup(".plt", 0)
|
|
|
|
|
got := ctxt.Syms.Lookup(".got.plt", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
if plt.Size == 0 {
|
|
|
|
|
// pushl got+4
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0xff)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0x35)
|
|
|
|
|
plt.AddAddrPlus(ctxt.Arch, got, 4)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// jmp *got+8
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0xff)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0x25)
|
|
|
|
|
plt.AddAddrPlus(ctxt.Arch, got, 8)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// zero pad
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint32(ctxt.Arch, 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// assume got->size == 0 too
|
2017-09-30 15:06:44 +00:00
|
|
|
got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-09-30 15:06:44 +00:00
|
|
|
got.AddUint32(ctxt.Arch, 0)
|
|
|
|
|
got.AddUint32(ctxt.Arch, 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-04 17:54:04 -04:00
|
|
|
func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
|
2015-02-27 22:57:28 -05:00
|
|
|
if s.Plt >= 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-12 15:59:15 +12:00
|
|
|
ld.Adddynsym(ctxt, s)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
if ld.Iself {
|
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
|
|
|
plt := ctxt.Syms.Lookup(".plt", 0)
|
|
|
|
|
got := ctxt.Syms.Lookup(".got.plt", 0)
|
|
|
|
|
rel := ctxt.Syms.Lookup(".rel.plt", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
if plt.Size == 0 {
|
2016-08-21 13:52:23 -04:00
|
|
|
elfsetupplt(ctxt)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// jmpq *got+size
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0xff)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0x25)
|
|
|
|
|
plt.AddAddrPlus(ctxt.Arch, got, got.Size)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// add to got: pointer to current pos in plt
|
2017-09-30 15:06:44 +00:00
|
|
|
got.AddAddrPlus(ctxt.Arch, plt, plt.Size)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// pushl $x
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0x68)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint32(ctxt.Arch, uint32(rel.Size))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// jmp .plt
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0xe9)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint32(ctxt.Arch, uint32(-(plt.Size + 4)))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// rel
|
2017-09-30 15:06:44 +00:00
|
|
|
rel.AddAddrPlus(ctxt.Arch, got, got.Size-4)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-10-06 16:01:02 -04:00
|
|
|
rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_JMP_SLOT)))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
s.Plt = int32(plt.Size - 16)
|
2017-04-18 12:53:25 -07:00
|
|
|
} else if ld.Headtype == objabi.Hdarwin {
|
2015-02-27 22:57:28 -05:00
|
|
|
// Same laziness as in 6l.
|
|
|
|
|
|
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
|
|
|
plt := ctxt.Syms.Lookup(".plt", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
addgotsym(ctxt, s)
|
|
|
|
|
|
2017-09-30 15:06:44 +00:00
|
|
|
ctxt.Syms.Lookup(".linkedit.plt", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// jmpq *got+size(IP)
|
|
|
|
|
s.Plt = int32(plt.Size)
|
|
|
|
|
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0xff)
|
|
|
|
|
plt.AddUint8(0x25)
|
|
|
|
|
plt.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".got", 0), int64(s.Got))
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
2016-09-17 09:39:33 -04:00
|
|
|
ld.Errorf(s, "addpltsym: unsupported binary format")
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-04 17:54:04 -04:00
|
|
|
func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
|
2015-02-27 22:57:28 -05:00
|
|
|
if s.Got >= 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-12 15:59:15 +12:00
|
|
|
ld.Adddynsym(ctxt, s)
|
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
|
|
|
got := ctxt.Syms.Lookup(".got", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
s.Got = int32(got.Size)
|
2017-09-30 15:06:44 +00:00
|
|
|
got.AddUint32(ctxt.Arch, 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
if ld.Iself {
|
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
|
|
|
rel := ctxt.Syms.Lookup(".rel", 0)
|
2017-09-30 15:06:44 +00:00
|
|
|
rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got))
|
2017-10-06 16:01:02 -04:00
|
|
|
rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_GLOB_DAT)))
|
2017-04-18 12:53:25 -07:00
|
|
|
} else if ld.Headtype == objabi.Hdarwin {
|
2017-09-30 15:06:44 +00:00
|
|
|
ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
2016-09-17 09:39:33 -04:00
|
|
|
ld.Errorf(s, "addgotsym: unsupported binary format")
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
func asmb(ctxt *ld.Link) {
|
2016-08-21 18:25:28 -04:00
|
|
|
if ctxt.Debugvlog != 0 {
|
2017-04-18 12:53:25 -07:00
|
|
|
ctxt.Logf("%5.2f asmb\n", ld.Cputime())
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ld.Iself {
|
2016-09-20 15:57:53 +12:00
|
|
|
ld.Asmbelfsetup()
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-04-18 21:52:06 +12:00
|
|
|
sect := ld.Segtext.Sections[0]
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
|
2016-06-11 17:12:28 -07:00
|
|
|
// 0xCC is INT $3 - breakpoint instruction
|
2016-08-19 22:40:38 -04:00
|
|
|
ld.CodeblkPad(ctxt, int64(sect.Vaddr), int64(sect.Length), []byte{0xCC})
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect = range ld.Segtext.Sections[1:] {
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
|
2016-08-19 22:40:38 -04:00
|
|
|
ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ld.Segrodata.Filelen > 0 {
|
2016-08-21 18:25:28 -04:00
|
|
|
if ctxt.Debugvlog != 0 {
|
2017-04-18 12:53:25 -07:00
|
|
|
ctxt.Logf("%5.2f rodatblk\n", ld.Cputime())
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
|
2016-08-19 22:40:38 -04:00
|
|
|
ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2016-09-05 23:29:16 -04:00
|
|
|
if ld.Segrelrodata.Filelen > 0 {
|
|
|
|
|
if ctxt.Debugvlog != 0 {
|
2017-04-18 12:53:25 -07:00
|
|
|
ctxt.Logf("%5.2f relrodatblk\n", ld.Cputime())
|
2016-09-05 23:29:16 -04:00
|
|
|
}
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
|
2016-09-05 23:29:16 -04:00
|
|
|
ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
|
|
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-08-21 18:25:28 -04:00
|
|
|
if ctxt.Debugvlog != 0 {
|
2017-04-18 12:53:25 -07:00
|
|
|
ctxt.Logf("%5.2f datblk\n", ld.Cputime())
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
|
2016-08-19 22:40:38 -04:00
|
|
|
ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
|
2016-08-19 22:40:38 -04:00
|
|
|
ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
|
2016-03-14 09:23:04 -07:00
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
machlink := uint32(0)
|
2017-04-18 12:53:25 -07:00
|
|
|
if ld.Headtype == objabi.Hdarwin {
|
2016-08-19 22:40:38 -04:00
|
|
|
machlink = uint32(ld.Domacholink(ctxt))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ld.Symsize = 0
|
|
|
|
|
ld.Spsize = 0
|
|
|
|
|
ld.Lcsize = 0
|
2015-03-02 12:35:15 -05:00
|
|
|
symo := uint32(0)
|
2016-08-21 18:34:24 -04:00
|
|
|
if !*ld.FlagS {
|
2015-02-27 22:57:28 -05:00
|
|
|
// TODO: rationalize
|
2016-08-21 18:25:28 -04:00
|
|
|
if ctxt.Debugvlog != 0 {
|
2017-04-18 12:53:25 -07:00
|
|
|
ctxt.Logf("%5.2f sym\n", ld.Cputime())
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2016-09-09 06:20:44 -04:00
|
|
|
switch ld.Headtype {
|
2015-02-27 22:57:28 -05:00
|
|
|
default:
|
|
|
|
|
if ld.Iself {
|
2016-03-14 09:23:04 -07:00
|
|
|
symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
|
2016-08-21 18:34:24 -04:00
|
|
|
symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hplan9:
|
2015-02-27 22:57:28 -05:00
|
|
|
symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
|
|
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hdarwin:
|
2016-08-21 18:34:24 -04:00
|
|
|
symo = uint32(ld.Segdwarf.Fileoff + uint64(ld.Rnd(int64(ld.Segdwarf.Filelen), int64(*ld.FlagRound))) + uint64(machlink))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hwindows:
|
2016-03-14 09:23:04 -07:00
|
|
|
symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
|
2015-02-27 22:57:28 -05:00
|
|
|
symo = uint32(ld.Rnd(int64(symo), ld.PEFILEALIGN))
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.SeekSet(int64(symo))
|
2016-09-09 06:20:44 -04:00
|
|
|
switch ld.Headtype {
|
2015-02-27 22:57:28 -05:00
|
|
|
default:
|
|
|
|
|
if ld.Iself {
|
2016-08-21 18:25:28 -04:00
|
|
|
if ctxt.Debugvlog != 0 {
|
2017-04-18 12:53:25 -07:00
|
|
|
ctxt.Logf("%5.2f elfsym\n", ld.Cputime())
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2016-08-19 22:40:38 -04:00
|
|
|
ld.Asmelfsym(ctxt)
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.Flush()
|
|
|
|
|
ctxt.Out.Write(ld.Elfstrdat)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-10-05 10:20:17 -04:00
|
|
|
if ctxt.LinkMode == ld.LinkExternal {
|
2016-08-19 22:40:38 -04:00
|
|
|
ld.Elfemitreloc(ctxt)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hplan9:
|
2016-08-19 22:40:38 -04:00
|
|
|
ld.Asmplan9sym(ctxt)
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.Flush()
|
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
|
|
|
sym := ctxt.Syms.Lookup("pclntab", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
if sym != nil {
|
|
|
|
|
ld.Lcsize = int32(len(sym.P))
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.Write(sym.P)
|
|
|
|
|
ctxt.Out.Flush()
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hwindows:
|
2016-08-21 18:25:28 -04:00
|
|
|
if ctxt.Debugvlog != 0 {
|
2017-04-18 12:53:25 -07:00
|
|
|
ctxt.Logf("%5.2f dwarf\n", ld.Cputime())
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hdarwin:
|
2017-10-05 10:20:17 -04:00
|
|
|
if ctxt.LinkMode == ld.LinkExternal {
|
2016-08-19 22:40:38 -04:00
|
|
|
ld.Machoemitreloc(ctxt)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-21 18:25:28 -04:00
|
|
|
if ctxt.Debugvlog != 0 {
|
2017-04-18 12:53:25 -07:00
|
|
|
ctxt.Logf("%5.2f headr\n", ld.Cputime())
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.SeekSet(0)
|
2016-09-09 06:20:44 -04:00
|
|
|
switch ld.Headtype {
|
2015-02-27 22:57:28 -05:00
|
|
|
default:
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hplan9: /* plan9 */
|
2015-03-02 12:35:15 -05:00
|
|
|
magic := int32(4*11*11 + 7)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.Write32b(uint32(magic)) /* magic */
|
|
|
|
|
ctxt.Out.Write32b(uint32(ld.Segtext.Filelen)) /* sizes */
|
|
|
|
|
ctxt.Out.Write32b(uint32(ld.Segdata.Filelen))
|
|
|
|
|
ctxt.Out.Write32b(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
|
|
|
|
|
ctxt.Out.Write32b(uint32(ld.Symsize)) /* nsyms */
|
|
|
|
|
ctxt.Out.Write32b(uint32(ld.Entryvalue(ctxt))) /* va of entry */
|
|
|
|
|
ctxt.Out.Write32b(uint32(ld.Spsize)) /* sp offsets */
|
|
|
|
|
ctxt.Out.Write32b(uint32(ld.Lcsize)) /* line offsets */
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hdarwin:
|
2016-08-19 22:40:38 -04:00
|
|
|
ld.Asmbmacho(ctxt)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hlinux,
|
|
|
|
|
objabi.Hfreebsd,
|
|
|
|
|
objabi.Hnetbsd,
|
|
|
|
|
objabi.Hopenbsd,
|
|
|
|
|
objabi.Hnacl:
|
2016-08-19 22:40:38 -04:00
|
|
|
ld.Asmbelf(ctxt, int64(symo))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hwindows:
|
2016-08-19 22:40:38 -04:00
|
|
|
ld.Asmbpe(ctxt)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.Flush()
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|