[dev.link] cmd/link: add Target to relocation functions

We need to propogate Target through the relocation functions.

Change-Id: I1192d54a20a34569fd13c1511d2b21ebf2d1272e
Reviewed-on: https://go-review.googlesource.com/c/go/+/220839
Run-TryBot: Jeremy Faller <jeremy@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Jeremy Faller 2020-02-24 21:04:50 -05:00
parent b7d5346889
commit b9642cbb8d
12 changed files with 80 additions and 64 deletions

View file

@ -563,11 +563,11 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, secto
return true return true
} }
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) { func archreloc(ctxt *ld.Link, target *ld.Target, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
return val, false return val, false
} }
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { func archrelocvariant(ctxt *ld.Link, target *ld.Target, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
log.Fatalf("unexpected relocation variant") log.Fatalf("unexpected relocation variant")
return t return t
} }

View file

@ -597,8 +597,8 @@ func gentrampdyn(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) {
} }
} }
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) { func archreloc(ctxt *ld.Link, target *ld.Target, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
if ctxt.LinkMode == ld.LinkExternal { if target.IsExternal() {
switch r.Type { switch r.Type {
case objabi.R_CALLARM: case objabi.R_CALLARM:
r.Done = false r.Done = false
@ -623,7 +623,7 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
// the section load address. // the section load address.
// we need to compensate that by removing the instruction's address // we need to compensate that by removing the instruction's address
// from addend. // from addend.
if ctxt.HeadType == objabi.Hdarwin { if target.IsDarwin() {
r.Xadd -= ld.Symaddr(s) + int64(r.Off) r.Xadd -= ld.Symaddr(s) + int64(r.Off)
} }
@ -667,7 +667,7 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
return val, false return val, false
} }
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { func archrelocvariant(ctxt *ld.Link, target *ld.Target, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
log.Fatalf("unexpected relocation variant") log.Fatalf("unexpected relocation variant")
return t return t
} }

View file

@ -36,7 +36,6 @@ import (
"cmd/link/internal/ld" "cmd/link/internal/ld"
"cmd/link/internal/sym" "cmd/link/internal/sym"
"debug/elf" "debug/elf"
"encoding/binary"
"fmt" "fmt"
"log" "log"
) )
@ -434,14 +433,14 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se
return true return true
} }
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) { func archreloc(ctxt *ld.Link, target *ld.Target, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
if ctxt.LinkMode == ld.LinkExternal { if target.IsExternal() {
switch r.Type { switch r.Type {
default: default:
return val, false return val, false
case objabi.R_ARM64_GOTPCREL: case objabi.R_ARM64_GOTPCREL:
var o1, o2 uint32 var o1, o2 uint32
if ctxt.Arch.ByteOrder == binary.BigEndian { if target.IsBigEndian() {
o1 = uint32(val >> 32) o1 = uint32(val >> 32)
o2 = uint32(val) o2 = uint32(val)
} else { } else {
@ -456,14 +455,14 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
// (https://sourceware.org/bugzilla/show_bug.cgi?id=18270). So // (https://sourceware.org/bugzilla/show_bug.cgi?id=18270). So
// we convert the adrp; ld64 + R_ARM64_GOTPCREL into adrp; // we convert the adrp; ld64 + R_ARM64_GOTPCREL into adrp;
// add + R_ADDRARM64. // add + R_ADDRARM64.
if !(r.Sym.IsFileLocal() || r.Sym.Attr.VisibilityHidden() || r.Sym.Attr.Local()) && r.Sym.Type == sym.STEXT && ctxt.DynlinkingGo() { if !(r.Sym.IsFileLocal() || r.Sym.Attr.VisibilityHidden() || r.Sym.Attr.Local()) && r.Sym.Type == sym.STEXT && target.IsDynlinkingGo() {
if o2&0xffc00000 != 0xf9400000 { if o2&0xffc00000 != 0xf9400000 {
ld.Errorf(s, "R_ARM64_GOTPCREL against unexpected instruction %x", o2) ld.Errorf(s, "R_ARM64_GOTPCREL against unexpected instruction %x", o2)
} }
o2 = 0x91000000 | (o2 & 0x000003ff) o2 = 0x91000000 | (o2 & 0x000003ff)
r.Type = objabi.R_ADDRARM64 r.Type = objabi.R_ADDRARM64
} }
if ctxt.Arch.ByteOrder == binary.BigEndian { if target.IsBigEndian() {
val = int64(o1)<<32 | int64(o2) val = int64(o1)<<32 | int64(o2)
} else { } else {
val = int64(o2)<<32 | int64(o1) val = int64(o2)<<32 | int64(o1)
@ -490,10 +489,10 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
// the BR26 relocation should be fully resolved at link time. // the BR26 relocation should be fully resolved at link time.
// That is the reason why the next if block is disabled. When the bug in ld64 // That is the reason why the next if block is disabled. When the bug in ld64
// is fixed, we can enable this block and also enable duff's device in cmd/7g. // is fixed, we can enable this block and also enable duff's device in cmd/7g.
if false && ctxt.HeadType == objabi.Hdarwin { if false && target.IsDarwin() {
var o0, o1 uint32 var o0, o1 uint32
if ctxt.Arch.ByteOrder == binary.BigEndian { if target.IsBigEndian() {
o0 = uint32(val >> 32) o0 = uint32(val >> 32)
o1 = uint32(val) o1 = uint32(val)
} else { } else {
@ -510,7 +509,7 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
r.Xadd = 0 r.Xadd = 0
// when laid out, the instruction order must always be o1, o2. // when laid out, the instruction order must always be o1, o2.
if ctxt.Arch.ByteOrder == binary.BigEndian { if target.IsBigEndian() {
val = int64(o0)<<32 | int64(o1) val = int64(o0)<<32 | int64(o1)
} else { } else {
val = int64(o1)<<32 | int64(o0) val = int64(o1)<<32 | int64(o0)
@ -543,7 +542,7 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
var o0, o1 uint32 var o0, o1 uint32
if ctxt.Arch.ByteOrder == binary.BigEndian { if target.IsBigEndian() {
o0 = uint32(val >> 32) o0 = uint32(val >> 32)
o1 = uint32(val) o1 = uint32(val)
} else { } else {
@ -555,42 +554,42 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
o1 |= uint32(t&0xfff) << 10 o1 |= uint32(t&0xfff) << 10
// when laid out, the instruction order must always be o1, o2. // when laid out, the instruction order must always be o1, o2.
if ctxt.Arch.ByteOrder == binary.BigEndian { if target.IsBigEndian() {
return int64(o0)<<32 | int64(o1), true return int64(o0)<<32 | int64(o1), true
} }
return int64(o1)<<32 | int64(o0), true return int64(o1)<<32 | int64(o0), true
case objabi.R_ARM64_TLS_LE: case objabi.R_ARM64_TLS_LE:
r.Done = false r.Done = false
if ctxt.HeadType == objabi.Hdarwin { if target.IsDarwin() {
ld.Errorf(s, "TLS reloc on unsupported OS %v", ctxt.HeadType) ld.Errorf(s, "TLS reloc on unsupported OS %v", target.HeadType)
} }
// The TCB is two pointers. This is not documented anywhere, but is // The TCB is two pointers. This is not documented anywhere, but is
// de facto part of the ABI. // de facto part of the ABI.
v := r.Sym.Value + int64(2*ctxt.Arch.PtrSize) v := r.Sym.Value + int64(2*target.Arch.PtrSize)
if v < 0 || v >= 32678 { if v < 0 || v >= 32678 {
ld.Errorf(s, "TLS offset out of range %d", v) ld.Errorf(s, "TLS offset out of range %d", v)
} }
return val | (v << 5), true return val | (v << 5), true
case objabi.R_ARM64_TLS_IE: case objabi.R_ARM64_TLS_IE:
if ctxt.BuildMode == ld.BuildModePIE && ctxt.IsELF { if target.IsPIE() && target.IsElf() {
// We are linking the final executable, so we // We are linking the final executable, so we
// can optimize any TLS IE relocation to LE. // can optimize any TLS IE relocation to LE.
r.Done = false r.Done = false
if ctxt.HeadType != objabi.Hlinux { if !target.IsLinux() {
ld.Errorf(s, "TLS reloc on unsupported OS %v", ctxt.HeadType) ld.Errorf(s, "TLS reloc on unsupported OS %v", target.HeadType)
} }
// The TCB is two pointers. This is not documented anywhere, but is // The TCB is two pointers. This is not documented anywhere, but is
// de facto part of the ABI. // de facto part of the ABI.
v := ld.Symaddr(r.Sym) + int64(2*ctxt.Arch.PtrSize) + r.Add v := ld.Symaddr(r.Sym) + int64(2*target.Arch.PtrSize) + r.Add
if v < 0 || v >= 32678 { if v < 0 || v >= 32678 {
ld.Errorf(s, "TLS offset out of range %d", v) ld.Errorf(s, "TLS offset out of range %d", v)
} }
var o0, o1 uint32 var o0, o1 uint32
if ctxt.Arch.ByteOrder == binary.BigEndian { if target.IsBigEndian() {
o0 = uint32(val >> 32) o0 = uint32(val >> 32)
o1 = uint32(val) o1 = uint32(val)
} else { } else {
@ -609,7 +608,7 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
o1 = 0xf2800000 | uint32(o1&0x1f) | (uint32(v&0xffff) << 5) o1 = 0xf2800000 | uint32(o1&0x1f) | (uint32(v&0xffff) << 5)
// when laid out, the instruction order must always be o0, o1. // when laid out, the instruction order must always be o0, o1.
if ctxt.Arch.ByteOrder == binary.BigEndian { if target.IsBigEndian() {
return int64(o0)<<32 | int64(o1), true return int64(o0)<<32 | int64(o1), true
} }
return int64(o1)<<32 | int64(o0), true return int64(o1)<<32 | int64(o0), true
@ -707,7 +706,7 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
return val, false return val, false
} }
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { func archrelocvariant(ctxt *ld.Link, target *ld.Target, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
log.Fatalf("unexpected relocation variant") log.Fatalf("unexpected relocation variant")
return -1 return -1
} }

View file

@ -222,7 +222,7 @@ func relocsym(ctxt *Link, target *Target, s *sym.Symbol) {
case 8: case 8:
o = int64(target.Arch.ByteOrder.Uint64(s.P[off:])) o = int64(target.Arch.ByteOrder.Uint64(s.P[off:]))
} }
if offset, ok := thearch.Archreloc(ctxt, r, s, o); ok { if offset, ok := thearch.Archreloc(ctxt, target, r, s, o); ok {
o = offset o = offset
} else { } else {
Errorf(s, "unknown reloc to %v: %d (%s)", r.Sym.Name, r.Type, sym.RelocName(target.Arch, r.Type)) Errorf(s, "unknown reloc to %v: %d (%s)", r.Sym.Name, r.Type, sym.RelocName(target.Arch, r.Type))
@ -520,7 +520,7 @@ func relocsym(ctxt *Link, target *Target, s *sym.Symbol) {
if target.IsPPC64() || target.IsS390X() { if target.IsPPC64() || target.IsS390X() {
r.InitExt() r.InitExt()
if r.Variant != sym.RV_NONE { if r.Variant != sym.RV_NONE {
o = thearch.Archrelocvariant(ctxt, r, s, o) o = thearch.Archrelocvariant(ctxt, target, r, s, o)
} }
} }

View file

@ -118,7 +118,7 @@ type Arch struct {
// value is the appropriately relocated value (to be written back // value is the appropriately relocated value (to be written back
// to the same spot in sym.P) and a boolean indicating // to the same spot in sym.P) and a boolean indicating
// success/failure (a failing value indicates a fatal error). // success/failure (a failing value indicates a fatal error).
Archreloc func(link *Link, rel *sym.Reloc, sym *sym.Symbol, Archreloc func(link *Link, target *Target, rel *sym.Reloc, sym *sym.Symbol,
offset int64) (relocatedOffset int64, success bool) offset int64) (relocatedOffset int64, success bool)
// Archrelocvariant is a second arch-specific hook used for // Archrelocvariant is a second arch-specific hook used for
// relocation processing; it handles relocations where r.Type is // relocation processing; it handles relocations where r.Type is
@ -128,7 +128,7 @@ type Arch struct {
// relocation applies, and "off" is the contents of the // relocation applies, and "off" is the contents of the
// to-be-relocated data item (from sym.P). Return is an updated // to-be-relocated data item (from sym.P). Return is an updated
// offset value. // offset value.
Archrelocvariant func(link *Link, rel *sym.Reloc, sym *sym.Symbol, Archrelocvariant func(link *Link, target *Target, rel *sym.Reloc, sym *sym.Symbol,
offset int64) (relocatedOffset int64) offset int64) (relocatedOffset int64)
Trampoline func(*Link, *sym.Reloc, *sym.Symbol) Trampoline func(*Link, *sym.Reloc, *sym.Symbol)

View file

@ -7,6 +7,7 @@ package ld
import ( import (
"cmd/internal/objabi" "cmd/internal/objabi"
"cmd/internal/sys" "cmd/internal/sys"
"encoding/binary"
) )
// Target holds the configuration we're building for. // Target holds the configuration we're building for.
@ -35,6 +36,10 @@ func (t *Target) IsPlugin() bool {
return t.BuildMode == BuildModePlugin return t.BuildMode == BuildModePlugin
} }
func (t *Target) IsInternal() bool {
return t.LinkMode == LinkInternal
}
func (t *Target) IsExternal() bool { func (t *Target) IsExternal() bool {
return t.LinkMode == LinkExternal return t.LinkMode == LinkExternal
} }
@ -83,6 +88,10 @@ func (t *Target) IsS390X() bool {
// OS Functions // OS Functions
// //
func (t *Target) IsLinux() bool {
return t.HeadType == objabi.Hlinux
}
func (t *Target) IsDarwin() bool { func (t *Target) IsDarwin() bool {
return t.HeadType == objabi.Hdarwin return t.HeadType == objabi.Hdarwin
} }
@ -102,3 +111,11 @@ func (t *Target) IsAIX() bool {
func (t *Target) IsSolaris() bool { func (t *Target) IsSolaris() bool {
return t.HeadType == objabi.Hsolaris return t.HeadType == objabi.Hsolaris
} }
//
// MISC
//
func (t *Target) IsBigEndian() bool {
return t.Arch.ByteOrder == binary.BigEndian
}

View file

@ -96,8 +96,8 @@ func applyrel(arch *sys.Arch, r *sym.Reloc, s *sym.Symbol, val int64, t int64) i
} }
} }
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) { func archreloc(ctxt *ld.Link, target *ld.Target, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
if ctxt.LinkMode == ld.LinkExternal { if target.IsExternal() {
switch r.Type { switch r.Type {
default: default:
return val, false return val, false
@ -116,12 +116,12 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
ld.Errorf(s, "missing section for %s", rs.Name) ld.Errorf(s, "missing section for %s", rs.Name)
} }
r.Xsym = rs r.Xsym = rs
return applyrel(ctxt.Arch, r, s, val, r.Xadd), true return applyrel(target.Arch, r, s, val, r.Xadd), true
case objabi.R_ADDRMIPSTLS, objabi.R_CALLMIPS, objabi.R_JMPMIPS: case objabi.R_ADDRMIPSTLS, objabi.R_CALLMIPS, objabi.R_JMPMIPS:
r.Done = false r.Done = false
r.Xsym = r.Sym r.Xsym = r.Sym
r.Xadd = r.Add r.Xadd = r.Add
return applyrel(ctxt.Arch, r, s, val, r.Add), true return applyrel(target.Arch, r, s, val, r.Add), true
} }
} }
@ -132,7 +132,7 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSU: case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSU:
t := ld.Symaddr(r.Sym) + r.Add t := ld.Symaddr(r.Sym) + r.Add
return applyrel(ctxt.Arch, r, s, val, t), true return applyrel(target.Arch, r, s, val, t), true
case objabi.R_CALLMIPS, objabi.R_JMPMIPS: case objabi.R_CALLMIPS, objabi.R_JMPMIPS:
t := ld.Symaddr(r.Sym) + r.Add t := ld.Symaddr(r.Sym) + r.Add
@ -145,20 +145,20 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
ld.Errorf(s, "direct call too far: %s %x", r.Sym.Name, t) ld.Errorf(s, "direct call too far: %s %x", r.Sym.Name, t)
} }
return applyrel(ctxt.Arch, r, s, val, t), true return applyrel(target.Arch, r, s, val, t), true
case objabi.R_ADDRMIPSTLS: case objabi.R_ADDRMIPSTLS:
// thread pointer is at 0x7000 offset from the start of TLS data area // thread pointer is at 0x7000 offset from the start of TLS data area
t := ld.Symaddr(r.Sym) + r.Add - 0x7000 t := ld.Symaddr(r.Sym) + r.Add - 0x7000
if t < -32768 || t >= 32678 { if t < -32768 || t >= 32678 {
ld.Errorf(s, "TLS offset out of range %d", t) ld.Errorf(s, "TLS offset out of range %d", t)
} }
return applyrel(ctxt.Arch, r, s, val, t), true return applyrel(target.Arch, r, s, val, t), true
} }
return val, false return val, false
} }
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { func archrelocvariant(ctxt *ld.Link, target *ld.Target, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
return -1 return -1
} }

View file

@ -99,8 +99,8 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se
return false return false
} }
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) { func archreloc(ctxt *ld.Link, target *ld.Target, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
if ctxt.LinkMode == ld.LinkExternal { if target.IsExternal() {
switch r.Type { switch r.Type {
default: default:
return val, false return val, false
@ -140,7 +140,7 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
case objabi.R_ADDRMIPS, case objabi.R_ADDRMIPS,
objabi.R_ADDRMIPSU: objabi.R_ADDRMIPSU:
t := ld.Symaddr(r.Sym) + r.Add t := ld.Symaddr(r.Sym) + r.Add
o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:]) o1 := target.Arch.ByteOrder.Uint32(s.P[r.Off:])
if r.Type == objabi.R_ADDRMIPS { if r.Type == objabi.R_ADDRMIPS {
return int64(o1&0xffff0000 | uint32(t)&0xffff), true return int64(o1&0xffff0000 | uint32(t)&0xffff), true
} }
@ -151,20 +151,20 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
if t < -32768 || t >= 32678 { if t < -32768 || t >= 32678 {
ld.Errorf(s, "TLS offset out of range %d", t) ld.Errorf(s, "TLS offset out of range %d", t)
} }
o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:]) o1 := target.Arch.ByteOrder.Uint32(s.P[r.Off:])
return int64(o1&0xffff0000 | uint32(t)&0xffff), true return int64(o1&0xffff0000 | uint32(t)&0xffff), true
case objabi.R_CALLMIPS, case objabi.R_CALLMIPS,
objabi.R_JMPMIPS: objabi.R_JMPMIPS:
// Low 26 bits = (S + A) >> 2 // Low 26 bits = (S + A) >> 2
t := ld.Symaddr(r.Sym) + r.Add t := ld.Symaddr(r.Sym) + r.Add
o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:]) o1 := target.Arch.ByteOrder.Uint32(s.P[r.Off:])
return int64(o1&0xfc000000 | uint32(t>>2)&^0xfc000000), true return int64(o1&0xfc000000 | uint32(t>>2)&^0xfc000000), true
} }
return val, false return val, false
} }
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { func archrelocvariant(ctxt *ld.Link, target *ld.Target, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
return -1 return -1
} }

View file

@ -536,8 +536,8 @@ func symtoc(ctxt *ld.Link, s *sym.Symbol) int64 {
// default load instruction can be changed to an addi instruction and the // default load instruction can be changed to an addi instruction and the
// symbol address can be used directly. // symbol address can be used directly.
// This code is for AIX only. // This code is for AIX only.
func archreloctoc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) int64 { func archreloctoc(ctxt *ld.Link, target *ld.Target, r *sym.Reloc, s *sym.Symbol, val int64) int64 {
if ctxt.HeadType == objabi.Hlinux { if target.IsLinux() {
ld.Errorf(s, "archrelocaddr called for %s relocation\n", r.Sym.Name) ld.Errorf(s, "archrelocaddr called for %s relocation\n", r.Sym.Name)
} }
var o1, o2 uint32 var o1, o2 uint32
@ -555,7 +555,7 @@ func archreloctoc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) int64 {
ld.Errorf(s, "archreloctoc called for a symbol without TOC anchor") ld.Errorf(s, "archreloctoc called for a symbol without TOC anchor")
} }
if ctxt.LinkMode == ld.LinkInternal && tarSym != nil && tarSym.Attr.Reachable() && (tarSym.Sect.Seg == &ld.Segdata) { if target.IsInternal() && tarSym != nil && tarSym.Attr.Reachable() && (tarSym.Sect.Seg == &ld.Segdata) {
t = ld.Symaddr(tarSym) + r.Add - ctxt.Syms.ROLookup("TOC", 0).Value t = ld.Symaddr(tarSym) + r.Add - ctxt.Syms.ROLookup("TOC", 0).Value
// change ld to addi in the second instruction // change ld to addi in the second instruction
o2 = (o2 & 0x03FF0000) | 0xE<<26 o2 = (o2 & 0x03FF0000) | 0xE<<26
@ -593,12 +593,12 @@ func archreloctoc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) int64 {
// archrelocaddr relocates a symbol address. // archrelocaddr relocates a symbol address.
// This code is for AIX only. // This code is for AIX only.
func archrelocaddr(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) int64 { func archrelocaddr(ctxt *ld.Link, target *ld.Target, r *sym.Reloc, s *sym.Symbol, val int64) int64 {
if ctxt.HeadType == objabi.Haix { if target.IsAIX() {
ld.Errorf(s, "archrelocaddr called for %s relocation\n", r.Sym.Name) ld.Errorf(s, "archrelocaddr called for %s relocation\n", r.Sym.Name)
} }
var o1, o2 uint32 var o1, o2 uint32
if ctxt.Arch.ByteOrder == binary.BigEndian { if target.IsBigEndian() {
o1 = uint32(val >> 32) o1 = uint32(val >> 32)
o2 = uint32(val) o2 = uint32(val)
} else { } else {
@ -635,7 +635,7 @@ func archrelocaddr(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) int64
return -1 return -1
} }
if ctxt.Arch.ByteOrder == binary.BigEndian { if target.IsBigEndian() {
return int64(o1)<<32 | int64(o2) return int64(o1)<<32 | int64(o2)
} }
return int64(o2)<<32 | int64(o1) return int64(o2)<<32 | int64(o1)
@ -770,7 +770,7 @@ func gentramp(ctxt *ld.Link, tramp, target *sym.Symbol, offset int64) {
ctxt.Arch.ByteOrder.PutUint32(tramp.P[12:], o4) ctxt.Arch.ByteOrder.PutUint32(tramp.P[12:], o4)
} }
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) { func archreloc(ctxt *ld.Link, target *ld.Target, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
if ctxt.LinkMode == ld.LinkExternal { if ctxt.LinkMode == ld.LinkExternal {
// On AIX, relocations (except TLS ones) must be also done to the // On AIX, relocations (except TLS ones) must be also done to the
// value with the current addresses. // value with the current addresses.
@ -825,9 +825,9 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
case objabi.R_GOTOFF: case objabi.R_GOTOFF:
return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
case objabi.R_ADDRPOWER_TOCREL, objabi.R_ADDRPOWER_TOCREL_DS: case objabi.R_ADDRPOWER_TOCREL, objabi.R_ADDRPOWER_TOCREL_DS:
return archreloctoc(ctxt, r, s, val), true return archreloctoc(ctxt, &ctxt.Target, r, s, val), true
case objabi.R_ADDRPOWER, objabi.R_ADDRPOWER_DS: case objabi.R_ADDRPOWER, objabi.R_ADDRPOWER_DS:
return archrelocaddr(ctxt, r, s, val), true return archrelocaddr(ctxt, target, r, s, val), true
case objabi.R_CALLPOWER: case objabi.R_CALLPOWER:
// Bits 6 through 29 = (S + A - P) >> 2 // Bits 6 through 29 = (S + A - P) >> 2
@ -865,7 +865,7 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
return val, false return val, false
} }
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { func archrelocvariant(ctxt *ld.Link, taget *ld.Target, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
switch r.Variant & sym.RV_TYPE_MASK { switch r.Variant & sym.RV_TYPE_MASK {
default: default:
ld.Errorf(s, "unexpected relocation variant %d", r.Variant) ld.Errorf(s, "unexpected relocation variant %d", r.Variant)

View file

@ -40,7 +40,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se
return false return false
} }
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) { func archreloc(ctxt *ld.Link, target *ld.Target, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
switch r.Type { switch r.Type {
case objabi.R_CALLRISCV: case objabi.R_CALLRISCV:
// Nothing to do. // Nothing to do.
@ -91,7 +91,7 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
return val, false return val, false
} }
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { func archrelocvariant(ctxt *ld.Link, target *ld.Target, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
log.Fatalf("archrelocvariant") log.Fatalf("archrelocvariant")
return -1 return -1
} }

View file

@ -387,8 +387,8 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se
return false return false
} }
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) { func archreloc(ctxt *ld.Link, target *ld.Target, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
if ctxt.LinkMode == ld.LinkExternal { if target.IsExternal() {
return val, false return val, false
} }
@ -402,7 +402,7 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
return val, false return val, false
} }
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { func archrelocvariant(ctxt *ld.Link, target *ld.Target, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
switch r.Variant & sym.RV_TYPE_MASK { switch r.Variant & sym.RV_TYPE_MASK {
default: default:
ld.Errorf(s, "unexpected relocation variant %d", r.Variant) ld.Errorf(s, "unexpected relocation variant %d", r.Variant)

View file

@ -492,8 +492,8 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, secto
return true return true
} }
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) { func archreloc(ctxt *ld.Link, target *ld.Target, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
if ctxt.LinkMode == ld.LinkExternal { if target.IsExternal() {
return val, false return val, false
} }
switch r.Type { switch r.Type {
@ -506,7 +506,7 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
return val, false return val, false
} }
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { func archrelocvariant(ctxt *ld.Link, target *ld.Target, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
log.Fatalf("unexpected relocation variant") log.Fatalf("unexpected relocation variant")
return t return t
} }