2022-04-28 22:55:44 +02:00
|
|
|
From 3879965dfda08a24e7d44ed76bbcc2f4a41df1fa Mon Sep 17 00:00:00 2001
|
2021-10-26 09:17:20 +02:00
|
|
|
From: Damien Le Moal <damien.lemoal@wdc.com>
|
|
|
|
Date: Wed, 9 Sep 2020 17:31:33 +0900
|
|
|
|
Subject: [PATCH] elf2flt: add riscv 64-bits support
|
|
|
|
|
|
|
|
Add support for riscv 64bits ISA by defining the relocation types
|
|
|
|
R_RISCV_32_PCREL, R_RISCV_ADD32, R_RISCV_SUB32, R_RISCV_32 and
|
|
|
|
R_RISCV_64. riscv64 support also needs the __global_pointer$ symbol to
|
|
|
|
be defined right after the relocation tables in the data section.
|
|
|
|
Furthermore, the .got and .got.plt sections must be reversed. These 2
|
|
|
|
requirements are handled with runtime modifications of the default
|
|
|
|
linker script using the append_sed() function.
|
|
|
|
(1) For the .got.plt and .got sections order swap, append_sed() is used
|
|
|
|
to rename "(.got.plt)" to "(.got.tmp)" and to rename "(.got)" to
|
|
|
|
"(.got.plt)". A last call finalize the name swap by replacing
|
|
|
|
"(.got.tmp)" with "(.got)"
|
|
|
|
(2) For the global pointer synbol, a definition line starting with
|
|
|
|
"RISCV_GP" is added. The "RISCV_GP" string is removed if the target CPU
|
|
|
|
type is riscv64. The definition line is dropped for other CPU types.
|
|
|
|
|
|
|
|
With these changes, buildroot/busybox builds and run on NOMMU
|
|
|
|
systems with kernel 5.13. Tested on Canaan Kendryte K210 boards.
|
|
|
|
|
|
|
|
This patch is based on earlier work by Christoph Hellwig <hch@lst.de>.
|
|
|
|
|
|
|
|
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
|
|
|
|
---
|
|
|
|
elf2flt.c | 23 +++++++++++++++++++++++
|
2022-04-28 22:55:44 +02:00
|
|
|
elf2flt.ld.in | 1 +
|
2021-10-26 09:17:20 +02:00
|
|
|
ld-elf2flt.c | 16 ++++++++++++++++
|
2022-04-28 22:55:44 +02:00
|
|
|
3 files changed, 40 insertions(+)
|
2021-10-26 09:17:20 +02:00
|
|
|
|
|
|
|
diff --git a/elf2flt.c b/elf2flt.c
|
2022-04-28 22:55:44 +02:00
|
|
|
index ea6b5a1..7100c20 100644
|
2021-10-26 09:17:20 +02:00
|
|
|
--- a/elf2flt.c
|
|
|
|
+++ b/elf2flt.c
|
2022-04-28 22:55:44 +02:00
|
|
|
@@ -81,6 +81,8 @@ const char *elf2flt_progname;
|
2021-10-26 09:17:20 +02:00
|
|
|
#include <elf/v850.h>
|
|
|
|
#elif defined(TARGET_xtensa)
|
|
|
|
#include <elf/xtensa.h>
|
|
|
|
+#elif defined(TARGET_riscv64)
|
|
|
|
+#include <elf/riscv.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(__MINGW32__)
|
2022-04-28 22:55:44 +02:00
|
|
|
@@ -123,6 +125,8 @@ const char *elf2flt_progname;
|
2021-10-26 09:17:20 +02:00
|
|
|
#define ARCH "nios2"
|
|
|
|
#elif defined(TARGET_xtensa)
|
|
|
|
#define ARCH "xtensa"
|
|
|
|
+#elif defined(TARGET_riscv64)
|
|
|
|
+#define ARCH "riscv64"
|
|
|
|
#else
|
|
|
|
#error "Don't know how to support your CPU architecture??"
|
|
|
|
#endif
|
2022-04-28 22:55:44 +02:00
|
|
|
@@ -821,6 +825,16 @@ output_relocs (
|
2021-10-26 09:17:20 +02:00
|
|
|
goto good_32bit_resolved_reloc;
|
|
|
|
default:
|
|
|
|
goto bad_resolved_reloc;
|
|
|
|
+#elif defined(TARGET_riscv64)
|
|
|
|
+ case R_RISCV_32_PCREL:
|
|
|
|
+ case R_RISCV_ADD32:
|
|
|
|
+ case R_RISCV_SUB32:
|
|
|
|
+ continue;
|
|
|
|
+ case R_RISCV_32:
|
|
|
|
+ case R_RISCV_64:
|
|
|
|
+ goto good_32bit_resolved_reloc;
|
|
|
|
+ default:
|
|
|
|
+ goto bad_resolved_reloc;
|
|
|
|
#else
|
|
|
|
default:
|
|
|
|
/* The default is to assume that the
|
2022-04-28 22:55:44 +02:00
|
|
|
@@ -1841,6 +1855,15 @@ int main(int argc, char *argv[])
|
2021-10-26 09:17:20 +02:00
|
|
|
if (!load_to_ram && !pfile)
|
|
|
|
load_to_ram = 1;
|
|
|
|
|
|
|
|
+#if defined(TARGET_riscv64)
|
|
|
|
+ /*
|
|
|
|
+ * riscv only supports loading text and data contiguously.
|
|
|
|
+ * So fail if load_to_ram is false.
|
|
|
|
+ */
|
|
|
|
+ if (!load_to_ram)
|
|
|
|
+ fatal("Loading to RAM ('-r' option) is required");
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
fname = argv[argc-1];
|
|
|
|
|
|
|
|
if (pfile) {
|
|
|
|
diff --git a/elf2flt.ld.in b/elf2flt.ld.in
|
2022-04-28 22:55:44 +02:00
|
|
|
index 0df999d..f1eed1f 100644
|
2021-10-26 09:17:20 +02:00
|
|
|
--- a/elf2flt.ld.in
|
|
|
|
+++ b/elf2flt.ld.in
|
2022-04-28 22:55:44 +02:00
|
|
|
@@ -109,6 +109,7 @@ W_RODAT: *(.gnu.linkonce.r*)
|
2021-10-26 09:17:20 +02:00
|
|
|
. = ALIGN(0x20) ;
|
|
|
|
LONG(-1)
|
|
|
|
. = ALIGN(0x20) ;
|
|
|
|
+RISCV_GP: __global_pointer$ = . + 0x800 ;
|
2022-04-28 22:55:44 +02:00
|
|
|
R_RODAT: *(.rodata)
|
|
|
|
R_RODAT: *(.rodata1)
|
|
|
|
R_RODAT: *(.rodata.*)
|
2021-10-26 09:17:20 +02:00
|
|
|
diff --git a/ld-elf2flt.c b/ld-elf2flt.c
|
2022-04-28 22:55:44 +02:00
|
|
|
index 7cb02d5..1a503dd 100644
|
2021-10-26 09:17:20 +02:00
|
|
|
--- a/ld-elf2flt.c
|
|
|
|
+++ b/ld-elf2flt.c
|
|
|
|
@@ -324,6 +324,22 @@ static int do_final_link(void)
|
|
|
|
append_option(&other_options, concat(got_offset, "=", buf, NULL));
|
|
|
|
}
|
|
|
|
|
|
|
|
+ if (streq(TARGET_CPU, "riscv64")) {
|
|
|
|
+ /*
|
|
|
|
+ * The .got section must come before the .got.plt section
|
|
|
|
+ * (gcc/ld bug ?).
|
|
|
|
+ */
|
|
|
|
+ append_sed(&sed, "(.got.plt)", "(.got.tmp)");
|
|
|
|
+ append_sed(&sed, "(.got.plt)", "(.got)");
|
|
|
|
+ append_sed(&sed, "(.got.tmp)", "(.got.plt)");
|
|
|
|
+
|
|
|
|
+ /* The global pointer symbol is defined after the GOT. */
|
|
|
|
+ append_sed(&sed, "^RISCV_GP:", "");
|
|
|
|
+ } else {
|
|
|
|
+ /* Get rid of the global pointer definition. */
|
|
|
|
+ append_sed(&sed, "^RISCV_GP:", NULL);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
/* Locate the default linker script, if we don't have one provided. */
|
|
|
|
if (!linker_script)
|
|
|
|
linker_script = concat(ldscriptpath, "/elf2flt.ld", NULL);
|
|
|
|
--
|
2022-04-28 22:55:44 +02:00
|
|
|
2.35.1
|
2021-10-26 09:17:20 +02:00
|
|
|
|