From 7434e5a2c7110e512baa93d747ce47d5b4798446 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Tue, 13 Jul 2021 16:59:43 +0200 Subject: [PATCH] main: strip debug information at link time instead of at compile time Stripping debug information at link time also allows relocation compression (aka linker relaxations). Keeping debug information at compile time and optionally stripping it at link time has some advantages: * Automatic stack sizes on Cortex-M rely on the presence of debug information. * Some parts of the compiler now rely on the presence of debug information for proper diagnostics. * It works better with the cache: there is no distinction between debug and no-debug builds. * It makes it easier (or possible at all) to enable debug information in the wasi-libc library without big downsides. --- builder/build.go | 35 ++++++++++++++++++++++++++++++++++- compileopts/config.go | 10 +++++----- main.go | 2 +- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/builder/build.go b/builder/build.go index 5c38433b..c1fd78e3 100644 --- a/builder/build.go +++ b/builder/build.go @@ -100,7 +100,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil AutomaticStackSize: config.AutomaticStackSize(), DefaultStackSize: config.Target.DefaultStackSize, NeedsStackObjects: config.NeedsStackObjects(), - Debug: config.Debug(), + Debug: true, LLVMFeatures: config.LLVMFeatures(), } @@ -539,6 +539,39 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil return fmt.Errorf("unknown libc: %s", config.Target.Libc) } + // Strip debug information with -no-debug. + if !config.Debug() { + for _, tag := range config.BuildTags() { + if tag == "baremetal" { + // Don't use -no-debug on baremetal targets. It makes no sense: + // the debug information isn't flashed to the device anyway. + return fmt.Errorf("stripping debug information is unnecessary for baremetal targets") + } + } + if config.Target.Linker == "wasm-ld" { + // Don't just strip debug information, also compress relocations + // while we're at it. Relocations can only be compressed when debug + // information is stripped. + ldflags = append(ldflags, "--strip-debug", "--compress-relocations") + } else { + switch config.GOOS() { + case "linux": + // Either real linux or an embedded system (like AVR) that + // pretends to be Linux. It's a ELF linker wrapped by GCC in any + // case. + ldflags = append(ldflags, "-Wl,--strip-debug") + case "darwin": + // MacOS (darwin) doesn't have a linker flag to strip debug + // information. Apple expects you to use the strip command + // instead. + return errors.New("cannot remove debug information: MacOS doesn't suppor this linker flag") + default: + // Other OSes may have different flags. + return errors.New("cannot remove debug information: unknown OS: " + config.GOOS()) + } + } + } + // Create a linker job, which links all object files together and does some // extra stuff that can only be done after linking. jobs = append(jobs, &compileJob{ diff --git a/compileopts/config.go b/compileopts/config.go index 36782506..f2ba2857 100644 --- a/compileopts/config.go +++ b/compileopts/config.go @@ -209,9 +209,8 @@ func (c *Config) CFlags() []string { cflags = append(cflags, "-nostdlibinc", "-Xclang", "-internal-isystem", "-Xclang", filepath.Join(root, "lib", "picolibc", "newlib", "libc", "include")) cflags = append(cflags, "-I"+filepath.Join(root, "lib/picolibc-include")) } - if c.Debug() { - cflags = append(cflags, "-g") - } + // Always emit debug information. It is optionally stripped at link time. + cflags = append(cflags, "-g") return cflags } @@ -250,8 +249,9 @@ func (c *Config) VerifyIR() bool { return c.Options.VerifyIR } -// Debug returns whether to add debug symbols to the IR, for debugging with GDB -// and similar. +// Debug returns whether debug (DWARF) information should be retained by the +// linker. By default, debug information is retained but it can be removed with +// the -no-debug flag. func (c *Config) Debug() bool { return c.Options.Debug } diff --git a/main.go b/main.go index 7c3ee96d..c9fd0c04 100644 --- a/main.go +++ b/main.go @@ -1019,7 +1019,7 @@ func main() { printStacks := flag.Bool("print-stacks", false, "print stack sizes of goroutines") printAllocsString := flag.String("print-allocs", "", "regular expression of functions for which heap allocations should be printed") printCommands := flag.Bool("x", false, "Print commands") - nodebug := flag.Bool("no-debug", false, "disable DWARF debug symbol generation") + nodebug := flag.Bool("no-debug", false, "strip debug information") ocdCommandsString := flag.String("ocd-commands", "", "OpenOCD commands, overriding target spec (can specify multiple separated by commas)") ocdOutput := flag.Bool("ocd-output", false, "print OCD daemon output during debug") port := flag.String("port", "", "flash port (can specify multiple candidates separated by commas)")