mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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:
parent
4ce8c0604e
commit
5b20eec8a0
25 changed files with 614 additions and 573 deletions
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
|
|
@ -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]
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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() {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue