From: Marek Vasut Date: Sat, 26 Aug 2023 22:25:36 +0000 (+0200) Subject: arch: m68k: Implement relocation X-Git-Url: http://git.dujemihanovic.xyz/img/sics.gif?a=commitdiff_plain;h=26af162ac8f8ab3222d32f00f06a4774a061150a;p=u-boot.git 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 --- diff --git a/arch/Kconfig b/arch/Kconfig index 90345cbee0..19f2891ba1 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 1911563e54..587edd50d7 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 3ccbe49220..643b7d1d35 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 d2a21c3279..c609e82163 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 51d2e23df1..3a2760236c 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 cef8d79aad..552e0204b7 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 72a2f99b7d..c3eae73a9c 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 a083c3d45d..5c3bfff791 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 133f79150b..03d427cd36 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 = .;