0005-elf2flt-add-riscv-64-bits-support.patch 4.2 KB

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