debug/elf: add sparc64 relocations
authorIan Lance Taylor <ian@gcc.gnu.org>
Fri, 14 Oct 2016 17:16:55 +0000 (17:16 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Fri, 14 Oct 2016 17:16:55 +0000 (17:16 +0000)
    This is a backport of https://go-review.googlesource.com/30870.

    Reviewed-on: https://go-review.googlesource.com/30916

From-SVN: r241171

gcc/go/gofrontend/MERGE
libgo/go/debug/elf/file.go
libgo/go/debug/elf/file_test.go
libgo/go/debug/elf/testdata/go-relocation-test-gcc620-sparc64.obj [new file with mode: 0644]

index 769defcc22100f1f8cd42348b73427dd7ee6802a..cadd8ec1b310f7b3c07be6d7e4d48560f4a80e50 100644 (file)
@@ -1,4 +1,4 @@
-5f043fc2bf0f92a84a1f7da57acd79a61c9d2592
+911fceabd4c955b2f29f6b532f241a002ca7ad4f
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
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/libgo/go/debug/elf/testdata/go-relocation-test-gcc620-sparc64.obj b/libgo/go/debug/elf/testdata/go-relocation-test-gcc620-sparc64.obj
new file mode 100644 (file)
index 0000000..d65c23e
Binary files /dev/null and b/libgo/go/debug/elf/testdata/go-relocation-test-gcc620-sparc64.obj differ