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  }