1
0
mirror of https://github.com/golang/go synced 2024-11-19 02:54:42 -07:00

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 <r@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Austin Clements 2015-03-04 10:58:21 -05:00
parent cc009687bc
commit 4ee347b0ad

View 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
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