mirror of
https://github.com/golang/go.git
synced 2024-09-22 10:58:58 +00:00
debug/elf: support DWARF that needs relocs for 386
It's not clear how widespread this issue is, but we do have a test case generated by a development version of clang. I don't know whether this should go into 1.3 or not; happy to hear arguments either way. LGTM=rsc R=golang-codereviews, bradfitz, rsc CC=golang-codereviews https://golang.org/cl/96680045
This commit is contained in:
parent
68bbf9d464
commit
0e197515b6
@ -522,13 +522,17 @@ func (f *File) applyRelocations(dst []byte, rels []byte) error {
|
||||
if f.Class == ELFCLASS64 && f.Machine == EM_X86_64 {
|
||||
return f.applyRelocationsAMD64(dst, rels)
|
||||
}
|
||||
if f.Class == ELFCLASS32 && f.Machine == EM_386 {
|
||||
return f.applyRelocations386(dst, rels)
|
||||
}
|
||||
|
||||
return errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
|
||||
if len(rels)%Sym64Size != 0 {
|
||||
return errors.New("length of relocation section is not a multiple of Sym64Size")
|
||||
// 24 is the size of Rela64.
|
||||
if len(rels)%24 != 0 {
|
||||
return errors.New("length of relocation section is not a multiple of 24")
|
||||
}
|
||||
|
||||
symbols, _, err := f.getSymbols(SHT_SYMTAB)
|
||||
@ -570,6 +574,43 @@ func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *File) applyRelocations386(dst []byte, rels []byte) error {
|
||||
// 8 is the size of Rel32.
|
||||
if len(rels)%8 != 0 {
|
||||
return errors.New("length of relocation section is not a multiple of 8")
|
||||
}
|
||||
|
||||
symbols, _, err := f.getSymbols(SHT_SYMTAB)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b := bytes.NewReader(rels)
|
||||
var rel Rel32
|
||||
|
||||
for b.Len() > 0 {
|
||||
binary.Read(b, f.ByteOrder, &rel)
|
||||
symNo := rel.Info >> 8
|
||||
t := R_386(rel.Info & 0xff)
|
||||
|
||||
if symNo == 0 || symNo > uint32(len(symbols)) {
|
||||
continue
|
||||
}
|
||||
sym := &symbols[symNo-1]
|
||||
|
||||
if t == R_386_32 {
|
||||
if rel.Off+4 >= uint32(len(dst)) {
|
||||
continue
|
||||
}
|
||||
val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4])
|
||||
val += uint32(sym.Value)
|
||||
f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *File) DWARF() (*dwarf.Data, error) {
|
||||
// There are many other DWARF sections, but these
|
||||
// are the required ones, and the debug/dwarf package
|
||||
@ -603,6 +644,19 @@ func (f *File) DWARF() (*dwarf.Data, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
|
@ -260,6 +260,12 @@ var relocationTests = []relocationTest{
|
||||
{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
|
||||
},
|
||||
},
|
||||
{
|
||||
"testdata/go-relocation-test-clang-x86.obj",
|
||||
[]relocationTestEntry{
|
||||
{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "clang version google3-trunk (trunk r209387)"}, {Attr: dwarf.AttrLanguage, Val: int64(12)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-clang.c"}, {Attr: dwarf.AttrStmtList, Val: int64(0)}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}}}},
|
||||
},
|
||||
},
|
||||
{
|
||||
"testdata/gcc-amd64-openbsd-debug-with-rela.obj",
|
||||
[]relocationTestEntry{
|
||||
|
BIN
src/pkg/debug/elf/testdata/go-relocation-test-clang-x86.obj
vendored
Normal file
BIN
src/pkg/debug/elf/testdata/go-relocation-test-clang-x86.obj
vendored
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user