]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
arch: m68k: Implement relocation
authorMarek Vasut <marek.vasut+renesas@mailbox.org>
Sat, 26 Aug 2023 22:25:36 +0000 (00:25 +0200)
committerAngelo Dureghello <angelo@kernel-space.org>
Wed, 6 Sep 2023 11:28:58 +0000 (13:28 +0200)
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>
arch/Kconfig
arch/m68k/Kconfig
arch/m68k/config.mk
arch/m68k/cpu/mcf523x/start.S
arch/m68k/cpu/mcf52x2/start.S
arch/m68k/cpu/mcf530x/start.S
arch/m68k/cpu/mcf532x/start.S
arch/m68k/cpu/mcf5445x/start.S
arch/m68k/cpu/u-boot.lds

index 90345cbee0d848397a4b8a189adc605c8b046036..19f2891ba1c5d6cb7c4545a5e07ab5de60337345 100644 (file)
@@ -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
index 1911563e54006666b8d019a64bb33491f5e6f692..587edd50d7e83f3b9ce14760280390d211e73aa4 100644 (file)
@@ -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
index 3ccbe49220213abc639c62a0d9db149d79c0c3c3..643b7d1d35d5bbffdf409fb78338c770cdf66bf6 100644 (file)
@@ -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
index d2a21c3279b98d9ac14fc7cbf4242bc6d5ef1875..c609e82163c1f67b1a52ef39584c5bb21572638b 100644 (file)
@@ -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 */
index 51d2e23df10a2734164e577ef760d0cbabc30f68..3a2760236ce6f799ea3fc7e8941a7695606d93f1 100644 (file)
@@ -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 */
index cef8d79aad1a7877d850fa235bc094939b2b38d0..552e0204b771f5a294d4e81f1cbbab2f52783309 100644 (file)
@@ -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 */
index 72a2f99b7dd2cb1cf0f723626708d0ad2e033dc0..c3eae73a9c08278f80f3bb8a000c2f9e04938084 100644 (file)
@@ -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 */
index a083c3d45d277ee552e859cd732de4aab2491578..5c3bfff791836b6d7eedda2896101099138daacd 100644 (file)
@@ -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 */
index 133f79150baa1fb786981872ab4235983c261602..03d427cd36c9596b635539c8d7864ea0ec9d5d06 100644 (file)
@@ -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 = .;