func LoadLinuxSystemMap( system_map string) (SystemMap, error) { // No map provided. if system_map == "" { return nil, nil } // Read the file. map_data, err := ioutil.ReadFile(system_map) if err != nil { return nil, err } // Create our new map. sysmap := new(LinuxSystemMap) sysmap.defined = make([]platform.Vaddr, 0, 0) sysmap.symbols = make(map[platform.Vaddr]string) sysmap.cache = make(map[platform.Vaddr]platform.Vaddr) // Extract all symbols. log.Printf("loader: Reading symbols (%d bytes)...", len(map_data)) add_symbol := func(line []byte) { // Format: <address> <type> <name> parts := strings.SplitN(string(line), " ", 3) if len(parts) != 3 { return } // Parse the address. addr, err := strconv.ParseUint(parts[0], 16, 64) if err != nil { return } // Save the symbol. sysmap.defined = append(sysmap.defined, platform.Vaddr(addr)) sysmap.symbols[platform.Vaddr(addr)] = parts[2] } start_i := 0 end_i := 0 for end_i = 0; end_i < len(map_data); end_i += 1 { if map_data[end_i] == '\n' { add_symbol(map_data[start_i:end_i]) start_i = (end_i + 1) } } if start_i != end_i && start_i < end_i { add_symbol(map_data[start_i:end_i]) } // Return our map. log.Printf("loader: System map has %d entries.", len(sysmap.defined)) return sysmap, nil }
func (tracer *Tracer) toPaddr( vcpu *platform.Vcpu, reg platform.RegisterValue) string { phys_addr, valid, _, _, err := vcpu.Translate(platform.Vaddr(reg)) if err != nil { return "%x->??" } if valid { return fmt.Sprintf("%x->%x", reg, phys_addr) } return fmt.Sprintf("%x", reg) }
func (tracer *Tracer) Trace(vcpu *platform.Vcpu, step bool) error { // Are we on? if !tracer.enabled { return nil } // Get the current instruction. addr, err := vcpu.GetRegister(tracer.convention.instruction) if err != nil { return err } // Skip duplicates (only if stepping is on). if step && platform.Vaddr(addr) == tracer.last_addr { return nil } // Lookup the current instruction. var fname string var offset uint64 if tracer.sysmap != nil { fname, offset = tracer.sysmap.Lookup(platform.Vaddr(addr)) } // Get the stack depth. stack, err := vcpu.GetRegister(tracer.convention.stack) if err != nil { return err } // Print the return value if applicable. if step && fname != tracer.last_fname && tracer.last_addr != 0 { rval, err := vcpu.GetRegister(tracer.convention.rvalue) if err != nil { return err } log.Printf(" trace: [%08x] %s => %s ?", stack, tracer.last_fname, tracer.toPaddr(vcpu, rval)) // Save the current. tracer.last_fname = fname } // Get a physical address string. rip_phys_str := tracer.toPaddr(vcpu, addr) if fname != "" { if offset == 0 { num_args := len(tracer.convention.arguments) arg_vals := make([]string, num_args, num_args) for i, reg := range tracer.convention.arguments { reg_val, err := vcpu.GetRegister(reg) if err != nil { arg_vals[i] = fmt.Sprintf("??") continue } arg_vals[i] = tracer.toPaddr(vcpu, reg_val) } log.Printf(" trace: [%08x] %s:%s(%s)", stack, fname, rip_phys_str, strings.Join(arg_vals, ",")) } else { log.Printf(" trace: [%08x] %s:%s ... +%x", stack, fname, rip_phys_str, offset) } } else { log.Printf(" trace: ??:%s", rip_phys_str) } // We're okay. tracer.last_addr = platform.Vaddr(addr) return nil }