From 0e197515b6b2514a4be25f25e3862b74baa5c9ed Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 3 Jun 2014 16:39:40 -0700 Subject: [PATCH] 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 --- src/pkg/debug/elf/file.go | 58 +++++++++++++++++- src/pkg/debug/elf/file_test.go | 6 ++ .../testdata/go-relocation-test-clang-x86.obj | Bin 0 -> 1900 bytes 3 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 src/pkg/debug/elf/testdata/go-relocation-test-clang-x86.obj 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 @@ -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{ 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 0000000000000000000000000000000000000000..e909cf4e6e19a63276f497b70a170492ade64156 GIT binary patch literal 1900 zcmb7F%W4!s6uq6E@imh%F;PTC11d(yw0S|I5zR(}7=j2QiV%Bd+R2ca?$BKcX5}Uy z;8JkyQgGwS&+s!`>DEO&r@CsoCXf&>+`8w~ee~_>s_GAqRv&ww=Zg_feDN%ST^`EG zyf%|EE~7%6PnUFPH4ibP_DqAIY+2XUL%Ag0sCTnAR`zQnCob1eVqW~(ld*@@dzGci z&>0c`1|}XTm-$;8W-&es>Pb7Pr%^X)hN_dqbrof*-t2~PJ7^+8(4uW` z5$Gy(2P$#_nzzk)cG!s(MiHGou@j{k3Qn|>q}`3?>MGriHzy`@lg>`xom*VEebmG6 zsNNQyrK|o=NeNm}W4pZ`HX3QPBY}$ED+!uOuNR@gppj(~;Dt@p)^Frb+c5QDw6GpOzZE`<(t@7WC?Bqz6j=s5 z2W4+mK9BJ>2T;1uDFP$bw+C)9U7w&!1V*fna~9L}6MB)ri1qP2xc$9Bf9!|-(c1oQ z0oxov`31d1V8r^agS+)wPCXpOe!W+~%;9mNltG^7P>=LcKN_niF}&oYBbGkJoW*n> z7I)sn+2=B@&IBW@LFEB<>+QM3@qGridkRn(_k+NQP5TO-UlO_FZCT_QoMWKlP_FX` z^b6Fj_YE7ngE=dUYbvVz#n#21LVDKg< zci)WM?S`ChSBT#~t@)fU*d&hldgm1rzHsLh;!Cw4K)wtg;P?wT;tOwyLVT<=*O6UO zN9E5x?$;x(|6rAu+d8hQPTZcC0XjEGX9wxbAl2KBca?{q5#PeY(($bEPstyNhe@6* Y4~<=;#Xgy$#U{~zEhOuFEQz)M0D2R@nE(I) literal 0 HcmV?d00001