cmd/internal/obj: replace obj.Addrel func with LSym.AddRel method

The old API was to do

	r := obj.AddRel(sym)
	r.Type = this
	r.Off = that
	etc

The new API is:

	sym.AddRel(ctxt, obj.Reloc{Type: this: Off: that, etc})

This new API is more idiomatic and avoids ever having relocations
that are only partially constructed. Most importantly, it sets up
for sym.AddRel being able to check relocation validity in the future.
(Passing ctxt is for use in validity checking.)

Passes golang.org/x/tools/cmd/toolstash/buildall.

Change-Id: I042ea76e61bb3bf6402f98ca11291a13f4799972
Reviewed-on: https://go-review.googlesource.com/c/go/+/625616
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
Russ Cox 2024-11-05 13:33:17 -05:00
parent 4ce8c0604e
commit 5b20eec8a0
25 changed files with 614 additions and 573 deletions

View file

@ -26,7 +26,7 @@ import (
"cmd/internal/src" "cmd/internal/src"
) )
func Info(fnsym *obj.LSym, infosym *obj.LSym, curfn obj.Func) (scopes []dwarf.Scope, inlcalls dwarf.InlCalls) { func Info(ctxt *obj.Link, fnsym *obj.LSym, infosym *obj.LSym, curfn obj.Func) (scopes []dwarf.Scope, inlcalls dwarf.InlCalls) {
fn := curfn.(*ir.Func) fn := curfn.(*ir.Func)
if fn.Nname != nil { if fn.Nname != nil {
@ -136,9 +136,7 @@ func Info(fnsym *obj.LSym, infosym *obj.LSym, curfn obj.Func) (scopes []dwarf.Sc
return strings.Compare(a.Name, b.Name) return strings.Compare(a.Name, b.Name)
}) })
for _, sym := range typesyms { for _, sym := range typesyms {
r := obj.Addrel(infosym) infosym.AddRel(ctxt, obj.Reloc{Type: objabi.R_USETYPE, Sym: sym})
r.Sym = sym
r.Type = objabi.R_USETYPE
} }
fnsym.Func().Autot = nil fnsym.Func().Autot = nil

View file

@ -138,9 +138,7 @@ func MakeTask() {
// that this package depends on (and thus, all of the packages // that this package depends on (and thus, all of the packages
// that need to be initialized before this one). // that need to be initialized before this one).
for _, d := range deps { for _, d := range deps {
r := obj.Addrel(lsym) lsym.AddRel(base.Ctxt, obj.Reloc{Type: objabi.R_INITORDER, Sym: d})
r.Type = objabi.R_INITORDER
r.Sym = d
} }
// An initTask has pointers, but none into the Go heap. // An initTask has pointers, but none into the Go heap.
// It's not quite read only, the state field must be modifiable. // It's not quite read only, the state field must be modifiable.

View file

@ -296,8 +296,6 @@ func writeOldMapType(t *types.Type, lsym *obj.LSym, c rttype.Cursor) {
// type live in the binary. This is important to make sure that // type live in the binary. This is important to make sure that
// a named map and that same map cast to its underlying type via // a named map and that same map cast to its underlying type via
// reflection, use the same hash function. See issue 37716. // reflection, use the same hash function. See issue 37716.
r := obj.Addrel(lsym) lsym.AddRel(base.Ctxt, obj.Reloc{Type: objabi.R_KEEP, Sym: writeType(u)})
r.Sym = writeType(u)
r.Type = objabi.R_KEEP
} }
} }

View file

@ -298,8 +298,6 @@ func writeSwissMapType(t *types.Type, lsym *obj.LSym, c rttype.Cursor) {
// type live in the binary. This is important to make sure that // type live in the binary. This is important to make sure that
// a named map and that same map cast to its underlying type via // a named map and that same map cast to its underlying type via
// reflection, use the same hash function. See issue 37716. // reflection, use the same hash function. See issue 37716.
r := obj.Addrel(lsym) lsym.AddRel(base.Ctxt, obj.Reloc{Type: objabi.R_KEEP, Sym: writeType(u)})
r.Sym = writeType(u)
r.Type = objabi.R_KEEP
} }
} }

View file

@ -385,9 +385,7 @@ func typePkg(t *types.Type) *types.Pkg {
func dmethodptrOff(c rttype.Cursor, x *obj.LSym) { func dmethodptrOff(c rttype.Cursor, x *obj.LSym) {
c.WriteInt32(0) c.WriteInt32(0)
r := c.Reloc() c.Reloc(obj.Reloc{Type: objabi.R_METHODOFF, Sym: x})
r.Sym = x
r.Type = objabi.R_METHODOFF
} }
var kinds = []abi.Kind{ var kinds = []abi.Kind{
@ -1533,9 +1531,7 @@ func MarkTypeUsedInInterface(t *types.Type, from *obj.LSym) {
func MarkTypeSymUsedInInterface(tsym *obj.LSym, from *obj.LSym) { func MarkTypeSymUsedInInterface(tsym *obj.LSym, from *obj.LSym) {
// Emit a marker relocation. The linker will know the type is converted // Emit a marker relocation. The linker will know the type is converted
// to an interface if "from" is reachable. // to an interface if "from" is reachable.
r := obj.Addrel(from) from.AddRel(base.Ctxt, obj.Reloc{Type: objabi.R_USEIFACE, Sym: tsym})
r.Sym = tsym
r.Type = objabi.R_USEIFACE
} }
// MarkUsedIfaceMethod marks that an interface method is used in the current // MarkUsedIfaceMethod marks that an interface method is used in the current
@ -1567,20 +1563,20 @@ func MarkUsedIfaceMethod(n *ir.CallExpr) {
// type, and the linker could do more complicated matching using // type, and the linker could do more complicated matching using
// some sort of fuzzy shape matching. For now, only use the name // some sort of fuzzy shape matching. For now, only use the name
// of the method for matching. // of the method for matching.
r := obj.Addrel(ir.CurFunc.LSym) ir.CurFunc.LSym.AddRel(base.Ctxt, obj.Reloc{
r.Sym = staticdata.StringSymNoCommon(dot.Sel.Name) Type: objabi.R_USENAMEDMETHOD,
r.Type = objabi.R_USENAMEDMETHOD Sym: staticdata.StringSymNoCommon(dot.Sel.Name),
})
return return
} }
tsym := TypeLinksym(ityp) // dot.Offset() is the method index * PtrSize (the offset of code pointer in itab).
r := obj.Addrel(ir.CurFunc.LSym)
r.Sym = tsym
// dot.Offset() is the method index * PtrSize (the offset of code pointer
// in itab).
midx := dot.Offset() / int64(types.PtrSize) midx := dot.Offset() / int64(types.PtrSize)
r.Add = InterfaceMethodOffset(ityp, midx) ir.CurFunc.LSym.AddRel(base.Ctxt, obj.Reloc{
r.Type = objabi.R_USEIFACEMETHOD Type: objabi.R_USEIFACEMETHOD,
Sym: TypeLinksym(ityp),
Add: InterfaceMethodOffset(ityp, midx),
})
} }
func deref(t *types.Type) *types.Type { func deref(t *types.Type) *types.Type {

View file

@ -245,11 +245,10 @@ func (c Cursor) WriteSlice(target *obj.LSym, off, len, cap int64) {
// Reloc adds a relocation from the current cursor position. // Reloc adds a relocation from the current cursor position.
// Reloc fills in Off and Siz fields. Caller should fill in the rest (Type, others). // Reloc fills in Off and Siz fields. Caller should fill in the rest (Type, others).
func (c Cursor) Reloc() *obj.Reloc { func (c Cursor) Reloc(rel obj.Reloc) {
r := obj.Addrel(c.lsym) rel.Off = int32(c.offset)
r.Off = int32(c.offset) rel.Siz = uint8(c.typ.Size())
r.Siz = uint8(c.typ.Size()) c.lsym.AddRel(base.Ctxt, rel)
return r
} }
// Field selects the field with the given name from the struct pointed to by c. // Field selects the field with the given name from the struct pointed to by c.

View file

@ -418,9 +418,7 @@ func fieldtrack(fnsym *obj.LSym, tracked map[*obj.LSym]struct{}) {
} }
slices.SortFunc(trackSyms, func(a, b *obj.LSym) int { return strings.Compare(a.Name, b.Name) }) slices.SortFunc(trackSyms, func(a, b *obj.LSym) int { return strings.Compare(a.Name, b.Name) })
for _, sym := range trackSyms { for _, sym := range trackSyms {
r := obj.Addrel(fnsym) fnsym.AddRel(base.Ctxt, obj.Reloc{Type: objabi.R_USEFIELD, Sym: sym})
r.Sym = sym
r.Type = objabi.R_USEFIELD
} }
} }

View file

@ -1189,9 +1189,7 @@ func AddKeepRelocations() {
if vs == nil { if vs == nil {
base.Fatalf("bad: mapvar %v has no linksym", k) base.Fatalf("bad: mapvar %v has no linksym", k)
} }
r := obj.Addrel(vs) vs.AddRel(base.Ctxt, obj.Reloc{Type: objabi.R_KEEP, Sym: fs})
r.Sym = fs
r.Type = objabi.R_KEEP
if base.Debug.WrapGlobalMapDbg > 1 { if base.Debug.WrapGlobalMapDbg > 1 {
fmt.Fprintf(os.Stderr, "=-= add R_KEEP relo from %s to %s\n", fmt.Fprintf(os.Stderr, "=-= add R_KEEP relo from %s to %s\n",
vs.Name, fs.Name) vs.Name, fs.Name)

View file

@ -1062,10 +1062,10 @@ func usemethod(n *ir.CallExpr) {
if ir.IsConst(targetName, constant.String) { if ir.IsConst(targetName, constant.String) {
name := constant.StringVal(targetName.Val()) name := constant.StringVal(targetName.Val())
ir.CurFunc.LSym.AddRel(base.Ctxt, obj.Reloc{
r := obj.Addrel(ir.CurFunc.LSym) Type: objabi.R_USENAMEDMETHOD,
r.Type = objabi.R_USENAMEDMETHOD Sym: staticdata.StringSymNoCommon(name),
r.Sym = staticdata.StringSymNoCommon(name) })
} else { } else {
ir.CurFunc.LSym.Set(obj.AttrReflectMethod, true) ir.CurFunc.LSym.Set(obj.AttrReflectMethod, true)
} }

View file

@ -1589,13 +1589,14 @@ func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) {
v := int32(-8) v := int32(-8)
if p.To.Sym != nil { if p.To.Sym != nil {
rel := obj.Addrel(c.cursym)
rel.Off = int32(c.pc)
rel.Siz = 4
rel.Sym = p.To.Sym
v += int32(p.To.Offset) v += int32(p.To.Offset)
rel.Add = int64(o1) | (int64(v)>>2)&0xffffff c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Type = objabi.R_CALLARM Type: objabi.R_CALLARM,
Off: int32(c.pc),
Siz: 4,
Sym: p.To.Sym,
Add: int64(o1) | (int64(v)>>2)&0xffffff,
})
break break
} }
@ -1620,10 +1621,10 @@ func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) {
} }
o1 = c.oprrr(p, ABL, int(p.Scond)) o1 = c.oprrr(p, ABL, int(p.Scond))
o1 |= (uint32(p.To.Reg) & 15) << 0 o1 |= (uint32(p.To.Reg) & 15) << 0
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_CALLIND,
rel.Siz = 0 Off: int32(c.pc),
rel.Type = objabi.R_CALLIND })
case 8: /* sll $c,[R],R -> mov (R<<$c),R */ case 8: /* sll $c,[R],R -> mov (R<<$c),R */
c.aclass(&p.From) c.aclass(&p.From)
@ -1663,23 +1664,23 @@ func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) {
if p.To.Sym != nil { if p.To.Sym != nil {
// This case happens with words generated // This case happens with words generated
// in the PC stream as part of the literal pool (c.pool). // in the PC stream as part of the literal pool (c.pool).
rel := obj.Addrel(c.cursym) typ := objabi.R_ADDR
add := p.To.Offset
rel.Off = int32(c.pc)
rel.Siz = 4
rel.Sym = p.To.Sym
rel.Add = p.To.Offset
if c.ctxt.Flag_shared { if c.ctxt.Flag_shared {
if p.To.Name == obj.NAME_GOTREF { if p.To.Name == obj.NAME_GOTREF {
rel.Type = objabi.R_GOTPCREL typ = objabi.R_GOTPCREL
} else { } else {
rel.Type = objabi.R_PCREL typ = objabi.R_PCREL
} }
rel.Add += c.pc - p.Rel.Pc - 8 add += c.pc - p.Rel.Pc - 8
} else {
rel.Type = objabi.R_ADDR
} }
c.cursym.AddRel(c.ctxt, obj.Reloc{
Type: typ,
Off: int32(c.pc),
Siz: 4,
Sym: p.To.Sym,
Add: add,
})
o1 = 0 o1 = 0
} }
@ -2159,12 +2160,12 @@ func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) {
} }
// This case happens with words generated in the PC stream as part of // This case happens with words generated in the PC stream as part of
// the literal c.pool. // the literal c.pool.
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
Type: objabi.R_TLS_LE,
rel.Off = int32(c.pc) Off: int32(c.pc),
rel.Siz = 4 Siz: 4,
rel.Sym = p.To.Sym Sym: p.To.Sym,
rel.Type = objabi.R_TLS_LE })
o1 = 0 o1 = 0
case 104: /* word tlsvar, initial exec */ case 104: /* word tlsvar, initial exec */
@ -2174,12 +2175,13 @@ func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) {
if p.To.Offset != 0 { if p.To.Offset != 0 {
c.ctxt.Diag("offset against tls var in %v", p) c.ctxt.Diag("offset against tls var in %v", p)
} }
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_TLS_IE,
rel.Siz = 4 Off: int32(c.pc),
rel.Sym = p.To.Sym Siz: 4,
rel.Type = objabi.R_TLS_IE Sym: p.To.Sym,
rel.Add = c.pc - p.Rel.Pc - 8 - int64(rel.Siz) Add: c.pc - p.Rel.Pc - 8 - 4,
})
case 68: /* floating point store -> ADDR */ case 68: /* floating point store -> ADDR */
o1 = c.omvl(p, &p.To, REGTMP) o1 = c.omvl(p, &p.To, REGTMP)

