65d78dcfeb
It contains several fixes and improvements compared to our current version, and two of our patches have been accepted upstream. Most notably, it fixes the issue we had in using elf2flt with recent versions of binutils (upstream commit ba379d08bb78c9300e84351c11080c26ddcc36b3). Patch 0001-ld-elf2flt-behave-properly-when-called-with-a-name-d.patch is upstream as of commit 1c9b454336eaf38f7d037917a3120fae04193fbe Patch 0002-elf2flt.c-add-new-relocation-types-for-xtensa.patch is upstream as of commit d7eb73163bcea31168c438fc132a0967ac172e3d The other two patches are refreshed to apply properly on 2021.08. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com> Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
130 lines
4.0 KiB
Diff
130 lines
4.0 KiB
Diff
From 3879965dfda08a24e7d44ed76bbcc2f4a41df1fa Mon Sep 17 00:00:00 2001
|
|
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 +++++++++++++++++++++++
|
|
elf2flt.ld.in | 1 +
|
|
ld-elf2flt.c | 16 ++++++++++++++++
|
|
3 files changed, 40 insertions(+)
|
|
|
|
diff --git a/elf2flt.c b/elf2flt.c
|
|
index ea6b5a1..7100c20 100644
|
|
--- a/elf2flt.c
|
|
+++ b/elf2flt.c
|
|
@@ -81,6 +81,8 @@ const char *elf2flt_progname;
|
|
#include <elf/v850.h>
|
|
#elif defined(TARGET_xtensa)
|
|
#include <elf/xtensa.h>
|
|
+#elif defined(TARGET_riscv64)
|
|
+#include <elf/riscv.h>
|
|
#endif
|
|
|
|
#if defined(__MINGW32__)
|
|
@@ -123,6 +125,8 @@ const char *elf2flt_progname;
|
|
#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
|
|
@@ -821,6 +825,16 @@ output_relocs (
|
|
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
|
|
@@ -1841,6 +1855,15 @@ int main(int argc, char *argv[])
|
|
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
|
|
index 0df999d..f1eed1f 100644
|
|
--- a/elf2flt.ld.in
|
|
+++ b/elf2flt.ld.in
|
|
@@ -109,6 +109,7 @@ W_RODAT: *(.gnu.linkonce.r*)
|
|
. = ALIGN(0x20) ;
|
|
LONG(-1)
|
|
. = ALIGN(0x20) ;
|
|
+RISCV_GP: __global_pointer$ = . + 0x800 ;
|
|
R_RODAT: *(.rodata)
|
|
R_RODAT: *(.rodata1)
|
|
R_RODAT: *(.rodata.*)
|
|
diff --git a/ld-elf2flt.c b/ld-elf2flt.c
|
|
index 7cb02d5..1a503dd 100644
|
|
--- 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);
|
|
--
|
|
2.35.1
|
|
|