@@ -660,13 +660,23 @@ func (d *Defer) EvalScope(thread Thread) (*EvalScope, error) {
660
660
}
661
661
662
662
// The arguments are stored immediately after the defer header struct, i.e.
663
- // addr+sizeof(_defer). Since CFA in go is always the address of the first
664
- // argument, that's what we use for the value of CFA.
665
- // For SP we use CFA minus the size of one pointer because that would be
666
- // the space occupied by pushing the return address on the stack during the
667
- // CALL.
668
- scope .Regs .CFA = (int64 (d .variable .Addr ) + d .variable .RealType .Common ().ByteSize )
669
- scope .Regs .Reg (scope .Regs .SPRegNum ).Uint64Val = uint64 (scope .Regs .CFA - int64 (bi .Arch .PtrSize ()))
663
+ // addr+sizeof(_defer).
664
+
665
+ if ! bi .Arch .usesLR {
666
+ // On architectures that don't have a link register CFA is always the address of the first
667
+ // argument, that's what we use for the value of CFA.
668
+ // For SP we use CFA minus the size of one pointer because that would be
669
+ // the space occupied by pushing the return address on the stack during the
670
+ // CALL.
671
+ scope .Regs .CFA = (int64 (d .variable .Addr ) + d .variable .RealType .Common ().ByteSize )
672
+ scope .Regs .Reg (scope .Regs .SPRegNum ).Uint64Val = uint64 (scope .Regs .CFA - int64 (bi .Arch .PtrSize ()))
673
+ } else {
674
+ // On architectures that have a link register CFA and SP have the same
675
+ // value but the address of the first argument is at CFA+ptrSize so we set
676
+ // CFA to the start of the argument frame minus one pointer size.
677
+ scope .Regs .CFA = int64 (d .variable .Addr ) + d .variable .RealType .Common ().ByteSize - int64 (bi .Arch .PtrSize ())
678
+ scope .Regs .Reg (scope .Regs .SPRegNum ).Uint64Val = uint64 (scope .Regs .CFA )
679
+ }
670
680
671
681
rdr := scope .Fn .cu .image .dwarfReader
672
682
rdr .Seek (scope .Fn .offset )
0 commit comments