mirror of https://github.com/golang/go.git
cmd/link,cmd/internal/objabi: factor out direct call identification
Factor out the direct CALL identification code from objabi.IsDirectJump and use this in two places that have separately maintained lists of reloc types. Provide an objabi.IsDirectCallOrJump function that implements the original behaviour of objabi.IsDirectJump. Change-Id: I48131bae92b2938fd7822110d53df0b4ffb35766 Reviewed-on: https://go-review.googlesource.com/c/go/+/196577 Run-TryBot: Joel Sing <joel@sing.id.au> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
4cb926001c
commit
a2b1dc863f
|
|
@ -223,16 +223,34 @@ const (
|
|||
R_XCOFFREF
|
||||
)
|
||||
|
||||
// IsDirectJump reports whether r is a relocation for a direct jump.
|
||||
// A direct jump is a CALL or JMP instruction that takes the target address
|
||||
// as immediate. The address is embedded into the instruction, possibly
|
||||
// with limited width.
|
||||
// An indirect jump is a CALL or JMP instruction that takes the target address
|
||||
// in register or memory.
|
||||
func (r RelocType) IsDirectJump() bool {
|
||||
// IsDirectCall reports whether r is a relocation for a direct call.
|
||||
// A direct call is a CALL instruction that takes the target address
|
||||
// as an immediate. The address is embedded into the instruction, possibly
|
||||
// with limited width. An indirect call is a CALL instruction that takes
|
||||
// the target address in register or memory.
|
||||
func (r RelocType) IsDirectCall() bool {
|
||||
switch r {
|
||||
case R_CALL, R_CALLARM, R_CALLARM64, R_CALLPOWER, R_CALLMIPS, R_JMPMIPS:
|
||||
case R_CALL, R_CALLARM, R_CALLARM64, R_CALLMIPS, R_CALLPOWER:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsDirectJump reports whether r is a relocation for a direct jump.
|
||||
// A direct jump is a JMP instruction that takes the target address
|
||||
// as an immediate. The address is embedded into the instruction, possibly
|
||||
// with limited width. An indirect jump is a JMP instruction that takes
|
||||
// the target address in register or memory.
|
||||
func (r RelocType) IsDirectJump() bool {
|
||||
switch r {
|
||||
case R_JMPMIPS:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsDirectCallOrJump reports whether r is a relocation for a direct
|
||||
// call or a direct jump.
|
||||
func (r RelocType) IsDirectCallOrJump() bool {
|
||||
return r.IsDirectCall() || r.IsDirectJump()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ func maxSizeTrampolinesPPC64(s *sym.Symbol, isTramp bool) uint64 {
|
|||
n := uint64(0)
|
||||
for ri := range s.R {
|
||||
r := &s.R[ri]
|
||||
if r.Type.IsDirectJump() {
|
||||
if r.Type.IsDirectCallOrJump() {
|
||||
n++
|
||||
}
|
||||
}
|
||||
|
|
@ -93,7 +93,7 @@ func trampoline(ctxt *Link, s *sym.Symbol) {
|
|||
|
||||
for ri := range s.R {
|
||||
r := &s.R[ri]
|
||||
if !r.Type.IsDirectJump() {
|
||||
if !r.Type.IsDirectCallOrJump() {
|
||||
continue
|
||||
}
|
||||
if Symaddr(r.Sym) == 0 && (r.Sym.Type != sym.SDYNIMPORT && r.Sym.Type != sym.SUNDEFEXT) {
|
||||
|
|
|
|||
|
|
@ -2191,9 +2191,8 @@ func stkcheck(ctxt *Link, up *chain, depth int) int {
|
|||
// Process calls in this span.
|
||||
for ; ri < endr && uint32(s.R[ri].Off) < pcsp.NextPC; ri++ {
|
||||
r = &s.R[ri]
|
||||
switch r.Type {
|
||||
// Direct call.
|
||||
case objabi.R_CALL, objabi.R_CALLARM, objabi.R_CALLARM64, objabi.R_CALLPOWER, objabi.R_CALLMIPS:
|
||||
switch {
|
||||
case r.Type.IsDirectCall():
|
||||
ch.limit = int(int32(limit) - pcsp.Value - int32(callsize(ctxt)))
|
||||
ch.sym = r.Sym
|
||||
if stkcheck(ctxt, &ch, depth+1) < 0 {
|
||||
|
|
@ -2204,9 +2203,8 @@ func stkcheck(ctxt *Link, up *chain, depth int) int {
|
|||
// so we have to make sure it can call morestack.
|
||||
// Arrange the data structures to report both calls, so that
|
||||
// if there is an error, stkprint shows all the steps involved.
|
||||
case objabi.R_CALLIND:
|
||||
case r.Type == objabi.R_CALLIND:
|
||||
ch.limit = int(int32(limit) - pcsp.Value - int32(callsize(ctxt)))
|
||||
|
||||
ch.sym = nil
|
||||
ch1.limit = ch.limit - callsize(ctxt) // for morestack in called prologue
|
||||
ch1.up = &ch
|
||||
|
|
@ -2525,7 +2523,7 @@ func (ctxt *Link) callgraph() {
|
|||
if r.Sym == nil {
|
||||
continue
|
||||
}
|
||||
if (r.Type == objabi.R_CALL || r.Type == objabi.R_CALLARM || r.Type == objabi.R_CALLARM64 || r.Type == objabi.R_CALLPOWER || r.Type == objabi.R_CALLMIPS) && r.Sym.Type == sym.STEXT {
|
||||
if r.Type.IsDirectCall() && r.Sym.Type == sym.STEXT {
|
||||
ctxt.Logf("%s calls %s\n", s.Name, r.Sym.Name)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ func (ctxt *Link) pclntab() {
|
|||
// set the resumption point to PC_B.
|
||||
lastWasmAddr = uint32(r.Add)
|
||||
}
|
||||
if r.Type.IsDirectJump() && r.Sym != nil && r.Sym.Name == "runtime.deferreturn" {
|
||||
if r.Type.IsDirectCall() && r.Sym != nil && r.Sym.Name == "runtime.deferreturn" {
|
||||
if ctxt.Arch.Family == sys.Wasm {
|
||||
deferreturn = lastWasmAddr - 1
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Reference in New Issue