diff --git a/_fixtures/fncall.go b/_fixtures/fncall.go index f1839ca4..d5e8ef85 100644 --- a/_fixtures/fncall.go +++ b/_fixtures/fncall.go @@ -199,6 +199,15 @@ func (i Issue2698) String() string { return fmt.Sprintf("%d %d %d %d", i.a, i.b, i.c, i.d) } +type Issue3364 struct { + a int + b uint32 +} + +func (i Issue3364) String() string { + return fmt.Sprintf("%d %d", i.a, i.b) +} + func main() { one, two := 1, 2 intslice := []int{1, 2, 3} @@ -222,6 +231,10 @@ func main() { c: 3, d: 4, } + issue3364 := Issue3364{ + a: 1, + b: 2, + } fn2clos := makeclos(pa) fn2glob := call1 @@ -241,5 +254,5 @@ func main() { d.Method() d.Base.Method() x.CallMe() - fmt.Println(one, two, zero, call, call0, call2, callexit, callpanic, callbreak, callstacktrace, stringsJoin, intslice, stringslice, comma, a.VRcvr, a.PRcvr, pa, vable_a, vable_pa, pable_pa, fn2clos, fn2glob, fn2valmeth, fn2ptrmeth, fn2nil, ga, escapeArg, a2, square, intcallpanic, onetwothree, curriedAdd, getAStruct, getAStructPtr, getVRcvrableFromAStruct, getPRcvrableFromAStructPtr, getVRcvrableFromAStructPtr, pa2, noreturncall, str, d, x, x2.CallMe(5), longstrs, regabistacktest, regabistacktest2, issue2698.String(), regabistacktest3, rast3, floatsum, ref) + fmt.Println(one, two, zero, call, call0, call2, callexit, callpanic, callbreak, callstacktrace, stringsJoin, intslice, stringslice, comma, a.VRcvr, a.PRcvr, pa, vable_a, vable_pa, pable_pa, fn2clos, fn2glob, fn2valmeth, fn2ptrmeth, fn2nil, ga, escapeArg, a2, square, intcallpanic, onetwothree, curriedAdd, getAStruct, getAStructPtr, getVRcvrableFromAStruct, getPRcvrableFromAStructPtr, getVRcvrableFromAStructPtr, pa2, noreturncall, str, d, x, x2.CallMe(5), longstrs, regabistacktest, regabistacktest2, issue2698.String(), issue3364.String(), regabistacktest3, rast3, floatsum, ref) } diff --git a/pkg/proc/dwarf_export_test.go b/pkg/proc/dwarf_export_test.go index 191fde56..7add16c7 100644 --- a/pkg/proc/dwarf_export_test.go +++ b/pkg/proc/dwarf_export_test.go @@ -20,7 +20,7 @@ func NewCompositeMemory(p *Target, pieces []op.Piece, base uint64) (*compositeMe dwarfregs := arch.RegistersToDwarfRegisters(0, regs) dwarfregs.ChangeFunc = p.CurrentThread().SetReg - mem, err := newCompositeMemory(p.Memory(), arch, *dwarfregs, pieces) + mem, err := newCompositeMemory(p.Memory(), arch, *dwarfregs, pieces, 0) if mem != nil { mem.base = base } diff --git a/pkg/proc/mem.go b/pkg/proc/mem.go index cb2a35f6..a215d274 100644 --- a/pkg/proc/mem.go +++ b/pkg/proc/mem.go @@ -98,17 +98,17 @@ type compositeMemory struct { // CreateCompositeMemory created a new composite memory type using the provided MemoryReadWriter as the // underlying memory buffer. -func CreateCompositeMemory(mem MemoryReadWriter, arch *Arch, regs op.DwarfRegisters, pieces []op.Piece) (*compositeMemory, error) { +func CreateCompositeMemory(mem MemoryReadWriter, arch *Arch, regs op.DwarfRegisters, pieces []op.Piece, size int64) (*compositeMemory, error) { // This is basically a small wrapper to avoid having to change all callers // of newCompositeMemory since it existed first. - cm, err := newCompositeMemory(mem, arch, regs, pieces) + cm, err := newCompositeMemory(mem, arch, regs, pieces, size) if cm != nil { cm.base = fakeAddressUnresolv } return cm, err } -func newCompositeMemory(mem MemoryReadWriter, arch *Arch, regs op.DwarfRegisters, pieces []op.Piece) (*compositeMemory, error) { +func newCompositeMemory(mem MemoryReadWriter, arch *Arch, regs op.DwarfRegisters, pieces []op.Piece, size int64) (*compositeMemory, error) { cmem := &compositeMemory{realmem: mem, arch: arch, regs: regs, pieces: pieces, data: []byte{}} for i := range pieces { piece := &pieces[i] @@ -147,6 +147,11 @@ func newCompositeMemory(mem MemoryReadWriter, arch *Arch, regs op.DwarfRegisters panic("unsupported piece kind") } } + paddingBytes := int(size) - len(cmem.data) + if paddingBytes > 0 && paddingBytes < arch.ptrSize { + padding := make([]byte, paddingBytes) + cmem.data = append(cmem.data, padding...) + } return cmem, nil } diff --git a/pkg/proc/target.go b/pkg/proc/target.go index 079a99d9..0a773448 100644 --- a/pkg/proc/target.go +++ b/pkg/proc/target.go @@ -454,7 +454,7 @@ func (t *Target) GetBufferedTracepoints() []*UProbeTraceResult { v.Kind = ip.Kind cachedMem := CreateLoadedCachedMemory(ip.Data) - compMem, _ := CreateCompositeMemory(cachedMem, t.BinInfo().Arch, op.DwarfRegisters{}, ip.Pieces) + compMem, _ := CreateCompositeMemory(cachedMem, t.BinInfo().Arch, op.DwarfRegisters{}, ip.Pieces, ip.RealType.Common().ByteSize) v.mem = compMem // Load the value here so that we don't have to export @@ -506,7 +506,7 @@ const ( // This caching is primarily done so that registerized variables don't get a // different address every time they are evaluated, which would be confusing // and leak memory. -func (t *Target) newCompositeMemory(mem MemoryReadWriter, regs op.DwarfRegisters, pieces []op.Piece, descr *locationExpr) (int64, *compositeMemory, error) { +func (t *Target) newCompositeMemory(mem MemoryReadWriter, regs op.DwarfRegisters, pieces []op.Piece, descr *locationExpr, size int64) (int64, *compositeMemory, error) { var key string if regs.CFA != 0 && len(pieces) > 0 { // key is created by concatenating the location expression with the CFA, @@ -521,7 +521,7 @@ func (t *Target) newCompositeMemory(mem MemoryReadWriter, regs op.DwarfRegisters } } - cmem, err := newCompositeMemory(mem, t.BinInfo().Arch, regs, pieces) + cmem, err := newCompositeMemory(mem, t.BinInfo().Arch, regs, pieces, size) if err != nil { return 0, cmem, err } diff --git a/pkg/proc/variables.go b/pkg/proc/variables.go index e04e16fa..65f5040d 100644 --- a/pkg/proc/variables.go +++ b/pkg/proc/variables.go @@ -1198,9 +1198,9 @@ func extractVarInfoFromEntry(tgt *Target, bi *BinaryInfo, image *Image, regs op. if pieces != nil { var cmem *compositeMemory if tgt != nil { - addr, cmem, err = tgt.newCompositeMemory(mem, regs, pieces, descr) + addr, cmem, err = tgt.newCompositeMemory(mem, regs, pieces, descr, t.Common().ByteSize) } else { - cmem, err = newCompositeMemory(mem, bi.Arch, regs, pieces) + cmem, err = newCompositeMemory(mem, bi.Arch, regs, pieces, t.Common().ByteSize) if cmem != nil { cmem.base = fakeAddressUnresolv addr = int64(cmem.base) diff --git a/pkg/proc/variables_test.go b/pkg/proc/variables_test.go index 82c155e4..7cc2dc5e 100644 --- a/pkg/proc/variables_test.go +++ b/pkg/proc/variables_test.go @@ -1267,6 +1267,7 @@ func TestCallFunction(t *testing.T) { {`regabistacktest("one", "two", "three", "four", "five", 4)`, []string{`:string:"onetwo"`, `:string:"twothree"`, `:string:"threefour"`, `:string:"fourfive"`, `:string:"fiveone"`, ":uint8:8"}, nil}, {`regabistacktest2(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)`, []string{":int:3", ":int:5", ":int:7", ":int:9", ":int:11", ":int:13", ":int:15", ":int:17", ":int:19", ":int:11"}, nil}, {`issue2698.String()`, []string{`:string:"1 2 3 4"`}, nil}, + {`issue3364.String()`, []string{`:string:"1 2"`}, nil}, {`regabistacktest3(rast3, 5)`, []string{`:[10]string:[10]string ["onetwo","twothree","threefour","fourfive","fivesix","sixseven","sevenheight","heightnine","nineten","tenone"]`, ":uint8:15"}, nil}, {`floatsum(1, 2)`, []string{":float64:3"}, nil}, }