github.com/decomp/exp@v0.0.0-20210624183419-6d058f5e1da6/disasm/mips/disasm.go (about) 1 // Package mips implements a disassembler for the MIPS architecture. 2 package mips 3 4 import ( 5 "fmt" 6 "log" 7 "os" 8 9 "github.com/decomp/exp/bin" 10 "github.com/decomp/exp/disasm" 11 "github.com/mewkiz/pkg/jsonutil" 12 "github.com/mewkiz/pkg/osutil" 13 "github.com/mewkiz/pkg/term" 14 "github.com/pkg/errors" 15 ) 16 17 // TODO: Remove loggers once the library matures. 18 19 // Loggers. 20 var ( 21 // dbg represents a logger with the "mips:" prefix, which logs debug messages 22 // to standard error. 23 dbg = log.New(os.Stderr, term.BlueBold("mips:")+" ", 0) 24 // warn represents a logger with the "warning:" prefix, which logs warning 25 // messages to standard error. 26 warn = log.New(os.Stderr, term.RedBold("warning:")+" ", 0) 27 ) 28 29 // A Disasm tracks information required to disassemble a binary executable. 30 // 31 // Data should only be written to this structure during initialization. After 32 // initialization the structure is considered in read-only mode to allow for 33 // concurrent decoding of functions. 34 type Disasm struct { 35 *disasm.Disasm 36 // Processor mode. 37 Mode int 38 } 39 40 // NewDisasm creates a new Disasm for accessing the assembly instructions of the 41 // given binary executable. 42 // 43 // Associated files of the generic disassembler. 44 // 45 // funcs.json 46 // blocks.json 47 // tables.json 48 // chunks.json 49 // data.json 50 // 51 // Associated files of the MIPS disassembler. 52 // 53 // contexts.json 54 func NewDisasm(file *bin.File) (*Disasm, error) { 55 // Prepare MIPS disassembler. 56 d, err := disasm.New(file) 57 if err != nil { 58 return nil, errors.WithStack(err) 59 } 60 dis := &Disasm{ 61 Disasm: d, 62 } 63 64 // Parse processor mode. 65 switch dis.File.Arch { 66 case bin.ArchMIPS_32: 67 dis.Mode = 32 68 default: 69 panic(fmt.Errorf("support for machine architecture %v not yet implemented", dis.File.Arch)) 70 } 71 72 // Parse CPU contexts. 73 //if err := parseJSON("contexts.json", &dis.Contexts); err != nil { 74 // return nil, errors.WithStack(err) 75 //} 76 77 return dis, nil 78 } 79 80 // ### [ Helper functions ] #################################################### 81 82 // parseJSON parses the given JSON file and stores the result into v. 83 func parseJSON(jsonPath string, v interface{}) error { 84 if !osutil.Exists(jsonPath) { 85 warn.Printf("unable to locate JSON file %q", jsonPath) 86 return nil 87 } 88 return jsonutil.ParseFile(jsonPath, v) 89 }