mirror of
https://github.com/golang/go
synced 2024-11-19 05:24: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:
parent
cc009687bc
commit
4ee347b0ad
@ -13,6 +13,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// TODO: error reporting detail
|
||||
@ -720,60 +721,9 @@ 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
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Look for DWARF4 .debug_types sections.
|
||||
for i, s := range f.Sections {
|
||||
if s.Name == ".debug_types" {
|
||||
// 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
|
||||
@ -795,6 +745,39 @@ func (f *File) DWARF() (*dwarf.Data, error) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
d, err := dwarf.New(dat["abbrev"], nil, nil, dat["info"], nil, nil, nil, dat["str"])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Look for DWARF4 .debug_types sections.
|
||||
for i, s := range f.Sections {
|
||||
if s.Name == ".debug_types" {
|
||||
b, err := sectionData(i, s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = d.AddTypes(fmt.Sprintf("types-%d", i), b)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user