// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package objfile
+// Package disasm provides disassembly routines.
+//
+// It is broken out from cmd/internal/objfile so tools that don't need
+// disassembling don't need to depend on x/arch disassembler code.
+package disasm
import (
"bufio"
"bytes"
"container/list"
- "debug/gosym"
"encoding/binary"
"fmt"
"io"
"strings"
"text/tabwriter"
+ "cmd/internal/objfile"
"cmd/internal/src"
"golang.org/x/arch/arm/armasm"
// Disasm is a disassembler for a given File.
type Disasm struct {
- syms []Sym //symbols in file, sorted by address
- pcln Liner // pcln table
+ syms []objfile.Sym // symbols in file, sorted by address
+ pcln objfile.Liner // pcln table
text []byte // bytes of text segment (actual instructions)
textStart uint64 // start PC of text
textEnd uint64 // end PC of text
byteOrder binary.ByteOrder // byte order for goarch
}
-// Disasm returns a disassembler for the file f.
-func (e *Entry) Disasm() (*Disasm, error) {
+// DisasmForFile returns a disassembler for the file f.
+func DisasmForFile(f *objfile.File) (*Disasm, error) {
+ return disasmForEntry(f.Entries()[0])
+}
+
+func disasmForEntry(e *objfile.Entry) (*Disasm, error) {
syms, err := e.Symbols()
if err != nil {
return nil, err
}
// Decode disassembles the text segment range [start, end), calling f for each instruction.
-func (d *Disasm) Decode(start, end uint64, relocs []Reloc, gnuAsm bool, f func(pc, size uint64, file string, line int, text string)) {
+func (d *Disasm) Decode(start, end uint64, relocs []objfile.Reloc, gnuAsm bool, f func(pc, size uint64, file string, line int, text string)) {
if start < d.textStart {
start = d.textStart
}
"riscv64": binary.LittleEndian,
"s390x": binary.BigEndian,
}
-
-type Liner interface {
- // Given a pc, returns the corresponding file, line, and function data.
- // If unknown, returns "",0,nil.
- PCToLine(uint64) (string, int, *gosym.Func)
-}
return f.entries[0].DWARF()
}
-func (f *File) Disasm() (*Disasm, error) {
- return f.entries[0].Disasm()
-}
-
func (e *Entry) Name() string {
return e.name
}
func (e *Entry) DWARF() (*dwarf.Data, error) {
return e.raw.dwarf()
}
+
+type Liner interface {
+ // Given a pc, returns the corresponding file, line, and function data.
+ // If unknown, returns "",0,nil.
+ PCToLine(uint64) (string, int, *gosym.Func)
+}
"sync"
"time"
+ "cmd/internal/disasm"
"cmd/internal/objfile"
"cmd/internal/telemetry/counter"
// (instead of invoking GNU binutils).
type objTool struct {
mu sync.Mutex
- disasmCache map[string]*objfile.Disasm
+ disasmCache map[string]*disasm.Disasm
}
func (*objTool) Open(name string, start, limit, offset uint64, relocationSymbol string) (driver.ObjFile, error) {
return asm, nil
}
-func (t *objTool) cachedDisasm(file string) (*objfile.Disasm, error) {
+func (t *objTool) cachedDisasm(file string) (*disasm.Disasm, error) {
t.mu.Lock()
defer t.mu.Unlock()
if t.disasmCache == nil {
- t.disasmCache = make(map[string]*objfile.Disasm)
+ t.disasmCache = make(map[string]*disasm.Disasm)
}
d := t.disasmCache[file]
if d != nil {
if err != nil {
return nil, err
}
- d, err = f.Disasm()
+ d, err = disasm.DisasmForFile(f)
f.Close()
if err != nil {
return nil, err