"bytes"
"cmd/compile/internal/ssa"
"cmd/compile/internal/types"
+ "cmd/internal/dwarf"
"cmd/internal/obj"
"cmd/internal/objabi"
"cmd/internal/src"
flag.StringVar(&benchfile, "bench", "", "append benchmark times to `file`")
objabi.Flagparse(usage)
+ // Record flags that affect the build result. (And don't
+ // record flags that don't, since that would cause spurious
+ // changes in the binary.)
+ recordFlags("B", "N", "l", "msan", "race", "shared", "dynlink", "dwarflocationlists")
+
Ctxt.Flag_shared = flag_dynlink || flag_shared
Ctxt.Flag_dynlink = flag_dynlink
Ctxt.Flag_optimize = Debug['N'] == 0
}
return true
}
+
+// recordFlags records the specified command-line flags to be placed
+// in the DWARF info.
+func recordFlags(flags ...string) {
+ if myimportpath == "" {
+ // We can't record the flags if we don't know what the
+ // package name is.
+ return
+ }
+
+ type BoolFlag interface {
+ IsBoolFlag() bool
+ }
+ type CountFlag interface {
+ IsCountFlag() bool
+ }
+ var cmd bytes.Buffer
+ for _, name := range flags {
+ f := flag.Lookup(name)
+ if f == nil {
+ continue
+ }
+ getter := f.Value.(flag.Getter)
+ if getter.String() == f.DefValue {
+ // Flag has default value, so omit it.
+ continue
+ }
+ if bf, ok := f.Value.(BoolFlag); ok && bf.IsBoolFlag() {
+ val, ok := getter.Get().(bool)
+ if ok && val {
+ fmt.Fprintf(&cmd, " -%s", f.Name)
+ continue
+ }
+ }
+ if cf, ok := f.Value.(CountFlag); ok && cf.IsCountFlag() {
+ val, ok := getter.Get().(int)
+ if ok && val == 1 {
+ fmt.Fprintf(&cmd, " -%s", f.Name)
+ continue
+ }
+ }
+ fmt.Fprintf(&cmd, " -%s=%v", f.Name, getter.Get())
+ }
+
+ if cmd.Len() == 0 {
+ return
+ }
+ s := Ctxt.Lookup(dwarf.CUInfoPrefix + "producer." + myimportpath)
+ s.Type = objabi.SDWARFINFO
+ Ctxt.Data = append(Ctxt.Data, s)
+ s.P = cmd.Bytes()[1:]
+}
// RangePrefix is the prefix for all the symbols containing DWARF range lists.
const RangePrefix = "go.range."
-// InfoConstPrefix is the prefix for all symbols containing DWARF info
+// ConstInfoPrefix is the prefix for all symbols containing DWARF info
// entries that contain constants.
const ConstInfoPrefix = "go.constinfo."
+// CUInfoPrefix is the prefix for symbols containing information to
+// populate the DWARF compilation unit info entries.
+const CUInfoPrefix = "go.cuinfo."
+
// Sym represents a symbol.
type Sym interface {
Len() int64
// the linker directory. If we move CU construction into the
// compiler, this should happen naturally.
newattr(dwinfo, dwarf.DW_AT_comp_dir, dwarf.DW_CLS_STRING, int64(len(compDir)), compDir)
+ producerExtra := ctxt.Syms.Lookup(dwarf.CUInfoPrefix+"producer."+lib.Pkg, 0)
producer := "Go cmd/compile " + objabi.Version
+ if len(producerExtra.P) > 0 {
+ // We put a semicolon before the flags to clearly
+ // separate them from the version, which can be long
+ // and have lots of weird things in it in development
+ // versions. We promise not to put a semicolon in the
+ // version, so it should be safe for readers to scan
+ // forward to the semicolon.
+ producer += "; " + string(producerExtra.P)
+ }
newattr(dwinfo, dwarf.DW_AT_producer, dwarf.DW_CLS_STRING, int64(len(producer)), producer)
// Write .debug_line Line Number Program Header (sec 6.2.4)