]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link, runtime, debug/gosym: move pclntab magic to internal/abi
authorIan Lance Taylor <iant@golang.org>
Thu, 13 Nov 2025 21:01:14 +0000 (13:01 -0800)
committerIan Lance Taylor <iant@golang.org>
Thu, 27 Nov 2025 04:06:46 +0000 (20:06 -0800)
Change-Id: I2d3c41b0e61b994d7b04bd16a791fd226dc45269
Reviewed-on: https://go-review.googlesource.com/c/go/+/720302
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/link/internal/ld/pcln.go
src/debug/gosym/pclntab.go
src/internal/abi/symtab.go
src/runtime/symtab.go

index 472fa715c742732b723d8bf2ac91f38bd85016e6..1eb7112e64415548401cab844d5bb27986cb3a06 100644 (file)
@@ -261,7 +261,7 @@ func (state *pclntab) generatePCHeader(ctxt *Link) {
 
                // Write header.
                // Keep in sync with runtime/symtab.go:pcHeader and package debug/gosym.
-               header.SetUint32(ctxt.Arch, 0, 0xfffffff1)
+               header.SetUint32(ctxt.Arch, 0, uint32(abi.CurrentPCLnTabMagic))
                header.SetUint8(ctxt.Arch, 6, uint8(ctxt.Arch.MinLC))
                header.SetUint8(ctxt.Arch, 7, uint8(ctxt.Arch.PtrSize))
                off := header.SetUint(ctxt.Arch, 8, uint64(state.nfunc))
index 1d5498e0376a081ef577255d5ca4cd07686d0b54..da80c8460d5c73a5392a2d439f23d8ade7161c2c 100644 (file)
@@ -11,6 +11,7 @@ package gosym
 import (
        "bytes"
        "encoding/binary"
+       "internal/abi"
        "sort"
        "sync"
 )
@@ -174,13 +175,6 @@ func (t *LineTable) isGo12() bool {
        return t.version >= ver12
 }
 
-const (
-       go12magic  = 0xfffffffb
-       go116magic = 0xfffffffa
-       go118magic = 0xfffffff0
-       go120magic = 0xfffffff1
-)
-
 // uintptr returns the pointer-sized value encoded at b.
 // The pointer size is dictated by the table being read.
 func (t *LineTable) uintptr(b []byte) uint64 {
@@ -220,24 +214,29 @@ func (t *LineTable) parsePclnTab() {
        }
 
        var possibleVersion version
-       leMagic := binary.LittleEndian.Uint32(t.Data)
-       beMagic := binary.BigEndian.Uint32(t.Data)
+
+       // The magic numbers are chosen such that reading the value with
+       // a different endianness does not result in the same value.
+       // That lets us the magic number to determine the endianness.
+       leMagic := abi.PCLnTabMagic(binary.LittleEndian.Uint32(t.Data))
+       beMagic := abi.PCLnTabMagic(binary.BigEndian.Uint32(t.Data))
+
        switch {
-       case leMagic == go12magic:
+       case leMagic == abi.Go12PCLnTabMagic:
                t.binary, possibleVersion = binary.LittleEndian, ver12
-       case beMagic == go12magic:
+       case beMagic == abi.Go12PCLnTabMagic:
                t.binary, possibleVersion = binary.BigEndian, ver12
-       case leMagic == go116magic:
+       case leMagic == abi.Go116PCLnTabMagic:
                t.binary, possibleVersion = binary.LittleEndian, ver116
-       case beMagic == go116magic:
+       case beMagic == abi.Go116PCLnTabMagic:
                t.binary, possibleVersion = binary.BigEndian, ver116
-       case leMagic == go118magic:
+       case leMagic == abi.Go118PCLnTabMagic:
                t.binary, possibleVersion = binary.LittleEndian, ver118
-       case beMagic == go118magic:
+       case beMagic == abi.Go118PCLnTabMagic:
                t.binary, possibleVersion = binary.BigEndian, ver118
-       case leMagic == go120magic:
+       case leMagic == abi.Go120PCLnTabMagic:
                t.binary, possibleVersion = binary.LittleEndian, ver120
-       case beMagic == go120magic:
+       case beMagic == abi.Go120PCLnTabMagic:
                t.binary, possibleVersion = binary.BigEndian, ver120
        default:
                return
index 86d67003886fedbbb9fa874015302ef0176d41e2..10033e72779eb6d21b6a45fb7cbd468932f61210 100644 (file)
@@ -4,6 +4,36 @@
 
 package abi
 
+// PCLnTabMagic is the version at the start of the PC/line table.
+// This is the start of the .pclntab section, and is also runtime.pcHeader.
+// The magic numbers are chosen such that reading the value with
+// a different endianness does not result in the same value.
+// That lets us the magic number to determine the endianness.
+type PCLnTabMagic uint32
+
+const (
+       // Initial PCLnTabMagic value used in Go 1.2 through Go 1.15.
+       Go12PCLnTabMagic PCLnTabMagic = 0xfffffffb
+       // PCLnTabMagic value used in Go 1.16 through Go 1.17.
+       // Several fields added to header (CL 241598).
+       Go116PCLnTabMagic PCLnTabMagic = 0xfffffffa
+       // PCLnTabMagic value used in Go 1.18 through Go 1.19.
+       // Entry PC of func data changed from address to offset (CL 351463).
+       Go118PCLnTabMagic PCLnTabMagic = 0xfffffff0
+       // PCLnTabMagic value used in Go 1.20 and later.
+       // A ":" was added to generated symbol names (#37762).
+       Go120PCLnTabMagic PCLnTabMagic = 0xfffffff1
+
+       // CurrentPCLnTabMagic is the value emitted by the current toolchain.
+       // This is written by the linker to the pcHeader and read by the
+       // runtime and debug/gosym (and external tools like Delve).
+       //
+       // Change this value when updating the pclntab version.
+       // Changing this exported value is OK because is an
+       // internal package.
+       CurrentPCLnTabMagic = Go120PCLnTabMagic
+)
+
 // A FuncFlag records bits about a function, passed to the runtime.
 type FuncFlag uint8
 
index 3a814cd2032ea1c8e138ce74ff61fc0ab1c89e47..c1643c1b39615889648eed6715427ff91ac7338a 100644 (file)
@@ -374,12 +374,12 @@ func (f *_func) funcInfo() funcInfo {
 
 // pcHeader holds data used by the pclntab lookups.
 type pcHeader struct {
-       magic      uint32 // 0xFFFFFFF1
-       pad1, pad2 uint8  // 0,0
-       minLC      uint8  // min instruction size
-       ptrSize    uint8  // size of a ptr in bytes
-       nfunc      int    // number of functions in the module
-       nfiles     uint   // number of entries in the file tab
+       magic      abi.PCLnTabMagic // abi.Go1NNPcLnTabMagic
+       pad1, pad2 uint8            // 0,0
+       minLC      uint8            // min instruction size
+       ptrSize    uint8            // size of a ptr in bytes
+       nfunc      int              // number of functions in the module
+       nfiles     uint             // number of entries in the file tab
 
        // The next field used to be textStart. This is no longer stored
        // as it requires a relocation. Code should use the moduledata text
@@ -623,7 +623,7 @@ const debugPcln = false
 func moduledataverify1(datap *moduledata) {
        // Check that the pclntab's format is valid.
        hdr := datap.pcHeader
-       if hdr.magic != 0xfffffff1 || hdr.pad1 != 0 || hdr.pad2 != 0 ||
+       if hdr.magic != abi.CurrentPCLnTabMagic || hdr.pad1 != 0 || hdr.pad2 != 0 ||
                hdr.minLC != sys.PCQuantum || hdr.ptrSize != goarch.PtrSize {
                println("runtime: pcHeader: magic=", hex(hdr.magic), "pad1=", hdr.pad1, "pad2=", hdr.pad2,
                        "minLC=", hdr.minLC, "ptrSize=", hdr.ptrSize, "pluginpath=", datap.pluginpath)