func (b *Block) BuildStree() (*stree.Tree, Records) { tree := stree.NewTree() s := new(Stack) for i := range b.context_records { s.Push(-len(b.context_records) + i) } for i := range b.records { r := &b.records[i] if r.Type == MEMA_FUNC_ENTER { s.Push(i) } else if r.Type == MEMA_FUNC_EXIT { i_start := s.Pop().(int) var r *Record if i_start < 0 { r = &b.context_records[-i_start-1] } else { r = &b.records[i_start] } // These should match, otherwise we're looking at something incomplete if (*r).FunctionCall().FuncPointer != (*r).FunctionCall().FuncPointer { log.Panic("Not matching.. - ", (*r).FunctionCall().FuncPointer, " - ", (*r).FunctionCall().FuncPointer, " ", i_start, " ", i) } tree.Push(i_start, i-1) } } return_context := make(Records, s.size) i := 0 for s.size > 0 { i_start := s.Pop().(int) tree.Push(i_start, len(b.records)) if i_start < 0 { //log.Print("CR: ", len(b.context_records), -i_start) return_context[i] = b.context_records[-i_start-1] } else { return_context[i] = b.records[i_start] } i += 1 } tree.BuildTree() return &tree, return_context }
func NewBinary(path string) *Binary { file, err := elf.Open(path) if err != nil { log.Print("Binary not available for ", path) return nil } debug_filename := GetDebugFilename(path, file) if debug_filename != "" { //log.Panic("Debug filename: ", debug_filename) file, err = elf.Open(debug_filename) if err != nil { log.Panic("Problem loading elf: ", err, " at ", debug_filename) } } dw, err := file.DWARF() if err != nil { log.Printf("!! No DWARF for %q err = %v", path, err) dw = nil } tree := stree.NewTree() result := &Binary{path, file, dw, make(map[uint64]*elf.Symbol), make(map[uint64]*dwarf.Entry), &tree} if dw != nil { //tree := result.dwarf_stree dwarf_entries := &result.dwarf_entries dr := dw.Reader() //log.Panic("Abort ", path, dwarf) i := 0 n := 0 for { i++ //if i > 1000 { break } entry, err := dr.Next() if err != nil { log.Panic("Error reading dwarf: ", entry) } //log.Print("Got dwarf entry: ", entry) if entry == nil { break } lpc := entry.Val(dwarf.AttrLowpc) hpc := entry.Val(dwarf.AttrHighpc) if hpc != nil && lpc != nil { var hpcv, lpcv uint64 hpcv = hpc.(uint64) lpcv = lpc.(uint64) tree.Push(int(lpcv), int(hpcv)) (*dwarf_entries)[lpcv] = entry //log.Print("Got one: ", lpcv, hpcv, entry) n++ } } log.Print("Building dwarf tree..") tree.BuildTree() log.Print("dwarf tree built.") //log.Panic("Abort, got ", n) } virtoffset := uint64(0) for i := range file.Progs { prog := file.Progs[i] if prog.Type == elf.PT_LOAD { virtoffset = prog.Vaddr break } } var syms []elf.Symbol func() { // populate symbolmap //var err error syms, err = file.Symbols() if err != nil { debugname := GetDebugFilename(path, file) log.Print("Got debug name: ", debugname) } }() for i := range syms { s := &syms[i] result.symbolmap[s.Value-virtoffset] = s } return result }