Repository: go
Issue: cmd/link: include per-package aggregate static temp symbols?
Labels: NeedsInvestigation,compiler/runtime

I've been working on a Go [binary size analysis tool](https://github.com/bradfitz/shotizam) that aims to attribute ~each byte of the binary back to a function or package.

One thing it's not great at doing at the moment in the general case is summing the size of static temp (..stmp_NNN) because those symbols are removed by default (except in external linking mode).

Worse, with Macho-O binaries not having sizes on symbols, I can't even accurately count the sizes of symbols that do exist because the stmp values are in the DATA, but lacking symbols, so I end up calculating the wrong size of existing symbols:

e.g. this `float64info` should actually be the same size as the `float32info`, but a bunch of stmp_NNN are omitted between `float64info` and `hash..inittask`:

```
   sym "debug/dwarf._Class_index" (at 19138544), size=464
   sym "strconv.float32info" (at 19139008), size=32
   sym "strconv.float64info" (at 19139040), size=1664
   sym "hash..inittask" (at 19140704), size=32
   sym "internal/bytealg..inittask" (at 19140736), size=32
   sym "internal/reflectlite..inittask" (at 19140768), size=32
   sym "internal/singleflight..inittask" (at 19140800), size=32
```

Looking at a binary with the `stmp` symbols, I get the accurate size for `float64info`:

```
   sym "unicode..stmp_539" (at 1005d4260), size=32
   sym "unicode..stmp_553" (at 1005d4280), size=32
   sym "unicode..stmp_558" (at 1005d42a0), size=32
   sym "crypto..stmp_2" (at 1005d42c0), size=32
   sym "crypto/tls..stmp_205" (at 1005d42e0), size=32
   sym "strconv.float32info" (at 1005d4300), size=32
   sym "strconv.float64info" (at 1005d4320), size=32
   sym "unicode..stmp_11" (at 1005d4340), size=32
   sym "unicode..stmp_113" (at 1005d4360), size=32
   sym "unicode..stmp_121" (at 1005d4380), size=32
   sym "unicode..stmp_147" (at 1005d43a0), size=32
   sym "unicode..stmp_150" (at 1005d43c0), size=32
```

So, my request: can we aggregate all the `stmp_NNN` symbols together per-package and emit one symbol per section per Go package, like:

```
        unicode..stmp_pkg
```

Then I can both calculate the sum stmp sizes per package (e.g. unicode is 68KB, crypto/tls is 12KB), and I can also accurately calculate the size of other symbols (Mach-o symbols without a size)

This would make binaries a tiny bit bigger (but bounded by number of packages at least) but would permit more analysis at making them much smaller, IMO. (Or output it to a separate file.)

It would also require sorting the stmp values all together in the binary. They're currently scattered around:

```
   sym "vendor/golang.org/x/net/route.rtmVersion" (at 100615964), size=2
   sym "runtime..stmp_40" (at 100615966), size=2
   sym "context.goroutines" (at 100615968), size=4
   sym "runtime..stmp_41" (at 10061596c), size=4
   sym "runtime.argc" (at 100615970), size=4
   sym "runtime.crashing" (at 100615974), size=4
```

(Note a `context` symbol between `runtime.stmp_40` and `stmp_41` )

What I'd like to see is something like:

```
   sym "vendor/golang.org/x/net/route.rtmVersion" (at 100615964), size=2
   sym "context.goroutines" (at 100615966), size=4
   sym "runtime..stmp_pkg" (at 100615970), size=6
   sym "runtime.argc" (at 100615970), size=4
   sym "runtime.crashing" (at 100615974), size=4
```

Thoughts? Alternatives?

/cc @ianlancetaylor (who schooled me on some of this), @cherrymui, @thanm, @randall77, @josharian, @jeremyfaller