diff options
author | David Symonds <dsymonds@golang.org> | 2014-06-04 11:23:24 +1000 |
---|---|---|
committer | David Symonds <dsymonds@golang.org> | 2014-06-04 11:23:24 +1000 |
commit | d7f399919e0b916e737f6164375d8702a2722858 (patch) | |
tree | 5818c33c665a0eeffbebe794bb8f7ba881f4b817 | |
parent | 6e3d786dbf90669d2c7027d723057d0d584f7d2d (diff) | |
download | go-d7f399919e0b916e737f6164375d8702a2722858.tar.gz go-d7f399919e0b916e737f6164375d8702a2722858.zip |
[release-branch.go1.3] debug/elf: support DWARF that needs relocs for 386
««« CL 96680045 / 5439c77d4acb
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
»»»
LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/102140043
-rw-r--r-- | src/pkg/debug/elf/file.go | 58 | ||||
-rw-r--r-- | src/pkg/debug/elf/file_test.go | 6 | ||||
-rw-r--r-- | src/pkg/debug/elf/testdata/go-relocation-test-clang-x86.obj | bin | 0 -> 1900 bytes |
3 files changed, 62 insertions, 2 deletions
diff --git a/src/pkg/debug/elf/file.go b/src/pkg/debug/elf/file.go index 2840f07674..423932fe0f 100644 --- a/src/pkg/debug/elf/file.go +++ b/src/pkg/debug/elf/file.go @@ -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 { diff --git a/src/pkg/debug/elf/file_test.go b/src/pkg/debug/elf/file_test.go index 38b5f9e707..7f88a54bcd 100644 --- a/src/pkg/debug/elf/file_test.go +++ b/src/pkg/debug/elf/file_test.go @@ -261,6 +261,12 @@ var relocationTests = []relocationTest{ }, }, { + "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{ {203, &dwarf.Entry{Offset: 0xc62, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{{Attr: dwarf.AttrName, Val: "it_interval"}, {Attr: dwarf.AttrDeclFile, Val: int64(7)}, {Attr: dwarf.AttrDeclLine, Val: int64(236)}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f)}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}}}}}, diff --git a/src/pkg/debug/elf/testdata/go-relocation-test-clang-x86.obj b/src/pkg/debug/elf/testdata/go-relocation-test-clang-x86.obj Binary files differnew file mode 100644 index 0000000000..e909cf4e6e --- /dev/null +++ b/src/pkg/debug/elf/testdata/go-relocation-test-clang-x86.obj |