github.com/riscv/riscv-go@v0.0.0-20200123204226-124ebd6fcc8e/src/cmd/disas/main.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "flag" 9 "fmt" 10 "io/ioutil" 11 "log" 12 "os" 13 "os/exec" 14 "strings" 15 16 "cmd/internal/goobj" 17 "cmd/internal/obj" 18 ) 19 20 func getobjdumpcmd(fname string) (*exec.Cmd, error) { 21 switch obj.GOARCH { 22 case "arm": 23 return exec.Command( 24 "arm-none-eabi-objdump", 25 "-b", "binary", 26 "-m", "arm", 27 "-EL", 28 "-D", fname), 29 nil 30 case "riscv": 31 return exec.Command( 32 "riscv64-unknown-elf-objdump", 33 "-b", "binary", 34 "-m", "riscv:rv64", 35 "-EL", 36 "-D", fname), 37 nil 38 default: 39 return nil, fmt.Errorf("unsupported architecture %s", obj.GOARCH) 40 } 41 } 42 43 func disas1(sym *goobj.Sym, data []byte) { 44 f, err := ioutil.TempFile("/tmp", "go_disas") 45 if err != nil { 46 log.Println(err) 47 return 48 } 49 defer os.Remove(f.Name()) 50 defer f.Close() 51 52 _, err = f.Write(data) 53 if err != nil { 54 log.Println(err) 55 return 56 } 57 58 objdumpcmd, err := getobjdumpcmd(f.Name()) 59 if err != nil { 60 log.Println(err) 61 return 62 } 63 objdumpout, err := objdumpcmd.Output() 64 if err != nil { 65 log.Println(err) 66 return 67 } 68 objdumplines := strings.Split(string(objdumpout[:]), "\n") 69 fmt.Printf("%s:\n", sym.Name) 70 for _, line := range objdumplines[7:] { 71 fmt.Println(line) 72 } 73 } 74 75 func disas(file string, pkgpath string) { 76 f, err := os.Open(file) 77 if err != nil { 78 log.Fatal(err) 79 } 80 defer f.Close() 81 82 obj, err := goobj.Parse(f, pkgpath) 83 if err != nil { 84 log.Fatal(err) 85 } 86 87 for _, sym := range obj.Syms { 88 data := make([]byte, sym.Data.Size) 89 90 _, err = f.Seek(sym.Data.Offset, 0) 91 if err != nil { 92 log.Println(err) 93 continue 94 } 95 96 _, err = f.Read(data) 97 if err != nil { 98 log.Println(err) 99 continue 100 } 101 102 disas1(sym, data) 103 } 104 } 105 106 func main() { 107 log.SetFlags(0) 108 log.SetPrefix("disas: ") 109 110 // Ensure that we actually support this architecture. 111 _, err := getobjdumpcmd("dummy") 112 if err != nil { 113 log.Fatal(err) 114 } 115 116 flag.Parse() 117 if flag.NArg() != 1 { 118 fmt.Fprintf(os.Stderr, "usage: disas file.o\n") 119 os.Exit(2) 120 } 121 122 disas(flag.Arg(0), "main") 123 }