]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link,cmd/internal/objabi: factor out direct call identification
authorJoel Sing <joel@sing.id.au>
Thu, 19 Sep 2019 17:25:16 +0000 (03:25 +1000)
committerJoel Sing <joel@sing.id.au>
Wed, 6 Nov 2019 17:03:51 +0000 (17:03 +0000)
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>
src/cmd/internal/objabi/reloctype.go
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ld/pcln.go

index 5dc9356fe1786c5e43fa27758af33cb82a6f7fc8..aed7e2a74d7ea968644d4194cefffd1cda791e1e 100644 (file)
@@ -223,16 +223,34 @@ const (
        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()
+}
index f4aa78f45cb7562a9bf22c2244860091a4f807ca..531b23a31f324d0b3f7e4ea8627433cae2b279d2 100644 (file)
@@ -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) {
index 9a72d4ff0d528f1f762f81965bb50c0f63ee4f38..4fafdc0646aa3e5e139eecb3c8afedb65311ddc2 100644 (file)
@@ -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)
                        }
                }
index 8048695b3d7a1309043363e9f32b7912b6f6c8e6..7253aa517bad60b26e7bc4ef31930fe7054a1ca8 100644 (file)
@@ -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 {