From 96f6cc15949c27df4fe5df3c5ac9952f37543333 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 12 Apr 2018 16:35:51 +0200 Subject: [PATCH] debug/elf: add riscv64 relocations Based on the code from https://github.com/riscv/riscv-go/ originally written by Amol Bhave. Change-Id: I8d5377096d4ff8b198dadb630511f9a0347f9797 Reviewed-on: https://go-review.googlesource.com/107339 Run-TryBot: Tobias Klauser TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/debug/elf/elf.go | 121 ++++++++++++++++++ src/debug/elf/file.go | 51 ++++++++ src/debug/elf/file_test.go | 19 +++ .../go-relocation-test-gcc720-riscv64.obj | Bin 0 -> 9576 bytes 4 files changed, 191 insertions(+) create mode 100644 src/debug/elf/testdata/go-relocation-test-gcc720-riscv64.obj diff --git a/src/debug/elf/elf.go b/src/debug/elf/elf.go index 6f96b3e3bc..4bf118ec73 100644 --- a/src/debug/elf/elf.go +++ b/src/debug/elf/elf.go @@ -12,6 +12,7 @@ * $FreeBSD: src/sys/powerpc/include/elf.h,v 1.7 2004/11/02 09:47:01 ssouhlal Exp $ * $FreeBSD: src/sys/sparc64/include/elf.h,v 1.12 2003/09/25 01:10:26 peter Exp $ * "ELF for the ARM® 64-bit Architecture (AArch64)" (ARM IHI 0056B) + * "RISC-V ELF psABI specification" (https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md) * * Copyright (c) 1996-1998 John D. Polstra. All rights reserved. * Copyright (c) 2001 David E. O'Brien @@ -237,6 +238,7 @@ const ( EM_TINYJ Machine = 61 /* Advanced Logic Corp. TinyJ processor. */ EM_X86_64 Machine = 62 /* Advanced Micro Devices x86-64 */ EM_AARCH64 Machine = 183 /* ARM 64-bit Architecture (AArch64) */ + EM_RISCV Machine = 243 /* RISC-V */ /* Non-standard or deprecated. */ EM_486 Machine = 6 /* Intel i486. */ @@ -290,6 +292,7 @@ var machineStrings = []intName{ {61, "EM_TINYJ"}, {62, "EM_X86_64"}, {183, "EM_AARCH64"}, + {243, "EM_RISCV"}, /* Non-standard or deprecated. */ {6, "EM_486"}, @@ -2082,6 +2085,124 @@ var rppc64Strings = []intName{ func (i R_PPC64) String() string { return stringName(uint32(i), rppc64Strings, false) } func (i R_PPC64) GoString() string { return stringName(uint32(i), rppc64Strings, true) } +// Relocation types for RISC-V processors. +type R_RISCV int + +const ( + R_RISCV_NONE R_RISCV = 0 /* No relocation. */ + R_RISCV_32 R_RISCV = 1 /* Add 32 bit zero extended symbol value */ + R_RISCV_64 R_RISCV = 2 /* Add 64 bit symbol value. */ + R_RISCV_RELATIVE R_RISCV = 3 /* Add load address of shared object. */ + R_RISCV_COPY R_RISCV = 4 /* Copy data from shared object. */ + R_RISCV_JUMP_SLOT R_RISCV = 5 /* Set GOT entry to code address. */ + R_RISCV_TLS_DTPMOD32 R_RISCV = 6 /* 32 bit ID of module containing symbol */ + R_RISCV_TLS_DTPMOD64 R_RISCV = 7 /* ID of module containing symbol */ + R_RISCV_TLS_DTPREL32 R_RISCV = 8 /* 32 bit relative offset in TLS block */ + R_RISCV_TLS_DTPREL64 R_RISCV = 9 /* Relative offset in TLS block */ + R_RISCV_TLS_TPREL32 R_RISCV = 10 /* 32 bit relative offset in static TLS block */ + R_RISCV_TLS_TPREL64 R_RISCV = 11 /* Relative offset in static TLS block */ + R_RISCV_BRANCH R_RISCV = 16 /* PC-relative branch */ + R_RISCV_JAL R_RISCV = 17 /* PC-relative jump */ + R_RISCV_CALL R_RISCV = 18 /* PC-relative call */ + R_RISCV_CALL_PLT R_RISCV = 19 /* PC-relative call (PLT) */ + R_RISCV_GOT_HI20 R_RISCV = 20 /* PC-relative GOT reference */ + R_RISCV_TLS_GOT_HI20 R_RISCV = 21 /* PC-relative TLS IE GOT offset */ + R_RISCV_TLS_GD_HI20 R_RISCV = 22 /* PC-relative TLS GD reference */ + R_RISCV_PCREL_HI20 R_RISCV = 23 /* PC-relative reference */ + R_RISCV_PCREL_LO12_I R_RISCV = 24 /* PC-relative reference */ + R_RISCV_PCREL_LO12_S R_RISCV = 25 /* PC-relative reference */ + R_RISCV_HI20 R_RISCV = 26 /* Absolute address */ + R_RISCV_LO12_I R_RISCV = 27 /* Absolute address */ + R_RISCV_LO12_S R_RISCV = 28 /* Absolute address */ + R_RISCV_TPREL_HI20 R_RISCV = 29 /* TLS LE thread offset */ + R_RISCV_TPREL_LO12_I R_RISCV = 30 /* TLS LE thread offset */ + R_RISCV_TPREL_LO12_S R_RISCV = 31 /* TLS LE thread offset */ + R_RISCV_TPREL_ADD R_RISCV = 32 /* TLS LE thread usage */ + R_RISCV_ADD8 R_RISCV = 33 /* 8-bit label addition */ + R_RISCV_ADD16 R_RISCV = 34 /* 16-bit label addition */ + R_RISCV_ADD32 R_RISCV = 35 /* 32-bit label addition */ + R_RISCV_ADD64 R_RISCV = 36 /* 64-bit label addition */ + R_RISCV_SUB8 R_RISCV = 37 /* 8-bit label subtraction */ + R_RISCV_SUB16 R_RISCV = 38 /* 16-bit label subtraction */ + R_RISCV_SUB32 R_RISCV = 39 /* 32-bit label subtraction */ + R_RISCV_SUB64 R_RISCV = 40 /* 64-bit label subtraction */ + R_RISCV_GNU_VTINHERIT R_RISCV = 41 /* GNU C++ vtable hierarchy */ + R_RISCV_GNU_VTENTRY R_RISCV = 42 /* GNU C++ vtable member usage */ + R_RISCV_ALIGN R_RISCV = 43 /* Alignment statement */ + R_RISCV_RVC_BRANCH R_RISCV = 44 /* PC-relative branch offset */ + R_RISCV_RVC_JUMP R_RISCV = 45 /* PC-relative jump offset */ + R_RISCV_RVC_LUI R_RISCV = 46 /* Absolute address */ + R_RISCV_GPREL_I R_RISCV = 47 /* GP-relative reference */ + R_RISCV_GPREL_S R_RISCV = 48 /* GP-relative reference */ + R_RISCV_TPREL_I R_RISCV = 49 /* TP-relative TLS LE load */ + R_RISCV_TPREL_S R_RISCV = 50 /* TP-relative TLS LE store */ + R_RISCV_RELAX R_RISCV = 51 /* Instruction pair can be relaxed */ + R_RISCV_SUB6 R_RISCV = 52 /* Local label subtraction */ + R_RISCV_SET6 R_RISCV = 53 /* Local label subtraction */ + R_RISCV_SET8 R_RISCV = 54 /* Local label subtraction */ + R_RISCV_SET16 R_RISCV = 55 /* Local label subtraction */ + R_RISCV_SET32 R_RISCV = 56 /* Local label subtraction */ +) + +var rriscvStrings = []intName{ + {0, "R_RISCV_NONE"}, + {1, "R_RISCV_32"}, + {2, "R_RISCV_64"}, + {3, "R_RISCV_RELATIVE"}, + {4, "R_RISCV_COPY"}, + {5, "R_RISCV_JUMP_SLOT"}, + {6, "R_RISCV_TLS_DTPMOD32"}, + {7, "R_RISCV_TLS_DTPMOD64"}, + {8, "R_RISCV_TLS_DTPREL32"}, + {9, "R_RISCV_TLS_DTPREL64"}, + {10, "R_RISCV_TLS_TPREL32"}, + {11, "R_RISCV_TLS_TPREL64"}, + {16, "R_RISCV_BRANCH"}, + {17, "R_RISCV_JAL"}, + {18, "R_RISCV_CALL"}, + {19, "R_RISCV_CALL_PLT"}, + {20, "R_RISCV_GOT_HI20"}, + {21, "R_RISCV_TLS_GOT_HI20"}, + {22, "R_RISCV_TLS_GD_HI20"}, + {23, "R_RISCV_PCREL_HI20"}, + {24, "R_RISCV_PCREL_LO12_I"}, + {25, "R_RISCV_PCREL_LO12_S"}, + {26, "R_RISCV_HI20"}, + {27, "R_RISCV_LO12_I"}, + {28, "R_RISCV_LO12_S"}, + {29, "R_RISCV_TPREL_HI20"}, + {30, "R_RISCV_TPREL_LO12_I"}, + {31, "R_RISCV_TPREL_LO12_S"}, + {32, "R_RISCV_TPREL_ADD"}, + {33, "R_RISCV_ADD8"}, + {34, "R_RISCV_ADD16"}, + {35, "R_RISCV_ADD32"}, + {36, "R_RISCV_ADD64"}, + {37, "R_RISCV_SUB8"}, + {38, "R_RISCV_SUB16"}, + {39, "R_RISCV_SUB32"}, + {40, "R_RISCV_SUB64"}, + {41, "R_RISCV_GNU_VTINHERIT"}, + {42, "R_RISCV_GNU_VTENTRY"}, + {43, "R_RISCV_ALIGN"}, + {44, "R_RISCV_RVC_BRANCH"}, + {45, "R_RISCV_RVC_JUMP"}, + {46, "R_RISCV_RVC_LUI"}, + {47, "R_RISCV_GPREL_I"}, + {48, "R_RISCV_GPREL_S"}, + {49, "R_RISCV_TPREL_I"}, + {50, "R_RISCV_TPREL_S"}, + {51, "R_RISCV_RELAX"}, + {52, "R_RISCV_SUB6"}, + {53, "R_RISCV_SET6"}, + {54, "R_RISCV_SET8"}, + {55, "R_RISCV_SET16"}, + {56, "R_RISCV_SET32"}, +} + +func (i R_RISCV) String() string { return stringName(uint32(i), rriscvStrings, false) } +func (i R_RISCV) GoString() string { return stringName(uint32(i), rriscvStrings, true) } + // Relocation types for s390x processors. type R_390 int diff --git a/src/debug/elf/file.go b/src/debug/elf/file.go index 95c0606f80..25b72642d8 100644 --- a/src/debug/elf/file.go +++ b/src/debug/elf/file.go @@ -609,6 +609,8 @@ func (f *File) applyRelocations(dst []byte, rels []byte) error { return f.applyRelocationsMIPS(dst, rels) case f.Class == ELFCLASS64 && f.Machine == EM_MIPS: return f.applyRelocationsMIPS64(dst, rels) + case f.Class == ELFCLASS64 && f.Machine == EM_RISCV: + return f.applyRelocationsRISCV64(dst, rels) case f.Class == ELFCLASS64 && f.Machine == EM_S390: return f.applyRelocationss390x(dst, rels) case f.Class == ELFCLASS64 && f.Machine == EM_SPARCV9: @@ -966,6 +968,55 @@ func (f *File) applyRelocationsMIPS64(dst []byte, rels []byte) error { return nil } +func (f *File) applyRelocationsRISCV64(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_RISCV(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_RISCV_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_RISCV_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) applyRelocationss390x(dst []byte, rels []byte) error { // 24 is the size of Rela64. if len(rels)%24 != 0 { diff --git a/src/debug/elf/file_test.go b/src/debug/elf/file_test.go index ce27abb064..880b66e797 100644 --- a/src/debug/elf/file_test.go +++ b/src/debug/elf/file_test.go @@ -567,6 +567,25 @@ var relocationTests = []relocationTest{ }}, }, }, + { + "testdata/go-relocation-test-gcc720-riscv64.obj", + []relocationTestEntry{ + {0, &dwarf.Entry{ + Offset: 0xb, + Tag: dwarf.TagCompileUnit, + Children: true, + Field: []dwarf.Field{ + {Attr: dwarf.AttrProducer, Val: "GNU C11 7.2.0 -march=rv64imafdc -mabi=lp64d -g -gdwarf-2", 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: uint64(0x2c), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + }, + }}, + }, + }, { "testdata/go-relocation-test-clang-x86.obj", []relocationTestEntry{ diff --git a/src/debug/elf/testdata/go-relocation-test-gcc720-riscv64.obj b/src/debug/elf/testdata/go-relocation-test-gcc720-riscv64.obj new file mode 100644 index 0000000000000000000000000000000000000000..91ae6487a3abc3313b48b02afb6fc6b6af5ba50d GIT binary patch literal 9576 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 literal 0 HcmV?d00001 -- 2.50.0