xref: /OK3568_Linux_fs/buildroot/package/elf2flt/0004-elf2flt-add-riscv-64-bits-support.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593SmuzhiyunFrom 1dea576eac4289602adc4a37f48c80330bf82e63 Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: Damien Le Moal <damien.lemoal@wdc.com>
3*4882a593SmuzhiyunDate: Wed, 9 Sep 2020 17:31:33 +0900
4*4882a593SmuzhiyunSubject: [PATCH] elf2flt: add riscv 64-bits support
5*4882a593Smuzhiyun
6*4882a593SmuzhiyunAdd support for riscv 64bits ISA by defining the relocation types
7*4882a593SmuzhiyunR_RISCV_32_PCREL, R_RISCV_ADD32, R_RISCV_SUB32, R_RISCV_32 and
8*4882a593SmuzhiyunR_RISCV_64. riscv64 support also needs the __global_pointer$ symbol to
9*4882a593Smuzhiyunbe defined right after the relocation tables in the data section.
10*4882a593SmuzhiyunFurthermore, the .got and .got.plt sections must be reversed. These 2
11*4882a593Smuzhiyunrequirements are handled with runtime modifications of the default
12*4882a593Smuzhiyunlinker script using the append_sed() function.
13*4882a593Smuzhiyun(1) For the .got.plt and .got sections order swap, append_sed() is used
14*4882a593Smuzhiyunto rename "(.got.plt)" to "(.got.tmp)" and to rename "(.got)" to
15*4882a593Smuzhiyun"(.got.plt)". A last call finalize the name swap by replacing
16*4882a593Smuzhiyun"(.got.tmp)" with "(.got)"
17*4882a593Smuzhiyun(2) For the global pointer synbol, a definition line starting with
18*4882a593Smuzhiyun"RISCV_GP" is added. The "RISCV_GP" string is removed if the target CPU
19*4882a593Smuzhiyuntype is riscv64. The definition line is dropped for other CPU types.
20*4882a593Smuzhiyun
21*4882a593SmuzhiyunWith these changes, buildroot/busybox builds and run on NOMMU
22*4882a593Smuzhiyunsystems with kernel 5.13. Tested on Canaan Kendryte K210 boards.
23*4882a593Smuzhiyun
24*4882a593SmuzhiyunThis patch is based on earlier work by Christoph Hellwig <hch@lst.de>.
25*4882a593Smuzhiyun
26*4882a593SmuzhiyunSigned-off-by: Damien Le Moal <damien.lemoal@wdc.com>
27*4882a593Smuzhiyun---
28*4882a593Smuzhiyun elf2flt.c     | 23 +++++++++++++++++++++++
29*4882a593Smuzhiyun elf2flt.ld.in |  9 +++++----
30*4882a593Smuzhiyun ld-elf2flt.c  | 16 ++++++++++++++++
31*4882a593Smuzhiyun 3 files changed, 44 insertions(+), 4 deletions(-)
32*4882a593Smuzhiyun
33*4882a593Smuzhiyundiff --git a/elf2flt.c b/elf2flt.c
34*4882a593Smuzhiyunindex f87f1fc..dbce467 100644
35*4882a593Smuzhiyun--- a/elf2flt.c
36*4882a593Smuzhiyun+++ b/elf2flt.c
37*4882a593Smuzhiyun@@ -80,6 +80,8 @@ const char *elf2flt_progname;
38*4882a593Smuzhiyun #include <elf/v850.h>
39*4882a593Smuzhiyun #elif defined(TARGET_xtensa)
40*4882a593Smuzhiyun #include <elf/xtensa.h>
41*4882a593Smuzhiyun+#elif defined(TARGET_riscv64)
42*4882a593Smuzhiyun+#include <elf/riscv.h>
43*4882a593Smuzhiyun #endif
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun #if defined(__MINGW32__)
46*4882a593Smuzhiyun@@ -122,6 +124,8 @@ const char *elf2flt_progname;
47*4882a593Smuzhiyun #define ARCH	"nios2"
48*4882a593Smuzhiyun #elif defined(TARGET_xtensa)
49*4882a593Smuzhiyun #define ARCH	"xtensa"
50*4882a593Smuzhiyun+#elif defined(TARGET_riscv64)
51*4882a593Smuzhiyun+#define ARCH	"riscv64"
52*4882a593Smuzhiyun #else
53*4882a593Smuzhiyun #error "Don't know how to support your CPU architecture??"
54*4882a593Smuzhiyun #endif
55*4882a593Smuzhiyun@@ -797,6 +801,16 @@ output_relocs (
56*4882a593Smuzhiyun 					goto good_32bit_resolved_reloc;
57*4882a593Smuzhiyun 				default:
58*4882a593Smuzhiyun 					goto bad_resolved_reloc;
59*4882a593Smuzhiyun+#elif defined(TARGET_riscv64)
60*4882a593Smuzhiyun+				case R_RISCV_32_PCREL:
61*4882a593Smuzhiyun+				case R_RISCV_ADD32:
62*4882a593Smuzhiyun+				case R_RISCV_SUB32:
63*4882a593Smuzhiyun+					continue;
64*4882a593Smuzhiyun+				case R_RISCV_32:
65*4882a593Smuzhiyun+				case R_RISCV_64:
66*4882a593Smuzhiyun+					goto good_32bit_resolved_reloc;
67*4882a593Smuzhiyun+				default:
68*4882a593Smuzhiyun+					goto bad_resolved_reloc;
69*4882a593Smuzhiyun #else
70*4882a593Smuzhiyun 				default:
71*4882a593Smuzhiyun 					/* The default is to assume that the
72*4882a593Smuzhiyun@@ -1806,6 +1820,15 @@ int main(int argc, char *argv[])
73*4882a593Smuzhiyun   if (!load_to_ram && !pfile)
74*4882a593Smuzhiyun     load_to_ram = 1;
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun+#if defined(TARGET_riscv64)
77*4882a593Smuzhiyun+  /*
78*4882a593Smuzhiyun+   * riscv only supports loading text and data contiguously.
79*4882a593Smuzhiyun+   * So fail if load_to_ram is false.
80*4882a593Smuzhiyun+   */
81*4882a593Smuzhiyun+  if (!load_to_ram)
82*4882a593Smuzhiyun+    fatal("Loading to RAM ('-r' option) is required");
83*4882a593Smuzhiyun+#endif
84*4882a593Smuzhiyun+
85*4882a593Smuzhiyun   fname = argv[argc-1];
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun   if (pfile) {
88*4882a593Smuzhiyundiff --git a/elf2flt.ld.in b/elf2flt.ld.in
89*4882a593Smuzhiyunindex ec1fe6f..c0c44b8 100644
90*4882a593Smuzhiyun--- a/elf2flt.ld.in
91*4882a593Smuzhiyun+++ b/elf2flt.ld.in
92*4882a593Smuzhiyun@@ -70,10 +70,11 @@ W_RODAT		*(.gnu.linkonce.r*)
93*4882a593Smuzhiyun 		. = ALIGN(0x20) ;
94*4882a593Smuzhiyun 		LONG(-1)
95*4882a593Smuzhiyun 		. = ALIGN(0x20) ;
96*4882a593Smuzhiyun-R_RODAT		*(.rodata)
97*4882a593Smuzhiyun-R_RODAT		*(.rodata1)
98*4882a593Smuzhiyun-R_RODAT		*(.rodata.*)
99*4882a593Smuzhiyun-R_RODAT		*(.gnu.linkonce.r*)
100*4882a593Smuzhiyun+RISCV_GP:	__global_pointer$ = . + 0x800 ;
101*4882a593Smuzhiyun+R_RODAT 	*(.rodata)
102*4882a593Smuzhiyun+R_RODAT 	*(.rodata1)
103*4882a593Smuzhiyun+R_RODAT 	*(.rodata.*)
104*4882a593Smuzhiyun+R_RODAT 	*(.gnu.linkonce.r*)
105*4882a593Smuzhiyun 		*(.data)
106*4882a593Smuzhiyun 		*(.data1)
107*4882a593Smuzhiyun 		*(.data.*)
108*4882a593Smuzhiyundiff --git a/ld-elf2flt.c b/ld-elf2flt.c
109*4882a593Smuzhiyunindex e5de506..31b565f 100644
110*4882a593Smuzhiyun--- a/ld-elf2flt.c
111*4882a593Smuzhiyun+++ b/ld-elf2flt.c
112*4882a593Smuzhiyun@@ -324,6 +324,22 @@ static int do_final_link(void)
113*4882a593Smuzhiyun 		append_option(&other_options, concat(got_offset, "=", buf, NULL));
114*4882a593Smuzhiyun 	}
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun+	if (streq(TARGET_CPU, "riscv64")) {
117*4882a593Smuzhiyun+		/*
118*4882a593Smuzhiyun+		 * The .got section must come before the .got.plt section
119*4882a593Smuzhiyun+		 * (gcc/ld bug ?).
120*4882a593Smuzhiyun+		 */
121*4882a593Smuzhiyun+		append_sed(&sed, "(.got.plt)", "(.got.tmp)");
122*4882a593Smuzhiyun+		append_sed(&sed, "(.got.plt)", "(.got)");
123*4882a593Smuzhiyun+		append_sed(&sed, "(.got.tmp)", "(.got.plt)");
124*4882a593Smuzhiyun+
125*4882a593Smuzhiyun+		/* The global pointer symbol is defined after the GOT. */
126*4882a593Smuzhiyun+		append_sed(&sed, "^RISCV_GP:", "");
127*4882a593Smuzhiyun+	} else {
128*4882a593Smuzhiyun+		/* Get rid of the global pointer definition. */
129*4882a593Smuzhiyun+		append_sed(&sed, "^RISCV_GP:", NULL);
130*4882a593Smuzhiyun+	}
131*4882a593Smuzhiyun+
132*4882a593Smuzhiyun 	/* Locate the default linker script, if we don't have one provided. */
133*4882a593Smuzhiyun 	if (!linker_script)
134*4882a593Smuzhiyun 		linker_script = concat(ldscriptpath, "/elf2flt.ld", NULL);
135*4882a593Smuzhiyun--
136*4882a593Smuzhiyun2.31.1
137*4882a593Smuzhiyun
138