github.com/decomp/exp@v0.0.0-20210624183419-6d058f5e1da6/disasm/x86/context.go (about) 1 package x86 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 8 "github.com/decomp/exp/bin" 9 "github.com/pkg/errors" 10 ) 11 12 // Contexts tracks the CPU context at various addresses of the executable. 13 type Contexts map[bin.Address]Context 14 15 // Context tracks the CPU context at a specific address of the executable. 16 type Context struct { 17 // Register constraints. 18 Regs map[Register]ValueContext `json:"regs"` 19 // Instruction argument constraints. 20 Args map[int]ValueContext `json:"args"` 21 } 22 23 // ValueContext defines constraints on a value used at a specific address. 24 // 25 // The following keys are defined. 26 // 27 // Key Type Description 28 // 29 // addr bin.Address virtual address. 30 // 31 // extractvalue bool extract value. 32 // 33 // min int64 minimum value. 34 // max int64 maximum value. 35 // 36 // Mem.offset int64 memory reference offset. 37 // 38 // param int64 parameter index. 39 // 40 // symbol string symbol name. 41 // 42 // type string LLVM IR type. 43 type ValueContext map[string]Value 44 45 // Value represents a value at a specific address. 46 type Value struct { 47 // underlying string representation of the value. 48 s string 49 } 50 51 // String returns the string representation of v. 52 func (v Value) String() string { 53 return v.s 54 } 55 56 // Set sets v to the value represented by s. 57 func (v *Value) Set(s string) error { 58 v.s = s 59 return nil 60 } 61 62 // UnmarshalText unmarshals the text into v. 63 func (v *Value) UnmarshalText(text []byte) error { 64 if err := v.Set(string(text)); err != nil { 65 return errors.WithStack(err) 66 } 67 return nil 68 } 69 70 // MarshalText returns the textual representation of v. 71 func (v Value) MarshalText() ([]byte, error) { 72 return []byte(v.String()), nil 73 } 74 75 // Addr returns the virtual address represented by v. 76 func (v Value) Addr() bin.Address { 77 var addr bin.Address 78 if err := addr.Set(v.s); err != nil { 79 panic(fmt.Errorf("unable to parse value %q as virtual address; %v", v.s, err)) 80 } 81 return addr 82 } 83 84 // Int64 returns the 64-bit signed integer represented by v. 85 func (v Value) Int64() int64 { 86 x, err := strconv.ParseInt(v.s, 10, 64) 87 if err != nil { 88 panic(fmt.Errorf("unable to parse value %q as int64; %v", v.s, err)) 89 } 90 return x 91 } 92 93 // Uint64 returns the 64-bit unsigned integer represented by v. 94 func (v Value) Uint64() uint64 { 95 s := v.s 96 base := 10 97 if strings.HasPrefix(s, "0x") { 98 s = s[len("0x"):] 99 } 100 x, err := strconv.ParseUint(s, base, 64) 101 if err != nil { 102 panic(fmt.Errorf("unable to parse value %q as uint64; %v", v.s, err)) 103 } 104 return x 105 } 106 107 // Bool returns the boolean represented by v. 108 func (v Value) Bool() bool { 109 b, err := strconv.ParseBool(v.s) 110 if err != nil { 111 panic(fmt.Errorf("unable to parse value %q as bool; %v", v.s, err)) 112 } 113 return b 114 }