R_XCOFFREF
)
+// 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_CALLMIPS, R_CALLPOWER:
+ return true
+ }
+ return false
+}
+
// 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.
+// 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_CALL, R_CALLARM, R_CALLARM64, R_CALLPOWER, R_CALLMIPS, R_JMPMIPS:
+ 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()
+}
n := uint64(0)
for ri := range s.R {
r := &s.R[ri]
- if r.Type.IsDirectJump() {
+ if r.Type.IsDirectCallOrJump() {
n++
}
}
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) {
// 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 {
// 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
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)
}
}
// 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 {