提交 ea335b3d 编写于 作者: D Derek Parker

Refactor frame API

上级 7e8d7c56
......@@ -15,7 +15,17 @@ type CommonInformationEntry struct {
InitialInstructions []byte
}
type FrameDescriptionEntries []*FrameDescriptionEntry
type addrange struct {
begin, end uint64
}
func (r *addrange) Cover(addr uint64) bool {
if (addr - r.begin) < r.end {
return true
}
return false
}
// Represents a Frame Descriptor Entry in the
// Dwarf .debug_frame section.
......@@ -26,25 +36,19 @@ type FrameDescriptionEntry struct {
Instructions []byte
}
type addrange struct {
begin, end uint64
func (fde *FrameDescriptionEntry) ReturnAddressOffset(pc uint64) int64 {
frame := executeDwarfProgram(fde, pc)
return frame.cfa.offset
}
func (r *addrange) Cover(addr uint64) bool {
if (addr - r.begin) < r.end {
return true
}
return false
}
type FrameDescriptionEntries []*FrameDescriptionEntry
func (fdes FrameDescriptionEntries) FindReturnAddressOffset(pc uint64) (uint64, error) {
func (fdes FrameDescriptionEntries) FDEForPC(pc uint64) (*FrameDescriptionEntry, error) {
for _, fde := range fdes {
if fde.AddressRange.Cover(pc) {
offset := unwind(fde, pc)
return offset, nil
return fde, nil
}
}
return 0, fmt.Errorf("Could not find return address.")
return nil, fmt.Errorf("Could not find FDE for %#v", pc)
}
......@@ -113,7 +113,7 @@ var fnlookup = map[byte]instruction{
}
// Unwind the stack to find the return address register.
func unwind(fde *FrameDescriptionEntry, pc uint64) uint64 {
func executeDwarfProgram(fde *FrameDescriptionEntry, pc uint64) *FrameContext {
frame := &FrameContext{
address: pc,
cie: fde.CIE,
......@@ -129,7 +129,7 @@ func unwind(fde *FrameDescriptionEntry, pc uint64) uint64 {
dwarfexec(frame, fde.CIE.InitialInstructions)
dwarfexec(frame, fde.Instructions)
return uint64(frame.cfa.offset)
return frame
}
// Execute dwarf instructions.
......
......@@ -82,17 +82,22 @@ func TestFindReturnAddress(t *testing.T) {
t.Fatal(err)
}
fde, err := fdes.FDEForPC(start)
if err != nil {
t.Fatal(err)
}
end, _, err := gsd.LineToPC(testsourcefile, 19)
if err != nil {
t.Fatal(err)
}
ret, err := fdes.FindReturnAddressOffset(start)
ret := fde.ReturnAddressOffset(start)
if err != nil {
t.Fatal(err)
}
addr := regs.Rsp + ret
addr := uint64(int64(regs.Rsp) + ret)
data := make([]byte, 8)
syscall.PtracePeekText(p.Pid, uintptr(addr), data)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册