From ba48db8275730fbc512c0872ae426970a09b5619 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Thu, 22 Sep 2022 14:03:07 +0200 Subject: add support for STM32F746G-DISCO device Tested with toolbox / simpleinit as userland. FDPIC/FLAT support both successfully tested. No LCD or Ethernet support. --- .../0001-elf2flt-handle-binutils-2.34.patch | 377 +++++++++++++++++++++ ...reinstate-32-byte-alignment-for-.data-sec.patch | 81 +++++ .../0003-elf2flt-add-riscv-64-bits-support.patch | 103 ++++++ ...4-elf2flt-create-a-common-helper-function.patch | 76 +++++ ...-fatal-error-regression-on-m68k-xtensa-ri.patch | 73 ++++ 5 files changed, 710 insertions(+) create mode 100644 toolchain/elf2flt/patches/v2021.08/0001-elf2flt-handle-binutils-2.34.patch create mode 100644 toolchain/elf2flt/patches/v2021.08/0002-elf2flt.ld-reinstate-32-byte-alignment-for-.data-sec.patch create mode 100644 toolchain/elf2flt/patches/v2021.08/0003-elf2flt-add-riscv-64-bits-support.patch create mode 100644 toolchain/elf2flt/patches/v2021.08/0004-elf2flt-create-a-common-helper-function.patch create mode 100644 toolchain/elf2flt/patches/v2021.08/0005-elf2flt-fix-fatal-error-regression-on-m68k-xtensa-ri.patch (limited to 'toolchain/elf2flt/patches') diff --git a/toolchain/elf2flt/patches/v2021.08/0001-elf2flt-handle-binutils-2.34.patch b/toolchain/elf2flt/patches/v2021.08/0001-elf2flt-handle-binutils-2.34.patch new file mode 100644 index 000000000..4aa473c24 --- /dev/null +++ b/toolchain/elf2flt/patches/v2021.08/0001-elf2flt-handle-binutils-2.34.patch @@ -0,0 +1,377 @@ +From d78acba6510527aaa01a41eaf4c931f7a57e5f44 Mon Sep 17 00:00:00 2001 +From: Romain Naour +Date: Wed, 5 Feb 2020 10:31:32 +0100 +Subject: [PATCH] elf2flt: handle binutils >= 2.34 + +The latest Binutils release (2.34) is not compatible with elf2flt due +to a change in bfd_section_* macros [1]. The issue has been reported +to the Binutils mailing list but Alan Modra recommend to bundle +libbfd library sources into each projects using it [2]. That's +because the API is not stable over the time without any backward +compatibility guaranties. + +On the other hand, the elf2flt tools needs to support modified +version of binutils for specific arch/target [3]. + +Add two tests in the configure script to detect this API change +in order to support binutils < 2.34 and binutils >= 2.34. + +Upstream status: [4] + +[1] https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=fd3619828e94a24a92cddec42cbc0ab33352eeb4 +[2] https://sourceware.org/ml/binutils/2020-02/msg00044.html +[3] https://github.com/uclinux-dev/elf2flt/issues/14 +[4] https://github.com/uclinux-dev/elf2flt/pull/15 + +Signed-off-by: Romain Naour +--- + configure.ac | 16 +++++++++++ + elf2flt.c | 81 +++++++++++++++++++++++++++++----------------------- + 2 files changed, 61 insertions(+), 36 deletions(-) + +diff --git a/configure.ac b/configure.ac +index b7db2cb..fdc0876 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -229,6 +229,22 @@ AC_CHECK_FUNCS([ \ + strsignal \ + ]) + ++dnl Various bfd section macros and functions like bfd_section_size() have been ++dnl modified starting with binutils >= 2.34. ++dnl Check if the prototypes take a bfd argument. ++if test "$binutils_build_dir" != "NONE"; then ++ CFLAGS="-I$binutils_include_dir -I$bfd_include_dir $CFLAGS" ++fi ++ ++AC_TRY_COMPILE([#include ], ++ [const asection *sec; bfd_section_size(sec);], ++ bfd_section_api_takes_bfd=no, ++ bfd_section_api_takes_bfd=yes) ++if test "$bfd_section_api_takes_bfd" = "yes" ; then ++ AC_DEFINE(HAVE_BFD_SECTION_API_TAKES_BFD, 1, ++ [define to 1 for binutils < 2.34]) ++fi ++ + if test "$GCC" = yes ; then + CFLAGS="-Wall $CFLAGS" + if test "$werror" = 1 ; then +diff --git a/elf2flt.c b/elf2flt.c +index 7ac0617..ea6b5a1 100644 +--- a/elf2flt.c ++++ b/elf2flt.c +@@ -149,6 +149,17 @@ const char *elf2flt_progname; + #define O_BINARY 0 + #endif + ++/* ++ * The bfd parameter isn't actually used by any of the bfd_section funcs and ++ * have been removed since binutils 2.34. ++ */ ++#ifdef HAVE_BFD_SECTION_API_TAKES_BFD ++#define elf2flt_bfd_section_size(s) bfd_section_size(NULL, s) ++#define elf2flt_bfd_section_vma(s) bfd_section_vma(NULL, s) ++#else ++#define elf2flt_bfd_section_size(s) bfd_section_size(s) ++#define elf2flt_bfd_section_vma(s) bfd_section_vma(s) ++#endif + + /* Extra output when running. */ + static int verbose = 0; +@@ -323,10 +334,8 @@ compare_relocs (const void *pa, const void *pb) + else if (!rb->sym_ptr_ptr || !*rb->sym_ptr_ptr) + return 1; + +- a_vma = bfd_section_vma(compare_relocs_bfd, +- (*(ra->sym_ptr_ptr))->section); +- b_vma = bfd_section_vma(compare_relocs_bfd, +- (*(rb->sym_ptr_ptr))->section); ++ a_vma = elf2flt_bfd_section_vma((*(ra->sym_ptr_ptr))->section); ++ b_vma = elf2flt_bfd_section_vma((*(rb->sym_ptr_ptr))->section); + va = (*(ra->sym_ptr_ptr))->value + a_vma + ra->addend; + vb = (*(rb->sym_ptr_ptr))->value + b_vma + rb->addend; + return va - vb; +@@ -403,7 +412,7 @@ output_relocs ( + } + + for (a = abs_bfd->sections; (a != (asection *) NULL); a = a->next) { +- section_vma = bfd_section_vma(abs_bfd, a); ++ section_vma = elf2flt_bfd_section_vma(a); + + if (verbose) + printf("SECTION: %s [%p]: flags=0x%x vma=0x%"PRIx32"\n", +@@ -443,7 +452,7 @@ output_relocs ( + continue; + if (verbose) + printf(" RELOCS: %s [%p]: flags=0x%x vma=0x%"BFD_VMA_FMT"x\n", +- r->name, r, r->flags, bfd_section_vma(abs_bfd, r)); ++ r->name, r, r->flags, elf2flt_bfd_section_vma(r)); + if ((r->flags & SEC_RELOC) == 0) + continue; + relsize = bfd_get_reloc_upper_bound(rel_bfd, r); +@@ -695,7 +704,7 @@ output_relocs ( + case R_BFIN_RIMM16: + case R_BFIN_LUIMM16: + case R_BFIN_HUIMM16: +- sym_vma = bfd_section_vma(abs_bfd, sym_section); ++ sym_vma = elf2flt_bfd_section_vma(sym_section); + sym_addr += sym_vma + q->addend; + + if (weak_und_symbol(sym_section->name, (*(q->sym_ptr_ptr)))) +@@ -728,7 +737,7 @@ output_relocs ( + break; + + case R_BFIN_BYTE4_DATA: +- sym_vma = bfd_section_vma(abs_bfd, sym_section); ++ sym_vma = elf2flt_bfd_section_vma(sym_section); + sym_addr += sym_vma + q->addend; + + if (weak_und_symbol (sym_section->name, (*(q->sym_ptr_ptr)))) +@@ -886,7 +895,7 @@ output_relocs ( + #if defined(TARGET_m68k) + case R_68K_32: + relocation_needed = 1; +- sym_vma = bfd_section_vma(abs_bfd, sym_section); ++ sym_vma = elf2flt_bfd_section_vma(sym_section); + sym_addr += sym_vma + q->addend; + break; + case R_68K_PC16: +@@ -911,7 +920,7 @@ output_relocs ( + q->address, sym_addr, + (*p)->howto->rightshift, + *(uint32_t *)r_mem); +- sym_vma = bfd_section_vma(abs_bfd, sym_section); ++ sym_vma = elf2flt_bfd_section_vma(sym_section); + sym_addr += sym_vma + q->addend; + break; + case R_ARM_GOT32: +@@ -939,7 +948,7 @@ output_relocs ( + #ifdef TARGET_v850 + case R_V850_ABS32: + relocation_needed = 1; +- sym_vma = bfd_section_vma(abs_bfd, sym_section); ++ sym_vma = elf2flt_bfd_section_vma(sym_section); + sym_addr += sym_vma + q->addend; + break; + case R_V850_ZDA_16_16_OFFSET: +@@ -961,7 +970,7 @@ output_relocs ( + sym_addr = (*(q->sym_ptr_ptr))->value; + q->address -= 1; + r_mem -= 1; /* tracks q->address */ +- sym_vma = bfd_section_vma(abs_bfd, sym_section); ++ sym_vma = elf2flt_bfd_section_vma(sym_section); + sym_addr += sym_vma + q->addend; + sym_addr |= (*(unsigned char *)r_mem<<24); + break; +@@ -974,7 +983,7 @@ output_relocs ( + /* Absolute symbol done not relocation */ + relocation_needed = !bfd_is_abs_section(sym_section); + sym_addr = (*(q->sym_ptr_ptr))->value; +- sym_vma = bfd_section_vma(abs_bfd, sym_section); ++ sym_vma = elf2flt_bfd_section_vma(sym_section); + sym_addr += sym_vma + q->addend; + break; + case R_H8_DIR32: +@@ -987,7 +996,7 @@ output_relocs ( + } + relocation_needed = 1; + sym_addr = (*(q->sym_ptr_ptr))->value; +- sym_vma = bfd_section_vma(abs_bfd, sym_section); ++ sym_vma = elf2flt_bfd_section_vma(sym_section); + sym_addr += sym_vma + q->addend; + break; + case R_H8_PCREL16: +@@ -1013,7 +1022,7 @@ output_relocs ( + #ifdef TARGET_microblaze + case R_MICROBLAZE_64: + /* work out the relocation */ +- sym_vma = bfd_section_vma(abs_bfd, sym_section); ++ sym_vma = elf2flt_bfd_section_vma(sym_section); + sym_addr += sym_vma + q->addend; + /* Write relocated pointer back */ + r_mem[2] = (sym_addr >> 24) & 0xff; +@@ -1027,7 +1036,7 @@ output_relocs ( + pflags = 0x80000000; + break; + case R_MICROBLAZE_32: +- sym_vma = bfd_section_vma(abs_bfd, sym_section); ++ sym_vma = elf2flt_bfd_section_vma(sym_section); + sym_addr += sym_vma + q->addend; + relocation_needed = 1; + break; +@@ -1059,7 +1068,7 @@ output_relocs ( + case R_NIOS2_BFD_RELOC_32: + relocation_needed = 1; + pflags = (FLAT_NIOS2_R_32 << 28); +- sym_vma = bfd_section_vma(abs_bfd, sym_section); ++ sym_vma = elf2flt_bfd_section_vma(sym_section); + sym_addr += sym_vma + q->addend; + /* modify target, in target order */ + *(unsigned long *)r_mem = htoniosl(sym_addr); +@@ -1069,7 +1078,7 @@ output_relocs ( + unsigned long exist_val; + relocation_needed = 1; + pflags = (FLAT_NIOS2_R_CALL26 << 28); +- sym_vma = bfd_section_vma(abs_bfd, sym_section); ++ sym_vma = elf2flt_bfd_section_vma(sym_section); + sym_addr += sym_vma + q->addend; + + /* modify target, in target order */ +@@ -1100,7 +1109,7 @@ output_relocs ( + ? FLAT_NIOS2_R_HIADJ_LO : FLAT_NIOS2_R_HI_LO; + pflags <<= 28; + +- sym_vma = bfd_section_vma(abs_bfd, sym_section); ++ sym_vma = elf2flt_bfd_section_vma(abs_bfd, sym_section); + sym_addr += sym_vma + q->addend; + + /* modify high 16 bits, in target order */ +@@ -1133,7 +1142,7 @@ output_relocs ( + goto NIOS2_RELOC_ERR; + } + /* _gp holds a absolute value, otherwise the ld cannot generate correct code */ +- sym_vma = bfd_section_vma(abs_bfd, sym_section); ++ sym_vma = elf2flt_bfd_section_vma(sym_section); + //printf("sym=%x, %d, _gp=%x, %d\n", sym_addr+sym_vma, sym_addr+sym_vma, gp, gp); + sym_addr += sym_vma + q->addend; + sym_addr -= gp; +@@ -1214,7 +1223,7 @@ NIOS2_RELOC_ERR: + case R_SPARC_32: + case R_SPARC_UA32: + relocation_needed = 1; +- sym_vma = bfd_section_vma(abs_bfd, sym_section); ++ sym_vma = elf2flt_bfd_section_vma(sym_section); + sym_addr += sym_vma + q->addend; + break; + case R_SPARC_PC22: +@@ -1233,7 +1242,7 @@ NIOS2_RELOC_ERR: + case R_SPARC_HI22: + relocation_needed = 1; + pflags = 0x80000000; +- sym_vma = bfd_section_vma(abs_bfd, sym_section); ++ sym_vma = elf2flt_bfd_section_vma(sym_section); + sym_addr += sym_vma + q->addend; + sym_addr |= ( + htonl(*(uint32_t *)r_mem) +@@ -1243,7 +1252,7 @@ NIOS2_RELOC_ERR: + case R_SPARC_LO10: + relocation_needed = 1; + pflags = 0x40000000; +- sym_vma = bfd_section_vma(abs_bfd, sym_section); ++ sym_vma = elf2flt_bfd_section_vma(sym_section); + sym_addr += sym_vma + q->addend; + sym_addr &= 0x000003ff; + sym_addr |= ( +@@ -1257,7 +1266,7 @@ NIOS2_RELOC_ERR: + #ifdef TARGET_sh + case R_SH_DIR32: + relocation_needed = 1; +- sym_vma = bfd_section_vma(abs_bfd, sym_section); ++ sym_vma = elf2flt_bfd_section_vma(sym_section); + sym_addr += sym_vma + q->addend; + break; + case R_SH_REL32: +@@ -1289,7 +1298,7 @@ NIOS2_RELOC_ERR: + case R_E1_CONST31: + relocation_needed = 1; + DBG_E1("Handling Reloc \n"); +- sec_vma = bfd_section_vma(abs_bfd, sym_section); ++ sec_vma = elf2flt_bfd_section_vma(sym_section); + DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n", + sec_vma, sym_addr, q->address); + sym_addr = sec_vma + sym_addr; +@@ -1304,7 +1313,7 @@ NIOS2_RELOC_ERR: + relocation_needed = 0; + DBG_E1("Handling Reloc \n"); + DBG_E1("DONT RELOCATE AT LOADING\n"); +- sec_vma = bfd_section_vma(abs_bfd, sym_section); ++ sec_vma = elf2flt_bfd_section_vma(sym_section); + DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n", + sec_vma, sym_addr, q->address); + sym_addr = sec_vma + sym_addr; +@@ -1331,7 +1340,7 @@ NIOS2_RELOC_ERR: + relocation_needed = 0; + DBG_E1("Handling Reloc \n"); + DBG_E1("DONT RELOCATE AT LOADING\n"); +- sec_vma = bfd_section_vma(abs_bfd, sym_section); ++ sec_vma = elf2flt_bfd_section_vma(sym_section); + DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n", + sec_vma, sym_addr, q->address); + sym_addr = sec_vma + sym_addr; +@@ -1364,7 +1373,7 @@ NIOS2_RELOC_ERR: + DBG_E1("Handling Reloc \n"); + DIS29_RELOCATION: + relocation_needed = 1; +- sec_vma = bfd_section_vma(abs_bfd, sym_section); ++ sec_vma = elf2flt_bfd_section_vma(sym_section); + DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n", + sec_vma, sym_addr); + sym_addr = sec_vma + sym_addr; +@@ -1381,7 +1390,7 @@ DIS29_RELOCATION: + relocation_needed = 0; + DBG_E1("Handling Reloc \n"); + DBG_E1("DONT RELOCATE AT LOADING\n"); +- sec_vma = bfd_section_vma(abs_bfd, sym_section); ++ sec_vma = elf2flt_bfd_section_vma(sym_section); + DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n", + sec_vma, sym_addr); + sym_addr = sec_vma + sym_addr; +@@ -1407,7 +1416,7 @@ DIS29_RELOCATION: + case R_E1_IMM32: + relocation_needed = 1; + DBG_E1("Handling Reloc \n"); +- sec_vma = bfd_section_vma(abs_bfd, sym_section); ++ sec_vma = elf2flt_bfd_section_vma(sym_section); + DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n", + sec_vma, sym_addr); + sym_addr = sec_vma + sym_addr; +@@ -1423,7 +1432,7 @@ DIS29_RELOCATION: + case R_E1_WORD: + relocation_needed = 1; + DBG_E1("Handling Reloc \n"); +- sec_vma = bfd_section_vma(abs_bfd, sym_section); ++ sec_vma = elf2flt_bfd_section_vma(sym_section); + DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n", + sec_vma, sym_addr); + sym_addr = sec_vma + sym_addr; +@@ -1450,7 +1459,7 @@ DIS29_RELOCATION: + } + + sprintf(&addstr[0], "+0x%lx", sym_addr - (*(q->sym_ptr_ptr))->value - +- bfd_section_vma(abs_bfd, sym_section)); ++ elf2flt_bfd_section_vma(sym_section)); + + + /* +@@ -1890,8 +1899,8 @@ int main(int argc, char *argv[]) + } else + continue; + +- sec_size = bfd_section_size(abs_bfd, s); +- sec_vma = bfd_section_vma(abs_bfd, s); ++ sec_size = elf2flt_bfd_section_size(s); ++ sec_vma = elf2flt_bfd_section_vma(s); + + if (sec_vma < *vma) { + if (*len > 0) +@@ -1920,7 +1929,7 @@ int main(int argc, char *argv[]) + (SEC_DATA | SEC_READONLY | SEC_RELOC))) + if (!bfd_get_section_contents(abs_bfd, s, + text + (s->vma - text_vma), 0, +- bfd_section_size(abs_bfd, s))) ++ elf2flt_bfd_section_size(s))) + { + fatal("read error section %s", s->name); + } +@@ -1950,7 +1959,7 @@ int main(int argc, char *argv[]) + (SEC_READONLY | SEC_RELOC))) + if (!bfd_get_section_contents(abs_bfd, s, + data + (s->vma - data_vma), 0, +- bfd_section_size(abs_bfd, s))) ++ elf2flt_bfd_section_size(s))) + { + fatal("read error section %s", s->name); + } +-- +2.35.1 + diff --git a/toolchain/elf2flt/patches/v2021.08/0002-elf2flt.ld-reinstate-32-byte-alignment-for-.data-sec.patch b/toolchain/elf2flt/patches/v2021.08/0002-elf2flt.ld-reinstate-32-byte-alignment-for-.data-sec.patch new file mode 100644 index 000000000..4df3ea592 --- /dev/null +++ b/toolchain/elf2flt/patches/v2021.08/0002-elf2flt.ld-reinstate-32-byte-alignment-for-.data-sec.patch @@ -0,0 +1,81 @@ +From 85ba5664eb368eb1cbd2c30b7cd574acd75edd4c Mon Sep 17 00:00:00 2001 +From: Niklas Cassel +Date: Mon, 4 Apr 2022 15:30:24 +0200 +Subject: [PATCH] elf2flt.ld: reinstate 32 byte alignment for .data section + +Commit 8a3e74446fe7 ("allow to build arm flat binaries") moved the +following commands: + . = ALIGN(0x20) ; + @SYMBOL_PREFIX@_etext = . ; +from the .text section to the top level in the SECTIONS node. + +The .text output section is being directed to a memory region using the +"> flatmem :text" output section attribute. Commands in the top level in +the SECTIONS node are not. + +This means that the ALIGN() command is no longer being appended to the +flatmem memory region, it will simply update the Location Counter. + +The heuristic for placing an output section is described here: +https://sourceware.org/binutils/docs-2.38/ld.html#Output-Section-Address + +"If an output memory region is set for the section then it is added to this +region and its address will be the next free address in that region." + +Since the .data section is being directed to the same memory region as the +.text section, this means that the Location Counter is not used when +assigning an address to the .data output section, it will simply use the +next free address. + +No longer directing these commands to the flatmem memory region means that +the .data output section is no longer aligned to a 32 byte boundary. + +Before commit 8a3e74446fe7 ("allow to build arm flat binaries"): +$ readelf -S busybox_unstripped.gdb | grep data + [ 3] .data PROGBITS 0000000000035ac0 00036ac0 +$ readelf -s busybox_unstripped.gdb | grep _etext + 19286: 0000000000035ac0 0 NOTYPE GLOBAL DEFAULT 1 _etext + +After commit 8a3e74446fe7 ("allow to build arm flat binaries"): +$ readelf -S busybox_unstripped.gdb | grep data + [ 3] .data PROGBITS 0000000000035ab0 00036ab0 +$ readelf -s busybox_unstripped.gdb | grep _etext + 19287: 0000000000035ac0 0 NOTYPE GLOBAL DEFAULT 3 _etext + +The .data output section has to be aligned to a 32 byte boundary, see the +FLAT_DATA_ALIGN 0x20 macro and its usage in fs/binfmt_flat.c: +https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/binfmt_flat.c?h=v5.17#n59 + +Readd an explicit ALIGN attribute on the .data section itself, since the +linker will obey this attribute regardless if being directed to a memory +region or not. Also remove the ALIGN() command before the .data section, +since this misleads the reader to think that the Location Counter is used +when assigning an address to the .data section, when it actually is not. + +Fixes: 8a3e74446fe7 ("allow to build arm flat binaries") +Signed-off-by: Niklas Cassel +--- + elf2flt.ld.in | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/elf2flt.ld.in b/elf2flt.ld.in +index 0df999d..e5aea14 100644 +--- a/elf2flt.ld.in ++++ b/elf2flt.ld.in +@@ -94,12 +94,9 @@ W_RODAT: *(.gnu.linkonce.r*) + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flatmem + @SYMBOL_PREFIX@__exidx_end = .; +- +- . = ALIGN(0x20) ; + @SYMBOL_PREFIX@_etext = . ; + +- .data : { +- . = ALIGN(0x4) ; ++ .data ALIGN(0x20): { + @SYMBOL_PREFIX@_sdata = . ; + @SYMBOL_PREFIX@__data_start = . ; + @SYMBOL_PREFIX@data_start = . ; +-- +2.35.1 + diff --git a/toolchain/elf2flt/patches/v2021.08/0003-elf2flt-add-riscv-64-bits-support.patch b/toolchain/elf2flt/patches/v2021.08/0003-elf2flt-add-riscv-64-bits-support.patch new file mode 100644 index 000000000..15c191c83 --- /dev/null +++ b/toolchain/elf2flt/patches/v2021.08/0003-elf2flt-add-riscv-64-bits-support.patch @@ -0,0 +1,103 @@ +From 3f1f323feb5cf25d8c80861991d0360784f4d2e6 Mon Sep 17 00:00:00 2001 +From: Damien Le Moal +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. To +define this symbol, the "RISCV_GP" line prefix is added. The "RISCV_GP" +string is removed if the target CPU type is riscv64 and the definition +line is dropped for other CPU types. + +With these changes, buildroot and busybox build and run on riscv NOMMU +systems with Linux kernel including patch 6045ab5fea4c +("binfmt_flat: do not stop relocating GOT entries prematurely on riscv") +fixing the binfmt_flat loader. Tested on QEMU and Canaan Kendryte K210 +boards. + +This patch is based on earlier work by Christoph Hellwig . + +Signed-off-by: Damien Le Moal +--- + elf2flt.c | 16 ++++++++++++++++ + elf2flt.ld.in | 1 + + ld-elf2flt.c | 8 ++++++++ + 3 files changed, 25 insertions(+) + +diff --git a/elf2flt.c b/elf2flt.c +index da25e93..a03ea3a 100644 +--- a/elf2flt.c ++++ b/elf2flt.c +@@ -81,6 +81,8 @@ const char *elf2flt_progname; + #include + #elif defined(TARGET_xtensa) + #include ++#elif defined(TARGET_riscv64) ++#include + #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 +@@ -812,6 +816,18 @@ 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_ADD64: ++ case R_RISCV_SUB32: ++ case R_RISCV_SUB64: ++ 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 +diff --git a/elf2flt.ld.in b/elf2flt.ld.in +index e5aea14..950849e 100644 +--- a/elf2flt.ld.in ++++ b/elf2flt.ld.in +@@ -106,6 +106,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..75ee1bb 100644 +--- a/ld-elf2flt.c ++++ b/ld-elf2flt.c +@@ -324,6 +324,14 @@ static int do_final_link(void) + append_option(&other_options, concat(got_offset, "=", buf, NULL)); + } + ++ /* riscv adds a global pointer symbol to the linker file with the ++ "RISCV_GP:" prefix. Remove the prefix for riscv64 architecture and ++ the entire line for other architectures. */ ++ if (streq(TARGET_CPU, "riscv64")) ++ append_sed(&sed, "^RISCV_GP:", ""); ++ else ++ 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.36.1 + diff --git a/toolchain/elf2flt/patches/v2021.08/0004-elf2flt-create-a-common-helper-function.patch b/toolchain/elf2flt/patches/v2021.08/0004-elf2flt-create-a-common-helper-function.patch new file mode 100644 index 000000000..6fee99d45 --- /dev/null +++ b/toolchain/elf2flt/patches/v2021.08/0004-elf2flt-create-a-common-helper-function.patch @@ -0,0 +1,76 @@ +From 37e1e0ace8ccebf54ec2f5522bfc1f9db86946ad Mon Sep 17 00:00:00 2001 +From: Niklas Cassel +Date: Tue, 9 Aug 2022 12:13:50 +0200 +Subject: [PATCH] elf2flt: create a common helper function + +In order to make the code more maintainable, +move duplicated code to a common helper function. + +No functional change intended. + +Signed-off-by: Niklas Cassel +--- + elf2flt.c | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +diff --git a/elf2flt.c b/elf2flt.c +index 669591e..9c32f9a 100644 +--- a/elf2flt.c ++++ b/elf2flt.c +@@ -337,6 +337,13 @@ compare_relocs (const void *pa, const void *pb) + } + #endif + ++static bool ++ro_reloc_data_section_should_be_in_text(asection *s) ++{ ++ return (s->flags & (SEC_DATA | SEC_READONLY | SEC_RELOC)) == ++ (SEC_DATA | SEC_READONLY | SEC_RELOC); ++} ++ + static uint32_t * + output_relocs ( + bfd *abs_bfd, +@@ -428,8 +435,7 @@ output_relocs ( + */ + if ((!pic_with_got || ALWAYS_RELOC_TEXT) && + ((a->flags & SEC_CODE) || +- ((a->flags & (SEC_DATA | SEC_READONLY | SEC_RELOC)) == +- (SEC_DATA | SEC_READONLY | SEC_RELOC)))) ++ ro_reloc_data_section_should_be_in_text(a))) + sectionp = text + (a->vma - text_vma); + else if (a->flags & SEC_DATA) + sectionp = data + (a->vma - data_vma); +@@ -1893,8 +1899,7 @@ int main(int argc, char *argv[]) + bfd_vma sec_vma; + + if ((s->flags & SEC_CODE) || +- ((s->flags & (SEC_DATA | SEC_READONLY | SEC_RELOC)) == +- (SEC_DATA | SEC_READONLY | SEC_RELOC))) { ++ ro_reloc_data_section_should_be_in_text(s)) { + vma = &text_vma; + len = &text_len; + } else if (s->flags & SEC_DATA) { +@@ -1932,8 +1937,7 @@ int main(int argc, char *argv[]) + * data sections.*/ + for (s = abs_bfd->sections; s != NULL; s = s->next) + if ((s->flags & SEC_CODE) || +- ((s->flags & (SEC_DATA | SEC_READONLY | SEC_RELOC)) == +- (SEC_DATA | SEC_READONLY | SEC_RELOC))) ++ ro_reloc_data_section_should_be_in_text(s)) + if (!bfd_get_section_contents(abs_bfd, s, + text + (s->vma - text_vma), 0, + bfd_section_size(abs_bfd, s))) +@@ -1962,8 +1966,7 @@ int main(int argc, char *argv[]) + * data sections already included in the text output section.*/ + for (s = abs_bfd->sections; s != NULL; s = s->next) + if ((s->flags & SEC_DATA) && +- ((s->flags & (SEC_READONLY | SEC_RELOC)) != +- (SEC_READONLY | SEC_RELOC))) ++ !ro_reloc_data_section_should_be_in_text(s)) + if (!bfd_get_section_contents(abs_bfd, s, + data + (s->vma - data_vma), 0, + bfd_section_size(abs_bfd, s))) +-- +2.37.1 + diff --git a/toolchain/elf2flt/patches/v2021.08/0005-elf2flt-fix-fatal-error-regression-on-m68k-xtensa-ri.patch b/toolchain/elf2flt/patches/v2021.08/0005-elf2flt-fix-fatal-error-regression-on-m68k-xtensa-ri.patch new file mode 100644 index 000000000..278709cb1 --- /dev/null +++ b/toolchain/elf2flt/patches/v2021.08/0005-elf2flt-fix-fatal-error-regression-on-m68k-xtensa-ri.patch @@ -0,0 +1,73 @@ +From 65ac5f9e69cfb989d970da74c41e478774d29be5 Mon Sep 17 00:00:00 2001 +From: Niklas Cassel +Date: Tue, 9 Aug 2022 21:06:05 +0200 +Subject: [PATCH] elf2flt: fix fatal error regression on m68k, xtensa, + riscv64 + +Commit ba379d08bb78 ("elf2flt: fix for segfault on some ARM ELFs") +changed the condition of which input sections that should be included +in the .text output section from: +((a->flags & (SEC_DATA | SEC_READONLY)) == (SEC_DATA | SEC_READONLY)) +to: +((a->flags & (SEC_DATA | SEC_READONLY | SEC_RELOC)) == +(SEC_DATA | SEC_READONLY | SEC_RELOC)) + +On ARM, the .eh_frame input section does not have the SEC_RELOC flag +set, so this specific change had no effect on ARM. + +However, on e.g. m68k and riscv64, the .eh_frame input section does +have the SEC_RELOC flag set, which means that after commit ba379d08bb78 +("elf2flt: fix for segfault on some ARM ELFs"), read-only relocation +data sections were placed in .text output section, instead of .data +output section. + +This will result in a fatal error on m68k, xtensa and riscv64: +ERROR: text=0x3bab8 overlaps data=0x33f60 ? + +This is because elf2flt cannot append to .text after .data has been +appended to. + +Note that the binutils maintainer says that the correct thing is +to put read-only relocation data sections in .text: +https://sourceware.org/legacy-ml/binutils/2019-10/msg00132.html + +So the proper fix is probably to rewrite elf2flt so that it can append +to .text after .data has been appended to (which will require elf2flt +to move/relocate everything that has already been appended to .data, +since the virtual addresses are contiguous). + +However, for now, add an exception for m68k, xtensa and riscv64 +(specifically for the problematic input section, .eh_frame), so that we +get the same behavior as older elf2flt releases, where we put read-only +relocation data in .data, which was working perfectly fine. + +Signed-off-by: Niklas Cassel +--- + elf2flt.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/elf2flt.c b/elf2flt.c +index 9c32f9a..a680c89 100644 +--- a/elf2flt.c ++++ b/elf2flt.c +@@ -340,8 +340,15 @@ compare_relocs (const void *pa, const void *pb) + static bool + ro_reloc_data_section_should_be_in_text(asection *s) + { +- return (s->flags & (SEC_DATA | SEC_READONLY | SEC_RELOC)) == +- (SEC_DATA | SEC_READONLY | SEC_RELOC); ++ if ((s->flags & (SEC_DATA | SEC_READONLY | SEC_RELOC)) == ++ (SEC_DATA | SEC_READONLY | SEC_RELOC)) { ++#if defined(TARGET_m68k) || defined(TARGET_riscv64) || defined(TARGET_xtensa) ++ if (!strcmp(".eh_frame", s->name)) ++ return false; ++#endif ++ return true; ++ } ++ return false; + } + + static uint32_t * +-- +2.37.1 + -- cgit v1.2.3