From 94d42069efea64813970ec406e317fa1d9b42d5b Mon Sep 17 00:00:00 2001 From: liuqiang Date: Wed, 13 May 2026 12:00:01 +0800 Subject: [PATCH] fix(loader): encode initial pcdata safe value --- loader/pcdata.go | 4 +++- loader/pcdata_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 loader/pcdata_test.go diff --git a/loader/pcdata.go b/loader/pcdata.go index efab4dac3..581b47c3f 100644 --- a/loader/pcdata.go +++ b/loader/pcdata.go @@ -71,13 +71,14 @@ func (self Pcdata) MarshalBinary() (data []byte, err error) { sv := int32(_PCDATA_START_VAL) sp := uint32(0) buf := make([]byte, binary.MaxVarintLen32) + started := false for _, v := range self { if v.PC < sp { panic("PC must be in ascending order!") } dp := uint64(v.PC - sp) dv := int64(v.Val - sv) - if dv == 0 || dp == 0 { + if dp == 0 || (dv == 0 && started) { continue } n := binary.PutVarint(buf, dv) @@ -86,6 +87,7 @@ func (self Pcdata) MarshalBinary() (data []byte, err error) { data = append(data, buf[:n2]...) sp = v.PC sv = v.Val + started = true } // put 0 to indicate ends data = append(data, 0) diff --git a/loader/pcdata_test.go b/loader/pcdata_test.go new file mode 100644 index 000000000..9813444cb --- /dev/null +++ b/loader/pcdata_test.go @@ -0,0 +1,42 @@ +package loader + +import ( + "bytes" + "testing" +) + +func TestPcdataMarshalBinarySingleSafeEntry(t *testing.T) { + data, err := (Pcdata{{PC: 32, Val: PCDATA_UnsafePointSafe}}).MarshalBinary() + if err != nil { + t.Fatal(err) + } + + want := []byte{0, 32, 0} + if !bytes.Equal(data, want) { + t.Fatalf("unexpected encoded table: got %x want %x", data, want) + } +} + +func TestPcdataMarshalBinarySingleUnsafeEntry(t *testing.T) { + data, err := (Pcdata{{PC: 32, Val: PCDATA_UnsafePointUnsafe}}).MarshalBinary() + if err != nil { + t.Fatal(err) + } + + want := []byte{1, 32, 0} + if !bytes.Equal(data, want) { + t.Fatalf("unexpected encoded table: got %x want %x", data, want) + } +} + +func TestBuildLoadFuncNoPreemptEncodesSafeUnsafePoint(t *testing.T) { + fn := buildLoadFunc(false, LoadOneItem{FuncName: "spin"}, 32, 0) + + data, err := fn.PcUnsafePoint.MarshalBinary() + if err != nil { + t.Fatal(err) + } + if len(data) <= 1 { + t.Fatalf("encoded unsafe-point table has no entries: %x", data) + } +}