View file

@ -3580,21 +3580,22 @@ func (c *ctxt7) asmout(p *obj.Prog, out []uint32) (count int) {
break break
} }
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_CALLARM64,
rel.Siz = 4 Off: int32(c.pc),
rel.Sym = p.To.Sym Siz: 4,
rel.Add = p.To.Offset Sym: p.To.Sym,
rel.Type = objabi.R_CALLARM64 Add: p.To.Offset,
})
case 6: /* b ,O(R); bl ,O(R) */ case 6: /* b ,O(R); bl ,O(R) */
o1 = c.opbrr(p, p.As) o1 = c.opbrr(p, p.As)
o1 |= uint32(p.To.Reg&31) << 5 o1 |= uint32(p.To.Reg&31) << 5
if p.As == obj.ACALL { if p.As == obj.ACALL {
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_CALLIND,
rel.Siz = 0 Off: int32(c.pc),
rel.Type = objabi.R_CALLIND })
} }
case 7: /* beq s */ case 7: /* beq s */
@ -3660,12 +3661,13 @@ func (c *ctxt7) asmout(p *obj.Prog, out []uint32) (count int) {
o1 = uint32(c.instoffset) o1 = uint32(c.instoffset)
o2 = uint32(c.instoffset >> 32) o2 = uint32(c.instoffset >> 32)
if p.To.Sym != nil { if p.To.Sym != nil {
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_ADDR,
rel.Siz = 8 Off: int32(c.pc),
rel.Sym = p.To.Sym Siz: 8,
rel.Add = p.To.Offset Sym: p.To.Sym,
rel.Type = objabi.R_ADDR Add: p.To.Offset,
})
o2 = 0 o2 = 0
o1 = o2 o1 = o2
} }
@ -3736,13 +3738,13 @@ func (c *ctxt7) asmout(p *obj.Prog, out []uint32) (count int) {
if p.To.Sym != nil { if p.To.Sym != nil {
// This case happens with words generated // This case happens with words generated
// in the PC stream as part of the literal pool. // in the PC stream as part of the literal pool.
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
Type: objabi.R_ADDR,
rel.Off = int32(c.pc) Off: int32(c.pc),
rel.Siz = 4 Siz: 4,
rel.Sym = p.To.Sym Sym: p.To.Sym,
rel.Add = p.To.Offset Add: p.To.Offset,
rel.Type = objabi.R_ADDR })
o1 = 0 o1 = 0
} }
@ -4659,37 +4661,43 @@ func (c *ctxt7) asmout(p *obj.Prog, out []uint32) (count int) {
c.ctxt.Diag("cannot use REGTMP as source: %v\n", p) c.ctxt.Diag("cannot use REGTMP as source: %v\n", p)
} }
o1 = ADR(1, 0, REGTMP) o1 = ADR(1, 0, REGTMP)
rel := obj.Addrel(c.cursym) var typ objabi.RelocType
rel.Off = int32(c.pc)
rel.Siz = 8
rel.Sym = p.To.Sym
rel.Add = p.To.Offset
// For unaligned access, fall back to adrp + add + movT R, (REGTMP). // For unaligned access, fall back to adrp + add + movT R, (REGTMP).
if o.size(c.ctxt, p) != 8 { if o.size(c.ctxt, p) != 8 {
o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31 o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
o3 = c.olsr12u(p, c.opstr(p, p.As), 0, REGTMP, p.From.Reg) o3 = c.olsr12u(p, c.opstr(p, p.As), 0, REGTMP, p.From.Reg)
rel.Type = objabi.R_ADDRARM64 typ = objabi.R_ADDRARM64
break } else {
o2 = c.olsr12u(p, c.opstr(p, p.As), 0, REGTMP, p.From.Reg)
typ = c.addrRelocType(p)
} }
o2 = c.olsr12u(p, c.opstr(p, p.As), 0, REGTMP, p.From.Reg) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Type = c.addrRelocType(p) Type: typ,
Off: int32(c.pc),
Siz: 8,
Sym: p.To.Sym,
Add: p.To.Offset,
})
case 65: /* movT addr,R -> adrp + movT (REGTMP), R */ case 65: /* movT addr,R -> adrp + movT (REGTMP), R */
o1 = ADR(1, 0, REGTMP) o1 = ADR(1, 0, REGTMP)
rel := obj.Addrel(c.cursym) var typ objabi.RelocType
rel.Off = int32(c.pc)
rel.Siz = 8
rel.Sym = p.From.Sym
rel.Add = p.From.Offset
// For unaligned access, fall back to adrp + add + movT (REGTMP), R. // For unaligned access, fall back to adrp + add + movT (REGTMP), R.
if o.size(c.ctxt, p) != 8 { if o.size(c.ctxt, p) != 8 {
o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31 o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
o3 = c.olsr12u(p, c.opldr(p, p.As), 0, REGTMP, p.To.Reg) o3 = c.olsr12u(p, c.opldr(p, p.As), 0, REGTMP, p.To.Reg)
rel.Type = objabi.R_ADDRARM64 typ = objabi.R_ADDRARM64
break } else {
o2 = c.olsr12u(p, c.opldr(p, p.As), 0, REGTMP, p.To.Reg)
typ = c.addrRelocType(p)
} }
o2 = c.olsr12u(p, c.opldr(p, p.As), 0, REGTMP, p.To.Reg) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Type = c.addrRelocType(p) Type: typ,
Off: int32(c.pc),
Siz: 8,
Sym: p.From.Sym,
Add: p.From.Offset,
})
case 66: /* ldp O(R)!, (r1, r2); ldp (R)O!, (r1, r2) */ case 66: /* ldp O(R)!, (r1, r2); ldp (R)O!, (r1, r2) */
rf, rt1, rt2 := p.From.Reg, p.To.Reg, int16(p.To.Offset) rf, rt1, rt2 := p.From.Reg, p.To.Reg, int16(p.To.Offset)
@ -4721,21 +4729,23 @@ func (c *ctxt7) asmout(p *obj.Prog, out []uint32) (count int) {
} }
o1 = ADR(1, 0, uint32(p.To.Reg)) o1 = ADR(1, 0, uint32(p.To.Reg))
o2 = c.opirr(p, AADD) | uint32(p.To.Reg&31)<<5 | uint32(p.To.Reg&31) o2 = c.opirr(p, AADD) | uint32(p.To.Reg&31)<<5 | uint32(p.To.Reg&31)
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_ADDRARM64,
rel.Siz = 8 Off: int32(c.pc),
rel.Sym = p.From.Sym Siz: 8,
rel.Add = p.From.Offset Sym: p.From.Sym,
rel.Type = objabi.R_ADDRARM64 Add: p.From.Offset,
})
case 69: /* LE model movd $tlsvar, reg -> movz reg, 0 + reloc */ case 69: /* LE model movd $tlsvar, reg -> movz reg, 0 + reloc */
o1 = c.opirr(p, AMOVZ) o1 = c.opirr(p, AMOVZ)
o1 |= uint32(p.To.Reg & 31) o1 |= uint32(p.To.Reg & 31)
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_ARM64_TLS_LE,
rel.Siz = 4 Off: int32(c.pc),
rel.Sym = p.From.Sym Siz: 4,
rel.Type = objabi.R_ARM64_TLS_LE Sym: p.From.Sym,
})
if p.From.Offset != 0 { if p.From.Offset != 0 {
c.ctxt.Diag("invalid offset on MOVW $tlsvar") c.ctxt.Diag("invalid offset on MOVW $tlsvar")
} }
@ -4743,12 +4753,12 @@ func (c *ctxt7) asmout(p *obj.Prog, out []uint32) (count int) {
case 70: /* IE model movd $tlsvar, reg -> adrp REGTMP, 0; ldr reg, [REGTMP, #0] + relocs */ case 70: /* IE model movd $tlsvar, reg -> adrp REGTMP, 0; ldr reg, [REGTMP, #0] + relocs */
o1 = ADR(1, 0, REGTMP) o1 = ADR(1, 0, REGTMP)
o2 = c.olsr12u(p, c.opldr(p, AMOVD), 0, REGTMP, p.To.Reg) o2 = c.olsr12u(p, c.opldr(p, AMOVD), 0, REGTMP, p.To.Reg)
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_ARM64_TLS_IE,
rel.Siz = 8 Off: int32(c.pc),
rel.Sym = p.From.Sym Siz: 8,
rel.Add = 0 Sym: p.From.Sym,
rel.Type = objabi.R_ARM64_TLS_IE })
if p.From.Offset != 0 { if p.From.Offset != 0 {
c.ctxt.Diag("invalid offset on MOVW $tlsvar") c.ctxt.Diag("invalid offset on MOVW $tlsvar")
} }
@ -4756,12 +4766,12 @@ func (c *ctxt7) asmout(p *obj.Prog, out []uint32) (count int) {
case 71: /* movd sym@GOT, reg -> adrp REGTMP, #0; ldr reg, [REGTMP, #0] + relocs */ case 71: /* movd sym@GOT, reg -> adrp REGTMP, #0; ldr reg, [REGTMP, #0] + relocs */
o1 = ADR(1, 0, REGTMP) o1 = ADR(1, 0, REGTMP)
o2 = c.olsr12u(p, c.opldr(p, AMOVD), 0, REGTMP, p.To.Reg) o2 = c.olsr12u(p, c.opldr(p, AMOVD), 0, REGTMP, p.To.Reg)
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_ARM64_GOTPCREL,
rel.Siz = 8 Off: int32(c.pc),
rel.Sym = p.From.Sym Siz: 8,
rel.Add = 0 Sym: p.From.Sym,
rel.Type = objabi.R_ARM64_GOTPCREL })
case 72: /* vaddp/vand/vcmeq/vorr/vadd/veor/vfmla/vfmls/vbit/vbsl/vcmtst/vsub/vbif/vuzip1/vuzip2/vrax1 Vm.<T>, Vn.<T>, Vd.<T> */ case 72: /* vaddp/vand/vcmeq/vorr/vadd/veor/vfmla/vfmls/vbit/vbsl/vcmtst/vsub/vbif/vuzip1/vuzip2/vrax1 Vm.<T>, Vn.<T>, Vd.<T> */
af := int((p.From.Reg >> 5) & 15) af := int((p.From.Reg >> 5) & 15)
@ -5295,24 +5305,26 @@ func (c *ctxt7) asmout(p *obj.Prog, out []uint32) (count int) {
} }
o1 = ADR(1, 0, REGTMP) o1 = ADR(1, 0, REGTMP)
o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31 o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_ADDRARM64,
rel.Siz = 8 Off: int32(c.pc),
rel.Sym = p.To.Sym Siz: 8,
rel.Add = p.To.Offset Sym: p.To.Sym,
rel.Type = objabi.R_ADDRARM64 Add: p.To.Offset,
})
o3 = c.opldpstp(p, o, 0, REGTMP, rf1, rf2, 0) o3 = c.opldpstp(p, o, 0, REGTMP, rf1, rf2, 0)
case 88: /* ldp addr(SB), (r,r) -> adrp + add + ldp */ case 88: /* ldp addr(SB), (r,r) -> adrp + add + ldp */
rt1, rt2 := p.To.Reg, int16(p.To.Offset) rt1, rt2 := p.To.Reg, int16(p.To.Offset)
o1 = ADR(1, 0, REGTMP) o1 = ADR(1, 0, REGTMP)
o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31 o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_ADDRARM64,
rel.Siz = 8 Off: int32(c.pc),
rel.Sym = p.From.Sym Siz: 8,
rel.Add = p.From.Offset Sym: p.From.Sym,
rel.Type = objabi.R_ADDRARM64 Add: p.From.Offset,
})
o3 = c.opldpstp(p, o, 0, REGTMP, rt1, rt2, 1) o3 = c.opldpstp(p, o, 0, REGTMP, rt1, rt2, 1)
case 89: /* vadd/vsub Vm, Vn, Vd */ case 89: /* vadd/vsub Vm, Vn, Vd */

