Beispiel #1
0
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
}
Beispiel #2
0
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
}