]> Cypherpunks repositories - gostls13.git/commitdiff
debug/elf: add sparc64 relocations
authorJames Clarke <jrtc27@jrtc27.com>
Tue, 11 Oct 2016 18:08:45 +0000 (19:08 +0100)
committerIan Lance Taylor <iant@golang.org>
Tue, 11 Oct 2016 21:52:37 +0000 (21:52 +0000)
Change-Id: I1a2504ad9ca8607588d2d366598115fe360435b5
Reviewed-on: https://go-review.googlesource.com/30870
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/debug/elf/file.go
src/debug/elf/file_test.go
src/debug/elf/testdata/go-relocation-test-gcc620-sparc64.obj [new file with mode: 0644]

index c173ea933169995653bf31e691fc7542dd6cc0d6..c1cbfa6225415ec0d2ce988025e1ba62c8c9b7fc 100644 (file)
@@ -598,6 +598,8 @@ func (f *File) applyRelocations(dst []byte, rels []byte) error {
                return f.applyRelocationsMIPS64(dst, rels)
        case f.Class == ELFCLASS64 && f.Machine == EM_S390:
                return f.applyRelocationss390x(dst, rels)
+       case f.Class == ELFCLASS64 && f.Machine == EM_SPARCV9:
+               return f.applyRelocationsSPARC64(dst, rels)
        default:
                return errors.New("applyRelocations: not implemented")
        }
@@ -962,6 +964,51 @@ func (f *File) applyRelocationss390x(dst []byte, rels []byte) error {
        return nil
 }
 
+func (f *File) applyRelocationsSPARC64(dst []byte, rels []byte) error {
+       // 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)
+       if err != nil {
+               return err
+       }
+
+       b := bytes.NewReader(rels)
+       var rela Rela64
+
+       for b.Len() > 0 {
+               binary.Read(b, f.ByteOrder, &rela)
+               symNo := rela.Info >> 32
+               t := R_SPARC(rela.Info & 0xffff)
+
+               if symNo == 0 || symNo > uint64(len(symbols)) {
+                       continue
+               }
+               sym := &symbols[symNo-1]
+               if SymType(sym.Info&0xf) != STT_SECTION {
+                       // We don't handle non-section relocations for now.
+                       continue
+               }
+
+               switch t {
+               case R_SPARC_64, R_SPARC_UA64:
+                       if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
+                               continue
+                       }
+                       f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend))
+               case R_SPARC_32, R_SPARC_UA32:
+                       if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
+                               continue
+                       }
+                       f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
+               }
+       }
+
+       return nil
+}
+
 func (f *File) DWARF() (*dwarf.Data, error) {
        // sectionData gets the data for s, checks its size, and
        // applies any applicable relations.
index b189219a556a21e8327f9e0869ac5255ff18f62a..f1e28a067159c772cf0249e48520c7f498aec41c 100644 (file)
@@ -491,6 +491,25 @@ var relocationTests = []relocationTest{
                        }},
                },
        },
+       {
+               "testdata/go-relocation-test-gcc620-sparc64.obj",
+               []relocationTestEntry{
+                       {0, &dwarf.Entry{
+                               Offset:   0xb,
+                               Tag:      dwarf.TagCompileUnit,
+                               Children: true,
+                               Field: []dwarf.Field{
+                                       {Attr: dwarf.AttrProducer, Val: "GNU C11 6.2.0 20160914 -mcpu=v9 -g -fstack-protector-strong", Class: dwarf.ClassString},
+                                       {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
+                                       {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
+                                       {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+                                       {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+                                       {Attr: dwarf.AttrHighpc, Val: int64(0x2c), Class: dwarf.ClassConstant},
+                                       {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+                               },
+                       }},
+               },
+       },
        {
                "testdata/go-relocation-test-gcc493-mips64le.obj",
                []relocationTestEntry{
diff --git a/src/debug/elf/testdata/go-relocation-test-gcc620-sparc64.obj b/src/debug/elf/testdata/go-relocation-test-gcc620-sparc64.obj
new file mode 100644 (file)
index 0000000..d65c23e
Binary files /dev/null and b/src/debug/elf/testdata/go-relocation-test-gcc620-sparc64.obj differ