View file

@ -118,15 +118,16 @@ func (s *LSym) writeAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64,
ctxt.Diag("WriteAddr: bad address size %d in %s", siz, s.Name) ctxt.Diag("WriteAddr: bad address size %d in %s", siz, s.Name)
} }
s.prepwrite(ctxt, off, siz) s.prepwrite(ctxt, off, siz)
r := Addrel(s) if int64(int32(off)) != off {
r.Off = int32(off)
if int64(r.Off) != off {
ctxt.Diag("WriteAddr: off overflow %d in %s", off, s.Name) ctxt.Diag("WriteAddr: off overflow %d in %s", off, s.Name)
} }
r.Siz = uint8(siz) s.AddRel(ctxt, Reloc{
r.Sym = rsym Type: rtype,
r.Type = rtype Off: int32(off),
r.Add = roff Siz: uint8(siz),
Sym: rsym,
Add: roff,
})
} }
// WriteAddr writes an address of size siz into s at offset off. // WriteAddr writes an address of size siz into s at offset off.
@ -155,15 +156,16 @@ func (s *LSym) WriteCURelativeAddr(ctxt *Link, off int64, rsym *LSym, roff int64
// rsym+roff-(start of section that s is in). // rsym+roff-(start of section that s is in).
func (s *LSym) WriteOff(ctxt *Link, off int64, rsym *LSym, roff int64) { func (s *LSym) WriteOff(ctxt *Link, off int64, rsym *LSym, roff int64) {
s.prepwrite(ctxt, off, 4) s.prepwrite(ctxt, off, 4)
r := Addrel(s) if int64(int32(off)) != off {
r.Off = int32(off)
if int64(r.Off) != off {
ctxt.Diag("WriteOff: off overflow %d in %s", off, s.Name) ctxt.Diag("WriteOff: off overflow %d in %s", off, s.Name)
} }
r.Siz = 4 s.AddRel(ctxt, Reloc{
r.Sym = rsym Type: objabi.R_ADDROFF,
r.Type = objabi.R_ADDROFF Off: int32(off),
r.Add = roff Siz: 4,
Sym: rsym,
Add: roff,
})
} }
// WriteWeakOff writes a weak 4 byte offset to rsym+roff into s at offset off. // WriteWeakOff writes a weak 4 byte offset to rsym+roff into s at offset off.
@ -171,15 +173,16 @@ func (s *LSym) WriteOff(ctxt *Link, off int64, rsym *LSym, roff int64) {
// rsym+roff-(start of section that s is in). // rsym+roff-(start of section that s is in).
func (s *LSym) WriteWeakOff(ctxt *Link, off int64, rsym *LSym, roff int64) { func (s *LSym) WriteWeakOff(ctxt *Link, off int64, rsym *LSym, roff int64) {
s.prepwrite(ctxt, off, 4) s.prepwrite(ctxt, off, 4)
r := Addrel(s) if int64(int32(off)) != off {
r.Off = int32(off) ctxt.Diag("WriteWeakOff: off overflow %d in %s", off, s.Name)
if int64(r.Off) != off {
ctxt.Diag("WriteOff: off overflow %d in %s", off, s.Name)
} }
r.Siz = 4 s.AddRel(ctxt, Reloc{
r.Sym = rsym Type: objabi.R_WEAKADDROFF,
r.Type = objabi.R_WEAKADDROFF Off: int32(off),
r.Add = roff Siz: 4,
Sym: rsym,
Add: roff,
})
} }
// WriteString writes a string of size siz into s at offset off. // WriteString writes a string of size siz into s at offset off.
@ -198,10 +201,7 @@ func (s *LSym) WriteBytes(ctxt *Link, off int64, b []byte) int64 {
return off + int64(len(b)) return off + int64(len(b))
} }
func Addrel(s *LSym) *Reloc { // AddRel adds the relocation rel to s.
if s.R == nil { func (s *LSym) AddRel(ctxt *Link, rel Reloc) {
s.R = make([]Reloc, 0, 4) s.R = append(s.R, rel)
}
s.R = append(s.R, Reloc{})
return &s.R[len(s.R)-1]
} }

View file

@ -344,7 +344,7 @@ func (ctxt *Link) populateDWARF(curfn Func, s *LSym) {
var scopes []dwarf.Scope var scopes []dwarf.Scope
var inlcalls dwarf.InlCalls var inlcalls dwarf.InlCalls
if ctxt.DebugInfo != nil { if ctxt.DebugInfo != nil {
scopes, inlcalls = ctxt.DebugInfo(s, info, curfn) scopes, inlcalls = ctxt.DebugInfo(ctxt, s, info, curfn)
} }
var err error var err error
dwctxt := dwCtxt{ctxt} dwctxt := dwCtxt{ctxt}
@ -421,7 +421,7 @@ func (ctxt *Link) DwarfAbstractFunc(curfn Func, s *LSym) {
if s.Func() == nil { if s.Func() == nil {
s.NewFuncInfo() s.NewFuncInfo()
} }
scopes, _ := ctxt.DebugInfo(s, absfn, curfn) scopes, _ := ctxt.DebugInfo(ctxt, s, absfn, curfn)
dwctxt := dwCtxt{ctxt} dwctxt := dwCtxt{ctxt}
fnstate := dwarf.FnState{ fnstate := dwarf.FnState{
Name: s.Name, Name: s.Name,

View file

@ -1138,7 +1138,7 @@ type Link struct {
Imports []goobj.ImportedPkg Imports []goobj.ImportedPkg
DiagFunc func(string, ...interface{}) DiagFunc func(string, ...interface{})
DiagFlush func() DiagFlush func()
DebugInfo func(fn *LSym, info *LSym, curfn Func) ([]dwarf.Scope, dwarf.InlCalls) DebugInfo func(ctxt *Link, fn *LSym, info *LSym, curfn Func) ([]dwarf.Scope, dwarf.InlCalls)
GenAbstractFunc func(fn *LSym) GenAbstractFunc func(fn *LSym)
Errors int Errors int

View file

@ -1489,12 +1489,13 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
} }
o1 = OP_B_BL(c.opirr(p.As), uint32(v)) o1 = OP_B_BL(c.opirr(p.As), uint32(v))
if p.To.Sym != nil { if p.To.Sym != nil {
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_CALLLOONG64,
rel.Siz = 4 Off: int32(c.pc),
rel.Sym = p.To.Sym Siz: 4,
rel.Add = p.To.Offset Sym: p.To.Sym,
rel.Type = objabi.R_CALLLOONG64 Add: p.To.Offset,
})
} }
case 12: // movbs r,r case 12: // movbs r,r
@ -1583,10 +1584,10 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
} }
o1 = OP_RRR(c.oprrr(p.As), uint32(0), uint32(p.To.Reg), uint32(r)) o1 = OP_RRR(c.oprrr(p.As), uint32(0), uint32(p.To.Reg), uint32(r))
if p.As == obj.ACALL { if p.As == obj.ACALL {
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_CALLIND,
rel.Siz = 0 Off: int32(c.pc),
rel.Type = objabi.R_CALLIND })
} }
case 19: // mov $lcon,r case 19: // mov $lcon,r
@ -1723,72 +1724,79 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
// relocation operations // relocation operations
case 50: // mov r,addr ==> pcalau12i + sw case 50: // mov r,addr ==> pcalau12i + sw
o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP)) o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP))
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_LOONG64_ADDR_HI,
rel.Siz = 4 Off: int32(c.pc),
rel.Sym = p.To.Sym Siz: 4,
rel.Add = p.To.Offset Sym: p.To.Sym,
rel.Type = objabi.R_LOONG64_ADDR_HI Add: p.To.Offset,
})
o2 = OP_12IRR(c.opirr(p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg)) o2 = OP_12IRR(c.opirr(p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
rel2 := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel2.Off = int32(c.pc + 4) Type: objabi.R_LOONG64_ADDR_LO,
rel2.Siz = 4 Off: int32(c.pc + 4),
rel2.Sym = p.To.Sym Siz: 4,
rel2.Add = p.To.Offset Sym: p.To.Sym,
rel2.Type = objabi.R_LOONG64_ADDR_LO Add: p.To.Offset,
})
case 51: // mov addr,r ==> pcalau12i + lw case 51: // mov addr,r ==> pcalau12i + lw
o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP)) o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP))
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_LOONG64_ADDR_HI,
rel.Siz = 4 Off: int32(c.pc),
rel.Sym = p.From.Sym Siz: 4,
rel.Add = p.From.Offset Sym: p.From.Sym,
rel.Type = objabi.R_LOONG64_ADDR_HI Add: p.From.Offset,
})
o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg)) o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
rel2 := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel2.Off = int32(c.pc + 4) Type: objabi.R_LOONG64_ADDR_LO,
rel2.Siz = 4 Off: int32(c.pc + 4),
rel2.Sym = p.From.Sym Siz: 4,
rel2.Add = p.From.Offset Sym: p.From.Sym,
rel2.Type = objabi.R_LOONG64_ADDR_LO Add: p.From.Offset,
})
case 52: // mov $ext, r case 52: // mov $ext, r
// NOTE: this case does not use REGTMP. If it ever does, // NOTE: this case does not use REGTMP. If it ever does,
// remove the NOTUSETMP flag in optab. // remove the NOTUSETMP flag in optab.
o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(p.To.Reg)) o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(p.To.Reg))
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_LOONG64_ADDR_HI,
rel.Siz = 4 Off: int32(c.pc),
rel.Sym = p.From.Sym Siz: 4,
rel.Add = p.From.Offset Sym: p.From.Sym,
rel.Type = objabi.R_LOONG64_ADDR_HI Add: p.From.Offset,
})
o2 = OP_12IRR(c.opirr(add), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg)) o2 = OP_12IRR(c.opirr(add), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
rel2 := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel2.Off = int32(c.pc + 4) Type: objabi.R_LOONG64_ADDR_LO,
rel2.Siz = 4 Off: int32(c.pc + 4),
rel2.Sym = p.From.Sym Siz: 4,
rel2.Add = p.From.Offset Sym: p.From.Sym,
rel2.Type = objabi.R_LOONG64_ADDR_LO Add: p.From.Offset,
})
case 53: // mov r, tlsvar ==> lu12i.w + ori + add r2, regtmp + sw o(regtmp) case 53: // mov r, tlsvar ==> lu12i.w + ori + add r2, regtmp + sw o(regtmp)
// NOTE: this case does not use REGTMP. If it ever does, // NOTE: this case does not use REGTMP. If it ever does,
// remove the NOTUSETMP flag in optab. // remove the NOTUSETMP flag in optab.
o1 = OP_IR(c.opir(ALU12IW), uint32(0), uint32(REGTMP)) o1 = OP_IR(c.opir(ALU12IW), uint32(0), uint32(REGTMP))
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_LOONG64_TLS_LE_HI,
rel.Siz = 4 Off: int32(c.pc),
rel.Sym = p.To.Sym Siz: 4,
rel.Add = p.To.Offset Sym: p.To.Sym,
rel.Type = objabi.R_LOONG64_TLS_LE_HI Add: p.To.Offset,
})
o2 = OP_12IRR(c.opirr(AOR), uint32(0), uint32(REGTMP), uint32(REGTMP)) o2 = OP_12IRR(c.opirr(AOR), uint32(0), uint32(REGTMP), uint32(REGTMP))
rel2 := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel2.Off = int32(c.pc + 4) Type: objabi.R_LOONG64_TLS_LE_LO,
rel2.Siz = 4 Off: int32(c.pc + 4),
rel2.Sym = p.To.Sym Siz: 4,
rel2.Add = p.To.Offset Sym: p.To.Sym,
rel2.Type = objabi.R_LOONG64_TLS_LE_LO Add: p.To.Offset,
})
o3 = OP_RRR(c.oprrr(AADDV), uint32(REG_R2), uint32(REGTMP), uint32(REGTMP)) o3 = OP_RRR(c.oprrr(AADDV), uint32(REG_R2), uint32(REGTMP), uint32(REGTMP))
o4 = OP_12IRR(c.opirr(p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg)) o4 = OP_12IRR(c.opirr(p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
@ -1796,55 +1804,57 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
// NOTE: this case does not use REGTMP. If it ever does, // NOTE: this case does not use REGTMP. If it ever does,
// remove the NOTUSETMP flag in optab. // remove the NOTUSETMP flag in optab.
o1 = OP_IR(c.opir(ALU12IW), uint32(0), uint32(REGTMP)) o1 = OP_IR(c.opir(ALU12IW), uint32(0), uint32(REGTMP))
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_LOONG64_TLS_LE_HI,
rel.Siz = 4 Off: int32(c.pc),
rel.Sym = p.From.Sym Siz: 4,
rel.Add = p.From.Offset Sym: p.From.Sym,
rel.Type = objabi.R_LOONG64_TLS_LE_HI Add: p.From.Offset,
})
o2 = OP_12IRR(c.opirr(AOR), uint32(0), uint32(REGTMP), uint32(REGTMP)) o2 = OP_12IRR(c.opirr(AOR), uint32(0), uint32(REGTMP), uint32(REGTMP))
rel2 := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel2.Off = int32(c.pc + 4) Type: objabi.R_LOONG64_TLS_LE_LO,
rel2.Siz = 4 Off: int32(c.pc + 4),
rel2.Sym = p.From.Sym Siz: 4,
rel2.Add = p.From.Offset Sym: p.From.Sym,
rel2.Type = objabi.R_LOONG64_TLS_LE_LO Add: p.From.Offset,
})
o3 = OP_RRR(c.oprrr(AADDV), uint32(REG_R2), uint32(REGTMP), uint32(REGTMP)) o3 = OP_RRR(c.oprrr(AADDV), uint32(REG_R2), uint32(REGTMP), uint32(REGTMP))
o4 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg)) o4 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
case 56: // mov r, tlsvar IE model ==> (pcalau12i + ld.d)tlsvar@got + add.d + st.d case 56: // mov r, tlsvar IE model ==> (pcalau12i + ld.d)tlsvar@got + add.d + st.d
o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP)) o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP))
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_LOONG64_TLS_IE_HI,
rel.Siz = 4 Off: int32(c.pc),
rel.Sym = p.To.Sym Siz: 4,
rel.Add = 0x0 Sym: p.To.Sym,
rel.Type = objabi.R_LOONG64_TLS_IE_HI })
o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(REGTMP)) o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(REGTMP))
rel2 := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel2.Off = int32(c.pc + 4) Type: objabi.R_LOONG64_TLS_IE_LO,
rel2.Siz = 4 Off: int32(c.pc + 4),
rel2.Sym = p.To.Sym Siz: 4,
rel2.Add = 0x0 Sym: p.To.Sym,
rel2.Type = objabi.R_LOONG64_TLS_IE_LO })
o3 = OP_RRR(c.oprrr(AADDVU), uint32(REGTMP), uint32(REG_R2), uint32(REGTMP)) o3 = OP_RRR(c.oprrr(AADDVU), uint32(REGTMP), uint32(REG_R2), uint32(REGTMP))
o4 = OP_12IRR(c.opirr(p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg)) o4 = OP_12IRR(c.opirr(p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
case 57: // mov tlsvar, r IE model ==> (pcalau12i + ld.d)tlsvar@got + add.d + ld.d case 57: // mov tlsvar, r IE model ==> (pcalau12i + ld.d)tlsvar@got + add.d + ld.d
o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP)) o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP))
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_LOONG64_TLS_IE_HI,
rel.Siz = 4 Off: int32(c.pc),
rel.Sym = p.From.Sym Siz: 4,
rel.Add = 0x0 Sym: p.From.Sym,
rel.Type = objabi.R_LOONG64_TLS_IE_HI })
o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(REGTMP)) o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(REGTMP))
rel2 := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel2.Off = int32(c.pc + 4) Type: objabi.R_LOONG64_TLS_IE_LO,
rel2.Siz = 4 Off: int32(c.pc + 4),
rel2.Sym = p.From.Sym Siz: 4,
rel2.Add = 0x0 Sym: p.From.Sym,
rel2.Type = objabi.R_LOONG64_TLS_IE_LO })
o3 = OP_RRR(c.oprrr(AADDVU), uint32(REGTMP), uint32(REG_R2), uint32(REGTMP)) o3 = OP_RRR(c.oprrr(AADDVU), uint32(REGTMP), uint32(REG_R2), uint32(REGTMP))
o4 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg)) o4 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
@ -1878,19 +1888,19 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
case 65: // mov sym@GOT, r ==> pcalau12i + ld.d case 65: // mov sym@GOT, r ==> pcalau12i + ld.d
o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(p.To.Reg)) o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(p.To.Reg))
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_LOONG64_GOT_HI,
rel.Siz = 4 Off: int32(c.pc),
rel.Sym = p.From.Sym Siz: 4,
rel.Type = objabi.R_LOONG64_GOT_HI Sym: p.From.Sym,
rel.Add = 0x0 })
o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg)) o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
rel2 := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel2.Off = int32(c.pc + 4) Type: objabi.R_LOONG64_GOT_LO,
rel2.Siz = 4 Off: int32(c.pc + 4),
rel2.Sym = p.From.Sym Siz: 4,
rel2.Type = objabi.R_LOONG64_GOT_LO Sym: p.From.Sym,
rel2.Add = 0x0 })
case 66: // am* From, To, RegTo2 ==> am* RegTo2, From, To case 66: // am* From, To, RegTo2 ==> am* RegTo2, From, To
rk := p.From.Reg rk := p.From.Reg

