Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115444585
D38301.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D38301.diff
View Options
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
@@ -225,9 +225,9 @@
rel->r_info = ELF32_R_INFO(count + dep->de_global,
R_PPC_REL32);
#elif defined(__riscv)
-/* XXX */
- printf("%s:%s(%d): RISC-V not implemented\n",
- __FUNCTION__, __FILE__, __LINE__);
+ rel->r_offset = s->dofs_offset + dofr[j].dofr_offset;
+ rel->r_info = ELF32_R_INFO(count + dep->de_global,
+ R_RISCV_32_PCREL);
#else
#error unknown ISA
#endif
@@ -403,7 +403,9 @@
rel->r_info = ELF64_R_INFO(count + dep->de_global,
R_PPC64_REL64);
#elif defined(__riscv)
-/* XXX */
+ rel->r_offset = s->dofs_offset + dofr[j].dofr_offset;
+ rel->r_info = ELF64_R_INFO(count + dep->de_global,
+ R_RISCV_32_PCREL);
#elif defined(__i386) || defined(__amd64)
rel->r_offset = s->dofs_offset +
dofr[j].dofr_offset;
@@ -504,6 +506,22 @@
elf_file.ehdr.e_machine = EM_386;
#elif defined(__aarch64__)
elf_file.ehdr.e_machine = EM_AARCH64;
+#elif defined(__riscv)
+ elf_file.ehdr.e_machine = EM_RISCV;
+
+ /* Set the ELF flags according to our current ABI */
+#if defined(__riscv_compressed)
+ elf_file.ehdr.e_flags |= EF_RISCV_RVC;
+#endif
+#if defined(__riscv_float_abi_soft)
+ elf_file.ehdr.e_flags |= EF_RISCV_FLOAT_ABI_SOFT;
+#endif
+#if defined(__riscv_float_abi_single)
+ elf_file.ehdr.e_flags |= EF_RISCV_FLOAT_ABI_SINGLE;
+#endif
+#if defined(__riscv_float_abi_double)
+ elf_file.ehdr.e_flags |= EF_RISCV_FLOAT_ABI_DOUBLE;
+#endif
#endif
elf_file.ehdr.e_version = EV_CURRENT;
elf_file.ehdr.e_shoff = sizeof (Elf32_Ehdr);
@@ -645,6 +663,22 @@
elf_file.ehdr.e_machine = EM_AMD64;
#elif defined(__aarch64__)
elf_file.ehdr.e_machine = EM_AARCH64;
+#elif defined(__riscv)
+ elf_file.ehdr.e_machine = EM_RISCV;
+
+ /* Set the ELF flags according to our current ABI */
+#if defined(__riscv_compressed)
+ elf_file.ehdr.e_flags |= EF_RISCV_RVC;
+#endif
+#if defined(__riscv_float_abi_soft)
+ elf_file.ehdr.e_flags |= EF_RISCV_FLOAT_ABI_SOFT;
+#endif
+#if defined(__riscv_float_abi_single)
+ elf_file.ehdr.e_flags |= EF_RISCV_FLOAT_ABI_SINGLE;
+#endif
+#if defined(__riscv_float_abi_double)
+ elf_file.ehdr.e_flags |= EF_RISCV_FLOAT_ABI_DOUBLE;
+#endif
#endif
elf_file.ehdr.e_version = EV_CURRENT;
elf_file.ehdr.e_shoff = sizeof (Elf64_Ehdr);
@@ -917,14 +951,74 @@
return (0);
}
#elif defined(__riscv)
+#define DT_OP_NOP 0x00000013 /* addi x0, x0, 0 */
+#define DT_OP_RET 0x00008067 /* jalr x0, x1, 0 */
+#define DT_OP_IS_AUIPC(op) (((op) & 0x7f) == 0x17)
+#define DT_OP_IS_JALR(op) (((op) & 0x707f) == 0x67)
+#define DT_OP_JALR_CALL 0x000080e7 /* jalr x1, x1, 0 */
+#define DT_OP_JALR_TAIL 0x00030067 /* jalr x0, x6, 0 */
#define DT_REL_NONE R_RISCV_NONE
+
static int
dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
uint32_t *off)
{
- printf("%s:%s(%d): RISC-V implementation required\n", __FUNCTION__,
- __FILE__, __LINE__);
- return (-1);
+ uint32_t *ip;
+
+ /*
+ * XXX: this implementation is untested, but should serve as a decent
+ * starting point.
+ */
+
+ /*
+ * Ensure that the offset is aligned on a compressed-instruction
+ * boundary.
+ */
+ if ((rela->r_offset & (sizeof (uint16_t) - 1)) != 0)
+ return (-1);
+
+ /*
+ * We only know about some specific relocation types.
+ * We also recognize relocation type NONE, since that gets used for
+ * relocations of USDT probes, and we might be re-processing a file.
+ */
+ if (GELF_R_TYPE(rela->r_info) != R_RISCV_CALL &&
+ GELF_R_TYPE(rela->r_info) != R_RISCV_CALL_PLT &&
+ GELF_R_TYPE(rela->r_info) != R_RISCV_NONE)
+ return (-1);
+
+ ip = (uint32_t *)(p + rela->r_offset);
+
+ /*
+ * We may have already processed this object file in an earlier linker
+ * invocation. Check to see if the present instruction sequence matches
+ * the one we would install below.
+ */
+ if (ip[0] == DT_OP_NOP && (ip[1] == DT_OP_NOP || ip[1] == DT_OP_RET))
+ return (0);
+
+ /*
+ * We expect a auipc+jalr pair, either from a call or a tail.
+ * - call: auipc x1 0; jalr x1, x1, 0
+ * - tail: auipc x6 0; jalr x0, x6, 0
+ */
+ if (!DT_OP_IS_AUIPC(ip[0]) || !DT_OP_IS_JALR(ip[1]))
+ return (-1);
+
+ /*
+ * On riscv, we do not have to differentiate between regular probes and
+ * is-enabled probes. Calls are to be converted into a no-op whereas
+ * tail calls should become a return.
+ */
+ if (ip[1] == DT_OP_JALR_CALL) {
+ ip[0] = DT_OP_NOP;
+ ip[1] = DT_OP_NOP;
+ } else {
+ ip[0] = DT_OP_NOP;
+ ip[1] = DT_OP_RET;
+ }
+
+ return (0);
}
#elif defined(__i386) || defined(__amd64)
@@ -1155,6 +1249,8 @@
emachine1 = emachine2 = EM_AMD64;
#elif defined(__aarch64__)
emachine1 = emachine2 = EM_AARCH64;
+#elif defined(__riscv)
+ emachine1 = emachine2 = EM_RISCV;
#endif
symsize = sizeof (Elf64_Sym);
} else {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Apr 24, 9:59 PM (17 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17767780
Default Alt Text
D38301.diff (4 KB)
Attached To
Mode
D38301: libdtrace: add riscv support
Attached
Detach File
Event Timeline
Log In to Comment