From 4ee347b0ad1e0aa7c917138dd623cffa9b68ebbf Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Wed, 4 Mar 2015 10:58:21 -0500 Subject: [PATCH] debug/elf: regularize DWARF section loading Previously, different DWARF sections had relocations applied in very different ways. .debug_info was relocated, but only on x86-64 and 386 and using hard-coded relocation section names instead of relocation links. .debug_abbrev and .debug_str were never relocated (which is excusable because they shouldn't need it). .debug_types sections were relocated on all architectures and found their relocation section using a relocation link because section names could be ambiguous. Simplify all of this so that every DWARF section that has a linked relocation section gets those relocations applied. This prepares this code to load .debug_line sections without the need for yet more ad hoc relocation logic. Change-Id: Ia00ac8e656b22f22bb31a5f6ef9b0f23cda64d19 Reviewed-on: https://go-review.googlesource.com/6780 Reviewed-by: Rob Pike Reviewed-by: Ian Lance Taylor --- src/debug/elf/file.go | 93 ++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 55 deletions(-) diff --git a/src/debug/elf/file.go b/src/debug/elf/file.go index 74d1db306c7..9f5d5527f36 100644 --- a/src/debug/elf/file.go +++ b/src/debug/elf/file.go @@ -13,6 +13,7 @@ import ( "fmt" "io" "os" + "strings" ) // TODO: error reporting detail @@ -720,53 +721,52 @@ func (f *File) applyRelocationsPPC64(dst []byte, rels []byte) error { } func (f *File) DWARF() (*dwarf.Data, error) { - // There are many other DWARF sections, but these - // are the required ones, and the debug/dwarf package - // does not use the others, so don't bother loading them. - var names = [...]string{"abbrev", "info", "str"} - var dat [len(names)][]byte - for i, name := range names { - name = ".debug_" + name - s := f.Section(name) - if s == nil { - continue - } + // sectionData gets the data for s, checks its size, and + // applies any applicable relations. + sectionData := func(i int, s *Section) ([]byte, error) { b, err := s.Data() if err != nil && uint64(len(b)) < s.Size { return nil, err } - dat[i] = b + + for _, r := range f.Sections { + if r.Type != SHT_RELA && r.Type != SHT_REL { + continue + } + if int(r.Info) != i { + continue + } + rd, err := r.Data() + if err != nil { + return nil, err + } + err = f.applyRelocations(b, rd) + if err != nil { + return nil, err + } + } + return b, nil } - // If there's a relocation table for .debug_info, we have to process it - // now otherwise the data in .debug_info is invalid for x86-64 objects. - rela := f.Section(".rela.debug_info") - if rela != nil && rela.Type == SHT_RELA && (f.Machine == EM_X86_64 || f.Machine == EM_AARCH64 || f.Machine == EM_PPC64) { - data, err := rela.Data() - if err != nil { - return nil, err - } - err = f.applyRelocations(dat[1], data) + // There are many other DWARF sections, but these + // are the required ones, and the debug/dwarf package + // does not use the others, so don't bother loading them. + var dat = map[string][]byte{"abbrev": nil, "info": nil, "str": nil} + for i, s := range f.Sections { + if !strings.HasPrefix(s.Name, ".debug_") { + continue + } + if _, ok := dat[s.Name[7:]]; !ok { + continue + } + b, err := sectionData(i, s) if err != nil { return nil, err } + dat[s.Name[7:]] = b } - // When using clang we need to process relocations even for 386. - rel := f.Section(".rel.debug_info") - if rel != nil && rel.Type == SHT_REL && f.Machine == EM_386 { - data, err := rel.Data() - if err != nil { - return nil, err - } - err = f.applyRelocations(dat[1], data) - if err != nil { - return nil, err - } - } - - abbrev, info, str := dat[0], dat[1], dat[2] - d, err := dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str) + d, err := dwarf.New(dat["abbrev"], nil, nil, dat["info"], nil, nil, nil, dat["str"]) if err != nil { return nil, err } @@ -774,28 +774,11 @@ func (f *File) DWARF() (*dwarf.Data, error) { // Look for DWARF4 .debug_types sections. for i, s := range f.Sections { if s.Name == ".debug_types" { - b, err := s.Data() - if err != nil && uint64(len(b)) < s.Size { + b, err := sectionData(i, s) + if err != nil { return nil, err } - for _, r := range f.Sections { - if r.Type != SHT_RELA && r.Type != SHT_REL { - continue - } - if int(r.Info) != i { - continue - } - rd, err := r.Data() - if err != nil { - return nil, err - } - err = f.applyRelocations(b, rd) - if err != nil { - return nil, err - } - } - err = d.AddTypes(fmt.Sprintf("types-%d", i), b) if err != nil { return nil, err