aboutsummaryrefslogtreecommitdiff
path: root/src/debug/elf/file.go
diff options
context:
space:
mode:
authorMichael Munday <munday@ca.ibm.com>2016-03-18 17:24:18 -0400
committerMinux Ma <minux@golang.org>2016-03-29 16:48:09 +0000
commit12fb62a57db6a34c4ba0162ac970724d60dbbfbb (patch)
tree78bfb5b66b836be599a791ed5f06e2aacb9f3cde /src/debug/elf/file.go
parentd0fb649713e6435cb854fcb202c6979c8a137c0b (diff)
downloadgo-12fb62a57db6a34c4ba0162ac970724d60dbbfbb.tar.xz
debug/elf: add s390x relocations
Change-Id: I8440f69c7f99d65b2f69035c26b4a62104f22bd3 Reviewed-on: https://go-review.googlesource.com/20874 Reviewed-by: Minux Ma <minux@golang.org>
Diffstat (limited to 'src/debug/elf/file.go')
-rw-r--r--src/debug/elf/file.go51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/debug/elf/file.go b/src/debug/elf/file.go
index 72796d535f..c28a964b73 100644
--- a/src/debug/elf/file.go
+++ b/src/debug/elf/file.go
@@ -596,6 +596,8 @@ func (f *File) applyRelocations(dst []byte, rels []byte) error {
return f.applyRelocationsPPC64(dst, rels)
case f.Class == ELFCLASS64 && f.Machine == EM_MIPS:
return f.applyRelocationsMIPS64(dst, rels)
+ case f.Class == ELFCLASS64 && f.Machine == EM_S390:
+ return f.applyRelocationss390x(dst, rels)
default:
return errors.New("applyRelocations: not implemented")
}
@@ -911,6 +913,55 @@ func (f *File) applyRelocationsMIPS64(dst []byte, rels []byte) error {
return nil
}
+func (f *File) applyRelocationss390x(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_390(rela.Info & 0xffff)
+
+ if symNo == 0 || symNo > uint64(len(symbols)) {
+ continue
+ }
+ sym := &symbols[symNo-1]
+ switch SymType(sym.Info & 0xf) {
+ case STT_SECTION, STT_NOTYPE:
+ break
+ default:
+ continue
+ }
+
+ switch t {
+ case R_390_64:
+ if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
+ continue
+ }
+ val := sym.Value + uint64(rela.Addend)
+ f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val)
+ case R_390_32:
+ if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
+ continue
+ }
+ val := uint32(sym.Value) + uint32(rela.Addend)
+ f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val)
+ }
+ }
+
+ return nil
+}
+
func (f *File) DWARF() (*dwarf.Data, error) {
// sectionData gets the data for s, checks its size, and
// applies any applicable relations.