mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/5g etc: mechanical cleanup
Run rsc.io/grind rev a26569f on C->Go conversions. The new change in grind is the inlining of goto targets. If code says 'goto x' and the block starting at label x is unreachable except through that goto and the code can be moved to where the goto is without changing the meaning of its variable names, grind does that move. Simlarly, a goto to a plain return statement turns into that return statement (even if there are other paths to the return statement). Combined, these remove many long-distance gotos, which in turn makes it possible to reduce the scope of more variable declarations. (Because gotos can't jump across declarations, the gotos were keeping the declarations from moving.) Checked bit-for-bit compatibility with toolstash + buildall. Reduces compiler runtime in html/template by about 12%. Change-Id: Id727c0bd7763a61aa22f3daa00aeb8fccbc057a3 Reviewed-on: https://go-review.googlesource.com/6472 Reviewed-by: Aram Hăvărneanu <aram@mgk.ro> Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
This commit is contained in:
parent
190357d560
commit
79f727a70e
67 changed files with 4118 additions and 5445 deletions
|
|
@ -25,15 +25,8 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
gc.Dump("cgen-res", res)
|
gc.Dump("cgen-res", res)
|
||||||
}
|
}
|
||||||
|
|
||||||
var n1 gc.Node
|
|
||||||
var nr *gc.Node
|
|
||||||
var nl *gc.Node
|
|
||||||
var a int
|
|
||||||
var f1 gc.Node
|
|
||||||
var f0 gc.Node
|
|
||||||
var n2 gc.Node
|
|
||||||
if n == nil || n.Type == nil {
|
if n == nil || n.Type == nil {
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if res == nil || res.Type == nil {
|
if res == nil || res.Type == nil {
|
||||||
|
|
@ -81,7 +74,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
gc.Tempname(&n1, n.Type)
|
gc.Tempname(&n1, n.Type)
|
||||||
cgen(n, &n1)
|
cgen(n, &n1)
|
||||||
cgen(&n1, res)
|
cgen(&n1, res)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,7 +83,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
gc.Fatal("forgot to compute width for %v", gc.Tconv(n.Type, 0))
|
gc.Fatal("forgot to compute width for %v", gc.Tconv(n.Type, 0))
|
||||||
}
|
}
|
||||||
sgen(n, res, n.Type.Width)
|
sgen(n, res, n.Type.Width)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// update addressability for string, slice
|
// update addressability for string, slice
|
||||||
|
|
@ -124,7 +117,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
regfree(&n1)
|
regfree(&n1)
|
||||||
}
|
}
|
||||||
|
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// if both are not addressable, use a temporary.
|
// if both are not addressable, use a temporary.
|
||||||
|
|
@ -179,16 +172,16 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sudoclean()
|
sudoclean()
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, the result is addressable but n is not.
|
// otherwise, the result is addressable but n is not.
|
||||||
// let's do some computation.
|
// let's do some computation.
|
||||||
|
|
||||||
nl = n.Left
|
nl := n.Left
|
||||||
|
|
||||||
nr = n.Right
|
nr := n.Right
|
||||||
|
|
||||||
if nl != nil && nl.Ullman >= gc.UINF {
|
if nl != nil && nl.Ullman >= gc.UINF {
|
||||||
if nr != nil && nr.Ullman >= gc.UINF {
|
if nr != nil && nr.Ullman >= gc.UINF {
|
||||||
|
|
@ -198,7 +191,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
n2 := *n
|
n2 := *n
|
||||||
n2.Left = &n1
|
n2.Left = &n1
|
||||||
cgen(&n2, res)
|
cgen(&n2, res)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -223,8 +216,34 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var a int
|
||||||
|
var f0 gc.Node
|
||||||
|
var n1 gc.Node
|
||||||
|
var n2 gc.Node
|
||||||
if nl != nil && gc.Isfloat[n.Type.Etype] != 0 && gc.Isfloat[nl.Type.Etype] != 0 {
|
if nl != nil && gc.Isfloat[n.Type.Etype] != 0 && gc.Isfloat[nl.Type.Etype] != 0 {
|
||||||
goto flt
|
// floating-point.
|
||||||
|
regalloc(&f0, nl.Type, res)
|
||||||
|
|
||||||
|
if nr != nil {
|
||||||
|
goto flt2
|
||||||
|
}
|
||||||
|
|
||||||
|
if n.Op == gc.OMINUS {
|
||||||
|
nr = gc.Nodintconst(-1)
|
||||||
|
gc.Convlit(&nr, n.Type)
|
||||||
|
n.Op = gc.OMUL
|
||||||
|
goto flt2
|
||||||
|
}
|
||||||
|
|
||||||
|
// unary
|
||||||
|
cgen(nl, &f0)
|
||||||
|
|
||||||
|
if n.Op != gc.OCONV && n.Op != gc.OPLUS {
|
||||||
|
gins(optoas(int(n.Op), n.Type), &f0, &f0)
|
||||||
|
}
|
||||||
|
gmove(&f0, res)
|
||||||
|
regfree(&f0)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
|
|
@ -255,11 +274,11 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
bgen(n, true, 0, p2)
|
bgen(n, true, 0, p2)
|
||||||
gmove(gc.Nodbool(false), res)
|
gmove(gc.Nodbool(false), res)
|
||||||
gc.Patch(p3, gc.Pc)
|
gc.Patch(p3, gc.Pc)
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
case gc.OPLUS:
|
case gc.OPLUS:
|
||||||
cgen(nl, res)
|
cgen(nl, res)
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
// unary
|
// unary
|
||||||
case gc.OCOM:
|
case gc.OCOM:
|
||||||
|
|
@ -286,7 +305,13 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
gc.OMUL:
|
gc.OMUL:
|
||||||
a = optoas(int(n.Op), nl.Type)
|
a = optoas(int(n.Op), nl.Type)
|
||||||
|
|
||||||
goto sbop
|
// symmetric binary
|
||||||
|
if nl.Ullman < nr.Ullman {
|
||||||
|
r := nl
|
||||||
|
nl = nr
|
||||||
|
nr = r
|
||||||
|
}
|
||||||
|
goto abop
|
||||||
|
|
||||||
// asymmetric binary
|
// asymmetric binary
|
||||||
case gc.OSUB:
|
case gc.OSUB:
|
||||||
|
|
@ -489,14 +514,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
goto abop
|
goto abop
|
||||||
}
|
}
|
||||||
|
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
sbop: // symmetric binary
|
|
||||||
if nl.Ullman < nr.Ullman {
|
|
||||||
r := nl
|
|
||||||
nl = nr
|
|
||||||
nr = r
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(kaib): use fewer registers here.
|
// TODO(kaib): use fewer registers here.
|
||||||
abop: // asymmetric binary
|
abop: // asymmetric binary
|
||||||
|
|
@ -561,33 +579,10 @@ norm:
|
||||||
if n2.Op != gc.OLITERAL {
|
if n2.Op != gc.OLITERAL {
|
||||||
regfree(&n2)
|
regfree(&n2)
|
||||||
}
|
}
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
flt: // floating-point.
|
|
||||||
regalloc(&f0, nl.Type, res)
|
|
||||||
|
|
||||||
if nr != nil {
|
|
||||||
goto flt2
|
|
||||||
}
|
|
||||||
|
|
||||||
if n.Op == gc.OMINUS {
|
|
||||||
nr = gc.Nodintconst(-1)
|
|
||||||
gc.Convlit(&nr, n.Type)
|
|
||||||
n.Op = gc.OMUL
|
|
||||||
goto flt2
|
|
||||||
}
|
|
||||||
|
|
||||||
// unary
|
|
||||||
cgen(nl, &f0)
|
|
||||||
|
|
||||||
if n.Op != gc.OCONV && n.Op != gc.OPLUS {
|
|
||||||
gins(optoas(int(n.Op), n.Type), &f0, &f0)
|
|
||||||
}
|
|
||||||
gmove(&f0, res)
|
|
||||||
regfree(&f0)
|
|
||||||
goto ret
|
|
||||||
|
|
||||||
flt2: // binary
|
flt2: // binary
|
||||||
|
var f1 gc.Node
|
||||||
if nl.Ullman >= nr.Ullman {
|
if nl.Ullman >= nr.Ullman {
|
||||||
cgen(nl, &f0)
|
cgen(nl, &f0)
|
||||||
regalloc(&f1, n.Type, nil)
|
regalloc(&f1, n.Type, nil)
|
||||||
|
|
@ -604,9 +599,7 @@ flt2: // binary
|
||||||
gmove(&f1, res)
|
gmove(&f1, res)
|
||||||
regfree(&f0)
|
regfree(&f0)
|
||||||
regfree(&f1)
|
regfree(&f1)
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
ret:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -666,7 +659,6 @@ func agen(n *gc.Node, res *gc.Node) {
|
||||||
n = n.Left
|
n = n.Left
|
||||||
}
|
}
|
||||||
|
|
||||||
var nl *gc.Node
|
|
||||||
if gc.Isconst(n, gc.CTNIL) && n.Type.Width > int64(gc.Widthptr) {
|
if gc.Isconst(n, gc.CTNIL) && n.Type.Width > int64(gc.Widthptr) {
|
||||||
// Use of a nil interface or nil slice.
|
// Use of a nil interface or nil slice.
|
||||||
// Create a temporary we can take the address of and read.
|
// Create a temporary we can take the address of and read.
|
||||||
|
|
@ -682,7 +674,7 @@ func agen(n *gc.Node, res *gc.Node) {
|
||||||
gins(arm.AMOVW, &n1, &n2)
|
gins(arm.AMOVW, &n1, &n2)
|
||||||
gmove(&n2, res)
|
gmove(&n2, res)
|
||||||
regfree(&n2)
|
regfree(&n2)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Addable != 0 {
|
if n.Addable != 0 {
|
||||||
|
|
@ -694,10 +686,10 @@ func agen(n *gc.Node, res *gc.Node) {
|
||||||
gins(arm.AMOVW, &n1, &n2)
|
gins(arm.AMOVW, &n1, &n2)
|
||||||
gmove(&n2, res)
|
gmove(&n2, res)
|
||||||
regfree(&n2)
|
regfree(&n2)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
nl = n.Left
|
nl := n.Left
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
|
|
@ -820,8 +812,6 @@ func agen(n *gc.Node, res *gc.Node) {
|
||||||
regfree(&n3)
|
regfree(&n3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1195,25 +1185,23 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
gc.Genlist(n.Ninit)
|
gc.Genlist(n.Ninit)
|
||||||
}
|
}
|
||||||
|
|
||||||
var et int
|
|
||||||
var nl *gc.Node
|
|
||||||
var nr *gc.Node
|
|
||||||
if n.Type == nil {
|
if n.Type == nil {
|
||||||
gc.Convlit(&n, gc.Types[gc.TBOOL])
|
gc.Convlit(&n, gc.Types[gc.TBOOL])
|
||||||
if n.Type == nil {
|
if n.Type == nil {
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
et = int(n.Type.Etype)
|
et := int(n.Type.Etype)
|
||||||
if et != gc.TBOOL {
|
if et != gc.TBOOL {
|
||||||
gc.Yyerror("cgen: bad type %v for %v", gc.Tconv(n.Type, 0), gc.Oconv(int(n.Op), 0))
|
gc.Yyerror("cgen: bad type %v for %v", gc.Tconv(n.Type, 0), gc.Oconv(int(n.Op), 0))
|
||||||
gc.Patch(gins(obj.AEND, nil, nil), to)
|
gc.Patch(gins(obj.AEND, nil, nil), to)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
nr = nil
|
nr := (*gc.Node)(nil)
|
||||||
|
|
||||||
|
var nl *gc.Node
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
a := gc.ONE
|
a := gc.ONE
|
||||||
|
|
@ -1221,14 +1209,14 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
a = gc.OEQ
|
a = gc.OEQ
|
||||||
}
|
}
|
||||||
gencmp0(n, n.Type, a, likely, to)
|
gencmp0(n, n.Type, a, likely, to)
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
// need to ask if it is bool?
|
// need to ask if it is bool?
|
||||||
case gc.OLITERAL:
|
case gc.OLITERAL:
|
||||||
if !true_ == (n.Val.U.Bval == 0) {
|
if !true_ == (n.Val.U.Bval == 0) {
|
||||||
gc.Patch(gc.Gbranch(arm.AB, nil, 0), to)
|
gc.Patch(gc.Gbranch(arm.AB, nil, 0), to)
|
||||||
}
|
}
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
case gc.OANDAND,
|
case gc.OANDAND,
|
||||||
gc.OOROR:
|
gc.OOROR:
|
||||||
|
|
@ -1246,7 +1234,7 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
bgen(n.Right, true_, likely, to)
|
bgen(n.Right, true_, likely, to)
|
||||||
}
|
}
|
||||||
|
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
case gc.OEQ,
|
case gc.OEQ,
|
||||||
gc.ONE,
|
gc.ONE,
|
||||||
|
|
@ -1256,7 +1244,7 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
gc.OGE:
|
gc.OGE:
|
||||||
nr = n.Right
|
nr = n.Right
|
||||||
if nr == nil || nr.Type == nil {
|
if nr == nil || nr.Type == nil {
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
||||||
|
|
@ -1264,14 +1252,14 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
nl = n.Left
|
nl = n.Left
|
||||||
|
|
||||||
if nl == nil || nl.Type == nil {
|
if nl == nil || nl.Type == nil {
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
case gc.ONOT:
|
case gc.ONOT:
|
||||||
bgen(nl, !true_, likely, to)
|
bgen(nl, !true_, likely, to)
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
case gc.OEQ,
|
case gc.OEQ,
|
||||||
gc.ONE,
|
gc.ONE,
|
||||||
|
|
@ -1293,7 +1281,7 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
n.Ninit = ll
|
n.Ninit = ll
|
||||||
gc.Patch(gc.Gbranch(arm.AB, nil, 0), to)
|
gc.Patch(gc.Gbranch(arm.AB, nil, 0), to)
|
||||||
gc.Patch(p2, gc.Pc)
|
gc.Patch(p2, gc.Pc)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
a = gc.Brcom(a)
|
a = gc.Brcom(a)
|
||||||
|
|
@ -1438,9 +1426,7 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
regfree(&n2)
|
regfree(&n2)
|
||||||
}
|
}
|
||||||
|
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
ret:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -329,7 +329,7 @@ func cgen_call(n *gc.Node, proc int) {
|
||||||
nod.Type = t
|
nod.Type = t
|
||||||
ginscall(&nod, proc)
|
ginscall(&nod, proc)
|
||||||
regfree(&nod)
|
regfree(&nod)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// call pointer
|
// call pointer
|
||||||
|
|
@ -340,15 +340,13 @@ func cgen_call(n *gc.Node, proc int) {
|
||||||
nod.Type = t
|
nod.Type = t
|
||||||
ginscall(&nod, proc)
|
ginscall(&nod, proc)
|
||||||
regfree(&nod)
|
regfree(&nod)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// call direct
|
// call direct
|
||||||
n.Left.Method = 1
|
n.Left.Method = 1
|
||||||
|
|
||||||
ginscall(n.Left, proc)
|
ginscall(n.Left, proc)
|
||||||
|
|
||||||
ret:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -331,10 +331,8 @@ func gmove(f *gc.Node, t *gc.Node) {
|
||||||
|
|
||||||
// cannot have two memory operands;
|
// cannot have two memory operands;
|
||||||
// except 64-bit, which always copies via registers anyway.
|
// except 64-bit, which always copies via registers anyway.
|
||||||
var flo gc.Node
|
|
||||||
var a int
|
var a int
|
||||||
var r1 gc.Node
|
var r1 gc.Node
|
||||||
var fhi gc.Node
|
|
||||||
if !gc.Is64(f.Type) && !gc.Is64(t.Type) && gc.Ismem(f) && gc.Ismem(t) {
|
if !gc.Is64(f.Type) && !gc.Is64(t.Type) && gc.Ismem(f) && gc.Ismem(t) {
|
||||||
goto hard
|
goto hard
|
||||||
}
|
}
|
||||||
|
|
@ -387,7 +385,9 @@ func gmove(f *gc.Node, t *gc.Node) {
|
||||||
|
|
||||||
switch uint32(ft)<<16 | uint32(tt) {
|
switch uint32(ft)<<16 | uint32(tt) {
|
||||||
default:
|
default:
|
||||||
goto fatal
|
// should not happen
|
||||||
|
gc.Fatal("gmove %v -> %v", gc.Nconv(f, 0), gc.Nconv(t, 0))
|
||||||
|
return
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* integer copy and truncate
|
* integer copy and truncate
|
||||||
|
|
@ -784,6 +784,8 @@ hard:
|
||||||
|
|
||||||
// truncate 64 bit integer
|
// truncate 64 bit integer
|
||||||
trunc64:
|
trunc64:
|
||||||
|
var fhi gc.Node
|
||||||
|
var flo gc.Node
|
||||||
split64(f, &flo, &fhi)
|
split64(f, &flo, &fhi)
|
||||||
|
|
||||||
regalloc(&r1, t.Type, nil)
|
regalloc(&r1, t.Type, nil)
|
||||||
|
|
@ -792,10 +794,6 @@ trunc64:
|
||||||
regfree(&r1)
|
regfree(&r1)
|
||||||
splitclean()
|
splitclean()
|
||||||
return
|
return
|
||||||
|
|
||||||
// should not happen
|
|
||||||
fatal:
|
|
||||||
gc.Fatal("gmove %v -> %v", gc.Nconv(f, 0), gc.Nconv(t, 0))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func samaddr(f *gc.Node, t *gc.Node) bool {
|
func samaddr(f *gc.Node, t *gc.Node) bool {
|
||||||
|
|
@ -1273,12 +1271,6 @@ func sudoaddable(as int, n *gc.Node, a *obj.Addr, w *int) bool {
|
||||||
|
|
||||||
*a = obj.Addr{}
|
*a = obj.Addr{}
|
||||||
|
|
||||||
var oary [10]int64
|
|
||||||
var nn *gc.Node
|
|
||||||
var reg *gc.Node
|
|
||||||
var n1 gc.Node
|
|
||||||
var reg1 *gc.Node
|
|
||||||
var o int
|
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
case gc.OLITERAL:
|
case gc.OLITERAL:
|
||||||
if !gc.Isconst(n, gc.CTINT) {
|
if !gc.Isconst(n, gc.CTINT) {
|
||||||
|
|
@ -1288,98 +1280,88 @@ func sudoaddable(as int, n *gc.Node, a *obj.Addr, w *int) bool {
|
||||||
if v >= 32000 || v <= -32000 {
|
if v >= 32000 || v <= -32000 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
goto lit
|
switch as {
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
|
||||||
|
case arm.AADD,
|
||||||
|
arm.ASUB,
|
||||||
|
arm.AAND,
|
||||||
|
arm.AORR,
|
||||||
|
arm.AEOR,
|
||||||
|
arm.AMOVB,
|
||||||
|
arm.AMOVBS,
|
||||||
|
arm.AMOVBU,
|
||||||
|
arm.AMOVH,
|
||||||
|
arm.AMOVHS,
|
||||||
|
arm.AMOVHU,
|
||||||
|
arm.AMOVW:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
cleani += 2
|
||||||
|
reg := &clean[cleani-1]
|
||||||
|
reg1 := &clean[cleani-2]
|
||||||
|
reg.Op = gc.OEMPTY
|
||||||
|
reg1.Op = gc.OEMPTY
|
||||||
|
gc.Naddr(n, a, 1)
|
||||||
|
return true
|
||||||
|
|
||||||
case gc.ODOT,
|
case gc.ODOT,
|
||||||
gc.ODOTPTR:
|
gc.ODOTPTR:
|
||||||
cleani += 2
|
cleani += 2
|
||||||
reg = &clean[cleani-1]
|
reg := &clean[cleani-1]
|
||||||
reg1 := &clean[cleani-2]
|
reg1 := &clean[cleani-2]
|
||||||
reg.Op = gc.OEMPTY
|
reg.Op = gc.OEMPTY
|
||||||
reg1.Op = gc.OEMPTY
|
reg1.Op = gc.OEMPTY
|
||||||
goto odot
|
var nn *gc.Node
|
||||||
|
var oary [10]int64
|
||||||
|
o := gc.Dotoffset(n, oary[:], &nn)
|
||||||
|
if nn == nil {
|
||||||
|
sudoclean()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if nn.Addable != 0 && o == 1 && oary[0] >= 0 {
|
||||||
|
// directly addressable set of DOTs
|
||||||
|
n1 := *nn
|
||||||
|
|
||||||
|
n1.Type = n.Type
|
||||||
|
n1.Xoffset += oary[0]
|
||||||
|
gc.Naddr(&n1, a, 1)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
regalloc(reg, gc.Types[gc.Tptr], nil)
|
||||||
|
n1 := *reg
|
||||||
|
n1.Op = gc.OINDREG
|
||||||
|
if oary[0] >= 0 {
|
||||||
|
agen(nn, reg)
|
||||||
|
n1.Xoffset = oary[0]
|
||||||
|
} else {
|
||||||
|
cgen(nn, reg)
|
||||||
|
gc.Cgen_checknil(reg)
|
||||||
|
n1.Xoffset = -(oary[0] + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 1; i < o; i++ {
|
||||||
|
if oary[i] >= 0 {
|
||||||
|
gc.Fatal("can't happen")
|
||||||
|
}
|
||||||
|
gins(arm.AMOVW, &n1, reg)
|
||||||
|
gc.Cgen_checknil(reg)
|
||||||
|
n1.Xoffset = -(oary[i] + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
a.Type = obj.TYPE_NONE
|
||||||
|
a.Name = obj.NAME_NONE
|
||||||
|
n1.Type = n.Type
|
||||||
|
gc.Naddr(&n1, a, 1)
|
||||||
|
return true
|
||||||
|
|
||||||
case gc.OINDEX:
|
case gc.OINDEX:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|
||||||
lit:
|
|
||||||
switch as {
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
|
|
||||||
case arm.AADD,
|
|
||||||
arm.ASUB,
|
|
||||||
arm.AAND,
|
|
||||||
arm.AORR,
|
|
||||||
arm.AEOR,
|
|
||||||
arm.AMOVB,
|
|
||||||
arm.AMOVBS,
|
|
||||||
arm.AMOVBU,
|
|
||||||
arm.AMOVH,
|
|
||||||
arm.AMOVHS,
|
|
||||||
arm.AMOVHU,
|
|
||||||
arm.AMOVW:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
cleani += 2
|
|
||||||
reg = &clean[cleani-1]
|
|
||||||
reg1 = &clean[cleani-2]
|
|
||||||
reg.Op = gc.OEMPTY
|
|
||||||
reg1.Op = gc.OEMPTY
|
|
||||||
gc.Naddr(n, a, 1)
|
|
||||||
goto yes
|
|
||||||
|
|
||||||
odot:
|
|
||||||
o = gc.Dotoffset(n, oary[:], &nn)
|
|
||||||
if nn == nil {
|
|
||||||
goto no
|
|
||||||
}
|
|
||||||
|
|
||||||
if nn.Addable != 0 && o == 1 && oary[0] >= 0 {
|
|
||||||
// directly addressable set of DOTs
|
|
||||||
n1 := *nn
|
|
||||||
|
|
||||||
n1.Type = n.Type
|
|
||||||
n1.Xoffset += oary[0]
|
|
||||||
gc.Naddr(&n1, a, 1)
|
|
||||||
goto yes
|
|
||||||
}
|
|
||||||
|
|
||||||
regalloc(reg, gc.Types[gc.Tptr], nil)
|
|
||||||
n1 = *reg
|
|
||||||
n1.Op = gc.OINDREG
|
|
||||||
if oary[0] >= 0 {
|
|
||||||
agen(nn, reg)
|
|
||||||
n1.Xoffset = oary[0]
|
|
||||||
} else {
|
|
||||||
cgen(nn, reg)
|
|
||||||
gc.Cgen_checknil(reg)
|
|
||||||
n1.Xoffset = -(oary[0] + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 1; i < o; i++ {
|
|
||||||
if oary[i] >= 0 {
|
|
||||||
gc.Fatal("can't happen")
|
|
||||||
}
|
|
||||||
gins(arm.AMOVW, &n1, reg)
|
|
||||||
gc.Cgen_checknil(reg)
|
|
||||||
n1.Xoffset = -(oary[i] + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
a.Type = obj.TYPE_NONE
|
|
||||||
a.Name = obj.NAME_NONE
|
|
||||||
n1.Type = n.Type
|
|
||||||
gc.Naddr(&n1, a, 1)
|
|
||||||
goto yes
|
|
||||||
|
|
||||||
yes:
|
|
||||||
return true
|
|
||||||
|
|
||||||
no:
|
|
||||||
sudoclean()
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -257,9 +257,8 @@ func subprop(r0 *gc.Flow) bool {
|
||||||
if !regtyp(v2) {
|
if !regtyp(v2) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
var r *gc.Flow
|
|
||||||
var info gc.ProgInfo
|
var info gc.ProgInfo
|
||||||
for r = gc.Uniqp(r0); r != nil; r = gc.Uniqp(r) {
|
for r := gc.Uniqp(r0); r != nil; r = gc.Uniqp(r) {
|
||||||
if gc.Uniqs(r) == nil {
|
if gc.Uniqs(r) == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -289,7 +288,32 @@ func subprop(r0 *gc.Flow) bool {
|
||||||
if p.To.Type == v1.Type {
|
if p.To.Type == v1.Type {
|
||||||
if p.To.Reg == v1.Reg {
|
if p.To.Reg == v1.Reg {
|
||||||
if p.Scond == arm.C_SCOND_NONE {
|
if p.Scond == arm.C_SCOND_NONE {
|
||||||
goto gotit
|
copysub(&p.To, v1, v2, 1)
|
||||||
|
if gc.Debug['P'] != 0 {
|
||||||
|
fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
|
||||||
|
if p.From.Type == v2.Type {
|
||||||
|
fmt.Printf(" excise")
|
||||||
|
}
|
||||||
|
fmt.Printf("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
|
||||||
|
p = r.Prog
|
||||||
|
copysub(&p.From, v1, v2, 1)
|
||||||
|
copysub1(p, v1, v2, 1)
|
||||||
|
copysub(&p.To, v1, v2, 1)
|
||||||
|
if gc.Debug['P'] != 0 {
|
||||||
|
fmt.Printf("%v\n", r.Prog)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t := int(int(v1.Reg))
|
||||||
|
v1.Reg = v2.Reg
|
||||||
|
v2.Reg = int16(t)
|
||||||
|
if gc.Debug['P'] != 0 {
|
||||||
|
fmt.Printf("%v last\n", r.Prog)
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -304,34 +328,6 @@ func subprop(r0 *gc.Flow) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|
||||||
gotit:
|
|
||||||
copysub(&p.To, v1, v2, 1)
|
|
||||||
if gc.Debug['P'] != 0 {
|
|
||||||
fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
|
|
||||||
if p.From.Type == v2.Type {
|
|
||||||
fmt.Printf(" excise")
|
|
||||||
}
|
|
||||||
fmt.Printf("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
|
|
||||||
p = r.Prog
|
|
||||||
copysub(&p.From, v1, v2, 1)
|
|
||||||
copysub1(p, v1, v2, 1)
|
|
||||||
copysub(&p.To, v1, v2, 1)
|
|
||||||
if gc.Debug['P'] != 0 {
|
|
||||||
fmt.Printf("%v\n", r.Prog)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
t := int(int(v1.Reg))
|
|
||||||
v1.Reg = v2.Reg
|
|
||||||
v2.Reg = int16(t)
|
|
||||||
if gc.Debug['P'] != 0 {
|
|
||||||
fmt.Printf("%v last\n", r.Prog)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -38,17 +38,14 @@ import (
|
||||||
import "cmd/internal/ld"
|
import "cmd/internal/ld"
|
||||||
|
|
||||||
func needlib(name string) int {
|
func needlib(name string) int {
|
||||||
var p string
|
|
||||||
var s *ld.LSym
|
|
||||||
|
|
||||||
if name[0] == '\x00' {
|
if name[0] == '\x00' {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reuse hash code in symbol table */
|
/* reuse hash code in symbol table */
|
||||||
p = fmt.Sprintf(".dynlib.%s", name)
|
p := fmt.Sprintf(".dynlib.%s", name)
|
||||||
|
|
||||||
s = ld.Linklookup(ld.Ctxt, p, 0)
|
s := ld.Linklookup(ld.Ctxt, p, 0)
|
||||||
|
|
||||||
if s.Type == 0 {
|
if s.Type == 0 {
|
||||||
s.Type = 100 // avoid SDATA, etc.
|
s.Type = 100 // avoid SDATA, etc.
|
||||||
|
|
@ -73,10 +70,7 @@ func adddynrela(rel *ld.LSym, s *ld.LSym, r *ld.Reloc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
||||||
var targ *ld.LSym
|
targ := r.Sym
|
||||||
var rel *ld.LSym
|
|
||||||
|
|
||||||
targ = r.Sym
|
|
||||||
ld.Ctxt.Cursym = s
|
ld.Ctxt.Cursym = s
|
||||||
|
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
|
|
@ -203,7 +197,7 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
||||||
}
|
}
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
adddynsym(ld.Ctxt, targ)
|
adddynsym(ld.Ctxt, targ)
|
||||||
rel = ld.Linklookup(ld.Ctxt, ".rel", 0)
|
rel := ld.Linklookup(ld.Ctxt, ".rel", 0)
|
||||||
ld.Addaddrplus(ld.Ctxt, rel, s, int64(r.Off))
|
ld.Addaddrplus(ld.Ctxt, rel, s, int64(r.Off))
|
||||||
ld.Adduint32(ld.Ctxt, rel, ld.ELF32_R_INFO(uint32(targ.Dynid), ld.R_ARM_GLOB_DAT)) // we need a nil + A dynmic reloc
|
ld.Adduint32(ld.Ctxt, rel, ld.ELF32_R_INFO(uint32(targ.Dynid), ld.R_ARM_GLOB_DAT)) // we need a nil + A dynmic reloc
|
||||||
r.Type = ld.R_CONST // write r->add during relocsym
|
r.Type = ld.R_CONST // write r->add during relocsym
|
||||||
|
|
@ -217,11 +211,9 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfreloc1(r *ld.Reloc, sectoff int64) int {
|
func elfreloc1(r *ld.Reloc, sectoff int64) int {
|
||||||
var elfsym int32
|
|
||||||
|
|
||||||
ld.Thearch.Lput(uint32(sectoff))
|
ld.Thearch.Lput(uint32(sectoff))
|
||||||
|
|
||||||
elfsym = r.Xsym.Elfsym
|
elfsym := r.Xsym.Elfsym
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
default:
|
default:
|
||||||
return -1
|
return -1
|
||||||
|
|
@ -267,11 +259,8 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfsetupplt() {
|
func elfsetupplt() {
|
||||||
var plt *ld.LSym
|
plt := ld.Linklookup(ld.Ctxt, ".plt", 0)
|
||||||
var got *ld.LSym
|
got := ld.Linklookup(ld.Ctxt, ".got.plt", 0)
|
||||||
|
|
||||||
plt = ld.Linklookup(ld.Ctxt, ".plt", 0)
|
|
||||||
got = ld.Linklookup(ld.Ctxt, ".got.plt", 0)
|
|
||||||
if plt.Size == 0 {
|
if plt.Size == 0 {
|
||||||
// str lr, [sp, #-4]!
|
// str lr, [sp, #-4]!
|
||||||
ld.Adduint32(ld.Ctxt, plt, 0xe52de004)
|
ld.Adduint32(ld.Ctxt, plt, 0xe52de004)
|
||||||
|
|
@ -298,9 +287,8 @@ func elfsetupplt() {
|
||||||
|
|
||||||
func machoreloc1(r *ld.Reloc, sectoff int64) int {
|
func machoreloc1(r *ld.Reloc, sectoff int64) int {
|
||||||
var v uint32
|
var v uint32
|
||||||
var rs *ld.LSym
|
|
||||||
|
|
||||||
rs = r.Xsym
|
rs := r.Xsym
|
||||||
|
|
||||||
if rs.Type == ld.SHOSTOBJ || r.Type == ld.R_CALLARM {
|
if rs.Type == ld.SHOSTOBJ || r.Type == ld.R_CALLARM {
|
||||||
if rs.Dynid < 0 {
|
if rs.Dynid < 0 {
|
||||||
|
|
@ -353,15 +341,13 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
|
func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
|
||||||
var rs *ld.LSym
|
|
||||||
|
|
||||||
if ld.Linkmode == ld.LinkExternal {
|
if ld.Linkmode == ld.LinkExternal {
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
case ld.R_CALLARM:
|
case ld.R_CALLARM:
|
||||||
r.Done = 0
|
r.Done = 0
|
||||||
|
|
||||||
// set up addend for eventual relocation via outer symbol.
|
// set up addend for eventual relocation via outer symbol.
|
||||||
rs = r.Sym
|
rs := r.Sym
|
||||||
|
|
||||||
r.Xadd = r.Add
|
r.Xadd = r.Add
|
||||||
if r.Xadd&0x800000 != 0 {
|
if r.Xadd&0x800000 != 0 {
|
||||||
|
|
@ -437,9 +423,7 @@ func archrelocvariant(r *ld.Reloc, s *ld.LSym, t int64) int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func addpltreloc(ctxt *ld.Link, plt *ld.LSym, got *ld.LSym, sym *ld.LSym, typ int) *ld.Reloc {
|
func addpltreloc(ctxt *ld.Link, plt *ld.LSym, got *ld.LSym, sym *ld.LSym, typ int) *ld.Reloc {
|
||||||
var r *ld.Reloc
|
r := ld.Addrel(plt)
|
||||||
|
|
||||||
r = ld.Addrel(plt)
|
|
||||||
r.Sym = got
|
r.Sym = got
|
||||||
r.Off = int32(plt.Size)
|
r.Off = int32(plt.Size)
|
||||||
r.Siz = 4
|
r.Siz = 4
|
||||||
|
|
@ -454,10 +438,6 @@ func addpltreloc(ctxt *ld.Link, plt *ld.LSym, got *ld.LSym, sym *ld.LSym, typ in
|
||||||
}
|
}
|
||||||
|
|
||||||
func addpltsym(ctxt *ld.Link, s *ld.LSym) {
|
func addpltsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
var plt *ld.LSym
|
|
||||||
var got *ld.LSym
|
|
||||||
var rel *ld.LSym
|
|
||||||
|
|
||||||
if s.Plt >= 0 {
|
if s.Plt >= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -465,9 +445,9 @@ func addpltsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
adddynsym(ctxt, s)
|
adddynsym(ctxt, s)
|
||||||
|
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
plt = ld.Linklookup(ctxt, ".plt", 0)
|
plt := ld.Linklookup(ctxt, ".plt", 0)
|
||||||
got = ld.Linklookup(ctxt, ".got.plt", 0)
|
got := ld.Linklookup(ctxt, ".got.plt", 0)
|
||||||
rel = ld.Linklookup(ctxt, ".rel.plt", 0)
|
rel := ld.Linklookup(ctxt, ".rel.plt", 0)
|
||||||
if plt.Size == 0 {
|
if plt.Size == 0 {
|
||||||
elfsetupplt()
|
elfsetupplt()
|
||||||
}
|
}
|
||||||
|
|
@ -497,13 +477,11 @@ func addpltsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func addgotsyminternal(ctxt *ld.Link, s *ld.LSym) {
|
func addgotsyminternal(ctxt *ld.Link, s *ld.LSym) {
|
||||||
var got *ld.LSym
|
|
||||||
|
|
||||||
if s.Got >= 0 {
|
if s.Got >= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
got = ld.Linklookup(ctxt, ".got", 0)
|
got := ld.Linklookup(ctxt, ".got", 0)
|
||||||
s.Got = int32(got.Size)
|
s.Got = int32(got.Size)
|
||||||
|
|
||||||
ld.Addaddrplus(ctxt, got, s, 0)
|
ld.Addaddrplus(ctxt, got, s, 0)
|
||||||
|
|
@ -515,20 +493,17 @@ func addgotsyminternal(ctxt *ld.Link, s *ld.LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func addgotsym(ctxt *ld.Link, s *ld.LSym) {
|
func addgotsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
var got *ld.LSym
|
|
||||||
var rel *ld.LSym
|
|
||||||
|
|
||||||
if s.Got >= 0 {
|
if s.Got >= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
adddynsym(ctxt, s)
|
adddynsym(ctxt, s)
|
||||||
got = ld.Linklookup(ctxt, ".got", 0)
|
got := ld.Linklookup(ctxt, ".got", 0)
|
||||||
s.Got = int32(got.Size)
|
s.Got = int32(got.Size)
|
||||||
ld.Adduint32(ctxt, got, 0)
|
ld.Adduint32(ctxt, got, 0)
|
||||||
|
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
rel = ld.Linklookup(ctxt, ".rel", 0)
|
rel := ld.Linklookup(ctxt, ".rel", 0)
|
||||||
ld.Addaddrplus(ctxt, rel, got, int64(s.Got))
|
ld.Addaddrplus(ctxt, rel, got, int64(s.Got))
|
||||||
ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_ARM_GLOB_DAT))
|
ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_ARM_GLOB_DAT))
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -537,10 +512,6 @@ func addgotsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func adddynsym(ctxt *ld.Link, s *ld.LSym) {
|
func adddynsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
var d *ld.LSym
|
|
||||||
var t int
|
|
||||||
var name string
|
|
||||||
|
|
||||||
if s.Dynid >= 0 {
|
if s.Dynid >= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -549,10 +520,10 @@ func adddynsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
s.Dynid = int32(ld.Nelfsym)
|
s.Dynid = int32(ld.Nelfsym)
|
||||||
ld.Nelfsym++
|
ld.Nelfsym++
|
||||||
|
|
||||||
d = ld.Linklookup(ctxt, ".dynsym", 0)
|
d := ld.Linklookup(ctxt, ".dynsym", 0)
|
||||||
|
|
||||||
/* name */
|
/* name */
|
||||||
name = s.Extname
|
name := s.Extname
|
||||||
|
|
||||||
ld.Adduint32(ctxt, d, uint32(ld.Addstring(ld.Linklookup(ctxt, ".dynstr", 0), name)))
|
ld.Adduint32(ctxt, d, uint32(ld.Addstring(ld.Linklookup(ctxt, ".dynstr", 0), name)))
|
||||||
|
|
||||||
|
|
@ -567,7 +538,7 @@ func adddynsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
ld.Adduint32(ctxt, d, 0)
|
ld.Adduint32(ctxt, d, 0)
|
||||||
|
|
||||||
/* type */
|
/* type */
|
||||||
t = ld.STB_GLOBAL << 4
|
t := ld.STB_GLOBAL << 4
|
||||||
|
|
||||||
if (s.Cgoexport&ld.CgoExportDynamic != 0) && s.Type&ld.SMASK == ld.STEXT {
|
if (s.Cgoexport&ld.CgoExportDynamic != 0) && s.Type&ld.SMASK == ld.STEXT {
|
||||||
t |= ld.STT_FUNC
|
t |= ld.STT_FUNC
|
||||||
|
|
@ -589,14 +560,12 @@ func adddynsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func adddynlib(lib string) {
|
func adddynlib(lib string) {
|
||||||
var s *ld.LSym
|
|
||||||
|
|
||||||
if needlib(lib) == 0 {
|
if needlib(lib) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
s = ld.Linklookup(ld.Ctxt, ".dynstr", 0)
|
s := ld.Linklookup(ld.Ctxt, ".dynstr", 0)
|
||||||
if s.Size == 0 {
|
if s.Size == 0 {
|
||||||
ld.Addstring(s, "")
|
ld.Addstring(s, "")
|
||||||
}
|
}
|
||||||
|
|
@ -609,13 +578,6 @@ func adddynlib(lib string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func asmb() {
|
func asmb() {
|
||||||
var symo uint32
|
|
||||||
var dwarfoff uint32
|
|
||||||
var machlink uint32
|
|
||||||
var sect *ld.Section
|
|
||||||
var sym *ld.LSym
|
|
||||||
var i int
|
|
||||||
|
|
||||||
if ld.Debug['v'] != 0 {
|
if ld.Debug['v'] != 0 {
|
||||||
fmt.Fprintf(&ld.Bso, "%5.2f asmb\n", obj.Cputime())
|
fmt.Fprintf(&ld.Bso, "%5.2f asmb\n", obj.Cputime())
|
||||||
}
|
}
|
||||||
|
|
@ -625,7 +587,7 @@ func asmb() {
|
||||||
ld.Asmbelfsetup()
|
ld.Asmbelfsetup()
|
||||||
}
|
}
|
||||||
|
|
||||||
sect = ld.Segtext.Sect
|
sect := ld.Segtext.Sect
|
||||||
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
|
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
|
||||||
ld.Codeblk(int64(sect.Vaddr), int64(sect.Length))
|
ld.Codeblk(int64(sect.Vaddr), int64(sect.Length))
|
||||||
for sect = sect.Next; sect != nil; sect = sect.Next {
|
for sect = sect.Next; sect != nil; sect = sect.Next {
|
||||||
|
|
@ -651,14 +613,14 @@ func asmb() {
|
||||||
ld.Cseek(int64(ld.Segdata.Fileoff))
|
ld.Cseek(int64(ld.Segdata.Fileoff))
|
||||||
ld.Datblk(int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
|
ld.Datblk(int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
|
||||||
|
|
||||||
machlink = 0
|
machlink := uint32(0)
|
||||||
if ld.HEADTYPE == ld.Hdarwin {
|
if ld.HEADTYPE == ld.Hdarwin {
|
||||||
if ld.Debug['v'] != 0 {
|
if ld.Debug['v'] != 0 {
|
||||||
fmt.Fprintf(&ld.Bso, "%5.2f dwarf\n", obj.Cputime())
|
fmt.Fprintf(&ld.Bso, "%5.2f dwarf\n", obj.Cputime())
|
||||||
}
|
}
|
||||||
|
|
||||||
if ld.Debug['w'] == 0 {
|
if ld.Debug['w'] == 0 {
|
||||||
dwarfoff = uint32(ld.Rnd(int64(uint64(ld.HEADR)+ld.Segtext.Length), int64(ld.INITRND)) + ld.Rnd(int64(ld.Segdata.Filelen), int64(ld.INITRND)))
|
dwarfoff := uint32(ld.Rnd(int64(uint64(ld.HEADR)+ld.Segtext.Length), int64(ld.INITRND)) + ld.Rnd(int64(ld.Segdata.Filelen), int64(ld.INITRND)))
|
||||||
ld.Cseek(int64(dwarfoff))
|
ld.Cseek(int64(dwarfoff))
|
||||||
|
|
||||||
ld.Segdwarf.Fileoff = uint64(ld.Cpos())
|
ld.Segdwarf.Fileoff = uint64(ld.Cpos())
|
||||||
|
|
@ -673,7 +635,7 @@ func asmb() {
|
||||||
ld.Symsize = 0
|
ld.Symsize = 0
|
||||||
|
|
||||||
ld.Lcsize = 0
|
ld.Lcsize = 0
|
||||||
symo = 0
|
symo := uint32(0)
|
||||||
if ld.Debug['s'] == 0 {
|
if ld.Debug['s'] == 0 {
|
||||||
// TODO: rationalize
|
// TODO: rationalize
|
||||||
if ld.Debug['v'] != 0 {
|
if ld.Debug['v'] != 0 {
|
||||||
|
|
@ -719,10 +681,10 @@ func asmb() {
|
||||||
ld.Asmplan9sym()
|
ld.Asmplan9sym()
|
||||||
ld.Cflush()
|
ld.Cflush()
|
||||||
|
|
||||||
sym = ld.Linklookup(ld.Ctxt, "pclntab", 0)
|
sym := ld.Linklookup(ld.Ctxt, "pclntab", 0)
|
||||||
if sym != nil {
|
if sym != nil {
|
||||||
ld.Lcsize = int32(len(sym.P))
|
ld.Lcsize = int32(len(sym.P))
|
||||||
for i = 0; int32(i) < ld.Lcsize; i++ {
|
for i := 0; int32(i) < ld.Lcsize; i++ {
|
||||||
ld.Cput(uint8(sym.P[i]))
|
ld.Cput(uint8(sym.P[i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,8 +81,6 @@ func linkarchinit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func archinit() {
|
func archinit() {
|
||||||
var s *ld.LSym
|
|
||||||
|
|
||||||
// getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
|
// getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
|
||||||
// Go was built; see ../../make.bash.
|
// Go was built; see ../../make.bash.
|
||||||
if ld.Linkmode == ld.LinkAuto && obj.Getgoextlinkenabled() == "0" {
|
if ld.Linkmode == ld.LinkAuto && obj.Getgoextlinkenabled() == "0" {
|
||||||
|
|
@ -175,7 +173,7 @@ func archinit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// embed goarm to runtime.goarm
|
// embed goarm to runtime.goarm
|
||||||
s = ld.Linklookup(ld.Ctxt, "runtime.goarm", 0)
|
s := ld.Linklookup(ld.Ctxt, "runtime.goarm", 0)
|
||||||
|
|
||||||
s.Type = ld.SRODATA
|
s.Type = ld.SRODATA
|
||||||
ld.Adduint8(ld.Ctxt, s, uint8(ld.Ctxt.Goarm))
|
ld.Adduint8(ld.Ctxt, s, uint8(ld.Ctxt.Goarm))
|
||||||
|
|
|
||||||
|
|
@ -29,13 +29,8 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
gc.Dump("cgen-res", res)
|
gc.Dump("cgen-res", res)
|
||||||
}
|
}
|
||||||
|
|
||||||
var nl *gc.Node
|
|
||||||
var n1 gc.Node
|
|
||||||
var nr *gc.Node
|
|
||||||
var n2 gc.Node
|
|
||||||
var a int
|
|
||||||
if n == nil || n.Type == nil {
|
if n == nil || n.Type == nil {
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if res == nil || res.Type == nil {
|
if res == nil || res.Type == nil {
|
||||||
|
|
@ -60,7 +55,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
} else {
|
} else {
|
||||||
gc.Cgen_slice(n, res)
|
gc.Cgen_slice(n, res)
|
||||||
}
|
}
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
case gc.OEFACE:
|
case gc.OEFACE:
|
||||||
if res.Op != gc.ONAME || res.Addable == 0 {
|
if res.Op != gc.ONAME || res.Addable == 0 {
|
||||||
|
|
@ -71,7 +66,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
} else {
|
} else {
|
||||||
gc.Cgen_eface(n, res)
|
gc.Cgen_eface(n, res)
|
||||||
}
|
}
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Ullman >= gc.UINF {
|
if n.Ullman >= gc.UINF {
|
||||||
|
|
@ -83,7 +78,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
gc.Tempname(&n1, n.Type)
|
gc.Tempname(&n1, n.Type)
|
||||||
cgen(n, &n1)
|
cgen(n, &n1)
|
||||||
cgen(&n1, res)
|
cgen(&n1, res)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,7 +87,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
gc.Fatal("forgot to compute width for %v", gc.Tconv(n.Type, 0))
|
gc.Fatal("forgot to compute width for %v", gc.Tconv(n.Type, 0))
|
||||||
}
|
}
|
||||||
sgen(n, res, n.Type.Width)
|
sgen(n, res, n.Type.Width)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if res.Addable == 0 {
|
if res.Addable == 0 {
|
||||||
|
|
@ -108,7 +103,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
|
|
||||||
cgen(&n1, res)
|
cgen(&n1, res)
|
||||||
regfree(&n1)
|
regfree(&n1)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var f int
|
var f int
|
||||||
|
|
@ -118,7 +113,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
|
|
||||||
if gc.Complexop(n, res) {
|
if gc.Complexop(n, res) {
|
||||||
gc.Complexgen(n, res)
|
gc.Complexgen(n, res)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
f = 1 // gen thru register
|
f = 1 // gen thru register
|
||||||
|
|
@ -151,7 +146,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
fmt.Printf("%v [ignore previous line]\n", p1)
|
fmt.Printf("%v [ignore previous line]\n", p1)
|
||||||
}
|
}
|
||||||
sudoclean()
|
sudoclean()
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -160,7 +155,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
igen(res, &n1, nil)
|
igen(res, &n1, nil)
|
||||||
cgen(n, &n1)
|
cgen(n, &n1)
|
||||||
regfree(&n1)
|
regfree(&n1)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// update addressability for string, slice
|
// update addressability for string, slice
|
||||||
|
|
@ -184,16 +179,16 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
|
|
||||||
if gc.Complexop(n, res) {
|
if gc.Complexop(n, res) {
|
||||||
gc.Complexgen(n, res)
|
gc.Complexgen(n, res)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Addable != 0 {
|
if n.Addable != 0 {
|
||||||
gmove(n, res)
|
gmove(n, res)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
nl = n.Left
|
nl := n.Left
|
||||||
nr = n.Right
|
nr := n.Right
|
||||||
|
|
||||||
if nl != nil && nl.Ullman >= gc.UINF {
|
if nl != nil && nl.Ullman >= gc.UINF {
|
||||||
if nr != nil && nr.Ullman >= gc.UINF {
|
if nr != nil && nr.Ullman >= gc.UINF {
|
||||||
|
|
@ -203,7 +198,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
n2 := *n
|
n2 := *n
|
||||||
n2.Left = &n1
|
n2.Left = &n1
|
||||||
cgen(&n2, res)
|
cgen(&n2, res)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -224,10 +219,11 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sudoclean()
|
sudoclean()
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var a int
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
gc.Dump("cgen", n)
|
gc.Dump("cgen", n)
|
||||||
|
|
@ -252,11 +248,11 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
bgen(n, true, 0, p2)
|
bgen(n, true, 0, p2)
|
||||||
gmove(gc.Nodbool(false), res)
|
gmove(gc.Nodbool(false), res)
|
||||||
gc.Patch(p3, gc.Pc)
|
gc.Patch(p3, gc.Pc)
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
case gc.OPLUS:
|
case gc.OPLUS:
|
||||||
cgen(nl, res)
|
cgen(nl, res)
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
// unary
|
// unary
|
||||||
case gc.OCOM:
|
case gc.OCOM:
|
||||||
|
|
@ -270,7 +266,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
gins(a, &n2, &n1)
|
gins(a, &n2, &n1)
|
||||||
gmove(&n1, res)
|
gmove(&n1, res)
|
||||||
regfree(&n1)
|
regfree(&n1)
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
case gc.OMINUS:
|
case gc.OMINUS:
|
||||||
if gc.Isfloat[nl.Type.Etype] != 0 {
|
if gc.Isfloat[nl.Type.Etype] != 0 {
|
||||||
|
|
@ -280,8 +276,16 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
goto sbop
|
goto sbop
|
||||||
}
|
}
|
||||||
|
|
||||||
a = optoas(int(n.Op), nl.Type)
|
a := optoas(int(n.Op), nl.Type)
|
||||||
goto uop
|
// unary
|
||||||
|
var n1 gc.Node
|
||||||
|
regalloc(&n1, nl.Type, res)
|
||||||
|
|
||||||
|
cgen(nl, &n1)
|
||||||
|
gins(a, nil, &n1)
|
||||||
|
gmove(&n1, res)
|
||||||
|
regfree(&n1)
|
||||||
|
return
|
||||||
|
|
||||||
// symmetric binary
|
// symmetric binary
|
||||||
case gc.OAND,
|
case gc.OAND,
|
||||||
|
|
@ -325,7 +329,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
gmove(&n2, res)
|
gmove(&n2, res)
|
||||||
regfree(&n2)
|
regfree(&n2)
|
||||||
regfree(&n1)
|
regfree(&n1)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -517,7 +521,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
cgen_shift(int(n.Op), n.Bounded, nl, nr, res)
|
cgen_shift(int(n.Op), n.Bounded, nl, nr, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* put simplest on right - we'll generate into left
|
* put simplest on right - we'll generate into left
|
||||||
|
|
@ -543,6 +547,8 @@ sbop: // symmetric binary
|
||||||
}
|
}
|
||||||
|
|
||||||
abop: // asymmetric binary
|
abop: // asymmetric binary
|
||||||
|
var n1 gc.Node
|
||||||
|
var n2 gc.Node
|
||||||
if nl.Ullman >= nr.Ullman {
|
if nl.Ullman >= nr.Ullman {
|
||||||
regalloc(&n1, nl.Type, res)
|
regalloc(&n1, nl.Type, res)
|
||||||
cgen(nl, &n1)
|
cgen(nl, &n1)
|
||||||
|
|
@ -588,18 +594,7 @@ abop: // asymmetric binary
|
||||||
if n2.Op != gc.OLITERAL {
|
if n2.Op != gc.OLITERAL {
|
||||||
regfree(&n2)
|
regfree(&n2)
|
||||||
}
|
}
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
uop: // unary
|
|
||||||
regalloc(&n1, nl.Type, res)
|
|
||||||
|
|
||||||
cgen(nl, &n1)
|
|
||||||
gins(a, nil, &n1)
|
|
||||||
gmove(&n1, res)
|
|
||||||
regfree(&n1)
|
|
||||||
goto ret
|
|
||||||
|
|
||||||
ret:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -878,7 +873,6 @@ func agen(n *gc.Node, res *gc.Node) {
|
||||||
n = n.Left
|
n = n.Left
|
||||||
}
|
}
|
||||||
|
|
||||||
var nl *gc.Node
|
|
||||||
if gc.Isconst(n, gc.CTNIL) && n.Type.Width > int64(gc.Widthptr) {
|
if gc.Isconst(n, gc.CTNIL) && n.Type.Width > int64(gc.Widthptr) {
|
||||||
// Use of a nil interface or nil slice.
|
// Use of a nil interface or nil slice.
|
||||||
// Create a temporary we can take the address of and read.
|
// Create a temporary we can take the address of and read.
|
||||||
|
|
@ -894,7 +888,7 @@ func agen(n *gc.Node, res *gc.Node) {
|
||||||
gins(x86.ALEAQ, &n1, &n2)
|
gins(x86.ALEAQ, &n1, &n2)
|
||||||
gmove(&n2, res)
|
gmove(&n2, res)
|
||||||
regfree(&n2)
|
regfree(&n2)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Addable != 0 {
|
if n.Addable != 0 {
|
||||||
|
|
@ -903,10 +897,10 @@ func agen(n *gc.Node, res *gc.Node) {
|
||||||
gins(x86.ALEAQ, n, &n1)
|
gins(x86.ALEAQ, n, &n1)
|
||||||
gmove(&n1, res)
|
gmove(&n1, res)
|
||||||
regfree(&n1)
|
regfree(&n1)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
nl = n.Left
|
nl := n.Left
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
|
|
@ -981,8 +975,6 @@ func agen(n *gc.Node, res *gc.Node) {
|
||||||
ginscon(optoas(gc.OADD, gc.Types[gc.Tptr]), n.Xoffset, res)
|
ginscon(optoas(gc.OADD, gc.Types[gc.Tptr]), n.Xoffset, res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1108,27 +1100,21 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
gc.Genlist(n.Ninit)
|
gc.Genlist(n.Ninit)
|
||||||
}
|
}
|
||||||
|
|
||||||
var a int
|
|
||||||
var et int
|
|
||||||
var nl *gc.Node
|
|
||||||
var n1 gc.Node
|
|
||||||
var nr *gc.Node
|
|
||||||
var n2 gc.Node
|
|
||||||
if n.Type == nil {
|
if n.Type == nil {
|
||||||
gc.Convlit(&n, gc.Types[gc.TBOOL])
|
gc.Convlit(&n, gc.Types[gc.TBOOL])
|
||||||
if n.Type == nil {
|
if n.Type == nil {
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
et = int(n.Type.Etype)
|
et := int(n.Type.Etype)
|
||||||
if et != gc.TBOOL {
|
if et != gc.TBOOL {
|
||||||
gc.Yyerror("cgen: bad type %v for %v", gc.Tconv(n.Type, 0), gc.Oconv(int(n.Op), 0))
|
gc.Yyerror("cgen: bad type %v for %v", gc.Tconv(n.Type, 0), gc.Oconv(int(n.Op), 0))
|
||||||
gc.Patch(gins(obj.AEND, nil, nil), to)
|
gc.Patch(gins(obj.AEND, nil, nil), to)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
nr = nil
|
nr := (*gc.Node)(nil)
|
||||||
|
|
||||||
for n.Op == gc.OCONVNOP {
|
for n.Op == gc.OCONVNOP {
|
||||||
n = n.Left
|
n = n.Left
|
||||||
|
|
@ -1137,6 +1123,7 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var nl *gc.Node
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
goto def
|
goto def
|
||||||
|
|
@ -1146,7 +1133,7 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
if !true_ == (n.Val.U.Bval == 0) {
|
if !true_ == (n.Val.U.Bval == 0) {
|
||||||
gc.Patch(gc.Gbranch(obj.AJMP, nil, likely), to)
|
gc.Patch(gc.Gbranch(obj.AJMP, nil, likely), to)
|
||||||
}
|
}
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
case gc.ONAME:
|
case gc.ONAME:
|
||||||
if n.Addable == 0 {
|
if n.Addable == 0 {
|
||||||
|
|
@ -1160,7 +1147,7 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
a = x86.AJEQ
|
a = x86.AJEQ
|
||||||
}
|
}
|
||||||
gc.Patch(gc.Gbranch(a, n.Type, likely), to)
|
gc.Patch(gc.Gbranch(a, n.Type, likely), to)
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
case gc.OANDAND,
|
case gc.OANDAND,
|
||||||
gc.OOROR:
|
gc.OOROR:
|
||||||
|
|
@ -1178,7 +1165,7 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
bgen(n.Right, true_, likely, to)
|
bgen(n.Right, true_, likely, to)
|
||||||
}
|
}
|
||||||
|
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
case gc.OEQ,
|
case gc.OEQ,
|
||||||
gc.ONE,
|
gc.ONE,
|
||||||
|
|
@ -1188,7 +1175,7 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
gc.OGE:
|
gc.OGE:
|
||||||
nr = n.Right
|
nr = n.Right
|
||||||
if nr == nil || nr.Type == nil {
|
if nr == nil || nr.Type == nil {
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
||||||
|
|
@ -1196,14 +1183,14 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
nl = n.Left
|
nl = n.Left
|
||||||
|
|
||||||
if nl == nil || nl.Type == nil {
|
if nl == nil || nl.Type == nil {
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
case gc.ONOT:
|
case gc.ONOT:
|
||||||
bgen(nl, !true_, likely, to)
|
bgen(nl, !true_, likely, to)
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
case gc.OEQ,
|
case gc.OEQ,
|
||||||
gc.ONE,
|
gc.ONE,
|
||||||
|
|
@ -1225,7 +1212,7 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
n.Ninit = ll
|
n.Ninit = ll
|
||||||
gc.Patch(gc.Gbranch(obj.AJMP, nil, 0), to)
|
gc.Patch(gc.Gbranch(obj.AJMP, nil, 0), to)
|
||||||
gc.Patch(p2, gc.Pc)
|
gc.Patch(p2, gc.Pc)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
a = gc.Brcom(a)
|
a = gc.Brcom(a)
|
||||||
|
|
@ -1352,22 +1339,22 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
regfree(&n2)
|
regfree(&n2)
|
||||||
}
|
}
|
||||||
|
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
def:
|
def:
|
||||||
|
var n1 gc.Node
|
||||||
regalloc(&n1, n.Type, nil)
|
regalloc(&n1, n.Type, nil)
|
||||||
cgen(n, &n1)
|
cgen(n, &n1)
|
||||||
|
var n2 gc.Node
|
||||||
gc.Nodconst(&n2, n.Type, 0)
|
gc.Nodconst(&n2, n.Type, 0)
|
||||||
gins(optoas(gc.OCMP, n.Type), &n1, &n2)
|
gins(optoas(gc.OCMP, n.Type), &n1, &n2)
|
||||||
a = x86.AJNE
|
a := x86.AJNE
|
||||||
if !true_ {
|
if !true_ {
|
||||||
a = x86.AJEQ
|
a = x86.AJEQ
|
||||||
}
|
}
|
||||||
gc.Patch(gc.Gbranch(a, n.Type, likely), to)
|
gc.Patch(gc.Gbranch(a, n.Type, likely), to)
|
||||||
regfree(&n1)
|
regfree(&n1)
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
ret:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -786,14 +786,6 @@ func cgen_hmul(nl *gc.Node, nr *gc.Node, res *gc.Node) {
|
||||||
* res = nl >> nr
|
* res = nl >> nr
|
||||||
*/
|
*/
|
||||||
func cgen_shift(op int, bounded bool, nl *gc.Node, nr *gc.Node, res *gc.Node) {
|
func cgen_shift(op int, bounded bool, nl *gc.Node, nr *gc.Node, res *gc.Node) {
|
||||||
var n1 gc.Node
|
|
||||||
var n2 gc.Node
|
|
||||||
var n3 gc.Node
|
|
||||||
var cx gc.Node
|
|
||||||
var oldcx gc.Node
|
|
||||||
var rcx int
|
|
||||||
var tcount *gc.Type
|
|
||||||
|
|
||||||
a := optoas(op, nl.Type)
|
a := optoas(op, nl.Type)
|
||||||
|
|
||||||
if nr.Op == gc.OLITERAL {
|
if nr.Op == gc.OLITERAL {
|
||||||
|
|
@ -813,7 +805,7 @@ func cgen_shift(op int, bounded bool, nl *gc.Node, nr *gc.Node, res *gc.Node) {
|
||||||
}
|
}
|
||||||
gmove(&n1, res)
|
gmove(&n1, res)
|
||||||
regfree(&n1)
|
regfree(&n1)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if nl.Ullman >= gc.UINF {
|
if nl.Ullman >= gc.UINF {
|
||||||
|
|
@ -830,24 +822,27 @@ func cgen_shift(op int, bounded bool, nl *gc.Node, nr *gc.Node, res *gc.Node) {
|
||||||
nr = &n5
|
nr = &n5
|
||||||
}
|
}
|
||||||
|
|
||||||
rcx = int(reg[x86.REG_CX])
|
rcx := int(reg[x86.REG_CX])
|
||||||
|
var n1 gc.Node
|
||||||
gc.Nodreg(&n1, gc.Types[gc.TUINT32], x86.REG_CX)
|
gc.Nodreg(&n1, gc.Types[gc.TUINT32], x86.REG_CX)
|
||||||
|
|
||||||
// Allow either uint32 or uint64 as shift type,
|
// Allow either uint32 or uint64 as shift type,
|
||||||
// to avoid unnecessary conversion from uint32 to uint64
|
// to avoid unnecessary conversion from uint32 to uint64
|
||||||
// just to do the comparison.
|
// just to do the comparison.
|
||||||
tcount = gc.Types[gc.Simtype[nr.Type.Etype]]
|
tcount := gc.Types[gc.Simtype[nr.Type.Etype]]
|
||||||
|
|
||||||
if tcount.Etype < gc.TUINT32 {
|
if tcount.Etype < gc.TUINT32 {
|
||||||
tcount = gc.Types[gc.TUINT32]
|
tcount = gc.Types[gc.TUINT32]
|
||||||
}
|
}
|
||||||
|
|
||||||
regalloc(&n1, nr.Type, &n1) // to hold the shift type in CX
|
regalloc(&n1, nr.Type, &n1) // to hold the shift type in CX
|
||||||
regalloc(&n3, tcount, &n1) // to clear high bits of CX
|
var n3 gc.Node
|
||||||
|
regalloc(&n3, tcount, &n1) // to clear high bits of CX
|
||||||
|
|
||||||
|
var cx gc.Node
|
||||||
gc.Nodreg(&cx, gc.Types[gc.TUINT64], x86.REG_CX)
|
gc.Nodreg(&cx, gc.Types[gc.TUINT64], x86.REG_CX)
|
||||||
|
|
||||||
oldcx = gc.Node{}
|
oldcx := gc.Node{}
|
||||||
if rcx > 0 && !gc.Samereg(&cx, res) {
|
if rcx > 0 && !gc.Samereg(&cx, res) {
|
||||||
regalloc(&oldcx, gc.Types[gc.TUINT64], nil)
|
regalloc(&oldcx, gc.Types[gc.TUINT64], nil)
|
||||||
gmove(&cx, &oldcx)
|
gmove(&cx, &oldcx)
|
||||||
|
|
@ -855,6 +850,7 @@ func cgen_shift(op int, bounded bool, nl *gc.Node, nr *gc.Node, res *gc.Node) {
|
||||||
|
|
||||||
cx.Type = tcount
|
cx.Type = tcount
|
||||||
|
|
||||||
|
var n2 gc.Node
|
||||||
if gc.Samereg(&cx, res) {
|
if gc.Samereg(&cx, res) {
|
||||||
regalloc(&n2, nl.Type, nil)
|
regalloc(&n2, nl.Type, nil)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -900,8 +896,6 @@ func cgen_shift(op int, bounded bool, nl *gc.Node, nr *gc.Node, res *gc.Node) {
|
||||||
|
|
||||||
regfree(&n1)
|
regfree(&n1)
|
||||||
regfree(&n2)
|
regfree(&n2)
|
||||||
|
|
||||||
ret:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -1349,12 +1349,6 @@ func sudoaddable(as int, n *gc.Node, a *obj.Addr) bool {
|
||||||
|
|
||||||
*a = obj.Addr{}
|
*a = obj.Addr{}
|
||||||
|
|
||||||
var o int
|
|
||||||
var n1 gc.Node
|
|
||||||
var oary [10]int64
|
|
||||||
var nn *gc.Node
|
|
||||||
var reg *gc.Node
|
|
||||||
var reg1 *gc.Node
|
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
case gc.OLITERAL:
|
case gc.OLITERAL:
|
||||||
if !gc.Isconst(n, gc.CTINT) {
|
if !gc.Isconst(n, gc.CTINT) {
|
||||||
|
|
@ -1364,118 +1358,108 @@ func sudoaddable(as int, n *gc.Node, a *obj.Addr) bool {
|
||||||
if v >= 32000 || v <= -32000 {
|
if v >= 32000 || v <= -32000 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
goto lit
|
switch as {
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
|
||||||
|
case x86.AADDB,
|
||||||
|
x86.AADDW,
|
||||||
|
x86.AADDL,
|
||||||
|
x86.AADDQ,
|
||||||
|
x86.ASUBB,
|
||||||
|
x86.ASUBW,
|
||||||
|
x86.ASUBL,
|
||||||
|
x86.ASUBQ,
|
||||||
|
x86.AANDB,
|
||||||
|
x86.AANDW,
|
||||||
|
x86.AANDL,
|
||||||
|
x86.AANDQ,
|
||||||
|
x86.AORB,
|
||||||
|
x86.AORW,
|
||||||
|
x86.AORL,
|
||||||
|
x86.AORQ,
|
||||||
|
x86.AXORB,
|
||||||
|
x86.AXORW,
|
||||||
|
x86.AXORL,
|
||||||
|
x86.AXORQ,
|
||||||
|
x86.AINCB,
|
||||||
|
x86.AINCW,
|
||||||
|
x86.AINCL,
|
||||||
|
x86.AINCQ,
|
||||||
|
x86.ADECB,
|
||||||
|
x86.ADECW,
|
||||||
|
x86.ADECL,
|
||||||
|
x86.ADECQ,
|
||||||
|
x86.AMOVB,
|
||||||
|
x86.AMOVW,
|
||||||
|
x86.AMOVL,
|
||||||
|
x86.AMOVQ:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
cleani += 2
|
||||||
|
reg := &clean[cleani-1]
|
||||||
|
reg1 := &clean[cleani-2]
|
||||||
|
reg.Op = gc.OEMPTY
|
||||||
|
reg1.Op = gc.OEMPTY
|
||||||
|
gc.Naddr(n, a, 1)
|
||||||
|
return true
|
||||||
|
|
||||||
case gc.ODOT,
|
case gc.ODOT,
|
||||||
gc.ODOTPTR:
|
gc.ODOTPTR:
|
||||||
cleani += 2
|
cleani += 2
|
||||||
reg = &clean[cleani-1]
|
reg := &clean[cleani-1]
|
||||||
reg1 := &clean[cleani-2]
|
reg1 := &clean[cleani-2]
|
||||||
reg.Op = gc.OEMPTY
|
reg.Op = gc.OEMPTY
|
||||||
reg1.Op = gc.OEMPTY
|
reg1.Op = gc.OEMPTY
|
||||||
goto odot
|
var nn *gc.Node
|
||||||
|
var oary [10]int64
|
||||||
|
o := gc.Dotoffset(n, oary[:], &nn)
|
||||||
|
if nn == nil {
|
||||||
|
sudoclean()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if nn.Addable != 0 && o == 1 && oary[0] >= 0 {
|
||||||
|
// directly addressable set of DOTs
|
||||||
|
n1 := *nn
|
||||||
|
|
||||||
|
n1.Type = n.Type
|
||||||
|
n1.Xoffset += oary[0]
|
||||||
|
gc.Naddr(&n1, a, 1)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
regalloc(reg, gc.Types[gc.Tptr], nil)
|
||||||
|
n1 := *reg
|
||||||
|
n1.Op = gc.OINDREG
|
||||||
|
if oary[0] >= 0 {
|
||||||
|
agen(nn, reg)
|
||||||
|
n1.Xoffset = oary[0]
|
||||||
|
} else {
|
||||||
|
cgen(nn, reg)
|
||||||
|
gc.Cgen_checknil(reg)
|
||||||
|
n1.Xoffset = -(oary[0] + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 1; i < o; i++ {
|
||||||
|
if oary[i] >= 0 {
|
||||||
|
gc.Fatal("can't happen")
|
||||||
|
}
|
||||||
|
gins(movptr, &n1, reg)
|
||||||
|
gc.Cgen_checknil(reg)
|
||||||
|
n1.Xoffset = -(oary[i] + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
a.Type = obj.TYPE_NONE
|
||||||
|
a.Index = obj.TYPE_NONE
|
||||||
|
fixlargeoffset(&n1)
|
||||||
|
gc.Naddr(&n1, a, 1)
|
||||||
|
return true
|
||||||
|
|
||||||
case gc.OINDEX:
|
case gc.OINDEX:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|
||||||
lit:
|
|
||||||
switch as {
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
|
|
||||||
case x86.AADDB,
|
|
||||||
x86.AADDW,
|
|
||||||
x86.AADDL,
|
|
||||||
x86.AADDQ,
|
|
||||||
x86.ASUBB,
|
|
||||||
x86.ASUBW,
|
|
||||||
x86.ASUBL,
|
|
||||||
x86.ASUBQ,
|
|
||||||
x86.AANDB,
|
|
||||||
x86.AANDW,
|
|
||||||
x86.AANDL,
|
|
||||||
x86.AANDQ,
|
|
||||||
x86.AORB,
|
|
||||||
x86.AORW,
|
|
||||||
x86.AORL,
|
|
||||||
x86.AORQ,
|
|
||||||
x86.AXORB,
|
|
||||||
x86.AXORW,
|
|
||||||
x86.AXORL,
|
|
||||||
x86.AXORQ,
|
|
||||||
x86.AINCB,
|
|
||||||
x86.AINCW,
|
|
||||||
x86.AINCL,
|
|
||||||
x86.AINCQ,
|
|
||||||
x86.ADECB,
|
|
||||||
x86.ADECW,
|
|
||||||
x86.ADECL,
|
|
||||||
x86.ADECQ,
|
|
||||||
x86.AMOVB,
|
|
||||||
x86.AMOVW,
|
|
||||||
x86.AMOVL,
|
|
||||||
x86.AMOVQ:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
cleani += 2
|
|
||||||
reg = &clean[cleani-1]
|
|
||||||
reg1 = &clean[cleani-2]
|
|
||||||
reg.Op = gc.OEMPTY
|
|
||||||
reg1.Op = gc.OEMPTY
|
|
||||||
gc.Naddr(n, a, 1)
|
|
||||||
goto yes
|
|
||||||
|
|
||||||
odot:
|
|
||||||
o = gc.Dotoffset(n, oary[:], &nn)
|
|
||||||
if nn == nil {
|
|
||||||
goto no
|
|
||||||
}
|
|
||||||
|
|
||||||
if nn.Addable != 0 && o == 1 && oary[0] >= 0 {
|
|
||||||
// directly addressable set of DOTs
|
|
||||||
n1 := *nn
|
|
||||||
|
|
||||||
n1.Type = n.Type
|
|
||||||
n1.Xoffset += oary[0]
|
|
||||||
gc.Naddr(&n1, a, 1)
|
|
||||||
goto yes
|
|
||||||
}
|
|
||||||
|
|
||||||
regalloc(reg, gc.Types[gc.Tptr], nil)
|
|
||||||
n1 = *reg
|
|
||||||
n1.Op = gc.OINDREG
|
|
||||||
if oary[0] >= 0 {
|
|
||||||
agen(nn, reg)
|
|
||||||
n1.Xoffset = oary[0]
|
|
||||||
} else {
|
|
||||||
cgen(nn, reg)
|
|
||||||
gc.Cgen_checknil(reg)
|
|
||||||
n1.Xoffset = -(oary[0] + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 1; i < o; i++ {
|
|
||||||
if oary[i] >= 0 {
|
|
||||||
gc.Fatal("can't happen")
|
|
||||||
}
|
|
||||||
gins(movptr, &n1, reg)
|
|
||||||
gc.Cgen_checknil(reg)
|
|
||||||
n1.Xoffset = -(oary[i] + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
a.Type = obj.TYPE_NONE
|
|
||||||
a.Index = obj.TYPE_NONE
|
|
||||||
fixlargeoffset(&n1)
|
|
||||||
gc.Naddr(&n1, a, 1)
|
|
||||||
goto yes
|
|
||||||
|
|
||||||
yes:
|
|
||||||
return true
|
|
||||||
|
|
||||||
no:
|
|
||||||
sudoclean()
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -563,8 +563,7 @@ func subprop(r0 *gc.Flow) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
var info gc.ProgInfo
|
var info gc.ProgInfo
|
||||||
var r *gc.Flow
|
for r := gc.Uniqp(r0); r != nil; r = gc.Uniqp(r) {
|
||||||
for r = gc.Uniqp(r0); r != nil; r = gc.Uniqp(r) {
|
|
||||||
if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
|
if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
|
||||||
fmt.Printf("\t? %v\n", r.Prog)
|
fmt.Printf("\t? %v\n", r.Prog)
|
||||||
}
|
}
|
||||||
|
|
@ -595,7 +594,31 @@ func subprop(r0 *gc.Flow) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.Flags&gc.Move != 0) && (info.Flags&(gc.SizeL|gc.SizeQ|gc.SizeF|gc.SizeD) != 0) && p.To.Type == v1.Type && p.To.Reg == v1.Reg {
|
if (info.Flags&gc.Move != 0) && (info.Flags&(gc.SizeL|gc.SizeQ|gc.SizeF|gc.SizeD) != 0) && p.To.Type == v1.Type && p.To.Reg == v1.Reg {
|
||||||
goto gotit
|
copysub(&p.To, v1, v2, 1)
|
||||||
|
if gc.Debug['P'] != 0 {
|
||||||
|
fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
|
||||||
|
if p.From.Type == v2.Type && p.From.Reg == v2.Reg {
|
||||||
|
fmt.Printf(" excise")
|
||||||
|
}
|
||||||
|
fmt.Printf("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
|
||||||
|
p = r.Prog
|
||||||
|
copysub(&p.From, v1, v2, 1)
|
||||||
|
copysub(&p.To, v1, v2, 1)
|
||||||
|
if gc.Debug['P'] != 0 {
|
||||||
|
fmt.Printf("%v\n", r.Prog)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t := int(int(v1.Reg))
|
||||||
|
v1.Reg = v2.Reg
|
||||||
|
v2.Reg = int16(t)
|
||||||
|
if gc.Debug['P'] != 0 {
|
||||||
|
fmt.Printf("%v last\n", r.Prog)
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if copyau(&p.From, v2) || copyau(&p.To, v2) {
|
if copyau(&p.From, v2) || copyau(&p.To, v2) {
|
||||||
|
|
@ -617,33 +640,6 @@ func subprop(r0 *gc.Flow) bool {
|
||||||
fmt.Printf("\tran off end; return 0\n")
|
fmt.Printf("\tran off end; return 0\n")
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|
||||||
gotit:
|
|
||||||
copysub(&p.To, v1, v2, 1)
|
|
||||||
if gc.Debug['P'] != 0 {
|
|
||||||
fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
|
|
||||||
if p.From.Type == v2.Type && p.From.Reg == v2.Reg {
|
|
||||||
fmt.Printf(" excise")
|
|
||||||
}
|
|
||||||
fmt.Printf("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
|
|
||||||
p = r.Prog
|
|
||||||
copysub(&p.From, v1, v2, 1)
|
|
||||||
copysub(&p.To, v1, v2, 1)
|
|
||||||
if gc.Debug['P'] != 0 {
|
|
||||||
fmt.Printf("%v\n", r.Prog)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
t := int(int(v1.Reg))
|
|
||||||
v1.Reg = v2.Reg
|
|
||||||
v2.Reg = int16(t)
|
|
||||||
if gc.Debug['P'] != 0 {
|
|
||||||
fmt.Printf("%v last\n", r.Prog)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -44,17 +44,14 @@ func PADDR(x uint32) uint32 {
|
||||||
var zeroes string
|
var zeroes string
|
||||||
|
|
||||||
func needlib(name string) int {
|
func needlib(name string) int {
|
||||||
var p string
|
|
||||||
var s *ld.LSym
|
|
||||||
|
|
||||||
if name[0] == '\x00' {
|
if name[0] == '\x00' {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reuse hash code in symbol table */
|
/* reuse hash code in symbol table */
|
||||||
p = fmt.Sprintf(".elfload.%s", name)
|
p := fmt.Sprintf(".elfload.%s", name)
|
||||||
|
|
||||||
s = ld.Linklookup(ld.Ctxt, p, 0)
|
s := ld.Linklookup(ld.Ctxt, p, 0)
|
||||||
|
|
||||||
if s.Type == 0 {
|
if s.Type == 0 {
|
||||||
s.Type = 100 // avoid SDATA, etc.
|
s.Type = 100 // avoid SDATA, etc.
|
||||||
|
|
@ -74,11 +71,7 @@ func adddynrela(rela *ld.LSym, s *ld.LSym, r *ld.Reloc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
||||||
var targ *ld.LSym
|
targ := r.Sym
|
||||||
var rela *ld.LSym
|
|
||||||
var got *ld.LSym
|
|
||||||
|
|
||||||
targ = r.Sym
|
|
||||||
ld.Ctxt.Cursym = s
|
ld.Ctxt.Cursym = s
|
||||||
|
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
|
|
@ -233,7 +226,7 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
||||||
}
|
}
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
adddynsym(ld.Ctxt, targ)
|
adddynsym(ld.Ctxt, targ)
|
||||||
rela = ld.Linklookup(ld.Ctxt, ".rela", 0)
|
rela := ld.Linklookup(ld.Ctxt, ".rela", 0)
|
||||||
ld.Addaddrplus(ld.Ctxt, rela, s, int64(r.Off))
|
ld.Addaddrplus(ld.Ctxt, rela, s, int64(r.Off))
|
||||||
if r.Siz == 8 {
|
if r.Siz == 8 {
|
||||||
ld.Adduint64(ld.Ctxt, rela, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_X86_64_64))
|
ld.Adduint64(ld.Ctxt, rela, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_X86_64_64))
|
||||||
|
|
@ -258,7 +251,7 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
||||||
// but we only need to support cgo and that's all it needs.
|
// but we only need to support cgo and that's all it needs.
|
||||||
adddynsym(ld.Ctxt, targ)
|
adddynsym(ld.Ctxt, targ)
|
||||||
|
|
||||||
got = ld.Linklookup(ld.Ctxt, ".got", 0)
|
got := ld.Linklookup(ld.Ctxt, ".got", 0)
|
||||||
s.Type = got.Type | ld.SSUB
|
s.Type = got.Type | ld.SSUB
|
||||||
s.Outer = got
|
s.Outer = got
|
||||||
s.Sub = got.Sub
|
s.Sub = got.Sub
|
||||||
|
|
@ -276,11 +269,9 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfreloc1(r *ld.Reloc, sectoff int64) int {
|
func elfreloc1(r *ld.Reloc, sectoff int64) int {
|
||||||
var elfsym int32
|
|
||||||
|
|
||||||
ld.Thearch.Vput(uint64(sectoff))
|
ld.Thearch.Vput(uint64(sectoff))
|
||||||
|
|
||||||
elfsym = r.Xsym.Elfsym
|
elfsym := r.Xsym.Elfsym
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
default:
|
default:
|
||||||
return -1
|
return -1
|
||||||
|
|
@ -337,9 +328,8 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int {
|
||||||
|
|
||||||
func machoreloc1(r *ld.Reloc, sectoff int64) int {
|
func machoreloc1(r *ld.Reloc, sectoff int64) int {
|
||||||
var v uint32
|
var v uint32
|
||||||
var rs *ld.LSym
|
|
||||||
|
|
||||||
rs = r.Xsym
|
rs := r.Xsym
|
||||||
|
|
||||||
if rs.Type == ld.SHOSTOBJ || r.Type == ld.R_PCREL {
|
if rs.Type == ld.SHOSTOBJ || r.Type == ld.R_PCREL {
|
||||||
if rs.Dynid < 0 {
|
if rs.Dynid < 0 {
|
||||||
|
|
@ -406,11 +396,8 @@ func archrelocvariant(r *ld.Reloc, s *ld.LSym, t int64) int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfsetupplt() {
|
func elfsetupplt() {
|
||||||
var plt *ld.LSym
|
plt := ld.Linklookup(ld.Ctxt, ".plt", 0)
|
||||||
var got *ld.LSym
|
got := ld.Linklookup(ld.Ctxt, ".got.plt", 0)
|
||||||
|
|
||||||
plt = ld.Linklookup(ld.Ctxt, ".plt", 0)
|
|
||||||
got = ld.Linklookup(ld.Ctxt, ".got.plt", 0)
|
|
||||||
if plt.Size == 0 {
|
if plt.Size == 0 {
|
||||||
// pushq got+8(IP)
|
// pushq got+8(IP)
|
||||||
ld.Adduint8(ld.Ctxt, plt, 0xff)
|
ld.Adduint8(ld.Ctxt, plt, 0xff)
|
||||||
|
|
@ -443,13 +430,9 @@ func addpltsym(s *ld.LSym) {
|
||||||
adddynsym(ld.Ctxt, s)
|
adddynsym(ld.Ctxt, s)
|
||||||
|
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
var plt *ld.LSym
|
plt := ld.Linklookup(ld.Ctxt, ".plt", 0)
|
||||||
var got *ld.LSym
|
got := ld.Linklookup(ld.Ctxt, ".got.plt", 0)
|
||||||
var rela *ld.LSym
|
rela := ld.Linklookup(ld.Ctxt, ".rela.plt", 0)
|
||||||
|
|
||||||
plt = ld.Linklookup(ld.Ctxt, ".plt", 0)
|
|
||||||
got = ld.Linklookup(ld.Ctxt, ".got.plt", 0)
|
|
||||||
rela = ld.Linklookup(ld.Ctxt, ".rela.plt", 0)
|
|
||||||
if plt.Size == 0 {
|
if plt.Size == 0 {
|
||||||
elfsetupplt()
|
elfsetupplt()
|
||||||
}
|
}
|
||||||
|
|
@ -491,10 +474,8 @@ func addpltsym(s *ld.LSym) {
|
||||||
// http://networkpx.blogspot.com/2009/09/about-lcdyldinfoonly-command.html
|
// http://networkpx.blogspot.com/2009/09/about-lcdyldinfoonly-command.html
|
||||||
// has details about what we're avoiding.
|
// has details about what we're avoiding.
|
||||||
|
|
||||||
var plt *ld.LSym
|
|
||||||
|
|
||||||
addgotsym(s)
|
addgotsym(s)
|
||||||
plt = ld.Linklookup(ld.Ctxt, ".plt", 0)
|
plt := ld.Linklookup(ld.Ctxt, ".plt", 0)
|
||||||
|
|
||||||
ld.Adduint32(ld.Ctxt, ld.Linklookup(ld.Ctxt, ".linkedit.plt", 0), uint32(s.Dynid))
|
ld.Adduint32(ld.Ctxt, ld.Linklookup(ld.Ctxt, ".linkedit.plt", 0), uint32(s.Dynid))
|
||||||
|
|
||||||
|
|
@ -510,20 +491,17 @@ func addpltsym(s *ld.LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func addgotsym(s *ld.LSym) {
|
func addgotsym(s *ld.LSym) {
|
||||||
var got *ld.LSym
|
|
||||||
var rela *ld.LSym
|
|
||||||
|
|
||||||
if s.Got >= 0 {
|
if s.Got >= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
adddynsym(ld.Ctxt, s)
|
adddynsym(ld.Ctxt, s)
|
||||||
got = ld.Linklookup(ld.Ctxt, ".got", 0)
|
got := ld.Linklookup(ld.Ctxt, ".got", 0)
|
||||||
s.Got = int32(got.Size)
|
s.Got = int32(got.Size)
|
||||||
ld.Adduint64(ld.Ctxt, got, 0)
|
ld.Adduint64(ld.Ctxt, got, 0)
|
||||||
|
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
rela = ld.Linklookup(ld.Ctxt, ".rela", 0)
|
rela := ld.Linklookup(ld.Ctxt, ".rela", 0)
|
||||||
ld.Addaddrplus(ld.Ctxt, rela, got, int64(s.Got))
|
ld.Addaddrplus(ld.Ctxt, rela, got, int64(s.Got))
|
||||||
ld.Adduint64(ld.Ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_X86_64_GLOB_DAT))
|
ld.Adduint64(ld.Ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_X86_64_GLOB_DAT))
|
||||||
ld.Adduint64(ld.Ctxt, rela, 0)
|
ld.Adduint64(ld.Ctxt, rela, 0)
|
||||||
|
|
@ -535,10 +513,6 @@ func addgotsym(s *ld.LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func adddynsym(ctxt *ld.Link, s *ld.LSym) {
|
func adddynsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
var d *ld.LSym
|
|
||||||
var t int
|
|
||||||
var name string
|
|
||||||
|
|
||||||
if s.Dynid >= 0 {
|
if s.Dynid >= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -547,13 +521,13 @@ func adddynsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
s.Dynid = int32(ld.Nelfsym)
|
s.Dynid = int32(ld.Nelfsym)
|
||||||
ld.Nelfsym++
|
ld.Nelfsym++
|
||||||
|
|
||||||
d = ld.Linklookup(ctxt, ".dynsym", 0)
|
d := ld.Linklookup(ctxt, ".dynsym", 0)
|
||||||
|
|
||||||
name = s.Extname
|
name := s.Extname
|
||||||
ld.Adduint32(ctxt, d, uint32(ld.Addstring(ld.Linklookup(ctxt, ".dynstr", 0), name)))
|
ld.Adduint32(ctxt, d, uint32(ld.Addstring(ld.Linklookup(ctxt, ".dynstr", 0), name)))
|
||||||
|
|
||||||
/* type */
|
/* type */
|
||||||
t = ld.STB_GLOBAL << 4
|
t := ld.STB_GLOBAL << 4
|
||||||
|
|
||||||
if s.Cgoexport != 0 && s.Type&ld.SMASK == ld.STEXT {
|
if s.Cgoexport != 0 && s.Type&ld.SMASK == ld.STEXT {
|
||||||
t |= ld.STT_FUNC
|
t |= ld.STT_FUNC
|
||||||
|
|
@ -595,14 +569,12 @@ func adddynsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func adddynlib(lib string) {
|
func adddynlib(lib string) {
|
||||||
var s *ld.LSym
|
|
||||||
|
|
||||||
if needlib(lib) == 0 {
|
if needlib(lib) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
s = ld.Linklookup(ld.Ctxt, ".dynstr", 0)
|
s := ld.Linklookup(ld.Ctxt, ".dynstr", 0)
|
||||||
if s.Size == 0 {
|
if s.Size == 0 {
|
||||||
ld.Addstring(s, "")
|
ld.Addstring(s, "")
|
||||||
}
|
}
|
||||||
|
|
@ -615,15 +587,6 @@ func adddynlib(lib string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func asmb() {
|
func asmb() {
|
||||||
var magic int32
|
|
||||||
var i int
|
|
||||||
var vl int64
|
|
||||||
var symo int64
|
|
||||||
var dwarfoff int64
|
|
||||||
var machlink int64
|
|
||||||
var sect *ld.Section
|
|
||||||
var sym *ld.LSym
|
|
||||||
|
|
||||||
if ld.Debug['v'] != 0 {
|
if ld.Debug['v'] != 0 {
|
||||||
fmt.Fprintf(&ld.Bso, "%5.2f asmb\n", obj.Cputime())
|
fmt.Fprintf(&ld.Bso, "%5.2f asmb\n", obj.Cputime())
|
||||||
}
|
}
|
||||||
|
|
@ -638,7 +601,7 @@ func asmb() {
|
||||||
ld.Asmbelfsetup()
|
ld.Asmbelfsetup()
|
||||||
}
|
}
|
||||||
|
|
||||||
sect = ld.Segtext.Sect
|
sect := ld.Segtext.Sect
|
||||||
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
|
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
|
||||||
ld.Codeblk(int64(sect.Vaddr), int64(sect.Length))
|
ld.Codeblk(int64(sect.Vaddr), int64(sect.Length))
|
||||||
for sect = sect.Next; sect != nil; sect = sect.Next {
|
for sect = sect.Next; sect != nil; sect = sect.Next {
|
||||||
|
|
@ -664,13 +627,13 @@ func asmb() {
|
||||||
ld.Cseek(int64(ld.Segdata.Fileoff))
|
ld.Cseek(int64(ld.Segdata.Fileoff))
|
||||||
ld.Datblk(int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
|
ld.Datblk(int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
|
||||||
|
|
||||||
machlink = 0
|
machlink := int64(0)
|
||||||
if ld.HEADTYPE == ld.Hdarwin {
|
if ld.HEADTYPE == ld.Hdarwin {
|
||||||
if ld.Debug['v'] != 0 {
|
if ld.Debug['v'] != 0 {
|
||||||
fmt.Fprintf(&ld.Bso, "%5.2f dwarf\n", obj.Cputime())
|
fmt.Fprintf(&ld.Bso, "%5.2f dwarf\n", obj.Cputime())
|
||||||
}
|
}
|
||||||
|
|
||||||
dwarfoff = ld.Rnd(int64(uint64(ld.HEADR)+ld.Segtext.Length), int64(ld.INITRND)) + ld.Rnd(int64(ld.Segdata.Filelen), int64(ld.INITRND))
|
dwarfoff := ld.Rnd(int64(uint64(ld.HEADR)+ld.Segtext.Length), int64(ld.INITRND)) + ld.Rnd(int64(ld.Segdata.Filelen), int64(ld.INITRND))
|
||||||
ld.Cseek(dwarfoff)
|
ld.Cseek(dwarfoff)
|
||||||
|
|
||||||
ld.Segdwarf.Fileoff = uint64(ld.Cpos())
|
ld.Segdwarf.Fileoff = uint64(ld.Cpos())
|
||||||
|
|
@ -708,7 +671,7 @@ func asmb() {
|
||||||
ld.Symsize = 0
|
ld.Symsize = 0
|
||||||
ld.Spsize = 0
|
ld.Spsize = 0
|
||||||
ld.Lcsize = 0
|
ld.Lcsize = 0
|
||||||
symo = 0
|
symo := int64(0)
|
||||||
if ld.Debug['s'] == 0 {
|
if ld.Debug['s'] == 0 {
|
||||||
if ld.Debug['v'] != 0 {
|
if ld.Debug['v'] != 0 {
|
||||||
fmt.Fprintf(&ld.Bso, "%5.2f sym\n", obj.Cputime())
|
fmt.Fprintf(&ld.Bso, "%5.2f sym\n", obj.Cputime())
|
||||||
|
|
@ -763,10 +726,10 @@ func asmb() {
|
||||||
ld.Asmplan9sym()
|
ld.Asmplan9sym()
|
||||||
ld.Cflush()
|
ld.Cflush()
|
||||||
|
|
||||||
sym = ld.Linklookup(ld.Ctxt, "pclntab", 0)
|
sym := ld.Linklookup(ld.Ctxt, "pclntab", 0)
|
||||||
if sym != nil {
|
if sym != nil {
|
||||||
ld.Lcsize = int32(len(sym.P))
|
ld.Lcsize = int32(len(sym.P))
|
||||||
for i = 0; int32(i) < ld.Lcsize; i++ {
|
for i := 0; int32(i) < ld.Lcsize; i++ {
|
||||||
ld.Cput(uint8(sym.P[i]))
|
ld.Cput(uint8(sym.P[i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -795,7 +758,7 @@ func asmb() {
|
||||||
switch ld.HEADTYPE {
|
switch ld.HEADTYPE {
|
||||||
default:
|
default:
|
||||||
case ld.Hplan9: /* plan9 */
|
case ld.Hplan9: /* plan9 */
|
||||||
magic = 4*26*26 + 7
|
magic := int32(4*26*26 + 7)
|
||||||
|
|
||||||
magic |= 0x00008000 /* fat header */
|
magic |= 0x00008000 /* fat header */
|
||||||
ld.Lputb(uint32(magic)) /* magic */
|
ld.Lputb(uint32(magic)) /* magic */
|
||||||
|
|
@ -803,7 +766,7 @@ func asmb() {
|
||||||
ld.Lputb(uint32(ld.Segdata.Filelen))
|
ld.Lputb(uint32(ld.Segdata.Filelen))
|
||||||
ld.Lputb(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
|
ld.Lputb(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
|
||||||
ld.Lputb(uint32(ld.Symsize)) /* nsyms */
|
ld.Lputb(uint32(ld.Symsize)) /* nsyms */
|
||||||
vl = ld.Entryvalue()
|
vl := ld.Entryvalue()
|
||||||
ld.Lputb(PADDR(uint32(vl))) /* va of entry */
|
ld.Lputb(PADDR(uint32(vl))) /* va of entry */
|
||||||
ld.Lputb(uint32(ld.Spsize)) /* sp offsets */
|
ld.Lputb(uint32(ld.Spsize)) /* sp offsets */
|
||||||
ld.Lputb(uint32(ld.Lcsize)) /* line offsets */
|
ld.Lputb(uint32(ld.Lcsize)) /* line offsets */
|
||||||
|
|
|
||||||
|
|
@ -254,8 +254,15 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
|
|
||||||
case gc.OMINUS,
|
case gc.OMINUS,
|
||||||
gc.OCOM:
|
gc.OCOM:
|
||||||
a = optoas(int(n.Op), nl.Type)
|
a := optoas(int(n.Op), nl.Type)
|
||||||
goto uop
|
// unary
|
||||||
|
var n1 gc.Node
|
||||||
|
gc.Tempname(&n1, nl.Type)
|
||||||
|
|
||||||
|
cgen(nl, &n1)
|
||||||
|
gins(a, nil, &n1)
|
||||||
|
gmove(&n1, res)
|
||||||
|
return
|
||||||
|
|
||||||
// symmetric binary
|
// symmetric binary
|
||||||
case gc.OAND,
|
case gc.OAND,
|
||||||
|
|
@ -270,7 +277,13 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
goto sbop
|
// symmetric binary
|
||||||
|
if nl.Ullman < nr.Ullman || nl.Op == gc.OLITERAL {
|
||||||
|
r := nl
|
||||||
|
nl = nr
|
||||||
|
nr = r
|
||||||
|
}
|
||||||
|
goto abop
|
||||||
|
|
||||||
// asymmetric binary
|
// asymmetric binary
|
||||||
case gc.OSUB:
|
case gc.OSUB:
|
||||||
|
|
@ -443,13 +456,6 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
sbop: // symmetric binary
|
|
||||||
if nl.Ullman < nr.Ullman || nl.Op == gc.OLITERAL {
|
|
||||||
r := nl
|
|
||||||
nl = nr
|
|
||||||
nr = r
|
|
||||||
}
|
|
||||||
|
|
||||||
abop: // asymmetric binary
|
abop: // asymmetric binary
|
||||||
if gc.Smallintconst(nr) {
|
if gc.Smallintconst(nr) {
|
||||||
var n1 gc.Node
|
var n1 gc.Node
|
||||||
|
|
@ -488,15 +494,6 @@ abop: // asymmetric binary
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
uop: // unary
|
|
||||||
var n1 gc.Node
|
|
||||||
gc.Tempname(&n1, nl.Type)
|
|
||||||
|
|
||||||
cgen(nl, &n1)
|
|
||||||
gins(a, nil, &n1)
|
|
||||||
gmove(&n1, res)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,7 @@ func cgen64(n *gc.Node, res *gc.Node) {
|
||||||
gins(i386.AMOVL, ncon(0), &lo2)
|
gins(i386.AMOVL, ncon(0), &lo2)
|
||||||
gins(i386.AMOVL, ncon(0), &hi2)
|
gins(i386.AMOVL, ncon(0), &hi2)
|
||||||
splitclean()
|
splitclean()
|
||||||
goto out
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if v >= 32 {
|
if v >= 32 {
|
||||||
|
|
@ -215,7 +215,7 @@ func cgen64(n *gc.Node, res *gc.Node) {
|
||||||
gins(i386.AMOVL, ncon(0), &lo2)
|
gins(i386.AMOVL, ncon(0), &lo2)
|
||||||
splitclean()
|
splitclean()
|
||||||
splitclean()
|
splitclean()
|
||||||
goto out
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// general shift
|
// general shift
|
||||||
|
|
@ -296,7 +296,7 @@ func cgen64(n *gc.Node, res *gc.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
splitclean()
|
splitclean()
|
||||||
goto out
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if v >= 32 {
|
if v >= 32 {
|
||||||
|
|
@ -316,7 +316,7 @@ func cgen64(n *gc.Node, res *gc.Node) {
|
||||||
}
|
}
|
||||||
splitclean()
|
splitclean()
|
||||||
splitclean()
|
splitclean()
|
||||||
goto out
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// general shift
|
// general shift
|
||||||
|
|
@ -482,7 +482,7 @@ func cgen64(n *gc.Node, res *gc.Node) {
|
||||||
|
|
||||||
splitclean()
|
splitclean()
|
||||||
splitclean()
|
splitclean()
|
||||||
goto out
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
gins(i386.AMOVL, &lo1, &ax)
|
gins(i386.AMOVL, &lo1, &ax)
|
||||||
|
|
@ -500,8 +500,6 @@ func cgen64(n *gc.Node, res *gc.Node) {
|
||||||
gins(i386.AMOVL, &ax, &lo1)
|
gins(i386.AMOVL, &ax, &lo1)
|
||||||
gins(i386.AMOVL, &dx, &hi1)
|
gins(i386.AMOVL, &dx, &hi1)
|
||||||
splitclean()
|
splitclean()
|
||||||
|
|
||||||
out:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -934,7 +934,27 @@ func cgen_float387(n *gc.Node, res *gc.Node) {
|
||||||
gc.Nodreg(&f0, nl.Type, i386.REG_F0)
|
gc.Nodreg(&f0, nl.Type, i386.REG_F0)
|
||||||
gc.Nodreg(&f1, n.Type, i386.REG_F0+1)
|
gc.Nodreg(&f1, n.Type, i386.REG_F0+1)
|
||||||
if nr != nil {
|
if nr != nil {
|
||||||
goto flt2
|
// binary
|
||||||
|
if nl.Ullman >= nr.Ullman {
|
||||||
|
cgen(nl, &f0)
|
||||||
|
if nr.Addable != 0 {
|
||||||
|
gins(foptoas(int(n.Op), n.Type, 0), nr, &f0)
|
||||||
|
} else {
|
||||||
|
cgen(nr, &f0)
|
||||||
|
gins(foptoas(int(n.Op), n.Type, Fpop), &f0, &f1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cgen(nr, &f0)
|
||||||
|
if nl.Addable != 0 {
|
||||||
|
gins(foptoas(int(n.Op), n.Type, Frev), nl, &f0)
|
||||||
|
} else {
|
||||||
|
cgen(nl, &f0)
|
||||||
|
gins(foptoas(int(n.Op), n.Type, Frev|Fpop), &f0, &f1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gmove(&f0, res)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// unary
|
// unary
|
||||||
|
|
@ -945,28 +965,6 @@ func cgen_float387(n *gc.Node, res *gc.Node) {
|
||||||
}
|
}
|
||||||
gmove(&f0, res)
|
gmove(&f0, res)
|
||||||
return
|
return
|
||||||
|
|
||||||
flt2: // binary
|
|
||||||
if nl.Ullman >= nr.Ullman {
|
|
||||||
cgen(nl, &f0)
|
|
||||||
if nr.Addable != 0 {
|
|
||||||
gins(foptoas(int(n.Op), n.Type, 0), nr, &f0)
|
|
||||||
} else {
|
|
||||||
cgen(nr, &f0)
|
|
||||||
gins(foptoas(int(n.Op), n.Type, Fpop), &f0, &f1)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cgen(nr, &f0)
|
|
||||||
if nl.Addable != 0 {
|
|
||||||
gins(foptoas(int(n.Op), n.Type, Frev), nl, &f0)
|
|
||||||
} else {
|
|
||||||
cgen(nl, &f0)
|
|
||||||
gins(foptoas(int(n.Op), n.Type, Frev|Fpop), &f0, &f1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gmove(&f0, res)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func cgen_floatsse(n *gc.Node, res *gc.Node) {
|
func cgen_floatsse(n *gc.Node, res *gc.Node) {
|
||||||
|
|
@ -1064,7 +1062,47 @@ func bgen_float(n *gc.Node, true_ int, likely int, to *obj.Prog) {
|
||||||
var n2 gc.Node
|
var n2 gc.Node
|
||||||
var ax gc.Node
|
var ax gc.Node
|
||||||
if gc.Use_sse != 0 {
|
if gc.Use_sse != 0 {
|
||||||
goto sse
|
if nl.Addable == 0 {
|
||||||
|
var n1 gc.Node
|
||||||
|
gc.Tempname(&n1, nl.Type)
|
||||||
|
cgen(nl, &n1)
|
||||||
|
nl = &n1
|
||||||
|
}
|
||||||
|
|
||||||
|
if nr.Addable == 0 {
|
||||||
|
var tmp gc.Node
|
||||||
|
gc.Tempname(&tmp, nr.Type)
|
||||||
|
cgen(nr, &tmp)
|
||||||
|
nr = &tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
var n2 gc.Node
|
||||||
|
regalloc(&n2, nr.Type, nil)
|
||||||
|
gmove(nr, &n2)
|
||||||
|
nr = &n2
|
||||||
|
|
||||||
|
if nl.Op != gc.OREGISTER {
|
||||||
|
var n3 gc.Node
|
||||||
|
regalloc(&n3, nl.Type, nil)
|
||||||
|
gmove(nl, &n3)
|
||||||
|
nl = &n3
|
||||||
|
}
|
||||||
|
|
||||||
|
if a == gc.OGE || a == gc.OGT {
|
||||||
|
// only < and <= work right with NaN; reverse if needed
|
||||||
|
r := nr
|
||||||
|
|
||||||
|
nr = nl
|
||||||
|
nl = r
|
||||||
|
a = gc.Brrev(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
gins(foptoas(gc.OCMP, nr.Type, 0), nl, nr)
|
||||||
|
if nl.Op == gc.OREGISTER {
|
||||||
|
regfree(nl)
|
||||||
|
}
|
||||||
|
regfree(nr)
|
||||||
|
goto ret
|
||||||
} else {
|
} else {
|
||||||
goto x87
|
goto x87
|
||||||
}
|
}
|
||||||
|
|
@ -1118,47 +1156,6 @@ x87:
|
||||||
|
|
||||||
goto ret
|
goto ret
|
||||||
|
|
||||||
sse:
|
|
||||||
if nl.Addable == 0 {
|
|
||||||
var n1 gc.Node
|
|
||||||
gc.Tempname(&n1, nl.Type)
|
|
||||||
cgen(nl, &n1)
|
|
||||||
nl = &n1
|
|
||||||
}
|
|
||||||
|
|
||||||
if nr.Addable == 0 {
|
|
||||||
var tmp gc.Node
|
|
||||||
gc.Tempname(&tmp, nr.Type)
|
|
||||||
cgen(nr, &tmp)
|
|
||||||
nr = &tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
regalloc(&n2, nr.Type, nil)
|
|
||||||
gmove(nr, &n2)
|
|
||||||
nr = &n2
|
|
||||||
|
|
||||||
if nl.Op != gc.OREGISTER {
|
|
||||||
var n3 gc.Node
|
|
||||||
regalloc(&n3, nl.Type, nil)
|
|
||||||
gmove(nl, &n3)
|
|
||||||
nl = &n3
|
|
||||||
}
|
|
||||||
|
|
||||||
if a == gc.OGE || a == gc.OGT {
|
|
||||||
// only < and <= work right with NaN; reverse if needed
|
|
||||||
r := nr
|
|
||||||
|
|
||||||
nr = nl
|
|
||||||
nl = r
|
|
||||||
a = gc.Brrev(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
gins(foptoas(gc.OCMP, nr.Type, 0), nl, nr)
|
|
||||||
if nl.Op == gc.OREGISTER {
|
|
||||||
regfree(nl)
|
|
||||||
}
|
|
||||||
regfree(nr)
|
|
||||||
|
|
||||||
ret:
|
ret:
|
||||||
if a == gc.OEQ {
|
if a == gc.OEQ {
|
||||||
// neither NE nor P
|
// neither NE nor P
|
||||||
|
|
|
||||||
|
|
@ -403,7 +403,48 @@ func foptoas(op int, t *gc.Type, flg int) int {
|
||||||
et := int(gc.Simtype[t.Etype])
|
et := int(gc.Simtype[t.Etype])
|
||||||
|
|
||||||
if gc.Use_sse != 0 {
|
if gc.Use_sse != 0 {
|
||||||
goto sse
|
switch uint32(op)<<16 | uint32(et) {
|
||||||
|
default:
|
||||||
|
gc.Fatal("foptoas-sse: no entry %v-%v", gc.Oconv(int(op), 0), gc.Tconv(t, 0))
|
||||||
|
|
||||||
|
case gc.OCMP<<16 | gc.TFLOAT32:
|
||||||
|
a = i386.AUCOMISS
|
||||||
|
|
||||||
|
case gc.OCMP<<16 | gc.TFLOAT64:
|
||||||
|
a = i386.AUCOMISD
|
||||||
|
|
||||||
|
case gc.OAS<<16 | gc.TFLOAT32:
|
||||||
|
a = i386.AMOVSS
|
||||||
|
|
||||||
|
case gc.OAS<<16 | gc.TFLOAT64:
|
||||||
|
a = i386.AMOVSD
|
||||||
|
|
||||||
|
case gc.OADD<<16 | gc.TFLOAT32:
|
||||||
|
a = i386.AADDSS
|
||||||
|
|
||||||
|
case gc.OADD<<16 | gc.TFLOAT64:
|
||||||
|
a = i386.AADDSD
|
||||||
|
|
||||||
|
case gc.OSUB<<16 | gc.TFLOAT32:
|
||||||
|
a = i386.ASUBSS
|
||||||
|
|
||||||
|
case gc.OSUB<<16 | gc.TFLOAT64:
|
||||||
|
a = i386.ASUBSD
|
||||||
|
|
||||||
|
case gc.OMUL<<16 | gc.TFLOAT32:
|
||||||
|
a = i386.AMULSS
|
||||||
|
|
||||||
|
case gc.OMUL<<16 | gc.TFLOAT64:
|
||||||
|
a = i386.AMULSD
|
||||||
|
|
||||||
|
case gc.ODIV<<16 | gc.TFLOAT32:
|
||||||
|
a = i386.ADIVSS
|
||||||
|
|
||||||
|
case gc.ODIV<<16 | gc.TFLOAT64:
|
||||||
|
a = i386.ADIVSD
|
||||||
|
}
|
||||||
|
|
||||||
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we need Fpop, it means we're working on
|
// If we need Fpop, it means we're working on
|
||||||
|
|
@ -499,50 +540,6 @@ func foptoas(op int, t *gc.Type, flg int) int {
|
||||||
|
|
||||||
gc.Fatal("foptoas %v %v %#x", gc.Oconv(int(op), 0), gc.Tconv(t, 0), flg)
|
gc.Fatal("foptoas %v %v %#x", gc.Oconv(int(op), 0), gc.Tconv(t, 0), flg)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
sse:
|
|
||||||
switch uint32(op)<<16 | uint32(et) {
|
|
||||||
default:
|
|
||||||
gc.Fatal("foptoas-sse: no entry %v-%v", gc.Oconv(int(op), 0), gc.Tconv(t, 0))
|
|
||||||
|
|
||||||
case gc.OCMP<<16 | gc.TFLOAT32:
|
|
||||||
a = i386.AUCOMISS
|
|
||||||
|
|
||||||
case gc.OCMP<<16 | gc.TFLOAT64:
|
|
||||||
a = i386.AUCOMISD
|
|
||||||
|
|
||||||
case gc.OAS<<16 | gc.TFLOAT32:
|
|
||||||
a = i386.AMOVSS
|
|
||||||
|
|
||||||
case gc.OAS<<16 | gc.TFLOAT64:
|
|
||||||
a = i386.AMOVSD
|
|
||||||
|
|
||||||
case gc.OADD<<16 | gc.TFLOAT32:
|
|
||||||
a = i386.AADDSS
|
|
||||||
|
|
||||||
case gc.OADD<<16 | gc.TFLOAT64:
|
|
||||||
a = i386.AADDSD
|
|
||||||
|
|
||||||
case gc.OSUB<<16 | gc.TFLOAT32:
|
|
||||||
a = i386.ASUBSS
|
|
||||||
|
|
||||||
case gc.OSUB<<16 | gc.TFLOAT64:
|
|
||||||
a = i386.ASUBSD
|
|
||||||
|
|
||||||
case gc.OMUL<<16 | gc.TFLOAT32:
|
|
||||||
a = i386.AMULSS
|
|
||||||
|
|
||||||
case gc.OMUL<<16 | gc.TFLOAT64:
|
|
||||||
a = i386.AMULSD
|
|
||||||
|
|
||||||
case gc.ODIV<<16 | gc.TFLOAT32:
|
|
||||||
a = i386.ADIVSS
|
|
||||||
|
|
||||||
case gc.ODIV<<16 | gc.TFLOAT64:
|
|
||||||
a = i386.ADIVSD
|
|
||||||
}
|
|
||||||
|
|
||||||
return a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var resvd = []int{
|
var resvd = []int{
|
||||||
|
|
@ -928,7 +925,9 @@ func gmove(f *gc.Node, t *gc.Node) {
|
||||||
|
|
||||||
switch uint32(ft)<<16 | uint32(tt) {
|
switch uint32(ft)<<16 | uint32(tt) {
|
||||||
default:
|
default:
|
||||||
goto fatal
|
// should not happen
|
||||||
|
gc.Fatal("gmove %v -> %v", gc.Nconv(f, 0), gc.Nconv(t, 0))
|
||||||
|
return
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* integer copy and truncate
|
* integer copy and truncate
|
||||||
|
|
@ -1164,10 +1163,6 @@ hard:
|
||||||
gmove(&r1, t)
|
gmove(&r1, t)
|
||||||
regfree(&r1)
|
regfree(&r1)
|
||||||
return
|
return
|
||||||
|
|
||||||
// should not happen
|
|
||||||
fatal:
|
|
||||||
gc.Fatal("gmove %v -> %v", gc.Nconv(f, 0), gc.Nconv(t, 0))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func floatmove(f *gc.Node, t *gc.Node) {
|
func floatmove(f *gc.Node, t *gc.Node) {
|
||||||
|
|
|
||||||
|
|
@ -371,8 +371,7 @@ func subprop(r0 *gc.Flow) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
var info gc.ProgInfo
|
var info gc.ProgInfo
|
||||||
var r *gc.Flow
|
for r := gc.Uniqp(r0); r != nil; r = gc.Uniqp(r) {
|
||||||
for r = gc.Uniqp(r0); r != nil; r = gc.Uniqp(r) {
|
|
||||||
if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
|
if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
|
||||||
fmt.Printf("\t? %v\n", r.Prog)
|
fmt.Printf("\t? %v\n", r.Prog)
|
||||||
}
|
}
|
||||||
|
|
@ -393,7 +392,31 @@ func subprop(r0 *gc.Flow) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.Flags&gc.Move != 0) && (info.Flags&(gc.SizeL|gc.SizeQ|gc.SizeF|gc.SizeD) != 0) && p.To.Type == v1.Type && p.To.Reg == v1.Reg {
|
if (info.Flags&gc.Move != 0) && (info.Flags&(gc.SizeL|gc.SizeQ|gc.SizeF|gc.SizeD) != 0) && p.To.Type == v1.Type && p.To.Reg == v1.Reg {
|
||||||
goto gotit
|
copysub(&p.To, v1, v2, 1)
|
||||||
|
if gc.Debug['P'] != 0 {
|
||||||
|
fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
|
||||||
|
if p.From.Type == v2.Type && p.From.Reg == v2.Reg {
|
||||||
|
fmt.Printf(" excise")
|
||||||
|
}
|
||||||
|
fmt.Printf("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
|
||||||
|
p = r.Prog
|
||||||
|
copysub(&p.From, v1, v2, 1)
|
||||||
|
copysub(&p.To, v1, v2, 1)
|
||||||
|
if gc.Debug['P'] != 0 {
|
||||||
|
fmt.Printf("%v\n", r.Prog)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t := int(v1.Reg)
|
||||||
|
v1.Reg = v2.Reg
|
||||||
|
v2.Reg = int16(t)
|
||||||
|
if gc.Debug['P'] != 0 {
|
||||||
|
fmt.Printf("%v last\n", r.Prog)
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if copyau(&p.From, v2) || copyau(&p.To, v2) {
|
if copyau(&p.From, v2) || copyau(&p.To, v2) {
|
||||||
|
|
@ -405,33 +428,6 @@ func subprop(r0 *gc.Flow) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|
||||||
gotit:
|
|
||||||
copysub(&p.To, v1, v2, 1)
|
|
||||||
if gc.Debug['P'] != 0 {
|
|
||||||
fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
|
|
||||||
if p.From.Type == v2.Type && p.From.Reg == v2.Reg {
|
|
||||||
fmt.Printf(" excise")
|
|
||||||
}
|
|
||||||
fmt.Printf("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
|
|
||||||
p = r.Prog
|
|
||||||
copysub(&p.From, v1, v2, 1)
|
|
||||||
copysub(&p.To, v1, v2, 1)
|
|
||||||
if gc.Debug['P'] != 0 {
|
|
||||||
fmt.Printf("%v\n", r.Prog)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
t := int(v1.Reg)
|
|
||||||
v1.Reg = v2.Reg
|
|
||||||
v2.Reg = int16(t)
|
|
||||||
if gc.Debug['P'] != 0 {
|
|
||||||
fmt.Printf("%v last\n", r.Prog)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -38,17 +38,14 @@ import (
|
||||||
import "cmd/internal/ld"
|
import "cmd/internal/ld"
|
||||||
|
|
||||||
func needlib(name string) int {
|
func needlib(name string) int {
|
||||||
var p string
|
|
||||||
var s *ld.LSym
|
|
||||||
|
|
||||||
if name[0] == '\x00' {
|
if name[0] == '\x00' {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reuse hash code in symbol table */
|
/* reuse hash code in symbol table */
|
||||||
p = fmt.Sprintf(".dynlib.%s", name)
|
p := fmt.Sprintf(".dynlib.%s", name)
|
||||||
|
|
||||||
s = ld.Linklookup(ld.Ctxt, p, 0)
|
s := ld.Linklookup(ld.Ctxt, p, 0)
|
||||||
|
|
||||||
if s.Type == 0 {
|
if s.Type == 0 {
|
||||||
s.Type = 100 // avoid SDATA, etc.
|
s.Type = 100 // avoid SDATA, etc.
|
||||||
|
|
@ -66,11 +63,7 @@ func adddynrela(rela *ld.LSym, s *ld.LSym, r *ld.Reloc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
||||||
var targ *ld.LSym
|
targ := r.Sym
|
||||||
var rel *ld.LSym
|
|
||||||
var got *ld.LSym
|
|
||||||
|
|
||||||
targ = r.Sym
|
|
||||||
ld.Ctxt.Cursym = s
|
ld.Ctxt.Cursym = s
|
||||||
|
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
|
|
@ -210,7 +203,7 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
||||||
}
|
}
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
adddynsym(ld.Ctxt, targ)
|
adddynsym(ld.Ctxt, targ)
|
||||||
rel = ld.Linklookup(ld.Ctxt, ".rel", 0)
|
rel := ld.Linklookup(ld.Ctxt, ".rel", 0)
|
||||||
ld.Addaddrplus(ld.Ctxt, rel, s, int64(r.Off))
|
ld.Addaddrplus(ld.Ctxt, rel, s, int64(r.Off))
|
||||||
ld.Adduint32(ld.Ctxt, rel, ld.ELF32_R_INFO(uint32(targ.Dynid), ld.R_386_32))
|
ld.Adduint32(ld.Ctxt, rel, ld.ELF32_R_INFO(uint32(targ.Dynid), ld.R_386_32))
|
||||||
r.Type = ld.R_CONST // write r->add during relocsym
|
r.Type = ld.R_CONST // write r->add during relocsym
|
||||||
|
|
@ -231,7 +224,7 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
||||||
// but we only need to support cgo and that's all it needs.
|
// but we only need to support cgo and that's all it needs.
|
||||||
adddynsym(ld.Ctxt, targ)
|
adddynsym(ld.Ctxt, targ)
|
||||||
|
|
||||||
got = ld.Linklookup(ld.Ctxt, ".got", 0)
|
got := ld.Linklookup(ld.Ctxt, ".got", 0)
|
||||||
s.Type = got.Type | ld.SSUB
|
s.Type = got.Type | ld.SSUB
|
||||||
s.Outer = got
|
s.Outer = got
|
||||||
s.Sub = got.Sub
|
s.Sub = got.Sub
|
||||||
|
|
@ -249,11 +242,9 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfreloc1(r *ld.Reloc, sectoff int64) int {
|
func elfreloc1(r *ld.Reloc, sectoff int64) int {
|
||||||
var elfsym int32
|
|
||||||
|
|
||||||
ld.Thearch.Lput(uint32(sectoff))
|
ld.Thearch.Lput(uint32(sectoff))
|
||||||
|
|
||||||
elfsym = r.Xsym.Elfsym
|
elfsym := r.Xsym.Elfsym
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
default:
|
default:
|
||||||
return -1
|
return -1
|
||||||
|
|
@ -287,9 +278,8 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int {
|
||||||
|
|
||||||
func machoreloc1(r *ld.Reloc, sectoff int64) int {
|
func machoreloc1(r *ld.Reloc, sectoff int64) int {
|
||||||
var v uint32
|
var v uint32
|
||||||
var rs *ld.LSym
|
|
||||||
|
|
||||||
rs = r.Xsym
|
rs := r.Xsym
|
||||||
|
|
||||||
if rs.Type == ld.SHOSTOBJ {
|
if rs.Type == ld.SHOSTOBJ {
|
||||||
if rs.Dynid < 0 {
|
if rs.Dynid < 0 {
|
||||||
|
|
@ -365,11 +355,8 @@ func archrelocvariant(r *ld.Reloc, s *ld.LSym, t int64) int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfsetupplt() {
|
func elfsetupplt() {
|
||||||
var plt *ld.LSym
|
plt := ld.Linklookup(ld.Ctxt, ".plt", 0)
|
||||||
var got *ld.LSym
|
got := ld.Linklookup(ld.Ctxt, ".got.plt", 0)
|
||||||
|
|
||||||
plt = ld.Linklookup(ld.Ctxt, ".plt", 0)
|
|
||||||
got = ld.Linklookup(ld.Ctxt, ".got.plt", 0)
|
|
||||||
if plt.Size == 0 {
|
if plt.Size == 0 {
|
||||||
// pushl got+4
|
// pushl got+4
|
||||||
ld.Adduint8(ld.Ctxt, plt, 0xff)
|
ld.Adduint8(ld.Ctxt, plt, 0xff)
|
||||||
|
|
@ -395,10 +382,6 @@ func elfsetupplt() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func addpltsym(ctxt *ld.Link, s *ld.LSym) {
|
func addpltsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
var plt *ld.LSym
|
|
||||||
var got *ld.LSym
|
|
||||||
var rel *ld.LSym
|
|
||||||
|
|
||||||
if s.Plt >= 0 {
|
if s.Plt >= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -406,9 +389,9 @@ func addpltsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
adddynsym(ctxt, s)
|
adddynsym(ctxt, s)
|
||||||
|
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
plt = ld.Linklookup(ctxt, ".plt", 0)
|
plt := ld.Linklookup(ctxt, ".plt", 0)
|
||||||
got = ld.Linklookup(ctxt, ".got.plt", 0)
|
got := ld.Linklookup(ctxt, ".got.plt", 0)
|
||||||
rel = ld.Linklookup(ctxt, ".rel.plt", 0)
|
rel := ld.Linklookup(ctxt, ".rel.plt", 0)
|
||||||
if plt.Size == 0 {
|
if plt.Size == 0 {
|
||||||
elfsetupplt()
|
elfsetupplt()
|
||||||
}
|
}
|
||||||
|
|
@ -441,9 +424,7 @@ func addpltsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
} else if ld.HEADTYPE == ld.Hdarwin {
|
} else if ld.HEADTYPE == ld.Hdarwin {
|
||||||
// Same laziness as in 6l.
|
// Same laziness as in 6l.
|
||||||
|
|
||||||
var plt *ld.LSym
|
plt := ld.Linklookup(ctxt, ".plt", 0)
|
||||||
|
|
||||||
plt = ld.Linklookup(ctxt, ".plt", 0)
|
|
||||||
|
|
||||||
addgotsym(ctxt, s)
|
addgotsym(ctxt, s)
|
||||||
|
|
||||||
|
|
@ -461,20 +442,17 @@ func addpltsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func addgotsym(ctxt *ld.Link, s *ld.LSym) {
|
func addgotsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
var got *ld.LSym
|
|
||||||
var rel *ld.LSym
|
|
||||||
|
|
||||||
if s.Got >= 0 {
|
if s.Got >= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
adddynsym(ctxt, s)
|
adddynsym(ctxt, s)
|
||||||
got = ld.Linklookup(ctxt, ".got", 0)
|
got := ld.Linklookup(ctxt, ".got", 0)
|
||||||
s.Got = int32(got.Size)
|
s.Got = int32(got.Size)
|
||||||
ld.Adduint32(ctxt, got, 0)
|
ld.Adduint32(ctxt, got, 0)
|
||||||
|
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
rel = ld.Linklookup(ctxt, ".rel", 0)
|
rel := ld.Linklookup(ctxt, ".rel", 0)
|
||||||
ld.Addaddrplus(ctxt, rel, got, int64(s.Got))
|
ld.Addaddrplus(ctxt, rel, got, int64(s.Got))
|
||||||
ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_386_GLOB_DAT))
|
ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_386_GLOB_DAT))
|
||||||
} else if ld.HEADTYPE == ld.Hdarwin {
|
} else if ld.HEADTYPE == ld.Hdarwin {
|
||||||
|
|
@ -485,10 +463,6 @@ func addgotsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func adddynsym(ctxt *ld.Link, s *ld.LSym) {
|
func adddynsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
var d *ld.LSym
|
|
||||||
var t int
|
|
||||||
var name string
|
|
||||||
|
|
||||||
if s.Dynid >= 0 {
|
if s.Dynid >= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -497,10 +471,10 @@ func adddynsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
s.Dynid = int32(ld.Nelfsym)
|
s.Dynid = int32(ld.Nelfsym)
|
||||||
ld.Nelfsym++
|
ld.Nelfsym++
|
||||||
|
|
||||||
d = ld.Linklookup(ctxt, ".dynsym", 0)
|
d := ld.Linklookup(ctxt, ".dynsym", 0)
|
||||||
|
|
||||||
/* name */
|
/* name */
|
||||||
name = s.Extname
|
name := s.Extname
|
||||||
|
|
||||||
ld.Adduint32(ctxt, d, uint32(ld.Addstring(ld.Linklookup(ctxt, ".dynstr", 0), name)))
|
ld.Adduint32(ctxt, d, uint32(ld.Addstring(ld.Linklookup(ctxt, ".dynstr", 0), name)))
|
||||||
|
|
||||||
|
|
@ -515,7 +489,7 @@ func adddynsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
ld.Adduint32(ctxt, d, 0)
|
ld.Adduint32(ctxt, d, 0)
|
||||||
|
|
||||||
/* type */
|
/* type */
|
||||||
t = ld.STB_GLOBAL << 4
|
t := ld.STB_GLOBAL << 4
|
||||||
|
|
||||||
if s.Cgoexport != 0 && s.Type&ld.SMASK == ld.STEXT {
|
if s.Cgoexport != 0 && s.Type&ld.SMASK == ld.STEXT {
|
||||||
t |= ld.STT_FUNC
|
t |= ld.STT_FUNC
|
||||||
|
|
@ -541,14 +515,12 @@ func adddynsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func adddynlib(lib string) {
|
func adddynlib(lib string) {
|
||||||
var s *ld.LSym
|
|
||||||
|
|
||||||
if needlib(lib) == 0 {
|
if needlib(lib) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
s = ld.Linklookup(ld.Ctxt, ".dynstr", 0)
|
s := ld.Linklookup(ld.Ctxt, ".dynstr", 0)
|
||||||
if s.Size == 0 {
|
if s.Size == 0 {
|
||||||
ld.Addstring(s, "")
|
ld.Addstring(s, "")
|
||||||
}
|
}
|
||||||
|
|
@ -561,14 +533,6 @@ func adddynlib(lib string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func asmb() {
|
func asmb() {
|
||||||
var magic int32
|
|
||||||
var symo uint32
|
|
||||||
var dwarfoff uint32
|
|
||||||
var machlink uint32
|
|
||||||
var sect *ld.Section
|
|
||||||
var sym *ld.LSym
|
|
||||||
var i int
|
|
||||||
|
|
||||||
if ld.Debug['v'] != 0 {
|
if ld.Debug['v'] != 0 {
|
||||||
fmt.Fprintf(&ld.Bso, "%5.2f asmb\n", obj.Cputime())
|
fmt.Fprintf(&ld.Bso, "%5.2f asmb\n", obj.Cputime())
|
||||||
}
|
}
|
||||||
|
|
@ -578,7 +542,7 @@ func asmb() {
|
||||||
ld.Asmbelfsetup()
|
ld.Asmbelfsetup()
|
||||||
}
|
}
|
||||||
|
|
||||||
sect = ld.Segtext.Sect
|
sect := ld.Segtext.Sect
|
||||||
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
|
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
|
||||||
ld.Codeblk(int64(sect.Vaddr), int64(sect.Length))
|
ld.Codeblk(int64(sect.Vaddr), int64(sect.Length))
|
||||||
for sect = sect.Next; sect != nil; sect = sect.Next {
|
for sect = sect.Next; sect != nil; sect = sect.Next {
|
||||||
|
|
@ -604,13 +568,13 @@ func asmb() {
|
||||||
ld.Cseek(int64(ld.Segdata.Fileoff))
|
ld.Cseek(int64(ld.Segdata.Fileoff))
|
||||||
ld.Datblk(int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
|
ld.Datblk(int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
|
||||||
|
|
||||||
machlink = 0
|
machlink := uint32(0)
|
||||||
if ld.HEADTYPE == ld.Hdarwin {
|
if ld.HEADTYPE == ld.Hdarwin {
|
||||||
if ld.Debug['v'] != 0 {
|
if ld.Debug['v'] != 0 {
|
||||||
fmt.Fprintf(&ld.Bso, "%5.2f dwarf\n", obj.Cputime())
|
fmt.Fprintf(&ld.Bso, "%5.2f dwarf\n", obj.Cputime())
|
||||||
}
|
}
|
||||||
|
|
||||||
dwarfoff = uint32(ld.Rnd(int64(uint64(ld.HEADR)+ld.Segtext.Length), int64(ld.INITRND)) + ld.Rnd(int64(ld.Segdata.Filelen), int64(ld.INITRND)))
|
dwarfoff := uint32(ld.Rnd(int64(uint64(ld.HEADR)+ld.Segtext.Length), int64(ld.INITRND)) + ld.Rnd(int64(ld.Segdata.Filelen), int64(ld.INITRND)))
|
||||||
ld.Cseek(int64(dwarfoff))
|
ld.Cseek(int64(dwarfoff))
|
||||||
|
|
||||||
ld.Segdwarf.Fileoff = uint64(ld.Cpos())
|
ld.Segdwarf.Fileoff = uint64(ld.Cpos())
|
||||||
|
|
@ -623,7 +587,7 @@ func asmb() {
|
||||||
ld.Symsize = 0
|
ld.Symsize = 0
|
||||||
ld.Spsize = 0
|
ld.Spsize = 0
|
||||||
ld.Lcsize = 0
|
ld.Lcsize = 0
|
||||||
symo = 0
|
symo := uint32(0)
|
||||||
if ld.Debug['s'] == 0 {
|
if ld.Debug['s'] == 0 {
|
||||||
// TODO: rationalize
|
// TODO: rationalize
|
||||||
if ld.Debug['v'] != 0 {
|
if ld.Debug['v'] != 0 {
|
||||||
|
|
@ -673,10 +637,10 @@ func asmb() {
|
||||||
ld.Asmplan9sym()
|
ld.Asmplan9sym()
|
||||||
ld.Cflush()
|
ld.Cflush()
|
||||||
|
|
||||||
sym = ld.Linklookup(ld.Ctxt, "pclntab", 0)
|
sym := ld.Linklookup(ld.Ctxt, "pclntab", 0)
|
||||||
if sym != nil {
|
if sym != nil {
|
||||||
ld.Lcsize = int32(len(sym.P))
|
ld.Lcsize = int32(len(sym.P))
|
||||||
for i = 0; int32(i) < ld.Lcsize; i++ {
|
for i := 0; int32(i) < ld.Lcsize; i++ {
|
||||||
ld.Cput(uint8(sym.P[i]))
|
ld.Cput(uint8(sym.P[i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -704,7 +668,7 @@ func asmb() {
|
||||||
switch ld.HEADTYPE {
|
switch ld.HEADTYPE {
|
||||||
default:
|
default:
|
||||||
case ld.Hplan9: /* plan9 */
|
case ld.Hplan9: /* plan9 */
|
||||||
magic = 4*11*11 + 7
|
magic := int32(4*11*11 + 7)
|
||||||
|
|
||||||
ld.Lputb(uint32(magic)) /* magic */
|
ld.Lputb(uint32(magic)) /* magic */
|
||||||
ld.Lputb(uint32(ld.Segtext.Filelen)) /* sizes */
|
ld.Lputb(uint32(ld.Segtext.Filelen)) /* sizes */
|
||||||
|
|
|
||||||
|
|
@ -26,13 +26,8 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
gc.Dump("cgen-res", res)
|
gc.Dump("cgen-res", res)
|
||||||
}
|
}
|
||||||
|
|
||||||
var a int
|
|
||||||
var nr *gc.Node
|
|
||||||
var nl *gc.Node
|
|
||||||
var n1 gc.Node
|
|
||||||
var n2 gc.Node
|
|
||||||
if n == nil || n.Type == nil {
|
if n == nil || n.Type == nil {
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if res == nil || res.Type == nil {
|
if res == nil || res.Type == nil {
|
||||||
|
|
@ -57,7 +52,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
} else {
|
} else {
|
||||||
gc.Cgen_slice(n, res)
|
gc.Cgen_slice(n, res)
|
||||||
}
|
}
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
case gc.OEFACE:
|
case gc.OEFACE:
|
||||||
if res.Op != gc.ONAME || res.Addable == 0 {
|
if res.Op != gc.ONAME || res.Addable == 0 {
|
||||||
|
|
@ -68,7 +63,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
} else {
|
} else {
|
||||||
gc.Cgen_eface(n, res)
|
gc.Cgen_eface(n, res)
|
||||||
}
|
}
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Ullman >= gc.UINF {
|
if n.Ullman >= gc.UINF {
|
||||||
|
|
@ -80,7 +75,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
gc.Tempname(&n1, n.Type)
|
gc.Tempname(&n1, n.Type)
|
||||||
cgen(n, &n1)
|
cgen(n, &n1)
|
||||||
cgen(&n1, res)
|
cgen(&n1, res)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,7 +84,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
gc.Fatal("forgot to compute width for %v", gc.Tconv(n.Type, 0))
|
gc.Fatal("forgot to compute width for %v", gc.Tconv(n.Type, 0))
|
||||||
}
|
}
|
||||||
sgen(n, res, n.Type.Width)
|
sgen(n, res, n.Type.Width)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if res.Addable == 0 {
|
if res.Addable == 0 {
|
||||||
|
|
@ -105,7 +100,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
|
|
||||||
cgen(&n1, res)
|
cgen(&n1, res)
|
||||||
regfree(&n1)
|
regfree(&n1)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var f int
|
var f int
|
||||||
|
|
@ -115,7 +110,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
|
|
||||||
if gc.Complexop(n, res) {
|
if gc.Complexop(n, res) {
|
||||||
gc.Complexgen(n, res)
|
gc.Complexgen(n, res)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
f = 1 // gen thru register
|
f = 1 // gen thru register
|
||||||
|
|
@ -148,7 +143,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
fmt.Printf("%v [ignore previous line]\n", p1)
|
fmt.Printf("%v [ignore previous line]\n", p1)
|
||||||
}
|
}
|
||||||
sudoclean()
|
sudoclean()
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,7 +152,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
igen(res, &n1, nil)
|
igen(res, &n1, nil)
|
||||||
cgen(n, &n1)
|
cgen(n, &n1)
|
||||||
regfree(&n1)
|
regfree(&n1)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// update addressability for string, slice
|
// update addressability for string, slice
|
||||||
|
|
@ -181,7 +176,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
|
|
||||||
if gc.Complexop(n, res) {
|
if gc.Complexop(n, res) {
|
||||||
gc.Complexgen(n, res)
|
gc.Complexgen(n, res)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// if both are addressable, move
|
// if both are addressable, move
|
||||||
|
|
@ -196,11 +191,11 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
regfree(&n1)
|
regfree(&n1)
|
||||||
}
|
}
|
||||||
|
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
nl = n.Left
|
nl := n.Left
|
||||||
nr = n.Right
|
nr := n.Right
|
||||||
|
|
||||||
if nl != nil && nl.Ullman >= gc.UINF {
|
if nl != nil && nl.Ullman >= gc.UINF {
|
||||||
if nr != nil && nr.Ullman >= gc.UINF {
|
if nr != nil && nr.Ullman >= gc.UINF {
|
||||||
|
|
@ -210,7 +205,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
n2 := *n
|
n2 := *n
|
||||||
n2.Left = &n1
|
n2.Left = &n1
|
||||||
cgen(&n2, res)
|
cgen(&n2, res)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -231,7 +226,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sudoclean()
|
sudoclean()
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -239,6 +234,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
// OGE, OLE, and ONE ourselves.
|
// OGE, OLE, and ONE ourselves.
|
||||||
// if(nl != N && isfloat[n->type->etype] && isfloat[nl->type->etype]) goto flt;
|
// if(nl != N && isfloat[n->type->etype] && isfloat[nl->type->etype]) goto flt;
|
||||||
|
|
||||||
|
var a int
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
gc.Dump("cgen", n)
|
gc.Dump("cgen", n)
|
||||||
|
|
@ -263,11 +259,11 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
bgen(n, true, 0, p2)
|
bgen(n, true, 0, p2)
|
||||||
gmove(gc.Nodbool(false), res)
|
gmove(gc.Nodbool(false), res)
|
||||||
gc.Patch(p3, gc.Pc)
|
gc.Patch(p3, gc.Pc)
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
case gc.OPLUS:
|
case gc.OPLUS:
|
||||||
cgen(nl, res)
|
cgen(nl, res)
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
// unary
|
// unary
|
||||||
case gc.OCOM:
|
case gc.OCOM:
|
||||||
|
|
@ -281,7 +277,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
gins(a, &n2, &n1)
|
gins(a, &n2, &n1)
|
||||||
gmove(&n1, res)
|
gmove(&n1, res)
|
||||||
regfree(&n1)
|
regfree(&n1)
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
case gc.OMINUS:
|
case gc.OMINUS:
|
||||||
if gc.Isfloat[nl.Type.Etype] != 0 {
|
if gc.Isfloat[nl.Type.Etype] != 0 {
|
||||||
|
|
@ -291,8 +287,16 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
goto sbop
|
goto sbop
|
||||||
}
|
}
|
||||||
|
|
||||||
a = optoas(int(n.Op), nl.Type)
|
a := optoas(int(n.Op), nl.Type)
|
||||||
goto uop
|
// unary
|
||||||
|
var n1 gc.Node
|
||||||
|
regalloc(&n1, nl.Type, res)
|
||||||
|
|
||||||
|
cgen(nl, &n1)
|
||||||
|
gins(a, nil, &n1)
|
||||||
|
gmove(&n1, res)
|
||||||
|
regfree(&n1)
|
||||||
|
return
|
||||||
|
|
||||||
// symmetric binary
|
// symmetric binary
|
||||||
case gc.OAND,
|
case gc.OAND,
|
||||||
|
|
@ -331,7 +335,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
gmove(&n2, res)
|
gmove(&n2, res)
|
||||||
regfree(&n2)
|
regfree(&n2)
|
||||||
regfree(&n1)
|
regfree(&n1)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -523,7 +527,7 @@ func cgen(n *gc.Node, res *gc.Node) {
|
||||||
cgen_shift(int(n.Op), n.Bounded, nl, nr, res)
|
cgen_shift(int(n.Op), n.Bounded, nl, nr, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* put simplest on right - we'll generate into left
|
* put simplest on right - we'll generate into left
|
||||||
|
|
@ -549,6 +553,8 @@ sbop: // symmetric binary
|
||||||
}
|
}
|
||||||
|
|
||||||
abop: // asymmetric binary
|
abop: // asymmetric binary
|
||||||
|
var n1 gc.Node
|
||||||
|
var n2 gc.Node
|
||||||
if nl.Ullman >= nr.Ullman {
|
if nl.Ullman >= nr.Ullman {
|
||||||
regalloc(&n1, nl.Type, res)
|
regalloc(&n1, nl.Type, res)
|
||||||
cgen(nl, &n1)
|
cgen(nl, &n1)
|
||||||
|
|
@ -610,18 +616,7 @@ abop: // asymmetric binary
|
||||||
if n2.Op != gc.OLITERAL {
|
if n2.Op != gc.OLITERAL {
|
||||||
regfree(&n2)
|
regfree(&n2)
|
||||||
}
|
}
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
uop: // unary
|
|
||||||
regalloc(&n1, nl.Type, res)
|
|
||||||
|
|
||||||
cgen(nl, &n1)
|
|
||||||
gins(a, nil, &n1)
|
|
||||||
gmove(&n1, res)
|
|
||||||
regfree(&n1)
|
|
||||||
goto ret
|
|
||||||
|
|
||||||
ret:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -887,7 +882,6 @@ func agen(n *gc.Node, res *gc.Node) {
|
||||||
n = n.Left
|
n = n.Left
|
||||||
}
|
}
|
||||||
|
|
||||||
var nl *gc.Node
|
|
||||||
if gc.Isconst(n, gc.CTNIL) && n.Type.Width > int64(gc.Widthptr) {
|
if gc.Isconst(n, gc.CTNIL) && n.Type.Width > int64(gc.Widthptr) {
|
||||||
// Use of a nil interface or nil slice.
|
// Use of a nil interface or nil slice.
|
||||||
// Create a temporary we can take the address of and read.
|
// Create a temporary we can take the address of and read.
|
||||||
|
|
@ -906,7 +900,7 @@ func agen(n *gc.Node, res *gc.Node) {
|
||||||
gins(ppc64.AMOVD, &n3, &n2)
|
gins(ppc64.AMOVD, &n3, &n2)
|
||||||
gmove(&n2, res)
|
gmove(&n2, res)
|
||||||
regfree(&n2)
|
regfree(&n2)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Addable != 0 {
|
if n.Addable != 0 {
|
||||||
|
|
@ -918,10 +912,10 @@ func agen(n *gc.Node, res *gc.Node) {
|
||||||
gins(ppc64.AMOVD, &n1, &n2)
|
gins(ppc64.AMOVD, &n1, &n2)
|
||||||
gmove(&n2, res)
|
gmove(&n2, res)
|
||||||
regfree(&n2)
|
regfree(&n2)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
nl = n.Left
|
nl := n.Left
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
|
|
@ -999,8 +993,6 @@ func agen(n *gc.Node, res *gc.Node) {
|
||||||
ginsadd(optoas(gc.OADD, gc.Types[gc.Tptr]), n.Xoffset, res)
|
ginsadd(optoas(gc.OADD, gc.Types[gc.Tptr]), n.Xoffset, res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1126,24 +1118,21 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
gc.Genlist(n.Ninit)
|
gc.Genlist(n.Ninit)
|
||||||
}
|
}
|
||||||
|
|
||||||
var et int
|
|
||||||
var nl *gc.Node
|
|
||||||
var nr *gc.Node
|
|
||||||
if n.Type == nil {
|
if n.Type == nil {
|
||||||
gc.Convlit(&n, gc.Types[gc.TBOOL])
|
gc.Convlit(&n, gc.Types[gc.TBOOL])
|
||||||
if n.Type == nil {
|
if n.Type == nil {
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
et = int(n.Type.Etype)
|
et := int(n.Type.Etype)
|
||||||
if et != gc.TBOOL {
|
if et != gc.TBOOL {
|
||||||
gc.Yyerror("cgen: bad type %v for %v", gc.Tconv(n.Type, 0), gc.Oconv(int(n.Op), 0))
|
gc.Yyerror("cgen: bad type %v for %v", gc.Tconv(n.Type, 0), gc.Oconv(int(n.Op), 0))
|
||||||
gc.Patch(gins(obj.AEND, nil, nil), to)
|
gc.Patch(gins(obj.AEND, nil, nil), to)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
nr = nil
|
nr := (*gc.Node)(nil)
|
||||||
|
|
||||||
for n.Op == gc.OCONVNOP {
|
for n.Op == gc.OCONVNOP {
|
||||||
n = n.Left
|
n = n.Left
|
||||||
|
|
@ -1152,6 +1141,7 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var nl *gc.Node
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
var n1 gc.Node
|
var n1 gc.Node
|
||||||
|
|
@ -1166,14 +1156,14 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
}
|
}
|
||||||
gc.Patch(gc.Gbranch(a, n.Type, likely), to)
|
gc.Patch(gc.Gbranch(a, n.Type, likely), to)
|
||||||
regfree(&n1)
|
regfree(&n1)
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
// need to ask if it is bool?
|
// need to ask if it is bool?
|
||||||
case gc.OLITERAL:
|
case gc.OLITERAL:
|
||||||
if !true_ == (n.Val.U.Bval == 0) {
|
if !true_ == (n.Val.U.Bval == 0) {
|
||||||
gc.Patch(gc.Gbranch(ppc64.ABR, nil, likely), to)
|
gc.Patch(gc.Gbranch(ppc64.ABR, nil, likely), to)
|
||||||
}
|
}
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
case gc.OANDAND,
|
case gc.OANDAND,
|
||||||
gc.OOROR:
|
gc.OOROR:
|
||||||
|
|
@ -1191,7 +1181,7 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
bgen(n.Right, true_, likely, to)
|
bgen(n.Right, true_, likely, to)
|
||||||
}
|
}
|
||||||
|
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
case gc.OEQ,
|
case gc.OEQ,
|
||||||
gc.ONE,
|
gc.ONE,
|
||||||
|
|
@ -1201,7 +1191,7 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
gc.OGE:
|
gc.OGE:
|
||||||
nr = n.Right
|
nr = n.Right
|
||||||
if nr == nil || nr.Type == nil {
|
if nr == nil || nr.Type == nil {
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
||||||
|
|
@ -1209,14 +1199,14 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
nl = n.Left
|
nl = n.Left
|
||||||
|
|
||||||
if nl == nil || nl.Type == nil {
|
if nl == nil || nl.Type == nil {
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
case gc.ONOT:
|
case gc.ONOT:
|
||||||
bgen(nl, !true_, likely, to)
|
bgen(nl, !true_, likely, to)
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
case gc.OEQ,
|
case gc.OEQ,
|
||||||
gc.ONE,
|
gc.ONE,
|
||||||
|
|
@ -1238,7 +1228,7 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
n.Ninit = ll
|
n.Ninit = ll
|
||||||
gc.Patch(gc.Gbranch(ppc64.ABR, nil, 0), to)
|
gc.Patch(gc.Gbranch(ppc64.ABR, nil, 0), to)
|
||||||
gc.Patch(p2, gc.Pc)
|
gc.Patch(p2, gc.Pc)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
a = gc.Brcom(a)
|
a = gc.Brcom(a)
|
||||||
|
|
@ -1365,9 +1355,7 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
|
||||||
regfree(&n2)
|
regfree(&n2)
|
||||||
}
|
}
|
||||||
|
|
||||||
goto ret
|
return
|
||||||
|
|
||||||
ret:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -572,10 +572,7 @@ func dodiv(op int, nl *gc.Node, nr *gc.Node, res *gc.Node) {
|
||||||
func cgen_div(op int, nl *gc.Node, nr *gc.Node, res *gc.Node) {
|
func cgen_div(op int, nl *gc.Node, nr *gc.Node, res *gc.Node) {
|
||||||
// TODO(minux): enable division by magic multiply (also need to fix longmod below)
|
// TODO(minux): enable division by magic multiply (also need to fix longmod below)
|
||||||
//if(nr->op != OLITERAL)
|
//if(nr->op != OLITERAL)
|
||||||
goto longdiv
|
|
||||||
|
|
||||||
// division and mod using (slow) hardware instruction
|
// division and mod using (slow) hardware instruction
|
||||||
longdiv:
|
|
||||||
dodiv(op, nl, nr, res)
|
dodiv(op, nl, nr, res)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
@ -639,11 +636,6 @@ func cgen_hmul(nl *gc.Node, nr *gc.Node, res *gc.Node) {
|
||||||
* res = nl >> nr
|
* res = nl >> nr
|
||||||
*/
|
*/
|
||||||
func cgen_shift(op int, bounded bool, nl *gc.Node, nr *gc.Node, res *gc.Node) {
|
func cgen_shift(op int, bounded bool, nl *gc.Node, nr *gc.Node, res *gc.Node) {
|
||||||
var n1 gc.Node
|
|
||||||
var n2 gc.Node
|
|
||||||
var n3 gc.Node
|
|
||||||
var tcount *gc.Type
|
|
||||||
|
|
||||||
a := int(optoas(op, nl.Type))
|
a := int(optoas(op, nl.Type))
|
||||||
|
|
||||||
if nr.Op == gc.OLITERAL {
|
if nr.Op == gc.OLITERAL {
|
||||||
|
|
@ -663,7 +655,7 @@ func cgen_shift(op int, bounded bool, nl *gc.Node, nr *gc.Node, res *gc.Node) {
|
||||||
}
|
}
|
||||||
gmove(&n1, res)
|
gmove(&n1, res)
|
||||||
regfree(&n1)
|
regfree(&n1)
|
||||||
goto ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if nl.Ullman >= gc.UINF {
|
if nl.Ullman >= gc.UINF {
|
||||||
|
|
@ -683,15 +675,18 @@ func cgen_shift(op int, bounded bool, nl *gc.Node, nr *gc.Node, res *gc.Node) {
|
||||||
// Allow either uint32 or uint64 as shift type,
|
// Allow either uint32 or uint64 as shift type,
|
||||||
// to avoid unnecessary conversion from uint32 to uint64
|
// to avoid unnecessary conversion from uint32 to uint64
|
||||||
// just to do the comparison.
|
// just to do the comparison.
|
||||||
tcount = gc.Types[gc.Simtype[nr.Type.Etype]]
|
tcount := gc.Types[gc.Simtype[nr.Type.Etype]]
|
||||||
|
|
||||||
if tcount.Etype < gc.TUINT32 {
|
if tcount.Etype < gc.TUINT32 {
|
||||||
tcount = gc.Types[gc.TUINT32]
|
tcount = gc.Types[gc.TUINT32]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var n1 gc.Node
|
||||||
regalloc(&n1, nr.Type, nil) // to hold the shift type in CX
|
regalloc(&n1, nr.Type, nil) // to hold the shift type in CX
|
||||||
regalloc(&n3, tcount, &n1) // to clear high bits of CX
|
var n3 gc.Node
|
||||||
|
regalloc(&n3, tcount, &n1) // to clear high bits of CX
|
||||||
|
|
||||||
|
var n2 gc.Node
|
||||||
regalloc(&n2, nl.Type, res)
|
regalloc(&n2, nl.Type, res)
|
||||||
|
|
||||||
if nl.Ullman >= nr.Ullman {
|
if nl.Ullman >= nr.Ullman {
|
||||||
|
|
@ -728,8 +723,6 @@ func cgen_shift(op int, bounded bool, nl *gc.Node, nr *gc.Node, res *gc.Node) {
|
||||||
|
|
||||||
regfree(&n1)
|
regfree(&n1)
|
||||||
regfree(&n2)
|
regfree(&n2)
|
||||||
|
|
||||||
ret:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func clearfat(nl *gc.Node) {
|
func clearfat(nl *gc.Node) {
|
||||||
|
|
@ -759,9 +752,8 @@ func clearfat(nl *gc.Node) {
|
||||||
agen(nl, &dst)
|
agen(nl, &dst)
|
||||||
|
|
||||||
var boff uint64
|
var boff uint64
|
||||||
var p *obj.Prog
|
|
||||||
if q > 128 {
|
if q > 128 {
|
||||||
p = gins(ppc64.ASUB, nil, &dst)
|
p := gins(ppc64.ASUB, nil, &dst)
|
||||||
p.From.Type = obj.TYPE_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = 8
|
p.From.Offset = 8
|
||||||
|
|
||||||
|
|
@ -784,7 +776,7 @@ func clearfat(nl *gc.Node) {
|
||||||
// The loop leaves R3 on the last zeroed dword
|
// The loop leaves R3 on the last zeroed dword
|
||||||
boff = 8
|
boff = 8
|
||||||
} else if q >= 4 {
|
} else if q >= 4 {
|
||||||
p = gins(ppc64.ASUB, nil, &dst)
|
p := gins(ppc64.ASUB, nil, &dst)
|
||||||
p.From.Type = obj.TYPE_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = 8
|
p.From.Offset = 8
|
||||||
f := (*gc.Node)(gc.Sysfunc("duffzero"))
|
f := (*gc.Node)(gc.Sysfunc("duffzero"))
|
||||||
|
|
@ -797,6 +789,7 @@ func clearfat(nl *gc.Node) {
|
||||||
// duffzero leaves R3 on the last zeroed dword
|
// duffzero leaves R3 on the last zeroed dword
|
||||||
boff = 8
|
boff = 8
|
||||||
} else {
|
} else {
|
||||||
|
var p *obj.Prog
|
||||||
for t := uint64(0); t < q; t++ {
|
for t := uint64(0); t < q; t++ {
|
||||||
p = gins(ppc64.AMOVD, &r0, &dst)
|
p = gins(ppc64.AMOVD, &r0, &dst)
|
||||||
p.To.Type = obj.TYPE_MEM
|
p.To.Type = obj.TYPE_MEM
|
||||||
|
|
@ -806,6 +799,7 @@ func clearfat(nl *gc.Node) {
|
||||||
boff = 8 * q
|
boff = 8 * q
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var p *obj.Prog
|
||||||
for t := uint64(0); t < c; t++ {
|
for t := uint64(0); t < c; t++ {
|
||||||
p = gins(ppc64.AMOVB, &r0, &dst)
|
p = gins(ppc64.AMOVB, &r0, &dst)
|
||||||
p.To.Type = obj.TYPE_MEM
|
p.To.Type = obj.TYPE_MEM
|
||||||
|
|
|
||||||
|
|
@ -407,9 +407,8 @@ func subprop(r0 *gc.Flow) bool {
|
||||||
if !regtyp(v2) {
|
if !regtyp(v2) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
var r *gc.Flow
|
|
||||||
var info gc.ProgInfo
|
var info gc.ProgInfo
|
||||||
for r = gc.Uniqp(r0); r != nil; r = gc.Uniqp(r) {
|
for r := gc.Uniqp(r0); r != nil; r = gc.Uniqp(r) {
|
||||||
if gc.Uniqs(r) == nil {
|
if gc.Uniqs(r) == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -425,7 +424,32 @@ func subprop(r0 *gc.Flow) bool {
|
||||||
if info.Flags&(gc.RightRead|gc.RightWrite) == gc.RightWrite {
|
if info.Flags&(gc.RightRead|gc.RightWrite) == gc.RightWrite {
|
||||||
if p.To.Type == v1.Type {
|
if p.To.Type == v1.Type {
|
||||||
if p.To.Reg == v1.Reg {
|
if p.To.Reg == v1.Reg {
|
||||||
goto gotit
|
copysub(&p.To, v1, v2, 1)
|
||||||
|
if gc.Debug['P'] != 0 {
|
||||||
|
fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
|
||||||
|
if p.From.Type == v2.Type {
|
||||||
|
fmt.Printf(" excise")
|
||||||
|
}
|
||||||
|
fmt.Printf("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
|
||||||
|
p = r.Prog
|
||||||
|
copysub(&p.From, v1, v2, 1)
|
||||||
|
copysub1(p, v1, v2, 1)
|
||||||
|
copysub(&p.To, v1, v2, 1)
|
||||||
|
if gc.Debug['P'] != 0 {
|
||||||
|
fmt.Printf("%v\n", r.Prog)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t := int(int(v1.Reg))
|
||||||
|
v1.Reg = v2.Reg
|
||||||
|
v2.Reg = int16(t)
|
||||||
|
if gc.Debug['P'] != 0 {
|
||||||
|
fmt.Printf("%v last\n", r.Prog)
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -439,34 +463,6 @@ func subprop(r0 *gc.Flow) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|
||||||
gotit:
|
|
||||||
copysub(&p.To, v1, v2, 1)
|
|
||||||
if gc.Debug['P'] != 0 {
|
|
||||||
fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
|
|
||||||
if p.From.Type == v2.Type {
|
|
||||||
fmt.Printf(" excise")
|
|
||||||
}
|
|
||||||
fmt.Printf("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
|
|
||||||
p = r.Prog
|
|
||||||
copysub(&p.From, v1, v2, 1)
|
|
||||||
copysub1(p, v1, v2, 1)
|
|
||||||
copysub(&p.To, v1, v2, 1)
|
|
||||||
if gc.Debug['P'] != 0 {
|
|
||||||
fmt.Printf("%v\n", r.Prog)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
t := int(int(v1.Reg))
|
|
||||||
v1.Reg = v2.Reg
|
|
||||||
v2.Reg = int16(t)
|
|
||||||
if gc.Debug['P'] != 0 {
|
|
||||||
fmt.Printf("%v last\n", r.Prog)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -39,17 +39,14 @@ import (
|
||||||
import "cmd/internal/ld"
|
import "cmd/internal/ld"
|
||||||
|
|
||||||
func needlib(name string) int {
|
func needlib(name string) int {
|
||||||
var p string
|
|
||||||
var s *ld.LSym
|
|
||||||
|
|
||||||
if name[0] == '\x00' {
|
if name[0] == '\x00' {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reuse hash code in symbol table */
|
/* reuse hash code in symbol table */
|
||||||
p = fmt.Sprintf(".dynlib.%s", name)
|
p := fmt.Sprintf(".dynlib.%s", name)
|
||||||
|
|
||||||
s = ld.Linklookup(ld.Ctxt, p, 0)
|
s := ld.Linklookup(ld.Ctxt, p, 0)
|
||||||
|
|
||||||
if s.Type == 0 {
|
if s.Type == 0 {
|
||||||
s.Type = 100 // avoid SDATA, etc.
|
s.Type = 100 // avoid SDATA, etc.
|
||||||
|
|
@ -163,16 +160,13 @@ func gentext() {
|
||||||
// Construct a call stub in stub that calls symbol targ via its PLT
|
// Construct a call stub in stub that calls symbol targ via its PLT
|
||||||
// entry.
|
// entry.
|
||||||
func gencallstub(abicase int, stub *ld.LSym, targ *ld.LSym) {
|
func gencallstub(abicase int, stub *ld.LSym, targ *ld.LSym) {
|
||||||
var plt *ld.LSym
|
|
||||||
var r *ld.Reloc
|
|
||||||
|
|
||||||
if abicase != 1 {
|
if abicase != 1 {
|
||||||
// If we see R_PPC64_TOCSAVE or R_PPC64_REL24_NOTOC
|
// If we see R_PPC64_TOCSAVE or R_PPC64_REL24_NOTOC
|
||||||
// relocations, we'll need to implement cases 2 and 3.
|
// relocations, we'll need to implement cases 2 and 3.
|
||||||
log.Fatalf("gencallstub only implements case 1 calls")
|
log.Fatalf("gencallstub only implements case 1 calls")
|
||||||
}
|
}
|
||||||
|
|
||||||
plt = ld.Linklookup(ld.Ctxt, ".plt", 0)
|
plt := ld.Linklookup(ld.Ctxt, ".plt", 0)
|
||||||
|
|
||||||
stub.Type = ld.STEXT
|
stub.Type = ld.STEXT
|
||||||
|
|
||||||
|
|
@ -180,7 +174,7 @@ func gencallstub(abicase int, stub *ld.LSym, targ *ld.LSym) {
|
||||||
ld.Adduint32(ld.Ctxt, stub, 0xf8410018) // std r2,24(r1)
|
ld.Adduint32(ld.Ctxt, stub, 0xf8410018) // std r2,24(r1)
|
||||||
|
|
||||||
// Load the function pointer from the PLT.
|
// Load the function pointer from the PLT.
|
||||||
r = ld.Addrel(stub)
|
r := ld.Addrel(stub)
|
||||||
|
|
||||||
r.Off = int32(stub.Size)
|
r.Off = int32(stub.Size)
|
||||||
r.Sym = plt
|
r.Sym = plt
|
||||||
|
|
@ -214,10 +208,7 @@ func adddynrela(rel *ld.LSym, s *ld.LSym, r *ld.Reloc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
||||||
var targ *ld.LSym
|
targ := r.Sym
|
||||||
var rela *ld.LSym
|
|
||||||
|
|
||||||
targ = r.Sym
|
|
||||||
ld.Ctxt.Cursym = s
|
ld.Ctxt.Cursym = s
|
||||||
|
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
|
|
@ -251,7 +242,7 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
||||||
// These happen in .toc sections
|
// These happen in .toc sections
|
||||||
adddynsym(ld.Ctxt, targ)
|
adddynsym(ld.Ctxt, targ)
|
||||||
|
|
||||||
rela = ld.Linklookup(ld.Ctxt, ".rela", 0)
|
rela := ld.Linklookup(ld.Ctxt, ".rela", 0)
|
||||||
ld.Addaddrplus(ld.Ctxt, rela, s, int64(r.Off))
|
ld.Addaddrplus(ld.Ctxt, rela, s, int64(r.Off))
|
||||||
ld.Adduint64(ld.Ctxt, rela, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_PPC64_ADDR64))
|
ld.Adduint64(ld.Ctxt, rela, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_PPC64_ADDR64))
|
||||||
ld.Adduint64(ld.Ctxt, rela, uint64(r.Add))
|
ld.Adduint64(ld.Ctxt, rela, uint64(r.Add))
|
||||||
|
|
@ -325,9 +316,7 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfsetupplt() {
|
func elfsetupplt() {
|
||||||
var plt *ld.LSym
|
plt := ld.Linklookup(ld.Ctxt, ".plt", 0)
|
||||||
|
|
||||||
plt = ld.Linklookup(ld.Ctxt, ".plt", 0)
|
|
||||||
if plt.Size == 0 {
|
if plt.Size == 0 {
|
||||||
// The dynamic linker stores the address of the
|
// The dynamic linker stores the address of the
|
||||||
// dynamic resolver and the DSO identifier in the two
|
// dynamic resolver and the DSO identifier in the two
|
||||||
|
|
@ -360,10 +349,6 @@ func symtoc(s *ld.LSym) int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
|
func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
|
||||||
var o1 uint32
|
|
||||||
var o2 uint32
|
|
||||||
var t int64
|
|
||||||
|
|
||||||
if ld.Linkmode == ld.LinkExternal {
|
if ld.Linkmode == ld.LinkExternal {
|
||||||
// TODO(minux): translate R_ADDRPOWER and R_CALLPOWER into standard ELF relocations.
|
// TODO(minux): translate R_ADDRPOWER and R_CALLPOWER into standard ELF relocations.
|
||||||
// R_ADDRPOWER corresponds to R_PPC_ADDR16_HA and R_PPC_ADDR16_LO.
|
// R_ADDRPOWER corresponds to R_PPC_ADDR16_HA and R_PPC_ADDR16_LO.
|
||||||
|
|
@ -386,9 +371,9 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
|
||||||
// The encoding of the immediate x<<16 + y,
|
// The encoding of the immediate x<<16 + y,
|
||||||
// where x is the low 16 bits of the first instruction and y is the low 16
|
// where x is the low 16 bits of the first instruction and y is the low 16
|
||||||
// bits of the second. Both x and y are signed (int16, not uint16).
|
// bits of the second. Both x and y are signed (int16, not uint16).
|
||||||
o1 = uint32(r.Add >> 32)
|
o1 := uint32(r.Add >> 32)
|
||||||
o2 = uint32(r.Add)
|
o2 := uint32(r.Add)
|
||||||
t = ld.Symaddr(r.Sym)
|
t := ld.Symaddr(r.Sym)
|
||||||
if t < 0 {
|
if t < 0 {
|
||||||
ld.Ctxt.Diag("relocation for %s is too big (>=2G): %d", s.Name, ld.Symaddr(r.Sym))
|
ld.Ctxt.Diag("relocation for %s is too big (>=2G): %d", s.Name, ld.Symaddr(r.Sym))
|
||||||
}
|
}
|
||||||
|
|
@ -410,13 +395,14 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
|
||||||
|
|
||||||
case ld.R_CALLPOWER:
|
case ld.R_CALLPOWER:
|
||||||
// Bits 6 through 29 = (S + A - P) >> 2
|
// Bits 6 through 29 = (S + A - P) >> 2
|
||||||
|
var o1 uint32
|
||||||
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian {
|
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian {
|
||||||
o1 = ld.Be32(s.P[r.Off:])
|
o1 = ld.Be32(s.P[r.Off:])
|
||||||
} else {
|
} else {
|
||||||
o1 = ld.Le32(s.P[r.Off:])
|
o1 = ld.Le32(s.P[r.Off:])
|
||||||
}
|
}
|
||||||
|
|
||||||
t = ld.Symaddr(r.Sym) + r.Add - (s.Value + int64(r.Off))
|
t := ld.Symaddr(r.Sym) + r.Add - (s.Value + int64(r.Off))
|
||||||
if t&3 != 0 {
|
if t&3 != 0 {
|
||||||
ld.Ctxt.Diag("relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
|
ld.Ctxt.Diag("relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
|
||||||
}
|
}
|
||||||
|
|
@ -439,7 +425,6 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func archrelocvariant(r *ld.Reloc, s *ld.LSym, t int64) int64 {
|
func archrelocvariant(r *ld.Reloc, s *ld.LSym, t int64) int64 {
|
||||||
var o1 uint32
|
|
||||||
switch r.Variant & ld.RV_TYPE_MASK {
|
switch r.Variant & ld.RV_TYPE_MASK {
|
||||||
default:
|
default:
|
||||||
ld.Diag("unexpected relocation variant %d", r.Variant)
|
ld.Diag("unexpected relocation variant %d", r.Variant)
|
||||||
|
|
@ -452,6 +437,7 @@ func archrelocvariant(r *ld.Reloc, s *ld.LSym, t int64) int64 {
|
||||||
if r.Variant&ld.RV_CHECK_OVERFLOW != 0 {
|
if r.Variant&ld.RV_CHECK_OVERFLOW != 0 {
|
||||||
// Whether to check for signed or unsigned
|
// Whether to check for signed or unsigned
|
||||||
// overflow depends on the instruction
|
// overflow depends on the instruction
|
||||||
|
var o1 uint32
|
||||||
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian {
|
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian {
|
||||||
o1 = ld.Be32(s.P[r.Off-2:])
|
o1 = ld.Be32(s.P[r.Off-2:])
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -485,6 +471,7 @@ func archrelocvariant(r *ld.Reloc, s *ld.LSym, t int64) int64 {
|
||||||
if r.Variant&ld.RV_CHECK_OVERFLOW != 0 {
|
if r.Variant&ld.RV_CHECK_OVERFLOW != 0 {
|
||||||
// Whether to check for signed or unsigned
|
// Whether to check for signed or unsigned
|
||||||
// overflow depends on the instruction
|
// overflow depends on the instruction
|
||||||
|
var o1 uint32
|
||||||
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian {
|
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian {
|
||||||
o1 = ld.Be32(s.P[r.Off-2:])
|
o1 = ld.Be32(s.P[r.Off-2:])
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -508,6 +495,7 @@ func archrelocvariant(r *ld.Reloc, s *ld.LSym, t int64) int64 {
|
||||||
return int64(int16(t))
|
return int64(int16(t))
|
||||||
|
|
||||||
case ld.RV_POWER_DS:
|
case ld.RV_POWER_DS:
|
||||||
|
var o1 uint32
|
||||||
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian {
|
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian {
|
||||||
o1 = uint32(ld.Be16(s.P[r.Off:]))
|
o1 = uint32(ld.Be16(s.P[r.Off:]))
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -535,23 +523,18 @@ func addpltsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
adddynsym(ctxt, s)
|
adddynsym(ctxt, s)
|
||||||
|
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
var plt *ld.LSym
|
plt := ld.Linklookup(ctxt, ".plt", 0)
|
||||||
var rela *ld.LSym
|
rela := ld.Linklookup(ctxt, ".rela.plt", 0)
|
||||||
var glink *ld.LSym
|
|
||||||
var r *ld.Reloc
|
|
||||||
|
|
||||||
plt = ld.Linklookup(ctxt, ".plt", 0)
|
|
||||||
rela = ld.Linklookup(ctxt, ".rela.plt", 0)
|
|
||||||
if plt.Size == 0 {
|
if plt.Size == 0 {
|
||||||
elfsetupplt()
|
elfsetupplt()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the glink resolver if necessary
|
// Create the glink resolver if necessary
|
||||||
glink = ensureglinkresolver()
|
glink := ensureglinkresolver()
|
||||||
|
|
||||||
// Write symbol resolver stub (just a branch to the
|
// Write symbol resolver stub (just a branch to the
|
||||||
// glink resolver stub)
|
// glink resolver stub)
|
||||||
r = ld.Addrel(glink)
|
r := ld.Addrel(glink)
|
||||||
|
|
||||||
r.Sym = glink
|
r.Sym = glink
|
||||||
r.Off = int32(glink.Size)
|
r.Off = int32(glink.Size)
|
||||||
|
|
@ -579,11 +562,7 @@ func addpltsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
|
|
||||||
// Generate the glink resolver stub if necessary and return the .glink section
|
// Generate the glink resolver stub if necessary and return the .glink section
|
||||||
func ensureglinkresolver() *ld.LSym {
|
func ensureglinkresolver() *ld.LSym {
|
||||||
var glink *ld.LSym
|
glink := ld.Linklookup(ld.Ctxt, ".glink", 0)
|
||||||
var s *ld.LSym
|
|
||||||
var r *ld.Reloc
|
|
||||||
|
|
||||||
glink = ld.Linklookup(ld.Ctxt, ".glink", 0)
|
|
||||||
if glink.Size != 0 {
|
if glink.Size != 0 {
|
||||||
return glink
|
return glink
|
||||||
}
|
}
|
||||||
|
|
@ -610,7 +589,7 @@ func ensureglinkresolver() *ld.LSym {
|
||||||
ld.Adduint32(ld.Ctxt, glink, 0x7800f082) // srdi r0,r0,2
|
ld.Adduint32(ld.Ctxt, glink, 0x7800f082) // srdi r0,r0,2
|
||||||
|
|
||||||
// r11 = address of the first byte of the PLT
|
// r11 = address of the first byte of the PLT
|
||||||
r = ld.Addrel(glink)
|
r := ld.Addrel(glink)
|
||||||
|
|
||||||
r.Off = int32(glink.Size)
|
r.Off = int32(glink.Size)
|
||||||
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0)
|
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0)
|
||||||
|
|
@ -636,7 +615,7 @@ func ensureglinkresolver() *ld.LSym {
|
||||||
|
|
||||||
// Add DT_PPC64_GLINK .dynamic entry, which points to 32 bytes
|
// Add DT_PPC64_GLINK .dynamic entry, which points to 32 bytes
|
||||||
// before the first symbol resolver stub.
|
// before the first symbol resolver stub.
|
||||||
s = ld.Linklookup(ld.Ctxt, ".dynamic", 0)
|
s := ld.Linklookup(ld.Ctxt, ".dynamic", 0)
|
||||||
|
|
||||||
ld.Elfwritedynentsymplus(s, ld.DT_PPC64_GLINK, glink, glink.Size-32)
|
ld.Elfwritedynentsymplus(s, ld.DT_PPC64_GLINK, glink, glink.Size-32)
|
||||||
|
|
||||||
|
|
@ -644,10 +623,6 @@ func ensureglinkresolver() *ld.LSym {
|
||||||
}
|
}
|
||||||
|
|
||||||
func adddynsym(ctxt *ld.Link, s *ld.LSym) {
|
func adddynsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
var d *ld.LSym
|
|
||||||
var t int
|
|
||||||
var name string
|
|
||||||
|
|
||||||
if s.Dynid >= 0 {
|
if s.Dynid >= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -656,13 +631,13 @@ func adddynsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
s.Dynid = int32(ld.Nelfsym)
|
s.Dynid = int32(ld.Nelfsym)
|
||||||
ld.Nelfsym++
|
ld.Nelfsym++
|
||||||
|
|
||||||
d = ld.Linklookup(ctxt, ".dynsym", 0)
|
d := ld.Linklookup(ctxt, ".dynsym", 0)
|
||||||
|
|
||||||
name = s.Extname
|
name := s.Extname
|
||||||
ld.Adduint32(ctxt, d, uint32(ld.Addstring(ld.Linklookup(ctxt, ".dynstr", 0), name)))
|
ld.Adduint32(ctxt, d, uint32(ld.Addstring(ld.Linklookup(ctxt, ".dynstr", 0), name)))
|
||||||
|
|
||||||
/* type */
|
/* type */
|
||||||
t = ld.STB_GLOBAL << 4
|
t := ld.STB_GLOBAL << 4
|
||||||
|
|
||||||
if s.Cgoexport != 0 && s.Type&ld.SMASK == ld.STEXT {
|
if s.Cgoexport != 0 && s.Type&ld.SMASK == ld.STEXT {
|
||||||
t |= ld.STT_FUNC
|
t |= ld.STT_FUNC
|
||||||
|
|
@ -696,14 +671,12 @@ func adddynsym(ctxt *ld.Link, s *ld.LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func adddynlib(lib string) {
|
func adddynlib(lib string) {
|
||||||
var s *ld.LSym
|
|
||||||
|
|
||||||
if needlib(lib) == 0 {
|
if needlib(lib) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
s = ld.Linklookup(ld.Ctxt, ".dynstr", 0)
|
s := ld.Linklookup(ld.Ctxt, ".dynstr", 0)
|
||||||
if s.Size == 0 {
|
if s.Size == 0 {
|
||||||
ld.Addstring(s, "")
|
ld.Addstring(s, "")
|
||||||
}
|
}
|
||||||
|
|
@ -714,11 +687,6 @@ func adddynlib(lib string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func asmb() {
|
func asmb() {
|
||||||
var symo uint32
|
|
||||||
var sect *ld.Section
|
|
||||||
var sym *ld.LSym
|
|
||||||
var i int
|
|
||||||
|
|
||||||
if ld.Debug['v'] != 0 {
|
if ld.Debug['v'] != 0 {
|
||||||
fmt.Fprintf(&ld.Bso, "%5.2f asmb\n", obj.Cputime())
|
fmt.Fprintf(&ld.Bso, "%5.2f asmb\n", obj.Cputime())
|
||||||
}
|
}
|
||||||
|
|
@ -728,7 +696,7 @@ func asmb() {
|
||||||
ld.Asmbelfsetup()
|
ld.Asmbelfsetup()
|
||||||
}
|
}
|
||||||
|
|
||||||
sect = ld.Segtext.Sect
|
sect := ld.Segtext.Sect
|
||||||
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
|
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
|
||||||
ld.Codeblk(int64(sect.Vaddr), int64(sect.Length))
|
ld.Codeblk(int64(sect.Vaddr), int64(sect.Length))
|
||||||
for sect = sect.Next; sect != nil; sect = sect.Next {
|
for sect = sect.Next; sect != nil; sect = sect.Next {
|
||||||
|
|
@ -758,7 +726,7 @@ func asmb() {
|
||||||
ld.Symsize = 0
|
ld.Symsize = 0
|
||||||
|
|
||||||
ld.Lcsize = 0
|
ld.Lcsize = 0
|
||||||
symo = 0
|
symo := uint32(0)
|
||||||
if ld.Debug['s'] == 0 {
|
if ld.Debug['s'] == 0 {
|
||||||
// TODO: rationalize
|
// TODO: rationalize
|
||||||
if ld.Debug['v'] != 0 {
|
if ld.Debug['v'] != 0 {
|
||||||
|
|
@ -801,10 +769,10 @@ func asmb() {
|
||||||
ld.Asmplan9sym()
|
ld.Asmplan9sym()
|
||||||
ld.Cflush()
|
ld.Cflush()
|
||||||
|
|
||||||
sym = ld.Linklookup(ld.Ctxt, "pclntab", 0)
|
sym := ld.Linklookup(ld.Ctxt, "pclntab", 0)
|
||||||
if sym != nil {
|
if sym != nil {
|
||||||
ld.Lcsize = int32(len(sym.P))
|
ld.Lcsize = int32(len(sym.P))
|
||||||
for i = 0; int32(i) < ld.Lcsize; i++ {
|
for i := 0; int32(i) < ld.Lcsize; i++ {
|
||||||
ld.Cput(uint8(sym.P[i]))
|
ld.Cput(uint8(sym.P[i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -163,11 +163,9 @@ func usage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Main() {
|
func Main() {
|
||||||
var p string
|
|
||||||
|
|
||||||
// Allow GOARCH=Thestring or GOARCH=Thestringsuffix,
|
// Allow GOARCH=Thestring or GOARCH=Thestringsuffix,
|
||||||
// but not other values.
|
// but not other values.
|
||||||
p = obj.Getgoarch()
|
p := obj.Getgoarch()
|
||||||
|
|
||||||
if !strings.HasPrefix(p, Thestring) {
|
if !strings.HasPrefix(p, Thestring) {
|
||||||
log.Fatalf("cannot use %cc with GOARCH=%s", Thechar, p)
|
log.Fatalf("cannot use %cc with GOARCH=%s", Thechar, p)
|
||||||
|
|
@ -219,8 +217,6 @@ func Main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func assemble(file string) int {
|
func assemble(file string) int {
|
||||||
var i int
|
|
||||||
|
|
||||||
if outfile == "" {
|
if outfile == "" {
|
||||||
outfile = strings.TrimSuffix(filepath.Base(file), ".s") + "." + string(Thechar)
|
outfile = strings.TrimSuffix(filepath.Base(file), ".s") + "." + string(Thechar)
|
||||||
}
|
}
|
||||||
|
|
@ -235,6 +231,7 @@ func assemble(file string) int {
|
||||||
fmt.Fprintf(&obuf, "go object %s %s %s\n", obj.Getgoos(), obj.Getgoarch(), obj.Getgoversion())
|
fmt.Fprintf(&obuf, "go object %s %s %s\n", obj.Getgoos(), obj.Getgoarch(), obj.Getgoversion())
|
||||||
fmt.Fprintf(&obuf, "!\n")
|
fmt.Fprintf(&obuf, "!\n")
|
||||||
|
|
||||||
|
var i int
|
||||||
for Pass = 1; Pass <= 2; Pass++ {
|
for Pass = 1; Pass <= 2; Pass++ {
|
||||||
pinit(file)
|
pinit(file)
|
||||||
for i = 0; i < len(Dlist); i++ {
|
for i = 0; i < len(Dlist); i++ {
|
||||||
|
|
|
||||||
|
|
@ -45,61 +45,50 @@ import (
|
||||||
* common code for all the assemblers
|
* common code for all the assemblers
|
||||||
*/
|
*/
|
||||||
func pragpack() {
|
func pragpack() {
|
||||||
|
|
||||||
for getnsc() != '\n' {
|
for getnsc() != '\n' {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func pragvararg() {
|
func pragvararg() {
|
||||||
for getnsc() != '\n' {
|
for getnsc() != '\n' {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func pragcgo(name string) {
|
func pragcgo(name string) {
|
||||||
for getnsc() != '\n' {
|
for getnsc() != '\n' {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func pragfpround() {
|
func pragfpround() {
|
||||||
for getnsc() != '\n' {
|
for getnsc() != '\n' {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func pragtextflag() {
|
func pragtextflag() {
|
||||||
for getnsc() != '\n' {
|
for getnsc() != '\n' {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func pragdataflag() {
|
func pragdataflag() {
|
||||||
for getnsc() != '\n' {
|
for getnsc() != '\n' {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func pragprofile() {
|
func pragprofile() {
|
||||||
for getnsc() != '\n' {
|
for getnsc() != '\n' {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func pragincomplete() {
|
func pragincomplete() {
|
||||||
for getnsc() != '\n' {
|
for getnsc() != '\n' {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setinclude(p string) {
|
func setinclude(p string) {
|
||||||
var i int
|
|
||||||
|
|
||||||
if p == "" {
|
if p == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for i = 1; i < len(include); i++ {
|
for i := 1; i < len(include); i++ {
|
||||||
if p == include[i] {
|
if p == include[i] {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -117,9 +106,7 @@ func errorexit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func pushio() {
|
func pushio() {
|
||||||
var i *Io
|
i := iostack
|
||||||
|
|
||||||
i = iostack
|
|
||||||
if i == nil {
|
if i == nil {
|
||||||
Yyerror("botch in pushio")
|
Yyerror("botch in pushio")
|
||||||
errorexit()
|
errorexit()
|
||||||
|
|
@ -129,10 +116,9 @@ func pushio() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newio() {
|
func newio() {
|
||||||
var i *Io
|
|
||||||
var pushdepth int = 0
|
var pushdepth int = 0
|
||||||
|
|
||||||
i = iofree
|
i := iofree
|
||||||
if i == nil {
|
if i == nil {
|
||||||
pushdepth++
|
pushdepth++
|
||||||
if pushdepth > 1000 {
|
if pushdepth > 1000 {
|
||||||
|
|
@ -149,9 +135,7 @@ func newio() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newfile(s string, f *os.File) {
|
func newfile(s string, f *os.File) {
|
||||||
var i *Io
|
i := ionext
|
||||||
|
|
||||||
i = ionext
|
|
||||||
i.Link = iostack
|
i.Link = iostack
|
||||||
iostack = i
|
iostack = i
|
||||||
i.F = f
|
i.F = f
|
||||||
|
|
@ -175,16 +159,13 @@ func Settext(s *obj.LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func LabelLookup(s *Sym) *Sym {
|
func LabelLookup(s *Sym) *Sym {
|
||||||
var p string
|
|
||||||
var lab *Sym
|
|
||||||
|
|
||||||
if thetext == nil {
|
if thetext == nil {
|
||||||
s.Labelname = s.Name
|
s.Labelname = s.Name
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
p = string(fmt.Sprintf("%s.%s", thetext.Name, s.Name))
|
p := string(fmt.Sprintf("%s.%s", thetext.Name, s.Name))
|
||||||
lab = Lookup(p)
|
lab := Lookup(p)
|
||||||
|
|
||||||
lab.Labelname = s.Name
|
lab.Labelname = s.Name
|
||||||
return lab
|
return lab
|
||||||
|
|
@ -249,11 +230,10 @@ type Yylval struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Yylex(yylval *Yylval) int {
|
func Yylex(yylval *Yylval) int {
|
||||||
var c int
|
|
||||||
var c1 int
|
var c1 int
|
||||||
var s *Sym
|
var s *Sym
|
||||||
|
|
||||||
c = peekc
|
c := peekc
|
||||||
if c != IGN {
|
if c != IGN {
|
||||||
peekc = IGN
|
peekc = IGN
|
||||||
goto l1
|
goto l1
|
||||||
|
|
@ -282,7 +262,48 @@ l1:
|
||||||
goto aloop
|
goto aloop
|
||||||
}
|
}
|
||||||
if isdigit(c) {
|
if isdigit(c) {
|
||||||
goto tnum
|
yybuf.Reset()
|
||||||
|
if c != '0' {
|
||||||
|
goto dc
|
||||||
|
}
|
||||||
|
yybuf.WriteByte(byte(c))
|
||||||
|
c = GETC()
|
||||||
|
c1 = 3
|
||||||
|
if c == 'x' || c == 'X' {
|
||||||
|
c1 = 4
|
||||||
|
c = GETC()
|
||||||
|
} else if c < '0' || c > '7' {
|
||||||
|
goto dc
|
||||||
|
}
|
||||||
|
yylval.Lval = 0
|
||||||
|
for {
|
||||||
|
if c >= '0' && c <= '9' {
|
||||||
|
if c > '7' && c1 == 3 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
yylval.Lval = int64(uint64(yylval.Lval) << uint(c1))
|
||||||
|
yylval.Lval += int64(c) - '0'
|
||||||
|
c = GETC()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if c1 == 3 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if c >= 'A' && c <= 'F' {
|
||||||
|
c += 'a' - 'A'
|
||||||
|
}
|
||||||
|
if c >= 'a' && c <= 'f' {
|
||||||
|
yylval.Lval = int64(uint64(yylval.Lval) << uint(c1))
|
||||||
|
yylval.Lval += int64(c) - 'a' + 10
|
||||||
|
c = GETC()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
goto ncu
|
||||||
}
|
}
|
||||||
switch c {
|
switch c {
|
||||||
case '\n':
|
case '\n':
|
||||||
|
|
@ -458,50 +479,6 @@ aloop:
|
||||||
yylval.Sval = last
|
yylval.Sval = last
|
||||||
return int(s.Type)
|
return int(s.Type)
|
||||||
|
|
||||||
tnum:
|
|
||||||
yybuf.Reset()
|
|
||||||
if c != '0' {
|
|
||||||
goto dc
|
|
||||||
}
|
|
||||||
yybuf.WriteByte(byte(c))
|
|
||||||
c = GETC()
|
|
||||||
c1 = 3
|
|
||||||
if c == 'x' || c == 'X' {
|
|
||||||
c1 = 4
|
|
||||||
c = GETC()
|
|
||||||
} else if c < '0' || c > '7' {
|
|
||||||
goto dc
|
|
||||||
}
|
|
||||||
yylval.Lval = 0
|
|
||||||
for {
|
|
||||||
if c >= '0' && c <= '9' {
|
|
||||||
if c > '7' && c1 == 3 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
yylval.Lval = int64(uint64(yylval.Lval) << uint(c1))
|
|
||||||
yylval.Lval += int64(c) - '0'
|
|
||||||
c = GETC()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if c1 == 3 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if c >= 'A' && c <= 'F' {
|
|
||||||
c += 'a' - 'A'
|
|
||||||
}
|
|
||||||
if c >= 'a' && c <= 'f' {
|
|
||||||
yylval.Lval = int64(uint64(yylval.Lval) << uint(c1))
|
|
||||||
yylval.Lval += int64(c) - 'a' + 10
|
|
||||||
c = GETC()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
goto ncu
|
|
||||||
|
|
||||||
dc:
|
dc:
|
||||||
for {
|
for {
|
||||||
if !(isdigit(c)) {
|
if !(isdigit(c)) {
|
||||||
|
|
@ -529,9 +506,7 @@ ncu:
|
||||||
}
|
}
|
||||||
|
|
||||||
func getc() int {
|
func getc() int {
|
||||||
var c int
|
c := peekc
|
||||||
|
|
||||||
c = peekc
|
|
||||||
if c != IGN {
|
if c != IGN {
|
||||||
peekc = IGN
|
peekc = IGN
|
||||||
if c == '\n' {
|
if c == '\n' {
|
||||||
|
|
@ -571,11 +546,10 @@ func unget(c int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func escchar(e int) int {
|
func escchar(e int) int {
|
||||||
var c int
|
|
||||||
var l int
|
var l int
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
c = getc()
|
c := getc()
|
||||||
if c == '\n' {
|
if c == '\n' {
|
||||||
Yyerror("newline in string")
|
Yyerror("newline in string")
|
||||||
return EOF
|
return EOF
|
||||||
|
|
@ -643,11 +617,10 @@ func pinit(f string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func filbuf() int {
|
func filbuf() int {
|
||||||
var i *Io
|
|
||||||
var n int
|
var n int
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
i = iostack
|
i := iostack
|
||||||
if i == nil {
|
if i == nil {
|
||||||
return EOF
|
return EOF
|
||||||
}
|
}
|
||||||
|
|
@ -705,11 +678,10 @@ func prfile(l int32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GETC() int {
|
func GETC() int {
|
||||||
var c int
|
|
||||||
if len(fi.P) == 0 {
|
if len(fi.P) == 0 {
|
||||||
return filbuf()
|
return filbuf()
|
||||||
}
|
}
|
||||||
c = int(fi.P[0])
|
c := int(fi.P[0])
|
||||||
fi.P = fi.P[1:]
|
fi.P = fi.P[1:]
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,14 +43,11 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func getnsn() int32 {
|
func getnsn() int32 {
|
||||||
var n int32
|
c := getnsc()
|
||||||
var c int
|
|
||||||
|
|
||||||
c = getnsc()
|
|
||||||
if c < '0' || c > '9' {
|
if c < '0' || c > '9' {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
n = 0
|
n := int32(0)
|
||||||
for c >= '0' && c <= '9' {
|
for c >= '0' && c <= '9' {
|
||||||
n = n*10 + int32(c) - '0'
|
n = n*10 + int32(c) - '0'
|
||||||
c = getc()
|
c = getc()
|
||||||
|
|
@ -61,9 +58,7 @@ func getnsn() int32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getsym() *Sym {
|
func getsym() *Sym {
|
||||||
var c int
|
c := getnsc()
|
||||||
|
|
||||||
c = getnsc()
|
|
||||||
if !isalpha(c) && c != '_' && c < 0x80 {
|
if !isalpha(c) && c != '_' && c < 0x80 {
|
||||||
unget(c)
|
unget(c)
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -84,15 +79,12 @@ func getsym() *Sym {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getsymdots(dots *int) *Sym {
|
func getsymdots(dots *int) *Sym {
|
||||||
var c int
|
s := getsym()
|
||||||
var s *Sym
|
|
||||||
|
|
||||||
s = getsym()
|
|
||||||
if s != nil {
|
if s != nil {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
c = getnsc()
|
c := getnsc()
|
||||||
if c != '.' {
|
if c != '.' {
|
||||||
unget(c)
|
unget(c)
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -153,10 +145,9 @@ func getcom() int {
|
||||||
|
|
||||||
func dodefine(cp string) {
|
func dodefine(cp string) {
|
||||||
var s *Sym
|
var s *Sym
|
||||||
var p string
|
|
||||||
|
|
||||||
if i := strings.Index(cp, "="); i >= 0 {
|
if i := strings.Index(cp, "="); i >= 0 {
|
||||||
p = cp[i+1:]
|
p := cp[i+1:]
|
||||||
cp = cp[:i]
|
cp = cp[:i]
|
||||||
s = Lookup(cp)
|
s = Lookup(cp)
|
||||||
s.Macro = &Macro{Text: p}
|
s.Macro = &Macro{Text: p}
|
||||||
|
|
@ -186,14 +177,11 @@ var mactab = []struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func domacro() {
|
func domacro() {
|
||||||
var i int
|
s := getsym()
|
||||||
var s *Sym
|
|
||||||
|
|
||||||
s = getsym()
|
|
||||||
if s == nil {
|
if s == nil {
|
||||||
s = Lookup("endif")
|
s = Lookup("endif")
|
||||||
}
|
}
|
||||||
for i = 0; i < len(mactab); i++ {
|
for i := 0; i < len(mactab); i++ {
|
||||||
if s.Name == mactab[i].Macname {
|
if s.Name == mactab[i].Macname {
|
||||||
if mactab[i].Macf != nil {
|
if mactab[i].Macf != nil {
|
||||||
mactab[i].Macf()
|
mactab[i].Macf()
|
||||||
|
|
@ -209,9 +197,7 @@ func domacro() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func macund() {
|
func macund() {
|
||||||
var s *Sym
|
s := getsym()
|
||||||
|
|
||||||
s = getsym()
|
|
||||||
macend()
|
macend()
|
||||||
if s == nil {
|
if s == nil {
|
||||||
Yyerror("syntax in #undef")
|
Yyerror("syntax in #undef")
|
||||||
|
|
@ -226,8 +212,6 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func macdef() {
|
func macdef() {
|
||||||
var s *Sym
|
|
||||||
var a *Sym
|
|
||||||
var args [NARG]string
|
var args [NARG]string
|
||||||
var n int
|
var n int
|
||||||
var i int
|
var i int
|
||||||
|
|
@ -236,7 +220,7 @@ func macdef() {
|
||||||
var ischr int
|
var ischr int
|
||||||
var base bytes.Buffer
|
var base bytes.Buffer
|
||||||
|
|
||||||
s = getsym()
|
s := getsym()
|
||||||
if s == nil {
|
if s == nil {
|
||||||
goto bad
|
goto bad
|
||||||
}
|
}
|
||||||
|
|
@ -251,6 +235,8 @@ func macdef() {
|
||||||
c = getnsc()
|
c = getnsc()
|
||||||
if c != ')' {
|
if c != ')' {
|
||||||
unget(c)
|
unget(c)
|
||||||
|
var a *Sym
|
||||||
|
var c int
|
||||||
for {
|
for {
|
||||||
a = getsymdots(&dots)
|
a = getsymdots(&dots)
|
||||||
if a == nil {
|
if a == nil {
|
||||||
|
|
@ -316,7 +302,6 @@ func macdef() {
|
||||||
ischr = 0
|
ischr = 0
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if c == '"' || c == '\'' {
|
if c == '"' || c == '\'' {
|
||||||
base.WriteByte(byte(c))
|
base.WriteByte(byte(c))
|
||||||
ischr = c
|
ischr = c
|
||||||
|
|
@ -417,20 +402,12 @@ bad:
|
||||||
if s == nil {
|
if s == nil {
|
||||||
Yyerror("syntax in #define")
|
Yyerror("syntax in #define")
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
Yyerror("syntax in #define: %s", s.Name)
|
Yyerror("syntax in #define: %s", s.Name)
|
||||||
}
|
}
|
||||||
macend()
|
macend()
|
||||||
}
|
}
|
||||||
|
|
||||||
func macexpand(s *Sym) []byte {
|
func macexpand(s *Sym) []byte {
|
||||||
var l int
|
|
||||||
var c int
|
|
||||||
var arg []string
|
|
||||||
var out bytes.Buffer
|
|
||||||
var buf bytes.Buffer
|
|
||||||
var cp string
|
|
||||||
|
|
||||||
if s.Macro.Narg == 0 {
|
if s.Macro.Narg == 0 {
|
||||||
if debug['m'] != 0 {
|
if debug['m'] != 0 {
|
||||||
fmt.Printf("#expand %s %s\n", s.Name, s.Macro.Text)
|
fmt.Printf("#expand %s %s\n", s.Name, s.Macro.Text)
|
||||||
|
|
@ -441,14 +418,19 @@ func macexpand(s *Sym) []byte {
|
||||||
nargs := s.Macro.Narg - 1
|
nargs := s.Macro.Narg - 1
|
||||||
dots := s.Macro.Dots
|
dots := s.Macro.Dots
|
||||||
|
|
||||||
c = getnsc()
|
c := getnsc()
|
||||||
|
var arg []string
|
||||||
|
var cp string
|
||||||
|
var out bytes.Buffer
|
||||||
if c != '(' {
|
if c != '(' {
|
||||||
goto bad
|
goto bad
|
||||||
}
|
}
|
||||||
c = getc()
|
c = getc()
|
||||||
if c != ')' {
|
if c != ')' {
|
||||||
unget(c)
|
unget(c)
|
||||||
l = 0
|
l := 0
|
||||||
|
var buf bytes.Buffer
|
||||||
|
var c int
|
||||||
for {
|
for {
|
||||||
c = getc()
|
c = getc()
|
||||||
if c == '"' {
|
if c == '"' {
|
||||||
|
|
@ -595,16 +577,14 @@ bad:
|
||||||
}
|
}
|
||||||
|
|
||||||
func macinc() {
|
func macinc() {
|
||||||
var c0 int
|
|
||||||
var c int
|
var c int
|
||||||
var i int
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
var f *os.File
|
var f *os.File
|
||||||
var hp string
|
var hp string
|
||||||
var str string
|
var str string
|
||||||
var symb string
|
var symb string
|
||||||
|
|
||||||
c0 = getnsc()
|
c0 := getnsc()
|
||||||
if c0 != '"' {
|
if c0 != '"' {
|
||||||
c = c0
|
c = c0
|
||||||
if c0 != '<' {
|
if c0 != '<' {
|
||||||
|
|
@ -630,7 +610,7 @@ func macinc() {
|
||||||
goto bad
|
goto bad
|
||||||
}
|
}
|
||||||
|
|
||||||
for i = 0; i < len(include); i++ {
|
for i := 0; i < len(include); i++ {
|
||||||
if i == 0 && c0 == '>' {
|
if i == 0 && c0 == '>' {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -663,13 +643,11 @@ bad:
|
||||||
}
|
}
|
||||||
|
|
||||||
func maclin() {
|
func maclin() {
|
||||||
var c int
|
|
||||||
var n int32
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
var symb string
|
var symb string
|
||||||
|
|
||||||
n = getnsn()
|
n := getnsn()
|
||||||
c = getc()
|
c := getc()
|
||||||
if n < 0 {
|
if n < 0 {
|
||||||
goto bad
|
goto bad
|
||||||
}
|
}
|
||||||
|
|
@ -783,16 +761,43 @@ bad:
|
||||||
}
|
}
|
||||||
|
|
||||||
func macprag() {
|
func macprag() {
|
||||||
var s *Sym
|
|
||||||
var c0 int
|
|
||||||
var c int
|
var c int
|
||||||
var buf bytes.Buffer
|
|
||||||
var symb string
|
|
||||||
|
|
||||||
s = getsym()
|
s := getsym()
|
||||||
|
|
||||||
if s != nil && s.Name == "lib" {
|
if s != nil && s.Name == "lib" {
|
||||||
goto praglib
|
c0 := getnsc()
|
||||||
|
if c0 != '"' {
|
||||||
|
c = c0
|
||||||
|
if c0 != '<' {
|
||||||
|
goto bad
|
||||||
|
}
|
||||||
|
c0 = '>'
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
for {
|
||||||
|
c = getc()
|
||||||
|
if c == c0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if c == '\n' {
|
||||||
|
goto bad
|
||||||
|
}
|
||||||
|
buf.WriteByte(byte(c))
|
||||||
|
}
|
||||||
|
symb := buf.String()
|
||||||
|
|
||||||
|
c = getcom()
|
||||||
|
if c != '\n' {
|
||||||
|
goto bad
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* put pragma-line in as a funny history
|
||||||
|
*/
|
||||||
|
obj.Linklinehist(Ctxt, int(Lineno), symb, -1)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if s != nil && s.Name == "pack" {
|
if s != nil && s.Name == "pack" {
|
||||||
pragpack()
|
pragpack()
|
||||||
|
|
@ -830,43 +835,9 @@ func macprag() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for getnsc() != '\n' {
|
for getnsc() != '\n' {
|
||||||
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|
||||||
praglib:
|
|
||||||
c0 = getnsc()
|
|
||||||
if c0 != '"' {
|
|
||||||
c = c0
|
|
||||||
if c0 != '<' {
|
|
||||||
goto bad
|
|
||||||
}
|
|
||||||
c0 = '>'
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
c = getc()
|
|
||||||
if c == c0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if c == '\n' {
|
|
||||||
goto bad
|
|
||||||
}
|
|
||||||
buf.WriteByte(byte(c))
|
|
||||||
}
|
|
||||||
symb = buf.String()
|
|
||||||
|
|
||||||
c = getcom()
|
|
||||||
if c != '\n' {
|
|
||||||
goto bad
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* put pragma-line in as a funny history
|
|
||||||
*/
|
|
||||||
obj.Linklinehist(Ctxt, int(Lineno), symb, -1)
|
|
||||||
return
|
|
||||||
|
|
||||||
bad:
|
bad:
|
||||||
unget(c)
|
unget(c)
|
||||||
Yyerror("syntax in #pragma lib")
|
Yyerror("syntax in #pragma lib")
|
||||||
|
|
|
||||||
|
|
@ -582,7 +582,96 @@ func evconst(n *Node) {
|
||||||
var v Val
|
var v Val
|
||||||
var norig *Node
|
var norig *Node
|
||||||
if nr == nil {
|
if nr == nil {
|
||||||
goto unary
|
// copy numeric value to avoid modifying
|
||||||
|
// nl, in case someone still refers to it (e.g. iota).
|
||||||
|
v = nl.Val
|
||||||
|
|
||||||
|
if wl == TIDEAL {
|
||||||
|
v = copyval(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch uint32(n.Op)<<16 | uint32(v.Ctype) {
|
||||||
|
default:
|
||||||
|
if n.Diag == 0 {
|
||||||
|
Yyerror("illegal constant expression %v %v", Oconv(int(n.Op), 0), Tconv(nl.Type, 0))
|
||||||
|
n.Diag = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
case OCONV<<16 | CTNIL,
|
||||||
|
OARRAYBYTESTR<<16 | CTNIL:
|
||||||
|
if n.Type.Etype == TSTRING {
|
||||||
|
v = tostr(v)
|
||||||
|
nl.Type = n.Type
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
|
||||||
|
// fall through
|
||||||
|
case OCONV<<16 | CTINT,
|
||||||
|
OCONV<<16 | CTRUNE,
|
||||||
|
OCONV<<16 | CTFLT,
|
||||||
|
OCONV<<16 | CTSTR:
|
||||||
|
convlit1(&nl, n.Type, true)
|
||||||
|
|
||||||
|
v = nl.Val
|
||||||
|
|
||||||
|
case OPLUS<<16 | CTINT,
|
||||||
|
OPLUS<<16 | CTRUNE:
|
||||||
|
break
|
||||||
|
|
||||||
|
case OMINUS<<16 | CTINT,
|
||||||
|
OMINUS<<16 | CTRUNE:
|
||||||
|
mpnegfix(v.U.Xval)
|
||||||
|
|
||||||
|
case OCOM<<16 | CTINT,
|
||||||
|
OCOM<<16 | CTRUNE:
|
||||||
|
et := Txxx
|
||||||
|
if nl.Type != nil {
|
||||||
|
et = int(nl.Type.Etype)
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate the mask in b
|
||||||
|
// result will be (a ^ mask)
|
||||||
|
var b Mpint
|
||||||
|
switch et {
|
||||||
|
// signed guys change sign
|
||||||
|
default:
|
||||||
|
Mpmovecfix(&b, -1)
|
||||||
|
|
||||||
|
// unsigned guys invert their bits
|
||||||
|
case TUINT8,
|
||||||
|
TUINT16,
|
||||||
|
TUINT32,
|
||||||
|
TUINT64,
|
||||||
|
TUINT,
|
||||||
|
TUINTPTR:
|
||||||
|
mpmovefixfix(&b, Maxintval[et])
|
||||||
|
}
|
||||||
|
|
||||||
|
mpxorfixfix(v.U.Xval, &b)
|
||||||
|
|
||||||
|
case OPLUS<<16 | CTFLT:
|
||||||
|
break
|
||||||
|
|
||||||
|
case OMINUS<<16 | CTFLT:
|
||||||
|
mpnegflt(v.U.Fval)
|
||||||
|
|
||||||
|
case OPLUS<<16 | CTCPLX:
|
||||||
|
break
|
||||||
|
|
||||||
|
case OMINUS<<16 | CTCPLX:
|
||||||
|
mpnegflt(&v.U.Cval.Real)
|
||||||
|
mpnegflt(&v.U.Cval.Imag)
|
||||||
|
|
||||||
|
case ONOT<<16 | CTBOOL:
|
||||||
|
if v.U.Bval == 0 {
|
||||||
|
goto settrue
|
||||||
|
}
|
||||||
|
goto setfalse
|
||||||
|
}
|
||||||
|
goto ret
|
||||||
}
|
}
|
||||||
if nr.Type == nil {
|
if nr.Type == nil {
|
||||||
return
|
return
|
||||||
|
|
@ -944,97 +1033,6 @@ func evconst(n *Node) {
|
||||||
|
|
||||||
goto ret
|
goto ret
|
||||||
|
|
||||||
// copy numeric value to avoid modifying
|
|
||||||
// nl, in case someone still refers to it (e.g. iota).
|
|
||||||
unary:
|
|
||||||
v = nl.Val
|
|
||||||
|
|
||||||
if wl == TIDEAL {
|
|
||||||
v = copyval(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
switch uint32(n.Op)<<16 | uint32(v.Ctype) {
|
|
||||||
default:
|
|
||||||
if n.Diag == 0 {
|
|
||||||
Yyerror("illegal constant expression %v %v", Oconv(int(n.Op), 0), Tconv(nl.Type, 0))
|
|
||||||
n.Diag = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
case OCONV<<16 | CTNIL,
|
|
||||||
OARRAYBYTESTR<<16 | CTNIL:
|
|
||||||
if n.Type.Etype == TSTRING {
|
|
||||||
v = tostr(v)
|
|
||||||
nl.Type = n.Type
|
|
||||||
break
|
|
||||||
}
|
|
||||||
fallthrough
|
|
||||||
|
|
||||||
// fall through
|
|
||||||
case OCONV<<16 | CTINT,
|
|
||||||
OCONV<<16 | CTRUNE,
|
|
||||||
OCONV<<16 | CTFLT,
|
|
||||||
OCONV<<16 | CTSTR:
|
|
||||||
convlit1(&nl, n.Type, true)
|
|
||||||
|
|
||||||
v = nl.Val
|
|
||||||
|
|
||||||
case OPLUS<<16 | CTINT,
|
|
||||||
OPLUS<<16 | CTRUNE:
|
|
||||||
break
|
|
||||||
|
|
||||||
case OMINUS<<16 | CTINT,
|
|
||||||
OMINUS<<16 | CTRUNE:
|
|
||||||
mpnegfix(v.U.Xval)
|
|
||||||
|
|
||||||
case OCOM<<16 | CTINT,
|
|
||||||
OCOM<<16 | CTRUNE:
|
|
||||||
et := Txxx
|
|
||||||
if nl.Type != nil {
|
|
||||||
et = int(nl.Type.Etype)
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate the mask in b
|
|
||||||
// result will be (a ^ mask)
|
|
||||||
var b Mpint
|
|
||||||
switch et {
|
|
||||||
// signed guys change sign
|
|
||||||
default:
|
|
||||||
Mpmovecfix(&b, -1)
|
|
||||||
|
|
||||||
// unsigned guys invert their bits
|
|
||||||
case TUINT8,
|
|
||||||
TUINT16,
|
|
||||||
TUINT32,
|
|
||||||
TUINT64,
|
|
||||||
TUINT,
|
|
||||||
TUINTPTR:
|
|
||||||
mpmovefixfix(&b, Maxintval[et])
|
|
||||||
}
|
|
||||||
|
|
||||||
mpxorfixfix(v.U.Xval, &b)
|
|
||||||
|
|
||||||
case OPLUS<<16 | CTFLT:
|
|
||||||
break
|
|
||||||
|
|
||||||
case OMINUS<<16 | CTFLT:
|
|
||||||
mpnegflt(v.U.Fval)
|
|
||||||
|
|
||||||
case OPLUS<<16 | CTCPLX:
|
|
||||||
break
|
|
||||||
|
|
||||||
case OMINUS<<16 | CTCPLX:
|
|
||||||
mpnegflt(&v.U.Cval.Real)
|
|
||||||
mpnegflt(&v.U.Cval.Imag)
|
|
||||||
|
|
||||||
case ONOT<<16 | CTBOOL:
|
|
||||||
if v.U.Bval == 0 {
|
|
||||||
goto settrue
|
|
||||||
}
|
|
||||||
goto setfalse
|
|
||||||
}
|
|
||||||
|
|
||||||
ret:
|
ret:
|
||||||
norig = saveorig(n)
|
norig = saveorig(n)
|
||||||
*n = *nl
|
*n = *nl
|
||||||
|
|
|
||||||
|
|
@ -255,10 +255,12 @@ func Complexop(n *Node, res *Node) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Op == OREAL || n.Op == OIMAG {
|
if n.Op == OREAL || n.Op == OIMAG {
|
||||||
goto yes
|
//dump("\ncomplex-yes", n);
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
goto no
|
//dump("\ncomplex-no", n);
|
||||||
|
return false
|
||||||
|
|
||||||
maybe:
|
maybe:
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
|
|
@ -270,23 +272,20 @@ maybe:
|
||||||
OCOMPLEX,
|
OCOMPLEX,
|
||||||
OREAL,
|
OREAL,
|
||||||
OIMAG:
|
OIMAG:
|
||||||
goto yes
|
//dump("\ncomplex-yes", n);
|
||||||
|
return true
|
||||||
|
|
||||||
case ODOT,
|
case ODOT,
|
||||||
ODOTPTR,
|
ODOTPTR,
|
||||||
OINDEX,
|
OINDEX,
|
||||||
OIND,
|
OIND,
|
||||||
ONAME:
|
ONAME:
|
||||||
goto yes
|
//dump("\ncomplex-yes", n);
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
//dump("\ncomplex-no", n);
|
//dump("\ncomplex-no", n);
|
||||||
no:
|
|
||||||
return false
|
return false
|
||||||
|
|
||||||
//dump("\ncomplex-yes", n);
|
|
||||||
yes:
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Complexmove(f *Node, t *Node) {
|
func Complexmove(f *Node, t *Node) {
|
||||||
|
|
|
||||||
|
|
@ -844,7 +844,6 @@ type Loophack struct {
|
||||||
var _yylex_lstk *Loophack
|
var _yylex_lstk *Loophack
|
||||||
|
|
||||||
func _yylex(yylval *yySymType) int32 {
|
func _yylex(yylval *yySymType) int32 {
|
||||||
var c int
|
|
||||||
var c1 int
|
var c1 int
|
||||||
var escflag int
|
var escflag int
|
||||||
var v int64
|
var v int64
|
||||||
|
|
@ -857,7 +856,7 @@ func _yylex(yylval *yySymType) int32 {
|
||||||
prevlineno = lineno
|
prevlineno = lineno
|
||||||
|
|
||||||
l0:
|
l0:
|
||||||
c = getc()
|
c := getc()
|
||||||
if yy_isspace(c) {
|
if yy_isspace(c) {
|
||||||
if c == '\n' && curio.nlsemi != 0 {
|
if c == '\n' && curio.nlsemi != 0 {
|
||||||
ungetc(c)
|
ungetc(c)
|
||||||
|
|
@ -887,7 +886,82 @@ l0:
|
||||||
}
|
}
|
||||||
|
|
||||||
if yy_isdigit(c) {
|
if yy_isdigit(c) {
|
||||||
goto tnum
|
cp = &lexbuf
|
||||||
|
cp.Reset()
|
||||||
|
if c != '0' {
|
||||||
|
for {
|
||||||
|
cp.WriteByte(byte(c))
|
||||||
|
c = getc()
|
||||||
|
if yy_isdigit(c) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if c == '.' {
|
||||||
|
goto casedot
|
||||||
|
}
|
||||||
|
if c == 'e' || c == 'E' || c == 'p' || c == 'P' {
|
||||||
|
goto caseep
|
||||||
|
}
|
||||||
|
if c == 'i' {
|
||||||
|
goto casei
|
||||||
|
}
|
||||||
|
goto ncu
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cp.WriteByte(byte(c))
|
||||||
|
c = getc()
|
||||||
|
if c == 'x' || c == 'X' {
|
||||||
|
for {
|
||||||
|
cp.WriteByte(byte(c))
|
||||||
|
c = getc()
|
||||||
|
if yy_isdigit(c) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if c >= 'a' && c <= 'f' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if c >= 'A' && c <= 'F' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if lexbuf.Len() == 2 {
|
||||||
|
Yyerror("malformed hex constant")
|
||||||
|
}
|
||||||
|
if c == 'p' {
|
||||||
|
goto caseep
|
||||||
|
}
|
||||||
|
goto ncu
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if c == 'p' { // 0p begins floating point zero
|
||||||
|
goto caseep
|
||||||
|
}
|
||||||
|
|
||||||
|
c1 = 0
|
||||||
|
for {
|
||||||
|
if !yy_isdigit(c) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if c < '0' || c > '7' {
|
||||||
|
c1 = 1 // not octal
|
||||||
|
}
|
||||||
|
cp.WriteByte(byte(c))
|
||||||
|
c = getc()
|
||||||
|
}
|
||||||
|
|
||||||
|
if c == '.' {
|
||||||
|
goto casedot
|
||||||
|
}
|
||||||
|
if c == 'e' || c == 'E' {
|
||||||
|
goto caseep
|
||||||
|
}
|
||||||
|
if c == 'i' {
|
||||||
|
goto casei
|
||||||
|
}
|
||||||
|
if c1 != 0 {
|
||||||
|
Yyerror("malformed octal constant")
|
||||||
|
}
|
||||||
|
goto ncu
|
||||||
}
|
}
|
||||||
|
|
||||||
switch c {
|
switch c {
|
||||||
|
|
@ -1321,86 +1395,6 @@ talph:
|
||||||
yylval.sym = s
|
yylval.sym = s
|
||||||
return int32(s.Lexical)
|
return int32(s.Lexical)
|
||||||
|
|
||||||
tnum:
|
|
||||||
cp = &lexbuf
|
|
||||||
cp.Reset()
|
|
||||||
if c != '0' {
|
|
||||||
for {
|
|
||||||
cp.WriteByte(byte(c))
|
|
||||||
c = getc()
|
|
||||||
if yy_isdigit(c) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
goto dc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cp.WriteByte(byte(c))
|
|
||||||
c = getc()
|
|
||||||
if c == 'x' || c == 'X' {
|
|
||||||
for {
|
|
||||||
cp.WriteByte(byte(c))
|
|
||||||
c = getc()
|
|
||||||
if yy_isdigit(c) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if c >= 'a' && c <= 'f' {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if c >= 'A' && c <= 'F' {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if lexbuf.Len() == 2 {
|
|
||||||
Yyerror("malformed hex constant")
|
|
||||||
}
|
|
||||||
if c == 'p' {
|
|
||||||
goto caseep
|
|
||||||
}
|
|
||||||
goto ncu
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if c == 'p' { // 0p begins floating point zero
|
|
||||||
goto caseep
|
|
||||||
}
|
|
||||||
|
|
||||||
c1 = 0
|
|
||||||
for {
|
|
||||||
if !yy_isdigit(c) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if c < '0' || c > '7' {
|
|
||||||
c1 = 1 // not octal
|
|
||||||
}
|
|
||||||
cp.WriteByte(byte(c))
|
|
||||||
c = getc()
|
|
||||||
}
|
|
||||||
|
|
||||||
if c == '.' {
|
|
||||||
goto casedot
|
|
||||||
}
|
|
||||||
if c == 'e' || c == 'E' {
|
|
||||||
goto caseep
|
|
||||||
}
|
|
||||||
if c == 'i' {
|
|
||||||
goto casei
|
|
||||||
}
|
|
||||||
if c1 != 0 {
|
|
||||||
Yyerror("malformed octal constant")
|
|
||||||
}
|
|
||||||
goto ncu
|
|
||||||
|
|
||||||
dc:
|
|
||||||
if c == '.' {
|
|
||||||
goto casedot
|
|
||||||
}
|
|
||||||
if c == 'e' || c == 'E' || c == 'p' || c == 'P' {
|
|
||||||
goto caseep
|
|
||||||
}
|
|
||||||
if c == 'i' {
|
|
||||||
goto casei
|
|
||||||
}
|
|
||||||
|
|
||||||
ncu:
|
ncu:
|
||||||
cp = nil
|
cp = nil
|
||||||
ungetc(c)
|
ungetc(c)
|
||||||
|
|
@ -1523,31 +1517,90 @@ func more(pp *string) bool {
|
||||||
*/
|
*/
|
||||||
func getlinepragma() int {
|
func getlinepragma() int {
|
||||||
var cmd, verb, name string
|
var cmd, verb, name string
|
||||||
var n int
|
|
||||||
var cp *bytes.Buffer
|
|
||||||
var linep int
|
|
||||||
|
|
||||||
c := int(getr())
|
c := int(getr())
|
||||||
if c == 'g' {
|
if c == 'g' {
|
||||||
goto go_
|
cp := &lexbuf
|
||||||
|
cp.Reset()
|
||||||
|
cp.WriteByte('g') // already read
|
||||||
|
for {
|
||||||
|
c = int(getr())
|
||||||
|
if c == EOF || c >= utf8.RuneSelf {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
if c == '\n' {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
cp.WriteByte(byte(c))
|
||||||
|
}
|
||||||
|
|
||||||
|
cp = nil
|
||||||
|
|
||||||
|
if strings.HasPrefix(lexbuf.String(), "go:cgo_") {
|
||||||
|
pragcgo(lexbuf.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = lexbuf.String()
|
||||||
|
verb = cmd
|
||||||
|
if i := strings.Index(verb, " "); i >= 0 {
|
||||||
|
verb = verb[:i]
|
||||||
|
}
|
||||||
|
|
||||||
|
if verb == "go:linkname" {
|
||||||
|
if imported_unsafe == 0 {
|
||||||
|
Yyerror("//go:linkname only allowed in Go files that import \"unsafe\"")
|
||||||
|
}
|
||||||
|
f := strings.Fields(cmd)
|
||||||
|
if len(f) != 3 {
|
||||||
|
Yyerror("usage: //go:linkname localname linkname")
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
Lookup(f[1]).Linkname = f[2]
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
if verb == "go:nointerface" && obj.Fieldtrack_enabled != 0 {
|
||||||
|
nointerface = true
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
if verb == "go:noescape" {
|
||||||
|
noescape = true
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
if verb == "go:nosplit" {
|
||||||
|
nosplit = true
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
if verb == "go:nowritebarrier" {
|
||||||
|
if compiling_runtime == 0 {
|
||||||
|
Yyerror("//go:nowritebarrier only allowed in runtime")
|
||||||
|
}
|
||||||
|
nowritebarrier = true
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return c
|
||||||
}
|
}
|
||||||
if c != 'l' {
|
if c != 'l' {
|
||||||
goto out
|
return c
|
||||||
}
|
}
|
||||||
for i := 1; i < 5; i++ {
|
for i := 1; i < 5; i++ {
|
||||||
c = int(getr())
|
c = int(getr())
|
||||||
if c != int("line "[i]) {
|
if c != int("line "[i]) {
|
||||||
goto out
|
return c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cp = &lexbuf
|
cp := &lexbuf
|
||||||
cp.Reset()
|
cp.Reset()
|
||||||
linep = 0
|
linep := 0
|
||||||
for {
|
for {
|
||||||
c = int(getr())
|
c = int(getr())
|
||||||
if c == EOF {
|
if c == EOF {
|
||||||
goto out
|
return c
|
||||||
}
|
}
|
||||||
if c == '\n' {
|
if c == '\n' {
|
||||||
break
|
break
|
||||||
|
|
@ -1564,9 +1617,9 @@ func getlinepragma() int {
|
||||||
cp = nil
|
cp = nil
|
||||||
|
|
||||||
if linep == 0 {
|
if linep == 0 {
|
||||||
goto out
|
return c
|
||||||
}
|
}
|
||||||
n = 0
|
n := 0
|
||||||
for _, c := range lexbuf.String()[linep:] {
|
for _, c := range lexbuf.String()[linep:] {
|
||||||
if c < '0' || c > '9' {
|
if c < '0' || c > '9' {
|
||||||
goto out
|
goto out
|
||||||
|
|
@ -1579,7 +1632,7 @@ func getlinepragma() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
if n <= 0 {
|
if n <= 0 {
|
||||||
goto out
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to avoid allocating file name over and over
|
// try to avoid allocating file name over and over
|
||||||
|
|
@ -1587,76 +1640,12 @@ func getlinepragma() int {
|
||||||
for h := Ctxt.Hist; h != nil; h = h.Link {
|
for h := Ctxt.Hist; h != nil; h = h.Link {
|
||||||
if h.Name != "" && h.Name == name {
|
if h.Name != "" && h.Name == name {
|
||||||
linehist(h.Name, int32(n), 0)
|
linehist(h.Name, int32(n), 0)
|
||||||
goto out
|
return c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
linehist(name, int32(n), 0)
|
linehist(name, int32(n), 0)
|
||||||
goto out
|
return c
|
||||||
|
|
||||||
go_:
|
|
||||||
cp = &lexbuf
|
|
||||||
cp.Reset()
|
|
||||||
cp.WriteByte('g') // already read
|
|
||||||
for {
|
|
||||||
c = int(getr())
|
|
||||||
if c == EOF || c >= utf8.RuneSelf {
|
|
||||||
goto out
|
|
||||||
}
|
|
||||||
if c == '\n' {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
cp.WriteByte(byte(c))
|
|
||||||
}
|
|
||||||
|
|
||||||
cp = nil
|
|
||||||
|
|
||||||
if strings.HasPrefix(lexbuf.String(), "go:cgo_") {
|
|
||||||
pragcgo(lexbuf.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd = lexbuf.String()
|
|
||||||
verb = cmd
|
|
||||||
if i := strings.Index(verb, " "); i >= 0 {
|
|
||||||
verb = verb[:i]
|
|
||||||
}
|
|
||||||
|
|
||||||
if verb == "go:linkname" {
|
|
||||||
if imported_unsafe == 0 {
|
|
||||||
Yyerror("//go:linkname only allowed in Go files that import \"unsafe\"")
|
|
||||||
}
|
|
||||||
f := strings.Fields(cmd)
|
|
||||||
if len(f) != 3 {
|
|
||||||
Yyerror("usage: //go:linkname localname linkname")
|
|
||||||
goto out
|
|
||||||
}
|
|
||||||
|
|
||||||
Lookup(f[1]).Linkname = f[2]
|
|
||||||
goto out
|
|
||||||
}
|
|
||||||
|
|
||||||
if verb == "go:nointerface" && obj.Fieldtrack_enabled != 0 {
|
|
||||||
nointerface = true
|
|
||||||
goto out
|
|
||||||
}
|
|
||||||
|
|
||||||
if verb == "go:noescape" {
|
|
||||||
noescape = true
|
|
||||||
goto out
|
|
||||||
}
|
|
||||||
|
|
||||||
if verb == "go:nosplit" {
|
|
||||||
nosplit = true
|
|
||||||
goto out
|
|
||||||
}
|
|
||||||
|
|
||||||
if verb == "go:nowritebarrier" {
|
|
||||||
if compiling_runtime == 0 {
|
|
||||||
Yyerror("//go:nowritebarrier only allowed in runtime")
|
|
||||||
}
|
|
||||||
nowritebarrier = true
|
|
||||||
goto out
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return c
|
return c
|
||||||
|
|
@ -1708,14 +1697,12 @@ func pragcgo(text string) {
|
||||||
var p string
|
var p string
|
||||||
p, ok = getquoted(&q)
|
p, ok = getquoted(&q)
|
||||||
if !ok {
|
if !ok {
|
||||||
goto err1
|
Yyerror("usage: //go:cgo_dynamic_linker \"path\"")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
pragcgobuf += fmt.Sprintf("cgo_dynamic_linker %v\n", plan9quote(p))
|
pragcgobuf += fmt.Sprintf("cgo_dynamic_linker %v\n", plan9quote(p))
|
||||||
goto out
|
return
|
||||||
|
|
||||||
err1:
|
|
||||||
Yyerror("usage: //go:cgo_dynamic_linker \"path\"")
|
|
||||||
goto out
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if verb == "dynexport" {
|
if verb == "dynexport" {
|
||||||
|
|
@ -1729,7 +1716,7 @@ func pragcgo(text string) {
|
||||||
}
|
}
|
||||||
if !more(&q) {
|
if !more(&q) {
|
||||||
pragcgobuf += fmt.Sprintf("%s %v\n", verb, plan9quote(local))
|
pragcgobuf += fmt.Sprintf("%s %v\n", verb, plan9quote(local))
|
||||||
goto out
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
remote = getimpsym(&q)
|
remote = getimpsym(&q)
|
||||||
|
|
@ -1737,11 +1724,11 @@ func pragcgo(text string) {
|
||||||
goto err2
|
goto err2
|
||||||
}
|
}
|
||||||
pragcgobuf += fmt.Sprintf("%s %v %v\n", verb, plan9quote(local), plan9quote(remote))
|
pragcgobuf += fmt.Sprintf("%s %v %v\n", verb, plan9quote(local), plan9quote(remote))
|
||||||
goto out
|
return
|
||||||
|
|
||||||
err2:
|
err2:
|
||||||
Yyerror("usage: //go:%s local [remote]", verb)
|
Yyerror("usage: //go:%s local [remote]", verb)
|
||||||
goto out
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if verb == "cgo_import_dynamic" || verb == "dynimport" {
|
if verb == "cgo_import_dynamic" || verb == "dynimport" {
|
||||||
|
|
@ -1754,7 +1741,7 @@ func pragcgo(text string) {
|
||||||
}
|
}
|
||||||
if !more(&q) {
|
if !more(&q) {
|
||||||
pragcgobuf += fmt.Sprintf("cgo_import_dynamic %v\n", plan9quote(local))
|
pragcgobuf += fmt.Sprintf("cgo_import_dynamic %v\n", plan9quote(local))
|
||||||
goto out
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
remote = getimpsym(&q)
|
remote = getimpsym(&q)
|
||||||
|
|
@ -1763,7 +1750,7 @@ func pragcgo(text string) {
|
||||||
}
|
}
|
||||||
if !more(&q) {
|
if !more(&q) {
|
||||||
pragcgobuf += fmt.Sprintf("cgo_import_dynamic %v %v\n", plan9quote(local), plan9quote(remote))
|
pragcgobuf += fmt.Sprintf("cgo_import_dynamic %v %v\n", plan9quote(local), plan9quote(remote))
|
||||||
goto out
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
p, ok = getquoted(&q)
|
p, ok = getquoted(&q)
|
||||||
|
|
@ -1771,24 +1758,22 @@ func pragcgo(text string) {
|
||||||
goto err3
|
goto err3
|
||||||
}
|
}
|
||||||
pragcgobuf += fmt.Sprintf("cgo_import_dynamic %v %v %v\n", plan9quote(local), plan9quote(remote), plan9quote(p))
|
pragcgobuf += fmt.Sprintf("cgo_import_dynamic %v %v %v\n", plan9quote(local), plan9quote(remote), plan9quote(p))
|
||||||
goto out
|
return
|
||||||
|
|
||||||
err3:
|
err3:
|
||||||
Yyerror("usage: //go:cgo_import_dynamic local [remote [\"library\"]]")
|
Yyerror("usage: //go:cgo_import_dynamic local [remote [\"library\"]]")
|
||||||
goto out
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if verb == "cgo_import_static" {
|
if verb == "cgo_import_static" {
|
||||||
local := getimpsym(&q)
|
local := getimpsym(&q)
|
||||||
if local == "" || more(&q) {
|
if local == "" || more(&q) {
|
||||||
goto err4
|
Yyerror("usage: //go:cgo_import_static local")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
pragcgobuf += fmt.Sprintf("cgo_import_static %v\n", plan9quote(local))
|
pragcgobuf += fmt.Sprintf("cgo_import_static %v\n", plan9quote(local))
|
||||||
goto out
|
return
|
||||||
|
|
||||||
err4:
|
|
||||||
Yyerror("usage: //go:cgo_import_static local")
|
|
||||||
goto out
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if verb == "cgo_ldflag" {
|
if verb == "cgo_ldflag" {
|
||||||
|
|
@ -1796,17 +1781,13 @@ func pragcgo(text string) {
|
||||||
var p string
|
var p string
|
||||||
p, ok = getquoted(&q)
|
p, ok = getquoted(&q)
|
||||||
if !ok {
|
if !ok {
|
||||||
goto err5
|
Yyerror("usage: //go:cgo_ldflag \"arg\"")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
pragcgobuf += fmt.Sprintf("cgo_ldflag %v\n", plan9quote(p))
|
pragcgobuf += fmt.Sprintf("cgo_ldflag %v\n", plan9quote(p))
|
||||||
goto out
|
return
|
||||||
|
|
||||||
err5:
|
|
||||||
Yyerror("usage: //go:cgo_ldflag \"arg\"")
|
|
||||||
goto out
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type yy struct{}
|
type yy struct{}
|
||||||
|
|
@ -1983,7 +1964,6 @@ func escchar(e int, escflg *int, val *int64) bool {
|
||||||
|
|
||||||
u := 0
|
u := 0
|
||||||
c = int(getr())
|
c = int(getr())
|
||||||
var l int64
|
|
||||||
var i int
|
var i int
|
||||||
switch c {
|
switch c {
|
||||||
case 'x':
|
case 'x':
|
||||||
|
|
@ -2010,7 +1990,24 @@ func escchar(e int, escflg *int, val *int64) bool {
|
||||||
'6',
|
'6',
|
||||||
'7':
|
'7':
|
||||||
*escflg = 1 // it's a byte
|
*escflg = 1 // it's a byte
|
||||||
goto oct
|
l := int64(c) - '0'
|
||||||
|
for i := 2; i > 0; i-- {
|
||||||
|
c = getc()
|
||||||
|
if c >= '0' && c <= '7' {
|
||||||
|
l = l*8 + int64(c) - '0'
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
Yyerror("non-octal character in escape sequence: %c", c)
|
||||||
|
ungetc(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
if l > 255 {
|
||||||
|
Yyerror("octal escape value > 255: %d", l)
|
||||||
|
}
|
||||||
|
|
||||||
|
*val = l
|
||||||
|
return false
|
||||||
|
|
||||||
case 'a':
|
case 'a':
|
||||||
c = '\a'
|
c = '\a'
|
||||||
|
|
@ -2039,7 +2036,7 @@ func escchar(e int, escflg *int, val *int64) bool {
|
||||||
return false
|
return false
|
||||||
|
|
||||||
hex:
|
hex:
|
||||||
l = 0
|
l := int64(0)
|
||||||
for ; i > 0; i-- {
|
for ; i > 0; i-- {
|
||||||
c = getc()
|
c = getc()
|
||||||
if c >= '0' && c <= '9' {
|
if c >= '0' && c <= '9' {
|
||||||
|
|
@ -2067,26 +2064,6 @@ hex:
|
||||||
l = utf8.RuneError
|
l = utf8.RuneError
|
||||||
}
|
}
|
||||||
|
|
||||||
*val = l
|
|
||||||
return false
|
|
||||||
|
|
||||||
oct:
|
|
||||||
l = int64(c) - '0'
|
|
||||||
for i := 2; i > 0; i-- {
|
|
||||||
c = getc()
|
|
||||||
if c >= '0' && c <= '7' {
|
|
||||||
l = l*8 + int64(c) - '0'
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
Yyerror("non-octal character in escape sequence: %c", c)
|
|
||||||
ungetc(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
if l > 255 {
|
|
||||||
Yyerror("octal escape value > 255: %d", l)
|
|
||||||
}
|
|
||||||
|
|
||||||
*val = l
|
*val = l
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -451,7 +451,6 @@ bad:
|
||||||
//
|
//
|
||||||
func mpatofix(a *Mpint, as string) {
|
func mpatofix(a *Mpint, as string) {
|
||||||
var c int
|
var c int
|
||||||
var s0 string
|
|
||||||
|
|
||||||
s := as
|
s := as
|
||||||
f := 0
|
f := 0
|
||||||
|
|
@ -471,7 +470,43 @@ func mpatofix(a *Mpint, as string) {
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
||||||
case '0':
|
case '0':
|
||||||
goto oct
|
var c int
|
||||||
|
c, s = intstarstringplusplus(s)
|
||||||
|
if c == 'x' || c == 'X' {
|
||||||
|
s0 := s
|
||||||
|
var c int
|
||||||
|
c, _ = intstarstringplusplus(s)
|
||||||
|
for c != 0 {
|
||||||
|
if (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') {
|
||||||
|
s = s[1:]
|
||||||
|
c, _ = intstarstringplusplus(s)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
Yyerror("malformed hex constant: %s", as)
|
||||||
|
goto bad
|
||||||
|
}
|
||||||
|
|
||||||
|
mphextofix(a, s0)
|
||||||
|
if a.Ovf != 0 {
|
||||||
|
Yyerror("constant too large: %s", as)
|
||||||
|
goto bad
|
||||||
|
}
|
||||||
|
goto out
|
||||||
|
}
|
||||||
|
for c != 0 {
|
||||||
|
if c >= '0' && c <= '7' {
|
||||||
|
mpmulcfix(a, 8)
|
||||||
|
mpaddcfix(a, int64(c)-'0')
|
||||||
|
c, s = intstarstringplusplus(s)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
Yyerror("malformed octal constant: %s", as)
|
||||||
|
goto bad
|
||||||
|
}
|
||||||
|
|
||||||
|
goto out
|
||||||
}
|
}
|
||||||
|
|
||||||
for c != 0 {
|
for c != 0 {
|
||||||
|
|
@ -488,45 +523,6 @@ func mpatofix(a *Mpint, as string) {
|
||||||
|
|
||||||
goto out
|
goto out
|
||||||
|
|
||||||
oct:
|
|
||||||
c, s = intstarstringplusplus(s)
|
|
||||||
if c == 'x' || c == 'X' {
|
|
||||||
goto hex
|
|
||||||
}
|
|
||||||
for c != 0 {
|
|
||||||
if c >= '0' && c <= '7' {
|
|
||||||
mpmulcfix(a, 8)
|
|
||||||
mpaddcfix(a, int64(c)-'0')
|
|
||||||
c, s = intstarstringplusplus(s)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
Yyerror("malformed octal constant: %s", as)
|
|
||||||
goto bad
|
|
||||||
}
|
|
||||||
|
|
||||||
goto out
|
|
||||||
|
|
||||||
hex:
|
|
||||||
s0 = s
|
|
||||||
c, _ = intstarstringplusplus(s)
|
|
||||||
for c != 0 {
|
|
||||||
if (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') {
|
|
||||||
s = s[1:]
|
|
||||||
c, _ = intstarstringplusplus(s)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
Yyerror("malformed hex constant: %s", as)
|
|
||||||
goto bad
|
|
||||||
}
|
|
||||||
|
|
||||||
mphextofix(a, s0)
|
|
||||||
if a.Ovf != 0 {
|
|
||||||
Yyerror("constant too large: %s", as)
|
|
||||||
goto bad
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if f != 0 {
|
if f != 0 {
|
||||||
mpnegfix(a)
|
mpnegfix(a)
|
||||||
|
|
|
||||||
|
|
@ -187,12 +187,44 @@ func mpaddfixfix(a *Mpint, b *Mpint, quiet int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
c := 0
|
c := 0
|
||||||
var x int
|
|
||||||
if a.Neg != b.Neg {
|
if a.Neg != b.Neg {
|
||||||
goto sub
|
// perform a-b
|
||||||
|
switch mpcmp(a, b) {
|
||||||
|
case 0:
|
||||||
|
Mpmovecfix(a, 0)
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
var x int
|
||||||
|
for i := 0; i < Mpprec; i++ {
|
||||||
|
x = a.A[i] - b.A[i] - c
|
||||||
|
c = 0
|
||||||
|
if x < 0 {
|
||||||
|
x += Mpbase
|
||||||
|
c = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
a.A[i] = x
|
||||||
|
}
|
||||||
|
|
||||||
|
case -1:
|
||||||
|
a.Neg ^= 1
|
||||||
|
var x int
|
||||||
|
for i := 0; i < Mpprec; i++ {
|
||||||
|
x = b.A[i] - a.A[i] - c
|
||||||
|
c = 0
|
||||||
|
if x < 0 {
|
||||||
|
x += Mpbase
|
||||||
|
c = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
a.A[i] = x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// perform a+b
|
// perform a+b
|
||||||
|
var x int
|
||||||
for i := 0; i < Mpprec; i++ {
|
for i := 0; i < Mpprec; i++ {
|
||||||
x = a.A[i] + b.A[i] + c
|
x = a.A[i] + b.A[i] + c
|
||||||
c = 0
|
c = 0
|
||||||
|
|
@ -210,40 +242,6 @@ func mpaddfixfix(a *Mpint, b *Mpint, quiet int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
// perform a-b
|
|
||||||
sub:
|
|
||||||
switch mpcmp(a, b) {
|
|
||||||
case 0:
|
|
||||||
Mpmovecfix(a, 0)
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
var x int
|
|
||||||
for i := 0; i < Mpprec; i++ {
|
|
||||||
x = a.A[i] - b.A[i] - c
|
|
||||||
c = 0
|
|
||||||
if x < 0 {
|
|
||||||
x += Mpbase
|
|
||||||
c = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
a.A[i] = x
|
|
||||||
}
|
|
||||||
|
|
||||||
case -1:
|
|
||||||
a.Neg ^= 1
|
|
||||||
var x int
|
|
||||||
for i := 0; i < Mpprec; i++ {
|
|
||||||
x = b.A[i] - a.A[i] - c
|
|
||||||
c = 0
|
|
||||||
if x < 0 {
|
|
||||||
x += Mpbase
|
|
||||||
c = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
a.A[i] = x
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func mpmulfixfix(a *Mpint, b *Mpint) {
|
func mpmulfixfix(a *Mpint, b *Mpint) {
|
||||||
|
|
|
||||||
|
|
@ -657,7 +657,7 @@ Next:
|
||||||
PPARAMOUT:
|
PPARAMOUT:
|
||||||
pos, ok := to.Node.(*Node).Opt.(int32) // index in vars
|
pos, ok := to.Node.(*Node).Opt.(int32) // index in vars
|
||||||
if !ok {
|
if !ok {
|
||||||
goto Next1
|
return
|
||||||
}
|
}
|
||||||
if pos >= int32(len(vars)) || vars[pos] != to.Node {
|
if pos >= int32(len(vars)) || vars[pos] != to.Node {
|
||||||
Fatal("bad bookkeeping in liveness %v %d", Nconv(to.Node.(*Node), 0), pos)
|
Fatal("bad bookkeeping in liveness %v %d", Nconv(to.Node.(*Node), 0), pos)
|
||||||
|
|
@ -690,8 +690,6 @@ Next:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Next1:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructs a new liveness structure used to hold the global state of the
|
// Constructs a new liveness structure used to hold the global state of the
|
||||||
|
|
|
||||||
|
|
@ -185,32 +185,22 @@ func overlap_reg(o1 int64, w1 int, o2 int64, w2 int) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func mkvar(f *Flow, a *obj.Addr) Bits {
|
func mkvar(f *Flow, a *obj.Addr) Bits {
|
||||||
var v *Var
|
|
||||||
var i int
|
|
||||||
var n int
|
|
||||||
var et int
|
|
||||||
var flag int
|
|
||||||
var w int64
|
|
||||||
var o int64
|
|
||||||
var bit Bits
|
|
||||||
var node *Node
|
|
||||||
var r *Reg
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* mark registers used
|
* mark registers used
|
||||||
*/
|
*/
|
||||||
if a.Type == obj.TYPE_NONE {
|
if a.Type == obj.TYPE_NONE {
|
||||||
goto none
|
return zbits
|
||||||
}
|
}
|
||||||
|
|
||||||
r = f.Data.(*Reg)
|
r := f.Data.(*Reg)
|
||||||
r.use1.b[0] |= Thearch.Doregbits(int(a.Index)) // TODO: Use RtoB
|
r.use1.b[0] |= Thearch.Doregbits(int(a.Index)) // TODO: Use RtoB
|
||||||
|
|
||||||
|
var n int
|
||||||
switch a.Type {
|
switch a.Type {
|
||||||
default:
|
default:
|
||||||
regu := Thearch.Doregbits(int(a.Reg)) | Thearch.RtoB(int(a.Reg)) // TODO: Use RtoB
|
regu := Thearch.Doregbits(int(a.Reg)) | Thearch.RtoB(int(a.Reg)) // TODO: Use RtoB
|
||||||
if regu == 0 {
|
if regu == 0 {
|
||||||
goto none
|
return zbits
|
||||||
}
|
}
|
||||||
bit := zbits
|
bit := zbits
|
||||||
bit.b[0] = regu
|
bit.b[0] = regu
|
||||||
|
|
@ -227,7 +217,7 @@ func mkvar(f *Flow, a *obj.Addr) Bits {
|
||||||
setaddrs(bit)
|
setaddrs(bit)
|
||||||
a.Type = obj.TYPE_ADDR
|
a.Type = obj.TYPE_ADDR
|
||||||
Ostats.Naddr++
|
Ostats.Naddr++
|
||||||
goto none
|
return zbits
|
||||||
|
|
||||||
memcase:
|
memcase:
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
@ -243,7 +233,7 @@ func mkvar(f *Flow, a *obj.Addr) Bits {
|
||||||
*/
|
*/
|
||||||
switch a.Name {
|
switch a.Name {
|
||||||
default:
|
default:
|
||||||
goto none
|
return zbits
|
||||||
|
|
||||||
case obj.NAME_EXTERN,
|
case obj.NAME_EXTERN,
|
||||||
obj.NAME_STATIC,
|
obj.NAME_STATIC,
|
||||||
|
|
@ -253,25 +243,27 @@ func mkvar(f *Flow, a *obj.Addr) Bits {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var node *Node
|
||||||
node, _ = a.Node.(*Node)
|
node, _ = a.Node.(*Node)
|
||||||
if node == nil || node.Op != ONAME || node.Orig == nil {
|
if node == nil || node.Op != ONAME || node.Orig == nil {
|
||||||
goto none
|
return zbits
|
||||||
}
|
}
|
||||||
node = node.Orig
|
node = node.Orig
|
||||||
if node.Orig != node {
|
if node.Orig != node {
|
||||||
Fatal("%v: bad node", Ctxt.Dconv(a))
|
Fatal("%v: bad node", Ctxt.Dconv(a))
|
||||||
}
|
}
|
||||||
if node.Sym == nil || node.Sym.Name[0] == '.' {
|
if node.Sym == nil || node.Sym.Name[0] == '.' {
|
||||||
goto none
|
return zbits
|
||||||
}
|
}
|
||||||
et = int(a.Etype)
|
et := int(a.Etype)
|
||||||
o = a.Offset
|
o := a.Offset
|
||||||
w = a.Width
|
w := a.Width
|
||||||
if w < 0 {
|
if w < 0 {
|
||||||
Fatal("bad width %d for %v", w, Ctxt.Dconv(a))
|
Fatal("bad width %d for %v", w, Ctxt.Dconv(a))
|
||||||
}
|
}
|
||||||
|
|
||||||
flag = 0
|
flag := 0
|
||||||
|
var v *Var
|
||||||
for i := 0; i < nvar; i++ {
|
for i := 0; i < nvar; i++ {
|
||||||
v = &var_[i:][0]
|
v = &var_[i:][0]
|
||||||
if v.node == node && int(v.name) == n {
|
if v.node == node && int(v.name) == n {
|
||||||
|
|
@ -299,7 +291,7 @@ func mkvar(f *Flow, a *obj.Addr) Bits {
|
||||||
switch et {
|
switch et {
|
||||||
case 0,
|
case 0,
|
||||||
TFUNC:
|
TFUNC:
|
||||||
goto none
|
return zbits
|
||||||
}
|
}
|
||||||
|
|
||||||
if nvar >= NVAR {
|
if nvar >= NVAR {
|
||||||
|
|
@ -319,10 +311,10 @@ func mkvar(f *Flow, a *obj.Addr) Bits {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
goto none
|
return zbits
|
||||||
}
|
}
|
||||||
|
|
||||||
i = nvar
|
i := nvar
|
||||||
nvar++
|
nvar++
|
||||||
v = &var_[i:][0]
|
v = &var_[i:][0]
|
||||||
v.id = i
|
v.id = i
|
||||||
|
|
@ -341,7 +333,7 @@ func mkvar(f *Flow, a *obj.Addr) Bits {
|
||||||
|
|
||||||
node.Opt = v
|
node.Opt = v
|
||||||
|
|
||||||
bit = blsh(uint(i))
|
bit := blsh(uint(i))
|
||||||
if n == obj.NAME_EXTERN || n == obj.NAME_STATIC {
|
if n == obj.NAME_EXTERN || n == obj.NAME_STATIC {
|
||||||
for z := 0; z < BITS; z++ {
|
for z := 0; z < BITS; z++ {
|
||||||
externs.b[z] |= bit.b[z]
|
externs.b[z] |= bit.b[z]
|
||||||
|
|
@ -401,9 +393,6 @@ func mkvar(f *Flow, a *obj.Addr) Bits {
|
||||||
Ostats.Nvar++
|
Ostats.Nvar++
|
||||||
|
|
||||||
return bit
|
return bit
|
||||||
|
|
||||||
none:
|
|
||||||
return zbits
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func prop(f *Flow, ref Bits, cal Bits) {
|
func prop(f *Flow, ref Bits, cal Bits) {
|
||||||
|
|
|
||||||
|
|
@ -533,21 +533,18 @@ func isliteral(n *Node) bool {
|
||||||
|
|
||||||
func simplename(n *Node) bool {
|
func simplename(n *Node) bool {
|
||||||
if n.Op != ONAME {
|
if n.Op != ONAME {
|
||||||
goto no
|
return false
|
||||||
}
|
}
|
||||||
if n.Addable == 0 {
|
if n.Addable == 0 {
|
||||||
goto no
|
return false
|
||||||
}
|
}
|
||||||
if n.Class&PHEAP != 0 {
|
if n.Class&PHEAP != 0 {
|
||||||
goto no
|
return false
|
||||||
}
|
}
|
||||||
if n.Class == PPARAMREF {
|
if n.Class == PPARAMREF {
|
||||||
goto no
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
||||||
no:
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func litas(l *Node, r *Node, init **NodeList) {
|
func litas(l *Node, r *Node, init **NodeList) {
|
||||||
|
|
@ -1191,48 +1188,48 @@ func anylit(ctxt int, n *Node, var_ *Node, init **NodeList) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func oaslit(n *Node, init **NodeList) bool {
|
func oaslit(n *Node, init **NodeList) bool {
|
||||||
var ctxt int
|
|
||||||
|
|
||||||
if n.Left == nil || n.Right == nil {
|
if n.Left == nil || n.Right == nil {
|
||||||
goto no
|
// not a special composit literal assignment
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
if n.Left.Type == nil || n.Right.Type == nil {
|
if n.Left.Type == nil || n.Right.Type == nil {
|
||||||
goto no
|
// not a special composit literal assignment
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
if !simplename(n.Left) {
|
if !simplename(n.Left) {
|
||||||
goto no
|
// not a special composit literal assignment
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
if !Eqtype(n.Left.Type, n.Right.Type) {
|
if !Eqtype(n.Left.Type, n.Right.Type) {
|
||||||
goto no
|
// not a special composit literal assignment
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// context is init() function.
|
// context is init() function.
|
||||||
// implies generated data executed
|
// implies generated data executed
|
||||||
// exactly once and not subject to races.
|
// exactly once and not subject to races.
|
||||||
ctxt = 0
|
ctxt := 0
|
||||||
|
|
||||||
// if(n->dodata == 1)
|
// if(n->dodata == 1)
|
||||||
// ctxt = 1;
|
// ctxt = 1;
|
||||||
|
|
||||||
switch n.Right.Op {
|
switch n.Right.Op {
|
||||||
default:
|
default:
|
||||||
goto no
|
// not a special composit literal assignment
|
||||||
|
return false
|
||||||
|
|
||||||
case OSTRUCTLIT,
|
case OSTRUCTLIT,
|
||||||
OARRAYLIT,
|
OARRAYLIT,
|
||||||
OMAPLIT:
|
OMAPLIT:
|
||||||
if vmatch1(n.Left, n.Right) {
|
if vmatch1(n.Left, n.Right) {
|
||||||
goto no
|
// not a special composit literal assignment
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
anylit(ctxt, n.Right, n.Left, init)
|
anylit(ctxt, n.Right, n.Left, init)
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Op = OEMPTY
|
n.Op = OEMPTY
|
||||||
return true
|
return true
|
||||||
|
|
||||||
// not a special composit literal assignment
|
|
||||||
no:
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getlit(lit *Node) int {
|
func getlit(lit *Node) int {
|
||||||
|
|
@ -1244,7 +1241,7 @@ func getlit(lit *Node) int {
|
||||||
|
|
||||||
func stataddr(nam *Node, n *Node) bool {
|
func stataddr(nam *Node, n *Node) bool {
|
||||||
if n == nil {
|
if n == nil {
|
||||||
goto no
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
|
|
@ -1281,7 +1278,6 @@ func stataddr(nam *Node, n *Node) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
no:
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1420,7 +1416,6 @@ func gen_as_init(n *Node) bool {
|
||||||
var nr *Node
|
var nr *Node
|
||||||
var nl *Node
|
var nl *Node
|
||||||
var nam Node
|
var nam Node
|
||||||
var nod1 Node
|
|
||||||
|
|
||||||
if n.Dodata == 0 {
|
if n.Dodata == 0 {
|
||||||
goto no
|
goto no
|
||||||
|
|
@ -1436,7 +1431,7 @@ func gen_as_init(n *Node) bool {
|
||||||
if nam.Class != PEXTERN {
|
if nam.Class != PEXTERN {
|
||||||
goto no
|
goto no
|
||||||
}
|
}
|
||||||
goto yes
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if nr.Type == nil || !Eqtype(nl.Type, nr.Type) {
|
if nr.Type == nil || !Eqtype(nl.Type, nr.Type) {
|
||||||
|
|
@ -1466,7 +1461,33 @@ func gen_as_init(n *Node) bool {
|
||||||
case OSLICEARR:
|
case OSLICEARR:
|
||||||
if nr.Right.Op == OKEY && nr.Right.Left == nil && nr.Right.Right == nil {
|
if nr.Right.Op == OKEY && nr.Right.Left == nil && nr.Right.Right == nil {
|
||||||
nr = nr.Left
|
nr = nr.Left
|
||||||
goto slice
|
gused(nil) // in case the data is the dest of a goto
|
||||||
|
nl := nr
|
||||||
|
if nr == nil || nr.Op != OADDR {
|
||||||
|
goto no
|
||||||
|
}
|
||||||
|
nr = nr.Left
|
||||||
|
if nr == nil || nr.Op != ONAME {
|
||||||
|
goto no
|
||||||
|
}
|
||||||
|
|
||||||
|
// nr is the array being converted to a slice
|
||||||
|
if nr.Type == nil || nr.Type.Etype != TARRAY || nr.Type.Bound < 0 {
|
||||||
|
goto no
|
||||||
|
}
|
||||||
|
|
||||||
|
nam.Xoffset += int64(Array_array)
|
||||||
|
gdata(&nam, nl, int(Types[Tptr].Width))
|
||||||
|
|
||||||
|
nam.Xoffset += int64(Array_nel) - int64(Array_array)
|
||||||
|
var nod1 Node
|
||||||
|
Nodconst(&nod1, Types[TINT], nr.Type.Bound)
|
||||||
|
gdata(&nam, &nod1, Widthint)
|
||||||
|
|
||||||
|
nam.Xoffset += int64(Array_cap) - int64(Array_nel)
|
||||||
|
gdata(&nam, &nod1, Widthint)
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
goto no
|
goto no
|
||||||
|
|
@ -1505,37 +1526,8 @@ func gen_as_init(n *Node) bool {
|
||||||
gdatastring(&nam, nr.Val.U.Sval)
|
gdatastring(&nam, nr.Val.U.Sval)
|
||||||
}
|
}
|
||||||
|
|
||||||
yes:
|
|
||||||
return true
|
return true
|
||||||
|
|
||||||
slice:
|
|
||||||
gused(nil) // in case the data is the dest of a goto
|
|
||||||
nl = nr
|
|
||||||
if nr == nil || nr.Op != OADDR {
|
|
||||||
goto no
|
|
||||||
}
|
|
||||||
nr = nr.Left
|
|
||||||
if nr == nil || nr.Op != ONAME {
|
|
||||||
goto no
|
|
||||||
}
|
|
||||||
|
|
||||||
// nr is the array being converted to a slice
|
|
||||||
if nr.Type == nil || nr.Type.Etype != TARRAY || nr.Type.Bound < 0 {
|
|
||||||
goto no
|
|
||||||
}
|
|
||||||
|
|
||||||
nam.Xoffset += int64(Array_array)
|
|
||||||
gdata(&nam, nl, int(Types[Tptr].Width))
|
|
||||||
|
|
||||||
nam.Xoffset += int64(Array_nel) - int64(Array_array)
|
|
||||||
Nodconst(&nod1, Types[TINT], nr.Type.Bound)
|
|
||||||
gdata(&nam, &nod1, Widthint)
|
|
||||||
|
|
||||||
nam.Xoffset += int64(Array_cap) - int64(Array_nel)
|
|
||||||
gdata(&nam, &nod1, Widthint)
|
|
||||||
|
|
||||||
goto yes
|
|
||||||
|
|
||||||
no:
|
no:
|
||||||
if n.Dodata == 2 {
|
if n.Dodata == 2 {
|
||||||
Dump("\ngen_as_init", n)
|
Dump("\ngen_as_init", n)
|
||||||
|
|
|
||||||
|
|
@ -1014,14 +1014,14 @@ func eqtype1(t1 *Type, t2 *Type, assumed_equal *TypePairList) bool {
|
||||||
Fatal("struct/interface missing field: %v %v", Tconv(t1, 0), Tconv(t2, 0))
|
Fatal("struct/interface missing field: %v %v", Tconv(t1, 0), Tconv(t2, 0))
|
||||||
}
|
}
|
||||||
if t1.Sym != t2.Sym || t1.Embedded != t2.Embedded || !eqtype1(t1.Type, t2.Type, &l) || !eqnote(t1.Note, t2.Note) {
|
if t1.Sym != t2.Sym || t1.Embedded != t2.Embedded || !eqtype1(t1.Type, t2.Type, &l) || !eqnote(t1.Note, t2.Note) {
|
||||||
goto no
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if t1 == nil && t2 == nil {
|
if t1 == nil && t2 == nil {
|
||||||
goto yes
|
return true
|
||||||
}
|
}
|
||||||
goto no
|
return false
|
||||||
|
|
||||||
// Loop over structs: receiver, in, out.
|
// Loop over structs: receiver, in, out.
|
||||||
case TFUNC:
|
case TFUNC:
|
||||||
|
|
@ -1043,40 +1043,34 @@ func eqtype1(t1 *Type, t2 *Type, assumed_equal *TypePairList) bool {
|
||||||
Fatal("func struct missing field: %v %v", Tconv(ta, 0), Tconv(tb, 0))
|
Fatal("func struct missing field: %v %v", Tconv(ta, 0), Tconv(tb, 0))
|
||||||
}
|
}
|
||||||
if ta.Isddd != tb.Isddd || !eqtype1(ta.Type, tb.Type, &l) {
|
if ta.Isddd != tb.Isddd || !eqtype1(ta.Type, tb.Type, &l) {
|
||||||
goto no
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ta != nil || tb != nil {
|
if ta != nil || tb != nil {
|
||||||
goto no
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if t1 == nil && t2 == nil {
|
if t1 == nil && t2 == nil {
|
||||||
goto yes
|
return true
|
||||||
}
|
}
|
||||||
goto no
|
return false
|
||||||
|
|
||||||
case TARRAY:
|
case TARRAY:
|
||||||
if t1.Bound != t2.Bound {
|
if t1.Bound != t2.Bound {
|
||||||
goto no
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
case TCHAN:
|
case TCHAN:
|
||||||
if t1.Chan != t2.Chan {
|
if t1.Chan != t2.Chan {
|
||||||
goto no
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if eqtype1(t1.Down, t2.Down, &l) && eqtype1(t1.Type, t2.Type, &l) {
|
if eqtype1(t1.Down, t2.Down, &l) && eqtype1(t1.Type, t2.Type, &l) {
|
||||||
goto yes
|
return true
|
||||||
}
|
}
|
||||||
goto no
|
|
||||||
|
|
||||||
yes:
|
|
||||||
return true
|
|
||||||
|
|
||||||
no:
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1376,10 +1370,8 @@ func assignconv(n *Node, t *Type, context string) *Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
func subtype(stp **Type, t *Type, d int) bool {
|
func subtype(stp **Type, t *Type, d int) bool {
|
||||||
var st *Type
|
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
st = *stp
|
st := *stp
|
||||||
if st == nil {
|
if st == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -1762,7 +1754,7 @@ func Structfirst(s *Iter, nn **Type) *Type {
|
||||||
|
|
||||||
t = n.Type
|
t = n.Type
|
||||||
if t == nil {
|
if t == nil {
|
||||||
goto rnil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.Etype != TFIELD {
|
if t.Etype != TFIELD {
|
||||||
|
|
@ -1775,7 +1767,6 @@ func Structfirst(s *Iter, nn **Type) *Type {
|
||||||
bad:
|
bad:
|
||||||
Fatal("structfirst: not struct %v", Tconv(n, 0))
|
Fatal("structfirst: not struct %v", Tconv(n, 0))
|
||||||
|
|
||||||
rnil:
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1783,21 +1774,17 @@ func structnext(s *Iter) *Type {
|
||||||
n := s.T
|
n := s.T
|
||||||
t := n.Down
|
t := n.Down
|
||||||
if t == nil {
|
if t == nil {
|
||||||
goto rnil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.Etype != TFIELD {
|
if t.Etype != TFIELD {
|
||||||
goto bad
|
Fatal("structnext: not struct %v", Tconv(n, 0))
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
s.T = t
|
s.T = t
|
||||||
return t
|
return t
|
||||||
|
|
||||||
bad:
|
|
||||||
Fatal("structnext: not struct %v", Tconv(n, 0))
|
|
||||||
|
|
||||||
rnil:
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -2135,54 +2122,47 @@ out:
|
||||||
// will give shortest unique addressing.
|
// will give shortest unique addressing.
|
||||||
// modify the tree with missing type names.
|
// modify the tree with missing type names.
|
||||||
func adddot(n *Node) *Node {
|
func adddot(n *Node) *Node {
|
||||||
var s *Sym
|
|
||||||
var c int
|
|
||||||
var d int
|
|
||||||
|
|
||||||
typecheck(&n.Left, Etype|Erv)
|
typecheck(&n.Left, Etype|Erv)
|
||||||
n.Diag |= n.Left.Diag
|
n.Diag |= n.Left.Diag
|
||||||
t := n.Left.Type
|
t := n.Left.Type
|
||||||
if t == nil {
|
if t == nil {
|
||||||
goto ret
|
|
||||||
}
|
|
||||||
|
|
||||||
if n.Left.Op == OTYPE {
|
|
||||||
goto ret
|
|
||||||
}
|
|
||||||
|
|
||||||
if n.Right.Op != ONAME {
|
|
||||||
goto ret
|
|
||||||
}
|
|
||||||
s = n.Right.Sym
|
|
||||||
if s == nil {
|
|
||||||
goto ret
|
|
||||||
}
|
|
||||||
|
|
||||||
for d = 0; d < len(dotlist); d++ {
|
|
||||||
c = adddot1(s, t, d, nil, 0)
|
|
||||||
if c > 0 {
|
|
||||||
goto out
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
goto ret
|
|
||||||
|
|
||||||
out:
|
|
||||||
if c > 1 {
|
|
||||||
Yyerror("ambiguous selector %v", Nconv(n, 0))
|
|
||||||
n.Left = nil
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
// rebuild elided dots
|
if n.Left.Op == OTYPE {
|
||||||
for c := d - 1; c >= 0; c-- {
|
return n
|
||||||
if n.Left.Type != nil && Isptr[n.Left.Type.Etype] != 0 {
|
}
|
||||||
n.Left.Implicit = 1
|
|
||||||
}
|
if n.Right.Op != ONAME {
|
||||||
n.Left = Nod(ODOT, n.Left, newname(dotlist[c].field.Sym))
|
return n
|
||||||
|
}
|
||||||
|
s := n.Right.Sym
|
||||||
|
if s == nil {
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
var c int
|
||||||
|
for d := 0; d < len(dotlist); d++ {
|
||||||
|
c = adddot1(s, t, d, nil, 0)
|
||||||
|
if c > 0 {
|
||||||
|
if c > 1 {
|
||||||
|
Yyerror("ambiguous selector %v", Nconv(n, 0))
|
||||||
|
n.Left = nil
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// rebuild elided dots
|
||||||
|
for c := d - 1; c >= 0; c-- {
|
||||||
|
if n.Left.Type != nil && Isptr[n.Left.Type.Etype] != 0 {
|
||||||
|
n.Left.Implicit = 1
|
||||||
|
}
|
||||||
|
n.Left = Nod(ODOT, n.Left, newname(dotlist[c].field.Sym))
|
||||||
|
}
|
||||||
|
|
||||||
|
return n
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret:
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3301,18 +3281,15 @@ func structcount(t *Type) int {
|
||||||
* 1000+ if it is a -(power of 2)
|
* 1000+ if it is a -(power of 2)
|
||||||
*/
|
*/
|
||||||
func powtwo(n *Node) int {
|
func powtwo(n *Node) int {
|
||||||
var v uint64
|
|
||||||
var b uint64
|
|
||||||
|
|
||||||
if n == nil || n.Op != OLITERAL || n.Type == nil {
|
if n == nil || n.Op != OLITERAL || n.Type == nil {
|
||||||
goto no
|
return -1
|
||||||
}
|
}
|
||||||
if Isint[n.Type.Etype] == 0 {
|
if Isint[n.Type.Etype] == 0 {
|
||||||
goto no
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
v = uint64(Mpgetfix(n.Val.U.Xval))
|
v := uint64(Mpgetfix(n.Val.U.Xval))
|
||||||
b = 1
|
b := uint64(1)
|
||||||
for i := 0; i < 64; i++ {
|
for i := 0; i < 64; i++ {
|
||||||
if b == v {
|
if b == v {
|
||||||
return i
|
return i
|
||||||
|
|
@ -3321,7 +3298,7 @@ func powtwo(n *Node) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
if Issigned[n.Type.Etype] == 0 {
|
if Issigned[n.Type.Etype] == 0 {
|
||||||
goto no
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
v = -v
|
v = -v
|
||||||
|
|
@ -3333,7 +3310,6 @@ func powtwo(n *Node) int {
|
||||||
b = b << 1
|
b = b << 1
|
||||||
}
|
}
|
||||||
|
|
||||||
no:
|
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3592,22 +3568,19 @@ func pathtoprefix(s string) string {
|
||||||
for i := 0; i < len(s); i++ {
|
for i := 0; i < len(s); i++ {
|
||||||
c := s[i]
|
c := s[i]
|
||||||
if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F {
|
if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F {
|
||||||
goto escape
|
var buf bytes.Buffer
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
c := s[i]
|
||||||
|
if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F {
|
||||||
|
fmt.Fprintf(&buf, "%%%02x", c)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
buf.WriteByte(c)
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
|
|
||||||
escape:
|
|
||||||
var buf bytes.Buffer
|
|
||||||
for i := 0; i < len(s); i++ {
|
|
||||||
c := s[i]
|
|
||||||
if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F {
|
|
||||||
fmt.Fprintf(&buf, "%%%02x", c)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
buf.WriteByte(c)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func mkpkg(path_ *Strlit) *Pkg {
|
func mkpkg(path_ *Strlit) *Pkg {
|
||||||
|
|
|
||||||
|
|
@ -1805,7 +1805,25 @@ reswitch:
|
||||||
|
|
||||||
arith:
|
arith:
|
||||||
if op == OLSH || op == ORSH {
|
if op == OLSH || op == ORSH {
|
||||||
goto shift
|
defaultlit(&r, Types[TUINT])
|
||||||
|
n.Right = r
|
||||||
|
t := r.Type
|
||||||
|
if Isint[t.Etype] == 0 || Issigned[t.Etype] != 0 {
|
||||||
|
Yyerror("invalid operation: %v (shift count type %v, must be unsigned integer)", Nconv(n, 0), Tconv(r.Type, 0))
|
||||||
|
goto error
|
||||||
|
}
|
||||||
|
|
||||||
|
t = l.Type
|
||||||
|
if t != nil && t.Etype != TIDEAL && Isint[t.Etype] == 0 {
|
||||||
|
Yyerror("invalid operation: %v (shift of type %v)", Nconv(n, 0), Tconv(t, 0))
|
||||||
|
goto error
|
||||||
|
}
|
||||||
|
|
||||||
|
// no defaultlit for left
|
||||||
|
// the outer context gives the type
|
||||||
|
n.Type = l.Type
|
||||||
|
|
||||||
|
goto ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// ideal mixed with non-ideal
|
// ideal mixed with non-ideal
|
||||||
|
|
@ -1993,27 +2011,6 @@ arith:
|
||||||
n.Type = t
|
n.Type = t
|
||||||
goto ret
|
goto ret
|
||||||
|
|
||||||
shift:
|
|
||||||
defaultlit(&r, Types[TUINT])
|
|
||||||
n.Right = r
|
|
||||||
t = r.Type
|
|
||||||
if Isint[t.Etype] == 0 || Issigned[t.Etype] != 0 {
|
|
||||||
Yyerror("invalid operation: %v (shift count type %v, must be unsigned integer)", Nconv(n, 0), Tconv(r.Type, 0))
|
|
||||||
goto error
|
|
||||||
}
|
|
||||||
|
|
||||||
t = l.Type
|
|
||||||
if t != nil && t.Etype != TIDEAL && Isint[t.Etype] == 0 {
|
|
||||||
Yyerror("invalid operation: %v (shift of type %v)", Nconv(n, 0), Tconv(t, 0))
|
|
||||||
goto error
|
|
||||||
}
|
|
||||||
|
|
||||||
// no defaultlit for left
|
|
||||||
// the outer context gives the type
|
|
||||||
n.Type = l.Type
|
|
||||||
|
|
||||||
goto ret
|
|
||||||
|
|
||||||
doconv:
|
doconv:
|
||||||
ok |= Erv
|
ok |= Erv
|
||||||
saveorignode(n)
|
saveorignode(n)
|
||||||
|
|
|
||||||
|
|
@ -14,31 +14,28 @@ import "cmd/internal/obj"
|
||||||
* rewrite with a constant
|
* rewrite with a constant
|
||||||
*/
|
*/
|
||||||
func unsafenmagic(nn *Node) *Node {
|
func unsafenmagic(nn *Node) *Node {
|
||||||
var r *Node
|
|
||||||
var s *Sym
|
|
||||||
var v int64
|
|
||||||
|
|
||||||
fn := nn.Left
|
fn := nn.Left
|
||||||
args := nn.List
|
args := nn.List
|
||||||
|
|
||||||
if safemode != 0 || fn == nil || fn.Op != ONAME {
|
if safemode != 0 || fn == nil || fn.Op != ONAME {
|
||||||
goto no
|
return nil
|
||||||
}
|
}
|
||||||
s = fn.Sym
|
s := fn.Sym
|
||||||
if s == nil {
|
if s == nil {
|
||||||
goto no
|
return nil
|
||||||
}
|
}
|
||||||
if s.Pkg != unsafepkg {
|
if s.Pkg != unsafepkg {
|
||||||
goto no
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if args == nil {
|
if args == nil {
|
||||||
Yyerror("missing argument for %v", Sconv(s, 0))
|
Yyerror("missing argument for %v", Sconv(s, 0))
|
||||||
goto no
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
r = args.N
|
r := args.N
|
||||||
|
|
||||||
|
var v int64
|
||||||
if s.Name == "Sizeof" {
|
if s.Name == "Sizeof" {
|
||||||
typecheck(&r, Erv)
|
typecheck(&r, Erv)
|
||||||
defaultlit(&r, nil)
|
defaultlit(&r, nil)
|
||||||
|
|
@ -127,7 +124,6 @@ func unsafenmagic(nn *Node) *Node {
|
||||||
goto yes
|
goto yes
|
||||||
}
|
}
|
||||||
|
|
||||||
no:
|
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
bad:
|
bad:
|
||||||
|
|
|
||||||
|
|
@ -39,17 +39,14 @@ func isdigit(c int) bool {
|
||||||
|
|
||||||
func plan9quote(s string) string {
|
func plan9quote(s string) string {
|
||||||
if s == "" {
|
if s == "" {
|
||||||
goto needquote
|
return "'" + strings.Replace(s, "'", "''", -1) + "'"
|
||||||
}
|
}
|
||||||
for i := 0; i < len(s); i++ {
|
for i := 0; i < len(s); i++ {
|
||||||
if s[i] <= ' ' || s[i] == '\'' {
|
if s[i] <= ' ' || s[i] == '\'' {
|
||||||
goto needquote
|
return "'" + strings.Replace(s, "'", "''", -1) + "'"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
|
|
||||||
needquote:
|
|
||||||
return "'" + strings.Replace(s, "'", "''", -1) + "'"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// simulation of int(*s++) in C
|
// simulation of int(*s++) in C
|
||||||
|
|
|
||||||
|
|
@ -3653,7 +3653,23 @@ func walkrotate(np **Node) {
|
||||||
if sl >= 0 {
|
if sl >= 0 {
|
||||||
sr := int(Mpgetfix(r.Right.Val.U.Xval))
|
sr := int(Mpgetfix(r.Right.Val.U.Xval))
|
||||||
if sr >= 0 && sl+sr == w {
|
if sr >= 0 && sl+sr == w {
|
||||||
goto yes
|
// Rewrite left shift half to left rotate.
|
||||||
|
if l.Op == OLSH {
|
||||||
|
n = l
|
||||||
|
} else {
|
||||||
|
n = r
|
||||||
|
}
|
||||||
|
n.Op = OLROT
|
||||||
|
|
||||||
|
// Remove rotate 0 and rotate w.
|
||||||
|
s := int(Mpgetfix(n.Right.Val.U.Xval))
|
||||||
|
|
||||||
|
if s == 0 || s == w {
|
||||||
|
n = n.Left
|
||||||
|
}
|
||||||
|
|
||||||
|
*np = n
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|
@ -3661,25 +3677,6 @@ func walkrotate(np **Node) {
|
||||||
|
|
||||||
// TODO: Could allow s and 32-s if s is bounded (maybe s&31 and 32-s&31).
|
// TODO: Could allow s and 32-s if s is bounded (maybe s&31 and 32-s&31).
|
||||||
return
|
return
|
||||||
|
|
||||||
// Rewrite left shift half to left rotate.
|
|
||||||
yes:
|
|
||||||
if l.Op == OLSH {
|
|
||||||
n = l
|
|
||||||
} else {
|
|
||||||
n = r
|
|
||||||
}
|
|
||||||
n.Op = OLROT
|
|
||||||
|
|
||||||
// Remove rotate 0 and rotate w.
|
|
||||||
s := int(Mpgetfix(n.Right.Val.U.Xval))
|
|
||||||
|
|
||||||
if s == 0 || s == w {
|
|
||||||
n = n.Left
|
|
||||||
}
|
|
||||||
|
|
||||||
*np = n
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -3793,11 +3790,124 @@ func walkdiv(np **Node, init **NodeList) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var n1 *Node
|
|
||||||
var m Magic
|
|
||||||
var n2 *Node
|
|
||||||
if pow < 0 {
|
if pow < 0 {
|
||||||
goto divbymul
|
// try to do division by multiply by (2^w)/d
|
||||||
|
// see hacker's delight chapter 10
|
||||||
|
// TODO: support 64-bit magic multiply here.
|
||||||
|
var m Magic
|
||||||
|
m.W = w
|
||||||
|
|
||||||
|
if Issigned[nl.Type.Etype] != 0 {
|
||||||
|
m.Sd = Mpgetfix(nr.Val.U.Xval)
|
||||||
|
Smagic(&m)
|
||||||
|
} else {
|
||||||
|
m.Ud = uint64(Mpgetfix(nr.Val.U.Xval))
|
||||||
|
Umagic(&m)
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.Bad != 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have a quick division method so use it
|
||||||
|
// for modulo too.
|
||||||
|
if n.Op == OMOD {
|
||||||
|
// rewrite as A%B = A - (A/B*B).
|
||||||
|
n1 := Nod(ODIV, nl, nr)
|
||||||
|
|
||||||
|
n2 := Nod(OMUL, n1, nr)
|
||||||
|
n = Nod(OSUB, nl, n2)
|
||||||
|
goto ret
|
||||||
|
}
|
||||||
|
|
||||||
|
switch Simtype[nl.Type.Etype] {
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
|
||||||
|
// n1 = nl * magic >> w (HMUL)
|
||||||
|
case TUINT8,
|
||||||
|
TUINT16,
|
||||||
|
TUINT32:
|
||||||
|
nc := Nod(OXXX, nil, nil)
|
||||||
|
|
||||||
|
Nodconst(nc, nl.Type, int64(m.Um))
|
||||||
|
n1 := Nod(OMUL, nl, nc)
|
||||||
|
typecheck(&n1, Erv)
|
||||||
|
n1.Op = OHMUL
|
||||||
|
if m.Ua != 0 {
|
||||||
|
// Select a Go type with (at least) twice the width.
|
||||||
|
var twide *Type
|
||||||
|
switch Simtype[nl.Type.Etype] {
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
|
||||||
|
case TUINT8,
|
||||||
|
TUINT16:
|
||||||
|
twide = Types[TUINT32]
|
||||||
|
|
||||||
|
case TUINT32:
|
||||||
|
twide = Types[TUINT64]
|
||||||
|
|
||||||
|
case TINT8,
|
||||||
|
TINT16:
|
||||||
|
twide = Types[TINT32]
|
||||||
|
|
||||||
|
case TINT32:
|
||||||
|
twide = Types[TINT64]
|
||||||
|
}
|
||||||
|
|
||||||
|
// add numerator (might overflow).
|
||||||
|
// n2 = (n1 + nl)
|
||||||
|
n2 := Nod(OADD, conv(n1, twide), conv(nl, twide))
|
||||||
|
|
||||||
|
// shift by m.s
|
||||||
|
nc := Nod(OXXX, nil, nil)
|
||||||
|
|
||||||
|
Nodconst(nc, Types[TUINT], int64(m.S))
|
||||||
|
n = conv(Nod(ORSH, n2, nc), nl.Type)
|
||||||
|
} else {
|
||||||
|
// n = n1 >> m.s
|
||||||
|
nc := Nod(OXXX, nil, nil)
|
||||||
|
|
||||||
|
Nodconst(nc, Types[TUINT], int64(m.S))
|
||||||
|
n = Nod(ORSH, n1, nc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// n1 = nl * magic >> w
|
||||||
|
case TINT8,
|
||||||
|
TINT16,
|
||||||
|
TINT32:
|
||||||
|
nc := Nod(OXXX, nil, nil)
|
||||||
|
|
||||||
|
Nodconst(nc, nl.Type, m.Sm)
|
||||||
|
n1 := Nod(OMUL, nl, nc)
|
||||||
|
typecheck(&n1, Erv)
|
||||||
|
n1.Op = OHMUL
|
||||||
|
if m.Sm < 0 {
|
||||||
|
// add the numerator.
|
||||||
|
n1 = Nod(OADD, n1, nl)
|
||||||
|
}
|
||||||
|
|
||||||
|
// shift by m.s
|
||||||
|
nc = Nod(OXXX, nil, nil)
|
||||||
|
|
||||||
|
Nodconst(nc, Types[TUINT], int64(m.S))
|
||||||
|
n2 := conv(Nod(ORSH, n1, nc), nl.Type)
|
||||||
|
|
||||||
|
// add 1 iff n1 is negative.
|
||||||
|
nc = Nod(OXXX, nil, nil)
|
||||||
|
|
||||||
|
Nodconst(nc, Types[TUINT], int64(w)-1)
|
||||||
|
n3 := Nod(ORSH, nl, nc) // n4 = -1 iff n1 is negative.
|
||||||
|
n = Nod(OSUB, n2, n3)
|
||||||
|
|
||||||
|
// apply sign.
|
||||||
|
if m.Sd < 0 {
|
||||||
|
n = Nod(OMINUS, n, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
goto ret
|
||||||
}
|
}
|
||||||
|
|
||||||
switch pow {
|
switch pow {
|
||||||
|
|
@ -3905,127 +4015,6 @@ func walkdiv(np **Node, init **NodeList) {
|
||||||
|
|
||||||
goto ret
|
goto ret
|
||||||
|
|
||||||
// try to do division by multiply by (2^w)/d
|
|
||||||
// see hacker's delight chapter 10
|
|
||||||
// TODO: support 64-bit magic multiply here.
|
|
||||||
divbymul:
|
|
||||||
m.W = w
|
|
||||||
|
|
||||||
if Issigned[nl.Type.Etype] != 0 {
|
|
||||||
m.Sd = Mpgetfix(nr.Val.U.Xval)
|
|
||||||
Smagic(&m)
|
|
||||||
} else {
|
|
||||||
m.Ud = uint64(Mpgetfix(nr.Val.U.Xval))
|
|
||||||
Umagic(&m)
|
|
||||||
}
|
|
||||||
|
|
||||||
if m.Bad != 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// We have a quick division method so use it
|
|
||||||
// for modulo too.
|
|
||||||
if n.Op == OMOD {
|
|
||||||
goto longmod
|
|
||||||
}
|
|
||||||
|
|
||||||
switch Simtype[nl.Type.Etype] {
|
|
||||||
default:
|
|
||||||
return
|
|
||||||
|
|
||||||
// n1 = nl * magic >> w (HMUL)
|
|
||||||
case TUINT8,
|
|
||||||
TUINT16,
|
|
||||||
TUINT32:
|
|
||||||
nc := Nod(OXXX, nil, nil)
|
|
||||||
|
|
||||||
Nodconst(nc, nl.Type, int64(m.Um))
|
|
||||||
n1 := Nod(OMUL, nl, nc)
|
|
||||||
typecheck(&n1, Erv)
|
|
||||||
n1.Op = OHMUL
|
|
||||||
if m.Ua != 0 {
|
|
||||||
// Select a Go type with (at least) twice the width.
|
|
||||||
var twide *Type
|
|
||||||
switch Simtype[nl.Type.Etype] {
|
|
||||||
default:
|
|
||||||
return
|
|
||||||
|
|
||||||
case TUINT8,
|
|
||||||
TUINT16:
|
|
||||||
twide = Types[TUINT32]
|
|
||||||
|
|
||||||
case TUINT32:
|
|
||||||
twide = Types[TUINT64]
|
|
||||||
|
|
||||||
case TINT8,
|
|
||||||
TINT16:
|
|
||||||
twide = Types[TINT32]
|
|
||||||
|
|
||||||
case TINT32:
|
|
||||||
twide = Types[TINT64]
|
|
||||||
}
|
|
||||||
|
|
||||||
// add numerator (might overflow).
|
|
||||||
// n2 = (n1 + nl)
|
|
||||||
n2 := Nod(OADD, conv(n1, twide), conv(nl, twide))
|
|
||||||
|
|
||||||
// shift by m.s
|
|
||||||
nc := Nod(OXXX, nil, nil)
|
|
||||||
|
|
||||||
Nodconst(nc, Types[TUINT], int64(m.S))
|
|
||||||
n = conv(Nod(ORSH, n2, nc), nl.Type)
|
|
||||||
} else {
|
|
||||||
// n = n1 >> m.s
|
|
||||||
nc := Nod(OXXX, nil, nil)
|
|
||||||
|
|
||||||
Nodconst(nc, Types[TUINT], int64(m.S))
|
|
||||||
n = Nod(ORSH, n1, nc)
|
|
||||||
}
|
|
||||||
|
|
||||||
// n1 = nl * magic >> w
|
|
||||||
case TINT8,
|
|
||||||
TINT16,
|
|
||||||
TINT32:
|
|
||||||
nc := Nod(OXXX, nil, nil)
|
|
||||||
|
|
||||||
Nodconst(nc, nl.Type, m.Sm)
|
|
||||||
n1 := Nod(OMUL, nl, nc)
|
|
||||||
typecheck(&n1, Erv)
|
|
||||||
n1.Op = OHMUL
|
|
||||||
if m.Sm < 0 {
|
|
||||||
// add the numerator.
|
|
||||||
n1 = Nod(OADD, n1, nl)
|
|
||||||
}
|
|
||||||
|
|
||||||
// shift by m.s
|
|
||||||
nc = Nod(OXXX, nil, nil)
|
|
||||||
|
|
||||||
Nodconst(nc, Types[TUINT], int64(m.S))
|
|
||||||
n2 := conv(Nod(ORSH, n1, nc), nl.Type)
|
|
||||||
|
|
||||||
// add 1 iff n1 is negative.
|
|
||||||
nc = Nod(OXXX, nil, nil)
|
|
||||||
|
|
||||||
Nodconst(nc, Types[TUINT], int64(w)-1)
|
|
||||||
n3 := Nod(ORSH, nl, nc) // n4 = -1 iff n1 is negative.
|
|
||||||
n = Nod(OSUB, n2, n3)
|
|
||||||
|
|
||||||
// apply sign.
|
|
||||||
if m.Sd < 0 {
|
|
||||||
n = Nod(OMINUS, n, nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
goto ret
|
|
||||||
|
|
||||||
// rewrite as A%B = A - (A/B*B).
|
|
||||||
longmod:
|
|
||||||
n1 = Nod(ODIV, nl, nr)
|
|
||||||
|
|
||||||
n2 = Nod(OMUL, n1, nr)
|
|
||||||
n = Nod(OSUB, nl, n2)
|
|
||||||
goto ret
|
|
||||||
|
|
||||||
ret:
|
ret:
|
||||||
typecheck(&n, Erv)
|
typecheck(&n, Erv)
|
||||||
walkexpr(&n, init)
|
walkexpr(&n, init)
|
||||||
|
|
|
||||||
|
|
@ -81,9 +81,7 @@ func setuintxx(ctxt *Link, s *LSym, off int64, v uint64, wid int64) int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func adduintxx(ctxt *Link, s *LSym, v uint64, wid int) int64 {
|
func adduintxx(ctxt *Link, s *LSym, v uint64, wid int) int64 {
|
||||||
var off int64
|
off := s.Size
|
||||||
|
|
||||||
off = s.Size
|
|
||||||
setuintxx(ctxt, s, off, v, int64(wid))
|
setuintxx(ctxt, s, off, v, int64(wid))
|
||||||
return off
|
return off
|
||||||
}
|
}
|
||||||
|
|
@ -113,17 +111,14 @@ func setuint32(ctxt *Link, s *LSym, r int64, v uint32) int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Addaddrplus(ctxt *Link, s *LSym, t *LSym, add int64) int64 {
|
func Addaddrplus(ctxt *Link, s *LSym, t *LSym, add int64) int64 {
|
||||||
var i int64
|
|
||||||
var r *Reloc
|
|
||||||
|
|
||||||
if s.Type == 0 {
|
if s.Type == 0 {
|
||||||
s.Type = SDATA
|
s.Type = SDATA
|
||||||
}
|
}
|
||||||
s.Reachable = true
|
s.Reachable = true
|
||||||
i = s.Size
|
i := s.Size
|
||||||
s.Size += int64(ctxt.Arch.Ptrsize)
|
s.Size += int64(ctxt.Arch.Ptrsize)
|
||||||
Symgrow(ctxt, s, s.Size)
|
Symgrow(ctxt, s, s.Size)
|
||||||
r = Addrel(s)
|
r := Addrel(s)
|
||||||
r.Sym = t
|
r.Sym = t
|
||||||
r.Off = int32(i)
|
r.Off = int32(i)
|
||||||
r.Siz = uint8(ctxt.Arch.Ptrsize)
|
r.Siz = uint8(ctxt.Arch.Ptrsize)
|
||||||
|
|
@ -133,17 +128,14 @@ func Addaddrplus(ctxt *Link, s *LSym, t *LSym, add int64) int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Addpcrelplus(ctxt *Link, s *LSym, t *LSym, add int64) int64 {
|
func Addpcrelplus(ctxt *Link, s *LSym, t *LSym, add int64) int64 {
|
||||||
var i int64
|
|
||||||
var r *Reloc
|
|
||||||
|
|
||||||
if s.Type == 0 {
|
if s.Type == 0 {
|
||||||
s.Type = SDATA
|
s.Type = SDATA
|
||||||
}
|
}
|
||||||
s.Reachable = true
|
s.Reachable = true
|
||||||
i = s.Size
|
i := s.Size
|
||||||
s.Size += 4
|
s.Size += 4
|
||||||
Symgrow(ctxt, s, s.Size)
|
Symgrow(ctxt, s, s.Size)
|
||||||
r = Addrel(s)
|
r := Addrel(s)
|
||||||
r.Sym = t
|
r.Sym = t
|
||||||
r.Off = int32(i)
|
r.Off = int32(i)
|
||||||
r.Add = add
|
r.Add = add
|
||||||
|
|
@ -157,8 +149,6 @@ func Addaddr(ctxt *Link, s *LSym, t *LSym) int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func setaddrplus(ctxt *Link, s *LSym, off int64, t *LSym, add int64) int64 {
|
func setaddrplus(ctxt *Link, s *LSym, off int64, t *LSym, add int64) int64 {
|
||||||
var r *Reloc
|
|
||||||
|
|
||||||
if s.Type == 0 {
|
if s.Type == 0 {
|
||||||
s.Type = SDATA
|
s.Type = SDATA
|
||||||
}
|
}
|
||||||
|
|
@ -168,7 +158,7 @@ func setaddrplus(ctxt *Link, s *LSym, off int64, t *LSym, add int64) int64 {
|
||||||
Symgrow(ctxt, s, s.Size)
|
Symgrow(ctxt, s, s.Size)
|
||||||
}
|
}
|
||||||
|
|
||||||
r = Addrel(s)
|
r := Addrel(s)
|
||||||
r.Sym = t
|
r.Sym = t
|
||||||
r.Off = int32(off)
|
r.Off = int32(off)
|
||||||
r.Siz = uint8(ctxt.Arch.Ptrsize)
|
r.Siz = uint8(ctxt.Arch.Ptrsize)
|
||||||
|
|
@ -182,17 +172,14 @@ func setaddr(ctxt *Link, s *LSym, off int64, t *LSym) int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func addsize(ctxt *Link, s *LSym, t *LSym) int64 {
|
func addsize(ctxt *Link, s *LSym, t *LSym) int64 {
|
||||||
var i int64
|
|
||||||
var r *Reloc
|
|
||||||
|
|
||||||
if s.Type == 0 {
|
if s.Type == 0 {
|
||||||
s.Type = SDATA
|
s.Type = SDATA
|
||||||
}
|
}
|
||||||
s.Reachable = true
|
s.Reachable = true
|
||||||
i = s.Size
|
i := s.Size
|
||||||
s.Size += int64(ctxt.Arch.Ptrsize)
|
s.Size += int64(ctxt.Arch.Ptrsize)
|
||||||
Symgrow(ctxt, s, s.Size)
|
Symgrow(ctxt, s, s.Size)
|
||||||
r = Addrel(s)
|
r := Addrel(s)
|
||||||
r.Sym = t
|
r.Sym = t
|
||||||
r.Off = int32(i)
|
r.Off = int32(i)
|
||||||
r.Siz = uint8(ctxt.Arch.Ptrsize)
|
r.Siz = uint8(ctxt.Arch.Ptrsize)
|
||||||
|
|
@ -201,17 +188,14 @@ func addsize(ctxt *Link, s *LSym, t *LSym) int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func addaddrplus4(ctxt *Link, s *LSym, t *LSym, add int64) int64 {
|
func addaddrplus4(ctxt *Link, s *LSym, t *LSym, add int64) int64 {
|
||||||
var i int64
|
|
||||||
var r *Reloc
|
|
||||||
|
|
||||||
if s.Type == 0 {
|
if s.Type == 0 {
|
||||||
s.Type = SDATA
|
s.Type = SDATA
|
||||||
}
|
}
|
||||||
s.Reachable = true
|
s.Reachable = true
|
||||||
i = s.Size
|
i := s.Size
|
||||||
s.Size += 4
|
s.Size += 4
|
||||||
Symgrow(ctxt, s, s.Size)
|
Symgrow(ctxt, s, s.Size)
|
||||||
r = Addrel(s)
|
r := Addrel(s)
|
||||||
r.Sym = t
|
r.Sym = t
|
||||||
r.Off = int32(i)
|
r.Off = int32(i)
|
||||||
r.Siz = 4
|
r.Siz = 4
|
||||||
|
|
@ -253,16 +237,12 @@ func listsubp(s *LSym) **LSym {
|
||||||
}
|
}
|
||||||
|
|
||||||
func listsort(l *LSym, cmp func(*LSym, *LSym) int, nextp func(*LSym) **LSym) *LSym {
|
func listsort(l *LSym, cmp func(*LSym, *LSym) int, nextp func(*LSym) **LSym) *LSym {
|
||||||
var l1 *LSym
|
|
||||||
var l2 *LSym
|
|
||||||
var le *LSym
|
|
||||||
|
|
||||||
if l == nil || *nextp(l) == nil {
|
if l == nil || *nextp(l) == nil {
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
l1 = l
|
l1 := l
|
||||||
l2 = l
|
l2 := l
|
||||||
for {
|
for {
|
||||||
l2 = *nextp(l2)
|
l2 = *nextp(l2)
|
||||||
if l2 == nil {
|
if l2 == nil {
|
||||||
|
|
@ -289,7 +269,7 @@ func listsort(l *LSym, cmp func(*LSym, *LSym) int, nextp func(*LSym) **LSym) *LS
|
||||||
l2 = *nextp(l2)
|
l2 = *nextp(l2)
|
||||||
}
|
}
|
||||||
|
|
||||||
le = l
|
le := l
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if l1 == nil {
|
if l1 == nil {
|
||||||
|
|
@ -332,14 +312,13 @@ func relocsym(s *LSym) {
|
||||||
var r *Reloc
|
var r *Reloc
|
||||||
var rs *LSym
|
var rs *LSym
|
||||||
var i16 int16
|
var i16 int16
|
||||||
var ri int32
|
|
||||||
var off int32
|
var off int32
|
||||||
var siz int32
|
var siz int32
|
||||||
var fl int32
|
var fl int32
|
||||||
var o int64
|
var o int64
|
||||||
|
|
||||||
Ctxt.Cursym = s
|
Ctxt.Cursym = s
|
||||||
for ri = 0; ri < int32(len(s.R)); ri++ {
|
for ri := int32(0); ri < int32(len(s.R)); ri++ {
|
||||||
r = &s.R[ri]
|
r = &s.R[ri]
|
||||||
r.Done = 1
|
r.Done = 1
|
||||||
off = r.Off
|
off = r.Off
|
||||||
|
|
@ -591,34 +570,28 @@ func relocsym(s *LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func reloc() {
|
func reloc() {
|
||||||
var s *LSym
|
|
||||||
|
|
||||||
if Debug['v'] != 0 {
|
if Debug['v'] != 0 {
|
||||||
fmt.Fprintf(&Bso, "%5.2f reloc\n", obj.Cputime())
|
fmt.Fprintf(&Bso, "%5.2f reloc\n", obj.Cputime())
|
||||||
}
|
}
|
||||||
Bflush(&Bso)
|
Bflush(&Bso)
|
||||||
|
|
||||||
for s = Ctxt.Textp; s != nil; s = s.Next {
|
for s := Ctxt.Textp; s != nil; s = s.Next {
|
||||||
relocsym(s)
|
relocsym(s)
|
||||||
}
|
}
|
||||||
for s = datap; s != nil; s = s.Next {
|
for s := datap; s != nil; s = s.Next {
|
||||||
relocsym(s)
|
relocsym(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func dynrelocsym(s *LSym) {
|
func dynrelocsym(s *LSym) {
|
||||||
var ri int
|
|
||||||
var r *Reloc
|
|
||||||
|
|
||||||
if HEADTYPE == Hwindows {
|
if HEADTYPE == Hwindows {
|
||||||
var rel *LSym
|
rel := Linklookup(Ctxt, ".rel", 0)
|
||||||
var targ *LSym
|
|
||||||
|
|
||||||
rel = Linklookup(Ctxt, ".rel", 0)
|
|
||||||
if s == rel {
|
if s == rel {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for ri = 0; ri < len(s.R); ri++ {
|
var r *Reloc
|
||||||
|
var targ *LSym
|
||||||
|
for ri := 0; ri < len(s.R); ri++ {
|
||||||
r = &s.R[ri]
|
r = &s.R[ri]
|
||||||
targ = r.Sym
|
targ = r.Sym
|
||||||
if targ == nil {
|
if targ == nil {
|
||||||
|
|
@ -655,7 +628,8 @@ func dynrelocsym(s *LSym) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for ri = 0; ri < len(s.R); ri++ {
|
var r *Reloc
|
||||||
|
for ri := 0; ri < len(s.R); ri++ {
|
||||||
r = &s.R[ri]
|
r = &s.R[ri]
|
||||||
if r.Sym != nil && r.Sym.Type == SDYNIMPORT || r.Type >= 256 {
|
if r.Sym != nil && r.Sym.Type == SDYNIMPORT || r.Type >= 256 {
|
||||||
if r.Sym != nil && !r.Sym.Reachable {
|
if r.Sym != nil && !r.Sym.Reachable {
|
||||||
|
|
@ -667,8 +641,6 @@ func dynrelocsym(s *LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func dynreloc() {
|
func dynreloc() {
|
||||||
var s *LSym
|
|
||||||
|
|
||||||
// -d suppresses dynamic loader format, so we may as well not
|
// -d suppresses dynamic loader format, so we may as well not
|
||||||
// compute these sections or mark their symbols as reachable.
|
// compute these sections or mark their symbols as reachable.
|
||||||
if Debug['d'] != 0 && HEADTYPE != Hwindows {
|
if Debug['d'] != 0 && HEADTYPE != Hwindows {
|
||||||
|
|
@ -679,10 +651,10 @@ func dynreloc() {
|
||||||
}
|
}
|
||||||
Bflush(&Bso)
|
Bflush(&Bso)
|
||||||
|
|
||||||
for s = Ctxt.Textp; s != nil; s = s.Next {
|
for s := Ctxt.Textp; s != nil; s = s.Next {
|
||||||
dynrelocsym(s)
|
dynrelocsym(s)
|
||||||
}
|
}
|
||||||
for s = datap; s != nil; s = s.Next {
|
for s := datap; s != nil; s = s.Next {
|
||||||
dynrelocsym(s)
|
dynrelocsym(s)
|
||||||
}
|
}
|
||||||
if Iself {
|
if Iself {
|
||||||
|
|
@ -692,9 +664,6 @@ func dynreloc() {
|
||||||
|
|
||||||
func blk(start *LSym, addr int64, size int64) {
|
func blk(start *LSym, addr int64, size int64) {
|
||||||
var sym *LSym
|
var sym *LSym
|
||||||
var eaddr int64
|
|
||||||
var p []byte
|
|
||||||
var ep []byte
|
|
||||||
|
|
||||||
for sym = start; sym != nil; sym = sym.Next {
|
for sym = start; sym != nil; sym = sym.Next {
|
||||||
if sym.Type&SSUB == 0 && sym.Value >= addr {
|
if sym.Type&SSUB == 0 && sym.Value >= addr {
|
||||||
|
|
@ -702,7 +671,9 @@ func blk(start *LSym, addr int64, size int64) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eaddr = addr + size
|
eaddr := addr + size
|
||||||
|
var ep []byte
|
||||||
|
var p []byte
|
||||||
for ; sym != nil; sym = sym.Next {
|
for ; sym != nil; sym = sym.Next {
|
||||||
if sym.Type&SSUB != 0 {
|
if sym.Type&SSUB != 0 {
|
||||||
continue
|
continue
|
||||||
|
|
@ -746,11 +717,6 @@ func blk(start *LSym, addr int64, size int64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Codeblk(addr int64, size int64) {
|
func Codeblk(addr int64, size int64) {
|
||||||
var sym *LSym
|
|
||||||
var eaddr int64
|
|
||||||
var n int64
|
|
||||||
var q []byte
|
|
||||||
|
|
||||||
if Debug['a'] != 0 {
|
if Debug['a'] != 0 {
|
||||||
fmt.Fprintf(&Bso, "codeblk [%#x,%#x) at offset %#x\n", addr, addr+size, Cpos())
|
fmt.Fprintf(&Bso, "codeblk [%#x,%#x) at offset %#x\n", addr, addr+size, Cpos())
|
||||||
}
|
}
|
||||||
|
|
@ -762,6 +728,7 @@ func Codeblk(addr int64, size int64) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sym *LSym
|
||||||
for sym = Ctxt.Textp; sym != nil; sym = sym.Next {
|
for sym = Ctxt.Textp; sym != nil; sym = sym.Next {
|
||||||
if !sym.Reachable {
|
if !sym.Reachable {
|
||||||
continue
|
continue
|
||||||
|
|
@ -771,7 +738,9 @@ func Codeblk(addr int64, size int64) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eaddr = addr + size
|
eaddr := addr + size
|
||||||
|
var n int64
|
||||||
|
var q []byte
|
||||||
for ; sym != nil; sym = sym.Next {
|
for ; sym != nil; sym = sym.Next {
|
||||||
if !sym.Reachable {
|
if !sym.Reachable {
|
||||||
continue
|
continue
|
||||||
|
|
@ -816,15 +785,6 @@ func Codeblk(addr int64, size int64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Datblk(addr int64, size int64) {
|
func Datblk(addr int64, size int64) {
|
||||||
var sym *LSym
|
|
||||||
var i int64
|
|
||||||
var eaddr int64
|
|
||||||
var p []byte
|
|
||||||
var ep []byte
|
|
||||||
var typ string
|
|
||||||
var rsname string
|
|
||||||
var r *Reloc
|
|
||||||
|
|
||||||
if Debug['a'] != 0 {
|
if Debug['a'] != 0 {
|
||||||
fmt.Fprintf(&Bso, "datblk [%#x,%#x) at offset %#x\n", addr, addr+size, Cpos())
|
fmt.Fprintf(&Bso, "datblk [%#x,%#x) at offset %#x\n", addr, addr+size, Cpos())
|
||||||
}
|
}
|
||||||
|
|
@ -836,13 +796,20 @@ func Datblk(addr int64, size int64) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sym *LSym
|
||||||
for sym = datap; sym != nil; sym = sym.Next {
|
for sym = datap; sym != nil; sym = sym.Next {
|
||||||
if sym.Value >= addr {
|
if sym.Value >= addr {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eaddr = addr + size
|
eaddr := addr + size
|
||||||
|
var ep []byte
|
||||||
|
var i int64
|
||||||
|
var p []byte
|
||||||
|
var r *Reloc
|
||||||
|
var rsname string
|
||||||
|
var typ string
|
||||||
for ; sym != nil; sym = sym.Next {
|
for ; sym != nil; sym = sym.Next {
|
||||||
if sym.Value >= eaddr {
|
if sym.Value >= eaddr {
|
||||||
break
|
break
|
||||||
|
|
@ -922,21 +889,16 @@ func addstrdata1(arg string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func addstrdata(name string, value string) {
|
func addstrdata(name string, value string) {
|
||||||
var s *LSym
|
p := fmt.Sprintf("%s.str", name)
|
||||||
var sp *LSym
|
sp := Linklookup(Ctxt, p, 0)
|
||||||
var p string
|
|
||||||
var reachable bool
|
|
||||||
|
|
||||||
p = fmt.Sprintf("%s.str", name)
|
|
||||||
sp = Linklookup(Ctxt, p, 0)
|
|
||||||
|
|
||||||
Addstring(sp, value)
|
Addstring(sp, value)
|
||||||
sp.Type = SRODATA
|
sp.Type = SRODATA
|
||||||
|
|
||||||
s = Linklookup(Ctxt, name, 0)
|
s := Linklookup(Ctxt, name, 0)
|
||||||
s.Size = 0
|
s.Size = 0
|
||||||
s.Dupok = 1
|
s.Dupok = 1
|
||||||
reachable = s.Reachable
|
reachable := s.Reachable
|
||||||
Addaddr(Ctxt, s, sp)
|
Addaddr(Ctxt, s, sp)
|
||||||
adduintxx(Ctxt, s, uint64(len(value)), Thearch.Ptrsize)
|
adduintxx(Ctxt, s, uint64(len(value)), Thearch.Ptrsize)
|
||||||
|
|
||||||
|
|
@ -949,15 +911,12 @@ func addstrdata(name string, value string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Addstring(s *LSym, str string) int64 {
|
func Addstring(s *LSym, str string) int64 {
|
||||||
var n int
|
|
||||||
var r int32
|
|
||||||
|
|
||||||
if s.Type == 0 {
|
if s.Type == 0 {
|
||||||
s.Type = SNOPTRDATA
|
s.Type = SNOPTRDATA
|
||||||
}
|
}
|
||||||
s.Reachable = true
|
s.Reachable = true
|
||||||
r = int32(s.Size)
|
r := int32(s.Size)
|
||||||
n = len(str) + 1
|
n := len(str) + 1
|
||||||
if s.Name == ".shstrtab" {
|
if s.Name == ".shstrtab" {
|
||||||
elfsetstring(str, int(r))
|
elfsetstring(str, int(r))
|
||||||
}
|
}
|
||||||
|
|
@ -969,9 +928,7 @@ func Addstring(s *LSym, str string) int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func dosymtype() {
|
func dosymtype() {
|
||||||
var s *LSym
|
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
||||||
|
|
||||||
for s = Ctxt.Allsym; s != nil; s = s.Allsym {
|
|
||||||
if len(s.P) > 0 {
|
if len(s.P) > 0 {
|
||||||
if s.Type == SBSS {
|
if s.Type == SBSS {
|
||||||
s.Type = SDATA
|
s.Type = SDATA
|
||||||
|
|
@ -984,13 +941,11 @@ func dosymtype() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func symalign(s *LSym) int32 {
|
func symalign(s *LSym) int32 {
|
||||||
var align int32
|
|
||||||
|
|
||||||
if s.Align != 0 {
|
if s.Align != 0 {
|
||||||
return s.Align
|
return s.Align
|
||||||
}
|
}
|
||||||
|
|
||||||
align = int32(Thearch.Maxalign)
|
align := int32(Thearch.Maxalign)
|
||||||
for int64(align) > s.Size && align > 1 {
|
for int64(align) > s.Size && align > 1 {
|
||||||
align >>= 1
|
align >>= 1
|
||||||
}
|
}
|
||||||
|
|
@ -1008,9 +963,8 @@ func aligndatsize(datsize int64, s *LSym) int64 {
|
||||||
// the list of symbols s; the list stops when s->type exceeds type.
|
// the list of symbols s; the list stops when s->type exceeds type.
|
||||||
func maxalign(s *LSym, type_ int) int32 {
|
func maxalign(s *LSym, type_ int) int32 {
|
||||||
var align int32
|
var align int32
|
||||||
var max int32
|
|
||||||
|
|
||||||
max = 0
|
max := int32(0)
|
||||||
for ; s != nil && int(s.Type) <= type_; s = s.Next {
|
for ; s != nil && int(s.Type) <= type_; s = s.Next {
|
||||||
align = symalign(s)
|
align = symalign(s)
|
||||||
if max < align {
|
if max < align {
|
||||||
|
|
@ -1042,16 +996,13 @@ func proggenemit(g *ProgGen, v uint8) {
|
||||||
|
|
||||||
// Writes insData block from g->data.
|
// Writes insData block from g->data.
|
||||||
func proggendataflush(g *ProgGen) {
|
func proggendataflush(g *ProgGen) {
|
||||||
var i int32
|
|
||||||
var s int32
|
|
||||||
|
|
||||||
if g.datasize == 0 {
|
if g.datasize == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
proggenemit(g, obj.InsData)
|
proggenemit(g, obj.InsData)
|
||||||
proggenemit(g, uint8(g.datasize))
|
proggenemit(g, uint8(g.datasize))
|
||||||
s = (g.datasize + obj.PointersPerByte - 1) / obj.PointersPerByte
|
s := (g.datasize + obj.PointersPerByte - 1) / obj.PointersPerByte
|
||||||
for i = 0; i < s; i++ {
|
for i := int32(0); i < s; i++ {
|
||||||
proggenemit(g, g.data[i])
|
proggenemit(g, g.data[i])
|
||||||
}
|
}
|
||||||
g.datasize = 0
|
g.datasize = 0
|
||||||
|
|
@ -1068,9 +1019,7 @@ func proggendata(g *ProgGen, d uint8) {
|
||||||
|
|
||||||
// Skip v bytes due to alignment, etc.
|
// Skip v bytes due to alignment, etc.
|
||||||
func proggenskip(g *ProgGen, off int64, v int64) {
|
func proggenskip(g *ProgGen, off int64, v int64) {
|
||||||
var i int64
|
for i := off; i < off+v; i++ {
|
||||||
|
|
||||||
for i = off; i < off+v; i++ {
|
|
||||||
if (i % int64(Thearch.Ptrsize)) == 0 {
|
if (i % int64(Thearch.Ptrsize)) == 0 {
|
||||||
proggendata(g, obj.BitsScalar)
|
proggendata(g, obj.BitsScalar)
|
||||||
}
|
}
|
||||||
|
|
@ -1101,11 +1050,6 @@ func proggenfini(g *ProgGen, size int64) {
|
||||||
|
|
||||||
// This function generates GC pointer info for global variables.
|
// This function generates GC pointer info for global variables.
|
||||||
func proggenaddsym(g *ProgGen, s *LSym) {
|
func proggenaddsym(g *ProgGen, s *LSym) {
|
||||||
var gcprog *LSym
|
|
||||||
var mask []byte
|
|
||||||
var i int64
|
|
||||||
var size int64
|
|
||||||
|
|
||||||
if s.Size == 0 {
|
if s.Size == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -1128,10 +1072,10 @@ func proggenaddsym(g *ProgGen, s *LSym) {
|
||||||
if (s.Size%int64(Thearch.Ptrsize) != 0) || (g.pos%int64(Thearch.Ptrsize) != 0) {
|
if (s.Size%int64(Thearch.Ptrsize) != 0) || (g.pos%int64(Thearch.Ptrsize) != 0) {
|
||||||
Diag("proggenaddsym: unaligned conservative symbol %s: size=%d pos=%d", s.Name, s.Size, g.pos)
|
Diag("proggenaddsym: unaligned conservative symbol %s: size=%d pos=%d", s.Name, s.Size, g.pos)
|
||||||
}
|
}
|
||||||
size = (s.Size + int64(Thearch.Ptrsize) - 1) / int64(Thearch.Ptrsize) * int64(Thearch.Ptrsize)
|
size := (s.Size + int64(Thearch.Ptrsize) - 1) / int64(Thearch.Ptrsize) * int64(Thearch.Ptrsize)
|
||||||
if size < int64(32*Thearch.Ptrsize) {
|
if size < int64(32*Thearch.Ptrsize) {
|
||||||
// Emit small symbols as data.
|
// Emit small symbols as data.
|
||||||
for i = 0; i < size/int64(Thearch.Ptrsize); i++ {
|
for i := int64(0); i < size/int64(Thearch.Ptrsize); i++ {
|
||||||
proggendata(g, obj.BitsPointer)
|
proggendata(g, obj.BitsPointer)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1148,7 +1092,7 @@ func proggenaddsym(g *ProgGen, s *LSym) {
|
||||||
if s.Size < int64(32*Thearch.Ptrsize) {
|
if s.Size < int64(32*Thearch.Ptrsize) {
|
||||||
// Emit small symbols as data.
|
// Emit small symbols as data.
|
||||||
// This case also handles unaligned and tiny symbols, so tread carefully.
|
// This case also handles unaligned and tiny symbols, so tread carefully.
|
||||||
for i = s.Value; i < s.Value+s.Size; i++ {
|
for i := s.Value; i < s.Value+s.Size; i++ {
|
||||||
if (i % int64(Thearch.Ptrsize)) == 0 {
|
if (i % int64(Thearch.Ptrsize)) == 0 {
|
||||||
proggendata(g, obj.BitsScalar)
|
proggendata(g, obj.BitsScalar)
|
||||||
}
|
}
|
||||||
|
|
@ -1168,24 +1112,24 @@ func proggenaddsym(g *ProgGen, s *LSym) {
|
||||||
// gc program, copy directly
|
// gc program, copy directly
|
||||||
proggendataflush(g)
|
proggendataflush(g)
|
||||||
|
|
||||||
gcprog = decodetype_gcprog(s.Gotype)
|
gcprog := decodetype_gcprog(s.Gotype)
|
||||||
size = decodetype_size(s.Gotype)
|
size := decodetype_size(s.Gotype)
|
||||||
if (size%int64(Thearch.Ptrsize) != 0) || (g.pos%int64(Thearch.Ptrsize) != 0) {
|
if (size%int64(Thearch.Ptrsize) != 0) || (g.pos%int64(Thearch.Ptrsize) != 0) {
|
||||||
Diag("proggenaddsym: unaligned gcprog symbol %s: size=%d pos=%d", s.Name, s.Size, g.pos)
|
Diag("proggenaddsym: unaligned gcprog symbol %s: size=%d pos=%d", s.Name, s.Size, g.pos)
|
||||||
}
|
}
|
||||||
for i = 0; i < int64(len(gcprog.P)-1); i++ {
|
for i := int64(0); i < int64(len(gcprog.P)-1); i++ {
|
||||||
proggenemit(g, uint8(gcprog.P[i]))
|
proggenemit(g, uint8(gcprog.P[i]))
|
||||||
}
|
}
|
||||||
g.pos = s.Value + size
|
g.pos = s.Value + size
|
||||||
} else {
|
} else {
|
||||||
// gc mask, it's small so emit as data
|
// gc mask, it's small so emit as data
|
||||||
mask = decodetype_gcmask(s.Gotype)
|
mask := decodetype_gcmask(s.Gotype)
|
||||||
|
|
||||||
size = decodetype_size(s.Gotype)
|
size := decodetype_size(s.Gotype)
|
||||||
if (size%int64(Thearch.Ptrsize) != 0) || (g.pos%int64(Thearch.Ptrsize) != 0) {
|
if (size%int64(Thearch.Ptrsize) != 0) || (g.pos%int64(Thearch.Ptrsize) != 0) {
|
||||||
Diag("proggenaddsym: unaligned gcmask symbol %s: size=%d pos=%d", s.Name, s.Size, g.pos)
|
Diag("proggenaddsym: unaligned gcmask symbol %s: size=%d pos=%d", s.Name, s.Size, g.pos)
|
||||||
}
|
}
|
||||||
for i = 0; i < size; i += int64(Thearch.Ptrsize) {
|
for i := int64(0); i < size; i += int64(Thearch.Ptrsize) {
|
||||||
proggendata(g, uint8((mask[i/int64(Thearch.Ptrsize)/2]>>uint64((i/int64(Thearch.Ptrsize)%2)*4+2))&obj.BitsMask))
|
proggendata(g, uint8((mask[i/int64(Thearch.Ptrsize)/2]>>uint64((i/int64(Thearch.Ptrsize)%2)*4+2))&obj.BitsMask))
|
||||||
}
|
}
|
||||||
g.pos = s.Value + size
|
g.pos = s.Value + size
|
||||||
|
|
@ -1193,9 +1137,7 @@ func proggenaddsym(g *ProgGen, s *LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func growdatsize(datsizep *int64, s *LSym) {
|
func growdatsize(datsizep *int64, s *LSym) {
|
||||||
var datsize int64
|
datsize := *datsizep
|
||||||
|
|
||||||
datsize = *datsizep
|
|
||||||
if s.Size < 0 {
|
if s.Size < 0 {
|
||||||
Diag("negative size (datsize = %d, s->size = %d)", datsize, s.Size)
|
Diag("negative size (datsize = %d, s->size = %d)", datsize, s.Size)
|
||||||
}
|
}
|
||||||
|
|
@ -1206,27 +1148,15 @@ func growdatsize(datsizep *int64, s *LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func dodata() {
|
func dodata() {
|
||||||
var n int32
|
|
||||||
var datsize int64
|
|
||||||
var sect *Section
|
|
||||||
var segro *Segment
|
|
||||||
var s *LSym
|
|
||||||
var last *LSym
|
|
||||||
var l **LSym
|
|
||||||
var toc *LSym
|
|
||||||
var gcdata *LSym
|
|
||||||
var gcbss *LSym
|
|
||||||
var gen ProgGen
|
|
||||||
|
|
||||||
if Debug['v'] != 0 {
|
if Debug['v'] != 0 {
|
||||||
fmt.Fprintf(&Bso, "%5.2f dodata\n", obj.Cputime())
|
fmt.Fprintf(&Bso, "%5.2f dodata\n", obj.Cputime())
|
||||||
}
|
}
|
||||||
Bflush(&Bso)
|
Bflush(&Bso)
|
||||||
|
|
||||||
last = nil
|
last := (*LSym)(nil)
|
||||||
datap = nil
|
datap = nil
|
||||||
|
|
||||||
for s = Ctxt.Allsym; s != nil; s = s.Allsym {
|
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
||||||
if !s.Reachable || s.Special != 0 {
|
if !s.Reachable || s.Special != 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -1245,7 +1175,7 @@ func dodata() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for s = datap; s != nil; s = s.Next {
|
for s := datap; s != nil; s = s.Next {
|
||||||
if int64(len(s.P)) > s.Size {
|
if int64(len(s.P)) > s.Size {
|
||||||
Diag("%s: initialize bounds (%d < %d)", s.Name, int64(s.Size), len(s.P))
|
Diag("%s: initialize bounds (%d < %d)", s.Name, int64(s.Size), len(s.P))
|
||||||
}
|
}
|
||||||
|
|
@ -1265,6 +1195,8 @@ func dodata() {
|
||||||
dynreloc()
|
dynreloc()
|
||||||
|
|
||||||
/* some symbols may no longer belong in datap (Mach-O) */
|
/* some symbols may no longer belong in datap (Mach-O) */
|
||||||
|
var l **LSym
|
||||||
|
var s *LSym
|
||||||
for l = &datap; ; {
|
for l = &datap; ; {
|
||||||
s = *l
|
s = *l
|
||||||
if s == nil {
|
if s == nil {
|
||||||
|
|
@ -1299,8 +1231,9 @@ func dodata() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* writable ELF sections */
|
/* writable ELF sections */
|
||||||
datsize = 0
|
datsize := int64(0)
|
||||||
|
|
||||||
|
var sect *Section
|
||||||
for ; s != nil && s.Type < SELFGOT; s = s.Next {
|
for ; s != nil && s.Type < SELFGOT; s = s.Next {
|
||||||
sect = addsection(&Segdata, s.Name, 06)
|
sect = addsection(&Segdata, s.Name, 06)
|
||||||
sect.Align = symalign(s)
|
sect.Align = symalign(s)
|
||||||
|
|
@ -1315,10 +1248,11 @@ func dodata() {
|
||||||
|
|
||||||
/* .got (and .toc on ppc64) */
|
/* .got (and .toc on ppc64) */
|
||||||
if s.Type == SELFGOT {
|
if s.Type == SELFGOT {
|
||||||
sect = addsection(&Segdata, ".got", 06)
|
sect := addsection(&Segdata, ".got", 06)
|
||||||
sect.Align = maxalign(s, SELFGOT)
|
sect.Align = maxalign(s, SELFGOT)
|
||||||
datsize = Rnd(datsize, int64(sect.Align))
|
datsize = Rnd(datsize, int64(sect.Align))
|
||||||
sect.Vaddr = uint64(datsize)
|
sect.Vaddr = uint64(datsize)
|
||||||
|
var toc *LSym
|
||||||
for ; s != nil && s.Type == SELFGOT; s = s.Next {
|
for ; s != nil && s.Type == SELFGOT; s = s.Next {
|
||||||
datsize = aligndatsize(datsize, s)
|
datsize = aligndatsize(datsize, s)
|
||||||
s.Sect = sect
|
s.Sect = sect
|
||||||
|
|
@ -1363,7 +1297,7 @@ func dodata() {
|
||||||
|
|
||||||
/* shared library initializer */
|
/* shared library initializer */
|
||||||
if Flag_shared != 0 {
|
if Flag_shared != 0 {
|
||||||
sect = addsection(&Segdata, ".init_array", 06)
|
sect := addsection(&Segdata, ".init_array", 06)
|
||||||
sect.Align = maxalign(s, SINITARR)
|
sect.Align = maxalign(s, SINITARR)
|
||||||
datsize = Rnd(datsize, int64(sect.Align))
|
datsize = Rnd(datsize, int64(sect.Align))
|
||||||
sect.Vaddr = uint64(datsize)
|
sect.Vaddr = uint64(datsize)
|
||||||
|
|
@ -1385,7 +1319,8 @@ func dodata() {
|
||||||
sect.Vaddr = uint64(datsize)
|
sect.Vaddr = uint64(datsize)
|
||||||
Linklookup(Ctxt, "runtime.data", 0).Sect = sect
|
Linklookup(Ctxt, "runtime.data", 0).Sect = sect
|
||||||
Linklookup(Ctxt, "runtime.edata", 0).Sect = sect
|
Linklookup(Ctxt, "runtime.edata", 0).Sect = sect
|
||||||
gcdata = Linklookup(Ctxt, "runtime.gcdata", 0)
|
gcdata := Linklookup(Ctxt, "runtime.gcdata", 0)
|
||||||
|
var gen ProgGen
|
||||||
proggeninit(&gen, gcdata)
|
proggeninit(&gen, gcdata)
|
||||||
for ; s != nil && s.Type < SBSS; s = s.Next {
|
for ; s != nil && s.Type < SBSS; s = s.Next {
|
||||||
if s.Type == SINITARR {
|
if s.Type == SINITARR {
|
||||||
|
|
@ -1412,7 +1347,7 @@ func dodata() {
|
||||||
sect.Vaddr = uint64(datsize)
|
sect.Vaddr = uint64(datsize)
|
||||||
Linklookup(Ctxt, "runtime.bss", 0).Sect = sect
|
Linklookup(Ctxt, "runtime.bss", 0).Sect = sect
|
||||||
Linklookup(Ctxt, "runtime.ebss", 0).Sect = sect
|
Linklookup(Ctxt, "runtime.ebss", 0).Sect = sect
|
||||||
gcbss = Linklookup(Ctxt, "runtime.gcbss", 0)
|
gcbss := Linklookup(Ctxt, "runtime.gcbss", 0)
|
||||||
proggeninit(&gen, gcbss)
|
proggeninit(&gen, gcbss)
|
||||||
for ; s != nil && s.Type < SNOPTRBSS; s = s.Next {
|
for ; s != nil && s.Type < SNOPTRBSS; s = s.Next {
|
||||||
s.Sect = sect
|
s.Sect = sect
|
||||||
|
|
@ -1449,7 +1384,7 @@ func dodata() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if Iself && Linkmode == LinkExternal && s != nil && s.Type == STLSBSS && HEADTYPE != Hopenbsd {
|
if Iself && Linkmode == LinkExternal && s != nil && s.Type == STLSBSS && HEADTYPE != Hopenbsd {
|
||||||
sect = addsection(&Segdata, ".tbss", 06)
|
sect := addsection(&Segdata, ".tbss", 06)
|
||||||
sect.Align = int32(Thearch.Ptrsize)
|
sect.Align = int32(Thearch.Ptrsize)
|
||||||
sect.Vaddr = 0
|
sect.Vaddr = 0
|
||||||
datsize = 0
|
datsize = 0
|
||||||
|
|
@ -1486,6 +1421,7 @@ func dodata() {
|
||||||
* since it's not our decision; that code expects the sections in
|
* since it's not our decision; that code expects the sections in
|
||||||
* segtext.
|
* segtext.
|
||||||
*/
|
*/
|
||||||
|
var segro *Segment
|
||||||
if Iself && Linkmode == LinkInternal {
|
if Iself && Linkmode == LinkInternal {
|
||||||
segro = &Segrodata
|
segro = &Segrodata
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1600,17 +1536,17 @@ func dodata() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* number the sections */
|
/* number the sections */
|
||||||
n = 1
|
n := int32(1)
|
||||||
|
|
||||||
for sect = Segtext.Sect; sect != nil; sect = sect.Next {
|
for sect := Segtext.Sect; sect != nil; sect = sect.Next {
|
||||||
sect.Extnum = int16(n)
|
sect.Extnum = int16(n)
|
||||||
n++
|
n++
|
||||||
}
|
}
|
||||||
for sect = Segrodata.Sect; sect != nil; sect = sect.Next {
|
for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
|
||||||
sect.Extnum = int16(n)
|
sect.Extnum = int16(n)
|
||||||
n++
|
n++
|
||||||
}
|
}
|
||||||
for sect = Segdata.Sect; sect != nil; sect = sect.Next {
|
for sect := Segdata.Sect; sect != nil; sect = sect.Next {
|
||||||
sect.Extnum = int16(n)
|
sect.Extnum = int16(n)
|
||||||
n++
|
n++
|
||||||
}
|
}
|
||||||
|
|
@ -1618,9 +1554,6 @@ func dodata() {
|
||||||
|
|
||||||
// assign addresses to text
|
// assign addresses to text
|
||||||
func textaddress() {
|
func textaddress() {
|
||||||
var va uint64
|
|
||||||
var sect *Section
|
|
||||||
var sym *LSym
|
|
||||||
var sub *LSym
|
var sub *LSym
|
||||||
|
|
||||||
addsection(&Segtext, ".text", 05)
|
addsection(&Segtext, ".text", 05)
|
||||||
|
|
@ -1628,14 +1561,14 @@ func textaddress() {
|
||||||
// Assign PCs in text segment.
|
// Assign PCs in text segment.
|
||||||
// Could parallelize, by assigning to text
|
// Could parallelize, by assigning to text
|
||||||
// and then letting threads copy down, but probably not worth it.
|
// and then letting threads copy down, but probably not worth it.
|
||||||
sect = Segtext.Sect
|
sect := Segtext.Sect
|
||||||
|
|
||||||
sect.Align = int32(Funcalign)
|
sect.Align = int32(Funcalign)
|
||||||
Linklookup(Ctxt, "runtime.text", 0).Sect = sect
|
Linklookup(Ctxt, "runtime.text", 0).Sect = sect
|
||||||
Linklookup(Ctxt, "runtime.etext", 0).Sect = sect
|
Linklookup(Ctxt, "runtime.etext", 0).Sect = sect
|
||||||
va = uint64(INITTEXT)
|
va := uint64(INITTEXT)
|
||||||
sect.Vaddr = va
|
sect.Vaddr = va
|
||||||
for sym = Ctxt.Textp; sym != nil; sym = sym.Next {
|
for sym := Ctxt.Textp; sym != nil; sym = sym.Next {
|
||||||
sym.Sect = sect
|
sym.Sect = sect
|
||||||
if sym.Type&SSUB != 0 {
|
if sym.Type&SSUB != 0 {
|
||||||
continue
|
continue
|
||||||
|
|
@ -1664,26 +1597,11 @@ func textaddress() {
|
||||||
|
|
||||||
// assign addresses
|
// assign addresses
|
||||||
func address() {
|
func address() {
|
||||||
var s *Section
|
va := uint64(INITTEXT)
|
||||||
var text *Section
|
|
||||||
var data *Section
|
|
||||||
var rodata *Section
|
|
||||||
var symtab *Section
|
|
||||||
var pclntab *Section
|
|
||||||
var noptr *Section
|
|
||||||
var bss *Section
|
|
||||||
var noptrbss *Section
|
|
||||||
var typelink *Section
|
|
||||||
var sym *LSym
|
|
||||||
var sub *LSym
|
|
||||||
var va uint64
|
|
||||||
var vlen int64
|
|
||||||
|
|
||||||
va = uint64(INITTEXT)
|
|
||||||
Segtext.Rwx = 05
|
Segtext.Rwx = 05
|
||||||
Segtext.Vaddr = va
|
Segtext.Vaddr = va
|
||||||
Segtext.Fileoff = uint64(HEADR)
|
Segtext.Fileoff = uint64(HEADR)
|
||||||
for s = Segtext.Sect; s != nil; s = s.Next {
|
for s := Segtext.Sect; s != nil; s = s.Next {
|
||||||
va = uint64(Rnd(int64(va), int64(s.Align)))
|
va = uint64(Rnd(int64(va), int64(s.Align)))
|
||||||
s.Vaddr = va
|
s.Vaddr = va
|
||||||
va += s.Length
|
va += s.Length
|
||||||
|
|
@ -1704,7 +1622,7 @@ func address() {
|
||||||
Segrodata.Vaddr = va
|
Segrodata.Vaddr = va
|
||||||
Segrodata.Fileoff = va - Segtext.Vaddr + Segtext.Fileoff
|
Segrodata.Fileoff = va - Segtext.Vaddr + Segtext.Fileoff
|
||||||
Segrodata.Filelen = 0
|
Segrodata.Filelen = 0
|
||||||
for s = Segrodata.Sect; s != nil; s = s.Next {
|
for s := Segrodata.Sect; s != nil; s = s.Next {
|
||||||
va = uint64(Rnd(int64(va), int64(s.Align)))
|
va = uint64(Rnd(int64(va), int64(s.Align)))
|
||||||
s.Vaddr = va
|
s.Vaddr = va
|
||||||
va += s.Length
|
va += s.Length
|
||||||
|
|
@ -1725,11 +1643,12 @@ func address() {
|
||||||
if HEADTYPE == Hplan9 {
|
if HEADTYPE == Hplan9 {
|
||||||
Segdata.Fileoff = Segtext.Fileoff + Segtext.Filelen
|
Segdata.Fileoff = Segtext.Fileoff + Segtext.Filelen
|
||||||
}
|
}
|
||||||
data = nil
|
data := (*Section)(nil)
|
||||||
noptr = nil
|
noptr := (*Section)(nil)
|
||||||
bss = nil
|
bss := (*Section)(nil)
|
||||||
noptrbss = nil
|
noptrbss := (*Section)(nil)
|
||||||
for s = Segdata.Sect; s != nil; s = s.Next {
|
var vlen int64
|
||||||
|
for s := Segdata.Sect; s != nil; s = s.Next {
|
||||||
vlen = int64(s.Length)
|
vlen = int64(s.Length)
|
||||||
if s.Next != nil {
|
if s.Next != nil {
|
||||||
vlen = int64(s.Next.Vaddr - s.Vaddr)
|
vlen = int64(s.Next.Vaddr - s.Vaddr)
|
||||||
|
|
@ -1753,17 +1672,19 @@ func address() {
|
||||||
|
|
||||||
Segdata.Filelen = bss.Vaddr - Segdata.Vaddr
|
Segdata.Filelen = bss.Vaddr - Segdata.Vaddr
|
||||||
|
|
||||||
text = Segtext.Sect
|
text := Segtext.Sect
|
||||||
|
var rodata *Section
|
||||||
if Segrodata.Sect != nil {
|
if Segrodata.Sect != nil {
|
||||||
rodata = Segrodata.Sect
|
rodata = Segrodata.Sect
|
||||||
} else {
|
} else {
|
||||||
rodata = text.Next
|
rodata = text.Next
|
||||||
}
|
}
|
||||||
typelink = rodata.Next
|
typelink := rodata.Next
|
||||||
symtab = typelink.Next
|
symtab := typelink.Next
|
||||||
pclntab = symtab.Next
|
pclntab := symtab.Next
|
||||||
|
|
||||||
for sym = datap; sym != nil; sym = sym.Next {
|
var sub *LSym
|
||||||
|
for sym := datap; sym != nil; sym = sym.Next {
|
||||||
Ctxt.Cursym = sym
|
Ctxt.Cursym = sym
|
||||||
if sym.Sect != nil {
|
if sym.Sect != nil {
|
||||||
sym.Value += int64((sym.Sect.(*Section)).Vaddr)
|
sym.Value += int64((sym.Sect.(*Section)).Vaddr)
|
||||||
|
|
@ -1780,7 +1701,7 @@ func address() {
|
||||||
xdefine("runtime.typelink", SRODATA, int64(typelink.Vaddr))
|
xdefine("runtime.typelink", SRODATA, int64(typelink.Vaddr))
|
||||||
xdefine("runtime.etypelink", SRODATA, int64(typelink.Vaddr+typelink.Length))
|
xdefine("runtime.etypelink", SRODATA, int64(typelink.Vaddr+typelink.Length))
|
||||||
|
|
||||||
sym = Linklookup(Ctxt, "runtime.gcdata", 0)
|
sym := Linklookup(Ctxt, "runtime.gcdata", 0)
|
||||||
xdefine("runtime.egcdata", SRODATA, Symaddr(sym)+sym.Size)
|
xdefine("runtime.egcdata", SRODATA, Symaddr(sym)+sym.Size)
|
||||||
Linklookup(Ctxt, "runtime.egcdata", 0).Sect = sym.Sect
|
Linklookup(Ctxt, "runtime.egcdata", 0).Sect = sym.Sect
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,7 @@ import "cmd/internal/obj"
|
||||||
// ../gc/reflect.c stuffs in these.
|
// ../gc/reflect.c stuffs in these.
|
||||||
|
|
||||||
func decode_reloc(s *LSym, off int32) *Reloc {
|
func decode_reloc(s *LSym, off int32) *Reloc {
|
||||||
var i int
|
for i := 0; i < len(s.R); i++ {
|
||||||
|
|
||||||
for i = 0; i < len(s.R); i++ {
|
|
||||||
if s.R[i].Off == off {
|
if s.R[i].Off == off {
|
||||||
return &s.R[i:][0]
|
return &s.R[i:][0]
|
||||||
}
|
}
|
||||||
|
|
@ -22,9 +20,7 @@ func decode_reloc(s *LSym, off int32) *Reloc {
|
||||||
}
|
}
|
||||||
|
|
||||||
func decode_reloc_sym(s *LSym, off int32) *LSym {
|
func decode_reloc_sym(s *LSym, off int32) *LSym {
|
||||||
var r *Reloc
|
r := decode_reloc(s, off)
|
||||||
|
|
||||||
r = decode_reloc(s, off)
|
|
||||||
if r == nil {
|
if r == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -75,9 +71,7 @@ func decodetype_gcprog(s *LSym) *LSym {
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodetype_gcmask(s *LSym) []byte {
|
func decodetype_gcmask(s *LSym) []byte {
|
||||||
var mask *LSym
|
mask := decode_reloc_sym(s, 1*int32(Thearch.Ptrsize)+8+1*int32(Thearch.Ptrsize))
|
||||||
|
|
||||||
mask = decode_reloc_sym(s, 1*int32(Thearch.Ptrsize)+8+1*int32(Thearch.Ptrsize))
|
|
||||||
return mask.P
|
return mask.P
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,9 +118,7 @@ func decodetype_funcoutcount(s *LSym) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodetype_funcintype(s *LSym, i int) *LSym {
|
func decodetype_funcintype(s *LSym, i int) *LSym {
|
||||||
var r *Reloc
|
r := decode_reloc(s, int32(commonsize())+int32(Thearch.Ptrsize))
|
||||||
|
|
||||||
r = decode_reloc(s, int32(commonsize())+int32(Thearch.Ptrsize))
|
|
||||||
if r == nil {
|
if r == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -134,9 +126,7 @@ func decodetype_funcintype(s *LSym, i int) *LSym {
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodetype_funcouttype(s *LSym, i int) *LSym {
|
func decodetype_funcouttype(s *LSym, i int) *LSym {
|
||||||
var r *Reloc
|
r := decode_reloc(s, int32(commonsize())+2*int32(Thearch.Ptrsize)+2*int32(Thearch.Intsize))
|
||||||
|
|
||||||
r = decode_reloc(s, int32(commonsize())+2*int32(Thearch.Ptrsize)+2*int32(Thearch.Intsize))
|
|
||||||
if r == nil {
|
if r == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -154,16 +144,14 @@ func structfieldsize() int {
|
||||||
|
|
||||||
// Type.StructType.fields[]-> name, typ and offset.
|
// Type.StructType.fields[]-> name, typ and offset.
|
||||||
func decodetype_structfieldname(s *LSym, i int) string {
|
func decodetype_structfieldname(s *LSym, i int) string {
|
||||||
var r *Reloc
|
|
||||||
|
|
||||||
// go.string."foo" 0x28 / 0x40
|
// go.string."foo" 0x28 / 0x40
|
||||||
s = decode_reloc_sym(s, int32(commonsize())+int32(Thearch.Ptrsize)+2*int32(Thearch.Intsize)+int32(i)*int32(structfieldsize()))
|
s = decode_reloc_sym(s, int32(commonsize())+int32(Thearch.Ptrsize)+2*int32(Thearch.Intsize)+int32(i)*int32(structfieldsize()))
|
||||||
|
|
||||||
if s == nil { // embedded structs have a nil name.
|
if s == nil { // embedded structs have a nil name.
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
r = decode_reloc(s, 0) // s has a pointer to the string data at offset 0
|
r := decode_reloc(s, 0) // s has a pointer to the string data at offset 0
|
||||||
if r == nil { // shouldn't happen.
|
if r == nil { // shouldn't happen.
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return cstring(r.Sym.P[r.Add:])
|
return cstring(r.Sym.P[r.Add:])
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -804,13 +804,11 @@ func elf64phdr(e *ElfPhdr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func elf32phdr(e *ElfPhdr) {
|
func elf32phdr(e *ElfPhdr) {
|
||||||
var frag int
|
|
||||||
|
|
||||||
if e.type_ == PT_LOAD {
|
if e.type_ == PT_LOAD {
|
||||||
// Correct ELF loaders will do this implicitly,
|
// Correct ELF loaders will do this implicitly,
|
||||||
// but buggy ELF loaders like the one in some
|
// but buggy ELF loaders like the one in some
|
||||||
// versions of QEMU won't.
|
// versions of QEMU won't.
|
||||||
frag = int(e.vaddr & (e.align - 1))
|
frag := int(e.vaddr & (e.align - 1))
|
||||||
|
|
||||||
e.off -= uint64(frag)
|
e.off -= uint64(frag)
|
||||||
e.vaddr -= uint64(frag)
|
e.vaddr -= uint64(frag)
|
||||||
|
|
@ -856,16 +854,14 @@ func elf32shdr(e *ElfShdr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfwriteshdrs() uint32 {
|
func elfwriteshdrs() uint32 {
|
||||||
var i int
|
|
||||||
|
|
||||||
if elf64 != 0 {
|
if elf64 != 0 {
|
||||||
for i = 0; i < int(ehdr.shnum); i++ {
|
for i := 0; i < int(ehdr.shnum); i++ {
|
||||||
elf64shdr(shdr[i])
|
elf64shdr(shdr[i])
|
||||||
}
|
}
|
||||||
return uint32(ehdr.shnum) * ELF64SHDRSIZE
|
return uint32(ehdr.shnum) * ELF64SHDRSIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
for i = 0; i < int(ehdr.shnum); i++ {
|
for i := 0; i < int(ehdr.shnum); i++ {
|
||||||
elf32shdr(shdr[i])
|
elf32shdr(shdr[i])
|
||||||
}
|
}
|
||||||
return uint32(ehdr.shnum) * ELF32SHDRSIZE
|
return uint32(ehdr.shnum) * ELF32SHDRSIZE
|
||||||
|
|
@ -883,25 +879,21 @@ func elfsetstring(s string, off int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfwritephdrs() uint32 {
|
func elfwritephdrs() uint32 {
|
||||||
var i int
|
|
||||||
|
|
||||||
if elf64 != 0 {
|
if elf64 != 0 {
|
||||||
for i = 0; i < int(ehdr.phnum); i++ {
|
for i := 0; i < int(ehdr.phnum); i++ {
|
||||||
elf64phdr(phdr[i])
|
elf64phdr(phdr[i])
|
||||||
}
|
}
|
||||||
return uint32(ehdr.phnum) * ELF64PHDRSIZE
|
return uint32(ehdr.phnum) * ELF64PHDRSIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
for i = 0; i < int(ehdr.phnum); i++ {
|
for i := 0; i < int(ehdr.phnum); i++ {
|
||||||
elf32phdr(phdr[i])
|
elf32phdr(phdr[i])
|
||||||
}
|
}
|
||||||
return uint32(ehdr.phnum) * ELF32PHDRSIZE
|
return uint32(ehdr.phnum) * ELF32PHDRSIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
func newElfPhdr() *ElfPhdr {
|
func newElfPhdr() *ElfPhdr {
|
||||||
var e *ElfPhdr
|
e := new(ElfPhdr)
|
||||||
|
|
||||||
e = new(ElfPhdr)
|
|
||||||
if ehdr.phnum >= NSECT {
|
if ehdr.phnum >= NSECT {
|
||||||
Diag("too many phdrs")
|
Diag("too many phdrs")
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -917,9 +909,7 @@ func newElfPhdr() *ElfPhdr {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newElfShdr(name int64) *ElfShdr {
|
func newElfShdr(name int64) *ElfShdr {
|
||||||
var e *ElfShdr
|
e := new(ElfShdr)
|
||||||
|
|
||||||
e = new(ElfShdr)
|
|
||||||
e.name = uint32(name)
|
e.name = uint32(name)
|
||||||
e.shnum = int(ehdr.shnum)
|
e.shnum = int(ehdr.shnum)
|
||||||
if ehdr.shnum >= NSECT {
|
if ehdr.shnum >= NSECT {
|
||||||
|
|
@ -937,9 +927,7 @@ func getElfEhdr() *ElfEhdr {
|
||||||
}
|
}
|
||||||
|
|
||||||
func elf64writehdr() uint32 {
|
func elf64writehdr() uint32 {
|
||||||
var i int
|
for i := 0; i < EI_NIDENT; i++ {
|
||||||
|
|
||||||
for i = 0; i < EI_NIDENT; i++ {
|
|
||||||
Cput(ehdr.ident[i])
|
Cput(ehdr.ident[i])
|
||||||
}
|
}
|
||||||
Thearch.Wput(ehdr.type_)
|
Thearch.Wput(ehdr.type_)
|
||||||
|
|
@ -959,9 +947,7 @@ func elf64writehdr() uint32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func elf32writehdr() uint32 {
|
func elf32writehdr() uint32 {
|
||||||
var i int
|
for i := 0; i < EI_NIDENT; i++ {
|
||||||
|
|
||||||
for i = 0; i < EI_NIDENT; i++ {
|
|
||||||
Cput(ehdr.ident[i])
|
Cput(ehdr.ident[i])
|
||||||
}
|
}
|
||||||
Thearch.Wput(ehdr.type_)
|
Thearch.Wput(ehdr.type_)
|
||||||
|
|
@ -1037,10 +1023,8 @@ func elfwritedynentsymsize(s *LSym, tag int, t *LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfinterp(sh *ElfShdr, startva uint64, resoff uint64, p string) int {
|
func elfinterp(sh *ElfShdr, startva uint64, resoff uint64, p string) int {
|
||||||
var n int
|
|
||||||
|
|
||||||
interp = p
|
interp = p
|
||||||
n = len(interp) + 1
|
n := len(interp) + 1
|
||||||
sh.addr = startva + resoff - uint64(n)
|
sh.addr = startva + resoff - uint64(n)
|
||||||
sh.off = resoff - uint64(n)
|
sh.off = resoff - uint64(n)
|
||||||
sh.size = uint64(n)
|
sh.size = uint64(n)
|
||||||
|
|
@ -1049,9 +1033,7 @@ func elfinterp(sh *ElfShdr, startva uint64, resoff uint64, p string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfwriteinterp() int {
|
func elfwriteinterp() int {
|
||||||
var sh *ElfShdr
|
sh := elfshname(".interp")
|
||||||
|
|
||||||
sh = elfshname(".interp")
|
|
||||||
Cseek(int64(sh.off))
|
Cseek(int64(sh.off))
|
||||||
coutbuf.w.WriteString(interp)
|
coutbuf.w.WriteString(interp)
|
||||||
Cput(0)
|
Cput(0)
|
||||||
|
|
@ -1059,9 +1041,7 @@ func elfwriteinterp() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sz int) int {
|
func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sz int) int {
|
||||||
var n uint64
|
n := 3*4 + uint64(sz) + resoff%4
|
||||||
|
|
||||||
n = 3*4 + uint64(sz) + resoff%4
|
|
||||||
|
|
||||||
sh.type_ = SHT_NOTE
|
sh.type_ = SHT_NOTE
|
||||||
sh.flags = SHF_ALLOC
|
sh.flags = SHF_ALLOC
|
||||||
|
|
@ -1074,9 +1054,7 @@ func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sz int) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfwritenotehdr(str string, namesz uint32, descsz uint32, tag uint32) *ElfShdr {
|
func elfwritenotehdr(str string, namesz uint32, descsz uint32, tag uint32) *ElfShdr {
|
||||||
var sh *ElfShdr
|
sh := elfshname(str)
|
||||||
|
|
||||||
sh = elfshname(str)
|
|
||||||
|
|
||||||
// Write Elf_Note header.
|
// Write Elf_Note header.
|
||||||
Cseek(int64(sh.off))
|
Cseek(int64(sh.off))
|
||||||
|
|
@ -1099,17 +1077,13 @@ const (
|
||||||
var ELF_NOTE_NETBSD_NAME = []byte("NetBSD\x00")
|
var ELF_NOTE_NETBSD_NAME = []byte("NetBSD\x00")
|
||||||
|
|
||||||
func elfnetbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
|
func elfnetbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
|
||||||
var n int
|
n := int(Rnd(ELF_NOTE_NETBSD_NAMESZ, 4) + Rnd(ELF_NOTE_NETBSD_DESCSZ, 4))
|
||||||
|
|
||||||
n = int(Rnd(ELF_NOTE_NETBSD_NAMESZ, 4) + Rnd(ELF_NOTE_NETBSD_DESCSZ, 4))
|
|
||||||
return elfnote(sh, startva, resoff, n)
|
return elfnote(sh, startva, resoff, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfwritenetbsdsig() int {
|
func elfwritenetbsdsig() int {
|
||||||
var sh *ElfShdr
|
|
||||||
|
|
||||||
// Write Elf_Note header.
|
// Write Elf_Note header.
|
||||||
sh = elfwritenotehdr(".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG)
|
sh := elfwritenotehdr(".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG)
|
||||||
|
|
||||||
if sh == nil {
|
if sh == nil {
|
||||||
return 0
|
return 0
|
||||||
|
|
@ -1135,17 +1109,13 @@ const (
|
||||||
var ELF_NOTE_OPENBSD_NAME = []byte("OpenBSD\x00")
|
var ELF_NOTE_OPENBSD_NAME = []byte("OpenBSD\x00")
|
||||||
|
|
||||||
func elfopenbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
|
func elfopenbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
|
||||||
var n int
|
n := ELF_NOTE_OPENBSD_NAMESZ + ELF_NOTE_OPENBSD_DESCSZ
|
||||||
|
|
||||||
n = ELF_NOTE_OPENBSD_NAMESZ + ELF_NOTE_OPENBSD_DESCSZ
|
|
||||||
return elfnote(sh, startva, resoff, n)
|
return elfnote(sh, startva, resoff, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfwriteopenbsdsig() int {
|
func elfwriteopenbsdsig() int {
|
||||||
var sh *ElfShdr
|
|
||||||
|
|
||||||
// Write Elf_Note header.
|
// Write Elf_Note header.
|
||||||
sh = elfwritenotehdr(".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG)
|
sh := elfwritenotehdr(".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG)
|
||||||
|
|
||||||
if sh == nil {
|
if sh == nil {
|
||||||
return 0
|
return 0
|
||||||
|
|
@ -1160,9 +1130,6 @@ func elfwriteopenbsdsig() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func addbuildinfo(val string) {
|
func addbuildinfo(val string) {
|
||||||
var ov string
|
|
||||||
var i int
|
|
||||||
var b int
|
|
||||||
var j int
|
var j int
|
||||||
|
|
||||||
if val[0] != '0' || val[1] != 'x' {
|
if val[0] != '0' || val[1] != 'x' {
|
||||||
|
|
@ -1170,9 +1137,10 @@ func addbuildinfo(val string) {
|
||||||
Exit(2)
|
Exit(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
ov = val
|
ov := val
|
||||||
val = val[2:]
|
val = val[2:]
|
||||||
i = 0
|
i := 0
|
||||||
|
var b int
|
||||||
for val != "" {
|
for val != "" {
|
||||||
if len(val) == 1 {
|
if len(val) == 1 {
|
||||||
fmt.Fprintf(os.Stderr, "%s: -B argument must have even number of digits: %s\n", os.Args[0], ov)
|
fmt.Fprintf(os.Stderr, "%s: -B argument must have even number of digits: %s\n", os.Args[0], ov)
|
||||||
|
|
@ -1216,16 +1184,12 @@ const (
|
||||||
var ELF_NOTE_BUILDINFO_NAME = []byte("GNU\x00")
|
var ELF_NOTE_BUILDINFO_NAME = []byte("GNU\x00")
|
||||||
|
|
||||||
func elfbuildinfo(sh *ElfShdr, startva uint64, resoff uint64) int {
|
func elfbuildinfo(sh *ElfShdr, startva uint64, resoff uint64) int {
|
||||||
var n int
|
n := int(ELF_NOTE_BUILDINFO_NAMESZ + Rnd(int64(len(buildinfo)), 4))
|
||||||
|
|
||||||
n = int(ELF_NOTE_BUILDINFO_NAMESZ + Rnd(int64(len(buildinfo)), 4))
|
|
||||||
return elfnote(sh, startva, resoff, n)
|
return elfnote(sh, startva, resoff, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfwritebuildinfo() int {
|
func elfwritebuildinfo() int {
|
||||||
var sh *ElfShdr
|
sh := elfwritenotehdr(".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, uint32(len(buildinfo)), ELF_NOTE_BUILDINFO_TAG)
|
||||||
|
|
||||||
sh = elfwritenotehdr(".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, uint32(len(buildinfo)), ELF_NOTE_BUILDINFO_TAG)
|
|
||||||
if sh == nil {
|
if sh == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
@ -1254,7 +1218,6 @@ type Elflib struct {
|
||||||
|
|
||||||
func addelflib(list **Elflib, file string, vers string) *Elfaux {
|
func addelflib(list **Elflib, file string, vers string) *Elfaux {
|
||||||
var lib *Elflib
|
var lib *Elflib
|
||||||
var aux *Elfaux
|
|
||||||
|
|
||||||
for lib = *list; lib != nil; lib = lib.next {
|
for lib = *list; lib != nil; lib = lib.next {
|
||||||
if lib.file == file {
|
if lib.file == file {
|
||||||
|
|
@ -1267,75 +1230,59 @@ func addelflib(list **Elflib, file string, vers string) *Elfaux {
|
||||||
*list = lib
|
*list = lib
|
||||||
|
|
||||||
havelib:
|
havelib:
|
||||||
for aux = lib.aux; aux != nil; aux = aux.next {
|
for aux := lib.aux; aux != nil; aux = aux.next {
|
||||||
if aux.vers == vers {
|
if aux.vers == vers {
|
||||||
goto haveaux
|
return aux
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
aux = new(Elfaux)
|
aux := new(Elfaux)
|
||||||
aux.next = lib.aux
|
aux.next = lib.aux
|
||||||
aux.vers = vers
|
aux.vers = vers
|
||||||
lib.aux = aux
|
lib.aux = aux
|
||||||
|
|
||||||
haveaux:
|
|
||||||
return aux
|
return aux
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfdynhash() {
|
func elfdynhash() {
|
||||||
var s *LSym
|
|
||||||
var sy *LSym
|
|
||||||
var dynstr *LSym
|
|
||||||
var i int
|
|
||||||
var j int
|
|
||||||
var nbucket int
|
|
||||||
var b int
|
|
||||||
var nfile int
|
|
||||||
var hc uint32
|
|
||||||
var chain []uint32
|
|
||||||
var buckets []uint32
|
|
||||||
var nsym int
|
|
||||||
var name string
|
|
||||||
var need []*Elfaux
|
|
||||||
var needlib *Elflib
|
|
||||||
var l *Elflib
|
|
||||||
var x *Elfaux
|
|
||||||
|
|
||||||
if !Iself {
|
if !Iself {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
nsym = Nelfsym
|
nsym := Nelfsym
|
||||||
s = Linklookup(Ctxt, ".hash", 0)
|
s := Linklookup(Ctxt, ".hash", 0)
|
||||||
s.Type = SELFROSECT
|
s.Type = SELFROSECT
|
||||||
s.Reachable = true
|
s.Reachable = true
|
||||||
|
|
||||||
i = nsym
|
i := nsym
|
||||||
nbucket = 1
|
nbucket := 1
|
||||||
for i > 0 {
|
for i > 0 {
|
||||||
nbucket++
|
nbucket++
|
||||||
i >>= 1
|
i >>= 1
|
||||||
}
|
}
|
||||||
|
|
||||||
needlib = nil
|
needlib := (*Elflib)(nil)
|
||||||
need = make([]*Elfaux, nsym)
|
need := make([]*Elfaux, nsym)
|
||||||
chain = make([]uint32, nsym)
|
chain := make([]uint32, nsym)
|
||||||
buckets = make([]uint32, nbucket)
|
buckets := make([]uint32, nbucket)
|
||||||
if need == nil || chain == nil || buckets == nil {
|
if need == nil || chain == nil || buckets == nil {
|
||||||
Ctxt.Cursym = nil
|
Ctxt.Cursym = nil
|
||||||
Diag("out of memory")
|
Diag("out of memory")
|
||||||
Errorexit()
|
Errorexit()
|
||||||
}
|
}
|
||||||
|
|
||||||
for i = 0; i < nsym; i++ {
|
for i := 0; i < nsym; i++ {
|
||||||
need[i] = nil
|
need[i] = nil
|
||||||
}
|
}
|
||||||
for i = 0; i < nsym; i++ {
|
for i := 0; i < nsym; i++ {
|
||||||
chain[i] = 0
|
chain[i] = 0
|
||||||
}
|
}
|
||||||
for i = 0; i < nbucket; i++ {
|
for i := 0; i < nbucket; i++ {
|
||||||
buckets[i] = 0
|
buckets[i] = 0
|
||||||
}
|
}
|
||||||
for sy = Ctxt.Allsym; sy != nil; sy = sy.Allsym {
|
var b int
|
||||||
|
var hc uint32
|
||||||
|
var name string
|
||||||
|
for sy := Ctxt.Allsym; sy != nil; sy = sy.Allsym {
|
||||||
if sy.Dynid <= 0 {
|
if sy.Dynid <= 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -1354,20 +1301,22 @@ func elfdynhash() {
|
||||||
|
|
||||||
Adduint32(Ctxt, s, uint32(nbucket))
|
Adduint32(Ctxt, s, uint32(nbucket))
|
||||||
Adduint32(Ctxt, s, uint32(nsym))
|
Adduint32(Ctxt, s, uint32(nsym))
|
||||||
for i = 0; i < nbucket; i++ {
|
for i := 0; i < nbucket; i++ {
|
||||||
Adduint32(Ctxt, s, buckets[i])
|
Adduint32(Ctxt, s, buckets[i])
|
||||||
}
|
}
|
||||||
for i = 0; i < nsym; i++ {
|
for i := 0; i < nsym; i++ {
|
||||||
Adduint32(Ctxt, s, chain[i])
|
Adduint32(Ctxt, s, chain[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
// version symbols
|
// version symbols
|
||||||
dynstr = Linklookup(Ctxt, ".dynstr", 0)
|
dynstr := Linklookup(Ctxt, ".dynstr", 0)
|
||||||
|
|
||||||
s = Linklookup(Ctxt, ".gnu.version_r", 0)
|
s = Linklookup(Ctxt, ".gnu.version_r", 0)
|
||||||
i = 2
|
i = 2
|
||||||
nfile = 0
|
nfile := 0
|
||||||
for l = needlib; l != nil; l = l.next {
|
var j int
|
||||||
|
var x *Elfaux
|
||||||
|
for l := needlib; l != nil; l = l.next {
|
||||||
nfile++
|
nfile++
|
||||||
|
|
||||||
// header
|
// header
|
||||||
|
|
@ -1405,7 +1354,7 @@ func elfdynhash() {
|
||||||
// version references
|
// version references
|
||||||
s = Linklookup(Ctxt, ".gnu.version", 0)
|
s = Linklookup(Ctxt, ".gnu.version", 0)
|
||||||
|
|
||||||
for i = 0; i < nsym; i++ {
|
for i := 0; i < nsym; i++ {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
Adduint16(Ctxt, s, 0) // first entry - no symbol
|
Adduint16(Ctxt, s, 0) // first entry - no symbol
|
||||||
} else if need[i] == nil {
|
} else if need[i] == nil {
|
||||||
|
|
@ -1424,14 +1373,14 @@ func elfdynhash() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if Thearch.Thechar == '6' || Thearch.Thechar == '9' {
|
if Thearch.Thechar == '6' || Thearch.Thechar == '9' {
|
||||||
sy = Linklookup(Ctxt, ".rela.plt", 0)
|
sy := Linklookup(Ctxt, ".rela.plt", 0)
|
||||||
if sy.Size > 0 {
|
if sy.Size > 0 {
|
||||||
Elfwritedynent(s, DT_PLTREL, DT_RELA)
|
Elfwritedynent(s, DT_PLTREL, DT_RELA)
|
||||||
elfwritedynentsymsize(s, DT_PLTRELSZ, sy)
|
elfwritedynentsymsize(s, DT_PLTRELSZ, sy)
|
||||||
elfwritedynentsym(s, DT_JMPREL, sy)
|
elfwritedynentsym(s, DT_JMPREL, sy)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sy = Linklookup(Ctxt, ".rel.plt", 0)
|
sy := Linklookup(Ctxt, ".rel.plt", 0)
|
||||||
if sy.Size > 0 {
|
if sy.Size > 0 {
|
||||||
Elfwritedynent(s, DT_PLTREL, DT_REL)
|
Elfwritedynent(s, DT_PLTREL, DT_REL)
|
||||||
elfwritedynentsymsize(s, DT_PLTRELSZ, sy)
|
elfwritedynentsymsize(s, DT_PLTRELSZ, sy)
|
||||||
|
|
@ -1443,9 +1392,7 @@ func elfdynhash() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfphload(seg *Segment) *ElfPhdr {
|
func elfphload(seg *Segment) *ElfPhdr {
|
||||||
var ph *ElfPhdr
|
ph := newElfPhdr()
|
||||||
|
|
||||||
ph = newElfPhdr()
|
|
||||||
ph.type_ = PT_LOAD
|
ph.type_ = PT_LOAD
|
||||||
if seg.Rwx&4 != 0 {
|
if seg.Rwx&4 != 0 {
|
||||||
ph.flags |= PF_R
|
ph.flags |= PF_R
|
||||||
|
|
@ -1467,45 +1414,37 @@ func elfphload(seg *Segment) *ElfPhdr {
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfshname(name string) *ElfShdr {
|
func elfshname(name string) *ElfShdr {
|
||||||
var i int
|
|
||||||
var off int
|
var off int
|
||||||
var sh *ElfShdr
|
var sh *ElfShdr
|
||||||
|
|
||||||
for i = 0; i < nelfstr; i++ {
|
for i := 0; i < nelfstr; i++ {
|
||||||
if name == elfstr[i].s {
|
if name == elfstr[i].s {
|
||||||
off = elfstr[i].off
|
off = elfstr[i].off
|
||||||
goto found
|
for i = 0; i < int(ehdr.shnum); i++ {
|
||||||
|
sh = shdr[i]
|
||||||
|
if sh.name == uint32(off) {
|
||||||
|
return sh
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sh = newElfShdr(int64(off))
|
||||||
|
return sh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Diag("cannot find elf name %s", name)
|
Diag("cannot find elf name %s", name)
|
||||||
Errorexit()
|
Errorexit()
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
found:
|
|
||||||
for i = 0; i < int(ehdr.shnum); i++ {
|
|
||||||
sh = shdr[i]
|
|
||||||
if sh.name == uint32(off) {
|
|
||||||
return sh
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sh = newElfShdr(int64(off))
|
|
||||||
return sh
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfshalloc(sect *Section) *ElfShdr {
|
func elfshalloc(sect *Section) *ElfShdr {
|
||||||
var sh *ElfShdr
|
sh := elfshname(sect.Name)
|
||||||
|
|
||||||
sh = elfshname(sect.Name)
|
|
||||||
sect.Elfsect = sh
|
sect.Elfsect = sh
|
||||||
return sh
|
return sh
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfshbits(sect *Section) *ElfShdr {
|
func elfshbits(sect *Section) *ElfShdr {
|
||||||
var sh *ElfShdr
|
sh := elfshalloc(sect)
|
||||||
|
|
||||||
sh = elfshalloc(sect)
|
|
||||||
if sh.type_ > 0 {
|
if sh.type_ > 0 {
|
||||||
return sh
|
return sh
|
||||||
}
|
}
|
||||||
|
|
@ -1540,11 +1479,6 @@ func elfshbits(sect *Section) *ElfShdr {
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfshreloc(sect *Section) *ElfShdr {
|
func elfshreloc(sect *Section) *ElfShdr {
|
||||||
var typ int
|
|
||||||
var sh *ElfShdr
|
|
||||||
var prefix string
|
|
||||||
var buf string
|
|
||||||
|
|
||||||
// If main section is SHT_NOBITS, nothing to relocate.
|
// If main section is SHT_NOBITS, nothing to relocate.
|
||||||
// Also nothing to relocate in .shstrtab.
|
// Also nothing to relocate in .shstrtab.
|
||||||
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
|
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
|
||||||
|
|
@ -1554,6 +1488,8 @@ func elfshreloc(sect *Section) *ElfShdr {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var prefix string
|
||||||
|
var typ int
|
||||||
if Thearch.Thechar == '6' || Thearch.Thechar == '9' {
|
if Thearch.Thechar == '6' || Thearch.Thechar == '9' {
|
||||||
prefix = ".rela"
|
prefix = ".rela"
|
||||||
typ = SHT_RELA
|
typ = SHT_RELA
|
||||||
|
|
@ -1562,8 +1498,8 @@ func elfshreloc(sect *Section) *ElfShdr {
|
||||||
typ = SHT_REL
|
typ = SHT_REL
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = fmt.Sprintf("%s%s", prefix, sect.Name)
|
buf := fmt.Sprintf("%s%s", prefix, sect.Name)
|
||||||
sh = elfshname(buf)
|
sh := elfshname(buf)
|
||||||
sh.type_ = uint32(typ)
|
sh.type_ = uint32(typ)
|
||||||
sh.entsize = uint64(Thearch.Regsize) * 2
|
sh.entsize = uint64(Thearch.Regsize) * 2
|
||||||
if typ == SHT_RELA {
|
if typ == SHT_RELA {
|
||||||
|
|
@ -1578,11 +1514,6 @@ func elfshreloc(sect *Section) *ElfShdr {
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfrelocsect(sect *Section, first *LSym) {
|
func elfrelocsect(sect *Section, first *LSym) {
|
||||||
var ri int
|
|
||||||
var sym *LSym
|
|
||||||
var eaddr int32
|
|
||||||
var r *Reloc
|
|
||||||
|
|
||||||
// If main section is SHT_NOBITS, nothing to relocate.
|
// If main section is SHT_NOBITS, nothing to relocate.
|
||||||
// Also nothing to relocate in .shstrtab.
|
// Also nothing to relocate in .shstrtab.
|
||||||
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
|
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
|
||||||
|
|
@ -1593,6 +1524,7 @@ func elfrelocsect(sect *Section, first *LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sect.Reloff = uint64(Cpos())
|
sect.Reloff = uint64(Cpos())
|
||||||
|
var sym *LSym
|
||||||
for sym = first; sym != nil; sym = sym.Next {
|
for sym = first; sym != nil; sym = sym.Next {
|
||||||
if !sym.Reachable {
|
if !sym.Reachable {
|
||||||
continue
|
continue
|
||||||
|
|
@ -1602,7 +1534,9 @@ func elfrelocsect(sect *Section, first *LSym) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eaddr = int32(sect.Vaddr + sect.Length)
|
eaddr := int32(sect.Vaddr + sect.Length)
|
||||||
|
var r *Reloc
|
||||||
|
var ri int
|
||||||
for ; sym != nil; sym = sym.Next {
|
for ; sym != nil; sym = sym.Next {
|
||||||
if !sym.Reachable {
|
if !sym.Reachable {
|
||||||
continue
|
continue
|
||||||
|
|
@ -1635,35 +1569,29 @@ func elfrelocsect(sect *Section, first *LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Elfemitreloc() {
|
func Elfemitreloc() {
|
||||||
var sect *Section
|
|
||||||
|
|
||||||
for Cpos()&7 != 0 {
|
for Cpos()&7 != 0 {
|
||||||
Cput(0)
|
Cput(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
elfrelocsect(Segtext.Sect, Ctxt.Textp)
|
elfrelocsect(Segtext.Sect, Ctxt.Textp)
|
||||||
for sect = Segtext.Sect.Next; sect != nil; sect = sect.Next {
|
for sect := Segtext.Sect.Next; sect != nil; sect = sect.Next {
|
||||||
elfrelocsect(sect, datap)
|
elfrelocsect(sect, datap)
|
||||||
}
|
}
|
||||||
for sect = Segrodata.Sect; sect != nil; sect = sect.Next {
|
for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
|
||||||
elfrelocsect(sect, datap)
|
elfrelocsect(sect, datap)
|
||||||
}
|
}
|
||||||
for sect = Segdata.Sect; sect != nil; sect = sect.Next {
|
for sect := Segdata.Sect; sect != nil; sect = sect.Next {
|
||||||
elfrelocsect(sect, datap)
|
elfrelocsect(sect, datap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func doelf() {
|
func doelf() {
|
||||||
var s *LSym
|
|
||||||
var shstrtab *LSym
|
|
||||||
var dynstr *LSym
|
|
||||||
|
|
||||||
if !Iself {
|
if !Iself {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
/* predefine strings we need for section headers */
|
/* predefine strings we need for section headers */
|
||||||
shstrtab = Linklookup(Ctxt, ".shstrtab", 0)
|
shstrtab := Linklookup(Ctxt, ".shstrtab", 0)
|
||||||
|
|
||||||
shstrtab.Type = SELFROSECT
|
shstrtab.Type = SELFROSECT
|
||||||
shstrtab.Reachable = true
|
shstrtab.Reachable = true
|
||||||
|
|
@ -1767,7 +1695,7 @@ func doelf() {
|
||||||
Addstring(shstrtab, ".gnu.version_r")
|
Addstring(shstrtab, ".gnu.version_r")
|
||||||
|
|
||||||
/* dynamic symbol table - first entry all zeros */
|
/* dynamic symbol table - first entry all zeros */
|
||||||
s = Linklookup(Ctxt, ".dynsym", 0)
|
s := Linklookup(Ctxt, ".dynsym", 0)
|
||||||
|
|
||||||
s.Type = SELFROSECT
|
s.Type = SELFROSECT
|
||||||
s.Reachable = true
|
s.Reachable = true
|
||||||
|
|
@ -1785,7 +1713,7 @@ func doelf() {
|
||||||
if s.Size == 0 {
|
if s.Size == 0 {
|
||||||
Addstring(s, "")
|
Addstring(s, "")
|
||||||
}
|
}
|
||||||
dynstr = s
|
dynstr := s
|
||||||
|
|
||||||
/* relocation table */
|
/* relocation table */
|
||||||
if Thearch.Thechar == '6' || Thearch.Thechar == '9' {
|
if Thearch.Thechar == '6' || Thearch.Thechar == '9' {
|
||||||
|
|
@ -1804,7 +1732,7 @@ func doelf() {
|
||||||
|
|
||||||
/* ppc64 glink resolver */
|
/* ppc64 glink resolver */
|
||||||
if Thearch.Thechar == '9' {
|
if Thearch.Thechar == '9' {
|
||||||
s = Linklookup(Ctxt, ".glink", 0)
|
s := Linklookup(Ctxt, ".glink", 0)
|
||||||
s.Reachable = true
|
s.Reachable = true
|
||||||
s.Type = SELFRXSECT
|
s.Type = SELFRXSECT
|
||||||
}
|
}
|
||||||
|
|
@ -1901,8 +1829,7 @@ func doelf() {
|
||||||
|
|
||||||
// Do not write DT_NULL. elfdynhash will finish it.
|
// Do not write DT_NULL. elfdynhash will finish it.
|
||||||
func shsym(sh *ElfShdr, s *LSym) {
|
func shsym(sh *ElfShdr, s *LSym) {
|
||||||
var addr int64
|
addr := Symaddr(s)
|
||||||
addr = Symaddr(s)
|
|
||||||
if sh.flags&SHF_ALLOC != 0 {
|
if sh.flags&SHF_ALLOC != 0 {
|
||||||
sh.addr = uint64(addr)
|
sh.addr = uint64(addr)
|
||||||
}
|
}
|
||||||
|
|
@ -1920,35 +1847,22 @@ func phsh(ph *ElfPhdr, sh *ElfShdr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Asmbelfsetup() {
|
func Asmbelfsetup() {
|
||||||
var sect *Section
|
|
||||||
|
|
||||||
/* This null SHdr must appear before all others */
|
/* This null SHdr must appear before all others */
|
||||||
elfshname("")
|
elfshname("")
|
||||||
|
|
||||||
for sect = Segtext.Sect; sect != nil; sect = sect.Next {
|
for sect := Segtext.Sect; sect != nil; sect = sect.Next {
|
||||||
elfshalloc(sect)
|
elfshalloc(sect)
|
||||||
}
|
}
|
||||||
for sect = Segrodata.Sect; sect != nil; sect = sect.Next {
|
for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
|
||||||
elfshalloc(sect)
|
elfshalloc(sect)
|
||||||
}
|
}
|
||||||
for sect = Segdata.Sect; sect != nil; sect = sect.Next {
|
for sect := Segdata.Sect; sect != nil; sect = sect.Next {
|
||||||
elfshalloc(sect)
|
elfshalloc(sect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Asmbelf(symo int64) {
|
func Asmbelf(symo int64) {
|
||||||
var a int64
|
eh := getElfEhdr()
|
||||||
var o int64
|
|
||||||
var startva int64
|
|
||||||
var resoff int64
|
|
||||||
var eh *ElfEhdr
|
|
||||||
var ph *ElfPhdr
|
|
||||||
var pph *ElfPhdr
|
|
||||||
var pnote *ElfPhdr
|
|
||||||
var sh *ElfShdr
|
|
||||||
var sect *Section
|
|
||||||
|
|
||||||
eh = getElfEhdr()
|
|
||||||
switch Thearch.Thechar {
|
switch Thearch.Thechar {
|
||||||
default:
|
default:
|
||||||
Diag("unknown architecture in asmbelf")
|
Diag("unknown architecture in asmbelf")
|
||||||
|
|
@ -1968,10 +1882,11 @@ func Asmbelf(symo int64) {
|
||||||
eh.machine = EM_PPC64
|
eh.machine = EM_PPC64
|
||||||
}
|
}
|
||||||
|
|
||||||
startva = INITTEXT - int64(HEADR)
|
startva := INITTEXT - int64(HEADR)
|
||||||
resoff = ELFRESERVE
|
resoff := int64(ELFRESERVE)
|
||||||
|
|
||||||
pph = nil
|
pph := (*ElfPhdr)(nil)
|
||||||
|
var pnote *ElfPhdr
|
||||||
if Linkmode == LinkExternal {
|
if Linkmode == LinkExternal {
|
||||||
/* skip program headers */
|
/* skip program headers */
|
||||||
eh.phoff = 0
|
eh.phoff = 0
|
||||||
|
|
@ -1996,7 +1911,7 @@ func Asmbelf(symo int64) {
|
||||||
* Except on NaCl where it must not be loaded.
|
* Except on NaCl where it must not be loaded.
|
||||||
*/
|
*/
|
||||||
if HEADTYPE != Hnacl {
|
if HEADTYPE != Hnacl {
|
||||||
o = int64(Segtext.Vaddr - pph.vaddr)
|
o := int64(Segtext.Vaddr - pph.vaddr)
|
||||||
Segtext.Vaddr -= uint64(o)
|
Segtext.Vaddr -= uint64(o)
|
||||||
Segtext.Length += uint64(o)
|
Segtext.Length += uint64(o)
|
||||||
o = int64(Segtext.Fileoff - pph.off)
|
o = int64(Segtext.Fileoff - pph.off)
|
||||||
|
|
@ -2006,7 +1921,7 @@ func Asmbelf(symo int64) {
|
||||||
|
|
||||||
if Debug['d'] == 0 {
|
if Debug['d'] == 0 {
|
||||||
/* interpreter */
|
/* interpreter */
|
||||||
sh = elfshname(".interp")
|
sh := elfshname(".interp")
|
||||||
|
|
||||||
sh.type_ = SHT_PROGBITS
|
sh.type_ = SHT_PROGBITS
|
||||||
sh.flags = SHF_ALLOC
|
sh.flags = SHF_ALLOC
|
||||||
|
|
@ -2035,7 +1950,7 @@ func Asmbelf(symo int64) {
|
||||||
|
|
||||||
resoff -= int64(elfinterp(sh, uint64(startva), uint64(resoff), interpreter))
|
resoff -= int64(elfinterp(sh, uint64(startva), uint64(resoff), interpreter))
|
||||||
|
|
||||||
ph = newElfPhdr()
|
ph := newElfPhdr()
|
||||||
ph.type_ = PT_INTERP
|
ph.type_ = PT_INTERP
|
||||||
ph.flags = PF_R
|
ph.flags = PF_R
|
||||||
phsh(ph, sh)
|
phsh(ph, sh)
|
||||||
|
|
@ -2043,7 +1958,7 @@ func Asmbelf(symo int64) {
|
||||||
|
|
||||||
pnote = nil
|
pnote = nil
|
||||||
if HEADTYPE == Hnetbsd || HEADTYPE == Hopenbsd {
|
if HEADTYPE == Hnetbsd || HEADTYPE == Hopenbsd {
|
||||||
sh = nil
|
sh := (*ElfShdr)(nil)
|
||||||
switch HEADTYPE {
|
switch HEADTYPE {
|
||||||
case Hnetbsd:
|
case Hnetbsd:
|
||||||
sh = elfshname(".note.netbsd.ident")
|
sh = elfshname(".note.netbsd.ident")
|
||||||
|
|
@ -2061,7 +1976,7 @@ func Asmbelf(symo int64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(buildinfo) > 0 {
|
if len(buildinfo) > 0 {
|
||||||
sh = elfshname(".note.gnu.build-id")
|
sh := elfshname(".note.gnu.build-id")
|
||||||
resoff -= int64(elfbuildinfo(sh, uint64(startva), uint64(resoff)))
|
resoff -= int64(elfbuildinfo(sh, uint64(startva), uint64(resoff)))
|
||||||
|
|
||||||
if pnote == nil {
|
if pnote == nil {
|
||||||
|
|
@ -2083,7 +1998,7 @@ func Asmbelf(symo int64) {
|
||||||
|
|
||||||
/* Dynamic linking sections */
|
/* Dynamic linking sections */
|
||||||
if Debug['d'] == 0 {
|
if Debug['d'] == 0 {
|
||||||
sh = elfshname(".dynsym")
|
sh := elfshname(".dynsym")
|
||||||
sh.type_ = SHT_DYNSYM
|
sh.type_ = SHT_DYNSYM
|
||||||
sh.flags = SHF_ALLOC
|
sh.flags = SHF_ALLOC
|
||||||
if elf64 != 0 {
|
if elf64 != 0 {
|
||||||
|
|
@ -2104,7 +2019,7 @@ func Asmbelf(symo int64) {
|
||||||
shsym(sh, Linklookup(Ctxt, ".dynstr", 0))
|
shsym(sh, Linklookup(Ctxt, ".dynstr", 0))
|
||||||
|
|
||||||
if elfverneed != 0 {
|
if elfverneed != 0 {
|
||||||
sh = elfshname(".gnu.version")
|
sh := elfshname(".gnu.version")
|
||||||
sh.type_ = SHT_GNU_VERSYM
|
sh.type_ = SHT_GNU_VERSYM
|
||||||
sh.flags = SHF_ALLOC
|
sh.flags = SHF_ALLOC
|
||||||
sh.addralign = 2
|
sh.addralign = 2
|
||||||
|
|
@ -2124,7 +2039,7 @@ func Asmbelf(symo int64) {
|
||||||
switch eh.machine {
|
switch eh.machine {
|
||||||
case EM_X86_64,
|
case EM_X86_64,
|
||||||
EM_PPC64:
|
EM_PPC64:
|
||||||
sh = elfshname(".rela.plt")
|
sh := elfshname(".rela.plt")
|
||||||
sh.type_ = SHT_RELA
|
sh.type_ = SHT_RELA
|
||||||
sh.flags = SHF_ALLOC
|
sh.flags = SHF_ALLOC
|
||||||
sh.entsize = ELF64RELASIZE
|
sh.entsize = ELF64RELASIZE
|
||||||
|
|
@ -2142,7 +2057,7 @@ func Asmbelf(symo int64) {
|
||||||
shsym(sh, Linklookup(Ctxt, ".rela", 0))
|
shsym(sh, Linklookup(Ctxt, ".rela", 0))
|
||||||
|
|
||||||
default:
|
default:
|
||||||
sh = elfshname(".rel.plt")
|
sh := elfshname(".rel.plt")
|
||||||
sh.type_ = SHT_REL
|
sh.type_ = SHT_REL
|
||||||
sh.flags = SHF_ALLOC
|
sh.flags = SHF_ALLOC
|
||||||
sh.entsize = ELF32RELSIZE
|
sh.entsize = ELF32RELSIZE
|
||||||
|
|
@ -2160,7 +2075,7 @@ func Asmbelf(symo int64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if eh.machine == EM_PPC64 {
|
if eh.machine == EM_PPC64 {
|
||||||
sh = elfshname(".glink")
|
sh := elfshname(".glink")
|
||||||
sh.type_ = SHT_PROGBITS
|
sh.type_ = SHT_PROGBITS
|
||||||
sh.flags = SHF_ALLOC + SHF_EXECINSTR
|
sh.flags = SHF_ALLOC + SHF_EXECINSTR
|
||||||
sh.addralign = 4
|
sh.addralign = 4
|
||||||
|
|
@ -2188,7 +2103,7 @@ func Asmbelf(symo int64) {
|
||||||
// On ppc64, .got comes from the input files, so don't
|
// On ppc64, .got comes from the input files, so don't
|
||||||
// create it here, and .got.plt is not used.
|
// create it here, and .got.plt is not used.
|
||||||
if eh.machine != EM_PPC64 {
|
if eh.machine != EM_PPC64 {
|
||||||
sh = elfshname(".got")
|
sh := elfshname(".got")
|
||||||
sh.type_ = SHT_PROGBITS
|
sh.type_ = SHT_PROGBITS
|
||||||
sh.flags = SHF_ALLOC + SHF_WRITE
|
sh.flags = SHF_ALLOC + SHF_WRITE
|
||||||
sh.entsize = uint64(Thearch.Regsize)
|
sh.entsize = uint64(Thearch.Regsize)
|
||||||
|
|
@ -2220,7 +2135,7 @@ func Asmbelf(symo int64) {
|
||||||
sh.addralign = uint64(Thearch.Regsize)
|
sh.addralign = uint64(Thearch.Regsize)
|
||||||
sh.link = uint32(elfshname(".dynstr").shnum)
|
sh.link = uint32(elfshname(".dynstr").shnum)
|
||||||
shsym(sh, Linklookup(Ctxt, ".dynamic", 0))
|
shsym(sh, Linklookup(Ctxt, ".dynamic", 0))
|
||||||
ph = newElfPhdr()
|
ph := newElfPhdr()
|
||||||
ph.type_ = PT_DYNAMIC
|
ph.type_ = PT_DYNAMIC
|
||||||
ph.flags = PF_R + PF_W
|
ph.flags = PF_R + PF_W
|
||||||
phsh(ph, sh)
|
phsh(ph, sh)
|
||||||
|
|
@ -2232,7 +2147,7 @@ func Asmbelf(symo int64) {
|
||||||
// not currently support it. This is handled
|
// not currently support it. This is handled
|
||||||
// appropriately in runtime/cgo.
|
// appropriately in runtime/cgo.
|
||||||
if Ctxt.Tlsoffset != 0 && HEADTYPE != Hopenbsd {
|
if Ctxt.Tlsoffset != 0 && HEADTYPE != Hopenbsd {
|
||||||
ph = newElfPhdr()
|
ph := newElfPhdr()
|
||||||
ph.type_ = PT_TLS
|
ph.type_ = PT_TLS
|
||||||
ph.flags = PF_R
|
ph.flags = PF_R
|
||||||
ph.memsz = uint64(-Ctxt.Tlsoffset)
|
ph.memsz = uint64(-Ctxt.Tlsoffset)
|
||||||
|
|
@ -2241,7 +2156,7 @@ func Asmbelf(symo int64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if HEADTYPE == Hlinux {
|
if HEADTYPE == Hlinux {
|
||||||
ph = newElfPhdr()
|
ph := newElfPhdr()
|
||||||
ph.type_ = PT_GNU_STACK
|
ph.type_ = PT_GNU_STACK
|
||||||
ph.flags = PF_W + PF_R
|
ph.flags = PF_W + PF_R
|
||||||
ph.align = uint64(Thearch.Regsize)
|
ph.align = uint64(Thearch.Regsize)
|
||||||
|
|
@ -2253,7 +2168,7 @@ func Asmbelf(symo int64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
elfobj:
|
elfobj:
|
||||||
sh = elfshname(".shstrtab")
|
sh := elfshname(".shstrtab")
|
||||||
sh.type_ = SHT_STRTAB
|
sh.type_ = SHT_STRTAB
|
||||||
sh.addralign = 1
|
sh.addralign = 1
|
||||||
shsym(sh, Linklookup(Ctxt, ".shstrtab", 0))
|
shsym(sh, Linklookup(Ctxt, ".shstrtab", 0))
|
||||||
|
|
@ -2265,29 +2180,29 @@ elfobj:
|
||||||
elfshname(".strtab")
|
elfshname(".strtab")
|
||||||
}
|
}
|
||||||
|
|
||||||
for sect = Segtext.Sect; sect != nil; sect = sect.Next {
|
for sect := Segtext.Sect; sect != nil; sect = sect.Next {
|
||||||
elfshbits(sect)
|
elfshbits(sect)
|
||||||
}
|
}
|
||||||
for sect = Segrodata.Sect; sect != nil; sect = sect.Next {
|
for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
|
||||||
elfshbits(sect)
|
elfshbits(sect)
|
||||||
}
|
}
|
||||||
for sect = Segdata.Sect; sect != nil; sect = sect.Next {
|
for sect := Segdata.Sect; sect != nil; sect = sect.Next {
|
||||||
elfshbits(sect)
|
elfshbits(sect)
|
||||||
}
|
}
|
||||||
|
|
||||||
if Linkmode == LinkExternal {
|
if Linkmode == LinkExternal {
|
||||||
for sect = Segtext.Sect; sect != nil; sect = sect.Next {
|
for sect := Segtext.Sect; sect != nil; sect = sect.Next {
|
||||||
elfshreloc(sect)
|
elfshreloc(sect)
|
||||||
}
|
}
|
||||||
for sect = Segrodata.Sect; sect != nil; sect = sect.Next {
|
for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
|
||||||
elfshreloc(sect)
|
elfshreloc(sect)
|
||||||
}
|
}
|
||||||
for sect = Segdata.Sect; sect != nil; sect = sect.Next {
|
for sect := Segdata.Sect; sect != nil; sect = sect.Next {
|
||||||
elfshreloc(sect)
|
elfshreloc(sect)
|
||||||
}
|
}
|
||||||
|
|
||||||
// add a .note.GNU-stack section to mark the stack as non-executable
|
// add a .note.GNU-stack section to mark the stack as non-executable
|
||||||
sh = elfshname(".note.GNU-stack")
|
sh := elfshname(".note.GNU-stack")
|
||||||
|
|
||||||
sh.type_ = SHT_PROGBITS
|
sh.type_ = SHT_PROGBITS
|
||||||
sh.addralign = 1
|
sh.addralign = 1
|
||||||
|
|
@ -2297,7 +2212,7 @@ elfobj:
|
||||||
// generate .tbss section for dynamic internal linking (except for OpenBSD)
|
// generate .tbss section for dynamic internal linking (except for OpenBSD)
|
||||||
// external linking generates .tbss in data.c
|
// external linking generates .tbss in data.c
|
||||||
if Linkmode == LinkInternal && Debug['d'] == 0 && HEADTYPE != Hopenbsd {
|
if Linkmode == LinkInternal && Debug['d'] == 0 && HEADTYPE != Hopenbsd {
|
||||||
sh = elfshname(".tbss")
|
sh := elfshname(".tbss")
|
||||||
sh.type_ = SHT_NOBITS
|
sh.type_ = SHT_NOBITS
|
||||||
sh.addralign = uint64(Thearch.Regsize)
|
sh.addralign = uint64(Thearch.Regsize)
|
||||||
sh.size = uint64(-Ctxt.Tlsoffset)
|
sh.size = uint64(-Ctxt.Tlsoffset)
|
||||||
|
|
@ -2305,7 +2220,7 @@ elfobj:
|
||||||
}
|
}
|
||||||
|
|
||||||
if Debug['s'] == 0 {
|
if Debug['s'] == 0 {
|
||||||
sh = elfshname(".symtab")
|
sh := elfshname(".symtab")
|
||||||
sh.type_ = SHT_SYMTAB
|
sh.type_ = SHT_SYMTAB
|
||||||
sh.off = uint64(symo)
|
sh.off = uint64(symo)
|
||||||
sh.size = uint64(Symsize)
|
sh.size = uint64(Symsize)
|
||||||
|
|
@ -2368,7 +2283,7 @@ elfobj:
|
||||||
}
|
}
|
||||||
|
|
||||||
Cseek(0)
|
Cseek(0)
|
||||||
a = 0
|
a := int64(0)
|
||||||
a += int64(elfwritehdr())
|
a += int64(elfwritehdr())
|
||||||
a += int64(elfwritephdrs())
|
a += int64(elfwritephdrs())
|
||||||
a += int64(elfwriteshdrs())
|
a += int64(elfwriteshdrs())
|
||||||
|
|
|
||||||
|
|
@ -54,11 +54,8 @@ var ihash [NIHASH]*Import
|
||||||
var nimport int
|
var nimport int
|
||||||
|
|
||||||
func hashstr(name string) int {
|
func hashstr(name string) int {
|
||||||
var h uint32
|
h := uint32(0)
|
||||||
var cp string
|
for cp := name; cp != ""; cp = cp[1:] {
|
||||||
|
|
||||||
h = 0
|
|
||||||
for cp = name; cp != ""; cp = cp[1:] {
|
|
||||||
h = h*1119 + uint32(cp[0])
|
h = h*1119 + uint32(cp[0])
|
||||||
}
|
}
|
||||||
h &= 0xffffff
|
h &= 0xffffff
|
||||||
|
|
@ -66,16 +63,13 @@ func hashstr(name string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ilookup(name string) *Import {
|
func ilookup(name string) *Import {
|
||||||
var h int
|
h := hashstr(name) % NIHASH
|
||||||
var x *Import
|
for x := ihash[h]; x != nil; x = x.hash {
|
||||||
|
|
||||||
h = hashstr(name) % NIHASH
|
|
||||||
for x = ihash[h]; x != nil; x = x.hash {
|
|
||||||
if x.name[0] == name[0] && x.name == name {
|
if x.name[0] == name[0] && x.name == name {
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
x = new(Import)
|
x := new(Import)
|
||||||
x.name = name
|
x.name = name
|
||||||
x.hash = ihash[h]
|
x.hash = ihash[h]
|
||||||
ihash[h] = x
|
ihash[h] = x
|
||||||
|
|
@ -84,10 +78,7 @@ func ilookup(name string) *Import {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ldpkg(f *Biobuf, pkg string, length int64, filename string, whence int) {
|
func ldpkg(f *Biobuf, pkg string, length int64, filename string, whence int) {
|
||||||
var bdata []byte
|
|
||||||
var data string
|
|
||||||
var p0, p1 int
|
var p0, p1 int
|
||||||
var name string
|
|
||||||
|
|
||||||
if Debug['g'] != 0 {
|
if Debug['g'] != 0 {
|
||||||
return
|
return
|
||||||
|
|
@ -101,7 +92,7 @@ func ldpkg(f *Biobuf, pkg string, length int64, filename string, whence int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
bdata = make([]byte, length)
|
bdata := make([]byte, length)
|
||||||
if int64(Bread(f, bdata)) != length {
|
if int64(Bread(f, bdata)) != length {
|
||||||
fmt.Fprintf(os.Stderr, "%s: short pkg read %s\n", os.Args[0], filename)
|
fmt.Fprintf(os.Stderr, "%s: short pkg read %s\n", os.Args[0], filename)
|
||||||
if Debug['u'] != 0 {
|
if Debug['u'] != 0 {
|
||||||
|
|
@ -109,7 +100,7 @@ func ldpkg(f *Biobuf, pkg string, length int64, filename string, whence int) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
data = string(bdata)
|
data := string(bdata)
|
||||||
|
|
||||||
// first \n$$ marks beginning of exports - skip rest of line
|
// first \n$$ marks beginning of exports - skip rest of line
|
||||||
p0 = strings.Index(data, "\n$$")
|
p0 = strings.Index(data, "\n$$")
|
||||||
|
|
@ -153,7 +144,7 @@ func ldpkg(f *Biobuf, pkg string, length int64, filename string, whence int) {
|
||||||
for p0 < p1 && (data[p0] == ' ' || data[p0] == '\t' || data[p0] == '\n') {
|
for p0 < p1 && (data[p0] == ' ' || data[p0] == '\t' || data[p0] == '\n') {
|
||||||
p0++
|
p0++
|
||||||
}
|
}
|
||||||
name = data[p0:]
|
name := data[p0:]
|
||||||
for p0 < p1 && data[p0] != ' ' && data[p0] != '\t' && data[p0] != '\n' {
|
for p0 < p1 && data[p0] != ' ' && data[p0] != '\t' && data[p0] != '\n' {
|
||||||
p0++
|
p0++
|
||||||
}
|
}
|
||||||
|
|
@ -221,14 +212,13 @@ func ldpkg(f *Biobuf, pkg string, length int64, filename string, whence int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadpkgdata(file string, pkg string, data string) {
|
func loadpkgdata(file string, pkg string, data string) {
|
||||||
var p string
|
|
||||||
var prefix string
|
var prefix string
|
||||||
var name string
|
var name string
|
||||||
var def string
|
var def string
|
||||||
var x *Import
|
var x *Import
|
||||||
|
|
||||||
file = file
|
file = file
|
||||||
p = data
|
p := data
|
||||||
for parsepkgdata(file, pkg, &p, &prefix, &name, &def) > 0 {
|
for parsepkgdata(file, pkg, &p, &prefix, &name, &def) > 0 {
|
||||||
x = ilookup(name)
|
x = ilookup(name)
|
||||||
if x.prefix == "" {
|
if x.prefix == "" {
|
||||||
|
|
@ -250,15 +240,10 @@ func loadpkgdata(file string, pkg string, data string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func parsepkgdata(file string, pkg string, pp *string, prefixp *string, namep *string, defp *string) int {
|
func parsepkgdata(file string, pkg string, pp *string, prefixp *string, namep *string, defp *string) int {
|
||||||
var p string
|
|
||||||
var prefix string
|
var prefix string
|
||||||
var name string
|
|
||||||
var def string
|
|
||||||
var meth string
|
|
||||||
var inquote bool
|
|
||||||
|
|
||||||
// skip white space
|
// skip white space
|
||||||
p = *pp
|
p := *pp
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
for len(p) > 0 && (p[0] == ' ' || p[0] == '\t' || p[0] == '\n') {
|
for len(p) > 0 && (p[0] == ' ' || p[0] == '\t' || p[0] == '\n') {
|
||||||
|
|
@ -310,9 +295,9 @@ loop:
|
||||||
prefix = prefix[:len(prefix)-len(p)-1]
|
prefix = prefix[:len(prefix)-len(p)-1]
|
||||||
|
|
||||||
// name: a.b followed by space
|
// name: a.b followed by space
|
||||||
name = p
|
name := p
|
||||||
|
|
||||||
inquote = false
|
inquote := false
|
||||||
for len(p) > 0 {
|
for len(p) > 0 {
|
||||||
if p[0] == ' ' && !inquote {
|
if p[0] == ' ' && !inquote {
|
||||||
break
|
break
|
||||||
|
|
@ -334,7 +319,7 @@ loop:
|
||||||
p = p[1:]
|
p = p[1:]
|
||||||
|
|
||||||
// def: free form to new line
|
// def: free form to new line
|
||||||
def = p
|
def := p
|
||||||
|
|
||||||
for len(p) > 0 && p[0] != '\n' {
|
for len(p) > 0 && p[0] != '\n' {
|
||||||
p = p[1:]
|
p = p[1:]
|
||||||
|
|
@ -347,6 +332,7 @@ loop:
|
||||||
p = p[1:]
|
p = p[1:]
|
||||||
|
|
||||||
// include methods on successive lines in def of named type
|
// include methods on successive lines in def of named type
|
||||||
|
var meth string
|
||||||
for parsemethod(&p, &meth) > 0 {
|
for parsemethod(&p, &meth) > 0 {
|
||||||
if defbuf == nil {
|
if defbuf == nil {
|
||||||
defbuf = new(bytes.Buffer)
|
defbuf = new(bytes.Buffer)
|
||||||
|
|
@ -372,10 +358,8 @@ loop:
|
||||||
}
|
}
|
||||||
|
|
||||||
func parsemethod(pp *string, methp *string) int {
|
func parsemethod(pp *string, methp *string) int {
|
||||||
var p string
|
|
||||||
|
|
||||||
// skip white space
|
// skip white space
|
||||||
p = *pp
|
p := *pp
|
||||||
|
|
||||||
for len(p) > 0 && (p[0] == ' ' || p[0] == '\t') {
|
for len(p) > 0 && (p[0] == ' ' || p[0] == '\t') {
|
||||||
p = p[1:]
|
p = p[1:]
|
||||||
|
|
@ -415,7 +399,6 @@ useline:
|
||||||
|
|
||||||
func loadcgo(file string, pkg string, p string) {
|
func loadcgo(file string, pkg string, p string) {
|
||||||
var next string
|
var next string
|
||||||
var p0 string
|
|
||||||
var q string
|
var q string
|
||||||
var f []string
|
var f []string
|
||||||
var local string
|
var local string
|
||||||
|
|
@ -423,7 +406,7 @@ func loadcgo(file string, pkg string, p string) {
|
||||||
var lib string
|
var lib string
|
||||||
var s *LSym
|
var s *LSym
|
||||||
|
|
||||||
p0 = ""
|
p0 := ""
|
||||||
for ; p != ""; p = next {
|
for ; p != ""; p = next {
|
||||||
if i := strings.Index(p, "\n"); i >= 0 {
|
if i := strings.Index(p, "\n"); i >= 0 {
|
||||||
p, next = p[:i], p[i+1:]
|
p, next = p[:i], p[i+1:]
|
||||||
|
|
@ -610,10 +593,9 @@ func mark(s *LSym) {
|
||||||
|
|
||||||
func markflood() {
|
func markflood() {
|
||||||
var a *Auto
|
var a *Auto
|
||||||
var s *LSym
|
|
||||||
var i int
|
var i int
|
||||||
|
|
||||||
for s = markq; s != nil; s = s.Queue {
|
for s := markq; s != nil; s = s.Queue {
|
||||||
if s.Type == STEXT {
|
if s.Type == STEXT {
|
||||||
if Debug['v'] > 1 {
|
if Debug['v'] > 1 {
|
||||||
fmt.Fprintf(&Bso, "marktext %s\n", s.Name)
|
fmt.Fprintf(&Bso, "marktext %s\n", s.Name)
|
||||||
|
|
@ -659,38 +641,32 @@ var markextra = []string{
|
||||||
}
|
}
|
||||||
|
|
||||||
func deadcode() {
|
func deadcode() {
|
||||||
var i int
|
|
||||||
var s *LSym
|
|
||||||
var last *LSym
|
|
||||||
var p *LSym
|
|
||||||
var fmt_ string
|
|
||||||
|
|
||||||
if Debug['v'] != 0 {
|
if Debug['v'] != 0 {
|
||||||
fmt.Fprintf(&Bso, "%5.2f deadcode\n", obj.Cputime())
|
fmt.Fprintf(&Bso, "%5.2f deadcode\n", obj.Cputime())
|
||||||
}
|
}
|
||||||
|
|
||||||
mark(Linklookup(Ctxt, INITENTRY, 0))
|
mark(Linklookup(Ctxt, INITENTRY, 0))
|
||||||
for i = 0; i < len(markextra); i++ {
|
for i := 0; i < len(markextra); i++ {
|
||||||
mark(Linklookup(Ctxt, markextra[i], 0))
|
mark(Linklookup(Ctxt, markextra[i], 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
for i = 0; i < len(dynexp); i++ {
|
for i := 0; i < len(dynexp); i++ {
|
||||||
mark(dynexp[i])
|
mark(dynexp[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
markflood()
|
markflood()
|
||||||
|
|
||||||
// keep each beginning with 'typelink.' if the symbol it points at is being kept.
|
// keep each beginning with 'typelink.' if the symbol it points at is being kept.
|
||||||
for s = Ctxt.Allsym; s != nil; s = s.Allsym {
|
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
||||||
if strings.HasPrefix(s.Name, "go.typelink.") {
|
if strings.HasPrefix(s.Name, "go.typelink.") {
|
||||||
s.Reachable = len(s.R) == 1 && s.R[0].Sym.Reachable
|
s.Reachable = len(s.R) == 1 && s.R[0].Sym.Reachable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove dead text but keep file information (z symbols).
|
// remove dead text but keep file information (z symbols).
|
||||||
last = nil
|
last := (*LSym)(nil)
|
||||||
|
|
||||||
for s = Ctxt.Textp; s != nil; s = s.Next {
|
for s := Ctxt.Textp; s != nil; s = s.Next {
|
||||||
if !s.Reachable {
|
if !s.Reachable {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -710,7 +686,7 @@ func deadcode() {
|
||||||
last.Next = nil
|
last.Next = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for s = Ctxt.Allsym; s != nil; s = s.Allsym {
|
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
||||||
if strings.HasPrefix(s.Name, "go.weak.") {
|
if strings.HasPrefix(s.Name, "go.weak.") {
|
||||||
s.Special = 1 // do not lay out in data segment
|
s.Special = 1 // do not lay out in data segment
|
||||||
s.Reachable = true
|
s.Reachable = true
|
||||||
|
|
@ -719,9 +695,10 @@ func deadcode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// record field tracking references
|
// record field tracking references
|
||||||
fmt_ = ""
|
fmt_ := ""
|
||||||
|
|
||||||
for s = Ctxt.Allsym; s != nil; s = s.Allsym {
|
var p *LSym
|
||||||
|
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
||||||
if strings.HasPrefix(s.Name, "go.track.") {
|
if strings.HasPrefix(s.Name, "go.track.") {
|
||||||
s.Special = 1 // do not lay out in data segment
|
s.Special = 1 // do not lay out in data segment
|
||||||
s.Hide = 1
|
s.Hide = 1
|
||||||
|
|
@ -741,7 +718,7 @@ func deadcode() {
|
||||||
if tracksym == "" {
|
if tracksym == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s = Linklookup(Ctxt, tracksym, 0)
|
s := Linklookup(Ctxt, tracksym, 0)
|
||||||
if !s.Reachable {
|
if !s.Reachable {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -749,12 +726,11 @@ func deadcode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func doweak() {
|
func doweak() {
|
||||||
var s *LSym
|
|
||||||
var t *LSym
|
var t *LSym
|
||||||
|
|
||||||
// resolve weak references only if
|
// resolve weak references only if
|
||||||
// target symbol will be in binary anyway.
|
// target symbol will be in binary anyway.
|
||||||
for s = Ctxt.Allsym; s != nil; s = s.Allsym {
|
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
||||||
if strings.HasPrefix(s.Name, "go.weak.") {
|
if strings.HasPrefix(s.Name, "go.weak.") {
|
||||||
t = Linkrlookup(Ctxt, s.Name[8:], int(s.Version))
|
t = Linkrlookup(Ctxt, s.Name[8:], int(s.Version))
|
||||||
if t != nil && t.Type != 0 && t.Reachable {
|
if t != nil && t.Type != 0 && t.Reachable {
|
||||||
|
|
@ -772,13 +748,11 @@ func doweak() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func addexport() {
|
func addexport() {
|
||||||
var i int
|
|
||||||
|
|
||||||
if HEADTYPE == Hdarwin {
|
if HEADTYPE == Hdarwin {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for i = 0; i < len(dynexp); i++ {
|
for i := 0; i < len(dynexp); i++ {
|
||||||
Thearch.Adddynsym(Ctxt, dynexp[i])
|
Thearch.Adddynsym(Ctxt, dynexp[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -840,16 +814,13 @@ var phash [1024]*Pkg
|
||||||
var pkgall *Pkg
|
var pkgall *Pkg
|
||||||
|
|
||||||
func getpkg(path_ string) *Pkg {
|
func getpkg(path_ string) *Pkg {
|
||||||
var p *Pkg
|
h := hashstr(path_) % len(phash)
|
||||||
var h int
|
for p := phash[h]; p != nil; p = p.next {
|
||||||
|
|
||||||
h = hashstr(path_) % len(phash)
|
|
||||||
for p = phash[h]; p != nil; p = p.next {
|
|
||||||
if p.path_ == path_ {
|
if p.path_ == path_ {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p = new(Pkg)
|
p := new(Pkg)
|
||||||
p.path_ = path_
|
p.path_ = path_
|
||||||
p.next = phash[h]
|
p.next = phash[h]
|
||||||
phash[h] = p
|
phash[h] = p
|
||||||
|
|
@ -859,24 +830,18 @@ func getpkg(path_ string) *Pkg {
|
||||||
}
|
}
|
||||||
|
|
||||||
func imported(pkg string, import_ string) {
|
func imported(pkg string, import_ string) {
|
||||||
var p *Pkg
|
|
||||||
var i *Pkg
|
|
||||||
|
|
||||||
// everyone imports runtime, even runtime.
|
// everyone imports runtime, even runtime.
|
||||||
if import_ == "\"runtime\"" {
|
if import_ == "\"runtime\"" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pkg = fmt.Sprintf("\"%v\"", Zconv(pkg, 0)) // turn pkg path into quoted form, freed below
|
pkg = fmt.Sprintf("\"%v\"", Zconv(pkg, 0)) // turn pkg path into quoted form, freed below
|
||||||
p = getpkg(pkg)
|
p := getpkg(pkg)
|
||||||
i = getpkg(import_)
|
i := getpkg(import_)
|
||||||
i.impby = append(i.impby, p)
|
i.impby = append(i.impby, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func cycle(p *Pkg) *Pkg {
|
func cycle(p *Pkg) *Pkg {
|
||||||
var i int
|
|
||||||
var bad *Pkg
|
|
||||||
|
|
||||||
if p.checked != 0 {
|
if p.checked != 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -889,7 +854,8 @@ func cycle(p *Pkg) *Pkg {
|
||||||
}
|
}
|
||||||
|
|
||||||
p.mark = 1
|
p.mark = 1
|
||||||
for i = 0; i < len(p.impby); i++ {
|
var bad *Pkg
|
||||||
|
for i := 0; i < len(p.impby); i++ {
|
||||||
bad = cycle(p.impby[i])
|
bad = cycle(p.impby[i])
|
||||||
if bad != nil {
|
if bad != nil {
|
||||||
p.mark = 0
|
p.mark = 0
|
||||||
|
|
@ -908,9 +874,7 @@ func cycle(p *Pkg) *Pkg {
|
||||||
}
|
}
|
||||||
|
|
||||||
func importcycles() {
|
func importcycles() {
|
||||||
var p *Pkg
|
for p := pkgall; p != nil; p = p.all {
|
||||||
|
|
||||||
for p = pkgall; p != nil; p = p.all {
|
|
||||||
cycle(p)
|
cycle(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,10 +86,7 @@ func addlib(ctxt *Link, src string, obj string, pathname string) {
|
||||||
* pkg: package import path, e.g. container/vector
|
* pkg: package import path, e.g. container/vector
|
||||||
*/
|
*/
|
||||||
func addlibpath(ctxt *Link, srcref string, objref string, file string, pkg string) {
|
func addlibpath(ctxt *Link, srcref string, objref string, file string, pkg string) {
|
||||||
var i int
|
for i := 0; i < len(ctxt.Library); i++ {
|
||||||
var l *Library
|
|
||||||
|
|
||||||
for i = 0; i < len(ctxt.Library); i++ {
|
|
||||||
if file == ctxt.Library[i].File {
|
if file == ctxt.Library[i].File {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -100,7 +97,7 @@ func addlibpath(ctxt *Link, srcref string, objref string, file string, pkg strin
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxt.Library = append(ctxt.Library, Library{})
|
ctxt.Library = append(ctxt.Library, Library{})
|
||||||
l = &ctxt.Library[len(ctxt.Library)-1]
|
l := &ctxt.Library[len(ctxt.Library)-1]
|
||||||
l.Objref = objref
|
l.Objref = objref
|
||||||
l.Srcref = srcref
|
l.Srcref = srcref
|
||||||
l.File = file
|
l.File = file
|
||||||
|
|
|
||||||
|
|
@ -285,39 +285,35 @@ func valuecmp(a *LSym, b *LSym) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ldelf(f *Biobuf, pkg string, length int64, pn string) {
|
func ldelf(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
var err error
|
symbols := []*LSym(nil)
|
||||||
var base int32
|
|
||||||
var add uint64
|
|
||||||
var info uint64
|
|
||||||
var name string
|
|
||||||
var i int
|
|
||||||
var j int
|
|
||||||
var rela int
|
|
||||||
var is64 int
|
|
||||||
var n int
|
|
||||||
var flag int
|
|
||||||
var hdrbuf [64]uint8
|
|
||||||
var p []byte
|
|
||||||
var hdr *ElfHdrBytes
|
|
||||||
var elfobj *ElfObj
|
|
||||||
var sect *ElfSect
|
|
||||||
var rsect *ElfSect
|
|
||||||
var sym ElfSym
|
|
||||||
var e binary.ByteOrder
|
|
||||||
var r []Reloc
|
|
||||||
var rp *Reloc
|
|
||||||
var s *LSym
|
|
||||||
var symbols []*LSym
|
|
||||||
|
|
||||||
symbols = nil
|
|
||||||
|
|
||||||
if Debug['v'] != 0 {
|
if Debug['v'] != 0 {
|
||||||
fmt.Fprintf(&Bso, "%5.2f ldelf %s\n", obj.Cputime(), pn)
|
fmt.Fprintf(&Bso, "%5.2f ldelf %s\n", obj.Cputime(), pn)
|
||||||
}
|
}
|
||||||
|
|
||||||
Ctxt.Version++
|
Ctxt.Version++
|
||||||
base = int32(Boffset(f))
|
base := int32(Boffset(f))
|
||||||
|
|
||||||
|
var add uint64
|
||||||
|
var e binary.ByteOrder
|
||||||
|
var elfobj *ElfObj
|
||||||
|
var err error
|
||||||
|
var flag int
|
||||||
|
var hdr *ElfHdrBytes
|
||||||
|
var hdrbuf [64]uint8
|
||||||
|
var info uint64
|
||||||
|
var is64 int
|
||||||
|
var j int
|
||||||
|
var n int
|
||||||
|
var name string
|
||||||
|
var p []byte
|
||||||
|
var r []Reloc
|
||||||
|
var rela int
|
||||||
|
var rp *Reloc
|
||||||
|
var rsect *ElfSect
|
||||||
|
var s *LSym
|
||||||
|
var sect *ElfSect
|
||||||
|
var sym ElfSym
|
||||||
if Bread(f, hdrbuf[:]) != len(hdrbuf) {
|
if Bread(f, hdrbuf[:]) != len(hdrbuf) {
|
||||||
goto bad
|
goto bad
|
||||||
}
|
}
|
||||||
|
|
@ -348,10 +344,8 @@ func ldelf(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
|
|
||||||
is64 = 0
|
is64 = 0
|
||||||
if hdr.Ident[4] == ElfClass64 {
|
if hdr.Ident[4] == ElfClass64 {
|
||||||
var hdr *ElfHdrBytes64
|
|
||||||
|
|
||||||
is64 = 1
|
is64 = 1
|
||||||
hdr = new(ElfHdrBytes64)
|
hdr := new(ElfHdrBytes64)
|
||||||
binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter
|
binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter
|
||||||
elfobj.type_ = uint32(e.Uint16(hdr.Type[:]))
|
elfobj.type_ = uint32(e.Uint16(hdr.Type[:]))
|
||||||
elfobj.machine = uint32(e.Uint16(hdr.Machine[:]))
|
elfobj.machine = uint32(e.Uint16(hdr.Machine[:]))
|
||||||
|
|
@ -426,7 +420,7 @@ func ldelf(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
elfobj.sect = make([]ElfSect, elfobj.shnum)
|
elfobj.sect = make([]ElfSect, elfobj.shnum)
|
||||||
|
|
||||||
elfobj.nsect = uint(elfobj.shnum)
|
elfobj.nsect = uint(elfobj.shnum)
|
||||||
for i = 0; uint(i) < elfobj.nsect; i++ {
|
for i := 0; uint(i) < elfobj.nsect; i++ {
|
||||||
if Bseek(f, int64(uint64(base)+elfobj.shoff+uint64(int64(i)*int64(elfobj.shentsize))), 0) < 0 {
|
if Bseek(f, int64(uint64(base)+elfobj.shoff+uint64(int64(i)*int64(elfobj.shentsize))), 0) < 0 {
|
||||||
goto bad
|
goto bad
|
||||||
}
|
}
|
||||||
|
|
@ -478,7 +472,7 @@ func ldelf(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
if err = elfmap(elfobj, sect); err != nil {
|
if err = elfmap(elfobj, sect); err != nil {
|
||||||
goto bad
|
goto bad
|
||||||
}
|
}
|
||||||
for i = 0; uint(i) < elfobj.nsect; i++ {
|
for i := 0; uint(i) < elfobj.nsect; i++ {
|
||||||
if elfobj.sect[i].nameoff != 0 {
|
if elfobj.sect[i].nameoff != 0 {
|
||||||
elfobj.sect[i].name = cstring(sect.base[elfobj.sect[i].nameoff:])
|
elfobj.sect[i].name = cstring(sect.base[elfobj.sect[i].nameoff:])
|
||||||
}
|
}
|
||||||
|
|
@ -517,7 +511,7 @@ func ldelf(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
// as well use one large chunk.
|
// as well use one large chunk.
|
||||||
|
|
||||||
// create symbols for elfmapped sections
|
// create symbols for elfmapped sections
|
||||||
for i = 0; uint(i) < elfobj.nsect; i++ {
|
for i := 0; uint(i) < elfobj.nsect; i++ {
|
||||||
sect = &elfobj.sect[i]
|
sect = &elfobj.sect[i]
|
||||||
if (sect.type_ != ElfSectProgbits && sect.type_ != ElfSectNobits) || sect.flags&ElfSectFlagAlloc == 0 {
|
if (sect.type_ != ElfSectProgbits && sect.type_ != ElfSectNobits) || sect.flags&ElfSectFlagAlloc == 0 {
|
||||||
continue
|
continue
|
||||||
|
|
@ -572,7 +566,7 @@ func ldelf(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
Errorexit()
|
Errorexit()
|
||||||
}
|
}
|
||||||
|
|
||||||
for i = 1; i < elfobj.nsymtab; i++ {
|
for i := 1; i < elfobj.nsymtab; i++ {
|
||||||
if err = readelfsym(elfobj, i, &sym, 1); err != nil {
|
if err = readelfsym(elfobj, i, &sym, 1); err != nil {
|
||||||
goto bad
|
goto bad
|
||||||
}
|
}
|
||||||
|
|
@ -645,7 +639,7 @@ func ldelf(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
|
|
||||||
// Sort outer lists by address, adding to textp.
|
// Sort outer lists by address, adding to textp.
|
||||||
// This keeps textp in increasing address order.
|
// This keeps textp in increasing address order.
|
||||||
for i = 0; uint(i) < elfobj.nsect; i++ {
|
for i := 0; uint(i) < elfobj.nsect; i++ {
|
||||||
s = elfobj.sect[i].sym
|
s = elfobj.sect[i].sym
|
||||||
if s == nil {
|
if s == nil {
|
||||||
continue
|
continue
|
||||||
|
|
@ -676,7 +670,7 @@ func ldelf(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// load relocations
|
// load relocations
|
||||||
for i = 0; uint(i) < elfobj.nsect; i++ {
|
for i := 0; uint(i) < elfobj.nsect; i++ {
|
||||||
rsect = &elfobj.sect[i]
|
rsect = &elfobj.sect[i]
|
||||||
if rsect.type_ != ElfSectRela && rsect.type_ != ElfSectRel {
|
if rsect.type_ != ElfSectRela && rsect.type_ != ElfSectRel {
|
||||||
continue
|
continue
|
||||||
|
|
@ -782,9 +776,7 @@ bad:
|
||||||
}
|
}
|
||||||
|
|
||||||
func section(elfobj *ElfObj, name string) *ElfSect {
|
func section(elfobj *ElfObj, name string) *ElfSect {
|
||||||
var i int
|
for i := 0; uint(i) < elfobj.nsect; i++ {
|
||||||
|
|
||||||
for i = 0; uint(i) < elfobj.nsect; i++ {
|
|
||||||
if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name {
|
if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name {
|
||||||
return &elfobj.sect[i]
|
return &elfobj.sect[i]
|
||||||
}
|
}
|
||||||
|
|
@ -812,8 +804,6 @@ func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func readelfsym(elfobj *ElfObj, i int, sym *ElfSym, needSym int) (err error) {
|
func readelfsym(elfobj *ElfObj, i int, sym *ElfSym, needSym int) (err error) {
|
||||||
var s *LSym
|
|
||||||
|
|
||||||
if i >= elfobj.nsymtab || i < 0 {
|
if i >= elfobj.nsymtab || i < 0 {
|
||||||
err = fmt.Errorf("invalid elf symbol index")
|
err = fmt.Errorf("invalid elf symbol index")
|
||||||
return err
|
return err
|
||||||
|
|
@ -845,7 +835,7 @@ func readelfsym(elfobj *ElfObj, i int, sym *ElfSym, needSym int) (err error) {
|
||||||
sym.other = b.Other
|
sym.other = b.Other
|
||||||
}
|
}
|
||||||
|
|
||||||
s = nil
|
s := (*LSym)(nil)
|
||||||
if sym.name == "_GLOBAL_OFFSET_TABLE_" {
|
if sym.name == "_GLOBAL_OFFSET_TABLE_" {
|
||||||
sym.name = ".got"
|
sym.name = ".got"
|
||||||
}
|
}
|
||||||
|
|
@ -940,11 +930,8 @@ func (x rbyoff) Swap(i, j int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x rbyoff) Less(i, j int) bool {
|
func (x rbyoff) Less(i, j int) bool {
|
||||||
var a *Reloc
|
a := &x[i]
|
||||||
var b *Reloc
|
b := &x[j]
|
||||||
|
|
||||||
a = &x[i]
|
|
||||||
b = &x[j]
|
|
||||||
if a.Off < b.Off {
|
if a.Off < b.Off {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -172,13 +172,8 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func unpackcmd(p []byte, m *LdMachoObj, c *LdMachoCmd, type_ uint, sz uint) int {
|
func unpackcmd(p []byte, m *LdMachoObj, c *LdMachoCmd, type_ uint, sz uint) int {
|
||||||
var e4 func([]byte) uint32
|
e4 := m.e.Uint32
|
||||||
var e8 func([]byte) uint64
|
e8 := m.e.Uint64
|
||||||
var s *LdMachoSect
|
|
||||||
var i int
|
|
||||||
|
|
||||||
e4 = m.e.Uint32
|
|
||||||
e8 = m.e.Uint64
|
|
||||||
|
|
||||||
c.type_ = int(type_)
|
c.type_ = int(type_)
|
||||||
c.size = uint32(sz)
|
c.size = uint32(sz)
|
||||||
|
|
@ -204,7 +199,8 @@ func unpackcmd(p []byte, m *LdMachoObj, c *LdMachoCmd, type_ uint, sz uint) int
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
p = p[56:]
|
p = p[56:]
|
||||||
for i = 0; uint32(i) < c.seg.nsect; i++ {
|
var s *LdMachoSect
|
||||||
|
for i := 0; uint32(i) < c.seg.nsect; i++ {
|
||||||
s = &c.seg.sect[i]
|
s = &c.seg.sect[i]
|
||||||
s.name = cstring(p[0:16])
|
s.name = cstring(p[0:16])
|
||||||
s.segname = cstring(p[16:32])
|
s.segname = cstring(p[16:32])
|
||||||
|
|
@ -238,7 +234,8 @@ func unpackcmd(p []byte, m *LdMachoObj, c *LdMachoCmd, type_ uint, sz uint) int
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
p = p[72:]
|
p = p[72:]
|
||||||
for i = 0; uint32(i) < c.seg.nsect; i++ {
|
var s *LdMachoSect
|
||||||
|
for i := 0; uint32(i) < c.seg.nsect; i++ {
|
||||||
s = &c.seg.sect[i]
|
s = &c.seg.sect[i]
|
||||||
s.name = cstring(p[0:16])
|
s.name = cstring(p[0:16])
|
||||||
s.segname = cstring(p[16:32])
|
s.segname = cstring(p[16:32])
|
||||||
|
|
@ -293,24 +290,19 @@ func unpackcmd(p []byte, m *LdMachoObj, c *LdMachoCmd, type_ uint, sz uint) int
|
||||||
}
|
}
|
||||||
|
|
||||||
func macholoadrel(m *LdMachoObj, sect *LdMachoSect) int {
|
func macholoadrel(m *LdMachoObj, sect *LdMachoSect) int {
|
||||||
var rel []LdMachoRel
|
|
||||||
var r *LdMachoRel
|
|
||||||
var buf []byte
|
|
||||||
var p []byte
|
|
||||||
var i int
|
|
||||||
var n int
|
|
||||||
var v uint32
|
|
||||||
|
|
||||||
if sect.rel != nil || sect.nreloc == 0 {
|
if sect.rel != nil || sect.nreloc == 0 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
rel = make([]LdMachoRel, sect.nreloc)
|
rel := make([]LdMachoRel, sect.nreloc)
|
||||||
n = int(sect.nreloc * 8)
|
n := int(sect.nreloc * 8)
|
||||||
buf = make([]byte, n)
|
buf := make([]byte, n)
|
||||||
if Bseek(m.f, m.base+int64(sect.reloff), 0) < 0 || Bread(m.f, buf) != n {
|
if Bseek(m.f, m.base+int64(sect.reloff), 0) < 0 || Bread(m.f, buf) != n {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
for i = 0; uint32(i) < sect.nreloc; i++ {
|
var p []byte
|
||||||
|
var r *LdMachoRel
|
||||||
|
var v uint32
|
||||||
|
for i := 0; uint32(i) < sect.nreloc; i++ {
|
||||||
r = &rel[i]
|
r = &rel[i]
|
||||||
p = buf[i*8:]
|
p = buf[i*8:]
|
||||||
r.addr = m.e.Uint32(p)
|
r.addr = m.e.Uint32(p)
|
||||||
|
|
@ -347,56 +339,44 @@ func macholoadrel(m *LdMachoObj, sect *LdMachoSect) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func macholoaddsym(m *LdMachoObj, d *LdMachoDysymtab) int {
|
func macholoaddsym(m *LdMachoObj, d *LdMachoDysymtab) int {
|
||||||
var p []byte
|
n := int(d.nindirectsyms)
|
||||||
var i int
|
|
||||||
var n int
|
|
||||||
|
|
||||||
n = int(d.nindirectsyms)
|
p := make([]byte, n*4)
|
||||||
|
|
||||||
p = make([]byte, n*4)
|
|
||||||
if Bseek(m.f, m.base+int64(d.indirectsymoff), 0) < 0 || Bread(m.f, p) != len(p) {
|
if Bseek(m.f, m.base+int64(d.indirectsymoff), 0) < 0 || Bread(m.f, p) != len(p) {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
d.indir = make([]uint32, n)
|
d.indir = make([]uint32, n)
|
||||||
for i = 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
d.indir[i] = m.e.Uint32(p[4*i:])
|
d.indir[i] = m.e.Uint32(p[4*i:])
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func macholoadsym(m *LdMachoObj, symtab *LdMachoSymtab) int {
|
func macholoadsym(m *LdMachoObj, symtab *LdMachoSymtab) int {
|
||||||
var strbuf []byte
|
|
||||||
var symbuf []byte
|
|
||||||
var p []byte
|
|
||||||
var i int
|
|
||||||
var n int
|
|
||||||
var symsize int
|
|
||||||
var sym []LdMachoSym
|
|
||||||
var s *LdMachoSym
|
|
||||||
var v uint32
|
|
||||||
|
|
||||||
if symtab.sym != nil {
|
if symtab.sym != nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
strbuf = make([]byte, symtab.strsize)
|
strbuf := make([]byte, symtab.strsize)
|
||||||
if Bseek(m.f, m.base+int64(symtab.stroff), 0) < 0 || Bread(m.f, strbuf) != len(strbuf) {
|
if Bseek(m.f, m.base+int64(symtab.stroff), 0) < 0 || Bread(m.f, strbuf) != len(strbuf) {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
symsize = 12
|
symsize := 12
|
||||||
if m.is64 {
|
if m.is64 {
|
||||||
symsize = 16
|
symsize = 16
|
||||||
}
|
}
|
||||||
n = int(symtab.nsym * uint32(symsize))
|
n := int(symtab.nsym * uint32(symsize))
|
||||||
symbuf = make([]byte, n)
|
symbuf := make([]byte, n)
|
||||||
if Bseek(m.f, m.base+int64(symtab.symoff), 0) < 0 || Bread(m.f, symbuf) != len(symbuf) {
|
if Bseek(m.f, m.base+int64(symtab.symoff), 0) < 0 || Bread(m.f, symbuf) != len(symbuf) {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
sym = make([]LdMachoSym, symtab.nsym)
|
sym := make([]LdMachoSym, symtab.nsym)
|
||||||
p = symbuf
|
p := symbuf
|
||||||
for i = 0; uint32(i) < symtab.nsym; i++ {
|
var s *LdMachoSym
|
||||||
|
var v uint32
|
||||||
|
for i := 0; uint32(i) < symtab.nsym; i++ {
|
||||||
s = &sym[i]
|
s = &sym[i]
|
||||||
v = m.e.Uint32(p)
|
v = m.e.Uint32(p)
|
||||||
if v >= symtab.strsize {
|
if v >= symtab.strsize {
|
||||||
|
|
@ -421,13 +401,11 @@ func macholoadsym(m *LdMachoObj, symtab *LdMachoSymtab) int {
|
||||||
|
|
||||||
func ldmacho(f *Biobuf, pkg string, length int64, pn string) {
|
func ldmacho(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
var err error
|
var err error
|
||||||
var i int
|
|
||||||
var j int
|
var j int
|
||||||
var is64 bool
|
var is64 bool
|
||||||
var secaddr uint64
|
var secaddr uint64
|
||||||
var hdr [7 * 4]uint8
|
var hdr [7 * 4]uint8
|
||||||
var cmdp []byte
|
var cmdp []byte
|
||||||
var tmp [4]uint8
|
|
||||||
var dat []byte
|
var dat []byte
|
||||||
var ncmd uint32
|
var ncmd uint32
|
||||||
var cmdsz uint32
|
var cmdsz uint32
|
||||||
|
|
@ -436,7 +414,6 @@ func ldmacho(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
var off uint32
|
var off uint32
|
||||||
var m *LdMachoObj
|
var m *LdMachoObj
|
||||||
var e binary.ByteOrder
|
var e binary.ByteOrder
|
||||||
var base int64
|
|
||||||
var sect *LdMachoSect
|
var sect *LdMachoSect
|
||||||
var rel *LdMachoRel
|
var rel *LdMachoRel
|
||||||
var rpi int
|
var rpi int
|
||||||
|
|
@ -452,7 +429,7 @@ func ldmacho(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
var name string
|
var name string
|
||||||
|
|
||||||
Ctxt.Version++
|
Ctxt.Version++
|
||||||
base = Boffset(f)
|
base := Boffset(f)
|
||||||
if Bread(f, hdr[:]) != len(hdr) {
|
if Bread(f, hdr[:]) != len(hdr) {
|
||||||
goto bad
|
goto bad
|
||||||
}
|
}
|
||||||
|
|
@ -475,6 +452,7 @@ func ldmacho(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if is64 {
|
if is64 {
|
||||||
|
var tmp [4]uint8
|
||||||
Bread(f, tmp[:4]) // skip reserved word in header
|
Bread(f, tmp[:4]) // skip reserved word in header
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -524,7 +502,7 @@ func ldmacho(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
symtab = nil
|
symtab = nil
|
||||||
dsymtab = nil
|
dsymtab = nil
|
||||||
|
|
||||||
for i = 0; uint32(i) < ncmd; i++ {
|
for i := 0; uint32(i) < ncmd; i++ {
|
||||||
ty = e.Uint32(cmdp)
|
ty = e.Uint32(cmdp)
|
||||||
sz = e.Uint32(cmdp[4:])
|
sz = e.Uint32(cmdp[4:])
|
||||||
m.cmd[i].off = off
|
m.cmd[i].off = off
|
||||||
|
|
@ -581,7 +559,7 @@ func ldmacho(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
goto bad
|
goto bad
|
||||||
}
|
}
|
||||||
|
|
||||||
for i = 0; uint32(i) < c.seg.nsect; i++ {
|
for i := 0; uint32(i) < c.seg.nsect; i++ {
|
||||||
sect = &c.seg.sect[i]
|
sect = &c.seg.sect[i]
|
||||||
if sect.segname != "__TEXT" && sect.segname != "__DATA" {
|
if sect.segname != "__TEXT" && sect.segname != "__DATA" {
|
||||||
continue
|
continue
|
||||||
|
|
@ -623,8 +601,7 @@ func ldmacho(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
|
|
||||||
// enter sub-symbols into symbol table.
|
// enter sub-symbols into symbol table.
|
||||||
// have to guess sizes from next symbol.
|
// have to guess sizes from next symbol.
|
||||||
for i = 0; uint32(i) < symtab.nsym; i++ {
|
for i := 0; uint32(i) < symtab.nsym; i++ {
|
||||||
var v int
|
|
||||||
sym = &symtab.sym[i]
|
sym = &symtab.sym[i]
|
||||||
if sym.type_&N_STAB != 0 {
|
if sym.type_&N_STAB != 0 {
|
||||||
continue
|
continue
|
||||||
|
|
@ -636,7 +613,7 @@ func ldmacho(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
if name[0] == '_' && name[1] != '\x00' {
|
if name[0] == '_' && name[1] != '\x00' {
|
||||||
name = name[1:]
|
name = name[1:]
|
||||||
}
|
}
|
||||||
v = 0
|
v := 0
|
||||||
if sym.type_&N_EXT == 0 {
|
if sym.type_&N_EXT == 0 {
|
||||||
v = Ctxt.Version
|
v = Ctxt.Version
|
||||||
}
|
}
|
||||||
|
|
@ -688,7 +665,7 @@ func ldmacho(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
|
|
||||||
// Sort outer lists by address, adding to textp.
|
// Sort outer lists by address, adding to textp.
|
||||||
// This keeps textp in increasing address order.
|
// This keeps textp in increasing address order.
|
||||||
for i = 0; uint32(i) < c.seg.nsect; i++ {
|
for i := 0; uint32(i) < c.seg.nsect; i++ {
|
||||||
sect = &c.seg.sect[i]
|
sect = &c.seg.sect[i]
|
||||||
s = sect.sym
|
s = sect.sym
|
||||||
if s == nil {
|
if s == nil {
|
||||||
|
|
@ -730,7 +707,7 @@ func ldmacho(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// load relocations
|
// load relocations
|
||||||
for i = 0; uint32(i) < c.seg.nsect; i++ {
|
for i := 0; uint32(i) < c.seg.nsect; i++ {
|
||||||
sect = &c.seg.sect[i]
|
sect = &c.seg.sect[i]
|
||||||
s = sect.sym
|
s = sect.sym
|
||||||
if s == nil {
|
if s == nil {
|
||||||
|
|
@ -746,9 +723,6 @@ func ldmacho(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
rp = &r[rpi]
|
rp = &r[rpi]
|
||||||
rel = §.rel[j]
|
rel = §.rel[j]
|
||||||
if rel.scattered != 0 {
|
if rel.scattered != 0 {
|
||||||
var k int
|
|
||||||
var ks *LdMachoSect
|
|
||||||
|
|
||||||
if Thearch.Thechar != '8' {
|
if Thearch.Thechar != '8' {
|
||||||
// mach-o only uses scattered relocation on 32-bit platforms
|
// mach-o only uses scattered relocation on 32-bit platforms
|
||||||
Diag("unexpected scattered relocation")
|
Diag("unexpected scattered relocation")
|
||||||
|
|
@ -792,54 +766,53 @@ func ldmacho(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
|
|
||||||
// now consider the desired symbol.
|
// now consider the desired symbol.
|
||||||
// find the section where it lives.
|
// find the section where it lives.
|
||||||
for k = 0; uint32(k) < c.seg.nsect; k++ {
|
var ks *LdMachoSect
|
||||||
|
for k := 0; uint32(k) < c.seg.nsect; k++ {
|
||||||
ks = &c.seg.sect[k]
|
ks = &c.seg.sect[k]
|
||||||
if ks.addr <= uint64(rel.value) && uint64(rel.value) < ks.addr+ks.size {
|
if ks.addr <= uint64(rel.value) && uint64(rel.value) < ks.addr+ks.size {
|
||||||
goto foundk
|
if ks.sym != nil {
|
||||||
|
rp.Sym = ks.sym
|
||||||
|
rp.Add += int64(uint64(rel.value) - ks.addr)
|
||||||
|
} else if ks.segname == "__IMPORT" && ks.name == "__pointers" {
|
||||||
|
// handle reference to __IMPORT/__pointers.
|
||||||
|
// how much worse can this get?
|
||||||
|
// why are we supporting 386 on the mac anyway?
|
||||||
|
rp.Type = 512 + MACHO_FAKE_GOTPCREL
|
||||||
|
|
||||||
|
// figure out which pointer this is a reference to.
|
||||||
|
k = int(uint64(ks.res1) + (uint64(rel.value)-ks.addr)/4)
|
||||||
|
|
||||||
|
// load indirect table for __pointers
|
||||||
|
// fetch symbol number
|
||||||
|
if dsymtab == nil || k < 0 || uint32(k) >= dsymtab.nindirectsyms || dsymtab.indir == nil {
|
||||||
|
err = fmt.Errorf("invalid scattered relocation: indirect symbol reference out of range")
|
||||||
|
goto bad
|
||||||
|
}
|
||||||
|
|
||||||
|
k = int(dsymtab.indir[k])
|
||||||
|
if k < 0 || uint32(k) >= symtab.nsym {
|
||||||
|
err = fmt.Errorf("invalid scattered relocation: symbol reference out of range")
|
||||||
|
goto bad
|
||||||
|
}
|
||||||
|
|
||||||
|
rp.Sym = symtab.sym[k].sym
|
||||||
|
} else {
|
||||||
|
err = fmt.Errorf("unsupported scattered relocation: reference to %s/%s", ks.segname, ks.name)
|
||||||
|
goto bad
|
||||||
|
}
|
||||||
|
|
||||||
|
rpi++
|
||||||
|
|
||||||
|
// skip #1 of 2 rel; continue skips #2 of 2.
|
||||||
|
j++
|
||||||
|
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = fmt.Errorf("unsupported scattered relocation: invalid address %#x", rel.addr)
|
err = fmt.Errorf("unsupported scattered relocation: invalid address %#x", rel.addr)
|
||||||
goto bad
|
goto bad
|
||||||
|
|
||||||
foundk:
|
|
||||||
if ks.sym != nil {
|
|
||||||
rp.Sym = ks.sym
|
|
||||||
rp.Add += int64(uint64(rel.value) - ks.addr)
|
|
||||||
} else if ks.segname == "__IMPORT" && ks.name == "__pointers" {
|
|
||||||
// handle reference to __IMPORT/__pointers.
|
|
||||||
// how much worse can this get?
|
|
||||||
// why are we supporting 386 on the mac anyway?
|
|
||||||
rp.Type = 512 + MACHO_FAKE_GOTPCREL
|
|
||||||
|
|
||||||
// figure out which pointer this is a reference to.
|
|
||||||
k = int(uint64(ks.res1) + (uint64(rel.value)-ks.addr)/4)
|
|
||||||
|
|
||||||
// load indirect table for __pointers
|
|
||||||
// fetch symbol number
|
|
||||||
if dsymtab == nil || k < 0 || uint32(k) >= dsymtab.nindirectsyms || dsymtab.indir == nil {
|
|
||||||
err = fmt.Errorf("invalid scattered relocation: indirect symbol reference out of range")
|
|
||||||
goto bad
|
|
||||||
}
|
|
||||||
|
|
||||||
k = int(dsymtab.indir[k])
|
|
||||||
if k < 0 || uint32(k) >= symtab.nsym {
|
|
||||||
err = fmt.Errorf("invalid scattered relocation: symbol reference out of range")
|
|
||||||
goto bad
|
|
||||||
}
|
|
||||||
|
|
||||||
rp.Sym = symtab.sym[k].sym
|
|
||||||
} else {
|
|
||||||
err = fmt.Errorf("unsupported scattered relocation: reference to %s/%s", ks.segname, ks.name)
|
|
||||||
goto bad
|
|
||||||
}
|
|
||||||
|
|
||||||
rpi++
|
|
||||||
|
|
||||||
// skip #1 of 2 rel; continue skips #2 of 2.
|
|
||||||
j++
|
|
||||||
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rp.Siz = rel.length
|
rp.Siz = rel.length
|
||||||
|
|
|
||||||
|
|
@ -127,36 +127,31 @@ type PeObj struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ldpe(f *Biobuf, pkg string, length int64, pn string) {
|
func ldpe(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
var err error
|
|
||||||
var name string
|
|
||||||
var base int32
|
|
||||||
var l uint32
|
|
||||||
var i int
|
|
||||||
var j int
|
|
||||||
var numaux int
|
|
||||||
var peobj *PeObj
|
|
||||||
var sect *PeSect
|
|
||||||
var rsect *PeSect
|
|
||||||
var symbuf [18]uint8
|
|
||||||
var s *LSym
|
|
||||||
var r []Reloc
|
|
||||||
var rp *Reloc
|
|
||||||
var sym *PeSym
|
|
||||||
|
|
||||||
if Debug['v'] != 0 {
|
if Debug['v'] != 0 {
|
||||||
fmt.Fprintf(&Bso, "%5.2f ldpe %s\n", obj.Cputime(), pn)
|
fmt.Fprintf(&Bso, "%5.2f ldpe %s\n", obj.Cputime(), pn)
|
||||||
}
|
}
|
||||||
|
|
||||||
sect = nil
|
sect := (*PeSect)(nil)
|
||||||
Ctxt.Version++
|
Ctxt.Version++
|
||||||
base = int32(Boffset(f))
|
base := int32(Boffset(f))
|
||||||
|
|
||||||
peobj = new(PeObj)
|
peobj := new(PeObj)
|
||||||
peobj.f = f
|
peobj.f = f
|
||||||
peobj.base = uint32(base)
|
peobj.base = uint32(base)
|
||||||
peobj.name = pn
|
peobj.name = pn
|
||||||
|
|
||||||
// read header
|
// read header
|
||||||
|
var err error
|
||||||
|
var j int
|
||||||
|
var l uint32
|
||||||
|
var name string
|
||||||
|
var numaux int
|
||||||
|
var r []Reloc
|
||||||
|
var rp *Reloc
|
||||||
|
var rsect *PeSect
|
||||||
|
var s *LSym
|
||||||
|
var sym *PeSym
|
||||||
|
var symbuf [18]uint8
|
||||||
if err = binary.Read(f, binary.LittleEndian, &peobj.fh); err != nil {
|
if err = binary.Read(f, binary.LittleEndian, &peobj.fh); err != nil {
|
||||||
goto bad
|
goto bad
|
||||||
}
|
}
|
||||||
|
|
@ -165,7 +160,7 @@ func ldpe(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
peobj.sect = make([]PeSect, peobj.fh.NumberOfSections)
|
peobj.sect = make([]PeSect, peobj.fh.NumberOfSections)
|
||||||
|
|
||||||
peobj.nsect = uint(peobj.fh.NumberOfSections)
|
peobj.nsect = uint(peobj.fh.NumberOfSections)
|
||||||
for i = 0; i < int(peobj.fh.NumberOfSections); i++ {
|
for i := 0; i < int(peobj.fh.NumberOfSections); i++ {
|
||||||
if err = binary.Read(f, binary.LittleEndian, &peobj.sect[i].sh); err != nil {
|
if err = binary.Read(f, binary.LittleEndian, &peobj.sect[i].sh); err != nil {
|
||||||
goto bad
|
goto bad
|
||||||
}
|
}
|
||||||
|
|
@ -189,7 +184,7 @@ func ldpe(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// rewrite section names if they start with /
|
// rewrite section names if they start with /
|
||||||
for i = 0; i < int(peobj.fh.NumberOfSections); i++ {
|
for i := 0; i < int(peobj.fh.NumberOfSections); i++ {
|
||||||
if peobj.sect[i].name == "" {
|
if peobj.sect[i].name == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -205,7 +200,7 @@ func ldpe(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
|
|
||||||
peobj.npesym = uint(peobj.fh.NumberOfSymbols)
|
peobj.npesym = uint(peobj.fh.NumberOfSymbols)
|
||||||
Bseek(f, int64(base)+int64(peobj.fh.PointerToSymbolTable), 0)
|
Bseek(f, int64(base)+int64(peobj.fh.PointerToSymbolTable), 0)
|
||||||
for i = 0; uint32(i) < peobj.fh.NumberOfSymbols; i += numaux + 1 {
|
for i := 0; uint32(i) < peobj.fh.NumberOfSymbols; i += numaux + 1 {
|
||||||
Bseek(f, int64(base)+int64(peobj.fh.PointerToSymbolTable)+int64(len(symbuf))*int64(i), 0)
|
Bseek(f, int64(base)+int64(peobj.fh.PointerToSymbolTable)+int64(len(symbuf))*int64(i), 0)
|
||||||
if Bread(f, symbuf[:]) != len(symbuf) {
|
if Bread(f, symbuf[:]) != len(symbuf) {
|
||||||
goto bad
|
goto bad
|
||||||
|
|
@ -230,7 +225,7 @@ func ldpe(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// create symbols for mapped sections
|
// create symbols for mapped sections
|
||||||
for i = 0; uint(i) < peobj.nsect; i++ {
|
for i := 0; uint(i) < peobj.nsect; i++ {
|
||||||
sect = &peobj.sect[i]
|
sect = &peobj.sect[i]
|
||||||
if sect.sh.Characteristics&IMAGE_SCN_MEM_DISCARDABLE != 0 {
|
if sect.sh.Characteristics&IMAGE_SCN_MEM_DISCARDABLE != 0 {
|
||||||
continue
|
continue
|
||||||
|
|
@ -277,7 +272,7 @@ func ldpe(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// load relocations
|
// load relocations
|
||||||
for i = 0; uint(i) < peobj.nsect; i++ {
|
for i := 0; uint(i) < peobj.nsect; i++ {
|
||||||
rsect = &peobj.sect[i]
|
rsect = &peobj.sect[i]
|
||||||
if rsect.sym == nil || rsect.sh.NumberOfRelocations == 0 {
|
if rsect.sym == nil || rsect.sh.NumberOfRelocations == 0 {
|
||||||
continue
|
continue
|
||||||
|
|
@ -298,12 +293,9 @@ func ldpe(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
if Bread(f, symbuf[:10]) != 10 {
|
if Bread(f, symbuf[:10]) != 10 {
|
||||||
goto bad
|
goto bad
|
||||||
}
|
}
|
||||||
var rva uint32
|
rva := Le32(symbuf[0:])
|
||||||
var symindex uint32
|
symindex := Le32(symbuf[4:])
|
||||||
var type_ uint16
|
type_ := Le16(symbuf[8:])
|
||||||
rva = Le32(symbuf[0:])
|
|
||||||
symindex = Le32(symbuf[4:])
|
|
||||||
type_ = Le16(symbuf[8:])
|
|
||||||
if err = readpesym(peobj, int(symindex), &sym); err != nil {
|
if err = readpesym(peobj, int(symindex), &sym); err != nil {
|
||||||
goto bad
|
goto bad
|
||||||
}
|
}
|
||||||
|
|
@ -360,7 +352,7 @@ func ldpe(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// enter sub-symbols into symbol table.
|
// enter sub-symbols into symbol table.
|
||||||
for i = 0; uint(i) < peobj.npesym; i++ {
|
for i := 0; uint(i) < peobj.npesym; i++ {
|
||||||
if peobj.pesym[i].name == "" {
|
if peobj.pesym[i].name == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -429,7 +421,7 @@ func ldpe(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
|
|
||||||
// Sort outer lists by address, adding to textp.
|
// Sort outer lists by address, adding to textp.
|
||||||
// This keeps textp in increasing address order.
|
// This keeps textp in increasing address order.
|
||||||
for i = 0; uint(i) < peobj.nsect; i++ {
|
for i := 0; uint(i) < peobj.nsect; i++ {
|
||||||
s = peobj.sect[i].sym
|
s = peobj.sect[i].sym
|
||||||
if s == nil {
|
if s == nil {
|
||||||
continue
|
continue
|
||||||
|
|
@ -486,18 +478,15 @@ func issect(s *PeSym) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func readpesym(peobj *PeObj, i int, y **PeSym) (err error) {
|
func readpesym(peobj *PeObj, i int, y **PeSym) (err error) {
|
||||||
var s *LSym
|
|
||||||
var sym *PeSym
|
|
||||||
var name string
|
|
||||||
|
|
||||||
if uint(i) >= peobj.npesym || i < 0 {
|
if uint(i) >= peobj.npesym || i < 0 {
|
||||||
err = fmt.Errorf("invalid pe symbol index")
|
err = fmt.Errorf("invalid pe symbol index")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
sym = &peobj.pesym[i]
|
sym := &peobj.pesym[i]
|
||||||
*y = sym
|
*y = sym
|
||||||
|
|
||||||
|
var name string
|
||||||
if issect(sym) {
|
if issect(sym) {
|
||||||
name = peobj.sect[sym.sectnum-1].sym.Name
|
name = peobj.sect[sym.sectnum-1].sym.Name
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -515,6 +504,7 @@ func readpesym(peobj *PeObj, i int, y **PeSym) (err error) {
|
||||||
name = name[:i]
|
name = name[:i]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var s *LSym
|
||||||
switch sym.type_ {
|
switch sym.type_ {
|
||||||
default:
|
default:
|
||||||
err = fmt.Errorf("%s: invalid symbol type %d", sym.name, sym.type_)
|
err = fmt.Errorf("%s: invalid symbol type %d", sym.name, sym.type_)
|
||||||
|
|
|
||||||
|
|
@ -294,16 +294,13 @@ func mayberemoveoutfile() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func libinit() {
|
func libinit() {
|
||||||
var suffix string
|
|
||||||
var suffixsep string
|
|
||||||
|
|
||||||
Funcalign = Thearch.Funcalign
|
Funcalign = Thearch.Funcalign
|
||||||
mywhatsys() // get goroot, goarch, goos
|
mywhatsys() // get goroot, goarch, goos
|
||||||
|
|
||||||
// add goroot to the end of the libdir list.
|
// add goroot to the end of the libdir list.
|
||||||
suffix = ""
|
suffix := ""
|
||||||
|
|
||||||
suffixsep = ""
|
suffixsep := ""
|
||||||
if flag_installsuffix != "" {
|
if flag_installsuffix != "" {
|
||||||
suffixsep = "_"
|
suffixsep = "_"
|
||||||
suffix = flag_installsuffix
|
suffix = flag_installsuffix
|
||||||
|
|
@ -353,11 +350,9 @@ func Errorexit() {
|
||||||
|
|
||||||
func loadinternal(name string) {
|
func loadinternal(name string) {
|
||||||
var pname string
|
var pname string
|
||||||
var i int
|
|
||||||
var found int
|
|
||||||
|
|
||||||
found = 0
|
found := 0
|
||||||
for i = 0; i < len(Ctxt.Libdir); i++ {
|
for i := 0; i < len(Ctxt.Libdir); i++ {
|
||||||
pname = fmt.Sprintf("%s/%s.a", Ctxt.Libdir[i], name)
|
pname = fmt.Sprintf("%s/%s.a", Ctxt.Libdir[i], name)
|
||||||
if Debug['v'] != 0 {
|
if Debug['v'] != 0 {
|
||||||
fmt.Fprintf(&Bso, "searching for %s.a in %s\n", name, pname)
|
fmt.Fprintf(&Bso, "searching for %s.a in %s\n", name, pname)
|
||||||
|
|
@ -375,15 +370,8 @@ func loadinternal(name string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadlib() {
|
func loadlib() {
|
||||||
var i int
|
|
||||||
var w int
|
|
||||||
var x int
|
|
||||||
var s *LSym
|
|
||||||
var tlsg *LSym
|
|
||||||
var cgostrsym string
|
|
||||||
|
|
||||||
if Flag_shared != 0 {
|
if Flag_shared != 0 {
|
||||||
s = Linklookup(Ctxt, "runtime.islibrary", 0)
|
s := Linklookup(Ctxt, "runtime.islibrary", 0)
|
||||||
s.Dupok = 1
|
s.Dupok = 1
|
||||||
Adduint8(Ctxt, s, 1)
|
Adduint8(Ctxt, s, 1)
|
||||||
}
|
}
|
||||||
|
|
@ -396,6 +384,7 @@ func loadlib() {
|
||||||
loadinternal("runtime/race")
|
loadinternal("runtime/race")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var i int
|
||||||
for i = 0; i < len(Ctxt.Library); i++ {
|
for i = 0; i < len(Ctxt.Library); i++ {
|
||||||
if Debug['v'] > 1 {
|
if Debug['v'] > 1 {
|
||||||
fmt.Fprintf(&Bso, "%5.2f autolib: %s (from %s)\n", obj.Cputime(), Ctxt.Library[i].File, Ctxt.Library[i].Objref)
|
fmt.Fprintf(&Bso, "%5.2f autolib: %s (from %s)\n", obj.Cputime(), Ctxt.Library[i].File, Ctxt.Library[i].Objref)
|
||||||
|
|
@ -438,7 +427,7 @@ func loadlib() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pretend that we really imported the package.
|
// Pretend that we really imported the package.
|
||||||
s = Linklookup(Ctxt, "go.importpath.runtime/cgo.", 0)
|
s := Linklookup(Ctxt, "go.importpath.runtime/cgo.", 0)
|
||||||
|
|
||||||
s.Type = SDATA
|
s.Type = SDATA
|
||||||
s.Dupok = 1
|
s.Dupok = 1
|
||||||
|
|
@ -446,10 +435,10 @@ func loadlib() {
|
||||||
|
|
||||||
// Provided by the code that imports the package.
|
// Provided by the code that imports the package.
|
||||||
// Since we are simulating the import, we have to provide this string.
|
// Since we are simulating the import, we have to provide this string.
|
||||||
cgostrsym = "go.string.\"runtime/cgo\""
|
cgostrsym := "go.string.\"runtime/cgo\""
|
||||||
|
|
||||||
if Linkrlookup(Ctxt, cgostrsym, 0) == nil {
|
if Linkrlookup(Ctxt, cgostrsym, 0) == nil {
|
||||||
s = Linklookup(Ctxt, cgostrsym, 0)
|
s := Linklookup(Ctxt, cgostrsym, 0)
|
||||||
s.Type = SRODATA
|
s.Type = SRODATA
|
||||||
s.Reachable = true
|
s.Reachable = true
|
||||||
addstrdata(cgostrsym, "runtime/cgo")
|
addstrdata(cgostrsym, "runtime/cgo")
|
||||||
|
|
@ -459,7 +448,7 @@ func loadlib() {
|
||||||
if Linkmode == LinkInternal {
|
if Linkmode == LinkInternal {
|
||||||
// Drop all the cgo_import_static declarations.
|
// Drop all the cgo_import_static declarations.
|
||||||
// Turns out we won't be needing them.
|
// Turns out we won't be needing them.
|
||||||
for s = Ctxt.Allsym; s != nil; s = s.Allsym {
|
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
||||||
if s.Type == SHOSTOBJ {
|
if s.Type == SHOSTOBJ {
|
||||||
// If a symbol was marked both
|
// If a symbol was marked both
|
||||||
// cgo_import_static and cgo_import_dynamic,
|
// cgo_import_static and cgo_import_dynamic,
|
||||||
|
|
@ -474,7 +463,7 @@ func loadlib() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsg = Linklookup(Ctxt, "runtime.tlsg", 0)
|
tlsg := Linklookup(Ctxt, "runtime.tlsg", 0)
|
||||||
|
|
||||||
// For most ports, runtime.tlsg is a placeholder symbol for TLS
|
// For most ports, runtime.tlsg is a placeholder symbol for TLS
|
||||||
// relocation. However, the Android and Darwin arm ports need it
|
// relocation. However, the Android and Darwin arm ports need it
|
||||||
|
|
@ -492,13 +481,13 @@ func loadlib() {
|
||||||
Ctxt.Tlsg = tlsg
|
Ctxt.Tlsg = tlsg
|
||||||
|
|
||||||
// Now that we know the link mode, trim the dynexp list.
|
// Now that we know the link mode, trim the dynexp list.
|
||||||
x = CgoExportDynamic
|
x := CgoExportDynamic
|
||||||
|
|
||||||
if Linkmode == LinkExternal {
|
if Linkmode == LinkExternal {
|
||||||
x = CgoExportStatic
|
x = CgoExportStatic
|
||||||
}
|
}
|
||||||
w = 0
|
w := 0
|
||||||
for i = 0; i < len(dynexp); i++ {
|
for i := 0; i < len(dynexp); i++ {
|
||||||
if int(dynexp[i].Cgoexport)&x != 0 {
|
if int(dynexp[i].Cgoexport)&x != 0 {
|
||||||
dynexp[w] = dynexp[i]
|
dynexp[w] = dynexp[i]
|
||||||
w++
|
w++
|
||||||
|
|
@ -564,12 +553,6 @@ func nextar(bp *Biobuf, off int64, a *ArHdr) int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func objfile(file string, pkg string) {
|
func objfile(file string, pkg string) {
|
||||||
var off int64
|
|
||||||
var l int64
|
|
||||||
var f *Biobuf
|
|
||||||
var pname string
|
|
||||||
var arhdr ArHdr
|
|
||||||
|
|
||||||
pkg = pathtoprefix(pkg)
|
pkg = pathtoprefix(pkg)
|
||||||
|
|
||||||
if Debug['v'] > 1 {
|
if Debug['v'] > 1 {
|
||||||
|
|
@ -577,6 +560,7 @@ func objfile(file string, pkg string) {
|
||||||
}
|
}
|
||||||
Bflush(&Bso)
|
Bflush(&Bso)
|
||||||
var err error
|
var err error
|
||||||
|
var f *Biobuf
|
||||||
f, err = Bopenr(file)
|
f, err = Bopenr(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Diag("cannot open file %s: %v", file, err)
|
Diag("cannot open file %s: %v", file, err)
|
||||||
|
|
@ -586,7 +570,7 @@ func objfile(file string, pkg string) {
|
||||||
magbuf := make([]byte, len(ARMAG))
|
magbuf := make([]byte, len(ARMAG))
|
||||||
if Bread(f, magbuf) != len(magbuf) || !strings.HasPrefix(string(magbuf), ARMAG) {
|
if Bread(f, magbuf) != len(magbuf) || !strings.HasPrefix(string(magbuf), ARMAG) {
|
||||||
/* load it as a regular file */
|
/* load it as a regular file */
|
||||||
l = Bseek(f, 0, 2)
|
l := Bseek(f, 0, 2)
|
||||||
|
|
||||||
Bseek(f, 0, 0)
|
Bseek(f, 0, 0)
|
||||||
ldobj(f, pkg, l, file, file, FileObj)
|
ldobj(f, pkg, l, file, file, FileObj)
|
||||||
|
|
@ -596,9 +580,11 @@ func objfile(file string, pkg string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip over optional __.GOSYMDEF and process __.PKGDEF */
|
/* skip over optional __.GOSYMDEF and process __.PKGDEF */
|
||||||
off = Boffset(f)
|
off := Boffset(f)
|
||||||
|
|
||||||
l = nextar(f, off, &arhdr)
|
var arhdr ArHdr
|
||||||
|
l := nextar(f, off, &arhdr)
|
||||||
|
var pname string
|
||||||
if l <= 0 {
|
if l <= 0 {
|
||||||
Diag("%s: short read on archive file symbol header", file)
|
Diag("%s: short read on archive file symbol header", file)
|
||||||
goto out
|
goto out
|
||||||
|
|
@ -684,12 +670,8 @@ var internalpkg = []string{
|
||||||
}
|
}
|
||||||
|
|
||||||
func ldhostobj(ld func(*Biobuf, string, int64, string), f *Biobuf, pkg string, length int64, pn string, file string) {
|
func ldhostobj(ld func(*Biobuf, string, int64, string), f *Biobuf, pkg string, length int64, pn string, file string) {
|
||||||
var i int
|
isinternal := 0
|
||||||
var isinternal int
|
for i := 0; i < len(internalpkg); i++ {
|
||||||
var h *Hostobj
|
|
||||||
|
|
||||||
isinternal = 0
|
|
||||||
for i = 0; i < len(internalpkg); i++ {
|
|
||||||
if pkg == internalpkg[i] {
|
if pkg == internalpkg[i] {
|
||||||
isinternal = 1
|
isinternal = 1
|
||||||
break
|
break
|
||||||
|
|
@ -713,7 +695,7 @@ func ldhostobj(ld func(*Biobuf, string, int64, string), f *Biobuf, pkg string, l
|
||||||
}
|
}
|
||||||
|
|
||||||
hostobj = append(hostobj, Hostobj{})
|
hostobj = append(hostobj, Hostobj{})
|
||||||
h = &hostobj[len(hostobj)-1]
|
h := &hostobj[len(hostobj)-1]
|
||||||
h.ld = ld
|
h.ld = ld
|
||||||
h.pkg = pkg
|
h.pkg = pkg
|
||||||
h.pn = pn
|
h.pn = pn
|
||||||
|
|
@ -723,11 +705,10 @@ func ldhostobj(ld func(*Biobuf, string, int64, string), f *Biobuf, pkg string, l
|
||||||
}
|
}
|
||||||
|
|
||||||
func hostobjs() {
|
func hostobjs() {
|
||||||
var i int
|
|
||||||
var f *Biobuf
|
var f *Biobuf
|
||||||
var h *Hostobj
|
var h *Hostobj
|
||||||
|
|
||||||
for i = 0; i < len(hostobj); i++ {
|
for i := 0; i < len(hostobj); i++ {
|
||||||
h = &hostobj[i]
|
h = &hostobj[i]
|
||||||
var err error
|
var err error
|
||||||
f, err = Bopenr(h.file)
|
f, err = Bopenr(h.file)
|
||||||
|
|
@ -750,8 +731,6 @@ func rmtemp() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func hostlinksetup() {
|
func hostlinksetup() {
|
||||||
var p string
|
|
||||||
|
|
||||||
if Linkmode != LinkExternal {
|
if Linkmode != LinkExternal {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -769,7 +748,7 @@ func hostlinksetup() {
|
||||||
// change our output to temporary object file
|
// change our output to temporary object file
|
||||||
cout.Close()
|
cout.Close()
|
||||||
|
|
||||||
p = fmt.Sprintf("%s/go.o", tmpdir)
|
p := fmt.Sprintf("%s/go.o", tmpdir)
|
||||||
var err error
|
var err error
|
||||||
cout, err = os.OpenFile(p, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0775)
|
cout, err = os.OpenFile(p, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0775)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -783,14 +762,6 @@ func hostlinksetup() {
|
||||||
var hostlink_buf = make([]byte, 64*1024)
|
var hostlink_buf = make([]byte, 64*1024)
|
||||||
|
|
||||||
func hostlink() {
|
func hostlink() {
|
||||||
var p string
|
|
||||||
var argv []string
|
|
||||||
var i int
|
|
||||||
var n int
|
|
||||||
var length int
|
|
||||||
var h *Hostobj
|
|
||||||
var f *Biobuf
|
|
||||||
|
|
||||||
if Linkmode != LinkExternal || nerrors > 0 {
|
if Linkmode != LinkExternal || nerrors > 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -798,6 +769,7 @@ func hostlink() {
|
||||||
if extld == "" {
|
if extld == "" {
|
||||||
extld = "gcc"
|
extld = "gcc"
|
||||||
}
|
}
|
||||||
|
var argv []string
|
||||||
argv = append(argv, extld)
|
argv = append(argv, extld)
|
||||||
switch Thearch.Thechar {
|
switch Thearch.Thechar {
|
||||||
case '8':
|
case '8':
|
||||||
|
|
@ -851,7 +823,12 @@ func hostlink() {
|
||||||
|
|
||||||
// already wrote main object file
|
// already wrote main object file
|
||||||
// copy host objects to temporary directory
|
// copy host objects to temporary directory
|
||||||
for i = 0; i < len(hostobj); i++ {
|
var f *Biobuf
|
||||||
|
var h *Hostobj
|
||||||
|
var length int
|
||||||
|
var n int
|
||||||
|
var p string
|
||||||
|
for i := 0; i < len(hostobj); i++ {
|
||||||
h = &hostobj[i]
|
h = &hostobj[i]
|
||||||
var err error
|
var err error
|
||||||
f, err = Bopenr(h.file)
|
f, err = Bopenr(h.file)
|
||||||
|
|
@ -886,7 +863,7 @@ func hostlink() {
|
||||||
length -= n
|
length -= n
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = w.Close(); err != nil {
|
if err := w.Close(); err != nil {
|
||||||
Ctxt.Cursym = nil
|
Ctxt.Cursym = nil
|
||||||
Diag("cannot write %s: %v", p, err)
|
Diag("cannot write %s: %v", p, err)
|
||||||
Errorexit()
|
Errorexit()
|
||||||
|
|
@ -896,6 +873,7 @@ func hostlink() {
|
||||||
}
|
}
|
||||||
|
|
||||||
argv = append(argv, fmt.Sprintf("%s/go.o", tmpdir))
|
argv = append(argv, fmt.Sprintf("%s/go.o", tmpdir))
|
||||||
|
var i int
|
||||||
for i = 0; i < len(ldflag); i++ {
|
for i = 0; i < len(ldflag); i++ {
|
||||||
argv = append(argv, ldflag[i])
|
argv = append(argv, ldflag[i])
|
||||||
}
|
}
|
||||||
|
|
@ -935,30 +913,18 @@ func hostlink() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ldobj(f *Biobuf, pkg string, length int64, pn string, file string, whence int) {
|
func ldobj(f *Biobuf, pkg string, length int64, pn string, file string, whence int) {
|
||||||
var line string
|
eof := Boffset(f) + length
|
||||||
var c1 int
|
|
||||||
var c2 int
|
|
||||||
var c3 int
|
|
||||||
var c4 int
|
|
||||||
var magic uint32
|
|
||||||
var import0 int64
|
|
||||||
var import1 int64
|
|
||||||
var eof int64
|
|
||||||
var start int64
|
|
||||||
var t string
|
|
||||||
|
|
||||||
eof = Boffset(f) + length
|
|
||||||
|
|
||||||
pn = pn
|
pn = pn
|
||||||
|
|
||||||
start = Boffset(f)
|
start := Boffset(f)
|
||||||
c1 = Bgetc(f)
|
c1 := Bgetc(f)
|
||||||
c2 = Bgetc(f)
|
c2 := Bgetc(f)
|
||||||
c3 = Bgetc(f)
|
c3 := Bgetc(f)
|
||||||
c4 = Bgetc(f)
|
c4 := Bgetc(f)
|
||||||
Bseek(f, start, 0)
|
Bseek(f, start, 0)
|
||||||
|
|
||||||
magic = uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4)
|
magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4)
|
||||||
if magic == 0x7f454c46 { // \x7F E L F
|
if magic == 0x7f454c46 { // \x7F E L F
|
||||||
ldhostobj(ldelf, f, pkg, length, pn, file)
|
ldhostobj(ldelf, f, pkg, length, pn, file)
|
||||||
return
|
return
|
||||||
|
|
@ -975,8 +941,11 @@ func ldobj(f *Biobuf, pkg string, length int64, pn string, file string, whence i
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check the header */
|
/* check the header */
|
||||||
line = Brdline(f, '\n')
|
line := Brdline(f, '\n')
|
||||||
|
|
||||||
|
var import0 int64
|
||||||
|
var import1 int64
|
||||||
|
var t string
|
||||||
if line == "" {
|
if line == "" {
|
||||||
if Blinelen(f) > 0 {
|
if Blinelen(f) > 0 {
|
||||||
Diag("%s: not an object file", pn)
|
Diag("%s: not an object file", pn)
|
||||||
|
|
@ -1055,9 +1024,7 @@ eof:
|
||||||
}
|
}
|
||||||
|
|
||||||
func zerosig(sp string) {
|
func zerosig(sp string) {
|
||||||
var s *LSym
|
s := Linklookup(Ctxt, sp, 0)
|
||||||
|
|
||||||
s = Linklookup(Ctxt, sp, 0)
|
|
||||||
s.Sig = 0
|
s.Sig = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1097,44 +1064,40 @@ func pathtoprefix(s string) string {
|
||||||
for i := 0; i < len(s); i++ {
|
for i := 0; i < len(s); i++ {
|
||||||
c := s[i]
|
c := s[i]
|
||||||
if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F {
|
if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F {
|
||||||
goto escape
|
var buf bytes.Buffer
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
c := s[i]
|
||||||
|
if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F {
|
||||||
|
fmt.Fprintf(&buf, "%%%02x", c)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
buf.WriteByte(c)
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
|
|
||||||
escape:
|
|
||||||
var buf bytes.Buffer
|
|
||||||
for i := 0; i < len(s); i++ {
|
|
||||||
c := s[i]
|
|
||||||
if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F {
|
|
||||||
fmt.Fprintf(&buf, "%%%02x", c)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
buf.WriteByte(c)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func iconv(p string) string {
|
func iconv(p string) string {
|
||||||
var fp string
|
|
||||||
|
|
||||||
if p == "" {
|
if p == "" {
|
||||||
|
var fp string
|
||||||
fp += "<nil>"
|
fp += "<nil>"
|
||||||
return fp
|
return fp
|
||||||
}
|
}
|
||||||
|
|
||||||
p = pathtoprefix(p)
|
p = pathtoprefix(p)
|
||||||
|
var fp string
|
||||||
fp += p
|
fp += p
|
||||||
return fp
|
return fp
|
||||||
}
|
}
|
||||||
|
|
||||||
func addsection(seg *Segment, name string, rwx int) *Section {
|
func addsection(seg *Segment, name string, rwx int) *Section {
|
||||||
var l **Section
|
var l **Section
|
||||||
var sect *Section
|
|
||||||
|
|
||||||
for l = &seg.Sect; *l != nil; l = &(*l).Next {
|
for l = &seg.Sect; *l != nil; l = &(*l).Next {
|
||||||
}
|
}
|
||||||
sect = new(Section)
|
sect := new(Section)
|
||||||
sect.Rwx = uint8(rwx)
|
sect.Rwx = uint8(rwx)
|
||||||
sect.Name = name
|
sect.Name = name
|
||||||
sect.Seg = seg
|
sect.Seg = seg
|
||||||
|
|
@ -1197,7 +1160,6 @@ func callsize() int {
|
||||||
|
|
||||||
func dostkcheck() {
|
func dostkcheck() {
|
||||||
var ch Chain
|
var ch Chain
|
||||||
var s *LSym
|
|
||||||
|
|
||||||
morestack = Linklookup(Ctxt, "runtime.morestack", 0)
|
morestack = Linklookup(Ctxt, "runtime.morestack", 0)
|
||||||
newstack = Linklookup(Ctxt, "runtime.newstack", 0)
|
newstack = Linklookup(Ctxt, "runtime.newstack", 0)
|
||||||
|
|
@ -1215,7 +1177,7 @@ func dostkcheck() {
|
||||||
|
|
||||||
// Check every function, but do the nosplit functions in a first pass,
|
// Check every function, but do the nosplit functions in a first pass,
|
||||||
// to make the printed failure chains as short as possible.
|
// to make the printed failure chains as short as possible.
|
||||||
for s = Ctxt.Textp; s != nil; s = s.Next {
|
for s := Ctxt.Textp; s != nil; s = s.Next {
|
||||||
// runtime.racesymbolizethunk is called from gcc-compiled C
|
// runtime.racesymbolizethunk is called from gcc-compiled C
|
||||||
// code running on the operating system thread stack.
|
// code running on the operating system thread stack.
|
||||||
// It uses more than the usual amount of stack but that's okay.
|
// It uses more than the usual amount of stack but that's okay.
|
||||||
|
|
@ -1230,7 +1192,7 @@ func dostkcheck() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for s = Ctxt.Textp; s != nil; s = s.Next {
|
for s := Ctxt.Textp; s != nil; s = s.Next {
|
||||||
if s.Nosplit == 0 {
|
if s.Nosplit == 0 {
|
||||||
Ctxt.Cursym = s
|
Ctxt.Cursym = s
|
||||||
ch.sym = s
|
ch.sym = s
|
||||||
|
|
@ -1240,17 +1202,8 @@ func dostkcheck() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func stkcheck(up *Chain, depth int) int {
|
func stkcheck(up *Chain, depth int) int {
|
||||||
var ch Chain
|
limit := up.limit
|
||||||
var ch1 Chain
|
s := up.sym
|
||||||
var s *LSym
|
|
||||||
var limit int
|
|
||||||
var r *Reloc
|
|
||||||
var ri int
|
|
||||||
var endr int
|
|
||||||
var pcsp Pciter
|
|
||||||
|
|
||||||
limit = up.limit
|
|
||||||
s = up.sym
|
|
||||||
|
|
||||||
// Don't duplicate work: only need to consider each
|
// Don't duplicate work: only need to consider each
|
||||||
// function at top of safe zone once.
|
// function at top of safe zone once.
|
||||||
|
|
@ -1288,12 +1241,16 @@ func stkcheck(up *Chain, depth int) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ch Chain
|
||||||
ch.up = up
|
ch.up = up
|
||||||
|
|
||||||
// Walk through sp adjustments in function, consuming relocs.
|
// Walk through sp adjustments in function, consuming relocs.
|
||||||
ri = 0
|
ri := 0
|
||||||
|
|
||||||
endr = len(s.R)
|
endr := len(s.R)
|
||||||
|
var ch1 Chain
|
||||||
|
var pcsp Pciter
|
||||||
|
var r *Reloc
|
||||||
for pciterinit(Ctxt, &pcsp, &s.Pcln.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
|
for pciterinit(Ctxt, &pcsp, &s.Pcln.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
|
||||||
// pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
|
// pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
|
||||||
|
|
||||||
|
|
@ -1384,16 +1341,12 @@ func stkprint(ch *Chain, limit int) {
|
||||||
func Yconv(s *LSym) string {
|
func Yconv(s *LSym) string {
|
||||||
var fp string
|
var fp string
|
||||||
|
|
||||||
var fmt_ string
|
|
||||||
var i int
|
|
||||||
var str string
|
|
||||||
|
|
||||||
if s == nil {
|
if s == nil {
|
||||||
fp += fmt.Sprintf("<nil>")
|
fp += fmt.Sprintf("<nil>")
|
||||||
} else {
|
} else {
|
||||||
fmt_ = ""
|
fmt_ := ""
|
||||||
fmt_ += fmt.Sprintf("%s @0x%08x [%d]", s.Name, int64(s.Value), int64(s.Size))
|
fmt_ += fmt.Sprintf("%s @0x%08x [%d]", s.Name, int64(s.Value), int64(s.Size))
|
||||||
for i = 0; int64(i) < s.Size; i++ {
|
for i := 0; int64(i) < s.Size; i++ {
|
||||||
if i%8 == 0 {
|
if i%8 == 0 {
|
||||||
fmt_ += fmt.Sprintf("\n\t0x%04x ", i)
|
fmt_ += fmt.Sprintf("\n\t0x%04x ", i)
|
||||||
}
|
}
|
||||||
|
|
@ -1401,11 +1354,11 @@ func Yconv(s *LSym) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt_ += fmt.Sprintf("\n")
|
fmt_ += fmt.Sprintf("\n")
|
||||||
for i = 0; i < len(s.R); i++ {
|
for i := 0; i < len(s.R); i++ {
|
||||||
fmt_ += fmt.Sprintf("\t0x%04x[%x] %d %s[%x]\n", s.R[i].Off, s.R[i].Siz, s.R[i].Type, s.R[i].Sym.Name, int64(s.R[i].Add))
|
fmt_ += fmt.Sprintf("\t0x%04x[%x] %d %s[%x]\n", s.R[i].Off, s.R[i].Siz, s.R[i].Type, s.R[i].Sym.Name, int64(s.R[i].Add))
|
||||||
}
|
}
|
||||||
|
|
||||||
str = fmt_
|
str := fmt_
|
||||||
fp += str
|
fp += str
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1439,9 +1392,7 @@ func usage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func setheadtype(s string) {
|
func setheadtype(s string) {
|
||||||
var h int
|
h := headtype(s)
|
||||||
|
|
||||||
h = headtype(s)
|
|
||||||
if h < 0 {
|
if h < 0 {
|
||||||
fmt.Fprintf(os.Stderr, "unknown header type -H %s\n", s)
|
fmt.Fprintf(os.Stderr, "unknown header type -H %s\n", s)
|
||||||
Errorexit()
|
Errorexit()
|
||||||
|
|
@ -1462,13 +1413,9 @@ func doversion() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
|
func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
|
||||||
var a *Auto
|
|
||||||
var s *LSym
|
|
||||||
var off int32
|
|
||||||
|
|
||||||
// These symbols won't show up in the first loop below because we
|
// These symbols won't show up in the first loop below because we
|
||||||
// skip STEXT symbols. Normal STEXT symbols are emitted by walking textp.
|
// skip STEXT symbols. Normal STEXT symbols are emitted by walking textp.
|
||||||
s = Linklookup(Ctxt, "runtime.text", 0)
|
s := Linklookup(Ctxt, "runtime.text", 0)
|
||||||
|
|
||||||
if s.Type == STEXT {
|
if s.Type == STEXT {
|
||||||
put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
|
put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
|
||||||
|
|
@ -1478,7 +1425,7 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
|
||||||
put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
|
put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
for s = Ctxt.Allsym; s != nil; s = s.Allsym {
|
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
||||||
if s.Hide != 0 || (s.Name[0] == '.' && s.Version == 0 && s.Name != ".rathole") {
|
if s.Hide != 0 || (s.Name[0] == '.' && s.Version == 0 && s.Name != ".rathole") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -1518,7 +1465,9 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for s = Ctxt.Textp; s != nil; s = s.Next {
|
var a *Auto
|
||||||
|
var off int32
|
||||||
|
for s := Ctxt.Textp; s != nil; s = s.Next {
|
||||||
put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), s.Gotype)
|
put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), s.Gotype)
|
||||||
|
|
||||||
// NOTE(ality): acid can't produce a stack trace without .frame symbols
|
// NOTE(ality): acid can't produce a stack trace without .frame symbols
|
||||||
|
|
@ -1568,9 +1517,7 @@ func Symaddr(s *LSym) int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func xdefine(p string, t int, v int64) {
|
func xdefine(p string, t int, v int64) {
|
||||||
var s *LSym
|
s := Linklookup(Ctxt, p, 0)
|
||||||
|
|
||||||
s = Linklookup(Ctxt, p, 0)
|
|
||||||
s.Type = int16(t)
|
s.Type = int16(t)
|
||||||
s.Value = v
|
s.Value = v
|
||||||
s.Reachable = true
|
s.Reachable = true
|
||||||
|
|
@ -1589,14 +1536,11 @@ func datoff(addr int64) int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Entryvalue() int64 {
|
func Entryvalue() int64 {
|
||||||
var a string
|
a := INITENTRY
|
||||||
var s *LSym
|
|
||||||
|
|
||||||
a = INITENTRY
|
|
||||||
if a[0] >= '0' && a[0] <= '9' {
|
if a[0] >= '0' && a[0] <= '9' {
|
||||||
return atolwhex(a)
|
return atolwhex(a)
|
||||||
}
|
}
|
||||||
s = Linklookup(Ctxt, a, 0)
|
s := Linklookup(Ctxt, a, 0)
|
||||||
if s.Type == 0 {
|
if s.Type == 0 {
|
||||||
return INITTEXT
|
return INITTEXT
|
||||||
}
|
}
|
||||||
|
|
@ -1607,11 +1551,10 @@ func Entryvalue() int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func undefsym(s *LSym) {
|
func undefsym(s *LSym) {
|
||||||
var i int
|
|
||||||
var r *Reloc
|
var r *Reloc
|
||||||
|
|
||||||
Ctxt.Cursym = s
|
Ctxt.Cursym = s
|
||||||
for i = 0; i < len(s.R); i++ {
|
for i := 0; i < len(s.R); i++ {
|
||||||
r = &s.R[i]
|
r = &s.R[i]
|
||||||
if r.Sym == nil { // happens for some external ARM relocs
|
if r.Sym == nil { // happens for some external ARM relocs
|
||||||
continue
|
continue
|
||||||
|
|
@ -1626,12 +1569,10 @@ func undefsym(s *LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func undef() {
|
func undef() {
|
||||||
var s *LSym
|
for s := Ctxt.Textp; s != nil; s = s.Next {
|
||||||
|
|
||||||
for s = Ctxt.Textp; s != nil; s = s.Next {
|
|
||||||
undefsym(s)
|
undefsym(s)
|
||||||
}
|
}
|
||||||
for s = datap; s != nil; s = s.Next {
|
for s := datap; s != nil; s = s.Next {
|
||||||
undefsym(s)
|
undefsym(s)
|
||||||
}
|
}
|
||||||
if nerrors > 0 {
|
if nerrors > 0 {
|
||||||
|
|
@ -1640,15 +1581,13 @@ func undef() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func callgraph() {
|
func callgraph() {
|
||||||
var s *LSym
|
|
||||||
var r *Reloc
|
|
||||||
var i int
|
|
||||||
|
|
||||||
if Debug['c'] == 0 {
|
if Debug['c'] == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for s = Ctxt.Textp; s != nil; s = s.Next {
|
var i int
|
||||||
|
var r *Reloc
|
||||||
|
for s := Ctxt.Textp; s != nil; s = s.Next {
|
||||||
for i = 0; i < len(s.R); i++ {
|
for i = 0; i < len(s.R); i++ {
|
||||||
r = &s.R[i]
|
r = &s.R[i]
|
||||||
if r.Sym == nil {
|
if r.Sym == nil {
|
||||||
|
|
@ -1678,11 +1617,6 @@ func Diag(format string, args ...interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkgo() {
|
func checkgo() {
|
||||||
var s *LSym
|
|
||||||
var r *Reloc
|
|
||||||
var i int
|
|
||||||
var changed int
|
|
||||||
|
|
||||||
if Debug['C'] == 0 {
|
if Debug['C'] == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -1691,6 +1625,10 @@ func checkgo() {
|
||||||
// which would simplify this logic quite a bit.
|
// which would simplify this logic quite a bit.
|
||||||
|
|
||||||
// Mark every Go-called C function with cfunc=2, recursively.
|
// Mark every Go-called C function with cfunc=2, recursively.
|
||||||
|
var changed int
|
||||||
|
var i int
|
||||||
|
var r *Reloc
|
||||||
|
var s *LSym
|
||||||
for {
|
for {
|
||||||
changed = 0
|
changed = 0
|
||||||
for s = Ctxt.Textp; s != nil; s = s.Next {
|
for s = Ctxt.Textp; s != nil; s = s.Next {
|
||||||
|
|
@ -1716,7 +1654,7 @@ func checkgo() {
|
||||||
|
|
||||||
// Complain about Go-called C functions that can split the stack
|
// Complain about Go-called C functions that can split the stack
|
||||||
// (that can be preempted for garbage collection or trigger a stack copy).
|
// (that can be preempted for garbage collection or trigger a stack copy).
|
||||||
for s = Ctxt.Textp; s != nil; s = s.Next {
|
for s := Ctxt.Textp; s != nil; s = s.Next {
|
||||||
if s.Cfunc == 0 || (s.Cfunc == 2 && s.Nosplit != 0) {
|
if s.Cfunc == 0 || (s.Cfunc == 2 && s.Nosplit != 0) {
|
||||||
for i = 0; i < len(s.R); i++ {
|
for i = 0; i < len(s.R); i++ {
|
||||||
r = &s.R[i]
|
r = &s.R[i]
|
||||||
|
|
@ -1736,13 +1674,11 @@ func checkgo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Rnd(v int64, r int64) int64 {
|
func Rnd(v int64, r int64) int64 {
|
||||||
var c int64
|
|
||||||
|
|
||||||
if r <= 0 {
|
if r <= 0 {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
v += r - 1
|
v += r - 1
|
||||||
c = v % r
|
c := v % r
|
||||||
if c < 0 {
|
if c < 0 {
|
||||||
c += r
|
c += r
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -156,14 +156,12 @@ func newMachoLoad(type_ uint32, ndata uint32) *MachoLoad {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMachoSeg(name string, msect int) *MachoSeg {
|
func newMachoSeg(name string, msect int) *MachoSeg {
|
||||||
var s *MachoSeg
|
|
||||||
|
|
||||||
if nseg >= len(seg) {
|
if nseg >= len(seg) {
|
||||||
Diag("too many segs")
|
Diag("too many segs")
|
||||||
Errorexit()
|
Errorexit()
|
||||||
}
|
}
|
||||||
|
|
||||||
s = &seg[nseg]
|
s := &seg[nseg]
|
||||||
nseg++
|
nseg++
|
||||||
s.name = name
|
s.name = name
|
||||||
s.msect = uint32(msect)
|
s.msect = uint32(msect)
|
||||||
|
|
@ -172,14 +170,12 @@ func newMachoSeg(name string, msect int) *MachoSeg {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMachoSect(seg *MachoSeg, name string, segname string) *MachoSect {
|
func newMachoSect(seg *MachoSeg, name string, segname string) *MachoSect {
|
||||||
var s *MachoSect
|
|
||||||
|
|
||||||
if seg.nsect >= seg.msect {
|
if seg.nsect >= seg.msect {
|
||||||
Diag("too many sects in segment %s", seg.name)
|
Diag("too many sects in segment %s", seg.name)
|
||||||
Errorexit()
|
Errorexit()
|
||||||
}
|
}
|
||||||
|
|
||||||
s = &seg.sect[seg.nsect]
|
s := &seg.sect[seg.nsect]
|
||||||
seg.nsect++
|
seg.nsect++
|
||||||
s.name = name
|
s.name = name
|
||||||
s.segname = segname
|
s.segname = segname
|
||||||
|
|
@ -196,18 +192,10 @@ var ndylib int
|
||||||
var linkoff int64
|
var linkoff int64
|
||||||
|
|
||||||
func machowrite() int {
|
func machowrite() int {
|
||||||
var o1 int64
|
o1 := Cpos()
|
||||||
var loadsize int
|
|
||||||
var i int
|
|
||||||
var j int
|
|
||||||
var s *MachoSeg
|
|
||||||
var t *MachoSect
|
|
||||||
var l *MachoLoad
|
|
||||||
|
|
||||||
o1 = Cpos()
|
loadsize := 4 * 4 * ndebug
|
||||||
|
for i := 0; i < len(load); i++ {
|
||||||
loadsize = 4 * 4 * ndebug
|
|
||||||
for i = 0; i < len(load); i++ {
|
|
||||||
loadsize += 4 * (len(load[i].data) + 2)
|
loadsize += 4 * (len(load[i].data) + 2)
|
||||||
}
|
}
|
||||||
if macho64 {
|
if macho64 {
|
||||||
|
|
@ -237,7 +225,10 @@ func machowrite() int {
|
||||||
Thearch.Lput(0) /* reserved */
|
Thearch.Lput(0) /* reserved */
|
||||||
}
|
}
|
||||||
|
|
||||||
for i = 0; i < nseg; i++ {
|
var j int
|
||||||
|
var s *MachoSeg
|
||||||
|
var t *MachoSect
|
||||||
|
for i := 0; i < nseg; i++ {
|
||||||
s = &seg[i]
|
s = &seg[i]
|
||||||
if macho64 {
|
if macho64 {
|
||||||
Thearch.Lput(25) /* segment 64 */
|
Thearch.Lput(25) /* segment 64 */
|
||||||
|
|
@ -296,7 +287,8 @@ func machowrite() int {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for i = 0; i < len(load); i++ {
|
var l *MachoLoad
|
||||||
|
for i := 0; i < len(load); i++ {
|
||||||
l = &load[i]
|
l = &load[i]
|
||||||
Thearch.Lput(l.type_)
|
Thearch.Lput(l.type_)
|
||||||
Thearch.Lput(4 * (uint32(len(l.data)) + 2))
|
Thearch.Lput(4 * (uint32(len(l.data)) + 2))
|
||||||
|
|
@ -309,14 +301,12 @@ func machowrite() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func domacho() {
|
func domacho() {
|
||||||
var s *LSym
|
|
||||||
|
|
||||||
if Debug['d'] != 0 {
|
if Debug['d'] != 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// empirically, string table must begin with " \x00".
|
// empirically, string table must begin with " \x00".
|
||||||
s = Linklookup(Ctxt, ".machosymstr", 0)
|
s := Linklookup(Ctxt, ".machosymstr", 0)
|
||||||
|
|
||||||
s.Type = SMACHOSYMSTR
|
s.Type = SMACHOSYMSTR
|
||||||
s.Reachable = true
|
s.Reachable = true
|
||||||
|
|
@ -328,7 +318,7 @@ func domacho() {
|
||||||
s.Reachable = true
|
s.Reachable = true
|
||||||
|
|
||||||
if Linkmode != LinkExternal {
|
if Linkmode != LinkExternal {
|
||||||
s = Linklookup(Ctxt, ".plt", 0) // will be __symbol_stub
|
s := Linklookup(Ctxt, ".plt", 0) // will be __symbol_stub
|
||||||
s.Type = SMACHOPLT
|
s.Type = SMACHOPLT
|
||||||
s.Reachable = true
|
s.Reachable = true
|
||||||
|
|
||||||
|
|
@ -364,12 +354,9 @@ func Machoadddynlib(lib string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func machoshbits(mseg *MachoSeg, sect *Section, segname string) {
|
func machoshbits(mseg *MachoSeg, sect *Section, segname string) {
|
||||||
var msect *MachoSect
|
buf := "__" + strings.Replace(sect.Name[1:], ".", "_", -1)
|
||||||
var buf string
|
|
||||||
|
|
||||||
buf = "__" + strings.Replace(sect.Name[1:], ".", "_", -1)
|
msect := newMachoSect(mseg, buf, segname)
|
||||||
|
|
||||||
msect = newMachoSect(mseg, buf, segname)
|
|
||||||
if sect.Rellen > 0 {
|
if sect.Rellen > 0 {
|
||||||
msect.reloc = uint32(sect.Reloff)
|
msect.reloc = uint32(sect.Reloff)
|
||||||
msect.nreloc = uint32(sect.Rellen / 8)
|
msect.nreloc = uint32(sect.Rellen / 8)
|
||||||
|
|
@ -413,20 +400,10 @@ func machoshbits(mseg *MachoSeg, sect *Section, segname string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Asmbmacho() {
|
func Asmbmacho() {
|
||||||
var v int64
|
|
||||||
var w int64
|
|
||||||
var va int64
|
|
||||||
var a int
|
|
||||||
var i int
|
|
||||||
var mh *MachoHdr
|
|
||||||
var ms *MachoSeg
|
|
||||||
var ml *MachoLoad
|
|
||||||
var sect *Section
|
|
||||||
|
|
||||||
/* apple MACH */
|
/* apple MACH */
|
||||||
va = INITTEXT - int64(HEADR)
|
va := INITTEXT - int64(HEADR)
|
||||||
|
|
||||||
mh = getMachoHdr()
|
mh := getMachoHdr()
|
||||||
switch Thearch.Thechar {
|
switch Thearch.Thechar {
|
||||||
default:
|
default:
|
||||||
Diag("unknown mach architecture")
|
Diag("unknown mach architecture")
|
||||||
|
|
@ -446,7 +423,7 @@ func Asmbmacho() {
|
||||||
mh.subcpu = MACHO_SUBCPU_X86
|
mh.subcpu = MACHO_SUBCPU_X86
|
||||||
}
|
}
|
||||||
|
|
||||||
ms = nil
|
ms := (*MachoSeg)(nil)
|
||||||
if Linkmode == LinkExternal {
|
if Linkmode == LinkExternal {
|
||||||
/* segment for entire file */
|
/* segment for entire file */
|
||||||
ms = newMachoSeg("", 40)
|
ms = newMachoSeg("", 40)
|
||||||
|
|
@ -462,7 +439,7 @@ func Asmbmacho() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* text */
|
/* text */
|
||||||
v = Rnd(int64(uint64(HEADR)+Segtext.Length), int64(INITRND))
|
v := Rnd(int64(uint64(HEADR)+Segtext.Length), int64(INITRND))
|
||||||
|
|
||||||
if Linkmode != LinkExternal {
|
if Linkmode != LinkExternal {
|
||||||
ms = newMachoSeg("__TEXT", 20)
|
ms = newMachoSeg("__TEXT", 20)
|
||||||
|
|
@ -474,13 +451,13 @@ func Asmbmacho() {
|
||||||
ms.prot2 = 5
|
ms.prot2 = 5
|
||||||
}
|
}
|
||||||
|
|
||||||
for sect = Segtext.Sect; sect != nil; sect = sect.Next {
|
for sect := Segtext.Sect; sect != nil; sect = sect.Next {
|
||||||
machoshbits(ms, sect, "__TEXT")
|
machoshbits(ms, sect, "__TEXT")
|
||||||
}
|
}
|
||||||
|
|
||||||
/* data */
|
/* data */
|
||||||
if Linkmode != LinkExternal {
|
if Linkmode != LinkExternal {
|
||||||
w = int64(Segdata.Length)
|
w := int64(Segdata.Length)
|
||||||
ms = newMachoSeg("__DATA", 20)
|
ms = newMachoSeg("__DATA", 20)
|
||||||
ms.vaddr = uint64(va) + uint64(v)
|
ms.vaddr = uint64(va) + uint64(v)
|
||||||
ms.vsize = uint64(w)
|
ms.vsize = uint64(w)
|
||||||
|
|
@ -490,7 +467,7 @@ func Asmbmacho() {
|
||||||
ms.prot2 = 3
|
ms.prot2 = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
for sect = Segdata.Sect; sect != nil; sect = sect.Next {
|
for sect := Segdata.Sect; sect != nil; sect = sect.Next {
|
||||||
machoshbits(ms, sect, "__DATA")
|
machoshbits(ms, sect, "__DATA")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -502,20 +479,20 @@ func Asmbmacho() {
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
||||||
case '5':
|
case '5':
|
||||||
ml = newMachoLoad(5, 17+2) /* unix thread */
|
ml := newMachoLoad(5, 17+2) /* unix thread */
|
||||||
ml.data[0] = 1 /* thread type */
|
ml.data[0] = 1 /* thread type */
|
||||||
ml.data[1] = 17 /* word count */
|
ml.data[1] = 17 /* word count */
|
||||||
ml.data[2+15] = uint32(Entryvalue()) /* start pc */
|
ml.data[2+15] = uint32(Entryvalue()) /* start pc */
|
||||||
|
|
||||||
case '6':
|
case '6':
|
||||||
ml = newMachoLoad(5, 42+2) /* unix thread */
|
ml := newMachoLoad(5, 42+2) /* unix thread */
|
||||||
ml.data[0] = 4 /* thread type */
|
ml.data[0] = 4 /* thread type */
|
||||||
ml.data[1] = 42 /* word count */
|
ml.data[1] = 42 /* word count */
|
||||||
ml.data[2+32] = uint32(Entryvalue()) /* start pc */
|
ml.data[2+32] = uint32(Entryvalue()) /* start pc */
|
||||||
ml.data[2+32+1] = uint32(Entryvalue() >> 16 >> 16) // hide >>32 for 8l
|
ml.data[2+32+1] = uint32(Entryvalue() >> 16 >> 16) // hide >>32 for 8l
|
||||||
|
|
||||||
case '8':
|
case '8':
|
||||||
ml = newMachoLoad(5, 16+2) /* unix thread */
|
ml := newMachoLoad(5, 16+2) /* unix thread */
|
||||||
ml.data[0] = 1 /* thread type */
|
ml.data[0] = 1 /* thread type */
|
||||||
ml.data[1] = 16 /* word count */
|
ml.data[1] = 16 /* word count */
|
||||||
ml.data[2+10] = uint32(Entryvalue()) /* start pc */
|
ml.data[2+10] = uint32(Entryvalue()) /* start pc */
|
||||||
|
|
@ -523,20 +500,15 @@ func Asmbmacho() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if Debug['d'] == 0 {
|
if Debug['d'] == 0 {
|
||||||
var s1 *LSym
|
|
||||||
var s2 *LSym
|
|
||||||
var s3 *LSym
|
|
||||||
var s4 *LSym
|
|
||||||
|
|
||||||
// must match domacholink below
|
// must match domacholink below
|
||||||
s1 = Linklookup(Ctxt, ".machosymtab", 0)
|
s1 := Linklookup(Ctxt, ".machosymtab", 0)
|
||||||
|
|
||||||
s2 = Linklookup(Ctxt, ".linkedit.plt", 0)
|
s2 := Linklookup(Ctxt, ".linkedit.plt", 0)
|
||||||
s3 = Linklookup(Ctxt, ".linkedit.got", 0)
|
s3 := Linklookup(Ctxt, ".linkedit.got", 0)
|
||||||
s4 = Linklookup(Ctxt, ".machosymstr", 0)
|
s4 := Linklookup(Ctxt, ".machosymstr", 0)
|
||||||
|
|
||||||
if Linkmode != LinkExternal {
|
if Linkmode != LinkExternal {
|
||||||
ms = newMachoSeg("__LINKEDIT", 0)
|
ms := newMachoSeg("__LINKEDIT", 0)
|
||||||
ms.vaddr = uint64(va) + uint64(v) + uint64(Rnd(int64(Segdata.Length), int64(INITRND)))
|
ms.vaddr = uint64(va) + uint64(v) + uint64(Rnd(int64(Segdata.Length), int64(INITRND)))
|
||||||
ms.vsize = uint64(s1.Size) + uint64(s2.Size) + uint64(s3.Size) + uint64(s4.Size)
|
ms.vsize = uint64(s1.Size) + uint64(s2.Size) + uint64(s3.Size) + uint64(s4.Size)
|
||||||
ms.fileoffset = uint64(linkoff)
|
ms.fileoffset = uint64(linkoff)
|
||||||
|
|
@ -545,7 +517,7 @@ func Asmbmacho() {
|
||||||
ms.prot2 = 3
|
ms.prot2 = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
ml = newMachoLoad(2, 4) /* LC_SYMTAB */
|
ml := newMachoLoad(2, 4) /* LC_SYMTAB */
|
||||||
ml.data[0] = uint32(linkoff) /* symoff */
|
ml.data[0] = uint32(linkoff) /* symoff */
|
||||||
ml.data[1] = uint32(nsortsym) /* nsyms */
|
ml.data[1] = uint32(nsortsym) /* nsyms */
|
||||||
ml.data[2] = uint32(linkoff + s1.Size + s2.Size + s3.Size) /* stroff */
|
ml.data[2] = uint32(linkoff + s1.Size + s2.Size + s3.Size) /* stroff */
|
||||||
|
|
@ -554,11 +526,11 @@ func Asmbmacho() {
|
||||||
machodysymtab()
|
machodysymtab()
|
||||||
|
|
||||||
if Linkmode != LinkExternal {
|
if Linkmode != LinkExternal {
|
||||||
ml = newMachoLoad(14, 6) /* LC_LOAD_DYLINKER */
|
ml := newMachoLoad(14, 6) /* LC_LOAD_DYLINKER */
|
||||||
ml.data[0] = 12 /* offset to string */
|
ml.data[0] = 12 /* offset to string */
|
||||||
stringtouint32(ml.data[1:], "/usr/lib/dyld")
|
stringtouint32(ml.data[1:], "/usr/lib/dyld")
|
||||||
|
|
||||||
for i = 0; i < len(dylib); i++ {
|
for i := 0; i < len(dylib); i++ {
|
||||||
ml = newMachoLoad(12, 4+(uint32(len(dylib[i]))+1+7)/8*2) /* LC_LOAD_DYLIB */
|
ml = newMachoLoad(12, 4+(uint32(len(dylib[i]))+1+7)/8*2) /* LC_LOAD_DYLIB */
|
||||||
ml.data[0] = 24 /* offset of string from beginning of load */
|
ml.data[0] = 24 /* offset of string from beginning of load */
|
||||||
ml.data[1] = 0 /* time stamp */
|
ml.data[1] = 0 /* time stamp */
|
||||||
|
|
@ -574,7 +546,7 @@ func Asmbmacho() {
|
||||||
dwarfaddmachoheaders()
|
dwarfaddmachoheaders()
|
||||||
}
|
}
|
||||||
|
|
||||||
a = machowrite()
|
a := machowrite()
|
||||||
if int32(a) > HEADR {
|
if int32(a) > HEADR {
|
||||||
Diag("HEADR too small: %d > %d", a, HEADR)
|
Diag("HEADR too small: %d > %d", a, HEADR)
|
||||||
}
|
}
|
||||||
|
|
@ -624,16 +596,11 @@ func (x machoscmp) Swap(i, j int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x machoscmp) Less(i, j int) bool {
|
func (x machoscmp) Less(i, j int) bool {
|
||||||
var s1 *LSym
|
s1 := x[i]
|
||||||
var s2 *LSym
|
s2 := x[j]
|
||||||
var k1 int
|
|
||||||
var k2 int
|
|
||||||
|
|
||||||
s1 = x[i]
|
k1 := symkind(s1)
|
||||||
s2 = x[j]
|
k2 := symkind(s2)
|
||||||
|
|
||||||
k1 = symkind(s1)
|
|
||||||
k2 = symkind(s2)
|
|
||||||
if k1 != k2 {
|
if k1 != k2 {
|
||||||
return k1-k2 < 0
|
return k1-k2 < 0
|
||||||
}
|
}
|
||||||
|
|
@ -642,10 +609,8 @@ func (x machoscmp) Less(i, j int) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func machogenasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
|
func machogenasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
|
||||||
var s *LSym
|
|
||||||
|
|
||||||
genasmsym(put)
|
genasmsym(put)
|
||||||
for s = Ctxt.Allsym; s != nil; s = s.Allsym {
|
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
||||||
if s.Type == SDYNIMPORT || s.Type == SHOSTOBJ {
|
if s.Type == SDYNIMPORT || s.Type == SHOSTOBJ {
|
||||||
if s.Reachable {
|
if s.Reachable {
|
||||||
put(s, "", 'D', 0, 0, 0, nil)
|
put(s, "", 'D', 0, 0, 0, nil)
|
||||||
|
|
@ -655,12 +620,10 @@ func machogenasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func machosymorder() {
|
func machosymorder() {
|
||||||
var i int
|
|
||||||
|
|
||||||
// On Mac OS X Mountain Lion, we must sort exported symbols
|
// On Mac OS X Mountain Lion, we must sort exported symbols
|
||||||
// So we sort them here and pre-allocate dynid for them
|
// So we sort them here and pre-allocate dynid for them
|
||||||
// See http://golang.org/issue/4029
|
// See http://golang.org/issue/4029
|
||||||
for i = 0; i < len(dynexp); i++ {
|
for i := 0; i < len(dynexp); i++ {
|
||||||
dynexp[i].Reachable = true
|
dynexp[i].Reachable = true
|
||||||
}
|
}
|
||||||
machogenasmsym(addsym)
|
machogenasmsym(addsym)
|
||||||
|
|
@ -668,23 +631,20 @@ func machosymorder() {
|
||||||
nsortsym = 0
|
nsortsym = 0
|
||||||
machogenasmsym(addsym)
|
machogenasmsym(addsym)
|
||||||
sort.Sort(machoscmp(sortsym[:nsortsym]))
|
sort.Sort(machoscmp(sortsym[:nsortsym]))
|
||||||
for i = 0; i < nsortsym; i++ {
|
for i := 0; i < nsortsym; i++ {
|
||||||
sortsym[i].Dynid = int32(i)
|
sortsym[i].Dynid = int32(i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func machosymtab() {
|
func machosymtab() {
|
||||||
var i int
|
|
||||||
var symtab *LSym
|
|
||||||
var symstr *LSym
|
|
||||||
var s *LSym
|
var s *LSym
|
||||||
var o *LSym
|
var o *LSym
|
||||||
var p string
|
var p string
|
||||||
|
|
||||||
symtab = Linklookup(Ctxt, ".machosymtab", 0)
|
symtab := Linklookup(Ctxt, ".machosymtab", 0)
|
||||||
symstr = Linklookup(Ctxt, ".machosymstr", 0)
|
symstr := Linklookup(Ctxt, ".machosymstr", 0)
|
||||||
|
|
||||||
for i = 0; i < nsortsym; i++ {
|
for i := 0; i < nsortsym; i++ {
|
||||||
s = sortsym[i]
|
s = sortsym[i]
|
||||||
Adduint32(Ctxt, symtab, uint32(symstr.Size))
|
Adduint32(Ctxt, symtab, uint32(symstr.Size))
|
||||||
|
|
||||||
|
|
@ -737,15 +697,9 @@ func machosymtab() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func machodysymtab() {
|
func machodysymtab() {
|
||||||
var n int
|
ml := newMachoLoad(11, 18) /* LC_DYSYMTAB */
|
||||||
var ml *MachoLoad
|
|
||||||
var s1 *LSym
|
|
||||||
var s2 *LSym
|
|
||||||
var s3 *LSym
|
|
||||||
|
|
||||||
ml = newMachoLoad(11, 18) /* LC_DYSYMTAB */
|
n := 0
|
||||||
|
|
||||||
n = 0
|
|
||||||
ml.data[0] = uint32(n) /* ilocalsym */
|
ml.data[0] = uint32(n) /* ilocalsym */
|
||||||
ml.data[1] = uint32(nkind[SymKindLocal]) /* nlocalsym */
|
ml.data[1] = uint32(nkind[SymKindLocal]) /* nlocalsym */
|
||||||
n += nkind[SymKindLocal]
|
n += nkind[SymKindLocal]
|
||||||
|
|
@ -765,10 +719,10 @@ func machodysymtab() {
|
||||||
ml.data[11] = 0 /* nextrefsyms */
|
ml.data[11] = 0 /* nextrefsyms */
|
||||||
|
|
||||||
// must match domacholink below
|
// must match domacholink below
|
||||||
s1 = Linklookup(Ctxt, ".machosymtab", 0)
|
s1 := Linklookup(Ctxt, ".machosymtab", 0)
|
||||||
|
|
||||||
s2 = Linklookup(Ctxt, ".linkedit.plt", 0)
|
s2 := Linklookup(Ctxt, ".linkedit.plt", 0)
|
||||||
s3 = Linklookup(Ctxt, ".linkedit.got", 0)
|
s3 := Linklookup(Ctxt, ".linkedit.got", 0)
|
||||||
ml.data[12] = uint32(linkoff + s1.Size) /* indirectsymoff */
|
ml.data[12] = uint32(linkoff + s1.Size) /* indirectsymoff */
|
||||||
ml.data[13] = uint32((s2.Size + s3.Size) / 4) /* nindirectsyms */
|
ml.data[13] = uint32((s2.Size + s3.Size) / 4) /* nindirectsyms */
|
||||||
|
|
||||||
|
|
@ -779,20 +733,14 @@ func machodysymtab() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Domacholink() int64 {
|
func Domacholink() int64 {
|
||||||
var size int
|
|
||||||
var s1 *LSym
|
|
||||||
var s2 *LSym
|
|
||||||
var s3 *LSym
|
|
||||||
var s4 *LSym
|
|
||||||
|
|
||||||
machosymtab()
|
machosymtab()
|
||||||
|
|
||||||
// write data that will be linkedit section
|
// write data that will be linkedit section
|
||||||
s1 = Linklookup(Ctxt, ".machosymtab", 0)
|
s1 := Linklookup(Ctxt, ".machosymtab", 0)
|
||||||
|
|
||||||
s2 = Linklookup(Ctxt, ".linkedit.plt", 0)
|
s2 := Linklookup(Ctxt, ".linkedit.plt", 0)
|
||||||
s3 = Linklookup(Ctxt, ".linkedit.got", 0)
|
s3 := Linklookup(Ctxt, ".linkedit.got", 0)
|
||||||
s4 = Linklookup(Ctxt, ".machosymstr", 0)
|
s4 := Linklookup(Ctxt, ".machosymstr", 0)
|
||||||
|
|
||||||
// Force the linkedit section to end on a 16-byte
|
// Force the linkedit section to end on a 16-byte
|
||||||
// boundary. This allows pure (non-cgo) Go binaries
|
// boundary. This allows pure (non-cgo) Go binaries
|
||||||
|
|
@ -815,7 +763,7 @@ func Domacholink() int64 {
|
||||||
Adduint8(Ctxt, s4, 0)
|
Adduint8(Ctxt, s4, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
size = int(s1.Size + s2.Size + s3.Size + s4.Size)
|
size := int(s1.Size + s2.Size + s3.Size + s4.Size)
|
||||||
|
|
||||||
if size > 0 {
|
if size > 0 {
|
||||||
linkoff = Rnd(int64(uint64(HEADR)+Segtext.Length), int64(INITRND)) + Rnd(int64(Segdata.Filelen), int64(INITRND)) + Rnd(int64(Segdwarf.Filelen), int64(INITRND))
|
linkoff = Rnd(int64(uint64(HEADR)+Segtext.Length), int64(INITRND)) + Rnd(int64(Segdata.Filelen), int64(INITRND)) + Rnd(int64(Segdwarf.Filelen), int64(INITRND))
|
||||||
|
|
@ -831,17 +779,13 @@ func Domacholink() int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func machorelocsect(sect *Section, first *LSym) {
|
func machorelocsect(sect *Section, first *LSym) {
|
||||||
var sym *LSym
|
|
||||||
var eaddr int32
|
|
||||||
var ri int
|
|
||||||
var r *Reloc
|
|
||||||
|
|
||||||
// If main section has no bits, nothing to relocate.
|
// If main section has no bits, nothing to relocate.
|
||||||
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
|
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sect.Reloff = uint64(Cpos())
|
sect.Reloff = uint64(Cpos())
|
||||||
|
var sym *LSym
|
||||||
for sym = first; sym != nil; sym = sym.Next {
|
for sym = first; sym != nil; sym = sym.Next {
|
||||||
if !sym.Reachable {
|
if !sym.Reachable {
|
||||||
continue
|
continue
|
||||||
|
|
@ -851,7 +795,9 @@ func machorelocsect(sect *Section, first *LSym) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eaddr = int32(sect.Vaddr + sect.Length)
|
eaddr := int32(sect.Vaddr + sect.Length)
|
||||||
|
var r *Reloc
|
||||||
|
var ri int
|
||||||
for ; sym != nil; sym = sym.Next {
|
for ; sym != nil; sym = sym.Next {
|
||||||
if !sym.Reachable {
|
if !sym.Reachable {
|
||||||
continue
|
continue
|
||||||
|
|
@ -876,17 +822,15 @@ func machorelocsect(sect *Section, first *LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Machoemitreloc() {
|
func Machoemitreloc() {
|
||||||
var sect *Section
|
|
||||||
|
|
||||||
for Cpos()&7 != 0 {
|
for Cpos()&7 != 0 {
|
||||||
Cput(0)
|
Cput(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
machorelocsect(Segtext.Sect, Ctxt.Textp)
|
machorelocsect(Segtext.Sect, Ctxt.Textp)
|
||||||
for sect = Segtext.Sect.Next; sect != nil; sect = sect.Next {
|
for sect := Segtext.Sect.Next; sect != nil; sect = sect.Next {
|
||||||
machorelocsect(sect, datap)
|
machorelocsect(sect, datap)
|
||||||
}
|
}
|
||||||
for sect = Segdata.Sect; sect != nil; sect = sect.Next {
|
for sect := Segdata.Sect; sect != nil; sect = sect.Next {
|
||||||
machorelocsect(sect, datap)
|
machorelocsect(sect, datap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,23 +17,19 @@ var startmagic string = "\x00\x00go13ld"
|
||||||
var endmagic string = "\xff\xffgo13ld"
|
var endmagic string = "\xff\xffgo13ld"
|
||||||
|
|
||||||
func ldobjfile(ctxt *Link, f *Biobuf, pkg string, length int64, pn string) {
|
func ldobjfile(ctxt *Link, f *Biobuf, pkg string, length int64, pn string) {
|
||||||
var c int
|
start := Boffset(f)
|
||||||
var buf [8]uint8
|
|
||||||
var start int64
|
|
||||||
var lib string
|
|
||||||
|
|
||||||
start = Boffset(f)
|
|
||||||
ctxt.Version++
|
ctxt.Version++
|
||||||
buf = [8]uint8{}
|
buf := [8]uint8{}
|
||||||
Bread(f, buf[:])
|
Bread(f, buf[:])
|
||||||
if string(buf[:]) != startmagic {
|
if string(buf[:]) != startmagic {
|
||||||
log.Fatalf("%s: invalid file start %x %x %x %x %x %x %x %x", pn, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7])
|
log.Fatalf("%s: invalid file start %x %x %x %x %x %x %x %x", pn, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7])
|
||||||
}
|
}
|
||||||
c = Bgetc(f)
|
c := Bgetc(f)
|
||||||
if c != 1 {
|
if c != 1 {
|
||||||
log.Fatalf("%s: invalid file version number %d", pn, c)
|
log.Fatalf("%s: invalid file version number %d", pn, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var lib string
|
||||||
for {
|
for {
|
||||||
lib = rdstring(f)
|
lib = rdstring(f)
|
||||||
if lib == "" {
|
if lib == "" {
|
||||||
|
|
@ -65,45 +61,28 @@ func ldobjfile(ctxt *Link, f *Biobuf, pkg string, length int64, pn string) {
|
||||||
var readsym_ndup int
|
var readsym_ndup int
|
||||||
|
|
||||||
func readsym(ctxt *Link, f *Biobuf, pkg string, pn string) {
|
func readsym(ctxt *Link, f *Biobuf, pkg string, pn string) {
|
||||||
var i int
|
|
||||||
var j int
|
|
||||||
var c int
|
|
||||||
var t int
|
|
||||||
var v int
|
|
||||||
var n int
|
|
||||||
var nreloc int
|
|
||||||
var size int
|
|
||||||
var dupok int
|
|
||||||
var name string
|
|
||||||
var data []byte
|
|
||||||
var r *Reloc
|
|
||||||
var s *LSym
|
|
||||||
var dup *LSym
|
|
||||||
var typ *LSym
|
|
||||||
var pc *Pcln
|
|
||||||
var a *Auto
|
|
||||||
|
|
||||||
if Bgetc(f) != 0xfe {
|
if Bgetc(f) != 0xfe {
|
||||||
log.Fatalf("readsym out of sync")
|
log.Fatalf("readsym out of sync")
|
||||||
}
|
}
|
||||||
t = int(rdint(f))
|
t := int(rdint(f))
|
||||||
name = expandpkg(rdstring(f), pkg)
|
name := expandpkg(rdstring(f), pkg)
|
||||||
v = int(rdint(f))
|
v := int(rdint(f))
|
||||||
if v != 0 && v != 1 {
|
if v != 0 && v != 1 {
|
||||||
log.Fatalf("invalid symbol version %d", v)
|
log.Fatalf("invalid symbol version %d", v)
|
||||||
}
|
}
|
||||||
dupok = int(rdint(f))
|
dupok := int(rdint(f))
|
||||||
dupok &= 1
|
dupok &= 1
|
||||||
size = int(rdint(f))
|
size := int(rdint(f))
|
||||||
typ = rdsym(ctxt, f, pkg)
|
typ := rdsym(ctxt, f, pkg)
|
||||||
|
var data []byte
|
||||||
rddata(f, &data)
|
rddata(f, &data)
|
||||||
nreloc = int(rdint(f))
|
nreloc := int(rdint(f))
|
||||||
|
|
||||||
if v != 0 {
|
if v != 0 {
|
||||||
v = ctxt.Version
|
v = ctxt.Version
|
||||||
}
|
}
|
||||||
s = Linklookup(ctxt, name, v)
|
s := Linklookup(ctxt, name, v)
|
||||||
dup = nil
|
dup := (*LSym)(nil)
|
||||||
if s.Type != 0 && s.Type != SXREF {
|
if s.Type != 0 && s.Type != SXREF {
|
||||||
if (t == SDATA || t == SBSS || t == SNOPTRBSS) && len(data) == 0 && nreloc == 0 {
|
if (t == SDATA || t == SBSS || t == SNOPTRBSS) && len(data) == 0 && nreloc == 0 {
|
||||||
if s.Size < int64(size) {
|
if s.Size < int64(size) {
|
||||||
|
|
@ -155,7 +134,8 @@ overwrite:
|
||||||
if nreloc > 0 {
|
if nreloc > 0 {
|
||||||
s.R = make([]Reloc, nreloc)
|
s.R = make([]Reloc, nreloc)
|
||||||
s.R = s.R[:nreloc]
|
s.R = s.R[:nreloc]
|
||||||
for i = 0; i < nreloc; i++ {
|
var r *Reloc
|
||||||
|
for i := 0; i < nreloc; i++ {
|
||||||
r = &s.R[i]
|
r = &s.R[i]
|
||||||
r.Off = int32(rdint(f))
|
r.Off = int32(rdint(f))
|
||||||
r.Siz = uint8(rdint(f))
|
r.Siz = uint8(rdint(f))
|
||||||
|
|
@ -179,11 +159,12 @@ overwrite:
|
||||||
s.Args = int32(rdint(f))
|
s.Args = int32(rdint(f))
|
||||||
s.Locals = int32(rdint(f))
|
s.Locals = int32(rdint(f))
|
||||||
s.Nosplit = uint8(rdint(f))
|
s.Nosplit = uint8(rdint(f))
|
||||||
v = int(rdint(f))
|
v := int(rdint(f))
|
||||||
s.Leaf = uint8(v & 1)
|
s.Leaf = uint8(v & 1)
|
||||||
s.Cfunc = uint8(v & 2)
|
s.Cfunc = uint8(v & 2)
|
||||||
n = int(rdint(f))
|
n := int(rdint(f))
|
||||||
for i = 0; i < n; i++ {
|
var a *Auto
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
a = new(Auto)
|
a = new(Auto)
|
||||||
a.Asym = rdsym(ctxt, f, pkg)
|
a.Asym = rdsym(ctxt, f, pkg)
|
||||||
a.Aoffset = int32(rdint(f))
|
a.Aoffset = int32(rdint(f))
|
||||||
|
|
@ -194,30 +175,30 @@ overwrite:
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Pcln = new(Pcln)
|
s.Pcln = new(Pcln)
|
||||||
pc = s.Pcln
|
pc := s.Pcln
|
||||||
rddata(f, &pc.Pcsp.P)
|
rddata(f, &pc.Pcsp.P)
|
||||||
rddata(f, &pc.Pcfile.P)
|
rddata(f, &pc.Pcfile.P)
|
||||||
rddata(f, &pc.Pcline.P)
|
rddata(f, &pc.Pcline.P)
|
||||||
n = int(rdint(f))
|
n = int(rdint(f))
|
||||||
pc.Pcdata = make([]Pcdata, n)
|
pc.Pcdata = make([]Pcdata, n)
|
||||||
pc.Npcdata = n
|
pc.Npcdata = n
|
||||||
for i = 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
rddata(f, &pc.Pcdata[i].P)
|
rddata(f, &pc.Pcdata[i].P)
|
||||||
}
|
}
|
||||||
n = int(rdint(f))
|
n = int(rdint(f))
|
||||||
pc.Funcdata = make([]*LSym, n)
|
pc.Funcdata = make([]*LSym, n)
|
||||||
pc.Funcdataoff = make([]int64, n)
|
pc.Funcdataoff = make([]int64, n)
|
||||||
pc.Nfuncdata = n
|
pc.Nfuncdata = n
|
||||||
for i = 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
pc.Funcdata[i] = rdsym(ctxt, f, pkg)
|
pc.Funcdata[i] = rdsym(ctxt, f, pkg)
|
||||||
}
|
}
|
||||||
for i = 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
pc.Funcdataoff[i] = rdint(f)
|
pc.Funcdataoff[i] = rdint(f)
|
||||||
}
|
}
|
||||||
n = int(rdint(f))
|
n = int(rdint(f))
|
||||||
pc.File = make([]*LSym, n)
|
pc.File = make([]*LSym, n)
|
||||||
pc.Nfile = n
|
pc.Nfile = n
|
||||||
for i = 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
pc.File[i] = rdsym(ctxt, f, pkg)
|
pc.File[i] = rdsym(ctxt, f, pkg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -257,7 +238,9 @@ overwrite:
|
||||||
fmt.Fprintf(ctxt.Bso, " args=%#x locals=%#x", uint64(s.Args), uint64(s.Locals))
|
fmt.Fprintf(ctxt.Bso, " args=%#x locals=%#x", uint64(s.Args), uint64(s.Locals))
|
||||||
}
|
}
|
||||||
fmt.Fprintf(ctxt.Bso, "\n")
|
fmt.Fprintf(ctxt.Bso, "\n")
|
||||||
for i = 0; i < len(s.P); {
|
var c int
|
||||||
|
var j int
|
||||||
|
for i := 0; i < len(s.P); {
|
||||||
fmt.Fprintf(ctxt.Bso, "\t%#04x", uint(i))
|
fmt.Fprintf(ctxt.Bso, "\t%#04x", uint(i))
|
||||||
for j = i; j < i+16 && j < len(s.P); j++ {
|
for j = i; j < i+16 && j < len(s.P); j++ {
|
||||||
fmt.Fprintf(ctxt.Bso, " %02x", s.P[j])
|
fmt.Fprintf(ctxt.Bso, " %02x", s.P[j])
|
||||||
|
|
@ -279,7 +262,8 @@ overwrite:
|
||||||
i += 16
|
i += 16
|
||||||
}
|
}
|
||||||
|
|
||||||
for i = 0; i < len(s.R); i++ {
|
var r *Reloc
|
||||||
|
for i := 0; i < len(s.R); i++ {
|
||||||
r = &s.R[i]
|
r = &s.R[i]
|
||||||
fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%d\n", int(r.Off), r.Siz, r.Type, r.Sym.Name, int64(r.Add))
|
fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%d\n", int(r.Off), r.Siz, r.Type, r.Sym.Name, int64(r.Add))
|
||||||
}
|
}
|
||||||
|
|
@ -288,11 +272,9 @@ overwrite:
|
||||||
|
|
||||||
func rdint(f *Biobuf) int64 {
|
func rdint(f *Biobuf) int64 {
|
||||||
var c int
|
var c int
|
||||||
var uv uint64
|
|
||||||
var shift int
|
|
||||||
|
|
||||||
uv = 0
|
uv := uint64(0)
|
||||||
for shift = 0; ; shift += 7 {
|
for shift := 0; ; shift += 7 {
|
||||||
if shift >= 64 {
|
if shift >= 64 {
|
||||||
log.Fatalf("corrupt input")
|
log.Fatalf("corrupt input")
|
||||||
}
|
}
|
||||||
|
|
@ -322,12 +304,7 @@ func rddata(f *Biobuf, pp *[]byte) {
|
||||||
var symbuf []byte
|
var symbuf []byte
|
||||||
|
|
||||||
func rdsym(ctxt *Link, f *Biobuf, pkg string) *LSym {
|
func rdsym(ctxt *Link, f *Biobuf, pkg string) *LSym {
|
||||||
var n int
|
n := int(rdint(f))
|
||||||
var v int
|
|
||||||
var p string
|
|
||||||
var s *LSym
|
|
||||||
|
|
||||||
n = int(rdint(f))
|
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
rdint(f)
|
rdint(f)
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -337,25 +314,23 @@ func rdsym(ctxt *Link, f *Biobuf, pkg string) *LSym {
|
||||||
symbuf = make([]byte, n)
|
symbuf = make([]byte, n)
|
||||||
}
|
}
|
||||||
Bread(f, symbuf[:n])
|
Bread(f, symbuf[:n])
|
||||||
p = string(symbuf[:n])
|
p := string(symbuf[:n])
|
||||||
v = int(rdint(f))
|
v := int(rdint(f))
|
||||||
if v != 0 {
|
if v != 0 {
|
||||||
v = ctxt.Version
|
v = ctxt.Version
|
||||||
}
|
}
|
||||||
s = Linklookup(ctxt, expandpkg(p, pkg), v)
|
s := Linklookup(ctxt, expandpkg(p, pkg), v)
|
||||||
|
|
||||||
if v == 0 && s.Name[0] == '$' && s.Type == 0 {
|
if v == 0 && s.Name[0] == '$' && s.Type == 0 {
|
||||||
if strings.HasPrefix(s.Name, "$f32.") {
|
if strings.HasPrefix(s.Name, "$f32.") {
|
||||||
var i32 int32
|
|
||||||
x, _ := strconv.ParseUint(s.Name[5:], 16, 32)
|
x, _ := strconv.ParseUint(s.Name[5:], 16, 32)
|
||||||
i32 = int32(x)
|
i32 := int32(x)
|
||||||
s.Type = SRODATA
|
s.Type = SRODATA
|
||||||
Adduint32(ctxt, s, uint32(i32))
|
Adduint32(ctxt, s, uint32(i32))
|
||||||
s.Reachable = false
|
s.Reachable = false
|
||||||
} else if strings.HasPrefix(s.Name, "$f64.") || strings.HasPrefix(s.Name, "$i64.") {
|
} else if strings.HasPrefix(s.Name, "$f64.") || strings.HasPrefix(s.Name, "$i64.") {
|
||||||
var i64 int64
|
|
||||||
x, _ := strconv.ParseUint(s.Name[5:], 16, 64)
|
x, _ := strconv.ParseUint(s.Name[5:], 16, 64)
|
||||||
i64 = int64(x)
|
i64 := int64(x)
|
||||||
s.Type = SRODATA
|
s.Type = SRODATA
|
||||||
Adduint64(ctxt, s, uint64(i64))
|
Adduint64(ctxt, s, uint64(i64))
|
||||||
s.Reachable = false
|
s.Reachable = false
|
||||||
|
|
|
||||||
|
|
@ -40,13 +40,9 @@ import (
|
||||||
// iteration over encoded pcdata tables.
|
// iteration over encoded pcdata tables.
|
||||||
|
|
||||||
func getvarint(pp *[]byte) uint32 {
|
func getvarint(pp *[]byte) uint32 {
|
||||||
var p []byte
|
v := uint32(0)
|
||||||
var shift int
|
p := *pp
|
||||||
var v uint32
|
for shift := 0; ; shift += 7 {
|
||||||
|
|
||||||
v = 0
|
|
||||||
p = *pp
|
|
||||||
for shift = 0; ; shift += 7 {
|
|
||||||
v |= uint32(p[0]&0x7F) << uint(shift)
|
v |= uint32(p[0]&0x7F) << uint(shift)
|
||||||
tmp4 := p
|
tmp4 := p
|
||||||
p = p[1:]
|
p = p[1:]
|
||||||
|
|
@ -60,9 +56,6 @@ func getvarint(pp *[]byte) uint32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func pciternext(it *Pciter) {
|
func pciternext(it *Pciter) {
|
||||||
var v uint32
|
|
||||||
var dv int32
|
|
||||||
|
|
||||||
it.pc = it.nextpc
|
it.pc = it.nextpc
|
||||||
if it.done != 0 {
|
if it.done != 0 {
|
||||||
return
|
return
|
||||||
|
|
@ -73,7 +66,7 @@ func pciternext(it *Pciter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// value delta
|
// value delta
|
||||||
v = getvarint(&it.p)
|
v := getvarint(&it.p)
|
||||||
|
|
||||||
if v == 0 && it.start == 0 {
|
if v == 0 && it.start == 0 {
|
||||||
it.done = 1
|
it.done = 1
|
||||||
|
|
@ -81,7 +74,7 @@ func pciternext(it *Pciter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
it.start = 0
|
it.start = 0
|
||||||
dv = int32(v>>1) ^ (int32(v<<31) >> 31)
|
dv := int32(v>>1) ^ (int32(v<<31) >> 31)
|
||||||
it.value += dv
|
it.value += dv
|
||||||
|
|
||||||
// pc delta
|
// pc delta
|
||||||
|
|
@ -107,12 +100,8 @@ func pciterinit(ctxt *Link, it *Pciter, d *Pcdata) {
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
func addvarint(d *Pcdata, val uint32) {
|
func addvarint(d *Pcdata, val uint32) {
|
||||||
var n int32
|
n := int32(0)
|
||||||
var v uint32
|
for v := val; v >= 0x80; v >>= 7 {
|
||||||
var p []byte
|
|
||||||
|
|
||||||
n = 0
|
|
||||||
for v = val; v >= 0x80; v >>= 7 {
|
|
||||||
n++
|
n++
|
||||||
}
|
}
|
||||||
n++
|
n++
|
||||||
|
|
@ -123,7 +112,8 @@ func addvarint(d *Pcdata, val uint32) {
|
||||||
}
|
}
|
||||||
d.P = d.P[:old+int(n)]
|
d.P = d.P[:old+int(n)]
|
||||||
|
|
||||||
p = d.P[old:]
|
p := d.P[old:]
|
||||||
|
var v uint32
|
||||||
for v = val; v >= 0x80; v >>= 7 {
|
for v = val; v >= 0x80; v >>= 7 {
|
||||||
p[0] = byte(v | 0x80)
|
p[0] = byte(v | 0x80)
|
||||||
p = p[1:]
|
p = p[1:]
|
||||||
|
|
@ -132,9 +122,7 @@ func addvarint(d *Pcdata, val uint32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func addpctab(ftab *LSym, off int32, d *Pcdata) int32 {
|
func addpctab(ftab *LSym, off int32, d *Pcdata) int32 {
|
||||||
var start int32
|
start := int32(len(ftab.P))
|
||||||
|
|
||||||
start = int32(len(ftab.P))
|
|
||||||
Symgrow(Ctxt, ftab, int64(start)+int64(len(d.P)))
|
Symgrow(Ctxt, ftab, int64(start)+int64(len(d.P)))
|
||||||
copy(ftab.P[start:], d.P)
|
copy(ftab.P[start:], d.P)
|
||||||
|
|
||||||
|
|
@ -142,29 +130,18 @@ func addpctab(ftab *LSym, off int32, d *Pcdata) int32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ftabaddstring(ftab *LSym, s string) int32 {
|
func ftabaddstring(ftab *LSym, s string) int32 {
|
||||||
var n int32
|
n := int32(len(s)) + 1
|
||||||
var start int32
|
start := int32(len(ftab.P))
|
||||||
|
|
||||||
n = int32(len(s)) + 1
|
|
||||||
start = int32(len(ftab.P))
|
|
||||||
Symgrow(Ctxt, ftab, int64(start)+int64(n)+1)
|
Symgrow(Ctxt, ftab, int64(start)+int64(n)+1)
|
||||||
copy(ftab.P[start:], s)
|
copy(ftab.P[start:], s)
|
||||||
return start
|
return start
|
||||||
}
|
}
|
||||||
|
|
||||||
func renumberfiles(ctxt *Link, files []*LSym, d *Pcdata) {
|
func renumberfiles(ctxt *Link, files []*LSym, d *Pcdata) {
|
||||||
var i int
|
|
||||||
var f *LSym
|
var f *LSym
|
||||||
var out Pcdata
|
|
||||||
var it Pciter
|
|
||||||
var v uint32
|
|
||||||
var oldval int32
|
|
||||||
var newval int32
|
|
||||||
var val int32
|
|
||||||
var dv int32
|
|
||||||
|
|
||||||
// Give files numbers.
|
// Give files numbers.
|
||||||
for i = 0; i < len(files); i++ {
|
for i := 0; i < len(files); i++ {
|
||||||
f = files[i]
|
f = files[i]
|
||||||
if f.Type != SFILEPATH {
|
if f.Type != SFILEPATH {
|
||||||
ctxt.Nhistfile++
|
ctxt.Nhistfile++
|
||||||
|
|
@ -175,9 +152,14 @@ func renumberfiles(ctxt *Link, files []*LSym, d *Pcdata) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newval = -1
|
newval := int32(-1)
|
||||||
out = Pcdata{}
|
out := Pcdata{}
|
||||||
|
|
||||||
|
var dv int32
|
||||||
|
var it Pciter
|
||||||
|
var oldval int32
|
||||||
|
var v uint32
|
||||||
|
var val int32
|
||||||
for pciterinit(ctxt, &it, d); it.done == 0; pciternext(&it) {
|
for pciterinit(ctxt, &it, d); it.done == 0; pciternext(&it) {
|
||||||
// value delta
|
// value delta
|
||||||
oldval = it.value
|
oldval = it.value
|
||||||
|
|
@ -221,22 +203,8 @@ func container(s *LSym) int {
|
||||||
var pclntab_zpcln Pcln
|
var pclntab_zpcln Pcln
|
||||||
|
|
||||||
func pclntab() {
|
func pclntab() {
|
||||||
var i int32
|
funcdata_bytes := int64(0)
|
||||||
var nfunc int32
|
ftab := Linklookup(Ctxt, "runtime.pclntab", 0)
|
||||||
var start int32
|
|
||||||
var funcstart int32
|
|
||||||
var ftab *LSym
|
|
||||||
var s *LSym
|
|
||||||
var last *LSym
|
|
||||||
var off int32
|
|
||||||
var end int32
|
|
||||||
var frameptrsize int32
|
|
||||||
var funcdata_bytes int64
|
|
||||||
var pcln *Pcln
|
|
||||||
var it Pciter
|
|
||||||
|
|
||||||
funcdata_bytes = 0
|
|
||||||
ftab = Linklookup(Ctxt, "runtime.pclntab", 0)
|
|
||||||
ftab.Type = SPCLNTAB
|
ftab.Type = SPCLNTAB
|
||||||
ftab.Reachable = true
|
ftab.Reachable = true
|
||||||
|
|
||||||
|
|
@ -246,7 +214,7 @@ func pclntab() {
|
||||||
// function table, alternating PC and offset to func struct [each entry thearch.ptrsize bytes]
|
// function table, alternating PC and offset to func struct [each entry thearch.ptrsize bytes]
|
||||||
// end PC [thearch.ptrsize bytes]
|
// end PC [thearch.ptrsize bytes]
|
||||||
// offset to file table [4 bytes]
|
// offset to file table [4 bytes]
|
||||||
nfunc = 0
|
nfunc := int32(0)
|
||||||
|
|
||||||
for Ctxt.Cursym = Ctxt.Textp; Ctxt.Cursym != nil; Ctxt.Cursym = Ctxt.Cursym.Next {
|
for Ctxt.Cursym = Ctxt.Textp; Ctxt.Cursym != nil; Ctxt.Cursym = Ctxt.Cursym.Next {
|
||||||
if container(Ctxt.Cursym) == 0 {
|
if container(Ctxt.Cursym) == 0 {
|
||||||
|
|
@ -261,7 +229,14 @@ func pclntab() {
|
||||||
setuintxx(Ctxt, ftab, 8, uint64(nfunc), int64(Thearch.Ptrsize))
|
setuintxx(Ctxt, ftab, 8, uint64(nfunc), int64(Thearch.Ptrsize))
|
||||||
|
|
||||||
nfunc = 0
|
nfunc = 0
|
||||||
last = nil
|
last := (*LSym)(nil)
|
||||||
|
var end int32
|
||||||
|
var frameptrsize int32
|
||||||
|
var funcstart int32
|
||||||
|
var i int32
|
||||||
|
var it Pciter
|
||||||
|
var off int32
|
||||||
|
var pcln *Pcln
|
||||||
for Ctxt.Cursym = Ctxt.Textp; Ctxt.Cursym != nil; Ctxt.Cursym = Ctxt.Cursym.Next {
|
for Ctxt.Cursym = Ctxt.Textp; Ctxt.Cursym != nil; Ctxt.Cursym = Ctxt.Cursym.Next {
|
||||||
last = Ctxt.Cursym
|
last = Ctxt.Cursym
|
||||||
if container(Ctxt.Cursym) != 0 {
|
if container(Ctxt.Cursym) != 0 {
|
||||||
|
|
@ -366,14 +341,14 @@ func pclntab() {
|
||||||
setaddrplus(Ctxt, ftab, 8+int64(Thearch.Ptrsize)+int64(nfunc)*2*int64(Thearch.Ptrsize), last, last.Size)
|
setaddrplus(Ctxt, ftab, 8+int64(Thearch.Ptrsize)+int64(nfunc)*2*int64(Thearch.Ptrsize), last, last.Size)
|
||||||
|
|
||||||
// Start file table.
|
// Start file table.
|
||||||
start = int32(len(ftab.P))
|
start := int32(len(ftab.P))
|
||||||
|
|
||||||
start += int32(-len(ftab.P)) & (int32(Thearch.Ptrsize) - 1)
|
start += int32(-len(ftab.P)) & (int32(Thearch.Ptrsize) - 1)
|
||||||
setuint32(Ctxt, ftab, 8+int64(Thearch.Ptrsize)+int64(nfunc)*2*int64(Thearch.Ptrsize)+int64(Thearch.Ptrsize), uint32(start))
|
setuint32(Ctxt, ftab, 8+int64(Thearch.Ptrsize)+int64(nfunc)*2*int64(Thearch.Ptrsize)+int64(Thearch.Ptrsize), uint32(start))
|
||||||
|
|
||||||
Symgrow(Ctxt, ftab, int64(start)+(int64(Ctxt.Nhistfile)+1)*4)
|
Symgrow(Ctxt, ftab, int64(start)+(int64(Ctxt.Nhistfile)+1)*4)
|
||||||
setuint32(Ctxt, ftab, int64(start), uint32(Ctxt.Nhistfile))
|
setuint32(Ctxt, ftab, int64(start), uint32(Ctxt.Nhistfile))
|
||||||
for s = Ctxt.Filesyms; s != nil; s = s.Next {
|
for s := Ctxt.Filesyms; s != nil; s = s.Next {
|
||||||
setuint32(Ctxt, ftab, int64(start)+s.Value*4, uint32(ftabaddstring(ftab, s.Name)))
|
setuint32(Ctxt, ftab, int64(start)+s.Value*4, uint32(ftabaddstring(ftab, s.Name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -394,43 +369,32 @@ const (
|
||||||
// findfunctab generates a lookup table to quickly find the containing
|
// findfunctab generates a lookup table to quickly find the containing
|
||||||
// function for a pc. See src/runtime/symtab.go:findfunc for details.
|
// function for a pc. See src/runtime/symtab.go:findfunc for details.
|
||||||
func findfunctab() {
|
func findfunctab() {
|
||||||
var t *LSym
|
t := Linklookup(Ctxt, "runtime.findfunctab", 0)
|
||||||
var s *LSym
|
|
||||||
var e *LSym
|
|
||||||
var idx int32
|
|
||||||
var i int32
|
|
||||||
var j int32
|
|
||||||
var nbuckets int32
|
|
||||||
var n int32
|
|
||||||
var base int32
|
|
||||||
var min int64
|
|
||||||
var max int64
|
|
||||||
var p int64
|
|
||||||
var q int64
|
|
||||||
var indexes []int32
|
|
||||||
|
|
||||||
t = Linklookup(Ctxt, "runtime.findfunctab", 0)
|
|
||||||
t.Type = SRODATA
|
t.Type = SRODATA
|
||||||
t.Reachable = true
|
t.Reachable = true
|
||||||
|
|
||||||
// find min and max address
|
// find min and max address
|
||||||
min = Ctxt.Textp.Value
|
min := Ctxt.Textp.Value
|
||||||
|
|
||||||
max = 0
|
max := int64(0)
|
||||||
for s = Ctxt.Textp; s != nil; s = s.Next {
|
for s := Ctxt.Textp; s != nil; s = s.Next {
|
||||||
max = s.Value + s.Size
|
max = s.Value + s.Size
|
||||||
}
|
}
|
||||||
|
|
||||||
// for each subbucket, compute the minimum of all symbol indexes
|
// for each subbucket, compute the minimum of all symbol indexes
|
||||||
// that map to that subbucket.
|
// that map to that subbucket.
|
||||||
n = int32((max - min + SUBBUCKETSIZE - 1) / SUBBUCKETSIZE)
|
n := int32((max - min + SUBBUCKETSIZE - 1) / SUBBUCKETSIZE)
|
||||||
|
|
||||||
indexes = make([]int32, n)
|
indexes := make([]int32, n)
|
||||||
for i = 0; i < n; i++ {
|
for i := int32(0); i < n; i++ {
|
||||||
indexes[i] = NOIDX
|
indexes[i] = NOIDX
|
||||||
}
|
}
|
||||||
idx = 0
|
idx := int32(0)
|
||||||
for s = Ctxt.Textp; s != nil; s = s.Next {
|
var e *LSym
|
||||||
|
var i int32
|
||||||
|
var p int64
|
||||||
|
var q int64
|
||||||
|
for s := Ctxt.Textp; s != nil; s = s.Next {
|
||||||
if container(s) != 0 {
|
if container(s) != 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -461,12 +425,14 @@ func findfunctab() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate table
|
// allocate table
|
||||||
nbuckets = int32((max - min + BUCKETSIZE - 1) / BUCKETSIZE)
|
nbuckets := int32((max - min + BUCKETSIZE - 1) / BUCKETSIZE)
|
||||||
|
|
||||||
Symgrow(Ctxt, t, 4*int64(nbuckets)+int64(n))
|
Symgrow(Ctxt, t, 4*int64(nbuckets)+int64(n))
|
||||||
|
|
||||||
// fill in table
|
// fill in table
|
||||||
for i = 0; i < nbuckets; i++ {
|
var base int32
|
||||||
|
var j int32
|
||||||
|
for i := int32(0); i < nbuckets; i++ {
|
||||||
base = indexes[i*SUBBUCKETS]
|
base = indexes[i*SUBBUCKETS]
|
||||||
if base == NOIDX {
|
if base == NOIDX {
|
||||||
Diag("hole in findfunctab")
|
Diag("hole in findfunctab")
|
||||||
|
|
|
||||||
|
|
@ -371,14 +371,12 @@ var coffsym []COFFSym
|
||||||
var ncoffsym int
|
var ncoffsym int
|
||||||
|
|
||||||
func addpesection(name string, sectsize int, filesize int) *IMAGE_SECTION_HEADER {
|
func addpesection(name string, sectsize int, filesize int) *IMAGE_SECTION_HEADER {
|
||||||
var h *IMAGE_SECTION_HEADER
|
|
||||||
|
|
||||||
if pensect == 16 {
|
if pensect == 16 {
|
||||||
Diag("too many sections")
|
Diag("too many sections")
|
||||||
Errorexit()
|
Errorexit()
|
||||||
}
|
}
|
||||||
|
|
||||||
h = &sh[pensect]
|
h := &sh[pensect]
|
||||||
pensect++
|
pensect++
|
||||||
copy(h.Name[:], name)
|
copy(h.Name[:], name)
|
||||||
h.VirtualSize = uint32(sectsize)
|
h.VirtualSize = uint32(sectsize)
|
||||||
|
|
@ -466,14 +464,11 @@ func strput(s string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func initdynimport() *Dll {
|
func initdynimport() *Dll {
|
||||||
var m *Imp
|
|
||||||
var d *Dll
|
var d *Dll
|
||||||
var s *LSym
|
|
||||||
var dynamic *LSym
|
|
||||||
|
|
||||||
dr = nil
|
dr = nil
|
||||||
m = nil
|
m := (*Imp)(nil)
|
||||||
for s = Ctxt.Allsym; s != nil; s = s.Allsym {
|
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
||||||
if !s.Reachable || s.Type != SDYNIMPORT {
|
if !s.Reachable || s.Type != SDYNIMPORT {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -497,10 +492,10 @@ func initdynimport() *Dll {
|
||||||
d.ms = m
|
d.ms = m
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic = Linklookup(Ctxt, ".windynamic", 0)
|
dynamic := Linklookup(Ctxt, ".windynamic", 0)
|
||||||
dynamic.Reachable = true
|
dynamic.Reachable = true
|
||||||
dynamic.Type = SWINDOWS
|
dynamic.Type = SWINDOWS
|
||||||
for d = dr; d != nil; d = d.next {
|
for d := dr; d != nil; d = d.next {
|
||||||
for m = d.ms; m != nil; m = m.next {
|
for m = d.ms; m != nil; m = m.next {
|
||||||
m.s.Type = SWINDOWS | SSUB
|
m.s.Type = SWINDOWS | SSUB
|
||||||
m.s.Sub = dynamic.Sub
|
m.s.Sub = dynamic.Sub
|
||||||
|
|
@ -516,35 +511,26 @@ func initdynimport() *Dll {
|
||||||
}
|
}
|
||||||
|
|
||||||
func addimports(datsect *IMAGE_SECTION_HEADER) {
|
func addimports(datsect *IMAGE_SECTION_HEADER) {
|
||||||
var isect *IMAGE_SECTION_HEADER
|
startoff := Cpos()
|
||||||
var n uint64
|
dynamic := Linklookup(Ctxt, ".windynamic", 0)
|
||||||
var oftbase uint64
|
|
||||||
var ftbase uint64
|
|
||||||
var startoff int64
|
|
||||||
var endoff int64
|
|
||||||
var m *Imp
|
|
||||||
var d *Dll
|
|
||||||
var dynamic *LSym
|
|
||||||
|
|
||||||
startoff = Cpos()
|
|
||||||
dynamic = Linklookup(Ctxt, ".windynamic", 0)
|
|
||||||
|
|
||||||
// skip import descriptor table (will write it later)
|
// skip import descriptor table (will write it later)
|
||||||
n = 0
|
n := uint64(0)
|
||||||
|
|
||||||
for d = dr; d != nil; d = d.next {
|
for d := dr; d != nil; d = d.next {
|
||||||
n++
|
n++
|
||||||
}
|
}
|
||||||
Cseek(startoff + int64(binary.Size(&IMAGE_IMPORT_DESCRIPTOR{}))*int64(n+1))
|
Cseek(startoff + int64(binary.Size(&IMAGE_IMPORT_DESCRIPTOR{}))*int64(n+1))
|
||||||
|
|
||||||
// write dll names
|
// write dll names
|
||||||
for d = dr; d != nil; d = d.next {
|
for d := dr; d != nil; d = d.next {
|
||||||
d.nameoff = uint64(Cpos()) - uint64(startoff)
|
d.nameoff = uint64(Cpos()) - uint64(startoff)
|
||||||
strput(d.name)
|
strput(d.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// write function names
|
// write function names
|
||||||
for d = dr; d != nil; d = d.next {
|
var m *Imp
|
||||||
|
for d := dr; d != nil; d = d.next {
|
||||||
for m = d.ms; m != nil; m = m.next {
|
for m = d.ms; m != nil; m = m.next {
|
||||||
m.off = uint64(nextsectoff) + uint64(Cpos()) - uint64(startoff)
|
m.off = uint64(nextsectoff) + uint64(Cpos()) - uint64(startoff)
|
||||||
Wputl(0) // hint
|
Wputl(0) // hint
|
||||||
|
|
@ -553,10 +539,10 @@ func addimports(datsect *IMAGE_SECTION_HEADER) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// write OriginalFirstThunks
|
// write OriginalFirstThunks
|
||||||
oftbase = uint64(Cpos()) - uint64(startoff)
|
oftbase := uint64(Cpos()) - uint64(startoff)
|
||||||
|
|
||||||
n = uint64(Cpos())
|
n = uint64(Cpos())
|
||||||
for d = dr; d != nil; d = d.next {
|
for d := dr; d != nil; d = d.next {
|
||||||
d.thunkoff = uint64(Cpos()) - n
|
d.thunkoff = uint64(Cpos()) - n
|
||||||
for m = d.ms; m != nil; m = m.next {
|
for m = d.ms; m != nil; m = m.next {
|
||||||
if pe64 != 0 {
|
if pe64 != 0 {
|
||||||
|
|
@ -576,17 +562,17 @@ func addimports(datsect *IMAGE_SECTION_HEADER) {
|
||||||
// add pe section and pad it at the end
|
// add pe section and pad it at the end
|
||||||
n = uint64(Cpos()) - uint64(startoff)
|
n = uint64(Cpos()) - uint64(startoff)
|
||||||
|
|
||||||
isect = addpesection(".idata", int(n), int(n))
|
isect := addpesection(".idata", int(n), int(n))
|
||||||
isect.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
|
isect.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
|
||||||
chksectoff(isect, startoff)
|
chksectoff(isect, startoff)
|
||||||
strnput("", int(uint64(isect.SizeOfRawData)-n))
|
strnput("", int(uint64(isect.SizeOfRawData)-n))
|
||||||
endoff = Cpos()
|
endoff := Cpos()
|
||||||
|
|
||||||
// write FirstThunks (allocated in .data section)
|
// write FirstThunks (allocated in .data section)
|
||||||
ftbase = uint64(dynamic.Value) - uint64(datsect.VirtualAddress) - PEBASE
|
ftbase := uint64(dynamic.Value) - uint64(datsect.VirtualAddress) - PEBASE
|
||||||
|
|
||||||
Cseek(int64(uint64(datsect.PointerToRawData) + ftbase))
|
Cseek(int64(uint64(datsect.PointerToRawData) + ftbase))
|
||||||
for d = dr; d != nil; d = d.next {
|
for d := dr; d != nil; d = d.next {
|
||||||
for m = d.ms; m != nil; m = m.next {
|
for m = d.ms; m != nil; m = m.next {
|
||||||
if pe64 != 0 {
|
if pe64 != 0 {
|
||||||
Vputl(m.off)
|
Vputl(m.off)
|
||||||
|
|
@ -605,7 +591,7 @@ func addimports(datsect *IMAGE_SECTION_HEADER) {
|
||||||
// finally write import descriptor table
|
// finally write import descriptor table
|
||||||
Cseek(startoff)
|
Cseek(startoff)
|
||||||
|
|
||||||
for d = dr; d != nil; d = d.next {
|
for d := dr; d != nil; d = d.next {
|
||||||
Lputl(uint32(uint64(isect.VirtualAddress) + oftbase + d.thunkoff))
|
Lputl(uint32(uint64(isect.VirtualAddress) + oftbase + d.thunkoff))
|
||||||
Lputl(0)
|
Lputl(0)
|
||||||
Lputl(0)
|
Lputl(0)
|
||||||
|
|
@ -640,19 +626,14 @@ func (x pescmp) Swap(i, j int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x pescmp) Less(i, j int) bool {
|
func (x pescmp) Less(i, j int) bool {
|
||||||
var s1 *LSym
|
s1 := x[i]
|
||||||
var s2 *LSym
|
s2 := x[j]
|
||||||
|
|
||||||
s1 = x[i]
|
|
||||||
s2 = x[j]
|
|
||||||
return stringsCompare(s1.Extname, s2.Extname) < 0
|
return stringsCompare(s1.Extname, s2.Extname) < 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func initdynexport() {
|
func initdynexport() {
|
||||||
var s *LSym
|
|
||||||
|
|
||||||
nexport = 0
|
nexport = 0
|
||||||
for s = Ctxt.Allsym; s != nil; s = s.Allsym {
|
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
||||||
if !s.Reachable || s.Cgoexport&CgoExportDynamic == 0 {
|
if !s.Reachable || s.Cgoexport&CgoExportDynamic == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -669,18 +650,10 @@ func initdynexport() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func addexports() {
|
func addexports() {
|
||||||
var sect *IMAGE_SECTION_HEADER
|
|
||||||
var e IMAGE_EXPORT_DIRECTORY
|
var e IMAGE_EXPORT_DIRECTORY
|
||||||
var size int
|
|
||||||
var i int
|
|
||||||
var va int
|
|
||||||
var va_name int
|
|
||||||
var va_addr int
|
|
||||||
var va_na int
|
|
||||||
var v int
|
|
||||||
|
|
||||||
size = binary.Size(&e) + 10*nexport + len(outfile) + 1
|
size := binary.Size(&e) + 10*nexport + len(outfile) + 1
|
||||||
for i = 0; i < nexport; i++ {
|
for i := 0; i < nexport; i++ {
|
||||||
size += len(dexport[i].Extname) + 1
|
size += len(dexport[i].Extname) + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -688,16 +661,16 @@ func addexports() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sect = addpesection(".edata", size, size)
|
sect := addpesection(".edata", size, size)
|
||||||
sect.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
|
sect.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
|
||||||
chksectoff(sect, Cpos())
|
chksectoff(sect, Cpos())
|
||||||
va = int(sect.VirtualAddress)
|
va := int(sect.VirtualAddress)
|
||||||
dd[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = uint32(va)
|
dd[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = uint32(va)
|
||||||
dd[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = sect.VirtualSize
|
dd[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = sect.VirtualSize
|
||||||
|
|
||||||
va_name = va + binary.Size(&e) + nexport*4
|
va_name := va + binary.Size(&e) + nexport*4
|
||||||
va_addr = va + binary.Size(&e)
|
va_addr := va + binary.Size(&e)
|
||||||
va_na = va + binary.Size(&e) + nexport*8
|
va_na := va + binary.Size(&e) + nexport*8
|
||||||
|
|
||||||
e.Characteristics = 0
|
e.Characteristics = 0
|
||||||
e.MajorVersion = 0
|
e.MajorVersion = 0
|
||||||
|
|
@ -714,37 +687,35 @@ func addexports() {
|
||||||
binary.Write(&coutbuf, binary.LittleEndian, &e)
|
binary.Write(&coutbuf, binary.LittleEndian, &e)
|
||||||
|
|
||||||
// put EXPORT Address Table
|
// put EXPORT Address Table
|
||||||
for i = 0; i < nexport; i++ {
|
for i := 0; i < nexport; i++ {
|
||||||
Lputl(uint32(dexport[i].Value - PEBASE))
|
Lputl(uint32(dexport[i].Value - PEBASE))
|
||||||
}
|
}
|
||||||
|
|
||||||
// put EXPORT Name Pointer Table
|
// put EXPORT Name Pointer Table
|
||||||
v = int(e.Name + uint32(len(outfile)) + 1)
|
v := int(e.Name + uint32(len(outfile)) + 1)
|
||||||
|
|
||||||
for i = 0; i < nexport; i++ {
|
for i := 0; i < nexport; i++ {
|
||||||
Lputl(uint32(v))
|
Lputl(uint32(v))
|
||||||
v += len(dexport[i].Extname) + 1
|
v += len(dexport[i].Extname) + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// put EXPORT Ordinal Table
|
// put EXPORT Ordinal Table
|
||||||
for i = 0; i < nexport; i++ {
|
for i := 0; i < nexport; i++ {
|
||||||
Wputl(uint16(i))
|
Wputl(uint16(i))
|
||||||
}
|
}
|
||||||
|
|
||||||
// put Names
|
// put Names
|
||||||
strnput(outfile, len(outfile)+1)
|
strnput(outfile, len(outfile)+1)
|
||||||
|
|
||||||
for i = 0; i < nexport; i++ {
|
for i := 0; i < nexport; i++ {
|
||||||
strnput(dexport[i].Extname, len(dexport[i].Extname)+1)
|
strnput(dexport[i].Extname, len(dexport[i].Extname)+1)
|
||||||
}
|
}
|
||||||
strnput("", int(sect.SizeOfRawData-uint32(size)))
|
strnput("", int(sect.SizeOfRawData-uint32(size)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func dope() {
|
func dope() {
|
||||||
var rel *LSym
|
|
||||||
|
|
||||||
/* relocation table */
|
/* relocation table */
|
||||||
rel = Linklookup(Ctxt, ".rel", 0)
|
rel := Linklookup(Ctxt, ".rel", 0)
|
||||||
|
|
||||||
rel.Reachable = true
|
rel.Reachable = true
|
||||||
rel.Type = SELFROSECT
|
rel.Type = SELFROSECT
|
||||||
|
|
@ -768,25 +739,19 @@ func strtbladd(name string) int {
|
||||||
* <http://www.microsoft.com/whdc/system/platform/firmware/PECOFFdwn.mspx>
|
* <http://www.microsoft.com/whdc/system/platform/firmware/PECOFFdwn.mspx>
|
||||||
*/
|
*/
|
||||||
func newPEDWARFSection(name string, size int64) *IMAGE_SECTION_HEADER {
|
func newPEDWARFSection(name string, size int64) *IMAGE_SECTION_HEADER {
|
||||||
var h *IMAGE_SECTION_HEADER
|
|
||||||
var s string
|
|
||||||
var off int
|
|
||||||
|
|
||||||
if size == 0 {
|
if size == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
off = strtbladd(name)
|
off := strtbladd(name)
|
||||||
s = fmt.Sprintf("/%d", off)
|
s := fmt.Sprintf("/%d", off)
|
||||||
h = addpesection(s, int(size), int(size))
|
h := addpesection(s, int(size), int(size))
|
||||||
h.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
|
h.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
|
||||||
|
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
func addpesym(s *LSym, name string, type_ int, addr int64, size int64, ver int, gotype *LSym) {
|
func addpesym(s *LSym, name string, type_ int, addr int64, size int64, ver int, gotype *LSym) {
|
||||||
var cs *COFFSym
|
|
||||||
|
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -806,7 +771,7 @@ func addpesym(s *LSym, name string, type_ int, addr int64, size int64, ver int,
|
||||||
}
|
}
|
||||||
|
|
||||||
if coffsym != nil {
|
if coffsym != nil {
|
||||||
cs = &coffsym[ncoffsym]
|
cs := &coffsym[ncoffsym]
|
||||||
cs.sym = s
|
cs.sym = s
|
||||||
if len(s.Name) > 8 {
|
if len(s.Name) > 8 {
|
||||||
cs.strtbloff = strtbladd(s.Name)
|
cs.strtbloff = strtbladd(s.Name)
|
||||||
|
|
@ -828,11 +793,6 @@ func addpesym(s *LSym, name string, type_ int, addr int64, size int64, ver int,
|
||||||
}
|
}
|
||||||
|
|
||||||
func addpesymtable() {
|
func addpesymtable() {
|
||||||
var h *IMAGE_SECTION_HEADER
|
|
||||||
var i int
|
|
||||||
var size int
|
|
||||||
var s *COFFSym
|
|
||||||
|
|
||||||
if Debug['s'] == 0 {
|
if Debug['s'] == 0 {
|
||||||
genasmsym(addpesym)
|
genasmsym(addpesym)
|
||||||
coffsym = make([]COFFSym, ncoffsym)
|
coffsym = make([]COFFSym, ncoffsym)
|
||||||
|
|
@ -840,15 +800,16 @@ func addpesymtable() {
|
||||||
genasmsym(addpesym)
|
genasmsym(addpesym)
|
||||||
}
|
}
|
||||||
|
|
||||||
size = len(strtbl) + 4 + 18*ncoffsym
|
size := len(strtbl) + 4 + 18*ncoffsym
|
||||||
h = addpesection(".symtab", size, size)
|
h := addpesection(".symtab", size, size)
|
||||||
h.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
|
h.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
|
||||||
chksectoff(h, Cpos())
|
chksectoff(h, Cpos())
|
||||||
fh.PointerToSymbolTable = uint32(Cpos())
|
fh.PointerToSymbolTable = uint32(Cpos())
|
||||||
fh.NumberOfSymbols = uint32(ncoffsym)
|
fh.NumberOfSymbols = uint32(ncoffsym)
|
||||||
|
|
||||||
// put COFF symbol table
|
// put COFF symbol table
|
||||||
for i = 0; i < ncoffsym; i++ {
|
var s *COFFSym
|
||||||
|
for i := 0; i < ncoffsym; i++ {
|
||||||
s = &coffsym[i]
|
s = &coffsym[i]
|
||||||
if s.strtbloff == 0 {
|
if s.strtbloff == 0 {
|
||||||
strnput(s.sym.Name, 8)
|
strnput(s.sym.Name, 8)
|
||||||
|
|
@ -867,7 +828,7 @@ func addpesymtable() {
|
||||||
// put COFF string table
|
// put COFF string table
|
||||||
Lputl(uint32(len(strtbl)) + 4)
|
Lputl(uint32(len(strtbl)) + 4)
|
||||||
|
|
||||||
for i = 0; i < len(strtbl); i++ {
|
for i := 0; i < len(strtbl); i++ {
|
||||||
Cput(uint8(strtbl[i]))
|
Cput(uint8(strtbl[i]))
|
||||||
}
|
}
|
||||||
strnput("", int(h.SizeOfRawData-uint32(size)))
|
strnput("", int(h.SizeOfRawData-uint32(size)))
|
||||||
|
|
@ -882,22 +843,19 @@ func setpersrc(sym *LSym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func addpersrc() {
|
func addpersrc() {
|
||||||
var h *IMAGE_SECTION_HEADER
|
|
||||||
var p []byte
|
|
||||||
var val uint32
|
|
||||||
var r *Reloc
|
|
||||||
var ri int
|
|
||||||
|
|
||||||
if rsrcsym == nil {
|
if rsrcsym == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
h = addpesection(".rsrc", int(rsrcsym.Size), int(rsrcsym.Size))
|
h := addpesection(".rsrc", int(rsrcsym.Size), int(rsrcsym.Size))
|
||||||
h.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_INITIALIZED_DATA
|
h.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_INITIALIZED_DATA
|
||||||
chksectoff(h, Cpos())
|
chksectoff(h, Cpos())
|
||||||
|
|
||||||
// relocation
|
// relocation
|
||||||
for ri = 0; ri < len(rsrcsym.R); ri++ {
|
var p []byte
|
||||||
|
var r *Reloc
|
||||||
|
var val uint32
|
||||||
|
for ri := 0; ri < len(rsrcsym.R); ri++ {
|
||||||
r = &rsrcsym.R[ri]
|
r = &rsrcsym.R[ri]
|
||||||
p = rsrcsym.P[r.Off:]
|
p = rsrcsym.P[r.Off:]
|
||||||
val = uint32(int64(h.VirtualAddress) + r.Add)
|
val = uint32(int64(h.VirtualAddress) + r.Add)
|
||||||
|
|
@ -920,9 +878,6 @@ func addpersrc() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Asmbpe() {
|
func Asmbpe() {
|
||||||
var t *IMAGE_SECTION_HEADER
|
|
||||||
var d *IMAGE_SECTION_HEADER
|
|
||||||
|
|
||||||
switch Thearch.Thechar {
|
switch Thearch.Thechar {
|
||||||
default:
|
default:
|
||||||
Diag("unknown PE architecture")
|
Diag("unknown PE architecture")
|
||||||
|
|
@ -936,12 +891,12 @@ func Asmbpe() {
|
||||||
fh.Machine = IMAGE_FILE_MACHINE_I386
|
fh.Machine = IMAGE_FILE_MACHINE_I386
|
||||||
}
|
}
|
||||||
|
|
||||||
t = addpesection(".text", int(Segtext.Length), int(Segtext.Length))
|
t := addpesection(".text", int(Segtext.Length), int(Segtext.Length))
|
||||||
t.Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ
|
t.Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ
|
||||||
chksectseg(t, &Segtext)
|
chksectseg(t, &Segtext)
|
||||||
textsect = pensect
|
textsect = pensect
|
||||||
|
|
||||||
d = addpesection(".data", int(Segdata.Length), int(Segdata.Filelen))
|
d := addpesection(".data", int(Segdata.Length), int(Segdata.Filelen))
|
||||||
d.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
|
d.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
|
||||||
chksectseg(d, &Segdata)
|
chksectseg(d, &Segdata)
|
||||||
datasect = pensect
|
datasect = pensect
|
||||||
|
|
|
||||||
|
|
@ -63,21 +63,18 @@ var headers = []struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func linknew(arch *LinkArch) *Link {
|
func linknew(arch *LinkArch) *Link {
|
||||||
var ctxt *Link
|
ctxt := new(Link)
|
||||||
var p string
|
|
||||||
var buf string
|
|
||||||
|
|
||||||
ctxt = new(Link)
|
|
||||||
ctxt.Hash = make(map[symVer]*LSym)
|
ctxt.Hash = make(map[symVer]*LSym)
|
||||||
ctxt.Arch = arch
|
ctxt.Arch = arch
|
||||||
ctxt.Version = HistVersion
|
ctxt.Version = HistVersion
|
||||||
ctxt.Goroot = obj.Getgoroot()
|
ctxt.Goroot = obj.Getgoroot()
|
||||||
|
|
||||||
p = obj.Getgoarch()
|
p := obj.Getgoarch()
|
||||||
if p != arch.Name {
|
if p != arch.Name {
|
||||||
log.Fatalf("invalid goarch %s (want %s)", p, arch.Name)
|
log.Fatalf("invalid goarch %s (want %s)", p, arch.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var buf string
|
||||||
buf, _ = os.Getwd()
|
buf, _ = os.Getwd()
|
||||||
if buf == "" {
|
if buf == "" {
|
||||||
buf = "/???"
|
buf = "/???"
|
||||||
|
|
@ -149,7 +146,7 @@ func linknew(arch *LinkArch) *Link {
|
||||||
|
|
||||||
// On arm, record goarm.
|
// On arm, record goarm.
|
||||||
if ctxt.Arch.Thechar == '5' {
|
if ctxt.Arch.Thechar == '5' {
|
||||||
p = obj.Getgoarm()
|
p := obj.Getgoarm()
|
||||||
if p != "" {
|
if p != "" {
|
||||||
ctxt.Goarm = int32(obj.Atoi(p))
|
ctxt.Goarm = int32(obj.Atoi(p))
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -161,9 +158,7 @@ func linknew(arch *LinkArch) *Link {
|
||||||
}
|
}
|
||||||
|
|
||||||
func linknewsym(ctxt *Link, symb string, v int) *LSym {
|
func linknewsym(ctxt *Link, symb string, v int) *LSym {
|
||||||
var s *LSym
|
s := new(LSym)
|
||||||
|
|
||||||
s = new(LSym)
|
|
||||||
*s = LSym{}
|
*s = LSym{}
|
||||||
|
|
||||||
s.Dynid = -1
|
s.Dynid = -1
|
||||||
|
|
@ -215,9 +210,7 @@ func Linkrlookup(ctxt *Link, name string, v int) *LSym {
|
||||||
var headstr_buf string
|
var headstr_buf string
|
||||||
|
|
||||||
func Headstr(v int) string {
|
func Headstr(v int) string {
|
||||||
var i int
|
for i := 0; i < len(headers); i++ {
|
||||||
|
|
||||||
for i = 0; i < len(headers); i++ {
|
|
||||||
if v == headers[i].val {
|
if v == headers[i].val {
|
||||||
return headers[i].name
|
return headers[i].name
|
||||||
}
|
}
|
||||||
|
|
@ -227,9 +220,7 @@ func Headstr(v int) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func headtype(name string) int {
|
func headtype(name string) int {
|
||||||
var i int
|
for i := 0; i < len(headers); i++ {
|
||||||
|
|
||||||
for i = 0; i < len(headers); i++ {
|
|
||||||
if name == headers[i].name {
|
if name == headers[i].name {
|
||||||
return headers[i].val
|
return headers[i].val
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,6 @@ import "strings"
|
||||||
var maxelfstr int
|
var maxelfstr int
|
||||||
|
|
||||||
func putelfstr(s string) int {
|
func putelfstr(s string) int {
|
||||||
var off int
|
|
||||||
var n int
|
|
||||||
|
|
||||||
if len(Elfstrdat) == 0 && s != "" {
|
if len(Elfstrdat) == 0 && s != "" {
|
||||||
// first entry must be empty string
|
// first entry must be empty string
|
||||||
putelfstr("")
|
putelfstr("")
|
||||||
|
|
@ -48,12 +45,12 @@ func putelfstr(s string) int {
|
||||||
// Rewrite · to . for ASCII-only tools like DTrace (sigh)
|
// Rewrite · to . for ASCII-only tools like DTrace (sigh)
|
||||||
s = strings.Replace(s, "·", ".", -1)
|
s = strings.Replace(s, "·", ".", -1)
|
||||||
|
|
||||||
n = len(s) + 1
|
n := len(s) + 1
|
||||||
for len(Elfstrdat)+n > cap(Elfstrdat) {
|
for len(Elfstrdat)+n > cap(Elfstrdat) {
|
||||||
Elfstrdat = append(Elfstrdat[:cap(Elfstrdat)], 0)[:len(Elfstrdat)]
|
Elfstrdat = append(Elfstrdat[:cap(Elfstrdat)], 0)[:len(Elfstrdat)]
|
||||||
}
|
}
|
||||||
|
|
||||||
off = len(Elfstrdat)
|
off := len(Elfstrdat)
|
||||||
Elfstrdat = Elfstrdat[:off+n]
|
Elfstrdat = Elfstrdat[:off+n]
|
||||||
copy(Elfstrdat[off:], s)
|
copy(Elfstrdat[off:], s)
|
||||||
|
|
||||||
|
|
@ -88,11 +85,7 @@ var numelfsym int = 1 // 0 is reserved
|
||||||
var elfbind int
|
var elfbind int
|
||||||
|
|
||||||
func putelfsym(x *LSym, s string, t int, addr int64, size int64, ver int, go_ *LSym) {
|
func putelfsym(x *LSym, s string, t int, addr int64, size int64, ver int, go_ *LSym) {
|
||||||
var bind int
|
|
||||||
var type_ int
|
var type_ int
|
||||||
var off int
|
|
||||||
var other int
|
|
||||||
var xo *LSym
|
|
||||||
|
|
||||||
switch t {
|
switch t {
|
||||||
default:
|
default:
|
||||||
|
|
@ -108,7 +101,7 @@ func putelfsym(x *LSym, s string, t int, addr int64, size int64, ver int, go_ *L
|
||||||
type_ = STT_OBJECT
|
type_ = STT_OBJECT
|
||||||
}
|
}
|
||||||
|
|
||||||
xo = x
|
xo := x
|
||||||
for xo.Outer != nil {
|
for xo.Outer != nil {
|
||||||
xo = xo.Outer
|
xo = xo.Outer
|
||||||
}
|
}
|
||||||
|
|
@ -126,7 +119,7 @@ func putelfsym(x *LSym, s string, t int, addr int64, size int64, ver int, go_ *L
|
||||||
|
|
||||||
// One pass for each binding: STB_LOCAL, STB_GLOBAL,
|
// One pass for each binding: STB_LOCAL, STB_GLOBAL,
|
||||||
// maybe one day STB_WEAK.
|
// maybe one day STB_WEAK.
|
||||||
bind = STB_GLOBAL
|
bind := STB_GLOBAL
|
||||||
|
|
||||||
if ver != 0 || (x.Type&SHIDDEN != 0) {
|
if ver != 0 || (x.Type&SHIDDEN != 0) {
|
||||||
bind = STB_LOCAL
|
bind = STB_LOCAL
|
||||||
|
|
@ -144,11 +137,11 @@ func putelfsym(x *LSym, s string, t int, addr int64, size int64, ver int, go_ *L
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
off = putelfstr(s)
|
off := putelfstr(s)
|
||||||
if Linkmode == LinkExternal {
|
if Linkmode == LinkExternal {
|
||||||
addr -= int64((xo.Sect.(*Section)).Vaddr)
|
addr -= int64((xo.Sect.(*Section)).Vaddr)
|
||||||
}
|
}
|
||||||
other = 2
|
other := 2
|
||||||
if x.Type&SHIDDEN != 0 {
|
if x.Type&SHIDDEN != 0 {
|
||||||
other = 0
|
other = 0
|
||||||
}
|
}
|
||||||
|
|
@ -164,9 +157,7 @@ func putelfsectionsym(s *LSym, shndx int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func putelfsymshndx(sympos int64, shndx int) {
|
func putelfsymshndx(sympos int64, shndx int) {
|
||||||
var here int64
|
here := Cpos()
|
||||||
|
|
||||||
here = Cpos()
|
|
||||||
switch Thearch.Thechar {
|
switch Thearch.Thechar {
|
||||||
case '6':
|
case '6':
|
||||||
Cseek(sympos + 6)
|
Cseek(sympos + 6)
|
||||||
|
|
@ -180,9 +171,6 @@ func putelfsymshndx(sympos int64, shndx int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Asmelfsym() {
|
func Asmelfsym() {
|
||||||
var s *LSym
|
|
||||||
var name string
|
|
||||||
|
|
||||||
// the first symbol entry is reserved
|
// the first symbol entry is reserved
|
||||||
putelfsyment(0, 0, 0, STB_LOCAL<<4|STT_NOTYPE, 0, 0)
|
putelfsyment(0, 0, 0, STB_LOCAL<<4|STT_NOTYPE, 0, 0)
|
||||||
|
|
||||||
|
|
@ -192,7 +180,7 @@ func Asmelfsym() {
|
||||||
genasmsym(putelfsym)
|
genasmsym(putelfsym)
|
||||||
|
|
||||||
if Linkmode == LinkExternal && HEADTYPE != Hopenbsd {
|
if Linkmode == LinkExternal && HEADTYPE != Hopenbsd {
|
||||||
s = Linklookup(Ctxt, "runtime.tlsg", 0)
|
s := Linklookup(Ctxt, "runtime.tlsg", 0)
|
||||||
if s.Sect == nil {
|
if s.Sect == nil {
|
||||||
Ctxt.Cursym = nil
|
Ctxt.Cursym = nil
|
||||||
Diag("missing section for %s", s.Name)
|
Diag("missing section for %s", s.Name)
|
||||||
|
|
@ -214,7 +202,8 @@ func Asmelfsym() {
|
||||||
elfglobalsymndx = numelfsym
|
elfglobalsymndx = numelfsym
|
||||||
genasmsym(putelfsym)
|
genasmsym(putelfsym)
|
||||||
|
|
||||||
for s = Ctxt.Allsym; s != nil; s = s.Allsym {
|
var name string
|
||||||
|
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
||||||
if s.Type != SHOSTOBJ && (s.Type != SDYNIMPORT || !s.Reachable) {
|
if s.Type != SHOSTOBJ && (s.Type != SDYNIMPORT || !s.Reachable) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -230,9 +219,6 @@ func Asmelfsym() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func putplan9sym(x *LSym, s string, t int, addr int64, size int64, ver int, go_ *LSym) {
|
func putplan9sym(x *LSym, s string, t int, addr int64, size int64, ver int, go_ *LSym) {
|
||||||
var i int
|
|
||||||
var l int
|
|
||||||
|
|
||||||
switch t {
|
switch t {
|
||||||
case 'T',
|
case 'T',
|
||||||
'L',
|
'L',
|
||||||
|
|
@ -249,7 +235,7 @@ func putplan9sym(x *LSym, s string, t int, addr int64, size int64, ver int, go_
|
||||||
'z',
|
'z',
|
||||||
'Z',
|
'Z',
|
||||||
'm':
|
'm':
|
||||||
l = 4
|
l := 4
|
||||||
if HEADTYPE == Hplan9 && Thearch.Thechar == '6' && Debug['8'] == 0 {
|
if HEADTYPE == Hplan9 && Thearch.Thechar == '6' && Debug['8'] == 0 {
|
||||||
Lputb(uint32(addr >> 32))
|
Lputb(uint32(addr >> 32))
|
||||||
l = 8
|
l = 8
|
||||||
|
|
@ -258,6 +244,7 @@ func putplan9sym(x *LSym, s string, t int, addr int64, size int64, ver int, go_
|
||||||
Lputb(uint32(addr))
|
Lputb(uint32(addr))
|
||||||
Cput(uint8(t + 0x80)) /* 0x80 is variable length */
|
Cput(uint8(t + 0x80)) /* 0x80 is variable length */
|
||||||
|
|
||||||
|
var i int
|
||||||
if t == 'z' || t == 'Z' {
|
if t == 'z' || t == 'Z' {
|
||||||
Cput(uint8(s[0]))
|
Cput(uint8(s[0]))
|
||||||
for i = 1; s[i] != 0 || s[i+1] != 0; i += 2 {
|
for i = 1; s[i] != 0 || s[i+1] != 0; i += 2 {
|
||||||
|
|
@ -327,12 +314,6 @@ func Vputl(v uint64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func symtab() {
|
func symtab() {
|
||||||
var s *LSym
|
|
||||||
var symtype *LSym
|
|
||||||
var symtypelink *LSym
|
|
||||||
var symgostring *LSym
|
|
||||||
var symgofunc *LSym
|
|
||||||
|
|
||||||
dosymtype()
|
dosymtype()
|
||||||
|
|
||||||
// Define these so that they'll get put into the symbol table.
|
// Define these so that they'll get put into the symbol table.
|
||||||
|
|
@ -357,7 +338,7 @@ func symtab() {
|
||||||
xdefine("runtime.esymtab", SRODATA, 0)
|
xdefine("runtime.esymtab", SRODATA, 0)
|
||||||
|
|
||||||
// garbage collection symbols
|
// garbage collection symbols
|
||||||
s = Linklookup(Ctxt, "runtime.gcdata", 0)
|
s := Linklookup(Ctxt, "runtime.gcdata", 0)
|
||||||
|
|
||||||
s.Type = SRODATA
|
s.Type = SRODATA
|
||||||
s.Size = 0
|
s.Size = 0
|
||||||
|
|
@ -376,21 +357,21 @@ func symtab() {
|
||||||
s.Type = STYPE
|
s.Type = STYPE
|
||||||
s.Size = 0
|
s.Size = 0
|
||||||
s.Reachable = true
|
s.Reachable = true
|
||||||
symtype = s
|
symtype := s
|
||||||
|
|
||||||
s = Linklookup(Ctxt, "go.string.*", 0)
|
s = Linklookup(Ctxt, "go.string.*", 0)
|
||||||
s.Type = SGOSTRING
|
s.Type = SGOSTRING
|
||||||
s.Size = 0
|
s.Size = 0
|
||||||
s.Reachable = true
|
s.Reachable = true
|
||||||
symgostring = s
|
symgostring := s
|
||||||
|
|
||||||
s = Linklookup(Ctxt, "go.func.*", 0)
|
s = Linklookup(Ctxt, "go.func.*", 0)
|
||||||
s.Type = SGOFUNC
|
s.Type = SGOFUNC
|
||||||
s.Size = 0
|
s.Size = 0
|
||||||
s.Reachable = true
|
s.Reachable = true
|
||||||
symgofunc = s
|
symgofunc := s
|
||||||
|
|
||||||
symtypelink = Linklookup(Ctxt, "runtime.typelink", 0)
|
symtypelink := Linklookup(Ctxt, "runtime.typelink", 0)
|
||||||
|
|
||||||
symt = Linklookup(Ctxt, "runtime.symtab", 0)
|
symt = Linklookup(Ctxt, "runtime.symtab", 0)
|
||||||
symt.Type = SSYMTAB
|
symt.Type = SSYMTAB
|
||||||
|
|
@ -401,7 +382,7 @@ func symtab() {
|
||||||
// within a type they sort by size, so the .* symbols
|
// within a type they sort by size, so the .* symbols
|
||||||
// just defined above will be first.
|
// just defined above will be first.
|
||||||
// hide the specific symbols.
|
// hide the specific symbols.
|
||||||
for s = Ctxt.Allsym; s != nil; s = s.Allsym {
|
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
|
||||||
if !s.Reachable || s.Special != 0 || s.Type != SRODATA {
|
if !s.Reachable || s.Special != 0 || s.Type != SRODATA {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,17 +26,14 @@ func cstring(x []byte) string {
|
||||||
|
|
||||||
func plan9quote(s string) string {
|
func plan9quote(s string) string {
|
||||||
if s == "" {
|
if s == "" {
|
||||||
goto needquote
|
return "'" + strings.Replace(s, "'", "''", -1) + "'"
|
||||||
}
|
}
|
||||||
for i := 0; i < len(s); i++ {
|
for i := 0; i < len(s); i++ {
|
||||||
if s[i] <= ' ' || s[i] == '\'' {
|
if s[i] <= ' ' || s[i] == '\'' {
|
||||||
goto needquote
|
return "'" + strings.Replace(s, "'", "''", -1) + "'"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
|
|
||||||
needquote:
|
|
||||||
return "'" + strings.Replace(s, "'", "''", -1) + "'"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func tokenize(s string) []string {
|
func tokenize(s string) []string {
|
||||||
|
|
|
||||||
|
|
@ -304,13 +304,7 @@ func casesz(ctxt *obj.Link, p *obj.Prog) int32 {
|
||||||
// In rare cases, asmoutnacl might split p into two instructions.
|
// In rare cases, asmoutnacl might split p into two instructions.
|
||||||
// origPC is the PC for this Prog (no padding is taken into account).
|
// origPC is the PC for this Prog (no padding is taken into account).
|
||||||
func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint32) int {
|
func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint32) int {
|
||||||
var size int
|
size := int(o.size)
|
||||||
var reg int
|
|
||||||
var q *obj.Prog
|
|
||||||
var a *obj.Addr
|
|
||||||
var a2 *obj.Addr
|
|
||||||
|
|
||||||
size = int(o.size)
|
|
||||||
|
|
||||||
// instruction specific
|
// instruction specific
|
||||||
switch p.As {
|
switch p.As {
|
||||||
|
|
@ -437,11 +431,12 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3
|
||||||
// split it into two instructions:
|
// split it into two instructions:
|
||||||
// ADD $-100004, R13
|
// ADD $-100004, R13
|
||||||
// MOVW R14, 0(R13)
|
// MOVW R14, 0(R13)
|
||||||
q = ctxt.NewProg()
|
q := ctxt.NewProg()
|
||||||
|
|
||||||
p.Scond &^= C_WBIT
|
p.Scond &^= C_WBIT
|
||||||
*q = *p
|
*q = *p
|
||||||
a = &p.To
|
a := &p.To
|
||||||
|
var a2 *obj.Addr
|
||||||
if p.To.Type == obj.TYPE_MEM {
|
if p.To.Type == obj.TYPE_MEM {
|
||||||
a2 = &q.To
|
a2 = &q.To
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -479,12 +474,13 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.To.Type == obj.TYPE_MEM && p.To.Reg != REG_R13 && p.To.Reg != REG_R9) || (p.From.Type == obj.TYPE_MEM && p.From.Reg != REG_R13 && p.From.Reg != REG_R9) { // MOVW Rx, X(Ry), y != 13 && y != 9 // MOVW X(Rx), Ry, x != 13 && x != 9
|
if (p.To.Type == obj.TYPE_MEM && p.To.Reg != REG_R13 && p.To.Reg != REG_R9) || (p.From.Type == obj.TYPE_MEM && p.From.Reg != REG_R13 && p.From.Reg != REG_R9) { // MOVW Rx, X(Ry), y != 13 && y != 9 // MOVW X(Rx), Ry, x != 13 && x != 9
|
||||||
|
var a *obj.Addr
|
||||||
if p.To.Type == obj.TYPE_MEM {
|
if p.To.Type == obj.TYPE_MEM {
|
||||||
a = &p.To
|
a = &p.To
|
||||||
} else {
|
} else {
|
||||||
a = &p.From
|
a = &p.From
|
||||||
}
|
}
|
||||||
reg = int(a.Reg)
|
reg := int(a.Reg)
|
||||||
if size == 4 {
|
if size == 4 {
|
||||||
// if addr.reg == 0, then it is probably load from x(FP) with small x, no need to modify.
|
// if addr.reg == 0, then it is probably load from x(FP) with small x, no need to modify.
|
||||||
if reg == 0 {
|
if reg == 0 {
|
||||||
|
|
@ -514,8 +510,9 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3
|
||||||
if p.Scond&(C_PBIT|C_WBIT) != 0 {
|
if p.Scond&(C_PBIT|C_WBIT) != 0 {
|
||||||
ctxt.Diag("unsupported instruction (.P/.W): %v", p)
|
ctxt.Diag("unsupported instruction (.P/.W): %v", p)
|
||||||
}
|
}
|
||||||
q = ctxt.NewProg()
|
q := ctxt.NewProg()
|
||||||
*q = *p
|
*q = *p
|
||||||
|
var a2 *obj.Addr
|
||||||
if p.To.Type == obj.TYPE_MEM {
|
if p.To.Type == obj.TYPE_MEM {
|
||||||
a2 = &q.To
|
a2 = &q.To
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -577,16 +574,6 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3
|
||||||
func span5(ctxt *obj.Link, cursym *obj.LSym) {
|
func span5(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
var p *obj.Prog
|
var p *obj.Prog
|
||||||
var op *obj.Prog
|
var op *obj.Prog
|
||||||
var o *Optab
|
|
||||||
var m int
|
|
||||||
var bflag int
|
|
||||||
var i int
|
|
||||||
var v int
|
|
||||||
var times int
|
|
||||||
var c int32
|
|
||||||
var opc int32
|
|
||||||
var out [6 + 3]uint32
|
|
||||||
var bp []byte
|
|
||||||
|
|
||||||
p = cursym.Text
|
p = cursym.Text
|
||||||
if p == nil || p.Link == nil { // handle external functions and ELF section symbols
|
if p == nil || p.Link == nil { // handle external functions and ELF section symbols
|
||||||
|
|
@ -600,10 +587,13 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
ctxt.Cursym = cursym
|
ctxt.Cursym = cursym
|
||||||
|
|
||||||
ctxt.Autosize = int32(p.To.Offset + 4)
|
ctxt.Autosize = int32(p.To.Offset + 4)
|
||||||
c = 0
|
c := int32(0)
|
||||||
|
|
||||||
op = p
|
op = p
|
||||||
p = p.Link
|
p = p.Link
|
||||||
|
var i int
|
||||||
|
var m int
|
||||||
|
var o *Optab
|
||||||
for ; p != nil || ctxt.Blitrl != nil; (func() { op = p; p = p.Link })() {
|
for ; p != nil || ctxt.Blitrl != nil; (func() { op = p; p = p.Link })() {
|
||||||
if p == nil {
|
if p == nil {
|
||||||
if checkpool(ctxt, op, 0) {
|
if checkpool(ctxt, op, 0) {
|
||||||
|
|
@ -676,8 +666,11 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
* generate extra passes putting branches
|
* generate extra passes putting branches
|
||||||
* around jmps to fix. this is rare.
|
* around jmps to fix. this is rare.
|
||||||
*/
|
*/
|
||||||
times = 0
|
times := 0
|
||||||
|
|
||||||
|
var bflag int
|
||||||
|
var opc int32
|
||||||
|
var out [6 + 3]uint32
|
||||||
for {
|
for {
|
||||||
if ctxt.Debugvlog != 0 {
|
if ctxt.Debugvlog != 0 {
|
||||||
fmt.Fprintf(ctxt.Bso, "%5.2f span1\n", obj.Cputime())
|
fmt.Fprintf(ctxt.Bso, "%5.2f span1\n", obj.Cputime())
|
||||||
|
|
@ -774,8 +767,9 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
ctxt.Autosize = int32(p.To.Offset + 4)
|
ctxt.Autosize = int32(p.To.Offset + 4)
|
||||||
obj.Symgrow(ctxt, cursym, cursym.Size)
|
obj.Symgrow(ctxt, cursym, cursym.Size)
|
||||||
|
|
||||||
bp = cursym.P
|
bp := cursym.P
|
||||||
c = int32(p.Pc) // even p->link might need extra padding
|
c = int32(p.Pc) // even p->link might need extra padding
|
||||||
|
var v int
|
||||||
for p = p.Link; p != nil; p = p.Link {
|
for p = p.Link; p != nil; p = p.Link {
|
||||||
ctxt.Pc = p.Pc
|
ctxt.Pc = p.Pc
|
||||||
ctxt.Curp = p
|
ctxt.Curp = p
|
||||||
|
|
@ -844,14 +838,12 @@ func checkpool(ctxt *obj.Link, p *obj.Prog, sz int) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func flushpool(ctxt *obj.Link, p *obj.Prog, skip int, force int) bool {
|
func flushpool(ctxt *obj.Link, p *obj.Prog, skip int, force int) bool {
|
||||||
var q *obj.Prog
|
|
||||||
|
|
||||||
if ctxt.Blitrl != nil {
|
if ctxt.Blitrl != nil {
|
||||||
if skip != 0 {
|
if skip != 0 {
|
||||||
if false && skip == 1 {
|
if false && skip == 1 {
|
||||||
fmt.Printf("note: flush literal pool at %x: len=%d ref=%x\n", uint64(p.Pc+4), pool.size, pool.start)
|
fmt.Printf("note: flush literal pool at %x: len=%d ref=%x\n", uint64(p.Pc+4), pool.size, pool.start)
|
||||||
}
|
}
|
||||||
q = ctxt.NewProg()
|
q := ctxt.NewProg()
|
||||||
q.As = AB
|
q.As = AB
|
||||||
q.To.Type = obj.TYPE_BRANCH
|
q.To.Type = obj.TYPE_BRANCH
|
||||||
q.Pcond = p.Link
|
q.Pcond = p.Link
|
||||||
|
|
@ -863,7 +855,7 @@ func flushpool(ctxt *obj.Link, p *obj.Prog, skip int, force int) bool {
|
||||||
}
|
}
|
||||||
if ctxt.Headtype == obj.Hnacl && pool.size%16 != 0 {
|
if ctxt.Headtype == obj.Hnacl && pool.size%16 != 0 {
|
||||||
// if pool is not multiple of 16 bytes, add an alignment marker
|
// if pool is not multiple of 16 bytes, add an alignment marker
|
||||||
q = ctxt.NewProg()
|
q := ctxt.NewProg()
|
||||||
|
|
||||||
q.As = ADATABUNDLEEND
|
q.As = ADATABUNDLEEND
|
||||||
ctxt.Elitrl.Link = q
|
ctxt.Elitrl.Link = q
|
||||||
|
|
@ -893,11 +885,9 @@ func flushpool(ctxt *obj.Link, p *obj.Prog, skip int, force int) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) {
|
func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) {
|
||||||
var q *obj.Prog
|
|
||||||
var t obj.Prog
|
var t obj.Prog
|
||||||
var c int
|
|
||||||
|
|
||||||
c = aclass(ctxt, a)
|
c := aclass(ctxt, a)
|
||||||
|
|
||||||
t.Ctxt = ctxt
|
t.Ctxt = ctxt
|
||||||
t.As = AWORD
|
t.As = AWORD
|
||||||
|
|
@ -928,7 +918,7 @@ func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.Pcrel == nil {
|
if t.Pcrel == nil {
|
||||||
for q = ctxt.Blitrl; q != nil; q = q.Link { /* could hash on t.t0.offset */
|
for q := ctxt.Blitrl; q != nil; q = q.Link { /* could hash on t.t0.offset */
|
||||||
if q.Pcrel == nil && q.To == t.To {
|
if q.Pcrel == nil && q.To == t.To {
|
||||||
p.Pcond = q
|
p.Pcond = q
|
||||||
return
|
return
|
||||||
|
|
@ -938,7 +928,7 @@ func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) {
|
||||||
|
|
||||||
if ctxt.Headtype == obj.Hnacl && pool.size%16 == 0 {
|
if ctxt.Headtype == obj.Hnacl && pool.size%16 == 0 {
|
||||||
// start a new data bundle
|
// start a new data bundle
|
||||||
q = ctxt.NewProg()
|
q := ctxt.NewProg()
|
||||||
q.As = ADATABUNDLE
|
q.As = ADATABUNDLE
|
||||||
q.Pc = int64(pool.size)
|
q.Pc = int64(pool.size)
|
||||||
pool.size += 4
|
pool.size += 4
|
||||||
|
|
@ -952,7 +942,7 @@ func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) {
|
||||||
ctxt.Elitrl = q
|
ctxt.Elitrl = q
|
||||||
}
|
}
|
||||||
|
|
||||||
q = ctxt.NewProg()
|
q := ctxt.NewProg()
|
||||||
*q = t
|
*q = t
|
||||||
q.Pc = int64(pool.size)
|
q.Pc = int64(pool.size)
|
||||||
|
|
||||||
|
|
@ -975,9 +965,7 @@ func regoff(ctxt *obj.Link, a *obj.Addr) int32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func immrot(v uint32) int32 {
|
func immrot(v uint32) int32 {
|
||||||
var i int
|
for i := 0; i < 16; i++ {
|
||||||
|
|
||||||
for i = 0; i < 16; i++ {
|
|
||||||
if v&^0xff == 0 {
|
if v&^0xff == 0 {
|
||||||
return int32(uint32(int32(i)<<8) | v | 1<<25)
|
return int32(uint32(int32(i)<<8) | v | 1<<25)
|
||||||
}
|
}
|
||||||
|
|
@ -1012,9 +1000,6 @@ func immhalf(v int32) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
||||||
var s *obj.LSym
|
|
||||||
var t int
|
|
||||||
|
|
||||||
switch a.Type {
|
switch a.Type {
|
||||||
case obj.TYPE_NONE:
|
case obj.TYPE_NONE:
|
||||||
return C_NONE
|
return C_NONE
|
||||||
|
|
@ -1060,7 +1045,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
||||||
|
|
||||||
case obj.NAME_AUTO:
|
case obj.NAME_AUTO:
|
||||||
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset
|
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset
|
||||||
t = int(immaddr(int32(ctxt.Instoffset)))
|
t := int(immaddr(int32(ctxt.Instoffset)))
|
||||||
if t != 0 {
|
if t != 0 {
|
||||||
if immhalf(int32(ctxt.Instoffset)) {
|
if immhalf(int32(ctxt.Instoffset)) {
|
||||||
if immfloat(int32(t)) {
|
if immfloat(int32(t)) {
|
||||||
|
|
@ -1079,7 +1064,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
||||||
|
|
||||||
case obj.NAME_PARAM:
|
case obj.NAME_PARAM:
|
||||||
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 4
|
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 4
|
||||||
t = int(immaddr(int32(ctxt.Instoffset)))
|
t := int(immaddr(int32(ctxt.Instoffset)))
|
||||||
if t != 0 {
|
if t != 0 {
|
||||||
if immhalf(int32(ctxt.Instoffset)) {
|
if immhalf(int32(ctxt.Instoffset)) {
|
||||||
if immfloat(int32(t)) {
|
if immfloat(int32(t)) {
|
||||||
|
|
@ -1098,7 +1083,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
||||||
|
|
||||||
case obj.TYPE_NONE:
|
case obj.TYPE_NONE:
|
||||||
ctxt.Instoffset = a.Offset
|
ctxt.Instoffset = a.Offset
|
||||||
t = int(immaddr(int32(ctxt.Instoffset)))
|
t := int(immaddr(int32(ctxt.Instoffset)))
|
||||||
if t != 0 {
|
if t != 0 {
|
||||||
if immhalf(int32(ctxt.Instoffset)) { /* n.b. that it will also satisfy immrot */
|
if immhalf(int32(ctxt.Instoffset)) { /* n.b. that it will also satisfy immrot */
|
||||||
if immfloat(int32(t)) {
|
if immfloat(int32(t)) {
|
||||||
|
|
@ -1110,7 +1095,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
||||||
if immfloat(int32(t)) {
|
if immfloat(int32(t)) {
|
||||||
return C_FOREG /* n.b. that it will also satisfy immrot */
|
return C_FOREG /* n.b. that it will also satisfy immrot */
|
||||||
}
|
}
|
||||||
t = int(immrot(uint32(ctxt.Instoffset)))
|
t := int(immrot(uint32(ctxt.Instoffset)))
|
||||||
if t != 0 {
|
if t != 0 {
|
||||||
return C_SROREG
|
return C_SROREG
|
||||||
}
|
}
|
||||||
|
|
@ -1150,7 +1135,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
||||||
return aconsize(ctxt)
|
return aconsize(ctxt)
|
||||||
}
|
}
|
||||||
|
|
||||||
t = int(immrot(uint32(ctxt.Instoffset)))
|
t := int(immrot(uint32(ctxt.Instoffset)))
|
||||||
if t != 0 {
|
if t != 0 {
|
||||||
return C_RCON
|
return C_RCON
|
||||||
}
|
}
|
||||||
|
|
@ -1162,7 +1147,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
||||||
|
|
||||||
case obj.NAME_EXTERN,
|
case obj.NAME_EXTERN,
|
||||||
obj.NAME_STATIC:
|
obj.NAME_STATIC:
|
||||||
s = a.Sym
|
s := a.Sym
|
||||||
if s == nil {
|
if s == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -1188,9 +1173,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func aconsize(ctxt *obj.Link) int {
|
func aconsize(ctxt *obj.Link) int {
|
||||||
var t int
|
t := int(immrot(uint32(ctxt.Instoffset)))
|
||||||
|
|
||||||
t = int(immrot(uint32(ctxt.Instoffset)))
|
|
||||||
if t != 0 {
|
if t != 0 {
|
||||||
return C_RACON
|
return C_RACON
|
||||||
}
|
}
|
||||||
|
|
@ -1202,16 +1185,7 @@ func prasm(p *obj.Prog) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func oplook(ctxt *obj.Link, p *obj.Prog) *Optab {
|
func oplook(ctxt *obj.Link, p *obj.Prog) *Optab {
|
||||||
var a1 int
|
a1 := int(p.Optab)
|
||||||
var a2 int
|
|
||||||
var a3 int
|
|
||||||
var r int
|
|
||||||
var c1 []byte
|
|
||||||
var c3 []byte
|
|
||||||
var o []Optab
|
|
||||||
var e []Optab
|
|
||||||
|
|
||||||
a1 = int(p.Optab)
|
|
||||||
if a1 != 0 {
|
if a1 != 0 {
|
||||||
return &optab[a1-1:][0]
|
return &optab[a1-1:][0]
|
||||||
}
|
}
|
||||||
|
|
@ -1222,19 +1196,19 @@ func oplook(ctxt *obj.Link, p *obj.Prog) *Optab {
|
||||||
}
|
}
|
||||||
|
|
||||||
a1--
|
a1--
|
||||||
a3 = int(p.To.Class)
|
a3 := int(p.To.Class)
|
||||||
if a3 == 0 {
|
if a3 == 0 {
|
||||||
a3 = aclass(ctxt, &p.To) + 1
|
a3 = aclass(ctxt, &p.To) + 1
|
||||||
p.To.Class = int8(a3)
|
p.To.Class = int8(a3)
|
||||||
}
|
}
|
||||||
|
|
||||||
a3--
|
a3--
|
||||||
a2 = C_NONE
|
a2 := C_NONE
|
||||||
if p.Reg != 0 {
|
if p.Reg != 0 {
|
||||||
a2 = C_REG
|
a2 = C_REG
|
||||||
}
|
}
|
||||||
r = int(p.As)
|
r := int(p.As)
|
||||||
o = oprange[r].start
|
o := oprange[r].start
|
||||||
if o == nil {
|
if o == nil {
|
||||||
o = oprange[r].stop /* just generate an error */
|
o = oprange[r].stop /* just generate an error */
|
||||||
}
|
}
|
||||||
|
|
@ -1244,9 +1218,9 @@ func oplook(ctxt *obj.Link, p *obj.Prog) *Optab {
|
||||||
fmt.Printf("\t\t%d %d\n", p.From.Type, p.To.Type)
|
fmt.Printf("\t\t%d %d\n", p.From.Type, p.To.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
e = oprange[r].stop
|
e := oprange[r].stop
|
||||||
c1 = xcmp[a1][:]
|
c1 := xcmp[a1][:]
|
||||||
c3 = xcmp[a3][:]
|
c3 := xcmp[a3][:]
|
||||||
for ; -cap(o) < -cap(e); o = o[1:] {
|
for ; -cap(o) < -cap(e); o = o[1:] {
|
||||||
if int(o[0].a2) == a2 {
|
if int(o[0].a2) == a2 {
|
||||||
if c1[o[0].a1] != 0 {
|
if c1[o[0].a1] != 0 {
|
||||||
|
|
@ -1340,13 +1314,9 @@ func (x ocmp) Swap(i, j int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x ocmp) Less(i, j int) bool {
|
func (x ocmp) Less(i, j int) bool {
|
||||||
var p1 *Optab
|
p1 := &x[i]
|
||||||
var p2 *Optab
|
p2 := &x[j]
|
||||||
var n int
|
n := int(p1.as) - int(p2.as)
|
||||||
|
|
||||||
p1 = &x[i]
|
|
||||||
p2 = &x[j]
|
|
||||||
n = int(p1.as) - int(p2.as)
|
|
||||||
if n != 0 {
|
if n != 0 {
|
||||||
return n < 0
|
return n < 0
|
||||||
}
|
}
|
||||||
|
|
@ -1366,11 +1336,9 @@ func (x ocmp) Less(i, j int) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildop(ctxt *obj.Link) {
|
func buildop(ctxt *obj.Link) {
|
||||||
var i int
|
|
||||||
var n int
|
var n int
|
||||||
var r int
|
|
||||||
|
|
||||||
for i = 0; i < C_GOK; i++ {
|
for i := 0; i < C_GOK; i++ {
|
||||||
for n = 0; n < C_GOK; n++ {
|
for n = 0; n < C_GOK; n++ {
|
||||||
if cmp(n, i) {
|
if cmp(n, i) {
|
||||||
xcmp[i][n] = 1
|
xcmp[i][n] = 1
|
||||||
|
|
@ -1388,7 +1356,8 @@ func buildop(ctxt *obj.Link) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Sort(ocmp(optab[:n]))
|
sort.Sort(ocmp(optab[:n]))
|
||||||
for i = 0; i < n; i++ {
|
var r int
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
r = int(optab[i].as)
|
r = int(optab[i].as)
|
||||||
oprange[r].start = optab[i:]
|
oprange[r].start = optab[i:]
|
||||||
for int(optab[i].as) == r {
|
for int(optab[i].as) == r {
|
||||||
|
|
@ -1536,26 +1505,13 @@ func buildop(ctxt *obj.Link) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
var o1 uint32
|
|
||||||
var o2 uint32
|
|
||||||
var o3 uint32
|
|
||||||
var o4 uint32
|
|
||||||
var o5 uint32
|
|
||||||
var o6 uint32
|
|
||||||
var v int32
|
|
||||||
var r int
|
|
||||||
var rf int
|
|
||||||
var rt int
|
|
||||||
var rt2 int
|
|
||||||
var rel *obj.Reloc
|
|
||||||
|
|
||||||
ctxt.Printp = p
|
ctxt.Printp = p
|
||||||
o1 = 0
|
o1 := uint32(0)
|
||||||
o2 = 0
|
o2 := uint32(0)
|
||||||
o3 = 0
|
o3 := uint32(0)
|
||||||
o4 = 0
|
o4 := uint32(0)
|
||||||
o5 = 0
|
o5 := uint32(0)
|
||||||
o6 = 0
|
o6 := uint32(0)
|
||||||
ctxt.Armsize += int32(o.size)
|
ctxt.Armsize += int32(o.size)
|
||||||
if false { /*debug['P']*/
|
if false { /*debug['P']*/
|
||||||
fmt.Printf("%x: %v\ttype %d\n", uint32(p.Pc), p, o.type_)
|
fmt.Printf("%x: %v\ttype %d\n", uint32(p.Pc), p, o.type_)
|
||||||
|
|
@ -1573,9 +1529,9 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
case 1: /* op R,[R],R */
|
case 1: /* op R,[R],R */
|
||||||
o1 = oprrr(ctxt, int(p.As), int(p.Scond))
|
o1 = oprrr(ctxt, int(p.As), int(p.Scond))
|
||||||
|
|
||||||
rf = int(p.From.Reg)
|
rf := int(p.From.Reg)
|
||||||
rt = int(p.To.Reg)
|
rt := int(p.To.Reg)
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
if p.To.Type == obj.TYPE_NONE {
|
if p.To.Type == obj.TYPE_NONE {
|
||||||
rt = 0
|
rt = 0
|
||||||
}
|
}
|
||||||
|
|
@ -1591,8 +1547,8 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
|
|
||||||
o1 = oprrr(ctxt, int(p.As), int(p.Scond))
|
o1 = oprrr(ctxt, int(p.As), int(p.Scond))
|
||||||
o1 |= uint32(immrot(uint32(ctxt.Instoffset)))
|
o1 |= uint32(immrot(uint32(ctxt.Instoffset)))
|
||||||
rt = int(p.To.Reg)
|
rt := int(p.To.Reg)
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
if p.To.Type == obj.TYPE_NONE {
|
if p.To.Type == obj.TYPE_NONE {
|
||||||
rt = 0
|
rt = 0
|
||||||
}
|
}
|
||||||
|
|
@ -1611,7 +1567,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
|
|
||||||
o1 = oprrr(ctxt, AADD, int(p.Scond))
|
o1 = oprrr(ctxt, AADD, int(p.Scond))
|
||||||
o1 |= uint32(immrot(uint32(ctxt.Instoffset)))
|
o1 |= uint32(immrot(uint32(ctxt.Instoffset)))
|
||||||
r = int(p.From.Reg)
|
r := int(p.From.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
|
|
@ -1621,9 +1577,9 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
case 5: /* bra s */
|
case 5: /* bra s */
|
||||||
o1 = opbra(ctxt, int(p.As), int(p.Scond))
|
o1 = opbra(ctxt, int(p.As), int(p.Scond))
|
||||||
|
|
||||||
v = -8
|
v := int32(-8)
|
||||||
if p.To.Sym != nil {
|
if p.To.Sym != nil {
|
||||||
rel = obj.Addrel(ctxt.Cursym)
|
rel := obj.Addrel(ctxt.Cursym)
|
||||||
rel.Off = int32(ctxt.Pc)
|
rel.Off = int32(ctxt.Pc)
|
||||||
rel.Siz = 4
|
rel.Siz = 4
|
||||||
rel.Sym = p.To.Sym
|
rel.Sym = p.To.Sym
|
||||||
|
|
@ -1654,7 +1610,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
}
|
}
|
||||||
o1 = oprrr(ctxt, ABL, int(p.Scond))
|
o1 = oprrr(ctxt, ABL, int(p.Scond))
|
||||||
o1 |= (uint32(p.To.Reg) & 15) << 0
|
o1 |= (uint32(p.To.Reg) & 15) << 0
|
||||||
rel = obj.Addrel(ctxt.Cursym)
|
rel := obj.Addrel(ctxt.Cursym)
|
||||||
rel.Off = int32(ctxt.Pc)
|
rel.Off = int32(ctxt.Pc)
|
||||||
rel.Siz = 0
|
rel.Siz = 0
|
||||||
rel.Type = obj.R_CALLIND
|
rel.Type = obj.R_CALLIND
|
||||||
|
|
@ -1663,7 +1619,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
aclass(ctxt, &p.From)
|
aclass(ctxt, &p.From)
|
||||||
|
|
||||||
o1 = oprrr(ctxt, int(p.As), int(p.Scond))
|
o1 = oprrr(ctxt, int(p.As), int(p.Scond))
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
|
|
@ -1674,7 +1630,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
case 9: /* sll R,[R],R -> mov (R<<R),R */
|
case 9: /* sll R,[R],R -> mov (R<<R),R */
|
||||||
o1 = oprrr(ctxt, int(p.As), int(p.Scond))
|
o1 = oprrr(ctxt, int(p.As), int(p.Scond))
|
||||||
|
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
|
|
@ -1697,7 +1653,7 @@ func asmout(ctxt *obj.Link, 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.
|
// in the PC stream as part of the literal pool.
|
||||||
rel = obj.Addrel(ctxt.Cursym)
|
rel := obj.Addrel(ctxt.Cursym)
|
||||||
|
|
||||||
rel.Off = int32(ctxt.Pc)
|
rel.Off = int32(ctxt.Pc)
|
||||||
rel.Siz = 4
|
rel.Siz = 4
|
||||||
|
|
@ -1742,7 +1698,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
}
|
}
|
||||||
o2 = oprrr(ctxt, int(p.As), int(p.Scond))
|
o2 = oprrr(ctxt, int(p.As), int(p.Scond))
|
||||||
o2 |= REGTMP & 15
|
o2 |= REGTMP & 15
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
if p.As == AMOVW || p.As == AMVN {
|
if p.As == AMOVW || p.As == AMVN {
|
||||||
r = 0
|
r = 0
|
||||||
} else if r == 0 {
|
} else if r == 0 {
|
||||||
|
|
@ -1762,7 +1718,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o2 = oprrr(ctxt, ASRA, int(p.Scond))
|
o2 = oprrr(ctxt, ASRA, int(p.Scond))
|
||||||
}
|
}
|
||||||
|
|
||||||
r = int(p.To.Reg)
|
r := int(p.To.Reg)
|
||||||
o1 |= (uint32(p.From.Reg)&15)<<0 | (uint32(r)&15)<<12
|
o1 |= (uint32(p.From.Reg)&15)<<0 | (uint32(r)&15)<<12
|
||||||
o2 |= uint32(r)&15 | (uint32(r)&15)<<12
|
o2 |= uint32(r)&15 | (uint32(r)&15)<<12
|
||||||
if p.As == AMOVB || p.As == AMOVBS || p.As == AMOVBU {
|
if p.As == AMOVB || p.As == AMOVBS || p.As == AMOVBU {
|
||||||
|
|
@ -1776,9 +1732,9 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
case 15: /* mul r,[r,]r */
|
case 15: /* mul r,[r,]r */
|
||||||
o1 = oprrr(ctxt, int(p.As), int(p.Scond))
|
o1 = oprrr(ctxt, int(p.As), int(p.Scond))
|
||||||
|
|
||||||
rf = int(p.From.Reg)
|
rf := int(p.From.Reg)
|
||||||
rt = int(p.To.Reg)
|
rt := int(p.To.Reg)
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = rt
|
r = rt
|
||||||
}
|
}
|
||||||
|
|
@ -1803,16 +1759,16 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
|
|
||||||
case 17:
|
case 17:
|
||||||
o1 = oprrr(ctxt, int(p.As), int(p.Scond))
|
o1 = oprrr(ctxt, int(p.As), int(p.Scond))
|
||||||
rf = int(p.From.Reg)
|
rf := int(p.From.Reg)
|
||||||
rt = int(p.To.Reg)
|
rt := int(p.To.Reg)
|
||||||
rt2 = int(p.To.Offset)
|
rt2 := int(p.To.Offset)
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
o1 |= (uint32(rf)&15)<<8 | (uint32(r)&15)<<0 | (uint32(rt)&15)<<16 | (uint32(rt2)&15)<<12
|
o1 |= (uint32(rf)&15)<<8 | (uint32(r)&15)<<0 | (uint32(rt)&15)<<16 | (uint32(rt2)&15)<<12
|
||||||
|
|
||||||
case 20: /* mov/movb/movbu R,O(R) */
|
case 20: /* mov/movb/movbu R,O(R) */
|
||||||
aclass(ctxt, &p.To)
|
aclass(ctxt, &p.To)
|
||||||
|
|
||||||
r = int(p.To.Reg)
|
r := int(p.To.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
|
|
@ -1821,7 +1777,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
case 21: /* mov/movbu O(R),R -> lr */
|
case 21: /* mov/movbu O(R),R -> lr */
|
||||||
aclass(ctxt, &p.From)
|
aclass(ctxt, &p.From)
|
||||||
|
|
||||||
r = int(p.From.Reg)
|
r := int(p.From.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
|
|
@ -1836,7 +1792,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
if o1 == 0 {
|
if o1 == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
r = int(p.To.Reg)
|
r := int(p.To.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
|
|
@ -1851,7 +1807,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
if o1 == 0 {
|
if o1 == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
r = int(p.From.Reg)
|
r := int(p.From.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
|
|
@ -1869,7 +1825,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
|
|
||||||
o2 = oprrr(ctxt, AADD, int(p.Scond))
|
o2 = oprrr(ctxt, AADD, int(p.Scond))
|
||||||
o2 |= REGTMP & 15
|
o2 |= REGTMP & 15
|
||||||
r = int(p.From.Reg)
|
r := int(p.From.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
|
|
@ -1961,18 +1917,18 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = 0xe8fd8000
|
o1 = 0xe8fd8000
|
||||||
|
|
||||||
case 50: /* floating point store */
|
case 50: /* floating point store */
|
||||||
v = regoff(ctxt, &p.To)
|
v := regoff(ctxt, &p.To)
|
||||||
|
|
||||||
r = int(p.To.Reg)
|
r := int(p.To.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
o1 = ofsr(ctxt, int(p.As), int(p.From.Reg), v, r, int(p.Scond), p)
|
o1 = ofsr(ctxt, int(p.As), int(p.From.Reg), v, r, int(p.Scond), p)
|
||||||
|
|
||||||
case 51: /* floating point load */
|
case 51: /* floating point load */
|
||||||
v = regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
|
|
||||||
r = int(p.From.Reg)
|
r := int(p.From.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
|
|
@ -1984,7 +1940,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
if o1 == 0 {
|
if o1 == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
r = int(p.To.Reg)
|
r := int(p.To.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
|
|
@ -1997,7 +1953,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
if o1 == 0 {
|
if o1 == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
r = int(p.From.Reg)
|
r := int(p.From.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
|
|
@ -2007,9 +1963,9 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
case 54: /* floating point arith */
|
case 54: /* floating point arith */
|
||||||
o1 = oprrr(ctxt, int(p.As), int(p.Scond))
|
o1 = oprrr(ctxt, int(p.As), int(p.Scond))
|
||||||
|
|
||||||
rf = int(p.From.Reg)
|
rf := int(p.From.Reg)
|
||||||
rt = int(p.To.Reg)
|
rt := int(p.To.Reg)
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = rt
|
r = rt
|
||||||
if p.As == AMOVF || p.As == AMOVD || p.As == AMOVFD || p.As == AMOVDF || p.As == ASQRTF || p.As == ASQRTD || p.As == AABSF || p.As == AABSD {
|
if p.As == AMOVF || p.As == AMOVD || p.As == AMOVFD || p.As == AMOVDF || p.As == ASQRTF || p.As == ASQRTD || p.As == AABSF || p.As == AABSD {
|
||||||
|
|
@ -2033,8 +1989,8 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = oprrr(ctxt, AAND, int(p.Scond))
|
o1 = oprrr(ctxt, AAND, int(p.Scond))
|
||||||
|
|
||||||
o1 |= uint32(immrot(0xff))
|
o1 |= uint32(immrot(0xff))
|
||||||
rt = int(p.To.Reg)
|
rt := int(p.To.Reg)
|
||||||
r = int(p.From.Reg)
|
r := int(p.From.Reg)
|
||||||
if p.To.Type == obj.TYPE_NONE {
|
if p.To.Type == obj.TYPE_NONE {
|
||||||
rt = 0
|
rt = 0
|
||||||
}
|
}
|
||||||
|
|
@ -2095,7 +2051,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
|
|
||||||
case 63: /* bcase */
|
case 63: /* bcase */
|
||||||
if p.Pcond != nil {
|
if p.Pcond != nil {
|
||||||
rel = obj.Addrel(ctxt.Cursym)
|
rel := obj.Addrel(ctxt.Cursym)
|
||||||
rel.Off = int32(ctxt.Pc)
|
rel.Off = int32(ctxt.Pc)
|
||||||
rel.Siz = 4
|
rel.Siz = 4
|
||||||
if p.To.Sym != nil && p.To.Sym.Type != 0 {
|
if p.To.Sym != nil && p.To.Sym.Type != 0 {
|
||||||
|
|
@ -2171,7 +2127,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
case 70: /* movh/movhu R,O(R) -> strh */
|
case 70: /* movh/movhu R,O(R) -> strh */
|
||||||
aclass(ctxt, &p.To)
|
aclass(ctxt, &p.To)
|
||||||
|
|
||||||
r = int(p.To.Reg)
|
r := int(p.To.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
|
|
@ -2180,7 +2136,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
case 71: /* movb/movh/movhu O(R),R -> ldrsb/ldrsh/ldrh */
|
case 71: /* movb/movh/movhu O(R),R -> ldrsb/ldrsh/ldrh */
|
||||||
aclass(ctxt, &p.From)
|
aclass(ctxt, &p.From)
|
||||||
|
|
||||||
r = int(p.From.Reg)
|
r := int(p.From.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
|
|
@ -2197,7 +2153,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
if o1 == 0 {
|
if o1 == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
r = int(p.To.Reg)
|
r := int(p.To.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
|
|
@ -2209,7 +2165,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
if o1 == 0 {
|
if o1 == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
r = int(p.From.Reg)
|
r := int(p.From.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
|
|
@ -2278,8 +2234,8 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o2 = oprrr(ctxt, ASUBF, int(p.Scond))
|
o2 = oprrr(ctxt, ASUBF, int(p.Scond))
|
||||||
}
|
}
|
||||||
|
|
||||||
v = 0x70 // 1.0
|
v := int32(0x70) // 1.0
|
||||||
r = (int(p.To.Reg) & 15) << 0
|
r := (int(p.To.Reg) & 15) << 0
|
||||||
|
|
||||||
// movf $1.0, r
|
// movf $1.0, r
|
||||||
o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
|
o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
|
||||||
|
|
@ -2298,7 +2254,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
}
|
}
|
||||||
o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
|
o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
|
||||||
o1 |= (uint32(p.To.Reg) & 15) << 12
|
o1 |= (uint32(p.To.Reg) & 15) << 12
|
||||||
v = int32(chipfloat5(ctxt, p.From.U.Dval))
|
v := int32(chipfloat5(ctxt, p.From.U.Dval))
|
||||||
o1 |= (uint32(v) & 0xf) << 0
|
o1 |= (uint32(v) & 0xf) << 0
|
||||||
o1 |= (uint32(v) & 0xf0) << 12
|
o1 |= (uint32(v) & 0xf0) << 12
|
||||||
|
|
||||||
|
|
@ -2475,18 +2431,14 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func mov(ctxt *obj.Link, p *obj.Prog) uint32 {
|
func mov(ctxt *obj.Link, p *obj.Prog) uint32 {
|
||||||
var o1 uint32
|
|
||||||
var rt int
|
|
||||||
var r int
|
|
||||||
|
|
||||||
aclass(ctxt, &p.From)
|
aclass(ctxt, &p.From)
|
||||||
o1 = oprrr(ctxt, int(p.As), int(p.Scond))
|
o1 := oprrr(ctxt, int(p.As), int(p.Scond))
|
||||||
o1 |= uint32(p.From.Offset)
|
o1 |= uint32(p.From.Offset)
|
||||||
rt = int(p.To.Reg)
|
rt := int(p.To.Reg)
|
||||||
if p.To.Type == obj.TYPE_NONE {
|
if p.To.Type == obj.TYPE_NONE {
|
||||||
rt = 0
|
rt = 0
|
||||||
}
|
}
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
if p.As == AMOVW || p.As == AMVN {
|
if p.As == AMOVW || p.As == AMVN {
|
||||||
r = 0
|
r = 0
|
||||||
} else if r == 0 {
|
} else if r == 0 {
|
||||||
|
|
@ -2497,9 +2449,7 @@ func mov(ctxt *obj.Link, p *obj.Prog) uint32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func oprrr(ctxt *obj.Link, a int, sc int) uint32 {
|
func oprrr(ctxt *obj.Link, a int, sc int) uint32 {
|
||||||
var o uint32
|
o := ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28
|
||||||
|
|
||||||
o = ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28
|
|
||||||
if sc&C_SBIT != 0 {
|
if sc&C_SBIT != 0 {
|
||||||
o |= 1 << 20
|
o |= 1 << 20
|
||||||
}
|
}
|
||||||
|
|
@ -2716,12 +2666,10 @@ func opbra(ctxt *obj.Link, a int, sc int) uint32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func olr(ctxt *obj.Link, v int32, b int, r int, sc int) uint32 {
|
func olr(ctxt *obj.Link, v int32, b int, r int, sc int) uint32 {
|
||||||
var o uint32
|
|
||||||
|
|
||||||
if sc&C_SBIT != 0 {
|
if sc&C_SBIT != 0 {
|
||||||
ctxt.Diag(".nil on LDR/STR instruction")
|
ctxt.Diag(".nil on LDR/STR instruction")
|
||||||
}
|
}
|
||||||
o = ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28
|
o := ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28
|
||||||
if sc&C_PBIT == 0 {
|
if sc&C_PBIT == 0 {
|
||||||
o |= 1 << 24
|
o |= 1 << 24
|
||||||
}
|
}
|
||||||
|
|
@ -2750,12 +2698,10 @@ func olr(ctxt *obj.Link, v int32, b int, r int, sc int) uint32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func olhr(ctxt *obj.Link, v int32, b int, r int, sc int) uint32 {
|
func olhr(ctxt *obj.Link, v int32, b int, r int, sc int) uint32 {
|
||||||
var o uint32
|
|
||||||
|
|
||||||
if sc&C_SBIT != 0 {
|
if sc&C_SBIT != 0 {
|
||||||
ctxt.Diag(".nil on LDRH/STRH instruction")
|
ctxt.Diag(".nil on LDRH/STRH instruction")
|
||||||
}
|
}
|
||||||
o = ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28
|
o := ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28
|
||||||
if sc&C_PBIT == 0 {
|
if sc&C_PBIT == 0 {
|
||||||
o |= 1 << 24
|
o |= 1 << 24
|
||||||
}
|
}
|
||||||
|
|
@ -2778,9 +2724,7 @@ func olhr(ctxt *obj.Link, v int32, b int, r int, sc int) uint32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func osr(ctxt *obj.Link, a int, r int, v int32, b int, sc int) uint32 {
|
func osr(ctxt *obj.Link, a int, r int, v int32, b int, sc int) uint32 {
|
||||||
var o uint32
|
o := olr(ctxt, v, b, r, sc) ^ (1 << 20)
|
||||||
|
|
||||||
o = olr(ctxt, v, b, r, sc) ^ (1 << 20)
|
|
||||||
if a != AMOVW {
|
if a != AMOVW {
|
||||||
o |= 1 << 22
|
o |= 1 << 22
|
||||||
}
|
}
|
||||||
|
|
@ -2788,9 +2732,7 @@ func osr(ctxt *obj.Link, a int, r int, v int32, b int, sc int) uint32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func oshr(ctxt *obj.Link, r int, v int32, b int, sc int) uint32 {
|
func oshr(ctxt *obj.Link, r int, v int32, b int, sc int) uint32 {
|
||||||
var o uint32
|
o := olhr(ctxt, v, b, r, sc) ^ (1 << 20)
|
||||||
|
|
||||||
o = olhr(ctxt, v, b, r, sc) ^ (1 << 20)
|
|
||||||
return o
|
return o
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2811,12 +2753,10 @@ func olhrr(ctxt *obj.Link, i int, b int, r int, sc int) uint32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ofsr(ctxt *obj.Link, a int, r int, v int32, b int, sc int, p *obj.Prog) uint32 {
|
func ofsr(ctxt *obj.Link, a int, r int, v int32, b int, sc int, p *obj.Prog) uint32 {
|
||||||
var o uint32
|
|
||||||
|
|
||||||
if sc&C_SBIT != 0 {
|
if sc&C_SBIT != 0 {
|
||||||
ctxt.Diag(".nil on FLDR/FSTR instruction")
|
ctxt.Diag(".nil on FLDR/FSTR instruction")
|
||||||
}
|
}
|
||||||
o = ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28
|
o := ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28
|
||||||
if sc&C_PBIT == 0 {
|
if sc&C_PBIT == 0 {
|
||||||
o |= 1 << 24
|
o |= 1 << 24
|
||||||
}
|
}
|
||||||
|
|
@ -2855,11 +2795,10 @@ func ofsr(ctxt *obj.Link, a int, r int, v int32, b int, sc int, p *obj.Prog) uin
|
||||||
}
|
}
|
||||||
|
|
||||||
func omvl(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, dr int) uint32 {
|
func omvl(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, dr int) uint32 {
|
||||||
var v int32
|
|
||||||
var o1 uint32
|
var o1 uint32
|
||||||
if p.Pcond == nil {
|
if p.Pcond == nil {
|
||||||
aclass(ctxt, a)
|
aclass(ctxt, a)
|
||||||
v = immrot(^uint32(ctxt.Instoffset))
|
v := immrot(^uint32(ctxt.Instoffset))
|
||||||
if v == 0 {
|
if v == 0 {
|
||||||
ctxt.Diag("missing literal")
|
ctxt.Diag("missing literal")
|
||||||
prasm(p)
|
prasm(p)
|
||||||
|
|
@ -2870,7 +2809,7 @@ func omvl(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, dr int) uint32 {
|
||||||
o1 |= uint32(v)
|
o1 |= uint32(v)
|
||||||
o1 |= (uint32(dr) & 15) << 12
|
o1 |= (uint32(dr) & 15) << 12
|
||||||
} else {
|
} else {
|
||||||
v = int32(p.Pcond.Pc - p.Pc - 8)
|
v := int32(p.Pcond.Pc - p.Pc - 8)
|
||||||
o1 = olr(ctxt, v, REGPC, dr, int(p.Scond)&C_SCOND)
|
o1 = olr(ctxt, v, REGPC, dr, int(p.Scond)&C_SCOND)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2886,29 +2825,23 @@ func chipzero5(ctxt *obj.Link, e float64) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func chipfloat5(ctxt *obj.Link, e float64) int {
|
func chipfloat5(ctxt *obj.Link, e float64) int {
|
||||||
var n int
|
|
||||||
var h1 uint32
|
|
||||||
var l uint32
|
|
||||||
var h uint32
|
|
||||||
var ei uint64
|
|
||||||
|
|
||||||
// We use GOARM=7 to gate the use of VFPv3 vmov (imm) instructions.
|
// We use GOARM=7 to gate the use of VFPv3 vmov (imm) instructions.
|
||||||
if ctxt.Goarm < 7 {
|
if ctxt.Goarm < 7 {
|
||||||
goto no
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
ei = math.Float64bits(e)
|
ei := math.Float64bits(e)
|
||||||
l = uint32(ei)
|
l := uint32(ei)
|
||||||
h = uint32(ei >> 32)
|
h := uint32(ei >> 32)
|
||||||
|
|
||||||
if l != 0 || h&0xffff != 0 {
|
if l != 0 || h&0xffff != 0 {
|
||||||
goto no
|
return -1
|
||||||
}
|
}
|
||||||
h1 = h & 0x7fc00000
|
h1 := h & 0x7fc00000
|
||||||
if h1 != 0x40000000 && h1 != 0x3fc00000 {
|
if h1 != 0x40000000 && h1 != 0x3fc00000 {
|
||||||
goto no
|
return -1
|
||||||
}
|
}
|
||||||
n = 0
|
n := 0
|
||||||
|
|
||||||
// sign bit (a)
|
// sign bit (a)
|
||||||
if h&0x80000000 != 0 {
|
if h&0x80000000 != 0 {
|
||||||
|
|
@ -2925,7 +2858,4 @@ func chipfloat5(ctxt *obj.Link, e float64) int {
|
||||||
|
|
||||||
//print("match %.8lux %.8lux %d\n", l, h, n);
|
//print("match %.8lux %.8lux %d\n", l, h, n);
|
||||||
return n
|
return n
|
||||||
|
|
||||||
no:
|
|
||||||
return -1
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,16 +61,9 @@ var extra = []string{
|
||||||
var bigP *obj.Prog
|
var bigP *obj.Prog
|
||||||
|
|
||||||
func Pconv(p *obj.Prog) string {
|
func Pconv(p *obj.Prog) string {
|
||||||
var str string
|
a := int(p.As)
|
||||||
var sc string
|
s := int(p.Scond)
|
||||||
var fp string
|
sc := extra[(s&C_SCOND)^C_SCOND_XOR]
|
||||||
|
|
||||||
var a int
|
|
||||||
var s int
|
|
||||||
|
|
||||||
a = int(p.As)
|
|
||||||
s = int(p.Scond)
|
|
||||||
sc = extra[(s&C_SCOND)^C_SCOND_XOR]
|
|
||||||
if s&C_SBIT != 0 {
|
if s&C_SBIT != 0 {
|
||||||
sc += ".S"
|
sc += ".S"
|
||||||
}
|
}
|
||||||
|
|
@ -83,6 +76,7 @@ func Pconv(p *obj.Prog) string {
|
||||||
if s&C_UBIT != 0 { /* ambiguous with FBIT */
|
if s&C_UBIT != 0 { /* ambiguous with FBIT */
|
||||||
sc += ".U"
|
sc += ".U"
|
||||||
}
|
}
|
||||||
|
var str string
|
||||||
if a == obj.ADATA {
|
if a == obj.ADATA {
|
||||||
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v",
|
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v",
|
||||||
p.Pc, p.Line(), Aconv(a), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To))
|
p.Pc, p.Line(), Aconv(a), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To))
|
||||||
|
|
@ -97,30 +91,23 @@ func Pconv(p *obj.Prog) string {
|
||||||
p.Pc, p.Line(), Aconv(a), sc, obj.Dconv(p, &p.From), Rconv(int(p.Reg)), obj.Dconv(p, &p.To))
|
p.Pc, p.Line(), Aconv(a), sc, obj.Dconv(p, &p.From), Rconv(int(p.Reg)), obj.Dconv(p, &p.To))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var fp string
|
||||||
fp += str
|
fp += str
|
||||||
return fp
|
return fp
|
||||||
}
|
}
|
||||||
|
|
||||||
func Aconv(a int) string {
|
func Aconv(a int) string {
|
||||||
var s string
|
s := "???"
|
||||||
var fp string
|
|
||||||
|
|
||||||
s = "???"
|
|
||||||
if a >= obj.AXXX && a < ALAST {
|
if a >= obj.AXXX && a < ALAST {
|
||||||
s = Anames[a]
|
s = Anames[a]
|
||||||
}
|
}
|
||||||
|
var fp string
|
||||||
fp += s
|
fp += s
|
||||||
return fp
|
return fp
|
||||||
}
|
}
|
||||||
|
|
||||||
func RAconv(a *obj.Addr) string {
|
func RAconv(a *obj.Addr) string {
|
||||||
var str string
|
str := fmt.Sprintf("GOK-reglist")
|
||||||
var fp string
|
|
||||||
|
|
||||||
var i int
|
|
||||||
var v int
|
|
||||||
|
|
||||||
str = fmt.Sprintf("GOK-reglist")
|
|
||||||
switch a.Type {
|
switch a.Type {
|
||||||
case obj.TYPE_CONST:
|
case obj.TYPE_CONST:
|
||||||
if a.Reg != 0 {
|
if a.Reg != 0 {
|
||||||
|
|
@ -129,9 +116,9 @@ func RAconv(a *obj.Addr) string {
|
||||||
if a.Sym != nil {
|
if a.Sym != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
v = int(a.Offset)
|
v := int(a.Offset)
|
||||||
str = ""
|
str = ""
|
||||||
for i = 0; i < NREG; i++ {
|
for i := 0; i < NREG; i++ {
|
||||||
if v&(1<<uint(i)) != 0 {
|
if v&(1<<uint(i)) != 0 {
|
||||||
if str == "" {
|
if str == "" {
|
||||||
str += "[R"
|
str += "[R"
|
||||||
|
|
@ -145,6 +132,7 @@ func RAconv(a *obj.Addr) string {
|
||||||
str += "]"
|
str += "]"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var fp string
|
||||||
fp += str
|
fp += str
|
||||||
return fp
|
return fp
|
||||||
}
|
}
|
||||||
|
|
@ -182,13 +170,11 @@ func Rconv(r int) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func DRconv(a int) string {
|
func DRconv(a int) string {
|
||||||
var s string
|
s := "C_??"
|
||||||
var fp string
|
|
||||||
|
|
||||||
s = "C_??"
|
|
||||||
if a >= C_NONE && a <= C_NCLASS {
|
if a >= C_NONE && a <= C_NCLASS {
|
||||||
s = cnames5[a]
|
s = cnames5[a]
|
||||||
}
|
}
|
||||||
|
var fp string
|
||||||
fp += s
|
fp += s
|
||||||
return fp
|
return fp
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,9 +41,6 @@ import (
|
||||||
var progedit_tlsfallback *obj.LSym
|
var progedit_tlsfallback *obj.LSym
|
||||||
|
|
||||||
func progedit(ctxt *obj.Link, p *obj.Prog) {
|
func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||||
var literal string
|
|
||||||
var s *obj.LSym
|
|
||||||
|
|
||||||
p.From.Class = 0
|
p.From.Class = 0
|
||||||
p.To.Class = 0
|
p.To.Class = 0
|
||||||
|
|
||||||
|
|
@ -111,12 +108,10 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||||
switch p.As {
|
switch p.As {
|
||||||
case AMOVF:
|
case AMOVF:
|
||||||
if p.From.Type == obj.TYPE_FCONST && chipfloat5(ctxt, p.From.U.Dval) < 0 && (chipzero5(ctxt, p.From.U.Dval) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) {
|
if p.From.Type == obj.TYPE_FCONST && chipfloat5(ctxt, p.From.U.Dval) < 0 && (chipzero5(ctxt, p.From.U.Dval) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) {
|
||||||
var i32 uint32
|
f32 := float32(p.From.U.Dval)
|
||||||
var f32 float32
|
i32 := math.Float32bits(f32)
|
||||||
f32 = float32(p.From.U.Dval)
|
literal := fmt.Sprintf("$f32.%08x", i32)
|
||||||
i32 = math.Float32bits(f32)
|
s := obj.Linklookup(ctxt, literal, 0)
|
||||||
literal = fmt.Sprintf("$f32.%08x", i32)
|
|
||||||
s = obj.Linklookup(ctxt, literal, 0)
|
|
||||||
if s.Type == 0 {
|
if s.Type == 0 {
|
||||||
s.Type = obj.SRODATA
|
s.Type = obj.SRODATA
|
||||||
obj.Adduint32(ctxt, s, i32)
|
obj.Adduint32(ctxt, s, i32)
|
||||||
|
|
@ -131,10 +126,9 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||||
|
|
||||||
case AMOVD:
|
case AMOVD:
|
||||||
if p.From.Type == obj.TYPE_FCONST && chipfloat5(ctxt, p.From.U.Dval) < 0 && (chipzero5(ctxt, p.From.U.Dval) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) {
|
if p.From.Type == obj.TYPE_FCONST && chipfloat5(ctxt, p.From.U.Dval) < 0 && (chipzero5(ctxt, p.From.U.Dval) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) {
|
||||||
var i64 uint64
|
i64 := math.Float64bits(p.From.U.Dval)
|
||||||
i64 = math.Float64bits(p.From.U.Dval)
|
literal := fmt.Sprintf("$f64.%016x", i64)
|
||||||
literal = fmt.Sprintf("$f64.%016x", i64)
|
s := obj.Linklookup(ctxt, literal, 0)
|
||||||
s = obj.Linklookup(ctxt, literal, 0)
|
|
||||||
if s.Type == 0 {
|
if s.Type == 0 {
|
||||||
s.Type = obj.SRODATA
|
s.Type = obj.SRODATA
|
||||||
obj.Adduint64(ctxt, s, i64)
|
obj.Adduint64(ctxt, s, i64)
|
||||||
|
|
@ -175,9 +169,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func linkcase(casep *obj.Prog) {
|
func linkcase(casep *obj.Prog) {
|
||||||
var p *obj.Prog
|
for p := casep; p != nil; p = p.Link {
|
||||||
|
|
||||||
for p = casep; p != nil; p = p.Link {
|
|
||||||
if p.As == ABCASE {
|
if p.As == ABCASE {
|
||||||
for ; p != nil && p.As == ABCASE; p = p.Link {
|
for ; p != nil && p.As == ABCASE; p = p.Link {
|
||||||
p.Pcrel = casep
|
p.Pcrel = casep
|
||||||
|
|
@ -188,25 +180,14 @@ func linkcase(casep *obj.Prog) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
var p *obj.Prog
|
autosize := int32(0)
|
||||||
var pl *obj.Prog
|
|
||||||
var p1 *obj.Prog
|
|
||||||
var p2 *obj.Prog
|
|
||||||
var q *obj.Prog
|
|
||||||
var q1 *obj.Prog
|
|
||||||
var q2 *obj.Prog
|
|
||||||
var o int
|
|
||||||
var autosize int32
|
|
||||||
var autoffset int32
|
|
||||||
|
|
||||||
autosize = 0
|
|
||||||
|
|
||||||
if ctxt.Symmorestack[0] == nil {
|
if ctxt.Symmorestack[0] == nil {
|
||||||
ctxt.Symmorestack[0] = obj.Linklookup(ctxt, "runtime.morestack", 0)
|
ctxt.Symmorestack[0] = obj.Linklookup(ctxt, "runtime.morestack", 0)
|
||||||
ctxt.Symmorestack[1] = obj.Linklookup(ctxt, "runtime.morestack_noctxt", 0)
|
ctxt.Symmorestack[1] = obj.Linklookup(ctxt, "runtime.morestack_noctxt", 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
q = nil
|
q := (*obj.Prog)(nil)
|
||||||
|
|
||||||
ctxt.Cursym = cursym
|
ctxt.Cursym = cursym
|
||||||
|
|
||||||
|
|
@ -216,8 +197,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
|
|
||||||
softfloat(ctxt, cursym)
|
softfloat(ctxt, cursym)
|
||||||
|
|
||||||
p = cursym.Text
|
p := cursym.Text
|
||||||
autoffset = int32(p.To.Offset)
|
autoffset := int32(p.To.Offset)
|
||||||
if autoffset < 0 {
|
if autoffset < 0 {
|
||||||
autoffset = 0
|
autoffset = 0
|
||||||
}
|
}
|
||||||
|
|
@ -259,8 +240,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
// MOVW.nil R3, 0(R1) +4
|
// MOVW.nil R3, 0(R1) +4
|
||||||
// CMP R1, R2
|
// CMP R1, R2
|
||||||
// BNE L
|
// BNE L
|
||||||
pl = obj.Appendp(ctxt, p)
|
pl := obj.Appendp(ctxt, p)
|
||||||
p = pl
|
p := pl
|
||||||
|
|
||||||
p.As = AMOVW
|
p.As = AMOVW
|
||||||
p.From.Type = obj.TYPE_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
|
|
@ -289,7 +270,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
* expand RET
|
* expand RET
|
||||||
* expand BECOME pseudo
|
* expand BECOME pseudo
|
||||||
*/
|
*/
|
||||||
for p = cursym.Text; p != nil; p = p.Link {
|
var q1 *obj.Prog
|
||||||
|
for p := cursym.Text; p != nil; p = p.Link {
|
||||||
switch p.As {
|
switch p.As {
|
||||||
case ACASE:
|
case ACASE:
|
||||||
if ctxt.Flag_shared != 0 {
|
if ctxt.Flag_shared != 0 {
|
||||||
|
|
@ -358,7 +340,11 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
q = p
|
q = p
|
||||||
}
|
}
|
||||||
|
|
||||||
for p = cursym.Text; p != nil; p = p.Link {
|
var o int
|
||||||
|
var p1 *obj.Prog
|
||||||
|
var p2 *obj.Prog
|
||||||
|
var q2 *obj.Prog
|
||||||
|
for p := cursym.Text; p != nil; p = p.Link {
|
||||||
o = int(p.As)
|
o = int(p.As)
|
||||||
switch o {
|
switch o {
|
||||||
case obj.ATEXT:
|
case obj.ATEXT:
|
||||||
|
|
@ -667,24 +653,20 @@ func isfloatreg(a *obj.Addr) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func softfloat(ctxt *obj.Link, cursym *obj.LSym) {
|
func softfloat(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
var p *obj.Prog
|
|
||||||
var next *obj.Prog
|
|
||||||
var symsfloat *obj.LSym
|
|
||||||
var wasfloat int
|
|
||||||
|
|
||||||
if ctxt.Goarm > 5 {
|
if ctxt.Goarm > 5 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
symsfloat = obj.Linklookup(ctxt, "_sfloat", 0)
|
symsfloat := obj.Linklookup(ctxt, "_sfloat", 0)
|
||||||
|
|
||||||
wasfloat = 0
|
wasfloat := 0
|
||||||
for p = cursym.Text; p != nil; p = p.Link {
|
for p := cursym.Text; p != nil; p = p.Link {
|
||||||
if p.Pcond != nil {
|
if p.Pcond != nil {
|
||||||
p.Pcond.Mark |= LABEL
|
p.Pcond.Mark |= LABEL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for p = cursym.Text; p != nil; p = p.Link {
|
var next *obj.Prog
|
||||||
|
for p := cursym.Text; p != nil; p = p.Link {
|
||||||
switch p.As {
|
switch p.As {
|
||||||
case AMOVW:
|
case AMOVW:
|
||||||
if isfloatreg(&p.To) || isfloatreg(&p.From) {
|
if isfloatreg(&p.To) || isfloatreg(&p.From) {
|
||||||
|
|
@ -880,13 +862,10 @@ func initdiv(ctxt *obj.Link) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func follow(ctxt *obj.Link, s *obj.LSym) {
|
func follow(ctxt *obj.Link, s *obj.LSym) {
|
||||||
var firstp *obj.Prog
|
|
||||||
var lastp *obj.Prog
|
|
||||||
|
|
||||||
ctxt.Cursym = s
|
ctxt.Cursym = s
|
||||||
|
|
||||||
firstp = ctxt.NewProg()
|
firstp := ctxt.NewProg()
|
||||||
lastp = firstp
|
lastp := firstp
|
||||||
xfol(ctxt, s.Text, &lastp)
|
xfol(ctxt, s.Text, &lastp)
|
||||||
lastp.Link = nil
|
lastp.Link = nil
|
||||||
s.Text = firstp.Link
|
s.Text = firstp.Link
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -43,7 +43,6 @@ var bigP *obj.Prog
|
||||||
|
|
||||||
func Pconv(p *obj.Prog) string {
|
func Pconv(p *obj.Prog) string {
|
||||||
var str string
|
var str string
|
||||||
var fp string
|
|
||||||
|
|
||||||
switch p.As {
|
switch p.As {
|
||||||
case obj.ADATA:
|
case obj.ADATA:
|
||||||
|
|
@ -72,6 +71,7 @@ func Pconv(p *obj.Prog) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var fp string
|
||||||
fp += str
|
fp += str
|
||||||
return fp
|
return fp
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,10 +51,6 @@ func canuselocaltls(ctxt *obj.Link) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func progedit(ctxt *obj.Link, p *obj.Prog) {
|
func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||||
var literal string
|
|
||||||
var s *obj.LSym
|
|
||||||
var q *obj.Prog
|
|
||||||
|
|
||||||
// See obj6.c for discussion of TLS.
|
// See obj6.c for discussion of TLS.
|
||||||
if canuselocaltls(ctxt) {
|
if canuselocaltls(ctxt) {
|
||||||
// Reduce TLS initial exec model to TLS local exec model.
|
// Reduce TLS initial exec model to TLS local exec model.
|
||||||
|
|
@ -92,7 +88,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||||
// MOVL off(BX)(TLS*1), BX
|
// MOVL off(BX)(TLS*1), BX
|
||||||
// This allows the C compilers to emit references to m and g using the direct off(TLS) form.
|
// This allows the C compilers to emit references to m and g using the direct off(TLS) form.
|
||||||
if p.As == AMOVL && p.From.Type == obj.TYPE_MEM && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_DI {
|
if p.As == AMOVL && p.From.Type == obj.TYPE_MEM && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_DI {
|
||||||
q = obj.Appendp(ctxt, p)
|
q := obj.Appendp(ctxt, p)
|
||||||
q.As = p.As
|
q.As = p.As
|
||||||
q.From.Type = obj.TYPE_MEM
|
q.From.Type = obj.TYPE_MEM
|
||||||
q.From.Reg = p.To.Reg
|
q.From.Reg = p.To.Reg
|
||||||
|
|
@ -159,12 +155,10 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||||
ACOMISS,
|
ACOMISS,
|
||||||
AUCOMISS:
|
AUCOMISS:
|
||||||
if p.From.Type == obj.TYPE_FCONST {
|
if p.From.Type == obj.TYPE_FCONST {
|
||||||
var i32 uint32
|
f32 := float32(p.From.U.Dval)
|
||||||
var f32 float32
|
i32 := math.Float32bits(f32)
|
||||||
f32 = float32(p.From.U.Dval)
|
literal := fmt.Sprintf("$f32.%08x", i32)
|
||||||
i32 = math.Float32bits(f32)
|
s := obj.Linklookup(ctxt, literal, 0)
|
||||||
literal = fmt.Sprintf("$f32.%08x", i32)
|
|
||||||
s = obj.Linklookup(ctxt, literal, 0)
|
|
||||||
if s.Type == 0 {
|
if s.Type == 0 {
|
||||||
s.Type = obj.SRODATA
|
s.Type = obj.SRODATA
|
||||||
obj.Adduint32(ctxt, s, i32)
|
obj.Adduint32(ctxt, s, i32)
|
||||||
|
|
@ -208,10 +202,9 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||||
ACOMISD,
|
ACOMISD,
|
||||||
AUCOMISD:
|
AUCOMISD:
|
||||||
if p.From.Type == obj.TYPE_FCONST {
|
if p.From.Type == obj.TYPE_FCONST {
|
||||||
var i64 uint64
|
i64 := math.Float64bits(p.From.U.Dval)
|
||||||
i64 = math.Float64bits(p.From.U.Dval)
|
literal := fmt.Sprintf("$f64.%016x", i64)
|
||||||
literal = fmt.Sprintf("$f64.%016x", i64)
|
s := obj.Linklookup(ctxt, literal, 0)
|
||||||
s = obj.Linklookup(ctxt, literal, 0)
|
|
||||||
if s.Type == 0 {
|
if s.Type == 0 {
|
||||||
s.Type = obj.SRODATA
|
s.Type = obj.SRODATA
|
||||||
obj.Adduint64(ctxt, s, i64)
|
obj.Adduint64(ctxt, s, i64)
|
||||||
|
|
@ -227,14 +220,6 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
var p *obj.Prog
|
|
||||||
var q *obj.Prog
|
|
||||||
var p1 *obj.Prog
|
|
||||||
var p2 *obj.Prog
|
|
||||||
var autoffset int32
|
|
||||||
var deltasp int32
|
|
||||||
var a int
|
|
||||||
|
|
||||||
if ctxt.Symmorestack[0] == nil {
|
if ctxt.Symmorestack[0] == nil {
|
||||||
ctxt.Symmorestack[0] = obj.Linklookup(ctxt, "runtime.morestack", 0)
|
ctxt.Symmorestack[0] = obj.Linklookup(ctxt, "runtime.morestack", 0)
|
||||||
ctxt.Symmorestack[1] = obj.Linklookup(ctxt, "runtime.morestack_noctxt", 0)
|
ctxt.Symmorestack[1] = obj.Linklookup(ctxt, "runtime.morestack_noctxt", 0)
|
||||||
|
|
@ -250,8 +235,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
p = cursym.Text
|
p := cursym.Text
|
||||||
autoffset = int32(p.To.Offset)
|
autoffset := int32(p.To.Offset)
|
||||||
if autoffset < 0 {
|
if autoffset < 0 {
|
||||||
autoffset = 0
|
autoffset = 0
|
||||||
}
|
}
|
||||||
|
|
@ -259,7 +244,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
cursym.Locals = autoffset
|
cursym.Locals = autoffset
|
||||||
cursym.Args = p.To.U.Argsize
|
cursym.Args = p.To.U.Argsize
|
||||||
|
|
||||||
q = nil
|
q := (*obj.Prog)(nil)
|
||||||
|
|
||||||
if p.From3.Offset&obj.NOSPLIT == 0 || (p.From3.Offset&obj.WRAPPER != 0) {
|
if p.From3.Offset&obj.NOSPLIT == 0 || (p.From3.Offset&obj.WRAPPER != 0) {
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
@ -292,7 +277,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
if q != nil {
|
if q != nil {
|
||||||
q.Pcond = p
|
q.Pcond = p
|
||||||
}
|
}
|
||||||
deltasp = autoffset
|
deltasp := autoffset
|
||||||
|
|
||||||
if cursym.Text.From3.Offset&obj.WRAPPER != 0 {
|
if cursym.Text.From3.Offset&obj.WRAPPER != 0 {
|
||||||
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
||||||
|
|
@ -329,7 +314,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AJEQ
|
p.As = AJEQ
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
p1 = p
|
p1 := p
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ALEAL
|
p.As = ALEAL
|
||||||
|
|
@ -350,7 +335,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AJNE
|
p.As = AJNE
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
p2 = p
|
p2 := p
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AMOVL
|
p.As = AMOVL
|
||||||
|
|
@ -400,6 +385,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
p.As = ASTOSL
|
p.As = ASTOSL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var a int
|
||||||
for ; p != nil; p = p.Link {
|
for ; p != nil; p = p.Link {
|
||||||
a = int(p.From.Name)
|
a = int(p.From.Name)
|
||||||
if a == obj.NAME_AUTO {
|
if a == obj.NAME_AUTO {
|
||||||
|
|
@ -479,8 +465,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
// prologue (caller must call appendp first) and in the epilogue.
|
// prologue (caller must call appendp first) and in the epilogue.
|
||||||
// Returns last new instruction.
|
// Returns last new instruction.
|
||||||
func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
|
func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
|
||||||
var next *obj.Prog
|
|
||||||
|
|
||||||
p.As = AMOVL
|
p.As = AMOVL
|
||||||
p.From.Type = obj.TYPE_MEM
|
p.From.Type = obj.TYPE_MEM
|
||||||
p.From.Reg = REG_TLS
|
p.From.Reg = REG_TLS
|
||||||
|
|
@ -488,7 +472,7 @@ func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REG_CX
|
p.To.Reg = REG_CX
|
||||||
|
|
||||||
next = p.Link
|
next := p.Link
|
||||||
progedit(ctxt, p)
|
progedit(ctxt, p)
|
||||||
for p.Link != next {
|
for p.Link != next {
|
||||||
p = p.Link
|
p = p.Link
|
||||||
|
|
@ -508,9 +492,6 @@ func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
|
||||||
// On return, *jmpok is the instruction that should jump
|
// On return, *jmpok is the instruction that should jump
|
||||||
// to the stack frame allocation if no split is needed.
|
// to the stack frame allocation if no split is needed.
|
||||||
func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt bool, jmpok **obj.Prog) *obj.Prog {
|
func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt bool, jmpok **obj.Prog) *obj.Prog {
|
||||||
var q *obj.Prog
|
|
||||||
var q1 *obj.Prog
|
|
||||||
|
|
||||||
if ctxt.Debugstack != 0 {
|
if ctxt.Debugstack != 0 {
|
||||||
// 8l -K means check not only for stack
|
// 8l -K means check not only for stack
|
||||||
// overflow but stack underflow.
|
// overflow but stack underflow.
|
||||||
|
|
@ -530,7 +511,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt bool, jmpok
|
||||||
p.As = AJCC
|
p.As = AJCC
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
p.To.Offset = 4
|
p.To.Offset = 4
|
||||||
q1 = p
|
q1 := p
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AINT
|
p.As = AINT
|
||||||
|
|
@ -542,7 +523,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt bool, jmpok
|
||||||
q1.Pcond = p
|
q1.Pcond = p
|
||||||
}
|
}
|
||||||
|
|
||||||
q1 = nil
|
q1 := (*obj.Prog)(nil)
|
||||||
|
|
||||||
if framesize <= obj.StackSmall {
|
if framesize <= obj.StackSmall {
|
||||||
// small stack: SP <= stackguard
|
// small stack: SP <= stackguard
|
||||||
|
|
@ -651,7 +632,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt bool, jmpok
|
||||||
p.As = AJHI
|
p.As = AJHI
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
p.To.Offset = 4
|
p.To.Offset = 4
|
||||||
q = p
|
q := p
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = obj.ACALL
|
p.As = obj.ACALL
|
||||||
|
|
@ -679,13 +660,10 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt bool, jmpok
|
||||||
}
|
}
|
||||||
|
|
||||||
func follow(ctxt *obj.Link, s *obj.LSym) {
|
func follow(ctxt *obj.Link, s *obj.LSym) {
|
||||||
var firstp *obj.Prog
|
|
||||||
var lastp *obj.Prog
|
|
||||||
|
|
||||||
ctxt.Cursym = s
|
ctxt.Cursym = s
|
||||||
|
|
||||||
firstp = ctxt.NewProg()
|
firstp := ctxt.NewProg()
|
||||||
lastp = firstp
|
lastp := firstp
|
||||||
xfol(ctxt, s.Text, &lastp)
|
xfol(ctxt, s.Text, &lastp)
|
||||||
lastp.Link = nil
|
lastp.Link = nil
|
||||||
s.Text = firstp.Link
|
s.Text = firstp.Link
|
||||||
|
|
|
||||||
|
|
@ -407,18 +407,7 @@ var oprange [ALAST]Oprang
|
||||||
var xcmp [C_NCLASS][C_NCLASS]uint8
|
var xcmp [C_NCLASS][C_NCLASS]uint8
|
||||||
|
|
||||||
func span9(ctxt *obj.Link, cursym *obj.LSym) {
|
func span9(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
var p *obj.Prog
|
p := cursym.Text
|
||||||
var q *obj.Prog
|
|
||||||
var o *Optab
|
|
||||||
var m int
|
|
||||||
var bflag int
|
|
||||||
var c int64
|
|
||||||
var otxt int64
|
|
||||||
var out [6]uint32
|
|
||||||
var i int32
|
|
||||||
var bp []byte
|
|
||||||
|
|
||||||
p = cursym.Text
|
|
||||||
if p == nil || p.Link == nil { // handle external functions and ELF section symbols
|
if p == nil || p.Link == nil { // handle external functions and ELF section symbols
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -429,9 +418,11 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
buildop(ctxt)
|
buildop(ctxt)
|
||||||
}
|
}
|
||||||
|
|
||||||
c = 0
|
c := int64(0)
|
||||||
p.Pc = c
|
p.Pc = c
|
||||||
|
|
||||||
|
var m int
|
||||||
|
var o *Optab
|
||||||
for p = p.Link; p != nil; p = p.Link {
|
for p = p.Link; p != nil; p = p.Link {
|
||||||
ctxt.Curp = p
|
ctxt.Curp = p
|
||||||
p.Pc = c
|
p.Pc = c
|
||||||
|
|
@ -455,8 +446,10 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
* generate extra passes putting branches
|
* generate extra passes putting branches
|
||||||
* around jmps to fix. this is rare.
|
* around jmps to fix. this is rare.
|
||||||
*/
|
*/
|
||||||
bflag = 1
|
bflag := 1
|
||||||
|
|
||||||
|
var otxt int64
|
||||||
|
var q *obj.Prog
|
||||||
for bflag != 0 {
|
for bflag != 0 {
|
||||||
if ctxt.Debugvlog != 0 {
|
if ctxt.Debugvlog != 0 {
|
||||||
fmt.Fprintf(ctxt.Bso, "%5.2f span1\n", obj.Cputime())
|
fmt.Fprintf(ctxt.Bso, "%5.2f span1\n", obj.Cputime())
|
||||||
|
|
@ -517,8 +510,10 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
|
|
||||||
obj.Symgrow(ctxt, cursym, cursym.Size)
|
obj.Symgrow(ctxt, cursym, cursym.Size)
|
||||||
|
|
||||||
bp = cursym.P
|
bp := cursym.P
|
||||||
for p = cursym.Text.Link; p != nil; p = p.Link {
|
var i int32
|
||||||
|
var out [6]uint32
|
||||||
|
for p := cursym.Text.Link; p != nil; p = p.Link {
|
||||||
ctxt.Pc = p.Pc
|
ctxt.Pc = p.Pc
|
||||||
ctxt.Curp = p
|
ctxt.Curp = p
|
||||||
o = oplook(ctxt, p)
|
o = oplook(ctxt, p)
|
||||||
|
|
@ -542,8 +537,6 @@ func isuint32(v uint64) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
||||||
var s *obj.LSym
|
|
||||||
|
|
||||||
switch a.Type {
|
switch a.Type {
|
||||||
case obj.TYPE_NONE:
|
case obj.TYPE_NONE:
|
||||||
return C_NONE
|
return C_NONE
|
||||||
|
|
@ -646,7 +639,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
||||||
|
|
||||||
case obj.NAME_EXTERN,
|
case obj.NAME_EXTERN,
|
||||||
obj.NAME_STATIC:
|
obj.NAME_STATIC:
|
||||||
s = a.Sym
|
s := a.Sym
|
||||||
if s == nil {
|
if s == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -720,18 +713,7 @@ func prasm(p *obj.Prog) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func oplook(ctxt *obj.Link, p *obj.Prog) *Optab {
|
func oplook(ctxt *obj.Link, p *obj.Prog) *Optab {
|
||||||
var a1 int
|
a1 := int(p.Optab)
|
||||||
var a2 int
|
|
||||||
var a3 int
|
|
||||||
var a4 int
|
|
||||||
var r int
|
|
||||||
var c1 []byte
|
|
||||||
var c3 []byte
|
|
||||||
var c4 []byte
|
|
||||||
var o []Optab
|
|
||||||
var e []Optab
|
|
||||||
|
|
||||||
a1 = int(p.Optab)
|
|
||||||
if a1 != 0 {
|
if a1 != 0 {
|
||||||
return &optab[a1-1:][0]
|
return &optab[a1-1:][0]
|
||||||
}
|
}
|
||||||
|
|
@ -742,36 +724,36 @@ func oplook(ctxt *obj.Link, p *obj.Prog) *Optab {
|
||||||
}
|
}
|
||||||
|
|
||||||
a1--
|
a1--
|
||||||
a3 = int(p.From3.Class)
|
a3 := int(p.From3.Class)
|
||||||
if a3 == 0 {
|
if a3 == 0 {
|
||||||
a3 = aclass(ctxt, &p.From3) + 1
|
a3 = aclass(ctxt, &p.From3) + 1
|
||||||
p.From3.Class = int8(a3)
|
p.From3.Class = int8(a3)
|
||||||
}
|
}
|
||||||
|
|
||||||
a3--
|
a3--
|
||||||
a4 = int(p.To.Class)
|
a4 := int(p.To.Class)
|
||||||
if a4 == 0 {
|
if a4 == 0 {
|
||||||
a4 = aclass(ctxt, &p.To) + 1
|
a4 = aclass(ctxt, &p.To) + 1
|
||||||
p.To.Class = int8(a4)
|
p.To.Class = int8(a4)
|
||||||
}
|
}
|
||||||
|
|
||||||
a4--
|
a4--
|
||||||
a2 = C_NONE
|
a2 := C_NONE
|
||||||
if p.Reg != 0 {
|
if p.Reg != 0 {
|
||||||
a2 = C_REG
|
a2 = C_REG
|
||||||
}
|
}
|
||||||
|
|
||||||
//print("oplook %P %d %d %d %d\n", p, a1, a2, a3, a4);
|
//print("oplook %P %d %d %d %d\n", p, a1, a2, a3, a4);
|
||||||
r = int(p.As)
|
r := int(p.As)
|
||||||
|
|
||||||
o = oprange[r].start
|
o := oprange[r].start
|
||||||
if o == nil {
|
if o == nil {
|
||||||
o = oprange[r].stop /* just generate an error */
|
o = oprange[r].stop /* just generate an error */
|
||||||
}
|
}
|
||||||
e = oprange[r].stop
|
e := oprange[r].stop
|
||||||
c1 = xcmp[a1][:]
|
c1 := xcmp[a1][:]
|
||||||
c3 = xcmp[a3][:]
|
c3 := xcmp[a3][:]
|
||||||
c4 = xcmp[a4][:]
|
c4 := xcmp[a4][:]
|
||||||
for ; -cap(o) < -cap(e); o = o[1:] {
|
for ; -cap(o) < -cap(e); o = o[1:] {
|
||||||
if int(o[0].a2) == a2 {
|
if int(o[0].a2) == a2 {
|
||||||
if c1[o[0].a1] != 0 {
|
if c1[o[0].a1] != 0 {
|
||||||
|
|
@ -881,13 +863,9 @@ func (x ocmp) Swap(i, j int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x ocmp) Less(i, j int) bool {
|
func (x ocmp) Less(i, j int) bool {
|
||||||
var p1 *Optab
|
p1 := &x[i]
|
||||||
var p2 *Optab
|
p2 := &x[j]
|
||||||
var n int
|
n := int(p1.as) - int(p2.as)
|
||||||
|
|
||||||
p1 = &x[i]
|
|
||||||
p2 = &x[j]
|
|
||||||
n = int(p1.as) - int(p2.as)
|
|
||||||
if n != 0 {
|
if n != 0 {
|
||||||
return n < 0
|
return n < 0
|
||||||
}
|
}
|
||||||
|
|
@ -911,11 +889,9 @@ func (x ocmp) Less(i, j int) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildop(ctxt *obj.Link) {
|
func buildop(ctxt *obj.Link) {
|
||||||
var i int
|
|
||||||
var n int
|
var n int
|
||||||
var r int
|
|
||||||
|
|
||||||
for i = 0; i < C_NCLASS; i++ {
|
for i := 0; i < C_NCLASS; i++ {
|
||||||
for n = 0; n < C_NCLASS; n++ {
|
for n = 0; n < C_NCLASS; n++ {
|
||||||
if cmp(n, i) {
|
if cmp(n, i) {
|
||||||
xcmp[i][n] = 1
|
xcmp[i][n] = 1
|
||||||
|
|
@ -925,7 +901,8 @@ func buildop(ctxt *obj.Link) {
|
||||||
for n = 0; optab[n].as != obj.AXXX; n++ {
|
for n = 0; optab[n].as != obj.AXXX; n++ {
|
||||||
}
|
}
|
||||||
sort.Sort(ocmp(optab[:n]))
|
sort.Sort(ocmp(optab[:n]))
|
||||||
for i = 0; i < n; i++ {
|
var r int
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
r = int(optab[i].as)
|
r = int(optab[i].as)
|
||||||
oprange[r].start = optab[i:]
|
oprange[r].start = optab[i:]
|
||||||
for int(optab[i].as) == r {
|
for int(optab[i].as) == r {
|
||||||
|
|
@ -1393,9 +1370,7 @@ func oclass(a *obj.Addr) int {
|
||||||
|
|
||||||
// add R_ADDRPOWER relocation to symbol s for the two instructions o1 and o2.
|
// add R_ADDRPOWER relocation to symbol s for the two instructions o1 and o2.
|
||||||
func addaddrreloc(ctxt *obj.Link, s *obj.LSym, o1 *uint32, o2 *uint32) {
|
func addaddrreloc(ctxt *obj.Link, s *obj.LSym, o1 *uint32, o2 *uint32) {
|
||||||
var rel *obj.Reloc
|
rel := obj.Addrel(ctxt.Cursym)
|
||||||
|
|
||||||
rel = obj.Addrel(ctxt.Cursym)
|
|
||||||
rel.Off = int32(ctxt.Pc)
|
rel.Off = int32(ctxt.Pc)
|
||||||
rel.Siz = 8
|
rel.Siz = 8
|
||||||
rel.Sym = s
|
rel.Sym = s
|
||||||
|
|
@ -1407,13 +1382,11 @@ func addaddrreloc(ctxt *obj.Link, s *obj.LSym, o1 *uint32, o2 *uint32) {
|
||||||
* 32-bit masks
|
* 32-bit masks
|
||||||
*/
|
*/
|
||||||
func getmask(m []byte, v uint32) bool {
|
func getmask(m []byte, v uint32) bool {
|
||||||
var i int
|
|
||||||
|
|
||||||
m[1] = 0
|
m[1] = 0
|
||||||
m[0] = m[1]
|
m[0] = m[1]
|
||||||
if v != ^uint32(0) && v&(1<<31) != 0 && v&1 != 0 { /* MB > ME */
|
if v != ^uint32(0) && v&(1<<31) != 0 && v&1 != 0 { /* MB > ME */
|
||||||
if getmask(m, ^v) {
|
if getmask(m, ^v) {
|
||||||
i = int(m[0])
|
i := int(m[0])
|
||||||
m[0] = m[1] + 1
|
m[0] = m[1] + 1
|
||||||
m[1] = byte(i - 1)
|
m[1] = byte(i - 1)
|
||||||
return true
|
return true
|
||||||
|
|
@ -1422,7 +1395,7 @@ func getmask(m []byte, v uint32) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
for i = 0; i < 32; i++ {
|
for i := 0; i < 32; i++ {
|
||||||
if v&(1<<uint(31-i)) != 0 {
|
if v&(1<<uint(31-i)) != 0 {
|
||||||
m[0] = byte(i)
|
m[0] = byte(i)
|
||||||
for {
|
for {
|
||||||
|
|
@ -1455,11 +1428,9 @@ func maskgen(ctxt *obj.Link, p *obj.Prog, m []byte, v uint32) {
|
||||||
* 64-bit masks (rldic etc)
|
* 64-bit masks (rldic etc)
|
||||||
*/
|
*/
|
||||||
func getmask64(m []byte, v uint64) bool {
|
func getmask64(m []byte, v uint64) bool {
|
||||||
var i int
|
|
||||||
|
|
||||||
m[1] = 0
|
m[1] = 0
|
||||||
m[0] = m[1]
|
m[0] = m[1]
|
||||||
for i = 0; i < 64; i++ {
|
for i := 0; i < 64; i++ {
|
||||||
if v&(uint64(1)<<uint(63-i)) != 0 {
|
if v&(uint64(1)<<uint(63-i)) != 0 {
|
||||||
m[0] = byte(i)
|
m[0] = byte(i)
|
||||||
for {
|
for {
|
||||||
|
|
@ -1489,9 +1460,7 @@ func maskgen64(ctxt *obj.Link, p *obj.Prog, m []byte, v uint64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadu32(r int, d int64) uint32 {
|
func loadu32(r int, d int64) uint32 {
|
||||||
var v int32
|
v := int32(d >> 16)
|
||||||
|
|
||||||
v = int32(d >> 16)
|
|
||||||
if isuint32(uint64(d)) {
|
if isuint32(uint64(d)) {
|
||||||
return LOP_IRR(OP_ORIS, uint32(r), REGZERO, uint32(v))
|
return LOP_IRR(OP_ORIS, uint32(r), REGZERO, uint32(v))
|
||||||
}
|
}
|
||||||
|
|
@ -1506,24 +1475,11 @@ func high16adjusted(d int32) uint16 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
var o1 uint32
|
o1 := uint32(0)
|
||||||
var o2 uint32
|
o2 := uint32(0)
|
||||||
var o3 uint32
|
o3 := uint32(0)
|
||||||
var o4 uint32
|
o4 := uint32(0)
|
||||||
var o5 uint32
|
o5 := uint32(0)
|
||||||
var v int32
|
|
||||||
var t int32
|
|
||||||
var d int64
|
|
||||||
var r int
|
|
||||||
var a int
|
|
||||||
var mask [2]uint8
|
|
||||||
var rel *obj.Reloc
|
|
||||||
|
|
||||||
o1 = 0
|
|
||||||
o2 = 0
|
|
||||||
o3 = 0
|
|
||||||
o4 = 0
|
|
||||||
o5 = 0
|
|
||||||
|
|
||||||
//print("%P => case %d\n", p, o->type);
|
//print("%P => case %d\n", p, o->type);
|
||||||
switch o.type_ {
|
switch o.type_ {
|
||||||
|
|
@ -1536,7 +1492,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
|
|
||||||
case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */
|
case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */
|
||||||
if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
|
if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
|
||||||
v = regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
|
if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
|
||||||
//nerrors--;
|
//nerrors--;
|
||||||
ctxt.Diag("literal operation on R0\n%v", p)
|
ctxt.Diag("literal operation on R0\n%v", p)
|
||||||
|
|
@ -1549,7 +1505,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = LOP_RRR(OP_OR, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg))
|
o1 = LOP_RRR(OP_OR, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg))
|
||||||
|
|
||||||
case 2: /* int/cr/fp op Rb,[Ra],Rd */
|
case 2: /* int/cr/fp op Rb,[Ra],Rd */
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
|
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
|
|
@ -1557,17 +1513,17 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
|
||||||
|
|
||||||
case 3: /* mov $soreg/addcon/ucon, r ==> addis/addi $i,reg',r */
|
case 3: /* mov $soreg/addcon/ucon, r ==> addis/addi $i,reg',r */
|
||||||
d = vregoff(ctxt, &p.From)
|
d := vregoff(ctxt, &p.From)
|
||||||
|
|
||||||
v = int32(d)
|
v := int32(d)
|
||||||
r = int(p.From.Reg)
|
r := int(p.From.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) {
|
if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) {
|
||||||
ctxt.Diag("literal operation on R0\n%v", p)
|
ctxt.Diag("literal operation on R0\n%v", p)
|
||||||
}
|
}
|
||||||
a = OP_ADDI
|
a := OP_ADDI
|
||||||
if o.a1 == C_UCON {
|
if o.a1 == C_UCON {
|
||||||
if d&0xffff != 0 {
|
if d&0xffff != 0 {
|
||||||
log.Fatalf("invalid handling of %v", p)
|
log.Fatalf("invalid handling of %v", p)
|
||||||
|
|
@ -1588,9 +1544,9 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = AOP_IRR(uint32(a), uint32(p.To.Reg), uint32(r), uint32(v))
|
o1 = AOP_IRR(uint32(a), uint32(p.To.Reg), uint32(r), uint32(v))
|
||||||
|
|
||||||
case 4: /* add/mul $scon,[r1],r2 */
|
case 4: /* add/mul $scon,[r1],r2 */
|
||||||
v = regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
|
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
|
|
@ -1606,7 +1562,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = uint32(oprrr(ctxt, int(p.As)))
|
o1 = uint32(oprrr(ctxt, int(p.As)))
|
||||||
|
|
||||||
case 6: /* logical op Rb,[Rs,]Ra; no literal */
|
case 6: /* logical op Rb,[Rs,]Ra; no literal */
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
|
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
|
|
@ -1614,12 +1570,12 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
|
o1 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
|
||||||
|
|
||||||
case 7: /* mov r, soreg ==> stw o(r) */
|
case 7: /* mov r, soreg ==> stw o(r) */
|
||||||
r = int(p.To.Reg)
|
r := int(p.To.Reg)
|
||||||
|
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
v = regoff(ctxt, &p.To)
|
v := regoff(ctxt, &p.To)
|
||||||
if p.To.Type == obj.TYPE_MEM && p.Reg != 0 {
|
if p.To.Type == obj.TYPE_MEM && p.Reg != 0 {
|
||||||
if v != 0 {
|
if v != 0 {
|
||||||
ctxt.Diag("illegal indexed instruction\n%v", p)
|
ctxt.Diag("illegal indexed instruction\n%v", p)
|
||||||
|
|
@ -1633,12 +1589,12 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */
|
case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */
|
||||||
r = int(p.From.Reg)
|
r := int(p.From.Reg)
|
||||||
|
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
v = regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
if p.From.Type == obj.TYPE_MEM && p.Reg != 0 {
|
if p.From.Type == obj.TYPE_MEM && p.Reg != 0 {
|
||||||
if v != 0 {
|
if v != 0 {
|
||||||
ctxt.Diag("illegal indexed instruction\n%v", p)
|
ctxt.Diag("illegal indexed instruction\n%v", p)
|
||||||
|
|
@ -1652,12 +1608,12 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */
|
case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */
|
||||||
r = int(p.From.Reg)
|
r := int(p.From.Reg)
|
||||||
|
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
v = regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
if p.From.Type == obj.TYPE_MEM && p.Reg != 0 {
|
if p.From.Type == obj.TYPE_MEM && p.Reg != 0 {
|
||||||
if v != 0 {
|
if v != 0 {
|
||||||
ctxt.Diag("illegal indexed instruction\n%v", p)
|
ctxt.Diag("illegal indexed instruction\n%v", p)
|
||||||
|
|
@ -1669,7 +1625,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
|
o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
|
||||||
|
|
||||||
case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
|
case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
|
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
|
|
@ -1677,7 +1633,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Reg), uint32(r))
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Reg), uint32(r))
|
||||||
|
|
||||||
case 11: /* br/bl lbra */
|
case 11: /* br/bl lbra */
|
||||||
v = 0
|
v := int32(0)
|
||||||
|
|
||||||
if p.Pcond != nil {
|
if p.Pcond != nil {
|
||||||
v = int32(p.Pcond.Pc - p.Pc)
|
v = int32(p.Pcond.Pc - p.Pc)
|
||||||
|
|
@ -1693,7 +1649,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
|
|
||||||
o1 = OP_BR(uint32(opirr(ctxt, int(p.As))), uint32(v), 0)
|
o1 = OP_BR(uint32(opirr(ctxt, int(p.As))), uint32(v), 0)
|
||||||
if p.To.Sym != nil {
|
if p.To.Sym != nil {
|
||||||
rel = obj.Addrel(ctxt.Cursym)
|
rel := obj.Addrel(ctxt.Cursym)
|
||||||
rel.Off = int32(ctxt.Pc)
|
rel.Off = int32(ctxt.Pc)
|
||||||
rel.Siz = 4
|
rel.Siz = 4
|
||||||
rel.Sym = p.To.Sym
|
rel.Sym = p.To.Sym
|
||||||
|
|
@ -1709,7 +1665,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
|
|
||||||
case 12: /* movb r,r (extsb); movw r,r (extsw) */
|
case 12: /* movb r,r (extsb); movw r,r (extsw) */
|
||||||
if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
|
if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
|
||||||
v = regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
|
if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
|
||||||
ctxt.Diag("literal operation on R0\n%v", p)
|
ctxt.Diag("literal operation on R0\n%v", p)
|
||||||
}
|
}
|
||||||
|
|
@ -1738,13 +1694,15 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
|
case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
|
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
d = vregoff(ctxt, &p.From3)
|
d := vregoff(ctxt, &p.From3)
|
||||||
|
var mask [2]uint8
|
||||||
maskgen64(ctxt, p, mask[:], uint64(d))
|
maskgen64(ctxt, p, mask[:], uint64(d))
|
||||||
|
var a int
|
||||||
switch p.As {
|
switch p.As {
|
||||||
case ARLDCL,
|
case ARLDCL,
|
||||||
ARLDCLCC:
|
ARLDCLCC:
|
||||||
|
|
@ -1773,16 +1731,16 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
|
|
||||||
case 17, /* bc bo,bi,lbra (same for now) */
|
case 17, /* bc bo,bi,lbra (same for now) */
|
||||||
16: /* bc bo,bi,sbra */
|
16: /* bc bo,bi,sbra */
|
||||||
a = 0
|
a := 0
|
||||||
|
|
||||||
if p.From.Type == obj.TYPE_CONST {
|
if p.From.Type == obj.TYPE_CONST {
|
||||||
a = int(regoff(ctxt, &p.From))
|
a = int(regoff(ctxt, &p.From))
|
||||||
}
|
}
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = 0
|
r = 0
|
||||||
}
|
}
|
||||||
v = 0
|
v := int32(0)
|
||||||
if p.Pcond != nil {
|
if p.Pcond != nil {
|
||||||
v = int32(p.Pcond.Pc - p.Pc)
|
v = int32(p.Pcond.Pc - p.Pc)
|
||||||
}
|
}
|
||||||
|
|
@ -1797,12 +1755,13 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = OP_BC(uint32(opirr(ctxt, int(p.As))), uint32(a), uint32(r), uint32(v), 0)
|
o1 = OP_BC(uint32(opirr(ctxt, int(p.As))), uint32(a), uint32(r), uint32(v), 0)
|
||||||
|
|
||||||
case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */
|
case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */
|
||||||
|
var v int32
|
||||||
if p.As == ABC || p.As == ABCL {
|
if p.As == ABC || p.As == ABCL {
|
||||||
v = regoff(ctxt, &p.To) & 31
|
v = regoff(ctxt, &p.To) & 31
|
||||||
} else {
|
} else {
|
||||||
v = 20 /* unconditional */
|
v = 20 /* unconditional */
|
||||||
}
|
}
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = 0
|
r = 0
|
||||||
}
|
}
|
||||||
|
|
@ -1814,12 +1773,13 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o2 = OP_BCR(o2, uint32(v), uint32(r))
|
o2 = OP_BCR(o2, uint32(v), uint32(r))
|
||||||
|
|
||||||
case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */
|
case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */
|
||||||
|
var v int32
|
||||||
if p.As == ABC || p.As == ABCL {
|
if p.As == ABC || p.As == ABCL {
|
||||||
v = regoff(ctxt, &p.From) & 31
|
v = regoff(ctxt, &p.From) & 31
|
||||||
} else {
|
} else {
|
||||||
v = 20 /* unconditional */
|
v = 20 /* unconditional */
|
||||||
}
|
}
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = 0
|
r = 0
|
||||||
}
|
}
|
||||||
|
|
@ -1841,7 +1801,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = OP_BCR(o1, uint32(v), uint32(r))
|
o1 = OP_BCR(o1, uint32(v), uint32(r))
|
||||||
|
|
||||||
case 19: /* mov $lcon,r ==> cau+or */
|
case 19: /* mov $lcon,r ==> cau+or */
|
||||||
d = vregoff(ctxt, &p.From)
|
d := vregoff(ctxt, &p.From)
|
||||||
|
|
||||||
if p.From.Sym == nil {
|
if p.From.Sym == nil {
|
||||||
o1 = loadu32(int(p.To.Reg), d)
|
o1 = loadu32(int(p.To.Reg), d)
|
||||||
|
|
@ -1855,9 +1815,9 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
//if(dlm) reloc(&p->from, p->pc, 0);
|
//if(dlm) reloc(&p->from, p->pc, 0);
|
||||||
|
|
||||||
case 20: /* add $ucon,,r */
|
case 20: /* add $ucon,,r */
|
||||||
v = regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
|
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
|
|
@ -1870,10 +1830,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
if p.To.Reg == REGTMP || p.Reg == REGTMP {
|
if p.To.Reg == REGTMP || p.Reg == REGTMP {
|
||||||
ctxt.Diag("cant synthesize large constant\n%v", p)
|
ctxt.Diag("cant synthesize large constant\n%v", p)
|
||||||
}
|
}
|
||||||
d = vregoff(ctxt, &p.From)
|
d := vregoff(ctxt, &p.From)
|
||||||
o1 = loadu32(REGTMP, d)
|
o1 = loadu32(REGTMP, d)
|
||||||
o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
|
o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
|
|
@ -1888,10 +1848,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
if p.To.Reg == REGTMP || p.Reg == REGTMP {
|
if p.To.Reg == REGTMP || p.Reg == REGTMP {
|
||||||
ctxt.Diag("cant synthesize large constant\n%v", p)
|
ctxt.Diag("cant synthesize large constant\n%v", p)
|
||||||
}
|
}
|
||||||
d = vregoff(ctxt, &p.From)
|
d := vregoff(ctxt, &p.From)
|
||||||
o1 = loadu32(REGTMP, d)
|
o1 = loadu32(REGTMP, d)
|
||||||
o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
|
o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
|
|
@ -1905,17 +1865,18 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
/*24*/
|
/*24*/
|
||||||
case 25:
|
case 25:
|
||||||
/* sld[.] $sh,rS,rA -> rldicr[.] $sh,rS,mask(0,63-sh),rA; srd[.] -> rldicl */
|
/* sld[.] $sh,rS,rA -> rldicr[.] $sh,rS,mask(0,63-sh),rA; srd[.] -> rldicl */
|
||||||
v = regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
|
|
||||||
if v < 0 {
|
if v < 0 {
|
||||||
v = 0
|
v = 0
|
||||||
} else if v > 63 {
|
} else if v > 63 {
|
||||||
v = 63
|
v = 63
|
||||||
}
|
}
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
|
var a int
|
||||||
switch p.As {
|
switch p.As {
|
||||||
case ASLD,
|
case ASLD,
|
||||||
ASLDCC:
|
ASLDCC:
|
||||||
|
|
@ -1950,8 +1911,8 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
if p.To.Reg == REGTMP {
|
if p.To.Reg == REGTMP {
|
||||||
ctxt.Diag("can't synthesize large constant\n%v", p)
|
ctxt.Diag("can't synthesize large constant\n%v", p)
|
||||||
}
|
}
|
||||||
v = regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
r = int(p.From.Reg)
|
r := int(p.From.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
|
|
@ -1959,16 +1920,16 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(v))
|
o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(v))
|
||||||
|
|
||||||
case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */
|
case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */
|
||||||
v = regoff(ctxt, &p.From3)
|
v := regoff(ctxt, &p.From3)
|
||||||
|
|
||||||
r = int(p.From.Reg)
|
r := int(p.From.Reg)
|
||||||
o1 = AOP_IRR(uint32(opirr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(v))
|
o1 = AOP_IRR(uint32(opirr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(v))
|
||||||
|
|
||||||
case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */
|
case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */
|
||||||
if p.To.Reg == REGTMP || p.From.Reg == REGTMP {
|
if p.To.Reg == REGTMP || p.From.Reg == REGTMP {
|
||||||
ctxt.Diag("can't synthesize large constant\n%v", p)
|
ctxt.Diag("can't synthesize large constant\n%v", p)
|
||||||
}
|
}
|
||||||
v = regoff(ctxt, &p.From3)
|
v := regoff(ctxt, &p.From3)
|
||||||
o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(v)>>16)
|
o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(v)>>16)
|
||||||
o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(v))
|
o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(v))
|
||||||
o3 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Reg), REGTMP)
|
o3 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Reg), REGTMP)
|
||||||
|
|
@ -1979,10 +1940,12 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
//if(dlm) reloc(&p->from3, p->pc, 0);
|
//if(dlm) reloc(&p->from3, p->pc, 0);
|
||||||
|
|
||||||
case 29: /* rldic[lr]? $sh,s,$mask,a -- left, right, plain give different masks */
|
case 29: /* rldic[lr]? $sh,s,$mask,a -- left, right, plain give different masks */
|
||||||
v = regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
|
|
||||||
d = vregoff(ctxt, &p.From3)
|
d := vregoff(ctxt, &p.From3)
|
||||||
|
var mask [2]uint8
|
||||||
maskgen64(ctxt, p, mask[:], uint64(d))
|
maskgen64(ctxt, p, mask[:], uint64(d))
|
||||||
|
var a int
|
||||||
switch p.As {
|
switch p.As {
|
||||||
case ARLDC,
|
case ARLDC,
|
||||||
ARLDCCC:
|
ARLDCCC:
|
||||||
|
|
@ -2020,9 +1983,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case 30: /* rldimi $sh,s,$mask,a */
|
case 30: /* rldimi $sh,s,$mask,a */
|
||||||
v = regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
|
|
||||||
d = vregoff(ctxt, &p.From3)
|
d := vregoff(ctxt, &p.From3)
|
||||||
|
var mask [2]uint8
|
||||||
maskgen64(ctxt, p, mask[:], uint64(d))
|
maskgen64(ctxt, p, mask[:], uint64(d))
|
||||||
if int32(mask[1]) != (63 - v) {
|
if int32(mask[1]) != (63 - v) {
|
||||||
ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p)
|
ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p)
|
||||||
|
|
@ -2037,7 +2001,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case 31: /* dword */
|
case 31: /* dword */
|
||||||
d = vregoff(ctxt, &p.From)
|
d := vregoff(ctxt, &p.From)
|
||||||
|
|
||||||
if ctxt.Arch.ByteOrder == binary.BigEndian {
|
if ctxt.Arch.ByteOrder == binary.BigEndian {
|
||||||
o1 = uint32(d >> 32)
|
o1 = uint32(d >> 32)
|
||||||
|
|
@ -2048,7 +2012,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.From.Sym != nil {
|
if p.From.Sym != nil {
|
||||||
rel = obj.Addrel(ctxt.Cursym)
|
rel := obj.Addrel(ctxt.Cursym)
|
||||||
rel.Off = int32(ctxt.Pc)
|
rel.Off = int32(ctxt.Pc)
|
||||||
rel.Siz = 8
|
rel.Siz = 8
|
||||||
rel.Sym = p.From.Sym
|
rel.Sym = p.From.Sym
|
||||||
|
|
@ -2059,7 +2023,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case 32: /* fmul frc,fra,frd */
|
case 32: /* fmul frc,fra,frd */
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
|
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
|
|
@ -2067,7 +2031,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0) | (uint32(p.From.Reg)&31)<<6
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0) | (uint32(p.From.Reg)&31)<<6
|
||||||
|
|
||||||
case 33: /* fabs [frb,]frd; fmr. frb,frd */
|
case 33: /* fabs [frb,]frd; fmr. frb,frd */
|
||||||
r = int(p.From.Reg)
|
r := int(p.From.Reg)
|
||||||
|
|
||||||
if oclass(&p.From) == C_NONE {
|
if oclass(&p.From) == C_NONE {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
|
|
@ -2078,9 +2042,9 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)) | (uint32(p.From3.Reg)&31)<<6
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)) | (uint32(p.From3.Reg)&31)<<6
|
||||||
|
|
||||||
case 35: /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */
|
case 35: /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */
|
||||||
v = regoff(ctxt, &p.To)
|
v := regoff(ctxt, &p.To)
|
||||||
|
|
||||||
r = int(p.To.Reg)
|
r := int(p.To.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
|
|
@ -2088,9 +2052,9 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o2 = AOP_IRR(uint32(opstore(ctxt, int(p.As))), uint32(p.From.Reg), REGTMP, uint32(v))
|
o2 = AOP_IRR(uint32(opstore(ctxt, int(p.As))), uint32(p.From.Reg), REGTMP, uint32(v))
|
||||||
|
|
||||||
case 36: /* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */
|
case 36: /* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */
|
||||||
v = regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
|
|
||||||
r = int(p.From.Reg)
|
r := int(p.From.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
|
|
@ -2098,9 +2062,9 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o2 = AOP_IRR(uint32(opload(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(v))
|
o2 = AOP_IRR(uint32(opload(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(v))
|
||||||
|
|
||||||
case 37: /* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */
|
case 37: /* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */
|
||||||
v = regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
|
|
||||||
r = int(p.From.Reg)
|
r := int(p.From.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(o.param)
|
r = int(o.param)
|
||||||
}
|
}
|
||||||
|
|
@ -2118,7 +2082,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(regoff(ctxt, &p.From3))&0x7F)<<11
|
o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(regoff(ctxt, &p.From3))&0x7F)<<11
|
||||||
|
|
||||||
case 43: /* unary indexed source: dcbf (b); dcbf (a+b) */
|
case 43: /* unary indexed source: dcbf (b); dcbf (a+b) */
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
|
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = 0
|
r = 0
|
||||||
|
|
@ -2126,7 +2090,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, uint32(r), uint32(p.From.Reg))
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, uint32(r), uint32(p.From.Reg))
|
||||||
|
|
||||||
case 44: /* indexed store */
|
case 44: /* indexed store */
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
|
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = 0
|
r = 0
|
||||||
|
|
@ -2134,7 +2098,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = AOP_RRR(uint32(opstorex(ctxt, int(p.As))), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg))
|
o1 = AOP_RRR(uint32(opstorex(ctxt, int(p.As))), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg))
|
||||||
|
|
||||||
case 45: /* indexed load */
|
case 45: /* indexed load */
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
|
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = 0
|
r = 0
|
||||||
|
|
@ -2145,7 +2109,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = uint32(oprrr(ctxt, int(p.As)))
|
o1 = uint32(oprrr(ctxt, int(p.As)))
|
||||||
|
|
||||||
case 47: /* op Ra, Rd; also op [Ra,] Rd */
|
case 47: /* op Ra, Rd; also op [Ra,] Rd */
|
||||||
r = int(p.From.Reg)
|
r := int(p.From.Reg)
|
||||||
|
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
|
|
@ -2153,7 +2117,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0)
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0)
|
||||||
|
|
||||||
case 48: /* op Rs, Ra */
|
case 48: /* op Rs, Ra */
|
||||||
r = int(p.From.Reg)
|
r := int(p.From.Reg)
|
||||||
|
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
|
|
@ -2162,20 +2126,20 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
|
|
||||||
case 49: /* op Rb; op $n, Rb */
|
case 49: /* op Rb; op $n, Rb */
|
||||||
if p.From.Type != obj.TYPE_REG { /* tlbie $L, rB */
|
if p.From.Type != obj.TYPE_REG { /* tlbie $L, rB */
|
||||||
v = regoff(ctxt, &p.From) & 1
|
v := regoff(ctxt, &p.From) & 1
|
||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, 0, uint32(p.To.Reg)) | uint32(v)<<21
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, 0, uint32(p.To.Reg)) | uint32(v)<<21
|
||||||
} else {
|
} else {
|
||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, 0, uint32(p.From.Reg))
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, 0, uint32(p.From.Reg))
|
||||||
}
|
}
|
||||||
|
|
||||||
case 50: /* rem[u] r1[,r2],r3 */
|
case 50: /* rem[u] r1[,r2],r3 */
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
|
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
v = oprrr(ctxt, int(p.As))
|
v := oprrr(ctxt, int(p.As))
|
||||||
t = v & (1<<10 | 1) /* OE|Rc */
|
t := v & (1<<10 | 1) /* OE|Rc */
|
||||||
o1 = AOP_RRR(uint32(v)&^uint32(t), REGTMP, uint32(r), uint32(p.From.Reg))
|
o1 = AOP_RRR(uint32(v)&^uint32(t), REGTMP, uint32(r), uint32(p.From.Reg))
|
||||||
o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, uint32(p.From.Reg))
|
o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, uint32(p.From.Reg))
|
||||||
o3 = AOP_RRR(OP_SUBF|uint32(t), uint32(p.To.Reg), REGTMP, uint32(r))
|
o3 = AOP_RRR(OP_SUBF|uint32(t), uint32(p.To.Reg), REGTMP, uint32(r))
|
||||||
|
|
@ -2187,19 +2151,19 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case 51: /* remd[u] r1[,r2],r3 */
|
case 51: /* remd[u] r1[,r2],r3 */
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
|
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
v = oprrr(ctxt, int(p.As))
|
v := oprrr(ctxt, int(p.As))
|
||||||
t = v & (1<<10 | 1) /* OE|Rc */
|
t := v & (1<<10 | 1) /* OE|Rc */
|
||||||
o1 = AOP_RRR(uint32(v)&^uint32(t), REGTMP, uint32(r), uint32(p.From.Reg))
|
o1 = AOP_RRR(uint32(v)&^uint32(t), REGTMP, uint32(r), uint32(p.From.Reg))
|
||||||
o2 = AOP_RRR(OP_MULLD, REGTMP, REGTMP, uint32(p.From.Reg))
|
o2 = AOP_RRR(OP_MULLD, REGTMP, REGTMP, uint32(p.From.Reg))
|
||||||
o3 = AOP_RRR(OP_SUBF|uint32(t), uint32(p.To.Reg), REGTMP, uint32(r))
|
o3 = AOP_RRR(OP_SUBF|uint32(t), uint32(p.To.Reg), REGTMP, uint32(r))
|
||||||
|
|
||||||
case 52: /* mtfsbNx cr(n) */
|
case 52: /* mtfsbNx cr(n) */
|
||||||
v = regoff(ctxt, &p.From) & 31
|
v := regoff(ctxt, &p.From) & 31
|
||||||
|
|
||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(v), 0, 0)
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(v), 0, 0)
|
||||||
|
|
||||||
|
|
@ -2221,9 +2185,9 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), 0, uint32(p.From.Reg))
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), 0, uint32(p.From.Reg))
|
||||||
|
|
||||||
case 56: /* sra $sh,[s,]a; srd $sh,[s,]a */
|
case 56: /* sra $sh,[s,]a; srd $sh,[s,]a */
|
||||||
v = regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
|
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
|
|
@ -2233,9 +2197,9 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case 57: /* slw $sh,[s,]a -> rlwinm ... */
|
case 57: /* slw $sh,[s,]a -> rlwinm ... */
|
||||||
v = regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
|
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
|
|
@ -2252,6 +2216,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
} else if v > 32 {
|
} else if v > 32 {
|
||||||
v = 32
|
v = 32
|
||||||
}
|
}
|
||||||
|
var mask [2]uint8
|
||||||
if p.As == ASRW || p.As == ASRWCC { /* shift right */
|
if p.As == ASRW || p.As == ASRWCC { /* shift right */
|
||||||
mask[0] = uint8(v)
|
mask[0] = uint8(v)
|
||||||
mask[1] = 31
|
mask[1] = 31
|
||||||
|
|
@ -2267,48 +2232,51 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case 58: /* logical $andcon,[s],a */
|
case 58: /* logical $andcon,[s],a */
|
||||||
v = regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
|
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
o1 = LOP_IRR(uint32(opirr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(v))
|
o1 = LOP_IRR(uint32(opirr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(v))
|
||||||
|
|
||||||
case 59: /* or/and $ucon,,r */
|
case 59: /* or/and $ucon,,r */
|
||||||
v = regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
|
|
||||||
r = int(p.Reg)
|
r := int(p.Reg)
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
r = int(p.To.Reg)
|
r = int(p.To.Reg)
|
||||||
}
|
}
|
||||||
o1 = LOP_IRR(uint32(opirr(ctxt, int(p.As)+ALAST)), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis */
|
o1 = LOP_IRR(uint32(opirr(ctxt, int(p.As)+ALAST)), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis */
|
||||||
|
|
||||||
case 60: /* tw to,a,b */
|
case 60: /* tw to,a,b */
|
||||||
r = int(regoff(ctxt, &p.From) & 31)
|
r := int(regoff(ctxt, &p.From) & 31)
|
||||||
|
|
||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(r), uint32(p.Reg), uint32(p.To.Reg))
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(r), uint32(p.Reg), uint32(p.To.Reg))
|
||||||
|
|
||||||
case 61: /* tw to,a,$simm */
|
case 61: /* tw to,a,$simm */
|
||||||
r = int(regoff(ctxt, &p.From) & 31)
|
r := int(regoff(ctxt, &p.From) & 31)
|
||||||
|
|
||||||
v = regoff(ctxt, &p.To)
|
v := regoff(ctxt, &p.To)
|
||||||
o1 = AOP_IRR(uint32(opirr(ctxt, int(p.As))), uint32(r), uint32(p.Reg), uint32(v))
|
o1 = AOP_IRR(uint32(opirr(ctxt, int(p.As))), uint32(r), uint32(p.Reg), uint32(v))
|
||||||
|
|
||||||
case 62: /* rlwmi $sh,s,$mask,a */
|
case 62: /* rlwmi $sh,s,$mask,a */
|
||||||
v = regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
|
|
||||||
|
var mask [2]uint8
|
||||||
maskgen(ctxt, p, mask[:], uint32(regoff(ctxt, &p.From3)))
|
maskgen(ctxt, p, mask[:], uint32(regoff(ctxt, &p.From3)))
|
||||||
o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(p.Reg), uint32(p.To.Reg), uint32(v))
|
o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(p.Reg), uint32(p.To.Reg), uint32(v))
|
||||||
o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
|
o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
|
||||||
|
|
||||||
case 63: /* rlwmi b,s,$mask,a */
|
case 63: /* rlwmi b,s,$mask,a */
|
||||||
|
var mask [2]uint8
|
||||||
maskgen(ctxt, p, mask[:], uint32(regoff(ctxt, &p.From3)))
|
maskgen(ctxt, p, mask[:], uint32(regoff(ctxt, &p.From3)))
|
||||||
|
|
||||||
o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(p.Reg), uint32(p.To.Reg), uint32(p.From.Reg))
|
o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(p.Reg), uint32(p.To.Reg), uint32(p.From.Reg))
|
||||||
o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
|
o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
|
||||||
|
|
||||||
case 64: /* mtfsf fr[, $m] {,fpcsr} */
|
case 64: /* mtfsf fr[, $m] {,fpcsr} */
|
||||||
|
var v int32
|
||||||
if p.From3.Type != obj.TYPE_NONE {
|
if p.From3.Type != obj.TYPE_NONE {
|
||||||
v = regoff(ctxt, &p.From3) & 255
|
v = regoff(ctxt, &p.From3) & 255
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2323,6 +2291,8 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = OP_MTFSFI | (uint32(p.To.Reg)&15)<<23 | (uint32(regoff(ctxt, &p.From))&31)<<12
|
o1 = OP_MTFSFI | (uint32(p.To.Reg)&15)<<23 | (uint32(regoff(ctxt, &p.From))&31)<<12
|
||||||
|
|
||||||
case 66: /* mov spr,r1; mov r1,spr, also dcr */
|
case 66: /* mov spr,r1; mov r1,spr, also dcr */
|
||||||
|
var r int
|
||||||
|
var v int32
|
||||||
if REG_R0 <= p.From.Reg && p.From.Reg <= REG_R31 {
|
if REG_R0 <= p.From.Reg && p.From.Reg <= REG_R31 {
|
||||||
r = int(p.From.Reg)
|
r = int(p.From.Reg)
|
||||||
v = int32(p.To.Reg)
|
v = int32(p.To.Reg)
|
||||||
|
|
@ -2351,13 +2321,14 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
|
|
||||||
case 68: /* mfcr rD; mfocrf CRM,rD */
|
case 68: /* mfcr rD; mfocrf CRM,rD */
|
||||||
if p.From.Type == obj.TYPE_REG && REG_CR0 <= p.From.Reg && p.From.Reg <= REG_CR7 {
|
if p.From.Type == obj.TYPE_REG && REG_CR0 <= p.From.Reg && p.From.Reg <= REG_CR7 {
|
||||||
v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */
|
v := int32(1 << uint(7-(p.To.Reg&7))) /* CR(n) */
|
||||||
o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) | 1<<20 | uint32(v)<<12 /* new form, mfocrf */
|
o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) | 1<<20 | uint32(v)<<12 /* new form, mfocrf */
|
||||||
} else {
|
} else {
|
||||||
o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /* old form, whole register */
|
o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /* old form, whole register */
|
||||||
}
|
}
|
||||||
|
|
||||||
case 69: /* mtcrf CRM,rS */
|
case 69: /* mtcrf CRM,rS */
|
||||||
|
var v int32
|
||||||
if p.From3.Type != obj.TYPE_NONE {
|
if p.From3.Type != obj.TYPE_NONE {
|
||||||
if p.To.Reg != 0 {
|
if p.To.Reg != 0 {
|
||||||
ctxt.Diag("can't use both mask and CR(n)\n%v", p)
|
ctxt.Diag("can't use both mask and CR(n)\n%v", p)
|
||||||
|
|
@ -2374,6 +2345,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = AOP_RRR(OP_MTCRF, uint32(p.From.Reg), 0, 0) | uint32(v)<<12
|
o1 = AOP_RRR(OP_MTCRF, uint32(p.From.Reg), 0, 0) | uint32(v)<<12
|
||||||
|
|
||||||
case 70: /* [f]cmp r,r,cr*/
|
case 70: /* [f]cmp r,r,cr*/
|
||||||
|
var r int
|
||||||
if p.Reg == 0 {
|
if p.Reg == 0 {
|
||||||
r = 0
|
r = 0
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2382,6 +2354,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg))
|
o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg))
|
||||||
|
|
||||||
case 71: /* cmp[l] r,i,cr*/
|
case 71: /* cmp[l] r,i,cr*/
|
||||||
|
var r int
|
||||||
if p.Reg == 0 {
|
if p.Reg == 0 {
|
||||||
r = 0
|
r = 0
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2420,7 +2393,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
|
|
||||||
/* relocation operations */
|
/* relocation operations */
|
||||||
case 74:
|
case 74:
|
||||||
v = regoff(ctxt, &p.To)
|
v := regoff(ctxt, &p.To)
|
||||||
|
|
||||||
o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(high16adjusted(v)))
|
o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(high16adjusted(v)))
|
||||||
o2 = AOP_IRR(uint32(opstore(ctxt, int(p.As))), uint32(p.From.Reg), REGTMP, uint32(v))
|
o2 = AOP_IRR(uint32(opstore(ctxt, int(p.As))), uint32(p.From.Reg), REGTMP, uint32(v))
|
||||||
|
|
@ -2429,7 +2402,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
//if(dlm) reloc(&p->to, p->pc, 1);
|
//if(dlm) reloc(&p->to, p->pc, 1);
|
||||||
|
|
||||||
case 75:
|
case 75:
|
||||||
v = regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(high16adjusted(v)))
|
o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(high16adjusted(v)))
|
||||||
o2 = AOP_IRR(uint32(opload(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(v))
|
o2 = AOP_IRR(uint32(opload(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(v))
|
||||||
addaddrreloc(ctxt, p.From.Sym, &o1, &o2)
|
addaddrreloc(ctxt, p.From.Sym, &o1, &o2)
|
||||||
|
|
@ -2437,7 +2410,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||||
//if(dlm) reloc(&p->from, p->pc, 1);
|
//if(dlm) reloc(&p->from, p->pc, 1);
|
||||||
|
|
||||||
case 76:
|
case 76:
|
||||||
v = regoff(ctxt, &p.From)
|
v := regoff(ctxt, &p.From)
|
||||||
o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(high16adjusted(v)))
|
o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(high16adjusted(v)))
|
||||||
o2 = AOP_IRR(uint32(opload(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(v))
|
o2 = AOP_IRR(uint32(opload(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(v))
|
||||||
addaddrreloc(ctxt, p.From.Sym, &o1, &o2)
|
addaddrreloc(ctxt, p.From.Sym, &o1, &o2)
|
||||||
|
|
|
||||||
|
|
@ -54,14 +54,9 @@ const (
|
||||||
var bigP *obj.Prog
|
var bigP *obj.Prog
|
||||||
|
|
||||||
func Pconv(p *obj.Prog) string {
|
func Pconv(p *obj.Prog) string {
|
||||||
var str string
|
a := int(p.As)
|
||||||
var fp string
|
|
||||||
|
|
||||||
var a int
|
str := ""
|
||||||
|
|
||||||
a = int(p.As)
|
|
||||||
|
|
||||||
str = ""
|
|
||||||
if a == obj.ADATA {
|
if a == obj.ADATA {
|
||||||
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v",
|
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v",
|
||||||
p.Pc, p.Line(), Aconv(a), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To))
|
p.Pc, p.Line(), Aconv(a), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To))
|
||||||
|
|
@ -107,23 +102,23 @@ func Pconv(p *obj.Prog) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.Spadj != 0 {
|
if p.Spadj != 0 {
|
||||||
|
var fp string
|
||||||
fp += fmt.Sprintf("%s # spadj=%d", str, p.Spadj)
|
fp += fmt.Sprintf("%s # spadj=%d", str, p.Spadj)
|
||||||
return fp
|
return fp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var fp string
|
||||||
fp += str
|
fp += str
|
||||||
return fp
|
return fp
|
||||||
}
|
}
|
||||||
|
|
||||||
func Aconv(a int) string {
|
func Aconv(a int) string {
|
||||||
var s string
|
s := "???"
|
||||||
var fp string
|
|
||||||
|
|
||||||
s = "???"
|
|
||||||
if a >= obj.AXXX && a < ALAST {
|
if a >= obj.AXXX && a < ALAST {
|
||||||
s = Anames[a]
|
s = Anames[a]
|
||||||
}
|
}
|
||||||
|
var fp string
|
||||||
fp += s
|
fp += s
|
||||||
return fp
|
return fp
|
||||||
}
|
}
|
||||||
|
|
@ -177,13 +172,11 @@ func Rconv(r int) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func DRconv(a int) string {
|
func DRconv(a int) string {
|
||||||
var s string
|
s := "C_??"
|
||||||
var fp string
|
|
||||||
|
|
||||||
s = "C_??"
|
|
||||||
if a >= C_NONE && a <= C_NCLASS {
|
if a >= C_NONE && a <= C_NCLASS {
|
||||||
s = cnames9[a]
|
s = cnames9[a]
|
||||||
}
|
}
|
||||||
|
var fp string
|
||||||
fp += s
|
fp += s
|
||||||
return fp
|
return fp
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func progedit(ctxt *obj.Link, p *obj.Prog) {
|
func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||||
var literal string
|
|
||||||
var s *obj.LSym
|
|
||||||
|
|
||||||
p.From.Class = 0
|
p.From.Class = 0
|
||||||
p.To.Class = 0
|
p.To.Class = 0
|
||||||
|
|
||||||
|
|
@ -59,12 +56,10 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||||
switch p.As {
|
switch p.As {
|
||||||
case AFMOVS:
|
case AFMOVS:
|
||||||
if p.From.Type == obj.TYPE_FCONST {
|
if p.From.Type == obj.TYPE_FCONST {
|
||||||
var i32 uint32
|
f32 := float32(p.From.U.Dval)
|
||||||
var f32 float32
|
i32 := math.Float32bits(f32)
|
||||||
f32 = float32(p.From.U.Dval)
|
literal := fmt.Sprintf("$f32.%08x", i32)
|
||||||
i32 = math.Float32bits(f32)
|
s := obj.Linklookup(ctxt, literal, 0)
|
||||||
literal = fmt.Sprintf("$f32.%08x", i32)
|
|
||||||
s = obj.Linklookup(ctxt, literal, 0)
|
|
||||||
s.Size = 4
|
s.Size = 4
|
||||||
p.From.Type = obj.TYPE_MEM
|
p.From.Type = obj.TYPE_MEM
|
||||||
p.From.Sym = s
|
p.From.Sym = s
|
||||||
|
|
@ -74,10 +69,9 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||||
|
|
||||||
case AFMOVD:
|
case AFMOVD:
|
||||||
if p.From.Type == obj.TYPE_FCONST {
|
if p.From.Type == obj.TYPE_FCONST {
|
||||||
var i64 uint64
|
i64 := math.Float64bits(p.From.U.Dval)
|
||||||
i64 = math.Float64bits(p.From.U.Dval)
|
literal := fmt.Sprintf("$f64.%016x", i64)
|
||||||
literal = fmt.Sprintf("$f64.%016x", i64)
|
s := obj.Linklookup(ctxt, literal, 0)
|
||||||
s = obj.Linklookup(ctxt, literal, 0)
|
|
||||||
s.Size = 8
|
s.Size = 8
|
||||||
p.From.Type = obj.TYPE_MEM
|
p.From.Type = obj.TYPE_MEM
|
||||||
p.From.Sym = s
|
p.From.Sym = s
|
||||||
|
|
@ -88,8 +82,8 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||||
// Put >32-bit constants in memory and load them
|
// Put >32-bit constants in memory and load them
|
||||||
case AMOVD:
|
case AMOVD:
|
||||||
if p.From.Type == obj.TYPE_CONST && p.From.Name == obj.NAME_NONE && p.From.Reg == 0 && int64(int32(p.From.Offset)) != p.From.Offset {
|
if p.From.Type == obj.TYPE_CONST && p.From.Name == obj.NAME_NONE && p.From.Reg == 0 && int64(int32(p.From.Offset)) != p.From.Offset {
|
||||||
literal = fmt.Sprintf("$i64.%016x", uint64(p.From.Offset))
|
literal := fmt.Sprintf("$i64.%016x", uint64(p.From.Offset))
|
||||||
s = obj.Linklookup(ctxt, literal, 0)
|
s := obj.Linklookup(ctxt, literal, 0)
|
||||||
s.Size = 8
|
s.Size = 8
|
||||||
p.From.Type = obj.TYPE_MEM
|
p.From.Type = obj.TYPE_MEM
|
||||||
p.From.Sym = s
|
p.From.Sym = s
|
||||||
|
|
@ -121,17 +115,6 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
var p *obj.Prog
|
|
||||||
var q *obj.Prog
|
|
||||||
var p1 *obj.Prog
|
|
||||||
var p2 *obj.Prog
|
|
||||||
var q1 *obj.Prog
|
|
||||||
var o int
|
|
||||||
var mov int
|
|
||||||
var aoffset int
|
|
||||||
var textstksiz int64
|
|
||||||
var autosize int32
|
|
||||||
|
|
||||||
if ctxt.Symmorestack[0] == nil {
|
if ctxt.Symmorestack[0] == nil {
|
||||||
ctxt.Symmorestack[0] = obj.Linklookup(ctxt, "runtime.morestack", 0)
|
ctxt.Symmorestack[0] = obj.Linklookup(ctxt, "runtime.morestack", 0)
|
||||||
ctxt.Symmorestack[1] = obj.Linklookup(ctxt, "runtime.morestack_noctxt", 0)
|
ctxt.Symmorestack[1] = obj.Linklookup(ctxt, "runtime.morestack_noctxt", 0)
|
||||||
|
|
@ -144,8 +127,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
p = cursym.Text
|
p := cursym.Text
|
||||||
textstksiz = p.To.Offset
|
textstksiz := p.To.Offset
|
||||||
|
|
||||||
cursym.Args = p.To.U.Argsize
|
cursym.Args = p.To.U.Argsize
|
||||||
cursym.Locals = int32(textstksiz)
|
cursym.Locals = int32(textstksiz)
|
||||||
|
|
@ -161,8 +144,9 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
}
|
}
|
||||||
obj.Bflush(ctxt.Bso)
|
obj.Bflush(ctxt.Bso)
|
||||||
|
|
||||||
q = nil
|
q := (*obj.Prog)(nil)
|
||||||
for p = cursym.Text; p != nil; p = p.Link {
|
var q1 *obj.Prog
|
||||||
|
for p := cursym.Text; p != nil; p = p.Link {
|
||||||
switch p.As {
|
switch p.As {
|
||||||
/* too hard, just leave alone */
|
/* too hard, just leave alone */
|
||||||
case obj.ATEXT:
|
case obj.ATEXT:
|
||||||
|
|
@ -326,8 +310,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
autosize = 0
|
autosize := int32(0)
|
||||||
for p = cursym.Text; p != nil; p = p.Link {
|
var aoffset int
|
||||||
|
var mov int
|
||||||
|
var o int
|
||||||
|
var p1 *obj.Prog
|
||||||
|
var p2 *obj.Prog
|
||||||
|
for p := cursym.Text; p != nil; p = p.Link {
|
||||||
o = int(p.As)
|
o = int(p.As)
|
||||||
switch o {
|
switch o {
|
||||||
case obj.ATEXT:
|
case obj.ATEXT:
|
||||||
|
|
@ -643,9 +632,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt bool) *obj.Prog {
|
func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt bool) *obj.Prog {
|
||||||
var q *obj.Prog
|
|
||||||
var q1 *obj.Prog
|
|
||||||
|
|
||||||
// MOVD g_stackguard(g), R3
|
// MOVD g_stackguard(g), R3
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
|
|
||||||
|
|
@ -659,7 +645,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt bool) *obj.
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REG_R3
|
p.To.Reg = REG_R3
|
||||||
|
|
||||||
q = nil
|
q := (*obj.Prog)(nil)
|
||||||
if framesize <= obj.StackSmall {
|
if framesize <= obj.StackSmall {
|
||||||
// small stack: SP < stackguard
|
// small stack: SP < stackguard
|
||||||
// CMP stackguard, SP
|
// CMP stackguard, SP
|
||||||
|
|
@ -750,7 +736,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt bool) *obj.
|
||||||
|
|
||||||
// q1: BLT done
|
// q1: BLT done
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
q1 = p
|
q1 := p
|
||||||
|
|
||||||
p.As = ABLT
|
p.As = ABLT
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
|
|
@ -795,13 +781,10 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt bool) *obj.
|
||||||
}
|
}
|
||||||
|
|
||||||
func follow(ctxt *obj.Link, s *obj.LSym) {
|
func follow(ctxt *obj.Link, s *obj.LSym) {
|
||||||
var firstp *obj.Prog
|
|
||||||
var lastp *obj.Prog
|
|
||||||
|
|
||||||
ctxt.Cursym = s
|
ctxt.Cursym = s
|
||||||
|
|
||||||
firstp = ctxt.NewProg()
|
firstp := ctxt.NewProg()
|
||||||
lastp = firstp
|
lastp := firstp
|
||||||
xfol(ctxt, s.Text, &lastp)
|
xfol(ctxt, s.Text, &lastp)
|
||||||
lastp.Link = nil
|
lastp.Link = nil
|
||||||
s.Text = firstp.Link
|
s.Text = firstp.Link
|
||||||
|
|
|
||||||
|
|
@ -123,8 +123,6 @@ func Headstr(v int) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Linknew(arch *LinkArch) *Link {
|
func Linknew(arch *LinkArch) *Link {
|
||||||
var buf string
|
|
||||||
|
|
||||||
linksetexp()
|
linksetexp()
|
||||||
|
|
||||||
ctxt := new(Link)
|
ctxt := new(Link)
|
||||||
|
|
@ -137,6 +135,7 @@ func Linknew(arch *LinkArch) *Link {
|
||||||
ctxt.Windows = 1
|
ctxt.Windows = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var buf string
|
||||||
buf, _ = os.Getwd()
|
buf, _ = os.Getwd()
|
||||||
if buf == "" {
|
if buf == "" {
|
||||||
buf = "/???"
|
buf = "/???"
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -55,7 +55,6 @@ var bigP *obj.Prog
|
||||||
|
|
||||||
func Pconv(p *obj.Prog) string {
|
func Pconv(p *obj.Prog) string {
|
||||||
var str string
|
var str string
|
||||||
var fp string
|
|
||||||
|
|
||||||
switch p.As {
|
switch p.As {
|
||||||
case obj.ADATA:
|
case obj.ADATA:
|
||||||
|
|
@ -84,6 +83,7 @@ func Pconv(p *obj.Prog) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var fp string
|
||||||
fp += str
|
fp += str
|
||||||
return fp
|
return fp
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,10 +49,6 @@ func canuselocaltls(ctxt *obj.Link) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func progedit(ctxt *obj.Link, p *obj.Prog) {
|
func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||||
var literal string
|
|
||||||
var s *obj.LSym
|
|
||||||
var q *obj.Prog
|
|
||||||
|
|
||||||
// Thread-local storage references use the TLS pseudo-register.
|
// Thread-local storage references use the TLS pseudo-register.
|
||||||
// As a register, TLS refers to the thread-local storage base, and it
|
// As a register, TLS refers to the thread-local storage base, and it
|
||||||
// can only be loaded into another register:
|
// can only be loaded into another register:
|
||||||
|
|
@ -121,7 +117,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||||
// MOVQ off(BX)(TLS*1), BX
|
// MOVQ off(BX)(TLS*1), BX
|
||||||
// This allows the C compilers to emit references to m and g using the direct off(TLS) form.
|
// This allows the C compilers to emit references to m and g using the direct off(TLS) form.
|
||||||
if (p.As == AMOVQ || p.As == AMOVL) && p.From.Type == obj.TYPE_MEM && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_R15 {
|
if (p.As == AMOVQ || p.As == AMOVL) && p.From.Type == obj.TYPE_MEM && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_R15 {
|
||||||
q = obj.Appendp(ctxt, p)
|
q := obj.Appendp(ctxt, p)
|
||||||
q.As = p.As
|
q.As = p.As
|
||||||
q.From = p.From
|
q.From = p.From
|
||||||
q.From.Type = obj.TYPE_MEM
|
q.From.Type = obj.TYPE_MEM
|
||||||
|
|
@ -214,12 +210,10 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||||
ACOMISS,
|
ACOMISS,
|
||||||
AUCOMISS:
|
AUCOMISS:
|
||||||
if p.From.Type == obj.TYPE_FCONST {
|
if p.From.Type == obj.TYPE_FCONST {
|
||||||
var i32 uint32
|
f32 := float32(p.From.U.Dval)
|
||||||
var f32 float32
|
i32 := math.Float32bits(f32)
|
||||||
f32 = float32(p.From.U.Dval)
|
literal := fmt.Sprintf("$f32.%08x", i32)
|
||||||
i32 = math.Float32bits(f32)
|
s := obj.Linklookup(ctxt, literal, 0)
|
||||||
literal = fmt.Sprintf("$f32.%08x", i32)
|
|
||||||
s = obj.Linklookup(ctxt, literal, 0)
|
|
||||||
if s.Type == 0 {
|
if s.Type == 0 {
|
||||||
s.Type = obj.SRODATA
|
s.Type = obj.SRODATA
|
||||||
obj.Adduint32(ctxt, s, i32)
|
obj.Adduint32(ctxt, s, i32)
|
||||||
|
|
@ -262,10 +256,9 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||||
ACOMISD,
|
ACOMISD,
|
||||||
AUCOMISD:
|
AUCOMISD:
|
||||||
if p.From.Type == obj.TYPE_FCONST {
|
if p.From.Type == obj.TYPE_FCONST {
|
||||||
var i64 uint64
|
i64 := math.Float64bits(p.From.U.Dval)
|
||||||
i64 = math.Float64bits(p.From.U.Dval)
|
literal := fmt.Sprintf("$f64.%016x", i64)
|
||||||
literal = fmt.Sprintf("$f64.%016x", i64)
|
s := obj.Linklookup(ctxt, literal, 0)
|
||||||
s = obj.Linklookup(ctxt, literal, 0)
|
|
||||||
if s.Type == 0 {
|
if s.Type == 0 {
|
||||||
s.Type = obj.SRODATA
|
s.Type = obj.SRODATA
|
||||||
obj.Adduint64(ctxt, s, i64)
|
obj.Adduint64(ctxt, s, i64)
|
||||||
|
|
@ -315,17 +308,6 @@ func nacladdr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
var p *obj.Prog
|
|
||||||
var q *obj.Prog
|
|
||||||
var p1 *obj.Prog
|
|
||||||
var p2 *obj.Prog
|
|
||||||
var autoffset int32
|
|
||||||
var deltasp int32
|
|
||||||
var a int
|
|
||||||
var pcsize int
|
|
||||||
var bpsize int
|
|
||||||
var textarg int64
|
|
||||||
|
|
||||||
if ctxt.Tlsg == nil {
|
if ctxt.Tlsg == nil {
|
||||||
ctxt.Tlsg = obj.Linklookup(ctxt, "runtime.tlsg", 0)
|
ctxt.Tlsg = obj.Linklookup(ctxt, "runtime.tlsg", 0)
|
||||||
}
|
}
|
||||||
|
|
@ -344,12 +326,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
p = cursym.Text
|
p := cursym.Text
|
||||||
autoffset = int32(p.To.Offset)
|
autoffset := int32(p.To.Offset)
|
||||||
if autoffset < 0 {
|
if autoffset < 0 {
|
||||||
autoffset = 0
|
autoffset = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var bpsize int
|
||||||
if obj.Framepointer_enabled != 0 && autoffset > 0 {
|
if obj.Framepointer_enabled != 0 && autoffset > 0 {
|
||||||
// Make room for to save a base pointer. If autoffset == 0,
|
// Make room for to save a base pointer. If autoffset == 0,
|
||||||
// this might do something special like a tail jump to
|
// this might do something special like a tail jump to
|
||||||
|
|
@ -362,12 +345,12 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
bpsize = 0
|
bpsize = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
textarg = int64(p.To.U.Argsize)
|
textarg := int64(p.To.U.Argsize)
|
||||||
cursym.Args = int32(textarg)
|
cursym.Args = int32(textarg)
|
||||||
cursym.Locals = int32(p.To.Offset)
|
cursym.Locals = int32(p.To.Offset)
|
||||||
|
|
||||||
if autoffset < obj.StackSmall && p.From3.Offset&obj.NOSPLIT == 0 {
|
if autoffset < obj.StackSmall && p.From3.Offset&obj.NOSPLIT == 0 {
|
||||||
for q = p; q != nil; q = q.Link {
|
for q := p; q != nil; q = q.Link {
|
||||||
if q.As == obj.ACALL {
|
if q.As == obj.ACALL {
|
||||||
goto noleaf
|
goto noleaf
|
||||||
}
|
}
|
||||||
|
|
@ -380,7 +363,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
noleaf:
|
noleaf:
|
||||||
}
|
}
|
||||||
|
|
||||||
q = nil
|
q := (*obj.Prog)(nil)
|
||||||
if p.From3.Offset&obj.NOSPLIT == 0 || (p.From3.Offset&obj.WRAPPER != 0) {
|
if p.From3.Offset&obj.NOSPLIT == 0 || (p.From3.Offset&obj.WRAPPER != 0) {
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p = load_g_cx(ctxt, p) // load g into CX
|
p = load_g_cx(ctxt, p) // load g into CX
|
||||||
|
|
@ -415,7 +398,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
if q != nil {
|
if q != nil {
|
||||||
q.Pcond = p
|
q.Pcond = p
|
||||||
}
|
}
|
||||||
deltasp = autoffset
|
deltasp := autoffset
|
||||||
|
|
||||||
if bpsize > 0 {
|
if bpsize > 0 {
|
||||||
// Save caller's BP
|
// Save caller's BP
|
||||||
|
|
@ -486,7 +469,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AJEQ
|
p.As = AJEQ
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
p1 = p
|
p1 := p
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = ALEAQ
|
p.As = ALEAQ
|
||||||
|
|
@ -517,7 +500,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AJNE
|
p.As = AJNE
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
p2 = p
|
p2 := p
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = AMOVQ
|
p.As = AMOVQ
|
||||||
|
|
@ -573,6 +556,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||||
p.As = ASTOSQ
|
p.As = ASTOSQ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var a int
|
||||||
|
var pcsize int
|
||||||
for ; p != nil; p = p.Link {
|
for ; p != nil; p = p.Link {
|
||||||
pcsize = int(p.Mode) / 8
|
pcsize = int(p.Mode) / 8
|
||||||
a = int(p.From.Name)
|
a = int(p.From.Name)
|
||||||
|
|
@ -691,8 +676,6 @@ func indir_cx(ctxt *obj.Link, a *obj.Addr) {
|
||||||
// prologue (caller must call appendp first) and in the epilogue.
|
// prologue (caller must call appendp first) and in the epilogue.
|
||||||
// Returns last new instruction.
|
// Returns last new instruction.
|
||||||
func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
|
func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
|
||||||
var next *obj.Prog
|
|
||||||
|
|
||||||
p.As = AMOVQ
|
p.As = AMOVQ
|
||||||
if ctxt.Arch.Ptrsize == 4 {
|
if ctxt.Arch.Ptrsize == 4 {
|
||||||
p.As = AMOVL
|
p.As = AMOVL
|
||||||
|
|
@ -703,7 +686,7 @@ func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REG_CX
|
p.To.Reg = REG_CX
|
||||||
|
|
||||||
next = p.Link
|
next := p.Link
|
||||||
progedit(ctxt, p)
|
progedit(ctxt, p)
|
||||||
for p.Link != next {
|
for p.Link != next {
|
||||||
p = p.Link
|
p = p.Link
|
||||||
|
|
@ -723,17 +706,10 @@ func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
|
||||||
// On return, *jmpok is the instruction that should jump
|
// On return, *jmpok is the instruction that should jump
|
||||||
// to the stack frame allocation if no split is needed.
|
// to the stack frame allocation if no split is needed.
|
||||||
func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, textarg int32, noctxt bool, jmpok **obj.Prog) *obj.Prog {
|
func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, textarg int32, noctxt bool, jmpok **obj.Prog) *obj.Prog {
|
||||||
var q *obj.Prog
|
cmp := ACMPQ
|
||||||
var q1 *obj.Prog
|
lea := ALEAQ
|
||||||
var cmp int
|
mov := AMOVQ
|
||||||
var lea int
|
sub := ASUBQ
|
||||||
var mov int
|
|
||||||
var sub int
|
|
||||||
|
|
||||||
cmp = ACMPQ
|
|
||||||
lea = ALEAQ
|
|
||||||
mov = AMOVQ
|
|
||||||
sub = ASUBQ
|
|
||||||
|
|
||||||
if ctxt.Headtype == obj.Hnacl {
|
if ctxt.Headtype == obj.Hnacl {
|
||||||
cmp = ACMPL
|
cmp = ACMPL
|
||||||
|
|
@ -742,7 +718,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, textarg int32, noc
|
||||||
sub = ASUBL
|
sub = ASUBL
|
||||||
}
|
}
|
||||||
|
|
||||||
q1 = nil
|
q1 := (*obj.Prog)(nil)
|
||||||
if framesize <= obj.StackSmall {
|
if framesize <= obj.StackSmall {
|
||||||
// small stack: SP <= stackguard
|
// small stack: SP <= stackguard
|
||||||
// CMPQ SP, stackguard
|
// CMPQ SP, stackguard
|
||||||
|
|
@ -845,7 +821,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, textarg int32, noc
|
||||||
|
|
||||||
p.As = AJHI
|
p.As = AJHI
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
q = p
|
q := p
|
||||||
|
|
||||||
p = obj.Appendp(ctxt, p)
|
p = obj.Appendp(ctxt, p)
|
||||||
p.As = obj.ACALL
|
p.As = obj.ACALL
|
||||||
|
|
@ -873,13 +849,10 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, textarg int32, noc
|
||||||
}
|
}
|
||||||
|
|
||||||
func follow(ctxt *obj.Link, s *obj.LSym) {
|
func follow(ctxt *obj.Link, s *obj.LSym) {
|
||||||
var firstp *obj.Prog
|
|
||||||
var lastp *obj.Prog
|
|
||||||
|
|
||||||
ctxt.Cursym = s
|
ctxt.Cursym = s
|
||||||
|
|
||||||
firstp = ctxt.NewProg()
|
firstp := ctxt.NewProg()
|
||||||
lastp = firstp
|
lastp := firstp
|
||||||
xfol(ctxt, s.Text, &lastp)
|
xfol(ctxt, s.Text, &lastp)
|
||||||
lastp.Link = nil
|
lastp.Link = nil
|
||||||
s.Text = firstp.Link
|
s.Text = firstp.Link
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue