[PATCH 1/2] tools: relocate-rela: Add M68K support

Add M68K ELF32 support into this tool, so it can patch static rela into M68K u-boot-nodtb.bin . This is the first step toward M68K relocation support, and in turn, removal of NEEDS_MANUAL_RELOC from the codebase altogether.
Signed-off-by: Marek Vasut marek.vasut+renesas@mailbox.org --- Cc: Angelo Dureghello angelo@kernel-space.org Cc: Angelo Durgehello angelo.dureghello@timesys.com Cc: Bin Meng bmeng.cn@gmail.com Cc: Heinrich Schuchardt xypron.glpk@gmx.de Cc: Huan Wang alison.wang@nxp.com Cc: Marek Vasut marek.vasut+renesas@mailbox.org Cc: Michal Simek michal.simek@amd.com Cc: Ovidiu Panait ovpanait@gmail.com Cc: Simon Glass sjg@chromium.org Cc: Zong Li zong.li@sifive.com --- tools/relocate-rela.c | 108 ++++++++++++++++++++++++++++++------------ 1 file changed, 77 insertions(+), 31 deletions(-)
diff --git a/tools/relocate-rela.c b/tools/relocate-rela.c index e28e7fcc6f5..2d008c7f602 100644 --- a/tools/relocate-rela.c +++ b/tools/relocate-rela.c @@ -24,6 +24,26 @@ #define R_AARCH64_RELATIVE 1027 #endif
+#ifndef EM_M68K +#define EM_M68K 4 +#endif + +#ifndef R_68K_NONE +#define R_68K_NONE 0 +#endif + +#ifndef R_68K_32 +#define R_68K_32 1 +#endif + +#ifndef R_68K_GLOB_DAT +#define R_68K_GLOB_DAT 20 +#endif + +#ifndef R_68K_RELATIVE +#define R_68K_RELATIVE 22 +#endif + #ifndef EM_MICROBLAZE #define EM_MICROBLAZE 189 #endif @@ -46,6 +66,7 @@
static int ei_class; static int ei_data; +static int machine;
static uint64_t rela_start, rela_end, text_base, dyn_start;
@@ -111,7 +132,7 @@ static int decode_elf64(FILE *felf, char **argv) uint64_t sh_addr, sh_offset, sh_size; Elf64_Half sh_index, sh_num; Elf64_Shdr *sh_table; /* Elf symbol table */ - int ret, i, machine; + int ret, i; char *sh_str;
debug("64bit version\n"); @@ -245,7 +266,7 @@ static int decode_elf32(FILE *felf, char **argv) uint32_t sh_addr, sh_offset, sh_size; Elf32_Half sh_index, sh_num; Elf32_Shdr *sh_table; /* Elf symbol table */ - int ret, i, machine; + int ret, i; char *sh_str;
debug("32bit version\n"); @@ -262,12 +283,20 @@ static int decode_elf32(FILE *felf, char **argv) machine = elf16_to_cpu(header.e_machine); debug("Machine %d\n", machine);
- if (machine != EM_MICROBLAZE) { + if (machine != EM_MICROBLAZE && machine != EM_M68K) { fprintf(stderr, "%s: Not supported machine type\n", argv[0]); return 30; }
text_base = elf32_to_cpu(header.e_entry); + /* + * M68K ELF entry point is MONITOR_BASE, not TEXT_BASE. + * TEXT_BASE is always MONITOR_BASE &~ 0x7ff, so clear + * those bits here. + */ + if (machine == EM_M68K) + text_base &= ~0x7ff; + section_header_base = elf32_to_cpu(header.e_shoff); section_header_size = elf16_to_cpu(header.e_shentsize) * elf16_to_cpu(header.e_shnum); @@ -488,25 +517,41 @@ static bool supported_rela32(Elf32_Rela *rela, uint32_t *type)
debug("Type:\t");
- switch (*type) { - case R_MICROBLAZE_32: - debug("R_MICROBLAZE_32\n"); - return true; - case R_MICROBLAZE_GLOB_DAT: - debug("R_MICROBLAZE_GLOB_DAT\n"); - return true; - case R_MICROBLAZE_NONE: - debug("R_MICROBLAZE_NONE - ignoring - do nothing\n"); - return false; - case R_MICROBLAZE_REL: - debug("R_MICROBLAZE_REL\n"); - return true; - default: - fprintf(stderr, "warning: unsupported relocation type %" - PRIu32 " at %" PRIx32 "\n", *type, rela->r_offset); - - return false; + if (machine == EM_M68K) { + switch (*type) { + case R_68K_32: + debug("R_68K_32\n"); + return true; + case R_68K_GLOB_DAT: + debug("R_68K_GLOB_DAT\n"); + return true; + case R_68K_NONE: + debug("R_68K_NONE - ignoring - do nothing\n"); + return false; + case R_68K_RELATIVE: + debug("R_68K_RELATIVE\n"); + return true; + } + } else { + switch (*type) { + case R_MICROBLAZE_32: + debug("R_MICROBLAZE_32\n"); + return true; + case R_MICROBLAZE_GLOB_DAT: + debug("R_MICROBLAZE_GLOB_DAT\n"); + return true; + case R_MICROBLAZE_NONE: + debug("R_MICROBLAZE_NONE - ignoring - do nothing\n"); + return false; + case R_MICROBLAZE_REL: + debug("R_MICROBLAZE_REL\n"); + return true; + } } + fprintf(stderr, "warning: unsupported relocation type %" + PRIu32 " at %" PRIx32 "\n", *type, rela->r_offset); + + return false; }
static int rela_elf32(char **argv, FILE *f) @@ -569,8 +614,8 @@ static int rela_elf32(char **argv, FILE *f)
debug("Addr:\t0x%" PRIx32 "\n", addr);
- switch (type) { - case R_MICROBLAZE_REL: + if ((machine == EM_M68K && type == R_68K_RELATIVE) || + (machine == EM_MICROBLAZE && type == R_MICROBLAZE_REL)) { if (fseek(f, addr, SEEK_SET) < 0) { fprintf(stderr, "%s: %s: seek to %" PRIx32 " failed: %s\n", @@ -585,9 +630,11 @@ static int rela_elf32(char **argv, FILE *f) argv[0], argv[1], addr); return 4; } - break; - case R_MICROBLAZE_32: - case R_MICROBLAZE_GLOB_DAT: + } else if ((machine == EM_M68K && + (type == R_68K_32 || type == R_68K_GLOB_DAT)) || + (machine == EM_MICROBLAZE && + (type == R_MICROBLAZE_32 || + type == R_MICROBLAZE_GLOB_DAT))) { /* global symbols read it and add reloc offset */ index = swrela.r_info >> 8; pos_dyn = dyn_start + sizeof(Elf32_Sym) * index; @@ -632,12 +679,11 @@ static int rela_elf32(char **argv, FILE *f) argv[0], argv[1], addr); return 4; } - - break; - case R_MICROBLAZE_NONE: + } else if (machine == EM_M68K && type == R_68K_NONE) { + debug("R_68K_NONE - skip\n"); + } else if (machine == EM_MICROBLAZE && type == R_MICROBLAZE_NONE) { debug("R_MICROBLAZE_NONE - skip\n"); - break; - default: + } else { fprintf(stderr, "warning: unsupported relocation type %" PRIu32 " at %" PRIx32 "\n", type, rela.r_offset);

Implement relocation for M68K. Perform all the updates in start.S relocate_code in assemby, since it is a simple matter of traversing the dynsym table and adding relocation offset - MONITOR_BASE to all the items in that table. The necessity to deal with MONITOR_BASE is a specific of M68K, where the ELF entry point is at offset 0x400, which is the MONITOR_BASE, while TEXT_BASE is at offset 0 .
This also removes the one last user of NEEDS_MANUAL_RELOC, so that could be finally cleaned up .
Signed-off-by: Marek Vasut marek.vasut+renesas@mailbox.org --- Cc: Angelo Dureghello angelo@kernel-space.org Cc: Angelo Durgehello angelo.dureghello@timesys.com Cc: Bin Meng bmeng.cn@gmail.com Cc: Heinrich Schuchardt xypron.glpk@gmx.de Cc: Huan Wang alison.wang@nxp.com Cc: Marek Vasut marek.vasut+renesas@mailbox.org Cc: Michal Simek michal.simek@amd.com Cc: Ovidiu Panait ovpanait@gmail.com Cc: Simon Glass sjg@chromium.org Cc: Zong Li zong.li@sifive.com --- arch/Kconfig | 1 - arch/m68k/Kconfig | 4 +-- arch/m68k/config.mk | 6 ++-- arch/m68k/cpu/mcf523x/start.S | 57 ++++++++++++++++++++------------ arch/m68k/cpu/mcf52x2/start.S | 57 ++++++++++++++++++++------------ arch/m68k/cpu/mcf530x/start.S | 59 +++++++++++++++++++++------------- arch/m68k/cpu/mcf532x/start.S | 57 ++++++++++++++++++++------------ arch/m68k/cpu/mcf5445x/start.S | 57 ++++++++++++++++++++------------ arch/m68k/cpu/u-boot.lds | 14 ++++++++ 9 files changed, 204 insertions(+), 108 deletions(-)
diff --git a/arch/Kconfig b/arch/Kconfig index c9a33592252..2e2cbdf37aa 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -68,7 +68,6 @@ config M68K bool "M68000 architecture" select HAVE_PRIVATE_LIBGCC select USE_PRIVATE_LIBGCC - select NEEDS_MANUAL_RELOC select SYS_BOOT_GET_CMDLINE select SYS_BOOT_GET_KBD select SYS_CACHE_SHIFT_4 diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 1911563e540..587edd50d7e 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -4,8 +4,8 @@ menu "M68000 architecture" config SYS_ARCH default "m68k"
-config NEEDS_MANUAL_RELOC - def_bool y +config STATIC_RELA + default y
# processor family config MCF520x diff --git a/arch/m68k/config.mk b/arch/m68k/config.mk index 3ccbe492202..643b7d1d35d 100644 --- a/arch/m68k/config.mk +++ b/arch/m68k/config.mk @@ -3,8 +3,8 @@ # (C) Copyright 2000-2002 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-PLATFORM_CPPFLAGS += -D__M68K__ -KBUILD_LDFLAGS += -n +PLATFORM_CPPFLAGS += -D__M68K__ -fPIC +KBUILD_LDFLAGS += -n -pie PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections PLATFORM_RELFLAGS += -ffixed-d7 -msep-data -LDFLAGS_FINAL += --gc-sections +LDFLAGS_FINAL += --gc-sections -pie diff --git a/arch/m68k/cpu/mcf523x/start.S b/arch/m68k/cpu/mcf523x/start.S index d2a21c3279b..c609e82163c 100644 --- a/arch/m68k/cpu/mcf523x/start.S +++ b/arch/m68k/cpu/mcf523x/start.S @@ -177,6 +177,39 @@ relocate_code: cmp.l %a1,%a2 bgt.s 1b
+#define R_68K_32 1 +#define R_68K_RELATIVE 22 + + move.l #(__rel_dyn_start), %a1 + move.l #(__rel_dyn_end), %a2 + +fixloop: + move.l (%a1)+, %d1 /* Elf32_Rela r_offset */ + move.l (%a1)+, %d2 /* Elf32_Rela r_info */ + move.l (%a1)+, %d3 /* Elf32_Rela r_addend */ + + andi.l #0xff, %d2 + cmp.l #R_68K_32, %d2 + beq.s fixup + cmp.l #R_68K_RELATIVE, %d2 + beq.s fixup + + bra fixnext + +fixup: + /* relative fix: store addend plus offset at dest location */ + move.l %a0, %a3 + add.l %d1, %a3 + sub.l #CONFIG_SYS_MONITOR_BASE, %a3 + move.l (%a3), %d4 + add.l %a0, %d4 + sub.l #CONFIG_SYS_MONITOR_BASE, %d4 + move.l %d4, (%a3) + +fixnext: + cmp.l %a1, %a2 + bge.s fixloop + /* * We are done. Do not return, instead branch to second part of board * initialization, now running from RAM. @@ -191,10 +224,8 @@ clear_bss: /* * Now clear BSS segment */ - move.l %a0, %a1 - add.l #(_sbss - CONFIG_SYS_MONITOR_BASE),%a1 - move.l %a0, %d1 - add.l #(_ebss - CONFIG_SYS_MONITOR_BASE),%d1 + move.l #(_sbss), %a1 + move.l #(_ebss), %d1 6: clr.l (%a1)+ cmp.l %a1,%d1 @@ -203,24 +234,10 @@ clear_bss: /* * fix got table in RAM */ - move.l %a0, %a1 - add.l #(__got_start - CONFIG_SYS_MONITOR_BASE),%a1 - move.l %a1,%a5 /* * fix got pointer register a5 */ - - move.l %a0, %a2 - add.l #(__got_end - CONFIG_SYS_MONITOR_BASE),%a2 - -7: - move.l (%a1),%d1 - sub.l #_start,%d1 - add.l %a0,%d1 - move.l %d1,(%a1)+ - cmp.l %a2, %a1 - bne 7b + move.l #(__got_start), %a5 /* fix got pointer register a5 */
/* calculate relative jump to board_init_r in ram */ - move.l %a0, %a1 - add.l #(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1 + move.l #(board_init_r), %a1
/* set parameters for board_init_r */ move.l %a0,-(%sp) /* dest_addr */ diff --git a/arch/m68k/cpu/mcf52x2/start.S b/arch/m68k/cpu/mcf52x2/start.S index 51d2e23df10..3a2760236ce 100644 --- a/arch/m68k/cpu/mcf52x2/start.S +++ b/arch/m68k/cpu/mcf52x2/start.S @@ -255,6 +255,39 @@ relocate_code: cmp.l %a1,%a2 bgt.s 1b
+#define R_68K_32 1 +#define R_68K_RELATIVE 22 + + move.l #(__rel_dyn_start), %a1 + move.l #(__rel_dyn_end), %a2 + +fixloop: + move.l (%a1)+, %d1 /* Elf32_Rela r_offset */ + move.l (%a1)+, %d2 /* Elf32_Rela r_info */ + move.l (%a1)+, %d3 /* Elf32_Rela r_addend */ + + andi.l #0xff, %d2 + cmp.l #R_68K_32, %d2 + beq.s fixup + cmp.l #R_68K_RELATIVE, %d2 + beq.s fixup + + bra fixnext + +fixup: + /* relative fix: store addend plus offset at dest location */ + move.l %a0, %a3 + add.l %d1, %a3 + sub.l #CONFIG_SYS_MONITOR_BASE, %a3 + move.l (%a3), %d4 + add.l %a0, %d4 + sub.l #CONFIG_SYS_MONITOR_BASE, %d4 + move.l %d4, (%a3) + +fixnext: + cmp.l %a1, %a2 + bge.s fixloop + /* * We are done. Do not return, instead branch to second part of board * initialization, now running from RAM. @@ -269,10 +302,8 @@ clear_bss: /* * Now clear BSS segment */ - move.l %a0, %a1 - add.l #(_sbss - CONFIG_SYS_MONITOR_BASE),%a1 - move.l %a0, %d1 - add.l #(_ebss - CONFIG_SYS_MONITOR_BASE),%d1 + move.l #(_sbss), %a1 + move.l #(_ebss), %d1 6: clr.l (%a1)+ cmp.l %a1,%d1 @@ -281,24 +312,10 @@ clear_bss: /* * fix got table in RAM */ - move.l %a0, %a1 - add.l #(__got_start - CONFIG_SYS_MONITOR_BASE),%a1 - move.l %a1,%a5 /* fix got pointer register a5 */ - - move.l %a0, %a2 - add.l #(__got_end - CONFIG_SYS_MONITOR_BASE),%a2 - -7: - move.l (%a1),%d1 - sub.l #_start,%d1 - add.l %a0,%d1 - move.l %d1,(%a1)+ - cmp.l %a2, %a1 - bne 7b + move.l #(__got_start), %a5 /* fix got pointer register a5 */
/* calculate relative jump to board_init_r in ram */ - move.l %a0, %a1 - add.l #(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1 + move.l #(board_init_r), %a1
/* set parameters for board_init_r */ move.l %a0,-(%sp) /* dest_addr */ diff --git a/arch/m68k/cpu/mcf530x/start.S b/arch/m68k/cpu/mcf530x/start.S index cef8d79aad1..552e0204b77 100644 --- a/arch/m68k/cpu/mcf530x/start.S +++ b/arch/m68k/cpu/mcf530x/start.S @@ -180,6 +180,39 @@ relocate_code: cmp.l %a1,%a2 bgt.s 1b
+#define R_68K_32 1 +#define R_68K_RELATIVE 22 + + move.l #(__rel_dyn_start), %a1 + move.l #(__rel_dyn_end), %a2 + +fixloop: + move.l (%a1)+, %d1 /* Elf32_Rela r_offset */ + move.l (%a1)+, %d2 /* Elf32_Rela r_info */ + move.l (%a1)+, %d3 /* Elf32_Rela r_addend */ + + andi.l #0xff, %d2 + cmp.l #R_68K_32, %d2 + beq.s fixup + cmp.l #R_68K_RELATIVE, %d2 + beq.s fixup + + bra fixnext + +fixup: + /* relative fix: store addend plus offset at dest location */ + move.l %a0, %a3 + add.l %d1, %a3 + sub.l #CONFIG_SYS_MONITOR_BASE, %a3 + move.l (%a3), %d4 + add.l %a0, %d4 + sub.l #CONFIG_SYS_MONITOR_BASE, %d4 + move.l %d4, (%a3) + +fixnext: + cmp.l %a1, %a2 + bge.s fixloop + /* * We are done. Do not return, instead branch to second part of board * initialization, now running from RAM. @@ -194,10 +227,8 @@ clear_bss: /* * Now clear BSS segment */ - move.l %a0, %a1 - add.l #(_sbss - CONFIG_SYS_MONITOR_BASE), %a1 - move.l %a0, %d1 - add.l #(_ebss - CONFIG_SYS_MONITOR_BASE), %d1 + move.l #(_sbss), %a1 + move.l #(_ebss), %d1 6: clr.l (%a1)+ cmp.l %a1,%d1 @@ -206,26 +237,10 @@ clear_bss: /* * fix got table in RAM */ - move.l %a0, %a1 - add.l #(__got_start - CONFIG_SYS_MONITOR_BASE), %a1 - - /* fix got pointer register a5 */ - move.l %a1,%a5 - - move.l %a0, %a2 - add.l #(__got_end - CONFIG_SYS_MONITOR_BASE), %a2 - -7: - move.l (%a1),%d1 - sub.l #_start, %d1 - add.l %a0,%d1 - move.l %d1,(%a1)+ - cmp.l %a2, %a1 - bne 7b + move.l #(__got_start), %a5 /* fix got pointer register a5 */
/* calculate relative jump to board_init_r in ram */ - move.l %a0, %a1 - add.l #(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1 + move.l #(board_init_r), %a1
/* set parameters for board_init_r */ move.l %a0,-(%sp) /* dest_addr */ diff --git a/arch/m68k/cpu/mcf532x/start.S b/arch/m68k/cpu/mcf532x/start.S index 72a2f99b7dd..c3eae73a9c0 100644 --- a/arch/m68k/cpu/mcf532x/start.S +++ b/arch/m68k/cpu/mcf532x/start.S @@ -192,6 +192,39 @@ relocate_code: cmp.l %a1,%a2 bgt.s 1b
+#define R_68K_32 1 +#define R_68K_RELATIVE 22 + + move.l #(__rel_dyn_start), %a1 + move.l #(__rel_dyn_end), %a2 + +fixloop: + move.l (%a1)+, %d1 /* Elf32_Rela r_offset */ + move.l (%a1)+, %d2 /* Elf32_Rela r_info */ + move.l (%a1)+, %d3 /* Elf32_Rela r_addend */ + + andi.l #0xff, %d2 + cmp.l #R_68K_32, %d2 + beq.s fixup + cmp.l #R_68K_RELATIVE, %d2 + beq.s fixup + + bra fixnext + +fixup: + /* relative fix: store addend plus offset at dest location */ + move.l %a0, %a3 + add.l %d1, %a3 + sub.l #CONFIG_SYS_MONITOR_BASE, %a3 + move.l (%a3), %d4 + add.l %a0, %d4 + sub.l #CONFIG_SYS_MONITOR_BASE, %d4 + move.l %d4, (%a3) + +fixnext: + cmp.l %a1, %a2 + bge.s fixloop + /* * We are done. Do not return, instead branch to second part of board * initialization, now running from RAM. @@ -206,10 +239,8 @@ clear_bss: /* * Now clear BSS segment */ - move.l %a0, %a1 - add.l #(_sbss - CONFIG_SYS_MONITOR_BASE),%a1 - move.l %a0, %d1 - add.l #(_ebss - CONFIG_SYS_MONITOR_BASE),%d1 + move.l #(_sbss), %a1 + move.l #(_ebss), %d1 6: clr.l (%a1)+ cmp.l %a1,%d1 @@ -218,24 +249,10 @@ clear_bss: /* * fix got table in RAM */ - move.l %a0, %a1 - add.l #(__got_start - CONFIG_SYS_MONITOR_BASE),%a1 - move.l %a1,%a5 /* fix got pointer register a5 */ - - move.l %a0, %a2 - add.l #(__got_end - CONFIG_SYS_MONITOR_BASE),%a2 - -7: - move.l (%a1),%d1 - sub.l #_start,%d1 - add.l %a0,%d1 - move.l %d1,(%a1)+ - cmp.l %a2, %a1 - bne 7b + move.l #(__got_start), %a5 /* fix got pointer register a5 */
/* calculate relative jump to board_init_r in ram */ - move.l %a0, %a1 - add.l #(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1 + move.l #(board_init_r), %a1
/* set parameters for board_init_r */ move.l %a0,-(%sp) /* dest_addr */ diff --git a/arch/m68k/cpu/mcf5445x/start.S b/arch/m68k/cpu/mcf5445x/start.S index a083c3d45d2..5c3bfff7918 100644 --- a/arch/m68k/cpu/mcf5445x/start.S +++ b/arch/m68k/cpu/mcf5445x/start.S @@ -533,6 +533,39 @@ relocate_code: cmp.l %a1,%a2 bgt.s 1b
+#define R_68K_32 1 +#define R_68K_RELATIVE 22 + + move.l #(__rel_dyn_start), %a1 + move.l #(__rel_dyn_end), %a2 + +fixloop: + move.l (%a1)+, %d1 /* Elf32_Rela r_offset */ + move.l (%a1)+, %d2 /* Elf32_Rela r_info */ + move.l (%a1)+, %d3 /* Elf32_Rela r_addend */ + + andi.l #0xff, %d2 + cmp.l #R_68K_32, %d2 + beq.s fixup + cmp.l #R_68K_RELATIVE, %d2 + beq.s fixup + + bra fixnext + +fixup: + /* relative fix: store addend plus offset at dest location */ + move.l %a0, %a3 + add.l %d1, %a3 + sub.l #CONFIG_SYS_MONITOR_BASE, %a3 + move.l (%a3), %d4 + add.l %a0, %d4 + sub.l #CONFIG_SYS_MONITOR_BASE, %d4 + move.l %d4, (%a3) + +fixnext: + cmp.l %a1, %a2 + bge.s fixloop + /* * We are done. Do not return, instead branch to second part of board * initialization, now running from RAM. @@ -547,10 +580,8 @@ clear_bss: /* * Now clear BSS segment */ - move.l %a0, %a1 - add.l #(_sbss - CONFIG_SYS_MONITOR_BASE),%a1 - move.l %a0, %d1 - add.l #(_ebss - CONFIG_SYS_MONITOR_BASE),%d1 + move.l #(_sbss), %a1 + move.l #(_ebss), %d1 6: clr.l (%a1)+ cmp.l %a1,%d1 @@ -559,24 +590,10 @@ clear_bss: /* * fix got table in RAM */ - move.l %a0, %a1 - add.l #(__got_start - CONFIG_SYS_MONITOR_BASE),%a1 - move.l %a1,%a5 /* fix got pointer register a5 */ - - move.l %a0, %a2 - add.l #(__got_end - CONFIG_SYS_MONITOR_BASE),%a2 - -7: - move.l (%a1),%d1 - sub.l #_start,%d1 - add.l %a0,%d1 - move.l %d1,(%a1)+ - cmp.l %a2, %a1 - bne 7b + move.l #(__got_start), %a5 /* fix got pointer register a5 */
/* calculate relative jump to board_init_r in ram */ - move.l %a0, %a1 - add.l #(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1 + move.l #(board_init_r), %a1
/* set parameters for board_init_r */ move.l %a0,-(%sp) /* dest_addr */ diff --git a/arch/m68k/cpu/u-boot.lds b/arch/m68k/cpu/u-boot.lds index 133f79150ba..03d427cd36c 100644 --- a/arch/m68k/cpu/u-boot.lds +++ b/arch/m68k/cpu/u-boot.lds @@ -76,6 +76,20 @@ SECTIONS . = ALIGN(4); __init_end = .;
+ . = ALIGN(4); + __rel_dyn_start = .; + .rela.dyn : { + *(.rela.dyn) + } + __rel_dyn_end = .; + + . = ALIGN(4); + __dyn_sym_start = .; + .dynsym : { + *(.dynsym) + } + __dyn_sym_end = .; + _end = .;
__bss_start = .;

On Sun, 30 Jul 2023 at 16:21, Marek Vasut marek.vasut+renesas@mailbox.org wrote:
Implement relocation for M68K. Perform all the updates in start.S relocate_code in assemby, since it is a simple matter of traversing the dynsym table and adding relocation offset - MONITOR_BASE to all the items in that table. The necessity to deal with MONITOR_BASE is a specific of M68K, where the ELF entry point is at offset 0x400, which is the MONITOR_BASE, while TEXT_BASE is at offset 0 .
This also removes the one last user of NEEDS_MANUAL_RELOC, so that could be finally cleaned up .
Signed-off-by: Marek Vasut marek.vasut+renesas@mailbox.org
Cc: Angelo Dureghello angelo@kernel-space.org Cc: Angelo Durgehello angelo.dureghello@timesys.com Cc: Bin Meng bmeng.cn@gmail.com Cc: Heinrich Schuchardt xypron.glpk@gmx.de Cc: Huan Wang alison.wang@nxp.com Cc: Marek Vasut marek.vasut+renesas@mailbox.org Cc: Michal Simek michal.simek@amd.com Cc: Ovidiu Panait ovpanait@gmail.com Cc: Simon Glass sjg@chromium.org Cc: Zong Li zong.li@sifive.com
arch/Kconfig | 1 - arch/m68k/Kconfig | 4 +-- arch/m68k/config.mk | 6 ++-- arch/m68k/cpu/mcf523x/start.S | 57 ++++++++++++++++++++------------ arch/m68k/cpu/mcf52x2/start.S | 57 ++++++++++++++++++++------------ arch/m68k/cpu/mcf530x/start.S | 59 +++++++++++++++++++++------------- arch/m68k/cpu/mcf532x/start.S | 57 ++++++++++++++++++++------------ arch/m68k/cpu/mcf5445x/start.S | 57 ++++++++++++++++++++------------ arch/m68k/cpu/u-boot.lds | 14 ++++++++ 9 files changed, 204 insertions(+), 108 deletions(-)
yay!
Reviewed-by: Simon Glass sjg@chromium.org

On 7/31/23 00:20, Marek Vasut wrote:
Add M68K ELF32 support into this tool, so it can patch static rela into M68K u-boot-nodtb.bin . This is the first step toward M68K relocation support, and in turn, removal of NEEDS_MANUAL_RELOC from the codebase altogether.
Signed-off-by: Marek Vasut marek.vasut+renesas@mailbox.org
Cc: Angelo Dureghello angelo@kernel-space.org Cc: Angelo Durgehello angelo.dureghello@timesys.com Cc: Bin Meng bmeng.cn@gmail.com Cc: Heinrich Schuchardt xypron.glpk@gmx.de Cc: Huan Wang alison.wang@nxp.com Cc: Marek Vasut marek.vasut+renesas@mailbox.org Cc: Michal Simek michal.simek@amd.com Cc: Ovidiu Panait ovpanait@gmail.com Cc: Simon Glass sjg@chromium.org Cc: Zong Li zong.li@sifive.com
tools/relocate-rela.c | 108 ++++++++++++++++++++++++++++++------------ 1 file changed, 77 insertions(+), 31 deletions(-)
diff --git a/tools/relocate-rela.c b/tools/relocate-rela.c index e28e7fcc6f5..2d008c7f602 100644 --- a/tools/relocate-rela.c +++ b/tools/relocate-rela.c @@ -24,6 +24,26 @@ #define R_AARCH64_RELATIVE 1027 #endif
+#ifndef EM_M68K +#define EM_M68K 4 +#endif
+#ifndef R_68K_NONE +#define R_68K_NONE 0 +#endif
+#ifndef R_68K_32 +#define R_68K_32 1 +#endif
+#ifndef R_68K_GLOB_DAT +#define R_68K_GLOB_DAT 20 +#endif
+#ifndef R_68K_RELATIVE +#define R_68K_RELATIVE 22 +#endif
- #ifndef EM_MICROBLAZE #define EM_MICROBLAZE 189 #endif
@@ -46,6 +66,7 @@
static int ei_class; static int ei_data; +static int machine;
static uint64_t rela_start, rela_end, text_base, dyn_start;
@@ -111,7 +132,7 @@ static int decode_elf64(FILE *felf, char **argv) uint64_t sh_addr, sh_offset, sh_size; Elf64_Half sh_index, sh_num; Elf64_Shdr *sh_table; /* Elf symbol table */
- int ret, i, machine;
int ret, i; char *sh_str;
debug("64bit version\n");
@@ -245,7 +266,7 @@ static int decode_elf32(FILE *felf, char **argv) uint32_t sh_addr, sh_offset, sh_size; Elf32_Half sh_index, sh_num; Elf32_Shdr *sh_table; /* Elf symbol table */
- int ret, i, machine;
int ret, i; char *sh_str;
debug("32bit version\n");
@@ -262,12 +283,20 @@ static int decode_elf32(FILE *felf, char **argv) machine = elf16_to_cpu(header.e_machine); debug("Machine %d\n", machine);
- if (machine != EM_MICROBLAZE) {
if (machine != EM_MICROBLAZE && machine != EM_M68K) { fprintf(stderr, "%s: Not supported machine type\n", argv[0]); return 30; }
text_base = elf32_to_cpu(header.e_entry);
/*
* M68K ELF entry point is MONITOR_BASE, not TEXT_BASE.
* TEXT_BASE is always MONITOR_BASE &~ 0x7ff, so clear
* those bits here.
*/
if (machine == EM_M68K)
text_base &= ~0x7ff;
section_header_base = elf32_to_cpu(header.e_shoff); section_header_size = elf16_to_cpu(header.e_shentsize) * elf16_to_cpu(header.e_shnum);
@@ -488,25 +517,41 @@ static bool supported_rela32(Elf32_Rela *rela, uint32_t *type)
debug("Type:\t");
- switch (*type) {
- case R_MICROBLAZE_32:
debug("R_MICROBLAZE_32\n");
return true;
- case R_MICROBLAZE_GLOB_DAT:
debug("R_MICROBLAZE_GLOB_DAT\n");
return true;
- case R_MICROBLAZE_NONE:
debug("R_MICROBLAZE_NONE - ignoring - do nothing\n");
return false;
- case R_MICROBLAZE_REL:
debug("R_MICROBLAZE_REL\n");
return true;
- default:
fprintf(stderr, "warning: unsupported relocation type %"
PRIu32 " at %" PRIx32 "\n", *type, rela->r_offset);
return false;
if (machine == EM_M68K) {
switch (*type) {
case R_68K_32:
debug("R_68K_32\n");
return true;
case R_68K_GLOB_DAT:
debug("R_68K_GLOB_DAT\n");
return true;
case R_68K_NONE:
debug("R_68K_NONE - ignoring - do nothing\n");
return false;
case R_68K_RELATIVE:
debug("R_68K_RELATIVE\n");
return true;
}
} else {
switch (*type) {
case R_MICROBLAZE_32:
debug("R_MICROBLAZE_32\n");
return true;
case R_MICROBLAZE_GLOB_DAT:
debug("R_MICROBLAZE_GLOB_DAT\n");
return true;
case R_MICROBLAZE_NONE:
debug("R_MICROBLAZE_NONE - ignoring - do nothing\n");
return false;
case R_MICROBLAZE_REL:
debug("R_MICROBLAZE_REL\n");
return true;
}
}
fprintf(stderr, "warning: unsupported relocation type %"
PRIu32 " at %" PRIx32 "\n", *type, rela->r_offset);
return false; }
static int rela_elf32(char **argv, FILE *f)
@@ -569,8 +614,8 @@ static int rela_elf32(char **argv, FILE *f)
debug("Addr:\t0x%" PRIx32 "\n", addr);
switch (type) {
case R_MICROBLAZE_REL:
if ((machine == EM_M68K && type == R_68K_RELATIVE) ||
(machine == EM_MICROBLAZE && type == R_MICROBLAZE_REL)) { if (fseek(f, addr, SEEK_SET) < 0) { fprintf(stderr, "%s: %s: seek to %" PRIx32 " failed: %s\n",
@@ -585,9 +630,11 @@ static int rela_elf32(char **argv, FILE *f) argv[0], argv[1], addr); return 4; }
break;
case R_MICROBLAZE_32:
case R_MICROBLAZE_GLOB_DAT:
} else if ((machine == EM_M68K &&
(type == R_68K_32 || type == R_68K_GLOB_DAT)) ||
(machine == EM_MICROBLAZE &&
(type == R_MICROBLAZE_32 ||
type == R_MICROBLAZE_GLOB_DAT))) { /* global symbols read it and add reloc offset */ index = swrela.r_info >> 8; pos_dyn = dyn_start + sizeof(Elf32_Sym) * index;
@@ -632,12 +679,11 @@ static int rela_elf32(char **argv, FILE *f) argv[0], argv[1], addr); return 4; }
break;
case R_MICROBLAZE_NONE:
} else if (machine == EM_M68K && type == R_68K_NONE) {
debug("R_68K_NONE - skip\n");
} else if (machine == EM_MICROBLAZE && type == R_MICROBLAZE_NONE) { debug("R_MICROBLAZE_NONE - skip\n");
break;
default:
} else { fprintf(stderr, "warning: unsupported relocation type %" PRIu32 " at %" PRIx32 "\n", type, rela.r_offset);
Tested-by: Michal Simek michal.simek@amd.com # microblaze, arm64
Thanks, Michal

Hi Marek,
thanks a lot for the job i should have done.
Tested on real hw:
m5282evb worked out of the box mcf54415 not working, had a lot of unsupported relocation type for R_68K_JMP_SLOT mcf5307 need to fix the hw, will do in short
i had to add this fix:
diff --git a/tools/relocate-rela.c b/tools/relocate-rela.c index 2d008c7f60..9722a6291a 100644 --- a/tools/relocate-rela.c +++ b/tools/relocate-rela.c @@ -40,6 +40,10 @@ #define R_68K_GLOB_DAT 20 #endif
+#ifndef R_68K_JMP_SLOT +#define R_68K_JMP_SLOT 21 +#endif + #ifndef R_68K_RELATIVE #define R_68K_RELATIVE 22 #endif @@ -531,6 +535,9 @@ static bool supported_rela32(Elf32_Rela *rela, uint32_t *type) case R_68K_RELATIVE: debug("R_68K_RELATIVE\n"); return true; + case R_68K_JMP_SLOT: + debug("R_68K_JMP_SLOT\n"); + return true; } } else { switch (*type) { @@ -631,8 +638,9 @@ static int rela_elf32(char **argv, FILE *f) return 4; } } else if ((machine == EM_M68K && - (type == R_68K_32 || type == R_68K_GLOB_DAT)) || - (machine == EM_MICROBLAZE && + (type == R_68K_32 || type == R_68K_GLOB_DAT || + type == R_68K_JMP_SLOT)) || + (machine == EM_MICROBLAZE && (type == R_MICROBLAZE_32 || type == R_MICROBLAZE_GLOB_DAT))) { /* global symbols read it and add reloc offset */
On 31/07/23 12:20 AM, Marek Vasut wrote:
Add M68K ELF32 support into this tool, so it can patch static rela into M68K u-boot-nodtb.bin . This is the first step toward M68K relocation support, and in turn, removal of NEEDS_MANUAL_RELOC from the codebase altogether.
Signed-off-by: Marek Vasut marek.vasut+renesas@mailbox.org
Cc: Angelo Dureghello angelo@kernel-space.org Cc: Angelo Durgehello angelo.dureghello@timesys.com Cc: Bin Meng bmeng.cn@gmail.com Cc: Heinrich Schuchardt xypron.glpk@gmx.de Cc: Huan Wang alison.wang@nxp.com Cc: Marek Vasut marek.vasut+renesas@mailbox.org Cc: Michal Simek michal.simek@amd.com Cc: Ovidiu Panait ovpanait@gmail.com Cc: Simon Glass sjg@chromium.org Cc: Zong Li zong.li@sifive.com
tools/relocate-rela.c | 108 ++++++++++++++++++++++++++++++------------ 1 file changed, 77 insertions(+), 31 deletions(-)
diff --git a/tools/relocate-rela.c b/tools/relocate-rela.c index e28e7fcc6f5..2d008c7f602 100644 --- a/tools/relocate-rela.c +++ b/tools/relocate-rela.c @@ -24,6 +24,26 @@ #define R_AARCH64_RELATIVE 1027 #endif
+#ifndef EM_M68K +#define EM_M68K 4 +#endif
+#ifndef R_68K_NONE +#define R_68K_NONE 0 +#endif
+#ifndef R_68K_32 +#define R_68K_32 1 +#endif
+#ifndef R_68K_GLOB_DAT +#define R_68K_GLOB_DAT 20 +#endif
+#ifndef R_68K_RELATIVE +#define R_68K_RELATIVE 22 +#endif
- #ifndef EM_MICROBLAZE #define EM_MICROBLAZE 189 #endif
@@ -46,6 +66,7 @@
static int ei_class; static int ei_data; +static int machine;
static uint64_t rela_start, rela_end, text_base, dyn_start;
@@ -111,7 +132,7 @@ static int decode_elf64(FILE *felf, char **argv) uint64_t sh_addr, sh_offset, sh_size; Elf64_Half sh_index, sh_num; Elf64_Shdr *sh_table; /* Elf symbol table */
- int ret, i, machine;
int ret, i; char *sh_str;
debug("64bit version\n");
@@ -245,7 +266,7 @@ static int decode_elf32(FILE *felf, char **argv) uint32_t sh_addr, sh_offset, sh_size; Elf32_Half sh_index, sh_num; Elf32_Shdr *sh_table; /* Elf symbol table */
- int ret, i, machine;
int ret, i; char *sh_str;
debug("32bit version\n");
@@ -262,12 +283,20 @@ static int decode_elf32(FILE *felf, char **argv) machine = elf16_to_cpu(header.e_machine); debug("Machine %d\n", machine);
- if (machine != EM_MICROBLAZE) {
if (machine != EM_MICROBLAZE && machine != EM_M68K) { fprintf(stderr, "%s: Not supported machine type\n", argv[0]); return 30; }
text_base = elf32_to_cpu(header.e_entry);
/*
* M68K ELF entry point is MONITOR_BASE, not TEXT_BASE.
* TEXT_BASE is always MONITOR_BASE &~ 0x7ff, so clear
* those bits here.
*/
if (machine == EM_M68K)
text_base &= ~0x7ff;
section_header_base = elf32_to_cpu(header.e_shoff); section_header_size = elf16_to_cpu(header.e_shentsize) * elf16_to_cpu(header.e_shnum);
@@ -488,25 +517,41 @@ static bool supported_rela32(Elf32_Rela *rela, uint32_t *type)
debug("Type:\t");
- switch (*type) {
- case R_MICROBLAZE_32:
debug("R_MICROBLAZE_32\n");
return true;
- case R_MICROBLAZE_GLOB_DAT:
debug("R_MICROBLAZE_GLOB_DAT\n");
return true;
- case R_MICROBLAZE_NONE:
debug("R_MICROBLAZE_NONE - ignoring - do nothing\n");
return false;
- case R_MICROBLAZE_REL:
debug("R_MICROBLAZE_REL\n");
return true;
- default:
fprintf(stderr, "warning: unsupported relocation type %"
PRIu32 " at %" PRIx32 "\n", *type, rela->r_offset);
return false;
if (machine == EM_M68K) {
switch (*type) {
case R_68K_32:
debug("R_68K_32\n");
return true;
case R_68K_GLOB_DAT:
debug("R_68K_GLOB_DAT\n");
return true;
case R_68K_NONE:
debug("R_68K_NONE - ignoring - do nothing\n");
return false;
case R_68K_RELATIVE:
debug("R_68K_RELATIVE\n");
return true;
}
} else {
switch (*type) {
case R_MICROBLAZE_32:
debug("R_MICROBLAZE_32\n");
return true;
case R_MICROBLAZE_GLOB_DAT:
debug("R_MICROBLAZE_GLOB_DAT\n");
return true;
case R_MICROBLAZE_NONE:
debug("R_MICROBLAZE_NONE - ignoring - do nothing\n");
return false;
case R_MICROBLAZE_REL:
debug("R_MICROBLAZE_REL\n");
return true;
}
}
fprintf(stderr, "warning: unsupported relocation type %"
PRIu32 " at %" PRIx32 "\n", *type, rela->r_offset);
return false; }
static int rela_elf32(char **argv, FILE *f)
@@ -569,8 +614,8 @@ static int rela_elf32(char **argv, FILE *f)
debug("Addr:\t0x%" PRIx32 "\n", addr);
switch (type) {
case R_MICROBLAZE_REL:
if ((machine == EM_M68K && type == R_68K_RELATIVE) ||
(machine == EM_MICROBLAZE && type == R_MICROBLAZE_REL)) { if (fseek(f, addr, SEEK_SET) < 0) { fprintf(stderr, "%s: %s: seek to %" PRIx32 " failed: %s\n",
@@ -585,9 +630,11 @@ static int rela_elf32(char **argv, FILE *f) argv[0], argv[1], addr); return 4; }
break;
case R_MICROBLAZE_32:
case R_MICROBLAZE_GLOB_DAT:
} else if ((machine == EM_M68K &&
(type == R_68K_32 || type == R_68K_GLOB_DAT)) ||
(machine == EM_MICROBLAZE &&
(type == R_MICROBLAZE_32 ||
type == R_MICROBLAZE_GLOB_DAT))) { /* global symbols read it and add reloc offset */ index = swrela.r_info >> 8; pos_dyn = dyn_start + sizeof(Elf32_Sym) * index;
@@ -632,12 +679,11 @@ static int rela_elf32(char **argv, FILE *f) argv[0], argv[1], addr); return 4; }
break;
case R_MICROBLAZE_NONE:
} else if (machine == EM_M68K && type == R_68K_NONE) {
debug("R_68K_NONE - skip\n");
} else if (machine == EM_MICROBLAZE && type == R_MICROBLAZE_NONE) { debug("R_MICROBLAZE_NONE - skip\n");
break;
default:
} else { fprintf(stderr, "warning: unsupported relocation type %" PRIu32 " at %" PRIx32 "\n", type, rela.r_offset);
Regards, angelo

On 8/26/23 09:44, Angelo Dureghello wrote:
Hi Marek,
thanks a lot for the job i should have done.
Tested on real hw:
m5282evb worked out of the box mcf54415 not working, had a lot of unsupported relocation type for R_68K_JMP_SLOT mcf5307 need to fix the hw, will do in short
i had to add this fix:
diff --git a/tools/relocate-rela.c b/tools/relocate-rela.c index 2d008c7f60..9722a6291a 100644 --- a/tools/relocate-rela.c +++ b/tools/relocate-rela.c @@ -40,6 +40,10 @@ #define R_68K_GLOB_DAT 20 #endif
+#ifndef R_68K_JMP_SLOT +#define R_68K_JMP_SLOT 21 +#endif
#ifndef R_68K_RELATIVE #define R_68K_RELATIVE 22 #endif @@ -531,6 +535,9 @@ static bool supported_rela32(Elf32_Rela *rela, uint32_t *type) case R_68K_RELATIVE: debug("R_68K_RELATIVE\n"); return true; + case R_68K_JMP_SLOT: + debug("R_68K_JMP_SLOT\n"); + return true; } } else { switch (*type) { @@ -631,8 +638,9 @@ static int rela_elf32(char **argv, FILE *f) return 4; } } else if ((machine == EM_M68K && - (type == R_68K_32 || type == R_68K_GLOB_DAT)) || - (machine == EM_MICROBLAZE && + (type == R_68K_32 || type == R_68K_GLOB_DAT || + type == R_68K_JMP_SLOT)) || + (machine == EM_MICROBLAZE && (type == R_MICROBLAZE_32 || type == R_MICROBLAZE_GLOB_DAT))) { /* global symbols read it and add reloc offset */
Wrapped into V2, thanks

Hi Marex,
thanks,
Acked-by: Angelo Dureghello angelo@kernel-space.org
On 27/08/23 12:29 AM, Marek Vasut wrote:
On 8/26/23 09:44, Angelo Dureghello wrote:
Hi Marek,
thanks a lot for the job i should have done.
Tested on real hw:
m5282evb worked out of the box mcf54415 not working, had a lot of unsupported relocation type for R_68K_JMP_SLOT mcf5307 need to fix the hw, will do in short
i had to add this fix:
diff --git a/tools/relocate-rela.c b/tools/relocate-rela.c index 2d008c7f60..9722a6291a 100644 --- a/tools/relocate-rela.c +++ b/tools/relocate-rela.c @@ -40,6 +40,10 @@ #define R_68K_GLOB_DAT 20 #endif
+#ifndef R_68K_JMP_SLOT +#define R_68K_JMP_SLOT 21 +#endif
#ifndef R_68K_RELATIVE #define R_68K_RELATIVE 22 #endif @@ -531,6 +535,9 @@ static bool supported_rela32(Elf32_Rela *rela, uint32_t *type) case R_68K_RELATIVE: debug("R_68K_RELATIVE\n"); return true; + case R_68K_JMP_SLOT: + debug("R_68K_JMP_SLOT\n"); + return true; } } else { switch (*type) { @@ -631,8 +638,9 @@ static int rela_elf32(char **argv, FILE *f) return 4; } } else if ((machine == EM_M68K && - (type == R_68K_32 || type == R_68K_GLOB_DAT)) || - (machine == EM_MICROBLAZE && + (type == R_68K_32 || type == R_68K_GLOB_DAT || + type == R_68K_JMP_SLOT)) || + (machine == EM_MICROBLAZE && (type == R_MICROBLAZE_32 || type == R_MICROBLAZE_GLOB_DAT))) { /* global symbols read it and add reloc offset */
Wrapped into V2, thanks

Hi,
applying this patchset to u-boot-coldfire
Thanks, angelo
On 27/08/23 12:29 AM, Marek Vasut wrote:
On 8/26/23 09:44, Angelo Dureghello wrote:
Hi Marek,
thanks a lot for the job i should have done.
Tested on real hw:
m5282evb worked out of the box mcf54415 not working, had a lot of unsupported relocation type for R_68K_JMP_SLOT mcf5307 need to fix the hw, will do in short
i had to add this fix:
diff --git a/tools/relocate-rela.c b/tools/relocate-rela.c index 2d008c7f60..9722a6291a 100644 --- a/tools/relocate-rela.c +++ b/tools/relocate-rela.c @@ -40,6 +40,10 @@ #define R_68K_GLOB_DAT 20 #endif
+#ifndef R_68K_JMP_SLOT +#define R_68K_JMP_SLOT 21 +#endif
#ifndef R_68K_RELATIVE #define R_68K_RELATIVE 22 #endif @@ -531,6 +535,9 @@ static bool supported_rela32(Elf32_Rela *rela, uint32_t *type) case R_68K_RELATIVE: debug("R_68K_RELATIVE\n"); return true; + case R_68K_JMP_SLOT: + debug("R_68K_JMP_SLOT\n"); + return true; } } else { switch (*type) { @@ -631,8 +638,9 @@ static int rela_elf32(char **argv, FILE *f) return 4; } } else if ((machine == EM_M68K && - (type == R_68K_32 || type == R_68K_GLOB_DAT)) || - (machine == EM_MICROBLAZE && + (type == R_68K_32 || type == R_68K_GLOB_DAT || + type == R_68K_JMP_SLOT)) || + (machine == EM_MICROBLAZE && (type == R_MICROBLAZE_32 || type == R_MICROBLAZE_GLOB_DAT))) { /* global symbols read it and add reloc offset */
Wrapped into V2, thanks
participants (5)
-
Angelo Dureghello
-
Marek Vasut
-
Marek Vasut
-
Michal Simek
-
Simon Glass