func (s Syscall) traceArg(args ...interface{}) string { hex := func(a interface{}) string { tmp := fmt.Sprintf("0x%x", a) if strings.HasPrefix(tmp, "0x-") { tmp = "-0x" + tmp[3:] } return tmp } switch arg := args[0].(type) { case Obuf: return hex(arg.Addr) case Buf: if len(args) > 1 { if length, ok := args[1].(Len); ok { mem, _ := s.Kernel.U.MemRead(arg.Addr, uint64(length)) return models.Repr(mem, s.Kernel.U.Config().Strsize) } } return hex(arg.Addr) case Off: return hex(arg) case Ptr: return hex(arg) case Fd: return fmt.Sprintf("%d", int32(arg)) case string: return models.Repr([]byte(arg), s.Kernel.U.Config().Strsize) case uint64: return hex(arg) default: return fmt.Sprintf("%v", arg) } }
func (s Syscall) traceArg(args []uint64, typ reflect.Type) string { if typ == BufType && len(args) > 1 { mem, _ := s.U().MemRead(args[0], args[1]) return models.Repr(mem) } switch typ { case BufType, ObufType, OffType, PtrType: return fmt.Sprintf("0x%x", args[0]) case LenType, FdType: return fmt.Sprintf("%d", args[0]) default: switch typ.Kind() { case reflect.String: s, _ := s.U().Mem().ReadStrAt(args[0]) return models.Repr([]byte(s)) default: // TODO: facilitate pretty printing? if v, ok := s.Unpack(args, typ); ok { return fmt.Sprintf("%v", v.Interface()) } return fmt.Sprintf("%d", int32(args[0])) } } }
func (s Syscall) TraceRet(args []uint64, ret uint64) { var out []string for i, typ := range s.In { if typ == ObufType && len(args) > i+1 { r := int(ret) if uint64(r) <= args[i+1] && r >= 0 { mem, _ := s.U().MemRead(args[i], uint64(r)) out = append(out, models.Repr(mem)) } } } if len(s.Out) > 0 { out = append(out, s.traceArg([]uint64{ret}, s.Out[0])) } if len(out) > 0 { fmt.Fprintf(os.Stderr, " = %s\n", strings.Join(out, ", ")) } else { fmt.Fprintf(os.Stderr, "\n") } }
func (s Syscall) TraceRet(args []uint64, ret uint64) string { var out []string for i, typ := range s.In { if typ == reflect.TypeOf(Obuf{}) && len(args) > i+1 { length := int(ret) if uint64(length) <= args[i+1] && length >= 0 { mem, _ := s.Kernel.U.MemRead(args[i], uint64(length)) out = append(out, models.Repr(mem, s.Kernel.U.Config().Strsize)) } } } if len(s.Out) > 0 { // TODO: need a standard for converting return values out = append(out, s.traceArg(ret)) } if len(out) > 0 { return fmt.Sprintf(" = %s\n", strings.Join(out, ", ")) } else { return "\n" } }