]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj: add a flag to not write referenced symbol names in object file
authorCherry Mui <cherryyz@google.com>
Thu, 5 May 2022 21:22:17 +0000 (17:22 -0400)
committerCherry Mui <cherryyz@google.com>
Wed, 11 May 2022 21:01:09 +0000 (21:01 +0000)
The Go object file references (some of) symbols from other
packages by indices, not by names. The linker doesn't need the
symbol names to do the linking. The names are included in the
object file so it is self-contained and tools (objdump, nm) can
read the referenced symbol names. Including the names increases
object file size. Add a flag to disable it on demand (off by
default).

Change-Id: I143a0eb656997497c750b8eb1541341b2aee8f30
Reviewed-on: https://go-review.googlesource.com/c/go/+/404297
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/base/debug.go
src/cmd/compile/internal/base/flag.go
src/cmd/internal/goobj/objfile.go
src/cmd/internal/obj/link.go
src/cmd/internal/obj/objfile.go
src/cmd/internal/obj/objfile_test.go

index 80b2ff5bd60f63d03a5f080d7e7061932e6fb366..f1d020f342ed0f3126f5c06b251cac077063c0ae 100644 (file)
@@ -31,6 +31,7 @@ type DebugFlags struct {
        LocationLists        int    `help:"print information about DWARF location list creation"`
        Nil                  int    `help:"print information about nil checks"`
        NoOpenDefer          int    `help:"disable open-coded defers"`
+       NoRefName            int    `help:"do not include referenced symbol names in object file"`
        PCTab                string `help:"print named pc-value table\nOne of: pctospadj, pctofile, pctoline, pctoinline, pctopcdata"`
        Panic                int    `help:"show all compiler panics"`
        Slice                int    `help:"print information about slice compilation"`
index 49e004cf18599e94d84e4c32f842c6dcec276899..4de0df21cbb7b21a029c14f0b400cd30c780422f 100644 (file)
@@ -192,6 +192,7 @@ func ParseFlags() {
        Ctxt.Flag_optimize = Flag.N == 0
        Ctxt.Debugasm = int(Flag.S)
        Ctxt.Flag_maymorestack = Debug.MayMoreStack
+       Ctxt.Flag_noRefName = Debug.NoRefName != 0
 
        if flag.NArg() < 1 {
                usage()
index 1b676b3677b54564746318a3cf01c8b997ce5e0b..665fa41475dd377ea4b45c7c5a0a0471d9830f8a 100644 (file)
@@ -177,6 +177,7 @@ const (
        PkgIdxHashed                        // Hashed (content-addressable) symbols
        PkgIdxBuiltin                       // Predefined runtime symbols (ex: runtime.newobject)
        PkgIdxSelf                          // Symbols defined in the current package
+       PkgIdxSpecial  = PkgIdxSelf         // Indices above it has special meanings
        PkgIdxInvalid  = 0
        // The index of other referenced packages starts from 1.
 )
index 8a50b2e4fe182f98f201063b7cfbda142a5f3ac4..58aeb87c4f3f8cfe07ea96df703293cfece596c2 100644 (file)
@@ -899,6 +899,7 @@ type Link struct {
        Flag_linkshared    bool
        Flag_optimize      bool
        Flag_locationlists bool
+       Flag_noRefName     bool   // do not include referenced symbol names in object file
        Retpoline          bool   // emit use of retpoline stubs for indirect jmp/call
        Flag_maymorestack  string // If not "", call this function before stack checks
        Bso                *bufio.Writer
index 2caff62702fd9c9d94d7fde00282668a7d51df37..d31afda703b7a07f85c1ec97aa49ff9f176e0952 100644 (file)
@@ -269,17 +269,21 @@ func (w *writer) StringTable() {
                w.AddString(pkg)
        }
        w.ctxt.traverseSyms(traverseAll, func(s *LSym) {
+               // Don't put names of builtins into the string table (to save
+               // space).
+               if s.PkgIdx == goobj.PkgIdxBuiltin {
+                       return
+               }
                // TODO: this includes references of indexed symbols from other packages,
                // for which the linker doesn't need the name. Consider moving them to
                // a separate block (for tools only).
+               if w.ctxt.Flag_noRefName && s.PkgIdx < goobj.PkgIdxSpecial {
+                       // Don't include them if Flag_noRefName
+                       return
+               }
                if w.pkgpath != "" {
                        s.Name = strings.Replace(s.Name, "\"\".", w.pkgpath+".", -1)
                }
-               // Don't put names of builtins into the string table (to save
-               // space).
-               if s.PkgIdx == goobj.PkgIdxBuiltin {
-                       return
-               }
                w.AddString(s.Name)
        })
 
@@ -625,6 +629,9 @@ func (w *writer) refFlags() {
 // Emits names of referenced indexed symbols, used by tools (objdump, nm)
 // only.
 func (w *writer) refNames() {
+       if w.ctxt.Flag_noRefName {
+               return
+       }
        seen := make(map[*LSym]bool)
        w.ctxt.traverseSyms(traverseRefs, func(rs *LSym) { // only traverse refs, not auxs, as tools don't need auxs
                switch rs.PkgIdx {
index f5a4016eec367627034006bb242d2135029913ed..91e96e435d617327c7fe3bfad5a17338c683dea5 100644 (file)
@@ -121,3 +121,25 @@ func TestSymbolTooLarge(t *testing.T) { // Issue 42054
                t.Errorf("unexpected error message: want: %q, got: %s", want, out)
        }
 }
+
+func TestNoRefName(t *testing.T) {
+       // Test that the norefname flag works.
+       testenv.MustHaveGoBuild(t)
+
+       tmpdir := t.TempDir()
+
+       src := filepath.Join(tmpdir, "x.go")
+       err := ioutil.WriteFile(src, []byte("package main; import \"fmt\"; func main() { fmt.Println(123) }\n"), 0666)
+       if err != nil {
+               t.Fatalf("failed to write source file: %v\n", err)
+       }
+       exe := filepath.Join(tmpdir, "x.exe")
+
+       // Build the fmt package with norefname. Not rebuilding all packages to save time.
+       // Also testing that norefname and non-norefname packages can link together.
+       cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags=fmt=-d=norefname", "-o", exe, src)
+       out, err := cmd.CombinedOutput()
+       if err != nil {
+               t.Fatalf("build failed: %v, output:\n%s", err, out)
+       }
+}