Skip to contentSkip to conversation

RISC-V: Handle R_RISCV_32 in modules

PATCH In review Andreas Schwab 2 participants 4 messages Jun 7, 2018 – Jun 11, 2018 RISC-V

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 RISC-V: Handle R_RISCV_32 in modules

With CONFIG_MODVERSIONS=y the R_RISCV_32 relocation is used by the __kcrctab section.

---
 arch/riscv/kernel/module.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
arch/riscv/kernel/module.c +12 -0
index 5dddba301d..1d5e9b934b 100644
@@ -17,6 +17,17 @@
 #include <linux/errno.h>
 #include <linux/moduleloader.h>
 
+static int apply_r_riscv_32_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+	if (v != (u32)v) {
+		pr_err("%s: value %016llx out of range for 32-bit field\n",
+		       me->name, v);
+		return -EINVAL;
+	}
+	*location = v;
+	return 0;
+}
+
 static int apply_r_riscv_64_rela(struct module *me, u32 *location, Elf_Addr v)
 {
 	*(u64 *)location = v;
@@ -265,6 +276,7 @@ static int apply_r_riscv_sub32_rela(struct module *me, u32 *location,
 
 static int (*reloc_handlers_rela[]) (struct module *me, u32 *location,
 				Elf_Addr v) = {
+	[R_RISCV_32]			= apply_r_riscv_32_rela,
 	[R_RISCV_64]			= apply_r_riscv_64_rela,
 	[R_RISCV_BRANCH]		= apply_r_riscv_branch_rela,
 	[R_RISCV_JAL]			= apply_r_riscv_jal_rela,
Signature · 7 lines
2.17.1


-- 
Andreas Schwab, SUSE Labs, schwab at suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."
#1 lore raw
Quoted 13 lines · schwab at suse.de

With CONFIG_MODVERSIONS=y the R_RISCV_32 relocation is used by the __kcrctab section.

---
 arch/riscv/kernel/module.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
arch/riscv/kernel/module.c +0 -0
index 5dddba301d..1d5e9b934b 100644

arch/riscv/kernel/module.c line 22

Quoted 6 lines
arch/riscv/kernel/module.c +3 -0
@@ -17,6 +17,17 @@
 #include <linux/errno.h>
 #include <linux/moduleloader.h>
 
+static int apply_r_riscv_32_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+	if (v != (u32)v) {

My worry with this kind of check is that it relies on some sort of undefined behavior in C and that at some point in the future GCC will just go decide the check can never fail. I checked and GCC doesn't elide these checks now, so I might be wrong.

Is this defined to do what it looks like it's doing?

Quoted 12 lines
arch/riscv/kernel/module.c +8 -0
+		pr_err("%s: value %016llx out of range for 32-bit field\n",
+		       me->name, v);
+		return -EINVAL;
+	}
+	*location = v;
+	return 0;
+}
+
 static int apply_r_riscv_64_rela(struct module *me, u32 *location, Elf_Addr v)
 {
 	*(u64 *)location = v;

arch/riscv/kernel/module.c static int apply_r_riscv_sub32_rela(struct module *me, u32 *location, · line 282

Quoted 7 lines
arch/riscv/kernel/module.c +1 -0
@@ -265,6 +276,7 @@ static int apply_r_riscv_sub32_rela(struct module *me, u32 *location,
 
 static int (*reloc_handlers_rela[]) (struct module *me, u32 *location,
 				Elf_Addr v) = {
+	[R_RISCV_32]			= apply_r_riscv_32_rela,
 	[R_RISCV_64]			= apply_r_riscv_64_rela,
 	[R_RISCV_BRANCH]		= apply_r_riscv_branch_rela,
 	[R_RISCV_JAL]			= apply_r_riscv_jal_rela,

Thanks!

#2 lore raw
Quoted 26 lines · Palmer Dabbelt
Quoted 13 lines · schwab at suse.de

With CONFIG_MODVERSIONS=y the R_RISCV_32 relocation is used by the __kcrctab section.

---
 arch/riscv/kernel/module.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
arch/riscv/kernel/module.c +0 -0
index 5dddba301d..1d5e9b934b 100644

arch/riscv/kernel/module.c line 22

Quoted 6 lines
arch/riscv/kernel/module.c +3 -0
@@ -17,6 +17,17 @@
 #include <linux/errno.h>
 #include <linux/moduleloader.h>
 
+static int apply_r_riscv_32_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+	if (v != (u32)v) {

My worry with this kind of check is that it relies on some sort of undefined behavior in C and that at some point in the future GCC will just go decide the check can never fail. I checked and GCC doesn't elide these checks now, so I might be wrong.

Quoted 1 line

Is this defined to do what it looks like it's doing?

This is unsigned arithmetic, thus fully defined.

Andreas.

Signature · 3 lines
Andreas Schwab, SUSE Labs, schwab at suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."
#3 lore raw
Quoted 28 lines · schwab at suse.de
Quoted 26 lines · Palmer Dabbelt
Quoted 13 lines · schwab at suse.de

With CONFIG_MODVERSIONS=y the R_RISCV_32 relocation is used by the __kcrctab section.

---
 arch/riscv/kernel/module.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
arch/riscv/kernel/module.c +0 -0
index 5dddba301d..1d5e9b934b 100644

arch/riscv/kernel/module.c line 22

Quoted 6 lines
arch/riscv/kernel/module.c +3 -0
@@ -17,6 +17,17 @@
 #include <linux/errno.h>
 #include <linux/moduleloader.h>
 
+static int apply_r_riscv_32_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+	if (v != (u32)v) {

My worry with this kind of check is that it relies on some sort of undefined behavior in C and that at some point in the future GCC will just go decide the check can never fail. I checked and GCC doesn't elide these checks now, so I might be wrong.

Quoted 3 lines
Quoted 1 line

Is this defined to do what it looks like it's doing?

This is unsigned arithmetic, thus fully defined.

Great, thanks! I guess I'm just a bit paranoid :)