aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Vasut <marek.vasut+renesas@mailbox.org>2023-08-27 00:25:36 +0200
committerAngelo Dureghello <angelo@kernel-space.org>2023-09-06 13:28:58 +0200
commit26af162ac8f8ab3222d32f00f06a4774a061150a (patch)
treea15efb3f50ae8be1a3d46f70f772c32ec4ad298f
parentbf10b9201c1ed198f76bc0a35fc64951de7583bc (diff)
downloadu-boot-26af162ac8f8ab3222d32f00f06a4774a061150a.zip
u-boot-26af162ac8f8ab3222d32f00f06a4774a061150a.tar.gz
u-boot-26af162ac8f8ab3222d32f00f06a4774a061150a.tar.bz2
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 <sjg@chromium.org> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
-rw-r--r--arch/Kconfig1
-rw-r--r--arch/m68k/Kconfig4
-rw-r--r--arch/m68k/config.mk6
-rw-r--r--arch/m68k/cpu/mcf523x/start.S57
-rw-r--r--arch/m68k/cpu/mcf52x2/start.S57
-rw-r--r--arch/m68k/cpu/mcf530x/start.S59
-rw-r--r--arch/m68k/cpu/mcf532x/start.S57
-rw-r--r--arch/m68k/cpu/mcf5445x/start.S57
-rw-r--r--arch/m68k/cpu/u-boot.lds14
9 files changed, 204 insertions, 108 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index 90345cb..19f2891 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 1911563..587edd5 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 3ccbe49..643b7d1 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 d2a21c3..c609e82 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 51d2e23..3a27602 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 cef8d79..552e020 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 72a2f99..c3eae73 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 a083c3d..5c3bfff 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 133f791..03d427c 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 = .;