View file

@ -1296,16 +1296,17 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
p.To.Sym = c.cursym.Func().Text.From.Sym p.To.Sym = c.cursym.Func().Text.From.Sym
p.To.Offset = p.To.Target().Pc p.To.Offset = p.To.Target().Pc
} }
rel := obj.Addrel(c.cursym) typ := objabi.R_JMPMIPS
rel.Off = int32(c.pc)
rel.Siz = 4
rel.Sym = p.To.Sym
rel.Add = p.To.Offset
if p.As == AJAL { if p.As == AJAL {
rel.Type = objabi.R_CALLMIPS typ = objabi.R_CALLMIPS
} else {
rel.Type = objabi.R_JMPMIPS
} }
c.cursym.AddRel(c.ctxt, obj.Reloc{
Type: typ,
Off: int32(c.pc),
Siz: 4,
Sym: p.To.Sym,
Add: p.To.Offset,
})
case 12: /* movbs r,r */ case 12: /* movbs r,r */
// NOTE: this case does not use REGTMP. If it ever does, // NOTE: this case does not use REGTMP. If it ever does,
@ -1363,10 +1364,10 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
} }
o1 = OP_RRR(c.oprrr(p.As), obj.REG_NONE, p.To.Reg, r) o1 = OP_RRR(c.oprrr(p.As), obj.REG_NONE, p.To.Reg, r)
if p.As == obj.ACALL { if p.As == obj.ACALL {
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_CALLIND,
rel.Siz = 0 Off: int32(c.pc),
rel.Type = objabi.R_CALLIND })
} }
case 19: /* mov $lcon,r ==> lu+or */ case 19: /* mov $lcon,r ==> lu+or */
@ -1559,71 +1560,80 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
/* relocation operations */ /* relocation operations */
case 50: /* mov r,addr ==> lu + add REGSB, REGTMP + sw o(REGTMP) */ case 50: /* mov r,addr ==> lu + add REGSB, REGTMP + sw o(REGTMP) */
o1 = OP_IRR(c.opirr(ALUI), 0, REGZERO, REGTMP) o1 = OP_IRR(c.opirr(ALUI), 0, REGZERO, REGTMP)
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_ADDRMIPSU,
rel.Siz = 4 Off: int32(c.pc),
rel.Sym = p.To.Sym Siz: 4,
rel.Add = p.To.Offset Sym: p.To.Sym,
rel.Type = objabi.R_ADDRMIPSU Add: p.To.Offset,
o2 = OP_IRR(c.opirr(p.As), 0, REGTMP, p.From.Reg) })
rel2 := obj.Addrel(c.cursym)
rel2.Off = int32(c.pc + 4)
rel2.Siz = 4
rel2.Sym = p.To.Sym
rel2.Add = p.To.Offset
rel2.Type = objabi.R_ADDRMIPS
o2 = OP_IRR(c.opirr(p.As), 0, REGTMP, p.From.Reg)
off := int32(c.pc + 4)
if o.size == 12 { if o.size == 12 {
o3 = o2 o3 = o2
o2 = OP_RRR(c.oprrr(AADDVU), REGSB, REGTMP, REGTMP) o2 = OP_RRR(c.oprrr(AADDVU), REGSB, REGTMP, REGTMP)
rel2.Off += 4 off += 4
} }
c.cursym.AddRel(c.ctxt, obj.Reloc{
Type: objabi.R_ADDRMIPS,
Off: off,
Siz: 4,
Sym: p.To.Sym,
Add: p.To.Offset,
})
case 51: /* mov addr,r ==> lu + add REGSB, REGTMP + lw o(REGTMP) */ case 51: /* mov addr,r ==> lu + add REGSB, REGTMP + lw o(REGTMP) */
o1 = OP_IRR(c.opirr(ALUI), 0, REGZERO, REGTMP) o1 = OP_IRR(c.opirr(ALUI), 0, REGZERO, REGTMP)
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_ADDRMIPSU,
rel.Siz = 4 Off: int32(c.pc),
rel.Sym = p.From.Sym Siz: 4,
rel.Add = p.From.Offset Sym: p.From.Sym,
rel.Type = objabi.R_ADDRMIPSU Add: p.From.Offset,
o2 = OP_IRR(c.opirr(-p.As), 0, REGTMP, p.To.Reg) })
rel2 := obj.Addrel(c.cursym)
rel2.Off = int32(c.pc + 4)
rel2.Siz = 4
rel2.Sym = p.From.Sym
rel2.Add = p.From.Offset
rel2.Type = objabi.R_ADDRMIPS
o2 = OP_IRR(c.opirr(-p.As), 0, REGTMP, p.To.Reg)
off := int32(c.pc + 4)
if o.size == 12 { if o.size == 12 {
o3 = o2 o3 = o2
o2 = OP_RRR(c.oprrr(AADDVU), REGSB, REGTMP, REGTMP) o2 = OP_RRR(c.oprrr(AADDVU), REGSB, REGTMP, REGTMP)
rel2.Off += 4 off += 4
} }
c.cursym.AddRel(c.ctxt, obj.Reloc{
Type: objabi.R_ADDRMIPS,
Off: off,
Siz: 4,
Sym: p.From.Sym,
Add: p.From.Offset,
})
case 52: /* mov $lext, r ==> lu + add REGSB, r + add */ case 52: /* mov $lext, r ==> lu + add REGSB, r + add */
// NOTE: this case does not use REGTMP. If it ever does, // NOTE: this case does not use REGTMP. If it ever does,
// remove the NOTUSETMP flag in optab. // remove the NOTUSETMP flag in optab.
o1 = OP_IRR(c.opirr(ALUI), 0, REGZERO, p.To.Reg) o1 = OP_IRR(c.opirr(ALUI), 0, REGZERO, p.To.Reg)
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_ADDRMIPSU,
rel.Siz = 4 Off: int32(c.pc),
rel.Sym = p.From.Sym Siz: 4,
rel.Add = p.From.Offset Sym: p.From.Sym,
rel.Type = objabi.R_ADDRMIPSU Add: p.From.Offset,
o2 = OP_IRR(c.opirr(add), 0, p.To.Reg, p.To.Reg) })
rel2 := obj.Addrel(c.cursym)
rel2.Off = int32(c.pc + 4)
rel2.Siz = 4
rel2.Sym = p.From.Sym
rel2.Add = p.From.Offset
rel2.Type = objabi.R_ADDRMIPS
o2 = OP_IRR(c.opirr(add), 0, p.To.Reg, p.To.Reg)
off := int32(c.pc + 4)
if o.size == 12 { if o.size == 12 {
o3 = o2 o3 = o2
o2 = OP_RRR(c.oprrr(AADDVU), REGSB, p.To.Reg, p.To.Reg) o2 = OP_RRR(c.oprrr(AADDVU), REGSB, p.To.Reg, p.To.Reg)
rel2.Off += 4 off += 4
} }
c.cursym.AddRel(c.ctxt, obj.Reloc{
Type: objabi.R_ADDRMIPS,
Off: off,
Siz: 4,
Sym: p.From.Sym,
Add: p.From.Offset,
})
case 53: /* mov r, tlsvar ==> rdhwr + sw o(r3) */ case 53: /* mov r, tlsvar ==> rdhwr + sw o(r3) */
// clobbers R3 ! // clobbers R3 !
@ -1632,12 +1642,13 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
// remove the NOTUSETMP flag in optab. // remove the NOTUSETMP flag in optab.
o1 = (037<<26 + 073) | (29 << 11) | (3 << 16) // rdhwr $29, r3 o1 = (037<<26 + 073) | (29 << 11) | (3 << 16) // rdhwr $29, r3
o2 = OP_IRR(c.opirr(p.As), 0, REG_R3, p.From.Reg) o2 = OP_IRR(c.opirr(p.As), 0, REG_R3, p.From.Reg)
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc + 4) Type: objabi.R_ADDRMIPSTLS,
rel.Siz = 4 Off: int32(c.pc + 4),
rel.Sym = p.To.Sym Siz: 4,
rel.Add = p.To.Offset Sym: p.To.Sym,
rel.Type = objabi.R_ADDRMIPSTLS Add: p.To.Offset,
})
case 54: /* mov tlsvar, r ==> rdhwr + lw o(r3) */ case 54: /* mov tlsvar, r ==> rdhwr + lw o(r3) */
// clobbers R3 ! // clobbers R3 !
@ -1645,12 +1656,13 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
// remove the NOTUSETMP flag in optab. // remove the NOTUSETMP flag in optab.
o1 = (037<<26 + 073) | (29 << 11) | (3 << 16) // rdhwr $29, r3 o1 = (037<<26 + 073) | (29 << 11) | (3 << 16) // rdhwr $29, r3
o2 = OP_IRR(c.opirr(-p.As), 0, REG_R3, p.To.Reg) o2 = OP_IRR(c.opirr(-p.As), 0, REG_R3, p.To.Reg)
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc + 4) Type: objabi.R_ADDRMIPSTLS,
rel.Siz = 4 Off: int32(c.pc + 4),
rel.Sym = p.From.Sym Siz: 4,
rel.Add = p.From.Offset Sym: p.From.Sym,
rel.Type = objabi.R_ADDRMIPSTLS Add: p.From.Offset,
})
case 55: /* mov $tlsvar, r ==> rdhwr + add */ case 55: /* mov $tlsvar, r ==> rdhwr + add */
// clobbers R3 ! // clobbers R3 !
@ -1658,12 +1670,13 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
// remove the NOTUSETMP flag in optab. // remove the NOTUSETMP flag in optab.
o1 = (037<<26 + 073) | (29 << 11) | (3 << 16) // rdhwr $29, r3 o1 = (037<<26 + 073) | (29 << 11) | (3 << 16) // rdhwr $29, r3
o2 = OP_IRR(c.opirr(add), 0, REG_R3, p.To.Reg) o2 = OP_IRR(c.opirr(add), 0, REG_R3, p.To.Reg)
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc + 4) Type: objabi.R_ADDRMIPSTLS,
rel.Siz = 4 Off: int32(c.pc + 4),
rel.Sym = p.From.Sym Siz: 4,
rel.Add = p.From.Offset Sym: p.From.Sym,
rel.Type = objabi.R_ADDRMIPSTLS Add: p.From.Offset,
})
case 56: /* vmov{b,h,w,d} $scon, wr */ case 56: /* vmov{b,h,w,d} $scon, wr */

