func (*objTool) Open(name string, start uint64) (plugin.ObjFile, error) { of, err := objfile.Open(name) if err != nil { return nil, err } f := &file{ name: name, file: of, } return f, nil }
func main() { log.SetFlags(0) log.SetPrefix("addr2line: ") // pprof expects this behavior when checking for addr2line if len(os.Args) > 1 && os.Args[1] == "--help" { printUsage(os.Stdout) os.Exit(0) } flag.Usage = usage flag.Parse() if flag.NArg() != 1 { usage() } f, err := objfile.Open(flag.Arg(0)) if err != nil { log.Fatal(err) } tab, err := f.PCLineTable() if err != nil { log.Fatalf("reading %s: %v", flag.Arg(0), err) } stdin := bufio.NewScanner(os.Stdin) stdout := bufio.NewWriter(os.Stdout) for stdin.Scan() { p := stdin.Text() if strings.Contains(p, ":") { // Reverse translate file:line to pc. // This was an extension in the old C version of 'go tool addr2line' // and is probably not used by anyone, but recognize the syntax. // We don't have an implementation. fmt.Fprintf(stdout, "!reverse translation not implemented\n") continue } pc, _ := strconv.ParseUint(strings.TrimPrefix(p, "0x"), 16, 64) file, line, fn := tab.PCToLine(pc) name := "?" if fn != nil { name = fn.Name } else { file = "?" line = 0 } fmt.Fprintf(stdout, "%s\n%s:%d\n", name, file, line) } stdout.Flush() }
func main() { log.SetFlags(0) log.SetPrefix("objdump: ") flag.Usage = usage flag.Parse() if flag.NArg() != 1 && flag.NArg() != 3 { usage() } if *symregexp != "" { re, err := regexp.Compile(*symregexp) if err != nil { log.Fatalf("invalid -s regexp: %v", err) } symRE = re } f, err := objfile.Open(flag.Arg(0)) if err != nil { log.Fatal(err) } dis, err := f.Disasm() if err != nil { log.Fatalf("disassemble %s: %v", flag.Arg(0), err) } switch flag.NArg() { default: usage() case 1: // disassembly of entire object dis.Print(os.Stdout, symRE, 0, ^uint64(0)) os.Exit(0) case 3: // disassembly of PC range start, err := strconv.ParseUint(strings.TrimPrefix(flag.Arg(1), "0x"), 16, 64) if err != nil { log.Fatalf("invalid start PC: %v", err) } end, err := strconv.ParseUint(strings.TrimPrefix(flag.Arg(2), "0x"), 16, 64) if err != nil { log.Fatalf("invalid end PC: %v", err) } dis.Print(os.Stdout, symRE, start, end) os.Exit(0) } }
func (*objTool) Open(name string, start uint64) (plugin.ObjFile, error) { of, err := objfile.Open(name) if err != nil { return nil, err } f := &file{ name: name, file: of, } if load, err := of.LoadAddress(); err == nil { f.offset = start - load } return f, nil }
func nm(file string) { f, err := objfile.Open(file) if err != nil { errorf("%v", err) return } defer f.Close() syms, err := f.Symbols() if err != nil { errorf("reading %s: %v", file, err) } if len(syms) == 0 { errorf("reading %s: no symbols", file) } switch *sortOrder { case "address": sort.Sort(byAddr(syms)) case "name": sort.Sort(byName(syms)) case "size": sort.Sort(bySize(syms)) } w := bufio.NewWriter(os.Stdout) for _, sym := range syms { if filePrefix { fmt.Fprintf(w, "%s:\t", file) } if sym.Code == 'U' { fmt.Fprintf(w, "%8s", "") } else { fmt.Fprintf(w, "%8x", sym.Addr) } if *printSize { fmt.Fprintf(w, " %10d", sym.Size) } fmt.Fprintf(w, " %c %s", sym.Code, sym.Name) if *printType && sym.Type != "" { fmt.Fprintf(w, " %s", sym.Type) } fmt.Fprintf(w, "\n") } w.Flush() }
func (t *objTool) cachedDisasm(file string) (*objfile.Disasm, error) { t.mu.Lock() defer t.mu.Unlock() if t.disasmCache == nil { t.disasmCache = make(map[string]*objfile.Disasm) } d := t.disasmCache[file] if d != nil { return d, nil } f, err := objfile.Open(file) if err != nil { return nil, err } d, err = f.Disasm() f.Close() if err != nil { return nil, err } t.disasmCache[file] = d return d, nil }