]> Cypherpunks repositories - gostls13.git/commitdiff
internal/sys: add LR and fixed frame size to sys.Arch
authorAustin Clements <austin@google.com>
Mon, 18 Apr 2022 17:39:52 +0000 (13:39 -0400)
committerAustin Clements <austin@google.com>
Tue, 19 Apr 2022 15:59:19 +0000 (15:59 +0000)
Storing this information in the Arch eliminates some code duplication
between the compiler and linker. This information is entirely
determined by the Arch, so the current approach of attaching it to an
entire Ctxt is a little silly. This will also make it easier to use
this information from tests.

The next CL will be a rote refactoring to eliminate the
Ctxt.FixedFrameSize methods.

Change-Id: I315c524fa66a0ea99f63ae5a2a6fdc367d843bad
Reviewed-on: https://go-review.googlesource.com/c/go/+/400818
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/internal/obj/link.go
src/cmd/internal/sys/arch.go
src/cmd/link/internal/ld/dwarf.go
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ld/link.go

index dc06a3aa11b78c67977384aa76c256a4d75e1385..12a4c94e2496a6907f4c2edb4521afc10a55a103 100644 (file)
@@ -989,16 +989,7 @@ func (fi *FuncInfo) UnspillRegisterArgs(last *Prog, pa ProgAlloc) *Prog {
 // on the stack in the function prologue and so always have a pointer between
 // the hardware stack pointer and the local variable area.
 func (ctxt *Link) FixedFrameSize() int64 {
-       switch ctxt.Arch.Family {
-       case sys.AMD64, sys.I386, sys.Wasm:
-               return 0
-       case sys.PPC64:
-               // PIC code on ppc64le requires 32 bytes of stack, and it's easier to
-               // just use that much stack always on ppc64x.
-               return int64(4 * ctxt.Arch.PtrSize)
-       default:
-               return int64(ctxt.Arch.PtrSize)
-       }
+       return ctxt.Arch.FixedFrameSize
 }
 
 // LinkArch is the definition of a single architecture.
index 84ed35ba8dd5c6560e59698054c2b418fbe1decd..5886b42e5155dedf901baf36d756d0233b35aea5 100644 (file)
@@ -56,6 +56,18 @@ type Arch struct {
        // CanJumpTable reports whether the backend can handle
        // compiling a jump table.
        CanJumpTable bool
+
+       // HasLR indicates that this architecture uses a link register
+       // for calls.
+       HasLR bool
+
+       // FixedFrameSize is the smallest possible offset from the
+       // hardware stack pointer to a local variable on the stack.
+       // Architectures that use a link register save its value on
+       // the stack in the function prologue and so always have a
+       // pointer between the hardware stack pointer and the local
+       // variable area.
+       FixedFrameSize int64
 }
 
 // InFamily reports whether a is a member of any of the specified
@@ -70,103 +82,121 @@ func (a *Arch) InFamily(xs ...ArchFamily) bool {
 }
 
 var Arch386 = &Arch{
-       Name:          "386",
-       Family:        I386,
-       ByteOrder:     binary.LittleEndian,
-       PtrSize:       4,
-       RegSize:       4,
-       MinLC:         1,
-       Alignment:     1,
-       CanMergeLoads: true,
+       Name:           "386",
+       Family:         I386,
+       ByteOrder:      binary.LittleEndian,
+       PtrSize:        4,
+       RegSize:        4,
+       MinLC:          1,
+       Alignment:      1,
+       CanMergeLoads:  true,
+       HasLR:          false,
+       FixedFrameSize: 0,
 }
 
 var ArchAMD64 = &Arch{
-       Name:          "amd64",
-       Family:        AMD64,
-       ByteOrder:     binary.LittleEndian,
-       PtrSize:       8,
-       RegSize:       8,
-       MinLC:         1,
-       Alignment:     1,
-       CanMergeLoads: true,
-       CanJumpTable:  true,
+       Name:           "amd64",
+       Family:         AMD64,
+       ByteOrder:      binary.LittleEndian,
+       PtrSize:        8,
+       RegSize:        8,
+       MinLC:          1,
+       Alignment:      1,
+       CanMergeLoads:  true,
+       CanJumpTable:   true,
+       HasLR:          false,
+       FixedFrameSize: 0,
 }
 
 var ArchARM = &Arch{
-       Name:          "arm",
-       Family:        ARM,
-       ByteOrder:     binary.LittleEndian,
-       PtrSize:       4,
-       RegSize:       4,
-       MinLC:         4,
-       Alignment:     4, // TODO: just for arm5?
-       CanMergeLoads: false,
+       Name:           "arm",
+       Family:         ARM,
+       ByteOrder:      binary.LittleEndian,
+       PtrSize:        4,
+       RegSize:        4,
+       MinLC:          4,
+       Alignment:      4, // TODO: just for arm5?
+       CanMergeLoads:  false,
+       HasLR:          true,
+       FixedFrameSize: 4, // LR
 }
 
 var ArchARM64 = &Arch{
-       Name:          "arm64",
-       Family:        ARM64,
-       ByteOrder:     binary.LittleEndian,
-       PtrSize:       8,
-       RegSize:       8,
-       MinLC:         4,
-       Alignment:     1,
-       CanMergeLoads: true,
+       Name:           "arm64",
+       Family:         ARM64,
+       ByteOrder:      binary.LittleEndian,
+       PtrSize:        8,
+       RegSize:        8,
+       MinLC:          4,
+       Alignment:      1,
+       CanMergeLoads:  true,
+       HasLR:          true,
+       FixedFrameSize: 8, // LR
 }
 
 var ArchLoong64 = &Arch{
-       Name:          "loong64",
-       Family:        Loong64,
-       ByteOrder:     binary.LittleEndian,
-       PtrSize:       8,
-       RegSize:       8,
-       MinLC:         4,
-       Alignment:     8, // Unaligned accesses are not guaranteed to be fast
-       CanMergeLoads: false,
+       Name:           "loong64",
+       Family:         Loong64,
+       ByteOrder:      binary.LittleEndian,
+       PtrSize:        8,
+       RegSize:        8,
+       MinLC:          4,
+       Alignment:      8, // Unaligned accesses are not guaranteed to be fast
+       CanMergeLoads:  false,
+       HasLR:          true,
+       FixedFrameSize: 8, // LR
 }
 
 var ArchMIPS = &Arch{
-       Name:          "mips",
-       Family:        MIPS,
-       ByteOrder:     binary.BigEndian,
-       PtrSize:       4,
-       RegSize:       4,
-       MinLC:         4,
-       Alignment:     4,
-       CanMergeLoads: false,
+       Name:           "mips",
+       Family:         MIPS,
+       ByteOrder:      binary.BigEndian,
+       PtrSize:        4,
+       RegSize:        4,
+       MinLC:          4,
+       Alignment:      4,
+       CanMergeLoads:  false,
+       HasLR:          true,
+       FixedFrameSize: 4, // LR
 }
 
 var ArchMIPSLE = &Arch{
-       Name:          "mipsle",
-       Family:        MIPS,
-       ByteOrder:     binary.LittleEndian,
-       PtrSize:       4,
-       RegSize:       4,
-       MinLC:         4,
-       Alignment:     4,
-       CanMergeLoads: false,
+       Name:           "mipsle",
+       Family:         MIPS,
+       ByteOrder:      binary.LittleEndian,
+       PtrSize:        4,
+       RegSize:        4,
+       MinLC:          4,
+       Alignment:      4,
+       CanMergeLoads:  false,
+       HasLR:          true,
+       FixedFrameSize: 4, // LR
 }
 
 var ArchMIPS64 = &Arch{
-       Name:          "mips64",
-       Family:        MIPS64,
-       ByteOrder:     binary.BigEndian,
-       PtrSize:       8,
-       RegSize:       8,
-       MinLC:         4,
-       Alignment:     8,
-       CanMergeLoads: false,
+       Name:           "mips64",
+       Family:         MIPS64,
+       ByteOrder:      binary.BigEndian,
+       PtrSize:        8,
+       RegSize:        8,
+       MinLC:          4,
+       Alignment:      8,
+       CanMergeLoads:  false,
+       HasLR:          true,
+       FixedFrameSize: 8, // LR
 }
 
 var ArchMIPS64LE = &Arch{
-       Name:          "mips64le",
-       Family:        MIPS64,
-       ByteOrder:     binary.LittleEndian,
-       PtrSize:       8,
-       RegSize:       8,
-       MinLC:         4,
-       Alignment:     8,
-       CanMergeLoads: false,
+       Name:           "mips64le",
+       Family:         MIPS64,
+       ByteOrder:      binary.LittleEndian,
+       PtrSize:        8,
+       RegSize:        8,
+       MinLC:          4,
+       Alignment:      8,
+       CanMergeLoads:  false,
+       HasLR:          true,
+       FixedFrameSize: 8, // LR
 }
 
 var ArchPPC64 = &Arch{
@@ -178,50 +208,62 @@ var ArchPPC64 = &Arch{
        MinLC:         4,
        Alignment:     1,
        CanMergeLoads: false,
+       HasLR:         true,
+       // PIC code on ppc64le requires 32 bytes of stack, and it's
+       // easier to just use that much stack always.
+       FixedFrameSize: 4 * 8,
 }
 
 var ArchPPC64LE = &Arch{
-       Name:          "ppc64le",
-       Family:        PPC64,
-       ByteOrder:     binary.LittleEndian,
-       PtrSize:       8,
-       RegSize:       8,
-       MinLC:         4,
-       Alignment:     1,
-       CanMergeLoads: true,
+       Name:           "ppc64le",
+       Family:         PPC64,
+       ByteOrder:      binary.LittleEndian,
+       PtrSize:        8,
+       RegSize:        8,
+       MinLC:          4,
+       Alignment:      1,
+       CanMergeLoads:  true,
+       HasLR:          true,
+       FixedFrameSize: 4 * 8,
 }
 
 var ArchRISCV64 = &Arch{
-       Name:          "riscv64",
-       Family:        RISCV64,
-       ByteOrder:     binary.LittleEndian,
-       PtrSize:       8,
-       RegSize:       8,
-       MinLC:         4,
-       Alignment:     8, // riscv unaligned loads work, but are really slow (trap + simulated by OS)
-       CanMergeLoads: false,
+       Name:           "riscv64",
+       Family:         RISCV64,
+       ByteOrder:      binary.LittleEndian,
+       PtrSize:        8,
+       RegSize:        8,
+       MinLC:          4,
+       Alignment:      8, // riscv unaligned loads work, but are really slow (trap + simulated by OS)
+       CanMergeLoads:  false,
+       HasLR:          true,
+       FixedFrameSize: 8, // LR
 }
 
 var ArchS390X = &Arch{
-       Name:          "s390x",
-       Family:        S390X,
-       ByteOrder:     binary.BigEndian,
-       PtrSize:       8,
-       RegSize:       8,
-       MinLC:         2,
-       Alignment:     1,
-       CanMergeLoads: true,
+       Name:           "s390x",
+       Family:         S390X,
+       ByteOrder:      binary.BigEndian,
+       PtrSize:        8,
+       RegSize:        8,
+       MinLC:          2,
+       Alignment:      1,
+       CanMergeLoads:  true,
+       HasLR:          true,
+       FixedFrameSize: 8, // LR
 }
 
 var ArchWasm = &Arch{
-       Name:          "wasm",
-       Family:        Wasm,
-       ByteOrder:     binary.LittleEndian,
-       PtrSize:       8,
-       RegSize:       8,
-       MinLC:         1,
-       Alignment:     1,
-       CanMergeLoads: false,
+       Name:           "wasm",
+       Family:         Wasm,
+       ByteOrder:      binary.LittleEndian,
+       PtrSize:        8,
+       RegSize:        8,
+       MinLC:          1,
+       Alignment:      1,
+       CanMergeLoads:  false,
+       HasLR:          false,
+       FixedFrameSize: 0,
 }
 
 var Archs = [...]*Arch{
index 2e209d0c6b7dfa090103122cf205630ac6a047ab..6ed9697aec43e9037405eb4bfbc6e9a5d0cf8811 100644 (file)
@@ -1360,7 +1360,7 @@ func (d *dwctxt) writeframes(fs loader.Sym) dwarfSecInfo {
        fsu := d.ldr.MakeSymbolUpdater(fs)
        fsu.SetType(sym.SDWARFSECT)
        isdw64 := isDwarf64(d.linkctxt)
-       haslr := haslinkregister(d.linkctxt)
+       haslr := d.linkctxt.Arch.HasLR
 
        // Length field is 4 bytes on Dwarf32 and 12 bytes on Dwarf64
        lengthFieldSize := int64(4)
index 4295bb8656893eff648f374f6cb336c3cb8903c7..7104a3c8b6b121d9b4fd6f5e3dec513ee5ef9e2c 100644 (file)
@@ -2349,12 +2349,8 @@ type chain struct {
        limit int // limit on entry to sym
 }
 
-func haslinkregister(ctxt *Link) bool {
-       return ctxt.FixedFrameSize() != 0
-}
-
 func callsize(ctxt *Link) int {
-       if haslinkregister(ctxt) {
+       if ctxt.Arch.HasLR {
                return 0
        }
        return ctxt.Arch.RegSize
@@ -2554,7 +2550,7 @@ func (sc *stkChk) print(ch *chain, limit int) {
                }
        } else {
                sc.print(ch.up, ch.limit+callsize(ctxt))
-               if !haslinkregister(ctxt) {
+               if !ctxt.Arch.HasLR {
                        fmt.Printf("\t%d\ton entry to %s\n", ch.limit, name)
                }
        }
index 64d18bd62c0752ec012160f7a818d5a987d4af5f..f1b5f4d223b93d3e2bf180e91fa3d433c2abbdfa 100644 (file)
@@ -33,7 +33,6 @@ package ld
 import (
        "bufio"
        "cmd/internal/objabi"
-       "cmd/internal/sys"
        "cmd/link/internal/loader"
        "cmd/link/internal/sym"
        "debug/elf"
@@ -108,16 +107,7 @@ type cgodata struct {
 // on the stack in the function prologue and so always have a pointer between
 // the hardware stack pointer and the local variable area.
 func (ctxt *Link) FixedFrameSize() int64 {
-       switch ctxt.Arch.Family {
-       case sys.AMD64, sys.I386:
-               return 0
-       case sys.PPC64:
-               // PIC code on ppc64le requires 32 bytes of stack, and it's easier to
-               // just use that much stack always on ppc64x.
-               return int64(4 * ctxt.Arch.PtrSize)
-       default:
-               return int64(ctxt.Arch.PtrSize)
-       }
+       return ctxt.Arch.FixedFrameSize
 }
 
 func (ctxt *Link) Logf(format string, args ...interface{}) {