From 4cfcb4a04bc140da0ad196b1b9cab32bde8f2a62 Mon Sep 17 00:00:00 2001 From: Joel Sing Date: Fri, 7 Sep 2012 13:32:40 +1000 Subject: [PATCH] cgo: use debug data section for ELF When generating enums use the debug data section instead of the DWARF debug info, if it is available in the ELF file. This allows mkerrors.sh to work correctly on OpenBSD/386 and NetBSD/386. Fixes #2470. R=golang-dev, minux.ma CC=golang-dev https://golang.org/cl/6495090 --- src/cmd/cgo/gcc.go | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/cmd/cgo/gcc.go b/src/cmd/cgo/gcc.go index 18be64fc7c..2aaa570d83 100644 --- a/src/cmd/cgo/gcc.go +++ b/src/cmd/cgo/gcc.go @@ -616,15 +616,16 @@ func (p *Package) loadDWARF(f *File, names []*Name) { n.FuncType = conv.FuncType(f, pos) } else { n.Type = conv.Type(types[i], pos) - if enums[i] != 0 && n.Type.EnumValues != nil { + // Prefer debug data over DWARF debug output, if we have it. + if n.Kind == "const" && i < len(enumVal) { + n.Const = fmt.Sprintf("%#x", enumVal[i]) + } else if enums[i] != 0 && n.Type.EnumValues != nil { k := fmt.Sprintf("__cgo_enum__%d", i) n.Kind = "const" n.Const = fmt.Sprintf("%#x", n.Type.EnumValues[k]) // Remove injected enum to ensure the value will deep-compare // equally in future loads of the same constant. delete(n.Type.EnumValues, k) - } else if n.Kind == "const" && i < len(enumVal) { - n.Const = fmt.Sprintf("%#x", enumVal[i]) } } } @@ -802,17 +803,35 @@ func (p *Package) gccDebug(stdin []byte) (*dwarf.Data, binary.ByteOrder, []byte) return d, f.ByteOrder, data } - // Can skip debug data block in ELF and PE for now. - // The DWARF information is complete. - if f, err := elf.Open(gccTmp()); err == nil { d, err := f.DWARF() if err != nil { fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) } - return d, f.ByteOrder, nil + var data []byte + symtab, err := f.Symbols() + if err == nil { + for i := range symtab { + s := &symtab[i] + if s.Name == "__cgodebug_data" { + // Found it. Now find data section. + if i := int(s.Section); 0 <= i && i < len(f.Sections) { + sect := f.Sections[i] + if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { + if sdat, err := sect.Data(); err == nil { + data = sdat[s.Value-sect.Addr:] + } + } + } + } + } + } + return d, f.ByteOrder, data } + // Can skip debug data block in PE for now. + // The DWARF information is complete. + if f, err := pe.Open(gccTmp()); err == nil { d, err := f.DWARF() if err != nil { -- 2.48.1