1// Copyright 2012 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// Objdump disassembles executable files. 6// 7// Usage: 8// 9// go tool objdump [-s symregexp] binary 10// 11// Objdump prints a disassembly of all text symbols (code) in the binary. 12// If the -s option is present, objdump only disassembles 13// symbols with names matching the regular expression. 14// 15// Alternate usage: 16// 17// go tool objdump binary start end 18// 19// In this mode, objdump disassembles the binary starting at the start address and 20// stopping at the end address. The start and end addresses are program 21// counters written in hexadecimal with optional leading 0x prefix. 22// In this mode, objdump prints a sequence of stanzas of the form: 23// 24// file:line 25// address: assembly 26// address: assembly 27// ... 28// 29// Each stanza gives the disassembly for a contiguous range of addresses 30// all mapped to the same original source file and line number. 31// This mode is intended for use by pprof. 32package main 33 34import ( 35 "flag" 36 "fmt" 37 "log" 38 "os" 39 "regexp" 40 "strconv" 41 "strings" 42 43 "cmd/internal/objfile" 44 "cmd/internal/telemetry/counter" 45) 46 47var printCode = flag.Bool("S", false, "print Go code alongside assembly") 48var symregexp = flag.String("s", "", "only dump symbols matching this regexp") 49var gnuAsm = flag.Bool("gnu", false, "print GNU assembly next to Go assembly (where supported)") 50var symRE *regexp.Regexp 51 52func usage() { 53 fmt.Fprintf(os.Stderr, "usage: go tool objdump [-S] [-gnu] [-s symregexp] binary [start end]\n\n") 54 flag.PrintDefaults() 55 os.Exit(2) 56} 57 58func main() { 59 log.SetFlags(0) 60 log.SetPrefix("objdump: ") 61 counter.Open() 62 63 flag.Usage = usage 64 flag.Parse() 65 counter.Inc("objdump/invocations") 66 counter.CountFlags("objdump/flag:", *flag.CommandLine) 67 if flag.NArg() != 1 && flag.NArg() != 3 { 68 usage() 69 } 70 71 if *symregexp != "" { 72 re, err := regexp.Compile(*symregexp) 73 if err != nil { 74 log.Fatalf("invalid -s regexp: %v", err) 75 } 76 symRE = re 77 } 78 79 f, err := objfile.Open(flag.Arg(0)) 80 if err != nil { 81 log.Fatal(err) 82 } 83 defer f.Close() 84 85 dis, err := f.Disasm() 86 if err != nil { 87 log.Fatalf("disassemble %s: %v", flag.Arg(0), err) 88 } 89 90 switch flag.NArg() { 91 default: 92 usage() 93 case 1: 94 // disassembly of entire object 95 dis.Print(os.Stdout, symRE, 0, ^uint64(0), *printCode, *gnuAsm) 96 97 case 3: 98 // disassembly of PC range 99 start, err := strconv.ParseUint(strings.TrimPrefix(flag.Arg(1), "0x"), 16, 64) 100 if err != nil { 101 log.Fatalf("invalid start PC: %v", err) 102 } 103 end, err := strconv.ParseUint(strings.TrimPrefix(flag.Arg(2), "0x"), 16, 64) 104 if err != nil { 105 log.Fatalf("invalid end PC: %v", err) 106 } 107 dis.Print(os.Stdout, symRE, start, end, *printCode, *gnuAsm) 108 } 109} 110