From 0ad3eef38121b378cac1383b13b7365b1b9b1922 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 31 Jul 2023 00:16:52 +0200 Subject: [PATCH 1/3] tools: relocate-rela: Fix BE symtab handling The symtab contains data in target endianness, convert the data to native endianness before doing any operations and on them, and back to target endianness before updating the bin file. Signed-off-by: Marek Vasut Tested-by: Michal Simek # microblaze, arm64 Reviewed-by: Angelo Dureghello --- tools/relocate-rela.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/tools/relocate-rela.c b/tools/relocate-rela.c index f230ec5676c..e28e7fcc6f5 100644 --- a/tools/relocate-rela.c +++ b/tools/relocate-rela.c @@ -78,6 +78,14 @@ static uint32_t elf32_to_cpu(uint32_t data) return be32_to_cpu(data); } +static uint32_t cpu_to_elf32(uint32_t data) +{ + if (ei_data == ELFDATA2LSB) + return cpu_to_le32(data); + + return cpu_to_be32(data); +} + static bool supported_rela(Elf64_Rela *rela) { uint64_t mask = 0xffffffffULL; /* would be different on 32-bit */ @@ -602,14 +610,16 @@ static int rela_elf32(char **argv, FILE *f) } debug("Symbol description:\n"); - debug(" st_name:\t0x%x\n", symbols.st_name); - debug(" st_value:\t0x%x\n", symbols.st_value); - debug(" st_size:\t0x%x\n", symbols.st_size); + debug(" st_name:\t0x%x\n", elf32_to_cpu(symbols.st_name)); + debug(" st_value:\t0x%x\n", elf32_to_cpu(symbols.st_value)); + debug(" st_size:\t0x%x\n", elf32_to_cpu(symbols.st_size)); - value = swrela.r_addend + symbols.st_value; + value = swrela.r_addend + elf32_to_cpu(symbols.st_value); debug("Value:\t0x%x\n", value); + value = cpu_to_elf32(value); + if (fseek(f, addr, SEEK_SET) < 0) { fprintf(stderr, "%s: %s: seek to %" PRIx32 " failed: %s\n", From bf10b9201c1ed198f76bc0a35fc64951de7583bc Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 27 Aug 2023 00:25:35 +0200 Subject: [PATCH 2/3] 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. Tested-by: Michal Simek # microblaze, arm64 Signed-off-by: Marek Vasut --- tools/relocate-rela.c | 116 +++++++++++++++++++++++++++++++----------- 1 file changed, 85 insertions(+), 31 deletions(-) diff --git a/tools/relocate-rela.c b/tools/relocate-rela.c index e28e7fcc6f5..613abd25ef4 100644 --- a/tools/relocate-rela.c +++ b/tools/relocate-rela.c @@ -24,6 +24,30 @@ #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_JMP_SLOT +#define R_68K_JMP_SLOT 21 +#endif + +#ifndef R_68K_RELATIVE +#define R_68K_RELATIVE 22 +#endif + #ifndef EM_MICROBLAZE #define EM_MICROBLAZE 189 #endif @@ -46,6 +70,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 +136,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 +270,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 +287,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 +521,44 @@ 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_JMP_SLOT: + debug("R_68K_JMP_SLOT\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 +621,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 +637,12 @@ 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 || + 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 */ index = swrela.r_info >> 8; pos_dyn = dyn_start + sizeof(Elf32_Sym) * index; @@ -632,12 +687,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); From 26af162ac8f8ab3222d32f00f06a4774a061150a Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 27 Aug 2023 00:25:36 +0200 Subject: [PATCH 3/3] arch: m68k: Implement relocation 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 . Reviewed-by: Simon Glass Signed-off-by: Marek Vasut --- 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 90345cbee0d..19f2891ba1c 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 = .;