]> Cypherpunks repositories - gostls13.git/commitdiff
debug/elf: regularize DWARF section loading
authorAustin Clements <austin@google.com>
Wed, 4 Mar 2015 15:58:21 +0000 (10:58 -0500)
committerAustin Clements <austin@google.com>
Tue, 10 Mar 2015 02:32:19 +0000 (02:32 +0000)
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 <r@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/debug/elf/file.go

index 74d1db306c78868111e5b5d882bc372c9b8f9cc8..9f5d5527f361c51acda4f70e217d84ccc4b8a422 100644 (file)
@@ -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
-       }
 
-       // 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)
-               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
+                       }
                }
+               return b, nil
        }
 
-       // 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
+       // 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
                }
-               err = f.applyRelocations(dat[1], data)
+               b, err := sectionData(i, s)
                if err != nil {
                        return nil, err
                }
+               dat[s.Name[7:]] = b
        }
 
-       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