Home | History | Annotate | Download | only in objdump
      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.
     32 package main
     33 
     34 import (
     35 	"flag"
     36 	"fmt"
     37 	"log"
     38 	"os"
     39 	"regexp"
     40 	"strconv"
     41 	"strings"
     42 
     43 	"cmd/internal/objfile"
     44 )
     45 
     46 var symregexp = flag.String("s", "", "only dump symbols matching this regexp")
     47 var symRE *regexp.Regexp
     48 
     49 func usage() {
     50 	fmt.Fprintf(os.Stderr, "usage: go tool objdump [-s symregexp] binary [start end]\n\n")
     51 	flag.PrintDefaults()
     52 	os.Exit(2)
     53 }
     54 
     55 type lookupFunc func(addr uint64) (sym string, base uint64)
     56 type disasmFunc func(code []byte, pc uint64, lookup lookupFunc) (text string, size int)
     57 
     58 func main() {
     59 	log.SetFlags(0)
     60 	log.SetPrefix("objdump: ")
     61 
     62 	flag.Usage = usage
     63 	flag.Parse()
     64 	if flag.NArg() != 1 && flag.NArg() != 3 {
     65 		usage()
     66 	}
     67 
     68 	if *symregexp != "" {
     69 		re, err := regexp.Compile(*symregexp)
     70 		if err != nil {
     71 			log.Fatalf("invalid -s regexp: %v", err)
     72 		}
     73 		symRE = re
     74 	}
     75 
     76 	f, err := objfile.Open(flag.Arg(0))
     77 	if err != nil {
     78 		log.Fatal(err)
     79 	}
     80 
     81 	dis, err := f.Disasm()
     82 	if err != nil {
     83 		log.Fatalf("disassemble %s: %v", flag.Arg(0), err)
     84 	}
     85 
     86 	switch flag.NArg() {
     87 	default:
     88 		usage()
     89 	case 1:
     90 		// disassembly of entire object
     91 		dis.Print(os.Stdout, symRE, 0, ^uint64(0))
     92 		os.Exit(0)
     93 
     94 	case 3:
     95 		// disassembly of PC range
     96 		start, err := strconv.ParseUint(strings.TrimPrefix(flag.Arg(1), "0x"), 16, 64)
     97 		if err != nil {
     98 			log.Fatalf("invalid start PC: %v", err)
     99 		}
    100 		end, err := strconv.ParseUint(strings.TrimPrefix(flag.Arg(2), "0x"), 16, 64)
    101 		if err != nil {
    102 			log.Fatalf("invalid end PC: %v", err)
    103 		}
    104 		dis.Print(os.Stdout, symRE, start, end)
    105 		os.Exit(0)
    106 	}
    107 }
    108