View file

@ -40,7 +40,7 @@ import (
) )
func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
c := ctxt0{ctxt: ctxt, newprog: newprog} c := ctxt0{ctxt: ctxt}
p.From.Class = 0 p.From.Class = 0
p.To.Class = 0 p.To.Class = 0

View file

@ -52,17 +52,13 @@ func TestContentHash(t *testing.T) {
s.PkgIdx = goobj.PkgIdxHashed s.PkgIdx = goobj.PkgIdxHashed
} }
// s3 references s0 // s3 references s0
r := Addrel(syms[3]) syms[3].R = []Reloc{{Sym: syms[0]}}
r.Sym = syms[0]
// s4 references s0 // s4 references s0
r = Addrel(syms[4]) syms[4].R = []Reloc{{Sym: syms[0]}}
r.Sym = syms[0]
// s5 references s1 // s5 references s1
r = Addrel(syms[5]) syms[5].R = []Reloc{{Sym: syms[1]}}
r.Sym = syms[1]
// s6 references s2 // s6 references s2
r = Addrel(syms[6]) syms[6].R = []Reloc{{Sym: syms[2]}}
r.Sym = syms[2]
// compute hashes // compute hashes
h := make([]goobj.HashType, len(syms)) h := make([]goobj.HashType, len(syms))

View file

