delve/dwarf/frame/entries.go

91 lines
2.2 KiB
Go
Raw Normal View History

package frame
2015-01-14 02:37:10 +00:00
import (
"fmt"
"sort"
)
// Represents a Common Information Entry in
// the Dwarf .debug_frame section.
type CommonInformationEntry struct {
Length uint32
CIE_id uint32
Version uint8
Augmentation string
CodeAlignmentFactor uint64
DataAlignmentFactor int64
ReturnAddressRegister uint64
InitialInstructions []byte
}
2015-03-03 00:06:04 +00:00
// Returns whether or not the given address is within the
// bounds of this frame.
2014-10-11 05:52:05 +00:00
func (fde *FrameDescriptionEntry) Cover(addr uint64) bool {
2014-10-11 06:05:27 +00:00
if (addr - fde.begin) < fde.end {
2014-06-29 16:52:30 +00:00
return true
}
return false
}
// Represents a Frame Descriptor Entry in the
// Dwarf .debug_frame section.
type FrameDescriptionEntry struct {
Length uint32
CIE *CommonInformationEntry
Instructions []byte
2014-10-11 06:05:27 +00:00
begin, end uint64
}
2015-03-03 00:06:04 +00:00
// Address of first location for this frame.
2014-10-11 06:05:27 +00:00
func (fde *FrameDescriptionEntry) Begin() uint64 {
return fde.begin
}
2015-03-03 00:06:04 +00:00
// Address of last location for this frame.
2014-10-11 06:05:27 +00:00
func (fde *FrameDescriptionEntry) End() uint64 {
return fde.begin + fde.end
}
2015-03-03 00:06:04 +00:00
// Set up frame for the given PC.
func (fde *FrameDescriptionEntry) EstablishFrame(pc uint64) *FrameContext {
return executeDwarfProgramUntilPC(fde, pc)
}
2015-03-03 00:06:04 +00:00
// Return the offset from the current SP that the return address is stored at.
2014-06-29 16:52:30 +00:00
func (fde *FrameDescriptionEntry) ReturnAddressOffset(pc uint64) int64 {
frame := fde.EstablishFrame(pc)
return frame.cfa.offset + frame.regs[fde.CIE.ReturnAddressRegister].offset
}
type FrameDescriptionEntries []*FrameDescriptionEntry
func NewFrameIndex() FrameDescriptionEntries {
return make(FrameDescriptionEntries, 0, 1000)
}
2015-03-03 00:06:04 +00:00
// Returns the Frame Description Entry for the given PC.
func (fdes FrameDescriptionEntries) FDEForPC(pc uint64) (*FrameDescriptionEntry, error) {
2015-01-14 02:37:10 +00:00
idx := sort.Search(len(fdes), func(i int) bool {
if fdes[i].Cover(pc) {
return true
}
if fdes[i].More(pc) {
return false
}
return true
2015-01-14 02:37:10 +00:00
})
if idx == len(fdes) {
return nil, fmt.Errorf("could not find FDE for PC %#v", pc)
}
2015-01-14 02:37:10 +00:00
return fdes[idx], nil
}
func (frame *FrameDescriptionEntry) Less(pc uint64) bool {
return frame.Begin() > pc
}
func (frame *FrameDescriptionEntry) More(pc uint64) bool {
return frame.End() < pc
}