]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/objfile: break out dissassemblers to another package
authorCherry Mui <cherryyz@google.com>
Tue, 10 Dec 2024 17:00:10 +0000 (12:00 -0500)
committerCherry Mui <cherryyz@google.com>
Wed, 11 Dec 2024 16:53:20 +0000 (08:53 -0800)
Currently, cmd/internal/objfile provides dissassembly routines for
various architectures, which depend on dissassemblers from x/arch.
cmd/internal/objfile is imported in tools that need dissassembly
(objdump, pprof) and tools that don't need dissassembly (nm,
addr2line). Adding/improving disassembly support for more
architectures can cause binary size increase, and for some tools
(nm, addr2line) it is not necessary.

This CL breaks out dissassembly routines to a different package,
which is only imported in tools that need dissassembly. Other
tools can depend on cmd/internal/objfile without the disassembly
code from x/arch.

This reduces binary sizes for those tools. On darwin/arm64,

                                 old         new
cmd/addr2line                  4554418     3648882   -20%
cmd/addr2line (-ldflags=-w)    3464626     2641650   -24%
cmd/nm                         4503874     3616722   -20%
cmd/nm (-ldflags=-w)           3430594     2609490   -24%

For #70699.

Change-Id: Ie45d5d5c5500c5f3882e8b3c4e6eb81f0d815292
Reviewed-on: https://go-review.googlesource.com/c/go/+/634916
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/internal/disasm/disasm.go [moved from src/cmd/internal/objfile/disasm.go with 94% similarity]
src/cmd/internal/objfile/objfile.go
src/cmd/objdump/main.go
src/cmd/pprof/pprof.go

similarity index 94%
rename from src/cmd/internal/objfile/disasm.go
rename to src/cmd/internal/disasm/disasm.go
index 99f54143fa986331e07749bbfc18d9623c78b625..c317effa900f60d3080b387a13463152b379e121 100644 (file)
@@ -2,13 +2,16 @@
 // 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"
@@ -19,6 +22,7 @@ import (
        "strings"
        "text/tabwriter"
 
+       "cmd/internal/objfile"
        "cmd/internal/src"
 
        "golang.org/x/arch/arm/armasm"
@@ -32,8 +36,8 @@ import (
 
 // 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
@@ -42,8 +46,12 @@ type Disasm struct {
        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
@@ -269,7 +277,7 @@ func (d *Disasm) Print(w io.Writer, filter *regexp.Regexp, start, end uint64, pr
 }
 
 // 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
        }
@@ -452,9 +460,3 @@ var byteOrders = map[string]binary.ByteOrder{
        "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)
-}
index 2f2d7718132d5741ee4c26e95b6516ef8e93a537..ed9aae280e55795bd78a1215675d79bfde74df0e 100644 (file)
@@ -119,10 +119,6 @@ func (f *File) DWARF() (*dwarf.Data, error) {
        return f.entries[0].DWARF()
 }
 
-func (f *File) Disasm() (*Disasm, error) {
-       return f.entries[0].Disasm()
-}
-
 func (e *Entry) Name() string {
        return e.name
 }
@@ -181,3 +177,9 @@ func (e *Entry) LoadAddress() (uint64, error) {
 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)
+}
index b5b0d7f5178d5bf4aa13ba81c7a29ae25a222640..c98551e6b857b0840d814c07461dbec7bae8ac7c 100644 (file)
@@ -40,6 +40,7 @@ import (
        "strconv"
        "strings"
 
+       "cmd/internal/disasm"
        "cmd/internal/objfile"
        "cmd/internal/telemetry/counter"
 )
@@ -82,7 +83,7 @@ func main() {
        }
        defer f.Close()
 
-       dis, err := f.Disasm()
+       dis, err := disasm.DisasmForFile(f)
        if err != nil {
                log.Fatalf("disassemble %s: %v", flag.Arg(0), err)
        }
index a1c2cd210f8dbaf2c3d4d49739af962e6793120f..bfc2911b69cd396013aea4a7215e17feb27a9386 100644 (file)
@@ -24,6 +24,7 @@ import (
        "sync"
        "time"
 
+       "cmd/internal/disasm"
        "cmd/internal/objfile"
        "cmd/internal/telemetry/counter"
 
@@ -162,7 +163,7 @@ func adjustURL(source string, duration, timeout time.Duration) (string, time.Dur
 // (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) {
@@ -202,11 +203,11 @@ func (t *objTool) Disasm(file string, start, end uint64, intelSyntax bool) ([]dr
        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 {
@@ -216,7 +217,7 @@ func (t *objTool) cachedDisasm(file string) (*objfile.Disasm, error) {
        if err != nil {
                return nil, err
        }
-       d, err = f.Disasm()
+       d, err = disasm.DisasmForFile(f)
        f.Close()
        if err != nil {
                return nil, err