aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Symonds <dsymonds@golang.org>2014-06-04 11:23:24 +1000
committerDavid Symonds <dsymonds@golang.org>2014-06-04 11:23:24 +1000
commitd7f399919e0b916e737f6164375d8702a2722858 (patch)
tree5818c33c665a0eeffbebe794bb8f7ba881f4b817
parent6e3d786dbf90669d2c7027d723057d0d584f7d2d (diff)
downloadgo-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.go58
-rw-r--r--src/pkg/debug/elf/file_test.go6
-rw-r--r--src/pkg/debug/elf/testdata/go-relocation-test-clang-x86.objbin0 -> 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
new file mode 100644
index 0000000000..e909cf4e6e
--- /dev/null
+++ b/src/pkg/debug/elf/testdata/go-relocation-test-clang-x86.obj
Binary files differ