2015-02-27 22:57:28 -05:00
|
|
|
// Inferno utils/5l/asm.c
|
2016-08-28 17:04:46 -07:00
|
|
|
// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/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 arm
|
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
|
|
|
"fmt"
|
|
|
|
|
"log"
|
|
|
|
|
)
|
|
|
|
|
|
2015-09-02 22:25:57 +12:00
|
|
|
// This assembler:
|
|
|
|
|
//
|
|
|
|
|
// .align 2
|
|
|
|
|
// local.dso_init:
|
|
|
|
|
// ldr r0, .Lmoduledata
|
|
|
|
|
// .Lloadfrom:
|
|
|
|
|
// ldr r0, [r0]
|
|
|
|
|
// b runtime.addmoduledata@plt
|
|
|
|
|
// .align 2
|
|
|
|
|
// .Lmoduledata:
|
|
|
|
|
// .word local.moduledata(GOT_PREL) + (. - (.Lloadfrom + 4))
|
|
|
|
|
// assembles to:
|
|
|
|
|
//
|
|
|
|
|
// 00000000 <local.dso_init>:
|
|
|
|
|
// 0: e59f0004 ldr r0, [pc, #4] ; c <local.dso_init+0xc>
|
|
|
|
|
// 4: e5900000 ldr r0, [r0]
|
|
|
|
|
// 8: eafffffe b 0 <runtime.addmoduledata>
|
|
|
|
|
// 8: R_ARM_JUMP24 runtime.addmoduledata
|
|
|
|
|
// c: 00000004 .word 0x00000004
|
|
|
|
|
// c: R_ARM_GOT_PREL local.moduledata
|
|
|
|
|
|
2016-08-21 13:52:23 -04:00
|
|
|
func gentext(ctxt *ld.Link) {
|
2016-08-25 21:06:10 -04:00
|
|
|
if !ctxt.DynlinkingGo() {
|
2015-09-02 22:25:57 +12:00
|
|
|
return
|
|
|
|
|
}
|
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-09-02 22:25:57 +12: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
|
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
|
2015-09-02 22:25:57 +12:00
|
|
|
o := func(op uint32) {
|
2017-09-30 15:06:44 +00:00
|
|
|
initfunc.AddUint32(ctxt.Arch, op)
|
2015-09-02 22:25:57 +12:00
|
|
|
}
|
|
|
|
|
o(0xe59f0004)
|
|
|
|
|
o(0xe08f0000)
|
|
|
|
|
|
|
|
|
|
o(0xeafffffe)
|
2017-09-30 15:06:44 +00:00
|
|
|
rel := initfunc.AddRel()
|
2015-09-02 22:25:57 +12:00
|
|
|
rel.Off = 8
|
|
|
|
|
rel.Siz = 4
|
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.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
|
2017-04-18 12:53:25 -07:00
|
|
|
rel.Type = objabi.R_CALLARM
|
2015-09-02 22:25:57 +12:00
|
|
|
rel.Add = 0xeafffffe // vomit
|
|
|
|
|
|
|
|
|
|
o(0x00000000)
|
2017-09-30 15:06:44 +00:00
|
|
|
rel = initfunc.AddRel()
|
2015-09-02 22:25:57 +12:00
|
|
|
rel.Off = 12
|
|
|
|
|
rel.Siz = 4
|
2016-08-21 13:52:23 -04:00
|
|
|
rel.Sym = ctxt.Moduledata
|
2017-04-18 12:53:25 -07:00
|
|
|
rel.Type = objabi.R_PCREL
|
2015-09-02 22:25:57 +12:00
|
|
|
rel.Add = 4
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Preserve highest 8 bits of a, and do addition to lower 24-bit
|
2016-02-24 11:55:20 +01:00
|
|
|
// of a and b; used to adjust ARM branch instruction's target
|
2015-02-27 22:57:28 -05:00
|
|
|
func braddoff(a int32, b int32) int32 {
|
|
|
|
|
return int32((uint32(a))&0xff000000 | 0x00ffffff&uint32(a+b))
|
|
|
|
|
}
|
|
|
|
|
|
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_ARM_PLT32):
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_CALLARM
|
2015-02-27 22:57:28 -05:00
|
|
|
|
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(braddoff(int32(r.Add), targ.Plt/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_ARM_THM_PC22): // R_ARM_THM_CALL
|
2015-04-09 07:37:17 -04:00
|
|
|
ld.Exitf("R_ARM_THM_CALL, are you using -marm?")
|
2016-09-05 23:49:53 -04:00
|
|
|
return false
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-10-06 16:01:02 -04:00
|
|
|
case 256 + objabi.RelocType(elf.R_ARM_GOT32): // R_ARM_GOT_BREL
|
2017-10-04 17:54:04 -04:00
|
|
|
if targ.Type != sym.SDYNIMPORT {
|
2016-08-21 13:52:23 -04:00
|
|
|
addgotsyminternal(ctxt, targ)
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
2016-08-21 13:52:23 -04:00
|
|
|
addgotsym(ctxt, targ)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
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_ARM_GOT_PREL): // GOT(nil) + A - nil
|
2017-10-04 17:54:04 -04:00
|
|
|
if targ.Type != sym.SDYNIMPORT {
|
2016-08-21 13:52:23 -04:00
|
|
|
addgotsyminternal(ctxt, targ)
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
2016-08-21 13:52:23 -04:00
|
|
|
addgotsym(ctxt, targ)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
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 += int64(targ.Got) + 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_ARM_GOTOFF): // R_ARM_GOTOFF32
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_GOTOFF
|
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
|
|
|
|
2017-10-06 16:01:02 -04:00
|
|
|
case 256 + objabi.RelocType(elf.R_ARM_GOTPC): // R_ARM_BASE_PREL
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_PCREL
|
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
|
|
|
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_ARM_CALL):
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_CALLARM
|
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(braddoff(int32(r.Add), targ.Plt/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_ARM_REL32): // R_ARM_REL32
|
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_ARM_ABS32):
|
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_ARM_ABS32 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
|
|
|
|
|
|
|
|
// we can just ignore this, because we are targeting ARM V5+ anyway
|
2017-10-06 16:01:02 -04:00
|
|
|
case 256 + objabi.RelocType(elf.R_ARM_V4BX):
|
2015-02-27 22:57:28 -05:00
|
|
|
if r.Sym != nil {
|
|
|
|
|
// R_ARM_V4BX is ABS relocation, so this symbol is a dummy symbol, ignore it
|
|
|
|
|
r.Sym.Type = 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r.Sym = nil
|
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_ARM_PC24),
|
|
|
|
|
256 + objabi.RelocType(elf.R_ARM_JUMP24):
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_CALLARM
|
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(braddoff(int32(r.Add), targ.Plt/4))
|
|
|
|
|
}
|
|
|
|
|
|
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_CALLARM:
|
2018-05-01 10:48:19 +02:00
|
|
|
if ctxt.LinkMode == ld.LinkExternal {
|
|
|
|
|
// External linker will do this relocation.
|
|
|
|
|
return true
|
|
|
|
|
}
|
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
|
|
|
|
|
}
|
2017-10-07 13:43:38 -04:00
|
|
|
if ctxt.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_ARM_GLOB_DAT))) // we need a nil + A dynamic reloc
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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_ARM_ABS32) | 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_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_ARM_REL32) | 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_CALLARM:
|
2015-02-27 22:57:28 -05:00
|
|
|
if r.Siz == 4 {
|
|
|
|
|
if r.Add&0xff000000 == 0xeb000000 { // BL
|
2017-10-06 16:01:02 -04:00
|
|
|
ctxt.Out.Write32(uint32(elf.R_ARM_CALL) | uint32(elfsym)<<8)
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
2017-10-06 16:01:02 -04:00
|
|
|
ctxt.Out.Write32(uint32(elf.R_ARM_JUMP24) | 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:
|
2017-10-06 16:01:02 -04:00
|
|
|
ctxt.Out.Write32(uint32(elf.R_ARM_TLS_LE32) | uint32(elfsym)<<8)
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_TLS_IE:
|
2017-10-06 16:01:02 -04:00
|
|
|
ctxt.Out.Write32(uint32(elf.R_ARM_TLS_IE32) | uint32(elfsym)<<8)
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_GOTPCREL:
|
2015-09-02 22:25:57 +12:00
|
|
|
if r.Siz == 4 {
|
2017-10-06 16:01:02 -04:00
|
|
|
ctxt.Out.Write32(uint32(elf.R_ARM_GOT_PREL) | uint32(elfsym)<<8)
|
2015-09-02 22:25:57 +12:00
|
|
|
} else {
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2015-09-02 22:25:57 +12: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
|
|
|
}
|
|
|
|
|
|
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 {
|
|
|
|
|
// str lr, [sp, #-4]!
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint32(ctxt.Arch, 0xe52de004)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// ldr lr, [pc, #4]
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint32(ctxt.Arch, 0xe59fe004)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// add lr, pc, lr
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint32(ctxt.Arch, 0xe08fe00e)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// ldr pc, [lr, #8]!
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint32(ctxt.Arch, 0xe5bef008)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// .word &GLOBAL_OFFSET_TABLE[0] - .
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddPCRelPlus(ctxt.Arch, got, 4)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// the first .plt entry requires 3 .plt.got entries
|
2017-09-30 15:06:44 +00:00
|
|
|
got.AddUint32(ctxt.Arch, 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 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-04-18 12:53:25 -07:00
|
|
|
if r.Type == objabi.R_PCREL {
|
2017-10-04 17:54:04 -04:00
|
|
|
if rs.Type == sym.SHOSTOBJ {
|
2016-09-17 09:39:33 -04:00
|
|
|
ld.Errorf(s, "pc-relative relocation of external symbol is not supported")
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2016-04-26 15:17:56 -04:00
|
|
|
}
|
|
|
|
|
if r.Siz != 4 {
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2016-04-26 15:17:56 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// emit a pair of "scattered" relocations that
|
|
|
|
|
// resolve to the difference of section addresses of
|
|
|
|
|
// the symbol and the instruction
|
|
|
|
|
// this value is added to the field being relocated
|
|
|
|
|
o1 := uint32(sectoff)
|
|
|
|
|
o1 |= 1 << 31 // scattered bit
|
|
|
|
|
o1 |= ld.MACHO_ARM_RELOC_SECTDIFF << 24
|
|
|
|
|
o1 |= 2 << 28 // size = 4
|
|
|
|
|
|
|
|
|
|
o2 := uint32(0)
|
|
|
|
|
o2 |= 1 << 31 // scattered bit
|
|
|
|
|
o2 |= ld.MACHO_ARM_RELOC_PAIR << 24
|
|
|
|
|
o2 |= 2 << 28 // size = 4
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
out.Write32(o1)
|
|
|
|
|
out.Write32(uint32(ld.Symaddr(rs)))
|
|
|
|
|
out.Write32(o2)
|
|
|
|
|
out.Write32(uint32(s.Value + int64(r.Off)))
|
2017-08-27 22:00:00 +09:00
|
|
|
return true
|
2016-04-26 15:17:56 -04:00
|
|
|
}
|
|
|
|
|
|
2017-10-04 17:54:04 -04:00
|
|
|
if rs.Type == sym.SHOSTOBJ || r.Type == objabi.R_CALLARM {
|
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
|
2015-02-27 22:57:28 -05:00
|
|
|
|
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_CALLARM:
|
2015-02-27 22:57:28 -05:00
|
|
|
v |= 1 << 24 // pc-relative bit
|
|
|
|
|
v |= ld.MACHO_ARM_RELOC_BR24 << 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
|
|
|
}
|
|
|
|
|
|
2016-09-14 14:47:12 -04:00
|
|
|
// sign extend a 24-bit integer
|
|
|
|
|
func signext24(x int64) int32 {
|
|
|
|
|
return (int32(x) << 8) >> 8
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-17 13:40:18 -04:00
|
|
|
// encode an immediate in ARM's imm12 format. copied from ../../../internal/obj/arm/asm5.go
|
|
|
|
|
func immrot(v uint32) uint32 {
|
|
|
|
|
for i := 0; i < 16; i++ {
|
|
|
|
|
if v&^0xff == 0 {
|
|
|
|
|
return uint32(i<<8) | v | 1<<25
|
|
|
|
|
}
|
|
|
|
|
v = v<<2 | v>>30
|
|
|
|
|
}
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-14 14:47:12 -04:00
|
|
|
// Convert the direct jump relocation r to refer to a trampoline if the target is too far
|
2017-10-04 17:54:04 -04:00
|
|
|
func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) {
|
2016-09-14 14:47:12 -04:00
|
|
|
switch r.Type {
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_CALLARM:
|
2016-09-14 14:47:12 -04:00
|
|
|
// r.Add is the instruction
|
|
|
|
|
// low 24-bit encodes the target address
|
|
|
|
|
t := (ld.Symaddr(r.Sym) + int64(signext24(r.Add&0xffffff)*4) - (s.Value + int64(r.Off))) / 4
|
|
|
|
|
if t > 0x7fffff || t < -0x800000 || (*ld.FlagDebugTramp > 1 && s.File != r.Sym.File) {
|
2016-10-17 13:40:18 -04:00
|
|
|
// direct call too far, need to insert trampoline.
|
|
|
|
|
// look up existing trampolines first. if we found one within the range
|
|
|
|
|
// of direct call, we can reuse it. otherwise create a new one.
|
2016-09-14 14:47:12 -04:00
|
|
|
offset := (signext24(r.Add&0xffffff) + 2) * 4
|
2017-10-04 17:54:04 -04:00
|
|
|
var tramp *sym.Symbol
|
2016-09-14 14:47:12 -04:00
|
|
|
for i := 0; ; i++ {
|
|
|
|
|
name := r.Sym.Name + fmt.Sprintf("%+d-tramp%d", offset, i)
|
|
|
|
|
tramp = ctxt.Syms.Lookup(name, int(r.Sym.Version))
|
2017-10-04 17:54:04 -04:00
|
|
|
if tramp.Type == sym.SDYNIMPORT {
|
2016-10-17 13:40:18 -04:00
|
|
|
// don't reuse trampoline defined in other module
|
|
|
|
|
continue
|
|
|
|
|
}
|
2016-09-14 14:47:12 -04:00
|
|
|
if tramp.Value == 0 {
|
|
|
|
|
// either the trampoline does not exist -- we need to create one,
|
|
|
|
|
// or found one the address which is not assigned -- this will be
|
|
|
|
|
// laid down immediately after the current function. use this one.
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
t = (ld.Symaddr(tramp) - 8 - (s.Value + int64(r.Off))) / 4
|
|
|
|
|
if t >= -0x800000 && t < 0x7fffff {
|
|
|
|
|
// found an existing trampoline that is not too far
|
|
|
|
|
// we can just use it
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if tramp.Type == 0 {
|
|
|
|
|
// trampoline does not exist, create one
|
|
|
|
|
ctxt.AddTramp(tramp)
|
2016-10-17 13:40:18 -04:00
|
|
|
if ctxt.DynlinkingGo() {
|
|
|
|
|
if immrot(uint32(offset)) == 0 {
|
|
|
|
|
ld.Errorf(s, "odd offset in dynlink direct call: %v+%d", r.Sym, offset)
|
|
|
|
|
}
|
2017-09-30 21:10:49 +00:00
|
|
|
gentrampdyn(ctxt.Arch, tramp, r.Sym, int64(offset))
|
2017-10-05 10:20:17 -04:00
|
|
|
} else if ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE {
|
2017-09-30 21:10:49 +00:00
|
|
|
gentramppic(ctxt.Arch, tramp, r.Sym, int64(offset))
|
2016-10-17 13:40:18 -04:00
|
|
|
} else {
|
2017-10-05 10:20:17 -04:00
|
|
|
gentramp(ctxt.Arch, ctxt.LinkMode, tramp, r.Sym, int64(offset))
|
2016-10-17 13:40:18 -04:00
|
|
|
}
|
2016-09-14 14:47:12 -04:00
|
|
|
}
|
|
|
|
|
// modify reloc to point to tramp, which will be resolved later
|
|
|
|
|
r.Sym = tramp
|
|
|
|
|
r.Add = r.Add&0xff000000 | 0xfffffe // clear the offset embedded in the instruction
|
2017-08-27 22:00:00 +09:00
|
|
|
r.Done = false
|
2016-09-14 14:47:12 -04:00
|
|
|
}
|
|
|
|
|
default:
|
2017-10-04 17:54:04 -04:00
|
|
|
ld.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
|
2016-09-14 14:47:12 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-17 13:40:18 -04:00
|
|
|
// generate a trampoline to target+offset
|
2017-10-05 10:20:17 -04:00
|
|
|
func gentramp(arch *sys.Arch, linkmode ld.LinkMode, tramp, target *sym.Symbol, offset int64) {
|
2016-10-17 13:40:18 -04:00
|
|
|
tramp.Size = 12 // 3 instructions
|
|
|
|
|
tramp.P = make([]byte, tramp.Size)
|
2018-02-25 20:08:22 +09:00
|
|
|
t := ld.Symaddr(target) + offset
|
2016-10-17 13:40:18 -04:00
|
|
|
o1 := uint32(0xe5900000 | 11<<12 | 15<<16) // MOVW (R15), R11 // R15 is actual pc + 8
|
|
|
|
|
o2 := uint32(0xe12fff10 | 11) // JMP (R11)
|
|
|
|
|
o3 := uint32(t) // WORD $target
|
2017-09-30 21:10:49 +00:00
|
|
|
arch.ByteOrder.PutUint32(tramp.P, o1)
|
|
|
|
|
arch.ByteOrder.PutUint32(tramp.P[4:], o2)
|
|
|
|
|
arch.ByteOrder.PutUint32(tramp.P[8:], o3)
|
2016-10-17 13:40:18 -04:00
|
|
|
|
2017-10-05 10:20:17 -04:00
|
|
|
if linkmode == ld.LinkExternal {
|
2017-09-30 15:06:44 +00:00
|
|
|
r := tramp.AddRel()
|
2016-10-17 13:40:18 -04:00
|
|
|
r.Off = 8
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_ADDR
|
2016-10-17 13:40:18 -04:00
|
|
|
r.Siz = 4
|
|
|
|
|
r.Sym = target
|
|
|
|
|
r.Add = offset
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// generate a trampoline to target+offset in position independent code
|
2017-10-04 17:54:04 -04:00
|
|
|
func gentramppic(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) {
|
2016-10-17 13:40:18 -04:00
|
|
|
tramp.Size = 16 // 4 instructions
|
|
|
|
|
tramp.P = make([]byte, tramp.Size)
|
|
|
|
|
o1 := uint32(0xe5900000 | 11<<12 | 15<<16 | 4) // MOVW 4(R15), R11 // R15 is actual pc + 8
|
|
|
|
|
o2 := uint32(0xe0800000 | 11<<12 | 15<<16 | 11) // ADD R15, R11, R11
|
|
|
|
|
o3 := uint32(0xe12fff10 | 11) // JMP (R11)
|
|
|
|
|
o4 := uint32(0) // WORD $(target-pc) // filled in with relocation
|
2017-09-30 21:10:49 +00:00
|
|
|
arch.ByteOrder.PutUint32(tramp.P, o1)
|
|
|
|
|
arch.ByteOrder.PutUint32(tramp.P[4:], o2)
|
|
|
|
|
arch.ByteOrder.PutUint32(tramp.P[8:], o3)
|
|
|
|
|
arch.ByteOrder.PutUint32(tramp.P[12:], o4)
|
2016-10-17 13:40:18 -04:00
|
|
|
|
2017-09-30 15:06:44 +00:00
|
|
|
r := tramp.AddRel()
|
2016-10-17 13:40:18 -04:00
|
|
|
r.Off = 12
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_PCREL
|
2016-10-17 13:40:18 -04:00
|
|
|
r.Siz = 4
|
|
|
|
|
r.Sym = target
|
|
|
|
|
r.Add = offset + 4
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// generate a trampoline to target+offset in dynlink mode (using GOT)
|
2017-10-04 17:54:04 -04:00
|
|
|
func gentrampdyn(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) {
|
2016-10-17 13:40:18 -04:00
|
|
|
tramp.Size = 20 // 5 instructions
|
|
|
|
|
o1 := uint32(0xe5900000 | 11<<12 | 15<<16 | 8) // MOVW 8(R15), R11 // R15 is actual pc + 8
|
|
|
|
|
o2 := uint32(0xe0800000 | 11<<12 | 15<<16 | 11) // ADD R15, R11, R11
|
|
|
|
|
o3 := uint32(0xe5900000 | 11<<12 | 11<<16) // MOVW (R11), R11
|
|
|
|
|
o4 := uint32(0xe12fff10 | 11) // JMP (R11)
|
|
|
|
|
o5 := uint32(0) // WORD $target@GOT // filled in with relocation
|
|
|
|
|
o6 := uint32(0)
|
|
|
|
|
if offset != 0 {
|
|
|
|
|
// insert an instruction to add offset
|
|
|
|
|
tramp.Size = 24 // 6 instructions
|
|
|
|
|
o6 = o5
|
|
|
|
|
o5 = o4
|
2018-02-25 20:08:22 +09:00
|
|
|
o4 = 0xe2800000 | 11<<12 | 11<<16 | immrot(uint32(offset)) // ADD $offset, R11, R11
|
|
|
|
|
o1 = uint32(0xe5900000 | 11<<12 | 15<<16 | 12) // MOVW 12(R15), R11
|
2016-10-17 13:40:18 -04:00
|
|
|
}
|
|
|
|
|
tramp.P = make([]byte, tramp.Size)
|
2017-09-30 21:10:49 +00:00
|
|
|
arch.ByteOrder.PutUint32(tramp.P, o1)
|
|
|
|
|
arch.ByteOrder.PutUint32(tramp.P[4:], o2)
|
|
|
|
|
arch.ByteOrder.PutUint32(tramp.P[8:], o3)
|
|
|
|
|
arch.ByteOrder.PutUint32(tramp.P[12:], o4)
|
|
|
|
|
arch.ByteOrder.PutUint32(tramp.P[16:], o5)
|
2016-10-17 13:40:18 -04:00
|
|
|
if offset != 0 {
|
2017-09-30 21:10:49 +00:00
|
|
|
arch.ByteOrder.PutUint32(tramp.P[20:], o6)
|
2016-10-17 13:40:18 -04:00
|
|
|
}
|
|
|
|
|
|
2017-09-30 15:06:44 +00:00
|
|
|
r := tramp.AddRel()
|
2016-10-17 13:40:18 -04:00
|
|
|
r.Off = 16
|
2017-04-18 12:53:25 -07:00
|
|
|
r.Type = objabi.R_GOTPCREL
|
2016-10-17 13:40:18 -04:00
|
|
|
r.Siz = 4
|
|
|
|
|
r.Sym = target
|
|
|
|
|
r.Add = 8
|
|
|
|
|
if offset != 0 {
|
|
|
|
|
// increase reloc offset by 4 as we inserted an ADD instruction
|
|
|
|
|
r.Off = 20
|
|
|
|
|
r.Add = 12
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
cmd/link: fewer allocs in ld.Arch.Archreloc
Archreloc had this signature:
func(*Link, *sym.Reloc, *sym.Symbol, *int64) bool
The last *int64 argument is used as out parameter.
Passed valus could be allocated on stack, but escape analysis
fails here, leading to high number of unwanted allocs.
If instead 4th arg is passed by value, and modified values is returned,
no problems with allocations arise:
func(*Link, *sym.Reloc, *sym.Symbol, int64) (int64, bool)
There are 2 benefits:
1. code becomes more readable.
2. less allocations.
For linking "hello world" example from net/http:
name old time/op new time/op delta
Linker-4 530ms ± 2% 520ms ± 2% -1.83% (p=0.001 n=17+16)
It's top 1 in alloc_objects from memprofile:
flat flat% sum% cum cum%
229379 33.05% 33.05% 229379 33.05% cmd/link/internal/ld.relocsym
...
list relocsym:
229379 229379 (flat, cum) 33.05% of Total
229379 229379 183: var o int64
After the patch, ~230k of int64 allocs (~ 1.75mb) removed.
Passes toolshash-check (toolstash cmp).
Change-Id: I25504fe27967bcff70c4b7338790f3921d15473d
Reviewed-on: https://go-review.googlesource.com/113637
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-05-17 19:50:29 +03:00
|
|
|
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
|
2017-10-05 10:20:17 -04:00
|
|
|
if ctxt.LinkMode == ld.LinkExternal {
|
2015-02-27 22:57:28 -05:00
|
|
|
switch r.Type {
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_CALLARM:
|
2017-08-27 22:00:00 +09:00
|
|
|
r.Done = false
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// set up addend for eventual relocation via outer symbol.
|
2015-03-02 12:35:15 -05:00
|
|
|
rs := r.Sym
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-09-14 14:47:12 -04:00
|
|
|
r.Xadd = int64(signext24(r.Add & 0xffffff))
|
2015-02-27 22:57:28 -05:00
|
|
|
r.Xadd *= 4
|
|
|
|
|
for rs.Outer != nil {
|
2016-09-17 09:39:33 -04:00
|
|
|
r.Xadd += ld.Symaddr(rs) - ld.Symaddr(rs.Outer)
|
2015-02-27 22:57:28 -05:00
|
|
|
rs = rs.Outer
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-04 17:54:04 -04:00
|
|
|
if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
|
2016-09-17 09:39:33 -04:00
|
|
|
ld.Errorf(s, "missing section for %s", rs.Name)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
r.Xsym = rs
|
|
|
|
|
|
|
|
|
|
// ld64 for arm seems to want the symbol table to contain offset
|
|
|
|
|
// into the section rather than pseudo virtual address that contains
|
|
|
|
|
// the section load address.
|
|
|
|
|
// we need to compensate that by removing the instruction's address
|
|
|
|
|
// from addend.
|
2017-10-07 13:49:44 -04:00
|
|
|
if ctxt.HeadType == objabi.Hdarwin {
|
2016-09-17 09:39:33 -04:00
|
|
|
r.Xadd -= ld.Symaddr(s) + int64(r.Off)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-09-14 14:47:12 -04:00
|
|
|
if r.Xadd/4 > 0x7fffff || r.Xadd/4 < -0x800000 {
|
|
|
|
|
ld.Errorf(s, "direct call too far %d", r.Xadd/4)
|
|
|
|
|
}
|
|
|
|
|
|
cmd/link: fewer allocs in ld.Arch.Archreloc
Archreloc had this signature:
func(*Link, *sym.Reloc, *sym.Symbol, *int64) bool
The last *int64 argument is used as out parameter.
Passed valus could be allocated on stack, but escape analysis
fails here, leading to high number of unwanted allocs.
If instead 4th arg is passed by value, and modified values is returned,
no problems with allocations arise:
func(*Link, *sym.Reloc, *sym.Symbol, int64) (int64, bool)
There are 2 benefits:
1. code becomes more readable.
2. less allocations.
For linking "hello world" example from net/http:
name old time/op new time/op delta
Linker-4 530ms ± 2% 520ms ± 2% -1.83% (p=0.001 n=17+16)
It's top 1 in alloc_objects from memprofile:
flat flat% sum% cum cum%
229379 33.05% 33.05% 229379 33.05% cmd/link/internal/ld.relocsym
...
list relocsym:
229379 229379 (flat, cum) 33.05% of Total
229379 229379 183: var o int64
After the patch, ~230k of int64 allocs (~ 1.75mb) removed.
Passes toolshash-check (toolstash cmp).
Change-Id: I25504fe27967bcff70c4b7338790f3921d15473d
Reviewed-on: https://go-review.googlesource.com/113637
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-05-17 19:50:29 +03:00
|
|
|
return int64(braddoff(int32(0xff000000&uint32(r.Add)), int32(0xffffff&uint32(r.Xadd/4)))), true
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
cmd/link: fewer allocs in ld.Arch.Archreloc
Archreloc had this signature:
func(*Link, *sym.Reloc, *sym.Symbol, *int64) bool
The last *int64 argument is used as out parameter.
Passed valus could be allocated on stack, but escape analysis
fails here, leading to high number of unwanted allocs.
If instead 4th arg is passed by value, and modified values is returned,
no problems with allocations arise:
func(*Link, *sym.Reloc, *sym.Symbol, int64) (int64, bool)
There are 2 benefits:
1. code becomes more readable.
2. less allocations.
For linking "hello world" example from net/http:
name old time/op new time/op delta
Linker-4 530ms ± 2% 520ms ± 2% -1.83% (p=0.001 n=17+16)
It's top 1 in alloc_objects from memprofile:
flat flat% sum% cum cum%
229379 33.05% 33.05% 229379 33.05% cmd/link/internal/ld.relocsym
...
list relocsym:
229379 229379 (flat, cum) 33.05% of Total
229379 229379 183: var o int64
After the patch, ~230k of int64 allocs (~ 1.75mb) removed.
Passes toolshash-check (toolstash cmp).
Change-Id: I25504fe27967bcff70c4b7338790f3921d15473d
Reviewed-on: https://go-review.googlesource.com/113637
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-05-17 19:50:29 +03:00
|
|
|
return -1, false
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch r.Type {
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_CONST:
|
cmd/link: fewer allocs in ld.Arch.Archreloc
Archreloc had this signature:
func(*Link, *sym.Reloc, *sym.Symbol, *int64) bool
The last *int64 argument is used as out parameter.
Passed valus could be allocated on stack, but escape analysis
fails here, leading to high number of unwanted allocs.
If instead 4th arg is passed by value, and modified values is returned,
no problems with allocations arise:
func(*Link, *sym.Reloc, *sym.Symbol, int64) (int64, bool)
There are 2 benefits:
1. code becomes more readable.
2. less allocations.
For linking "hello world" example from net/http:
name old time/op new time/op delta
Linker-4 530ms ± 2% 520ms ± 2% -1.83% (p=0.001 n=17+16)
It's top 1 in alloc_objects from memprofile:
flat flat% sum% cum cum%
229379 33.05% 33.05% 229379 33.05% cmd/link/internal/ld.relocsym
...
list relocsym:
229379 229379 (flat, cum) 33.05% of Total
229379 229379 183: var o int64
After the patch, ~230k of int64 allocs (~ 1.75mb) removed.
Passes toolshash-check (toolstash cmp).
Change-Id: I25504fe27967bcff70c4b7338790f3921d15473d
Reviewed-on: https://go-review.googlesource.com/113637
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-05-17 19:50:29 +03:00
|
|
|
return r.Add, true
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_GOTOFF:
|
cmd/link: fewer allocs in ld.Arch.Archreloc
Archreloc had this signature:
func(*Link, *sym.Reloc, *sym.Symbol, *int64) bool
The last *int64 argument is used as out parameter.
Passed valus could be allocated on stack, but escape analysis
fails here, leading to high number of unwanted allocs.
If instead 4th arg is passed by value, and modified values is returned,
no problems with allocations arise:
func(*Link, *sym.Reloc, *sym.Symbol, int64) (int64, bool)
There are 2 benefits:
1. code becomes more readable.
2. less allocations.
For linking "hello world" example from net/http:
name old time/op new time/op delta
Linker-4 530ms ± 2% 520ms ± 2% -1.83% (p=0.001 n=17+16)
It's top 1 in alloc_objects from memprofile:
flat flat% sum% cum cum%
229379 33.05% 33.05% 229379 33.05% cmd/link/internal/ld.relocsym
...
list relocsym:
229379 229379 (flat, cum) 33.05% of Total
229379 229379 183: var o int64
After the patch, ~230k of int64 allocs (~ 1.75mb) removed.
Passes toolshash-check (toolstash cmp).
Change-Id: I25504fe27967bcff70c4b7338790f3921d15473d
Reviewed-on: https://go-review.googlesource.com/113637
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-05-17 19:50:29 +03:00
|
|
|
return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-09-24 21:38:58 +02:00
|
|
|
// The following three arch specific relocations are only for generation of
|
2015-02-27 22:57:28 -05:00
|
|
|
// Linux/ARM ELF's PLT entry (3 assembler instruction)
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_PLT0: // add ip, pc, #0xXX00000
|
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
|
|
|
if ld.Symaddr(ctxt.Syms.Lookup(".got.plt", 0)) < ld.Symaddr(ctxt.Syms.Lookup(".plt", 0)) {
|
2016-09-17 09:39:33 -04:00
|
|
|
ld.Errorf(s, ".got.plt should be placed after .plt section.")
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
cmd/link: fewer allocs in ld.Arch.Archreloc
Archreloc had this signature:
func(*Link, *sym.Reloc, *sym.Symbol, *int64) bool
The last *int64 argument is used as out parameter.
Passed valus could be allocated on stack, but escape analysis
fails here, leading to high number of unwanted allocs.
If instead 4th arg is passed by value, and modified values is returned,
no problems with allocations arise:
func(*Link, *sym.Reloc, *sym.Symbol, int64) (int64, bool)
There are 2 benefits:
1. code becomes more readable.
2. less allocations.
For linking "hello world" example from net/http:
name old time/op new time/op delta
Linker-4 530ms ± 2% 520ms ± 2% -1.83% (p=0.001 n=17+16)
It's top 1 in alloc_objects from memprofile:
flat flat% sum% cum cum%
229379 33.05% 33.05% 229379 33.05% cmd/link/internal/ld.relocsym
...
list relocsym:
229379 229379 (flat, cum) 33.05% of Total
229379 229379 183: var o int64
After the patch, ~230k of int64 allocs (~ 1.75mb) removed.
Passes toolshash-check (toolstash cmp).
Change-Id: I25504fe27967bcff70c4b7338790f3921d15473d
Reviewed-on: https://go-review.googlesource.com/113637
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-05-17 19:50:29 +03:00
|
|
|
return 0xe28fc600 + (0xff & (int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ctxt.Syms.Lookup(".plt", 0))+int64(r.Off))+r.Add)) >> 20)), true
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_PLT1: // add ip, ip, #0xYY000
|
cmd/link: fewer allocs in ld.Arch.Archreloc
Archreloc had this signature:
func(*Link, *sym.Reloc, *sym.Symbol, *int64) bool
The last *int64 argument is used as out parameter.
Passed valus could be allocated on stack, but escape analysis
fails here, leading to high number of unwanted allocs.
If instead 4th arg is passed by value, and modified values is returned,
no problems with allocations arise:
func(*Link, *sym.Reloc, *sym.Symbol, int64) (int64, bool)
There are 2 benefits:
1. code becomes more readable.
2. less allocations.
For linking "hello world" example from net/http:
name old time/op new time/op delta
Linker-4 530ms ± 2% 520ms ± 2% -1.83% (p=0.001 n=17+16)
It's top 1 in alloc_objects from memprofile:
flat flat% sum% cum cum%
229379 33.05% 33.05% 229379 33.05% cmd/link/internal/ld.relocsym
...
list relocsym:
229379 229379 (flat, cum) 33.05% of Total
229379 229379 183: var o int64
After the patch, ~230k of int64 allocs (~ 1.75mb) removed.
Passes toolshash-check (toolstash cmp).
Change-Id: I25504fe27967bcff70c4b7338790f3921d15473d
Reviewed-on: https://go-review.googlesource.com/113637
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-05-17 19:50:29 +03:00
|
|
|
return 0xe28cca00 + (0xff & (int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ctxt.Syms.Lookup(".plt", 0))+int64(r.Off))+r.Add+4)) >> 12)), true
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_PLT2: // ldr pc, [ip, #0xZZZ]!
|
cmd/link: fewer allocs in ld.Arch.Archreloc
Archreloc had this signature:
func(*Link, *sym.Reloc, *sym.Symbol, *int64) bool
The last *int64 argument is used as out parameter.
Passed valus could be allocated on stack, but escape analysis
fails here, leading to high number of unwanted allocs.
If instead 4th arg is passed by value, and modified values is returned,
no problems with allocations arise:
func(*Link, *sym.Reloc, *sym.Symbol, int64) (int64, bool)
There are 2 benefits:
1. code becomes more readable.
2. less allocations.
For linking "hello world" example from net/http:
name old time/op new time/op delta
Linker-4 530ms ± 2% 520ms ± 2% -1.83% (p=0.001 n=17+16)
It's top 1 in alloc_objects from memprofile:
flat flat% sum% cum cum%
229379 33.05% 33.05% 229379 33.05% cmd/link/internal/ld.relocsym
...
list relocsym:
229379 229379 (flat, cum) 33.05% of Total
229379 229379 183: var o int64
After the patch, ~230k of int64 allocs (~ 1.75mb) removed.
Passes toolshash-check (toolstash cmp).
Change-Id: I25504fe27967bcff70c4b7338790f3921d15473d
Reviewed-on: https://go-review.googlesource.com/113637
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-05-17 19:50:29 +03:00
|
|
|
return 0xe5bcf000 + (0xfff & int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ctxt.Syms.Lookup(".plt", 0))+int64(r.Off))+r.Add+8))), true
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_CALLARM: // bl XXXXXX or b YYYYYY
|
2016-09-14 14:47:12 -04:00
|
|
|
// r.Add is the instruction
|
|
|
|
|
// low 24-bit encodes the target address
|
|
|
|
|
t := (ld.Symaddr(r.Sym) + int64(signext24(r.Add&0xffffff)*4) - (s.Value + int64(r.Off))) / 4
|
|
|
|
|
if t > 0x7fffff || t < -0x800000 {
|
|
|
|
|
ld.Errorf(s, "direct call too far: %s %x", r.Sym.Name, t)
|
|
|
|
|
}
|
cmd/link: fewer allocs in ld.Arch.Archreloc
Archreloc had this signature:
func(*Link, *sym.Reloc, *sym.Symbol, *int64) bool
The last *int64 argument is used as out parameter.
Passed valus could be allocated on stack, but escape analysis
fails here, leading to high number of unwanted allocs.
If instead 4th arg is passed by value, and modified values is returned,
no problems with allocations arise:
func(*Link, *sym.Reloc, *sym.Symbol, int64) (int64, bool)
There are 2 benefits:
1. code becomes more readable.
2. less allocations.
For linking "hello world" example from net/http:
name old time/op new time/op delta
Linker-4 530ms ± 2% 520ms ± 2% -1.83% (p=0.001 n=17+16)
It's top 1 in alloc_objects from memprofile:
flat flat% sum% cum cum%
229379 33.05% 33.05% 229379 33.05% cmd/link/internal/ld.relocsym
...
list relocsym:
229379 229379 (flat, cum) 33.05% of Total
229379 229379 183: var o int64
After the patch, ~230k of int64 allocs (~ 1.75mb) removed.
Passes toolshash-check (toolstash cmp).
Change-Id: I25504fe27967bcff70c4b7338790f3921d15473d
Reviewed-on: https://go-review.googlesource.com/113637
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-05-17 19:50:29 +03:00
|
|
|
return int64(braddoff(int32(0xff000000&uint32(r.Add)), int32(0xffffff&t))), true
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
cmd/link: fewer allocs in ld.Arch.Archreloc
Archreloc had this signature:
func(*Link, *sym.Reloc, *sym.Symbol, *int64) bool
The last *int64 argument is used as out parameter.
Passed valus could be allocated on stack, but escape analysis
fails here, leading to high number of unwanted allocs.
If instead 4th arg is passed by value, and modified values is returned,
no problems with allocations arise:
func(*Link, *sym.Reloc, *sym.Symbol, int64) (int64, bool)
There are 2 benefits:
1. code becomes more readable.
2. less allocations.
For linking "hello world" example from net/http:
name old time/op new time/op delta
Linker-4 530ms ± 2% 520ms ± 2% -1.83% (p=0.001 n=17+16)
It's top 1 in alloc_objects from memprofile:
flat flat% sum% cum cum%
229379 33.05% 33.05% 229379 33.05% cmd/link/internal/ld.relocsym
...
list relocsym:
229379 229379 (flat, cum) 33.05% of Total
229379 229379 183: var o int64
After the patch, ~230k of int64 allocs (~ 1.75mb) removed.
Passes toolshash-check (toolstash cmp).
Change-Id: I25504fe27967bcff70c4b7338790f3921d15473d
Reviewed-on: https://go-review.googlesource.com/113637
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-05-17 19:50:29 +03:00
|
|
|
return val, 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
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-03 15:52:30 +01:00
|
|
|
func addpltreloc(ctxt *ld.Link, plt *sym.Symbol, got *sym.Symbol, s *sym.Symbol, typ objabi.RelocType) {
|
2017-09-30 15:06:44 +00:00
|
|
|
r := plt.AddRel()
|
2015-02-27 22:57:28 -05:00
|
|
|
r.Sym = got
|
|
|
|
|
r.Off = int32(plt.Size)
|
|
|
|
|
r.Siz = 4
|
2016-07-02 17:19:25 -07:00
|
|
|
r.Type = typ
|
2017-10-04 17:54:04 -04:00
|
|
|
r.Add = int64(s.Got) - 8
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-10-04 17:54:04 -04:00
|
|
|
plt.Attr |= sym.AttrReachable
|
2015-02-27 22:57:28 -05:00
|
|
|
plt.Size += 4
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.Grow(plt.Size)
|
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
|
|
|
|
2017-10-07 13:43:38 -04:00
|
|
|
if ctxt.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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// .got entry
|
|
|
|
|
s.Got = int32(got.Size)
|
|
|
|
|
|
|
|
|
|
// In theory, all GOT should point to the first PLT entry,
|
|
|
|
|
// Linux/ARM's dynamic linker will do that for us, but FreeBSD/ARM's
|
|
|
|
|
// dynamic linker won't, so we'd better do it ourselves.
|
2017-09-30 15:06:44 +00:00
|
|
|
got.AddAddrPlus(ctxt.Arch, plt, 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// .plt entry, this depends on the .got entry
|
|
|
|
|
s.Plt = int32(plt.Size)
|
|
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
addpltreloc(ctxt, plt, got, s, objabi.R_PLT0) // add lr, pc, #0xXX00000
|
|
|
|
|
addpltreloc(ctxt, plt, got, s, objabi.R_PLT1) // add lr, lr, #0xYY000
|
|
|
|
|
addpltreloc(ctxt, plt, got, s, objabi.R_PLT2) // ldr pc, [lr, #0xZZZ]!
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// rel
|
2017-09-30 15:06:44 +00:00
|
|
|
rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got))
|
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_ARM_JUMP_SLOT)))
|
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 addgotsyminternal(ctxt *ld.Link, s *sym.Symbol) {
|
2015-02-27 22:57:28 -05:00
|
|
|
if s.Got >= 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
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.AddAddrPlus(ctxt.Arch, s, 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-10-07 13:43:38 -04:00
|
|
|
if ctxt.IsELF {
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
2016-09-17 09:39:33 -04:00
|
|
|
ld.Errorf(s, "addgotsyminternal: 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
|
|
|
|
2017-10-07 13:43:38 -04:00
|
|
|
if ctxt.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_ARM_GLOB_DAT)))
|
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
|
|
|
}
|
|
|
|
|
|
2017-10-07 13:43:38 -04:00
|
|
|
if ctxt.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-08-19 22:40:38 -04:00
|
|
|
ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
|
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-10-07 13:49:44 -04:00
|
|
|
if ctxt.HeadType == objabi.Hdarwin {
|
2016-08-19 22:40:38 -04:00
|
|
|
machlink = uint32(ld.Domacholink(ctxt))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* output symbol table */
|
|
|
|
|
ld.Symsize = 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
|
|
|
}
|
2017-10-07 13:49:44 -04:00
|
|
|
switch ctxt.HeadType {
|
2015-02-27 22:57:28 -05:00
|
|
|
default:
|
2017-10-07 13:43:38 -04:00
|
|
|
if ctxt.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-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.SeekSet(int64(symo))
|
2017-10-07 13:49:44 -04:00
|
|
|
switch ctxt.HeadType {
|
2015-02-27 22:57:28 -05:00
|
|
|
default:
|
2017-10-07 13:43:38 -04:00
|
|
|
if ctxt.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.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 header\n", ld.Cputime())
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.SeekSet(0)
|
2017-10-07 13:49:44 -04:00
|
|
|
switch ctxt.HeadType {
|
2015-02-27 22:57:28 -05:00
|
|
|
default:
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hplan9: /* plan 9 */
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.Write32b(0x647) /* 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(0)
|
|
|
|
|
ctxt.Out.Write32b(uint32(ld.Lcsize))
|
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.Hdarwin:
|
2016-08-19 22:40:38 -04:00
|
|
|
ld.Asmbmacho(ctxt)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.Flush()
|
2016-08-21 18:34:24 -04:00
|
|
|
if *ld.FlagC {
|
2015-02-27 22:57:28 -05:00
|
|
|
fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
|
|
|
|
|
fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
|
|
|
|
|
fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen)
|
|
|
|
|
fmt.Printf("symsize=%d\n", ld.Symsize)
|
|
|
|
|
fmt.Printf("lcsize=%d\n", ld.Lcsize)
|
|
|
|
|
fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize))
|
|
|
|
|
}
|
|
|
|
|
}
|