@ -2409,7 +2409,8 @@ func (c *ctxt9) opform(insn uint32) int {
// Encode instructions and create relocation for accessing s+d according to the // Encode instructions and create relocation for accessing s+d according to the
// instruction op with source or destination (as appropriate) register reg. // instruction op with source or destination (as appropriate) register reg.
func (c *ctxt9) symbolAccess(s *obj.LSym, d int64, reg int16, op uint32, reuse bool) (o1, o2 uint32, rel *obj.Reloc) { // The caller must call c.cursym.AddRel(c.ctxt, rel) when finished editing rel.
func (c *ctxt9) symbolAccess(s *obj.LSym, d int64, reg int16, op uint32, reuse bool) (o1, o2 uint32, rel obj.Reloc) {
if c.ctxt.Headtype == objabi.Haix { if c.ctxt.Headtype == objabi.Haix {
// Every symbol access must be made via a TOC anchor. // Every symbol access must be made via a TOC anchor.
c.ctxt.Diag("symbolAccess called for %s", s.Name) c.ctxt.Diag("symbolAccess called for %s", s.Name)
@ -2430,27 +2431,29 @@ func (c *ctxt9) symbolAccess(s *obj.LSym, d int64, reg int16, op uint32, reuse b
o1 = AOP_IRR(OP_ADDIS, uint32(reg), base, 0) o1 = AOP_IRR(OP_ADDIS, uint32(reg), base, 0)
o2 = AOP_IRR(op, uint32(reg), uint32(reg), 0) o2 = AOP_IRR(op, uint32(reg), uint32(reg), 0)
} }
rel = obj.Addrel(c.cursym) var typ objabi.RelocType
rel.Off = int32(c.pc)
rel.Siz = 8
rel.Sym = s
rel.Add = d
if c.ctxt.Flag_shared { if c.ctxt.Flag_shared {
switch form { switch form {
case D_FORM: case D_FORM:
rel.Type = objabi.R_ADDRPOWER_TOCREL typ = objabi.R_ADDRPOWER_TOCREL
case DS_FORM: case DS_FORM:
rel.Type = objabi.R_ADDRPOWER_TOCREL_DS typ = objabi.R_ADDRPOWER_TOCREL_DS
} }
} else { } else {
switch form { switch form {
case D_FORM: case D_FORM:
rel.Type = objabi.R_ADDRPOWER typ = objabi.R_ADDRPOWER
case DS_FORM: case DS_FORM:
rel.Type = objabi.R_ADDRPOWER_DS typ = objabi.R_ADDRPOWER_DS
} }
} }
rel = obj.Reloc{
Type: typ,
Off: int32(c.pc),
Siz: 8,
Sym: s,
Add: d,
}
return return
} }
@ -2668,18 +2671,18 @@ func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) {
o1 = OP_BR(c.opirr(p.As), uint32(v), 0) o1 = OP_BR(c.opirr(p.As), uint32(v), 0)
if p.To.Sym != nil { if p.To.Sym != nil {
rel := obj.Addrel(c.cursym)
rel.Off = int32(c.pc)
rel.Siz = 4
rel.Sym = p.To.Sym
v += int32(p.To.Offset) v += int32(p.To.Offset)
if v&03 != 0 { if v&03 != 0 {
c.ctxt.Diag("odd branch target address\n%v", p) c.ctxt.Diag("odd branch target address\n%v", p)
v &^= 03 v &^= 03
} }
c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Add = int64(v) Type: objabi.R_CALLPOWER,
rel.Type = objabi.R_CALLPOWER Off: int32(c.pc),
Siz: 4,
Sym: p.To.Sym,
Add: int64(v),
})
} }
o2 = NOP // nop, sometimes overwritten by ld r2, 24(r1) when dynamic linking o2 = NOP // nop, sometimes overwritten by ld r2, 24(r1) when dynamic linking
@ -3052,7 +3055,9 @@ func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) {
switch p.From.Name { switch p.From.Name {
case obj.NAME_EXTERN, obj.NAME_STATIC: case obj.NAME_EXTERN, obj.NAME_STATIC:
// Load a 32 bit constant, or relocation depending on if a symbol is attached // Load a 32 bit constant, or relocation depending on if a symbol is attached
o1, o2, rel = c.symbolAccess(p.From.Sym, v, p.To.Reg, OP_ADDI, true) var rel1 obj.Reloc
o1, o2, rel1 = c.symbolAccess(p.From.Sym, v, p.To.Reg, OP_ADDI, true)
rel = &rel1
default: default:
// Add a 32 bit offset to a register. // Add a 32 bit offset to a register.
o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), uint32(r), uint32(high16adjusted(int32(v)))) o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), uint32(r), uint32(high16adjusted(int32(v))))
@ -3067,6 +3072,9 @@ func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) {
rel.Type = objabi.R_ADDRPOWER_PCREL34 rel.Type = objabi.R_ADDRPOWER_PCREL34
} }
} }
if rel != nil {
c.cursym.AddRel(c.ctxt, *rel)
}
case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */ case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */
v := c.regoff(p.GetFrom3()) v := c.regoff(p.GetFrom3())
@ -3146,12 +3154,13 @@ func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) {
} }
if p.From.Sym != nil { if p.From.Sym != nil {
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) Type: objabi.R_ADDR,
rel.Siz = 8 Off: int32(c.pc),
rel.Sym = p.From.Sym Siz: 8,
rel.Add = p.From.Offset Sym: p.From.Sym,
rel.Type = objabi.R_ADDR Add: p.From.Offset,
})
o2 = 0 o2 = 0
o1 = o2 o1 = o2
} }
@ -3537,12 +3546,12 @@ func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) {
/* relocation operations */ /* relocation operations */
case 74: case 74:
var rel *obj.Reloc
v := c.vregoff(&p.To) v := c.vregoff(&p.To)
// Offsets in DS form stores must be a multiple of 4 // Offsets in DS form stores must be a multiple of 4
inst := c.opstore(p.As) inst := c.opstore(p.As)
// Can't reuse base for store instructions. // Can't reuse base for store instructions.
var rel obj.Reloc
o1, o2, rel = c.symbolAccess(p.To.Sym, v, p.From.Reg, inst, false) o1, o2, rel = c.symbolAccess(p.To.Sym, v, p.From.Reg, inst, false)
// Rewrite as a prefixed store if supported. // Rewrite as a prefixed store if supported.
@ -3552,13 +3561,14 @@ func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) {
} else if c.opform(inst) == DS_FORM && v&0x3 != 0 { } else if c.opform(inst) == DS_FORM && v&0x3 != 0 {
log.Fatalf("invalid offset for DS form load/store %v", p) log.Fatalf("invalid offset for DS form load/store %v", p)
} }
c.cursym.AddRel(c.ctxt, rel)
case 75: // 32 bit offset symbol loads (got/toc/addr) case 75: // 32 bit offset symbol loads (got/toc/addr)
var rel *obj.Reloc
v := p.From.Offset v := p.From.Offset
// Offsets in DS form loads must be a multiple of 4 // Offsets in DS form loads must be a multiple of 4
inst := c.opload(p.As) inst := c.opload(p.As)
var rel obj.Reloc
switch p.From.Name { switch p.From.Name {
case obj.NAME_GOTREF, obj.NAME_TOCREF: case obj.NAME_GOTREF, obj.NAME_TOCREF:
if v != 0 { if v != 0 {
@ -3566,7 +3576,6 @@ func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) {
} }
o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0) o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
o2 = AOP_IRR(inst, uint32(p.To.Reg), uint32(p.To.Reg), 0) o2 = AOP_IRR(inst, uint32(p.To.Reg), uint32(p.To.Reg), 0)
rel = obj.Addrel(c.cursym)
rel.Off = int32(c.pc) rel.Off = int32(c.pc)
rel.Siz = 8 rel.Siz = 8
rel.Sym = p.From.Sym rel.Sym = p.From.Sym
@ -3602,6 +3611,7 @@ func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) {
} else if c.opform(inst) == DS_FORM && v&0x3 != 0 { } else if c.opform(inst) == DS_FORM && v&0x3 != 0 {
log.Fatalf("invalid offset for DS form load/store %v", p) log.Fatalf("invalid offset for DS form load/store %v", p)
} }
c.cursym.AddRel(c.ctxt, rel)
o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0) o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
@ -3609,41 +3619,47 @@ func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) {
if p.From.Offset != 0 { if p.From.Offset != 0 {
c.ctxt.Diag("invalid offset against tls var %v", p) c.ctxt.Diag("invalid offset against tls var %v", p)
} }
rel := obj.Addrel(c.cursym) var typ objabi.RelocType
rel.Off = int32(c.pc)
rel.Siz = 8
rel.Sym = p.From.Sym
if !o.ispfx { if !o.ispfx {
o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R13, 0) o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R13, 0)
o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), uint32(p.To.Reg), 0) o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), uint32(p.To.Reg), 0)
rel.Type = objabi.R_POWER_TLS_LE typ = objabi.R_POWER_TLS_LE
} else { } else {
o1, o2 = pfxadd(p.To.Reg, REG_R13, PFX_R_ABS, 0) o1, o2 = pfxadd(p.To.Reg, REG_R13, PFX_R_ABS, 0)
rel.Type = objabi.R_POWER_TLS_LE_TPREL34 typ = objabi.R_POWER_TLS_LE_TPREL34
} }
c.cursym.AddRel(c.ctxt, obj.Reloc{
Type: typ,
Off: int32(c.pc),
Siz: 8,
Sym: p.From.Sym,
})
case 80: case 80:
if p.From.Offset != 0 { if p.From.Offset != 0 {
c.ctxt.Diag("invalid offset against tls var %v", p) c.ctxt.Diag("invalid offset against tls var %v", p)
} }
rel := obj.Addrel(c.cursym) typ := objabi.R_POWER_TLS_IE
rel.Off = int32(c.pc)
rel.Siz = 8
rel.Sym = p.From.Sym
rel.Type = objabi.R_POWER_TLS_IE
if !o.ispfx { if !o.ispfx {
o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0) o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
o2 = AOP_IRR(c.opload(AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0) o2 = AOP_IRR(c.opload(AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)
} else { } else {
o1, o2 = pfxload(p.As, p.To.Reg, REG_R0, PFX_R_PCREL) o1, o2 = pfxload(p.As, p.To.Reg, REG_R0, PFX_R_PCREL)
rel.Type = objabi.R_POWER_TLS_IE_PCREL34 typ = objabi.R_POWER_TLS_IE_PCREL34
} }
c.cursym.AddRel(c.ctxt, obj.Reloc{
Type: typ,
Off: int32(c.pc),
Siz: 8,
Sym: p.From.Sym,
})
o3 = AOP_RRR(OP_ADD, uint32(p.To.Reg), uint32(p.To.Reg), REG_R13) o3 = AOP_RRR(OP_ADD, uint32(p.To.Reg), uint32(p.To.Reg), REG_R13)
rel = obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc) + 8 Type: objabi.R_POWER_TLS,
rel.Siz = 4 Off: int32(c.pc) + 8,
rel.Sym = p.From.Sym Siz: 4,
rel.Type = objabi.R_POWER_TLS Sym: p.From.Sym,
})
case 82: /* vector instructions, VX-form and VC-form */ case 82: /* vector instructions, VX-form and VC-form */
if p.From.Type == obj.TYPE_REG { if p.From.Type == obj.TYPE_REG {

View file

@ -867,11 +867,12 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
q.Pos = p.Pos q.Pos = p.Pos
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = 0x38420000 q.From.Offset = 0x38420000
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = 0 Type: objabi.R_ADDRPOWER_PCREL,
rel.Siz = 8 Off: 0,
rel.Sym = c.ctxt.Lookup(".TOC.") Siz: 8,
rel.Type = objabi.R_ADDRPOWER_PCREL Sym: c.ctxt.Lookup(".TOC."),
})
} }
if !c.cursym.Func().Text.From.Sym.NoSplit() { if !c.cursym.Func().Text.From.Sym.NoSplit() {

View file

@ -2625,12 +2625,13 @@ func assemble(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
switch p.As { switch p.As {
case AJAL: case AJAL:
if p.Mark&NEED_JAL_RELOC == NEED_JAL_RELOC { if p.Mark&NEED_JAL_RELOC == NEED_JAL_RELOC {
rel := obj.Addrel(cursym) cursym.AddRel(ctxt, obj.Reloc{
rel.Off = int32(p.Pc) Type: objabi.R_RISCV_JAL,
rel.Siz = 4 Off: int32(p.Pc),
rel.Sym = p.To.Sym Siz: 4,
rel.Add = p.To.Offset Sym: p.To.Sym,
rel.Type = objabi.R_RISCV_JAL Add: p.To.Offset,
})
} }
case AJALR: case AJALR:
if p.To.Sym != nil { if p.To.Sym != nil {
@ -2671,12 +2672,13 @@ func assemble(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
} }
} }
rel := obj.Addrel(cursym) cursym.AddRel(ctxt, obj.Reloc{
rel.Off = int32(p.Pc) Type: rt,
rel.Siz = 8 Off: int32(p.Pc),
rel.Sym = addr.Sym Siz: 8,
rel.Add = addr.Offset Sym: addr.Sym,
rel.Type = rt Add: addr.Offset,
})
case obj.APCALIGN: case obj.APCALIGN:
alignedValue := p.From.Offset alignedValue := p.From.Offset

View file

@ -2643,48 +2643,48 @@ func oclass(a *obj.Addr) int {
// Add a relocation for the immediate in a RIL style instruction. // Add a relocation for the immediate in a RIL style instruction.
// The addend will be adjusted as required. // The addend will be adjusted as required.
func (c *ctxtz) addrilreloc(sym *obj.LSym, add int64) *obj.Reloc { func (c *ctxtz) addrilreloc(sym *obj.LSym, add int64) {
if sym == nil { if sym == nil {
c.ctxt.Diag("require symbol to apply relocation") c.ctxt.Diag("require symbol to apply relocation")
} }
offset := int64(2) // relocation offset from start of instruction offset := int64(2) // relocation offset from start of instruction
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc + offset) Type: objabi.R_PCRELDBL,
rel.Siz = 4 Off: int32(c.pc + offset),
rel.Sym = sym Siz: 4,
rel.Add = add + offset + int64(rel.Siz) Sym: sym,
rel.Type = objabi.R_PCRELDBL Add: add + offset + 4,
return rel })
} }
func (c *ctxtz) addrilrelocoffset(sym *obj.LSym, add, offset int64) *obj.Reloc { func (c *ctxtz) addrilrelocoffset(sym *obj.LSym, add, offset int64) {
if sym == nil { if sym == nil {
c.ctxt.Diag("require symbol to apply relocation") c.ctxt.Diag("require symbol to apply relocation")
} }
offset += int64(2) // relocation offset from start of instruction offset += int64(2) // relocation offset from start of instruction
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc + offset) Type: objabi.R_PCRELDBL,
rel.Siz = 4 Off: int32(c.pc + offset),
rel.Sym = sym Siz: 4,
rel.Add = add + offset + int64(rel.Siz) Sym: sym,
rel.Type = objabi.R_PCRELDBL Add: add + offset + 4,
return rel })
} }
// Add a CALL relocation for the immediate in a RIL style instruction. // Add a CALL relocation for the immediate in a RIL style instruction.
// The addend will be adjusted as required. // The addend will be adjusted as required.
func (c *ctxtz) addcallreloc(sym *obj.LSym, add int64) *obj.Reloc { func (c *ctxtz) addcallreloc(sym *obj.LSym, add int64) {
if sym == nil { if sym == nil {
c.ctxt.Diag("require symbol to apply relocation") c.ctxt.Diag("require symbol to apply relocation")
} }
offset := int64(2) // relocation offset from start of instruction offset := int64(2) // relocation offset from start of instruction
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc + offset) Type: objabi.R_CALL,
rel.Siz = 4 Off: int32(c.pc + offset),
rel.Sym = sym Siz: 4,
rel.Add = add + offset + int64(rel.Siz) Sym: sym,
rel.Type = objabi.R_CALL Add: add + offset + int64(4),
return rel })
} }
func (c *ctxtz) branchMask(p *obj.Prog) CCMask { func (c *ctxtz) branchMask(p *obj.Prog) CCMask {
@ -4008,24 +4008,25 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) {
c.ctxt.Diag("invalid offset against GOT slot %v", p) c.ctxt.Diag("invalid offset against GOT slot %v", p)
} }
zRIL(_b, op_LGRL, uint32(p.To.Reg), 0, asm) zRIL(_b, op_LGRL, uint32(p.To.Reg), 0, asm)
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc + 2) Type: objabi.R_GOTPCREL,
rel.Siz = 4 Off: int32(c.pc + 2),
rel.Sym = p.From.Sym Siz: 4,
rel.Type = objabi.R_GOTPCREL Sym: p.From.Sym,
rel.Add = 2 + int64(rel.Siz) Add: 2 + 4,
})
case 94: // TLS local exec model case 94: // TLS local exec model
zRIL(_b, op_LARL, regtmp(p), (sizeRIL+sizeRXY+sizeRI)>>1, asm) zRIL(_b, op_LARL, regtmp(p), (sizeRIL+sizeRXY+sizeRI)>>1, asm)
zRXY(op_LG, uint32(p.To.Reg), regtmp(p), 0, 0, asm) zRXY(op_LG, uint32(p.To.Reg), regtmp(p), 0, 0, asm)
zRI(op_BRC, 0xF, (sizeRI+8)>>1, asm) zRI(op_BRC, 0xF, (sizeRI+8)>>1, asm)
*asm = append(*asm, 0, 0, 0, 0, 0, 0, 0, 0) *asm = append(*asm, 0, 0, 0, 0, 0, 0, 0, 0)
rel := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
rel.Off = int32(c.pc + sizeRIL + sizeRXY + sizeRI) Type: objabi.R_TLS_LE,
rel.Siz = 8 Off: int32(c.pc + sizeRIL + sizeRXY + sizeRI),
rel.Sym = p.From.Sym Siz: 8,
rel.Type = objabi.R_TLS_LE Sym: p.From.Sym,
rel.Add = 0 })
case 95: // TLS initial exec model case 95: // TLS initial exec model
// Assembly | Relocation symbol | Done Here? // Assembly | Relocation symbol | Done Here?
@ -4040,12 +4041,13 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) {
// R_390_TLS_IEENT // R_390_TLS_IEENT
zRIL(_b, op_LARL, regtmp(p), 0, asm) zRIL(_b, op_LARL, regtmp(p), 0, asm)
ieent := obj.Addrel(c.cursym) c.cursym.AddRel(c.ctxt, obj.Reloc{
ieent.Off = int32(c.pc + 2) Type: objabi.R_TLS_IE,
ieent.Siz = 4 Off: int32(c.pc + 2),
ieent.Sym = p.From.Sym Siz: 4,
ieent.Type = objabi.R_TLS_IE Sym: p.From.Sym,
ieent.Add = 2 + int64(ieent.Siz) Add: 2 + 4,
})
// R_390_TLS_LOAD // R_390_TLS_LOAD
zRXY(op_LGF, uint32(p.To.Reg), regtmp(p), 0, 0, asm) zRXY(op_LGF, uint32(p.To.Reg), regtmp(p), 0, 0, asm)

View file

@ -1276,14 +1276,16 @@ func assemble(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
fmt.Println(p.To) fmt.Println(p.To)
panic("bad name for Call") panic("bad name for Call")
} }
r := obj.Addrel(s) typ := objabi.R_CALL
r.Siz = 1 // actually variable sized
r.Off = int32(w.Len())
r.Type = objabi.R_CALL
if p.Mark&WasmImport != 0 { if p.Mark&WasmImport != 0 {
r.Type = objabi.R_WASMIMPORT typ = objabi.R_WASMIMPORT
} }
r.Sym = p.To.Sym s.AddRel(ctxt, obj.Reloc{
Type: typ,
Off: int32(w.Len()),
Siz: 1, // actually variable sized
Sym: p.To.Sym,
})
if hasLocalSP { if hasLocalSP {
// The stack may have moved, which changes SP. Update the local SP variable. // The stack may have moved, which changes SP. Update the local SP variable.
updateLocalSP(w) updateLocalSP(w)
@ -1303,12 +1305,13 @@ func assemble(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
case AI32Const, AI64Const: case AI32Const, AI64Const:
if p.From.Name == obj.NAME_EXTERN { if p.From.Name == obj.NAME_EXTERN {
r := obj.Addrel(s) s.AddRel(ctxt, obj.Reloc{
r.Siz = 1 // actually variable sized Type: objabi.R_ADDR,
r.Off = int32(w.Len()) Off: int32(w.Len()),
r.Type = objabi.R_ADDR Siz: 1, // actually variable sized
r.Sym = p.From.Sym Sym: p.From.Sym,
r.Add = p.From.Offset Add: p.From.Offset,
})
break break
} }
writeSleb128(w, p.From.Offset) writeSleb128(w, p.From.Offset)

View file

@ -3518,9 +3518,8 @@ func (ab *AsmBuf) relput4(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, a *obj.
if rel.Siz != 4 { if rel.Siz != 4 {
ctxt.Diag("bad reloc") ctxt.Diag("bad reloc")
} }
r := obj.Addrel(cursym) rel.Off = int32(p.Pc + int64(ab.Len()))
*r = rel cursym.AddRel(ctxt, rel)
r.Off = int32(p.Pc + int64(ab.Len()))
} }
ab.PutInt32(int32(v)) ab.PutInt32(int32(v))
@ -3779,9 +3778,8 @@ putrelv:
goto bad goto bad
} }
r := obj.Addrel(cursym) rel.Off = int32(p.Pc + int64(ab.Len()))
*r = rel cursym.AddRel(ctxt, rel)
r.Off = int32(p.Pc + int64(ab.Len()))
} }
ab.PutInt32(v) ab.PutInt32(v)
@ -4298,18 +4296,10 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
} }
ft := int(p.Ft) * Ymax ft := int(p.Ft) * Ymax
var f3t int
tt := int(p.Tt) * Ymax tt := int(p.Tt) * Ymax
xo := obj.Bool2int(o.op[0] == 0x0f) xo := obj.Bool2int(o.op[0] == 0x0f)
z := 0 z := 0
var a *obj.Addr
var l int
var op int
var q *obj.Prog
var r *obj.Reloc
var rel obj.Reloc
var v int64
args := make([]int, 0, argListMax) args := make([]int, 0, argListMax)
if ft != Ynone*Ymax { if ft != Ynone*Ymax {
@ -4322,6 +4312,7 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
args = append(args, tt) args = append(args, tt)
} }
var f3t int
for _, yt := range o.ytab { for _, yt := range o.ytab {
// ytab matching is purely args-based, // ytab matching is purely args-based,
// but AVX512 suffixes like "Z" or "RU_SAE" will // but AVX512 suffixes like "Z" or "RU_SAE" will
@ -4440,7 +4431,7 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
if z >= len(o.op) { if z >= len(o.op) {
log.Fatalf("asmins bad table %v", p) log.Fatalf("asmins bad table %v", p)
} }
op = int(o.op[z]) op := int(o.op[z])
if op == 0x0f { if op == 0x0f {
ab.Put1(byte(op)) ab.Put1(byte(op))
z++ z++
@ -4698,10 +4689,10 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
ab.asmando(ctxt, cursym, p, &p.To, int(o.op[z+1])) ab.asmando(ctxt, cursym, p, &p.To, int(o.op[z+1]))
case Zcallindreg: case Zcallindreg:
r = obj.Addrel(cursym) cursym.AddRel(ctxt, obj.Reloc{
r.Off = int32(p.Pc) Type: objabi.R_CALLIND,
r.Type = objabi.R_CALLIND Off: int32(p.Pc),
r.Siz = 0 })
fallthrough fallthrough
case Zo_m64: case Zo_m64:
@ -4724,6 +4715,7 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
ab.Put1(byte(vaddr(ctxt, p, &p.From, nil))) ab.Put1(byte(vaddr(ctxt, p, &p.From, nil)))
case Z_ib, Zib_: case Z_ib, Zib_:
var a *obj.Addr
if yt.zcase == Zib_ { if yt.zcase == Zib_ {
a = &p.From a = &p.From
} else { } else {
@ -4743,7 +4735,7 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
ab.rexflag |= regrex[p.To.Reg] & Rxb ab.rexflag |= regrex[p.To.Reg] & Rxb
ab.Put1(byte(op + reg[p.To.Reg])) ab.Put1(byte(op + reg[p.To.Reg]))
if o.prefix == Pe { if o.prefix == Pe {
v = vaddr(ctxt, p, &p.From, nil) v := vaddr(ctxt, p, &p.From, nil)
ab.PutInt16(int16(v)) ab.PutInt16(int16(v))
} else { } else {
ab.relput4(ctxt, cursym, p, &p.From) ab.relput4(ctxt, cursym, p, &p.From)
@ -4752,22 +4744,22 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
case Zo_iw: case Zo_iw:
ab.Put1(byte(op)) ab.Put1(byte(op))
if p.From.Type != obj.TYPE_NONE { if p.From.Type != obj.TYPE_NONE {
v = vaddr(ctxt, p, &p.From, nil) v := vaddr(ctxt, p, &p.From, nil)
ab.PutInt16(int16(v)) ab.PutInt16(int16(v))
} }
case Ziq_rp: case Ziq_rp:
v = vaddr(ctxt, p, &p.From, &rel) var rel obj.Reloc
l = int(v >> 32) v := vaddr(ctxt, p, &p.From, &rel)
l := int(v >> 32)
if l == 0 && rel.Siz != 8 { if l == 0 && rel.Siz != 8 {
ab.rexflag &^= (0x40 | Rxw) ab.rexflag &^= (0x40 | Rxw)
ab.rexflag |= regrex[p.To.Reg] & Rxb ab.rexflag |= regrex[p.To.Reg] & Rxb
ab.Put1(byte(0xb8 + reg[p.To.Reg])) ab.Put1(byte(0xb8 + reg[p.To.Reg]))
if rel.Type != 0 { if rel.Type != 0 {
r = obj.Addrel(cursym) rel.Off = int32(p.Pc + int64(ab.Len()))
*r = rel cursym.AddRel(ctxt, rel)
r.Off = int32(p.Pc + int64(ab.Len()))
} }
ab.PutInt32(int32(v)) ab.PutInt32(int32(v))
@ -4780,9 +4772,8 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
ab.rexflag |= regrex[p.To.Reg] & Rxb ab.rexflag |= regrex[p.To.Reg] & Rxb
ab.Put1(byte(op + reg[p.To.Reg])) ab.Put1(byte(op + reg[p.To.Reg]))
if rel.Type != 0 { if rel.Type != 0 {
r = obj.Addrel(cursym) rel.Off = int32(p.Pc + int64(ab.Len()))
*r = rel cursym.AddRel(ctxt, rel)
r.Off = int32(p.Pc + int64(ab.Len()))
} }
ab.PutInt64(v) ab.PutInt64(v)
@ -4794,6 +4785,7 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
ab.Put1(byte(vaddr(ctxt, p, &p.From, nil))) ab.Put1(byte(vaddr(ctxt, p, &p.From, nil)))
case Z_il, Zil_: case Z_il, Zil_:
var a *obj.Addr
if yt.zcase == Zil_ { if yt.zcase == Zil_ {
a = &p.From a = &p.From
} else { } else {
@ -4801,13 +4793,14 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
} }
ab.Put1(byte(op)) ab.Put1(byte(op))
if o.prefix == Pe { if o.prefix == Pe {
v = vaddr(ctxt, p, a, nil) v := vaddr(ctxt, p, a, nil)
ab.PutInt16(int16(v)) ab.PutInt16(int16(v))
} else { } else {
ab.relput4(ctxt, cursym, p, a) ab.relput4(ctxt, cursym, p, a)
} }
case Zm_ilo, Zilo_m: case Zm_ilo, Zilo_m:
var a *obj.Addr
ab.Put1(byte(op)) ab.Put1(byte(op))
if yt.zcase == Zilo_m { if yt.zcase == Zilo_m {
a = &p.From a = &p.From
@ -4818,7 +4811,7 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
} }
if o.prefix == Pe { if o.prefix == Pe {
v = vaddr(ctxt, p, a, nil) v := vaddr(ctxt, p, a, nil)
ab.PutInt16(int16(v)) ab.PutInt16(int16(v))
} else { } else {
ab.relput4(ctxt, cursym, p, a) ab.relput4(ctxt, cursym, p, a)
@ -4828,7 +4821,7 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
ab.Put1(byte(op)) ab.Put1(byte(op))
ab.asmand(ctxt, cursym, p, &p.To, &p.To) ab.asmand(ctxt, cursym, p, &p.To, &p.To)
if o.prefix == Pe { if o.prefix == Pe {
v = vaddr(ctxt, p, &p.From, nil) v := vaddr(ctxt, p, &p.From, nil)
ab.PutInt16(int16(v)) ab.PutInt16(int16(v))
} else { } else {
ab.relput4(ctxt, cursym, p, &p.From) ab.relput4(ctxt, cursym, p, &p.From)
@ -4848,25 +4841,27 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
} else { } else {
ab.Put1(o.op[z+1]) ab.Put1(o.op[z+1])
} }
r = obj.Addrel(cursym) cursym.AddRel(ctxt, obj.Reloc{
r.Off = int32(p.Pc + int64(ab.Len())) Type: objabi.R_PCREL,
r.Type = objabi.R_PCREL Off: int32(p.Pc + int64(ab.Len())),
r.Siz = 4 Siz: 4,
r.Add = p.To.Offset Add: p.To.Offset,
})
ab.PutInt32(0) ab.PutInt32(0)
case Zcallind: case Zcallind:
ab.Put2(byte(op), o.op[z+1]) ab.Put2(byte(op), o.op[z+1])
r = obj.Addrel(cursym) typ := objabi.R_ADDR
r.Off = int32(p.Pc + int64(ab.Len()))
if ctxt.Arch.Family == sys.AMD64 { if ctxt.Arch.Family == sys.AMD64 {
r.Type = objabi.R_PCREL typ = objabi.R_PCREL
} else {
r.Type = objabi.R_ADDR
} }
r.Siz = 4 cursym.AddRel(ctxt, obj.Reloc{
r.Add = p.To.Offset Type: typ,
r.Sym = p.To.Sym Off: int32(p.Pc + int64(ab.Len())),
Siz: 4,
Sym: p.To.Sym,
Add: p.To.Offset,
})
ab.PutInt32(0) ab.PutInt32(0)
case Zcall, Zcallduff: case Zcall, Zcallduff:
@ -4891,12 +4886,13 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
ab.Put(bpduff1) ab.Put(bpduff1)
} }
ab.Put1(byte(op)) ab.Put1(byte(op))
r = obj.Addrel(cursym) cursym.AddRel(ctxt, obj.Reloc{
r.Off = int32(p.Pc + int64(ab.Len())) Type: objabi.R_CALL,
r.Sym = p.To.Sym Off: int32(p.Pc + int64(ab.Len())),
r.Add = p.To.Offset Siz: 4,
r.Type = objabi.R_CALL Sym: p.To.Sym,
r.Siz = 4 Add: p.To.Offset,
})
ab.PutInt32(0) ab.PutInt32(0)
if yt.zcase == Zcallduff && ctxt.Arch.Family == sys.AMD64 { if yt.zcase == Zcallduff && ctxt.Arch.Family == sys.AMD64 {
@ -4918,13 +4914,14 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
} }
ab.Put1(o.op[z+1]) ab.Put1(o.op[z+1])
r = obj.Addrel(cursym) cursym.AddRel(ctxt, obj.Reloc{
r.Off = int32(p.Pc + int64(ab.Len())) // Note: R_CALL instead of R_PCREL. R_CALL is more permissive in that
r.Sym = p.To.Sym // it can point to a trampoline instead of the destination itself.
// Note: R_CALL instead of R_PCREL. R_CALL is more permissive in that Type: objabi.R_CALL,
// it can point to a trampoline instead of the destination itself. Off: int32(p.Pc + int64(ab.Len())),
r.Type = objabi.R_CALL Siz: 4,
r.Siz = 4 Sym: p.To.Sym,
})
ab.PutInt32(0) ab.PutInt32(0)
break break
} }
@ -4933,7 +4930,7 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
// TODO: Check in input, preserve in brchain. // TODO: Check in input, preserve in brchain.
// Fill in backward jump now. // Fill in backward jump now.
q = p.To.Target() q := p.To.Target()
if q == nil { if q == nil {
ctxt.Diag("jmp/branch/loop without target") ctxt.Diag("jmp/branch/loop without target")
@ -4942,7 +4939,7 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
} }
if p.Back&branchBackwards != 0 { if p.Back&branchBackwards != 0 {
v = q.Pc - (p.Pc + 2) v := q.Pc - (p.Pc + 2)
if v >= -128 && p.As != AXBEGIN { if v >= -128 && p.As != AXBEGIN {
if p.As == AJCXZL { if p.As == AJCXZL {
ab.Put1(0x67) ab.Put1(0x67)
@ -4987,12 +4984,12 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
} }
case Zbyte: case Zbyte:
v = vaddr(ctxt, p, &p.From, &rel) var rel obj.Reloc
v := vaddr(ctxt, p, &p.From, &rel)
if rel.Siz != 0 { if rel.Siz != 0 {
rel.Siz = uint8(op) rel.Siz = uint8(op)
r = obj.Addrel(cursym) rel.Off = int32(p.Pc + int64(ab.Len()))
*r = rel cursym.AddRel(ctxt, rel)
r.Off = int32(p.Pc + int64(ab.Len()))
} }
ab.Put1(byte(v)) ab.Put1(byte(v))
@ -5138,19 +5135,21 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
// instruction. // instruction.
dst := p.To.Reg dst := p.To.Reg
ab.Put1(0xe8) ab.Put1(0xe8)
r = obj.Addrel(cursym) cursym.AddRel(ctxt, obj.Reloc{
r.Off = int32(p.Pc + int64(ab.Len())) Type: objabi.R_CALL,
r.Type = objabi.R_CALL Off: int32(p.Pc + int64(ab.Len())),
r.Siz = 4 Siz: 4,
r.Sym = ctxt.Lookup("__x86.get_pc_thunk." + strings.ToLower(rconv(int(dst)))) Sym: ctxt.Lookup("__x86.get_pc_thunk." + strings.ToLower(rconv(int(dst)))),
})
ab.PutInt32(0) ab.PutInt32(0)
ab.Put2(0x8B, byte(2<<6|reg[dst]|(reg[dst]<<3))) ab.Put2(0x8B, byte(2<<6|reg[dst]|(reg[dst]<<3)))
r = obj.Addrel(cursym) cursym.AddRel(ctxt, obj.Reloc{
r.Off = int32(p.Pc + int64(ab.Len())) Type: objabi.R_TLS_IE,
r.Type = objabi.R_TLS_IE Off: int32(p.Pc + int64(ab.Len())),
r.Siz = 4 Siz: 4,
r.Add = 2 Add: 2,
})
ab.PutInt32(0) ab.PutInt32(0)
} else { } else {
// ELF TLS base is 0(GS). // ELF TLS base is 0(GS).
@ -5198,11 +5197,12 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
ab.rexflag = Pw | (regrex[p.To.Reg] & Rxr) ab.rexflag = Pw | (regrex[p.To.Reg] & Rxr)
ab.Put2(0x8B, byte(0x05|(reg[p.To.Reg]<<3))) ab.Put2(0x8B, byte(0x05|(reg[p.To.Reg]<<3)))
r = obj.Addrel(cursym) cursym.AddRel(ctxt, obj.Reloc{
r.Off = int32(p.Pc + int64(ab.Len())) Type: objabi.R_TLS_IE,
r.Type = objabi.R_TLS_IE Off: int32(p.Pc + int64(ab.Len())),
r.Siz = 4 Siz: 4,
r.Add = -4 Add: -4,
})
ab.PutInt32(0) ab.PutInt32(0)
case objabi.Hplan9: case objabi.Hplan9:

View file

@ -153,11 +153,12 @@ func populateSeh(ctxt *obj.Link, s *obj.LSym) (sehsym *obj.LSym) {
s.Set(obj.AttrLocal, true) s.Set(obj.AttrLocal, true)
s.Set(obj.AttrContentAddressable, true) s.Set(obj.AttrContentAddressable, true)
if exceptionHandler != nil { if exceptionHandler != nil {
r := obj.Addrel(s) s.AddRel(ctxt, obj.Reloc{
r.Off = int32(len(buf.data) - 4) Type: objabi.R_PEIMAGEOFF,
r.Siz = 4 Off: int32(len(buf.data) - 4),
r.Sym = exceptionHandler Siz: 4,
r.Type = objabi.R_PEIMAGEOFF Sym: exceptionHandler,
})
} }
ctxt.SEHSyms = append(ctxt.SEHSyms, s) ctxt.SEHSyms = append(ctxt.SEHSyms, s)
}) })